## Automatically generated incremental diff
## From:   linux-2.4.2-pre1
## To:     linux-2.4.2-pre2
## Robot:  $Id: make-incremental-diff,v 1.8 2001/12/04 06:05:04 hpa Exp $

diff -urN linux-2.4.2-pre1/CREDITS linux/CREDITS
--- linux-2.4.2-pre1/CREDITS	Mon Dec  3 22:27:36 2001
+++ linux/CREDITS	Mon Dec  3 22:27:48 2001
@@ -957,6 +957,8 @@
 N: Hans Grobler
 E: grobh@sun.ac.za
 D: Various AX.25/ROSE/NETROM + hamradio driver patches
+D: Various X.25/LABP + driver patches
+D: Misc kernel fixes and updates
 S: Department of Electronic Engineering
 S: University of Stellenbosch
 S: Stellenbosch, Western Cape
@@ -1051,11 +1053,12 @@
 N: Jochen Hein
 E: jochen@jochen.org
 P: 1024/4A27F015 25 72 FB E3 85 9F DE 3B  CB 0A DA DA 40 77 05 6C
+P: 1024D/77D4FC9B F5C5 1C20 1DFC DEC3 3107  54A4 2332 ADFC 77D4 FC9B
 D: National Language Support
 D: Linux Internationalization Project
 D: German Localization for Linux and GNU software
-S: Frankenstraße 33
-S: 34131 Kassel
+S: Helenenstrasse 18
+S: 65183 Wiesbaden
 S: Germany
 
 N: Christoph Hellwig
@@ -1250,11 +1253,7 @@
 N: Niels Kristian Bech Jensen
 E: nkbj@image.dk
 W: http://www.image.dk/~nkbj
-D: 4.4BSD and NeXTstep filesystem support in the old ufs.
-D: Openstep filesystem and NeXTstep CDROM support in the new ufs.
-D: Replace CPU==[3-6]86 and __i386__ submodel flags by configuration options.
-D: Replace __SMP__ by CONFIG_SMP.
-D: Danish HOWTO, Linux+FreeBSD mini-HOWTO.
+D: Miscellaneous kernel updates and fixes.
 S: Dr. Holsts Vej 34, lejl. 164
 S: DK-8230 Åbyhøj
 S: Denmark
@@ -2938,9 +2937,10 @@
 D: some Alpha platform porting from 2.0, Memory Technology Devices,
 D: Acquire watchdog timer, PC speaker driver maintenance,
 D: various other stuff that annoyed me by not working.
-S: c/o Red Hat UK Limited
-S: 35-36 Cambridge Place
-S: Cambridge. CB2 1NS
+S: c/o Red Hat Engineering
+S: Rustat House
+S: 60 Clifton Road
+S: Cambridge. CB1 7EG
 S: England
 
 N: Frank Xia
diff -urN linux-2.4.2-pre1/Documentation/00-INDEX linux/Documentation/00-INDEX
--- linux-2.4.2-pre1/Documentation/00-INDEX	Tue Nov 14 10:54:07 2000
+++ linux/Documentation/00-INDEX	Mon Dec  3 22:27:48 2001
@@ -1,8 +1,8 @@
+
 This is a brief list of all the files in ./linux/Documentation and what
 they contain. If you add a documentation file, please list it here in 
 alphabetical order as well, or risk being hunted down like a rabid dog. 
-Note that subdirectories have their own index files too. Please try and
-keep the descriptions small enough to fit on one line.
+Please try and keep the descriptions small enough to fit on one line.
 							 Thanks -- Paul G.
 
 00-INDEX
@@ -15,28 +15,40 @@
 	- how the boss likes the C code in the kernel to look.
 Configure.help
 	- text file that is used for help when you run "make config"
-IO-APIC.txt
-	- info on using the enhanced interrupt hardware on SMP boards.
+DMA-mapping.txt
+	- info for PCI drivers using DMA portably across all platforms.
+DocBook/
+	- directory with DocBook templates etc. for kernel documentation.
 IO-mapping.txt
 	- how to access I/O mapped memory from within device drivers.
+IRQ-affinity.txt
+	- how to select which CPU(s) handle which interrupt events on SMP.
+LVM-HOWTO
+	- info on setting up logical volume management (virtual disks etc.)
 README.DAC960
 	- info on Mylex DAC960/DAC1100 PCI RAID Controller Driver for Linux
+README.moxa
+	- release notes for Moxa mutiport serial card.
+SubmittingDrivers
+	- procedure to get a new driver source included into the kernel tree.
+SubmittingPatches
+	- procedure to get a source patch included into the kernel tree.
 VGA-softcursor.txt
 	- how to change your VGA cursor from a blinking underscore.
 arm/
 	- directory with info about Linux on the ARM architecture.
-atm.txt
-	- info on Linux ATM support
 binfmt_misc.txt
 	- info on the kernel support for extra binary formats.
+cachetlb.txt
+	- describes the cache/TLB flushing interfaces Linux uses.
+cciss.txt
+	- info, major/minor #'s for Compaq's SMART Array Controllers.
 cdrom/
 	- directory with information on the CD-ROM drivers that Linux has.
 computone.txt
 	- info on Computone Intelliport II/Plus Multiport Serial Driver
 cpqarray.txt
 	- info on using Compaq's SMART2 Intelligent Disk Array Controllers.
-devices.tex
-	- LaTeX source listing of all the nodes in /dev/ with major minor #'s
 devices.txt
 	- plain ASCII listing of all the nodes in /dev/ with major minor #'s
 digiboard.txt
@@ -51,12 +63,20 @@
 	- directory with info on the frame buffer graphics abstraction layer.
 filesystems/
 	- directory with info on the various filesystems that Linux supports.
+floppy.txt
+	- notes and driver options for the floppy disk driver.
 ftape.txt
 	- notes about the floppy tape device driver
 hayes-esp.txt
 	- info on using the Hayes ESP serial driver.
+highuid.txt
+	- notes on the change from 16 bit to 32 bit user/group IDs.
+i2c/
+	- directory with info about the I2C bus/protocol (2 wire, kHz speed)
 i386/
-	- directory with info about Linux on the intel ix86 architecture.
+	- directory with info about Linux on intel 32 bit architecture.
+ia64/
+	- directory with info about Linux on intel 64 bit architecture.
 ide.txt
 	- important info for users of ATA devices (IDE/EIDE disks and CD-ROMS)
 initrd.txt
@@ -77,6 +97,8 @@
 	- info on using joystick devices (and driver) with Linux.
 kbuild/
 	- directory with info about the kernel build process
+kernel-doc-nano-HOWTO.txt
+	- mini HowTo on generation and location of kernel documentation files.
 kernel-docs.txt
 	- listing of various WWW + books that document kernel internals.
 kernel-parameters.txt
@@ -101,10 +123,14 @@
 	- info on boot arguments for the multiple devices driver
 memory.txt
 	- info on typical Linux memory problems.
+mkdev.cciss
+	- script to make /dev entries for SMART controllers (see cciss.txt)
 mkdev.ida
 	- script to make /dev entries for Intelligent Disk Array Controllers.
 modules.txt
 	- short guide on how to make kernel parts into loadable modules
+moxa-smartio
+	- info on installing/using Moxa multiport serial driver.
 mtrr.txt
 	- how to use PPro Memory Type Range Registers to increase performance
 nbd.txt
@@ -119,8 +145,12 @@
 	- how to decode those nasty internal kernel error dump messages.
 paride.txt
 	- information about the parallel port IDE subsystem.
+parisc/
+	- directory with info on using Linux on PA-RISC architecture.
 parport.txt
 	- how to use the parallel-port driver.
+parport-lowlevel.txt
+	- description and usage of the low level parallel port functions.
 pci.txt
 	- info on the PCI subsystem for device driver authors
 pcwd-watchdog.txt
@@ -129,14 +159,14 @@
 	- info on Linux power management support
 powerpc/
 	- directory with info on using Linux with the PowerPC.
-proc_usb_info.txt
-	- info on /proc/bus/usb direcory generated for USB devices
 ramdisk.txt
 	- short guide on how to set up and use the RAM disk.
 riscom8.txt
 	- notes on using the RISCom/8 multi-port serial driver.
 rtc.txt
 	- notes on how to use the Real Time Clock (aka CMOS clock) driver.
+s390/
+	- directory with info on using Linux on the IBM S390.
 scsi-generic.txt
 	- info on the sg driver for generic (non-disk/CD/tape) SCSI devices.
 scsi.txt
@@ -153,6 +183,8 @@
 	- a few more notes on symmetric multi-processing
 sound/
 	- directory with info on sound card support
+sparc/
+	- directory with info on using Linux on Sparc architecture.
 specialix.txt
 	- info on hardware/driver for specialix IO8+ multiport serial card.
 spinlocks.txt
@@ -167,8 +199,12 @@
 	- directory with info on the /proc/sys/* files
 sysrq.txt
 	- info on the magic SysRq key
+telephony/
+	- directory with info on telephony (e.g. voice over IP) support.
 unicode.txt
 	- info on the Unicode character/font mapping used in Linux.
+usb/
+	- directory with info regarding the Universal Serial Bus.
 video4linux/
 	- directory with info regarding video/TV/radio cards and linux.
 vm/
@@ -177,4 +213,6 @@
 	- how to auto-reboot Linux if it has "fallen and can't get up". ;-)
 xterm-linux.xpm
 	- XPM image of penguin logo (see logo.txt) sitting on an xterm.
+zorro.txt
+	- info on writing drivers for Zorro bus devices found on Amigas.
 
diff -urN linux-2.4.2-pre1/Documentation/Configure.help linux/Documentation/Configure.help
--- linux-2.4.2-pre1/Documentation/Configure.help	Mon Dec  3 22:27:36 2001
+++ linux/Documentation/Configure.help	Mon Dec  3 22:27:48 2001
@@ -1,7 +1,7 @@
 # Maintained by Axel Boldt (axel@uni-paderborn.de)
 #
 # This version of the Linux kernel configuration help texts
-# corresponds to the kernel versions 2.3.x.
+# corresponds to the kernel versions 2.4.x.
 #
 # Translations of this file available on the WWW:
 #
@@ -1575,16 +1575,6 @@
   more details about the Baget see the Linux/MIPS FAQ on 
   http://oss.sgi.com/mips .
 
-Support for Cobalt Microserver
-CONFIG_COBALT_MICRO_SERVER
-  This enables support for the Cobalt Microserver.  For more information
-  see the Linux/MIPS FAQ on http://oss.sgi.com/mips .
-
-Support for 2800
-CONFIG_COBALT_28
-  This adds support for the Cobalt Microserver 2800.  A kernel with this
-  option selected will only work on the 2800.
-
 Support for DECstations
 CONFIG_DECSTATION
   This enables support for DEC's MIPS based workstations.  For details
@@ -2572,7 +2562,7 @@
   inserted in and removed from the running kernel whenever you want).
   If you want to compile it as a module, say M here and read
   Documentation/modules.txt. You will get modules called i2o_core.o
-  and i20_config.o. 
+  and i2o_config.o. 
 
   If unsure, say N.
 
@@ -10361,14 +10351,12 @@
 USB Serial converter support
 CONFIG_USB_SERIAL
   Say Y here if you have a USB device that provides normal serial
-  ports, and you want to connect it to your USB bus. Supported devices
-  are the Tech WhiteHEAT multi-port USB to serial converter, and the
-  FTDI or Keyspan single port USB to serial converter Handspring
-  Visor. In addition to saying Y here, you need to say Y to the driver
-  for your specific hardware below. Some other devices may also be
-  used if you say Y to "USB Generic Serial Driver", below.
+  ports, or acts like a serial device, and you want to connect it to
+  your USB bus.
 
-  Please read Documentation/usb/usb-serial.txt for more information.
+  Please read Documentation/usb/usb-serial.txt for more information
+  on the specifics of the different devices that are supported, and
+  on how to use them.
   
   This code is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -10474,6 +10462,10 @@
 CONFIG_USB_SERIAL_KEYSPAN_USA19W
   Say Y here to include firmware for the USA-19W converter.
 
+USB Keyspan USA-49W Firmware
+CONFIG_USB_SERIAL_KEYSPAN_USA49W
+  Say Y here to include firmware for the USA-49W converter.
+
 USB ZyXEL omni.net LCD Plus Driver
 CONFIG_USB_SERIAL_OMNINET
   Say Y here if you want to use a ZyXEL omni.net LCD ISDN TA.
@@ -10514,6 +10506,9 @@
 CONFIG_USB_SERIAL_MCT_U232
   Say Y here if you want to use a USB Serial single port adapter from
   Magic Control Technology Corp. (U232 is one of the model numbers).
+  
+  This driver also works with Sitecom U232-P25 and D-Link DU-H3SP USB
+  BAY devices.
 
   This code is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -10523,7 +10518,7 @@
 USB Serial Converter verbose debug
 CONFIG_USB_SERIAL_DEBUG
   Say Y here if you want verbose debug messages from the USB Serial
-  Converter. 
+  Drivers sent to the kernel debug log.
 
 USB Printer support
 CONFIG_USB_PRINTER
diff -urN linux-2.4.2-pre1/Documentation/DocBook/kernel-hacking.tmpl linux/Documentation/DocBook/kernel-hacking.tmpl
--- linux-2.4.2-pre1/Documentation/DocBook/kernel-hacking.tmpl	Mon Nov 27 17:47:38 2000
+++ linux/Documentation/DocBook/kernel-hacking.tmpl	Mon Dec  3 22:27:48 2001
@@ -1179,7 +1179,7 @@
      You may well want to make your CONFIG option only visible if
      <symbol>CONFIG_EXPERIMENTAL</symbol> is enabled: this serves as a
      warning to users.  There many other fancy things you can do: see
-     the the various <filename>Config.in</filename> files for ideas.
+     the various <filename>Config.in</filename> files for ideas.
     </para>
    </listitem>
 
diff -urN linux-2.4.2-pre1/Documentation/DocBook/kernel-locking.tmpl linux/Documentation/DocBook/kernel-locking.tmpl
--- linux-2.4.2-pre1/Documentation/DocBook/kernel-locking.tmpl	Fri Dec 29 14:07:19 2000
+++ linux/Documentation/DocBook/kernel-locking.tmpl	Mon Dec  3 22:27:48 2001
@@ -386,7 +386,7 @@
        <function>spin_lock()</function> and
        <function>spin_unlock()</function> calls.  
        <function>spin_lock_bh()</function> is
-       unnecessary here, as you are already in a a tasklet, and
+       unnecessary here, as you are already in a tasklet, and
        none will be run on the same CPU.
      </para>
     </sect2>
diff -urN linux-2.4.2-pre1/Documentation/SubmittingDrivers linux/Documentation/SubmittingDrivers
--- linux-2.4.2-pre1/Documentation/SubmittingDrivers	Sun Dec  3 17:48:18 2000
+++ linux/Documentation/SubmittingDrivers	Mon Dec  3 22:27:48 2001
@@ -45,7 +45,7 @@
 What Criteria Determine Acceptance
 ----------------------------------
 
-Licensing:	The code must be released to us under the GNU public license. 
+Licensing:	The code must be released to us under the GNU General Public License. 
 		We don't insist on any kind of exclusively GPL licensing,
 		and if you wish the driver to be useful to other communities
 		such as BSD you may well wish to release under multiple
diff -urN linux-2.4.2-pre1/Documentation/cris/README linux/Documentation/cris/README
--- linux-2.4.2-pre1/Documentation/cris/README	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/cris/README	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,174 @@
+Linux 2.4 on the CRIS architecture
+==================================
+$Id: README,v 1.5 2001/01/10 17:20:55 bjornw Exp $
+
+This is a port of Linux 2.4 to Axis Communications ETRAX 100LX embedded network CPU. For
+more information about CRIS and ETRAX please see further below.
+
+<... to come: instructions on how to grab the right gcc, compiling and booting ...>
+
+
+What is CRIS ?
+--------------
+
+CRIS is an acronym for 'Code Reduced Instruction Set'. It is the CPU architecture in Axis
+Communication AB's range of embedded network CPU's, called ETRAX. The latest CPU is called
+ETRAX 100LX, where LX stands for 'Linux' because the chip was designed to be a good host for
+the Linux operating system.
+
+The ETRAX 100LX chip
+--------------------
+
+For reference, plase see the press-release:
+
+http://www.axis.com/news/us/001101_etrax.htm
+
+The ETRAX 100LX is a 100 MIPS processor with 8kB cache, MMU, and a very broad range of 
+built-in interfaces, all with modern scatter/gather DMA.
+
+Memory interfaces:
+
+	* SRAM
+	* NOR-flash/ROM
+	* EDO or page-mode DRAM
+	* SDRAM
+
+I/O interfaces:
+
+	* one 10/100 Mbit/s ethernet controller
+	* four serial-ports (up to 6 Mbit/s)
+	* two synchronous serial-ports for multimedia codec's etc.
+	* USB host controller and USB slave
+	* ATA
+	* SCSI
+	* two parallel-ports
+	* two generic 8-bit ports
+	
+	(not all interfaces are available at the same time due to chip pin multiplexing)
+
+The previous version of the ETRAX, the ETRAX 100, sits in almost all of Axis shipping 
+thin-servers like the Axis 2100 web camera or the developer-board. It lacks an MMU so the
+Linux we run on that is a version of uClinux (Linux 2.0 without MM-support) ported to the CRIS
+architecture. The new Linux 2.4 port has full MM and needs a CPU with an MMU, so it will not
+run on the ETRAX 100. 
+
+A version of the Axis developer-board with ETRAX 100LX will be available as soon as the chip 
+is ramped up (please see http://developer.axis.com for further information on that).
+
+
+
+Bootlog
+-------
+
+Just as an example, this is the debug-output from a boot of Linux 2.4 on an Axis
+developer-board with ETRAX 100LX. The displayed BogoMIPS value is 5 times too small :)
+At the end you see some user-mode programs booting like telnet and ftp daemons.
+
+Linux version 2.4.0-test11 (bjornw@godzilla.axis.se) (gcc version 2.96 20000427 (experimental)) #358 Wed Nov 22 19:29:15 CET 2000
+ROM fs in RAM, size 368640 bytes
+Setting up paging and the MMU.
+On node 0 totalpages: 1024
+zone(0): 1024 pages.
+zone(1): 0 pages.
+zone(2): 0 pages.
+Linux/CRIS port (c) 2000 Axis Communications AB
+Kernel command line: 
+Calibrating delay loop... 19.92 BogoMIPS
+Memory: 6864k/8192k available (531k kernel code, 1328k reserved, 85k data, 24k init)
+kmem_create: Forcing size word alignment - vm_area_struct
+kmem_create: Forcing size word alignment - filp
+Dentry-cache hash table entries: 1024 (order: 0, 8192 bytes)
+Buffer-cache hash table entries: 2048 (order: 0, 8192 bytes)
+Page-cache hash table entries: 2048 (order: 0, 8192 bytes)
+kmem_create: Forcing size word alignment - kiobuf
+kmem_create: Forcing size word alignment - bdev_cache
+Inode-cache hash table entries: 1024 (order: 0, 8192 bytes)
+kmem_create: Forcing size word alignment - inode_cache
+POSIX conformance testing by UNIFIX
+Linux NET4.0 for Linux 2.4
+Based upon Swansea University Computer Society NET3.039
+kmem_create: Forcing size word alignment - skbuff_head_cache
+Starting kswapd v1.8
+kmem_create: Forcing size word alignment - file lock cache
+kmem_create: Forcing size word alignment - blkdev_requests
+ETRAX 100LX 10/100MBit ethernet v2.0 (c) 2000 Axis Communications AB
+eth0 initialized
+eth0: changed MAC to 00:40:8C:CD:00:00
+ETRAX 100LX serial-driver $Revision: 1.5 $, (c) 2000 Axis Communications AB
+ttyS0 at 0xb0000060 is a builtin UART with DMA
+ttyS1 at 0xb0000068 is a builtin UART with DMA
+ttyS2 at 0xb0000070 is a builtin UART with DMA
+ttyS3 at 0xb0000078 is a builtin UART with DMA
+NET4: Linux TCP/IP 1.0 for NET4.0
+IP Protocols: ICMP, UDP, TCP
+kmem_create: Forcing size word alignment - ip_dst_cache
+IP: routing cache hash table of 1024 buckets, 8Kbytes
+TCP: Hash tables configured (established 1024 bind 1024)
+NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
+VFS: Mounted root (cramfs filesystem) readonly.
+Init starts up...
+Setting up eth0 with ip 10.13.9.116 and mac 00:40:8c:18:04:60
+eth0: changed MAC to 00:40:8C:18:04:60
+Setting up lo with ip 127.0.0.1
+Default gateway is 10.13.9.1
+Hostname is bbox1
+Telnetd starting, using port 23.
+  using /bin/sh as shell.
+sftpd[14]: sftpd $Revision: 1.5 $ starting up
+
+
+And here is how some /proc entries look:
+
+17# cd /proc
+17# cat cpuinfo
+cpu             : ETRAX
+cpu revision    : 10
+cpu model       : ETRAX 100LX
+cache size      : 8 kB
+fpu             : no
+mmu             : yes
+ethernet        : 10/100 Mbps
+token ring      : no
+scsi            : yes
+ata             : yes
+usb             : yes
+bogomips        : 99.84
+17# cat meminfo
+        total:    used:    free:  shared: buffers:  cached:
+Mem:   7028736   925696  6103040   114688        0   229376
+Swap:        0        0        0
+MemTotal:         6864 kB
+MemFree:          5960 kB
+MemShared:         112 kB
+Buffers:             0 kB
+Cached:            224 kB
+Active:            224 kB
+Inact_dirty:         0 kB
+Inact_clean:         0 kB
+Inact_target:        0 kB
+HighTotal:           0 kB
+HighFree:            0 kB
+LowTotal:         6864 kB
+LowFree:          5960 kB
+SwapTotal:           0 kB
+SwapFree:            0 kB
+17# ls -l /bin
+-rwxr-xr-x  1 342      100         10356  Jan 01 00:00 ifconfig
+-rwxr-xr-x  1 342      100         17548  Jan 01 00:00 init
+-rwxr-xr-x  1 342      100          9488  Jan 01 00:00 route
+-rwxr-xr-x  1 342      100         46036  Jan 01 00:00 sftpd
+-rwxr-xr-x  1 342      100         48104  Jan 01 00:00 sh
+-rwxr-xr-x  1 342      100         16252  Jan 01 00:00 telnetd
+
+
+(All programs are statically linked to the libc at this point - we have not ported the
+ shared libraries yet)
+
+
+
+
+
+
+
+
+
diff -urN linux-2.4.2-pre1/Documentation/filesystems/00-INDEX linux/Documentation/filesystems/00-INDEX
--- linux-2.4.2-pre1/Documentation/filesystems/00-INDEX	Wed Feb 16 15:42:05 2000
+++ linux/Documentation/filesystems/00-INDEX	Mon Dec  3 22:27:48 2001
@@ -1,5 +1,7 @@
 00-INDEX
 	- this file (info on some of the filesystems supported by linux).
+Locking
+	- info on locking rules as they pertain to Linux VFS.
 adfs.txt
 	- info and mount options for the Acorn Advanced Disc Filing System.
 affs.txt
@@ -8,8 +10,12 @@
 	- info for the SCO UnixWare Boot Filesystem (BFS).
 coda.txt
 	- description of the CODA filesystem.
-devfs
+cramfs.txt
+	- info on the cram filesystem for small storage (ROMs etc)
+devfs/
 	- directory containing devfs documentation.
+ext2.txt
+	- info, mount options and specifications for the Ext2 filesystem.
 fat_cvf.txt
 	- info on the Compressed Volume Files extension to the FAT filesystem
 hpfs.txt
diff -urN linux-2.4.2-pre1/Documentation/ia64/efirtc.txt linux/Documentation/ia64/efirtc.txt
--- linux-2.4.2-pre1/Documentation/ia64/efirtc.txt	Fri Jul 28 12:50:51 2000
+++ linux/Documentation/ia64/efirtc.txt	Mon Dec  3 22:27:48 2001
@@ -13,7 +13,7 @@
 
 EFI provides 4 calls one can make once the OS is booted: GetTime(),
 SetTime(), GetWakeupTime(), SetWakeupTime() which are all supported by this driver.
-We describes those calls as well the the design of the driver in the following
+We describe those calls as well the design of the driver in the following
 sections.
 
 II/ Design Decisions
diff -urN linux-2.4.2-pre1/Documentation/isdn/README.HiSax linux/Documentation/isdn/README.HiSax
--- linux-2.4.2-pre1/Documentation/isdn/README.HiSax	Tue Nov 28 21:43:13 2000
+++ linux/Documentation/isdn/README.HiSax	Mon Dec  3 22:27:48 2001
@@ -442,6 +442,7 @@
 	Enrik Berkhan (enrik@starfleet.inka.de) for S0BOX specific stuff
 	Ton van Rosmalen for Teles PCI
 	Petr Novak <petr.novak@i.cz> for Winbond W6692 support
+	Werner Cornelius <werner@isdn4linux.de> for HFC-PCI, HFC-S(+/P) and supplementary services support
         and more people who are hunting bugs. (If I forgot somebody, please
 	send me a mail).
 
diff -urN linux-2.4.2-pre1/Documentation/isdn/README.diversion linux/Documentation/isdn/README.diversion
--- linux-2.4.2-pre1/Documentation/isdn/README.diversion	Fri Jul 28 12:50:51 2000
+++ linux/Documentation/isdn/README.diversion	Mon Dec  3 22:27:48 2001
@@ -6,7 +6,7 @@
 the HiSax driver.
 The diversion kernel interface and controlling tool divertctrl were written
 by Werner Cornelius (werner@isdn4linux.de or werner@titro.de) under the
-GNU Public License.
+GNU General Public License.
 
     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
diff -urN linux-2.4.2-pre1/Documentation/isdn/README.hfc-pci linux/Documentation/isdn/README.hfc-pci
--- linux-2.4.2-pre1/Documentation/isdn/README.hfc-pci	Sun Nov  7 16:34:00 1999
+++ linux/Documentation/isdn/README.hfc-pci	Mon Dec  3 22:27:48 2001
@@ -35,7 +35,7 @@
 supplied else the parameter is assumed 0 and a auto search for a free card is
 invoked which may not give the wanted result. 
 
-Comments and reports to werner@isdn4linux.de or werner@titro.de .
+Comments and reports to werner@isdn4linux.de or werner@isdn-development.de
 
 
 
diff -urN linux-2.4.2-pre1/Documentation/isdn/README.hysdn linux/Documentation/isdn/README.hysdn
--- linux-2.4.2-pre1/Documentation/isdn/README.hysdn	Mon Aug 21 07:49:02 2000
+++ linux/Documentation/isdn/README.hysdn	Mon Dec  3 22:27:48 2001
@@ -2,7 +2,7 @@
 The hysdn driver has been written by
 by Werner Cornelius (werner@isdn4linux.de or werner@titro.de) 
 for Hypercope GmbH Aachen Germany. Hypercope agreed to publish this driver
-under the GNU Public License.
+under the GNU General Public License.
 
 The CAPI 2.0-support was added by Ulrich Albrecht (ualbrecht@hypercope.de)
 for Hypercope GmbH Aachen, Germany.
diff -urN linux-2.4.2-pre1/Documentation/networking/00-INDEX linux/Documentation/networking/00-INDEX
--- linux-2.4.2-pre1/Documentation/networking/00-INDEX	Sat Nov 27 15:27:48 1999
+++ linux/Documentation/networking/00-INDEX	Mon Dec  3 22:27:48 2001
@@ -4,32 +4,46 @@
 	- information on the 3Com EtherLink Plus (3c505) driver.
 6pack.txt
 	- info on the 6pack protocol, an alternative to KISS for AX.25
+8139too.txt
+	- info on the 8139too driver for RTL-8139 based network cards.
 Configurable
 	- info on some of the configurable network parameters
 DLINK.txt
 	- info on the D-Link DE-600/DE-620 parallel port pocket adapters
 PLIP.txt
 	- PLIP: The Parallel Line Internet Protocol device driver
+README.sb1000
+	- info on General Instrument/NextLevel SURFboard1000 cable modem.
 alias.txt
 	- info on using alias network devices 
 arcnet-hardware.txt
 	- tons of info on ARCnet, hubs, jumper settings for ARCnet cards, etc.
 arcnet.txt
 	- info on the using the ARCnet driver itself.
+atm.txt
+	- info on where to get ATM programs and support for Linux.
 ax25.txt
 	- info on using AX.25 and NET/ROM code for Linux
 baycom.txt
 	- info on the driver for Baycom style amateur radio modems
+bridge.txt
+	- where to get user space programs for ethernet bridging with Linux.
+comx.txt
+	- info on drivers for COMX line of synchronous serial adapters.
 cops.txt
 	- info on the COPS LocalTalk Linux driver
 cs89x0.txt
 	- the Crystal LAN (CS8900/20-based) Ethernet ISA adapter driver
 de4x5.txt
 	- the Digital EtherWORKS DE4?? and DE5?? PCI Ethernet driver
+decnet.txt
+	- info on using the DECnet networking layer in Linux.
 depca.txt
 	- the Digital DEPCA/EtherWORKS DE1?? and DE2?? LANCE Ethernet driver
 dgrs.txt
 	- the Digi International RightSwitch SE-X Ethernet driver
+dmfe.txt
+	- info on the Davicom DM9102(A)/DM9132/DM9801 fast ethernet driver.
 eql.txt
 	- serial IP load balancing
 ethertap.txt
@@ -38,6 +52,8 @@
 	- the Digital EtherWORKS 3 DE203/4/5 Ethernet driver
 filter.txt
 	- Linux Socket Filtering
+fore200e.txt
+	- FORE Systems PCA-200E/SBA-200E ATM NIC driver info.
 framerelay.txt
 	- info on using Frame Relay/Data Link Connection Identifier (DLCI).
 ip-sysctl.txt
@@ -46,6 +62,10 @@
 	- IP dynamic address hack e.g. for auto-dialup links
 ipddp.txt
 	- AppleTalk-IP Decapsulation and AppleTalk-IP Encapsulation
+iphase.txt
+	- Interphase PCI ATM (i)Chip IA Linux driver info.
+irda.txt
+	- where to get IrDA (infrared) utilities and info for Linux.
 lapb-module.txt
 	- programming information of the LAPB module.
 ltpc.txt
@@ -56,22 +76,42 @@
 	- notes on how NCSA telnet (DOS) breaks with MTU discovery enabled.
 net-modules.txt
 	- info and "insmod" parameters for all network driver modules.
+netdevices.txt
+	- info on network device driver functions exported to the kernel.
+olympic.txt
+	- IBM PCI Pit/Pit-Phy/Olympic Token Ring driver info.
 policy-routing.txt
 	- IP policy-based routing
 pt.txt
 	- the Gracilis Packetwin AX.25 device driver
+ray_cs.txt
+	- Raylink Wireless LAN card driver info.
 routing.txt
 	- the new routing mechanism
 shaper.txt
 	- info on the module that can shape/limit transmitted traffic.
+sis900.txt
+	- SiS 900/7016 Fast Ethernet device driver info.
+sk98lin.txt
+	- SysKonnect SK-NET (SK-98xx) Gigabit Ethernet driver info.
+skfp.txt
+	- SysKonnect FDDI (SK-5xxx, Compaq Netelligent) driver info.
 smc9.txt
 	- the driver for SMC's 9000 series of Ethernet cards
+smctr.txt
+	- SMC TokenCard TokenRing Linux driver info.
 soundmodem.txt
 	- Linux driver for sound cards as AX.25 modems
 tcp.txt
 	- short blurb on how TCP output takes place.
+tlan.txt
+	- ThunderLAN (Compaq Netelligent 10/100, Olicom OC-2xxx) driver info.
+tms380tr.txt
+	- SysKonnect Token Ring ISA/PCI adapter driver info.
 tulip.txt
 	- info on using DEC 21040/21041/21140 based PCI Ethernet cards.
+tuntap.txt
+	- TUN/TAP device driver, allowing user space Rx/Tx of packets.
 vortex.txt
 	- info on using 3Com Vortex (3c590, 3c592, 3c595, 3c597) Ethernet cards.
 wan-router.txt
diff -urN linux-2.4.2-pre1/Documentation/networking/smc9.txt linux/Documentation/networking/smc9.txt
--- linux-2.4.2-pre1/Documentation/networking/smc9.txt	Sat Nov 29 10:33:18 1997
+++ linux/Documentation/networking/smc9.txt	Mon Dec  3 22:27:48 2001
@@ -3,7 +3,7 @@
 Revision 0.12 
 3/5/96
 Copyright 1996  Erik Stahlman 
-Released under terms of the GNU public license. 
+Released under terms of the GNU General Public License. 
 
 This file contains the instructions and caveats for my SMC9xxx driver.  You
 should not be using the driver without reading this file.  
diff -urN linux-2.4.2-pre1/Documentation/scsi-generic.txt linux/Documentation/scsi-generic.txt
--- linux-2.4.2-pre1/Documentation/scsi-generic.txt	Mon Aug 21 08:57:35 2000
+++ linux/Documentation/scsi-generic.txt	Mon Dec  3 22:27:48 2001
@@ -314,7 +314,7 @@
 (limit is SG_MAX_QUEUE (16) outstanding packets per file descriptor).
 However, for backward compatibility, command queuing is turned off
 by default (#define SG_DEF_COMMAND_Q 0 in sg.h). This can be changed
-via the the SG_SET_COMMAND_Q ioctl() [or by recompiling after changing
+via the SG_SET_COMMAND_Q ioctl() [or by recompiling after changing
 the above define to 1].
 
 In this sg driver a write() should return more or less immediately.
diff -urN linux-2.4.2-pre1/Documentation/sound/Maestro3 linux/Documentation/sound/Maestro3
--- linux-2.4.2-pre1/Documentation/sound/Maestro3	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/sound/Maestro3	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,84 @@
+	An OSS/Lite Driver for the ESS Maestro3 family of sound chips
+
+			Zach Brown, January 2001
+
+Driver Status and Availability
+------------------------------
+
+The most recent version of this driver will hopefully always be available at
+	http://www.zabbo.net/maestro3/
+
+I will try and maintain the most recent stable version of the driver
+in both the stable and development kernel lines.
+
+Historically I've sucked pretty hard at actually doing that, however.
+
+ESS Maestro3 Chip Family
+-----------------------
+
+The 'Maestro3' is much like the Maestro2 chip.  The noted improvement
+is the removal of the silicon in the '2' that did PCM mixing.  All that
+work is now done through a custom DSP called the ASSP, the Asynchronus
+Specific Signal Processor.
+
+The 'Allegro' is a baby version of the Maestro3.  I'm not entirely clear
+on the extent of the differences, but the driver supports them both :)
+
+The 'Allegro' shows up as PCI ID 0x1988 and the Maestro3 as 0x1998,
+both under ESS's vendor ID of 0x125D.  The Maestro3 can also show up as
+0x199a when hardware strapping is used.
+
+The chip can also act as a multi function device.  The modem IDs follow
+the audio multimedia device IDs.  (so the modem part of an Allegro shows
+up as 0x1989)
+
+Driver OSS Behavior
+--------------------
+
+This OSS driver exports /dev/mixer and /dev/dsp to applications, which
+mostly adhere to the OSS spec.   This driver doesn't register itself
+with /dev/sndstat, so don't expect information to appear there.
+
+The /dev/dsp device exported behaves as expected.  Playback is
+supported in all the various lovely formats.  8/16bit stereo/mono from
+8khz to 48khz, with both read()/write(), and mmap().
+
+/dev/mixer is an interface to the AC'97 codec on the Maestro3.  It is
+worth noting that there are a variety of AC'97s that can be wired to
+the Maestro3.  Which is used is entirely up to the hardware implementor.
+This should only be visible to the user by the presence, or lack, of
+'Bass' and 'Treble' sliders in the mixer.  Not all AC'97s have them.
+The Allegro has an onchip AC'97.
+
+The driver doesn't support MIDI or FM playback at the moment.
+
+Compiling and Installing
+------------------------
+
+With the drivers inclusion into the kernel, compiling and installing
+is the same as most OSS/Lite modular sound drivers.  Compilation
+of the driver is enabled through the CONFIG_SOUND_MAESTRO3 variable
+in the config system.  
+
+It may be modular or statically linked.  If it is modular it should be
+installed with the rest of the modules for the kernel on the system.
+Typically this will be in /lib/modules/ somewhere.  'alias sound-slot-0
+maestro3' should also be added to your module configs (typically
+/etc/modules.conf) if you're using modular OSS/Lite sound and want to
+default to using a maestro3 chip.
+
+There are very few options to the driver.  One is 'debug' which will 
+tell the driver to print minimal debugging information as it runs.  This
+can be collected with 'dmesg' or through the klogd daemon.
+
+The other is 'external_amp', which tells the driver to attempt to enable
+an external amplifier.  This defaults to '1', you can tell the driver
+not to bother enabling such an amplifier by setting it to '0'.
+
+Power Management
+----------------
+
+This driver has a minimal understanding of PCI Power Management.  It will
+try and power down the chip when the system is suspended, and power
+it up with it is resumed.  It will also try and power down the chip
+when the machine is shut down.
diff -urN linux-2.4.2-pre1/Documentation/sound/NM256 linux/Documentation/sound/NM256
--- linux-2.4.2-pre1/Documentation/sound/NM256	Mon Oct 25 08:26:52 1999
+++ linux/Documentation/sound/NM256	Mon Dec  3 22:27:48 2001
@@ -53,7 +53,7 @@
 compatible OSS driver with these chipsets.  I cannot provide any
 assistance with machines using the SB16, AD1848 or CS4232 compatible
 versions.  (The driver now attempts to detect the mixer version, and
-will refuse to load if it believes the hardware is not not
+will refuse to load if it believes the hardware is not
 AC97-compatible.)
 
 The sound support is very basic, but it does include simultaneous
diff -urN linux-2.4.2-pre1/Documentation/sound/OPL3-SA2 linux/Documentation/sound/OPL3-SA2
--- linux-2.4.2-pre1/Documentation/sound/OPL3-SA2	Wed May 24 19:28:05 2000
+++ linux/Documentation/sound/OPL3-SA2	Mon Dec  3 22:27:48 2001
@@ -2,22 +2,26 @@
 ---------------------------------------------------------------
 
 Scott Murray, scott@spiteful.org
-January 5, 1999
+January 7, 2001
 
 NOTE: All trade-marked terms mentioned below are properties of their
       respective owners.
 
+
+Supported Devices
+-----------------
+
 This driver is for PnP soundcards based on the following Yamaha audio
 controller chipsets:
 
 YMF711 aka OPL3-SA2
-YMF715 aka OPL3-SA3
-YMF719 aka OPL3-SAx (?)
+YMF715 and YMF719 aka OPL3-SA3
 
-I'm a little fuzzy on what exactly is classified a SAx, as I've seen
-the label used to refer to the whole 7xx family and as a specific
-identifier for the 719 on my no-name soundcard.  To make matters
-worse, there seem to be several revisions of the 715 chipset.
+Up until recently (December 2000), I'd thought the 719 to be a
+different chipset, the OPL3-SAx.  After an email exhange with
+Yamaha, however, it turns out that the 719 is just a re-badged
+715, and the chipsets are identical.  The chipset detection code
+has been updated to refkect this.
 
 Anyways, all of these chipsets implement the following devices:
 
@@ -31,75 +35,142 @@
 device and the MSS device.  Since the MSS device has better
 capabilities, I have implemented the driver to use it.
 
-Being PnP cards, some configuration is required.  There are two ways
-of doing this.  The most common is to use the isapnptools package to
-initialize the card, and use the kernel module form of the sound
-subsystem and sound drivers.  Alternatively, some BIOS's allow manual
-configuration of installed PnP devices in a BIOS menu, which should
-allow using the non-modular sound drivers, i.e. built into the kernel.
+
+Mixer Channels
+--------------
+
+Older versions of this driver (pre-December 2000) had two mixers,
+an OPL3-SA2 or SA3 mixer and a MSS mixer.  The OPL3-SA[23] mixer
+device contained a superset of mixer channels consisting of its own
+channels and all of the MSS mixer channels.  To simplify the driver
+considerably, and to partition functionality better, the OPL3-SA[23]
+mixer device now contains has its own specific mixer channels.  They
+are:
+
+Volume     - Hardware master volume control
+Bass       - SA3 only, now supports left and right channels
+Treble     - SA3 only, now supports left and right channels
+Microphone - Hardware microphone input volume control
+Digital1   - Yamaha 3D enhancement "Wide" mixer
+
+All other mixer channels (e.g. "PCM", "CD", etc.) now have to be
+controlled via the "MS Sound System (CS4231)" mixer.  To facilitate
+this, the mixer device creation order has been switched so that
+the MSS mixer is created first.  This allows accessing the majority
+of the useful mixer channels even via single mixer-aware tools
+such as "aumix".
+
+
+Plug 'n Play
+------------
+
+In previous kernels (2.2.x), some configuration was required to
+get the driver to talk to the card.  Being the new millenium and
+all, the 2.4.x kernels now support auto-configuration if ISA PnP
+support is configured in.  Theoretically, the driver even supports
+having more than one card in this case.
+
+With the addition of PnP support to the driver, two new parameters
+have been added to control it:
+
+isapnp   - set to 0 to disable ISA PnP card detection
+
+multiple - set to 0 to disable multiple PnP card detection
+
+
+Optional Parameters
+-------------------
+
+Recent (December 2000) additions to the driver (based on a patch
+provided by Peter Englmaier) are two new parameters:
+
+ymode -    Set Yamaha 3D enhancement mode:
+           0 = Desktop/Normal  5-12 cm speakers
+           1 = Notebook PC (1) 3 cm speakers
+           2 = Notebook PC (2) 1.5 cm speakers
+           3 = Hi-Fi           16-38 cm speakers
+
+loopback - Set A/D input source. Useful for echo cancellation:
+           0 = Mic Right channel (default)
+           1 = Mono output loopback
+
+The ymode parameter has been tested and does work.  The loopback
+parameter, however, is untested.  Any feedback on its usefulness
+would be appreciated.
+
+
+Manual Configuration
+--------------------
+
+If for some reason you decide not to compile ISA PnP support into
+your kernel, or disabled the driver's usage of it by setting the
+isapnp parameter as discussed above, then you will need to do some
+manual configuration.  There are two ways of doing this.  The most
+common is to use the isapnptools package to initialize the card, and
+use the kernel module form of the sound subsystem and sound drivers.
+Alternatively, some BIOS's allow manual configuration of installed
+PnP devices in a BIOS menu, which should allow using the non-modular
+sound drivers, i.e. built into the kernel.
 
 I personally use isapnp and modules, and do not have access to a PnP
-BIOS machine to test.  If you have such a beast, try building both the
-MSS driver and this driver into the kernel (appropriately configured,
-of course).  I have received reports of this working, so it should be
-possible for most people with PnP BIOS.  If it does not work for you,
-then email me if you are willing to experiment in an effort to make it
-work.
-
-************************************************************************
-* I have now had two such machines, and I have fixed this to work
-* properly when built into the kernel.  The Toshiba Libretto series, or
-* at least models 70CT and 110CT which I have owned, use a Yamaha
-* OPL3-SAx (OPL3-SA3 according to documentation) sound chip, IRQ 5,
-* IO addresses 220/530/388/330/370 and DMA 1,0 (_not_ 0,1).  All these
-* configuration settings can be gathered by booting another OS which
-* recognizes the card already.
-*
-* I have made things 'just work' for the non-modular case on such
-* machines when configured properly.
-*
-* David Luyer <luyer@ucs.uwa.edu.au>
-************************************************************************
-
-If you are using isapnp, follow the directions in its documentation to
-produce a configuration file.  Here is the relevant excerpt I use for
-my SAx card from my isapnp.conf:
+BIOS machine to test.  If you have such a beast, configuring the
+driver to be built into the kernel should just work (thanks to work
+done by David Luyer <luyer@ucs.uwa.edu.au>).  You will still need
+to specify settings, which can be done by adding:
+
+opl3sa2=<io>,<irq>,<dma>,<dma2>,<mssio>,<mpuio>
+
+to the kernel command line.  For example:
+
+opl3sa2=0x370,5,0,1,0x530,0x330
+
+If you are instead using the isapnp tools (as most people have been
+before Linux 2.4.x), follow the directions in their documentation to
+produce a configuration file.  Here is the relevant excerpt I used to
+use for my SA3 card from my isapnp.conf:
 
 (CONFIGURE YMH0800/-1 (LD 0
 
-# Instead of (IO 0 (BASE 0x0220)), disable SB:
-(IO 0 (BASE 0x0000))
+# NOTE: IO 0 is for the unused SoundBlaster part of the chipset.
+(IO 0 (BASE 0x0220))
 (IO 1 (BASE 0x0530))
 (IO 2 (BASE 0x0388))
 (IO 3 (BASE 0x0330))
 (IO 4 (BASE 0x0370))
-(INT 0 (IRQ 7 (MODE +E)))
+(INT 0 (IRQ 5 (MODE +E)))
 (DMA 0 (CHANNEL 0))
-(DMA 1 (CHANNEL 3))
+(DMA 1 (CHANNEL 1))
 
 Here, note that:
 
 Port  Acceptable Range  Purpose
 ----  ----------------  -------
-IO 0  0x0220 - 0x0280   SB base address, I set to 0 just to be safe.
+IO 0  0x0220 - 0x0280   SB base address, unused.
 IO 1  0x0530 - 0x0F48   MSS base address
 IO 2  0x0388 - 0x03F8   OPL3 base address
 IO 3  0x0300 - 0x0334   MPU base address
 IO 4  0x0100 - 0x0FFE   card's own base address for its control I/O ports
 
-The IRQ and DMA values can be any that considered acceptable for a
+The IRQ and DMA values can be any that are considered acceptable for a
 MSS.  Assuming you've got isapnp all happy, then you should be able to
 do something like the following (which matches up with the isapnp
 configuration above):
 
-insmod mpu401
-insmod ad1848
-insmod opl3sa2 io=0x370 mss_io=0x530 mpu_io=0x330 irq=7 dma=0 dma2=3
-insmod opl3 io=0x388
-
-Remember that the opl3sa2 module's io argument is for it's own control
-port, which handles the card's master mixer for volume (on all cards),
-and bass and treble (on SA3 and SAx cards).
+modprobe mpu401
+modprobe ad1848
+modprobe opl3sa2 io=0x370 mss_io=0x530 mpu_io=0x330 irq=5 dma=0 dma2=1
+modprobe opl3 io=0x388
+
+See the section "Automatic Module Loading" below for how to set up
+/etc/modules.conf to automate this.
+
+An important thing to remember that the opl3sa2 module's io argument is
+for it's own control port, which handles the card's master mixer for
+volume (on all cards), and bass and treble (on SA3 cards).
+
+
+Troubleshooting
+---------------
 
 If all goes well and you see no error messages, you should be able to
 start using the sound capabilities of your system.  If you get an
@@ -112,29 +183,27 @@
 
 If you still cannot get the module to load, look at the contents of
 your system log file, usually /var/log/messages.  If you see the
-message "Unknown Yamaha audio controller version", then you have a
-different chipset than I've encountered so far.  Look for a line in
-the log file that says "opl3sa2.c: chipset version = <some number>".
-If you want me to add support for your card, send me the number from
-this line and any information you have on the make and chipset of your
-sound card, and I should be able to work up a permanent fix.
-
-If you do not see the chipset version message, and none of the other
-messages present in the system log are helpful, email me some details
-and I'll try my best to help.
+message "opl3sa2: Unknown Yamaha audio controller version", then you
+have a different chipset version than I've encountered so far.  Look
+for all messages in the log file that start with "opl3sa2: " and see
+if they provide any clues.  If you do not see the chipset version
+message, and none of the other messages present in the system log are
+helpful, email me some details and I'll try my best to help.
+
+
+Automatic Module Loading
+------------------------
 
 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 modules.conf file:
 
 # Sound
-alias char-major-14 opl3sa2
-pre-install opl3sa2 modprobe "-k" "ad1848"
-post-install opl3sa2 modprobe "-k" "opl3"
+alias sound-slot-0 opl3sa2
 options opl3sa2 io=0x370 mss_io=0x530 mpu_io=0x330 irq=7 dma=0 dma2=3
 options opl3 io=0x388
 
-That's all it currently takes to get an OPL3-SAx card working on my
+That's all it currently takes to get an OPL3-SA3 card working on my
 system.  Once again, if you have any other problems, email me at the
 address listed above.
 
diff -urN linux-2.4.2-pre1/Documentation/usb/usb-serial.txt linux/Documentation/usb/usb-serial.txt
--- linux-2.4.2-pre1/Documentation/usb/usb-serial.txt	Tue Jan 16 14:29:54 2001
+++ linux/Documentation/usb/usb-serial.txt	Mon Dec  3 22:27:48 2001
@@ -73,6 +73,11 @@
   the port to use for the HotSync transfer. The "Generic" port can be used
   for other device communication, such as a PPP link.
 
+  If after pressing the sync button, nothing shows up in the system log,
+  try resetting the Visor, first a hot reset, and then a cold reset if
+  necessary.  Some Visors need this before they can talk to the USB port
+  properly.
+  
   There is a webpage and mailing lists for this portion of the driver at: 
   http://usbvisor.sourceforge.net/
 
@@ -103,22 +108,22 @@
 
 Keyspan USA-series Serial Adapters
 
-  Single and Dual port adapters - driver uses Keyspan supplied 
+  Single, Dual and Quad port adapters - driver uses Keyspan supplied 
   firmware and is being developed with their support.
   
-  Driver isn't as far advanced as Keyspan PDA driver mentioned above.
-  
 Current status:
- Things that work:
-   Firmware upload for USA-18X, USA-28, USA-28X, USA-19 and USA-19W 
-   Simple character I/O fixed at 9600 baud on USA-19 only
-   
- Things that don't:
-   Everything else. (for now...)
+  The USA-18X, USA-28X, USA-19, USA-19W and USA-49W are supported and
+  have been pretty throughly tested at various baud rates with 8-N-1
+  character settings.  Other character lengths and parity setups are
+  presently untested.
+
+  The USA-28 isn't yet supported though doing so should be pretty
+  straightforward.  Contact the maintainer if you require this
+  functionality.
+  
+  More information is available at:
+        http://www.linuxcare.com.au/hugh/keyspan.html
    
- Big Things on the todo list:
-   Driver is in infancy, much functionality remains to be added
-
 
 FTDI Single Port Serial Driver
 
@@ -157,6 +162,7 @@
 Belkin USB Serial Adapter F5U103
 
   Single port DB-9/PS-2 serial adapter from Belkin with firmware by eTEK Labs.
+  The Peracom single port serial adapter also works with this driver.
 
 Current status:
   The following have been tested and work:
@@ -210,6 +216,11 @@
  The driver is generally working, though it still needs some more
  testing. It is derived from the Belkin USB Serial Adapter F5U103
  driver and its TODO list is valid for this driver as well.
+
+ This driver has also been found to work for other products, which have 
+ the same Vendor ID but different Product IDs. Sitecom's U232-P25 
+ serial converter uses Product ID 0x230 and Vendor ID 0x711 and works with 
+ this driver. Also, D-Link's DU-H3SP USB BAY also works with this driver.
 
 
 Generic Serial driver
diff -urN linux-2.4.2-pre1/MAINTAINERS linux/MAINTAINERS
--- linux-2.4.2-pre1/MAINTAINERS	Sun Jan 28 13:37:18 2001
+++ linux/MAINTAINERS	Mon Dec  3 22:27:48 2001
@@ -857,6 +857,12 @@
 M:	pavel@atrey.karlin.mff.cuni.cz
 S:	Maintained
 
+NETWORK DEVICE DRIVERS
+P:	Jeff Garzik
+M:	jgarzik@mandrakesoft.com
+L:	linux-net@vger.kernel.org
+S:	Maintained
+
 NETWORKING [GENERAL]
 P:	Networking Team
 M:	netdev@oss.sgi.com
diff -urN linux-2.4.2-pre1/Makefile linux/Makefile
--- linux-2.4.2-pre1/Makefile	Mon Dec  3 22:27:36 2001
+++ linux/Makefile	Mon Dec  3 22:27:48 2001
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 2
-EXTRAVERSION =-pre1
+EXTRAVERSION =-pre2
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
@@ -110,7 +110,7 @@
 export SVGA_MODE = -DSVGA_MODE=NORMAL_VGA
 
 #
-# if you want the RAM disk device, define this to be the size in blocks.
+# If you want the RAM disk device, define this to be the size in blocks.
 # This is i386 specific.
 #
 
@@ -138,7 +138,7 @@
 DRIVERS-$(CONFIG_ISDN) += drivers/isdn/isdn.a
 DRIVERS-$(CONFIG_NET_FC) += drivers/net/fc/fc.o
 DRIVERS-$(CONFIG_APPLETALK) += drivers/net/appletalk/appletalk.o
-DRIVERS-$(CONFIG_TR) += drivers/net/tokenring/tr.a
+DRIVERS-$(CONFIG_TR) += drivers/net/tokenring/tr.o
 DRIVERS-$(CONFIG_WAN) += drivers/net/wan/wan.o
 DRIVERS-$(CONFIG_ARCNET) += drivers/net/arcnet/arcnet.a
 DRIVERS-$(CONFIG_ATM) += drivers/atm/atm.o
diff -urN linux-2.4.2-pre1/arch/alpha/kernel/alpha_ksyms.c linux/arch/alpha/kernel/alpha_ksyms.c
--- linux-2.4.2-pre1/arch/alpha/kernel/alpha_ksyms.c	Sun Nov 12 19:27:11 2000
+++ linux/arch/alpha/kernel/alpha_ksyms.c	Mon Dec  3 22:27:48 2001
@@ -98,6 +98,8 @@
 EXPORT_SYMBOL(__memset);
 EXPORT_SYMBOL(__memsetw);
 EXPORT_SYMBOL(__constant_c_memset);
+EXPORT_SYMBOL(copy_page);
+EXPORT_SYMBOL(clear_page);
 
 EXPORT_SYMBOL(__direct_map_base);
 EXPORT_SYMBOL(__direct_map_size);
diff -urN linux-2.4.2-pre1/arch/alpha/kernel/osf_sys.c linux/arch/alpha/kernel/osf_sys.c
--- linux-2.4.2-pre1/arch/alpha/kernel/osf_sys.c	Wed Jan 24 15:16:23 2001
+++ linux/arch/alpha/kernel/osf_sys.c	Mon Dec  3 22:27:48 2001
@@ -74,8 +74,10 @@
 	mm = current->mm;
 	mm->end_code = bss_start + bss_len;
 	mm->brk = bss_start + bss_len;
+#if 0
 	printk("set_program_attributes(%lx %lx %lx %lx)\n",
 		text_start, text_len, bss_start, bss_len);
+#endif
 	unlock_kernel();
 	return 0;
 }
diff -urN linux-2.4.2-pre1/arch/alpha/kernel/process.c linux/arch/alpha/kernel/process.c
--- linux-2.4.2-pre1/arch/alpha/kernel/process.c	Tue Sep  5 13:50:02 2000
+++ linux/arch/alpha/kernel/process.c	Mon Dec  3 22:27:48 2001
@@ -416,22 +416,20 @@
  * Don't do this at home.
  */
 asmlinkage int
-sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
-	unsigned long a3, unsigned long a4, unsigned long a5,
-	struct pt_regs regs)
+sys_execve(char *ufilename, char **argv, char **envp,
+	   unsigned long a3, unsigned long a4, unsigned long a5,
+	   struct pt_regs regs)
 {
 	int error;
-	char * filename;
+	char *filename;
 
-	lock_kernel();
-	filename = getname((char *) a0);
+	filename = getname(ufilename);
 	error = PTR_ERR(filename);
 	if (IS_ERR(filename))
 		goto out;
-	error = do_execve(filename, (char **) a1, (char **) a2, &regs);
+	error = do_execve(filename, argv, envp, &regs);
 	putname(filename);
 out:
-	unlock_kernel();
 	return error;
 }
 
diff -urN linux-2.4.2-pre1/arch/alpha/kernel/sys_ruffian.c linux/arch/alpha/kernel/sys_ruffian.c
--- linux-2.4.2-pre1/arch/alpha/kernel/sys_ruffian.c	Mon Nov 27 17:50:12 2000
+++ linux/arch/alpha/kernel/sys_ruffian.c	Mon Dec  3 22:27:48 2001
@@ -92,14 +92,80 @@
 #endif
 }
 
+/*
+ *  Interrupt routing:
+ *
+ *		Primary bus
+ *	  IdSel		INTA	INTB	INTC	INTD
+ * 21052   13		  -	  -	  -	  -
+ * SIO	   14		 23	  -	  -	  -
+ * 21143   15		 44	  -	  -	  -
+ * Slot 0  17		 43	 42	 41	 40
+ *
+ *		Secondary bus
+ *	  IdSel		INTA	INTB	INTC	INTD
+ * Slot 0   8 (18)	 19	 18	 17	 16
+ * Slot 1   9 (19)	 31	 30	 29	 28
+ * Slot 2  10 (20)	 27	 26	 25	 24
+ * Slot 3  11 (21)	 39	 38	 37	 36
+ * Slot 4  12 (22)	 35	 34	 33	 32
+ * 53c875  13 (23)	 20	  -	  -	  -
+ *
+ */
+
 static int __init
 ruffian_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 {
-	/* We don't know anything about the PCI routing, so leave
-	   the IRQ unchanged.  */
-	return dev->irq;
+        static char irq_tab[11][5] __initdata = {
+	      /*INT  INTA INTB INTC INTD */
+		{-1,  -1,  -1,  -1,  -1},  /* IdSel 13,  21052	     */
+		{-1,  -1,  -1,  -1,  -1},  /* IdSel 14,  SIO	     */
+		{44,  44,  44,  44,  44},  /* IdSel 15,  21143	     */
+		{-1,  -1,  -1,  -1,  -1},  /* IdSel 16,  none	     */
+		{43,  43,  42,  41,  40},  /* IdSel 17,  64-bit slot */
+		/* the next 6 are actually on PCI bus 1, across the bridge */
+		{19,  19,  18,  17,  16},  /* IdSel  8,  slot 0	     */
+		{31,  31,  30,  29,  28},  /* IdSel  9,  slot 1	     */
+		{27,  27,  26,  25,  24},  /* IdSel 10,  slot 2	     */
+		{39,  39,  38,  37,  36},  /* IdSel 11,  slot 3	     */
+		{35,  35,  34,  33,  32},  /* IdSel 12,  slot 4	     */
+		{20,  20,  20,  20,  20},  /* IdSel 13,  53c875	     */
+        };
+	const long min_idsel = 13, max_idsel = 23, irqs_per_slot = 5;
+	return COMMON_TABLE_LOOKUP;
 }
 
+static u8 __init
+ruffian_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+	int slot, pin = *pinp;
+
+	if (dev->bus->number == 0) {
+		slot = PCI_SLOT(dev->devfn);
+	}		
+	/* Check for the built-in bridge.  */
+	else if (PCI_SLOT(dev->bus->self->devfn) == 13) {
+		slot = PCI_SLOT(dev->devfn) + 10;
+	}
+	else 
+	{
+		/* Must be a card-based bridge.  */
+		do {
+			if (PCI_SLOT(dev->bus->self->devfn) == 13) {
+				slot = PCI_SLOT(dev->devfn) + 10;
+				break;
+			}
+			pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
+
+			/* Move up the chain of bridges.  */
+			dev = dev->bus->self;
+			/* Slot of the next bridge.  */
+			slot = PCI_SLOT(dev->devfn);
+		} while (dev->bus->self);
+	}
+	*pinp = pin;
+	return slot;
+}
 
 #ifdef BUILDING_FOR_MILO
 /*
@@ -164,6 +230,6 @@
 	init_pci:		cia_init_pci,
 	kill_arch:		ruffian_kill_arch,
 	pci_map_irq:		ruffian_map_irq,
-	pci_swizzle:		common_swizzle,
+	pci_swizzle:		ruffian_swizzle,
 };
 ALIAS_MV(ruffian)
diff -urN linux-2.4.2-pre1/arch/alpha/kernel/traps.c linux/arch/alpha/kernel/traps.c
--- linux-2.4.2-pre1/arch/alpha/kernel/traps.c	Mon Jun 19 17:59:33 2000
+++ linux/arch/alpha/kernel/traps.c	Mon Dec  3 22:27:48 2001
@@ -1093,7 +1093,9 @@
 {
 	/* We only get here for OSF system calls, minus #112;
 	   the rest go to sys_ni_syscall.  */
+#if 0
 	printk("<sc %ld(%lx,%lx,%lx)>", regs.r0, a0, a1, a2);
+#endif
 	return -ENOSYS;
 }
 
diff -urN linux-2.4.2-pre1/arch/alpha/lib/Makefile linux/arch/alpha/lib/Makefile
--- linux-2.4.2-pre1/arch/alpha/lib/Makefile	Sat Dec 30 11:13:36 2000
+++ linux/arch/alpha/lib/Makefile	Mon Dec  3 22:27:48 2001
@@ -42,6 +42,8 @@
 	$(ev6)strncpy_from_user.o \
 	$(ev67)strlen_user.o \
 	$(ev6)csum_ipv6_magic.o \
+	$(ev6)clear_page.o \
+	$(ev6)copy_page.o \
 	strcasecmp.o \
 	fpreg.o \
 	callback_srm.o srm_puts.o srm_printk.o
diff -urN linux-2.4.2-pre1/arch/alpha/lib/clear_page.S linux/arch/alpha/lib/clear_page.S
--- linux-2.4.2-pre1/arch/alpha/lib/clear_page.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/alpha/lib/clear_page.S	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,39 @@
+/*
+ * arch/alpha/lib/clear_page.S
+ *
+ * Zero an entire page.
+ */
+
+	.text
+	.align 4
+	.global clear_page
+	.ent clear_page
+clear_page:
+	.prologue 0
+
+	lda	$0,128
+	nop
+	unop
+	nop
+
+1:	stq	$31,0($16)
+	stq	$31,8($16)
+	stq	$31,16($16)
+	stq	$31,24($16)
+
+	stq	$31,32($16)
+	stq	$31,40($16)
+	stq	$31,48($16)
+	subq	$0,1,$0
+
+	stq	$31,56($16)
+	addq	$16,64,$16
+	unop
+	bne	$0,1b
+
+	ret
+	nop
+	unop
+	nop
+
+	.end clear_page
diff -urN linux-2.4.2-pre1/arch/alpha/lib/copy_page.S linux/arch/alpha/lib/copy_page.S
--- linux-2.4.2-pre1/arch/alpha/lib/copy_page.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/alpha/lib/copy_page.S	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,49 @@
+/*
+ * arch/alpha/lib/copy_page.S
+ *
+ * Copy an entire page.
+ */
+
+	.text
+	.align 4
+	.global copy_page
+	.ent copy_page
+copy_page:
+	.prologue 0
+
+	lda	$18,128
+	nop
+	unop
+	nop
+
+1:	ldq	$0,0($17)
+	ldq	$1,8($17)
+	ldq	$2,16($17)
+	ldq	$3,24($17)
+
+	ldq	$4,32($17)
+	ldq	$5,40($17)
+	ldq	$6,48($17)
+	ldq	$7,56($17)
+
+	stq	$0,0($16)
+	subq	$18,1,$18
+	stq	$1,8($16)
+	addq	$17,64,$17
+
+	stq	$2,16($16)
+	stq	$3,24($16)
+	stq	$4,32($16)
+	stq	$5,40($16)
+
+	stq	$6,48($16)
+	stq	$7,56($16)
+	addq	$16,64,$16
+	bne	$18, 1b
+
+	ret
+	nop
+	unop
+	nop
+
+	.end copy_page
diff -urN linux-2.4.2-pre1/arch/alpha/lib/ev6-clear_page.S linux/arch/alpha/lib/ev6-clear_page.S
--- linux-2.4.2-pre1/arch/alpha/lib/ev6-clear_page.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/alpha/lib/ev6-clear_page.S	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,54 @@
+/*
+ * arch/alpha/lib/ev6-clear_page.S
+ *
+ * Zero an entire page.
+ */
+
+        .text
+        .align 4
+        .global clear_page
+        .ent clear_page
+clear_page:
+        .prologue 0
+
+	lda	$0,128
+	lda	$1,125
+	addq	$16,64,$2
+	addq	$16,128,$3
+
+	addq	$16,192,$17
+	wh64	($16)
+	wh64	($2)
+	wh64	($3)
+
+1:	wh64	($17)
+	stq	$31,0($16)
+	subq	$0,1,$0
+	subq	$1,1,$1
+
+	stq	$31,8($16)
+	stq	$31,16($16)
+	addq	$17,64,$2
+	nop
+
+	stq	$31,24($16)
+	stq	$31,32($16)
+	cmovgt	$1,$2,$17
+	nop
+
+	stq	$31,40($16)
+	stq	$31,48($16)
+	nop
+	nop
+
+	stq	$31,56($16)
+	addq	$16,64,$16
+	nop
+	bne	$0,1b
+
+	ret
+	nop
+	nop
+	nop
+
+	.end clear_page
diff -urN linux-2.4.2-pre1/arch/alpha/lib/ev6-copy_page.S linux/arch/alpha/lib/ev6-copy_page.S
--- linux-2.4.2-pre1/arch/alpha/lib/ev6-copy_page.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/alpha/lib/ev6-copy_page.S	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,203 @@
+/*
+ * arch/alpha/lib/ev6-copy_page.S
+ *
+ * Copy an entire page.
+ */
+
+/* The following comparison of this routine vs the normal copy_page.S
+   was written by an unnamed ev6 hardware designer and forwarded to me
+   via Steven Hobbs <hobbs@steven.zko.dec.com>.
+ 
+   First Problem: STQ overflows.
+   -----------------------------
+
+	It would be nice if EV6 handled every resource overflow efficiently,
+	but for some it doesn't.  Including store queue overflows.  It causes
+	a trap and a restart of the pipe.
+
+	To get around this we sometimes use (to borrow a term from a VSSAD
+	researcher) "aeration".  The idea is to slow the rate at which the
+	processor receives valid instructions by inserting nops in the fetch
+	path.  In doing so, you can prevent the overflow and actually make
+	the code run faster.  You can, of course, take advantage of the fact
+	that the processor can fetch at most 4 aligned instructions per cycle.
+
+	I inserted enough nops to force it to take 10 cycles to fetch the
+	loop code.  In theory, EV6 should be able to execute this loop in
+	9 cycles but I was not able to get it to run that fast -- the initial
+	conditions were such that I could not reach this optimum rate on
+	(chaotic) EV6.  I wrote the code such that everything would issue
+	in order. 
+
+   Second Problem: Dcache index matches.
+   -------------------------------------
+
+	If you are going to use this routine on random aligned pages, there
+	is a 25% chance that the pages will be at the same dcache indices.
+	This results in many nasty memory traps without care.
+
+	The solution is to schedule the prefetches to avoid the memory
+	conflicts.  I schedule the wh64 prefetches farther ahead of the
+	read prefetches to avoid this problem.
+
+   Third Problem: Needs more prefetching.
+   --------------------------------------
+
+	In order to improve the code I added deeper prefetching to take the
+	most advantage of EV6's bandwidth.
+
+	I also prefetched the read stream. Note that adding the read prefetch
+	forced me to add another cycle to the inner-most kernel - up to 11
+	from the original 8 cycles per iteration.  We could improve performance
+	further by unrolling the loop and doing multiple prefetches per cycle.
+
+   I think that the code below will be very robust and fast code for the
+   purposes of copying aligned pages.  It is slower when both source and
+   destination pages are in the dcache, but it is my guess that this is
+   less important than the dcache miss case.  */
+
+
+	.text
+	.align 4
+	.global copy_page
+	.ent copy_page
+copy_page:
+	.prologue 0
+
+	/* Prefetch 5 read cachelines; write-hint 10 cache lines.  */
+	wh64	($16)
+	ldl	$31,0($17)
+	ldl	$31,64($17)
+	lda	$1,1*64($16)
+
+	wh64	($1)
+	ldl	$31,128($17)
+	ldl	$31,192($17)
+	lda	$1,2*64($16)
+
+	wh64	($1)
+	ldl	$31,256($17)
+	lda	$18,118
+	lda	$1,3*64($16)
+
+	wh64	($1)
+	nop
+	lda	$1,4*64($16)
+	lda	$2,5*64($16)
+
+	wh64	($1)
+	wh64	($2)
+	lda	$1,6*64($16)
+	lda	$2,7*64($16)
+
+	wh64	($1)
+	wh64	($2)
+	lda	$1,8*64($16)
+	lda	$2,9*64($16)
+
+	wh64	($1)
+	wh64	($2)
+	lda	$19,10*64($16)
+	nop
+
+	/* Main prefetching/write-hinting loop.  */
+1:	ldq	$0,0($17)
+	ldq	$1,8($17)
+	unop
+	unop
+
+	unop
+	unop
+	ldq	$2,16($17)
+	ldq	$3,24($17)
+
+	ldq	$4,32($17)
+	ldq	$5,40($17)
+	unop
+	unop
+
+	unop
+	unop
+	ldq	$6,48($17)
+	ldq	$7,56($17)
+
+	ldl	$31,320($17)
+	unop
+	unop
+	unop
+
+	/* This gives the extra cycle of aeration above the minimum.  */
+	unop			
+	unop
+	unop
+	unop
+
+	wh64	($19)
+	unop
+	unop
+	unop
+
+	stq	$0,0($16)
+	subq	$18,1,$18
+	stq	$1,8($16)
+	unop
+
+	unop
+	stq	$2,16($16)
+	addq	$17,64,$17
+	stq	$3,24($16)
+
+	stq	$4,32($16)
+	stq	$5,40($16)
+	addq	$19,64,$19
+	unop
+
+	stq	$6,48($16)
+	stq	$7,56($16)
+	addq	$16,64,$16
+	bne	$18, 1b
+
+	/* Prefetch the final 5 cache lines of the read stream.  */
+	lda	$18,10
+	ldl	$31,320($17)
+	ldl	$31,384($17)
+	ldl	$31,448($17)
+
+	ldl	$31,512($17)
+	ldl	$31,576($17)
+	nop
+	nop
+
+	/* Non-prefetching, non-write-hinting cleanup loop for the
+	   final 10 cache lines.  */
+2:	ldq	$0,0($17)
+	ldq	$1,8($17)
+	ldq	$2,16($17)
+	ldq	$3,24($17)
+
+	ldq	$4,32($17)
+	ldq	$5,40($17)
+	ldq	$6,48($17)
+	ldq	$7,56($17)
+
+	stq	$0,0($16)
+	subq	$18,1,$18
+	stq	$1,8($16)
+	addq	$17,64,$17
+
+	stq	$2,16($16)
+	stq	$3,24($16)
+	stq	$4,32($16)
+	stq	$5,40($16)
+
+	stq	$6,48($16)
+	stq	$7,56($16)
+	addq	$16,64,$16
+	bne	$18, 2b
+
+	ret
+	nop
+	unop
+	nop
+
+	.end copy_page
diff -urN linux-2.4.2-pre1/arch/arm/Makefile linux/arch/arm/Makefile
--- linux-2.4.2-pre1/arch/arm/Makefile	Mon Sep 18 15:15:24 2000
+++ linux/arch/arm/Makefile	Mon Dec  3 22:27:48 2001
@@ -12,25 +12,18 @@
 #
 # Copyright (C) 1995-2000 by Russell King
 
-OBJCOPY		:= $(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S
-CPP		:= $(CC) -E
-LINKFLAGS	:= -p -X -T arch/arm/vmlinux.lds
-ARCHCC		:= $(word 1,$(CC))
-
-AFLAGS		+= -mno-fpu
-CFLAGS_PIPE	:= -pipe
-CFLAGS		:= $(CFLAGS) $(CFLAGS_PIPE) -msoft-float
+LINKFLAGS	:=-p -X -T arch/arm/vmlinux.lds
+GZFLAGS		:=-9
+CFLAGS		+=-fno-common -pipe
 
 ifdef CONFIG_FRAME_POINTER
-CFLAGS		:= $(CFLAGS:-fomit-frame-pointer=)
+CFLAGS		:=$(CFLAGS:-fomit-frame-pointer=)
 endif
 
 ifdef CONFIG_DEBUG_INFO
-CFLAGS		+= -g
+CFLAGS		+=-g
 endif
 
-GZFLAGS		= -9
-
 # Ensure this is ld "2.9.4" or later
 NEW_LINKER	:= $(shell $(LD) --gc-sections --version >/dev/null 2>&1; echo $$?)
 
@@ -40,61 +33,42 @@
 		@false
 endif
 
-# GCC 2.7 uses different options to later compilers; sort out which we have
-NEW_GCC		:= $(shell $(CC) --version 2>&1 | grep '^2\.7' > /dev/null; echo $$?)
-
-#
-# select flags depending on the compiler
+# Select CPU dependent flags.  Note that order of declaration is important;
+# the options further down the list override previous items.
 #
-ifneq ($(NEW_GCC),0)
-CFLAGS			+= -mshort-load-bytes
-CFLAGS_PROC_CPU_26	:= -mcpu=arm3 -mapcs-26 -Os
-CFLAGS_PROC_CPU_32v3	:= -march=armv3
-CFLAGS_PROC_CPU_32v4	:= -march=armv4
-else
-CFLAGS			+= -DNO_TEXT_SECTIONS
-CFLAGS_PROC_CPU_26	:= -m3
-CFLAGS_PROC_CPU_32v3	:= -m6
-CFLAGS_PROC_CPU_32v4	:= -m6
-endif
+apcs-$(CONFIG_CPU_26)		:=-mapcs-26 -mcpu=arm3 -Os
+apcs-$(CONFIG_CPU_32)		:=-mapcs-32
+
+arch-$(CONFIG_CPU_32v3)		:=-march=armv3
+arch-$(CONFIG_CPU_32v4)		:=-march=armv4
+arch-$(CONFIG_CPU_32v5)		:=-march=armv5
+
+proc-$(CONFIG_CPU_32v3)		:=-marmv3m
+proc-$(CONFIG_CPU_32v4)		:=-marmv4
+proc-$(CONFIG_CPU_32v5)		:=-marmv5
+
+tune-$(CONFIG_CPU_ARM610)	:=-mtune=arm610
+tune-$(CONFIG_CPU_ARM710)	:=-mtune=arm710
+tune-$(CONFIG_CPU_ARM720T)	:=-mtune=arm7tdmi
+tune-$(CONFIG_CPU_ARM920T)	:=-mtune=arm9tdmi
+tune-$(CONFIG_CPU_SA110)	:=-mtune=strongarm110
+tune-$(CONFIG_CPU_SA1100)	:=-mtune=strongarm1100
+
+CFLAGS		+= $(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float
+AFLAGS		+= $(apcs-y) $(proc-y) -mno-fpu
+
+LIBGCC		:= $(shell $(CC) $(CFLAGS) --print-libgcc-file-name)
 
-#
-# Select CPU dependent flags
-#
 ifeq ($(CONFIG_CPU_26),y)
- PROCESSOR	 = armo
- TEXTADDR	 = 0x02080000
- CFLAGS		+= $(CFLAGS_PROC_CPU_26)
- AFLAGS		+= -mapcs-26
+PROCESSOR	 = armo
+TEXTADDR	 = 0x02080000
 endif
 
 ifeq ($(CONFIG_CPU_32),y)
- PROCESSOR	 = armv
- TEXTADDR	 = 0xC0008000
- ifeq ($(CONFIG_CPU_32v4),y)
-  CFLAGS	+= $(CFLAGS_PROC_CPU_32v4)
-  AFLAGS	+= -mapcs-32 -marmv4
- else
-  CFLAGS	+= $(CFLAGS_PROC_CPU_32v3)
-  AFLAGS	+= -mapcs-32 -marmv3m
- endif
-
- opt-$(CONFIG_CPU_ARM6)		:= -mtune=arm6
- opt-$(CONFIG_CPU_ARM7)		:= -mtune=arm7
- opt-$(CONFIG_CPU_ARM720)	:= -mtune=arm7tdmi
- opt-$(CONFIG_CPU_ARM920)	:= -mtune=arm9tdmi
- opt-$(CONFIG_CPU_SA110)	:= -mtune=strongarm110
- opt-$(CONFIG_CPU_SA1100)	:= -mtune=strongarm110
-
- ifneq ($(NEW_GCC),0)
- CFLAGS	+= $(opt-y)
- endif
+PROCESSOR	 = armv
+TEXTADDR	 = 0xC0008000
 endif
 
-LIBGCC		:= $(shell $(CC) $(CFLAGS) --print-libgcc-file-name)
-
-export	LIBGCC MACHINE PROCESSOR TEXTADDR GZFLAGS
-
 ifeq ($(CONFIG_ARCH_ARCA5K),y)
 MACHINE		 = arc
 endif
@@ -132,6 +106,10 @@
 endif
 
 ifeq ($(CONFIG_ARCH_SA1100),y)
+ifeq ($(CONFIG_SA1111),y)
+# SA1111 DMA bug: we don't want the kernel to live in precious DMA-able memory
+TEXTADDR	 = 0xc0208000
+endif
 MACHINE		 = sa1100
 endif
 
@@ -143,6 +121,13 @@
 MACHINE		 = integrator
 endif
 
+ifeq ($(CONFIG_ARCH_CLPS711X),y)
+TEXTADDR	 = 0xc0018000
+MACHINE		 = clps711x
+endif
+
+export	LIBGCC MACHINE PROCESSOR TEXTADDR GZFLAGS
+
 # Only set INCDIR if its not already defined above
 # Grr, ?= doesn't work as all the other assignment operators do.  Make bug?
 ifeq ($(origin INCDIR), undefined)
@@ -158,8 +143,7 @@
 
 HEAD		:= arch/arm/kernel/head-$(PROCESSOR).o \
 		   arch/arm/kernel/init_task.o
-SUBDIRS		+= arch/arm/kernel arch/arm/mm arch/arm/lib \
-		   arch/arm/nwfpe
+SUBDIRS		+= arch/arm/kernel arch/arm/mm arch/arm/lib arch/arm/nwfpe
 CORE_FILES	:= arch/arm/kernel/kernel.o arch/arm/mm/mm.o $(CORE_FILES)
 LIBS		:= arch/arm/lib/lib.o arch/arm/lib/lib.a $(LIBS) $(LIBGCC)
 
@@ -167,14 +151,6 @@
 LIBS		:= arch/arm/nwfpe/math-emu.o $(LIBS)
 endif
 
-ifeq ($(CONFIG_ARCH_ACORN),y)
-SUBDIRS		+= drivers/acorn
-DRIVERS		+= drivers/acorn/block/acorn-block.a
-DRIVERS		+= drivers/acorn/char/acorn-char.o
-DRIVERS		+= drivers/acorn/net/acorn-net.o
-DRIVERS		+= drivers/acorn/scsi/acorn-scsi.a
-endif
-
 ifeq ($(CONFIG_ARCH_CLPS7500),y)
 SUBDIRS		+= drivers/acorn/char
 DRIVERS		+= drivers/acorn/char/acorn-char.o
@@ -230,6 +206,7 @@
 Img:;	@$(MAKEBOOT) Image
 i:;	@$(MAKEBOOT) install
 zi:;	@$(MAKEBOOT) zinstall
+bp:;	@$(MAKEBOOT) bootpImage
 
 #
 # Configuration targets.  Use these to select a
@@ -237,9 +214,10 @@
 CFGS=	a5k_config		ebsa110_config		\
 	footbridge_config	rpc_config		\
 	brutus_config		victor_config		\
-	empeg_config		thinclient_config	\
+	empeg_config		graphicsclient_config	\
 	assabet_config		lart_config		\
-	cerf_config		lusl7200_config 
+	cerf_config		lusl7200_config 	\
+	sherman_config		pangolin_config
 
 $(CFGS):
 	@( \
diff -urN linux-2.4.2-pre1/arch/arm/boot/Makefile linux/arch/arm/boot/Makefile
--- linux-2.4.2-pre1/arch/arm/boot/Makefile	Mon Nov 27 17:07:59 2000
+++ linux/arch/arm/boot/Makefile	Mon Dec  3 22:27:48 2001
@@ -83,15 +83,18 @@
 ZRELADDR	 = 0xc0008000
 ifeq ($(CONFIG_SA1100_VICTOR),y)
   ZTEXTADDR	 = 0x00002000
-  ZBSSADDR	 = 0xc0100000
+  ZBSSADDR	 = 0xc0200000
 endif
 ifeq ($(CONFIG_SA1100_SHERMAN),y)
   ZTEXTADDR      = 0x00050000   
-  ZBSSADDR       = 0xc0100000
+  ZBSSADDR       = 0xc0200000
 endif
 ifeq ($(CONFIG_SA1100_GRAPHICSCLIENT),y)
   ZTEXTADDR	 = 0xC0200000
 endif
+ifeq ($(CONFIG_SA1111),y)
+  ZRELADDR	 = 0xc0208000
+endif
 endif
 
 #
@@ -105,15 +108,15 @@
 export	SYSTEM ZTEXTADDR ZBSSADDR ZRELADDR INITRD_PHYS INITRD_VIRT PARAMS_PHYS
 
 Image:	$(CONFIGURE) $(SYSTEM)
-	$(OBJCOPY) $(SYSTEM) $@
+	$(OBJCOPY) -O binary -R .note -R .comment -S $(SYSTEM) $@
 
 bzImage: zImage
 
 zImage:	$(CONFIGURE) compressed/vmlinux
-	$(OBJCOPY) compressed/vmlinux $@
+	$(OBJCOPY) -O binary -R .note -R .comment -S compressed/vmlinux $@
 
 bootpImage: bootp/bootp
-	$(OBJCOPY) bootp/bootp $@
+	$(OBJCOPY) -O binary -R .note -R .comment -S bootp/bootp $@
 
 compressed/vmlinux: $(TOPDIR)/vmlinux dep
 	@$(MAKE) -C compressed vmlinux
diff -urN linux-2.4.2-pre1/arch/arm/boot/bootp/Makefile linux/arch/arm/boot/bootp/Makefile
--- linux-2.4.2-pre1/arch/arm/boot/bootp/Makefile	Sun Sep  3 11:19:11 2000
+++ linux/arch/arm/boot/bootp/Makefile	Mon Dec  3 22:27:48 2001
@@ -7,7 +7,8 @@
 ZLDFLAGS	=-p -X -T bootp.lds \
 		 --defsym initrd_addr=$(INITRD_PHYS) \
 		 --defsym initrd_virt=$(INITRD_VIRT) \
-		 --defsym params=$(PARAMS_PHYS)
+		 --defsym params=$(PARAMS_PHYS) \
+		 --defsym kernel_addr=$(ZTEXTADDR)
 
 all:		bootp
 
diff -urN linux-2.4.2-pre1/arch/arm/boot/bootp/init.S linux/arch/arm/boot/bootp/init.S
--- linux-2.4.2-pre1/arch/arm/boot/bootp/init.S	Mon Sep 18 15:15:24 2000
+++ linux/arch/arm/boot/bootp/init.S	Mon Dec  3 22:27:48 2001
@@ -12,33 +12,59 @@
  */
 		.section .start,#alloc,#execinstr
 		.type	_entry, #function
-_entry:
-kernel_addr:	adr	r10, initdata
-		ldmia	r10, {r11, r12}
+_entry:		adr	r10, initdata
+		ldr	r11, initdata
 		sub	r11, r10, r11		@ work out exec offset
-		add	r12, r12, r11		@ correct "splitify"
-		mov	pc, r12			@ jump to splitify
+		b	splitify
 		.size	_entry,. - _entry
 
 		.type	initdata, #object
 initdata:	.word	initdata		@ compiled address of this
-		.word	splitify
 		.size	initdata,. - initdata
 
 		.text
 splitify:	adr	r13, data
-		ldmia	r13!, {r4-r6}		@ move the kernel
+		ldmia	r13!, {r4-r6}		@ move the initrd
 		add	r4, r4, r11		@ correction
-		mov	r12, r5
 		bl	move
 
-		ldmia	r13!, {r4-r6}		@ then the initrd
+		ldmia	r13!, {r4-r6}		@ then the kernel
+		mov	r12, r5
 		add	r4, r4, r11		@ correction
 		bl	move
 
-		ldmib	r13, {r5,r6,r7}		@ get size and addr of initrd
-		add	r7, r7, #16*4		@ offset of initrd_start in param_struct
-		stmia	r7, {r5,r6}		@ save in param_struct
+/*
+ * Setup the initrd parameters to pass to the kernel.  This can either be
+ * passed in via a param_struct or a tag list.  We spot the param_struct
+ * method by looking at the first word; this should either indicate a page
+ * size of 4K, 16K or 32K.
+ */
+		ldmia	r13, {r5-r8}		@ get size and addr of initrd
+						@ r5 = ATAG_INITRD
+						@ r6 = initrd start
+						@ r7 = initrd end
+						@ r8 = param_struct address
+		ldr	r9, [r8, #0]		@ no param struct?
+		teq	r9, #0x1000		@ 4K?
+		teqne	r9, #0x4000		@ 16K?
+		teqne	r9, #0x8000		@ 32K?
+		beq	no_taglist
+
+/*
+ * find the end of the tag list, and then add an INITRD tag on the end.
+ */
+taglist:	ldr	r9, [r8, #0]		@ tag length
+		teq	r9, #0			@ last tag?
+		addne	r8, r8, r9
+		bne	taglist
+
+		mov	r4, #16			@ length of initrd tag
+		mov	r9, #0			@ end of tag list terminator
+		stmia	r8, {r4, r5, r6, r7, r9}
+		mov	pc, r12			@ call kernel
+
+no_taglist:	add	r8, r8, #16*4
+		stmia	r8, {r6,r7}		@ save in param_struct
 		mov	pc, r12			@ call kernel
 
 move:		ldmia	r4!, {r7 - r10}		@ move 32-bytes at a time
@@ -49,17 +75,18 @@
 		bcs	move
 		mov	pc, lr
 
-data:		.word	kernel_start
-		.word	kernel_addr
-		.word	kernel_len
-
-		.word	initrd_start
+data:		.word	initrd_start
 		.word	initrd_addr
 		.word	initrd_len
 
-		.word	initrd_virt
-		.word	initrd_len
-		.word	params
+		.word	kernel_start
+		.word	kernel_addr
+		.word	kernel_len
+
+		.word	0x54410005		@ r5 = ATAG_INITRD
+		.word	initrd_virt		@ r6
+		.word	initrd_len		@ r7
+		.word	params			@ r8
 
 		.type	kernel_start,#object
 		.type	initrd_start,#object
diff -urN linux-2.4.2-pre1/arch/arm/boot/compressed/Makefile linux/arch/arm/boot/compressed/Makefile
--- linux-2.4.2-pre1/arch/arm/boot/compressed/Makefile	Mon Nov 27 17:07:59 2000
+++ linux/arch/arm/boot/compressed/Makefile	Mon Dec  3 22:27:48 2001
@@ -66,7 +66,7 @@
 		$(CC) $(AFLAGS) -traditional -c $(HEAD:.o=.S)
 
 piggy.o:	$(SYSTEM)
-		$(OBJCOPY) $(SYSTEM) piggy
+		$(OBJCOPY) -O binary -R .note -R .comment -S $(SYSTEM) piggy
 		gzip $(GZFLAGS) < piggy > piggy.gz
 		$(LD) -r -o $@ -b binary piggy.gz
 		rm -f piggy piggy.gz
diff -urN linux-2.4.2-pre1/arch/arm/boot/compressed/head-ftvpci.S linux/arch/arm/boot/compressed/head-ftvpci.S
--- linux-2.4.2-pre1/arch/arm/boot/compressed/head-ftvpci.S	Sun Sep  3 11:19:11 2000
+++ linux/arch/arm/boot/compressed/head-ftvpci.S	Mon Dec  3 22:27:48 2001
@@ -6,6 +6,13 @@
  * Special startup code for FTV PCI board.
  */
 
+/*
+ * 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.
+ */
+
 	.section        ".start", #alloc, #execinstr
 ftv_start:
 	mcr	p15, 0, r0, c7, c5, 0		@ flush I cache
diff -urN linux-2.4.2-pre1/arch/arm/boot/compressed/head-l7200.S linux/arch/arm/boot/compressed/head-l7200.S
--- linux-2.4.2-pre1/arch/arm/boot/compressed/head-l7200.S	Sun Aug 13 09:54:15 2000
+++ linux/arch/arm/boot/compressed/head-l7200.S	Mon Dec  3 22:27:48 2001
@@ -3,7 +3,7 @@
  * 
  * Copyright (C) 2000 Steve Hill <sjhill@cotw.com>
  * 
- * Some code borrowed from Nicola Pitre's 'head-sa1100.S' file. This
+ * Some code borrowed from Nicolas Pitre's 'head-sa1100.S' file. This
  * is merged with head.S by the linker.
  */
 
@@ -16,15 +16,14 @@
 		.section        ".start", #alloc, #execinstr
 
 __L7200_start:
-
 		mov	r0, #0x00100000		@ FLASH address of initrd
 		mov	r2, #0xf1000000		@ RAM address of initrd
-		add	r1, r2, #0x00700000	@ Size of initrd 
+		add	r3, r2, #0x00700000	@ Size of initrd 
 1:
-		ldmia   r0!, {r3, r4, r5, r6}
-		stmia   r2!, {r3, r4, r5, r6}
-		cmp	r2, r1
+		ldmia   r0!, {r4, r5, r6, r7}
+		stmia   r2!, {r4, r5, r6, r7}
+		cmp	r2, r3
 		ble	1b
-		
+
 		mov	r8, #0			@ Zero it out
 		mov	r7, #19			@ Set architecture ID
diff -urN linux-2.4.2-pre1/arch/arm/boot/compressed/head-sa1100.S linux/arch/arm/boot/compressed/head-sa1100.S
--- linux-2.4.2-pre1/arch/arm/boot/compressed/head-sa1100.S	Sun Aug 13 09:54:15 2000
+++ linux/arch/arm/boot/compressed/head-sa1100.S	Mon Dec  3 22:27:48 2001
@@ -11,10 +11,6 @@
 #include <linux/linkage.h>
 #include <asm/mach-types.h>
 
-#ifndef CONFIG_ARCH_SA1100
-#error What am I doing here...
-#endif
-
 		.section        ".start", #alloc, #execinstr
 
 __SA1100_start:
@@ -54,6 +50,8 @@
 		bic	r0, r0, #0x0d		@ clear WB, DC, MMU
 		bic	r0, r0, #0x1000		@ clear Icache
 		mcr	p15, 0, r0, c1, c0, 0
+
+#ifdef CONFIG_ANGELBOOT
 /*
  * Pause for a short time so that we give enough time
  * for the host to start a terminal up.
@@ -61,3 +59,5 @@
 		mov	r0, #0x00200000
 1:		subs	r0, r0, #1
 		bne	1b
+#endif
+
diff -urN linux-2.4.2-pre1/arch/arm/boot/compressed/head-shark.S linux/arch/arm/boot/compressed/head-shark.S
--- linux-2.4.2-pre1/arch/arm/boot/compressed/head-shark.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/boot/compressed/head-shark.S	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,121 @@
+/* The head-file for the Shark
+ * by Alexander.Schulz@stud.uni-karlsruhe.de
+ *
+ * Does the following:
+ * - get the memory layout from firmware. This can only be done as long as the mmu
+ *   is still on.
+ * - switch the mmu off, so we have physical addresses
+ * - copy the kernel to 0x08508000. This is done to have a fixed address where the
+ *   C-parts (misc.c) are executed. This address must be known at compile-time,
+ *   but the load-address of the kernel depends on how much memory is installed.
+ * - Jump to this location.
+ * - Set r8 with 0, r7 with the architecture ID for head.S
+ */
+
+#include <linux/linkage.h>
+
+#include <asm/assembler.h>
+	
+		.section	".start", #alloc, #execinstr
+
+		b	__beginning
+	
+__serial_addr:	.long	0xf7eff3f8
+		.long	0				@ space
+__ofw_data:	.long	0				@ the number of memory blocks
+		.space  128				@ (startaddr,size) ...
+		.space  128				@ bootargs
+		.align
+
+__beginning:	mov	r4, r0				@ save the entry to the firmware
+
+		mov	r0, #0xC0			@ disable irq and fiq
+		mov	r1, r0
+		mrs	r3, cpsr_all
+		bic	r2, r3, r0
+		eor	r2, r2, r1
+		msr	cpsr_all, r2
+
+		ldr	r0, __serial_addr		@ disable serial interrupt
+		mov	r1, #0				@ hangs the machine, I don t know why.
+		strb	r1, [r0, #0x01]
+
+		mov	r0, r4				@ get the Memory layout from firmware
+		adr	r1, __ofw_data
+		add	r2, r1, #4
+		mov	lr, pc
+		b	SYMBOL_NAME(ofw_init)
+		mov	r1, #0
+
+		adr	r2, __mmu_off			@ calculate physical address
+		sub	r2, r2, #0xf0000000		@ openprom maps us at f000 virt, 0e50 phys
+		adr	r0, __ofw_data
+		ldr	r0, [r0, #4]
+		add	r2, r2, r0
+		add	r2, r2, #0x00500000
+
+		mrc	p15, 0, r3, c1, c0
+		bic	r3, r3, #0xC			@ Write Buffer and DCache
+		bic	r3, r3, #0x1000			@ ICache
+		mcr	p15, 0, r3, c1, c0		@ disabled
+
+		mov	r0, #0
+		mcr	p15, 0, r0, c7, c7		@ flush I,D caches on v4
+		mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
+		mcr	p15, 0, r0, c8, c7		@ flush I,D TLBs on v4
+
+		bic	r3, r3, #0x1			@ MMU
+		mcr	p15, 0, r3, c1, c0		@ disabled
+
+		mov	pc, r2
+
+__copy_target:	.long	0x08508000
+__copy_end:	.long	0x08608000
+		
+		.word	_start
+		.word	__bss_start
+
+		.align
+__temp_stack:	.space 128
+
+__mmu_off:
+		adr	r0, __ofw_data
+		ldr	r0, [r0, #4]
+		orr	r0, r0, #0x00600000
+	
+		ldr	r1, __copy_end
+		ldr	r3, __copy_target
+
+/* r0 = 0x0e600000 (current end of kernelcode)
+ * r3 = 0x08508000 (where it should begin)
+ * r1 = 0x08608000 (end of copying area, 1MB)
+ * The kernel is compressed, so 1 MB should be enough.
+ * copy the kernel to the beginning of physical memory
+ * We start from the highest address, so we can copy
+ * from 0x08500000 to 0x08508000 if we have only 8MB
+ */
+
+	
+__Copy:		ldr	r2, [r0], #-4
+		str	r2, [r1], #-4
+		teq	r1, r3
+		bne	__Copy
+		/* and jump to it */
+		adr	r2, __go_on
+		adr	r0, __ofw_data
+		ldr	r0, [r0, #4]
+		sub	r2, r2, r0
+		sub	r2, r2, #0x00500000
+		ldr	r0, __copy_target
+		add	r2, r2, r0
+		mov	pc, r2
+
+__go_on:
+		adr	sp, __temp_stack
+		add	sp, sp, #128
+		adr	r0, __ofw_data
+		mov	lr, pc
+		b	SYMBOL_NAME(create_params)
+	
+		mov	r8, #0
+		mov	r7, #15
diff -urN linux-2.4.2-pre1/arch/arm/boot/compressed/head.S linux/arch/arm/boot/compressed/head.S
--- linux-2.4.2-pre1/arch/arm/boot/compressed/head.S	Mon Sep 18 15:15:24 2000
+++ linux/arch/arm/boot/compressed/head.S	Mon Dec  3 22:27:48 2001
@@ -112,8 +112,7 @@
 		 */
 
 		.text
-1:		mrc	p15, 0, r6, c0, c0	@ get processor ID
-		adr	r2, LC0
+1:		adr	r2, LC0
 		ldmia	r2, {r2, r3, r4, r5, sp}
 
 		mov	r0, #0
@@ -124,14 +123,15 @@
 		cmp	r2, r3
 		blt	1b
 
+		mrc	p15, 0, r6, c0, c0	@ get processor ID
 		bl	cache_on
 
 		mov	r1, sp			@ malloc space above stack
 		add	r2, sp, #0x10000	@ 64k max
 
 		teq	r4, r5			@ will we overwrite ourselves?
-		moveq	r5, r2
-		movne	r5, r4
+		moveq	r5, r2			@ decompress after image
+		movne	r5, r4			@ decompress to final location
 
 		mov	r0, r5
 		mov	r3, r7
diff -urN linux-2.4.2-pre1/arch/arm/boot/compressed/ofw-shark.c linux/arch/arm/boot/compressed/ofw-shark.c
--- linux-2.4.2-pre1/arch/arm/boot/compressed/ofw-shark.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/boot/compressed/ofw-shark.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,216 @@
+/*
+ * linux/arch/arm/boot/compressed/ofw-shark.c
+ *
+ * by Alexander.Schulz@stud.uni-karlsruhe.de
+ *
+ * This file is used to get some basic information
+ * about the memory layout of the shark we are running
+ * on. Memory is usually divided in blocks a 8 MB.
+ * And bootargs are copied from OpenFirmware.
+ */
+
+
+#include <linux/kernel.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+
+
+asmlinkage void
+create_params (unsigned long *buffer)
+{
+	/* Is there a better address? Also change in kernel/arch.c */
+	struct param_struct *params = (struct param_struct *) 0x08003000;
+	int j,i,m,k,nr_banks,size;
+
+	for (j=0;j<256;j++) params->u1.unused[j]=0;
+
+	size=0;
+	nr_banks=(unsigned int) buffer[0];
+	if (nr_banks > NR_BANKS) nr_banks = NR_BANKS;
+	for (j=0;j<nr_banks;j++){
+		/* search the lowest address and put it into the next entry   */
+		/* not a fast sort algorithm, but there are at most 8 entries */
+		/* and this is used only once anyway                          */
+		m=0xffffffff;
+		for (i=0;i<(unsigned int) buffer[0];i++){
+			if (buffer[2*i+1]<m) {
+				m=buffer[2*i+1];
+				k=i;
+			}
+		}
+	  
+		/* using pages_in_bank for startaddress and size               */
+		/* start is in bytes, size in pages and not bigger than 0x2000 */
+		/* This is decoded in fixup_shark in arch/arm/kernel/arch.c    */
+		params->u1.s.pages_in_bank[j]=buffer[2*k+1]|(buffer[2*k+2]/PAGE_SIZE);
+		size += buffer[2*k+2];
+
+		buffer[2*k+1]=0xffffffff;                    /* mark as copied             */
+	}
+	
+	params->u1.s.page_size = PAGE_SIZE;
+	params->u1.s.nr_pages  = size/PAGE_SIZE;
+	params->u1.s.flags     = FLAG_READONLY;
+	
+	/* Copy over the bootargs */
+	for (j=0;j<128/4;j++) {
+		((unsigned long *) params->commandline)[j]=buffer[33+j];
+	}
+}
+
+
+typedef int (*ofw_handle_t)(void *);
+
+/* Everything below is called with a wrong MMU setting.
+ * This means: no string constants, no initialization of
+ * arrays, no global variables! This is ugly but I didn't
+ * want to write this in assembler :-)
+ */
+
+int
+of_decode_int(const unsigned char *p)
+{
+	unsigned int i = *p++ << 8;
+	i = (i + *p++) << 8;
+	i = (i + *p++) << 8;
+	return (i + *p);
+}
+  
+int
+OF_finddevice(ofw_handle_t openfirmware, char *name)
+{
+	unsigned int args[8];
+	char service[12];
+
+	service[0]='f';
+	service[1]='i';
+	service[2]='n';
+	service[3]='d';
+	service[4]='d';
+	service[5]='e';
+	service[6]='v';
+	service[7]='i';
+	service[8]='c';
+	service[9]='e';
+	service[10]='\0';
+
+	args[0]=(unsigned int)service;
+	args[1]=1;
+	args[2]=1;
+	args[3]=(unsigned int)name;
+
+	if (openfirmware(args) == -1)
+		return -1;
+	return args[4];
+}
+
+int
+OF_getproplen(ofw_handle_t openfirmware, int handle, char *prop)
+{
+	unsigned int args[8];
+	char service[12];
+
+	service[0]='g';
+	service[1]='e';
+	service[2]='t';
+	service[3]='p';
+	service[4]='r';
+	service[5]='o';
+	service[6]='p';
+	service[7]='l';
+	service[8]='e';
+	service[9]='n';
+	service[10]='\0';
+
+	args[0] = (unsigned int)service;
+	args[1] = 2;
+	args[2] = 1;
+	args[3] = (unsigned int)handle;
+	args[4] = (unsigned int)prop;
+
+	if (openfirmware(args) == -1)
+		return -1;
+	return args[5];
+}
+  
+int
+OF_getprop(ofw_handle_t openfirmware, int handle, char *prop, void *buf, unsigned int buflen)
+{
+	unsigned int args[8];
+	char service[8];
+
+	service[0]='g';
+	service[1]='e';
+	service[2]='t';
+	service[3]='p';
+	service[4]='r';
+	service[5]='o';
+	service[6]='p';
+	service[7]='\0';
+
+	args[0] = (unsigned int)service;
+	args[1] = 4;
+	args[2] = 1;
+	args[3] = (unsigned int)handle;
+	args[4] = (unsigned int)prop;
+	args[5] = (unsigned int)buf;
+	args[6] = buflen;
+
+	if (openfirmware(args) == -1)
+		return -1;
+	return args[7];
+}
+  
+asmlinkage void ofw_init(ofw_handle_t o, int *nomr, int *pointer)
+{
+	int phandle,i,mem_len,buffer[32];
+	char temp[12];
+  
+	temp[0]='/';
+	temp[1]='m';
+	temp[2]='e';
+	temp[3]='m';
+	temp[4]='o';
+	temp[5]='r';
+	temp[6]='y';
+	temp[7]='\0';
+
+	phandle=OF_finddevice(o,temp);
+
+	temp[0]='r';
+	temp[1]='e';
+	temp[2]='g';
+	temp[3]='\0';
+
+	mem_len = OF_getproplen(o,phandle, temp);
+	OF_getprop(o,phandle, temp, buffer, mem_len);
+	*nomr=mem_len >> 3;
+
+	for (i=0; i<=mem_len/4; i++) pointer[i]=of_decode_int((const unsigned char *)&buffer[i]);
+
+	temp[0]='/';
+	temp[1]='c';
+	temp[2]='h';
+	temp[3]='o';
+	temp[4]='s';
+	temp[5]='e';
+	temp[6]='n';
+	temp[7]='\0';
+
+	phandle=OF_finddevice(o,temp);
+
+	temp[0]='b';
+	temp[1]='o';
+	temp[2]='o';
+	temp[3]='t';
+	temp[4]='a';
+	temp[5]='r';
+	temp[6]='g';
+	temp[7]='s';
+	temp[8]='\0';
+
+	mem_len = OF_getproplen(o,phandle, temp);
+	OF_getprop(o,phandle, temp, buffer, mem_len);
+	for (i=0; i<=mem_len/4; i++) pointer[i+32]=buffer[i];
+  
+}
diff -urN linux-2.4.2-pre1/arch/arm/boot/compressed/setup-sa1100.S linux/arch/arm/boot/compressed/setup-sa1100.S
--- linux-2.4.2-pre1/arch/arm/boot/compressed/setup-sa1100.S	Mon Sep 18 15:15:24 2000
+++ linux/arch/arm/boot/compressed/setup-sa1100.S	Mon Dec  3 22:27:48 2001
@@ -33,13 +33,11 @@
 #define UTSR0           0x1c
 #define UTSR1           0x20
 
-#define BAUD_DIV_230400	0x000
-#define BAUD_DIV_115200	0x001
-#define BAUD_DIV_57600	0x003
-#define BAUD_DIV_38400	0x005
-#define BAUD_DIV_19200	0x00b
-#define BAUD_DIV_9600	0x017
-#define BAUD_DIV	BAUD_DIV_9600
+#ifndef CONFIG_SA1100_DEFAULT_BAUDRATE
+#define CONFIG_SA1100_DEFAULT_BAUDRATE	9600
+#endif
+
+#define BAUD_DIV	((230400/CONFIG_SA1100_DEFAULT_BAUDRATE)-1)
 
 SCR_loc:	.long	SYMBOL_NAME(SCR_value)
 #define GPIO_2_9	0x3fc
@@ -92,7 +90,7 @@
 		bne	skip_uart
 
 		@ UART3 if Assabet is used with Neponset
-		teq	r3, #25			@ if Assabet 
+		teq	r3, #MACH_TYPE_ASSABET	@ if Assabet 
 		tsteq	r2, #(1 << 9)		@ ... and Neponset present
 		ldreq	r0, UART3_BASE
 		beq	uart_init
diff -urN linux-2.4.2-pre1/arch/arm/boot/compressed/vmlinux.lds.in linux/arch/arm/boot/compressed/vmlinux.lds.in
--- linux-2.4.2-pre1/arch/arm/boot/compressed/vmlinux.lds.in	Mon Sep 18 15:15:24 2000
+++ linux/arch/arm/boot/compressed/vmlinux.lds.in	Mon Dec  3 22:27:48 2001
@@ -19,12 +19,13 @@
 
   .text : {
     _start = .;
-    head.o(.start)
     *(.start)
-    head.o(.text)
     *(.text)
     *(.fixup)
     *(.gnu.warning)
+    *(.rodata)
+    *(.glue_7)
+    *(.glue_7t)
     input_data = .;
     piggy.o
     input_data_end = .;
diff -urN linux-2.4.2-pre1/arch/arm/config.in linux/arch/arm/config.in
--- linux-2.4.2-pre1/arch/arm/config.in	Thu Nov 16 12:51:28 2000
+++ linux/arch/arm/config.in	Mon Dec  3 22:27:48 2001
@@ -352,7 +352,7 @@
 
 source drivers/ieee1394/Config.in
 
-source drivers/i2o/Config.in
+source drivers/message/i2o/Config.in
 
 mainmenu_option next_comment
 comment 'ISDN subsystem'
diff -urN linux-2.4.2-pre1/arch/arm/kernel/Makefile linux/arch/arm/kernel/Makefile
--- linux-2.4.2-pre1/arch/arm/kernel/Makefile	Mon Sep 18 15:15:24 2000
+++ linux/arch/arm/kernel/Makefile	Mon Dec  3 22:27:48 2001
@@ -10,16 +10,14 @@
 HEAD_OBJ  = head-$(PROCESSOR).o
 ENTRY_OBJ = entry-$(PROCESSOR).o
 
-AFLAGS_head-armv.o := -DTEXTADDR=$(TEXTADDR) -traditional
-AFLAGS_head-armo.o := -DTEXTADDR=$(TEXTADDR) -traditional
+AFLAGS_head-armv.o := -DTEXTADDR=$(TEXTADDR)
+AFLAGS_head-armo.o := -DTEXTADDR=$(TEXTADDR)
 
 O_OBJS_arc        = dma-arc.o oldlatches.o
 O_OBJS_rpc        = dma-rpc.o
 O_OBJS_footbridge = dma-footbridge.o isa.o
 O_OBJS_l7200      = fiq.o
 
-leds-ebsa110	  = leds-ebsa110.o
-
 pci-nexuspci	  = plx90x0.o
 pci-footbridge	  = dec21285.o
 pci-shark	  = via82c505.o
@@ -31,36 +29,28 @@
 
 # Object file lists.
 
-obj-y			:= arch.o dma.o $(ENTRY_OBJ) irq.o process.o ptrace.o \
-			   semaphore.o setup.o signal.o sys_arm.o time.o \
-			   traps.o $(O_OBJS_$(MACHINE))
-obj-m			:=
-obj-n			:=
-obj-			:=
-
-export-objs		:= armksyms.o dma.o ecard.o \
-			   $(leds-$(MACHINE)) oldlatches.o \
-			   time.o
+obj-y		:= arch.o dma.o $(ENTRY_OBJ) irq.o process.o ptrace.o    \
+		   semaphore.o setup.o signal.o sys_arm.o time.o traps.o \
+		   $(O_OBJS_$(MACHINE))
+obj-m		:=
+obj-n		:=
+obj-		:=
+
+export-objs	:= armksyms.o dma.o ecard.o fiq.o oldlatches.o time.o
+
+no-irq-arch	:= $(CONFIG_ARCH_INTEGRATOR) $(CONFIG_ARCH_CLPS711X) \
+		   $(CONFIG_ARCH_FOOTBRIDGE) $(CONFIG_ARCH_EBSA110)
+
+ifneq ($(findstring y,$(no-irq-arch)),y)
+  obj-y		+= irq-arch.o
+endif
 
 obj-$(CONFIG_ARCH_ACORN) += ecard.o fiq.o time-acorn.o
 obj-$(CONFIG_DEBUG_LL)	+= debug-$(PROCESSOR).o
 obj-$(CONFIG_MODULES)	+= armksyms.o
-obj-$(CONFIG_LEDS)	+= $(leds-$(MACHINE))
 obj-$(CONFIG_ARTHUR)	+= arthur.o
 obj-$(CONFIG_ISA_DMA)	+= dma-isa.o
-
 obj-$(CONFIG_PCI)	+= bios32.o $(pci-$(MACHINE)) $(pci-y)
-
-# Files that are both resident and modular; remove from modular.
-
-obj-m		:= $(filter-out $(obj-y), $(obj-m))
-
-# Translate to Rules.make lists.
-
-O_OBJS		:= $(filter-out $(export-objs), $(obj-y))
-OX_OBJS 	:= $(filter	$(export-objs), $(obj-y))
-M_OBJS		:= $(sort $(filter-out $(export-objs), $(obj-m)))
-MX_OBJS 	:= $(sort $(filter     $(export-objs), $(obj-m)))
 
 all: kernel.o $(HEAD_OBJ) init_task.o
 
diff -urN linux-2.4.2-pre1/arch/arm/kernel/bios32.c linux/arch/arm/kernel/bios32.c
--- linux-2.4.2-pre1/arch/arm/kernel/bios32.c	Mon Nov 27 17:51:34 2000
+++ linux/arch/arm/kernel/bios32.c	Mon Dec  3 22:27:48 2001
@@ -257,11 +257,30 @@
 			(struct arm_pci_sysdata *)bus->sysdata;
 	struct arm_bus_sysdata *busdata;
 
-	if (bus->number < MAX_NR_BUS)
-		busdata = sysdata->bus + bus->number;
-	else
+	if (bus->number >= MAX_NR_BUS)
 		BUG();
 
+	if (bus->self) {
+		struct pci_dev *dev = bus->self;
+		int i;
+
+		for (i = 0; i < 3; i++) {
+			bus->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES + i];
+			bus->resource[i]->name = bus->name;
+		}
+		bus->resource[0]->start = ioport_resource.start;
+		bus->resource[0]->end   = ioport_resource.end;
+		bus->resource[0]->flags |= pci_bridge_check_io(dev);
+		bus->resource[1]->start = iomem_resource.start;
+		bus->resource[1]->end   = iomem_resource.end;
+		bus->resource[1]->flags |= IORESOURCE_MEM;
+
+		/* Turn off downsteam prefetchable memory address range */
+		bus->resource[2]->start = 1024*1024;
+		bus->resource[2]->end   = bus->resource[2]->start - 1;
+	}
+
+	busdata = sysdata->bus + bus->number;
 	busdata->max_lat = 255;
 
 	/*
@@ -363,10 +382,6 @@
 void __init
 pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *ranges)
 {
-	ranges->io_start -= bus->resource[0]->start;
-	ranges->io_end -= bus->resource[0]->start;
-	ranges->mem_start -= bus->resource[1]->start;
-	ranges->mem_end -= bus->resource[1]->start;
 }
 
 u8 __init no_swizzle(struct pci_dev *dev, u8 *pin)
@@ -442,7 +457,8 @@
 	hw_pci->init(&sysdata);
 
 	/*
-	 * Other architectures don't seem to do this... should we?
+	 * Claim the currently allocated resources.  This ensures
+	 * that we will not allocate an already inuse region.
 	 */
 	pcibios_claim_resources();
 
diff -urN linux-2.4.2-pre1/arch/arm/kernel/dma-arc.c linux/arch/arm/kernel/dma-arc.c
--- linux-2.4.2-pre1/arch/arm/kernel/dma-arc.c	Mon Nov 27 17:07:59 2000
+++ linux/arch/arm/kernel/dma-arc.c	Mon Dec  3 22:27:48 2001
@@ -40,7 +40,7 @@
 		memcpy ((void *)0x1c, (void *)&fdc1772_dma_read,
 			&fdc1772_dma_read_end - &fdc1772_dma_read);
 		fdc1772_setupdma(dma->buf.length, dma->buf.address); /* Sets data pointer up */
-		enable_irq (64);
+		enable_fiq(FIQ_FLOPPYDATA);
 		restore_flags(flags);
 	   }
 	   break;
@@ -55,7 +55,7 @@
 		memcpy ((void *)0x1c, (void *)&fdc1772_dma_write,
 			&fdc1772_dma_write_end - &fdc1772_dma_write);
 		fdc1772_setupdma(dma->buf.length, dma->buf.address); /* Sets data pointer up */
-		enable_irq (64);
+		enable_fiq(FIQ_FLOPPYDATA;
 
 		restore_flags(flags);
 	    }
@@ -102,7 +102,7 @@
 
 static void arc_disable_dma(dmach_t channel, dma_t *dma)
 {
-	disable_irq(dma->dma_irq);
+	disable_fiq(dma->dma_irq);
 }
 
 static struct dma_ops arc_floppy_data_dma_ops = {
@@ -158,12 +158,12 @@
 	regs.ARM_r10 = dma->buf.address;
 	regs.ARM_fp = FLOPPYDMA_BASE;
 	set_fiq_regs(&regs);
-	enable_irq(dma->dma_irq);
+	enable_fiq(dma->dma_irq);
 }
 
 static void a5k_floppy_disable_dma(dmach_t channel, dma_t *dma)
 {
-	disable_irq(dma->dma_irq);
+	disable_fiq(dma->dma_irq);
 	release_fiq(&fh);
 }
 
@@ -192,15 +192,15 @@
 {
 #if defined(CONFIG_BLK_DEV_FD1772) || defined(CONFIG_BLK_DEV_FD1772_MODULE)
 	if (machine_is_archimedes()) {
-		dma[DMA_VIRTUAL_FLOPPY0].dma_irq = 64;
+		dma[DMA_VIRTUAL_FLOPPY0].dma_irq = FIQ_FLOPPYDATA;
 		dma[DMA_VIRTUAL_FLOPPY0].d_ops   = &arc_floppy_data_dma_ops;
-		dma[DMA_VIRTUAL_FLOPPY1].dma_irq = 65;
+		dma[DMA_VIRTUAL_FLOPPY1].dma_irq = 1;
 		dma[DMA_VIRTUAL_FLOPPY1].d_ops   = &arc_floppy_cmdend_dma_ops;
 	}
 #endif
 #ifdef CONFIG_ARCH_A5K
 	if (machine_is_a5k()) {
-		dma[DMA_VIRTUAL_FLOPPY0].dma_irq = 64;
+		dma[DMA_VIRTUAL_FLOPPY0].dma_irq = FIQ_FLOPPYDATA;
 		dma[DMA_VIRTUAL_FLOPPY0].d_ops   = &a5k_floppy_dma_ops;
 	}
 #endif
diff -urN linux-2.4.2-pre1/arch/arm/kernel/dma-rpc.c linux/arch/arm/kernel/dma-rpc.c
--- linux-2.4.2-pre1/arch/arm/kernel/dma-rpc.c	Mon Sep 18 15:15:24 2000
+++ linux/arch/arm/kernel/dma-rpc.c	Mon Dec  3 22:27:48 2001
@@ -42,11 +42,11 @@
 #define TRANSFER_SIZE	2
 
 #define CURA	(0)
-#define ENDA	((IOMD_IO0ENDA - IOMD_IO0CURA) << 2)
-#define CURB	((IOMD_IO0CURB - IOMD_IO0CURA) << 2)
-#define ENDB	((IOMD_IO0ENDB - IOMD_IO0CURA) << 2)
-#define CR	((IOMD_IO0CR - IOMD_IO0CURA) << 2)
-#define ST	((IOMD_IO0ST - IOMD_IO0CURA) << 2)
+#define ENDA	(IOMD_IO0ENDA - IOMD_IO0CURA)
+#define CURB	(IOMD_IO0CURB - IOMD_IO0CURA)
+#define ENDB	(IOMD_IO0ENDB - IOMD_IO0CURA)
+#define CR	(IOMD_IO0CR - IOMD_IO0CURA)
+#define ST	(IOMD_IO0ST - IOMD_IO0CURA)
 
 #define state_prog_a	0
 #define state_wait_a	1
@@ -93,14 +93,14 @@
 
 static inline void iomd_setup_dma_a(struct scatterlist *sg, dma_t *dma)
 {
-	outl_t(sg->dma_address, dma->dma_base + CURA);
-	outl_t(sg->length, dma->dma_base + ENDA);
+	iomd_writel(sg->dma_address, dma->dma_base + CURA);
+	iomd_writel(sg->length, dma->dma_base + ENDA);
 }
 
 static inline void iomd_setup_dma_b(struct scatterlist *sg, dma_t *dma)
 {
-	outl_t(sg->dma_address, dma->dma_base + CURB);
-	outl_t(sg->length, dma->dma_base + ENDB);
+	iomd_writel(sg->dma_address, dma->dma_base + CURB);
+	iomd_writel(sg->length, dma->dma_base + ENDB);
 }
 
 static void iomd_dma_handle(int irq, void *dev_id, struct pt_regs *regs)
@@ -116,7 +116,7 @@
 			dma->state = state_wait_a;
 
 		case state_wait_a:
-			status = inb_t(dma->dma_base + ST);
+			status = iomd_readb(dma->dma_base + ST);
 			switch (status & (DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB)) {
 			case DMA_ST_OFL|DMA_ST_INT:
 				iomd_get_next_sg(&dma->cur_sg, dma);
@@ -137,7 +137,7 @@
 			break;
 
 		case state_wait_b:
-			status = inb_t(dma->dma_base + ST);
+			status = iomd_readb(dma->dma_base + ST);
 			switch (status & (DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB)) {
 			case DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB:
 				iomd_get_next_sg(&dma->cur_sg, dma);
@@ -193,14 +193,14 @@
 				PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
 		}
 
-		outb_t(DMA_CR_C, dma_base + CR);
+		iomd_writeb(DMA_CR_C, dma_base + CR);
 		dma->state = state_prog_a;
 	}
 		
 	if (dma->dma_mode == DMA_MODE_READ)
 		ctrl |= DMA_CR_D;
 
-	outb_t(ctrl, dma_base + CR);
+	iomd_writeb(ctrl, dma_base + CR);
 	enable_irq(dma->dma_irq);
 }
 
@@ -210,8 +210,8 @@
 	unsigned int ctrl;
 
 	disable_irq(dma->dma_irq);
-	ctrl = inb_t(dma_base + CR);
-	outb_t(ctrl & ~DMA_CR_E, dma_base + CR);
+	ctrl = iomd_readb(dma_base + CR);
+	iomd_writeb(ctrl & ~DMA_CR_E, dma_base + CR);
 }
 
 static int iomd_set_dma_speed(dmach_t channel, dma_t *dma, int cycle)
@@ -227,7 +227,7 @@
 	else
 		speed = 0;
 
-	tcr = inb(IOMD_DMATCR);
+	tcr = iomd_readb(IOMD_DMATCR);
 	speed &= 3;
 
 	switch (channel) {
@@ -251,7 +251,7 @@
 		break;
 	}
 
-	outb(tcr, IOMD_DMATCR);
+	iomd_writeb(tcr, IOMD_DMATCR);
 
 	return speed;
 }
@@ -287,7 +287,7 @@
 
 	regs.ARM_r9  = dma->buf.length;
 	regs.ARM_r10 = (unsigned long)dma->buf.address;
-	regs.ARM_fp  = (unsigned long)PCIO_FLOPPYDMABASE;
+	regs.ARM_fp  = FLOPPYDMA_BASE;
 
 	if (claim_fiq(&fh)) {
 		printk("floppydma: couldn't claim FIQ.\n");
@@ -296,12 +296,12 @@
 
 	set_fiq_handler(fiqhandler_start, fiqhandler_length);
 	set_fiq_regs(&regs);
-	enable_irq(dma->dma_irq);
+	enable_fiq(dma->dma_irq);
 }
 
 static void floppy_disable_dma(dmach_t channel, dma_t *dma)
 {
-	disable_irq(dma->dma_irq);
+	disable_fiq(dma->dma_irq);
 	release_fiq(&fh);
 }
 
@@ -334,32 +334,32 @@
 
 void __init arch_dma_init(dma_t *dma)
 {
-	outb(0, IOMD_IO0CR);
-	outb(0, IOMD_IO1CR);
-	outb(0, IOMD_IO2CR);
-	outb(0, IOMD_IO3CR);
+	iomd_writeb(0, IOMD_IO0CR);
+	iomd_writeb(0, IOMD_IO1CR);
+	iomd_writeb(0, IOMD_IO2CR);
+	iomd_writeb(0, IOMD_IO3CR);
 
-	outb(0xa0, IOMD_DMATCR);
+	iomd_writeb(0xa0, IOMD_DMATCR);
 
-	dma[DMA_0].dma_base		= ioaddr(IOMD_IO0CURA);
+	dma[DMA_0].dma_base		= IOMD_IO0CURA;
 	dma[DMA_0].dma_irq		= IRQ_DMA0;
 	dma[DMA_0].d_ops		= &iomd_dma_ops;
-	dma[DMA_1].dma_base		= ioaddr(IOMD_IO1CURA);
+	dma[DMA_1].dma_base		= IOMD_IO1CURA;
 	dma[DMA_1].dma_irq		= IRQ_DMA1;
 	dma[DMA_1].d_ops		= &iomd_dma_ops;
-	dma[DMA_2].dma_base		= ioaddr(IOMD_IO2CURA);
+	dma[DMA_2].dma_base		= IOMD_IO2CURA;
 	dma[DMA_2].dma_irq		= IRQ_DMA2;
 	dma[DMA_2].d_ops		= &iomd_dma_ops;
-	dma[DMA_3].dma_base		= ioaddr(IOMD_IO3CURA);
+	dma[DMA_3].dma_base		= IOMD_IO3CURA;
 	dma[DMA_3].dma_irq		= IRQ_DMA3;
 	dma[DMA_3].d_ops		= &iomd_dma_ops;
-	dma[DMA_S0].dma_base		= ioaddr(IOMD_SD0CURA);
+	dma[DMA_S0].dma_base		= IOMD_SD0CURA;
 	dma[DMA_S0].dma_irq		= IRQ_DMAS0;
 	dma[DMA_S0].d_ops		= &iomd_dma_ops;
-	dma[DMA_S1].dma_base		= ioaddr(IOMD_SD1CURA);
+	dma[DMA_S1].dma_base		= IOMD_SD1CURA;
 	dma[DMA_S1].dma_irq		= IRQ_DMAS1;
 	dma[DMA_S1].d_ops		= &iomd_dma_ops;
-	dma[DMA_VIRTUAL_FLOPPY].dma_irq	= 64;
+	dma[DMA_VIRTUAL_FLOPPY].dma_irq	= FIQ_FLOPPYDATA;
 	dma[DMA_VIRTUAL_FLOPPY].d_ops	= &floppy_dma_ops;
 	dma[DMA_VIRTUAL_SOUND].d_ops	= &sound_dma_ops;
 
@@ -367,5 +367,5 @@
 	 * Setup DMA channels 2,3 to be for podules
 	 * and channels 0,1 for internal devices
 	 */
-	outb(DMA_EXT_IO3|DMA_EXT_IO2, IOMD_DMAEXT);
+	iomd_writeb(DMA_EXT_IO3|DMA_EXT_IO2, IOMD_DMAEXT);
 }
diff -urN linux-2.4.2-pre1/arch/arm/kernel/entry-armo.S linux/arch/arm/kernel/entry-armo.S
--- linux-2.4.2-pre1/arch/arm/kernel/entry-armo.S	Mon Sep 18 15:15:24 2000
+++ linux/arch/arm/kernel/entry-armo.S	Mon Dec  3 22:27:48 2001
@@ -197,8 +197,7 @@
 #endif
 #define FAULT_CODE_PREFETCH	0x04
 #define FAULT_CODE_WRITE	0x02
-#define FAULT_CODE_USER		0x01
-
+#define FAULT_CODE_FORCECOW	0x01
 
 #define SVC_SAVE_ALL				\
 		str	sp, [sp, #-16]!		;\
@@ -487,7 +486,6 @@
 		save_user_regs
 		teqp	pc, #0x00000003		@ NOT a problem - doesnt change mode
 		mask_pc	r0, lr
-		mov	r2, #FAULT_CODE_USER
 		bl	Ldata_do
 		b	ret_from_exception
 
@@ -499,7 +497,6 @@
 		tst	lr, #0x08000000
 		teqeqp	pc, #0x00000003		@ NOT a problem - doesnt change mode
 		mask_pc	r0, lr
-		mov	r2, #0
 		bl	Ldata_do
 		SVC_RESTORE_ALL
 
@@ -510,6 +507,7 @@
 
 Ldata_do:	mov	r3, sp
 		ldr	r4, [r0]		@ Get instruction
+		mov	r2, #0
 		tst	r4, #1 << 20		@ Check to see if it is a write instruction
 		orreq	r2, r2, #FAULT_CODE_WRITE @ Indicate write instruction
 		mov	r1, r4, lsr #22		@ Now branch to the relevent processing routine
diff -urN linux-2.4.2-pre1/arch/arm/kernel/fiq.c linux/arch/arm/kernel/fiq.c
--- linux-2.4.2-pre1/arch/arm/kernel/fiq.c	Mon Nov 27 17:07:59 2000
+++ linux/arch/arm/kernel/fiq.c	Mon Dec  3 22:27:48 2001
@@ -36,12 +36,14 @@
  *  6. Goto 3
  */
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
 #include <linux/init.h>
 
 #include <asm/fiq.h>
 #include <asm/io.h>
+#include <asm/irq.h>
 #include <asm/pgalloc.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -71,7 +73,7 @@
  * - we always relinquish FIQ control
  * - we always reacquire FIQ control
  */
-int fiq_def_op(void *ref, int relinquish)
+static int fiq_def_op(void *ref, int relinquish)
 {
 	if (!relinquish) {
 		unprotect_page_0();
@@ -213,6 +215,24 @@
 		current_fiq = current_fiq->next;
 	while (current_fiq->fiq_op(current_fiq->dev_id, 0));
 }
+
+void enable_fiq(int fiq)
+{
+	enable_irq(fiq + FIQ_START);
+}
+
+void disable_fiq(int fiq)
+{
+	disable_irq(fiq + FIQ_START);
+}
+
+EXPORT_SYMBOL(set_fiq_handler);
+EXPORT_SYMBOL(set_fiq_regs);
+EXPORT_SYMBOL(get_fiq_regs);
+EXPORT_SYMBOL(claim_fiq);
+EXPORT_SYMBOL(release_fiq);
+EXPORT_SYMBOL(enable_fiq);
+EXPORT_SYMBOL(disable_fiq);
 
 void __init init_FIQ(void)
 {
diff -urN linux-2.4.2-pre1/arch/arm/kernel/process.c linux/arch/arm/kernel/process.c
--- linux-2.4.2-pre1/arch/arm/kernel/process.c	Mon Sep 18 15:15:25 2000
+++ linux/arch/arm/kernel/process.c	Mon Dec  3 22:27:48 2001
@@ -92,8 +92,10 @@
 		void (*idle)(void) = pm_idle;
 		if (!idle)
 			idle = arch_idle;
+		leds_event(led_idle_start);
 		while (!current->need_resched)
 			idle();
+		leds_event(led_idle_end);
 		schedule();
 #ifndef CONFIG_NO_PGT_CACHE
 		check_pgt_cache();
@@ -364,20 +366,23 @@
  */
 pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
 {
-	extern long sys_exit(int) __attribute__((noreturn));
 	pid_t __ret;
 
 	__asm__ __volatile__(
-	"mov	r0, %1		@ kernel_thread sys_clone
+	"orr	r0, %1, %2	@ kernel_thread sys_clone
 	mov	r1, #0
 	"__syscall(clone)"
-	teq	r0, #0		@ if we are the child
-	moveq	fp, #0		@ ensure that fp is zero
-	mov	%0, r0"
+	movs	%0, r0		@ if we are the child
+	bne	1f
+	mov	fp, #0		@ ensure that fp is zero
+	mov	r0, %4
+	mov	lr, pc
+	mov	pc, %3
+	b	sys_exit
+1:	"
         : "=r" (__ret)
-        : "Ir" (flags | CLONE_VM) : "r0", "r1");
-	if (__ret == 0)
-		sys_exit((fn)(arg));
+        : "Ir" (flags), "I" (CLONE_VM), "r" (fn), "r" (arg)
+	: "r0", "r1", "lr");
 	return __ret;
 }
 
diff -urN linux-2.4.2-pre1/arch/arm/kernel/time.c linux/arch/arm/kernel/time.c
--- linux-2.4.2-pre1/arch/arm/kernel/time.c	Mon Sep 18 15:15:25 2000
+++ linux/arch/arm/kernel/time.c	Mon Dec  3 22:27:48 2001
@@ -134,32 +134,17 @@
 #ifdef CONFIG_MODULES
 EXPORT_SYMBOL(leds_event);
 #endif
+#endif
 
+#ifdef CONFIG_LEDS_TIMER
 static void do_leds(void)
 {
-#ifdef CONFIG_LEDS_CPU
-	{
-		static int last_pid;
+	static unsigned int count = 50;
 
-		if (current->pid != last_pid) {
-			last_pid = current->pid;
-			if (last_pid)
-				leds_event(led_idle_end);
-			else
-				leds_event(led_idle_start);
-		}
+	if (--count == 0) {
+		count = 50;
+		leds_event(led_timer);
 	}
-#endif
-#ifdef CONFIG_LEDS_TIMER
-	{
-		static unsigned int count = 50;
-
-		if (--count == 0) {
-			count = 50;
-			leds_event(led_timer);
-		}
-	}
-#endif
 }
 #else
 #define do_leds()
diff -urN linux-2.4.2-pre1/arch/arm/kernel/traps.c linux/arch/arm/kernel/traps.c
--- linux-2.4.2-pre1/arch/arm/kernel/traps.c	Sun Dec  3 17:48:19 2000
+++ linux/arch/arm/kernel/traps.c	Mon Dec  3 22:27:48 2001
@@ -107,7 +107,7 @@
 			bad = __get_user(val, &((u32 *)addr)[i]);
 
 		if (!bad)
-			printk(i == 0 ? "(%0*x) " : "%0*x", width, val);
+			printk(i == 0 ? "(%0*x) " : "%0*x ", width, val);
 		else {
 			printk("bad PC value.");
 			break;
@@ -133,7 +133,7 @@
 		printk("no frame pointer");
 		ok = 0;
 	} else if (verify_stack(fp)) {
-		printk("invalid frame pointer %08lx", fp);
+		printk("invalid frame pointer 0x%08x", fp);
 		ok = 0;
 	} else if (fp < 4096+(unsigned long)tsk)
 		printk("frame pointer underflow");
diff -urN linux-2.4.2-pre1/arch/arm/lib/Makefile linux/arch/arm/lib/Makefile
--- linux-2.4.2-pre1/arch/arm/lib/Makefile	Mon Nov 27 17:07:59 2000
+++ linux/arch/arm/lib/Makefile	Mon Dec  3 22:27:48 2001
@@ -1,57 +1,57 @@
 #
 # linux/arch/arm/lib/Makefile
 #
-# Copyright (C) 1995-1999 Russell King
+# Copyright (C) 1995-2000 Russell King
 #
 
 USE_STANDARD_AS_RULE := true
 
-L_TARGET := lib.a
-L_OBJS   := changebit.o csumipv6.o csumpartial.o csumpartialcopy.o \
-	    csumpartialcopyuser.o clearbit.o copy_page.o findbit.o \
-	    memchr.o memcpy.o memset.o memzero.o setbit.o          \
-	    strncpy_from_user.o strnlen_user.o strchr.o strrchr.o  \
-	    testchangebit.o testclearbit.o testsetbit.o uaccess.o
-
-l-obj-y	:=
-l-obj-n	:=
-
-O_TARGET := lib.o
-O_OBJS   := backtrace.o delay.o
-
-ifeq ($(CONFIG_ARCH_ACORN),y)
-  half := n
-  full := y
+L_TARGET	:= lib.a
+
+obj-y		:= backtrace.o changebit.o csumipv6.o csumpartial.o   \
+		   csumpartialcopy.o csumpartialcopyuser.o clearbit.o \
+		   copy_page.o delay.o findbit.o memchr.o memcpy.o    \
+		   memset.o memzero.o setbit.o strncpy_from_user.o    \
+		   strnlen_user.o strchr.o strrchr.o testchangebit.o  \
+		   testclearbit.o testsetbit.o uaccess.o
+obj-m		:=
+obj-n		:=
+
+export-objs	:= io.o
+
+obj-arc		:= ecard.o io-acorn.o floppydma.o
+obj-rpc		:= ecard.o io-acorn.o floppydma.o
+obj-clps7500	:= io-acorn.o
+obj-footbridge	:= io-pcio.o
+obj-l7200     	:= io-acorn.o
+obj-nexuspci	:= io-pcio.o
+obj-sa1100	:= io-pcio.o
+obj-shark	:= io-shark.o
+obj-integrator	:= io-pcio.o
+obj-clps711x	:= io-shark.o
+
+obj-y		+= $(obj-$(MACHINE))
+
+ifeq ($(CONFIG_CPU_32v4),y)
+  v3		:= n
+  v4		:= y
 else
-  half := y
-  full := n
+  v3		:= y
+  v4		:= n
 endif
 
-L_OBJS_arc		:= ecard.o io-acorn.o floppydma.o
-L_OBJS_rpc		:= ecard.o io-acorn.o floppydma.o
-L_OBJS_clps7500		:= io-acorn.o
-L_OBJS_footbridge	:= io-pcio.o
-L_OBJS_l7200     	:= io-acorn.o
-L_OBJS_nexuspci		:= io-pcio.o
-L_OBJS_sa1100		:= io-pcio.o
-L_OBJS_shark		:= io-shark.o
-L_OBJS_integrator	:= io-pcio.o
-L_OBJS_clps711x		:= io-shark.o
-
-l-obj-y			+= io-readsb.o io-writesb.o
-l-obj-$(full)		+= io-readsw-armv3.o io-writesw-armv3.o
-l-obj-$(half)		+= io-readsw-armv4.o io-writesw-armv4.o
-l-obj-y			+= io-readsl.o io-writesl.o
+obj-y		+= io-readsb.o io-writesb.o
+obj-$(v3)	+= io-readsw-armv3.o io-writesw-armv3.o io-readsl-armv3.o
+obj-$(v4)	+= io-readsw-armv4.o io-writesw-armv4.o io-readsl-armv4.o
+obj-y		+= io-writesl.o
 
 ifeq ($(PROCESSOR),armo)
-  L_OBJS += uaccess-armo.o
+  obj-y		+= uaccess-armo.o
 endif
 
 ifneq ($(MACHINE),ebsa110)
-  OX_OBJS += io.o
+  obj-y		+= io.o
 endif
-
-L_OBJS	+= $(L_OBJS_$(MACHINE)) $(l-obj-y)
 
 include $(TOPDIR)/Rules.make
 
diff -urN linux-2.4.2-pre1/arch/arm/lib/io-acorn.S linux/arch/arm/lib/io-acorn.S
--- linux-2.4.2-pre1/arch/arm/lib/io-acorn.S	Mon Nov 27 17:07:59 2000
+++ linux/arch/arm/lib/io-acorn.S	Mon Dec  3 22:27:48 2001
@@ -60,32 +60,32 @@
  */
 
 ENTRY(insw)
-		teq	r2, #0
-		RETINSTR(moveq, pc, lr)
 		addr	r0
-		b	__arch_readsw
+		teq	r2, #0
+		bne	__arch_readsw
+		RETINSTR(mov, pc, lr)
 
 ENTRY(insb)
-		teq	r2, #0
-		RETINSTR(moveq, pc, lr)
 		addr	r0
-		b	__arch_readsb
+		teq	r2, #0
+		bne	__arch_readsb
+		RETINSTR(mov, pc, lr)
 
 @ Purpose: write a block of data from memory to a hardware register.
 @ Proto  : outsw(int to_reg, void *from, int len_in_words);
 @ Notes  : increments from
 
 ENTRY(outsw)
-		teq	r2, #0
-		RETINSTR(moveq, pc, lr)
 		addr	r0
-		b	__arch_writesw
+		teq	r2, #0
+		bne	__arch_writesw
+		RETINSTR(mov, pc, lr)
 
 ENTRY(outsb)
-		teq	r2, #0
-		RETINSTR(moveq, pc, lr)
 		addr	r0
-		b	__arch_writesb
+		teq	r2, #0
+		bne	__arch_writesb
+		RETINSTR(mov, pc, lr)
 
 @ Purpose: write a memc register
 @ Proto  : void memc_write(int register, int value);
diff -urN linux-2.4.2-pre1/arch/arm/lib/io-pcio.S linux/arch/arm/lib/io-pcio.S
--- linux-2.4.2-pre1/arch/arm/lib/io-pcio.S	Mon Nov 27 17:07:59 2000
+++ linux/arch/arm/lib/io-pcio.S	Mon Dec  3 22:27:48 2001
@@ -1,4 +1,5 @@
 #include <linux/linkage.h>
+#include <asm/assembler.h>
 #include <asm/hardware.h>
 
 		.equ	pcio_high, PCIO_BASE & 0xff000000
@@ -13,26 +14,37 @@
 
 ENTRY(insl)
 		ioaddr	r0, r0
-		b	__arch_readsl
+		teq	r2, #0
+		bne	__arch_readsl
+		RETINSTR(mov, pc, lr)
 
 ENTRY(outsl)
 		ioaddr	r0, r0
-		b	__arch_writesl
-
-		/* Nobody could say these are optimal, but not to worry. */
+		teq	r2, #0
+		bne	__arch_writesl
+		RETINSTR(mov, pc, lr)
 
 ENTRY(outsw)
 		ioaddr	r0, r0
-		b	__arch_writesw
+		teq	r2, #0
+		bne	__arch_writesw
+		RETINSTR(mov, pc, lr)
 
 ENTRY(insw)
 		ioaddr	r0, r0
-		b	__arch_readsw
+		teq	r2, #0
+		bne	__arch_readsw
+		RETINSTR(mov, pc, lr)
 
 ENTRY(insb)
 		ioaddr	r0, r0
-		b	__arch_readsb
+		teq	r2, #0
+		bne	__arch_readsb
+		RETINSTR(mov, pc, lr)
 
 ENTRY(outsb)
 		ioaddr	r0, r0
-		b	__arch_writesb
+		teq	r2, #0
+		bne	__arch_writesb
+		RETINSTR(mov, pc, lr)
+
diff -urN linux-2.4.2-pre1/arch/arm/lib/io-readsb.S linux/arch/arm/lib/io-readsb.S
--- linux-2.4.2-pre1/arch/arm/lib/io-readsb.S	Mon Nov 27 17:07:59 2000
+++ linux/arch/arm/lib/io-readsb.S	Mon Dec  3 22:27:48 2001
@@ -62,6 +62,7 @@
 		ldrb	ip, [r0]
 		orr	r6, r6, ip, lsl #24
 		stmia	r1!, {r3 - r6}
+
 		subs	r2, r2, #16
 		bpl	.insb_16_lp
 
@@ -88,7 +89,7 @@
 		stmia	r1!, {r3, r4}
 
 .insb_no_8:	tst	r2, #4
-		bne	.insb_no_4
+		beq	.insb_no_4
 
 		ldrb	r3, [r0]
 		ldrb	r4, [r0]
@@ -101,6 +102,7 @@
 
 .insb_no_4:	ands	r2, r2, #3
 		LOADREGS(eqfd, sp!, {r4 - r6, pc})
+
 		cmp	r2, #2
 		ldrb	r3, [r0]
 		strb	r3, [r1], #1
@@ -108,4 +110,5 @@
 		strgeb	r3, [r1], #1
 		ldrgtb	r3, [r0]
 		strgtb	r3, [r1]
+
 		LOADREGS(fd, sp!, {r4 - r6, pc})
diff -urN linux-2.4.2-pre1/arch/arm/lib/io-readsl-armv3.S linux/arch/arm/lib/io-readsl-armv3.S
--- linux-2.4.2-pre1/arch/arm/lib/io-readsl-armv3.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/io-readsl-armv3.S	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,76 @@
+/*
+ *  linux/arch/arm/lib/io-readsl-armv3.S
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+/*
+ * Note that some reads can be aligned on half-word boundaries.
+ */
+ENTRY(__arch_readsl)
+		ands	ip, r1, #3
+		bne	2f
+
+1:		ldr	r3, [r0]
+		str	r3, [r1], #4
+		subs	r2, r2, #1
+		bne	1b
+		mov	pc, lr
+
+2:		cmp	ip, #2
+		ldr	ip, [r0]
+		blt	4f
+		bgt	6f
+
+		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+3:		subs	r2, r2, #1
+		ldrne	r3, [r0]
+		orrne	ip, ip, r3, lsl #16
+		strne	ip, [r1], #4
+		movne	ip, r3, lsr #16
+		bne	3b
+		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+		strb	ip, [r1], #1
+		mov	pc, lr
+
+4:		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+5:		subs	r2, r2, #1
+		ldrne	r3, [r0]
+		orrne	ip, ip, r3, lsl #8
+		strne	ip, [r1], #4
+		movne	ip, r3, lsr #24
+		bne	5b
+		strb	ip, [r1], #1
+		mov	pc, lr
+
+6:		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+7:		subs	r2, r2, #1
+		ldrne	r3, [r0]
+		orrne	ip, ip, r3, lsl #24
+		strne	ip, [r1], #4
+		movne	ip, r3, lsr #8
+		bne	7b
+		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+		strb	ip, [r1], #1
+		mov	pc, lr
+
diff -urN linux-2.4.2-pre1/arch/arm/lib/io-readsl-armv4.S linux/arch/arm/lib/io-readsl-armv4.S
--- linux-2.4.2-pre1/arch/arm/lib/io-readsl-armv4.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/io-readsl-armv4.S	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,68 @@
+/*
+ *  linux/arch/arm/lib/io-readsl-armv4.S
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+/*
+ * Note that some reads can be aligned on half-word boundaries.
+ */
+ENTRY(__arch_readsl)
+		ands	ip, r1, #3
+		bne	2f
+
+1:		ldr	r3, [r0]
+		str	r3, [r1], #4
+		subs	r2, r2, #1
+		bne	1b
+		mov	pc, lr
+
+2:		cmp	ip, #2
+		ldr	ip, [r0]
+		blt	4f
+		bgt	6f
+
+		strh	ip, [r1], #2
+		mov	ip, ip, lsr #16
+3:		subs	r2, r2, #1
+		ldrne	r3, [r0]
+		orrne	ip, ip, r3, lsl #16
+		strne	ip, [r1], #4
+		movne	ip, r3, lsr #16
+		bne	3b
+		strh	ip, [r1], #2
+		mov	pc, lr
+
+4:		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+		strh	ip, [r1], #2
+		mov	ip, ip, lsr #16
+5:		subs	r2, r2, #1
+		ldrne	r3, [r0]
+		orrne	ip, ip, r3, lsl #8
+		strne	ip, [r1], #4
+		movne	ip, r3, lsr #24
+		bne	5b
+		strb	ip, [r1], #1
+		mov	pc, lr
+
+6:		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+7:		subs	r2, r2, #1
+		ldrne	r3, [r0]
+		orrne	ip, ip, r3, lsl #24
+		strne	ip, [r1], #4
+		movne	ip, r3, lsr #8
+		bne	7b
+		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+		strh	ip, [r1], #2
+		mov	pc, lr
+
diff -urN linux-2.4.2-pre1/arch/arm/lib/io-readsl.S linux/arch/arm/lib/io-readsl.S
--- linux-2.4.2-pre1/arch/arm/lib/io-readsl.S	Mon Nov 27 17:07:59 2000
+++ linux/arch/arm/lib/io-readsl.S	Wed Dec 31 16:00:00 1969
@@ -1,65 +0,0 @@
-/*
- *  linux/arch/arm/lib/io-readsb.S
- *
- *  Copyright (C) 1995-2000 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-#include <asm/hardware.h>
-
-ENTRY(__arch_readsl)
-		ands	ip, r1, #3
-		bne	2f
-
-1:		ldr	r3, [r0]
-		str	r3, [r1], #4
-		subs	r2, r2, #1
-		bne	1b
-		mov	pc, lr
-
-2:		cmp	ip, #2
-		ldr	ip, [r0]
-		blt	4f
-		bgt	6f
-
-		strh	ip, [r1], #2
-		mov	ip, ip, lsr #16
-3:		subs	r2, r2, #1
-		ldrne	r3, [r0]
-		orrne	ip, ip, r3, lsl #16
-		strne	ip, [r1], #4
-		movne	ip, r3, lsr #16
-		bne	3b
-		strh	ip, [r1], #2
-		mov	pc, lr
-
-4:		strb	ip, [r1], #1
-		mov	ip, ip, lsr #8
-		strh	ip, [r1], #2
-		mov	ip, ip, lsr #16
-5:		subs	r2, r2, #1
-		ldrne	r3, [r0]
-		orrne	ip, ip, r3, lsl #8
-		strne	ip, [r1], #4
-		movne	ip, r3, lsr #24
-		bne	5b
-		strb	ip, [r1], #1
-		mov	pc, lr
-
-6:		strb	ip, [r1], #1
-		mov	ip, ip, lsr #8
-7:		subs	r2, r2, #1
-		ldrne	r3, [r0]
-		orrne	ip, ip, r3, lsl #24
-		strne	ip, [r1], #4
-		movne	ip, r3, lsr #8
-		bne	7b
-		strb	ip, [r1], #1
-		mov	ip, ip, lsr #8
-		strh	ip, [r1], #2
-		mov	pc, lr
-
diff -urN linux-2.4.2-pre1/arch/arm/lib/io-readsw-armv3.S linux/arch/arm/lib/io-readsw-armv3.S
--- linux-2.4.2-pre1/arch/arm/lib/io-readsw-armv3.S	Mon Nov 27 17:07:59 2000
+++ linux/arch/arm/lib/io-readsw-armv3.S	Mon Dec  3 22:27:48 2001
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/io-readsb.S
+ *  linux/arch/arm/lib/io-readsw-armv3.S
  *
  *  Copyright (C) 1995-2000 Russell King
  *
@@ -62,8 +62,10 @@
 		orr	r6, r6, lr, lsl #16
 
 		stmia	r1!, {r3 - r6}
+
 		subs	r2, r2, #8
 		bpl	.insw_8_lp
+
 		tst	r2, #7
 		LOADREGS(eqfd, sp!, {r4, r5, r6, pc})
 
@@ -97,6 +99,7 @@
 		strneb	r3, [r1], #1
 		movne	r3, r3, lsr #8
 		strneb	r3, [r1]
+
 		LOADREGS(fd, sp!, {r4, r5, r6, pc})
 
 
diff -urN linux-2.4.2-pre1/arch/arm/lib/io-readsw-armv4.S linux/arch/arm/lib/io-readsw-armv4.S
--- linux-2.4.2-pre1/arch/arm/lib/io-readsw-armv4.S	Mon Nov 27 17:07:59 2000
+++ linux/arch/arm/lib/io-readsw-armv4.S	Mon Dec  3 22:27:48 2001
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/io-readsb.S
+ *  linux/arch/arm/lib/io-readsw-armv4.S
  *
  *  Copyright (C) 1995-2000 Russell King
  *
@@ -46,16 +46,18 @@
 		orr	r4, r4, r5, lsl #16
 
 		ldrh	r5, [r0]
-		ldrh	r6, [r0]
-		orr	r5, r5, r6, lsl #16
+		ldrh	ip, [r0]
+		orr	r5, r5, ip, lsl #16
 
 		ldrh	ip, [r0]
 		ldrh	lr, [r0]
 		orr	ip, ip, lr, lsl #16
 
 		stmia	r1!, {r3 - r5, ip}
+
 		subs	r2, r2, #8
 		bpl	.insw_8_lp
+
 		tst	r2, #7
 		LOADREGS(eqfd, sp!, {r4, r5, pc})
 
@@ -84,4 +86,5 @@
 .no_insw_2:	tst	r2, #1
 		ldrneh	r3, [r0]
 		strneh	r3, [r1]
+
 		LOADREGS(fd, sp!, {r4, r5, pc})
diff -urN linux-2.4.2-pre1/arch/arm/lib/io-writesb.S linux/arch/arm/lib/io-writesb.S
--- linux-2.4.2-pre1/arch/arm/lib/io-writesb.S	Mon Nov 27 17:07:59 2000
+++ linux/arch/arm/lib/io-writesb.S	Mon Dec  3 22:27:48 2001
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/io-readsb.S
+ *  linux/arch/arm/lib/io-writesb.S
  *
  *  Copyright (C) 1995-2000 Russell King
  *
@@ -13,7 +13,7 @@
 
 .outsb_align:	rsb	ip, ip, #4
 		cmp	ip, r2
-		mov	ip, r2
+		movgt	ip, r2
 		cmp	ip, #2
 		ldrb	r3, [r1], #1
 		strb	r3, [r0]
@@ -34,6 +34,7 @@
 		bmi	.outsb_no_16
 
 .outsb_16_lp:	ldmia	r1!, {r3 - r6}
+
 		strb	r3, [r0]
 		mov	r3, r3, lsr #8
 		strb	r3, [r0]
@@ -65,6 +66,7 @@
 		strb	r6, [r0]
 		mov	r6, r6, lsr #8
 		strb	r6, [r0]
+
 		subs	r2, r2, #16
 		bpl	.outsb_16_lp
 
@@ -74,7 +76,8 @@
 .outsb_no_16:	tst	r2, #8
 		beq	.outsb_no_8
 
-		ldmia	r1, {r3, r4}
+		ldmia	r1!, {r3, r4}
+
 		strb	r3, [r0]
 		mov	r3, r3, lsr #8
 		strb	r3, [r0]
@@ -92,7 +95,7 @@
 		strb	r4, [r0]
 
 .outsb_no_8:	tst	r2, #4
-		bne	.outsb_no_4
+		beq	.outsb_no_4
 
 		ldr	r3, [r1], #4
 		strb	r3, [r0]
@@ -105,6 +108,7 @@
 
 .outsb_no_4:	ands	r2, r2, #3
 		LOADREGS(eqfd, sp!, {r4 - r6, pc})
+
 		cmp	r2, #2
 		ldrb	r3, [r1], #1
 		strb	r3, [r0]
@@ -112,4 +116,5 @@
 		strgeb	r3, [r0]
 		ldrgtb	r3, [r1]
 		strgtb	r3, [r0]
+
 		LOADREGS(fd, sp!, {r4 - r6, pc})
diff -urN linux-2.4.2-pre1/arch/arm/lib/io-writesl.S linux/arch/arm/lib/io-writesl.S
--- linux-2.4.2-pre1/arch/arm/lib/io-writesl.S	Mon Nov 27 17:07:59 2000
+++ linux/arch/arm/lib/io-writesl.S	Mon Dec  3 22:27:48 2001
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/io-readsb.S
+ *  linux/arch/arm/lib/io-writesl.S
  *
  *  Copyright (C) 1995-2000 Russell King
  *
diff -urN linux-2.4.2-pre1/arch/arm/lib/io-writesw-armv3.S linux/arch/arm/lib/io-writesw-armv3.S
--- linux-2.4.2-pre1/arch/arm/lib/io-writesw-armv3.S	Mon Nov 27 17:07:59 2000
+++ linux/arch/arm/lib/io-writesw-armv3.S	Mon Dec  3 22:27:48 2001
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/io-readsb.S
+ *  linux/arch/arm/lib/io-writesw-armv3.S
  *
  *  Copyright (C) 1995-2000 Russell King
  *
@@ -39,6 +39,7 @@
 
 		subs	r2, r2, #8
 		bmi	.no_outsw_8
+
 .outsw_8_lp:	ldmia	r1!, {r3, r4, r5, r6}
 
 		mov	ip, r3, lsl #16
@@ -75,6 +76,7 @@
 
 		subs	r2, r2, #8
 		bpl	.outsw_8_lp
+
 		tst	r2, #7
 		LOADREGS(eqfd, sp!, {r4, r5, r6, pc})
 
@@ -121,5 +123,3 @@
 		strne	ip, [r0]
 
 		LOADREGS(fd, sp!, {r4, r5, r6, pc})
-
-
diff -urN linux-2.4.2-pre1/arch/arm/lib/io-writesw-armv4.S linux/arch/arm/lib/io-writesw-armv4.S
--- linux-2.4.2-pre1/arch/arm/lib/io-writesw-armv4.S	Mon Nov 27 17:07:59 2000
+++ linux/arch/arm/lib/io-writesw-armv4.S	Mon Dec  3 22:27:48 2001
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/io-readsb.S
+ *  linux/arch/arm/lib/io-writesw-armv4.S
  *
  *  Copyright (C) 1995-2000 Russell King
  *
@@ -32,11 +32,11 @@
 		tst	r1, #3
 		bne	.outsw_align
 
+		stmfd	sp!, {r4, r5, lr}
+
 		subs	r2, r2, #8
 		bmi	.no_outsw_8
 
-		stmfd	sp!, {r4, r5, lr}
-
 .outsw_8_lp:	ldmia	r1!, {r3, r4, r5, ip}
 
 		strh	r3, [r0]
@@ -54,26 +54,31 @@
 
 		subs	r2, r2, #8
 		bpl	.outsw_8_lp
-		ldmfd	sp!, {r4, r5, lr}
+
 		tst	r2, #7
-		RETINSTR(moveq, pc, lr)
+		LOADREGS(eqfd, sp!, {r4, r5, pc})
 
 .no_outsw_8:	tst	r2, #4
-		ldmneia	r1!, {r3, ip}
-		strneh	r3, [r0]
-		movne	r3, r3, lsr #16
-		strneh	r3, [r0]
-		strneh	ip, [r0]
-		movne	ip, ip, lsr #16
-		strneh	ip, [r0]
-		tst	r2, #2
-		ldrne	r3, [r1], #4
-		strneh	r3, [r0]
-		movne	r3, r3, lsr #16
-		strneh	r3, [r0]
-		tst	r2, #1
+		beq	.no_outsw_4
+
+		ldmia	r1!, {r3, ip}
+		strh	r3, [r0]
+		mov	r3, r3, lsr #16
+		strh	r3, [r0]
+		strh	ip, [r0]
+		mov	ip, ip, lsr #16
+		strh	ip, [r0]
+
+.no_outsw_4:	tst	r2, #2
+		beq	.no_outsw_2
+
+		ldr	r3, [r1], #4
+		strh	r3, [r0]
+		mov	r3, r3, lsr #16
+		strh	r3, [r0]
+
+.no_outsw_2:	tst	r2, #1
 		ldrneh	r3, [r1]
 		strneh	r3, [r0]
-		RETINSTR(mov, pc, lr)
-
 
+		LOADREGS(fd, sp!, {r4, r5, pc})
diff -urN linux-2.4.2-pre1/arch/arm/mach-sa1100/Makefile linux/arch/arm/mach-sa1100/Makefile
--- linux-2.4.2-pre1/arch/arm/mach-sa1100/Makefile	Mon Sep 18 15:15:25 2000
+++ linux/arch/arm/mach-sa1100/Makefile	Mon Dec  3 22:27:48 2001
@@ -20,15 +20,4 @@
 
 obj-$(CONFIG_LEDS)	+= leds.o
 
-# Files that are both resident and modular; remove from modular.
-
-obj-m		:= $(filter-out $(obj-y), $(obj-m))
-
-# Translate to Rules.make lists.
-
-O_OBJS		:= $(filter-out $(export-objs), $(obj-y))
-OX_OBJS 	:= $(filter	$(export-objs), $(obj-y))
-M_OBJS		:= $(sort $(filter-out $(export-objs), $(obj-m)))
-MX_OBJS 	:= $(sort $(filter     $(export-objs), $(obj-m)))
-
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.2-pre1/arch/arm/mach-sa1100/hw.c linux/arch/arm/mach-sa1100/hw.c
--- linux-2.4.2-pre1/arch/arm/mach-sa1100/hw.c	Mon Sep 18 15:15:25 2000
+++ linux/arch/arm/mach-sa1100/hw.c	Mon Dec  3 22:27:48 2001
@@ -90,12 +90,12 @@
 void clr_bitsy_egpio(unsigned long x) 
 {
   bitsy_egpio &= ~x;
-  *(volatile int *)0xdc000000 = bitsy_egpio;
+  BITSY_EGPIO = bitsy_egpio;
 }
 void set_bitsy_egpio(unsigned long x) 
 {
   bitsy_egpio |= x;
-  *(volatile int *)0xdc000000 = bitsy_egpio;
+  BITSY_EGPIO = bitsy_egpio;
 }
 EXPORT_SYMBOL(clr_bitsy_egpio);
 EXPORT_SYMBOL(set_bitsy_egpio);
@@ -119,8 +119,8 @@
   /* First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
    * (SA-1110 Developer's Manual, section 9.1.2.1)
    */
-  GAFR |= GPIO_GPIO27;
-  GPDR |= GPIO_GPIO27;
+  GAFR |= GPIO_32_768kHz;
+  GPDR |= GPIO_32_768kHz;
   TUCR = TUCR_3_6864MHz;
 
   /* Now, set up the PLL and RCLK in the SA-1111: */
@@ -133,32 +133,32 @@
    * using the SKPCR.
    */
 
-  {
-  /*
-   * SA1111 DMA bus master setup 
+  /* If the system is going to use the SA-1111 DMA engines, set up
+   * the memory bus request/grant pins. Also configure the shared
+   * memory controller on the SA-1111 (SA-1111 Developer's Manual,
+   * section 3.2.3) and power up the DMA bus clock:
    */
-	int cas;
+  if(machine_is_assabet()){
 
-	/* SA1111 side */
-	switch ( (MDCNFG>>12) & 0x03 ) {
-	case 0x02:
-		cas = 0; break;
-	case 0x03:
-		cas = 1; break;
-	default:
-		cas = 1; break;
-	}
-	SMCR = 1		/* 1: memory is SDRAM */
-		| ( 1 << 1 )	/* 1:MBGNT is enable */
-		| ( ((MDCNFG >> 4) & 0x07) << 2 )	/* row address lines */
-		| ( cas << 5 );	/* CAS latency */
-
-	/* SA1110 side */
-	GPDR |= 1<<21;
-	GPDR &= ~(1<<22);
-	GAFR |= ( (1<<21) | (1<<22) );
+    GAFR |= (GPIO_MBGNT | GPIO_MBREQ);
+    GPDR |= GPIO_MBGNT;
+    GPDR &= ~GPIO_MBREQ;
+    TUCR |= TUCR_MR;
+
+    /* Assabet is populated by default with two Samsung KM416S8030T-G8
+     * 128Mb SDRAMs, which are organized as 12-bit (row addr) x 9-bit
+     * (column addr), according to the data sheet. Apparently, the 
+     * bank selects factor into the row address, as Angel sets up the
+     * SA-1110 to use 14x9 addresses. The SDRAM datasheet specifies
+     * that when running at 100-125MHz, the CAS latency for -8 parts
+     * is 3 cycles, which is consistent with Angel.
+     */
+
+    SMCR = (SMCR_DTIM | SMCR_MBGE | 
+	    FInsrt(FExtr(MDCNFG, MDCNFG_SA1110_DRAC0), SMCR_DRAC) |
+	    ((FExtr(MDCNFG, MDCNFG_SA1110_TDL0)==3) ? SMCR_CLAT : 0));
 
-	TUCR |= (1<<10);
+    SKPCR |= SKPCR_DCLKEN;
   }
 }
 
diff -urN linux-2.4.2-pre1/arch/arm/mach-shark/Makefile linux/arch/arm/mach-shark/Makefile
--- linux-2.4.2-pre1/arch/arm/mach-shark/Makefile	Mon Sep 18 15:15:25 2000
+++ linux/arch/arm/mach-shark/Makefile	Mon Dec  3 22:27:48 2001
@@ -5,6 +5,8 @@
 # removes any old dependencies. DON'T put your own dependencies here
 # unless it's something special (ie not a .c file).
 
+USE_STANDARD_AS_RULE := true
+
 O_TARGET		:= shark.o
 
 # Object file lists.
@@ -17,16 +19,5 @@
 export-objs		:= 
 
 #obj-$(CONFIG_LEDS)	+= leds.o
-
-# Files that are both resident and modular; remove from modular.
-
-obj-m		:= $(filter-out $(obj-y), $(obj-m))
-
-# Translate to Rules.make lists.
-
-O_OBJS		:= $(filter-out $(export-objs), $(obj-y))
-OX_OBJS 	:= $(filter	$(export-objs), $(obj-y))
-M_OBJS		:= $(sort $(filter-out $(export-objs), $(obj-m)))
-MX_OBJS 	:= $(sort $(filter     $(export-objs), $(obj-m)))
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.2-pre1/arch/arm/mm/Makefile linux/arch/arm/mm/Makefile
--- linux-2.4.2-pre1/arch/arm/mm/Makefile	Mon Sep 18 15:15:25 2000
+++ linux/arch/arm/mm/Makefile	Mon Dec  3 22:27:48 2001
@@ -9,12 +9,11 @@
 
 USE_STANDARD_AS_RULE := true
 
-EXTRA_AFLAGS	:= -traditional
 O_TARGET	:= mm.o
 
 # Object file lists.
 
-obj-y		:= extable.o fault-$(PROCESSOR).o init.o \
+obj-y		:= extable.o fault-common.o fault-$(PROCESSOR).o init.o \
 		   mm-$(PROCESSOR).o small_page.o
 obj-m		:=
 obj-n		:=
@@ -22,10 +21,10 @@
 export-objs	:= proc-syms.o
 
 p-$(CONFIG_CPU_26)	+= proc-arm2,3.o
-p-$(CONFIG_CPU_ARM6)	+= proc-arm6,7.o
-p-$(CONFIG_CPU_ARM7)	+= proc-arm6,7.o
-p-$(CONFIG_CPU_ARM720)	+= proc-arm720.o
-p-$(CONFIG_CPU_ARM920)	+= proc-arm920.o
+p-$(CONFIG_CPU_ARM610)	+= proc-arm6,7.o
+p-$(CONFIG_CPU_ARM710)	+= proc-arm6,7.o
+p-$(CONFIG_CPU_ARM720T)	+= proc-arm720.o
+p-$(CONFIG_CPU_ARM920T)	+= proc-arm920.o
 p-$(CONFIG_CPU_ARM10)	+= proc-arm10.o
 p-$(CONFIG_CPU_SA110)	+= proc-sa110.o
 p-$(CONFIG_CPU_SA1100)	+= proc-sa110.o
@@ -37,29 +36,16 @@
 
 # Integrator follows "new style"
 # Soon, others will do too, and we can get rid of this
-MMMACH		:= mm-$(MACHINE).o
+MMMACH		:= mm-$(MACHINE).c
 ifeq ($(MMMACH),$(wildcard $(MMMACH)))
-obj-$(CONFIG_CPU_32)	+= $(MMMACH)
+obj-$(CONFIG_CPU_32)	+= $(MMMACH:.c=.o)
 endif
 
 obj-y		+= $(sort $(p-y))
 
-# Files that are both resident and modular; remove from modular.
-
-obj-m		:= $(filter-out $(obj-y), $(obj-m))
-
-# Translate to Rules.make lists.
-
-O_OBJS		:= $(filter-out $(export-objs), $(obj-y))
-OX_OBJS 	:= $(filter	$(export-objs), $(obj-y))
-M_OBJS		:= $(sort $(filter-out $(export-objs), $(obj-m)))
-MX_OBJS 	:= $(sort $(filter     $(export-objs), $(obj-m)))
-
 include $(TOPDIR)/Rules.make
 
 # Special dependencies
-fault-armv.o:   fault-common.c
-fault-armo.o:   fault-common.c
 proc-arm2,3.o:	../lib/constants.h
 proc-arm6,7.o:	../lib/constants.h
 proc-arm720.o:	../lib/constants.h
diff -urN linux-2.4.2-pre1/arch/arm/mm/fault-armo.c linux/arch/arm/mm/fault-armo.c
--- linux-2.4.2-pre1/arch/arm/mm/fault-armo.c	Mon Sep 18 15:15:25 2000
+++ linux/arch/arm/mm/fault-armo.c	Mon Dec  3 22:27:48 2001
@@ -23,14 +23,20 @@
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 
-#define FAULT_CODE_FORCECOW	0x80
+#define FAULT_CODE_LDRSTRPOST	0x80
+#define FAULT_CODE_LDRSTRPRE	0x40
+#define FAULT_CODE_LDRSTRREG	0x20
+#define FAULT_CODE_LDMSTM	0x10
+#define FAULT_CODE_LDCSTC	0x08
 #define FAULT_CODE_PREFETCH	0x04
 #define FAULT_CODE_WRITE	0x02
+#define FAULT_CODE_FORCECOW	0x01
 
 #define DO_COW(m)		((m) & (FAULT_CODE_WRITE|FAULT_CODE_FORCECOW))
 #define READ_FAULT(m)		(!((m) & FAULT_CODE_WRITE))
 
-#include "fault-common.c"
+extern int do_page_fault(unsigned long addr, int mode, struct pt_regs *regs);
+extern void show_pte(struct mm_struct *mm, unsigned long addr);
 
 /*
  * Handle a data abort.  Note that we have to handle a range of addresses
diff -urN linux-2.4.2-pre1/arch/arm/mm/fault-armv.c linux/arch/arm/mm/fault-armv.c
--- linux-2.4.2-pre1/arch/arm/mm/fault-armv.c	Mon Sep 18 15:15:25 2000
+++ linux/arch/arm/mm/fault-armv.c	Mon Dec  3 22:27:48 2001
@@ -27,27 +27,9 @@
 #include <asm/pgtable.h>
 #include <asm/unaligned.h>
 
-#define FAULT_CODE_READ		0x02
-
-#define DO_COW(m)		(!((m) & FAULT_CODE_READ))
-#define READ_FAULT(m)		((m) & FAULT_CODE_READ)
-
 extern void die_if_kernel(const char *str, struct pt_regs *regs, int err);
-
-#include "fault-common.c"
-
-#ifdef DEBUG
-static int sp_valid(unsigned long *sp)
-{
-	unsigned long addr = (unsigned long) sp;
-
-	if (addr >= 0xb0000000 && addr < 0xd0000000)
-		return 1;
-	if (addr >= 0x03ff0000 && addr < 0x04000000)
-		return 1;
-	return 0;
-}
-#endif
+extern void show_pte(struct mm_struct *mm, unsigned long addr);
+extern int do_page_fault(unsigned long addr, int mode, struct pt_regs *regs);
 
 #ifdef CONFIG_ALIGNMENT_TRAP
 /*
@@ -178,6 +160,15 @@
 					eaddr -= offset.un;
 			}
 
+			/*
+			 * This is a "hint" - we already have eaddr worked out by the
+			 * processor for us.
+			 */
+			if (addr != eaddr)
+				printk(KERN_ERR "LDRHSTRH: PC = %08lx, instr = %08x, "
+					"addr = %08lx, eaddr = %08lx\n",
+					 instruction_pointer(regs), instr, addr, eaddr);
+
 			if (LDST_L_BIT(instr))
 				regs->uregs[rd] = get_unaligned((unsigned short *)eaddr);
 			else
@@ -253,8 +244,15 @@
 			}
 		}
 
-if (addr != eaddr)
-printk("PC = %08lx, instr = %08x, addr = %08lx, eaddr = %08lx\n", instruction_pointer(regs), instr, addr, eaddr);
+		/*
+		 * This is a "hint" - we already have eaddr worked out by the
+		 * processor for us.
+		 */
+		if (addr != eaddr)
+			printk(KERN_ERR "LDRSTR: PC = %08lx, instr = %08x, "
+				"addr = %08lx, eaddr = %08lx\n",
+				 instruction_pointer(regs), instr, addr, eaddr);
+
 		if (LDST_L_BIT(instr)) {
 			regs->uregs[rd] = get_unaligned((unsigned long *)eaddr);
 			if (rd == 15)
@@ -284,6 +282,15 @@
 		if  (!LDST_U_BIT(instr))
 			eaddr -= nr_regs;
 
+		/*
+		 * This is a "hint" - we already have eaddr worked out by the
+		 * processor for us.
+		 */
+		if (addr != eaddr)
+			printk(KERN_ERR "LDMSTM: PC = %08lx, instr = %08x, "
+				"addr = %08lx, eaddr = %08lx\n",
+				 instruction_pointer(regs), instr, addr, eaddr);
+
 		if ((LDST_U_BIT(instr) == 0 && LDST_P_BIT(instr) == 0) ||
 		    (LDST_U_BIT(instr)      && LDST_P_BIT(instr)))
 			eaddr += 4;
@@ -322,39 +329,39 @@
 
 #endif
 
-#ifdef CONFIG_DEBUG_USER
-
+/*
+ * Some section permission faults need to be handled gracefully, for
+ * instance, when they happen due to a __{get,put}_user during an oops).
+ * In this case, we should return an error to the __{get,put}_user caller
+ * instead of causing another oops.  We should also fixup this fault as
+ * the user could pass a pointer to a section to the kernel.
+ */
 static int
 do_sect_fault(unsigned long addr, int error_code, struct pt_regs *regs)
 {
+	unsigned long fixup;
+
 	if (user_mode(regs)) {
+#ifdef CONFIG_DEBUG_USER
 		printk("%s: permission fault on section, "
 		       "address=0x%08lx, code %d\n",
 		       current->comm, addr, error_code);
+#endif
+		goto fail;
+	}
+
+	fixup = search_exception_table(instruction_pointer(regs));
+	if (fixup != 0) {
 #ifdef DEBUG
-		{
-			unsigned int i, j;
-			unsigned long *sp;
-
-			sp = (unsigned long *) (regs->ARM_sp - 128);
-			for (j = 0; j < 20 && sp_valid(sp); j++) {
-				printk("%p: ", sp);
-				for (i = 0; i < 8 && sp_valid(sp); i += 1, sp++)
-					printk("%08lx ", *sp);
-				printk("\n");
-			}
-			show_regs(regs);
-			c_backtrace(regs->ARM_fp, regs->ARM_cpsr);
-		}
+		printk(KERN_DEBUG "%s: Exception at [<%lx>] addr=%lx (fixup: %lx)\n",
+			tsk->comm, regs->ARM_pc, addr, fixup);
 #endif
+		regs->ARM_pc = fixup;
+		return 0;
 	}
+fail:
 	return 1;	/* not fixed up */
 }
-#else
-
-#define do_sect_fault NULL
-
-#endif
 
 static const struct fsr_info {
 	int	(*fn)(unsigned long addr, int error_code, struct pt_regs *regs);
@@ -382,18 +389,19 @@
 /*
  * Currently dropped down to debug level
  */
-#define BUG_PROC_MSG \
-  KERN_DEBUG "Weird data abort (%08X).\n" \
-  KERN_DEBUG "Please see http://www.arm.linux.org.uk/state.html for " \
-	"more information\n"
-
 asmlinkage void
 do_DataAbort(unsigned long addr, int error_code, struct pt_regs *regs, int fsr)
 {
 	const struct fsr_info *inf = fsr_info + (fsr & 15);
 
+#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100)
 	if (addr == regs->ARM_pc)
-		goto weirdness;
+		goto sa1_weirdness;
+#endif
+#if defined(CONFIG_CPU_ARM720T) && defined(CONFIG_ALIGNMENT_TRAP)
+	if (addr & 3 && (fsr & 13) != 1)
+		goto arm720_weirdness;
+#endif
 
 	if (!inf->fn)
 		goto bad;
@@ -409,26 +417,51 @@
 	die_if_kernel("Oops", regs, 0);
 	return;
 
-weirdness:
+#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100)
+sa1_weirdness:
 	if (user_mode(regs)) {
 		static int first = 1;
 		if (first)
-			/*
-			 * I want statistical information on this problem,
-			 * but we don't want to hastle the users too much.
-			 */
-			printk(BUG_PROC_MSG, fsr);
+			printk(KERN_DEBUG "Weird data abort detected\n");
 		first = 0;
 		return;
 	}
 
 	if (!inf->fn || inf->fn(addr, error_code, regs))
 		goto bad;
+	return;
+#endif
+#if defined(CONFIG_CPU_ARM720T) && defined(CONFIG_ALIGNMENT_TRAP)
+arm720_weirdness:
+	if (!user_mode(regs)) {
+		unsigned long instr;
+
+		instr = *(unsigned long *)instruction_pointer(regs);
+
+		if ((instr & 0x04400000) != 0x04400000) {
+			static int first = 1;
+			if (first)
+				printk("Mis-reported alignment fault at "
+					"0x%08lx, fsr 0x%02x, code 0x%02x, "
+					"PC = 0x%08lx, instr = 0x%08lx\n",
+					addr, fsr, error_code, regs->ARM_pc,
+					instr);
+			first = 0;
+			cpu_tlb_invalidate_all();
+			cpu_cache_clean_invalidate_all();
+			return;
+		}
+	}
+
+	if (!inf->fn || inf->fn(addr, error_code, regs))
+		goto bad;
+	return;
+#endif
 }
 
 asmlinkage int
 do_PrefetchAbort(unsigned long addr, struct pt_regs *regs)
 {
-	do_page_fault(addr, FAULT_CODE_READ, regs);
+	do_page_fault(addr, 0, regs);
 	return 1;
 }
diff -urN linux-2.4.2-pre1/arch/arm/mm/fault-common.c linux/arch/arm/mm/fault-common.c
--- linux-2.4.2-pre1/arch/arm/mm/fault-common.c	Mon Nov 27 17:07:59 2000
+++ linux/arch/arm/mm/fault-common.c	Mon Dec  3 22:27:48 2001
@@ -9,8 +9,41 @@
  * published by the Free Software Foundation.
  */
 #include <linux/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/unaligned.h>
+
+#ifdef CONFIG_CPU_26
+#define FAULT_CODE_WRITE	0x02
+#define FAULT_CODE_FORCECOW	0x01
+#define DO_COW(m)		((m) & (FAULT_CODE_WRITE|FAULT_CODE_FORCECOW))
+#define READ_FAULT(m)		(!((m) & FAULT_CODE_WRITE))
+#else
+/*
+ * On 32-bit processors, we define "mode" to be zero when reading,
+ * non-zero when writing.  This now ties up nicely with the polarity
+ * of the 26-bit machines, and also means that we avoid the horrible
+ * gcc code for "int val = !other_val;".
+ */
+#define DO_COW(m)		(m)
+#define READ_FAULT(m)		(!(m))
+#endif
 
-extern void die(const char *msg, struct pt_regs *regs, int err);
+NORET_TYPE void die(const char *msg, struct pt_regs *regs, int err) ATTRIB_NORET;
 
 /*
  * This is useful to dump out the page tables associated with
@@ -60,7 +93,9 @@
 	printk("\n");
 }
 
-static int __do_page_fault(struct mm_struct *mm, unsigned long addr, int mode, struct task_struct *tsk)
+static int
+__do_page_fault(struct mm_struct *mm, unsigned long addr, int mode,
+		struct task_struct *tsk)
 {
 	struct vm_area_struct *vma;
 	int fault, mask;
@@ -159,7 +194,7 @@
 	return -2;
 }
 
-static int do_page_fault(unsigned long addr, int mode, struct pt_regs *regs)
+int do_page_fault(unsigned long addr, int mode, struct pt_regs *regs)
 {
 	struct task_struct *tsk;
 	struct mm_struct *mm;
@@ -278,8 +313,10 @@
 	 * Oops. The kernel tried to access some bad page. We'll have to
 	 * terminate things with extreme prejudice.
 	 */
-	printk(KERN_ALERT "Unable to handle kernel %s at virtual address %08lx\n",
-		(addr < PAGE_SIZE) ? "NULL pointer dereference" : "paging request", addr);
+	printk(KERN_ALERT
+		"Unable to handle kernel %s at virtual address %08lx\n",
+		(addr < PAGE_SIZE) ? "NULL pointer dereference" :
+		"paging request", addr);
 
 	show_pte(mm, addr);
 	die("Oops", regs, mode);
diff -urN linux-2.4.2-pre1/arch/arm/mm/init.c linux/arch/arm/mm/init.c
--- linux-2.4.2-pre1/arch/arm/mm/init.c	Mon Nov 27 17:07:59 2000
+++ linux/arch/arm/mm/init.c	Mon Dec  3 22:27:48 2001
@@ -49,7 +49,7 @@
 #define TABLE_SIZE	((TABLE_OFFSET + PTRS_PER_PTE) * sizeof(void *))
 
 static unsigned long totalram_pages;
-pgd_t swapper_pg_dir[PTRS_PER_PGD];
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
 extern char _stext, _text, _etext, _end, __init_begin, __init_end;
 
 /*
@@ -418,7 +418,7 @@
 	if (machine_is_archimedes() || machine_is_a5k())
 		reserve_bootmem_node(pgdat, 0x02000000, 0x00080000);
 	if (machine_is_p720t())
-		reserve_bootmem_node(pgdat, 0xc0000000, 0x00014000);
+		reserve_bootmem_node(pgdat, PAGE_OFFSET, 0x00014000);
 }
 
 /*
@@ -450,8 +450,28 @@
 	initrd_node   = check_initrd(mi);
 
 	map_pg = bootmap_pfn;
-	
-	for (node = 0; node < numnodes; node++, np++) {
+
+	/*
+	 * Initialise the bootmem nodes.
+	 *
+	 * What we really want to do is:
+	 *
+	 *   unmap_all_regions_except_kernel();
+	 *   for_each_node_in_reverse_order(node) {
+	 *     map_node(node);
+	 *     allocate_bootmem_map(node);
+	 *     init_bootmem_node(node);
+	 *     free_bootmem_node(node);
+	 *   }
+	 *
+	 * but this is a 2.5-type change.  For now, we just set
+	 * the nodes up in reverse order.
+	 *
+	 * (we could also do with rolling bootmem_init and paging_init
+	 * into one generic "memory_init" type function).
+	 */
+	np += numnodes - 1;
+	for (node = numnodes - 1; node >= 0; node--, np--) {
 		/*
 		 * If there are no pages in this node, ignore it.
 		 * Note that node 0 must always have some pages.
diff -urN linux-2.4.2-pre1/arch/arm/mm/mm-armv.c linux/arch/arm/mm/mm-armv.c
--- linux-2.4.2-pre1/arch/arm/mm/mm-armv.c	Mon Nov 27 17:07:59 2000
+++ linux/arch/arm/mm/mm-armv.c	Mon Dec  3 22:27:48 2001
@@ -275,7 +275,7 @@
 	off    = md->physical - virt;
 	length = md->length;
 
-	while ((virt & 1048575 || (virt + off) & 1048575) && length >= PAGE_SIZE) {
+	while ((virt & 0xfffff || (virt + off) & 0xfffff) && length >= PAGE_SIZE) {
 		alloc_init_page(virt, virt + off, md->domain, prot_pte);
 
 		virt   += PAGE_SIZE;
diff -urN linux-2.4.2-pre1/arch/arm/mm/proc-arm6,7.S linux/arch/arm/mm/proc-arm6,7.S
--- linux-2.4.2-pre1/arch/arm/mm/proc-arm6,7.S	Mon Sep 18 15:15:25 2000
+++ linux/arch/arm/mm/proc-arm6,7.S	Mon Dec  3 22:27:48 2001
@@ -7,10 +7,8 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
- *  MMU functions for ARM6
- *
  *  These are the low level assembler for performing cache and TLB
- *  functions on the ARM6 & ARM7.
+ *  functions on the ARM610 & ARM710.
  */
 #include <linux/linkage.h>
 #include <asm/assembler.h>
@@ -105,9 +103,9 @@
 
 ENTRY(cpu_arm6_data_abort)
 		ldr	r4, [r0]			@ read instruction causing problem
-		mov	r1, r4, lsr #19			@ r1 b1 = L
+		tst	r4, r4, lsr #21			@ C = bit 20
+		sbc	r1, r1, r1			@ r1 = C - 1
 		and	r2, r4, #14 << 24
-		and	r1, r1, #2			@ check read/write bit
 		teq	r2, #8 << 24			@ was it ldm/stm
 		bne	Ldata_simple
 
@@ -138,9 +136,9 @@
 
 ENTRY(cpu_arm7_data_abort)
 		ldr	r4, [r0]			@ read instruction causing problem
-		mov	r1, r4, lsr #19			@ r1 b1 = L
+		tst	r4, r4, lsr #21			@ C = bit 20
+		sbc	r1, r1, r1			@ r1 = C - 1
 		and	r2, r4, #15 << 24
-		and	r1, r1, #2			@ check read/write bit
 		add	pc, pc, r2, lsr #22		@ Now branch to the relevent processing routine
 		movs	pc, lr
 
diff -urN linux-2.4.2-pre1/arch/arm/mm/proc-arm720.S linux/arch/arm/mm/proc-arm720.S
--- linux-2.4.2-pre1/arch/arm/mm/proc-arm720.S	Mon Nov 27 17:07:59 2000
+++ linux/arch/arm/mm/proc-arm720.S	Mon Dec  3 22:27:48 2001
@@ -144,9 +144,9 @@
 
 ENTRY(cpu_arm720_data_abort)
 		ldr	r4, [r0]			@ read instruction causing problem
-		mov	r1, r4, lsr #19			@ r1 b1 = L
+		tst	r4, r4, lsr #21			@ C = bit 20
+		sbc	r1, r1, r1			@ r1 = C - 1
 		and	r2, r4, #15 << 24
-		and	r1, r1, #2			@ check read/write bit
 		add	pc, pc, r2, lsr #22		@ Now branch to the relevent processing routine
 		movs	pc, lr
 
@@ -283,23 +283,11 @@
 		ldmfd	sp!, {pc}
 
 /*
- * Function: arm720_proc_do_idle (void)
- *
- * Params  : r0 = call type:
- *           0 = slow idle
- *           1 = fast idle
- *           2 = switch to slow processor clock
- *           3 = switch to fast processor clock
- *
+ * Function: arm720_proc_do_idle(void)
+ * Params  : r0 = unused
  * Purpose : put the processer in proper idle mode
  */
 ENTRY(cpu_arm720_do_idle)
-#if 0 /* FIXME: is this part of the processor? */
-		ldr	r2, =IO_BASE			@ Virt addr of IO
-		add	r2, r2, #0x00050000		@ Start of PMU regs
-		mov	r1, #0x01			@ Idle mode
-		str	r1, [r2, #4]
-#endif
 		mov	pc, lr
 
 /*
diff -urN linux-2.4.2-pre1/arch/arm/mm/proc-arm920.S linux/arch/arm/mm/proc-arm920.S
--- linux-2.4.2-pre1/arch/arm/mm/proc-arm920.S	Mon Sep 18 15:15:25 2000
+++ linux/arch/arm/mm/proc-arm920.S	Mon Dec  3 22:27:48 2001
@@ -68,9 +68,9 @@
 ENTRY(cpu_arm920_data_abort)
 	ldr	r1, [r0]			@ read aborted instruction
 	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
-	mov	r1, r1, lsr #19			@ b1 = L
+	tst	r1, r1, lsr #21			@ C = bit 20
 	mrc	p15, 0, r3, c5, c0, 0		@ get FSR
-	and	r1, r1, #2
+	sbc	r1, r1, r1			@ r1 = C - 1
 	and	r3, r3, #255
 	mov	pc, lr
 
@@ -330,7 +330,7 @@
 	mov	r0, #0
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 ENTRY(cpu_arm920_icache_invalidate_page)
-	/* why no invalidate I cache --rmk */
+	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
 	mov	pc, lr
 
 
diff -urN linux-2.4.2-pre1/arch/arm/mm/proc-sa110.S linux/arch/arm/mm/proc-sa110.S
--- linux-2.4.2-pre1/arch/arm/mm/proc-sa110.S	Mon Sep 18 15:15:25 2000
+++ linux/arch/arm/mm/proc-sa110.S	Mon Dec  3 22:27:48 2001
@@ -83,9 +83,9 @@
 ENTRY(cpu_sa1100_data_abort)
 	ldr	r1, [r0]			@ read aborted instruction
 	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
-	mov	r1, r1, lsr #19			@ b1 = L
+	tst	r1, r1, lsr #21			@ C = bit 20
 	mrc	p15, 0, r3, c5, c0, 0		@ get FSR
-	and	r1, r1, #2
+	sbc	r1, r1, r1			@ r1 = C - 1
 	and	r3, r3, #255
 	mov	pc, lr
 
diff -urN linux-2.4.2-pre1/arch/arm/nwfpe/Makefile linux/arch/arm/nwfpe/Makefile
--- linux-2.4.2-pre1/arch/arm/nwfpe/Makefile	Sun Aug 13 09:54:15 2000
+++ linux/arch/arm/nwfpe/Makefile	Mon Dec  3 22:27:48 2001
@@ -6,27 +6,27 @@
 
 USE_STANDARD_AS_RULE := true
 
-NWFPE_OBJS := fpa11.o fpa11_cpdo.o fpa11_cpdt.o fpa11_cprt.o \
-	      fpmodule.o fpopcode.o softfloat.o \
-	      single_cpdo.o double_cpdo.o extended_cpdo.o
+O_TARGET		:= math-emu.o
 
-ifeq ($(CONFIG_CPU_26),y)
-NWFPE_OBJS += entry26.o
-else
-NWFPE_OBJS += entry.o
-endif
+obj-y			:=
+obj-m			:=
+obj-n			:=
+
+list-multi		:= nwfpe.o
 
-ifeq ($(CONFIG_NWFPE),y)
-O_TARGET := math-emu.o
-O_OBJS = $(NWFPE_OBJS)
+obj-$(CONFIG_NWFPE)	+= nwfpe.o
+
+nwfpe-objs		:= fpa11.o fpa11_cpdo.o fpa11_cpdt.o fpa11_cprt.o \
+			   fpmodule.o fpopcode.o softfloat.o \
+			   single_cpdo.o double_cpdo.o extended_cpdo.o
+
+ifeq ($(CONFIG_CPU_26),y)
+nwfpe-objs		+= entry26.o
 else
-  ifeq ($(CONFIG_NWFPE),m)
-    M_OBJS = nwfpe.o
-    MI_OBJS = $(NWFPE_OBJS)
-  endif
+nwfpe-objs		+= entry.o
 endif
 
 include $(TOPDIR)/Rules.make
 
-nwfpe.o: $(MI_OBJS) $(MIX_OBJS)
-	 $(LD) $(LD_RFLAG) -r -o $@ $(MI_OBJS) $(MIX_OBJS)
+nwfpe.o: $(nwfpe-objs)
+	$(LD) -r -o $@ $(nwfpe-objs)
diff -urN linux-2.4.2-pre1/arch/arm/vmlinux-armo.lds.in linux/arch/arm/vmlinux-armo.lds.in
--- linux-2.4.2-pre1/arch/arm/vmlinux-armo.lds.in	Mon Nov 27 17:07:59 2000
+++ linux/arch/arm/vmlinux-armo.lds.in	Mon Dec  3 22:27:48 2001
@@ -47,6 +47,8 @@
 			*(.gnu.warning)
 			*(.text.lock)	/* out-of-line lock text */
 			*(.rodata)
+			*(.glue_7)
+			*(.glue_7t)
 			*(.kstrtab)
 		. = ALIGN(16);		/* Exception table		*/
 		__start___ex_table = .;
diff -urN linux-2.4.2-pre1/arch/arm/vmlinux-armv.lds.in linux/arch/arm/vmlinux-armv.lds.in
--- linux-2.4.2-pre1/arch/arm/vmlinux-armv.lds.in	Mon Nov 27 17:07:59 2000
+++ linux/arch/arm/vmlinux-armv.lds.in	Mon Dec  3 22:27:48 2001
@@ -42,6 +42,8 @@
 			*(.gnu.warning)
 			*(.text.lock)	/* out-of-line lock text */
 			*(.rodata)
+			*(.glue_7)
+			*(.glue_7t)
 			*(.kstrtab)
 		. = ALIGN(16);
 		__start___ex_table = .;	/* Exception table		*/
diff -urN linux-2.4.2-pre1/arch/cris/Makefile linux/arch/cris/Makefile
--- linux-2.4.2-pre1/arch/cris/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/Makefile	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,96 @@
+# $Id: Makefile,v 1.11 2000/11/27 17:58:30 bjornw Exp $
+# cris/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies. Remember to do have actions
+# for "archclean" and "archdep" for cleaning up and making dependencies for
+# this architecture
+#
+# 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.
+
+LD_SCRIPT=$(TOPDIR)/arch/cris/cris.ld
+
+# A bug in ld prevents us from having a (constant-value) symbol in a
+# "ORIGIN =" or "LENGTH =" expression.  We fix that by generating a
+# linker file with the symbolic part of those expressions evaluated.
+#  Unfortunately, there is trouble making vmlinux depend on anything we
+# generate here, so we *always* regenerate the final linker script and
+# replace the LD macro to get what we want.  Thankfully(?) vmlinux is
+# always rebuilt (due to calling make recursively and not knowing if
+# anything was rebuilt).
+#  The shell script to build in some kind of dependency is really not
+# necessary for reasons of speed.  It's there because always
+# regenerating stuff (even for incremental linking of subsystems!) is
+# even more nauseating.
+LD = if [ ! -e $(LD_SCRIPT).tmp -o $(LD_SCRIPT) -nt $(LD_SCRIPT).tmp ]; then \
+          sed -e s/@ETRAX_DRAM_BASE@/0x$(ETRAX_DRAM_BASE)/ \
+              -e s/@ETRAX_DRAM_SIZE_M@/$(ETRAX_DRAM_SIZE)/ \
+              < $(LD_SCRIPT) > $(LD_SCRIPT).tmp; \
+     else true; \
+     fi && $(CROSS_COMPILE)ld -mcriself
+
+LINKFLAGS =-qmagic -mcriself -T $(LD_SCRIPT).tmp
+
+# objcopy is used to make binary images from the resulting linked file
+
+OBJCOPY := $(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S
+
+# normally, gcc on a linux box adds __linux__ but we do it "manually"
+# gcc-cris defaults to a.out, we need ELF, so -melf
+
+CFLAGS := $(CFLAGS) -march=v10 -fno-strict-aliasing -pipe -D__linux__
+
+ifdef CONFIG_KGDB
+CFLAGS := $(subst -fomit-frame-pointer,,$(CFLAGS)) -g
+CFLAGS += -fno-omit-frame-pointer
+endif
+
+HEAD := arch/cris/kernel/head.o
+
+SUBDIRS += arch/cris/kernel arch/cris/mm arch/cris/lib arch/cris/drivers
+CORE_FILES += arch/cris/kernel/kernel.o arch/cris/mm/mm.o arch/cris/drivers/drivers.o
+LIBGCC = $(shell $(CC) $(CFLAGS) -print-file-name=libgcc.a)
+LIBS := $(TOPDIR)/arch/cris/lib/lib.a $(LIBS) $(TOPDIR)/arch/cris/lib/lib.a $(LIBGCC)
+
+arch/cris/kernel: dummy
+	$(MAKE) linuxsubdirs SUBDIRS=arch/cris/kernel
+
+arch/cris/mm: dummy
+	$(MAKE) linuxsubdirs SUBDIRS=arch/cris/mm
+
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
+vmlinux.bin: vmlinux
+	$(OBJCOPY) vmlinux vmlinux.bin
+
+timage: vmlinux.bin
+	cat vmlinux.bin cramfs.img >timage
+
+simimage: timage
+	cp vmlinux.bin simvmlinux.bin
+
+# the following will remake timage without compiling the kernel
+# it does of course require that all object files exist...
+
+cramfs:
+## cramfs      - Creates a cramfs image
+	mkcramfs -p 8192 root cramfs.img
+	cat vmlinux.bin cramfs.img >timage
+
+zImage: vmlinux
+## zImage     - Compressed kernel (gzip)
+	@$(MAKEBOOT) zImage
+
+compressed: zImage
+
+archclean:
+	@$(MAKEBOOT) clean
+	rm -f timage vmlinux.bin cramfs.img
+	rm -rf $(LD_SCRIPT).tmp
+
+archmrproper:
+
+archdep:
+	@$(MAKEBOOT) dep
diff -urN linux-2.4.2-pre1/arch/cris/README.mm linux/arch/cris/README.mm
--- linux-2.4.2-pre1/arch/cris/README.mm	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/README.mm	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,241 @@
+Memory management for CRIS/MMU
+------------------------------
+HISTORY:
+
+$Log: README.mm,v $
+Revision 1.1  2000/07/10 16:25:21  bjornw
+Initial revision
+
+Revision 1.4  2000/01/17 02:31:59  bjornw
+Added discussion of paging and VM.
+
+Revision 1.3  1999/12/03 16:43:23  hp
+Blurb about that the 3.5G-limitation is not a MMU limitation
+
+Revision 1.2  1999/12/03 16:04:21  hp
+Picky comment about not mapping the first page
+
+Revision 1.1  1999/12/03 15:41:30  bjornw
+First version of CRIS/MMU memory layout specification.
+
+
+
+
+
+------------------------------
+
+See the ETRAX-NG HSDD for reference.
+
+We use the page-size of 8 kbytes, as opposed to the i386 page-size of 4 kbytes.
+
+The MMU can, apart from the normal mapping of pages, also do a top-level
+segmentation of the kernel memory space. We use this feature to avoid having
+to use page-tables to map the physical memory into the kernel's address
+space. We also use it to keep the user-mode virtual mapping in the same
+map during kernel-mode, so that the kernel easily can access the corresponding
+user-mode process' data.
+
+As a comparision, the Linux/i386 2.0 puts the kernel and physical RAM at
+address 0, overlapping with the user-mode virtual space, so that descriptor
+registers are needed for each memory access to specify which MMU space to
+map through. That changed in 2.2, putting the kernel/physical RAM at 
+0xc0000000, to co-exist with the user-mode mapping. We will do something
+quite similar, but with the additional complexity of having to map the
+internal chip I/O registers and the flash memory area (including SRAM
+and peripherial chip-selets).
+
+The kernel-mode segmentation map:
+
+        ------------------------                ------------------------
+FFFFFFFF|                      | => cached      |                      | 
+        |    kernel seg_f      |    flash       |                      |
+F0000000|______________________|                |                      |
+EFFFFFFF|                      | => uncached    |                      | 
+        |    kernel seg_e      |    flash       |                      |
+E0000000|______________________|                |        DRAM          |
+DFFFFFFF|                      |  paged to any  |      Un-cached       | 
+        |    kernel seg_d      |    =======>    |                      |
+D0000000|______________________|                |                      |
+CFFFFFFF|                      |                |                      | 
+        |    kernel seg_c      |==\             |                      |
+C0000000|______________________|   \            |______________________|
+BFFFFFFF|                      |  uncached      |                      |
+        |    kernel seg_b      |=====\=========>|       Registers      |
+B0000000|______________________|      \c        |______________________|
+AFFFFFFF|                      |       \a       |                      |
+        |                      |        \c      | FLASH/SRAM/Peripheral|
+        |                      |         \h     |______________________|
+        |                      |          \e    |                      |
+        |                      |           \d   |                      |
+        | kernel seg_0 - seg_a |            \==>|         DRAM         | 
+        |                      |                |        Cached        |
+        |                      |  paged to any  |                      |
+        |                      |    =======>    |______________________| 
+        |                      |                |                      |
+        |                      |                |        Illegal       |
+        |                      |                |______________________|
+        |                      |                |                      |      
+        |                      |                | FLASH/SRAM/Peripheral|
+00000000|______________________|                |______________________|
+
+In user-mode it looks the same except that only the space 0-AFFFFFFF is
+available. Therefore, in this model, the virtual address space per process
+is limited to 0xb0000000 bytes (minus 8192 bytes, since the first page,
+0..8191, is never mapped, in order to trap NULL references).
+
+It also means that the total physical RAM that can be mapped is 256 MB
+(kseg_c above). More RAM can be mapped by choosing a different segmentation
+and shrinking the user-mode memory space.
+
+The MMU can map all 4 GB in user mode, but doing that would mean that a
+few extra instructions would be needed for each access to user mode
+memory.
+
+The kernel needs access to both cached and uncached flash. Uncached is
+necessary because of the special write/erase sequences. Also, the 
+peripherial chip-selects are decoded from that region.
+
+The kernel also needs its own virtual memory space. That is kseg_d. It
+is used by the vmalloc() kernel function to allocate virtual contiguous
+chunks of memory not possible using the normal kmalloc physical RAM 
+allocator.
+
+The setting of the actual MMU control registers to use this layout would
+be something like this:
+
+R_MMU_KSEG = ( ( seg_f, seg     ) |   // Flash cached
+               ( seg_e, seg     ) |   // Flash uncached
+               ( seg_d, page    ) |   // kernel vmalloc area    
+               ( seg_c, seg     ) |   // kernel linear segment
+               ( seg_b, seg     ) |   // kernel linear segment
+               ( seg_a, page    ) |
+               ( seg_9, page    ) |
+               ( seg_8, page    ) |
+               ( seg_7, page    ) |
+               ( seg_6, page    ) |
+               ( seg_5, page    ) |
+               ( seg_4, page    ) |
+               ( seg_3, page    ) |
+               ( seg_2, page    ) |
+               ( seg_1, page    ) |
+               ( seg_0, page    ) );
+
+R_MMU_KBASE_HI = ( ( base_f, 0x0 ) |   // flash/sram/periph cached
+                   ( base_e, 0x8 ) |   // flash/sram/periph uncached
+                   ( base_d, 0x0 ) |   // don't care
+                   ( base_c, 0x4 ) |   // physical RAM cached area
+                   ( base_b, 0xb ) |   // uncached on-chip registers
+                   ( base_a, 0x0 ) |   // don't care
+                   ( base_9, 0x0 ) |   // don't care
+                   ( base_8, 0x0 ) );  // don't care
+
+R_MMU_KBASE_LO = ( ( base_7, 0x0 ) |   // don't care
+                   ( base_6, 0x0 ) |   // don't care
+                   ( base_5, 0x0 ) |   // don't care
+                   ( base_4, 0x0 ) |   // don't care
+                   ( base_3, 0x0 ) |   // don't care
+                   ( base_2, 0x0 ) |   // don't care
+                   ( base_1, 0x0 ) |   // don't care
+                   ( base_0, 0x0 ) );  // don't care
+
+NOTE: while setting up the MMU, we run in a non-mapped mode in the DRAM (0x40
+segment) and need to setup the seg_4 to a unity mapping, so that we don't get
+a fault before we have had time to jump into the real kernel segment (0xc0). This
+is done in head.S temporarily, but fixed by the kernel later in paging_init.
+
+
+Paging - PTE's, PMD's and PGD's
+-------------------------------
+
+[ References: asm/pgtable.h, asm/page.h, asm/mmu.h ]
+
+The paging mechanism uses virtual addresses to split a process memory-space into
+pages, a page being the smallest unit that can be freely remapped in memory. On
+Linux/CRIS, a page is 8192 bytes (for technical reasons not equal to 4096 as in 
+most other 32-bit architectures). It would be inefficient to let a virtual memory
+mapping be controlled by a long table of page mappings, so it is broken down into
+a 2-level structure with a Page Directory containing pointers to Page Tables which
+each have maps of up to 2048 pages (8192 / sizeof(void *)). Linux can actually
+handle 3-level structures as well, with a Page Middle Directory in between, but
+in many cases, this is folded into a two-level structure by excluding the Middle
+Directory.
+
+We'll take a look at how an address is translated while we discuss how it's handled
+in the Linux kernel.
+
+The example address is 0xd004000c; in binary this is:
+
+31       23       15       7      0
+11010000 00000100 00000000 00001100
+
+|______| |__________||____________|
+  PGD        PTE       page offset
+
+Given the top-level Page Directory, the offset in that directory is calculated
+using the upper 8 bits:
+
+extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
+{
+	return mm->pgd + (address >> PGDIR_SHIFT);
+}
+
+PGDIR_SHIFT is the log2 of the amount of memory an entry in the PGD can map; in our
+case it is 24, corresponding to 16 MB. This means that each entry in the PGD 
+corresponds to 16 MB of virtual memory.
+
+The pgd_t from our example will therefore be the 208'th (0xd0) entry in mm->pgd.
+
+Since the Middle Directory does not exist, it is a unity mapping:
+
+extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
+{
+	return (pmd_t *) dir;
+}
+
+The Page Table provides the final lookup by using bits 13 to 23 as index:
+
+extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address)
+{
+	return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) &
+					   (PTRS_PER_PTE - 1));
+}
+
+PAGE_SHIFT is the log2 of the size of a page; 13 in our case. PTRS_PER_PTE is
+the number of pointers that fit in a Page Table and is used to mask off the 
+PGD-part of the address.
+
+The so-far unused bits 0 to 12 are used to index inside a page linearily.
+
+The VM system
+-------------
+
+The kernels own page-directory is the swapper_pg_dir, cleared in paging_init, 
+and contains the kernels virtual mappings (the kernel itself is not paged - it
+is mapped linearily using kseg_c as described above). Architectures without
+kernel segments like the i386, need to setup swapper_pg_dir directly in head.S
+to map the kernel itself. swapper_pg_dir is pointed to by init_mm.pgd as the
+init-task's PGD.
+
+To see what support functions are used to setup a page-table, let's look at the
+kernel's internal paged memory system, vmalloc/vfree.
+
+void * vmalloc(unsigned long size)
+
+The vmalloc-system keeps a paged segment in kernel-space at 0xd0000000. What
+happens first is that a virtual address chunk is allocated to the request using
+get_vm_area(size). After that, physical RAM pages are allocated and put into
+the kernel's page-table using alloc_area_pages(addr, size). 
+
+static int alloc_area_pages(unsigned long address, unsigned long size)
+
+First the PGD entry is found using init_mm.pgd. This is passed to
+alloc_area_pmd (remember the 3->2 folding). It uses pte_alloc_kernel to
+check if the PGD entry points anywhere - if not, a page table page is
+allocated and the PGD entry updated. Then the alloc_area_pte function is
+used just like alloc_area_pmd to check which page table entry is desired, 
+and a physical page is allocated and the table entry updated. All of this
+is repeated at the top-level until the entire address range specified has 
+been mapped.
+
+
+
diff -urN linux-2.4.2-pre1/arch/cris/boot/Makefile linux/arch/cris/boot/Makefile
--- linux-2.4.2-pre1/arch/cris/boot/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/boot/Makefile	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,14 @@
+#
+# arch/cris/boot/Makefile
+#
+
+zImage: compressed/vmlinuz
+
+compressed/vmlinuz: $(TOPDIR)/vmlinux
+	@$(MAKE) -C compressed vmlinuz
+
+dep:
+
+clean:
+	rm -f zImage tools/build compressed/vmlinux.out
+	@$(MAKE) -C compressed clean
diff -urN linux-2.4.2-pre1/arch/cris/boot/compressed/Makefile linux/arch/cris/boot/compressed/Makefile
--- linux-2.4.2-pre1/arch/cris/boot/compressed/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/boot/compressed/Makefile	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,37 @@
+#
+# linux/arch/etrax100/boot/compressed/Makefile
+#
+# create a compressed vmlinux image from the original vmlinux files and romfs
+#
+
+CC = gcc-cris -melf -I $(TOPDIR)/include
+CFLAGS = -O2
+LD = ld-cris
+OBJCOPY = objcopy-cris
+
+OBJECTS = head.o misc.o
+
+# files to compress
+SYSTEM = $(TOPDIR)/vmlinux.bin
+
+all: vmlinuz
+
+vmlinuz: piggy.img $(OBJECTS)
+	$(LD) -mcriself -T decompress.ld -o decompress.o $(OBJECTS)
+	$(OBJCOPY) -O binary --remove-section=.bss decompress.o decompress.bin
+# save it for mkprod in the topdir.
+	cp decompress.bin $(TOPDIR)
+	cat decompress.bin piggy.img $(TOPDIR)/cramfs.img > vmlinuz
+	rm -f piggy.img
+
+head.o: head.S
+	$(CC) -D__ASSEMBLY__ -traditional -c head.S -o head.o
+
+# gzip the kernel image
+
+piggy.img: $(SYSTEM)
+	cat $(SYSTEM) | gzip -f -9 > piggy.img
+
+clean:
+	rm -f piggy.img vmlinuz vmlinuz.o
+
diff -urN linux-2.4.2-pre1/arch/cris/boot/compressed/README linux/arch/cris/boot/compressed/README
--- linux-2.4.2-pre1/arch/cris/boot/compressed/README	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/boot/compressed/README	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,25 @@
+Creation of the self-extracting compressed kernel image (vmlinuz)
+-----------------------------------------------------------------
+$Id: README,v 1.1 2000/11/22 17:20:46 bjornw Exp $
+
+This can be slightly confusing because it's a process with many steps.
+
+The kernel object built by the arch/etrax100/Makefile, vmlinux, is split
+by that makefile into text and data binary files, vmlinux.text and 
+vmlinux.data.
+
+Those files together with a ROM filesystem can be catted together and
+burned into a flash or executed directly at the DRAM origin.
+
+They can also be catted together and compressed with gzip, which is what
+happens in this makefile. Together they make up piggy.img. 
+
+The decompressor is built into the file decompress.o. It is turned into
+the binary file decompress.bin, which is catted together with piggy.img
+into the file vmlinuz. It can be executed in an arbitrary place in flash.
+
+Be careful - it assumes some things about free locations in DRAM. It
+assumes the DRAM starts at 0x40000000 and that it is at least 8 MB,
+so it puts its code at 0x40700000, and initial stack at 0x40800000.
+
+-Bjorn
diff -urN linux-2.4.2-pre1/arch/cris/boot/compressed/decompress.ld linux/arch/cris/boot/compressed/decompress.ld
--- linux-2.4.2-pre1/arch/cris/boot/compressed/decompress.ld	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/boot/compressed/decompress.ld	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,26 @@
+MEMORY 
+	{
+	dram : ORIGIN = 0x40700000,
+	       LENGTH = 0x00100000
+	}
+
+SECTIONS
+{
+	.text :
+	{
+		_stext = . ;
+		*(.text)
+		*(.rodata)
+		_etext = . ;
+	} > dram
+	.data :
+	{
+		*(.data)
+		_edata = . ;
+	} > dram
+	.bss :
+	{
+		*(.bss)
+		_end = ALIGN( 0x10 ) ;
+	} > dram
+}
diff -urN linux-2.4.2-pre1/arch/cris/boot/compressed/head.S linux/arch/cris/boot/compressed/head.S
--- linux-2.4.2-pre1/arch/cris/boot/compressed/head.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/boot/compressed/head.S	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,100 @@
+/*
+ *  arch/etrax100/boot/compressed/head.S
+ *
+ *  Copyright (C) 1999 Axis Communications AB
+ *
+ *  Code that sets up the DRAM registers, calls the
+ *  decompressor to unpack the piggybacked kernel, and jumps.
+ *
+ */
+
+#include <linux/config.h>
+#define ASSEMBLER_MACROS_ONLY
+#include <asm/sv_addr_ag.h>
+
+	;; Exported symbols
+	
+	.globl	_input_data
+
+	
+	.text
+
+	nop
+	di
+
+#ifndef CONFIG_SVINTO_SIM	
+
+	;; We need to setup the bus registers before we start using the DRAM
+
+	move.d   DEF_R_WAITSTATES, r0
+	move.d   r0, [R_WAITSTATES]
+
+	move.d   DEF_R_BUS_CONFIG, r0
+	move.d   r0, [R_BUS_CONFIG]
+  
+	move.d   DEF_R_DRAM_CONFIG, r0
+	move.d   r0, [R_DRAM_CONFIG]
+
+	move.d   DEF_R_DRAM_TIMING, r0
+	move.d   r0, [R_DRAM_TIMING]
+
+#endif
+
+	;; Setup the stack to a suitably high address.
+	;; We assume 8 MB is the minimum DRAM in an eLinux
+	;; product and put the sp at the top for now.
+
+	move.d	0x40800000, sp
+
+	;; Figure out where the compressed piggyback image is
+	;; in the flash (since we wont try to copy it to DRAM
+	;; before unpacking). It is at _edata, but in flash.
+	;; Use (_edata - basse) as offset to the current PC.
+	
+basse:	move.d	pc, r5
+	and.d	0x7fffffff, r5	; strip any non-cache bit
+	subq	2, r5		; compensate for the move.d pc instr
+	move.d	r5, r0		; save for later - flash address of 'basse'
+	add.d	_edata, r5
+	sub.d	basse, r5	; r5 = flash address of '_edata'
+	
+	;; Copy text+data to DRAM
+	
+	move.d	basse, r1	; destination
+	move.d	_edata, r2	; end destination
+1:	move.w	[r0+], r3
+	move.w	r3, [r1+]
+	cmp.d	r2, r1
+	bcs	1b
+	nop
+
+	move.d	r5, [_input_data] ; for the decompressor
+
+	;; Clear the decompressors BSS (between _edata and _end)
+	
+	moveq	0, r0
+	move.d	_edata, r1
+	move.d	_end, r2
+1:	move.w	r0, [r1+]
+	cmp.d	r2, r1
+	bcs	1b
+	nop
+	
+	;; Do the decompression and save compressed size in _inptr
+	
+	jsr	_decompress_kernel
+
+	;; Put start address of cramfs in r9 so the kernel can use it
+	;; when mounting from flash
+
+	move.d	[_input_data], r9	; flash address of compressed kernel
+	add.d	[_inptr], r9		; size of compressed kernel
+
+	;; Enter the decompressed kernel
+		
+	jump	0x40004000	; kernel is linked to this address
+	
+	.data
+
+_input_data:
+	.dword	0		; used by the decompressor
diff -urN linux-2.4.2-pre1/arch/cris/boot/compressed/misc.c linux/arch/cris/boot/compressed/misc.c
--- linux-2.4.2-pre1/arch/cris/boot/compressed/misc.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/boot/compressed/misc.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,260 @@
+/*
+ * misc.c
+ *
+ * $Id: misc.c,v 1.3 2001/01/17 15:54:18 jonashg Exp $
+ * 
+ * This is a collection of several routines from gzip-1.0.3 
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ * puts by Nick Holloway 1993, better puts by Martin Mares 1995
+ * adoptation for Linux/CRIS Axis Communications AB, 1999
+ * 
+ */
+
+/* where the piggybacked kernel image expects itself to live.
+ * it is the same adress we use when we network load an uncompressed
+ * image into DRAM, and it is the address the kernel is linked to live
+ * at by etrax100.ld.
+ */
+
+#define KERNEL_LOAD_ADR 0x40004000
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <asm/svinto.h>
+
+/*
+ * gzip declarations
+ */
+
+#define OF(args)  args
+#define STATIC static
+
+void* memset(void* s, int c, size_t n);
+void* memcpy(void* __dest, __const void* __src,
+	     size_t __n);
+
+#define memzero(s, n)     memset ((s), 0, (n))
+
+
+typedef unsigned char  uch;
+typedef unsigned short ush;
+typedef unsigned long  ulg;
+
+#define WSIZE 0x8000		/* Window size must be at least 32k, */
+				/* and a power of two */
+
+static uch *inbuf;	     /* input buffer */
+static uch window[WSIZE];    /* Sliding window buffer */
+
+unsigned inptr = 0;	/* index of next byte to be processed in inbuf
+			 * After decompression it will contain the
+			 * compressed size, and head.S will read it.
+			 */
+
+static unsigned outcnt = 0;  /* bytes in output buffer */
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
+#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
+#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
+#define COMMENT      0x10 /* bit 4 set: file comment present */
+#define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
+#define RESERVED     0xC0 /* bit 6,7:   reserved */
+
+#define get_byte() inbuf[inptr++]	
+	
+/* Diagnostic functions */
+#ifdef DEBUG
+#  define Assert(cond,msg) {if(!(cond)) error(msg);}
+#  define Trace(x) fprintf x
+#  define Tracev(x) {if (verbose) fprintf x ;}
+#  define Tracevv(x) {if (verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+static int  fill_inbuf(void);
+static void flush_window(void);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+extern char *input_data;  /* lives in head.S */
+
+static long bytes_out = 0;
+static uch *output_data;
+static unsigned long output_ptr = 0;
+ 
+static void *malloc(int size);
+static void free(void *where);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+ 
+static void puts(const char *);
+
+/* the "heap" is put directly after the BSS ends, at end */
+  
+extern int end;
+static long free_mem_ptr = (long)&end;
+ 
+#include "../../../../lib/inflate.c"
+
+static void *malloc(int size)
+{
+	void *p;
+
+	if (size <0) error("Malloc error\n");
+
+	free_mem_ptr = (free_mem_ptr + 3) & ~3;	/* Align */
+
+	p = (void *)free_mem_ptr;
+	free_mem_ptr += size;
+
+	return p;
+}
+
+static void free(void *where)
+{	/* Don't care */
+}
+
+static void gzip_mark(void **ptr)
+{
+	*ptr = (void *) free_mem_ptr;
+}
+
+static void gzip_release(void **ptr)
+{
+	free_mem_ptr = (long) *ptr;
+}
+
+/* decompressor info and error messages to serial console */
+
+static void
+puts(const char *s)
+{
+#ifndef CONFIG_DEBUG_PORT_NULL
+	while(*s) {
+#ifdef CONFIG_DEBUG_PORT0
+		while(!(*R_SERIAL0_STATUS & (1 << 5))) ;
+		*R_SERIAL0_TR_DATA = *s++;
+#endif
+#ifdef CONFIG_DEBUG_PORT1
+		while(!(*R_SERIAL1_STATUS & (1 << 5))) ;
+		*R_SERIAL1_TR_DATA = *s++;
+#endif
+#ifdef CONFIG_DEBUG_PORT2
+		while(!(*R_SERIAL2_STATUS & (1 << 5))) ;
+		*R_SERIAL2_TR_DATA = *s++;
+#endif
+#ifdef CONFIG_DEBUG_PORT3
+		while(!(*R_SERIAL3_STATUS & (1 << 5))) ;
+		*R_SERIAL3_TR_DATA = *s++;
+#endif
+	}
+#endif
+}
+
+void*
+memset(void* s, int c, size_t n)
+{
+	int i;
+	char *ss = (char*)s;
+
+	for (i=0;i<n;i++) ss[i] = c;
+}
+
+void*
+memcpy(void* __dest, __const void* __src,
+			    size_t __n)
+{
+	int i;
+	char *d = (char *)__dest, *s = (char *)__src;
+
+	for (i=0;i<__n;i++) d[i] = s[i];
+}
+
+/* ===========================================================================
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+
+static void
+flush_window()
+{
+    ulg c = crc;         /* temporary variable */
+    unsigned n;
+    uch *in, *out, ch;
+    
+    in = window;
+    out = &output_data[output_ptr]; 
+    for (n = 0; n < outcnt; n++) {
+	    ch = *out++ = *in++;
+	    c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+    }
+    crc = c;
+    bytes_out += (ulg)outcnt;
+    output_ptr += (ulg)outcnt;
+    outcnt = 0;
+}
+
+static void
+error(char *x)
+{
+	puts("\n\n");
+	puts(x);
+	puts("\n\n -- System halted\n");
+
+	while(1);	/* Halt */
+}
+
+void
+setup_normal_output_buffer()
+{
+	output_data = (char *)KERNEL_LOAD_ADR;
+}
+
+void
+decompress_kernel()
+{
+	/* input_data is set in head.S */
+	inbuf = input_data;
+
+#ifdef CONFIG_DEBUG_PORT0
+	*R_SERIAL0_XOFF = 0;
+	*R_SERIAL0_BAUD = 0x99;
+	*R_SERIAL0_TR_CTRL = 0x40;
+#endif
+#ifdef CONFIG_DEBUG_PORT1
+	*R_SERIAL1_XOFF = 0;
+	*R_SERIAL1_BAUD = 0x99;
+	*R_SERIAL1_TR_CTRL = 0x40;
+#endif
+#ifdef CONFIG_DEBUG_PORT2
+	*R_SERIAL2_XOFF = 0;
+	*R_SERIAL2_BAUD = 0x99;
+	*R_SERIAL2_TR_CTRL = 0x40;
+#endif
+#ifdef CONFIG_DEBUG_PORT3
+	*R_SERIAL3_XOFF = 0;
+	*R_SERIAL3_BAUD = 0x99;
+	*R_SERIAL3_TR_CTRL = 0x40;
+#endif
+       
+	setup_normal_output_buffer();
+
+	makecrc();
+	puts("Uncompressing Linux...\n");
+	gunzip();
+	puts("Done. Now booting the kernel.\n");
+}
diff -urN linux-2.4.2-pre1/arch/cris/config.in linux/arch/cris/config.in
--- linux-2.4.2-pre1/arch/cris/config.in	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/config.in	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,223 @@
+#
+# For a description of the syntax of this configuration file,
+# see the Configure script.
+#
+mainmenu_name "Linux/CRIS Kernel Configuration"
+
+define_bool CONFIG_UID16 y
+
+mainmenu_option next_comment
+comment 'Code maturity level options'
+bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+endmenu
+
+mainmenu_option next_comment
+comment 'General setup'
+
+bool 'Networking support' CONFIG_NET y
+bool 'System V IPC' CONFIG_SYSVIPC y
+
+tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF y
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  tristate 'Kernel support for JAVA binaries' CONFIG_BINFMT_JAVA
+fi
+
+bool 'Use kernel gdb debugger' CONFIG_KGDB n
+
+bool 'Enable Etrax100 watchdog' CONFIG_ETRAX_WATCHDOG y
+
+bool 'Use serial console (on the debug port)' CONFIG_USE_SERIAL_CONSOLE y
+
+bool 'Use in-kernel ifconfig/route setup' CONFIG_KERNEL_IFCONFIG n
+
+endmenu
+
+mainmenu_option next_comment
+comment 'Hardware setup'
+
+choice 'Processor type' \
+	"Etrax-100-LX	CONFIG_ETRAX100LX	\
+	 Etrax-100-LX-for-xsim-simulator   CONFIG_SVINTO_SIM" Etrax-100-LX
+
+# For both LX version 1 and the current simulator we enable the low VM mapping
+# Later when LX version 2 and above exist, this should be done with an if
+
+define_bool CONFIG_CRIS_LOW_MAP y
+
+hex 'DRAM base (hex)' ETRAX_DRAM_BASE 40000000
+int 'DRAM size (dec, in MB)' ETRAX_DRAM_SIZE 8
+
+int 'Max possible flash size (dec, in MB)' CONFIG_ETRAX_FLASH_LENGTH 2
+int 'Buswidth of flash in bytes' CONFIG_ETRAX_FLASH_BUSWIDTH 2
+
+choice 'Product LED port' \
+	"Port-PA-LEDs	CONFIG_ETRAX_PA_LEDS	\
+	 Port-PB-LEDs	CONFIG_ETRAX_PB_LEDS	\
+	 Mem-0x90000000-LEDs	CONFIG_ETRAX_90000000_LEDS  \
+	 None	CONFIG_ETRAX_NO_LEDS" Port-PA-LEDs
+
+if [ "$CONFIG_ETRAX_NO_LEDS" != "y" ]; then
+  int '  First green LED bit' CONFIG_ETRAX_LED1G 2
+  int '  First red LED bit' CONFIG_ETRAX_LED1R 3
+  int '  Second green LED bit' CONFIG_ETRAX_LED2G 4
+  int '  Second red LED bit' CONFIG_ETRAX_LED2R 5
+  int '  Third green LED bit' CONFIG_ETRAX_LED3R 2
+  int '  Third red LED bit' CONFIG_ETRAX_LED3G 2
+fi
+
+choice 'Product debug-port' \
+	"Serial-0	CONFIG_DEBUG_PORT0	\
+	 Serial-1	CONFIG_DEBUG_PORT1	\
+	 Serial-2	CONFIG_DEBUG_PORT2	\
+	 Serial-3	CONFIG_DEBUG_PORT3" Serial-0
+
+hex 'R_WAITSTATES' DEF_R_WAITSTATES 95a6
+hex 'R_BUS_CONFIG' DEF_R_BUS_CONFIG 104
+hex 'R_DRAM_CONFIG' DEF_R_DRAM_CONFIG 1a200040
+hex 'R_DRAM_TIMING' DEF_R_DRAM_TIMING 5611
+hex 'R_PORT_PA_DIR' DEF_R_PORT_PA_DIR 1c
+hex 'R_PORT_PA_DATA' DEF_R_PORT_PA_DATA 00
+hex 'R_PORT_PB_CONFIG' DEF_R_PORT_PB_CONFIG 00
+hex 'R_PORT_PB_DIR' DEF_R_PORT_PB_DIR 00
+hex 'R_PORT_PB_DATA' DEF_R_PORT_PB_DATA ff
+
+endmenu
+
+# only configure IP numbers if the kernel ifconfig/route setup is enabled
+
+if [ "$CONFIG_KERNEL_IFCONFIG" = "y" ]; then
+  mainmenu_option next_comment	
+  comment 'IP address selection'
+
+  comment 'All addresses are in hexadecimal form without 0x prefix'
+
+  hex 'IP address' ELTEST_IPADR ab1005af
+  hex 'Network' ELTEST_NETWORK ab100000
+  hex 'Netmask' ELTEST_NETMASK ffff0000
+  hex 'Broadcast' ELTEST_BROADCAST ab10ffff
+  hex 'Gateway' ELTEST_GATEWAY ab100101
+  hwaddr 'Ethernet address' ELTEST_ETHADR 00408ccd0000
+
+  endmenu
+fi
+
+# bring in Etrax built-in drivers
+
+source arch/cris/drivers/Config.in
+
+# standard linux drivers
+
+source drivers/mtd/Config.in
+
+source drivers/parport/Config.in
+
+source drivers/pnp/Config.in
+
+source drivers/block/Config.in
+
+source drivers/md/Config.in
+
+if [ "$CONFIG_NET" = "y" ]; then
+  source net/Config.in
+fi
+
+source drivers/telephony/Config.in
+
+mainmenu_option next_comment
+comment 'ATA/IDE/MFM/RLL support'
+
+tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
+
+if [ "$CONFIG_IDE" != "n" ]; then
+  source drivers/ide/Config.in
+else
+  define_bool CONFIG_BLK_DEV_IDE_MODES n
+  define_bool CONFIG_BLK_DEV_HD n
+fi
+endmenu
+
+mainmenu_option next_comment
+comment 'SCSI support'
+
+tristate 'SCSI support' CONFIG_SCSI
+
+if [ "$CONFIG_SCSI" != "n" ]; then
+  source drivers/scsi/Config.in
+fi
+endmenu
+
+source drivers/ieee1394/Config.in
+
+source drivers/i2o/Config.in
+
+if [ "$CONFIG_NET" = "y" ]; then
+  mainmenu_option next_comment
+  comment 'Network device support'
+
+  bool 'Network device support' CONFIG_NETDEVICES
+  if [ "$CONFIG_NETDEVICES" = "y" ]; then
+    source drivers/net/Config.in
+      if [ "$CONFIG_ATM" = "y" ]; then
+         source drivers/atm/Config.in
+      fi
+  fi
+  endmenu
+fi
+
+source net/ax25/Config.in
+
+source net/irda/Config.in
+
+mainmenu_option next_comment
+comment 'ISDN subsystem'
+if [ "$CONFIG_NET" != "n" ]; then
+   tristate 'ISDN support' CONFIG_ISDN
+   if [ "$CONFIG_ISDN" != "n" ]; then
+      source drivers/isdn/Config.in
+   fi
+fi
+endmenu
+
+mainmenu_option next_comment
+comment 'Old CD-ROM drivers (not SCSI, not IDE)'
+
+bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
+if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
+   source drivers/cdrom/Config.in
+fi
+endmenu
+
+#
+# input before char - char/joystick depends on it. As does USB.
+#
+source drivers/input/Config.in
+source drivers/char/Config.in
+
+#source drivers/misc/Config.in
+
+source drivers/media/Config.in
+
+source fs/Config.in
+
+source drivers/char/Config.in
+
+mainmenu_option next_comment
+comment 'Sound'
+
+tristate 'Sound card support' CONFIG_SOUND
+if [ "$CONFIG_SOUND" != "n" ]; then
+  source drivers/sound/Config.in
+fi
+endmenu
+
+source drivers/usb/Config.in
+
+mainmenu_option next_comment
+comment 'Kernel hacking'
+
+#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
+bool 'Kernel profiling support' CONFIG_PROFILE
+if [ "$CONFIG_PROFILE" = "y" ]; then
+  int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
+fi
+endmenu
diff -urN linux-2.4.2-pre1/arch/cris/cris.ld linux/arch/cris/cris.ld
--- linux-2.4.2-pre1/arch/cris/cris.ld	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/cris.ld	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,81 @@
+/* ld script to make the Linux/CRIS kernel
+ * Authors: Bjorn Wesen (bjornw@axis.com)
+ *
+ * For now, on Etrax-100 LX, the DRAM starts virtually at 0x6. Normally
+ * it should be at 0xc.
+ */	
+
+SECTIONS
+{
+	. = 0x60000000;               /* DRAM starts virtually at 0x60000000 */
+	_dram_start = .;
+	_ibr_start = .;
+	. = . + 0x4000; /* see head.S and pages reserved at the start */
+
+	_text = .;                    /* Text and read-only data */
+	_text_start = .;              /* lots of aliases */
+	_stext = .;
+	__stext = .;
+	.text : {
+		*(.text)
+		*(.fixup)
+		*(.text.__*)
+		*(.rodata)
+	}
+
+	. = ALIGN(4);                /* Exception table */
+  	__start___ex_table = .;
+  	__ex_table : { *(__ex_table) }
+  	__stop___ex_table = .;
+
+	_etext = . ;                  /* End of text section */ 
+	__etext = .;
+
+	. = ALIGN (4);
+	___data_rom_start = . ;
+	___data_start = . ;
+	__Sdata = . ;
+	.data : {                     /* Data */
+		*(.data)
+	}
+	__edata = . ;                 /* End of data section */
+	_edata = . ;
+
+	. = ALIGN(8192);              /* init_task and stack, must be aligned */
+  	.data.init_task : { *(.data.init_task) }
+
+  	. = ALIGN(8192);              /* Init code and data */
+  	___init_begin = .;
+  	.text.init : { *(.text.init) }
+  	.data.init : { *(.data.init) }
+  	. = ALIGN(16);
+  	___setup_start = .;
+  	.setup.init : { *(.setup.init) }
+  	___setup_end = .;
+  	___initcall_start = .;
+  	.initcall.init : { *(.initcall.init) }
+  	___initcall_end = .;
+	__vmlinux_end = .;            /* last adress of the physical file */
+  	. = ALIGN(8192);
+  	___init_end = .;
+
+	__data_end = . ;              /* Move to _edata ? */
+	__bss_start = .;              /* BSS */
+	.bss : {
+		*(COMMON)
+		*(.bss)
+	}
+
+	. =  ALIGN (0x20);
+	_end = .;
+	__end = .;
+
+	/* Sections to be discarded */
+  	/DISCARD/ : {
+        	*(.text.exit)
+        	*(.data.exit)
+		*(.exitcall.exit)
+        }
+
+	_dram_end = 0x60000000 + @ETRAX_DRAM_SIZE_M@*1024*1024;
+}
diff -urN linux-2.4.2-pre1/arch/cris/defconfig linux/arch/cris/defconfig
--- linux-2.4.2-pre1/arch/cris/defconfig	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/defconfig	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,319 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_UID16=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# General setup
+#
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_JAVA is not set
+# CONFIG_KGDB is not set
+# CONFIG_ETRAX_WATCHDOG is not set
+CONFIG_USE_SERIAL_CONSOLE=y
+# CONFIG_KERNEL_IFCONFIG is not set
+
+#
+# Hardware setup
+#
+CONFIG_ETRAX100LX=y
+# CONFIG_SVINTO_SIM is not set
+CONFIG_CRIS_LOW_MAP=y
+ETRAX_DRAM_BASE=40000000
+ETRAX_DRAM_SIZE=8
+CONFIG_ETRAX_PA_LEDS=y
+# CONFIG_ETRAX_PB_LEDS is not set
+# CONFIG_ETRAX_90000000_LEDS is not set
+# CONFIG_ETRAX_NO_LEDS is not set
+CONFIG_ETRAX_LED1G=2
+CONFIG_ETRAX_LED1R=2
+CONFIG_ETRAX_LED2G=2
+CONFIG_ETRAX_LED2R=2
+CONFIG_DEBUG_PORT0=y
+# CONFIG_DEBUG_PORT1 is not set
+# CONFIG_DEBUG_PORT2 is not set
+# CONFIG_DEBUG_PORT3 is not set
+DEF_R_WAITSTATES=95a6
+DEF_R_BUS_CONFIG=104
+DEF_R_DRAM_CONFIG=1a200040
+DEF_R_DRAM_TIMING=5611
+DEF_R_PORT_PA_DIR=1d
+DEF_R_PORT_PA_DATA=f0
+DEF_R_PORT_PB_CONFIG=00
+DEF_R_PORT_PB_DIR=1e
+DEF_R_PORT_PB_DATA=f3
+
+#
+# Drivers for Etrax built-in interfaces
+#
+CONFIG_ETRAX_ETHERNET=y
+CONFIG_NET_ETHERNET=y
+CONFIG_ETRAX_SERIAL=y
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_CRAMFS=y
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_EXT2_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_SYSV_FS_WRITE is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_NFS_FS is not set
+# CONFIG_NFS_V3 is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_SUNRPC is not set
+# CONFIG_LOCKD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_MOUNT_SUBDIR is not set
+# CONFIG_NCPFS_NDS_DOMAINS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_PRINTER is not set
+# CONFIG_PPDEV is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PROFILE is not set
diff -urN linux-2.4.2-pre1/arch/cris/drivers/Config.in linux/arch/cris/drivers/Config.in
--- linux-2.4.2-pre1/arch/cris/drivers/Config.in	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/Config.in	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,49 @@
+mainmenu_option next_comment
+comment 'Drivers for Etrax built-in interfaces'
+
+bool 'Ethernet support' CONFIG_ETRAX_ETHERNET y
+if [ "$CONFIG_ETRAX_ETHERNET" = "y" ]; then
+# this is just so that the user does not have to go into the
+# normal ethernet driver section just to enable ethernetworking
+  define_bool CONFIG_NET_ETHERNET y
+fi
+
+bool 'Serial-port support' CONFIG_ETRAX_SERIAL y
+
+bool 'ATA/IDE support' CONFIG_ETRAX_IDE n
+
+if [ "$CONFIG_ETRAX_IDE" = "y" ]; then
+# here we should add the CONFIG_'s necessary to enable the basic
+# general ide drivers so the common case does not need to go
+# into that config submenu. enable disk and CD support. others
+# need to go fiddle in the submenu..
+	define_bool CONFIG_IDE y
+
+	define_bool CONFIG_BLK_DEV_IDE y
+	define_bool CONFIG_BLK_DEV_IDEDISK y
+	define_bool CONFIG_BLK_DEV_IDECD y
+
+	define_bool CONFIG_BLK_DEV_IDEDMA y
+	define_bool CONFIG_DMA_NONPCI y
+ 
+	choice 'IDE reset pin' \
+  	"Port_PB_Bit_7  CONFIG_ETRAX_IDE_PB7_RESET\
+   	 Port_G_Bit_27  CONFIG_ETRAX_IDE_G27_RESET\
+   	 Port_CSE1_Bit_16  CONFIG_ETRAX_IDE_CSE1_16_RESET" Port_PB_Bit_7 
+fi
+
+bool 'Axis flash-map support' CONFIG_ETRAX_AXISFLASHMAP n
+
+if [ "$CONFIG_ETRAX_AXISFLASHMAP" = "y" ]; then
+# here we define the CONFIG_'s necessary to enable MTD support
+# for the flash
+	define_bool CONFIG_MTD y
+
+	define_bool CONFIG_MTD_CFI y
+	define_bool CONFIG_MTD_CFI_INTELEXT n
+	define_bool CONFIG_MTD_CFI_AMDSTD y
+
+	define_bool CONFIG_MTD_CHAR y
+fi
+
+endmenu
diff -urN linux-2.4.2-pre1/arch/cris/drivers/Makefile linux/arch/cris/drivers/Makefile
--- linux-2.4.2-pre1/arch/cris/drivers/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/Makefile	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,14 @@
+#
+# Makefile for Etrax-specific drivers
+#
+
+O_TARGET := drivers.o
+
+obj-y :=
+
+obj-$(CONFIG_ETRAX_ETHERNET)     += ethernet.o
+obj-$(CONFIG_ETRAX_SERIAL)       += serial.o
+obj-$(CONFIG_ETRAX_IDE)          += ide.o
+obj-$(CONFIG_ETRAX_AXISFLASHMAP) += axisflashmap.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.2-pre1/arch/cris/drivers/axisflashmap.c linux/arch/cris/drivers/axisflashmap.c
--- linux-2.4.2-pre1/arch/cris/drivers/axisflashmap.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/axisflashmap.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,311 @@
+/*
+ * Physical mapping layer for MTD using the Axis partitiontable format
+ *
+ * Copyright (c) 2001 Axis Communications AB
+ *
+ * This file is under the GPL.
+ *
+ * First partition is always sector 0 regardless of if we find a partitiontable
+ * or not. In the start of the next sector, there can be a partitiontable that
+ * tells us what other partitions to define. If there isn't, we use a default
+ * partition split defined below.
+ *
+ * $Log: axisflashmap.c,v $
+ * Revision 1.1  2001/01/12 17:01:18  bjornw
+ * * Added axisflashmap.c, a physical mapping for MTD that reads and understands
+ *   Axis partition-table format.
+ *
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/config.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/axisflashmap.h>
+#include <asm/mmu.h>
+
+#ifdef CONFIG_CRIS_LOW_MAP
+#define FLASH_UNCACHED_ADDR  KSEG_E
+#define FLASH_CACHED_ADDR    KSEG_5
+#else
+#define FLASH_UNCACHED_ADDR  KSEG_E
+#define FLASH_CACHED_ADDR    KSEG_F
+#endif
+
+/*
+ * WINDOW_SIZE is the total size where the flash chips are mapped,
+ * my guess is that this can be the total memory area even if there
+ * are many flash chips inside the area or if they are not all mounted.
+ * So possibly we can get rid of the CONFIG_ here and just write something
+ * like 32 MB always.
+ */
+
+#define WINDOW_SIZE  (CONFIG_ETRAX_FLASH_LENGTH * 1024 * 1024)
+
+/* Byte-offset where the partition-table is placed in the first chip
+ */
+
+#define PTABLE_SECTOR 65536
+
+/* 
+ * Map driver
+ *
+ * Ok this is the scoop - we need to access the flash both with and without
+ * the cache - without when doing all the fancy flash interfacing, and with
+ * when we do actual copying because otherwise it will be slow like molasses.
+ * I hope this works the way it's intended, so that there won't be any cases
+ * of non-synchronicity because of the different access modes below...
+ */
+
+static __u8 flash_read8(struct map_info *map, unsigned long ofs)
+{
+	return *(__u8 *)(FLASH_UNCACHED_ADDR + ofs);
+}
+
+static __u16 flash_read16(struct map_info *map, unsigned long ofs)
+{
+	return *(__u16 *)(FLASH_UNCACHED_ADDR + ofs);
+}
+
+static __u32 flash_read32(struct map_info *map, unsigned long ofs)
+{
+	return *(volatile unsigned int *)(FLASH_UNCACHED_ADDR + ofs);
+}
+
+static void flash_copy_from(struct map_info *map, void *to,
+			    unsigned long from, ssize_t len)
+{
+	memcpy(to, (void *)(FLASH_CACHED_ADDR + from), len);
+}
+
+static void flash_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	*(__u8 *)(FLASH_UNCACHED_ADDR + adr) = d;
+}
+
+static void flash_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	*(__u16 *)(FLASH_UNCACHED_ADDR + adr) = d;
+}
+
+static void flash_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	*(__u32 *)(FLASH_UNCACHED_ADDR + adr) = d;
+}
+
+static void flash_copy_to(struct map_info *map, unsigned long to,
+			  const void *from, ssize_t len)
+{
+	memcpy((void *)(FLASH_CACHED_ADDR + to), from, len);
+}
+
+static struct map_info axis_map = {
+	name: "Axis flash",
+	size: WINDOW_SIZE,
+	buswidth: CONFIG_ETRAX_FLASH_BUSWIDTH,
+	read8: flash_read8,
+	read16: flash_read16,
+	read32: flash_read32,
+	copy_from: flash_copy_from,
+	write8: flash_write8,
+	write16: flash_write16,
+	write32: flash_write32,
+	copy_to: flash_copy_to
+};
+
+/* If no partition-table was found, we use this default-set.
+ */
+
+#define MAX_PARTITIONS         7  
+#define NUM_DEFAULT_PARTITIONS 3
+
+static struct mtd_partition axis_default_partitions[NUM_DEFAULT_PARTITIONS] = {
+	{
+		name: "boot firmware",
+		size: PTABLE_SECTOR,
+		offset: 0
+	},
+	{
+		name: "kernel",
+		size: 0x1a0000,
+		offset: PTABLE_SECTOR
+	},
+	{
+		name: "filesystem",
+		size: 0x50000,
+		offset: (0x1a0000 + PTABLE_SECTOR)
+	}
+};
+
+static struct mtd_partition axis_partitions[MAX_PARTITIONS] = {
+	{
+		name: "part0",
+		size: 0,
+		offset: 0
+	},
+	{
+		name: "part1",
+		size: 0,
+		offset: 0
+	},
+	{
+		name: "part2",
+		size: 0,
+		offset: 0
+	},
+	{
+		name: "part3",
+		size: 0,
+		offset: 0
+	},
+	{
+		name: "part4",
+		size: 0,
+		offset: 0
+	},
+	{
+		name: "part5",
+		size: 0,
+		offset: 0
+	},
+	{
+		name: "part6",
+		size: 0,
+		offset: 0
+	},
+};
+
+/* 
+ * This is the master MTD device for which all the others are just
+ * auto-relocating aliases.
+ */
+static struct mtd_info *mymtd;
+
+/* CFI-scan the flash, and if there was a chip, read the partition-table
+ * and register the partitions with MTD.
+ */
+
+static int __init
+init_axis_flash(void)
+{
+	int pidx = 0;
+	struct partitiontable_head *ptable_head;
+	struct partitiontable_entry *ptable;
+	int use_default_ptable = 1; /* Until proven otherwise */
+	const char *pmsg = "  /dev/flash%d at 0x%x, size 0x%x\n";
+
+	printk(KERN_NOTICE "Axis flash mapping: %x at %x\n",
+	       WINDOW_SIZE, FLASH_CACHED_ADDR);
+
+	mymtd = do_cfi_probe(&axis_map);
+
+	if(!mymtd) {
+		printk("cfi_probe erred %d\n", mymtd);
+		return -ENXIO;
+	}
+
+	mymtd->module = THIS_MODULE;
+
+	/* The partition-table is at an offset within the second 
+	 * sector of the flash. We _define_ this to be at offset 64k
+	 * even if the actual sector-size in the flash changes.. for
+	 * now at least.
+	 */
+
+	ptable_head = FLASH_CACHED_ADDR + PTABLE_SECTOR + PARTITION_TABLE_OFFSET;
+	pidx++;  /* first partition is always set to the default */
+
+	if ((ptable_head->magic == PARTITION_TABLE_MAGIC)
+	    && (ptable_head->size
+		< (MAX_PARTITIONS
+		   * sizeof(struct partitiontable_entry) + 4))
+	    && (*(unsigned long*)
+		((void*)ptable_head
+		 + sizeof(*ptable_head)
+		 + ptable_head->size - 4)
+		==  PARTITIONTABLE_END_MARKER)) {
+		/* Looks like a start, sane length and end of a
+		 * partition table, lets check csum etc.
+		 */
+		int ptable_ok = 0;
+		struct partitiontable_entry *max_addr =
+			(struct partitiontable_entry *)
+			((unsigned long)ptable_head + sizeof(*ptable_head) +
+			 ptable_head->size);
+		unsigned long offset = PTABLE_SECTOR;
+		unsigned char *p;
+		unsigned long csum = 0;
+		
+		ptable = (struct partitiontable_entry *)
+			((unsigned long)ptable_head + sizeof(*ptable_head));
+
+		/* Lets be PARANOID, and check the checksum. */
+		p = (unsigned char*) ptable;
+
+		while (p <= (unsigned char*)max_addr) {
+			csum += *p++;
+			csum += *p++;
+			csum += *p++;
+			csum += *p++;
+		}
+		/* printk("  total csum: 0x%08X 0x%08X\n",
+		   csum, ptable_head->checksum); */
+		ptable_ok = (csum == ptable_head->checksum);
+
+		/* Read the entries and use/show the info.  */
+		ptable = (struct partitiontable_entry *)
+			((unsigned long)ptable_head + sizeof(*ptable_head));
+		
+		printk(" Found %s partition table at 0x%08lX-0x%08lX.\n",
+		       (ptable_ok ? "valid" : "invalid"),
+		       (unsigned long)ptable_head,
+		       (unsigned long)max_addr);
+
+		/* We have found a working bootblock.  Now read the
+		   partition table.  Scan the table.  It ends when
+		   there is 0xffffffff, that is, empty flash.  */
+		
+		while (ptable_ok
+		       && ptable->offset != 0xffffffff
+		       && ptable < max_addr
+		       && pidx < MAX_PARTITIONS) {
+#if 0
+			/* wait with multi-chip support until we know
+			 * how mtd detects multiple chips
+			 */
+			if ((offset + ptable->offset) >= chips[0].size) {
+				partitions[pidx].start
+					= offset + chips[1].start
+					+ ptable->offset - chips[0].size;
+			}
+#endif
+			axis_partitions[pidx].offset = offset + ptable->offset;
+			axis_partitions[pidx].size = ptable->size;
+
+			printk(pmsg, pidx, axis_partitions[pidx].offset,
+			       axis_partitions[pidx].size);
+			pidx++;
+			ptable++;
+		}
+		use_default_ptable = !ptable_ok;
+	}
+
+	if(use_default_ptable) {
+		printk(" Using default partition table\n");
+		return add_mtd_partitions(mymtd, axis_default_partitions,
+					  NUM_DEFAULT_PARTITIONS);
+	} else {
+		return add_mtd_partitions(mymtd, axis_partitions, pidx);
+	}		
+}
+
+/* This adds the above to the kernels init-call chain */
+
+module_init(init_axis_flash);
+
diff -urN linux-2.4.2-pre1/arch/cris/drivers/ethernet.c linux/arch/cris/drivers/ethernet.c
--- linux-2.4.2-pre1/arch/cris/drivers/ethernet.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/ethernet.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,1041 @@
+/* $Id: ethernet.c,v 1.5 2000/11/29 17:22:22 bjornw Exp $
+ *
+ * e100net.c: A network driver for the ETRAX 100LX network controller.
+ *
+ * Copyright (c) 1998-2000 Axis Communications AB.
+ *
+ * The outline of this driver comes from skeleton.c.
+ *
+ * $Log: ethernet.c,v $
+ * Revision 1.5  2000/11/29 17:22:22  bjornw
+ * Get rid of the udword types legacy stuff
+ *
+ * Revision 1.4  2000/11/22 16:36:09  bjornw
+ * Please marketing by using the correct case when spelling Etrax.
+ *
+ * Revision 1.3  2000/11/21 16:43:04  bjornw
+ * Minor short->int change
+ *
+ * Revision 1.2  2000/11/08 14:27:57  bjornw
+ * 2.4 port
+ *
+ * Revision 1.1  2000/11/06 13:56:00  bjornw
+ * Verbatim copy of the 1.24 version of e100net.c from elinux
+ *
+ * Revision 1.24  2000/10/04 15:55:23  bjornw
+ * * Use virt_to_phys etc. for DMA addresses
+ * * Removed bogus CHECKSUM_UNNECESSARY
+ *
+ *
+ */
+
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/malloc.h>
+#include <linux/string.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <linux/spinlock.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include <asm/svinto.h>
+
+//#define ETHDEBUG
+
+#define D(x)
+
+/*
+ * The name of the card. Is used for messages and in the requests for
+ * io regions, irqs and dma channels
+ */
+
+static const char* cardname = "ETRAX 100LX built-in ethernet controller";
+
+/* A default ethernet address. Highlevel SW will set the real one later */
+
+static struct sockaddr default_mac = {
+	0,
+        { 0x00, 0x40, 0x8C, 0xCD, 0x00, 0x00 }
+};
+
+/* Information that need to be kept for each board. */
+struct net_local {
+	struct net_device_stats stats;
+
+	/* Tx control lock.  This protects the transmit buffer ring
+	 * state along with the "tx full" state of the driver.  This
+	 * means all netif_queue flow control actions are protected
+	 * by this lock as well.
+	 */
+	spinlock_t lock;
+};
+
+#define NETWORK_DMARX_IRQ 17  /* irq 17 is the DMA1 irq */
+#define NETWORK_DMATX_IRQ 16  /* irq 16 is the DMA0 irq */
+#define NETWORK_STATUS_IRQ 6  /* irq 6 is the network irq */
+
+/* Dma descriptors etc. */
+
+#define RX_BUF_SIZE 32768
+
+#define MAX_MEDIA_DATA_SIZE 1518
+
+#define MIN_PACKET_LEN      46
+#define ETHER_HEAD_LEN      14
+
+/* 
+** MDIO constants.
+*/
+#define MDIO_BASE_STATUS_REG   0x1
+#define MDIO_BASE_CONTROL_REG  0x0
+#define MDIO_LINK_UP_MASK      0x4
+#define MDIO_START                          0x1
+#define MDIO_READ                           0x2
+#define MDIO_WRITE                          0x1
+#define MDIO_PREAMBLE              0xfffffffful
+
+/* Broadcom specific */
+#define MDIO_AUX_CTRL_STATUS_REG           0x18
+#define MDIO_SPEED                          0x2
+#define MDIO_PHYS_ADDR                      0x0
+
+/* Network flash constants */
+#define NET_FLASH_TIME                        2 /* 20 ms */
+#define NET_LINK_UP_CHECK_INTERVAL          200 /* 2 s   */
+
+/* RX_DESC_BUF_SIZE should be a multiple of four to avoid the buffer
+ * alignment bug in Etrax 100 release 1
+ */
+
+#define RX_DESC_BUF_SIZE   256
+#define NBR_OF_RX_DESC     (RX_BUF_SIZE / \
+			    RX_DESC_BUF_SIZE)
+
+#define GET_BIT(bit,val)   (((val) >> (bit)) & 0x01)
+
+static etrax_dma_descr *myNextRxDesc;  /* Points to the next descriptor to
+					  to be processed */
+static etrax_dma_descr *myLastRxDesc;  /* The last processed descriptor */
+static etrax_dma_descr *myPrevRxDesc;  /* The descriptor right before myNextRxDesc */
+
+static unsigned char RxBuf[RX_BUF_SIZE];
+
+static etrax_dma_descr RxDescList[NBR_OF_RX_DESC];
+static etrax_dma_descr TxDesc;
+
+static struct sk_buff *tx_skb;
+
+/* Network speed indication. */
+static struct timer_list speed_timer;
+static struct timer_list clear_led_timer;
+static int current_speed;
+static int led_clear_time;
+static int nolink;
+
+/* Index to functions, as function prototypes. */
+
+static int etrax_ethernet_init(struct net_device *dev);
+
+static int e100_open(struct net_device *dev);
+static int e100_set_mac_address(struct net_device *dev, void *addr);
+static int e100_send_packet(struct sk_buff *skb, struct net_device *dev);
+static void e100rx_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static void e100tx_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static void e100nw_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static void e100_rx(struct net_device *dev);
+static int e100_close(struct net_device *dev);
+static struct net_device_stats *e100_get_stats(struct net_device *dev);
+static void set_multicast_list(struct net_device *dev);
+static void e100_hardware_send_packet(char *buf, int length);
+static void update_rx_stats(struct net_device_stats *);
+static void update_tx_stats(struct net_device_stats *);
+
+static void e100_check_speed(unsigned long dummy);
+static unsigned short e100_get_mdio_reg(unsigned char reg_num);
+static void e100_send_mdio_cmd(unsigned short cmd, int write_cmd);
+static void e100_send_mdio_bit(unsigned char bit);
+static unsigned char e100_receive_mdio_bit(void);
+static void e100_reset_tranceiver(void);
+
+static void e100_clear_network_leds(unsigned long dummy);
+
+#define tx_done(dev) (*R_DMA_CH0_CMD == 0)
+
+/*
+ * Check for a network adaptor of this type, and return '0' if one exists.
+ * If dev->base_addr == 0, probe all likely locations.
+ * If dev->base_addr == 1, always return failure.
+ * If dev->base_addr == 2, allocate space for the device and return success
+ * (detachable devices only).
+ */
+
+static int __init
+etrax_ethernet_init(struct net_device *dev)
+{
+	int i;
+	int anOffset = 0;
+
+	printk("ETRAX 100LX 10/100MBit ethernet v2.0 (c) 2000 Axis Communications AB\n");
+
+	dev->base_addr = (unsigned int)R_NETWORK_SA_0; /* just to have something to show */
+
+	printk("%s initialized\n", dev->name);
+
+	/* make Linux aware of the new hardware  */
+
+	if (!dev) {
+		printk("dev == NULL. Should this happen?\n");
+		dev = init_etherdev(dev, sizeof(struct net_local));
+	}
+
+	/* setup generic handlers and stuff in the dev struct */
+
+	ether_setup(dev);
+
+	/* make room for the local structure containing stats etc */
+
+	dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+	if (dev->priv == NULL)
+		return -ENOMEM;
+	memset(dev->priv, 0, sizeof(struct net_local));
+
+	/* now setup our etrax specific stuff */
+
+	dev->irq = NETWORK_DMARX_IRQ; /* we really use DMATX as well... */
+	dev->dma = 1;
+
+	/* fill in our handlers so the network layer can talk to us in the future */
+
+	dev->open               = e100_open;
+	dev->hard_start_xmit    = e100_send_packet;
+	dev->stop               = e100_close;
+	dev->get_stats          = e100_get_stats;
+	dev->set_multicast_list = set_multicast_list;
+	dev->set_mac_address    = e100_set_mac_address;
+
+	/* set the default MAC address */
+
+	e100_set_mac_address(dev, &default_mac);
+
+	/* Initialise the list of Etrax DMA-descriptors */
+
+	/* Initialise receive descriptors */
+
+	for(i = 0; i < (NBR_OF_RX_DESC - 1); i++) {
+		RxDescList[i].ctrl   = 0;
+		RxDescList[i].sw_len = RX_DESC_BUF_SIZE;
+		RxDescList[i].next   = virt_to_phys(&RxDescList[i + 1]);
+		RxDescList[i].buf    = virt_to_phys(RxBuf + anOffset);
+		RxDescList[i].status = 0;
+		RxDescList[i].hw_len = 0;
+		anOffset += RX_DESC_BUF_SIZE;
+	}
+
+	RxDescList[i].ctrl   = d_eol;
+	RxDescList[i].sw_len = RX_DESC_BUF_SIZE;
+	RxDescList[i].next   = virt_to_phys(&RxDescList[0]);
+	RxDescList[i].buf    = virt_to_phys(RxBuf + anOffset);
+	RxDescList[i].status = 0;
+	RxDescList[i].hw_len = 0;
+
+	/* Initialise initial pointers */
+
+	myNextRxDesc = &RxDescList[0];
+	myLastRxDesc = &RxDescList[NBR_OF_RX_DESC - 1];
+	myPrevRxDesc = &RxDescList[NBR_OF_RX_DESC - 1];
+
+	/* Initialize speed indicator stuff. */
+
+	nolink = 0;
+	current_speed = 10;
+	speed_timer.expires = jiffies + NET_LINK_UP_CHECK_INTERVAL;
+	speed_timer.function = e100_check_speed;
+	add_timer(&speed_timer);
+	clear_led_timer.function = e100_clear_network_leds;
+	clear_led_timer.expires = jiffies + 10;
+	add_timer(&clear_led_timer);
+
+	return 0;
+}
+
+/* set MAC adress of the interface. called from the core after a
+ * SIOCSIFADDR ioctl, and from the bootup above.
+ */
+
+static int
+e100_set_mac_address(struct net_device *dev, void *p)
+{
+	struct sockaddr *addr = p;
+	int i;
+
+	/* remember it */
+
+        memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+	/* Write it to the hardware.
+	 * Note the way the adress is wrapped:
+	 * *R_NETWORK_SA_0 = a0_0 | (a0_1 << 8) | (a0_2 << 16) | (a0_3 << 24);
+	 * *R_NETWORK_SA_1 = a0_4 | (a0_5 << 8);
+	 */
+	
+	*R_NETWORK_SA_0 = dev->dev_addr[0] | (dev->dev_addr[1] << 8) |
+		(dev->dev_addr[2] << 16) | (dev->dev_addr[3] << 24);
+	*R_NETWORK_SA_1 = dev->dev_addr[4] | (dev->dev_addr[5] << 8);
+	*R_NETWORK_SA_2 = 0;
+
+	/* show it in the log as well */
+
+	printk("%s: changed MAC to ", dev->name);
+
+	for (i = 0; i < 5; i++)
+		printk("%02X:", dev->dev_addr[i]);
+
+	printk("%02X\n", dev->dev_addr[i]);
+
+	return 0;
+}
+
+/*
+ * Open/initialize the board. This is called (in the current kernel)
+ * sometime after booting when the 'ifconfig' program is run.
+ *
+ * This routine should set everything up anew at each open, even
+ * registers that "should" only need to be set once at boot, so that
+ * there is non-reboot way to recover if something goes wrong.
+ */
+
+static int
+e100_open(struct net_device *dev)
+{
+	unsigned long flags;
+
+	/* disable the ethernet interface while we configure it */
+
+	*R_NETWORK_GEN_CONFIG =
+		IO_STATE(R_NETWORK_GEN_CONFIG, phy,    mii_clk) |
+		IO_STATE(R_NETWORK_GEN_CONFIG, enable, off);
+
+	/* enable the MDIO output pin */
+
+	*R_NETWORK_MGM_CTRL = IO_STATE(R_NETWORK_MGM_CTRL, mdoe, enable);
+
+	*R_IRQ_MASK0_CLR = 0xe0000; /* clear excessive_col, over/underrun irq mask */
+	*R_IRQ_MASK2_CLR = 0xf; /* clear dma0 and 1 eop and descr irq masks */
+
+	/* Reset and wait for the DMA channels */
+
+	RESET_DMA(0);
+	RESET_DMA(1);
+	WAIT_DMA(0);
+	WAIT_DMA(1);
+
+	/* Initialise the etrax network controller */
+
+	/* allocate the irq corresponding to the receiving DMA */
+
+	if (request_irq(NETWORK_DMARX_IRQ, e100rx_interrupt, 0,
+			cardname, (void *)dev)) {
+		goto grace_exit;
+	}
+
+	/* allocate the irq corresponding to the transmitting DMA */
+
+	if (request_irq(NETWORK_DMATX_IRQ, e100tx_interrupt, 0,
+			cardname, (void *)dev)) {
+		goto grace_exit;
+	}
+
+	/* allocate the irq corresponding to the network errors etc */
+
+	if (request_irq(NETWORK_STATUS_IRQ, e100nw_interrupt, 0,
+			cardname, (void *)dev)) {
+		goto grace_exit;
+	}
+
+	/*
+	 * Always allocate the DMA channels after the IRQ,
+	 * and clean up on failure.
+	 */
+
+	if(request_dma(0, cardname)) {
+		goto grace_exit;
+	}
+
+	if(request_dma(1, cardname)) {
+	grace_exit:
+		/* this will cause some 'trying to free free irq' but what the heck... */
+		free_dma(0);
+		free_irq(NETWORK_DMARX_IRQ, NULL);
+		free_irq(NETWORK_DMATX_IRQ, NULL);
+		free_irq(NETWORK_STATUS_IRQ, NULL);
+		return -EAGAIN;
+	}
+
+	/* give the HW an idea of what MAC address we want */
+
+	*R_NETWORK_SA_0 = dev->dev_addr[0] | (dev->dev_addr[1] << 8) |
+		(dev->dev_addr[2] << 16) | (dev->dev_addr[3] << 24);
+	*R_NETWORK_SA_1 = dev->dev_addr[4] | (dev->dev_addr[5] << 8);
+	*R_NETWORK_SA_2 = 0;
+
+#if 0
+	/* use promiscuous mode for testing */
+	*R_NETWORK_GA_0 = 0xffffffff;
+	*R_NETWORK_GA_1 = 0xffffffff;
+
+	*R_NETWORK_REC_CONFIG = 0xd; /* broadcast rec, individ. rec, ma0 enabled */
+#else
+	*R_NETWORK_REC_CONFIG =
+		IO_STATE(R_NETWORK_REC_CONFIG, broadcast, receive) |
+		IO_STATE(R_NETWORK_REC_CONFIG, ma0,       enable);
+#endif
+
+	*R_NETWORK_GEN_CONFIG =
+		IO_STATE(R_NETWORK_GEN_CONFIG, phy,    mii_clk) |
+		IO_STATE(R_NETWORK_GEN_CONFIG, enable, on);
+
+	save_flags(flags);
+	cli();
+
+	/* enable the irq's for ethernet DMA */
+
+	*R_IRQ_MASK2_SET =
+		IO_STATE(R_IRQ_MASK2_SET, dma0_eop, set) |
+		IO_STATE(R_IRQ_MASK2_SET, dma1_eop, set);
+
+	*R_IRQ_MASK0_SET =
+		IO_STATE(R_IRQ_MASK0_SET, overrun,       set) |
+		IO_STATE(R_IRQ_MASK0_SET, underrun,      set) |
+		IO_STATE(R_IRQ_MASK0_SET, excessive_col, set);
+
+	tx_skb = 0;
+
+	/* make sure the irqs are cleared */
+
+	*R_DMA_CH0_CLR_INTR = IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do);
+	*R_DMA_CH1_CLR_INTR = IO_STATE(R_DMA_CH1_CLR_INTR, clr_eop, do);
+
+	/* make sure the rec and transmit error counters are cleared */
+
+	(void)*R_REC_COUNTERS;  /* dummy read */
+	(void)*R_TR_COUNTERS;   /* dummy read */
+
+	/* start the receiving DMA channel so we can receive packets from now on */
+
+	*R_DMA_CH1_FIRST = virt_to_phys(myNextRxDesc);
+	*R_DMA_CH1_CMD = IO_STATE(R_DMA_CH1_CMD, cmd, start);
+
+	restore_flags(flags);
+	
+	/* We are now ready to accept transmit requeusts from
+	 * the queueing layer of the networking.
+	 */
+	netif_start_queue(dev);
+
+	return 0;
+}
+
+
+static void
+e100_check_speed(unsigned long dummy)
+{
+	unsigned long data;
+	data = e100_get_mdio_reg(MDIO_BASE_STATUS_REG);
+	if (!(data & MDIO_LINK_UP_MASK)) {
+		nolink = 1;
+		LED_NETWORK_TX_SET(1); /* Make it red, link is down. */
+	} else {
+		nolink = 0;
+		LED_NETWORK_TX_SET(0); /* Link is up again, clear red LED. */
+		data = e100_get_mdio_reg(MDIO_AUX_CTRL_STATUS_REG);
+		if (data & MDIO_SPEED) {
+			current_speed = 100;
+		} else {
+			current_speed = 10;
+		}
+	}
+	
+	/* Reinitialize the timer. */
+	speed_timer.expires = jiffies + NET_LINK_UP_CHECK_INTERVAL;
+	add_timer(&speed_timer);
+}
+
+static unsigned short
+e100_get_mdio_reg(unsigned char reg_num)
+{
+	unsigned long flags;
+	unsigned short cmd;    /* Data to be sent on MDIO port */
+	unsigned short data;   /* Data read from MDIO */
+	int bitCounter;
+	
+	save_flags(flags);
+	cli();
+	
+	/* Start of frame, OP Code, Physical Address, Register Address */
+	cmd = (MDIO_START << 14) | (MDIO_READ << 12) | (MDIO_PHYS_ADDR << 7) |
+		(reg_num << 2);
+	
+	e100_send_mdio_cmd(cmd, 0);
+	
+	data = 0;
+	
+	/* Data... */
+	for(bitCounter=15; bitCounter>=0 ; bitCounter--) {
+		data |= (e100_receive_mdio_bit() << bitCounter);
+	}
+	
+	restore_flags(flags);
+	return data;
+}
+
+static void
+e100_send_mdio_cmd(unsigned short cmd, int write_cmd)
+{
+	int bitCounter;
+	unsigned char data = 0x2;
+	
+	/* Preamble */
+	for(bitCounter = 31; bitCounter>= 0; bitCounter--)
+		e100_send_mdio_bit(GET_BIT(bitCounter, MDIO_PREAMBLE));
+
+	for(bitCounter = 15; bitCounter >= 2; bitCounter--)
+		e100_send_mdio_bit(GET_BIT(bitCounter, cmd));
+
+	/* Turnaround */
+	for(bitCounter = 1; bitCounter >= 0 ; bitCounter--)
+		if (write_cmd)
+			e100_send_mdio_bit(GET_BIT(bitCounter, data));
+		else
+			e100_receive_mdio_bit();
+}
+
+static void
+e100_send_mdio_bit(unsigned char bit)
+{
+	volatile int i;
+	*R_NETWORK_MGM_CTRL = 2 | bit&1;
+	for (i=40; i; i--);
+	*R_NETWORK_MGM_CTRL = 6 | bit&1;
+	for (i=40; i; i--);
+}
+
+static unsigned char
+e100_receive_mdio_bit()
+{
+	unsigned char bit;
+	volatile int i;
+	*R_NETWORK_MGM_CTRL = 0;
+	bit = *R_NETWORK_STAT & 1;
+	for (i=40; i; i--);
+	*R_NETWORK_MGM_CTRL = 4;
+	for (i=40; i; i--);
+	return bit;
+}
+
+static void 
+e100_reset_tranceiver(void)
+{
+	unsigned long flags;
+	unsigned short cmd;
+	unsigned short data;
+	int bitCounter;
+
+	save_flags(flags);
+	cli();
+
+	data = e100_get_mdio_reg(MDIO_BASE_CONTROL_REG);
+
+	cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (MDIO_PHYS_ADDR << 7) | (MDIO_BASE_CONTROL_REG << 2);
+
+	e100_send_mdio_cmd(cmd, 0);
+	
+	data |= 0x8000;
+	
+	for(bitCounter = 15; bitCounter >= 0 ; bitCounter--) {
+		e100_send_mdio_bit(GET_BIT(bitCounter, data));
+	}
+	
+	restore_flags(flags);
+}
+
+/* Called by upper layers if they decide it took too long to complete
+ * sending a packet - we need to reset and stuff.
+ */
+
+static void
+e100_tx_timeout(struct net_device *dev)
+{
+	struct net_local *np = (struct net_local *)dev->priv;
+
+	printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
+	       tx_done(dev) ? "IRQ problem" : "network cable problem");
+	
+	/* remember we got an error */
+	
+	np->stats.tx_errors++; 
+	
+	/* reset the TX DMA in case it has hung on something */
+	
+	RESET_DMA(0);
+	WAIT_DMA(0);
+	
+	/* Reset the tranceiver. */
+	
+	e100_reset_tranceiver();
+	
+	/* and get rid of the packet that never got an interrupt */
+	
+	dev_kfree_skb(tx_skb);
+	tx_skb = 0;
+	
+	/* tell the upper layers we're ok again */
+	
+	netif_wake_queue(dev);
+}
+
+
+/* This will only be invoked if the driver is _not_ in XOFF state.
+ * What this means is that we need not check it, and that this
+ * invariant will hold if we make sure that the netif_*_queue()
+ * calls are done at the proper times.
+ */
+
+static int
+e100_send_packet(struct sk_buff *skb, struct net_device *dev)
+{
+	struct net_local *np = (struct net_local *)dev->priv;
+	int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
+	unsigned char *buf = skb->data;
+	
+#ifdef ETHDEBUG
+	printk("send packet len %d\n", length);
+#endif
+	spin_lock_irq(&np->lock);  /* protect from tx_interrupt */
+
+	tx_skb = skb; /* remember it so we can free it in the tx irq handler later */
+	dev->trans_start = jiffies;
+	
+	e100_hardware_send_packet(buf, length);
+
+	/* this simple TX driver has only one send-descriptor so we're full
+	 * directly. If this had a send-ring instead, we would only do this if
+	 * the ring got full.
+	 */
+
+	netif_stop_queue(dev);
+
+	spin_unlock_irq(&np->lock);
+
+	return 0;
+}
+
+/*
+ * The typical workload of the driver:
+ *   Handle the network interface interrupts.
+ */
+
+static void
+e100rx_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct net_device *dev = (struct net_device *)dev_id;
+	unsigned long irqbits = *R_IRQ_MASK2_RD;
+
+	if(irqbits & (1U << 3)) {
+
+		/* acknowledge the eop interrupt */
+
+		*R_DMA_CH1_CLR_INTR = IO_STATE(R_DMA_CH1_CLR_INTR, clr_eop, do);
+
+		/* check if one or more complete packets were indeed received */
+
+		while(*R_DMA_CH1_FIRST != virt_to_phys(myNextRxDesc)) {
+			/* Take out the buffer and give it to the OS, then
+			 * allocate a new buffer to put a packet in.
+			 */
+			e100_rx(dev);
+			((struct net_local *)dev->priv)->stats.rx_packets++;
+			*R_DMA_CH1_CMD = 3; /* restart/continue on the channel, for safety */
+			*R_DMA_CH1_CLR_INTR = 3; /* clear dma channel 1 eop/descr irq bits */
+			/* now, we might have gotten another packet so we have to loop back
+			   and check if so */
+		}
+	}
+}
+
+/* the transmit dma channel interrupt
+ *
+ * this is supposed to free the skbuff which was pending during transmission,
+ * and inform the kernel that we can send one more buffer
+ */
+
+static void
+e100tx_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct net_device *dev = (struct net_device *)dev_id;
+	unsigned long irqbits = *R_IRQ_MASK2_RD;
+	struct net_local *np = (struct net_local *)dev->priv;
+
+	if(irqbits & 2) { /* check for a dma0_eop interrupt */
+
+		/* This protects us from concurrent execution of
+		 * our dev->hard_start_xmit function above.
+		 */
+
+		spin_lock(&np->lock);
+		
+		/* acknowledge the eop interrupt */
+
+		*R_DMA_CH0_CLR_INTR = IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do);
+
+		if(*R_DMA_CH0_FIRST == 0 && tx_skb) {
+			np->stats.tx_bytes += tx_skb->len;
+			np->stats.tx_packets++;
+			/* dma is ready with the transmission of the data in tx_skb, so now
+			   we can release the skb memory */
+			dev_kfree_skb_irq(tx_skb);
+			tx_skb = 0;
+			netif_wake_queue(dev);
+		} else {
+			printk("tx weird interrupt\n");
+		}
+
+		spin_unlock(&np->lock);
+	}
+}
+
+static void
+e100nw_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct net_device *dev = (struct net_device *)dev_id;
+	struct net_local *np = (struct net_local *)dev->priv;
+	unsigned long irqbits = *R_IRQ_MASK0_RD;
+
+	if(irqbits & (1 << 19)) { /* check for overrun irq */
+		update_rx_stats(&np->stats); /* this will ack the irq */
+		D(printk("ethernet receiver overrun!\n"));
+	}
+	if(irqbits & (1 << 17)) { /* check for excessive collision irq */
+		*R_NETWORK_TR_CTRL = 1 << 8; /* clear the interrupt */
+		np->stats.tx_errors++;
+		D(printk("ethernet excessive collisions!\n"));
+	}
+
+}
+
+/* We have a good packet(s), get it/them out of the buffers. */
+static void
+e100_rx(struct net_device *dev)
+{
+	struct sk_buff *skb;
+	int length=0;
+	int i;
+	struct etrax_dma_descr *mySaveRxDesc = myNextRxDesc;
+	unsigned char *skb_data_ptr;
+
+	/* light the network rx packet depending on the current speed.
+	** But only if link has been detected.
+	*/
+	if (!nolink)
+		if (current_speed == 10) {
+			LED_NETWORK_TX_SET(1);
+			LED_NETWORK_RX_SET(1);
+		} else
+			LED_NETWORK_RX_SET(1);
+  
+	/* Set the earliest time we may clear the LED */
+
+	led_clear_time = jiffies + NET_FLASH_TIME;
+  
+	/* If the packet is broken down in many small packages then merge
+	 * count how much space we will need to alloc with skb_alloc() for
+	 * it to fit.
+	 */
+
+	while (!(myNextRxDesc->status & d_eop)) {
+		length += myNextRxDesc->sw_len; /* use sw_len for the first descs */
+		myNextRxDesc->status = 0;
+		myNextRxDesc = phys_to_virt(myNextRxDesc->next);
+	}
+
+	length += myNextRxDesc->hw_len; /* use hw_len for the last descr */
+
+#ifdef ETHDEBUG
+	printk("Got a packet of length %d:\n", length);
+	/* dump the first bytes in the packet */
+	skb_data_ptr = (unsigned char *)phys_to_virt(mySaveRxDesc->buf);
+	for(i = 0; i < 8; i++) {
+		printk("%d: %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x\n", i * 8,
+		       skb_data_ptr[0],skb_data_ptr[1],skb_data_ptr[2],skb_data_ptr[3],
+		       skb_data_ptr[4],skb_data_ptr[5],skb_data_ptr[6],skb_data_ptr[7]);
+		skb_data_ptr += 8;
+	}
+#endif
+
+	skb = dev_alloc_skb(length - ETHER_HEAD_LEN);
+	if (!skb) {
+		printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n",
+		       dev->name);
+		return;
+	}
+
+	skb_put(skb, length - ETHER_HEAD_LEN);        /* allocate room for the packet body */
+	skb_data_ptr = skb_push(skb, ETHER_HEAD_LEN); /* allocate room for the header */
+
+#if 0
+	printk("head = 0x%x, data = 0x%x, tail = 0x%x, end = 0x%x\n",
+	       skb->head, skb->data, skb->tail, skb->end);
+	printk("copying packet to 0x%x.\n", skb_data_ptr);
+#endif
+
+	/* this loop can be made using max two memcpy's if optimized */
+
+	while(mySaveRxDesc != myNextRxDesc) {
+		memcpy(skb_data_ptr, phys_to_virt(mySaveRxDesc->buf),
+		       mySaveRxDesc->sw_len);
+		skb_data_ptr += mySaveRxDesc->sw_len;
+		mySaveRxDesc = phys_to_virt(mySaveRxDesc->next);
+	}
+
+	memcpy(skb_data_ptr, phys_to_virt(mySaveRxDesc->buf),
+	       mySaveRxDesc->hw_len);
+
+	skb->dev = dev;
+	skb->protocol = eth_type_trans(skb, dev);
+
+	/* Send the packet to the upper layers */
+
+	netif_rx(skb);
+
+	/* Prepare for next packet */
+
+	myNextRxDesc->status = 0;
+	myPrevRxDesc = myNextRxDesc;
+	myNextRxDesc = phys_to_virt(myNextRxDesc->next);
+
+	myPrevRxDesc->ctrl |= d_eol;
+	myLastRxDesc->ctrl &= ~d_eol;
+	myLastRxDesc = myPrevRxDesc;
+
+	return;
+}
+
+/* The inverse routine to net_open(). */
+static int
+e100_close(struct net_device *dev)
+{
+	struct net_local *np = (struct net_local *)dev->priv;
+
+	printk("Closing %s.\n", dev->name);
+
+	netif_stop_queue(dev);
+
+	*R_NETWORK_GEN_CONFIG =
+		IO_STATE(R_NETWORK_GEN_CONFIG, phy,    mii_clk) |
+		IO_STATE(R_NETWORK_GEN_CONFIG, enable, off);
+
+	*R_IRQ_MASK0_CLR = 0xe0000; /* clear excessive_col, over/underrun irq mask */
+	*R_IRQ_MASK2_CLR = 0xf; /* clear dma0 and 1 eop and descr irq masks */
+
+	/* Stop the reciever and the transmitter */
+
+	RESET_DMA(0);
+	RESET_DMA(1);
+
+	/* Flush the Tx and disable Rx here. */
+
+	free_irq(NETWORK_DMARX_IRQ, NULL);
+	free_irq(NETWORK_DMATX_IRQ, NULL);
+	free_irq(NETWORK_STATUS_IRQ, NULL);
+
+	free_dma(0);
+	free_dma(1);
+
+	/* Update the statistics here. */
+
+	update_rx_stats(&np->stats);
+	update_tx_stats(&np->stats);
+
+	return 0;
+}
+
+static void
+update_rx_stats(struct net_device_stats *es)
+{
+	unsigned long r = *R_REC_COUNTERS;
+	/* update stats relevant to reception errors */
+	es->rx_fifo_errors += r >> 24;            /* fifo overrun */
+	es->rx_crc_errors += r & 0xff;            /* crc error */
+	es->rx_frame_errors += (r >> 8) & 0xff;   /* alignment error */
+	es->rx_length_errors += (r >> 16) & 0xff; /* oversized frames */
+}
+
+static void
+update_tx_stats(struct net_device_stats *es)
+{
+	unsigned long r = *R_TR_COUNTERS;
+	/* update stats relevant to transmission errors */
+	es->collisions += (r & 0xff) + ((r >> 8) & 0xff); /* single_col + multiple_col */
+	es->tx_errors += (r >> 24) & 0xff; /* deferred transmit frames */
+}
+
+/*
+ * Get the current statistics.
+ * This may be called with the card open or closed.
+ */
+static struct net_device_stats *
+e100_get_stats(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *)dev->priv;
+
+	update_rx_stats(&lp->stats);
+	update_tx_stats(&lp->stats);
+
+	return &lp->stats;
+}
+
+/*
+ * Set or clear the multicast filter for this adaptor.
+ * num_addrs == -1	Promiscuous mode, receive all packets
+ * num_addrs == 0	Normal mode, clear multicast list
+ * num_addrs > 0	Multicast mode, receive normal and MC packets,
+ *			and do best-effort filtering.
+ */
+static void
+set_multicast_list(struct net_device *dev)
+{
+	int num_addr = dev->mc_count;
+	unsigned long int lo_bits;
+	unsigned long int hi_bits;
+	if (num_addr == -1)
+	{
+		/* promiscuous mode */
+		lo_bits = 0xfffffffful;
+		hi_bits = 0xfffffffful;
+	} else if (num_addr == 0) {
+		/* Normal, clear the mc list */
+		lo_bits = 0x00000000ul;
+		hi_bits = 0x00000000ul;
+	} else {
+		/* MC mode, receive normal and MC packets */
+		char hash_ix;
+		struct dev_mc_list *dmi = dev->mc_list;
+		int i;
+		char *baddr;
+		lo_bits = 0x00000000ul;
+		hi_bits = 0x00000000ul;
+		for (i=0; i<num_addr; i++) {
+			/* Calculate the hash index for the GA registers */
+			
+			hash_ix = 0;
+			baddr = dmi->dmi_addr;
+			hash_ix ^= (*baddr) & 0x3f;
+			hash_ix ^= ((*baddr) >> 6) & 0x03;
+			++baddr;
+			hash_ix ^= ((*baddr) << 2) & 0x03c;
+			hash_ix ^= ((*baddr) >> 4) & 0xf;
+			++baddr;
+			hash_ix ^= ((*baddr) << 4) & 0x30;
+			hash_ix ^= ((*baddr) >> 2) & 0x3f;
+			++baddr;
+			hash_ix ^= (*baddr) & 0x3f;
+			hash_ix ^= ((*baddr) >> 6) & 0x03;
+			++baddr;
+			hash_ix ^= ((*baddr) << 2) & 0x03c;
+			hash_ix ^= ((*baddr) >> 4) & 0xf;
+			++baddr;
+			hash_ix ^= ((*baddr) << 4) & 0x30;
+			hash_ix ^= ((*baddr) >> 2) & 0x3f;
+			
+			hash_ix &= 0x3f;
+			
+			if (hash_ix > 32) {
+				hi_bits |= (1 << (hash_ix-32));
+			}
+			else {
+				lo_bits |= (1 << hash_ix);
+			}
+			dmi = dmi->next;
+		}
+	}
+	*R_NETWORK_GA_0 = lo_bits;
+	*R_NETWORK_GA_1 = hi_bits;
+}
+
+void
+e100_hardware_send_packet(char *buf, int length)
+{
+	D(printk("e100 send pack, buf 0x%x len %d\n", buf, length));
+	/* light the network leds depending on the current speed.
+	** But only if link has been detected.
+	*/
+	if (!nolink) {
+		if (current_speed == 10) {
+			LED_NETWORK_TX_SET(1);
+			LED_NETWORK_RX_SET(1);
+		} else {
+			LED_NETWORK_RX_SET(1);
+		}
+	}
+
+	/* Set the earliest time we may clear the LED */
+
+	led_clear_time = jiffies + NET_FLASH_TIME;
+	
+	/* configure the tx dma descriptor */
+
+	TxDesc.sw_len = length;
+	TxDesc.ctrl = d_eop | d_eol | d_wait;
+	TxDesc.buf = virt_to_phys(buf);
+
+	/* setup the dma channel and start it */
+
+	*R_DMA_CH0_FIRST = virt_to_phys(&TxDesc);
+	*R_DMA_CH0_CMD = IO_STATE(R_DMA_CH0_CMD, cmd, start);
+}
+
+static void
+e100_clear_network_leds(unsigned long dummy)
+{
+	if (jiffies > led_clear_time) {
+		if (nolink)
+			LED_NETWORK_TX_SET(1);
+		else
+			LED_NETWORK_TX_SET(0);
+		LED_NETWORK_RX_SET(0); 
+	}
+	
+	clear_led_timer.expires = jiffies + 10;
+	add_timer(&clear_led_timer);
+}
+
+static struct net_device dev_etrax_ethernet;  /* only got one */
+
+static int
+etrax_init_module(void)
+{
+	struct net_device *d = &dev_etrax_ethernet;
+
+	d->init = etrax_ethernet_init;
+
+	if(register_netdev(d) == 0)
+		return 0;
+	else
+		return -ENODEV;
+}
+
+module_init(etrax_init_module);
diff -urN linux-2.4.2-pre1/arch/cris/drivers/ide.c linux/arch/cris/drivers/ide.c
--- linux-2.4.2-pre1/arch/cris/drivers/ide.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/ide.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,818 @@
+/* $Id: ide.c,v 1.4 2001/01/10 21:14:32 bjornw Exp $
+ *
+ * Etrax specific IDE functions, like init and PIO-mode setting etc.
+ * Almost the entire ide.c is used for the rest of the Etrax ATA driver.
+ * Copyright (c) 2000, 2001 Axis Communications AB 
+ *
+ * Authors:    Bjorn Wesen        (initial version)
+ *             Mikael Starvik     (pio setup stuff)
+ *
+ * $Log: ide.c,v $
+ * Revision 1.4  2001/01/10 21:14:32  bjornw
+ * Initialize hwif->ideproc, for the new way of handling ide_xxx_data
+ *
+ * Revision 1.3  2000/12/01 17:48:18  bjornw
+ * - atapi_output_bytes now uses DMA
+ * - dma_active check removed - the kernel does proper serializing and it had
+ *   a race-condition anyway
+ * - ide_build_dmatable had a nameclash
+ * - re-added the RESET_DMA thingys because sometimes the interface can get
+ *   stuck apparently
+ * - added ide_release_dma
+ *
+ * Revision 1.2  2000/11/29 17:31:29  bjornw
+ * 2.4 port
+ *
+ * - The "register addresses" stored in the hwif are now 32-bit fields that
+ *   don't need to be shifted into correct positions in R_ATA_CTRL_DATA
+ * - PIO-mode detection temporarily disabled since ide-modes.c is not compiled
+ * - All DMA uses virt_to_phys conversions for DMA buffers and descriptor ptrs
+ * - Probably correct ide_dma_begin semantics in dmaproc now for ATAPI devices
+ * - Removed RESET_DMA when starting a new transfer - why was this necessary ?
+ * - Indentation fix
+ *
+ *
+ */
+
+/* Regarding DMA: 
+ *
+ * There are two forms of DMA - "DMA handshaking" between the interface and the drive,
+ * and DMA between the memory and the interface. We can ALWAYS use the latter, since it's
+ * something built-in in the Etrax. However only some drives support the DMA-mode handshaking
+ * on the ATA-bus. The normal PC driver and Triton interface disables memory-if DMA when the
+ * device can't do DMA handshaking for some stupid reason. We don't need to do that.
+ */ 
+
+#undef REALLY_SLOW_IO           /* most systems can safely undef this */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <linux/ide.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/svinto.h>
+
+/* number of Etrax DMA descriptors */
+#define MAX_DMA_DESCRS 64
+
+#define LOWDB(x)
+#define D(x)
+
+void OUT_BYTE(unsigned char data, ide_ioreg_t reg) {
+	LOWDB(printk("ob: data 0x%x, reg 0x%x\n", data, reg));
+	while(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)); /* wait for busy flag */
+	*R_ATA_CTRL_DATA = reg | data; /* write data to the drive's register */
+	while(!(*R_ATA_STATUS_DATA &
+		IO_MASK(R_ATA_STATUS_DATA, tr_rdy))); /* wait for transmitter ready */
+}
+
+unsigned char IN_BYTE(ide_ioreg_t reg) {
+	int status;
+	while(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)); /* wait for busy flag */
+	*R_ATA_CTRL_DATA = reg | IO_STATE(R_ATA_CTRL_DATA, rw, read); /* read data */ 
+	while(!((status = *R_ATA_STATUS_DATA) &
+		IO_MASK(R_ATA_STATUS_DATA, dav))); /* wait for available */
+	LOWDB(printk("inb: 0x%x from reg 0x%x\n", status & 0xff, reg));
+	return (unsigned char)status; /* data was in the lower 16 bits in the status reg */
+}
+
+/* PIO timing (in R_ATA_CONFIG)
+ *
+ *                        _____________________________
+ * ADDRESS :     ________/
+ *
+ *                            _______________
+ * DIOR    :     ____________/               \__________
+ *
+ *                               _______________
+ * DATA    :     XXXXXXXXXXXXXXXX_______________XXXXXXXX
+ *
+ *
+ * DIOR is unbuffered while address and data is buffered.
+ * This creates two problems:
+ * 1. The DIOR pulse is to early (because it is unbuffered)
+ * 2. The rise time of DIOR is long
+ *
+ * There are at least three different plausible solutions
+ * 1. Use a pad capable of larger currents in Etrax
+ * 2. Use an external buffer
+ * 3. Make the strobe pulse longer
+ *
+ * Some of the strobe timings below are modified to compensate
+ * for this. This implies a slight performance decrease.
+ *
+ * THIS SHOULD NEVER BE CHANGED!
+ *
+ * TODO: Is this true for the latest LX boards still ?
+ */
+
+#define ATA_DMA2_STROBE  4 
+#define ATA_DMA2_HOLD    0
+#define ATA_DMA1_STROBE  4 
+#define ATA_DMA1_HOLD    1
+#define ATA_DMA0_STROBE 12 
+#define ATA_DMA0_HOLD    9
+#define ATA_PIO4_SETUP   1
+#define ATA_PIO4_STROBE  5
+#define ATA_PIO4_HOLD    0
+#define ATA_PIO3_SETUP   1
+#define ATA_PIO3_STROBE  5
+#define ATA_PIO3_HOLD    1
+#define ATA_PIO2_SETUP   1
+#define ATA_PIO2_STROBE  6
+#define ATA_PIO2_HOLD    2
+#define ATA_PIO1_SETUP   2
+#define ATA_PIO1_STROBE 11
+#define ATA_PIO1_HOLD    4
+#define ATA_PIO0_SETUP   4
+#define ATA_PIO0_STROBE 19
+#define ATA_PIO0_HOLD    4
+
+/*
+ * good_dma_drives() lists the model names (from "hdparm -i")
+ * of drives which do not support mword2 DMA but which are
+ * known to work fine with this interface under Linux.
+ */
+
+const char *good_dma_drives[] = {"Micropolis 2112A",
+				 "CONNER CTMA 4000",
+				 "CONNER CTT8000-A",
+				 NULL};
+
+static void tune_e100_ide(ide_drive_t *drive, byte pio)
+{
+	unsigned long flags;
+	
+	pio = 4;
+	//pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
+	
+	save_flags(flags);
+	cli();
+
+	/* set pio mode! */
+  	 
+	switch(pio) {
+		case 0:
+			*R_ATA_CONFIG = ( IO_FIELD( R_ATA_CONFIG, enable,     1 ) |
+					  IO_FIELD( R_ATA_CONFIG, dma_strobe, ATA_DMA2_STROBE ) |
+					  IO_FIELD( R_ATA_CONFIG, dma_hold,   ATA_DMA2_HOLD ) |
+					  IO_FIELD( R_ATA_CONFIG, pio_setup,  ATA_PIO0_SETUP ) |
+					  IO_FIELD( R_ATA_CONFIG, pio_strobe, ATA_PIO0_STROBE ) |
+					  IO_FIELD( R_ATA_CONFIG, pio_hold,   ATA_PIO0_HOLD ) );
+			break;
+		case 1:
+			*R_ATA_CONFIG = ( IO_FIELD( R_ATA_CONFIG, enable,     1 ) |
+					  IO_FIELD( R_ATA_CONFIG, dma_strobe, ATA_DMA2_STROBE ) |
+					  IO_FIELD( R_ATA_CONFIG, dma_hold,   ATA_DMA2_HOLD ) |
+					  IO_FIELD( R_ATA_CONFIG, pio_setup,  ATA_PIO1_SETUP ) |
+					  IO_FIELD( R_ATA_CONFIG, pio_strobe, ATA_PIO1_STROBE ) |
+					  IO_FIELD( R_ATA_CONFIG, pio_hold,   ATA_PIO1_HOLD ) );
+			break;
+		case 2:
+			*R_ATA_CONFIG = ( IO_FIELD( R_ATA_CONFIG, enable,     1 ) |
+					  IO_FIELD( R_ATA_CONFIG, dma_strobe, ATA_DMA2_STROBE ) |
+					  IO_FIELD( R_ATA_CONFIG, dma_hold,   ATA_DMA2_HOLD ) |
+					  IO_FIELD( R_ATA_CONFIG, pio_setup,  ATA_PIO2_SETUP ) |
+					  IO_FIELD( R_ATA_CONFIG, pio_strobe, ATA_PIO2_STROBE ) |
+					  IO_FIELD( R_ATA_CONFIG, pio_hold,   ATA_PIO2_HOLD ) );
+			break;
+		case 3:
+			*R_ATA_CONFIG = ( IO_FIELD( R_ATA_CONFIG, enable,     1 ) |
+					  IO_FIELD( R_ATA_CONFIG, dma_strobe, ATA_DMA2_STROBE ) |
+					  IO_FIELD( R_ATA_CONFIG, dma_hold,   ATA_DMA2_HOLD ) |
+					  IO_FIELD( R_ATA_CONFIG, pio_setup,  ATA_PIO3_SETUP ) |
+					  IO_FIELD( R_ATA_CONFIG, pio_strobe, ATA_PIO3_STROBE ) |
+					  IO_FIELD( R_ATA_CONFIG, pio_hold,   ATA_PIO3_HOLD ) );
+			break;
+		case 4:
+			*R_ATA_CONFIG = ( IO_FIELD( R_ATA_CONFIG, enable,     1 ) |
+					  IO_FIELD( R_ATA_CONFIG, dma_strobe, ATA_DMA2_STROBE ) |
+					  IO_FIELD( R_ATA_CONFIG, dma_hold,   ATA_DMA2_HOLD ) |
+					  IO_FIELD( R_ATA_CONFIG, pio_setup,  ATA_PIO4_SETUP ) |
+					  IO_FIELD( R_ATA_CONFIG, pio_strobe, ATA_PIO4_STROBE ) |
+					  IO_FIELD( R_ATA_CONFIG, pio_hold,   ATA_PIO4_HOLD ) );
+			break;
+	}
+	restore_flags(flags);
+}
+
+static int e100_dmaproc (ide_dma_action_t func, ide_drive_t *drive); /* defined below */
+static void e100_ideproc (ide_ide_action_t func, ide_drive_t *drive,
+			  void *buffer, unsigned int length);        /* defined below */
+
+void __init init_e100_ide (void)
+{
+	volatile unsigned int dummy;
+	int h;
+
+	printk("ide: ETRAX 100LX built-in ATA DMA controller\n");
+
+	/* first fill in some stuff in the ide_hwifs fields */
+	
+	for(h = 0; h < MAX_HWIFS; h++) {
+		ide_hwif_t *hwif = &ide_hwifs[h];
+		hwif->chipset = ide_etrax100;
+		hwif->tuneproc = &tune_e100_ide;
+		hwif->dmaproc = &e100_dmaproc;
+		hwif->ideproc = &e100_ideproc;
+	}
+	/* actually reset and configure the etrax100 ide/ata interface */
+
+	/* de-assert bus-reset */
+#ifdef CONFIG_ETRAX_IDE_PB7_RESET  
+	port_pb_dir_shadow = port_pb_dir_shadow | 
+		IO_STATE(R_PORT_PB_DIR, dir7, output);
+	*R_PORT_PB_DIR = port_pb_dir_shadow;
+	REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, 7, 1);
+#endif
+#ifdef CONFIG_ETRAX_IDE_G27_RESET
+	*R_PORT_G_DATA = 0;
+#endif 
+
+	*R_ATA_CTRL_DATA = 0;
+	*R_ATA_TRANSFER_CNT = 0;
+	*R_ATA_CONFIG = 0;
+
+	genconfig_shadow = (genconfig_shadow & 
+			    ~IO_MASK(R_GEN_CONFIG, dma2) &
+			    ~IO_MASK(R_GEN_CONFIG, dma3) &
+			    ~IO_MASK(R_GEN_CONFIG, ata)) | 
+		( IO_STATE( R_GEN_CONFIG, dma3, ata    ) |
+		  IO_STATE( R_GEN_CONFIG, dma2, ata    ) |
+		  IO_STATE( R_GEN_CONFIG, ata,  select ) );
+
+	*R_GEN_CONFIG = genconfig_shadow;
+
+#ifdef CONFIG_ETRAX_IDE_CSE1_16_RESET
+	*(volatile long *)(MEM_CSE1_START | MEM_NON_CACHEABLE) = 0;
+#endif
+
+	/* wait some */
+
+	dummy = 1;
+	dummy = 2;
+	dummy = 3;
+
+#ifdef CONFIG_ETRAX_IDE_CSE1_16_RESET
+	*(volatile long *)(MEM_CSE1_START | MEM_NON_CACHEABLE) = 1 << 16;
+	*R_PORT_G_DATA = 0;  /* de-assert bus-reset */
+#endif
+
+	/* make a dummy read to set the ata controller in a proper state */
+	dummy = *R_ATA_STATUS_DATA;
+  
+	*R_ATA_CONFIG = ( IO_FIELD( R_ATA_CONFIG, enable,     1 ) |
+			  IO_FIELD( R_ATA_CONFIG, dma_strobe, ATA_DMA2_STROBE ) |
+			  IO_FIELD( R_ATA_CONFIG, dma_hold,   ATA_DMA2_HOLD ) |
+			  IO_FIELD( R_ATA_CONFIG, pio_setup,  ATA_PIO4_SETUP ) |
+			  IO_FIELD( R_ATA_CONFIG, pio_strobe, ATA_PIO4_STROBE ) |
+			  IO_FIELD( R_ATA_CONFIG, pio_hold,   ATA_PIO4_HOLD ) );
+
+	*R_ATA_CTRL_DATA = ( IO_STATE( R_ATA_CTRL_DATA, rw,   read) |
+			     IO_FIELD( R_ATA_CTRL_DATA, addr, 1   ) );
+
+	while(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)); /* wait for busy flag*/
+
+	*R_IRQ_MASK0_SET = ( IO_STATE( R_IRQ_MASK0_SET, ata_irq0, set ) |
+			     IO_STATE( R_IRQ_MASK0_SET, ata_irq1, set ) |
+			     IO_STATE( R_IRQ_MASK0_SET, ata_irq2, set ) |
+			     IO_STATE( R_IRQ_MASK0_SET, ata_irq3, set ) );
+
+	printk("ide: waiting 10 seconds for drives to regain consciousness\n");
+
+	h = jiffies + 1000;
+	while(jiffies < h) ;
+
+  /* reset the dma channels we will use */
+
+	RESET_DMA(2);
+	RESET_DMA(3);
+	WAIT_DMA(2);
+	WAIT_DMA(3);
+
+}
+
+static etrax_dma_descr mydescr;
+
+/*
+ * The following routines are mainly used by the ATAPI drivers.
+ *
+ * These routines will round up any request for an odd number of bytes,
+ * so if an odd bytecount is specified, be sure that there's at least one
+ * extra byte allocated for the buffer.
+ */
+static void 
+e100_atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount)
+{
+	ide_ioreg_t data_reg = IDE_DATA_REG;
+	unsigned long status;
+
+	D(printk("atapi_input_bytes, dreg 0x%x, buffer 0x%x, count %d\n",
+		 data_reg, buffer, bytecount));
+	
+	if(bytecount & 1) {
+		printk("warning, odd bytecount in cdrom_in_bytes = %d.\n", bytecount);
+		bytecount++; /* to round off */
+	}
+	
+	/* make sure the DMA channel is available */
+	RESET_DMA(3);
+	WAIT_DMA(3); 
+	
+	/* setup DMA descriptor */
+	
+	mydescr.sw_len = bytecount;
+	mydescr.ctrl   = d_eol;
+	mydescr.buf    = virt_to_phys(buffer);
+	
+	/* start the dma channel */
+	
+	*R_DMA_CH3_FIRST = virt_to_phys(&mydescr);
+	*R_DMA_CH3_CMD   = IO_STATE(R_DMA_CH3_CMD, cmd, start);
+	
+	/* initiate a multi word dma read using PIO handshaking */
+	
+	*R_ATA_TRANSFER_CNT = bytecount >> 1;
+	
+	*R_ATA_CTRL_DATA = data_reg |
+		IO_STATE(R_ATA_CTRL_DATA, rw,       read) |
+		IO_STATE(R_ATA_CTRL_DATA, src_dst,  dma) |
+		IO_STATE(R_ATA_CTRL_DATA, handsh,   pio) |
+		IO_STATE(R_ATA_CTRL_DATA, multi,    on) |
+		IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
+	
+	/* wait for completion */
+	
+	LED_DISK_READ(1);
+	WAIT_DMA(3);
+	LED_DISK_READ(0);
+	
+#if 0
+	/* old polled transfer code */
+	
+	/* initiate a multi word read */
+	
+	*R_ATA_TRANSFER_CNT = wcount << 1;
+	
+	*R_ATA_CTRL_DATA = data_reg |
+		IO_STATE(R_ATA_CTRL_DATA, rw,       read) |
+		IO_STATE(R_ATA_CTRL_DATA, src_dst,  register) |
+		IO_STATE(R_ATA_CTRL_DATA, handsh,   pio) |
+		IO_STATE(R_ATA_CTRL_DATA, multi,    on) |
+		IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
+	
+	/* svinto has a latency until the busy bit actually is set */
+	
+	nop(); nop();
+	nop(); nop();
+	nop(); nop();
+	nop(); nop();
+	nop(); nop();
+	
+	/* unit should be busy during multi transfer */
+	while((status = *R_ATA_STATUS_DATA) & IO_MASK(R_ATA_STATUS_DATA, busy)) {
+		while(!(status & IO_MASK(R_ATA_STATUS_DATA, dav)))
+			status = *R_ATA_STATUS_DATA;
+		*ptr++ = (unsigned short)(status & 0xffff);
+	}
+#endif
+}
+
+static void 
+e100_atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount)
+{
+	ide_ioreg_t data_reg = IDE_DATA_REG;
+	unsigned short *ptr = (unsigned short *)buffer;
+	unsigned long ctrl;
+	
+	D(printk("atapi_output_bytes, dreg 0x%x, buffer 0x%x, count %d\n",
+		 data_reg, buffer, bytecount));
+
+	if(bytecount & 1) {
+		printk("odd bytecount %d in atapi_out_bytes!\n", bytecount);
+		bytecount++;
+	}
+
+	/* make sure the DMA channel is available */
+	RESET_DMA(2);
+	WAIT_DMA(2); 
+	
+	/* setup DMA descriptor */
+	
+	mydescr.sw_len = bytecount;
+	mydescr.ctrl   = d_eol;
+	mydescr.buf    = virt_to_phys(buffer);
+
+	/* start the dma channel */
+	
+	*R_DMA_CH2_FIRST = virt_to_phys(&mydescr);
+	*R_DMA_CH2_CMD   = IO_STATE(R_DMA_CH2_CMD, cmd, start);
+	
+	/* initiate a multi word dma write using PIO handshaking */
+	
+	*R_ATA_TRANSFER_CNT = bytecount >> 1;
+	
+	*R_ATA_CTRL_DATA = data_reg |
+		IO_STATE(R_ATA_CTRL_DATA, rw,       write) |
+		IO_STATE(R_ATA_CTRL_DATA, src_dst,  dma) |
+		IO_STATE(R_ATA_CTRL_DATA, handsh,   pio) |
+		IO_STATE(R_ATA_CTRL_DATA, multi,    on) |
+		IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
+	
+	/* wait for completion */
+	
+	LED_DISK_WRITE(1);
+	WAIT_DMA(2);
+	LED_DISK_WRITE(0);
+
+#if 0
+	/* old polled write code */
+
+	while(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)); /* wait for busy flag */
+
+	/* initiate a multi word write */
+
+	*R_ATA_TRANSFER_CNT = bytecount >> 1;
+
+	ctrl = data_reg |
+		IO_STATE(R_ATA_CTRL_DATA, rw,       write) |
+		IO_STATE(R_ATA_CTRL_DATA, src_dst,  register) |
+		IO_STATE(R_ATA_CTRL_DATA, handsh,   pio) |
+		IO_STATE(R_ATA_CTRL_DATA, multi,    on) |
+		IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
+	
+	LED_DISK_WRITE(1);
+	
+	/* Etrax will set busy = 1 until the multi pio transfer has finished
+	 * and tr_rdy = 1 after each succesful word transfer. 
+	 * When the last byte has been transfered Etrax will first set tr_tdy = 1 
+	 * and then busy = 0 (not in the same cycle). If we read busy before it
+	 * has been set to 0 we will think that we should transfer more bytes 
+	 * and then tr_rdy would be 0 forever. This is solved by checking busy
+	 * in the inner loop.
+	 */
+	
+	do {
+		*R_ATA_CTRL_DATA = ctrl | *ptr++;
+		while(!(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, tr_rdy)) &&
+		      (*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)));
+	} while(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy));
+
+	LED_DISK_WRITE(0);
+#endif	
+}
+
+/*
+ * This is used for most PIO data transfers *from* the IDE interface
+ */
+static void 
+e100_ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
+{
+	e100_atapi_input_bytes(drive, buffer, wcount << 2);
+}
+
+/*
+ * This is used for most PIO data transfers *to* the IDE interface
+ */
+static void
+e100_ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
+{
+	e100_atapi_output_bytes(drive, buffer, wcount << 2);
+}
+
+/*
+ * The multiplexor for ide_xxxput_data and atapi calls
+ */
+static void 
+e100_ideproc (ide_ide_action_t func, ide_drive_t *drive,
+	      void *buffer, unsigned int length)
+{
+	switch (func) {
+		case ideproc_ide_input_data:
+			e100_ide_input_data(drive, buffer, length);
+			break;
+		case ideproc_ide_output_data:
+			e100_ide_input_data(drive, buffer, length);
+			break;
+		case ideproc_atapi_input_bytes:
+			e100_atapi_input_bytes(drive, buffer, length);
+			break;
+		case ideproc_atapi_output_bytes:
+			e100_atapi_output_bytes(drive, buffer, length);
+			break;
+		default:
+			printk("e100_ideproc: unsupported func %d!\n", func);
+			break;
+	}
+}
+
+/* we only have one DMA channel on the chip for ATA, so we can keep these statically */
+static etrax_dma_descr ata_descrs[MAX_DMA_DESCRS];
+static unsigned int ata_tot_size;
+
+/*
+ * e100_ide_build_dmatable() prepares a dma request.
+ * Returns 0 if all went okay, returns 1 otherwise.
+ */
+static int e100_ide_build_dmatable (ide_drive_t *drive)
+{
+	struct request *rq = HWGROUP(drive)->rq;
+	struct buffer_head *bh = rq->bh;
+	unsigned long size, addr;
+	unsigned int count = 0;
+
+	ata_tot_size = 0;
+
+	do {
+		/*
+		 * Determine addr and size of next buffer area.  We assume that
+		 * individual virtual buffers are always composed linearly in
+		 * physical memory.  For example, we assume that any 8kB buffer
+		 * is always composed of two adjacent physical 4kB pages rather
+		 * than two possibly non-adjacent physical 4kB pages.
+		 */
+		if (bh == NULL) {  /* paging and tape requests have (rq->bh == NULL) */
+			addr = virt_to_phys (rq->buffer);
+			size = rq->nr_sectors << 9;
+		} else {
+			/* group sequential buffers into one large buffer */
+			addr = virt_to_phys (bh->b_data);
+			size = bh->b_size;
+			while ((bh = bh->b_reqnext) != NULL) {
+				if ((addr + size) != virt_to_phys (bh->b_data))
+					break;
+				size += bh->b_size;
+			}
+		}
+
+		/* did we run out of descriptors? */
+
+		if(count >= MAX_DMA_DESCRS) {
+			printk("%s: too few DMA descriptors\n", drive->name);
+			return 1;
+		}
+
+		/* uh.. I'm lazy.. if size >= 65536, it should loop below and split it in
+		   more than one descriptor */
+
+		if(size >= 65536) {
+			printk("too large ATA DMA request block, size = %d!\n", size);
+			return 1;
+		}
+
+		/* however, this case is more difficult - R_ATA_TRANSFER_CNT cannot be more
+		   than 65536 words per transfer, so in that case we need to either 
+		   1) use a DMA interrupt to re-trigger R_ATA_TRANSFER_CNT and continue with
+		      the descriptors, or
+		   2) simply do the request here, and get dma_intr to only ide_end_request on 
+		      those blocks that were actually set-up for transfer.
+		*/
+
+		if(ata_tot_size + size >= 131072) {
+			printk("too large total ATA DMA request, %d + %d!\n", ata_tot_size, size);
+			return 1;
+		}
+
+		/* ok we want to do IO at addr, size bytes. set up a new descriptor entry */
+
+		ata_descrs[count].sw_len = size;
+		ata_descrs[count].ctrl = 0;
+		ata_descrs[count].buf = addr;
+		ata_descrs[count].next = virt_to_phys(&ata_descrs[count + 1]);
+		count++;
+		ata_tot_size += size;
+
+	} while (bh != NULL);
+
+	if (count) {
+		/* set the end-of-list flag on the last descriptor */
+		ata_descrs[count - 1].ctrl |= d_eol;
+		/* return and say all is ok */
+		return 0;
+	}
+
+	printk("%s: empty DMA table?\n", drive->name);
+	return 1;	/* let the PIO routines handle this weirdness */
+}
+
+static int config_drive_for_dma (ide_drive_t *drive)
+{
+        const char **list;
+        struct hd_driveid *id = drive->id;
+
+        if (id && (id->capability & 1)) {
+                /* Enable DMA on any drive that supports mword2 DMA */
+                if ((id->field_valid & 2) && (id->dma_mword & 0x404) == 0x404) {
+                        drive->using_dma = 1;
+                        return 0;               /* DMA enabled */
+                }
+
+                /* Consult the list of known "good" drives */
+                list = good_dma_drives;
+                while (*list) {
+                        if (!strcmp(*list++,id->model)) {
+                                drive->using_dma = 1;
+                                return 0;       /* DMA enabled */
+                        }
+                }
+        }
+        return 1;       /* DMA not enabled */
+}
+
+/*
+ * etrax_dma_intr() is the handler for disk read/write DMA interrupts
+ */
+static ide_startstop_t etrax_dma_intr (ide_drive_t *drive)
+{
+	int i, dma_stat;
+	byte stat;
+
+	LED_DISK_READ(0);
+	LED_DISK_WRITE(0);
+
+	dma_stat = HWIF(drive)->dmaproc(ide_dma_end, drive);
+	stat = GET_STAT();			/* get drive status */
+	if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
+		if (!dma_stat) {
+			struct request *rq;
+			rq = HWGROUP(drive)->rq;
+			for (i = rq->nr_sectors; i > 0;) {
+				i -= rq->current_nr_sectors;
+				ide_end_request(1, HWGROUP(drive));
+			}
+			return ide_stopped;
+		}
+		printk("%s: bad DMA status\n", drive->name);
+	}
+	return ide_error(drive, "dma_intr", stat);
+}
+
+/*
+ * e100_dmaproc() initiates/aborts DMA read/write operations on a drive.
+ *
+ * The caller is assumed to have selected the drive and programmed the drive's
+ * sector address using CHS or LBA.  All that remains is to prepare for DMA
+ * and then issue the actual read/write DMA/PIO command to the drive.
+ *
+ * For ATAPI devices, we just prepare for DMA and return. The caller should
+ * then issue the packet command to the drive and call us again with
+ * ide_dma_begin afterwards.
+ *
+ * Returns 0 if all went well.
+ * Returns 1 if DMA read/write could not be started, in which case
+ * the caller should revert to PIO for the current request.
+ */
+
+static int e100_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
+{
+        static unsigned int reading; /* static to support ide_dma_begin semantics */
+	int atapi = 0;
+
+	D(printk("e100_dmaproc func %d\n", func));
+
+        switch (func) {
+		case ide_dma_verbose:
+			return 0;
+                case ide_dma_check:
+                        return config_drive_for_dma (drive);
+		case ide_dma_off:
+		case ide_dma_off_quietly:
+			/* ok.. we don't really need to do anything I think. */
+			return 0;
+                case ide_dma_write:
+                        reading = 0;
+			break;
+                case ide_dma_read:
+			reading = 1;
+                        break;
+                case ide_dma_begin:
+			/* begin DMA, used by ATAPI devices which want to issue the 
+			 * appropriate IDE command themselves.
+			 *
+			 * they have already called ide_dma_read/write to set the
+			 * static reading flag, now they call ide_dma_begin to do
+			 * the real stuff. we tell our code below not to issue
+			 * any IDE commands itself and jump into it. 
+			 */
+			atapi++;
+			goto dma_begin;
+		case ide_dma_end: /* returns 1 on error, 0 otherwise */
+			/* TODO: check if something went wrong with the DMA */
+			return 0;
+
+                default:
+                        printk("e100_dmaproc: unsupported func %d\n", func);
+                        return 1;
+        }
+
+	/* ATAPI-devices (not disks) first call ide_dma_read/write to set the direction
+	 * then they call ide_dma_begin after they have issued the appropriate drive command
+	 * themselves to actually start the chipset DMA. so we just return here if we're
+	 * not a diskdrive.
+	 */
+
+        if (drive->media != ide_disk)
+                return 0;
+
+ dma_begin:
+
+	if(reading) {
+
+		RESET_DMA(3); /* sometimes the DMA channel get stuck so we need to do this */
+		WAIT_DMA(3);
+
+		/* set up the Etrax DMA descriptors */
+		
+		if(e100_ide_build_dmatable (drive))
+			return 1;
+
+		if(!atapi) {
+			/* set the irq handler which will finish the request when DMA is done */
+		
+			ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
+			
+			/* issue cmd to drive */
+			
+			OUT_BYTE(WIN_READDMA, IDE_COMMAND_REG);
+		}
+
+		/* begin DMA */
+	      
+		*R_DMA_CH3_FIRST = virt_to_phys(ata_descrs);
+		*R_DMA_CH3_CMD   = IO_STATE(R_DMA_CH3_CMD, cmd, start);
+		
+		/* initiate a multi word dma read using DMA handshaking */
+		
+		*R_ATA_TRANSFER_CNT = ata_tot_size >> 1;
+		
+		*R_ATA_CTRL_DATA = IDE_DATA_REG  |
+			IO_STATE(R_ATA_CTRL_DATA, rw,       read) |
+			IO_STATE(R_ATA_CTRL_DATA, src_dst,  dma)  |
+			IO_STATE(R_ATA_CTRL_DATA, handsh,   dma)  |
+			IO_STATE(R_ATA_CTRL_DATA, multi,    on)   |
+			IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
+
+		LED_DISK_READ(1);
+
+		D(printk("dma read of %d bytes.\n", ata_tot_size));
+ 
+	} else {
+		/* writing */
+
+		RESET_DMA(2); /* sometimes the DMA channel get stuck so we need to do this */
+		WAIT_DMA(2);
+
+		/* set up the Etrax DMA descriptors */
+
+		if(e100_ide_build_dmatable (drive))
+			return 1;
+
+		if(!atapi) {
+			/* set the irq handler which will finish the request when DMA is done */
+				
+			ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
+			
+			/* issue cmd to drive */
+			
+			OUT_BYTE(WIN_WRITEDMA, IDE_COMMAND_REG);
+		}
+
+		/* begin DMA */
+		
+		*R_DMA_CH2_FIRST = virt_to_phys(ata_descrs);
+		*R_DMA_CH2_CMD   = IO_STATE(R_DMA_CH2_CMD, cmd, start);
+		
+		/* initiate a multi word dma write using DMA handshaking */
+		
+		*R_ATA_TRANSFER_CNT = ata_tot_size >> 1;
+		
+		*R_ATA_CTRL_DATA = IDE_DATA_REG |
+			IO_STATE(R_ATA_CTRL_DATA, rw,       write) |
+			IO_STATE(R_ATA_CTRL_DATA, src_dst,  dma) |
+			IO_STATE(R_ATA_CTRL_DATA, handsh,   dma) |
+			IO_STATE(R_ATA_CTRL_DATA, multi,    on) |
+			IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
+
+		LED_DISK_WRITE(1);
+
+		D(printk("dma write of %d bytes.\n", ata_tot_size));
+	}
+
+	/* DMA started successfully */
+	return 0;
+}
+
+/* ide.c calls this, but we don't need to do anything particular */
+
+int ide_release_dma (ide_hwif_t *hwif)
+{
+	return 1;
+}
diff -urN linux-2.4.2-pre1/arch/cris/drivers/serial.c linux/arch/cris/drivers/serial.c
--- linux-2.4.2-pre1/arch/cris/drivers/serial.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/serial.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,3039 @@
+/* $Id: serial.c,v 1.6 2000/11/22 16:36:09 bjornw Exp $
+ *
+ * Serial port driver for the ETRAX 100LX chip
+ *
+ *      Copyright (C) 1998, 1999, 2000  Axis Communications AB
+ *
+ *      Many, many authors. Based once upon a time on serial.c for 16x50.
+ *
+ * $Log: serial.c,v $
+ * Revision 1.6  2000/11/22 16:36:09  bjornw
+ * Please marketing by using the correct case when spelling Etrax.
+ *
+ * Revision 1.5  2000/11/21 16:43:37  bjornw
+ * Fixed so it compiles under CONFIG_SVINTO_SIM
+ *
+ * Revision 1.4  2000/11/15 17:34:12  bjornw
+ * Added a timeout timer for flushing input channels. The interrupt-based
+ * fast flush system should be easy to merge with this later (works the same
+ * way, only with an irq instead of a system timer_list)
+ *
+ * Revision 1.3  2000/11/13 17:19:57  bjornw
+ * * Incredibly, this almost complete rewrite of serial.c worked (at least
+ *   for output) the first time.
+ *
+ *   Items worth noticing:
+ *
+ *      No Etrax100 port 1 workarounds (does only compile on 2.4 anyway now)
+ *      RS485 is not ported (why cant it be done in userspace as on x86 ?)
+ *      Statistics done through async_icount - if any more stats are needed,
+ *      that's the place to put them or in an arch-dep version of it.
+ *      timeout_interrupt and the other fast timeout stuff not ported yet
+ *      There be dragons in this 3k+ line driver
+ *
+ * Revision 1.2  2000/11/10 16:50:28  bjornw
+ * First shot at a 2.4 port, does not compile totally yet
+ *
+ * Revision 1.1  2000/11/10 16:47:32  bjornw
+ * Added verbatim copy of rev 1.49 etrax100ser.c from elinux
+ *
+ * Revision 1.49  2000/10/30 15:47:14  tobiasa
+ * Changed version number.
+ *
+ * Revision 1.48  2000/10/25 11:02:43  johana
+ * Changed %ul to %lu in printf's
+ *
+ * Revision 1.47  2000/10/18 15:06:53  pkj
+ * Compile correctly with CONFIG_ETRAX100_SERIAL_FLUSH_DMA_FAST and
+ * CONFIG_SERIAL_PROC_ENTRY together.
+ * Some clean-up of the /proc/serial file.
+ *
+ * Revision 1.46  2000/10/16 12:59:40  johana
+ * Added CONFIG_SERIAL_PROC_ENTRY for statistics and debug info.
+ *
+ * Revision 1.45  2000/10/13 17:10:59  pkj
+ * Do not flush DMAs while flipping TTY buffers.
+ *
+ * Revision 1.44  2000/10/13 16:34:29  pkj
+ * Added a delay in ser_interrupt() for 2.3ms when an error is detected.
+ * We do not know why this delay is required yet, but without it the
+ * irmaflash program does not work (this was the program that needed
+ * the ser_interrupt() to be needed in the first place). This should not
+ * affect normal use of the serial ports.
+ *
+ * Revision 1.43  2000/10/13 16:30:44  pkj
+ * New version of the fast flush of serial buffers code. This time
+ * it is localized to the serial driver and uses a fast timer to
+ * do the work.
+ *
+ * Revision 1.42  2000/10/13 14:54:26  bennyo
+ * Fix for switching RTS when using rs485
+ *
+ * Revision 1.41  2000/10/12 11:43:44  pkj
+ * Cleaned up a number of comments.
+ *
+ * Revision 1.40  2000/10/10 11:58:39  johana
+ * Made RS485 support generic for all ports.
+ * Toggle rts in interrupt if no delay wanted.
+ * WARNING: No true transmitter empty check??
+ * Set d_wait bit when sending data so interrupt is delayed until
+ * fifo flushed. (Fix tcdrain() problem)
+ *
+ * Revision 1.39  2000/10/04 16:08:02  bjornw
+ * * Use virt_to_phys etc. for DMA addresses
+ * * Removed CONFIG_FLUSH_DMA_FAST hacks
+ * * Indentation fix
+ *
+ * Revision 1.38  2000/10/02 12:27:10  mattias
+ * * added variable used when using fast flush on serial dma.
+ *   (CONFIG_FLUSH_DMA_FAST)
+ *
+ * Revision 1.37  2000/09/27 09:44:24  pkj
+ * Uncomment definition of SERIAL_HANDLE_EARLY_ERRORS.
+ *
+ * Revision 1.36  2000/09/20 13:12:52  johana
+ * Support for CONFIG_ETRAX100_SERIAL_RX_TIMEOUT_TICKS:
+ *   Number of timer ticks between flush of receive fifo (1 tick = 10ms).
+ *   Try 0-3 for low latency applications. Approx 5 for high load
+ *   applications (e.g. PPP). Maybe this should be more adaptive some day...
+ *
+ * Revision 1.35  2000/09/20 10:36:08  johana
+ * Typo in get_lsr_info()
+ *
+ * Revision 1.34  2000/09/20 10:29:59  johana
+ * Let rs_chars_in_buffer() check fifo content as well.
+ * get_lsr_info() might work now (not tested).
+ * Easier to change the port to debug.
+ *
+ * Revision 1.33  2000/09/13 07:52:11  torbjore
+ * Support RS485
+ *
+ * Revision 1.32  2000/08/31 14:45:37  bjornw
+ * After sending a break we need to reset the transmit DMA channel
+ *
+ * Revision 1.31  2000/06/21 12:13:29  johana
+ * Fixed wait for all chars sent when closing port.
+ * (Used to always take 1 second!)
+ * Added shadows for directions of status/ctrl signals.
+ *
+ * Revision 1.30  2000/05/29 16:27:55  bjornw
+ * Simulator ifdef moved a bit
+ *
+ * Revision 1.29  2000/05/09 09:40:30  mattias
+ * * Added description of dma registers used in timeout_interrupt
+ * * Removed old code
+ *
+ * Revision 1.28  2000/05/08 16:38:58  mattias
+ * * Bugfix for flushing fifo in timeout_interrupt
+ *   Problem occurs when bluetooth stack waits for a small number of bytes
+ *   containing an event acknowledging free buffers in bluetooth HW
+ *   As before, data was stuck in fifo until more data came on uart and
+ *   flushed it up to the stack.
+ *
+ * Revision 1.27  2000/05/02 09:52:28  jonasd
+ * Added fix for peculiar etrax behaviour when eop is forced on an empty
+ * fifo. This is used when flashing the IRMA chip. Disabled by default.
+ *
+ * Revision 1.26  2000/03/29 15:32:02  bjornw
+ * 2.0.34 updates
+ *
+ * Revision 1.25  2000/02/16 16:59:36  bjornw
+ * * Receive DMA directly into the flip-buffer, eliminating an intermediary
+ *   receive buffer and a memcpy. Will avoid some overruns.
+ * * Error message on debug port if an overrun or flip buffer overrun occurs.
+ * * Just use the first byte in the flag flip buffer for errors.
+ * * Check for timeout on the serial ports only each 5/100 s, not 1/100.
+ *
+ * Revision 1.24  2000/02/09 18:02:28  bjornw
+ * * Clear serial errors (overrun, framing, parity) correctly. Before, the
+ *   receiver would get stuck if an error occured and we did not restart
+ *   the input DMA.
+ * * Cosmetics (indentation, some code made into inlines)
+ * * Some more debug options
+ * * Actually shut down the serial port (DMA irq, DMA reset, receiver stop)
+ *   when the last open is closed. Corresponding fixes in startup().
+ * * rs_close() "tx FIFO wait" code moved into right place, bug & -> && fixed
+ *   and make a special case out of port 1 (R_DMA_CHx_STATUS is broken for that)
+ * * e100_disable_rx/enable_rx just disables/enables the receiver, not RTS
+ *
+ * Revision 1.23  2000/01/24 17:46:19  johana
+ * Wait for flush of DMA/FIFO when closing port.
+ *
+ * Revision 1.22  2000/01/20 18:10:23  johana
+ * Added TIOCMGET ioctl to return modem status.
+ * Implemented modem status/control that works with the extra signals
+ * (DTR, DSR, RI,CD) as well.
+ * 3 different modes supported:
+ * ser0 on PB (Bundy), ser1 on PB (Lisa) and ser2 on PA (Bundy)
+ * Fixed DEF_TX value that caused the serial transmitter pin (txd) to go to 0 when
+ * closing the last filehandle, NASTY!.
+ * Added break generation, not tested though!
+ * Use SA_SHIRQ when request_irq() for ser2 and ser3 (shared with) par0 and par1.
+ * You can't use them at the same time (yet..), but you can hopefully switch
+ * between ser2/par0, ser3/par1 with the same kernel config.
+ * Replaced some magic constants with defines
+ *
+ *
+ */
+
+static char *serial_version = "$Revision: 1.6 $";
+
+#include <linux/config.h>
+#include <linux/version.h>
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+#if (LINUX_VERSION_CODE >= 131343)
+#include <linux/init.h>
+#endif
+#if (LINUX_VERSION_CODE >= 131336)
+#include <asm/uaccess.h>
+#endif
+#include <linux/kernel.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/segment.h>
+#include <asm/bitops.h>
+#include <asm/delay.h>
+
+#include <asm/svinto.h>
+
+/* non-arch dependant serial structures are in linux/serial.h */
+#include <linux/serial.h>
+/* while we keep our own stuff (struct e100_serial) in a local .h file */
+#include "serial.h"
+
+/*
+ * All of the compatibilty code so we can compile serial.c against
+ * older kernels is hidden in serial_compat.h
+ */
+#if defined(LOCAL_HEADERS) || (LINUX_VERSION_CODE < 0x020317) /* 2.3.23 */
+#include "serial_compat.h"
+#endif
+
+static DECLARE_TASK_QUEUE(tq_serial);
+
+struct tty_driver serial_driver, callout_driver;
+static int serial_refcount;
+
+/* serial subtype definitions */
+#ifndef SERIAL_TYPE_NORMAL
+#define SERIAL_TYPE_NORMAL	1
+#define SERIAL_TYPE_CALLOUT	2
+#endif
+
+/* number of characters left in xmit buffer before we ask for more */
+#define WAKEUP_CHARS 256
+
+//#define SERIAL_DEBUG_INTR
+//#define SERIAL_DEBUG_OPEN 
+//#define SERIAL_DEBUG_FLOW
+//#define SERIAL_DEBUG_DATA
+//#define SERIAL_DEBUG_THROTTLE
+//#define SERIAL_DEBUG_IO  /* Debug for Extra control and status pins */
+#define SERIAL_DEBUG_LINE 0 /* What serport we want to debug */
+
+/* Enable this to use serial interrupts to handle when you
+   expect the first recieved event on the serial port to
+   be an error, break or similar. Used to be able to flash IRMA
+   from eLinux */
+//#define SERIAL_HANDLE_EARLY_ERRORS
+
+
+#ifndef CONFIG_ETRAX100_SERIAL_RX_TIMEOUT_TICKS
+/* Default number of timer ticks before flushing rx fifo 
+ * When using "little data, low latency applications: use 0
+ * When using "much data applications (PPP)" use ~5
+ */
+#define CONFIG_ETRAX100_SERIAL_RX_TIMEOUT_TICKS 5 
+#endif
+
+#define MAX_FLUSH_TIME 8
+
+#define _INLINE_ inline
+
+static void change_speed(struct e100_serial *info);
+static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
+static int rs_write(struct tty_struct * tty, int from_user,
+                    const unsigned char *buf, int count);
+
+#define DEF_BAUD 0x99   /* 115.2 kbit/s */
+#define STD_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST )
+#define DEF_RX 0x20  /* or SERIAL_CTRL_W >> 8 */
+/* Default value of tx_ctrl register: has txd(bit 7)=1 (idle) as default */
+#define DEF_TX 0x80  /* or SERIAL_CTRL_B */
+
+/* offsets from R_SERIALx_CTRL */
+
+#define REG_DATA 0
+#define REG_TR_DATA 0
+#define REG_STATUS 1
+#define REG_TR_CTRL 1
+#define REG_REC_CTRL 2
+#define REG_BAUD 3
+#define REG_XOFF 4  /* this is a 32 bit register */
+
+/* this is the data for the four serial ports in the etrax100 */
+/*  DMA2(ser2), DMA4(ser3), DMA6(ser0) or DMA8(ser1) */
+/* R_DMA_CHx_CLR_INTR, R_DMA_CHx_FIRST, R_DMA_CHx_CMD */
+
+static struct e100_serial rs_table[] = {
+	{ DEF_BAUD, (unsigned char *)R_SERIAL0_CTRL, 1U << 12, /* uses DMA 6 and 7 */
+	  R_DMA_CH6_CLR_INTR, R_DMA_CH6_FIRST, R_DMA_CH6_CMD,
+	  R_DMA_CH6_STATUS, R_DMA_CH6_HWSW,
+	  R_DMA_CH7_CLR_INTR, R_DMA_CH7_FIRST, R_DMA_CH7_CMD,
+	  R_DMA_CH7_STATUS, R_DMA_CH7_HWSW,
+	  STD_FLAGS, DEF_RX, DEF_TX, 2 },  /* ttyS0 */
+#ifndef CONFIG_SVINTO_SIM
+	{ DEF_BAUD, (unsigned char *)R_SERIAL1_CTRL, 1U << 16, /* uses DMA 8 and 9 */
+	  R_DMA_CH8_CLR_INTR, R_DMA_CH8_FIRST, R_DMA_CH8_CMD,
+	  R_DMA_CH8_STATUS, R_DMA_CH8_HWSW,
+	  R_DMA_CH9_CLR_INTR, R_DMA_CH9_FIRST, R_DMA_CH9_CMD,
+	  R_DMA_CH9_STATUS, R_DMA_CH9_HWSW,
+	  STD_FLAGS, DEF_RX, DEF_TX, 3 },  /* ttyS1 */
+
+	{ DEF_BAUD, (unsigned char *)R_SERIAL2_CTRL, 1U << 4,  /* uses DMA 2 and 3 */
+	  R_DMA_CH2_CLR_INTR, R_DMA_CH2_FIRST, R_DMA_CH2_CMD,
+	  R_DMA_CH2_STATUS, R_DMA_CH2_HWSW,
+	  R_DMA_CH3_CLR_INTR, R_DMA_CH3_FIRST, R_DMA_CH3_CMD,
+	  R_DMA_CH3_STATUS, R_DMA_CH3_HWSW,
+	  STD_FLAGS, DEF_RX, DEF_TX, 0 },  /* ttyS2 */
+
+	{ DEF_BAUD, (unsigned char *)R_SERIAL3_CTRL, 1U << 8,  /* uses DMA 4 and 5 */
+	  R_DMA_CH4_CLR_INTR, R_DMA_CH4_FIRST, R_DMA_CH4_CMD,
+	  R_DMA_CH4_STATUS, R_DMA_CH4_HWSW,
+	  R_DMA_CH5_CLR_INTR, R_DMA_CH5_FIRST, R_DMA_CH5_CMD,
+	  R_DMA_CH5_STATUS, R_DMA_CH5_HWSW,
+	  STD_FLAGS, DEF_RX, DEF_TX, 1 }   /* ttyS3 */
+#endif
+};
+
+
+#define NR_PORTS (sizeof(rs_table)/sizeof(struct e100_serial))
+  
+static struct tty_struct *serial_table[NR_PORTS]; 
+static struct termios *serial_termios[NR_PORTS];
+static struct termios *serial_termios_locked[NR_PORTS];
+
+
+/* RS-485 */
+#if defined(CONFIG_RS485)
+#if defined(CONFIG_RS485_ON_PA)
+static int rs485_pa_bit = CONFIG_RS485_ON_PA_BIT;
+#endif
+#endif
+  
+
+/* For now we assume that all bits are on the same port for each serial port */
+
+/* Dummy shadow variables */
+static unsigned char dummy_ser0 = 0x00;
+static unsigned char dummy_ser1 = 0x00;
+static unsigned char dummy_ser2 = 0x00;
+static unsigned char dummy_ser3 = 0x00;
+
+static unsigned char dummy_dir_ser0 = 0x00;
+static unsigned char dummy_dir_ser1 = 0x00;
+static unsigned char dummy_dir_ser2 = 0x00;
+static unsigned char dummy_dir_ser3 = 0x00;
+
+/* Info needed for each ports extra control/status signals.
+   We only supports that all pins uses same register for each port */
+struct control_pins
+{
+	volatile unsigned char *port;
+	volatile unsigned char *shadow;
+	volatile unsigned char *dir_shadow;
+	
+	unsigned char dtr_bit;
+	unsigned char ri_bit;
+	unsigned char dsr_bit;
+	unsigned char cd_bit;
+};
+
+static const struct control_pins e100_modem_pins[NR_PORTS] = 
+{
+/* Ser 0 */
+  {
+#if defined(CONFIG_ETRAX100_SER0_DTR_RI_DSR_CD_ON_PB)
+    R_PORT_PB_DATA,  &port_pb_data_shadow,  &port_pb_dir_shadow,
+    CONFIG_ETRAX100_SER0_DTR_ON_PB_BIT,
+	  CONFIG_ETRAX100_SER0_RI_ON_PB_BIT, 
+	  CONFIG_ETRAX100_SER0_DSR_ON_PB_BIT, 
+	  CONFIG_ETRAX100_SER0_CD_ON_PB_BIT
+#else
+    &dummy_ser0, &dummy_ser0, &dummy_dir_ser0, 0, 1, 2, 3
+#endif   
+  },
+/* Ser 1 */
+  {
+#if defined(CONFIG_ETRAX100_SER1_DTR_RI_DSR_CD_ON_PB)
+    R_PORT_PB_DATA,  &port_pb_data_shadow,  &port_pb_dir_shadow,
+    CONFIG_ETRAX100_SER1_DTR_ON_PB_BIT,
+	  CONFIG_ETRAX100_SER1_RI_ON_PB_BIT, 
+	  CONFIG_ETRAX100_SER1_DSR_ON_PB_BIT, 
+	  CONFIG_ETRAX100_SER1_CD_ON_PB_BIT
+#else
+    &dummy_ser1, &dummy_ser1, &dummy_dir_ser1, 0, 1, 2, 3
+#endif   
+  },  
+/* Ser 2 */
+  {
+#if defined(CONFIG_ETRAX100_SER2_DTR_RI_DSR_CD_ON_PA)
+    R_PORT_PA_DATA,  &port_pa_data_shadow,  &port_pa_dir_shadow,
+    CONFIG_ETRAX100_SER2_DTR_ON_PA_BIT,
+	  CONFIG_ETRAX100_SER2_RI_ON_PA_BIT, 
+	  CONFIG_ETRAX100_SER2_DSR_ON_PA_BIT, 
+	  CONFIG_ETRAX100_SER2_CD_ON_PA_BIT
+#else
+    &dummy_ser2, &dummy_ser2, &dummy_dir_ser2, 0, 1, 2, 3
+#endif   
+  },
+/* Ser 3 */
+  {
+    &dummy_ser3, &dummy_ser3, &dummy_dir_ser3, 0, 1, 2, 3
+  }
+};
+
+#if defined(CONFIG_RS485) && defined(CONFIG_RS485_ON_PA)
+unsigned char rs485_pa_port = CONFIG_RS485_ON_PA_BIT;
+#endif
+
+#define E100_RTS_MASK 0x20
+#define E100_CTS_MASK 0x40
+
+
+/* All serial port signals are active low:
+ * active   = 0 -> 3.3V to RS-232 driver -> -12V on RS-232 level
+ * inactive = 1 -> 0V   to RS-232 driver -> +12V on RS-232 level
+ *
+ * These macros returns the pin value: 0=0V, >=1 = 3.3V on ETRAX chip
+ */
+
+/* Output */
+#define E100_RTS_GET(info) ((info)->rx_ctrl & E100_RTS_MASK)
+/* Input */
+#define E100_CTS_GET(info) ((info)->port[REG_STATUS] & E100_CTS_MASK)
+
+/* These are typically PA or PB and 0 means 0V, 1 means 3.3V */
+/* Is an output */
+#define E100_DTR_GET(info) ((*e100_modem_pins[(info)->line].shadow) & (1 << e100_modem_pins[(info)->line].dtr_bit))
+
+/* Normally inputs */
+#define E100_RI_GET(info) ((*e100_modem_pins[(info)->line].port) & (1 << e100_modem_pins[(info)->line].ri_bit))
+#define E100_CD_GET(info) ((*e100_modem_pins[(info)->line].port) & (1 << e100_modem_pins[(info)->line].cd_bit))
+
+/* Input */
+#define E100_DSR_GET(info) ((*e100_modem_pins[(info)->line].port) & (1 << e100_modem_pins[(info)->line].dsr_bit))
+
+
+#ifndef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#endif
+
+/*
+ * tmp_buf is used as a temporary buffer by serial_write.  We need to
+ * lock it in case the memcpy_fromfs blocks while swapping in a page,
+ * and some other program tries to do a serial write at the same time.
+ * Since the lock will only come under contention when the system is
+ * swapping and available memory is low, it makes sense to share one
+ * buffer across all the serial ports, since it significantly saves
+ * memory if large numbers of serial ports are open.
+ */
+static unsigned char *tmp_buf;
+#ifdef DECLARE_MUTEX
+static DECLARE_MUTEX(tmp_buf_sem);
+#else
+static struct semaphore tmp_buf_sem = MUTEX;
+#endif
+
+#ifdef CONFIG_ETRAX100_SERIAL_FLUSH_DMA_FAST
+#define TIMER1_IRQ_NBR 3
+
+/* clock select 10 for timer 1 gives 230400 Hz */
+#define FASTTIMER_SELECT (10)
+/* we use a source of 230400 Hz and a divider of 15 => 15360 Hz */
+#define FASTTIMER_DIV (15)
+
+/* fast flush timer stuff */
+static int fast_timer_started = 0;
+static unsigned long int fast_timer_ints = 0;
+
+static void _INLINE_ start_flush_timer(void)
+{
+	if (fast_timer_started)
+		return;
+
+	*R_TIMER_CTRL = r_timer_ctrl_shadow = 
+		(r_timer_ctrl_shadow &
+		 ~IO_MASK(R_TIMER_CTRL, timerdiv1) &
+		 ~IO_MASK(R_TIMER_CTRL, tm1) &
+		 ~IO_MASK(R_TIMER_CTRL, clksel1)) | 
+		IO_FIELD(R_TIMER_CTRL, timerdiv1, FASTTIMER_DIV) |
+		IO_STATE(R_TIMER_CTRL, tm1, stop_ld) | 
+		IO_FIELD(R_TIMER_CTRL, clksel1, FASTTIMER_SELECT);
+
+	*R_TIMER_CTRL = r_timer_ctrl_shadow = 
+		(r_timer_ctrl_shadow & ~IO_MASK(R_TIMER_CTRL, tm1)) |
+		IO_STATE(R_TIMER_CTRL, tm1, run);
+
+	/* enable timer1 irq */
+
+	*R_IRQ_MASK0_SET = IO_STATE(R_IRQ_MASK0_SET, timer1, set);
+	fast_timer_started = 1;
+}
+#endif /* CONFIG_ETRAX100_SERIAL_FLUSH_DMA_FAST */
+
+/*
+ * This function maps from the Bxxxx defines in asm/termbits.h into real
+ * baud rates.
+ */
+
+static int 
+cflag_to_baud(unsigned int cflag)
+{
+	static int baud_table[] = {
+		0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400,
+		4800, 9600, 19200, 38400 };
+	
+	static int ext_baud_table[] = {
+		0, 57600, 115200, 230400, 460800, 921600, 1843200, 6250000 };
+	
+	if(cflag & CBAUDEX)
+		return ext_baud_table[(cflag & CBAUD) & ~CBAUDEX];
+	else 
+		return baud_table[cflag & CBAUD];
+}
+
+/* and this maps to an etrax100 hardware baud constant */
+
+static unsigned char 
+cflag_to_etrax_baud(unsigned int cflag)
+{
+	char retval;
+	
+	static char baud_table[] = {
+		-1, -1, -1, -1, -1, -1, -1, 0, 1, 2, -1, 3, 4, 5, 6, 7 };
+	
+	static char ext_baud_table[] = {
+		-1, 8, 9, 10, 11, 12, 13, 14 };
+	
+	if(cflag & CBAUDEX)
+		retval = ext_baud_table[(cflag & CBAUD) & ~CBAUDEX];
+	else 
+		retval = baud_table[cflag & CBAUD];
+	
+	if(retval < 0) {
+		printk("serdriver tried setting invalid baud rate, flags %x.\n", cflag);
+		retval = 5; /* choose default 9600 instead */
+	}
+
+	return retval | (retval << 4); /* choose same for both TX and RX */
+}
+
+
+/* Various static support functions */
+
+/* Functions to set or clear DTR/RTS on the requested line */
+/* It is complicated by the fact that RTS is a serial port register, while
+ * DTR might not be implemented in the HW at all, and if it is, it can be on
+ * any general port.
+ */
+
+static inline void 
+e100_dtr(struct e100_serial *info, int set)
+{
+#ifndef CONFIG_SVINTO_SIM
+	unsigned char mask  = ( 1 << e100_modem_pins[info->line].dtr_bit);
+#ifdef SERIAL_DEBUG_IO  
+	printk("ser%i dtr %i mask: 0x%02X\n", info->line, set, mask);
+	printk("ser%i shadow before 0x%02X get: %i\n", 
+	       info->line, *e100_modem_pins[info->line].shadow,
+	       E100_DTR_GET(info));
+#endif
+	/* DTR is active low */
+	{
+		unsigned long flags;	
+		save_flags(flags);
+		cli();
+		*e100_modem_pins[info->line].shadow &= ~mask;
+		*e100_modem_pins[info->line].shadow |= (set ? 0 : mask); 
+		*e100_modem_pins[info->line].port = *e100_modem_pins[info->line].shadow;
+		restore_flags(flags);
+	}
+	
+#if 0
+	REG_SHADOW_SET(e100_modem_pins[info->line].port,
+		       *e100_modem_pins[info->line].shadow,
+		       e100_modem_pins[info->line].dtr_bit, !set);
+#endif
+#ifdef SERIAL_DEBUG_IO
+	printk("ser%i shadow after 0x%02X get: %i\n", 
+	       info->line, *e100_modem_pins[info->line].shadow, 
+	       E100_DTR_GET(info));
+#endif
+#endif
+}
+
+/* set = 0 means 3.3V on the pin, bitvalue: 0=active, 1=inactive  
+ *                                          0=0V    , 1=3.3V
+ */
+static inline void 
+e100_rts(struct e100_serial *info, int set)
+{
+#ifndef CONFIG_SVINTO_SIM
+#ifdef SERIAL_DEBUG_IO  
+	printk("ser%i rts %i\n", info->line, set);
+#endif
+	info->rx_ctrl &= ~E100_RTS_MASK;
+	info->rx_ctrl |= (set ? 0 : E100_RTS_MASK);  /* RTS is active low */
+	info->port[REG_REC_CTRL] = info->rx_ctrl;
+#endif
+}
+
+/* If this behaves as a modem, RI and CD is an output */
+static inline void 
+e100_ri_out(struct e100_serial *info, int set)
+{
+#ifndef CONFIG_SVINTO_SIM
+	/* RI is active low */
+	{
+		unsigned char mask  = ( 1 << e100_modem_pins[info->line].ri_bit);
+		unsigned long flags;	
+		save_flags(flags);
+		cli();
+		*e100_modem_pins[info->line].shadow &= ~mask;
+		*e100_modem_pins[info->line].shadow |= (set ? 0 : mask); 
+		*e100_modem_pins[info->line].port = *e100_modem_pins[info->line].shadow;
+		restore_flags(flags);
+	}
+#if 0
+	REG_SHADOW_SET(e100_modem_pins[info->line].port,
+		       *e100_modem_pins[info->line].shadow,
+		       e100_modem_pins[info->line].ri_bit, !set);
+#endif
+#endif
+}
+static inline void 
+e100_cd_out(struct e100_serial *info, int set)
+{
+#ifndef CONFIG_SVINTO_SIM
+	/* CD is active low */
+	{
+		unsigned char mask  = ( 1 << e100_modem_pins[info->line].cd_bit);
+		unsigned long flags;	
+		save_flags(flags);
+		cli();
+		*e100_modem_pins[info->line].shadow &= ~mask;
+		*e100_modem_pins[info->line].shadow |= (set ? 0 : mask); 
+		*e100_modem_pins[info->line].port = *e100_modem_pins[info->line].shadow;
+		restore_flags(flags);
+	}
+#if 0
+	REG_SHADOW_SET(e100_modem_pins[info->line].port,
+		       *e100_modem_pins[info->line].shadow,
+		       e100_modem_pins[info->line].cd_bit, !set);
+#endif
+#endif
+}
+
+static inline void
+e100_disable_rx(struct e100_serial *info)
+{
+#ifndef CONFIG_SVINTO_SIM
+	/* disable the receiver */
+	info->port[REG_REC_CTRL] = (info->rx_ctrl &= ~0x40);
+#endif
+}
+
+static inline void 
+e100_enable_rx(struct e100_serial *info)
+{
+#ifndef CONFIG_SVINTO_SIM
+	/* enable the receiver */
+	info->port[REG_REC_CTRL] = (info->rx_ctrl |= 0x40);
+#endif
+}
+
+/* the rx DMA uses both the dma_descr and the dma_eop interrupts */
+
+static inline void
+e100_disable_rxdma_irq(struct e100_serial *info) 
+{
+#ifdef SERIAL_DEBUG_INTR
+	printk("rxdma_irq(%d): 0\n",info->line);
+#endif
+	*R_IRQ_MASK2_CLR = (info->irq << 2) | (info->irq << 3);
+}
+
+static inline void
+e100_enable_rxdma_irq(struct e100_serial *info) 
+{
+#ifdef SERIAL_DEBUG_INTR
+	printk("rxdma_irq(%d): 1\n",info->line);
+#endif
+	*R_IRQ_MASK2_SET = (info->irq << 2) | (info->irq << 3);
+}
+
+/* the tx DMA uses only dma_descr interrupt */
+
+static inline void
+e100_disable_txdma_irq(struct e100_serial *info) 
+{
+#ifdef SERIAL_DEBUG_INTR
+	printk("txdma_irq(%d): 0\n",info->line);
+#endif
+	*R_IRQ_MASK2_CLR = info->irq;
+}
+
+static inline void
+e100_enable_txdma_irq(struct e100_serial *info) 
+{
+#ifdef SERIAL_DEBUG_INTR
+	printk("txdma_irq(%d): 1\n",info->line);
+#endif
+	*R_IRQ_MASK2_SET = info->irq;
+}
+
+#ifdef SERIAL_HANDLE_EARLY_ERRORS
+/* in order to detect and fix errors on the first byte
+ we have to use the serial interrupts as well. */
+
+static inline void
+e100_disable_serial_data_irq(struct e100_serial *info) 
+{
+#ifdef SERIAL_DEBUG_INTR
+	printk("ser_irq(%d): 0\n",info->line);
+#endif
+	*R_IRQ_MASK1_CLR = (1U << (8+2*info->line));
+}
+
+static inline void
+e100_enable_serial_data_irq(struct e100_serial *info) 
+{
+#ifdef SERIAL_DEBUG_INTR
+	printk("ser_irq(%d): 1\n",info->line);
+	printk("**** %d = %d\n",
+	       (8+2*info->line),
+	       (1U << (8+2*info->line)));
+#endif
+	*R_IRQ_MASK1_SET = (1U << (8+2*info->line));
+}
+#endif
+
+#if defined(CONFIG_RS485)
+/* Enable RS-485 mode on selected port. This is UGLY. */
+static int
+e100_enable_rs485(struct tty_struct *tty,struct rs485_control *r)
+{
+	struct e100_serial * info = (struct e100_serial *)tty->driver_data;
+
+#if defined(CONFIG_RS485_ON_PA)	
+	*R_PORT_PA_DATA = port_pa_data_shadow |= (1 << rs485_pa_bit);
+#endif
+
+	info->rs485.rts_on_send = 0x01 & r->rts_on_send;
+	info->rs485.rts_after_sent = 0x01 & r->rts_after_sent;
+	info->rs485.delay_rts_before_send = r->delay_rts_before_send;
+	info->rs485.enabled = r->enabled;
+	
+	return 0;
+}
+
+/* Enable RS-485 mode on selected port. This is UGLY. */
+static int
+e100_write_rs485(struct tty_struct *tty,struct rs485_write *r)
+{
+	int stop_delay;
+	int total, i;
+	int max_j, delay_ms, bits;
+	tcflag_t cflags;
+	int size = (*r).outc_size;
+	struct e100_serial * info = (struct e100_serial *)tty->driver_data;
+	struct wait_queue wait = { current, NULL };
+
+	/* If we are in RS-485 mode, we need to toggle RTS and disable
+	 * the receiver before initiating a DMA transfer
+	 */
+	e100_rts(info, info->rs485.rts_on_send);
+#if defined(CONFIG_RS485_DISABLE_RECEIVER)
+	e100_disable_rx(info);
+	e100_disable_rxdma_irq(info);
+#endif
+
+	if (info->rs485.delay_rts_before_send > 0){
+		current->timeout = jiffies + (info->rs485.delay_rts_before_send * HZ)/1000;
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		current->timeout = 0;
+	}
+	total = rs_write(tty, 1, (*r).outc, (*r).outc_size);
+
+	/* If we are in RS-485 mode the following things has to be done:
+	 * wait until DMA is ready
+	 * wait on transmit shift register
+	 * wait to toggle RTS
+	 * enable the receiver
+	 */	
+
+	/* wait on transmit shift register */
+	/* All is sent, check if we should wait more before toggling rts */
+	
+	/* calc. number of bits / data byte */
+	cflags = info->tty->termios->c_cflag;
+	/* databits + startbit and 1 stopbit */
+	if((cflags & CSIZE) == CS7) 
+	  bits = 9;
+	else
+	  bits = 10;  
+
+	if(cflags & CSTOPB)     /* 2 stopbits ? */
+	  bits++;
+
+	if(cflags & PARENB)     /* parity bit ? */
+	  bits++;
+	
+	/* calc timeout */
+	delay_ms = ((bits * size * 1000) / info->baud) + 1;
+	max_j = jiffies + (delay_ms * HZ)/1000 + 10;
+
+	while (jiffies < max_j ) {
+	  if (info->port[REG_STATUS] & 0x20) {
+	    for( i=0 ; i<100; i++ ) {};
+	    if (info->port[REG_STATUS] & 0x20) {
+	      /* ~25 for loops per usec */
+	      stop_delay = 25 * (1000000 / info->baud);
+	      if(cflags & CSTOPB) 
+		stop_delay *= 2;
+	      for( i=0 ; i<stop_delay; i++ ) {};
+	      break;
+	    }
+	  }
+	}
+
+	e100_rts(info, info->rs485.rts_after_sent);
+	
+#if defined(CONFIG_RS485_DISABLE_RECEIVER)
+	e100_enable_rx(info);
+	e100_enable_rxdma_irq(info);
+#endif
+
+	return total;
+}
+#endif
+
+/*
+ * ------------------------------------------------------------
+ * rs_stop() and rs_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+
+/* FIXME - when are these used and what is the purpose ? 
+ * In rs_stop we probably just can block the transmit DMA ready irq
+ * and in rs_start we re-enable it (and then the old one will come).
+ */
+
+static void 
+rs_stop(struct tty_struct *tty)
+{
+}
+
+static void 
+rs_start(struct tty_struct *tty)
+{
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Here starts the interrupt handling routines.  All of the following
+ * subroutines are declared as inline and are folded into
+ * rs_interrupt().  They were separated out for readability's sake.
+ *
+ * Note: rs_interrupt() is a "fast" interrupt, which means that it
+ * runs with interrupts turned off.  People who may want to modify
+ * rs_interrupt() should try to keep the interrupt handler as fast as
+ * possible.  After you are done making modifications, it is not a bad
+ * idea to do:
+ * 
+ * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
+ *
+ * and look at the resulting assemble code in serial.s.
+ *
+ * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
+ * -----------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+static _INLINE_ void 
+rs_sched_event(struct e100_serial *info,
+				    int event)
+{
+	info->event |= 1 << event;
+	queue_task(&info->tqueue, &tq_serial);
+	mark_bh(SERIAL_BH);
+}
+
+/* The output DMA channel is free - use it to send as many chars as possible
+ * NOTES:
+ *   We don't pay attention to info->x_char, which means if the TTY wants to
+ *   use XON/XOFF it will set info->x_char but we won't send any X char!
+ * 
+ *   To implement this, we'd just start a DMA send of 1 byte pointing at a
+ *   buffer containing the X char, and skip updating xmit. We'd also have to
+ *   check if the last sent char was the X char when we enter this function
+ *   the next time, to avoid updating xmit with the sent X value.
+ */
+
+static void 
+transmit_chars(struct e100_serial *info)
+{
+	unsigned int c, sentl;
+	struct etrax_dma_descr *descr;
+
+#ifdef CONFIG_SVINTO_SIM
+	/* This will output too little if tail is not 0 always since
+	 * we don't reloop to send the other part. Anyway this SHOULD be a
+	 * no-op - transmit_chars would never really be called during sim
+	 * since rs_write does not write into the xmit buffer then.
+	 */
+	if(info->xmit.tail)
+		printk("Error in serial.c:transmit_chars(), tail!=0\n");
+	if(info->xmit.head != info->xmit.tail) {
+		SIMCOUT(info->xmit.buf + info->xmit.tail,
+			CIRC_CNT(info->xmit.head,
+				 info->xmit.tail,
+				 SERIAL_XMIT_SIZE));
+		info->xmit.head = info->xmit.tail;  /* move back head */
+		info->tr_running = 0;
+	}
+	return;
+#endif
+	/* acknowledge both a dma_descr and dma_eop irq in R_DMAx_CLRINTR */
+	*info->oclrintradr = 3;
+
+#ifdef SERIAL_DEBUG_INTR
+	if(info->line == SERIAL_DEBUG_LINE)
+		printk("tc\n");
+#endif
+	if(!info->tr_running) {
+		/* weirdo... we shouldn't get here! */
+		printk("Achtung: transmit_chars with !tr_running\n");
+		return;
+	}
+
+	descr = &info->tr_descr;
+
+	/* first get the amount of bytes sent during the last DMA transfer,
+	   and update xmit accordingly */
+
+	/* if the stop bit was not set, all data has been sent */
+	if(!(descr->status & d_stop)) {
+		sentl = descr->sw_len;
+	} else 
+		/* otherwise we find the amount of data sent here */
+		sentl = descr->hw_len;
+
+	/* update stats */
+	info->icount.tx += sentl;
+
+	/* update xmit buffer */
+	info->xmit.tail = (info->xmit.tail + sentl) & (SERIAL_XMIT_SIZE - 1);
+
+	/* if there is only a few chars left in the buf, wake up the blocked
+	   write if any */
+	if (CIRC_CNT(info->xmit.head,
+		     info->xmit.tail,
+		     SERIAL_XMIT_SIZE) < WAKEUP_CHARS)
+		rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+
+	/* find out the largest amount of consecutive bytes we want to send now */
+
+	c = CIRC_CNT_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+
+	if(c <= 0) {
+		/* our job here is done, don't schedule any new DMA transfer */
+		info->tr_running = 0;
+
+#if defined(CONFIG_RS485)
+		/* Check if we should toggle RTS now */
+		if (info->rs485.enabled)
+		{
+			/* Make sure fifo is empty */
+			int in_fifo = 0 ;
+			do{
+				in_fifo = (*info->ostatusadr) & 0x007F ;
+			}  while (in_fifo > 0) ;
+			/* Any way to really check transmitter empty? (TEMT) */
+			/* Control RTS to set to RX mode */
+			e100_rts(info, info->rs485.rts_after_sent); 
+#if defined(CONFIG_RS485_DISABLE_RECEIVER)
+			e100_enable_rx(info);
+			e100_enable_rxdma_irq(info);
+#endif
+		}
+#endif /* RS485 */
+
+		return;
+	}
+
+	/* ok we can schedule a dma send of c chars starting at info->xmit.tail */
+	/* set up the descriptor correctly for output */
+
+	descr->ctrl = d_int | d_eol | d_wait; /* Wait needed for tty_wait_until_sent() */
+	descr->sw_len = c;
+	descr->buf = virt_to_phys(info->xmit.buf + info->xmit.tail);
+	descr->status = 0;
+
+	*info->ofirstadr = virt_to_phys(descr); /* write to R_DMAx_FIRST */
+	*info->ocmdadr = 1;       /* dma command start -> R_DMAx_CMD */
+	
+	/* DMA is now running (hopefully) */
+
+}
+
+static void 
+start_transmit(struct e100_serial *info)
+{
+#if 0
+	if(info->line == SERIAL_DEBUG_LINE)
+		printk("x\n");
+#endif
+
+	info->tr_descr.sw_len = 0;
+	info->tr_descr.hw_len = 0;
+	info->tr_descr.status = 0;
+	info->tr_running = 1;
+
+	transmit_chars(info);
+}
+
+
+static _INLINE_ void 
+receive_chars(struct e100_serial *info)
+{
+	struct tty_struct *tty;
+	unsigned char rstat;
+	unsigned int recvl;
+	struct etrax_dma_descr *descr;
+
+#ifdef CONFIG_SVINTO_SIM
+	/* No receive in the simulator.  Will probably be when the rest of
+	 * the serial interface works, and this piece will just be removed.
+	 */
+	return;
+#endif
+
+	tty = info->tty;
+
+	/* acknowledge both a dma_descr and dma_eop irq in R_DMAx_CLRINTR */
+
+	*info->iclrintradr = 3;
+
+	if(!tty) /* something wrong... */
+		return;
+
+	descr = &info->rec_descr;
+  
+	/* find out how many bytes were read */
+
+	/* if the eop bit was not set, all data has been received */
+	if(!(descr->status & d_eop)) {
+		recvl = descr->sw_len;
+	} else {
+		/* otherwise we find the amount of data received here */
+		recvl = descr->hw_len;
+	}
+	if(recvl) {
+		unsigned char *buf;
+		struct async_icount *icount;
+
+		icount = &info->icount;
+
+		/* update stats */
+		icount->rx += recvl;
+
+		/* read the status register so we can detect errors */
+		rstat = info->port[REG_STATUS];
+
+		if(rstat & 0xe) {
+			/* if we got an error, we must reset it by reading the
+			 * data_in field
+			 */
+			(void)info->port[REG_DATA];
+		}
+		
+		/* we only ever write errors into the first byte in the flip 
+		 * flag buffer, so we dont have to clear it all every time
+		 */
+
+		if(rstat & 0x04) {
+			icount->parity++;
+			*tty->flip.flag_buf_ptr = TTY_PARITY;
+		} else if(rstat & 0x08) {
+			icount->overrun++;
+			*tty->flip.flag_buf_ptr = TTY_OVERRUN;
+		} else if(rstat & 0x02) {
+			icount->frame++;
+			*tty->flip.flag_buf_ptr = TTY_FRAME;
+		} else
+			*tty->flip.flag_buf_ptr = 0;
+
+		/* use the flip buffer next in turn to restart DMA into */
+		
+		if (tty->flip.buf_num) {
+			buf = tty->flip.char_buf;
+		} else {
+			buf = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
+		}
+
+		if(buf == phys_to_virt(descr->buf)) {
+			printk("ttyS%d flip-buffer overrun!\n", info->line);
+			icount->overrun++;
+			*tty->flip.flag_buf_ptr = TTY_OVERRUN;
+			/* restart old buffer */
+		} else {
+			descr->buf = virt_to_phys(buf);
+			
+			/* schedule or push a flip of the buffer */
+			
+			info->tty->flip.count = recvl;
+
+#if (LINUX_VERSION_CODE > 131394) /* 2.1.66 */
+			/* this includes a check for low-latency */
+			tty_flip_buffer_push(tty);
+#else
+			queue_task_irq_off(&tty->flip.tqueue, &tq_timer);
+#endif	
+		}
+	}
+	
+	/* restart the receiving dma */
+	
+	descr->sw_len = TTY_FLIPBUF_SIZE;
+	descr->ctrl = d_int | d_eol | d_eop;
+	descr->hw_len = 0;
+	descr->status = 0;
+
+	*info->ifirstadr = virt_to_phys(descr);
+	*info->icmdadr = 1; /* start */
+
+#ifdef SERIAL_HANDLE_EARLY_ERRORS
+	e100_enable_serial_data_irq(info);
+#endif	
+	/* input dma should be running now */
+}
+
+static void 
+start_receive(struct e100_serial *info)
+{
+	struct etrax_dma_descr *descr;
+	
+#ifdef CONFIG_SVINTO_SIM
+	/* No receive in the simulator.  Will probably be when the rest of
+	 * the serial interface works, and this piece will just be removed.
+	 */
+	return;
+#endif
+
+	/* reset the input dma channel to be sure it works */
+	
+	*info->icmdadr = 4;
+	while((*info->icmdadr & 7) == 4);
+
+	descr = &info->rec_descr;
+	
+	/* start the receiving dma into the flip buffer */
+	
+	descr->ctrl = d_int | d_eol | d_eop;
+	descr->sw_len = TTY_FLIPBUF_SIZE;
+	descr->buf = virt_to_phys(info->tty->flip.char_buf_ptr);
+	descr->hw_len = 0;
+	descr->status = 0;
+	
+	info->tty->flip.count = 0;
+
+	*info->ifirstadr = virt_to_phys(descr);
+	*info->icmdadr = 1; /* start */
+}
+
+
+static _INLINE_ void 
+status_handle(struct e100_serial *info, unsigned short status)
+{
+}
+
+/* the bits in the MASK2 register are laid out like this:
+   DMAI_EOP DMAI_DESCR DMAO_EOP DMAO_DESCR
+   where I is the input channel and O is the output channel for the port.
+   info->irq is the bit number for the DMAO_DESCR so to check the others we
+   shift info->irq to the left.
+*/
+
+/* dma output channel interrupt handler
+   this interrupt is called from DMA2(ser2), DMA4(ser3), DMA6(ser0) or
+   DMA8(ser1) when they have finished a descriptor with the intr flag set.
+*/
+
+static void 
+tr_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct e100_serial *info;
+	unsigned long ireg;
+	int i;
+	
+#ifdef CONFIG_SVINTO_SIM
+	/* No receive in the simulator.  Will probably be when the rest of
+	 * the serial interface works, and this piece will just be removed.
+	 */
+	{
+		const char *s = "What? tr_interrupt in simulator??\n";
+		SIMCOUT(s,strlen(s));
+	}
+	return;
+#endif
+	
+	/* find out the line that caused this irq and get it from rs_table */
+	
+	ireg = *R_IRQ_MASK2_RD;  /* get the active irq bits for the dma channels */
+	
+	for(i = 0; i < NR_PORTS; i++) {
+		info = rs_table + i;
+		/* check for dma_descr (dont need to check for dma_eop in output dma for serial */
+		if(ireg & info->irq) {  
+			/* we can send a new dma bunch. make it so. */
+			transmit_chars(info);
+		}
+		
+		/* FIXME: here we should really check for a change in the
+		   status lines and if so call status_handle(info) */
+	}
+}
+
+/* dma input channel interrupt handler */
+
+static void 
+rec_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct e100_serial *info;
+	unsigned long ireg;
+	int i;
+
+#ifdef CONFIG_SVINTO_SIM
+	/* No receive in the simulator.  Will probably be when the rest of
+	 * the serial interface works, and this piece will just be removed.
+	 */
+	{
+		const char *s = "What? rec_interrupt in simulator??\n";
+		SIMCOUT(s,strlen(s));
+	}
+	return;
+#endif
+	
+	/* find out the line that caused this irq and get it from rs_table */
+	
+	ireg = *R_IRQ_MASK2_RD;  /* get the active irq bits for the dma channels */
+	
+	for(i = 0; i < NR_PORTS; i++) {
+		info = rs_table + i;
+		/* check for both dma_eop and dma_descr for the input dma channel */
+		if(ireg & ((info->irq << 2) | (info->irq << 3))) {
+			/* we have received something */
+			receive_chars(info);
+		}
+		
+		/* FIXME: here we should really check for a change in the
+		   status lines and if so call status_handle(info) */
+	}
+}
+
+/* dma fifo/buffer timeout handler
+   forces an end-of-packet for the dma input channel if no chars 
+   have been received for CONFIG_ETRAX100_RX_TIMEOUT_TICKS/100 s.
+   If CONFIG_ETRAX100_SERIAL_FLUSH_DMA_FAST is configured then this
+   handler is instead run at 15360 Hz.
+*/
+
+#ifndef CONFIG_ETRAX100_SERIAL_FLUSH_DMA_FAST
+static int timeout_divider = 0;
+#endif
+
+static struct timer_list flush_timer;
+
+static void 
+timed_flush_handler(void)
+{
+	struct e100_serial *info;
+	int i;
+	unsigned int magic;
+
+#ifdef CONFIG_SVINTO_SIM
+	return;
+#endif
+	
+	for(i = 0; i < NR_PORTS; i++) {
+		info = rs_table + i;
+		if(!(info->flags & ASYNC_INITIALIZED))
+			continue;
+
+		/* istatusadr (bit 6-0) hold number of bytes in fifo 
+		 * ihwswadr (bit 31-16) holds number of bytes in dma buffer
+		 * ihwswadr (bit 15-0) specifies size of dma buffer
+		 */
+
+		magic = (*info->istatusadr & 0x3f);
+		magic += ((*info->ihwswadr&0xffff ) - (*info->ihwswadr >> 16));
+
+		/* if magic is equal to fifo_magic (magic in previous
+		 * timeout_interrupt) then no new data has arrived since last
+		 * interrupt and we'll force eop to flush fifo+dma buffers
+		 */
+
+		if(magic != info->fifo_magic) {
+			info->fifo_magic = magic;
+			info->fifo_didmagic = 0;
+		} else {
+			/* hit the timeout, force an EOP for the input
+			 * dma channel if we haven't already
+			 */
+			if(!info->fifo_didmagic && magic) {
+				info->fifo_didmagic = 1;
+				info->fifo_magic = 0;
+				*R_SET_EOP = 1U << info->iseteop;
+			}
+		}
+	}
+
+	/* restart flush timer */
+
+	mod_timer(&flush_timer, jiffies + MAX_FLUSH_TIME);
+}
+
+
+#ifdef SERIAL_HANDLE_EARLY_ERRORS
+
+/* If there is an error (ie break) when the DMA is running and
+ * there are no bytes in the fifo the DMA is stopped and we get no
+ * eop interrupt. Thus we have to monitor the first bytes on a DMA
+ * transfer, and if it is without error we can turn the serial
+ * interrupts off.
+ */
+
+static void 
+ser_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct e100_serial *info;
+	int i;
+	unsigned char rstat;
+
+	for(i = 0; i < NR_PORTS; i++) {
+
+		info = rs_table + i;
+		rstat = info->port[REG_STATUS];
+		
+		if(*R_IRQ_MASK1_RD & (1U << (8+2*info->line))) { /* This line caused the irq */
+#ifdef SERIAL_DEBUG_INTR
+			printk("Interrupt from serport %d\n", i);
+#endif
+			if(rstat & 0x0e) {
+				/* FIXME: This is weird, but if this delay is
+				 * not present then irmaflash does not work...
+				 */
+				udelay(2300);
+
+				/* if we got an error, we must reset it by
+				 * reading the data_in field
+				 */
+				(void)info->port[REG_DATA];
+				
+				PROCSTAT(early_errors_cnt[info->line]++);
+
+				/* restart the DMA */
+				*info->icmdadr = 3;
+			} 
+			else { /* it was a valid byte, now let the dma do the rest */
+#ifdef SERIAL_DEBUG_INTR
+				printk("** OK, disabling ser_interupts\n");
+#endif
+				e100_disable_serial_data_irq(info);
+			}
+		}
+	}
+}
+#endif
+
+/*
+ * -------------------------------------------------------------------
+ * Here ends the serial interrupt routines.
+ * -------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used to handle the "bottom half" processing for the
+ * serial driver, known also the "software interrupt" processing.
+ * This processing is done at the kernel interrupt level, after the
+ * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
+ * is where time-consuming activities which can not be done in the
+ * interrupt driver proper are done; the interrupt driver schedules
+ * them using rs_sched_event(), and they get done here.
+ */
+static void 
+do_serial_bh(void)
+{
+	run_task_queue(&tq_serial);
+}
+
+static void 
+do_softint(void *private_)
+{
+	struct e100_serial	*info = (struct e100_serial *) private_;
+	struct tty_struct	*tty;
+	
+	tty = info->tty;
+	if (!tty)
+		return;
+	
+	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+		    tty->ldisc.write_wakeup)
+			(tty->ldisc.write_wakeup)(tty);
+		wake_up_interruptible(&tty->write_wait);
+	}
+}
+
+/*
+ * This routine is called from the scheduler tqueue when the interrupt
+ * routine has signalled that a hangup has occurred.  The path of
+ * hangup processing is:
+ *
+ * 	serial interrupt routine -> (scheduler tqueue) ->
+ * 	do_serial_hangup() -> tty->hangup() -> rs_hangup()
+ * 
+ */
+static void 
+do_serial_hangup(void *private_)
+{
+	struct e100_serial	*info = (struct e100_serial *) private_;
+	struct tty_struct	*tty;
+	
+	tty = info->tty;
+	if (!tty)
+		return;
+	
+	tty_hangup(tty);
+}
+
+static int 
+startup(struct e100_serial * info)
+{
+	unsigned long flags;
+	unsigned long page;
+
+	page = get_zeroed_page(GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+
+	save_flags(flags); cli();
+
+	/* if it was already initialized, skip this */
+	
+	if (info->flags & ASYNC_INITIALIZED) {
+		free_page(page);
+		restore_flags(flags);
+		return -EBUSY;
+	}
+	
+	if (info->xmit.buf)
+		free_page(page);
+	else
+		info->xmit.buf = (unsigned char *) page;
+		
+#ifdef SERIAL_DEBUG_OPEN
+	printk("starting up ttyS%d (xmit_buf 0x%x)...\n", info->line, info->xmit_buf);
+#endif
+
+	if(info->tty) {
+
+		/* clear the tty flip flag buffer since we will not
+		 * be using it (we only use the first byte..)
+		 */
+
+		memset(info->tty->flip.flag_buf, 0, TTY_FLIPBUF_SIZE * 2);
+	}
+
+	save_flags(flags);
+	cli();
+	
+#ifdef CONFIG_SVINTO_SIM
+	/* Bits and pieces collected from below.  Better to have them
+	   in one ifdef:ed clause than to mix in a lot of ifdefs,
+	   right? */
+	if (info->tty)
+		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+	info->xmit.head = info->xmit.tail = 0;
+	
+	/* No real action in the simulator, but may set info important
+	   to ioctl. */
+	change_speed(info);
+#else
+
+	/*
+	 * Clear the FIFO buffers and disable them
+	 * (they will be reenabled in change_speed())
+	 */
+	
+	/*
+	 * Reset the DMA channels and make sure their interrupts are cleared
+	 */
+	
+	*info->icmdadr = 4; /* reset command */
+	*info->ocmdadr = 4; /* reset command */
+	
+	while((*info->icmdadr & 7) == 4); /* wait until reset cycle is complete */
+	while((*info->ocmdadr & 7) == 4);
+	
+	*info->iclrintradr = 3; /* make sure the irqs are cleared */
+	*info->oclrintradr = 3;
+	
+	if (info->tty)
+		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+
+        info->xmit.head = info->xmit.tail = 0;
+	
+	/*
+	 * and set the speed and other flags of the serial port
+	 * this will start the rx/tx as well
+	 */
+#ifdef SERIAL_HANDLE_EARLY_ERRORS
+	e100_enable_serial_data_irq(info);
+#endif	
+	change_speed(info);
+
+	/* dummy read to reset any serial errors */
+
+	(void)info->port[REG_DATA];
+
+	/* enable the interrupts */
+
+	e100_enable_txdma_irq(info);
+	e100_enable_rxdma_irq(info);
+
+	info->tr_running = 0;  /* to be sure we dont lock up the transmitter */
+
+	/* setup the dma input descriptor and start dma */
+	
+	start_receive(info);
+	
+	/* for safety, make sure the descriptors last result is 0 bytes written */
+	
+	info->tr_descr.sw_len = 0;
+	info->tr_descr.hw_len = 0;
+	info->tr_descr.status = 0;
+
+	/* enable RTS/DTR last */
+
+	e100_rts(info, 1);
+	e100_dtr(info, 1);
+		
+#endif /* CONFIG_SVINTO_SIM */
+	
+	info->flags |= ASYNC_INITIALIZED;
+	
+	restore_flags(flags);
+	return 0;
+}
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void 
+shutdown(struct e100_serial * info)
+{
+	unsigned long flags;
+
+#ifndef CONFIG_SVINTO_SIM	
+	/* shut down the transmitter and receiver  */
+
+	e100_disable_rx(info);
+	info->port[REG_TR_CTRL] = (info->tx_ctrl &= ~0x40);
+
+	e100_disable_rxdma_irq(info);
+	e100_disable_txdma_irq(info);
+
+	info->tr_running = 0;
+
+	/* reset both dma channels */
+
+	*info->icmdadr = 4;
+	*info->ocmdadr = 4;
+
+#endif /* CONFIG_SVINTO_SIM */
+
+	if (!(info->flags & ASYNC_INITIALIZED))
+		return;
+	
+#ifdef SERIAL_DEBUG_OPEN
+	printk("Shutting down serial port %d (irq %d)....\n", info->line,
+	       info->irq);
+#endif
+	
+	save_flags(flags);
+	cli(); /* Disable interrupts */
+	
+	if (info->xmit.buf) {
+		unsigned long pg = (unsigned long) info->xmit.buf;
+		info->xmit.buf = 0;
+		free_page(pg);
+	}
+
+	if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
+		/* hang up DTR and RTS if HUPCL is enabled */
+		e100_dtr(info, 0);
+		e100_rts(info, 0); /* could check CRTSCTS before doing this */
+	}
+
+	if (info->tty)
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
+	
+	info->flags &= ~ASYNC_INITIALIZED;
+	restore_flags(flags);
+}
+
+
+/* change baud rate and other assorted parameters */
+
+static void 
+change_speed(struct e100_serial *info)
+{
+	unsigned int cflag;
+
+	/* first some safety checks */
+	
+	if(!info->tty || !info->tty->termios)
+		return;
+	if (!info->port)
+		return;
+	
+	cflag = info->tty->termios->c_cflag;
+	
+	/* possibly, the tx/rx should be disabled first to do this safely */
+	
+	/* change baud-rate and write it to the hardware */
+	
+	info->baud = cflag_to_baud(cflag);
+	
+#ifndef CONFIG_SVINTO_SIM
+	info->port[REG_BAUD] = cflag_to_etrax_baud(cflag);
+	/* start with default settings and then fill in changes */
+	
+	info->rx_ctrl &= ~(0x07); /* 8 bit, no/even parity */
+	info->tx_ctrl &= ~(0x37); /* 8 bit, no/even parity, 1 stop bit, no cts */
+	
+	if ((cflag & CSIZE) == CS7) {
+		/* set 7 bit mode */
+		info->tx_ctrl |= 0x01;
+		info->rx_ctrl |= 0x01;
+	}
+	
+	if (cflag & CSTOPB) {
+		/* set 2 stop bit mode */
+		info->tx_ctrl |= 0x10;
+	}	  
+	
+	if (cflag & PARENB) {
+		/* enable parity */
+		info->tx_ctrl |= 0x02;
+		info->rx_ctrl |= 0x02;
+	}
+	
+	if (cflag & PARODD) {
+		/* set odd parity */
+		info->tx_ctrl |= 0x04;
+		info->rx_ctrl |= 0x04;
+	}
+	
+	if (cflag & CRTSCTS) {
+		/* enable automatic CTS handling */
+		info->tx_ctrl |= 0x20;
+	}
+	
+	/* make sure the tx and rx are enabled */
+	
+	info->tx_ctrl |= 0x40;
+	info->rx_ctrl |= 0x40;
+
+	/* actually write the control regs to the hardware */
+	
+	info->port[REG_TR_CTRL] = info->tx_ctrl;
+	info->port[REG_REC_CTRL] = info->rx_ctrl;
+	*((unsigned long *)&info->port[REG_XOFF]) = 0;
+
+#endif /* CONFIG_SVINTO_SIM */
+}
+
+/* start transmitting chars NOW */
+
+static void 
+rs_flush_chars(struct tty_struct *tty)
+{
+	struct e100_serial *info = (struct e100_serial *)tty->driver_data;
+	unsigned long flags;
+
+	if (info->tr_running
+	    || info->xmit.head == info->xmit.tail
+	    || tty->stopped
+	    || tty->hw_stopped
+	    || !info->xmit.buf)
+		return;
+
+#ifdef SERIAL_DEBUG_FLOW
+	printk("rs_flush_chars\n");
+#endif
+	
+	/* this protection might not exactly be necessary here */
+	
+	save_flags(flags);
+	cli();
+	start_transmit(info);
+	restore_flags(flags);
+}
+
+static int 
+rs_write(struct tty_struct * tty, int from_user,
+	 const unsigned char *buf, int count)
+{
+	int	c, ret = 0;
+	struct e100_serial *info = (struct e100_serial *)tty->driver_data;
+	unsigned long flags;
+	
+	/* first some sanity checks */
+	
+	if (!tty || !info->xmit.buf || !tmp_buf)
+		return 0;
+	
+#ifdef SERIAL_DEBUG_DATA
+	if(info->line == SERIAL_DEBUG_LINE)
+		printk("rs_write (%d), status %d\n", 
+		       count, info->port[REG_STATUS]);
+#endif
+
+#ifdef CONFIG_SVINTO_SIM
+	/* Really simple.  The output is here and now. */
+	SIMCOUT(buf, count);
+	return;
+#endif
+	save_flags(flags);
+	
+	/* the cli/restore_flags pairs below are needed because the
+	 * DMA interrupt handler moves the info->xmit values. the memcpy
+	 * needs to be in the critical region unfortunately, because we
+	 * need to read xmit values, memcpy, write xmit values in one
+	 * atomic operation... this could perhaps be avoided by more clever
+	 * design.
+	 */
+	if(from_user) {
+		down(&tmp_buf_sem);
+		while (1) {
+			int c1;
+			c = CIRC_SPACE_TO_END(info->xmit.head,
+					      info->xmit.tail,
+					      SERIAL_XMIT_SIZE);
+			if (count < c)
+				c = count;
+			if (c <= 0)
+				break;
+
+			c -= copy_from_user(tmp_buf, buf, c);
+			if (!c) {
+				if (!ret)
+					ret = -EFAULT;
+				break;
+			}
+			cli();
+			c1 = CIRC_SPACE_TO_END(info->xmit.head,
+					       info->xmit.tail,
+					       SERIAL_XMIT_SIZE);
+			if (c1 < c)
+				c = c1;
+			memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c);
+			info->xmit.head = ((info->xmit.head + c) &
+					   (SERIAL_XMIT_SIZE-1));
+			restore_flags(flags);
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		up(&tmp_buf_sem);
+	} else {
+		cli();	
+		while(1) {
+			c = CIRC_SPACE_TO_END(info->xmit.head,
+					      info->xmit.tail,
+					      SERIAL_XMIT_SIZE);
+
+			if (count < c)
+				c = count;
+			if (c <= 0)
+				break;
+		
+			memcpy(info->xmit.buf + info->xmit.head, buf, c);
+			info->xmit.head = (info->xmit.head + c) &
+				(SERIAL_XMIT_SIZE-1);
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		restore_flags(flags);
+	}
+	
+	/* enable transmitter if not running, unless the tty is stopped
+	 * this does not need IRQ protection since if tr_running == 0
+	 * the IRQ's are not running anyway for this port.
+	 */
+	
+	if(info->xmit.head != info->xmit.tail
+	   && !tty->stopped &&
+	   !tty->hw_stopped &&
+	   !info->tr_running) {
+		start_transmit(info);
+	}
+ 	
+	return ret;
+}
+
+/* how much space is available in the xmit buffer? */
+
+static int 
+rs_write_room(struct tty_struct *tty)
+{
+	struct e100_serial *info = (struct e100_serial *)tty->driver_data;
+	
+	return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+/* How many chars are in the xmit buffer?
+ * This does not include any chars in the transmitter FIFO.
+ * Use wait_until_sent for waiting for FIFO drain.
+ */
+
+static int 
+rs_chars_in_buffer(struct tty_struct *tty)
+{
+	struct e100_serial *info = (struct e100_serial *)tty->driver_data;
+
+	return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+/* discard everything in the xmit buffer */
+
+static void 
+rs_flush_buffer(struct tty_struct *tty)
+{
+	struct e100_serial *info = (struct e100_serial *)tty->driver_data;
+	unsigned long flags;
+	
+	save_flags(flags);
+	cli();
+	info->xmit.head = info->xmit.tail = 0;
+	restore_flags(flags);
+
+	wake_up_interruptible(&tty->write_wait);
+
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+	    tty->ldisc.write_wakeup)
+		(tty->ldisc.write_wakeup)(tty);
+}
+
+/*
+ * This function is used to send a high-priority XON/XOFF character to
+ * the device
+ *
+ * Since we don't bother to check for info->x_char in transmit_chars yet,
+ * we don't really implement this function yet.
+ */
+static void rs_send_xchar(struct tty_struct *tty, char ch)
+{
+	struct e100_serial *info = (struct e100_serial *)tty->driver_data;
+
+	printk("serial.c:rs_send_xchar not implemented!\n");
+
+	info->x_char = ch;
+	if (ch) {
+		/* Make sure transmit interrupts are on */
+		/* TODO. */
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_throttle()
+ * 
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void 
+rs_throttle(struct tty_struct * tty)
+{
+	struct e100_serial *info = (struct e100_serial *)tty->driver_data;
+	unsigned long flags;
+#ifdef SERIAL_DEBUG_THROTTLE
+	char	buf[64];
+	
+	printk("throttle %s: %d....\n", _tty_name(tty, buf),
+	       tty->ldisc.chars_in_buffer(tty));
+#endif
+	
+	if (I_IXOFF(tty))
+		info->x_char = STOP_CHAR(tty);
+	
+	/* Turn off RTS line (do this atomic) should here be an else ?? */
+	
+	save_flags(flags); 
+	cli();
+	e100_rts(info, 0);
+	restore_flags(flags);
+}
+
+static void 
+rs_unthrottle(struct tty_struct * tty)
+{
+	struct e100_serial *info = (struct e100_serial *)tty->driver_data;
+	unsigned long flags;
+#ifdef SERIAL_DEBUG_THROTTLE
+	char	buf[64];
+	
+	printk("unthrottle %s: %d....\n", _tty_name(tty, buf),
+	       tty->ldisc.chars_in_buffer(tty));
+#endif
+	
+	if (I_IXOFF(tty)) {
+		if (info->x_char)
+			info->x_char = 0;
+		else
+			info->x_char = START_CHAR(tty);
+	}
+	
+	/* Assert RTS line (do this atomic) */
+	
+	save_flags(flags); 
+	cli();
+	e100_rts(info, 1);
+	restore_flags(flags);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_ioctl() and friends
+ * ------------------------------------------------------------
+ */
+
+static int 
+get_serial_info(struct e100_serial * info,
+		struct serial_struct * retinfo)
+{
+	struct serial_struct tmp;
+	
+	/* this is all probably wrong, there are a lot of fields
+	 * here that we don't have in e100_serial and maybe we
+	 * should set them to something else than 0.
+	 */
+
+	if (!retinfo)
+		return -EFAULT;
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.type = info->type;
+	tmp.line = info->line;
+	tmp.port = (int)info->port;
+	tmp.irq = info->irq;
+	tmp.flags = info->flags;
+	tmp.close_delay = info->close_delay;
+	tmp.closing_wait = info->closing_wait;
+	if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
+		return -EFAULT;
+	return 0;
+}
+
+static int
+set_serial_info(struct e100_serial * info,
+		struct serial_struct * new_info)
+{
+	struct serial_struct new_serial;
+	struct e100_serial old_info;
+	int 			retval = 0;
+
+	if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
+		return -EFAULT;
+
+	old_info = *info;
+	
+	if(!capable(CAP_SYS_ADMIN)) {
+		if((new_serial.type != info->type) ||
+		   (new_serial.close_delay != info->close_delay) ||
+		   ((new_serial.flags & ~ASYNC_USR_MASK) !=
+		    (info->flags & ~ASYNC_USR_MASK)))
+			return -EPERM;
+		info->flags = ((info->flags & ~ASYNC_USR_MASK) |
+			       (new_serial.flags & ASYNC_USR_MASK));
+		goto check_and_exit;
+	}
+	
+	if (info->count > 1)
+		return -EBUSY;
+	
+	/*
+	 * OK, past this point, all the error checking has been done.
+	 * At this point, we start making changes.....
+	 */
+	
+	info->flags = ((info->flags & ~ASYNC_FLAGS) |
+		       (new_serial.flags & ASYNC_FLAGS));
+	info->type = new_serial.type;
+	info->close_delay = new_serial.close_delay;
+	info->closing_wait = new_serial.closing_wait;
+#if (LINUX_VERSION_CODE > 0x20100)
+	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+#endif
+
+ check_and_exit:
+	if(info->flags & ASYNC_INITIALIZED) {
+		change_speed(info);
+	} else
+		retval = startup(info);
+	return retval;
+}
+
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ * 	    is emptied.  On bus types like RS485, the transmitter must
+ * 	    release the bus after transmitting. This must be done when
+ * 	    the transmit shift register is empty, not be done when the
+ * 	    transmit holding register is empty.  This functionality
+ * 	    allows an RS485 driver to be written in user space. 
+ */
+static int 
+get_lsr_info(struct e100_serial * info, unsigned int *value)
+{
+	unsigned int result;
+
+#ifdef CONFIG_SVINTO_SIM
+	/* Always open. */
+	result = TIOCSER_TEMT;
+#else
+	if (*info->ostatusadr & 0x007F)  /* something in fifo */
+		result = 0;
+	else
+		result = TIOCSER_TEMT;
+#endif
+
+	if (copy_to_user(value, &result, sizeof(int)))
+		return -EFAULT;
+	return 0;
+}
+
+#ifdef SERIAL_DEBUG_IO 
+struct state_str
+{
+  int state;
+  const char *str;
+  
+};
+
+const struct state_str control_state_str[]={
+	{TIOCM_DTR, "DTR" },
+	{TIOCM_RTS, "RTS"},
+	{TIOCM_ST, "ST?" },
+	{TIOCM_SR, "SR?" },
+	{TIOCM_CTS, "CTS" },
+	{TIOCM_CD, "CD" },
+	{TIOCM_RI, "RI" },
+	{TIOCM_DSR, "DSR" },
+	{0, NULL }
+};
+
+char *get_control_state_str(int MLines, char *s)
+{
+	int i = 0;
+	s[0]='\0';
+	while (control_state_str[i].str != NULL) {
+		if (MLines & control_state_str[i].state) {
+			if (s[0] != '\0') {
+				strcat(s, ", ");
+			}
+			strcat(s, control_state_str[i].str);
+		}
+		i++;
+	}
+	return s;
+}
+#endif
+
+static int 
+get_modem_info(struct e100_serial * info, unsigned int *value)
+{
+	unsigned int result;
+	/* Polarity isn't verified */
+#if 0 /*def SERIAL_DEBUG_IO  */
+
+	printk("get_modem_info: RTS: %i DTR: %i CD: %i RI: %i DSR: %i CTS: %i\n",
+	       E100_RTS_GET(info),
+	       E100_DTR_GET(info),
+	       E100_CD_GET(info),
+	       E100_RI_GET(info),
+	       E100_DSR_GET(info),
+	       E100_CTS_GET(info));
+#endif
+	result =  
+		(!E100_RTS_GET(info) ? TIOCM_RTS : 0)
+		| (!E100_DTR_GET(info) ? TIOCM_DTR : 0)
+		| (!E100_CD_GET(info) ? TIOCM_CAR : 0)
+		| (!E100_RI_GET(info) ? TIOCM_RNG : 0)
+		| (!E100_DSR_GET(info) ? TIOCM_DSR : 0)
+		| (!E100_CTS_GET(info) ? TIOCM_CTS : 0);
+	
+#ifdef SERIAL_DEBUG_IO 
+	printk("e100ser: modem state: %i 0x%08X\n", result, result);
+	{
+		char s[100];
+		
+		get_control_state_str(result, s);
+		printk("state: %s\n", s);
+	}
+#endif  
+	if (copy_to_user(value, &result, sizeof(int)))
+		return -EFAULT;
+	return 0;
+}
+
+
+static int
+set_modem_info(struct e100_serial * info, unsigned int cmd,
+	       unsigned int *value)
+{
+	unsigned int arg;
+
+	if (copy_from_user(&arg, value, sizeof(int)))
+		return -EFAULT;
+
+	switch (cmd) {
+	case TIOCMBIS: 
+		if (arg & TIOCM_RTS) {
+			e100_rts(info, 1);
+		}
+		if (arg & TIOCM_DTR) {
+			e100_dtr(info, 1);
+		}
+		/* Handle FEMALE behaviour */
+		if (arg & TIOCM_RI) {
+			e100_ri_out(info, 1);
+		}
+		if (arg & TIOCM_CD) {
+			e100_cd_out(info, 1);
+		}
+		break;
+	case TIOCMBIC:
+		if (arg & TIOCM_RTS) {
+			e100_rts(info, 0);
+		}
+		if (arg & TIOCM_DTR) {
+			e100_dtr(info, 0);
+		}
+		/* Handle FEMALE behaviour */
+		if (arg & TIOCM_RI) {
+			e100_ri_out(info, 0);
+		}
+		if (arg & TIOCM_CD) {
+			e100_cd_out(info, 0);
+		}
+		break;
+	case TIOCMSET:
+		e100_rts(info, arg & TIOCM_RTS);
+		e100_dtr(info, arg & TIOCM_DTR);
+		/* Handle FEMALE behaviour */
+		e100_ri_out(info, arg & TIOCM_RI);
+		e100_cd_out(info, arg & TIOCM_CD);
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/*
+ * This routine sends a break character out the serial port.
+ */
+#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
+static void 
+send_break(struct e100_serial * info, int duration)
+{
+	unsigned long flags;	
+
+	if (!info->port)
+		return;
+
+	current->state = TASK_INTERRUPTIBLE;
+	current->timeout = jiffies + duration;
+
+	save_flags(flags);
+	cli();
+
+	/* Go to manual mode and set the txd pin to 0 */
+
+	info->tx_ctrl &= 0x3F; /* Clear bit 7 (txd) and 6 (tr_enable) */
+	info->port[REG_TR_CTRL] = info->tx_ctrl;
+
+	/* wait for "duration" jiffies */
+
+	schedule();
+
+	info->tx_ctrl |= (0x80 | 0x40); /* Set bit 7 (txd) and 6 (tr_enable) */
+	info->port[REG_TR_CTRL] = info->tx_ctrl;
+
+	/* the DMA gets awfully confused if we toggle the tranceiver like this 
+	 * so we need to reset it 
+	 */
+	*info->ocmdadr = 4;
+
+	restore_flags(flags);
+}
+#else
+static void 
+rs_break(struct tty_struct *tty, int break_state)
+{
+	struct e100_serial * info = (struct e100_serial *)tty->driver_data;
+	unsigned long flags;
+
+	if (!info->port)
+		return;
+	
+	save_flags(flags);
+	cli();
+	if (break_state == -1) {
+		/* Go to manual mode and set the txd pin to 0 */
+		info->tx_ctrl &= 0x3F; /* Clear bit 7 (txd) and 6 (tr_enable) */
+	} else {
+		info->tx_ctrl |= (0x80 | 0x40); /* Set bit 7 (txd) and 6 (tr_enable) */
+	}
+	info->port[REG_TR_CTRL] = info->tx_ctrl;
+	restore_flags(flags);
+}
+#endif
+
+static int 
+rs_ioctl(struct tty_struct *tty, struct file * file,
+	 unsigned int cmd, unsigned long arg)
+{
+	int error;
+	struct e100_serial * info = (struct e100_serial *)tty->driver_data;
+	int retval;
+	
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD)  &&
+	    (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+			return -EIO;
+	}
+	
+	switch (cmd) {
+#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
+	        case TCSBRK:	/* SVID version: non-zero arg --> no break */
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			if (signal_pending(current))
+				return -EINTR;
+			if (!arg) {
+				send_break(info, HZ/4);	/* 1/4 second */
+				if (signal_pending(current))
+					return -EINTR;
+			}
+			return 0;
+		case TCSBRKP:	/* support for POSIX tcsendbreak() */
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			if (signal_pending(current))
+				return -EINTR;
+			send_break(info, arg ? arg*(HZ/10) : HZ/4);
+			if (signal_pending(current))
+				return -EINTR;
+			return 0;
+		case TIOCGSOFTCAR:
+			error = verify_area(VERIFY_WRITE, (void *) arg,sizeof(long));
+			if (error)
+				return error;
+			put_fs_long(C_CLOCAL(tty) ? 1 : 0,
+				    (unsigned long *) arg);
+			return 0;
+		case TIOCSSOFTCAR:
+			arg = get_fs_long((unsigned long *) arg);
+			tty->termios->c_cflag =
+				((tty->termios->c_cflag & ~CLOCAL) |
+				 (arg ? CLOCAL : 0));
+			return 0;
+#endif
+		case TIOCMGET:
+			return get_modem_info(info, (unsigned int *) arg);
+		case TIOCMBIS:
+		case TIOCMBIC:
+		case TIOCMSET:
+			return set_modem_info(info, cmd, (unsigned int *) arg);
+		case TIOCGSERIAL:
+			return get_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSSERIAL:
+			return set_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSERGETLSR: /* Get line status register */
+			return get_lsr_info(info, (unsigned int *) arg);
+
+		case TIOCSERGSTRUCT:
+			if (copy_to_user((struct e100_serial *) arg,
+					 info, sizeof(struct e100_serial)))
+				return -EFAULT;
+			return 0;
+
+#if defined(CONFIG_RS485)
+		case TIOCSERSETRS485:
+			error = verify_area(VERIFY_WRITE, (void *) arg,
+					sizeof(struct rs485_control));
+			
+			if (error)
+				return error;
+			
+			return e100_enable_rs485(tty, (struct rs485_control *) arg);
+
+		case TIOCSERWRRS485:
+			error = verify_area(VERIFY_WRITE, (void *) arg,
+					sizeof(struct rs485_write));
+			
+			if (error)
+				return error;
+			
+			return e100_write_rs485(tty, (struct rs485_write *) arg);
+#endif
+			
+		default:
+			return -ENOIOCTLCMD;
+	}
+	return 0;
+}
+
+static void 
+rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+	struct e100_serial *info = (struct e100_serial *)tty->driver_data;
+
+	if (tty->termios->c_cflag == old_termios->c_cflag)
+		return;
+
+	change_speed(info);
+
+	if ((old_termios->c_cflag & CRTSCTS) &&
+	    !(tty->termios->c_cflag & CRTSCTS)) {
+		tty->hw_stopped = 0;
+		rs_start(tty);
+	}
+	
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_close()
+ * 
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * S structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void 
+rs_close(struct tty_struct *tty, struct file * filp)
+{
+	struct e100_serial * info = (struct e100_serial *)tty->driver_data;
+	unsigned long flags;
+
+	if (!info)
+		return;
+  
+	/* interrupts are disabled for this entire function */
+  
+	save_flags(flags); 
+	cli();
+  
+	if (tty_hung_up_p(filp)) {
+		restore_flags(flags);
+		return;
+	}
+  
+#ifdef SERIAL_DEBUG_OPEN
+	printk("[%d] rs_close ttyS%d, count = %d\n", current->pid, 
+	       info->line, info->count);
+#endif
+	if ((tty->count == 1) && (info->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  Info->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk("rs_close: bad serial port count; tty->count is 1, "
+		       "info->count is %d\n", info->count);
+		info->count = 1;
+	}
+	if (--info->count < 0) {
+		printk("rs_close: bad serial port count for ttyS%d: %d\n",
+		       info->line, info->count);
+		info->count = 0;
+	}
+	if (info->count) {
+		restore_flags(flags);
+		return;
+	}
+	info->flags |= ASYNC_CLOSING;
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (info->flags & ASYNC_NORMAL_ACTIVE)
+		info->normal_termios = *tty->termios;
+	if (info->flags & ASYNC_CALLOUT_ACTIVE)
+		info->callout_termios = *tty->termios;
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, info->closing_wait);
+	/*
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the serial receiver and the DMA receive interrupt.
+	 */
+#ifdef SERIAL_HANDLE_EARLY_ERRORS 
+	e100_disable_serial_data_irq(info);
+#endif
+
+#ifndef CONFIG_SVINTO_SIM
+	e100_disable_rx(info);
+	e100_disable_rxdma_irq(info);
+
+	if (info->flags & ASYNC_INITIALIZED) {
+		/*
+		 * Before we drop DTR, make sure the UART transmitter
+		 * has completely drained; this is especially
+		 * important as we have a transmit FIFO!
+		 */
+		rs_wait_until_sent(tty, HZ);
+	}
+#endif
+
+	shutdown(info);
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = 0;
+	if (info->blocked_open) {
+		if (info->close_delay) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(info->close_delay);
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
+			 ASYNC_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+	restore_flags(flags);
+
+	/* port closed */
+
+#if defined(CONFIG_RS485)
+	if (info->rs485.enabled) {
+		info->rs485.enabled = 0;
+#if defined(CONFIG_RS485_ON_PA)
+		*R_PORT_PA_DATA = port_pa_data_shadow &= ~(1 << rs485_pa_bit);
+#endif
+	}
+#endif
+}
+
+/*
+ * rs_wait_until_sent() --- wait until the transmitter is empty
+ */
+static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+	unsigned long orig_jiffies;
+	struct e100_serial *info = (struct e100_serial *)tty->driver_data;
+
+	/*
+	 * Check R_DMA_CHx_STATUS bit 0-6=number of available bytes in FIFO
+	 * R_DMA_CHx_HWSW bit 31-16=nbr of bytes left in DMA buffer (0=64k)
+	 */
+	orig_jiffies = jiffies;
+	while(info->xmit.head != info->xmit.tail || /* More in send queue */
+	      (*info->ostatusadr & 0x007f)) { /* more in FIFO */
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(1);
+		if (signal_pending(current))
+			break;
+		if (timeout && time_after(jiffies, orig_jiffies + timeout))
+			break;
+	}
+	set_current_state(TASK_RUNNING);
+}
+
+/*
+ * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+void 
+rs_hangup(struct tty_struct *tty)
+{
+	struct e100_serial * info = (struct e100_serial *)tty->driver_data;
+	
+	rs_flush_buffer(tty);
+	shutdown(info);
+	info->event = 0;
+	info->count = 0;
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->tty = 0;
+	wake_up_interruptible(&info->open_wait);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_open() and friends
+ * ------------------------------------------------------------
+ */
+static int 
+block_til_ready(struct tty_struct *tty, struct file * filp,
+		struct e100_serial *info)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	unsigned long   flags;
+	int		retval;
+	int		do_clocal = 0, extra_count = 0;
+	
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (tty_hung_up_p(filp) ||
+	    (info->flags & ASYNC_CLOSING)) {
+		if (info->flags & ASYNC_CLOSING)
+			interruptible_sleep_on(&info->close_wait);
+#ifdef SERIAL_DO_RESTART
+		if (info->flags & ASYNC_HUP_NOTIFY)
+			return -EAGAIN;
+		else
+			return -ERESTARTSYS;
+#else
+		return -EAGAIN;
+#endif
+	}
+  
+	/*
+	 * If this is a callout device, then just make sure the normal
+	 * device isn't being used.
+	 */
+	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
+		if (info->flags & ASYNC_NORMAL_ACTIVE)
+			return -EBUSY;
+		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
+		    (info->session != current->session))
+			return -EBUSY;
+		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
+		    (info->pgrp != current->pgrp))
+			return -EBUSY;
+		info->flags |= ASYNC_CALLOUT_ACTIVE;
+		return 0;
+	}
+	
+	/*
+	 * If non-blocking mode is set, or the port is not enabled,
+	 * then make the check up front and then exit.
+	 */
+	if ((filp->f_flags & O_NONBLOCK) ||
+	    (tty->flags & (1 << TTY_IO_ERROR))) {
+		if (info->flags & ASYNC_CALLOUT_ACTIVE)
+			return -EBUSY;
+		info->flags |= ASYNC_NORMAL_ACTIVE;
+		return 0;
+	}
+	
+	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
+		if (info->normal_termios.c_cflag & CLOCAL)
+			do_clocal = 1;
+	} else {
+		if (tty->termios->c_cflag & CLOCAL)
+			do_clocal = 1;
+	}
+	
+	/*
+	 * Block waiting for the carrier detect and the line to become
+	 * free (i.e., not in use by the callout).  While we are in
+	 * this loop, info->count is dropped by one, so that
+	 * rs_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	retval = 0;
+	add_wait_queue(&info->open_wait, &wait);
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready before block: ttyS%d, count = %d\n",
+	       info->line, info->count);
+#endif
+	save_flags(flags); 
+	cli();
+	if (!tty_hung_up_p(filp)) {
+		extra_count++;
+		info->count--;
+	}
+	restore_flags(flags);
+	info->blocked_open++;
+	while (1) {
+		save_flags(flags);
+		cli();
+		if (!(info->flags & ASYNC_CALLOUT_ACTIVE)) {
+			/* assert RTS and DTR */
+			e100_rts(info, 1);
+			e100_dtr(info, 1);
+		}
+		restore_flags(flags);
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (tty_hung_up_p(filp) ||
+		    !(info->flags & ASYNC_INITIALIZED)) {
+#ifdef SERIAL_DO_RESTART
+			if (info->flags & ASYNC_HUP_NOTIFY)
+				retval = -EAGAIN;
+			else
+				retval = -ERESTARTSYS;	
+#else
+			retval = -EAGAIN;
+#endif
+			break;
+		}
+		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    !(info->flags & ASYNC_CLOSING) && do_clocal)
+			/* && (do_clocal || DCD_IS_ASSERTED) */
+			break;
+		if (signal_pending(current)) {
+			retval = -ERESTARTSYS;
+			break;
+		}
+#ifdef SERIAL_DEBUG_OPEN
+		printk("block_til_ready blocking: ttyS%d, count = %d\n",
+		       info->line, info->count);
+#endif
+		schedule();
+	}
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(&info->open_wait, &wait);
+	if (extra_count)
+		info->count++;
+	info->blocked_open--;
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready after blocking: ttyS%d, count = %d\n",
+	       info->line, info->count);
+#endif
+	if (retval)
+		return retval;
+	info->flags |= ASYNC_NORMAL_ACTIVE;
+	return 0;
+}	
+
+/*
+ * This routine is called whenever a serial port is opened. 
+ * It performs the serial-specific initialization for the tty structure.
+ */
+static int 
+rs_open(struct tty_struct *tty, struct file * filp)
+{
+	struct e100_serial	*info;
+	int 			retval, line;
+	unsigned long           page;
+
+	/* find which port we want to open */
+
+	line = MINOR(tty->device) - tty->driver.minor_start;
+  
+	if (line < 0 || line >= NR_PORTS)
+		return -ENODEV;
+
+	/* dont allow opening ports that are not enabled in the HW config */
+
+#ifndef CONFIG_ETRAX100_SERIAL_PORT2
+	if (line == 2)
+		return -ENODEV;
+#endif
+#ifndef CONFIG_ETRAX100_SERIAL_PORT3
+	if (line == 3)
+		return -ENODEV;
+#endif
+
+	/* find the corresponding e100_serial struct in the table */
+
+	info = rs_table + line;
+  
+#ifdef SERIAL_DEBUG_OPEN
+	printk("[%d] rs_open %s%d, count = %d\n", current->pid,
+	       tty->driver.name, info->line,
+	       info->count);
+#endif
+
+	info->count++;
+	tty->driver_data = info;
+	info->tty = tty;
+
+#if (LINUX_VERSION_CODE > 0x20100)
+	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+#endif
+
+	if (!tmp_buf) {
+		page = get_zeroed_page(GFP_KERNEL);
+		if (!page) {
+			return -ENOMEM;
+		}
+		if (tmp_buf)
+			free_page(page);
+		else
+			tmp_buf = (unsigned char *) page;
+	}
+
+	/*
+	 * If the port is the middle of closing, bail out now
+	 */
+	if (tty_hung_up_p(filp) ||
+	    (info->flags & ASYNC_CLOSING)) {
+		if (info->flags & ASYNC_CLOSING)
+			interruptible_sleep_on(&info->close_wait);
+#ifdef SERIAL_DO_RESTART
+		return ((info->flags & ASYNC_HUP_NOTIFY) ?
+			-EAGAIN : -ERESTARTSYS);
+#else
+		return -EAGAIN;
+#endif
+	}
+
+	/*
+	 * Start up the serial port
+	 */
+
+	retval = startup(info);
+	if (retval)
+		return retval;
+  
+	retval = block_til_ready(tty, filp, info);
+	if (retval) {
+#ifdef SERIAL_DEBUG_OPEN
+		printk("rs_open returning after block_til_ready with %d\n",
+		       retval);
+#endif
+		return retval;
+	}
+
+	if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = info->normal_termios;
+		else 
+			*tty->termios = info->callout_termios;
+		change_speed(info);
+	}
+
+	info->session = current->session;
+	info->pgrp = current->pgrp;
+  
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open ttyS%d successful...\n", info->line);
+#endif
+	return 0;
+}
+
+/*
+ * /proc fs routines....
+ */
+
+static inline int line_info(char *buf, struct e100_serial *info)
+{
+	char	stat_buf[30], control, status;
+	int	ret;
+	unsigned long flags;
+
+	ret = sprintf(buf, "%d: uart:E100 port:%lX irq:%d",
+		      info->line, info->port, info->irq);
+
+	if (!info->port || (info->type == PORT_UNKNOWN)) {
+		ret += sprintf(buf+ret, "\n");
+		return ret;
+	}
+
+	stat_buf[0] = 0;
+	stat_buf[1] = 0;
+	if (E100_RTS_GET(info))
+		strcat(stat_buf, "|RTS");
+	if (E100_CTS_GET(info))
+		strcat(stat_buf, "|CTS");
+	if (E100_DTR_GET(info))
+		strcat(stat_buf, "|DTR");
+	if (E100_DSR_GET(info))
+		strcat(stat_buf, "|DSR");
+	if (E100_CD_GET(info))
+		strcat(stat_buf, "|CD");
+	if (E100_RI_GET(info))
+		strcat(stat_buf, "|RI");
+
+	ret += sprintf(buf+ret, " baud:%d", info->baud);
+
+	ret += sprintf(buf+ret, " tx:%d rx:%d",
+		      info->icount.tx, info->icount.rx);
+
+	if (info->icount.frame)
+		ret += sprintf(buf+ret, " fe:%d", info->icount.frame);
+	
+	if (info->icount.parity)
+		ret += sprintf(buf+ret, " pe:%d", info->icount.parity);
+	
+	if (info->icount.brk)
+		ret += sprintf(buf+ret, " brk:%d", info->icount.brk);	
+
+	if (info->icount.overrun)
+		ret += sprintf(buf+ret, " oe:%d", info->icount.overrun);
+
+	/*
+	 * Last thing is the RS-232 status lines
+	 */
+	ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+	return ret;
+}
+
+int rs_read_proc(char *page, char **start, off_t off, int count,
+		 int *eof, void *data)
+{
+	int i, len = 0, l;
+	off_t	begin = 0;
+
+	len += sprintf(page, "serinfo:1.0 driver:%s\n",
+		       serial_version);
+	for (i = 0; i < NR_PORTS && len < 4000; i++) {
+		l = line_info(page + len, &rs_table[i]);
+		len += l;
+		if (len+begin > off+count)
+			goto done;
+		if (len+begin < off) {
+			begin += len;
+			len = 0;
+		}
+	}
+	*eof = 1;
+done:
+	if (off >= len+begin)
+		return 0;
+	*start = page + (off-begin);
+	return ((count < begin+len-off) ? count : begin+len-off);
+}
+
+/* Finally, routines used to initialize the serial driver. */
+
+static void 
+show_serial_version(void)
+{
+	printk("ETRAX 100LX serial-driver %s, (c) 2000 Axis Communications AB\r\n",
+	       serial_version);
+}
+
+/* rs_init inits the driver at boot (using the module_init chain) */
+
+static int __init
+rs_init(void)
+{
+	int i;
+	struct e100_serial *info;
+
+	show_serial_version();
+        
+	init_bh(SERIAL_BH, do_serial_bh);
+
+	/* Setup the timed flush handler system */
+
+	init_timer(&flush_timer);
+	flush_timer.function = timed_flush_handler;
+	mod_timer(&flush_timer, jiffies + MAX_FLUSH_TIME);
+
+	/* Initialize the tty_driver structure */
+  
+	memset(&serial_driver, 0, sizeof(struct tty_driver));
+	serial_driver.magic = TTY_DRIVER_MAGIC;
+#if (LINUX_VERSION_CODE > 0x20100)
+	serial_driver.driver_name = "serial";
+#endif
+	serial_driver.name = "ttyS";
+	serial_driver.major = TTY_MAJOR;
+	serial_driver.minor_start = 64;
+	serial_driver.num = NR_PORTS;       /* etrax100 has 4 serial ports */
+	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	serial_driver.subtype = SERIAL_TYPE_NORMAL;
+	serial_driver.init_termios = tty_std_termios;
+	serial_driver.init_termios.c_cflag =
+		B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */
+	serial_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+	serial_driver.refcount = &serial_refcount;
+	serial_driver.table = serial_table;
+	serial_driver.termios = serial_termios;
+	serial_driver.termios_locked = serial_termios_locked;
+  
+	serial_driver.open = rs_open;
+	serial_driver.close = rs_close;
+	serial_driver.write = rs_write;
+	/* should we have an rs_put_char as well here ? */
+	serial_driver.flush_chars = rs_flush_chars;
+	serial_driver.write_room = rs_write_room;
+	serial_driver.chars_in_buffer = rs_chars_in_buffer;
+	serial_driver.flush_buffer = rs_flush_buffer;
+	serial_driver.ioctl = rs_ioctl;
+	serial_driver.throttle = rs_throttle;
+	serial_driver.unthrottle = rs_unthrottle;
+	serial_driver.set_termios = rs_set_termios;
+	serial_driver.stop = rs_stop;
+	serial_driver.start = rs_start;
+	serial_driver.hangup = rs_hangup;
+#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */
+	serial_driver.break_ctl = rs_break;
+#endif
+#if (LINUX_VERSION_CODE >= 131343)
+	serial_driver.send_xchar = rs_send_xchar;
+	serial_driver.wait_until_sent = rs_wait_until_sent;
+	serial_driver.read_proc = rs_read_proc;
+#endif
+	  
+	/*
+	 * The callout device is just like normal device except for
+	 * major number and the subtype code.
+	 */
+	callout_driver = serial_driver;
+	callout_driver.name = "cua";
+	callout_driver.major = TTYAUX_MAJOR;
+	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+#if (LINUX_VERSION_CODE >= 131343)
+	callout_driver.read_proc = 0;
+	callout_driver.proc_entry = 0;
+#endif
+  
+	if (tty_register_driver(&serial_driver))
+		panic("Couldn't register serial driver\n");
+	if (tty_register_driver(&callout_driver))
+		panic("Couldn't register callout driver\n");
+  
+	/* do some initializing for the separate ports */
+  
+	for (i = 0, info = rs_table; i < NR_PORTS; i++,info++) {
+		info->line = i;
+		info->tty = 0;
+		info->type = PORT_ETRAX100;
+		info->tr_running = 0;
+		info->fifo_magic = 0;
+		info->fifo_didmagic = 0;
+		info->flags = 0;
+		info->close_delay = 5*HZ/10;
+		info->closing_wait = 30*HZ;
+		info->x_char = 0;
+		info->event = 0;
+		info->count = 0;
+		info->blocked_open = 0;
+		info->tqueue.routine = do_softint;
+		info->tqueue.data = info;
+		info->callout_termios = callout_driver.init_termios;
+		info->normal_termios = serial_driver.init_termios;
+		init_waitqueue_head(&info->open_wait);
+		init_waitqueue_head(&info->close_wait);
+		info->xmit.buf = 0;
+		info->xmit.tail = info->xmit.head = 0;
+
+		printk(KERN_INFO "%s%d at 0x%x is a builtin UART with DMA\n",
+		       serial_driver.name, info->line, (unsigned int)info->port);
+	}
+
+#ifndef CONFIG_SVINTO_SIM
+	/* Not needed in simulator.  May only complicate stuff. */
+	/* hook the irq's for DMA channel 6 and 7, serial output and input, and some more... */
+	if(request_irq(22, tr_interrupt, SA_INTERRUPT, "serial 0 dma tr", NULL))
+		panic("irq22");
+	if(request_irq(23, rec_interrupt, SA_INTERRUPT, "serial 0 dma rec", NULL))
+		panic("irq23");
+#ifdef SERIAL_HANDLE_EARLY_ERRORS
+	if(request_irq(8, ser_interrupt, SA_INTERRUPT, "serial ", NULL))
+		panic("irq8");
+#endif
+	if(request_irq(24, tr_interrupt, SA_INTERRUPT, "serial 1 dma tr", NULL))
+		panic("irq24");
+	if(request_irq(25, rec_interrupt, SA_INTERRUPT, "serial 1 dma rec", NULL))
+		panic("irq25");
+#ifdef CONFIG_ETRAX100_SERIAL_PORT2
+	/* DMA Shared with par0 (and SCSI0 and ATA) */
+	if(request_irq(18, tr_interrupt, SA_SHIRQ, "serial 2 dma tr", NULL))
+		panic("irq18");
+	if(request_irq(19, rec_interrupt, SA_SHIRQ, "serial 2 dma rec", NULL))
+		panic("irq19");
+#endif
+#ifdef CONFIG_ETRAX100_SERIAL_PORT3
+	/* DMA Shared with par1 (and SCSI1 and Extern DMA 0) */
+	if(request_irq(20, tr_interrupt, SA_SHIRQ, "serial 3 dma tr", NULL))
+		panic("irq20");
+	if(request_irq(21, rec_interrupt, SA_SHIRQ, "serial 3 dma rec", NULL))
+		panic("irq21");
+#endif
+#ifdef CONFIG_ETRAX100_SERIAL_FLUSH_DMA_FAST
+	/* TODO: a timeout_interrupt needs to be written that calls timeout_handler */
+	if(request_irq(TIMER1_IRQ_NBR, timeout_interrupt, SA_SHIRQ,
+		       "fast serial dma timeout", NULL)) {
+		printk("err: timer1 irq\n");
+	}
+#endif
+#endif /* CONFIG_SVINTO_SIM */
+
+	return 0;
+}
+
+/* this makes sure that rs_init is called during kernel boot */
+
+module_init(rs_init);
+
+/*
+ * register_serial and unregister_serial allows for serial ports to be
+ * configured at run-time, to support PCMCIA modems.
+ */
+int 
+register_serial(struct serial_struct *req)
+{
+	return -1;
+}
+
+void unregister_serial(int line)
+{
+}
diff -urN linux-2.4.2-pre1/arch/cris/drivers/serial.h linux/arch/cris/drivers/serial.h
--- linux-2.4.2-pre1/arch/cris/drivers/serial.h	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/serial.h	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,106 @@
+/*
+ * serial.h: Arch-dep definitions for the Etrax100 serial driver.
+ *
+ * Copyright (C) 1998, 1999, 2000 Axis Communications AB
+ */
+
+#ifndef _ETRAX100_SERIAL_H
+#define _ETRAX100_SERIAL_H
+
+#include <linux/config.h>
+#include <linux/circ_buf.h>
+#include <asm/termios.h>
+
+/* Software state per channel */
+
+#ifdef __KERNEL__
+/*
+ * This is our internal structure for each serial port's state.
+ * 
+ * Many fields are paralleled by the structure used by the serial_struct
+ * structure.
+ *
+ * For definitions of the flags field, see tty.h
+ */
+
+struct e100_serial {
+	int                   baud;
+	volatile unsigned char *	port; /* R_SERIALx_CTRL */
+	unsigned long	        irq;  /* bitnr in R_IRQ_MASK2 for dmaX_descr */
+
+	volatile char *oclrintradr; /* adr to R_DMA_CHx_CLR_INTR, output */
+	volatile unsigned long *ofirstadr;   /* adr to R_DMA_CHx_FIRST, output */
+	volatile char *ocmdadr;     /* adr to R_DMA_CHx_CMD, output */
+	const volatile unsigned short *ostatusadr;  /* adr to R_DMA_CHx_STATUS, output */
+	volatile unsigned long  *ohwswadr;    /* adr to R_DMA_CHx_HWSW, output */
+
+	volatile char *iclrintradr; /* adr to R_DMA_CHx_CLR_INTR, input */
+	volatile unsigned long *ifirstadr;   /* adr to R_DMA_CHx_FIRST, input */
+	volatile char *icmdadr;     /* adr to R_DMA_CHx_CMD, input */
+	const volatile unsigned short *istatusadr;  /* adr to R_DMA_CHx_STATUS, input */
+	volatile unsigned long  *ihwswadr;    /* adr to R_DMA_CHx_HWSW, input */
+
+	int			flags; 		/* defined in tty.h */
+
+	unsigned char           rx_ctrl; /* shadow for R_SERIALx_REC_CTRL */
+	unsigned char           tx_ctrl; /* shadow for R_SERIALx_TR_CTRL */
+	unsigned char           iseteop; /* bit number for R_SET_EOP for the input dma */
+/* end of fields defined in rs_table[] in .c-file */
+	unsigned char           fifo_didmagic; /* a fifo eop has been forced */
+
+	struct etrax_dma_descr tr_descr, rec_descr;
+
+	int                     fifo_magic; /* fifo amount - bytes left in dma buffer */
+
+	volatile int            tr_running; /* 1 if output is running */
+
+	struct tty_struct 	*tty;
+	int			read_status_mask;
+	int			ignore_status_mask;
+	int			x_char;	/* xon/xoff character */
+	int			close_delay;
+	unsigned short	        closing_wait;
+	unsigned short	        closing_wait2;
+	unsigned long		event;
+	unsigned long		last_active;
+	int			line;
+	int                     type;  /* PORT_ETRAX100 */
+	int			count;	    /* # of fd on device */
+	int			blocked_open; /* # of blocked opens */
+	long			session; /* Session of opening process */
+	long			pgrp; /* pgrp of opening process */
+	struct circ_buf         xmit;
+
+	struct tq_struct	tqueue;
+	struct async_icount     icount;   /* error-statistics etc.*/
+	struct termios	        normal_termios;
+	struct termios	        callout_termios;
+#ifdef DECLARE_WAITQUEUE
+	wait_queue_head_t       open_wait;
+        wait_queue_head_t       close_wait;
+#else   
+        struct wait_queue       *open_wait;
+        struct wait_queue       *close_wait;
+#endif  
+
+#ifdef CONFIG_RS485
+	struct rs485_control    rs485;  /* RS-485 support */
+#endif
+};
+
+/* this PORT is not in the standard serial.h. it's not actually used for
+ * anything since we only have one type of async serial-port anyway in this
+ * system.
+ */
+
+#define PORT_ETRAX100 1
+
+/*
+ * Events are used to schedule things to happen at timer-interrupt
+ * time, instead of at rs interrupt time.
+ */
+#define RS_EVENT_WRITE_WAKEUP	0
+
+#endif /* __KERNEL__ */
+
+#endif /* !(_ETRAX100_SERIAL_H) */
diff -urN linux-2.4.2-pre1/arch/cris/kernel/Makefile linux/arch/cris/kernel/Makefile
--- linux-2.4.2-pre1/arch/cris/kernel/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/kernel/Makefile	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,25 @@
+# $Id: Makefile,v 1.3 2001/01/10 21:11:07 bjornw Exp $
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+.S.o:
+	$(CC) $(AFLAGS) -traditional -c $< -o $*.o
+
+all: kernel.o head.o
+
+O_TARGET := kernel.o
+obj-y   := process.o signal.o entry.o traps.o irq.o \
+           ptrace.o setup.o time.o sys_cris.o shadows.o \
+	   debugport.o semaphore.o
+
+obj-$(CONFIG_KGDB) += kgdb.o
+
+clean:
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.2-pre1/arch/cris/kernel/debugport.c linux/arch/cris/kernel/debugport.c
--- linux-2.4.2-pre1/arch/cris/kernel/debugport.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/kernel/debugport.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,242 @@
+/* Serialport functions for debugging
+ *
+ * Copyright (c) 2000 Axis Communications AB
+ *
+ * Authors:  Bjorn Wesen
+ *
+ * Exports:
+ *    console_print_etrax(char *buf)
+ *    int getDebugChar()
+ *    putDebugChar(int)
+ *    enableDebugIRQ()
+ *    init_etrax_debug()
+ *
+ * $Log: debugport.c,v $
+ * Revision 1.4  2000/10/06 12:37:26  bjornw
+ * Use physical addresses when talking to DMA
+ *
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/major.h>
+
+#include <asm/system.h>
+#include <asm/svinto.h>
+#include <asm/io.h>             /* Get SIMCOUT. */
+
+/* Which serial-port is our debug port ? */
+
+#if defined(CONFIG_DEBUG_PORT0) || defined(CONFIG_DEBUG_PORT_NULL)
+#define DEBUG_PORT_IDX 0
+#define DEBUG_OCMD R_DMA_CH6_CMD
+#define DEBUG_FIRST R_DMA_CH6_FIRST
+#define DEBUG_OCLRINT R_DMA_CH6_CLR_INTR
+#define DEBUG_STATUS R_DMA_CH6_STATUS
+#define DEBUG_READ R_SERIAL0_READ
+#define DEBUG_WRITE R_SERIAL0_TR_DATA
+#define DEBUG_TR_CTRL R_SERIAL0_TR_CTRL
+#define DEBUG_REC_CTRL R_SERIAL0_REC_CTRL
+#define DEBUG_IRQ IO_STATE(R_IRQ_MASK1_SET, ser0_data, set)
+#define DEBUG_DMA_IRQ_CLR IO_STATE(R_IRQ_MASK2_CLR, dma6_descr, clr)
+#endif
+
+#ifdef CONFIG_DEBUG_PORT1
+#define DEBUG_PORT_IDX 1
+#define DEBUG_OCMD R_DMA_CH8_CMD
+#define DEBUG_FIRST R_DMA_CH8_FIRST
+#define DEBUG_OCLRINT R_DMA_CH8_CLR_INTR
+#define DEBUG_STATUS R_DMA_CH8_STATUS
+#define DEBUG_READ R_SERIAL1_READ
+#define DEBUG_WRITE R_SERIAL1_TR_DATA
+#define DEBUG_TR_CTRL R_SERIAL1_TR_CTRL
+#define DEBUG_REC_CTRL R_SERIAL1_REC_CTRL
+#define DEBUG_IRQ IO_STATE(R_IRQ_MASK1_SET, ser1_data, set)
+#define DEBUG_DMA_IRQ_CLR IO_STATE(R_IRQ_MASK2_CLR, dma8_descr, clr)
+#endif
+
+#ifdef CONFIG_DEBUG_PORT2
+#define DEBUG_PORT_IDX 2
+#define DEBUG_OCMD R_DMA_CH2_CMD
+#define DEBUG_FIRST R_DMA_CH2_FIRST
+#define DEBUG_OCLRINT R_DMA_CH2_CLR_INTR
+#define DEBUG_STATUS R_DMA_CH2_STATUS
+#define DEBUG_READ R_SERIAL2_READ
+#define DEBUG_WRITE R_SERIAL2_TR_DATA
+#define DEBUG_TR_CTRL R_SERIAL2_TR_CTRL
+#define DEBUG_REC_CTRL R_SERIAL2_REC_CTRL
+#define DEBUG_IRQ IO_STATE(R_IRQ_MASK1_SET, ser2_data, set)
+#define DEBUG_DMA_IRQ_CLR IO_STATE(R_IRQ_MASK2_CLR, dma2_descr, clr)
+#endif
+
+#ifdef CONFIG_DEBUG_PORT3
+#define DEBUG_PORT_IDX 3
+#define DEBUG_OCMD R_DMA_CH4_CMD
+#define DEBUG_FIRST R_DMA_CH4_FIRST
+#define DEBUG_OCLRINT R_DMA_CH4_CLR_INTR
+#define DEBUG_STATUS R_DMA_CH4_STATUS
+#define DEBUG_READ R_SERIAL3_READ
+#define DEBUG_WRITE R_SERIAL3_TR_DATA
+#define DEBUG_TR_CTRL R_SERIAL3_TR_CTRL
+#define DEBUG_REC_CTRL R_SERIAL3_REC_CTRL
+#define DEBUG_IRQ IO_STATE(R_IRQ_MASK1_SET, ser3_data, set)
+#define DEBUG_DMA_IRQ_CLR IO_STATE(R_IRQ_MASK2_CLR, dma4_descr, clr)
+#endif
+
+/* Write a string of count length to the console (debug port) using DMA, polled
+ * for completion. Interrupts are disabled during the whole process. Some
+ * caution needs to be taken to not interfere with ttyS business on this port.
+ */
+
+static void 
+console_write(struct console *co, const char *buf, unsigned int len)
+{
+	static struct etrax_dma_descr descr;
+	unsigned long flags; 
+	int in_progress;
+	
+#ifdef CONFIG_DEBUG_PORT_NULL
+        /* no debug printout at all */
+        return;
+#endif
+
+#ifdef CONFIG_SVINTO_SIM
+	/* no use to simulate the serial debug output */
+	SIMCOUT(buf,len);
+	return;
+#endif
+	
+	save_flags(flags);
+	cli();
+
+#ifdef CONFIG_KGDB
+	/* kgdb needs to output debug info using the gdb protocol */
+	putDebugString(buf, len);
+	restore_flags(flags);
+	return;
+#endif
+
+	/* make sure the transmitter is enabled. 
+	 * NOTE: this overrides any setting done in ttySx, to 8N1, no auto-CTS.
+	 * in the future, move the tr/rec_ctrl shadows from etrax100ser.c to
+	 * shadows.c and use it here as well...
+	 */
+
+	*DEBUG_TR_CTRL = 0x40;
+
+	/* if the tty has some ongoing business, remember it */
+
+	in_progress = *DEBUG_OCMD & 7;
+
+	if(in_progress) {
+		/* wait until the output dma channel is ready */
+		
+		while(*DEBUG_OCMD & 7) /* nothing */ ;
+	}
+
+	descr.ctrl = d_eol;
+	descr.sw_len = len;
+	descr.buf = __pa(buf);
+
+	*DEBUG_FIRST = __pa(&descr); /* write to R_DMAx_FIRST */
+	*DEBUG_OCMD = 1;       /* dma command start -> R_DMAx_CMD */
+
+	/* wait until the output dma channel is ready again */
+
+	while(*DEBUG_OCMD & 7) /* nothing */;
+
+	/* clear pending interrupts so we don't get a surprise below */
+
+	if(in_progress)
+		*DEBUG_OCLRINT = 2;  /* only clear EOP, leave DESCR for the tty */
+	else
+		*DEBUG_OCLRINT = 3;  /* clear both EOP and DESCR */
+
+	while(*DEBUG_STATUS & 0x7f); /* wait until output FIFO is empty as well */
+
+	restore_flags(flags);
+}
+
+/* legacy function */
+
+void
+console_print_etrax(const char *buf)
+{
+	console_write(NULL, buf, strlen(buf));
+}
+
+/* Use polling to get a single character FROM the debug port */
+
+int
+getDebugChar(void)
+{
+	unsigned long readval;
+	
+	do {
+		readval = *DEBUG_READ;
+	} while(!(readval & IO_MASK(R_SERIAL0_READ, data_avail)));
+
+	return (readval & IO_MASK(R_SERIAL0_READ, data_in));
+}
+
+/* Use polling to put a single character to the debug port */
+
+void
+putDebugChar(int val)
+{
+	while(!(*DEBUG_READ & IO_MASK(R_SERIAL0_READ, tr_ready))) ;
+;
+	*DEBUG_WRITE = val;
+}
+
+/* Enable irq for receiving chars on the debug port, used by kgdb */
+
+void
+enableDebugIRQ(void)
+{
+	*R_IRQ_MASK1_SET = DEBUG_IRQ;
+	/* use R_VECT_MASK directly, since we really bypass Linux normal
+	 * IRQ handling in kgdb anyway, we don't need to use enable_irq
+	 */
+	*R_VECT_MASK_SET = IO_STATE(R_VECT_MASK_SET, serial, set);
+
+	*DEBUG_REC_CTRL = IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable);
+}
+
+static kdev_t 
+console_device(struct console *c)
+{
+         return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+static int __init 
+console_setup(struct console *co, char *options)
+{
+        return 0;
+}
+
+static struct console sercons = {
+        "ttyS",
+        console_write,
+        NULL,
+        console_device,
+        NULL,
+	NULL,
+	console_setup,
+	CON_PRINTBUFFER,
+	DEBUG_PORT_IDX,
+	0,
+	NULL
+};
+
+/*
+ *      Register console (for printk's etc)
+ */
+
+void __init 
+init_etrax_debug(void)
+{
+	register_console(&sercons);
+}
diff -urN linux-2.4.2-pre1/arch/cris/kernel/entry.S linux/arch/cris/kernel/entry.S
--- linux-2.4.2-pre1/arch/cris/kernel/entry.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/kernel/entry.S	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,738 @@
+/* $Id: entry.S,v 1.11 2001/01/10 21:13:29 bjornw Exp $
+ *
+ *  linux/arch/cris/entry.S
+ *
+ *  Copyright (C) 2000 Axis Communications AB
+ *
+ *  Authors:	Bjorn Wesen (bjornw@axis.com)
+ *
+ *  $Log: entry.S,v $
+ *  Revision 1.11  2001/01/10 21:13:29  bjornw
+ *  SYMBOL_NAME is defined incorrectly for the compiler options we currently use
+ *
+ *  Revision 1.10  2000/12/18 23:47:56  bjornw
+ *  * Added syscall trace support (ptrace), completely untested of course
+ *  * Removed redundant check for NULL entries in syscall_table
+ *
+ *  Revision 1.9  2000/11/21 16:40:51  bjornw
+ *  * New frame type used when an SBFS frame needs to be popped without
+ *    actually restarting the instruction
+ *  * Enable interrupts in signal_return (they did so in x86, I hope it's a good
+ *    idea)
+ *
+ *  Revision 1.8  2000/11/17 16:53:35  bjornw
+ *  Added detection of frame-type in Rexit, so that mmu_bus_fault can
+ *  use ret_from_intr in the return-path to check for signals (like SEGV)
+ *  and other foul things that might have occured during the fault.
+ *
+ *  Revision 1.7  2000/10/06 15:04:28  bjornw
+ *  Include mof in register savings
+ *
+ *  Revision 1.6  2000/09/12 16:02:44  bjornw
+ *  Linux-2.4.0-test7 derived updates
+ *
+ *  Revision 1.5  2000/08/17 15:35:15  bjornw
+ *  2.4.0-test6 changed local_irq_count and friends API
+ *
+ *  Revision 1.4  2000/08/02 13:59:30  bjornw
+ *  Removed olduname and uname from the syscall list
+ *
+ *  Revision 1.3  2000/07/31 13:32:58  bjornw
+ *  * Export ret_from_intr
+ *  * _resume updated (prev/last tjohejsan)
+ *  * timer_interrupt obsolete
+ *  * SIGSEGV detection in mmu_bus_fault temporarily disabled
+ *
+ *
+ */
+
+/*
+ * entry.S contains the system-call and fault low-level handling routines.
+ *
+ * NOTE: This code handles signal-recognition, which happens every time
+ * after a timer-interrupt and after each system call.
+ *
+ * Stack layout in 'ret_from_system_call':
+ * 	ptrace needs to have all regs on the stack.
+ *	if the order here is changed, it needs to be 
+ *	updated in fork.c:copy_process, signal.c:do_signal,
+ *	ptrace.c and ptrace.h
+ *
+ */
+
+#include <linux/linkage.h>
+#include <linux/sys.h>
+			
+	;; functions exported from this file
+	
+	.globl _system_call
+	.globl _ret_from_intr
+	.globl _ret_from_sys_call
+	.globl _resume
+	.globl _multiple_interrupt
+	.globl _hwbreakpoint
+	.globl _IRQ1_interrupt
+	.globl _timer_interrupt
+	.globl _timer_shortcut
+	.globl _spurious_interrupt
+	.globl _hw_bp_trigs
+	.globl _mmu_bus_fault
+				
+	.globl _sys_call_table
+		
+	;; syscall error codes
+	
+LENOSYS = 38
+
+	;; offsets into the task_struct (found at sp aligned to THREAD_SIZE, 8192)
+	;; linux/sched.h
+	
+LTASK_SIGPENDING  =  8
+LTASK_NEEDRESCHED = 20
+LTASK_PTRACE      = 24
+
+	;; some pt_regs offsets (from ptrace.h)
+	
+LORIG_R10	= 4
+LR13		= 8
+LR12		= 12
+LR11		= 16
+LR10		= 20
+LR1		= 56
+LR0		= 60	
+LDCCR		= 68
+LSRP		= 72
+LIRP		= 76
+
+	;; below are various parts of system_call which are not in the fast-path
+	
+	;; handle software irqs
+				
+handle_softirq:
+	push	r9
+	jsr	_do_softirq		; call the C routine for softirq handling
+	pop	r9
+
+	;; fall-through
+	
+_ret_from_intr:
+	;; check for resched only if we're going back to user-mode
+
+	move	ccr, r0
+	btstq	8, r0		; U-flag
+	bpl	Rexit		; go back directly
+	nop
+	ba	ret_with_reschedule  ; go back but check schedule and signals first 
+	nop
+		
+reschedule:
+	;; keep r9 intact
+	push	r9
+	jsr	_schedule
+	pop	r9
+	ba	_ret_from_sys_call
+	nop
+
+	;; return but call do_signal first
+signal_return:
+	ei			; we can get here from an interrupt
+	move.d	r9,r10		; do_signals syscall/irq param
+	moveq	0,r11		; oldset param - 0 in this case
+	move.d	sp,r12		; another argument to do_signal (the regs param)
+	jsr	_do_signal	; arch/cris/kernel/signal.c
+	ba	Rexit
+	nop
+	
+	;; The system_call is called by a BREAK instruction, which works like
+	;; an interrupt call but it stores the return PC in BRP instead of IRP.
+	;; Since we dont really want to have two epilogues (one for system calls
+	;; and one for interrupts) we push the contents of BRP instead of IRP in the
+	;; system call prologue, to make it look like an ordinary interrupt on the
+	;; stackframe.
+	;;
+	;; Since we can't have system calls inside interrupts, it should not matter
+	;; that we don't stack IRP.
+	;; 
+	;; In r1 we have the wanted syscall number. Arguments come in r10,r11,r12,r13,r0
+	;;
+	;; This function looks on the _surface_ like spaghetti programming, but it's
+	;; really designed so that the fast-path does not force cache-loading of non-used
+	;; instructions. Only the non-common cases cause the outlined code to run..
+
+_system_call:
+	;; stack-frame similar to the irq heads, which is reversed in ret_from_sys_call
+	push	brp		; this is normally push irp
+	push	srp
+	push	dccr
+	push	mof
+	subq	14*4,sp		; make room for r0-r13
+	movem	r13,[sp]	; push r0-r13
+	push	r10		; push orig_r10
+	clear.d [sp=sp-4]	; frametype == 0, normal stackframe
+	
+	move.d	r10,r2		; save for later
+	
+	movs.w	-LENOSYS,r10
+	move.d	r10,[sp+LR10]	; put the default return value in r10 in the frame
+	
+	move.d	sp,r10
+	jsr	_set_esp0	; save top of frame (clobbers r9...)
+
+	;; check if this process is syscall-traced
+
+	move.d	sp, r10
+	and.d	-8192, r10		; THREAD_SIZE == 8192
+	move.d	[r10+LTASK_PTRACE],r10
+	btstq	2, r10	                ; PT_TRACESYS
+	bmi	tracesys
+	nop	
+
+	;; check for sanity in the requested syscall number
+	
+	cmpu.w	NR_syscalls,r1	
+	bcc	_ret_from_sys_call
+	lslq	2,r1		;  multiply by 4, in the delay slot
+
+	;; read the system call vector into r1
+	
+	move.d	[r1+_sys_call_table],r1	
+
+	;; the parameter carrying registers r11, r12 and 13 are intact - restore r10.
+	;; the fifth parameter (if any) was in r0, and we need to put it on the stack
+
+	push	r0
+	move.d	r2,r10
+	
+	jsr	r1		; actually call the corresponding system call
+	addq	4,sp		; pop the r0 parameter
+	move.d	r10,[sp+LR10]	; save the return value
+
+	moveq	1,r9		; "parameter" to ret_from_sys_call to show it was a sys call
+	
+	;; fall through into ret_from_sys_call to return
+	
+_ret_from_sys_call:
+	;; r9 is a parameter - if 1, we came from a syscall, if 0, from an irq
+		
+	;; check if any bottom halves need service
+	
+	move.d	[_irq_stat],r0	       ; softirq_active
+	and.d	[_irq_stat+4],r0       ; softirq_mask
+	bne	handle_softirq
+	nop
+
+ret_with_reschedule:
+	;; first get the current task-struct pointer (see top for defs)
+
+	move.d	sp, r0
+	and.d	-8192, r0	; THREAD_SIZE == 8192
+	
+	;; see if we want to reschedule into another process
+	
+	test.d	[r0+LTASK_NEEDRESCHED]
+	bne	reschedule
+	nop
+
+	;; see if we need to run signal checks (important that r9 is intact here)
+
+	test.d	[r0+LTASK_SIGPENDING]
+	bne	signal_return
+	nop
+	
+Rexit:
+	;; this epilogue MUST match the prologues in multiple_interrupt, irq.h and ptregs.h
+	pop	r10		; frametype
+	bne	RBFexit		; was not CRIS_FRAME_NORMAL, handle otherwise
+	addq	4,sp		; skip orig_r10, in delayslot
+	movem	[sp+],r13	; registers r0-r13
+	pop	mof		; multiply overflow register 
+	pop	dccr		; condition codes
+	pop	srp		; subroutine return pointer
+	jmpu	[sp+]		; return by popping irp and jumping there
+	;; jmpu takes the U-flag into account to see if we return to
+	;; user-mode or kernel mode.
+
+RBFexit:
+	cmpq	2, r10		; was it CRIS_FRAME_FIXUP ?
+	beq	2f
+	movem	[sp+],r13	; registers r0-r13, in delay slot
+	pop	mof		; multiply overflow register 
+	pop	dccr		; condition codes
+	pop	srp		; subroutine return pointer
+	rbf	[sp+]		; return by popping the CPU status
+
+2:	pop	mof		; multiply overflow register
+	pop	dccr		; condition codes
+	pop	srp		; subroutine return pointer
+	;; now we have a 4-word SBFS frame which we do not want to restore
+	;; using RBF since we have made a fixup. instead we would like to
+	;; just get the PC value to restart it with, and skip the rest of
+	;; the frame.
+	pop	irp		; fixup location will be here
+	pop	p8		; null pop
+	pop	p8		; null pop
+	reti			; return to IRP, taking U-flag into account
+	pop	p8		; null pop in delayslot
+
+
+tracesys:
+	;; this first invocation of syscall_trace _requires_ that
+	;; LR10 in the frame contains -LENOSYS (as is set in the beginning
+	;; of system_call
+
+	jsr	_syscall_trace
+
+	;; now we should more or less do the same things as in the system_call
+	;; but since our argument regs got clobbered during syscall_trace and
+	;; because syscall_trace might want to alter them, we need to reload them
+	;; from the stack-frame as we use them.
+
+	;; check for sanity in the requested syscall number
+
+	move.d	[sp+LR1], r1
+	movs.w	-LENOSYS, r10
+	cmpu.w	NR_syscalls,r1	
+	bcc	1f
+	lslq	2,r1		;  multiply by 4, in the delay slot
+
+	;; read the system call vector entry into r1
+	
+	move.d	[r1+_sys_call_table],r1
+
+	;; restore r10, r11, r12, r13 and r0 into the needed registers
+
+	move.d	[sp+LORIG_R10], r10  ; LR10 is already filled with -LENOSYS
+	move.d	[sp+LR11],      r11
+	move.d	[sp+LR12],      r12
+	move.d	[sp+LR13],      r13
+	move.d	[sp+LR0],       r0
+
+	;; the fifth parameter needs to be put on the stack for the system
+	;; call to find it
+
+	push	r0
+	jsr	r1		; actually call the system-call
+	addq	4,sp		; pop the r0 parameter
+
+1:	move.d	r10,[sp+LR10]	; save the return value
+
+	;; second call of syscall_trace, to let it grab the results
+		
+	jsr	_syscall_trace
+
+	moveq	1,r9		; "parameter" to ret_from_sys_call to show it was a sys call
+	ba	_ret_from_sys_call
+	nop
+		
+	;; from asm/processor.h, the thread_struct
+	
+LTHREAD_KSP	= 0
+LTHREAD_USP	= 4
+LTHREAD_ESP0	= 8
+LTHREAD_DCCR	= 12
+	
+	;; _resume performs the actual task-switching, by switching stack pointers
+	;; input arguments: r10 = prev, r11 = next, r12 = thread offset in task struct
+	;; returns old current in r10
+	;;
+	;; TODO:  see the i386 version. The switch_to which calls resume in our version
+	;;        could really be an inline asm of this.
+
+_resume:	
+	push	srp		         ; we keep the old/new PC on the stack 
+	add.d	r12, r10		 ; r10 = current tasks tss
+	move	dccr, [r10+LTHREAD_DCCR] ; save irq enable state
+	di
+
+	move	usp, [r10+LTHREAD_USP]	 ; save user-mode stackpointer
+	
+	subq	10*4, sp
+	movem	r9, [sp]		 ; save non-scratch registers
+	
+	move.d	sp, [r10+LTHREAD_KSP]	 ; save the kernel stack pointer for the old task
+	move.d	sp, r10			 ; return last running task in r10
+	and.d   -8192, r10	         ; get task ptr from stackpointer
+	add.d	r12, r11		 ; find the new tasks tss
+	move.d	[r11+LTHREAD_KSP], sp	 ; switch into the new stackframe by restoring kernel sp
+
+	movem	[sp+], r9		 ; restore non-scratch registers
+
+	move	[r11+LTHREAD_USP], usp	 ; restore user-mode stackpointer
+	
+	move	[r11+LTHREAD_DCCR], dccr ; restore irq enable status
+	jump	[sp+]		         ; restore PC
+
+	;; This is the MMU bus fault handler.
+	;; It needs to stack the CPU status and overall is different
+	;; from the other interrupt handlers.
+
+_mmu_bus_fault:	
+	sbfs	[sp=sp-16]	; push the internal CPU status
+	;; the first longword in the sbfs frame was the interrupted PC
+	;; which fits nicely with the "IRP" slot in pt_regs normally used to
+	;; contain the return address. used by Oops to print kernel errors..
+	push	srp		; make a stackframe similar to pt_regs
+	push	dccr
+	push	mof
+	di
+	subq	14*4, sp
+	movem	r13, [sp]
+	push	r10		; dummy orig_r10
+	moveq	1, r10
+	push	r10		; frametype == 1, BUSFAULT frame type
+
+	moveq	0, r9		; busfault is equivalent to an irq
+		
+	move.d	sp, r10		; pt_regs argument to handle_mmu_bus_fault
+		
+	jsr	_handle_mmu_bus_fault  ; in arch/cris/mm/fault.c
+
+	;; now we need to return through the normal path, we cannot just
+	;; do the RBFexit since we might have killed off the running
+	;; process due to a SEGV, scheduled due to a page blocking or
+	;; whatever.
+
+	ba	_ret_from_intr
+	nop
+		
+	;; special handlers for breakpoint and NMI
+#if 0			
+_hwbreakpoint:
+	push	dccr
+	di
+	push	r10
+	push	r11
+	push	r12
+	push	r13
+	clearf	b
+	move	brp,r11
+	move.d	[_hw_bp_msg],r10
+	jsr	_printk
+	setf	b
+	pop	r13
+	pop	r12
+	pop	r11
+	pop	r10
+	pop	dccr
+	retb
+	nop
+#else
+_hwbreakpoint:
+	push	dccr
+	di
+#if 1
+	push	r10
+	push	r11
+	move.d	[_hw_bp_trig_ptr],r10
+	move.d	[r10],r11
+	cmp.d	42,r11
+	beq	nobp
+	nop
+	move	brp,r11
+	move.d	r11,[r10+]
+	move.d	r10,[_hw_bp_trig_ptr]
+nobp:	pop	r11
+	pop	r10
+#endif
+	pop	dccr
+	retb
+	nop
+#endif
+	
+_IRQ1_interrupt:
+_spurious_interrupt:	
+	di
+	move.b	4,r0
+	move.b	r0,[0xb0000030]
+basse2:	ba	basse2
+	nop
+
+	;; this handles the case when multiple interrupts arrive at the same time
+	;; we jump to the first set interrupt bit in a priority fashion
+	;; the hardware will call the unserved interrupts after the handler finishes
+	
+_multiple_interrupt:
+	;; this prologue MUST match the one in irq.h and the struct in ptregs.h!!!
+	push	irp
+	push	srp
+	push	dccr
+	push	mof
+	di
+	subq	14*4,sp
+	movem	r13,[sp]
+	push	r10		; push orig_r10
+	clear.d [sp=sp-4]	; frametype == 0, normal frame
+	
+	move.d	_irq_shortcuts + 8,r1
+	moveq	2,r2		; first bit we care about is the timer0 irq
+	move.d	[0xb00000d8],r0	; read the irq bits that triggered the multiple irq
+multloop:	
+	btst	r2,r0		; check for the irq given by bit r2
+	bmi	do_shortcut	; actually do the shortcut
+	nop
+	addq	1,r2		; next vector bit - remember this is in the delay slot!
+	addq	4,r1		; next vector
+	cmpq	26,r2
+	bne	multloop	; process all irq's up to and including number 25
+	nop
+	
+	;; strange, we didn't get any set vector bits.. oh well, just return
+	
+	ba	Rexit
+	nop
+
+do_shortcut:
+	test.d	[r1]
+	beq	Rexit
+	nop
+	jump	[r1]		; jump to the irq handlers shortcut
+
+	
+	.data
+
+_hw_bp_trigs:
+	.space 64*4
+_hw_bp_trig_ptr:
+	.dword _hw_bp_trigs
+
+/* linux/linkage.h got it wrong for this compiler currently */
+	
+#undef SYMBOL_NAME
+#define SYMBOL_NAME(X) _/**/X
+		
+_sys_call_table:	
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 0  -  old "setup()" system call*/
+	.long SYMBOL_NAME(sys_exit)
+	.long SYMBOL_NAME(sys_fork)
+	.long SYMBOL_NAME(sys_read)
+	.long SYMBOL_NAME(sys_write)
+	.long SYMBOL_NAME(sys_open)		/* 5 */
+	.long SYMBOL_NAME(sys_close)
+	.long SYMBOL_NAME(sys_waitpid)
+	.long SYMBOL_NAME(sys_creat)
+	.long SYMBOL_NAME(sys_link)
+	.long SYMBOL_NAME(sys_unlink)		/* 10 */
+	.long SYMBOL_NAME(sys_execve)
+	.long SYMBOL_NAME(sys_chdir)
+	.long SYMBOL_NAME(sys_time)
+	.long SYMBOL_NAME(sys_mknod)
+	.long SYMBOL_NAME(sys_chmod)		/* 15 */
+	.long SYMBOL_NAME(sys_lchown16)
+	.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 */
+	.long SYMBOL_NAME(sys_mount)
+	.long SYMBOL_NAME(sys_oldumount)
+	.long SYMBOL_NAME(sys_setuid16)
+	.long SYMBOL_NAME(sys_getuid16)
+	.long SYMBOL_NAME(sys_stime)		/* 25 */
+	.long SYMBOL_NAME(sys_ptrace)
+	.long SYMBOL_NAME(sys_alarm)
+	.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_access)
+	.long SYMBOL_NAME(sys_nice)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 35  old ftime syscall holder */
+	.long SYMBOL_NAME(sys_sync)
+	.long SYMBOL_NAME(sys_kill)
+	.long SYMBOL_NAME(sys_rename)
+	.long SYMBOL_NAME(sys_mkdir)
+	.long SYMBOL_NAME(sys_rmdir)		/* 40 */
+	.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_brk)		/* 45 */
+	.long SYMBOL_NAME(sys_setgid16)
+	.long SYMBOL_NAME(sys_getgid16)
+	.long SYMBOL_NAME(sys_signal)
+	.long SYMBOL_NAME(sys_geteuid16)
+	.long SYMBOL_NAME(sys_getegid16)	/* 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_ioctl)
+	.long SYMBOL_NAME(sys_fcntl)		/* 55 */
+	.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 sys_olduname holder */
+	.long SYMBOL_NAME(sys_umask)		/* 60 */
+	.long SYMBOL_NAME(sys_chroot)
+	.long SYMBOL_NAME(sys_ustat)
+	.long SYMBOL_NAME(sys_dup2)
+	.long SYMBOL_NAME(sys_getppid)
+	.long SYMBOL_NAME(sys_getpgrp)		/* 65 */
+	.long SYMBOL_NAME(sys_setsid)
+	.long SYMBOL_NAME(sys_sigaction)
+	.long SYMBOL_NAME(sys_sgetmask)
+	.long SYMBOL_NAME(sys_ssetmask)
+	.long SYMBOL_NAME(sys_setreuid16)	/* 70 */
+	.long SYMBOL_NAME(sys_setregid16)
+	.long SYMBOL_NAME(sys_sigsuspend)
+	.long SYMBOL_NAME(sys_sigpending)
+	.long SYMBOL_NAME(sys_sethostname)
+	.long SYMBOL_NAME(sys_setrlimit)	/* 75 */
+	.long SYMBOL_NAME(sys_old_getrlimit)
+	.long SYMBOL_NAME(sys_getrusage)
+	.long SYMBOL_NAME(sys_gettimeofday)
+	.long SYMBOL_NAME(sys_settimeofday)
+	.long SYMBOL_NAME(sys_getgroups16)	/* 80 */
+	.long SYMBOL_NAME(sys_setgroups16)
+	.long SYMBOL_NAME(sys_select)           /* was old_select in Linux/E100 */
+	.long SYMBOL_NAME(sys_symlink)
+	.long SYMBOL_NAME(sys_lstat)
+	.long SYMBOL_NAME(sys_readlink)		/* 85 */
+	.long SYMBOL_NAME(sys_uselib)
+	.long SYMBOL_NAME(sys_swapon)
+	.long SYMBOL_NAME(sys_reboot)
+	.long SYMBOL_NAME(old_readdir)
+	.long SYMBOL_NAME(old_mmap)		/* 90 */
+	.long SYMBOL_NAME(sys_munmap)
+	.long SYMBOL_NAME(sys_truncate)
+	.long SYMBOL_NAME(sys_ftruncate)
+	.long SYMBOL_NAME(sys_fchmod)
+	.long SYMBOL_NAME(sys_fchown16)		/* 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_statfs)
+	.long SYMBOL_NAME(sys_fstatfs)		/* 100 */
+	.long SYMBOL_NAME(sys_ni_syscall)       /* sys_ioperm in i386 */
+	.long SYMBOL_NAME(sys_socketcall)
+	.long SYMBOL_NAME(sys_syslog)
+	.long SYMBOL_NAME(sys_setitimer)
+	.long SYMBOL_NAME(sys_getitimer)	/* 105 */
+	.long SYMBOL_NAME(sys_newstat)
+	.long SYMBOL_NAME(sys_newlstat)
+	.long SYMBOL_NAME(sys_newfstat)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* old sys_uname holder */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_iopl in i386 */
+	.long SYMBOL_NAME(sys_vhangup)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* old "idle" system call */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* vm86old in i386 */
+	.long SYMBOL_NAME(sys_wait4)
+	.long SYMBOL_NAME(sys_swapoff)		/* 115 */
+	.long SYMBOL_NAME(sys_sysinfo)
+	.long SYMBOL_NAME(sys_ipc)
+	.long SYMBOL_NAME(sys_fsync)
+	.long SYMBOL_NAME(sys_sigreturn)
+	.long SYMBOL_NAME(sys_clone)		/* 120 */
+	.long SYMBOL_NAME(sys_setdomainname)
+	.long SYMBOL_NAME(sys_newuname)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* TODO sys_modify_ldt - do something ?*/
+	.long SYMBOL_NAME(sys_adjtimex)
+	.long SYMBOL_NAME(sys_mprotect)		/* 125 */
+	.long SYMBOL_NAME(sys_sigprocmask)
+	.long SYMBOL_NAME(sys_create_module)
+	.long SYMBOL_NAME(sys_init_module)
+	.long SYMBOL_NAME(sys_delete_module)
+	.long SYMBOL_NAME(sys_get_kernel_syms)	/* 130 */
+	.long SYMBOL_NAME(sys_quotactl)
+	.long SYMBOL_NAME(sys_getpgid)
+	.long SYMBOL_NAME(sys_fchdir)
+	.long SYMBOL_NAME(sys_bdflush)
+	.long SYMBOL_NAME(sys_sysfs)		/* 135 */
+	.long SYMBOL_NAME(sys_personality)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* for afs_syscall */
+	.long SYMBOL_NAME(sys_setfsuid16)
+	.long SYMBOL_NAME(sys_setfsgid16)
+	.long SYMBOL_NAME(sys_llseek)		/* 140 */
+	.long SYMBOL_NAME(sys_getdents)
+	.long SYMBOL_NAME(sys_select)
+	.long SYMBOL_NAME(sys_flock)
+	.long SYMBOL_NAME(sys_msync)
+	.long SYMBOL_NAME(sys_readv)		/* 145 */
+	.long SYMBOL_NAME(sys_writev)
+	.long SYMBOL_NAME(sys_getsid)
+	.long SYMBOL_NAME(sys_fdatasync)
+	.long SYMBOL_NAME(sys_sysctl)
+	.long SYMBOL_NAME(sys_mlock)		/* 150 */
+	.long SYMBOL_NAME(sys_munlock)
+	.long SYMBOL_NAME(sys_mlockall)
+	.long SYMBOL_NAME(sys_munlockall)
+	.long SYMBOL_NAME(sys_sched_setparam)
+	.long SYMBOL_NAME(sys_sched_getparam)   /* 155 */
+	.long SYMBOL_NAME(sys_sched_setscheduler)
+	.long SYMBOL_NAME(sys_sched_getscheduler)
+	.long SYMBOL_NAME(sys_sched_yield)
+	.long SYMBOL_NAME(sys_sched_get_priority_max)
+	.long SYMBOL_NAME(sys_sched_get_priority_min)  /* 160 */
+	.long SYMBOL_NAME(sys_sched_rr_get_interval)
+	.long SYMBOL_NAME(sys_nanosleep)
+	.long SYMBOL_NAME(sys_mremap)
+	.long SYMBOL_NAME(sys_setresuid16)
+	.long SYMBOL_NAME(sys_getresuid16)	/* 165 */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_vm86 */
+	.long SYMBOL_NAME(sys_query_module)
+	.long SYMBOL_NAME(sys_poll)
+	.long SYMBOL_NAME(sys_nfsservctl)
+	.long SYMBOL_NAME(sys_setresgid16)	/* 170 */
+	.long SYMBOL_NAME(sys_getresgid16)
+	.long SYMBOL_NAME(sys_prctl)
+	.long SYMBOL_NAME(sys_rt_sigreturn)
+	.long SYMBOL_NAME(sys_rt_sigaction)
+	.long SYMBOL_NAME(sys_rt_sigprocmask)	/* 175 */
+	.long SYMBOL_NAME(sys_rt_sigpending)
+	.long SYMBOL_NAME(sys_rt_sigtimedwait)
+	.long SYMBOL_NAME(sys_rt_sigqueueinfo)
+	.long SYMBOL_NAME(sys_rt_sigsuspend)
+	.long SYMBOL_NAME(sys_pread)		/* 180 */
+	.long SYMBOL_NAME(sys_pwrite)
+	.long SYMBOL_NAME(sys_chown16)
+	.long SYMBOL_NAME(sys_getcwd)
+	.long SYMBOL_NAME(sys_capget)
+	.long SYMBOL_NAME(sys_capset)           /* 185 */
+	.long SYMBOL_NAME(sys_sigaltstack)
+	.long SYMBOL_NAME(sys_sendfile)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* streams1 */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* streams2 */
+	.long SYMBOL_NAME(sys_vfork)            /* 190 */
+	.long SYMBOL_NAME(sys_getrlimit)
+	.long SYMBOL_NAME(sys_mmap2)
+	.long SYMBOL_NAME(sys_truncate64)
+	.long SYMBOL_NAME(sys_ftruncate64)
+	.long SYMBOL_NAME(sys_stat64)		/* 195 */
+	.long SYMBOL_NAME(sys_lstat64)
+	.long SYMBOL_NAME(sys_fstat64)
+	.long SYMBOL_NAME(sys_lchown)
+	.long SYMBOL_NAME(sys_getuid)
+	.long SYMBOL_NAME(sys_getgid)		/* 200 */
+	.long SYMBOL_NAME(sys_geteuid)
+	.long SYMBOL_NAME(sys_getegid)
+	.long SYMBOL_NAME(sys_setreuid)
+	.long SYMBOL_NAME(sys_setregid)
+	.long SYMBOL_NAME(sys_getgroups)	/* 205 */
+	.long SYMBOL_NAME(sys_setgroups)
+	.long SYMBOL_NAME(sys_fchown)
+	.long SYMBOL_NAME(sys_setresuid)
+	.long SYMBOL_NAME(sys_getresuid)
+	.long SYMBOL_NAME(sys_setresgid)	/* 210 */
+	.long SYMBOL_NAME(sys_getresgid)
+	.long SYMBOL_NAME(sys_chown)
+	.long SYMBOL_NAME(sys_setuid)
+	.long SYMBOL_NAME(sys_setgid)
+	.long SYMBOL_NAME(sys_setfsuid)		/* 215 */
+	.long SYMBOL_NAME(sys_setfsgid)
+	.long SYMBOL_NAME(sys_pivot_root)
+	.long SYMBOL_NAME(sys_mincore)
+	.long SYMBOL_NAME(sys_madvise)
+	.long SYMBOL_NAME(sys_getdents64)       /* 220 */
+
+        /*
+         * NOTE!! This doesn't have to be exact - we just have
+         * to make sure we have _enough_ of the "sys_ni_syscall"
+         * entries. Don't panic if you notice that this hasn't
+         * been shrunk every time we add a new system call.
+         */
+
+	;; TODO: this needs to actually generate sys_ni_syscall entires
+	;; since we now have removed the check for NULL entries in this
+	;; table in system_call!
+	
+	.space (NR_syscalls-220)*4
+	
diff -urN linux-2.4.2-pre1/arch/cris/kernel/head.S linux/arch/cris/kernel/head.S
--- linux-2.4.2-pre1/arch/cris/kernel/head.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/kernel/head.S	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,519 @@
+	;; $Id: head.S,v 1.11 2001/01/16 16:31:38 bjornw Exp $
+	;; 
+	;; Head of the kernel - alter with care
+	;;
+	;; Copyright (C) 2000, 2001 Axis Communications AB
+	;;
+	;; Authors:	Bjorn Wesen (bjornw@axis.com)
+	;; 
+	;; $Log: head.S,v $
+	;; Revision 1.11  2001/01/16 16:31:38  bjornw
+	;; * Changed name and semantics of running_from_flash to romfs_in_flash,
+	;;   set by head.S to indicate to setup.c whether there is a cramfs image
+	;;   after the kernels BSS or not. Should work for all three boot-cases
+	;;   (DRAM with cramfs in DRAM, DRAM with cramfs in flash (compressed boot),
+	;;    and flash with cramfs in flash)
+	;;
+	;; Revision 1.10  2001/01/16 14:12:21  bjornw
+	;; * Check for cramfs start passed in r9 from the decompressor, if all other
+	;;   cramfs options fail (if we boot from DRAM but don't find a cramfs image
+	;;   after the kernel in DRAM, it is probably still in the flash)
+	;; * Check magic in cramfs detection when booting from flash directly
+	;;
+	;; Revision 1.9  2001/01/15 17:17:02  bjornw
+	;; * Corrected the code that detects the cramfs lengths
+	;; * Added a comment saying that the above does not work due to other
+	;;   reasons..
+	;;
+	;; Revision 1.8  2001/01/15 16:27:51  jonashg
+	;; Made boot after flashing work.
+	;; * end destination is __vmlinux_end in RAM.
+	;; * _romfs_start moved because of virtual memory.
+	;;
+	;; Revision 1.7  2000/11/21 13:55:29  bjornw
+	;; Use CONFIG_CRIS_LOW_MAP for the low VM map instead of explicit CPU type
+	;;
+	;; Revision 1.6  2000/10/06 12:36:55  bjornw
+	;; Forgot swapper_pg_dir when changing memory map..
+	;;
+	;; Revision 1.5  2000/10/04 16:49:30  bjornw
+	;; * Fixed memory mapping in LX
+	;; * Check for cramfs instead of romfs
+	;;
+	;;
+	
+#include <linux/config.h>
+#define ASSEMBLER_MACROS_ONLY
+#include <asm/sv_addr_ag.h>
+
+#define CRAMFS_MAGIC 0x28cd3d45
+	
+	;; exported symbols
+		
+	.globl	_etrax_irv
+	.globl	_romfs_start
+	.globl	_romfs_length
+	.globl	_romfs_in_flash
+	.globl  _swapper_pg_dir
+					
+	.text
+
+	;; This is the entry point of the kernel. We are in supervisor mode.
+	;; 0x00000000 if Flash, 0x40004000 if DRAM
+	;; since etrax actually starts at address 2 when booting from flash, we
+	;; put a nop (2 bytes) here first so we dont accidentally skip the di
+	;;
+	;; NOTICE! The register r9 is used as a parameter carrying register from
+	;; the decompressor (if the kernel was compressed). It should not be
+	;; used in the code below until it is read.
+	
+	nop	
+	di
+
+	;; First setup the kseg_c mapping from where the kernel is linked
+	;; to 0x40000000 (where the actual DRAM resides) otherwise
+	;; we cannot do very much! See arch/cris/README.mm
+	;;
+	;; Notice that since we're potentially running at 0x00 or 0x40 right now,
+	;; we will get a fault as soon as we enable the MMU if we dont
+	;; temporarily map those segments linearily.
+	;;
+	;; Due to a bug in Etrax-100 LX version 1 we need to map the memory
+	;; slightly different. We also let the simulator get this mapping for now.
+
+#ifdef CONFIG_CRIS_LOW_MAP
+	move.d	0x0800b000, r0	; kseg mappings
+	move.d	r0, [R_MMU_KBASE_HI]
+
+	move.d	0x04040000, r0	; temporary map of 0x40->0x40 and 0x00->0x00 
+	move.d	r0, [R_MMU_KBASE_LO]
+
+	move.d	0x80074871, r0	; mmu enable, segs e,b,6,5,4,0 segment mapped
+	move.d	r0, [R_MMU_CONFIG]
+#else
+	move.d	0x0804b000, r0	; kseg mappings
+	move.d	r0, [R_MMU_KBASE_HI]
+
+	move.d	0x00040000, r0	; temporary map of 0x40->0x40 and 0x00->0x00 
+	move.d	r0, [R_MMU_KBASE_LO]
+
+	move.d	0x8007d811, r0	; mmu enable, segs f,e,c,b,4,0 segment mapped
+	move.d	r0, [R_MMU_CONFIG]
+#endif
+
+	;; Now we need to sort out the segments and their locations in RAM or
+	;; Flash. The image in the Flash (or in DRAM) consists of 3 pieces:
+	;; 1) kernel text, 2) kernel data, 3) ROM filesystem image
+	;; But the linker has linked the kernel to expect this layout in
+	;; DRAM memory:
+	;; 1) kernel text, 2) kernel data, 3) kernel BSS
+	;; (the location of the ROM filesystem is determined by the krom driver)
+	;; If we boot this from Flash, we want to keep the ROM filesystem in
+	;; the flash, we want to copy the text and need to copy the data to DRAM.
+	;; But if we boot from DRAM, we need to move the ROMFS image
+	;; from its position after kernel data, to after kernel BSS, BEFORE the
+	;; kernel starts using the BSS area (since its "overlayed" with the ROMFS)
+	;;
+	;; In both cases, we start in un-cached mode, and need to jump into a
+	;; cached PC after we're done fiddling around with the segments.
+	;; 
+	;; arch/etrax100/etrax100.ld sets some symbols that define the start
+	;; and end of each segment.
+	
+	;; Check if we start from DRAM or FLASH by testing PC
+	
+	move.d	pc,r0
+	and.d	0x7fffffff,r0	; get rid of the non-cache bit
+	cmp.d	0x10000,r0	; arbitrary... just something above this code
+	bcs	inflash
+	nop
+
+	jump	inram		; enter cached ram
+	
+inflash:
+
+#ifndef CONFIG_SVINTO_SIM	
+
+	;; We need to setup the bus registers before we start using the DRAM
+
+	move.d   DEF_R_WAITSTATES, r0
+	move.d   r0, [R_WAITSTATES]
+
+	move.d   DEF_R_BUS_CONFIG, r0
+	move.d   r0, [R_BUS_CONFIG]
+  
+	move.d   DEF_R_DRAM_CONFIG, r0
+	move.d   r0, [R_DRAM_CONFIG]
+
+	move.d   DEF_R_DRAM_TIMING, r0
+	move.d   r0, [R_DRAM_TIMING]
+
+#endif
+	;; Copy text+data to DRAM
+	;; This is fragile - the calculation of r4 as the image size depends
+	;; on that the labels below actually are the first and last positions
+	;; in the linker-script.
+	;;
+	;; Then the locating of the cramfs image depends on the aforementioned
+	;; image being located in the flash at 0. This is most often not true,
+	;; thus the following does not work (normally there is a rescue-block
+	;; between the physical start of the flash and the flash-image start,
+	;; and when run with compression, the kernel is actually unpacked to
+	;; DRAM and we never get here in the first place :))
+	
+	moveq	0, r0			; source
+	move.d	_text_start, r1		; destination
+	move.d	__vmlinux_end, r2	; end destination
+	move.d	r2, r4
+	sub.d	r1, r4			; r4=__vmlinux_end in flash, used below
+1:	move.w	[r0+], r3
+	move.w	r3, [r1+]
+	cmp.d	r2, r1
+	bcs	1b
+	nop
+
+	;; We keep the cramfs in the flash.
+	;; There might be none, but that does not matter because
+	;; we don't do anything than read some bytes here.
+
+	moveq	0, r0
+	move.d	r0, [_romfs_length] ; default if there is no cramfs
+
+	move.d  [r4], r0	; cramfs_super.magic
+	cmp.d	CRAMFS_MAGIC, r0
+	bne	1f
+	nop
+	move.d	[r4 + 4], r0	; cramfs_super.size
+	move.d	r0, [_romfs_length]
+#ifdef CONFIG_CRIS_LOW_MAP
+	add.d   0x50000000, r4	; add flash start in virtual memory (cached)
+#else
+	add.d   0xf0000000, r4	; add flash start in virtual memory (cached)
+#endif
+	move.d	r4, [_romfs_start]
+1:	
+	moveq	1, r0
+	move.d	r0, [_romfs_in_flash]
+		
+	jump	start_it	; enter code, cached this time
+
+inram:
+	;; Move the ROM fs to after BSS end. This assumes that the cramfs
+	;; second longword contains the length of the cramfs
+	
+	moveq	0, r0
+	move.d	r0, [_romfs_length] ; default if there is no cramfs
+	
+	;; First check if there is a cramfs (magic value)
+	;; Notice that we check for cramfs magic value - which is
+	;; the "rom fs" we'll possibly use in 2.4 if not JFFS (which does
+	;; not need this mechanism anyway)
+	
+	move.d	__vmlinux_end, r0 ; the image will be after the vmlinux end address
+	move.d	[r0], r1	; cramfs assumes same endian on host/target
+	cmp.d	CRAMFS_MAGIC, r1; magic value in cramfs superblock
+	bne	no_romfs_in_ram
+	nop
+
+	;; Ok. What is its size ? 
+	
+	move.d	[r0 + 4], r2	; cramfs_super.size (again, no need to swapwb)
+
+	;; We want to copy it to the end of the BSS
+
+	move.d	_end, r1
+
+	;; Remember values so cramfs and setup can find this info
+
+	move.d	r1, [_romfs_start]	; new romfs location
+	move.d	r2, [_romfs_length]
+
+	;; We need to copy it backwards, since they can be overlapping
+
+	add.d	r2, r0
+	add.d	r2, r1
+		
+	;; Go ahead. Make my loop.
+
+	lsrq	1, r2		; size is in bytes, we copy words
+
+1:	move.w	[r0=r0-2],r3
+	move.w	r3,[r1=r1-2]
+	subq	1, r2
+	bne	1b
+	nop
+	
+	;; Dont worry that the BSS is tainted. It will be cleared later.
+
+	moveq	0, r0
+	move.d	r0, [_romfs_in_flash]
+
+	jump	start_it	; better skip the additional cramfs check below
+			
+no_romfs_in_ram:
+
+	;; We have still one other possibility at this point - the kernel
+	;; could have been unpacked to DRAM by the loader, but the cramfs
+	;; image was still in the Flash directly after the compressed kernel
+	;; image. The loader passes the address of the byte succeeding the
+	;; last compressed byte in the flash in the register r9 when starting
+	;; the kernel. Check if r9 points to a decent cramfs image!
+	;; (Notice that if this is not booted from the loader, r9 will be
+	;;  garbage but we do sanity checks on it, the chance that it points
+	;;  to a cramfs magic is small.. )
+	
+	cmp.d	0x0ffffff8, r9
+	bcc	1f		; r9 points outside the flash area
+	nop
+	move.d	[r9], r0	; cramfs_super.magic
+	cmp.d	CRAMFS_MAGIC, r0
+	bne	1f
+	nop
+	move.d	[r9+4], r0	; cramfs_super.length
+	move.d	r0, [_romfs_length]
+#ifdef CONFIG_CRIS_LOW_MAP
+	add.d   0x50000000, r9	; add flash start in virtual memory (cached)
+#else
+	add.d   0xf0000000, r9	; add flash start in virtual memory (cached)
+#endif
+	move.d	r9, [_romfs_start]
+
+	moveq	1, r0
+	move.d	r0, [_romfs_in_flash]
+1:	
+	
+	jump	start_it	; enter code, cached this time
+	
+start_it:
+	;; the kernel stack is overlayed with the task structure for each
+	;; task. thus the initial kernel stack is in the same page as the
+	;; init_task (but starts in the top of the page, size 8192)
+	move.d	_init_task_union + 8192,sp
+	move.d	_ibr_start,r0	; this symbol is set by the linker script 
+	move	r0,ibr
+	move.d	r0,[_etrax_irv]	; set the interrupt base register and pointer
+
+	;; Clear BSS region, from _bss_start to _end
+
+	move.d	__bss_start, r0
+	move.d	_end, r1
+1:	clear.d	[r0+]
+	cmp.d	r1, r0
+	bcs	1b
+	nop
+	
+#ifdef CONFIG_BLK_DEV_ETRAXIDE
+	;; disable ATA before enabling it in genconfig below
+	moveq	0,r0
+	move.d	r0,[R_ATA_CTRL_DATA]
+	move.d	r0,[R_ATA_TRANSFER_CNT]
+	move.d	r0,[R_ATA_CONFIG]
+#if 0
+	move.d	R_PORT_G_DATA,r1
+	move.d	r0,[r1]; assert ATA bus-reset
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	move.d	0x08000000,r0
+	move.d	r0,[r1]
+#endif
+#endif
+
+#ifdef CONFIG_JULIETTE
+	;; configure external DMA channel 0 before enabling it in genconfig
+	
+	moveq	0,r0
+	move.d	r0,[R_EXT_DMA_0_ADDR]
+	move.d	0x860000,r0	; cnt enable, word size, output, stop, size 0
+	move.d	r0,[R_EXT_DMA_0_CMD]
+
+	;; reset dma4 and wait for completion
+	
+	moveq	4,r0
+	move.b	r0,[R_DMA_CH4_CMD]
+w4u:	move.b	[R_DMA_CH4_CMD],r0
+	and.b	7,r0
+	cmp.b	4,r0
+	beq	w4u
+	nop
+
+	;; reset dma5 and wait for completion
+	
+	moveq	4,r0
+	move.b	r0,[R_DMA_CH5_CMD]
+w5u:	move.b	[R_DMA_CH5_CMD],r0
+	and.b	7,r0
+	cmp.b	4,r0
+	beq	w5u
+	nop
+#endif	
+			
+	;; Etrax product HW genconfig setup
+
+	moveq	0,r0
+#if !defined(CONFIG_KGDB) && !defined(CONFIG_DMA_MEMCPY)
+	or.d	0x140000,r0	; DMA channels 6 and 7 to ser0, kgdb doesnt want DMA
+#endif
+#if !defined(CONFIG_KGDB) || !defined(CONFIG_DEBUG_PORT1)
+	or.d	0xc00000,r0	; DMA channels 8 and 9 to ser1, kgdb doesnt want DMA
+#endif
+#ifdef CONFIG_DMA_MEMCPY
+	or.d	0x003c0000,r0	; 6/7 memory-memory DMA
+#endif
+#ifdef CONFIG_ETRAX100_SERIAL_PORT2
+	or.d	0x2808,r0	; DMA channels 2 and 3 to serport 2, port 2 enabled
+#endif
+#ifdef CONFIG_ETRAX100_SERIAL_PORT3
+	or.d	0x28100,r0	; DMA channels 4 and 5 to serport 3, port 3 enabled
+#endif
+#if defined(CONFIG_ETRAX100_PARALLEL_PORT0) || defined(CONFIG_ETRAX_ETHERNET_LPSLAVE)
+	or.w	0x4,r0	; parport 0 enabled using DMA 2/3
+#endif
+#if defined(CONFIG_ETRAX100_PARALLEL_PORT1) || defined(CONFIG_ETRAX_ETHERNET_LPSLAVE)
+	or.w	0x80,r0	; parport 1 enabled using DMA 4/5
+#endif
+#ifdef CONFIG_BLK_DEV_ETRAXIDE
+	or.d	0x3c02,r0	; DMA channels 2 and 3 to ATA, ATA enabled
+#endif
+#ifdef CONFIG_JULIETTE
+	or.d	0x3c000,r0	; DMA channels 4 and 5 to EXTDMA0, for Juliette
+#ifndef CONFIG_BLK_DEV_ETRAXIDE
+	or.d	0x41,r0		; HACK for now! To make G27 connected for the RTC
+#endif
+#endif
+	move.d	r0,[_genconfig_shadow] ; init a shadow register of R_GEN_CONFIG
+
+#ifndef CONFIG_SVINTO_SIM
+	move.d	r0,[R_GEN_CONFIG]
+
+#if 0
+	moveq	4,r0
+	move.b	r0,[R_DMA_CH6_CMD]	; reset (ser0 dma out)
+	move.b	r0,[R_DMA_CH7_CMD]	; reset (ser0 dma in)
+w61:	move.b	[R_DMA_CH6_CMD],r0	; wait for reset cycle to finish
+	and.b	7,r0
+	cmp.b	4,r0
+	beq	w61
+	nop
+w71:	move.b	[R_DMA_CH7_CMD],r0	; wait for reset cycle to finish
+	and.b	7,r0
+	cmp.b	4,r0
+	beq	w71
+	nop
+#endif
+	
+	moveq	4,r0
+	move.b	r0,[R_DMA_CH8_CMD]	; reset (ser1 dma out)
+	move.b	r0,[R_DMA_CH9_CMD]	; reset (ser1 dma in)
+w81:	move.b	[R_DMA_CH8_CMD],r0	; wait for reset cycle to finish
+	and.b	7,r0
+	cmp.b	4,r0
+	beq	w81
+	nop
+w91:	move.b	[R_DMA_CH9_CMD],r0	; wait for reset cycle to finish
+	and.b	7,r0
+	cmp.b	4,r0
+	beq	w91
+	nop
+
+	;; setup port PA and PB default initial directions and data
+	;; including their shadow registers
+		
+	move.b	DEF_R_PORT_PA_DIR,r0
+	move.b	r0,[_port_pa_dir_shadow]
+	move.b	r0,[R_PORT_PA_DIR]
+	move.b	DEF_R_PORT_PA_DATA,r0
+	move.b	r0,[_port_pa_data_shadow]
+	move.b	r0,[R_PORT_PA_DATA]
+	
+	move.b	DEF_R_PORT_PB_CONFIG,r0
+	move.b	r0,[_port_pb_config_shadow]
+	move.b	r0,[R_PORT_PB_CONFIG]
+	move.b	DEF_R_PORT_PB_DIR,r0
+	move.b	r0,[_port_pb_dir_shadow]
+	move.b	r0,[R_PORT_PB_DIR]
+	move.b	DEF_R_PORT_PB_DATA,r0
+	move.b	r0,[_port_pb_data_shadow]
+	move.b	r0,[R_PORT_PB_DATA]
+
+	moveq	0,r0
+	move.d	r0,[_port_g_data_shadow]
+	move.d	r0,[R_PORT_G_DATA]
+	
+	;; setup the serial port 0 at 115200 baud for debug purposes
+	
+	moveq	0,r0
+	move.d	r0,[R_SERIAL0_XOFF] 
+
+	move.b	0x99,r0
+	move.b	r0,[R_SERIAL0_BAUD]	; 115.2kbaud for both transmit and receive
+
+	move.b	0x40,r0			; rec enable
+	move.b	r0,[R_SERIAL0_REC_CTRL] 
+	
+	move.b	0x40,r0			; tr enable
+	move.b	r0,[R_SERIAL0_TR_CTRL]
+
+	;; setup the serial port 1 at 115200 baud for debug purposes
+	
+	moveq	0,r0
+	move.d	r0,[R_SERIAL1_XOFF] 
+
+	move.b	0x99,r0
+	move.b	r0,[R_SERIAL1_BAUD]	; 115.2kbaud for both transmit and receive
+
+	move.b	0x40,r0			; rec enable
+	move.b	r0,[R_SERIAL1_REC_CTRL] 
+	
+	move.b	0x40,r0			; tr enable
+	move.b	r0,[R_SERIAL1_TR_CTRL]
+
+#ifdef CONFIG_ETRAX_90000000_LEDS
+	;; clear LED's on Stallone and Olga boards
+	moveq	-1,r0
+	move.d	r0,[_port_90000000_shadow]
+	move.d	r0,[0x90000000]
+#endif
+	
+#ifdef CONFIG_ETRAX100_SERIAL_PORT3	
+	;; setup the serial port 3 at 115200 baud for debug purposes
+	
+	moveq	0,r0
+	move.d	r0,[R_SERIAL3_XOFF] 
+
+	move.b	0x99,r0
+	move.b	r0,[R_SERIAL3_BAUD]	; 115.2kbaud for both transmit and receive
+
+	move.b	0x40,r0			; rec enable
+	move.b	r0,[R_SERIAL3_REC_CTRL] 
+	
+	move.b	0x40,r0			; tr enable
+	move.b	r0,[R_SERIAL3_TR_CTRL]
+#endif
+	
+#endif /* CONFIG_SVINTO_SIM */
+
+	jump	_start_kernel	; jump into the C-function _start_kernel in init/main.c
+
+	
+	.data
+_etrax_irv:	
+	.dword	0
+_romfs_start:
+	.dword	0
+_romfs_length:
+	.dword	0
+_romfs_in_flash:
+	.dword	0
+
+	;; put some special pages at the beginning of the kernel aligned
+	;; to page boundaries - the kernel cannot start until after this
+
+#ifdef CONFIG_CRIS_LOW_MAP
+_swapper_pg_dir = 0x60002000
+#else	
+_swapper_pg_dir = 0xc0002000
+#endif
diff -urN linux-2.4.2-pre1/arch/cris/kernel/hexify.c linux/arch/cris/kernel/hexify.c
--- linux-2.4.2-pre1/arch/cris/kernel/hexify.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/kernel/hexify.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,31 @@
+#include <stdio.h>
+
+
+void main()
+{
+	int c;
+	int comma=0;
+	int count=0;
+	while((c=getchar())!=EOF)
+	{
+		unsigned char x=c;
+		if(comma)
+			printf(",");
+		else
+			comma=1;
+		if(count==8)
+		{
+			count=0;
+			printf("\n");
+		}
+		if(count==0)
+			printf("\t");
+		printf("0x%02X",c);
+		count++;
+	}
+	if(count)
+		printf("\n");
+	exit(0);
+}
+
+		
diff -urN linux-2.4.2-pre1/arch/cris/kernel/irq.c linux/arch/cris/kernel/irq.c
--- linux-2.4.2-pre1/arch/cris/kernel/irq.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/kernel/irq.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,467 @@
+/* $Id: irq.c,v 1.5 2000/08/17 15:35:15 bjornw Exp $
+ *
+ *	linux/arch/cris/kernel/irq.c
+ *
+ *      Copyright (c) 2000 Axis Communications AB
+ *
+ *      Authors: Bjorn Wesen (bjornw@axis.com)
+ *
+ * This file contains the code used by various IRQ handling routines:
+ * asking for different IRQ's should be done through these routines
+ * instead of just grabbing them. Thus setups with different IRQ numbers
+ * shouldn't result in any weird surprises, and installing new handlers
+ * should be easier.
+ *
+ * Notice Linux/CRIS: these routines do not care about SMP
+ *
+ */
+
+/*
+ * IRQ's are in fact implemented a bit like signal handlers for the kernel.
+ * Naturally it's not a 1:1 relation, but there are similarities.
+ */
+
+#include <linux/config.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/malloc.h>
+#include <linux/random.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+
+#include <asm/svinto.h>
+
+char *hw_bp_msg = "BP 0x%x\n";
+
+static inline void
+mask_irq(unsigned int irq_nr)
+{
+	*R_VECT_MASK_CLR = 1 << irq_nr;
+}
+
+static inline void
+unmask_irq(unsigned int irq_nr)
+{
+	*R_VECT_MASK_SET = 1 << irq_nr;
+}
+
+void
+disable_irq(unsigned int irq_nr)
+{
+	unsigned long flags;
+	
+	save_flags(flags);
+	cli();
+	mask_irq(irq_nr);
+	restore_flags(flags);
+}
+
+void
+enable_irq(unsigned int irq_nr)
+{
+	unsigned long flags;
+	save_flags(flags);
+	cli();
+	unmask_irq(irq_nr);
+	restore_flags(flags);
+}
+
+unsigned long
+probe_irq_on()
+{
+	return 0;
+}
+
+int
+probe_irq_off(unsigned long x)
+{
+	return 0;
+}
+
+irqvectptr irq_shortcuts[NR_IRQS]; /* vector of shortcut jumps after the irq prologue */
+
+/* don't use set_int_vector, it bypasses the linux interrupt handlers. it is
+ * global just so that the kernel gdb can use it.
+ */
+
+void
+set_int_vector(int n, irqvectptr addr, irqvectptr saddr)
+{
+	/* remember the shortcut entry point, after the prologue */
+
+	irq_shortcuts[n] = saddr;
+
+	etrax_irv->v[n + 0x20] = (irqvectptr)addr;
+}
+
+/* the breakpoint vector is obviously not made just like the normal irq handlers
+ * but needs to contain _code_ to jump to addr.
+ *
+ * the BREAK n instruction jumps to IBR + n * 8
+ */
+
+void
+set_break_vector(int n, irqvectptr addr)
+{
+	unsigned short *jinstr = (unsigned short *)&etrax_irv->v[n*2];
+	unsigned long *jaddr = (unsigned long *)(jinstr + 1);
+
+	/* if you don't know what this does, do not touch it! */
+	
+	*jinstr = 0x0d3f;
+	*jaddr = (unsigned long)addr;
+
+	/* 00000026 <clrlop+1a> 3f0d82000000     jump  0x82 */
+}
+
+
+/*
+ * This builds up the IRQ handler stubs using some ugly macros in irq.h
+ *
+ * These macros create the low-level assembly IRQ routines that do all
+ * the operations that are needed. They are also written to be fast - and to
+ * disable interrupts as little as humanly possible.
+ *
+ */
+
+/* IRQ0 and 1 are special traps */
+void hwbreakpoint(void);
+void IRQ1_interrupt(void);
+BUILD_IRQ(2, 0x04)             /* the timer interrupt */
+BUILD_IRQ(3, 0x08)
+BUILD_IRQ(4, 0x10)
+BUILD_IRQ(5, 0x20)
+BUILD_IRQ(6, 0x40)
+BUILD_IRQ(7, 0x80)
+BUILD_IRQ(8, 0x100)
+BUILD_IRQ(9, 0x200)
+BUILD_IRQ(10, 0x400)
+BUILD_IRQ(11, 0x800)
+BUILD_IRQ(12, 0x1000)
+BUILD_IRQ(13, 0x2000)
+void mmu_bus_fault(void);      /* IRQ 14 is the bus fault interrupt */
+void multiple_interrupt(void); /* IRQ 15 is the multiple IRQ interrupt */
+BUILD_IRQ(16, 0x10000)
+BUILD_IRQ(17, 0x20000)
+BUILD_IRQ(18, 0x40000)
+BUILD_IRQ(19, 0x80000)
+BUILD_IRQ(20, 0x100000)
+BUILD_IRQ(21, 0x200000)
+BUILD_IRQ(22, 0x400000)
+BUILD_IRQ(23, 0x800000)
+BUILD_IRQ(24, 0x1000000)
+BUILD_IRQ(25, 0x2000000)
+ 
+/*
+ * Pointers to the low-level handlers 
+ */
+
+static void (*interrupt[NR_IRQS])(void) = {
+	NULL, NULL, IRQ2_interrupt, IRQ3_interrupt,
+	IRQ4_interrupt, IRQ5_interrupt, IRQ6_interrupt, IRQ7_interrupt,
+	IRQ8_interrupt, IRQ9_interrupt, IRQ10_interrupt, IRQ11_interrupt,
+	IRQ12_interrupt, IRQ13_interrupt, NULL, NULL,	
+	IRQ16_interrupt, IRQ17_interrupt, IRQ18_interrupt, IRQ19_interrupt,	
+	IRQ20_interrupt, IRQ21_interrupt, IRQ22_interrupt, IRQ23_interrupt,	
+	IRQ24_interrupt, IRQ25_interrupt
+};
+
+static void (*sinterrupt[NR_IRQS])(void) = {
+	NULL, NULL, sIRQ2_interrupt, sIRQ3_interrupt,
+	sIRQ4_interrupt, sIRQ5_interrupt, sIRQ6_interrupt, sIRQ7_interrupt,
+	sIRQ8_interrupt, sIRQ9_interrupt, sIRQ10_interrupt, sIRQ11_interrupt,
+	sIRQ12_interrupt, sIRQ13_interrupt, NULL, NULL,	
+	sIRQ16_interrupt, sIRQ17_interrupt, sIRQ18_interrupt, sIRQ19_interrupt,	
+	sIRQ20_interrupt, sIRQ21_interrupt, sIRQ22_interrupt, sIRQ23_interrupt,	
+	sIRQ24_interrupt, sIRQ25_interrupt
+};
+
+static void (*bad_interrupt[NR_IRQS])(void) = {
+        NULL, NULL,
+	NULL, bad_IRQ3_interrupt,
+	bad_IRQ4_interrupt, bad_IRQ5_interrupt,
+	bad_IRQ6_interrupt, bad_IRQ7_interrupt,
+	bad_IRQ8_interrupt, bad_IRQ9_interrupt,
+	bad_IRQ10_interrupt, bad_IRQ11_interrupt,
+	bad_IRQ12_interrupt, bad_IRQ13_interrupt,
+	NULL, NULL,
+	bad_IRQ16_interrupt, bad_IRQ17_interrupt,
+	bad_IRQ18_interrupt, bad_IRQ19_interrupt,
+	bad_IRQ20_interrupt, bad_IRQ21_interrupt,
+	bad_IRQ22_interrupt, bad_IRQ23_interrupt,
+	bad_IRQ24_interrupt, bad_IRQ25_interrupt
+};
+
+/*
+ * Initial irq handlers.
+ */
+
+static struct irqaction *irq_action[NR_IRQS] = {
+	NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL,
+	NULL, NULL
+};
+
+int get_irq_list(char *buf)
+{
+	int i, len = 0;
+	struct irqaction * action;
+
+	for (i = 0; i < NR_IRQS; i++) {
+		action = irq_action[i];
+		if (!action) 
+			continue;
+		len += sprintf(buf+len, "%2d: %10u %c %s",
+			i, kstat.irqs[0][i],
+			(action->flags & SA_INTERRUPT) ? '+' : ' ',
+			action->name);
+		for (action = action->next; action; action = action->next) {
+			len += sprintf(buf+len, ",%s %s",
+				(action->flags & SA_INTERRUPT) ? " +" : "",
+				action->name);
+		}
+		len += sprintf(buf+len, "\n");
+	}
+	return len;
+}
+
+/* called by the assembler IRQ entry functions defined in irq.h
+ * to dispatch the interrupts to registred handlers
+ * interrupts are disabled upon entry - depending on if the
+ * interrupt was registred with SA_INTERRUPT or not, interrupts
+ * are re-enabled or not.
+ */
+
+asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
+{
+	struct irqaction *action;
+	int do_random, cpu;
+
+        cpu = smp_processor_id();
+        irq_enter(cpu);
+	kstat.irqs[cpu][irq]++;
+
+	action = *(irq + irq_action);
+        if (action) {
+                if (!(action->flags & SA_INTERRUPT))
+                        __sti();
+                action = *(irq + irq_action);
+                do_random = 0;
+                do {
+                        do_random |= action->flags;
+                        action->handler(irq, action->dev_id, regs);
+                        action = action->next;
+                } while (action);
+                if (do_random & SA_SAMPLE_RANDOM)
+                        add_interrupt_randomness(irq);
+                __cli();
+        }
+        irq_exit(cpu);
+
+	if (softirq_active(cpu) & softirq_mask(cpu))
+                do_softirq();
+
+        /* unmasking and bottom half handling is done magically for us. */
+}
+
+/* this function links in a handler into the chain of handlers for the
+   given irq, and if the irq has never been registred, the appropriate
+   handler is entered into the interrupt vector
+*/
+
+int setup_etrax_irq(int irq, struct irqaction * new)
+{
+	int shared = 0;
+	struct irqaction *old, **p;
+	unsigned long flags;
+
+	p = irq_action + irq;
+	if ((old = *p) != NULL) {
+		/* Can't share interrupts unless both agree to */
+		if (!(old->flags & new->flags & SA_SHIRQ))
+			return -EBUSY;
+
+		/* Can't share interrupts unless both are same type */
+		if ((old->flags ^ new->flags) & SA_INTERRUPT)
+			return -EBUSY;
+
+		/* add new interrupt at end of irq queue */
+		do {
+			p = &old->next;
+			old = *p;
+		} while (old);
+		shared = 1;
+	}
+
+	if (new->flags & SA_SAMPLE_RANDOM)
+		rand_initialize_irq(irq);
+
+	save_flags(flags);
+	cli();
+	*p = new;
+
+	if (!shared) {
+		/* if the irq wasn't registred before, enter it into the vector table
+		   and unmask it physically 
+		*/
+		set_int_vector(irq, interrupt[irq], sinterrupt[irq]);
+		unmask_irq(irq);
+	}
+	
+	restore_flags(flags);
+	return 0;
+}
+
+/* this function is called by a driver to register an irq handler
+   Valid flags:
+   SA_INTERRUPT -> it's a fast interrupt, handler called with irq disabled and
+                   no signal checking etc is performed upon exit
+   SA_SHIRQ -> the interrupt can be shared between different handlers, the handler
+                is required to check if the irq was "aimed" at it explicitely
+   SA_RANDOM -> the interrupt will add to the random generators entropy
+*/
+
+int request_irq(unsigned int irq, 
+		void (*handler)(int, void *, struct pt_regs *),
+		unsigned long irqflags, 
+		const char * devname,
+		void *dev_id)
+{
+	int retval;
+	struct irqaction * action;
+
+	/* interrupts 0 and 1 are hardware breakpoint and NMI and we can't support
+	   these yet. interrupt 15 is the multiple irq, it's special. */
+
+	if(irq < 2 || irq == 15 || irq >= NR_IRQS)
+		return -EINVAL;
+
+	if(!handler)
+		return -EINVAL;
+
+	/* allocate and fill in a handler structure and setup the irq */
+
+	action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+	if (!action)
+		return -ENOMEM;
+
+	action->handler = handler;
+	action->flags = irqflags;
+	action->mask = 0;
+	action->name = devname;
+	action->next = NULL;
+	action->dev_id = dev_id;
+
+	retval = setup_etrax_irq(irq, action);
+
+	if (retval)
+		kfree(action);
+	return retval;
+}
+		
+void free_irq(unsigned int irq, void *dev_id)
+{
+	struct irqaction * action, **p;
+	unsigned long flags;
+
+	if (irq >= NR_IRQS) {
+		printk("Trying to free IRQ%d\n",irq);
+		return;
+	}
+	for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) {
+		if (action->dev_id != dev_id)
+			continue;
+
+		/* Found it - now free it */
+		save_flags(flags);
+		cli();
+		*p = action->next;
+		if (!irq[irq_action]) {
+			mask_irq(irq);
+			set_int_vector(irq, bad_interrupt[irq], 0);
+		}
+		restore_flags(flags);
+		kfree(action);
+		return;
+	}
+	printk("Trying to free free IRQ%d\n",irq);
+}
+
+void weird_irq(void)
+{
+	__asm__("di");
+	printk("weird irq\n");
+	while(1);
+}
+
+/* init_IRQ() is called by start_kernel and is responsible for fixing IRQ masks and
+   setting the irq vector table to point to bad_interrupt ptrs.
+*/
+
+void system_call(void);  /* from entry.S */
+
+void init_IRQ(void)
+{
+	int i;
+
+	/* clear all interrupt masks */
+
+#ifndef CONFIG_SVINTO_SIM
+	*R_IRQ_MASK0_CLR = 0xffffffff;
+	*R_IRQ_MASK1_CLR = 0xffffffff;
+	*R_IRQ_MASK2_CLR = 0xffffffff;
+#endif
+
+	*R_VECT_MASK_CLR = 0xffffffff;
+
+	/* clear the shortcut entry points */
+
+	for(i = 0; i < NR_IRQS; i++)
+		irq_shortcuts[i] = NULL;
+	
+	for (i = 0; i < 256; i++)
+		etrax_irv->v[i] = weird_irq;
+      
+	/* set all etrax irq's to the bad handlers */
+	for (i = 2; i < NR_IRQS; i++)
+		set_int_vector(i, bad_interrupt[i], 0);
+
+	/* except IRQ 15 which is the multiple-IRQ handler on Etrax100 */
+
+	set_int_vector(15, multiple_interrupt, 0);
+	
+	/* 0 and 1 which are special breakpoint/NMI traps */
+
+	set_int_vector(0, hwbreakpoint, 0);
+	set_int_vector(1, IRQ1_interrupt, 0);
+
+	/* and irq 14 which is the mmu bus fault handler */
+
+	set_int_vector(14, mmu_bus_fault, 0);
+
+	/* setup the system-call trap, which is reached by BREAK 13 */
+
+	set_break_vector(13, system_call);
+
+#ifdef CONFIG_KGDB
+	/* setup kgdb if its enabled, and break into the debugger */
+
+	kgdb_init();
+
+	breakpoint();
+#endif
+
+} 
diff -urN linux-2.4.2-pre1/arch/cris/kernel/kgdb.c linux/arch/cris/kernel/kgdb.c
--- linux-2.4.2-pre1/arch/cris/kernel/kgdb.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/kernel/kgdb.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,1540 @@
+/*!**************************************************************************
+*!
+*! FILE NAME  : kgdb.c
+*!
+*! DESCRIPTION: Implementation of the gdb stub with respect to ETRAX 100.
+*!              It is a mix of arch/m68k/kernel/kgdb.c and cris_stub.c.
+*!
+*!---------------------------------------------------------------------------
+*! HISTORY
+*!
+*! DATE         NAME            CHANGES
+*! ----         ----            -------
+*! Apr 26 1999  Hendrik Ruijter Initial version.
+*! May  6 1999  Hendrik Ruijter Removed call to strlen in libc and removed
+*!                              struct assignment as it generates calls to
+*!                              memcpy in libc.
+*! Jun 17 1999  Hendrik Ruijter Added gdb 4.18 support. 'X', 'qC' and 'qL'.
+*! Jul 21 1999  Bjorn Wesen     eLinux port
+*!
+*! $Log: kgdb.c,v $
+*! Revision 1.2  2001/01/12 14:22:25  orjanf
+*! Updated kernel debugging support to work with ETRAX 100LX.
+*!
+*! Revision 1.1  2000/07/10 16:25:21  bjornw
+*! Initial revision
+*!
+*! Revision 1.1.1.1  1999/12/03 14:57:31  bjornw
+*! * Initial version of arch/cris, the latest CRIS architecture with an MMU.
+*!   Mostly copied from arch/etrax100 with appropriate renames of files.
+*!   The mm/ subdir is copied from arch/i386.
+*!   This does not compile yet at all.
+*!
+*!
+*! Revision 1.4  1999/07/22 17:25:25  bjornw
+*! Dont wait for + in putpacket if we havent hit the initial breakpoint yet. Added a kgdb_init function which sets up the break and irq vectors.
+*!
+*! Revision 1.3  1999/07/21 19:51:18  bjornw
+*! Check if the interrupting char is a ctrl-C, ignore otherwise.
+*!
+*! Revision 1.2  1999/07/21 18:09:39  bjornw
+*! Ported to eLinux architecture, and added some kgdb documentation.
+*!
+*!
+*!---------------------------------------------------------------------------
+*!
+*! $Id: kgdb.c,v 1.2 2001/01/12 14:22:25 orjanf Exp $
+*!
+*! (C) Copyright 1999, Axis Communications AB, LUND, SWEDEN
+*!
+*!**************************************************************************/
+/* @(#) cris_stub.c 1.3 06/17/99 */
+
+/*
+ *  kgdb usage notes:
+ *  -----------------
+ *
+ * If you select CONFIG_KGDB in the configuration, the kernel will be built
+ * with different gcc flags: "-g" is added to get debug infos, and
+ * "-fomit-frame-pointer" is omitted to make debugging easier. Since the
+ * resulting kernel will be quite big (approx. > 7 MB), it will be stripped
+ * before compresion. Such a kernel will behave just as usually, except if
+ * given a "debug=<device>" command line option. (Only serial devices are
+ * allowed for <device>, i.e. no printers or the like; possible values are
+ * machine depedend and are the same as for the usual debug device, the one
+ * for logging kernel messages.) If that option is given and the device can be
+ * initialized, the kernel will connect to the remote gdb in trap_init(). The
+ * serial parameters are fixed to 8N1 and 115200 bps, for easyness of
+ * implementation.
+ *
+ * To start a debugging session, start that gdb with the debugging kernel
+ * image (the one with the symbols, vmlinux.debug) named on the command line.
+ * This file will be used by gdb to get symbol and debugging infos about the
+ * kernel. Next, select remote debug mode by
+ *    target remote <device>
+ * where <device> is the name of the serial device over which the debugged
+ * machine is connected. Maybe you have to adjust the baud rate by
+ *    set remotebaud <rate>
+ * or also other parameters with stty:
+ *    shell stty ... </dev/...
+ * If the kernel to debug has already booted, it waited for gdb and now
+ * connects, and you'll see a breakpoint being reported. If the kernel isn't
+ * running yet, start it now. The order of gdb and the kernel doesn't matter.
+ * Another thing worth knowing about in the getting-started phase is how to
+ * debug the remote protocol itself. This is activated with
+ *    set remotedebug 1
+ * gdb will then print out each packet sent or received. You'll also get some
+ * messages about the gdb stub on the console of the debugged machine.
+ *
+ * If all that works, you can use lots of the usual debugging techniques on
+ * the kernel, e.g. inspecting and changing variables/memory, setting
+ * breakpoints, single stepping and so on. It's also possible to interrupt the
+ * debugged kernel by pressing C-c in gdb. Have fun! :-)
+ *
+ * The gdb stub is entered (and thus the remote gdb gets control) in the
+ * following situations:
+ *
+ *  - If breakpoint() is called. This is just after kgdb initialization, or if
+ *    a breakpoint() call has been put somewhere into the kernel source.
+ *    (Breakpoints can of course also be set the usual way in gdb.)
+ *    In eLinux, we call breakpoint() in init/main.c after IRQ initialization.
+ *
+ *  - If there is a kernel exception, i.e. bad_super_trap() or die_if_kernel()
+ *    are entered. All the CPU exceptions are mapped to (more or less..., see
+ *    the hard_trap_info array below) appropriate signal, which are reported
+ *    to gdb. die_if_kernel() is usually called after some kind of access
+ *    error and thus is reported as SIGSEGV.
+ *
+ *  - When panic() is called. This is reported as SIGABRT.
+ *
+ *  - If C-c is received over the serial line, which is treated as
+ *    SIGINT.
+ *
+ * Of course, all these signals are just faked for gdb, since there is no
+ * signal concept as such for the kernel. It also isn't possible --obviously--
+ * to set signal handlers from inside gdb, or restart the kernel with a
+ * signal.
+ *
+ * Current limitations:
+ *
+ *  - While the kernel is stopped, interrupts are disabled for safety reasons
+ *    (i.e., variables not changing magically or the like). But this also
+ *    means that the clock isn't running anymore, and that interrupts from the
+ *    hardware may get lost/not be served in time. This can cause some device
+ *    errors...
+ *
+ *  - When single-stepping, only one instruction of the current thread is
+ *    executed, but interrupts are allowed for that time and will be serviced
+ *    if pending. Be prepared for that.
+ *
+ *  - All debugging happens in kernel virtual address space. There's no way to
+ *    access physical memory not mapped in kernel space, or to access user
+ *    space. A way to work around this is using get_user_long & Co. in gdb
+ *    expressions, but only for the current process.
+ *
+ *  - Interrupting the kernel only works if interrupts are currently allowed,
+ *    and the interrupt of the serial line isn't blocked by some other means
+ *    (IPL too high, disabled, ...)
+ *
+ *  - The gdb stub is currently not reentrant, i.e. errors that happen therein
+ *    (e.g. accesing invalid memory) may not be caught correctly. This could
+ *    be removed in future by introducing a stack of struct registers.
+ *
+ */
+
+/*
+ *  To enable debugger support, two things need to happen.  One, a
+ *  call to kgdb_init() is necessary in order to allow any breakpoints
+ *  or error conditions to be properly intercepted and reported to gdb.
+ *  Two, a breakpoint needs to be generated to begin communication.  This
+ *  is most easily accomplished by a call to breakpoint(). 
+ *
+ *    The following gdb commands are supported:
+ *
+ * command          function                               Return value
+ *
+ *    g             return the value of the CPU registers  hex data or ENN
+ *    G             set the value of the CPU registers     OK or ENN
+ *
+ *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
+ *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
+ *
+ *    c             Resume at current address              SNN   ( signal NN)
+ *    cAA..AA       Continue at address AA..AA             SNN
+ *
+ *    s             Step one instruction                   SNN
+ *    sAA..AA       Step one instruction from AA..AA       SNN
+ *
+ *    k             kill
+ *
+ *    ?             What was the last sigval ?             SNN   (signal NN)
+ *
+ *    bBB..BB	    Set baud rate to BB..BB		   OK or BNN, then sets
+ *							   baud rate
+ *
+ * All commands and responses are sent with a packet which includes a
+ * checksum.  A packet consists of
+ *
+ * $<packet info>#<checksum>.
+ *
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum>    :: < two hex digits computed as modulo 256 sum of <packetinfo>>
+ *
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer.  '-' indicates a failed transfer.
+ *
+ * Example:
+ *
+ * Host:                  Reply:
+ * $m0,10#2a               +$00010203040506070809101112131415#42
+ *
+ */
+
+
+#include <linux/string.h>
+#include <linux/signal.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/linkage.h>
+
+#include <asm/setup.h>
+#include <asm/ptrace.h>
+
+#include <asm/svinto.h>
+#include <asm/irq.h>
+
+static int kgdb_started = 0;
+
+/********************************* Register image ****************************/
+/* Use the order of registers as defined in "AXIS ETRAX CRIS Programmer's
+   Reference", p. 1-1, with the additional register definitions of the
+   ETRAX 100LX in cris-opc.h.
+   There are 16 general 32-bit registers, R0-R15, where R14 is the stack
+   pointer, SP, and R15 is the program counter, PC.
+   There are 16 special registers, P0-P15, where three of the unimplemented
+   registers, P0, P4 and P8, are reserved as zero-registers. A read from
+   any of these registers returns zero and a write has no effect. */
+
+typedef
+struct register_image
+{
+	/* Offset */
+	unsigned int     r0;   /* 0x00 */
+	unsigned int     r1;   /* 0x04 */
+	unsigned int     r2;   /* 0x08 */
+	unsigned int     r3;   /* 0x0C */
+	unsigned int     r4;   /* 0x10 */
+	unsigned int     r5;   /* 0x14 */
+	unsigned int     r6;   /* 0x18 */
+	unsigned int     r7;   /* 0x1C */
+	unsigned int     r8;   /* 0x20 Frame pointer */
+	unsigned int     r9;   /* 0x24 */
+	unsigned int    r10;   /* 0x28 */
+	unsigned int    r11;   /* 0x2C */
+	unsigned int    r12;   /* 0x30 */
+	unsigned int    r13;   /* 0x34 */
+	unsigned int     sp;   /* 0x38 Stack pointer */
+	unsigned int     pc;   /* 0x3C Program counter */
+
+        unsigned char    p0;   /* 0x40 8-bit zero-register */
+	unsigned char    vr;   /* 0x41 Version register */
+
+        unsigned short   p4;   /* 0x42 16-bit zero-register */
+	unsigned short  ccr;   /* 0x44 Condition code register */
+	
+	unsigned int    mof;   /* 0x46 Multiply overflow register */
+	
+        unsigned int     p8;   /* 0x4A 32-bit zero-register */
+	unsigned int    ibr;   /* 0x4E Interrupt base register */
+	unsigned int    irp;   /* 0x52 Interrupt return pointer */
+	unsigned int    srp;   /* 0x56 Subroutine return pointer */
+	unsigned int    bar;   /* 0x5A Breakpoint address register */
+	unsigned int   dccr;   /* 0x5E Double condition code register */
+	unsigned int    brp;   /* 0x62 Breakpoint return pointer (pc in caller) */
+	unsigned int    usp;   /* 0x66 User mode stack pointer */
+} registers;
+
+/************** Prototypes for local library functions ***********************/
+
+/* Copy of strcpy from libc. */
+static char *gdb_cris_strcpy (char *s1, const char *s2);
+
+/* Copy of strlen from libc. */
+static int gdb_cris_strlen (const char *s);
+
+/* Copy of memchr from libc. */
+static void *gdb_cris_memchr (const void *s, int c, int n);
+
+/* Copy of strtol from libc. Does only support base 16. */
+static int gdb_cris_strtol (const char *s, char **endptr, int base);
+
+/********************** Prototypes for local functions. **********************/
+/* Copy the content of a register image into another. The size n is
+   the size of the register image. Due to struct assignment generation of
+   memcpy in libc. */
+static void copy_registers (registers *dptr, registers *sptr, int n);
+
+/* Copy the stored registers from the stack. Put the register contents
+   of thread thread_id in the struct reg. */
+static void copy_registers_from_stack (int thread_id, registers *reg);
+
+/* Copy the registers to the stack. Put the register contents of thread
+   thread_id from struct reg to the stack. */
+static void copy_registers_to_stack (int thread_id, registers *reg);
+
+/* Write a value to a specified register regno in the register image
+   of the current thread. */
+static int write_register (int regno, char *val);
+
+/* Write a value to a specified register in the stack of a thread other
+   than the current thread. */
+static write_stack_register (int thread_id, int regno, char *valptr);
+
+/* Read a value from a specified register in the register image. Returns the
+   status of the read operation. The register value is returned in valptr. */
+static int read_register (char regno, unsigned int *valptr);
+
+/* Serial port, reads one character. ETRAX 100 specific. from debugport.c */
+int getDebugChar (void);
+
+/* Serial port, writes one character. ETRAX 100 specific. from debugport.c */
+void putDebugChar (int val);
+
+void enableDebugIRQ (void);
+
+/* Returns the character equivalent of a nibble, bit 7, 6, 5, and 4 of a byte,
+   represented by int x. */
+static char highhex (int x);
+
+/* Returns the character equivalent of a nibble, bit 3, 2, 1, and 0 of a byte,
+   represented by int x. */
+static char lowhex (int x);
+
+/* Returns the integer equivalent of a hexadecimal character. */
+static int hex (char ch);
+
+/* Convert the memory, pointed to by mem into hexadecimal representation.
+   Put the result in buf, and return a pointer to the last character
+   in buf (null). */
+static char *mem2hex (char *buf, unsigned char *mem, int count);
+
+/* Convert the array, in hexadecimal representation, pointed to by buf into
+   binary representation. Put the result in mem, and return a pointer to
+   the character after the last byte written. */
+static unsigned char *hex2mem (unsigned char *mem, char *buf, int count);
+
+/* Put the content of the array, in binary representation, pointed to by buf
+   into memory pointed to by mem, and return a pointer to
+   the character after the last byte written. */
+static unsigned char *bin2mem (unsigned char *mem, unsigned char *buf, int count);
+
+/* Await the sequence $<data>#<checksum> and store <data> in the array buffer
+   returned. */
+static void getpacket (char *buffer);
+
+/* Send $<data>#<checksum> from the <data> in the array buffer. */
+static void putpacket (char *buffer);
+
+/* Build and send a response packet in order to inform the host the
+   stub is stopped. */
+static void stub_is_stopped (int sigval);
+
+/* All expected commands are sent from remote.c. Send a response according
+   to the description in remote.c. */
+static void handle_exception (int sigval);
+
+/* Performs a complete re-start from scratch. ETRAX specific. */
+static void kill_restart (void);
+
+/******************** Prototypes for global functions. ***********************/
+
+/* The string str is prepended with the GDB printout token and sent. */
+void putDebugString (const unsigned char *str, int length); /* used by etrax100ser.c */
+
+/* The hook for both static (compiled) and dynamic breakpoints set by GDB.
+   ETRAX 100 specific. */
+void handle_breakpoint (void);                          /* used by irq.c */
+
+/* The hook for an interrupt generated by GDB. ETRAX 100 specific. */
+void handle_interrupt (void);                           /* used by irq.c */
+
+/* A static breakpoint to be used at startup. */
+void breakpoint (void);                                 /* called by init/main.c */
+
+/* From osys_int.c, executing_task contains the number of the current
+   executing task in osys. Does not know of object-oriented threads. */
+extern unsigned char executing_task;
+
+/* The number of characters used for a 64 bit thread identifier. */
+#define HEXCHARS_IN_THREAD_ID 16
+
+/* Avoid warning as the internal_stack is not used in the C-code. */
+#define USEDVAR(name)    { if (name) { ; } }
+#define USEDFUN(name) { void (*pf)(void) = (void *)name; USEDVAR(pf) }
+
+/********************************** Packet I/O ******************************/
+/* BUFMAX defines the maximum number of characters in
+   inbound/outbound buffers */
+#define BUFMAX 512
+
+/* Run-length encoding maximum length. Send 64 at most. */
+#define RUNLENMAX 64
+
+/* Definition of all valid hexadecimal characters */
+static const char hexchars[] = "0123456789abcdef";
+
+/* The inbound/outbound buffers used in packet I/O */
+static char remcomInBuffer[BUFMAX];
+static char remcomOutBuffer[BUFMAX];
+
+/* Error and warning messages. */
+enum error_type
+{
+	SUCCESS, E01, E02, E03, E04, E05, E06, E07
+};
+static char *error_message[] =
+{
+	"",
+	"E01 Set current or general thread - H[c,g] - internal error.",
+	"E02 Change register content - P - cannot change read-only register.",
+	"E03 Thread is not alive.", /* T, not used. */
+	"E04 The command is not supported - [s,C,S,!,R,d,r] - internal error.",
+	"E05 Change register content - P - the register is not implemented..",
+	"E06 Change memory content - M - internal error.",
+	"E07 Change register content - P - the register is not stored on the stack"
+};
+/********************************* Register image ****************************/
+/* Use the order of registers as defined in "AXIS ETRAX CRIS Programmer's
+   Reference", p. 1-1, with the additional register definitions of the
+   ETRAX 100LX in cris-opc.h.
+   There are 16 general 32-bit registers, R0-R15, where R14 is the stack
+   pointer, SP, and R15 is the program counter, PC.
+   There are 16 special registers, P0-P15, where three of the unimplemented
+   registers, P0, P4 and P8, are reserved as zero-registers. A read from
+   any of these registers returns zero and a write has no effect. */
+enum register_name
+{
+	R0,  R1,   R2,  R3,
+	R4,  R5,   R6,  R7,
+	R8,  R9,   R10, R11,
+	R12, R13,  SP,  PC,
+	P0,  VR,   P2,  P3,
+	P4,  CCR,  P6,  MOF,
+	P8,  IBR,  IRP, SRP,
+	BAR, DCCR, BRP, USP
+};
+
+/* The register sizes of the registers in register_name. An unimplemented register
+   is designated by size 0 in this array. */
+static int register_size[] =
+{
+	4, 4, 4, 4,
+	4, 4, 4, 4,
+	4, 4, 4, 4,
+	4, 4, 4, 4,
+	1, 1, 0, 0,
+	2, 2, 0, 4,
+	4, 4, 4, 4,
+	4, 4, 4, 4
+};
+
+/* Contains the register image of the executing thread in the assembler
+   part of the code in order to avoid horrible addressing modes. */
+static registers reg;
+
+/* FIXME: Should this be used? Delete otherwise. */
+/* Contains the assumed consistency state of the register image. Uses the
+   enum error_type for state information. */
+static int consistency_status = SUCCESS;
+
+/********************************** Handle exceptions ************************/
+/* The variable reg contains the register image associated with the
+   current_thread_c variable. It is a complete register image created at
+   entry. The reg_g contains a register image of a task where the general
+   registers are taken from the stack and all special registers are taken
+   from the executing task. It is associated with current_thread_g and used
+   in order to provide access mainly for 'g', 'G' and 'P'.
+*/
+
+/* Need two task id pointers in order to handle Hct and Hgt commands. */
+static int current_thread_c = 0;
+static int current_thread_g = 0;
+
+/* Need two register images in order to handle Hct and Hgt commands. The
+   variable reg_g is in addition to reg above. */
+static registers reg_g;
+
+/********************************** Breakpoint *******************************/
+/* Use an internal stack in the breakpoint and interrupt response routines */
+#define INTERNAL_STACK_SIZE 1024
+static char internal_stack[INTERNAL_STACK_SIZE];
+
+/* Due to the breakpoint return pointer, a state variable is needed to keep
+   track of whether it is a static (compiled) or dynamic (gdb-invoked)
+   breakpoint to be handled. A static breakpoint uses the content of register
+   BRP as it is whereas a dynamic breakpoint requires subtraction with 2
+   in order to execute the instruction. The first breakpoint is static. */
+static unsigned char is_dyn_brkp = 0;
+
+/********************************* String library ****************************/
+/* Single-step over library functions creates trap loops. */
+
+/* Copy char s2[] to s1[]. */
+static char*
+gdb_cris_strcpy (char *s1, const char *s2)
+{
+	char *s = s1;
+	
+	for (s = s1; (*s++ = *s2++) != '\0'; )
+		;
+	return (s1);
+}
+
+/* Find length of s[]. */
+static int
+gdb_cris_strlen (const char *s)
+{
+	const char *sc;
+	
+	for (sc = s; *sc != '\0'; sc++)
+		;
+	return (sc - s);
+}
+
+/* Find first occurrence of c in s[n]. */
+static void*
+gdb_cris_memchr (const void *s, int c, int n)
+{
+	const unsigned char uc = c;
+	const unsigned char *su;
+	
+	for (su = s; 0 < n; ++su, --n)
+		if (*su == uc)
+			return ((void *)su);
+	return (NULL);
+}
+/******************************* Standard library ****************************/
+/* Single-step over library functions creates trap loops. */
+/* Convert string to long. */
+static int
+gdb_cris_strtol (const char *s, char **endptr, int base)
+{
+	char *s1;
+	char *sd;
+	int x = 0;
+	
+	for (s1 = (char*)s; (sd = gdb_cris_memchr(hexchars, *s1, base)) != NULL; ++s1)
+		x = x * base + (sd - hexchars);
+        
+        if (endptr)
+        {
+                /* Unconverted suffix is stored in endptr unless endptr is NULL. */
+                *endptr = s1;
+        }
+        
+	return x;
+}
+
+int
+double_this(int x)
+{
+        return 2 * x;
+}
+
+/********************************* Register image ****************************/
+/* Copy the content of a register image into another. The size n is
+   the size of the register image. Due to struct assignment generation of
+   memcpy in libc. */
+static void
+copy_registers (registers *dptr, registers *sptr, int n)
+{
+	unsigned char *dreg;
+	unsigned char *sreg;
+	
+	for (dreg = (unsigned char*)dptr, sreg = (unsigned char*)sptr; n > 0; n--)
+		*dreg++ = *sreg++;
+}
+
+#ifdef PROCESS_SUPPORT
+/* Copy the stored registers from the stack. Put the register contents
+   of thread thread_id in the struct reg. */
+static void
+copy_registers_from_stack (int thread_id, registers *regptr)
+{
+	int j;
+	stack_registers *s = (stack_registers *)stack_list[thread_id];
+	unsigned int *d = (unsigned int *)regptr;
+	
+	for (j = 13; j >= 0; j--)
+		*d++ = s->r[j];
+	regptr->sp = (unsigned int)stack_list[thread_id];
+	regptr->pc = s->pc;
+	regptr->dccr = s->dccr;
+	regptr->srp = s->srp;
+}
+
+/* Copy the registers to the stack. Put the register contents of thread
+   thread_id from struct reg to the stack. */
+static void
+copy_registers_to_stack (int thread_id, registers *regptr)
+{
+	int i;
+	stack_registers *d = (stack_registers *)stack_list[thread_id];
+	unsigned int *s = (unsigned int *)regptr;
+	
+	for (i = 0; i < 14; i++) {
+		d->r[i] = *s++;
+	}
+	d->pc = regptr->pc;
+	d->dccr = regptr->dccr;
+	d->srp = regptr->srp;
+}
+#endif
+
+/* Write a value to a specified register in the register image of the current
+   thread. Returns status code SUCCESS, E02 or E05. */
+static int
+write_register (int regno, char *val)
+{
+	int status = SUCCESS;
+	registers *current_reg = &reg;
+
+        if (regno >= R0 && regno <= PC) {
+		/* 32-bit register with simple offset. */
+		hex2mem ((unsigned char *)current_reg + regno * sizeof(unsigned int),
+			 val, sizeof(unsigned int));
+	}
+        else if (regno == P0 || regno == VR || regno == P4 || regno == P8) {
+		/* Do not support read-only registers. */
+		status = E02;
+	}
+        else if (regno == CCR) {
+		/* 16 bit register with complex offset. (P4 is read-only, P6 is not implemented, 
+                   and P7 (MOF) is 32 bits in ETRAX 100LX. */
+		hex2mem ((unsigned char *)&(current_reg->ccr) + (regno-CCR) * sizeof(unsigned short),
+			 val, sizeof(unsigned short));
+	}
+	else if (regno >= MOF && regno <= USP) {
+		/* 32 bit register with complex offset.  (P8 has been taken care of.) */
+		hex2mem ((unsigned char *)&(current_reg->ibr) + (regno-IBR) * sizeof(unsigned int),
+			 val, sizeof(unsigned int));
+	} 
+        else {
+		/* Do not support nonexisting or unimplemented registers (P2, P3, and P6). */
+		status = E05;
+	}
+	return status;
+}
+
+#ifdef PROCESS_SUPPORT
+/* Write a value to a specified register in the stack of a thread other
+   than the current thread. Returns status code SUCCESS or E07. */
+static int
+write_stack_register (int thread_id, int regno, char *valptr)
+{
+	int status = SUCCESS;
+	stack_registers *d = (stack_registers *)stack_list[thread_id];
+	unsigned int val;
+	
+	hex2mem ((unsigned char *)&val, valptr, sizeof(unsigned int));
+	if (regno >= R0 && regno < SP) {
+		d->r[regno] = val;
+	}
+	else if (regno == SP) {
+		stack_list[thread_id] = val;
+	}
+	else if (regno == PC) {
+		d->pc = val;
+	}
+	else if (regno == SRP) {
+		d->srp = val;
+	}
+	else if (regno == DCCR) {
+		d->dccr = val;
+	}
+	else {
+		/* Do not support registers in the current thread. */
+		status = E07;
+	}
+	return status;
+}
+#endif
+
+/* Read a value from a specified register in the register image. Returns the
+   value in the register or -1 for non-implemented registers.
+   Should check consistency_status after a call which may be E05 after changes
+   in the implementation. */
+static int
+read_register (char regno, unsigned int *valptr)
+{
+	registers *current_reg = &reg;
+
+	if (regno >= R0 && regno <= PC) {
+		/* 32-bit register with simple offset. */
+		*valptr = *(unsigned int *)((char *)current_reg + regno * sizeof(unsigned int));
+                return SUCCESS;
+	}
+	else if (regno == P0 || regno == VR) {
+		/* 8 bit register with complex offset. */
+		*valptr = (unsigned int)(*(unsigned char *)
+                                         ((char *)&(current_reg->p0) + (regno-P0) * sizeof(char)));
+                return SUCCESS;
+	}
+	else if (regno == P4 || regno == CCR) {
+		/* 16 bit register with complex offset. */
+		*valptr = (unsigned int)(*(unsigned short *)
+                                         ((char *)&(current_reg->p4) + (regno-P4) * sizeof(unsigned short)));
+                return SUCCESS;
+	}
+	else if (regno >= MOF && regno <= USP) {
+		/* 32 bit register with complex offset. */
+		*valptr = *(unsigned int *)((char *)&(current_reg->p8)
+                                            + (regno-P8) * sizeof(unsigned int));
+                return SUCCESS;
+	}
+	else {
+		/* Do not support nonexisting or unimplemented registers (P2, P3, and P6). */
+		consistency_status = E05;
+		return E05;
+	}
+}
+
+/********************************** Packet I/O ******************************/
+/* Returns the character equivalent of a nibble, bit 7, 6, 5, and 4 of a byte,
+   represented by int x. */
+static inline char
+highhex(int x)
+{
+	return hexchars[(x >> 4) & 0xf];
+}
+
+/* Returns the character equivalent of a nibble, bit 3, 2, 1, and 0 of a byte,
+   represented by int x. */
+static inline char
+lowhex(int x)
+{
+	return hexchars[x & 0xf];
+}
+
+/* Returns the integer equivalent of a hexadecimal character. */
+static int
+hex (char ch)
+{
+	if ((ch >= 'a') && (ch <= 'f'))
+		return (ch - 'a' + 10);
+	if ((ch >= '0') && (ch <= '9'))
+		return (ch - '0');
+	if ((ch >= 'A') && (ch <= 'F'))
+		return (ch - 'A' + 10);
+	return (-1);
+}
+
+/* Convert the memory, pointed to by mem into hexadecimal representation.
+   Put the result in buf, and return a pointer to the last character
+   in buf (null). */
+
+static int do_printk = 0;
+
+static char *
+mem2hex(char *buf, unsigned char *mem, int count)
+{
+	int i;
+	int ch;
+        
+        if (mem == NULL) {
+                /* Bogus read from m0. FIXME: What constitutes a valid address? */
+                for (i = 0; i < count; i++) {
+                        *buf++ = '0';
+                        *buf++ = '0';
+                }
+        } else {
+                /* Valid mem address. */
+                for (i = 0; i < count; i++) {
+                        ch = *mem++;
+                        *buf++ = highhex (ch);
+                        *buf++ = lowhex (ch);
+                }
+        }
+        
+        /* Terminate properly. */
+	*buf = '\0';
+	return (buf);
+}
+
+/* Convert the array, in hexadecimal representation, pointed to by buf into
+   binary representation. Put the result in mem, and return a pointer to
+   the character after the last byte written. */
+static unsigned char*
+hex2mem (unsigned char *mem, char *buf, int count)
+{
+	int i;
+	unsigned char ch;
+	for (i = 0; i < count; i++) {
+		ch = hex (*buf++) << 4;
+		ch = ch + hex (*buf++);
+		*mem++ = ch;
+	}
+	return (mem);
+}
+
+/* Put the content of the array, in binary representation, pointed to by buf
+   into memory pointed to by mem, and return a pointer to the character after
+   the last byte written.
+   Gdb will escape $, #, and the escape char (0x7d). */
+static unsigned char*
+bin2mem (unsigned char *mem, unsigned char *buf, int count)
+{
+	int i;
+	unsigned char *next;
+	for (i = 0; i < count; i++) {
+		/* Check for any escaped characters. Be paranoid and
+		   only unescape chars that should be escaped. */
+		if (*buf == 0x7d) {
+			next = buf + 1;
+			if (*next == 0x3 || *next == 0x4 || *next == 0x5D) /* #, $, ESC */
+				{
+					buf++;
+					*buf += 0x20;
+				}
+		}
+		*mem++ = *buf++;
+	}
+	return (mem);
+}
+
+/* Await the sequence $<data>#<checksum> and store <data> in the array buffer
+   returned. */
+static void
+getpacket (char *buffer)
+{
+	unsigned char checksum;
+	unsigned char xmitcsum;
+	int i;
+	int count;
+	char ch;
+	do {
+		while ((ch = getDebugChar ()) != '$')
+			/* Wait for the start character $ and ignore all other characters */;
+		checksum = 0;
+		xmitcsum = -1;
+		count = 0;
+		/* Read until a # or the end of the buffer is reached */
+		while (count < BUFMAX) {
+			ch = getDebugChar ();
+			if (ch == '#')
+				break;
+			checksum = checksum + ch;
+			buffer[count] = ch;
+			count = count + 1;
+		}
+		buffer[count] = '\0';
+		
+		if (ch == '#') {
+			xmitcsum = hex (getDebugChar ()) << 4;
+			xmitcsum += hex (getDebugChar ());
+			if (checksum != xmitcsum) {
+				/* Wrong checksum */
+				putDebugChar ('-');
+			}
+			else {
+				/* Correct checksum */
+				putDebugChar ('+');
+				/* If sequence characters are received, reply with them */
+				if (buffer[2] == ':') {
+					putDebugChar (buffer[0]);
+					putDebugChar (buffer[1]);
+					/* Remove the sequence characters from the buffer */
+					count = gdb_cris_strlen (buffer);
+					for (i = 3; i <= count; i++)
+						buffer[i - 3] = buffer[i];
+				}
+			}
+		}
+	} while (checksum != xmitcsum);
+}
+
+/* Send $<data>#<checksum> from the <data> in the array buffer. */
+
+static void
+putpacket(char *buffer)
+{
+	int checksum;
+	int runlen;
+	int encode;
+	
+	do {
+		char *src = buffer;
+		putDebugChar ('$');
+		checksum = 0;
+		while (*src) {
+			/* Do run length encoding */
+			putDebugChar (*src);
+			checksum += *src;
+			runlen = 0;
+			while (runlen < RUNLENMAX && *src == src[runlen]) {
+				runlen++;
+			}
+			if (runlen > 3) {
+				/* Got a useful amount */
+				putDebugChar ('*');
+				checksum += '*';
+				encode = runlen + ' ' - 4;
+				putDebugChar (encode);
+				checksum += encode;
+				src += runlen;
+			}
+			else {
+				src++;
+			}
+		}
+		putDebugChar ('#');
+		putDebugChar (highhex (checksum));
+		putDebugChar (lowhex (checksum));
+	} while(kgdb_started && (getDebugChar() != '+'));
+}
+
+/* The string str is prepended with the GDB printout token and sent. Required
+   in traditional implementations. */
+void
+putDebugString (const unsigned char *str, int length)
+{
+        remcomOutBuffer[0] = 'O';
+        mem2hex(&remcomOutBuffer[1], (unsigned char *)str, length);
+        putpacket(remcomOutBuffer);
+}
+
+/********************************** Handle exceptions ************************/
+/* Build and send a response packet in order to inform the host the
+   stub is stopped. TAAn...:r...;n...:r...;n...:r...;
+                    AA = signal number
+                    n... = register number (hex)
+                    r... = register contents
+                    n... = `thread'
+                    r... = thread process ID.  This is a hex integer.
+                    n... = other string not starting with valid hex digit.
+                    gdb should ignore this n,r pair and go on to the next.
+                    This way we can extend the protocol. */
+static void
+stub_is_stopped(int sigval)
+{
+	char *ptr = remcomOutBuffer;
+	int regno;
+
+	unsigned int reg_cont;
+	int status;
+        
+	/* Send trap type (converted to signal) */
+
+	*ptr++ = 'T';	
+	*ptr++ = highhex (sigval);
+	*ptr++ = lowhex (sigval);
+
+	/* Send register contents. We probably only need to send the
+	 * PC, frame pointer and stack pointer here. Other registers will be
+	 * explicitely asked for. But for now, send all. 
+	 */
+	
+	for (regno = R0; regno <= USP; regno++) {
+		/* Store n...:r...; for the registers in the buffer. */
+
+                status = read_register (regno, &reg_cont);
+                
+		if (status == SUCCESS) {
+                        
+                        *ptr++ = highhex (regno);
+                        *ptr++ = lowhex (regno);
+                        *ptr++ = ':';
+
+                        ptr = mem2hex(ptr, (unsigned char *)&reg_cont,
+                                      register_size[regno]);
+                        *ptr++ = ';';
+                }
+                
+	}
+
+#ifdef PROCESS_SUPPORT
+	/* Store the registers of the executing thread. Assume that both step,
+	   continue, and register content requests are with respect to this
+	   thread. The executing task is from the operating system scheduler. */
+
+	current_thread_c = executing_task;
+	current_thread_g = executing_task;
+
+	/* A struct assignment translates into a libc memcpy call. Avoid
+	   all libc functions in order to prevent recursive break points. */
+	copy_registers (&reg_g, &reg, sizeof(registers));
+
+	/* Store thread:r...; with the executing task TID. */
+	gdb_cris_strcpy (&remcomOutBuffer[pos], "thread:");
+	pos += gdb_cris_strlen ("thread:");
+	remcomOutBuffer[pos++] = highhex (executing_task);
+	remcomOutBuffer[pos++] = lowhex (executing_task);
+	gdb_cris_strcpy (&remcomOutBuffer[pos], ";");
+#endif
+
+	/* null-terminate and send it off */
+
+	*ptr = 0;
+
+	putpacket (remcomOutBuffer);
+}
+
+/* All expected commands are sent from remote.c. Send a response according
+   to the description in remote.c. */
+static void
+handle_exception (int sigval)
+{
+	/* Avoid warning of not used. */
+
+	USEDFUN(handle_exception);
+	USEDVAR(internal_stack[0]);
+
+	/* Send response. */
+
+	stub_is_stopped (sigval);
+
+	for (;;) {
+		remcomOutBuffer[0] = '\0';
+		getpacket (remcomInBuffer);
+		switch (remcomInBuffer[0]) {
+			case 'g':
+				/* Read registers: g
+				   Success: Each byte of register data is described by two hex digits.
+				   Registers are in the internal order for GDB, and the bytes
+				   in a register  are in the same order the machine uses.
+				   Failure: void. */
+				
+				{
+#ifdef PROCESS_SUPPORT
+					/* Use the special register content in the executing thread. */
+					copy_registers (&reg_g, &reg, sizeof(registers));
+					/* Replace the content available on the stack. */
+					if (current_thread_g != executing_task) {
+						copy_registers_from_stack (current_thread_g, &reg_g);
+					}
+					mem2hex ((unsigned char *)remcomOutBuffer, (unsigned char *)&reg_g, sizeof(registers));
+#else
+					mem2hex(remcomOutBuffer, (char *)&reg, sizeof(registers));
+#endif
+				}
+				break;
+				
+			case 'G':
+				/* Write registers. GXX..XX
+				   Each byte of register data  is described by two hex digits.
+				   Success: OK
+				   Failure: void. */
+#ifdef PROCESS_SUPPORT
+				hex2mem ((unsigned char *)&reg_g, &remcomInBuffer[1], sizeof(registers));
+				if (current_thread_g == executing_task) {
+					copy_registers (&reg, &reg_g, sizeof(registers));
+				}
+				else {
+					copy_registers_to_stack(current_thread_g, &reg_g);
+				}
+#else
+				hex2mem((char *)&reg, &remcomInBuffer[1], sizeof(registers));
+#endif
+				gdb_cris_strcpy (remcomOutBuffer, "OK");
+				break;
+				
+			case 'P':
+				/* Write register. Pn...=r...
+				   Write register n..., hex value without 0x, with value r...,
+				   which contains a hex value without 0x and two hex digits
+				   for each byte in the register (target byte order). P1f=11223344 means
+				   set register 31 to 44332211.
+				   Success: OK
+				   Failure: E02, E05 */
+				{
+					char *suffix;
+					int regno = gdb_cris_strtol (&remcomInBuffer[1], &suffix, 16);
+					int status;
+#ifdef PROCESS_SUPPORT
+					if (current_thread_g =! executing_task)
+						status = write_stack_register (current_thread_g, regno, suffix+1);
+					else
+#endif
+						status = write_register (regno, suffix+1);
+
+					switch (status) {
+						case E02:
+							/* Do not support read-only registers. */
+							gdb_cris_strcpy (remcomOutBuffer, error_message[E02]);
+							break;
+						case E05:
+							/* Do not support non-existing registers. */
+							gdb_cris_strcpy (remcomOutBuffer, error_message[E05]);
+							break;
+						case E07:
+							/* Do not support non-existing registers on the stack. */
+							gdb_cris_strcpy (remcomOutBuffer, error_message[E07]);
+							break;
+						default:
+							/* Valid register number. */
+							gdb_cris_strcpy (remcomOutBuffer, "OK");
+							break;
+					}
+				}
+				break;
+				
+			case 'm':
+				/* Read from memory. mAA..AA,LLLL
+				   AA..AA is the address and LLLL is the length.
+				   Success: XX..XX is the memory content.  Can be fewer bytes than
+				   requested if only part of the data may be read. m6000120a,6c means
+				   retrieve 108 byte from base address 6000120a.
+				   Failure: void. */
+				{
+                                        char *suffix;
+					unsigned char *addr = (unsigned char *)gdb_cris_strtol(&remcomInBuffer[1],
+                                                                                               &suffix, 16);                                        int length = gdb_cris_strtol(suffix+1, 0, 16);
+                                        
+                                        mem2hex(remcomOutBuffer, addr, length);
+                                }
+				break;
+				
+			case 'X':
+				/* Write to memory. XAA..AA,LLLL:XX..XX
+				   AA..AA is the start address,  LLLL is the number of bytes, and
+				   XX..XX is the binary data.
+				   Success: OK
+				   Failure: void. */
+			case 'M':
+				/* Write to memory. MAA..AA,LLLL:XX..XX
+				   AA..AA is the start address,  LLLL is the number of bytes, and
+				   XX..XX is the hexadecimal data.
+				   Success: OK
+				   Failure: void. */
+				{
+					char *lenptr;
+					char *dataptr;
+					unsigned char *addr = (unsigned char *)gdb_cris_strtol(&remcomInBuffer[1],
+										      &lenptr, 16);
+					int length = gdb_cris_strtol(lenptr+1, &dataptr, 16);
+					if (*lenptr == ',' && *dataptr == ':') {
+						if (remcomInBuffer[0] == 'M') {
+							hex2mem(addr, dataptr + 1, length);
+						}
+						else /* X */ {
+							bin2mem(addr, dataptr + 1, length);
+						}
+						gdb_cris_strcpy (remcomOutBuffer, "OK");
+					}
+					else {
+						gdb_cris_strcpy (remcomOutBuffer, error_message[E06]);
+					}
+				}
+				break;
+				
+			case 'c':
+				/* Continue execution. cAA..AA
+				   AA..AA is the address where execution is resumed. If AA..AA is
+				   omitted, resume at the present address.
+				   Success: return to the executing thread.
+				   Failure: will never know. */
+				if (remcomInBuffer[1] != '\0') {
+					reg.pc = gdb_cris_strtol (&remcomInBuffer[1], 0, 16);
+				}
+				enableDebugIRQ();
+				return;
+				
+			case 's':
+				/* Step. sAA..AA
+				   AA..AA is the address where execution is resumed. If AA..AA is
+				   omitted, resume at the present address. Success: return to the
+				   executing thread. Failure: will never know.
+				   
+				   Should never be invoked. The single-step is implemented on
+				   the host side. If ever invoked, it is an internal error E04. */
+				gdb_cris_strcpy (remcomOutBuffer, error_message[E04]);
+				putpacket (remcomOutBuffer);
+				return;
+				
+			case '?':
+				/* The last signal which caused a stop. ?
+				   Success: SAA, where AA is the signal number.
+				   Failure: void. */
+				remcomOutBuffer[0] = 'S';
+				remcomOutBuffer[1] = highhex (sigval);
+				remcomOutBuffer[2] = lowhex (sigval);
+				remcomOutBuffer[3] = 0;
+				break;
+				
+			case 'D':
+				/* Detach from host. D
+				   Success: OK, and return to the executing thread.
+				   Failure: will never know */
+				putpacket ("OK");
+				return;
+				
+			case 'k':
+			case 'r':
+				/* kill request or reset request.
+				   Success: restart of target.
+				   Failure: will never know. */
+				kill_restart ();
+				break;
+				
+			case 'C':
+			case 'S':
+			case '!':
+			case 'R':
+			case 'd':
+				/* Continue with signal sig. Csig;AA..AA
+				   Step with signal sig. Ssig;AA..AA
+				   Use the extended remote protocol. !
+				   Restart the target system. R0
+				   Toggle debug flag. d
+				   Search backwards. tAA:PP,MM
+				   Not supported: E04 */
+				gdb_cris_strcpy (remcomOutBuffer, error_message[E04]);
+				break;
+#ifdef PROCESS_SUPPORT
+
+			case 'T':
+				/* Thread alive. TXX
+				   Is thread XX alive?
+				   Success: OK, thread XX is alive.
+				   Failure: E03, thread XX is dead. */
+				{
+					int thread_id = (int)gdb_cris_strtol (&remcomInBuffer[1], 0, 16);
+					/* Cannot tell whether it is alive or not. */
+					if (thread_id >= 0 && thread_id < number_of_tasks)
+						gdb_cris_strcpy (remcomOutBuffer, "OK");
+				}
+				break;
+								
+			case 'H':
+				/* Set thread for subsequent operations: Hct
+				   c = 'c' for thread used in step and continue;
+				   t can be -1 for all threads.
+				   c = 'g' for thread used in other  operations.
+				   t = 0 means pick any thread.
+				   Success: OK
+				   Failure: E01 */
+				{
+					int thread_id = gdb_cris_strtol (&remcomInBuffer[2], 0, 16);
+					if (remcomInBuffer[1] == 'c') {
+						/* c = 'c' for thread used in step and continue */
+						/* Do not change current_thread_c here. It would create a mess in
+						   the scheduler. */
+						gdb_cris_strcpy (remcomOutBuffer, "OK");
+					}
+					else if (remcomInBuffer[1] == 'g') {
+						/* c = 'g' for thread used in other  operations.
+						   t = 0 means pick any thread. Impossible since the scheduler does
+						   not allow that. */
+						if (thread_id >= 0 && thread_id < number_of_tasks) {
+							current_thread_g = thread_id;
+							gdb_cris_strcpy (remcomOutBuffer, "OK");
+						}
+						else {
+							/* Not expected - send an error message. */
+							gdb_cris_strcpy (remcomOutBuffer, error_message[E01]);
+						}
+					}
+					else {
+						/* Not expected - send an error message. */
+						gdb_cris_strcpy (remcomOutBuffer, error_message[E01]);
+					}
+				}
+				break;
+				
+			case 'q':
+			case 'Q':
+				/* Query of general interest. qXXXX
+				   Set general value XXXX. QXXXX=yyyy */
+				{
+					int pos;
+					int nextpos;
+					int thread_id;
+					
+					switch (remcomInBuffer[1]) {
+						case 'C':
+							/* Identify the remote current thread. */
+							gdb_cris_strcpy (&remcomOutBuffer[0], "QC");
+							remcomOutBuffer[2] = highhex (current_thread_c);
+							remcomOutBuffer[3] = lowhex (current_thread_c);
+							remcomOutBuffer[4] = '\0';
+							break;
+						case 'L':
+							gdb_cris_strcpy (&remcomOutBuffer[0], "QM");
+							/* Reply with number of threads. */
+							if (os_is_started()) {
+								remcomOutBuffer[2] = highhex (number_of_tasks);
+								remcomOutBuffer[3] = lowhex (number_of_tasks);
+							}
+							else {
+								remcomOutBuffer[2] = highhex (0);
+								remcomOutBuffer[3] = lowhex (1);
+							}
+							/* Done with the reply. */
+							remcomOutBuffer[4] = lowhex (1);
+							pos = 5;
+							/* Expects the argument thread id. */
+							for (; pos < (5 + HEXCHARS_IN_THREAD_ID); pos++)
+								remcomOutBuffer[pos] = remcomInBuffer[pos];
+							/* Reply with the thread identifiers. */
+							if (os_is_started()) {
+								/* Store the thread identifiers of all tasks. */
+								for (thread_id = 0; thread_id < number_of_tasks; thread_id++) {
+									nextpos = pos + HEXCHARS_IN_THREAD_ID - 1;
+									for (; pos < nextpos; pos ++)
+										remcomOutBuffer[pos] = lowhex (0);
+									remcomOutBuffer[pos++] = lowhex (thread_id);
+								}
+							}
+							else {
+								/* Store the thread identifier of the boot task. */
+								nextpos = pos + HEXCHARS_IN_THREAD_ID - 1;
+								for (; pos < nextpos; pos ++)
+									remcomOutBuffer[pos] = lowhex (0);
+								remcomOutBuffer[pos++] = lowhex (current_thread_c);
+							}
+							remcomOutBuffer[pos] = '\0';
+							break;
+						default:
+							/* Not supported: "" */
+							/* Request information about section offsets: qOffsets. */
+							remcomOutBuffer[0] = 0;
+							break;
+					}
+				}
+				break;
+#endif /* PROCESS_SUPPORT */
+				
+			default:
+				/* The stub should ignore other request and send an empty
+				   response ($#<checksum>). This way we can extend the protocol and GDB
+				   can tell whether the stub it is talking to uses the old or the new. */
+				remcomOutBuffer[0] = 0;
+				break;
+		}
+		putpacket(remcomOutBuffer);
+	}
+}
+
+/* The jump is to the address 0x00000002. Performs a complete re-start
+   from scratch. */
+static void
+kill_restart ()
+{
+	__asm__ volatile ("jump 2");
+}
+
+/********************************** Breakpoint *******************************/
+/* The hook for both a static (compiled) and a dynamic breakpoint set by GDB.
+   An internal stack is used by the stub. The register image of the caller is
+   stored in the structure register_image.
+   Interactive communication with the host is handled by handle_exception and
+   finally the register image is restored. */
+
+void kgdb_handle_breakpoint(void);
+
+asm ("
+  .global _kgdb_handle_breakpoint
+_kgdb_handle_breakpoint:
+;;
+;; Response to the break-instruction
+;;
+;; Create a register image of the caller
+;;
+  move     dccr,[_reg+0x5E] ; Save the flags in DCCR before disable interrupts
+  di                        ; Disable interrupts
+  move.d   r0,[_reg]        ; Save R0
+  move.d   r1,[_reg+0x04]   ; Save R1
+  move.d   r2,[_reg+0x08]   ; Save R2
+  move.d   r3,[_reg+0x0C]   ; Save R3
+  move.d   r4,[_reg+0x10]   ; Save R4
+  move.d   r5,[_reg+0x14]   ; Save R5
+  move.d   r6,[_reg+0x18]   ; Save R6
+  move.d   r7,[_reg+0x1C]   ; Save R7
+  move.d   r8,[_reg+0x20]   ; Save R8
+  move.d   r9,[_reg+0x24]   ; Save R9
+  move.d   r10,[_reg+0x28]  ; Save R10
+  move.d   r11,[_reg+0x2C]  ; Save R11
+  move.d   r12,[_reg+0x30]  ; Save R12
+  move.d   r13,[_reg+0x34]  ; Save R13
+  move.d   sp,[_reg+0x38]   ; Save SP (R14)
+;; Due to the old assembler-versions BRP might not be recognized
+  .word 0xE670              ; move brp,r0
+  subq     2,r0             ; Set to address of previous instruction.
+  move.d   r0,[_reg+0x3c]   ; Save the address in PC (R15)
+  clear.b  [_reg+0x40]      ; Clear P0
+  move     vr,[_reg+0x41]   ; Save special register P1
+  clear.w  [_reg+0x42]      ; Clear P4
+  move     ccr,[_reg+0x44]  ; Save special register CCR
+  move     mof,[_reg+0x46]  ; P7
+  clear.d  [_reg+0x4A]      ; Clear P8
+  move     ibr,[_reg+0x4E]  ; P9,
+  move     irp,[_reg+0x52]  ; P10,
+  move     srp,[_reg+0x56]  ; P11,
+  move     dtp0,[_reg+0x5A] ; P12, register BAR, assembler might not know BAR
+                            ; P13, register DCCR already saved
+;; Due to the old assembler-versions BRP might not be recognized
+  .word 0xE670              ; move brp,r0
+;; Static (compiled) breakpoints must return to the next instruction in order
+;; to avoid infinite loops. Dynamic (gdb-invoked) must restore the instruction
+;; in order to execute it when execution is continued.
+  test.b   [_is_dyn_brkp]    ; Is this a dynamic breakpoint?
+  beq      is_static         ; No, a static breakpoint
+  nop
+  subq     2,r0              ; rerun the instruction the break replaced
+is_static:
+  moveq    1,r1
+  move.b   r1,[_is_dyn_brkp] ; Set the state variable to dynamic breakpoint
+  move.d   r0,[_reg+0x62]    ; Save the return address in BRP
+  move     usp,[_reg+0x66]   ; USP
+;;
+;; Handle the communication
+;;
+  move.d   _internal_stack+1020,sp ; Use the internal stack which grows upward
+  moveq    5,r10                   ; SIGTRAP
+  jsr      _handle_exception       ; Interactive routine
+;;
+;; Return to the caller
+;;
+   move.d  [_reg],r0         ; Restore R0
+   move.d  [_reg+0x04],r1    ; Restore R1
+   move.d  [_reg+0x08],r2    ; Restore R2
+   move.d  [_reg+0x0C],r3    ; Restore R3
+   move.d  [_reg+0x10],r4    ; Restore R4
+   move.d  [_reg+0x14],r5    ; Restore R5
+   move.d  [_reg+0x18],r6    ; Restore R6
+   move.d  [_reg+0x1C],r7    ; Restore R7
+   move.d  [_reg+0x20],r8    ; Restore R8
+   move.d  [_reg+0x24],r9    ; Restore R9
+   move.d  [_reg+0x28],r10   ; Restore R10
+   move.d  [_reg+0x2C],r11   ; Restore R11
+   move.d  [_reg+0x30],r12   ; Restore R12
+   move.d  [_reg+0x34],r13   ; Restore R13
+;;
+;; FIXME: Which registers should be restored?
+;;
+   move.d  [_reg+0x38],sp    ; Restore SP (R14)
+   move    [_reg+0x56],srp   ; Restore the subroutine return pointer.
+   move    [_reg+0x5E],dccr  ; Restore DCCR
+   move    [_reg+0x66],usp   ; Restore USP
+   jump    [_reg+0x62]       ; A jump to the content in register BRP works.
+   nop                       ;
+");
+
+/* The hook for an interrupt generated by GDB. An internal stack is used
+   by the stub. The register image of the caller is stored in the structure
+   register_image. Interactive communication with the host is handled by
+   handle_exception and finally the register image is restored. Due to the
+   old assembler which does not recognise the break instruction and the
+   breakpoint return pointer hex-code is used. */
+
+void kgdb_handle_serial(void);
+
+asm ("
+  .global _kgdb_handle_serial
+_kgdb_handle_serial:
+;;
+;; Response to a serial interrupt
+;;
+
+  move     dccr,[_reg+0x5E] ; Save the flags in DCCR
+  di                        ; Disable interrupts
+  move.d   r0,[_reg]        ; Save R0
+  move.d   r1,[_reg+0x04]   ; Save R1
+  move.d   r2,[_reg+0x08]   ; Save R2
+  move.d   r3,[_reg+0x0C]   ; Save R3
+  move.d   r4,[_reg+0x10]   ; Save R4
+  move.d   r5,[_reg+0x14]   ; Save R5
+  move.d   r6,[_reg+0x18]   ; Save R6
+  move.d   r7,[_reg+0x1C]   ; Save R7
+  move.d   r8,[_reg+0x20]   ; Save R8
+  move.d   r9,[_reg+0x24]   ; Save R9
+  move.d   r10,[_reg+0x28]  ; Save R10
+  move.d   r11,[_reg+0x2C]  ; Save R11
+  move.d   r12,[_reg+0x30]  ; Save R12
+  move.d   r13,[_reg+0x34]  ; Save R13
+  move.d   sp,[_reg+0x38]   ; Save SP (R14)
+  move     irp,[_reg+0x3c]  ; Save the address in PC (R15)
+  clear.b  [_reg+0x40]      ; Clear P0
+  move     vr,[_reg+0x41]   ; Save special register P1,
+  clear.w  [_reg+0x42]      ; Clear P4
+  move     ccr,[_reg+0x44]  ; Save special register CCR
+  move     mof,[_reg+0x46]  ; P7
+  clear.d  [_reg+0x4A]      ; Clear P8
+  move     ibr,[_reg+0x4E]  ; P9,
+  move     irp,[_reg+0x52]  ; P10,
+  move     srp,[_reg+0x56]  ; P11,
+  move     dtp0,[_reg+0x5A] ; P12, register BAR, assembler might not know BAR
+                            ; P13, register DCCR already saved
+;; Due to the old assembler-versions BRP might not be recognized
+  .word 0xE670              ; move brp,r0
+  move.d   r0,[_reg+0x62]   ; Save the return address in BRP
+  move     usp,[_reg+0x66]  ; USP
+
+;; get the serial character (from debugport.c) and check if its a ctrl-c
+
+  jsr _getDebugChar
+  cmp.b 3, r10
+  bne goback
+  nop
+
+;;
+;; Handle the communication
+;;
+  move.d   _internal_stack+1020,sp ; Use the internal stack
+  moveq    2,r10                   ; SIGINT
+  jsr      _handle_exception       ; Interactive routine
+
+goback:
+;;
+;; Return to the caller
+;;
+   move.d  [_reg],r0         ; Restore R0
+   move.d  [_reg+0x04],r1    ; Restore R1
+   move.d  [_reg+0x08],r2    ; Restore R2
+   move.d  [_reg+0x0C],r3    ; Restore R3
+   move.d  [_reg+0x10],r4    ; Restore R4
+   move.d  [_reg+0x14],r5    ; Restore R5
+   move.d  [_reg+0x18],r6    ; Restore R6
+   move.d  [_reg+0x1C],r7    ; Restore R7
+   move.d  [_reg+0x20],r8    ; Restore R8
+   move.d  [_reg+0x24],r9    ; Restore R9
+   move.d  [_reg+0x28],r10   ; Restore R10
+   move.d  [_reg+0x2C],r11   ; Restore R11
+   move.d  [_reg+0x30],r12   ; Restore R12
+   move.d  [_reg+0x34],r13   ; Restore R13
+;;
+;; FIXME: Which registers should be restored?
+;;
+   move.d  [_reg+0x38],sp    ; Restore SP (R14)
+   move    [_reg+0x56],srp   ; Restore the subroutine return pointer.
+   move    [_reg+0x5E],dccr  ; Restore DCCR
+   move    [_reg+0x66],usp   ; Restore USP
+   reti                      ; Return from the interrupt routine
+   nop
+");
+
+/* Use this static breakpoint in the start-up only. */
+
+void
+breakpoint(void)
+{
+	kgdb_started = 1;
+	is_dyn_brkp = 0;     /* This is a static, not a dynamic breakpoint. */
+	__asm__ volatile ("break 8"); /* Jump to handle_breakpoint. */
+}
+
+/* initialize kgdb. doesn't break into the debugger, but sets up irq and ports */
+
+void
+kgdb_init(void)
+{
+	/* could initialize debug port as well but it's done in head.S already... */
+
+	set_break_vector(8, kgdb_handle_breakpoint);
+	set_int_vector(8, kgdb_handle_serial, 0);
+	
+	enableDebugIRQ();
+}
+
+/****************************** End of file **********************************/
diff -urN linux-2.4.2-pre1/arch/cris/kernel/ksyms.c linux/arch/cris/kernel/ksyms.c
--- linux-2.4.2-pre1/arch/cris/kernel/ksyms.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/kernel/ksyms.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,2 @@
+/* no kernel support yet */
+
diff -urN linux-2.4.2-pre1/arch/cris/kernel/process.c linux/arch/cris/kernel/process.c
--- linux-2.4.2-pre1/arch/cris/kernel/process.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/kernel/process.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,327 @@
+/* $Id: process.c,v 1.8 2000/09/13 14:34:13 bjornw Exp $
+ * 
+ *  linux/arch/cris/kernel/process.c
+ *
+ *  Copyright (C) 1995  Linus Torvalds
+ *  Copyright (C) 2000  Axis Communications AB
+ *
+ *  Authors:   Bjorn Wesen (bjornw@axis.com)
+ *
+ */
+
+/*
+ * This file handles the architecture-dependent parts of process handling..
+ */
+
+#define __KERNEL_SYSCALLS__
+#include <stdarg.h>
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/malloc.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <linux/smp.h>
+
+//#define DEBUG
+
+/*
+ * Initial task structure. Make this a per-architecture thing,
+ * because different architectures tend to have different
+ * alignment requirements and potentially different initial
+ * setup.
+ */
+
+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;
+static struct signal_struct init_signals = INIT_SIGNALS;
+struct mm_struct init_mm = INIT_MM(init_mm);
+
+/*
+ * Initial task structure.
+ *
+ * We need to make sure that this is 8192-byte aligned due to the
+ * way process stacks are handled. This is done by having a special
+ * "init_task" linker map entry..
+ */
+
+union task_union init_task_union 
+      __attribute__((__section__(".data.init_task"))) =
+             { INIT_TASK(init_task_union.task) };
+
+static int hlt_counter=0;
+
+/* in a system call, set_esp0 is called to remember the stack frame, therefore
+   in the implementation of syscalls we can use that value to access the stack
+   frame and saved registers.
+*/
+
+#define currentregs ((struct pt_regs *)current->thread.esp0)
+
+asmlinkage void set_esp0(unsigned long ssp)
+{
+	current->thread.esp0 = ssp;
+}
+
+void disable_hlt(void)
+{
+	hlt_counter++;
+}
+
+void enable_hlt(void)
+{
+	hlt_counter--;
+}
+ 
+int cpu_idle(void *unused)
+{
+	while(1) {
+		current->counter = -100;
+		schedule();
+	}
+}
+
+/* if the watchdog is enabled, we can simply disable interrupts and go
+ * into an eternal loop, and the watchdog will reset the CPU after 0.1s
+ */
+
+void hard_reset_now (void)
+{
+	printk("*** HARD RESET ***\n");
+	cli();
+	while(1) /* waiting for RETRIBUTION! */ ;
+}
+
+void machine_restart(void)
+{
+	hard_reset_now();
+}
+
+/* can't do much here... */
+
+void machine_halt(void)
+{
+}
+
+void machine_power_off(void)
+{
+}
+
+/*
+ * This is the mechanism for creating a new kernel thread.
+ *
+ * NOTE! Only a kernel-only process(ie the swapper or direct descendants
+ * who haven't done an "execve()") should use this: it will work within
+ * a system call from a "real" process, but the process memory space will
+ * not be free'd until both the parent and the child have exited.
+ */
+
+int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+{
+	register long __a __asm__ ("r10");
+	
+	__asm__ __volatile__
+		("movu.w %1,r1\n\t"     /* r1 contains syscall number, to sys_clone */
+		 "clear.d r10\n\t"      /* r10 is argument 1 to clone */
+		 "move.d %2,r11\n\t"    /* r11 is argument 2 to clone, the flags */
+		 "break 13\n\t"         /* call sys_clone, this will fork */
+		 "test.d r10\n\t"       /* parent or child? child returns 0 here. */
+		 "bne 1f\n\t"           /* jump if parent */
+		 "nop\n\t"              /* delay slot */
+		 "move.d %4,r10\n\t"    /* set argument to function to call */
+		 "jsr %5\n\t"           /* call specified function */
+		 "movu.w %3,r1\n\t"     /* r1 is sys_exit syscall number */
+		 "moveq -1,r10\n\t"     /* Give a really bad exit-value */
+		 "break 13\n\t"         /* call sys_exit, killing the child */
+		 "1:\n\t"
+		 : "=r" (__a) 
+		 : "g" (__NR_clone), "r" (flags | CLONE_VM), "g" (__NR_exit),
+		   "r" (arg), "r" (fn) 
+		 : "r10", "r11", "r1");
+	
+	return __a;
+}
+
+
+
+void flush_thread(void)
+{
+}
+
+asmlinkage void ret_from_sys_call(void);
+
+/* setup the child's kernel stack with a pt_regs and switch_stack on it.
+ * it will be un-nested during _resume and _ret_from_sys_call when the
+ * new thread is scheduled.
+ *
+ * also setup the thread switching structure which is used to keep
+ * thread-specific data during _resumes.
+ *
+ */
+
+int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+		unsigned long unused,
+		struct task_struct *p, struct pt_regs *regs)
+{
+	struct pt_regs * childregs;
+	struct switch_stack *swstack;
+	
+	/* put the pt_regs structure at the end of the new kernel stack page and fix it up
+	 * remember that the task_struct doubles as the kernel stack for the task
+	 */
+
+	childregs = ((struct pt_regs *) ((unsigned long)p + THREAD_SIZE)) - 1;
+
+	*childregs = *regs;  /* struct copy of pt_regs */
+
+	childregs->r10 = 0;  /* child returns 0 after a fork/clone */
+	
+	/* put the switch stack right below the pt_regs */
+
+	swstack = ((struct switch_stack *)childregs) - 1;
+
+	swstack->r9 = 0; /* parameter to ret_from_sys_call, 0 == dont restart the syscall */
+
+	/* we want to return into ret_from_sys_call after the _resume */
+
+	swstack->return_ip = (unsigned long) ret_from_sys_call;
+	
+	/* fix the user-mode stackpointer */
+
+	p->thread.usp = usp;	
+
+	/* and the kernel-mode one */
+
+	p->thread.ksp = (unsigned long) swstack;
+
+	/* esp0 keeps the pt_regs stacked structure pointer */
+
+	p->thread.esp0 = (unsigned long) childregs;
+
+#ifdef DEBUG
+	printk("kern_stack_page 0x%x, used stack %d, thread.usp 0x%x, usp 0x%x\n", 
+	       current->kernel_stack_page, usedstack, p->thread.usp, usp);
+#endif
+	return 0;
+}
+
+/*
+ * fill in the user structure for a core dump..
+ */
+void dump_thread(struct pt_regs * regs, struct user * dump)
+{
+	int i;
+#if 0
+/* changed the size calculations - should hopefully work better. lbt */
+	dump->magic = CMAGIC;
+	dump->start_code = 0;
+	dump->start_stack = regs->esp & ~(PAGE_SIZE - 1);
+	dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
+	dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT;
+	dump->u_dsize -= dump->u_tsize;
+	dump->u_ssize = 0;
+	for (i = 0; i < 8; i++)
+		dump->u_debugreg[i] = current->debugreg[i];  
+
+	if (dump->start_stack < TASK_SIZE)
+		dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
+
+	dump->regs = *regs;
+
+	dump->u_fpvalid = dump_fpu (regs, &dump->i387);
+#endif 
+}
+
+asmlinkage int sys_fork(void)
+{
+	return do_fork(SIGCHLD, rdusp(), currentregs, 0);
+}
+
+/* if newusp is 0, we just grab the old usp */
+
+asmlinkage int sys_clone(unsigned long newusp, unsigned long flags)
+{
+	if (!newusp)
+		newusp = rdusp();
+	return do_fork(flags, newusp, currentregs, 0);
+}
+
+/* vfork is a system call in i386 because of register-pressure - maybe
+ * we can remove it and handle it in libc but we put it here until then.
+ */
+
+asmlinkage int sys_vfork(void)
+{
+        return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), currentregs, 0);
+}
+
+/*
+ * sys_execve() executes a new program.
+ */
+asmlinkage int sys_execve(const char *fname, char **argv, char **envp)
+{
+	int error;
+	char *filename;
+
+	filename = getname(fname);
+	error = PTR_ERR(filename);
+
+	if (IS_ERR(filename))
+	        goto out;
+	error = do_execve(filename, argv, envp, currentregs);
+	putname(filename);
+ out:
+	return error;
+}
+
+/*
+ * These bracket the sleeping functions..
+ */
+
+extern void scheduling_functions_start_here(void);
+extern void scheduling_functions_end_here(void);
+#define first_sched     ((unsigned long) scheduling_functions_start_here)
+#define last_sched      ((unsigned long) scheduling_functions_end_here)
+
+unsigned long get_wchan(struct task_struct *p)
+{
+#if 0
+	/* YURGH. TODO. */
+
+        unsigned long ebp, esp, eip;
+        unsigned long stack_page;
+        int count = 0;
+        if (!p || p == current || p->state == TASK_RUNNING)
+                return 0;
+        stack_page = (unsigned long)p;
+        esp = p->thread.esp;
+        if (!stack_page || esp < stack_page || esp > 8188+stack_page)
+                return 0;
+        /* include/asm-i386/system.h:switch_to() pushes ebp last. */
+        ebp = *(unsigned long *) esp;
+        do {
+                if (ebp < stack_page || ebp > 8184+stack_page)
+                        return 0;
+                eip = *(unsigned long *) (ebp+4);
+                if (eip < first_sched || eip >= last_sched)
+                        return eip;
+                ebp = *(unsigned long *) ebp;
+        } while (count++ < 16);
+#endif
+        return 0;
+}
+#undef last_sched
+#undef first_sched
diff -urN linux-2.4.2-pre1/arch/cris/kernel/ptrace.c linux/arch/cris/kernel/ptrace.c
--- linux-2.4.2-pre1/arch/cris/kernel/ptrace.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/kernel/ptrace.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,340 @@
+/*
+ *  linux/arch/cris/kernel/ptrace.c
+ *
+ * Parts taken from the m68k port.
+ * 
+ * Copyright (c) 2000 Axis Communications AB
+ *
+ * Authors:   Bjorn Wesen
+ *
+ * $Log: ptrace.c,v $
+ * Revision 1.3  2000/12/18 23:45:25  bjornw
+ * Linux/CRIS first version
+ *
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+
+#include <asm/uaccess.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/processor.h>
+
+/*
+ * does not yet catch signals sent when the child dies.
+ * in exit.c or in signal.c.
+ */
+
+/* determines which bits in DCCR the user has access to. */
+/* 1 = access 0 = no access */
+#define DCCR_MASK 0x0000001f     /* XNZVC */
+
+/*
+ * Get contents of register REGNO in task TASK.
+ */
+static inline long get_reg(struct task_struct *task, unsigned int regno)
+{
+	/* USP is a special case, it's not in the pt_regs struct but
+	 * in the tasks thread struct
+	 */
+
+	if (regno == PT_USP)
+		return task->thread.usp;
+	else if (regno <= PT_MAX)
+		return ((unsigned long *)(task->thread.esp0))[regno];
+	else
+		return 0;
+}
+
+/*
+ * Write contents of register REGNO in task TASK.
+ */
+static inline int put_reg(struct task_struct *task, unsigned int regno,
+			  unsigned long data)
+{
+	unsigned long *addr;
+
+	if (regno == PT_USP)
+		task->thread.usp = data;
+	else if (regno <= PT_MAX)
+		((unsigned long *)(task->thread.esp0))[regno] = data;
+	else
+		return -1;
+	return 0;
+}
+
+asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+{
+	struct task_struct *child;
+	int ret;
+
+	lock_kernel();
+	ret = -EPERM;
+	if (request == PTRACE_TRACEME) {
+		/* are we already being traced? */
+		if (current->ptrace & PT_PTRACED)
+			goto out;
+		/* set the ptrace bit in the process flags. */
+		current->ptrace |= PT_PTRACED;
+		ret = 0;
+		goto out;
+	}
+	ret = -ESRCH;
+	read_lock(&tasklist_lock);
+	child = find_task_by_pid(pid);
+	if (child)
+		get_task_struct(child);
+	read_unlock(&tasklist_lock);
+	if (!child)
+		goto out;
+	ret = -EPERM;
+	if (pid == 1)		/* you may not mess with init */
+		goto out_tsk;
+	if (request == PTRACE_ATTACH) {
+		if (child == current)
+			goto out_tsk;
+		if ((!child->dumpable ||
+		    (current->uid != child->euid) ||
+		    (current->uid != child->suid) ||
+		    (current->uid != child->uid) ||
+	 	    (current->gid != child->egid) ||
+		    (current->gid != child->sgid) ||
+	 	    (!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
+	 	    (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
+			goto out_tsk;
+		/* the same process cannot be attached many times */
+		if (child->ptrace & PT_PTRACED)
+			goto out_tsk;
+		child->ptrace |= PT_PTRACED;
+
+		write_lock_irq(&tasklist_lock);
+		if (child->p_pptr != current) {
+			REMOVE_LINKS(child);
+			child->p_pptr = current;
+			SET_LINKS(child);
+		}
+		write_unlock_irq(&tasklist_lock);
+
+		send_sig(SIGSTOP, child, 1);
+		ret = 0;
+		goto out_tsk;
+	}
+	ret = -ESRCH;
+	if (!(child->ptrace & PT_PTRACED))
+		goto out_tsk;
+	if (child->state != TASK_STOPPED) {
+		if (request != PTRACE_KILL)
+			goto out_tsk;
+	}
+	if (child->p_pptr != current)
+		goto out_tsk;
+
+	switch (request) {
+	/* when I and D space are separate, these will need to be fixed. */
+		case PTRACE_PEEKTEXT: /* read word at location addr. */ 
+		case PTRACE_PEEKDATA: {
+			unsigned long tmp;
+			int copied;
+
+			copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+			ret = -EIO;
+			if (copied != sizeof(tmp))
+				break;
+			ret = put_user(tmp,(unsigned long *) data);
+			break;
+		}
+
+		/* read the word at location addr in the USER area. */
+		case PTRACE_PEEKUSR: {
+			unsigned long tmp;
+			
+			ret = -EIO;
+			if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
+				break;
+			
+			tmp = 0;  /* Default return condition */
+			ret = -EIO;
+			if (addr < sizeof(struct pt_regs)) {
+				tmp = get_reg(child, addr >> 2);
+				ret = put_user(tmp, (unsigned long *)data);
+			}
+			break;
+		}
+
+		/* when I and D space are separate, this will have to be fixed. */
+		case PTRACE_POKETEXT: /* write the word at location addr. */
+		case PTRACE_POKEDATA:
+			ret = 0;
+			if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
+				break;
+			ret = -EIO;
+			break;
+
+		case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
+			ret = -EIO;
+			if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
+				break;
+
+			if (addr < sizeof(struct pt_regs)) {
+				addr >>= 2;
+
+				if (addr == PT_DCCR) {
+				/* don't allow the tracing process to change stuff like
+				 * interrupt enable, kernel/user bit, dma enables etc.
+				 */
+					data &= DCCR_MASK;
+					data |= get_reg(child, PT_DCCR) & ~DCCR_MASK;
+				}
+				if (put_reg(child, addr, data))
+					break;
+				ret = 0;
+			}
+			break;
+
+		case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+		case PTRACE_CONT: { /* restart after signal. */
+			long tmp;
+
+			ret = -EIO;
+			if ((unsigned long) data > _NSIG)
+				break;
+			if (request == PTRACE_SYSCALL)
+				child->ptrace |= PT_TRACESYS;
+			else
+				child->ptrace &= ~PT_TRACESYS;
+			child->exit_code = data;
+			/* TODO: make sure any pending breakpoint is killed */
+			wake_up_process(child);
+			ret = 0;
+			break;
+		}
+
+/*
+ * make the child exit.  Best I can do is send it a sigkill. 
+ * perhaps it should be put in the status that it wants to 
+ * exit.
+ */
+		case PTRACE_KILL: {
+			long tmp;
+
+			ret = 0;
+			if (child->state == TASK_ZOMBIE) /* already dead */
+				break;
+			child->exit_code = SIGKILL;
+			/* TODO: make sure any pending breakpoint is killed */
+			wake_up_process(child);
+			break;
+		}
+
+		case PTRACE_SINGLESTEP: {  /* set the trap flag. */
+			long tmp;
+
+			ret = -EIO;
+			if ((unsigned long) data > _NSIG)
+				break;
+			child->ptrace &= ~PT_TRACESYS;
+
+			/* TODO: set some clever breakpoint mechanism... */
+
+			child->exit_code = data;
+			/* give it a chance to run. */
+			wake_up_process(child);
+			ret = 0;
+			break;
+		}
+
+		case PTRACE_DETACH: { /* detach a process that was attached. */
+			long tmp;
+
+			ret = -EIO;
+			if ((unsigned long) data > _NSIG)
+				break;
+			child->ptrace &= ~(PT_PTRACED | PT_TRACESYS);
+			child->exit_code = data;
+			write_lock_irq(&tasklist_lock);
+			REMOVE_LINKS(child);
+			child->p_pptr = child->p_opptr;
+			SET_LINKS(child);
+			write_unlock_irq(&tasklist_lock);
+			/* TODO: make sure any pending breakpoint is killed */
+			wake_up_process(child);
+			ret = 0;
+			break;
+		}
+
+		case PTRACE_GETREGS: { /* Get all gp regs from the child. */
+		  	int i;
+			unsigned long tmp;
+			for (i = 0; i <= PT_MAX; i++) {
+				tmp = get_reg(child, i);
+				if (put_user(tmp, (unsigned long *) data)) {
+					ret = -EFAULT;
+					break;
+				}
+				data += sizeof(long);
+			}
+			ret = 0;
+			break;
+		}
+
+		case PTRACE_SETREGS: { /* Set all gp regs in the child. */
+			int i;
+			unsigned long tmp;
+			for (i = 0; i <= PT_MAX; i++) {
+				if (get_user(tmp, (unsigned long *) data)) {
+					ret = -EFAULT;
+					break;
+				}
+				if (i == PT_DCCR) {
+					tmp &= DCCR_MASK;
+					tmp |= get_reg(child, PT_DCCR) & ~DCCR_MASK;
+				}
+				put_reg(child, i, tmp);
+				data += sizeof(long);
+			}
+			ret = 0;
+			break;
+		}
+
+		default:
+			ret = -EIO;
+			break;
+	}
+out_tsk:
+	free_task_struct(child);
+out:
+	unlock_kernel();
+	return ret;
+}
+
+asmlinkage void syscall_trace(void)
+{
+	if ((current->ptrace & (PT_PTRACED | PT_TRACESYS)) !=
+	    (PT_PTRACED | PT_TRACESYS))
+		return;
+	/* TODO: make a way to distinguish between a syscall stop and SIGTRAP
+	 * delivery like in the i386 port ? 
+	 */
+	current->exit_code = SIGTRAP;
+	current->state = TASK_STOPPED;
+	notify_parent(current, SIGCHLD);
+	schedule();
+	/*
+	 * this isn't the same as continuing with a signal, but it will do
+	 * for normal use.  strace only continues with a signal if the
+	 * stopping signal is not SIGTRAP.  -brl
+	 */
+	if (current->exit_code) {
+		send_sig(current->exit_code, current, 1);
+		current->exit_code = 0;
+	}
+}
diff -urN linux-2.4.2-pre1/arch/cris/kernel/semaphore.c linux/arch/cris/kernel/semaphore.c
--- linux-2.4.2-pre1/arch/cris/kernel/semaphore.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/kernel/semaphore.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,238 @@
+/*
+ *  Generic semaphore code. Buyer beware. Do your own
+ * specific changes in <asm/semaphore-helper.h>
+ */
+
+#include <linux/sched.h>
+#include <asm/semaphore-helper.h>
+
+/*
+ * Semaphores are implemented using a two-way counter:
+ * The "count" variable is decremented for each process
+ * that tries to sleep, while the "waking" variable is
+ * incremented when the "up()" code goes to wake up waiting
+ * processes.
+ *
+ * Notably, the inline "up()" and "down()" functions can
+ * efficiently test if they need to do any extra work (up
+ * needs to do something only if count was negative before
+ * the increment operation.
+ *
+ * waking_non_zero() (from asm/semaphore.h) must execute
+ * atomically.
+ *
+ * When __up() is called, the count was negative before
+ * incrementing it, and we need to wake up somebody.
+ *
+ * This routine adds one to the count of processes that need to
+ * wake up and exit.  ALL waiting processes actually wake up but
+ * only the one that gets to the "waking" field first will gate
+ * through and acquire the semaphore.  The others will go back
+ * to sleep.
+ *
+ * Note that these functions are only called when there is
+ * contention on the lock, and as such all this is the
+ * "non-critical" part of the whole semaphore business. The
+ * critical part is the inline stuff in <asm/semaphore.h>
+ * where we want to avoid any extra jumps and calls.
+ */
+void __up(struct semaphore *sem)
+{
+	wake_one_more(sem);
+	wake_up(&sem->wait);
+}
+
+/*
+ * Perform the "down" function.  Return zero for semaphore acquired,
+ * return negative for signalled out of the function.
+ *
+ * If called from __down, the return is ignored and the wait loop is
+ * not interruptible.  This means that a task waiting on a semaphore
+ * using "down()" cannot be killed until someone does an "up()" on
+ * the semaphore.
+ *
+ * If called from __down_interruptible, the return value gets checked
+ * upon return.  If the return value is negative then the task continues
+ * with the negative value in the return register (it can be tested by
+ * the caller).
+ *
+ * Either form may be used in conjunction with "up()".
+ *
+ */
+
+#define DOWN_VAR				\
+	struct task_struct *tsk = current;	\
+	wait_queue_t wait;			\
+	init_waitqueue_entry(&wait, tsk);
+
+#define DOWN_HEAD(task_state)						\
+									\
+									\
+	tsk->state = (task_state);					\
+	add_wait_queue(&sem->wait, &wait);				\
+									\
+	/*								\
+	 * Ok, we're set up.  sem->count is known to be less than zero	\
+	 * so we must wait.						\
+	 *								\
+	 * We can let go the lock for purposes of waiting.		\
+	 * We re-acquire it after awaking so as to protect		\
+	 * all semaphore operations.					\
+	 *								\
+	 * If "up()" is called before we call waking_non_zero() then	\
+	 * we will catch it right away.  If it is called later then	\
+	 * we will have to go through a wakeup cycle to catch it.	\
+	 *								\
+	 * Multiple waiters contend for the semaphore lock to see	\
+	 * who gets to gate through and who has to wait some more.	\
+	 */								\
+	for (;;) {
+
+#define DOWN_TAIL(task_state)			\
+		tsk->state = (task_state);	\
+	}					\
+	tsk->state = TASK_RUNNING;		\
+	remove_wait_queue(&sem->wait, &wait);
+
+void __down(struct semaphore * sem)
+{
+	DOWN_VAR
+	DOWN_HEAD(TASK_UNINTERRUPTIBLE)
+	if (waking_non_zero(sem))
+		break;
+	schedule();
+	DOWN_TAIL(TASK_UNINTERRUPTIBLE)
+}
+
+int __down_interruptible(struct semaphore * sem)
+{
+	int ret = 0;
+	DOWN_VAR
+	DOWN_HEAD(TASK_INTERRUPTIBLE)
+
+	ret = waking_non_zero_interruptible(sem, tsk);
+	if (ret)
+	{
+		if (ret == 1)
+			/* ret != 0 only if we get interrupted -arca */
+			ret = 0;
+		break;
+	}
+	schedule();
+	DOWN_TAIL(TASK_INTERRUPTIBLE)
+	return ret;
+}
+
+int __down_trylock(struct semaphore * sem)
+{
+	return waking_non_zero_trylock(sem);
+}
+
+/*
+ * RW Semaphores
+ */
+void
+__down_read(struct rw_semaphore *sem, int count)
+{
+	DOWN_VAR;
+
+ retry_down:
+	if (count < 0) {
+		/* Wait for the lock to become unbiased.  Readers
+		   are non-exclusive.  */
+		
+		/* This takes care of granting the lock.  */
+		up_read(sem);
+
+		add_wait_queue(&sem->wait, &wait);
+		while (atomic_read(&sem->count) < 0) {
+			set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+			if (atomic_read(&sem->count) >= 0)
+				break;
+			schedule();
+		}
+
+		remove_wait_queue(&sem->wait, &wait);
+		tsk->state = TASK_RUNNING;
+
+		mb();
+		count = atomic_dec_return(&sem->count);
+		if (count <= 0)
+			goto retry_down;
+	} else {
+		add_wait_queue(&sem->wait, &wait);
+
+		while (1) {
+			if (test_and_clear_bit(0, &sem->granted))
+				break;
+			set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+			if ((sem->granted & 1) == 0)
+				schedule();
+		}
+
+		remove_wait_queue(&sem->wait, &wait);
+		tsk->state = TASK_RUNNING;
+	}
+}
+
+void
+__down_write(struct rw_semaphore *sem, int count)
+{
+	DOWN_VAR;
+
+ retry_down:
+	if (count + RW_LOCK_BIAS < 0) {
+		up_write(sem);
+
+		add_wait_queue_exclusive(&sem->wait, &wait);
+	
+		while (atomic_read(&sem->count) < 0) {
+			set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+			if (atomic_read(&sem->count) >= RW_LOCK_BIAS)
+				break;
+			schedule();
+		}
+
+		remove_wait_queue(&sem->wait, &wait);
+		tsk->state = TASK_RUNNING;
+
+		mb();
+		count = atomic_sub_return(RW_LOCK_BIAS, &sem->count);
+		if (count != 0)
+			goto retry_down;
+	} else {
+		/* Put ourselves at the end of the list.  */
+		add_wait_queue_exclusive(&sem->write_bias_wait, &wait);
+
+		while (1) {
+			if (test_and_clear_bit(1, &sem->granted))
+				break;
+			set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+			if ((sem->granted & 2) == 0)
+				schedule();
+		}
+
+		remove_wait_queue(&sem->write_bias_wait, &wait);
+		tsk->state = TASK_RUNNING;
+
+		/* If the lock is currently unbiased, awaken the sleepers.
+		   FIXME: This wakes up the readers early in a bit of a
+		   stampede -> bad!  */
+		if (atomic_read(&sem->count) >= 0)
+			wake_up(&sem->wait);
+	}
+}
+
+void
+__rwsem_wake(struct rw_semaphore *sem, unsigned long readers)
+{
+	if (readers) {
+		if (test_and_set_bit(0, &sem->granted))
+			BUG();
+		wake_up(&sem->wait);
+	} else {
+		if (test_and_set_bit(1, &sem->granted))
+			BUG();
+		wake_up(&sem->write_bias_wait);
+	}
+}
diff -urN linux-2.4.2-pre1/arch/cris/kernel/setup.c linux/arch/cris/kernel/setup.c
--- linux-2.4.2-pre1/arch/cris/kernel/setup.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/kernel/setup.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,264 @@
+/* $Id: setup.c,v 1.8 2001/01/16 16:31:38 bjornw Exp $
+ *
+ *  linux/arch/cris/kernel/setup.c
+ *
+ *  Copyright (C) 1995  Linus Torvalds
+ *  Copyright (c) 2000  Axis Communications AB
+ */
+
+/*
+ * This file handles the architecture-dependent parts of initialization
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/malloc.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/tty.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+
+#include <asm/segment.h>
+#include <asm/system.h>
+#include <asm/smp.h>
+#include <asm/types.h>
+#include <asm/svinto.h>
+
+/*
+ * Setup options
+ */
+struct drive_info_struct { char dummy[32]; } drive_info;
+struct screen_info screen_info;
+
+unsigned char aux_device_present;
+
+#ifdef CONFIG_BLK_DEV_RAM
+extern int rd_doload;		/* 1 = load ramdisk, 0 = don't load */
+extern int rd_prompt;		/* 1 = prompt for ramdisk, 0 = don't prompt */
+extern int rd_image_start;	/* starting block # of image */
+#endif
+
+extern int root_mountflags;
+extern char _etext, _edata, _end;
+
+#define COMMAND_LINE_SIZE 256
+
+static char command_line[COMMAND_LINE_SIZE] = { 0, };
+       char saved_command_line[COMMAND_LINE_SIZE];
+
+extern const unsigned long text_start, edata; /* set by the linker script */
+
+extern unsigned long romfs_start, romfs_length, romfs_in_flash; /* from head.S */
+
+/* This mainly sets up the memory area, and can be really confusing.
+ *
+ * The physical DRAM is virtually mapped into dram_start to dram_end
+ * (usually c0000000 to c0000000 + DRAM size). The physical address is
+ * given by the macro __pa().
+ *
+ * In this DRAM, the kernel code and data is loaded, in the beginning.
+ * It really starts at c00a0000 to make room for some special pages - 
+ * the start address is text_start. The kernel data ends at _end. After
+ * this the ROM filesystem is appended (if there is any).
+ * 
+ * Between this address and dram_end, we have RAM pages usable to the
+ * boot code and the system.
+ *
+ */
+
+void __init setup_arch(char **cmdline_p)
+{
+        unsigned long bootmap_size;
+	unsigned long start_pfn, max_pfn;
+	unsigned long memory_start;
+	extern void console_print_etrax(const char *b);
+
+#if (defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH))
+	/* TODO: move this into flash_init I think */
+	flash_probe();
+#endif
+
+ 	/* register an initial console printing routine for printk's */
+
+	init_etrax_debug();
+
+	/* we should really poll for DRAM size! */
+
+	high_memory = &dram_end;
+
+	if(romfs_in_flash || !romfs_length) {
+		/* if we have the romfs in flash, or if there is no rom filesystem,
+		 * our free area starts directly after the BSS 
+		 */
+		memory_start = (unsigned long) &_end;
+	} else {
+		/* otherwise the free area starts after the ROM filesystem */
+		printk("ROM fs in RAM, size %d bytes\n", romfs_length);
+		memory_start = romfs_start + romfs_length;
+	}
+
+	/* process 1's initial memory region is the kernel code/data */
+
+	init_mm.start_code = (unsigned long) &text_start;
+	init_mm.end_code =   (unsigned long) &_etext;
+	init_mm.end_data =   (unsigned long) &_edata;
+	init_mm.brk =        (unsigned long) &_end;
+
+#define PFN_UP(x)       (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define PFN_DOWN(x)     ((x) >> PAGE_SHIFT)
+#define PFN_PHYS(x)     ((x) << PAGE_SHIFT)
+
+	/* min_low_pfn points to the start of DRAM, start_pfn points
+	 * to the first DRAM pages after the kernel, and max_low_pfn
+	 * to the end of DRAM.
+	 */
+
+        /*
+         * partially used pages are not usable - thus
+         * we are rounding upwards:
+         */
+
+        start_pfn = PFN_UP(memory_start);  /* usually c0000000 + kernel + romfs */
+	max_pfn =   PFN_DOWN((unsigned long)high_memory); /* usually c0000000 + dram size */
+
+        /*
+         * Initialize the boot-time allocator (start, end)
+	 *
+	 * We give it access to all our DRAM, but we could as well just have
+	 * given it a small slice. No point in doing that though, unless we
+	 * have non-contiguous memory and want the boot-stuff to be in, say,
+	 * the smallest area.
+	 *
+	 * It will put a bitmap of the allocated pages in the beginning
+	 * of the range we give it, but it won't mark the bitmaps pages
+	 * as reserved. We have to do that ourselves below.
+	 *
+	 * We need to use init_bootmem_node instead of init_bootmem
+	 * because our map starts at a quite high address (min_low_pfn).
+         */
+
+	max_low_pfn = max_pfn;
+	min_low_pfn = PAGE_OFFSET >> PAGE_SHIFT;
+
+	bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn,
+					 min_low_pfn, 
+					 max_low_pfn);
+
+	/* And free all memory not belonging to the kernel (addr, size) */
+
+	free_bootmem(PFN_PHYS(start_pfn), PFN_PHYS(max_pfn - start_pfn));
+
+        /*
+         * Reserve the bootmem bitmap itself as well. We do this in two
+         * steps (first step was init_bootmem()) because this catches
+         * the (very unlikely) case of us accidentally initializing the
+         * bootmem allocator with an invalid RAM area.
+	 *
+	 * Arguments are start, size
+         */
+
+        reserve_bootmem(PFN_PHYS(start_pfn), bootmap_size);
+
+	/* paging_init() sets up the MMU and marks all pages as reserved */
+
+	paging_init();
+
+	/* we dont use a command line yet, so just let it be an empty string */
+
+	*cmdline_p = command_line;
+	strcpy(command_line, "root=/dev/rom"); /* use the appended romdisk as root */
+
+	/* give credit for the CRIS port */
+
+	printk("Linux/CRIS port on ETRAX 100LX (c) 2000 Axis Communications AB\n");
+
+}
+
+#ifdef CONFIG_PROC_FS
+#define HAS_FPU		0x0001
+#define HAS_MMU		0x0002
+#define HAS_ETHERNET100	0x0004
+#define HAS_TOKENRING	0x0008
+#define HAS_SCSI	0x0010
+#define HAS_ATA		0x0020
+#define HAS_USB		0x0040
+#define HAS_IRQ_BUG	0x0080
+
+static struct cpu_info {
+	char *model;
+	unsigned short cache;
+	unsigned short flags;
+} cpu_info[] = {
+	{ "ETRAX 1",   0, 0 },
+	{ "ETRAX 2",   0, 0 },	/* Don't say it HAS_TOKENRING - there are
+				   lethal bugs in that chip that
+				   prevents T-R from ever working.
+				   Never go there, and never lead anyone
+				   into believing it can work.  BTW:
+				   Anyone working on a T-R network
+				   driver? :-) :-) :-) :-/ */
+	{ "ETRAX 3",   0, HAS_TOKENRING },
+	{ "ETRAX 4",   0, HAS_TOKENRING | HAS_SCSI },
+	{ "Unknown",   0, 0 },
+	{ "Unknown",   0, 0 },
+	{ "Unknown",   0, 0 },
+	{ "Simulator",     8, HAS_ETHERNET100 | HAS_SCSI | HAS_ATA },
+	{ "ETRAX 100",     8, HAS_ETHERNET100 | HAS_SCSI | HAS_ATA | HAS_IRQ_BUG },
+	{ "ETRAX 100",     8, HAS_ETHERNET100 | HAS_SCSI | HAS_ATA },
+	{ "ETRAX 100LX",  8, HAS_ETHERNET100 | HAS_SCSI | HAS_ATA | HAS_USB | HAS_MMU },
+	{ "Unknown",   0, 0 },
+};
+
+/*
+ * BUFFER is PAGE_SIZE bytes long.
+ */
+int get_cpuinfo(char *buffer)
+{
+	int revision;
+#ifndef CONFIG_SVINTO_SIM
+	unsigned char tmp;
+
+	__asm__ volatile ("move vr,%0" : "=rm" (tmp));
+	revision = tmp;
+#else
+        /* Fake a revision for the simulator */
+	revision = 7;
+#endif
+
+	return sprintf(buffer,
+		       "cpu\t\t: CRIS\n"
+		       "cpu revision\t: %d\n"
+		       "cpu model\t: %s\n"
+		       "cache size\t: %d kB\n"
+		       "fpu\t\t: %s\n"
+		       "mmu\t\t: %s\n"
+		       "ethernet\t: %s Mbps\n"
+		       "token ring\t: %s\n"
+		       "scsi\t\t: %s\n"
+		       "ata\t\t: %s\n"
+		       "usb\t\t: %s\n"
+		       "bogomips\t: %lu.%02lu\n",
+
+		       revision,
+		       cpu_info[revision].model,
+		       cpu_info[revision].cache,
+		       cpu_info[revision].flags & HAS_FPU ? "yes" : "no",
+		       cpu_info[revision].flags & HAS_MMU ? "yes" : "no",
+		       cpu_info[revision].flags & HAS_ETHERNET100 ? "10/100" : "10",
+		       cpu_info[revision].flags & HAS_TOKENRING ? "4/16 Mbps" : "no",
+		       cpu_info[revision].flags & HAS_SCSI ? "yes" : "no",
+		       cpu_info[revision].flags & HAS_ATA ? "yes" : "no",
+		       cpu_info[revision].flags & HAS_USB ? "yes" : "no",
+		       (loops_per_jiffy * HZ + 500) / 100000,
+		       ((loops_per_jiffy * HZ + 500) / 1000) % 100);
+}
+#endif /* CONFIG_PROC_FS */
diff -urN linux-2.4.2-pre1/arch/cris/kernel/shadows.c linux/arch/cris/kernel/shadows.c
--- linux-2.4.2-pre1/arch/cris/kernel/shadows.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/kernel/shadows.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,20 @@
+/* $Id: shadows.c,v 1.1 2000/07/10 16:25:21 bjornw Exp $
+ * 
+ * Various Etrax shadow registers. Defines for these are in include/asm-etrax100/io.h
+ */
+
+#include <linux/config.h>
+
+unsigned long genconfig_shadow = 42;
+unsigned long port_g_data_shadow = 42;
+unsigned char port_pa_dir_shadow = 42;
+unsigned char port_pa_data_shadow = 42;
+unsigned char port_pb_i2c_shadow = 42;
+unsigned char port_pb_config_shadow = 42;
+unsigned char port_pb_dir_shadow = 42;
+unsigned char port_pb_data_shadow = 42;
+unsigned long r_timer_ctrl_shadow = 42;
+
+#ifdef CONFIG_ETRAX_90000000_LEDS
+unsigned long port_90000000_shadow = 42;
+#endif
diff -urN linux-2.4.2-pre1/arch/cris/kernel/signal.c linux/arch/cris/kernel/signal.c
--- linux-2.4.2-pre1/arch/cris/kernel/signal.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/kernel/signal.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,667 @@
+/*
+ *  linux/arch/cris/kernel/signal.c
+ *
+ *  Based on arch/i386/kernel/signal.c by
+ *     Copyright (C) 1991, 1992  Linus Torvalds
+ *     1997-11-28  Modified for POSIX.1b signals by Richard Henderson *
+ *
+ *  Ideas also taken from arch/arm.
+ *
+ *  Copyright (C) 2000 Axis Communications AB
+ *
+ *  Authors:  Bjorn Wesen (bjornw@axis.com)
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+
+#include <asm/processor.h>
+#include <asm/ucontext.h>
+#include <asm/uaccess.h>
+
+#define DEBUG_SIG 0
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+/* a syscall in Linux/CRIS is a break 13 instruction which is 2 bytes */
+/* manipulate regs so that upon return, it will be re-executed */
+
+#define RESTART_CRIS_SYS(regs) regs->r10 = regs->orig_r10; regs->irp -= 2;
+
+int sys_wait4(pid_t pid, unsigned long *stat_addr,
+			 int options, unsigned long *ru);
+
+int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs);
+
+int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
+{
+	if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
+		return -EFAULT;
+	if (from->si_code < 0)
+		return __copy_to_user(to, from, sizeof(siginfo_t));
+	else {
+		int err;
+
+		/* If you change siginfo_t structure, please be sure
+		   this code is fixed accordingly.
+		   It should never copy any pad contained in the structure
+		   to avoid security leaks, but must copy the generic
+		   3 ints plus the relevant union member.  */
+		err = __put_user(from->si_signo, &to->si_signo);
+		err |= __put_user(from->si_errno, &to->si_errno);
+		err |= __put_user((short)from->si_code, &to->si_code);
+		/* First 32bits of unions are always present.  */
+		err |= __put_user(from->si_pid, &to->si_pid);
+		switch (from->si_code >> 16) {
+		case __SI_FAULT >> 16:
+			break;
+		case __SI_CHLD >> 16:
+			err |= __put_user(from->si_utime, &to->si_utime);
+			err |= __put_user(from->si_stime, &to->si_stime);
+			err |= __put_user(from->si_status, &to->si_status);
+		default:
+			err |= __put_user(from->si_uid, &to->si_uid);
+			break;
+		/* case __SI_RT: This is not generated by the kernel as of now.  */
+		}
+		return err;
+	}
+}
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+int
+sys_sigsuspend(old_sigset_t mask)
+{
+	struct pt_regs * regs = (struct pt_regs *)current_regs();
+	sigset_t saveset;
+
+	mask &= _BLOCKABLE;
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	siginitset(&current->blocked, mask);
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	regs->r10 = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(0, &saveset, regs))
+			return -EINTR;
+	}
+}
+
+int
+sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
+{
+	struct pt_regs * regs = (struct pt_regs *)current_regs();
+	sigset_t saveset, newset;
+
+	/* XXX: Don't preclude handling different sized sigset_t's.  */
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	if (copy_from_user(&newset, unewset, sizeof(newset)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	regs->r10 = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(0, &saveset, regs))
+			return -EINTR;
+	}
+}
+
+int 
+sys_sigaction(int sig, const struct old_sigaction *act,
+	      struct old_sigaction *oact)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+
+	if (act) {
+		old_sigset_t mask;
+		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+			return -EFAULT;
+		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		__get_user(mask, &act->sa_mask);
+		siginitset(&new_ka.sa.sa_mask, mask);
+	}
+
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+	if (!ret && oact) {
+		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+			return -EFAULT;
+		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+	}
+
+	return ret;
+}
+
+int
+sys_sigaltstack(const stack_t *uss, stack_t *uoss)
+{
+	return do_sigaltstack(uss, uoss, rdusp());
+}
+
+
+/*
+ * Do a signal return; undo the signal stack.
+ */
+
+struct sigframe {
+	struct sigcontext sc;
+	unsigned long extramask[_NSIG_WORDS-1];
+	unsigned char retcode[8];  /* trampoline code */
+};
+
+struct rt_sigframe {
+	struct siginfo *pinfo;
+	void *puc;
+	struct siginfo info;
+	struct ucontext uc;
+	unsigned char retcode[8];  /* trampoline code */
+};
+
+
+static int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+{
+	unsigned int err = 0;
+	unsigned long old_usp;
+
+	/* restore the regs from &sc->regs (same as sc, since regs is first)
+	 * (sc is already checked for VERIFY_READ since the sigframe was
+	 *  checked in sys_sigreturn previously)
+	 */
+
+	if (__copy_from_user(regs, sc, sizeof(struct pt_regs)))
+                goto badframe;
+
+	/* make sure the U-flag is set so user-mode cannot fool us */
+
+	regs->dccr |= 1 << 8;
+
+	/* restore the old USP as it was before we stacked the sc etc.
+	 * (we cannot just pop the sigcontext since we aligned the sp and
+	 *  stuff after pushing it)
+	 */
+
+	err |= __get_user(old_usp, &sc->usp);
+
+	wrusp(old_usp);
+
+	/* TODO: the other ports use regs->orig_XX to disable syscall checks
+	 * after this completes, but we don't use that mechanism. maybe we can
+	 * use it now ? 
+	 */
+
+	return err;
+
+badframe:
+	return 1;
+}
+
+asmlinkage int sys_sigreturn(void)
+{
+	struct pt_regs *regs = (struct pt_regs *)current_regs();
+	struct sigframe *frame = (struct sigframe *)rdusp();
+	sigset_t set;
+
+        /*
+         * Since we stacked the signal on a dword boundary,
+         * then frame should be dword aligned here.  If it's
+         * not, then the user is trying to mess with us.
+         */
+        if (((long)frame) & 3)
+                goto badframe;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__get_user(set.sig[0], &frame->sc.oldmask)
+	    || (_NSIG_WORDS > 1
+		&& __copy_from_user(&set.sig[1], &frame->extramask,
+				    sizeof(frame->extramask))))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+	
+	if (restore_sigcontext(regs, &frame->sc))
+		goto badframe;
+
+	/* TODO: SIGTRAP when single-stepping as in arm ? */
+
+	return regs->r10;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}	
+
+asmlinkage int sys_rt_sigreturn(void)
+{
+	struct pt_regs *regs = (struct pt_regs *)current_regs();
+	struct rt_sigframe *frame = (struct rt_sigframe *)rdusp();
+	sigset_t set;
+	stack_t st;
+
+        /*
+         * Since we stacked the signal on a dword boundary,
+         * then frame should be dword aligned here.  If it's
+         * not, then the user is trying to mess with us.
+         */
+        if (((long)frame) & 3)
+                goto badframe;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+	
+	if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
+		goto badframe;
+
+	if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
+		goto badframe;
+	/* It is more difficult to avoid calling this function than to
+	   call it and ignore errors.  */
+	do_sigaltstack(&st, NULL, rdusp());
+
+	return regs->r10;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}	
+
+/*
+ * Set up a signal frame.
+ */
+
+static int
+setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, unsigned long mask)
+{
+	int err = 0;
+	unsigned long usp = rdusp();
+
+	/* copy the regs. they are first in sc so we can use sc directly */
+
+	err |= __copy_to_user(sc, regs, sizeof(struct pt_regs));
+
+	/* then some other stuff */
+
+	err |= __put_user(mask, &sc->oldmask);
+
+	err |= __put_user(usp, &sc->usp);
+
+	return err;
+}
+
+/* figure out where we want to put the new signal frame - usually on the stack */
+
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
+{
+	unsigned long sp = rdusp();
+
+	/* This is the X/Open sanctioned signal stack switching.  */
+	if (ka->sa.sa_flags & SA_ONSTACK) {
+		if (! on_sig_stack(sp))
+			sp = current->sas_ss_sp + current->sas_ss_size;
+	}
+
+	/* make sure the frame is dword-aligned */
+
+	sp &= ~3;
+
+	return (void *)(sp - frame_size);
+}
+
+/* grab and setup a signal frame.
+ * 
+ * basically we stack a lot of state info, and arrange for the
+ * user-mode program to return to the kernel using either a
+ * trampoline which performs the syscall sigreturn, or a provided
+ * user-mode trampoline.
+ */
+
+static void setup_frame(int sig, struct k_sigaction *ka,
+			sigset_t *set, struct pt_regs * regs)
+{
+	struct sigframe *frame;
+	unsigned long return_ip;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto give_sigsegv;
+
+	err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
+	if (err)
+		goto give_sigsegv;
+
+	if (_NSIG_WORDS > 1) {
+		err |= __copy_to_user(frame->extramask, &set->sig[1],
+				      sizeof(frame->extramask));
+	}
+	if (err)
+		goto give_sigsegv;
+
+	/* Set up to return from userspace.  If provided, use a stub
+	   already in userspace.  */
+	if (ka->sa.sa_flags & SA_RESTORER) {
+		return_ip = (unsigned long)ka->sa.sa_restorer;
+	} else {
+		/* trampoline - the desired return ip is the retcode itself */
+		return_ip = (unsigned long)&frame->retcode;
+		/* This is movu.w __NR_sigreturn, r1; break 13; */
+		/* TODO: check byteorder */
+		err |= __put_user(0x1c5f,         (short *)(frame->retcode+0));
+		err |= __put_user(__NR_sigreturn, (short *)(frame->retcode+2));
+		err |= __put_user(0xe93d,         (short *)(frame->retcode+4));
+	}
+
+	if (err)
+		goto give_sigsegv;
+
+	/* Set up registers for signal handler */
+
+	regs->irp = (unsigned long) ka->sa.sa_handler;  /* what we enter NOW   */
+	regs->srp = return_ip;                          /* what we enter LATER */
+
+	/* actually move the usp to reflect the stacked frame */
+
+	wrusp((unsigned long)frame);
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+			   sigset_t *set, struct pt_regs * regs)
+{
+	struct rt_sigframe *frame;
+	unsigned long return_ip;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto give_sigsegv;
+
+	err |= __put_user(&frame->info, &frame->pinfo);
+	err |= __put_user(&frame->uc, &frame->puc);
+	err |= copy_siginfo_to_user(&frame->info, info);
+	if (err)
+		goto give_sigsegv;
+
+	/* Clear all the bits of the ucontext we don't use.  */
+        err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
+
+	err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
+
+	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+
+	if (err)
+		goto give_sigsegv;
+
+	/* Set up to return from userspace.  If provided, use a stub
+	   already in userspace.  */
+	if (ka->sa.sa_flags & SA_RESTORER) {
+		return_ip = (unsigned long)ka->sa.sa_restorer;
+	} else {
+		/* trampoline - the desired return ip is the retcode itself */
+		return_ip = (unsigned long)&frame->retcode;
+		/* This is movu.w __NR_sigreturn, r1; break 13; */
+		/* TODO: check byteorder */
+		err |= __put_user(0x1c5f,         (short *)(frame->retcode+0));
+		err |= __put_user(__NR_sigreturn, (short *)(frame->retcode+2));
+		err |= __put_user(0xe93d,         (short *)(frame->retcode+4));
+	}
+
+	if (err)
+		goto give_sigsegv;
+
+	/* TODO what is the current->exec_domain stuff and invmap ? */
+
+	/* Set up registers for signal handler */
+
+	regs->irp = (unsigned long) ka->sa.sa_handler;  /* what we enter NOW   */
+	regs->srp = return_ip;                          /* what we enter LATER */
+
+	/* actually move the usp to reflect the stacked frame */
+
+	wrusp((unsigned long)frame);
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+/*
+ * OK, we're invoking a handler
+ */	
+
+static inline void
+handle_signal(int canrestart, unsigned long sig, struct k_sigaction *ka,
+	      siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
+{
+	/* Are we from a system call? */
+	if (canrestart) {
+		/* If so, check system call restarting.. */
+		switch (regs->r10) {
+			case -ERESTARTNOHAND:
+				/* ERESTARTNOHAND means that the syscall should only be
+				   restarted if there was no handler for the signal, and since
+				   we only get here if there is a handler, we dont restart */
+				regs->r10 = -EINTR;
+				break;
+
+			case -ERESTARTSYS:
+				/* ERESTARTSYS means to restart the syscall if there is no
+				   handler or the handler was registered with SA_RESTART */
+				if (!(ka->sa.sa_flags & SA_RESTART)) {
+					regs->r10 = -EINTR;
+					break;
+				}
+			/* fallthrough */
+			case -ERESTARTNOINTR:
+				/* ERESTARTNOINTR means that the syscall should be called again
+				   after the signal handler returns. */
+				RESTART_CRIS_SYS(regs);
+		}
+	}
+
+	/* Set up the stack frame */
+	if (ka->sa.sa_flags & SA_SIGINFO)
+		setup_rt_frame(sig, ka, info, oldset, regs);
+	else
+		setup_frame(sig, ka, oldset, regs);
+
+	if (ka->sa.sa_flags & SA_ONESHOT)
+		ka->sa.sa_handler = SIG_DFL;
+
+	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+		spin_lock_irq(&current->sigmask_lock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		sigaddset(&current->blocked,sig);
+		recalc_sigpending(current);
+		spin_unlock_irq(&current->sigmask_lock);
+	}
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ */
+int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs)
+{
+	siginfo_t info;
+	struct k_sigaction *ka;
+
+	/*
+	 * We want the common case to go fast, which
+	 * is why we may in certain cases get here from
+	 * kernel mode. Just return without doing anything
+	 * if so.
+	 */
+	if (!user_mode(regs))
+		return 1;
+
+	if (!oldset)
+		oldset = &current->blocked;
+
+	for (;;) {
+		unsigned long signr;
+
+		spin_lock_irq(&current->sigmask_lock);
+		signr = dequeue_signal(&current->blocked, &info);
+		spin_unlock_irq(&current->sigmask_lock);
+
+		if (!signr)
+			break;
+
+		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+			/* Let the debugger run.  */
+			current->exit_code = signr;
+			current->state = TASK_STOPPED;
+			notify_parent(current, SIGCHLD);
+			schedule();
+
+			/* We're back.  Did the debugger cancel the sig?  */
+			if (!(signr = current->exit_code))
+				continue;
+			current->exit_code = 0;
+
+			/* The debugger continued.  Ignore SIGSTOP.  */
+			if (signr == SIGSTOP)
+				continue;
+
+			/* Update the siginfo structure.  Is this good?  */
+			if (signr != info.si_signo) {
+				info.si_signo = signr;
+				info.si_errno = 0;
+				info.si_code = SI_USER;
+				info.si_pid = current->p_pptr->pid;
+				info.si_uid = current->p_pptr->uid;
+			}
+
+			/* If the (new) signal is now blocked, requeue it.  */
+			if (sigismember(&current->blocked, signr)) {
+				send_sig_info(signr, &info, current);
+				continue;
+			}
+		}
+
+		ka = &current->sig->action[signr-1];
+		if (ka->sa.sa_handler == SIG_IGN) {
+			if (signr != SIGCHLD)
+				continue;
+			/* Check for SIGCHLD: it's special.  */
+			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+				/* nothing */;
+			continue;
+		}
+
+		if (ka->sa.sa_handler == SIG_DFL) {
+			int exit_code = signr;
+
+			/* Init gets no signals it doesn't want.  */
+			if (current->pid == 1)
+				continue;
+
+			switch (signr) {
+			case SIGCONT: case SIGCHLD: case SIGWINCH:
+				continue;
+
+			case SIGTSTP: case SIGTTIN: case SIGTTOU:
+				if (is_orphaned_pgrp(current->pgrp))
+					continue;
+				/* FALLTHRU */
+
+			case SIGSTOP:
+				current->state = TASK_STOPPED;
+				current->exit_code = signr;
+				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
+					notify_parent(current, SIGCHLD);
+				schedule();
+				continue;
+
+			case SIGQUIT: case SIGILL: case SIGTRAP:
+			case SIGABRT: case SIGFPE: case SIGSEGV:
+			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
+				if (do_coredump(signr, regs))
+					exit_code |= 0x80;
+				/* FALLTHRU */
+
+			default:
+				lock_kernel();
+				sigaddset(&current->pending.signal, signr);
+				recalc_sigpending(current);
+				current->flags |= PF_SIGNALED;
+				do_exit(exit_code);
+				/* NOTREACHED */
+			}
+		}
+
+		/* Whee!  Actually deliver the signal.  */
+		handle_signal(canrestart, signr, ka, &info, oldset, regs);
+		return 1;
+	}
+
+	/* Did we come from a system call? */
+	if (canrestart) {
+		/* Restart the system call - no handlers present */
+		if (regs->r10 == -ERESTARTNOHAND ||
+		    regs->r10 == -ERESTARTSYS ||
+		    regs->r10 == -ERESTARTNOINTR) {
+			RESTART_CRIS_SYS(regs);
+		}
+	}
+	return 0;
+}
diff -urN linux-2.4.2-pre1/arch/cris/kernel/sys_cris.c linux/arch/cris/kernel/sys_cris.c
--- linux-2.4.2-pre1/arch/cris/kernel/sys_cris.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/kernel/sys_cris.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,201 @@
+/* $Id: sys_cris.c,v 1.3 2000/08/02 13:59:02 bjornw Exp $
+ *
+ * linux/arch/cris/kernel/sys_etrax.c
+ *
+ * This file contains various random system calls that
+ * have a non-standard calling sequence on some platforms.
+ * Since we don't have to do any backwards compatibility, our
+ * versions are done in the most "normal" way possible.
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/mman.h>
+#include <linux/file.h>
+
+#include <asm/uaccess.h>
+#include <asm/ipc.h>
+#include <asm/segment.h>
+
+/*
+ * sys_pipe() is the normal C calling standard for creating
+ * a pipe. It's not the way Unix traditionally does this, though.
+ */
+asmlinkage int sys_pipe(unsigned long * fildes)
+{
+        int fd[2];
+        int error;
+
+        lock_kernel();
+        error = do_pipe(fd);
+        unlock_kernel();
+        if (!error) {
+                if (copy_to_user(fildes, fd, 2*sizeof(int)))
+                        error = -EFAULT;
+        }
+        return error;
+}
+
+/* sys_mmap used to take a ptr to a buffer instead containing the args
+ * but we support syscalls with 6 arguments now 
+ */
+
+asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len,
+				  unsigned long prot, unsigned long flags,
+                                  unsigned long fd, off_t offset)
+{
+	struct file * file = NULL;
+        int ret = -EBADF;
+	
+        lock_kernel();
+        if (!(flags & MAP_ANONYMOUS)) {
+                if (!(file = fget(fd)))
+                        goto out;
+        }
+        
+        flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+        down(&current->mm->mmap_sem);
+        ret = do_mmap(file, addr, len, prot, flags, offset);
+        up(&current->mm->mmap_sem);
+        if (file)
+                fput(file);
+ out:
+        unlock_kernel();
+        return ret;
+}
+
+/* common code for old and new mmaps */
+static inline long
+do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
+        unsigned long flags, unsigned long fd, unsigned long pgoff)
+{
+        int error = -EBADF;
+        struct file * file = NULL;
+
+        flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+        if (!(flags & MAP_ANONYMOUS)) {
+                file = fget(fd);
+                if (!file)
+                        goto out;
+        }
+
+        down(&current->mm->mmap_sem);
+        error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+        up(&current->mm->mmap_sem);
+
+        if (file)
+                fput(file);
+out:
+        return error;
+}
+
+asmlinkage unsigned long old_mmap(unsigned long addr, size_t len, int prot,
+                                  int flags, int fd, off_t offset)
+{
+        return do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+}
+
+asmlinkage long
+sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
+          unsigned long flags, unsigned long fd, unsigned long pgoff)
+{
+        return do_mmap2(addr, len, prot, flags, fd, pgoff);
+}
+
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly. (same as arch/i386)
+ */
+
+asmlinkage int sys_ipc (uint call, int first, int second,
+			int third, void *ptr, long fifth)
+{
+	int version, ret;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	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 (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);
+
+	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;
+	}
+}
+
+/* apparently this is legacy - if we don't need this in Linux/CRIS we can remove it. */
+
+asmlinkage int sys_pause(void)
+{
+        current->state = TASK_INTERRUPTIBLE;
+        schedule();
+        return -ERESTARTNOHAND;
+}
diff -urN linux-2.4.2-pre1/arch/cris/kernel/time.c linux/arch/cris/kernel/time.c
--- linux-2.4.2-pre1/arch/cris/kernel/time.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/kernel/time.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,453 @@
+/* $Id: time.c,v 1.4 2000/10/17 14:44:58 bjornw Exp $
+ *
+ *  linux/arch/cris/kernel/time.c
+ *
+ *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
+ *  Copyright (C) 1999, 2000 Axis Communications AB
+ *
+ * 1994-07-02    Alan Modra
+ *	fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
+ * 1995-03-26    Markus Kuhn
+ *      fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887
+ *      precision CMOS clock update
+ * 1996-05-03    Ingo Molnar
+ *      fixed time warps in do_[slow|fast]_gettimeoffset()
+ * 1997-09-10	Updated NTP code according to technical memorandum Jan '96
+ *		"A Kernel Model for Precision Timekeeping" by Dave Mills
+ *
+ * Linux/CRIS specific code:
+ *
+ * Authors:    Bjorn Wesen
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/delay.h>
+#include <asm/rtc.h>
+
+#include <linux/timex.h>
+#include <linux/config.h>
+
+#include <asm/svinto.h>
+
+static int have_rtc;  /* used to remember if we have an RTC or not */
+
+/* define this if you need to use print_timestamp */
+/* it will make jiffies at 96 hz instead of 100 hz though */
+#undef USE_CASCADE_TIMERS
+
+extern int setup_etrax_irq(int, struct irqaction *);
+
+#define TICK_SIZE tick
+
+static unsigned long do_slow_gettimeoffset(void)
+{
+	unsigned long count;
+
+	static unsigned long count_p = LATCH;    /* for the first call after boot */
+	static unsigned long jiffies_p = 0;
+
+	/*
+	 * cache volatile jiffies temporarily; we have IRQs turned off. 
+	 */
+	unsigned long jiffies_t;
+
+	/* The timer interrupt comes from Etrax timer 0. In order to get
+	 * better precision, we check the current value. It might have
+	 * underflowed already though.
+	 */
+
+#ifndef CONFIG_SVINTO_SIM
+	/* Not available in the xsim simulator. */
+	count = *R_TIMER0_DATA;
+#else
+	count = 0;
+#endif
+
+ 	jiffies_t = jiffies;
+
+	/*
+	 * avoiding timer inconsistencies (they are rare, but they happen)...
+	 * there are three kinds of problems that must be avoided here:
+	 *  1. the timer counter underflows
+	 *  2. hardware problem with the timer, not giving us continuous time,
+	 *     the counter does small "jumps" upwards on some Pentium systems,
+	 *     thus causes time warps
+	 *  3. we are after the timer interrupt, but the bottom half handler
+	 *     hasn't executed yet.
+	 */
+	if( jiffies_t == jiffies_p ) {
+		if( count > count_p ) {
+		}
+	} else
+		jiffies_p = jiffies_t;
+
+        count_p = count;
+
+	count = ((LATCH-1) - count) * TICK_SIZE;
+	count = (count + LATCH/2) / LATCH;
+
+	return count;
+}
+
+static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;
+
+/*
+ * This version of gettimeofday has near microsecond resolution.
+ */
+void do_gettimeofday(struct timeval *tv)
+{
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+	*tv = xtime;
+	tv->tv_usec += do_gettimeoffset();
+	if (tv->tv_usec >= 1000000) {
+		tv->tv_usec -= 1000000;
+		tv->tv_sec++;
+	}
+	restore_flags(flags);
+}
+
+void do_settimeofday(struct timeval *tv)
+{
+	cli();
+	/* This is revolting. We need to set the xtime.tv_usec
+	 * correctly. However, the value in this location is
+	 * is value at the last tick.
+	 * Discover what correction gettimeofday
+	 * would have done, and then undo it!
+	 */
+	tv->tv_usec -= do_gettimeoffset();
+
+	if (tv->tv_usec < 0) {
+		tv->tv_usec += 1000000;
+		tv->tv_sec--;
+	}
+
+	xtime = *tv;
+	time_adjust = 0;		/* stop active adjtime() */
+	time_status |= STA_UNSYNC;
+	time_state = TIME_ERROR;	/* p. 24, (a) */
+	time_maxerror = NTP_PHASE_LIMIT;
+	time_esterror = NTP_PHASE_LIMIT;
+	sti();
+}
+
+
+/*
+ * BUG: This routine does not handle hour overflow properly; it just
+ *      sets the minutes. Usually you'll only notice that after reboot!
+ */
+
+static int set_rtc_mmss(unsigned long nowtime)
+{
+	int retval = 0;
+	int real_seconds, real_minutes, cmos_minutes;
+	unsigned char save_control, save_freq_select;
+
+	printk("set_rtc_mmss(%d)\n", nowtime);
+
+	if(!have_rtc)
+		return 0;
+
+	cmos_minutes = CMOS_READ(RTC_MINUTES);
+	BCD_TO_BIN(cmos_minutes);
+
+	/*
+	 * since we're only adjusting minutes and seconds,
+	 * don't interfere with hour overflow. This avoids
+	 * messing with unknown time zones but requires your
+	 * RTC not to be off by more than 15 minutes
+	 */
+	real_seconds = nowtime % 60;
+	real_minutes = nowtime / 60;
+	if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
+		real_minutes += 30;		/* correct for half hour time zone */
+	real_minutes %= 60;
+
+	if (abs(real_minutes - cmos_minutes) < 30) {
+		BIN_TO_BCD(real_seconds);
+		BIN_TO_BCD(real_minutes);
+		CMOS_WRITE(real_seconds,RTC_SECONDS);
+		CMOS_WRITE(real_minutes,RTC_MINUTES);
+	} else {
+		printk(KERN_WARNING
+		       "set_rtc_mmss: can't update from %d to %d\n",
+		       cmos_minutes, real_minutes);
+		retval = -1;
+	}
+
+	return retval;
+}
+
+/* Except from the Etrax100 HSDD about the built-in watchdog:
+ *
+ * 3.10.4 Watchdog timer
+
+ * When the watchdog timer is started, it generates an NMI if the watchdog
+ * isn't restarted or stopped within 0.1 s. If it still isn't restarted or
+ * stopped after an additional 3.3 ms, the watchdog resets the chip.
+ * The watchdog timer is stopped after reset. The watchdog timer is controlled
+ * by the R_WATCHDOG register. The R_WATCHDOG register contains an enable bit
+ * and a 3-bit key value. The effect of writing to the R_WATCHDOG register is
+ * described in the table below:
+ * 
+ *   Watchdog    Value written:
+ *   state:      To enable:  To key:      Operation:
+ *   --------    ----------  -------      ----------
+ *   stopped         0         X          No effect.
+ *   stopped         1       key_val      Start watchdog with key = key_val.
+ *   started         0       ~key         Stop watchdog
+ *   started         1       ~key         Restart watchdog with key = ~key.
+ *   started         X       new_key_val  Change key to new_key_val.
+ * 
+ * Note: '~' is the bitwise NOT operator.
+ * 
+ */
+
+/* right now, starting the watchdog is the same as resetting it */
+#define start_watchdog reset_watchdog
+
+static int watchdog_key = 0;  /* arbitrary number */
+
+/* number of pages to consider "out of memory". it is normal that the memory
+ * is used though, so put this really low.
+ */
+
+#define WATCHDOG_MIN_FREE_PAGES 8
+
+extern int nr_free_pages;
+
+static inline void
+reset_watchdog(void)
+{
+#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
+	/* only keep watchdog happy as long as we have memory left! */
+	if(nr_free_pages > WATCHDOG_MIN_FREE_PAGES) {
+		/* reset the watchdog with the inverse of the old key */
+		watchdog_key ^= 0x7; /* invert key, which is 3 bits */
+		*R_WATCHDOG = IO_FIELD(R_WATCHDOG, key, watchdog_key) |
+			IO_STATE(R_WATCHDOG, enable, start);
+	}
+#endif
+}
+
+/* last time the cmos clock got updated */
+static long last_rtc_update = 0;
+
+/*
+ * timer_interrupt() needs to keep up the real-time clock,
+ * as well as call the "do_timer()" routine every clocktick
+ */
+
+//static unsigned short myjiff; /* used by our debug routine print_timestamp */
+
+static inline void
+timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	/* acknowledge the timer irq */
+
+#ifdef USE_CASCADE_TIMERS
+	*R_TIMER_CTRL =
+		IO_FIELD( R_TIMER_CTRL, timerdiv1, 0) |
+		IO_FIELD( R_TIMER_CTRL, timerdiv0, 0) |
+		IO_STATE( R_TIMER_CTRL, i1, clr) |
+		IO_STATE( R_TIMER_CTRL, tm1, run) |
+		IO_STATE( R_TIMER_CTRL, clksel1, cascade0) |
+		IO_STATE( R_TIMER_CTRL, i0, clr) |
+		IO_STATE( R_TIMER_CTRL, tm0, run) |
+		IO_STATE( R_TIMER_CTRL, clksel0, c6250kHz);
+#else
+	*R_TIMER_CTRL = r_timer_ctrl_shadow | 
+		IO_STATE(R_TIMER_CTRL, i0, clr);
+#endif
+
+	/* reset watchdog otherwise it resets us! */
+
+	reset_watchdog();
+	
+	/* call the real timer interrupt handler */
+
+	do_timer(regs);
+	
+	/*
+	 * If we have an externally synchronized Linux clock, then update
+	 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+	 * called as close as possible to 500 ms before the new second starts.
+	 */
+
+	if ((time_status & STA_UNSYNC) == 0 &&
+	    xtime.tv_sec > last_rtc_update + 660 &&
+	    xtime.tv_usec > 500000 - (tick >> 1) &&
+	    xtime.tv_usec < 500000 + (tick >> 1))
+		if (set_rtc_mmss(xtime.tv_sec) == 0)
+			last_rtc_update = xtime.tv_sec;
+		else
+			last_rtc_update = xtime.tv_sec - 600;
+	
+}
+
+#if 0
+/* some old debug code for testing the microsecond timing of packets */
+static unsigned int lastjiff;
+
+void print_timestamp(const char *s)
+{
+	unsigned long flags;
+	unsigned int newjiff;
+	save_flags(flags);
+	cli();
+	newjiff = (myjiff << 16) | (unsigned short)(-*R_TIMER01_DATA); 
+	printk("%s: %x (%x)\n", s, newjiff, newjiff - lastjiff);
+	lastjiff = newjiff;
+	restore_flags(flags);
+}
+#endif
+
+/* grab the time from the RTC chip */
+
+unsigned long
+get_cmos_time(void)
+{
+	unsigned int year, mon, day, hour, min, sec;
+	int i;
+
+	sec = CMOS_READ(RTC_SECONDS);
+	min = CMOS_READ(RTC_MINUTES);
+	hour = CMOS_READ(RTC_HOURS);
+	day = CMOS_READ(RTC_DAY_OF_MONTH);
+	mon = CMOS_READ(RTC_MONTH);
+	year = CMOS_READ(RTC_YEAR);
+
+	printk("rtc: sec 0x%x min 0x%x hour 0x%x day 0x%x mon 0x%x year 0x%x\n", 
+	       sec, min, hour, day, mon, year);
+
+	BCD_TO_BIN(sec);
+	BCD_TO_BIN(min);
+	BCD_TO_BIN(hour);
+	BCD_TO_BIN(day);
+	BCD_TO_BIN(mon);
+	BCD_TO_BIN(year);
+
+	if ((year += 1900) < 1970)
+		year += 100;
+
+	return mktime(year, mon, day, hour, min, sec);
+}
+
+/* update xtime from the CMOS settings. used when /dev/rtc gets a SET_TIME.
+ * TODO: this doesn't reset the fancy NTP phase stuff as do_settimeofday does.
+ */
+
+void
+update_xtime_from_cmos(void)
+{
+	if(have_rtc) {
+		xtime.tv_sec = get_cmos_time();
+		xtime.tv_usec = 0;
+	}
+}
+
+/* timer is SA_SHIRQ so drivers can add stuff to the timer irq chain
+ * it needs to be SA_INTERRUPT to make the jiffies update work properly
+ */
+
+static struct irqaction irq2  = { timer_interrupt, SA_SHIRQ | SA_INTERRUPT,
+				  0, "timer", NULL, NULL};
+
+void __init
+time_init(void)
+{	
+	/* probe for the RTC and read it if it exists */
+
+	if(RTC_INIT() < 0) {
+		/* no RTC, start at 1980 */
+		xtime.tv_sec = 0;
+		xtime.tv_usec = 0;
+		have_rtc = 0;
+	} else {		
+		/* get the current time */
+		have_rtc = 1;
+		update_xtime_from_cmos();
+	}
+
+	/* Setup the etrax timers
+	 * Base frequency is 19200 hz, divider 192 -> 100 hz as Linux wants
+	 * In normal mode, we use timer0, so timer1 is free. In cascade
+	 * mode (which we sometimes use for debugging) both timers are used.
+	 * Remember that linux/timex.h contains #defines that rely on the
+	 * timer settings below (hz and divide factor) !!!
+	 */
+	
+#ifdef USE_CASCADE_TIMERS
+	*R_TIMER_CTRL =
+		IO_FIELD( R_TIMER_CTRL, timerdiv1, 0) |
+		IO_FIELD( R_TIMER_CTRL, timerdiv0, 0) |
+		IO_STATE( R_TIMER_CTRL, i1, nop) |
+		IO_STATE( R_TIMER_CTRL, tm1, stop_ld) |
+		IO_STATE( R_TIMER_CTRL, clksel1, cascade0) |
+		IO_STATE( R_TIMER_CTRL, i0, nop) |
+		IO_STATE( R_TIMER_CTRL, tm0, stop_ld) |
+		IO_STATE( R_TIMER_CTRL, clksel0, c6250kHz);
+	
+	*R_TIMER_CTRL = r_timer_ctrl_shadow = 
+		IO_FIELD( R_TIMER_CTRL, timerdiv1, 0) |
+		IO_FIELD( R_TIMER_CTRL, timerdiv0, 0) |
+		IO_STATE( R_TIMER_CTRL, i1, nop) |
+		IO_STATE( R_TIMER_CTRL, tm1, run) |
+		IO_STATE( R_TIMER_CTRL, clksel1, cascade0) |
+		IO_STATE( R_TIMER_CTRL, i0, nop) |
+		IO_STATE( R_TIMER_CTRL, tm0, run) |
+		IO_STATE( R_TIMER_CTRL, clksel0, c6250kHz);
+#else
+	*R_TIMER_CTRL = 
+		IO_FIELD(R_TIMER_CTRL, timerdiv1, 192)      | 
+		IO_FIELD(R_TIMER_CTRL, timerdiv0, 192)      |
+		IO_STATE(R_TIMER_CTRL, i1,        nop)      | 
+		IO_STATE(R_TIMER_CTRL, tm1,       stop_ld)  |
+		IO_STATE(R_TIMER_CTRL, clksel1,   c19k2Hz)  |
+		IO_STATE(R_TIMER_CTRL, i0,        nop)      |
+		IO_STATE(R_TIMER_CTRL, tm0,       stop_ld)  |
+		IO_STATE(R_TIMER_CTRL, clksel0,   c19k2Hz);
+	
+	*R_TIMER_CTRL = r_timer_ctrl_shadow =
+		IO_FIELD(R_TIMER_CTRL, timerdiv1, 192)      | 
+		IO_FIELD(R_TIMER_CTRL, timerdiv0, 192)      |
+		IO_STATE(R_TIMER_CTRL, i1,        nop)      |
+		IO_STATE(R_TIMER_CTRL, tm1,       run)      |
+		IO_STATE(R_TIMER_CTRL, clksel1,   c19k2Hz)  |
+		IO_STATE(R_TIMER_CTRL, i0,        nop)      |
+		IO_STATE(R_TIMER_CTRL, tm0,       run)      |
+		IO_STATE(R_TIMER_CTRL, clksel0,   c19k2Hz);
+#endif
+	
+	*R_IRQ_MASK0_SET =
+		IO_STATE(R_IRQ_MASK0_SET, timer0, set); /* unmask the timer irq */
+	
+	/* now actually register the timer irq handler that calls timer_interrupt() */
+	
+	setup_etrax_irq(2, &irq2); /* irq 2 is the timer0 irq in etrax */
+
+	/* enable watchdog if we should use one */
+
+#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
+	printk("Enabling watchdog...\n");
+	start_watchdog();
+#endif
+
+}
diff -urN linux-2.4.2-pre1/arch/cris/kernel/traps.c linux/arch/cris/kernel/traps.c
--- linux-2.4.2-pre1/arch/cris/kernel/traps.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/kernel/traps.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,167 @@
+/* $Id: traps.c,v 1.3 2000/10/04 16:50:06 bjornw Exp $
+ *
+ *  linux/arch/cris/traps.c
+ *
+ *  Etrax100 does not have any hardware traps, only IRQ's, which we setup
+ *  in irq.c instead. Here we just define the die_if_kernel Oops'er.
+ *
+ *  Copyright (C) 2000 Axis Communications AB
+ *
+ *  Authors:   Bjorn Wesen
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+
+#include <asm/system.h>
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+
+int kstack_depth_to_print = 24;
+
+/*
+ * These constants are for searching for possible module text
+ * segments. MODULE_RANGE is a guess of how much space is likely
+ * to be vmalloced.
+ */
+
+#define MODULE_RANGE (8*1024*1024)
+
+void show_stack(unsigned long *sp)
+{
+        unsigned long *stack, addr, module_start, module_end;
+        int i;
+	extern char _stext, _etext;
+
+        // debugging aid: "show_stack(NULL);" prints the
+        // back trace for this cpu.
+
+        if(sp == NULL)
+                sp = (unsigned long*)rdsp();
+
+        stack = sp;
+
+        for(i = 0; i < kstack_depth_to_print; i++) {
+                if (((long) stack & (THREAD_SIZE-1)) == 0)
+                        break;
+                if (i && ((i % 8) == 0))
+                        printk("\n       ");
+                printk("%08lx ", *stack++);
+        }
+
+        printk("\nCall Trace: ");
+        stack = sp;
+        i = 1;
+        module_start = VMALLOC_START;
+        module_end = VMALLOC_END;
+        while (((long) stack & (THREAD_SIZE-1)) != 0) {
+                addr = *stack++;
+                /*
+                 * If the address is either in the text segment of the
+                 * kernel, or in the region which contains vmalloc'ed
+                 * memory, it *may* be the address of a calling
+                 * routine; if so, print it so that someone tracing
+                 * down the cause of the crash will be able to figure
+                 * out the call path that was taken.
+                 */
+                if (((addr >= (unsigned long) &_stext) &&
+                     (addr <= (unsigned long) &_etext)) ||
+                    ((addr >= module_start) && (addr <= module_end))) {
+                        if (i && ((i % 8) == 0))
+                                printk("\n       ");
+                        printk("[<%08lx>] ", addr);
+                        i++;
+                }
+        }
+}
+
+#if 0
+/* displays a short stack trace */
+
+int show_stack()
+{
+	unsigned long *sp = (unsigned long *)rdusp();
+	int i;
+	printk("Stack dump [0x%08lx]:\n", (unsigned long)sp);
+	for(i = 0; i < 16; i++)
+		printk("sp + %d: 0x%08lx\n", i*4, sp[i]);
+	return 0;
+}
+#endif
+
+void show_registers(struct pt_regs * regs)
+{
+	unsigned long usp = rdusp();
+
+	printk("IRP: %08lx SRP: %08lx CCR: %08lx USP: %08lx\n",
+	       regs->irp, regs->srp, regs->dccr, usp );
+	printk(" r0: %08lx  r1: %08lx  r2: %08lx  r3: %08lx\n",
+	       regs->r0, regs->r1, regs->r2, regs->r3);
+	printk(" r4: %08lx  r5: %08lx  r6: %08lx  r7: %08lx\n",
+	       regs->r4, regs->r5, regs->r6, regs->r7);
+	printk(" r8: %08lx  r9: %08lx r10: %08lx r11: %08lx\n",
+	       regs->r8, regs->r9, regs->r10, regs->r11);
+	printk("r12: %08lx r13: %08lx oR10: %08lx\n",
+	       regs->r12, regs->r13, regs->orig_r10);
+	printk("Process %s (pid: %d, stackpage=%08lx)\n",
+	       current->comm, current->pid, (unsigned long)current);
+
+	// TODO, fix in_kernel detection
+
+#if 0
+	/*
+         * When in-kernel, we also print out the stack and code at the
+         * time of the fault..
+         */
+        if (1) {
+		
+                printk("\nStack: ");
+                show_stack((unsigned long*)usp);
+
+                printk("\nCode: ");
+                if(regs->irp < PAGE_OFFSET)
+                        goto bad;
+
+                for(i = 0; i < 20; i++)
+                {
+                        unsigned char c;
+                        if(__get_user(c, &((unsigned char*)regs->irp)[i])) {
+bad:
+                                printk(" Bad IP value.");
+                                break;
+                        }
+                        printk("%02x ", c);
+                }
+        }
+        printk("\n");
+#endif
+}
+
+
+
+void die_if_kernel(const char * str, struct pt_regs * regs, long err)
+{
+	if(user_mode(regs))
+		return;
+
+	printk("%s: %04lx\n", str, err & 0xffff);
+
+	show_registers(regs);
+	show_stack(NULL);  /* print backtrace for kernel stack on this CPU */
+
+	do_exit(SIGSEGV);
+}
+
+void __init trap_init(void)
+{
+  
+
+}
diff -urN linux-2.4.2-pre1/arch/cris/lib/Makefile linux/arch/cris/lib/Makefile
--- linux-2.4.2-pre1/arch/cris/lib/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/lib/Makefile	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,11 @@
+#
+# Makefile for Etrax-specific library files..
+#
+
+.S.o:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o
+
+L_TARGET = lib.a
+obj-y  = checksum.o checksumcopy.o string.o usercopy.o memset.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.2-pre1/arch/cris/lib/checksum.S linux/arch/cris/lib/checksum.S
--- linux-2.4.2-pre1/arch/cris/lib/checksum.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/lib/checksum.S	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,113 @@
+	;; $Id: checksum.S,v 1.1 2000/07/10 16:25:21 bjornw Exp $
+	;; A fast checksum routine using movem
+	;; Copyright (c) 1998 Bjorn Wesen/Axis Communications AB
+
+	;; csum_partial(const unsigned char * buff, int len, unsigned int sum)
+	
+	.globl	_csum_partial
+_csum_partial:
+	
+	;; check for breakeven length between movem and normal word looping versions
+	
+	cmpu.w	80,r11
+	bcs	no_movem
+	nop
+
+	;; need to save the registers we use below in the movem loop
+	;; this overhead is why we have a check above for breakeven length
+	
+	subq	9*4,sp
+	movem	r8,[sp]
+	
+	;; do a movem checksum
+
+	;; r10 - src
+	;; r11 - length
+	;; r12 - checksum
+
+	subq	10*4,r11	; update length for the first loop
+	
+mloop:	movem	[r10+],r9	; read 10 longwords
+
+	;; perform dword checksumming on the 10 longwords
+	
+	add.d	r0,r12
+	ax
+	add.d	r1,r12
+	ax
+	add.d	r2,r12
+	ax
+	add.d	r3,r12
+	ax
+	add.d	r4,r12
+	ax
+	add.d	r5,r12
+	ax
+	add.d	r6,r12
+	ax
+	add.d	r7,r12
+	ax
+	add.d	r8,r12
+	ax
+	add.d	r9,r12
+
+	;; fold the carry into the checksum, to avoid having to loop the carry
+	;; back into the top
+	
+	ax
+	addq	0,r12
+	ax			; do it again, since we might have generated a carry
+	addq	0,r12
+
+	subq	10*4,r11
+	bge	mloop
+	nop
+
+	addq	10*4,r11	; compensate for last loop underflowing length
+
+	;; fold 32-bit checksum into a 16-bit checksum, to avoid carries below
+	
+	moveq	-1,r1		; put 0xffff in r1, faster than move.d 0xffff,r1
+	lsrq	16,r1
+	
+	move.d	r12,r0
+	lsrq	16,r0		; r0 = checksum >> 16
+	and.d	r1,r12		; checksum = checksum & 0xffff
+	add.d	r0,r12		; checksum += r0
+	move.d	r12,r0		; do the same again, maybe we got a carry last add
+	lsrq	16,r0
+	and.d	r1,r12
+	add.d	r0,r12
+	
+	movem	[sp+],r8	; restore regs
+
+no_movem:
+	cmpq	2,r11
+	blt	no_words
+	nop
+	
+	;; checksum the rest of the words
+	
+	subq	2,r11
+	
+wloop:	subq	2,r11
+	bge	wloop
+	addu.w	[r10+],r12
+	
+	addq	2,r11
+		
+no_words:
+	;; see if we have one odd byte more
+	cmpq	1,r11
+	beq	do_byte
+	nop
+	ret
+	move.d	r12, r10
+
+do_byte:	
+	;; copy and checksum the last byte
+	addu.b	[r10],r12
+	ret
+	move.d	r12, r10
+		
+	
\ No newline at end of file
diff -urN linux-2.4.2-pre1/arch/cris/lib/checksumcopy.S linux/arch/cris/lib/checksumcopy.S
--- linux-2.4.2-pre1/arch/cris/lib/checksumcopy.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/lib/checksumcopy.S	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,120 @@
+	;; $Id: checksumcopy.S,v 1.2 2000/08/08 16:57:31 bjornw Exp $
+	;; A fast checksum+copy routine using movem
+	;; Copyright (c) 1998, 2000 Axis Communications AB
+	;;
+	;; Authors:	Bjorn Wesen
+	;; 
+	;; csum_partial_copy_nocheck(const char *src, char *dst,
+	;;		             int len, unsigned int sum)
+
+	.globl	_csum_partial_copy_nocheck
+_csum_partial_copy_nocheck:	
+	
+	;; check for breakeven length between movem and normal word looping versions
+	
+	cmpu.w	80,r12
+	bcs	no_movem
+	nop
+
+	;; need to save the registers we use below in the movem loop
+	;; this overhead is why we have a check above for breakeven length
+	
+	subq	9*4,sp
+	movem	r8,[sp]
+	
+	;; do a movem copy and checksum
+
+	;; r10 - src
+	;; r11 - dst
+	;; r12 - length
+	;; r13 - checksum
+
+	subq	10*4,r12	; update length for the first loop
+	
+mloop:	movem	[r10+],r9	; read 10 longwords
+	movem	r9,[r11+]	; write 10 longwords
+
+	;; perform dword checksumming on the 10 longwords
+	
+	add.d	r0,r13
+	ax
+	add.d	r1,r13
+	ax
+	add.d	r2,r13
+	ax
+	add.d	r3,r13
+	ax
+	add.d	r4,r13
+	ax
+	add.d	r5,r13
+	ax
+	add.d	r6,r13
+	ax
+	add.d	r7,r13
+	ax
+	add.d	r8,r13
+	ax
+	add.d	r9,r13
+
+	;; fold the carry into the checksum, to avoid having to loop the carry
+	;; back into the top
+	
+	ax
+	addq	0,r13
+
+	subq	10*4,r12
+	bge	mloop
+	nop
+
+	addq	10*4,r12	; compensate for last loop underflowing length
+
+	;; fold 32-bit checksum into a 16-bit checksum, to avoid carries below
+	
+	moveq	-1,r1		; put 0xffff in r1, faster than move.d 0xffff,r1
+	lsrq	16,r1
+	
+	move.d	r13,r0
+	lsrq	16,r0		; r0 = checksum >> 16
+	and.d	r1,r13		; checksum = checksum & 0xffff
+	add.d	r0,r13		; checksum += r0
+	move.d	r13,r0		; do the same again, maybe we got a carry last add
+	lsrq	16,r0
+	and.d	r1,r13
+	add.d	r0,r13
+	
+	movem	[sp+],r8	; restore regs
+		
+no_movem:
+	cmpq	2,r12
+	blt	no_words
+	nop
+	
+	;; copy and checksum the rest of the words
+	
+	subq	2,r12
+	
+wloop:	move.w	[r10+],r9
+	addu.w	r9,r13
+	subq	2,r12
+	bge	wloop
+	move.w	r9,[r11+]
+	
+	addq	2,r12
+		
+no_words:
+	;; see if we have one odd byte more
+	cmpq	1,r12
+	beq	do_byte
+	nop
+	ret
+	move.d	r13, r10
+
+do_byte:	
+	;; copy and checksum the last byte
+	move.b	[r10],r9
+	addu.b	r9,r13
+	move.b	r9,[r11]
+	ret
+	move.d	r13, r10
+		
+	
\ No newline at end of file
diff -urN linux-2.4.2-pre1/arch/cris/lib/dmacopy.c linux/arch/cris/lib/dmacopy.c
--- linux-2.4.2-pre1/arch/cris/lib/dmacopy.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/lib/dmacopy.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,43 @@
+/* $Id: dmacopy.c,v 1.1 2000/07/10 16:25:21 bjornw Exp $ 
+ *
+ * memcpy for large blocks, using memory-memory DMA channels 6 and 7 in Etrax
+ */
+
+#include <asm/svinto.h>
+#include <asm/io.h>
+
+#define D(x)
+
+void *dma_memcpy(void *pdst,
+		 const void *psrc,
+		 unsigned int pn)
+{
+	static etrax_dma_descr indma, outdma;
+	
+	D(printk("dma_memcpy %d bytes... ", pn));
+
+#if 0
+	*R_GEN_CONFIG = genconfig_shadow = 
+		(genconfig_shadow & ~0x3c0000) |
+		IO_STATE(R_GEN_CONFIG, dma6, intdma7) |
+		IO_STATE(R_GEN_CONFIG, dma7, intdma6);
+#endif
+	indma.sw_len = outdma.sw_len = pn;
+	indma.ctrl = d_eol | d_eop;
+	outdma.ctrl = d_eol;
+	indma.buf = psrc;
+	outdma.buf = pdst;
+
+	*R_DMA_CH6_FIRST = &indma;
+	*R_DMA_CH7_FIRST = &outdma;
+	*R_DMA_CH6_CMD = IO_STATE(R_DMA_CH6_CMD, cmd, start);
+	*R_DMA_CH7_CMD = IO_STATE(R_DMA_CH7_CMD, cmd, start);
+	
+	while(*R_DMA_CH7_CMD == 1) /* wait for completion */ ;
+
+	D(printk("done\n"));
+
+}
+
+
+
diff -urN linux-2.4.2-pre1/arch/cris/lib/memset.c linux/arch/cris/lib/memset.c
--- linux-2.4.2-pre1/arch/cris/lib/memset.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/lib/memset.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,245 @@
+/*#************************************************************************#*/
+/*#-------------------------------------------------------------------------*/
+/*#                                                                         */
+/*# FUNCTION NAME: memset()                                                 */
+/*#                                                                         */
+/*# PARAMETERS:  void* dst;   Destination address.                          */
+/*#              int     c;   Value of byte to write.                       */
+/*#              int   len;   Number of bytes to write.                     */
+/*#                                                                         */
+/*# RETURNS:     dst.                                                       */
+/*#                                                                         */
+/*# DESCRIPTION: Sets the memory dst of length len bytes to c, as standard. */
+/*#              Framework taken from memcpy.  This routine is              */
+/*#              very sensitive to compiler changes in register allocation. */
+/*#              Should really be rewritten to avoid this problem.          */
+/*#                                                                         */
+/*#-------------------------------------------------------------------------*/
+/*#                                                                         */
+/*# HISTORY                                                                 */
+/*#                                                                         */
+/*# DATE      NAME            CHANGES                                       */
+/*# ----      ----            -------                                       */
+/*# 990713    HP              Tired of watching this function (or           */
+/*#                           really, the nonoptimized generic              */
+/*#                           implementation) take up 90% of simulator      */
+/*#                           output.  Measurements needed.                 */
+/*#                                                                         */
+/*#-------------------------------------------------------------------------*/
+
+/* No, there's no macro saying 12*4, since it is "hard" to get it into
+   the asm in a good way.  Thus better to expose the problem everywhere.
+   */
+
+/* Assuming 1 cycle per dword written or read (ok, not really true), and
+   one per instruction, then 43+3*(n/48-1) <= 24+24*(n/48-1)
+   so n >= 45.7; n >= 0.9; we win on the first full 48-byte block to set. */
+
+#define ZERO_BLOCK_SIZE (1*12*4)
+
+void *memset(void *pdst,
+             int c,
+             unsigned int plen)
+{
+  /* Ok.  Now we want the parameters put in special registers.
+     Make sure the compiler is able to make something useful of this. */
+
+  register char *return_dst __asm__ ("r10") = pdst;
+  register int n __asm__ ("r12") = plen;
+  register int lc __asm__ ("r11") = c;
+
+  /* Most apps use memset sanely.  Only those memsetting about 3..4
+     bytes or less get penalized compared to the generic implementation
+     - and that's not really sane use. */
+
+  /* Ugh.  This is fragile at best.  Check with newer GCC releases, if
+     they compile cascaded "x |= x << 8" sanely! */
+  __asm__("movu.b %0,r13\n\tlslq 8,r13\n\tmove.b %0,r13\n\tmove.d r13,%0\n\tlslq 16,r13\n\tor.d r13,%0"
+          : "=r" (lc) : "0" (lc) : "r13");
+
+  {
+    register char *dst __asm__ ("r13") = pdst;
+ 
+  /* This is NONPORTABLE, but since this whole routine is     */
+  /* grossly nonportable that doesn't matter.                 */
+
+  if (((unsigned long) pdst & 3) != 0
+     /* Oops! n=0 must be a legal call, regardless of alignment. */
+      && n >= 3)
+  {
+    if ((unsigned long)dst & 1)
+    {
+      *dst = (char) lc;
+      n--;
+      dst++;
+    }
+
+    if ((unsigned long)dst & 2)
+    {
+      *(short *)dst = lc;
+      n -= 2;
+      dst += 2;
+    }
+  }
+
+  /* Now the fun part.  For the threshold value of this, check the equation
+     above. */
+  /* Decide which copying method to use. */
+  if (n >= ZERO_BLOCK_SIZE)
+  {
+    /* For large copies we use 'movem' */
+
+  /* It is not optimal to tell the compiler about clobbering any
+     registers; that will move the saving/restoring of those registers
+     to the function prologue/epilogue, and make non-movem sizes
+     suboptimal.
+
+      This method is not foolproof; it assumes that the "asm reg"
+     declarations at the beginning of the function really are used
+     here (beware: they may be moved to temporary registers).
+      This way, we do not have to save/move the registers around into
+     temporaries; we can safely use them straight away.
+
+      If you want to check that the allocation was right; then
+      check the equalities in the first comment.  It should say
+      "r13=r13, r12=r12, r11=r11" */
+    __asm__ volatile ("
+        ;; Check that the following is true (same register names on
+        ;; both sides of equal sign, as in r8=r8):
+        ;; %0=r13, %1=r12, %4=r11
+        ;;
+	;; Save the registers we'll clobber in the movem process
+	;; on the stack.  Don't mention them to gcc, it will only be
+	;; upset.
+	subq 	11*4,sp
+        movem   r10,[sp]
+
+        move.d  r11,r0
+        move.d  r11,r1
+        move.d  r11,r2
+        move.d  r11,r3
+        move.d  r11,r4
+        move.d  r11,r5
+        move.d  r11,r6
+        move.d  r11,r7
+        move.d  r11,r8
+        move.d  r11,r9
+        move.d  r11,r10
+
+        ;; Now we've got this:
+	;; r13 - dst
+	;; r12 - n
+	
+        ;; Update n for the first loop
+        subq    12*4,r12
+0:
+        subq   12*4,r12
+        bge     0b
+	movem	r11,[r13+]
+
+        addq   12*4,r12  ;; compensate for last loop underflowing n
+
+	;; Restore registers from stack
+        movem [sp+],r10" 
+
+     /* Outputs */ : "=r" (dst), "=r" (n)
+     /* Inputs */ : "0" (dst), "1" (n), "r" (lc));
+    
+  }
+
+    /* Either we directly starts copying, using dword copying
+       in a loop, or we copy as much as possible with 'movem' 
+       and then the last block (<44 bytes) is copied here.
+       This will work since 'movem' will have updated src,dst,n. */
+
+    while ( n >= 16 )
+    {
+      *((long*)dst)++ = lc;
+      *((long*)dst)++ = lc;
+      *((long*)dst)++ = lc;
+      *((long*)dst)++ = lc;
+      n -= 16;
+    }
+
+    /* A switch() is definitely the fastest although it takes a LOT of code.
+     * Particularly if you inline code this.
+     */
+    switch (n)
+    {
+      case 0:
+        break;
+      case 1:
+        *(char*)dst = (char) lc;
+        break;
+      case 2:
+        *(short*)dst = (short) lc;
+        break;
+      case 3:
+        *((short*)dst)++ = (short) lc;
+        *(char*)dst = (char) lc;
+        break;
+      case 4:
+        *((long*)dst)++ = lc;
+        break;
+      case 5:
+        *((long*)dst)++ = lc;
+        *(char*)dst = (char) lc;
+        break;
+      case 6:
+        *((long*)dst)++ = lc;
+        *(short*)dst = (short) lc;
+        break;
+      case 7:
+        *((long*)dst)++ = lc;
+        *((short*)dst)++ = (short) lc;
+        *(char*)dst = (char) lc;
+        break;
+      case 8:
+        *((long*)dst)++ = lc;
+        *((long*)dst)++ = lc;
+        break;
+      case 9:
+        *((long*)dst)++ = lc;
+        *((long*)dst)++ = lc;
+        *(char*)dst = (char) lc;
+        break;
+      case 10:
+        *((long*)dst)++ = lc;
+        *((long*)dst)++ = lc;
+        *(short*)dst = (short) lc;
+        break;
+      case 11:
+        *((long*)dst)++ = lc;
+        *((long*)dst)++ = lc;
+        *((short*)dst)++ = (short) lc;
+        *(char*)dst = (char) lc;
+        break;
+      case 12:
+        *((long*)dst)++ = lc;
+        *((long*)dst)++ = lc;
+        *((long*)dst)++ = lc;
+        break;
+      case 13:
+        *((long*)dst)++ = lc;
+        *((long*)dst)++ = lc;
+        *((long*)dst)++ = lc;
+        *(char*)dst = (char) lc;
+        break;
+      case 14:
+        *((long*)dst)++ = lc;
+        *((long*)dst)++ = lc;
+        *((long*)dst)++ = lc;
+        *(short*)dst = (short) lc;
+        break;
+      case 15:
+        *((long*)dst)++ = lc;
+        *((long*)dst)++ = lc;
+        *((long*)dst)++ = lc;
+        *((short*)dst)++ = (short) lc;
+        *(char*)dst = (char) lc;
+        break;
+    }
+  }
+
+  return return_dst; /* destination pointer. */
+} /* memset() */
diff -urN linux-2.4.2-pre1/arch/cris/lib/old_checksum.c linux/arch/cris/lib/old_checksum.c
--- linux-2.4.2-pre1/arch/cris/lib/old_checksum.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/lib/old_checksum.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,127 @@
+/* $Id: old_checksum.c,v 1.1 2000/07/10 16:25:21 bjornw Exp $
+ *
+ * INET		An implementation of the TCP/IP protocol suite for the LINUX
+ *		operating system.  INET is implemented using the  BSD Socket
+ *		interface as the means of communication with the user level.
+ *
+ *		IP/TCP/UDP checksumming routines
+ *
+ * Authors:	Jorge Cwik, <jorge@laser.satlink.net>
+ *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
+ *		Tom May, <ftom@netcom.com>
+ *		Lots of code moved from tcp.c and ip.c; see those files
+ *		for more names.
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ */
+
+#include <net/checksum.h>
+
+#undef PROFILE_CHECKSUM
+
+#ifdef PROFILE_CHECKSUM
+/* these are just for profiling the checksum code with an oscillioscope.. uh */
+#if 0
+#define BITOFF *((unsigned char *)0xb0000030) = 0xff
+#define BITON *((unsigned char *)0xb0000030) = 0x0
+#endif
+#include <asm/io.h>
+#define CBITON LED_ACTIVE_SET(1)
+#define CBITOFF LED_ACTIVE_SET(0)
+#define BITOFF
+#define BITON
+#else
+#define BITOFF
+#define BITON
+#define CBITOFF
+#define CBITON
+#endif
+
+/*
+ * computes a partial checksum, e.g. for TCP/UDP fragments
+ */
+
+#include <asm/delay.h>
+
+unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
+{
+  /*
+   * Experiments with ethernet and slip connections show that buff
+   * is aligned on either a 2-byte or 4-byte boundary.
+   */
+  const unsigned char *endMarker = buff + len;
+  const unsigned char *marker = endMarker - (len % 16);
+#if 0
+  if((int)buff & 0x3)
+    printk("unaligned buff %p\n", buff);
+  __delay(900); /* extra delay of 90 us to test performance hit */
+#endif
+  BITON;
+  while (buff < marker) {
+    sum += *((unsigned short *)buff)++;
+    sum += *((unsigned short *)buff)++;
+    sum += *((unsigned short *)buff)++;
+    sum += *((unsigned short *)buff)++;
+    sum += *((unsigned short *)buff)++;
+    sum += *((unsigned short *)buff)++;
+    sum += *((unsigned short *)buff)++;
+    sum += *((unsigned short *)buff)++;
+  }
+  marker = endMarker - (len % 2);
+  while(buff < marker) {
+    sum += *((unsigned short *)buff)++;
+  }
+  if(endMarker - buff > 0) {
+    sum += *buff;                 /* add extra byte seperately */
+  }
+  BITOFF;
+  return(sum);
+}
+
+#if 0
+
+/*
+ * copy while checksumming, otherwise like csum_partial
+ */
+
+unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst, 
+				  int len, unsigned int sum)
+{
+  const unsigned char *endMarker;
+  const unsigned char *marker;
+  printk("csum_partial_copy len %d.\n", len);
+#if 0
+  if((int)src & 0x3)
+    printk("unaligned src %p\n", src);
+  if((int)dst & 0x3)
+    printk("unaligned dst %p\n", dst);
+  __delay(1800); /* extra delay of 90 us to test performance hit */
+#endif
+  endMarker = src + len;
+  marker = endMarker - (len % 16);
+  CBITON;
+  while(src < marker) {
+    sum += (*((unsigned short *)dst)++ = *((unsigned short *)src)++);
+    sum += (*((unsigned short *)dst)++ = *((unsigned short *)src)++);
+    sum += (*((unsigned short *)dst)++ = *((unsigned short *)src)++);
+    sum += (*((unsigned short *)dst)++ = *((unsigned short *)src)++);
+    sum += (*((unsigned short *)dst)++ = *((unsigned short *)src)++);
+    sum += (*((unsigned short *)dst)++ = *((unsigned short *)src)++);
+    sum += (*((unsigned short *)dst)++ = *((unsigned short *)src)++);
+    sum += (*((unsigned short *)dst)++ = *((unsigned short *)src)++);
+  }
+  marker = endMarker - (len % 2);
+  while(src < marker) {
+    sum += (*((unsigned short *)dst)++ = *((unsigned short *)src)++);
+  }
+  if(endMarker - src > 0) {
+    sum += (*dst = *src);                 /* add extra byte seperately */
+  }
+  CBITOFF;
+  return(sum);
+}
+
+#endif
diff -urN linux-2.4.2-pre1/arch/cris/lib/string.c linux/arch/cris/lib/string.c
--- linux-2.4.2-pre1/arch/cris/lib/string.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/lib/string.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,223 @@
+/*#************************************************************************#*/
+/*#-------------------------------------------------------------------------*/
+/*#                                                                         */
+/*# FUNCTION NAME: memcpy()                                                 */
+/*#                                                                         */
+/*# PARAMETERS:  void* dst;   Destination address.                          */
+/*#              void* src;   Source address.                               */
+/*#              int   len;   Number of bytes to copy.                      */
+/*#                                                                         */
+/*# RETURNS:     dst.                                                       */
+/*#                                                                         */
+/*# DESCRIPTION: Copies len bytes of memory from src to dst.  No guarantees */
+/*#              about copying of overlapping memory areas. This routine is */
+/*#              very sensitive to compiler changes in register allocation. */
+/*#              Should really be rewritten to avoid this problem.          */
+/*#                                                                         */
+/*#-------------------------------------------------------------------------*/
+/*#                                                                         */
+/*# HISTORY                                                                 */
+/*#                                                                         */
+/*# DATE      NAME            CHANGES                                       */
+/*# ----      ----            -------                                       */
+/*# 941007    Kenny R         Creation                                      */
+/*# 941011    Kenny R         Lots of optimizations and inlining.           */
+/*# 941129    Ulf A           Adapted for use in libc.                      */
+/*# 950216    HP              N==0 forgotten if non-aligned src/dst.        */
+/*#                           Added some optimizations.                     */
+/*# 001025    HP              Make src and dst char *.  Align dst to	    */
+/*#			      dword, not just word-if-both-src-and-dst-	    */
+/*#			      are-misaligned.				    */
+/*#                                                                         */
+/*#-------------------------------------------------------------------------*/
+
+void *memcpy(void *pdst,
+             const void *psrc,
+             unsigned int pn)
+{
+  /* Ok.  Now we want the parameters put in special registers.
+     Make sure the compiler is able to make something useful of this.
+      As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
+
+     If gcc was allright, it really would need no temporaries, and no
+     stack space to save stuff on. */
+
+  register void *return_dst __asm__ ("r10") = pdst;
+  register char *dst __asm__ ("r13") = pdst;
+  register const char *src __asm__ ("r11") = psrc;
+  register int n __asm__ ("r12") = pn;
+  
+ 
+  /* When src is aligned but not dst, this makes a few extra needless
+     cycles.  I believe it would take as many to check that the
+     re-alignment was unnecessary.  */
+  if (((unsigned long) dst & 3) != 0
+      /* Don't align if we wouldn't copy more than a few bytes; so we
+	 don't have to check further for overflows.  */
+      && n >= 3)
+  {
+    if ((unsigned long) dst & 1)
+    {
+      n--;
+      *(char*)dst = *(char*)src;
+      src++;
+      dst++;
+    }
+
+    if ((unsigned long) dst & 2)
+    {
+      n -= 2;
+      *(short*)dst = *(short*)src;
+      src += 2;
+      dst += 2;
+    }
+  }
+
+  /* Decide which copying method to use. */
+  if (n >= 44*2)                /* Break even between movem and
+                                   move16 is at 38.7*2, but modulo 44. */
+  {
+    /* For large copies we use 'movem' */
+
+  /* It is not optimal to tell the compiler about clobbering any
+     registers; that will move the saving/restoring of those registers
+     to the function prologue/epilogue, and make non-movem sizes
+     suboptimal.
+
+      This method is not foolproof; it assumes that the "asm reg"
+     declarations at the beginning of the function really are used
+     here (beware: they may be moved to temporary registers).
+      This way, we do not have to save/move the registers around into
+     temporaries; we can safely use them straight away.
+
+      If you want to check that the allocation was right; then
+      check the equalities in the first comment.  It should say
+      "r13=r13, r11=r11, r12=r12" */
+    __asm__ volatile ("
+        ;; Check that the following is true (same register names on
+        ;; both sides of equal sign, as in r8=r8):
+        ;; %0=r13, %1=r11, %2=r12
+        ;;
+	;; Save the registers we'll use in the movem process
+	;; on the stack.
+	subq 	11*4,sp
+	movem	r10,[sp]
+
+        ;; Now we've got this:
+	;; r11 - src
+	;; r13 - dst
+	;; r12 - n
+	
+        ;; Update n for the first loop
+        subq    44,r12
+0:
+	movem	[r11+],r10
+        subq   44,r12
+        bge     0b
+	movem	r10,[r13+]
+
+        addq   44,r12  ;; compensate for last loop underflowing n
+
+	;; Restore registers from stack
+        movem [sp+],r10" 
+
+     /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n) 
+     /* Inputs */ : "0" (dst), "1" (src), "2" (n));
+    
+  }
+
+  /* Either we directly starts copying, using dword copying
+     in a loop, or we copy as much as possible with 'movem' 
+     and then the last block (<44 bytes) is copied here.
+     This will work since 'movem' will have updated src,dst,n. */
+
+  while ( n >= 16 )
+  {
+    *((long*)dst)++ = *((long*)src)++;
+    *((long*)dst)++ = *((long*)src)++;
+    *((long*)dst)++ = *((long*)src)++;
+    *((long*)dst)++ = *((long*)src)++;
+    n -= 16;
+  }
+
+  /* A switch() is definitely the fastest although it takes a LOT of code.
+   * Particularly if you inline code this.
+   */
+  switch (n)
+  {
+    case 0:
+      break;
+    case 1:
+      *(char*)dst = *(char*)src;
+      break;
+    case 2:
+      *(short*)dst = *(short*)src;
+      break;
+    case 3:
+      *((short*)dst)++ = *((short*)src)++;
+      *(char*)dst = *(char*)src;
+      break;
+    case 4:
+      *((long*)dst)++ = *((long*)src)++;
+      break;
+    case 5:
+      *((long*)dst)++ = *((long*)src)++;
+      *(char*)dst = *(char*)src;
+      break;
+    case 6:
+      *((long*)dst)++ = *((long*)src)++;
+      *(short*)dst = *(short*)src;
+      break;
+    case 7:
+      *((long*)dst)++ = *((long*)src)++;
+      *((short*)dst)++ = *((short*)src)++;
+      *(char*)dst = *(char*)src;
+      break;
+    case 8:
+      *((long*)dst)++ = *((long*)src)++;
+      *((long*)dst)++ = *((long*)src)++;
+      break;
+    case 9:
+      *((long*)dst)++ = *((long*)src)++;
+      *((long*)dst)++ = *((long*)src)++;
+      *(char*)dst = *(char*)src;
+      break;
+    case 10:
+      *((long*)dst)++ = *((long*)src)++;
+      *((long*)dst)++ = *((long*)src)++;
+      *(short*)dst = *(short*)src;
+      break;
+    case 11:
+      *((long*)dst)++ = *((long*)src)++;
+      *((long*)dst)++ = *((long*)src)++;
+      *((short*)dst)++ = *((short*)src)++;
+      *(char*)dst = *(char*)src;
+      break;
+    case 12:
+      *((long*)dst)++ = *((long*)src)++;
+      *((long*)dst)++ = *((long*)src)++;
+      *((long*)dst)++ = *((long*)src)++;
+      break;
+    case 13:
+      *((long*)dst)++ = *((long*)src)++;
+      *((long*)dst)++ = *((long*)src)++;
+      *((long*)dst)++ = *((long*)src)++;
+      *(char*)dst = *(char*)src;
+      break;
+    case 14:
+      *((long*)dst)++ = *((long*)src)++;
+      *((long*)dst)++ = *((long*)src)++;
+      *((long*)dst)++ = *((long*)src)++;
+      *(short*)dst = *(short*)src;
+      break;
+    case 15:
+      *((long*)dst)++ = *((long*)src)++;
+      *((long*)dst)++ = *((long*)src)++;
+      *((long*)dst)++ = *((long*)src)++;
+      *((short*)dst)++ = *((short*)src)++;
+      *(char*)dst = *(char*)src;
+      break;
+  }
+
+  return return_dst; /* destination pointer. */
+} /* memcpy() */
diff -urN linux-2.4.2-pre1/arch/cris/lib/usercopy.c linux/arch/cris/lib/usercopy.c
--- linux-2.4.2-pre1/arch/cris/lib/usercopy.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/lib/usercopy.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,501 @@
+/*
+ * User address space access functions.
+ * The non-inlined parts of asm-cris/uaccess.h are here.
+ *
+ * Copyright (C) 2000, Axis Communications AB.
+ *
+ * Written by Hans-Peter Nilsson.
+ * Pieces used from memcpy, originally by Kenny Ranerup long time ago.
+ */
+
+#include <asm/uaccess.h>
+
+/* Asm:s have been tweaked (within the domain of correctness) to give
+   satisfactory results for "gcc version 2.96 20000427 (experimental)".
+
+   Check regularly...
+
+   Note that the PC saved at a bus-fault is the address *after* the
+   faulting instruction, which means the branch-target for instructions in
+   delay-slots for taken branches.  Note also that the postincrement in
+   the instruction is performed regardless of bus-fault; the register is
+   seen updated in fault handlers.
+
+   Oh, and on the code formatting issue, to whomever feels like "fixing
+   it" to Conformity: I'm too "lazy", but why don't you go ahead and "fix"
+   string.c too.  I just don't think too many people will hack this file
+   for the code format to be an issue.  */
+
+
+/* Copy to userspace.  This is based on the memcpy used for
+   kernel-to-kernel copying; see "string.c".  */
+
+unsigned long
+__copy_user (void *pdst, const void *psrc, unsigned long pn)
+{
+  /* We want the parameters put in special registers.
+     Make sure the compiler is able to make something useful of this.
+     As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
+
+     FIXME: Comment for old gcc version.  Check.
+     If gcc was allright, it really would need no temporaries, and no
+     stack space to save stuff on. */
+
+  register char *dst __asm__ ("r13") = pdst;
+  register const char *src __asm__ ("r11") = psrc;
+  register int n __asm__ ("r12") = pn;
+  register int retn __asm__ ("r10") = 0;
+
+
+  /* When src is aligned but not dst, this makes a few extra needless
+     cycles.  I believe it would take as many to check that the
+     re-alignment was unnecessary.  */
+  if (((unsigned long) dst & 3) != 0
+      /* Don't align if we wouldn't copy more than a few bytes; so we
+	 don't have to check further for overflows.  */
+      && n >= 3)
+  {
+    if ((unsigned long) dst & 1)
+    {
+      __asm_copy_to_user_1 (dst, src, retn);
+      n--;
+    }
+
+    if ((unsigned long) dst & 2)
+    {
+      __asm_copy_to_user_2 (dst, src, retn);
+      n -= 2;
+    }
+  }
+
+  /* Decide which copying method to use. */
+  if (n >= 44*2)		/* Break even between movem and
+				   move16 is at 38.7*2, but modulo 44. */
+  {
+    /* For large copies we use 'movem'.  */
+
+    /* It is not optimal to tell the compiler about clobbering any
+       registers; that will move the saving/restoring of those registers
+       to the function prologue/epilogue, and make non-movem sizes
+       suboptimal.
+
+       This method is not foolproof; it assumes that the "asm reg"
+       declarations at the beginning of the function really are used
+       here (beware: they may be moved to temporary registers).
+       This way, we do not have to save/move the registers around into
+       temporaries; we can safely use them straight away.
+
+       If you want to check that the allocation was right; then
+       check the equalities in the first comment.  It should say
+       "r13=r13, r11=r11, r12=r12".  */
+    __asm__ volatile ("
+	;; Check that the following is true (same register names on
+	;; both sides of equal sign, as in r8=r8):
+	;; %0=r13, %1=r11, %2=r12 %3=r10
+	;;
+	;; Save the registers we'll use in the movem process
+	;; on the stack.
+	subq	11*4,sp
+	movem	r10,[sp]
+
+	;; Now we've got this:
+	;; r11 - src
+	;; r13 - dst
+	;; r12 - n
+
+	;; Update n for the first loop
+	subq	44,r12
+
+; Since the noted PC of a faulting instruction in a delay-slot of a taken
+; branch, is that of the branch target, we actually point at the from-movem
+; for this case.  There is no ambiguity here; if there was a fault in that
+; instruction (meaning a kernel oops), the faulted PC would be the address
+; after *that* movem.
+
+0:
+	movem	[r11+],r10
+	subq   44,r12
+	bge	0b
+	movem	r10,[r13+]
+1:
+	addq   44,r12  ;; compensate for last loop underflowing n
+
+	;; Restore registers from stack
+	movem [sp+],r10
+2:
+	.section .fixup,\"ax\"
+
+; To provide a correct count in r10 of bytes that failed to be copied,
+; we jump back into the loop if the loop-branch was taken.  There is no
+; performance penalty for sany use; the program will segfault soon enough.
+
+3:
+	move.d [sp],r10
+	addq 44,r10
+	move.d r10,[sp]
+	jump 0b
+4:
+	movem [sp+],r10
+	addq 44,r10
+	addq 44,r12
+	jump 2b
+
+	.previous
+	.section __ex_table,\"a\"
+	.dword 0b,3b
+	.dword 1b,4b
+	.previous"
+
+     /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n), "=r" (retn)
+     /* Inputs */ : "0" (dst), "1" (src), "2" (n), "3" (retn));
+
+  }
+
+  /* Either we directly start copying, using dword copying in a loop, or
+     we copy as much as possible with 'movem' and then the last block (<44
+     bytes) is copied here.  This will work since 'movem' will have
+     updated SRC, DST and N.  */
+
+  while (n >= 16)
+  {
+    __asm_copy_to_user_16 (dst, src, retn);
+    n -= 16;
+  }
+
+  /* Having a separate by-four loops cuts down on cache footprint.
+     FIXME:  Test with and without; increasing switch to be 0..15.  */
+  while (n >= 4)
+  {
+    __asm_copy_to_user_4 (dst, src, retn);
+    n -= 4;
+  }
+
+  switch (n)
+  {
+    case 0:
+      break;
+    case 1:
+      __asm_copy_to_user_1 (dst, src, retn);
+      break;
+    case 2:
+      __asm_copy_to_user_2 (dst, src, retn);
+      break;
+    case 3:
+      __asm_copy_to_user_3 (dst, src, retn);
+      break;
+  }
+
+  return retn;
+}
+
+/* Copy from user to kernel, zeroing the bytes that were inaccessible in
+   userland.  */
+
+unsigned long
+__copy_user_zeroing (void *pdst, const void *psrc, unsigned long pn)
+{
+  /* We want the parameters put in special registers.
+     Make sure the compiler is able to make something useful of this.
+     As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
+
+     FIXME: Comment for old gcc version.  Check.
+     If gcc was allright, it really would need no temporaries, and no
+     stack space to save stuff on.  */
+
+  register char *dst __asm__ ("r13") = pdst;
+  register const char *src __asm__ ("r11") = psrc;
+  register int n __asm__ ("r12") = pn;
+  register int retn __asm__ ("r10") = 0;
+
+  /* When src is aligned but not dst, this makes a few extra needless
+     cycles.  I believe it would take as many to check that the
+     re-alignment was unnecessary.  */
+  if (((unsigned long) dst & 3) != 0
+      /* Don't align if we wouldn't copy more than a few bytes; so we
+	 don't have to check further for overflows.  */
+      && n >= 3)
+  {
+    if ((unsigned long) dst & 1)
+    {
+      __asm_copy_from_user_1 (dst, src, retn);
+      n--;
+    }
+
+    if ((unsigned long) dst & 2)
+    {
+      __asm_copy_from_user_2 (dst, src, retn);
+      n -= 2;
+    }
+  }
+
+  /* Decide which copying method to use. */
+  if (n >= 44*2)		/* Break even between movem and
+				   move16 is at 38.7*2, but modulo 44. */
+  {
+    /* For large copies we use 'movem' */
+
+    /* It is not optimal to tell the compiler about clobbering any
+       registers; that will move the saving/restoring of those registers
+       to the function prologue/epilogue, and make non-movem sizes
+       suboptimal.
+
+       This method is not foolproof; it assumes that the "asm reg"
+       declarations at the beginning of the function really are used
+       here (beware: they may be moved to temporary registers).
+       This way, we do not have to save/move the registers around into
+       temporaries; we can safely use them straight away.
+
+       If you want to check that the allocation was right; then
+       check the equalities in the first comment.  It should say
+       "r13=r13, r11=r11, r12=r12" */
+    __asm__ volatile ("
+	;; Check that the following is true (same register names on
+	;; both sides of equal sign, as in r8=r8):
+	;; %0=r13, %1=r11, %2=r12 %3=r10
+	;;
+	;; Save the registers we'll use in the movem process
+	;; on the stack.
+	subq	11*4,sp
+	movem	r10,[sp]
+
+	;; Now we've got this:
+	;; r11 - src
+	;; r13 - dst
+	;; r12 - n
+
+	;; Update n for the first loop
+	subq	44,r12
+0:
+	movem	[r11+],r10
+1:
+	subq   44,r12
+	bge	0b
+	movem	r10,[r13+]
+
+	addq   44,r12  ;; compensate for last loop underflowing n
+
+	;; Restore registers from stack
+	movem [sp+],r10
+
+	.section .fixup,\"ax\"
+
+; To provide a correct count in r10 of bytes that failed to be copied,
+; we jump back into the loop if the loop-branch was taken.
+;  There is no performance penalty; the program will segfault soon
+; enough.
+
+3:
+	move.d [sp],r10
+	addq 44,r10
+	move.d r10,[sp]
+	clear.d r0
+	clear.d r1
+	clear.d r2
+	clear.d r3
+	clear.d r4
+	clear.d r5
+	clear.d r6
+	clear.d r7
+	clear.d r8
+	clear.d r9
+	clear.d r10
+	jump 1b
+
+	.previous
+	.section __ex_table,\"a\"
+	.dword 1b,3b
+	.previous"
+
+     /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n), "=r" (retn)
+     /* Inputs */ : "0" (dst), "1" (src), "2" (n), "3" (retn));
+
+  }
+
+  /* Either we directly start copying here, using dword copying in a loop,
+     or we copy as much as possible with 'movem' and then the last block
+     (<44 bytes) is copied here.  This will work since 'movem' will have
+     updated src, dst and n. */
+
+  while (n >= 16)
+  {
+    __asm_copy_from_user_16 (dst, src, retn);
+    n -= 16;
+  }
+
+  /* Having a separate by-four loops cuts down on cache footprint.
+     FIXME:  Test with and without; increasing switch to be 0..15.  */
+  while (n >= 4)
+  {
+    __asm_copy_from_user_4 (dst, src, retn);
+    n -= 4;
+  }
+
+  switch (n)
+  {
+    case 0:
+      break;
+    case 1:
+      __asm_copy_from_user_1 (dst, src, retn);
+      break;
+    case 2:
+      __asm_copy_from_user_2 (dst, src, retn);
+      break;
+    case 3:
+      __asm_copy_from_user_3 (dst, src, retn);
+      break;
+  }
+
+  return retn;
+}
+
+/* Zero userspace.  */
+
+unsigned long
+__do_clear_user (void *pto, unsigned long pn)
+{
+  /* We want the parameters put in special registers.
+     Make sure the compiler is able to make something useful of this.
+      As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
+
+     FIXME: Comment for old gcc version.  Check.
+     If gcc was allright, it really would need no temporaries, and no
+     stack space to save stuff on. */
+
+  register char *dst __asm__ ("r13") = pto;
+  register int n __asm__ ("r12") = pn;
+  register int retn __asm__ ("r10") = 0;
+
+
+  if (((unsigned long) dst & 3) != 0
+     /* Don't align if we wouldn't copy more than a few bytes.  */
+      && n >= 3)
+  {
+    if ((unsigned long) dst & 1)
+    {
+      __asm_clear_1 (dst, retn);
+      n--;
+    }
+
+    if ((unsigned long) dst & 2)
+    {
+      __asm_clear_2 (dst, retn);
+      n -= 2;
+    }
+  }
+
+  /* Decide which copying method to use.
+     FIXME: This number is from the "ordinary" kernel memset.  */
+  if (n >= (1*48))
+  {
+    /* For large clears we use 'movem' */
+
+    /* It is not optimal to tell the compiler about clobbering any
+       call-saved registers; that will move the saving/restoring of
+       those registers to the function prologue/epilogue, and make
+       non-movem sizes suboptimal.
+
+       This method is not foolproof; it assumes that the "asm reg"
+       declarations at the beginning of the function really are used
+       here (beware: they may be moved to temporary registers).
+       This way, we do not have to save/move the registers around into
+       temporaries; we can safely use them straight away.
+
+      If you want to check that the allocation was right; then
+      check the equalities in the first comment.  It should say
+      something like "r13=r13, r11=r11, r12=r12". */
+    __asm__ volatile ("
+	;; Check that the following is true (same register names on
+	;; both sides of equal sign, as in r8=r8):
+	;; %0=r13, %1=r12 %2=r10
+	;;
+	;; Save the registers we'll clobber in the movem process
+	;; on the stack.  Don't mention them to gcc, it will only be
+	;; upset.
+	subq	11*4,sp
+	movem	r10,[sp]
+
+	clear.d r0
+	clear.d r1
+	clear.d r2
+	clear.d r3
+	clear.d r4
+	clear.d r5
+	clear.d r6
+	clear.d r7
+	clear.d r8
+	clear.d r9
+	clear.d r10
+	clear.d r11
+
+	;; Now we've got this:
+	;; r13 - dst
+	;; r12 - n
+
+	;; Update n for the first loop
+	subq	12*4,r12
+0:
+	subq   12*4,r12
+	bge	0b
+	movem	r11,[r13+]
+1:
+	addq   12*4,r12	 ;; compensate for last loop underflowing n
+
+	;; Restore registers from stack
+	movem [sp+],r10
+2:
+	.section .fixup,\"ax\"
+3:
+	move.d [sp],r10
+	addq 12*4,r10
+	move.d r10,[sp]
+	clear.d r10
+	jump 0b
+
+4:
+	movem [sp+],r10
+	addq 12*4,r10
+	addq 12*4,r12
+	jump 2b
+
+	.previous
+	.section __ex_table,\"a\"
+	.dword 0b,3b
+	.dword 1b,4b
+	.previous"
+
+     /* Outputs */ : "=r" (dst), "=r" (n), "=r" (retn)
+     /* Inputs */ : "0" (dst), "1" (n), "2" (retn)
+     /* Clobber */ : "r11");
+  }
+
+  while (n >= 16)
+  {
+    __asm_clear_16 (dst, retn);
+    n -= 16;
+  }
+
+  /* Having a separate by-four loops cuts down on cache footprint.
+     FIXME:  Test with and without; increasing switch to be 0..15.  */
+  while (n >= 4)
+  {
+    __asm_clear_4 (dst, retn);
+    n -= 4;
+  }
+
+  switch (n)
+  {
+    case 0:
+      break;
+    case 1:
+      __asm_clear_1 (dst, retn);
+      break;
+    case 2:
+      __asm_clear_2 (dst, retn);
+      break;
+    case 3:
+      __asm_clear_3 (dst, retn);
+      break;
+  }
+
+  return retn;
+}
diff -urN linux-2.4.2-pre1/arch/cris/mm/Makefile linux/arch/cris/mm/Makefile
--- linux-2.4.2-pre1/arch/cris/mm/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/mm/Makefile	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,13 @@
+#
+# Makefile for the linux cris-specific parts of the memory manager.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
+O_TARGET := mm.o
+obj-y	 := init.o fault.o tlb.o extable.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.2-pre1/arch/cris/mm/extable.c linux/arch/cris/mm/extable.c
--- linux-2.4.2-pre1/arch/cris/mm/extable.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/mm/extable.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,55 @@
+/*
+ * linux/arch/cris/mm/extable.c
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+
+extern const struct exception_table_entry _start___ex_table[];
+extern const struct exception_table_entry _stop___ex_table[];
+
+static inline unsigned long
+search_one_table(const struct exception_table_entry *first,
+		 const struct exception_table_entry *last,
+		 unsigned long value)
+{
+        while (first <= last) {
+		const struct exception_table_entry *mid;
+		long diff;
+
+		mid = (last - first) / 2 + first;
+		diff = mid->insn - value;
+                if (diff == 0)
+                        return mid->fixup;
+                else if (diff < 0)
+                        first = mid+1;
+                else
+                        last = mid-1;
+        }
+        return 0;
+}
+
+unsigned long
+search_exception_table(unsigned long addr)
+{
+	unsigned long ret;
+
+#ifndef CONFIG_MODULES
+	/* There is only the kernel to search.  */
+	ret = search_one_table(_start___ex_table, _stop___ex_table-1, addr);
+	if (ret) return ret;
+#else
+	/* The kernel is the last "module" -- no need to treat it special.  */
+	struct module *mp;
+	for (mp = module_list; mp != NULL; mp = mp->next) {
+		if (mp->ex_table_start == NULL)
+			continue;
+		ret = search_one_table(mp->ex_table_start,
+				       mp->ex_table_end - 1, addr);
+		if (ret) return ret;
+	}
+#endif
+
+	return 0;
+}
diff -urN linux-2.4.2-pre1/arch/cris/mm/fault.c linux/arch/cris/mm/fault.c
--- linux-2.4.2-pre1/arch/cris/mm/fault.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/mm/fault.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,390 @@
+/*
+ *  linux/arch/cris/mm/fault.c
+ *
+ *  Copyright (C) 2000  Axis Communications AB
+ *
+ *  Authors:  Bjorn Wesen 
+ * 
+ *  $Log: fault.c,v $
+ *  Revision 1.8  2000/11/22 14:45:31  bjornw
+ *  * 2.4.0-test10 removed the set_pgdir instantaneous kernel global mapping
+ *    into all processes. Instead we fill in the missing PTE entries on demand.
+ *
+ *  Revision 1.7  2000/11/21 16:39:09  bjornw
+ *  fixup switches frametype
+ *
+ *  Revision 1.6  2000/11/17 16:54:08  bjornw
+ *  More detailed siginfo reporting
+ *
+ *
+ */
+
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+
+#include <asm/system.h>
+#include <asm/segment.h>
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+#include <asm/svinto.h>
+
+extern void die_if_kernel(const char *,struct pt_regs *,long);
+
+asmlinkage void do_invalid_op (struct pt_regs *, unsigned long);
+asmlinkage void do_page_fault(unsigned long address, struct pt_regs *regs,
+			      int error_code);
+
+/* debug of low-level TLB reload */
+#define D(x)
+/* debug of higher-level faults */
+#define DPG(x)
+
+/* fast TLB-fill fault handler */
+
+void
+handle_mmu_bus_fault(struct pt_regs *regs)
+{
+	int cause, select;
+	int index;
+	int page_id;
+	int miss, we, acc, inv;  
+	struct mm_struct *mm = current->active_mm;
+	pmd_t *pmd;
+	pte_t pte;
+	int errcode = 0;
+	unsigned long address;
+
+	cause = *R_MMU_CAUSE;
+	select = *R_TLB_SELECT;
+
+	address = cause & PAGE_MASK; /* get faulting address */
+	
+	page_id = IO_EXTRACT(R_MMU_CAUSE,  page_id,   cause);
+	miss    = IO_EXTRACT(R_MMU_CAUSE,  miss_excp, cause);
+	we      = IO_EXTRACT(R_MMU_CAUSE,  we_excp,   cause);
+	acc     = IO_EXTRACT(R_MMU_CAUSE,  acc_excp,  cause);
+	inv     = IO_EXTRACT(R_MMU_CAUSE,  inv_excp,  cause);  
+	index  =  IO_EXTRACT(R_TLB_SELECT, index,     select);
+	
+	D(printk("bus_fault from IRP 0x%x: addr 0x%x, miss %d, inv %d, we %d, acc %d, "
+		 "idx %d pid %d\n",
+		 regs->irp, address, miss, inv, we, acc, index, page_id));
+
+	/* for a miss, we need to reload the TLB entry */
+
+	if(miss) {
+
+		/* see if the pte exists at all */
+		
+		pmd = (pmd_t *)pgd_offset(mm, address);
+		if(pmd_none(*pmd))
+			goto dofault;
+		if(pmd_bad(*pmd)) {
+			printk("bad pgdir entry 0x%x at 0x%x\n", *pmd, pmd);
+			pmd_clear(pmd);
+			return;
+		}
+		pte = *pte_offset(pmd, address);
+		if(!pte_present(pte))
+			goto dofault;
+		
+		D(printk(" found pte %x pg %x ", pte_val(pte), pte_page(pte)));
+		D(
+		  {
+			  if(pte_val(pte) & _PAGE_SILENT_WRITE)
+				  printk("Silent-W ");
+			  if(pte_val(pte) & _PAGE_KERNEL)
+				  printk("Kernel ");
+			  if(pte_val(pte) & _PAGE_SILENT_READ)
+				  printk("Silent-R ");
+			  if(pte_val(pte) & _PAGE_GLOBAL)
+				  printk("Global ");
+			  if(pte_val(pte) & _PAGE_PRESENT)
+				  printk("Present ");
+			  if(pte_val(pte) & _PAGE_ACCESSED)
+				  printk("Accessed ");
+			  if(pte_val(pte) & _PAGE_MODIFIED)
+				  printk("Modified ");
+			  if(pte_val(pte) & _PAGE_READ)
+				  printk("Readable ");
+			  if(pte_val(pte) & _PAGE_WRITE)
+				  printk("Writeable ");
+			  printk("\n");
+		  });
+
+		/* load up the chosen TLB entry
+		 * this assumes the pte format is the same as the TLB_LO layout.
+		 *
+		 * the write to R_TLB_LO also writes the vpn and page_id fields from
+		 * R_MMU_CAUSE, which we in this case obviously want to keep
+		 */
+		
+		*R_TLB_LO = pte_val(pte);
+
+		return;
+	} 
+
+	errcode = 0x01 | (we << 1);
+
+ dofault:
+	/* leave it to the MM system fault handler below */
+	D(printk("do_page_fault %p errcode %d\n", address, errcode));
+	do_page_fault(address, regs, errcode);
+}
+
+/*
+ * This routine handles page faults.  It determines the address,
+ * and the problem, and then passes it off to one of the appropriate
+ * routines.
+ *
+ * Notice that the address we're given is aligned to the page the fault
+ * occured in, since we only get the PFN in R_MMU_CAUSE not the complete
+ * address.
+ *
+ * error_code:
+ *	bit 0 == 0 means no page found, 1 means protection fault
+ *	bit 1 == 0 means read, 1 means write
+ *
+ * If this routine detects a bad access, it returns 1, otherwise it
+ * returns 0.
+ */
+
+asmlinkage void
+do_page_fault(unsigned long address, struct pt_regs *regs,
+	      int error_code)
+{
+	struct task_struct *tsk;
+	struct mm_struct *mm;
+	struct vm_area_struct * vma;
+	int writeaccess;
+	int fault;
+	unsigned long fixup;
+	siginfo_t info;
+
+	tsk = current;
+
+        /*
+         * We fault-in kernel-space virtual memory on-demand. The
+         * 'reference' page table is init_mm.pgd.
+         *
+         * NOTE! We MUST NOT take any locks for this case. We may
+         * be in an interrupt or a critical region, and should
+         * only copy the information from the master page table,
+         * nothing more.
+	 *
+	 * NOTE2: This is done so that, when updating the vmalloc
+	 * mappings we don't have to walk all processes pgdirs and
+	 * add the high mappings all at once. Instead we do it as they
+	 * are used.
+	 *
+	 * TODO: On CRIS, we have a PTE Global bit which should be set in
+	 * all the PTE's related to vmalloc in all processes - that means if
+	 * we switch process and a vmalloc PTE is still in the TLB, it won't
+	 * need to be reloaded. It's an optimization.
+	 *
+	 * Linux/CRIS's kernel is not page-mapped, so the comparision below
+	 * should really be >= VMALLOC_START, however, kernel fixup errors
+	 * will be handled more quickly by going through vmalloc_fault and then
+	 * into bad_area_nosemaphore than falling through the find_vma user-mode
+	 * tests.
+         */
+
+        if (address >= TASK_SIZE)
+                goto vmalloc_fault;
+
+	mm = tsk->mm;
+	writeaccess = error_code & 2;
+	info.si_code = SEGV_MAPERR;
+
+	/*
+	 * If we're in an interrupt or have no user
+	 * context, we must not take the fault..
+	 */
+
+	if (in_interrupt() || !mm)
+		goto no_context;
+
+	down(&mm->mmap_sem);
+	vma = find_vma(mm, address);
+	if (!vma)
+		goto bad_area;
+	if (vma->vm_start <= address)
+		goto good_area;
+	if (!(vma->vm_flags & VM_GROWSDOWN))
+		goto bad_area;
+	if (user_mode(regs)) {
+		/*
+		 * accessing the stack below usp is always a bug.
+		 * we get page-aligned addresses so we can only check
+		 * if we're within a page from usp, but that might be
+		 * enough to catch brutal errors at least.
+		 */
+		if (address + PAGE_SIZE < rdusp())
+			goto bad_area;
+	}
+	if (expand_stack(vma, address))
+		goto bad_area;
+
+	/*
+	 * Ok, we have a good vm_area for this memory access, so
+	 * we can handle it..
+	 */
+
+ good_area:
+	info.si_code = SEGV_ACCERR;
+
+	/* first do some preliminary protection checks */
+
+	if (writeaccess) {
+		if (!(vma->vm_flags & VM_WRITE))
+			goto bad_area;
+	} else {
+		if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+			goto bad_area;
+	}
+
+	/*
+	 * If for any reason at all we couldn't handle the fault,
+	 * make sure we exit gracefully rather than endlessly redo
+	 * the fault.
+	 */
+
+	switch (handle_mm_fault(mm, vma, address, writeaccess)) {
+        case 1:
+                tsk->min_flt++;
+                break;
+        case 2:
+                tsk->maj_flt++;
+                break;
+        case 0:
+                goto do_sigbus;
+        default:
+                goto out_of_memory;
+	}
+
+	up(&mm->mmap_sem);
+	return;
+	
+	/*
+	 * Something tried to access memory that isn't in our memory map..
+	 * Fix it, but check if it's kernel or user first..
+	 */
+
+ bad_area:
+
+	up(&mm->mmap_sem);
+
+ bad_area_nosemaphore:
+	DPG(show_registers(regs));
+
+	/* User mode accesses just cause a SIGSEGV */
+
+	if (user_mode(regs)) {
+		info.si_signo = SIGSEGV;
+		info.si_errno = 0;
+		/* info.si_code has been set above */
+		info.si_addr = (void *)address;
+		force_sig_info(SIGSEGV, &info, tsk);
+		return;
+	}
+
+ no_context:
+
+	/* Are we prepared to handle this kernel fault?
+	 *
+	 * (The kernel has valid exception-points in the source 
+	 *  when it acesses user-memory. When it fails in one
+	 *  of those points, we find it in a table and do a jump
+	 *  to some fixup code that loads an appropriate error
+	 *  code)
+	 */
+
+        if ((fixup = search_exception_table(regs->irp)) != 0) {
+                regs->irp = fixup;
+		regs->frametype = CRIS_FRAME_FIXUP;
+		D(printk("doing fixup to 0x%x\n", fixup));
+                return;
+        }
+
+/*
+ * Oops. The kernel tried to access some bad page. We'll have to
+ * terminate things with extreme prejudice.
+ */
+	if ((unsigned long) (address) < PAGE_SIZE)
+		printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
+	else
+		printk(KERN_ALERT "Unable to handle kernel access");
+	printk(" at virtual address %08lx\n",address);
+
+	die_if_kernel("Oops", regs, error_code);
+
+	do_exit(SIGKILL);
+
+	/*
+	 * We ran out of memory, or some other thing happened to us that made
+	 * us unable to handle the page fault gracefully.
+	 */
+
+ out_of_memory:
+        up(&mm->mmap_sem);
+	printk("VM: killing process %s\n", tsk->comm);
+	if(user_mode(regs))
+		do_exit(SIGKILL);
+	goto no_context;
+
+ do_sigbus:
+	up(&mm->mmap_sem);
+
+	/*
+         * Send a sigbus, regardless of whether we were in kernel
+         * or user mode.
+         */
+	info.si_code = SIGBUS;
+	info.si_errno = 0;
+	info.si_code = BUS_ADRERR;
+	info.si_addr = (void *)address;
+	force_sig_info(SIGBUS, &info, tsk);
+	
+        /* Kernel mode? Handle exceptions or die */
+        if (!user_mode(regs))
+                goto no_context;
+        return;
+
+vmalloc_fault:
+        {
+                /*
+                 * Synchronize this task's top level page-table
+                 * with the 'reference' page table.
+                 */
+                int offset = pgd_index(address);
+                pgd_t *pgd, *pgd_k;
+                pmd_t *pmd, *pmd_k;
+
+                pgd = tsk->active_mm->pgd + offset;
+                pgd_k = init_mm.pgd + offset;
+
+                if (!pgd_present(*pgd)) {
+                        if (!pgd_present(*pgd_k))
+                                goto bad_area_nosemaphore;
+                        set_pgd(pgd, *pgd_k);
+                        return;
+                }
+
+                pmd = pmd_offset(pgd, address);
+                pmd_k = pmd_offset(pgd_k, address);
+
+                if (pmd_present(*pmd) || !pmd_present(*pmd_k))
+                        goto bad_area_nosemaphore;
+                set_pmd(pmd, *pmd_k);
+                return;
+        }
+
+}
diff -urN linux-2.4.2-pre1/arch/cris/mm/init.c linux/arch/cris/mm/init.c
--- linux-2.4.2-pre1/arch/cris/mm/init.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/mm/init.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,506 @@
+/*
+ *  linux/arch/cris/mm/init.c
+ *
+ *  Copyright (C) 1995  Linus Torvalds
+ *  Copyright (C) 2000  Axis Communications AB
+ *
+ *  Authors:  Bjorn Wesen (bjornw@axis.com)
+ *
+ *  $Log: init.c,v $
+ *  Revision 1.15  2001/01/10 21:12:10  bjornw
+ *  loops_per_sec -> loops_per_jiffy
+ *
+ *  Revision 1.14  2000/11/22 16:23:20  bjornw
+ *  Initialize totalhigh counters to 0 to make /proc/meminfo look nice.
+ *
+ *  Revision 1.13  2000/11/21 16:37:51  bjornw
+ *  Temporarily disable initmem freeing
+ *
+ *  Revision 1.12  2000/11/21 13:55:07  bjornw
+ *  Use CONFIG_CRIS_LOW_MAP for the low VM map instead of explicit CPU type
+ *
+ *  Revision 1.11  2000/10/06 12:38:22  bjornw
+ *  Cast empty_bad_page correctly (should really be of * type from the start..
+ *
+ *  Revision 1.10  2000/10/04 16:53:57  bjornw
+ *  Fix memory-map due to LX features
+ *
+ *  Revision 1.9  2000/09/13 15:47:49  bjornw
+ *  Wrong count in reserved-pages loop
+ *
+ *  Revision 1.8  2000/09/13 14:35:10  bjornw
+ *  2.4.0-test8 added a new arg to free_area_init_node
+ *
+ *  Revision 1.7  2000/08/17 15:35:55  bjornw
+ *  2.4.0-test6 removed MAP_NR and inserted virt_to_page
+ *
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/smp.h>
+#include <linux/bootmem.h>
+
+#include <asm/system.h>
+#include <asm/segment.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <asm/dma.h>
+#include <asm/svinto.h>
+
+static unsigned long totalram_pages;
+
+struct pgtable_cache_struct quicklists;  /* see asm/pgalloc.h */
+
+const char bad_pmd_string[] = "Bad pmd in pte_alloc: %08lx\n";
+
+extern void die_if_kernel(char *,struct pt_regs *,long);
+extern void show_net_buffers(void);
+extern void tlb_init(void);
+
+/*
+ * empty_bad_page is the page that is used for page faults when linux
+ * is out-of-memory. Older versions of linux just did a
+ * do_exit(), but using this instead means there is less risk
+ * for a process dying in kernel mode, possibly leaving a inode
+ * unused etc..
+ *
+ * the main point is that when a page table error occurs, we want to get
+ * out of the kernel safely before killing the process, so we need something
+ * to feed the MMU with when the fault occurs even if we don't have any
+ * real PTE's or page tables.
+ *
+ * empty_bad_page_table is the accompanying page-table: it is initialized
+ * to point to empty_bad_page writable-shared entries.
+ *
+ * empty_zero_page is a special page that is used for zero-initialized
+ * data and COW.
+ */
+
+unsigned long empty_bad_page_table;
+unsigned long empty_bad_page;
+unsigned long empty_zero_page;
+
+pte_t * __bad_pagetable(void)
+{
+	/* somehow it is enough to just clear it and not fill it with
+	 * bad page PTE's...
+	 */
+	memset((void *)empty_bad_page_table, 0, PAGE_SIZE);
+
+	return (pte_t *) empty_bad_page_table;
+}
+
+pte_t __bad_page(void)
+{
+
+	/* clear the empty_bad_page page. this should perhaps be
+	 * a more simple inlined loop like it is on the other 
+	 * architectures.
+	 */
+
+	memset((void *)empty_bad_page, 0, PAGE_SIZE);
+
+	return pte_mkdirty(__mk_pte((void *)empty_bad_page, PAGE_SHARED));
+}
+
+static pte_t * get_bad_pte_table(void)
+{
+	pte_t *empty_bad_pte_table = (pte_t *)empty_bad_page_table;
+	pte_t v;
+	int i;
+
+	v = __bad_page();
+
+	for (i = 0; i < PAGE_SIZE/sizeof(pte_t); i++)
+		empty_bad_pte_table[i] = v;
+
+	return empty_bad_pte_table;
+}
+
+void __handle_bad_pmd(pmd_t *pmd)
+{
+	pmd_ERROR(*pmd);
+	pmd_set(pmd, get_bad_pte_table());
+}
+
+void __handle_bad_pmd_kernel(pmd_t *pmd)
+{
+	pmd_ERROR(*pmd);
+	pmd_set_kernel(pmd, get_bad_pte_table());
+}
+
+pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
+{
+        pte_t *pte;
+
+        pte = (pte_t *) __get_free_page(GFP_KERNEL);
+        if (pmd_none(*pmd)) {
+                if (pte) {
+                        clear_page(pte);
+			pmd_set_kernel(pmd, pte);
+                        return pte + offset;
+                }
+		pmd_set_kernel(pmd, get_bad_pte_table());
+                return NULL;
+        }
+        free_page((unsigned long)pte);
+        if (pmd_bad(*pmd)) {
+                __handle_bad_pmd_kernel(pmd);
+                return NULL;
+        }
+        return (pte_t *) pmd_page(*pmd) + offset;
+}
+
+pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
+{
+	pte_t *pte;
+
+        pte = (pte_t *) __get_free_page(GFP_KERNEL);
+        if (pmd_none(*pmd)) {
+                if (pte) {
+                        clear_page(pte);
+			pmd_set(pmd, pte);
+                        return pte + offset;
+                }
+		pmd_set(pmd, get_bad_pte_table());
+                return NULL;
+        }
+        free_page((unsigned long)pte);
+        if (pmd_bad(*pmd)) {
+                __handle_bad_pmd(pmd);
+                return NULL;
+        }
+        return (pte_t *) pmd_page(*pmd) + offset;
+}
+
+#ifndef CONFIG_NO_PGT_CACHE
+struct pgtable_cache_struct quicklists;
+
+/* trim the page-table cache if necessary */
+
+int do_check_pgt_cache(int low, int high)
+{
+        int freed = 0;
+
+        if(pgtable_cache_size > high) {
+                do {
+                        if(pgd_quicklist) {
+                                free_pgd_slow(get_pgd_fast());
+                                freed++;
+                        }
+                        if(pmd_quicklist) {
+                                free_pmd_slow(get_pmd_fast());
+                                freed++;
+                        }
+                        if(pte_quicklist) {
+                                free_pte_slow(get_pte_fast());
+                                 freed++;
+                        }
+                } while(pgtable_cache_size > low);
+        }
+        return freed;
+}
+#else
+int do_check_pgt_cache(int low, int high)
+{
+        return 0;
+}
+#endif
+
+void show_mem(void)
+{
+	int i,free = 0,total = 0,cached = 0, reserved = 0, nonshared = 0;
+	int shared = 0;
+
+	printk("\nMem-info:\n");
+	show_free_areas();
+	printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
+	i = max_mapnr;
+	while (i-- > 0) {
+		total++;
+		if (PageReserved(mem_map+i))
+			reserved++;
+		else if (PageSwapCache(mem_map+i))
+			cached++;
+		else if (!page_count(mem_map+i))
+			free++;
+		else if (page_count(mem_map+i) == 1)
+			nonshared++;
+		else
+			shared += page_count(mem_map+i) - 1;
+	}
+	printk("%d pages of RAM\n",total);
+	printk("%d free pages\n",free);
+	printk("%d reserved pages\n",reserved);
+	printk("%d pages nonshared\n",nonshared);
+	printk("%d pages shared\n",shared);
+	printk("%d pages swap cached\n",cached);
+	printk("%ld pages in page table cache\n",pgtable_cache_size);
+	show_buffers();
+}
+
+/*
+ * The kernel is already mapped with a kernel segment at kseg_c so 
+ * we don't need to map it with a page table. However head.S also
+ * temporarily mapped it at kseg_4 so we should set up the ksegs again,
+ * clear the TLB and do some other paging setup stuff.
+ */
+
+void __init 
+paging_init(void)
+{
+	int i;
+	unsigned long zones_size[MAX_NR_ZONES];
+
+	printk("Setting up paging and the MMU.\n");
+	
+	/* clear out the init_mm.pgd that will contain the kernel's mappings */
+
+	for(i = 0; i < PTRS_PER_PGD; i++)
+		swapper_pg_dir[i] = __pgd(0);
+
+	/* initialise the TLB (tlb.c) */
+
+	tlb_init();
+
+	/* see README.mm for details on the KSEG setup */
+
+#ifdef CONFIG_CRIS_LOW_MAP
+
+	/* Etrax-100 LX version 1 has a bug so that we cannot map anything
+	 * across the 0x80000000 boundary, so we need to shrink the user-virtual
+	 * area to 0x50000000 instead of 0xb0000000 and map things slightly
+	 * different. The unused areas are marked as paged so that we can catch
+	 * freak kernel accesses there.
+	 *
+	 * The Juliette chip is mapped at 0xa so we pass that segment straight
+	 * through. We cannot vremap it because the vmalloc area is below 0x8
+	 * and Juliette needs an uncached area above 0x8.
+	 */
+
+	*R_MMU_KSEG = ( IO_STATE(R_MMU_KSEG, seg_f, page ) | 
+			IO_STATE(R_MMU_KSEG, seg_e, seg  ) |  /* uncached flash */
+			IO_STATE(R_MMU_KSEG, seg_d, page ) | 
+			IO_STATE(R_MMU_KSEG, seg_c, page ) | 
+			IO_STATE(R_MMU_KSEG, seg_b, seg  ) |  /* kernel reg area */
+			IO_STATE(R_MMU_KSEG, seg_a, seg  ) |  /* Juliette etc. */
+			IO_STATE(R_MMU_KSEG, seg_9, page ) |
+			IO_STATE(R_MMU_KSEG, seg_8, page ) |
+			IO_STATE(R_MMU_KSEG, seg_7, page ) |  /* kernel vmalloc area */
+			IO_STATE(R_MMU_KSEG, seg_6, seg  ) |  /* kernel DRAM area */
+			IO_STATE(R_MMU_KSEG, seg_5, seg  ) |  /* cached flash */
+			IO_STATE(R_MMU_KSEG, seg_4, page ) |  /* user area */
+			IO_STATE(R_MMU_KSEG, seg_3, page ) |  /* user area */
+			IO_STATE(R_MMU_KSEG, seg_2, page ) |  /* user area */
+			IO_STATE(R_MMU_KSEG, seg_1, page ) |  /* user area */
+			IO_STATE(R_MMU_KSEG, seg_0, page ) ); /* user area */
+
+	*R_MMU_KBASE_HI = ( IO_FIELD(R_MMU_KBASE_HI, base_f, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_HI, base_e, 0x8 ) |
+			    IO_FIELD(R_MMU_KBASE_HI, base_d, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_HI, base_c, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_HI, base_b, 0xb ) |
+			    IO_FIELD(R_MMU_KBASE_HI, base_a, 0xa ) |
+			    IO_FIELD(R_MMU_KBASE_HI, base_9, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_HI, base_8, 0x0 ) );
+	
+	*R_MMU_KBASE_LO = ( IO_FIELD(R_MMU_KBASE_LO, base_7, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_LO, base_6, 0x4 ) |
+			    IO_FIELD(R_MMU_KBASE_LO, base_5, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_LO, base_4, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_LO, base_3, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_LO, base_2, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_LO, base_1, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_LO, base_0, 0x0 ) );
+#else
+	/* This code is for the hopefully corrected Etrax-100 LX version 2... */
+
+	*R_MMU_KSEG = ( IO_STATE(R_MMU_KSEG, seg_f, seg  ) | /* cached flash */
+			IO_STATE(R_MMU_KSEG, seg_e, seg  ) | /* uncached flash */
+			IO_STATE(R_MMU_KSEG, seg_d, page ) | /* vmalloc area */
+			IO_STATE(R_MMU_KSEG, seg_c, seg  ) | /* kernel area */
+			IO_STATE(R_MMU_KSEG, seg_b, seg  ) | /* kernel reg area */
+			IO_STATE(R_MMU_KSEG, seg_a, page ) | /* user area */
+			IO_STATE(R_MMU_KSEG, seg_9, page ) |
+			IO_STATE(R_MMU_KSEG, seg_8, page ) |
+			IO_STATE(R_MMU_KSEG, seg_7, page ) |
+			IO_STATE(R_MMU_KSEG, seg_6, page ) |
+			IO_STATE(R_MMU_KSEG, seg_5, page ) |
+			IO_STATE(R_MMU_KSEG, seg_4, page ) |
+			IO_STATE(R_MMU_KSEG, seg_3, page ) |
+			IO_STATE(R_MMU_KSEG, seg_2, page ) |
+			IO_STATE(R_MMU_KSEG, seg_1, page ) |
+			IO_STATE(R_MMU_KSEG, seg_0, page ) );
+
+	*R_MMU_KBASE_HI = ( IO_FIELD(R_MMU_KBASE_HI, base_f, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_HI, base_e, 0x8 ) |
+			    IO_FIELD(R_MMU_KBASE_HI, base_d, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_HI, base_c, 0x4 ) |
+			    IO_FIELD(R_MMU_KBASE_HI, base_b, 0xb ) |
+			    IO_FIELD(R_MMU_KBASE_HI, base_a, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_HI, base_9, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_HI, base_8, 0x0 ) );
+	
+	*R_MMU_KBASE_LO = ( IO_FIELD(R_MMU_KBASE_LO, base_7, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_LO, base_6, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_LO, base_5, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_LO, base_4, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_LO, base_3, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_LO, base_2, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_LO, base_1, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_LO, base_0, 0x0 ) );
+#endif	
+
+	*R_MMU_CONTEXT = ( IO_FIELD(R_MMU_CONTEXT, page_id, 0 ) );
+	
+	/* The MMU has been enabled ever since head.S but just to make
+	 * it totally obvious we do it here as well.
+	 */
+
+	*R_MMU_CTRL = ( IO_STATE(R_MMU_CTRL, inv_excp, enable ) |
+			IO_STATE(R_MMU_CTRL, acc_excp, enable ) |
+			IO_STATE(R_MMU_CTRL, we_excp,  enable ) );
+	
+	*R_MMU_ENABLE = IO_STATE(R_MMU_ENABLE, mmu_enable, enable);
+
+	/*
+	 * initialize the bad page table and bad page to point
+	 * to a couple of allocated pages
+	 */
+
+	empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+	empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+	empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+	memset((void *)empty_zero_page, 0, PAGE_SIZE);
+
+	/* All pages are DMA'able in Etrax, so put all in the DMA'able zone */
+
+	zones_size[0] = ((unsigned long)high_memory - PAGE_OFFSET) >> PAGE_SHIFT;
+
+	for (i = 1; i < MAX_NR_ZONES; i++)
+		zones_size[i] = 0;
+
+	/* Use free_area_init_node instead of free_area_init, because the former
+	 * is designed for systems where the DRAM starts at an address substantially
+	 * higher than 0, like us (we start at PAGE_OFFSET). This saves space in the
+	 * mem_map page array.
+	 */
+
+	free_area_init_node(0, 0, 0, zones_size, PAGE_OFFSET, 0);
+}
+
+extern unsigned long loops_per_jiffy; /* init/main.c */
+unsigned long loops_per_usec;
+
+extern char _stext, _edata, _etext;
+extern char __init_begin, __init_end;
+
+void __init
+mem_init(void)
+{
+	int codesize, reservedpages, datasize, initsize;
+	unsigned long tmp;
+
+	if(!mem_map)
+		BUG();
+
+	/* max/min_low_pfn was set by setup.c
+	 * now we just copy it to some other necessary places...
+	 *
+	 * high_memory was also set in setup.c
+	 */
+
+	max_mapnr = num_physpages = max_low_pfn - min_low_pfn;
+ 
+	/* this will put all memory onto the freelists */
+        totalram_pages = free_all_bootmem();
+
+	reservedpages = 0;
+	for (tmp = 0; tmp < max_mapnr; tmp++) {
+		/*
+                 * Only count reserved RAM pages
+                 */
+		if (PageReserved(mem_map + tmp))
+			reservedpages++;
+	}
+
+	codesize =  (unsigned long) &_etext - (unsigned long) &_stext;
+        datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
+        initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
+	
+        printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, "
+	       "%dk init)\n" ,
+	       (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+	       max_mapnr << (PAGE_SHIFT-10),
+	       codesize >> 10,
+	       reservedpages << (PAGE_SHIFT-10),
+	       datasize >> 10,
+	       initsize >> 10
+               );
+	
+	/* HACK alert - calculate a loops_per_usec for asm/delay.h here
+	 * since this is called just after calibrate_delay in init/main.c
+	 * but before places which use udelay. cannot be in time.c since
+	 * that is called _before_ calibrate_delay
+	 */
+
+	loops_per_usec = (loops_per_jiffy * HZ) / 1000000;
+
+	return;
+}
+
+/* free the pages occupied by initialization code */
+
+void free_initmem(void)
+{
+#if 0
+	/* currently this is a bad idea since the cramfs image is catted onto
+	 * the vmlinux image, and the end of that image is not page-padded so
+	 * part of the cramfs image will be freed here
+	 */
+        unsigned long addr;
+
+        addr = (unsigned long)(&__init_begin);
+        for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
+                ClearPageReserved(virt_to_page(addr));
+                set_page_count(virt_to_page(addr), 1);
+                free_page(addr);
+                totalram_pages++;
+        }
+        printk ("Freeing unused kernel memory: %dk freed\n", 
+		(&__init_end - &__init_begin) >> 10);
+#endif
+}
+
+void si_meminfo(struct sysinfo *val)
+{
+	int i;
+
+	i = max_mapnr;
+	val->totalram = 0;
+	val->sharedram = 0;
+	val->freeram = nr_free_pages();
+	val->bufferram = atomic_read(&buffermem_pages);
+	while (i-- > 0)  {
+		if (PageReserved(mem_map+i))
+			continue;
+		val->totalram++;
+		if (!atomic_read(&mem_map[i].count))
+			continue;
+		val->sharedram += atomic_read(&mem_map[i].count) - 1;
+	}
+	val->mem_unit = PAGE_SIZE;
+	val->totalhigh = 0;
+	val->freehigh = 0;
+}
diff -urN linux-2.4.2-pre1/arch/cris/mm/tlb.c linux/arch/cris/mm/tlb.c
--- linux-2.4.2-pre1/arch/cris/mm/tlb.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/mm/tlb.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,301 @@
+/*
+ *  linux/arch/cris/mm/tlb.c
+ *
+ *  Copyright (C) 2000  Axis Communications AB
+ *  
+ *  Authors:   Bjorn Wesen (bjornw@axis.com)
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/segment.h>
+#include <asm/pgtable.h>
+#include <asm/svinto.h>
+
+#define D(x)
+
+/* CRIS in Etrax100LX TLB */
+
+#define NUM_TLB_ENTRIES 64
+#define NUM_PAGEID 64
+#define INVALID_PAGEID 63
+#define NO_CONTEXT -1
+
+/* The TLB can host up to 64 different mm contexts at the same time.
+ * The running context is R_MMU_CONTEXT, and each TLB entry contains a
+ * page_id that has to match to give a hit. In page_id_map, we keep track
+ * of which mm's we have assigned which page_id's, so that we know when
+ * to invalidate TLB entries.
+ *
+ * The last page_id is never running - it is used as an invalid page_id
+ * so we can make TLB entries that will never match.
+ */
+
+struct mm_struct *page_id_map[NUM_PAGEID];
+
+static int map_replace_ptr = 1;  /* which page_id_map entry to replace next */
+
+/* invalidate all TLB entries */
+
+void
+flush_tlb_all()
+{
+	int i;
+
+	/* the vpn of i & 0xf is so we dont write similar TLB entries
+	 * in the same 4-way entry group. details.. 
+	 */
+
+	for(i = 0; i < NUM_TLB_ENTRIES; i++) {
+		*R_TLB_SELECT = ( IO_FIELD(R_TLB_SELECT, index, i) );
+
+		*R_TLB_HI = ( IO_FIELD(R_TLB_HI, page_id, INVALID_PAGEID ) |
+			      IO_FIELD(R_TLB_HI, vpn,     i & 0xf ) );
+		
+		*R_TLB_LO = ( IO_STATE(R_TLB_LO, global,no       ) |
+			      IO_STATE(R_TLB_LO, valid, no       ) |
+			      IO_STATE(R_TLB_LO, kernel,no	 ) |
+			      IO_STATE(R_TLB_LO, we,    no       ) |
+			      IO_FIELD(R_TLB_LO, pfn,   0        ) );
+	}
+	D(printk("tlb: flushed all\n"));
+}
+
+/* invalidate the selected mm context only */
+
+void
+flush_tlb_mm(struct mm_struct *mm)
+{
+	int i;
+	int page_id = mm->context;
+
+	D(printk("tlb: flush mm context %d (%p)\n", page_id, mm));
+
+	if(page_id == NO_CONTEXT)
+		return;
+	
+	/* mark the TLB entries that match the page_id as invalid.
+	 * here we could also check the _PAGE_GLOBAL bit and NOT flush
+	 * global pages. is it worth the extra I/O ? 
+	 */
+
+	for(i = 0; i < NUM_TLB_ENTRIES; i++) {
+		*R_TLB_SELECT = IO_FIELD(R_TLB_SELECT, index, i);
+		if (IO_EXTRACT(R_TLB_HI, page_id, *R_TLB_HI) == page_id) {
+			*R_TLB_HI = ( IO_FIELD(R_TLB_HI, page_id, INVALID_PAGEID ) |
+				      IO_FIELD(R_TLB_HI, vpn,     i & 0xf ) );
+			
+			*R_TLB_LO = ( IO_STATE(R_TLB_LO, global,no  ) |
+				      IO_STATE(R_TLB_LO, valid, no  ) |
+				      IO_STATE(R_TLB_LO, kernel,no  ) |
+				      IO_STATE(R_TLB_LO, we,    no  ) |
+				      IO_FIELD(R_TLB_LO, pfn,   0   ) );
+		}
+	}
+}
+
+/* invalidate a single page */
+
+void
+flush_tlb_page(struct vm_area_struct *vma, 
+	       unsigned long addr)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	int page_id = mm->context;
+	int i;
+
+	D(printk("tlb: flush page %p in context %d (%p)\n", addr, page_id, mm));
+
+	if(page_id == NO_CONTEXT)
+		return;
+
+	addr &= PAGE_MASK; /* perhaps not necessary */
+
+	/* invalidate those TLB entries that match both the mm context
+	 * and the virtual address requested 
+	 */
+
+	for(i = 0; i < NUM_TLB_ENTRIES; i++) {
+		unsigned long tlb_hi;
+		*R_TLB_SELECT = IO_FIELD(R_TLB_SELECT, index, i);
+		tlb_hi = *R_TLB_HI;
+		if (IO_EXTRACT(R_TLB_HI, page_id, tlb_hi) == page_id &&
+		    (tlb_hi & PAGE_MASK) == addr) {
+			*R_TLB_HI = IO_FIELD(R_TLB_HI, page_id, INVALID_PAGEID ) |
+				addr; /* same addr as before works. */
+			
+			*R_TLB_LO = ( IO_STATE(R_TLB_LO, global,no  ) |
+				      IO_STATE(R_TLB_LO, valid, no  ) |
+				      IO_STATE(R_TLB_LO, kernel,no  ) |
+				      IO_STATE(R_TLB_LO, we,    no  ) |
+				      IO_FIELD(R_TLB_LO, pfn,   0   ) );
+		}
+	}
+}
+
+/* invalidate a page range */
+
+void
+flush_tlb_range(struct mm_struct *mm, 
+		unsigned long start,
+		unsigned long end)
+{
+	int page_id = mm->context;
+	int i;
+
+	D(printk("tlb: flush range %p<->%p in context %d (%p)\n",
+		 start, end, page_id, mm));
+
+	if(page_id == NO_CONTEXT)
+		return;
+
+	start &= PAGE_MASK;  /* probably not necessary */
+	end &= PAGE_MASK;    /* dito */
+
+	/* invalidate those TLB entries that match both the mm context
+	 * and the virtual address range
+	 */
+
+	for(i = 0; i < NUM_TLB_ENTRIES; i++) {
+		unsigned long tlb_hi, vpn;
+		*R_TLB_SELECT = IO_FIELD(R_TLB_SELECT, index, i);
+		tlb_hi = *R_TLB_HI;
+		vpn = tlb_hi & PAGE_MASK;
+		if (IO_EXTRACT(R_TLB_HI, page_id, tlb_hi) == page_id &&
+		    vpn >= start && vpn < end) {
+			*R_TLB_HI = ( IO_FIELD(R_TLB_HI, page_id, INVALID_PAGEID ) |
+				      IO_FIELD(R_TLB_HI, vpn,     i & 0xf ) );
+			
+			*R_TLB_LO = ( IO_STATE(R_TLB_LO, global,no  ) |
+				      IO_STATE(R_TLB_LO, valid, no  ) |
+				      IO_STATE(R_TLB_LO, kernel,no  ) |
+				      IO_STATE(R_TLB_LO, we,    no  ) |
+				      IO_FIELD(R_TLB_LO, pfn,   0   ) );
+		}
+	}
+}
+
+/*
+ * Initialize the context related info for a new mm_struct
+ * instance.
+ */
+
+int
+init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+	mm->context = NO_CONTEXT;
+	return 0;
+}
+
+/* the following functions are similar to those used in the PPC port */
+
+static inline void
+alloc_context(struct mm_struct *mm)
+{
+	struct mm_struct *old_mm;
+
+	D(printk("tlb: alloc context %d (%p)\n", map_replace_ptr, mm));
+
+	/* did we replace an mm ? */
+
+	old_mm = page_id_map[map_replace_ptr];
+
+	if(old_mm) {
+		/* throw out any TLB entries belonging to the mm we replace
+		 * in the map
+		 */
+		flush_tlb_mm(old_mm);
+
+		old_mm->context = NO_CONTEXT;
+	}
+
+	/* insert it into the page_id_map */
+
+	mm->context = map_replace_ptr;
+	page_id_map[map_replace_ptr] = mm;
+
+	map_replace_ptr++;
+
+	if(map_replace_ptr == INVALID_PAGEID)
+		map_replace_ptr = 0;         /* wrap around */
+	
+}
+
+/* 
+ * if needed, get a new MMU context for the mm. otherwise nothing is done.
+ */
+
+void
+get_mmu_context(struct mm_struct *mm)
+{
+	if(mm->context == NO_CONTEXT)
+		alloc_context(mm);
+}
+
+/* called in schedule() just before actually doing the switch_to */
+
+void 
+switch_mm(struct mm_struct *prev, struct mm_struct *next,
+	  struct task_struct *tsk, int cpu)
+{
+	/* make sure we have a context */
+
+	get_mmu_context(next);
+
+	/* switch context in the MMU */
+	
+	D(printk("switching mmu_context to %d (%p)\n", next->context, next));
+
+	*R_MMU_CONTEXT = IO_FIELD(R_MMU_CONTEXT, page_id, next->context);
+}
+
+
+/* called by __exit_mm to destroy the used MMU context if any before
+ * destroying the mm itself. this is only called when the last user of the mm
+ * drops it.
+ *
+ * the only thing we really need to do here is mark the used PID slot
+ * as empty.
+ */
+
+void
+destroy_context(struct mm_struct *mm)
+{
+	if(mm->context != NO_CONTEXT) {
+		D(printk("destroy_context %d (%p)\n", mm->context, mm));
+		flush_tlb_mm(mm);  /* TODO this might be redundant ? */
+		page_id_map[mm->context] = NULL;
+		/* mm->context = NO_CONTEXT; redundant.. mm will be freed */
+	}
+}
+
+/* called once during VM initialization, from init.c */
+
+void __init
+tlb_init(void)
+{
+	int i;
+
+	/* clear the page_id map */
+
+	for(i = 0; i < 64; i++)
+		page_id_map[i] = NULL;
+	
+	/* invalidate the entire TLB */
+
+	flush_tlb_all();
+
+	/* the init_mm has context 0 from the boot */
+
+	page_id_map[0] = &init_mm;
+}
diff -urN linux-2.4.2-pre1/arch/i386/kernel/pci-pc.c linux/arch/i386/kernel/pci-pc.c
--- linux-2.4.2-pre1/arch/i386/kernel/pci-pc.c	Thu Jun 22 07:17:16 2000
+++ linux/arch/i386/kernel/pci-pc.c	Mon Dec  3 22:27:48 2001
@@ -843,30 +843,40 @@
 	pcibios_last_bus = -1;
 }
 
+/*
+ * ServerWorks host bridges -- Find and scan all secondary buses.
+ * Register 0x44 contains first, 0x45 last bus number routed there.
+ */
 static void __init pci_fixup_serverworks(struct pci_dev *d)
 {
-	/*
-	 * ServerWorks host bridges -- Find and scan all secondary buses.
-	 * Register 0x44 contains first, 0x45 last bus number routed there.
-	 */
-	u8 busno;
-	pci_read_config_byte(d, 0x44, &busno);
-	printk("PCI: ServerWorks host bridge: secondary bus %02x\n", busno);
-	pci_scan_bus(busno, pci_root_ops, NULL);
-	pcibios_last_bus = -1;
+	u8 busno1, busno2;
+
+	pci_read_config_byte(d, 0x44, &busno1);
+	pci_read_config_byte(d, 0x45, &busno2);
+	if (busno2 < busno1)
+		busno2 = busno1;
+	if (busno2 > pcibios_last_bus) {
+		pcibios_last_bus = busno2;
+		printk("PCI: ServerWorks host bridge: last bus %02x\n", pcibios_last_bus);
+	}
 }
 
+/*	
+ * Compaq host bridges -- Find and scan all secondary buses.
+ * This time registers 0xc8 and 0xc9.
+ */
 static void __init pci_fixup_compaq(struct pci_dev *d)
 {
-	/*	
-	 * Compaq host bridges -- Find and scan all secondary buses.
-	 * This time registers 0xc8 and 0xc9.
-	 */
-	u8 busno;
-	pci_read_config_byte(d, 0xc8, &busno);
-	printk("PCI: Compaq host bridge: secondary bus %02x\n", busno);
-	pci_scan_bus(busno, pci_root_ops, NULL);
-	pcibios_last_bus = -1;
+	u8 busno1, busno2;
+
+	pci_read_config_byte(d, 0xc8, &busno1);
+	pci_read_config_byte(d, 0xc9, &busno2);
+	if (busno2 < busno1)
+		busno2 = busno1;
+	if (busno2 > pcibios_last_bus) {
+		pcibios_last_bus = busno2;
+		printk("PCI: Compaq host bridge: last bus %02x\n", busno2);
+	}
 }
 
 static void __init pci_fixup_umc_ide(struct pci_dev *d)
@@ -924,6 +934,22 @@
 	pcibios_max_latency = 32;
 }
 
+static void __init pci_fixup_vt8363(struct pci_dev *d)
+{
+	/*
+	 *  VIA VT8363 host bridge has broken feature 'PCI Master Read
+	 *  Caching'. It caches more than is good for it, sometimes
+	 *  serving the bus master with stale data. Some BIOSes enable
+	 *  it by default, so we disable it.
+	 */
+	u8 tmp;
+	pci_read_config_byte(d, 0x70, &tmp);
+	if(tmp & 4) {
+		printk("PCI: Bus master read caching disabled\n");
+		pci_write_config_byte(d, 0x70, tmp & ~4);
+	}
+}
+
 struct pci_fixup pcibios_fixups[] = {
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82451NX,	pci_fixup_i450nx },
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82454GX,	pci_fixup_i450gx },
@@ -936,6 +962,7 @@
 	{ PCI_FIXUP_HEADER,	PCI_ANY_ID,		PCI_ANY_ID,			pci_fixup_ide_bases },
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_5597,		pci_fixup_latency },
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_5598,		pci_fixup_latency },
+	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8363_0,	pci_fixup_vt8363 },
 	{ 0 }
 };
 
diff -urN linux-2.4.2-pre1/arch/mips/cobalt/Makefile linux/arch/mips/cobalt/Makefile
--- linux-2.4.2-pre1/arch/mips/cobalt/Makefile	Sun Jul  9 22:18:15 2000
+++ linux/arch/mips/cobalt/Makefile	Wed Dec 31 16:00:00 1969
@@ -1,24 +0,0 @@
-#
-# Makefile for the Cobalt micro systems family specific parts of the kernel
-#
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# $Id: Makefile,v 1.1 1997/10/23 22:25:41 ralf Exp $
-#
-
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
-
-all: cobalt.o
-O_TARGET := cobalt.o
-O_OBJS	 := cobaltscc.o hw-access.o int-handler.o pci.o reset.o setup.o via.o
-
-int-handler.o: int-handler.S
-
-clean:
-
-include $(TOPDIR)/Rules.make
diff -urN linux-2.4.2-pre1/arch/mips/cobalt/cobaltscc.c linux/arch/mips/cobalt/cobaltscc.c
--- linux-2.4.2-pre1/arch/mips/cobalt/cobaltscc.c	Sun Jul  9 22:18:15 2000
+++ linux/arch/mips/cobalt/cobaltscc.c	Wed Dec 31 16:00:00 1969
@@ -1,350 +0,0 @@
-/*
- * Filename: cobaltscc.c
- * 
- * Description: Functions for supporting and testing serial I/O
- * 
- * Author(s): Timothy Stonis
- * 
- * Copyright 1997, Cobalt Microserver, Inc.
- */
-#include "z8530.h"
-#include "diagdefs.h"
-#include "serial.h"
-#include "asm/io.h"
-
-/*
- * Function prototypes
- */
-void InitSerialPort(unsigned char *);
-void RegisterDelay(void);
-void InitScc(void);
-
-/*
- * Function: RegisterDelay
- *
- * Description: A little delay since the SCC can't handle quick consecutive 
- *              accesses
- * In: none
- * Out: none
- */
-void RegisterDelay(void)
-{
-	register int ctr;
-  
-	for(ctr=0;ctr<0x40;ctr++);
-}
-
-/*
- * Function: SccInit
- *
- * Description: Initialize all the SCC registers for 19200 baud, asynchronous,
- *		8 bit, 1 stop bit, no parity communication (Channel A)
- *
- * In: none
- *
- * Out: none
- */
-void InitScc(void)
-{
-	/* Force hardware reset */
-	Write8530(kSCC_ChanA | kSCC_Command, R9 | NULLCODE);
-	RegisterDelay();
-	Write8530(kSCC_ChanA, FHWRES);
-	RegisterDelay();
-  
-	/* x32 clock, 1 stop bit, no parity */
-	Write8530(kSCC_ChanA | kSCC_Command, R4 | NULLCODE);
-	RegisterDelay();
-	Write8530(kSCC_ChanA, X16CLK | SB1);
-	RegisterDelay();
-  
-	/* Rx 8 bits, Rx disabled */
-	Write8530(kSCC_ChanA | kSCC_Command, R3 | NULLCODE);
-	RegisterDelay();
-	Write8530(kSCC_ChanA, Rx8);
-	RegisterDelay();
-   
-	/* Tx 8 bits, DTR, RTS, Tx off */
-	Write8530(kSCC_ChanA | kSCC_Command, R5 | NULLCODE);
-	RegisterDelay();
-	Write8530(kSCC_ChanA, Tx8 | DTR | RTS);
-	RegisterDelay();
-
-	/* Int. Disabled */
-	Write8530(kSCC_ChanA | kSCC_Command, R9 | NULLCODE);
-	RegisterDelay();
-	Write8530(kSCC_ChanA, 0x0);
-	RegisterDelay();
-
-	/* NRZ */
-	Write8530(kSCC_ChanA | kSCC_Command, R10 | NULLCODE);
-	RegisterDelay();
-	Write8530(kSCC_ChanA, NRZ);
-	RegisterDelay();
-
-	/* Tx & Rx = BRG out, TRxC = BRG out */
-	Write8530(kSCC_ChanA | kSCC_Command, R11 | NULLCODE);
-	RegisterDelay();
-	Write8530(kSCC_ChanA, TCBR | RCBR | TRxCBR | TRxCOI); 
-	RegisterDelay();
-
-	/* Time constant = 0x01 */
-	Write8530(kSCC_ChanA | kSCC_Command, R12 | NULLCODE);
-	RegisterDelay();
-	Write8530(kSCC_ChanA, kSCC_115200 ); 
-	RegisterDelay();
-
-	/* Time constant high = 0x00 */
-	Write8530(kSCC_ChanA | kSCC_Command, R13 | NULLCODE);
-	RegisterDelay();
-	Write8530(kSCC_ChanA, 0x00); 
-	RegisterDelay();
-
-	/* BRG in = ~RTxC, BRG off, loopback */
-	Write8530(kSCC_ChanA | kSCC_Command, R14 | NULLCODE);
-	RegisterDelay();
-	Write8530(kSCC_ChanA, LOOPBAK | BRSRC); 
-	RegisterDelay();
-}
-
-/*
- * Function: EnableScc
- *
- * Description: Enable transmit and receive on SCC Channel A
- * In: none
- * Out: none
- */
-void EnableScc(void)
-{
-	/* Enable BRG */
-	Write8530(kSCC_ChanA | kSCC_Command, R14 | NULLCODE);
-	RegisterDelay();
-	Write8530(kSCC_ChanA, BRENABL | BRSRC);
-	RegisterDelay();
-  
-	/* Rx enable (Rx 8 bits) */
-	Write8530(kSCC_ChanA | kSCC_Command, R3 | NULLCODE);
-	RegisterDelay();
-	Write8530(kSCC_ChanA, RxENABLE | Rx8);
-	RegisterDelay();
-
-	/* Tx enable (Tx8, DTR, RTS) */
-	Write8530(kSCC_ChanA | kSCC_Command, R5 | NULLCODE);
-	RegisterDelay();
-	Write8530(kSCC_ChanA, TxENAB | Tx8 | DTR | RTS); 
-	RegisterDelay();
-}
-
-/*
- * Function: SccOutb
- *
- * Description: Write a byte to the SCC (Channel A) and blink LED
- * In: Byte to send
- * Out: none
- */
-void SccOutb(unsigned char byte)
-{
-	/* LED on.. */
-	Write8530(kSCC_ChanB | kSCC_Command, R5);
-	RegisterDelay();
-	Write8530(kSCC_ChanB | kSCC_Command, RTS);
-	RegisterDelay();
- 
-	while ((Read8530(kSCC_ChanA) & Tx_BUF_EMP) == 0)
-		RegisterDelay();
- 
-	Write8530(kSCC_ChanA | kSCC_Direct, byte);
-	RegisterDelay();
- 
-	/* LED off.. */
-	Write8530(kSCC_ChanB | kSCC_Command, R9);
-	RegisterDelay();
-	Write8530(kSCC_ChanB | kSCC_Command, CHRB);
-	RegisterDelay();
-}
-
-/*
- * Function: SccInb
- *
- * Description: Read a byte from the SCC (Channel A)
- * In: Byte to send
- * Out: none
- */
-void SccInb(unsigned char *byte)
-{
-	while ((Read8530(kSCC_ChanA) & Rx_CH_AV) == 0)
-		RegisterDelay();
- 
-	*byte = Read8530(kSCC_ChanA | kSCC_Direct);
-	RegisterDelay();
-}
-
-/*
- * Function: SccWrite
- *
- * Description: Write a null terminated string to the SCC 
- * In: C string
- * Out: none
- */
-void SccWrite(const unsigned char *string)
-{
-	while((*string) != 0) { 
-		if (*string == 10)
-			SccOutb((unsigned char) 13);
-		SccOutb(*(string++));
-	}
-}
-
-/*
- * Function: InitSerialPort
- *
- * Description: Initialize the SCC and spit out the header message 
- * In: Header message
- * Out: none
- */
-void InitSerialPort(unsigned char *msg)
-{
-	InitScc();
-	EnableScc();
-	SccWrite(msg);
-}
-
-/*
- * Function: SccInbTimeout
- *
- * Description: Read a byte from the SCC (Channel A) with timeout
- * In: Byte to send
- * Out: Timeout status
- */
-unsigned char SccInbTimeout(unsigned char *byte, unsigned long timeout)
-{
-	unsigned long ctr = 0;
-
-	while ((Read8530(kSCC_ChanA) & Rx_CH_AV) == 0) {
-		RegisterDelay();
-		if ((ctr++) > timeout)
-			return 0xFF;
-	}
-
-	*byte = Read8530(kSCC_ChanA | kSCC_Direct);
-	RegisterDelay();
- 
-	return 0;
-}
-
-#include <linux/serial_reg.h>
-
-extern int serial_echo_init (int base);
-extern int serial_echo_print (const char *s);
-
-/*
- * this defines the address for the port to which printk echoing is done
- *  when CONFIG_SERIAL_ECHO is defined
- */
-#define SERIAL_ECHO_PORT       0x1C800000 
-
-static int serial_echo_port = 0;
-
-#define serial_echo_outb(v,a) outb((v),(a)+serial_echo_port)
-#define serial_echo_inb(a)    inb((a)+serial_echo_port)
-
-#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
-
-/* Wait for transmitter & holding register to empty */
-#define WAIT_FOR_XMITR \
- do { \
-       lsr = serial_echo_inb(UART_LSR); \
- } while ((lsr & BOTH_EMPTY) != BOTH_EMPTY)
-
-/*
- * These two functions abstract the actual communications with the
- * debug port.  This is so we can change the underlying communications
- * mechanism without modifying the rest of the code.
- */
-int
-serial_echo_print(const char *s)
-{
-        int     lsr, ier;
-        int     i;
-
-        if (!serial_echo_port)
-		return 0;
-
-        /*
-         * First save the IER then disable the interrupts
-         */
-        ier = serial_echo_inb(UART_IER);
-        serial_echo_outb(0x00, UART_IER);
-
-        /*
-         * Now, do each character
-         */
-        for (i = 0; *s; i++, s++) {
-                WAIT_FOR_XMITR;
-
-                /* Send the character out. */
-                serial_echo_outb(*s, UART_TX);
-
-                /* if a LF, also do CR... */
-                if (*s == 10) {
-                        WAIT_FOR_XMITR;
-                        serial_echo_outb(13, UART_TX);
-                }
-        }
-
-        /*
-         * Finally, Wait for transmitter & holding register to empty
-         *  and restore the IER
-         */
-        do {
-                lsr = serial_echo_inb(UART_LSR);
-        } while ((lsr & BOTH_EMPTY) != BOTH_EMPTY);
-        serial_echo_outb(ier, UART_IER);
-
-        return 0;
-}
-
-
-int
-serial_echo_init(int base)
-{
-        int comstat, hi, lo;
-
-        serial_echo_port = base;
-
-        /*
-         * read the Divisor Latch
-         */
-        comstat = serial_echo_inb(UART_LCR);
-        serial_echo_outb(comstat | UART_LCR_DLAB, UART_LCR);
-        hi = serial_echo_inb(UART_DLM);
-        lo = serial_echo_inb(UART_DLL);
-        serial_echo_outb(comstat, UART_LCR);
-
-        /*
-         * now do hardwired init
-         */
-        serial_echo_outb(0x03, UART_LCR); /* No parity, 8 data bits, 1 stop */
-        serial_echo_outb(0x83, UART_LCR); /* Access divisor latch */
-
-	/* This is computed using:
-	 *
-	 * const BASE_BAUD = (18432000 / 16);
-	 * UART_DLM = (BASE_BAUD / baud_I_want) >> 8;
-	 * UART_DLL = (BASE_BAUD / baud_I_want) & 0xff;
-	 */
-        serial_echo_outb(0x00, UART_DLM); /* 115200 baud */
-        serial_echo_outb(0x0A, UART_DLL);
-
-        serial_echo_outb(0x03, UART_LCR); /* Done with divisor */
-
-        /*
-	 * Prior to disabling interrupts, read the LSR and RBR
-         * registers
-         */
-        comstat = serial_echo_inb(UART_LSR); /* COM? LSR */
-        comstat = serial_echo_inb(UART_RX);     /* COM? RBR */
-        serial_echo_outb(0x00, UART_IER); /* Disable all interrupts */
-
-        return 0;
-}
diff -urN linux-2.4.2-pre1/arch/mips/cobalt/diagdefs.h linux/arch/mips/cobalt/diagdefs.h
--- linux-2.4.2-pre1/arch/mips/cobalt/diagdefs.h	Sun Jul  9 22:18:15 2000
+++ linux/arch/mips/cobalt/diagdefs.h	Wed Dec 31 16:00:00 1969
@@ -1,177 +0,0 @@
-/*
- * Filename: diagdefs.h
- * 
- * Description: Some general definitions used by the diagnostics 
- * 
- * Author(s): Timothy Stonis
- * 
- * Copyright 1997, Cobalt Microserver, Inc.
- */
-
-#define KSEG0_Base		0x80000000
-#define KSEG1_Base		0xA0000000
-
-// Some useful Galileo registers/base addresses (boot time kseg1 mapping) 
-#define kGal_InternalBase	( 0x14000000 | KSEG1_Base ) 
-#define kGal_DevBank0Base	( 0x1C000000 | KSEG1_Base )
-#define kGal_DevBank1Base 	( 0x1C800000 | KSEG1_Base )
-
-#define kGal_RAS10Lo		0x008
-#define kGal_RAS10Hi		0x010
-#define kGal_RAS32Lo		0x018
-#define kGal_RAS32Hi		0x020
-
-#define kGal_PCIIOLo		0x048
-#define kGal_PCIIOHi		0x050
-
-#define kGal_RAS10LoCfg		0x000
-#define kGal_RAS10HiCfg		0x03
-#define kGal_RAS32LoCfg		0x004
-#define kGal_RAS32HiCfg		0x07
-
-#define kGal_PCIIOLoCfg		0x000
-#define kGal_PCIIOHiCfg		0x0F
-
-
-#define kGal_DevBank0PReg	0x45C
-#define kGal_DevBank1PReg	0x460
-#define kGal_DevBank2PReg	0x464
-#define kGal_DevBank3PReg	0x468
-#define kGal_DevBankBPReg	0x46C
-
-#define kGal_DRAMCReg		0x448
-#define kGal_DRAM0PReg		0x44C
-#define kGal_DRAM1PReg		0x450
-#define kGal_DRAM2PReg		0x454
-#define kGal_DRAM3PReg		0x458
-
-#define kGal_ConfigAddr		0xCF8
-#define kGal_ConfigData		0xCFC
-#define kGal_PCICfgEn		0x1F // Generate config cycle 
-#define kGal_DevNum		0x00 // Technically 0x06, but 0 works too
-#define kGal_MasMemEn		0x06
-#define kGal_Latency		0x700
-
-#define kGal_RAS01StartReg	0x10
-#define kGal_RAS23StartReg	0x14
-#define kGal_RAS01SizeReg	0x0C08
-#define kGal_RAS23SizeReg	0x0C0C
-
-
-#define kGal_RAS01Start		0x000
-#define kGal_RAS23Start		0x00800000
-#define kGal_RAS01Size		0x007FFFFF
-#define kGal_RAS23Size		0x007FFFFF
-
-
-// Paramter information for devices, DRAM, etc
-#define	kGal_DevBank0Cfg	0x1446DB33
-#define	kGal_DevBank1Cfg	0x144FE667
-#define	kGal_DevBankBCfg	0x1446DC43
-#define	kGal_DRAMConfig		0x00000300
-#define	kGal_DRAM0Config	0x00000010
-#define	kGal_DRAM1Config	0x00000010
-#define	kGal_DRAM2Config	0x00000010
-#define	kGal_DRAM3Config	0x00000010
-
-#define	kGal_DRAM0Hi		0x00000003
-#define	kGal_DRAM0Lo		0x00000000
-#define	kGal_DRAM1Hi		0x00000007
-#define	kGal_DRAM1Lo		0x00000004
-#define	kGal_DRAM2Hi		0x0000000B
-#define	kGal_DRAM2Lo		0x00000008
-#define	kGal_DRAM3Hi		0x0000000F
-#define	kGal_DRAM3Lo		0x0000000C
-
-#define kGal_RAS0Lo		0x400
-#define kGal_RAS0Hi		0x404
-#define kGal_RAS1Lo		0x408
-#define kGal_RAS1Hi		0x40C
-#define kGal_RAS2Lo		0x410
-#define kGal_RAS2Hi		0x414
-#define kGal_RAS3Lo		0x418
-#define kGal_RAS3Hi		0x41C
-
-// Feedback LED indicators during setup code (reset.S, main.c) 
-#define kLED_AllOn	0x0F
-#define kLED_FlashTest	0x01
-#define kLED_MemTest	0x02
-#define kLED_SCCTest	0x03
-#define kLED_GalPCI	0x04
-#define kLED_EnetTest	0x05
-#define kLED_SCSITest	0x06
-#define kLED_IOCTest	0x07
-#define kLED_Quickdone	0x0A
-#define kLED_Exception	0x0B
-#define kLED_ProcInit	0x0E
-#define kLED_AllOff	0x00
-
-#define kLEDBase	kGal_DevBank0Base
-
-// Some memory related constants 
-#define kRAM_Start	(0x00000000 | KSEG0_Base)
-
-#define	kTestPat1	0xA5A5A5A5
-#define kTestPat2	0x5A5A5A5A
-
-#define k1Meg_kseg1 	(0x00100000 | KSEG0_Base)
-#define k2Meg_kseg1  	(0x00200000 | KSEG0_Base)
-#define k4Meg_kseg1  	(0x00400000 | KSEG0_Base)
-#define k8Meg_kseg1  	(0x00800000 | KSEG0_Base)
-#define k16Meg_kseg1  	(0x01000000 | KSEG0_Base)
-
-#define kInit_SP	k4Meg_kseg1 - 0x100
-#define kVectorBase	0x200	
-#define kDebugVectors	0x400
-#define kMallocCheese	0x80E00000
-#define kDecompAddr	0x80700000
-#define kCompAddr	0x80500000
-
-
-// Ethernet definitions
-#define	kEnet_VIOBase	( 0x12100000 | KSEG1_Base )
-#define	kEnet_PIOBase	0x12100000
-#define	kEnet_CSCfg	0x46
-#define kEnet_DevNum	0x07
-#define kEnet_CSR3	0x18
-#define kEnet_CSR15	0x78
-
-
-#define kEnet_GEPOut	0x080f0000
-#define kEnet_GEPOn	0x000f0000
-
-
-// SCSI definitions
-#define	kSCSI_VIOBase	( 0x12200000 | KSEG1_Base )
-#define	kSCSI_PIOBase	0x12200000 
-#define	kSCSI_CSCfg	0x46 
-#define kSCSI_DevNum	0x08
-#define kSCSI_GPCNTL	0x47
-#define kSCSI_GPREG	0x07
-#define kSCSI_SCRTCHA	0x34
-
-#define kSCSI_GPIOOut	0x0C
-#define kSCSI_LEDsOn	0x00
-
-// I/O Controller definitions
-#define kIOC_VIOBase	( 0x10000000 | KSEG1_Base )
-#define kIOC_RIOBase	0x10000000 
-#define kIOC_DevNum	0x09
-#define kIOC_ISAFunc	0x00
-#define kIOC_IDEFunc	0x01
-#define kIOC_USBFunc	0x02
-#define kIOC_MiscC0	0x44
-#define kIOC_IDEEnable	0x40
-
-#define kIOC_PCIIDEOn 	0x02800085
-#define kIOC_PriIDEOn	0x0A
-
-// Some PCI Definitions
-#define	kPCI_StatCmd	0x04
-#define	kPCI_LatCache	0x0C
-#define	kPCI_CBIO	0x10
-#define	kPCI_CBMEM	0x14
-
-// Random constants
-#define kBogoSec	0x0003F940
-#define kSCCDelay	0x00000001
diff -urN linux-2.4.2-pre1/arch/mips/cobalt/hw-access.c linux/arch/mips/cobalt/hw-access.c
--- linux-2.4.2-pre1/arch/mips/cobalt/hw-access.c	Sun Jul  9 22:18:15 2000
+++ linux/arch/mips/cobalt/hw-access.c	Wed Dec 31 16:00:00 1969
@@ -1,58 +0,0 @@
-/*
- * Low-level hardware access stuff for Cobalt Microserver 27 board.
- *
- * 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.
- *
- * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
- */
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/linkage.h>
-#include <linux/types.h>
-#include <asm/cachectl.h>
-#include <asm/cobalt.h>
-#include <asm/segment.h>
-#include <asm/vector.h>
-
-void
-dummy(void)
-{
-	panic("What the hell is this called for?");
-}
-
-static unsigned char cobalt_read_cmos(unsigned long reg)
-{
-	unsigned char retval;
-
-	VIA_PORT_WRITE(0x70, reg);
-	retval = VIA_PORT_READ(0x71);
-	VIA_DELAY();
-
-	return retval;
-}
-
-static void cobalt_write_cmos(unsigned char val, unsigned long reg)
-{
-	VIA_PORT_WRITE(0x70, reg);
-	VIA_PORT_WRITE(0x71, val); 
-}
-
-struct feature cobalt_feature = {
-	/*
-	 * How to access the floppy controller's ports
-	 */
-	(void *)dummy, (void *)dummy,
-	/*
-	 * How to access the floppy DMA functions.
-	 */
-	(void *)dummy, (void *)dummy, (void *)dummy, (void *)dummy,
-	(void *)dummy, (void *)dummy, (void *)dummy, (void *)dummy,
-	(void *)dummy, (void *)dummy, (void *)dummy,
-	/*
-	 * How to access the RTC functions.
-	 */
-	cobalt_read_cmos,
-	cobalt_write_cmos
-};
diff -urN linux-2.4.2-pre1/arch/mips/cobalt/int-handler.S linux/arch/mips/cobalt/int-handler.S
--- linux-2.4.2-pre1/arch/mips/cobalt/int-handler.S	Sun Jul  9 22:18:15 2000
+++ linux/arch/mips/cobalt/int-handler.S	Wed Dec 31 16:00:00 1969
@@ -1,140 +0,0 @@
-/*
- * arch/mips/cobalt/int-handler.S
- */
-#include <asm/asm.h>
-#include <asm/mipsconfig.h>
-#include <asm/mipsregs.h>
-#include <asm/cobalt.h>
-#include <asm/irq.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-/*
- * cobalt_handle_int: Interrupt handler for the twenty-seven board.
- */
-		.align	5
-		.set	noreorder
-		NESTED(cobalt_handle_int, PT_SIZE, ra)
-		.set	noat
-		SAVE_ALL
-		REG_S	sp,PT_OR2(sp)
-		CLI
-		.set	at
-		mfc0	t0,CP0_CAUSE
-		mfc0	t1,CP0_STATUS
-		and	t0,t1
-		xor	t1,t0
-		mtc0	t1,CP0_STATUS	# mask all active ints
-		/* Such a kind of cascade is optimal for R5000 */
-
-		andi	t1,t0,STATUSF_IP2
-		bnez	t1,ll_galileo_irq
-		 andi	t1,t0,STATUSF_IP3
-		bnez	t1,ll_ethernet0_irq
-/*
- * This should be conditional, and not used for the cube-1, but
- * there is not a config flag that is useful.
- */
-	
-		 andi	t1,t0,STATUSF_IP4
-		bnez	t1,ll_ethernet1_irq
-/* #endif  */
-		 andi	t1,t0,STATUSF_IP6
-		bnez	t1,ll_via_irq
-		 andi	t1,t0,STATUSF_IP5
-		bnez	t1,ll_serial_irq
-		 andi	t1,t0,STATUSF_IP7
-		bnez	t1,ll_pci_irq
-		  nop
-		/* wrong alarm ... */
-		j	spurious_interrupt
-		 nop
-		END(cobalt_handle_int)
-	
-
-		.align	5
-		.set	reorder
-ll_galileo_irq:	move	a0,sp
-		INC_INTR_COUNT(s1,s2)
-		jal	galileo_irq
-		  nop
-		DEC_INTR_COUNT(s1,s2)
-		j	ret_from_irq
-		  nop
-
-		.align	5
-		.set	reorder
-ll_via_irq:	move	a0,sp
-		INC_INTR_COUNT(s1,s2)
-		jal	via_irq
-		  nop
-		DEC_INTR_COUNT(s1,s2)
-		j	ret_from_irq
-		  nop
-
-		.align	5
-		.set	reorder
-ll_ethernet0_irq:
-		INC_INTR_COUNT(s1,s2)
-		mfc0	s0,CP0_STATUS		# mask interrupt
-		ori	t0,s0,(STATUSF_IP3 | STATUSF_IP4)
-		xori	t0,(STATUSF_IP3 | STATUSF_IP4)
-		mtc0	t0,CP0_STATUS
-		li	a0,4
-		move	a1,sp
-		jal     do_IRQ
-		  nop
-		mtc0	s0,CP0_STATUS
-		DEC_INTR_COUNT(s1,s2)
-		j	ret_from_irq
-		  nop
-
-		.align	5
-		.set	reorder
-ll_serial_irq:	li	a0,7
-		INC_INTR_COUNT(s1,s2)
-		move	a1,sp
-		jal     do_IRQ
-		  nop
-		DEC_INTR_COUNT(s1,s2)
-		j	ret_from_irq
-		  nop
-
-
-		.align	5
-		.set	reorder
-ll_ethernet1_irq:
-		INC_INTR_COUNT(s1,s2)
-		mfc0	s0,CP0_STATUS		# mask interrupt
-
-		ori	t0,s0, (STATUSF_IP3 | STATUSF_IP4)
-		xori	t0,(STATUSF_IP3 | STATUSF_IP4)
-
-		mtc0	t0,CP0_STATUS
-		li	a0,13
-		move	a1,sp
-		jal     do_IRQ
-		  nop
-		mtc0	s0,CP0_STATUS
-		DEC_INTR_COUNT(s1,s2)
-		j	ret_from_irq
-		  nop
-
-	#
-	# This is pretty weird.  The "pci" interrupt on the hardware
-	# skematic is from the PCI side of the galileo, so we would
-	# only get interrupts here if WE write the control register
-	# that normally enables the cpu to send interrupts to the PCI.
-	#
-	# If you want to interrupt a PCI card, look elsewhere.
-	#
-		.align	5
-		.set	reorder
-ll_pci_irq:	li	a0,7
-		INC_INTR_COUNT(s1,s2)
-		move	a1,sp
-		jal     do_IRQ
-		  nop
-		DEC_INTR_COUNT(s1,s2)
-		j	ret_from_irq
-		  nop
diff -urN linux-2.4.2-pre1/arch/mips/cobalt/pci.c linux/arch/mips/cobalt/pci.c
--- linux-2.4.2-pre1/arch/mips/cobalt/pci.c	Sun Jul  9 22:18:15 2000
+++ linux/arch/mips/cobalt/pci.c	Wed Dec 31 16:00:00 1969
@@ -1,348 +0,0 @@
-/*
- * 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.
- *
- * Cobalt Qube specific PCI support.
- */
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/bios32.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <asm/cobalt.h>
-#include <asm/pci.h>
-#include <asm/io.h>
- 
-#undef PCI_DEBUG 
-
-#ifdef CONFIG_PCI
-
-static void qube_expansion_slot_bist(void)
-{
-	unsigned char ctrl;
-	int timeout = 100000;
-
-	pcibios_read_config_byte(0, (0x0a<<3), PCI_BIST, &ctrl);
-	if(!(ctrl & PCI_BIST_CAPABLE))
-		return;
-
-	pcibios_write_config_byte(0, (0x0a<<3), PCI_BIST, ctrl|PCI_BIST_START);
-	do {
-		pcibios_read_config_byte(0, (0x0a<<3), PCI_BIST, &ctrl);
-		if(!(ctrl & PCI_BIST_START))
-			break;
-	} while(--timeout > 0);
-	if((timeout <= 0) || (ctrl & PCI_BIST_CODE_MASK))
-		printk("PCI: Expansion slot card failed BIST with code %x\n",
-		       (ctrl & PCI_BIST_CODE_MASK));
-}
-
-static void qube_expansion_slot_fixup(void)
-{
-	unsigned short pci_cmd;
-	unsigned long ioaddr_base = 0x10108000; /* It's magic, ask Doug. */
-	unsigned long memaddr_base = 0x12000000;
-	int i;
-
-	/* Enable bits in COMMAND so driver can talk to it. */
-	pcibios_read_config_word(0, (0x0a<<3), PCI_COMMAND, &pci_cmd);
-	pci_cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
-	pcibios_write_config_word(0, (0x0a<<3), PCI_COMMAND, pci_cmd);
-
-	/* Give it a working IRQ. */
-	pcibios_write_config_byte(0, (0x0a<<3), PCI_INTERRUPT_LINE, 9);
-
-	/* Fixup base addresses, we only support I/O at the moment. */
-	for(i = 0; i <= 5; i++) {
-		unsigned int regaddr = (PCI_BASE_ADDRESS_0 + (i * 4));
-		unsigned int rval, mask, size, alignme, aspace;
-		unsigned long *basep = &ioaddr_base;
-
-		/* Check type first, punt if non-IO. */
-		pcibios_read_config_dword(0, (0x0a<<3), regaddr, &rval);
-		aspace = (rval & PCI_BASE_ADDRESS_SPACE);
-		if(aspace != PCI_BASE_ADDRESS_SPACE_IO)
-			basep = &memaddr_base;
-
-		/* Figure out how much it wants, if anything. */
-		pcibios_write_config_dword(0, (0x0a<<3), regaddr, 0xffffffff);
-		pcibios_read_config_dword(0, (0x0a<<3), regaddr, &rval);
-
-		/* Unused? */
-		if(rval == 0)
-			continue;
-
-		rval &= PCI_BASE_ADDRESS_IO_MASK;
-		mask = (~rval << 1) | 0x1;
-		size = (mask & rval) & 0xffffffff;
-		alignme = size;
-		if(alignme < 0x400)
-			alignme = 0x400;
-		rval = ((*basep + (alignme - 1)) & ~(alignme - 1));
-		*basep = (rval + size);
-		pcibios_write_config_dword(0, (0x0a<<3), regaddr, rval | aspace);
-	}
-	qube_expansion_slot_bist();
-}
-
-static void qube_raq_tulip_fixup(void)
-{
-	unsigned short pci_cmd;
-
-	/* Enable the device. */
-	pcibios_read_config_word(0, (0x0c<<3), PCI_COMMAND, &pci_cmd);
-	pci_cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MASTER);
-	pcibios_write_config_word(0, (0x0c<<3), PCI_COMMAND, pci_cmd);
-
-	/* Give it it's IRQ. */
-	/* NOTE: RaQ board #1 has a bunch of green wires which swapped the
-	 *       IRQ line values of Tulip 0 and Tulip 1.  All other
-	 *       boards have eth0=4,eth1=13.  -DaveM
-	 */
-#ifndef RAQ_BOARD_1_WITH_HWHACKS
-	pcibios_write_config_byte(0, (0x0c<<3), PCI_INTERRUPT_LINE, 13);
-#else
-	pcibios_write_config_byte(0, (0x0c<<3), PCI_INTERRUPT_LINE, 4);
-#endif
-
-	/* And finally, a usable I/O space allocation, right after what
-	 * the first Tulip uses.
-	 */
-	pcibios_write_config_dword(0, (0x0c<<3), PCI_BASE_ADDRESS_0, 0x10101001);
-}
-
-static void qube_raq_scsi_fixup(void)
-{
-	unsigned short pci_cmd;
-
-	/* Enable the device. */
-	pcibios_read_config_word(0, (0x08<<3), PCI_COMMAND, &pci_cmd);
-
-	pci_cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY
-		| PCI_COMMAND_INVALIDATE);
-	pcibios_write_config_word(0, (0x08<<3), PCI_COMMAND, pci_cmd);
-
-	/* Give it it's IRQ. */
-	pcibios_write_config_byte(0, (0x08<<3), PCI_INTERRUPT_LINE, 4);
-
-	/* And finally, a usable I/O space allocation, right after what
-	 * the second Tulip uses.
-	 */
-	pcibios_write_config_dword(0, (0x08<<3), PCI_BASE_ADDRESS_0, 0x10102001);
-	pcibios_write_config_dword(0, (0x08<<3), PCI_BASE_ADDRESS_1, 0x00002000);
-	pcibios_write_config_dword(0, (0x08<<3), PCI_BASE_ADDRESS_2, 0x00100000);
-}
-
-static unsigned long
-qube_pcibios_fixup(unsigned long mem_start, unsigned long mem_end)
-{
-	extern int cobalt_is_raq;
-	int raq_p = cobalt_is_raq;
-	unsigned int tmp;
-
-	/* Fixup I/O and Memory space decoding on Galileo.  */
-	isa_slot_offset = COBALT_LOCAL_IO_SPACE;
-
-	/* Fix PCI latency-timer and cache-line-size values in Galileo
-	 * host bridge.
-	 */
-	pcibios_write_config_byte(0, 0, PCI_LATENCY_TIMER, 64);
-	pcibios_write_config_byte(0, 0, PCI_CACHE_LINE_SIZE, 7);
-
-        /*
-         * Now tell the SCSI device that we expect an interrupt at
-         * IRQ 7 and not the default 0.
-         */
-        pcibios_write_config_byte(0, 0x08<<3, PCI_INTERRUPT_LINE,
-                                  COBALT_SCSI_IRQ);
-
-        /*
-         * Now tell the Ethernet device that we expect an interrupt at
-         * IRQ 13 and not the default 189.
-	 *
-	 * The IRQ of the first Tulip is different on Qube and RaQ
-	 * hardware except for the weird first RaQ bringup board,
-	 * see above for details.  -DaveM
-         */
-	if (! raq_p) {
-		/* All Qube's route this the same way. */
-		pcibios_write_config_byte(0, 0x07<<3, PCI_INTERRUPT_LINE,
-					  COBALT_ETHERNET_IRQ);
-	} else {
-#ifndef RAQ_BOARD_1_WITH_HWHACKS
-		pcibios_write_config_byte(0, (0x07<<3), PCI_INTERRUPT_LINE, 4);
-#else
-		pcibios_write_config_byte(0, (0x07<<3), PCI_INTERRUPT_LINE, 13);
-#endif
-	}
-
-	if (! raq_p) {
-		/* See if there is a device in the expansion slot, if so
-		 * fixup IRQ, fix base addresses, and enable master +
-		 * I/O + memory accesses in config space.
-		 */
-		pcibios_read_config_dword(0, 0x0a<<3, PCI_VENDOR_ID, &tmp);
-		if(tmp != 0xffffffff && tmp != 0x00000000)
-			qube_expansion_slot_fixup();
-	} else {
-		/* If this is a RAQ, we may need to setup the second Tulip
-		 * and SCSI as well.  Due to the different configurations
-		 * a RaQ can have, we need to explicitly check for the
-		 * presence of each of these (optional) devices.  -DaveM
-		 */
-		pcibios_read_config_dword(0, 0x0c<<3, PCI_VENDOR_ID, &tmp);
-		if(tmp != 0xffffffff && tmp != 0x00000000)
-			qube_raq_tulip_fixup();
-
-		pcibios_read_config_dword(0, 0x08<<3, PCI_VENDOR_ID, &tmp);
-		if(tmp != 0xffffffff && tmp != 0x00000000)
-			qube_raq_scsi_fixup();
-
-		/* And if we are a 2800 we have to setup the expansion slot
-		 * too.
-		 */
-		pcibios_read_config_dword(0, 0x0a<<3, PCI_VENDOR_ID, &tmp);
-		if(tmp != 0xffffffff && tmp != 0x00000000)
-			qube_expansion_slot_fixup();
-	}
-
-	return mem_start;
-}
-
-static __inline__ int pci_range_ck(unsigned char bus, unsigned char dev) 
-{
-	if ((bus == 0) && ( (dev==0) || ((dev>6) && (dev <= 12))) )
-		return 0;  /* OK device number  */
-
-	return -1;  /* NOT ok device number */
-}
-
-#define PCI_CFG_DATA	((volatile unsigned long *)0xb4000cfc)
-#define PCI_CFG_CTRL	((volatile unsigned long *)0xb4000cf8)
-
-#define PCI_CFG_SET(dev,fun,off) \
-	((*PCI_CFG_CTRL) = (0x80000000 | ((dev)<<11) | \
-			    ((fun)<<8) | (off)))
-
-static int qube_pcibios_read_config_dword (unsigned char bus,
-					   unsigned char dev,
-					   unsigned char offset,
-					   unsigned int *val)
-{
-	unsigned char fun = dev & 0x07;
-
-	dev >>= 3;
-	if (offset & 0x3)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	if (pci_range_ck(bus, dev)) {
-		*val = 0xFFFFFFFF;
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	PCI_CFG_SET(dev, fun, offset);
-	*val = *PCI_CFG_DATA;
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int qube_pcibios_read_config_word (unsigned char bus,
-					  unsigned char dev,
-					  unsigned char offset,
-					  unsigned short *val)
-{
-	unsigned char fun = dev & 0x07;
-
-	dev >>= 3;
-	if (offset & 0x1)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	if (pci_range_ck(bus, dev)) {
-		*val = 0xffff;
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	PCI_CFG_SET(dev, fun, (offset & ~0x3));
-	*val = *PCI_CFG_DATA >> ((offset & 3) * 8);
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int qube_pcibios_read_config_byte (unsigned char bus,
-					  unsigned char dev,
-					  unsigned char offset,
-					  unsigned char *val)
-{
-	unsigned char fun = dev & 0x07;
-
-	dev >>= 3;
-	if (pci_range_ck(bus, dev)) {
-		*val = 0xff;
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	PCI_CFG_SET(dev, fun, (offset & ~0x3));
-	*val = *PCI_CFG_DATA >> ((offset & 3) * 8);
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int qube_pcibios_write_config_dword (unsigned char bus,
-					    unsigned char dev,
-					    unsigned char offset,
-					    unsigned int val)
-{
-	unsigned char fun = dev & 0x07;
-
-	dev >>= 3;
-	if(offset & 0x3)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	if (pci_range_ck(bus, dev))
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	PCI_CFG_SET(dev, fun, offset);
-	*PCI_CFG_DATA = val;
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-qube_pcibios_write_config_word (unsigned char bus, unsigned char dev,
-                                unsigned char offset, unsigned short val)
-{
-	unsigned char fun = dev & 0x07;
-	unsigned long tmp;
-
-	dev >>= 3;
-	if (offset & 0x1)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	if (pci_range_ck(bus, dev))
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	PCI_CFG_SET(dev, fun, (offset & ~0x3));
-	tmp = *PCI_CFG_DATA;
-	tmp &= ~(0xffff << ((offset & 0x3) * 8));
-	tmp |=  (val << ((offset & 0x3) * 8));
-	*PCI_CFG_DATA = tmp;
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-qube_pcibios_write_config_byte (unsigned char bus, unsigned char dev,
-                                unsigned char offset, unsigned char val)
-{
-	unsigned char fun = dev & 0x07;
-	unsigned long tmp;
-
-	dev >>= 3;
-	if (pci_range_ck(bus, dev))
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	PCI_CFG_SET(dev, fun, (offset & ~0x3));
-	tmp = *PCI_CFG_DATA;
-	tmp &= ~(0xff << ((offset & 0x3) * 8));
-	tmp |=  (val << ((offset & 0x3) * 8));
-	*PCI_CFG_DATA = tmp;
-	return PCIBIOS_SUCCESSFUL;
-}
-
-struct pci_ops qube_pci_ops = {
-	qube_pcibios_fixup,
-	qube_pcibios_read_config_byte,
-	qube_pcibios_read_config_word,
-	qube_pcibios_read_config_dword,
-	qube_pcibios_write_config_byte,
-	qube_pcibios_write_config_word,
-	qube_pcibios_write_config_dword
-};
-
-#endif /* CONFIG_PCI */
diff -urN linux-2.4.2-pre1/arch/mips/cobalt/reset.c linux/arch/mips/cobalt/reset.c
--- linux-2.4.2-pre1/arch/mips/cobalt/reset.c	Thu Jul 13 09:39:49 2000
+++ linux/arch/mips/cobalt/reset.c	Wed Dec 31 16:00:00 1969
@@ -1,61 +0,0 @@
-/*
- *  Reset a Cobalt Qube.
- */
-#include <linux/config.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/processor.h>
-#include <asm/reboot.h>
-#include <asm/system.h>
-
-void cobalt_machine_restart(char *command)
-{
-	*(volatile char *)0xbc000000 = 0x0f;
-
-	/*
-	 * Ouch, we're still alive ... This time we take the silver bullet ...
-	 * ... and find that we leave the hardware in a state in which the
-	 * kernel in the flush locks up somewhen during of after the PCI
-	 * detection stuff.
-	 */
-	set_cp0_status((ST0_BEV | ST0_ERL), (ST0_BEV | ST0_ERL));
-	set_cp0_config(CONFIG_CM_CMASK, CONFIG_CM_UNCACHED);
-	flush_cache_all();
-	write_32bit_cp0_register(CP0_WIRED, 0);
-	__asm__ __volatile__(
-		"jr\t%0"
-		:
-		: "r" (0xbfc00000));
-}
-
-extern int led_state;
-#define kLED            0xBC000000
-#define LEDSet(x)       (*(volatile unsigned char *) kLED) = (( unsigned char)x)
-
-void cobalt_machine_halt(void)
-{
-	int mark;
-
-	// Blink our cute little LED (number 3)...
-	while (1) {
-		led_state = led_state | ( 1 << 3 );
-		LEDSet(led_state);  
-		mark = jiffies;
-		while (jiffies<(mark+HZ));
-		led_state = led_state & ~( 1 << 3 );
-		LEDSet(led_state);
-		mark = jiffies;
-		while (jiffies<(mark+HZ));
-	} 
-}
-
-/*
- * This triggers the luser mode device driver for the power switch ;-)
- */
-void cobalt_machine_power_off(void)
-{
-	printk("You can switch the machine off now.\n");
-	cobalt_machine_halt();
-}
diff -urN linux-2.4.2-pre1/arch/mips/cobalt/serial.h linux/arch/mips/cobalt/serial.h
--- linux-2.4.2-pre1/arch/mips/cobalt/serial.h	Sun Jul  9 22:18:15 2000
+++ linux/arch/mips/cobalt/serial.h	Wed Dec 31 16:00:00 1969
@@ -1,28 +0,0 @@
-/*
- * 
- * Filename: serial.h
- * 
- * Description: Some general definitions used for serial code 
- * 
- * Author(s): Timothy Stonis
- * 
- * Copyright 1997, Cobalt Microserver, Inc.
- */
- 
-/*
- * Serial port definitions
- */
-#define kSCC_Base	kGal_DevBank1Base
-#define kHelloWorldMsg	"Cobalt Networks Diagnostics - 'We serve it, you surf it'\n\r"
-#define kSCC_ChanA	0x01
-#define kSCC_ChanB	0x00
-#define kSCC_Direct	0x02
-#define kSCC_Command	0x00
-
-#define kSCC_TestVal	0xA5
-#define kSCC_19200	0x07	/* x32 clock mode, 19200 baud 	*/
-#define kSCC_115200	0x01	/* x16 clock mode, 115200 baud 	*/
-
-#define Read8530(n)	(*((unsigned char *) (kSCC_Base | (n))))
-
-#define Write8530(x,y)	(*((unsigned char *) (kSCC_Base | (x))) = (y))
diff -urN linux-2.4.2-pre1/arch/mips/cobalt/setup.c linux/arch/mips/cobalt/setup.c
--- linux-2.4.2-pre1/arch/mips/cobalt/setup.c	Sun Jul  9 22:18:15 2000
+++ linux/arch/mips/cobalt/setup.c	Wed Dec 31 16:00:00 1969
@@ -1,411 +0,0 @@
-/*
- * Setup pointers to hardware dependand routines.
- *
- * 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.
- *
- * Copyright (C) 1996, 1997 by Ralf Baechle
- */
-#include <linux/bios32.h>
-#include <linux/config.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/timex.h>
-#include <asm/bootinfo.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/cobalt.h>
-#include <asm/pci.h>
-#include <asm/processor.h>
-#include <asm/ptrace.h>
-#include <asm/reboot.h>
-#include <asm/vector.h>
-
-extern void cobalt_machine_restart(char *command);
-extern void cobalt_machine_halt(void);
-extern void cobalt_machine_power_off(void);
-
-extern int serial_console;
-
-/*
- * Initial irq handlers.
- */
-static void no_action(int cpl, void *dev_id, struct pt_regs *regs)
-{ 
-}
-
-/*
- * IRQ2 is cascade interrupt to second interrupt controller
- */
-static struct irqaction irq2  = { no_action, 0, 0, "cascade", NULL, NULL};
-
-extern struct feature cobalt_feature;
-extern asmlinkage void cobalt_handle_int(void);
-
-static void cobalt_irq_setup(void) 
-{
-	/*
-	 * Clear all of the interrupts while we change the able around a bit.
-	 */
- 	set_cp0_status(ST0_IM, 0);
-
-	/* Sets the exception_handler array. */
-	set_except_vector(0, cobalt_handle_int);
-
-	request_region(0xb0000020, 0x20, "pic1");
-	request_region(0xb00000A0, 0x20, "pic2");
-	setup_x86_irq(2, &irq2);
-
-	cli();
-
-	set_cp0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1 | IE_IRQ0);
-
-	/* Setup VIA irq mask */
-	VIA_PORT_WRITE(0x20, 0x10);
-	VIA_PORT_WRITE(0x21, 0x00);
-	VIA_PORT_WRITE(0x21, 0x00);
-
-	VIA_PORT_WRITE(0xa0, 0x10);
-	VIA_PORT_WRITE(0xa1, 0x00);
-	VIA_PORT_WRITE(0xa1, 0x00);
-}
-
-void (*board_time_init)(struct irqaction *irq);
-
-static void cobalt_calibrate_timer(void)
-{
-	volatile unsigned long *timer_reg = (volatile unsigned long *)0xb4000850;
-
-	/* Default to 150MHZ, since this is what we are shipping. */
-	*timer_reg = 500000;
-}
-
-static void cobalt_time_init(struct irqaction *irq)
-{
-	/* Load timer value for 100 Hz */
-	cobalt_calibrate_timer();
-	/* *((volatile unsigned long *) 0xb4000850) = (unsigned long) 440000; */
-
-	setup_x86_irq(0, irq);
-
-	/* Enable timer ints */
-	*((volatile unsigned long *) 0xb4000864) = (unsigned long) 0x00000003;
-	/* Unmask timer int */
-	*((volatile unsigned long *) 0xb4000c1c) = (unsigned long) 0x00000100; 
-}
-
-extern struct pci_ops qube_pci_ops;
-int cobalt_serial_present;
-int cobalt_serial_type;
-int cobalt_is_raq;
-
-void cobalt_setup(void)
-{
-	tag *atag;
-
-	/*
-	 * We just check if a tag_screen_info can be gathered
-	 * in setup_arch(), if yes we don't proceed futher...
-	 */
-	atag = bi_TagFind(tag_screen_info);
-	if (!atag) {
-		/*
-		 * If no, we try to find the tag_arc_displayinfo which is
-		 * always created by Milo for an ARC box (for now Milo only
-		 * works on ARC boxes :) -Stoned.
-		 */
-		atag = bi_TagFind(tag_arcdisplayinfo);
-		if (atag) {
-
-			screen_info.orig_x = 
-				((mips_arc_DisplayInfo*)TAGVALPTR(atag))->cursor_x;
-			screen_info.orig_y = 
-				((mips_arc_DisplayInfo*)TAGVALPTR(atag))->cursor_y;
-			screen_info.orig_video_cols  = 
-				((mips_arc_DisplayInfo*)TAGVALPTR(atag))->columns;
-			screen_info.orig_video_lines  = 
-				((mips_arc_DisplayInfo*)TAGVALPTR(atag))->lines;
-		}
-	}
-
-	_machine_restart = cobalt_machine_restart;
-	_machine_halt = cobalt_machine_halt;
-	_machine_power_off = cobalt_machine_power_off;
-
-	irq_setup = cobalt_irq_setup;
-	board_time_init = cobalt_time_init;
-	feature = &cobalt_feature;
-	mips_io_port_base = COBALT_LOCAL_IO_SPACE;
-
-	pci_ops = &qube_pci_ops;
-
-#ifdef CONFIG_COBALT_SERIAL
-	serial_console = 1;
-#endif /* CONFIG_COBALT_SERIAL */
-
-	/* We have to do this early, here, before the value could
-	 * possibly be overwritten by the bootup sequence.
-	 */
-	cobalt_serial_present = *((unsigned long *) 0xa020001c);
-	cobalt_serial_type    = *((unsigned long *) 0xa0200020);
-	cobalt_is_raq         = (cobalt_serial_present != 0x0
-				 && cobalt_serial_type == 0x1);
-}
-
-void	AddTagsEndSymbol(void);
-int bi_TagAdd (enum bi_tag type, unsigned long size, void *data);
-unsigned long next_tag = (unsigned long) NULL;
-unsigned long memory_upper = (unsigned long) NULL;
-
-int bi_TagAdd (enum bi_tag type, unsigned long size, void *data)
-{
-	tag t;
-	unsigned long addr;
-
-	t.tag = type;
-	t.size = size;
-
-	/*
-	 * If next_tag equals NULL it means it's the first tag we're asked
-	 * to create.
-	 */
-	if (next_tag == (unsigned long) NULL)  {
-		/*
-		 * If memory_upper not equals NULL it means that identify()
-		 * was able to figure out how much memory is present in the
-		 * box so we initialize next_tag from it.
-		 */
-		if (memory_upper != (unsigned long) NULL)
-			next_tag = memory_upper;
-
-		/* Else we rely on the fact that the first tag we create for
-		 * a box for which we don't know how RAM it gots is a tag of
-		 * type tag_memupper.  This is ensured by the first entry in
-		 * the defaults tag list for such a box (see identify.c).
-		 * First we check this.
-		 */
-		else {
-			/* Ok it's a memupper tag: we put it's value in 
-			 * memory_upper so launch() can pass it to the
-			 * kernel in register a0 and we initialize next_tag.
-			 */
- 			next_tag = *(unsigned long *) data;
-			memory_upper = *((unsigned long *) data);
-		}
-	}
-
-	/* We put the tag structure.  */
-	addr = next_tag - (sizeof (tag));
-
-	memcpy ((void *) addr, (void *) &t, (size_t) (sizeof (tag)));
-
-	/* We put the tag's data if any.  */
-	if (size != 0) {
-		addr = addr - size;
-		memcpy ((void *) addr, data, (size_t) (t.size));
-	}
-
-	/*
-	 * Set next_tag ready for the next tag creation.
-	 */
-	next_tag = addr;
-	AddTagsEndSymbol();
-
-	return 0;
-}
-
-void SetUpBootInfo(void)
-{
-	unsigned long LongVar;
-	int atag;
-
-	/*
-	 * This is hard coded here but will change when we have a
-	 * Size mem routine.
-	 */
-
-	/*
-	 * 64mb of memory.
-	 */
-
- 	//mips_memory_upper = 0x84000000;
-
-
-#ifndef BOOTLOADER
-
-#if 0	/* You break'a the kernel I break'a ya face. -DaveM */
-
-	/* Eight meg of memory.         */
-	mips_memory_upper = 0x80800000;  /* XXX  this appears to be unused  - 
-                                           this assignment is not present in the normal
-                                           $cvstree/linux/arch/mips/cobalt/setup.c */
-#endif
-#else
-#include "../../../../include/diagdefs.h"
-	mips_memory_upper = (unsigned long) kBootloaderMipsMemoryUpper;
-#endif
- 
-	LongVar = mips_memory_upper;
-	atag = bi_TagAdd(tag_memupper, ULONGSIZE, &LongVar);
-
-	/* Here is the machine type.
-	*/
-	LongVar = MACH_COBALT_27;
-	atag = bi_TagAdd(tag_machtype, ULONGSIZE, &LongVar);
-
-	LongVar = 0x80000000;
-	atag = bi_TagAdd(tag_memlower, ULONGSIZE, &LongVar);
-
-	LongVar = CPU_R4300;
-	atag = bi_TagAdd(tag_cputype, ULONGSIZE, &LongVar);
-
-	LongVar = MACH_GROUP_COBALT;
-	atag = bi_TagAdd(tag_machgroup, ULONGSIZE, &LongVar);
-
-	LongVar = 0;
-	atag = bi_TagAdd(tag_scache_size, ULONGSIZE, &LongVar);
-
-	LongVar = 48;
-	atag = bi_TagAdd(tag_tlb_entries, ULONGSIZE, &LongVar);
-
- 	LongVar = 0;
-	atag = bi_TagAdd(tag_drive_info, ULONGSIZE, &LongVar);
-
-	LongVar = 0xe0800000;
-	atag = bi_TagAdd(tag_vram_base, ULONGSIZE, &LongVar);
-
-	LongVar = 0;
-	atag = bi_TagAdd(tag_dummy, 0, &LongVar);
-}
-
-void AddTagsEndSymbol(void)
-{
-	short	X;
-	X = 1;
-}
-
-/*
- * Oh shit, this is so crappy ...
- */
-#include <linux/mm.h>
-#include <asm/pgtable.h>
-int my_cacheflush(unsigned long start, unsigned long size, unsigned int what)
-{
-	flush_cache_range(current->mm, start, start + size);
-	return 0;
-}
-
-
-/*
- * The ROM set the flag to 0x1 to turn off output.  This is interpreted
- * as "valid", "no kernel output", and index '0' into the following
- * tables.  We overload entry '0' to specify a sensible default rate.
- */
-static int cons_baud_int[]  = { 9600, 0,  9600, 0, 0,  115200, 0, 0 };
-static int cons_baud_baud[] = { B9600, 0, B9600, 0, 0, B115200, 0, 0 };
-
-static union cobalt_cons_info
-cobalt_get_console_info(void)
-{
-	char board_id = 0;
-	static union cobalt_cons_info cons_info;
-	static int read_info = 0;
-	extern void add_init_env(char *);
-
-	if (read_info)
-		return cons_info;
-
-	VIA_PORT_WRITE(VIA_CMOS_ADDR, VIA_CMOS_CONSOLE_FLG);
-	cons_info.ccons_char = VIA_PORT_READ(VIA_CMOS_DATA);
-
-#if 0
-	printk("cobalt_get_console_info: read 0x%x from console flag\n",
-	       cons_info.ccons_char);
-#endif
-
-	/*
-	 * CMOS hasn't been initialized or baud rate isn't known.
-	 * - read the board id and provide backwards compat.
-	 */
-	if (cons_info.ccons_bits.valid != VIA_CMOS_CONS_VALID
-	    || ! cons_baud_int[cons_info.ccons_bits.baud]
-	    || ! cons_baud_baud[cons_info.ccons_bits.baud]) {
-		pcibios_read_config_byte(0, PCI_DEVSHFT(COBALT_PCICONF_VIA),
-	                                 VIA_COBALT_BRD_ID_REG, &board_id);
-
-#if 0
-		printk("cobalt_get_console_info: read 0x%x from board config\n",
-		       board_id);
-#endif
-
-		switch (VIA_COBALT_BRD_REG_to_ID(board_id)) {
-		case COBALT_BRD_ID_QUBE1:
-			cons_info.ccons_bits.baud = VIA_CMOS_CONS_115K;
-			cons_info.ccons_bits.kout = 1;
-			break;
-		case COBALT_BRD_ID_RAQ1:
-			cons_info.ccons_bits.baud = VIA_CMOS_CONS_9600;
-			cons_info.ccons_bits.kout = 1;
-			break;
-		case COBALT_BRD_ID_QUBE2:
-			cons_info.ccons_bits.baud = VIA_CMOS_CONS_9600;
-			cons_info.ccons_bits.kout = 0;
-			break;
-		case COBALT_BRD_ID_RAQ2:
-			cons_info.ccons_bits.baud = VIA_CMOS_CONS_9600;
-			cons_info.ccons_bits.kout = 1;
-			break;
-		}
-		cons_info.ccons_bits.valid = VIA_CMOS_CONS_VALID;
-	}
-
-	read_info = 1;
-
-#if defined(DEBUG_LOADER)
-	cons_info.ccons_bits.kout = 1;
-#endif
-
-	if (!cons_info.ccons_bits.kout) {
-		add_init_env("CONSOLE=/dev/null");
-	}
-
-#if 0
-	printk("cobalt_get_console_info: returning 0x%x\n",
-		cons_info.ccons_char);
-#endif
-
-	return cons_info;
-}
-
-int
-cobalt_cons_koutok(void)
-{
-	union cobalt_cons_info cons;
-
-	cons = cobalt_get_console_info();
-
-	return cons.ccons_bits.kout;
-}
-
-int
-cobalt_cons_baudbaud(void)
-{
-	union cobalt_cons_info cons;
-
-	cons = cobalt_get_console_info();
-
-	return cons_baud_baud[cons.ccons_bits.baud];
-}
-
-int
-cobalt_cons_baudint(void)
-{
-	union cobalt_cons_info cons;
-
-	cons = cobalt_get_console_info();
-
-	return cons_baud_int[cons.ccons_bits.baud];
-}
diff -urN linux-2.4.2-pre1/arch/mips/cobalt/via.c linux/arch/mips/cobalt/via.c
--- linux-2.4.2-pre1/arch/mips/cobalt/via.c	Sun Jul  9 22:18:15 2000
+++ linux/arch/mips/cobalt/via.c	Wed Dec 31 16:00:00 1969
@@ -1,90 +0,0 @@
-/*
- * Interrupt handling for the VIA ISA bridge.
- *
- * Everything the same ... just different ...
- */
-#include <linux/kernel.h>
-#include <asm/cobalt.h>
-#include <asm/ptrace.h>
-#include <asm/io.h>
-
-extern asmlinkage void do_IRQ(int irq, struct pt_regs * regs);
-
-extern unsigned char cache_21;
-extern unsigned char cache_A1;
-
-/*
- * (un)mask_irq, disable_irq() and enable_irq() only handle (E)ISA and
- * PCI devices.  Other onboard hardware needs specific routines.
- */
-void mask_irq(unsigned int irq_nr)
-{
-	unsigned char mask;
-
-	mask = 1 << (irq_nr & 7);
-	if (irq_nr < 8) {
-		cache_21 |= mask;
-		outb(cache_21, 0x10000021);
-	} else {
-		cache_A1 |= mask;
-		outb(cache_A1, 0x100000a1);
-	}
-}
-
-void unmask_irq(unsigned int irq_nr)
-{
-	unsigned char mask;
-
-	mask = ~(1 << (irq_nr & 7));
-	if (irq_nr < 8) {
-		cache_21 &= mask;
-		outb(cache_21, 0x10000021);
-	} else {
-		cache_A1 &= mask;
-		outb(cache_A1, 0x100000a1);
-	}
-}
-
-asmlinkage void via_irq(struct pt_regs *regs)
-{
-	char mstat, sstat;
-  
-	/* Read Master Status */
-	VIA_PORT_WRITE(0x20, 0x0C);
-	mstat = VIA_PORT_READ(0x20);
- 
-	if (mstat < 0) {
-		mstat &= 0x7f;
-		if (mstat != 2) {     	
-			do_IRQ(mstat, regs);
-			VIA_PORT_WRITE(0x20, mstat | 0x20);
-		} else {
-			sstat = VIA_PORT_READ(0xA0);
-
-			/* Slave interrupt */
-			VIA_PORT_WRITE(0xA0, 0x0C);
-			sstat = VIA_PORT_READ(0xA0);
-   
-			if (sstat < 0) {
-				do_IRQ((sstat + 8) & 0x7f, regs);
-				VIA_PORT_WRITE(0x20, 0x22);       
-				VIA_PORT_WRITE(0xA0, (sstat & 0x7f) | 0x20);
-			} else {
-				printk("Spurious slave interrupt...\n");
-			}
-		}
-	} else
-		printk("Spurious master interrupt...");
-}
-
-asmlinkage void galileo_irq(struct pt_regs *regs)
-{
-	unsigned long irq_src = *((unsigned long *) 0xb4000c18); 
-  
-	/* Check for timer irq ... */
-	if (irq_src & 0x00000100) {
-		*((volatile unsigned long *) 0xb4000c18) = 0;
-		do_IRQ(0, regs);
-	} else
-		printk("Spurious Galileo interrupt...\n");
-}
diff -urN linux-2.4.2-pre1/arch/mips/cobalt/z8530.h linux/arch/mips/cobalt/z8530.h
--- linux-2.4.2-pre1/arch/mips/cobalt/z8530.h	Sun Jul  9 22:18:15 2000
+++ linux/arch/mips/cobalt/z8530.h	Wed Dec 31 16:00:00 1969
@@ -1,219 +0,0 @@
-/* 8530 Serial Communications Controller Register definitions */
-#define	FLAG	0x7e
-
-/* Write Register 0 */
-#define	R0	0		/* Register selects */
-#define	R1	1
-#define	R2	2
-#define	R3	3
-#define	R4	4
-#define	R5	5
-#define	R6	6
-#define	R7	7
-#define	R8	8
-#define	R9	9
-#define	R10	10
-#define	R11	11
-#define	R12	12
-#define	R13	13
-#define	R14	14
-#define	R15	15
-
-#define	NULLCODE	0	/* Null Code */
-#define	POINT_HIGH	0x8	/* Select upper half of registers */
-#define	RES_EXT_INT	0x10	/* Reset Ext. Status Interrupts */
-#define	SEND_ABORT	0x18	/* HDLC Abort */
-#define	RES_RxINT_FC	0x20	/* Reset RxINT on First Character */
-#define	RES_Tx_P	0x28	/* Reset TxINT Pending */
-#define	ERR_RES		0x30	/* Error Reset */
-#define	RES_H_IUS	0x38	/* Reset highest IUS */
-
-#define	RES_Rx_CRC	0x40	/* Reset Rx CRC Checker */
-#define	RES_Tx_CRC	0x80	/* Reset Tx CRC Checker */
-#define	RES_EOM_L	0xC0	/* Reset EOM latch */
-
-/* Write Register 1 */
-
-#define	EXT_INT_ENAB	0x1	/* Ext Int Enable */
-#define	TxINT_ENAB	0x2	/* Tx Int Enable */
-#define	PAR_SPEC	0x4	/* Parity is special condition */
-
-#define	RxINT_DISAB	0	/* Rx Int Disable */
-#define	RxINT_FCERR	0x8	/* Rx Int on First Character Only or Error */
-#define	INT_ALL_Rx	0x10	/* Int on all Rx Characters or error */
-#define	INT_ERR_Rx	0x18	/* Int on error only */
-
-#define	WT_RDY_RT	0x20	/* Wait/Ready on R/T */
-#define	WT_FN_RDYFN	0x40	/* Wait/FN/Ready FN */
-#define	WT_RDY_ENAB	0x80	/* Wait/Ready Enable */
-
-/* Write Register #2 (Interrupt Vector) */
-
-/* Write Register 3 */
-
-#define	RxENABLE	0x1	/* Rx Enable */
-#define	SYNC_L_INH	0x2	/* Sync Character Load Inhibit */
-#define	ADD_SM		0x4	/* Address Search Mode (SDLC) */
-#define	RxCRC_ENAB	0x8	/* Rx CRC Enable */
-#define	ENT_HM		0x10	/* Enter Hunt Mode */
-#define	AUTO_ENAB	0x20	/* Auto Enables */
-#define	Rx5		0x0	/* Rx 5 Bits/Character */
-#define	Rx7		0x40	/* Rx 7 Bits/Character */
-#define	Rx6		0x80	/* Rx 6 Bits/Character */
-#define	Rx8		0xc0	/* Rx 8 Bits/Character */
-
-/* Write Register 4 */
-
-#define	PAR_ENA		0x1	/* Parity Enable */
-#define	PAR_EVEN	0x2	/* Parity Even/Odd* */
-
-#define	SYNC_ENAB	0	/* Sync Modes Enable */
-#define	SB1		0x4	/* 1 stop bit/char */
-#define	SB15		0x8	/* 1.5 stop bits/char */
-#define	SB2		0xc	/* 2 stop bits/char */
-
-#define	MONSYNC		0	/* 8 Bit Sync character */
-#define	BISYNC		0x10	/* 16 bit sync character */
-#define	SDLC		0x20	/* SDLC Mode (01111110 Sync Flag) */
-#define	EXTSYNC		0x30	/* External Sync Mode */
-
-#define	X1CLK		0x0	/* x1 clock mode */
-#define	X16CLK		0x40	/* x16 clock mode */
-#define	X32CLK		0x80	/* x32 clock mode */
-#define	X64CLK		0xC0	/* x64 clock mode */
-
-/* Write Register 5 */
-
-#define	TxCRC_ENAB	0x1	/* Tx CRC Enable */
-#define	RTS		0x2	/* RTS */
-#define	SDLC_CRC	0x4	/* SDLC/CRC-16 */
-#define	TxENAB		0x8	/* Tx Enable */
-#define	SND_BRK		0x10	/* Send Break */
-#define	Tx5		0x0	/* Tx 5 bits (or less)/character */
-#define	Tx7		0x20	/* Tx 7 bits/character */
-#define	Tx6		0x40	/* Tx 6 bits/character */
-#define	Tx8		0x60	/* Tx 8 bits/character */
-#define	DTR		0x80	/* DTR */
-
-/* Write Register 6 (Sync bits 0-7/SDLC Address Field) */
-
-/* Write Register 7 (Sync bits 8-15/SDLC 01111110) */
-
-/* Write Register 8 (transmit buffer) */
-
-/* Write Register 9 (Master interrupt control) */
-#define	VIS	1	/* Vector Includes Status */
-#define	NV	2	/* No Vector */
-#define	DLC	4	/* Disable Lower Chain */
-#define	MIE	8	/* Master Interrupt Enable */
-#define	STATHI	0x10	/* Status high */
-#define	NORESET	0	/* No reset on write to R9 */
-#define	CHRB	0x40	/* Reset channel B */
-#define	CHRA	0x80	/* Reset channel A */
-#define	FHWRES	0xc0	/* Force hardware reset */
-
-/* Write Register 10 (misc control bits) */
-#define	BIT6	1	/* 6 bit/8bit sync */
-#define	LOOPMODE 2	/* SDLC Loop mode */
-#define	ABUNDER	4	/* Abort/flag on SDLC xmit underrun */
-#define	MARKIDLE 8	/* Mark/flag on idle */
-#define	GAOP	0x10	/* Go active on poll */
-#define	NRZ	0	/* NRZ mode */
-#define	NRZI	0x20	/* NRZI mode */
-#define	FM1	0x40	/* FM1 (transition = 1) */
-#define	FM0	0x60	/* FM0 (transition = 0) */
-#define	CRCPS	0x80	/* CRC Preset I/O */
-
-/* Write Register 11 (Clock Mode control) */
-#define	TRxCXT	0	/* TRxC = Xtal output */
-#define	TRxCTC	1	/* TRxC = Transmit clock */
-#define	TRxCBR	2	/* TRxC = BR Generator Output */
-#define	TRxCDP	3	/* TRxC = DPLL output */
-#define	TRxCOI	4	/* TRxC O/I */
-#define	TCRTxCP	0	/* Transmit clock = RTxC pin */
-#define	TCTRxCP	8	/* Transmit clock = TRxC pin */
-#define	TCBR	0x10	/* Transmit clock = BR Generator output */
-#define	TCDPLL	0x18	/* Transmit clock = DPLL output */
-#define	RCRTxCP	0	/* Receive clock = RTxC pin */
-#define	RCTRxCP	0x20	/* Receive clock = TRxC pin */
-#define	RCBR	0x40	/* Receive clock = BR Generator output */
-#define	RCDPLL	0x60	/* Receive clock = DPLL output */
-#define	RTxCX	0x80	/* RTxC Xtal/No Xtal */
-
-/* Write Register 12 (lower byte of baud rate generator time constant) */
-
-/* Write Register 13 (upper byte of baud rate generator time constant) */
-
-/* Write Register 14 (Misc control bits) */
-#define	BRENABL	1	/* Baud rate generator enable */
-#define	BRSRC	2	/* Baud rate generator source */
-#define	DTRREQ	4	/* DTR/Request function */
-#define	AUTOECHO 8	/* Auto Echo */
-#define	LOOPBAK	0x10	/* Local loopback */
-#define	SEARCH	0x20	/* Enter search mode */
-#define	RMC	0x40	/* Reset missing clock */
-#define	DISDPLL	0x60	/* Disable DPLL */
-#define	SSBR	0x80	/* Set DPLL source = BR generator */
-#define	SSRTxC	0xa0	/* Set DPLL source = RTxC */
-#define	SFMM	0xc0	/* Set FM mode */
-#define	SNRZI	0xe0	/* Set NRZI mode */
-
-/* Write Register 15 (external/status interrupt control) */
-#define	ZCIE	2	/* Zero count IE */
-#define	DCDIE	8	/* DCD IE */
-#define	SYNCIE	0x10	/* Sync/hunt IE */
-#define	CTSIE	0x20	/* CTS IE */
-#define	TxUIE	0x40	/* Tx Underrun/EOM IE */
-#define	BRKIE	0x80	/* Break/Abort IE */
-
-
-/* Read Register 0 */
-#define	Rx_CH_AV	0x1	/* Rx Character Available */
-#define	ZCOUNT		0x2	/* Zero count */
-#define	Tx_BUF_EMP	0x4	/* Tx Buffer empty */
-#define	DCD		0x8	/* DCD */
-#define	SYNC_HUNT	0x10	/* Sync/hunt */
-#define	CTS		0x20	/* CTS */
-#define	TxEOM		0x40	/* Tx underrun */
-#define	BRK_ABRT	0x80	/* Break/Abort */
-
-/* Read Register 1 */
-#define	ALL_SNT		0x1	/* All sent */
-/* Residue Data for 8 Rx bits/char programmed */
-#define	RES3		0x8	/* 0/3 */
-#define	RES4		0x4	/* 0/4 */
-#define	RES5		0xc	/* 0/5 */
-#define	RES6		0x2	/* 0/6 */
-#define	RES7		0xa	/* 0/7 */
-#define	RES8		0x6	/* 0/8 */
-#define	RES18		0xe	/* 1/8 */
-#define	RES28		0x0	/* 2/8 */
-/* Special Rx Condition Interrupts */
-#define	PAR_ERR		0x10	/* Parity error */
-#define	Rx_OVR		0x20	/* Rx Overrun Error */
-#define	CRC_ERR		0x40	/* CRC/Framing Error */
-#define	END_FR		0x80	/* End of Frame (SDLC) */
-
-/* Read Register 2 (channel b only) - Interrupt vector */
-
-/* Read Register 3 (interrupt pending register) ch a only */
-#define	CHBEXT	0x1		/* Channel B Ext/Stat IP */
-#define	CHBTxIP	0x2		/* Channel B Tx IP */
-#define	CHBRxIP	0x4		/* Channel B Rx IP */
-#define	CHAEXT	0x8		/* Channel A Ext/Stat IP */
-#define	CHATxIP	0x10		/* Channel A Tx IP */
-#define	CHARxIP	0x20		/* Channel A Rx IP */
-
-/* Read Register 8 (receive data register) */
-
-/* Read Register 10  (misc status bits) */
-#define	ONLOOP	2		/* On loop */
-#define	LOOPSEND 0x10		/* Loop sending */
-#define	CLK2MIS	0x40		/* Two clocks missing */
-#define	CLK1MIS	0x80		/* One clock missing */
-
-/* Read Register 12 (lower byte of baud rate generator constant) */
-
-/* Read Register 13 (upper byte of baud rate generator constant) */
-
-/* Read Register 15 (value of WR 15) */
diff -urN linux-2.4.2-pre1/arch/mips64/Makefile linux/arch/mips64/Makefile
--- linux-2.4.2-pre1/arch/mips64/Makefile	Wed Dec  6 20:32:41 2000
+++ linux/arch/mips64/Makefile	Mon Dec  3 22:27:48 2001
@@ -33,7 +33,7 @@
 # machines may also.  Since BFD is incredibly buggy with respect to
 # crossformat linking we rely on the elf2ecoff tool for format conversion.
 #
-CFLAGS		+= -I $(TOPDIR)/include/asm $(CFLAGS)
+CFLAGS		+= -I $(TOPDIR)/include/asm/gcc $(CFLAGS)
 CFLAGS		+= -mabi=64 -G 0 -mno-abicalls -fno-pic -Wa,--trap -pipe
 LINKFLAGS	+= -G 0 -static # -N
 MODFLAGS	+= -mlong-calls
@@ -153,7 +153,6 @@
 
 archclean:
 	@$(MAKEBOOT) clean
-	$(MAKE) -C arch/$(ARCH)/kernel clean
 	$(MAKE) -C arch/$(ARCH)/tools clean
 	rm -f vmlinux.64 arch/$(ARCH)/ld.script.elf32
 
diff -urN linux-2.4.2-pre1/arch/mips64/arc/Makefile linux/arch/mips64/arc/Makefile
--- linux-2.4.2-pre1/arch/mips64/arc/Makefile	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/arc/Makefile	Mon Dec  3 22:27:48 2001
@@ -3,15 +3,13 @@
 #
 
 L_TARGET = arclib.a
-L_OBJS  = init.o printf.o tree.o env.o cmdline.o misc.o time.o \
-	  file.o identify.o
+obj-y	:= init.o printf.o tree.o env.o cmdline.o misc.o time.o file.o \
+	   identify.o
 
 ifndef CONFIG_SGI_IP27
-L_OBJS += console.o
+  obj-y += console.o
 endif
 
-ifdef CONFIG_ARC_MEMORY
-L_OBJS += memory.o
-endif
+obj-$(CONFIG_ARC_MEMORY) += memory.o
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.2-pre1/arch/mips64/boot/Makefile linux/arch/mips64/boot/Makefile
--- linux-2.4.2-pre1/arch/mips64/boot/Makefile	Sun Jul  9 22:18:16 2000
+++ linux/arch/mips64/boot/Makefile	Mon Dec  3 22:27:48 2001
@@ -1,4 +1,3 @@
-# $Id: Makefile,v 1.1 1999/08/18 21:46:52 ralf Exp $
 #
 # This file is subject to the terms and conditions of the GNU General Public
 # License.  See the file "COPYING" in the main directory of this archive
diff -urN linux-2.4.2-pre1/arch/mips64/config.in linux/arch/mips64/config.in
--- linux-2.4.2-pre1/arch/mips64/config.in	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/config.in	Mon Dec  3 22:27:48 2001
@@ -1,4 +1,3 @@
-# $Id: config.in,v 1.19 2000/03/27 01:44:45 ralf Exp $
 #
 # For a description of the syntax of this configuration file,
 # see Documentation/kbuild/config-language.txt.
@@ -76,7 +75,7 @@
 	"R4300 CONFIG_CPU_R4300			\
 	 R4x00 CONFIG_CPU_R4X00			\
 	 R5000 CONFIG_CPU_R5000			\
-	 R56x0 CONFIG_CPU_NEVADA		\
+	 R52x0 CONFIG_CPU_NEVADA		\
 	 R8000 CONFIG_CPU_R8000			\
 	 R10000 CONFIG_CPU_R10000" R4x00
 endmenu
diff -urN linux-2.4.2-pre1/arch/mips64/defconfig linux/arch/mips64/defconfig
--- linux-2.4.2-pre1/arch/mips64/defconfig	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/defconfig	Mon Dec  3 22:27:48 2001
@@ -91,7 +91,6 @@
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
 # CONFIG_BLK_DEV_LVM is not set
-# CONFIG_LVM_PROC_FS is not set
 
 #
 # Networking options
@@ -144,6 +143,7 @@
 CONFIG_BLK_DEV_SD=y
 CONFIG_SD_EXTRA_DEVS=40
 CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
 # CONFIG_BLK_DEV_SR is not set
 # CONFIG_CHR_DEV_SG is not set
 
@@ -350,6 +350,8 @@
 # CONFIG_QUOTA is not set
 CONFIG_AUTOFS_FS=y
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
@@ -405,8 +407,6 @@
 # CONFIG_NCPFS_NFS_NS is not set
 # CONFIG_NCPFS_OS2_NS is not set
 # CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_MOUNT_SUBDIR is not set
-# CONFIG_NCPFS_NDS_DOMAINS is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 
@@ -426,6 +426,7 @@
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 CONFIG_KCORE_ELF=y
 
diff -urN linux-2.4.2-pre1/arch/mips64/defconfig-ip22 linux/arch/mips64/defconfig-ip22
--- linux-2.4.2-pre1/arch/mips64/defconfig-ip22	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/defconfig-ip22	Mon Dec  3 22:27:48 2001
@@ -81,7 +81,6 @@
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
 # CONFIG_BLK_DEV_LVM is not set
-# CONFIG_LVM_PROC_FS is not set
 
 #
 # Networking options
@@ -267,6 +266,8 @@
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
@@ -321,8 +322,6 @@
 # CONFIG_NCPFS_NFS_NS is not set
 # CONFIG_NCPFS_OS2_NS is not set
 # CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_MOUNT_SUBDIR is not set
-# CONFIG_NCPFS_NDS_DOMAINS is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 
@@ -331,6 +330,7 @@
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_SGI_PARTITION=y
+# CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
diff -urN linux-2.4.2-pre1/arch/mips64/defconfig-ip27 linux/arch/mips64/defconfig-ip27
--- linux-2.4.2-pre1/arch/mips64/defconfig-ip27	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/defconfig-ip27	Mon Dec  3 22:27:48 2001
@@ -91,7 +91,6 @@
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
 # CONFIG_BLK_DEV_LVM is not set
-# CONFIG_LVM_PROC_FS is not set
 
 #
 # Networking options
@@ -144,6 +143,7 @@
 CONFIG_BLK_DEV_SD=y
 CONFIG_SD_EXTRA_DEVS=40
 CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
 # CONFIG_BLK_DEV_SR is not set
 # CONFIG_CHR_DEV_SG is not set
 
@@ -350,6 +350,8 @@
 # CONFIG_QUOTA is not set
 CONFIG_AUTOFS_FS=y
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
@@ -405,8 +407,6 @@
 # CONFIG_NCPFS_NFS_NS is not set
 # CONFIG_NCPFS_OS2_NS is not set
 # CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_MOUNT_SUBDIR is not set
-# CONFIG_NCPFS_NDS_DOMAINS is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 
@@ -426,6 +426,7 @@
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 CONFIG_KCORE_ELF=y
 
diff -urN linux-2.4.2-pre1/arch/mips64/kernel/Makefile linux/arch/mips64/kernel/Makefile
--- linux-2.4.2-pre1/arch/mips64/kernel/Makefile	Sun Jul  9 22:18:16 2000
+++ linux/arch/mips64/kernel/Makefile	Mon Dec  3 22:27:48 2001
@@ -12,27 +12,20 @@
 all:	kernel.o head.o init_task.o
 
 O_TARGET := kernel.o
-O_OBJS	:= branch.o entry.o proc.o process.o ptrace.o r4k_cache.o r4k_fpu.o \
+
+export-objs = mips64_ksyms.o
+
+obj-y	:= branch.o entry.o proc.o process.o ptrace.o r4k_cache.o r4k_fpu.o \
 	   r4k_genex.o r4k_switch.o r4k_tlb.o r4k_tlb_debug.o r4k_tlb_glue.o \
 	   scall_64.o semaphore.o setup.o signal.o softfp.o syscall.o \
 	   traps.o unaligned.o
-OX_OBJS := mips64_ksyms.o
-
-ifdef CONFIG_MIPS32_COMPAT
-O_OBJS += linux32.o scall_o32.o signal32.o ioctl32.o
-endif
 
-ifdef CONFIG_BINFMT_ELF32
-O_OBJS += binfmt_elf32.o
-endif
-
-ifdef CONFIG_SMP
-O_OBJS += smp.o
-endif
+obj-$(CONFIG_MODULES)		+= mips64_ksyms.o
+obj-$(CONFIG_MIPS32_COMPAT)	+= linux32.o scall_o32.o signal32.o ioctl32.o
+obj-$(CONFIG_BINFMT_ELF32)	+= binfmt_elf32.o
+obj-$(CONFIG_SMP)		+= smp.o
 
 CFLAGS_r4k_genex.o := -P
 CFLAGS_r4k_tlb_glue.o := -P
-
-clean:
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.2-pre1/arch/mips64/kernel/setup.c linux/arch/mips64/kernel/setup.c
--- linux-2.4.2-pre1/arch/mips64/kernel/setup.c	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/kernel/setup.c	Mon Dec  3 22:27:48 2001
@@ -56,6 +56,8 @@
  */
 char cyclecounter_available;
 
+unsigned long loops_per_sec;
+
 /*
  * Set if box has EISA slots.
  */
diff -urN linux-2.4.2-pre1/arch/mips64/kernel/smp.c linux/arch/mips64/kernel/smp.c
--- linux-2.4.2-pre1/arch/mips64/kernel/smp.c	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/kernel/smp.c	Mon Dec  3 22:27:48 2001
@@ -57,7 +57,7 @@
 int smp_threads_ready;	/* Not used */
 atomic_t smp_commenced = ATOMIC_INIT(0);
 struct cpuinfo_mips cpu_data[NR_CPUS];
-int smp_num_cpus;		/* Number that came online.  */
+int smp_num_cpus = 1;		/* Number that came online.  */
 int __cpu_number_map[NR_CPUS];
 int __cpu_logical_map[NR_CPUS];
 cycles_t cacheflush_time;
diff -urN linux-2.4.2-pre1/arch/mips64/lib/Makefile linux/arch/mips64/lib/Makefile
--- linux-2.4.2-pre1/arch/mips64/lib/Makefile	Tue Dec  5 23:15:12 2000
+++ linux/arch/mips64/lib/Makefile	Mon Dec  3 22:27:48 2001
@@ -8,7 +8,8 @@
 	$(CC) $(CFLAGS) -c $< -o $*.o
 
 L_TARGET = lib.a
-L_OBJS	= csum_partial.o csum_partial_copy.o dump_tlb.o floppy-std.o \
+
+obj-y	+= csum_partial.o csum_partial_copy.o dump_tlb.o floppy-std.o \
 	  floppy-no.o ide-std.o ide-no.o kbd-std.o kbd-no.o rtc-std.o \
 	  rtc-no.o memset.o memcpy.o strlen_user.o strncpy_user.o \
 	  strnlen_user.o watch.o
diff -urN linux-2.4.2-pre1/arch/mips64/lib/rtc-no.c linux/arch/mips64/lib/rtc-no.c
--- linux-2.4.2-pre1/arch/mips64/lib/rtc-no.c	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/lib/rtc-no.c	Mon Dec  3 22:27:48 2001
@@ -1,5 +1,4 @@
-/* $Id: rtc-no.c,v 1.1 1999/08/21 21:43:01 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -7,9 +6,10 @@
  * Stub RTC routines to keep Linux from crashing on machine which don't
  * have a RTC chip.
  *
- * Copyright (C) 1998 by Ralf Baechle
+ * Copyright (C) 1998, 2001 by Ralf Baechle
  */
 #include <linux/kernel.h>
+#include <linux/spinlock.h>
 #include <linux/mc146818rtc.h>
 
 static unsigned char no_rtc_read_data(unsigned long addr)
diff -urN linux-2.4.2-pre1/arch/mips64/lib/rtc-std.c linux/arch/mips64/lib/rtc-std.c
--- linux-2.4.2-pre1/arch/mips64/lib/rtc-std.c	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/lib/rtc-std.c	Mon Dec  3 22:27:48 2001
@@ -1,5 +1,4 @@
-/* $Id: rtc-std.c,v 1.1 1999/08/21 21:43:01 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -8,6 +7,7 @@
  *
  * Copyright (C) 1998 by Ralf Baechle
  */
+#include <linux/spinlock.h>
 #include <linux/mc146818rtc.h>
 #include <asm/io.h>
 
diff -urN linux-2.4.2-pre1/arch/mips64/mm/Makefile linux/arch/mips64/mm/Makefile
--- linux-2.4.2-pre1/arch/mips64/mm/Makefile	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/mm/Makefile	Mon Dec  3 22:27:48 2001
@@ -1,33 +1,16 @@
-# $Id: Makefile,v 1.4 2000/01/17 23:32:46 ralf Exp $
 #
 # Makefile for the Linux/MIPS-specific parts of the memory manager.
 #
 
 O_TARGET := mm.o
-O_OBJS	 := extable.o init.o fault.o loadmmu.o
 
-ifdef CONFIG_CPU_R4300
-O_OBJS	+= r4xx0.o
-endif
-ifdef CONFIG_CPU_R4X00
-O_OBJS	+= r4xx0.o
-endif
-ifdef CONFIG_CPU_R5000
-O_OBJS	+= r4xx0.o
-endif
-ifdef CONFIG_CPU_NEVADA
-O_OBJS	+= r4xx0.o
-endif
-ifdef CONFIG_CPU_R10000
-O_OBJS	+= andes.o
-endif
+obj-y	 := extable.o init.o fault.o loadmmu.o
 
-ifdef CONFIG_SGI_IP22
-O_OBJS   += umap.o
-endif
-
-ifdef CONFIG_BAGET_MIPS
-O_OBJS   += umap.o
-endif
+obj-$(CONFIG_CPU_R4300)		+= r4xx0.o
+obj-$(CONFIG_CPU_R4X00)		+= r4xx0.o
+obj-$(CONFIG_CPU_R5000)		+= r4xx0.o
+obj-$(CONFIG_CPU_NEVADA)	+= r4xx0.o
+obj-$(CONFIG_CPU_R10000)	+= andes.o
+obj-$(CONFIG_SGI_IP22)		+= umap.o
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.2-pre1/arch/mips64/mm/r4xx0.c linux/arch/mips64/mm/r4xx0.c
--- linux-2.4.2-pre1/arch/mips64/mm/r4xx0.c	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/mm/r4xx0.c	Mon Dec  3 22:27:48 2001
@@ -2129,7 +2129,6 @@
 	       regs->cp0_epc, regs->cp0_badvaddr);
 	printk("Status  : %08x\nCause   : %08x\n",
 	       (unsigned int) regs->cp0_status, (unsigned int) regs->cp0_cause);
-//{static int x = 3; x--; if(!x) while(1);}
 }
 
 /* Detect and size the various r4k caches. */
diff -urN linux-2.4.2-pre1/arch/mips64/sgi-ip22/Makefile linux/arch/mips64/sgi-ip22/Makefile
--- linux-2.4.2-pre1/arch/mips64/sgi-ip22/Makefile	Sat May 13 08:30:17 2000
+++ linux/arch/mips64/sgi-ip22/Makefile	Mon Dec  3 22:27:48 2001
@@ -1,4 +1,3 @@
-# $Id: Makefile,v 1.1 1999/08/20 21:13:33 ralf Exp $
 #
 # Makefile for the SGI specific kernel interface routines
 # under Linux.
@@ -10,7 +9,8 @@
 	$(CC) $(CFLAGS) -c $< -o $*.o
 
 L_TARGET = ip22.a
-L_OBJS  = ip22-berr.o ip22-mc.o ip22-sc.o ip22-hpc.o ip22-int.o ip22-rtc.o \
-        ip22-setup.o system.o ip22-timer.o ip22-irq.o ip22-reset.o time.o
+
+obj-y	+= ip22-berr.o ip22-mc.o ip22-sc.o ip22-hpc.o ip22-int.o ip22-rtc.o \
+	   ip22-setup.o system.o ip22-timer.o ip22-irq.o ip22-reset.o time.o
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.2-pre1/arch/mips64/sgi-ip27/Makefile linux/arch/mips64/sgi-ip27/Makefile
--- linux-2.4.2-pre1/arch/mips64/sgi-ip27/Makefile	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/sgi-ip27/Makefile	Mon Dec  3 22:27:48 2001
@@ -8,8 +8,9 @@
 	$(CC) $(CFLAGS) -c $< -o $*.o
 
 O_TARGET = ip27.a
-O_OBJS  = ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o ip27-irq-glue.o \
-	  ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-pci.o \
-	  ip27-pci-dma.o ip27-reset.o ip27-setup.o ip27-timer.o
+
+obj-y	:= ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o ip27-irq-glue.o \
+	   ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-pci.o \
+	   ip27-pci-dma.o ip27-reset.o ip27-setup.o ip27-timer.o
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.2-pre1/arch/mips64/sgi-ip27/ip27-init.c linux/arch/mips64/sgi-ip27/ip27-init.c
--- linux-2.4.2-pre1/arch/mips64/sgi-ip27/ip27-init.c	Tue Nov 28 21:42:04 2000
+++ linux/arch/mips64/sgi-ip27/ip27-init.c	Mon Dec  3 22:27:48 2001
@@ -472,9 +472,9 @@
 			sprintf(p->comm, "%s%d", "Idle", num_cpus);
 			init_tasks[num_cpus] = p;
 			alloc_cpupda(cpu, num_cpus);
+			del_from_runqueue(p);
 			p->processor = num_cpus;
 			p->has_cpu = 1; /* we schedule the first task manually */
-			del_from_runqueue(p);
 			unhash_process(p);
 			/* Attach to the address space of init_task. */
 			atomic_inc(&init_mm.mm_count);
diff -urN linux-2.4.2-pre1/drivers/acorn/Makefile linux/drivers/acorn/Makefile
--- linux-2.4.2-pre1/drivers/acorn/Makefile	Wed Oct 20 16:29:08 1999
+++ linux/drivers/acorn/Makefile	Mon Dec  3 22:27:48 2001
@@ -5,8 +5,11 @@
 # removes any old dependencies. DON'T put your own dependencies here
 # unless it's something special (not a .c file).
 
-SUB_DIRS     := block char net scsi
-MOD_SUB_DIRS := $(SUB_DIRS)
-ALL_SUB_DIRS := $(SUB_DIRS)
+subdir-y	:= char
+subdir-m	:= $(subdir-y)
+
+# the BLOCK subdir is included from drivers/block now
+# the SCSI subdir is included from drivers/scsi now
+# the NET subdir is included from drivers/net now
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.2-pre1/drivers/acorn/block/Makefile linux/drivers/acorn/block/Makefile
--- linux-2.4.2-pre1/drivers/acorn/block/Makefile	Sun Aug 13 09:54:15 2000
+++ linux/drivers/acorn/block/Makefile	Mon Dec  3 22:27:48 2001
@@ -11,7 +11,7 @@
 
 USE_STANDARD_AS_RULE := true
 
-L_TARGET	:= acorn-block.a
+O_TARGET	:= acorn-block.o
 
 obj-y		:=
 obj-m		:=
@@ -24,36 +24,12 @@
 mfmhd_mod-objs	:= mfmhd.o mfm.o
 
 obj-$(CONFIG_BLK_DEV_FD1772)	+= fd1772_mod.o
-obj-$(CONFIG_BLK_DEV_MFM)	+= mfmhd.o mfm.o
-
-# Extract lists of the multi-part drivers.
-# The 'int-*' lists are intermediate files used to build the multi's.
-
-multi-y		:= $(filter $(list-multi), $(obj-y))
-multi-m		:= $(filter $(list-multi), $(obj-m))
-int-y		:= $(sort $(foreach m, $(multi-y), $($(basename $(m))-objs)))
-int-m		:= $(sort $(foreach m, $(multi-m), $($(basename $(m))-objs)))
-
-# Files that are both resident and modular; remove from modular.
-
-obj-m		:= $(filter-out $(obj-y), $(obj-m))
-int-m		:= $(filter-out $(int-y), $(int-m))
-
-# Take multi-part drivers out of obj-y and put components in.
-
-obj-y		:= $(filter-out $(list-multi), $(obj-y)) $(int-y)
-
-# Translate to Rules.make lists.
-
-L_OBJS		:= $(filter-out $(export-objs), $(obj-y))
-LX_OBJS		:= $(filter     $(export-objs), $(obj-y))
-M_OBJS		:= $(sort $(filter-out $(export-objs), $(obj-m)))
-MX_OBJS		:= $(sort $(filter     $(export-objs), $(obj-m)))
+obj-$(CONFIG_BLK_DEV_MFM)	+= mfmhd_mod.o
 
 include $(TOPDIR)/Rules.make
 
-fd1772_mod.o: $(FLOPPY)
-	$(LD) -r -o $@ $(FLOPPY)
+fd1772_mod.o: $(fd1772_mod-objs)
+	$(LD) -r -o $@ $(fd1772_mod-objs)
 
-mfmhd_mod.o: mfmhd.o mfm.o
-	$(LD) -r -o $@ mfmhd.o mfm.o
+mfmhd_mod.o: $(mfmhd_mod-objs)
+	$(LD) -r -o $@ $(mfmhd_mod-objs)
diff -urN linux-2.4.2-pre1/drivers/acorn/block/fd1772.c linux/drivers/acorn/block/fd1772.c
--- linux-2.4.2-pre1/drivers/acorn/block/fd1772.c	Sun Oct  1 20:35:15 2000
+++ linux/drivers/acorn/block/fd1772.c	Mon Dec  3 22:27:48 2001
@@ -276,8 +276,8 @@
 static volatile int fdc_busy = 0;
 static DECLARE_WAIT_QUEUE_HEAD(fdc_wait);
 
-
-static unsigned int changed_floppies = 0xff, fake_change = 0;
+/* long req'd for set_bit --RR */
+static unsigned long changed_floppies = 0xff, fake_change = 0;
 #define	CHECK_CHANGE_DELAY	HZ/2
 
 /* DAG - increased to 30*HZ - not sure if this is the correct thing to do */
diff -urN linux-2.4.2-pre1/drivers/acorn/char/Makefile linux/drivers/acorn/char/Makefile
--- linux-2.4.2-pre1/drivers/acorn/char/Makefile	Mon Sep 18 15:15:21 2000
+++ linux/drivers/acorn/char/Makefile	Mon Dec  3 22:27:48 2001
@@ -11,11 +11,6 @@
 
 O_TARGET 	:= acorn-char.o
 
-O_OBJS		:=
-OX_OBJS		:=
-M_OBJS		:=
-MX_OBJS		:=
-
 # Object file lists.
 
 obj-y   	:=
@@ -37,10 +32,5 @@
 
 # Do the i2c and rtc last
 obj-y		+= $(obj-$(MACHINE)) 
-
-O_OBJS		:= $(filter-out $(export-objs), $(obj-y))
-OX_OBJS		:= $(filter     $(export-objs), $(obj-y))
-M_OBJS		:= $(sort $(filter-out $(export-objs), $(obj-m)))
-MX_OBJS		:= $(sort $(filter     $(export-objs), $(obj-m)))
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.2-pre1/drivers/acorn/net/Config.in linux/drivers/acorn/net/Config.in
--- linux-2.4.2-pre1/drivers/acorn/net/Config.in	Thu Oct 28 10:16:02 1999
+++ linux/drivers/acorn/net/Config.in	Mon Dec  3 22:27:48 2001
@@ -2,6 +2,6 @@
 # Acorn Network device configuration
 #  These are for Acorn's Expansion card network interfaces
 #
-tristate '  Acorn Ether1 (82586) support' CONFIG_ARM_ETHER1
-tristate '  Acorn/ANT Ether3 (NQ8005) support' CONFIG_ARM_ETHER3
-tristate '  I-cubed EtherH (NS8390) support' CONFIG_ARM_ETHERH
+tristate '  Acorn Ether1 support' CONFIG_ARM_ETHER1
+tristate '  Acorn/ANT Ether3 support' CONFIG_ARM_ETHER3
+tristate '  I-cubed EtherH/ANT EtherM support' CONFIG_ARM_ETHERH
diff -urN linux-2.4.2-pre1/drivers/acorn/net/Makefile linux/drivers/acorn/net/Makefile
--- linux-2.4.2-pre1/drivers/acorn/net/Makefile	Sun Aug  6 11:23:40 2000
+++ linux/drivers/acorn/net/Makefile	Mon Dec  3 22:27:48 2001
@@ -14,7 +14,4 @@
 obj-$(CONFIG_ARM_ETHER3)	+= ether3.o
 obj-$(CONFIG_ARM_ETHER1)	+= ether1.o
 
-O_OBJS	:= $(obj-y)
-M_OBJS	:= $(obj-m)
-
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.2-pre1/drivers/acorn/net/ether1.c linux/drivers/acorn/net/ether1.c
--- linux-2.4.2-pre1/drivers/acorn/net/ether1.c	Mon Sep 18 15:15:22 2000
+++ linux/drivers/acorn/net/ether1.c	Mon Dec  3 22:27:48 2001
@@ -74,7 +74,8 @@
 static void ether1_timeout(struct net_device *dev);
 
 /* ------------------------------------------------------------------------- */
-static char *version = "ether1 ethernet driver (c) 2000 Russell King v1.07\n";
+
+static const char version[] __initdata = KERN_INFO "ether1 ethernet driver (c) 2000 Russell King v1.07\n";
 
 #define BUS_16 16
 #define BUS_8  8
@@ -646,18 +647,13 @@
 {
 	struct ether1_priv *priv = (struct ether1_priv *)dev->priv;
 
-	MOD_INC_USE_COUNT;
-
-	if (request_irq(dev->irq, ether1_interrupt, 0, "ether1", dev)) {
-		MOD_DEC_USE_COUNT;
+	if (request_irq(dev->irq, ether1_interrupt, 0, "ether1", dev))
 		return -EAGAIN;
-	}
 
 	memset (&priv->stats, 0, sizeof (struct net_device_stats));
 
 	if (ether1_init_for_open (dev)) {
 		free_irq (dev->irq, dev);
-		MOD_DEC_USE_COUNT;
 		return -EAGAIN;
 	}
 
@@ -965,8 +961,6 @@
 
 	free_irq(dev->irq, dev);
 
-	MOD_DEC_USE_COUNT;
-
 	return 0;
 }
 
@@ -996,7 +990,7 @@
 	static unsigned int version_printed = 0;
 
 	if (net_debug && version_printed++ == 0)
-		printk (KERN_INFO "%s", version);
+		printk (version);
 }
 
 static struct net_device * __init ether1_init_one(struct expansion_card *ec)
@@ -1008,11 +1002,13 @@
 	ether1_banner();
 
 	ecard_claim(ec);
-	
+
 	dev = init_etherdev(NULL, sizeof(struct ether1_priv));
 	if (!dev)
 		goto out;
 
+	SET_MODULE_OWNER(dev);
+
 	dev->base_addr	= ecard_address(ec, ECARD_IOC, ECARD_FAST);
 	dev->irq	= ec->irq;
 
@@ -1024,18 +1020,18 @@
 
 	priv = (struct ether1_priv *)dev->priv;
 	if ((priv->bus_type = ether1_reset(dev)) == 0)
-		goto free_dev;
+		goto release;
 
-	printk(KERN_INFO "%s: ether1 at %lx, IRQ%d, ether address ",
-		dev->name, dev->base_addr, dev->irq);
+	printk(KERN_INFO "%s: ether1 in slot %d, ",
+		dev->name, ec->slot_no);
     
 	for (i = 0; i < 6; i++) {
 		dev->dev_addr[i] = inb(IDPROM_ADDRESS + i);
-		printk (i==0?" %02x":i==5?":%02x\n":":%02x", dev->dev_addr[i]);
+		printk ("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':');
 	}
 
 	if (ether1_init_2(dev))
-		goto free_dev;
+		goto release;
 
 	dev->open		= ether1_open;
 	dev->stop		= ether1_close;
@@ -1046,9 +1042,10 @@
 	dev->watchdog_timeo	= 5 * HZ / 100;
 	return 0;
 
-free_dev:
+release:
 	release_region(dev->base_addr, 16);
 	release_region(dev->base_addr + 0x800, 4096);
+free:
 	unregister_netdev(dev);
 	kfree(dev);
 out:
diff -urN linux-2.4.2-pre1/drivers/acorn/net/ether3.c linux/drivers/acorn/net/ether3.c
--- linux-2.4.2-pre1/drivers/acorn/net/ether3.c	Mon Sep 18 15:15:22 2000
+++ linux/drivers/acorn/net/ether3.c	Mon Dec  3 22:27:48 2001
@@ -46,8 +46,6 @@
  * 1.17	RMK	13/05/2000	Updated for 2.3.99-pre8
  */
 
-static char *version = "ether3 ethernet driver (c) 1995-2000 R.M.King v1.17\n";
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -72,13 +70,15 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
+static const char version[] __initdata = "ether3 ethernet driver (c) 1995-2000 R.M.King v1.17\n";
+
 #include "ether3.h"
 
 static unsigned int net_debug = NET_DEBUG;
 static const card_ids __init ether3_cids[] = {
 	{ MANU_ANT2, PROD_ANT_ETHER3 },
 	{ MANU_ANT,  PROD_ANT_ETHER3 },
-	{ MANU_ANT,  PROD_ANT_ETHERB }, /* trial - will etherb work? */
+	{ MANU_ANT,  PROD_ANT_ETHERB },
 	{ 0xffff, 0xffff }
 };
 
@@ -97,12 +97,6 @@
 #define BUS_8		1
 #define BUS_UNKNOWN	0
 
-/*
- * I'm not sure what address we should default to if the internal one
- * is corrupted...
- */
-unsigned char def_eth_addr[6] = {0x00, 'L', 'i', 'n', 'u', 'x'};
-
 /* --------------------------------------------------------------------------- */
 
 typedef enum {
@@ -214,7 +208,7 @@
  * Read the ethernet address string from the on board rom.
  * This is an ascii string!!!
  */
-static void __init
+static int __init
 ether3_addr(char *addr, struct expansion_card *ec)
 {
 	struct in_chunk_dir cd;
@@ -228,13 +222,13 @@
 				break;
 		}
 		if (i == 6)
-			return;
+			return 0;
 	}
 	/* I wonder if we should even let the user continue in this case
 	 *   - no, it would be better to disable the device
 	 */
 	printk(KERN_ERR "ether3: Couldn't read a valid MAC address from card.\n");
-	memcpy(addr, def_eth_addr, 6);
+	return -ENODEV;
 }
 
 /* --------------------------------------------------------------------------- */
@@ -423,12 +417,8 @@
 static int
 ether3_open(struct net_device *dev)
 {
-	MOD_INC_USE_COUNT;
-
-	if (request_irq(dev->irq, ether3_interrupt, 0, "ether3", dev)) {
-	    	MOD_DEC_USE_COUNT;
+	if (request_irq(dev->irq, ether3_interrupt, 0, "ether3", dev))
 		return -EAGAIN;
-	}
 
 	ether3_init_for_open(dev);
 
@@ -457,7 +447,6 @@
 
 	free_irq(dev->irq, dev);
 
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
@@ -807,7 +796,8 @@
 	ec->irqaddr = (volatile unsigned char *)ioaddr(dev->base_addr);
 	ec->irqmask = 0xf0;
 
-	ether3_addr(dev->dev_addr, ec);
+	if (ether3_addr(dev->dev_addr, ec))
+		name = NULL;
 
 	return name;
 }
@@ -827,12 +817,17 @@
 	if (!dev)
 		goto out;
 
+	SET_MODULE_OWNER(dev);
+
 	name = ether3_get_dev(dev, ec);
+	if (!name)
+		goto free;
 
 	/*
 	 * this will not fail - the nature of the bus ensures this
 	 */
-	request_region(dev->base_addr, 128, dev->name);
+	if (!request_region(dev->base_addr, 128, dev->name))
+		goto free;
 
 	priv = (struct dev_priv *) dev->priv;
 
@@ -868,10 +863,9 @@
 		break;
 	}
 
-	printk("%s: %s at %lx, IRQ%d, ether address ",
-		dev->name, name, dev->base_addr, dev->irq);
+	printk("%s: %s in slot %d, ", dev->name, name, ec->slot_no);
 	for (i = 0; i < 6; i++)
-		printk(i == 5 ? "%2.2x\n" : "%2.2x:", dev->dev_addr[i]);
+		printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':');
 
 	if (ether3_init_2(dev))
 		goto failed;
@@ -887,6 +881,7 @@
 
 failed:
 	release_region(dev->base_addr, 128);
+free:
 	unregister_netdev(dev);
 	kfree(dev);
 out:
diff -urN linux-2.4.2-pre1/drivers/acorn/net/etherh.c linux/drivers/acorn/net/etherh.c
--- linux-2.4.2-pre1/drivers/acorn/net/etherh.c	Tue Nov  7 10:59:42 2000
+++ linux/drivers/acorn/net/etherh.c	Mon Dec  3 22:27:48 2001
@@ -67,7 +67,7 @@
 MODULE_AUTHOR("Russell King");
 MODULE_DESCRIPTION("i3 EtherH driver");
 
-static char version[] __initdata =
+static const char version[] __initdata =
 	"etherh [500/600/600A] ethernet driver (c) 2000 R.M.King v1.07\n";
 
 #define ETHERH500_DATAPORT	0x200	/* MEMC */
@@ -363,12 +363,8 @@
 static int
 etherh_open(struct net_device *dev)
 {
-	MOD_INC_USE_COUNT;
-
-	if (request_irq(dev->irq, ei_interrupt, 0, "etherh", dev)) {
-		MOD_DEC_USE_COUNT;
+	if (request_irq(dev->irq, ei_interrupt, 0, "etherh", dev))
 		return -EAGAIN;
-	}
 
 	/*
 	 * Make sure that we aren't going to change the
@@ -406,8 +402,6 @@
 {
 	ei_close (dev);
 	free_irq (dev->irq, dev);
-
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
@@ -424,12 +418,8 @@
 }
 
 static expansioncard_ops_t etherh_ops = {
-	etherh_irq_enable,
-	etherh_irq_disable,
-	NULL,
-	NULL,
-	NULL,
-	NULL
+	irqenable:	etherh_irq_enable,
+	irqdisable:	etherh_irq_disable,
 };
 
 /*
@@ -508,6 +498,8 @@
 	dev = init_etherdev(NULL, 0);
 	if (!dev)
 		goto out;
+
+	SET_MODULE_OWNER(dev);
 
 	etherh_addr(dev->dev_addr, ec);
 
diff -urN linux-2.4.2-pre1/drivers/acorn/scsi/Makefile linux/drivers/acorn/scsi/Makefile
--- linux-2.4.2-pre1/drivers/acorn/scsi/Makefile	Sun Aug 13 09:54:15 2000
+++ linux/drivers/acorn/scsi/Makefile	Mon Dec  3 22:27:48 2001
@@ -4,7 +4,7 @@
 
 USE_STANDARD_AS_RULE := true
 
-L_TARGET	:= acorn-scsi.a
+O_TARGET	:= acorn-scsi.o
 
 obj-y		:=
 obj-m		:=
@@ -24,31 +24,7 @@
 obj-$(CONFIG_SCSI_POWERTECSCSI)	+= powertec.o fas216.o queue.o msgqueue.o
 obj-$(CONFIG_SCSI_EESOXSCSI)	+= eesox.o fas216.o queue.o msgqueue.o
 
-# Extract lists of the multi-part drivers.
-# The 'int-*' lists are intermediate files used to build the multi's.
-
-multi-y		:= $(filter $(list-multi), $(obj-y))
-multi-m		:= $(filter $(list-multi), $(obj-m))
-int-y		:= $(sort $(foreach m, $(multi-y), $($(basename $(m))-objs)))
-int-m		:= $(sort $(foreach m, $(multi-m), $($(basename $(m))-objs)))
-
-# Files that are both resident and modular; remove from modular.
-
-obj-m		:= $(filter-out $(obj-y), $(obj-m))
-int-m		:= $(filter-out $(int-y), $(int-m))
-
-# Take multi-part drivers out of obj-y and put components in.
-
-obj-y		:= $(filter-out $(list-multi), $(obj-y)) $(int-y)
-
-# Translate to Rules.make lists.
-
-L_OBJS		:= $(filter-out $(export-objs), $(obj-y))
-LX_OBJS		:= $(filter     $(export-objs), $(obj-y))
-M_OBJS		:= $(sort $(filter-out $(export-objs), $(obj-m)))
-MX_OBJS		:= $(sort $(filter     $(export-objs), $(obj-m)))
-
 include $(TOPDIR)/Rules.make
 
-acornscsi_mod.o: acornscsi.o acornscsi-io.o
-	$(LD) $(LD_RFLAG) -r -o $@ acornscsi.o acornscsi-io.o
+acornscsi_mod.o: $(acornscsi_mod-objs)
+	$(LD) -r -o $@ $(acornscsi_mod-objs)
diff -urN linux-2.4.2-pre1/drivers/acorn/scsi/arxescsi.c linux/drivers/acorn/scsi/arxescsi.c
--- linux-2.4.2-pre1/drivers/acorn/scsi/arxescsi.c	Mon Sep 18 15:15:22 2000
+++ linux/drivers/acorn/scsi/arxescsi.c	Mon Dec  3 22:27:48 2001
@@ -16,6 +16,7 @@
  *  01-01-2000	SH	0.1.0   Added *real* pseudo dma writing
  *				(arxescsi_pseudo_dma_write)
  *  02-04-2000	RMK	0.1.1	Updated for new error handling code.
+ *  22-10-2000  SH		Updated for new registering scheme.
  */
 #include <linux/module.h>
 #include <linux/blk.h>
@@ -27,6 +28,7 @@
 #include <linux/unistd.h>
 #include <linux/stat.h>
 #include <linux/delay.h>
+#include <linux/init.h>
 
 #include <asm/dma.h>
 #include <asm/io.h>
@@ -416,8 +418,24 @@
 	return pos;
 }
 
-#ifdef MODULE
-Scsi_Host_Template driver_template = ARXEScsi;
+static Scsi_Host_Template arxescsi_template = ARXEScsi;
+
+static int __init init_arxe_scsi_driver(void)
+{
+        arxescsi_template.module = THIS_MODULE;
+	scsi_register_module(MODULE_SCSI_HA, &arxescsi_template);
+	if (arxescsi_template.present)
+		return 0;
+
+	scsi_unregister_module(MODULE_SCSI_HA, &arxescsi_template);
+	return -ENODEV;
+}
+
+static void __exit exit_arxe_scsi_driver(void)
+{
+	scsi_unregister_module(MODULE_SCSI_HA, &arxescsi_template);
+}
+
+module_init(init_arxe_scsi_driver);
+module_exit(exit_arxe_scsi_driver);
 
-#include "../../scsi/scsi_module.c"
-#endif
diff -urN linux-2.4.2-pre1/drivers/acorn/scsi/cumana_1.c linux/drivers/acorn/scsi/cumana_1.c
--- linux-2.4.2-pre1/drivers/acorn/scsi/cumana_1.c	Thu Nov 11 16:57:30 1999
+++ linux/drivers/acorn/scsi/cumana_1.c	Mon Dec  3 22:27:48 2001
@@ -51,24 +51,53 @@
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/ioport.h>
-#include <linux/init.h>
 #include <linux/blk.h>
+#include <linux/init.h>
 
 #include <asm/ecard.h>
 #include <asm/io.h>
+#include <asm/irq.h>
 #include <asm/system.h>
 
 #include "../../scsi/scsi.h"
 #include "../../scsi/hosts.h"
-#include "cumana_1.h"
-#include "../../scsi/NCR5380.h"
 #include "../../scsi/constants.h"
 
+#include <scsi/scsicam.h>
+
+#define CUMANASCSI_PUBLIC_RELEASE 1
+
 static const card_ids cumanascsi_cids[] = {
 	{ MANU_CUMANA, PROD_CUMANA_SCSI_1 },
 	{ 0xffff, 0xffff }
 };
 
+#define NCR5380_implementation_fields \
+    int port, ctrl
+
+#define NCR5380_local_declare() \
+        struct Scsi_Host *_instance
+
+#define NCR5380_setup(instance) \
+        _instance = instance
+
+#define NCR5380_read(reg) cumanascsi_read(_instance, reg)
+#define NCR5380_write(reg, value) cumanascsi_write(_instance, reg, value)
+
+#define do_NCR5380_intr do_cumanascsi_intr
+#define NCR5380_queue_command cumanascsi_queue_command
+#define NCR5380_abort cumanascsi_abort
+#define NCR5380_reset cumanascsi_reset
+#define NCR5380_proc_info cumanascsi_proc_info
+
+int NCR5380_proc_info(char *buffer, char **start, off_t offset,
+		      int length, int hostno, int inout);
+
+#define BOARD_NORMAL	0
+#define BOARD_NCR53C400	1
+
+#include "../../scsi/NCR5380.h"
+
 /*
  * Function : cumanascsi_setup(char *str, int *ints)
  *
@@ -79,7 +108,8 @@
  *
  */
 
-void cumanascsi_setup(char *str, int *ints) {
+void cumanascsi_setup(char *str, int *ints)
+{
 }
 
 #define CUMANA_ADDRESS(card) (ecard_address((card), ECARD_IOC, ECARD_SLOW) + 0x800)
@@ -141,7 +171,7 @@
 	else
 	    printk (" %d", instance->irq);
 	printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
-	    CAN_QUEUE, CMD_PER_LUN, CUMANASCSI_PUBLIC_RELEASE);
+	    tpnt->can_queue, tpnt->cmd_per_lun, CUMANASCSI_PUBLIC_RELEASE);
 	printk("\nscsi%d:", instance->host_no);
 	NCR5380_print_options(instance);
 	printk("\n");
@@ -359,9 +389,38 @@
 
 #include "../../scsi/NCR5380.c"
 
-#ifdef MODULE
+static Scsi_Host_Template cumanascsi_template = {
+	module:			THIS_MODULE,
+	name:			"Cumana 16-bit SCSI",
+	detect:			cumanascsi_detect,
+	release:		cumanascsi_release,
+	info:			cumanascsi_info,
+	queuecommand:		cumanascsi_queue_command,
+	abort:			cumanascsi_abort,
+	reset:			cumanascsi_reset,
+	bios_param:		scsicam_bios_param,
+	can_queue:		16,
+	this_id:		7,
+	sg_tablesize:		SG_ALL,
+	cmd_per_lun:		2,
+	unchecked_isa_dma:	0,
+	use_clustering:		DISABLE_CLUSTERING
+};
 
-Scsi_Host_Template driver_template = CUMANA_NCR5380;
+static int __init cumanascsi_init(void)
+{
+	scsi_register_module(MODULE_SCSI_HA, &cumanascsi_template);
+	if (cumanascsi_template.present)
+		return 0;
 
-#include "../../scsi/scsi_module.c"
-#endif
+	scsi_unregister_module(MODULE_SCSI_HA, &cumanascsi_template);
+	return -ENODEV;
+}
+
+static void __exit cumanascsi_exit(void)
+{
+	scsi_unregister_module(MODULE_SCSI_HA, &cumanascsi_template);
+}
+
+module_init(cumanascsi_init);
+module_exit(cumanascsi_exit);
diff -urN linux-2.4.2-pre1/drivers/acorn/scsi/cumana_1.h linux/drivers/acorn/scsi/cumana_1.h
--- linux-2.4.2-pre1/drivers/acorn/scsi/cumana_1.h	Sat Jul 18 11:55:24 1998
+++ linux/drivers/acorn/scsi/cumana_1.h	Wed Dec 31 16:00:00 1969
@@ -1,105 +0,0 @@
-/*
- * Cumana Generic NCR5380 driver defines
- *
- * Copyright 1993, Drew Eckhardt
- *	Visionary Computing
- *	(Unix and Linux consulting and custom programming)
- *	drew@colorado.edu
- *      +1 (303) 440-4894
- *
- * ALPHA RELEASE 1.
- *
- * For more information, please consult
- *
- * NCR 5380 Family
- * SCSI Protocol Controller
- * Databook
- *
- * NCR Microelectronics
- * 1635 Aeroplaza Drive
- * Colorado Springs, CO 80916
- * 1+ (719) 578-3400
- * 1+ (800) 334-5454
- */
-
-/*
- * $Log: cumana_1.h,v $
- * Revision 1.1  1998/02/23 02:45:22  davem
- * Merge to 2.1.88
- *
- */
-
-#ifndef CUMANA_NCR5380_H
-#define CUMANA_NCR5380_H
-
-#define CUMANASCSI_PUBLIC_RELEASE 1
-
-
-#ifndef ASM
-int cumanascsi_abort (Scsi_Cmnd *);
-int cumanascsi_detect (Scsi_Host_Template *);
-int cumanascsi_release (struct Scsi_Host *);
-const char *cumanascsi_info (struct Scsi_Host *);
-int cumanascsi_reset(Scsi_Cmnd *, unsigned int);
-int cumanascsi_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int cumanascsi_proc_info (char *buffer, char **start, off_t offset,
-			int length, int hostno, int inout);
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 2
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 16
-#endif
-
-#include <scsi/scsicam.h>
-
-#define CUMANA_NCR5380 {						\
-name:			"Cumana 16-bit SCSI",				\
-detect:			cumanascsi_detect,				\
-release:		cumanascsi_release,	/* Release */		\
-info:			cumanascsi_info,				\
-queuecommand:		cumanascsi_queue_command,			\
-abort:			cumanascsi_abort,			 	\
-reset:			cumanascsi_reset,				\
-bios_param:		scsicam_bios_param,	/* biosparam */		\
-can_queue:		CAN_QUEUE,		/* can queue */		\
-this_id:		7,			/* id */		\
-sg_tablesize:		SG_ALL,			/* sg_tablesize */	\
-cmd_per_lun:		CMD_PER_LUN,		/* cmd per lun */	\
-unchecked_isa_dma:	0,			/* unchecked_isa_dma */	\
-use_clustering:		DISABLE_CLUSTERING				\
-	}
-
-#ifndef HOSTS_C
-
-#define NCR5380_implementation_fields \
-    int port, ctrl
-
-#define NCR5380_local_declare() \
-        struct Scsi_Host *_instance
-
-#define NCR5380_setup(instance) \
-        _instance = instance
-
-#define NCR5380_read(reg) cumanascsi_read(_instance, reg)
-#define NCR5380_write(reg, value) cumanascsi_write(_instance, reg, value)
-
-#define do_NCR5380_intr do_cumanascsi_intr
-#define NCR5380_queue_command cumanascsi_queue_command
-#define NCR5380_abort cumanascsi_abort
-#define NCR5380_reset cumanascsi_reset
-#define NCR5380_proc_info cumanascsi_proc_info
-
-#define BOARD_NORMAL	0
-#define BOARD_NCR53C400	1
-
-#endif /* ndef HOSTS_C */
-#endif /* ndef ASM */
-#endif /* CUMANA_NCR5380_H */
-
diff -urN linux-2.4.2-pre1/drivers/acorn/scsi/cumana_2.c linux/drivers/acorn/scsi/cumana_2.c
--- linux-2.4.2-pre1/drivers/acorn/scsi/cumana_2.c	Mon Sep 18 15:15:22 2000
+++ linux/drivers/acorn/scsi/cumana_2.c	Mon Dec  3 22:27:48 2001
@@ -27,6 +27,7 @@
 #include <linux/stat.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
+#include <linux/init.h>
 
 #include <asm/dma.h>
 #include <asm/ecard.h>
@@ -36,7 +37,9 @@
 
 #include "../../scsi/sd.h"
 #include "../../scsi/hosts.h"
-#include "cumana_2.h"
+#include "fas216.h"
+
+#include <scsi/scsicam.h>
 
 /* Configuration */
 #define CUMANASCSI2_XTALFREQ		40
@@ -89,6 +92,22 @@
  */
 int term[MAX_ECARDS] = { 1, 1, 1, 1, 1, 1, 1, 1 };
 
+#define NR_SG	256
+
+typedef struct {
+	FAS216_Info info;
+
+	/* other info... */
+	unsigned int	status;		/* card status register	*/
+	unsigned int	alatch;		/* Control register	*/
+	unsigned int	terms;		/* Terminator state	*/
+	unsigned int	dmaarea;	/* Pseudo DMA area	*/
+	struct scatterlist sg[NR_SG];	/* Scatter DMA list	*/
+} CumanaScsi2_Info;
+
+#define CSTATUS_IRQ	(1 << 0)
+#define CSTATUS_DRQ	(1 << 1)
+
 /* Prototype: void cumanascsi_2_irqenable(ec, irqnr)
  * Purpose  : Enable interrupts on Cumana SCSI 2 card
  * Params   : ec    - expansion card structure
@@ -541,8 +560,42 @@
 	return pos;
 }
 
-#ifdef MODULE
-Scsi_Host_Template driver_template = CUMANASCSI_2;
+static Scsi_Host_Template cumanascsi2_template = {
+	module:				THIS_MODULE,
+	proc_info:			cumanascsi_2_proc_info,
+	name:				"Cumana SCSI II",
+	detect:				cumanascsi_2_detect,
+	release:			cumanascsi_2_release,
+	info:				cumanascsi_2_info,
+	bios_param:			scsicam_bios_param,
+	can_queue:			1,
+	this_id:			7,
+	sg_tablesize:			SG_ALL,
+	cmd_per_lun:			1,
+	use_clustering:			DISABLE_CLUSTERING,
+	command:			fas216_command,
+	queuecommand:			fas216_queue_command,
+	eh_host_reset_handler:		fas216_eh_host_reset,
+	eh_bus_reset_handler:		fas216_eh_bus_reset,
+	eh_device_reset_handler:	fas216_eh_device_reset,
+	eh_abort_handler:		fas216_eh_abort,
+	use_new_eh_code:		1
+};
 
-#include "../../scsi/scsi_module.c"
-#endif
+static int __init cumanascsi2_init(void)
+{
+	scsi_register_module(MODULE_SCSI_HA, &cumanascsi2_template);
+	if (cumanascsi2_template.present)
+		return 0;
+
+	scsi_unregister_module(MODULE_SCSI_HA, &cumanascsi2_template);
+	return -ENODEV;
+}
+
+static void __exit cumanascsi2_exit(void)
+{
+	scsi_unregister_module(MODULE_SCSI_HA, &cumanascsi2_template);
+}
+
+module_init(cumanascsi2_init);
+module_exit(cumanascsi2_exit);
diff -urN linux-2.4.2-pre1/drivers/acorn/scsi/cumana_2.h linux/drivers/acorn/scsi/cumana_2.h
--- linux-2.4.2-pre1/drivers/acorn/scsi/cumana_2.h	Mon Sep 18 15:15:22 2000
+++ linux/drivers/acorn/scsi/cumana_2.h	Wed Dec 31 16:00:00 1969
@@ -1,93 +0,0 @@
-/*
- *  linux/drivers/acorn/scsi/cumana_2.h
- *
- *  Copyright (C) 1997-2000 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- *  Cumana SCSI II driver
- */
-#ifndef CUMANA_2_H
-#define CUMANA_2_H
-
-extern int cumanascsi_2_detect (Scsi_Host_Template *);
-extern int cumanascsi_2_release (struct Scsi_Host *);
-extern const char *cumanascsi_2_info (struct Scsi_Host *);
-extern int cumanascsi_2_proc_info (char *buffer, char **start, off_t offset,
-					int length, int hostno, int inout);
-
-#ifndef NULL
-#define NULL ((void *)0)
-#endif
-
-#ifndef CAN_QUEUE
-/*
- * Default queue size
- */
-#define CAN_QUEUE	1
-#endif
-
-#ifndef CMD_PER_LUN
-/*
- * Default queue size
- */
-#define CMD_PER_LUN	1
-#endif
-
-#ifndef SCSI_ID
-/*
- * Default SCSI host ID
- */
-#define SCSI_ID		7
-#endif
-
-#include <scsi/scsicam.h>
-
-#include "fas216.h"
-
-#define CUMANASCSI_2 {					\
-proc_info:			cumanascsi_2_proc_info,	\
-name:				"Cumana SCSI II",	\
-detect:				cumanascsi_2_detect,	\
-release:			cumanascsi_2_release,	\
-info:				cumanascsi_2_info,	\
-bios_param:			scsicam_bios_param,	\
-can_queue:			CAN_QUEUE,		\
-this_id:			SCSI_ID,		\
-sg_tablesize:			SG_ALL,			\
-cmd_per_lun:			CMD_PER_LUN,		\
-use_clustering:			DISABLE_CLUSTERING,	\
-command:			fas216_command,		\
-queuecommand:			fas216_queue_command,	\
-eh_host_reset_handler:		fas216_eh_host_reset,	\
-eh_bus_reset_handler:		fas216_eh_bus_reset,	\
-eh_device_reset_handler:	fas216_eh_device_reset,	\
-eh_abort_handler:		fas216_eh_abort,	\
-use_new_eh_code:		1			\
-	}
-
-#ifndef HOSTS_C
-
-#include <asm/dma.h>
-
-#define NR_SG	256
-
-typedef struct {
-	FAS216_Info info;
-
-	/* other info... */
-	unsigned int	status;		/* card status register	*/
-	unsigned int	alatch;		/* Control register	*/
-	unsigned int	terms;		/* Terminator state	*/
-	unsigned int	dmaarea;	/* Pseudo DMA area	*/
-	struct scatterlist sg[NR_SG];	/* Scatter DMA list	*/
-} CumanaScsi2_Info;
-
-#define CSTATUS_IRQ	(1 << 0)
-#define CSTATUS_DRQ	(1 << 1)
-
-#endif /* HOSTS_C */
-
-#endif /* CUMANASCSI_2_H */
diff -urN linux-2.4.2-pre1/drivers/acorn/scsi/ecoscsi.c linux/drivers/acorn/scsi/ecoscsi.c
--- linux-2.4.2-pre1/drivers/acorn/scsi/ecoscsi.c	Thu Nov 11 16:57:30 1999
+++ linux/drivers/acorn/scsi/ecoscsi.c	Mon Dec  3 22:27:48 2001
@@ -53,10 +53,11 @@
 
 #include "../../scsi/scsi.h"
 #include "../../scsi/hosts.h"
-#include "ecoscsi.h"
 #include "../../scsi/NCR5380.h"
 #include "../../scsi/constants.h"
 
+#define ECOSCSI_PUBLIC_RELEASE 1
+
 static char ecoscsi_read(struct Scsi_Host *instance, int reg)
 {
   int iobase = instance->io_port;
@@ -231,11 +232,63 @@
 #endif
 #undef STAT
 
+#ifndef HOSTS_C
+#define NCR5380_implementation_fields \
+    int port, ctrl
+
+#define NCR5380_local_declare() \
+        struct Scsi_Host *_instance
+
+#define NCR5380_setup(instance) \
+        _instance = instance
+
+#define NCR5380_read(reg) ecoscsi_read(_instance, reg)
+#define NCR5380_write(reg, value) ecoscsi_write(_instance, reg, value)
+
+#define do_NCR5380_intr do_ecoscsi_intr
+#define NCR5380_queue_command ecoscsi_queue_command
+#define NCR5380_abort ecoscsi_abort
+#define NCR5380_reset ecoscsi_reset
+#define NCR5380_proc_info ecoscsi_proc_info
+
+int NCR5380_proc_info(char *buffer, char **start, off_t offset,
+		      int length, int hostno, int inout);
+
+#define BOARD_NORMAL	0
+#define BOARD_NCR53C400	1
+
 #include "../../scsi/NCR5380.c"
 
-#ifdef MODULE
+static Scsi_Host_Template ecoscsi_template =  {
+	module:		THIS_MODULE,
+	name:		"Serial Port EcoSCSI NCR5380",
+	detect:		ecoscsi_detect,
+	release:	ecoscsi_release,
+	info:		ecoscsi_info,
+	queuecommand:	ecoscsi_queue_command,
+	abort:		ecoscsi_abort,
+	reset:		ecoscsi_reset,
+	can_queue:	16,
+	this_id:	7,
+	sg_tablesize:	SG_ALL,
+	cmd_per_lun:	2,
+	use_clustering:	DISABLE_CLUSTERING
+};
+
+static int __init ecoscsi_init(void)
+{
+	scsi_register_module(MODULE_SCSI_HA, &ecoscsi_template);
+	if (ecoscsi_template.present)
+		return 0;
+
+	scsi_unregister_module(MODULE_SCSI_HA, &ecoscsi_template);
+	return -ENODEV;
+}
 
-Scsi_Host_Template driver_template = ECOSCSI_NCR5380;
+static void __exit ecoscsi_exit(void)
+{
+	scsi_unregister_module(MODULE_SCSI_HA, &ecoscsi_template);
+}
 
-#include "../../scsi/scsi_module.c"
-#endif
+module_init(ecoscsi_init);
+module_exit(ecoscsi_exit);
diff -urN linux-2.4.2-pre1/drivers/acorn/scsi/ecoscsi.h linux/drivers/acorn/scsi/ecoscsi.h
--- linux-2.4.2-pre1/drivers/acorn/scsi/ecoscsi.h	Sat Jul 18 11:55:24 1998
+++ linux/drivers/acorn/scsi/ecoscsi.h	Wed Dec 31 16:00:00 1969
@@ -1,96 +0,0 @@
-/*
- * Cumana Generic NCR5380 driver defines
- *
- * Copyright 1995, Russell King
- *
- * ALPHA RELEASE 1.
- *
- * For more information, please consult
- *
- * NCR 5380 Family
- * SCSI Protocol Controller
- * Databook
- *
- * NCR Microelectronics
- * 1635 Aeroplaza Drive
- * Colorado Springs, CO 80916
- * 1+ (719) 578-3400
- * 1+ (800) 334-5454
- */
-
-/*
- * $Log: ecoscsi.h,v $
- * Revision 1.1  1998/02/23 02:45:24  davem
- * Merge to 2.1.88
- *
- */
-
-#ifndef ECOSCSI_NCR5380_H
-#define ECOSCSI_NCR5380_H
-
-#define ECOSCSI_PUBLIC_RELEASE 1
-
-
-#ifndef ASM
-int ecoscsi_abort (Scsi_Cmnd *);
-int ecoscsi_detect (Scsi_Host_Template *);
-int ecoscsi_release (struct Scsi_Host *);
-const char *ecoscsi_info (struct Scsi_Host *);
-int ecoscsi_reset(Scsi_Cmnd *, unsigned int);
-int ecoscsi_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int ecoscsi_proc_info (char *buffer, char **start, off_t offset,
-			int length, int hostno, int inout);
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 2
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 16
-#endif
-
-#define ECOSCSI_NCR5380 {					\
-name:		"Serial Port EcoSCSI NCR5380",			\
-detect:		ecoscsi_detect,					\
-release:	ecoscsi_release,				\
-info:		ecoscsi_info,					\
-queuecommand:	ecoscsi_queue_command,				\
-abort:		ecoscsi_abort, 					\
-reset:		ecoscsi_reset,					\
-can_queue:	CAN_QUEUE,		/* can queue */		\
-this_id:	7,			/* id */		\
-sg_tablesize:	SG_ALL,						\
-cmd_per_lun:	CMD_PER_LUN,		/* cmd per lun */	\
-use_clustering:	DISABLE_CLUSTERING				\
-	}
-
-#ifndef HOSTS_C
-#define NCR5380_implementation_fields \
-    int port, ctrl
-
-#define NCR5380_local_declare() \
-        struct Scsi_Host *_instance
-
-#define NCR5380_setup(instance) \
-        _instance = instance
-
-#define NCR5380_read(reg) ecoscsi_read(_instance, reg)
-#define NCR5380_write(reg, value) ecoscsi_write(_instance, reg, value)
-
-#define do_NCR5380_intr do_ecoscsi_intr
-#define NCR5380_queue_command ecoscsi_queue_command
-#define NCR5380_abort ecoscsi_abort
-#define NCR5380_reset ecoscsi_reset
-#define NCR5380_proc_info ecoscsi_proc_info
-
-#define BOARD_NORMAL	0
-#define BOARD_NCR53C400	1
-
-#endif /* ndef HOSTS_C */
-#endif /* ndef ASM */
-#endif /* ECOSCSI_NCR5380_H */
-
diff -urN linux-2.4.2-pre1/drivers/acorn/scsi/eesox.c linux/drivers/acorn/scsi/eesox.c
--- linux-2.4.2-pre1/drivers/acorn/scsi/eesox.c	Mon Sep 18 15:15:22 2000
+++ linux/drivers/acorn/scsi/eesox.c	Mon Dec  3 22:27:48 2001
@@ -33,6 +33,7 @@
 #include <linux/stat.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
+#include <linux/init.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -42,7 +43,9 @@
 
 #include "../../scsi/sd.h"
 #include "../../scsi/hosts.h"
-#include "eesox.h"
+#include "fas216.h"
+
+#include <scsi/scsicam.h>
 
 /* Configuration */
 #define EESOX_XTALFREQ		40
@@ -87,6 +90,22 @@
  */
 int term[MAX_ECARDS] = { 1, 1, 1, 1, 1, 1, 1, 1 };
 
+#define NR_SG	256
+
+struct control {
+	unsigned int	io_port;
+	unsigned int	control;
+};
+
+typedef struct {
+	FAS216_Info info;
+
+	struct control control;
+
+	unsigned int	dmaarea;	/* Pseudo DMA area	*/
+	struct scatterlist sg[NR_SG];	/* Scatter DMA list	*/
+} EESOXScsi_Info;
+
 /* Prototype: void eesoxscsi_irqenable(ec, irqnr)
  * Purpose  : Enable interrupts on EESOX SCSI card
  * Params   : ec    - expansion card structure
@@ -543,8 +562,43 @@
 	return pos;
 }
 
-#ifdef MODULE
-Scsi_Host_Template driver_template = EESOXSCSI;
+static Scsi_Host_Template eesox_template = {
+	module:				THIS_MODULE,
+	proc_info:			eesoxscsi_proc_info,
+	name:				"EESOX SCSI",
+	detect:				eesoxscsi_detect,
+	release:			eesoxscsi_release,
+	info:				eesoxscsi_info,
+	bios_param:			scsicam_bios_param,
+	can_queue:			1,
+	this_id:			7,
+	sg_tablesize:			SG_ALL,
+	cmd_per_lun:			1,
+	use_clustering:			DISABLE_CLUSTERING,
+	command:			fas216_command,
+	queuecommand:			fas216_queue_command,
+	eh_host_reset_handler:		fas216_eh_host_reset,
+	eh_bus_reset_handler:		fas216_eh_bus_reset,
+	eh_device_reset_handler:	fas216_eh_device_reset,
+	eh_abort_handler:		fas216_eh_abort,
+	use_new_eh_code:		1
+};
+
+static int __init eesox_init(void)
+{
+	scsi_register_module(MODULE_SCSI_HA, &eesox_template);
+	if (eesox_template.present)
+		return 0;
+
+	scsi_unregister_module(MODULE_SCSI_HA, &eesox_template);
+	return -ENODEV;
+}
+
+static void __exit eesox_exit(void)
+{
+	scsi_unregister_module(MODULE_SCSI_HA, &eesox_template);
+}
+
+module_init(eesox_init);
+module_exit(eesox_exit);
 
-#include "../../scsi/scsi_module.c"
-#endif
diff -urN linux-2.4.2-pre1/drivers/acorn/scsi/eesox.h linux/drivers/acorn/scsi/eesox.h
--- linux-2.4.2-pre1/drivers/acorn/scsi/eesox.h	Mon Sep 18 15:15:22 2000
+++ linux/drivers/acorn/scsi/eesox.h	Wed Dec 31 16:00:00 1969
@@ -1,90 +0,0 @@
-/*
- *  linux/drivers/acorn/scsi/eesox.h
- *
- *  Copyright (C) 1997-2000 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- *  EESOX SCSI driver
- */
-#ifndef EESOXSCSI_H
-#define EESOXSCSI_H
-
-extern int eesoxscsi_detect (Scsi_Host_Template *);
-extern int eesoxscsi_release (struct Scsi_Host *);
-extern const char *eesoxscsi_info (struct Scsi_Host *);
-extern int eesoxscsi_proc_info (char *buffer, char **start, off_t offset,
-					int length, int hostno, int inout);
-
-#ifndef NULL
-#define NULL ((void *)0)
-#endif
-
-#ifndef CAN_QUEUE
-/*
- * Default queue size
- */
-#define CAN_QUEUE	1
-#endif
-
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN	1
-#endif
-
-#ifndef SCSI_ID
-/*
- * Default SCSI host ID
- */
-#define SCSI_ID		7
-#endif
-
-#include <scsi/scsicam.h>
-
-#include "fas216.h"
-
-#define EESOXSCSI {					\
-proc_info:			eesoxscsi_proc_info,	\
-name:				"EESOX SCSI",		\
-detect:				eesoxscsi_detect,	\
-release:			eesoxscsi_release,	\
-info:				eesoxscsi_info,		\
-bios_param:			scsicam_bios_param,	\
-can_queue:			CAN_QUEUE,		\
-this_id:			SCSI_ID,		\
-sg_tablesize:			SG_ALL,			\
-cmd_per_lun:			CAN_QUEUE,		\
-use_clustering:			DISABLE_CLUSTERING,	\
-command:			fas216_command,		\
-queuecommand:			fas216_queue_command,	\
-eh_host_reset_handler:		fas216_eh_host_reset,	\
-eh_bus_reset_handler:		fas216_eh_bus_reset,	\
-eh_device_reset_handler:	fas216_eh_device_reset,	\
-eh_abort_handler:		fas216_eh_abort,	\
-use_new_eh_code:		1			\
-	}
-
-#ifndef HOSTS_C
-
-#include <asm/dma.h>
-
-#define NR_SG	256
-
-struct control {
-	unsigned int	io_port;
-	unsigned int	control;
-};
-
-typedef struct {
-	FAS216_Info info;
-
-	struct control control;
-
-	unsigned int	dmaarea;	/* Pseudo DMA area	*/
-	struct scatterlist sg[NR_SG];	/* Scatter DMA list	*/
-} EESOXScsi_Info;
-
-#endif /* HOSTS_C */
-
-#endif /* EESOXSCSI_H */
diff -urN linux-2.4.2-pre1/drivers/acorn/scsi/fas216.c linux/drivers/acorn/scsi/fas216.c
--- linux-2.4.2-pre1/drivers/acorn/scsi/fas216.c	Mon Sep 18 15:15:22 2000
+++ linux/drivers/acorn/scsi/fas216.c	Mon Dec  3 22:27:48 2001
@@ -47,6 +47,7 @@
 #include <linux/unistd.h>
 #include <linux/stat.h>
 #include <linux/delay.h>
+#include <linux/init.h>
 
 #include <asm/dma.h>
 #include <asm/io.h>
@@ -2767,12 +2768,12 @@
 EXPORT_SYMBOL(fas216_print_device);
 
 #ifdef MODULE
-int init_module(void)
+int __init init_module(void)
 {
 	return 0;
 }
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
 }
 #endif
diff -urN linux-2.4.2-pre1/drivers/acorn/scsi/msgqueue.c linux/drivers/acorn/scsi/msgqueue.c
--- linux-2.4.2-pre1/drivers/acorn/scsi/msgqueue.c	Mon Sep 18 15:15:22 2000
+++ linux/drivers/acorn/scsi/msgqueue.c	Mon Dec  3 22:27:48 2001
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/stddef.h>
+#include <linux/init.h>
 
 #include "msgqueue.h"
 
@@ -128,7 +129,7 @@
 
 		va_start(ap, length);
 		for (i = 0; i < length; i++)
-			mq->msg.msg[i] = va_arg(ap, unsigned char);
+			mq->msg.msg[i] = va_arg(ap, unsigned int);
 		va_end(ap);
 
 		mq->msg.length = length;
@@ -169,12 +170,12 @@
 EXPORT_SYMBOL(msgqueue_flush);
 
 #ifdef MODULE
-int init_module(void)
+int __init init_module(void)
 {
 	return 0;
 }
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
 }
 #endif
diff -urN linux-2.4.2-pre1/drivers/acorn/scsi/oak.c linux/drivers/acorn/scsi/oak.c
--- linux-2.4.2-pre1/drivers/acorn/scsi/oak.c	Thu Nov 11 16:57:30 1999
+++ linux/drivers/acorn/scsi/oak.c	Mon Dec  3 22:27:48 2001
@@ -59,10 +59,35 @@
 
 #include "../../scsi/scsi.h"
 #include "../../scsi/hosts.h"
-#include "oak.h"
-#include "../../scsi/NCR5380.h"
 #include "../../scsi/constants.h"
 
+#define OAKSCSI_PUBLIC_RELEASE 1
+
+#define NCR5380_read(reg)		oakscsi_read(_instance, reg)
+#define NCR5380_write(reg, value)	oakscsi_write(_instance, reg, value)
+#define do_NCR5380_intr			do_oakscsi_intr
+#define NCR5380_queue_command		oakscsi_queue_command
+#define NCR5380_abort			oakscsi_abort
+#define NCR5380_reset			oakscsi_reset
+#define NCR5380_proc_info		oakscsi_proc_info
+
+int NCR5380_proc_info(char *buffer, char **start, off_t offset,
+		      int length, int hostno, int inout);
+
+#define NCR5380_implementation_fields \
+	int port, ctrl
+
+#define NCR5380_local_declare() \
+        struct Scsi_Host *_instance
+
+#define NCR5380_setup(instance) \
+        _instance = instance
+
+#define BOARD_NORMAL	0
+#define BOARD_NCR53C400	1
+
+#include "../../scsi/NCR5380.h"
+
 #undef START_DMA_INITIATOR_RECEIVE_REG
 #define START_DMA_INITIATOR_RECEIVE_REG (7 + 128)
 
@@ -129,7 +154,7 @@
 	else
 	    printk (" %d", instance->irq);
 	printk(" options CAN_QUEUE=%d  CMD_PER_LUN=%d release=%d",
-	    CAN_QUEUE, CMD_PER_LUN, OAKSCSI_PUBLIC_RELEASE);
+	    tpnt->can_queue, tpnt->cmd_per_lun, OAKSCSI_PUBLIC_RELEASE);
 	printk("\nscsi%d:", instance->host_no);
 	NCR5380_print_options(instance);
 	printk("\n");
@@ -226,9 +251,37 @@
 
 #include "../../scsi/NCR5380.c"
 
-#ifdef MODULE
+static Scsi_Host_Template oakscsi_template = {
+	module:		THIS_MODULE,
+	proc_info:	oakscsi_proc_info,
+	name:		"Oak 16-bit SCSI",
+	detect:		oakscsi_detect,
+	release:	oakscsi_release,
+	info:		oakscsi_info,
+	queuecommand:	oakscsi_queue_command,
+	abort:		oakscsi_abort,
+	reset:		oakscsi_reset,
+	can_queue:	16,
+	this_id:	7,
+	sg_tablesize:	SG_ALL,
+	cmd_per_lun:	2,
+	use_clustering:	DISABLE_CLUSTERING
+};
 
-Scsi_Host_Template driver_template = OAK_NCR5380;
+static int __init oakscsi_init(void)
+{
+	scsi_register_module(MODULE_SCSI_HA, &oakscsi_template);
+	if (oakscsi_template.present)
+		return 0;
 
-#include "../../scsi/scsi_module.c"
-#endif
+	scsi_unregister_module(MODULE_SCSI_HA, &oakscsi_template);
+	return -ENODEV;
+}
+
+static void __exit oakscsi_exit(void)
+{
+	scsi_unregister_module(MODULE_SCSI_HA, &oakscsi_template);
+}
+
+module_init(oakscsi_init);
+module_exit(oakscsi_exit);
diff -urN linux-2.4.2-pre1/drivers/acorn/scsi/oak.h linux/drivers/acorn/scsi/oak.h
--- linux-2.4.2-pre1/drivers/acorn/scsi/oak.h	Sat Jul 18 11:55:24 1998
+++ linux/drivers/acorn/scsi/oak.h	Wed Dec 31 16:00:00 1969
@@ -1,100 +0,0 @@
-/*
- * Cumana Generic NCR5380 driver defines
- *
- * Copyright 1993, Drew Eckhardt
- *	Visionary Computing
- *	(Unix and Linux consulting and custom programming)
- *	drew@colorado.edu
- *      +1 (303) 440-4894
- *
- * ALPHA RELEASE 1.
- *
- * For more information, please consult
- *
- * NCR 5380 Family
- * SCSI Protocol Controller
- * Databook
- *
- * NCR Microelectronics
- * 1635 Aeroplaza Drive
- * Colorado Springs, CO 80916
- * 1+ (719) 578-3400
- * 1+ (800) 334-5454
- */
-
-/*
- * $Log: oak.h,v $
- * Revision 1.1  1998/02/23 02:45:27  davem
- * Merge to 2.1.88
- *
- */
-
-#ifndef OAK_NCR5380_H
-#define OAK_NCR5380_H
-
-#define OAKSCSI_PUBLIC_RELEASE 1
-
-
-#ifndef ASM
-int oakscsi_abort(Scsi_Cmnd *);
-int oakscsi_detect(Scsi_Host_Template *);
-int oakscsi_release(struct Scsi_Host *);
-const char *oakscsi_info(struct Scsi_Host *);
-int oakscsi_reset(Scsi_Cmnd *, unsigned int);
-int oakscsi_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int oakscsi_proc_info (char *buffer, char **start, off_t off,
-		int length, int hostno, int inout);
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 2
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 16
-#endif
-
-#define OAK_NCR5380 {						\
-proc_info:	oakscsi_proc_info,				\
-name:		"Oak 16-bit SCSI",				\
-detect:		oakscsi_detect,					\
-release:	oakscsi_release,	/* Release */		\
-info:		oakscsi_info,					\
-queuecommand:	oakscsi_queue_command,				\
-abort:		oakscsi_abort, 					\
-reset:		oakscsi_reset,					\
-can_queue:	CAN_QUEUE,		/* can queue */		\
-this_id:	7,			/* id */		\
-sg_tablesize:	SG_ALL,			/* sg_tablesize */	\
-cmd_per_lun:	CMD_PER_LUN,		/* cmd per lun */	\
-use_clustering:	DISABLE_CLUSTERING				\
-	}
-
-#ifndef HOSTS_C
-#define NCR5380_implementation_fields \
-	int port, ctrl
-
-#define NCR5380_local_declare() \
-        struct Scsi_Host *_instance
-
-#define NCR5380_setup(instance) \
-        _instance = instance
-
-#define NCR5380_read(reg)		oakscsi_read(_instance, reg)
-#define NCR5380_write(reg, value)	oakscsi_write(_instance, reg, value)
-#define do_NCR5380_intr			do_oakscsi_intr
-#define NCR5380_queue_command		oakscsi_queue_command
-#define NCR5380_abort			oakscsi_abort
-#define NCR5380_reset			oakscsi_reset
-#define NCR5380_proc_info		oakscsi_proc_info
-
-#define BOARD_NORMAL	0
-#define BOARD_NCR53C400	1
-
-#endif /* else def HOSTS_C */
-#endif /* ndef ASM */
-#endif /* OAK_NCR5380_H */
-
diff -urN linux-2.4.2-pre1/drivers/acorn/scsi/powertec.c linux/drivers/acorn/scsi/powertec.c
--- linux-2.4.2-pre1/drivers/acorn/scsi/powertec.c	Mon Sep 18 15:15:22 2000
+++ linux/drivers/acorn/scsi/powertec.c	Mon Dec  3 22:27:48 2001
@@ -30,6 +30,7 @@
 #include <linux/stat.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
+#include <linux/init.h>
 
 #include <asm/dma.h>
 #include <asm/ecard.h>
@@ -39,7 +40,9 @@
 
 #include "../../scsi/sd.h"
 #include "../../scsi/hosts.h"
-#include "powertec.h"
+#include "fas216.h"
+
+#include <scsi/scsicam.h>
 
 /* Configuration */
 #define POWERTEC_XTALFREQ	40
@@ -86,6 +89,20 @@
  */
 int term[MAX_ECARDS] = { 1, 1, 1, 1, 1, 1, 1, 1 };
 
+#define NR_SG	256
+
+typedef struct {
+	FAS216_Info info;
+
+	struct {
+		unsigned int term_port;
+		unsigned int terms;
+	} control;
+
+	/* other info... */
+	struct scatterlist sg[NR_SG];	/* Scatter DMA list	*/
+} PowerTecScsi_Info;
+
 /* Prototype: void powertecscsi_irqenable(ec, irqnr)
  * Purpose  : Enable interrupts on Powertec SCSI card
  * Params   : ec    - expansion card structure
@@ -445,8 +462,42 @@
 	return pos;
 }
 
-#ifdef MODULE
-Scsi_Host_Template driver_template = POWERTECSCSI;
+static Scsi_Host_Template powertecscsi_template = {
+	module:				THIS_MODULE,
+	proc_info:			powertecscsi_proc_info,
+	name:				"PowerTec SCSI",
+	detect:				powertecscsi_detect,
+	release:			powertecscsi_release,
+	info:				powertecscsi_info,
+	bios_param:			scsicam_bios_param,
+	can_queue:			1,
+	this_id:			7,
+	sg_tablesize:			SG_ALL,
+	cmd_per_lun:			1,
+	use_clustering:			ENABLE_CLUSTERING,
+	command:			fas216_command,
+	queuecommand:			fas216_queue_command,
+	eh_host_reset_handler:		fas216_eh_host_reset,
+	eh_bus_reset_handler:		fas216_eh_bus_reset,
+	eh_device_reset_handler:	fas216_eh_device_reset,
+	eh_abort_handler:		fas216_eh_abort,
+	use_new_eh_code:		1
+};
+
+static int __init powertecscsi_init(void)
+{
+	scsi_register_module(MODULE_SCSI_HA, &powertecscsi_template);
+	if (powertecscsi_template.present)
+		return 0;
+
+	scsi_unregister_module(MODULE_SCSI_HA, &powertecscsi_template);
+	return -ENODEV;
+}
+
+static void __exit powertecscsi_exit(void)
+{
+	scsi_unregister_module(MODULE_SCSI_HA, &powertecscsi_template);
+}
 
-#include "../../scsi/scsi_module.c"
-#endif
+module_init(powertecscsi_init);
+module_exit(powertecscsi_exit);
diff -urN linux-2.4.2-pre1/drivers/acorn/scsi/powertec.h linux/drivers/acorn/scsi/powertec.h
--- linux-2.4.2-pre1/drivers/acorn/scsi/powertec.h	Mon Sep 18 15:15:22 2000
+++ linux/drivers/acorn/scsi/powertec.h	Wed Dec 31 16:00:00 1969
@@ -1,88 +0,0 @@
-/*
- *  linux/drivers/acorn/scsi/powertec.h
- *
- *  Copyright (C) 1997-2000 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- *  PowerTec SCSI driver
- */
-#ifndef POWERTECSCSI_H
-#define POWERTECSCSI_H
-
-extern int powertecscsi_detect (Scsi_Host_Template *);
-extern int powertecscsi_release (struct Scsi_Host *);
-extern const char *powertecscsi_info (struct Scsi_Host *);
-extern int powertecscsi_proc_info (char *buffer, char **start, off_t offset,
-					int length, int hostno, int inout);
-
-#ifndef NULL
-#define NULL ((void *)0)
-#endif
-
-#ifndef CAN_QUEUE
-/*
- * Default queue size
- */
-#define CAN_QUEUE	1
-#endif
-
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN	1
-#endif
-
-#ifndef SCSI_ID
-/*
- * Default SCSI host ID
- */
-#define SCSI_ID		7
-#endif
-
-#include <scsi/scsicam.h>
-
-#include "fas216.h"
-
-#define POWERTECSCSI {					\
-proc_info:			powertecscsi_proc_info,	\
-name:				"PowerTec SCSI",	\
-detect:				powertecscsi_detect,	\
-release:			powertecscsi_release,	\
-info:				powertecscsi_info,	\
-bios_param:			scsicam_bios_param,	\
-can_queue:			CAN_QUEUE,		\
-this_id:			SCSI_ID,		\
-sg_tablesize:			SG_ALL,			\
-cmd_per_lun:			CMD_PER_LUN,		\
-use_clustering:			ENABLE_CLUSTERING,	\
-command:			fas216_command,		\
-queuecommand:			fas216_queue_command,	\
-eh_host_reset_handler:		fas216_eh_host_reset,	\
-eh_bus_reset_handler:		fas216_eh_bus_reset,	\
-eh_device_reset_handler:	fas216_eh_device_reset,	\
-eh_abort_handler:		fas216_eh_abort,	\
-use_new_eh_code:		1			\
-	}
-
-#ifndef HOSTS_C
-
-#include <asm/dma.h>
-
-#define NR_SG	256
-
-typedef struct {
-	FAS216_Info info;
-
-	struct {
-		unsigned int term_port;
-		unsigned int terms;
-	} control;
-
-	/* other info... */
-	struct scatterlist sg[NR_SG];	/* Scatter DMA list	*/
-} PowerTecScsi_Info;
-
-#endif /* HOSTS_C */
-
-#endif /* POWERTECSCSI_H */
diff -urN linux-2.4.2-pre1/drivers/acorn/scsi/queue.c linux/drivers/acorn/scsi/queue.c
--- linux-2.4.2-pre1/drivers/acorn/scsi/queue.c	Mon Sep 18 15:15:22 2000
+++ linux/drivers/acorn/scsi/queue.c	Mon Dec  3 22:27:48 2001
@@ -21,6 +21,7 @@
 #include <linux/malloc.h>
 #include <linux/spinlock.h>
 #include <linux/list.h>
+#include <linux/init.h>
 
 #include "../../scsi/scsi.h"
 
@@ -295,12 +296,12 @@
 EXPORT_SYMBOL(queue_probetgtlun);
 
 #ifdef MODULE
-int init_module (void)
+int __init init_module (void)
 {
 	return 0;
 }
 
-void cleanup_module (void)
+void __exit cleanup_module (void)
 {
 }
 #endif
diff -urN linux-2.4.2-pre1/drivers/atm/fore200e.c linux/drivers/atm/fore200e.c
--- linux-2.4.2-pre1/drivers/atm/fore200e.c	Fri Dec 29 14:35:47 2000
+++ linux/drivers/atm/fore200e.c	Mon Dec  3 22:27:48 2001
@@ -2020,6 +2020,8 @@
     struct prom_data* prom = fore200e_kmalloc(sizeof(struct prom_data), GFP_KERNEL | GFP_DMA);
     int ok, i;
 
+    if (!prom)
+	return -ENOMEM;
     ok = fore200e->bus->prom_read(fore200e, prom);
     if (ok < 0)
 	return -EBUSY;
diff -urN linux-2.4.2-pre1/drivers/atm/iphase.c linux/drivers/atm/iphase.c
--- linux-2.4.2-pre1/drivers/atm/iphase.c	Fri Dec 29 14:35:47 2000
+++ linux/drivers/atm/iphase.c	Mon Dec  3 22:27:48 2001
@@ -6,7 +6,7 @@
 *******************************************************************************
       
       This software may be used and distributed according to the terms
-      of the GNU Public License (GPL), incorporated herein by reference.
+      of the GNU General Public License (GPL), incorporated herein by reference.
       Drivers based on this skeleton fall under the GPL and must retain
       the authorship (implicit copyright) notice.
 
@@ -78,8 +78,8 @@
 
 static unsigned char ia_phy_get(struct atm_dev *dev, unsigned long addr);
 
-static IADEV *ia_dev[8] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
-static struct atm_dev *_ia_dev[8] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
+static IADEV *ia_dev[8];
+static struct atm_dev *_ia_dev[8];
 static int iadev_count = 0;
 static void ia_led_timer(unsigned long arg);
 static struct timer_list ia_timer = { function: ia_led_timer };
@@ -951,7 +951,7 @@
                                   SUNI_PM7345_PLB);
 #ifdef __SNMP__
    suni_pm7345->suni_rxcp_intr_en_sts |= SUNI_OOCDE;
-#endif __SNMP__
+#endif /* __SNMP__ */
    return;
 }
 
@@ -2130,6 +2130,8 @@
 		memset((caddr_t)evc, 0, sizeof(struct ext_vc));  
                 iadev->testTable[i] = (struct testTable_t *)
                             kmalloc(sizeof(struct testTable_t), GFP_KERNEL);
+		if (!iadev->testTable[i])
+			return -ENOMEM;
               	iadev->testTable[i]->lastTime = 0;
  		iadev->testTable[i]->fract = 0;
                 iadev->testTable[i]->vc_status = VC_UBR;
@@ -2376,7 +2378,10 @@
 	  
 	/* lets try reading the MAC address */  
 	error = get_esi(dev);  
-	if (error) return error;  
+	if (error) {
+	  iounmap((void *) iadev->base);
+	  return error;  
+	}
         printk("IA: ");
 	for (i=0; i < ESI_LEN; i++)  
                 printk("%s%02X",i ? "-" : "",dev->esi[i]);  
@@ -2384,6 +2389,7 @@
   
         /* reset SAR */  
         if (reset_sar(dev)) {
+	   iounmap((void *) iadev->base);
            printk("IA: reset SAR fail, please try again\n");
            return 1;
         }
@@ -2869,8 +2875,11 @@
         iavcc = INPH_IA_VCC(vcc);
         if (!iavcc->txing) {
            printk("discard packet on closed VC\n");
-           if (vcc->pop) vcc->pop(vcc, skb);
-           else dev_kfree_skb_any(skb);
+           if (vcc->pop)
+		vcc->pop(vcc, skb);
+           else
+		dev_kfree_skb_any(skb);
+	   return 0;
         }
 
         if (skb->len > iadev->tx_buf_sz - 8) {
diff -urN linux-2.4.2-pre1/drivers/atm/iphase.h linux/drivers/atm/iphase.h
--- linux-2.4.2-pre1/drivers/atm/iphase.h	Mon Dec 11 13:22:09 2000
+++ linux/drivers/atm/iphase.h	Mon Dec  3 22:27:48 2001
@@ -7,7 +7,7 @@
 *******************************************************************************
       
       This software may be used and distributed according to the terms
-      of the GNU Public License (GPL), incorporated herein by reference.
+      of the GNU General Public License (GPL), incorporated herein by reference.
       Drivers based on this skeleton fall under the GPL and must retain
       the authorship (implicit copyright) notice.
 
diff -urN linux-2.4.2-pre1/drivers/atm/nicstar.c linux/drivers/atm/nicstar.c
--- linux-2.4.2-pre1/drivers/atm/nicstar.c	Fri Dec 29 14:35:47 2000
+++ linux/drivers/atm/nicstar.c	Mon Dec  3 22:27:48 2001
@@ -121,7 +121,7 @@
 #define ALIGN_ADDRESS(addr, alignment) \
         bus_to_virt(ALIGN_BUS_ADDR(virt_to_bus(addr), alignment))
 
-#undef CEIL(d)
+#undef CEIL
 
 #ifndef ATM_SKB
 #define ATM_SKB(s) (&(s)->atm)
diff -urN linux-2.4.2-pre1/drivers/block/cpqarray.c linux/drivers/block/cpqarray.c
--- linux-2.4.2-pre1/drivers/block/cpqarray.c	Sat Jan 20 08:51:40 2001
+++ linux/drivers/block/cpqarray.c	Mon Dec  3 22:27:48 2001
@@ -1327,7 +1327,7 @@
 	case IDA_WRITE_MEDIA:
 		kfree(p);
 		break;
-	default:
+	default:;
 		/* Nothing to do */
 	}
 
diff -urN linux-2.4.2-pre1/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
--- linux-2.4.2-pre1/drivers/block/ll_rw_blk.c	Mon Jan 29 12:11:32 2001
+++ linux/drivers/block/ll_rw_blk.c	Mon Dec  3 22:27:48 2001
@@ -590,10 +590,6 @@
 	 * inserted at elevator_merge time
 	 */
 	list_add(&req->queue, insert_here);
-
-	major = MAJOR(req->rq_dev);
-	if (major >= DAC960_MAJOR+0 && major <= DAC960_MAJOR+7)
-		q->request_fn(q);
 }
 
 void inline blk_refill_freelist(request_queue_t *q, int rw)
@@ -705,7 +701,7 @@
 {
 	unsigned int sector, count;
 	int max_segments = MAX_SEGMENTS;
-	struct request * req = NULL, *freereq = NULL;
+	struct request * req, *freereq = NULL;
 	int rw_ahead, max_sectors, el_ret;
 	struct list_head *head, *insert_here;
 	int latency;
@@ -751,6 +747,7 @@
 	max_sectors = get_max_sectors(bh->b_rdev);
 
 again:
+	req = NULL;
 	head = &q->queue_head;
 	/*
 	 * Now we acquire the request spinlock, we have to be mega careful
@@ -851,8 +848,6 @@
 out:
 	if (freereq)
 		blkdev_release_request(freereq);
-	if (!q->plugged)
-		q->request_fn(q);
 	spin_unlock_irq(&io_request_lock);
 	return 0;
 end_io:
diff -urN linux-2.4.2-pre1/drivers/block/loop.c linux/drivers/block/loop.c
--- linux-2.4.2-pre1/drivers/block/loop.c	Fri Dec 29 14:07:21 2000
+++ linux/drivers/block/loop.c	Mon Dec  3 22:27:48 2001
@@ -4,7 +4,7 @@
  *  Written by Theodore Ts'o, 3/29/93
  * 
  * Copyright 1993 by Theodore Ts'o.  Redistribution of this file is
- * permitted under the GNU Public License.
+ * permitted under the GNU General Public License.
  *
  * DES encryption plus some minor changes by Werner Almesberger, 30-MAY-1993
  * more DES encryption plus IDEA encryption by Nicholas J. Leon, June 20, 1996
diff -urN linux-2.4.2-pre1/drivers/block/paride/aten.c linux/drivers/block/paride/aten.c
--- linux-2.4.2-pre1/drivers/block/paride/aten.c	Thu Dec 16 13:57:04 1999
+++ linux/drivers/block/paride/aten.c	Mon Dec  3 22:27:48 2001
@@ -1,6 +1,6 @@
 /* 
         aten.c  (c) 1997-8  Grant R. Guenther <grant@torque.net>
-                            Under the terms of the GNU public license.
+                            Under the terms of the GNU General Public License.
 
 	aten.c is a low-level protocol driver for the ATEN EH-100
 	parallel port adapter.  The EH-100 supports 4-bit and 8-bit
diff -urN linux-2.4.2-pre1/drivers/block/paride/bpck.c linux/drivers/block/paride/bpck.c
--- linux-2.4.2-pre1/drivers/block/paride/bpck.c	Thu Dec 16 13:57:04 1999
+++ linux/drivers/block/paride/bpck.c	Mon Dec  3 22:27:48 2001
@@ -1,6 +1,6 @@
 /* 
 	bpck.c	(c) 1996-8  Grant R. Guenther <grant@torque.net>
-		            Under the terms of the GNU public license.
+		            Under the terms of the GNU General Public License.
 
 	bpck.c is a low-level protocol driver for the MicroSolutions 
 	"backpack" parallel port IDE adapter.  
diff -urN linux-2.4.2-pre1/drivers/block/paride/comm.c linux/drivers/block/paride/comm.c
--- linux-2.4.2-pre1/drivers/block/paride/comm.c	Thu Dec 16 13:57:04 1999
+++ linux/drivers/block/paride/comm.c	Mon Dec  3 22:27:48 2001
@@ -1,6 +1,6 @@
 /* 
         comm.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
-                              Under the terms of the GNU public license.
+                              Under the terms of the GNU General Public License.
 
 	comm.c is a low-level protocol driver for some older models
 	of the DataStor "Commuter" parallel to IDE adapter.  Some of
diff -urN linux-2.4.2-pre1/drivers/block/paride/dstr.c linux/drivers/block/paride/dstr.c
--- linux-2.4.2-pre1/drivers/block/paride/dstr.c	Thu Dec 16 13:57:04 1999
+++ linux/drivers/block/paride/dstr.c	Mon Dec  3 22:27:48 2001
@@ -1,6 +1,6 @@
 /* 
         dstr.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
-                              Under the terms of the GNU public license.
+                              Under the terms of the GNU General Public License.
 
         dstr.c is a low-level protocol driver for the 
         DataStor EP2000 parallel to IDE adapter chip.
diff -urN linux-2.4.2-pre1/drivers/block/paride/epat.c linux/drivers/block/paride/epat.c
--- linux-2.4.2-pre1/drivers/block/paride/epat.c	Thu Dec 16 13:57:04 1999
+++ linux/drivers/block/paride/epat.c	Mon Dec  3 22:27:48 2001
@@ -1,6 +1,6 @@
 /* 
         epat.c  (c) 1997-8  Grant R. Guenther <grant@torque.net>
-                            Under the terms of the GNU public license.
+                            Under the terms of the GNU General Public License.
 
 	This is the low level protocol driver for the EPAT parallel
         to IDE adapter from Shuttle Technologies.  This adapter is
diff -urN linux-2.4.2-pre1/drivers/block/paride/epia.c linux/drivers/block/paride/epia.c
--- linux-2.4.2-pre1/drivers/block/paride/epia.c	Thu Dec 16 13:57:04 1999
+++ linux/drivers/block/paride/epia.c	Mon Dec  3 22:27:48 2001
@@ -1,6 +1,6 @@
 /* 
         epia.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
-                              Under the terms of the GNU public license.
+                              Under the terms of the GNU General Public License.
 
         epia.c is a low-level protocol driver for Shuttle Technologies 
 	EPIA parallel to IDE adapter chip.  This device is now obsolete
diff -urN linux-2.4.2-pre1/drivers/block/paride/fit2.c linux/drivers/block/paride/fit2.c
--- linux-2.4.2-pre1/drivers/block/paride/fit2.c	Thu Dec 16 13:57:04 1999
+++ linux/drivers/block/paride/fit2.c	Mon Dec  3 22:27:48 2001
@@ -1,6 +1,6 @@
 /* 
         fit2.c        (c) 1998  Grant R. Guenther <grant@torque.net>
-                          Under the terms of the GNU public license.
+                          Under the terms of the GNU General Public License.
 
 	fit2.c is a low-level protocol driver for the older version
         of the Fidelity International Technology parallel port adapter.  
diff -urN linux-2.4.2-pre1/drivers/block/paride/fit3.c linux/drivers/block/paride/fit3.c
--- linux-2.4.2-pre1/drivers/block/paride/fit3.c	Thu Dec 16 13:57:04 1999
+++ linux/drivers/block/paride/fit3.c	Mon Dec  3 22:27:48 2001
@@ -1,6 +1,6 @@
 /* 
         fit3.c        (c) 1998  Grant R. Guenther <grant@torque.net>
-                          Under the terms of the GNU public license.
+                          Under the terms of the GNU General Public License.
 
 	fit3.c is a low-level protocol driver for newer models 
         of the Fidelity International Technology parallel port adapter.  
diff -urN linux-2.4.2-pre1/drivers/block/paride/friq.c linux/drivers/block/paride/friq.c
--- linux-2.4.2-pre1/drivers/block/paride/friq.c	Thu Dec 16 13:57:04 1999
+++ linux/drivers/block/paride/friq.c	Mon Dec  3 22:27:48 2001
@@ -1,6 +1,6 @@
 /* 
 	friq.c	(c) 1998    Grant R. Guenther <grant@torque.net>
-		            Under the terms of the GNU public license
+		            Under the terms of the GNU General Public License
 
 	friq.c is a low-level protocol driver for the Freecom "IQ"
 	parallel port IDE adapter.   Early versions of this adapter
diff -urN linux-2.4.2-pre1/drivers/block/paride/frpw.c linux/drivers/block/paride/frpw.c
--- linux-2.4.2-pre1/drivers/block/paride/frpw.c	Thu Dec 16 13:57:04 1999
+++ linux/drivers/block/paride/frpw.c	Mon Dec  3 22:27:48 2001
@@ -1,6 +1,6 @@
 /* 
 	frpw.c	(c) 1996-8  Grant R. Guenther <grant@torque.net>
-		            Under the terms of the GNU public license
+		            Under the terms of the GNU General Public License
 
 	frpw.c is a low-level protocol driver for the Freecom "Power"
 	parallel port IDE adapter.
diff -urN linux-2.4.2-pre1/drivers/block/paride/kbic.c linux/drivers/block/paride/kbic.c
--- linux-2.4.2-pre1/drivers/block/paride/kbic.c	Thu Dec 16 13:57:04 1999
+++ linux/drivers/block/paride/kbic.c	Mon Dec  3 22:27:48 2001
@@ -1,6 +1,6 @@
 /*
         kbic.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
-                              Under the terms of the GNU public license.
+                              Under the terms of the GNU General Public License.
 
         This is a low-level driver for the KBIC-951A and KBIC-971A
         parallel to IDE adapter chips from KingByte Information Systems.
diff -urN linux-2.4.2-pre1/drivers/block/paride/ktti.c linux/drivers/block/paride/ktti.c
--- linux-2.4.2-pre1/drivers/block/paride/ktti.c	Thu Dec 16 13:57:04 1999
+++ linux/drivers/block/paride/ktti.c	Mon Dec  3 22:27:48 2001
@@ -1,6 +1,6 @@
 /* 
         ktti.c        (c) 1998  Grant R. Guenther <grant@torque.net>
-                          Under the terms of the GNU public license.
+                          Under the terms of the GNU General Public License.
 
 	ktti.c is a low-level protocol driver for the KT Technology
 	parallel port adapter.  This adapter is used in the "PHd" 
diff -urN linux-2.4.2-pre1/drivers/block/paride/on20.c linux/drivers/block/paride/on20.c
--- linux-2.4.2-pre1/drivers/block/paride/on20.c	Thu Dec 16 13:57:04 1999
+++ linux/drivers/block/paride/on20.c	Mon Dec  3 22:27:48 2001
@@ -1,6 +1,6 @@
 /* 
 	on20.c	(c) 1996-8  Grant R. Guenther <grant@torque.net>
-		            Under the terms of the GNU public license.
+		            Under the terms of the GNU General Public License.
 
         on20.c is a low-level protocol driver for the
         Onspec 90c20 parallel to IDE adapter. 
diff -urN linux-2.4.2-pre1/drivers/block/paride/on26.c linux/drivers/block/paride/on26.c
--- linux-2.4.2-pre1/drivers/block/paride/on26.c	Wed May  3 01:45:18 2000
+++ linux/drivers/block/paride/on26.c	Mon Dec  3 22:27:48 2001
@@ -1,6 +1,6 @@
 /* 
         on26.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
-                              Under the terms of the GNU public license.
+                              Under the terms of the GNU General Public License.
 
         on26.c is a low-level protocol driver for the 
         OnSpec 90c26 parallel to IDE adapter chip.
diff -urN linux-2.4.2-pre1/drivers/block/paride/paride.c linux/drivers/block/paride/paride.c
--- linux-2.4.2-pre1/drivers/block/paride/paride.c	Wed Jul 12 16:24:33 2000
+++ linux/drivers/block/paride/paride.c	Mon Dec  3 22:27:48 2001
@@ -1,6 +1,6 @@
 /* 
         paride.c  (c) 1997-8  Grant R. Guenther <grant@torque.net>
-                              Under the terms of the GNU public license.
+                              Under the terms of the GNU General Public License.
 
 	This is the base module for the family of device drivers
         that support parallel port IDE devices.  
diff -urN linux-2.4.2-pre1/drivers/block/paride/pcd.c linux/drivers/block/paride/pcd.c
--- linux-2.4.2-pre1/drivers/block/paride/pcd.c	Thu Oct 26 23:35:47 2000
+++ linux/drivers/block/paride/pcd.c	Mon Dec  3 22:27:48 2001
@@ -1,6 +1,6 @@
 /* 
 	pcd.c	(c) 1997-8  Grant R. Guenther <grant@torque.net>
-		            Under the terms of the GNU public license.
+		            Under the terms of the GNU General Public License.
 
 	This is a high-level driver for parallel port ATAPI CD-ROM
         drives based on chips supported by the paride module.
diff -urN linux-2.4.2-pre1/drivers/block/paride/pd.c linux/drivers/block/paride/pd.c
--- linux-2.4.2-pre1/drivers/block/paride/pd.c	Mon Jan 15 13:08:15 2001
+++ linux/drivers/block/paride/pd.c	Mon Dec  3 22:27:48 2001
@@ -1,6 +1,6 @@
 /* 
         pd.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
-                            Under the terms of the GNU public license.
+                            Under the terms of the GNU General Public License.
 
         This is the high-level driver for parallel port IDE hard
         drives based on chips supported by the paride module.
diff -urN linux-2.4.2-pre1/drivers/block/paride/pf.c linux/drivers/block/paride/pf.c
--- linux-2.4.2-pre1/drivers/block/paride/pf.c	Mon Jan 15 13:08:15 2001
+++ linux/drivers/block/paride/pf.c	Mon Dec  3 22:27:48 2001
@@ -1,6 +1,6 @@
 /* 
         pf.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
-                            Under the terms of the GNU public license.
+                            Under the terms of the GNU General Public License.
 
         This is the high-level driver for parallel port ATAPI disk
         drives based on chips supported by the paride module.
diff -urN linux-2.4.2-pre1/drivers/block/paride/pg.c linux/drivers/block/paride/pg.c
--- linux-2.4.2-pre1/drivers/block/paride/pg.c	Mon Oct 16 12:58:51 2000
+++ linux/drivers/block/paride/pg.c	Mon Dec  3 22:27:48 2001
@@ -1,6 +1,6 @@
 /* 
 	pg.c    (c) 1998  Grant R. Guenther <grant@torque.net>
-			  Under the terms of the GNU public license.
+			  Under the terms of the GNU General Public License.
 
 	The pg driver provides a simple character device interface for
 	sending ATAPI commands to a device.  With the exception of the
diff -urN linux-2.4.2-pre1/drivers/block/paride/pseudo.h linux/drivers/block/paride/pseudo.h
--- linux-2.4.2-pre1/drivers/block/paride/pseudo.h	Mon Dec 11 12:58:14 2000
+++ linux/drivers/block/paride/pseudo.h	Mon Dec  3 22:27:48 2001
@@ -1,6 +1,6 @@
 /* 
         pseudo.h    (c) 1997-8  Grant R. Guenther <grant@torque.net>
-                                Under the terms of the GNU public license.
+                                Under the terms of the GNU General Public License.
 
 	This is the "pseudo-interrupt" logic for parallel port drivers.
 
diff -urN linux-2.4.2-pre1/drivers/block/paride/pt.c linux/drivers/block/paride/pt.c
--- linux-2.4.2-pre1/drivers/block/paride/pt.c	Mon Oct 16 12:58:51 2000
+++ linux/drivers/block/paride/pt.c	Mon Dec  3 22:27:48 2001
@@ -1,6 +1,6 @@
 /* 
         pt.c    (c) 1998  Grant R. Guenther <grant@torque.net>
-                          Under the terms of the GNU public license.
+                          Under the terms of the GNU General Public License.
 
         This is the high-level driver for parallel port ATAPI tape
         drives based on chips supported by the paride module.
diff -urN linux-2.4.2-pre1/drivers/block/paride/setup.h linux/drivers/block/paride/setup.h
--- linux-2.4.2-pre1/drivers/block/paride/setup.h	Mon Dec 11 12:50:10 2000
+++ linux/drivers/block/paride/setup.h	Mon Dec  3 22:27:48 2001
@@ -1,6 +1,6 @@
 /*
 	setup.h	   (c) 1997-8   Grant R. Guenther <grant@torque.net>
-		                Under the terms of the GNU public license.
+		                Under the terms of the GNU General Public License.
 
         This is a table driven setup function for kernel modules
         using the module.variable=val,... command line notation.
diff -urN linux-2.4.2-pre1/drivers/cdrom/cm206.c linux/drivers/cdrom/cm206.c
--- linux-2.4.2-pre1/drivers/cdrom/cm206.c	Thu Oct 26 23:35:47 2000
+++ linux/drivers/cdrom/cm206.c	Mon Dec  3 22:27:48 2001
@@ -1283,7 +1283,7 @@
   case 1: 
     kfree(cd);
     release_region(cm206_base, 16);
-  default:
+  default:;
   }
 }
 
diff -urN linux-2.4.2-pre1/drivers/cdrom/cm206.h linux/drivers/cdrom/cm206.h
--- linux-2.4.2-pre1/drivers/cdrom/cm206.h	Tue Dec  2 11:41:44 1997
+++ linux/drivers/cdrom/cm206.h	Mon Dec  3 22:27:48 2001
@@ -166,6 +166,6 @@
 #undef y
 #undef x
 
-#endif STATISTICS
+#endif /* STATISTICS */
 
-#endif LINUX_CM206_H
+#endif /* LINUX_CM206_H */
diff -urN linux-2.4.2-pre1/drivers/cdrom/mcd.c linux/drivers/cdrom/mcd.c
--- linux-2.4.2-pre1/drivers/cdrom/mcd.c	Thu Oct 26 23:35:47 2000
+++ linux/drivers/cdrom/mcd.c	Mon Dec  3 22:27:48 2001
@@ -1158,7 +1158,7 @@
       return;
     }
     blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-  default:
+  default:;
   }
 }
 
diff -urN linux-2.4.2-pre1/drivers/cdrom/optcd.c linux/drivers/cdrom/optcd.c
--- linux-2.4.2-pre1/drivers/cdrom/optcd.c	Thu Oct 26 23:35:48 2000
+++ linux/drivers/cdrom/optcd.c	Mon Dec  3 22:27:48 2001
@@ -924,7 +924,7 @@
 		return -EIO;
 	return 0;
 }
-#endif MULTISESSION
+#endif /* MULTISESSION */
 
 
 static int update_toc(void)
@@ -962,7 +962,7 @@
 #ifdef MULTISESSION
  	if (disk_info.xa)
 		get_multi_disk_info();	/* Here disk_info.multi is set */
-#endif MULTISESSION
+#endif /* MULTISESSION */
 	if (disk_info.multi)
 		printk(KERN_WARNING "optcd: Multisession support experimental, "
 			"see linux/Documentation/cdrom/optcd\n");
@@ -1709,11 +1709,11 @@
 			disk_info.last_session.minute,
 			disk_info.last_session.second,
 			disk_info.last_session.frame);
-#endif DEBUG_MULTIS
+#endif /* DEBUG_MULTIS */
 
 	return 0;
 }
-#endif MULTISESSION
+#endif /* MULTISESSION */
 
 
 static int cdromreset(void)
@@ -2026,7 +2026,7 @@
 
 __setup("optcd=", optcd_setup);
 
-#endif MODULE
+#endif /* MODULE */
 
 /* Test for presence of drive and initialize it. Called at boot time
    or during module initialisation. */
diff -urN linux-2.4.2-pre1/drivers/cdrom/optcd.h linux/drivers/cdrom/optcd.h
--- linux-2.4.2-pre1/drivers/cdrom/optcd.h	Tue Dec  2 11:41:44 1997
+++ linux/drivers/cdrom/optcd.h	Mon Dec  3 22:27:48 2001
@@ -49,4 +49,4 @@
 #define N_BUFS		6
 
 
-#endif _LINUX_OPTCD_H
+#endif /* _LINUX_OPTCD_H */
diff -urN linux-2.4.2-pre1/drivers/cdrom/sbpcd.c linux/drivers/cdrom/sbpcd.c
--- linux-2.4.2-pre1/drivers/cdrom/sbpcd.c	Thu Oct 26 23:35:48 2000
+++ linux/drivers/cdrom/sbpcd.c	Mon Dec  3 22:27:48 2001
@@ -322,6 +322,9 @@
  *		CD_AUDIO_COMPLETED state so workman (and other playes) can repeat play.
  *		Andrew J. Kroll <ag784@freenet.buffalo.edu> Wed Jul 26 04:24:10 EDT 2000
  *
+ *  4.64 Fix module parameters - were being completely ignored.
+ *	 Can also specify max_drives as 3rd setup int to get rid of
+ *	 "ghost" drives on crap hardware (aren't they all?)   Paul Gortmaker
  *
  *  TODO
  *     implement "read all subchannel data" (96 bytes per frame)
@@ -473,7 +476,7 @@
 #else
 static int sbpcd[] = {CDROM_PORT, SBPRO}; /* probe with user's setup only */
 #endif
-MODULE_PARM(sbpcd, "2i");
+MODULE_PARM(sbpcd, "3i");
 
 #define NUM_PROBE  (sizeof(sbpcd) / sizeof(int))
 
@@ -561,7 +564,6 @@
 
 static int sbpcd_ioaddr = CDROM_PORT;	/* default I/O base address */
 static int sbpro_type = SBPRO;
-static unsigned char setup_done;
 static unsigned char f_16bit;
 static unsigned char do_16bit;
 static int CDo_command, CDo_reset;
@@ -578,15 +580,19 @@
 static unsigned char msgnum;
 static char msgbuf[80];
 
-static const char *str_sb = "SoundBlaster";
+static int max_drives = MAX_DRIVES;
+#ifndef MODULE
+static unsigned char setup_done;
 static const char *str_sb_l = "soundblaster";
-static const char *str_lm = "LaserMate";
-static const char *str_sp = "SPEA";
 static const char *str_sp_l = "spea";
-static const char *str_ss = "SoundScape";
 static const char *str_ss_l = "soundscape";
-static const char *str_t16 = "Teac16bit";
 static const char *str_t16_l = "teac16bit";
+static const char *str_ss = "SoundScape";
+#endif
+static const char *str_sb = "SoundBlaster";
+static const char *str_lm = "LaserMate";
+static const char *str_sp = "SPEA";
+static const char *str_t16 = "Teac16bit";
 static const char *type;
 
 #if !(SBPCD_ISSUE-1)
@@ -3739,7 +3745,7 @@
 	
 	msg(DBG_INI,"check_drives entered.\n");
 	ndrives=0;
-	for (j=0;j<MAX_DRIVES;j++)
+	for (j=0;j<max_drives;j++)
 	{
 		D_S[ndrives].drv_id=j;
 		if (sbpro_type==1) D_S[ndrives].drv_sel=(j&0x01)<<1|(j&0x02)>>1;
@@ -5540,6 +5546,7 @@
 int sbpcd_setup(char *s)
 #endif
 {
+#ifndef MODULE
 	int p[4];
 	(void)get_options(s, ARRAY_SIZE(p), p);
 	setup_done++;
@@ -5555,6 +5562,12 @@
 	else if (!strcmp(s,str_t16)) sbpro_type=3;
 	else if (!strcmp(s,str_t16_l)) sbpro_type=3;
 	if (p[0]>0) sbpcd_ioaddr=p[1];
+	if (p[0]>2) max_drives=p[3];
+#else
+	sbpcd_ioaddr = sbpcd[0];
+	sbpro_type = sbpcd[1];
+	max_drives = sbpcd[2];
+#endif
 	
 	CDo_command=sbpcd_ioaddr;
 	CDi_info=sbpcd_ioaddr;
diff -urN linux-2.4.2-pre1/drivers/char/drm/Makefile linux/drivers/char/drm/Makefile
--- linux-2.4.2-pre1/drivers/char/drm/Makefile	Fri Jan 19 13:35:02 2001
+++ linux/drivers/char/drm/Makefile	Mon Dec  3 22:27:48 2001
@@ -10,7 +10,7 @@
 module-list     := gamma.o tdfx.o r128.o ffb.o mga.o i810.o
 export-objs     := $(patsubst %.o,%_drv.o,$(module-list))
 
-# libs-objs are included in every module so that radical changes to the
+# lib-objs are included in every module so that radical changes to the
 # architecture of the DRM support library can be made at a later time.
 #
 # The downside is that each module is larger, and a system that uses
diff -urN linux-2.4.2-pre1/drivers/char/ftape/lowlevel/fdc-isr.c linux/drivers/char/ftape/lowlevel/fdc-isr.c
--- linux-2.4.2-pre1/drivers/char/ftape/lowlevel/fdc-isr.c	Mon Oct 16 12:58:51 2000
+++ linux/drivers/char/ftape/lowlevel/fdc-isr.c	Mon Dec  3 22:27:48 2001
@@ -81,7 +81,7 @@
 	case overrun_error:
 		TRACE(ft_t_noise, "overrun error");
 		break;
-	default:
+	default:;
 	}
 	TRACE_EXIT;
 }
@@ -184,7 +184,7 @@
 	case no_data_error:
 		ft_history.no_data_errors++;
 		break;
-	default:
+	default:;
 	}
 }
 
diff -urN linux-2.4.2-pre1/drivers/char/lp.c linux/drivers/char/lp.c
--- linux-2.4.2-pre1/drivers/char/lp.c	Thu Oct 12 14:20:47 2000
+++ linux/drivers/char/lp.c	Mon Dec  3 22:27:48 2001
@@ -222,6 +222,21 @@
 	return error;
 }
 
+static int lp_wait_ready(int minor)
+{
+	int error = 0;
+	do {
+		error = lp_check_status (minor);
+		if (error && (LP_F(minor) & LP_ABORT))
+			break;
+		if (signal_pending (current)) {
+			error = -EINTR;
+			break;
+		}
+	} while (error);
+	return error;
+}
+
 static ssize_t lp_write(struct file * file, const char * buf,
 		        size_t count, loff_t *ppos)
 {
@@ -259,7 +274,7 @@
 	parport_set_timeout (lp_table[minor].dev,
 			     lp_table[minor].timeout);
 
-	if ((retv = lp_check_status (minor)) == 0)
+	if ((retv = lp_wait_ready (minor)) == 0)
 	do {
 		/* Write the data. */
 		written = parport_write (port, kbuf, copy_size);
@@ -279,9 +294,9 @@
 
 		if (copy_size > 0) {
 			/* incomplete write -> check error ! */
-			int error = lp_check_status (minor);
+			int error = lp_wait_ready (minor);
 
-			if (LP_F(minor) & LP_ABORT) {
+			if (error) {
 				if (retv == 0)
 					retv = error;
 				break;
diff -urN linux-2.4.2-pre1/drivers/char/mem.c linux/drivers/char/mem.c
--- linux-2.4.2-pre1/drivers/char/mem.c	Thu Jan  4 13:00:55 2001
+++ linux/drivers/char/mem.c	Mon Dec  3 22:27:48 2001
@@ -28,9 +28,6 @@
 #ifdef CONFIG_I2C
 extern int i2c_init_all(void);
 #endif
-#ifdef CONFIG_ISDN
-int isdn_init(void);
-#endif
 #ifdef CONFIG_VIDEO_DEV
 extern int videodev_init(void);
 #endif
@@ -157,9 +154,6 @@
 		prot = (prot & _CACHEMASK040) | _PAGE_NOCACHE_S;
 #elif defined(__mips__)
 	prot = (prot & ~_CACHE_MASK) | _CACHE_UNCACHED;
-#elif defined(__arm__) && defined(CONFIG_CPU_32)
-	/* Turn off caching for all I/O areas */
-	prot &= ~(L_PTE_CACHEABLE | L_PTE_BUFFERABLE);
 #endif
 
 	return __pgprot(prot);
@@ -643,9 +637,6 @@
 	misc_init();
 #if CONFIG_QIC02_TAPE
 	qic02_tape_init();
-#endif
-#if CONFIG_ISDN
-	isdn_init();
 #endif
 #ifdef CONFIG_FTAPE
 	ftape_init();
diff -urN linux-2.4.2-pre1/drivers/char/pc110pad.c linux/drivers/char/pc110pad.c
--- linux-2.4.2-pre1/drivers/char/pc110pad.c	Mon Oct 16 12:58:51 2000
+++ linux/drivers/char/pc110pad.c	Mon Dec  3 22:27:48 2001
@@ -42,6 +42,7 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/smp_lock.h>
+#include <linux/init.h>
 
 #include <asm/signal.h>
 #include <asm/io.h>
@@ -54,14 +55,13 @@
 
 
 static struct pc110pad_params default_params = {
-	PC110PAD_PS2,	/* read mode */
-	50 MS,		/* bounce interval */
-	200 MS,		/* tap interval */
-	10,		/* IRQ */
-	0x15E0,		/* I/O port */
+	mode:			PC110PAD_PS2,
+	bounce_interval:	50 MS,
+	tap_interval:		200 MS,
+	irq:			10,
+	io:			0x15E0,
 };
 
-
 static struct pc110pad_params current_params;
 
 
@@ -134,7 +134,7 @@
 {
 	if(!recent_transition)
 	{
-		printk("pc110pad: tap_timeout but no recent transition!\n");
+		printk(KERN_ERR "pc110pad: tap_timeout but no recent transition!\n");
 	}
 	if( transition_count==2 || transition_count==4 || transition_count==6 )
 	{
@@ -783,73 +783,60 @@
 
 
 static struct miscdevice pc110_pad = {
-	PC110PAD_MINOR, "pc110 pad", &pad_fops
+	minor:		PC110PAD_MINOR,
+	name:		"pc110 pad",
+	fops:		&pad_fops,
 };
 
 
 /**
- *	pc110pad_init:
+ *	pc110pad_init_driver:
  *
  *	We configure the pad with the default parameters (that is PS/2 
  *	emulation mode. We then claim the needed I/O and interrupt resources.
  *	Finally as a matter of paranoia we turn the pad off until we are
  *	asked to open it by an application.
  */
- 
-int pc110pad_init(void)
+
+static const char banner[] __initdata = KERN_INFO "PC110 digitizer pad at 0x%X, irq %d.\n";
+
+static int __init pc110pad_init_driver(void)
 {
+	init_MUTEX(&reader_lock);
 	current_params = default_params;
 
-	if(request_irq(current_params.irq, pad_irq, 0, "pc110pad", 0))
-	{
-		printk("pc110pad: Unable to get IRQ.\n");
+	if (request_irq(current_params.irq, pad_irq, 0, "pc110pad", 0)) {
+		printk(KERN_ERR "pc110pad: Unable to get IRQ.\n");
 		return -EBUSY;
 	}
-	if(check_region(current_params.io, 4))
-	{
-		printk("pc110pad: I/O area in use.\n");
+	if (!request_region(current_params.io, 4, "pc110pad"))	{
+		printk(KERN_ERR "pc110pad: I/O area in use.\n");
 		free_irq(current_params.irq,0);
 		return -EBUSY;
 	}
-	request_region(current_params.io, 4, "pc110pad");
 	init_waitqueue_head(&queue);
-	printk("PC110 digitizer pad at 0x%X, irq %d.\n",
-		current_params.io,current_params.irq);
+	printk(banner, current_params.io, current_params.irq);
 	misc_register(&pc110_pad);
 	outb(0x30, current_params.io+2);	/* switch off digitiser */
-	
 	return 0;
 }
 
-#ifdef MODULE
-
-/**
- *	pc110pad_unload:
+/*
+ *	pc110pad_exit_driver:
  *
  *	Free the resources we acquired when the module was loaded. We also
  *	turn the pad off to be sure we don't leave it using power.
  */
- 
-static void pc110pad_unload(void)
+
+static void __exit pc110pad_exit_driver(void)
 {
 	outb(0x30, current_params.io+2);	/* switch off digitiser */
-	if(current_params.irq)
+	if (current_params.irq)
 		free_irq(current_params.irq, 0);
-	current_params.irq=0;
+	current_params.irq = 0;
 	release_region(current_params.io, 4);
 	misc_deregister(&pc110_pad);
 }
 
-
-
-int init_module(void)
-{
-	init_MUTEX(&reader_lock);
-	return pc110pad_init();
-}
-
-void cleanup_module(void)
-{
-	pc110pad_unload();
-}
-#endif
+module_init(pc110pad_init_driver);
+module_exit(pc110pad_exit_driver);
diff -urN linux-2.4.2-pre1/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
--- linux-2.4.2-pre1/drivers/ide/ide-disk.c	Thu Oct 26 23:35:48 2000
+++ linux/drivers/ide/ide-disk.c	Mon Dec  3 22:27:48 2001
@@ -223,67 +223,53 @@
  * ide_multwrite() transfers a block of up to mcount sectors of data
  * to a drive as part of a disk multiple-sector write operation.
  *
- * Returns 0 if successful;  returns 1 if request had to be aborted due to corrupted buffer list.
+ * Returns 0 on success.
+ *
+ * Note that we may be called from two contexts - the do_rw_disk context
+ * and IRQ context. The IRQ can happen any time after we've output the
+ * full "mcount" number of sectors, so we must make sure we update the
+ * state _before_ we output the final part of the data!
  */
 int ide_multwrite (ide_drive_t *drive, unsigned int mcount)
 {
  	ide_hwgroup_t	*hwgroup= HWGROUP(drive);
-
-	/*
-	 *	This may look a bit odd, but remember wrq is a copy of the
-	 *	request not the original. The pointers are real however so the
-	 *	bh's are not copies. Remember that or bad stuff will happen
-	 *
-	 *	At the point we are called the drive has asked us for the
-	 *	data, and its our job to feed it, walking across bh boundaries
-	 *	if need be.
-	 */
-
  	struct request	*rq = &hwgroup->wrq;
-
+ 
   	do {
- 		unsigned long flags;
-  		unsigned int nsect = rq->current_nr_sectors;
+  		char *buffer;
+  		int nsect = rq->current_nr_sectors;
+ 
 		if (nsect > mcount)
 			nsect = mcount;
 		mcount -= nsect;
+		buffer = rq->buffer;
 
-		idedisk_output_data(drive, rq->buffer, nsect<<7);
-#ifdef DEBUG
-		printk("%s: multwrite: sector %ld, buffer=0x%08lx, count=%d, remaining=%ld\n",
-			drive->name, rq->sector, (unsigned long) rq->buffer,
-			nsect, rq->nr_sectors - nsect);
-#endif
-		spin_lock_irqsave(&io_request_lock, flags);	/* Is this really necessary? */
-#ifdef CONFIG_BLK_DEV_PDC4030
 		rq->sector += nsect;
-#endif
-		if (((long)(rq->nr_sectors -= nsect)) <= 0) {
-#ifdef DEBUG
-			printk("%s: multwrite: count=%d, current=%ld\n",
-				drive->name, nsect, rq->nr_sectors);
-#endif
-			spin_unlock_irqrestore(&io_request_lock, flags);
-			break;
-		}
-		if ((rq->current_nr_sectors -= nsect) == 0) {
-			if ((rq->bh = rq->bh->b_reqnext) != NULL) {
-				rq->current_nr_sectors = rq->bh->b_size>>9;
-				rq->buffer             = rq->bh->b_data;
+		rq->buffer += nsect << 9;
+		rq->nr_sectors -= nsect;
+		rq->current_nr_sectors -= nsect;
+
+		/* Do we move to the next bh after this? */
+		if (!rq->current_nr_sectors) {
+			struct buffer_head *bh = rq->bh->b_reqnext;
+
+			/* end early early we ran out of requests */
+			if (!bh) {
+				mcount = 0;
 			} else {
-				spin_unlock_irqrestore(&io_request_lock, flags);
-				printk("%s: buffer list corrupted (%ld, %ld, %d)\n",
-					drive->name, rq->current_nr_sectors,
-					rq->nr_sectors, nsect);
-				ide_end_request(0, hwgroup);
-				return 1;
+				rq->bh = bh;
+				rq->current_nr_sectors = bh->b_size >> 9;
+				rq->buffer             = bh->b_data;
 			}
-		} else {
-			/* Fix the pointer.. we ate data */
-			rq->buffer += nsect << 9;
 		}
-                spin_unlock_irqrestore(&io_request_lock, flags);
+
+		/*
+		 * Ok, we're all setup for the interrupt
+		 * re-entering us on the last transfer.
+		 */
+		idedisk_output_data(drive, buffer, nsect<<7);
 	} while (mcount);
+
         return 0;
 }
 
diff -urN linux-2.4.2-pre1/drivers/ide/ide-probe.c linux/drivers/ide/ide-probe.c
--- linux-2.4.2-pre1/drivers/ide/ide-probe.c	Mon Jan 15 13:08:15 2001
+++ linux/drivers/ide/ide-probe.c	Mon Dec  3 22:27:48 2001
@@ -652,6 +652,8 @@
 		hwgroup = match->hwgroup;
 	} else {
 		hwgroup = kmalloc(sizeof(ide_hwgroup_t), GFP_KERNEL);
+		if (!hwgroup)
+			return 1;
 		memset(hwgroup, 0, sizeof(ide_hwgroup_t));
 		hwgroup->hwif     = hwif->next = hwif;
 		hwgroup->rq       = NULL;
diff -urN linux-2.4.2-pre1/drivers/ide/osb4.c linux/drivers/ide/osb4.c
--- linux-2.4.2-pre1/drivers/ide/osb4.c	Tue Jan  2 16:58:45 2001
+++ linux/drivers/ide/osb4.c	Mon Dec  3 22:27:48 2001
@@ -46,8 +46,8 @@
 #include <linux/hdreg.h>
 #include <linux/ide.h>
 #include <linux/init.h>
+#include <linux/delay.h>
 
-#include <asm/delay.h>
 #include <asm/io.h>
 
 #include "ide_modes.h"
diff -urN linux-2.4.2-pre1/drivers/ieee1394/guid.c linux/drivers/ieee1394/guid.c
--- linux-2.4.2-pre1/drivers/ieee1394/guid.c	Mon Dec 11 12:39:44 2000
+++ linux/drivers/ieee1394/guid.c	Mon Dec  3 22:27:48 2001
@@ -163,7 +163,7 @@
                         return;
                 }
 
-                INIT_LIST_HEAD(&greq->tq.list);
+                INIT_TQ_LINK(greq->tq);
                 greq->tq.sync = 0;
                 greq->tq.routine = (void (*)(void*))pkt_complete;
                 greq->tq.data = greq;
diff -urN linux-2.4.2-pre1/drivers/ieee1394/hosts.c linux/drivers/ieee1394/hosts.c
--- linux-2.4.2-pre1/drivers/ieee1394/hosts.c	Sun Oct  1 19:53:07 2000
+++ linux/drivers/ieee1394/hosts.c	Mon Dec  3 22:27:48 2001
@@ -106,6 +106,7 @@
         sema_init(&h->tlabel_count, 64);
         spin_lock_init(&h->tlabel_lock);
 
+        INIT_TQ_LINK(h->timeout_tq);
         h->timeout_tq.routine = (void (*)(void*))abort_timedouts;
         h->timeout_tq.data = h;
 
diff -urN linux-2.4.2-pre1/drivers/ieee1394/ieee1394_core.c linux/drivers/ieee1394/ieee1394_core.c
--- linux-2.4.2-pre1/drivers/ieee1394/ieee1394_core.c	Sun Oct  1 19:53:07 2000
+++ linux/drivers/ieee1394/ieee1394_core.c	Mon Dec  3 22:27:48 2001
@@ -98,6 +98,7 @@
                 packet->data_size = data_size;
         }
 
+        INIT_TQ_HEAD(packet->complete_tq);
         INIT_LIST_HEAD(&packet->list);
         sema_init(&packet->state_change, 0);
         packet->state = unused;
diff -urN linux-2.4.2-pre1/drivers/ieee1394/ieee1394_types.h linux/drivers/ieee1394/ieee1394_types.h
--- linux-2.4.2-pre1/drivers/ieee1394/ieee1394_types.h	Mon Dec 11 13:20:17 2000
+++ linux/drivers/ieee1394/ieee1394_types.h	Mon Dec  3 22:27:48 2001
@@ -15,6 +15,9 @@
 #define V22_COMPAT_MOD_INC_USE_COUNT do {} while (0)
 #define V22_COMPAT_MOD_DEC_USE_COUNT do {} while (0)
 #define OWNER_THIS_MODULE owner: THIS_MODULE,
+
+#define INIT_TQ_LINK(tq) INIT_LIST_HEAD(&(tq).list)
+#define INIT_TQ_HEAD(tq) INIT_LIST_HEAD(&(tq))
 #endif
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18)
diff -urN linux-2.4.2-pre1/drivers/ieee1394/ohci1394.c linux/drivers/ieee1394/ohci1394.c
--- linux-2.4.2-pre1/drivers/ieee1394/ohci1394.c	Tue Jan  2 16:45:38 2001
+++ linux/drivers/ieee1394/ohci1394.c	Mon Dec  3 22:27:48 2001
@@ -97,6 +97,81 @@
 #include "ieee1394_core.h"
 #include "ohci1394.h"
 
+
+/* This structure is not properly initialized ... it is taken from
+   the lynx_csr_rom written by Andreas ... Some fields in the root
+   directory and the module dependent info needs to be modified
+   I do not have the proper doc */
+quadlet_t ohci_csr_rom[] = {
+        /* bus info block */
+        0x04040000, /* info/CRC length, CRC */
+        0x31333934, /* 1394 magic number */
+        0xf07da002, /* cyc_clk_acc = 125us, max_rec = 1024 */
+        0x00000000, /* vendor ID, chip ID high (written from card info) */
+        0x00000000, /* chip ID low (written from card info) */
+        /* root directory - FIXME */
+        0x00090000, /* CRC length, CRC */
+        0x03080028, /* vendor ID (Texas Instr.) */
+        0x81000009, /* offset to textual ID */
+        0x0c000200, /* node capabilities */
+        0x8d00000e, /* offset to unique ID */
+        0xc7000010, /* offset to module independent info */
+        0x04000000, /* module hardware version */
+        0x81000026, /* offset to textual ID */
+        0x09000000, /* node hardware version */
+        0x81000026, /* offset to textual ID */
+        /* module vendor ID textual */
+        0x00080000, /* CRC length, CRC */
+        0x00000000,
+        0x00000000,
+        0x54455841, /* "Texas Instruments" */
+        0x5320494e,
+        0x53545255,
+        0x4d454e54,
+        0x53000000,
+        /* node unique ID leaf */
+        0x00020000, /* CRC length, CRC */
+        0x08002856, /* vendor ID, chip ID high */
+        0x0000083E, /* chip ID low */
+        /* module dependent info - FIXME */
+        0x00060000, /* CRC length, CRC */
+        0xb8000006, /* ??? offset to module textual ID */
+        0x81000004, /* ??? textual descriptor */
+        0x00000000, /* SRAM size */
+        0x00000000, /* AUXRAM size */
+        0x00000000, /* AUX device */
+        /* module textual ID */
+        0x00050000, /* CRC length, CRC */
+        0x00000000,
+        0x00000000,
+        0x54534231, /* "TSB12LV22" */
+        0x324c5632,
+        0x32000000,
+        /* part number */
+        0x00060000, /* CRC length, CRC */
+        0x00000000,
+        0x00000000,
+        0x39383036, /* "9806000-0001" */
+        0x3030342d,
+        0x30303431,
+        0x20000001,
+        /* module hardware version textual */
+        0x00050000, /* CRC length, CRC */
+        0x00000000,
+        0x00000000,
+        0x5453424b, /* "TSBKOHCI403" */
+        0x4f484349,
+        0x34303300,
+        /* node hardware version textual */
+        0x00050000, /* CRC length, CRC */
+        0x00000000,
+        0x00000000,
+        0x54534234, /* "TSB41LV03" */
+        0x314c5630,
+        0x33000000
+};
+
+
 #ifdef CONFIG_IEEE1394_VERBOSEDEBUG
 #define OHCI1394_DEBUG
 #endif
@@ -1641,7 +1716,7 @@
 
         /* initialize bottom handler */
         d->task.sync = 0;
-        INIT_LIST_HEAD(&d->task.list);
+        INIT_TQ_LINK(d->task);
         d->task.routine = dma_rcv_bh;
         d->task.data = (void*)d;
 
@@ -1730,6 +1805,7 @@
         spin_lock_init(&d->lock);
 
         /* initialize bottom handler */
+        INIT_TQ_LINK(d->task);
         d->task.routine = dma_trm_bh;
         d->task.data = (void*)d;
 
diff -urN linux-2.4.2-pre1/drivers/ieee1394/ohci1394.h linux/drivers/ieee1394/ohci1394.h
--- linux-2.4.2-pre1/drivers/ieee1394/ohci1394.h	Tue Jan  2 16:45:38 2001
+++ linux/drivers/ieee1394/ohci1394.h	Mon Dec  3 22:27:48 2001
@@ -276,79 +276,6 @@
         return readl(ohci->registers + offset);
 }
 
-/* This structure is not properly initialized ... it is taken from
-   the lynx_csr_rom written by Andreas ... Some fields in the root
-   directory and the module dependent info needs to be modified
-   I do not have the proper doc */
-quadlet_t ohci_csr_rom[] = {
-        /* bus info block */
-        0x04040000, /* info/CRC length, CRC */
-        0x31333934, /* 1394 magic number */
-        0xf07da002, /* cyc_clk_acc = 125us, max_rec = 1024 */
-        0x00000000, /* vendor ID, chip ID high (written from card info) */
-        0x00000000, /* chip ID low (written from card info) */
-        /* root directory - FIXME */
-        0x00090000, /* CRC length, CRC */
-        0x03080028, /* vendor ID (Texas Instr.) */
-        0x81000009, /* offset to textual ID */
-        0x0c000200, /* node capabilities */
-        0x8d00000e, /* offset to unique ID */
-        0xc7000010, /* offset to module independent info */
-        0x04000000, /* module hardware version */
-        0x81000026, /* offset to textual ID */
-        0x09000000, /* node hardware version */
-        0x81000026, /* offset to textual ID */
-        /* module vendor ID textual */
-        0x00080000, /* CRC length, CRC */
-        0x00000000,
-        0x00000000,
-        0x54455841, /* "Texas Instruments" */
-        0x5320494e,
-        0x53545255,
-        0x4d454e54,
-        0x53000000,
-        /* node unique ID leaf */
-        0x00020000, /* CRC length, CRC */
-        0x08002856, /* vendor ID, chip ID high */
-        0x0000083E, /* chip ID low */
-        /* module dependent info - FIXME */
-        0x00060000, /* CRC length, CRC */
-        0xb8000006, /* ??? offset to module textual ID */
-        0x81000004, /* ??? textual descriptor */
-        0x00000000, /* SRAM size */
-        0x00000000, /* AUXRAM size */
-        0x00000000, /* AUX device */
-        /* module textual ID */
-        0x00050000, /* CRC length, CRC */
-        0x00000000,
-        0x00000000,
-        0x54534231, /* "TSB12LV22" */
-        0x324c5632,
-        0x32000000,
-        /* part number */
-        0x00060000, /* CRC length, CRC */
-        0x00000000,
-        0x00000000,
-        0x39383036, /* "9806000-0001" */
-        0x3030342d,
-        0x30303431,
-        0x20000001,
-        /* module hardware version textual */
-        0x00050000, /* CRC length, CRC */
-        0x00000000,
-        0x00000000,
-        0x5453424b, /* "TSBKOHCI403" */
-        0x4f484349,
-        0x34303300,
-        /* node hardware version textual */
-        0x00050000, /* CRC length, CRC */
-        0x00000000,
-        0x00000000,
-        0x54534234, /* "TSB41LV03" */
-        0x314c5630,
-        0x33000000
-};
-
 
 /* 2 KiloBytes of register space */
 #define OHCI1394_REGISTER_SIZE                0x800       
diff -urN linux-2.4.2-pre1/drivers/ieee1394/pcilynx.c linux/drivers/ieee1394/pcilynx.c
--- linux-2.4.2-pre1/drivers/ieee1394/pcilynx.c	Tue Nov 28 21:45:16 2000
+++ linux/drivers/ieee1394/pcilynx.c	Mon Dec  3 22:27:48 2001
@@ -289,7 +289,8 @@
         char phyreg[7];
         int i;
 
-        for (i = 0; i < 7; i++) {
+        phyreg[0] = lynx->phy_reg0;
+        for (i = 1; i < 7; i++) {
                 phyreg[i] = get_phy_reg(lynx, i);
         }
 
@@ -317,13 +318,18 @@
         return lsid;
 }
 
-static void handle_selfid(struct ti_lynx *lynx, struct hpsb_host *host, size_t size)
+static void handle_selfid(struct ti_lynx *lynx, struct hpsb_host *host)
 {
         quadlet_t *q = lynx->rcv_page;
-        int phyid, isroot;
+        int phyid, isroot, size;
         quadlet_t lsid = 0;
         int i;
 
+        if (lynx->phy_reg0 == -1 || lynx->selfid_size == -1) return;
+
+        size = lynx->selfid_size;
+        phyid = lynx->phy_reg0;
+
         i = (size > 16 ? 16 : size) / 4 - 1;
         while (i >= 0) {
                 cpu_to_be32s(&q[i]);
@@ -334,7 +340,6 @@
                 lsid = generate_own_selfid(lynx, host);
         }
 
-        phyid = get_phy_reg(lynx, 0);
         isroot = (phyid & 2) != 0;
         phyid >>= 2;
         PRINT(KERN_INFO, lynx->id, "SelfID process finished (phyid %d, %s)",
@@ -369,9 +374,14 @@
                 hpsb_selfid_received(host, lsid);
         }
 
-        if (isroot) reg_set_bits(lynx, LINK_CONTROL, LINK_CONTROL_CYCMASTER);
-
         hpsb_selfid_complete(host, phyid, isroot);
+
+        if (host->in_bus_reset) return;
+
+        if (isroot) reg_set_bits(lynx, LINK_CONTROL, LINK_CONTROL_CYCMASTER);
+        reg_set_bits(lynx, LINK_CONTROL,
+                     LINK_CONTROL_RCV_CMP_VALID | LINK_CONTROL_TX_ASYNC_EN
+                     | LINK_CONTROL_RX_ASYNC_EN | LINK_CONTROL_CYCTIMEREN);
 }
 
 
@@ -456,6 +466,9 @@
         int i;
         u32 *pcli;
 
+        lynx->selfid_size = -1;
+        lynx->phy_reg0 = -1;
+
         lynx->async.queue = NULL;
         spin_lock_init(&lynx->async.queue_lock);
         spin_lock_init(&lynx->phy_reg_lock);
@@ -531,8 +544,8 @@
         reg_write(lynx, DMA_WORD0_CMP_ENABLE(CHANNEL_ASYNC_RCV), 0xa<<4);
         reg_write(lynx, DMA_WORD1_CMP_VALUE(CHANNEL_ASYNC_RCV), 0);
         reg_write(lynx, DMA_WORD1_CMP_ENABLE(CHANNEL_ASYNC_RCV),
-                  DMA_WORD1_CMP_MATCH_NODE_BCAST | DMA_WORD1_CMP_MATCH_BROADCAST
-                  | DMA_WORD1_CMP_MATCH_LOCAL    | DMA_WORD1_CMP_MATCH_BUS_BCAST
+                  DMA_WORD1_CMP_MATCH_LOCAL_NODE | DMA_WORD1_CMP_MATCH_BROADCAST
+                  | DMA_WORD1_CMP_MATCH_EXACT    | DMA_WORD1_CMP_MATCH_BUS_BCAST
                   | DMA_WORD1_CMP_ENABLE_SELF_ID | DMA_WORD1_CMP_ENABLE_MASTER);
 
         run_pcl(lynx, lynx->rcv_pcl_start, CHANNEL_ASYNC_RCV);
@@ -547,12 +560,21 @@
         reg_write(lynx, LINK_CONTROL, LINK_CONTROL_RCV_CMP_VALID
                   | LINK_CONTROL_TX_ISO_EN   | LINK_CONTROL_RX_ISO_EN
                   | LINK_CONTROL_TX_ASYNC_EN | LINK_CONTROL_RX_ASYNC_EN
-                  | LINK_CONTROL_RESET_TX    | LINK_CONTROL_RESET_RX
-                  | LINK_CONTROL_CYCTIMEREN);
-        
-        /* attempt to enable contender bit -FIXME- would this work elsewhere? */
-        reg_set_bits(lynx, GPIO_CTRL_A, 0x1);
-        reg_write(lynx, GPIO_DATA_BASE + 0x3c, 0x1); 
+                  | LINK_CONTROL_RESET_TX    | LINK_CONTROL_RESET_RX);
+
+        if (!lynx->phyic.reg_1394a) {
+                /* attempt to enable contender bit -FIXME- would this work
+                 * elsewhere? */
+                reg_set_bits(lynx, GPIO_CTRL_A, 0x1);
+                reg_write(lynx, GPIO_DATA_BASE + 0x3c, 0x1); 
+        } else {
+                /* set the contender bit in the extended PHY register
+                 * set. (Should check that bis 0,1,2 (=0xE0) is set
+                 * in register 2?)
+                 */
+                i = get_phy_reg(lynx, 4);
+                if (i != -1) set_phy_reg(lynx, 4, i | 0x40);
+        }
 
         return 1;
 }
@@ -628,6 +650,11 @@
 
         switch (cmd) {
         case RESET_BUS:
+                if (reg_read(lynx, LINK_INT_STATUS) & LINK_INT_PHY_BUSRESET) {
+                        retval = 0;
+                        break;
+                }
+
                 if (arg) {
                         arg = 3 << 6;
                 } else {
@@ -642,6 +669,8 @@
                       (host->attempt_root ? " and attempting to become root"
                        : ""));
 
+                lynx->selfid_size = -1;
+                lynx->phy_reg0 = -1;
                 set_phy_reg(lynx, 1, arg);
                 break;
 
@@ -1102,14 +1131,28 @@
                 }
                 if (linkint & LINK_INT_PHY_BUSRESET) {
                         PRINT(KERN_INFO, lynx->id, "bus reset interrupt");
-                        if (!host->in_bus_reset) {
+                        lynx->selfid_size = -1;
+                        lynx->phy_reg0 = -1;
+                        if (!host->in_bus_reset)
                                 hpsb_bus_reset(host);
-                        }
                 }
                 if (linkint & LINK_INT_PHY_REG_RCVD) {
+                        u32 reg;
+
+                        spin_lock(&lynx->phy_reg_lock);
+                        reg = reg_read(lynx, LINK_PHY);
+                        spin_unlock(&lynx->phy_reg_lock);
+
                         if (!host->in_bus_reset) {
                                 PRINT(KERN_INFO, lynx->id,
                                       "phy reg received without reset");
+                        } else if (reg & 0xf00) {
+                                PRINT(KERN_INFO, lynx->id,
+                                      "unsolicited phy reg %d received",
+                                      (reg >> 8) & 0xf);
+                        } else {
+                                lynx->phy_reg0 = reg & 0xff;
+                                handle_selfid(lynx, host);
                         }
                 }
                 if (linkint & LINK_INT_ISO_STUCK) {
@@ -1125,6 +1168,10 @@
                         PRINT(KERN_INFO, lynx->id, "invalid transaction code");
                 }
                 if (linkint & LINK_INT_GRF_OVERFLOW) {
+                        /* flush FIFO if overflow happens during reset */
+                        if (host->in_bus_reset)
+                                reg_write(lynx, FIFO_CONTROL,
+                                          FIFO_CONTROL_GRF_FLUSH);
                         PRINT(KERN_INFO, lynx->id, "GRF overflow");
                 }
                 if (linkint & LINK_INT_ITF_UNDERFLOW) {
@@ -1227,11 +1274,8 @@
                        stat & 0x1fff); 
 
                 if (stat & DMA_CHAN_STAT_SELFID) {
-                        handle_selfid(lynx, host, stat & 0x1fff);
-                        reg_set_bits(lynx, LINK_CONTROL,
-                                     LINK_CONTROL_RCV_CMP_VALID
-                                     | LINK_CONTROL_TX_ASYNC_EN
-                                     | LINK_CONTROL_RX_ASYNC_EN);
+                        lynx->selfid_size = stat & 0x1fff;
+                        handle_selfid(lynx, host);
                 } else {
                         quadlet_t *q_data = lynx->rcv_page;
                         if ((*q_data >> 4 & 0xf) == TCODE_READQ_RESPONSE
@@ -1415,13 +1459,15 @@
 
         lynx->lock = SPIN_LOCK_UNLOCKED;
 
-        reg_write(lynx, PCI_INT_ENABLE, PCI_INT_AUX_INT | PCI_INT_DMA_ALL);
+        reg_write(lynx, PCI_INT_ENABLE, PCI_INT_DMA_ALL);
 
 #ifdef CONFIG_IEEE1394_PCILYNX_PORTS
+        reg_set_bits(lynx, PCI_INT_ENABLE, PCI_INT_AUX_INT);
         init_waitqueue_head(&lynx->mem_dma_intr_wait);
         init_waitqueue_head(&lynx->aux_intr_wait);
 #endif
 
+        INIT_TQ_LINK(lynx->iso_rcv.tq);
         lynx->iso_rcv.tq.routine = (void (*)(void*))iso_rcv_bh;
         lynx->iso_rcv.tq.data = lynx;
         lynx->iso_rcv.lock = SPIN_LOCK_UNLOCKED;
diff -urN linux-2.4.2-pre1/drivers/ieee1394/pcilynx.h linux/drivers/ieee1394/pcilynx.h
--- linux-2.4.2-pre1/drivers/ieee1394/pcilynx.h	Mon Dec 11 13:20:21 2000
+++ linux/drivers/ieee1394/pcilynx.h	Mon Dec  3 22:27:48 2001
@@ -80,6 +80,8 @@
         struct hpsb_host *host;
 
         int phyid, isroot;
+        int selfid_size;
+        int phy_reg0;
 
         spinlock_t phy_reg_lock;
 
@@ -248,9 +250,9 @@
 #define FIFO_SIZES                        0xa00
 
 #define FIFO_CONTROL                      0xa10
-#define GRF_FLUSH                         (1<<4)
-#define ITF_FLUSH                         (1<<3)
-#define ATF_FLUSH                         (1<<2)
+#define FIFO_CONTROL_GRF_FLUSH            (1<<4)
+#define FIFO_CONTROL_ITF_FLUSH            (1<<3)
+#define FIFO_CONTROL_ATF_FLUSH            (1<<2)
 
 #define FIFO_XMIT_THRESHOLD               0xa14
 
@@ -285,8 +287,8 @@
 #define DMA_WORD1_CMP_MATCH_OTHERBUS      (1<<15)
 #define DMA_WORD1_CMP_MATCH_BROADCAST     (1<<14)
 #define DMA_WORD1_CMP_MATCH_BUS_BCAST     (1<<13)
-#define DMA_WORD1_CMP_MATCH_NODE_BCAST    (1<<12)
-#define DMA_WORD1_CMP_MATCH_LOCAL         (1<<11)
+#define DMA_WORD1_CMP_MATCH_LOCAL_NODE    (1<<12)
+#define DMA_WORD1_CMP_MATCH_EXACT         (1<<11)
 #define DMA_WORD1_CMP_ENABLE_SELF_ID      (1<<10)
 #define DMA_WORD1_CMP_ENABLE_MASTER       (1<<8)
 
diff -urN linux-2.4.2-pre1/drivers/ieee1394/raw1394.c linux/drivers/ieee1394/raw1394.c
--- linux-2.4.2-pre1/drivers/ieee1394/raw1394.c	Tue Nov 28 21:45:16 2000
+++ linux/drivers/ieee1394/raw1394.c	Mon Dec  3 22:27:48 2001
@@ -64,6 +64,7 @@
         if (req != NULL) {
                 memset(req, 0, sizeof(struct pending_request));
                 INIT_LIST_HEAD(&req->list);
+                INIT_TQ_LINK(req->tq);
                 req->tq.routine = (void(*)(void*))queue_complete_cb;
         }
 
diff -urN linux-2.4.2-pre1/drivers/isdn/avmb1/capi.c linux/drivers/isdn/avmb1/capi.c
--- linux-2.4.2-pre1/drivers/isdn/avmb1/capi.c	Fri Dec 29 14:07:22 2000
+++ linux/drivers/isdn/avmb1/capi.c	Mon Dec  3 22:27:48 2001
@@ -1,11 +1,18 @@
 /*
- * $Id: capi.c,v 1.45 2000/12/02 19:47:29 kai Exp $
+ * $Id: capi.c,v 1.44.6.3 2000/12/17 22:45:08 kai Exp $
  *
  * CAPI 2.0 Interface for Linux
  *
  * Copyright 1996 by Carsten Paeth (calle@calle.in-berlin.de)
  *
  * $Log: capi.c,v $
+ * Revision 1.44.6.3  2000/12/17 22:45:08  kai
+ * That's hopefully it for test13-4
+ *
+ * Revision 1.44.6.2  2000/12/14 23:04:12  kai
+ * Makefile changes and the like for 2.4.0-test13-pre1
+ * No compatiblity code for older kernels yet, but note the branch
+ *
  * Revision 1.45  2000/12/02 19:47:29  kai
  * Change the Makefiles to new style.
  * There may be problems there that I missed, so this shouldn't go into
@@ -247,7 +254,7 @@
 #endif
 #include <linux/slab.h>
 
-static char *revision = "$Revision: 1.45 $";
+static char *revision = "$Revision: 1.44.6.3 $";
 
 MODULE_AUTHOR("Carsten Paeth (calle@calle.in-berlin.de)");
 
diff -urN linux-2.4.2-pre1/drivers/isdn/divert/isdn_divert.c linux/drivers/isdn/divert/isdn_divert.c
--- linux-2.4.2-pre1/drivers/isdn/divert/isdn_divert.c	Fri Nov 17 11:16:20 2000
+++ linux/drivers/isdn/divert/isdn_divert.c	Mon Dec  3 22:27:48 2001
@@ -1,5 +1,5 @@
 /* 
- * $Id: isdn_divert.c,v 1.6 2000/11/13 22:51:47 kai Exp $
+ * $Id: isdn_divert.c,v 1.6.6.1 2001/02/07 11:31:31 kai Exp $
  *
  * DSS1 main diversion supplementary handling for i4l.
  *
@@ -187,7 +187,7 @@
   restore_flags(flags);
   *procid = cs->ics.parm.dss1_io.ll_id;  
 
-  sprintf(cs->info,"%d 0x%lx %s%s 0 %s %0x %d%s%s\n",
+  sprintf(cs->info,"%d 0x%lx %s%s 0 %s %02x %d%s%s\n",
 	  (!mode ) ? DIVERT_DEACTIVATE : (mode == 1) ? DIVERT_ACTIVATE : DIVERT_REPORT,
           cs->ics.parm.dss1_io.ll_id,
           (mode != 2) ? "" : "0 ",
diff -urN linux-2.4.2-pre1/drivers/isdn/hisax/netjet.c linux/drivers/isdn/hisax/netjet.c
--- linux-2.4.2-pre1/drivers/isdn/hisax/netjet.c	Fri Dec 29 14:07:22 2000
+++ linux/drivers/isdn/hisax/netjet.c	Mon Dec  3 22:27:48 2001
@@ -1,4 +1,4 @@
-/* $Id: netjet.c,v 1.24.6.1 2000/12/06 16:59:20 kai Exp $
+/* $Id: netjet.c,v 1.24.6.2 2000/12/17 22:45:11 kai Exp $
  *
  * netjet.c     low level stuff for Traverse Technologie NETJet ISDN cards
  *
@@ -19,17 +19,10 @@
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/ppp_defs.h>
+#include <asm/io.h>
 #include "netjet.h"
 
-#ifndef bus_to_virt
-#define bus_to_virt (u_int *)
-#endif
-
-#ifndef virt_to_bus
-#define virt_to_bus (u_int)
-#endif
-
-const char *NETjet_revision = "$Revision: 1.24.6.1 $";
+const char *NETjet_revision = "$Revision: 1.24.6.2 $";
 
 /* Interface functions */
 
diff -urN linux-2.4.2-pre1/drivers/isdn/hisax/nj_s.c linux/drivers/isdn/hisax/nj_s.c
--- linux-2.4.2-pre1/drivers/isdn/hisax/nj_s.c	Wed Nov 29 10:12:29 2000
+++ linux/drivers/isdn/hisax/nj_s.c	Mon Dec  3 22:27:48 2001
@@ -1,4 +1,4 @@
-// $Id: nj_s.c,v 2.7.6.1 2000/11/29 16:00:14 kai Exp $
+// $Id: nj_s.c,v 2.7.6.2 2001/02/07 11:31:31 kai Exp $
 //
 // This file is (c) under GNU PUBLIC LICENSE
 //
@@ -14,7 +14,7 @@
 #include <linux/ppp_defs.h>
 #include "netjet.h"
 
-const char *NETjet_S_revision = "$Revision: 2.7.6.1 $";
+const char *NETjet_S_revision = "$Revision: 2.7.6.2 $";
 
 static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off)
 {
@@ -171,6 +171,7 @@
 			PCI_DEVICE_ID_TIGERJET_300,  dev_netjet))) {
 			if (pci_enable_device(dev_netjet))
 				return(0);
+			pci_set_master(dev_netjet);
 			cs->irq = dev_netjet->irq;
 			if (!cs->irq) {
 				printk(KERN_WARNING "NETjet-S: No IRQ for PCI card found\n");
diff -urN linux-2.4.2-pre1/drivers/isdn/hisax/nj_u.c linux/drivers/isdn/hisax/nj_u.c
--- linux-2.4.2-pre1/drivers/isdn/hisax/nj_u.c	Wed Nov 29 10:12:29 2000
+++ linux/drivers/isdn/hisax/nj_u.c	Mon Dec  3 22:27:48 2001
@@ -1,4 +1,4 @@
-/* $Id: nj_u.c,v 2.8.6.1 2000/11/29 16:00:14 kai Exp $ 
+/* $Id: nj_u.c,v 2.8.6.2 2001/02/07 11:31:31 kai Exp $ 
  *
  * This file is (c) under GNU PUBLIC LICENSE
  *
@@ -15,7 +15,7 @@
 #include <linux/ppp_defs.h>
 #include "netjet.h"
 
-const char *NETjet_U_revision = "$Revision: 2.8.6.1 $";
+const char *NETjet_U_revision = "$Revision: 2.8.6.2 $";
 
 static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off)
 {
@@ -174,6 +174,7 @@
 			PCI_DEVICE_ID_TIGERJET_300,  dev_netjet))) {
 			if (pci_enable_device(dev_netjet))
 				return(0);
+			pci_set_master(dev_netjet);
 			cs->irq = dev_netjet->irq;
 			if (!cs->irq) {
 				printk(KERN_WARNING "NETspider-U: No IRQ for PCI card found\n");
diff -urN linux-2.4.2-pre1/drivers/isdn/isdn_common.c linux/drivers/isdn/isdn_common.c
--- linux-2.4.2-pre1/drivers/isdn/isdn_common.c	Mon Jan  8 15:06:01 2001
+++ linux/drivers/isdn/isdn_common.c	Mon Dec  3 22:27:48 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_common.c,v 1.114 2000/11/25 17:00:59 kai Exp $
+/* $Id: isdn_common.c,v 1.114.6.6 2001/02/07 11:31:30 kai Exp $
 
  * Linux ISDN subsystem, common used functions (linklevel).
  *
@@ -24,6 +24,7 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/version.h>
 #include <linux/poll.h>
 #include <linux/vmalloc.h>
@@ -51,7 +52,7 @@
 
 isdn_dev *dev;
 
-static char *isdn_revision = "$Revision: 1.114 $";
+static char *isdn_revision = "$Revision: 1.114.6.6 $";
 
 extern char *isdn_net_revision;
 extern char *isdn_tty_revision;
@@ -2004,16 +2005,6 @@
 }
 
 int
-register_isdn_module(isdn_module *m) {
-	return 0;
-}
-
-int
-unregister_isdn_module(isdn_module *m) {
-	return 0;
-}
-
-int
 isdn_add_channels(driver *d, int drvidx, int n, int adding)
 {
 	int j, k, m;
@@ -2173,8 +2164,6 @@
 
 
 EXPORT_SYMBOL(register_isdn);
-EXPORT_SYMBOL(register_isdn_module);
-EXPORT_SYMBOL(unregister_isdn_module);
 #ifdef CONFIG_ISDN_PPP
 EXPORT_SYMBOL(isdn_ppp_register_compressor);
 EXPORT_SYMBOL(isdn_ppp_unregister_compressor);
@@ -2242,12 +2231,6 @@
  *****************************************************************************
  */
 
-extern int printk(const char *fmt,...);
-
-#ifdef MODULE
-#define isdn_init init_module
-#endif
-
 static char *
 isdn_getrev(const char *revision)
 {
@@ -2356,8 +2339,7 @@
 /*
  * Allocate and initialize all data, register modem-devices
  */
-int
-isdn_init(void)
+static int __init isdn_init(void)
 {
 	int i;
 	char tmprev[50];
@@ -2433,12 +2415,10 @@
 	return 0;
 }
 
-#ifdef MODULE
 /*
  * Unload module
  */
-void
-cleanup_module(void)
+static void __exit isdn_exit(void)
 {
 	int flags;
 	int i;
@@ -2482,4 +2462,6 @@
 		printk(KERN_NOTICE "ISDN-subsystem unloaded\n");
 	}
 }
-#endif
+
+module_init(isdn_init);
+module_exit(isdn_exit);
diff -urN linux-2.4.2-pre1/drivers/isdn/isdn_net.c linux/drivers/isdn/isdn_net.c
--- linux-2.4.2-pre1/drivers/isdn/isdn_net.c	Mon Jan  8 15:06:01 2001
+++ linux/drivers/isdn/isdn_net.c	Mon Dec  3 22:27:48 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_net.c,v 1.140.6.1 2000/12/10 22:01:04 kai Exp $
+/* $Id: isdn_net.c,v 1.140.6.3 2001/02/07 11:31:30 kai Exp $
 
  * Linux ISDN subsystem, network interfaces and related functions (linklevel).
  *
@@ -154,6 +154,7 @@
 	if (!(isdn_net_device_busy(lp))) {
 		if (!skb_queue_empty(&lp->super_tx_queue)) {
 			queue_task(&lp->tqueue, &tq_immediate);
+			mark_bh(IMMEDIATE_BH);
 		} else {
 			isdn_net_device_wake_queue(lp);
 		}
@@ -181,7 +182,7 @@
 int isdn_net_force_dial_lp(isdn_net_local *);
 static int isdn_net_start_xmit(struct sk_buff *, struct net_device *);
 
-char *isdn_net_revision = "$Revision: 1.140.6.1 $";
+char *isdn_net_revision = "$Revision: 1.140.6.3 $";
 
  /*
   * Code for raw-networking over ISDN
@@ -981,11 +982,12 @@
  */
 void isdn_net_write_super(isdn_net_local *lp, struct sk_buff *skb)
 {
-	if (in_interrupt()) {
+	if (in_irq()) {
 		// we can't grab the lock from irq context, 
 		// so we just queue the packet
 		skb_queue_tail(&lp->super_tx_queue, skb); 
 		queue_task(&lp->tqueue, &tq_immediate);
+		mark_bh(IMMEDIATE_BH);
 		return;
 	}
 
diff -urN linux-2.4.2-pre1/drivers/isdn/isdn_ppp.c linux/drivers/isdn/isdn_ppp.c
--- linux-2.4.2-pre1/drivers/isdn/isdn_ppp.c	Mon Jan 22 12:21:54 2001
+++ linux/drivers/isdn/isdn_ppp.c	Mon Dec  3 22:27:48 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_ppp.c,v 1.85 2000/11/25 17:00:59 kai Exp $
+/* $Id: isdn_ppp.c,v 1.85.6.2 2001/01/23 17:45:02 kai Exp $
  *
  * Linux ISDN subsystem, functions for synchronous PPP (linklevel).
  *
@@ -83,7 +83,7 @@
 static int isdn_ppp_bundle(struct ippp_struct *, int unit);
 #endif	/* CONFIG_ISDN_MPP */
   
-char *isdn_ppp_revision = "$Revision: 1.85 $";
+char *isdn_ppp_revision = "$Revision: 1.85.6.2 $";
 
 static struct ippp_struct *ippp_table[ISDN_MAX_CHANNELS];
 
diff -urN linux-2.4.2-pre1/drivers/isdn/isdn_v110.c linux/drivers/isdn/isdn_v110.c
--- linux-2.4.2-pre1/drivers/isdn/isdn_v110.c	Mon Jan 15 15:31:18 2001
+++ linux/drivers/isdn/isdn_v110.c	Mon Dec  3 22:27:48 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_v110.c,v 1.5 2000/05/11 22:29:21 kai Exp $
+/* $Id: isdn_v110.c,v 1.5.6.1 2001/01/23 17:45:02 kai Exp $
 
  * Linux ISDN subsystem, V.110 related functions (linklevel).
  *
@@ -30,7 +30,7 @@
 
 #undef ISDN_V110_DEBUG
 
-char *isdn_v110_revision = "$Revision: 1.5 $";
+char *isdn_v110_revision = "$Revision: 1.5.6.1 $";
 
 #define V110_38400 255
 #define V110_19200  15
diff -urN linux-2.4.2-pre1/drivers/macintosh/Makefile linux/drivers/macintosh/Makefile
--- linux-2.4.2-pre1/drivers/macintosh/Makefile	Fri Dec 29 14:07:22 2000
+++ linux/drivers/macintosh/Makefile	Mon Dec  3 22:27:48 2001
@@ -26,10 +26,7 @@
 
 # Each configuration option enables a list of files.
 
-ifeq ($(CONFIG_PMAC_PBOOK),y)
-	obj-y			+= mediabay.o
-endif
-
+obj-$(CONFIG_PMAC_PBOOK)	+= mediabay.o
 obj-$(CONFIG_MAC_SERIAL)	+= macserial.o
 obj-$(CONFIG_NVRAM)		+= nvram.o
 obj-$(CONFIG_MAC_HID)		+= mac_hid.o
diff -urN linux-2.4.2-pre1/drivers/macintosh/macserial.c linux/drivers/macintosh/macserial.c
--- linux-2.4.2-pre1/drivers/macintosh/macserial.c	Thu Oct 12 14:20:47 2000
+++ linux/drivers/macintosh/macserial.c	Mon Dec  3 22:27:48 2001
@@ -952,6 +952,67 @@
 	info->dma_initted = 1;
 }
 
+/*
+ * FixZeroBug....Works around a bug in the SCC receving channel.
+ * Taken from Darwin code, 15 Sept. 2000  -DanM
+ *
+ * The following sequence prevents a problem that is seen with O'Hare ASICs
+ * (most versions -- also with some Heathrow and Hydra ASICs) where a zero
+ * at the input to the receiver becomes 'stuck' and locks up the receiver.
+ * This problem can occur as a result of a zero bit at the receiver input
+ * coincident with any of the following events:
+ *
+ *	The SCC is initialized (hardware or software).
+ *	A framing error is detected.
+ *	The clocking option changes from synchronous or X1 asynchronous
+ *		clocking to X16, X32, or X64 asynchronous clocking.
+ *	The decoding mode is changed among NRZ, NRZI, FM0, or FM1.
+ *
+ * This workaround attempts to recover from the lockup condition by placing
+ * the SCC in synchronous loopback mode with a fast clock before programming
+ * any of the asynchronous modes.
+ */
+static void fix_zero_bug_scc(struct mac_serial * info)
+{
+	write_zsreg(info->zs_channel, 9,
+		    (info->zs_channel == info->zs_chan_a? CHRA: CHRB));
+	udelay(10);
+	write_zsreg(info->zs_channel, 9,
+		    ((info->zs_channel == info->zs_chan_a? CHRA: CHRB) | NV));
+
+	write_zsreg(info->zs_channel, 4, (X1CLK | EXTSYNC));
+
+	/* I think this is wrong....but, I just copying code....
+	*/
+	write_zsreg(info->zs_channel, 3, (8 & ~RxENABLE));
+
+	write_zsreg(info->zs_channel, 5, (8 & ~TxENAB));
+	write_zsreg(info->zs_channel, 9, NV);	/* Didn't we already do this? */
+	write_zsreg(info->zs_channel, 11, (RCBR | TCBR));
+	write_zsreg(info->zs_channel, 12, 0);
+	write_zsreg(info->zs_channel, 13, 0);
+	write_zsreg(info->zs_channel, 14, (LOOPBAK | SSBR));
+	write_zsreg(info->zs_channel, 14, (LOOPBAK | SSBR | BRENABL));
+	write_zsreg(info->zs_channel, 3, (8 | RxENABLE));
+	write_zsreg(info->zs_channel, 0, RES_EXT_INT);
+	write_zsreg(info->zs_channel, 0, RES_EXT_INT);	/* to kill some time */
+
+	/* The channel should be OK now, but it is probably receiving
+	 * loopback garbage.
+	 * Switch to asynchronous mode, disable the receiver,
+	 * and discard everything in the receive buffer.
+	 */
+	write_zsreg(info->zs_channel, 9, NV);
+	write_zsreg(info->zs_channel, 4, PAR_ENA);
+	write_zsreg(info->zs_channel, 3, (8 & ~RxENABLE));
+
+	while (read_zsreg(info->zs_channel, 0) & Rx_CH_AV) {
+		(void)read_zsreg(info->zs_channel, 8);
+		write_zsreg(info->zs_channel, 0, RES_EXT_INT);
+		write_zsreg(info->zs_channel, 0, ERR_RES);
+	}
+}
+
 static int setup_scc(struct mac_serial * info)
 {
 	unsigned long flags;
@@ -960,6 +1021,9 @@
 
 	save_flags(flags); cli(); /* Disable interrupts */
 
+	/* Nice buggy HW ... */
+	fix_zero_bug_scc(info);
+
 	/*
 	 * Reset the chip.
 	 */
@@ -1080,7 +1144,7 @@
 
 	info->curregs[5] &= ~TxENAB;
 	if (!info->tty || C_HUPCL(info->tty))
-		info->curregs[5] &= ~(DTR | RTS);
+		info->curregs[5] &= ~DTR;
 	info->pendregs[5] = info->curregs[5];
 	write_zsreg(info->zs_channel, 5, info->curregs[5]);
 
@@ -1252,7 +1316,7 @@
 
 	/* assert DTR, wait 30ms, talk to the chip */
 	write_zsreg(info->zs_channel, 5, Tx8 | TxENAB | RTS | DTR);
-	udelay(30000);
+	mdelay(30);
 	while (read_zsreg(info->zs_channel, 0) & Rx_CH_AV)
 		read_zsdata(info->zs_channel);
 
@@ -1589,17 +1653,35 @@
 	if (C_CRTSCTS(tty)) {
 		/*
 		 * Here we want to turn off the RTS line.  On Macintoshes,
-		 * we only get the DTR line, which goes to both DTR and
-		 * RTS on the modem.  RTS doesn't go out to the serial
-		 * port socket.  So you should make sure your modem is
-		 * set to ignore DTR if you're using CRTSCTS.
+		 * the external serial ports using a DIN-8 or DIN-9
+		 * connector only have the DTR line (which is usually
+		 * wired to both RTS and DTR on an external modem in
+		 * the cable).  RTS doesn't go out to the serial port
+		 * socket, it acts as an output enable for the transmit
+		 * data line.  So in this case we don't drop RTS.
+		 *
+		 * Macs with internal modems generally do have both RTS
+		 * and DTR wired to the modem, so in that case we do
+		 * drop RTS.
 		 */
+		if (info->is_internal_modem) {
+			save_flags(flags); cli();
+			info->curregs[5] &= ~RTS;
+			info->pendregs[5] &= ~RTS;
+			write_zsreg(info->zs_channel, 5, info->curregs[5]);
+			restore_flags(flags);
+		}
+	}
+	
+#ifdef CDTRCTS
+	if (tty->termios->c_cflag & CDTRCTS) {
 		save_flags(flags); cli();
-		info->curregs[5] &= ~(DTR | RTS);
-		info->pendregs[5] &= ~(DTR | RTS);
+		info->curregs[5] &= ~DTR;
+		info->pendregs[5] &= ~DTR;
 		write_zsreg(info->zs_channel, 5, info->curregs[5]);
 		restore_flags(flags);
 	}
+#endif /* CDTRCTS */
 }
 
 static void rs_unthrottle(struct tty_struct * tty)
@@ -1625,14 +1707,25 @@
 		restore_flags(flags);
 	}
 
-	if (C_CRTSCTS(tty)) {
-		/* Assert RTS and DTR lines */
+	if (C_CRTSCTS(tty) && info->is_internal_modem) {
+		/* Assert RTS line */
 		save_flags(flags); cli();
-		info->curregs[5] |= DTR | RTS;
-		info->pendregs[5] |= DTR | RTS;
+		info->curregs[5] |= RTS;
+		info->pendregs[5] |= RTS;
 		write_zsreg(info->zs_channel, 5, info->curregs[5]);
 		restore_flags(flags);
 	}
+
+#ifdef CDTRCTS
+	if (tty->termios->c_cflag & CDTRCTS) {
+		/* Assert DTR line */
+		save_flags(flags); cli();
+		info->curregs[5] |= DTR;
+		info->pendregs[5] |= DTR;
+		write_zsreg(info->zs_channel, 5, info->curregs[5]);
+		restore_flags(flags);
+	}
+#endif
 }
 
 /*
@@ -2196,8 +2289,8 @@
 #endif
 	if (serial_paranoia_check(info, tty->device, "rs_open"))
 		return -ENODEV;
-	OPNDBG("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
-	       info->count);
+	OPNDBG("rs_open %s%d, count = %d, tty=%p\n", tty->driver.name,
+	       info->line, info->count, tty);
 
 	info->count++;
 	tty->driver_data = info;
@@ -2314,8 +2407,12 @@
 	zss->is_irda = conn && (strcmp(conn, "infrared") == 0);
 	/* 1999 Powerbook G3 has slot-names property instead */
 	slots = (struct slot_names_prop *)get_property(ch, "slot-names", &len);
-	if (slots && slots->count > 0 && strcmp(slots->name, "IrDA") == 0)
-		zss->is_irda = 1;
+	if (slots && slots->count > 0) {
+		if (strcmp(slots->name, "IrDA") == 0)
+			zss->is_irda = 1;
+		else if (strcmp(slots->name, "Modem") == 0)
+			zss->is_internal_modem = 1;
+	}
 
 	if (zss->has_dma) {
 		zss->dma_priv = NULL;
@@ -2564,6 +2661,8 @@
 			printk(", port = %s", connector);
 		if (info->is_cobalt_modem)
 			printk(" (cobalt modem)");
+		else if (info->is_internal_modem)
+			printk(" (internal modem)");
 		if (info->is_irda)
 			printk(" (IrDA)");
 		printk("\n");
diff -urN linux-2.4.2-pre1/drivers/macintosh/macserial.h linux/drivers/macintosh/macserial.h
--- linux-2.4.2-pre1/drivers/macintosh/macserial.h	Sat May 20 12:07:56 2000
+++ linux/drivers/macintosh/macserial.h	Mon Dec  3 22:27:48 2001
@@ -110,6 +110,7 @@
 	char break_abort;   /* Is serial console in, so process brk/abrt */
 	char kgdb_channel;  /* Kgdb is running on this channel */
 	char is_cons;       /* Is this our console. */
+	char is_internal_modem; /* is connected to an internal modem */
 	char is_cobalt_modem;	/* is a gatwick-based cobalt modem */
 	char is_irda;		/* is connected to an IrDA codec */
 	unsigned char tx_active; /* character is being xmitted */
diff -urN linux-2.4.2-pre1/drivers/macintosh/via-pmu.c linux/drivers/macintosh/via-pmu.c
--- linux-2.4.2-pre1/drivers/macintosh/via-pmu.c	Sat Nov 11 18:19:56 2000
+++ linux/drivers/macintosh/via-pmu.c	Mon Dec  3 22:27:48 2001
@@ -166,12 +166,6 @@
 extern void sleep_save_intrs(int);
 extern void sleep_restore_intrs(void);
 
-extern int grackle_pcibios_read_config_word(unsigned char bus,
-	unsigned char dev_fn, unsigned char offset, unsigned short *val);
-
-extern int grackle_pcibios_write_config_word(unsigned char bus,
-	unsigned char dev_fn, unsigned char offset, unsigned short val);
-
 /*
  * This table indicates for each PMU opcode:
  * - the number of data bytes to be sent with the command, or -1
@@ -1336,6 +1330,11 @@
 	unsigned short pmcr1;
 	struct adb_request req;
 	int ret, timeout;
+	struct pci_dev *grackle;
+
+	grackle = pci_find_slot(0, 0);
+	if (!grackle)
+		return -ENODEV;
 
 	/* Notify device drivers */
 	ret = broadcast_sleep(PBOOK_SLEEP_REQUEST, PBOOK_SLEEP_REJECT);
@@ -1409,21 +1408,21 @@
 	/* We shut down some HW */
 	feature_prepare_for_sleep();
 
-	grackle_pcibios_read_config_word(0,0,0x70,&pmcr1);
+	pci_read_config_word(grackle, 0x70, &pmcr1);
 	/* Apparently, MacOS uses NAP mode for Grackle ??? */
 	pmcr1 &= ~(GRACKLE_DOZE|GRACKLE_SLEEP); 
 	pmcr1 |= GRACKLE_PM|GRACKLE_NAP;
-	grackle_pcibios_write_config_word(0, 0, 0x70, pmcr1);
+	pci_write_config_word(grackle, 0x70, pmcr1);
 
 	/* Call low-level ASM sleep handler */
 	low_sleep_handler();
 
 	/* We're awake again, stop grackle PM */
-	grackle_pcibios_read_config_word(0, 0, 0x70, &pmcr1);
+	pci_read_config_word(grackle, 0x70, &pmcr1);
 	pmcr1 &= ~(GRACKLE_PM|GRACKLE_DOZE|GRACKLE_SLEEP|GRACKLE_NAP); 
-	grackle_pcibios_write_config_word(0, 0, 0x70, pmcr1);
-	
-	/* Restore things */
+	pci_write_config_word(grackle, 0x70, pmcr1);
+
+	/* Make sure the PMU is idle */
 	feature_wake_up();
 	restore_via_state();
 	
diff -urN linux-2.4.2-pre1/drivers/md/md.c linux/drivers/md/md.c
--- linux-2.4.2-pre1/drivers/md/md.c	Mon Jan 29 13:16:00 2001
+++ linux/drivers/md/md.c	Mon Dec  3 22:27:48 2001
@@ -2590,7 +2590,7 @@
 			err = md_put_user (read_ahead[
 				MAJOR(dev)], (long *) arg);
 			goto done;
-		default:
+		default:;
 	}
 
 	/*
@@ -2609,7 +2609,7 @@
 				err = -EEXIST;
 				goto abort;
 			}
-		default:
+		default:;
 	}
 	switch (cmd)
 	{
@@ -2662,7 +2662,7 @@
 			}
 			goto done;
 
-		default:
+		default:;
 	}
 
 	/*
@@ -3665,6 +3665,7 @@
  *             elements in device-list are read by name_to_kdev_t so can be
  *             a hex number or something like /dev/hda1 /dev/sdb
  */
+#ifndef MODULE
 extern kdev_t name_to_kdev_t(char *line) md__init;
 static int md__init md_setup(char *str)
 {
@@ -3740,6 +3741,7 @@
 	md_setup_args.device_set[minor] = 1;
 	return 1;
 }
+#endif /* !MODULE */
 
 void md__init md_setup_drive(void)
 {
diff -urN linux-2.4.2-pre1/drivers/media/video/stradis.c linux/drivers/media/video/stradis.c
--- linux-2.4.2-pre1/drivers/media/video/stradis.c	Fri Nov 17 17:56:51 2000
+++ linux/drivers/media/video/stradis.c	Mon Dec  3 22:27:48 2001
@@ -2067,11 +2067,15 @@
 	if (result == -EBUSY)
 		printk(KERN_ERR "stradis%d: IRQ %ld busy, change your PnP"
 		       " config in BIOS\n", num, saa->irq);
-	if (result < 0)
+	if (result < 0) {
+		iounmap(saa->saa7146_mem);
 		return result;
+	}
 	pci_set_master(dev);
-	if (video_register_device(&saa->video_dev, VFL_TYPE_GRABBER) < 0)
+	if (video_register_device(&saa->video_dev, VFL_TYPE_GRABBER) < 0) {
+		iounmap(saa->saa7146_mem);
 		return -1;
+	}
 #if 0
 	/* i2c generic interface is currently BROKEN */
 	i2c_register_bus(&saa->i2c);
diff -urN linux-2.4.2-pre1/drivers/media/video/zr36120.c linux/drivers/media/video/zr36120.c
--- linux-2.4.2-pre1/drivers/media/video/zr36120.c	Fri Nov 17 17:56:52 2000
+++ linux/drivers/media/video/zr36120.c	Mon Dec  3 22:27:48 2001
@@ -1866,14 +1866,16 @@
 			SA_SHIRQ|SA_INTERRUPT,"zoran",(void *)ztv);
 		if (result==-EINVAL)
 		{
+			iounmap(ztv->zoran_mem);
 			printk(KERN_ERR "zoran: Bad irq number or handler\n");
 			return -EINVAL;
 		}
 		if (result==-EBUSY)
 			printk(KERN_ERR "zoran: IRQ %d busy, change your PnP config in BIOS\n",dev->irq);
-		if (result < 0)
+		if (result < 0) {
+			iounmap(ztv->zoran_mem);
 			return result;
-
+		}
 		/* Enable bus-mastering */
 		pci_set_master(dev);
 
diff -urN linux-2.4.2-pre1/drivers/mtd/cfi_cmdset_0001.c linux/drivers/mtd/cfi_cmdset_0001.c
--- linux-2.4.2-pre1/drivers/mtd/cfi_cmdset_0001.c	Wed Nov 15 00:41:03 2000
+++ linux/drivers/mtd/cfi_cmdset_0001.c	Mon Dec  3 22:27:48 2001
@@ -816,13 +816,13 @@
 			 * as the whole point is that nobody can do anything
 			 * with the chip now anyway.
 			 */
-			spin_unlock_bh(chip->mutex);
 			break;
 
 		default:
 			ret = -EAGAIN;
 			break;
 		}
+		spin_unlock_bh(chip->mutex);
 	}
 
 	/* Unlock the chips again */
diff -urN linux-2.4.2-pre1/drivers/mtd/cfi_cmdset_0002.c linux/drivers/mtd/cfi_cmdset_0002.c
--- linux-2.4.2-pre1/drivers/mtd/cfi_cmdset_0002.c	Sun Dec  3 17:45:22 2000
+++ linux/drivers/mtd/cfi_cmdset_0002.c	Mon Dec  3 22:27:48 2001
@@ -552,13 +552,13 @@
 			 * as the whole point is that nobody can do anything
 			 * with the chip now anyway.
 			 */
-			spin_unlock_bh(chip->mutex);
 			break;
 
 		default:
 			ret = -EAGAIN;
 			break;
 		}
+		spin_unlock_bh(chip->mutex);
 	}
 
 	/* Unlock the chips again */
diff -urN linux-2.4.2-pre1/drivers/mtd/ftl.c linux/drivers/mtd/ftl.c
--- linux-2.4.2-pre1/drivers/mtd/ftl.c	Sun Dec  3 17:45:22 2000
+++ linux/drivers/mtd/ftl.c	Mon Dec  3 22:27:48 2001
@@ -30,7 +30,7 @@
     are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
 
     Alternatively, the contents of this file may be used under the
-    terms of the GNU Public License version 2 (the "GPL"), in which
+    terms of the GNU General Public License version 2 (the "GPL"), in which
     case the provisions of the GPL are applicable instead of the
     above.  If you wish to allow the use of your version of this file
     only under the terms of the GPL and not to allow others to use
diff -urN linux-2.4.2-pre1/drivers/mtd/mapped.c linux/drivers/mtd/mapped.c
--- linux-2.4.2-pre1/drivers/mtd/mapped.c	Sun Sep 24 12:12:33 2000
+++ linux/drivers/mtd/mapped.c	Wed Dec 31 16:00:00 1969
@@ -1,673 +0,0 @@
-// -*- mode: cpp; mode: fold -*-
-// Description                                                          /*{{{*/
-// $Id: mapped.c,v 1.8 2000/03/31 14:40:42 dwmw2 Exp $
-/* ######################################################################
-
-   Flash MTD Routines
-
-   These routine support IDing and manipulating flash. Currently the 
-   older JEDEC ID mechanism and a table is used for determining the
-   flash characterisitics, but it is trivial to add support for the
-   CFI specification:
-     http://www.pentium.com/design/flash/ in the technote section.
-   
-   ##################################################################### */
-									/*}}}*/
-#include <linux/mtd/mapped.h>
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <asm/io.h>
-
-struct JEDECTable mtd_JEDEC_table[] = 
-  {{0x01AD,"AMD Am29F016",2*1024*1024,64*1024,MTD_CAP_NORFLASH},
-   {0x01D5,"AMD Am29F080",1*1024*1024,64*1024,MTD_CAP_NORFLASH},
-   {}};
-
-// flash_setup - Setup the mapped_mtd_info structure for normal flash	/*{{{*/
-// ---------------------------------------------------------------------
-/* There is a set of commands that flash manufactures follow for getting the
-   JEDEC id, erasing and writing. So long as your flash device supports 
-   getting the JEDEC ID in this (standard?) way it will be supported as flash,
-   otherwise it is converted to ROM. Upon completion the structure is 
-   registered with the MTD layer */
-int mtd_mapped_setup(struct mapped_mtd_info *map)
-{
-   DEBUG(1, "\n");
-   // Must define a page function to use the defaults!
-   if (map->page == 0)
-      return -1;
-   
-   if (map->jedec_sense == 0)
-      map->jedec_sense = flash_jedec;
-
-   if (map->jedec_sense(map) != 0)
-      return -1;
-
-   if (map->mtd.erase == 0 && map->mtd.type == MTD_NORFLASH)
-      map->mtd.erase = flash_erase;
-   if (map->mtd.write == 0)
-   {
-      if (map->mtd.type == MTD_NORFLASH)
-	 map->mtd.write = flash_write;
-      if (map->mtd.type == MTD_RAM)
-	 map->mtd.write = ram_write;      
-   }   
-   if (map->mtd.read == 0)
-      map->mtd.read = rom_read;   
-   
-   return add_mtd_device(&map->mtd);
-}
-									/*}}}*/
-// flash_remove - Remove the flash device from the MTD layer		/*{{{*/
-// ---------------------------------------------------------------------
-/* Free any memory allocated for the device here */
-int mtd_mapped_remove(struct mapped_mtd_info *map)
-{
-   return del_mtd_device(&map->mtd);
-}
-									/*}}}*/
-
-// checkparity - Checks a number for odd parity				/*{{{*/
-// ---------------------------------------------------------------------
-/* Helper for the JEDEC function, JEDEC numbers all have odd parity */
-static int checkparity(u_char C)
-{
-   u_char parity = 0;
-   while (C != 0)
-   {
-      parity ^= C & 1;
-      C >>= 1;
-   }
-   
-   return parity == 1;
-}
-									/*}}}*/
-// SetJedec - Set the jedec information for a chip			/*{{{*/
-// ---------------------------------------------------------------------
-/* We track the configuration of each chip separately in the chip list, 
-   each chip can have a different type and configuration to allow for 
-   maximum flexability. */
-void set_jedec(struct mapped_mtd_info *map,unsigned chip,unsigned char mfr,
-	      unsigned char id)
-{
-   unsigned long longID = (mfr << 8) + id;
-   unsigned int I;
-   
-   map->mtd.type = MTD_NORFLASH;
-   map->mfr = mfr;
-   map->id = id;
-
-   // Locate the chip in the jedec table
-   for (I = 0; mtd_JEDEC_table[I].jedec != 0; I++)
-   {      
-      if (mtd_JEDEC_table[I].jedec == longID)
-	 break;
-   }
-
-   if (mtd_JEDEC_table[I].jedec != longID || longID == 0)
-   {
-      printk("Unknown JEDEC number %x-%x, treating as ROM\n",map->mfr,
-	     map->id);
-      map->mtd.type = MTD_ROM;
-      return;
-   }
-      
-   // Setup the MTD from the JEDEC information
-//   map->mtd.size = mtd_JEDEC_table[I].size;
-//   map->mtd.erasesize = mtd_JEDEC_table[I].sectorsize;
-//   map->mtd.capabilities = mtd_JEDEC_table[I].capabilities;
-//   strncpy(map->mtd.part,mtd_JEDEC_table[I].name,sizeof(map->mtd.part)-1);
-   
-   map->chips[chip].jedec = longID;
-   map->chips[chip].size = mtd_JEDEC_table[I].size;
-   map->chips[chip].sectorsize = mtd_JEDEC_table[I].sectorsize;
-   map->chips[chip].capabilities = mtd_JEDEC_table[I].capabilities;
-   map->chips[chip].base = 0; 
-}
-									/*}}}*/
-// isjedec - Check if reading from the memory location gives jedec #s	/*{{{*/
-// ---------------------------------------------------------------------
-/* This is ment to be called on the flash window once it is in jedec mode */
-int isjedec(unsigned long base)
-{
-   // Test #1, JEDEC numbers are readable from 0x??00/0x??01
-   if (readb(base + 0) != readb(base + 0x100) || 
-       readb(base + 1) != readb(base + 0x101))
-      return 0;
-   
-   // Test #2 JEDEC numbers exhibit odd parity
-   if (checkparity(readb(base + 0)) == 0 || checkparity(readb(base + 1)) == 0)
-      return 0;
-   return 1;
-}
-									/*}}}*/
-// flash_jedec - JEDEC ID sensor					/*{{{*/
-// ---------------------------------------------------------------------
-/* The mysterious jedec flash probe sequence writes a specific pattern of
-   bytes to the flash. This should be general enough to work with any MTD
-   structure that may contain a flash chip, but note that it will corrupt
-   address 0x5555 on SRAM cards if the machine dies between the two 
-   critical operations. */
-int flash_jedec(struct mapped_mtd_info *map)
-{
-   unsigned I;
-   u_char OldVal;
-   unsigned long base;
-   unsigned long baseaddr = 0;
-   unsigned chip = 0;
-   unsigned count;
-   
-   // Who has a page size this small? :>
-   if (map->pagesize < 0x555)
-      return 1;
-   
-   base = map->page(map,0);
-   
-   // Wait for any write/erase operation to settle
-   OldVal = readb(base);
-   for (I = 0; OldVal != readb(base) && I < 10000; I++)
-      OldVal = readb(base);
-   
-   /* Check for sram by writing to it, the write also happens to be part 
-      of the flash reset sequence.. */
-   OldVal = readb(base + 0x555);
-   writeb(OldVal,base + 0x555);
-   writeb(0xF0,base + 0x555);
-   if (OldVal != readb(base + 0x555))
-   {
-      udelay(100);
-      
-      // Set it back and make sure..
-      writeb(OldVal,base + 0x555);
-      if (OldVal == readb(base + 0x555))
-      {
-	 map->mtd.type = MTD_RAM;
-	 return 0;
-      }
-      
-      writeb(0xF0,base + 0x555);
-   }
-   
-   // Probe for chips
-   while (chip < sizeof(map->chips)/sizeof(map->chips[0]))
-   {
-      // Already in jedec mode, we might be doing some address wrap around
-      if (chip != 0 && isjedec(base) != 0)
-      {
-	 /* Try to reset this page and check if that resets the first page
-	    to confirm */
-	 writeb(0xF0,base + 0x555);
-	 if (isjedec(base) != 0)
-	    break;
-	 base = map->page(map,0);
-	 if (isjedec(base) == 0)
-	    break;
-	 base = map->page(map,baseaddr/map->pagesize);
-      }
-      
-      // Send the sequence
-      writeb(0xAA,base + 0x555);
-      writeb(0x55,base + 0x2AA);
-      writeb(0x90,base + 0x555);
-
-      // Check the jedec number
-      if (isjedec(base) == 0)
-      {
-	 /* If this is the first chip it must be rom, otherwise it is the
-	    end of the flash region */
-	 if (chip == 0)
-	 {
-	    map->mtd.type = MTD_ROM;
-	    return 0;
-	 }
-	 break;
-      }      
-      
-      // Store the jdec info
-      set_jedec(map,chip,readb(base + 0),readb(base + 1));
-      map->chips[chip].base = baseaddr;
-      
-      // Jump to the next chip
-      baseaddr += map->chips[chip].size;
-      if (baseaddr/map->pagesize > map->maxsize)
-	 break;
-      base = map->page(map,baseaddr/map->pagesize);
-      if (base == 0)
-	 return -EIO;
-      
-      chip++;
-   }
-
-   // Reset all of the chips
-   map->mtd.size = 0;
-   baseaddr = 0;
-   map->mtd.flags = 0xFFFF;
-   for (I = 0; map->chips[I].jedec != 0; I++)
-   {
-      // Fill in the various MTD structures
-      map->mtd.size += map->chips[I].size;
-      if (map->mtd.erasesize < map->chips[I].sectorsize)
-	 map->mtd.erasesize = map->chips[I].sectorsize;
-      map->mtd.flags &= map->chips[I].capabilities;
-      
-      base = map->page(map,baseaddr/map->pagesize);
-      baseaddr += map->chips[chip].size;
-      writeb(0xF0,base + 0);  // Reset      
-   }   
-   
-   /* Generate a part name that includes the number of different chips and
-      other configuration information */
-   count = 1;
-   map->part[0] = 0;
-   for (I = 0; map->chips[I].jedec != 0; I++)
-   {
-      unsigned J;
-      if (map->chips[I+1].jedec == map->chips[I].jedec)
-      {
-	 count++;
-	 continue;
-      }
-      
-      // Locate the chip in the jedec table
-      for (J = 0; mtd_JEDEC_table[J].jedec != 0; J++)
-      {      
-	 if (mtd_JEDEC_table[J].jedec == map->chips[I].jedec)
-	    break;
-      }
-      
-      if (map->part[0] != 0)
-	 strcat(map->part,",");
-      
-      if (count != 1)
-	 sprintf(map->part+strlen(map->part),"%u*[%s]",count,
-		 mtd_JEDEC_table[J].name);
-      else
-	 sprintf(map->part+strlen(map->part),"%s",
-		 mtd_JEDEC_table[J].name);
-      count = 1;
-   }   
-   return 0;
-}
-									/*}}}*/
-
-// flash_failed - Print a console message about why the failure		/*{{{*/
-// ---------------------------------------------------------------------
-/* Pass the flags value that the flash return before it re-entered read 
-   mode. */
-static void flash_failed(unsigned char code)
-{
-   /* Bit 5 being high indicates that there was an internal device
-      failure, erasure time limits exceeded or something */
-   if ((code & (1 << 5)) != 0)
-   {
-      printk("mtd: Internal Flash failure\n");
-      return;
-   }
-   printk("mtd: Programming didn't take\n");
-}
-									/*}}}*/
-// flash_erase - Generic erase function					/*{{{*/
-// ---------------------------------------------------------------------
-/* This uses the erasure function described in the AMD Flash Handbook, 
-   it will work for flashes with a fixed sector size only. Flashes with
-   a selection of sector sizes (ie the AMD Am29F800B) will need a different
-   routine. This routine tries to parallize erasing multiple chips/sectors 
-   where possible */
-int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
-{
-   unsigned long Time = 0;
-   unsigned long NoTime = 0;
-   unsigned long start = instr->addr, len = instr->len;
-   unsigned int I;
-   struct mapped_mtd_info *map = (struct mapped_mtd_info *)mtd;
-
-   // Verify the arguments..
-   if (start + len > map->mtd.size ||
-       (start % map->mtd.erasesize) != 0 ||
-       (len % map->mtd.erasesize) != 0 ||
-       (len/map->mtd.erasesize) == 0)
-      return -EINVAL;
-   
-   flash_chip_scan(map,start,len);
-
-   // Start the erase sequence on each chip
-   for (I = 0; map->chips[I].jedec != 0; I++)
-   {
-      unsigned long off;
-      struct flash_chip *chip = map->chips + I;
-      unsigned long base;
-      unsigned long flags;
-      
-      if (chip->length == 0)
-	 continue;
-      
-      if (page_jump(map,chip->base + chip->start,0x555,&base,0) != 0)
-	 return -EIO;
-      
-      // Send the erase setup code
-      writeb(0xF0,base + 0x555);
-      writeb(0xAA,base + 0x555);
-      writeb(0x55,base + 0x2AA);
-      writeb(0x80,base + 0x555);
-      writeb(0xAA,base + 0x555);
-      writeb(0x55,base + 0x2AA);
-
-      // Use chip erase if possible
-      if (chip->start == 0 && chip->length == chip->size)
-      {
-	 writeb(0x10,base+0x555);
-	 continue;
-      }
-            
-      /* Once we start selecting the erase sectors the delay between each 
-         command must not exceed 50us or it will immediately start erasing 
-         and ignore the other sectors */
-      save_flags(flags);
-      cli();
-      for (off = 0; off < chip->length; off += chip->sectorsize)
-      {
-	 if (page_jump(map,chip->base + chip->start + off,1,&base,0) != 0)
-	    return -EIO;
-	 
-	 // Check to make sure we didn't timeout
-	 writeb(0x30,base);
-	 if ((readb(base) & (1 << 3)) != 0)
-	 {
-	    printk("mtd: Ack! We timed out the erase timer!\n");
-	    return -EIO;
-	 }       	 
-      }
-      restore_flags(flags);
-   }   
-
-   /* We could split this into a timer routine and return early, performing
-      background erasure.. Maybe later if the need warrents */
-   
-   /* Poll the flash for erasure completion, specs say this can take as long
-      as 480 seconds to do all the sectors (for a 2 meg flash). 
-      Erasure time is dependant on chip age, temp and wear.. */
-   Time = 0;
-   NoTime = 0;
-   for (I = 0; map->chips[I].jedec != 0; I++)
-   {
-      struct flash_chip *chip = map->chips + I;
-      unsigned long base;
-      unsigned long off = 0;
-      if (chip->length == 0)
-	 continue;
-      
-      if (page_jump(map,chip->base + chip->start,1,&base,0) != 0)
-	 return -EIO;
-      
-      while (1)
-      {
-	 unsigned char Last[4];
-	 unsigned long Count = 0;
-	 
-	 /* During erase bit 7 is held low and bit 6 toggles, we watch this,
-	    should it stop toggling or go high then the erase is completed,
-  	    or this is not really flash ;> */
-	 Last[0] = readb(base);
-	 Last[1] = readb(base);
-	 Last[2] = readb(base);
-	 for (Count = 3; (Last[(Count - 1) % 4] & (1 << 7)) == 0 && 
-	      Last[(Count - 1) % 4] != Last[(Count - 2) % 4]; Count++)
-	 {
-	    if (NoTime == 0)
-	       Time += HZ/10 - schedule_timeout(HZ/10);
-	    NoTime = 0;
-	    
-	    Last[Count % 4] = readb(base);
-	 
-	    // Count time, max of 15s per sector (according to AMD)
-	    if (Time > 15*len/mtd->erasesize*HZ)
-	    {
-	       printk("mtd: Flash Erase Timed out\n");
-	       return -EIO;
-	    }	    
-	 }
-	 
-	 if (Last[(Count - 1) % 4] == Last[(Count - 2) % 4])
-	 {
-	    flash_failed(Last[(Count - 3) % 4]);
-	    return -EIO;
-	 }
-	 
-	 // Skip to the next chip if we used chip erase
-	 if (chip->length == chip->size)
-	    off = chip->size;
-	 else
-	    off += chip->sectorsize;
-	 
-	 if (off >= chip->length)
-	    break;
-	 if (page_jump(map,chip->base + chip->start + off,1,&base,0) != 0)
-	    return -EIO;	 
-	 NoTime = 1;
-      }      
-   }
-       	 
-   // Paranoid verify of erasure
-   {
-      unsigned long base;
-      unsigned long buflen;
-      while (len > 0)
-      {
-	 unsigned long step;
-	 
-	 if (page_jump(map,start,len,&base,&buflen) != 0)
-	    return -EIO;
-	 start += buflen;
-	 len -= buflen;
-	 step = buflen/128;
-	 for (;buflen != 0; buflen -= step)
-	 {
-	    if (readb(base+buflen-1) != 0xFF)
-	    {
-	       printk("mtd: Flash Erase didn't take %lu %lu %lu\n",buflen,len,start);
-	       return -EIO;
-	    }
-	 }	 
-      }      
-   }   
-   
-   return 0;
-}
-#if 1
-									/*}}}*/
-// flash_write - Generic writing function				/*{{{*/
-// ---------------------------------------------------------------------
-/* This could do parallel writes on multiple chips but doesnt, memory 
-   constraints make that infeasable. This should work with any sort of 
-   linear flash that is not interleved */
-extern int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
-		       size_t *retlen, const u_char *buf)
-{
-   struct mapped_mtd_info *map = (struct mapped_mtd_info *)mtd;
-   unsigned long base;
-   unsigned long off;
-   DEBUG(1,"\n");
-   if (start + len > mtd->size)
-      return -EIO;
-   
-   while (len != 0)
-   {
-      // Compute the page offset and reposition
-      base = map->page(map,(u_long)start/map->pagesize);
-      off = (u_long)start %  map->pagesize;
-
-      // Loop over this page
-      for (; off != map->pagesize && len != 0; start++, len--, off++,buf++)
-      {
-	 unsigned char oldbyte = readb(base+off);
-	 unsigned char Last[4];
-	 unsigned long Count = 0;
-
-	 if (oldbyte == *buf)
-	    continue;
-	 if (((~oldbyte) & *buf) != 0)
-	    printk("mtd: warn: Trying to set a 0 to a 1\n");
-	     
-	 // Write
-	 writeb(0xAA,base + 0x555);
-	 writeb(0x55,base + 0x2AA);
-	 writeb(0xA0,base + 0x555);
-	 writeb(*buf,base + off);
-	 Last[0] = readb(base + off);
-	 Last[1] = readb(base + off);
-	 Last[2] = readb(base + off);
-	 
-	 /* Wait for the flash to finish the operation. We store the last 4
-	    status bytes that have been retrieved so we can determine why
-	    it failed. The toggle bits keep toggling when there is a 
-	    failure */
-	 for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] &&
-	      Count < 10000; Count++)
-	    Last[Count % 4] = readb(base + off);
-	 if (Last[(Count - 1) % 4] != *buf)
-	 {
-	    flash_failed(Last[(Count - 3) % 4]);
-	    return -EIO;
-	 }	 
-      }
-   }
-   *retlen = len;
-   return 0;
-}
-#endif
-
-// ram_write - Generic writing function	for ram				/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-extern int ram_write(struct mtd_info *mtd, loff_t start, size_t len,
-		       size_t *retlen, const u_char *buf)
-{
-   struct mapped_mtd_info *map = (struct mapped_mtd_info *)mtd;
-   unsigned long base;
-   size_t origlen = len;
-   unsigned long buflen;
-   DEBUG(1,"\n");
-   if (start + len > mtd->size)
-      return -EIO;
-   
-   while (len != 0)
-   {
-      // Reposition..
-      if (page_jump(map,start,len,&base,&buflen) != 0)
-	 return -EIO;
-      
-      // Copy
-      memcpy_toio(base,buf,buflen);
-      len -= buflen;
-      start += buflen;
-   }
-   *retlen = origlen;
-   return 0;
-}
-
-// rom_read - Read handler for any sort of device			/*{{{*/
-// ---------------------------------------------------------------------
-/* This is a generic read function that should work with any device in the
-   mapped region. */
-extern int rom_read(struct mtd_info *mtd, loff_t start, size_t len,
-		    size_t *retlen, u_char *buf)
-{
-   struct mapped_mtd_info *map = (struct mapped_mtd_info *)mtd;
-   size_t origlen = len;
-   unsigned long base;
-   unsigned long buflen;
-
-   printk("Rom_Read\n");
-   if (start + len > mtd->size)
-      return -EIO;
-   
-   while (len != 0)
-   {
-      // Reposition..
-      if (page_jump(map,start,len,&base,&buflen) != 0)
-	 return -EIO;
-      
-      // Copy
-      memcpy_fromio(buf,base,buflen);
-      len -= buflen;
-      start += buflen;
-   }
-   *retlen = origlen;
-   return 0;
-}
-
-// page_jump - Move the window and return the buffer			/*{{{*/
-// ---------------------------------------------------------------------
-/* Unlike the page function this returns a buffer and length adjusted for
-   the page dimensions and the reading offset into the page, simplifies
-   many of the other routines */
-int page_jump(struct mapped_mtd_info *map,unsigned long start,
-	      unsigned long len,unsigned long *base,
-	      unsigned long *retlen)
-{
-   DEBUG(1,"Page Jump\n");
-   if (start > map->mtd.size || start + len > map->mtd.size)
-      return -EINVAL;
-      
-   *base = map->page(map,start/map->pagesize);
-   if (*base == 0)
-      return -EIO;
-
-   *base += start % map->pagesize;
-
-   // If retlen is 0 that mean the caller requires len bytes, no quibbling.
-   if (retlen == 0)
-   {
-      if (len > map->pagesize  - (start % map->pagesize))
-	 return -EIO;
-      return 0;
-   }
-   
-   // Compute the buffer paramaters and return
-   if (len > map->pagesize - (start % map->pagesize))
-      *retlen = map->pagesize - (start % map->pagesize);
-   else
-      *retlen = len;
-   return 0;
-}
-									/*}}}*/
-// flash_chip_scan - Intersect a region with the flash chip structure	/*{{{*/
-// ---------------------------------------------------------------------
-/* This is used to enhance the speed of the erase routine,
-   when things are being done to multiple chips it is possible to
-   parallize the operations, particularly full memory erases of multi
-   chip memories benifit */
-
-void flash_chip_scan(struct mapped_mtd_info *map,unsigned long start,
-		     unsigned long len)
-{
-   unsigned int I = 0;
-
-   DEBUG(1,"\n");
-   // Zero the records
-   for (I = 0; map->chips[I].jedec != 0; I++)
-      map->chips[I].start = map->chips[I].length = 0;
-   
-   // Intesect our region with the chip structures
-   for (I = 0; map->chips[I].jedec != 0 && len != 0; I++)
-   {
-      // Havent found the start yet
-      if (start >= map->chips[I].base + map->chips[I].size)
-	 continue;
-
-      // Store the portion of this chip that is being effected
-      map->chips[I].start = start - map->chips[I].base;
-      if (len <= map->chips[I].size - map->chips[I].start)
-	 map->chips[I].length = len;
-      else
-	 map->chips[I].length = map->chips[I].size - map->chips[I].start;
-      len -= map->chips[I].length;
-      start = map->chips[I].base + map->chips[I].size;
-   }
-}
-									/*}}}*/
-
diff -urN linux-2.4.2-pre1/drivers/mtd/mtdchar.c linux/drivers/mtd/mtdchar.c
--- linux-2.4.2-pre1/drivers/mtd/mtdchar.c	Fri Dec 29 14:07:22 2000
+++ linux/drivers/mtd/mtdchar.c	Mon Dec  3 22:27:48 2001
@@ -1,6 +1,5 @@
 /*
- * Almost: $Id: mtdchar.c,v 1.21 2000/12/09 21:15:12 dwmw2 Exp $
- * (With some of the compatibility for previous kernels taken out)
+ * $Id: mtdchar.c,v 1.21.2.3 2001/01/09 00:18:31 dwmw2 Exp $
  *
  * Character-device access to raw MTD devices.
  *
@@ -447,10 +446,6 @@
 mod_init_t init_mtdchar(void)
 {
 #ifdef CONFIG_DEVFS_FS
-	int i;
-	char name[8];
-	struct mtd_info* mtd;
-
 	if (devfs_register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops))
 	{
 		printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
diff -urN linux-2.4.2-pre1/drivers/mtd/nftlmount.c linux/drivers/mtd/nftlmount.c
--- linux-2.4.2-pre1/drivers/mtd/nftlmount.c	Fri Dec 29 14:07:22 2000
+++ linux/drivers/mtd/nftlmount.c	Mon Dec  3 22:27:48 2001
@@ -118,7 +118,7 @@
 				break;
 			}
 		}
-	ReplUnitTable:
+	ReplUnitTable:;
 	}
 
 	if (boot_record_count == 0) {
@@ -652,7 +652,7 @@
 				}
 			}
 		}
-	examine_ReplUnitTable:
+	examine_ReplUnitTable:;
 	}
 
 	/* second pass to format unreferenced blocks  and init free block count */
diff -urN linux-2.4.2-pre1/drivers/mtd/pmc551.c linux/drivers/mtd/pmc551.c
--- linux-2.4.2-pre1/drivers/mtd/pmc551.c	Sun Dec  3 17:45:22 2000
+++ linux/drivers/mtd/pmc551.c	Mon Dec  3 22:27:48 2001
@@ -804,6 +804,7 @@
 
                 if (add_mtd_device(mtd)) {
                         printk(KERN_NOTICE "pmc551: Failed to register new device\n");
+			iounmap(priv->start);
                         kfree(mtd->priv);
                         kfree(mtd);
                         break;
diff -urN linux-2.4.2-pre1/drivers/mtd/rpxlite.c linux/drivers/mtd/rpxlite.c
--- linux-2.4.2-pre1/drivers/mtd/rpxlite.c	Mon Dec 11 14:57:58 2000
+++ linux/drivers/mtd/rpxlite.c	Mon Dec  3 22:27:48 2001
@@ -94,6 +94,7 @@
 		return 0;
 	}
 
+	iounmap((void *)rpxlite_map.map_priv_1);
 	return -ENXIO;
 }
 
diff -urN linux-2.4.2-pre1/drivers/mtd/slram.c linux/drivers/mtd/slram.c
--- linux-2.4.2-pre1/drivers/mtd/slram.c	Tue Jul  4 10:10:05 2000
+++ linux/drivers/mtd/slram.c	Mon Dec  3 22:27:48 2001
@@ -200,6 +200,7 @@
 	if (add_mtd_device(mymtd))
 	{
 		printk("Failed to register new device\n");
+	        iounmap(((struct mypriv *)mymtd->priv)->start);
 		kfree(mymtd->priv);
 		kfree(mymtd);
 		return -EAGAIN;
diff -urN linux-2.4.2-pre1/drivers/mtd/vmax301.c linux/drivers/mtd/vmax301.c
--- linux-2.4.2-pre1/drivers/mtd/vmax301.c	Mon Dec 11 14:57:58 2000
+++ linux/drivers/mtd/vmax301.c	Mon Dec  3 22:27:48 2001
@@ -228,8 +228,10 @@
 		}
 	}
 
-	if (!vmax_mtd[1] && !vmax_mtd[2])
+	if (!vmax_mtd[1] && !vmax_mtd[2]) {
+		iounmap(iomapadr);
 		return -ENXIO;
+	}
 
 	return 0;
 }
diff -urN linux-2.4.2-pre1/drivers/net/8390.c linux/drivers/net/8390.c
--- linux-2.4.2-pre1/drivers/net/8390.c	Thu Jan  4 13:00:55 2001
+++ linux/drivers/net/8390.c	Mon Dec  3 22:27:48 2001
@@ -6,7 +6,7 @@
 	Director, National Security Agency.
 
 	This software may be used and distributed according to the terms
-	of the GNU Public License, incorporated herein by reference.
+	of the GNU General Public License, incorporated herein by reference.
 
 	The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
 	Center of Excellence in Space Data and Information Sciences
@@ -742,6 +742,7 @@
 				ei_block_input(dev, pkt_len, skb, current_offset + sizeof(rx_frame));
 				skb->protocol=eth_type_trans(skb,dev);
 				netif_rx(skb);
+				dev->last_rx = jiffies;
 				ei_local->stat.rx_packets++;
 				ei_local->stat.rx_bytes += pkt_len;
 				if (pkt_stat & ENRSR_PHY)
diff -urN linux-2.4.2-pre1/drivers/net/8390.h linux/drivers/net/8390.h
--- linux-2.4.2-pre1/drivers/net/8390.h	Mon Jan 29 23:26:09 2001
+++ linux/drivers/net/8390.h	Mon Dec  3 22:27:48 2001
@@ -45,10 +45,6 @@
 extern unsigned long autoirq_report(int waittime);
 #endif
 
-/* Currently unused - delete in v2.5.x after purging from drivers */
-#define load_8390_module(driver)	0
-#define unload_8390_module()		do { } while (0)
-
 extern int ethdev_init(struct net_device *dev);
 extern void NS8390_init(struct net_device *dev, int startp);
 extern int ei_open(struct net_device *dev);
@@ -67,7 +63,8 @@
 	unsigned char mcfilter[8];
 	unsigned open:1;
 	unsigned word16:1;  		/* We have the 16-bit (vs 8-bit) version of the card. */
-	unsigned bigendian:1;		/* 16-bit big endian mode */
+	unsigned bigendian:1;		/* 16-bit big endian mode. Do NOT */
+					/* set this on random 8390 clones! */
 	unsigned txing:1;		/* Transmit Active */
 	unsigned irqlock:1;		/* 8390's intrs disabled when '1'. */
 	unsigned dmaing:1;		/* Remote DMA Active */
diff -urN linux-2.4.2-pre1/drivers/net/Space.c linux/drivers/net/Space.c
--- linux-2.4.2-pre1/drivers/net/Space.c	Thu Jan  4 13:00:55 2001
+++ linux/drivers/net/Space.c	Mon Dec  3 22:27:48 2001
@@ -640,47 +640,6 @@
 #define	NEXT_DEV	(&sbni0_dev)
 #endif 
 	
-/* S/390 channels */
-#ifdef CONFIG_CTC
-    extern int ctc_probe(struct net_device *dev);
-    static struct net_device ctc7_dev =
-       {"ctc7", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV,  ctc_probe};
-    static struct net_device ctc6_dev =
-       {"ctc6", 0, 0, 0, 0, 0, 0, 0, 0, 0, &ctc7_dev, ctc_probe};
-    static struct net_device ctc5_dev =
-       {"ctc5", 0, 0, 0, 0, 0, 0, 0, 0, 0, &ctc6_dev, ctc_probe};
-    static struct net_device ctc4_dev =
-       {"ctc4", 0, 0, 0, 0, 0, 0, 0, 0, 0, &ctc5_dev, ctc_probe};
-    static struct net_device ctc3_dev =
-       {"ctc3", 0, 0, 0, 0, 0, 0, 0, 0, 0, &ctc4_dev, ctc_probe};
-    static struct net_device ctc2_dev =
-       {"ctc2", 0, 0, 0, 0, 0, 0, 0, 0, 0, &ctc3_dev, ctc_probe};
-    static struct net_device ctc1_dev =
-       {"ctc1", 0, 0, 0, 0, 0, 0, 0, 0, 0, &ctc2_dev, ctc_probe};
-    static struct net_device ctc0_dev =
-       {"ctc0", 0, 0, 0, 0, 0, 0, 0, 0, 0, &ctc1_dev, ctc_probe}; 
-
-    static struct net_device escon7_dev =
-       {"escon7", 0, 0, 0, 0, 0, 0, 0, 0, 0, &ctc0_dev,   ctc_probe};
-    static struct net_device escon6_dev =
-       {"escon6", 0, 0, 0, 0, 0, 0, 0, 0, 0, &escon7_dev, ctc_probe};
-    static struct net_device escon5_dev =
-       {"escon5", 0, 0, 0, 0, 0, 0, 0, 0, 0, &escon6_dev, ctc_probe};
-    static struct net_device escon4_dev =
-       {"escon4", 0, 0, 0, 0, 0, 0, 0, 0, 0, &escon5_dev, ctc_probe};
-    static struct net_device escon3_dev =
-       {"escon3", 0, 0, 0, 0, 0, 0, 0, 0, 0, &escon4_dev, ctc_probe};
-    static struct net_device escon2_dev =
-       {"escon2", 0, 0, 0, 0, 0, 0, 0, 0, 0, &escon3_dev, ctc_probe};
-    static struct net_device escon1_dev =
-       {"escon1", 0, 0, 0, 0, 0, 0, 0, 0, 0, &escon2_dev, ctc_probe};
-    static struct net_device escon0_dev =
-       {"escon0", 0, 0, 0, 0, 0, 0, 0, 0, 0, &escon1_dev, ctc_probe}; 
-
-#undef  NEXT_DEV
-#define NEXT_DEV        (&escon0_dev)                                  
-#endif  
-
 /*
  *	The loopback device is global so it can be directly referenced
  *	by the network code. Also, it must be first on device list.
diff -urN linux-2.4.2-pre1/drivers/net/eepro100.c linux/drivers/net/eepro100.c
--- linux-2.4.2-pre1/drivers/net/eepro100.c	Sat Jan 27 10:40:14 2001
+++ linux/drivers/net/eepro100.c	Mon Dec  3 22:27:48 2001
@@ -10,7 +10,7 @@
 	Please use this email address and linux-kernel mailing list for bug reports.
 
 	This software may be used and distributed according to the terms
-	of the GNU Public License, incorporated herein by reference.
+	of the GNU General Public License, incorporated herein by reference.
 
 	This driver is for the Intel EtherExpress Pro100 (Speedo3) design.
 	It should work with all i82557/558/559 boards.
@@ -475,7 +475,7 @@
 	struct speedo_mc_block *mc_setup_tail;/* Multicast setup frame list tail. */
 	int in_interrupt;					/* Word-aligned dev->interrupt */
 	unsigned char acpi_pwr;
-	char rx_mode;						/* Current PROMISC/ALLMULTI setting. */
+	signed char rx_mode;					/* Current PROMISC/ALLMULTI setting. */
 	unsigned int tx_full:1;				/* The Tx queue is full. */
 	unsigned int full_duplex:1;			/* Full-duplex operation requested. */
 	unsigned int flow_ctrl:1;			/* Use 802.3x flow control. */
@@ -725,7 +725,7 @@
 		/* The self-test results must be paragraph aligned. */
 		volatile s32 *self_test_results;
 		int boguscnt = 16000;	/* Timeout for set-test. */
-		if (eeprom[3] & 0x03)
+		if ((eeprom[3] & 0x03) != 0x03)
 			printk(KERN_INFO "  Receiver lock-up bug exists -- enabling"
 				   " work-around.\n");
 		printk(KERN_INFO "  Board assembly %4.4x%2.2x-%3.3d, Physical"
diff -urN linux-2.4.2-pre1/drivers/net/ewrk3.c linux/drivers/net/ewrk3.c
--- linux-2.4.2-pre1/drivers/net/ewrk3.c	Mon Dec 11 13:38:29 2000
+++ linux/drivers/net/ewrk3.c	Mon Dec  3 22:27:48 2001
@@ -5,7 +5,7 @@
    Copyright 1994 Digital Equipment Corporation.
 
    This software may be used and distributed according to the terms of
-   the GNU Public License, incorporated herein by reference.
+   the GNU General Public License, incorporated herein by reference.
 
    This driver is written for the Digital Equipment Corporation series
    of EtherWORKS ethernet cards:
@@ -819,24 +819,24 @@
 					}
 					outb(page, EWRK3_TQ);	/* Start sending pkt */
 				} else {
-					writeb((char) (TCR_QMODE | TCR_PAD | TCR_IFC), (char *) buf);	/* ctrl byte */
+					isa_writeb((char) (TCR_QMODE | TCR_PAD | TCR_IFC), buf);	/* ctrl byte */
 					buf += 1;
-					writeb((char) (skb->len & 0xff), (char *) buf);		/* length (16 bit xfer) */
+					isa_writeb((char) (skb->len & 0xff), buf);		/* length (16 bit xfer) */
 					buf += 1;
 					if (lp->txc) {
-						writeb((char) (((skb->len >> 8) & 0xff) | XCT), (char *) buf);
+						isa_writeb((char) (((skb->len >> 8) & 0xff) | XCT), buf);
 						buf += 1;
-						writeb(0x04, (char *) buf);	/* index byte */
+						isa_writeb(0x04, buf);	/* index byte */
 						buf += 1;
-						writeb(0x00, (char *) (buf + skb->len));	/* Write the XCT flag */
+						isa_writeb(0x00, (buf + skb->len));	/* Write the XCT flag */
 						isa_memcpy_toio(buf, skb->data, PRELOAD);	/* Write PRELOAD bytes */
 						outb(page, EWRK3_TQ);	/* Start sending pkt */
 						isa_memcpy_toio(buf + PRELOAD, skb->data + PRELOAD, skb->len - PRELOAD);
-						writeb(0xff, (char *) (buf + skb->len));	/* Write the XCT flag */
+						isa_writeb(0xff, (buf + skb->len));	/* Write the XCT flag */
 					} else {
-						writeb((char) ((skb->len >> 8) & 0xff), (char *) buf);
+						isa_writeb((char) ((skb->len >> 8) & 0xff), buf);
 						buf += 1;
-						writeb(0x04, (char *) buf);	/* index byte */
+						isa_writeb(0x04, buf);	/* index byte */
 						buf += 1;
 						isa_memcpy_toio(buf, skb->data, skb->len);		/* Write data bytes */
 						outb(page, EWRK3_TQ);	/* Start sending pkt */
@@ -968,9 +968,9 @@
 					pkt_len = inb(EWRK3_DATA);
 					pkt_len |= ((u_short) inb(EWRK3_DATA) << 8);
 				} else {
-					rx_status = readb(buf);
+					rx_status = isa_readb(buf);
 					buf += 1;
-					pkt_len = readw(buf);
+					pkt_len = isa_readw(buf);
 					buf += 3;
 				}
 
@@ -1010,6 +1010,7 @@
 						/*
 						   ** Update stats
 						 */
+						dev->last_rx = jiffies;
 						lp->stats.rx_packets++;
 						lp->stats.rx_bytes += pkt_len;
 						for (i = 1; i < EWRK3_PKT_STAT_SZ - 1; i++) {
@@ -1204,7 +1205,7 @@
 			if (lp->shmem_length == IO_ONLY) {
 				outb(0xff, EWRK3_DATA);
 			} else {	/* memset didn't work here */
-				writew(0xffff, p);
+				isa_writew(0xffff, (int) p);
 				p++;
 				i++;
 			}
@@ -1221,8 +1222,8 @@
 				outb(0x00, EWRK3_DATA);
 			}
 		} else {
-			memset_io(lp->mctbl, 0, (HASH_TABLE_LEN >> 3));
-			writeb(0x80, (char *) (lp->mctbl + (HASH_TABLE_LEN >> 4) - 1));
+			isa_memset_io((int) lp->mctbl, 0, (HASH_TABLE_LEN >> 3));
+			isa_writeb(0x80, (int) (lp->mctbl + (HASH_TABLE_LEN >> 4) - 1));
 		}
 
 		/* Update table */
@@ -1251,7 +1252,7 @@
 					outw((short) ((long) lp->mctbl) + byte, EWRK3_PIR1);
 					outb(tmp, EWRK3_DATA);
 				} else {
-					writeb(readb(lp->mctbl + byte) | bit, lp->mctbl + byte);
+					isa_writeb(isa_readb((int)(lp->mctbl + byte)) | bit, (int)(lp->mctbl + byte));
 				}
 			}
 		}
diff -urN linux-2.4.2-pre1/drivers/net/ewrk3.h linux/drivers/net/ewrk3.h
--- linux-2.4.2-pre1/drivers/net/ewrk3.h	Thu Apr 11 23:49:37 1996
+++ linux/drivers/net/ewrk3.h	Mon Dec  3 22:27:48 2001
@@ -4,7 +4,7 @@
     Copyright 1994 Digital Equipment Corporation.
 
     This software may be used and distributed according to  the terms of the
-    GNU Public License, incorporated herein by reference.
+    GNU General Public License, incorporated herein by reference.
 
     The author may    be  reached as davies@wanton.lkg.dec.com  or   Digital
     Equipment Corporation, 550 King Street, Littleton MA 01460.
diff -urN linux-2.4.2-pre1/drivers/net/hamradio/6pack.c linux/drivers/net/hamradio/6pack.c
--- linux-2.4.2-pre1/drivers/net/hamradio/6pack.c	Thu Jan  4 12:50:12 2001
+++ linux/drivers/net/hamradio/6pack.c	Mon Dec  3 22:27:48 2001
@@ -32,7 +32,6 @@
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
 #include <linux/if_arp.h>
-#include <linux/if_slip.h>
 #include <linux/init.h>
 #include <linux/ip.h>
 #include <linux/tcp.h>
@@ -75,7 +74,7 @@
 #define SIXP_RESYNC_TIMEOUT		500	/* in 10 ms */
 
 /* 6pack configuration. */
-#define SIXP_NRUNIT			256	/* MAX number of 6pack channels */
+#define SIXP_NRUNIT			31      /* MAX number of 6pack channels */
 #define SIXP_MTU			256	/* Default MTU */
 
 enum sixpack_flags {
@@ -128,20 +127,18 @@
 	struct timer_list	resync_t;
 };
 
-/* should later be moved to include/net/ax25.h */
 #define AX25_6PACK_HEADER_LEN 0
 #define SIXPACK_MAGIC 0x5304
 
-static const char banner[] __initdata = KERN_INFO "AX.25: 6pack driver, " SIXPACK_VERSION " (dynamic channels, max=%d)\n";
-
 typedef struct sixpack_ctrl {
-	struct sixpack	ctrl;		/* 6pack things			*/
+	struct sixpack	ctrl;			/* 6pack things			*/
 	struct net_device	dev;		/* the device			*/
 } sixpack_ctrl_t;
 static sixpack_ctrl_t **sixpack_ctrls;
-int sixpack_maxdev = SIXP_NRUNIT;	/* Can be overridden with insmod! */
 
-static struct tty_ldisc	sp_ldisc;
+int sixpack_maxdev = SIXP_NRUNIT;	/* Can be overridden with insmod! */
+MODULE_PARM(sixpack_maxdev, "i");
+MODULE_PARM_DESC(sixpack_maxdev, "number of 6PACK devices");
 
 static void sp_start_tx_timer(struct sixpack *);
 static void sp_xmit_on_air(unsigned long);
@@ -687,52 +684,67 @@
 	return 0;
 }
 
+/* Fill in our line protocol discipline */
+static struct tty_ldisc sp_ldisc = {
+	magic:		TTY_LDISC_MAGIC,
+	name:		"6pack",
+	open:		sixpack_open,
+	close:		sixpack_close,
+	ioctl:		(int (*)(struct tty_struct *, struct file *,
+			unsigned int, unsigned long)) sixpack_ioctl,
+	receive_buf:	sixpack_receive_buf,
+	receive_room:	sixpack_receive_room,
+	write_wakeup:	sixpack_write_wakeup,
+};
+
 /* Initialize 6pack control device -- register 6pack line discipline */
 
+static const char msg_banner[]  __initdata = KERN_INFO "AX.25: 6pack driver, " SIXPACK_VERSION " (dynamic channels, max=%d)\n";
+static const char msg_invparm[] __initdata = KERN_ERR  "6pack: sixpack_maxdev parameter too large.\n";
+static const char msg_nomem[]   __initdata = KERN_ERR  "6pack: can't allocate sixpack_ctrls[] array! No 6pack available.\n";
+static const char msg_regfail[] __initdata = KERN_ERR  "6pack: can't register line discipline (err = %d)\n";
+
 static int __init sixpack_init_driver(void)
 {
 	int status;
 
+	/* Do sanity checks on maximum device parameter. */
 	if (sixpack_maxdev < 4)
-		sixpack_maxdev = 4; /* Sanity */
+		sixpack_maxdev = 4;
+	if (sixpack_maxdev * sizeof(void*) >= KMALLOC_MAXSIZE) {
+	        printk(msg_invparm);
+		return -ENFILE;
+	}
 
-	printk(banner, sixpack_maxdev);
+	printk(msg_banner, sixpack_maxdev);
 
 	sixpack_ctrls = (sixpack_ctrl_t **) kmalloc(sizeof(void*)*sixpack_maxdev, GFP_KERNEL);
 	if (sixpack_ctrls == NULL) {
-		printk(KERN_WARNING "6pack: Can't allocate sixpack_ctrls[] array!  Uaargh! (-> No 6pack available)\n");
+		printk(msg_nomem);
 		return -ENOMEM;
 	}
 
 	/* Clear the pointer array, we allocate devices when we need them */
 	memset(sixpack_ctrls, 0, sizeof(void*)*sixpack_maxdev); /* Pointers */
 
-	/* Fill in our line protocol discipline, and register it */
-	sp_ldisc.magic  = TTY_LDISC_MAGIC;
-	sp_ldisc.name   = "6pack";
-	sp_ldisc.flags  = 0;
-	sp_ldisc.open   = sixpack_open;
-	sp_ldisc.close  = sixpack_close;
-	sp_ldisc.read   = NULL;
-	sp_ldisc.write  = NULL;
-	sp_ldisc.ioctl  = (int (*)(struct tty_struct *, struct file *,
-				   unsigned int, unsigned long)) sixpack_ioctl;
-	sp_ldisc.poll = NULL;
-	sp_ldisc.receive_buf = sixpack_receive_buf;
-	sp_ldisc.receive_room = sixpack_receive_room;
-	sp_ldisc.write_wakeup = sixpack_write_wakeup;
-	if ((status = tty_register_ldisc(N_6PACK, &sp_ldisc)) != 0)  {
-		printk(KERN_WARNING "6pack: can't register line discipline (err = %d)\n", status);
+	/* Register the provided line protocol discipline */
+	if ((status = tty_register_ldisc(N_6PACK, &sp_ldisc)) != 0) {
+		printk(msg_regfail, status);
 		kfree(sixpack_ctrls);
 	}
 
 	return status;
 }
 
-static void __exit sixpack_cleanup_driver(void)
+static const char msg_unregfail[] __exitdata = KERN_ERR "6pack: can't unregister line discipline (err = %d)\n";
+
+static void __exit sixpack_exit_driver(void)
 {
 	int i;
 
+	if ((i = tty_register_ldisc(N_6PACK, NULL)))
+		printk(msg_unregfail, i);
+
 	for (i = 0; i < sixpack_maxdev; i++) {
 		if (sixpack_ctrls[i]) {
 			/*
@@ -746,8 +758,6 @@
 		}
 	}
 	kfree(sixpack_ctrls);
-	if ((i = tty_register_ldisc(N_6PACK, NULL)))
-		printk(KERN_WARNING "6pack: can't unregister line discipline (err = %d)\n", i);
 }
 
 
@@ -1059,8 +1069,6 @@
 
 MODULE_AUTHOR("Andreas Könsgen <ajk@ccac.rwth-aachen.de>");
 MODULE_DESCRIPTION("6pack driver for AX.25");
-MODULE_PARM(sixpack_maxdev, "i");
-MODULE_PARM_DESC(sixpack_maxdev, "number of 6PACK devices");
 
 module_init(sixpack_init_driver);
-module_exit(sixpack_cleanup_driver);
+module_exit(sixpack_exit_driver);
diff -urN linux-2.4.2-pre1/drivers/net/hamradio/scc.c linux/drivers/net/hamradio/scc.c
--- linux-2.4.2-pre1/drivers/net/hamradio/scc.c	Mon Jan 22 13:32:10 2001
+++ linux/drivers/net/hamradio/scc.c	Mon Dec  3 22:27:48 2001
@@ -1776,7 +1776,7 @@
 
 			if (hwcfg.vector_latch) {
 				if (!request_region(Vector_Latch, 1, "scc vector latch"))
-					printk(KERN_WARNING "z8530drv: warning, cannot reserve vector latch port 0x%x\n, disabled.", (unsigned int)hwcfg.vector_latch);
+					printk(KERN_WARNING "z8530drv: warning, cannot reserve vector latch port 0x%lx\n, disabled.", hwcfg.vector_latch);
 				else
 					Vector_Latch = hwcfg.vector_latch;
 			}
diff -urN linux-2.4.2-pre1/drivers/net/hamradio/yam.c linux/drivers/net/hamradio/yam.c
--- linux-2.4.2-pre1/drivers/net/hamradio/yam.c	Fri Dec 29 14:35:47 2000
+++ linux/drivers/net/hamradio/yam.c	Mon Dec  3 22:27:48 2001
@@ -878,7 +878,6 @@
 
 	printk(KERN_INFO "%s at iobase 0x%lx irq %u uart %s\n", dev->name, dev->base_addr, dev->irq,
 		   uart_str[u]);
-	MOD_INC_USE_COUNT;
 	return 0;
 }
 
@@ -905,7 +904,6 @@
 
 	printk(KERN_INFO "%s: close yam at iobase 0x%lx irq %u\n",
 		   yam_drvname, dev->base_addr, dev->irq);
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
@@ -938,14 +936,17 @@
 	case SIOCYAMSMCS:
 		if (netif_running(dev))
 			return -EINVAL;		/* Cannot change this parameter when up */
-		ym = kmalloc(sizeof(struct yamdrv_ioctl_mcs), GFP_KERNEL);
-		if(ym==NULL)
+		if ((ym = kmalloc(sizeof(struct yamdrv_ioctl_mcs), GFP_KERNEL)) == NULL)
 			return -ENOBUFS;
 		ym->bitrate = 9600;
-		if (copy_from_user(ym, ifr->ifr_data, sizeof(struct yamdrv_ioctl_mcs)))
-			 return -EFAULT;
-		if (ym->bitrate > YAM_MAXBITRATE)
+		if (copy_from_user(ym, ifr->ifr_data, sizeof(struct yamdrv_ioctl_mcs))) {
+			kfree(ym);
+			return -EFAULT;
+		}
+		if (ym->bitrate > YAM_MAXBITRATE) {
+			kfree(ym);
 			return -EINVAL;
+		}
 		add_mcs(ym->bits, ym->bitrate);
 		kfree(ym);
 		break;
@@ -1129,8 +1130,11 @@
 
 		if (register_netdev(dev)) {
 			printk(KERN_WARNING "yam: cannot register net device %s\n", dev->name);
+			dev->priv = NULL;
 			return -ENXIO;
 		}
+
+		SET_MODULE_OWNER(dev);
 	}
 
 	yam_timer.function = yam_dotimer;
diff -urN linux-2.4.2-pre1/drivers/net/hydra.c linux/drivers/net/hydra.c
--- linux-2.4.2-pre1/drivers/net/hydra.c	Thu Jan  4 13:00:55 2001
+++ linux/drivers/net/hydra.c	Mon Dec  3 22:27:48 2001
@@ -82,9 +82,6 @@
     unsigned long board;
     int err = -ENODEV;
 
-    if (load_8390_module("hydra.c"))
-	return -ENOSYS;
-
     while ((z = zorro_find_device(ZORRO_PROD_HYDRA_SYSTEMS_AMIGANET, z))) {
 	board = z->resource.start;
 	if (!request_mem_region(board, 0x10000, "Hydra"))
@@ -96,10 +93,9 @@
 	err = 0;
     }
 
-    if (err == -ENODEV) {
+    if (err == -ENODEV)
 	printk("No Hydra ethernet card found.\n");
-	unload_8390_module();
-    }
+
     return err;
 }
 
@@ -116,9 +112,10 @@
 	0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
     };
 
-    dev = init_etherdev(0, 0);
+    dev = init_etherdev(NULL, 0);
     if (!dev)
 	return -ENOMEM;
+    SET_MODULE_OWNER(dev);
 
     for(j = 0; j < ETHER_ADDR_LEN; j++)
 	dev->dev_addr[j] = *((u8 *)(board + HYDRA_ADDRPROM + 2*j));
@@ -174,7 +171,6 @@
 static int hydra_open(struct net_device *dev)
 {
     ei_open(dev);
-    MOD_INC_USE_COUNT;
     return 0;
 }
 
@@ -183,7 +179,6 @@
     if (ei_debug > 1)
 	printk("%s: Shutting down ethercard.\n", dev->name);
     ei_close(dev);
-    MOD_DEC_USE_COUNT;
     return 0;
 }
 
@@ -254,7 +249,6 @@
 	kfree(dev);
 	root_hydra_dev = next;
     }
-    unload_8390_module();
 #endif
 }
 
diff -urN linux-2.4.2-pre1/drivers/net/irda/irport.c linux/drivers/net/irda/irport.c
--- linux-2.4.2-pre1/drivers/net/irda/irport.c	Sun Nov 12 20:43:07 2000
+++ linux/drivers/net/irda/irport.c	Mon Dec  3 22:27:48 2001
@@ -616,7 +616,7 @@
 	struct irport_cb *self;
 	unsigned long flags;
 	int iobase;
-	__u32 speed;
+	__s32 speed;
 
 	ASSERT(dev != NULL, return 0;);
 	
@@ -628,12 +628,14 @@
 	netif_stop_queue(dev);
 	
 	/* Check if we need to change the speed */
-	if ((speed = irda_get_speed(skb)) != self->io.speed) {
+	speed = irda_get_next_speed(skb);
+	if ((speed != self->io.speed) && (speed != -1)) {
 		/* Check for empty frame */
 		if (!skb->len) {
 			irda_task_execute(self, __irport_change_speed, 
 					  irport_change_speed_complete, 
 					  NULL, (void *) speed);
+			dev_kfree_skb(skb);
 			return 0;
 		} else
 			self->new_speed = speed;
diff -urN linux-2.4.2-pre1/drivers/net/irda/irtty.c linux/drivers/net/irda/irtty.c
--- linux-2.4.2-pre1/drivers/net/irda/irtty.c	Mon Nov 27 18:07:31 2000
+++ linux/drivers/net/irda/irtty.c	Mon Dec  3 22:27:48 2001
@@ -279,6 +279,11 @@
 	tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
 	tty->disc_data = 0;
 	
+	/* We are not using any dongle anymore! */
+	if (self->dongle)
+		irda_device_dongle_cleanup(self->dongle);
+	self->dongle = NULL;
+
 	/* Remove netdevice */
 	if (self->netdev) {
 		rtnl_lock();
@@ -286,11 +291,6 @@
 		rtnl_unlock();
 	}
 	
-	/* We are not using any dongle anymore! */
-	if (self->dongle)
-		irda_device_dongle_cleanup(self->dongle);
-	self->dongle = NULL;
-
 	/* Remove speed changing task if any */
 	if (self->task)
 		irda_task_delete(self->task);
@@ -629,7 +629,7 @@
 {
 	struct irtty_cb *self;
 	int actual = 0;
-	__u32 speed;
+	__s32 speed;
 
 	self = (struct irtty_cb *) dev->priv;
 	ASSERT(self != NULL, return 0;);
@@ -638,12 +638,14 @@
 	netif_stop_queue(dev);
 	
 	/* Check if we need to change the speed */
-	if ((speed = irda_get_speed(skb)) != self->io.speed) {
+	speed = irda_get_next_speed(skb);
+	if ((speed != self->io.speed) && (speed != -1)) {
 		/* Check for empty frame */
 		if (!skb->len) {
 			irda_task_execute(self, irtty_change_speed, 
 					  irtty_change_speed_complete, 
 					  NULL, (void *) speed);
+			dev_kfree_skb(skb);
 			return 0;
 		} else
 			self->new_speed = speed;
diff -urN linux-2.4.2-pre1/drivers/net/irda/nsc-ircc.c linux/drivers/net/irda/nsc-ircc.c
--- linux-2.4.2-pre1/drivers/net/irda/nsc-ircc.c	Mon Nov 27 18:07:31 2000
+++ linux/drivers/net/irda/nsc-ircc.c	Mon Dec  3 22:27:48 2001
@@ -1064,7 +1064,7 @@
 	struct nsc_ircc_cb *self;
 	unsigned long flags;
 	int iobase;
-	__u32 speed;
+	__s32 speed;
 	__u8 bank;
 	
 	self = (struct nsc_ircc_cb *) dev->priv;
@@ -1076,10 +1076,12 @@
 	netif_stop_queue(dev);
 		
 	/* Check if we need to change the speed */
-	if ((speed = irda_get_speed(skb)) != self->io.speed) {
+	speed = irda_get_next_speed(skb);
+	if ((speed != self->io.speed) && (speed != -1)) {
 		/* Check for empty frame */
 		if (!skb->len) {
 			nsc_ircc_change_speed(self, speed); 
+			dev_kfree_skb(skb);
 			return 0;
 		} else
 			self->new_speed = speed;
@@ -1116,7 +1118,7 @@
 	struct nsc_ircc_cb *self;
 	unsigned long flags;
 	int iobase;
-	__u32 speed;
+	__s32 speed;
 	__u8 bank;
 	int mtt, diff;
 	
@@ -1126,10 +1128,12 @@
 	netif_stop_queue(dev);
 	
 	/* Check if we need to change the speed */
-	if ((speed = irda_get_speed(skb)) != self->io.speed) {
+	speed = irda_get_next_speed(skb);
+	if ((speed != self->io.speed) && (speed != -1)) {
 		/* Check for empty frame */
 		if (!skb->len) {
 			nsc_ircc_change_speed(self, speed); 
+			dev_kfree_skb(skb);
 			return 0;
 		} else
 			self->new_speed = speed;
@@ -1956,16 +1960,20 @@
 	/* Disable interrupts & save flags */
 	save_flags(flags);
 	cli();
-	
+
 	switch (cmd) {
 	case SIOCSBANDWIDTH: /* Set bandwidth */
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
+		if (!capable(CAP_NET_ADMIN)) {
+			ret = -EPERM;
+			goto out;
+		}
 		nsc_ircc_change_speed(self, irq->ifr_baudrate);
 		break;
 	case SIOCSMEDIABUSY: /* Set media busy */
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
+		if (!capable(CAP_NET_ADMIN)) {
+			ret = -EPERM;
+			goto out;
+		}
 		irda_device_set_media_busy(self->netdev, TRUE);
 		break;
 	case SIOCGRECEIVING: /* Check if we are receiving right now */
@@ -1974,9 +1982,8 @@
 	default:
 		ret = -EOPNOTSUPP;
 	}
-	
+out:
 	restore_flags(flags);
-	
 	return ret;
 }
 
diff -urN linux-2.4.2-pre1/drivers/net/irda/smc-ircc.c linux/drivers/net/irda/smc-ircc.c
--- linux-2.4.2-pre1/drivers/net/irda/smc-ircc.c	Fri Dec 29 14:07:22 2000
+++ linux/drivers/net/irda/smc-ircc.c	Mon Dec  3 22:27:48 2001
@@ -606,7 +606,7 @@
 	struct irport_cb *irport;
 	struct ircc_cb *self;
 	unsigned long flags;
-	__u32 speed;
+	__s32 speed;
 	int iobase;
 	int mtt;
 
@@ -619,10 +619,12 @@
 	netif_stop_queue(dev);
 
 	/* Check if we need to change the speed after this frame */
-	if ((speed = irda_get_speed(skb)) != self->io.speed) {
+	speed = irda_get_next_speed(skb);
+	if ((speed != self->io.speed) && (speed != -1)) {
 		/* Check for empty frame */
 		if (!skb->len) {
 			ircc_change_speed(self, speed); 
+			dev_kfree_skb(skb);
 			return 0;
 		} else
 			self->new_speed = speed;
diff -urN linux-2.4.2-pre1/drivers/net/irda/toshoboe.c linux/drivers/net/irda/toshoboe.c
--- linux-2.4.2-pre1/drivers/net/irda/toshoboe.c	Thu Jan  4 12:50:12 2001
+++ linux/drivers/net/irda/toshoboe.c	Mon Dec  3 22:27:48 2001
@@ -263,7 +263,7 @@
 toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev)
 {
   struct toshoboe_cb *self;
-  __u32 speed;
+  __s32 speed;
   int mtt, len;
 
   self = (struct toshoboe_cb *) dev->priv;
@@ -272,10 +272,12 @@
     );
 
   /* Check if we need to change the speed */
-  if ((speed = irda_get_speed(skb)) != self->io.speed) {
+  speed = irda_get_next_speed(skb);
+  if ((speed != self->io.speed) && (speed != -1)) {
 	/* Check for empty frame */
 	if (!skb->len) {
 	    toshoboe_setbaud(self, speed); 
+	    dev_kfree_skb(skb);
 	    return 0;
 	} else
 	    self->new_speed = speed;
diff -urN linux-2.4.2-pre1/drivers/net/irda/w83977af_ir.c linux/drivers/net/irda/w83977af_ir.c
--- linux-2.4.2-pre1/drivers/net/irda/w83977af_ir.c	Sat Nov 11 18:11:23 2000
+++ linux/drivers/net/irda/w83977af_ir.c	Mon Dec  3 22:27:48 2001
@@ -497,7 +497,7 @@
 int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct w83977af_ir *self;
-	__u32 speed;
+	__s32 speed;
 	int iobase;
 	__u8 set;
 	int mtt;
@@ -513,10 +513,12 @@
 	netif_stop_queue(dev);
 	
 	/* Check if we need to change the speed */
-	if ((speed = irda_get_speed(skb)) != self->io.speed) {
+	speed = irda_get_next_speed(skb);
+	if ((speed != self->io.speed) && (speed != -1)) {
 		/* Check for empty frame */
 		if (!skb->len) {
 			w83977af_change_speed(self, speed); 
+			dev_kfree_skb(skb);
 			return 0;
 		} else
 			self->new_speed = speed;
@@ -1337,13 +1339,17 @@
 	
 	switch (cmd) {
 	case SIOCSBANDWIDTH: /* Set bandwidth */
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
+		if (!capable(CAP_NET_ADMIN)) {
+			ret = -EPERM;
+			goto out;
+		}
 		w83977af_change_speed(self, irq->ifr_baudrate);
 		break;
 	case SIOCSMEDIABUSY: /* Set media busy */
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
+		if (!capable(CAP_NET_ADMIN)) {
+			ret = -EPERM;
+			goto out;
+		}
 		irda_device_set_media_busy(self->netdev, TRUE);
 		break;
 	case SIOCGRECEIVING: /* Check if we are receiving right now */
@@ -1352,9 +1358,8 @@
 	default:
 		ret = -EOPNOTSUPP;
 	}
-	
+out:
 	restore_flags(flags);
-	
 	return ret;
 }
 
diff -urN linux-2.4.2-pre1/drivers/net/natsemi.c linux/drivers/net/natsemi.c
--- linux-2.4.2-pre1/drivers/net/natsemi.c	Mon Dec 11 13:38:29 2000
+++ linux/drivers/net/natsemi.c	Mon Dec  3 22:27:48 2001
@@ -26,6 +26,11 @@
 		- Bug fixes and better intr performance (Tjeerd)
 	Version 1.0.2:
 		- Now reads correct MAC address from eeprom
+	Version 1.0.3:
+		- Eliminate redundant priv->tx_full flag
+		- Call netif_start_queue from dev->tx_timeout
+		- wmb() in start_tx() to flush data
+		- Update Tx locking
 
 */
 
@@ -35,7 +40,7 @@
 static const char version2[] =
 "  http://www.scyld.com/network/natsemi.html\n";
 static const char version3[] =
-"  (unofficial 2.4.x kernel port, version 1.0.2, October 6, 2000 Jeff Garzik, Tjeerd Mulder)\n";
+"  (unofficial 2.4.x kernel port, version 1.0.3, January 21, 2001 Jeff Garzik, Tjeerd Mulder)\n";
 /* Updated to recommendations in pci-skeleton v2.03. */
 
 /* Automatically extracted configuration info:
@@ -187,13 +192,14 @@
 
 The send packet thread has partial control over the Tx ring and 'dev->tbusy'
 flag.  It sets the tbusy flag whenever it's queuing a Tx packet. If the next
-queue slot is empty, it clears the tbusy flag when finished otherwise it sets
-the 'lp->tx_full' flag.
+queue slot is empty, it clears the tbusy flag when finished.  Under 2.4, the
+"tbusy flag" is now controlled by netif_{start,stop,wake}_queue() and tested
+by netif_queue_stopped().
 
 The interrupt handler has exclusive control over the Rx ring and records stats
 from the Tx ring.  After reaping the stats, it marks the Tx queue entry as
-empty by incrementing the dirty_tx mark. Iff the 'lp->tx_full' flag is set, it
-clears both the tx_full and tbusy flags.
+empty by incrementing the dirty_tx mark. Iff Tx queueing is stopped and Tx
+entries were reaped, the Tx queue is started and scheduled.
 
 IV. Notes
 
@@ -319,7 +325,6 @@
 	unsigned int cur_rx, dirty_rx;		/* Producer/consumer ring indices */
 	unsigned int cur_tx, dirty_tx;
 	unsigned int rx_buf_sz;				/* Based on MTU+slack. */
-	unsigned int tx_full:1;				/* The Tx queue is full. */
 	/* These values are keep track of the transceiver/media in use. */
 	unsigned int full_duplex:1;			/* Full-duplex operation requested. */
 	unsigned int duplex_lock:1;
@@ -697,7 +702,7 @@
 
 	dev->trans_start = jiffies;
 	np->stats.tx_errors++;
-	return;
+	netif_start_queue(dev);
 }
 
 
@@ -707,7 +712,6 @@
 	struct netdev_private *np = (struct netdev_private *)dev->priv;
 	int i;
 
-	np->tx_full = 0;
 	np->cur_rx = np->cur_tx = 0;
 	np->dirty_rx = np->dirty_tx = 0;
 
@@ -763,11 +767,13 @@
 	np->cur_tx++;
 
 	/* StrongARM: Explicitly cache flush np->tx_ring and skb->data,skb->len. */
+	wmb();
 
-	if (np->cur_tx - np->dirty_tx >= TX_QUEUE_LEN - 1) {
-		np->tx_full = 1;
+	spin_lock_irq(&np->lock);
+	if (np->cur_tx - np->dirty_tx >= TX_QUEUE_LEN - 1)
 		netif_stop_queue(dev);
-	}
+	spin_unlock_irq(&np->lock);
+
 	/* Wake the potentially-idle transmit channel. */
 	writel(TxOn, dev->base_addr + ChipCmd);
 
@@ -798,9 +804,7 @@
 #endif
 
 	ioaddr = dev->base_addr;
-	np = (struct netdev_private *)dev->priv;
-
-	spin_lock(&np->lock);
+	np = dev->priv;
 
 	do {
 		u32 intr_status = readl(ioaddr + IntrStatus);
@@ -818,6 +822,8 @@
 		if (intr_status & (IntrRxDone | IntrRxErr | IntrRxIdle | IntrRxOverrun))
 			netdev_rx(dev);
 
+		spin_lock(&np->lock);
+
 		for (; np->cur_tx - np->dirty_tx > 0; np->dirty_tx++) {
 			int entry = np->dirty_tx % TX_RING_SIZE;
 			if (np->tx_ring[entry].cmd_status & cpu_to_le32(DescOwn))
@@ -839,13 +845,14 @@
 			dev_kfree_skb_irq(np->tx_skbuff[entry]);
 			np->tx_skbuff[entry] = 0;
 		}
-		if (np->tx_full
+		if (netif_queue_stopped(dev)
 			&& np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 4) {
 			/* The ring is no longer full, wake queue. */
-			np->tx_full = 0;
 			netif_wake_queue(dev);
 		}
 
+		spin_unlock(&np->lock);
+
 		/* Abnormal error summary/uncommon events handlers. */
 		if (intr_status & IntrAbnormalSummary)
 			netdev_error(dev, intr_status);
@@ -873,8 +880,6 @@
 		}
 	}
 #endif
-
-	spin_unlock(&np->lock);
 }
 
 /* This routine is logically part of the interrupt handler, but separated
diff -urN linux-2.4.2-pre1/drivers/net/pcmcia/xirc2ps_cs.c linux/drivers/net/pcmcia/xirc2ps_cs.c
--- linux-2.4.2-pre1/drivers/net/pcmcia/xirc2ps_cs.c	Thu Oct 26 16:52:16 2000
+++ linux/drivers/net/pcmcia/xirc2ps_cs.c	Mon Dec  3 22:27:48 2001
@@ -2058,3 +2058,28 @@
 module_init(init_xirc2ps_cs);
 module_exit(exit_xirc2ps_cs);
 
+#ifndef MODULE
+static int __init setup_xirc2ps_cs(char *str)
+{
+	/* irq, irq_mask, if_port, full_duplex, do_sound, lockup_hack
+	 * [,irq2 [,irq3 [,irq4]]]
+	 */
+	int ints[10] = { -1 };
+
+	str = get_options(str, 9, ints);
+
+#define MAYBE_SET(X,Y) if (ints[0] >= Y && ints[Y] != -1) { X = ints[Y]; }
+	MAYBE_SET(irq_list[0], 1);
+	MAYBE_SET(irq_mask, 2);
+	MAYBE_SET(if_port, 3);
+	MAYBE_SET(full_duplex, 4);
+	MAYBE_SET(do_sound, 5);
+	MAYBE_SET(lockup_hack, 6);
+	MAYBE_SET(irq_list[1], 7);
+	MAYBE_SET(irq_list[2], 8);
+	MAYBE_SET(irq_list[3], 9);
+#undef  MAYBE_SET(X,Y)
+}
+
+__setup("xirc2ps_cs=", setup_xirc2ps_cs);
+#endif
diff -urN linux-2.4.2-pre1/drivers/net/pcnet32.c linux/drivers/net/pcnet32.c
--- linux-2.4.2-pre1/drivers/net/pcnet32.c	Sun Jan 28 13:28:09 2001
+++ linux/drivers/net/pcnet32.c	Mon Dec  3 22:27:48 2001
@@ -8,7 +8,7 @@
  *	Director, National Security Agency.
  * 
  *	This software may be used and distributed according to the terms
- *	of the GNU Public License, incorporated herein by reference.
+ *	of the GNU General Public License, incorporated herein by reference.
  *
  *	This driver is for PCnet32 and PCnetPCI based ethercards
  */
@@ -811,7 +811,7 @@
 	val |= 0x10;
     lp->a.write_csr (ioaddr, 124, val);
     
-    if (lp->mii & !(lp->options & PORT_ASEL)) {
+    if (lp->mii && !(lp->options & PORT_ASEL)) {
 	val = lp->a.read_bcr (ioaddr, 32) & ~0x38; /* disable Auto Negotiation, set 10Mpbs, HD */
 	if (lp->options & PORT_FD)
 	    val |= 0x10;
diff -urN linux-2.4.2-pre1/drivers/net/ppp_generic.c linux/drivers/net/ppp_generic.c
--- linux-2.4.2-pre1/drivers/net/ppp_generic.c	Tue Nov 28 21:53:45 2000
+++ linux/drivers/net/ppp_generic.c	Mon Dec  3 22:27:48 2001
@@ -1412,6 +1412,7 @@
 			skb->protocol = htons(npindex_to_ethertype[npi]);
 			skb->mac.raw = skb->data;
 			netif_rx(skb);
+			ppp->dev->last_rx = jiffies;
 		}
 	}
 	return;
@@ -2342,7 +2343,7 @@
 	write_lock_bh(&pch->upl);
 	ret = -EINVAL;
 	if (pch->ppp != 0)
-		goto outw;
+		goto outwl;
 	ppp_lock(ppp);
 	spin_lock_bh(&pch->downl);
 	if (pch->chan == 0)		/* need to check this?? */
@@ -2361,7 +2362,7 @@
  outr:
 	spin_unlock_bh(&pch->downl);
 	ppp_unlock(ppp);
- outw:
+ outwl:
 	write_unlock_bh(&pch->upl);
  out:
 	spin_unlock(&all_ppp_lock);
@@ -2408,7 +2409,7 @@
 	kfree(pch);
 }
 
-void __exit ppp_cleanup(void)
+static void __exit ppp_cleanup(void)
 {
 	/* should never happen */
 	if (!list_empty(&all_ppp_units) || !list_empty(&all_channels))
diff -urN linux-2.4.2-pre1/drivers/net/rclanmtl.c linux/drivers/net/rclanmtl.c
--- linux-2.4.2-pre1/drivers/net/rclanmtl.c	Mon Dec 11 13:04:09 2000
+++ linux/drivers/net/rclanmtl.c	Mon Dec  3 22:27:48 2001
@@ -36,15 +36,11 @@
 ** *************************************************************************
 */
 
-#undef DEBUG
+#define DEBUG 1
 
 #define RC_LINUX_MODULE
 #include "rclanmtl.h"
 
-#define dprintf kprintf
-
-extern int printk(const char * fmt, ...);
-
  /* RedCreek LAN device Target ID */
 #define RC_LAN_TARGET_ID  0x10 
  /* RedCreek's OSM default LAN receive Initiator */
@@ -216,8 +212,8 @@
 /* #define RC_PRIVATE_GET_IP_AND_MASK  0x0007 */ /* OBSOLETE */
 #define RC_PRIVATE_GET_LINK_SPEED   0x0008
 #define RC_PRIVATE_GET_FIRMWARE_REV 0x0009
-/* #define RC_PRIVATE_GET_MAC_ADDR     0x000A *//**/
-#define RC_PRIVATE_GET_IP_AND_MASK  0x000B /**/
+/* #define RC_PRIVATE_GET_MAC_ADDR     0x000A */
+#define RC_PRIVATE_GET_IP_AND_MASK  0x000B 
 #define RC_PRIVATE_DEBUG_MSG        0x000C
 #define RC_PRIVATE_REPORT_DRIVER_CAPABILITY  0x000D
 #define RC_PRIVATE_SET_PROMISCUOUS_MODE  0x000e
@@ -247,72 +243,11 @@
 #define MSG_FRAME_SIZE  512
 #define NMBR_MSG_FRAMES 30
 
-/*
-**  Message Unit CSR definitions for RedCreek PCI45 board
-*/
-typedef struct tag_rcatu 
-{
-    volatile unsigned long APICRegSel;  /* APIC Register Select */
-    volatile unsigned long reserved0;
-    volatile unsigned long APICWinReg;  /* APIC Window Register */
-    volatile unsigned long reserved1;
-    volatile unsigned long InMsgReg0;   /* inbound message register 0 */
-    volatile unsigned long InMsgReg1;   /* inbound message register 1 */
-    volatile unsigned long OutMsgReg0;  /* outbound message register 0 */
-    volatile unsigned long OutMsgReg1;  /* outbound message register 1 */
-    volatile unsigned long InDoorReg;   /* inbound doorbell register */
-    volatile unsigned long InIntStat;   /* inbound interrupt status register */
-    volatile unsigned long InIntMask;   /* inbound interrupt mask register */
-    volatile unsigned long OutDoorReg;  /* outbound doorbell register */
-    volatile unsigned long OutIntStat;  /* outbound interrupt status register */
-    volatile unsigned long OutIntMask;  /* outbound interrupt mask register */
-    volatile unsigned long reserved2;
-    volatile unsigned long reserved3;
-    volatile unsigned long InQueue;     /* inbound queue port */
-    volatile unsigned long OutQueue;    /* outbound queue port */
-    volatile unsigned long reserved4;
-    volatile unsigned long reserver5;
-    /* RedCreek extension */
-    volatile unsigned long EtherMacLow;
-    volatile unsigned long EtherMacHi;
-    volatile unsigned long IPaddr;
-    volatile unsigned long IPmask;
-}
-ATU, *PATU;
-
- /* 
- ** typedef PAB
- **
- ** PCI Adapter Block - holds instance specific information and is located
- ** in a reserved space at the start of the message buffer allocated by user.
- */
-typedef struct
-{
-    PATU             p_atu;                /* ptr to  ATU register block */
-    PU8              pPci45LinBaseAddr;
-    PU8              pLinOutMsgBlock;
-    U32              outMsgBlockPhyAddr; 
-    PFNTXCALLBACK    pTransCallbackFunc;
-    PFNRXCALLBACK    pRecvCallbackFunc;
-    PFNCALLBACK      pRebootCallbackFunc;
-    PFNCALLBACK      pCallbackFunc;
-    U16              IOPState;
-    U16              InboundMFrameSize;
-}
-PAB, *PPAB;
-
  /* 
  ** in reserved space right after PAB in host memory is area for returning
  ** values from card 
  */
 
- /* 
- ** Array of pointers to PCI Adapter Blocks.
- ** Indexed by a zero based (0-31) interface number.
- */ 
-#define MAX_ADAPTERS 32
-static PPAB  PCIAdapterBlock[MAX_ADAPTERS];
-
 /*
 ** typedef NICSTAT
 **
@@ -357,19 +292,13 @@
 static int SendEnableSysMsg(PPAB pPab);
 
 
-/* 1st 100h bytes of message block is reserved for messenger instance */
-#define ADAPTER_BLOCK_RESERVED_SPACE 0x100
-
 /*
 ** =========================================================================
 ** RCInitI2OMsgLayer()
 **
 ** Initialize the RedCreek I2O Module and adapter.
 **
-** Inputs:  AdapterID - interface number from 0 to 15
-**          pciBaseAddr - virual base address of PCI (set by BIOS)
-**          p_msgbuf - virual address to private message block (min. 16K)
-**          p_phymsgbuf - physical address of private message block
+** Inputs:  dev - the devices net_device struct
 **          TransmitCallbackFunction - address of transmit callback function
 **          ReceiveCallbackFunction  - address of receive  callback function
 **
@@ -379,42 +308,49 @@
 ** =========================================================================
 */
 RC_RETURN
-RCInitI2OMsgLayer(U16 AdapterID, U32 pciBaseAddr, 
-                  PU8 p_msgbuf,  PU8 p_phymsgbuf,
+RCInitI2OMsgLayer(struct net_device *dev,
                   PFNTXCALLBACK  TransmitCallbackFunction,
                   PFNRXCALLBACK  ReceiveCallbackFunction,
                   PFNCALLBACK    RebootCallbackFunction)
 {
     int result;
     PPAB pPab; 
-    
-#ifdef DEBUG
-    kprintf("InitI2O: Adapter:0x%04.4ux ATU:0x%08.8ulx msgbuf:0x%08.8ulx phymsgbuf:0x%08.8ulx\n"
-            "TransmitCallbackFunction:0x%08.8ulx  ReceiveCallbackFunction:0x%08.8ulx\n",
-            AdapterID, pciBaseAddr, p_msgbuf, p_phymsgbuf, TransmitCallbackFunction, ReceiveCallbackFunction);
-#endif /* DEBUG */
+    U32 pciBaseAddr = dev->base_addr;
+    PDPA pDpa = dev->priv;
+    PU8 p_msgbuf = pDpa->PLanApiPA;
+    PU8 p_phymsgbuf = (PU8)virt_to_bus((void *) p_msgbuf);    
+    
+    dprintk("InitI2O: Adapter:0x%04ux ATU:0x%08ulx msgbuf:0x%08ulx phymsgbuf:0x%08ulx\n"
+            "TransmitCallbackFunction:0x%08ulx  ReceiveCallbackFunction:0x%08ulx\n",
+            pDpa->id, pciBaseAddr, (u32)p_msgbuf, (u32)p_phymsgbuf, 
+	    (u32)TransmitCallbackFunction, (u32)ReceiveCallbackFunction);
 
     
     /* Check if this interface already initialized - if so, shut it down */
-    if (PCIAdapterBlock[AdapterID] != NULL)
-    {
-        printk("PCIAdapterBlock[%d]!=NULL\n", AdapterID);
-//        RCResetLANCard(AdapterID, 0, (PU32)NULL, (PFNCALLBACK)NULL);
-        PCIAdapterBlock[AdapterID] = NULL;
+    if (pDpa->pPab != NULL) {
+	    printk(KERN_WARNING "(rcpci45 driver:) pDpa->pPab [%d] != NULL\n", pDpa->id);
+/*          RCResetLANCard(pDpa->id, 0, (PU32)NULL, (PFNCALLBACK)NULL); */
+	    pDpa->pPab = NULL;
     }
 
-    /* 
-    ** store adapter instance values in adapter block.
-    ** Adapter block is at beginning of message buffer
-    */  
-    pPab = (PPAB)p_msgbuf;
+    /* store adapter instance values in adapter block.
+     * Adapter block is at beginning of message buffer */  
     
+    pPab = kmalloc(sizeof(*pPab), GFP_KERNEL);
+    if (!pPab) {
+	    printk(KERN_ERR "(rcpci45 driver:) RCInitI2OMsgLayer: Could not allocate memory for PAB struct!\n");
+	    result = RC_RTN_MALLOC_ERROR;
+	    goto err_out;
+    }
+
+    memset(pPab, 0, sizeof(*pPab));
+    pDpa->pPab = pPab;
     pPab->p_atu = (PATU)pciBaseAddr;
     pPab->pPci45LinBaseAddr =  (PU8)pciBaseAddr;
     
-    /* Set outbound message frame addr - skip over Adapter Block */
-    pPab->outMsgBlockPhyAddr = (U32)(p_phymsgbuf + ADAPTER_BLOCK_RESERVED_SPACE);
-    pPab->pLinOutMsgBlock    = (PU8)(p_msgbuf + ADAPTER_BLOCK_RESERVED_SPACE);
+    /* Set outbound message frame addr */
+    pPab->outMsgBlockPhyAddr = (U32)p_phymsgbuf;
+    pPab->pLinOutMsgBlock    = (PU8)p_msgbuf;
 
     /* store callback function addresses */
     pPab->pTransCallbackFunc = TransmitCallbackFunction;
@@ -428,26 +364,29 @@
     result = GetI2OStatus(pPab);
     
     if (result != RC_RTN_NO_ERROR)
-        return result;
+	    goto err_out_dealloc;
 
-    if (pPab->IOPState == I2O_IOP_STATE_OPERATIONAL)
-    {
-        printk("pPab->IOPState == op: resetting adapter\n");
-        RCResetLANCard(AdapterID, 0, (PU32)NULL, (PFNCALLBACK)NULL);
+    if (pPab->IOPState == I2O_IOP_STATE_OPERATIONAL) {
+        printk(KERN_INFO "(rcpci45 driver:) pPab->IOPState == op: resetting adapter\n");
+        RCResetLANCard(dev, 0, (PU32)NULL, (PFNCALLBACK)NULL);
     }
         
     result = SendI2OOutboundQInitMsg(pPab);
     
     if (result != RC_RTN_NO_ERROR)
-        return result;
+	    goto err_out_dealloc;
 
     result = SendEnableSysMsg(pPab);
    
     if (result != RC_RTN_NO_ERROR)
-        return result;
+	    goto err_out_dealloc;
    
-    PCIAdapterBlock[AdapterID] = pPab;
     return RC_RTN_NO_ERROR;
+
+ err_out_dealloc:
+    kfree(pPab);
+ err_out:
+    return result;
 }
 
 /*
@@ -462,13 +401,11 @@
 */
 #define i960_OUT_POST_Q_INT_BIT        0x0008 /* bit set masks interrupts */
 
-RC_RETURN RCDisableI2OInterrupts(U16 AdapterID)
+RC_RETURN RCDisableI2OInterrupts(struct net_device *dev)
 {
-    PPAB pPab;
+    PPAB pPab = ((PDPA)dev->priv)->pPab;
 
 
-    pPab = PCIAdapterBlock[AdapterID];
-    
     if (pPab == NULL)
         return RC_RTN_ADPTR_NOT_REGISTERED;
         
@@ -477,12 +414,11 @@
     return RC_RTN_NO_ERROR;
 }
 
-RC_RETURN RCEnableI2OInterrupts(U16 AdapterID)
+RC_RETURN RCEnableI2OInterrupts(struct net_device *dev)
 {
-    PPAB pPab;
+    PPAB pPab = ((PDPA)dev->priv)->pPab;
+
 
-    pPab = PCIAdapterBlock[AdapterID];
-    
     if (pPab == NULL)
         return RC_RTN_ADPTR_NOT_REGISTERED;
     
@@ -499,18 +435,16 @@
 ** =========================================================================
 */
 RC_RETURN
-RCI2OSendPacket(U16 AdapterID, U32 InitiatorContext, PRCTCB pTransCtrlBlock)
+RCI2OSendPacket(struct net_device *dev, U32 InitiatorContext, 
+		PRCTCB pTransCtrlBlock)
 {
     U32 msgOffset;
     PU32 pMsg;
     int size;
-    PPAB pPab;
+    PPAB pPab = ((PDPA)dev->priv)->pPab;
 
-#ifdef DEBUG
-    kprintf("RCI2OSendPacket()...\n");
-#endif /* DEBUG */
-    
-    pPab = PCIAdapterBlock[AdapterID];
+
+    dprintk("RCI2OSendPacket()...\n");
 
     if (pPab == NULL)
         return RC_RTN_ADPTR_NOT_REGISTERED;
@@ -522,9 +456,7 @@
 
     if (msgOffset == 0xFFFFFFFF)
     {
-#ifdef DEBUG
-        kprintf("RCI2OSendPacket(): Inbound Free Q empty!\n");
-#endif /* DEBUG */
+        dprintk("RCI2OSendPacket(): Inbound Free Q empty!\n");
         return RC_RTN_FREE_Q_EMPTY;
     }
         
@@ -535,9 +467,7 @@
 
     if (size == -1) /* error processing TCB - send NOP msg */
     {
-#ifdef DEBUG
-        kprintf("RCI2OSendPacket(): Error Rrocess TCB!\n");
-#endif /* DEBUG */
+        dprintk("RCI2OSendPacket(): Error Rrocess TCB!\n");
         pMsg[0] = THREE_WORD_MSG_SIZE | SGL_OFFSET_0;
         pMsg[1] = I2O_UTIL_NOP << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
         return RC_RTN_TCB_ERROR;
@@ -565,35 +495,28 @@
 ** =========================================================================
 */
 RC_RETURN
-RCPostRecvBuffers(U16 AdapterID, PRCTCB pTransCtrlBlock)
+RCPostRecvBuffers(struct net_device *dev, PRCTCB pTransCtrlBlock)
 {
     U32 msgOffset;
     PU32 pMsg;
     int size;
-    PPAB pPab;
+    PPAB pPab = ((PDPA)dev->priv)->pPab;
 
-#ifdef DEBUG
-    kprintf("RCPostRecvBuffers()...\n");
-#endif /* DEBUG */
+    dprintk("RCPostRecvBuffers()...\n");
     
     /* search for DeviceHandle */
-    pPab = PCIAdapterBlock[AdapterID];
 
     if (pPab == NULL)
         return RC_RTN_ADPTR_NOT_REGISTERED;
     
-
     /* get Inbound free Q entry - reading from In Q gets free Q entry */
     /* offset to Msg Frame in PCI msg block */
     msgOffset = pPab->p_atu->InQueue; 
 
     if (msgOffset == 0xFFFFFFFF)
     {
-#ifdef DEBUG
-        kprintf("RCPostRecvBuffers(): Inbound Free Q empty!\n");
-#endif /* DEBUG */
+        dprintk("RCPostRecvBuffers(): Inbound Free Q empty!\n");
         return RC_RTN_FREE_Q_EMPTY;
-   
     }
     /* calc virual address of msg - virual already mapped to physical */    
     pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
@@ -602,9 +525,7 @@
 
     if (size == -1) /* error prcessing TCB - send 3 DWORD private msg == NOP */
     {
-#ifdef DEBUG
-        kprintf("RCPostRecvBuffers(): Error Processing TCB! size = %d\n", size);
-#endif /* DEBUG */
+        dprintk("RCPostRecvBuffers(): Error Processing TCB! size = %d\n", size);
         pMsg[0] = THREE_WORD_MSG_SIZE | SGL_OFFSET_0;
         pMsg[1] = I2O_UTIL_NOP << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
         /* post to Post Q */   
@@ -632,17 +553,16 @@
 ** =========================================================================
 */
 void 
-RCProcI2OMsgQ(U16 AdapterID)
+RCProcI2OMsgQ(struct net_device *dev)
 {
     U32 phyAddrMsg;
     PU8 p8Msg;
     PU32 p32;
     U16 count;
-    PPAB pPab;
+    PPAB pPab = ((PDPA)dev->priv)->pPab;
     unsigned char debug_msg[20];
     
-    pPab = PCIAdapterBlock[AdapterID];
-    
+
     if (pPab == NULL)
         return;
     
@@ -653,89 +573,66 @@
         p8Msg = pPab->pLinOutMsgBlock + (phyAddrMsg - pPab->outMsgBlockPhyAddr);
         p32 = (PU32)p8Msg;
         
-        //printk(" msg: 0x%x  0x%x \n", p8Msg[7], p32[5]);
+        dprintk("msg: 0x%x  0x%x \n", p8Msg[7], p32[5]);
 
-        /* 
-        ** Send Packet Reply Msg
-        */
-        if (I2O_LAN_PACKET_SEND == p8Msg[7])  /* function code byte */
-        {
+        /* Send Packet Reply Msg */
+        if (I2O_LAN_PACKET_SEND == p8Msg[7]) {  /* function code byte */
             count = *(PU16)(p8Msg+2);
             count -= p8Msg[0] >> 4;
             /* status, count, context[], adapter */
-            (*pPab->pTransCallbackFunc)(p8Msg[19], count, p32+5, AdapterID);
-        }             
-        /* 
-        ** Receive Packet Reply Msg */
-        else if (I2O_LAN_RECEIVE_POST == p8Msg[7])
-        {
-#ifdef DEBUG    
-            kprintf("I2O_RECV_REPLY pPab:0x%08.8ulx p8Msg:0x%08.8ulx p32:0x%08.8ulx\n", pPab, p8Msg, p32);
-            kprintf("msg: 0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n",
-                    p32[0], p32[1], p32[2], p32[3]);
-            kprintf("     0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n",
-                    p32[4], p32[5], p32[6], p32[7]);
-            kprintf("     0x%08.8ulx:0X%08.8ulx:0x%08.8ulx:0x%08.8ulx\n",
-                    p32[8], p32[9], p32[10], p32[11]);
-#endif
-            /*  status, count, buckets remaining, packetParmBlock, adapter */
-            (*pPab->pRecvCallbackFunc)(p8Msg[19], p8Msg[12], p32[5], p32+6, AdapterID);
-      
-      
-        }
-        else if (I2O_LAN_RESET == p8Msg[7] || I2O_LAN_SHUTDOWN == p8Msg[7])
-        {
-            if (pPab->pCallbackFunc)
-            {
-                (*pPab->pCallbackFunc)(p8Msg[19],0,0,AdapterID);
-            }
-            else
-            {
-                pPab->pCallbackFunc = (PFNCALLBACK) 1;
-            }
-            //PCIAdapterBlock[AdapterID] = 0;
-        }
-        else if (I2O_PRIVATE == p8Msg[7])
-        {
-            //printk("i2o private 0x%x, 0x%x \n", p8Msg[7], p32[5]);
+            (*pPab->pTransCallbackFunc)(p8Msg[19], count, p32+5, dev);
+        } else if (I2O_LAN_RECEIVE_POST == p8Msg[7]) { /* Receive Packet Reply Msg */
+		dprintk("I2O_RECV_REPLY pPab:0x%08ulx p8Msg:0x%08ulx p32:0x%08ulx\n", (u32)pPab, (u32)p8Msg, (u32)p32);
+		dprintk("msg: 0x%08ulx:0x%08ulx:0x%08ulx:0x%08ulx\n",
+			p32[0], p32[1], p32[2], p32[3]);
+		dprintk("     0x%08ulx:0x%08ulx:0x%08ulx:0x%08ulx\n",
+			p32[4], p32[5], p32[6], p32[7]);
+		dprintk("     0x%08ulx:0X%08ulx:0x%08ulx:0x%08ulx\n",
+			p32[8], p32[9], p32[10], p32[11]);
+		/*  status, count, buckets remaining, packetParmBlock, adapter */
+		(*pPab->pRecvCallbackFunc)(p8Msg[19], p8Msg[12], p32[5], p32+6, dev);      
+        } else if (I2O_LAN_RESET == p8Msg[7] || I2O_LAN_SHUTDOWN == p8Msg[7])
+		if (pPab->pCallbackFunc)
+			(*pPab->pCallbackFunc)(p8Msg[19],0,0,dev);
+		else		
+			pPab->pCallbackFunc = (PFNCALLBACK) 1;
+        else if (I2O_PRIVATE == p8Msg[7]) {
+	    dprintk("i2o private 0x%x, 0x%x \n", p8Msg[7], p32[5]);
             switch (p32[5])
             {
             case RC_PRIVATE_DEBUG_MSG:
                 msgFlag = 1;
-                /*printk("Received I2O_PRIVATE msg\n");*/
-                debug_msg[15]  = (p32[6]&0xff000000) >> 24;
-                debug_msg[14]  = (p32[6]&0x00ff0000) >> 16;
-                debug_msg[13]  = (p32[6]&0x0000ff00) >> 8;
-                debug_msg[12]  = (p32[6]&0x000000ff);
-
-                debug_msg[11]  = (p32[7]&0xff000000) >> 24;
-                debug_msg[10]  = (p32[7]&0x00ff0000) >> 16;
-                debug_msg[ 9]  = (p32[7]&0x0000ff00) >> 8;
-                debug_msg[ 8]  = (p32[7]&0x000000ff);
-
-                debug_msg[ 7]  = (p32[8]&0xff000000) >> 24;
-                debug_msg[ 6]  = (p32[8]&0x00ff0000) >> 16;
+                dprintk("Received I2O_PRIVATE msg\n");
+                debug_msg[15] = (p32[6]&0xff000000) >> 24;
+                debug_msg[14] = (p32[6]&0x00ff0000) >> 16;
+                debug_msg[13] = (p32[6]&0x0000ff00) >> 8;
+                debug_msg[12] = (p32[6]&0x000000ff);
+			      
+                debug_msg[11] = (p32[7]&0xff000000) >> 24;
+                debug_msg[10] = (p32[7]&0x00ff0000) >> 16;
+                debug_msg[ 9] = (p32[7]&0x0000ff00) >> 8;
+                debug_msg[ 8] = (p32[7]&0x000000ff);
+			      
+                debug_msg[ 7] = (p32[8]&0xff000000) >> 24;
+                debug_msg[ 6] = (p32[8]&0x00ff0000) >> 16;
                 debug_msg[ 5] = (p32[8]&0x0000ff00) >> 8;
                 debug_msg[ 4] = (p32[8]&0x000000ff);
-
+			      
                 debug_msg[ 3] = (p32[9]&0xff000000) >> 24;
                 debug_msg[ 2] = (p32[9]&0x00ff0000) >> 16;
                 debug_msg[ 1] = (p32[9]&0x0000ff00) >> 8;
                 debug_msg[ 0] = (p32[9]&0x000000ff);
 
                 debug_msg[16] = '\0';
-                printk (debug_msg);
+                dprintk("%s", debug_msg);
                 break;
             case RC_PRIVATE_REBOOT:
-                printk("Adapter reboot initiated...\n");
+                dprintk("Adapter reboot initiated...\n");
                 if (pPab->pRebootCallbackFunc)
-                {
-                    (*pPab->pRebootCallbackFunc)(0,0,0,AdapterID);
-                }
+                    (*pPab->pRebootCallbackFunc)(0,0,0,dev);
                 break;
             default:
-                printk("Unknown private I2O msg received: 0x%lx\n",
-                       p32[5]);
+                printk(KERN_WARNING "(rcpci45 driver:) Unknown private I2O msg received: 0x%x\n", p32[5]);
                 break;
             }
         }
@@ -744,9 +641,7 @@
         ** Process other Msg's
         */
         else
-        {
             ProcessOutboundI2OMsg(pPab, phyAddrMsg);
-        }
         
         /* return MFA to outbound free Q*/
         pPab->p_atu->OutQueue = phyAddrMsg;
@@ -766,7 +661,7 @@
 ** =========================================================================
 */
 RC_RETURN
-RCGetLinkStatistics(U16 AdapterID, 
+RCGetLinkStatistics(struct net_device *dev, 
                     P_RCLINKSTATS StatsReturnAddr,
                     PFNWAITCALLBACK WaitCallback)
 {
@@ -776,11 +671,10 @@
     volatile PU32 p32, pReturnAddr;
     P_NICSTAT pStats;
     int i;
-    PPAB pPab;
+    PPAB pPab = ((PDPA)dev->priv)->pPab;
 
-/*kprintf("Get82558Stats() StatsReturnAddr:0x%08.8ulx\n", StatsReturnAddr);*/
 
-    pPab = PCIAdapterBlock[AdapterID];
+/*dprintk("Get82558Stats() StatsReturnAddr:0x%08ulx\n", StatsReturnAddr); */
 
     if (pPab == NULL)
         return RC_RTN_ADPTR_NOT_REGISTERED;
@@ -789,28 +683,25 @@
 
     if (msgOffset == 0xFFFFFFFF)
     {
-#ifdef DEBUG
-        kprintf("Get8255XStats(): Inbound Free Q empty!\n");
-#endif
+        dprintk("Get8255XStats(): Inbound Free Q empty!\n");
         return RC_RTN_FREE_Q_EMPTY;
     }
 
     /* calc virual address of msg - virual already mapped to physical */
     pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
 
-/*dprintf("Get82558Stats - pMsg = 0x%08ulx, InQ msgOffset = 0x%08ulx\n", pMsg, msgOffset);*/
-/*dprintf("Get82558Stats - pMsg = 0x%08X, InQ msgOffset = 0x%08X\n", pMsg, msgOffset);*/
+/*dprintk("Get82558Stats - pMsg = 0x%08ulx, InQ msgOffset = 0x%08ulx\n", pMsg, msgOffset);*/
+/*dprintk("Get82558Stats - pMsg = 0x%08X, InQ msgOffset = 0x%08X\n", pMsg, msgOffset);*/
 
     pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
     pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
     pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
     pMsg[3] = 0x112; /* transaction context */
     pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_NIC_STATS;
-    pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
-
-    p32 = (PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
-
-    pStats = (P_NICSTAT)p32;
+    pMsg[5] = pPab->outMsgBlockPhyAddr;
+    
+    p32 = (PU32) pPab->outMsgBlockPhyAddr;
+    pStats = (P_NICSTAT)pPab->pLinOutMsgBlock;
     pStats->dump_status = 0xFFFFFFFF;
 
     /* post to Inbound Post Q */
@@ -822,17 +713,14 @@
         if (WaitCallback)
             (*WaitCallback)();
         
-        for (i = 0; i < 1000; i++)
-            ;
+	udelay(10);
 
         if (pStats->dump_status != 0xFFFFFFFF)
             break;
 
         if (!timeout--)
         {
-#ifdef DEBUG
-            kprintf("RCGet82558Stats() Timeout waiting for NIC statistics\n");
-#endif
+            dprintk("RCGet82558Stats() Timeout waiting for NIC statistics\n");
             return RC_RTN_MSG_REPLY_TIMEOUT;
         }
     }
@@ -853,17 +741,17 @@
 ** =========================================================================
 */
 RC_RETURN
-RCGetLinkStatus(U16 AdapterID, PU32 ReturnAddr, PFNWAITCALLBACK WaitCallback)
+RCGetLinkStatus(struct net_device *dev, PU32 ReturnAddr, 
+		PFNWAITCALLBACK WaitCallback)
 {
     U32 msgOffset;
     volatile U32 timeout;
     volatile PU32 pMsg;
     volatile PU32 p32;
-    PPAB pPab;
+    PPAB pPab = ((PDPA)dev->priv)->pPab;
 
-/*kprintf("Get82558LinkStatus() ReturnPhysAddr:0x%08.8ulx\n", ReturnAddr);*/
 
-    pPab = PCIAdapterBlock[AdapterID];
+    dprintk("Get82558LinkStatus() ReturnPhysAddr:0x%08ulx\n", (u32)ReturnAddr);
 
     if (pPab == NULL)
         return RC_RTN_ADPTR_NOT_REGISTERED;
@@ -872,49 +760,40 @@
 
     if (msgOffset == 0xFFFFFFFF)
     {
-#ifdef DEBUG
-        dprintf("Get82558LinkStatus(): Inbound Free Q empty!\n");
-#endif
+        dprintk("Get82558LinkStatus(): Inbound Free Q empty!\n");
         return RC_RTN_FREE_Q_EMPTY;
     }
 
     /* calc virual address of msg - virual already mapped to physical */
     pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
-/*dprintf("Get82558LinkStatus - pMsg = 0x%08ulx, InQ msgOffset = 0x%08ulx\n", pMsg, msgOffset);*/
-/*dprintf("Get82558LinkStatus - pMsg = 0x%08X, InQ msgOffset = 0x%08X\n", pMsg, msgOffset);*/
+/*dprintk("Get82558LinkStatus - pMsg = 0x%08ulx, InQ msgOffset = 0x%08ulx\n", pMsg, msgOffset);*/
+/*dprintk("Get82558LinkStatus - pMsg = 0x%08X, InQ msgOffset = 0x%08X\n", pMsg, msgOffset);*/
 
     pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
     pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
     pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
     pMsg[3] = 0x112; /* transaction context */
     pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_LINK_STATUS;
-    pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
+    pMsg[5] = pPab->outMsgBlockPhyAddr;
 
-    p32 = (PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
+    p32 = (PU32)pPab->pLinOutMsgBlock;
     *p32 = 0xFFFFFFFF;
     
     /* post to Inbound Post Q */
     pPab->p_atu->InQueue = msgOffset;
 
     timeout = 100000;
-    while (1)
-    {
-        U32 i;
-
+    while (1) {
         if (WaitCallback)
             (*WaitCallback)();
         
-        for (i = 0; i < 1000; i++)
-            ;
+	udelay(10);
 
         if (*p32 != 0xFFFFFFFF)
             break;
 
-        if (!timeout--)
-        {
-#ifdef DEBUG
-            kprintf("Timeout waiting for link status\n");
-#endif    
+        if (!timeout--) {
+            dprintk("Timeout waiting for link status\n");
             return RC_RTN_MSG_REPLY_TIMEOUT;
         }
     }
@@ -934,17 +813,16 @@
 ** =========================================================================
 */
 RC_RETURN
-RCGetMAC(U16 AdapterID, PU8 mac, PFNWAITCALLBACK WaitCallback)
+RCGetMAC(struct net_device *dev, PFNWAITCALLBACK WaitCallback)
 {
-    unsigned i, timeout;
+    unsigned timeout;
     U32      off;
+    PU8      mac = dev->dev_addr;
     PU32     p;
     U32      temp[2];
-    PPAB     pPab;
+    PPAB     pPab = ((PDPA)dev->priv)->pPab;
     PATU     p_atu;
     
-    pPab = PCIAdapterBlock[AdapterID];
-    
     if (pPab == NULL)
         return RC_RTN_ADPTR_NOT_REGISTERED;
     
@@ -960,10 +838,8 @@
 
     p = (PU32)(pPab->pPci45LinBaseAddr + off);
 
-#ifdef RCDEBUG
-    printk("RCGetMAC: p_atu 0x%08x, off 0x%08x, p 0x%08x\n", 
+    dprintk("RCGetMAC: p_atu 0x%08x, off 0x%08x, p 0x%08x\n", 
            (uint)p_atu, (uint)off, (uint)p);
-#endif /* RCDEBUG */
     /* setup private message */
     p[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0;
     p[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
@@ -973,10 +849,8 @@
 
 
     p_atu->InQueue = off;   /* send it to the I2O device */
-#ifdef RCDEBUG
-    printk("RCGetMAC: p_atu 0x%08x, off 0x%08x, p 0x%08x\n", 
+    dprintk("RCGetMAC: p_atu 0x%08x, off 0x%08x, p 0x%08x\n", 
            (uint)p_atu, (uint)off, (uint)p);
-#endif /* RCDEBUG */
 
     /* wait for the rcpci45 board to update the info */
     timeout = 1000000;
@@ -985,8 +859,7 @@
         if (WaitCallback)
             (*WaitCallback)();
     
-        for (i = 0; i < 1000; i++)
-            ;
+	udelay(10);
 
         if (!timeout--)
         {
@@ -1001,9 +874,7 @@
     memcpy((char *)mac, (char *)temp, 6);
 
 
-#ifdef RCDEBUG
-//    printk("rc_getmac: 0x%X\n", ptr);
-#endif /* RCDEBUG */
+    dprintk("rc_getmac: 0x%x\n", (u32)mac);
 
     return RC_RTN_NO_ERROR;
 }
@@ -1018,15 +889,13 @@
 ** =========================================================================
 */
 RC_RETURN
-RCSetMAC(U16 AdapterID, PU8 mac)
+RCSetMAC(struct net_device *dev, PU8 mac)
 {
     U32  off;
     PU32 pMsg;
-    PPAB pPab;
+    PPAB pPab = ((PDPA)dev->priv)->pPab;
 
 
-    pPab = PCIAdapterBlock[AdapterID];
-    
     if (pPab == NULL)
         return RC_RTN_ADPTR_NOT_REGISTERED;
     
@@ -1067,15 +936,13 @@
 ** =========================================================================
 */
 RC_RETURN
-RCSetLinkSpeed(U16 AdapterID, U16 LinkSpeedCode)
+RCSetLinkSpeed(struct net_device *dev, U16 LinkSpeedCode)
 {
     U32  off;
     PU32 pMsg;
-    PPAB pPab;
+    PPAB pPab = ((PDPA)dev->priv)->pPab;
 
     
-    pPab =PCIAdapterBlock[AdapterID];
-     
     if (pPab == NULL)
         return RC_RTN_ADPTR_NOT_REGISTERED;
     
@@ -1109,14 +976,12 @@
 ** =========================================================================
 */
 RC_RETURN
-RCSetPromiscuousMode(U16 AdapterID, U16 Mode)
+RCSetPromiscuousMode(struct net_device *dev, U16 Mode)
 {
     U32  off;
     PU32 pMsg;
-    PPAB pPab;
+    PPAB pPab = ((PDPA)dev->priv)->pPab;
     
-    pPab =PCIAdapterBlock[AdapterID];
-     
     if (pPab == NULL)
         return RC_RTN_ADPTR_NOT_REGISTERED;
     
@@ -1152,22 +1017,20 @@
 ** =========================================================================
 */
 RC_RETURN
-RCGetPromiscuousMode(U16 AdapterID, PU32 pMode, PFNWAITCALLBACK WaitCallback)
+RCGetPromiscuousMode(struct net_device *dev, PU32 pMode, 
+		     PFNWAITCALLBACK WaitCallback)
 {
     U32 msgOffset, timeout;
     PU32 pMsg;
     volatile PU32 p32;
-    PPAB pPab;
-
-    pPab =PCIAdapterBlock[AdapterID];
+    PPAB pPab = ((PDPA)dev->priv)->pPab;
 
 
     msgOffset = pPab->p_atu->InQueue;
 
-
     if (msgOffset == 0xFFFFFFFF)
     {
-        kprintf("RCGetLinkSpeed(): Inbound Free Q empty!\n");
+	printk(KERN_WARNING "(rcpci45 driver:) RCGetLinkSpeed(): Inbound Free Q empty!\n");
         return RC_RTN_FREE_Q_EMPTY;
     }
 
@@ -1175,7 +1038,7 @@
     pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
 
     /* virtual pointer to return buffer - clear first two dwords */
-    p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
+    p32 = (volatile PU32)pPab->pLinOutMsgBlock;
     p32[0] = 0xff;
 
     /* setup private message */
@@ -1185,7 +1048,7 @@
     pMsg[3] = 0x219;             /* transaction context */
     pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_PROMISCUOUS_MODE;
     /* phys address to return status - area right after PAB */
-    pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
+    pMsg[5] = pPab->outMsgBlockPhyAddr;
    
     /* post to Inbound Post Q */   
 
@@ -1193,23 +1056,19 @@
 
     /* wait for response */
     timeout = 1000000;
-    while(1)
-    {
-        int i;
-        
+    while(1) {
         if (WaitCallback)
             (*WaitCallback)();
 
-        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
-            ;
-            
+	udelay(10);  /* please don't hog the bus!!! */
+
         if (p32[0] != 0xff)
             break;
             
         if (!timeout--)
         {
-            kprintf("Timeout waiting for promiscuous mode from adapter\n");
-            kprintf("0x%8.8lx\n", p32[0]);
+	    dprintk("Timeout waiting for promiscuous mode from adapter\n");
+            dprintk("0x%8x\n", p32[0]);
             return RC_RTN_NO_LINK_SPEED;
         }
     }
@@ -1230,14 +1089,13 @@
 ** =========================================================================
 */
 RC_RETURN
-RCSetBroadcastMode(U16 AdapterID, U16 Mode)
+RCSetBroadcastMode(struct net_device *dev, U16 Mode)
 {
     U32  off;
     PU32 pMsg;
-    PPAB pPab;
+    PPAB pPab = ((PDPA)dev->priv)->pPab;
     
-    pPab =PCIAdapterBlock[AdapterID];
-     
+
     if (pPab == NULL)
         return RC_RTN_ADPTR_NOT_REGISTERED;
     
@@ -1273,22 +1131,20 @@
 ** =========================================================================
 */
 RC_RETURN
-RCGetBroadcastMode(U16 AdapterID, PU32 pMode, PFNWAITCALLBACK WaitCallback)
+RCGetBroadcastMode(struct net_device *dev, PU32 pMode, 
+		   PFNWAITCALLBACK WaitCallback)
 {
     U32 msgOffset, timeout;
     PU32 pMsg;
     volatile PU32 p32;
-    PPAB pPab;
-
-    pPab =PCIAdapterBlock[AdapterID];
+    PPAB pPab = ((PDPA)dev->priv)->pPab;
 
 
     msgOffset = pPab->p_atu->InQueue;
 
-
     if (msgOffset == 0xFFFFFFFF)
     {
-        kprintf("RCGetLinkSpeed(): Inbound Free Q empty!\n");
+        printk(KERN_WARNING "(rcpci45 driver:) RCGetLinkSpeed(): Inbound Free Q empty!\n");
         return RC_RTN_FREE_Q_EMPTY;
     }
 
@@ -1296,7 +1152,7 @@
     pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
 
     /* virtual pointer to return buffer - clear first two dwords */
-    p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
+    p32 = (volatile PU32)pPab->pLinOutMsgBlock;
     p32[0] = 0xff;
 
     /* setup private message */
@@ -1306,7 +1162,7 @@
     pMsg[3] = 0x219;             /* transaction context */
     pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_BROADCAST_MODE;
     /* phys address to return status - area right after PAB */
-    pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
+    pMsg[5] = pPab->outMsgBlockPhyAddr;
    
     /* post to Inbound Post Q */   
 
@@ -1314,23 +1170,19 @@
 
     /* wait for response */
     timeout = 1000000;
-    while(1)
-    {
-        int i;
-        
+    while(1) {
         if (WaitCallback)
             (*WaitCallback)();
 
-        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
-            ;
+        udelay(10);      /* please don't hog the bus!!! */
             
         if (p32[0] != 0xff)
             break;
             
         if (!timeout--)
         {
-            kprintf("Timeout waiting for promiscuous mode from adapter\n");
-            kprintf("0x%8.8lx\n", p32[0]);
+            printk(KERN_WARNING "(rcpci45 driver:) Timeout waiting for promiscuous mode from adapter\n");
+            printk(KERN_WARNING "(rcpci45 driver:) 0x%8x\n", p32[0]);
             return RC_RTN_NO_LINK_SPEED;
         }
     }
@@ -1356,23 +1208,21 @@
 ** =========================================================================
 */
 RC_RETURN
-RCGetLinkSpeed(U16 AdapterID, PU32 pLinkSpeedCode, PFNWAITCALLBACK WaitCallback)
+RCGetLinkSpeed(struct net_device *dev, PU32 pLinkSpeedCode, 
+	       PFNWAITCALLBACK WaitCallback)
 {
     U32 msgOffset, timeout;
     PU32 pMsg;
     volatile PU32 p32;
     U8 IOPLinkSpeed;
-    PPAB pPab;
-
-    pPab =PCIAdapterBlock[AdapterID];
+    PPAB pPab = ((PDPA)dev->priv)->pPab;
 
 
     msgOffset = pPab->p_atu->InQueue;
 
-
     if (msgOffset == 0xFFFFFFFF)
     {
-        kprintf("RCGetLinkSpeed(): Inbound Free Q empty!\n");
+        printk(KERN_WARNING "(rcpci45 driver:) RCGetLinkSpeed(): Inbound Free Q empty!\n");
         return RC_RTN_FREE_Q_EMPTY;
     }
 
@@ -1380,7 +1230,7 @@
     pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
 
     /* virtual pointer to return buffer - clear first two dwords */
-    p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
+    p32 = (volatile PU32)pPab->pLinOutMsgBlock;
     p32[0] = 0xff;
 
     /* setup private message */
@@ -1390,7 +1240,7 @@
     pMsg[3] = 0x219;             /* transaction context */
     pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_LINK_SPEED;
     /* phys address to return status - area right after PAB */
-    pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
+    pMsg[5] = pPab->outMsgBlockPhyAddr;
    
     /* post to Inbound Post Q */   
 
@@ -1398,23 +1248,19 @@
 
     /* wait for response */
     timeout = 1000000;
-    while(1)
-    {
-        int i;
-        
+    while(1) {
         if (WaitCallback)
             (*WaitCallback)();
 
-        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
-            ;
+        udelay(10);      /* please don't hog the bus!!! */
             
         if (p32[0] != 0xff)
             break;
             
         if (!timeout--)
         {
-            kprintf("Timeout waiting for link speed from IOP\n");
-            kprintf("0x%8.8lx\n", p32[0]);
+            dprintk("Timeout waiting for link speed from IOP\n");
+            dprintk("0x%8x\n", p32[0]);
             return RC_RTN_NO_LINK_SPEED;
         }
     }
@@ -1429,7 +1275,7 @@
 
 /*
 ** =========================================================================
-** RCReportDriverCapability(U16 AdapterID, U32 capability)
+** RCReportDriverCapability(struct net_device *dev, U32 capability)
 **
 ** Currently defined bits:
 ** WARM_REBOOT_CAPABLE   0x01
@@ -1437,14 +1283,12 @@
 ** =========================================================================
 */
 RC_RETURN
-RCReportDriverCapability(U16 AdapterID, U32 capability)
+RCReportDriverCapability(struct net_device *dev, U32 capability)
 {
     U32  off;
     PU32 pMsg;
-    PPAB pPab;
+    PPAB pPab = ((PDPA)dev->priv)->pPab;
 
-    pPab =PCIAdapterBlock[AdapterID];
-     
     if (pPab == NULL)
         return RC_RTN_ADPTR_NOT_REGISTERED;
     
@@ -1477,21 +1321,19 @@
 ** =========================================================================
 */
 RC_RETURN
-RCGetFirmwareVer(U16 AdapterID, PU8 pFirmString, PFNWAITCALLBACK WaitCallback)
+RCGetFirmwareVer(struct net_device *dev, PU8 pFirmString, 
+		 PFNWAITCALLBACK WaitCallback)
 {
     U32 msgOffset, timeout;
     PU32 pMsg;
     volatile PU32 p32;
-    PPAB pPab;
+    PPAB pPab = ((PDPA)dev->priv)->pPab;
 
-    pPab =PCIAdapterBlock[AdapterID];
 
     msgOffset = pPab->p_atu->InQueue;
-
-
     if (msgOffset == 0xFFFFFFFF)
     {
-        kprintf("RCGetFirmwareVer(): Inbound Free Q empty!\n");
+        dprintk("RCGetFirmwareVer(): Inbound Free Q empty!\n");
         return RC_RTN_FREE_Q_EMPTY;
     }
 
@@ -1499,7 +1341,7 @@
     pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
 
     /* virtual pointer to return buffer - clear first two dwords */
-    p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
+    p32 = (volatile PU32)pPab->pLinOutMsgBlock;
     p32[0] = 0xff;
 
     /* setup private message */
@@ -1509,7 +1351,7 @@
     pMsg[3] = 0x219;             /* transaction context */
     pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_FIRMWARE_REV;
     /* phys address to return status - area right after PAB */
-    pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
+    pMsg[5] = pPab->outMsgBlockPhyAddr;
 
 
    
@@ -1520,22 +1362,18 @@
     
     /* wait for response */
     timeout = 1000000;
-    while(1)
-    {
-        int i;
-        
-        if (WaitCallback)
+    while(1) {
+	if (WaitCallback)
             (*WaitCallback)();
             
-        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
-            ;
+        udelay(10);     /* please don't hog the bus!!! */
 
         if (p32[0] != 0xff)
             break;
             
         if (!timeout--)
         {
-            kprintf("Timeout waiting for link speed from IOP\n");
+            dprintk("Timeout waiting for link speed from IOP\n");
             return RC_RTN_NO_FIRM_VER;
         }
     }
@@ -1558,17 +1396,15 @@
 ** =========================================================================
 */
 RC_RETURN 
-RCResetLANCard(U16 AdapterID, U16 ResourceFlags, PU32 ReturnAddr, PFNCALLBACK CallbackFunction)
+RCResetLANCard(struct net_device *dev, U16 ResourceFlags, PU32 ReturnAddr, 
+	       PFNCALLBACK CallbackFunction)
 {
     unsigned long off;
     PU32 pMsg;
-    PPAB pPab;
-    int i;
+    PPAB pPab = ((PDPA)dev->priv)->pPab;
     long timeout = 0;
 
     
-    pPab =PCIAdapterBlock[AdapterID];
-     
     if (pPab == NULL)
         return RC_RTN_ADPTR_NOT_REGISTERED;
 
@@ -1595,9 +1431,8 @@
            or until timer goes off */
         while (pPab->pCallbackFunc == (PFNCALLBACK)NULL)
         {
-            RCProcI2OMsgQ(AdapterID);
-            for (i = 0; i < 100000; i++)     /* please don't hog the bus!!! */
-                ;
+            RCProcI2OMsgQ(dev);
+            udelay(1000);    /* please don't hog the bus!!! */
             timeout++;
             if (timeout > 10000)
             {
@@ -1619,14 +1454,13 @@
 ** =========================================================================
 */
 RC_RETURN 
-RCResetIOP(U16 AdapterID)
+RCResetIOP(struct net_device *dev)
 {
     U32 msgOffset, timeout;
     PU32 pMsg;
-    PPAB pPab;
+    PPAB pPab = ((PDPA)dev->priv)->pPab;
     volatile PU32 p32;
     
-    pPab = PCIAdapterBlock[AdapterID];
     msgOffset = pPab->p_atu->InQueue;
 
     if (msgOffset == 0xFFFFFFFF)
@@ -1644,12 +1478,12 @@
     pMsg[4] = 0; /* universal context */
     pMsg[5] = 0; /* universal context */
     /* phys address to return status - area right after PAB */
-    pMsg[6] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
+    pMsg[6] = pPab->outMsgBlockPhyAddr;
     pMsg[7] = 0;
     pMsg[8] = 1;  /*  return 1 byte */
 
     /* virual pointer to return buffer - clear first two dwords */
-    p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
+    p32 = (volatile PU32)pPab->pLinOutMsgBlock;
     p32[0] = 0;
     p32[1] = 0;
 
@@ -1659,19 +1493,15 @@
 
     /* wait for response */
     timeout = 1000000;
-    while(1)
-    {
-        int i;
-        
-        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
-            ;
+    while(1) {        
+        udelay(10);     /* please don't hog the bus!!! */
             
         if (p32[0] || p32[1])
             break;
             
         if (!timeout--)
         {
-            printk("RCResetIOP timeout\n");
+            dprintk("RCResetIOP timeout\n");
             return RC_RTN_MSG_REPLY_TIMEOUT;
         }
     }
@@ -1692,16 +1522,14 @@
 ** =========================================================================
 */
 RC_RETURN 
-RCShutdownLANCard(U16 AdapterID, U16 ResourceFlags, PU32 ReturnAddr, PFNCALLBACK CallbackFunction)
+RCShutdownLANCard(struct net_device *dev, U16 ResourceFlags, 
+		  PU32 ReturnAddr, PFNCALLBACK CallbackFunction)
 {
     volatile PU32 pMsg;
     U32 off;
-    PPAB pPab;
-    int i;
+    PPAB pPab = ((PDPA)dev->priv)->pPab;
     long timeout = 0;
 
-    pPab = PCIAdapterBlock[AdapterID];
-
     if (pPab == NULL)
         return RC_RTN_ADPTR_NOT_REGISTERED;
 
@@ -1728,13 +1556,12 @@
            or until timer goes off */
         while (pPab->pCallbackFunc == (PFNCALLBACK)NULL)
         {
-            RCProcI2OMsgQ(AdapterID);
-            for (i = 0; i < 100000; i++)     /* please don't hog the bus!!! */
-                ;
+            RCProcI2OMsgQ(dev);
+            udelay(1000);     /* please don't hog the bus!!! */
             timeout++;
             if (timeout > 10000)
             {
-				printk("RCShutdownLANCard(): timeout\n");
+		printk(KERN_WARNING "(rcpci45 driver:) RCShutdownLANCard(): timeout\n");
                 break;
             }
         }
@@ -1758,13 +1585,11 @@
 ** =========================================================================
 */
 RC_RETURN
-RCSetRavlinIPandMask(U16 AdapterID, U32 ipAddr, U32 netMask)
+RCSetRavlinIPandMask(struct net_device *dev, U32 ipAddr, U32 netMask)
 {
     volatile PU32 pMsg;
     U32 off;
-    PPAB pPab;
-
-    pPab = PCIAdapterBlock[AdapterID];
+    PPAB pPab = ((PDPA)dev->priv)->pPab;
 
     if (pPab == NULL)
         return RC_RTN_ADPTR_NOT_REGISTERED;
@@ -1800,21 +1625,17 @@
 ** =========================================================================
 */
 RC_RETURN
-RCGetRavlinIPandMask(U16 AdapterID, PU32 pIpAddr, PU32 pNetMask, 
+RCGetRavlinIPandMask(struct net_device *dev, PU32 pIpAddr, PU32 pNetMask, 
                      PFNWAITCALLBACK WaitCallback)
 {
-    unsigned i, timeout;
+    unsigned timeout;
     U32      off;
     PU32     pMsg, p32;
-    PPAB     pPab;
+    PPAB     pPab = ((PDPA)dev->priv)->pPab;
     PATU     p_atu;
     
-#ifdef DEBUG
-    kprintf("RCGetRavlinIPandMask: pIpAddr is 0x%08.8ulx, *IpAddr is 0x%08.8ulx\n", pIpAddr, *pIpAddr);
-#endif /* DEBUG */
+    dprintk("RCGetRavlinIPandMask: pIpAddr is 0x%08ulx, *IpAddr is 0x%08ulx\n", (u32)pIpAddr, *pIpAddr);
 
-    pPab = PCIAdapterBlock[AdapterID];
-    
     if (pPab == NULL)
         return RC_RTN_ADPTR_NOT_REGISTERED;
     
@@ -1824,26 +1645,22 @@
     if (0xFFFFFFFF == off)
         return RC_RTN_FREE_Q_EMPTY;
 
-    p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
+    p32 = (volatile PU32)pPab->pLinOutMsgBlock;
     *p32 = 0xFFFFFFFF;
 
     pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
 
-#ifdef DEBUG
-    kprintf("RCGetRavlinIPandMask: p_atu 0x%08.8ulx, off 0x%08.8ulx, p32 0x%08.8ulx\n", p_atu, off, p32);
-#endif /* DEBUG */
+    dprintk("RCGetRavlinIPandMask: p_atu 0x%08ulx, off 0x%08ulx, p32 0x%08ulx\n", (u32)p_atu, off, (u32)p32);
     /* setup private message */
     pMsg[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0;
     pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
     pMsg[2] = 0;               /* initiator context */
     pMsg[3] = 0x218;           /* transaction context */
     pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_IP_AND_MASK;
-    pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
+    pMsg[5] = pPab->outMsgBlockPhyAddr;
 
     p_atu->InQueue = off;   /* send it to the I2O device */
-#ifdef DEBUG
-    kprintf("RCGetRavlinIPandMask: p_atu 0x%08.8ulx, off 0x%08.8ulx, p32 0x%08.8ulx\n", p_atu, off, p32);
-#endif /* DEBUG */
+    dprintk("RCGetRavlinIPandMask: p_atu 0x%08ulx, off 0x%08ulx, p32 0x%08ulx\n", (u32)p_atu, off, (u32)p32);
 
     /* wait for the rcpci45 board to update the info */
     timeout = 100000;
@@ -1851,32 +1668,24 @@
     {
         if (WaitCallback)
             (*WaitCallback)();
-    
-        for (i = 0; i < 1000; i++)
-            ;
+
+	udelay(10);
 
         if (!timeout--)
         {
-#ifdef DEBUG
-            kprintf("RCGetRavlinIPandMask: Timeout\n");
-#endif /* DEBUG */
+            dprintk("RCGetRavlinIPandMask: Timeout\n");
             return RC_RTN_MSG_REPLY_TIMEOUT;
         }
     }
 
-#ifdef DEBUG
-    kprintf("RCGetRavlinIPandMask: after time out\n", \
-            "p32[0] (IpAddr) 0x%08.8ulx, p32[1] (IPmask) 0x%08.8ulx\n", p32[0], p32[1]);
-#endif /* DEBUG */
+    dprintk("RCGetRavlinIPandMask: after time out\np32[0] (IpAddr) 0x%08ulx, p32[1] (IPmask) 0x%08ulx\n", p32[0], p32[1]);
     
     /* send IP and mask to user's space  */
     *pIpAddr  = p32[0];
     *pNetMask = p32[1];
 
 
-#ifdef DEBUG
-    kprintf("RCGetRavlinIPandMask: pIpAddr is 0x%08.8ulx, *IpAddr is 0x%08.8ulx\n", pIpAddr, *pIpAddr);
-#endif /* DEBUG */
+    dprintk("RCGetRavlinIPandMask: pIpAddr is 0x%08ulx, *IpAddr is 0x%08ulx\n", (u32)pIpAddr, *pIpAddr);
 
     return RC_RTN_NO_ERROR;
 }
@@ -1911,9 +1720,7 @@
     
     if (msgOffset == 0xFFFFFFFF)
     {
-#ifdef DEBUG
-        kprintf("SendI2OOutboundQInitMsg(): Inbound Free Q empty!\n");
-#endif /* DEBUG */
+        dprintk("SendI2OOutboundQInitMsg(): Inbound Free Q empty!\n");
         return RC_RTN_FREE_Q_EMPTY;
     }
     
@@ -1921,9 +1728,7 @@
     /* calc virual address of msg - virual already mapped to physical */    
     pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
 
-#ifdef DEBUG
-    kprintf("SendI2OOutboundQInitMsg - pMsg = 0x%08.8ulx, InQ msgOffset = 0x%08.8ulx\n", pMsg, msgOffset);
-#endif /* DEBUG */
+    dprintk("SendI2OOutboundQInitMsg - pMsg = 0x%08ulx, InQ msgOffset = 0x%08ulx\n", (u32)pMsg, msgOffset);
 
     pMsg[0] = EIGHT_WORD_MSG_SIZE | TRL_OFFSET_6;
     pMsg[1] = I2O_EXEC_OUTBOUND_INIT << 24 | I2O_HOST_TID << 12 | I2O_IOP_TID;
@@ -1933,10 +1738,10 @@
     pMsg[5] = MSG_FRAME_SIZE  << 16 | 0x80; /* outbound msg frame size and Initcode */
     pMsg[6] = 0xD0000004;       /* simple sgl element LE, EOB */
     /* phys address to return status - area right after PAB */
-    pMsg[7] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
+    pMsg[7] = pPab->outMsgBlockPhyAddr;
 
     /* virual pointer to return buffer - clear first two dwords */
-    p32 = (PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
+    p32 = (PU32)pPab->pLinOutMsgBlock;
     p32[0] = 0;
     
     /* post to Inbound Post Q */   
@@ -1946,17 +1751,14 @@
     timeout = 100000;
     while(1)
     {
-        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
-            ;
+        udelay(10);      /* please don't hog the bus!!! */
             
         if (p32[0])
             break;
             
         if (!timeout--)
         {
-#ifdef DEBUG
-            kprintf("Timeout wait for InitOutQ InPrgress status from IOP\n");
-#endif /* DEBUG */
+            dprintk("Timeout wait for InitOutQ InPrgress status from IOP\n");
             return RC_RTN_NO_I2O_STATUS;
         }
     }
@@ -1964,17 +1766,14 @@
     timeout = 100000;
     while(1)
     {
-        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
-            ;
+	udelay(10);    /* please don't hog the bus!!! */
             
         if (p32[0] == I2O_EXEC_OUTBOUND_INIT_COMPLETE)
             break;
 
         if (!timeout--)
         {
-#ifdef DEBUG
-            kprintf("Timeout wait for InitOutQ Complete status from IOP\n");
-#endif /* DEBUG */
+            dprintk("Timeout wait for InitOutQ Complete status from IOP\n");
             return RC_RTN_NO_I2O_STATUS;
         }
     }
@@ -2008,14 +1807,10 @@
     
     
     msgOffset = pPab->p_atu->InQueue; 
-#ifdef DEBUG
-    printk("GetI2OStatus: msg offset = 0x%x\n", msgOffset);
-#endif /* DEBUG */
+    dprintk("GetI2OStatus: msg offset = 0x%x\n", msgOffset);
     if (msgOffset == 0xFFFFFFFF)
     {
-#ifdef DEBUG
-        kprintf("GetI2OStatus(): Inbound Free Q empty!\n");
-#endif /* DEBUG */
+        dprintk("GetI2OStatus(): Inbound Free Q empty!\n");
         return RC_RTN_FREE_Q_EMPTY;
     }
 
@@ -2029,64 +1824,50 @@
     pMsg[4] = 0; /* universal context */
     pMsg[5] = 0; /* universal context */
     /* phys address to return status - area right after PAB */
-    pMsg[6] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
+    pMsg[6] = pPab->outMsgBlockPhyAddr;
     pMsg[7] = 0;
     pMsg[8] = 88;  /*  return 88 bytes */
 
     /* virual pointer to return buffer - clear first two dwords */
-    p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
+    p32 = (volatile PU32)pPab->pLinOutMsgBlock;
     p32[0] = 0;
     p32[1] = 0;
 
-#ifdef DEBUG
-    kprintf("GetI2OStatus - pMsg:0x%08.8ulx, msgOffset:0x%08.8ulx, [1]:0x%08.8ulx, [6]:0x%08.8ulx\n",
-            pMsg, msgOffset, pMsg[1], pMsg[6]);
-#endif /* DEBUG */
+    dprintk("GetI2OStatus - pMsg:0x%08ulx, msgOffset:0x%08ulx, [1]:0x%08ulx, [6]:0x%08ulx\n",
+            (u32)pMsg, msgOffset, pMsg[1], pMsg[6]);
    
     /* post to Inbound Post Q */   
     pPab->p_atu->InQueue = msgOffset;
     
-#ifdef DEBUG
-    kprintf("Return status to p32 = 0x%08.8ulx\n", p32);
-#endif /* DEBUG */
+    dprintk("Return status to p32 = 0x%08ulx\n", (u32)p32);
     
     /* wait for response */
     timeout = 1000000;
-    while(1)
-    {
-        int i;
-        
-        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
-            ;
+    while(1) {
+        udelay(10);      /* please don't hog the bus!!! */
             
         if (p32[0] && p32[1])
             break;
             
         if (!timeout--)
         {
-#ifdef DEBUG
-            kprintf("Timeout waiting for status from IOP\n");
-            kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[0], p32[1], p32[2], p32[3]);
-            kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[4], p32[5], p32[6], p32[7]);
-            kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[8], p32[9], p32[10], p32[11]);
-#endif /* DEBUG */
+            dprintk("Timeout waiting for status from IOP\n");
+            dprintk("0x%08ulx:0x%08ulx:0x%08ulx:0x%08ulx\n", p32[0], p32[1], p32[2], p32[3]);
+            dprintk("0x%08ulx:0x%08ulx:0x%08ulx:0x%08ulx\n", p32[4], p32[5], p32[6], p32[7]);
+            dprintk("0x%08ulx:0x%08ulx:0x%08ulx:0x%08ulx\n", p32[8], p32[9], p32[10], p32[11]);
             return RC_RTN_NO_I2O_STATUS;
         }
     }
             
-#ifdef DEBUG
-    kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[0], p32[1], p32[2], p32[3]);
-    kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[4], p32[5], p32[6], p32[7]);
-    kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[8], p32[9], p32[10], p32[11]);
-#endif /* DEBUG */
+    dprintk("0x%08ulx:0x%08ulx:0x%08ulx:0x%08ulx\n", p32[0], p32[1], p32[2], p32[3]);
+    dprintk("0x%08ulx:0x%08ulx:0x%08ulx:0x%08ulx\n", p32[4], p32[5], p32[6], p32[7]);
+    dprintk("0x%08ulx:0x%08ulx:0x%08ulx:0x%08ulx\n", p32[8], p32[9], p32[10], p32[11]);
     /* get IOP state */
     pPab->IOPState = ((volatile PU8)p32)[10];
     pPab->InboundMFrameSize  = ((volatile PU16)p32)[6];
     
-#ifdef DEBUG
-    kprintf("IOP state 0x%02.2x InFrameSize = 0x%04.4x\n", 
+    dprintk("IOP state 0x%02x InFrameSize = 0x%04x\n", 
             pPab->IOPState, pPab->InboundMFrameSize);
-#endif /* DEBUG */
     return RC_RTN_NO_ERROR;
 }
 
@@ -2101,25 +1882,21 @@
 static int 
 SendEnableSysMsg(PPAB pPab)
 {
-    U32 msgOffset; // timeout;
+    U32 msgOffset; 
     volatile PU32 pMsg;
 
     msgOffset = pPab->p_atu->InQueue;
 
     if (msgOffset == 0xFFFFFFFF)
     {
-#ifdef DEBUG
-        kprintf("SendEnableSysMsg(): Inbound Free Q empty!\n");
-#endif /* DEBUG */
+        dprintk("SendEnableSysMsg(): Inbound Free Q empty!\n");
         return RC_RTN_FREE_Q_EMPTY;
     }
 
     /* calc virual address of msg - virual already mapped to physical */
     pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
 
-#ifdef DEBUG
-    kprintf("SendEnableSysMsg - pMsg = 0x%08.8ulx, InQ msgOffset = 0x%08.8ulx\n", pMsg, msgOffset);
-#endif /* DEBUG */
+    dprintk("SendEnableSysMsg - pMsg = 0x%08ulx, InQ msgOffset = 0x%08ulx\n", (u32)pMsg, msgOffset);
 
     pMsg[0] = FOUR_WORD_MSG_SIZE | SGL_OFFSET_0;
     pMsg[1] = I2O_EXEC_SYS_ENABLE << 24 | I2O_HOST_TID << 12 | I2O_IOP_TID;
@@ -2160,12 +1937,10 @@
     pMsg = pMsgFrame;
     nmbrDwords = 0;
 
-#ifdef DEBUG
-    kprintf("FillI2OMsgSGLFromTCBX\n");
-    kprintf("TCB  0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n",
+    dprintk("FillI2OMsgSGLFromTCBX\n");
+    dprintk("TCB  0x%08ulx:0x%08ulx:0x%08ulx:0x%08ulx:0x%08ulx\n",
             pTCB[0], pTCB[1], pTCB[2], pTCB[3], pTCB[4]);
-    kprintf("pTCB 0x%08.8ulx, pMsg 0x%08.8ulx\n", pTCB, pMsg);
-#endif /* DEBUG */
+    dprintk("pTCB 0x%08ulx, pMsg 0x%08ulx\n", (u32)pTCB, (u32)pMsg);
     
     nmbrBuffers = *pTCB++;
     
@@ -2245,23 +2020,19 @@
 {
     PU8 p8Msg;
     PU32 p32;
-    //  U16 count;
+/*      U16 count; */
     
     
     p8Msg = pPab->pLinOutMsgBlock + (phyAddrMsg - pPab->outMsgBlockPhyAddr);
     p32 = (PU32)p8Msg;
     
-#ifdef DEBUG
-    kprintf("VXD: ProcessOutboundI2OMsg - pPab 0x%08.8ulx, phyAdr 0x%08.8ulx, linAdr 0x%08.8ulx\n", pPab, phyAddrMsg, p8Msg);
-    kprintf("msg :0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[0], p32[1], p32[2], p32[3]);
-    kprintf("msg :0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[4], p32[5], p32[6], p32[7]);
-#endif /* DEBUG */
+    dprintk("VXD: ProcessOutboundI2OMsg - pPab 0x%08ulx, phyAdr 0x%08ulx, linAdr 0x%08ulx\n", (u32)pPab, phyAddrMsg, (u32)p8Msg);
+    dprintk("msg :0x%08ulx:0x%08ulx:0x%08ulx:0x%08ulx\n", p32[0], p32[1], p32[2], p32[3]);
+    dprintk("msg :0x%08ulx:0x%08ulx:0x%08ulx:0x%08ulx\n", p32[4], p32[5], p32[6], p32[7]);
 
     if (p32[4] >> 24 != I2O_REPLY_STATUS_SUCCESS)
     {
-#ifdef DEBUG
-        kprintf("Message reply status not success\n");
-#endif /* DEBUG */
+        dprintk("Message reply status not success\n");
         return;
     }
     
@@ -2269,36 +2040,26 @@
     {
     case I2O_EXEC_SYS_TAB_SET:
         msgFlag = 1;
-#ifdef DEBUG
-        kprintf("Received I2O_EXEC_SYS_TAB_SET reply\n");
-#endif /* DEBUG */
+        dprintk("Received I2O_EXEC_SYS_TAB_SET reply\n");
         break;
 
     case I2O_EXEC_HRT_GET:
         msgFlag = 1;
-#ifdef DEBUG
-        kprintf("Received I2O_EXEC_HRT_GET reply\n");
-#endif /* DEBUG */
+        dprintk("Received I2O_EXEC_HRT_GET reply\n");
         break;
         
     case I2O_EXEC_LCT_NOTIFY:
         msgFlag = 1;
-#ifdef DEBUG
-        kprintf("Received I2O_EXEC_LCT_NOTIFY reply\n");
-#endif /* DEBUG */
+        dprintk("Received I2O_EXEC_LCT_NOTIFY reply\n");
         break;
         
     case I2O_EXEC_SYS_ENABLE:
         msgFlag = 1;
-#ifdef DEBUG
-        kprintf("Received I2O_EXEC_SYS_ENABLE reply\n");
-#endif /* DEBUG */
+        dprintk("Received I2O_EXEC_SYS_ENABLE reply\n");
         break;
 
     default:    
-#ifdef DEBUG
-        kprintf("Received UNKNOWN reply\n");
-#endif /* DEBUG */
+        dprintk("Received UNKNOWN reply\n");
         break;
     }
 }
diff -urN linux-2.4.2-pre1/drivers/net/rclanmtl.h linux/drivers/net/rclanmtl.h
--- linux-2.4.2-pre1/drivers/net/rclanmtl.h	Mon Dec 11 13:01:09 2000
+++ linux/drivers/net/rclanmtl.h	Mon Dec  3 22:27:48 2001
@@ -39,34 +39,31 @@
 
 /* Linux specific includes */
 #include <asm/types.h>
-#define kprintf printk
 #ifdef RC_LINUX_MODULE     /* linux modules need non-library version of string functions */
 #include <linux/string.h>
 #else
 #include <string.h>
 #endif
+#include <linux/delay.h> /* for udelay() */
 
-/* PCI/45 Configuration space values */
-#define RC_PCI45_VENDOR_ID  0x4916
-#define RC_PCI45_DEVICE_ID  0x1960
+#include <linux/netdevice.h>
+#include <linux/if_ether.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
 
+#include <asm/io.h>
 
- /* RedCreek API function return values */
-#define RC_RTN_NO_ERROR             0
-#define RC_RTN_I2O_NOT_INIT         1
-#define RC_RTN_FREE_Q_EMPTY         2
-#define RC_RTN_TCB_ERROR            3
-#define RC_RTN_TRANSACTION_ERROR    4
-#define RC_RTN_ADAPTER_ALREADY_INIT 5
-#define RC_RTN_MALLOC_ERROR         6
-#define RC_RTN_ADPTR_NOT_REGISTERED 7
-#define RC_RTN_MSG_REPLY_TIMEOUT    8
-#define RC_RTN_NO_I2O_STATUS        9
-#define RC_RTN_NO_FIRM_VER         10
-#define RC_RTN_NO_LINK_SPEED       11
+/* Debug stuff. Define for debug output */
+#define RCDEBUG
 
-/* Driver capability flags */
-#define WARM_REBOOT_CAPABLE      0x01
+#ifdef RCDEBUG
+#define dprintk(args...) printk(KERN_DEBUG "(rcpci45 driver:) " args)
+#else
+#define dprintk(args...) { }
+#endif
+
+
+/* Typedefs */
 
  /* scalar data types */
 typedef __u8		U8;
@@ -78,7 +75,6 @@
 typedef unsigned long   BF;
 typedef int             RC_RETURN;
 
-
  /* 
  ** type PFNWAITCALLBACK
  **
@@ -116,7 +112,7 @@
                               U8   PktCount,
                               U32  BucketsRemain,
                               PU32 PacketDescBlock,
-                              U16  AdapterID);
+                              struct net_device *);
 
  /* 
  ** type PFNCALLBACK 
@@ -129,7 +125,105 @@
 typedef void (*PFNCALLBACK)(U32  Status,
                               U32  Param1,
                               U32  Param2,
-                              U16  AdapterID);
+                              struct net_device *dev);
+
+/*
+**  Message Unit CSR definitions for RedCreek PCI45 board
+*/
+typedef struct tag_rcatu 
+{
+    volatile unsigned long APICRegSel;  /* APIC Register Select */
+    volatile unsigned long reserved0;
+    volatile unsigned long APICWinReg;  /* APIC Window Register */
+    volatile unsigned long reserved1;
+    volatile unsigned long InMsgReg0;   /* inbound message register 0 */
+    volatile unsigned long InMsgReg1;   /* inbound message register 1 */
+    volatile unsigned long OutMsgReg0;  /* outbound message register 0 */
+    volatile unsigned long OutMsgReg1;  /* outbound message register 1 */
+    volatile unsigned long InDoorReg;   /* inbound doorbell register */
+    volatile unsigned long InIntStat;   /* inbound interrupt status register */
+    volatile unsigned long InIntMask;   /* inbound interrupt mask register */
+    volatile unsigned long OutDoorReg;  /* outbound doorbell register */
+    volatile unsigned long OutIntStat;  /* outbound interrupt status register */
+    volatile unsigned long OutIntMask;  /* outbound interrupt mask register */
+    volatile unsigned long reserved2;
+    volatile unsigned long reserved3;
+    volatile unsigned long InQueue;     /* inbound queue port */
+    volatile unsigned long OutQueue;    /* outbound queue port */
+    volatile unsigned long reserved4;
+    volatile unsigned long reserver5;
+    /* RedCreek extension */
+    volatile unsigned long EtherMacLow;
+    volatile unsigned long EtherMacHi;
+    volatile unsigned long IPaddr;
+    volatile unsigned long IPmask;
+} *PATU;
+
+ /* 
+ ** typedef PAB
+ **
+ ** PCI Adapter Block - holds instance specific information.
+ */
+typedef struct
+{
+    PATU             p_atu;                /* ptr to  ATU register block */
+    PU8              pPci45LinBaseAddr;
+    PU8              pLinOutMsgBlock;
+    U32              outMsgBlockPhyAddr; 
+    PFNTXCALLBACK    pTransCallbackFunc;
+    PFNRXCALLBACK    pRecvCallbackFunc;
+    PFNCALLBACK      pRebootCallbackFunc;
+    PFNCALLBACK      pCallbackFunc;
+    U16              IOPState;
+    U16              InboundMFrameSize;
+} *PPAB;
+
+/*
+ * Driver Private Area, DPA.
+ */
+typedef struct
+{
+    U8     id;                        /* the AdapterID */
+
+    /* These two field are basically for the RCioctl function.
+     * I could not determine if they could be avoided. (RAA)*/
+    U32    pci_addr;               /* the pci address of the adapter */
+    U32    pci_addr_len;
+
+    struct timer_list timer;        /*  timer */
+    struct net_device_stats  stats; /* the statistics structure */
+    unsigned long numOutRcvBuffers;/* number of outstanding receive buffers*/
+    unsigned char shutdown;
+    unsigned char reboot;
+    unsigned char nexus;
+    PU8    msgbuf;            /* Pointer to Lan Api Private Area */
+    PU8    PLanApiPA;         /* Pointer to Lan Api Private Area (aligned) */
+    PPAB   pPab;              /* Pointer to the PCI Adapter Block */
+} *PDPA;
+
+
+
+/* PCI/45 Configuration space values */
+#define RC_PCI45_VENDOR_ID  0x4916
+#define RC_PCI45_DEVICE_ID  0x1960
+
+
+ /* RedCreek API function return values */
+#define RC_RTN_NO_ERROR             0
+#define RC_RTN_I2O_NOT_INIT         1
+#define RC_RTN_FREE_Q_EMPTY         2
+#define RC_RTN_TCB_ERROR            3
+#define RC_RTN_TRANSACTION_ERROR    4
+#define RC_RTN_ADAPTER_ALREADY_INIT 5
+#define RC_RTN_MALLOC_ERROR         6
+#define RC_RTN_ADPTR_NOT_REGISTERED 7
+#define RC_RTN_MSG_REPLY_TIMEOUT    8
+#define RC_RTN_NO_I2O_STATUS        9
+#define RC_RTN_NO_FIRM_VER         10
+#define RC_RTN_NO_LINK_SPEED       11
+
+/* Driver capability flags */
+#define WARM_REBOOT_CAPABLE      0x01
 
 /*
 ** Status - Transmit and Receive callback status word 
@@ -298,21 +392,15 @@
  ** transport layer.  This buffer must be a contigous memory block of a 
  ** minimum of 16K bytes and long word aligned.  The user also must provide
  ** the base address of the RedCreek PCI adapter assigned by BIOS or operating
- ** system.  The user provided value AdapterID is a zero based index of the
- ** Ravlin 45/PCI adapter.  This interface number is used in all subsequent API
- ** calls to identify which adpapter for which the function is intended.  
- ** Up to sixteen interfaces are supported with this API.
- **
- ** Inputs:  AdapterID - interface number from 0 to 15
- **          pciBaseAddr - virual base address of PCI (set by BIOS)
- **          p_msgbuf - virual address to private message block (min. 16K)
- **          p_phymsgbuf - physical address of private message block
+ ** system.  
+ **
+ ** Inputs:  dev - the net_device struct for the device.
  **          TransmitCallbackFunction - address of user's TX callback function
  **          ReceiveCallbackFunction  - address of user's RX callback function
+ **          RebootCallbackFunction  - address of user's reboot callback function
  **
  */
-RC_RETURN RCInitI2OMsgLayer(U16 AdapterID, U32 pciBaseAddr, 
-                            PU8 p_msgbuf,  PU8 p_phymsgbuf,
+RC_RETURN RCInitI2OMsgLayer(struct net_device *dev,
                             PFNTXCALLBACK TransmitCallbackFunction,
                             PFNRXCALLBACK ReceiveCallbackFunction,
                             PFNCALLBACK   RebootCallbackFunction);
@@ -327,7 +415,7 @@
  ** 0x04030201 and 0x00FFFFFF on a little endian machine.
  **
  */
-RC_RETURN RCSetRavlinIPandMask(U16 AdapterID, U32 ipAddr, U32 netMask);
+RC_RETURN RCSetRavlinIPandMask(struct net_device *dev, U32 ipAddr, U32 netMask);
 
 
 /*
@@ -339,7 +427,7 @@
 ** =========================================================================
 */
 RC_RETURN
-RCGetRavlinIPandMask(U16 AdapterID, PU32 pIpAddr, PU32 pNetMask, 
+RCGetRavlinIPandMask(struct net_device *dev, PU32 pIpAddr, PU32 pNetMask, 
                         PFNWAITCALLBACK WaitCallback);
 
  /* 
@@ -351,7 +439,7 @@
  ** callback functions, TransmitCallbackFunction or ReceiveCallbackFunction,
  ** if a TX or RX transaction has completed.
  */
-void RCProcI2OMsgQ(U16 AdapterID);
+void RCProcI2OMsgQ(struct net_device *dev);
 
 
  /*
@@ -362,8 +450,8 @@
  ** will prevent hardware interrupt to host even though the outbound I2O msg
  ** queue is not emtpy.
  */
-RC_RETURN RCEnableI2OInterrupts(U16 adapterID);
-RC_RETURN RCDisableI2OInterrupts(U16 AdapterID);
+RC_RETURN RCEnableI2OInterrupts(struct net_device *dev);
+RC_RETURN RCDisableI2OInterrupts(struct net_device *dev);
 
 
  /* 
@@ -378,7 +466,7 @@
  ** to the RedCreek adapter are considered owned by the adapter until the
  ** context is return to user through the ReceiveCallbackFunction.
  */
-RC_RETURN RCPostRecvBuffers(U16 AdapterID, PRCTCB pTransactionCtrlBlock);
+RC_RETURN RCPostRecvBuffers(struct net_device *dev, PRCTCB pTransactionCtrlBlock);
 #define MAX_NMBR_POST_BUFFERS_PER_MSG 32
 
  /*
@@ -391,7 +479,7 @@
  ** Transmit buffer are considered owned by the adapter until context's
  ** returned to user through the TransmitCallbackFunction.
  */
-RC_RETURN RCI2OSendPacket(U16 AdapterID, 
+RC_RETURN RCI2OSendPacket(struct net_device *dev, 
                           U32 context, 
                           PRCTCB pTransactionCtrlBlock);
 
@@ -425,7 +513,7 @@
  ** If given, not NULL, the function WaitCallback is called during the wait
  ** loop while waiting for the adapter to respond.
  */
-RC_RETURN RCGetLinkStatistics(U16 AdapterID,
+RC_RETURN RCGetLinkStatistics(struct net_device *dev,
                               P_RCLINKSTATS StatsReturnAddr,
                               PFNWAITCALLBACK WaitCallback);
 
@@ -436,7 +524,7 @@
  ** If given, not NULL, the function WaitCallback is called during the wait
  ** loop while waiting for the adapter to respond.
  */
-RC_RETURN RCGetLinkStatus(U16 AdapterID, 
+RC_RETURN RCGetLinkStatus(struct net_device *dev, 
                           PU32 pReturnStatus,
                           PFNWAITCALLBACK WaitCallback);
                                
@@ -453,7 +541,7 @@
  ** adapter runs in promiscous mode because of the dual address requirement.
  ** The MAC address is returned to the unsigned char array pointer to by mac.
  */
-RC_RETURN RCGetMAC(U16 AdapterID, PU8 mac, PFNWAITCALLBACK WaitCallback);
+RC_RETURN RCGetMAC(struct net_device *dev, PFNWAITCALLBACK WaitCallback);
 
  /*
  ** RCSetMAC()
@@ -461,14 +549,14 @@
  ** Set a new user port MAC address.  This address will be returned on
  ** subsequent RCGetMAC() calls.
  */
-RC_RETURN RCSetMAC(U16 AdapterID, PU8 mac);
+RC_RETURN RCSetMAC(struct net_device *dev, PU8 mac);
 
  /*
  ** RCSetLinkSpeed()
  **
  ** set adapter's link speed based on given input code.
  */
-RC_RETURN RCSetLinkSpeed(U16 AdapterID, U16 LinkSpeedCode);
+RC_RETURN RCSetLinkSpeed(struct net_device *dev, U16 LinkSpeedCode);
  /* Set link speed codes */
 #define LNK_SPD_AUTO_NEG_NWAY   0
 #define LNK_SPD_100MB_FULL      1
@@ -492,10 +580,10 @@
 #define LNK_SPD_10MB_HALF       4
 
 RC_RETURN
-RCGetLinkSpeed(U16 AdapterID, PU32 pLinkSpeedCode, PFNWAITCALLBACK WaitCallback);
+RCGetLinkSpeed(struct net_device *dev, PU32 pLinkSpeedCode, PFNWAITCALLBACK WaitCallback);
 /*
 ** =========================================================================
-** RCSetPromiscuousMode(U16 AdapterID, U16 Mode)
+** RCSetPromiscuousMode(struct net_device *dev, U16 Mode)
 **
 ** Defined values for Mode:
 **  0 - turn off promiscuous mode
@@ -506,10 +594,10 @@
 #define PROMISCUOUS_MODE_OFF 0
 #define PROMISCUOUS_MODE_ON  1
 RC_RETURN
-RCSetPromiscuousMode(U16 AdapterID, U16 Mode);
+RCSetPromiscuousMode(struct net_device *dev, U16 Mode);
 /*
 ** =========================================================================
-** RCGetPromiscuousMode(U16 AdapterID, PU32 pMode, PFNWAITCALLBACK WaitCallback)
+** RCGetPromiscuousMode(struct net_device *dev, PU32 pMode, PFNWAITCALLBACK WaitCallback)
 **
 ** get promiscuous mode setting
 **
@@ -520,11 +608,11 @@
 ** =========================================================================
 */
 RC_RETURN
-RCGetPromiscuousMode(U16 AdapterID, PU32 pMode, PFNWAITCALLBACK WaitCallback);
+RCGetPromiscuousMode(struct net_device *dev, PU32 pMode, PFNWAITCALLBACK WaitCallback);
 
 /*
 ** =========================================================================
-** RCSetBroadcastMode(U16 AdapterID, U16 Mode)
+** RCSetBroadcastMode(struct net_device *dev, U16 Mode)
 **
 ** Defined values for Mode:
 **  0 - turn off promiscuous mode
@@ -535,10 +623,10 @@
 #define BROADCAST_MODE_OFF 0
 #define BROADCAST_MODE_ON  1
 RC_RETURN
-RCSetBroadcastMode(U16 AdapterID, U16 Mode);
+RCSetBroadcastMode(struct net_device *dev, U16 Mode);
 /*
 ** =========================================================================
-** RCGetBroadcastMode(U16 AdapterID, PU32 pMode, PFNWAITCALLBACK WaitCallback)
+** RCGetBroadcastMode(struct net_device *dev, PU32 pMode, PFNWAITCALLBACK WaitCallback)
 **
 ** get broadcast mode setting
 **
@@ -549,10 +637,10 @@
 ** =========================================================================
 */
 RC_RETURN
-RCGetBroadcastMode(U16 AdapterID, PU32 pMode, PFNWAITCALLBACK WaitCallback);
+RCGetBroadcastMode(struct net_device *dev, PU32 pMode, PFNWAITCALLBACK WaitCallback);
 /*
 ** =========================================================================
-** RCReportDriverCapability(U16 AdapterID, U32 capability)
+** RCReportDriverCapability(struct net_device *dev, U32 capability)
 **
 ** Currently defined bits:
 ** WARM_REBOOT_CAPABLE   0x01
@@ -560,7 +648,7 @@
 ** =========================================================================
 */
 RC_RETURN
-RCReportDriverCapability(U16 AdapterID, U32 capability);
+RCReportDriverCapability(struct net_device *dev, U32 capability);
 
 /*
 ** RCGetFirmwareVer()
@@ -570,7 +658,7 @@
 ** WARNING: user's space pointed to by pFirmString should be at least 60 bytes.
 */
 RC_RETURN
-RCGetFirmwareVer(U16 AdapterID, PU8 pFirmString, PFNWAITCALLBACK WaitCallback);
+RCGetFirmwareVer(struct net_device *dev, PU8 pFirmString, PFNWAITCALLBACK WaitCallback);
 
 /*
 ** ----------------------------------------------
@@ -601,7 +689,7 @@
  ** operation if the receive buffers were returned during LANReset.
  ** Note: The IOP status is not affected by a LAN reset.
  */
-RC_RETURN RCResetLANCard(U16 AdapterID, U16 ResourceFlags, PU32 ReturnAddr, PFNCALLBACK CallbackFunction);
+RC_RETURN RCResetLANCard(struct net_device *dev, U16 ResourceFlags, PU32 ReturnAddr, PFNCALLBACK CallbackFunction);
 
 
  /*
@@ -623,7 +711,7 @@
  ** Note: The IOP status is not affected by a LAN shutdown.
  */                                      
 RC_RETURN 
-RCShutdownLANCard(U16 AdapterID, U16 ResourceFlags, PU32 ReturnAddr, PFNCALLBACK CallbackFunction);
+RCShutdownLANCard(struct net_device *dev, U16 ResourceFlags, PU32 ReturnAddr, PFNCALLBACK CallbackFunction);
 
  /*
  ** RCResetIOP();
@@ -633,6 +721,6 @@
  **     Clears outbound message Q. 
  */
 RC_RETURN 
-RCResetIOP(U16 AdapterID);
+RCResetIOP(struct net_device *dev);
 
 #endif /* RCLANMTL_H */
diff -urN linux-2.4.2-pre1/drivers/net/rcpci45.c linux/drivers/net/rcpci45.c
--- linux-2.4.2-pre1/drivers/net/rcpci45.c	Mon Jan  1 10:17:49 2001
+++ linux/drivers/net/rcpci45.c	Mon Dec  3 22:27:48 2001
@@ -15,12 +15,6 @@
 ** 
 ** None known at this time.
 **
-**  TODO:
-**      -Get rid of the wait loops in the API and replace them
-**       with system independent delays ...something like
-**       "delayms(2)".  However, under normal circumstances, the 
-**       delays are very short so they're not a problem.
-**
 **  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
@@ -36,7 +30,8 @@
 **  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 **
 **   
-**  Rasmus Andersen, December 2000: Converted to new PCI API.
+**  Rasmus Andersen, December 2000: Converted to new PCI API and general
+**  cleanup.
 **
 **  Pete Popov, January 11,99: Fixed a couple of 2.1.x problems 
 **  (virt_to_bus() not called), tested it under 2.2pre5 (as a module), and 
@@ -64,13 +59,8 @@
 #include <linux/timer.h>
 #include <asm/irq.h>            /* For NR_IRQS only. */
 #include <asm/bitops.h>
-#include <asm/io.h>
 #include <asm/uaccess.h>
 
-#include <linux/if_ether.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
 
 
 static char version[] __initdata =
@@ -83,7 +73,6 @@
 #define RUN_AT(x) (jiffies + (x))
 
 #define NEW_MULTICAST
-#include <linux/delay.h>
 
 /* PCI/45 Configuration space values */
 #define RC_PCI45_VENDOR_ID  0x4916
@@ -106,38 +95,7 @@
 
 static void rc_timer(unsigned long);
 
-/*
- * Driver Private Area, DPA.
- */
-typedef struct
-{
-
-    /* 
-     *    pointer to the device structure which is part
-     * of the interface to the Linux kernel.
-     */
-    struct net_device *dev;            
-     
-    U8     id;                        /* the AdapterID */
-    U32    pci_addr;               /* the pci address of the adapter */
-    U32    bus;
-    U32    function;
-    struct timer_list timer;        /*  timer */
-    struct net_device_stats  stats; /* the statistics structure */
-    unsigned long numOutRcvBuffers;/* number of outstanding receive buffers*/
-    unsigned char shutdown;
-    unsigned char reboot;
-    unsigned char nexus;
-    PU8    PLanApiPA;             /* Pointer to Lan Api Private Area */
-
-}
-DPA, *PDPA;
-
-#define MAX_ADAPTERS 32
-
-static PDPA  PCIAdapters[MAX_ADAPTERS];
-
-static int RCinit(struct net_device *dev);
+static int RCinit(struct net_device *);
 
 static int RCopen(struct net_device *);
 static int RC_xmit_packet(struct sk_buff *, struct net_device *);
@@ -146,35 +104,39 @@
 static struct net_device_stats *RCget_stats(struct net_device *);
 static int RCioctl(struct net_device *, struct ifreq *, int);
 static int RCconfig(struct net_device *, struct ifmap *);
-static void RCxmit_callback(U32, U16, PU32, U16);
-static void RCrecv_callback(U32, U8, U32, PU32, U16);
-static void RCreset_callback(U32, U32, U32, U16);
-static void RCreboot_callback(U32, U32, U32, U16);
+static void RCxmit_callback(U32, U16, PU32, struct net_device *);
+static void RCrecv_callback(U32, U8, U32, PU32, struct net_device *);
+static void RCreset_callback(U32, U32, U32, struct net_device *);
+static void RCreboot_callback(U32, U32, U32, struct net_device *);
 static int RC_allocate_and_post_buffers(struct net_device *, int);
 
 
 static struct pci_device_id rcpci45_pci_table[] __devinitdata = {
-	{ RC_PCI45_VENDOR_ID, RC_PCI45_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0, }
+	{ RC_PCI45_VENDOR_ID, RC_PCI45_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, },
+	{ }
 };
 MODULE_DEVICE_TABLE(pci, rcpci45_pci_table);
 
-static void rcpci45_remove_one(struct pci_dev *pdev)
+static void __exit rcpci45_remove_one(struct pci_dev *pdev)
 {
 	struct net_device *dev = pdev->driver_data;
 	PDPA pDpa = dev->priv;
 
         if (!dev) {
-                printk (KERN_ERR "remove non-existent device\n");
+                printk (KERN_ERR "(rcpci45 driver:) remove non-existent device\n");
                 return;
         }
 
-	printk("IOP reset: 0x%x\n", RCResetIOP(pDpa->id));
+	dprintk("remove_one: IOP reset: 0x%x\n", RCResetIOP(dev));
 
-	unregister_netdev(dev);
+	/* RAA Inspired by starfire.c and yellowfin.c we keep these
+	 * here. */
+  	unregister_netdev(dev);
+	free_irq(dev->irq, dev); 
 	iounmap((void *)dev->base_addr);
-        free_irq(dev->irq, dev);
-
+	kfree(pDpa->PLanApiPA);
+	kfree(pDpa->pPab);
+	kfree(pDpa);
 	kfree(dev);
 }
 
@@ -192,18 +154,16 @@
 static int rcpci45_init_one(struct pci_dev *pdev, 
 			    const struct pci_device_id *ent)
 {
-    int dev_size = 32768;        
-    unsigned long *vaddr=0;
+    unsigned long *vaddr;
     PDPA pDpa;
-    int init_status;
-
-    long memaddr = pci_resource_start(pdev, 0);
-    int card_idx;    
+    int error = -ENOMEM;
+    static int card_idx = -1;
     struct net_device *dev;
+    unsigned long pci_start = pci_resource_start(pdev,0);
+    unsigned long pci_len = pci_resource_len(pdev,0);
+    
 
-    static int card_counter = 0;
-
-    card_idx = card_counter++; /* Yeah, icky hack. */
+    card_idx++;
 
     /* 
      * Allocate and fill new device structure. 
@@ -214,111 +174,80 @@
      * the LAN API layer.
      */
 
-    dev = (struct net_device *) kmalloc(dev_size, GFP_DMA | GFP_KERNEL |GFP_ATOMIC);
-    if (!dev)
-    {
-        printk("rcpci45 driver: unable to kmalloc dev struct\n");
-        return 1;   
+    dev = init_etherdev(NULL, sizeof(*pDpa));
+    if (!dev) {
+	printk(KERN_ERR "(rcpci45 driver:) unable to allocate in init_etherdev\n");
+	goto err_out;
     }
-    memset(dev, 0, dev_size);
 
     pdev->driver_data = dev;
-
-    /*
-     * dev->priv will point to the start of DPA.
-     */
-    dev->priv = (void *)(((long)dev + sizeof(struct net_device) + 15) & ~15);
-
-#ifdef RCDEBUG
-    printk("rc: dev = 0x%x, dev->priv = 0x%x\n", (uint)dev, (uint)dev->priv);
-#endif
     
     pDpa = dev->priv;
+    pDpa->id = card_idx;
+    pDpa->pci_addr = pci_start;
 
-    pDpa->dev = dev;            /* this is just for easy reference */
-    pDpa->function = pdev->devfn;
-    pDpa->bus = (unsigned char)pdev->bus->number;
-    pDpa->id = card_idx;        /* the device number */
-    pDpa->pci_addr = memaddr;
-    PCIAdapters[card_idx] = pDpa;
-
-#ifdef RCDEBUG
-    printk("rc: pDpa = 0x%x, id = %d \n", (uint)pDpa, (uint)pDpa->id);
-#endif
+    if (!pci_start || !(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
+	printk(KERN_ERR "(rcpci45 driver:) No PCI memory resources! Aborting.\n");
+	goto err_out_free_dev;
+    }    
 
     /*
      * Save the starting address of the LAN API private area.  We'll
      * pass that to RCInitI2OMsgLayer().
      */
-    pDpa->PLanApiPA = (void *)(((long)pDpa + sizeof(DPA) + 0xff) & ~0xff);
-#ifdef RCDEBUG
-    printk("rc: pDpa->PLanApiPA = 0x%x\n", (uint)pDpa->PLanApiPA);
-#endif
+    /* RAA FIXME: This size should be a #define somewhere after I
+     * clear up some questions: What flags are neeeded in the alloc below
+     * and what needs to be done before the memarea is long word aligned?
+     * (Look in old code for an approach.) (Also note that the 16K below
+     * is substantially less than the 32K allocated before (even though
+     * some of the spacce was used for data structures.) */
+    pDpa->msgbuf = kmalloc(16384, GFP_KERNEL);
+    if (!pDpa->msgbuf) {
+        printk(KERN_ERR "(rcpci45 driver:) Could not allocate %d byte memory for the private msgbuf!\n", 16384); /* RAA FIXME not hardcoded! */
+	goto err_out_free_dev;
+    }
+    pDpa->PLanApiPA = (void *)(((long)pDpa->msgbuf + 0xff) & ~0xff);
+
+    dprintk("pDpa->PLanApiPA = 0x%x\n", (uint)pDpa->PLanApiPA);
     
-    /* The adapter is accessable through memory-access read/write, not
+    /* The adapter is accessible through memory-access read/write, not
      * I/O read/write.  Thus, we need to map it to some virtual address
-     * area in order to access the registers are normal memory.
-     */
-    vaddr = (ulong *) ioremap (memaddr, 2*32768);
-#ifdef RCDEBUG
-    printk("rc: RCfound_device: 0x%x, priv = 0x%x, vaddr = 0x%x\n", 
-           (uint)dev, (uint)dev->priv, (uint)vaddr);
-#endif
-    dev->base_addr = (unsigned long)vaddr;
-    dev->irq = pdev->irq;
-
-    /*
-     * Request a shared interrupt line.
+     * area in order to access the registers as normal memory.
      */
-    if ( request_irq(dev->irq, (void *)RCinterrupt,
-                     SA_INTERRUPT|SA_SHIRQ, "RedCreek VPN Adapter", dev) )
-    {
-        printk( "RC PCI 45: %s: unable to get IRQ %d\n", (PU8)dev->name, (uint)dev->irq );
-        iounmap(vaddr);
-        kfree(dev);
-        return 1;
+    if (request_mem_region(pci_start, pci_len, dev->name) == NULL) {
+        printk(KERN_ERR "(rcpci45 driver:) %d: resource 0x%lx @ 0x%lx busy, aborting\n",card_idx, pci_start, pci_len);
+	goto err_out_free_msgbuf;
     }
 
-    init_status = RCInitI2OMsgLayer(pDpa->id, dev->base_addr, 
-                  pDpa->PLanApiPA, (PU8)virt_to_bus((void *)pDpa->PLanApiPA),
-                  (PFNTXCALLBACK)RCxmit_callback,
-                  (PFNRXCALLBACK)RCrecv_callback,
-                  (PFNCALLBACK)RCreboot_callback);
-    if (init_status)
-    {
-        printk("rc: Unable to initialize msg layer\n");
-        free_irq(dev->irq, dev);
-        iounmap(vaddr);
-        kfree(dev);
-        return 1;
+    if (pci_enable_device(pdev)) {
+        printk(KERN_ERR "(rcpci45 driver:) %d: unable to enable pci device, aborting\n",card_idx);
+	goto err_out_free_msgbuf;
     }
-    if (RCGetMAC(pDpa->id, dev->dev_addr, NULL))
-    {
-        printk("rc: Unable to get adapter MAC\n");
-        free_irq(dev->irq, dev);
-        iounmap(vaddr);
-        kfree(dev);
-        return 1;
+
+    vaddr = (ulong *) ioremap (pci_start, pci_len); 
+    if (!vaddr) {
+        printk(KERN_ERR "(rcpci45 driver:) Unable to remap address range from %lu to %lu\n", pci_start, pci_start+pci_len);
+	goto err_out_free_msgbuf;
     }
 
-    DriverControlWord |= WARM_REBOOT_CAPABLE;
-    RCReportDriverCapability(pDpa->id, DriverControlWord);
+    dprintk("rcpci45_init_one: 0x%x, priv = 0x%x, vaddr = 0x%x\n", 
+           (uint)dev, (uint)dev->priv, (uint)vaddr);
+    dev->base_addr = (unsigned long)vaddr;
+    dev->irq = pdev->irq;
 
     dev->init = &RCinit;
-    ether_setup(dev);            /* linux kernel interface */
-
-    if (register_netdev(dev) != 0) /* linux kernel interface */
-    {
-        printk("rc: unable to register device \n");
-        free_irq(dev->irq, dev);
-        iounmap(vaddr);
-        kfree(dev);
-        return 1;
-    }
-    printk("%s: RedCreek Communications IPSEC VPN adapter\n",
-        dev->name);
 
     return 0; /* success */
+
+
+ err_out_free_msgbuf:
+    kfree(pDpa->msgbuf);
+ err_out_free_dev:
+    kfree(dev);
+ err_out:
+    unregister_netdev(dev);
+    card_idx--;
+    return error;
 }
 
 static struct pci_driver rcpci45_driver = {
@@ -328,12 +257,12 @@
 	remove: rcpci45_remove_one,
 };
 
-static int __init rcpci_init_module (void)
+static int __init rcpci_init_module(void)
 {
 	int rc = pci_module_init(&rcpci45_driver);
 
 	if (!rc)
-		printk(version);
+		printk(KERN_INFO "%s",version);
 	return rc;
 }
 
@@ -344,14 +273,42 @@
     PDPA pDpa = (PDPA) dev->priv;
     int count = 0;
     int requested = 0;
+    int error;
 
-#ifdef RCDEBUG
-    printk("rc: RCopen\n");
-#endif
-    RCEnableI2OInterrupts(pDpa->id);
+    dprintk("(rcpci45 driver:) RCopen\n");
 
-    if (pDpa->nexus)
-    {
+    /* Request a shared interrupt line. */
+    if ( (error=request_irq(dev->irq, (void *)RCinterrupt,
+                     SA_INTERRUPT|SA_SHIRQ, "RedCreek VPN Adapter", dev)) ) {
+        printk(KERN_ERR "(rcpci45 driver:) %s: unable to get IRQ %d\n", dev->name, dev->irq );
+	goto err_out;
+    }
+
+    error = RCInitI2OMsgLayer(dev, (PFNTXCALLBACK)RCxmit_callback,
+			      (PFNRXCALLBACK)RCrecv_callback,
+			      (PFNCALLBACK)RCreboot_callback);
+    if (error) {
+        printk(KERN_ERR "(rcpci45 driver:) Unable to initialize msg layer\n");
+	goto err_out_free_irq;
+    }
+    if ( (error=RCGetMAC(dev, NULL)) ) {
+        printk(KERN_ERR "(rcpci45 driver:) Unable to get adapter MAC\n");
+	goto err_out_free_irq;
+    }
+
+    DriverControlWord |= WARM_REBOOT_CAPABLE;
+    RCReportDriverCapability(dev, DriverControlWord);
+
+    printk(KERN_INFO "%s: RedCreek Communications IPSEC VPN adapter\n",
+        dev->name);
+
+
+    /* RAA: Old RCopen starts here */
+    RCEnableI2OInterrupts(dev);
+
+    /* RAA Hmm, how does the comment below jibe with the newly imported
+     * code above? A FIXME!!*/
+    if (pDpa->nexus) {
         /* This is not the first time RCopen is called.  Thus,
          * the interface was previously opened and later closed
          * by RCclose().  RCclose() does a Shutdown; to wake up
@@ -361,16 +318,12 @@
          * were turned off -- we need will need to reinitialize
          * the adapter, rather than simply waking it up.  
          */
-        printk("rc: Waking up adapter...\n");
-        RCResetLANCard(pDpa->id,0,0,0);
-    }
-    else
-    {
+	dprintk(KERN_INFO "Waking up adapter...\n");
+        RCResetLANCard(dev,0,0,0);
+    } else
         pDpa->nexus = 1;
-    }
 
-    while(post_buffers)
-    {
+    while(post_buffers) {
         if (post_buffers > MAX_NMBR_POST_BUFFERS_PER_MSG)
             requested = MAX_NMBR_POST_BUFFERS_PER_MSG;
         else
@@ -382,25 +335,26 @@
             /*
              * Check to see if we were able to post any buffers at all.
              */
-            if (post_buffers == MAX_NMBR_RCV_BUFFERS)
-            {
-                printk("rc: Error RCopen: not able to allocate any buffers\r\n");
+            if (post_buffers == MAX_NMBR_RCV_BUFFERS) {
+                printk(KERN_ERR "(rcpci45 driver:) Error RCopen: not able to allocate any buffers\r\n");
                 return(-ENOMEM);                    
             }
-            printk("rc: Warning RCopen: not able to allocate all requested buffers\r\n");
+            printk(KERN_WARNING "(rcpci45 driver:) Warning RCopen: not able to allocate all requested buffers\r\n");
             break;            /* we'll try to post more buffers later */
-        }
-        else
+        } else
             post_buffers -= count;
     }
     pDpa->numOutRcvBuffers = MAX_NMBR_RCV_BUFFERS - post_buffers;
     pDpa->shutdown = 0;        /* just in case */
-#ifdef RCDEBUG
-    printk("rc: RCopen: posted %d buffers\n", (uint)pDpa->numOutRcvBuffers);
-#endif
+    dprintk("RCopen: posted %d buffers\n", (uint)pDpa->numOutRcvBuffers);
     MOD_INC_USE_COUNT;
     netif_start_queue(dev);
     return 0;
+
+ err_out_free_irq:
+    free_irq(dev->irq, dev);
+ err_out:
+    return error;
 }
 
 static int
@@ -414,11 +368,8 @@
    
     netif_stop_queue(dev);
      
-    if (pDpa->shutdown || pDpa->reboot)
-    {
-#ifdef RCDEBUG
-            printk("rc: RC_xmit_packet: tbusy!\n");
-#endif
+    if (pDpa->shutdown || pDpa->reboot) {
+            dprintk("RC_xmit_packet: tbusy!\n");
             return 1;
     }
       
@@ -440,20 +391,13 @@
     ptcb->b.size = skb->len;
     ptcb->b.addr = virt_to_bus((void *)skb->data);
 
-#ifdef RCDEBUG
-    printk("rc: RC xmit: skb = 0x%x, pDpa = 0x%x, id = %d, ptcb = 0x%x\n", 
+    dprintk("RC xmit: skb = 0x%x, pDpa = 0x%x, id = %d, ptcb = 0x%x\n", 
            (uint)skb, (uint)pDpa, (uint)pDpa->id, (uint)ptcb);
-#endif
-    if ( (status = RCI2OSendPacket(pDpa->id, (U32)NULL, (PRCTCB)ptcb))
-         != RC_RTN_NO_ERROR)
-    {
-#ifdef RCDEBUG
-        printk("rc: RC send error 0x%x\n", (uint)status);
-#endif
+    if ( (status = RCI2OSendPacket(dev, (U32)NULL, (PRCTCB)ptcb))
+         != RC_RTN_NO_ERROR) {
+        dprintk("RC send error 0x%x\n", (uint)status);
         return 1;
-    }
-    else
-    {
+    } else {
         dev->trans_start = jiffies;
         netif_wake_queue(dev);
     }
@@ -477,103 +421,77 @@
 RCxmit_callback(U32 Status, 
                 U16 PcktCount, 
                 PU32 BufferContext, 
-                U16 AdapterID)
+                struct net_device *dev)
 {
     struct sk_buff *skb;
-    PDPA pDpa;
-    struct net_device *dev;
+    PDPA pDpa = dev->priv;
 
-        pDpa = PCIAdapters[AdapterID];
-        if (!pDpa)
-        {
-            printk("rc: Fatal error: xmit callback, !pDpa\n");
+    if (!pDpa) {
+            printk(KERN_ERR "(rcpci45 driver:) Fatal error: xmit callback, !pDpa\n");
             return;
-        }
-        dev = pDpa->dev;
+    }
 
-        // printk("xmit_callback: Status = 0x%x\n", (uint)Status);
-        if (Status != I2O_REPLY_STATUS_SUCCESS)
-        {
-            printk("rc: xmit_callback: Status = 0x%x\n", (uint)Status);
-        }
-#ifdef RCDEBUG
-        if (pDpa->shutdown || pDpa->reboot)
-            printk("rc: xmit callback: shutdown||reboot\n");
-#endif
-
-#ifdef RCDEBUG     
-        printk("rc: xmit_callback: PcktCount = %d, BC = 0x%x\n", 
-               (uint)PcktCount, (uint)BufferContext);
-#endif
-        while (PcktCount--)
-        {
+/*      dprintk("xmit_callback: Status = 0x%x\n", (uint)Status); */
+    if (Status != I2O_REPLY_STATUS_SUCCESS)
+            dprintk("xmit_callback: Status = 0x%x\n", (uint)Status);
+    if (pDpa->shutdown || pDpa->reboot)
+            dprintk("xmit callback: shutdown||reboot\n");
+
+    dprintk("xmit_callback: PcktCount = %d, BC = 0x%x\n", 
+	   (uint)PcktCount, (uint)BufferContext);
+
+    while (PcktCount--) {
             skb = (struct sk_buff *)(BufferContext[0]);
-#ifdef RCDEBUG
-            printk("rc: skb = 0x%x\n", (uint)skb);
-#endif
+            dprintk("skb = 0x%x\n", (uint)skb);
             BufferContext++;
             dev_kfree_skb_irq(skb);
-        }
-	netif_wake_queue(dev);
+    }
+    netif_wake_queue(dev);
 }
 
 static void
-RCreset_callback(U32 Status, U32 p1, U32 p2, U16 AdapterID)
+RCreset_callback(U32 Status, U32 p1, U32 p2, struct net_device *dev)
 {
-    PDPA pDpa;
-    struct net_device *dev;
+    PDPA pDpa = dev->priv;
      
-    pDpa = PCIAdapters[AdapterID];
-    dev = pDpa->dev;
-#ifdef RCDEBUG
-    printk("rc: RCreset_callback Status 0x%x\n", (uint)Status);
-#endif
+    dprintk("RCreset_callback Status 0x%x\n", (uint)Status);
     /*
      * Check to see why we were called.
      */
-    if (pDpa->shutdown)
-    {
-        printk("rc: Shutting down interface\n");
+    if (pDpa->shutdown) {
+        printk(KERN_INFO "(rcpci45 driver:) Shutting down interface\n");
         pDpa->shutdown = 0;
         pDpa->reboot = 0;
         MOD_DEC_USE_COUNT; 
-    }
-    else if (pDpa->reboot)
-    {
-        printk("rc: reboot, shutdown adapter\n");
+    } else if (pDpa->reboot) {
+        printk(KERN_INFO "(rcpci45 driver:) reboot, shutdown adapter\n");
         /*
          * We don't set any of the flags in RCShutdownLANCard()
          * and we don't pass a callback routine to it.
          * The adapter will have already initiated the reboot by
          * the time the function returns.
          */
-        RCDisableI2OInterrupts(pDpa->id);
-        RCShutdownLANCard(pDpa->id,0,0,0);
-        printk("rc: scheduling timer...\n");
+        RCDisableI2OInterrupts(dev);
+        RCShutdownLANCard(dev,0,0,0);
+        printk(KERN_INFO "(rcpci45 driver:) scheduling timer...\n");
         init_timer(&pDpa->timer);
         pDpa->timer.expires = RUN_AT((40*HZ)/10); /* 4 sec. */
         pDpa->timer.data = (unsigned long)dev;
         pDpa->timer.function = &rc_timer;    /* timer handler */
         add_timer(&pDpa->timer);
     }
-
-
-
 }
 
 static void
-RCreboot_callback(U32 Status, U32 p1, U32 p2, U16 AdapterID)
+RCreboot_callback(U32 Status, U32 p1, U32 p2, struct net_device *dev)
 {
-    PDPA pDpa;
+    PDPA pDpa = dev->priv;
     
-    pDpa = PCIAdapters[AdapterID];
-#ifdef RCDEBUG
-    printk("rc: RCreboot: rcv buffers outstanding = %d\n", 
+    dprintk("RCreboot: rcv buffers outstanding = %d\n", 
            (uint)pDpa->numOutRcvBuffers);
-#endif
-    if (pDpa->shutdown)
-    {
-        printk("rc: skipping reboot sequence -- shutdown already initiated\n");
+
+    if (pDpa->shutdown) {
+        printk(KERN_INFO "(rcpci45 driver:) skipping reboot sequence -- shutdown already initiated\n");
         return;
     }
     pDpa->reboot = 1;
@@ -587,8 +505,7 @@
      * schedule a timer callback routine to execute 3 seconds 
      * later; this routine will reinitialize the adapter at that time.
      */
-    RCResetLANCard(pDpa->id, 
-                   RC_RESOURCE_RETURN_POSTED_RX_BUCKETS | 
+    RCResetLANCard(dev, RC_RESOURCE_RETURN_POSTED_RX_BUCKETS | 
                    RC_RESOURCE_RETURN_PEND_TX_BUFFERS,0,
                    (PFNCALLBACK)RCreset_callback);
 }
@@ -615,66 +532,51 @@
                 U8   PktCount, 
                 U32  BucketsRemain, 
                 PU32 PacketDescBlock, 
-                U16  AdapterID)
+                struct net_device *dev)
 {
 
     U32 len, count;
-    PDPA pDpa;
+    PDPA pDpa = dev->priv;
     struct sk_buff *skb;
-    struct net_device *dev;
     singleTCB tcb;
     psingleTCB ptcb = &tcb;
 
 
-        pDpa = PCIAdapters[AdapterID];
-        dev = pDpa->dev;
-
-        ptcb->bcount = 1;
-
-#ifdef RCDEBUG
-        printk("rc: RCrecv_callback: 0x%x, 0x%x, 0x%x\n",
-               (uint)PktCount, (uint)BucketsRemain, (uint)PacketDescBlock);
-#endif
-        
-#ifdef RCDEBUG
-        if ((pDpa->shutdown || pDpa->reboot) && !Status)
-            printk("shutdown||reboot && !Status: PktCount = %d\n",PktCount);
-#endif
+    ptcb->bcount = 1;
+    
+    dprintk("RCrecv_callback: 0x%x, 0x%x, 0x%x\n",
+	   (uint)PktCount, (uint)BucketsRemain, (uint)PacketDescBlock);
 
-        if ( (Status != I2O_REPLY_STATUS_SUCCESS) || pDpa->shutdown)
-        {
+    if ((pDpa->shutdown || pDpa->reboot) && !Status)
+            dprintk("shutdown||reboot && !Status: PktCount = %d\n",PktCount);
+    
+    if ( (Status != I2O_REPLY_STATUS_SUCCESS) || pDpa->shutdown)
+    {
             /*
              * Free whatever buffers the adapter returned, but don't
              * pass them to the kernel.
              */
-        
-                if (!pDpa->shutdown && !pDpa->reboot)
-                    printk("rc: RCrecv error: status = 0x%x\n", (uint)Status);
-#ifdef RCDEBUG
+	    
+	    if (!pDpa->shutdown && !pDpa->reboot)
+                    printk(KERN_INFO "(rcpci45 driver:) RCrecv error: status = 0x%x\n", (uint)Status);
                 else
-                    printk("rc: Returning %d buffers, status = 0x%x\n", 
+			dprintk("Returning %d buffers, status = 0x%x\n", 
                            PktCount, (uint)Status);
-#endif
             /*
              * TO DO: check the nature of the failure and put the adapter in
              * failed mode if it's a hard failure.  Send a reset to the adapter
              * and free all outstanding memory.
              */
             if (Status == I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER)
-            {
-#ifdef RCDEBUG
-                printk("RCrecv status ABORT NO DATA TRANSFER\n");
-#endif
-            }
+                dprintk("RCrecv status ABORT NO DATA TRANSFER\n");
+
             /* check for reset status: I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER */ 
             if (PacketDescBlock)
             {
                 while(PktCount--)
                 {
                     skb = (struct sk_buff *)PacketDescBlock[0];
-#ifdef RCDEBUG
-                    printk("free skb 0x%p\n", skb);
-#endif
+                    dprintk("free skb 0x%p\n", skb);
                     dev_kfree_skb (skb);
                     pDpa->numOutRcvBuffers--;
                     PacketDescBlock += BD_SIZE; /* point to next context field */
@@ -687,14 +589,12 @@
             while(PktCount--)
             {
                 skb = (struct sk_buff *)PacketDescBlock[0];
-#ifdef RCDEBUG
                 if (pDpa->shutdown)
-                    printk("shutdown: skb=0x%x\n", (uint)skb);
+			dprintk("shutdown: skb=0x%x\n", (uint)skb);
 
-                printk("skb = 0x%x: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", (uint)skb,
+                dprintk("skb = 0x%x: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", (uint)skb,
                        (uint)skb->data[0], (uint)skb->data[1], (uint)skb->data[2],
                        (uint)skb->data[3], (uint)skb->data[4], (uint)skb->data[5]);
-#endif
 
 #ifdef PROMISCUOUS_BY_DEFAULT   /* early 2.x firmware */
                 if ( (memcmp(dev->dev_addr, skb->data, 6)) &&
@@ -711,15 +611,13 @@
                     ptcb->b.size = MAX_ETHER_SIZE;
                     ptcb->b.addr = virt_to_bus((void *)skb->data);
 
-                    if ( RCPostRecvBuffers(pDpa->id, (PRCTCB)ptcb ) != RC_RTN_NO_ERROR)
+                    if ( RCPostRecvBuffers(dev, (PRCTCB)ptcb ) != RC_RTN_NO_ERROR)
                     {
-                        printk("rc: RCrecv_callback: post buffer failed!\n");
+                        printk(KERN_WARNING "(rcpci45 driver:) RCrecv_callback: post buffer failed!\n");
                         dev_kfree_skb (skb);
                     }
                     else
-                    {
                         pDpa->numOutRcvBuffers++;
-                    }
                 }
                 else
 #endif /* PROMISCUOUS_BY_DEFAULT */
@@ -768,16 +666,14 @@
 
     pDpa = (PDPA) (dev->priv);
      
-#ifdef RCDEBUG
     if (pDpa->shutdown)
-        printk("rc: shutdown: service irq\n");
+        dprintk("shutdown: service irq\n");
 
-    printk("RC irq: pDpa = 0x%x, dev = 0x%x, id = %d\n", 
+    dprintk("RC irq: pDpa = 0x%x, dev = 0x%x, id = %d\n", 
            (uint)pDpa, (uint)dev, (uint)pDpa->id);
-    printk("dev = 0x%x\n", (uint)dev);
-#endif
+    dprintk("dev = 0x%x\n", (uint)dev);
 
-    RCProcI2OMsgQ(pDpa->id);
+    RCProcI2OMsgQ(dev);
 }
 
 
@@ -794,12 +690,9 @@
 
     if (pDpa->reboot)
     {
-        init_status = RCInitI2OMsgLayer(pDpa->id, dev->base_addr, 
-                                    pDpa->PLanApiPA, 
-                                    (PU8)virt_to_bus((void *)pDpa->PLanApiPA),
-                                    (PFNTXCALLBACK)RCxmit_callback,
-                                    (PFNRXCALLBACK)RCrecv_callback,
-                                    (PFNCALLBACK)RCreboot_callback);
+        init_status = RCInitI2OMsgLayer(dev, (PFNTXCALLBACK)RCxmit_callback,
+					(PFNRXCALLBACK)RCrecv_callback,
+					(PFNCALLBACK)RCreboot_callback);
 
         switch(init_status)
         {
@@ -807,8 +700,8 @@
  
             pDpa->reboot = 0;
             pDpa->shutdown = 0;        /* just in case */
-            RCReportDriverCapability(pDpa->id, DriverControlWord);
-            RCEnableI2OInterrupts(pDpa->id);
+            RCReportDriverCapability(dev, DriverControlWord);
+            RCEnableI2OInterrupts(dev);
 
             if (dev->flags & IFF_UP)
             {
@@ -825,34 +718,34 @@
                 }
                 pDpa->numOutRcvBuffers = 
                     MAX_NMBR_RCV_BUFFERS - post_buffers;
-                printk("rc: posted %d buffers \r\n", 
+                dprintk("rc: posted %d buffers \r\n", 
                        (uint)pDpa->numOutRcvBuffers);
             }
-            printk("rc: Initialization done.\n");
+            dprintk("Initialization done.\n");
             netif_wake_queue(dev);
             retry=0;
             return;
         case RC_RTN_FREE_Q_EMPTY:
             retry++;
-            printk("rc: inbound free q empty\n");
+            printk(KERN_WARNING "(rcpci45 driver:) inbound free q empty\n");
             break;
         default:
             retry++;
-            printk("rc: bad status after reboot: %d\n", init_status);    
+            printk(KERN_WARNING "(rcpci45 driver:) bad status after reboot: %d\n", init_status);    
             break;
         }
 
         if (retry > REBOOT_REINIT_RETRY_LIMIT)
         {
-            printk("rc: unable to reinitialize adapter after reboot\n");
-            printk("rc: decrementing driver and closing interface\n");
-            RCDisableI2OInterrupts(pDpa->id);
+            printk(KERN_WARNING "(rcpci45 driver:) unable to reinitialize adapter after reboot\n");
+            printk(KERN_WARNING "(rcpci45 driver:) decrementing driver and closing interface\n");
+            RCDisableI2OInterrupts(dev);
             dev->flags &= ~IFF_UP;
             MOD_DEC_USE_COUNT; 
         }
         else
         {
-            printk("rc: rescheduling timer...\n");
+            printk(KERN_INFO "(rcpci45 driver:) rescheduling timer...\n");
             init_timer(&pDpa->timer);
             pDpa->timer.expires = RUN_AT((40*HZ)/10); /* 3 sec. */
             pDpa->timer.data = (unsigned long)dev;
@@ -861,33 +754,26 @@
         }
     }
     else
-    {
-        printk("rc: timer??\n");
-    }
+        printk(KERN_WARNING "(rcpci45 driver:) timer??\n");
 }
 
 static int
 RCclose(struct net_device *dev)
 {
-
     PDPA pDpa = (PDPA) dev->priv;
 
     netif_stop_queue(dev);
     
-#ifdef RCDEBUG
-    printk("rc: RCclose\r\n");
-#endif
+    dprintk("RCclose\r\n");
+
     if (pDpa->reboot)
     {
-        printk("rc: skipping reset -- adapter already in reboot mode\n");
+        printk(KERN_INFO "(rcpci45 driver:) skipping reset -- adapter already in reboot mode\n");
         dev->flags &= ~IFF_UP;
         pDpa->shutdown = 1;
         return 0;
     }
-#ifdef RCDEBUG
-    printk("rc: receive buffers outstanding: %d\n", 
-           (uint)pDpa->numOutRcvBuffers);
-#endif
+    dprintk("receive buffers outstanding: %d\n", (uint)pDpa->numOutRcvBuffers);
 
     pDpa->shutdown = 1;
 
@@ -898,12 +784,11 @@
      * even if there are none.
      */
 
-    RCShutdownLANCard(pDpa->id, 
-                      RC_RESOURCE_RETURN_POSTED_RX_BUCKETS | 
+    RCShutdownLANCard(dev, RC_RESOURCE_RETURN_POSTED_RX_BUCKETS | 
                       RC_RESOURCE_RETURN_PEND_TX_BUFFERS,0,
                       (PFNCALLBACK)RCreset_callback);
 
-        dev->flags &= ~IFF_UP;
+    dev->flags &= ~IFF_UP;
     return 0;
 }
 
@@ -916,39 +801,35 @@
 
     if (!pDpa)
     {
-        printk("rc: RCget_stats: !pDpa\n");
+	dprintk("RCget_stats: !pDpa\n");
         return 0;
     }
     else if (!(dev->flags & IFF_UP))    
     {
-#ifdef RCDEBUG
-        printk("rc: RCget_stats: device down\n");
-#endif
+	dprintk("RCget_stats: device down\n");
         return 0;
     }
 
     memset(&RCstats, 0, sizeof(RCLINKSTATS));
-    if ( (RCGetLinkStatistics(pDpa->id, &RCstats, (void *)0)) == RC_RTN_NO_ERROR )
+    if ( (RCGetLinkStatistics(dev, &RCstats, (void *)0)) == RC_RTN_NO_ERROR )
     {
-#ifdef RCDEBUG
-        printk("rc: TX_good 0x%x\n", (uint)RCstats.TX_good);
-        printk("rc: TX_maxcol 0x%x\n", (uint)RCstats.TX_maxcol);
-        printk("rc: TX_latecol 0x%x\n", (uint)RCstats.TX_latecol);
-        printk("rc: TX_urun 0x%x\n", (uint)RCstats.TX_urun);
-        printk("rc: TX_crs 0x%x\n", (uint)RCstats.TX_crs);
-        printk("rc: TX_def 0x%x\n", (uint)RCstats.TX_def);
-        printk("rc: TX_singlecol 0x%x\n", (uint)RCstats.TX_singlecol);
-        printk("rc: TX_multcol 0x%x\n", (uint)RCstats.TX_multcol);
-        printk("rc: TX_totcol 0x%x\n", (uint)RCstats.TX_totcol);
-
-        printk("rc: Rcv_good 0x%x\n", (uint)RCstats.Rcv_good);
-        printk("rc: Rcv_CRCerr 0x%x\n", (uint)RCstats.Rcv_CRCerr);
-        printk("rc: Rcv_alignerr 0x%x\n", (uint)RCstats.Rcv_alignerr);
-        printk("rc: Rcv_reserr 0x%x\n", (uint)RCstats.Rcv_reserr);
-        printk("rc: Rcv_orun 0x%x\n", (uint)RCstats.Rcv_orun);
-        printk("rc: Rcv_cdt 0x%x\n", (uint)RCstats.Rcv_cdt);
-        printk("rc: Rcv_runt 0x%x\n", (uint)RCstats.Rcv_runt);
-#endif
+	dprintk("TX_good 0x%x\n", (uint)RCstats.TX_good);
+        dprintk("TX_maxcol 0x%x\n", (uint)RCstats.TX_maxcol);
+        dprintk("TX_latecol 0x%x\n", (uint)RCstats.TX_latecol);
+        dprintk("TX_urun 0x%x\n", (uint)RCstats.TX_urun);
+        dprintk("TX_crs 0x%x\n", (uint)RCstats.TX_crs);
+        dprintk("TX_def 0x%x\n", (uint)RCstats.TX_def);
+        dprintk("TX_singlecol 0x%x\n", (uint)RCstats.TX_singlecol);
+        dprintk("TX_multcol 0x%x\n", (uint)RCstats.TX_multcol);
+        dprintk("TX_totcol 0x%x\n", (uint)RCstats.TX_totcol);
+		 
+        dprintk("Rcv_good 0x%x\n", (uint)RCstats.Rcv_good);
+        dprintk("Rcv_CRCerr 0x%x\n", (uint)RCstats.Rcv_CRCerr);
+        dprintk("Rcv_alignerr 0x%x\n", (uint)RCstats.Rcv_alignerr);
+        dprintk("Rcv_reserr 0x%x\n", (uint)RCstats.Rcv_reserr);
+        dprintk("Rcv_orun 0x%x\n", (uint)RCstats.Rcv_orun);
+        dprintk("Rcv_cdt 0x%x\n", (uint)RCstats.Rcv_cdt);
+        dprintk("Rcv_runt 0x%x\n", (uint)RCstats.Rcv_runt);
 
         pDpa->stats.rx_packets = RCstats.Rcv_good; /* total packets received    */
         pDpa->stats.tx_packets = RCstats.TX_good; /* total packets transmitted    */
@@ -1000,9 +881,7 @@
     RCuser_struct RCuser;
     PDPA pDpa = dev->priv;
 
-#if RCDEBUG
-    printk("RCioctl: cmd = 0x%x\n", cmd);
-#endif
+    dprintk("RCioctl: cmd = 0x%x\n", cmd);
  
     if(!capable(CAP_NET_ADMIN))
     	return -EPERM;
@@ -1023,109 +902,107 @@
         if(copy_from_user(&RCuser, rq->ifr_data, sizeof(RCuser)))
              return -EFAULT;
         
-#ifdef RCDEBUG
-        printk("RCioctl: RCuser_cmd = 0x%x\n", RCuser.cmd);
-#endif
+        dprintk("RCioctl: RCuser_cmd = 0x%x\n", RCuser.cmd);
   
         switch(RCuser.cmd)
         {
         case RCUC_GETFWVER:
-            printk("RC GETFWVER\n");
+            printk(KERN_INFO "(rcpci45 driver:) RC GETFWVER\n");
             RCUD_GETFWVER = &RCuser.RCUS_GETFWVER;
-            RCGetFirmwareVer(pDpa->id, (PU8) &RCUD_GETFWVER->FirmString, NULL);
+            RCGetFirmwareVer(dev, (PU8) &RCUD_GETFWVER->FirmString, NULL);
             break;
         case RCUC_GETINFO:
-            printk("RC GETINFO\n");
+            printk(KERN_INFO "(rcpci45 driver:) RC GETINFO\n");
             RCUD_GETINFO = &RCuser.RCUS_GETINFO;
             RCUD_GETINFO -> mem_start = dev->base_addr;
-            RCUD_GETINFO -> mem_end = dev->base_addr + 2*32768;
-            RCUD_GETINFO -> base_addr = pDpa->pci_addr;
+	    RCUD_GETINFO -> mem_end = dev->base_addr + pDpa->pci_addr_len;
+	    RCUD_GETINFO -> base_addr = pDpa->pci_addr;  
             RCUD_GETINFO -> irq = dev->irq;
             break;
         case RCUC_GETIPANDMASK:
-            printk("RC GETIPANDMASK\n");
+            printk(KERN_INFO "(rcpci45 driver:) RC GETIPANDMASK\n");
             RCUD_GETIPANDMASK = &RCuser.RCUS_GETIPANDMASK;
-            RCGetRavlinIPandMask(pDpa->id, (PU32) &RCUD_GETIPANDMASK->IpAddr,
+            RCGetRavlinIPandMask(dev, (PU32) &RCUD_GETIPANDMASK->IpAddr,
                                  (PU32) &RCUD_GETIPANDMASK->NetMask, NULL);
             break;
         case RCUC_GETLINKSTATISTICS:
-            printk("RC GETLINKSTATISTICS\n");
+            printk(KERN_INFO "(rcpci45 driver:) RC GETLINKSTATISTICS\n");
             RCUD_GETLINKSTATISTICS = &RCuser.RCUS_GETLINKSTATISTICS;
-            RCGetLinkStatistics(pDpa->id, (P_RCLINKSTATS) &RCUD_GETLINKSTATISTICS->StatsReturn, NULL);
+            RCGetLinkStatistics(dev, (P_RCLINKSTATS) &RCUD_GETLINKSTATISTICS->StatsReturn, NULL);
             break;
         case RCUC_GETLINKSTATUS:
-            printk("RC GETLINKSTATUS\n");
+            printk(KERN_INFO "(rcpci45 driver:) RC GETLINKSTATUS\n");
             RCUD_GETLINKSTATUS = &RCuser.RCUS_GETLINKSTATUS;
-            RCGetLinkStatus(pDpa->id, (PU32) &RCUD_GETLINKSTATUS->ReturnStatus, NULL);
+            RCGetLinkStatus(dev, (PU32) &RCUD_GETLINKSTATUS->ReturnStatus, NULL);
             break;
         case RCUC_GETMAC:
-            printk("RC GETMAC\n");
+            printk(KERN_INFO "(rcpci45 driver:) RC GETMAC\n");
             RCUD_GETMAC = &RCuser.RCUS_GETMAC;
-            RCGetMAC(pDpa->id, (PU8) &RCUD_GETMAC->mac, NULL);
+            RCGetMAC(dev, NULL);
             break;
         case RCUC_GETPROM:
-            printk("RC GETPROM\n");
+            printk(KERN_INFO "(rcpci45 driver:) RC GETPROM\n");
             RCUD_GETPROM = &RCuser.RCUS_GETPROM;
-            RCGetPromiscuousMode(pDpa->id, (PU32) &RCUD_GETPROM->PromMode, NULL);
+            RCGetPromiscuousMode(dev, (PU32) &RCUD_GETPROM->PromMode, NULL);
             break;
         case RCUC_GETBROADCAST:
-            printk("RC GETBROADCAST\n");
+            printk(KERN_INFO "(rcpci45 driver:) RC GETBROADCAST\n");
             RCUD_GETBROADCAST = &RCuser.RCUS_GETBROADCAST;
-            RCGetBroadcastMode(pDpa->id, (PU32) &RCUD_GETBROADCAST->BroadcastMode, NULL);
+            RCGetBroadcastMode(dev, (PU32) &RCUD_GETBROADCAST->BroadcastMode, NULL);
             break;
         case RCUC_GETSPEED:
-            printk("RC GETSPEED\n");
+            printk(KERN_INFO "(rcpci45 driver:) RC GETSPEED\n");
             if (!(dev->flags & IFF_UP))    
             {
-                printk("RCioctl, GETSPEED error: interface down\n");
+                printk(KERN_ERR "(rcpci45 driver:) RCioctl, GETSPEED error: interface down\n");
                 return -ENODATA;
             }
             RCUD_GETSPEED = &RCuser.RCUS_GETSPEED;
-            RCGetLinkSpeed(pDpa->id, (PU32) &RCUD_GETSPEED->LinkSpeedCode, NULL);
-            printk("RC speed = 0x%u\n", RCUD_GETSPEED->LinkSpeedCode);
+            RCGetLinkSpeed(dev, (PU32) &RCUD_GETSPEED->LinkSpeedCode, NULL);
+            printk(KERN_INFO "(rcpci45 driver:) RC speed = 0x%u\n", RCUD_GETSPEED->LinkSpeedCode);
             break;
         case RCUC_SETIPANDMASK:
-            printk("RC SETIPANDMASK\n");
+            printk(KERN_INFO "(rcpci45 driver:) RC SETIPANDMASK\n");
             RCUD_SETIPANDMASK = &RCuser.RCUS_SETIPANDMASK;
-            printk ("RC New IP Addr = %d.%d.%d.%d, ", (U8) ((RCUD_SETIPANDMASK->IpAddr) & 0xff),
+            printk (KERN_INFO "(rcpci45 driver:) RC New IP Addr = %d.%d.%d.%d, ", (U8) ((RCUD_SETIPANDMASK->IpAddr) & 0xff),
                     (U8) ((RCUD_SETIPANDMASK->IpAddr >>  8) & 0xff),
                     (U8) ((RCUD_SETIPANDMASK->IpAddr >> 16) & 0xff),
                     (U8) ((RCUD_SETIPANDMASK->IpAddr >> 24) & 0xff));
-            printk ("RC New Mask = %d.%d.%d.%d\n", (U8) ((RCUD_SETIPANDMASK->NetMask) & 0xff),
+            printk (KERN_INFO "(rcpci45 driver:) RC New Mask = %d.%d.%d.%d\n", (U8) ((RCUD_SETIPANDMASK->NetMask) & 0xff),
                     (U8) ((RCUD_SETIPANDMASK->NetMask >>  8) & 0xff),
                     (U8) ((RCUD_SETIPANDMASK->NetMask >> 16) & 0xff),
                     (U8) ((RCUD_SETIPANDMASK->NetMask >> 24) & 0xff));
-            RCSetRavlinIPandMask(pDpa->id, (U32) RCUD_SETIPANDMASK->IpAddr,
+            RCSetRavlinIPandMask(dev, (U32) RCUD_SETIPANDMASK->IpAddr,
                                  (U32) RCUD_SETIPANDMASK->NetMask);
             break;
         case RCUC_SETMAC:
-            printk("RC SETMAC\n");
+            printk(KERN_INFO "(rcpci45 driver:) RC SETMAC\n");
             RCUD_SETMAC = &RCuser.RCUS_SETMAC;
-            printk ("RC New MAC addr = %02X:%02X:%02X:%02X:%02X:%02X\n",
+            printk (KERN_INFO "(rcpci45 driver:) RC New MAC addr = %02X:%02X:%02X:%02X:%02X:%02X\n",
                     (U8) (RCUD_SETMAC->mac[0]), (U8) (RCUD_SETMAC->mac[1]), (U8) (RCUD_SETMAC->mac[2]),
                     (U8) (RCUD_SETMAC->mac[3]), (U8) (RCUD_SETMAC->mac[4]), (U8) (RCUD_SETMAC->mac[5]));
-            RCSetMAC(pDpa->id, (PU8) &RCUD_SETMAC->mac);
+            RCSetMAC(dev, (PU8) &RCUD_SETMAC->mac);
             break;
         case RCUC_SETSPEED:
-            printk("RC SETSPEED\n");
+            printk(KERN_INFO "(rcpci45 driver:) RC SETSPEED\n");
             RCUD_SETSPEED = &RCuser.RCUS_SETSPEED;
-            RCSetLinkSpeed(pDpa->id, (U16) RCUD_SETSPEED->LinkSpeedCode);
-            printk("RC New speed = 0x%x\n", RCUD_SETSPEED->LinkSpeedCode);
+            RCSetLinkSpeed(dev, (U16) RCUD_SETSPEED->LinkSpeedCode);
+            printk(KERN_INFO "(rcpci45 driver:) RC New speed = 0x%x\n", RCUD_SETSPEED->LinkSpeedCode);
             break;
         case RCUC_SETPROM:
-            printk("RC SETPROM\n");
+            printk(KERN_INFO "(rcpci45 driver:) RC SETPROM\n");
             RCUD_SETPROM = &RCuser.RCUS_SETPROM;
-            RCSetPromiscuousMode(pDpa->id,(U16)RCUD_SETPROM->PromMode);
-            printk("RC New prom mode = 0x%x\n", RCUD_SETPROM->PromMode);
+            RCSetPromiscuousMode(dev,(U16)RCUD_SETPROM->PromMode);
+            printk(KERN_INFO "(rcpci45 driver:) RC New prom mode = 0x%x\n", RCUD_SETPROM->PromMode);
             break;
         case RCUC_SETBROADCAST:
-            printk("RC SETBROADCAST\n");
+            printk(KERN_INFO "(rcpci45 driver:) RC SETBROADCAST\n");
             RCUD_SETBROADCAST = &RCuser.RCUS_SETBROADCAST;
-            RCSetBroadcastMode(pDpa->id,(U16)RCUD_SETBROADCAST->BroadcastMode);
-            printk("RC New broadcast mode = 0x%x\n", RCUD_SETBROADCAST->BroadcastMode);
+            RCSetBroadcastMode(dev,(U16)RCUD_SETBROADCAST->BroadcastMode);
+            printk(KERN_INFO "(rcpci45 driver:) RC New broadcast mode = 0x%x\n", RCUD_SETBROADCAST->BroadcastMode);
             break;
         default:
-            printk("RC command default\n");
+            printk(KERN_INFO "(rcpci45 driver:) RC command default\n");
             RCUD_DEFAULT = &RCuser.RCUS_DEFAULT;
             RCUD_DEFAULT -> rc = 0x11223344;
             break;
@@ -1147,14 +1024,14 @@
     /*
      * To be completed ...
       */
-    printk("rc: RCconfig\n");
+    dprintk("RCconfig\n");
     return 0;
     if (dev->flags & IFF_UP)    /* can't act on a running interface */
         return -EBUSY;
 
      /* Don't allow changing the I/O address */
     if (map->base_addr != dev->base_addr) {
-        printk(KERN_WARNING "RC pci45: Change I/O address not implemented\n");
+        printk(KERN_WARNING "(rcpci45 driver:)  Change I/O address not implemented\n");
         return -EOPNOTSUPP;
     }
     return 0;
@@ -1175,54 +1052,46 @@
 {
 
     int i;
-    PDPA pDpa = (PDPA)dev->priv;
     PU32 p;
     psingleB pB;
     struct sk_buff *skb;
     RC_RETURN status;
+    U32 res;
 
     if (!numBuffers)
         return 0;
     else if (numBuffers > MAX_NMBR_POST_BUFFERS_PER_MSG)
     {
-#ifdef RCDEBUG
-        printk("rc: Too many buffers requested!\n");
-        printk("rc: attempting to allocate only 32 buffers\n");
-#endif
+        dprintk("Too many buffers requested!\n");
+        dprintk("attempting to allocate only 32 buffers\n");
         numBuffers = 32;
     }
     
-    p = (PU32) kmalloc(sizeof(U32) + numBuffers*sizeof(singleB), GFP_ATOMIC);
+    p = (PU32) kmalloc(sizeof(U32) + numBuffers*sizeof(singleB), GFP_KERNEL);
 
-#ifdef RCDEBUG
-    printk("rc: TCB = 0x%x\n", (uint)p);
-#endif
+    dprintk("TCB = 0x%x\n", (uint)p);
 
     if (!p)
     {
-        printk("rc: RCopen: unable to allocate TCB\n");
+        printk(KERN_WARNING "(rcpci45 driver:) RCopen: unable to allocate TCB\n");
         return 0;
     }
 
     p[0] = 0;                              /* Buffer Count */
     pB = (psingleB)((U32)p + sizeof(U32)); /* point to the first buffer */
 
-#ifdef RCDEBUG
-    printk("rc: p[0] = 0x%x, p = 0x%x, pB = 0x%x\n", (uint)p[0], (uint)p, (uint)pB);
-    printk("rc: pB = 0x%x\n", (uint)pB);
-#endif
+    dprintk("p[0] = 0x%x, p = 0x%x, pB = 0x%x\n", (uint)p[0], (uint)p, (uint)pB);
+    dprintk("pB = 0x%x\n", (uint)pB);
 
     for (i=0; i<numBuffers; i++)
     {
         skb = dev_alloc_skb(MAX_ETHER_SIZE+2);
         if (!skb)
         {
-            printk("rc: Doh! RCopen: unable to allocate enough skbs!\n");
+            dprintk("Doh! RCopen: unable to allocate enough skbs!\n");
             if (*p != 0)        /* did we allocate any buffers at all? */
             {
-#ifdef RCDEBUG
-                printk("rc: will post only %d buffers \n", (uint)(*p));
-#endif
+                dprintk("will post only %d buffers \n", (uint)(*p));
                 break;
             }
             else 
@@ -1231,9 +1100,7 @@
                 return 0;
             }
         }
-#ifdef RCDEBUG
-        printk("post 0x%x\n", (uint)skb);
-#endif
+        dprintk("post 0x%x\n", (uint)skb);
         skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
         pB->context = (U32)skb;
         pB->scount = 1;        /* segment count */
@@ -1243,24 +1110,21 @@
         pB++;
     }
 
-    if ( (status = RCPostRecvBuffers(pDpa->id, (PRCTCB)p )) != RC_RTN_NO_ERROR)
+    if ( (status = RCPostRecvBuffers(dev, (PRCTCB)p )) != RC_RTN_NO_ERROR)
     {
-        printk("rc: Post buffer failed with error code 0x%x!\n", status);
+        printk(KERN_WARNING "(rcpci45 driver:) Post buffer failed with error code 0x%x!\n", status);
         pB = (psingleB)((U32)p + sizeof(U32)); /* point to the first buffer */
         while(p[0])
         {
             skb = (struct sk_buff *)pB->context;
-#ifdef RCDEBUG
-            printk("rc: freeing 0x%x\n", (uint)skb);
-#endif
+            dprintk("freeing 0x%x\n", (uint)skb);
             dev_kfree_skb (skb);
             p[0]--;
             pB++;
         }
-#ifdef RCDEBUG
-        printk("rc: freed all buffers, p[0] = %ld\n", p[0]);
-#endif
+        dprintk("freed all buffers, p[0] = %d\n", (uint)p[0]);
     }
+    res = p[0];
     kfree(p);
-    return(p[0]);                /* return the number of posted buffers */
+    return(res);                /* return the number of posted buffers */
 }
diff -urN linux-2.4.2-pre1/drivers/net/strip.c linux/drivers/net/strip.c
--- linux-2.4.2-pre1/drivers/net/strip.c	Tue Jul 11 11:12:24 2000
+++ linux/drivers/net/strip.c	Mon Dec  3 22:27:48 2001
@@ -82,12 +82,9 @@
 /* Header files								*/
 
 #include <linux/config.h>
-
-#ifdef MODULE
 #include <linux/module.h>
 #include <linux/version.h>
-#endif
-
+#include <linux/init.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/segment.h>
@@ -459,7 +456,7 @@
 /************************************************************************/
 /* Global variables							*/
 
-static struct strip *struct_strip_list = NULL;
+static struct strip *struct_strip_list;
 
 
 /************************************************************************/
@@ -492,7 +489,7 @@
 
 typedef unsigned long InterruptStatus;
 
-extern __inline__ InterruptStatus DisableInterrupts(void)
+static inline InterruptStatus DisableInterrupts(void)
 {
     InterruptStatus x;
     save_flags(x);
@@ -500,7 +497,7 @@
     return(x);
 }
 
-extern __inline__ void RestoreInterrupts(InterruptStatus x)
+static inline void RestoreInterrupts(InterruptStatus x)
 {
     restore_flags(x);
 }
@@ -2589,11 +2586,7 @@
     dev->hard_start_xmit    = strip_xmit;
     dev->hard_header        = strip_header;
     dev->rebuild_header     = strip_rebuild_header;
-    /*  dev->type_trans            unused */
-    /*  dev->set_multicast_list   unused */
     dev->set_mac_address    = dev_set_mac_address;
-    /*  dev->do_ioctl             unused */
-    /*  dev->set_config           unused */
     dev->get_stats          = strip_get_stats;
     return 0;
 }
@@ -2730,9 +2723,7 @@
     tty->termios->c_cflag |= CLOCAL;    /* Ignore modem control signals. */
     tty->termios->c_cflag &= ~HUPCL;    /* Don't close on hup */
 
-#ifdef MODULE
     MOD_INC_USE_COUNT;
-#endif
 
     printk(KERN_INFO "STRIP: device \"%s\" activated\n", strip_info->dev.name);
 
@@ -2760,7 +2751,6 @@
     if (!strip_info || strip_info->magic != STRIP_MAGIC)
         return;
 
-    dev_close(&strip_info->dev);
     unregister_netdev(&strip_info->dev);
 
     tty->disc_data = 0;
@@ -2768,9 +2758,7 @@
     printk(KERN_INFO "STRIP: device \"%s\" closed down\n", strip_info->dev.name);
     strip_free(strip_info);
     tty->disc_data = NULL;
-#ifdef MODULE
     MOD_DEC_USE_COUNT;
-#endif
 }
 
 
@@ -2823,80 +2811,65 @@
 /************************************************************************/
 /* Initialization							*/
 
+static struct tty_ldisc strip_ldisc = {
+	magic:		TTY_LDISC_MAGIC,
+	name:		"strip",
+	open:		strip_open,
+	close:		strip_close,
+	ioctl:		strip_ioctl,
+	receive_buf:	strip_receive_buf,
+	receive_room:	strip_receive_room,
+	write_wakeup:	strip_write_some_more,
+};
+
 /*
  * Initialize the STRIP driver.
  * This routine is called at boot time, to bootstrap the multi-channel
  * STRIP driver
  */
 
-int strip_init_ctrl_dev(struct net_device *dummy)
+static const char signon[] __initdata = KERN_INFO "STRIP: Version %s (unlimited channels)\n";
+
+static int __init strip_init_driver(void)
 {
-    static struct tty_ldisc strip_ldisc;
     int status;
 
-    printk(KERN_INFO "STRIP: Version %s (unlimited channels)\n", StripVersion);
+    printk(signon, StripVersion);
 
     /*
      * Fill in our line protocol discipline, and register it
      */
-
-    memset(&strip_ldisc, 0, sizeof(strip_ldisc));
-    strip_ldisc.magic        = TTY_LDISC_MAGIC;
-    strip_ldisc.flags        = 0;
-    strip_ldisc.open         = strip_open;
-    strip_ldisc.close        = strip_close;
-    strip_ldisc.read         = NULL;
-    strip_ldisc.write        = NULL;
-    strip_ldisc.ioctl        = strip_ioctl;
-    strip_ldisc.poll         = NULL;
-    strip_ldisc.receive_buf  = strip_receive_buf;
-    strip_ldisc.receive_room = strip_receive_room;
-    strip_ldisc.write_wakeup = strip_write_some_more;
-    status = tty_register_ldisc(N_STRIP, &strip_ldisc);
-    if (status != 0)
-    {
+    if ((status = tty_register_ldisc(N_STRIP, &strip_ldisc)))
         printk(KERN_ERR "STRIP: can't register line discipline (err = %d)\n", status);
-    }
 
     /*
      * Register the status file with /proc
      */
-    proc_net_create ("strip", S_IFREG | S_IRUGO, get_status_info);
+    proc_net_create("strip", S_IFREG | S_IRUGO, get_status_info);
 
-#ifdef MODULE
-     return status;
-#else
-
-    /* Return "not found", so that dev_init() will unlink
-     * the placeholder device entry for us.
-     */
-    return -ENODEV;
-#endif
+    return status;
 }
+module_init(strip_init_driver);
 
+static const char signoff[] __exitdata = KERN_INFO "STRIP: Module Unloaded\n";
 
-/************************************************************************/
-/* From here down is only used when compiled as an external module	*/
-
-#ifdef MODULE
-
-int init_module(void)
-{
-    return strip_init_ctrl_dev(0);
-}
-
-void cleanup_module(void)
+static void __exit strip_exit_driver(void)
 {
     int i;
     while (struct_strip_list)
         strip_free(struct_strip_list);
 
     /* Unregister with the /proc/net file here. */
-    proc_net_remove ("strip");
+    proc_net_remove("strip");
 
     if ((i = tty_register_ldisc(N_STRIP, NULL)))
         printk(KERN_ERR "STRIP: can't unregister line discipline (err = %d)\n", i);
 
-    printk(KERN_INFO "STRIP: Module Unloaded\n");
+    printk(signoff);
 }
-#endif /* MODULE */
+module_exit(strip_exit_driver);
+
+MODULE_AUTHOR("Stuart Cheshire <cheshire@cs.stanford.edu>");
+MODULE_DESCRIPTION("Starmode Radio IP (STRIP) Device Driver");
+MODULE_SUPPORTED_DEVICE("Starmode Radio IP (STRIP) modem");
+
diff -urN linux-2.4.2-pre1/drivers/net/tokenring/Makefile linux/drivers/net/tokenring/Makefile
--- linux-2.4.2-pre1/drivers/net/tokenring/Makefile	Fri Dec 29 14:07:22 2000
+++ linux/drivers/net/tokenring/Makefile	Mon Dec  3 22:27:48 2001
@@ -21,6 +21,6 @@
 obj-$(CONFIG_TMSPCI) 	+= tmspci.o
 obj-$(CONFIG_SMCTR) 	+= smctr.o
 
-L_TARGET := tr.a
+O_TARGET := tr.o
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.2-pre1/drivers/net/tokenring/smctr.c linux/drivers/net/tokenring/smctr.c
--- linux-2.4.2-pre1/drivers/net/tokenring/smctr.c	Mon Oct 16 12:58:51 2000
+++ linux/drivers/net/tokenring/smctr.c	Mon Dec  3 22:27:48 2001
@@ -4,11 +4,11 @@
  *  Written by Jay Schulist <jschlst@turbolinux.com>
  *
  *  This software may be used and distributed according to the terms
- *  of the GNU Public License, incorporated herein by reference.
+ *  of the GNU General Public License, incorporated herein by reference.
  *
  *  This device driver works with the following SMC adapters:
- *      - SMC TokenCard Elite   (8115T)
- *      - SMC TokenCard Elite/A MCA (8115T/A)
+ *      - SMC TokenCard Elite   (8115T, chips 825/584)
+ *      - SMC TokenCard Elite/A MCA (8115T/A, chips 825/594)
  *
  *  Source(s):
  *  	- SMC TokenCard SDK.
@@ -16,13 +16,16 @@
  *  Maintainer(s):
  *    JS        Jay Schulist <jschlst@turbolinux.com>
  *
+ * Changes:
+ *    07102000          JS      Fixed a timing problem in smctr_wait_cmd();
+ *                              Also added a bit more discriptive error msgs.
+ *    07122000          JS      Fixed problem with detecting a card with
+ *				module io/irq/mem specified.
+ *
  *  To do:
  *    1. Multicast support.
  */
 
-static const char *version = "smctr.c: v1.1 1/1/00 by jschlst@turbolinux.com\n";
-static const char *cardname = "smctr";
-
 #ifdef MODULE
 #include <linux/module.h>
 #include <linux/version.h>
@@ -59,6 +62,10 @@
 #include "smctr.h"               /* Our Stuff */
 #include "smctr_firmware.h"      /* SMC adapter firmware */
 
+static char version[] __initdata = KERN_INFO "smctr.c: v1.4 7/12/00 by jschlst@turbolinux.com\n";
+static const char *cardname = "smctr";
+
+
 #define SMCTR_IO_EXTENT   20
 
 /* A zero-terminated list of I/O addresses to be probed. */
@@ -72,7 +79,7 @@
 static unsigned int smctr_posid = 0x6ec6;
 #endif
 
-static int ringspeed = 0;
+static int ringspeed;
 
 /* SMC Name of the Adapter. */
 static char *smctr_name = "SMC TokenCard";
@@ -107,7 +114,6 @@
 static int smctr_decode_firmware(struct net_device *dev);
 static int smctr_disable_16bit(struct net_device *dev);
 static int smctr_disable_adapter_ctrl_store(struct net_device *dev);
-static int smctr_disable_adapter_ram(struct net_device *dev);
 static int smctr_disable_bic_int(struct net_device *dev);
 
 /* E */
@@ -219,9 +225,7 @@
         struct net_device *dev, __u16 rx_status);
 
 /* R */
-static int smctr_ram_conflict_test(struct net_device *dev);
 static int smctr_ram_memory_test(struct net_device *dev);
-static unsigned int __init smctr_read_584_chksum(int ioaddr);
 static int smctr_rcv_chg_param(struct net_device *dev, MAC_HEADER *rmf,
         __u16 *correlator);
 static int smctr_rcv_init(struct net_device *dev, MAC_HEADER *rmf,
@@ -234,7 +238,6 @@
 static int smctr_reset_adapter(struct net_device *dev);
 static int smctr_restart_tx_chain(struct net_device *dev, short queue);
 static int smctr_ring_status_chg(struct net_device *dev);
-static int smctr_rom_conflict_test(struct net_device *dev);
 static int smctr_rx_frame(struct net_device *dev);
 
 /* S */
@@ -626,7 +629,10 @@
                         break;
 
                 case WD8115T:
-                        smctr_model = "8115T";
+			if(tp->extra_info & CHIP_REV_MASK)
+                                smctr_model = "8115T rev XE";
+                        else
+                                smctr_model = "8115T rev XD";
                         break;
 
                 default:
@@ -827,16 +833,6 @@
 
 static int smctr_disable_16bit(struct net_device *dev)
 {
-        struct net_local *tp = (struct net_local *)dev->priv;
-        __u8 r;
-
-        if(tp->adapter_bus == BUS_ISA16_TYPE
-                && ((tp->adapter_flags & FORCED_16BIT_MODE) == 0))
-        {
-                r = inb(dev->base_addr + LAAR);
-                outb((r & ~LAAR_MEM16ENB), dev->base_addr + LAAR);
-        }
-
         return (0);
 }
 
@@ -860,22 +856,6 @@
         return (0);
 }
 
-static int smctr_disable_adapter_ram(struct net_device *dev)
-{
-        int ioaddr = dev->base_addr;
-        __u8 r;
-
-        /* First disable memory enable bit. */
-        r = inb(ioaddr + MSR);
-        outb(~MSR_MEMB & r, ioaddr + MSR);
-
-        /* Now disable 16 bit memory enable bit. */
-        r = inb(ioaddr + LAAR);
-        outb(~LAAR_MEM16ENB & r, ioaddr + LAAR);
-
-        return (0);
-}
-
 static int smctr_disable_bic_int(struct net_device *dev)
 {
         struct net_local *tp = (struct net_local *)dev->priv;
@@ -993,6 +973,11 @@
         request_region(ioaddr, SMCTR_IO_EXTENT, smctr_name);
 
         b = inb(ioaddr + BDID);
+	if(b != BRD_ID_8115T)
+        {
+                printk("%s: The adapter found is not supported\n", dev->name);
+                return (-1);
+        }
 
         /* Check for 8115T Board ID */
         r2 = 0;
@@ -1015,7 +1000,10 @@
                         break;
 
                 case WD8115T:
-                        smctr_model = "8115T";
+			if(tp->extra_info & CHIP_REV_MASK)
+                                smctr_model = "8115T rev XE";
+                        else
+                                smctr_model = "8115T rev XD";
                         break;
 
                 default:
@@ -1164,12 +1152,13 @@
                 if(!(r1 & 0x2) )           /* GP2_ETRD */
                         tp->mode_bits |= EARLY_TOKEN_REL;
 
-                /* see if the chip is corrupted */
+                /* see if the chip is corrupted
                 if(smctr_read_584_chksum(ioaddr))
                 {
                         printk("%s: EEPROM Checksum Failure\n", dev->name);
                         return(-1);
                 }
+		*/
         }
 
         return (0);
@@ -1607,53 +1596,48 @@
         smctr_disable_bic_int(dev);
         smctr_set_trc_reset(dev->base_addr);
 
-        /* By default the adapter will operate in 16-bit mode only. If
-         * there are two or more adapters in a box, switching between
-         * 16-bit and 8-bit mode may cause problems. In short the adapters
-         * will interfere with each other. XXX - smc.
-         */
-        smctr_disable_adapter_ram(dev);
-        if((err = smctr_rom_conflict_test(dev)))
-                return (err);
-
-        if((err = smctr_ram_conflict_test(dev)))
-                return (err);
-
-        smctr_enable_adapter_ram(dev);
         smctr_enable_16bit(dev);
         smctr_set_page(dev, (__u8 *)tp->ram_access);
 
         if(smctr_checksum_firmware(dev))
-                return (UCODE_NOT_PRESENT);
-
-        if((err = smctr_ram_memory_test(dev)))
-                return (err);
-
-        smctr_enable_16bit(dev);
-        if(smctr_checksum_firmware(dev))
-                return (-1);
+	{
+                printk("%s: Previously loaded firmware is missing\n",dev->name);                return (-ENOENT);
+        }
 
         if((err = smctr_ram_memory_test(dev)))
-                return (-1);
+	{
+                printk("%s: RAM memory test failed.\n", dev->name);
+                return (-EIO);
+        }
 
-        smctr_set_rx_look_ahead(dev);
+	smctr_set_rx_look_ahead(dev);
         smctr_load_node_addr(dev);
 
         /* Initialize adapter for Internal Self Test. */
         smctr_reset_adapter(dev);
-
         if((err = smctr_init_card_real(dev)))
-                return (err);
+	{
+                printk("%s: Initialization of card failed (%d)\n",
+                        dev->name, err);
+                return (-EINVAL);
+        }
 
         /* This routine clobbers the TRC's internal registers. */
         if((err = smctr_internal_self_test(dev)))
-                return (err);
+	{
+                printk("%s: Card failed internal self test (%d)\n",
+                        dev->name, err);
+                return (-EINVAL);
+        }
 
         /* Re-Initialize adapter's internal registers */
         smctr_reset_adapter(dev);
-
         if((err = smctr_init_card_real(dev)))
-                return (err);
+	{
+                printk("%s: Initialization of card failed (%d)\n",
+                        dev->name, err);
+                return (-EINVAL);
+        }
 
         smctr_enable_bic_int(dev);
 
@@ -1742,7 +1726,10 @@
                 return (err);
 
         if((err = smctr_issue_init_txrx_cmd(dev)))
+	{
+                printk("%s: Hardware failure\n", dev->name);
                 return (err);
+        }
 
         return (0);
 }
@@ -2737,7 +2724,10 @@
                 return (err);
 
         if((err = smctr_wait_cmd(dev)))
+	{
+                printk("%s: Hardware failure\n", dev->name);
                 return (err);
+        }
 
         /* Initialize Transmit Queue Pointers that are used, to point to
          * a single FCB.
@@ -3551,18 +3541,11 @@
  */
 static int smctr_open(struct net_device *dev)
 {
-        struct net_local *tp = (struct net_local *)dev->priv;
         int err;
 
         if(smctr_debug > 10)
                 printk("%s: smctr_open\n", dev->name);
 
-        tp->status = NOT_INITIALIZED;
-
-        err = smctr_load_firmware(dev);
-        if(err < 0)
-                return (err);
-
         err = smctr_init_adapter(dev);
         if(err < 0)
                 return (err);
@@ -3596,16 +3579,16 @@
         smctr_set_page(dev, (__u8 *)tp->ram_access);
 
         if((err = smctr_issue_resume_rx_fcb_cmd(dev, (short)MAC_QUEUE)))
-                return (err);
+                goto out;
 
         if((err = smctr_issue_resume_rx_bdb_cmd(dev, (short)MAC_QUEUE)))
-                return (err);
+                goto out;
 
         if((err = smctr_issue_resume_rx_fcb_cmd(dev, (short)NON_MAC_QUEUE)))
-                return (err);
+                goto out;
 
         if((err = smctr_issue_resume_rx_bdb_cmd(dev, (short)NON_MAC_QUEUE)))
-                return (err);
+                goto out;
 
         tp->status = CLOSED;
 
@@ -3652,10 +3635,16 @@
                         {
                                 if(!(err = smctr_lobe_media_test(dev)))
                                         err = smctr_issue_insert_cmd(dev);
+				else
+                                {
+                                        if(err == LOBE_MEDIA_TEST_FAILED)
+                                                printk("%s: Lobe Media Test Failure - Check cable?\n", dev->name);
+                                }
                         }
                 }
         }
 
+out:
         restore_flags(flags);
 
         return (err);
@@ -3689,13 +3678,13 @@
 
 static int __init smctr_probe1(struct net_device *dev, int ioaddr)
 {
-        static unsigned version_printed = 0;
+        static unsigned version_printed;
         struct net_local *tp;
         int err;
         __u32 *ram;
 
         if(smctr_debug && version_printed++ == 0)
-                printk("%s", version);
+                printk(version);
 
 #ifndef MODULE
         dev = init_trdev(dev, 0);
@@ -3706,8 +3695,10 @@
         /* Setup this devices private information structure */
         tp = (struct net_local *)kmalloc(sizeof(struct net_local),
                 GFP_KERNEL);
-        if(tp == NULL)
-                return (-ENOMEM);
+        if(tp == NULL) {
+		err = -ENOMEM;
+		goto out;
+	}
         memset(tp, 0, sizeof(struct net_local));
         dev->priv = tp;
         dev->base_addr = ioaddr;
@@ -3716,11 +3707,9 @@
         err = smctr_chk_isa(dev);
         if(err < 0)
         {
-		err = smctr_chk_mca(dev);
-		if(err < 0)
-		{
-                	kfree(tp);
-                	return (-ENODEV);
+		if ((err = smctr_chk_mca(dev)) < 0) {
+			err = -ENODEV;
+			goto out_tp;
 		}
         }
 
@@ -3729,6 +3718,15 @@
         dev->rmem_end = dev->mem_end = dev->mem_start + 0x10000;
         ram = (__u32 *)phys_to_virt(dev->mem_start);
         tp->ram_access = *(__u32 *)&ram;
+	tp->status = NOT_INITIALIZED;
+
+        err = smctr_load_firmware(dev);
+        if(err != UCODE_PRESENT && err != SUCCESS)
+        {
+                printk("%s: Firmware load failed (%d)\n", dev->name, err);
+		err = -EIO;
+		goto out_tp;
+        }
 
 	/* Allow user to specify ring speed on module insert. */
 	if(ringspeed == 4)
@@ -3741,6 +3739,7 @@
                 (unsigned int)dev->base_addr,
                 dev->irq, tp->rom_base, tp->ram_base);
 
+	/* AKPM: there's no point in this */
         dev->init               = smctr_init_card;
         dev->open               = smctr_open;
         dev->stop               = smctr_close;
@@ -3749,8 +3748,12 @@
         dev->watchdog_timeo	= HZ;
         dev->get_stats          = smctr_get_stats;
         dev->set_multicast_list = &smctr_set_multicast_list;
-
         return (0);
+
+out_tp:
+	kfree(tp);
+out:
+	return err;
 }
 
 static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size,
@@ -3952,7 +3955,8 @@
         {
                 rmf->vl = SWAP_BYTES(rmf->vl);
 
-                skb = dev_alloc_skb(size);
+                if (!(skb = dev_alloc_skb(size)))
+			return -ENOMEM;
                 skb->len = size;
 
                 /* Slide data into a sleek skb. */
@@ -3967,33 +3971,13 @@
                 skb->dev = dev;
                 skb->protocol = tr_type_trans(skb, dev);
                 netif_rx(skb);
+		dev->last_rx = jiffies;
                 err = 0;
         }
 
         return (err);
 }
 
-/* Test for RAM in adapter RAM space. */
-static int smctr_ram_conflict_test(struct net_device *dev)
-{
-        struct net_local *tp = (struct net_local *)dev->priv;
-        unsigned int i;
-        __u16 sword;
-
-        for(i = 0; i < (unsigned int)(tp->ram_usable * 1024); i += 1024)
-        {
-                sword = *(__u16 *)(tp->ram_access + i);
-                *(__u16 *)(tp->ram_access + i) = 0x1234;
-                if(*(__u16 *)(tp->ram_access + i) == 0x1234)
-                {
-                        *(__u16 *)(tp->ram_access + i) = sword;
-                        return (-1);
-                }
-        }
-
-        return (0);
-}
-
 /* Adapter RAM test. Incremental word ODD boundry data test. */
 static int smctr_ram_memory_test(struct net_device *dev)
 {
@@ -4034,7 +4018,7 @@
                                 err_offset      = j;
                                 err_word        = word_read;
                                 err_pattern     = word_pattern;
-                                return (-1);
+                                return (RAM_TEST_FAILED);
                         }
                 }
         }
@@ -4059,7 +4043,7 @@
                                 err_offset      = j;
                                 err_word        = word_read;
                                 err_pattern     = word_pattern;
-                                return (-1);
+                                return (RAM_TEST_FAILED);
                         }
                 }
         }
@@ -4069,57 +4053,6 @@
         return (0);
 }
 
-static unsigned int __init smctr_read_584_chksum(int ioaddr)
-{
-        __u8 pg_no, r1, r2;
-        __u16 byte_no, csum_val = 0;
-
-        for(pg_no = 0; pg_no < 16; pg_no++)
-        {
-                r1 = inb(ioaddr + 0x01);
-                r1 &= 0x04;
-                r1 |= 0x02;
-
-                outb(r1, ioaddr + 0x01);
-
-                r1 = inb(ioaddr + 0x03);
-                r1 &= 0x0f;
-                r1 |= (pg_no << 4);
-
-                outb(r1, ioaddr + 0x03);
-
-                r1 = inb(ioaddr + 0x01);
-                r1 &= 0x04;
-                r1 |= 0x12;
-
-                outb(r1, ioaddr + 0x01);
-
-                do {
-                        r1 = inb(ioaddr + 0x01);
-                } while(r1 & 0x10);
-
-                r2 = 0;
-                for(byte_no = 0x08; byte_no < 0x10; byte_no++)
-                {
-                        r1 = inb(ioaddr + byte_no);
-                        r2 += r1;
-                }
-
-                csum_val += r2;
-        }
-
-        r1 = inb(ioaddr + 0x01);
-        r1 &= 0x04;
-        r1 |= 0x10;
-        outb(r1, ioaddr + 0x01);
-
-        csum_val &= 0xff;
-        if(csum_val == 0xff)
-                return (0);
-        else
-                return (-1);
-}
-
 static int smctr_rcv_chg_param(struct net_device *dev, MAC_HEADER *rmf,
         __u16 *correlator)
 {
@@ -4445,10 +4378,10 @@
         int ioaddr = dev->base_addr;
 
         /* Reseting the NIC will put it in a halted and un-initialized state. */        smctr_set_trc_reset(ioaddr);
-        udelay(200000); /* ~2 ms */
+        mdelay(200); /* ~2 ms */
 
         smctr_clear_trc_reset(ioaddr);
-        udelay(200000); /* ~2 ms */
+        mdelay(200); /* ~2 ms */
 
         /* Remove any latched interrupts that occured prior to reseting the
          * adapter or possibily caused by line glitches due to the reset.
@@ -4578,21 +4511,6 @@
         return (0);
 }
 
-/* Test for ROM signature within adapter RAM space. */
-static int smctr_rom_conflict_test(struct net_device *dev)
-{
-        struct net_local *tp = (struct net_local *)dev->priv;
-        unsigned int i;
-
-        for(i = 0; i < (unsigned int)tp->ram_usable * 1024; i += 4096)
-        {
-                if(*(__u16 *)(tp->ram_access + i) == 0xaa55)
-                        return (-1);
-        }
-
-        return (0);
-}
-
 static int smctr_rx_frame(struct net_device *dev)
 {
         struct net_local *tp = (struct net_local *)dev->priv;
@@ -4641,6 +4559,7 @@
                                 skb->dev = dev;
                                 skb->protocol = tr_type_trans(skb, dev);
                                 netif_rx(skb);
+				dev->last_rx = jiffies;
                         }
                         else
                                 smctr_process_rx_packet((MAC_HEADER *)pbuff,
@@ -4700,7 +4619,7 @@
         {
                 if(fcb->frame_status & FCB_COMMAND_DONE)
                         break;
-                udelay(1000);
+                mdelay(1);
         }
 
         /* Check if GOOD frame Tx'ed. */
@@ -4814,7 +4733,7 @@
         {
                 if(fcb->frame_status & FCB_COMMAND_DONE)
                         break;
-                udelay(1000);
+                mdelay(1);
         }
 
         /* Check if GOOD frame Tx'ed */
@@ -5118,7 +5037,7 @@
 		{
           		if(fcb->frame_status & FCB_COMMAND_DONE)
               			break;
-          		udelay(1000);
+          		mdelay(1);
       		}
 
                 /* Check if GOOD frame Tx'ed */
@@ -5181,7 +5100,7 @@
 	{
        		if(fcb->frame_status & FCB_COMMAND_DONE)
            		break;
-        	udelay(1000);
+        	mdelay(1);
    	}
 
         /* Check if GOOD frame Tx'ed */
@@ -5194,7 +5113,7 @@
 		{
           		if(fcb->frame_status & FCB_COMMAND_DONE)
               			break;
-        		udelay(1000);
+        		mdelay(1);
       		}
 
                 if(!(fcb->frame_status & FCB_COMMAND_DONE))
@@ -5451,7 +5370,7 @@
 {
         struct net_local *tp = (struct net_local *)dev->priv;
 
-        tp->acb_head->cmd_done_status   = 0;
+        tp->acb_head->cmd_done_status   = ACB_COMMAND_NOT_DONE;
         tp->acb_head->cmd               = command;
         tp->acb_head->subcmd            = subcommand;
         tp->acb_head->data_offset_lo
@@ -5752,14 +5671,15 @@
         {
                 if(tp->acb_head->cmd_done_status & ACB_COMMAND_DONE)
                         break;
+		udelay(1);
                 loop_count--;
         }
 
         if(loop_count == 0)
-                return(-1);
+                return(HARDWARE_FAILED);
 
         if(tp->acb_head->cmd_done_status & 0xff)
-                return(-1);
+                return(HARDWARE_FAILED);
 
         return (0);
 }
@@ -5795,7 +5715,7 @@
         if(timeout)
                 return (0);
         else
-                return (-1);
+                return (HARDWARE_FAILED);
 }
 
 #ifdef MODULE
diff -urN linux-2.4.2-pre1/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c
--- linux-2.4.2-pre1/drivers/scsi/aha152x.c	Mon Dec  3 22:27:36 2001
+++ linux/drivers/scsi/aha152x.c	Mon Dec  3 22:27:48 2001
@@ -1,6 +1,6 @@
 /* aha152x.c -- Adaptec AHA-152x driver
  * Author: Jürgen E. Fischer, fischer@norbit.de
- * Copyright 1993-1999 Jürgen E. Fischer
+ * Copyright 1993-2000 Jürgen E. Fischer
  *
  * 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
@@ -13,9 +13,13 @@
  * General Public License for more details.
  *
  *
- * $Id: aha152x.c,v 2.3 2000/11/04 16:40:26 fischer Exp $
+ * $Id: aha152x.c,v 2.4 2000/12/16 12:53:56 fischer Exp $
  *
  * $Log: aha152x.c,v $
+ * Revision 2.4  2000/12/16 12:53:56  fischer
+ * - allow REQUEST SENSE to be queued
+ * - handle shared PCI interrupts
+ *
  * Revision 2.3  2000/11/04 16:40:26  fischer
  * - handle data overruns
  * - extend timeout for data phases
@@ -299,7 +303,7 @@
                         (cmd) ? ((cmd)->target & 0x0f) : -1, \
 			(cmd) ? ((cmd)->lun & 0x07) : -1
 
-#define DELAY_DEFAULT 100
+#define DELAY_DEFAULT 1000
 
 /* possible irq range */
 #if defined(PCMCIA)
@@ -932,6 +936,8 @@
         	printk(KERN_ERR "aha152x%d: catched software interrupt for unknown controller.\n", HOSTNO);
 
 	HOSTDATA(shpnt)->swint++;
+
+	SETPORT(DMACNTRL0, INTEN);
 }
 
 
@@ -1231,18 +1237,12 @@
 		if (setup[i].reconnect)
 			shpnt->can_queue = AHA152X_MAXQUEUE;
 
-#if 0
-		if(!shpnt->hostt->use_new_eh_code) {
-#endif
-			/* RESET OUT */
-			printk("aha152x: resetting bus...\n");
-			SETPORT(SCSISEQ, SCSIRSTO);
-			mdelay(256);
-			SETPORT(SCSISEQ, 0);
-			mdelay(DELAY);
-#if 0
-		}
-#endif
+		/* RESET OUT */
+		printk("aha152x: resetting bus...\n");
+		SETPORT(SCSISEQ, SCSIRSTO);
+		mdelay(256);
+		SETPORT(SCSISEQ, 0);
+		mdelay(DELAY);
 
 		reset_ports(shpnt);
 
@@ -1274,7 +1274,7 @@
 		SETPORT(SIMODE0, 0);
 		SETPORT(SIMODE1, 0);
 
-		ok = request_irq(shpnt->irq, swintr, SA_INTERRUPT, "aha152x", shpnt);
+		ok = request_irq(shpnt->irq, swintr, SA_INTERRUPT|SA_SHIRQ, "aha152x", shpnt);
 		if (ok < 0) {
 			if (ok==-EINVAL)
 				printk(KERN_ERR "aha152x%d: bad IRQ %d.\n", HOSTNO, shpnt->irq);
@@ -1308,6 +1308,8 @@
 				printk("failed.\n");
 			}
 
+			SETPORT(DMACNTRL0, INTEN);
+
 			printk(KERN_ERR "aha152x%d: IRQ %d possibly wrong.  Please verify.\n", HOSTNO, shpnt->irq);
 
 			registered_count--;
@@ -1319,13 +1321,12 @@
 		}
 		printk("ok.\n");
 
-		SETPORT(DMACNTRL0, INTEN);
 
 		/* clear interrupts */
 		SETPORT(SSTAT0, 0x7f);
 		SETPORT(SSTAT1, 0xef);
 
-		if (request_irq(shpnt->irq, intr, SA_INTERRUPT, "aha152x", shpnt) < 0) {
+		if (request_irq(shpnt->irq, intr, SA_INTERRUPT|SA_SHIRQ, "aha152x", shpnt) < 0) {
 			printk(KERN_ERR "aha152x%d: failed to reassign interrupt.\n", HOSTNO);
 
 			scsi_unregister(shpnt);
@@ -1469,12 +1470,14 @@
 
 int aha152x_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
 {
+#if 0
 	if(*SCpnt->cmnd == REQUEST_SENSE) {
 		SCpnt->result = 0;
 		done(SCpnt);
 
-		return SUCCESS;
+		return 0;
 	}
+#endif
 
 	return aha152x_internal_queue(SCpnt, 0, 0, 0, done);
 }
@@ -1604,7 +1607,7 @@
 
 	init_timer(&timer);
 	timer.data     = (unsigned long) &sem;
-	timer.expires  = jiffies + 10 * HZ;   /* 10s */
+	timer.expires  = jiffies + 100*HZ;   /* 10s */
 	timer.function = (void (*)(unsigned long)) timer_expired;
 	add_timer(&timer);
 
@@ -2579,7 +2582,7 @@
 		if(TESTHI(DMASTAT, DFIFOFULL)) {
 			fifodata = 128;
 		} else {
-			the_time=jiffies + HZ;
+			the_time=jiffies + 10*HZ;
 			while(TESTLO(SSTAT2, SEMPTY) && time_before(jiffies,the_time))
 				barrier();
 
@@ -2735,7 +2738,7 @@
 			CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length;
 		}
 
-		the_time=jiffies+10*HZ;
+		the_time=jiffies + 10*HZ;
 		while(TESTLO(DMASTAT, DFIFOEMP|INTSTAT) && time_before(jiffies,the_time))
 			barrier();
 
diff -urN linux-2.4.2-pre1/drivers/scsi/aha152x.h linux/drivers/scsi/aha152x.h
--- linux-2.4.2-pre1/drivers/scsi/aha152x.h	Mon Dec 11 13:19:02 2000
+++ linux/drivers/scsi/aha152x.h	Mon Dec  3 22:27:48 2001
@@ -2,7 +2,7 @@
 #define _AHA152X_H
 
 /*
- * $Id: aha152x.h,v 2.3 2000/11/04 16:41:37 fischer Exp $
+ * $Id: aha152x.h,v 2.4 2000/12/16 12:48:48 fischer Exp $
  */
 
 #if defined(__KERNEL__)
@@ -27,7 +27,7 @@
    (unless we support more than 1 cmd_per_lun this should do) */
 #define AHA152X_MAXQUEUE 7
 
-#define AHA152X_REVID "Adaptec 152x SCSI driver; $Revision: 2.3 $"
+#define AHA152X_REVID "Adaptec 152x SCSI driver; $Revision: 2.4 $"
 
 /* Initial value of Scsi_Host entry */
 #define AHA152X { proc_name:			"aha152x",		\
diff -urN linux-2.4.2-pre1/drivers/scsi/eata.c linux/drivers/scsi/eata.c
--- linux-2.4.2-pre1/drivers/scsi/eata.c	Mon Nov 27 17:49:00 2000
+++ linux/drivers/scsi/eata.c	Mon Dec  3 22:27:48 2001
@@ -1,6 +1,9 @@
 /*
  *      eata.c - Low-level driver for EATA/DMA SCSI host adapters.
  *
+ *      25 Jan 2001 Rev. 6.03 for linux 2.4.0
+ *        + "check_region" call replaced by "request_region".
+ *
  *      22 Nov 2000 Rev. 6.02 for linux 2.4.0-test11
  *        + Return code checked when calling pci_enable_device.
  *        + Removed old scsi error handling support.
@@ -210,7 +213,7 @@
  *          This driver is based on the CAM (Common Access Method Committee)
  *          EATA (Enhanced AT Bus Attachment) rev. 2.0A, using DMA protocol.
  *
- *  Copyright (C) 1994-2000 Dario Ballabio (ballabio_dario@emc.com)
+ *  Copyright (C) 1994-2001 Dario Ballabio (ballabio_dario@emc.com)
  *
  *  Alternate email: dario.ballabio@inwind.it, dario.ballabio@tiscalinet.it
  *
@@ -901,25 +904,34 @@
 
    sprintf(name, "%s%d", driver_name, j);
 
-   if(check_region(port_base, REGION_SIZE)) {
+   if(!request_region(port_base, REGION_SIZE, driver_name)) {
 #if defined(DEBUG_DETECT)
       printk("%s: address 0x%03lx in use, skipping probe.\n", name, port_base);
 #endif
       return FALSE;
       }
 
-   if (do_dma(port_base, 0, READ_CONFIG_PIO)) return FALSE;
+   if (do_dma(port_base, 0, READ_CONFIG_PIO)) {
+      release_region(port_base, REGION_SIZE);
+      return FALSE;
+      }
 
    /* Read the info structure */
-   if (read_pio(port_base, (ushort *)&info, (ushort *)&info.ipad[0]))
+   if (read_pio(port_base, (ushort *)&info, (ushort *)&info.ipad[0])) {
+      release_region(port_base, REGION_SIZE);
       return FALSE;
+      }
 
    /* Check the controller "EATA" signature */
-   if (info.sign != EATA_SIGNATURE) return FALSE;
+   if (info.sign != EATA_SIGNATURE) {
+      release_region(port_base, REGION_SIZE);
+      return FALSE;
+      }
 
    if (DEV2H(info.data_len) < EATA_2_0A_SIZE) {
       printk("%s: config structure size (%d bytes) too short, detaching.\n",
              name, DEV2H(info.data_len));
+      release_region(port_base, REGION_SIZE);
       return FALSE;
       }
    else if (DEV2H(info.data_len) == EATA_2_0A_SIZE)
@@ -957,6 +969,7 @@
    if (!info.haaval || info.ata) {
       printk("%s: address 0x%03lx, unusable %s board (%d%d), detaching.\n",
              name, port_base, bus_type, info.haaval, info.ata);
+      release_region(port_base, REGION_SIZE);
       return FALSE;
       }
 
@@ -996,6 +1009,7 @@
              SA_INTERRUPT | ((subversion == ESA) ? SA_SHIRQ : 0),
              driver_name, (void *) &sha[j])) {
       printk("%s: unable to allocate IRQ %u, detaching.\n", name, irq);
+      release_region(port_base, REGION_SIZE);
       return FALSE;
       }
 
@@ -1003,6 +1017,7 @@
       printk("%s: unable to allocate DMA channel %u, detaching.\n",
              name, dma_channel);
       free_irq(irq, &sha[j]);
+      release_region(port_base, REGION_SIZE);
       return FALSE;
       }
 
@@ -1017,6 +1032,7 @@
 
    if (do_dma(port_base, (unsigned long)&config, SET_CONFIG_DMA)) {
       printk("%s: busy timeout sending configuration, detaching.\n", name);
+      release_region(port_base, REGION_SIZE);
       return FALSE;
       }
    }
@@ -1031,6 +1047,7 @@
 
       if (subversion == ISA) free_dma(dma_channel);
 
+      release_region(port_base, REGION_SIZE);
       return FALSE;
       }
 
@@ -1129,7 +1146,7 @@
    else                                 tag_type = 'n';
 
    if (j == 0) {
-      printk("EATA/DMA 2.0x: Copyright (C) 1994-2000 Dario Ballabio.\n");
+      printk("EATA/DMA 2.0x: Copyright (C) 1994-2001 Dario Ballabio.\n");
       printk("%s config options -> tc:%c, lc:%c, mq:%d, rs:%c, et:%c.\n",
              driver_name, tag_type, YESNO(linked_comm), max_queue_depth,
              YESNO(rev_scan), YESNO(ext_tran));
@@ -1149,7 +1166,7 @@
 
 #if defined(DEBUG_DETECT)
    printk("%s: Vers. 0x%x, ocs %u, tar %u, trnxfr %u, more %u, SYNC 0x%x, "\
-          "sec. %u, infol %ld, cpl %ld spl %ld.\n", name, info.version,
+          "sec. %u, infol %d, cpl %d spl %d.\n", name, info.version,
           info.ocsena, info.tarsup, info.trnxfr, info.morsup, info.sync,
           info.second, DEV2H(info.data_len), DEV2H(info.cp_len),
           DEV2H(info.sp_len));
diff -urN linux-2.4.2-pre1/drivers/scsi/eata.h linux/drivers/scsi/eata.h
--- linux-2.4.2-pre1/drivers/scsi/eata.h	Mon Nov 27 17:49:00 2000
+++ linux/drivers/scsi/eata.h	Mon Dec  3 22:27:48 2001
@@ -13,7 +13,7 @@
 int eata2x_reset(Scsi_Cmnd *);
 int eata2x_biosparam(Disk *, kdev_t, int *);
 
-#define EATA_VERSION "6.02.00"
+#define EATA_VERSION "6.03.00"
 
 #define EATA {                                                               \
                 name:              "EATA/DMA 2.0x rev. " EATA_VERSION " ",   \
diff -urN linux-2.4.2-pre1/drivers/scsi/scsi_ioctl.c linux/drivers/scsi/scsi_ioctl.c
--- linux-2.4.2-pre1/drivers/scsi/scsi_ioctl.c	Thu Nov 16 12:51:28 2000
+++ linux/drivers/scsi/scsi_ioctl.c	Mon Dec  3 22:27:48 2001
@@ -101,7 +101,10 @@
 
 
 	SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", cmd[0]));
-	SRpnt = scsi_allocate_request(dev);
+	if (NULL == (SRpnt = scsi_allocate_request(dev))) {
+		printk("SCSI internal ioctl failed, no memory\n");
+		return -ENOMEM;
+	}
 
 	SRpnt->sr_data_direction = SCSI_DATA_NONE;
         scsi_wait_req(SRpnt, cmd, NULL, 0, timeout, retries);
diff -urN linux-2.4.2-pre1/drivers/scsi/scsi_scan.c linux/drivers/scsi/scsi_scan.c
--- linux-2.4.2-pre1/drivers/scsi/scsi_scan.c	Tue Sep 19 08:01:34 2000
+++ linux/drivers/scsi/scsi_scan.c	Mon Dec  3 22:27:48 2001
@@ -492,7 +492,10 @@
 	SDpnt->expecting_cc_ua = 0;
 	SDpnt->starved = 0;
 
-	SRpnt = scsi_allocate_request(SDpnt);
+	if (NULL == (SRpnt = scsi_allocate_request(SDpnt))) {
+		printk("scan_scsis_single: no memory\n");
+		return 0;
+	}
 
 	/*
 	 * We used to do a TEST_UNIT_READY before the INQUIRY but that was 
diff -urN linux-2.4.2-pre1/drivers/scsi/u14-34f.c linux/drivers/scsi/u14-34f.c
--- linux-2.4.2-pre1/drivers/scsi/u14-34f.c	Mon Nov 27 17:49:00 2000
+++ linux/drivers/scsi/u14-34f.c	Mon Dec  3 22:27:48 2001
@@ -1,7 +1,10 @@
 /*
  *      u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters.
  *
- *      01 Nov 2000 Rev. 6.02 for linux 2.4.0-test11
+ *      25 Jan 2001 Rev. 6.03 for linux 2.4.0
+ *        + "check_region" call replaced by "request_region".
+ *
+ *      22 Nov 2000 Rev. 6.02 for linux 2.4.0-test11
  *        + Removed old scsi error handling support.
  *        + The obsolete boot option flag eh:n is silently ignored.
  *        + Removed error messages while a disk drive is powered up at
@@ -177,7 +180,7 @@
  *
  *          Multiple U14F and/or U34F host adapters are supported.
  *
- *  Copyright (C) 1994-2000 Dario Ballabio (ballabio_dario@emc.com)
+ *  Copyright (C) 1994-2001 Dario Ballabio (ballabio_dario@emc.com)
  *
  *  Alternate email: dario.ballabio@inwind.it, dario.ballabio@tiscalinet.it
  *
@@ -729,18 +732,24 @@
 
    sprintf(name, "%s%d", driver_name, j);
 
-   if(check_region(port_base, REGION_SIZE)) {
+   if(!request_region(port_base, REGION_SIZE, driver_name)) {
 #if defined(DEBUG_DETECT)
       printk("%s: address 0x%03lx in use, skipping probe.\n", name, port_base);
 #endif
       return FALSE;
       }
 
-   if (inb(port_base + REG_PRODUCT_ID1) != PRODUCT_ID1) return FALSE;
+   if (inb(port_base + REG_PRODUCT_ID1) != PRODUCT_ID1) {
+      release_region(port_base, REGION_SIZE);
+      return FALSE;
+      }
 
    in_byte = inb(port_base + REG_PRODUCT_ID2);
 
-   if ((in_byte & 0xf0) != PRODUCT_ID2) return FALSE;
+   if ((in_byte & 0xf0) != PRODUCT_ID2) {
+      release_region(port_base, REGION_SIZE);
+      return FALSE;
+      }
 
    *(char *)&config_1 = inb(port_base + REG_CONFIG1);
    *(char *)&config_2 = inb(port_base + REG_CONFIG2);
@@ -754,6 +763,7 @@
              SA_INTERRUPT | ((subversion == ESA) ? SA_SHIRQ : 0),
              driver_name, (void *) &sha[j])) {
       printk("%s: unable to allocate IRQ %u, detaching.\n", name, irq);
+      release_region(port_base, REGION_SIZE);
       return FALSE;
       }
 
@@ -761,6 +771,7 @@
       printk("%s: unable to allocate DMA channel %u, detaching.\n",
              name, dma_channel);
       free_irq(irq, &sha[j]);
+      release_region(port_base, REGION_SIZE);
       return FALSE;
       }
 
@@ -775,6 +786,7 @@
 
       if (subversion == ISA) free_dma(dma_channel);
 
+      release_region(port_base, REGION_SIZE);
       return FALSE;
       }
 
@@ -805,9 +817,6 @@
    /* If BIOS is disabled, force enable interrupts */
    if (sh[j]->base == 0) outb(CMD_ENA_INTR, sh[j]->io_port + REG_SYS_MASK);
 
-   /* Register the I/O space that we use */
-   request_region(sh[j]->io_port, sh[j]->n_io_port, driver_name);
-
    memset(HD(j), 0, sizeof(struct hostdata));
    HD(j)->heads = mapping_table[config_2.mapping_mode].heads;
    HD(j)->sectors = mapping_table[config_2.mapping_mode].sectors;
@@ -873,7 +882,7 @@
    if (max_queue_depth < MAX_CMD_PER_LUN) max_queue_depth = MAX_CMD_PER_LUN;
 
    if (j == 0) {
-      printk("UltraStor 14F/34F: Copyright (C) 1994-2000 Dario Ballabio.\n");
+      printk("UltraStor 14F/34F: Copyright (C) 1994-2001 Dario Ballabio.\n");
       printk("%s config options -> of:%c, lc:%c, mq:%d, et:%c.\n",
              driver_name, YESNO(have_old_firmware), YESNO(linked_comm),
              max_queue_depth, YESNO(ext_tran));
diff -urN linux-2.4.2-pre1/drivers/scsi/u14-34f.h linux/drivers/scsi/u14-34f.h
--- linux-2.4.2-pre1/drivers/scsi/u14-34f.h	Mon Nov 27 17:49:00 2000
+++ linux/drivers/scsi/u14-34f.h	Mon Dec  3 22:27:48 2001
@@ -13,7 +13,7 @@
 int u14_34f_reset(Scsi_Cmnd *);
 int u14_34f_biosparam(Disk *, kdev_t, int *);
 
-#define U14_34F_VERSION "6.02.00"
+#define U14_34F_VERSION "6.03.00"
 
 #define ULTRASTOR_14_34F {                                                   \
                 name:         "UltraStor 14F/34F rev. " U14_34F_VERSION " ", \
diff -urN linux-2.4.2-pre1/drivers/sound/Config.in linux/drivers/sound/Config.in
--- linux-2.4.2-pre1/drivers/sound/Config.in	Fri Jan 26 23:31:16 2001
+++ linux/drivers/sound/Config.in	Mon Dec  3 22:27:48 2001
@@ -21,6 +21,7 @@
 dep_tristate '  Creative Ensoniq AudioPCI 97 (ES1371)' CONFIG_SOUND_ES1371 $CONFIG_SOUND
 dep_tristate '  ESS Technology Solo1' CONFIG_SOUND_ESSSOLO1 $CONFIG_SOUND
 dep_tristate '  ESS Maestro, Maestro2, Maestro2E driver' CONFIG_SOUND_MAESTRO $CONFIG_SOUND
+dep_tristate '  ESS Maestro3/Allegro driver (EXPERIMENTAL)' CONFIG_SOUND_MAESTRO3 $CONFIG_SOUND $CONFIG_PCI $CONFIG_EXPERIMENTAL
 dep_tristate '  S3 SonicVibes' CONFIG_SOUND_SONICVIBES $CONFIG_SOUND
 if [ "$CONFIG_VISWS" = "y" ]; then
     dep_tristate '  SGI Visual Workstation Sound' CONFIG_SOUND_VWSND $CONFIG_SOUND
@@ -141,11 +142,9 @@
 
    dep_tristate '    Yamaha FM synthesizer (YM3812/OPL-3) support' CONFIG_SOUND_YM3812 $CONFIG_SOUND_OSS
    dep_tristate '    Yamaha OPL3-SA1 audio controller' CONFIG_SOUND_OPL3SA1 $CONFIG_SOUND_OSS
-   dep_tristate '    Yamaha OPL3-SA2, SA3, and SAx based PnP cards' CONFIG_SOUND_OPL3SA2 $CONFIG_SOUND_OSS
+   dep_tristate '    Yamaha OPL3-SA2 and SA3 based PnP cards' CONFIG_SOUND_OPL3SA2 $CONFIG_SOUND_OSS
    dep_tristate '    Yamaha YMF7xx PCI audio (native mode)' CONFIG_SOUND_YMFPCI $CONFIG_SOUND_OSS $CONFIG_PCI
-   if [ "$CONFIG_SOUND_YMFPCI" != "n" ]; then
-      bool '      Yamaha PCI legacy ports support' CONFIG_SOUND_YMFPCI_LEGACY
-   fi
+   dep_mbool '      Yamaha PCI legacy ports support' CONFIG_SOUND_YMFPCI_LEGACY $CONFIG_SOUND_YMFPCI
    dep_tristate '    6850 UART support' CONFIG_SOUND_UART6850 $CONFIG_SOUND_OSS
   
    dep_tristate '    Gallant Audio Cards (SC-6000 and SC-6600 based)' CONFIG_SOUND_AEDSP16 $CONFIG_SOUND_OSS
diff -urN linux-2.4.2-pre1/drivers/sound/Makefile linux/drivers/sound/Makefile
--- linux-2.4.2-pre1/drivers/sound/Makefile	Fri Jan 26 23:31:16 2001
+++ linux/drivers/sound/Makefile	Mon Dec  3 22:27:48 2001
@@ -62,14 +62,19 @@
 obj-$(CONFIG_SOUND_ES1371)	+= es1371.o ac97_codec.o
 obj-$(CONFIG_SOUND_ESSSOLO1)	+= esssolo1.o
 obj-$(CONFIG_SOUND_FUSION)	+= cs46xx.o ac97_codec.o
-obj-$(CONFIG_SOUND_CS4281)	+= cs4281.o
 obj-$(CONFIG_SOUND_MAESTRO)	+= maestro.o
+obj-$(CONFIG_SOUND_MAESTRO3)	+= maestro3.o ac97_codec.o
 obj-$(CONFIG_SOUND_TRIDENT)	+= trident.o ac97_codec.o
 
 subdir-$(CONFIG_SOUND_EMU10K1) += emu10k1
+subdir-$(CONFIG_SOUND_CS4281) += cs4281
 
 ifeq ($(CONFIG_SOUND_EMU10K1),y)
   obj-y += emu10k1/emu10k1.o
+endif
+
+ifeq ($(CONFIG_SOUND_CS4281),y)
+  obj-y += cs4281/cs4281.o
 endif
 
 subdir-$(CONFIG_DMASOUND) += dmasound
diff -urN linux-2.4.2-pre1/drivers/sound/ad1816.c linux/drivers/sound/ad1816.c
--- linux-2.4.2-pre1/drivers/sound/ad1816.c	Thu Nov 16 12:51:28 2000
+++ linux/drivers/sound/ad1816.c	Mon Dec  3 22:27:48 2001
@@ -1314,30 +1314,44 @@
 	return(ad1816_dev);
 }
 
+static struct ad1816_data {
+	struct pci_dev * (*initfunc)(struct pci_bus*, struct pci_dev *, struct address_info *);
+	char *name;
+} ad1816_pnp_data[] __initdata = {
+	{ &ad1816_init_generic, "Analog Devices 1815" },
+	{ &ad1816_init_generic, "Analog Devices 1816A" }
+};
+
 static struct {
+	unsigned short card_vendor, card_device;
 	unsigned short vendor;
 	unsigned short function;
-	struct pci_dev * (*initfunc)(struct pci_bus*, struct pci_dev *, struct address_info *);
-	char *name;
+	struct ad1816_data *data;
 } isapnp_ad1816_list[] __initdata = {
-	{ISAPNP_VENDOR('A','D','S'), ISAPNP_FUNCTION(0x7150), &ad1816_init_generic, "Analog Devices 1815" },
-	{ISAPNP_VENDOR('A','D','S'), ISAPNP_FUNCTION(0x7180), &ad1816_init_generic, "Analog Devices 1816A" },
+	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+		ISAPNP_VENDOR('A','D','S'), ISAPNP_FUNCTION(0x7150), 
+		&ad1816_pnp_data[0] },
+	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+		ISAPNP_VENDOR('A','D','S'), ISAPNP_FUNCTION(0x7180),
+		&ad1816_pnp_data[1] },
 	{0}
 };
 
+MODULE_DEVICE_TABLE(isapnp, isapnp_ad1816_list);
+
 static int __init ad1816_init_isapnp(struct address_info *hw_config,
 	struct pci_bus *bus, struct pci_dev *card, int slot)
 {
 	struct pci_dev *idev = NULL;
 	
 	/* You missed the init func? That's bad. */
-	if(isapnp_ad1816_list[slot].initfunc) {
-		char *busname = bus->name[0] ? bus->name : isapnp_ad1816_list[slot].name;
+	if(isapnp_ad1816_list[slot].data->initfunc) {
+		char *busname = bus->name[0] ? bus->name : isapnp_ad1816_list[slot].data->name;
 		
 		printk(KERN_INFO "ad1816: %s detected\n", busname);
 		
 		/* Initialize this baby. */
-		if((idev = isapnp_ad1816_list[slot].initfunc(bus, card, hw_config))) {
+		if((idev = isapnp_ad1816_list[slot].data->initfunc(bus, card, hw_config))) {
 			/* We got it. */
 
 			printk(KERN_NOTICE "ad1816: ISAPnP reports '%s' at i/o %#x, irq %d, dma %d, %d\n",
diff -urN linux-2.4.2-pre1/drivers/sound/ad1848.c linux/drivers/sound/ad1848.c
--- linux-2.4.2-pre1/drivers/sound/ad1848.c	Fri Aug 11 08:26:43 2000
+++ linux/drivers/sound/ad1848.c	Mon Dec  3 22:27:48 2001
@@ -28,6 +28,7 @@
  *		          of irqs. Use dev_id.
  * Christoph Hellwig	: adapted to module_init/module_exit
  * Aki Laukkanen	: added power management support
+ * Arnaldo C. de Melo	: added missing restore_flags in ad1848_resume
  *
  * Status:
  *		Tested. Believed fully functional.
@@ -1900,9 +1901,6 @@
 	if(portc==NULL)
 		return -1;
 
-	if (owner)
-		ad1848_audio_driver.owner = owner;
-	
 	if ((my_dev = sound_install_audiodrv(AUDIO_DRIVER_VERSION,
 					     dev_name,
 					     &ad1848_audio_driver,
@@ -1920,6 +1918,8 @@
 	
 	audio_devs[my_dev]->portc = portc;
 	audio_devs[my_dev]->mixer_dev = -1;
+	if (owner)
+		audio_devs[my_dev]->d->owner = owner;
 	memset((char *) portc, 0, sizeof(*portc));
 
 	nr_ad1848_devs++;
@@ -1986,6 +1986,7 @@
 			if (sound_alloc_dma(dma_capture, devc->name))
 				printk(KERN_WARNING "ad1848.c: Can't allocate DMA%d\n", dma_capture);
 	}
+
 	if ((e = sound_install_mixer(MIXER_DRIVER_VERSION,
 				     dev_name,
 				     &ad1848_mixer_operations,
@@ -1993,6 +1994,8 @@
 				     devc)) >= 0)
 	{
 		audio_devs[my_dev]->mixer_dev = e;
+		if (owner)
+			mixer_devs[e]->owner = owner;
 	}
 	return my_dev;
 }
@@ -2751,6 +2754,7 @@
 		bits = interrupt_bits[devc->irq];
 		if (bits == -1) {
 			printk(KERN_ERR "MSS: Bad IRQ %d\n", devc->irq);
+			restore_flags(flags);
 			return -1;
 		}
 
diff -urN linux-2.4.2-pre1/drivers/sound/audio.c linux/drivers/sound/audio.c
--- linux-2.4.2-pre1/drivers/sound/audio.c	Fri Aug 11 08:26:43 2000
+++ linux/drivers/sound/audio.c	Mon Dec  3 22:27:48 2001
@@ -21,6 +21,9 @@
  * Daniel Rodriksson: reworked the use of the device specific copy_user
  *                    still generic
  * Horst von Brand:  Add missing #include <linux/string.h>
+ * Chris Rankin    : Update the module-usage counter for the coprocessor,
+ *                   and decrement the counters again if we cannot open
+ *                   the audio device.
  */
 
 #include <linux/stddef.h>
@@ -71,6 +74,8 @@
 	int bits;
 	int dev_type = dev & 0x0f;
 	int mode = translate_mode(file);
+	const struct audio_driver *driver;
+	const struct coproc_operations *coprocessor;
 
 	dev = dev >> 4;
 
@@ -82,18 +87,20 @@
 	if (dev < 0 || dev >= num_audiodevs)
 		return -ENXIO;
 
-	if (audio_devs[dev]->d->owner)
-		__MOD_INC_USE_COUNT (audio_devs[dev]->d->owner);
+	driver = audio_devs[dev]->d;
+	if (driver->owner)
+		__MOD_INC_USE_COUNT(driver->owner);
 
 	if ((ret = DMAbuf_open(dev, mode)) < 0)
-		return ret;
+		goto error_1;
 
-	if (audio_devs[dev]->coproc) {
-		if ((ret = audio_devs[dev]->coproc->
-			open(audio_devs[dev]->coproc->devc, COPR_PCM)) < 0) {
-			audio_release(dev, file);
+	if ( (coprocessor = audio_devs[dev]->coproc) != NULL ) {
+		if (coprocessor->owner)
+			__MOD_INC_USE_COUNT(coprocessor->owner);
+
+		if ((ret = coprocessor->open(coprocessor->devc, COPR_PCM)) < 0) {
 			printk(KERN_WARNING "Sound: Can't access coprocessor device\n");
-			return ret;
+			goto error_2;
 		}
 	}
 	
@@ -106,6 +113,20 @@
 
 	audio_devs[dev]->audio_mode = AM_NONE;
 
+	return 0;
+
+	/*
+	 * Clean-up stack: this is what needs (un)doing if
+	 * we can't open the audio device ...
+	 */
+	error_2:
+	if (coprocessor->owner)
+		__MOD_DEC_USE_COUNT(coprocessor->owner);
+	DMAbuf_release(dev, mode);
+
+	error_1:
+	if (driver->owner)
+		__MOD_DEC_USE_COUNT(driver->owner);
 
 	return ret;
 }
@@ -156,7 +177,8 @@
 
 void audio_release(int dev, struct file *file)
 {
-	int             mode = translate_mode(file);
+	const struct coproc_operations *coprocessor;
+	int mode = translate_mode(file);
 
 	dev = dev >> 4;
 
@@ -176,8 +198,12 @@
 	if (mode & OPEN_WRITE)
 		sync_output(dev);
 
-	if (audio_devs[dev]->coproc)
-		audio_devs[dev]->coproc->close(audio_devs[dev]->coproc->devc, COPR_PCM);
+	if ( (coprocessor = audio_devs[dev]->coproc) != NULL ) {
+		coprocessor->close(coprocessor->devc, COPR_PCM);
+
+		if (coprocessor->owner)
+			__MOD_DEC_USE_COUNT(coprocessor->owner);
+	}
 	DMAbuf_release(dev, mode);
 
 	if (audio_devs[dev]->d->owner)
diff -urN linux-2.4.2-pre1/drivers/sound/awe_wave.c linux/drivers/sound/awe_wave.c
--- linux-2.4.2-pre1/drivers/sound/awe_wave.c	Thu Nov 16 12:51:28 2000
+++ linux/drivers/sound/awe_wave.c	Mon Dec  3 22:27:48 2001
@@ -4772,15 +4772,24 @@
 	
 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
 static struct {
+	unsigned short card_vendor, card_device;
 	unsigned short vendor;
 	unsigned short function;
 	char *name;
 } isapnp_awe_list[] __initdata = {
-	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0021), "AWE32 WaveTable"},
-	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0022), "AWE64 WaveTable"},
-	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0023), "AWE64 Gold WaveTable"},
-	{0,}
+	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0021),
+		"AWE32 WaveTable" },
+	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0022),
+		"AWE64 WaveTable" },
+	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0023),
+		"AWE64 Gold WaveTable" },
+	{0}
 };
+
+MODULE_DEVICE_TABLE(isapnp, isapnp_awe_list);
 
 static struct pci_dev *idev = NULL;
 
diff -urN linux-2.4.2-pre1/drivers/sound/cs4281/Makefile linux/drivers/sound/cs4281/Makefile
--- linux-2.4.2-pre1/drivers/sound/cs4281/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/drivers/sound/cs4281/Makefile	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,12 @@
+# Makefile for Cirrus Logic-Crystal CS4281 
+#
+
+O_TARGET := cs4281.o
+
+obj-y := cs4281m.o
+obj-m := $(O_TARGET)
+
+include $(TOPDIR)/Rules.make
+
+clean:
+	rm -f core *.o *.a *.s
diff -urN linux-2.4.2-pre1/drivers/sound/cs4281/cs4281_hwdefs.h linux/drivers/sound/cs4281/cs4281_hwdefs.h
--- linux-2.4.2-pre1/drivers/sound/cs4281/cs4281_hwdefs.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/sound/cs4281/cs4281_hwdefs.h	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,1234 @@
+//****************************************************************************
+//
+// HWDEFS.H - Definitions of the registers and data structures used by the
+//            CS4281
+//
+// Copyright (c) 1999,2000,2001 Crystal Semiconductor Corp.
+//
+//****************************************************************************
+
+#ifndef _H_HWDEFS
+#define _H_HWDEFS
+
+//****************************************************************************
+//
+// The following define the offsets of the registers located in the PCI
+// configuration space of the CS4281 part.
+//
+//****************************************************************************
+#define PCICONFIG_DEVID_VENID                   0x00000000L
+#define PCICONFIG_STATUS_COMMAND                0x00000004L
+#define PCICONFIG_CLASS_REVISION                0x00000008L
+#define PCICONFIG_LATENCY_TIMER                 0x0000000CL
+#define PCICONFIG_BA0                           0x00000010L
+#define PCICONFIG_BA1                           0x00000014L
+#define PCICONFIG_SUBSYSID_SUBSYSVENID          0x0000002CL
+#define PCICONFIG_INTERRUPT                     0x0000003CL
+
+//****************************************************************************
+//
+// The following define the offsets of the registers accessed via base address
+// register zero on the CS4281 part.
+//
+//****************************************************************************
+#define BA0_HISR                                0x00000000L
+#define BA0_HICR                                0x00000008L
+#define BA0_HIMR                                0x0000000CL
+#define BA0_IIER                                0x00000010L
+#define BA0_HDSR0                               0x000000F0L
+#define BA0_HDSR1                               0x000000F4L
+#define BA0_HDSR2                               0x000000F8L
+#define BA0_HDSR3                               0x000000FCL
+#define BA0_DCA0                                0x00000110L
+#define BA0_DCC0                                0x00000114L
+#define BA0_DBA0                                0x00000118L
+#define BA0_DBC0                                0x0000011CL
+#define BA0_DCA1                                0x00000120L
+#define BA0_DCC1                                0x00000124L
+#define BA0_DBA1                                0x00000128L
+#define BA0_DBC1                                0x0000012CL
+#define BA0_DCA2                                0x00000130L
+#define BA0_DCC2                                0x00000134L
+#define BA0_DBA2                                0x00000138L
+#define BA0_DBC2                                0x0000013CL
+#define BA0_DCA3                                0x00000140L
+#define BA0_DCC3                                0x00000144L
+#define BA0_DBA3                                0x00000148L
+#define BA0_DBC3                                0x0000014CL
+#define BA0_DMR0                                0x00000150L
+#define BA0_DCR0                                0x00000154L
+#define BA0_DMR1                                0x00000158L
+#define BA0_DCR1                                0x0000015CL
+#define BA0_DMR2                                0x00000160L
+#define BA0_DCR2                                0x00000164L
+#define BA0_DMR3                                0x00000168L
+#define BA0_DCR3                                0x0000016CL
+#define BA0_DLMR                                0x00000170L
+#define BA0_DLSR                                0x00000174L
+#define BA0_FCR0                                0x00000180L
+#define BA0_FCR1                                0x00000184L
+#define BA0_FCR2                                0x00000188L
+#define BA0_FCR3                                0x0000018CL
+#define BA0_FPDR0                               0x00000190L
+#define BA0_FPDR1                               0x00000194L
+#define BA0_FPDR2                               0x00000198L
+#define BA0_FPDR3                               0x0000019CL
+#define BA0_FCHS                                0x0000020CL
+#define BA0_FSIC0                               0x00000210L
+#define BA0_FSIC1                               0x00000214L
+#define BA0_FSIC2                               0x00000218L
+#define BA0_FSIC3                               0x0000021CL
+#define BA0_PCICFG00                            0x00000300L
+#define BA0_PCICFG04                            0x00000304L
+#define BA0_PCICFG08                            0x00000308L
+#define BA0_PCICFG0C                            0x0000030CL
+#define BA0_PCICFG10                            0x00000310L
+#define BA0_PCICFG14                            0x00000314L
+#define BA0_PCICFG18                            0x00000318L
+#define BA0_PCICFG1C                            0x0000031CL
+#define BA0_PCICFG20                            0x00000320L
+#define BA0_PCICFG24                            0x00000324L
+#define BA0_PCICFG28                            0x00000328L
+#define BA0_PCICFG2C                            0x0000032CL
+#define BA0_PCICFG30                            0x00000330L
+#define BA0_PCICFG34                            0x00000334L
+#define BA0_PCICFG38                            0x00000338L
+#define BA0_PCICFG3C                            0x0000033CL
+#define BA0_PCICFG40                            0x00000340L
+#define BA0_PMCS                                0x00000344L
+#define BA0_CWPR                                0x000003E0L
+#define BA0_EPPMC                               0x000003E4L
+#define BA0_GPIOR                               0x000003E8L
+#define BA0_SPMC                                0x000003ECL
+#define BA0_CFLR                                0x000003F0L
+#define BA0_IISR                                0x000003F4L
+#define BA0_TMS                                 0x000003F8L
+#define BA0_SSVID                               0x000003FCL
+#define BA0_CLKCR1                              0x00000400L
+#define BA0_FRR                                 0x00000410L
+#define BA0_SLT12O                              0x0000041CL
+#define BA0_SERMC                               0x00000420L
+#define BA0_SERC1                               0x00000428L
+#define BA0_SERC2                               0x0000042CL
+#define BA0_SLT12M                              0x0000045CL
+#define BA0_ACCTL                               0x00000460L
+#define BA0_ACSTS                               0x00000464L
+#define BA0_ACOSV                               0x00000468L
+#define BA0_ACCAD                               0x0000046CL
+#define BA0_ACCDA                               0x00000470L
+#define BA0_ACISV                               0x00000474L
+#define BA0_ACSAD                               0x00000478L
+#define BA0_ACSDA                               0x0000047CL
+#define BA0_JSPT                                0x00000480L
+#define BA0_JSCTL                               0x00000484L
+#define BA0_MIDCR                               0x00000490L
+#define BA0_MIDCMD                              0x00000494L
+#define BA0_MIDSR                               0x00000494L
+#define BA0_MIDWP                               0x00000498L
+#define BA0_MIDRP                               0x0000049CL
+#define BA0_AODSD1                              0x000004A8L
+#define BA0_AODSD2                              0x000004ACL
+#define BA0_CFGI                                0x000004B0L
+#define BA0_SLT12M2                             0x000004DCL
+#define BA0_ACSTS2                              0x000004E4L
+#define BA0_ACISV2                              0x000004F4L
+#define BA0_ACSAD2                              0x000004F8L
+#define BA0_ACSDA2                              0x000004FCL
+#define BA0_IOTGP                               0x00000500L
+#define BA0_IOTSB                               0x00000504L
+#define BA0_IOTFM                               0x00000508L
+#define BA0_IOTDMA                              0x0000050CL
+#define BA0_IOTAC0                              0x00000500L
+#define BA0_IOTAC1                              0x00000504L
+#define BA0_IOTAC2                              0x00000508L
+#define BA0_IOTAC3                              0x0000050CL
+#define BA0_IOTPCP                              0x0000052CL
+#define BA0_IOTCC                               0x00000530L
+#define BA0_IOTCR                               0x0000058CL
+#define BA0_PCPRR                               0x00000600L
+#define BA0_PCPGR                               0x00000604L
+#define BA0_PCPCR                               0x00000608L
+#define BA0_PCPCIEN                             0x00000608L
+#define BA0_SBMAR                               0x00000700L
+#define BA0_SBMDR                               0x00000704L
+#define BA0_SBRR                                0x00000708L
+#define BA0_SBRDP                               0x0000070CL
+#define BA0_SBWDP                               0x00000710L
+#define BA0_SBWBS                               0x00000710L
+#define BA0_SBRBS                               0x00000714L
+#define BA0_FMSR                                0x00000730L
+#define BA0_B0AP                                0x00000730L
+#define BA0_FMDP                                0x00000734L
+#define BA0_B1AP                                0x00000738L
+#define BA0_B1DP                                0x0000073CL
+#define BA0_SSPM                                0x00000740L
+#define BA0_DACSR                               0x00000744L
+#define BA0_ADCSR                               0x00000748L
+#define BA0_SSCR                                0x0000074CL
+#define BA0_FMLVC                               0x00000754L
+#define BA0_FMRVC                               0x00000758L
+#define BA0_SRCSA                               0x0000075CL
+#define BA0_PPLVC                               0x00000760L
+#define BA0_PPRVC                               0x00000764L
+#define BA0_PASR                                0x00000768L
+#define BA0_CASR                                0x0000076CL
+
+//****************************************************************************
+//
+// The following define the offsets of the AC97 shadow registers, which appear
+// as a virtual extension to the base address register zero memory range.
+//
+//****************************************************************************
+#define AC97_REG_OFFSET_MASK                    0x0000007EL
+#define AC97_CODEC_NUMBER_MASK                  0x00003000L
+
+#define BA0_AC97_RESET                          0x00001000L
+#define BA0_AC97_MASTER_VOLUME                  0x00001002L
+#define BA0_AC97_HEADPHONE_VOLUME               0x00001004L
+#define BA0_AC97_MASTER_VOLUME_MONO             0x00001006L
+#define BA0_AC97_MASTER_TONE                    0x00001008L
+#define BA0_AC97_PC_BEEP_VOLUME                 0x0000100AL
+#define BA0_AC97_PHONE_VOLUME                   0x0000100CL
+#define BA0_AC97_MIC_VOLUME                     0x0000100EL
+#define BA0_AC97_LINE_IN_VOLUME                 0x00001010L
+#define BA0_AC97_CD_VOLUME                      0x00001012L
+#define BA0_AC97_VIDEO_VOLUME                   0x00001014L
+#define BA0_AC97_AUX_VOLUME                     0x00001016L
+#define BA0_AC97_PCM_OUT_VOLUME                 0x00001018L
+#define BA0_AC97_RECORD_SELECT                  0x0000101AL
+#define BA0_AC97_RECORD_GAIN                    0x0000101CL
+#define BA0_AC97_RECORD_GAIN_MIC                0x0000101EL
+#define BA0_AC97_GENERAL_PURPOSE                0x00001020L
+#define BA0_AC97_3D_CONTROL                     0x00001022L
+#define BA0_AC97_MODEM_RATE                     0x00001024L
+#define BA0_AC97_POWERDOWN                      0x00001026L
+#define BA0_AC97_EXT_AUDIO_ID                   0x00001028L
+#define BA0_AC97_EXT_AUDIO_POWER                0x0000102AL
+#define BA0_AC97_PCM_FRONT_DAC_RATE             0x0000102CL
+#define BA0_AC97_PCM_SURR_DAC_RATE              0x0000102EL
+#define BA0_AC97_PCM_LFE_DAC_RATE               0x00001030L
+#define BA0_AC97_PCM_LR_ADC_RATE                0x00001032L
+#define BA0_AC97_MIC_ADC_RATE                   0x00001034L
+#define BA0_AC97_6CH_VOL_C_LFE                  0x00001036L
+#define BA0_AC97_6CH_VOL_SURROUND               0x00001038L
+#define BA0_AC97_RESERVED_3A                    0x0000103AL
+#define BA0_AC97_EXT_MODEM_ID                   0x0000103CL
+#define BA0_AC97_EXT_MODEM_POWER                0x0000103EL
+#define BA0_AC97_LINE1_CODEC_RATE               0x00001040L
+#define BA0_AC97_LINE2_CODEC_RATE               0x00001042L
+#define BA0_AC97_HANDSET_CODEC_RATE             0x00001044L
+#define BA0_AC97_LINE1_CODEC_LEVEL              0x00001046L
+#define BA0_AC97_LINE2_CODEC_LEVEL              0x00001048L
+#define BA0_AC97_HANDSET_CODEC_LEVEL            0x0000104AL
+#define BA0_AC97_GPIO_PIN_CONFIG                0x0000104CL
+#define BA0_AC97_GPIO_PIN_TYPE                  0x0000104EL
+#define BA0_AC97_GPIO_PIN_STICKY                0x00001050L
+#define BA0_AC97_GPIO_PIN_WAKEUP                0x00001052L
+#define BA0_AC97_GPIO_PIN_STATUS                0x00001054L
+#define BA0_AC97_MISC_MODEM_AFE_STAT            0x00001056L
+#define BA0_AC97_RESERVED_58                    0x00001058L
+#define BA0_AC97_CRYSTAL_REV_N_FAB_ID           0x0000105AL
+#define BA0_AC97_TEST_AND_MISC_CTRL             0x0000105CL
+#define BA0_AC97_AC_MODE                        0x0000105EL
+#define BA0_AC97_MISC_CRYSTAL_CONTROL           0x00001060L
+#define BA0_AC97_LINE1_HYPRID_CTRL              0x00001062L
+#define BA0_AC97_VENDOR_RESERVED_64             0x00001064L
+#define BA0_AC97_VENDOR_RESERVED_66             0x00001066L
+#define BA0_AC97_SPDIF_CONTROL                  0x00001068L
+#define BA0_AC97_VENDOR_RESERVED_6A             0x0000106AL
+#define BA0_AC97_VENDOR_RESERVED_6C             0x0000106CL
+#define BA0_AC97_VENDOR_RESERVED_6E             0x0000106EL
+#define BA0_AC97_VENDOR_RESERVED_70             0x00001070L
+#define BA0_AC97_VENDOR_RESERVED_72             0x00001072L
+#define BA0_AC97_VENDOR_RESERVED_74             0x00001074L
+#define BA0_AC97_CAL_ADDRESS                    0x00001076L
+#define BA0_AC97_CAL_DATA                       0x00001078L
+#define BA0_AC97_VENDOR_RESERVED_7A             0x0000107AL
+#define BA0_AC97_VENDOR_ID1                     0x0000107CL
+#define BA0_AC97_VENDOR_ID2                     0x0000107EL
+
+//****************************************************************************
+//
+// The following define the offsets of the registers and memories accessed via
+// base address register one on the CS4281 part.
+//
+//****************************************************************************
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PCI device ID/vendor ID
+// register.
+//
+//****************************************************************************
+#define PDV_VENID_MASK                          0x0000FFFFL
+#define PDV_DEVID_MASK                          0xFFFF0000L
+#define PDV_VENID_SHIFT                         0L
+#define PDV_DEVID_SHIFT                         16L
+#define VENID_CIRRUS_LOGIC                      0x1013L
+#define DEVID_CS4281                            0x6005L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PCI status and command
+// register.
+//
+//****************************************************************************
+#define PSC_IO_SPACE_ENABLE                     0x00000001L
+#define PSC_MEMORY_SPACE_ENABLE                 0x00000002L
+#define PSC_BUS_MASTER_ENABLE                   0x00000004L
+#define PSC_SPECIAL_CYCLES                      0x00000008L
+#define PSC_MWI_ENABLE                          0x00000010L
+#define PSC_VGA_PALETTE_SNOOP                   0x00000020L
+#define PSC_PARITY_RESPONSE                     0x00000040L
+#define PSC_WAIT_CONTROL                        0x00000080L
+#define PSC_SERR_ENABLE                         0x00000100L
+#define PSC_FAST_B2B_ENABLE                     0x00000200L
+#define PSC_UDF_MASK                            0x007F0000L
+#define PSC_FAST_B2B_CAPABLE                    0x00800000L
+#define PSC_PARITY_ERROR_DETECTED               0x01000000L
+#define PSC_DEVSEL_TIMING_MASK                  0x06000000L
+#define PSC_TARGET_ABORT_SIGNALLED              0x08000000L
+#define PSC_RECEIVED_TARGET_ABORT               0x10000000L
+#define PSC_RECEIVED_MASTER_ABORT               0x20000000L
+#define PSC_SIGNALLED_SERR                      0x40000000L
+#define PSC_DETECTED_PARITY_ERROR               0x80000000L
+#define PSC_UDF_SHIFT                           16L
+#define PSC_DEVSEL_TIMING_SHIFT                 25L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PCI class/revision ID
+// register.
+//
+//****************************************************************************
+#define PCR_REVID_MASK                          0x000000FFL
+#define PCR_INTERFACE_MASK                      0x0000FF00L
+#define PCR_SUBCLASS_MASK                       0x00FF0000L
+#define PCR_CLASS_MASK                          0xFF000000L
+#define PCR_REVID_SHIFT                         0L
+#define PCR_INTERFACE_SHIFT                     8L
+#define PCR_SUBCLASS_SHIFT                      16L
+#define PCR_CLASS_SHIFT                         24L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PCI latency timer register.
+//
+//****************************************************************************
+#define PLT_CACHE_LINE_SIZE_MASK                0x000000FFL
+#define PLT_LATENCY_TIMER_MASK                  0x0000FF00L
+#define PLT_HEADER_TYPE_MASK                    0x00FF0000L
+#define PLT_BIST_MASK                           0xFF000000L
+#define PLT_CACHE_LINE_SIZE_SHIFT               0L
+#define PLT_LATENCY_TIMER_SHIFT                 8L
+#define PLT_HEADER_TYPE_SHIFT                   16L
+#define PLT_BIST_SHIFT                          24L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PCI base address registers.
+//
+//****************************************************************************
+#define PBAR_MEMORY_SPACE_INDICATOR             0x00000001L
+#define PBAR_LOCATION_TYPE_MASK                 0x00000006L
+#define PBAR_NOT_PREFETCHABLE                   0x00000008L
+#define PBAR_ADDRESS_MASK                       0xFFFFFFF0L
+#define PBAR_LOCATION_TYPE_SHIFT                1L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PCI subsystem ID/subsystem
+// vendor ID register.
+//
+//****************************************************************************
+#define PSS_SUBSYSTEM_VENDOR_ID_MASK            0x0000FFFFL
+#define PSS_SUBSYSTEM_ID_MASK                   0xFFFF0000L
+#define PSS_SUBSYSTEM_VENDOR_ID_SHIFT           0L
+#define PSS_SUBSYSTEM_ID_SHIFT                  16L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PCI interrupt register.
+//
+//****************************************************************************
+#define PI_LINE_MASK                            0x000000FFL
+#define PI_PIN_MASK                             0x0000FF00L
+#define PI_MIN_GRANT_MASK                       0x00FF0000L
+#define PI_MAX_LATENCY_MASK                     0xFF000000L
+#define PI_LINE_SHIFT                           0L
+#define PI_PIN_SHIFT                            8L
+#define PI_MIN_GRANT_SHIFT                      16L
+#define PI_MAX_LATENCY_SHIFT                    24L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the host interrupt status
+// register.
+//
+//****************************************************************************
+#define HISR_HVOLMASK                            0x00000003L
+#define HISR_VDNI                                0x00000001L
+#define HISR_VUPI                                0x00000002L
+#define HISR_GP1I                                0x00000004L
+#define HISR_GP3I                                0x00000008L
+#define HISR_GPSI                                0x00000010L
+#define HISR_GPPI                                0x00000020L
+#define HISR_DMAI                                0x00040000L
+#define HISR_FIFOI                               0x00100000L
+#define HISR_HVOL                                0x00200000L
+#define HISR_MIDI                                0x00400000L
+#define HISR_SBINT                               0x00800000L
+#define HISR_INTENA                              0x80000000L
+#define HISR_DMA_MASK                            0x00000F00L
+#define HISR_FIFO_MASK                           0x0000F000L
+#define HISR_DMA_SHIFT                           8L
+#define HISR_FIFO_SHIFT                          12L
+#define HISR_FIFO0                               0x00001000L
+#define HISR_FIFO1                               0x00002000L
+#define HISR_FIFO2                               0x00004000L
+#define HISR_FIFO3                               0x00008000L
+#define HISR_DMA0                                0x00000100L
+#define HISR_DMA1                                0x00000200L
+#define HISR_DMA2                                0x00000400L
+#define HISR_DMA3                                0x00000800L
+#define HISR_RESERVED                            0x40000000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the host interrupt control
+// register.
+//
+//****************************************************************************
+#define HICR_IEV                                 0x00000001L
+#define HICR_CHGM                                0x00000002L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the DMA Mode Register n
+// (DMRn)
+//
+//****************************************************************************
+#define DMRn_TR_MASK                             0x0000000CL
+#define DMRn_TR_SHIFT                            2L
+#define DMRn_AUTO                                0x00000010L
+#define DMRn_TR_READ                             0x00000008L
+#define DMRn_TR_WRITE                            0x00000004L
+#define DMRn_TYPE_MASK                           0x000000C0L
+#define DMRn_TYPE_SHIFT                          6L
+#define DMRn_SIZE8                               0x00010000L
+#define DMRn_MONO                                0x00020000L
+#define DMRn_BEND                                0x00040000L
+#define DMRn_USIGN                               0x00080000L
+#define DMRn_SIZE20                              0x00100000L
+#define DMRn_SWAPC                               0x00400000L
+#define DMRn_CBC                                 0x01000000L
+#define DMRn_TBC                                 0x02000000L
+#define DMRn_POLL                                0x10000000L
+#define DMRn_DMA                                 0x20000000L
+#define DMRn_FSEL_MASK                           0xC0000000L
+#define DMRn_FSEL_SHIFT                          30L
+#define DMRn_FSEL0                               0x00000000L
+#define DMRn_FSEL1                               0x40000000L
+#define DMRn_FSEL2                               0x80000000L
+#define DMRn_FSEL3                               0xC0000000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the DMA Command Register n
+// (DCRn)
+//
+//****************************************************************************
+#define DCRn_HTCIE                               0x00020000L
+#define DCRn_TCIE                                0x00010000L
+#define DCRn_MSK                                 0x00000001L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the FIFO Control 
+// register n.(FCRn)
+//
+//****************************************************************************
+#define FCRn_OF_MASK                            0x0000007FL
+#define FCRn_OF_SHIFT                           0L
+#define FCRn_SZ_MASK                            0x00007F00L
+#define FCRn_SZ_SHIFT                           8L
+#define FCRn_LS_MASK                            0x001F0000L
+#define FCRn_LS_SHIFT                           16L
+#define FCRn_RS_MASK                            0x1F000000L
+#define FCRn_RS_SHIFT                           24L
+#define FCRn_FEN                                0x80000000L
+#define FCRn_PSH                                0x20000000L
+#define FCRn_DACZ                               0x40000000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the serial port Power Management
+// control register.(SPMC)
+//
+//****************************************************************************
+#define SPMC_RSTN                               0x00000001L
+#define SPMC_ASYN                               0x00000002L
+#define SPMC_WUP1                               0x00000004L
+#define SPMC_WUP2                               0x00000008L
+#define SPMC_ASDI2E                             0x00000100L
+#define SPMC_ESSPD                              0x00000200L
+#define SPMC_GISPEN                             0x00004000L
+#define SPMC_GIPPEN                             0x00008000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the Configuration Load register.
+// (CFLR)
+//
+//****************************************************************************
+#define CFLR_CLOCK_SOURCE_MASK                  0x00000003L
+#define CFLR_CLOCK_SOURCE_AC97                  0x00000001L
+
+#define CFLR_CB0_MASK                            0x000000FFL
+#define CFLR_CB1_MASK                            0x0000FF00L
+#define CFLR_CB2_MASK                            0x00FF0000L
+#define CFLR_CB3_MASK                            0xFF000000L
+#define CFLR_CB0_SHIFT                           0L
+#define CFLR_CB1_SHIFT                           8L
+#define CFLR_CB2_SHIFT                           16L
+#define CFLR_CB3_SHIFT                           24L
+
+#define IOTCR_DMA0                              0x00000000L
+#define IOTCR_DMA1                              0x00000400L
+#define IOTCR_DMA2                              0x00000800L
+#define IOTCR_DMA3                              0x00000C00L
+#define IOTCR_CCLS                              0x00000100L
+#define IOTCR_PCPCI                             0x00000200L
+#define IOTCR_DDMA                              0x00000300L
+
+#define SBWBS_WBB                               0x00000080L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the SRC Slot Assignment Register
+// (SRCSA)
+//
+//****************************************************************************
+#define SRCSA_PLSS_MASK                         0x0000001FL
+#define SRCSA_PLSS_SHIFT                        0L
+#define SRCSA_PRSS_MASK                         0x00001F00L
+#define SRCSA_PRSS_SHIFT                        8L
+#define SRCSA_CLSS_MASK                         0x001F0000L
+#define SRCSA_CLSS_SHIFT                        16L
+#define SRCSA_CRSS_MASK                         0x1F000000L
+#define SRCSA_CRSS_SHIFT                        24L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the Sound System Power Management
+// register.(SSPM)
+//
+//****************************************************************************
+#define SSPM_FPDN                               0x00000080L
+#define SSPM_MIXEN                              0x00000040L
+#define SSPM_CSRCEN                             0x00000020L
+#define SSPM_PSRCEN                             0x00000010L
+#define SSPM_JSEN                               0x00000008L
+#define SSPM_ACLEN                              0x00000004L
+#define SSPM_FMEN                               0x00000002L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the Sound System Control
+// Register. (SSCR)
+//
+//****************************************************************************
+#define SSCR_SB                                 0x00000004L
+#define SSCR_HVC                                0x00000008L
+#define SSCR_LPFIFO                             0x00000040L
+#define SSCR_LPSRC                              0x00000080L
+#define SSCR_XLPSRC                             0x00000100L
+#define SSCR_MVMD                               0x00010000L
+#define SSCR_MVAD                               0x00020000L
+#define SSCR_MVLD                               0x00040000L
+#define SSCR_MVCS                               0x00080000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the Clock Control Register 1. 
+// (CLKCR1)
+//
+//****************************************************************************
+#define CLKCR1_DLLSS_MASK                       0x0000000CL
+#define CLKCR1_DLLSS_SHIFT                      2L
+#define CLKCR1_DLLP                             0x00000010L
+#define CLKCR1_SWCE                             0x00000020L
+#define CLKCR1_DLLOS                            0x00000040L
+#define CLKCR1_CKRA                             0x00010000L
+#define CLKCR1_CKRN                             0x00020000L
+#define CLKCR1_DLLRDY                           0x01000000L
+#define CLKCR1_CLKON                            0x02000000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the Sound Blaster Read Buffer
+// Status.(SBRBS)
+//
+//****************************************************************************
+#define SBRBS_RD_MASK                           0x0000007FL
+#define SBRBS_RD_SHIFT                          0L
+#define SBRBS_RBF                               0x00000080L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the serial port master control
+// register.(SERMC)
+//
+//****************************************************************************
+#define SERMC_MSPE                              0x00000001L
+#define SERMC_PTC_MASK                          0x0000000EL
+#define SERMC_PTC_SHIFT                         1L
+#define SERMC_PTC_AC97                          0x00000002L
+#define SERMC_PLB                               0x00000010L
+#define SERMC_PXLB                              0x00000020L
+#define SERMC_LOFV                              0x00080000L
+#define SERMC_SLB                               0x00100000L
+#define SERMC_SXLB                              0x00200000L
+#define SERMC_ODSEN1                            0x01000000L
+#define SERMC_ODSEN2                            0x02000000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the General Purpose I/O Register. 
+// (GPIOR)
+//
+//****************************************************************************
+#define GPIOR_VDNS                              0x00000001L
+#define GPIOR_VUPS                              0x00000002L
+#define GPIOR_GP1S                              0x00000004L
+#define GPIOR_GP3S                              0x00000008L
+#define GPIOR_GPSS                              0x00000010L
+#define GPIOR_GPPS                              0x00000020L
+#define GPIOR_GP1D                              0x00000400L
+#define GPIOR_GP3D                              0x00000800L
+#define GPIOR_VDNLT                             0x00010000L
+#define GPIOR_VDNPO                             0x00020000L
+#define GPIOR_VDNST                             0x00040000L
+#define GPIOR_VDNW                              0x00080000L
+#define GPIOR_VUPLT                             0x00100000L
+#define GPIOR_VUPPO                             0x00200000L
+#define GPIOR_VUPST                             0x00400000L
+#define GPIOR_VUPW                              0x00800000L
+#define GPIOR_GP1OE                             0x01000000L
+#define GPIOR_GP1PT                             0x02000000L
+#define GPIOR_GP1ST                             0x04000000L
+#define GPIOR_GP1W                              0x08000000L
+#define GPIOR_GP3OE                             0x10000000L
+#define GPIOR_GP3PT                             0x20000000L
+#define GPIOR_GP3ST                             0x40000000L
+#define GPIOR_GP3W                              0x80000000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the clock control register 1.
+//
+//****************************************************************************
+#define CLKCR1_PLLSS_MASK                       0x0000000CL
+#define CLKCR1_PLLSS_SERIAL                     0x00000000L
+#define CLKCR1_PLLSS_CRYSTAL                    0x00000004L
+#define CLKCR1_PLLSS_PCI                        0x00000008L
+#define CLKCR1_PLLSS_RESERVED                   0x0000000CL
+#define CLKCR1_PLLP                             0x00000010L
+#define CLKCR1_SWCE                             0x00000020L
+#define CLKCR1_PLLOS                            0x00000040L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the feature reporting register.
+//
+//****************************************************************************
+#define FRR_FAB_MASK                            0x00000003L
+#define FRR_MASK_MASK                           0x0000001CL
+#define FRR_ID_MASK                             0x00003000L
+#define FRR_FAB_SHIFT                           0L
+#define FRR_MASK_SHIFT                          2L
+#define FRR_ID_SHIFT                            12L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the serial port 1 configuration
+// register.
+//
+//****************************************************************************
+#define SERC1_VALUE                             0x00000003L
+#define SERC1_SO1EN                             0x00000001L
+#define SERC1_SO1F_MASK                         0x0000000EL
+#define SERC1_SO1F_CS423X                       0x00000000L
+#define SERC1_SO1F_AC97                         0x00000002L
+#define SERC1_SO1F_DAC                          0x00000004L
+#define SERC1_SO1F_SPDIF                        0x00000006L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the serial port 2 configuration
+// register.
+//
+//****************************************************************************
+#define SERC2_VALUE                             0x00000003L
+#define SERC2_SI1EN                             0x00000001L
+#define SERC2_SI1F_MASK                         0x0000000EL
+#define SERC2_SI1F_CS423X                       0x00000000L
+#define SERC2_SI1F_AC97                         0x00000002L
+#define SERC2_SI1F_ADC                          0x00000004L
+#define SERC2_SI1F_SPDIF                        0x00000006L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 control register.
+//
+//****************************************************************************
+#define ACCTL_ESYN                              0x00000002L
+#define ACCTL_VFRM                              0x00000004L
+#define ACCTL_DCV                               0x00000008L
+#define ACCTL_CRW                               0x00000010L
+#define ACCTL_TC                                0x00000040L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 status register.
+//
+//****************************************************************************
+#define ACSTS_CRDY                              0x00000001L
+#define ACSTS_VSTS                              0x00000002L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 output slot valid
+// register.
+//
+//****************************************************************************
+#define ACOSV_SLV3                              0x00000001L
+#define ACOSV_SLV4                              0x00000002L
+#define ACOSV_SLV5                              0x00000004L
+#define ACOSV_SLV6                              0x00000008L
+#define ACOSV_SLV7                              0x00000010L
+#define ACOSV_SLV8                              0x00000020L
+#define ACOSV_SLV9                              0x00000040L
+#define ACOSV_SLV10                             0x00000080L
+#define ACOSV_SLV11                             0x00000100L
+#define ACOSV_SLV12                             0x00000200L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 command address
+// register.
+//
+//****************************************************************************
+#define ACCAD_CI_MASK                           0x0000007FL
+#define ACCAD_CI_SHIFT                          0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 command data register.
+//
+//****************************************************************************
+#define ACCDA_CD_MASK                           0x0000FFFFL
+#define ACCDA_CD_SHIFT                          0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 input slot valid
+// register.
+//
+//****************************************************************************
+#define ACISV_ISV3                              0x00000001L
+#define ACISV_ISV4                              0x00000002L
+#define ACISV_ISV5                              0x00000004L
+#define ACISV_ISV6                              0x00000008L
+#define ACISV_ISV7                              0x00000010L
+#define ACISV_ISV8                              0x00000020L
+#define ACISV_ISV9                              0x00000040L
+#define ACISV_ISV10                             0x00000080L
+#define ACISV_ISV11                             0x00000100L
+#define ACISV_ISV12                             0x00000200L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 status address
+// register.
+//
+//****************************************************************************
+#define ACSAD_SI_MASK                           0x0000007FL
+#define ACSAD_SI_SHIFT                          0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 status data register.
+//
+//****************************************************************************
+#define ACSDA_SD_MASK                           0x0000FFFFL
+#define ACSDA_SD_SHIFT                          0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the I/O trap address and control
+// registers (all 12).
+//
+//****************************************************************************
+#define IOTAC_SA_MASK                           0x0000FFFFL
+#define IOTAC_MSK_MASK                          0x000F0000L
+#define IOTAC_IODC_MASK                         0x06000000L
+#define IOTAC_IODC_16_BIT                       0x00000000L
+#define IOTAC_IODC_10_BIT                       0x02000000L
+#define IOTAC_IODC_12_BIT                       0x04000000L
+#define IOTAC_WSPI                              0x08000000L
+#define IOTAC_RSPI                              0x10000000L
+#define IOTAC_WSE                               0x20000000L
+#define IOTAC_WE                                0x40000000L
+#define IOTAC_RE                                0x80000000L
+#define IOTAC_SA_SHIFT                          0L
+#define IOTAC_MSK_SHIFT                         16L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PC/PCI master enable
+// register.
+//
+//****************************************************************************
+#define PCPCIEN_EN                              0x00000001L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the joystick poll/trigger
+// register.
+//
+//****************************************************************************
+#define JSPT_CAX                                0x00000001L
+#define JSPT_CAY                                0x00000002L
+#define JSPT_CBX                                0x00000004L
+#define JSPT_CBY                                0x00000008L
+#define JSPT_BA1                                0x00000010L
+#define JSPT_BA2                                0x00000020L
+#define JSPT_BB1                                0x00000040L
+#define JSPT_BB2                                0x00000080L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the joystick control register.
+// The TBF bit has been moved from MIDSR register to JSCTL register bit 8.
+//
+//****************************************************************************
+#define JSCTL_SP_MASK                           0x00000003L
+#define JSCTL_SP_SLOW                           0x00000000L
+#define JSCTL_SP_MEDIUM_SLOW                    0x00000001L
+#define JSCTL_SP_MEDIUM_FAST                    0x00000002L
+#define JSCTL_SP_FAST                           0x00000003L
+#define JSCTL_ARE                               0x00000004L
+#define JSCTL_TBF                               0x00000100L
+
+
+//****************************************************************************
+//
+// The following defines are for the flags in the MIDI control register.
+//
+//****************************************************************************
+#define MIDCR_TXE                               0x00000001L
+#define MIDCR_RXE                               0x00000002L
+#define MIDCR_RIE                               0x00000004L
+#define MIDCR_TIE                               0x00000008L
+#define MIDCR_MLB                               0x00000010L
+#define MIDCR_MRST                              0x00000020L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the MIDI status register.
+//
+//****************************************************************************
+#define MIDSR_RBE                               0x00000080L
+#define MIDSR_RDA                               0x00008000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the MIDI write port register.
+//
+//****************************************************************************
+#define MIDWP_MWD_MASK                          0x000000FFL
+#define MIDWP_MWD_SHIFT                         0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the MIDI read port register.
+//
+//****************************************************************************
+#define MIDRP_MRD_MASK                          0x000000FFL
+#define MIDRP_MRD_SHIFT                         0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the configuration interface
+// register.
+//
+//****************************************************************************
+#define CFGI_CLK                                0x00000001L
+#define CFGI_DOUT                               0x00000002L
+#define CFGI_DIN_EEN                            0x00000004L
+#define CFGI_EELD                               0x00000008L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the subsystem ID and vendor ID
+// register.
+//
+//****************************************************************************
+#define SSVID_VID_MASK                          0x0000FFFFL
+#define SSVID_SID_MASK                          0xFFFF0000L
+#define SSVID_VID_SHIFT                         0L
+#define SSVID_SID_SHIFT                         16L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the GPIO pin interface register.
+//
+//****************************************************************************
+#define GPIOR_VOLDN                             0x00000001L
+#define GPIOR_VOLUP                             0x00000002L
+#define GPIOR_SI2D                              0x00000004L
+#define GPIOR_SI2OE                             0x00000008L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 status register 2.
+//
+//****************************************************************************
+#define ACSTS2_CRDY                             0x00000001L
+#define ACSTS2_VSTS                             0x00000002L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 input slot valid
+// register 2.
+//
+//****************************************************************************
+#define ACISV2_ISV3                             0x00000001L
+#define ACISV2_ISV4                             0x00000002L
+#define ACISV2_ISV5                             0x00000004L
+#define ACISV2_ISV6                             0x00000008L
+#define ACISV2_ISV7                             0x00000010L
+#define ACISV2_ISV8                             0x00000020L
+#define ACISV2_ISV9                             0x00000040L
+#define ACISV2_ISV10                            0x00000080L
+#define ACISV2_ISV11                            0x00000100L
+#define ACISV2_ISV12                            0x00000200L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 status address
+// register 2.
+//
+//****************************************************************************
+#define ACSAD2_SI_MASK                          0x0000007FL
+#define ACSAD2_SI_SHIFT                         0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 status data register 2.
+//
+//****************************************************************************
+#define ACSDA2_SD_MASK                          0x0000FFFFL
+#define ACSDA2_SD_SHIFT                         0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the I/O trap control register.
+//
+//****************************************************************************
+#define IOTCR_ITD                               0x00000001L
+#define IOTCR_HRV                               0x00000002L
+#define IOTCR_SRV                               0x00000004L
+#define IOTCR_DTI                               0x00000008L
+#define IOTCR_DFI                               0x00000010L
+#define IOTCR_DDP                               0x00000020L
+#define IOTCR_JTE                               0x00000040L
+#define IOTCR_PPE                               0x00000080L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the I/O trap address and control
+// registers for Hardware Master Volume.  
+//
+//****************************************************************************
+#define IOTGP_SA_MASK                           0x0000FFFFL
+#define IOTGP_MSK_MASK                          0x000F0000L
+#define IOTGP_IODC_MASK                         0x06000000L
+#define IOTGP_IODC_16_BIT                       0x00000000L
+#define IOTGP_IODC_10_BIT                       0x02000000L
+#define IOTGP_IODC_12_BIT                       0x04000000L
+#define IOTGP_WSPI                              0x08000000L
+#define IOTGP_RSPI                              0x10000000L
+#define IOTGP_WSE                               0x20000000L
+#define IOTGP_WE                                0x40000000L
+#define IOTGP_RE                                0x80000000L
+#define IOTGP_SA_SHIFT                          0L
+#define IOTGP_MSK_SHIFT                         16L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the I/O trap address and control
+// registers for Sound Blaster
+//
+//****************************************************************************
+#define IOTSB_SA_MASK                           0x0000FFFFL
+#define IOTSB_MSK_MASK                          0x000F0000L
+#define IOTSB_IODC_MASK                         0x06000000L
+#define IOTSB_IODC_16_BIT                       0x00000000L
+#define IOTSB_IODC_10_BIT                       0x02000000L
+#define IOTSB_IODC_12_BIT                       0x04000000L
+#define IOTSB_WSPI                              0x08000000L
+#define IOTSB_RSPI                              0x10000000L
+#define IOTSB_WSE                               0x20000000L
+#define IOTSB_WE                                0x40000000L
+#define IOTSB_RE                                0x80000000L
+#define IOTSB_SA_SHIFT                          0L
+#define IOTSB_MSK_SHIFT                         16L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the I/O trap address and control
+// registers for FM.
+//
+//****************************************************************************
+#define IOTFM_SA_MASK                           0x0000FFFFL
+#define IOTFM_MSK_MASK                          0x000F0000L
+#define IOTFM_IODC_MASK                         0x06000000L
+#define IOTFM_IODC_16_BIT                       0x00000000L
+#define IOTFM_IODC_10_BIT                       0x02000000L
+#define IOTFM_IODC_12_BIT                       0x04000000L
+#define IOTFM_WSPI                              0x08000000L
+#define IOTFM_RSPI                              0x10000000L
+#define IOTFM_WSE                               0x20000000L
+#define IOTFM_WE                                0x40000000L
+#define IOTFM_RE                                0x80000000L
+#define IOTFM_SA_SHIFT                          0L
+#define IOTFM_MSK_SHIFT                         16L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PC/PCI request register.
+//
+//****************************************************************************
+#define PCPRR_RDC_MASK                         0x00000007L
+#define PCPRR_REQ                              0x00008000L
+#define PCPRR_RDC_SHIFT                        0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PC/PCI grant register.
+//
+//****************************************************************************
+#define PCPGR_GDC_MASK                         0x00000007L
+#define PCPGR_VL                               0x00008000L
+#define PCPGR_GDC_SHIFT                        0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PC/PCI Control Register.
+//
+//****************************************************************************
+#define PCPCR_EN                               0x00000001L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the debug index register.
+//
+//****************************************************************************
+#define DREG_REGID_MASK                         0x0000007FL
+#define DREG_DEBUG                              0x00000080L
+#define DREG_RGBK_MASK                          0x00000700L
+#define DREG_TRAP                               0x00000800L
+#if !defined(NO_CS4612)
+#if !defined(NO_CS4615)
+#define DREG_TRAPX                              0x00001000L
+#endif
+#endif
+#define DREG_REGID_SHIFT                        0L
+#define DREG_RGBK_SHIFT                         8L
+#define DREG_RGBK_REGID_MASK                    0x0000077FL
+#define DREG_REGID_R0                           0x00000010L
+#define DREG_REGID_R1                           0x00000011L
+#define DREG_REGID_R2                           0x00000012L
+#define DREG_REGID_R3                           0x00000013L
+#define DREG_REGID_R4                           0x00000014L
+#define DREG_REGID_R5                           0x00000015L
+#define DREG_REGID_R6                           0x00000016L
+#define DREG_REGID_R7                           0x00000017L
+#define DREG_REGID_R8                           0x00000018L
+#define DREG_REGID_R9                           0x00000019L
+#define DREG_REGID_RA                           0x0000001AL
+#define DREG_REGID_RB                           0x0000001BL
+#define DREG_REGID_RC                           0x0000001CL
+#define DREG_REGID_RD                           0x0000001DL
+#define DREG_REGID_RE                           0x0000001EL
+#define DREG_REGID_RF                           0x0000001FL
+#define DREG_REGID_RA_BUS_LOW                   0x00000020L
+#define DREG_REGID_RA_BUS_HIGH                  0x00000038L
+#define DREG_REGID_YBUS_LOW                     0x00000050L
+#define DREG_REGID_YBUS_HIGH                    0x00000058L
+#define DREG_REGID_TRAP_0                       0x00000100L
+#define DREG_REGID_TRAP_1                       0x00000101L
+#define DREG_REGID_TRAP_2                       0x00000102L
+#define DREG_REGID_TRAP_3                       0x00000103L
+#define DREG_REGID_TRAP_4                       0x00000104L
+#define DREG_REGID_TRAP_5                       0x00000105L
+#define DREG_REGID_TRAP_6                       0x00000106L
+#define DREG_REGID_TRAP_7                       0x00000107L
+#define DREG_REGID_INDIRECT_ADDRESS             0x0000010EL
+#define DREG_REGID_TOP_OF_STACK                 0x0000010FL
+#if !defined(NO_CS4612)
+#if !defined(NO_CS4615)
+#define DREG_REGID_TRAP_8                       0x00000110L
+#define DREG_REGID_TRAP_9                       0x00000111L
+#define DREG_REGID_TRAP_10                      0x00000112L
+#define DREG_REGID_TRAP_11                      0x00000113L
+#define DREG_REGID_TRAP_12                      0x00000114L
+#define DREG_REGID_TRAP_13                      0x00000115L
+#define DREG_REGID_TRAP_14                      0x00000116L
+#define DREG_REGID_TRAP_15                      0x00000117L
+#define DREG_REGID_TRAP_16                      0x00000118L
+#define DREG_REGID_TRAP_17                      0x00000119L
+#define DREG_REGID_TRAP_18                      0x0000011AL
+#define DREG_REGID_TRAP_19                      0x0000011BL
+#define DREG_REGID_TRAP_20                      0x0000011CL
+#define DREG_REGID_TRAP_21                      0x0000011DL
+#define DREG_REGID_TRAP_22                      0x0000011EL
+#define DREG_REGID_TRAP_23                      0x0000011FL
+#endif
+#endif
+#define DREG_REGID_RSA0_LOW                     0x00000200L
+#define DREG_REGID_RSA0_HIGH                    0x00000201L
+#define DREG_REGID_RSA1_LOW                     0x00000202L
+#define DREG_REGID_RSA1_HIGH                    0x00000203L
+#define DREG_REGID_RSA2                         0x00000204L
+#define DREG_REGID_RSA3                         0x00000205L
+#define DREG_REGID_RSI0_LOW                     0x00000206L
+#define DREG_REGID_RSI0_HIGH                    0x00000207L
+#define DREG_REGID_RSI1                         0x00000208L
+#define DREG_REGID_RSI2                         0x00000209L
+#define DREG_REGID_SAGUSTATUS                   0x0000020AL
+#define DREG_REGID_RSCONFIG01_LOW               0x0000020BL
+#define DREG_REGID_RSCONFIG01_HIGH              0x0000020CL
+#define DREG_REGID_RSCONFIG23_LOW               0x0000020DL
+#define DREG_REGID_RSCONFIG23_HIGH              0x0000020EL
+#define DREG_REGID_RSDMA01E                     0x0000020FL
+#define DREG_REGID_RSDMA23E                     0x00000210L
+#define DREG_REGID_RSD0_LOW                     0x00000211L
+#define DREG_REGID_RSD0_HIGH                    0x00000212L
+#define DREG_REGID_RSD1_LOW                     0x00000213L
+#define DREG_REGID_RSD1_HIGH                    0x00000214L
+#define DREG_REGID_RSD2_LOW                     0x00000215L
+#define DREG_REGID_RSD2_HIGH                    0x00000216L
+#define DREG_REGID_RSD3_LOW                     0x00000217L
+#define DREG_REGID_RSD3_HIGH                    0x00000218L
+#define DREG_REGID_SRAR_HIGH                    0x0000021AL
+#define DREG_REGID_SRAR_LOW                     0x0000021BL
+#define DREG_REGID_DMA_STATE                    0x0000021CL
+#define DREG_REGID_CURRENT_DMA_STREAM           0x0000021DL
+#define DREG_REGID_NEXT_DMA_STREAM              0x0000021EL
+#define DREG_REGID_CPU_STATUS                   0x00000300L
+#define DREG_REGID_MAC_MODE                     0x00000301L
+#define DREG_REGID_STACK_AND_REPEAT             0x00000302L
+#define DREG_REGID_INDEX0                       0x00000304L
+#define DREG_REGID_INDEX1                       0x00000305L
+#define DREG_REGID_DMA_STATE_0_3                0x00000400L
+#define DREG_REGID_DMA_STATE_4_7                0x00000404L
+#define DREG_REGID_DMA_STATE_8_11               0x00000408L
+#define DREG_REGID_DMA_STATE_12_15              0x0000040CL
+#define DREG_REGID_DMA_STATE_16_19              0x00000410L
+#define DREG_REGID_DMA_STATE_20_23              0x00000414L
+#define DREG_REGID_DMA_STATE_24_27              0x00000418L
+#define DREG_REGID_DMA_STATE_28_31              0x0000041CL
+#define DREG_REGID_DMA_STATE_32_35              0x00000420L
+#define DREG_REGID_DMA_STATE_36_39              0x00000424L
+#define DREG_REGID_DMA_STATE_40_43              0x00000428L
+#define DREG_REGID_DMA_STATE_44_47              0x0000042CL
+#define DREG_REGID_DMA_STATE_48_51              0x00000430L
+#define DREG_REGID_DMA_STATE_52_55              0x00000434L
+#define DREG_REGID_DMA_STATE_56_59              0x00000438L
+#define DREG_REGID_DMA_STATE_60_63              0x0000043CL
+#define DREG_REGID_DMA_STATE_64_67              0x00000440L
+#define DREG_REGID_DMA_STATE_68_71              0x00000444L
+#define DREG_REGID_DMA_STATE_72_75              0x00000448L
+#define DREG_REGID_DMA_STATE_76_79              0x0000044CL
+#define DREG_REGID_DMA_STATE_80_83              0x00000450L
+#define DREG_REGID_DMA_STATE_84_87              0x00000454L
+#define DREG_REGID_DMA_STATE_88_91              0x00000458L
+#define DREG_REGID_DMA_STATE_92_95              0x0000045CL
+#define DREG_REGID_TRAP_SELECT                  0x00000500L
+#define DREG_REGID_TRAP_WRITE_0                 0x00000500L
+#define DREG_REGID_TRAP_WRITE_1                 0x00000501L
+#define DREG_REGID_TRAP_WRITE_2                 0x00000502L
+#define DREG_REGID_TRAP_WRITE_3                 0x00000503L
+#define DREG_REGID_TRAP_WRITE_4                 0x00000504L
+#define DREG_REGID_TRAP_WRITE_5                 0x00000505L
+#define DREG_REGID_TRAP_WRITE_6                 0x00000506L
+#define DREG_REGID_TRAP_WRITE_7                 0x00000507L
+#if !defined(NO_CS4612)
+#if !defined(NO_CS4615)
+#define DREG_REGID_TRAP_WRITE_8                 0x00000510L
+#define DREG_REGID_TRAP_WRITE_9                 0x00000511L
+#define DREG_REGID_TRAP_WRITE_10                0x00000512L
+#define DREG_REGID_TRAP_WRITE_11                0x00000513L
+#define DREG_REGID_TRAP_WRITE_12                0x00000514L
+#define DREG_REGID_TRAP_WRITE_13                0x00000515L
+#define DREG_REGID_TRAP_WRITE_14                0x00000516L
+#define DREG_REGID_TRAP_WRITE_15                0x00000517L
+#define DREG_REGID_TRAP_WRITE_16                0x00000518L
+#define DREG_REGID_TRAP_WRITE_17                0x00000519L
+#define DREG_REGID_TRAP_WRITE_18                0x0000051AL
+#define DREG_REGID_TRAP_WRITE_19                0x0000051BL
+#define DREG_REGID_TRAP_WRITE_20                0x0000051CL
+#define DREG_REGID_TRAP_WRITE_21                0x0000051DL
+#define DREG_REGID_TRAP_WRITE_22                0x0000051EL
+#define DREG_REGID_TRAP_WRITE_23                0x0000051FL
+#endif
+#endif
+#define DREG_REGID_MAC0_ACC0_LOW                0x00000600L
+#define DREG_REGID_MAC0_ACC1_LOW                0x00000601L
+#define DREG_REGID_MAC0_ACC2_LOW                0x00000602L
+#define DREG_REGID_MAC0_ACC3_LOW                0x00000603L
+#define DREG_REGID_MAC1_ACC0_LOW                0x00000604L
+#define DREG_REGID_MAC1_ACC1_LOW                0x00000605L
+#define DREG_REGID_MAC1_ACC2_LOW                0x00000606L
+#define DREG_REGID_MAC1_ACC3_LOW                0x00000607L
+#define DREG_REGID_MAC0_ACC0_MID                0x00000608L
+#define DREG_REGID_MAC0_ACC1_MID                0x00000609L
+#define DREG_REGID_MAC0_ACC2_MID                0x0000060AL
+#define DREG_REGID_MAC0_ACC3_MID                0x0000060BL
+#define DREG_REGID_MAC1_ACC0_MID                0x0000060CL
+#define DREG_REGID_MAC1_ACC1_MID                0x0000060DL
+#define DREG_REGID_MAC1_ACC2_MID                0x0000060EL
+#define DREG_REGID_MAC1_ACC3_MID                0x0000060FL
+#define DREG_REGID_MAC0_ACC0_HIGH               0x00000610L
+#define DREG_REGID_MAC0_ACC1_HIGH               0x00000611L
+#define DREG_REGID_MAC0_ACC2_HIGH               0x00000612L
+#define DREG_REGID_MAC0_ACC3_HIGH               0x00000613L
+#define DREG_REGID_MAC1_ACC0_HIGH               0x00000614L
+#define DREG_REGID_MAC1_ACC1_HIGH               0x00000615L
+#define DREG_REGID_MAC1_ACC2_HIGH               0x00000616L
+#define DREG_REGID_MAC1_ACC3_HIGH               0x00000617L
+#define DREG_REGID_RSHOUT_LOW                   0x00000620L
+#define DREG_REGID_RSHOUT_MID                   0x00000628L
+#define DREG_REGID_RSHOUT_HIGH                  0x00000630L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 S/PDIF Control register.
+//
+//****************************************************************************
+#define SPDIF_CONTROL_SPDIF_EN                 0x00008000L
+#define SPDIF_CONTROL_VAL                      0x00004000L
+#define SPDIF_CONTROL_COPY                     0x00000004L
+#define SPDIF_CONTROL_CC0                      0x00000010L
+#define SPDIF_CONTROL_CC1                      0x00000020L
+#define SPDIF_CONTROL_CC2                      0x00000040L
+#define SPDIF_CONTROL_CC3                      0x00000080L
+#define SPDIF_CONTROL_CC4                      0x00000100L
+#define SPDIF_CONTROL_CC5                      0x00000200L
+#define SPDIF_CONTROL_CC6                      0x00000400L
+#define SPDIF_CONTROL_L                        0x00000800L
+
+#endif // _H_HWDEFS
diff -urN linux-2.4.2-pre1/drivers/sound/cs4281/cs4281_wrapper-24.c linux/drivers/sound/cs4281/cs4281_wrapper-24.c
--- linux-2.4.2-pre1/drivers/sound/cs4281/cs4281_wrapper-24.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/sound/cs4281/cs4281_wrapper-24.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,51 @@
+/*******************************************************************************
+*
+*      "cs4281_wrapper.c" --  Cirrus Logic-Crystal CS4281 linux audio driver.
+*
+*      Copyright (C) 2000,2001  Cirrus Logic Corp.  
+*            -- tom woller (twoller@crystal.cirrus.com) or
+*               (audio@crystal.cirrus.com).
+*
+*      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.
+*
+* 12/20/00 trw - new file. 
+*
+*******************************************************************************/
+
+#include <linux/spinlock.h>
+
+void cs4281_null(struct pci_dev *pcidev) { return; }
+#define cs4x_mem_map_reserve(page) mem_map_reserve(page)
+#define cs4x_mem_map_unreserve(page) mem_map_unreserve(page)
+
+#define free_dmabuf(state, dmabuf) \
+	pci_free_consistent(state->pcidev, \
+			    PAGE_SIZE << (dmabuf)->buforder, \
+			    (dmabuf)->rawbuf, (dmabuf)->dmaaddr);
+#define free_dmabuf2(state, dmabuf) \
+	pci_free_consistent((state)->pcidev, \
+				    PAGE_SIZE << (state)->buforder_tmpbuff, \
+				    (state)->tmpbuff, (state)->dmaaddr_tmpbuff);
+#define cs4x_pgoff(vma) ((vma)->vm_pgoff)
+
+#define RSRCISIOREGION(dev,num) ((dev)->resource[(num)].start != 0 && \
+	 ((dev)->resource[(num)].flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
+#define RSRCISMEMORYREGION(dev,num) ((dev)->resource[(num)].start != 0 && \
+	 ((dev)->resource[(num)].flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY)
+#define RSRCADDRESS(dev,num) ((dev)->resource[(num)].start)
+#define PCI_GET_DRIVER_DATA pci_get_drvdata
+#define PCI_SET_DRIVER_DATA pci_set_drvdata
+#define PCI_SET_DMA_MASK(pcidev,mask) pcidev->dma_mask = mask
+
diff -urN linux-2.4.2-pre1/drivers/sound/cs4281/cs4281m.c linux/drivers/sound/cs4281/cs4281m.c
--- linux-2.4.2-pre1/drivers/sound/cs4281/cs4281m.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/sound/cs4281/cs4281m.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,4537 @@
+/*******************************************************************************
+*
+*      "cs4281.c" --  Cirrus Logic-Crystal CS4281 linux audio driver.
+*
+*      Copyright (C) 2000,2001  Cirrus Logic Corp.  
+*            -- adapted from drivers by Thomas Sailer, 
+*            -- but don't bug him; Problems should go to:
+*            -- tom woller (twoller@crystal.cirrus.com) or
+*               (audio@crystal.cirrus.com).
+*
+*      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.
+*
+* Module command line parameters:
+*   none
+*
+*  Supported devices:
+*  /dev/dsp    standard /dev/dsp device, (mostly) OSS compatible
+*  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible
+*  /dev/midi   simple MIDI UART interface, no ioctl
+*
+* Modification History
+* 08/20/00 trw - silence and no stopping DAC until release
+* 08/23/00 trw - added CS_DBG statements, fix interrupt hang issue on DAC stop.
+* 09/18/00 trw - added 16bit only record with conversion 
+* 09/24/00 trw - added Enhanced Full duplex (separate simultaneous 
+*                capture/playback rates)
+* 10/03/00 trw - fixed mmap (fixed GRECORD and the XMMS mmap test plugin  
+*                libOSSm.so)
+* 10/11/00 trw - modified for 2.4.0-test9 kernel enhancements (NR_MAP removal)
+* 11/03/00 trw - fixed interrupt loss/stutter, added debug.
+* 11/10/00 bkz - added __devinit to cs4281_hw_init()
+* 11/10/00 trw - fixed SMP and capture spinlock hang.
+* 12/04/00 trw - cleaned up CSDEBUG flags and added "defaultorder" moduleparm.
+* 12/05/00 trw - fixed polling (myth2), and added underrun swptr fix.
+* 12/08/00 trw - added PM support. 
+* 12/14/00 trw - added wrapper code, builds under 2.4.0, 2.2.17-20, 2.2.17-8 
+*		 (RH/Dell base), 2.2.18, 2.2.12.  cleaned up code mods by ident.
+* 12/19/00 trw - added PM support for 2.2 base (apm_callback). other PM cleanup.
+* 12/21/00 trw - added fractional "defaultorder" inputs. if >100 then use 
+*		 defaultorder-100 as power of 2 for the buffer size. example:
+*		 106 = 2^(106-100) = 2^6 = 64 bytes for the buffer size.
+*
+*******************************************************************************/
+
+/* uncomment the following line to disable building PM support into the driver */
+//#define NOT_CS4281_PM 1 
+
+#include <linux/list.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/sound.h>
+#include <linux/malloc.h>
+#include <linux/soundcard.h>
+#include <linux/pci.h>
+#include <linux/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/smp_lock.h>
+#include <linux/wrapper.h>
+#include <asm/uaccess.h>
+#include <asm/hardirq.h>
+//#include "cs_dm.h"
+#include "cs4281_hwdefs.h"
+#include "cs4281pm.h"
+
+struct cs4281_state;
+EXPORT_NO_SYMBOLS;
+
+static void stop_dac(struct cs4281_state *s);
+static void stop_adc(struct cs4281_state *s);
+static void start_dac(struct cs4281_state *s);
+static void start_adc(struct cs4281_state *s);
+#undef OSS_DOCUMENTED_MIXER_SEMANTICS
+
+// --------------------------------------------------------------------- 
+
+#ifndef PCI_VENDOR_ID_CIRRUS
+#define PCI_VENDOR_ID_CIRRUS          0x1013
+#endif
+#ifndef PCI_DEVICE_ID_CRYSTAL_CS4281
+#define PCI_DEVICE_ID_CRYSTAL_CS4281  0x6005
+#endif
+
+#define CS4281_MAGIC  ((PCI_DEVICE_ID_CRYSTAL_CS4281<<16) | PCI_VENDOR_ID_CIRRUS)
+#define	CS4281_CFLR_DEFAULT	0x00000001  /* CFLR must be in AC97 link mode */
+
+// buffer order determines the size of the dma buffer for the driver.
+// under Linux, a smaller buffer allows more responsiveness from many of the 
+// applications (e.g. games).  A larger buffer allows some of the apps (esound) 
+// to not underrun the dma buffer as easily.  As default, use 32k (order=3)
+// rather than 64k as some of the games work more responsively.
+// log base 2( buff sz = 32k).
+static unsigned long defaultorder = 3;
+MODULE_PARM(defaultorder, "i");
+
+//
+// Turn on/off debugging compilation by commenting out "#define CSDEBUG"
+//
+#define CSDEBUG 1
+#if CSDEBUG
+#define CSDEBUG_INTERFACE 1
+#else
+#undef CSDEBUG_INTERFACE
+#endif
+//
+// cs_debugmask areas
+//
+#define CS_INIT	 	0x00000001	// initialization and probe functions
+#define CS_ERROR 	0x00000002	// tmp debugging bit placeholder
+#define CS_INTERRUPT	0x00000004	// interrupt handler (separate from all other)
+#define CS_FUNCTION 	0x00000008	// enter/leave functions
+#define CS_WAVE_WRITE 	0x00000010	// write information for wave
+#define CS_WAVE_READ 	0x00000020	// read information for wave
+#define CS_MIDI_WRITE 	0x00000040	// write information for midi
+#define CS_MIDI_READ 	0x00000080	// read information for midi
+#define CS_MPU401_WRITE 0x00000100	// write information for mpu401
+#define CS_MPU401_READ 	0x00000200	// read information for mpu401
+#define CS_OPEN		0x00000400	// all open functions in the driver
+#define CS_RELEASE	0x00000800	// all release functions in the driver
+#define CS_PARMS	0x00001000	// functional and operational parameters
+#define CS_IOCTL	0x00002000	// ioctl (non-mixer)
+#define CS_PM		0x00004000	// power management 
+#define CS_TMP		0x10000000	// tmp debug mask bit
+
+#define CS_IOCTL_CMD_SUSPEND	0x1	// suspend
+#define CS_IOCTL_CMD_RESUME	0x2	// resume
+//
+// CSDEBUG is usual mode is set to 1, then use the
+// cs_debuglevel and cs_debugmask to turn on or off debugging.
+// Debug level of 1 has been defined to be kernel errors and info
+// that should be printed on any released driver.
+//
+#if CSDEBUG
+#define CS_DBGOUT(mask,level,x) if((cs_debuglevel >= (level)) && ((mask) & cs_debugmask) ) {x;}
+#else
+#define CS_DBGOUT(mask,level,x)
+#endif
+
+#if CSDEBUG
+static unsigned long cs_debuglevel = 1;	// levels range from 1-9
+static unsigned long cs_debugmask = CS_INIT | CS_ERROR;	// use CS_DBGOUT with various mask values
+MODULE_PARM(cs_debuglevel, "i");
+MODULE_PARM(cs_debugmask, "i");
+#endif
+#define CS_TRUE 	1
+#define CS_FALSE 	0
+
+// MIDI buffer sizes 
+#define MIDIINBUF  500
+#define MIDIOUTBUF 500
+
+#define FMODE_MIDI_SHIFT 3
+#define FMODE_MIDI_READ  (FMODE_READ << FMODE_MIDI_SHIFT)
+#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT)
+
+#define CS4281_MAJOR_VERSION 	1
+#define CS4281_MINOR_VERSION 	13
+#ifdef __ia64__
+#define CS4281_ARCH	     	64	//architecture key
+#else
+#define CS4281_ARCH	     	32	//architecture key
+#endif
+
+#define CS_TYPE_ADC 0
+#define CS_TYPE_DAC 1
+
+
+static const char invalid_magic[] =
+    KERN_CRIT "cs4281: invalid magic value\n";
+
+#define VALIDATE_STATE(s)                         \
+({                                                \
+        if (!(s) || (s)->magic != CS4281_MAGIC) { \
+                printk(invalid_magic);            \
+                return -ENXIO;                    \
+        }                                         \
+})
+
+#define list_for_each(pos, head) \
+        for (pos = (head)->next; pos != (head); pos = pos->next)
+
+//LIST_HEAD(cs4281_devs);
+struct list_head cs4281_devs = { &cs4281_devs, &cs4281_devs };
+
+struct cs4281_state; 
+
+#include "cs4281_wrapper-24.c"
+
+struct cs4281_state {
+	// magic 
+	unsigned int magic;
+
+	// we keep the cards in a linked list 
+	struct cs4281_state *next;
+
+	// pcidev is needed to turn off the DDMA controller at driver shutdown 
+	struct pci_dev *pcidev;
+	struct list_head list;
+
+	// soundcore stuff 
+	int dev_audio;
+	int dev_mixer;
+	int dev_midi;
+
+	// hardware resources 
+	unsigned int pBA0phys, pBA1phys;
+	char *pBA0, *pBA1;
+	unsigned int irq;
+
+	// mixer registers 
+	struct {
+		unsigned short vol[10];
+		unsigned int recsrc;
+		unsigned int modcnt;
+		unsigned short micpreamp;
+	} mix;
+
+	// wave stuff   
+	struct properties {
+		unsigned fmt;
+		unsigned fmt_original;	// original requested format
+		unsigned channels;
+		unsigned rate;
+		unsigned char clkdiv;
+	} prop_dac, prop_adc;
+	unsigned conversion:1;	// conversion from 16 to 8 bit in progress
+	void *tmpbuff;		// tmp buffer for sample conversions
+	unsigned ena;
+	spinlock_t lock;
+	struct semaphore open_sem;
+	struct semaphore open_sem_adc;
+	struct semaphore open_sem_dac;
+	mode_t open_mode;
+	wait_queue_head_t open_wait;
+	wait_queue_head_t open_wait_adc;
+	wait_queue_head_t open_wait_dac;
+
+	dma_addr_t dmaaddr_tmpbuff;
+	unsigned buforder_tmpbuff;	// Log base 2 of 'rawbuf' size in bytes..
+	struct dmabuf {
+		void *rawbuf;	// Physical address of  
+		dma_addr_t dmaaddr;
+		unsigned buforder;	// Log base 2 of 'rawbuf' size in bytes..
+		unsigned numfrag;	// # of 'fragments' in the buffer.
+		unsigned fragshift;	// Log base 2 of fragment size.
+		unsigned hwptr, swptr;
+		unsigned total_bytes;	// # bytes process since open.
+		unsigned blocks;	// last returned blocks value GETOPTR
+		unsigned wakeup;	// interrupt occurred on block 
+		int count;
+		unsigned underrun;	// underrun flag
+		unsigned error;	// over/underrun 
+		wait_queue_head_t wait;
+		// redundant, but makes calculations easier 
+		unsigned fragsize;	// 2**fragshift..
+		unsigned dmasize;	// 2**buforder.
+		unsigned fragsamples;
+		// OSS stuff 
+		unsigned mapped:1;	// Buffer mapped in cs4281_mmap()?
+		unsigned ready:1;	// prog_dmabuf_dac()/adc() successful?
+		unsigned endcleared:1;
+		unsigned type:1;	// adc or dac buffer (CS_TYPE_XXX)
+		unsigned ossfragshift;
+		int ossmaxfrags;
+		unsigned subdivision;
+	} dma_dac, dma_adc;
+
+	// midi stuff 
+	struct {
+		unsigned ird, iwr, icnt;
+		unsigned ord, owr, ocnt;
+		wait_queue_head_t iwait;
+		wait_queue_head_t owait;
+		struct timer_list timer;
+		unsigned char ibuf[MIDIINBUF];
+		unsigned char obuf[MIDIOUTBUF];
+	} midi;
+
+	struct cs4281_pm pm;
+	struct cs4281_pipeline pl[CS4281_NUMBER_OF_PIPELINES];
+};
+
+#include "cs4281pm-24.c"
+
+#if CSDEBUG
+
+// DEBUG ROUTINES
+
+#define SOUND_MIXER_CS_GETDBGLEVEL 	_SIOWR('M',120, int)
+#define SOUND_MIXER_CS_SETDBGLEVEL 	_SIOWR('M',121, int)
+#define SOUND_MIXER_CS_GETDBGMASK 	_SIOWR('M',122, int)
+#define SOUND_MIXER_CS_SETDBGMASK 	_SIOWR('M',123, int)
+
+#define SOUND_MIXER_CS_APM	 	_SIOWR('M',124, int)
+
+
+static void cs_printioctl(unsigned int x)
+{
+	unsigned int i;
+	unsigned char vidx;
+	// Index of mixtable1[] member is Device ID 
+	// and must be <= SOUND_MIXER_NRDEVICES.
+	// Value of array member is index into s->mix.vol[]
+	static const unsigned char mixtable1[SOUND_MIXER_NRDEVICES] = {
+		[SOUND_MIXER_PCM] = 1,	// voice 
+		[SOUND_MIXER_LINE1] = 2,	// AUX
+		[SOUND_MIXER_CD] = 3,	// CD 
+		[SOUND_MIXER_LINE] = 4,	// Line 
+		[SOUND_MIXER_SYNTH] = 5,	// FM
+		[SOUND_MIXER_MIC] = 6,	// Mic 
+		[SOUND_MIXER_SPEAKER] = 7,	// Speaker 
+		[SOUND_MIXER_RECLEV] = 8,	// Recording level 
+		[SOUND_MIXER_VOLUME] = 9	// Master Volume 
+	};
+
+	switch (x) {
+	case SOUND_MIXER_CS_GETDBGMASK:
+		CS_DBGOUT(CS_IOCTL, 4,
+			  printk("SOUND_MIXER_CS_GETDBGMASK:\n"));
+		break;
+	case SOUND_MIXER_CS_GETDBGLEVEL:
+		CS_DBGOUT(CS_IOCTL, 4,
+			  printk("SOUND_MIXER_CS_GETDBGLEVEL:\n"));
+		break;
+	case SOUND_MIXER_CS_SETDBGMASK:
+		CS_DBGOUT(CS_IOCTL, 4,
+			  printk("SOUND_MIXER_CS_SETDBGMASK:\n"));
+		break;
+	case SOUND_MIXER_CS_SETDBGLEVEL:
+		CS_DBGOUT(CS_IOCTL, 4,
+			  printk("SOUND_MIXER_CS_SETDBGLEVEL:\n"));
+		break;
+	case OSS_GETVERSION:
+		CS_DBGOUT(CS_IOCTL, 4, printk("OSS_GETVERSION:\n"));
+		break;
+	case SNDCTL_DSP_SYNC:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SYNC:\n"));
+		break;
+	case SNDCTL_DSP_SETDUPLEX:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETDUPLEX:\n"));
+		break;
+	case SNDCTL_DSP_GETCAPS:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETCAPS:\n"));
+		break;
+	case SNDCTL_DSP_RESET:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_RESET:\n"));
+		break;
+	case SNDCTL_DSP_SPEED:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SPEED:\n"));
+		break;
+	case SNDCTL_DSP_STEREO:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_STEREO:\n"));
+		break;
+	case SNDCTL_DSP_CHANNELS:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_CHANNELS:\n"));
+		break;
+	case SNDCTL_DSP_GETFMTS:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETFMTS:\n"));
+		break;
+	case SNDCTL_DSP_SETFMT:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETFMT:\n"));
+		break;
+	case SNDCTL_DSP_POST:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_POST:\n"));
+		break;
+	case SNDCTL_DSP_GETTRIGGER:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETTRIGGER:\n"));
+		break;
+	case SNDCTL_DSP_SETTRIGGER:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETTRIGGER:\n"));
+		break;
+	case SNDCTL_DSP_GETOSPACE:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETOSPACE:\n"));
+		break;
+	case SNDCTL_DSP_GETISPACE:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETISPACE:\n"));
+		break;
+	case SNDCTL_DSP_NONBLOCK:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_NONBLOCK:\n"));
+		break;
+	case SNDCTL_DSP_GETODELAY:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETODELAY:\n"));
+		break;
+	case SNDCTL_DSP_GETIPTR:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETIPTR:\n"));
+		break;
+	case SNDCTL_DSP_GETOPTR:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETOPTR:\n"));
+		break;
+	case SNDCTL_DSP_GETBLKSIZE:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETBLKSIZE:\n"));
+		break;
+	case SNDCTL_DSP_SETFRAGMENT:
+		CS_DBGOUT(CS_IOCTL, 4,
+			  printk("SNDCTL_DSP_SETFRAGMENT:\n"));
+		break;
+	case SNDCTL_DSP_SUBDIVIDE:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SUBDIVIDE:\n"));
+		break;
+	case SOUND_PCM_READ_RATE:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_PCM_READ_RATE:\n"));
+		break;
+	case SOUND_PCM_READ_CHANNELS:
+		CS_DBGOUT(CS_IOCTL, 4,
+			  printk("SOUND_PCM_READ_CHANNELS:\n"));
+		break;
+	case SOUND_PCM_READ_BITS:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_PCM_READ_BITS:\n"));
+		break;
+	case SOUND_PCM_WRITE_FILTER:
+		CS_DBGOUT(CS_IOCTL, 4,
+			  printk("SOUND_PCM_WRITE_FILTER:\n"));
+		break;
+	case SNDCTL_DSP_SETSYNCRO:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETSYNCRO:\n"));
+		break;
+	case SOUND_PCM_READ_FILTER:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_PCM_READ_FILTER:\n"));
+		break;
+	case SOUND_MIXER_PRIVATE1:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE1:\n"));
+		break;
+	case SOUND_MIXER_PRIVATE2:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE2:\n"));
+		break;
+	case SOUND_MIXER_PRIVATE3:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE3:\n"));
+		break;
+	case SOUND_MIXER_PRIVATE4:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE4:\n"));
+		break;
+	case SOUND_MIXER_PRIVATE5:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE5:\n"));
+		break;
+	case SOUND_MIXER_INFO:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_INFO:\n"));
+		break;
+	case SOUND_OLD_MIXER_INFO:
+		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_OLD_MIXER_INFO:\n"));
+		break;
+
+	default:
+		switch (_IOC_NR(x)) {
+		case SOUND_MIXER_VOLUME:
+			CS_DBGOUT(CS_IOCTL, 4,
+				  printk("SOUND_MIXER_VOLUME:\n"));
+			break;
+		case SOUND_MIXER_SPEAKER:
+			CS_DBGOUT(CS_IOCTL, 4,
+				  printk("SOUND_MIXER_SPEAKER:\n"));
+			break;
+		case SOUND_MIXER_RECLEV:
+			CS_DBGOUT(CS_IOCTL, 4,
+				  printk("SOUND_MIXER_RECLEV:\n"));
+			break;
+		case SOUND_MIXER_MIC:
+			CS_DBGOUT(CS_IOCTL, 4,
+				  printk("SOUND_MIXER_MIC:\n"));
+			break;
+		case SOUND_MIXER_SYNTH:
+			CS_DBGOUT(CS_IOCTL, 4,
+				  printk("SOUND_MIXER_SYNTH:\n"));
+			break;
+		case SOUND_MIXER_RECSRC:
+			CS_DBGOUT(CS_IOCTL, 4,
+				  printk("SOUND_MIXER_RECSRC:\n"));
+			break;
+		case SOUND_MIXER_DEVMASK:
+			CS_DBGOUT(CS_IOCTL, 4,
+				  printk("SOUND_MIXER_DEVMASK:\n"));
+			break;
+		case SOUND_MIXER_RECMASK:
+			CS_DBGOUT(CS_IOCTL, 4,
+				  printk("SOUND_MIXER_RECMASK:\n"));
+			break;
+		case SOUND_MIXER_STEREODEVS:
+			CS_DBGOUT(CS_IOCTL, 4,
+				  printk("SOUND_MIXER_STEREODEVS:\n"));
+			break;
+		case SOUND_MIXER_CAPS:
+			CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_CAPS:\n"));
+			break;
+		default:
+			i = _IOC_NR(x);
+			if (i >= SOUND_MIXER_NRDEVICES
+			    || !(vidx = mixtable1[i])) {
+				CS_DBGOUT(CS_IOCTL, 4, printk
+					("UNKNOWN IOCTL: 0x%.8x NR=%d\n",
+						x, i));
+			} else {
+				CS_DBGOUT(CS_IOCTL, 4, printk
+					("SOUND_MIXER_IOCTL AC9x: 0x%.8x NR=%d\n",
+						x, i));
+			}
+			break;
+		}
+	}
+}
+#endif
+static int prog_dmabuf_adc(struct cs4281_state *s);
+static void prog_codec(struct cs4281_state *s, unsigned type);
+
+// --------------------------------------------------------------------- 
+//
+//              Hardware Interfaces For the CS4281
+//
+
+
+//******************************************************************************
+// "delayus()-- Delay for the specified # of microseconds.
+//******************************************************************************
+static void delayus(struct cs4281_state *s, u32 delay)
+{
+	u32 j;
+	if ((delay > 9999) && (s->pm.flags & CS4281_PM_IDLE)) {
+		j = (delay * HZ) / 1000000;	/* calculate delay in jiffies  */
+		if (j < 1)
+			j = 1;	/* minimum one jiffy. */
+		current->state = TASK_UNINTERRUPTIBLE;
+		schedule_timeout(j);
+	} else
+		udelay(delay);
+	return;
+}
+
+
+//******************************************************************************
+// "cs4281_read_ac97" -- Reads a word from the specified location in the
+//               CS4281's address space(based on the BA0 register).
+//
+// 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
+// 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 register,
+//                                            0h for reads.
+// 3. Write ACCTL = Control Register = 460h for initiating the write
+// 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 17h
+// 5. if DCV not cleared, break and return error
+// 6. Read ACSTS = Status Register = 464h, check VSTS bit
+//****************************************************************************
+static int cs4281_read_ac97(struct cs4281_state *card, u32 offset,
+			    u32 * value)
+{
+	u32 count, status;
+
+	// Make sure that there is not data sitting
+	// around from a previous uncompleted access.
+	// ACSDA = Status Data Register = 47Ch
+	status = readl(card->pBA0 + BA0_ACSDA);
+
+	// Setup the AC97 control registers on the CS4281 to send the
+	// appropriate command to the AC97 to perform the read.
+	// ACCAD = Command Address Register = 46Ch
+	// ACCDA = Command Data Register = 470h
+	// ACCTL = Control Register = 460h
+	// bit DCV - will clear when process completed
+	// bit CRW - Read command
+	// bit VFRM - valid frame enabled
+	// bit ESYN - ASYNC generation enabled
+
+	// Get the actual AC97 register from the offset
+	writel(offset - BA0_AC97_RESET, card->pBA0 + BA0_ACCAD);
+	writel(0, card->pBA0 + BA0_ACCDA);
+	writel(ACCTL_DCV | ACCTL_CRW | ACCTL_VFRM | ACCTL_ESYN,
+	       card->pBA0 + BA0_ACCTL);
+
+	// Wait for the read to occur.
+	for (count = 0; count < 10; count++) {
+		// First, we want to wait for a short time.
+		udelay(25);
+
+		// Now, check to see if the read has completed.
+		// ACCTL = 460h, DCV should be reset by now and 460h = 17h
+		if (!(readl(card->pBA0 + BA0_ACCTL) & ACCTL_DCV))
+			break;
+	}
+
+	// Make sure the read completed.
+	if (readl(card->pBA0 + BA0_ACCTL) & ACCTL_DCV)
+		return 1;
+
+	// Wait for the valid status bit to go active.
+	for (count = 0; count < 10; count++) {
+		// Read the AC97 status register.
+		// ACSTS = Status Register = 464h
+		status = readl(card->pBA0 + BA0_ACSTS);
+
+		// See if we have valid status.
+		// VSTS - Valid Status
+		if (status & ACSTS_VSTS)
+			break;
+		// Wait for a short while.
+		udelay(25);
+	}
+
+	// Make sure we got valid status.
+	if (!(status & ACSTS_VSTS))
+		return 1;
+
+	// Read the data returned from the AC97 register.
+	// ACSDA = Status Data Register = 474h
+	*value = readl(card->pBA0 + BA0_ACSDA);
+
+	// Success.
+	return (0);
+}
+
+
+//****************************************************************************
+//
+// "cs4281_write_ac97()"-- writes a word to the specified location in the
+// CS461x's address space (based on the part's base address zero register).
+//
+// 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
+// 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 reg.
+// 3. Write ACCTL = Control Register = 460h for initiating the write
+// 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 07h
+// 5. if DCV not cleared, break and return error
+//
+//****************************************************************************
+static int cs4281_write_ac97(struct cs4281_state *card, u32 offset,
+			     u32 value)
+{
+	u32 count, status=0;
+
+	CS_DBGOUT(CS_FUNCTION, 2,
+		  printk(KERN_INFO "cs4281: cs_4281_write_ac97()+ \n"));
+
+	// Setup the AC97 control registers on the CS4281 to send the
+	// appropriate command to the AC97 to perform the read.
+	// ACCAD = Command Address Register = 46Ch
+	// ACCDA = Command Data Register = 470h
+	// ACCTL = Control Register = 460h
+	// set DCV - will clear when process completed
+	// reset CRW - Write command
+	// set VFRM - valid frame enabled
+	// set ESYN - ASYNC generation enabled
+	// set RSTN - ARST# inactive, AC97 codec not reset
+
+	// Get the actual AC97 register from the offset
+
+	writel(offset - BA0_AC97_RESET, card->pBA0 + BA0_ACCAD);
+	writel(value, card->pBA0 + BA0_ACCDA);
+	writel(ACCTL_DCV | ACCTL_VFRM | ACCTL_ESYN,
+	       card->pBA0 + BA0_ACCTL);
+
+	// Wait for the write to occur.
+	for (count = 0; count < 10; count++) {
+		// First, we want to wait for a short time.
+		udelay(25);
+		// Now, check to see if the write has completed.
+		// ACCTL = 460h, DCV should be reset by now and 460h = 07h
+		status = readl(card->pBA0 + BA0_ACCTL);
+		if (!(status & ACCTL_DCV))
+			break;
+	}
+
+	// Make sure the write completed.
+	if (status & ACCTL_DCV) {
+		CS_DBGOUT(CS_ERROR, 1, printk(KERN_INFO
+	      		"cs4281: cs_4281_write_ac97()- unable to write. ACCTL_DCV active\n"));
+		return 1;
+	}
+	CS_DBGOUT(CS_FUNCTION, 2,
+		  printk(KERN_INFO "cs4281: cs_4281_write_ac97()- 0\n"));
+	// Success.
+	return 0;
+}
+
+
+//******************************************************************************
+// "Init4281()" -- Bring up the part.
+//******************************************************************************
+static __devinit int cs4281_hw_init(struct cs4281_state *card)
+{
+	u32 ac97_slotid;
+	u32 temp1, temp2;
+
+	CS_DBGOUT(CS_FUNCTION, 2,
+		  printk(KERN_INFO "cs4281: cs4281_hw_init()+ \n"));
+#ifndef NOT_CS4281_PM
+	if(!card)
+		return 1;
+#endif
+	temp2 = readl(card->pBA0 + BA0_CFLR);
+	CS_DBGOUT(CS_INIT | CS_ERROR | CS_PARMS, 4, printk(KERN_INFO 
+		"cs4281: cs4281_hw_init() CFLR 0x%x\n", temp2));
+	if(temp2 != CS4281_CFLR_DEFAULT)
+	{
+		CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_INFO 
+			"cs4281: cs4281_hw_init() CFLR invalid - resetting from 0x%x to 0x%x\n",
+				temp2,CS4281_CFLR_DEFAULT));
+		writel(CS4281_CFLR_DEFAULT, card->pBA0 + BA0_CFLR);
+		temp2 = readl(card->pBA0 + BA0_CFLR);
+		if(temp2 != CS4281_CFLR_DEFAULT)
+		{
+			CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_INFO 
+				"cs4281: cs4281_hw_init() Invalid hardware - unable to configure CFLR\n"));
+			return 1;
+		}
+	}
+
+	//***************************************7
+	//  Set up the Sound System Configuration
+	//***************************************
+
+	// Set the 'Configuration Write Protect' register
+	// to 4281h.  Allows vendor-defined configuration
+	// space between 0e4h and 0ffh to be written.
+
+	writel(0x4281, card->pBA0 + BA0_CWPR);	// (3e0h)
+
+	// (0), Blast the clock control register to zero so that the
+	// PLL starts out in a known state, and blast the master serial
+	// port control register to zero so that the serial ports also
+	// start out in a known state.
+
+	writel(0, card->pBA0 + BA0_CLKCR1);	// (400h)
+	writel(0, card->pBA0 + BA0_SERMC);	// (420h)
+
+
+	// (1), Make ESYN go to zero to turn off
+	// the Sync pulse on the AC97 link.
+
+	writel(0, card->pBA0 + BA0_ACCTL);
+	udelay(50);
+
+
+	// (2) Drive the ARST# pin low for a minimum of 1uS (as defined in
+	// the AC97 spec) and then drive it high.  This is done for non
+	// AC97 modes since there might be logic external to the CS461x
+	// that uses the ARST# line for a reset.
+
+	writel(0, card->pBA0 + BA0_SPMC);	// (3ech)
+	udelay(100);
+	writel(SPMC_RSTN, card->pBA0 + BA0_SPMC);
+	delayus(card,50000);		// Wait 50 ms for ABITCLK to become stable.
+
+	// (3) Turn on the Sound System Clocks.
+	writel(CLKCR1_PLLP, card->pBA0 + BA0_CLKCR1);	// (400h)
+	delayus(card,50000);		// Wait for the PLL to stabilize.
+	// Turn on clocking of the core (CLKCR1(400h) = 0x00000030)
+	writel(CLKCR1_PLLP | CLKCR1_SWCE, card->pBA0 + BA0_CLKCR1);
+
+	// (4) Power on everything for now..
+	writel(0x7E, card->pBA0 + BA0_SSPM);	// (740h)
+
+	// (5) Wait for clock stabilization.
+	for (temp1 = 0; temp1 < 1000; temp1++) {
+		udelay(1000);
+		if (readl(card->pBA0 + BA0_CLKCR1) & CLKCR1_DLLRDY)
+			break;
+	}
+	if (!(readl(card->pBA0 + BA0_CLKCR1) & CLKCR1_DLLRDY)) {
+		CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR 
+			"cs4281: DLLRDY failed!\n"));
+		return -EIO;
+	}
+	// (6) Enable ASYNC generation.
+	writel(ACCTL_ESYN, card->pBA0 + BA0_ACCTL);	// (460h)
+
+	// Now wait 'for a short while' to allow the  AC97
+	// part to start generating bit clock. (so we don't
+	// Try to start the PLL without an input clock.)
+	delayus(card,50000);
+
+	// Set the serial port timing configuration, so that the
+	// clock control circuit gets its clock from the right place.
+	writel(SERMC_PTC_AC97, card->pBA0 + BA0_SERMC);	// (420h)=2.
+
+	// (7) Wait for the codec ready signal from the AC97 codec.
+
+	for (temp1 = 0; temp1 < 1000; temp1++) {
+		// Delay a mil to let things settle out and
+		// to prevent retrying the read too quickly.
+		udelay(1000);
+		if (readl(card->pBA0 + BA0_ACSTS) & ACSTS_CRDY)	// If ready,  (464h)
+			break;	//   exit the 'for' loop.
+	}
+	if (!(readl(card->pBA0 + BA0_ACSTS) & ACSTS_CRDY))	// If never came ready,
+	{
+		CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_ERR
+			 "cs4281: ACSTS never came ready!\n"));
+		return -EIO;	//   exit initialization.
+	}
+	// (8) Assert the 'valid frame' signal so we can
+	// begin sending commands to the AC97 codec.
+	writel(ACCTL_VFRM | ACCTL_ESYN, card->pBA0 + BA0_ACCTL);	// (460h)
+
+	// (9), Wait until CODEC calibration is finished.
+	// Print an error message if it doesn't.
+	for (temp1 = 0; temp1 < 1000; temp1++) {
+		delayus(card,10000);
+		// Read the AC97 Powerdown Control/Status Register.
+		cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp2);
+		if ((temp2 & 0x0000000F) == 0x0000000F)
+			break;
+	}
+	if ((temp2 & 0x0000000F) != 0x0000000F) {
+		CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_ERR
+			"cs4281: Codec failed to calibrate.  Status = %.8x.\n",
+				temp2));
+		return -EIO;
+	}
+	// (10), Set the serial port timing configuration, so that the
+	// clock control circuit gets its clock from the right place.
+	writel(SERMC_PTC_AC97, card->pBA0 + BA0_SERMC);	// (420h)=2.
+
+
+	// (11) Wait until we've sampled input slots 3 & 4 as valid, meaning
+	// that the codec is pumping ADC data across the AC link.
+	for (temp1 = 0; temp1 < 1000; temp1++) {
+		// Delay a mil to let things settle out and
+		// to prevent retrying the read too quickly.
+		delayus(card,1000);	//(test)
+
+		// Read the input slot valid register;  See
+		// if input slots 3 and 4 are valid yet.
+		if (
+		    (readl(card->pBA0 + BA0_ACISV) &
+		     (ACISV_ISV3 | ACISV_ISV4)) ==
+		    (ACISV_ISV3 | ACISV_ISV4)) break;	// Exit the 'for' if slots are valid.
+	}
+	// If we never got valid data, exit initialization.
+	if ((readl(card->pBA0 + BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4))
+	    != (ACISV_ISV3 | ACISV_ISV4)) {
+		CS_DBGOUT(CS_FUNCTION, 2,
+			  printk(KERN_ERR
+				 "cs4281: Never got valid data!\n"));
+		return -EIO;	// If no valid data, exit initialization.
+	}
+	// (12), Start digital data transfer of audio data to the codec.
+	writel(ACOSV_SLV3 | ACOSV_SLV4, card->pBA0 + BA0_ACOSV);	// (468h)
+
+
+	//**************************************
+	// Unmute the Master and Alternate
+	// (headphone) volumes.  Set to max.
+	//**************************************
+	cs4281_write_ac97(card, BA0_AC97_HEADPHONE_VOLUME, 0);
+	cs4281_write_ac97(card, BA0_AC97_MASTER_VOLUME, 0);
+
+	//******************************************
+	// Power on the DAC(AddDACUser()from main())
+	//******************************************
+	cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
+	cs4281_write_ac97(card, BA0_AC97_POWERDOWN, temp1 &= 0xfdff);
+
+	// Wait until we sample a DAC ready state.
+	for (temp2 = 0; temp2 < 32; temp2++) {
+		// Let's wait a mil to let things settle.
+		delayus(card,1000);
+		// Read the current state of the power control reg.
+		cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
+		// If the DAC ready state bit is set, stop waiting.
+		if (temp1 & 0x2)
+			break;
+	}
+
+	//******************************************
+	// Power on the ADC(AddADCUser()from main())
+	//******************************************
+	cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
+	cs4281_write_ac97(card, BA0_AC97_POWERDOWN, temp1 &= 0xfeff);
+
+	// Wait until we sample ADC ready state.
+	for (temp2 = 0; temp2 < 32; temp2++) {
+		// Let's wait a mil to let things settle.
+		delayus(card,1000);
+		// Read the current state of the power control reg.
+		cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
+		// If the ADC ready state bit is set, stop waiting.
+		if (temp1 & 0x1)
+			break;
+	}
+	// Set up 4281 Register contents that
+	// don't change for boot duration.
+
+	// For playback, we map AC97 slot 3 and 4(Left
+	// & Right PCM playback) to DMA Channel 0.
+	// Set the fifo to be 15 bytes at offset zero.
+
+	ac97_slotid = 0x01000f00;	// FCR0.RS[4:0]=1(=>slot4, right PCM playback).
+	// FCR0.LS[4:0]=0(=>slot3, left PCM playback).
+	// FCR0.SZ[6-0]=15; FCR0.OF[6-0]=0.
+	writel(ac97_slotid, card->pBA0 + BA0_FCR0);	// (180h)
+	writel(ac97_slotid | FCRn_FEN, card->pBA0 + BA0_FCR0);	// Turn on FIFO Enable.
+
+	// For capture, we map AC97 slot 10 and 11(Left
+	// and Right PCM Record) to DMA Channel 1.
+	// Set the fifo to be 15 bytes at offset sixteen.
+	ac97_slotid = 0x0B0A0f10;	// FCR1.RS[4:0]=11(=>slot11, right PCM record).
+	// FCR1.LS[4:0]=10(=>slot10, left PCM record).
+	// FCR1.SZ[6-0]=15; FCR1.OF[6-0]=16.
+	writel(ac97_slotid | FCRn_PSH, card->pBA0 + BA0_FCR1);	// (184h)
+	writel(ac97_slotid | FCRn_FEN, card->pBA0 + BA0_FCR1);	// Turn on FIFO Enable.
+
+	// Map the Playback SRC to the same AC97 slots(3 & 4--
+	// --Playback left & right)as DMA channel 0.
+	// Map the record SRC to the same AC97 slots(10 & 11--
+	// -- Record left & right) as DMA channel 1.
+
+	ac97_slotid = 0x0b0a0100;	// SCRSA.PRSS[4:0]=1(=>slot4, right PCM playback).
+	// SCRSA.PLSS[4:0]=0(=>slot3, left PCM playback).
+	// SCRSA.CRSS[4:0]=11(=>slot11, right PCM record)
+	// SCRSA.CLSS[4:0]=10(=>slot10, left PCM record).
+	writel(ac97_slotid, card->pBA0 + BA0_SRCSA);	// (75ch)
+
+	// Set 'Half Terminal Count Interrupt Enable' and 'Terminal
+	// Count Interrupt Enable' in DMA Control Registers 0 & 1.
+	// Set 'MSK' flag to 1 to keep the DMA engines paused.
+	temp1 = (DCRn_HTCIE | DCRn_TCIE | DCRn_MSK);	// (00030001h)
+	writel(temp1, card->pBA0 + BA0_DCR0);	// (154h
+	writel(temp1, card->pBA0 + BA0_DCR1);	// (15ch)
+
+	// Set 'Auto-Initialize Control' to 'enabled'; For playback,
+	// set 'Transfer Type Control'(TR[1:0]) to 'read transfer',
+	// for record, set Transfer Type Control to 'write transfer'.
+	// All other bits set to zero;  Some will be changed @ transfer start.
+	temp1 = (DMRn_DMA | DMRn_AUTO | DMRn_TR_READ);	// (20000018h)
+	writel(temp1, card->pBA0 + BA0_DMR0);	// (150h)
+	temp1 = (DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE);	// (20000014h)
+	writel(temp1, card->pBA0 + BA0_DMR1);	// (158h)
+
+	// Enable DMA interrupts generally, and
+	// DMA0 & DMA1 interrupts specifically.
+	temp1 = readl(card->pBA0 + BA0_HIMR) & 0xfffbfcff;
+	writel(temp1, card->pBA0 + BA0_HIMR);
+
+	CS_DBGOUT(CS_FUNCTION, 2,
+		  printk(KERN_INFO "cs4281: cs4281_hw_init()- 0\n"));
+	return 0;
+}
+
+#ifndef NOT_CS4281_PM
+void printpm(struct cs4281_state *s)
+{
+	CS_DBGOUT(CS_PM, 9, printk("pm struct:\n"));
+	CS_DBGOUT(CS_PM, 9, printk("flags:0x%x u32CLKCR1_SAVE: 0%x u32SSPMValue: 0x%x\n",
+		(unsigned)s->pm.flags,s->pm.u32CLKCR1_SAVE,s->pm.u32SSPMValue));
+	CS_DBGOUT(CS_PM, 9, printk("u32PPLVCvalue: 0x%x u32PPRVCvalue: 0x%x\n",
+		s->pm.u32PPLVCvalue,s->pm.u32PPRVCvalue));
+	CS_DBGOUT(CS_PM, 9, printk("u32FMLVCvalue: 0x%x u32FMRVCvalue: 0x%x\n",
+		s->pm.u32FMLVCvalue,s->pm.u32FMRVCvalue));
+	CS_DBGOUT(CS_PM, 9, printk("u32GPIORvalue: 0x%x u32JSCTLvalue: 0x%x\n",
+		s->pm.u32GPIORvalue,s->pm.u32JSCTLvalue));
+	CS_DBGOUT(CS_PM, 9, printk("u32SSCR: 0x%x u32SRCSA: 0x%x\n",
+		s->pm.u32SSCR,s->pm.u32SRCSA));
+	CS_DBGOUT(CS_PM, 9, printk("u32DacASR: 0x%x u32AdcASR: 0x%x\n",
+		s->pm.u32DacASR,s->pm.u32AdcASR));
+	CS_DBGOUT(CS_PM, 9, printk("u32DacSR: 0x%x u32AdcSR: 0x%x\n",
+		s->pm.u32DacSR,s->pm.u32AdcSR));
+	CS_DBGOUT(CS_PM, 9, printk("u32MIDCR_Save: 0x%x\n",
+		s->pm.u32MIDCR_Save));
+
+}
+void printpipe(struct cs4281_pipeline *pl)
+{
+
+	CS_DBGOUT(CS_PM, 9, printk("pm struct:\n"));
+	CS_DBGOUT(CS_PM, 9, printk("flags:0x%x number: 0%x\n",
+		(unsigned)pl->flags,pl->number));
+	CS_DBGOUT(CS_PM, 9, printk("u32DBAnValue: 0%x u32DBCnValue: 0x%x\n",
+		pl->u32DBAnValue,pl->u32DBCnValue));
+	CS_DBGOUT(CS_PM, 9, printk("u32DMRnValue: 0x%x u32DCRnValue: 0x%x\n",
+		pl->u32DMRnValue,pl->u32DCRnValue));
+	CS_DBGOUT(CS_PM, 9, printk("u32DBAnAddress: 0x%x u32DBCnAddress: 0x%x\n",
+		pl->u32DBAnAddress,pl->u32DBCnAddress));
+	CS_DBGOUT(CS_PM, 9, printk("u32DCAnAddress: 0x%x u32DCCnAddress: 0x%x\n",
+		pl->u32DCCnAddress,pl->u32DCCnAddress));
+	CS_DBGOUT(CS_PM, 9, printk("u32DMRnAddress: 0x%x u32DCRnAddress: 0x%x\n",
+		pl->u32DMRnAddress,pl->u32DCRnAddress));
+	CS_DBGOUT(CS_PM, 9, printk("u32HDSRnAddress: 0x%x u32DBAn_Save: 0x%x\n",
+		pl->u32HDSRnAddress,pl->u32DBAn_Save));
+	CS_DBGOUT(CS_PM, 9, printk("u32DBCn_Save: 0x%x u32DMRn_Save: 0x%x\n",
+		pl->u32DBCn_Save,pl->u32DMRn_Save));
+	CS_DBGOUT(CS_PM, 9, printk("u32DCRn_Save: 0x%x u32DCCn_Save: 0x%x\n",
+		pl->u32DCRn_Save,pl->u32DCCn_Save));
+	CS_DBGOUT(CS_PM, 9, printk("u32DCAn_Save: 0x%x\n",
+		pl->u32DCAn_Save));
+	CS_DBGOUT(CS_PM, 9, printk("u32FCRn_Save: 0x%x u32FSICn_Save: 0x%x\n",
+		pl->u32FCRn_Save,pl->u32FSICn_Save));
+	CS_DBGOUT(CS_PM, 9, printk("u32FCRnValue: 0x%x u32FSICnValue: 0x%x\n",
+		pl->u32FCRnValue,pl->u32FSICnValue));
+	CS_DBGOUT(CS_PM, 9, printk("u32FCRnAddress: 0x%x u32FSICnAddress: 0x%x\n",
+		pl->u32FCRnAddress,pl->u32FSICnAddress));
+	CS_DBGOUT(CS_PM, 9, printk("u32FPDRnValue: 0x%x u32FPDRnAddress: 0x%x\n",
+		pl->u32FPDRnValue,pl->u32FPDRnAddress));
+}
+void printpipelines(struct cs4281_state *s)
+{
+	int i;
+	for(i=0;i<CS4281_NUMBER_OF_PIPELINES;i++)
+	{
+		if(s->pl[i].flags & CS4281_PIPELINE_VALID)
+		{
+			printpipe(&s->pl[i]);
+		}
+	}
+}
+/****************************************************************************
+*
+*  Suspend - save the ac97 regs, mute the outputs and power down the part.  
+*
+****************************************************************************/
+void cs4281_ac97_suspend(struct cs4281_state *s)
+{
+	int Count,i;
+
+	CS_DBGOUT(CS_PM, 9, printk("cs4281: cs4281_ac97_suspend()+\n"));
+/*
+* change the state, save the current hwptr, then stop the dac/adc
+*/
+	s->pm.flags &= ~CS4281_PM_IDLE;
+	s->pm.flags |= CS4281_PM_SUSPENDING;
+	s->pm.u32hwptr_playback = readl(s->pBA0 + BA0_DCA0);
+	s->pm.u32hwptr_capture = readl(s->pBA0 + BA0_DCA1);
+	stop_dac(s);
+	stop_adc(s);
+
+	for(Count = 0x2, i=0; (Count <= CS4281_AC97_HIGHESTREGTORESTORE)
+			&& (i < CS4281_AC97_NUMBER_RESTORE_REGS); 
+		Count += 2, i++)
+	{
+		cs4281_read_ac97(s, BA0_AC97_RESET + Count, &s->pm.ac97[i]);
+	}
+/*
+* Save the ac97 volume registers as well as the current powerdown state.
+* Now, mute the all the outputs (master, headphone, and mono), as well
+* as the PCM volume, in preparation for powering down the entire part.
+*/ 
+	cs4281_read_ac97(s, BA0_AC97_MASTER_VOLUME, &s->pm.u32AC97_master_volume);
+	cs4281_read_ac97(s, BA0_AC97_HEADPHONE_VOLUME, &s->pm.u32AC97_headphone_volume);
+	cs4281_read_ac97(s, BA0_AC97_MASTER_VOLUME_MONO, &s->pm.u32AC97_master_volume_mono);
+	cs4281_read_ac97(s, BA0_AC97_PCM_OUT_VOLUME, &s->pm.u32AC97_pcm_out_volume);
+		
+	cs4281_write_ac97(s, BA0_AC97_MASTER_VOLUME, 0x8000);
+	cs4281_write_ac97(s, BA0_AC97_HEADPHONE_VOLUME, 0x8000);
+	cs4281_write_ac97(s, BA0_AC97_MASTER_VOLUME_MONO, 0x8000);
+	cs4281_write_ac97(s, BA0_AC97_PCM_OUT_VOLUME, 0x8000);
+
+	cs4281_read_ac97(s, BA0_AC97_POWERDOWN, &s->pm.u32AC97_powerdown);
+	cs4281_read_ac97(s, BA0_AC97_GENERAL_PURPOSE, &s->pm.u32AC97_general_purpose);
+
+/*
+* And power down everything on the AC97 codec.
+*/
+	cs4281_write_ac97(s, BA0_AC97_POWERDOWN, 0xff00);
+	CS_DBGOUT(CS_PM, 9, printk("cs4281: cs4281_ac97_suspend()-\n"));
+}
+
+/****************************************************************************
+*
+*  Resume - power up the part and restore its registers..  
+*
+****************************************************************************/
+void cs4281_ac97_resume(struct cs4281_state *s)
+{
+	int Count,i;
+
+	CS_DBGOUT(CS_PM, 9, printk("cs4281: cs4281_ac97_resume()+\n"));
+
+/* do not save the power state registers at this time
+    //
+    // If we saved away the power control registers, write them into the
+    // shadows so those saved values get restored instead of the current
+    // shadowed value.
+    //
+    if( bPowerStateSaved )
+    {
+        PokeShadow( 0x26, ulSaveReg0x26 );
+        bPowerStateSaved = FALSE;
+    }
+*/
+
+//
+// First, we restore the state of the general purpose register.  This
+// contains the mic select (mic1 or mic2) and if we restore this after
+// we restore the mic volume/boost state and mic2 was selected at
+// suspend time, we will end up with a brief period of time where mic1
+// is selected with the volume/boost settings for mic2, causing
+// acoustic feedback.  So we restore the general purpose register
+// first, thereby getting the correct mic selected before we restore
+// the mic volume/boost.
+//
+	cs4281_write_ac97(s, BA0_AC97_GENERAL_PURPOSE, s->pm.u32AC97_general_purpose);
+
+//
+// Now, while the outputs are still muted, restore the state of power
+// on the AC97 part.
+//
+	cs4281_write_ac97(s, BA0_AC97_POWERDOWN, s->pm.u32AC97_powerdown);
+
+/*
+* Restore just the first set of registers, from register number
+* 0x02 to the register number that ulHighestRegToRestore specifies.
+*/
+	for(	Count = 0x2, i=0; 
+		(Count <= CS4281_AC97_HIGHESTREGTORESTORE)
+			&& (i < CS4281_AC97_NUMBER_RESTORE_REGS); 
+		Count += 2, i++)
+	{
+		cs4281_write_ac97(s, BA0_AC97_RESET + Count, s->pm.ac97[i]);
+	}
+	CS_DBGOUT(CS_PM, 9, printk("cs4281: cs4281_ac97_resume()-\n"));
+}
+
+/* do not save the power state registers at this time
+****************************************************************************
+*
+*  SavePowerState - Save the power registers away. 
+*
+****************************************************************************
+void 
+HWAC97codec::SavePowerState(void)
+{
+    ENTRY(TM_OBJECTCALLS, "HWAC97codec::SavePowerState()\r\n");
+
+    ulSaveReg0x26 = PeekShadow(0x26);
+
+    //
+    // Note that we have saved registers that need to be restored during a
+    // resume instead of ulAC97Regs[].
+    //
+    bPowerStateSaved = TRUE;
+
+} // SavePowerState
+*/
+
+void cs4281_SuspendFIFO(struct cs4281_state *s, struct cs4281_pipeline *pl)
+{
+ /*
+ * We need to save the contents of the BASIC FIFO Registers.
+ */
+	pl->u32FCRn_Save = readl(s->pBA0 + pl->u32FCRnAddress);
+	pl->u32FSICn_Save = readl(s->pBA0 + pl->u32FSICnAddress);
+}
+void cs4281_ResumeFIFO(struct cs4281_state *s, struct cs4281_pipeline *pl)
+{
+ /*
+ * We need to restore the contents of the BASIC FIFO Registers.
+ */
+	writel(pl->u32FCRn_Save,s->pBA0 + pl->u32FCRnAddress);
+	writel(pl->u32FSICn_Save,s->pBA0 + pl->u32FSICnAddress);
+}
+void cs4281_SuspendDMAengine(struct cs4281_state *s, struct cs4281_pipeline *pl)
+{
+	//
+	// We need to save the contents of the BASIC DMA Registers.
+	//
+	pl->u32DBAn_Save = readl(s->pBA0 + pl->u32DBAnAddress);
+	pl->u32DBCn_Save = readl(s->pBA0 + pl->u32DBCnAddress);
+	pl->u32DMRn_Save = readl(s->pBA0 + pl->u32DMRnAddress);
+	pl->u32DCRn_Save = readl(s->pBA0 + pl->u32DCRnAddress);
+	pl->u32DCCn_Save = readl(s->pBA0 + pl->u32DCCnAddress);
+	pl->u32DCAn_Save = readl(s->pBA0 + pl->u32DCAnAddress);
+}
+void cs4281_ResumeDMAengine(struct cs4281_state *s, struct cs4281_pipeline *pl)
+{
+	//
+	// We need to save the contents of the BASIC DMA Registers.
+	//
+	writel( pl->u32DBAn_Save, s->pBA0 + pl->u32DBAnAddress);
+	writel( pl->u32DBCn_Save, s->pBA0 + pl->u32DBCnAddress);
+	writel( pl->u32DMRn_Save, s->pBA0 + pl->u32DMRnAddress);
+	writel( pl->u32DCRn_Save, s->pBA0 + pl->u32DCRnAddress);
+	writel( pl->u32DCCn_Save, s->pBA0 + pl->u32DCCnAddress);
+	writel( pl->u32DCAn_Save, s->pBA0 + pl->u32DCAnAddress);
+}
+
+int cs4281_suspend(struct cs4281_state *s)
+{
+	int i;
+	u32 u32CLKCR1;
+	struct cs4281_pm *pm = &s->pm;
+	CS_DBGOUT(CS_PM | CS_FUNCTION, 9, 
+		printk("cs4281: cs4281_suspend()+ flags=%d\n",
+			(unsigned)s->pm.flags));
+/*
+* check the current state, only suspend if IDLE
+*/
+	if(!(s->pm.flags & CS4281_PM_IDLE))
+	{
+		CS_DBGOUT(CS_PM | CS_ERROR, 2, 
+			printk("cs4281: cs4281_suspend() unable to suspend, not IDLE\n"));
+		return 1;
+	}
+	s->pm.flags &= ~CS4281_PM_IDLE;
+	s->pm.flags |= CS4281_PM_SUSPENDING;
+
+//
+// Gershwin CLKRUN - Set CKRA
+//
+	u32CLKCR1 = readl(s->pBA0 + BA0_CLKCR1);
+
+	pm->u32CLKCR1_SAVE = u32CLKCR1;
+	if(!(u32CLKCR1 & 0x00010000 ) )
+		writel(u32CLKCR1 | 0x00010000, s->pBA0 + BA0_CLKCR1);
+
+//
+// First, turn on the clocks (yikes) to the devices, so that they will
+// respond when we try to save their state.
+//
+	if(!(u32CLKCR1 & CLKCR1_SWCE))
+	{
+		writel(u32CLKCR1 | CLKCR1_SWCE , s->pBA0 + BA0_CLKCR1);
+	}
+    
+	//
+	// Save the power state
+	//
+	pm->u32SSPMValue = readl(s->pBA0 + BA0_SSPM);
+
+	//
+	// Disable interrupts.
+	//
+	writel(HICR_CHGM, s->pBA0 + BA0_HICR);
+
+	//
+	// Save the PCM Playback Left and Right Volume Control.
+	//
+	pm->u32PPLVCvalue = readl(s->pBA0 + BA0_PPLVC);
+	pm->u32PPRVCvalue = readl(s->pBA0 + BA0_PPRVC);
+
+	//
+	// Save the FM Synthesis Left and Right Volume Control.
+	//
+	pm->u32FMLVCvalue = readl(s->pBA0 + BA0_FMLVC);
+	pm->u32FMRVCvalue = readl(s->pBA0 + BA0_FMRVC);
+
+	//
+	// Save the GPIOR value.
+	//
+	pm->u32GPIORvalue = readl(s->pBA0 + BA0_GPIOR);
+
+	//
+	// Save the JSCTL value.
+	//
+	pm->u32JSCTLvalue = readl(s->pBA0 + BA0_GPIOR);
+
+	//
+	// Save Sound System Control Register
+	//
+	pm->u32SSCR = readl(s->pBA0 + BA0_SSCR);
+
+	//
+	// Save SRC Slot Assinment register
+	//
+	pm->u32SRCSA = readl(s->pBA0 + BA0_SRCSA);
+
+	//
+	// Save sample rate
+	//
+	pm->u32DacASR = readl(s->pBA0 + BA0_PASR);
+	pm->u32AdcASR = readl(s->pBA0 + BA0_CASR);
+	pm->u32DacSR = readl(s->pBA0 + BA0_DACSR);
+	pm->u32AdcSR = readl(s->pBA0 + BA0_ADCSR);
+
+	//
+	// Loop through all of the PipeLines 
+	//
+	for(i = 0; i < CS4281_NUMBER_OF_PIPELINES; i++)
+        {
+		if(s->pl[i].flags & CS4281_PIPELINE_VALID)
+		{
+		//
+		// Ask the DMAengines and FIFOs to Suspend.
+		//
+			cs4281_SuspendDMAengine(s,&s->pl[i]);
+			cs4281_SuspendFIFO(s,&s->pl[i]);
+		}
+	}
+	//
+	// We need to save the contents of the Midi Control Register.
+	//
+	pm->u32MIDCR_Save = readl(s->pBA0 + BA0_MIDCR);
+/*
+* save off the AC97 part information
+*/
+	cs4281_ac97_suspend(s);
+    
+	//
+	// Turn off the serial ports.
+	//
+	writel(0, s->pBA0 + BA0_SERMC);
+
+	//
+	// Power off FM, Joystick, AC link, 
+	//
+	writel(0, s->pBA0 + BA0_SSPM);
+
+	//
+	// DLL off.
+	//
+	writel(0, s->pBA0 + BA0_CLKCR1);
+
+	//
+	// AC link off.
+	//
+	writel(0, s->pBA0 + BA0_SPMC);
+
+	//
+	// Put the chip into D3(hot) state.
+	//
+	// PokeBA0(BA0_PMCS, 0x00000003);
+
+	//
+	// Gershwin CLKRUN - Clear CKRA
+	//
+	u32CLKCR1 = readl(s->pBA0 + BA0_CLKCR1);
+	writel(u32CLKCR1 & 0xFFFEFFFF, s->pBA0 + BA0_CLKCR1);
+
+#ifdef CSDEBUG
+	printpm(s);
+	printpipelines(s);
+#endif
+
+	s->pm.flags &= ~CS4281_PM_SUSPENDING;
+	s->pm.flags |= CS4281_PM_SUSPENDED;
+
+	CS_DBGOUT(CS_PM | CS_FUNCTION, 9, 
+		printk("cs4281: cs4281_suspend()- flags=%d\n",
+			(unsigned)s->pm.flags));
+	return 0;
+}
+
+int cs4281_resume(struct cs4281_state *s)
+{
+	int i;
+	unsigned temp1;
+	u32 u32CLKCR1;
+	struct cs4281_pm *pm = &s->pm;
+	CS_DBGOUT(CS_PM | CS_FUNCTION, 4, 
+		printk( "cs4281: cs4281_resume()+ flags=%d\n",
+			(unsigned)s->pm.flags));
+	if(!(s->pm.flags & CS4281_PM_SUSPENDED))
+	{
+		CS_DBGOUT(CS_PM | CS_ERROR, 2, 
+			printk("cs4281: cs4281_resume() unable to resume, not SUSPENDED\n"));
+		return 1;
+	}
+	s->pm.flags &= ~CS4281_PM_SUSPENDED;
+	s->pm.flags |= CS4281_PM_RESUMING;
+
+//
+// Gershwin CLKRUN - Set CKRA
+//
+	u32CLKCR1 = readl(s->pBA0 + BA0_CLKCR1);
+	writel(u32CLKCR1 | 0x00010000, s->pBA0 + BA0_CLKCR1);
+
+	//
+	// set the power state.
+	//
+	//old PokeBA0(BA0_PMCS, 0);
+
+	//
+	// Program the clock circuit and serial ports.
+	//
+	temp1 = cs4281_hw_init(s);
+	if (temp1) {
+		CS_DBGOUT(CS_ERROR | CS_INIT, 1,
+		    printk(KERN_ERR
+			"cs4281: resume cs4281_hw_init() error.\n"));
+		return -1;
+	}
+
+	//
+	// restore the Power state
+	//
+	writel(pm->u32SSPMValue, s->pBA0 + BA0_SSPM);
+
+	//
+	// Set post SRC mix setting (FM or ALT48K)
+	//
+	writel(pm->u32SSPM_BITS, s->pBA0 + BA0_SSPM);
+
+	//
+	// Loop through all of the PipeLines 
+	//
+	for(i = 0; i < CS4281_NUMBER_OF_PIPELINES; i++)
+        {
+		if(s->pl[i].flags & CS4281_PIPELINE_VALID)
+		{
+		//
+		// Ask the DMAengines and FIFOs to Resume.
+		//
+			cs4281_ResumeDMAengine(s,&s->pl[i]);
+			cs4281_ResumeFIFO(s,&s->pl[i]);
+		}
+	}
+	//
+	// We need to restore the contents of the Midi Control Register.
+	//
+	writel(pm->u32MIDCR_Save, s->pBA0 + BA0_MIDCR);
+
+	cs4281_ac97_resume(s);
+	//
+	// Restore the PCM Playback Left and Right Volume Control.
+	//
+	writel(pm->u32PPLVCvalue, s->pBA0 + BA0_PPLVC);
+	writel(pm->u32PPRVCvalue, s->pBA0 + BA0_PPRVC);
+
+	//
+	// Restore the FM Synthesis Left and Right Volume Control.
+	//
+	writel(pm->u32FMLVCvalue, s->pBA0 + BA0_FMLVC);
+	writel(pm->u32FMRVCvalue, s->pBA0 + BA0_FMRVC);
+
+	//
+	// Restore the JSCTL value.
+	//
+	writel(pm->u32JSCTLvalue, s->pBA0 + BA0_JSCTL);
+
+	//
+	// Restore the GPIOR register value.
+	//
+	writel(pm->u32GPIORvalue, s->pBA0 + BA0_GPIOR);
+
+	//
+	// Restore Sound System Control Register
+	//
+	writel(pm->u32SSCR, s->pBA0 + BA0_SSCR);
+
+	//
+	// Restore SRC Slot Assignment register
+	//
+	writel(pm->u32SRCSA, s->pBA0 + BA0_SRCSA);
+
+	//
+	// Restore sample rate
+	//
+	writel(pm->u32DacASR, s->pBA0 + BA0_PASR);
+	writel(pm->u32AdcASR, s->pBA0 + BA0_CASR);
+	writel(pm->u32DacSR, s->pBA0 + BA0_DACSR);
+	writel(pm->u32AdcSR, s->pBA0 + BA0_ADCSR);
+
+	// 
+	// Restore CFL1/2 registers we saved to compensate for OEM bugs.
+	//
+	//	PokeBA0(BA0_CFLR, ulConfig);
+
+	//
+	// Gershwin CLKRUN - Clear CKRA
+	//
+	writel(pm->u32CLKCR1_SAVE, s->pBA0 + BA0_CLKCR1);
+
+	//
+	// Enable interrupts on the part.
+	//
+	writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);
+
+#ifdef CSDEBUG
+	printpm(s);
+	printpipelines(s);
+#endif
+/*
+* change the state, restore the current hwptrs, then stop the dac/adc
+*/
+	s->pm.flags |= CS4281_PM_IDLE;
+	s->pm.flags &= ~(CS4281_PM_SUSPENDING | CS4281_PM_SUSPENDED 
+			| CS4281_PM_RESUMING | CS4281_PM_RESUMED);
+
+	writel(s->pm.u32hwptr_playback, s->pBA0 + BA0_DCA0);
+	writel(s->pm.u32hwptr_capture, s->pBA0 + BA0_DCA1);
+	start_dac(s);
+	start_adc(s);
+
+	CS_DBGOUT(CS_PM | CS_FUNCTION, 9, printk("cs4281: cs4281_resume()- flags=%d\n",
+		(unsigned)s->pm.flags));
+	return 0;
+}
+
+#endif
+
+//******************************************************************************
+// "cs4281_play_rate()" --
+//******************************************************************************
+static void cs4281_play_rate(struct cs4281_state *card, u32 playrate)
+{
+	u32 DACSRvalue = 1;
+
+	// Based on the sample rate, program the DACSR register.
+	if (playrate == 8000)
+		DACSRvalue = 5;
+	if (playrate == 11025)
+		DACSRvalue = 4;
+	else if (playrate == 22050)
+		DACSRvalue = 2;
+	else if (playrate == 44100)
+		DACSRvalue = 1;
+	else if ((playrate <= 48000) && (playrate >= 6023))
+		DACSRvalue = 24576000 / (playrate * 16);
+	else if (playrate < 6023)
+		// Not allowed by open.
+		return;
+	else if (playrate > 48000)
+		// Not allowed by open.
+		return;
+	CS_DBGOUT(CS_WAVE_WRITE | CS_PARMS, 2, printk(KERN_INFO
+		"cs4281: cs4281_play_rate(): DACSRvalue=0x%.8x playrate=%d\n",
+			DACSRvalue, playrate));
+	//  Write the 'sample rate select code'
+	//  to the 'DAC Sample Rate' register.
+	writel(DACSRvalue, card->pBA0 + BA0_DACSR);	// (744h)
+}
+
+//******************************************************************************
+// "cs4281_record_rate()" -- Initialize the record sample rate converter.
+//******************************************************************************
+static void cs4281_record_rate(struct cs4281_state *card, u32 outrate)
+{
+	u32 ADCSRvalue = 1;
+
+	//
+	// Based on the sample rate, program the ADCSR register
+	//
+	if (outrate == 8000)
+		ADCSRvalue = 5;
+	if (outrate == 11025)
+		ADCSRvalue = 4;
+	else if (outrate == 22050)
+		ADCSRvalue = 2;
+	else if (outrate == 44100)
+		ADCSRvalue = 1;
+	else if ((outrate <= 48000) && (outrate >= 6023))
+		ADCSRvalue = 24576000 / (outrate * 16);
+	else if (outrate < 6023) {
+		// Not allowed by open.
+		return;
+	} else if (outrate > 48000) {
+		// Not allowed by open.
+		return;
+	}
+	CS_DBGOUT(CS_WAVE_READ | CS_PARMS, 2, printk(KERN_INFO
+		"cs4281: cs4281_record_rate(): ADCSRvalue=0x%.8x outrate=%d\n",
+			ADCSRvalue, outrate));
+	//  Write the 'sample rate select code
+	//  to the 'ADC Sample Rate' register.
+	writel(ADCSRvalue, card->pBA0 + BA0_ADCSR);	// (748h)
+}
+
+
+
+static void stop_dac(struct cs4281_state *s)
+{
+	unsigned long flags;
+	unsigned temp1;
+
+	CS_DBGOUT(CS_WAVE_WRITE, 3, printk(KERN_INFO "cs4281: stop_dac():\n"));
+	spin_lock_irqsave(&s->lock, flags);
+	s->ena &= ~FMODE_WRITE;
+	temp1 = readl(s->pBA0 + BA0_DCR0) | DCRn_MSK;
+	writel(temp1, s->pBA0 + BA0_DCR0);
+
+	spin_unlock_irqrestore(&s->lock, flags);
+}
+
+
+static void start_dac(struct cs4281_state *s)
+{
+	unsigned long flags;
+	unsigned temp1;
+
+	CS_DBGOUT(CS_FUNCTION, 3, printk(KERN_INFO "cs4281: start_dac()+\n"));
+	spin_lock_irqsave(&s->lock, flags);
+	if (!(s->ena & FMODE_WRITE) && (s->dma_dac.mapped ||
+					(s->dma_dac.count > 0
+	    				&& s->dma_dac.ready))
+#ifndef NOT_CS4281_PM
+	&& (s->pm.flags & CS4281_PM_IDLE))
+#else
+)
+#endif
+ {
+		s->ena |= FMODE_WRITE;
+		temp1 = readl(s->pBA0 + BA0_DCR0) & ~DCRn_MSK;	// Clear DMA0 channel mask.
+		writel(temp1, s->pBA0 + BA0_DCR0);	// Start DMA'ing.
+		writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);	// Enable interrupts.              
+
+		writel(7, s->pBA0 + BA0_PPRVC);
+		writel(7, s->pBA0 + BA0_PPLVC);
+		CS_DBGOUT(CS_WAVE_WRITE | CS_PARMS, 8, printk(KERN_INFO
+			"cs4281: start_dac(): writel 0x%x start dma\n", temp1));
+
+	}
+	spin_unlock_irqrestore(&s->lock, flags);
+	CS_DBGOUT(CS_FUNCTION, 3,
+		  printk(KERN_INFO "cs4281: start_dac()-\n"));
+}
+
+
+static void stop_adc(struct cs4281_state *s)
+{
+	unsigned long flags;
+	unsigned temp1;
+
+	CS_DBGOUT(CS_FUNCTION, 3,
+		  printk(KERN_INFO "cs4281: stop_adc()+\n"));
+
+	spin_lock_irqsave(&s->lock, flags);
+	s->ena &= ~FMODE_READ;
+
+	if (s->conversion == 1) {
+		s->conversion = 0;
+		s->prop_adc.fmt = s->prop_adc.fmt_original;
+	}
+	temp1 = readl(s->pBA0 + BA0_DCR1) | DCRn_MSK;
+	writel(temp1, s->pBA0 + BA0_DCR1);
+	spin_unlock_irqrestore(&s->lock, flags);
+	CS_DBGOUT(CS_FUNCTION, 3,
+		  printk(KERN_INFO "cs4281: stop_adc()-\n"));
+}
+
+
+static void start_adc(struct cs4281_state *s)
+{
+	unsigned long flags;
+	unsigned temp1;
+
+	CS_DBGOUT(CS_FUNCTION, 2,
+		  printk(KERN_INFO "cs4281: start_adc()+\n"));
+
+	if (!(s->ena & FMODE_READ) &&
+	    (s->dma_adc.mapped || s->dma_adc.count <=
+	     (signed) (s->dma_adc.dmasize - 2 * s->dma_adc.fragsize))
+	    && s->dma_adc.ready
+#ifndef NOT_CS4281_PM
+	&& (s->pm.flags & CS4281_PM_IDLE))
+#else
+) 
+#endif
+	{
+		if (s->prop_adc.fmt & AFMT_S8 || s->prop_adc.fmt & AFMT_U8) {
+			// 
+			// now only use 16 bit capture, due to truncation issue
+			// in the chip, noticable distortion occurs.
+			// allocate buffer and then convert from 16 bit to 
+			// 8 bit for the user buffer.
+			//
+			s->prop_adc.fmt_original = s->prop_adc.fmt;
+			if (s->prop_adc.fmt & AFMT_S8) {
+				s->prop_adc.fmt &= ~AFMT_S8;
+				s->prop_adc.fmt |= AFMT_S16_LE;
+			}
+			if (s->prop_adc.fmt & AFMT_U8) {
+				s->prop_adc.fmt &= ~AFMT_U8;
+				s->prop_adc.fmt |= AFMT_U16_LE;
+			}
+			//
+			// prog_dmabuf_adc performs a stop_adc() but that is
+			// ok since we really haven't started the DMA yet.
+			//
+			prog_codec(s, CS_TYPE_ADC);
+
+			if (prog_dmabuf_adc(s) != 0) {
+				CS_DBGOUT(CS_ERROR, 2, printk(KERN_INFO
+					 "cs4281: start_adc(): error in prog_dmabuf_adc\n"));
+			}
+			s->conversion = 1;
+		}
+		spin_lock_irqsave(&s->lock, flags);
+		s->ena |= FMODE_READ;
+		temp1 = readl(s->pBA0 + BA0_DCR1) & ~DCRn_MSK;	// Clear DMA1 channel mask bit.
+		writel(temp1, s->pBA0 + BA0_DCR1);	// Start recording
+		writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);	// Enable interrupts.
+		spin_unlock_irqrestore(&s->lock, flags);
+
+		CS_DBGOUT(CS_PARMS, 6, printk(KERN_INFO
+			 "cs4281: start_adc(): writel 0x%x \n", temp1));
+	}
+	CS_DBGOUT(CS_FUNCTION, 2,
+		  printk(KERN_INFO "cs4281: start_adc()-\n"));
+
+}
+
+
+// --------------------------------------------------------------------- 
+
+#define DMABUF_MINORDER 1	// ==> min buffer size = 8K.
+
+
+extern void dealloc_dmabuf(struct cs4281_state *s, struct dmabuf *db)
+{
+	struct page *map, *mapend;
+
+	if (db->rawbuf) {
+		// Undo prog_dmabuf()'s marking the pages as reserved 
+		mapend =
+		    virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) -
+				 1);
+		for (map = virt_to_page(db->rawbuf); map <= mapend; map++)
+			cs4x_mem_map_unreserve(map);
+		free_dmabuf(s, db);
+	}
+	if (s->tmpbuff && (db->type == CS_TYPE_ADC)) {
+		// Undo prog_dmabuf()'s marking the pages as reserved 
+		mapend =
+		    virt_to_page(s->tmpbuff +
+				 (PAGE_SIZE << s->buforder_tmpbuff) - 1);
+		for (map = virt_to_page(s->tmpbuff); map <= mapend; map++)
+			cs4x_mem_map_unreserve(map);
+		free_dmabuf2(s, db);
+	}
+	s->tmpbuff = NULL;
+	db->rawbuf = NULL;
+	db->mapped = db->ready = 0;
+}
+
+static int prog_dmabuf(struct cs4281_state *s, struct dmabuf *db)
+{
+	int order;
+	unsigned bytespersec, temp1;
+	unsigned bufs, sample_shift = 0;
+	struct page *map, *mapend;
+	unsigned long df;
+
+	CS_DBGOUT(CS_FUNCTION, 2,
+		  printk(KERN_INFO "cs4281: prog_dmabuf()+\n"));
+	db->hwptr = db->swptr = db->total_bytes = db->count = db->error =
+	    db->endcleared = db->blocks = db->wakeup = db->underrun = 0;
+/*
+* check for order within limits, but do not overwrite value, check
+* later for a fractional defaultorder (i.e. 100+).
+*/
+	if((defaultorder > 0) && (defaultorder < 12))
+		df = defaultorder;
+	else
+		df = 1;	
+
+	if (!db->rawbuf) {
+		db->ready = db->mapped = 0;
+		for (order = df; order >= DMABUF_MINORDER; order--)
+			if ( (db->rawbuf = (void *) pci_alloc_consistent(
+				s->pcidev, PAGE_SIZE << order, &db-> dmaaddr)))
+				    break;
+		if (!db->rawbuf) {
+			CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
+				"cs4281: prog_dmabuf(): unable to allocate rawbuf\n"));
+			return -ENOMEM;
+		}
+		db->buforder = order;
+		// Now mark the pages as reserved; otherwise the 
+		// remap_page_range() in cs4281_mmap doesn't work.
+		// 1. get index to last page in mem_map array for rawbuf.
+		mapend = virt_to_page(db->rawbuf + 
+			(PAGE_SIZE << db->buforder) - 1);
+
+		// 2. mark each physical page in range as 'reserved'.
+		for (map = virt_to_page(db->rawbuf); map <= mapend; map++)
+			cs4x_mem_map_reserve(map);
+	}
+	if (!s->tmpbuff && (db->type == CS_TYPE_ADC)) {
+		for (order = df; order >= DMABUF_MINORDER;
+		     order--)
+			if ( (s->tmpbuff = (void *) pci_alloc_consistent(
+					s->pcidev, PAGE_SIZE << order, 
+					&s->dmaaddr_tmpbuff)))
+				    break;
+		if (!s->tmpbuff) {
+			CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
+				"cs4281: prog_dmabuf(): unable to allocate tmpbuff\n"));
+			return -ENOMEM;
+		}
+		s->buforder_tmpbuff = order;
+		// Now mark the pages as reserved; otherwise the 
+		// remap_page_range() in cs4281_mmap doesn't work.
+		// 1. get index to last page in mem_map array for rawbuf.
+		mapend = virt_to_page(s->tmpbuff + 
+				(PAGE_SIZE << s->buforder_tmpbuff) - 1);
+
+		// 2. mark each physical page in range as 'reserved'.
+		for (map = virt_to_page(s->tmpbuff); map <= mapend; map++)
+			cs4x_mem_map_reserve(map);
+	}
+	if (db->type == CS_TYPE_DAC) {
+		if (s->prop_dac.fmt & (AFMT_S16_LE | AFMT_U16_LE))
+			sample_shift++;
+		if (s->prop_dac.channels > 1)
+			sample_shift++;
+		bytespersec = s->prop_dac.rate << sample_shift;
+	} else			// CS_TYPE_ADC
+	{
+		if (s->prop_adc.fmt & (AFMT_S16_LE | AFMT_U16_LE))
+			sample_shift++;
+		if (s->prop_adc.channels > 1)
+			sample_shift++;
+		bytespersec = s->prop_adc.rate << sample_shift;
+	}
+	bufs = PAGE_SIZE << db->buforder;
+
+/*
+* added fractional "defaultorder" inputs. if >100 then use 
+* defaultorder-100 as power of 2 for the buffer size. example:
+* 106 = 2^(106-100) = 2^6 = 64 bytes for the buffer size.
+*/
+	if(defaultorder >= 100)
+	{
+		bufs = 1 << (defaultorder-100);
+	}
+
+#define INTERRUPT_RATE_MS       100	// Interrupt rate in milliseconds.
+	db->numfrag = 2;
+/* 
+* Nominal frag size(bytes/interrupt)
+*/
+	temp1 = bytespersec / (1000 / INTERRUPT_RATE_MS);
+	db->fragshift = 8;	// Min 256 bytes.
+	while (1 << db->fragshift < temp1)	// Calc power of 2 frag size.
+		db->fragshift += 1;
+	db->fragsize = 1 << db->fragshift;
+	db->dmasize = db->fragsize * 2;
+	db->fragsamples = db->fragsize >> sample_shift;	// # samples/fragment.
+
+// If the calculated size is larger than the allocated
+//  buffer, divide the allocated buffer into 2 fragments.
+	if (db->dmasize > bufs) {
+
+		db->numfrag = 2;	// Two fragments.
+		db->fragsize = bufs >> 1;	// Each 1/2 the alloc'ed buffer.
+		db->fragsamples = db->fragsize >> sample_shift;	// # samples/fragment.
+		db->dmasize = bufs;	// Use all the alloc'ed buffer.
+
+		db->fragshift = 0;	// Calculate 'fragshift'.
+		temp1 = db->fragsize;	// update_ptr() uses it 
+		while ((temp1 >>= 1) > 1)	// to calc 'total-bytes'
+			db->fragshift += 1;	// returned in DSP_GETI/OPTR. 
+	}
+	CS_DBGOUT(CS_PARMS, 3, printk(KERN_INFO
+		"cs4281: prog_dmabuf(): numfrag=%d fragsize=%d fragsamples=%d fragshift=%d bufs=%d fmt=0x%x ch=%d\n",
+			db->numfrag, db->fragsize, db->fragsamples, 
+			db->fragshift, bufs, 
+			(db->type == CS_TYPE_DAC) ? s->prop_dac.fmt : 
+				s->prop_adc.fmt, 
+			(db->type == CS_TYPE_DAC) ? s->prop_dac.channels : 
+				s->prop_adc.channels));
+	CS_DBGOUT(CS_FUNCTION, 2,
+		  printk(KERN_INFO "cs4281: prog_dmabuf()-\n"));
+	return 0;
+}
+
+
+static int prog_dmabuf_adc(struct cs4281_state *s)
+{
+	unsigned long va;
+	unsigned count;
+	int c;
+	stop_adc(s);
+	s->dma_adc.type = CS_TYPE_ADC;
+	if ((c = prog_dmabuf(s, &s->dma_adc)))
+		return c;
+
+	if (s->dma_adc.rawbuf) {
+		memset(s->dma_adc.rawbuf,
+		       (s->prop_adc.
+			fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0,
+		       s->dma_adc.dmasize);
+	}
+	if (s->tmpbuff) {
+		memset(s->tmpbuff,
+		       (s->prop_adc.
+			fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0,
+		       PAGE_SIZE << s->buforder_tmpbuff);
+	}
+
+	va = virt_to_bus(s->dma_adc.rawbuf);
+
+	count = s->dma_adc.dmasize;
+
+	if (s->prop_adc.
+	    fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE))
+		    count /= 2;	// 16-bit.
+
+	if (s->prop_adc.channels > 1)
+		count /= 2;	// Assume stereo.
+
+	CS_DBGOUT(CS_WAVE_READ, 3, printk(KERN_INFO
+		"cs4281: prog_dmabuf_adc(): count=%d va=0x%.8x\n",
+			count, (unsigned) va));
+
+	writel(va, s->pBA0 + BA0_DBA1);	// Set buffer start address.
+	writel(count - 1, s->pBA0 + BA0_DBC1);	// Set count. 
+	s->dma_adc.ready = 1;
+	return 0;
+}
+
+
+static int prog_dmabuf_dac(struct cs4281_state *s)
+{
+	unsigned long va;
+	unsigned count;
+	int c;
+	stop_dac(s);
+	s->dma_dac.type = CS_TYPE_DAC;
+	if ((c = prog_dmabuf(s, &s->dma_dac)))
+		return c;
+	memset(s->dma_dac.rawbuf,
+	       (s->prop_dac.fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0,
+	       s->dma_dac.dmasize);
+
+	va = virt_to_bus(s->dma_dac.rawbuf);
+
+	count = s->dma_dac.dmasize;
+	if (s->prop_dac.
+	    fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE))
+		    count /= 2;	// 16-bit.
+
+	if (s->prop_dac.channels > 1)
+		count /= 2;	// Assume stereo.
+
+	writel(va, s->pBA0 + BA0_DBA0);	// Set buffer start address.
+	writel(count - 1, s->pBA0 + BA0_DBC0);	// Set count.             
+
+	CS_DBGOUT(CS_WAVE_WRITE, 3, printk(KERN_INFO
+		"cs4281: prog_dmabuf_dac(): count=%d va=0x%.8x\n",
+			count, (unsigned) va));
+
+	s->dma_dac.ready = 1;
+	return 0;
+}
+
+
+static void clear_advance(void *buf, unsigned bsize, unsigned bptr,
+			  unsigned len, unsigned char c)
+{
+	if (bptr + len > bsize) {
+		unsigned x = bsize - bptr;
+		memset(((char *) buf) + bptr, c, x);
+		bptr = 0;
+		len -= x;
+	}
+	CS_DBGOUT(CS_WAVE_WRITE, 4, printk(KERN_INFO
+		"cs4281: clear_advance(): memset %d at 0x%.8x for %d size \n",
+			(unsigned)c, (unsigned)((char *) buf) + bptr, len));
+	memset(((char *) buf) + bptr, c, len);
+}
+
+
+
+// call with spinlock held! 
+static void cs4281_update_ptr(struct cs4281_state *s, int intflag)
+{
+	int diff;
+	unsigned hwptr, va;
+
+	// update ADC pointer 
+	if (s->ena & FMODE_READ) {
+		hwptr = readl(s->pBA0 + BA0_DCA1);	// Read capture DMA address.
+		va = virt_to_bus(s->dma_adc.rawbuf);
+		hwptr -= (unsigned) va;
+		diff =
+		    (s->dma_adc.dmasize + hwptr -
+		     s->dma_adc.hwptr) % s->dma_adc.dmasize;
+		s->dma_adc.hwptr = hwptr;
+		s->dma_adc.total_bytes += diff;
+		s->dma_adc.count += diff;
+		if (s->dma_adc.count > s->dma_adc.dmasize)
+			s->dma_adc.count = s->dma_adc.dmasize;
+		if (s->dma_adc.mapped) {
+			if (s->dma_adc.count >=
+			    (signed) s->dma_adc.fragsize) wake_up(&s->
+								  dma_adc.
+								  wait);
+		} else {
+			if (s->dma_adc.count > 0)
+				wake_up(&s->dma_adc.wait);
+		}
+		CS_DBGOUT(CS_PARMS, 8, printk(KERN_INFO
+			"cs4281: cs4281_update_ptr(): s=0x%.8x hwptr=%d total_bytes=%d count=%d \n",
+				(unsigned)s, s->dma_adc.hwptr, 
+				s->dma_adc.total_bytes, s->dma_adc.count));
+	}
+	// update DAC pointer 
+	//
+	// check for end of buffer, means that we are going to wait for another interrupt
+	// to allow silence to fill the fifos on the part, to keep pops down to a minimum.
+	//
+	if (s->ena & FMODE_WRITE) {
+		hwptr = readl(s->pBA0 + BA0_DCA0);	// Read play DMA address.
+		va = virt_to_bus(s->dma_dac.rawbuf);
+		hwptr -= (unsigned) va;
+		diff = (s->dma_dac.dmasize + hwptr -
+		     s->dma_dac.hwptr) % s->dma_dac.dmasize;
+		s->dma_dac.hwptr = hwptr;
+		s->dma_dac.total_bytes += diff;
+		if (s->dma_dac.mapped) {
+			s->dma_dac.count += diff;
+			if (s->dma_dac.count >= s->dma_dac.fragsize) {
+				s->dma_dac.wakeup = 1;
+				wake_up(&s->dma_dac.wait);
+				if (s->dma_dac.count > s->dma_dac.dmasize)
+					s->dma_dac.count &=
+					    s->dma_dac.dmasize - 1;
+			}
+		} else {
+			s->dma_dac.count -= diff;
+			if (s->dma_dac.count <= 0) {
+				//
+				// fill with silence, and do not shut down the DAC.
+				// Continue to play silence until the _release.
+				//
+				CS_DBGOUT(CS_WAVE_WRITE, 6, printk(KERN_INFO
+					"cs4281: cs4281_update_ptr(): memset %d at 0x%.8x for %d size \n",
+						(unsigned)(s->prop_dac.fmt & 
+						(AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0, 
+						(unsigned)s->dma_dac.rawbuf, 
+						s->dma_dac.dmasize));
+				memset(s->dma_dac.rawbuf,
+				       (s->prop_dac.
+					fmt & (AFMT_U8 | AFMT_U16_LE)) ?
+				       0x80 : 0, s->dma_dac.dmasize);
+				if (s->dma_dac.count < 0) {
+					s->dma_dac.underrun = 1;
+					s->dma_dac.count = 0;
+					CS_DBGOUT(CS_ERROR, 9, printk(KERN_INFO
+					 "cs4281: cs4281_update_ptr(): underrun\n"));
+				}
+			} else if (s->dma_dac.count <=
+				   (signed) s->dma_dac.fragsize
+				   && !s->dma_dac.endcleared) {
+				clear_advance(s->dma_dac.rawbuf,
+					      s->dma_dac.dmasize,
+					      s->dma_dac.swptr,
+					      s->dma_dac.fragsize,
+					      (s->prop_dac.
+					       fmt & (AFMT_U8 |
+						      AFMT_U16_LE)) ? 0x80
+					      : 0);
+				s->dma_dac.endcleared = 1;
+			}
+			if ( (s->dma_dac.count <= (signed) s->dma_dac.dmasize/2) ||
+				intflag)
+			{
+				wake_up(&s->dma_dac.wait);
+			}
+		}
+		CS_DBGOUT(CS_PARMS, 8, printk(KERN_INFO
+			"cs4281: cs4281_update_ptr(): s=0x%.8x hwptr=%d total_bytes=%d count=%d \n",
+				(unsigned) s, s->dma_dac.hwptr, 
+				s->dma_dac.total_bytes, s->dma_dac.count));
+	}
+}
+
+
+// --------------------------------------------------------------------- 
+
+static void prog_codec(struct cs4281_state *s, unsigned type)
+{
+	unsigned long flags;
+	unsigned temp1, format;
+
+	CS_DBGOUT(CS_FUNCTION, 2,
+		  printk(KERN_INFO "cs4281: prog_codec()+ \n"));
+
+	spin_lock_irqsave(&s->lock, flags);
+	if (type == CS_TYPE_ADC) {
+		temp1 = readl(s->pBA0 + BA0_DCR1);
+		writel(temp1 | DCRn_MSK, s->pBA0 + BA0_DCR1);	// Stop capture DMA, if active.
+
+		// program sampling rates  
+		// Note, for CS4281, capture & play rates can be set independently.
+		cs4281_record_rate(s, s->prop_adc.rate);
+
+		// program ADC parameters 
+		format = DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE;
+		if (s->prop_adc.
+		    fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE)) {	// 16-bit
+			if (s->prop_adc.fmt & (AFMT_S16_BE | AFMT_U16_BE))	// Big-endian?
+				format |= DMRn_BEND;
+			if (s->prop_adc.fmt & (AFMT_U16_LE | AFMT_U16_BE))
+				format |= DMRn_USIGN;	// Unsigned.      
+		} else
+			format |= DMRn_SIZE8 | DMRn_USIGN;	// 8-bit, unsigned
+		if (s->prop_adc.channels < 2)
+			format |= DMRn_MONO;
+
+		writel(format, s->pBA0 + BA0_DMR1);
+
+		CS_DBGOUT(CS_PARMS, 2, printk(KERN_INFO
+			"cs4281: prog_codec(): adc %s %s %s rate=%d DMR0 format=0x%.8x\n",
+				(format & DMRn_SIZE8) ? "8" : "16",
+				(format & DMRn_USIGN) ?  "Unsigned" : "Signed", 
+				(format & DMRn_MONO) ? "Mono" : "Stereo", 
+				s->prop_adc.rate, format));
+
+		s->ena &= ~FMODE_READ;	// not capturing data yet
+	}
+
+
+	if (type == CS_TYPE_DAC) {
+		temp1 = readl(s->pBA0 + BA0_DCR0);
+		writel(temp1 | DCRn_MSK, s->pBA0 + BA0_DCR0);	// Stop play DMA, if active.
+
+		// program sampling rates  
+		// Note, for CS4281, capture & play rates can be set independently.
+		cs4281_play_rate(s, s->prop_dac.rate);
+
+		// program DAC parameters 
+		format = DMRn_DMA | DMRn_AUTO | DMRn_TR_READ;
+		if (s->prop_dac.
+		    fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE)) {	// 16-bit
+			if (s->prop_dac.fmt & (AFMT_S16_BE | AFMT_U16_BE))
+				format |= DMRn_BEND;	// Big Endian.
+			if (s->prop_dac.fmt & (AFMT_U16_LE | AFMT_U16_BE))
+				format |= DMRn_USIGN;	// Unsigned.      
+		} else
+			format |= DMRn_SIZE8 | DMRn_USIGN;	// 8-bit, unsigned
+
+		if (s->prop_dac.channels < 2)
+			format |= DMRn_MONO;
+
+		writel(format, s->pBA0 + BA0_DMR0);
+
+
+		CS_DBGOUT(CS_PARMS, 2, printk(KERN_INFO
+			"cs4281: prog_codec(): dac %s %s %s rate=%d DMR0 format=0x%.8x\n",
+				(format & DMRn_SIZE8) ? "8" : "16",
+				(format & DMRn_USIGN) ?  "Unsigned" : "Signed",
+				(format & DMRn_MONO) ? "Mono" : "Stereo", 
+				s->prop_dac.rate, format));
+
+		s->ena &= ~FMODE_WRITE;	// not capturing data yet
+
+	}
+	spin_unlock_irqrestore(&s->lock, flags);
+	CS_DBGOUT(CS_FUNCTION, 2,
+		  printk(KERN_INFO "cs4281: prog_codec()- \n"));
+}
+
+
+static int mixer_ioctl(struct cs4281_state *s, unsigned int cmd,
+		       unsigned long arg)
+{
+	// Index to mixer_src[] is value of AC97 Input Mux Select Reg.
+	// Value of array member is recording source Device ID Mask.
+	static const unsigned int mixer_src[8] = {
+		SOUND_MASK_MIC, SOUND_MASK_CD, 0, SOUND_MASK_LINE1,
+		SOUND_MASK_LINE, SOUND_MASK_VOLUME, 0, 0
+	};
+
+	// Index of mixtable1[] member is Device ID 
+	// and must be <= SOUND_MIXER_NRDEVICES.
+	// Value of array member is index into s->mix.vol[]
+	static const unsigned char mixtable1[SOUND_MIXER_NRDEVICES] = {
+		[SOUND_MIXER_PCM] = 1,	// voice 
+		[SOUND_MIXER_LINE1] = 2,	// AUX
+		[SOUND_MIXER_CD] = 3,	// CD 
+		[SOUND_MIXER_LINE] = 4,	// Line 
+		[SOUND_MIXER_SYNTH] = 5,	// FM
+		[SOUND_MIXER_MIC] = 6,	// Mic 
+		[SOUND_MIXER_SPEAKER] = 7,	// Speaker 
+		[SOUND_MIXER_RECLEV] = 8,	// Recording level 
+		[SOUND_MIXER_VOLUME] = 9	// Master Volume 
+	};
+
+
+	static const unsigned mixreg[] = {
+		BA0_AC97_PCM_OUT_VOLUME,
+		BA0_AC97_AUX_VOLUME,
+		BA0_AC97_CD_VOLUME,
+		BA0_AC97_LINE_IN_VOLUME
+	};
+	unsigned char l, r, rl, rr, vidx;
+	unsigned char attentbl[11] =
+	    { 63, 42, 26, 17, 14, 11, 8, 6, 4, 2, 0 };
+	unsigned temp1;
+	int i, val;
+
+	VALIDATE_STATE(s);
+	CS_DBGOUT(CS_FUNCTION, 4, printk(KERN_INFO
+		 "cs4281: mixer_ioctl(): s=0x%.8x cmd=0x%.8x\n",
+			 (unsigned) s, cmd));
+#if CSDEBUG
+	cs_printioctl(cmd);
+#endif
+#if CSDEBUG_INTERFACE
+
+	if ((cmd == SOUND_MIXER_CS_GETDBGMASK) ||
+	    (cmd == SOUND_MIXER_CS_SETDBGMASK) ||
+	    (cmd == SOUND_MIXER_CS_GETDBGLEVEL) ||
+	    (cmd == SOUND_MIXER_CS_SETDBGLEVEL) ||
+	    (cmd == SOUND_MIXER_CS_APM))
+	{
+		switch (cmd) {
+
+		case SOUND_MIXER_CS_GETDBGMASK:
+			return put_user(cs_debugmask,
+					(unsigned long *) arg);
+
+		case SOUND_MIXER_CS_GETDBGLEVEL:
+			return put_user(cs_debuglevel,
+					(unsigned long *) arg);
+
+		case SOUND_MIXER_CS_SETDBGMASK:
+			if (get_user(val, (unsigned long *) arg))
+				return -EFAULT;
+			cs_debugmask = val;
+			return 0;
+
+		case SOUND_MIXER_CS_SETDBGLEVEL:
+			if (get_user(val, (unsigned long *) arg))
+				return -EFAULT;
+			cs_debuglevel = val;
+			return 0;
+#ifndef NOT_CS4281_PM
+		case SOUND_MIXER_CS_APM:
+			if (get_user(val, (unsigned long *) arg))
+				return -EFAULT;
+			if(val == CS_IOCTL_CMD_SUSPEND)
+				cs4281_suspend(s);
+			else if(val == CS_IOCTL_CMD_RESUME)
+				cs4281_resume(s);
+			else
+			{
+				CS_DBGOUT(CS_ERROR, 1, printk(KERN_INFO
+				    "cs4281: mixer_ioctl(): invalid APM cmd (%d)\n",
+					val));
+			}
+			return 0;
+#endif
+		default:
+			CS_DBGOUT(CS_ERROR, 1, printk(KERN_INFO
+				"cs4281: mixer_ioctl(): ERROR unknown debug cmd\n"));
+			return 0;
+		}
+	}
+#endif
+
+	if (cmd == SOUND_MIXER_PRIVATE1) {
+		// enable/disable/query mixer preamp 
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (val != -1) {
+			cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1);
+			temp1 = val ? (temp1 | 0x40) : (temp1 & 0xffbf);
+			cs4281_write_ac97(s, BA0_AC97_MIC_VOLUME, temp1);
+		}
+		cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1);
+		val = (temp1 & 0x40) ? 1 : 0;
+		return put_user(val, (int *) arg);
+	}
+	if (cmd == SOUND_MIXER_PRIVATE2) {
+		// enable/disable/query spatializer 
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (val != -1) {
+			temp1 = (val & 0x3f) >> 2;
+			cs4281_write_ac97(s, BA0_AC97_3D_CONTROL, temp1);
+			cs4281_read_ac97(s, BA0_AC97_GENERAL_PURPOSE,
+					 &temp1);
+			cs4281_write_ac97(s, BA0_AC97_GENERAL_PURPOSE,
+					  temp1 | 0x2000);
+		}
+		cs4281_read_ac97(s, BA0_AC97_3D_CONTROL, &temp1);
+		return put_user((temp1 << 2) | 3, (int *) arg);
+	}
+	if (cmd == SOUND_MIXER_INFO) {
+		mixer_info info;
+		strncpy(info.id, "CS4281", sizeof(info.id));
+		strncpy(info.name, "Crystal CS4281", sizeof(info.name));
+		info.modify_counter = s->mix.modcnt;
+		if (copy_to_user((void *) arg, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
+	}
+	if (cmd == SOUND_OLD_MIXER_INFO) {
+		_old_mixer_info info;
+		strncpy(info.id, "CS4281", sizeof(info.id));
+		strncpy(info.name, "Crystal CS4281", sizeof(info.name));
+		if (copy_to_user((void *) arg, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
+	}
+	if (cmd == OSS_GETVERSION)
+		return put_user(SOUND_VERSION, (int *) arg);
+
+	if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
+		return -EINVAL;
+
+	// If ioctl has only the SIOC_READ bit(bit 31)
+	// on, process the only-read commands. 
+	if (_SIOC_DIR(cmd) == _SIOC_READ) {
+		switch (_IOC_NR(cmd)) {
+		case SOUND_MIXER_RECSRC:	// Arg contains a bit for each recording source 
+			cs4281_read_ac97(s, BA0_AC97_RECORD_SELECT,
+					 &temp1);
+			return put_user(mixer_src[temp1 & 7], (int *) arg);
+
+		case SOUND_MIXER_DEVMASK:	// Arg contains a bit for each supported device 
+			return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH |
+					SOUND_MASK_CD | SOUND_MASK_LINE |
+					SOUND_MASK_LINE1 | SOUND_MASK_MIC |
+					SOUND_MASK_VOLUME |
+					SOUND_MASK_RECLEV |
+					SOUND_MASK_SPEAKER, (int *) arg);
+
+		case SOUND_MIXER_RECMASK:	// Arg contains a bit for each supported recording source 
+			return put_user(SOUND_MASK_LINE | SOUND_MASK_MIC |
+					SOUND_MASK_CD | SOUND_MASK_VOLUME |
+					SOUND_MASK_LINE1, (int *) arg);
+
+		case SOUND_MIXER_STEREODEVS:	// Mixer channels supporting stereo 
+			return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH |
+					SOUND_MASK_CD | SOUND_MASK_LINE |
+					SOUND_MASK_LINE1 | SOUND_MASK_MIC |
+					SOUND_MASK_VOLUME |
+					SOUND_MASK_RECLEV, (int *) arg);
+
+		case SOUND_MIXER_CAPS:
+			return put_user(SOUND_CAP_EXCL_INPUT, (int *) arg);
+
+		default:
+			i = _IOC_NR(cmd);
+			if (i >= SOUND_MIXER_NRDEVICES
+			    || !(vidx = mixtable1[i]))
+				return -EINVAL;
+			return put_user(s->mix.vol[vidx - 1], (int *) arg);
+		}
+	}
+	// If ioctl doesn't have both the SIOC_READ and 
+	// the SIOC_WRITE bit set, return invalid.
+	if (_SIOC_DIR(cmd) != (_SIOC_READ | _SIOC_WRITE))
+		return -EINVAL;
+
+	// Increment the count of volume writes.
+	s->mix.modcnt++;
+
+	// Isolate the command; it must be a write.
+	switch (_IOC_NR(cmd)) {
+
+	case SOUND_MIXER_RECSRC:	// Arg contains a bit for each recording source 
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		i = hweight32(val);	// i = # bits on in val.
+		if (i != 1)	// One & only 1 bit must be on.
+			return 0;
+		for (i = 0; i < sizeof(mixer_src) / sizeof(int); i++) {
+			if (val == mixer_src[i]) {
+				temp1 = (i << 8) | i;
+				cs4281_write_ac97(s,
+						  BA0_AC97_RECORD_SELECT,
+						  temp1);
+				return 0;
+			}
+		}
+		return 0;
+
+	case SOUND_MIXER_VOLUME:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		l = val & 0xff;
+		if (l > 100)
+			l = 100;	// Max soundcard.h vol is 100.
+		if (l < 6) {
+			rl = 63;
+			l = 0;
+		} else
+			rl = attentbl[(10 * l) / 100];	// Convert 0-100 vol to 63-0 atten.
+
+		r = (val >> 8) & 0xff;
+		if (r > 100)
+			r = 100;	// Max right volume is 100, too
+		if (r < 6) {
+			rr = 63;
+			r = 0;
+		} else
+			rr = attentbl[(10 * r) / 100];	// Convert volume to attenuation.
+
+		if ((rl > 60) && (rr > 60))	// If both l & r are 'low',          
+			temp1 = 0x8000;	//  turn on the mute bit.
+		else
+			temp1 = 0;
+
+		temp1 |= (rl << 8) | rr;
+
+		cs4281_write_ac97(s, BA0_AC97_MASTER_VOLUME, temp1);
+		cs4281_write_ac97(s, BA0_AC97_HEADPHONE_VOLUME, temp1);
+
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+		s->mix.vol[8] = ((unsigned int) r << 8) | l;
+#else
+		s->mix.vol[8] = val;
+#endif
+		return put_user(s->mix.vol[8], (int *) arg);
+
+	case SOUND_MIXER_SPEAKER:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		l = val & 0xff;
+		if (l > 100)
+			l = 100;
+		if (l < 3) {
+			rl = 0;
+			l = 0;
+		} else {
+			rl = (l * 2 - 5) / 13;	// Convert 0-100 range to 0-15.
+			l = (rl * 13 + 5) / 2;
+		}
+
+		if (rl < 3) {
+			temp1 = 0x8000;
+			rl = 0;
+		} else
+			temp1 = 0;
+		rl = 15 - rl;	// Convert volume to attenuation.
+		temp1 |= rl << 1;
+		cs4281_write_ac97(s, BA0_AC97_PC_BEEP_VOLUME, temp1);
+
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+		s->mix.vol[6] = l << 8;
+#else
+		s->mix.vol[6] = val;
+#endif
+		return put_user(s->mix.vol[6], (int *) arg);
+
+	case SOUND_MIXER_RECLEV:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		l = val & 0xff;
+		if (l > 100)
+			l = 100;
+		r = (val >> 8) & 0xff;
+		if (r > 100)
+			r = 100;
+		rl = (l * 2 - 5) / 13;	// Convert 0-100 scale to 0-15.
+		rr = (r * 2 - 5) / 13;
+		if (rl < 3 && rr < 3)
+			temp1 = 0x8000;
+		else
+			temp1 = 0;
+
+		temp1 = temp1 | (rl << 8) | rr;
+		cs4281_write_ac97(s, BA0_AC97_RECORD_GAIN, temp1);
+
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+		s->mix.vol[7] = ((unsigned int) r << 8) | l;
+#else
+		s->mix.vol[7] = val;
+#endif
+		return put_user(s->mix.vol[7], (int *) arg);
+
+	case SOUND_MIXER_MIC:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		l = val & 0xff;
+		if (l > 100)
+			l = 100;
+		if (l < 1) {
+			l = 0;
+			rl = 0;
+		} else {
+			rl = ((unsigned) l * 5 - 4) / 16;	// Convert 0-100 range to 0-31.
+			l = (rl * 16 + 4) / 5;
+		}
+		cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1);
+		temp1 &= 0x40;	// Isolate 20db gain bit.
+		if (rl < 3) {
+			temp1 |= 0x8000;
+			rl = 0;
+		}
+		rl = 31 - rl;	// Convert volume to attenuation.
+		temp1 |= rl;
+		cs4281_write_ac97(s, BA0_AC97_MIC_VOLUME, temp1);
+
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+		s->mix.vol[5] = val << 8;
+#else
+		s->mix.vol[5] = val;
+#endif
+		return put_user(s->mix.vol[5], (int *) arg);
+
+
+	case SOUND_MIXER_SYNTH:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		l = val & 0xff;
+		if (l > 100)
+			l = 100;
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		r = (val >> 8) & 0xff;
+		if (r > 100)
+			r = 100;
+		rl = (l * 2 - 11) / 3;	// Convert 0-100 range to 0-63.
+		rr = (r * 2 - 11) / 3;
+		if (rl < 3)	// If l is low, turn on
+			temp1 = 0x0080;	//  the mute bit.
+		else
+			temp1 = 0;
+
+		rl = 63 - rl;	// Convert vol to attenuation.
+		writel(temp1 | rl, s->pBA0 + BA0_FMLVC);
+		if (rr < 3)	//  If rr is low, turn on
+			temp1 = 0x0080;	//   the mute bit.
+		else
+			temp1 = 0;
+		rr = 63 - rr;	// Convert vol to attenuation.
+		writel(temp1 | rr, s->pBA0 + BA0_FMRVC);
+
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+		s->mix.vol[4] = (r << 8) | l;
+#else
+		s->mix.vol[4] = val;
+#endif
+		return put_user(s->mix.vol[4], (int *) arg);
+
+
+	default:
+		CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
+			"cs4281: mixer_ioctl(): default\n"));
+
+		i = _IOC_NR(cmd);
+		if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i]))
+			return -EINVAL;
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		l = val & 0xff;
+		if (l > 100)
+			l = 100;
+		if (l < 1) {
+			l = 0;
+			rl = 31;
+		} else
+			rl = (attentbl[(l * 10) / 100]) >> 1;
+
+		r = (val >> 8) & 0xff;
+		if (r > 100)
+			r = 100;
+		if (r < 1) {
+			r = 0;
+			rr = 31;
+		} else
+			rr = (attentbl[(r * 10) / 100]) >> 1;
+		if ((rl > 30) && (rr > 30))
+			temp1 = 0x8000;
+		else
+			temp1 = 0;
+		temp1 = temp1 | (rl << 8) | rr;
+		cs4281_write_ac97(s, mixreg[vidx - 1], temp1);
+
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+		s->mix.vol[vidx - 1] = ((unsigned int) r << 8) | l;
+#else
+		s->mix.vol[vidx - 1] = val;
+#endif
+#ifndef NOT_CS4281_PM
+		CS_DBGOUT(CS_PM, 9, printk(KERN_INFO 
+			"write ac97 mixreg[%d]=0x%x mix.vol[]=0x%x\n", 
+				vidx-1,temp1,s->mix.vol[vidx-1]));
+#endif
+		return put_user(s->mix.vol[vidx - 1], (int *) arg);
+	}
+}
+
+
+// --------------------------------------------------------------------- 
+
+static loff_t cs4281_llseek(struct file *file, loff_t offset, int origin)
+{
+	return -ESPIPE;
+}
+
+
+// --------------------------------------------------------------------- 
+
+static int cs4281_open_mixdev(struct inode *inode, struct file *file)
+{
+	int minor = MINOR(inode->i_rdev);
+	struct cs4281_state *s=NULL;
+	struct list_head *entry;
+
+	CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4,
+		  printk(KERN_INFO "cs4281: cs4281_open_mixdev()+\n"));
+
+	list_for_each(entry, &cs4281_devs)
+	{
+		s = list_entry(entry, struct cs4281_state, list);
+		if(s->dev_mixer == minor)
+			break;
+	}
+	if (!s)
+	{
+		CS_DBGOUT(CS_FUNCTION | CS_OPEN | CS_ERROR, 2,
+			printk(KERN_INFO "cs4281: cs4281_open_mixdev()- -ENODEV\n"));
+		return -ENODEV;
+	}
+	VALIDATE_STATE(s);
+	file->private_data = s;
+	MOD_INC_USE_COUNT;
+
+	CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4,
+		  printk(KERN_INFO "cs4281: cs4281_open_mixdev()- 0\n"));
+
+	return 0;
+}
+
+
+static int cs4281_release_mixdev(struct inode *inode, struct file *file)
+{
+	struct cs4281_state *s =
+	    (struct cs4281_state *) file->private_data;
+
+	VALIDATE_STATE(s);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+
+static int cs4281_ioctl_mixdev(struct inode *inode, struct file *file,
+			       unsigned int cmd, unsigned long arg)
+{
+	return mixer_ioctl((struct cs4281_state *) file->private_data, cmd,
+			   arg);
+}
+
+
+// ******************************************************************************************
+//   Mixer file operations struct.
+// ******************************************************************************************
+static /*const */ struct file_operations cs4281_mixer_fops = {
+	llseek:cs4281_llseek,
+	ioctl:cs4281_ioctl_mixdev,
+	open:cs4281_open_mixdev,
+	release:cs4281_release_mixdev,
+};
+
+// --------------------------------------------------------------------- 
+
+
+static int drain_adc(struct cs4281_state *s, int nonblock)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	unsigned long flags;
+	int count;
+	unsigned tmo;
+
+	if (s->dma_adc.mapped)
+		return 0;
+	add_wait_queue(&s->dma_adc.wait, &wait);
+	for (;;) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_adc.count;
+		CS_DBGOUT(CS_FUNCTION, 2,
+			  printk(KERN_INFO "cs4281: drain_adc() %d\n", count));
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count <= 0) {
+			CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_INFO
+				 "cs4281: drain_adc() count<0\n"));
+			break;
+		}
+		if (signal_pending(current))
+			break;
+		if (nonblock) {
+			remove_wait_queue(&s->dma_adc.wait, &wait);
+			current->state = TASK_RUNNING;
+			return -EBUSY;
+		}
+		tmo =
+		    3 * HZ * (count +
+			      s->dma_adc.fragsize) / 2 / s->prop_adc.rate;
+		if (s->prop_adc.fmt & (AFMT_S16_LE | AFMT_U16_LE))
+			tmo >>= 1;
+		if (s->prop_adc.channels > 1)
+			tmo >>= 1;
+		if (!schedule_timeout(tmo + 1))
+			printk(KERN_DEBUG "cs4281: dma timed out??\n");
+	}
+	remove_wait_queue(&s->dma_adc.wait, &wait);
+	current->state = TASK_RUNNING;
+	if (signal_pending(current))
+		return -ERESTARTSYS;
+	return 0;
+}
+
+static int drain_dac(struct cs4281_state *s, int nonblock)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	unsigned long flags;
+	int count;
+	unsigned tmo;
+
+	if (s->dma_dac.mapped)
+		return 0;
+	add_wait_queue(&s->dma_dac.wait, &wait);
+	for (;;) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_dac.count;
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count <= 0)
+			break;
+		if (signal_pending(current))
+			break;
+		if (nonblock) {
+			remove_wait_queue(&s->dma_dac.wait, &wait);
+			current->state = TASK_RUNNING;
+			return -EBUSY;
+		}
+		tmo =
+		    3 * HZ * (count +
+			      s->dma_dac.fragsize) / 2 / s->prop_dac.rate;
+		if (s->prop_dac.fmt & (AFMT_S16_LE | AFMT_U16_LE))
+			tmo >>= 1;
+		if (s->prop_dac.channels > 1)
+			tmo >>= 1;
+		if (!schedule_timeout(tmo + 1))
+			printk(KERN_DEBUG "cs4281: dma timed out??\n");
+	}
+	remove_wait_queue(&s->dma_dac.wait, &wait);
+	current->state = TASK_RUNNING;
+	if (signal_pending(current))
+		return -ERESTARTSYS;
+	return 0;
+}
+
+//****************************************************************************
+//
+// CopySamples copies 16-bit stereo samples from the source to the
+// destination, possibly converting down to either 8-bit or mono or both.
+// count specifies the number of output bytes to write.
+//
+//  Arguments:
+//
+//  dst             - Pointer to a destination buffer.
+//  src             - Pointer to a source buffer
+//  count           - The number of bytes to copy into the destination buffer.
+//  iChannels       - Stereo - 2
+//                    Mono   - 1
+//  fmt             - AFMT_xxx (soundcard.h formats)
+//
+// NOTES: only call this routine for conversion to 8bit from 16bit
+//
+//****************************************************************************
+static void CopySamples(char *dst, char *src, int count, int iChannels,
+			unsigned fmt)
+{
+
+	unsigned short *psSrc;
+	long lAudioSample;
+
+	CS_DBGOUT(CS_FUNCTION, 2,
+		  printk(KERN_INFO "cs4281: CopySamples()+ "));
+	CS_DBGOUT(CS_WAVE_READ, 8, printk(KERN_INFO
+		 " dst=0x%x src=0x%x count=%d iChannels=%d fmt=0x%x\n",
+			 (unsigned) dst, (unsigned) src, (unsigned) count,
+			 (unsigned) iChannels, (unsigned) fmt));
+
+	// Gershwin does format conversion in hardware so normally
+	// we don't do any host based coversion. The data formatter
+	// truncates 16 bit data to 8 bit and that causes some hiss.
+	// We have already forced the HW to do 16 bit sampling and 
+	// 2 channel so that we can use software to round instead 
+	// of truncate
+
+	//
+	// See if the data should be output as 8-bit unsigned stereo.
+	// or if the data should be output at 8-bit unsigned mono.
+	//
+	if ( ((iChannels == 2) && (fmt & AFMT_U8)) ||
+		((iChannels == 1) && (fmt & AFMT_U8)) ) {
+		//
+		// Convert each 16-bit unsigned stereo sample to 8-bit unsigned 
+		// stereo using rounding.
+		//
+		psSrc = (unsigned short *) src;
+		count = count / 2;
+		while (count--) {
+			lAudioSample = (long) psSrc[count] + (long) 0x80;
+			if (lAudioSample > 0xffff) {
+				lAudioSample = 0xffff;
+			}
+			dst[count] = (char) (lAudioSample >> 8);
+		}
+	}
+	//
+	// check for 8-bit signed stereo.
+	//
+	else if ((iChannels == 2) && (fmt & AFMT_S8)) {
+		//
+		// Convert each 16-bit stereo sample to 8-bit stereo using rounding.
+		//
+		psSrc = (short *) src;
+		while (count--) {
+			lAudioSample =
+			    (((long) psSrc[0] + (long) psSrc[1]) / 2);
+			psSrc += 2;
+			*dst++ = (char) ((short) lAudioSample >> 8);
+		}
+	}
+	//
+	// Otherwise, the data should be output as 8-bit signed mono.
+	//
+	else if ((iChannels == 1) && (fmt & AFMT_S8)) {
+		//
+		// Convert each 16-bit signed mono sample to 8-bit signed mono 
+		// using rounding.
+		//
+		psSrc = (short *) src;
+		count = count / 2;
+		while (count--) {
+			lAudioSample =
+			    (((long) psSrc[0] + (long) psSrc[1]) / 2);
+			if (lAudioSample > 0x7fff) {
+				lAudioSample = 0x7fff;
+			}
+			psSrc += 2;
+			*dst++ = (char) ((short) lAudioSample >> 8);
+		}
+	}
+}
+
+//
+// cs_copy_to_user()
+// replacement for the standard copy_to_user, to allow for a conversion from
+// 16 bit to 8 bit if the record conversion is active.  the cs4281 has some
+// issues with 8 bit capture, so the driver always captures data in 16 bit
+// and then if the user requested 8 bit, converts from 16 to 8 bit.
+//
+static unsigned cs_copy_to_user(struct cs4281_state *s, void *dest,
+				unsigned *hwsrc, unsigned cnt,
+				unsigned *copied)
+{
+	void *src = hwsrc;	//default to the standard destination buffer addr
+
+	CS_DBGOUT(CS_FUNCTION, 6, printk(KERN_INFO
+		"cs_copy_to_user()+ fmt=0x%x fmt_o=0x%x cnt=%d dest=0x%.8x\n",
+			s->prop_adc.fmt, s->prop_adc.fmt_original,
+			(unsigned) cnt, (unsigned) dest));
+
+	if (cnt > s->dma_adc.dmasize) {
+		cnt = s->dma_adc.dmasize;
+	}
+	if (!cnt) {
+		*copied = 0;
+		return 0;
+	}
+	if (s->conversion) {
+		if (!s->tmpbuff) {
+			*copied = cnt / 2;
+			return 0;
+		}
+		CopySamples(s->tmpbuff, (void *) hwsrc, cnt,
+			    (unsigned) s->prop_adc.channels,
+			    s->prop_adc.fmt_original);
+		src = s->tmpbuff;
+		cnt = cnt / 2;
+	}
+
+	if (copy_to_user(dest, src, cnt)) {
+		*copied = 0;
+		return -EFAULT;
+	}
+	*copied = cnt;
+	CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_INFO
+		"cs4281: cs_copy_to_user()- copied bytes is %d \n", cnt));
+	return 0;
+}
+
+// --------------------------------------------------------------------- 
+
+static ssize_t cs4281_read(struct file *file, char *buffer, size_t count,
+			   loff_t * ppos)
+{
+	struct cs4281_state *s =
+	    (struct cs4281_state *) file->private_data;
+	ssize_t ret;
+	unsigned long flags;
+	unsigned swptr;
+	int cnt;
+	unsigned copied = 0;
+
+	CS_DBGOUT(CS_FUNCTION | CS_WAVE_READ, 2,
+		  printk(KERN_INFO "cs4281: cs4281_read()+ %d \n", count));
+
+	VALIDATE_STATE(s);
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	if (s->dma_adc.mapped)
+		return -ENXIO;
+	if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
+		return ret;
+	if (!access_ok(VERIFY_WRITE, buffer, count))
+		return -EFAULT;
+	ret = 0;
+//
+// "count" is the amount of bytes to read (from app), is decremented each loop
+//      by the amount of bytes that have been returned to the user buffer.
+// "cnt" is the running total of each read from the buffer (changes each loop)
+// "buffer" points to the app's buffer
+// "ret" keeps a running total of the amount of bytes that have been copied
+//      to the user buffer.
+// "copied" is the total bytes copied into the user buffer for each loop.
+//
+	while (count > 0) {
+		CS_DBGOUT(CS_WAVE_READ, 8, printk(KERN_INFO
+			"_read() count>0 count=%d .count=%d .swptr=%d .hwptr=%d \n",
+				count, s->dma_adc.count,
+				s->dma_adc.swptr, s->dma_adc.hwptr));
+		spin_lock_irqsave(&s->lock, flags);
+
+		// get the current copy point of the sw buffer
+		swptr = s->dma_adc.swptr;
+
+		// cnt is the amount of unread bytes from the end of the 
+		// hw buffer to the current sw pointer
+		cnt = s->dma_adc.dmasize - swptr;
+
+		// dma_adc.count is the current total bytes that have not been read.
+		// if the amount of unread bytes from the current sw pointer to the
+		// end of the buffer is greater than the current total bytes that
+		// have not been read, then set the "cnt" (unread bytes) to the
+		// amount of unread bytes.  
+
+		if (s->dma_adc.count < cnt)
+			cnt = s->dma_adc.count;
+		spin_unlock_irqrestore(&s->lock, flags);
+		//
+		// if we are converting from 8/16 then we need to copy
+		// twice the number of 16 bit bytes then 8 bit bytes.
+		// 
+		if (s->conversion) {
+			if (cnt > (count * 2))
+				cnt = (count * 2);
+		} else {
+			if (cnt > count)
+				cnt = count;
+		}
+		//
+		// "cnt" NOW is the smaller of the amount that will be read,
+		// and the amount that is requested in this read (or partial).
+		// if there are no bytes in the buffer to read, then start the
+		// ADC and wait for the interrupt handler to wake us up.
+		//
+		if (cnt <= 0) {
+
+			// start up the dma engine and then continue back to the top of
+			// the loop when wake up occurs.
+			start_adc(s);
+			if (file->f_flags & O_NONBLOCK)
+				return ret ? ret : -EAGAIN;
+			interruptible_sleep_on(&s->dma_adc.wait);
+			if (signal_pending(current))
+				return ret ? ret : -ERESTARTSYS;
+			continue;
+		}
+		// there are bytes in the buffer to read.
+		// copy from the hw buffer over to the user buffer.
+		// user buffer is designated by "buffer"
+		// virtual address to copy from is rawbuf+swptr
+		// the "cnt" is the number of bytes to read.
+
+		CS_DBGOUT(CS_WAVE_READ, 2, printk(KERN_INFO
+			"_read() copy_to cnt=%d count=%d ", cnt, count));
+		CS_DBGOUT(CS_WAVE_READ, 8, printk(KERN_INFO
+			 " .dmasize=%d .count=%d buffer=0x%.8x ret=%d\n",
+				 s->dma_adc.dmasize, s->dma_adc.count,
+				 (unsigned) buffer, ret));
+
+		if (cs_copy_to_user
+		    (s, buffer, s->dma_adc.rawbuf + swptr, cnt, &copied))
+			return ret ? ret : -EFAULT;
+		swptr = (swptr + cnt) % s->dma_adc.dmasize;
+		spin_lock_irqsave(&s->lock, flags);
+		s->dma_adc.swptr = swptr;
+		s->dma_adc.count -= cnt;
+		spin_unlock_irqrestore(&s->lock, flags);
+		count -= copied;
+		buffer += copied;
+		ret += copied;
+		start_adc(s);
+	}
+	CS_DBGOUT(CS_FUNCTION | CS_WAVE_READ, 2,
+		  printk(KERN_INFO "cs4281: cs4281_read()- %d\n", ret));
+	return ret;
+}
+
+
+static ssize_t cs4281_write(struct file *file, const char *buffer,
+			    size_t count, loff_t * ppos)
+{
+	struct cs4281_state *s =
+	    (struct cs4281_state *) file->private_data;
+	ssize_t ret;
+	unsigned long flags;
+	unsigned swptr, hwptr, busaddr;
+	int cnt;
+
+	CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE, 2,
+		  printk(KERN_INFO "cs4281: cs4281_write()+ count=%d\n",
+			 count));
+	VALIDATE_STATE(s);
+
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	if (s->dma_dac.mapped)
+		return -ENXIO;
+	if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s)))
+		return ret;
+	if (!access_ok(VERIFY_READ, buffer, count))
+		return -EFAULT;
+	ret = 0;
+	while (count > 0) {
+		spin_lock_irqsave(&s->lock, flags);
+		if (s->dma_dac.count < 0) {
+			s->dma_dac.count = 0;
+			s->dma_dac.swptr = s->dma_dac.hwptr;
+		}
+		if (s->dma_dac.underrun) {
+			s->dma_dac.underrun = 0;
+			hwptr = readl(s->pBA0 + BA0_DCA0);
+			busaddr = virt_to_bus(s->dma_dac.rawbuf);
+			hwptr -= (unsigned) busaddr;
+			s->dma_dac.swptr = s->dma_dac.hwptr = hwptr;
+		}
+		swptr = s->dma_dac.swptr;
+		cnt = s->dma_dac.dmasize - swptr;
+		if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
+			cnt = s->dma_dac.dmasize - s->dma_dac.count;
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (cnt > count)
+			cnt = count;
+		if (cnt <= 0) {
+			start_dac(s);
+			if (file->f_flags & O_NONBLOCK)
+				return ret ? ret : -EAGAIN;
+			interruptible_sleep_on(&s->dma_dac.wait);
+			if (signal_pending(current))
+				return ret ? ret : -ERESTARTSYS;
+			continue;
+		}
+		if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt))
+			return ret ? ret : -EFAULT;
+		swptr = (swptr + cnt) % s->dma_dac.dmasize;
+		spin_lock_irqsave(&s->lock, flags);
+		s->dma_dac.swptr = swptr;
+		s->dma_dac.count += cnt;
+		s->dma_dac.endcleared = 0;
+		spin_unlock_irqrestore(&s->lock, flags);
+		count -= cnt;
+		buffer += cnt;
+		ret += cnt;
+		start_dac(s);
+	}
+	CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE, 2,
+		  printk(KERN_INFO "cs4281: cs4281_write()- %d\n", ret));
+	return ret;
+}
+
+
+static unsigned int cs4281_poll(struct file *file,
+				struct poll_table_struct *wait)
+{
+	struct cs4281_state *s =
+	    (struct cs4281_state *) file->private_data;
+	unsigned long flags;
+	unsigned int mask = 0;
+
+	CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
+		  printk(KERN_INFO "cs4281: cs4281_poll()+\n"));
+	VALIDATE_STATE(s);
+	if (file->f_mode & FMODE_WRITE) {
+		CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
+			  printk(KERN_INFO
+				 "cs4281: cs4281_poll() wait on FMODE_WRITE\n"));
+		if(!s->dma_dac.ready && prog_dmabuf_dac(s))
+			return 0;
+		poll_wait(file, &s->dma_dac.wait, wait);
+	}
+	if (file->f_mode & FMODE_READ) {
+		CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
+			  printk(KERN_INFO
+				 "cs4281: cs4281_poll() wait on FMODE_READ\n"));
+		if(!s->dma_dac.ready && prog_dmabuf_adc(s))
+			return 0;
+		poll_wait(file, &s->dma_adc.wait, wait);
+	}
+	spin_lock_irqsave(&s->lock, flags);
+	cs4281_update_ptr(s,CS_FALSE);
+	if (file->f_mode & FMODE_WRITE) {
+		if (s->dma_dac.mapped) {
+			if (s->dma_dac.count >=
+			    (signed) s->dma_dac.fragsize) {
+				if (s->dma_dac.wakeup)
+					mask |= POLLOUT | POLLWRNORM;
+				else
+					mask = 0;
+				s->dma_dac.wakeup = 0;
+			}
+		} else {
+			if ((signed) (s->dma_dac.dmasize/2) >= s->dma_dac.count)
+				mask |= POLLOUT | POLLWRNORM;
+		}
+	} else if (file->f_mode & FMODE_READ) {
+		if (s->dma_adc.mapped) {
+			if (s->dma_adc.count >= (signed) s->dma_adc.fragsize) 
+				mask |= POLLIN | POLLRDNORM;
+		} else {
+			if (s->dma_adc.count > 0)
+				mask |= POLLIN | POLLRDNORM;
+		}
+	}
+	spin_unlock_irqrestore(&s->lock, flags);
+	CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
+		  printk(KERN_INFO "cs4281: cs4281_poll()- 0x%.8x\n",
+			 mask));
+	return mask;
+}
+
+
+static int cs4281_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct cs4281_state *s =
+	    (struct cs4281_state *) file->private_data;
+	struct dmabuf *db;
+	int ret;
+	unsigned long size;
+
+	CS_DBGOUT(CS_FUNCTION | CS_PARMS | CS_OPEN, 4,
+		  printk(KERN_INFO "cs4281: cs4281_mmap()+\n"));
+
+	VALIDATE_STATE(s);
+	if (vma->vm_flags & VM_WRITE) {
+		if ((ret = prog_dmabuf_dac(s)) != 0)
+			return ret;
+		db = &s->dma_dac;
+	} else if (vma->vm_flags & VM_READ) {
+		if ((ret = prog_dmabuf_adc(s)) != 0)
+			return ret;
+		db = &s->dma_adc;
+	} else
+		return -EINVAL;
+//
+// only support PLAYBACK for now
+//
+	db = &s->dma_dac;
+
+	if (cs4x_pgoff(vma) != 0)
+		return -EINVAL;
+	size = vma->vm_end - vma->vm_start;
+	if (size > (PAGE_SIZE << db->buforder))
+		return -EINVAL;
+	if (remap_page_range
+	    (vma->vm_start, virt_to_phys(db->rawbuf), size,
+	     vma->vm_page_prot)) return -EAGAIN;
+	db->mapped = 1;
+
+	CS_DBGOUT(CS_FUNCTION | CS_PARMS | CS_OPEN, 4,
+		  printk(KERN_INFO "cs4281: cs4281_mmap()- 0 size=%d\n",
+			 (unsigned) size));
+
+	return 0;
+}
+
+
+static int cs4281_ioctl(struct inode *inode, struct file *file,
+			unsigned int cmd, unsigned long arg)
+{
+	struct cs4281_state *s =
+	    (struct cs4281_state *) file->private_data;
+	unsigned long flags;
+	audio_buf_info abinfo;
+	count_info cinfo;
+	int val, mapped, ret;
+
+	CS_DBGOUT(CS_FUNCTION, 4, printk(KERN_INFO
+		 "cs4281: cs4281_ioctl(): file=0x%.8x cmd=0x%.8x\n",
+			 (unsigned) file, cmd));
+#if CSDEBUG
+	cs_printioctl(cmd);
+#endif
+	VALIDATE_STATE(s);
+	mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
+	    ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
+	switch (cmd) {
+	case OSS_GETVERSION:
+		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
+			"cs4281: cs4281_ioctl(): SOUND_VERSION=0x%.8x\n",
+				 SOUND_VERSION));
+		return put_user(SOUND_VERSION, (int *) arg);
+
+	case SNDCTL_DSP_SYNC:
+		CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
+			 "cs4281: cs4281_ioctl(): DSP_SYNC\n"));
+		if (file->f_mode & FMODE_WRITE)
+			return drain_dac(s,
+					 0 /*file->f_flags & O_NONBLOCK */
+					 );
+		return 0;
+
+	case SNDCTL_DSP_SETDUPLEX:
+		return 0;
+
+	case SNDCTL_DSP_GETCAPS:
+		return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
+				DSP_CAP_TRIGGER | DSP_CAP_MMAP,
+				(int *) arg);
+
+	case SNDCTL_DSP_RESET:
+		CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
+			 "cs4281: cs4281_ioctl(): DSP_RESET\n"));
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			synchronize_irq();
+			s->dma_dac.swptr = s->dma_dac.hwptr =
+			    s->dma_dac.count = s->dma_dac.total_bytes =
+			    s->dma_dac.blocks = s->dma_dac.wakeup = 0;
+			prog_codec(s, CS_TYPE_DAC);
+		}
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			synchronize_irq();
+			s->dma_adc.swptr = s->dma_adc.hwptr =
+			    s->dma_adc.count = s->dma_adc.total_bytes =
+			    s->dma_adc.blocks = s->dma_dac.wakeup = 0;
+			prog_codec(s, CS_TYPE_ADC);
+		}
+		return 0;
+
+	case SNDCTL_DSP_SPEED:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
+			 "cs4281: cs4281_ioctl(): DSP_SPEED val=%d\n", val));
+		//
+		// support independent capture and playback channels
+		// assume that the file mode bit determines the 
+		// direction of the data flow.
+		//
+		if (file->f_mode & FMODE_READ) {
+			if (val >= 0) {
+				stop_adc(s);
+				s->dma_adc.ready = 0;
+				// program sampling rates 
+				if (val > 48000)
+					val = 48000;
+				if (val < 6300)
+					val = 6300;
+				s->prop_adc.rate = val;
+				prog_codec(s, CS_TYPE_ADC);
+			}
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			if (val >= 0) {
+				stop_dac(s);
+				s->dma_dac.ready = 0;
+				// program sampling rates 
+				if (val > 48000)
+					val = 48000;
+				if (val < 6300)
+					val = 6300;
+				s->prop_dac.rate = val;
+				prog_codec(s, CS_TYPE_DAC);
+			}
+		}
+
+		if (file->f_mode & FMODE_WRITE)
+			val = s->prop_dac.rate;
+		else if (file->f_mode & FMODE_READ)
+			val = s->prop_adc.rate;
+
+		return put_user(val, (int *) arg);
+
+	case SNDCTL_DSP_STEREO:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
+			 "cs4281: cs4281_ioctl(): DSP_STEREO val=%d\n", val));
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			s->dma_adc.ready = 0;
+			s->prop_adc.channels = val ? 2 : 1;
+			prog_codec(s, CS_TYPE_ADC);
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			s->dma_dac.ready = 0;
+			s->prop_dac.channels = val ? 2 : 1;
+			prog_codec(s, CS_TYPE_DAC);
+		}
+		return 0;
+
+	case SNDCTL_DSP_CHANNELS:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
+			 "cs4281: cs4281_ioctl(): DSP_CHANNELS val=%d\n",
+				 val));
+		if (val != 0) {
+			if (file->f_mode & FMODE_READ) {
+				stop_adc(s);
+				s->dma_adc.ready = 0;
+				if (val >= 2)
+					s->prop_adc.channels = 2;
+				else
+					s->prop_adc.channels = 1;
+				prog_codec(s, CS_TYPE_ADC);
+			}
+			if (file->f_mode & FMODE_WRITE) {
+				stop_dac(s);
+				s->dma_dac.ready = 0;
+				if (val >= 2)
+					s->prop_dac.channels = 2;
+				else
+					s->prop_dac.channels = 1;
+				prog_codec(s, CS_TYPE_DAC);
+			}
+		}
+
+		if (file->f_mode & FMODE_WRITE)
+			val = s->prop_dac.channels;
+		else if (file->f_mode & FMODE_READ)
+			val = s->prop_adc.channels;
+
+		return put_user(val, (int *) arg);
+
+	case SNDCTL_DSP_GETFMTS:	// Returns a mask 
+		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
+			"cs4281: cs4281_ioctl(): DSP_GETFMT val=0x%.8x\n",
+				 AFMT_S16_LE | AFMT_U16_LE | AFMT_S8 |
+				 AFMT_U8));
+		return put_user(AFMT_S16_LE | AFMT_U16_LE | AFMT_S8 |
+				AFMT_U8, (int *) arg);
+
+	case SNDCTL_DSP_SETFMT:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
+			 "cs4281: cs4281_ioctl(): DSP_SETFMT val=0x%.8x\n",
+				 val));
+		if (val != AFMT_QUERY) {
+			if (file->f_mode & FMODE_READ) {
+				stop_adc(s);
+				s->dma_adc.ready = 0;
+				if (val != AFMT_S16_LE
+				    && val != AFMT_U16_LE && val != AFMT_S8
+				    && val != AFMT_U8)
+					val = AFMT_U8;
+				s->prop_adc.fmt = val;
+				s->prop_adc.fmt_original = s->prop_adc.fmt;
+				prog_codec(s, CS_TYPE_ADC);
+			}
+			if (file->f_mode & FMODE_WRITE) {
+				stop_dac(s);
+				s->dma_dac.ready = 0;
+				if (val != AFMT_S16_LE
+				    && val != AFMT_U16_LE && val != AFMT_S8
+				    && val != AFMT_U8)
+					val = AFMT_U8;
+				s->prop_dac.fmt = val;
+				s->prop_dac.fmt_original = s->prop_dac.fmt;
+				prog_codec(s, CS_TYPE_DAC);
+			}
+		} else {
+			if (file->f_mode & FMODE_WRITE)
+				val = s->prop_dac.fmt_original;
+			else if (file->f_mode & FMODE_READ)
+				val = s->prop_adc.fmt_original;
+		}
+		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
+		  "cs4281: cs4281_ioctl(): DSP_SETFMT return val=0x%.8x\n", 
+			val));
+		return put_user(val, (int *) arg);
+
+	case SNDCTL_DSP_POST:
+		CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
+			 "cs4281: cs4281_ioctl(): DSP_POST\n"));
+		return 0;
+
+	case SNDCTL_DSP_GETTRIGGER:
+		val = 0;
+		if (file->f_mode & s->ena & FMODE_READ)
+			val |= PCM_ENABLE_INPUT;
+		if (file->f_mode & s->ena & FMODE_WRITE)
+			val |= PCM_ENABLE_OUTPUT;
+		return put_user(val, (int *) arg);
+
+	case SNDCTL_DSP_SETTRIGGER:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (file->f_mode & FMODE_READ) {
+			if (val & PCM_ENABLE_INPUT) {
+				if (!s->dma_adc.ready
+				    && (ret = prog_dmabuf_adc(s)))
+					return ret;
+				start_adc(s);
+			} else
+				stop_adc(s);
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			if (val & PCM_ENABLE_OUTPUT) {
+				if (!s->dma_dac.ready
+				    && (ret = prog_dmabuf_dac(s)))
+					return ret;
+				start_dac(s);
+			} else
+				stop_dac(s);
+		}
+		return 0;
+
+	case SNDCTL_DSP_GETOSPACE:
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
+		if (!s->dma_dac.ready && (val = prog_dmabuf_dac(s)))
+			return val;
+		spin_lock_irqsave(&s->lock, flags);
+		cs4281_update_ptr(s,CS_FALSE);
+		abinfo.fragsize = s->dma_dac.fragsize;
+		if (s->dma_dac.mapped)
+			abinfo.bytes = s->dma_dac.dmasize;
+		else
+			abinfo.bytes =
+			    s->dma_dac.dmasize - s->dma_dac.count;
+		abinfo.fragstotal = s->dma_dac.numfrag;
+		abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
+		CS_DBGOUT(CS_FUNCTION | CS_PARMS, 4, printk(KERN_INFO
+			"cs4281: cs4281_ioctl(): GETOSPACE .fragsize=%d .bytes=%d .fragstotal=%d .fragments=%d\n",
+				abinfo.fragsize,abinfo.bytes,abinfo.fragstotal,
+				abinfo.fragments));
+		spin_unlock_irqrestore(&s->lock, flags);
+		return copy_to_user((void *) arg, &abinfo,
+				    sizeof(abinfo)) ? -EFAULT : 0;
+
+	case SNDCTL_DSP_GETISPACE:
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
+		if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)))
+			return val;
+		spin_lock_irqsave(&s->lock, flags);
+		cs4281_update_ptr(s,CS_FALSE);
+		if (s->conversion) {
+			abinfo.fragsize = s->dma_adc.fragsize / 2;
+			abinfo.bytes = s->dma_adc.count / 2;
+			abinfo.fragstotal = s->dma_adc.numfrag;
+			abinfo.fragments =
+			    abinfo.bytes >> (s->dma_adc.fragshift - 1);
+		} else {
+			abinfo.fragsize = s->dma_adc.fragsize;
+			abinfo.bytes = s->dma_adc.count;
+			abinfo.fragstotal = s->dma_adc.numfrag;
+			abinfo.fragments =
+			    abinfo.bytes >> s->dma_adc.fragshift;
+		}
+		spin_unlock_irqrestore(&s->lock, flags);
+		return copy_to_user((void *) arg, &abinfo,
+				    sizeof(abinfo)) ? -EFAULT : 0;
+
+	case SNDCTL_DSP_NONBLOCK:
+		file->f_flags |= O_NONBLOCK;
+		return 0;
+
+	case SNDCTL_DSP_GETODELAY:
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
+		if(!s->dma_dac.ready && prog_dmabuf_dac(s))
+			return 0;
+		spin_lock_irqsave(&s->lock, flags);
+		cs4281_update_ptr(s,CS_FALSE);
+		val = s->dma_dac.count;
+		spin_unlock_irqrestore(&s->lock, flags);
+		return put_user(val, (int *) arg);
+
+	case SNDCTL_DSP_GETIPTR:
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
+		if(!s->dma_adc.ready && prog_dmabuf_adc(s))
+			return 0;
+		spin_lock_irqsave(&s->lock, flags);
+		cs4281_update_ptr(s,CS_FALSE);
+		cinfo.bytes = s->dma_adc.total_bytes;
+		if (s->dma_adc.mapped) {
+			cinfo.blocks =
+			    (cinfo.bytes >> s->dma_adc.fragshift) -
+			    s->dma_adc.blocks;
+			s->dma_adc.blocks =
+			    cinfo.bytes >> s->dma_adc.fragshift;
+		} else {
+			if (s->conversion) {
+				cinfo.blocks =
+				    s->dma_adc.count /
+				    2 >> (s->dma_adc.fragshift - 1);
+			} else
+				cinfo.blocks =
+				    s->dma_adc.count >> s->dma_adc.
+				    fragshift;
+		}
+		if (s->conversion)
+			cinfo.ptr = s->dma_adc.hwptr / 2;
+		else
+			cinfo.ptr = s->dma_adc.hwptr;
+		if (s->dma_adc.mapped)
+			s->dma_adc.count &= s->dma_adc.fragsize - 1;
+		spin_unlock_irqrestore(&s->lock, flags);
+		return copy_to_user((void *) arg, &cinfo, sizeof(cinfo));
+
+	case SNDCTL_DSP_GETOPTR:
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
+		if(!s->dma_dac.ready && prog_dmabuf_dac(s))
+			return 0;
+		spin_lock_irqsave(&s->lock, flags);
+		cs4281_update_ptr(s,CS_FALSE);
+		cinfo.bytes = s->dma_dac.total_bytes;
+		if (s->dma_dac.mapped) {
+			cinfo.blocks =
+			    (cinfo.bytes >> s->dma_dac.fragshift) -
+			    s->dma_dac.blocks;
+			s->dma_dac.blocks =
+			    cinfo.bytes >> s->dma_dac.fragshift;
+		} else {
+			cinfo.blocks =
+			    s->dma_dac.count >> s->dma_dac.fragshift;
+		}
+		cinfo.ptr = s->dma_dac.hwptr;
+		if (s->dma_dac.mapped)
+			s->dma_dac.count &= s->dma_dac.fragsize - 1;
+		spin_unlock_irqrestore(&s->lock, flags);
+		return copy_to_user((void *) arg, &cinfo, sizeof(cinfo));
+
+	case SNDCTL_DSP_GETBLKSIZE:
+		if (file->f_mode & FMODE_WRITE) {
+			if ((val = prog_dmabuf_dac(s)))
+				return val;
+			return put_user(s->dma_dac.fragsize, (int *) arg);
+		}
+		if ((val = prog_dmabuf_adc(s)))
+			return val;
+		if (s->conversion)
+			return put_user(s->dma_adc.fragsize / 2,
+					(int *) arg);
+		else
+			return put_user(s->dma_adc.fragsize, (int *) arg);
+
+	case SNDCTL_DSP_SETFRAGMENT:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		return 0;	// Say OK, but do nothing.
+
+	case SNDCTL_DSP_SUBDIVIDE:
+		if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision)
+		    || (file->f_mode & FMODE_WRITE
+			&& s->dma_dac.subdivision)) return -EINVAL;
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (val != 1 && val != 2 && val != 4)
+			return -EINVAL;
+		if (file->f_mode & FMODE_READ)
+			s->dma_adc.subdivision = val;
+		else if (file->f_mode & FMODE_WRITE)
+			s->dma_dac.subdivision = val;
+		return 0;
+
+	case SOUND_PCM_READ_RATE:
+		if (file->f_mode & FMODE_READ)
+			return put_user(s->prop_adc.rate, (int *) arg);
+		else if (file->f_mode & FMODE_WRITE)
+			return put_user(s->prop_dac.rate, (int *) arg);
+
+	case SOUND_PCM_READ_CHANNELS:
+		if (file->f_mode & FMODE_READ)
+			return put_user(s->prop_adc.channels, (int *) arg);
+		else if (file->f_mode & FMODE_WRITE)
+			return put_user(s->prop_dac.channels, (int *) arg);
+
+	case SOUND_PCM_READ_BITS:
+		if (file->f_mode & FMODE_READ)
+			return
+			    put_user(
+				     (s->prop_adc.
+				      fmt & (AFMT_S8 | AFMT_U8)) ? 8 : 16,
+				     (int *) arg);
+		else if (file->f_mode & FMODE_WRITE)
+			return
+			    put_user(
+				     (s->prop_dac.
+				      fmt & (AFMT_S8 | AFMT_U8)) ? 8 : 16,
+				     (int *) arg);
+
+	case SOUND_PCM_WRITE_FILTER:
+	case SNDCTL_DSP_SETSYNCRO:
+	case SOUND_PCM_READ_FILTER:
+		return -EINVAL;
+	}
+	return mixer_ioctl(s, cmd, arg);
+}
+
+
+static int cs4281_release(struct inode *inode, struct file *file)
+{
+	struct cs4281_state *s =
+	    (struct cs4281_state *) file->private_data;
+
+	CS_DBGOUT(CS_FUNCTION | CS_RELEASE, 2, printk(KERN_INFO
+		 "cs4281: cs4281_release(): inode=0x%.8x file=0x%.8x f_mode=%d\n",
+			 (unsigned) inode, (unsigned) file, file->f_mode));
+
+	VALIDATE_STATE(s);
+
+	if (file->f_mode & FMODE_WRITE) {
+		drain_dac(s, file->f_flags & O_NONBLOCK);
+		down(&s->open_sem_dac);
+		stop_dac(s);
+		dealloc_dmabuf(s, &s->dma_dac);
+		s->open_mode &= ~FMODE_WRITE;
+		up(&s->open_sem_dac);
+		wake_up(&s->open_wait_dac);
+		MOD_DEC_USE_COUNT;
+	}
+	if (file->f_mode & FMODE_READ) {
+		drain_adc(s, file->f_flags & O_NONBLOCK);
+		down(&s->open_sem_adc);
+		stop_adc(s);
+		dealloc_dmabuf(s, &s->dma_adc);
+		s->open_mode &= ~FMODE_READ;
+		up(&s->open_sem_adc);
+		wake_up(&s->open_wait_adc);
+		MOD_DEC_USE_COUNT;
+	}
+	return 0;
+}
+
+static int cs4281_open(struct inode *inode, struct file *file)
+{
+	int minor = MINOR(inode->i_rdev);
+	struct cs4281_state *s=NULL;
+	struct list_head *entry;
+
+	CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO
+		"cs4281: cs4281_open(): inode=0x%.8x file=0x%.8x f_mode=0x%x\n",
+			(unsigned) inode, (unsigned) file, file->f_mode));
+
+	list_for_each(entry, &cs4281_devs)
+	{
+		s = list_entry(entry, struct cs4281_state, list);
+
+		if (!((s->dev_audio ^ minor) & ~0xf))
+			break;
+	}
+	if (entry == &cs4281_devs)
+		return -ENODEV;
+	if (!s) {
+		CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO
+			"cs4281: cs4281_open(): Error - unable to find audio state struct\n"));
+		return -ENODEV;
+	}
+	VALIDATE_STATE(s);
+	file->private_data = s;
+
+	// wait for device to become free 
+	if (!(file->f_mode & (FMODE_WRITE | FMODE_READ))) {
+		CS_DBGOUT(CS_FUNCTION | CS_OPEN | CS_ERROR, 2, printk(KERN_INFO
+			 "cs4281: cs4281_open(): Error - must open READ and/or WRITE\n"));
+		return -ENODEV;
+	}
+	if (file->f_mode & FMODE_WRITE) {
+		down(&s->open_sem_dac);
+		while (s->open_mode & FMODE_WRITE) {
+			if (file->f_flags & O_NONBLOCK) {
+				up(&s->open_sem_dac);
+				return -EBUSY;
+			}
+			up(&s->open_sem_dac);
+			interruptible_sleep_on(&s->open_wait_dac);
+
+			if (signal_pending(current))
+				return -ERESTARTSYS;
+			down(&s->open_sem_dac);
+		}
+	}
+	if (file->f_mode & FMODE_READ) {
+		down(&s->open_sem_adc);
+		while (s->open_mode & FMODE_READ) {
+			if (file->f_flags & O_NONBLOCK) {
+				up(&s->open_sem_adc);
+				return -EBUSY;
+			}
+			up(&s->open_sem_adc);
+			interruptible_sleep_on(&s->open_wait_adc);
+
+			if (signal_pending(current))
+				return -ERESTARTSYS;
+			down(&s->open_sem_adc);
+		}
+	}
+	s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
+	if (file->f_mode & FMODE_READ) {
+		s->prop_adc.fmt = AFMT_U8;
+		s->prop_adc.fmt_original = s->prop_adc.fmt;
+		s->prop_adc.channels = 1;
+		s->prop_adc.rate = 8000;
+		s->prop_adc.clkdiv = 96 | 0x80;
+		s->conversion = 0;
+		s->ena &= ~FMODE_READ;
+		s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
+		    s->dma_adc.subdivision = 0;
+		up(&s->open_sem_adc);
+		MOD_INC_USE_COUNT;
+
+		if (prog_dmabuf_adc(s)) {
+			CS_DBGOUT(CS_OPEN | CS_ERROR, 2, printk(KERN_ERR
+				"cs4281: adc Program dmabufs failed.\n"));
+			cs4281_release(inode, file);
+			return -ENOMEM;
+		}
+		prog_codec(s, CS_TYPE_ADC);
+	}
+	if (file->f_mode & FMODE_WRITE) {
+		s->prop_dac.fmt = AFMT_U8;
+		s->prop_dac.fmt_original = s->prop_dac.fmt;
+		s->prop_dac.channels = 1;
+		s->prop_dac.rate = 8000;
+		s->prop_dac.clkdiv = 96 | 0x80;
+		s->conversion = 0;
+		s->ena &= ~FMODE_WRITE;
+		s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags =
+		    s->dma_dac.subdivision = 0;
+		up(&s->open_sem_dac);
+		MOD_INC_USE_COUNT;
+
+		if (prog_dmabuf_dac(s)) {
+			CS_DBGOUT(CS_OPEN | CS_ERROR, 2, printk(KERN_ERR
+				"cs4281: dac Program dmabufs failed.\n"));
+			cs4281_release(inode, file);
+			return -ENOMEM;
+		}
+		prog_codec(s, CS_TYPE_DAC);
+	}
+	CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2,
+		  printk(KERN_INFO "cs4281: cs4281_open()- 0\n"));
+	return 0;
+}
+
+
+// ******************************************************************************************
+//   Wave (audio) file operations struct.
+// ******************************************************************************************
+static /*const */ struct file_operations cs4281_audio_fops = {
+	llseek:cs4281_llseek,
+	read:cs4281_read,
+	write:cs4281_write,
+	poll:cs4281_poll,
+	ioctl:cs4281_ioctl,
+	mmap:cs4281_mmap,
+	open:cs4281_open,
+	release:cs4281_release,
+};
+
+// --------------------------------------------------------------------- 
+
+// hold spinlock for the following! 
+static void cs4281_handle_midi(struct cs4281_state *s)
+{
+	unsigned char ch;
+	int wake;
+	unsigned temp1;
+
+	wake = 0;
+	while (!(readl(s->pBA0 + BA0_MIDSR) & 0x80)) {
+		ch = readl(s->pBA0 + BA0_MIDRP);
+		if (s->midi.icnt < MIDIINBUF) {
+			s->midi.ibuf[s->midi.iwr] = ch;
+			s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF;
+			s->midi.icnt++;
+		}
+		wake = 1;
+	}
+	if (wake)
+		wake_up(&s->midi.iwait);
+	wake = 0;
+	while (!(readl(s->pBA0 + BA0_MIDSR) & 0x40) && s->midi.ocnt > 0) {
+		temp1 = (s->midi.obuf[s->midi.ord]) & 0x000000ff;
+		writel(temp1, s->pBA0 + BA0_MIDWP);
+		s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF;
+		s->midi.ocnt--;
+		if (s->midi.ocnt < MIDIOUTBUF - 16)
+			wake = 1;
+	}
+	if (wake)
+		wake_up(&s->midi.owait);
+}
+
+
+
+static void cs4281_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct cs4281_state *s = (struct cs4281_state *) dev_id;
+	unsigned int temp1;
+
+	// fastpath out, to ease interrupt sharing 
+	temp1 = readl(s->pBA0 + BA0_HISR);	// Get Int Status reg.
+
+	CS_DBGOUT(CS_INTERRUPT, 6, printk(KERN_INFO
+		  "cs4281: cs4281_interrupt() BA0_HISR=0x%.8x\n", temp1));
+/*
+* If not DMA or MIDI interrupt, then just return.
+*/
+	if (!(temp1 & (HISR_DMA0 | HISR_DMA1 | HISR_MIDI))) {
+		writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);
+		CS_DBGOUT(CS_INTERRUPT, 9, printk(KERN_INFO
+			"cs4281: cs4281_interrupt(): returning not cs4281 interrupt.\n"));
+		return;
+	}
+
+	if (temp1 & HISR_DMA0)	// If play interrupt,
+		readl(s->pBA0 + BA0_HDSR0);	//   clear the source.
+
+	if (temp1 & HISR_DMA1)	// Same for play.
+		readl(s->pBA0 + BA0_HDSR1);
+	writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);	// Local EOI
+
+	spin_lock(&s->lock);
+	cs4281_update_ptr(s,CS_TRUE);
+	cs4281_handle_midi(s);
+	spin_unlock(&s->lock);
+}
+
+// **************************************************************************
+
+static void cs4281_midi_timer(unsigned long data)
+{
+	struct cs4281_state *s = (struct cs4281_state *) data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&s->lock, flags);
+	cs4281_handle_midi(s);
+	spin_unlock_irqrestore(&s->lock, flags);
+	s->midi.timer.expires = jiffies + 1;
+	add_timer(&s->midi.timer);
+}
+
+
+// --------------------------------------------------------------------- 
+
+static ssize_t cs4281_midi_read(struct file *file, char *buffer,
+				size_t count, loff_t * ppos)
+{
+	struct cs4281_state *s =
+	    (struct cs4281_state *) file->private_data;
+	ssize_t ret;
+	unsigned long flags;
+	unsigned ptr;
+	int cnt;
+
+	VALIDATE_STATE(s);
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	if (!access_ok(VERIFY_WRITE, buffer, count))
+		return -EFAULT;
+	ret = 0;
+	while (count > 0) {
+		spin_lock_irqsave(&s->lock, flags);
+		ptr = s->midi.ird;
+		cnt = MIDIINBUF - ptr;
+		if (s->midi.icnt < cnt)
+			cnt = s->midi.icnt;
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (cnt > count)
+			cnt = count;
+		if (cnt <= 0) {
+			if (file->f_flags & O_NONBLOCK)
+				return ret ? ret : -EAGAIN;
+			interruptible_sleep_on(&s->midi.iwait);
+			if (signal_pending(current))
+				return ret ? ret : -ERESTARTSYS;
+			continue;
+		}
+		if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt))
+			return ret ? ret : -EFAULT;
+		ptr = (ptr + cnt) % MIDIINBUF;
+		spin_lock_irqsave(&s->lock, flags);
+		s->midi.ird = ptr;
+		s->midi.icnt -= cnt;
+		spin_unlock_irqrestore(&s->lock, flags);
+		count -= cnt;
+		buffer += cnt;
+		ret += cnt;
+	}
+	return ret;
+}
+
+
+static ssize_t cs4281_midi_write(struct file *file, const char *buffer,
+				 size_t count, loff_t * ppos)
+{
+	struct cs4281_state *s =
+	    (struct cs4281_state *) file->private_data;
+	ssize_t ret;
+	unsigned long flags;
+	unsigned ptr;
+	int cnt;
+
+	VALIDATE_STATE(s);
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	if (!access_ok(VERIFY_READ, buffer, count))
+		return -EFAULT;
+	ret = 0;
+	while (count > 0) {
+		spin_lock_irqsave(&s->lock, flags);
+		ptr = s->midi.owr;
+		cnt = MIDIOUTBUF - ptr;
+		if (s->midi.ocnt + cnt > MIDIOUTBUF)
+			cnt = MIDIOUTBUF - s->midi.ocnt;
+		if (cnt <= 0)
+			cs4281_handle_midi(s);
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (cnt > count)
+			cnt = count;
+		if (cnt <= 0) {
+			if (file->f_flags & O_NONBLOCK)
+				return ret ? ret : -EAGAIN;
+			interruptible_sleep_on(&s->midi.owait);
+			if (signal_pending(current))
+				return ret ? ret : -ERESTARTSYS;
+			continue;
+		}
+		if (copy_from_user(s->midi.obuf + ptr, buffer, cnt))
+			return ret ? ret : -EFAULT;
+		ptr = (ptr + cnt) % MIDIOUTBUF;
+		spin_lock_irqsave(&s->lock, flags);
+		s->midi.owr = ptr;
+		s->midi.ocnt += cnt;
+		spin_unlock_irqrestore(&s->lock, flags);
+		count -= cnt;
+		buffer += cnt;
+		ret += cnt;
+		spin_lock_irqsave(&s->lock, flags);
+		cs4281_handle_midi(s);
+		spin_unlock_irqrestore(&s->lock, flags);
+	}
+	return ret;
+}
+
+
+static unsigned int cs4281_midi_poll(struct file *file,
+				     struct poll_table_struct *wait)
+{
+	struct cs4281_state *s =
+	    (struct cs4281_state *) file->private_data;
+	unsigned long flags;
+	unsigned int mask = 0;
+
+	VALIDATE_STATE(s);
+	if (file->f_flags & FMODE_WRITE)
+		poll_wait(file, &s->midi.owait, wait);
+	if (file->f_flags & FMODE_READ)
+		poll_wait(file, &s->midi.iwait, wait);
+	spin_lock_irqsave(&s->lock, flags);
+	if (file->f_flags & FMODE_READ) {
+		if (s->midi.icnt > 0)
+			mask |= POLLIN | POLLRDNORM;
+	}
+	if (file->f_flags & FMODE_WRITE) {
+		if (s->midi.ocnt < MIDIOUTBUF)
+			mask |= POLLOUT | POLLWRNORM;
+	}
+	spin_unlock_irqrestore(&s->lock, flags);
+	return mask;
+}
+
+
+static int cs4281_midi_open(struct inode *inode, struct file *file)
+{
+	unsigned long flags, temp1;
+	int minor = MINOR(inode->i_rdev);
+	struct cs4281_state *s=NULL;
+	struct list_head *entry;
+	list_for_each(entry, &cs4281_devs)
+	{
+		s = list_entry(entry, struct cs4281_state, list);
+
+		if (s->dev_midi == minor)
+			break;
+	}
+
+	if (entry == &cs4281_devs)
+		return -ENODEV;
+	if (!s)
+	{
+		CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO
+			"cs4281: cs4281_open(): Error - unable to find audio state struct\n"));
+		return -ENODEV;
+	}
+	VALIDATE_STATE(s);
+	file->private_data = s;
+	// wait for device to become free 
+	down(&s->open_sem);
+	while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
+		if (file->f_flags & O_NONBLOCK) {
+			up(&s->open_sem);
+			return -EBUSY;
+		}
+		up(&s->open_sem);
+		interruptible_sleep_on(&s->open_wait);
+		if (signal_pending(current))
+			return -ERESTARTSYS;
+		down(&s->open_sem);
+	}
+	spin_lock_irqsave(&s->lock, flags);
+	if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
+		s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
+		s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
+		writel(1, s->pBA0 + BA0_MIDCR);	// Reset the interface.
+		writel(0, s->pBA0 + BA0_MIDCR);	// Return to normal mode.
+		s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
+		writel(0x0000000f, s->pBA0 + BA0_MIDCR);	// Enable transmit, record, ints.
+		temp1 = readl(s->pBA0 + BA0_HIMR);
+		writel(temp1 & 0xffbfffff, s->pBA0 + BA0_HIMR);	// Enable midi int. recognition.
+		writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);	// Enable interrupts
+		init_timer(&s->midi.timer);
+		s->midi.timer.expires = jiffies + 1;
+		s->midi.timer.data = (unsigned long) s;
+		s->midi.timer.function = cs4281_midi_timer;
+		add_timer(&s->midi.timer);
+	}
+	if (file->f_mode & FMODE_READ) {
+		s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
+	}
+	if (file->f_mode & FMODE_WRITE) {
+		s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
+	}
+	spin_unlock_irqrestore(&s->lock, flags);
+	s->open_mode |=
+	    (file->
+	     f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ |
+					    FMODE_MIDI_WRITE);
+	up(&s->open_sem);
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+
+static int cs4281_midi_release(struct inode *inode, struct file *file)
+{
+	struct cs4281_state *s =
+	    (struct cs4281_state *) file->private_data;
+	DECLARE_WAITQUEUE(wait, current);
+	unsigned long flags;
+	unsigned count, tmo;
+
+	VALIDATE_STATE(s);
+
+	if (file->f_mode & FMODE_WRITE) {
+		add_wait_queue(&s->midi.owait, &wait);
+		for (;;) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			spin_lock_irqsave(&s->lock, flags);
+			count = s->midi.ocnt;
+			spin_unlock_irqrestore(&s->lock, flags);
+			if (count <= 0)
+				break;
+			if (signal_pending(current))
+				break;
+			if (file->f_flags & O_NONBLOCK) {
+				remove_wait_queue(&s->midi.owait, &wait);
+				current->state = TASK_RUNNING;
+				return -EBUSY;
+			}
+			tmo = (count * HZ) / 3100;
+			if (!schedule_timeout(tmo ? : 1) && tmo)
+				printk(KERN_DEBUG
+				       "cs4281: midi timed out??\n");
+		}
+		remove_wait_queue(&s->midi.owait, &wait);
+		current->state = TASK_RUNNING;
+	}
+	down(&s->open_sem);
+	s->open_mode &=
+	    (~(file->f_mode << FMODE_MIDI_SHIFT)) & (FMODE_MIDI_READ |
+						     FMODE_MIDI_WRITE);
+	spin_lock_irqsave(&s->lock, flags);
+	if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
+		writel(0, s->pBA0 + BA0_MIDCR);	// Disable Midi interrupts.  
+		del_timer(&s->midi.timer);
+	}
+	spin_unlock_irqrestore(&s->lock, flags);
+	up(&s->open_sem);
+	wake_up(&s->open_wait);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+// ******************************************************************************************
+//   Midi file operations struct.
+// ******************************************************************************************
+static /*const */ struct file_operations cs4281_midi_fops = {
+	llseek:cs4281_llseek,
+	read:cs4281_midi_read,
+	write:cs4281_midi_write,
+	poll:cs4281_midi_poll,
+	open:cs4281_midi_open,
+	release:cs4281_midi_release,
+};
+
+
+// --------------------------------------------------------------------- 
+
+// maximum number of devices 
+#define NR_DEVICE 8		// Only eight devices supported currently.
+
+// --------------------------------------------------------------------- 
+
+static struct initvol {
+	int mixch;
+	int vol;
+} initvol[] __initdata = {
+
+	{
+	SOUND_MIXER_WRITE_VOLUME, 0x4040}, {
+	SOUND_MIXER_WRITE_PCM, 0x4040}, {
+	SOUND_MIXER_WRITE_SYNTH, 0x4040}, {
+	SOUND_MIXER_WRITE_CD, 0x4040}, {
+	SOUND_MIXER_WRITE_LINE, 0x4040}, {
+	SOUND_MIXER_WRITE_LINE1, 0x4040}, {
+	SOUND_MIXER_WRITE_RECLEV, 0x0000}, {
+	SOUND_MIXER_WRITE_SPEAKER, 0x4040}, {
+	SOUND_MIXER_WRITE_MIC, 0x0000}
+};
+
+
+#ifndef NOT_CS4281_PM
+void __devinit cs4281_BuildFIFO(
+	struct cs4281_pipeline *p, 
+	struct cs4281_state *s)
+{
+	switch(p->number)
+	{
+		case 0:  /* playback */
+		{
+			p->u32FCRnAddress  =  BA0_FCR0;
+			p->u32FSICnAddress = BA0_FSIC0;
+			p->u32FPDRnAddress = BA0_FPDR0;
+			break;
+		}
+		case 1:  /* capture */
+		{
+			p->u32FCRnAddress  =  BA0_FCR1;
+			p->u32FSICnAddress = BA0_FSIC1;
+			p->u32FPDRnAddress = BA0_FPDR1;
+			break;
+		}
+
+		case 2: 
+		{
+			p->u32FCRnAddress  =  BA0_FCR2;
+			p->u32FSICnAddress = BA0_FSIC2;
+			p->u32FPDRnAddress = BA0_FPDR2;
+			break;
+		}
+		case 3: 
+		{
+			p->u32FCRnAddress  =  BA0_FCR3;
+			p->u32FSICnAddress = BA0_FSIC3;
+			p->u32FPDRnAddress = BA0_FPDR3;
+			break;
+		}
+		default:
+			break;
+	}
+	//
+	// first read the hardware to initialize the member variables
+	//
+	p->u32FCRnValue = readl(s->pBA0 + p->u32FCRnAddress);
+	p->u32FSICnValue = readl(s->pBA0 + p->u32FSICnAddress);
+	p->u32FPDRnValue = readl(s->pBA0 + p->u32FPDRnAddress);
+
+}
+
+void __devinit cs4281_BuildDMAengine(
+	struct cs4281_pipeline *p, 
+	struct cs4281_state *s)
+{
+/*
+* initialize all the addresses of this pipeline dma info.
+*/
+	switch(p->number)
+	{
+		case 0:  /* playback */
+		{
+			p->u32DBAnAddress = BA0_DBA0;
+			p->u32DCAnAddress = BA0_DCA0;
+			p->u32DBCnAddress = BA0_DBC0;
+			p->u32DCCnAddress = BA0_DCC0;
+			p->u32DMRnAddress = BA0_DMR0;
+			p->u32DCRnAddress = BA0_DCR0;
+			p->u32HDSRnAddress = BA0_HDSR0;
+			break;
+		}
+
+		case 1: /* capture */
+		{
+			p->u32DBAnAddress = BA0_DBA1;
+			p->u32DCAnAddress = BA0_DCA1;
+			p->u32DBCnAddress = BA0_DBC1;
+			p->u32DCCnAddress = BA0_DCC1;
+			p->u32DMRnAddress = BA0_DMR1;
+			p->u32DCRnAddress = BA0_DCR1;
+			p->u32HDSRnAddress = BA0_HDSR1;
+			break;
+		}
+
+		case 2:
+		{
+			p->u32DBAnAddress = BA0_DBA2;
+			p->u32DCAnAddress = BA0_DCA2;
+			p->u32DBCnAddress = BA0_DBC2;
+			p->u32DCCnAddress = BA0_DCC2;
+			p->u32DMRnAddress = BA0_DMR2;
+			p->u32DCRnAddress = BA0_DCR2;
+			p->u32HDSRnAddress = BA0_HDSR2;
+			break;
+		}
+
+		case 3:
+		{
+			p->u32DBAnAddress = BA0_DBA3;
+			p->u32DCAnAddress = BA0_DCA3;
+			p->u32DBCnAddress = BA0_DBC3;
+			p->u32DCCnAddress = BA0_DCC3;
+			p->u32DMRnAddress = BA0_DMR3;
+			p->u32DCRnAddress = BA0_DCR3;
+			p->u32HDSRnAddress = BA0_HDSR3;
+			break;
+		}
+		default:
+			break;
+	}
+
+//
+// Initialize the dma values for this pipeline
+//
+	p->u32DBAnValue = readl(s->pBA0 + p->u32DBAnAddress);
+	p->u32DBCnValue = readl(s->pBA0 + p->u32DBCnAddress);
+	p->u32DMRnValue = readl(s->pBA0 + p->u32DMRnAddress);
+	p->u32DCRnValue = readl(s->pBA0 + p->u32DCRnAddress);
+
+}
+
+void __devinit cs4281_InitPM(struct cs4281_state *s)
+{
+	int i;
+	struct cs4281_pipeline *p;
+
+	for(i=0;i<CS4281_NUMBER_OF_PIPELINES;i++)
+	{
+		p = &s->pl[i];
+		p->number = i;
+		cs4281_BuildDMAengine(p,s);
+		cs4281_BuildFIFO(p,s);
+	/*
+	* currently only  2 pipelines are used
+	* so, only set the valid bit on the playback and capture.
+	*/
+		if( (i == CS4281_PLAYBACK_PIPELINE_NUMBER) || 
+			(i == CS4281_CAPTURE_PIPELINE_NUMBER))
+			p->flags |= CS4281_PIPELINE_VALID;
+	}
+	s->pm.u32SSPM_BITS = 0x7e;  /* rev c, use 0x7c for rev a or b */
+}
+#endif
+
+static int __devinit cs4281_probe(struct pci_dev *pcidev,
+				  const struct pci_device_id *pciid)
+{
+#ifndef NOT_CS4281_PM
+	struct pm_dev *pmdev;
+#endif
+	struct cs4281_state *s;
+	dma_addr_t dma_mask;
+	mm_segment_t fs;
+	int i, val;
+	unsigned int temp1, temp2;
+
+	CS_DBGOUT(CS_FUNCTION | CS_INIT, 2,
+		  printk(KERN_INFO "cs4281: probe()+\n"));
+
+	if (!RSRCISMEMORYREGION(pcidev, 0) ||
+	    !RSRCISMEMORYREGION(pcidev, 1)) {
+		CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
+			 "cs4281: probe()- Memory region not assigned\n"));
+		return -1;
+	}
+	if (pcidev->irq == 0) {
+		CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
+			 "cs4281: probe() IRQ not assigned\n"));
+		return -1;
+	}
+	if (!pci_dma_supported(pcidev, 0xffffffff)) {
+		CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
+		      "cs4281: probe() architecture does not support 32bit PCI busmaster DMA\n"));
+		return -1;
+	}
+	dma_mask = 0xffffffff;	/* this enables playback and recording */
+	if (!(s = kmalloc(sizeof(struct cs4281_state), GFP_KERNEL))) {
+		CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
+		      "cs4281: probe() no memory for state struct.\n"));
+		return -1;
+	}
+	memset(s, 0, sizeof(struct cs4281_state));
+	init_waitqueue_head(&s->dma_adc.wait);
+	init_waitqueue_head(&s->dma_dac.wait);
+	init_waitqueue_head(&s->open_wait);
+	init_waitqueue_head(&s->open_wait_adc);
+	init_waitqueue_head(&s->open_wait_dac);
+	init_waitqueue_head(&s->midi.iwait);
+	init_waitqueue_head(&s->midi.owait);
+	init_MUTEX(&s->open_sem);
+	init_MUTEX(&s->open_sem_adc);
+	init_MUTEX(&s->open_sem_dac);
+	spin_lock_init(&s->lock);
+	s->pBA0phys = RSRCADDRESS(pcidev, 0);
+	s->pBA1phys = RSRCADDRESS(pcidev, 1);
+
+	/* Convert phys to linear. */
+	s->pBA0 = ioremap_nocache(s->pBA0phys, 4096);
+	if (!s->pBA0) {
+		CS_DBGOUT(CS_ERROR | CS_INIT, 1, printk(KERN_ERR
+			 "cs4281: BA0 I/O mapping failed. Skipping part.\n"));
+		goto err_free;
+	}
+	s->pBA1 = ioremap_nocache(s->pBA1phys, 65536);
+	if (!s->pBA1) {
+		CS_DBGOUT(CS_ERROR | CS_INIT, 1, printk(KERN_ERR
+			 "cs4281: BA1 I/O mapping failed. Skipping part.\n"));
+		goto err_unmap;
+	}
+
+	temp1 = readl(s->pBA0 + BA0_PCICFG00);
+	temp2 = readl(s->pBA0 + BA0_PCICFG04);
+
+	CS_DBGOUT(CS_INIT, 2,
+		  printk(KERN_INFO
+			 "cs4281: probe() BA0=0x%.8x BA1=0x%.8x pBA0=0x%.8x pBA1=0x%.8x \n",
+			 (unsigned) temp1, (unsigned) temp2,
+			 (unsigned) s->pBA0, (unsigned) s->pBA1));
+
+	CS_DBGOUT(CS_INIT, 2,
+		  printk(KERN_INFO
+			 "cs4281: probe() pBA0phys=0x%.8x pBA1phys=0x%.8x\n",
+			 (unsigned) s->pBA0phys, (unsigned) s->pBA1phys));
+
+#ifndef NOT_CS4281_PM
+	s->pm.flags = CS4281_PM_IDLE;
+#endif
+	temp1 = cs4281_hw_init(s);
+	if (temp1) {
+		CS_DBGOUT(CS_ERROR | CS_INIT, 1, printk(KERN_ERR
+			 "cs4281: cs4281_hw_init() failed. Skipping part.\n"));
+		goto err_irq;
+	}
+	s->magic = CS4281_MAGIC;
+	s->pcidev = pcidev;
+	s->irq = pcidev->irq;
+	if (pci_enable_device(pcidev)) {
+		CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR
+			 "cs4281: pci_enable_device() failed\n"));
+		goto err_irq;
+	}
+	if (request_irq
+	    (s->irq, cs4281_interrupt, SA_SHIRQ, "Crystal CS4281", s)) {
+		CS_DBGOUT(CS_INIT | CS_ERROR, 1,
+			  printk(KERN_ERR "cs4281: irq %u in use\n", s->irq));
+		goto err_irq;
+	}
+	if ((s->dev_audio = register_sound_dsp(&cs4281_audio_fops, -1)) <
+	    0) {
+		CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR
+			 "cs4281: probe() register_sound_dsp() failed.\n"));
+		goto err_dev1;
+	}
+	if ((s->dev_mixer = register_sound_mixer(&cs4281_mixer_fops, -1)) <
+	    0) {
+		CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR
+			 "cs4281: probe() register_sound_mixer() failed.\n"));
+		goto err_dev2;
+	}
+	if ((s->dev_midi = register_sound_midi(&cs4281_midi_fops, -1)) < 0) {
+		CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR
+			 "cs4281: probe() register_sound_midi() failed.\n"));
+		goto err_dev3;
+	}
+#ifndef NOT_CS4281_PM
+	cs4281_InitPM(s);
+	pmdev = cs_pm_register(PM_PCI_DEV, PM_PCI_ID(pcidev), cs4281_pm_callback);
+	if (pmdev)
+	{
+		CS_DBGOUT(CS_INIT | CS_PM, 4, printk(KERN_INFO
+			 "cs4281: probe() pm_register() succeeded (0x%x).\n",
+				(unsigned)pmdev));
+		pmdev->data = s;
+	}
+	else
+	{
+		CS_DBGOUT(CS_INIT | CS_PM | CS_ERROR, 0, printk(KERN_INFO
+			 "cs4281: probe() pm_register() failed (0x%x).\n",
+				(unsigned)pmdev));
+		s->pm.flags |= CS4281_PM_NOT_REGISTERED;
+	}
+#endif
+
+	pci_set_master(pcidev);	// enable bus mastering 
+
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+	val = SOUND_MASK_LINE;
+	mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long) &val);
+	for (i = 0; i < sizeof(initvol) / sizeof(initvol[0]); i++) {
+		val = initvol[i].vol;
+		mixer_ioctl(s, initvol[i].mixch, (unsigned long) &val);
+	}
+	val = 1;		// enable mic preamp 
+	mixer_ioctl(s, SOUND_MIXER_PRIVATE1, (unsigned long) &val);
+	set_fs(fs);
+
+	PCI_SET_DRIVER_DATA(pcidev, s);
+	PCI_SET_DMA_MASK(pcidev, dma_mask);
+	list_add(&s->list, &cs4281_devs);
+	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO
+		"cs4281: probe()- device allocated successfully\n"));
+	return 0;
+
+      err_dev3:
+	unregister_sound_mixer(s->dev_mixer);
+      err_dev2:
+	unregister_sound_dsp(s->dev_audio);
+      err_dev1:
+	free_irq(s->irq, s);
+      err_irq:
+	iounmap(s->pBA1);
+      err_unmap:
+	iounmap(s->pBA0);
+      err_free:
+	kfree(s);
+
+	CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_INFO
+		"cs4281: probe()- no device allocated\n"));
+	return -ENODEV;
+} // probe_cs4281
+
+
+// --------------------------------------------------------------------- 
+
+static void __devinit cs4281_remove(struct pci_dev *pci_dev)
+{
+	struct cs4281_state *s = PCI_GET_DRIVER_DATA(pci_dev);
+	// stop DMA controller 
+	synchronize_irq();
+	free_irq(s->irq, s);
+	unregister_sound_dsp(s->dev_audio);
+	unregister_sound_mixer(s->dev_mixer);
+	unregister_sound_midi(s->dev_midi);
+	iounmap(s->pBA1);
+	iounmap(s->pBA0);
+	kfree(s);
+	PCI_SET_DRIVER_DATA(pci_dev,NULL);
+	list_del(&s->list);
+	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO
+		 "cs4281: cs4281_remove()-: remove successful\n"));
+}
+
+static struct pci_device_id cs4281_pci_tbl[] __devinitdata = {
+	{PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CRYSTAL_CS4281,
+	 PCI_ANY_ID, PCI_ANY_ID, 0, 0},
+	{0,}
+};
+
+MODULE_DEVICE_TABLE(pci, cs4281_pci_tbl);
+
+struct pci_driver cs4281_pci_driver = {
+	name:"cs4281",
+	id_table:cs4281_pci_tbl,
+	probe:cs4281_probe,
+	remove:cs4281_remove,
+	suspend:CS4281_SUSPEND_TBL,
+	resume:CS4281_RESUME_TBL,
+};
+
+int __init cs4281_init_module(void)
+{
+	int rtn = 0;
+	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO 
+		"cs4281: cs4281_init_module()+ \n"));
+	if (!pci_present()) {	/* No PCI bus in this machine! */
+		CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO
+			"cs4281: cs4281_init_module()- no pci bus found\n"));
+		return -ENODEV;
+	}
+	printk(KERN_INFO "cs4281: version v%d.%02d.%d time " __TIME__ " "
+	       __DATE__ "\n", CS4281_MAJOR_VERSION, CS4281_MINOR_VERSION,
+	       CS4281_ARCH);
+	rtn = pci_module_init(&cs4281_pci_driver);
+
+	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
+		  printk(KERN_INFO "cs4281: cs4281_init_module()- (%d)\n",rtn));
+	return rtn;
+}
+
+void __exit cs4281_cleanup_module(void)
+{
+	pci_unregister_driver(&cs4281_pci_driver);
+#ifndef NOT_CS4281_PM
+	cs_pm_unregister_all(cs4281_pm_callback);
+#endif
+	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
+		  printk(KERN_INFO "cs4281: cleanup_cs4281() finished\n"));
+}
+// --------------------------------------------------------------------- 
+
+MODULE_AUTHOR("gw boynton, audio@crystal.cirrus.com");
+MODULE_DESCRIPTION("Cirrus Logic CS4281 Driver");
+
+// --------------------------------------------------------------------- 
+
+module_init(cs4281_init_module);
+module_exit(cs4281_cleanup_module);
+
+#ifndef MODULE
+int __init init_cs4281(void)
+{
+	return cs4281_init_module();
+}
+#endif
diff -urN linux-2.4.2-pre1/drivers/sound/cs4281/cs4281pm-24.c linux/drivers/sound/cs4281/cs4281pm-24.c
--- linux-2.4.2-pre1/drivers/sound/cs4281/cs4281pm-24.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/sound/cs4281/cs4281pm-24.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,84 @@
+/*******************************************************************************
+*
+*      "cs4281pm.c" --  Cirrus Logic-Crystal CS4281 linux audio driver.
+*
+*      Copyright (C) 2000,2001  Cirrus Logic Corp.  
+*            -- tom woller (twoller@crystal.cirrus.com) or
+*               (audio@crystal.cirrus.com).
+*
+*      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.
+*
+* 12/22/00 trw - new file. 
+*
+*******************************************************************************/
+
+#ifndef NOT_CS4281_PM
+#include <linux/pm.h>
+
+#define cs_pm_register(a, b, c) pm_register((a), (b), (c));
+#define cs_pm_unregister_all(a) pm_unregister_all((a));
+
+int cs4281_suspend(struct cs4281_state *s);
+int cs4281_resume(struct cs4281_state *s);
+/* 
+* for now (12/22/00) only enable the pm_register PM support.
+* allow these table entries to be null.
+#define CS4281_SUSPEND_TBL cs4281_suspend_tbl
+#define CS4281_RESUME_TBL cs4281_resume_tbl
+*/
+#define CS4281_SUSPEND_TBL cs4281_null
+#define CS4281_RESUME_TBL cs4281_null
+
+int cs4281_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
+{
+	struct cs4281_state *state;
+
+	CS_DBGOUT(CS_PM, 2, printk(KERN_INFO 
+		"cs4281: cs4281_pm_callback dev=0x%x rqst=0x%x state=%d\n",
+			(unsigned)dev,(unsigned)rqst,(unsigned)data));
+	state = (struct cs4281_state *) dev->data;
+	if (state) {
+		switch(rqst) {
+			case PM_SUSPEND:
+				CS_DBGOUT(CS_PM, 2, printk(KERN_INFO
+					"cs4281: PM suspend request\n"));
+				if(cs4281_suspend(state))
+				{
+				    CS_DBGOUT(CS_ERROR, 2, printk(KERN_INFO
+					"cs4281: PM suspend request refused\n"));
+					return 1; 
+				}
+				break;
+			case PM_RESUME:
+				CS_DBGOUT(CS_PM, 2, printk(KERN_INFO
+					"cs4281: PM resume request\n"));
+				if(cs4281_resume(state))
+				{
+				    CS_DBGOUT(CS_ERROR, 2, printk(KERN_INFO
+					"cs4281: PM resume request refused\n"));
+					return 1;
+				}
+				break;
+		}
+	}
+
+	return 0;
+}
+
+#else /* CS4281_PM */
+#define CS4281_SUSPEND_TBL cs4281_null
+#define CS4281_RESUME_TBL cs4281_null
+#endif /* CS4281_PM */
+
diff -urN linux-2.4.2-pre1/drivers/sound/cs4281/cs4281pm.h linux/drivers/sound/cs4281/cs4281pm.h
--- linux-2.4.2-pre1/drivers/sound/cs4281/cs4281pm.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/sound/cs4281/cs4281pm.h	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,74 @@
+#ifndef NOT_CS4281_PM
+/*******************************************************************************
+*
+*      "cs4281pm.h" --  Cirrus Logic-Crystal CS4281 linux audio driver.
+*
+*      Copyright (C) 2000,2001  Cirrus Logic Corp.  
+*            -- tom woller (twoller@crystal.cirrus.com) or
+*               (audio@crystal.cirrus.com).
+*
+*      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.
+*
+* 12/22/00 trw - new file. 
+*
+*******************************************************************************/
+/* general pm definitions */
+#define CS4281_AC97_HIGHESTREGTORESTORE 0x26
+#define CS4281_AC97_NUMBER_RESTORE_REGS (CS4281_AC97_HIGHESTREGTORESTORE/2-1)
+
+/* pipeline definitions */
+#define CS4281_NUMBER_OF_PIPELINES 	4
+#define CS4281_PIPELINE_VALID 		0x0001
+#define CS4281_PLAYBACK_PIPELINE_NUMBER	0x0000
+#define CS4281_CAPTURE_PIPELINE_NUMBER 	0x0001
+
+/* PM state defintions */
+#define CS4281_PM_NOT_REGISTERED	0x1000
+#define CS4281_PM_IDLE			0x0001
+#define CS4281_PM_SUSPENDING		0x0002
+#define CS4281_PM_SUSPENDED		0x0004
+#define CS4281_PM_RESUMING		0x0008
+#define CS4281_PM_RESUMED		0x0010
+
+struct cs4281_pm {
+	unsigned long flags;
+	u32 u32CLKCR1_SAVE,u32SSPMValue,u32PPLVCvalue,u32PPRVCvalue;
+	u32 u32FMLVCvalue,u32FMRVCvalue,u32GPIORvalue,u32JSCTLvalue,u32SSCR;
+	u32 u32SRCSA,u32DacASR,u32AdcASR,u32DacSR,u32AdcSR,u32MIDCR_Save;
+	u32 u32SSPM_BITS;
+	u32 ac97[CS4281_AC97_NUMBER_RESTORE_REGS];
+	u32 u32AC97_master_volume, u32AC97_headphone_volume, u32AC97_master_volume_mono;
+	u32 u32AC97_pcm_out_volume, u32AC97_powerdown, u32AC97_general_purpose;
+	u32 u32hwptr_playback,u32hwptr_capture;
+};
+
+struct cs4281_pipeline {
+	unsigned flags;
+	unsigned number;
+	u32 u32DBAnValue,u32DBCnValue,u32DMRnValue,u32DCRnValue;
+	u32 u32DBAnAddress,u32DCAnAddress,u32DBCnAddress,u32DCCnAddress;
+	u32 u32DMRnAddress,u32DCRnAddress,u32HDSRnAddress;
+	u32 u32DBAn_Save,u32DBCn_Save,u32DMRn_Save,u32DCRn_Save;
+	u32 u32DCCn_Save,u32DCAn_Save;
+/* 
+* technically, these are fifo variables, but just map the 
+* first fifo with the first pipeline and then use the fifo
+* variables inside of the pipeline struct.
+*/
+	u32 u32FCRn_Save,u32FSICn_Save;
+	u32 u32FCRnValue,u32FCRnAddress,u32FSICnValue,u32FSICnAddress;
+	u32 u32FPDRnValue,u32FPDRnAddress;
+};
+#endif
diff -urN linux-2.4.2-pre1/drivers/sound/cs4281.c linux/drivers/sound/cs4281.c
--- linux-2.4.2-pre1/drivers/sound/cs4281.c	Fri Dec 29 14:35:47 2000
+++ linux/drivers/sound/cs4281.c	Wed Dec 31 16:00:00 1969
@@ -1,3799 +0,0 @@
-//*****************************************************************************
-//
-//      "cs4281.c" --  Cirrus Logic-Crystal CS4281 linux audio driver.
-//
-//      Copyright (C) 2000  Cirrus Logic Corp.  
-//            -- adapted from drivers by Thomas Sailer, 
-//            -- but don't bug him; Problems should go to:
-//            -- gw boynton (wesb@crystal.cirrus.com) or
-//            -- tom woller (twoller@crystal.cirrus.com).
-//
-//      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.
-//
-// Module command line parameters:
-//   none
-//
-//  Supported devices:
-//  /dev/dsp    standard /dev/dsp device, (mostly) OSS compatible
-//  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible
-//  /dev/midi   simple MIDI UART interface, no ioctl
-//
-// Modification History
-// 08/20/00 trw - silence and no stopping DAC until release
-// 08/23/00 trw - added CS_DBG statements, fix interrupt hang issue on DAC stop.
-// 09/18/00 trw - added 16bit only record with conversion 
-// 09/24/00 trw - added Enhanced Full duplex (separate simultaneous 
-//                capture/playback rates)
-// 10/03/00 trw - fixed mmap (fixed GRECORD and the XMMS mmap test plugin  
-//                libOSSm.so)
-// 10/11/00 trw - modified for 2.4.0-test9 kernel enhancements (NR_MAP removal)
-// 11/03/00 trw - fixed interrupt loss/stutter, added debug.
-// 11/10/00 bkz - added __devinit to cs4281_hw_init()
-//
-// *****************************************************************************
-
-#include <linux/config.h>
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/malloc.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/bitops.h>
-#include <linux/spinlock.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/smp_lock.h>
-#include <linux/wrapper.h>
-#include <asm/uaccess.h>
-#include <asm/hardirq.h>
-//#include <linux/vmalloc.h>
-#include "dm.h"
-#include "cs4281_hwdefs.h"
-
-EXPORT_NO_SYMBOLS;
-
-#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-
-// --------------------------------------------------------------------- 
-
-#ifndef PCI_VENDOR_ID_CIRRUS
-#define PCI_VENDOR_ID_CIRRUS          0x1013
-#endif
-#ifndef PCI_DEVICE_ID_CRYSTAL_CS4281
-#define PCI_DEVICE_ID_CRYSTAL_CS4281  0x6005
-#endif
-
-#define CS4281_MAGIC  ((PCI_DEVICE_ID_CRYSTAL_CS4281<<16) | PCI_VENDOR_ID_CIRRUS)
-
-// Turn on/off debugging compilation by using 1/0 respectively for CSDEBUG
-//
-#define CSDEBUG_INTERFACE 1
-#define CSDEBUG 1
-//
-// CSDEBUG is usual mode is set to 1, then use the
-// cs_debuglevel and cs_debugmask to turn on or off debugging.
-// Debug level of 1 has been defined to be kernel errors and info
-// that should be printed on any released driver.
-//
-#if CSDEBUG
-extern unsigned long cs_debugmask;
-extern unsigned long cs_debuglevel;
-#define CS_DBGOUT(mask,level,x) if((cs_debuglevel >= (level)) && ((mask) & cs_debugmask) ) {x;}
-#else
-#define CS_DBGOUT(mask,level,x)
-#endif
-//
-// cs_debugmask areas
-//
-#define CS_INIT	 	0x00000001	// initialization and probe functions
-#define CS_ERROR 	0x00000002	// tmp debugging bit placeholder
-#define CS_INTERRUPT	0x00000004	// interrupt handler (separate from all other)
-#define CS_FUNCTION 	0x00000008	// enter/leave functions
-#define CS_WAVE_WRITE 	0x00000010	// write information for wave
-#define CS_WAVE_READ 	0x00000020	// read information for wave
-#define CS_MIDI_WRITE 	0x00000040	// write information for midi
-#define CS_MIDI_READ 	0x00000080	// read information for midi
-#define CS_MPU401_WRITE 0x00000100	// write information for mpu401
-#define CS_MPU401_READ 	0x00000200	// read information for mpu401
-#define CS_OPEN		0x00000400	// all open functions in the driver
-#define CS_RELEASE	0x00000800	// all release functions in the driver
-#define CS_PARMS	0x00001000	// functional and operational parameters
-#define CS_IOCTL	0x00002000	// ioctl (non-mixer)
-#define CS_TMP		0x10000000	// tmp debug mask bit
-
-#if CSDEBUG
-static unsigned long cs_debuglevel = 1;	// levels range from 1-9
-static unsigned long cs_debugmask = CS_INIT | CS_ERROR;	// use CS_DBGOUT with various mask values
-#if MODULE
-MODULE_PARM(cs_debuglevel, "i");
-MODULE_PARM(cs_debugmask, "i");
-#endif
-#endif
-
-// MIDI buffer sizes 
-#define MIDIINBUF  500
-#define MIDIOUTBUF 500
-
-#define FMODE_MIDI_SHIFT 3
-#define FMODE_MIDI_READ  (FMODE_READ << FMODE_MIDI_SHIFT)
-#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT)
-
-#define RSRCISIOREGION(dev,num) ((dev)->resource[(num)].start != 0 && \
-	 ((dev)->resource[(num)].flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
-#define RSRCISMEMORYREGION(dev,num) ((dev)->resource[(num)].start != 0 && \
-	 ((dev)->resource[(num)].flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY)
-#define RSRCADDRESS(dev,num) ((dev)->resource[(num)].start)
-
-#define CS4281_MAJOR_VERSION 	1
-#define CS4281_MINOR_VERSION 	1
-#ifdef __ia64__
-#define CS4281_ARCH	     	64	//architecture key
-#else
-#define CS4281_ARCH	     	32	//architecture key
-#endif
-
-#define CS_TYPE_ADC 0
-#define CS_TYPE_DAC 1
-
-struct cs4281_state {
-	// magic 
-	unsigned int magic;
-
-	// we keep the cards in a linked list 
-	struct cs4281_state *next;
-
-	// pcidev is needed to turn off the DDMA controller at driver shutdown 
-	struct pci_dev *pcidev;
-
-	// soundcore stuff 
-	int dev_audio;
-	int dev_mixer;
-	int dev_midi;
-
-	// hardware resources 
-	unsigned int pBA0phys, pBA1phys;
-	char *pBA0, *pBA1;
-	unsigned int irq;
-
-	// mixer registers 
-	struct {
-		unsigned short vol[10];
-		unsigned int recsrc;
-		unsigned int modcnt;
-		unsigned short micpreamp;
-	} mix;
-
-	// wave stuff   
-	struct properties {
-		unsigned fmt;
-		unsigned fmt_original;	// original requested format
-		unsigned channels;
-		unsigned rate;
-		unsigned char clkdiv;
-	} prop_dac, prop_adc;
-	unsigned conversion:1;	// conversion from 16 to 8 bit in progress
-	void *tmpbuff;		// tmp buffer for sample conversions
-	unsigned ena;
-	spinlock_t lock;
-	struct semaphore open_sem;
-	struct semaphore open_sem_adc;
-	struct semaphore open_sem_dac;
-	mode_t open_mode;
-	wait_queue_head_t open_wait;
-	wait_queue_head_t open_wait_adc;
-	wait_queue_head_t open_wait_dac;
-
-	dma_addr_t dmaaddr_tmpbuff;
-	unsigned buforder_tmpbuff;	// Log base 2 of 'rawbuf' size in bytes..
-	struct dmabuf {
-		void *rawbuf;	// Physical address of  
-		dma_addr_t dmaaddr;
-		unsigned buforder;	// Log base 2 of 'rawbuf' size in bytes..
-		unsigned numfrag;	// # of 'fragments' in the buffer.
-		unsigned fragshift;	// Log base 2 of fragment size.
-		unsigned hwptr, swptr;
-		unsigned total_bytes;	// # bytes process since open.
-		unsigned blocks;	// last returned blocks value GETOPTR
-		unsigned wakeup;	// interrupt occurred on block 
-		int count;
-		unsigned error;	// over/underrun 
-		wait_queue_head_t wait;
-		// redundant, but makes calculations easier 
-		unsigned fragsize;	// 2**fragshift..
-		unsigned dmasize;	// 2**buforder.
-		unsigned fragsamples;
-		// OSS stuff 
-		unsigned mapped:1;	// Buffer mapped in cs4281_mmap()?
-		unsigned ready:1;	// prog_dmabuf_dac()/adc() successful?
-		unsigned endcleared:1;
-		unsigned type:1;	// adc or dac buffer (CS_TYPE_XXX)
-		unsigned ossfragshift;
-		int ossmaxfrags;
-		unsigned subdivision;
-	} dma_dac, dma_adc;
-
-	// midi stuff 
-	struct {
-		unsigned ird, iwr, icnt;
-		unsigned ord, owr, ocnt;
-		wait_queue_head_t iwait;
-		wait_queue_head_t owait;
-		struct timer_list timer;
-		unsigned char ibuf[MIDIINBUF];
-		unsigned char obuf[MIDIOUTBUF];
-	} midi;
-
-};
-
-#if CSDEBUG
-
-// DEBUG ROUTINES
-
-#define SOUND_MIXER_CS_GETDBGLEVEL 	_SIOWR('M',120, int)
-#define SOUND_MIXER_CS_SETDBGLEVEL 	_SIOWR('M',121, int)
-#define SOUND_MIXER_CS_GETDBGMASK 	_SIOWR('M',122, int)
-#define SOUND_MIXER_CS_SETDBGMASK 	_SIOWR('M',123, int)
-
-#define SNDCTL_DSP_CS_GETDBGLEVEL 	_SIOWR('P', 50, int)
-#define SNDCTL_DSP_CS_SETDBGLEVEL 	_SIOWR('P', 51, int)
-#define SNDCTL_DSP_CS_GETDBGMASK 	_SIOWR('P', 52, int)
-#define SNDCTL_DSP_CS_SETDBGMASK 	_SIOWR('P', 53, int)
-
-static void printioctl(unsigned int x)
-{
-	unsigned int i;
-	unsigned char vidx;
-	// Index of mixtable1[] member is Device ID 
-	// and must be <= SOUND_MIXER_NRDEVICES.
-	// Value of array member is index into s->mix.vol[]
-	static const unsigned char mixtable1[SOUND_MIXER_NRDEVICES] = {
-		[SOUND_MIXER_PCM] = 1,	// voice 
-		[SOUND_MIXER_LINE1] = 2,	// AUX
-		[SOUND_MIXER_CD] = 3,	// CD 
-		[SOUND_MIXER_LINE] = 4,	// Line 
-		[SOUND_MIXER_SYNTH] = 5,	// FM
-		[SOUND_MIXER_MIC] = 6,	// Mic 
-		[SOUND_MIXER_SPEAKER] = 7,	// Speaker 
-		[SOUND_MIXER_RECLEV] = 8,	// Recording level 
-		[SOUND_MIXER_VOLUME] = 9	// Master Volume 
-	};
-
-	switch (x) {
-	case SOUND_MIXER_CS_GETDBGMASK:
-		CS_DBGOUT(CS_IOCTL, 4,
-			  printk("SOUND_MIXER_CS_GETDBGMASK:\n"));
-		break;
-	case SOUND_MIXER_CS_GETDBGLEVEL:
-		CS_DBGOUT(CS_IOCTL, 4,
-			  printk("SOUND_MIXER_CS_GETDBGLEVEL:\n"));
-		break;
-	case SOUND_MIXER_CS_SETDBGMASK:
-		CS_DBGOUT(CS_IOCTL, 4,
-			  printk("SOUND_MIXER_CS_SETDBGMASK:\n"));
-		break;
-	case SOUND_MIXER_CS_SETDBGLEVEL:
-		CS_DBGOUT(CS_IOCTL, 4,
-			  printk("SOUND_MIXER_CS_SETDBGLEVEL:\n"));
-		break;
-	case OSS_GETVERSION:
-		CS_DBGOUT(CS_IOCTL, 4, printk("OSS_GETVERSION:\n"));
-		break;
-	case SNDCTL_DSP_SYNC:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SYNC:\n"));
-		break;
-	case SNDCTL_DSP_SETDUPLEX:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETDUPLEX:\n"));
-		break;
-	case SNDCTL_DSP_GETCAPS:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETCAPS:\n"));
-		break;
-	case SNDCTL_DSP_RESET:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_RESET:\n"));
-		break;
-	case SNDCTL_DSP_SPEED:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SPEED:\n"));
-		break;
-	case SNDCTL_DSP_STEREO:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_STEREO:\n"));
-		break;
-	case SNDCTL_DSP_CHANNELS:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_CHANNELS:\n"));
-		break;
-	case SNDCTL_DSP_GETFMTS:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETFMTS:\n"));
-		break;
-	case SNDCTL_DSP_SETFMT:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETFMT:\n"));
-		break;
-	case SNDCTL_DSP_POST:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_POST:\n"));
-		break;
-	case SNDCTL_DSP_GETTRIGGER:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETTRIGGER:\n"));
-		break;
-	case SNDCTL_DSP_SETTRIGGER:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETTRIGGER:\n"));
-		break;
-	case SNDCTL_DSP_GETOSPACE:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETOSPACE:\n"));
-		break;
-	case SNDCTL_DSP_GETISPACE:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETISPACE:\n"));
-		break;
-	case SNDCTL_DSP_NONBLOCK:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_NONBLOCK:\n"));
-		break;
-	case SNDCTL_DSP_GETODELAY:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETODELAY:\n"));
-		break;
-	case SNDCTL_DSP_GETIPTR:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETIPTR:\n"));
-		break;
-	case SNDCTL_DSP_GETOPTR:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETOPTR:\n"));
-		break;
-	case SNDCTL_DSP_GETBLKSIZE:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETBLKSIZE:\n"));
-		break;
-	case SNDCTL_DSP_SETFRAGMENT:
-		CS_DBGOUT(CS_IOCTL, 4,
-			  printk("SNDCTL_DSP_SETFRAGMENT:\n"));
-		break;
-	case SNDCTL_DSP_SUBDIVIDE:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SUBDIVIDE:\n"));
-		break;
-	case SOUND_PCM_READ_RATE:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_PCM_READ_RATE:\n"));
-		break;
-	case SOUND_PCM_READ_CHANNELS:
-		CS_DBGOUT(CS_IOCTL, 4,
-			  printk("SOUND_PCM_READ_CHANNELS:\n"));
-		break;
-	case SOUND_PCM_READ_BITS:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_PCM_READ_BITS:\n"));
-		break;
-	case SOUND_PCM_WRITE_FILTER:
-		CS_DBGOUT(CS_IOCTL, 4,
-			  printk("SOUND_PCM_WRITE_FILTER:\n"));
-		break;
-	case SNDCTL_DSP_SETSYNCRO:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETSYNCRO:\n"));
-		break;
-	case SOUND_PCM_READ_FILTER:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_PCM_READ_FILTER:\n"));
-		break;
-	case SNDCTL_DSP_CS_GETDBGMASK:
-		CS_DBGOUT(CS_IOCTL, 4,
-			  printk("SNDCTL_DSP_CS_GETDBGMASK:\n"));
-		break;
-	case SNDCTL_DSP_CS_GETDBGLEVEL:
-		CS_DBGOUT(CS_IOCTL, 4,
-			  printk("SNDCTL_DSP_CS_GETDBGLEVEL:\n"));
-		break;
-	case SNDCTL_DSP_CS_SETDBGMASK:
-		CS_DBGOUT(CS_IOCTL, 4,
-			  printk("SNDCTL_DSP_CS_SETDBGMASK:\n"));
-		break;
-	case SNDCTL_DSP_CS_SETDBGLEVEL:
-		CS_DBGOUT(CS_IOCTL, 4,
-			  printk("SNDCTL_DSP_CS_SETDBGLEVEL:\n"));
-		break;
-
-	case SOUND_MIXER_PRIVATE1:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE1:\n"));
-		break;
-	case SOUND_MIXER_PRIVATE2:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE2:\n"));
-		break;
-	case SOUND_MIXER_PRIVATE3:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE3:\n"));
-		break;
-	case SOUND_MIXER_PRIVATE4:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE4:\n"));
-		break;
-	case SOUND_MIXER_PRIVATE5:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE5:\n"));
-		break;
-	case SOUND_MIXER_INFO:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_INFO:\n"));
-		break;
-	case SOUND_OLD_MIXER_INFO:
-		CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_OLD_MIXER_INFO:\n"));
-		break;
-
-	default:
-		switch (_IOC_NR(x)) {
-		case SOUND_MIXER_VOLUME:
-			CS_DBGOUT(CS_IOCTL, 4,
-				  printk("SOUND_MIXER_VOLUME:\n"));
-			break;
-		case SOUND_MIXER_SPEAKER:
-			CS_DBGOUT(CS_IOCTL, 4,
-				  printk("SOUND_MIXER_SPEAKER:\n"));
-			break;
-		case SOUND_MIXER_RECLEV:
-			CS_DBGOUT(CS_IOCTL, 4,
-				  printk("SOUND_MIXER_RECLEV:\n"));
-			break;
-		case SOUND_MIXER_MIC:
-			CS_DBGOUT(CS_IOCTL, 4,
-				  printk("SOUND_MIXER_MIC:\n"));
-			break;
-		case SOUND_MIXER_SYNTH:
-			CS_DBGOUT(CS_IOCTL, 4,
-				  printk("SOUND_MIXER_SYNTH:\n"));
-			break;
-		case SOUND_MIXER_RECSRC:
-			CS_DBGOUT(CS_IOCTL, 4,
-				  printk("SOUND_MIXER_RECSRC:\n"));
-			break;
-		case SOUND_MIXER_DEVMASK:
-			CS_DBGOUT(CS_IOCTL, 4,
-				  printk("SOUND_MIXER_DEVMASK:\n"));
-			break;
-		case SOUND_MIXER_RECMASK:
-			CS_DBGOUT(CS_IOCTL, 4,
-				  printk("SOUND_MIXER_RECMASK:\n"));
-			break;
-		case SOUND_MIXER_STEREODEVS:
-			CS_DBGOUT(CS_IOCTL, 4,
-				  printk("SOUND_MIXER_STEREODEVS:\n"));
-			break;
-		case SOUND_MIXER_CAPS:
-			CS_DBGOUT(CS_IOCTL, 4,
-				  printk("SOUND_MIXER_CAPS:\n"));
-			break;
-		default:
-			i = _IOC_NR(x);
-			if (i >= SOUND_MIXER_NRDEVICES
-			    || !(vidx = mixtable1[i])) {
-				CS_DBGOUT(CS_IOCTL, 4,
-					  printk
-					  ("UNKNOWN IOCTL: 0x%.8x NR=%d\n",
-					   x, i));
-			} else {
-				CS_DBGOUT(CS_IOCTL, 4,
-					  printk
-					  ("SOUND_MIXER_IOCTL AC9x: 0x%.8x NR=%d\n",
-					   x, i));
-			}
-			break;
-		}
-	}
-}
-#endif
-static int prog_dmabuf_adc(struct cs4281_state *s);
-static void prog_codec(struct cs4281_state *s, unsigned type);
-
-static struct cs4281_state *devs = NULL;
-// --------------------------------------------------------------------- 
-//
-//              Hardware Interfaces For the CS4281
-//
-
-
-//******************************************************************************
-// "delayus()-- Delay for the specified # of microseconds.
-//******************************************************************************
-static void delayus(u32 delay)
-{
-	u32 j;
-	if (delay > 9999) {
-		j = (delay * HZ) / 1000000;	/* calculate delay in jiffies  */
-		if (j < 1)
-			j = 1;	/* minimum one jiffy. */
-		current->state = TASK_UNINTERRUPTIBLE;
-		schedule_timeout(j);
-	} else
-		udelay(delay);
-	return;
-}
-
-
-//******************************************************************************
-// "cs4281_read_ac97" -- Reads a word from the specified location in the
-//               CS4281's address space(based on the BA0 register).
-//
-// 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
-// 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 register,
-//                                            0h for reads.
-// 3. Write ACCTL = Control Register = 460h for initiating the write
-// 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 17h
-// 5. if DCV not cleared, break and return error
-// 6. Read ACSTS = Status Register = 464h, check VSTS bit
-//****************************************************************************
-static int cs4281_read_ac97(struct cs4281_state *card, u32 offset,
-			    u32 * value)
-{
-	u32 count, status;
-
-	// Make sure that there is not data sitting
-	// around from a previous uncompleted access.
-	// ACSDA = Status Data Register = 47Ch
-	status = readl(card->pBA0 + BA0_ACSDA);
-
-	// Setup the AC97 control registers on the CS4281 to send the
-	// appropriate command to the AC97 to perform the read.
-	// ACCAD = Command Address Register = 46Ch
-	// ACCDA = Command Data Register = 470h
-	// ACCTL = Control Register = 460h
-	// bit DCV - will clear when process completed
-	// bit CRW - Read command
-	// bit VFRM - valid frame enabled
-	// bit ESYN - ASYNC generation enabled
-
-	// Get the actual AC97 register from the offset
-	writel(offset - BA0_AC97_RESET, card->pBA0 + BA0_ACCAD);
-	writel(0, card->pBA0 + BA0_ACCDA);
-	writel(ACCTL_DCV | ACCTL_CRW | ACCTL_VFRM | ACCTL_ESYN,
-	       card->pBA0 + BA0_ACCTL);
-
-	// Wait for the read to occur.
-	for (count = 0; count < 10; count++) {
-		// First, we want to wait for a short time.
-		udelay(25);
-
-		// Now, check to see if the read has completed.
-		// ACCTL = 460h, DCV should be reset by now and 460h = 17h
-		if (!(readl(card->pBA0 + BA0_ACCTL) & ACCTL_DCV))
-			break;
-	}
-
-	// Make sure the read completed.
-	if (readl(card->pBA0 + BA0_ACCTL) & ACCTL_DCV)
-		return 1;
-
-	// Wait for the valid status bit to go active.
-	for (count = 0; count < 10; count++) {
-		// Read the AC97 status register.
-		// ACSTS = Status Register = 464h
-		status = readl(card->pBA0 + BA0_ACSTS);
-
-		// See if we have valid status.
-		// VSTS - Valid Status
-		if (status & ACSTS_VSTS)
-			break;
-		// Wait for a short while.
-		udelay(25);
-	}
-
-	// Make sure we got valid status.
-	if (!(status & ACSTS_VSTS))
-		return 1;
-
-	// Read the data returned from the AC97 register.
-	// ACSDA = Status Data Register = 474h
-	*value = readl(card->pBA0 + BA0_ACSDA);
-
-	// Success.
-	return (0);
-}
-
-
-//****************************************************************************
-//
-// "cs4281_write_ac97()"-- writes a word to the specified location in the
-// CS461x's address space (based on the part's base address zero register).
-//
-// 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
-// 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 reg.
-// 3. Write ACCTL = Control Register = 460h for initiating the write
-// 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 07h
-// 5. if DCV not cleared, break and return error
-//
-//****************************************************************************
-static int cs4281_write_ac97(struct cs4281_state *card, u32 offset,
-			     u32 value)
-{
-	u32 count, status;
-
-	CS_DBGOUT(CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: cs_4281_write_ac97()+ \n"));
-
-	// Setup the AC97 control registers on the CS4281 to send the
-	// appropriate command to the AC97 to perform the read.
-	// ACCAD = Command Address Register = 46Ch
-	// ACCDA = Command Data Register = 470h
-	// ACCTL = Control Register = 460h
-	// set DCV - will clear when process completed
-	// reset CRW - Write command
-	// set VFRM - valid frame enabled
-	// set ESYN - ASYNC generation enabled
-	// set RSTN - ARST# inactive, AC97 codec not reset
-
-	// Get the actual AC97 register from the offset
-
-	writel(offset - BA0_AC97_RESET, card->pBA0 + BA0_ACCAD);
-	writel(value, card->pBA0 + BA0_ACCDA);
-	writel(ACCTL_DCV | ACCTL_VFRM | ACCTL_ESYN,
-	       card->pBA0 + BA0_ACCTL);
-
-	// Wait for the write to occur.
-	for (count = 0; count < 10; count++) {
-		// First, we want to wait for a short time.
-		udelay(25);
-		// Now, check to see if the write has completed.
-		// ACCTL = 460h, DCV should be reset by now and 460h = 07h
-		status = readl(card->pBA0 + BA0_ACCTL);
-		if (!(status & ACCTL_DCV))
-			break;
-	}
-
-	// Make sure the write completed.
-	if (status & ACCTL_DCV) {
-		CS_DBGOUT(CS_ERROR, 1, printk(KERN_INFO
-					      "cs4281: cs_4281_write_ac97()- unable to write. ACCTL_DCV active\n"));
-		return 1;
-	}
-	CS_DBGOUT(CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: cs_4281_write_ac97()- 0\n"));
-	// Success.
-	return 0;
-}
-
-
-//******************************************************************************
-// "Init4281()" -- Bring up the part.
-//******************************************************************************
-static int __devinit cs4281_hw_init(struct cs4281_state *card)
-{
-	u32 ac97_slotid;
-	u32 temp1, temp2;
-
-	CS_DBGOUT(CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: cs4281_hw_init()+ \n"));
-	//***************************************7
-	//  Set up the Sound System Configuration
-	//***************************************
-
-	// Set the 'Configuration Write Protect' register
-	// to 4281h.  Allows vendor-defined configuration
-	// space between 0e4h and 0ffh to be written.
-
-	writel(0x4281, card->pBA0 + BA0_CWPR);	// (3e0h)
-
-	// (0), Blast the clock control register to zero so that the
-	// PLL starts out in a known state, and blast the master serial
-	// port control register to zero so that the serial ports also
-	// start out in a known state.
-
-	writel(0, card->pBA0 + BA0_CLKCR1);	// (400h)
-	writel(0, card->pBA0 + BA0_SERMC);	// (420h)
-
-
-	// (1), Make ESYN go to zero to turn off
-	// the Sync pulse on the AC97 link.
-
-	writel(0, card->pBA0 + BA0_ACCTL);
-	udelay(50);
-
-
-	// (2) Drive the ARST# pin low for a minimum of 1uS (as defined in
-	// the AC97 spec) and then drive it high.  This is done for non
-	// AC97 modes since there might be logic external to the CS461x
-	// that uses the ARST# line for a reset.
-
-	writel(0, card->pBA0 + BA0_SPMC);	// (3ech)
-	udelay(100);
-	writel(SPMC_RSTN, card->pBA0 + BA0_SPMC);
-	delayus(50000);		// Wait 50 ms for ABITCLK to become stable.
-
-	// (3) Turn on the Sound System Clocks.
-	writel(CLKCR1_PLLP, card->pBA0 + BA0_CLKCR1);	// (400h)
-	delayus(50000);		// Wait for the PLL to stabilize.
-	// Turn on clocking of the core (CLKCR1(400h) = 0x00000030)
-	writel(CLKCR1_PLLP | CLKCR1_SWCE, card->pBA0 + BA0_CLKCR1);
-
-	// (4) Power on everything for now..
-	writel(0x7E, card->pBA0 + BA0_SSPM);	// (740h)
-
-	// (5) Wait for clock stabilization.
-	for (temp1 = 0; temp1 < 1000; temp1++) {
-		udelay(1000);
-		if (readl(card->pBA0 + BA0_CLKCR1) & CLKCR1_DLLRDY)
-			break;
-	}
-	if (!(readl(card->pBA0 + BA0_CLKCR1) & CLKCR1_DLLRDY)) {
-		CS_DBGOUT(CS_ERROR, 1,
-			  printk(KERN_ERR "cs4281: DLLRDY failed!\n"));
-		return -EIO;
-	}
-	// (6) Enable ASYNC generation.
-	writel(ACCTL_ESYN, card->pBA0 + BA0_ACCTL);	// (460h)
-
-	// Now wait 'for a short while' to allow the  AC97
-	// part to start generating bit clock. (so we don't
-	// Try to start the PLL without an input clock.)
-	delayus(50000);
-
-	// Set the serial port timing configuration, so that the
-	// clock control circuit gets its clock from the right place.
-	writel(SERMC_PTC_AC97, card->pBA0 + BA0_SERMC);	// (420h)=2.
-
-	// (7) Wait for the codec ready signal from the AC97 codec.
-
-	for (temp1 = 0; temp1 < 1000; temp1++) {
-		// Delay a mil to let things settle out and
-		// to prevent retrying the read too quickly.
-		udelay(1000);
-		if (readl(card->pBA0 + BA0_ACSTS) & ACSTS_CRDY)	// If ready,  (464h)
-			break;	//   exit the 'for' loop.
-	}
-	if (!(readl(card->pBA0 + BA0_ACSTS) & ACSTS_CRDY))	// If never came ready,
-	{
-		CS_DBGOUT(CS_FUNCTION, 2,
-			  printk(KERN_ERR
-				 "cs4281: ACSTS never came ready!\n"));
-		return -EIO;	//   exit initialization.
-	}
-	// (8) Assert the 'valid frame' signal so we can
-	// begin sending commands to the AC97 codec.
-	writel(ACCTL_VFRM | ACCTL_ESYN, card->pBA0 + BA0_ACCTL);	// (460h)
-
-	// (9), Wait until CODEC calibration is finished.
-	// Print an error message if it doesn't.
-	for (temp1 = 0; temp1 < 1000; temp1++) {
-		delayus(10000);
-		// Read the AC97 Powerdown Control/Status Register.
-		cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp2);
-		if ((temp2 & 0x0000000F) == 0x0000000F)
-			break;
-	}
-	if ((temp2 & 0x0000000F) != 0x0000000F) {
-		CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_ERR
-						 "cs4281: Codec failed to calibrate.  Status = %.8x.\n",
-						 temp2));
-		return -EIO;
-	}
-	// (10), Set the serial port timing configuration, so that the
-	// clock control circuit gets its clock from the right place.
-	writel(SERMC_PTC_AC97, card->pBA0 + BA0_SERMC);	// (420h)=2.
-
-
-	// (11) Wait until we've sampled input slots 3 & 4 as valid, meaning
-	// that the codec is pumping ADC data across the AC link.
-	for (temp1 = 0; temp1 < 1000; temp1++) {
-		// Delay a mil to let things settle out and
-		// to prevent retrying the read too quickly.
-		delayus(1000);	//(test)
-
-		// Read the input slot valid register;  See
-		// if input slots 3 and 4 are valid yet.
-		if (
-		    (readl(card->pBA0 + BA0_ACISV) &
-		     (ACISV_ISV3 | ACISV_ISV4)) ==
-		    (ACISV_ISV3 | ACISV_ISV4)) break;	// Exit the 'for' if slots are valid.
-	}
-	// If we never got valid data, exit initialization.
-	if ((readl(card->pBA0 + BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4))
-	    != (ACISV_ISV3 | ACISV_ISV4)) {
-		CS_DBGOUT(CS_FUNCTION, 2,
-			  printk(KERN_ERR
-				 "cs4281: Never got valid data!\n"));
-		return -EIO;	// If no valid data, exit initialization.
-	}
-	// (12), Start digital data transfer of audio data to the codec.
-	writel(ACOSV_SLV3 | ACOSV_SLV4, card->pBA0 + BA0_ACOSV);	// (468h)
-
-
-	//**************************************
-	// Unmute the Master and Alternate
-	// (headphone) volumes.  Set to max.
-	//**************************************
-	cs4281_write_ac97(card, BA0_AC97_HEADPHONE_VOLUME, 0);
-	cs4281_write_ac97(card, BA0_AC97_MASTER_VOLUME, 0);
-
-	//******************************************
-	// Power on the DAC(AddDACUser()from main())
-	//******************************************
-	cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
-	cs4281_write_ac97(card, BA0_AC97_POWERDOWN, temp1 &= 0xfdff);
-
-	// Wait until we sample a DAC ready state.
-	for (temp2 = 0; temp2 < 32; temp2++) {
-		// Let's wait a mil to let things settle.
-		delayus(1000);
-		// Read the current state of the power control reg.
-		cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
-		// If the DAC ready state bit is set, stop waiting.
-		if (temp1 & 0x2)
-			break;
-	}
-
-	//******************************************
-	// Power on the ADC(AddADCUser()from main())
-	//******************************************
-	cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
-	cs4281_write_ac97(card, BA0_AC97_POWERDOWN, temp1 &= 0xfeff);
-
-	// Wait until we sample ADC ready state.
-	for (temp2 = 0; temp2 < 32; temp2++) {
-		// Let's wait a mil to let things settle.
-		delayus(1000);
-		// Read the current state of the power control reg.
-		cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
-		// If the ADC ready state bit is set, stop waiting.
-		if (temp1 & 0x1)
-			break;
-	}
-	// Set up 4281 Register contents that
-	// don't change for boot duration.
-
-	// For playback, we map AC97 slot 3 and 4(Left
-	// & Right PCM playback) to DMA Channel 0.
-	// Set the fifo to be 15 bytes at offset zero.
-
-	ac97_slotid = 0x01000f00;	// FCR0.RS[4:0]=1(=>slot4, right PCM playback).
-	// FCR0.LS[4:0]=0(=>slot3, left PCM playback).
-	// FCR0.SZ[6-0]=15; FCR0.OF[6-0]=0.
-	writel(ac97_slotid, card->pBA0 + BA0_FCR0);	// (180h)
-	writel(ac97_slotid | FCRn_FEN, card->pBA0 + BA0_FCR0);	// Turn on FIFO Enable.
-
-	// For capture, we map AC97 slot 10 and 11(Left
-	// and Right PCM Record) to DMA Channel 1.
-	// Set the fifo to be 15 bytes at offset sixteen.
-	ac97_slotid = 0x0B0A0f10;	// FCR1.RS[4:0]=11(=>slot11, right PCM record).
-	// FCR1.LS[4:0]=10(=>slot10, left PCM record).
-	// FCR1.SZ[6-0]=15; FCR1.OF[6-0]=16.
-	writel(ac97_slotid | FCRn_PSH, card->pBA0 + BA0_FCR1);	// (184h)
-	writel(ac97_slotid | FCRn_FEN, card->pBA0 + BA0_FCR1);	// Turn on FIFO Enable.
-
-	// Map the Playback SRC to the same AC97 slots(3 & 4--
-	// --Playback left & right)as DMA channel 0.
-	// Map the record SRC to the same AC97 slots(10 & 11--
-	// -- Record left & right) as DMA channel 1.
-
-	ac97_slotid = 0x0b0a0100;	// SCRSA.PRSS[4:0]=1(=>slot4, right PCM playback).
-	// SCRSA.PLSS[4:0]=0(=>slot3, left PCM playback).
-	// SCRSA.CRSS[4:0]=11(=>slot11, right PCM record)
-	// SCRSA.CLSS[4:0]=10(=>slot10, left PCM record).
-	writel(ac97_slotid, card->pBA0 + BA0_SRCSA);	// (75ch)
-
-	// Set 'Half Terminal Count Interrupt Enable' and 'Terminal
-	// Count Interrupt Enable' in DMA Control Registers 0 & 1.
-	// Set 'MSK' flag to 1 to keep the DMA engines paused.
-	temp1 = (DCRn_HTCIE | DCRn_TCIE | DCRn_MSK);	// (00030001h)
-	writel(temp1, card->pBA0 + BA0_DCR0);	// (154h
-	writel(temp1, card->pBA0 + BA0_DCR1);	// (15ch)
-
-	// Set 'Auto-Initialize Control' to 'enabled'; For playback,
-	// set 'Transfer Type Control'(TR[1:0]) to 'read transfer',
-	// for record, set Transfer Type Control to 'write transfer'.
-	// All other bits set to zero;  Some will be changed @ transfer start.
-	temp1 = (DMRn_DMA | DMRn_AUTO | DMRn_TR_READ);	// (20000018h)
-	writel(temp1, card->pBA0 + BA0_DMR0);	// (150h)
-	temp1 = (DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE);	// (20000014h)
-	writel(temp1, card->pBA0 + BA0_DMR1);	// (158h)
-
-	// Enable DMA interrupts generally, and
-	// DMA0 & DMA1 interrupts specifically.
-	temp1 = readl(card->pBA0 + BA0_HIMR) & 0xfffbfcff;
-	writel(temp1, card->pBA0 + BA0_HIMR);
-
-	CS_DBGOUT(CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: cs4281_hw_init()- 0\n"));
-	return 0;
-}
-
-
-//******************************************************************************
-// "cs4281_play_rate()" --
-//******************************************************************************
-static void cs4281_play_rate(struct cs4281_state *card, u32 playrate)
-{
-	u32 DACSRvalue = 1;
-
-	// Based on the sample rate, program the DACSR register.
-	if (playrate == 8000)
-		DACSRvalue = 5;
-	if (playrate == 11025)
-		DACSRvalue = 4;
-	else if (playrate == 22050)
-		DACSRvalue = 2;
-	else if (playrate == 44100)
-		DACSRvalue = 1;
-	else if ((playrate <= 48000) && (playrate >= 6023))
-		DACSRvalue = 24576000 / (playrate * 16);
-	else if (playrate < 6023)
-		// Not allowed by open.
-		return;
-	else if (playrate > 48000)
-		// Not allowed by open.
-		return;
-	CS_DBGOUT(CS_WAVE_WRITE | CS_PARMS, 2, printk(KERN_INFO
-						      "cs4281: cs4281_play_rate(): DACSRvalue=0x%.8x playrate=%d\n",
-						      DACSRvalue,
-						      playrate));
-	//  Write the 'sample rate select code'
-	//  to the 'DAC Sample Rate' register.
-	writel(DACSRvalue, card->pBA0 + BA0_DACSR);	// (744h)
-}
-
-//******************************************************************************
-// "cs4281_record_rate()" -- Initialize the record sample rate converter.
-//******************************************************************************
-static void cs4281_record_rate(struct cs4281_state *card, u32 outrate)
-{
-	u32 ADCSRvalue = 1;
-
-	//
-	// Based on the sample rate, program the ADCSR register
-	//
-	if (outrate == 8000)
-		ADCSRvalue = 5;
-	if (outrate == 11025)
-		ADCSRvalue = 4;
-	else if (outrate == 22050)
-		ADCSRvalue = 2;
-	else if (outrate == 44100)
-		ADCSRvalue = 1;
-	else if ((outrate <= 48000) && (outrate >= 6023))
-		ADCSRvalue = 24576000 / (outrate * 16);
-	else if (outrate < 6023) {
-		// Not allowed by open.
-		return;
-	} else if (outrate > 48000) {
-		// Not allowed by open.
-		return;
-	}
-	CS_DBGOUT(CS_WAVE_READ | CS_PARMS, 2, printk(KERN_INFO
-						     "cs4281: cs4281_record_rate(): ADCSRvalue=0x%.8x outrate=%d\n",
-						     ADCSRvalue, outrate));
-	//  Write the 'sample rate select code
-	//  to the 'ADC Sample Rate' register.
-	writel(ADCSRvalue, card->pBA0 + BA0_ADCSR);	// (748h)
-}
-
-
-
-static void stop_dac(struct cs4281_state *s)
-{
-	unsigned long flags;
-	unsigned temp1;
-
-	CS_DBGOUT(CS_WAVE_WRITE, 3,
-		  printk(KERN_INFO "cs4281: stop_dac():\n"));
-	spin_lock_irqsave(&s->lock, flags);
-	s->ena &= ~FMODE_WRITE;
-	temp1 = readl(s->pBA0 + BA0_DCR0) | DCRn_MSK;
-	writel(temp1, s->pBA0 + BA0_DCR0);
-
-	spin_unlock_irqrestore(&s->lock, flags);
-}
-
-
-static void start_dac(struct cs4281_state *s)
-{
-	unsigned long flags;
-	unsigned temp1;
-
-	CS_DBGOUT(CS_FUNCTION, 3,
-		  printk(KERN_INFO "cs4281: start_dac()+\n"));
-	spin_lock_irqsave(&s->lock, flags);
-	if (!(s->ena & FMODE_WRITE) && (s->dma_dac.mapped ||
-					s->dma_dac.count > 0)
-	    && s->dma_dac.ready) {
-		s->ena |= FMODE_WRITE;
-		temp1 = readl(s->pBA0 + BA0_DCR0) & ~DCRn_MSK;	// Clear DMA0 channel mask.
-		writel(temp1, s->pBA0 + BA0_DCR0);	// Start DMA'ing.
-		writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);	// Enable interrupts.              
-
-		writel(7, s->pBA0 + BA0_PPRVC);
-		writel(7, s->pBA0 + BA0_PPLVC);
-		CS_DBGOUT(CS_WAVE_WRITE | CS_PARMS, 8, printk(KERN_INFO
-							      "cs4281: start_dac(): writel 0x%x start dma\n",
-							      temp1));
-
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	CS_DBGOUT(CS_FUNCTION, 3,
-		  printk(KERN_INFO "cs4281: start_dac()-\n"));
-}
-
-
-static void stop_adc(struct cs4281_state *s)
-{
-	unsigned long flags;
-	unsigned temp1;
-
-	CS_DBGOUT(CS_FUNCTION, 3,
-		  printk(KERN_INFO "cs4281: stop_adc()+\n"));
-
-	spin_lock_irqsave(&s->lock, flags);
-	s->ena &= ~FMODE_READ;
-
-	if (s->conversion == 1) {
-		s->conversion = 0;
-		s->prop_adc.fmt = s->prop_adc.fmt_original;
-	}
-	temp1 = readl(s->pBA0 + BA0_DCR1) | DCRn_MSK;
-	writel(temp1, s->pBA0 + BA0_DCR1);
-	spin_unlock_irqrestore(&s->lock, flags);
-	CS_DBGOUT(CS_FUNCTION, 3,
-		  printk(KERN_INFO "cs4281: stop_adc()-\n"));
-}
-
-
-static void start_adc(struct cs4281_state *s)
-{
-	unsigned long flags;
-	unsigned temp1;
-
-	CS_DBGOUT(CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: start_adc()+\n"));
-
-	spin_lock_irqsave(&s->lock, flags);
-	if (!(s->ena & FMODE_READ) &&
-	    (s->dma_adc.mapped || s->dma_adc.count <=
-	     (signed) (s->dma_adc.dmasize - 2 * s->dma_adc.fragsize))
-	    && s->dma_adc.ready) {
-		if (s->prop_adc.fmt & AFMT_S8 || s->prop_adc.fmt & AFMT_U8) {
-			// 
-			// now only use 16 bit capture, due to truncation issue
-			// in the chip, noticable distortion occurs.
-			// allocate buffer and then convert from 16 bit to 
-			// 8 bit for the user buffer.
-			//
-			s->prop_adc.fmt_original = s->prop_adc.fmt;
-			if (s->prop_adc.fmt & AFMT_S8) {
-				s->prop_adc.fmt &= ~AFMT_S8;
-				s->prop_adc.fmt |= AFMT_S16_LE;
-			}
-			if (s->prop_adc.fmt & AFMT_U8) {
-				s->prop_adc.fmt &= ~AFMT_U8;
-				s->prop_adc.fmt |= AFMT_U16_LE;
-			}
-			//
-			// prog_dmabuf_adc performs a stop_adc() but that is
-			// ok since we really haven't started the DMA yet.
-			//
-			prog_codec(s, CS_TYPE_ADC);
-
-			if (prog_dmabuf_adc(s) != 0) {
-				CS_DBGOUT(CS_ERROR, 3,
-					  printk(KERN_INFO
-						 "cs4281: start_adc(): error in prog_dmabuf_adc\n"));
-			}
-			s->conversion = 1;
-		}
-		s->ena |= FMODE_READ;
-		temp1 = readl(s->pBA0 + BA0_DCR1) & ~DCRn_MSK;	// Clear DMA1 channel mask bit.
-		writel(temp1, s->pBA0 + BA0_DCR1);	// Start recording
-		writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);	// Enable interrupts.
-		CS_DBGOUT(CS_PARMS, 6,
-			  printk(KERN_INFO
-				 "cs4281: start_adc(): writel 0x%x \n",
-				 temp1));
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	CS_DBGOUT(CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: start_adc()-\n"));
-
-}
-
-
-// --------------------------------------------------------------------- 
-// use 64k (+1) rather than 32k as some of the higher frequencies need a larger buffer.
-// comments reflect 32k.
-#define DMABUF_DEFAULTORDER (15-PAGE_SHIFT+1)	// == 3(for PC), = log base 2( buff sz = 32k).
-#define DMABUF_MINORDER 1	// ==> min buffer size = 8K.
-
-
-extern void dealloc_dmabuf(struct cs4281_state *s, struct dmabuf *db)
-{
-	struct page *map, *mapend;
-
-	if (db->rawbuf) {
-		// Undo prog_dmabuf()'s marking the pages as reserved 
-		mapend =
-		    virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) -
-				 1);
-		for (map = virt_to_page(db->rawbuf); map <= mapend; map++)
-			mem_map_unreserve(map);
-		pci_free_consistent(s->pcidev, PAGE_SIZE << db->buforder,
-				    db->rawbuf, db->dmaaddr);
-	}
-	if (s->tmpbuff && (db->type == CS_TYPE_ADC)) {
-		// Undo prog_dmabuf()'s marking the pages as reserved 
-		mapend =
-		    virt_to_page(s->tmpbuff +
-				 (PAGE_SIZE << s->buforder_tmpbuff) - 1);
-		for (map = virt_to_page(s->tmpbuff); map <= mapend; map++)
-			mem_map_unreserve(map);
-		pci_free_consistent(s->pcidev,
-				    PAGE_SIZE << s->buforder_tmpbuff,
-				    s->tmpbuff, s->dmaaddr_tmpbuff);
-	}
-	s->tmpbuff = NULL;
-	db->rawbuf = NULL;
-	db->mapped = db->ready = 0;
-}
-
-static int prog_dmabuf(struct cs4281_state *s, struct dmabuf *db)
-{
-	int order;
-	unsigned bytespersec, temp1;
-	unsigned bufs, sample_shift = 0;
-	struct page *map, *mapend;
-
-	CS_DBGOUT(CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: prog_dmabuf()+\n"));
-	db->hwptr = db->swptr = db->total_bytes = db->count = db->error =
-	    db->endcleared = db->blocks = db->wakeup = 0;
-
-	if (!db->rawbuf) {
-		db->ready = db->mapped = 0;
-		for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER;
-		     order--)
-			if (
-			    (db->rawbuf =
-			     (void *) pci_alloc_consistent(s->pcidev,
-							   PAGE_SIZE <<
-							   order,
-							   &db->
-							   dmaaddr)))
-				    break;
-		if (!db->rawbuf) {
-			CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
-						      "cs4281: prog_dmabuf(): unable to allocate rawbuf\n"));
-			return -ENOMEM;
-		}
-		db->buforder = order;
-		// Now mark the pages as reserved; otherwise the 
-		// remap_page_range() in cs4281_mmap doesn't work.
-		// 1. get index to last page in mem_map array for rawbuf.
-		mapend =
-		    virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) -
-				 1);
-
-		// 2. mark each physical page in range as 'reserved'.
-		for (map = virt_to_page(db->rawbuf); map <= mapend; map++)
-			mem_map_reserve(map);
-	}
-	if (!s->tmpbuff && (db->type == CS_TYPE_ADC)) {
-		for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER;
-		     order--)
-			if (
-			    (s->tmpbuff =
-			     (void *) pci_alloc_consistent(s->pcidev,
-							   PAGE_SIZE <<
-							   order,
-							   &s->
-							   dmaaddr_tmpbuff)))
-				    break;
-		if (!s->tmpbuff) {
-			CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
-						      "cs4281: prog_dmabuf(): unable to allocate tmpbuff\n"));
-			return -ENOMEM;
-		}
-		s->buforder_tmpbuff = order;
-		// Now mark the pages as reserved; otherwise the 
-		// remap_page_range() in cs4281_mmap doesn't work.
-		// 1. get index to last page in mem_map array for rawbuf.
-		mapend =
-		    virt_to_page(s->tmpbuff +
-				 (PAGE_SIZE << s->buforder_tmpbuff) - 1);
-
-		// 2. mark each physical page in range as 'reserved'.
-		for (map = virt_to_page(s->tmpbuff); map <= mapend; map++)
-			mem_map_reserve(map);
-	}
-	if (db->type == CS_TYPE_DAC) {
-		if (s->prop_dac.fmt & (AFMT_S16_LE | AFMT_U16_LE))
-			sample_shift++;
-		if (s->prop_dac.channels > 1)
-			sample_shift++;
-		bytespersec = s->prop_dac.rate << sample_shift;
-	} else			// CS_TYPE_ADC
-	{
-		if (s->prop_adc.fmt & (AFMT_S16_LE | AFMT_U16_LE))
-			sample_shift++;
-		if (s->prop_adc.channels > 1)
-			sample_shift++;
-		bytespersec = s->prop_adc.rate << sample_shift;
-	}
-	bufs = PAGE_SIZE << db->buforder;
-
-
-#define INTERRUPT_RATE_MS       100	// Interrupt rate in milliseconds.
-	db->numfrag = 2;
-	temp1 = bytespersec / (1000 / INTERRUPT_RATE_MS);	// Nominal frag size(bytes/interrupt)
-	db->fragshift = 8;	// Min 256 bytes.
-	while (1 << db->fragshift < temp1)	// Calc power of 2 frag size.
-		db->fragshift += 1;
-	db->fragsize = 1 << db->fragshift;
-	db->dmasize = db->fragsize * 2;
-	db->fragsamples = db->fragsize >> sample_shift;	// # samples/fragment.
-
-// If the calculated size is larger than the allocated
-//  buffer, divide the allocated buffer into 2 fragments.
-	if (db->dmasize > bufs) {
-
-		db->numfrag = 2;	// Two fragments.
-		db->fragsize = bufs >> 1;	// Each 1/2 the alloc'ed buffer.
-		db->fragsamples = db->fragsize >> sample_shift;	// # samples/fragment.
-		db->dmasize = bufs;	// Use all the alloc'ed buffer.
-
-		db->fragshift = 0;	// Calculate 'fragshift'.
-		temp1 = db->fragsize;	// update_ptr() uses it 
-		while ((temp1 >>= 1) > 1)	// to calc 'total-bytes'
-			db->fragshift += 1;	// returned in DSP_GETI/OPTR. 
-	}
-	CS_DBGOUT(CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: prog_dmabuf()-\n"));
-	CS_DBGOUT(CS_PARMS, 8,
-		  printk(KERN_INFO
-			 "cs4281: prog_dmabuf(): numfrag=%d fragsize=%d fragsamples=%d fragshift=%d bufs=%d fmt=0x%x ch=%d\n",
-			 db->numfrag, db->fragsize, db->fragsamples,
-			 db->fragshift, bufs,
-			 (db->type ==
-			  CS_TYPE_DAC) ? s->prop_dac.fmt : s->prop_adc.fmt,
-			 (db->type ==
-			  CS_TYPE_DAC) ? s->prop_dac.channels : s->
-			 prop_adc.channels));
-	return 0;
-}
-
-
-static int prog_dmabuf_adc(struct cs4281_state *s)
-{
-	unsigned long va;
-	unsigned count;
-	int c;
-	stop_adc(s);
-	s->dma_adc.type = CS_TYPE_ADC;
-	if ((c = prog_dmabuf(s, &s->dma_adc)))
-		return c;
-
-	if (s->dma_adc.rawbuf) {
-		memset(s->dma_adc.rawbuf,
-		       (s->prop_adc.
-			fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0,
-		       s->dma_adc.dmasize);
-	}
-	if (s->tmpbuff) {
-		memset(s->tmpbuff,
-		       (s->prop_adc.
-			fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0,
-		       PAGE_SIZE << s->buforder_tmpbuff);
-	}
-
-	va = virt_to_bus(s->dma_adc.rawbuf);
-
-	count = s->dma_adc.dmasize;
-
-	if (s->prop_adc.
-	    fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE))
-		    count /= 2;	// 16-bit.
-
-	if (s->prop_adc.channels > 1)
-		count /= 2;	// Assume stereo.
-
-	CS_DBGOUT(CS_WAVE_READ, 3, printk(KERN_INFO
-					  "cs4281: prog_dmabuf_adc(): count=%d va=0x%.8x\n",
-					  count, (unsigned) va));
-
-	writel(va, s->pBA0 + BA0_DBA1);	// Set buffer start address.
-	writel(count - 1, s->pBA0 + BA0_DBC1);	// Set count. 
-	s->dma_adc.ready = 1;
-	return 0;
-}
-
-
-static int prog_dmabuf_dac(struct cs4281_state *s)
-{
-	unsigned long va;
-	unsigned count;
-	int c;
-	stop_dac(s);
-	s->dma_dac.type = CS_TYPE_DAC;
-	if ((c = prog_dmabuf(s, &s->dma_dac)))
-		return c;
-	memset(s->dma_dac.rawbuf,
-	       (s->prop_dac.fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0,
-	       s->dma_dac.dmasize);
-
-	va = virt_to_bus(s->dma_dac.rawbuf);
-
-	count = s->dma_dac.dmasize;
-	if (s->prop_dac.
-	    fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE))
-		    count /= 2;	// 16-bit.
-
-	if (s->prop_dac.channels > 1)
-		count /= 2;	// Assume stereo.
-
-	writel(va, s->pBA0 + BA0_DBA0);	// Set buffer start address.
-	writel(count - 1, s->pBA0 + BA0_DBC0);	// Set count.             
-
-	CS_DBGOUT(CS_WAVE_WRITE, 3, printk(KERN_INFO
-					   "cs4281: prog_dmabuf_dac(): count=%d va=0x%.8x\n",
-					   count, (unsigned) va));
-
-	s->dma_dac.ready = 1;
-	return 0;
-}
-
-
-static void clear_advance(void *buf, unsigned bsize, unsigned bptr,
-			  unsigned len, unsigned char c)
-{
-	if (bptr + len > bsize) {
-		unsigned x = bsize - bptr;
-		memset(((char *) buf) + bptr, c, x);
-		bptr = 0;
-		len -= x;
-	}
-	CS_DBGOUT(CS_WAVE_WRITE, 4, printk(KERN_INFO
-					   "cs4281: clear_advance(): memset %d at 0x%.8x for %d size \n",
-					   (unsigned) c,
-					   (unsigned) ((char *) buf) +
-					   bptr, len));
-	memset(((char *) buf) + bptr, c, len);
-}
-
-
-
-// call with spinlock held! 
-static void cs4281_update_ptr(struct cs4281_state *s)
-{
-	int diff;
-	unsigned hwptr, va;
-
-	// update ADC pointer 
-	if (s->ena & FMODE_READ) {
-		hwptr = readl(s->pBA0 + BA0_DCA1);	// Read capture DMA address.
-		va = virt_to_bus(s->dma_adc.rawbuf);
-		hwptr -= (unsigned) va;
-		diff =
-		    (s->dma_adc.dmasize + hwptr -
-		     s->dma_adc.hwptr) % s->dma_adc.dmasize;
-		s->dma_adc.hwptr = hwptr;
-		s->dma_adc.total_bytes += diff;
-		s->dma_adc.count += diff;
-		if (s->dma_adc.count > s->dma_adc.dmasize)
-			s->dma_adc.count = s->dma_adc.dmasize;
-		if (s->dma_adc.mapped) {
-			if (s->dma_adc.count >=
-			    (signed) s->dma_adc.fragsize) wake_up(&s->
-								  dma_adc.
-								  wait);
-		} else {
-			if (s->dma_adc.count > 0)
-				wake_up(&s->dma_adc.wait);
-		}
-		CS_DBGOUT(CS_PARMS, 8, printk(KERN_INFO
-					      "cs4281: cs4281_update_ptr(): s=0x%.8x hwptr=%d total_bytes=%d count=%d \n",
-					      (unsigned) s,
-					      s->dma_adc.hwptr,
-					      s->dma_adc.total_bytes,
-					      s->dma_adc.count));
-	}
-	// update DAC pointer 
-	//
-	// check for end of buffer, means that we are going to wait for another interrupt
-	// to allow silence to fill the fifos on the part, to keep pops down to a minimum.
-	//
-	if (s->ena & FMODE_WRITE) {
-		hwptr = readl(s->pBA0 + BA0_DCA0);	// Read play DMA address.
-		va = virt_to_bus(s->dma_dac.rawbuf);
-		hwptr -= (unsigned) va;
-		diff =
-		    (s->dma_dac.dmasize + hwptr -
-		     s->dma_dac.hwptr) % s->dma_dac.dmasize;
-		s->dma_dac.hwptr = hwptr;
-		s->dma_dac.total_bytes += diff;
-		if (s->dma_dac.mapped) {
-			s->dma_dac.count += diff;
-			if (s->dma_dac.count >= s->dma_dac.fragsize) {
-				s->dma_dac.wakeup = 1;
-				wake_up(&s->dma_dac.wait);
-				if (s->dma_dac.count > s->dma_dac.dmasize)
-					s->dma_dac.count &=
-					    s->dma_dac.dmasize - 1;
-			}
-		} else {
-
-			s->dma_dac.count -= diff;
-			if (s->dma_dac.count <= 0) {
-				//
-				// fill with silence, and do not shut down the DAC.
-				// Continue to play silence until the _release.
-				//
-				CS_DBGOUT(CS_WAVE_WRITE, 6,
-					  printk(KERN_INFO
-						 "cs4281: cs4281_update_ptr(): memset %d at 0x%.8x for %d size \n",
-						 (unsigned) (s->prop_dac.
-							     fmt & (AFMT_U8
-								    |
-								    AFMT_U16_LE))
-						 ? 0x80 : 0,
-						 (unsigned) s->dma_dac.
-						 rawbuf,
-						 s->dma_dac.dmasize));
-				memset(s->dma_dac.rawbuf,
-				       (s->prop_dac.
-					fmt & (AFMT_U8 | AFMT_U16_LE)) ?
-				       0x80 : 0, s->dma_dac.dmasize);
-			} else if (s->dma_dac.count <=
-				   (signed) s->dma_dac.fragsize
-				   && !s->dma_dac.endcleared) {
-				clear_advance(s->dma_dac.rawbuf,
-					      s->dma_dac.dmasize,
-					      s->dma_dac.swptr,
-					      s->dma_dac.fragsize,
-					      (s->prop_dac.
-					       fmt & (AFMT_U8 |
-						      AFMT_U16_LE)) ? 0x80
-					      : 0);
-				s->dma_dac.endcleared = 1;
-			}
-			if (s->dma_dac.count < (signed) s->dma_dac.dmasize)
-				wake_up(&s->dma_dac.wait);
-		}
-		CS_DBGOUT(CS_PARMS, 8, printk(KERN_INFO
-					      "cs4281: cs4281_update_ptr(): s=0x%.8x hwptr=%d total_bytes=%d count=%d \n",
-					      (unsigned) s,
-					      s->dma_dac.hwptr,
-					      s->dma_dac.total_bytes,
-					      s->dma_dac.count));
-	}
-}
-
-
-// --------------------------------------------------------------------- 
-
-static void prog_codec(struct cs4281_state *s, unsigned type)
-{
-	unsigned long flags;
-	unsigned temp1, format;
-
-	CS_DBGOUT(CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: prog_codec()+ \n"));
-
-	spin_lock_irqsave(&s->lock, flags);
-	if (type == CS_TYPE_ADC) {
-		temp1 = readl(s->pBA0 + BA0_DCR1);
-		writel(temp1 | DCRn_MSK, s->pBA0 + BA0_DCR1);	// Stop capture DMA, if active.
-
-		// program sampling rates  
-		// Note, for CS4281, capture & play rates can be set independently.
-		cs4281_record_rate(s, s->prop_adc.rate);
-
-		// program ADC parameters 
-		format = DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE;
-		if (s->prop_adc.
-		    fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE)) {	// 16-bit
-			if (s->prop_adc.fmt & (AFMT_S16_BE | AFMT_U16_BE))	// Big-endian?
-				format |= DMRn_BEND;
-			if (s->prop_adc.fmt & (AFMT_U16_LE | AFMT_U16_BE))
-				format |= DMRn_USIGN;	// Unsigned.      
-		} else
-			format |= DMRn_SIZE8 | DMRn_USIGN;	// 8-bit, unsigned
-		if (s->prop_adc.channels < 2)
-			format |= DMRn_MONO;
-
-		writel(format, s->pBA0 + BA0_DMR1);
-
-		CS_DBGOUT(CS_PARMS, 2, printk(KERN_INFO
-					      "cs4281: prog_codec(): adc %s %s %s rate=%d DMR0 format=0x%.8x\n",
-					      (format & DMRn_SIZE8) ? "8" :
-					      "16",
-					      (format & DMRn_USIGN) ?
-					      "Unsigned" : "Signed",
-					      (format & DMRn_MONO) ? "Mono"
-					      : "Stereo", s->prop_adc.rate,
-					      format));
-
-		s->ena &= ~FMODE_READ;	// not capturing data yet
-	}
-
-
-	if (type == CS_TYPE_DAC) {
-		temp1 = readl(s->pBA0 + BA0_DCR0);
-		writel(temp1 | DCRn_MSK, s->pBA0 + BA0_DCR0);	// Stop play DMA, if active.
-
-		// program sampling rates  
-		// Note, for CS4281, capture & play rates can be set independently.
-		cs4281_play_rate(s, s->prop_dac.rate);
-
-		// program DAC parameters 
-		format = DMRn_DMA | DMRn_AUTO | DMRn_TR_READ;
-		if (s->prop_dac.
-		    fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE)) {	// 16-bit
-			if (s->prop_dac.fmt & (AFMT_S16_BE | AFMT_U16_BE))
-				format |= DMRn_BEND;	// Big Endian.
-			if (s->prop_dac.fmt & (AFMT_U16_LE | AFMT_U16_BE))
-				format |= DMRn_USIGN;	// Unsigned.      
-		} else
-			format |= DMRn_SIZE8 | DMRn_USIGN;	// 8-bit, unsigned
-
-		if (s->prop_dac.channels < 2)
-			format |= DMRn_MONO;
-
-		writel(format, s->pBA0 + BA0_DMR0);
-
-
-		CS_DBGOUT(CS_PARMS, 2, printk(KERN_INFO
-					      "cs4281: prog_codec(): dac %s %s %s rate=%d DMR0 format=0x%.8x\n",
-					      (format & DMRn_SIZE8) ? "8" :
-					      "16",
-					      (format & DMRn_USIGN) ?
-					      "Unsigned" : "Signed",
-					      (format & DMRn_MONO) ? "Mono"
-					      : "Stereo", s->prop_dac.rate,
-					      format));
-
-		s->ena &= ~FMODE_WRITE;	// not capturing data yet
-
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	CS_DBGOUT(CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: prog_codec()- \n"));
-}
-
-
-// --------------------------------------------------------------------- 
-
-static const char invalid_magic[] =
-    KERN_CRIT "cs4281: invalid magic value\n";
-
-#define VALIDATE_STATE(s)                         \
-({                                                \
-        if (!(s) || (s)->magic != CS4281_MAGIC) { \
-                printk(invalid_magic);            \
-                return -ENXIO;                    \
-        }                                         \
-})
-
-// --------------------------------------------------------------------- 
-
-
-static int mixer_ioctl(struct cs4281_state *s, unsigned int cmd,
-		       unsigned long arg)
-{
-	// Index to mixer_src[] is value of AC97 Input Mux Select Reg.
-	// Value of array member is recording source Device ID Mask.
-	static const unsigned int mixer_src[8] = {
-		SOUND_MASK_MIC, SOUND_MASK_CD, 0, SOUND_MASK_LINE1,
-		SOUND_MASK_LINE, SOUND_MASK_VOLUME, 0, 0
-	};
-
-	// Index of mixtable1[] member is Device ID 
-	// and must be <= SOUND_MIXER_NRDEVICES.
-	// Value of array member is index into s->mix.vol[]
-	static const unsigned char mixtable1[SOUND_MIXER_NRDEVICES] = {
-		[SOUND_MIXER_PCM] = 1,	// voice 
-		[SOUND_MIXER_LINE1] = 2,	// AUX
-		[SOUND_MIXER_CD] = 3,	// CD 
-		[SOUND_MIXER_LINE] = 4,	// Line 
-		[SOUND_MIXER_SYNTH] = 5,	// FM
-		[SOUND_MIXER_MIC] = 6,	// Mic 
-		[SOUND_MIXER_SPEAKER] = 7,	// Speaker 
-		[SOUND_MIXER_RECLEV] = 8,	// Recording level 
-		[SOUND_MIXER_VOLUME] = 9	// Master Volume 
-	};
-
-
-	static const unsigned mixreg[] = {
-		BA0_AC97_PCM_OUT_VOLUME,
-		BA0_AC97_AUX_VOLUME,
-		BA0_AC97_CD_VOLUME,
-		BA0_AC97_LINE_IN_VOLUME
-	};
-	unsigned char l, r, rl, rr, vidx;
-	unsigned char attentbl[11] =
-	    { 63, 42, 26, 17, 14, 11, 8, 6, 4, 2, 0 };
-	unsigned temp1;
-	int i, val;
-
-	VALIDATE_STATE(s);
-	CS_DBGOUT(CS_FUNCTION, 4,
-		  printk(KERN_INFO
-			 "cs4281: mixer_ioctl(): s=0x%.8x cmd=0x%.8x\n",
-			 (unsigned) s, cmd));
-#if CSDEBUG
-	printioctl(cmd);
-#endif
-#if CSDEBUG_INTERFACE
-
-	if ((cmd == SOUND_MIXER_CS_GETDBGMASK) ||
-	    (cmd == SOUND_MIXER_CS_SETDBGMASK) ||
-	    (cmd == SOUND_MIXER_CS_GETDBGLEVEL) ||
-	    (cmd == SOUND_MIXER_CS_SETDBGLEVEL)) {
-		switch (cmd) {
-
-		case SOUND_MIXER_CS_GETDBGMASK:
-			return put_user(cs_debugmask,
-					(unsigned long *) arg);
-
-		case SOUND_MIXER_CS_GETDBGLEVEL:
-			return put_user(cs_debuglevel,
-					(unsigned long *) arg);
-
-		case SOUND_MIXER_CS_SETDBGMASK:
-			if (get_user(val, (unsigned long *) arg))
-				return -EFAULT;
-			cs_debugmask = val;
-			return 0;
-
-		case SOUND_MIXER_CS_SETDBGLEVEL:
-			if (get_user(val, (unsigned long *) arg))
-				return -EFAULT;
-			cs_debuglevel = val;
-			return 0;
-		default:
-			CS_DBGOUT(CS_ERROR, 1, printk(KERN_INFO
-						      "cs4281: mixer_ioctl(): ERROR unknown debug cmd\n"));
-			return 0;
-		}
-	}
-#endif
-
-	if (cmd == SOUND_MIXER_PRIVATE1) {
-		// enable/disable/query mixer preamp 
-		if (get_user(val, (int *) arg))
-			return -EFAULT;
-		if (val != -1) {
-			cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1);
-			temp1 = val ? (temp1 | 0x40) : (temp1 & 0xffbf);
-			cs4281_write_ac97(s, BA0_AC97_MIC_VOLUME, temp1);
-		}
-		cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1);
-		val = (temp1 & 0x40) ? 1 : 0;
-		return put_user(val, (int *) arg);
-	}
-	if (cmd == SOUND_MIXER_PRIVATE2) {
-		// enable/disable/query spatializer 
-		if (get_user(val, (int *) arg))
-			return -EFAULT;
-		if (val != -1) {
-			temp1 = (val & 0x3f) >> 2;
-			cs4281_write_ac97(s, BA0_AC97_3D_CONTROL, temp1);
-			cs4281_read_ac97(s, BA0_AC97_GENERAL_PURPOSE,
-					 &temp1);
-			cs4281_write_ac97(s, BA0_AC97_GENERAL_PURPOSE,
-					  temp1 | 0x2000);
-		}
-		cs4281_read_ac97(s, BA0_AC97_3D_CONTROL, &temp1);
-		return put_user((temp1 << 2) | 3, (int *) arg);
-	}
-	if (cmd == SOUND_MIXER_INFO) {
-		mixer_info info;
-		strncpy(info.id, "CS4281", sizeof(info.id));
-		strncpy(info.name, "Crystal CS4281", sizeof(info.name));
-		info.modify_counter = s->mix.modcnt;
-		if (copy_to_user((void *) arg, &info, sizeof(info)))
-			return -EFAULT;
-		return 0;
-	}
-	if (cmd == SOUND_OLD_MIXER_INFO) {
-		_old_mixer_info info;
-		strncpy(info.id, "CS4281", sizeof(info.id));
-		strncpy(info.name, "Crystal CS4281", sizeof(info.name));
-		if (copy_to_user((void *) arg, &info, sizeof(info)))
-			return -EFAULT;
-		return 0;
-	}
-	if (cmd == OSS_GETVERSION)
-		return put_user(SOUND_VERSION, (int *) arg);
-
-	if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
-		return -EINVAL;
-
-	// If ioctl has only the SIOC_READ bit(bit 31)
-	// on, process the only-read commands. 
-	if (_SIOC_DIR(cmd) == _SIOC_READ) {
-		switch (_IOC_NR(cmd)) {
-		case SOUND_MIXER_RECSRC:	// Arg contains a bit for each recording source 
-			cs4281_read_ac97(s, BA0_AC97_RECORD_SELECT,
-					 &temp1);
-			return put_user(mixer_src[temp1 & 7], (int *) arg);
-
-		case SOUND_MIXER_DEVMASK:	// Arg contains a bit for each supported device 
-			return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH |
-					SOUND_MASK_CD | SOUND_MASK_LINE |
-					SOUND_MASK_LINE1 | SOUND_MASK_MIC |
-					SOUND_MASK_VOLUME |
-					SOUND_MASK_RECLEV |
-					SOUND_MASK_SPEAKER, (int *) arg);
-
-		case SOUND_MIXER_RECMASK:	// Arg contains a bit for each supported recording source 
-			return put_user(SOUND_MASK_LINE | SOUND_MASK_MIC |
-					SOUND_MASK_CD | SOUND_MASK_VOLUME |
-					SOUND_MASK_LINE1, (int *) arg);
-
-		case SOUND_MIXER_STEREODEVS:	// Mixer channels supporting stereo 
-			return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH |
-					SOUND_MASK_CD | SOUND_MASK_LINE |
-					SOUND_MASK_LINE1 | SOUND_MASK_MIC |
-					SOUND_MASK_VOLUME |
-					SOUND_MASK_RECLEV, (int *) arg);
-
-		case SOUND_MIXER_CAPS:
-			return put_user(SOUND_CAP_EXCL_INPUT, (int *) arg);
-
-		default:
-			i = _IOC_NR(cmd);
-			if (i >= SOUND_MIXER_NRDEVICES
-			    || !(vidx = mixtable1[i]))
-				return -EINVAL;
-			return put_user(s->mix.vol[vidx - 1], (int *) arg);
-		}
-	}
-	// If ioctl doesn't have both the SIOC_READ and 
-	// the SIOC_WRITE bit set, return invalid.
-	if (_SIOC_DIR(cmd) != (_SIOC_READ | _SIOC_WRITE))
-		return -EINVAL;
-
-	// Increment the count of volume writes.
-	s->mix.modcnt++;
-
-	// Isolate the command; it must be a write.
-	switch (_IOC_NR(cmd)) {
-
-	case SOUND_MIXER_RECSRC:	// Arg contains a bit for each recording source 
-		if (get_user(val, (int *) arg))
-			return -EFAULT;
-		i = hweight32(val);	// i = # bits on in val.
-		if (i != 1)	// One & only 1 bit must be on.
-			return 0;
-		for (i = 0; i < sizeof(mixer_src) / sizeof(int); i++) {
-			if (val == mixer_src[i]) {
-				temp1 = (i << 8) | i;
-				cs4281_write_ac97(s,
-						  BA0_AC97_RECORD_SELECT,
-						  temp1);
-				return 0;
-			}
-		}
-		return 0;
-
-	case SOUND_MIXER_VOLUME:
-		if (get_user(val, (int *) arg))
-			return -EFAULT;
-		l = val & 0xff;
-		if (l > 100)
-			l = 100;	// Max soundcard.h vol is 100.
-		if (l < 6) {
-			rl = 63;
-			l = 0;
-		} else
-			rl = attentbl[(10 * l) / 100];	// Convert 0-100 vol to 63-0 atten.
-
-		r = (val >> 8) & 0xff;
-		if (r > 100)
-			r = 100;	// Max right volume is 100, too
-		if (r < 6) {
-			rr = 63;
-			r = 0;
-		} else
-			rr = attentbl[(10 * r) / 100];	// Convert volume to attenuation.
-
-		if ((rl > 60) && (rr > 60))	// If both l & r are 'low',          
-			temp1 = 0x8000;	//  turn on the mute bit.
-		else
-			temp1 = 0;
-
-		temp1 |= (rl << 8) | rr;
-
-		cs4281_write_ac97(s, BA0_AC97_MASTER_VOLUME, temp1);
-		cs4281_write_ac97(s, BA0_AC97_HEADPHONE_VOLUME, temp1);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-		s->mix.vol[8] = ((unsigned int) r << 8) | l;
-#else
-		s->mix.vol[8] = val;
-#endif
-		return put_user(s->mix.vol[8], (int *) arg);
-
-	case SOUND_MIXER_SPEAKER:
-		if (get_user(val, (int *) arg))
-			return -EFAULT;
-		l = val & 0xff;
-		if (l > 100)
-			l = 100;
-		if (l < 3) {
-			rl = 0;
-			l = 0;
-		} else {
-			rl = (l * 2 - 5) / 13;	// Convert 0-100 range to 0-15.
-			l = (rl * 13 + 5) / 2;
-		}
-
-		if (rl < 3) {
-			temp1 = 0x8000;
-			rl = 0;
-		} else
-			temp1 = 0;
-		rl = 15 - rl;	// Convert volume to attenuation.
-		temp1 |= rl << 1;
-		cs4281_write_ac97(s, BA0_AC97_PC_BEEP_VOLUME, temp1);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-		s->mix.vol[6] = l << 8;
-#else
-		s->mix.vol[6] = val;
-#endif
-		return put_user(s->mix.vol[6], (int *) arg);
-
-	case SOUND_MIXER_RECLEV:
-		if (get_user(val, (int *) arg))
-			return -EFAULT;
-		l = val & 0xff;
-		if (l > 100)
-			l = 100;
-		r = (val >> 8) & 0xff;
-		if (r > 100)
-			r = 100;
-		rl = (l * 2 - 5) / 13;	// Convert 0-100 scale to 0-15.
-		rr = (r * 2 - 5) / 13;
-		if (rl < 3 && rr < 3)
-			temp1 = 0x8000;
-		else
-			temp1 = 0;
-
-		temp1 = temp1 | (rl << 8) | rr;
-		cs4281_write_ac97(s, BA0_AC97_RECORD_GAIN, temp1);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-		s->mix.vol[7] = ((unsigned int) r << 8) | l;
-#else
-		s->mix.vol[7] = val;
-#endif
-		return put_user(s->mix.vol[7], (int *) arg);
-
-	case SOUND_MIXER_MIC:
-		if (get_user(val, (int *) arg))
-			return -EFAULT;
-		l = val & 0xff;
-		if (l > 100)
-			l = 100;
-		if (l < 1) {
-			l = 0;
-			rl = 0;
-		} else {
-			rl = ((unsigned) l * 5 - 4) / 16;	// Convert 0-100 range to 0-31.
-			l = (rl * 16 + 4) / 5;
-		}
-		cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1);
-		temp1 &= 0x40;	// Isolate 20db gain bit.
-		if (rl < 3) {
-			temp1 |= 0x8000;
-			rl = 0;
-		}
-		rl = 31 - rl;	// Convert volume to attenuation.
-		temp1 |= rl;
-		cs4281_write_ac97(s, BA0_AC97_MIC_VOLUME, temp1);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-		s->mix.vol[5] = val << 8;
-#else
-		s->mix.vol[5] = val;
-#endif
-		return put_user(s->mix.vol[5], (int *) arg);
-
-
-	case SOUND_MIXER_SYNTH:
-		if (get_user(val, (int *) arg))
-			return -EFAULT;
-		l = val & 0xff;
-		if (l > 100)
-			l = 100;
-		if (get_user(val, (int *) arg))
-			return -EFAULT;
-		r = (val >> 8) & 0xff;
-		if (r > 100)
-			r = 100;
-		rl = (l * 2 - 11) / 3;	// Convert 0-100 range to 0-63.
-		rr = (r * 2 - 11) / 3;
-		if (rl < 3)	// If l is low, turn on
-			temp1 = 0x0080;	//  the mute bit.
-		else
-			temp1 = 0;
-
-		rl = 63 - rl;	// Convert vol to attenuation.
-		writel(temp1 | rl, s->pBA0 + BA0_FMLVC);
-		if (rr < 3)	//  If rr is low, turn on
-			temp1 = 0x0080;	//   the mute bit.
-		else
-			temp1 = 0;
-		rr = 63 - rr;	// Convert vol to attenuation.
-		writel(temp1 | rr, s->pBA0 + BA0_FMRVC);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-		s->mix.vol[4] = (r << 8) | l;
-#else
-		s->mix.vol[4] = val;
-#endif
-		return put_user(s->mix.vol[4], (int *) arg);
-
-
-	default:
-		CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
-					      "cs4281: mixer_ioctl(): default\n"));
-
-		i = _IOC_NR(cmd);
-		if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i]))
-			return -EINVAL;
-		if (get_user(val, (int *) arg))
-			return -EFAULT;
-		l = val & 0xff;
-		if (l > 100)
-			l = 100;
-		if (l < 1) {
-			l = 0;
-			rl = 31;
-		} else
-			rl = (attentbl[(l * 10) / 100]) >> 1;
-
-		r = (val >> 8) & 0xff;
-		if (r > 100)
-			r = 100;
-		if (r < 1) {
-			r = 0;
-			rr = 31;
-		} else
-			rr = (attentbl[(r * 10) / 100]) >> 1;
-		if ((rl > 30) && (rr > 30))
-			temp1 = 0x8000;
-		else
-			temp1 = 0;
-		temp1 = temp1 | (rl << 8) | rr;
-		cs4281_write_ac97(s, mixreg[vidx - 1], temp1);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-		s->mix.vol[vidx - 1] = ((unsigned int) r << 8) | l;
-#else
-		s->mix.vol[vidx - 1] = val;
-#endif
-		return put_user(s->mix.vol[vidx - 1], (int *) arg);
-	}
-}
-
-
-// --------------------------------------------------------------------- 
-
-static loff_t cs4281_llseek(struct file *file, loff_t offset, int origin)
-{
-	return -ESPIPE;
-}
-
-
-// --------------------------------------------------------------------- 
-
-static int cs4281_open_mixdev(struct inode *inode, struct file *file)
-{
-	int minor = MINOR(inode->i_rdev);
-	struct cs4281_state *s = devs;
-
-	while (s && s->dev_mixer != minor)
-		s = s->next;
-	if (!s)
-		return -ENODEV;
-	VALIDATE_STATE(s);
-	file->private_data = s;
-	MOD_INC_USE_COUNT;
-	return 0;
-}
-
-
-static int cs4281_release_mixdev(struct inode *inode, struct file *file)
-{
-	struct cs4281_state *s =
-	    (struct cs4281_state *) file->private_data;
-
-	VALIDATE_STATE(s);
-	MOD_DEC_USE_COUNT;
-	return 0;
-}
-
-
-static int cs4281_ioctl_mixdev(struct inode *inode, struct file *file,
-			       unsigned int cmd, unsigned long arg)
-{
-	return mixer_ioctl((struct cs4281_state *) file->private_data, cmd,
-			   arg);
-}
-
-
-// ******************************************************************************************
-//   Mixer file operations struct.
-// ******************************************************************************************
-static /*const */ struct file_operations cs4281_mixer_fops = {
-	llseek:cs4281_llseek,
-	ioctl:cs4281_ioctl_mixdev,
-	open:cs4281_open_mixdev,
-	release:cs4281_release_mixdev,
-};
-
-// --------------------------------------------------------------------- 
-
-
-static int drain_adc(struct cs4281_state *s, int nonblock)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	int count;
-	unsigned tmo;
-
-	if (s->dma_adc.mapped)
-		return 0;
-	add_wait_queue(&s->dma_adc.wait, &wait);
-	for (;;) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		spin_lock_irqsave(&s->lock, flags);
-		count = s->dma_adc.count;
-		CS_DBGOUT(CS_FUNCTION, 2,
-			  printk(KERN_INFO "cs4281: drain_adc() %d\n",
-				 count));
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (count <= 0) {
-			CS_DBGOUT(CS_FUNCTION, 2,
-				  printk(KERN_INFO
-					 "cs4281: drain_adc() count<0\n"));
-			break;
-		}
-		if (signal_pending(current))
-			break;
-		if (nonblock) {
-			remove_wait_queue(&s->dma_adc.wait, &wait);
-			current->state = TASK_RUNNING;
-			return -EBUSY;
-		}
-		tmo =
-		    3 * HZ * (count +
-			      s->dma_adc.fragsize) / 2 / s->prop_adc.rate;
-		if (s->prop_adc.fmt & (AFMT_S16_LE | AFMT_U16_LE))
-			tmo >>= 1;
-		if (s->prop_adc.channels > 1)
-			tmo >>= 1;
-		if (!schedule_timeout(tmo + 1))
-			printk(KERN_DEBUG "cs4281: dma timed out??\n");
-	}
-	remove_wait_queue(&s->dma_adc.wait, &wait);
-	current->state = TASK_RUNNING;
-	if (signal_pending(current))
-		return -ERESTARTSYS;
-	return 0;
-}
-
-static int drain_dac(struct cs4281_state *s, int nonblock)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	int count;
-	unsigned tmo;
-
-	if (s->dma_dac.mapped)
-		return 0;
-	add_wait_queue(&s->dma_dac.wait, &wait);
-	for (;;) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		spin_lock_irqsave(&s->lock, flags);
-		count = s->dma_dac.count;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (count <= 0)
-			break;
-		if (signal_pending(current))
-			break;
-		if (nonblock) {
-			remove_wait_queue(&s->dma_dac.wait, &wait);
-			current->state = TASK_RUNNING;
-			return -EBUSY;
-		}
-		tmo =
-		    3 * HZ * (count +
-			      s->dma_dac.fragsize) / 2 / s->prop_dac.rate;
-		if (s->prop_dac.fmt & (AFMT_S16_LE | AFMT_U16_LE))
-			tmo >>= 1;
-		if (s->prop_dac.channels > 1)
-			tmo >>= 1;
-		if (!schedule_timeout(tmo + 1))
-			printk(KERN_DEBUG "cs4281: dma timed out??\n");
-	}
-	remove_wait_queue(&s->dma_dac.wait, &wait);
-	current->state = TASK_RUNNING;
-	if (signal_pending(current))
-		return -ERESTARTSYS;
-	return 0;
-}
-
-//****************************************************************************
-//
-// CopySamples copies 16-bit stereo samples from the source to the
-// destination, possibly converting down to either 8-bit or mono or both.
-// count specifies the number of output bytes to write.
-//
-//  Arguments:
-//
-//  dst             - Pointer to a destination buffer.
-//  src             - Pointer to a source buffer
-//  count           - The number of bytes to copy into the destination buffer.
-//  iChannels       - Stereo - 2
-//                    Mono   - 1
-//  fmt             - AFMT_xxx (soundcard.h formats)
-//
-// NOTES: only call this routine for conversion to 8bit from 16bit
-//
-//****************************************************************************
-static void CopySamples(char *dst, char *src, int count, int iChannels,
-			unsigned fmt)
-{
-
-	unsigned short *psSrc;
-	long lAudioSample;
-
-	CS_DBGOUT(CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: CopySamples()+ "));
-	CS_DBGOUT(CS_WAVE_READ, 8,
-		  printk(KERN_INFO
-			 " dst=0x%x src=0x%x count=%d iChannels=%d fmt=0x%x\n",
-			 (unsigned) dst, (unsigned) src, (unsigned) count,
-			 (unsigned) iChannels, (unsigned) fmt));
-
-	// Gershwin does format conversion in hardware so normally
-	// we don't do any host based coversion. The data formatter
-	// truncates 16 bit data to 8 bit and that causes some hiss.
-	// We have already forced the HW to do 16 bit sampling and 
-	// 2 channel so that we can use software to round instead 
-	// of truncate
-
-	//
-	// See if the data should be output as 8-bit unsigned stereo.
-	//
-	if ((iChannels == 2) && (fmt & AFMT_U8)) {
-		//
-		// Convert each 16-bit unsigned stereo sample to 8-bit unsigned 
-		// stereo using rounding.
-		//
-		psSrc = (unsigned short *) src;
-		count = count / 2;
-		while (count--) {
-			lAudioSample = (long) psSrc[count] + (long) 0x80;
-			if (lAudioSample > 0xffff) {
-				lAudioSample = 0xffff;
-			}
-			dst[count] = (char) (lAudioSample >> 8);
-		}
-	}
-	//
-	// check for 8-bit signed stereo.
-	//
-	else if ((iChannels == 2) && (fmt & AFMT_S8)) {
-		//
-		// Convert each 16-bit stereo sample to 8-bit stereo using rounding.
-		//
-		psSrc = (short *) src;
-		while (count--) {
-			lAudioSample =
-			    (((long) psSrc[0] + (long) psSrc[1]) / 2);
-			psSrc += 2;
-			*dst++ = (char) ((short) lAudioSample >> 8);
-		}
-	}
-	//
-	// See if the data should be output at 8-bit unsigned mono.
-	//
-	else if ((iChannels == 1) && (fmt & AFMT_U8)) {
-		//
-		// Convert each 16-bit unsigned mono sample to 8-bit unsigned
-		// mono using rounding.
-		//
-
-		psSrc = (short *) src;
-		while (count--) {
-			lAudioSample = (long) *psSrc++ + (long) 0x80;
-			if (lAudioSample > 0x7fff) {
-				lAudioSample = 0x7fff;
-			}
-			//
-			// Convert Signed to Unsigned.
-			//
-
-			*dst++ =
-			    (unsigned
-			     char) (((short) lAudioSample +
-				     (short) 0x8000) >> 8);
-		}
-	}
-	//
-	// Otherwise, the data should be output as 8-bit signed mono.
-	//
-	else if ((iChannels == 1) && (fmt & AFMT_S8)) {
-		//
-		// Convert each 16-bit signed mono sample to 8-bit signed mono 
-		// using rounding.
-		//
-		psSrc = (short *) src;
-		while (count--) {
-			lAudioSample =
-			    (((long) psSrc[0] + (long) psSrc[1]) / 2);
-			if (lAudioSample > 0x7fff) {
-				lAudioSample = 0x7fff;
-			}
-			psSrc += 2;
-			*dst++ = (char) ((short) lAudioSample >> 8);
-		}
-	}
-}
-
-//
-// cs_copy_to_user()
-// replacement for the standard copy_to_user, to allow for a conversion from
-// 16 bit to 8 bit if the record conversion is active.  the cs4281 has some
-// issues with 8 bit capture, so the driver always captures data in 16 bit
-// and then if the user requested 8 bit, converts from 16 to 8 bit.
-//
-static unsigned cs_copy_to_user(struct cs4281_state *s, void *dest,
-				unsigned *hwsrc, unsigned cnt,
-				unsigned *copied)
-{
-	void *src = hwsrc;	//default to the standard destination buffer addr
-
-	CS_DBGOUT(CS_FUNCTION, 6, printk(KERN_INFO
-					 "cs_copy_to_user()+ fmt=0x%x fmt_o=0x%x cnt=%d dest=0x%.8x\n",
-					 s->prop_adc.fmt,
-					 s->prop_adc.fmt_original,
-					 (unsigned) cnt, (unsigned) dest));
-
-	if (cnt > s->dma_adc.dmasize) {
-		cnt = s->dma_adc.dmasize;
-	}
-	if (!cnt) {
-		*copied = 0;
-		return 0;
-	}
-	if (s->conversion) {
-		if (!s->tmpbuff) {
-			*copied = cnt / 2;
-			return 0;
-		}
-		CopySamples(s->tmpbuff, (void *) hwsrc, cnt,
-			    (unsigned) s->prop_adc.channels,
-			    s->prop_adc.fmt_original);
-		src = s->tmpbuff;
-		cnt = cnt / 2;
-	}
-
-	if (copy_to_user(dest, src, cnt)) {
-		*copied = 0;
-		return -EFAULT;
-	}
-	*copied = cnt;
-	CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_INFO
-					 "cs4281: cs_copy_to_user()- copied bytes is %d \n",
-					 cnt));
-	return 0;
-}
-
-// --------------------------------------------------------------------- 
-
-static ssize_t cs4281_read(struct file *file, char *buffer, size_t count,
-			   loff_t * ppos)
-{
-	struct cs4281_state *s =
-	    (struct cs4281_state *) file->private_data;
-	ssize_t ret;
-	unsigned long flags;
-	unsigned swptr;
-	int cnt;
-	unsigned copied = 0;
-
-	CS_DBGOUT(CS_FUNCTION | CS_WAVE_READ, 2,
-		  printk(KERN_INFO "cs4281: cs4281_read()+ %d \n", count));
-
-	VALIDATE_STATE(s);
-	if (ppos != &file->f_pos)
-		return -ESPIPE;
-	if (s->dma_adc.mapped)
-		return -ENXIO;
-	if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
-		return ret;
-	if (!access_ok(VERIFY_WRITE, buffer, count))
-		return -EFAULT;
-	ret = 0;
-//
-// "count" is the amount of bytes to read (from app), is decremented each loop
-//      by the amount of bytes that have been returned to the user buffer.
-// "cnt" is the running total of each read from the buffer (changes each loop)
-// "buffer" points to the app's buffer
-// "ret" keeps a running total of the amount of bytes that have been copied
-//      to the user buffer.
-// "copied" is the total bytes copied into the user buffer for each loop.
-//
-	while (count > 0) {
-		CS_DBGOUT(CS_WAVE_READ, 8, printk(KERN_INFO
-						  "_read() count>0 count=%d .count=%d .swptr=%d .hwptr=%d \n",
-						  count, s->dma_adc.count,
-						  s->dma_adc.swptr,
-						  s->dma_adc.hwptr));
-		spin_lock_irqsave(&s->lock, flags);
-
-		// get the current copy point of the sw buffer
-		swptr = s->dma_adc.swptr;
-
-		// cnt is the amount of unread bytes from the end of the 
-		// hw buffer to the current sw pointer
-		cnt = s->dma_adc.dmasize - swptr;
-
-		// dma_adc.count is the current total bytes that have not been read.
-		// if the amount of unread bytes from the current sw pointer to the
-		// end of the buffer is greater than the current total bytes that
-		// have not been read, then set the "cnt" (unread bytes) to the
-		// amount of unread bytes.  
-
-		if (s->dma_adc.count < cnt)
-			cnt = s->dma_adc.count;
-		spin_unlock_irqrestore(&s->lock, flags);
-		//
-		// if we are converting from 8/16 then we need to copy
-		// twice the number of 16 bit bytes then 8 bit bytes.
-		// 
-		if (s->conversion) {
-			if (cnt > (count * 2))
-				cnt = (count * 2);
-		} else {
-			if (cnt > count)
-				cnt = count;
-		}
-		//
-		// "cnt" NOW is the smaller of the amount that will be read,
-		// and the amount that is requested in this read (or partial).
-		// if there are no bytes in the buffer to read, then start the
-		// ADC and wait for the interrupt handler to wake us up.
-		//
-		if (cnt <= 0) {
-
-			// start up the dma engine and then continue back to the top of
-			// the loop when wake up occurs.
-			start_adc(s);
-			if (file->f_flags & O_NONBLOCK)
-				return ret ? ret : -EAGAIN;
-			interruptible_sleep_on(&s->dma_adc.wait);
-			if (signal_pending(current))
-				return ret ? ret : -ERESTARTSYS;
-			continue;
-		}
-		// there are bytes in the buffer to read.
-		// copy from the hw buffer over to the user buffer.
-		// user buffer is designated by "buffer"
-		// virtual address to copy from is rawbuf+swptr
-		// the "cnt" is the number of bytes to read.
-
-		CS_DBGOUT(CS_WAVE_READ, 2, printk(KERN_INFO
-						  "_read() copy_to cnt=%d count=%d ",
-						  cnt, count));
-		CS_DBGOUT(CS_WAVE_READ, 8,
-			  printk(KERN_INFO
-				 " .dmasize=%d .count=%d buffer=0x%.8x ret=%d\n",
-				 s->dma_adc.dmasize, s->dma_adc.count,
-				 (unsigned) buffer, ret));
-
-		if (cs_copy_to_user
-		    (s, buffer, s->dma_adc.rawbuf + swptr, cnt, &copied))
-			return ret ? ret : -EFAULT;
-		swptr = (swptr + cnt) % s->dma_adc.dmasize;
-		spin_lock_irqsave(&s->lock, flags);
-		s->dma_adc.swptr = swptr;
-		s->dma_adc.count -= cnt;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= copied;
-		buffer += copied;
-		ret += copied;
-		start_adc(s);
-	}
-	CS_DBGOUT(CS_FUNCTION | CS_WAVE_READ, 2,
-		  printk(KERN_INFO "cs4281: cs4281_read()- %d\n", ret));
-	return ret;
-}
-
-
-static ssize_t cs4281_write(struct file *file, const char *buffer,
-			    size_t count, loff_t * ppos)
-{
-	struct cs4281_state *s =
-	    (struct cs4281_state *) file->private_data;
-	ssize_t ret;
-	unsigned long flags;
-	unsigned swptr;
-	int cnt;
-
-	CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE, 2,
-		  printk(KERN_INFO "cs4281: cs4281_write()+ count=%d\n",
-			 count));
-	VALIDATE_STATE(s);
-
-	if (ppos != &file->f_pos)
-		return -ESPIPE;
-	if (s->dma_dac.mapped)
-		return -ENXIO;
-	if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s)))
-		return ret;
-	if (!access_ok(VERIFY_READ, buffer, count))
-		return -EFAULT;
-	ret = 0;
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		if (s->dma_dac.count < 0) {
-			s->dma_dac.count = 0;
-			s->dma_dac.swptr = s->dma_dac.hwptr;
-		}
-		swptr = s->dma_dac.swptr;
-		cnt = s->dma_dac.dmasize - swptr;
-		if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
-			cnt = s->dma_dac.dmasize - s->dma_dac.count;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-
-			start_dac(s);
-			if (file->f_flags & O_NONBLOCK)
-				return ret ? ret : -EAGAIN;
-			interruptible_sleep_on(&s->dma_dac.wait);
-			if (signal_pending(current))
-				return ret ? ret : -ERESTARTSYS;
-			continue;
-		}
-		if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt))
-			return ret ? ret : -EFAULT;
-		swptr = (swptr + cnt) % s->dma_dac.dmasize;
-		spin_lock_irqsave(&s->lock, flags);
-		s->dma_dac.swptr = swptr;
-		s->dma_dac.count += cnt;
-		s->dma_dac.endcleared = 0;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		start_dac(s);
-	}
-	CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE, 2,
-		  printk(KERN_INFO "cs4281: cs4281_write()- %d\n", ret));
-	return ret;
-}
-
-
-static unsigned int cs4281_poll(struct file *file,
-				struct poll_table_struct *wait)
-{
-	struct cs4281_state *s =
-	    (struct cs4281_state *) file->private_data;
-	unsigned long flags;
-	unsigned int mask = 0;
-
-	CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
-		  printk(KERN_INFO "cs4281: cs4281_poll()+\n"));
-	VALIDATE_STATE(s);
-	if (file->f_mode & FMODE_WRITE) {
-		CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
-			  printk(KERN_INFO
-				 "cs4281: cs4281_poll() wait on FMODE_WRITE\n"));
-		if (!s->dma_dac.ready && prog_dmabuf_dac(s))
-			return 0;
-		poll_wait(file, &s->dma_dac.wait, wait);
-	}
-	if (file->f_mode & FMODE_READ) {
-		CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
-			  printk(KERN_INFO
-				 "cs4281: cs4281_poll() wait on FMODE_READ\n"));
-		if (!s->dma_adc.ready && prog_dmabuf_adc(s))
-			return 0;
-		poll_wait(file, &s->dma_adc.wait, wait);
-	}
-
-	spin_lock_irqsave(&s->lock, flags);
-	cs4281_update_ptr(s);
-	if (file->f_mode & FMODE_WRITE) {
-		if (s->dma_dac.mapped) {
-			if (s->dma_dac.count >=
-			    (signed) s->dma_dac.fragsize) {
-				if (s->dma_dac.wakeup)
-					mask |= POLLOUT | POLLWRNORM;
-				else
-					mask = 0;
-				s->dma_dac.wakeup = 0;
-			}
-		} else {
-			if ((signed) s->dma_dac.dmasize > s->dma_dac.count)
-				mask |= POLLOUT | POLLWRNORM;
-		}
-	} else if (file->f_mode & FMODE_READ) {
-		if (s->dma_adc.mapped) {
-			if (s->dma_adc.count >=
-			    (signed) s->dma_adc.fragsize)
-				mask |= POLLIN | POLLRDNORM;
-		} else {
-			if (s->dma_adc.count > 0)
-				mask |= POLLIN | POLLRDNORM;
-		}
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
-		  printk(KERN_INFO "cs4281: cs4281_poll()- 0x%.8x\n",
-			 mask));
-	return mask;
-}
-
-
-static int cs4281_mmap(struct file *file, struct vm_area_struct *vma)
-{
-	struct cs4281_state *s =
-	    (struct cs4281_state *) file->private_data;
-	struct dmabuf *db;
-	int ret;
-	unsigned long size;
-
-	CS_DBGOUT(CS_FUNCTION | CS_PARMS | CS_OPEN, 4,
-		  printk(KERN_INFO "cs4281: cs4281_mmap()+\n"));
-
-	VALIDATE_STATE(s);
-	if (vma->vm_flags & VM_WRITE) {
-		if ((ret = prog_dmabuf_dac(s)) != 0)
-			return ret;
-		db = &s->dma_dac;
-	} else if (vma->vm_flags & VM_READ) {
-		if ((ret = prog_dmabuf_adc(s)) != 0)
-			return ret;
-		db = &s->dma_adc;
-	} else
-		return -EINVAL;
-//
-// only support PLAYBACK for now
-//
-	db = &s->dma_dac;
-
-	if (vma->vm_pgoff != 0)
-		return -EINVAL;
-	size = vma->vm_end - vma->vm_start;
-	if (size > (PAGE_SIZE << db->buforder))
-		return -EINVAL;
-	if (remap_page_range
-	    (vma->vm_start, virt_to_phys(db->rawbuf), size,
-	     vma->vm_page_prot)) return -EAGAIN;
-	db->mapped = 1;
-
-	CS_DBGOUT(CS_FUNCTION | CS_PARMS | CS_OPEN, 4,
-		  printk(KERN_INFO "cs4281: cs4281_mmap()- 0 size=%d\n",
-			 (unsigned) size));
-
-	return 0;
-}
-
-
-static int cs4281_ioctl(struct inode *inode, struct file *file,
-			unsigned int cmd, unsigned long arg)
-{
-	struct cs4281_state *s =
-	    (struct cs4281_state *) file->private_data;
-	unsigned long flags;
-	audio_buf_info abinfo;
-	count_info cinfo;
-	int val, mapped, ret;
-
-	CS_DBGOUT(CS_FUNCTION, 4,
-		  printk(KERN_INFO
-			 "cs4281: cs4281_ioctl(): file=0x%.8x cmd=0x%.8x\n",
-			 (unsigned) file, cmd));
-#if CSDEBUG
-	printioctl(cmd);
-#endif
-	VALIDATE_STATE(s);
-	mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
-	    ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-	switch (cmd) {
-	case OSS_GETVERSION:
-		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
-							 "cs4281: cs4281_ioctl(): SOUND_VERSION=0x%.8x\n",
-							 SOUND_VERSION));
-		return put_user(SOUND_VERSION, (int *) arg);
-
-	case SNDCTL_DSP_SYNC:
-		CS_DBGOUT(CS_IOCTL, 4,
-			  printk(KERN_INFO
-				 "cs4281: cs4281_ioctl(): DSP_SYNC\n"));
-		if (file->f_mode & FMODE_WRITE)
-			return drain_dac(s,
-					 0 /*file->f_flags & O_NONBLOCK */
-					 );
-		return 0;
-
-	case SNDCTL_DSP_SETDUPLEX:
-		return 0;
-
-	case SNDCTL_DSP_GETCAPS:
-		return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
-				DSP_CAP_TRIGGER | DSP_CAP_MMAP,
-				(int *) arg);
-
-	case SNDCTL_DSP_RESET:
-		CS_DBGOUT(CS_IOCTL, 4,
-			  printk(KERN_INFO
-				 "cs4281: cs4281_ioctl(): DSP_RESET\n"));
-		if (file->f_mode & FMODE_WRITE) {
-			stop_dac(s);
-			synchronize_irq();
-			s->dma_dac.swptr = s->dma_dac.hwptr =
-			    s->dma_dac.count = s->dma_dac.total_bytes =
-			    s->dma_dac.blocks = s->dma_dac.wakeup = 0;
-			prog_codec(s, CS_TYPE_DAC);
-		}
-		if (file->f_mode & FMODE_READ) {
-			stop_adc(s);
-			synchronize_irq();
-			s->dma_adc.swptr = s->dma_adc.hwptr =
-			    s->dma_adc.count = s->dma_adc.total_bytes =
-			    s->dma_adc.blocks = s->dma_dac.wakeup = 0;
-			prog_codec(s, CS_TYPE_ADC);
-		}
-		return 0;
-
-	case SNDCTL_DSP_SPEED:
-		if (get_user(val, (int *) arg))
-			return -EFAULT;
-		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4,
-			  printk(KERN_INFO
-				 "cs4281: cs4281_ioctl(): DSP_SPEED val=%d\n",
-				 val));
-		//
-		// support independent capture and playback channels
-		// assume that the file mode bit determines the 
-		// direction of the data flow.
-		//
-		if (file->f_mode & FMODE_READ) {
-			if (val >= 0) {
-				stop_adc(s);
-				s->dma_adc.ready = 0;
-				// program sampling rates 
-				if (val > 48000)
-					val = 48000;
-				if (val < 6300)
-					val = 6300;
-				s->prop_adc.rate = val;
-				prog_codec(s, CS_TYPE_ADC);
-			}
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			if (val >= 0) {
-				stop_dac(s);
-				s->dma_dac.ready = 0;
-				// program sampling rates 
-				if (val > 48000)
-					val = 48000;
-				if (val < 6300)
-					val = 6300;
-				s->prop_dac.rate = val;
-				prog_codec(s, CS_TYPE_DAC);
-			}
-		}
-
-		if (file->f_mode & FMODE_WRITE)
-			val = s->prop_dac.rate;
-		else if (file->f_mode & FMODE_READ)
-			val = s->prop_adc.rate;
-
-		return put_user(val, (int *) arg);
-
-	case SNDCTL_DSP_STEREO:
-		if (get_user(val, (int *) arg))
-			return -EFAULT;
-		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4,
-			  printk(KERN_INFO
-				 "cs4281: cs4281_ioctl(): DSP_STEREO val=%d\n",
-				 val));
-		if (file->f_mode & FMODE_READ) {
-			stop_adc(s);
-			s->dma_adc.ready = 0;
-			s->prop_adc.channels = val ? 2 : 1;
-			prog_codec(s, CS_TYPE_ADC);
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			stop_dac(s);
-			s->dma_dac.ready = 0;
-			s->prop_dac.channels = val ? 2 : 1;
-			prog_codec(s, CS_TYPE_DAC);
-		}
-		return 0;
-
-	case SNDCTL_DSP_CHANNELS:
-		if (get_user(val, (int *) arg))
-			return -EFAULT;
-		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4,
-			  printk(KERN_INFO
-				 "cs4281: cs4281_ioctl(): DSP_CHANNELS val=%d\n",
-				 val));
-		if (val != 0) {
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(s);
-				s->dma_adc.ready = 0;
-				if (val >= 2)
-					s->prop_adc.channels = 2;
-				else
-					s->prop_adc.channels = 1;
-				prog_codec(s, CS_TYPE_ADC);
-			}
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac(s);
-				s->dma_dac.ready = 0;
-				if (val >= 2)
-					s->prop_dac.channels = 2;
-				else
-					s->prop_dac.channels = 1;
-				prog_codec(s, CS_TYPE_DAC);
-			}
-		}
-
-		if (file->f_mode & FMODE_WRITE)
-			val = s->prop_dac.channels;
-		else if (file->f_mode & FMODE_READ)
-			val = s->prop_adc.channels;
-
-		return put_user(val, (int *) arg);
-
-	case SNDCTL_DSP_GETFMTS:	// Returns a mask 
-		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4,
-			  printk(KERN_INFO
-				 "cs4281: cs4281_ioctl(): DSP_GETFMT val=0x%.8x\n",
-				 AFMT_S16_LE | AFMT_U16_LE | AFMT_S8 |
-				 AFMT_U8));
-		return put_user(AFMT_S16_LE | AFMT_U16_LE | AFMT_S8 |
-				AFMT_U8, (int *) arg);
-
-	case SNDCTL_DSP_SETFMT:
-		if (get_user(val, (int *) arg))
-			return -EFAULT;
-		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4,
-			  printk(KERN_INFO
-				 "cs4281: cs4281_ioctl(): DSP_SETFMT val=0x%.8x\n",
-				 val));
-		if (val != AFMT_QUERY) {
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(s);
-				s->dma_adc.ready = 0;
-				if (val != AFMT_S16_LE
-				    && val != AFMT_U16_LE && val != AFMT_S8
-				    && val != AFMT_U8)
-					val = AFMT_U8;
-				s->prop_adc.fmt = val;
-				s->prop_adc.fmt_original = s->prop_adc.fmt;
-				prog_codec(s, CS_TYPE_ADC);
-			}
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac(s);
-				s->dma_dac.ready = 0;
-				if (val != AFMT_S16_LE
-				    && val != AFMT_U16_LE && val != AFMT_S8
-				    && val != AFMT_U8)
-					val = AFMT_U8;
-				s->prop_dac.fmt = val;
-				s->prop_dac.fmt_original = s->prop_dac.fmt;
-				prog_codec(s, CS_TYPE_DAC);
-			}
-		} else {
-			if (file->f_mode & FMODE_WRITE)
-				val = s->prop_dac.fmt_original;
-			else if (file->f_mode & FMODE_READ)
-				val = s->prop_adc.fmt_original;
-		}
-		CS_DBGOUT(CS_IOCTL | CS_PARMS, 4,
-			  printk(KERN_INFO
-				 "cs4281: cs4281_ioctl(): DSP_SETFMT return val=0x%.8x\n",
-				 val));
-		return put_user(val, (int *) arg);
-
-	case SNDCTL_DSP_POST:
-		CS_DBGOUT(CS_IOCTL, 4,
-			  printk(KERN_INFO
-				 "cs4281: cs4281_ioctl(): DSP_POST\n"));
-		return 0;
-
-	case SNDCTL_DSP_GETTRIGGER:
-		val = 0;
-		if (file->f_mode & s->ena & FMODE_READ)
-			val |= PCM_ENABLE_INPUT;
-		if (file->f_mode & s->ena & FMODE_WRITE)
-			val |= PCM_ENABLE_OUTPUT;
-		return put_user(val, (int *) arg);
-
-	case SNDCTL_DSP_SETTRIGGER:
-		if (get_user(val, (int *) arg))
-			return -EFAULT;
-		if (file->f_mode & FMODE_READ) {
-			if (val & PCM_ENABLE_INPUT) {
-				if (!s->dma_adc.ready
-				    && (ret = prog_dmabuf_adc(s)))
-					return ret;
-				start_adc(s);
-			} else
-				stop_adc(s);
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			if (val & PCM_ENABLE_OUTPUT) {
-				if (!s->dma_dac.ready
-				    && (ret = prog_dmabuf_dac(s)))
-					return ret;
-				start_dac(s);
-			} else
-				stop_dac(s);
-		}
-		return 0;
-
-	case SNDCTL_DSP_GETOSPACE:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)))
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		cs4281_update_ptr(s);
-		abinfo.fragsize = s->dma_dac.fragsize;
-		if (s->dma_dac.mapped)
-			abinfo.bytes = s->dma_dac.dmasize;
-		else
-			abinfo.bytes =
-			    s->dma_dac.dmasize - s->dma_dac.count;
-		abinfo.fragstotal = s->dma_dac.numfrag;
-		abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
-		CS_DBGOUT(CS_FUNCTION | CS_PARMS, 4, printk(KERN_INFO
-							    "cs4281: cs4281_ioctl(): GETOSPACE .fragsize=%d .bytes=%d .fragstotal=%d .fragments=%d\n",
-							    abinfo.
-							    fragsize,
-							    abinfo.bytes,
-							    abinfo.
-							    fragstotal,
-							    abinfo.
-							    fragments));
-		spin_unlock_irqrestore(&s->lock, flags);
-		return copy_to_user((void *) arg, &abinfo,
-				    sizeof(abinfo)) ? -EFAULT : 0;
-
-	case SNDCTL_DSP_GETISPACE:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		if (!s->dma_dac.ready && (val = prog_dmabuf_dac(s)))
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		cs4281_update_ptr(s);
-		if (s->conversion) {
-			abinfo.fragsize = s->dma_adc.fragsize / 2;
-			abinfo.bytes = s->dma_adc.count / 2;
-			abinfo.fragstotal = s->dma_adc.numfrag;
-			abinfo.fragments =
-			    abinfo.bytes >> (s->dma_adc.fragshift - 1);
-		} else {
-			abinfo.fragsize = s->dma_adc.fragsize;
-			abinfo.bytes = s->dma_adc.count;
-			abinfo.fragstotal = s->dma_adc.numfrag;
-			abinfo.fragments =
-			    abinfo.bytes >> s->dma_adc.fragshift;
-		}
-		spin_unlock_irqrestore(&s->lock, flags);
-		return copy_to_user((void *) arg, &abinfo,
-				    sizeof(abinfo)) ? -EFAULT : 0;
-
-	case SNDCTL_DSP_NONBLOCK:
-		file->f_flags |= O_NONBLOCK;
-		return 0;
-
-	case SNDCTL_DSP_GETODELAY:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)))
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		cs4281_update_ptr(s);
-		val = s->dma_dac.count;
-		spin_unlock_irqrestore(&s->lock, flags);
-		return put_user(val, (int *) arg);
-
-	case SNDCTL_DSP_GETIPTR:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		if (!s->dma_dac.ready && (val = prog_dmabuf_dac(s)))
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		cs4281_update_ptr(s);
-		cinfo.bytes = s->dma_adc.total_bytes;
-		if (s->dma_adc.mapped) {
-			cinfo.blocks =
-			    (cinfo.bytes >> s->dma_adc.fragshift) -
-			    s->dma_adc.blocks;
-			s->dma_adc.blocks =
-			    cinfo.bytes >> s->dma_adc.fragshift;
-		} else {
-			if (s->conversion) {
-				cinfo.blocks =
-				    s->dma_adc.count /
-				    2 >> (s->dma_adc.fragshift - 1);
-			} else
-				cinfo.blocks =
-				    s->dma_adc.count >> s->dma_adc.
-				    fragshift;
-		}
-		if (s->conversion)
-			cinfo.ptr = s->dma_adc.hwptr / 2;
-		else
-			cinfo.ptr = s->dma_adc.hwptr;
-		if (s->dma_adc.mapped)
-			s->dma_adc.count &= s->dma_adc.fragsize - 1;
-		spin_unlock_irqrestore(&s->lock, flags);
-		return copy_to_user((void *) arg, &cinfo, sizeof(cinfo));
-
-	case SNDCTL_DSP_GETOPTR:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)))
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		cs4281_update_ptr(s);
-		cinfo.bytes = s->dma_dac.total_bytes;
-		if (s->dma_dac.mapped) {
-			cinfo.blocks =
-			    (cinfo.bytes >> s->dma_dac.fragshift) -
-			    s->dma_dac.blocks;
-			s->dma_dac.blocks =
-			    cinfo.bytes >> s->dma_dac.fragshift;
-		} else {
-			cinfo.blocks =
-			    s->dma_dac.count >> s->dma_dac.fragshift;
-		}
-		cinfo.ptr = s->dma_dac.hwptr;
-		if (s->dma_dac.mapped)
-			s->dma_dac.count &= s->dma_dac.fragsize - 1;
-		spin_unlock_irqrestore(&s->lock, flags);
-		return copy_to_user((void *) arg, &cinfo, sizeof(cinfo));
-
-	case SNDCTL_DSP_GETBLKSIZE:
-		if (file->f_mode & FMODE_WRITE) {
-			if ((val = prog_dmabuf_dac(s)))
-				return val;
-			return put_user(s->dma_dac.fragsize, (int *) arg);
-		}
-		if ((val = prog_dmabuf_adc(s)))
-			return val;
-		if (s->conversion)
-			return put_user(s->dma_adc.fragsize / 2,
-					(int *) arg);
-		else
-			return put_user(s->dma_adc.fragsize, (int *) arg);
-
-	case SNDCTL_DSP_SETFRAGMENT:
-		if (get_user(val, (int *) arg))
-			return -EFAULT;
-		return 0;	// Say OK, but do nothing.
-
-	case SNDCTL_DSP_SUBDIVIDE:
-		if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision)
-		    || (file->f_mode & FMODE_WRITE
-			&& s->dma_dac.subdivision)) return -EINVAL;
-		if (get_user(val, (int *) arg))
-			return -EFAULT;
-		if (val != 1 && val != 2 && val != 4)
-			return -EINVAL;
-		if (file->f_mode & FMODE_READ)
-			s->dma_adc.subdivision = val;
-		else if (file->f_mode & FMODE_WRITE)
-			s->dma_dac.subdivision = val;
-		return 0;
-
-	case SOUND_PCM_READ_RATE:
-		if (file->f_mode & FMODE_READ)
-			return put_user(s->prop_adc.rate, (int *) arg);
-		else if (file->f_mode & FMODE_WRITE)
-			return put_user(s->prop_dac.rate, (int *) arg);
-
-	case SOUND_PCM_READ_CHANNELS:
-		if (file->f_mode & FMODE_READ)
-			return put_user(s->prop_adc.channels, (int *) arg);
-		else if (file->f_mode & FMODE_WRITE)
-			return put_user(s->prop_dac.channels, (int *) arg);
-
-	case SOUND_PCM_READ_BITS:
-		if (file->f_mode & FMODE_READ)
-			return
-			    put_user(
-				     (s->prop_adc.
-				      fmt & (AFMT_S8 | AFMT_U8)) ? 8 : 16,
-				     (int *) arg);
-		else if (file->f_mode & FMODE_WRITE)
-			return
-			    put_user(
-				     (s->prop_dac.
-				      fmt & (AFMT_S8 | AFMT_U8)) ? 8 : 16,
-				     (int *) arg);
-
-	case SOUND_PCM_WRITE_FILTER:
-	case SNDCTL_DSP_SETSYNCRO:
-	case SOUND_PCM_READ_FILTER:
-		return -EINVAL;
-
-#if CSDEBUG_INTERFACE
-
-	case SNDCTL_DSP_CS_GETDBGMASK:
-		return put_user(cs_debugmask, (unsigned long *) arg);
-
-	case SNDCTL_DSP_CS_GETDBGLEVEL:
-		return put_user(cs_debuglevel, (unsigned long *) arg);
-
-	case SNDCTL_DSP_CS_SETDBGMASK:
-		if (get_user(val, (unsigned long *) arg))
-			return -EFAULT;
-		cs_debugmask = val;
-		return 0;
-
-	case SNDCTL_DSP_CS_SETDBGLEVEL:
-		if (get_user(val, (unsigned long *) arg))
-			return -EFAULT;
-		cs_debuglevel = val;
-		return 0;
-#endif
-
-	}
-	return mixer_ioctl(s, cmd, arg);
-}
-
-
-static int cs4281_release(struct inode *inode, struct file *file)
-{
-	struct cs4281_state *s =
-	    (struct cs4281_state *) file->private_data;
-
-	CS_DBGOUT(CS_FUNCTION | CS_RELEASE, 2,
-		  printk(KERN_INFO
-			 "cs4281: cs4281_release(): inode=0x%.8x file=0x%.8x f_mode=%d\n",
-			 (unsigned) inode, (unsigned) file, file->f_mode));
-
-	VALIDATE_STATE(s);
-
-	if (file->f_mode & FMODE_WRITE) {
-		drain_dac(s, file->f_flags & O_NONBLOCK);
-		down(&s->open_sem_dac);
-		stop_dac(s);
-		dealloc_dmabuf(s, &s->dma_dac);
-		s->open_mode &= ~FMODE_WRITE;
-		up(&s->open_sem_dac);
-		wake_up(&s->open_wait_dac);
-		MOD_DEC_USE_COUNT;
-	}
-	if (file->f_mode & FMODE_READ) {
-		drain_adc(s, file->f_flags & O_NONBLOCK);
-		down(&s->open_sem_adc);
-		stop_adc(s);
-		dealloc_dmabuf(s, &s->dma_adc);
-		s->open_mode &= ~FMODE_READ;
-		up(&s->open_sem_adc);
-		wake_up(&s->open_wait_adc);
-		MOD_DEC_USE_COUNT;
-	}
-	return 0;
-}
-
-static int cs4281_open(struct inode *inode, struct file *file)
-{
-	int minor = MINOR(inode->i_rdev);
-	struct cs4281_state *s = devs;
-
-	CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2,
-		  printk(KERN_INFO
-			 "cs4281: cs4281_open(): inode=0x%.8x file=0x%.8x f_mode=0x%x\n",
-			 (unsigned) inode, (unsigned) file, file->f_mode));
-	while (s && ((s->dev_audio ^ minor) & ~0xf))
-		s = s->next;
-	if (!s) {
-		CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO
-							   "cs4281: cs4281_open(): Error - unable to find audio state struct\n"));
-		return -ENODEV;
-	}
-	VALIDATE_STATE(s);
-	file->private_data = s;
-
-	// wait for device to become free 
-	if (!(file->f_mode & (FMODE_WRITE | FMODE_READ))) {
-		CS_DBGOUT(CS_FUNCTION | CS_OPEN | CS_ERROR, 2,
-			  printk(KERN_INFO
-				 "cs4281: cs4281_open(): Error - must open READ and/or WRITE\n"));
-		return -ENODEV;
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		down(&s->open_sem_dac);
-		while (s->open_mode & FMODE_WRITE) {
-			if (file->f_flags & O_NONBLOCK) {
-				up(&s->open_sem_dac);
-				return -EBUSY;
-			}
-			up(&s->open_sem_dac);
-			interruptible_sleep_on(&s->open_wait_dac);
-
-			if (signal_pending(current))
-				return -ERESTARTSYS;
-			down(&s->open_sem_dac);
-		}
-	}
-	if (file->f_mode & FMODE_READ) {
-		down(&s->open_sem_adc);
-		while (s->open_mode & FMODE_READ) {
-			if (file->f_flags & O_NONBLOCK) {
-				up(&s->open_sem_adc);
-				return -EBUSY;
-			}
-			up(&s->open_sem_adc);
-			interruptible_sleep_on(&s->open_wait_adc);
-
-			if (signal_pending(current))
-				return -ERESTARTSYS;
-			down(&s->open_sem_adc);
-		}
-	}
-	s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-	if (file->f_mode & FMODE_READ) {
-		s->prop_adc.fmt = AFMT_U8;
-		s->prop_adc.fmt_original = s->prop_adc.fmt;
-		s->prop_adc.channels = 1;
-		s->prop_adc.rate = 8000;
-		s->prop_adc.clkdiv = 96 | 0x80;
-		s->conversion = 0;
-		s->ena &= ~FMODE_READ;
-		s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
-		    s->dma_adc.subdivision = 0;
-		up(&s->open_sem_adc);
-		MOD_INC_USE_COUNT;
-
-		if (prog_dmabuf_adc(s)) {
-			CS_DBGOUT(CS_OPEN | CS_ERROR, 2, printk(KERN_ERR
-								"cs4281: adc Program dmabufs failed.\n"));
-			cs4281_release(inode, file);
-			return -ENOMEM;
-		}
-		prog_codec(s, CS_TYPE_ADC);
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		s->prop_dac.fmt = AFMT_U8;
-		s->prop_dac.fmt_original = s->prop_dac.fmt;
-		s->prop_dac.channels = 1;
-		s->prop_dac.rate = 8000;
-		s->prop_dac.clkdiv = 96 | 0x80;
-		s->conversion = 0;
-		s->ena &= ~FMODE_WRITE;
-		s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags =
-		    s->dma_dac.subdivision = 0;
-		up(&s->open_sem_dac);
-		MOD_INC_USE_COUNT;
-
-		if (prog_dmabuf_dac(s)) {
-			CS_DBGOUT(CS_OPEN | CS_ERROR, 2, printk(KERN_ERR
-								"cs4281: dac Program dmabufs failed.\n"));
-			cs4281_release(inode, file);
-			return -ENOMEM;
-		}
-		prog_codec(s, CS_TYPE_DAC);
-	}
-	CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2,
-		  printk(KERN_INFO "cs4281: cs4281_open()- 0\n"));
-	return 0;
-}
-
-
-// ******************************************************************************************
-//   Wave (audio) file operations struct.
-// ******************************************************************************************
-static /*const */ struct file_operations cs4281_audio_fops = {
-	llseek:cs4281_llseek,
-	read:cs4281_read,
-	write:cs4281_write,
-	poll:cs4281_poll,
-	ioctl:cs4281_ioctl,
-	mmap:cs4281_mmap,
-	open:cs4281_open,
-	release:cs4281_release,
-};
-
-// --------------------------------------------------------------------- 
-
-// hold spinlock for the following! 
-static void cs4281_handle_midi(struct cs4281_state *s)
-{
-	unsigned char ch;
-	int wake;
-	unsigned temp1;
-
-	wake = 0;
-	while (!(readl(s->pBA0 + BA0_MIDSR) & 0x80)) {
-		ch = readl(s->pBA0 + BA0_MIDRP);
-		if (s->midi.icnt < MIDIINBUF) {
-			s->midi.ibuf[s->midi.iwr] = ch;
-			s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF;
-			s->midi.icnt++;
-		}
-		wake = 1;
-	}
-	if (wake)
-		wake_up(&s->midi.iwait);
-	wake = 0;
-	while (!(readl(s->pBA0 + BA0_MIDSR) & 0x40) && s->midi.ocnt > 0) {
-		temp1 = (s->midi.obuf[s->midi.ord]) & 0x000000ff;
-		writel(temp1, s->pBA0 + BA0_MIDWP);
-		s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF;
-		s->midi.ocnt--;
-		if (s->midi.ocnt < MIDIOUTBUF - 16)
-			wake = 1;
-	}
-	if (wake)
-		wake_up(&s->midi.owait);
-}
-
-
-
-static void cs4281_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	struct cs4281_state *s = (struct cs4281_state *) dev_id;
-	unsigned int temp1;
-
-	// fastpath out, to ease interrupt sharing 
-	temp1 = readl(s->pBA0 + BA0_HISR);	// Get Int Status reg.
-
-	CS_DBGOUT(CS_INTERRUPT, 6, printk(KERN_INFO
-					  "cs4281: cs4281_interrupt() BA0_HISR=0x%.8x\n",
-					  temp1));
-
-	if (!(temp1 & (HISR_DMA0 | HISR_DMA1 | HISR_MIDI))) {	// If not DMA or MIDI int,
-		writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);	//  reenable interrupts
-		CS_DBGOUT(CS_INTERRUPT, 4, printk(KERN_INFO
-						  "cs4281: cs4281_interrupt(): returning not cs4281 interrupt.\n"));
-		return;		//   and return.
-	}
-
-	if (temp1 & HISR_DMA0)	// If play interrupt,
-		readl(s->pBA0 + BA0_HDSR0);	//   clear the source.
-
-	if (temp1 & HISR_DMA1)	// Same for play.
-		readl(s->pBA0 + BA0_HDSR1);
-	writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);	// Local EOI
-
-	spin_lock(&s->lock);
-	cs4281_update_ptr(s);
-	cs4281_handle_midi(s);
-	spin_unlock(&s->lock);
-}
-
-// **************************************************************************
-
-static void cs4281_midi_timer(unsigned long data)
-{
-	struct cs4281_state *s = (struct cs4281_state *) data;
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	cs4281_handle_midi(s);
-	spin_unlock_irqrestore(&s->lock, flags);
-	s->midi.timer.expires = jiffies + 1;
-	add_timer(&s->midi.timer);
-}
-
-
-// --------------------------------------------------------------------- 
-
-static ssize_t cs4281_midi_read(struct file *file, char *buffer,
-				size_t count, loff_t * ppos)
-{
-	struct cs4281_state *s =
-	    (struct cs4281_state *) file->private_data;
-	ssize_t ret;
-	unsigned long flags;
-	unsigned ptr;
-	int cnt;
-
-	VALIDATE_STATE(s);
-	if (ppos != &file->f_pos)
-		return -ESPIPE;
-	if (!access_ok(VERIFY_WRITE, buffer, count))
-		return -EFAULT;
-	ret = 0;
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		ptr = s->midi.ird;
-		cnt = MIDIINBUF - ptr;
-		if (s->midi.icnt < cnt)
-			cnt = s->midi.icnt;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-			if (file->f_flags & O_NONBLOCK)
-				return ret ? ret : -EAGAIN;
-			interruptible_sleep_on(&s->midi.iwait);
-			if (signal_pending(current))
-				return ret ? ret : -ERESTARTSYS;
-			continue;
-		}
-		if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt))
-			return ret ? ret : -EFAULT;
-		ptr = (ptr + cnt) % MIDIINBUF;
-		spin_lock_irqsave(&s->lock, flags);
-		s->midi.ird = ptr;
-		s->midi.icnt -= cnt;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-	}
-	return ret;
-}
-
-
-static ssize_t cs4281_midi_write(struct file *file, const char *buffer,
-				 size_t count, loff_t * ppos)
-{
-	struct cs4281_state *s =
-	    (struct cs4281_state *) file->private_data;
-	ssize_t ret;
-	unsigned long flags;
-	unsigned ptr;
-	int cnt;
-
-	VALIDATE_STATE(s);
-	if (ppos != &file->f_pos)
-		return -ESPIPE;
-	if (!access_ok(VERIFY_READ, buffer, count))
-		return -EFAULT;
-	ret = 0;
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		ptr = s->midi.owr;
-		cnt = MIDIOUTBUF - ptr;
-		if (s->midi.ocnt + cnt > MIDIOUTBUF)
-			cnt = MIDIOUTBUF - s->midi.ocnt;
-		if (cnt <= 0)
-			cs4281_handle_midi(s);
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-			if (file->f_flags & O_NONBLOCK)
-				return ret ? ret : -EAGAIN;
-			interruptible_sleep_on(&s->midi.owait);
-			if (signal_pending(current))
-				return ret ? ret : -ERESTARTSYS;
-			continue;
-		}
-		if (copy_from_user(s->midi.obuf + ptr, buffer, cnt))
-			return ret ? ret : -EFAULT;
-		ptr = (ptr + cnt) % MIDIOUTBUF;
-		spin_lock_irqsave(&s->lock, flags);
-		s->midi.owr = ptr;
-		s->midi.ocnt += cnt;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		spin_lock_irqsave(&s->lock, flags);
-		cs4281_handle_midi(s);
-		spin_unlock_irqrestore(&s->lock, flags);
-	}
-	return ret;
-}
-
-
-static unsigned int cs4281_midi_poll(struct file *file,
-				     struct poll_table_struct *wait)
-{
-	struct cs4281_state *s =
-	    (struct cs4281_state *) file->private_data;
-	unsigned long flags;
-	unsigned int mask = 0;
-
-	VALIDATE_STATE(s);
-	if (file->f_flags & FMODE_WRITE)
-		poll_wait(file, &s->midi.owait, wait);
-	if (file->f_flags & FMODE_READ)
-		poll_wait(file, &s->midi.iwait, wait);
-	spin_lock_irqsave(&s->lock, flags);
-	if (file->f_flags & FMODE_READ) {
-		if (s->midi.icnt > 0)
-			mask |= POLLIN | POLLRDNORM;
-	}
-	if (file->f_flags & FMODE_WRITE) {
-		if (s->midi.ocnt < MIDIOUTBUF)
-			mask |= POLLOUT | POLLWRNORM;
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	return mask;
-}
-
-
-static int cs4281_midi_open(struct inode *inode, struct file *file)
-{
-	int minor = MINOR(inode->i_rdev);
-	struct cs4281_state *s = devs;
-	unsigned long flags, temp1;
-	while (s && s->dev_midi != minor)
-		s = s->next;
-	if (!s)
-		return -ENODEV;
-	VALIDATE_STATE(s);
-	file->private_data = s;
-	// wait for device to become free 
-	down(&s->open_sem);
-	while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
-		if (file->f_flags & O_NONBLOCK) {
-			up(&s->open_sem);
-			return -EBUSY;
-		}
-		up(&s->open_sem);
-		interruptible_sleep_on(&s->open_wait);
-		if (signal_pending(current))
-			return -ERESTARTSYS;
-		down(&s->open_sem);
-	}
-	spin_lock_irqsave(&s->lock, flags);
-	if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-		s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-		s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-		writel(1, s->pBA0 + BA0_MIDCR);	// Reset the interface.
-		writel(0, s->pBA0 + BA0_MIDCR);	// Return to normal mode.
-		s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-		writel(0x0000000f, s->pBA0 + BA0_MIDCR);	// Enable transmit, record, ints.
-		temp1 = readl(s->pBA0 + BA0_HIMR);
-		writel(temp1 & 0xffbfffff, s->pBA0 + BA0_HIMR);	// Enable midi int. recognition.
-		writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);	// Enable interrupts
-		init_timer(&s->midi.timer);
-		s->midi.timer.expires = jiffies + 1;
-		s->midi.timer.data = (unsigned long) s;
-		s->midi.timer.function = cs4281_midi_timer;
-		add_timer(&s->midi.timer);
-	}
-	if (file->f_mode & FMODE_READ) {
-		s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	s->open_mode |=
-	    (file->
-	     f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ |
-					    FMODE_MIDI_WRITE);
-	up(&s->open_sem);
-	MOD_INC_USE_COUNT;
-	return 0;
-}
-
-
-static int cs4281_midi_release(struct inode *inode, struct file *file)
-{
-	struct cs4281_state *s =
-	    (struct cs4281_state *) file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	unsigned count, tmo;
-
-	VALIDATE_STATE(s);
-
-	if (file->f_mode & FMODE_WRITE) {
-		add_wait_queue(&s->midi.owait, &wait);
-		for (;;) {
-			set_current_state(TASK_INTERRUPTIBLE);
-			spin_lock_irqsave(&s->lock, flags);
-			count = s->midi.ocnt;
-			spin_unlock_irqrestore(&s->lock, flags);
-			if (count <= 0)
-				break;
-			if (signal_pending(current))
-				break;
-			if (file->f_flags & O_NONBLOCK) {
-				remove_wait_queue(&s->midi.owait, &wait);
-				current->state = TASK_RUNNING;
-				return -EBUSY;
-			}
-			tmo = (count * HZ) / 3100;
-			if (!schedule_timeout(tmo ? : 1) && tmo)
-				printk(KERN_DEBUG
-				       "cs4281: midi timed out??\n");
-		}
-		remove_wait_queue(&s->midi.owait, &wait);
-		current->state = TASK_RUNNING;
-	}
-	down(&s->open_sem);
-	s->open_mode &=
-	    (~(file->f_mode << FMODE_MIDI_SHIFT)) & (FMODE_MIDI_READ |
-						     FMODE_MIDI_WRITE);
-	spin_lock_irqsave(&s->lock, flags);
-	if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-		writel(0, s->pBA0 + BA0_MIDCR);	// Disable Midi interrupts.  
-		del_timer(&s->midi.timer);
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	up(&s->open_sem);
-	wake_up(&s->open_wait);
-	MOD_DEC_USE_COUNT;
-	return 0;
-}
-
-// ******************************************************************************************
-//   Midi file operations struct.
-// ******************************************************************************************
-static /*const */ struct file_operations cs4281_midi_fops = {
-	llseek:cs4281_llseek,
-	read:cs4281_midi_read,
-	write:cs4281_midi_write,
-	poll:cs4281_midi_poll,
-	open:cs4281_midi_open,
-	release:cs4281_midi_release,
-};
-
-
-// --------------------------------------------------------------------- 
-
-// maximum number of devices 
-#define NR_DEVICE 8		// Only eight devices supported currently.
-
-// --------------------------------------------------------------------- 
-
-static struct initvol {
-	int mixch;
-	int vol;
-} initvol[] __initdata = {
-
-	{
-	SOUND_MIXER_WRITE_VOLUME, 0x4040}, {
-	SOUND_MIXER_WRITE_PCM, 0x4040}, {
-	SOUND_MIXER_WRITE_SYNTH, 0x4040}, {
-	SOUND_MIXER_WRITE_CD, 0x4040}, {
-	SOUND_MIXER_WRITE_LINE, 0x4040}, {
-	SOUND_MIXER_WRITE_LINE1, 0x4040}, {
-	SOUND_MIXER_WRITE_RECLEV, 0x0000}, {
-	SOUND_MIXER_WRITE_SPEAKER, 0x4040}, {
-	SOUND_MIXER_WRITE_MIC, 0x0000}
-};
-
-
-static int __devinit cs4281_probe(struct pci_dev *pcidev,
-				  const struct pci_device_id *pciid)
-{
-	struct cs4281_state *s;
-	dma_addr_t dma_mask;
-	mm_segment_t fs;
-	int i, val, index = 0;
-	unsigned int temp1, temp2;
-
-	CS_DBGOUT(CS_FUNCTION | CS_INIT, 2,
-		  printk(KERN_INFO "cs4281: probe()+\n"));
-
-	if (!RSRCISMEMORYREGION(pcidev, 0) ||
-	    !RSRCISMEMORYREGION(pcidev, 1)) {
-		CS_DBGOUT(CS_ERROR, 1,
-			  printk(KERN_ERR
-				 "cs4281: probe()- Memory region not assigned\n"));
-		return -1;
-	}
-	if (pcidev->irq == 0) {
-		CS_DBGOUT(CS_ERROR, 1,
-			  printk(KERN_ERR
-				 "cs4281: probe() IRQ not assigned\n"));
-		return -1;
-	}
-	if (!pci_dma_supported(pcidev, 0xffffffff)) {
-		CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
-					      "cs4281: probe() architecture does not support 32bit PCI busmaster DMA\n"));
-		return -1;
-	}
-	dma_mask = 0xffffffff;	/* this enables playback and recording */
-	if (!(s = kmalloc(sizeof(struct cs4281_state), GFP_KERNEL))) {
-		CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
-					      "cs4281: probe() no memory for state struct.\n"));
-		return -1;
-	}
-	memset(s, 0, sizeof(struct cs4281_state));
-	init_waitqueue_head(&s->dma_adc.wait);
-	init_waitqueue_head(&s->dma_dac.wait);
-	init_waitqueue_head(&s->open_wait);
-	init_waitqueue_head(&s->open_wait_adc);
-	init_waitqueue_head(&s->open_wait_dac);
-	init_waitqueue_head(&s->midi.iwait);
-	init_waitqueue_head(&s->midi.owait);
-	init_MUTEX(&s->open_sem);
-	init_MUTEX(&s->open_sem_adc);
-	init_MUTEX(&s->open_sem_dac);
-	spin_lock_init(&s->lock);
-	s->pBA0phys = RSRCADDRESS(pcidev, 0);
-	s->pBA1phys = RSRCADDRESS(pcidev, 1);
-	s->pBA0 = ioremap_nocache(s->pBA0phys, 4096);	// Convert phys 
-	s->pBA1 = ioremap_nocache(s->pBA1phys, 65536);	//  to linear. 
-	temp1 = readl(s->pBA0 + BA0_PCICFG00);
-	temp2 = readl(s->pBA0 + BA0_PCICFG04);
-
-	CS_DBGOUT(CS_INIT, 2,
-		  printk(KERN_INFO
-			 "cs4281: probe() BA0=0x%.8x BA1=0x%.8x pBA0=0x%.8x pBA1=0x%.8x \n",
-			 (unsigned) temp1, (unsigned) temp2,
-			 (unsigned) s->pBA0, (unsigned) s->pBA1));
-
-	CS_DBGOUT(CS_INIT, 2,
-		  printk(KERN_INFO
-			 "cs4281: probe() pBA0phys=0x%.8x pBA1phys=0x%.8x\n",
-			 (unsigned) s->pBA0phys, (unsigned) s->pBA1phys));
-
-	temp1 = cs4281_hw_init(s);
-	if (temp1) {
-		CS_DBGOUT(CS_ERROR | CS_INIT, 1,
-			  printk(KERN_ERR
-				 "cs4281: cs4281_hw_init() failed. Skipping part.\n"));
-		return -1;
-	}
-	s->magic = CS4281_MAGIC;
-	s->pcidev = pcidev;
-	s->irq = pcidev->irq;
-	if (pci_enable_device(pcidev)) {
-		CS_DBGOUT(CS_INIT | CS_ERROR, 1,
-			  printk(KERN_ERR
-				 "cs4281: pci_enable_device() failed\n"));
-		goto err_irq;
-	}
-	if (request_irq
-	    (s->irq, cs4281_interrupt, SA_SHIRQ, "Crystal CS4281", s)) {
-		CS_DBGOUT(CS_INIT | CS_ERROR, 1,
-			  printk(KERN_ERR "cs4281: irq %u in use\n",
-				 s->irq));
-		goto err_irq;
-	}
-	if ((s->dev_audio = register_sound_dsp(&cs4281_audio_fops, -1)) <
-	    0) {
-		CS_DBGOUT(CS_INIT | CS_ERROR, 1,
-			  printk(KERN_ERR
-				 "cs4281: probe() register_sound_dsp() failed.\n"));
-		goto err_dev1;
-	}
-	if ((s->dev_mixer = register_sound_mixer(&cs4281_mixer_fops, -1)) <
-	    0) {
-		CS_DBGOUT(CS_INIT | CS_ERROR, 1,
-			  printk(KERN_ERR
-				 "cs4281: probe() register_sound_mixer() failed.\n"));
-		goto err_dev2;
-	}
-	if ((s->dev_midi = register_sound_midi(&cs4281_midi_fops, -1)) < 0) {
-		CS_DBGOUT(CS_INIT | CS_ERROR, 1,
-			  printk(KERN_ERR
-				 "cs4281: probe() register_sound_midi() failed.\n"));
-		goto err_dev3;
-	}
-
-	pci_set_master(pcidev);	// enable bus mastering 
-
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-	val = SOUND_MASK_LINE;
-	mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long) &val);
-	for (i = 0; i < sizeof(initvol) / sizeof(initvol[0]); i++) {
-		val = initvol[i].vol;
-		mixer_ioctl(s, initvol[i].mixch, (unsigned long) &val);
-	}
-	val = 1;		// enable mic preamp 
-	mixer_ioctl(s, SOUND_MIXER_PRIVATE1, (unsigned long) &val);
-	set_fs(fs);
-
-	// queue it for later freeing 
-	s->next = devs;
-	pcidev->driver_data = s;
-	pcidev->dma_mask = dma_mask;
-	devs = s;
-	index++;
-	return 0;
-
-      err_dev3:
-	unregister_sound_mixer(s->dev_mixer);
-      err_dev2:
-	unregister_sound_dsp(s->dev_audio);
-      err_dev1:
-	free_irq(s->irq, s);
-      err_irq:
-	kfree(s);
-
-	if (!devs) {
-		CS_DBGOUT(CS_INIT | CS_ERROR, 1,
-			  printk(KERN_INFO
-				 "cs4281: probe()- no device allocated\n"));
-		return -ENODEV;
-	}
-	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
-		  printk(KERN_INFO
-			 "cs4281: probe()- device allocated successfully\n"));
-	return 0;
-}				// probe_cs4281
-
-
-// --------------------------------------------------------------------- 
-
-static void __devinit cs4281_remove(struct pci_dev *dev)
-{
-	struct cs4281_state *s = (struct cs4281_state *) dev->driver_data;
-	// stop DMA controller 
-	synchronize_irq();
-	free_irq(s->irq, s);
-	unregister_sound_dsp(s->dev_audio);
-	unregister_sound_mixer(s->dev_mixer);
-	unregister_sound_midi(s->dev_midi);
-	kfree(s);
-	dev->driver_data = NULL;
-	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
-		  printk(KERN_INFO
-			 "cs4281: cs4281_remove(): remove successful\n"));
-}
-
-static struct pci_device_id id_table[] __devinitdata = {
-	
-	    {PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CRYSTAL_CS4281,
-	 PCI_ANY_ID, PCI_ANY_ID, 0, 0},
-	{0,}
-};
-
-MODULE_DEVICE_TABLE(pci, id_table);
-
-static struct pci_driver cs4281_driver = {
-	name:"cs4281",
-	id_table:id_table,
-	probe:cs4281_probe,
-	remove:cs4281_remove
-};
-
-static int __init init_cs4281(void)
-{
-
-	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: init_cs4281()+ \n"));
-	if (!pci_present()) {	/* No PCI bus in this machine! */
-		CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
-			  printk(KERN_INFO
-				 "cs4281: init_cs4281()- no pci bus found\n"));
-		return -ENODEV;
-	}
-	printk(KERN_INFO "cs4281: version v%d.%02d.%d time " __TIME__ " "
-	       __DATE__ "\n", CS4281_MAJOR_VERSION, CS4281_MINOR_VERSION,
-	       CS4281_ARCH);
-	if (!pci_register_driver(&cs4281_driver)) {
-		pci_unregister_driver(&cs4281_driver);
-		CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
-			  printk(KERN_INFO
-				 "cs4281: init_cs4281()- unable to register pci device \n"));
-		return -ENODEV;
-	}
-	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: init_cs4281()- 0\n"));
-	return 0;
-}
-
-
-// --------------------------------------------------------------------- 
-
-
-MODULE_AUTHOR("gw boynton, wesb@crystal.cirrus.com");
-MODULE_DESCRIPTION("Cirrus Logic CS4281 Driver");
-
-static void __exit cleanup_cs4281(void)
-{
-	pci_unregister_driver(&cs4281_driver);
-	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
-		  printk(KERN_INFO "cs4281: cleanup_cs4281() finished\n"));
-}
-
-// --------------------------------------------------------------------- 
-
-module_init(init_cs4281);
-module_exit(cleanup_cs4281);
diff -urN linux-2.4.2-pre1/drivers/sound/cs4281_hwdefs.h linux/drivers/sound/cs4281_hwdefs.h
--- linux-2.4.2-pre1/drivers/sound/cs4281_hwdefs.h	Sat Sep 23 20:23:09 2000
+++ linux/drivers/sound/cs4281_hwdefs.h	Wed Dec 31 16:00:00 1969
@@ -1,1234 +0,0 @@
-//****************************************************************************
-//
-// HWDEFS.H - Definitions of the registers and data structures used by the
-//            CS4281
-//
-// Copyright (c) 1999 Crystal Semiconductor Corp.
-//
-//****************************************************************************
-
-#ifndef _H_HWDEFS
-#define _H_HWDEFS
-
-//****************************************************************************
-//
-// The following define the offsets of the registers located in the PCI
-// configuration space of the CS4281 part.
-//
-//****************************************************************************
-#define PCICONFIG_DEVID_VENID                   0x00000000L
-#define PCICONFIG_STATUS_COMMAND                0x00000004L
-#define PCICONFIG_CLASS_REVISION                0x00000008L
-#define PCICONFIG_LATENCY_TIMER                 0x0000000CL
-#define PCICONFIG_BA0                           0x00000010L
-#define PCICONFIG_BA1                           0x00000014L
-#define PCICONFIG_SUBSYSID_SUBSYSVENID          0x0000002CL
-#define PCICONFIG_INTERRUPT                     0x0000003CL
-
-//****************************************************************************
-//
-// The following define the offsets of the registers accessed via base address
-// register zero on the CS4281 part.
-//
-//****************************************************************************
-#define BA0_HISR                                0x00000000L
-#define BA0_HICR                                0x00000008L
-#define BA0_HIMR                                0x0000000CL
-#define BA0_IIER                                0x00000010L
-#define BA0_HDSR0                               0x000000F0L
-#define BA0_HDSR1                               0x000000F4L
-#define BA0_HDSR2                               0x000000F8L
-#define BA0_HDSR3                               0x000000FCL
-#define BA0_DCA0                                0x00000110L
-#define BA0_DCC0                                0x00000114L
-#define BA0_DBA0                                0x00000118L
-#define BA0_DBC0                                0x0000011CL
-#define BA0_DCA1                                0x00000120L
-#define BA0_DCC1                                0x00000124L
-#define BA0_DBA1                                0x00000128L
-#define BA0_DBC1                                0x0000012CL
-#define BA0_DCA2                                0x00000130L
-#define BA0_DCC2                                0x00000134L
-#define BA0_DBA2                                0x00000138L
-#define BA0_DBC2                                0x0000013CL
-#define BA0_DCA3                                0x00000140L
-#define BA0_DCC3                                0x00000144L
-#define BA0_DBA3                                0x00000148L
-#define BA0_DBC3                                0x0000014CL
-#define BA0_DMR0                                0x00000150L
-#define BA0_DCR0                                0x00000154L
-#define BA0_DMR1                                0x00000158L
-#define BA0_DCR1                                0x0000015CL
-#define BA0_DMR2                                0x00000160L
-#define BA0_DCR2                                0x00000164L
-#define BA0_DMR3                                0x00000168L
-#define BA0_DCR3                                0x0000016CL
-#define BA0_DLMR                                0x00000170L
-#define BA0_DLSR                                0x00000174L
-#define BA0_FCR0                                0x00000180L
-#define BA0_FCR1                                0x00000184L
-#define BA0_FCR2                                0x00000188L
-#define BA0_FCR3                                0x0000018CL
-#define BA0_FPDR0                               0x00000190L
-#define BA0_FPDR1                               0x00000194L
-#define BA0_FPDR2                               0x00000198L
-#define BA0_FPDR3                               0x0000019CL
-#define BA0_FCHS                                0x0000020CL
-#define BA0_FSIC0                               0x00000210L
-#define BA0_FSIC1                               0x00000214L
-#define BA0_FSIC2                               0x00000218L
-#define BA0_FSIC3                               0x0000021CL
-#define BA0_PCICFG00                            0x00000300L
-#define BA0_PCICFG04                            0x00000304L
-#define BA0_PCICFG08                            0x00000308L
-#define BA0_PCICFG0C                            0x0000030CL
-#define BA0_PCICFG10                            0x00000310L
-#define BA0_PCICFG14                            0x00000314L
-#define BA0_PCICFG18                            0x00000318L
-#define BA0_PCICFG1C                            0x0000031CL
-#define BA0_PCICFG20                            0x00000320L
-#define BA0_PCICFG24                            0x00000324L
-#define BA0_PCICFG28                            0x00000328L
-#define BA0_PCICFG2C                            0x0000032CL
-#define BA0_PCICFG30                            0x00000330L
-#define BA0_PCICFG34                            0x00000334L
-#define BA0_PCICFG38                            0x00000338L
-#define BA0_PCICFG3C                            0x0000033CL
-#define BA0_PCICFG40                            0x00000340L
-#define BA0_PMCS                                0x00000344L
-#define BA0_CWPR                                0x000003E0L
-#define BA0_EPPMC                               0x000003E4L
-#define BA0_GPIOR                               0x000003E8L
-#define BA0_SPMC                                0x000003ECL
-#define BA0_CFLR                                0x000003F0L
-#define BA0_IISR                                0x000003F4L
-#define BA0_TMS                                 0x000003F8L
-#define BA0_SSVID                               0x000003FCL
-#define BA0_CLKCR1                              0x00000400L
-#define BA0_FRR                                 0x00000410L
-#define BA0_SLT12O                              0x0000041CL
-#define BA0_SERMC                               0x00000420L
-#define BA0_SERC1                               0x00000428L
-#define BA0_SERC2                               0x0000042CL
-#define BA0_SLT12M                              0x0000045CL
-#define BA0_ACCTL                               0x00000460L
-#define BA0_ACSTS                               0x00000464L
-#define BA0_ACOSV                               0x00000468L
-#define BA0_ACCAD                               0x0000046CL
-#define BA0_ACCDA                               0x00000470L
-#define BA0_ACISV                               0x00000474L
-#define BA0_ACSAD                               0x00000478L
-#define BA0_ACSDA                               0x0000047CL
-#define BA0_JSPT                                0x00000480L
-#define BA0_JSCTL                               0x00000484L
-#define BA0_MIDCR                               0x00000490L
-#define BA0_MIDCMD                              0x00000494L
-#define BA0_MIDSR                               0x00000494L
-#define BA0_MIDWP                               0x00000498L
-#define BA0_MIDRP                               0x0000049CL
-#define BA0_AODSD1                              0x000004A8L
-#define BA0_AODSD2                              0x000004ACL
-#define BA0_CFGI                                0x000004B0L
-#define BA0_SLT12M2                             0x000004DCL
-#define BA0_ACSTS2                              0x000004E4L
-#define BA0_ACISV2                              0x000004F4L
-#define BA0_ACSAD2                              0x000004F8L
-#define BA0_ACSDA2                              0x000004FCL
-#define BA0_IOTGP                               0x00000500L
-#define BA0_IOTSB                               0x00000504L
-#define BA0_IOTFM                               0x00000508L
-#define BA0_IOTDMA                              0x0000050CL
-#define BA0_IOTAC0                              0x00000500L
-#define BA0_IOTAC1                              0x00000504L
-#define BA0_IOTAC2                              0x00000508L
-#define BA0_IOTAC3                              0x0000050CL
-#define BA0_IOTPCP                              0x0000052CL
-#define BA0_IOTCC                               0x00000530L
-#define BA0_IOTCR                               0x0000058CL
-#define BA0_PCPRR                               0x00000600L
-#define BA0_PCPGR                               0x00000604L
-#define BA0_PCPCR                               0x00000608L
-#define BA0_PCPCIEN                             0x00000608L
-#define BA0_SBMAR                               0x00000700L
-#define BA0_SBMDR                               0x00000704L
-#define BA0_SBRR                                0x00000708L
-#define BA0_SBRDP                               0x0000070CL
-#define BA0_SBWDP                               0x00000710L
-#define BA0_SBWBS                               0x00000710L
-#define BA0_SBRBS                               0x00000714L
-#define BA0_FMSR                                0x00000730L
-#define BA0_B0AP                                0x00000730L
-#define BA0_FMDP                                0x00000734L
-#define BA0_B1AP                                0x00000738L
-#define BA0_B1DP                                0x0000073CL
-#define BA0_SSPM                                0x00000740L
-#define BA0_DACSR                               0x00000744L
-#define BA0_ADCSR                               0x00000748L
-#define BA0_SSCR                                0x0000074CL
-#define BA0_FMLVC                               0x00000754L
-#define BA0_FMRVC                               0x00000758L
-#define BA0_SRCSA                               0x0000075CL
-#define BA0_PPLVC                               0x00000760L
-#define BA0_PPRVC                               0x00000764L
-#define BA0_PASR                                0x00000768L
-#define BA0_CASR                                0x0000076CL
-
-//****************************************************************************
-//
-// The following define the offsets of the AC97 shadow registers, which appear
-// as a virtual extension to the base address register zero memory range.
-//
-//****************************************************************************
-#define AC97_REG_OFFSET_MASK                    0x0000007EL
-#define AC97_CODEC_NUMBER_MASK                  0x00003000L
-
-#define BA0_AC97_RESET                          0x00001000L
-#define BA0_AC97_MASTER_VOLUME                  0x00001002L
-#define BA0_AC97_HEADPHONE_VOLUME               0x00001004L
-#define BA0_AC97_MASTER_VOLUME_MONO             0x00001006L
-#define BA0_AC97_MASTER_TONE                    0x00001008L
-#define BA0_AC97_PC_BEEP_VOLUME                 0x0000100AL
-#define BA0_AC97_PHONE_VOLUME                   0x0000100CL
-#define BA0_AC97_MIC_VOLUME                     0x0000100EL
-#define BA0_AC97_LINE_IN_VOLUME                 0x00001010L
-#define BA0_AC97_CD_VOLUME                      0x00001012L
-#define BA0_AC97_VIDEO_VOLUME                   0x00001014L
-#define BA0_AC97_AUX_VOLUME                     0x00001016L
-#define BA0_AC97_PCM_OUT_VOLUME                 0x00001018L
-#define BA0_AC97_RECORD_SELECT                  0x0000101AL
-#define BA0_AC97_RECORD_GAIN                    0x0000101CL
-#define BA0_AC97_RECORD_GAIN_MIC                0x0000101EL
-#define BA0_AC97_GENERAL_PURPOSE                0x00001020L
-#define BA0_AC97_3D_CONTROL                     0x00001022L
-#define BA0_AC97_MODEM_RATE                     0x00001024L
-#define BA0_AC97_POWERDOWN                      0x00001026L
-#define BA0_AC97_EXT_AUDIO_ID                   0x00001028L
-#define BA0_AC97_EXT_AUDIO_POWER                0x0000102AL
-#define BA0_AC97_PCM_FRONT_DAC_RATE             0x0000102CL
-#define BA0_AC97_PCM_SURR_DAC_RATE              0x0000102EL
-#define BA0_AC97_PCM_LFE_DAC_RATE               0x00001030L
-#define BA0_AC97_PCM_LR_ADC_RATE                0x00001032L
-#define BA0_AC97_MIC_ADC_RATE                   0x00001034L
-#define BA0_AC97_6CH_VOL_C_LFE                  0x00001036L
-#define BA0_AC97_6CH_VOL_SURROUND               0x00001038L
-#define BA0_AC97_RESERVED_3A                    0x0000103AL
-#define BA0_AC97_EXT_MODEM_ID                   0x0000103CL
-#define BA0_AC97_EXT_MODEM_POWER                0x0000103EL
-#define BA0_AC97_LINE1_CODEC_RATE               0x00001040L
-#define BA0_AC97_LINE2_CODEC_RATE               0x00001042L
-#define BA0_AC97_HANDSET_CODEC_RATE             0x00001044L
-#define BA0_AC97_LINE1_CODEC_LEVEL              0x00001046L
-#define BA0_AC97_LINE2_CODEC_LEVEL              0x00001048L
-#define BA0_AC97_HANDSET_CODEC_LEVEL            0x0000104AL
-#define BA0_AC97_GPIO_PIN_CONFIG                0x0000104CL
-#define BA0_AC97_GPIO_PIN_TYPE                  0x0000104EL
-#define BA0_AC97_GPIO_PIN_STICKY                0x00001050L
-#define BA0_AC97_GPIO_PIN_WAKEUP                0x00001052L
-#define BA0_AC97_GPIO_PIN_STATUS                0x00001054L
-#define BA0_AC97_MISC_MODEM_AFE_STAT            0x00001056L
-#define BA0_AC97_RESERVED_58                    0x00001058L
-#define BA0_AC97_CRYSTAL_REV_N_FAB_ID           0x0000105AL
-#define BA0_AC97_TEST_AND_MISC_CTRL             0x0000105CL
-#define BA0_AC97_AC_MODE                        0x0000105EL
-#define BA0_AC97_MISC_CRYSTAL_CONTROL           0x00001060L
-#define BA0_AC97_LINE1_HYPRID_CTRL              0x00001062L
-#define BA0_AC97_VENDOR_RESERVED_64             0x00001064L
-#define BA0_AC97_VENDOR_RESERVED_66             0x00001066L
-#define BA0_AC97_SPDIF_CONTROL                  0x00001068L
-#define BA0_AC97_VENDOR_RESERVED_6A             0x0000106AL
-#define BA0_AC97_VENDOR_RESERVED_6C             0x0000106CL
-#define BA0_AC97_VENDOR_RESERVED_6E             0x0000106EL
-#define BA0_AC97_VENDOR_RESERVED_70             0x00001070L
-#define BA0_AC97_VENDOR_RESERVED_72             0x00001072L
-#define BA0_AC97_VENDOR_RESERVED_74             0x00001074L
-#define BA0_AC97_CAL_ADDRESS                    0x00001076L
-#define BA0_AC97_CAL_DATA                       0x00001078L
-#define BA0_AC97_VENDOR_RESERVED_7A             0x0000107AL
-#define BA0_AC97_VENDOR_ID1                     0x0000107CL
-#define BA0_AC97_VENDOR_ID2                     0x0000107EL
-
-//****************************************************************************
-//
-// The following define the offsets of the registers and memories accessed via
-// base address register one on the CS4281 part.
-//
-//****************************************************************************
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI device ID/vendor ID
-// register.
-//
-//****************************************************************************
-#define PDV_VENID_MASK                          0x0000FFFFL
-#define PDV_DEVID_MASK                          0xFFFF0000L
-#define PDV_VENID_SHIFT                         0L
-#define PDV_DEVID_SHIFT                         16L
-#define VENID_CIRRUS_LOGIC                      0x1013L
-#define DEVID_CS4281                            0x6005L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI status and command
-// register.
-//
-//****************************************************************************
-#define PSC_IO_SPACE_ENABLE                     0x00000001L
-#define PSC_MEMORY_SPACE_ENABLE                 0x00000002L
-#define PSC_BUS_MASTER_ENABLE                   0x00000004L
-#define PSC_SPECIAL_CYCLES                      0x00000008L
-#define PSC_MWI_ENABLE                          0x00000010L
-#define PSC_VGA_PALETTE_SNOOP                   0x00000020L
-#define PSC_PARITY_RESPONSE                     0x00000040L
-#define PSC_WAIT_CONTROL                        0x00000080L
-#define PSC_SERR_ENABLE                         0x00000100L
-#define PSC_FAST_B2B_ENABLE                     0x00000200L
-#define PSC_UDF_MASK                            0x007F0000L
-#define PSC_FAST_B2B_CAPABLE                    0x00800000L
-#define PSC_PARITY_ERROR_DETECTED               0x01000000L
-#define PSC_DEVSEL_TIMING_MASK                  0x06000000L
-#define PSC_TARGET_ABORT_SIGNALLED              0x08000000L
-#define PSC_RECEIVED_TARGET_ABORT               0x10000000L
-#define PSC_RECEIVED_MASTER_ABORT               0x20000000L
-#define PSC_SIGNALLED_SERR                      0x40000000L
-#define PSC_DETECTED_PARITY_ERROR               0x80000000L
-#define PSC_UDF_SHIFT                           16L
-#define PSC_DEVSEL_TIMING_SHIFT                 25L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI class/revision ID
-// register.
-//
-//****************************************************************************
-#define PCR_REVID_MASK                          0x000000FFL
-#define PCR_INTERFACE_MASK                      0x0000FF00L
-#define PCR_SUBCLASS_MASK                       0x00FF0000L
-#define PCR_CLASS_MASK                          0xFF000000L
-#define PCR_REVID_SHIFT                         0L
-#define PCR_INTERFACE_SHIFT                     8L
-#define PCR_SUBCLASS_SHIFT                      16L
-#define PCR_CLASS_SHIFT                         24L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI latency timer register.
-//
-//****************************************************************************
-#define PLT_CACHE_LINE_SIZE_MASK                0x000000FFL
-#define PLT_LATENCY_TIMER_MASK                  0x0000FF00L
-#define PLT_HEADER_TYPE_MASK                    0x00FF0000L
-#define PLT_BIST_MASK                           0xFF000000L
-#define PLT_CACHE_LINE_SIZE_SHIFT               0L
-#define PLT_LATENCY_TIMER_SHIFT                 8L
-#define PLT_HEADER_TYPE_SHIFT                   16L
-#define PLT_BIST_SHIFT                          24L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI base address registers.
-//
-//****************************************************************************
-#define PBAR_MEMORY_SPACE_INDICATOR             0x00000001L
-#define PBAR_LOCATION_TYPE_MASK                 0x00000006L
-#define PBAR_NOT_PREFETCHABLE                   0x00000008L
-#define PBAR_ADDRESS_MASK                       0xFFFFFFF0L
-#define PBAR_LOCATION_TYPE_SHIFT                1L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI subsystem ID/subsystem
-// vendor ID register.
-//
-//****************************************************************************
-#define PSS_SUBSYSTEM_VENDOR_ID_MASK            0x0000FFFFL
-#define PSS_SUBSYSTEM_ID_MASK                   0xFFFF0000L
-#define PSS_SUBSYSTEM_VENDOR_ID_SHIFT           0L
-#define PSS_SUBSYSTEM_ID_SHIFT                  16L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI interrupt register.
-//
-//****************************************************************************
-#define PI_LINE_MASK                            0x000000FFL
-#define PI_PIN_MASK                             0x0000FF00L
-#define PI_MIN_GRANT_MASK                       0x00FF0000L
-#define PI_MAX_LATENCY_MASK                     0xFF000000L
-#define PI_LINE_SHIFT                           0L
-#define PI_PIN_SHIFT                            8L
-#define PI_MIN_GRANT_SHIFT                      16L
-#define PI_MAX_LATENCY_SHIFT                    24L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the host interrupt status
-// register.
-//
-//****************************************************************************
-#define HISR_HVOLMASK                            0x00000003L
-#define HISR_VDNI                                0x00000001L
-#define HISR_VUPI                                0x00000002L
-#define HISR_GP1I                                0x00000004L
-#define HISR_GP3I                                0x00000008L
-#define HISR_GPSI                                0x00000010L
-#define HISR_GPPI                                0x00000020L
-#define HISR_DMAI                                0x00040000L
-#define HISR_FIFOI                               0x00100000L
-#define HISR_HVOL                                0x00200000L
-#define HISR_MIDI                                0x00400000L
-#define HISR_SBINT                               0x00800000L
-#define HISR_INTENA                              0x80000000L
-#define HISR_DMA_MASK                            0x00000F00L
-#define HISR_FIFO_MASK                           0x0000F000L
-#define HISR_DMA_SHIFT                           8L
-#define HISR_FIFO_SHIFT                          12L
-#define HISR_FIFO0                               0x00001000L
-#define HISR_FIFO1                               0x00002000L
-#define HISR_FIFO2                               0x00004000L
-#define HISR_FIFO3                               0x00008000L
-#define HISR_DMA0                                0x00000100L
-#define HISR_DMA1                                0x00000200L
-#define HISR_DMA2                                0x00000400L
-#define HISR_DMA3                                0x00000800L
-#define HISR_RESERVED                            0x40000000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the host interrupt control
-// register.
-//
-//****************************************************************************
-#define HICR_IEV                                 0x00000001L
-#define HICR_CHGM                                0x00000002L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the DMA Mode Register n
-// (DMRn)
-//
-//****************************************************************************
-#define DMRn_TR_MASK                             0x0000000CL
-#define DMRn_TR_SHIFT                            2L
-#define DMRn_AUTO                                0x00000010L
-#define DMRn_TR_READ                             0x00000008L
-#define DMRn_TR_WRITE                            0x00000004L
-#define DMRn_TYPE_MASK                           0x000000C0L
-#define DMRn_TYPE_SHIFT                          6L
-#define DMRn_SIZE8                               0x00010000L
-#define DMRn_MONO                                0x00020000L
-#define DMRn_BEND                                0x00040000L
-#define DMRn_USIGN                               0x00080000L
-#define DMRn_SIZE20                              0x00100000L
-#define DMRn_SWAPC                               0x00400000L
-#define DMRn_CBC                                 0x01000000L
-#define DMRn_TBC                                 0x02000000L
-#define DMRn_POLL                                0x10000000L
-#define DMRn_DMA                                 0x20000000L
-#define DMRn_FSEL_MASK                           0xC0000000L
-#define DMRn_FSEL_SHIFT                          30L
-#define DMRn_FSEL0                               0x00000000L
-#define DMRn_FSEL1                               0x40000000L
-#define DMRn_FSEL2                               0x80000000L
-#define DMRn_FSEL3                               0xC0000000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the DMA Command Register n
-// (DCRn)
-//
-//****************************************************************************
-#define DCRn_HTCIE                               0x00020000L
-#define DCRn_TCIE                                0x00010000L
-#define DCRn_MSK                                 0x00000001L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the FIFO Control 
-// register n.(FCRn)
-//
-//****************************************************************************
-#define FCRn_OF_MASK                            0x0000007FL
-#define FCRn_OF_SHIFT                           0L
-#define FCRn_SZ_MASK                            0x00007F00L
-#define FCRn_SZ_SHIFT                           8L
-#define FCRn_LS_MASK                            0x001F0000L
-#define FCRn_LS_SHIFT                           16L
-#define FCRn_RS_MASK                            0x1F000000L
-#define FCRn_RS_SHIFT                           24L
-#define FCRn_FEN                                0x80000000L
-#define FCRn_PSH                                0x20000000L
-#define FCRn_DACZ                               0x40000000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the serial port Power Management
-// control register.(SPMC)
-//
-//****************************************************************************
-#define SPMC_RSTN                               0x00000001L
-#define SPMC_ASYN                               0x00000002L
-#define SPMC_WUP1                               0x00000004L
-#define SPMC_WUP2                               0x00000008L
-#define SPMC_ASDI2E                             0x00000100L
-#define SPMC_ESSPD                              0x00000200L
-#define SPMC_GISPEN                             0x00004000L
-#define SPMC_GIPPEN                             0x00008000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the Configuration Load register.
-// (CFLR)
-//
-//****************************************************************************
-#define CFLR_CLOCK_SOURCE_MASK                  0x00000003L
-#define CFLR_CLOCK_SOURCE_AC97                  0x00000001L
-
-#define CFLR_CB0_MASK                            0x000000FFL
-#define CFLR_CB1_MASK                            0x0000FF00L
-#define CFLR_CB2_MASK                            0x00FF0000L
-#define CFLR_CB3_MASK                            0xFF000000L
-#define CFLR_CB0_SHIFT                           0L
-#define CFLR_CB1_SHIFT                           8L
-#define CFLR_CB2_SHIFT                           16L
-#define CFLR_CB3_SHIFT                           24L
-
-#define IOTCR_DMA0                              0x00000000L
-#define IOTCR_DMA1                              0x00000400L
-#define IOTCR_DMA2                              0x00000800L
-#define IOTCR_DMA3                              0x00000C00L
-#define IOTCR_CCLS                              0x00000100L
-#define IOTCR_PCPCI                             0x00000200L
-#define IOTCR_DDMA                              0x00000300L
-
-#define SBWBS_WBB                               0x00000080L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the SRC Slot Assignment Register
-// (SRCSA)
-//
-//****************************************************************************
-#define SRCSA_PLSS_MASK                         0x0000001FL
-#define SRCSA_PLSS_SHIFT                        0L
-#define SRCSA_PRSS_MASK                         0x00001F00L
-#define SRCSA_PRSS_SHIFT                        8L
-#define SRCSA_CLSS_MASK                         0x001F0000L
-#define SRCSA_CLSS_SHIFT                        16L
-#define SRCSA_CRSS_MASK                         0x1F000000L
-#define SRCSA_CRSS_SHIFT                        24L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the Sound System Power Management
-// register.(SSPM)
-//
-//****************************************************************************
-#define SSPM_FPDN                               0x00000080L
-#define SSPM_MIXEN                              0x00000040L
-#define SSPM_CSRCEN                             0x00000020L
-#define SSPM_PSRCEN                             0x00000010L
-#define SSPM_JSEN                               0x00000008L
-#define SSPM_ACLEN                              0x00000004L
-#define SSPM_FMEN                               0x00000002L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the Sound System Control
-// Register. (SSCR)
-//
-//****************************************************************************
-#define SSCR_SB                                 0x00000004L
-#define SSCR_HVC                                0x00000008L
-#define SSCR_LPFIFO                             0x00000040L
-#define SSCR_LPSRC                              0x00000080L
-#define SSCR_XLPSRC                             0x00000100L
-#define SSCR_MVMD                               0x00010000L
-#define SSCR_MVAD                               0x00020000L
-#define SSCR_MVLD                               0x00040000L
-#define SSCR_MVCS                               0x00080000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the Clock Control Register 1. 
-// (CLKCR1)
-//
-//****************************************************************************
-#define CLKCR1_DLLSS_MASK                       0x0000000CL
-#define CLKCR1_DLLSS_SHIFT                      2L
-#define CLKCR1_DLLP                             0x00000010L
-#define CLKCR1_SWCE                             0x00000020L
-#define CLKCR1_DLLOS                            0x00000040L
-#define CLKCR1_CKRA                             0x00010000L
-#define CLKCR1_CKRN                             0x00020000L
-#define CLKCR1_DLLRDY                           0x01000000L
-#define CLKCR1_CLKON                            0x02000000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the Sound Blaster Read Buffer
-// Status.(SBRBS)
-//
-//****************************************************************************
-#define SBRBS_RD_MASK                           0x0000007FL
-#define SBRBS_RD_SHIFT                          0L
-#define SBRBS_RBF                               0x00000080L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the serial port master control
-// register.(SERMC)
-//
-//****************************************************************************
-#define SERMC_MSPE                              0x00000001L
-#define SERMC_PTC_MASK                          0x0000000EL
-#define SERMC_PTC_SHIFT                         1L
-#define SERMC_PTC_AC97                          0x00000002L
-#define SERMC_PLB                               0x00000010L
-#define SERMC_PXLB                              0x00000020L
-#define SERMC_LOFV                              0x00080000L
-#define SERMC_SLB                               0x00100000L
-#define SERMC_SXLB                              0x00200000L
-#define SERMC_ODSEN1                            0x01000000L
-#define SERMC_ODSEN2                            0x02000000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the General Purpose I/O Register. 
-// (GPIOR)
-//
-//****************************************************************************
-#define GPIOR_VDNS                              0x00000001L
-#define GPIOR_VUPS                              0x00000002L
-#define GPIOR_GP1S                              0x00000004L
-#define GPIOR_GP3S                              0x00000008L
-#define GPIOR_GPSS                              0x00000010L
-#define GPIOR_GPPS                              0x00000020L
-#define GPIOR_GP1D                              0x00000400L
-#define GPIOR_GP3D                              0x00000800L
-#define GPIOR_VDNLT                             0x00010000L
-#define GPIOR_VDNPO                             0x00020000L
-#define GPIOR_VDNST                             0x00040000L
-#define GPIOR_VDNW                              0x00080000L
-#define GPIOR_VUPLT                             0x00100000L
-#define GPIOR_VUPPO                             0x00200000L
-#define GPIOR_VUPST                             0x00400000L
-#define GPIOR_VUPW                              0x00800000L
-#define GPIOR_GP1OE                             0x01000000L
-#define GPIOR_GP1PT                             0x02000000L
-#define GPIOR_GP1ST                             0x04000000L
-#define GPIOR_GP1W                              0x08000000L
-#define GPIOR_GP3OE                             0x10000000L
-#define GPIOR_GP3PT                             0x20000000L
-#define GPIOR_GP3ST                             0x40000000L
-#define GPIOR_GP3W                              0x80000000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the clock control register 1.
-//
-//****************************************************************************
-#define CLKCR1_PLLSS_MASK                       0x0000000CL
-#define CLKCR1_PLLSS_SERIAL                     0x00000000L
-#define CLKCR1_PLLSS_CRYSTAL                    0x00000004L
-#define CLKCR1_PLLSS_PCI                        0x00000008L
-#define CLKCR1_PLLSS_RESERVED                   0x0000000CL
-#define CLKCR1_PLLP                             0x00000010L
-#define CLKCR1_SWCE                             0x00000020L
-#define CLKCR1_PLLOS                            0x00000040L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the feature reporting register.
-//
-//****************************************************************************
-#define FRR_FAB_MASK                            0x00000003L
-#define FRR_MASK_MASK                           0x0000001CL
-#define FRR_ID_MASK                             0x00003000L
-#define FRR_FAB_SHIFT                           0L
-#define FRR_MASK_SHIFT                          2L
-#define FRR_ID_SHIFT                            12L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the serial port 1 configuration
-// register.
-//
-//****************************************************************************
-#define SERC1_VALUE                             0x00000003L
-#define SERC1_SO1EN                             0x00000001L
-#define SERC1_SO1F_MASK                         0x0000000EL
-#define SERC1_SO1F_CS423X                       0x00000000L
-#define SERC1_SO1F_AC97                         0x00000002L
-#define SERC1_SO1F_DAC                          0x00000004L
-#define SERC1_SO1F_SPDIF                        0x00000006L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the serial port 2 configuration
-// register.
-//
-//****************************************************************************
-#define SERC2_VALUE                             0x00000003L
-#define SERC2_SI1EN                             0x00000001L
-#define SERC2_SI1F_MASK                         0x0000000EL
-#define SERC2_SI1F_CS423X                       0x00000000L
-#define SERC2_SI1F_AC97                         0x00000002L
-#define SERC2_SI1F_ADC                          0x00000004L
-#define SERC2_SI1F_SPDIF                        0x00000006L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 control register.
-//
-//****************************************************************************
-#define ACCTL_ESYN                              0x00000002L
-#define ACCTL_VFRM                              0x00000004L
-#define ACCTL_DCV                               0x00000008L
-#define ACCTL_CRW                               0x00000010L
-#define ACCTL_TC                                0x00000040L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 status register.
-//
-//****************************************************************************
-#define ACSTS_CRDY                              0x00000001L
-#define ACSTS_VSTS                              0x00000002L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 output slot valid
-// register.
-//
-//****************************************************************************
-#define ACOSV_SLV3                              0x00000001L
-#define ACOSV_SLV4                              0x00000002L
-#define ACOSV_SLV5                              0x00000004L
-#define ACOSV_SLV6                              0x00000008L
-#define ACOSV_SLV7                              0x00000010L
-#define ACOSV_SLV8                              0x00000020L
-#define ACOSV_SLV9                              0x00000040L
-#define ACOSV_SLV10                             0x00000080L
-#define ACOSV_SLV11                             0x00000100L
-#define ACOSV_SLV12                             0x00000200L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 command address
-// register.
-//
-//****************************************************************************
-#define ACCAD_CI_MASK                           0x0000007FL
-#define ACCAD_CI_SHIFT                          0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 command data register.
-//
-//****************************************************************************
-#define ACCDA_CD_MASK                           0x0000FFFFL
-#define ACCDA_CD_SHIFT                          0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 input slot valid
-// register.
-//
-//****************************************************************************
-#define ACISV_ISV3                              0x00000001L
-#define ACISV_ISV4                              0x00000002L
-#define ACISV_ISV5                              0x00000004L
-#define ACISV_ISV6                              0x00000008L
-#define ACISV_ISV7                              0x00000010L
-#define ACISV_ISV8                              0x00000020L
-#define ACISV_ISV9                              0x00000040L
-#define ACISV_ISV10                             0x00000080L
-#define ACISV_ISV11                             0x00000100L
-#define ACISV_ISV12                             0x00000200L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 status address
-// register.
-//
-//****************************************************************************
-#define ACSAD_SI_MASK                           0x0000007FL
-#define ACSAD_SI_SHIFT                          0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 status data register.
-//
-//****************************************************************************
-#define ACSDA_SD_MASK                           0x0000FFFFL
-#define ACSDA_SD_SHIFT                          0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the I/O trap address and control
-// registers (all 12).
-//
-//****************************************************************************
-#define IOTAC_SA_MASK                           0x0000FFFFL
-#define IOTAC_MSK_MASK                          0x000F0000L
-#define IOTAC_IODC_MASK                         0x06000000L
-#define IOTAC_IODC_16_BIT                       0x00000000L
-#define IOTAC_IODC_10_BIT                       0x02000000L
-#define IOTAC_IODC_12_BIT                       0x04000000L
-#define IOTAC_WSPI                              0x08000000L
-#define IOTAC_RSPI                              0x10000000L
-#define IOTAC_WSE                               0x20000000L
-#define IOTAC_WE                                0x40000000L
-#define IOTAC_RE                                0x80000000L
-#define IOTAC_SA_SHIFT                          0L
-#define IOTAC_MSK_SHIFT                         16L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PC/PCI master enable
-// register.
-//
-//****************************************************************************
-#define PCPCIEN_EN                              0x00000001L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the joystick poll/trigger
-// register.
-//
-//****************************************************************************
-#define JSPT_CAX                                0x00000001L
-#define JSPT_CAY                                0x00000002L
-#define JSPT_CBX                                0x00000004L
-#define JSPT_CBY                                0x00000008L
-#define JSPT_BA1                                0x00000010L
-#define JSPT_BA2                                0x00000020L
-#define JSPT_BB1                                0x00000040L
-#define JSPT_BB2                                0x00000080L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the joystick control register.
-// The TBF bit has been moved from MIDSR register to JSCTL register bit 8.
-//
-//****************************************************************************
-#define JSCTL_SP_MASK                           0x00000003L
-#define JSCTL_SP_SLOW                           0x00000000L
-#define JSCTL_SP_MEDIUM_SLOW                    0x00000001L
-#define JSCTL_SP_MEDIUM_FAST                    0x00000002L
-#define JSCTL_SP_FAST                           0x00000003L
-#define JSCTL_ARE                               0x00000004L
-#define JSCTL_TBF                               0x00000100L
-
-
-//****************************************************************************
-//
-// The following defines are for the flags in the MIDI control register.
-//
-//****************************************************************************
-#define MIDCR_TXE                               0x00000001L
-#define MIDCR_RXE                               0x00000002L
-#define MIDCR_RIE                               0x00000004L
-#define MIDCR_TIE                               0x00000008L
-#define MIDCR_MLB                               0x00000010L
-#define MIDCR_MRST                              0x00000020L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the MIDI status register.
-//
-//****************************************************************************
-#define MIDSR_RBE                               0x00000080L
-#define MIDSR_RDA                               0x00008000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the MIDI write port register.
-//
-//****************************************************************************
-#define MIDWP_MWD_MASK                          0x000000FFL
-#define MIDWP_MWD_SHIFT                         0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the MIDI read port register.
-//
-//****************************************************************************
-#define MIDRP_MRD_MASK                          0x000000FFL
-#define MIDRP_MRD_SHIFT                         0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the configuration interface
-// register.
-//
-//****************************************************************************
-#define CFGI_CLK                                0x00000001L
-#define CFGI_DOUT                               0x00000002L
-#define CFGI_DIN_EEN                            0x00000004L
-#define CFGI_EELD                               0x00000008L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the subsystem ID and vendor ID
-// register.
-//
-//****************************************************************************
-#define SSVID_VID_MASK                          0x0000FFFFL
-#define SSVID_SID_MASK                          0xFFFF0000L
-#define SSVID_VID_SHIFT                         0L
-#define SSVID_SID_SHIFT                         16L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the GPIO pin interface register.
-//
-//****************************************************************************
-#define GPIOR_VOLDN                             0x00000001L
-#define GPIOR_VOLUP                             0x00000002L
-#define GPIOR_SI2D                              0x00000004L
-#define GPIOR_SI2OE                             0x00000008L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 status register 2.
-//
-//****************************************************************************
-#define ACSTS2_CRDY                             0x00000001L
-#define ACSTS2_VSTS                             0x00000002L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 input slot valid
-// register 2.
-//
-//****************************************************************************
-#define ACISV2_ISV3                             0x00000001L
-#define ACISV2_ISV4                             0x00000002L
-#define ACISV2_ISV5                             0x00000004L
-#define ACISV2_ISV6                             0x00000008L
-#define ACISV2_ISV7                             0x00000010L
-#define ACISV2_ISV8                             0x00000020L
-#define ACISV2_ISV9                             0x00000040L
-#define ACISV2_ISV10                            0x00000080L
-#define ACISV2_ISV11                            0x00000100L
-#define ACISV2_ISV12                            0x00000200L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 status address
-// register 2.
-//
-//****************************************************************************
-#define ACSAD2_SI_MASK                          0x0000007FL
-#define ACSAD2_SI_SHIFT                         0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 status data register 2.
-//
-//****************************************************************************
-#define ACSDA2_SD_MASK                          0x0000FFFFL
-#define ACSDA2_SD_SHIFT                         0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the I/O trap control register.
-//
-//****************************************************************************
-#define IOTCR_ITD                               0x00000001L
-#define IOTCR_HRV                               0x00000002L
-#define IOTCR_SRV                               0x00000004L
-#define IOTCR_DTI                               0x00000008L
-#define IOTCR_DFI                               0x00000010L
-#define IOTCR_DDP                               0x00000020L
-#define IOTCR_JTE                               0x00000040L
-#define IOTCR_PPE                               0x00000080L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the I/O trap address and control
-// registers for Hardware Master Volume.  
-//
-//****************************************************************************
-#define IOTGP_SA_MASK                           0x0000FFFFL
-#define IOTGP_MSK_MASK                          0x000F0000L
-#define IOTGP_IODC_MASK                         0x06000000L
-#define IOTGP_IODC_16_BIT                       0x00000000L
-#define IOTGP_IODC_10_BIT                       0x02000000L
-#define IOTGP_IODC_12_BIT                       0x04000000L
-#define IOTGP_WSPI                              0x08000000L
-#define IOTGP_RSPI                              0x10000000L
-#define IOTGP_WSE                               0x20000000L
-#define IOTGP_WE                                0x40000000L
-#define IOTGP_RE                                0x80000000L
-#define IOTGP_SA_SHIFT                          0L
-#define IOTGP_MSK_SHIFT                         16L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the I/O trap address and control
-// registers for Sound Blaster
-//
-//****************************************************************************
-#define IOTSB_SA_MASK                           0x0000FFFFL
-#define IOTSB_MSK_MASK                          0x000F0000L
-#define IOTSB_IODC_MASK                         0x06000000L
-#define IOTSB_IODC_16_BIT                       0x00000000L
-#define IOTSB_IODC_10_BIT                       0x02000000L
-#define IOTSB_IODC_12_BIT                       0x04000000L
-#define IOTSB_WSPI                              0x08000000L
-#define IOTSB_RSPI                              0x10000000L
-#define IOTSB_WSE                               0x20000000L
-#define IOTSB_WE                                0x40000000L
-#define IOTSB_RE                                0x80000000L
-#define IOTSB_SA_SHIFT                          0L
-#define IOTSB_MSK_SHIFT                         16L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the I/O trap address and control
-// registers for FM.
-//
-//****************************************************************************
-#define IOTFM_SA_MASK                           0x0000FFFFL
-#define IOTFM_MSK_MASK                          0x000F0000L
-#define IOTFM_IODC_MASK                         0x06000000L
-#define IOTFM_IODC_16_BIT                       0x00000000L
-#define IOTFM_IODC_10_BIT                       0x02000000L
-#define IOTFM_IODC_12_BIT                       0x04000000L
-#define IOTFM_WSPI                              0x08000000L
-#define IOTFM_RSPI                              0x10000000L
-#define IOTFM_WSE                               0x20000000L
-#define IOTFM_WE                                0x40000000L
-#define IOTFM_RE                                0x80000000L
-#define IOTFM_SA_SHIFT                          0L
-#define IOTFM_MSK_SHIFT                         16L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PC/PCI request register.
-//
-//****************************************************************************
-#define PCPRR_RDC_MASK                         0x00000007L
-#define PCPRR_REQ                              0x00008000L
-#define PCPRR_RDC_SHIFT                        0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PC/PCI grant register.
-//
-//****************************************************************************
-#define PCPGR_GDC_MASK                         0x00000007L
-#define PCPGR_VL                               0x00008000L
-#define PCPGR_GDC_SHIFT                        0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PC/PCI Control Register.
-//
-//****************************************************************************
-#define PCPCR_EN                               0x00000001L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the debug index register.
-//
-//****************************************************************************
-#define DREG_REGID_MASK                         0x0000007FL
-#define DREG_DEBUG                              0x00000080L
-#define DREG_RGBK_MASK                          0x00000700L
-#define DREG_TRAP                               0x00000800L
-#if !defined(NO_CS4612)
-#if !defined(NO_CS4615)
-#define DREG_TRAPX                              0x00001000L
-#endif
-#endif
-#define DREG_REGID_SHIFT                        0L
-#define DREG_RGBK_SHIFT                         8L
-#define DREG_RGBK_REGID_MASK                    0x0000077FL
-#define DREG_REGID_R0                           0x00000010L
-#define DREG_REGID_R1                           0x00000011L
-#define DREG_REGID_R2                           0x00000012L
-#define DREG_REGID_R3                           0x00000013L
-#define DREG_REGID_R4                           0x00000014L
-#define DREG_REGID_R5                           0x00000015L
-#define DREG_REGID_R6                           0x00000016L
-#define DREG_REGID_R7                           0x00000017L
-#define DREG_REGID_R8                           0x00000018L
-#define DREG_REGID_R9                           0x00000019L
-#define DREG_REGID_RA                           0x0000001AL
-#define DREG_REGID_RB                           0x0000001BL
-#define DREG_REGID_RC                           0x0000001CL
-#define DREG_REGID_RD                           0x0000001DL
-#define DREG_REGID_RE                           0x0000001EL
-#define DREG_REGID_RF                           0x0000001FL
-#define DREG_REGID_RA_BUS_LOW                   0x00000020L
-#define DREG_REGID_RA_BUS_HIGH                  0x00000038L
-#define DREG_REGID_YBUS_LOW                     0x00000050L
-#define DREG_REGID_YBUS_HIGH                    0x00000058L
-#define DREG_REGID_TRAP_0                       0x00000100L
-#define DREG_REGID_TRAP_1                       0x00000101L
-#define DREG_REGID_TRAP_2                       0x00000102L
-#define DREG_REGID_TRAP_3                       0x00000103L
-#define DREG_REGID_TRAP_4                       0x00000104L
-#define DREG_REGID_TRAP_5                       0x00000105L
-#define DREG_REGID_TRAP_6                       0x00000106L
-#define DREG_REGID_TRAP_7                       0x00000107L
-#define DREG_REGID_INDIRECT_ADDRESS             0x0000010EL
-#define DREG_REGID_TOP_OF_STACK                 0x0000010FL
-#if !defined(NO_CS4612)
-#if !defined(NO_CS4615)
-#define DREG_REGID_TRAP_8                       0x00000110L
-#define DREG_REGID_TRAP_9                       0x00000111L
-#define DREG_REGID_TRAP_10                      0x00000112L
-#define DREG_REGID_TRAP_11                      0x00000113L
-#define DREG_REGID_TRAP_12                      0x00000114L
-#define DREG_REGID_TRAP_13                      0x00000115L
-#define DREG_REGID_TRAP_14                      0x00000116L
-#define DREG_REGID_TRAP_15                      0x00000117L
-#define DREG_REGID_TRAP_16                      0x00000118L
-#define DREG_REGID_TRAP_17                      0x00000119L
-#define DREG_REGID_TRAP_18                      0x0000011AL
-#define DREG_REGID_TRAP_19                      0x0000011BL
-#define DREG_REGID_TRAP_20                      0x0000011CL
-#define DREG_REGID_TRAP_21                      0x0000011DL
-#define DREG_REGID_TRAP_22                      0x0000011EL
-#define DREG_REGID_TRAP_23                      0x0000011FL
-#endif
-#endif
-#define DREG_REGID_RSA0_LOW                     0x00000200L
-#define DREG_REGID_RSA0_HIGH                    0x00000201L
-#define DREG_REGID_RSA1_LOW                     0x00000202L
-#define DREG_REGID_RSA1_HIGH                    0x00000203L
-#define DREG_REGID_RSA2                         0x00000204L
-#define DREG_REGID_RSA3                         0x00000205L
-#define DREG_REGID_RSI0_LOW                     0x00000206L
-#define DREG_REGID_RSI0_HIGH                    0x00000207L
-#define DREG_REGID_RSI1                         0x00000208L
-#define DREG_REGID_RSI2                         0x00000209L
-#define DREG_REGID_SAGUSTATUS                   0x0000020AL
-#define DREG_REGID_RSCONFIG01_LOW               0x0000020BL
-#define DREG_REGID_RSCONFIG01_HIGH              0x0000020CL
-#define DREG_REGID_RSCONFIG23_LOW               0x0000020DL
-#define DREG_REGID_RSCONFIG23_HIGH              0x0000020EL
-#define DREG_REGID_RSDMA01E                     0x0000020FL
-#define DREG_REGID_RSDMA23E                     0x00000210L
-#define DREG_REGID_RSD0_LOW                     0x00000211L
-#define DREG_REGID_RSD0_HIGH                    0x00000212L
-#define DREG_REGID_RSD1_LOW                     0x00000213L
-#define DREG_REGID_RSD1_HIGH                    0x00000214L
-#define DREG_REGID_RSD2_LOW                     0x00000215L
-#define DREG_REGID_RSD2_HIGH                    0x00000216L
-#define DREG_REGID_RSD3_LOW                     0x00000217L
-#define DREG_REGID_RSD3_HIGH                    0x00000218L
-#define DREG_REGID_SRAR_HIGH                    0x0000021AL
-#define DREG_REGID_SRAR_LOW                     0x0000021BL
-#define DREG_REGID_DMA_STATE                    0x0000021CL
-#define DREG_REGID_CURRENT_DMA_STREAM           0x0000021DL
-#define DREG_REGID_NEXT_DMA_STREAM              0x0000021EL
-#define DREG_REGID_CPU_STATUS                   0x00000300L
-#define DREG_REGID_MAC_MODE                     0x00000301L
-#define DREG_REGID_STACK_AND_REPEAT             0x00000302L
-#define DREG_REGID_INDEX0                       0x00000304L
-#define DREG_REGID_INDEX1                       0x00000305L
-#define DREG_REGID_DMA_STATE_0_3                0x00000400L
-#define DREG_REGID_DMA_STATE_4_7                0x00000404L
-#define DREG_REGID_DMA_STATE_8_11               0x00000408L
-#define DREG_REGID_DMA_STATE_12_15              0x0000040CL
-#define DREG_REGID_DMA_STATE_16_19              0x00000410L
-#define DREG_REGID_DMA_STATE_20_23              0x00000414L
-#define DREG_REGID_DMA_STATE_24_27              0x00000418L
-#define DREG_REGID_DMA_STATE_28_31              0x0000041CL
-#define DREG_REGID_DMA_STATE_32_35              0x00000420L
-#define DREG_REGID_DMA_STATE_36_39              0x00000424L
-#define DREG_REGID_DMA_STATE_40_43              0x00000428L
-#define DREG_REGID_DMA_STATE_44_47              0x0000042CL
-#define DREG_REGID_DMA_STATE_48_51              0x00000430L
-#define DREG_REGID_DMA_STATE_52_55              0x00000434L
-#define DREG_REGID_DMA_STATE_56_59              0x00000438L
-#define DREG_REGID_DMA_STATE_60_63              0x0000043CL
-#define DREG_REGID_DMA_STATE_64_67              0x00000440L
-#define DREG_REGID_DMA_STATE_68_71              0x00000444L
-#define DREG_REGID_DMA_STATE_72_75              0x00000448L
-#define DREG_REGID_DMA_STATE_76_79              0x0000044CL
-#define DREG_REGID_DMA_STATE_80_83              0x00000450L
-#define DREG_REGID_DMA_STATE_84_87              0x00000454L
-#define DREG_REGID_DMA_STATE_88_91              0x00000458L
-#define DREG_REGID_DMA_STATE_92_95              0x0000045CL
-#define DREG_REGID_TRAP_SELECT                  0x00000500L
-#define DREG_REGID_TRAP_WRITE_0                 0x00000500L
-#define DREG_REGID_TRAP_WRITE_1                 0x00000501L
-#define DREG_REGID_TRAP_WRITE_2                 0x00000502L
-#define DREG_REGID_TRAP_WRITE_3                 0x00000503L
-#define DREG_REGID_TRAP_WRITE_4                 0x00000504L
-#define DREG_REGID_TRAP_WRITE_5                 0x00000505L
-#define DREG_REGID_TRAP_WRITE_6                 0x00000506L
-#define DREG_REGID_TRAP_WRITE_7                 0x00000507L
-#if !defined(NO_CS4612)
-#if !defined(NO_CS4615)
-#define DREG_REGID_TRAP_WRITE_8                 0x00000510L
-#define DREG_REGID_TRAP_WRITE_9                 0x00000511L
-#define DREG_REGID_TRAP_WRITE_10                0x00000512L
-#define DREG_REGID_TRAP_WRITE_11                0x00000513L
-#define DREG_REGID_TRAP_WRITE_12                0x00000514L
-#define DREG_REGID_TRAP_WRITE_13                0x00000515L
-#define DREG_REGID_TRAP_WRITE_14                0x00000516L
-#define DREG_REGID_TRAP_WRITE_15                0x00000517L
-#define DREG_REGID_TRAP_WRITE_16                0x00000518L
-#define DREG_REGID_TRAP_WRITE_17                0x00000519L
-#define DREG_REGID_TRAP_WRITE_18                0x0000051AL
-#define DREG_REGID_TRAP_WRITE_19                0x0000051BL
-#define DREG_REGID_TRAP_WRITE_20                0x0000051CL
-#define DREG_REGID_TRAP_WRITE_21                0x0000051DL
-#define DREG_REGID_TRAP_WRITE_22                0x0000051EL
-#define DREG_REGID_TRAP_WRITE_23                0x0000051FL
-#endif
-#endif
-#define DREG_REGID_MAC0_ACC0_LOW                0x00000600L
-#define DREG_REGID_MAC0_ACC1_LOW                0x00000601L
-#define DREG_REGID_MAC0_ACC2_LOW                0x00000602L
-#define DREG_REGID_MAC0_ACC3_LOW                0x00000603L
-#define DREG_REGID_MAC1_ACC0_LOW                0x00000604L
-#define DREG_REGID_MAC1_ACC1_LOW                0x00000605L
-#define DREG_REGID_MAC1_ACC2_LOW                0x00000606L
-#define DREG_REGID_MAC1_ACC3_LOW                0x00000607L
-#define DREG_REGID_MAC0_ACC0_MID                0x00000608L
-#define DREG_REGID_MAC0_ACC1_MID                0x00000609L
-#define DREG_REGID_MAC0_ACC2_MID                0x0000060AL
-#define DREG_REGID_MAC0_ACC3_MID                0x0000060BL
-#define DREG_REGID_MAC1_ACC0_MID                0x0000060CL
-#define DREG_REGID_MAC1_ACC1_MID                0x0000060DL
-#define DREG_REGID_MAC1_ACC2_MID                0x0000060EL
-#define DREG_REGID_MAC1_ACC3_MID                0x0000060FL
-#define DREG_REGID_MAC0_ACC0_HIGH               0x00000610L
-#define DREG_REGID_MAC0_ACC1_HIGH               0x00000611L
-#define DREG_REGID_MAC0_ACC2_HIGH               0x00000612L
-#define DREG_REGID_MAC0_ACC3_HIGH               0x00000613L
-#define DREG_REGID_MAC1_ACC0_HIGH               0x00000614L
-#define DREG_REGID_MAC1_ACC1_HIGH               0x00000615L
-#define DREG_REGID_MAC1_ACC2_HIGH               0x00000616L
-#define DREG_REGID_MAC1_ACC3_HIGH               0x00000617L
-#define DREG_REGID_RSHOUT_LOW                   0x00000620L
-#define DREG_REGID_RSHOUT_MID                   0x00000628L
-#define DREG_REGID_RSHOUT_HIGH                  0x00000630L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 S/PDIF Control register.
-//
-//****************************************************************************
-#define SPDIF_CONTROL_SPDIF_EN                 0x00008000L
-#define SPDIF_CONTROL_VAL                      0x00004000L
-#define SPDIF_CONTROL_COPY                     0x00000004L
-#define SPDIF_CONTROL_CC0                      0x00000010L
-#define SPDIF_CONTROL_CC1                      0x00000020L
-#define SPDIF_CONTROL_CC2                      0x00000040L
-#define SPDIF_CONTROL_CC3                      0x00000080L
-#define SPDIF_CONTROL_CC4                      0x00000100L
-#define SPDIF_CONTROL_CC5                      0x00000200L
-#define SPDIF_CONTROL_CC6                      0x00000400L
-#define SPDIF_CONTROL_L                        0x00000800L
-
-#endif // _H_HWDEFS
diff -urN linux-2.4.2-pre1/drivers/sound/cs46xx.c linux/drivers/sound/cs46xx.c
--- linux-2.4.2-pre1/drivers/sound/cs46xx.c	Mon Jan  1 11:24:54 2001
+++ linux/drivers/sound/cs46xx.c	Mon Dec  3 22:27:48 2001
@@ -139,19 +139,18 @@
 
 #if CSDEBUG
 static unsigned long cs_debuglevel=1;			/* levels range from 1-9 */
+MODULE_PARM(cs_debuglevel, "i");
 static unsigned long cs_debugmask=CS_INIT | CS_ERROR;	/* use CS_DBGOUT with various mask values */
+MODULE_PARM(cs_debugmask, "i");
 #endif
 #define DMABUF_DEFAULTORDER 3
 static unsigned long defaultorder=DMABUF_DEFAULTORDER;
-#if MODULE
 MODULE_PARM(defaultorder, "i");
-MODULE_PARM(cs_debuglevel, "i");
-MODULE_PARM(cs_debugmask, "i");
-#endif
-
-static int external_amp = 0;
-static int thinkpad = 0;
 
+static int external_amp;
+MODULE_PARM(external_amp, "i");
+static int thinkpad;
+MODULE_PARM(thinkpad, "i");
 
 /* An instance of the 4610 channel */
 
@@ -312,7 +311,7 @@
 	} midi;
 };
 
-static struct cs_card *devs = NULL;
+static struct cs_card *devs;
 
 static int cs_open_mixdev(struct inode *inode, struct file *file);
 static int cs_release_mixdev(struct inode *inode, struct file *file);
@@ -320,7 +319,7 @@
 				unsigned long arg);
 static loff_t cs_llseek(struct file *file, loff_t offset, int origin);
 
-extern __inline__ unsigned ld2(unsigned int x)
+static inline unsigned ld2(unsigned int x)
 {
 	unsigned r = 0;
 	
@@ -905,7 +904,7 @@
 /* get current playback/recording dma buffer pointer (byte offset from LBA),
    called with spinlock held! */
    
-extern __inline__ unsigned cs_get_dma_addr(struct cs_state *state)
+static inline unsigned cs_get_dma_addr(struct cs_state *state)
 {
 	struct dmabuf *dmabuf = &state->dmabuf;
 	u32 offset;
@@ -950,7 +949,7 @@
 }
 	
 /* Stop recording (lock held) */
-extern __inline__ void __stop_adc(struct cs_state *state)
+static inline void __stop_adc(struct cs_state *state)
 {
 	struct dmabuf *dmabuf = &state->dmabuf;
 	struct cs_card *card = state->card;
@@ -999,7 +998,7 @@
 }
 
 /* stop playback (lock held) */
-extern __inline__ void __stop_dac(struct cs_state *state)
+static inline void __stop_dac(struct cs_state *state)
 {
 	struct dmabuf *dmabuf = &state->dmabuf;
 	struct cs_card *card = state->card;
@@ -1766,6 +1765,7 @@
  *   Midi file operations struct.
  */
 static /*const*/ struct file_operations cs_midi_fops = {
+	owner:		THIS_MODULE,
         llseek:		cs_llseek,
         read:		cs_midi_read,
         write:		cs_midi_write,
@@ -3144,6 +3144,7 @@
 }
 
 static /*const*/ struct file_operations cs461x_fops = {
+	owner:		THIS_MODULE,
 	llseek:		cs_llseek,
 	read:		cs_read,
 	write:		cs_write,
@@ -3352,7 +3353,7 @@
 
 static int cs_open_mixdev(struct inode *inode, struct file *file)
 {
-	int i;
+	int i=0;
 	int minor = MINOR(inode->i_rdev);
 	struct cs_card *card = devs;
 
@@ -3437,6 +3438,7 @@
 }
 
 static /*const*/ struct file_operations cs_mixer_fops = {
+	owner:		THIS_MODULE,
 	llseek:		cs_llseek,
 	ioctl:		cs_ioctl_mixdev,
 	open:		cs_open_mixdev,
@@ -4233,16 +4235,18 @@
 MODULE_AUTHOR("Alan Cox <alan@redhat.com>, Jaroslav Kysela, <audio@crystal.cirrus.com>");
 MODULE_DESCRIPTION("Crystal SoundFusion Audio Support");
 
-int __init cs_probe(void)
+static char banner[] __initdata = KERN_INFO "Crystal 4280/461x + AC97 Audio, version " DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n";
+static char fndmsg[] __initdata = KERN_INFO "cs461x: Found %d audio device(s).\n";
+
+static int __init cs_init_driver(void)
 {
 	struct pci_dev *pcidev = NULL;
 	int foundone=0;
-	
+
 	if (!pci_present())   /* No PCI bus in this machine! */
 		return -ENODEV;
-		
-	printk(KERN_INFO "Crystal 4280/461x + AC97 Audio, version "
-	       DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
+
+	printk(banner);
 
 	while( (pcidev = pci_find_device(PCI_VENDOR_ID_CIRRUS, 0x6001 , pcidev))!=NULL ) {
 		if (cs_install(pcidev)==0)
@@ -4257,19 +4261,11 @@
 			foundone++;
 	}
 
-	printk(KERN_INFO "cs461x: Found %d audio device(s).\n",
-		foundone);
-	return foundone;
-}
-
-int __init init_module(void)
-{
-	if(cs_probe()==0)
-		printk(KERN_ERR "cs461x: No devices found.\n");
-	return 0;
+	printk(fndmsg, foundone);
+	return foundone ? 0 : -ENODEV;
 }
 
-void __exit cleanup_module (void)
+static void __exit cs_exit_driver(void)
 {
 	struct cs_card *next;
 #ifdef CS46XX_PM
@@ -4283,5 +4279,5 @@
 	}
 }
 
-MODULE_PARM(external_amp, "i");
-MODULE_PARM(thinkpad, "i");
+module_init(cs_init_driver);
+module_exit(cs_exit_driver);
diff -urN linux-2.4.2-pre1/drivers/sound/dev_table.h linux/drivers/sound/dev_table.h
--- linux-2.4.2-pre1/drivers/sound/dev_table.h	Fri Aug 11 08:26:43 2000
+++ linux/drivers/sound/dev_table.h	Mon Dec  3 22:27:48 2001
@@ -150,6 +150,7 @@
 typedef struct coproc_operations 
 {
 	char name[64];
+	struct module *owner;
 	int (*open) (void *devc, int sub_device);
 	void (*close) (void *devc, int sub_device);
 	int (*ioctl) (void *devc, unsigned int cmd, caddr_t arg, int local);
diff -urN linux-2.4.2-pre1/drivers/sound/emu10k1/ecard.h linux/drivers/sound/emu10k1/ecard.h
--- linux-2.4.2-pre1/drivers/sound/emu10k1/ecard.h	Mon Dec 11 13:02:22 2000
+++ linux/drivers/sound/emu10k1/ecard.h	Mon Dec  3 22:27:48 2001
@@ -99,7 +99,7 @@
 #define HC_EA 0x01L
 
 /* ECARD state structure.  This structure maintains the state
- * for various portions of the the ECARD's onboard hardware.
+ * for various portions of the ECARD's onboard hardware.
  */
 struct ecard_state {
 	u32 control_bits;
diff -urN linux-2.4.2-pre1/drivers/sound/emu10k1/midi.c linux/drivers/sound/emu10k1/midi.c
--- linux-2.4.2-pre1/drivers/sound/emu10k1/midi.c	Thu Sep 21 13:25:09 2000
+++ linux/drivers/sound/emu10k1/midi.c	Mon Dec  3 22:27:48 2001
@@ -85,7 +85,7 @@
 static int emu10k1_midi_open(struct inode *inode, struct file *file)
 {
 	int minor = MINOR(inode->i_rdev);
-	struct emu10k1_card *card;
+	struct emu10k1_card *card=NULL;
 	struct emu10k1_mididevice *midi_dev;
 	struct list_head *entry;
 
@@ -423,6 +423,7 @@
 		break;
 
 	default:		/* Unknown message */
+		spin_unlock_irqrestore(&midi_spinlock, flags);
 		return -1;
 	}
 
diff -urN linux-2.4.2-pre1/drivers/sound/maestro3.c linux/drivers/sound/maestro3.c
--- linux-2.4.2-pre1/drivers/sound/maestro3.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/sound/maestro3.c	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,2947 @@
+/*****************************************************************************
+ *
+ *      ESS Maestro3/Allegro driver for Linux 2.4.x
+ *
+ *      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.
+ *
+ *    (c) Copyright 2000 Zach Brown <zab@zabbo.net>
+ *
+ * I need to thank many people for helping make this driver happen.  
+ * As always, Eric Brombaugh was a hacking machine and killed many bugs
+ * that I was too dumb to notice.  Howard Kim at ESS provided reference boards 
+ * and as much docs as he could.  Todd and Mick at Dell tested snapshots on 
+ * an army of laptops.  msw and deviant at Red Hat also humoured me by hanging
+ * their laptops every few hours in the name of science.
+ * 
+ * Shouts go out to Mike "DJ XPCom" Ang.
+ *
+ * History
+ *  v1.20 - Jan 30 2001 - Zach Brown <zab@zabbo.net>
+ *   get rid of pm callback and use pci_dev suspend/resume instead
+ *   m3_probe cleanups, including pm oops think-o
+ *  v1.10 - Jan 6 2001 - Zach Brown <zab@zabbo.net>
+ *   revert to lame remap_page_range mmap() just to make it work
+ *   record mmap fixed.
+ *   fix up incredibly broken open/release resource management
+ *   duh.  fix record format setting.
+ *   add SMP locking and cleanup formatting here and there
+ *  v1.00 - Dec 16 2000 - Zach Brown <zab@zabbo.net>
+ *   port to sexy 2.4 interfaces
+ *   properly align instance allocations so recording works
+ *   clean up function namespace a little :/
+ *   update PCI IDs based on mail from ESS
+ *   arbitrarily bump version number to show its 2.4 now, 
+ *      2.2 will stay 0., oss_audio port gets 2.
+ *  v0.03 - Nov 05 2000 - Zach Brown <zab@zabbo.net>
+ *   disable recording but allow dsp to be opened read 
+ *   pull out most silly compat defines
+ *  v0.02 - Nov 04 2000 - Zach Brown <zab@zabbo.net>
+ *   changed clocking setup for m3, slowdown fixed.
+ *   codec reset is hopefully reliable now
+ *   rudimentary apm/power management makes suspend/resume work
+ *  v0.01 - Oct 31 2000 - Zach Brown <zab@zabbo.net>
+ *   first release
+ *  v0.00 - Sep 09 2000 - Zach Brown <zab@zabbo.net>
+ *   first pass derivation from maestro.c
+ *
+ * TODO
+ *  in/out allocated contiguously so fullduplex mmap will work?
+ *  no beep on init (mute)
+ *  resetup msrc data memory if freq changes?
+ *
+ *  --
+ *
+ *  Allow me to ramble a bit about the m3 architecture.  The core of the
+ *  chip is the 'assp', the custom ESS dsp that runs the show.  It has
+ *  a small amount of code and data ram.  ESS drops binary dsp code images
+ *  on our heads, but we don't get to see specs on the dsp.  
+ *
+ *  The constant piece of code on the dsp is the 'kernel'.  It also has a 
+ *  chunk of the dsp memory that is statically set aside for its control
+ *  info.  This is the KDATA defines in maestro3.h.  Part of its core
+ *  data is a list of code addresses that point to the pieces of DSP code
+ *  that it should walk through in its loop.  These other pieces of code
+ *  do the real work.  The kernel presumably jumps into each of them in turn.
+ *  These code images tend to have their own data area, and one can have
+ *  multiple data areas representing different states for each of the 'client
+ *  instance' code portions.  There is generaly a list in the kernel data
+ *  that points to the data instances for a given piece of code.
+ *
+ *  We've only been given the binary image for the 'minisrc', mini sample 
+ *  rate converter.  This is rather annoying because it limits the work
+ *  we can do on the dsp, but it also greatly simplifies the job of managing
+ *  dsp data memory for the code and data for our playing streams :).  We
+ *  statically allocate the minisrc code into a region we 'know' to be free
+ *  based on the map of the binary kernel image we're loading.  We also 
+ *  statically allocate the data areas for the maximum number of pcm streams
+ *  we can be dealing with.  This max is set by the length of the static list
+ *  in the kernel data that records the number of minisrc data regions we
+ *  can have.  Thats right, all software dsp mixing with static code list
+ *  limits.  Rock.
+ *
+ *  How sound goes in and out is still a relative mystery.  It appears
+ *  that the dsp has the ability to get input and output through various
+ *  'connections'.  To do IO from or to a connection, you put the address
+ *  of the minisrc client area in the static kernel data lists for that 
+ *  input or output.  so for pcm -> dsp -> mixer, we put the minisrc data
+ *  instance in the DMA list and also in the list for the mixer.  I guess
+ *  it Just Knows which is in/out, and we give some dma control info that
+ *  helps.  There are all sorts of cool inputs/outputs that it seems we can't
+ *  use without dsp code images that know how to use them.
+ *
+ *  So at init time we preload all the memory allocation stuff and set some
+ *  system wide parameters.  When we really get a sound to play we build
+ *  up its minisrc header (stream parameters, buffer addresses, input/output
+ *  settings).  Then we throw its header on the various lists.  We also
+ *  tickle some KDATA settings that ask the assp to raise clock interrupts
+ *  and do some amount of software mixing before handing data to the ac97.
+ *
+ *  Sorry for the vague details.  Feel free to ask Eric or myself if you
+ *  happen to be trying to use this driver elsewhere.  Please accept my
+ *  apologies for the quality of the OSS support code, its passed through
+ *  too many hands now and desperately wants to be rethought.
+ */
+
+/*****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/sound.h>
+#include <linux/malloc.h>
+#include <linux/soundcard.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/reboot.h>
+#include <asm/uaccess.h>
+#include <asm/hardirq.h>
+#include <linux/spinlock.h>
+#include <linux/ac97_codec.h>
+
+ /*
+  * for crizappy mmap()
+  */
+#include <linux/wrapper.h>
+
+#include "maestro3.h"
+
+#define M_DEBUG 1
+
+#define DRIVER_VERSION      "1.20"
+#define M3_MODULE_NAME      "maestro3"
+#define PFX                 M3_MODULE_NAME ": "
+
+#define M3_STATE_MAGIC      0x734d724d
+#define M3_CARD_MAGIC       0x646e6f50
+
+#define ESS_FMT_STEREO      0x01
+#define ESS_FMT_16BIT       0x02
+#define ESS_FMT_MASK        0x03
+#define ESS_DAC_SHIFT       0   
+#define ESS_ADC_SHIFT       4
+
+#define DAC_RUNNING         1
+#define ADC_RUNNING         2
+
+#define SND_DEV_DSP16       5 
+   
+#ifdef M_DEBUG
+static int debug=0;
+#define DPMOD   1   /* per module load */
+#define DPSTR   2   /* per 'stream' */
+#define DPSYS   3   /* per syscall */
+#define DPCRAP  4   /* stuff the user shouldn't see unless they're really debuggin */
+#define DPINT   5   /* per interrupt, LOTS */
+#define DPRINTK(DP, args...) {if (debug >= (DP)) printk(KERN_DEBUG PFX args);}
+#else
+#define DPRINTK(x)
+#endif
+
+struct m3_list {
+    int curlen;
+    u16 mem_addr;
+    int max;
+};
+
+int external_amp = 1;
+
+struct m3_state {
+    unsigned int magic;
+    struct m3_card *card;
+    unsigned char fmt, enable;
+
+    int index;
+
+    /* this locks around the oss state in the driver */
+    spinlock_t lock;
+
+    struct semaphore open_sem;
+    wait_queue_head_t open_wait;
+    mode_t open_mode;
+
+    int dev_audio;
+
+    struct assp_instance {
+        u16 code, data;
+    } dac_inst, adc_inst;
+
+    /* should be in dmabuf */
+    unsigned int rateadc, ratedac;
+
+    struct dmabuf {
+        void *rawbuf;
+        unsigned buforder;
+        unsigned numfrag;
+        unsigned fragshift;
+        unsigned hwptr, swptr;
+        unsigned total_bytes;
+        int count;
+        unsigned error; /* over/underrun */
+        wait_queue_head_t wait;
+        /* redundant, but makes calculations easier */
+        unsigned fragsize;
+        unsigned dmasize;
+        unsigned fragsamples;
+        /* OSS stuff */
+        unsigned mapped:1;
+        unsigned ready:1;    
+        unsigned endcleared:1;
+        unsigned ossfragshift;
+        int ossmaxfrags;
+        unsigned subdivision;
+        /* new in m3 */
+        int mixer_index, dma_index, msrc_index, adc1_index;
+        int in_lists;
+        /* 2.4.. */
+        dma_addr_t handle;
+
+    } dma_dac, dma_adc;
+};
+    
+struct m3_card {
+    unsigned int magic;
+
+    struct m3_card *next;
+
+    struct ac97_codec *ac97;
+    spinlock_t ac97_lock;
+
+    int card_type;
+
+#define NR_DSPS 1
+#define MAX_DSPS NR_DSPS
+    struct m3_state channels[MAX_DSPS];
+
+    /* this locks around the physical registers on the card */
+    spinlock_t lock;
+
+    /* hardware resources */
+    struct pci_dev *pcidev;
+    u32 iobase;
+    u32 irq;
+
+    int dacs_active;
+
+    int timer_users;
+
+    struct m3_list  msrc_list,
+                    mixer_list,
+                    adc1_list,
+                    dma_list;
+
+    /* for storing reset state..*/
+    u8 reset_state;
+
+    u16 *suspend_mem;
+    int in_suspend;
+    wait_queue_head_t suspend_queue;
+};
+
+/*
+ * an arbitrary volume we set the internal
+ * volume settings to so that the ac97 volume
+ * range is a little less insane.  0x7fff is 
+ * max.
+ */
+#define ARB_VOLUME ( 0x6800 )
+
+static const unsigned sample_shift[] = { 0, 1, 1, 2 };
+
+enum {
+    ESS_ALLEGRO,
+    ESS_MAESTRO3,
+    /*
+     * a maestro3 with 'hardware strapping', only
+     * found inside ESS?
+     */
+    ESS_MAESTRO3HW,
+};
+
+static char *card_names[] = {
+    [ESS_ALLEGRO] = "Allegro",
+    [ESS_MAESTRO3] = "Maestro3(i)",
+    [ESS_MAESTRO3HW] = "Maestro3(i)hw"
+};
+
+#ifndef PCI_VENDOR_ESS
+#define PCI_VENDOR_ESS      0x125D
+#endif
+
+#define M3_DEVICE(DEV, TYPE)                \
+{                                           \
+vendor: PCI_VENDOR_ESS,                     \
+device: DEV,                                \
+subvendor: PCI_ANY_ID,                      \
+subdevice: PCI_ANY_ID,                      \
+class:  PCI_CLASS_MULTIMEDIA_AUDIO << 8,    \
+class_mask: 0xffff << 8,                    \
+driver_data: TYPE,                          \
+}
+
+static struct pci_device_id m3_id_table[] __initdata = {
+    M3_DEVICE(0x1988, ESS_ALLEGRO),
+    M3_DEVICE(0x1998, ESS_MAESTRO3),
+    M3_DEVICE(0x199a, ESS_MAESTRO3HW),
+    {0,}
+};
+
+MODULE_DEVICE_TABLE (pci, m3_id_table);
+
+static unsigned 
+ld2(unsigned int x)
+{
+    unsigned r = 0;
+    
+    if (x >= 0x10000) {
+        x >>= 16;
+        r += 16;
+    }
+    if (x >= 0x100) {
+        x >>= 8;
+        r += 8;
+    }
+    if (x >= 0x10) {
+        x >>= 4;
+        r += 4;
+    }
+    if (x >= 4) {
+        x >>= 2;
+        r += 2;
+    }
+    if (x >= 2)
+        r++;
+    return r;
+}
+
+static struct m3_card *devs = NULL;
+
+/*
+ * I'm not very good at laying out functions in a file :)
+ */
+static int m3_notifier(struct notifier_block *nb, unsigned long event, void *buf);
+static void m3_suspend(struct pci_dev *pci_dev);
+static void check_suspend(struct m3_card *card);
+
+struct notifier_block m3_reboot_nb = {m3_notifier, NULL, 0};
+
+static void m3_outw(struct m3_card *card,
+        u16 value, unsigned long reg)
+{
+    check_suspend(card);
+    outw(value, card->iobase + reg);
+}
+
+static u16 m3_inw(struct m3_card *card, unsigned long reg)
+{
+    check_suspend(card);
+    return inw(card->iobase + reg);
+}
+static void m3_outb(struct m3_card *card, 
+        u8 value, unsigned long reg)
+{
+    check_suspend(card);
+    outb(value, card->iobase + reg);
+}
+static u8 m3_inb(struct m3_card *card, unsigned long reg)
+{
+    check_suspend(card);
+    return inb(card->iobase + reg);
+}
+
+/*
+ * access 16bit words to the code or data regions of the dsp's memory.
+ * index addresses 16bit words.
+ */
+static u16 __m3_assp_read(struct m3_card *card, u16 region, u16 index)
+{
+    m3_outw(card, region & MEMTYPE_MASK, DSP_PORT_MEMORY_TYPE);
+    m3_outw(card, index, DSP_PORT_MEMORY_INDEX);
+    return m3_inw(card, DSP_PORT_MEMORY_DATA);
+}
+static u16 m3_assp_read(struct m3_card *card, u16 region, u16 index)
+{
+    unsigned long flags;
+    u16 ret;
+
+    spin_lock_irqsave(&(card->lock), flags);
+    ret = __m3_assp_read(card, region, index);
+    spin_unlock_irqrestore(&(card->lock), flags);
+
+    return ret;
+}
+
+static void __m3_assp_write(struct m3_card *card, 
+        u16 region, u16 index, u16 data)
+{
+    m3_outw(card, region & MEMTYPE_MASK, DSP_PORT_MEMORY_TYPE);
+    m3_outw(card, index, DSP_PORT_MEMORY_INDEX);
+    m3_outw(card, data, DSP_PORT_MEMORY_DATA);
+}
+static void m3_assp_write(struct m3_card *card, 
+        u16 region, u16 index, u16 data)
+{
+    unsigned long flags;
+
+    spin_lock_irqsave(&(card->lock), flags);
+    __m3_assp_write(card, region, index, data);
+    spin_unlock_irqrestore(&(card->lock), flags);
+}
+
+static void m3_assp_halt(struct m3_card *card)
+{
+    card->reset_state = m3_inb(card, DSP_PORT_CONTROL_REG_B) & ~REGB_STOP_CLOCK;
+    mdelay(10);
+    m3_outb(card, card->reset_state & ~REGB_ENABLE_RESET, DSP_PORT_CONTROL_REG_B);
+}
+
+static void m3_assp_continue(struct m3_card *card)
+{
+    m3_outb(card, card->reset_state | REGB_ENABLE_RESET, DSP_PORT_CONTROL_REG_B);
+}
+
+/*
+ * This makes me sad. the maestro3 has lists
+ * internally that must be packed.. 0 terminates,
+ * apparently, or maybe all unused entries have
+ * to be 0, the lists have static lengths set
+ * by the binary code images.
+ */
+
+static int m3_add_list(struct m3_card *card,
+        struct m3_list *list, u16 val)
+{
+    DPRINTK(DPSTR, "adding val 0x%x to list 0x%p at pos %d\n",
+            val, list, list->curlen);
+
+    m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
+            list->mem_addr + list->curlen,
+            val);
+
+    return list->curlen++;
+
+}
+
+static void m3_remove_list(struct m3_card *card,
+        struct m3_list *list, int index)
+{
+    u16  val;
+    int lastindex = list->curlen - 1;
+
+    DPRINTK(DPSTR, "removing ind %d from list 0x%p\n",
+            index, list);
+
+    if(index != lastindex) {
+        val = m3_assp_read(card, MEMTYPE_INTERNAL_DATA,
+                list->mem_addr + lastindex);
+        m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
+                list->mem_addr + index,
+                val);
+    }
+
+    m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
+            list->mem_addr + lastindex,
+            0);
+
+    list->curlen--;
+}
+
+static void set_fmt(struct m3_state *s, unsigned char mask, unsigned char data)
+{
+    int tmp;
+
+    s->fmt = (s->fmt & mask) | data;
+
+    tmp = (s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK;
+
+    /* write to 'mono' word */
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+            s->dac_inst.data + SRC3_DIRECTION_OFFSET + 1, 
+            (tmp & ESS_FMT_STEREO) ? 0 : 1);
+    /* write to '8bit' word */
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+            s->dac_inst.data + SRC3_DIRECTION_OFFSET + 2, 
+            (tmp & ESS_FMT_16BIT) ? 0 : 1);
+
+    tmp = (s->fmt >> ESS_ADC_SHIFT) & ESS_FMT_MASK;
+
+    /* write to 'mono' word */
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+            s->adc_inst.data + SRC3_DIRECTION_OFFSET + 1, 
+            (tmp & ESS_FMT_STEREO) ? 0 : 1);
+    /* write to '8bit' word */
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+            s->adc_inst.data + SRC3_DIRECTION_OFFSET + 2, 
+            (tmp & ESS_FMT_16BIT) ? 0 : 1);
+}
+
+static void set_dac_rate(struct m3_state *s, unsigned int rate)
+{
+    u32 freq;
+
+    if (rate > 48000)
+        rate = 48000;
+    if (rate < 8000)
+        rate = 8000;
+
+    s->ratedac = rate;
+
+    freq = ((rate << 15) + 24000 ) / 48000;
+    if(freq) 
+        freq--;
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+            s->dac_inst.data + CDATA_FREQUENCY,
+            freq);
+}
+
+static void set_adc_rate(struct m3_state *s, unsigned int rate)
+{
+    u32 freq;
+
+    if (rate > 48000)
+        rate = 48000;
+    if (rate < 8000)
+        rate = 8000;
+
+    s->rateadc = rate;
+
+    freq = ((rate << 15) + 24000 ) / 48000;
+    if(freq) 
+        freq--;
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+            s->adc_inst.data + CDATA_FREQUENCY,
+            freq);
+}
+
+static void inc_timer_users(struct m3_card *card)
+{
+    unsigned long flags;
+
+    spin_lock_irqsave(&card->lock, flags);
+    
+    card->timer_users++;
+    DPRINTK(DPSYS, "inc timer users now %d\n",
+            card->timer_users);
+    if(card->timer_users != 1) 
+        goto out;
+
+    __m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
+        KDATA_TIMER_COUNT_RELOAD,
+         240 ) ;
+
+    __m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
+        KDATA_TIMER_COUNT_CURRENT,
+         240 ) ;
+
+    m3_outw(card,  
+            m3_inw(card, HOST_INT_CTRL) | CLKRUN_GEN_ENABLE,
+            HOST_INT_CTRL);
+out:
+    spin_unlock_irqrestore(&card->lock, flags);
+}
+
+static void dec_timer_users(struct m3_card *card)
+{
+    unsigned long flags;
+
+    spin_lock_irqsave(&card->lock, flags);
+
+    card->timer_users--;
+    DPRINTK(DPSYS, "dec timer users now %d\n",
+            card->timer_users);
+    if(card->timer_users > 0 ) 
+        goto out;
+
+    __m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
+        KDATA_TIMER_COUNT_RELOAD,
+         0 ) ;
+
+    __m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
+        KDATA_TIMER_COUNT_CURRENT,
+         0 ) ;
+
+    m3_outw(card,  m3_inw(card, HOST_INT_CTRL) & ~CLKRUN_GEN_ENABLE,
+            HOST_INT_CTRL);
+out:
+    spin_unlock_irqrestore(&card->lock, flags);
+}
+
+/*
+ * {start,stop}_{adc,dac} should be called
+ * while holding the 'state' lock and they
+ * will try to grab the 'card' lock..
+ */
+static void stop_adc(struct m3_state *s)
+{
+    if (! (s->enable & ADC_RUNNING)) 
+        return;
+
+    s->enable &= ~ADC_RUNNING;
+    dec_timer_users(s->card);
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+            s->adc_inst.data + CDATA_INSTANCE_READY, 0);
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+            KDATA_ADC1_REQUEST, 0);
+}    
+
+static void stop_dac(struct m3_state *s)
+{
+    if (! (s->enable & DAC_RUNNING)) 
+        return;
+
+    DPRINTK(DPSYS, "stop_dac()\n");
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+            s->dac_inst.data + CDATA_INSTANCE_READY, 0);
+
+    s->enable &= ~DAC_RUNNING;
+    s->card->dacs_active--;
+    dec_timer_users(s->card);
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+            KDATA_MIXER_TASK_NUMBER, 
+            s->card->dacs_active ) ;
+}    
+
+static void start_dac(struct m3_state *s)
+{
+    if( (!s->dma_dac.mapped && s->dma_dac.count < 1) ||
+            !s->dma_dac.ready ||
+            (s->enable & DAC_RUNNING)) 
+        return;
+
+    DPRINTK(DPSYS, "start_dac()\n");
+
+    s->enable |= DAC_RUNNING;
+    s->card->dacs_active++;
+    inc_timer_users(s->card);
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+            s->dac_inst.data + CDATA_INSTANCE_READY, 1);
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+            KDATA_MIXER_TASK_NUMBER, 
+            s->card->dacs_active ) ;
+}    
+
+static void start_adc(struct m3_state *s)
+{
+    if ((! s->dma_adc.mapped &&
+                s->dma_adc.count >= (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize)) 
+        || !s->dma_adc.ready 
+        || (s->enable & ADC_RUNNING) ) 
+            return;
+
+    DPRINTK(DPSYS, "start_adc()\n");
+
+    s->enable |= ADC_RUNNING;
+    inc_timer_users(s->card);
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+            KDATA_ADC1_REQUEST, 1);
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+            s->adc_inst.data + CDATA_INSTANCE_READY, 1);
+}    
+
+static struct play_vals {
+    u16 addr, val;
+} pv[] = {
+    {CDATA_LEFT_VOLUME, ARB_VOLUME},
+    {CDATA_RIGHT_VOLUME, ARB_VOLUME},
+    {SRC3_DIRECTION_OFFSET, 0} ,
+    /* +1, +2 are stereo/16 bit */
+    {SRC3_DIRECTION_OFFSET + 3, 0x0000}, /* fraction? */
+    {SRC3_DIRECTION_OFFSET + 4, 0}, /* first l */
+    {SRC3_DIRECTION_OFFSET + 5, 0}, /* first r */
+    {SRC3_DIRECTION_OFFSET + 6, 0}, /* second l */
+    {SRC3_DIRECTION_OFFSET + 7, 0}, /* second r */
+    {SRC3_DIRECTION_OFFSET + 8, 0}, /* delta l */
+    {SRC3_DIRECTION_OFFSET + 9, 0}, /* delta r */
+    {SRC3_DIRECTION_OFFSET + 10, 0x8000}, /* round */
+    {SRC3_DIRECTION_OFFSET + 11, 0xFF00}, /* higher bute mark */
+    {SRC3_DIRECTION_OFFSET + 13, 0}, /* temp0 */
+    {SRC3_DIRECTION_OFFSET + 14, 0}, /* c fraction */
+    {SRC3_DIRECTION_OFFSET + 15, 0}, /* counter */
+    {SRC3_DIRECTION_OFFSET + 16, 8}, /* numin */
+    {SRC3_DIRECTION_OFFSET + 17, 50*2}, /* numout */
+    {SRC3_DIRECTION_OFFSET + 18, MINISRC_BIQUAD_STAGE - 1}, /* numstage */
+    {SRC3_DIRECTION_OFFSET + 20, 0}, /* filtertap */
+    {SRC3_DIRECTION_OFFSET + 21, 0} /* booster */
+};
+
+
+/* the mode passed should be already shifted and masked */
+static void m3_play_setup(struct m3_state *s, int mode, u32 rate, void *buffer, int size)
+{
+    int dsp_in_size = MINISRC_IN_BUFFER_SIZE - (0x20 * 2);
+    int dsp_out_size = MINISRC_OUT_BUFFER_SIZE - (0x20 * 2);
+    int dsp_in_buffer = s->dac_inst.data + (MINISRC_TMP_BUFFER_SIZE / 2);
+    int dsp_out_buffer = dsp_in_buffer + (dsp_in_size / 2) + 1;
+    struct dmabuf *db = &s->dma_dac;
+    int i;
+
+    DPRINTK(DPSTR, "mode=%d rate=%d buf=%p len=%d.\n",
+        mode, rate, buffer, size);
+
+#define LO(x) ((x) & 0xffff)
+#define HI(x) LO((x) >> 16)
+
+    /* host dma buffer pointers */
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->dac_inst.data + CDATA_HOST_SRC_ADDRL,
+        LO(virt_to_bus(buffer)));
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->dac_inst.data + CDATA_HOST_SRC_ADDRH,
+        HI(virt_to_bus(buffer)));
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->dac_inst.data + CDATA_HOST_SRC_END_PLUS_1L,
+        LO(virt_to_bus(buffer) + size));
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->dac_inst.data + CDATA_HOST_SRC_END_PLUS_1H,
+        HI(virt_to_bus(buffer) + size));
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->dac_inst.data + CDATA_HOST_SRC_CURRENTL,
+        LO(virt_to_bus(buffer)));
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->dac_inst.data + CDATA_HOST_SRC_CURRENTH,
+        HI(virt_to_bus(buffer)));
+#undef LO
+#undef HI
+
+    /* dsp buffers */
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->dac_inst.data + CDATA_IN_BUF_BEGIN,
+        dsp_in_buffer);
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->dac_inst.data + CDATA_IN_BUF_END_PLUS_1,
+        dsp_in_buffer + (dsp_in_size / 2));
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->dac_inst.data + CDATA_IN_BUF_HEAD,
+        dsp_in_buffer);
+    
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->dac_inst.data + CDATA_IN_BUF_TAIL,
+        dsp_in_buffer);
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->dac_inst.data + CDATA_OUT_BUF_BEGIN,
+        dsp_out_buffer);
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->dac_inst.data + CDATA_OUT_BUF_END_PLUS_1,
+        dsp_out_buffer + (dsp_out_size / 2));
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->dac_inst.data + CDATA_OUT_BUF_HEAD,
+        dsp_out_buffer);
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->dac_inst.data + CDATA_OUT_BUF_TAIL,
+        dsp_out_buffer);
+
+    /*
+     * some per client initializers
+     */
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->dac_inst.data + SRC3_DIRECTION_OFFSET + 12,
+        s->dac_inst.data + 40 + 8);
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->dac_inst.data + SRC3_DIRECTION_OFFSET + 19,
+        s->dac_inst.code + MINISRC_COEF_LOC);
+
+    /* enable or disable low pass filter? */
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->dac_inst.data + SRC3_DIRECTION_OFFSET + 22,
+        s->ratedac > 45000 ? 0xff : 0 );
+    
+    /* tell it which way dma is going? */
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->dac_inst.data + CDATA_DMA_CONTROL,
+        DMACONTROL_AUTOREPEAT + DMAC_PAGE3_SELECTOR + DMAC_BLOCKF_SELECTOR);
+
+    /*
+     * set an armload of static initializers
+     */
+    for(i = 0 ; i < (sizeof(pv) / sizeof(pv[0])) ; i++) 
+        m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+            s->dac_inst.data + pv[i].addr, pv[i].val);
+
+    /* 
+     * put us in the lists if we're not already there
+     */
+
+    if(db->in_lists == 0) {
+
+        db->msrc_index = m3_add_list(s->card, &s->card->msrc_list, 
+                s->dac_inst.data >> DP_SHIFT_COUNT);
+
+        db->dma_index = m3_add_list(s->card, &s->card->dma_list, 
+                s->dac_inst.data >> DP_SHIFT_COUNT);
+
+        db->mixer_index = m3_add_list(s->card, &s->card->mixer_list, 
+                s->dac_inst.data >> DP_SHIFT_COUNT);
+
+        db->in_lists = 1;
+    }
+
+    set_dac_rate(s,rate);
+    start_dac(s);
+}
+
+/*
+ *    Native record driver 
+ */
+static struct rec_vals {
+    u16 addr, val;
+} rv[] = {
+    {CDATA_LEFT_VOLUME, ARB_VOLUME},
+    {CDATA_RIGHT_VOLUME, ARB_VOLUME},
+    {SRC3_DIRECTION_OFFSET, 1} ,
+    /* +1, +2 are stereo/16 bit */
+    {SRC3_DIRECTION_OFFSET + 3, 0x0000}, /* fraction? */
+    {SRC3_DIRECTION_OFFSET + 4, 0}, /* first l */
+    {SRC3_DIRECTION_OFFSET + 5, 0}, /* first r */
+    {SRC3_DIRECTION_OFFSET + 6, 0}, /* second l */
+    {SRC3_DIRECTION_OFFSET + 7, 0}, /* second r */
+    {SRC3_DIRECTION_OFFSET + 8, 0}, /* delta l */
+    {SRC3_DIRECTION_OFFSET + 9, 0}, /* delta r */
+    {SRC3_DIRECTION_OFFSET + 10, 0x8000}, /* round */
+    {SRC3_DIRECTION_OFFSET + 11, 0xFF00}, /* higher bute mark */
+    {SRC3_DIRECTION_OFFSET + 13, 0}, /* temp0 */
+    {SRC3_DIRECTION_OFFSET + 14, 0}, /* c fraction */
+    {SRC3_DIRECTION_OFFSET + 15, 0}, /* counter */
+    {SRC3_DIRECTION_OFFSET + 16, 50},/* numin */
+    {SRC3_DIRECTION_OFFSET + 17, 8}, /* numout */
+    {SRC3_DIRECTION_OFFSET + 18, 0}, /* numstage */
+    {SRC3_DIRECTION_OFFSET + 19, 0}, /* coef */
+    {SRC3_DIRECTION_OFFSET + 20, 0}, /* filtertap */
+    {SRC3_DIRECTION_OFFSET + 21, 0}, /* booster */
+    {SRC3_DIRECTION_OFFSET + 22, 0xff} /* skip lpf */
+};
+
+/* again, passed mode is alrady shifted/masked */
+static void m3_rec_setup(struct m3_state *s, int mode, u32 rate, void *buffer, int size)
+{
+    int dsp_in_size = MINISRC_IN_BUFFER_SIZE + (0x10 * 2);
+    int dsp_out_size = MINISRC_OUT_BUFFER_SIZE - (0x10 * 2);
+    int dsp_in_buffer = s->adc_inst.data + (MINISRC_TMP_BUFFER_SIZE / 2);
+    int dsp_out_buffer = dsp_in_buffer + (dsp_in_size / 2) + 1;
+    struct dmabuf *db = &s->dma_adc;
+    int i;
+
+    DPRINTK(DPSTR, "rec_setup mode=%d rate=%d buf=%p len=%d.\n",
+        mode, rate, buffer, size);
+
+#define LO(x) ((x) & 0xffff)
+#define HI(x) LO((x) >> 16)
+
+    /* host dma buffer pointers */
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->adc_inst.data + CDATA_HOST_SRC_ADDRL,
+        LO(virt_to_bus(buffer)));
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->adc_inst.data + CDATA_HOST_SRC_ADDRH,
+        HI(virt_to_bus(buffer)));
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->adc_inst.data + CDATA_HOST_SRC_END_PLUS_1L,
+        LO(virt_to_bus(buffer) + size));
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->adc_inst.data + CDATA_HOST_SRC_END_PLUS_1H,
+        HI(virt_to_bus(buffer) + size));
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->adc_inst.data + CDATA_HOST_SRC_CURRENTL,
+        LO(virt_to_bus(buffer)));
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->adc_inst.data + CDATA_HOST_SRC_CURRENTH,
+        HI(virt_to_bus(buffer)));
+#undef LO
+#undef HI
+
+    /* dsp buffers */
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->adc_inst.data + CDATA_IN_BUF_BEGIN,
+        dsp_in_buffer);
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->adc_inst.data + CDATA_IN_BUF_END_PLUS_1,
+        dsp_in_buffer + (dsp_in_size / 2));
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->adc_inst.data + CDATA_IN_BUF_HEAD,
+        dsp_in_buffer);
+    
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->adc_inst.data + CDATA_IN_BUF_TAIL,
+        dsp_in_buffer);
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->adc_inst.data + CDATA_OUT_BUF_BEGIN,
+        dsp_out_buffer);
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->adc_inst.data + CDATA_OUT_BUF_END_PLUS_1,
+        dsp_out_buffer + (dsp_out_size / 2));
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->adc_inst.data + CDATA_OUT_BUF_HEAD,
+        dsp_out_buffer);
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->adc_inst.data + CDATA_OUT_BUF_TAIL,
+        dsp_out_buffer);
+
+    /*
+     * some per client initializers
+     */
+
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->adc_inst.data + SRC3_DIRECTION_OFFSET + 12,
+        s->adc_inst.data + 40 + 8);
+
+    /* tell it which way dma is going? */
+    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+        s->adc_inst.data + CDATA_DMA_CONTROL,
+        DMACONTROL_DIRECTION + DMACONTROL_AUTOREPEAT + 
+        DMAC_PAGE3_SELECTOR + DMAC_BLOCKF_SELECTOR);
+
+    /*
+     * set an armload of static initializers
+     */
+    for(i = 0 ; i < (sizeof(rv) / sizeof(rv[0])) ; i++) 
+        m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
+            s->adc_inst.data + rv[i].addr, rv[i].val);
+
+    /* 
+     * put us in the lists if we're not already there
+     */
+
+    if(db->in_lists == 0) {
+
+        db->adc1_index = m3_add_list(s->card, &s->card->adc1_list, 
+                s->adc_inst.data >> DP_SHIFT_COUNT);
+
+        db->dma_index = m3_add_list(s->card, &s->card->dma_list, 
+                s->adc_inst.data >> DP_SHIFT_COUNT);
+
+        db->msrc_index = m3_add_list(s->card, &s->card->msrc_list, 
+                s->adc_inst.data >> DP_SHIFT_COUNT);
+
+        db->in_lists = 1;
+    }
+
+    set_adc_rate(s,rate);
+    start_adc(s);
+}
+/* --------------------------------------------------------------------- */
+
+static void set_dmaa(struct m3_state *s, unsigned int addr, unsigned int count)
+{
+    DPRINTK(DPINT,"set_dmaa??\n");
+}
+
+static void set_dmac(struct m3_state *s, unsigned int addr, unsigned int count)
+{
+    DPRINTK(DPINT,"set_dmac??\n");
+}
+
+u32 get_dma_pos(struct m3_card *card,
+        int instance_addr)
+{
+    u16 hi = 0, lo = 0;
+    int retry = 10;
+
+    /*
+     * try and get a valid answer
+     */
+    while(retry--) {
+        hi =  m3_assp_read(card, MEMTYPE_INTERNAL_DATA,
+                instance_addr + CDATA_HOST_SRC_CURRENTH);
+
+        lo = m3_assp_read(card, MEMTYPE_INTERNAL_DATA,
+                instance_addr + CDATA_HOST_SRC_CURRENTL);
+
+        if(hi == m3_assp_read(card, MEMTYPE_INTERNAL_DATA,
+                instance_addr + CDATA_HOST_SRC_CURRENTH))
+            break;
+    }
+    return lo | (hi<<16);
+}
+
+u32 get_dmaa(struct m3_state *s)
+{
+    u32 offset;
+
+    offset = get_dma_pos(s->card, s->dac_inst.data) - 
+        virt_to_bus(s->dma_dac.rawbuf);
+
+    DPRINTK(DPINT,"get_dmaa: 0x%08x\n",offset);
+
+    return offset;
+}
+
+u32 get_dmac(struct m3_state *s)
+{
+    u32 offset;
+
+    offset = get_dma_pos(s->card, s->adc_inst.data) -
+        virt_to_bus(s->dma_adc.rawbuf);
+
+    DPRINTK(DPINT,"get_dmac: 0x%08x\n",offset);
+
+    return offset;
+
+}
+
+static void m3_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+static int 
+prog_dmabuf(struct m3_state *s, unsigned rec)
+{
+    struct dmabuf *db = rec ? &s->dma_adc : &s->dma_dac;
+    unsigned rate = rec ? s->rateadc : s->ratedac;
+    unsigned bytepersec;
+    unsigned bufs;
+    unsigned char fmt;
+    unsigned long flags;
+
+    spin_lock_irqsave(&s->lock, flags);
+
+    fmt = s->fmt;
+    if (rec) {
+        stop_adc(s);
+        fmt >>= ESS_ADC_SHIFT;
+    } else {
+        stop_dac(s);
+        fmt >>= ESS_DAC_SHIFT;
+    }
+    fmt &= ESS_FMT_MASK;
+
+    db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
+
+    bytepersec = rate << sample_shift[fmt];
+    bufs = PAGE_SIZE << db->buforder;
+    if (db->ossfragshift) {
+        if ((1000 << db->ossfragshift) < bytepersec)
+            db->fragshift = ld2(bytepersec/1000);
+        else
+            db->fragshift = db->ossfragshift;
+    } else {
+        db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1));
+        if (db->fragshift < 3)
+            db->fragshift = 3; 
+    }
+    db->numfrag = bufs >> db->fragshift;
+    while (db->numfrag < 4 && db->fragshift > 3) {
+        db->fragshift--;
+        db->numfrag = bufs >> db->fragshift;
+    }
+    db->fragsize = 1 << db->fragshift;
+    if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
+        db->numfrag = db->ossmaxfrags;
+    db->fragsamples = db->fragsize >> sample_shift[fmt];
+    db->dmasize = db->numfrag << db->fragshift;
+
+    DPRINTK(DPSTR,"prog_dmabuf: numfrag: %d fragsize: %d dmasize: %d\n",db->numfrag,db->fragsize,db->dmasize);
+
+    memset(db->rawbuf, (fmt & ESS_FMT_16BIT) ? 0 : 0x80, db->dmasize);
+
+    if (rec) 
+        m3_rec_setup(s, fmt, s->rateadc, db->rawbuf, db->dmasize);
+    else 
+        m3_play_setup(s, fmt, s->ratedac, db->rawbuf, db->dmasize);
+
+    db->ready = 1;
+
+    spin_unlock_irqrestore(&s->lock, flags);
+
+    return 0;
+}
+
+static void clear_advance(struct m3_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;
+    unsigned bptr = s->dma_dac.swptr;
+    unsigned len = s->dma_dac.fragsize;
+    
+    if (bptr + len > bsize) {
+        unsigned x = bsize - bptr;
+        memset(buf + bptr, c, x);
+        /* account for wrapping? */
+        bptr = 0;
+        len -= x;
+    }
+    memset(buf + bptr, c, len);
+}
+
+/* call with spinlock held! */
+static void m3_update_ptr(struct m3_state *s)
+{
+    unsigned hwptr;
+    int diff;
+
+    /* update ADC pointer */
+    if (s->dma_adc.ready) {
+        hwptr = get_dmac(s) % s->dma_adc.dmasize;
+        diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
+        s->dma_adc.hwptr = hwptr;
+        s->dma_adc.total_bytes += diff;
+        s->dma_adc.count += diff;
+        if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) 
+            wake_up(&s->dma_adc.wait);
+        if (!s->dma_adc.mapped) {
+            if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
+                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++;
+            }
+        }
+    }
+    /* update DAC pointer */
+    if (s->dma_dac.ready) {
+        hwptr = get_dmaa(s) % s->dma_dac.dmasize; 
+        diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
+
+        DPRINTK(DPINT,"updating dac: hwptr: %6d diff: %6d count: %6d\n",
+                hwptr,diff,s->dma_dac.count);
+
+        s->dma_dac.hwptr = hwptr;
+        s->dma_dac.total_bytes += diff;
+
+        if (s->dma_dac.mapped) {
+            
+            s->dma_dac.count += diff;
+            if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) {
+                wake_up(&s->dma_dac.wait);
+            }
+        } else {
+
+            s->dma_dac.count -= diff;
+            
+            if (s->dma_dac.count <= 0) {
+                DPRINTK(DPCRAP,"underflow! diff: %d (0x%x) count: %d (0x%x) hw: %d (0x%x) sw: %d (0x%x)\n", 
+                        diff, diff, 
+                        s->dma_dac.count, 
+                        s->dma_dac.count, 
+                    hwptr, hwptr,
+                    s->dma_dac.swptr,
+                    s->dma_dac.swptr);
+                stop_dac(s);
+                /* brute force everyone back in sync, sigh */
+                s->dma_dac.count = 0; 
+                s->dma_dac.swptr = hwptr; 
+                s->dma_dac.error++;
+            } else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) {
+                clear_advance(s);
+                s->dma_dac.endcleared = 1;
+            }
+            if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize) {
+                wake_up(&s->dma_dac.wait);
+                DPRINTK(DPINT,"waking up DAC count: %d sw: %d hw: %d\n",
+                        s->dma_dac.count, s->dma_dac.swptr, hwptr);
+            }
+        }
+    }
+}
+
+static void m3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+    struct m3_card *c = (struct m3_card *)dev_id;
+    struct m3_state *s = &c->channels[0];
+    u8 status;
+
+    status = inb(c->iobase+0x1A);
+
+    if(status == 0xff) return;
+   
+    /* presumably acking the ints? */
+    outw(status, c->iobase+0x1A); 
+
+    if(c->in_suspend)
+        return;
+
+    /*
+     * ack an assp int if its running
+     * and has an int pending
+     */
+    if( status & ASSP_INT_PENDING) {
+        u8 ctl = inb(c->iobase + ASSP_CONTROL_B);
+        if( !(ctl & STOP_ASSP_CLOCK)) {
+            ctl = inb(c->iobase + ASSP_HOST_INT_STATUS );
+            if(ctl & DSP2HOST_REQ_TIMER) {
+                outb( DSP2HOST_REQ_TIMER, c->iobase + ASSP_HOST_INT_STATUS);
+                /* update adc/dac info if it was a timer int */
+                spin_lock(&s->lock);
+                m3_update_ptr(s);
+                spin_unlock(&s->lock);
+            }
+        }
+    }
+
+    /* XXX is this needed? */
+    if(status & 0x40) 
+        outb(0x40, c->iobase+0x1A);
+}
+
+
+/* --------------------------------------------------------------------- */
+
+static const char invalid_magic[] = KERN_CRIT PFX "invalid magic value in %s\n";
+
+#define VALIDATE_MAGIC(FOO,MAG)                         \
+({                                                \
+    if (!(FOO) || (FOO)->magic != MAG) { \
+        printk(invalid_magic,__FUNCTION__);            \
+        return -ENXIO;                    \
+    }                                         \
+})
+
+#define VALIDATE_STATE(a) VALIDATE_MAGIC(a,M3_STATE_MAGIC)
+#define VALIDATE_CARD(a) VALIDATE_MAGIC(a,M3_CARD_MAGIC)
+
+/* --------------------------------------------------------------------- */
+
+static loff_t m3_llseek(struct file *file, loff_t offset, int origin)
+{
+    return -ESPIPE;
+}
+
+/* --------------------------------------------------------------------- */
+
+static int drain_dac(struct m3_state *s, int nonblock)
+{
+    DECLARE_WAITQUEUE(wait,current);
+    unsigned long flags;
+    int count;
+    signed long tmo;
+
+    if (s->dma_dac.mapped || !s->dma_dac.ready)
+        return 0;
+    current->state = TASK_INTERRUPTIBLE;
+    add_wait_queue(&s->dma_dac.wait, &wait);
+    for (;;) {
+        spin_lock_irqsave(&s->lock, flags);
+        count = s->dma_dac.count;
+        spin_unlock_irqrestore(&s->lock, flags);
+        if (count <= 0)
+            break;
+        if (signal_pending(current))
+            break;
+        if (nonblock) {
+            remove_wait_queue(&s->dma_dac.wait, &wait);
+            current->state = TASK_RUNNING;
+            return -EBUSY;
+        }
+        tmo = (count * HZ) / s->ratedac;
+        tmo >>= sample_shift[(s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK];
+        /* XXX this is just broken.  someone is waking us up alot, or schedule_timeout is broken.
+            or something.  who cares. - zach */
+        if (!schedule_timeout(tmo ? tmo : 1) && tmo)
+            DPRINTK(DPCRAP,"dma timed out?? %ld\n",jiffies);
+    }
+    remove_wait_queue(&s->dma_dac.wait, &wait);
+    current->state = TASK_RUNNING;
+    if (signal_pending(current))
+            return -ERESTARTSYS;
+    return 0;
+}
+
+static ssize_t m3_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+{
+    struct m3_state *s = (struct m3_state *)file->private_data;
+    ssize_t ret;
+    unsigned long flags;
+    unsigned swptr;
+    int cnt;
+    
+    VALIDATE_STATE(s);
+    if (ppos != &file->f_pos)
+        return -ESPIPE;
+    if (s->dma_adc.mapped)
+        return -ENXIO;
+    if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
+        return ret;
+    if (!access_ok(VERIFY_WRITE, buffer, count))
+        return -EFAULT;
+    ret = 0;
+
+    spin_lock_irqsave(&s->lock, flags);
+
+    while (count > 0) {
+        int timed_out;
+
+        swptr = s->dma_adc.swptr;
+        cnt = s->dma_adc.dmasize-swptr;
+        if (s->dma_adc.count < cnt)
+            cnt = s->dma_adc.count;
+
+        if (cnt > count)
+            cnt = count;
+
+        if (cnt <= 0) {
+            start_adc(s);
+            if (file->f_flags & O_NONBLOCK) 
+            {
+                ret = ret ? ret : -EAGAIN;
+                goto out;
+            }
+
+            spin_unlock_irqrestore(&s->lock, flags);
+            timed_out = interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ) == 0;
+            spin_lock_irqsave(&s->lock, flags);
+
+            if(timed_out) {
+                printk("read: chip lockup? dmasz %u fragsz %u count %u hwptr %u swptr %u\n",
+                       s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count, 
+                       s->dma_adc.hwptr, s->dma_adc.swptr);
+                stop_adc(s);
+                set_dmac(s, virt_to_bus(s->dma_adc.rawbuf), s->dma_adc.numfrag << s->dma_adc.fragshift);
+                s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
+            }
+            if (signal_pending(current)) 
+            {
+                ret = ret ? ret : -ERESTARTSYS;
+                goto out;
+            }
+            continue;
+        }
+    
+        spin_unlock_irqrestore(&s->lock, flags);
+        if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {
+            ret = ret ? ret : -EFAULT;
+            return ret;
+        }
+        spin_lock_irqsave(&s->lock, flags);
+
+        swptr = (swptr + cnt) % s->dma_adc.dmasize;
+        s->dma_adc.swptr = swptr;
+        s->dma_adc.count -= cnt;
+        count -= cnt;
+        buffer += cnt;
+        ret += cnt;
+        start_adc(s);
+    }
+
+out:
+    spin_unlock_irqrestore(&s->lock, flags);
+    return ret;
+}
+
+static ssize_t m3_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+{
+    struct m3_state *s = (struct m3_state *)file->private_data;
+    ssize_t ret;
+    unsigned long flags;
+    unsigned swptr;
+    int cnt;
+    
+    VALIDATE_STATE(s);
+    if (ppos != &file->f_pos)
+        return -ESPIPE;
+    if (s->dma_dac.mapped)
+        return -ENXIO;
+    if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
+        return ret;
+    if (!access_ok(VERIFY_READ, buffer, count))
+        return -EFAULT;
+    ret = 0;
+
+    spin_lock_irqsave(&s->lock, flags);
+
+    while (count > 0) {
+        int timed_out;
+
+        if (s->dma_dac.count < 0) {
+            s->dma_dac.count = 0;
+            s->dma_dac.swptr = s->dma_dac.hwptr;
+        }
+        swptr = s->dma_dac.swptr;
+
+        cnt = s->dma_dac.dmasize-swptr;
+
+        if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
+            cnt = s->dma_dac.dmasize - s->dma_dac.count;
+
+
+        if (cnt > count)
+            cnt = count;
+
+        if (cnt <= 0) {
+            start_dac(s);
+            if (file->f_flags & O_NONBLOCK) {
+                if(!ret) ret = -EAGAIN;
+                goto out;
+            }
+            spin_unlock_irqrestore(&s->lock, flags);
+            timed_out = interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ) == 0;
+            spin_lock_irqsave(&s->lock, flags);
+            if(timed_out) {
+                DPRINTK(DPCRAP,"write: chip lockup? dmasz %u fragsz %u count %u hwptr %u swptr %u\n",
+                       s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count, 
+                       s->dma_dac.hwptr, s->dma_dac.swptr);
+                stop_dac(s);
+                set_dmaa(s, virt_to_bus(s->dma_dac.rawbuf), s->dma_dac.numfrag << s->dma_dac.fragshift);
+                s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0;
+            }
+            if (signal_pending(current)) {
+                if (!ret) ret = -ERESTARTSYS;
+                goto out;
+            }
+            continue;
+        }
+        spin_unlock_irqrestore(&s->lock, flags);
+        if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) {
+            if (!ret) ret = -EFAULT;
+            return ret;
+        }
+        spin_lock_irqsave(&s->lock, flags);
+
+        DPRINTK(DPSYS,"wrote %6d bytes at sw: %6d cnt: %6d while hw: %6d\n",
+                cnt, swptr, s->dma_dac.count, s->dma_dac.hwptr);
+        
+        swptr = (swptr + cnt) % s->dma_dac.dmasize;
+
+        s->dma_dac.swptr = swptr;
+        s->dma_dac.count += cnt;
+        s->dma_dac.endcleared = 0;
+        count -= cnt;
+        buffer += cnt;
+        ret += cnt;
+        start_dac(s);
+    }
+out:
+    spin_unlock_irqrestore(&s->lock, flags);
+    return ret;
+}
+
+static unsigned int m3_poll(struct file *file, struct poll_table_struct *wait)
+{
+    struct m3_state *s = (struct m3_state *)file->private_data;
+    unsigned long flags;
+    unsigned int mask = 0;
+
+    VALIDATE_STATE(s);
+    if (file->f_mode & FMODE_WRITE)
+        poll_wait(file, &s->dma_dac.wait, wait);
+    if (file->f_mode & FMODE_READ)
+        poll_wait(file, &s->dma_adc.wait, wait);
+
+    spin_lock_irqsave(&s->lock, flags);
+    m3_update_ptr(s);
+
+    if (file->f_mode & FMODE_READ) {
+        if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
+            mask |= POLLIN | POLLRDNORM;
+    }
+    if (file->f_mode & FMODE_WRITE) {
+        if (s->dma_dac.mapped) {
+            if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) 
+                mask |= POLLOUT | POLLWRNORM;
+        } else {
+            if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize)
+                mask |= POLLOUT | POLLWRNORM;
+        }
+    }
+
+    spin_unlock_irqrestore(&s->lock, flags);
+    return mask;
+}
+
+static int m3_mmap(struct file *file, struct vm_area_struct *vma)
+{
+    struct m3_state *s = (struct m3_state *)file->private_data;
+    unsigned long max_size, size, start, offset;
+    struct dmabuf *db;
+    int ret = -EINVAL;
+
+    VALIDATE_STATE(s);
+    if (vma->vm_flags & VM_WRITE) {
+        if ((ret = prog_dmabuf(s, 0)) != 0)
+            return ret;
+        db = &s->dma_dac;
+    } else 
+    if (vma->vm_flags & VM_READ) {
+        if ((ret = prog_dmabuf(s, 1)) != 0)
+            return ret;
+        db = &s->dma_adc;
+    } else  
+        return -EINVAL;
+
+    max_size = db->dmasize;
+
+    start = vma->vm_start;
+    offset = (vma->vm_pgoff << PAGE_SHIFT);
+    size = vma->vm_end - vma->vm_start;
+
+    if(size > max_size)
+        goto out;
+    if(offset > max_size - size)
+        goto out;
+
+    /*
+     * this will be ->nopage() once I can 
+     * ask Jeff what the hell I'm doing wrong.
+     */
+    ret = -EAGAIN;
+    if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot))
+        goto out;
+
+    db->mapped = 1;
+    ret = 0;
+
+out:
+    return ret;
+}
+
+/*
+ * this function is a disaster..
+ */
+#define get_user_ret(x, ptr,  ret) ({ if(get_user(x, ptr)) return ret; })
+static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+    struct m3_state *s = (struct m3_state *)file->private_data;
+    unsigned long flags;
+    audio_buf_info abinfo;
+    count_info cinfo;
+    int val, mapped, ret;
+    unsigned char fmtm, fmtd;
+
+    VALIDATE_STATE(s);
+
+    mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
+        ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
+
+    DPRINTK(DPSYS,"m3_ioctl: cmd %d\n", cmd);
+
+    switch (cmd) {
+    case OSS_GETVERSION:
+        return put_user(SOUND_VERSION, (int *)arg);
+
+    case SNDCTL_DSP_SYNC:
+        if (file->f_mode & FMODE_WRITE)
+            return drain_dac(s, file->f_flags & O_NONBLOCK);
+        return 0;
+        
+    case SNDCTL_DSP_SETDUPLEX:
+        /* XXX fix */
+        return 0;
+
+    case SNDCTL_DSP_GETCAPS:
+        return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+        
+    case SNDCTL_DSP_RESET:
+        spin_lock_irqsave(&s->lock, flags);
+        if (file->f_mode & FMODE_WRITE) {
+            stop_dac(s);
+            synchronize_irq();
+            s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;
+        }
+        if (file->f_mode & FMODE_READ) {
+            stop_adc(s);
+            synchronize_irq();
+            s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
+        }
+        spin_unlock_irqrestore(&s->lock, flags);
+        return 0;
+
+    case SNDCTL_DSP_SPEED:
+        get_user_ret(val, (int *)arg, -EFAULT);
+        spin_lock_irqsave(&s->lock, flags);
+        if (val >= 0) {
+            if (file->f_mode & FMODE_READ) {
+                stop_adc(s);
+                s->dma_adc.ready = 0;
+                set_adc_rate(s, val);
+            }
+            if (file->f_mode & FMODE_WRITE) {
+                stop_dac(s);
+                s->dma_dac.ready = 0;
+                set_dac_rate(s, val);
+            }
+        }
+        spin_unlock_irqrestore(&s->lock, flags);
+        return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
+        
+    case SNDCTL_DSP_STEREO:
+        get_user_ret(val, (int *)arg, -EFAULT);
+        spin_lock_irqsave(&s->lock, flags);
+        fmtd = 0;
+        fmtm = ~0;
+        if (file->f_mode & FMODE_READ) {
+            stop_adc(s);
+            s->dma_adc.ready = 0;
+            if (val)
+                fmtd |= ESS_FMT_STEREO << ESS_ADC_SHIFT;
+            else
+                fmtm &= ~(ESS_FMT_STEREO << ESS_ADC_SHIFT);
+        }
+        if (file->f_mode & FMODE_WRITE) {
+            stop_dac(s);
+            s->dma_dac.ready = 0;
+            if (val)
+                fmtd |= ESS_FMT_STEREO << ESS_DAC_SHIFT;
+            else
+                fmtm &= ~(ESS_FMT_STEREO << ESS_DAC_SHIFT);
+        }
+        set_fmt(s, fmtm, fmtd);
+        spin_unlock_irqrestore(&s->lock, flags);
+        return 0;
+
+    case SNDCTL_DSP_CHANNELS:
+        get_user_ret(val, (int *)arg, -EFAULT);
+        spin_lock_irqsave(&s->lock, flags);
+        if (val != 0) {
+            fmtd = 0;
+            fmtm = ~0;
+            if (file->f_mode & FMODE_READ) {
+                stop_adc(s);
+                s->dma_adc.ready = 0;
+                if (val >= 2)
+                    fmtd |= ESS_FMT_STEREO << ESS_ADC_SHIFT;
+                else
+                    fmtm &= ~(ESS_FMT_STEREO << ESS_ADC_SHIFT);
+            }
+            if (file->f_mode & FMODE_WRITE) {
+                stop_dac(s);
+                s->dma_dac.ready = 0;
+                if (val >= 2)
+                    fmtd |= ESS_FMT_STEREO << ESS_DAC_SHIFT;
+                else
+                    fmtm &= ~(ESS_FMT_STEREO << ESS_DAC_SHIFT);
+            }
+            set_fmt(s, fmtm, fmtd);
+        }
+        spin_unlock_irqrestore(&s->lock, flags);
+        return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT) 
+                       : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, (int *)arg);
+        
+    case SNDCTL_DSP_GETFMTS: /* Returns a mask */
+        return put_user(AFMT_U8|AFMT_S16_LE, (int *)arg);
+        
+    case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
+        get_user_ret(val, (int *)arg, -EFAULT);
+        spin_lock_irqsave(&s->lock, flags);
+        if (val != AFMT_QUERY) {
+            fmtd = 0;
+            fmtm = ~0;
+            if (file->f_mode & FMODE_READ) {
+                stop_adc(s);
+                s->dma_adc.ready = 0;
+                if (val == AFMT_S16_LE)
+                    fmtd |= ESS_FMT_16BIT << ESS_ADC_SHIFT;
+                else
+                    fmtm &= ~(ESS_FMT_16BIT << ESS_ADC_SHIFT);
+            }
+            if (file->f_mode & FMODE_WRITE) {
+                stop_dac(s);
+                s->dma_dac.ready = 0;
+                if (val == AFMT_S16_LE)
+                    fmtd |= ESS_FMT_16BIT << ESS_DAC_SHIFT;
+                else
+                    fmtm &= ~(ESS_FMT_16BIT << ESS_DAC_SHIFT);
+            }
+            set_fmt(s, fmtm, fmtd);
+        }
+        spin_unlock_irqrestore(&s->lock, flags);
+        return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? 
+            (ESS_FMT_16BIT << ESS_ADC_SHIFT) 
+            : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 
+                AFMT_S16_LE : 
+                AFMT_U8, 
+            (int *)arg);
+        
+    case SNDCTL_DSP_POST:
+        return 0;
+
+    case SNDCTL_DSP_GETTRIGGER:
+        val = 0;
+        if ((file->f_mode & FMODE_READ) && (s->enable & ADC_RUNNING))
+            val |= PCM_ENABLE_INPUT;
+        if ((file->f_mode & FMODE_WRITE) && (s->enable & DAC_RUNNING)) 
+            val |= PCM_ENABLE_OUTPUT;
+        return put_user(val, (int *)arg);
+        
+    case SNDCTL_DSP_SETTRIGGER:
+        get_user_ret(val, (int *)arg, -EFAULT);
+        if (file->f_mode & FMODE_READ) {
+            if (val & PCM_ENABLE_INPUT) {
+                if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
+                    return ret;
+                start_adc(s);
+            } else
+                stop_adc(s);
+        }
+        if (file->f_mode & FMODE_WRITE) {
+            if (val & PCM_ENABLE_OUTPUT) {
+                if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
+                    return ret;
+                start_dac(s);
+            } else
+                stop_dac(s);
+        }
+        return 0;
+
+    case SNDCTL_DSP_GETOSPACE:
+        if (!(file->f_mode & FMODE_WRITE))
+            return -EINVAL;
+        if (!(s->enable & DAC_RUNNING) && (val = prog_dmabuf(s, 0)) != 0)
+            return val;
+        spin_lock_irqsave(&s->lock, flags);
+        m3_update_ptr(s);
+        abinfo.fragsize = s->dma_dac.fragsize;
+        abinfo.bytes = s->dma_dac.dmasize - s->dma_dac.count;
+        abinfo.fragstotal = s->dma_dac.numfrag;
+        abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;      
+        spin_unlock_irqrestore(&s->lock, flags);
+        return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+
+    case SNDCTL_DSP_GETISPACE:
+        if (!(file->f_mode & FMODE_READ))
+            return -EINVAL;
+        if (!(s->enable & ADC_RUNNING) && (val = prog_dmabuf(s, 1)) != 0)
+            return val;
+        spin_lock_irqsave(&s->lock, flags);
+        m3_update_ptr(s);
+        abinfo.fragsize = s->dma_adc.fragsize;
+        abinfo.bytes = s->dma_adc.count;
+        abinfo.fragstotal = s->dma_adc.numfrag;
+        abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
+        spin_unlock_irqrestore(&s->lock, flags);
+        return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+        
+    case SNDCTL_DSP_NONBLOCK:
+        file->f_flags |= O_NONBLOCK;
+        return 0;
+
+    case SNDCTL_DSP_GETODELAY:
+        if (!(file->f_mode & FMODE_WRITE))
+            return -EINVAL;
+        spin_lock_irqsave(&s->lock, flags);
+        m3_update_ptr(s);
+        val = s->dma_dac.count;
+        spin_unlock_irqrestore(&s->lock, flags);
+        return put_user(val, (int *)arg);
+
+    case SNDCTL_DSP_GETIPTR:
+        if (!(file->f_mode & FMODE_READ))
+            return -EINVAL;
+        spin_lock_irqsave(&s->lock, flags);
+        m3_update_ptr(s);
+        cinfo.bytes = s->dma_adc.total_bytes;
+        cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift;
+        cinfo.ptr = s->dma_adc.hwptr;
+        if (s->dma_adc.mapped)
+            s->dma_adc.count &= s->dma_adc.fragsize-1;
+        spin_unlock_irqrestore(&s->lock, flags);
+        return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+
+    case SNDCTL_DSP_GETOPTR:
+        if (!(file->f_mode & FMODE_WRITE))
+            return -EINVAL;
+        spin_lock_irqsave(&s->lock, flags);
+        m3_update_ptr(s);
+        cinfo.bytes = s->dma_dac.total_bytes;
+        cinfo.blocks = s->dma_dac.count >> s->dma_dac.fragshift;
+        cinfo.ptr = s->dma_dac.hwptr;
+        if (s->dma_dac.mapped)
+            s->dma_dac.count &= s->dma_dac.fragsize-1;
+        spin_unlock_irqrestore(&s->lock, flags);
+        return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+
+    case SNDCTL_DSP_GETBLKSIZE:
+        if (file->f_mode & FMODE_WRITE) {
+            if ((val = prog_dmabuf(s, 0)))
+                return val;
+            return put_user(s->dma_dac.fragsize, (int *)arg);
+        }
+        if ((val = prog_dmabuf(s, 1)))
+            return val;
+        return put_user(s->dma_adc.fragsize, (int *)arg);
+
+    case SNDCTL_DSP_SETFRAGMENT:
+        get_user_ret(val, (int *)arg, -EFAULT);
+        spin_lock_irqsave(&s->lock, flags);
+        if (file->f_mode & FMODE_READ) {
+            s->dma_adc.ossfragshift = val & 0xffff;
+            s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
+            if (s->dma_adc.ossfragshift < 4)
+                s->dma_adc.ossfragshift = 4;
+            if (s->dma_adc.ossfragshift > 15)
+                s->dma_adc.ossfragshift = 15;
+            if (s->dma_adc.ossmaxfrags < 4)
+                s->dma_adc.ossmaxfrags = 4;
+        }
+        if (file->f_mode & FMODE_WRITE) {
+            s->dma_dac.ossfragshift = val & 0xffff;
+            s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
+            if (s->dma_dac.ossfragshift < 4)
+                s->dma_dac.ossfragshift = 4;
+            if (s->dma_dac.ossfragshift > 15)
+                s->dma_dac.ossfragshift = 15;
+            if (s->dma_dac.ossmaxfrags < 4)
+                s->dma_dac.ossmaxfrags = 4;
+        }
+        spin_unlock_irqrestore(&s->lock, flags);
+        return 0;
+
+    case SNDCTL_DSP_SUBDIVIDE:
+        if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
+            (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
+            return -EINVAL;
+                get_user_ret(val, (int *)arg, -EFAULT);
+        if (val != 1 && val != 2 && val != 4)
+            return -EINVAL;
+        if (file->f_mode & FMODE_READ)
+            s->dma_adc.subdivision = val;
+        if (file->f_mode & FMODE_WRITE)
+            s->dma_dac.subdivision = val;
+        return 0;
+
+    case SOUND_PCM_READ_RATE:
+        return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
+
+    case SOUND_PCM_READ_CHANNELS:
+        return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT) 
+                       : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, (int *)arg);
+
+    case SOUND_PCM_READ_BITS:
+        return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_16BIT << ESS_ADC_SHIFT) 
+                       : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 16 : 8, (int *)arg);
+
+    case SOUND_PCM_WRITE_FILTER:
+    case SNDCTL_DSP_SETSYNCRO:
+    case SOUND_PCM_READ_FILTER:
+        return -EINVAL;
+        
+    }
+    return -EINVAL;
+}
+
+static int
+allocate_dmabuf(struct pci_dev *pci_dev, struct dmabuf *db)
+{
+    int order;
+
+    DPRINTK(DPSTR,"allocating for dmabuf %p\n", db);
+
+    /* 
+     * alloc as big a chunk as we can, start with 
+     * 64k 'cause we're insane.  based on order cause
+     * the amazingly complicated prog_dmabuf wants it.
+     *
+     * pci_alloc_sonsistent guarantees that it won't cross a natural
+     * boundry; the m3 hardware can't have dma cross a 64k bus
+     * address boundry.
+     */
+    for (order = 16-PAGE_SHIFT; order >= 1; order--) {
+        db->rawbuf = pci_alloc_consistent(pci_dev, PAGE_SIZE << order,
+                        &(db->handle));
+        if(db->rawbuf)
+            break;
+    }
+
+    if (!db->rawbuf)
+        return 1;
+
+    DPRINTK(DPSTR,"allocated %ld (%d) bytes at %p\n",
+            PAGE_SIZE<<order, order, db->rawbuf);
+
+    {
+        struct page *page, *pend;
+
+        pend = virt_to_page(db->rawbuf + (PAGE_SIZE << order) - 1);
+        for (page = virt_to_page(db->rawbuf); page <= pend; page++)
+            mem_map_reserve(page);
+    }
+
+
+    db->buforder = order;
+    db->ready = 0;
+    db->mapped = 0;
+
+    return 0;
+}
+
+static void
+nuke_lists(struct m3_card *card, struct dmabuf *db)
+{
+    m3_remove_list(card, &(card->dma_list), db->dma_index);
+    m3_remove_list(card, &(card->msrc_list), db->msrc_index);
+    db->in_lists = 0;
+}
+
+static void
+free_dmabuf(struct pci_dev *pci_dev, struct dmabuf *db)
+{
+    DPRINTK(DPSTR,"freeing %p from dmabuf %p\n",db->rawbuf, db);
+
+    {
+        struct page *page, *pend;
+        pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
+        for (page = virt_to_page(db->rawbuf); page <= pend; page++)
+            mem_map_unreserve(page);
+    }
+
+
+    pci_free_consistent(pci_dev, PAGE_SIZE << db->buforder,
+            db->rawbuf, db->handle);
+
+    db->rawbuf = NULL;
+    db->buforder = 0;
+    db->mapped = 0;
+    db->ready = 0;
+}
+
+static int m3_open(struct inode *inode, struct file *file)
+{
+    int minor = MINOR(inode->i_rdev);
+    struct m3_card *c;
+    struct m3_state *s = NULL;
+    int i, ret = 0;
+    unsigned char fmtm = ~0, fmts = 0;
+    unsigned long flags;
+
+    /*
+     *    Scan the cards and find the channel. We only
+     *    do this at open time so it is ok
+     */
+    for(c = devs ; c != NULL ; c = c->next) {
+
+        for(i=0;i<NR_DSPS;i++) {
+
+            if(c->channels[i].dev_audio < 0)
+                continue;
+            if((c->channels[i].dev_audio ^ minor) & ~0xf)
+                continue;
+
+            s = &c->channels[i];
+            break;
+        }
+    }
+        
+    if (!s)
+        return -ENODEV;
+        
+    VALIDATE_STATE(s);
+
+    file->private_data = s;
+
+    /* wait for device to become free */
+    down(&s->open_sem);
+    while (s->open_mode & file->f_mode) {
+        if (file->f_flags & O_NONBLOCK) {
+            up(&s->open_sem);
+            return -EWOULDBLOCK;
+        }
+        up(&s->open_sem);
+        interruptible_sleep_on(&s->open_wait);
+        if (signal_pending(current))
+            return -ERESTARTSYS;
+        down(&s->open_sem);
+    }
+    
+    spin_lock_irqsave(&s->lock, flags);
+
+    if (file->f_mode & FMODE_READ) {
+        if(allocate_dmabuf(s->card->pcidev, &(s->dma_adc)))  {
+            ret = -ENOMEM;
+            goto out;
+        }
+        fmtm &= ~((ESS_FMT_STEREO | ESS_FMT_16BIT) << ESS_ADC_SHIFT);
+        if ((minor & 0xf) == SND_DEV_DSP16)
+            fmts |= ESS_FMT_16BIT << ESS_ADC_SHIFT; 
+
+        s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
+        set_adc_rate(s, 8000);
+    }
+    if (file->f_mode & FMODE_WRITE) {
+        if(allocate_dmabuf(s->card->pcidev, &(s->dma_dac)))  {
+            ret = -ENOMEM;
+            goto out;
+        }
+        fmtm &= ~((ESS_FMT_STEREO | ESS_FMT_16BIT) << ESS_DAC_SHIFT);
+        if ((minor & 0xf) == SND_DEV_DSP16)
+            fmts |= ESS_FMT_16BIT << ESS_DAC_SHIFT;
+
+        s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
+        set_dac_rate(s, 8000);
+    }
+    set_fmt(s, fmtm, fmts);
+    s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
+
+    MOD_INC_USE_COUNT;
+out:
+    up(&s->open_sem);
+    spin_unlock_irqrestore(&s->lock, flags);
+    return 0;
+}
+
+static int m3_release(struct inode *inode, struct file *file)
+{
+    struct m3_state *s = (struct m3_state *)file->private_data;
+    unsigned long flags;
+
+    VALIDATE_STATE(s);
+    if (file->f_mode & FMODE_WRITE)
+        drain_dac(s, file->f_flags & O_NONBLOCK);
+
+    down(&s->open_sem);
+    spin_lock_irqsave(&s->lock, flags);
+
+    if (file->f_mode & FMODE_WRITE) {
+        stop_dac(s);
+        if(s->dma_dac.in_lists) {
+            m3_remove_list(s->card, &(s->card->mixer_list), s->dma_dac.mixer_index);
+            nuke_lists(s->card, &(s->dma_dac));
+        }
+        free_dmabuf(s->card->pcidev, &(s->dma_dac));
+    }
+    if (file->f_mode & FMODE_READ) {
+        stop_adc(s);
+        if(s->dma_adc.in_lists) {
+            m3_remove_list(s->card, &(s->card->adc1_list), s->dma_adc.adc1_index);
+            nuke_lists(s->card, &(s->dma_adc));
+        }
+        free_dmabuf(s->card->pcidev, &(s->dma_adc));
+    }
+        
+    s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
+
+    spin_unlock_irqrestore(&s->lock, flags);
+    up(&s->open_sem);
+    wake_up(&s->open_wait);
+
+    MOD_DEC_USE_COUNT;
+    return 0;
+}
+
+/*
+ * Wait for the ac97 serial bus to be free.
+ * return nonzero if the bus is still busy.
+ */
+static int m3_ac97_wait(struct m3_card *card)
+{
+    int i = 10000;
+
+    while( (m3_inb(card, 0x30) & 1) && i--) ;
+
+    return i == 0;
+}
+
+u16 m3_ac97_read(struct ac97_codec *codec, u8 reg)
+{
+    u16 ret = 0;
+    struct m3_card *card = codec->private_data;
+
+    spin_lock(&card->ac97_lock);
+
+    if(m3_ac97_wait(card)) {
+        printk(KERN_ERR PFX "serial bus busy reading reg 0x%x\n",reg);
+        goto out;
+    }
+
+    m3_outb(card, 0x80 | (reg & 0x7f), 0x30);
+
+    if(m3_ac97_wait(card)) {
+        printk(KERN_ERR PFX "serial bus busy finishing read reg 0x%x\n",reg);
+        goto out;
+    }
+
+    ret =  m3_inw(card, 0x32);
+    DPRINTK(DPCRAP,"reading 0x%04x from 0x%02x\n",ret, reg);
+
+out:
+    spin_unlock(&card->ac97_lock);
+    return ret;
+}
+
+void m3_ac97_write(struct ac97_codec *codec, u8 reg, u16 val)
+{
+    struct m3_card *card = codec->private_data;
+
+    spin_lock(&card->ac97_lock);
+
+    if(m3_ac97_wait(card)) {
+        printk(KERN_ERR PFX "serial bus busy writing 0x%x to 0x%x\n",val, reg);
+        goto out;
+    }
+    DPRINTK(DPCRAP,"writing 0x%04x  to  0x%02x\n", val, reg);
+
+    m3_outw(card, val, 0x32);
+    m3_outb(card, reg & 0x7f, 0x30);
+out:
+    spin_unlock(&card->ac97_lock);
+}
+/* OSS /dev/mixer file operation methods */
+static int m3_open_mixdev(struct inode *inode, struct file *file)
+{
+    int minor = MINOR(inode->i_rdev);
+    struct m3_card *card = devs;
+
+    MOD_INC_USE_COUNT;
+    for (card = devs; card != NULL; card = card->next) {
+        if((card->ac97 != NULL) && (card->ac97->dev_mixer == minor))
+                break;
+    }
+
+    if (!card) {
+        MOD_DEC_USE_COUNT;
+        return -ENODEV;
+    }
+
+    file->private_data = card->ac97;
+
+    return 0;
+}
+
+static int m3_release_mixdev(struct inode *inode, struct file *file)
+{
+    MOD_DEC_USE_COUNT;
+    return 0;
+}
+
+static int m3_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd,
+                                    unsigned long arg)
+{
+    struct ac97_codec *codec = (struct ac97_codec *)file->private_data;
+
+    return codec->mixer_ioctl(codec, cmd, arg);
+}
+
+static struct file_operations m3_mixer_fops = {
+    llseek:         m3_llseek,
+    ioctl:          m3_ioctl_mixdev,
+    open:           m3_open_mixdev,
+    release:        m3_release_mixdev,
+};
+
+void remote_codec_config(int io, int isremote)
+{
+    isremote = isremote ? 1 : 0;
+
+    outw(  (inw(io + RING_BUS_CTRL_B) & ~SECOND_CODEC_ID_MASK) | isremote,
+            io + RING_BUS_CTRL_B);
+    outw(  (inw(io + SDO_OUT_DEST_CTRL) & ~COMMAND_ADDR_OUT) | isremote,
+            io + SDO_OUT_DEST_CTRL);
+    outw(  (inw(io + SDO_IN_DEST_CTRL) & ~STATUS_ADDR_IN) | isremote,
+            io + SDO_IN_DEST_CTRL);
+}
+
+/* 
+ * hack, returns non zero on err 
+ */
+static int try_read_vendor(struct m3_card *card)
+{
+    u16 ret;
+
+    if(m3_ac97_wait(card)) 
+        return 1;
+
+    m3_outb(card, 0x80 | (AC97_VENDOR_ID1 & 0x7f), 0x30);
+
+    if(m3_ac97_wait(card)) 
+        return 1;
+
+    ret =  m3_inw(card, 0x32);
+
+    return (ret == 0) || (ret == 0xffff);
+}
+
+static void m3_codec_reset(struct m3_card *card, int busywait)
+{
+    u16 dir;
+    int delay1 = 0, delay2 = 0, i;
+    int io = card->iobase;
+
+    switch (card->card_type) {
+        /*
+         * the onboard codec on the allegro seems 
+         * to want to wait a very long time before
+         * coming back to life 
+         */
+        case ESS_ALLEGRO:
+            delay1 = 50;
+            delay2 = 800;
+        break;
+        case ESS_MAESTRO3:
+        case ESS_MAESTRO3HW:
+            delay1 = 20;
+            delay2 = 500;
+        break;
+    }
+
+    for(i = 0; i < 5; i ++) {
+        dir = inw(io + GPIO_DIRECTION);
+        dir |= 0x10; /* assuming pci bus master? */
+
+        remote_codec_config(io, 0);
+
+        outw(IO_SRAM_ENABLE, io + RING_BUS_CTRL_A);
+        udelay(20);
+
+        outw(dir & ~GPO_PRIMARY_AC97 , io + GPIO_DIRECTION);
+        outw(~GPO_PRIMARY_AC97 , io + GPIO_MASK);
+        outw(0, io + GPIO_DATA);
+        outw(dir | GPO_PRIMARY_AC97, io + GPIO_DIRECTION);
+
+        if(busywait)  {
+            mdelay(delay1);
+        } else {
+            current->state = TASK_UNINTERRUPTIBLE;
+            schedule_timeout((delay1 * HZ) / 1000);
+        }
+
+        outw(GPO_PRIMARY_AC97, io + GPIO_DATA);
+        udelay(5);
+        /* ok, bring back the ac-link */
+        outw(IO_SRAM_ENABLE | SERIAL_AC_LINK_ENABLE, io + RING_BUS_CTRL_A);
+        outw(~0, io + GPIO_MASK);
+
+        if(busywait) {
+            mdelay(delay2);
+        } else {
+            current->state = TASK_UNINTERRUPTIBLE;
+            schedule_timeout((delay2 * HZ) / 1000);
+        }
+        if(! try_read_vendor(card))
+            break;
+
+        delay1 += 10;
+        delay2 += 100;
+
+        DPRINTK(DPMOD, "retrying codec reset with delays of %d and %d ms\n",
+                delay1, delay2);
+    }
+
+#if 0
+    /* more gung-ho reset that doesn't
+     * seem to work anywhere :)
+     */
+    tmp = inw(io + RING_BUS_CTRL_A);
+    outw(RAC_SDFS_ENABLE|LAC_SDFS_ENABLE, io + RING_BUS_CTRL_A);
+    mdelay(20);
+    outw(tmp, io + RING_BUS_CTRL_A);
+    mdelay(50);
+#endif
+}
+
+static int __init m3_codec_install(struct m3_card *card)
+{
+    struct ac97_codec *codec;
+
+    if ((codec = kmalloc(sizeof(struct ac97_codec), GFP_KERNEL)) == NULL)
+        return -ENOMEM;
+    memset(codec, 0, sizeof(struct ac97_codec));
+
+    codec->private_data = card;
+    codec->codec_read = m3_ac97_read;
+    codec->codec_write = m3_ac97_write;
+
+    if (ac97_probe_codec(codec) == 0) {
+        printk(KERN_ERR PFX "codec probe failed\n");
+        kfree(codec);
+        return -1;
+    }
+
+    if ((codec->dev_mixer = register_sound_mixer(&m3_mixer_fops, -1)) < 0) {
+        printk(KERN_ERR PFX "couldn't register mixer!\n");
+        kfree(codec);
+        return -1;
+    }
+
+    card->ac97 = codec;
+
+    return 0;
+}
+
+
+#define MINISRC_LPF_LEN 10
+static u16 minisrc_lpf[MINISRC_LPF_LEN] = {
+    0X0743, 0X1104, 0X0A4C, 0XF88D, 0X242C,
+    0X1023, 0X1AA9, 0X0B60, 0XEFDD, 0X186F
+};
+static void m3_assp_init(struct m3_card *card)
+{
+    int i;
+
+    /* zero kernel data */
+    for(i = 0 ; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++)
+        m3_assp_write(card, MEMTYPE_INTERNAL_DATA, 
+                KDATA_BASE_ADDR + i, 0);
+
+    /* zero mixer data? */
+    for(i = 0 ; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++)
+        m3_assp_write(card, MEMTYPE_INTERNAL_DATA, 
+                KDATA_BASE_ADDR2 + i, 0);
+
+    /* init dma pointer */
+    m3_assp_write(card, MEMTYPE_INTERNAL_DATA, 
+            KDATA_CURRENT_DMA, 
+            KDATA_DMA_XFER0);
+
+    /* write kernel into code memory.. */
+    for(i = 0 ; i < sizeof(assp_kernel_image) / 2; i++) {
+        m3_assp_write(card, MEMTYPE_INTERNAL_CODE, 
+                REV_B_CODE_MEMORY_BEGIN + i, 
+                assp_kernel_image[i]);
+    }
+
+    /*
+     * We only have this one client and we know that 0x400
+     * is free in our kernel's mem map, so lets just
+     * drop it there.  It seems that the minisrc doesn't
+     * need vectors, so we won't bother with them..
+     */
+    for(i = 0 ; i < sizeof(assp_minisrc_image) / 2; i++) {
+        m3_assp_write(card, MEMTYPE_INTERNAL_CODE, 
+                0x400 + i, 
+                assp_minisrc_image[i]);
+    }
+
+    /*
+     * write the coefficients for the low pass filter?
+     */
+    for(i = 0; i < MINISRC_LPF_LEN ; i++) {
+        m3_assp_write(card, MEMTYPE_INTERNAL_CODE,
+            0x400 + MINISRC_COEF_LOC + i,
+            minisrc_lpf[i]);
+    }
+
+    m3_assp_write(card, MEMTYPE_INTERNAL_CODE,
+        0x400 + MINISRC_COEF_LOC + MINISRC_LPF_LEN,
+        0x8000);
+
+    /*
+     * the minisrc is the only thing on
+     * our task list..
+     */
+    m3_assp_write(card, MEMTYPE_INTERNAL_DATA, 
+            KDATA_TASK0, 
+            0x400);
+
+    /*
+     * init the mixer number..
+     */
+
+    m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
+            KDATA_MIXER_TASK_NUMBER,0);
+
+    /*
+     * EXTREME KERNEL MASTER VOLUME
+     */
+    m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
+        KDATA_DAC_LEFT_VOLUME, ARB_VOLUME);
+    m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
+        KDATA_DAC_RIGHT_VOLUME, ARB_VOLUME);
+
+    card->mixer_list.mem_addr = KDATA_MIXER_XFER0;
+    card->mixer_list.max = MAX_VIRTUAL_MIXER_CHANNELS;
+    card->adc1_list.mem_addr = KDATA_ADC1_XFER0;
+    card->adc1_list.max = MAX_VIRTUAL_ADC1_CHANNELS;
+    card->dma_list.mem_addr = KDATA_DMA_XFER0;
+    card->dma_list.max = MAX_VIRTUAL_DMA_CHANNELS;
+    card->msrc_list.mem_addr = KDATA_INSTANCE0_MINISRC;
+    card->msrc_list.max = MAX_INSTANCE_MINISRC;
+}
+
+static int setup_msrc(struct m3_card *card,
+        struct assp_instance *inst, int index)
+{
+    int data_bytes = 2 * ( MINISRC_TMP_BUFFER_SIZE / 2 + 
+            MINISRC_IN_BUFFER_SIZE / 2 +
+            1 + MINISRC_OUT_BUFFER_SIZE / 2 + 1 );
+    int address, i;
+
+    /*
+     * the revb memory map has 0x1100 through 0x1c00
+     * free.  
+     */
+
+    /*
+     * align instance address to 256 bytes so that it's
+     * shifted list address is aligned.  
+     * list address = (mem address >> 1) >> 7;
+     */
+    data_bytes = (data_bytes + 255) & ~255;
+    address = 0x1100 + ((data_bytes/2) * index);
+
+    if((address + (data_bytes/2)) >= 0x1c00) {
+        printk(KERN_ERR PFX "no memory for %d bytes at ind %d (addr 0x%x)\n",
+                data_bytes, index, address);
+        return -1;
+    }
+
+    for(i = 0; i < data_bytes/2 ; i++) 
+        m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
+                address + i, 0);
+
+    inst->code = 0x400;
+    inst->data = address;
+
+    return 0;
+}
+
+static int m3_assp_client_init(struct m3_state *s)
+{
+    setup_msrc(s->card, &(s->dac_inst), s->index * 2);
+    setup_msrc(s->card, &(s->adc_inst), (s->index * 2) + 1);
+
+    return 0;
+}
+
+static void m3_amp_enable(struct m3_card *card, int enable)
+{
+    /* 
+     * this works for the reference board, have to find
+     * out about others
+     *
+     * this needs more magic for 4 speaker, but..
+     */
+    int io = card->iobase;
+    u16 gpo, polarity_port, polarity;
+
+    if(!external_amp)
+        return;
+
+    switch (card->card_type) {
+        case ESS_ALLEGRO:
+            polarity_port = 0x1800;
+            break;
+        default:
+            /* presumably this is for all 'maestro3's.. */
+            polarity_port = 0x1100;
+            break;
+    }
+
+    gpo = (polarity_port >> 8) & 0x0F;
+    polarity = polarity_port >> 12;
+    if ( enable )
+        polarity = !polarity;
+    polarity = polarity << gpo;
+    gpo = 1 << gpo;
+
+    outw(~gpo , io + GPIO_MASK);
+
+    outw( inw(io + GPIO_DIRECTION) | gpo ,
+            io + GPIO_DIRECTION);
+
+    outw( (GPO_SECONDARY_AC97 | GPO_PRIMARY_AC97 | polarity) ,
+            io + GPIO_DATA);
+
+    outw(0xffff , io + GPIO_MASK);
+}
+
+static int
+maestro_config(struct m3_card *card) 
+{
+    struct pci_dev *pcidev = card->pcidev;
+    u32 n;
+    u8  t; /* makes as much sense as 'n', no? */
+
+    pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n);
+    n &= REDUCED_DEBOUNCE;
+    n |= PM_CTRL_ENABLE | CLK_DIV_BY_49 | USE_PCI_TIMING;
+    pci_write_config_dword(pcidev, PCI_ALLEGRO_CONFIG, n);
+
+    outb(RESET_ASSP, card->iobase + ASSP_CONTROL_B);
+    pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n);
+    n &= ~INT_CLK_SELECT;
+    if(card->card_type >= ESS_MAESTRO3)  {
+        n &= ~INT_CLK_MULT_ENABLE; 
+        n |= INT_CLK_SRC_NOT_PCI;
+    }
+    n &=  ~( CLK_MULT_MODE_SELECT | CLK_MULT_MODE_SELECT_2 );
+    pci_write_config_dword(pcidev, PCI_ALLEGRO_CONFIG, n);
+
+    if(card->card_type <= ESS_ALLEGRO) {
+        pci_read_config_dword(pcidev, PCI_USER_CONFIG, &n);
+        n |= IN_CLK_12MHZ_SELECT;
+        pci_write_config_dword(pcidev, PCI_USER_CONFIG, n);
+    }
+
+    t = inb(card->iobase + ASSP_CONTROL_A);
+    t &= ~( DSP_CLK_36MHZ_SELECT  | ASSP_CLK_49MHZ_SELECT);
+    t |= ASSP_CLK_49MHZ_SELECT;
+    t |= ASSP_0_WS_ENABLE; 
+    outb(t, card->iobase + ASSP_CONTROL_A);
+
+    outb(RUN_ASSP, card->iobase + ASSP_CONTROL_B); 
+
+    return 0;
+} 
+
+static void m3_enable_ints(struct m3_card *card)
+{
+    unsigned long io = card->iobase;
+
+    outw(ASSP_INT_ENABLE, io + HOST_INT_CTRL);
+    outb(inb(io + ASSP_CONTROL_C) | ASSP_HOST_INT_ENABLE,
+            io + ASSP_CONTROL_C);
+}
+
+static struct file_operations m3_audio_fops = {
+    llseek:     &m3_llseek,
+    read:       &m3_read,
+    write:      &m3_write,
+    poll:       &m3_poll,
+    ioctl:      &m3_ioctl,
+    mmap:       &m3_mmap,
+    open:       &m3_open,
+    release:    &m3_release,
+};
+
+#ifdef CONFIG_PM
+int alloc_dsp_suspendmem(struct m3_card *card)
+{
+    int len = sizeof(u16) * (REV_B_CODE_MEMORY_LENGTH + REV_B_DATA_MEMORY_LENGTH);
+
+    if( (card->suspend_mem = vmalloc(len)) == NULL)
+        return 1;
+
+    return 0;
+}
+void free_dsp_suspendmem(struct m3_card *card)
+{
+   if(card->suspend_mem)
+       vfree(card->suspend_mem);
+}
+
+#else
+#define alloc_dsp_suspendmem(args...) 0
+#define free_dsp_suspendmem(args...) 
+#endif
+
+/*
+ * great day!  this function is ugly as hell.
+ */
+static int __init m3_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id)
+{
+    u32 n;
+    int i;
+    struct m3_card *card = NULL;
+    int ret = 0;
+    int card_type = pci_id->driver_data;
+
+    DPRINTK(DPMOD, "in maestro_install\n");
+
+    if (!pci_dma_supported(pci_dev, 0xffffffff)) {
+        printk(KERN_ERR PFX "architecture does not support 32bit PCI busmaster DMA\n");
+        return -ENODEV;
+    }
+        
+    if (pci_enable_device(pci_dev))
+        return -EIO;
+
+    pci_set_master(pci_dev);
+
+    if( (card = kmalloc(sizeof(struct m3_card), GFP_KERNEL)) == NULL) {
+        printk(KERN_WARNING PFX "out of memory\n");
+        return -ENOMEM;
+    }
+    memset(card, 0, sizeof(struct m3_card));
+    card->pcidev = pci_dev;
+    init_waitqueue_head(&card->suspend_queue);
+
+    if ( ! request_region(pci_resource_start(pci_dev, 0),
+                pci_resource_len (pci_dev, 0), M3_MODULE_NAME)) {
+
+        printk(KERN_WARNING PFX "unable to reserve I/O space.\n");
+        ret = -EBUSY;
+        goto out;
+    }
+
+    card->iobase = pci_resource_start(pci_dev, 0);
+
+    if(alloc_dsp_suspendmem(card)) {
+        printk(KERN_WARNING PFX "couldn't alloc %d bytes for saving dsp state on suspend\n",
+                REV_B_CODE_MEMORY_LENGTH + REV_B_DATA_MEMORY_LENGTH);
+        ret = -ENOMEM;
+        goto out;
+    }
+
+    card->card_type = card_type;
+    card->irq = pci_dev->irq;
+    card->next = devs;
+    card->magic = M3_CARD_MAGIC;
+    spin_lock_init(&card->lock);
+    spin_lock_init(&card->ac97_lock);
+    devs = card;
+    for(i = 0; i<NR_DSPS; i++) {
+        struct m3_state *s = &(card->channels[i]);
+        s->dev_audio = -1;
+    }
+
+    printk(KERN_INFO PFX "Configuring ESS %s found at IO 0x%04X IRQ %d\n", 
+        card_names[card->card_type], card->iobase, card->irq);
+
+    pci_read_config_dword(pci_dev, PCI_SUBSYSTEM_VENDOR_ID, &n);
+    printk(KERN_INFO PFX " subvendor id: 0x%08x\n",n); 
+
+    maestro_config(card);
+    m3_assp_halt(card);
+
+    m3_codec_reset(card, 0);
+
+    if(m3_codec_install(card))  {
+        ret = -EIO; 
+        goto out;
+    }
+
+    m3_assp_init(card);
+    m3_amp_enable(card, 1);
+    
+    for(i=0;i<NR_DSPS;i++) {
+        struct m3_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);
+        init_MUTEX(&(s->open_sem));
+        s->magic = M3_STATE_MAGIC;
+
+        m3_assp_client_init(s);
+        
+        if(s->dma_adc.ready || s->dma_dac.ready || s->dma_adc.rawbuf)
+            printk(KERN_WARNING PFX "initing a dsp device that is already in use?\n");
+        /* register devices */
+        if ((s->dev_audio = register_sound_dsp(&m3_audio_fops, -1)) < 0) {
+            break;
+        }
+    }
+    
+    if(request_irq(card->irq, m3_interrupt, SA_SHIRQ, card_names[card->card_type], card)) {
+
+        printk(KERN_ERR PFX "unable to allocate irq %d,\n", card->irq);
+
+        ret = -EIO;
+        goto out;
+    }
+
+    pci_dev->driver_data = card;
+    
+    m3_enable_ints(card);
+    m3_assp_continue(card);
+
+out:
+    if(ret) {
+        if(card->iobase)
+            release_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));
+        free_dsp_suspendmem(card);
+        if(card->ac97) {
+            unregister_sound_mixer(card->ac97->dev_mixer);
+            kfree(card->ac97);
+        }
+        for(i=0;i<NR_DSPS;i++)
+        {
+            struct m3_state *s = &card->channels[i];
+            if(s->dev_audio != -1)
+                unregister_sound_dsp(s->dev_audio);
+        }
+        kfree(card);
+    }
+
+    return ret; 
+}
+
+static void m3_remove(struct pci_dev *pci_dev)
+{
+    struct m3_card *card;
+
+    unregister_reboot_notifier(&m3_reboot_nb);
+
+    while ((card = devs)) {
+        int i;
+        devs = devs->next;
+    
+        free_irq(card->irq, card);
+        unregister_sound_mixer(card->ac97->dev_mixer);
+        kfree(card->ac97);
+
+        for(i=0;i<NR_DSPS;i++)
+        {
+            struct m3_state *s = &card->channels[i];
+            if(s->dev_audio != -1)
+                unregister_sound_dsp(s->dev_audio);
+        }
+
+        release_region(card->iobase, 256);
+        free_dsp_suspendmem(card);
+        kfree(card);
+    }
+    devs = NULL;
+}
+
+/*
+ * some bioses like the sound chip to be powered down
+ * at shutdown.  We're just calling _suspend to
+ * achieve that..
+ */
+static int m3_notifier(struct notifier_block *nb, unsigned long event, void *buf)
+{
+    struct m3_card *card;
+
+    DPRINTK(DPMOD, "notifier suspending all cards\n");
+
+    for(card = devs; card != NULL; card = card->next) {
+        if(!card->in_suspend)
+            m3_suspend(card->pcidev); /* XXX legal? */
+    }
+    return 0;
+}
+
+static void m3_suspend(struct pci_dev *pci_dev)
+{
+    unsigned long flags;
+    int index;
+    int i;
+    struct m3_card *card = pci_dev->driver_data;
+
+    /* must be a better way.. */
+    save_flags(flags);
+    cli();
+
+    DPRINTK(DPMOD, "pm in dev %p\n",card);
+
+    for(i=0;i<NR_DSPS;i++) {
+        struct m3_state *s = &card->channels[i];
+
+        if(s->dev_audio == -1)
+            continue;
+
+        DPRINTK(DPMOD, "stop_adc/dac() device %d\n",i);
+        stop_dac(s);
+        stop_adc(s);
+    }
+
+    mdelay(10); /* give the assp a chance to idle.. */
+
+    m3_assp_halt(card);
+
+    index = 0;
+    DPRINTK(DPMOD, "saving code\n");
+    for(i = REV_B_CODE_MEMORY_BEGIN ; i <= REV_B_CODE_MEMORY_END; i++)
+        card->suspend_mem[index++] = 
+            m3_assp_read(card, MEMTYPE_INTERNAL_CODE, i);
+    DPRINTK(DPMOD, "saving data\n");
+    for(i = REV_B_DATA_MEMORY_BEGIN ; i <= REV_B_DATA_MEMORY_END; i++)
+        card->suspend_mem[index++] = 
+            m3_assp_read(card, MEMTYPE_INTERNAL_DATA, i);
+
+    DPRINTK(DPMOD, "powering down apci regs\n");
+    m3_outw(card, 0xffff, 0x54);
+    m3_outw(card, 0xffff, 0x56);
+
+    card->in_suspend = 1;
+
+    restore_flags(flags);
+}
+
+static void m3_resume(struct pci_dev *pci_dev)
+{
+    unsigned long flags;
+    int index;
+    int i;
+    struct m3_card *card = pci_dev->driver_data;
+
+    save_flags(flags); /* paranoia */
+    cli();
+    card->in_suspend = 0;
+
+    DPRINTK(DPMOD, "resuming\n");
+
+    /* first lets just bring everything back. .*/
+
+    DPRINTK(DPMOD, "bringing power back on card 0x%p\n",card);
+    m3_outw(card, 0, 0x54);
+    m3_outw(card, 0, 0x56);
+
+    DPRINTK(DPMOD, "restoring pci configs and reseting codec\n");
+    maestro_config(card);
+    m3_assp_halt(card);
+    m3_codec_reset(card, 1);
+
+    DPRINTK(DPMOD, "restoring dsp code card\n");
+    index = 0;
+    for(i = REV_B_CODE_MEMORY_BEGIN ; i <= REV_B_CODE_MEMORY_END; i++)
+        m3_assp_write(card, MEMTYPE_INTERNAL_CODE, i, 
+            card->suspend_mem[index++]);
+    for(i = REV_B_DATA_MEMORY_BEGIN ; i <= REV_B_DATA_MEMORY_END; i++)
+        m3_assp_write(card, MEMTYPE_INTERNAL_DATA, i, 
+            card->suspend_mem[index++]);
+
+     /* tell the dma engine to restart itself */
+    m3_assp_write(card, MEMTYPE_INTERNAL_DATA, 
+        KDATA_DMA_ACTIVE, 0);
+
+    DPRINTK(DPMOD, "resuming dsp\n");
+    m3_assp_continue(card);
+
+    DPRINTK(DPMOD, "enabling ints\n");
+    m3_enable_ints(card);
+
+    /* bring back the old school flavor */
+    for(i = 0; i < SOUND_MIXER_NRDEVICES ; i++) {
+        int state = card->ac97->mixer_state[i];
+        if (!supported_mixer(card->ac97, i)) 
+                continue;
+
+        card->ac97->write_mixer(card->ac97, i, 
+                state & 0xff, (state >> 8) & 0xff);
+    }
+
+    m3_amp_enable(card, 1);
+
+    /* 
+     * now we flip on the music 
+     */
+    for(i=0;i<NR_DSPS;i++) {
+        struct m3_state *s = &card->channels[i];
+        if(s->dev_audio == -1)
+            continue;
+        /*
+         * db->ready makes it so these guys can be
+         * called unconditionally..
+         */
+        DPRINTK(DPMOD, "turning on dacs ind %d\n",i);
+        start_dac(s);    
+        start_adc(s);    
+    }
+
+    restore_flags(flags);
+
+    /* 
+     * all right, we think things are ready, 
+     * wake up people who were using the device 
+     * when we suspended
+     */
+    wake_up(&card->suspend_queue);
+}
+
+MODULE_AUTHOR("Zach Brown <zab@zabbo.net>");
+MODULE_DESCRIPTION("ESS Maestro3/Allegro Driver");
+#ifdef M_DEBUG
+MODULE_PARM(debug,"i");
+#endif
+MODULE_PARM(external_amp,"i");
+
+static struct pci_driver m3_pci_driver = {
+    name:       "ess_m3_audio",
+    id_table:   m3_id_table,
+    probe:      m3_probe,
+    remove:     m3_remove,
+    suspend:    m3_suspend,
+    resume:     m3_resume,
+};
+
+static int __init m3_init_module(void)
+{
+    if (!pci_present())   /* No PCI bus in this machine! */
+        return -ENODEV;
+
+    printk(KERN_INFO PFX "version " DRIVER_VERSION " built at " __TIME__ " " __DATE__ "\n");
+
+    if (register_reboot_notifier(&m3_reboot_nb)) {
+        printk(KERN_WARNING PFX "reboot notifier registration failed\n");
+        return -ENODEV; /* ? */
+    }
+
+    if (!pci_register_driver(&m3_pci_driver)) {
+        pci_unregister_driver(&m3_pci_driver);
+        return -ENODEV;
+    }
+    return 0;
+}
+
+static void __exit m3_cleanup_module(void)
+{
+    pci_unregister_driver(&m3_pci_driver);
+}
+
+module_init(m3_init_module);
+module_exit(m3_cleanup_module);
+
+void check_suspend(struct m3_card *card)
+{
+    DECLARE_WAITQUEUE(wait, current);
+
+    if(!card->in_suspend) 
+        return;
+
+    card->in_suspend++;
+    add_wait_queue(&card->suspend_queue, &wait);
+    current->state = TASK_UNINTERRUPTIBLE;
+    schedule();
+    remove_wait_queue(&card->suspend_queue, &wait);
+    current->state = TASK_RUNNING;
+}
diff -urN linux-2.4.2-pre1/drivers/sound/maestro3.h linux/drivers/sound/maestro3.h
--- linux-2.4.2-pre1/drivers/sound/maestro3.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/sound/maestro3.h	Mon Dec  3 22:27:48 2001
@@ -0,0 +1,821 @@
+/*
+ *      ESS Technology allegro audio driver.
+ *
+ *      Copyright (C) 1992-2000  Don Kim (don.kim@esstech.com)
+ *
+ *      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.
+ *
+ *      Hacked for the maestro3 driver by zab
+ */
+
+// Allegro PCI configuration registers
+#define PCI_LEGACY_AUDIO_CTRL   0x40
+#define SOUND_BLASTER_ENABLE    0x00000001
+#define FM_SYNTHESIS_ENABLE     0x00000002
+#define GAME_PORT_ENABLE        0x00000004
+#define MPU401_IO_ENABLE        0x00000008
+#define MPU401_IRQ_ENABLE       0x00000010
+#define ALIAS_10BIT_IO          0x00000020
+#define SB_DMA_MASK             0x000000C0
+#define SB_DMA_0                0x00000040
+#define SB_DMA_1                0x00000040
+#define SB_DMA_R                0x00000080
+#define SB_DMA_3                0x000000C0
+#define SB_IRQ_MASK             0x00000700
+#define SB_IRQ_5                0x00000000
+#define SB_IRQ_7                0x00000100
+#define SB_IRQ_9                0x00000200
+#define SB_IRQ_10               0x00000300
+#define MIDI_IRQ_MASK           0x00003800
+#define SERIAL_IRQ_ENABLE       0x00004000
+#define DISABLE_LEGACY          0x00008000
+
+#define PCI_ALLEGRO_CONFIG      0x50
+#define SB_ADDR_240             0x00000004
+#define MPU_ADDR_MASK           0x00000018
+#define MPU_ADDR_330            0x00000000
+#define MPU_ADDR_300            0x00000008
+#define MPU_ADDR_320            0x00000010
+#define MPU_ADDR_340            0x00000018
+#define USE_PCI_TIMING          0x00000040
+#define POSTED_WRITE_ENABLE     0x00000080
+#define DMA_POLICY_MASK         0x00000700
+#define DMA_DDMA                0x00000000
+#define DMA_TDMA                0x00000100
+#define DMA_PCPCI               0x00000200
+#define DMA_WBDMA16             0x00000400
+#define DMA_WBDMA4              0x00000500
+#define DMA_WBDMA2              0x00000600
+#define DMA_WBDMA1              0x00000700
+#define DMA_SAFE_GUARD          0x00000800
+#define HI_PERF_GP_ENABLE       0x00001000
+#define PIC_SNOOP_MODE_0        0x00002000
+#define PIC_SNOOP_MODE_1        0x00004000
+#define SOUNDBLASTER_IRQ_MASK   0x00008000
+#define RING_IN_ENABLE          0x00010000
+#define SPDIF_TEST_MODE         0x00020000
+#define CLK_MULT_MODE_SELECT_2  0x00040000
+#define EEPROM_WRITE_ENABLE     0x00080000
+#define CODEC_DIR_IN            0x00100000
+#define HV_BUTTON_FROM_GD       0x00200000
+#define REDUCED_DEBOUNCE        0x00400000
+#define HV_CTRL_ENABLE          0x00800000
+#define SPDIF_ENABLE            0x01000000
+#define CLK_DIV_SELECT          0x06000000
+#define CLK_DIV_BY_48           0x00000000
+#define CLK_DIV_BY_49           0x02000000
+#define CLK_DIV_BY_50           0x04000000
+#define CLK_DIV_RESERVED        0x06000000
+#define PM_CTRL_ENABLE          0x08000000
+#define CLK_MULT_MODE_SELECT    0x30000000
+#define CLK_MULT_MODE_SHIFT     28
+#define CLK_MULT_MODE_0         0x00000000
+#define CLK_MULT_MODE_1         0x10000000
+#define CLK_MULT_MODE_2         0x20000000
+#define CLK_MULT_MODE_3         0x30000000
+#define INT_CLK_SELECT          0x40000000
+#define INT_CLK_MULT_RESET      0x80000000
+
+// M3
+#define INT_CLK_SRC_NOT_PCI     0x00100000
+#define INT_CLK_MULT_ENABLE     0x80000000
+
+#define PCI_ACPI_CONTROL        0x54
+#define PCI_ACPI_D0             0x00000000
+#define PCI_ACPI_D1             0xB4F70000
+#define PCI_ACPI_D2             0xB4F7B4F7
+
+#define PCI_USER_CONFIG         0x58
+#define EXT_PCI_MASTER_ENABLE   0x00000001
+#define SPDIF_OUT_SELECT        0x00000002
+#define TEST_PIN_DIR_CTRL       0x00000004
+#define AC97_CODEC_TEST         0x00000020
+#define TRI_STATE_BUFFER        0x00000080
+#define IN_CLK_12MHZ_SELECT     0x00000100
+#define MULTI_FUNC_DISABLE      0x00000200
+#define EXT_MASTER_PAIR_SEL     0x00000400
+#define PCI_MASTER_SUPPORT      0x00000800
+#define STOP_CLOCK_ENABLE       0x00001000
+#define EAPD_DRIVE_ENABLE       0x00002000
+#define REQ_TRI_STATE_ENABLE    0x00004000
+#define REQ_LOW_ENABLE          0x00008000
+#define MIDI_1_ENABLE           0x00010000
+#define MIDI_2_ENABLE           0x00020000
+#define SB_AUDIO_SYNC           0x00040000
+#define HV_CTRL_TEST            0x00100000
+#define SOUNDBLASTER_TEST       0x00400000
+
+#define PCI_USER_CONFIG_C       0x5C
+
+#define PCI_DDMA_CTRL           0x60
+#define DDMA_ENABLE             0x00000001
+
+
+// Allegro registers
+#define HOST_INT_CTRL           0x18
+#define SB_INT_ENABLE           0x0001
+#define MPU401_INT_ENABLE       0x0002
+#define ASSP_INT_ENABLE         0x0010
+#define RING_INT_ENABLE         0x0020
+#define HV_INT_ENABLE           0x0040
+#define CLKRUN_GEN_ENABLE       0x0100
+#define HV_CTRL_TO_PME          0x0400
+#define SOFTWARE_RESET_ENABLE   0x8000
+
+/*
+ * should be using the above defines, probably.
+ */
+#define REGB_ENABLE_RESET               0x01
+#define REGB_STOP_CLOCK                 0x10
+
+#define HOST_INT_STATUS         0x1A
+#define SB_INT_PENDING          0x01
+#define MPU401_INT_PENDING      0x02
+#define ASSP_INT_PENDING        0x10
+#define RING_INT_PENDING        0x20
+#define HV_INT_PENDING          0x40
+
+#define HARDWARE_VOL_CTRL       0x1B
+#define SHADOW_MIX_REG_VOICE    0x1C
+#define HW_VOL_COUNTER_VOICE    0x1D
+#define SHADOW_MIX_REG_MASTER   0x1E
+#define HW_VOL_COUNTER_MASTER   0x1F
+
+#define CODEC_COMMAND           0x30
+#define CODEC_READ_B            0x80
+
+#define CODEC_STATUS            0x30
+#define CODEC_BUSY_B            0x01
+
+#define CODEC_DATA              0x32
+
+#define RING_BUS_CTRL_A         0x36
+#define RAC_PME_ENABLE          0x0100
+#define RAC_SDFS_ENABLE         0x0200
+#define LAC_PME_ENABLE          0x0400
+#define LAC_SDFS_ENABLE         0x0800
+#define SERIAL_AC_LINK_ENABLE   0x1000
+#define IO_SRAM_ENABLE          0x2000
+#define IIS_INPUT_ENABLE        0x8000
+
+#define RING_BUS_CTRL_B         0x38
+#define SECOND_CODEC_ID_MASK    0x0003
+#define SPDIF_FUNC_ENABLE       0x0010
+#define SECOND_AC_ENABLE        0x0020
+#define SB_MODULE_INTF_ENABLE   0x0040
+#define SSPE_ENABLE             0x0040
+#define M3I_DOCK_ENABLE         0x0080
+
+#define SDO_OUT_DEST_CTRL       0x3A
+#define COMMAND_ADDR_OUT        0x0003
+#define PCM_LR_OUT_LOCAL        0x0000
+#define PCM_LR_OUT_REMOTE       0x0004
+#define PCM_LR_OUT_MUTE         0x0008
+#define PCM_LR_OUT_BOTH         0x000C
+#define LINE1_DAC_OUT_LOCAL     0x0000
+#define LINE1_DAC_OUT_REMOTE    0x0010
+#define LINE1_DAC_OUT_MUTE      0x0020
+#define LINE1_DAC_OUT_BOTH      0x0030
+#define PCM_CLS_OUT_LOCAL       0x0000
+#define PCM_CLS_OUT_REMOTE      0x0040
+#define PCM_CLS_OUT_MUTE        0x0080
+#define PCM_CLS_OUT_BOTH        0x00C0
+#define PCM_RLF_OUT_LOCAL       0x0000
+#define PCM_RLF_OUT_REMOTE      0x0100
+#define PCM_RLF_OUT_MUTE        0x0200
+#define PCM_RLF_OUT_BOTH        0x0300
+#define LINE2_DAC_OUT_LOCAL     0x0000
+#define LINE2_DAC_OUT_REMOTE    0x0400
+#define LINE2_DAC_OUT_MUTE      0x0800
+#define LINE2_DAC_OUT_BOTH      0x0C00
+#define HANDSET_OUT_LOCAL       0x0000
+#define HANDSET_OUT_REMOTE      0x1000
+#define HANDSET_OUT_MUTE        0x2000
+#define HANDSET_OUT_BOTH        0x3000
+#define IO_CTRL_OUT_LOCAL       0x0000
+#define IO_CTRL_OUT_REMOTE      0x4000
+#define IO_CTRL_OUT_MUTE        0x8000
+#define IO_CTRL_OUT_BOTH        0xC000
+
+#define SDO_IN_DEST_CTRL        0x3C
+#define STATUS_ADDR_IN          0x0003
+#define PCM_LR_IN_LOCAL         0x0000
+#define PCM_LR_IN_REMOTE        0x0004
+#define PCM_LR_RESERVED         0x0008
+#define PCM_LR_IN_BOTH          0x000C
+#define LINE1_ADC_IN_LOCAL      0x0000
+#define LINE1_ADC_IN_REMOTE     0x0010
+#define LINE1_ADC_IN_MUTE       0x0020
+#define MIC_ADC_IN_LOCAL        0x0000
+#define MIC_ADC_IN_REMOTE       0x0040
+#define MIC_ADC_IN_MUTE         0x0080
+#define LINE2_DAC_IN_LOCAL      0x0000
+#define LINE2_DAC_IN_REMOTE     0x0400
+#define LINE2_DAC_IN_MUTE       0x0800
+#define HANDSET_IN_LOCAL        0x0000
+#define HANDSET_IN_REMOTE       0x1000
+#define HANDSET_IN_MUTE         0x2000
+#define IO_STATUS_IN_LOCAL      0x0000
+#define IO_STATUS_IN_REMOTE     0x4000
+
+#define SPDIF_IN_CTRL           0x3E
+#define SPDIF_IN_ENABLE         0x0001
+
+#define GPIO_DATA               0x60
+#define GPIO_DATA_MASK          0x0FFF
+#define GPIO_HV_STATUS          0x3000
+#define GPIO_PME_STATUS         0x4000
+
+#define GPIO_MASK               0x64
+#define GPIO_DIRECTION          0x68
+#define GPO_PRIMARY_AC97        0x0001
+#define GPI_LINEOUT_SENSE       0x0004
+#define GPO_SECONDARY_AC97      0x0008
+#define GPI_VOL_DOWN            0x0010
+#define GPI_VOL_UP              0x0020
+#define GPI_IIS_CLK             0x0040
+#define GPI_IIS_LRCLK           0x0080
+#define GPI_IIS_DATA            0x0100
+#define GPI_DOCKING_STATUS      0x0100
+#define GPI_HEADPHONE_SENSE     0x0200
+#define GPO_EXT_AMP_SHUTDOWN    0x1000
+
+// M3
+#define GPO_M3_EXT_AMP_SHUTDN   0x0002
+
+#define ASSP_INDEX_PORT         0x80
+#define ASSP_MEMORY_PORT        0x82
+#define ASSP_DATA_PORT          0x84
+
+#define MPU401_DATA_PORT        0x98
+#define MPU401_STATUS_PORT      0x99
+
+#define CLK_MULT_DATA_PORT      0x9C
+
+#define ASSP_CONTROL_A          0xA2
+#define ASSP_0_WS_ENABLE        0x01
+#define ASSP_CTRL_A_RESERVED1   0x02
+#define ASSP_CTRL_A_RESERVED2   0x04
+#define ASSP_CLK_49MHZ_SELECT   0x08
+#define FAST_PLU_ENABLE         0x10
+#define ASSP_CTRL_A_RESERVED3   0x20
+#define DSP_CLK_36MHZ_SELECT    0x40
+
+#define ASSP_CONTROL_B          0xA4
+#define RESET_ASSP              0x00
+#define RUN_ASSP                0x01
+#define ENABLE_ASSP_CLOCK       0x00
+#define STOP_ASSP_CLOCK         0x10
+#define RESET_TOGGLE            0x40
+
+#define ASSP_CONTROL_C          0xA6
+#define ASSP_HOST_INT_ENABLE    0x01
+#define FM_ADDR_REMAP_DISABLE   0x02
+#define HOST_WRITE_PORT_ENABLE  0x08
+
+#define ASSP_HOST_INT_STATUS    0xAC
+#define DSP2HOST_REQ_PIORECORD  0x01
+#define DSP2HOST_REQ_I2SRATE    0x02
+#define DSP2HOST_REQ_TIMER      0x04
+
+// AC97 registers
+// XXX fix this crap up
+/*#define AC97_RESET              0x00*/
+
+#define AC97_VOL_MUTE_B         0x8000
+#define AC97_VOL_M              0x1F
+#define AC97_LEFT_VOL_S         8
+
+#define AC97_MASTER_VOL         0x02
+#define AC97_LINE_LEVEL_VOL     0x04
+#define AC97_MASTER_MONO_VOL    0x06
+#define AC97_PC_BEEP_VOL        0x0A
+#define AC97_PC_BEEP_VOL_M      0x0F
+#define AC97_SROUND_MASTER_VOL  0x38
+#define AC97_PC_BEEP_VOL_S      1
+
+/*#define AC97_PHONE_VOL          0x0C
+#define AC97_MIC_VOL            0x0E*/
+#define AC97_MIC_20DB_ENABLE    0x40
+
+/*#define AC97_LINEIN_VOL         0x10
+#define AC97_CD_VOL             0x12
+#define AC97_VIDEO_VOL          0x14
+#define AC97_AUX_VOL            0x16*/
+#define AC97_PCM_OUT_VOL        0x18
+/*#define AC97_RECORD_SELECT      0x1A*/
+#define AC97_RECORD_MIC         0x00
+#define AC97_RECORD_CD          0x01
+#define AC97_RECORD_VIDEO       0x02
+#define AC97_RECORD_AUX         0x03
+#define AC97_RECORD_MONO_MUX    0x02
+#define AC97_RECORD_DIGITAL     0x03
+#define AC97_RECORD_LINE        0x04
+#define AC97_RECORD_STEREO      0x05
+#define AC97_RECORD_MONO        0x06
+#define AC97_RECORD_PHONE       0x07
+
+/*#define AC97_RECORD_GAIN        0x1C*/
+#define AC97_RECORD_VOL_M       0x0F
+
+/*#define AC97_GENERAL_PURPOSE    0x20*/
+#define AC97_POWER_DOWN_CTRL    0x26
+#define AC97_ADC_READY          0x0001
+#define AC97_DAC_READY          0x0002
+#define AC97_ANALOG_READY       0x0004
+#define AC97_VREF_ON            0x0008
+#define AC97_PR0                0x0100
+#define AC97_PR1                0x0200
+#define AC97_PR2                0x0400
+#define AC97_PR3                0x0800
+#define AC97_PR4                0x1000
+
+#define AC97_RESERVED1          0x28
+
+#define AC97_VENDOR_TEST        0x5A
+
+#define AC97_CLOCK_DELAY        0x5C
+#define AC97_LINEOUT_MUX_SEL    0x0001
+#define AC97_MONO_MUX_SEL       0x0002
+#define AC97_CLOCK_DELAY_SEL    0x1F
+#define AC97_DAC_CDS_SHIFT      6
+#define AC97_ADC_CDS_SHIFT      11
+
+#define AC97_MULTI_CHANNEL_SEL  0x74
+
+/*#define AC97_VENDOR_ID1         0x7C
+#define AC97_VENDOR_ID2         0x7E*/
+
+/*
+ * ASSP control regs
+ */
+#define DSP_PORT_TIMER_COUNT    0x06
+
+#define DSP_PORT_MEMORY_INDEX   0x80
+
+#define DSP_PORT_MEMORY_TYPE    0x82
+#define MEMTYPE_INTERNAL_CODE   0x0002
+#define MEMTYPE_INTERNAL_DATA   0x0003
+#define MEMTYPE_MASK            0x0003
+
+#define DSP_PORT_MEMORY_DATA    0x84
+
+#define DSP_PORT_CONTROL_REG_A  0xA2
+#define DSP_PORT_CONTROL_REG_B  0xA4
+#define DSP_PORT_CONTROL_REG_C  0xA6
+
+#define REV_A_CODE_MEMORY_BEGIN         0x0000
+#define REV_A_CODE_MEMORY_END           0x0FFF
+#define REV_A_CODE_MEMORY_UNIT_LENGTH   0x0040
+#define REV_A_CODE_MEMORY_LENGTH        (REV_A_CODE_MEMORY_END - REV_A_CODE_MEMORY_BEGIN + 1)
+
+#define REV_B_CODE_MEMORY_BEGIN         0x0000
+#define REV_B_CODE_MEMORY_END           0x0BFF
+#define REV_B_CODE_MEMORY_UNIT_LENGTH   0x0040
+#define REV_B_CODE_MEMORY_LENGTH        (REV_B_CODE_MEMORY_END - REV_B_CODE_MEMORY_BEGIN + 1)
+
+#define REV_A_DATA_MEMORY_BEGIN         0x1000
+#define REV_A_DATA_MEMORY_END           0x2FFF
+#define REV_A_DATA_MEMORY_UNIT_LENGTH   0x0080
+#define REV_A_DATA_MEMORY_LENGTH        (REV_A_DATA_MEMORY_END - REV_A_DATA_MEMORY_BEGIN + 1)
+
+#define REV_B_DATA_MEMORY_BEGIN         0x1000
+#define REV_B_DATA_MEMORY_END           0x2BFF
+#define REV_B_DATA_MEMORY_UNIT_LENGTH   0x0080
+#define REV_B_DATA_MEMORY_LENGTH        (REV_B_DATA_MEMORY_END - REV_B_DATA_MEMORY_BEGIN + 1)
+
+
+#define NUM_UNITS_KERNEL_CODE          16
+#define NUM_UNITS_KERNEL_DATA           2
+
+#define NUM_UNITS_KERNEL_CODE_WITH_HSP 16
+#define NUM_UNITS_KERNEL_DATA_WITH_HSP  5
+
+/*
+ * Kernel data layout
+ */
+
+#define DP_SHIFT_COUNT                  7
+
+#define KDATA_BASE_ADDR                 0x1000
+#define KDATA_BASE_ADDR2                0x1080
+
+#define KDATA_TASK0                     (KDATA_BASE_ADDR + 0x0000)
+#define KDATA_TASK1                     (KDATA_BASE_ADDR + 0x0001)
+#define KDATA_TASK2                     (KDATA_BASE_ADDR + 0x0002)
+#define KDATA_TASK3                     (KDATA_BASE_ADDR + 0x0003)
+#define KDATA_TASK4                     (KDATA_BASE_ADDR + 0x0004)
+#define KDATA_TASK5                     (KDATA_BASE_ADDR + 0x0005)
+#define KDATA_TASK6                     (KDATA_BASE_ADDR + 0x0006)
+#define KDATA_TASK7                     (KDATA_BASE_ADDR + 0x0007)
+#define KDATA_TASK_ENDMARK              (KDATA_BASE_ADDR + 0x0008)
+
+#define KDATA_CURRENT_TASK              (KDATA_BASE_ADDR + 0x0009)
+#define KDATA_TASK_SWITCH               (KDATA_BASE_ADDR + 0x000A)
+
+#define KDATA_INSTANCE0_POS3D           (KDATA_BASE_ADDR + 0x000B)
+#define KDATA_INSTANCE1_POS3D           (KDATA_BASE_ADDR + 0x000C)
+#define KDATA_INSTANCE2_POS3D           (KDATA_BASE_ADDR + 0x000D)
+#define KDATA_INSTANCE3_POS3D           (KDATA_BASE_ADDR + 0x000E)
+#define KDATA_INSTANCE4_POS3D           (KDATA_BASE_ADDR + 0x000F)
+#define KDATA_INSTANCE5_POS3D           (KDATA_BASE_ADDR + 0x0010)
+#define KDATA_INSTANCE6_POS3D           (KDATA_BASE_ADDR + 0x0011)
+#define KDATA_INSTANCE7_POS3D           (KDATA_BASE_ADDR + 0x0012)
+#define KDATA_INSTANCE8_POS3D           (KDATA_BASE_ADDR + 0x0013)
+#define KDATA_INSTANCE_POS3D_ENDMARK    (KDATA_BASE_ADDR + 0x0014)
+
+#define KDATA_INSTANCE0_SPKVIRT         (KDATA_BASE_ADDR + 0x0015)
+#define KDATA_INSTANCE_SPKVIRT_ENDMARK  (KDATA_BASE_ADDR + 0x0016)
+
+#define KDATA_INSTANCE0_SPDIF           (KDATA_BASE_ADDR + 0x0017)
+#define KDATA_INSTANCE_SPDIF_ENDMARK    (KDATA_BASE_ADDR + 0x0018)
+
+#define KDATA_INSTANCE0_MODEM           (KDATA_BASE_ADDR + 0x0019)
+#define KDATA_INSTANCE_MODEM_ENDMARK    (KDATA_BASE_ADDR + 0x001A)
+
+#define KDATA_INSTANCE0_SRC             (KDATA_BASE_ADDR + 0x001B)
+#define KDATA_INSTANCE1_SRC             (KDATA_BASE_ADDR + 0x001C)
+#define KDATA_INSTANCE_SRC_ENDMARK      (KDATA_BASE_ADDR + 0x001D)
+
+#define KDATA_INSTANCE0_MINISRC         (KDATA_BASE_ADDR + 0x001E)
+#define KDATA_INSTANCE1_MINISRC         (KDATA_BASE_ADDR + 0x001F)
+#define KDATA_INSTANCE2_MINISRC         (KDATA_BASE_ADDR + 0x0020)
+#define KDATA_INSTANCE3_MINISRC         (KDATA_BASE_ADDR + 0x0021)
+#define KDATA_INSTANCE_MINISRC_ENDMARK  (KDATA_BASE_ADDR + 0x0022)
+
+#define KDATA_INSTANCE0_CPYTHRU         (KDATA_BASE_ADDR + 0x0023)
+#define KDATA_INSTANCE1_CPYTHRU         (KDATA_BASE_ADDR + 0x0024)
+#define KDATA_INSTANCE_CPYTHRU_ENDMARK  (KDATA_BASE_ADDR + 0x0025)
+
+#define KDATA_CURRENT_DMA               (KDATA_BASE_ADDR + 0x0026)
+#define KDATA_DMA_SWITCH                (KDATA_BASE_ADDR + 0x0027)
+#define KDATA_DMA_ACTIVE                (KDATA_BASE_ADDR + 0x0028)
+
+#define KDATA_DMA_XFER0                 (KDATA_BASE_ADDR + 0x0029)
+#define KDATA_DMA_XFER1                 (KDATA_BASE_ADDR + 0x002A)
+#define KDATA_DMA_XFER2                 (KDATA_BASE_ADDR + 0x002B)
+#define KDATA_DMA_XFER3                 (KDATA_BASE_ADDR + 0x002C)
+#define KDATA_DMA_XFER4                 (KDATA_BASE_ADDR + 0x002D)
+#define KDATA_DMA_XFER5                 (KDATA_BASE_ADDR + 0x002E)
+#define KDATA_DMA_XFER6                 (KDATA_BASE_ADDR + 0x002F)
+#define KDATA_DMA_XFER7                 (KDATA_BASE_ADDR + 0x0030)
+#define KDATA_DMA_XFER8                 (KDATA_BASE_ADDR + 0x0031)
+#define KDATA_DMA_XFER_ENDMARK          (KDATA_BASE_ADDR + 0x0032)
+
+#define KDATA_I2S_SAMPLE_COUNT          (KDATA_BASE_ADDR + 0x0033)
+#define KDATA_I2S_INT_METER             (KDATA_BASE_ADDR + 0x0034)
+#define KDATA_I2S_ACTIVE                (KDATA_BASE_ADDR + 0x0035)
+
+#define KDATA_TIMER_COUNT_RELOAD        (KDATA_BASE_ADDR + 0x0036)
+#define KDATA_TIMER_COUNT_CURRENT       (KDATA_BASE_ADDR + 0x0037)
+
+#define KDATA_HALT_SYNCH_CLIENT         (KDATA_BASE_ADDR + 0x0038)
+#define KDATA_HALT_SYNCH_DMA            (KDATA_BASE_ADDR + 0x0039)
+#define KDATA_HALT_ACKNOWLEDGE          (KDATA_BASE_ADDR + 0x003A)
+
+#define KDATA_ADC1_XFER0                (KDATA_BASE_ADDR + 0x003B)
+#define KDATA_ADC1_XFER_ENDMARK         (KDATA_BASE_ADDR + 0x003C)
+#define KDATA_ADC1_LEFT_VOLUME			(KDATA_BASE_ADDR + 0x003D)
+#define KDATA_ADC1_RIGHT_VOLUME  		(KDATA_BASE_ADDR + 0x003E)
+#define KDATA_ADC1_LEFT_SUR_VOL			(KDATA_BASE_ADDR + 0x003F)
+#define KDATA_ADC1_RIGHT_SUR_VOL		(KDATA_BASE_ADDR + 0x0040)
+
+#define KDATA_ADC2_XFER0                (KDATA_BASE_ADDR + 0x0041)
+#define KDATA_ADC2_XFER_ENDMARK         (KDATA_BASE_ADDR + 0x0042)
+#define KDATA_ADC2_LEFT_VOLUME			(KDATA_BASE_ADDR + 0x0043)
+#define KDATA_ADC2_RIGHT_VOLUME			(KDATA_BASE_ADDR + 0x0044)
+#define KDATA_ADC2_LEFT_SUR_VOL			(KDATA_BASE_ADDR + 0x0045)
+#define KDATA_ADC2_RIGHT_SUR_VOL		(KDATA_BASE_ADDR + 0x0046)
+
+#define KDATA_CD_XFER0					(KDATA_BASE_ADDR + 0x0047)					
+#define KDATA_CD_XFER_ENDMARK			(KDATA_BASE_ADDR + 0x0048)
+#define KDATA_CD_LEFT_VOLUME			(KDATA_BASE_ADDR + 0x0049)
+#define KDATA_CD_RIGHT_VOLUME			(KDATA_BASE_ADDR + 0x004A)
+#define KDATA_CD_LEFT_SUR_VOL			(KDATA_BASE_ADDR + 0x004B)
+#define KDATA_CD_RIGHT_SUR_VOL			(KDATA_BASE_ADDR + 0x004C)
+
+#define KDATA_MIC_XFER0					(KDATA_BASE_ADDR + 0x004D)
+#define KDATA_MIC_XFER_ENDMARK			(KDATA_BASE_ADDR + 0x004E)
+#define KDATA_MIC_VOLUME				(KDATA_BASE_ADDR + 0x004F)
+#define KDATA_MIC_SUR_VOL				(KDATA_BASE_ADDR + 0x0050)
+
+#define KDATA_I2S_XFER0                 (KDATA_BASE_ADDR + 0x0051)
+#define KDATA_I2S_XFER_ENDMARK          (KDATA_BASE_ADDR + 0x0052)
+
+#define KDATA_CHI_XFER0                 (KDATA_BASE_ADDR + 0x0053)
+#define KDATA_CHI_XFER_ENDMARK          (KDATA_BASE_ADDR + 0x0054)
+
+#define KDATA_SPDIF_XFER                (KDATA_BASE_ADDR + 0x0055)
+#define KDATA_SPDIF_CURRENT_FRAME       (KDATA_BASE_ADDR + 0x0056)
+#define KDATA_SPDIF_FRAME0              (KDATA_BASE_ADDR + 0x0057)
+#define KDATA_SPDIF_FRAME1              (KDATA_BASE_ADDR + 0x0058)
+#define KDATA_SPDIF_FRAME2              (KDATA_BASE_ADDR + 0x0059)
+
+#define KDATA_SPDIF_REQUEST             (KDATA_BASE_ADDR + 0x005A)
+#define KDATA_SPDIF_TEMP                (KDATA_BASE_ADDR + 0x005B)
+
+#define KDATA_SPDIFIN_XFER0             (KDATA_BASE_ADDR + 0x005C)
+#define KDATA_SPDIFIN_XFER_ENDMARK      (KDATA_BASE_ADDR + 0x005D)
+#define KDATA_SPDIFIN_INT_METER         (KDATA_BASE_ADDR + 0x005E)
+
+#define KDATA_DSP_RESET_COUNT           (KDATA_BASE_ADDR + 0x005F)
+#define KDATA_DEBUG_OUTPUT              (KDATA_BASE_ADDR + 0x0060)
+
+#define KDATA_KERNEL_ISR_LIST           (KDATA_BASE_ADDR + 0x0061)
+
+#define KDATA_KERNEL_ISR_CBSR1          (KDATA_BASE_ADDR + 0x0062)
+#define KDATA_KERNEL_ISR_CBER1          (KDATA_BASE_ADDR + 0x0063)
+#define KDATA_KERNEL_ISR_CBCR           (KDATA_BASE_ADDR + 0x0064)
+#define KDATA_KERNEL_ISR_AR0            (KDATA_BASE_ADDR + 0x0065)
+#define KDATA_KERNEL_ISR_AR1            (KDATA_BASE_ADDR + 0x0066)
+#define KDATA_KERNEL_ISR_AR2            (KDATA_BASE_ADDR + 0x0067)
+#define KDATA_KERNEL_ISR_AR3            (KDATA_BASE_ADDR + 0x0068)
+#define KDATA_KERNEL_ISR_AR4            (KDATA_BASE_ADDR + 0x0069)
+#define KDATA_KERNEL_ISR_AR5            (KDATA_BASE_ADDR + 0x006A)
+#define KDATA_KERNEL_ISR_BRCR           (KDATA_BASE_ADDR + 0x006B)
+#define KDATA_KERNEL_ISR_PASR           (KDATA_BASE_ADDR + 0x006C)
+#define KDATA_KERNEL_ISR_PAER           (KDATA_BASE_ADDR + 0x006D)
+
+#define KDATA_CLIENT_SCRATCH0           (KDATA_BASE_ADDR + 0x006E)
+#define KDATA_CLIENT_SCRATCH1           (KDATA_BASE_ADDR + 0x006F)
+#define KDATA_KERNEL_SCRATCH            (KDATA_BASE_ADDR + 0x0070)
+#define KDATA_KERNEL_ISR_SCRATCH        (KDATA_BASE_ADDR + 0x0071)
+
+#define KDATA_OUEUE_LEFT                (KDATA_BASE_ADDR + 0x0072)
+#define KDATA_QUEUE_RIGHT               (KDATA_BASE_ADDR + 0x0073)
+
+#define KDATA_ADC1_REQUEST              (KDATA_BASE_ADDR + 0x0074)
+#define KDATA_ADC2_REQUEST              (KDATA_BASE_ADDR + 0x0075)
+#define KDATA_CD_REQUEST				(KDATA_BASE_ADDR + 0x0076)
+#define KDATA_MIC_REQUEST				(KDATA_BASE_ADDR + 0x0077)
+
+#define KDATA_ADC1_MIXER_REQUEST        (KDATA_BASE_ADDR + 0x0078)
+#define KDATA_ADC2_MIXER_REQUEST        (KDATA_BASE_ADDR + 0x0079)
+#define KDATA_CD_MIXER_REQUEST			(KDATA_BASE_ADDR + 0x007A)
+#define KDATA_MIC_MIXER_REQUEST			(KDATA_BASE_ADDR + 0x007B)
+#define KDATA_MIC_SYNC_COUNTER			(KDATA_BASE_ADDR + 0x007C)
+
+/*
+ * second 'segment' (?) reserved for mixer
+ * buffers..
+ */
+
+#define KDATA_MIXER_WORD0               (KDATA_BASE_ADDR2 + 0x0000)
+#define KDATA_MIXER_WORD1               (KDATA_BASE_ADDR2 + 0x0001)
+#define KDATA_MIXER_WORD2               (KDATA_BASE_ADDR2 + 0x0002)
+#define KDATA_MIXER_WORD3               (KDATA_BASE_ADDR2 + 0x0003)
+#define KDATA_MIXER_WORD4               (KDATA_BASE_ADDR2 + 0x0004)
+#define KDATA_MIXER_WORD5               (KDATA_BASE_ADDR2 + 0x0005)
+#define KDATA_MIXER_WORD6               (KDATA_BASE_ADDR2 + 0x0006)
+#define KDATA_MIXER_WORD7               (KDATA_BASE_ADDR2 + 0x0007)
+#define KDATA_MIXER_WORD8               (KDATA_BASE_ADDR2 + 0x0008)
+#define KDATA_MIXER_WORD9               (KDATA_BASE_ADDR2 + 0x0009)
+#define KDATA_MIXER_WORDA               (KDATA_BASE_ADDR2 + 0x000A)
+#define KDATA_MIXER_WORDB               (KDATA_BASE_ADDR2 + 0x000B)
+#define KDATA_MIXER_WORDC               (KDATA_BASE_ADDR2 + 0x000C)
+#define KDATA_MIXER_WORDD               (KDATA_BASE_ADDR2 + 0x000D)
+#define KDATA_MIXER_WORDE               (KDATA_BASE_ADDR2 + 0x000E)
+#define KDATA_MIXER_WORDF               (KDATA_BASE_ADDR2 + 0x000F)
+
+#define KDATA_MIXER_XFER0               (KDATA_BASE_ADDR2 + 0x0010)
+#define KDATA_MIXER_XFER1               (KDATA_BASE_ADDR2 + 0x0011)
+#define KDATA_MIXER_XFER2               (KDATA_BASE_ADDR2 + 0x0012)
+#define KDATA_MIXER_XFER3               (KDATA_BASE_ADDR2 + 0x0013)
+#define KDATA_MIXER_XFER4               (KDATA_BASE_ADDR2 + 0x0014)
+#define KDATA_MIXER_XFER5               (KDATA_BASE_ADDR2 + 0x0015)
+#define KDATA_MIXER_XFER6               (KDATA_BASE_ADDR2 + 0x0016)
+#define KDATA_MIXER_XFER7               (KDATA_BASE_ADDR2 + 0x0017)
+#define KDATA_MIXER_XFER8               (KDATA_BASE_ADDR2 + 0x0018)
+#define KDATA_MIXER_XFER9               (KDATA_BASE_ADDR2 + 0x0019)
+#define KDATA_MIXER_XFER_ENDMARK        (KDATA_BASE_ADDR2 + 0x001A)
+
+#define KDATA_MIXER_TASK_NUMBER         (KDATA_BASE_ADDR2 + 0x001B)
+#define KDATA_CURRENT_MIXER             (KDATA_BASE_ADDR2 + 0x001C)
+#define KDATA_MIXER_ACTIVE              (KDATA_BASE_ADDR2 + 0x001D)
+#define KDATA_MIXER_BANK_STATUS         (KDATA_BASE_ADDR2 + 0x001E)
+#define KDATA_DAC_LEFT_VOLUME	        (KDATA_BASE_ADDR2 + 0x001F)
+#define KDATA_DAC_RIGHT_VOLUME          (KDATA_BASE_ADDR2 + 0x0020)
+
+#define MAX_INSTANCE_MINISRC            (KDATA_INSTANCE_MINISRC_ENDMARK - KDATA_INSTANCE0_MINISRC)
+#define MAX_VIRTUAL_DMA_CHANNELS        (KDATA_DMA_XFER_ENDMARK - KDATA_DMA_XFER0)
+#define MAX_VIRTUAL_MIXER_CHANNELS      (KDATA_MIXER_XFER_ENDMARK - KDATA_MIXER_XFER0)
+#define MAX_VIRTUAL_ADC1_CHANNELS       (KDATA_ADC1_XFER_ENDMARK - KDATA_ADC1_XFER0)
+
+/*
+ * client data area offsets
+ */
+#define CDATA_INSTANCE_READY            0x00
+
+#define CDATA_HOST_SRC_ADDRL            0x01
+#define CDATA_HOST_SRC_ADDRH            0x02
+#define CDATA_HOST_SRC_END_PLUS_1L      0x03
+#define CDATA_HOST_SRC_END_PLUS_1H      0x04
+#define CDATA_HOST_SRC_CURRENTL         0x05
+#define CDATA_HOST_SRC_CURRENTH         0x06
+
+#define CDATA_IN_BUF_CONNECT            0x07
+#define CDATA_OUT_BUF_CONNECT           0x08
+
+#define CDATA_IN_BUF_BEGIN              0x09
+#define CDATA_IN_BUF_END_PLUS_1         0x0A
+#define CDATA_IN_BUF_HEAD               0x0B
+#define CDATA_IN_BUF_TAIL               0x0C
+#define CDATA_OUT_BUF_BEGIN             0x0D
+#define CDATA_OUT_BUF_END_PLUS_1        0x0E
+#define CDATA_OUT_BUF_HEAD              0x0F
+#define CDATA_OUT_BUF_TAIL              0x10
+
+#define CDATA_DMA_CONTROL               0x11
+#define CDATA_RESERVED                  0x12
+
+#define CDATA_FREQUENCY                 0x13
+#define CDATA_LEFT_VOLUME               0x14
+#define CDATA_RIGHT_VOLUME              0x15
+#define CDATA_LEFT_SUR_VOL              0x16
+#define CDATA_RIGHT_SUR_VOL             0x17
+
+#define CDATA_HEADER_LEN                0x18
+
+#define SRC3_DIRECTION_OFFSET           CDATA_HEADER_LEN
+#define SRC3_MODE_OFFSET                (CDATA_HEADER_LEN + 1)
+#define SRC3_WORD_LENGTH_OFFSET         (CDATA_HEADER_LEN + 2)
+#define SRC3_PARAMETER_OFFSET           (CDATA_HEADER_LEN + 3)
+#define SRC3_COEFF_ADDR_OFFSET          (CDATA_HEADER_LEN + 8)
+#define SRC3_FILTAP_ADDR_OFFSET         (CDATA_HEADER_LEN + 10)
+#define SRC3_TEMP_INBUF_ADDR_OFFSET     (CDATA_HEADER_LEN + 16)
+#define SRC3_TEMP_OUTBUF_ADDR_OFFSET    (CDATA_HEADER_LEN + 17)
+
+#define MINISRC_IN_BUFFER_SIZE   ( 0x50 * 2 )
+#define MINISRC_OUT_BUFFER_SIZE  ( 0x50 * 2 * 2)
+#define MINISRC_OUT_BUFFER_SIZE  ( 0x50 * 2 * 2)
+#define MINISRC_TMP_BUFFER_SIZE  ( 112 + ( MINISRC_BIQUAD_STAGE * 3 + 4 ) * 2 * 2 )
+#define MINISRC_BIQUAD_STAGE    2
+#define MINISRC_COEF_LOC          0X175
+
+#define DMACONTROL_BLOCK_MASK           0x000F
+#define  DMAC_BLOCK0_SELECTOR           0x0000
+#define  DMAC_BLOCK1_SELECTOR           0x0001
+#define  DMAC_BLOCK2_SELECTOR           0x0002
+#define  DMAC_BLOCK3_SELECTOR           0x0003
+#define  DMAC_BLOCK4_SELECTOR           0x0004
+#define  DMAC_BLOCK5_SELECTOR           0x0005
+#define  DMAC_BLOCK6_SELECTOR           0x0006
+#define  DMAC_BLOCK7_SELECTOR           0x0007
+#define  DMAC_BLOCK8_SELECTOR           0x0008
+#define  DMAC_BLOCK9_SELECTOR           0x0009
+#define  DMAC_BLOCKA_SELECTOR           0x000A
+#define  DMAC_BLOCKB_SELECTOR           0x000B
+#define  DMAC_BLOCKC_SELECTOR           0x000C
+#define  DMAC_BLOCKD_SELECTOR           0x000D
+#define  DMAC_BLOCKE_SELECTOR           0x000E
+#define  DMAC_BLOCKF_SELECTOR           0x000F
+#define DMACONTROL_PAGE_MASK            0x00F0
+#define  DMAC_PAGE0_SELECTOR            0x0030
+#define  DMAC_PAGE1_SELECTOR            0x0020
+#define  DMAC_PAGE2_SELECTOR            0x0010
+#define  DMAC_PAGE3_SELECTOR            0x0000
+#define DMACONTROL_AUTOREPEAT           0x1000
+#define DMACONTROL_STOPPED              0x2000
+#define DMACONTROL_DIRECTION            0x0100
+
+
+/*
+ * DSP Code images
+ */
+
+u16 assp_kernel_image[] = {
+    0x7980, 0x0030, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x00FB, 0x7980, 0x00DD, 0x7980, 0x03B4, 
+    0x7980, 0x0332, 0x7980, 0x0287, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 
+    0x7980, 0x031A, 0x7980, 0x03B4, 0x7980, 0x022F, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 
+    0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x0063, 0x7980, 0x006B, 0x7980, 0x03B4, 0x7980, 0x03B4, 
+    0xBF80, 0x2C7C, 0x8806, 0x8804, 0xBE40, 0xBC20, 0xAE09, 0x1000, 0xAE0A, 0x0001, 0x6938, 0xEB08, 
+    0x0053, 0x695A, 0xEB08, 0x00D6, 0x0009, 0x8B88, 0x6980, 0xE388, 0x0036, 0xBE30, 0xBC20, 0x6909, 
+    0xB801, 0x9009, 0xBE41, 0xBE41, 0x6928, 0xEB88, 0x0078, 0xBE41, 0xBE40, 0x7980, 0x0038, 0xBE41, 
+    0xBE41, 0x903A, 0x6938, 0xE308, 0x0056, 0x903A, 0xBE41, 0xBE40, 0xEF00, 0x903A, 0x6939, 0xE308, 
+    0x005E, 0x903A, 0xEF00, 0x690B, 0x660C, 0xEF8C, 0x690A, 0x660C, 0x620B, 0x6609, 0xEF00, 0x6910, 
+    0x660F, 0xEF04, 0xE388, 0x0075, 0x690E, 0x660F, 0x6210, 0x660D, 0xEF00, 0x690E, 0x660D, 0xEF00, 
+    0xAE70, 0x0001, 0xBC20, 0xAE27, 0x0001, 0x6939, 0xEB08, 0x005D, 0x6926, 0xB801, 0x9026, 0x0026, 
+    0x8B88, 0x6980, 0xE388, 0x00CB, 0x9028, 0x0D28, 0x4211, 0xE100, 0x007A, 0x4711, 0xE100, 0x00A0, 
+    0x7A80, 0x0063, 0xB811, 0x660A, 0x6209, 0xE304, 0x007A, 0x0C0B, 0x4005, 0x100A, 0xBA01, 0x9012, 
+    0x0C12, 0x4002, 0x7980, 0x00AF, 0x7A80, 0x006B, 0xBE02, 0x620E, 0x660D, 0xBA10, 0xE344, 0x007A, 
+    0x0C10, 0x4005, 0x100E, 0xBA01, 0x9012, 0x0C12, 0x4002, 0x1003, 0xBA02, 0x9012, 0x0C12, 0x4000, 
+    0x1003, 0xE388, 0x00BA, 0x1004, 0x7980, 0x00BC, 0x1004, 0xBA01, 0x9012, 0x0C12, 0x4001, 0x0C05, 
+    0x4003, 0x0C06, 0x4004, 0x1011, 0xBFB0, 0x01FF, 0x9012, 0x0C12, 0x4006, 0xBC20, 0xEF00, 0xAE26, 
+    0x1028, 0x6970, 0xBFD0, 0x0001, 0x9070, 0xE388, 0x007A, 0xAE28, 0x0000, 0xEF00, 0xAE70, 0x0300, 
+    0x0C70, 0xB00C, 0xAE5A, 0x0000, 0xEF00, 0x7A80, 0x038A, 0x697F, 0xB801, 0x907F, 0x0056, 0x8B88, 
+    0x0CA0, 0xB008, 0xAF71, 0xB000, 0x4E71, 0xE200, 0x00F3, 0xAE56, 0x1057, 0x0056, 0x0CA0, 0xB008, 
+    0x8056, 0x7980, 0x03A1, 0x0810, 0xBFA0, 0x1059, 0xE304, 0x03A1, 0x8056, 0x7980, 0x03A1, 0x7A80, 
+    0x038A, 0xBF01, 0xBE43, 0xBE59, 0x907C, 0x6937, 0xE388, 0x010D, 0xBA01, 0xE308, 0x010C, 0xAE71, 
+    0x0004, 0x0C71, 0x5000, 0x6936, 0x9037, 0xBF0A, 0x109E, 0x8B8A, 0xAF80, 0x8014, 0x4C80, 0xBF0A, 
+    0x0560, 0xF500, 0xBF0A, 0x0520, 0xB900, 0xBB17, 0x90A0, 0x6917, 0xE388, 0x0148, 0x0D17, 0xE100, 
+    0x0127, 0xBF0C, 0x0578, 0xBF0D, 0x057C, 0x7980, 0x012B, 0xBF0C, 0x0538, 0xBF0D, 0x053C, 0x6900, 
+    0xE308, 0x0135, 0x8B8C, 0xBE59, 0xBB07, 0x90A0, 0xBC20, 0x7980, 0x0157, 0x030C, 0x8B8B, 0xB903, 
+    0x8809, 0xBEC6, 0x013E, 0x69AC, 0x90AB, 0x69AD, 0x90AB, 0x0813, 0x660A, 0xE344, 0x0144, 0x0309, 
+    0x830C, 0xBC20, 0x7980, 0x0157, 0x6955, 0xE388, 0x0157, 0x7C38, 0xBF0B, 0x0578, 0xF500, 0xBF0B, 
+    0x0538, 0xB907, 0x8809, 0xBEC6, 0x0156, 0x10AB, 0x90AA, 0x6974, 0xE388, 0x0163, 0xAE72, 0x0540, 
+    0xF500, 0xAE72, 0x0500, 0xAE61, 0x103B, 0x7A80, 0x02F6, 0x6978, 0xE388, 0x0182, 0x8B8C, 0xBF0C, 
+    0x0560, 0xE500, 0x7C40, 0x0814, 0xBA20, 0x8812, 0x733D, 0x7A80, 0x0380, 0x733E, 0x7A80, 0x0380, 
+    0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, 0x0814, 0xBA2C, 0x8812, 0x733F, 0x7A80, 0x0380, 0x7340, 
+    0x7A80, 0x0380, 0x6975, 0xE388, 0x018E, 0xAE72, 0x0548, 0xF500, 0xAE72, 0x0508, 0xAE61, 0x1041, 
+    0x7A80, 0x02F6, 0x6979, 0xE388, 0x01AD, 0x8B8C, 0xBF0C, 0x0560, 0xE500, 0x7C40, 0x0814, 0xBA18, 
+    0x8812, 0x7343, 0x7A80, 0x0380, 0x7344, 0x7A80, 0x0380, 0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, 
+    0x0814, 0xBA24, 0x8812, 0x7345, 0x7A80, 0x0380, 0x7346, 0x7A80, 0x0380, 0x6976, 0xE388, 0x01B9, 
+    0xAE72, 0x0558, 0xF500, 0xAE72, 0x0518, 0xAE61, 0x1047, 0x7A80, 0x02F6, 0x697A, 0xE388, 0x01D8, 
+    0x8B8C, 0xBF0C, 0x0560, 0xE500, 0x7C40, 0x0814, 0xBA08, 0x8812, 0x7349, 0x7A80, 0x0380, 0x734A, 
+    0x7A80, 0x0380, 0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, 0x0814, 0xBA14, 0x8812, 0x734B, 0x7A80, 
+    0x0380, 0x734C, 0x7A80, 0x0380, 0xBC21, 0xAE1C, 0x1090, 0x8B8A, 0xBF0A, 0x0560, 0xE500, 0x7C40, 
+    0x0812, 0xB804, 0x8813, 0x8B8D, 0xBF0D, 0x056C, 0xE500, 0x7C40, 0x0815, 0xB804, 0x8811, 0x7A80, 
+    0x034A, 0x8B8A, 0xBF0A, 0x0560, 0xE500, 0x7C40, 0x731F, 0xB903, 0x8809, 0xBEC6, 0x01F9, 0x548A, 
+    0xBE03, 0x98A0, 0x7320, 0xB903, 0x8809, 0xBEC6, 0x0201, 0x548A, 0xBE03, 0x98A0, 0x1F20, 0x2F1F, 
+    0x9826, 0xBC20, 0x6935, 0xE388, 0x03A1, 0x6933, 0xB801, 0x9033, 0xBFA0, 0x02EE, 0xE308, 0x03A1, 
+    0x9033, 0xBF00, 0x6951, 0xE388, 0x021F, 0x7334, 0xBE80, 0x5760, 0xBE03, 0x9F7E, 0xBE59, 0x9034, 
+    0x697E, 0x0D51, 0x9013, 0xBC20, 0x695C, 0xE388, 0x03A1, 0x735E, 0xBE80, 0x5760, 0xBE03, 0x9F7E, 
+    0xBE59, 0x905E, 0x697E, 0x0D5C, 0x9013, 0x7980, 0x03A1, 0x7A80, 0x038A, 0xBF01, 0xBE43, 0x6977, 
+    0xE388, 0x024E, 0xAE61, 0x104D, 0x0061, 0x8B88, 0x6980, 0xE388, 0x024E, 0x9071, 0x0D71, 0x000B, 
+    0xAFA0, 0x8010, 0xAFA0, 0x8010, 0x0810, 0x660A, 0xE308, 0x0249, 0x0009, 0x0810, 0x660C, 0xE388, 
+    0x024E, 0x800B, 0xBC20, 0x697B, 0xE388, 0x03A1, 0xBF0A, 0x109E, 0x8B8A, 0xAF80, 0x8014, 0x4C80, 
+    0xE100, 0x0266, 0x697C, 0xBF90, 0x0560, 0x9072, 0x0372, 0x697C, 0xBF90, 0x0564, 0x9073, 0x0473, 
+    0x7980, 0x0270, 0x697C, 0xBF90, 0x0520, 0x9072, 0x0372, 0x697C, 0xBF90, 0x0524, 0x9073, 0x0473, 
+    0x697C, 0xB801, 0x907C, 0xBF0A, 0x10FD, 0x8B8A, 0xAF80, 0x8010, 0x734F, 0x548A, 0xBE03, 0x9880, 
+    0xBC21, 0x7326, 0x548B, 0xBE03, 0x618B, 0x988C, 0xBE03, 0x6180, 0x9880, 0x7980, 0x03A1, 0x7A80, 
+    0x038A, 0x0D28, 0x4711, 0xE100, 0x02BE, 0xAF12, 0x4006, 0x6912, 0xBFB0, 0x0C00, 0xE388, 0x02B6, 
+    0xBFA0, 0x0800, 0xE388, 0x02B2, 0x6912, 0xBFB0, 0x0C00, 0xBFA0, 0x0400, 0xE388, 0x02A3, 0x6909, 
+    0x900B, 0x7980, 0x02A5, 0xAF0B, 0x4005, 0x6901, 0x9005, 0x6902, 0x9006, 0x4311, 0xE100, 0x02ED, 
+    0x6911, 0xBFC0, 0x2000, 0x9011, 0x7980, 0x02ED, 0x6909, 0x900B, 0x7980, 0x02B8, 0xAF0B, 0x4005, 
+    0xAF05, 0x4003, 0xAF06, 0x4004, 0x7980, 0x02ED, 0xAF12, 0x4006, 0x6912, 0xBFB0, 0x0C00, 0xE388, 
+    0x02E7, 0xBFA0, 0x0800, 0xE388, 0x02E3, 0x6912, 0xBFB0, 0x0C00, 0xBFA0, 0x0400, 0xE388, 0x02D4, 
+    0x690D, 0x9010, 0x7980, 0x02D6, 0xAF10, 0x4005, 0x6901, 0x9005, 0x6902, 0x9006, 0x4311, 0xE100, 
+    0x02ED, 0x6911, 0xBFC0, 0x2000, 0x9011, 0x7980, 0x02ED, 0x690D, 0x9010, 0x7980, 0x02E9, 0xAF10, 
+    0x4005, 0xAF05, 0x4003, 0xAF06, 0x4004, 0xBC20, 0x6970, 0x9071, 0x7A80, 0x0078, 0x6971, 0x9070, 
+    0x7980, 0x03A1, 0xBC20, 0x0361, 0x8B8B, 0x6980, 0xEF88, 0x0272, 0x0372, 0x7804, 0x9071, 0x0D71, 
+    0x8B8A, 0x000B, 0xB903, 0x8809, 0xBEC6, 0x0309, 0x69A8, 0x90AB, 0x69A8, 0x90AA, 0x0810, 0x660A, 
+    0xE344, 0x030F, 0x0009, 0x0810, 0x660C, 0xE388, 0x0314, 0x800B, 0xBC20, 0x6961, 0xB801, 0x9061, 
+    0x7980, 0x02F7, 0x7A80, 0x038A, 0x5D35, 0x0001, 0x6934, 0xB801, 0x9034, 0xBF0A, 0x109E, 0x8B8A, 
+    0xAF80, 0x8014, 0x4880, 0xAE72, 0x0550, 0xF500, 0xAE72, 0x0510, 0xAE61, 0x1051, 0x7A80, 0x02F6, 
+    0x7980, 0x03A1, 0x7A80, 0x038A, 0x5D35, 0x0002, 0x695E, 0xB801, 0x905E, 0xBF0A, 0x109E, 0x8B8A, 
+    0xAF80, 0x8014, 0x4780, 0xAE72, 0x0558, 0xF500, 0xAE72, 0x0518, 0xAE61, 0x105C, 0x7A80, 0x02F6, 
+    0x7980, 0x03A1, 0x001C, 0x8B88, 0x6980, 0xEF88, 0x901D, 0x0D1D, 0x100F, 0x6610, 0xE38C, 0x0358, 
+    0x690E, 0x6610, 0x620F, 0x660D, 0xBA0F, 0xE301, 0x037A, 0x0410, 0x8B8A, 0xB903, 0x8809, 0xBEC6, 
+    0x036C, 0x6A8C, 0x61AA, 0x98AB, 0x6A8C, 0x61AB, 0x98AD, 0x6A8C, 0x61AD, 0x98A9, 0x6A8C, 0x61A9, 
+    0x98AA, 0x7C04, 0x8B8B, 0x7C04, 0x8B8D, 0x7C04, 0x8B89, 0x7C04, 0x0814, 0x660E, 0xE308, 0x0379, 
+    0x040D, 0x8410, 0xBC21, 0x691C, 0xB801, 0x901C, 0x7980, 0x034A, 0xB903, 0x8809, 0x8B8A, 0xBEC6, 
+    0x0388, 0x54AC, 0xBE03, 0x618C, 0x98AA, 0xEF00, 0xBC20, 0xBE46, 0x0809, 0x906B, 0x080A, 0x906C, 
+    0x080B, 0x906D, 0x081A, 0x9062, 0x081B, 0x9063, 0x081E, 0x9064, 0xBE59, 0x881E, 0x8065, 0x8166, 
+    0x8267, 0x8368, 0x8469, 0x856A, 0xEF00, 0xBC20, 0x696B, 0x8809, 0x696C, 0x880A, 0x696D, 0x880B, 
+    0x6962, 0x881A, 0x6963, 0x881B, 0x6964, 0x881E, 0x0065, 0x0166, 0x0267, 0x0368, 0x0469, 0x056A, 
+    0xBE3A, 
+};
+
+/*
+ * Mini sample rate converter code image
+ * that is to be loaded at 0x400 on the DSP.
+ */
+u16 assp_minisrc_image[] = {
+
+    0xBF80, 0x101E, 0x906E, 0x006E, 0x8B88, 0x6980, 0xEF88, 0x906F, 0x0D6F, 0x6900, 0xEB08, 0x0412, 
+    0xBC20, 0x696E, 0xB801, 0x906E, 0x7980, 0x0403, 0xB90E, 0x8807, 0xBE43, 0xBF01, 0xBE47, 0xBE41, 
+    0x7A80, 0x002A, 0xBE40, 0x3029, 0xEFCC, 0xBE41, 0x7A80, 0x0028, 0xBE40, 0x3028, 0xEFCC, 0x6907, 
+    0xE308, 0x042A, 0x6909, 0x902C, 0x7980, 0x042C, 0x690D, 0x902C, 0x1009, 0x881A, 0x100A, 0xBA01, 
+    0x881B, 0x100D, 0x881C, 0x100E, 0xBA01, 0x881D, 0xBF80, 0x00ED, 0x881E, 0x050C, 0x0124, 0xB904, 
+    0x9027, 0x6918, 0xE308, 0x04B3, 0x902D, 0x6913, 0xBFA0, 0x7598, 0xF704, 0xAE2D, 0x00FF, 0x8B8D, 
+    0x6919, 0xE308, 0x0463, 0x691A, 0xE308, 0x0456, 0xB907, 0x8809, 0xBEC6, 0x0453, 0x10A9, 0x90AD, 
+    0x7980, 0x047C, 0xB903, 0x8809, 0xBEC6, 0x0460, 0x1889, 0x6C22, 0x90AD, 0x10A9, 0x6E23, 0x6C22, 
+    0x90AD, 0x7980, 0x047C, 0x101A, 0xE308, 0x046F, 0xB903, 0x8809, 0xBEC6, 0x046C, 0x10A9, 0x90A0, 
+    0x90AD, 0x7980, 0x047C, 0xB901, 0x8809, 0xBEC6, 0x047B, 0x1889, 0x6C22, 0x90A0, 0x90AD, 0x10A9, 
+    0x6E23, 0x6C22, 0x90A0, 0x90AD, 0x692D, 0xE308, 0x049C, 0x0124, 0xB703, 0xB902, 0x8818, 0x8B89, 
+    0x022C, 0x108A, 0x7C04, 0x90A0, 0x692B, 0x881F, 0x7E80, 0x055B, 0x692A, 0x8809, 0x8B89, 0x99A0, 
+    0x108A, 0x90A0, 0x692B, 0x881F, 0x7E80, 0x055B, 0x692A, 0x8809, 0x8B89, 0x99AF, 0x7B99, 0x0484, 
+    0x0124, 0x060F, 0x101B, 0x2013, 0x901B, 0xBFA0, 0x7FFF, 0xE344, 0x04AC, 0x901B, 0x8B89, 0x7A80, 
+    0x051A, 0x6927, 0xBA01, 0x9027, 0x7A80, 0x0523, 0x6927, 0xE308, 0x049E, 0x7980, 0x050F, 0x0624, 
+    0x1026, 0x2013, 0x9026, 0xBFA0, 0x7FFF, 0xE304, 0x04C0, 0x8B8D, 0x7A80, 0x051A, 0x7980, 0x04B4, 
+    0x9026, 0x1013, 0x3026, 0x901B, 0x8B8D, 0x7A80, 0x051A, 0x7A80, 0x0523, 0x1027, 0xBA01, 0x9027, 
+    0xE308, 0x04B4, 0x0124, 0x060F, 0x8B89, 0x691A, 0xE308, 0x04EA, 0x6919, 0xE388, 0x04E0, 0xB903, 
+    0x8809, 0xBEC6, 0x04DD, 0x1FA0, 0x2FAE, 0x98A9, 0x7980, 0x050F, 0xB901, 0x8818, 0xB907, 0x8809, 
+    0xBEC6, 0x04E7, 0x10EE, 0x90A9, 0x7980, 0x050F, 0x6919, 0xE308, 0x04FE, 0xB903, 0x8809, 0xBE46, 
+    0xBEC6, 0x04FA, 0x17A0, 0xBE1E, 0x1FAE, 0xBFBF, 0xFF00, 0xBE13, 0xBFDF, 0x8080, 0x99A9, 0xBE47, 
+    0x7980, 0x050F, 0xB901, 0x8809, 0xBEC6, 0x050E, 0x16A0, 0x26A0, 0xBFB7, 0xFF00, 0xBE1E, 0x1EA0, 
+    0x2EAE, 0xBFBF, 0xFF00, 0xBE13, 0xBFDF, 0x8080, 0x99A9, 0x850C, 0x860F, 0x6907, 0xE388, 0x0516, 
+    0x0D07, 0x8510, 0xBE59, 0x881E, 0xBE4A, 0xEF00, 0x101E, 0x901C, 0x101F, 0x901D, 0x10A0, 0x901E, 
+    0x10A0, 0x901F, 0xEF00, 0x101E, 0x301C, 0x9020, 0x731B, 0x5420, 0xBE03, 0x9825, 0x1025, 0x201C, 
+    0x9025, 0x7325, 0x5414, 0xBE03, 0x8B8E, 0x9880, 0x692F, 0xE388, 0x0539, 0xBE59, 0xBB07, 0x6180, 
+    0x9880, 0x8BA0, 0x101F, 0x301D, 0x9021, 0x731B, 0x5421, 0xBE03, 0x982E, 0x102E, 0x201D, 0x902E, 
+    0x732E, 0x5415, 0xBE03, 0x9880, 0x692F, 0xE388, 0x054F, 0xBE59, 0xBB07, 0x6180, 0x9880, 0x8BA0, 
+    0x6918, 0xEF08, 0x7325, 0x5416, 0xBE03, 0x98A0, 0x732E, 0x5417, 0xBE03, 0x98A0, 0xEF00, 0x8BA0, 
+    0xBEC6, 0x056B, 0xBE59, 0xBB04, 0xAA90, 0xBE04, 0xBE1E, 0x99E0, 0x8BE0, 0x69A0, 0x90D0, 0x69A0, 
+    0x90D0, 0x081F, 0xB805, 0x881F, 0x8B90, 0x69A0, 0x90D0, 0x69A0, 0x9090, 0x8BD0, 0x8BD8, 0xBE1F, 
+    0xEF00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+};
+
diff -urN linux-2.4.2-pre1/drivers/sound/mpu401.c linux/drivers/sound/mpu401.c
--- linux-2.4.2-pre1/drivers/sound/mpu401.c	Mon Jan  1 10:23:21 2001
+++ linux/drivers/sound/mpu401.c	Mon Dec  3 22:27:48 2001
@@ -14,6 +14,7 @@
  * Thomas Sailer	ioctl code reworked (vmalloc/vfree removed)
  * Alan Cox		modularisation, use normal request_irq, use dev_id
  * Bartlomiej Zolnierkiewicz	removed some __init to allow using many drivers
+ * Chris Rankin		Update the module-usage counter for the coprocessor
  */
 
 #include <linux/module.h>
@@ -73,6 +74,9 @@
 #define	COMDPORT(base)   (base+1)
 #define	STATPORT(base)   (base+1)
 
+
+static void mpu401_close(int dev);
+
 static int mpu401_status(struct mpu_config *devc)
 {
 	return inb(STATPORT(devc->base));
@@ -465,6 +469,7 @@
 {
 	int err;
 	struct mpu_config *devc;
+	struct coproc_operations *coprocessor;
 
 	if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL)
 		return -ENXIO;
@@ -490,12 +495,15 @@
 		reset_mpu401(devc);
 	}
 
-	if (midi_devs[dev]->coproc)
+	if ( (coprocessor = midi_devs[dev]->coproc) != NULL )
 	{
-		if ((err = midi_devs[dev]->coproc->
-		     open(midi_devs[dev]->coproc->devc, COPR_MIDI)) < 0)
+		if (coprocessor->owner)
+			__MOD_INC_USE_COUNT(coprocessor->owner);
+
+		if ((err = coprocessor->open(coprocessor->devc, COPR_MIDI)) < 0)
 		{
-			printk("MPU-401: Can't access coprocessor device\n");
+			printk(KERN_WARNING "MPU-401: Can't access coprocessor device\n");
+			mpu401_close(dev);
 			return err;
 		}
 	}
@@ -515,6 +523,7 @@
 static void mpu401_close(int dev)
 {
 	struct mpu_config *devc;
+	struct coproc_operations *coprocessor;
 
 	devc = &dev_conf[dev];
 	if (devc->uart_mode)
@@ -524,8 +533,13 @@
 	devc->mode = 0;
 	devc->inputintr = NULL;
 
-	if (midi_devs[dev]->coproc)
-		midi_devs[dev]->coproc->close(midi_devs[dev]->coproc->devc, COPR_MIDI);
+	coprocessor = midi_devs[dev]->coproc;
+	if (coprocessor) {
+		coprocessor->close(coprocessor->devc, COPR_MIDI);
+
+		if (coprocessor->owner)
+			__MOD_DEC_USE_COUNT(coprocessor->owner);
+	}
 	devc->opened = 0;
 }
 
@@ -791,6 +805,7 @@
 {
 	int midi_dev, err;
 	struct mpu_config *devc;
+	struct coproc_operations *coprocessor;
 
 	midi_dev = synth_devs[dev]->midi_dev;
 
@@ -822,13 +837,17 @@
 
 	devc->inputintr = NULL;
 
-	if (midi_devs[midi_dev]->coproc)
-		if ((err = midi_devs[midi_dev]->coproc->
-		 open(midi_devs[midi_dev]->coproc->devc, COPR_MIDI)) < 0)
+	coprocessor = midi_devs[midi_dev]->coproc;
+	if (coprocessor) {
+		if (coprocessor->owner)
+			__MOD_INC_USE_COUNT(coprocessor->owner);
+
+		if ((err = coprocessor->open(coprocessor->devc, COPR_MIDI)) < 0)
 		{
 			printk(KERN_WARNING "mpu401: Can't access coprocessor device\n");
 			return err;
 		}
+	}
 	devc->opened = mode;
 	reset_mpu401(devc);
 
@@ -845,6 +864,7 @@
 { 
 	int midi_dev;
 	struct mpu_config *devc;
+	struct coproc_operations *coprocessor;
 
 	midi_dev = synth_devs[dev]->midi_dev;
 
@@ -854,8 +874,13 @@
 
 	devc->inputintr = NULL;
 
-	if (midi_devs[midi_dev]->coproc)
-		midi_devs[midi_dev]->coproc->close(midi_devs[midi_dev]->coproc->devc, COPR_MIDI);
+	coprocessor = midi_devs[midi_dev]->coproc;
+	if (coprocessor) {
+		coprocessor->close(coprocessor->devc, COPR_MIDI);
+
+		if (coprocessor->owner)
+			__MOD_DEC_USE_COUNT(coprocessor->owner);
+	}
 	devc->opened = 0;
 	devc->mode = 0;
 }
@@ -1030,6 +1055,8 @@
 			(char *) &mpu401_synth_proto,
 			 sizeof(struct synth_operations));
 	}
+	if (owner)
+		mpu401_synth_operations[m]->owner = owner;
 
 	memcpy((char *) &mpu401_midi_operations[m],
 	       (char *) &mpu401_midi_proto,
diff -urN linux-2.4.2-pre1/drivers/sound/opl3sa2.c linux/drivers/sound/opl3sa2.c
--- linux-2.4.2-pre1/drivers/sound/opl3sa2.c	Fri Aug 11 08:26:43 2000
+++ linux/drivers/sound/opl3sa2.c	Mon Dec  3 22:27:48 2001
@@ -2,9 +2,12 @@
  * sound/opl3sa2.c
  *
  * A low level driver for Yamaha OPL3-SA2 and SA3 cards.
- * SAx cards should work, as they are just variants of the SA3.
+ * NOTE: All traces of the name OPL3-SAx have now (December 2000) been
+ *       removed from the driver code, as an email exchange with Yamaha
+ *       provided the information that the YMF-719 is indeed just a
+ *       re-badged 715.
  *
- * Copyright 1998, 1999 Scott Murray <scottm@interlog.com>
+ * Copyright 1998-2001 Scott Murray <scott@spiteful.org>
  *
  * Originally based on the CS4232 driver (in cs4232.c) by Hannu Savolainen
  * and others.  Now incorporates code/ideas from pss.c, also by Hannu
@@ -33,12 +36,32 @@
  *                         (with thanks to Ben Hutchings for the heuristic),
  *                         removed now unnecessary force option. (Jan 5, 1999)
  * Christoph Hellwig	   Adapted to module_init/module_exit (Mar 4, 2000)
+ * Scott Murray            Reworked SA2 versus SA3 mixer code, updated chipset
+ *                         version detection code (again!). (Dec 5, 2000)
+ * Scott Murray            Adjusted master volume mixer scaling. (Dec 6, 2000)
+ * Scott Murray            Based on a patch by Joel Yliluoma (aka Bisqwit),
+ *                         integrated wide mixer and adjusted mic, bass, treble
+ *                         scaling. (Dec 6, 2000)
+ * Scott Murray            Based on a patch by Peter Englmaier, integrated
+ *                         ymode and loopback options. (Dec 6, 2000)
+ * Scott Murray            Inspired by a patch by Peter Englmaier, and based on
+ *                         what ALSA does, added initialization code for the
+ *                         default DMA and IRQ settings. (Dec 6, 2000)
+ * Scott Murray            Added some more checks to the card detection code,
+ *                         based on what ALSA does. (Dec 12, 2000)
+ * Scott Murray            Inspired by similar patches from John Fremlin,
+ *                         Jim Radford, Mike Rolig, and Ingmar Steen, added 2.4
+ *                         ISA PnP API support, mainly based on bits from
+ *                         sb_card.c and awe_wave.c. (Dec 12, 2000)
+ * Scott Murray            Some small cleanups to the init code output.
+ *                         (Jan 7, 2001)
  *
  */
 
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/isapnp.h>
 
 #include "sound_config.h"
 
@@ -46,6 +69,9 @@
 #include "mpu401.h"
 
 /* Useful control port indexes: */
+#define OPL3SA2_SYS_CTRL     0x02
+#define OPL3SA2_IRQ_CONFIG   0x03
+#define OPL3SA2_DMA_CONFIG   0x06
 #define OPL3SA2_MASTER_LEFT  0x07
 #define OPL3SA2_MASTER_RIGHT 0x08
 #define OPL3SA2_MIC          0x09
@@ -60,83 +86,157 @@
 #define DEFAULT_MIC    50
 #define DEFAULT_TIMBRE 0
 
+/* For checking against what the card returns: */
+#define VERSION_UNKNOWN 0
+#define VERSION_YMF711  1
+#define VERSION_YMF715  2
+#define VERSION_YMF715B 3
+#define VERSION_YMF715E 4
+/* also assuming that anything > 4 but <= 7 is a 715E */
+
+/* Chipset type constants for use below */
 #define CHIPSET_UNKNOWN -1
+#define CHIPSET_OPL3SA2 0
+#define CHIPSET_OPL3SA3 1
 
-/*
- * These are used both as masks against what the card returns,
- * and as constants.
- */
-#define CHIPSET_OPL3SA2  1
-#define CHIPSET_OPL3SA3  2
-#define CHIPSET_OPL3SAX  4
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#define OPL3SA2_CARDS_MAX 4
+#else
+#define OPL3SA2_CARDS_MAX 1
+#endif
 
+/* This should be pretty obvious */
+static int opl3sa2_cards_num; /* = 0 */
 
-/* What's my version? */
-static int chipset = CHIPSET_UNKNOWN;
+/* What's my version(s)? */
+static int chipset[OPL3SA2_CARDS_MAX] = { CHIPSET_UNKNOWN };
 
-/* Oh well, let's just cache the name */
-static char chipset_name[16];
+/* Oh well, let's just cache the name(s) */
+static char chipset_name[OPL3SA2_CARDS_MAX][12];
 
-/* Where's my mixer */
-static int opl3sa2_mixer = -1;
+/* Where's my mixer(s)? */
+static int opl3sa2_mixer[OPL3SA2_CARDS_MAX] = { -1 };
 
 /* Bag o' mixer data */
-typedef struct opl3sa2_mixerdata {
+typedef struct opl3sa2_mixerdata_tag {
 	unsigned short cfg_port;
 	unsigned short padding;
-	int            ad_mixer_dev;
 	unsigned int   volume_l;
 	unsigned int   volume_r;
 	unsigned int   mic;
-	unsigned int   bass;
-	unsigned int   treble;
+	unsigned int   bass_l;
+	unsigned int   bass_r;
+	unsigned int   treble_l;
+	unsigned int   treble_r;
+	unsigned int   wide_l;
+	unsigned int   wide_r;
 } opl3sa2_mixerdata;
+static opl3sa2_mixerdata opl3sa2_data[OPL3SA2_CARDS_MAX];
+
+static struct address_info cfg[OPL3SA2_CARDS_MAX];
+static struct address_info cfg_mss[OPL3SA2_CARDS_MAX];
+static struct address_info cfg_mpu[OPL3SA2_CARDS_MAX];
+
+/* Our parameters */
+static int __initdata io	= -1;
+static int __initdata mss_io	= -1;
+static int __initdata mpu_io	= -1;
+static int __initdata irq	= -1;
+static int __initdata dma	= -1;
+static int __initdata dma2	= -1;
+static int __initdata ymode	= -1;
+static int __initdata loopback	= -1;
+
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+/* PnP specific parameters */
+static int __initdata isapnp = 1;
+static int __initdata multiple = 1;
 
-#ifdef CONFIG_OPL3SA2_CTRL_BASE
-/* Set control port if compiled into the kernel */
-static opl3sa2_mixerdata opl3sa2_data = { CONFIG_OPL3SA2_CTRL_BASE, };
+/* PnP devices */
+struct pci_dev* opl3sa2_dev[OPL3SA2_CARDS_MAX];
+
+/* Whether said devices have been activated */
+static int opl3sa2_activated[OPL3SA2_CARDS_MAX];
 #else
-static opl3sa2_mixerdata opl3sa2_data;
+static int __initdata isapnp; /* = 0 */
+static int __initdata multiple; /* = 0 */
 #endif
 
-static opl3sa2_mixerdata *devc = &opl3sa2_data;
+MODULE_DESCRIPTION("Module for OPL3-SA2 and SA3 sound cards (uses AD1848 MSS driver).");
+MODULE_AUTHOR("Scott Murray <scott@spiteful.org>");
+
+MODULE_PARM(io, "i");
+MODULE_PARM_DESC(io, "Set I/O base of OPL3-SA2 or SA3 card (usually 0x370.  Address must be even and must be from 0x100 to 0xFFE)");
+
+MODULE_PARM(mss_io, "i");
+MODULE_PARM_DESC(mss_io, "Set MSS (audio) I/O base (0x530, 0xE80, or other. Address must end in 0 or 4 and must be from 0x530 to 0xF48)");
+
+MODULE_PARM(mpu_io, "i");
+MODULE_PARM_DESC(mpu_io, "Set MIDI I/O base (0x330 or other. Address must be even and must be from 0x300 to 0x334)");
+
+MODULE_PARM(irq, "i");
+MODULE_PARM_DESC(mss_irq, "Set MSS (audio) IRQ (5, 7, 9, 10, 11, 12)");
+
+MODULE_PARM(dma, "i");
+MODULE_PARM_DESC(dma, "Set MSS (audio) first DMA channel (0, 1, 3)");
+
+MODULE_PARM(dma2, "i");
+MODULE_PARM_DESC(dma2, "Set MSS (audio) second DMA channel (0, 1, 3)");
+
+MODULE_PARM(ymode, "i");
+MODULE_PARM_DESC(ymode, "Set Yamaha 3D enhancement mode (0 = Desktop/Normal, 1 = Notebook PC (1), 2 = Notebook PC (2), 3 = Hi-Fi)");
+
+MODULE_PARM(loopback, "i");
+MODULE_PARM_DESC(loopback, "Set A/D input source. Useful for echo cancellation (0 = Mic Rch (default), 1 = Mono output loopback)");
+
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+MODULE_PARM(isapnp, "i");
+MODULE_PARM_DESC(isapnp, "When set to 0, ISA PnP support will be disabled");
+
+MODULE_PARM(multiple, "i");
+MODULE_PARM_DESC(multiple, "When set to 0, will not search for multiple cards");
+#endif
 
 
-/* Standard read and write functions */
+/*
+ * Standard read and write functions
+*/
 
-static void opl3sa2_write(unsigned short port,
-			  unsigned char  index,
-			  unsigned char  data)
+static inline void opl3sa2_write(unsigned short port,
+				 unsigned char  index,
+				 unsigned char  data)
 {
 	outb_p(index, port);
 	outb(data, port + 1);
 }
 
 
-static void opl3sa2_read(unsigned short port,
-			 unsigned char  index,
-			 unsigned char* data)
+static inline void opl3sa2_read(unsigned short port,
+				unsigned char  index,
+				unsigned char* data)
 {
 	outb_p(index, port);
 	*data = inb(port + 1);
 }
 
 
-/* All of the mixer functions... */
+/*
+ * All of the mixer functions...
+ */
 
-static void opl3sa2_set_volume(opl3sa2_mixerdata *devc, int left, int right)
+static void opl3sa2_set_volume(opl3sa2_mixerdata* devc, int left, int right)
 {
 	static unsigned char scale[101] = {
-		0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 
-		0x0e, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 
-		0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 
-		0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 
-		0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08, 
-		0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 
-		0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 
-		0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 
-		0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 
-		0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
+		0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e,
+		0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0c,
+		0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b,
+		0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09,
+		0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x08,
+		0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
+		0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03,
+		0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01,
+		0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
 		0x00
 	};
 	unsigned char vol;
@@ -159,12 +259,12 @@
 }
 
 
-static void opl3sa2_set_mic(opl3sa2_mixerdata *devc, int level)
+static void opl3sa2_set_mic(opl3sa2_mixerdata* devc, int level)
 {
 	unsigned char vol = 0x1F;
 
 	if((level >= 0) && (level <= 100))
-		vol = 0x1F - (unsigned char) (0x1F * level / 100L);
+		vol = 0x1F - (unsigned char) (32 * level / 101);
 
 	/* If level is zero, turn on mute */
 	if(!level)
@@ -174,283 +274,286 @@
 }
 
 
-static void opl3sa3_set_bass(opl3sa2_mixerdata *devc, int level)
+static void opl3sa3_set_bass(opl3sa2_mixerdata* devc, int left, int right)
 {
 	unsigned char bass;
 
-	bass = level ? ((unsigned char) (0x07 * level / 100L)) : 0; 
-	bass |= (bass << 4);
+	bass = left ? ((unsigned char) (8 * left / 101)) : 0; 
+	bass |= (right ? ((unsigned char) (8 * right / 101)) : 0) << 4;
 
 	opl3sa2_write(devc->cfg_port, OPL3SA3_BASS, bass);
 }
 
 
-static void opl3sa3_set_treble(opl3sa2_mixerdata *devc, int level)
+static void opl3sa3_set_treble(opl3sa2_mixerdata* devc, int left, int right)
 {	
 	unsigned char treble;
 
-	treble = level ? ((unsigned char) (0x07 * level / 100L)) : 0; 
-	treble |= (treble << 4);
+	treble = left ? ((unsigned char) (8 * left / 101)) : 0; 
+	treble |= (right ? ((unsigned char) (8 * right / 101)) : 0) << 4;
 
 	opl3sa2_write(devc->cfg_port, OPL3SA3_TREBLE, treble);
 }
 
 
-static void opl3sa2_mixer_reset(opl3sa2_mixerdata *devc)
+static void opl3sa3_set_wide(opl3sa2_mixerdata* devc, int left, int right)
+{	
+	unsigned char wide;
+
+	wide = left ? ((unsigned char) (8 * left / 101)) : 0; 
+	wide |= (right ? ((unsigned char) (8 * right / 101)) : 0) << 4;
+
+	opl3sa2_write(devc->cfg_port, OPL3SA3_WIDE, wide);
+}
+
+
+static void opl3sa2_mixer_reset(opl3sa2_mixerdata* devc, int card)
 {
-	if(devc)
-	{
+	if(devc) {
 		opl3sa2_set_volume(devc, DEFAULT_VOLUME, DEFAULT_VOLUME);
 		devc->volume_l = devc->volume_r = DEFAULT_VOLUME;
 
 		opl3sa2_set_mic(devc, DEFAULT_MIC);
 		devc->mic = DEFAULT_MIC;
 
-		opl3sa3_set_bass(devc, DEFAULT_TIMBRE);
-		opl3sa3_set_treble(devc, DEFAULT_TIMBRE);
-		devc->bass = devc->treble = DEFAULT_TIMBRE;
+		if(chipset[card] == CHIPSET_OPL3SA3) {
+			opl3sa3_set_bass(devc, DEFAULT_TIMBRE, DEFAULT_TIMBRE);
+			devc->bass_l = devc->bass_r = DEFAULT_TIMBRE;
+			opl3sa3_set_treble(devc, DEFAULT_TIMBRE, DEFAULT_TIMBRE);
+			devc->treble_l = devc->treble_r = DEFAULT_TIMBRE;
+		}
 	}
 }
 
 
-static void arg_to_volume_mono(unsigned int volume, int *aleft)
+static inline void arg_to_vol_mono(unsigned int vol, int* value)
 {
 	int left;
 	
-	left = volume & 0x00ff;
+	left = vol & 0x00ff;
 	if (left > 100)
 		left = 100;
-	*aleft = left;
+	*value = left;
 }
 
 
-static void arg_to_volume_stereo(unsigned int volume, int *aleft, int *aright)
+static inline void arg_to_vol_stereo(unsigned int vol, int* aleft, int* aright)
 {
-	arg_to_volume_mono(volume, aleft);
-	arg_to_volume_mono(volume >> 8, aright);
+	arg_to_vol_mono(vol, aleft);
+	arg_to_vol_mono(vol >> 8, aright);
 }
 
 
-static int ret_vol_mono(int left)
+static inline int ret_vol_mono(int vol)
 {
-	return ((left << 8) | left);
+	return ((vol << 8) | vol);
 }
 
 
-static int ret_vol_stereo(int left, int right)
+static inline int ret_vol_stereo(int left, int right)
 {
 	return ((right << 8) | left);
 }
 
 
-static int call_ad_mixer(opl3sa2_mixerdata *devc, unsigned int cmd, caddr_t arg)
-{
-	if(devc->ad_mixer_dev != -1) 
-		return mixer_devs[devc->ad_mixer_dev]->ioctl(devc->ad_mixer_dev,
-							     cmd,
-							     arg);
-	else 
-		return -EINVAL;
-}
-
-
 static int opl3sa2_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
 {
 	int cmdf = cmd & 0xff;
 
 	opl3sa2_mixerdata* devc = (opl3sa2_mixerdata*) mixer_devs[dev]->devc;
 	
-	switch(cmdf)
-	{
+	switch(cmdf) {
 		case SOUND_MIXER_VOLUME:
 		case SOUND_MIXER_MIC:
-		case SOUND_MIXER_BASS:
-		case SOUND_MIXER_TREBLE:
 		case SOUND_MIXER_DEVMASK:
 		case SOUND_MIXER_STEREODEVS: 
 		case SOUND_MIXER_RECMASK:
-		case SOUND_MIXER_CAPS: 
 		case SOUND_MIXER_RECSRC:
+		case SOUND_MIXER_CAPS: 
 			break;
 
 		default:
-			return call_ad_mixer(devc, cmd, arg);
+			return -EINVAL;
 	}
 	
 	if(((cmd >> 8) & 0xff) != 'M')
 		return -EINVAL;
 		
-	if(_SIOC_DIR (cmd) & _SIOC_WRITE)
-	{
-		switch (cmdf)	
-		{
-			case SOUND_MIXER_RECSRC:
-				if(devc->ad_mixer_dev != -1)
-					return call_ad_mixer(devc, cmd, arg);
-				else
-				{
-					if(*(int*)arg != 0)
-						return -EINVAL;
-					return 0;
-				}
-
+	if(_SIOC_DIR (cmd) & _SIOC_WRITE) {
+		switch (cmdf) {
 			case SOUND_MIXER_VOLUME:
-				arg_to_volume_stereo(*(unsigned int*)arg,
-						     &devc->volume_l,
-						     &devc->volume_r); 
-				opl3sa2_set_volume(devc, devc->volume_l,
-						   devc->volume_r);
-				*(int*)arg = ret_vol_stereo(devc->volume_l,
-							     devc->volume_r);
+				arg_to_vol_stereo(*(unsigned int*)arg,
+						  &devc->volume_l, &devc->volume_r); 
+				opl3sa2_set_volume(devc, devc->volume_l, devc->volume_r);
+				*(int*)arg = ret_vol_stereo(devc->volume_l, devc->volume_r);
 				return 0;
 		  
 			case SOUND_MIXER_MIC:
-				arg_to_volume_mono(*(unsigned int*)arg,
-						   &devc->mic);
+				arg_to_vol_mono(*(unsigned int*)arg, &devc->mic);
 				opl3sa2_set_mic(devc, devc->mic);
 				*(int*)arg = ret_vol_mono(devc->mic);
 				return 0;
-		  
-			case SOUND_MIXER_BASS:
-				if(chipset != CHIPSET_OPL3SA2)
-				{
-					arg_to_volume_mono(*(unsigned int*)arg,
-							   &devc->bass);
-					opl3sa3_set_bass(devc, devc->bass);
-					*(int*)arg = ret_vol_mono(devc->bass);
-					return 0;
-				}
-				return -EINVAL;
-		  
-			case SOUND_MIXER_TREBLE:
-				if(chipset != CHIPSET_OPL3SA2)
-				{
-					arg_to_volume_mono(*(unsigned int *)arg,
-							   &devc->treble);
-					opl3sa3_set_treble(devc, devc->treble);
-					*(int*)arg = ret_vol_mono(devc->treble);
-					return 0;
-				}
-				return -EINVAL;
-		  
+
 			default:
 				return -EINVAL;
 		}
 	}
-	else			
-	{
+	else {
 		/*
 		 * Return parameters
 		 */
-		switch (cmdf)
-		{
+		switch (cmdf) {
 			case SOUND_MIXER_DEVMASK:
-				if(call_ad_mixer(devc, cmd, arg) == -EINVAL)
-					*(int*)arg = 0; /* no mixer devices */
-
-				*(int*)arg |= (SOUND_MASK_VOLUME | SOUND_MASK_MIC);
-
-				/* OPL3-SA2 has no bass and treble mixers */
-				if(chipset != CHIPSET_OPL3SA2)
-					*(int*)arg |= (SOUND_MASK_BASS |
-						       SOUND_MASK_TREBLE);
+				*(int*)arg = (SOUND_MASK_VOLUME | SOUND_MASK_MIC);
 				return 0;
 		  
 			case SOUND_MIXER_STEREODEVS:
-				if(call_ad_mixer(devc, cmd, arg) == -EINVAL)
-					*(int*)arg = 0; /* no stereo devices */
-				*(int*)arg |= SOUND_MASK_VOLUME;
+				*(int*)arg = SOUND_MASK_VOLUME;
 				return 0;
 		  
 			case SOUND_MIXER_RECMASK:
-				if(devc->ad_mixer_dev != -1)
-				{
-					return call_ad_mixer(devc, cmd, arg);
-				}
-				else
-				{
-					/* No recording devices */
-					return (*(int*)arg = 0);
-				}
+				/* No recording devices */
+				return (*(int*)arg = 0);
 
 			case SOUND_MIXER_CAPS:
-				if(devc->ad_mixer_dev != -1)
-				{
-					return call_ad_mixer(devc, cmd, arg);
-				}
-				else
-				{
-					*(int*)arg = SOUND_CAP_EXCL_INPUT;
-					return 0;
-				}
+				*(int*)arg = SOUND_CAP_EXCL_INPUT;
+				return 0;
 
 			case SOUND_MIXER_RECSRC:
-				if(devc->ad_mixer_dev != -1)
-				{
-					return call_ad_mixer(devc, cmd, arg);
-				}
-				else
-				{
-					/* No recording source */
-					return (*(int*)arg = 0);
-				}
+				/* No recording source */
+				return (*(int*)arg = 0);
 
 			case SOUND_MIXER_VOLUME:
-				*(int*)arg = ret_vol_stereo(devc->volume_l,
-							    devc->volume_r);
+				*(int*)arg = ret_vol_stereo(devc->volume_l, devc->volume_r);
 				return 0;
 			  
 			case SOUND_MIXER_MIC:
 				*(int*)arg = ret_vol_mono(devc->mic);
 				return 0;
 
+			default:
+				return -EINVAL;
+		}
+	}
+}
+/* opl3sa2_mixer_ioctl end */
+
+
+static int opl3sa3_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
+{
+	int cmdf = cmd & 0xff;
+
+	opl3sa2_mixerdata* devc = (opl3sa2_mixerdata*) mixer_devs[dev]->devc;
+
+	switch(cmdf) {
+		case SOUND_MIXER_BASS:
+		case SOUND_MIXER_TREBLE:
+		case SOUND_MIXER_DIGITAL1:
+		case SOUND_MIXER_DEVMASK:
+		case SOUND_MIXER_STEREODEVS: 
+			break;
+
+		default:
+			return opl3sa2_mixer_ioctl(dev, cmd, arg);
+	}
+
+	if(((cmd >> 8) & 0xff) != 'M')
+		return -EINVAL;
+		
+	if(_SIOC_DIR (cmd) & _SIOC_WRITE) {
+		switch (cmdf) {
 			case SOUND_MIXER_BASS:
-				if(chipset != CHIPSET_OPL3SA2)
-				{
-					*(int*)arg = ret_vol_mono(devc->bass);
-					return 0;
-				}
-				else
-				{
-					return -EINVAL;
-				}
-			  
+				arg_to_vol_stereo(*(unsigned int*)arg,
+						  &devc->bass_l, &devc->bass_r); 
+				opl3sa3_set_bass(devc, devc->bass_l, devc->bass_r);
+				*(int*)arg = ret_vol_stereo(devc->bass_l, devc->bass_r);
+				return 0;
+		  
 			case SOUND_MIXER_TREBLE:
-				if(chipset != CHIPSET_OPL3SA2)
-				{
-					*(int*)arg = ret_vol_mono(devc->treble);
-					return 0;
-				}
-				else
-				{
-					return -EINVAL;
-				}
+				arg_to_vol_stereo(*(unsigned int*)arg,
+						  &devc->treble_l, &devc->treble_r); 
+				opl3sa3_set_treble(devc, devc->treble_l, devc->treble_r);
+				*(int*)arg = ret_vol_stereo(devc->treble_l, devc->treble_r);
+				return 0;
+
+			case SOUND_MIXER_DIGITAL1:
+				arg_to_vol_stereo(*(unsigned int*)arg,
+						  &devc->wide_l, &devc->wide_r); 
+				opl3sa3_set_wide(devc, devc->wide_l, devc->wide_r);
+				*(int*)arg = ret_vol_stereo(devc->wide_l, devc->wide_r);
+				return 0;
+
+			default:
+				return -EINVAL;
+		}
+	}
+	else			
+	{
+		/*
+		 * Return parameters
+		 */
+		switch (cmdf) {
+			case SOUND_MIXER_DEVMASK:
+				*(int*)arg = (SOUND_MASK_VOLUME | SOUND_MASK_MIC |
+					      SOUND_MASK_BASS | SOUND_MASK_TREBLE |
+					      SOUND_MASK_DIGITAL1);
+				return 0;
+		  
+			case SOUND_MIXER_STEREODEVS:
+				*(int*)arg = (SOUND_MASK_VOLUME | SOUND_MASK_BASS |
+					      SOUND_MASK_TREBLE | SOUND_MASK_DIGITAL1);
+				return 0;
+		  
+			case SOUND_MIXER_BASS:
+				*(int*)arg = ret_vol_stereo(devc->bass_l, devc->bass_r);
+				return 0;
 			  
+			case SOUND_MIXER_TREBLE:
+				*(int*)arg = ret_vol_stereo(devc->treble_l, devc->treble_r);
+				return 0;
+
+			case SOUND_MIXER_DIGITAL1:
+				*(int*)arg = ret_vol_stereo(devc->wide_l, devc->wide_r);
+				return 0;
+
 			default:
 				return -EINVAL;
 		}
 	}
 }
+/* opl3sa3_mixer_ioctl end */
 
 
 static struct mixer_operations opl3sa2_mixer_operations =
 {
 	owner:	THIS_MODULE,
-	id:	"Yamaha",
-	name:	"", /* hmm? */
+	id:	"OPL3-SA2",
+	name:	"Yamaha OPL3-SA2",
 	ioctl:	opl3sa2_mixer_ioctl
 };
 
+static struct mixer_operations opl3sa3_mixer_operations =
+{
+	owner:	THIS_MODULE,
+	id:	"OPL3-SA3",
+	name:	"Yamaha OPL3-SA3",
+	ioctl:	opl3sa3_mixer_ioctl
+};
+
 /* End of mixer-related stuff */
 
 
-static inline int __init probe_opl3sa2_mpu(struct address_info *hw_config)
+/*
+ * Component probe, attach, unload functions
+ */
+
+static inline int __init probe_opl3sa2_mpu(struct address_info* hw_config)
 {
 	return probe_mpu401(hw_config);
 }
 
 
-static inline void __init attach_opl3sa2_mpu(struct address_info *hw_config)
+static inline void __init attach_opl3sa2_mpu(struct address_info* hw_config)
 {
 	attach_mpu401(hw_config, THIS_MODULE);
 }
@@ -462,255 +565,472 @@
 }
 
 
-static inline int __init probe_opl3sa2_mss(struct address_info *hw_config)
+static inline int __init probe_opl3sa2_mss(struct address_info* hw_config)
 {
 	return probe_ms_sound(hw_config);
 }
 
 
-static void __init attach_opl3sa2_mss(struct address_info *hw_config)
+static void __init attach_opl3sa2_mss(struct address_info* hw_config)
 {
-	char mixer_name[64];
-
-	/* Create pretty names for mixer stuff */
-	strncpy(mixer_name, chipset_name, 16);
-	strncat(mixer_name, " and AD1848 (through MSS)", 64);
-
-	strncpy(opl3sa2_mixer_operations.name, chipset_name, 16);
-	strncat(opl3sa2_mixer_operations.name, "-AD1848", 64);
-
-	/* Install master mixer */
-	devc->ad_mixer_dev = -1;
-	if((opl3sa2_mixer = sound_install_mixer(MIXER_DRIVER_VERSION,
-						mixer_name,
-						&opl3sa2_mixer_operations,
-						sizeof(struct mixer_operations),
-						devc)) < 0) 
-	{
-		printk(KERN_ERR "Could not install %s master mixer\n", chipset_name);
-		return;
-	}
-
-	opl3sa2_mixer_reset(devc);
+	int initial_mixers;
 
+	initial_mixers = num_mixers;
 	attach_ms_sound(hw_config, THIS_MODULE);	/* Slot 0 */
-	if(hw_config->slots[0] != -1)
-	{
+	if(hw_config->slots[0] != -1) {
 		/* Did the MSS driver install? */
-		if(num_mixers == (opl3sa2_mixer + 2))
-		{
-			/* The MSS mixer is installed */
-			devc->ad_mixer_dev = audio_devs[hw_config->slots[0]]->mixer_dev;
-
-			/* Reroute mixers appropiately */
+		if(num_mixers == (initial_mixers + 1)) {
+			/* The MSS mixer is installed, reroute mixers appropiately */
 			AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_CD);
 			AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_SYNTH);
 			AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_LINE);
 		}
+		else {
+			printk(KERN_ERR "opl3sa2: MSS mixer not installed?\n");
+		}
 	}
 }
 
 
-static inline void __exit unload_opl3sa2_mss(struct address_info *hw_config)
+static inline void __exit unload_opl3sa2_mss(struct address_info* hw_config)
 {
 	unload_ms_sound(hw_config);
 }
 
 
-static int __init probe_opl3sa2(struct address_info *hw_config)
+static int __init probe_opl3sa2(struct address_info* hw_config, int card)
 {
-	unsigned char version = 0;
+	unsigned char misc;
+	unsigned char tmp;
+	unsigned char version;
 	char tag;
 
 	/*
 	 * Verify that the I/O port range is free.
 	 */
-	if(check_region(hw_config->io_base, 2))
-	{
-	    printk(KERN_ERR
-		   "%s: Control I/O port 0x%03x not free\n",
-		   __FILE__,
-		   hw_config->io_base);
-	    return 0;
+	if(check_region(hw_config->io_base, 2)) {
+		printk(KERN_ERR "opl3sa2: Control I/O port %#x not free\n",
+		       hw_config->io_base);
+		return 0;
 	}
 
 	/*
-	 * Determine chipset type (SA2, SA3, or SAx)
+	 * Check if writing to the read-only version bits of the miscellaneous
+	 * register succeeds or not (it should not).
 	 */
+	opl3sa2_read(hw_config->io_base, OPL3SA2_MISC, &misc);
+	opl3sa2_write(hw_config->io_base, OPL3SA2_MISC, misc ^ 0x07);
+	opl3sa2_read(hw_config->io_base, OPL3SA2_MISC, &tmp);
+	if(tmp != misc) {
+		printk(KERN_ERR "opl3sa2: Control I/O port %#x is not a YMF7xx chipset!\n",
+		       hw_config->io_base);
+		return 0;
+	}
 
 	/*
-	 * Look at chipset version in lower 3 bits of index 0x0A, miscellaneous
+	 * Check if the MIC register is accessible.
 	 */
-	opl3sa2_read(hw_config->io_base,
-		     OPL3SA2_MISC,
-		     (unsigned char*) &version);
-	version &= 0x07;
-
-	/* Match version number to appropiate chipset */
-	if(version & CHIPSET_OPL3SAX)
-	{
-		chipset = CHIPSET_OPL3SAX;
-		tag = 'x';
-		printk(KERN_INFO "Found OPL3-SAx (YMF719)\n");
+	opl3sa2_read(hw_config->io_base, OPL3SA2_MIC, &tmp);
+	opl3sa2_write(hw_config->io_base, OPL3SA2_MIC, 0x8a);
+	opl3sa2_read(hw_config->io_base, OPL3SA2_MIC, &tmp);
+	if((tmp & 0x9f) != 0x8a) {
+		printk(KERN_ERR
+		       "opl3sa2: Control I/O port %#x is not a YMF7xx chipset!\n",
+		       hw_config->io_base);
+		return 0;
 	}
-	else
-	{
- 		if(version & CHIPSET_OPL3SA3)
-		{
-			chipset = CHIPSET_OPL3SA3;
+	opl3sa2_write(hw_config->io_base, OPL3SA2_MIC, tmp);
+
+	/*
+	 * Determine chipset type (SA2 or SA3)
+	 *
+	 * This is done by looking at the chipset version in the lower 3 bits
+	 * of the miscellaneous register.
+	 */
+	version = misc & 0x07;
+	printk(KERN_DEBUG "opl3sa2: chipset version = %#x\n", version);
+	switch(version) {
+		case 0:
+			chipset[card] = CHIPSET_UNKNOWN;
+			tag = '?'; /* silence compiler warning */
+			printk(KERN_ERR
+			       "opl3sa2: Unknown Yamaha audio controller version\n");
+			break;
+
+		case VERSION_YMF711:
+			chipset[card] = CHIPSET_OPL3SA2;
+			tag = '2';
+			printk(KERN_INFO "opl3sa2: Found OPL3-SA2 (YMF711)\n");
+			break;
+
+		case VERSION_YMF715:
+			chipset[card] = CHIPSET_OPL3SA3;
 			tag = '3';
-			printk(KERN_INFO "Found OPL3-SA3 (YMF715)\n");
-		}
-		else
-		{
-			if(version & CHIPSET_OPL3SA2)
-			{
-				chipset = CHIPSET_OPL3SA2;
-				tag = '2';
-				printk(KERN_INFO "Found OPL3-SA2 (YMF711)\n");
-			}
-			else
-			{
-				chipset = CHIPSET_UNKNOWN;
-				tag = '?';
-				printk(KERN_ERR
-				       "Unknown Yamaha audio controller version\n");
-				printk(KERN_INFO
-				       "%s: chipset version = %x\n",
-				       __FILE__,
-				       version);
-			}
-		}
+			printk(KERN_INFO
+			       "opl3sa2: Found OPL3-SA3 (YMF715 or YMF719)\n");
+			break;
+
+		case VERSION_YMF715B:
+			chipset[card] = CHIPSET_OPL3SA3;
+			tag = '3';
+			printk(KERN_INFO
+			       "opl3sa2: Found OPL3-SA3 (YMF715B or YMF719B)\n");
+			break;
+
+		case VERSION_YMF715E:
+		default:
+			chipset[card] = CHIPSET_OPL3SA3;
+			tag = '3';
+			printk(KERN_INFO
+			       "opl3sa2: Found OPL3-SA3 (YMF715E or YMF719E)\n");
+			break;
 	}
 
-	if(chipset != CHIPSET_UNKNOWN)
-	{
+	if(chipset[card] != CHIPSET_UNKNOWN) {
 		/* Generate a pretty name */
-		sprintf(chipset_name, "OPL3-SA%c", tag);
+		sprintf(chipset_name[card], "OPL3-SA%c", tag);
 		return 1;
 	}
 	return 0;
 }
 
 
-static void __init attach_opl3sa2(struct address_info *hw_config)
+static void __init attach_opl3sa2(struct address_info* hw_config, int card)
+{
+   	request_region(hw_config->io_base, 2, chipset_name[card]);
+
+	/* Initialize IRQ configuration to IRQ-B: -, IRQ-A: WSS+MPU+OPL3 */
+	opl3sa2_write(hw_config->io_base, OPL3SA2_IRQ_CONFIG, 0x0d);
+
+	/* Initialize DMA configuration */
+	if(hw_config->dma2 == hw_config->dma) {
+		/* Want DMA configuration DMA-B: -, DMA-A: WSS-P+WSS-R */
+		opl3sa2_write(hw_config->io_base, OPL3SA2_DMA_CONFIG, 0x03);
+	}
+	else {
+		/* Want DMA configuration DMA-B: WSS-R, DMA-A: WSS-P */
+		opl3sa2_write(hw_config->io_base, OPL3SA2_DMA_CONFIG, 0x21);
+	}
+}
+
+
+static void __init attach_opl3sa2_mixer(struct address_info *hw_config, int card)
+{
+	struct mixer_operations* mixer_operations;
+	opl3sa2_mixerdata* devc;
+
+	/* Install master mixer */
+	if(chipset[card] == CHIPSET_OPL3SA3) {
+		mixer_operations = &opl3sa3_mixer_operations;
+	}
+	else {
+		mixer_operations = &opl3sa2_mixer_operations;
+	}
+
+	if((devc = &opl3sa2_data[card])) {
+		devc->cfg_port = hw_config->io_base;
+
+		opl3sa2_mixer[card] = sound_install_mixer(MIXER_DRIVER_VERSION,
+							  mixer_operations->name,
+							  mixer_operations,
+							  sizeof(struct mixer_operations),
+							  devc);
+		if(opl3sa2_mixer[card] < 0) {
+			printk(KERN_ERR "opl3sa2: Could not install %s master mixer\n",
+				 mixer_operations->name);
+		}
+		else
+			opl3sa2_mixer_reset(devc, card);
+	}
+}
+
+
+static void __init opl3sa2_clear_slots(struct address_info* hw_config)
+{
+	int i;
+
+	for(i = 0; i < 6; i++) {
+		hw_config->slots[i] = -1;
+	}
+}
+
+
+static void __init opl3sa2_set_ymode(struct address_info* hw_config, int ymode)
 {
-   	request_region(hw_config->io_base, 2, chipset_name);
+	/*
+	 * Set the Yamaha 3D enhancement mode (aka Ymersion) if asked to and
+	 * it's supported.
+	 *
+	 * 0: Desktop (aka normal)   5-12 cm speakers
+	 * 1: Notebook PC mode 1     3 cm speakers
+	 * 2: Notebook PC mode 2     1.5 cm speakers
+	 * 3: Hi-fi                  16-38 cm speakers
+	 */
+	if(ymode >= 0 && ymode <= 3) {
+		unsigned char sys_ctrl;
+
+		opl3sa2_read(hw_config->io_base, OPL3SA2_SYS_CTRL, &sys_ctrl);
+		sys_ctrl = (sys_ctrl & 0xcf) | ((ymode & 3) << 4);
+		opl3sa2_write(hw_config->io_base, OPL3SA2_SYS_CTRL, sys_ctrl);
+	}
+	else {
+		printk(KERN_ERR "opl3sa2: not setting ymode, it must be one of 0,1,2,3\n");
+	}
+}
+
+
+static void __init opl3sa2_set_loopback(struct address_info* hw_config, int loopback)
+{
+	if(loopback >= 0 && loopback <= 1) {
+		unsigned char misc;
 
-	devc->cfg_port = hw_config->io_base;
+		opl3sa2_read(hw_config->io_base, OPL3SA2_MISC, &misc);
+		misc = (misc & 0xef) | ((loopback & 1) << 4);
+		opl3sa2_write(hw_config->io_base, OPL3SA2_MISC, misc);
+	}
+	else {
+		printk(KERN_ERR "opl3sa2: not setting loopback, it must be either 0 or 1\n");
+	}
 }
 
 
-static void __exit unload_opl3sa2(struct address_info *hw_config)
+static void __exit unload_opl3sa2(struct address_info* hw_config, int card)
 {
         /* Release control ports */
 	release_region(hw_config->io_base, 2);
 
 	/* Unload mixer */
-	if(opl3sa2_mixer >= 0)
-		sound_unload_mixerdev(opl3sa2_mixer);
+	if(opl3sa2_mixer[card] >= 0)
+		sound_unload_mixerdev(opl3sa2_mixer[card]);
 }
 
-static struct address_info cfg;
-static struct address_info cfg2;
-static struct address_info cfg_mpu;
 
-static int __initdata io	= -1;
-static int __initdata mss_io	= -1;
-static int __initdata mpu_io	= -1;
-static int __initdata irq	= -1;
-static int __initdata dma	= -1;
-static int __initdata dma2	= -1;
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+static int __init opl3sa2_isapnp_probe(struct address_info* hw_cfg,
+				       struct address_info* mss_cfg,
+				       struct address_info* mpu_cfg,
+				       int card)
+{
+	static struct pci_dev* dev;
+	int ret;
+
+	/* Find and configure device */
+	dev = isapnp_find_dev(NULL,
+			      ISAPNP_VENDOR('Y','M','H'),
+			      ISAPNP_FUNCTION(0x0021),
+			      dev);
+	if(dev == NULL) {
+		return -ENODEV;
+	}
 
-MODULE_PARM(io, "i");
-MODULE_PARM_DESC(io, "Set i/o base of OPL3-SA2 or SA3 card (usually 0x370)");
+	/*
+	 * If device is active, assume configured with /proc/isapnp
+	 * and use anyway. Any other way to check this?
+	 */
+	ret = dev->prepare(dev);
+	if(ret && ret != -EBUSY) {
+		printk(KERN_ERR "opl3sa2: ISA PnP found device that could not be autoconfigured.\n");
+		return -ENODEV;
+	}
+	if(ret == -EBUSY) {
+		opl3sa2_activated[card] = 1;
+	}
+	else {
+		if(dev->activate(dev) < 0) {
+			printk(KERN_WARNING "opl3sa2: ISA PnP activate failed\n");
+			opl3sa2_activated[card] = 0;
+			return -ENODEV;
+		}
 
-MODULE_PARM(mss_io, "i");
-MODULE_PARM_DESC(mss_io, "Set MSS (audio) I/O base (0x530, 0xE80, or other. Address must end in 0 or 4 and must be from 0x530 to 0xF48)");
+		printk(KERN_DEBUG
+		       "opl3sa2: Activated ISA PnP card %d (active=%d)\n",
+		       card, dev->active);
 
-MODULE_PARM(mpu_io, "i");
-MODULE_PARM_DESC(mpu_io, "Set MIDI I/O base (0x330 or other. Address must be on 4 location boundaries and must be from 0x300 to 0x334)");
+	}
 
-MODULE_PARM(irq, "i");
-MODULE_PARM_DESC(mss_irq, "Set MSS (audio) IRQ (5, 7, 9, 10, 11, 12)");
+	/* Our own config: */
+	hw_cfg->io_base = dev->resource[4].start;
+	hw_cfg->irq     = 0;
+	hw_cfg->dma     = -1;
+	hw_cfg->dma2    = -1;
+	
+	/* The MSS config: */
+	mss_cfg->io_base      = dev->resource[1].start;
+	mss_cfg->irq          = dev->irq_resource[0].start;
+	mss_cfg->dma          = dev->dma_resource[0].start;
+	mss_cfg->dma2         = dev->dma_resource[1].start;
+	mss_cfg->card_subtype = 1; /* No IRQ or DMA setup */
+
+	mpu_cfg->io_base       = dev->resource[3].start;
+	mpu_cfg->irq           = dev->irq_resource[0].start;
+	mpu_cfg->dma           = -1;
+	mpu_cfg->dma2          = -1;
+	mpu_cfg->always_detect = 1; /* It's there, so use shared IRQs */
 
-MODULE_PARM(dma, "i");
-MODULE_PARM_DESC(dma, "Set MSS (audio) first DMA channel (0, 1, 3)");
+	/* Call me paranoid: */
+	opl3sa2_clear_slots(hw_cfg);
+	opl3sa2_clear_slots(mss_cfg);
+	opl3sa2_clear_slots(mpu_cfg);
 
-MODULE_PARM(dma2, "i");
-MODULE_PARM_DESC(dma2, "Set MSS (audio) second DMA channel (0, 1, 3)");
+	opl3sa2_dev[card] = dev;
+
+	return 0;
+}
+#endif /* CONFIG_ISAPNP || CONFIG_ISAPNP_MODULE */
+
+/* End of component functions */
 
-MODULE_DESCRIPTION("Module for OPL3-SA2 and SA3 sound cards (uses AD1848 MSS driver).");
-MODULE_AUTHOR("Scott Murray <scottm@interlog.com>");
 
 /*
- * Install a OPL3SA2 based card.
+ * Install OPL3-SA2 based card(s).
  *
  * Need to have ad1848 and mpu401 loaded ready.
  */
 static int __init init_opl3sa2(void)
 {
-        int i;
+        int card;
+	int max;
 
-        /* Our own config: */
-        cfg.io_base = io;
-	cfg.irq     = irq;
-	cfg.dma     = dma;
-	cfg.dma2    = dma2;
-	
-        /* The MSS config: */
-	cfg2.io_base      = mss_io;
-	cfg2.irq          = irq;
-	cfg2.dma          = dma;
-	cfg2.dma2         = dma2;
-	cfg2.card_subtype = 1;      /* No IRQ or DMA setup */
-
-	cfg_mpu.io_base       = mpu_io;
-	cfg_mpu.irq           = irq;
-	cfg_mpu.dma           = dma;
-	cfg_mpu.always_detect = 1;  /* It's there, so use shared IRQs */
+	/* Sanitize isapnp and multiple settings */
+	isapnp = isapnp != 0 ? 1 : 0;
+	multiple = multiple != 0 ? 1 : 0;
+
+	max = (multiple && isapnp) ? OPL3SA2_CARDS_MAX : 1;
+	for(card = 0; card < max; card++, opl3sa2_cards_num++) {
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+		/*
+		 * Please remember that even with CONFIG_ISAPNP defined one
+		 * should still be able to disable PNP support for this 
+		 * single driver!
+		 */
+		if(isapnp && opl3sa2_isapnp_probe(&cfg[card],
+						  &cfg_mss[card],
+						  &cfg_mpu[card],
+						  card) < 0) {
+			if(!opl3sa2_cards_num)
+				printk(KERN_NOTICE "opl3sa2: No cards found\n");
+			break;
+		}
+#endif
+		if(!isapnp) {
+			if(io == -1 || irq == -1 || dma == -1 ||
+			   dma2 == -1 || mss_io == -1) {
+				printk(KERN_ERR
+				       "opl3sa2: io, mss_io, irq, dma, and dma2 must be set\n");
+				return -EINVAL;
+			}
 
-	if(cfg.io_base == -1 || cfg.irq == -1 || cfg.dma == -1 || cfg.dma2 == -1 || cfg2.io_base == -1) {
-		printk(KERN_ERR "opl3sa2: io, mss_io, irq, dma, and dma2 must be set.\n");
-		return -EINVAL;
-	}
+			/*
+			 * Our own config:
+			 * (NOTE: IRQ and DMA aren't used, so they're set to
+			 *  give pretty output from conf_printf. :)
+			 */
+			cfg[card].io_base = io;
+			cfg[card].irq     = 0;
+			cfg[card].dma     = -1;
+			cfg[card].dma2    = -1;
+	
+			/* The MSS config: */
+			cfg_mss[card].io_base      = mss_io;
+			cfg_mss[card].irq          = irq;
+			cfg_mss[card].dma          = dma;
+			cfg_mss[card].dma2         = dma2;
+			cfg_mss[card].card_subtype = 1; /* No IRQ or DMA setup */
+
+			cfg_mpu[card].io_base       = mpu_io;
+			cfg_mpu[card].irq           = irq;
+			cfg_mpu[card].dma           = -1;
+			cfg_mpu[card].always_detect = 1; /* Use shared IRQs */
+
+			/* Call me paranoid: */
+			opl3sa2_clear_slots(&cfg[card]);
+			opl3sa2_clear_slots(&cfg_mss[card]);
+			opl3sa2_clear_slots(&cfg_mpu[card]);
+		}
 
-	/* Call me paranoid: */
-	for(i = 0; i < 6; i++)
-	{
-		cfg.slots[i] = cfg2.slots[i] = cfg_mpu.slots[i] = -1;
-	}
+		if(!probe_opl3sa2(&cfg[card], card) ||
+		   !probe_opl3sa2_mss(&cfg_mss[card])) {
+			/*
+			 * If one or more cards are already registered, don't
+			 * return an error but print a warning.  Note, this
+			 * should never really happen unless the hardware or
+			 * ISA PnP screwed up.
+			 */
+			if(opl3sa2_cards_num) {
+				printk(KERN_WARNING
+				       "opl3sa2: There was a problem probing one "
+				       " of the ISA PNP cards, continuing\n");
+				opl3sa2_cards_num--;
+				continue;
+			} else
+				return -ENODEV;
+		}
 
-	if(probe_opl3sa2(&cfg) == 0)
-	{
-		return -ENODEV;
-	}
+		attach_opl3sa2(&cfg[card], card);
+		conf_printf(chipset_name[card], &cfg[card]);
+		attach_opl3sa2_mss(&cfg_mss[card]);
+		attach_opl3sa2_mixer(&cfg[card], card);
 
-	if(probe_opl3sa2_mss(&cfg2) == 0)
-	{
-		return -ENODEV;
-	}
+		/*
+		 * Set the Yamaha 3D enhancement mode (aka Ymersion) if asked to and
+		 * it's supported.
+		 */
+		if(ymode != -1) {
+			if(chipset[card] == CHIPSET_OPL3SA2) {
+				printk(KERN_ERR
+				       "opl3sa2: ymode not supported on OPL3-SA2\n");
+			}
+			else {
+				opl3sa2_set_ymode(&cfg[card], ymode);
+			}
+		}
 
-	attach_opl3sa2(&cfg);
-	attach_opl3sa2_mss(&cfg2);
 
-	if(cfg_mpu.io_base != -1) {
-		if(probe_opl3sa2_mpu(&cfg_mpu)) {
-			attach_opl3sa2_mpu(&cfg_mpu);
+		/* Set A/D input to Mono loopback if asked to. */
+		if(loopback != -1) {
+			opl3sa2_set_loopback(&cfg[card], loopback);
 		}
+		
+		/* Attach MPU if we've been asked to do so */
+		if(cfg_mpu[card].io_base != -1) {
+			if(probe_opl3sa2_mpu(&cfg_mpu[card])) {
+				attach_opl3sa2_mpu(&cfg_mpu[card]);
+			}
+		}
+	}
+
+	if(isapnp) {
+		printk(KERN_NOTICE "opl3sa2: %d PnP card(s) found.\n", opl3sa2_cards_num);
 	}
 
 	return 0;
 }
 
 
+/*
+ * Uninstall OPL3-SA2 based card(s).
+ */
 static void __exit cleanup_opl3sa2(void)
 {
-        if(cfg_mpu.slots[1] != -1) {
-		unload_opl3sa2_mpu(&cfg_mpu);
+	int card;
+
+	for(card = 0; card < opl3sa2_cards_num; card++) {
+	        if(cfg_mpu[card].slots[1] != -1) {
+			unload_opl3sa2_mpu(&cfg_mpu[card]);
+		}
+		unload_opl3sa2_mss(&cfg_mss[card]);
+		unload_opl3sa2(&cfg[card], card);
+
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+		if(opl3sa2_activated[card] && opl3sa2_dev[card]) {
+			opl3sa2_dev[card]->deactivate(opl3sa2_dev[card]);
+
+			printk(KERN_DEBUG
+			       "opl3sa2: Deactivated ISA PnP card %d (active=%d)\n",
+			       card, opl3sa2_dev[card]->active);
+		}
+#endif
 	}
-	unload_opl3sa2_mss(&cfg2);
-	unload_opl3sa2(&cfg);
 }
 
 module_init(init_opl3sa2);
@@ -719,18 +1039,26 @@
 #ifndef MODULE
 static int __init setup_opl3sa2(char *str)
 {
-	/* io, irq, dma, dma2 */
-	int ints[7];
-	
+	/* io, irq, dma, dma2,... */
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+	int ints[11];
+#else
+	int ints[9];
+#endif
 	str = get_options(str, ARRAY_SIZE(ints), ints);
 	
-	io	= ints[1];
-	irq	= ints[2];
-	dma	= ints[3];
-	dma2	= ints[4];
-	mss_io	= ints[5];
-	mpu_io	= ints[6];
-
+	io       = ints[1];
+	irq      = ints[2];
+	dma      = ints[3];
+	dma2     = ints[4];
+	mss_io   = ints[5];
+	mpu_io   = ints[6];
+	ymode    = ints[7];
+	loopback = ints[8];
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+	isapnp   = ints[9];
+	multiple = ints[10];
+#endif
 	return 1;
 }
 
diff -urN linux-2.4.2-pre1/drivers/sound/pss.c linux/drivers/sound/pss.c
--- linux-2.4.2-pre1/drivers/sound/pss.c	Sat Nov 11 18:33:14 2000
+++ linux/drivers/sound/pss.c	Mon Dec  3 22:27:48 2001
@@ -52,6 +52,8 @@
  *	    Adapted to module_init/module_exit
  * 11-10-2000: Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
  *	    Added __init to probe_pss(), attach_pss() and probe_pss_mpu()
+ * 02-Jan-2001: Chris Rankin
+ *          Specify that this module owns the coprocessor
  */
 
 
@@ -979,6 +981,7 @@
 static coproc_operations pss_coproc_operations =
 {
 	"ADSP-2115",
+	THIS_MODULE,
 	pss_coproc_open,
 	pss_coproc_close,
 	pss_coproc_ioctl,
diff -urN linux-2.4.2-pre1/drivers/sound/sb_card.c linux/drivers/sound/sb_card.c
--- linux-2.4.2-pre1/drivers/sound/sb_card.c	Sun Dec 31 09:27:57 2000
+++ linux/drivers/sound/sb_card.c	Mon Dec  3 22:27:48 2001
@@ -484,6 +484,188 @@
 	{0}
 };
 
+static struct isapnp_device_id id_table[] __devinitdata = {
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0024),
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0025),
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0026), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0027), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0028), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0029), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x002a),
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x002b), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0051), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0001), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0070), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0001), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0080), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00F0), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0043), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0039), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0042), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0043), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0044),
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0048), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0054), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009C), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009F),
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009D), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0042), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009E), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0044), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00B2),
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0044), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C1), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0042), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C3), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C5), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C7), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00E4), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), 0 },
+
+	{	ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x0968), 
+		ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x0968), 0 },
+
+	{	ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1868), 
+		ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1868), 0 },
+
+	{	ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1868), 
+		ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x8611), 0 },
+
+	{	ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x0003), 
+		ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1869), 0 },
+
+	{	ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1869), 
+		ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1869), 0 },
+
+	{	ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1878), 
+		ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1878), 0 },
+
+	{	ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1879), 
+		ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1879), 0 },
+
+	{	ISAPNP_VENDOR('C','M','I'), ISAPNP_DEVICE(0x0001), 
+		ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001), 0 },
+
+	{	ISAPNP_VENDOR('C','M','I'), ISAPNP_DEVICE(0x0001), 
+		ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0 },
+
+	{	ISAPNP_VENDOR('C','M','I'), ISAPNP_DEVICE(0x0001), 
+		ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001), 0 },
+
+	{	ISAPNP_VENDOR('R','W','B'), ISAPNP_DEVICE(0x1688), 
+		ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001), 0 },
+
+	{	ISAPNP_VENDOR('R','W','B'), ISAPNP_DEVICE(0x1688), 
+		ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001), 0 },
+
+	{	ISAPNP_VENDOR('R','W','B'), ISAPNP_DEVICE(0x1688), 
+		ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0 },
+
+	{	ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0007),
+		ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001), 0 },
+
+	{	ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0007),
+		ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001), 0 },
+
+	{	ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0007),
+		ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0 },
+
+	{	ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0001), 
+		ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001), 0 },
+
+	{	ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0001), 
+		ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001), 0 },
+
+	{	ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0001), 
+		ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0 },
+
+	{	ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0110),
+		ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x1001), 0 },
+
+	{	ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0110),
+		ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x1001), 0 },
+
+	{	ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0110),
+		ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0 },
+
+	{	ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0120),
+		ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x2001), 0 },
+
+	{	ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0120),
+		ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x2001), 0 },
+
+	{	ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0120),
+		ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0 },
+
+	{	ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0200),
+		ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0020), 0 },
+
+	{	ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0200),
+		ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0020), 0 },
+
+	{	ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0200),
+		ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0 },
+
+	{	ISAPNP_VENDOR('R','T','L'), ISAPNP_DEVICE(0x3000),
+		ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x2001), 0 },
+
+	{	ISAPNP_VENDOR('R','T','L'), ISAPNP_DEVICE(0x3000),
+		ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x2001), 0 },
+
+	{	ISAPNP_VENDOR('R','T','L'), ISAPNP_DEVICE(0x3000),
+		ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0 },
+	{0}
+};
+
+MODULE_DEVICE_TABLE(isapnp, id_table);
+
 static struct pci_dev *activate_dev(char *devname, char *resname, struct pci_dev *dev)
 {
 	int err;
diff -urN linux-2.4.2-pre1/drivers/sound/sscape.c linux/drivers/sound/sscape.c
--- linux-2.4.2-pre1/drivers/sound/sscape.c	Sat Nov 11 18:33:14 2000
+++ linux/drivers/sound/sscape.c	Mon Dec  3 22:27:48 2001
@@ -15,6 +15,8 @@
  * Sergey Smitienko	: ensoniq p'n'p support
  * Christoph Hellwig	: adapted to module_init/module_exit
  * Bartlomiej Zolnierkiewicz : added __init to attach_sscape()
+ * Chris Rankin		: Specify that this module owns the coprocessor
+ * Arnaldo C. de Melo	: added missing restore_flags in sscape_pnp_upload_file
  */
 
 #include <linux/init.h>
@@ -600,6 +602,7 @@
 static coproc_operations sscape_coproc_operations =
 {
 	"SoundScape M68K",
+	THIS_MODULE,
 	sscape_coproc_open,
 	sscape_coproc_close,
 	sscape_coproc_ioctl,
@@ -671,7 +674,7 @@
 		return;
 	}
 	
-	if (sscape_is_pnp == 0) {
+	if (!sscape_is_pnp) {
 	
 	    save_flags(flags);
 	    cli();
@@ -967,7 +970,10 @@
 		memcpy(devc->raw_buf, dt, l); dt += l;
 		sscape_start_dma(devc->dma, devc->raw_buf_phys, l, 0x48);
 		sscape_pnp_start_dma ( devc, 0 );
-		if (sscape_pnp_wait_dma ( devc, 0 ) == 0) return 0;
+		if (sscape_pnp_wait_dma ( devc, 0 ) == 0) {
+			restore_flags(flags);	    
+			return 0;
+		}
 	}
 	
 	restore_flags(flags);	    
@@ -1087,8 +1093,8 @@
 		sscape_pnp_write_codec( devc, 10, (sscape_pnp_read_codec(devc, 10) & 0x7f) |
 		 ( sscape_mic_enable == 0 ? 0x00 : 0x80) );
 	}
-	sscape_write_host_ctrl2( devc, 0x84, 0x32 );
-	sscape_write_host_ctrl2( devc, 0x86, 0x32 );
+	sscape_write_host_ctrl2( devc, 0x84, 0x64 );  /* MIDI volume */
+	sscape_write_host_ctrl2( devc, 0x86, 0x64 );  /* MIDI volume?? */
 	sscape_write_host_ctrl2( devc, 0x8A, sscape_ext_midi);
 
 	sscape_pnp_write_codec ( devc, 6, 0x3f ); //WAV_VOL
@@ -1239,10 +1245,7 @@
 
 	sscape_pnp_write_codec( devc, 0, sscape_pnp_read_codec( devc, 0) | 0x20);
 	sscape_pnp_write_codec( devc, 0, sscape_pnp_read_codec( devc, 1) | 0x20);
-	
-	release_region(devc->codec, 2);
-	release_region(devc->base, 8);		
-		
+
 	return 1;	
 }
 
diff -urN linux-2.4.2-pre1/drivers/sound/uart401.c linux/drivers/sound/uart401.c
--- linux-2.4.2-pre1/drivers/sound/uart401.c	Wed Sep 27 13:53:57 2000
+++ linux/drivers/sound/uart401.c	Mon Dec  3 22:27:48 2001
@@ -202,7 +202,7 @@
 #define MIDI_SYNTH_CAPS	SYNTH_CAP_INPUT
 #include "midi_synth.h"
 
-static struct midi_operations uart401_operations =
+static const struct midi_operations uart401_operations =
 {
 	owner:		THIS_MODULE,
 	info:		{"MPU-401 (UART) MIDI", 0, 0, SNDCARD_MPU401},
@@ -351,7 +351,6 @@
 		goto cleanup_irq;
 	}
 	conf_printf(name, hw_config);
-	std_midi_synth.midi_dev = devc->my_dev;
 	midi_devs[devc->my_dev] = kmalloc(sizeof(struct midi_operations), GFP_KERNEL);
 	if (!midi_devs[devc->my_dev]) {
 		printk(KERN_ERR "uart401: Failed to allocate memory\n");
@@ -371,6 +370,11 @@
 	memcpy(midi_devs[devc->my_dev]->converter, &std_midi_synth, sizeof(struct synth_operations));
 	strcpy(midi_devs[devc->my_dev]->info.name, name);
 	midi_devs[devc->my_dev]->converter->id = "UART401";
+	midi_devs[devc->my_dev]->converter->midi_dev = devc->my_dev;
+
+	if (owner)
+		midi_devs[devc->my_dev]->converter->owner = owner;
+
 	hw_config->slots[4] = devc->my_dev;
 	sequencer_init();
 	devc->opened = 0;
diff -urN linux-2.4.2-pre1/drivers/sound/via82cxxx_audio.c linux/drivers/sound/via82cxxx_audio.c
--- linux-2.4.2-pre1/drivers/sound/via82cxxx_audio.c	Wed Jan 24 15:30:43 2001
+++ linux/drivers/sound/via82cxxx_audio.c	Mon Dec  3 22:27:48 2001
@@ -34,8 +34,8 @@
 #include <linux/smp_lock.h>
 #include <linux/ioport.h>
 #include <linux/wrapper.h>
+#include <linux/delay.h>
 #include <asm/io.h>
-#include <asm/delay.h>
 #include <asm/uaccess.h>
 #include <asm/hardirq.h>
 #include <asm/semaphore.h>
@@ -1535,6 +1535,9 @@
 
 	/* acknowledge any flagged bits ASAP */
 	outb (status, chan->iobase);
+
+	if (!chan->sgtable) /* XXX: temporary solution */
+		return;
 
 	/* grab current h/w ptr value */
 	n = atomic_read (&chan->hw_ptr);
diff -urN linux-2.4.2-pre1/drivers/sound/ymf_sb.c linux/drivers/sound/ymf_sb.c
--- linux-2.4.2-pre1/drivers/sound/ymf_sb.c	Sun Dec 31 10:26:17 2000
+++ linux/drivers/sound/ymf_sb.c	Wed Dec 31 16:00:00 1969
@@ -1,853 +0,0 @@
-/*
-  Legacy audio driver for YMF724, 740, 744, 754 series.
-  Copyright 2000 Daisuke Nagano <breeze.nagano@nifty.ne.jp>
-
-  Based on the VIA 82Cxxx driver by Jeff Garzik <jgarzik@pobox.com>
-  And ported to 2.3.x by Jeff Garzik too :)  My it is a small world.
-
-  Distribued under the GNU PUBLIC LICENSE (GPL) Version 2.
-  See the "COPYING" file distributed with kernel source tree for more info.
-
-  -------------------------------------------------------------------------
-
-  It only supports SBPro compatible function of YMF7xx series s.t.
-    * 22.05kHz, 8-bit and stereo sample
-    * OPL3-compatible FM synthesizer
-    * MPU-401 compatible "external" MIDI interface
-
-  -------------------------------------------------------------------------
-
-  Revision history
-
-   Tue May 14 19:00:00 2000   0.0.1
-   * initial release
-
-   Tue May 16 19:29:29 2000   0.0.2
-
-   * add a little delays for reset devices.
-   * fixed addressing bug.
-
-   Sun May 21 15:14:37 2000   0.0.3
-
-   * Add 'master_vol' module parameter to change 'PCM out Vol' of AC'97.
-   * remove native UART401 support. External MIDI port should be supported 
-     by sb_midi driver.
-   * add support for SPDIF OUT. Module parameter 'spdif_out' is now available.
-
-   Wed May 31 00:13:57 2000   0.0.4
-
-   * remove entries in Hwmcode.h. Now YMF744 / YMF754 sets instructions 
-     in 724hwmcode.h.
-   * fixed wrong legacy_io setting on YMF744/YMF754 .
-
-   Thu Sep 21 05:32:51 BRT 2000 0.0.5
-   * got rid of attach_uart401 and attach_sbmpu
-     Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/ac97_codec.h>
-
-#include <asm/io.h>
-
-#include "sound_config.h"
-#include "sb.h"
-
-#include "724hwmcode.h"
-
-#undef YMF_DEBUG
-#define SUPPORT_UART401_MIDI 1
-
-/* ---------------------------------------------------------------------- */
-
-#ifndef PCI_VENDOR_ID_YAMAHA
-#define PCI_VENDOR_ID_YAMAHA  0x1073
-#endif
-#ifndef PCI_DEVICE_ID_YMF724
-#define PCI_DEVICE_ID_YMF724  0x0004
-#endif
-#ifndef PCI_DEVICE_ID_YMF740
-#define PCI_DEVICE_ID_YMF740  0x000A
-#endif
-#ifndef PCI_DEVICE_ID_YMF740C
-#define PCI_DEVICE_ID_YMF740C 0x000C
-#endif
-#ifndef PCI_DEVICE_ID_YMF724F
-#define PCI_DEVICE_ID_YMF724F 0x000D
-#endif
-#ifndef PCI_DEVICE_ID_YMF744
-#define PCI_DEVICE_ID_YMF744  0x0010
-#endif
-#ifndef PCI_DEVICE_ID_YMF754
-#define PCI_DEVICE_ID_YMF754  0x0012
-#endif
-
-/* ---------------------------------------------------------------------- */
-
-#define YMFSB_RESET_DELAY               5
-
-#define YMFSB_REGSIZE                   0x8000
-
-#define YMFSB_AC97TIMEOUT               2000
-
-#define	YMFSB_WORKBITTIMEOUT            250000
-
-#define	YMFSB_DSPLENGTH                 0x0080
-#define	YMFSB_CTRLLENGTH                0x3000
-
-#define YMFSB_PCIR_VENDORID             0x00
-#define YMFSB_PCIR_DEVICEID             0x02
-#define YMFSB_PCIR_CMD                  0x04
-#define YMFSB_PCIR_REVISIONID           0x08
-#define YMFSB_PCIR_BASEADDR             0x10
-#define YMFSB_PCIR_IRQ                  0x3c
-
-#define	YMFSB_PCIR_LEGCTRL              0x40
-#define	YMFSB_PCIR_ELEGCTRL             0x42
-#define	YMFSB_PCIR_DSXGCTRL             0x48
-#define YMFSB_PCIR_OPLADR               0x60
-#define YMFSB_PCIR_SBADR                0x62
-#define YMFSB_PCIR_MPUADR               0x64
-
-#define	YMFSB_INTFLAG                   0x0004
-#define	YMFSB_ACTIVITY                  0x0006
-#define	YMFSB_GLOBALCTRL                0x0008
-#define	YMFSB_ZVCTRL                    0x000A
-#define	YMFSB_TIMERCTRL                 0x0010
-#define	YMFSB_TIMERCOUNT                0x0012
-#define	YMFSB_SPDIFOUTCTRL              0x0018
-#define	YMFSB_SPDIFOUTSTATUS            0x001C
-#define	YMFSB_EEPROMCTRL                0x0020
-#define	YMFSB_SPDIFINCTRL               0x0034
-#define	YMFSB_SPDIFINSTATUS             0x0038
-#define	YMFSB_DSPPROGRAMDL              0x0048
-#define	YMFSB_DLCNTRL                   0x004C
-#define	YMFSB_GPIOININTFLAG             0x0050
-#define	YMFSB_GPIOININTENABLE           0x0052
-#define	YMFSB_GPIOINSTATUS              0x0054
-#define	YMFSB_GPIOOUTCTRL               0x0056
-#define	YMFSB_GPIOFUNCENABLE            0x0058
-#define	YMFSB_GPIOTYPECONFIG            0x005A
-#define	YMFSB_AC97CMDDATA               0x0060
-#define	YMFSB_AC97CMDADR                0x0062
-#define	YMFSB_PRISTATUSDATA             0x0064
-#define	YMFSB_PRISTATUSADR              0x0066
-#define	YMFSB_SECSTATUSDATA             0x0068
-#define	YMFSB_SECSTATUSADR              0x006A
-#define	YMFSB_SECCONFIG                 0x0070
-#define	YMFSB_LEGACYOUTVOL              0x0080
-#define	YMFSB_LEGACYOUTVOLL             0x0080
-#define	YMFSB_LEGACYOUTVOLR             0x0082
-#define	YMFSB_NATIVEDACOUTVOL           0x0084
-#define	YMFSB_NATIVEDACOUTVOLL          0x0084
-#define	YMFSB_NATIVEDACOUTVOLR          0x0086
-#define	YMFSB_SPDIFOUTVOL               0x0088
-#define	YMFSB_SPDIFOUTVOLL              0x0088
-#define	YMFSB_SPDIFOUTVOLR              0x008A
-#define	YMFSB_AC3OUTVOL                 0x008C
-#define	YMFSB_AC3OUTVOLL                0x008C
-#define	YMFSB_AC3OUTVOLR                0x008E
-#define	YMFSB_PRIADCOUTVOL              0x0090
-#define	YMFSB_PRIADCOUTVOLL             0x0090
-#define	YMFSB_PRIADCOUTVOLR             0x0092
-#define	YMFSB_LEGACYLOOPVOL             0x0094
-#define	YMFSB_LEGACYLOOPVOLL            0x0094
-#define	YMFSB_LEGACYLOOPVOLR            0x0096
-#define	YMFSB_NATIVEDACLOOPVOL          0x0098
-#define	YMFSB_NATIVEDACLOOPVOLL         0x0098
-#define	YMFSB_NATIVEDACLOOPVOLR         0x009A
-#define	YMFSB_SPDIFLOOPVOL              0x009C
-#define	YMFSB_SPDIFLOOPVOLL             0x009E
-#define	YMFSB_SPDIFLOOPVOLR             0x009E
-#define	YMFSB_AC3LOOPVOL                0x00A0
-#define	YMFSB_AC3LOOPVOLL               0x00A0
-#define	YMFSB_AC3LOOPVOLR               0x00A2
-#define	YMFSB_PRIADCLOOPVOL             0x00A4
-#define	YMFSB_PRIADCLOOPVOLL            0x00A4
-#define	YMFSB_PRIADCLOOPVOLR            0x00A6
-#define	YMFSB_NATIVEADCINVOL            0x00A8
-#define	YMFSB_NATIVEADCINVOLL           0x00A8
-#define	YMFSB_NATIVEADCINVOLR           0x00AA
-#define	YMFSB_NATIVEDACINVOL            0x00AC
-#define	YMFSB_NATIVEDACINVOLL           0x00AC
-#define	YMFSB_NATIVEDACINVOLR           0x00AE
-#define	YMFSB_BUF441OUTVOL              0x00B0
-#define	YMFSB_BUF441OUTVOLL             0x00B0
-#define	YMFSB_BUF441OUTVOLR             0x00B2
-#define	YMFSB_BUF441LOOPVOL             0x00B4
-#define	YMFSB_BUF441LOOPVOLL            0x00B4
-#define	YMFSB_BUF441LOOPVOLR            0x00B6
-#define	YMFSB_SPDIFOUTVOL2              0x00B8
-#define	YMFSB_SPDIFOUTVOL2L             0x00B8
-#define	YMFSB_SPDIFOUTVOL2R             0x00BA
-#define	YMFSB_SPDIFLOOPVOL2             0x00BC
-#define	YMFSB_SPDIFLOOPVOL2L            0x00BC
-#define	YMFSB_SPDIFLOOPVOL2R            0x00BE
-#define	YMFSB_ADCSLOTSR                 0x00C0
-#define	YMFSB_RECSLOTSR                 0x00C4
-#define	YMFSB_ADCFORMAT                 0x00C8
-#define	YMFSB_RECFORMAT                 0x00CC
-#define	YMFSB_P44SLOTSR                 0x00D0
-#define	YMFSB_STATUS                    0x0100
-#define	YMFSB_CTRLSELECT                0x0104
-#define	YMFSB_MODE                      0x0108
-#define	YMFSB_SAMPLECOUNT               0x010C
-#define	YMFSB_NUMOFSAMPLES              0x0110
-#define	YMFSB_CONFIG                    0x0114
-#define	YMFSB_PLAYCTRLSIZE              0x0140
-#define	YMFSB_RECCTRLSIZE               0x0144
-#define	YMFSB_EFFCTRLSIZE               0x0148
-#define	YMFSB_WORKSIZE                  0x014C
-#define	YMFSB_MAPOFREC                  0x0150
-#define	YMFSB_MAPOFEFFECT               0x0154
-#define	YMFSB_PLAYCTRLBASE              0x0158
-#define	YMFSB_RECCTRLBASE               0x015C
-#define	YMFSB_EFFCTRLBASE               0x0160
-#define	YMFSB_WORKBASE                  0x0164
-#define	YMFSB_DSPINSTRAM                0x1000
-#define	YMFSB_CTRLINSTRAM               0x4000
-
-
-/* ---------------------------------------------------------------------- */
-
-#define MAX_CARDS	4
-
-#define PFX		"ymf_sb: "
-
-#define YMFSB_VERSION	"0.0.6"
-#define YMFSB_CARD_NAME	"YMF7xx Legacy Audio driver " YMFSB_VERSION
-
-#ifdef SUPPORT_UART401_MIDI
-#if 0
-# define ymf7xxsb_probe_midi probe_uart401
-# define ymf7xxsb_unload_midi unload_uart401
-#else
-# define ymf7xxsb_probe_midi probe_sbmpu
-# define ymf7xxsb_unload_midi unload_sbmpu
-#endif
-#endif
-
-/* ---------------------------------------------------------------------- */
-
-static struct address_info	sb_data[MAX_CARDS];
-static struct address_info	opl3_data[MAX_CARDS];
-#ifdef SUPPORT_UART401_MIDI
-static struct address_info	mpu_data[MAX_CARDS];
-#endif
-static unsigned			cards = 0;
-static unsigned short          *ymfbase[MAX_CARDS];
-
-/* ---------------------------------------------------------------------- */
-
-#ifdef MODULE
-#ifdef SUPPORT_UART401_MIDI
-static int mpu_io   = 0;
-#endif
-static int synth_io = 0;
-static int io       = 0;
-static int dma      = 0;
-static int master_vol = -1;
-static int spdif_out = 0;
-#ifdef SUPPORT_UART401_MIDI
-MODULE_PARM(mpu_io, "i");
-#endif
-MODULE_PARM(synth_io, "i");
-MODULE_PARM(io,"i");
-MODULE_PARM(dma,"i");
-MODULE_PARM(master_vol,"i");
-MODULE_PARM(spdif_out,"i");
-#else
-#ifdef SUPPORT_UART401_MIDI
-static int mpu_io     = 0x330;
-#endif
-static int synth_io   = 0x388;
-static int io         = 0x220;
-static int dma        = 1;
-static int master_vol = 80;
-static int spdif_out  = 0;
-#endif
-
-/* ---------------------------------------------------------------------- */
-
-static int readRegWord( int adr ) {
-
-	if (ymfbase[cards]==NULL) return 0;
-
-	return readw(ymfbase[cards]+adr/2);
-}
-
-static void writeRegWord( int adr, int val ) {
-
-	if (ymfbase[cards]==NULL) return;
-
-	writew((unsigned short)(val&0xffff), ymfbase[cards] + adr/2);
-
-	return;
-}
-
-static int readRegDWord( int adr ) {
-
-	if (ymfbase[cards]==NULL) return 0;
-
-	return (readl(ymfbase[cards]+adr/2));
-}
-
-static void writeRegDWord( int adr, int val ) {
-
-	if (ymfbase[cards]==NULL) return;
-
-	writel((unsigned int)(val&0xffffffff), ymfbase[cards]+adr/2);
-
-	return;
-}
-
-/* ---------------------------------------------------------------------- */
-
-static int checkPrimaryBusy( void )
-{
-	int timeout=0;
-
-	while ( timeout++ < YMFSB_AC97TIMEOUT )
-	{
-		if ( (readRegWord(YMFSB_PRISTATUSADR) & 0x8000) == 0x0000 )
-			return 0;
-	}
-	return -1;
-}
-
-static int writeAc97( int adr, unsigned short val )
-{
-
-	if ( adr > 0x7f || adr < 0x00 ) return -1;
-
-	if ( checkPrimaryBusy() ) return -1;
-
-#ifdef YMF_DEBUG
-	printk(KERN_INFO PFX "AC97 0x%0x = 0x%0x\n",adr,val);
-#endif
-
-	writeRegWord( YMFSB_AC97CMDADR,  0x0000 | adr );
-	writeRegWord( YMFSB_AC97CMDDATA, val );
-
-	return 0;
-}
-
-static int __init checkCodec( struct pci_dev *pcidev )
-{
-	u8 tmp8;
-
-	pci_read_config_byte(pcidev, YMFSB_PCIR_DSXGCTRL, &tmp8);
-	if ( tmp8 & 0x03 ) {
-		pci_write_config_byte(pcidev, YMFSB_PCIR_DSXGCTRL, tmp8&0xfc);
-		mdelay(YMFSB_RESET_DELAY);
-		pci_write_config_byte(pcidev, YMFSB_PCIR_DSXGCTRL, tmp8|0x03);
-		mdelay(YMFSB_RESET_DELAY);
-		pci_write_config_byte(pcidev, YMFSB_PCIR_DSXGCTRL, tmp8&0xfc);
-		mdelay(YMFSB_RESET_DELAY);
-	}
-
-	if ( checkPrimaryBusy() ) return -1;
-
-	return 0;
-}
-
-static int __init setupLegacyIO( struct pci_dev *pcidev )
-{
-	int v;
-	int sbio=0,mpuio=0,oplio=0,dma=0;
-
-	switch(sb_data[cards].io_base) {
-	case 0x220:
-		sbio = 0;
-		break;
-	case 0x240:
-		sbio = 1;
-		break;
-	case 0x260:
-		sbio = 2;
-		break;
-	case 0x280:
-		sbio = 3;
-		break;
-	default:
-		return -1;
-		break;
-	}
-#ifdef YMF_DEBUG
-	printk(PFX "set SBPro I/O at 0x%x\n",sb_data[cards].io_base);
-#endif
-
-#ifdef SUPPORT_UART401_MIDI
-	switch(mpu_data[cards].io_base) {
-	case 0x330:
-		mpuio = 0;
-		break;
-	case 0x300:
-		mpuio = 1;
-		break;
-	case 0x332:
-		mpuio = 2;
-		break;
-	case 0x334:
-		mpuio = 3;
-		break;
-	default:
-		mpuio = 0;
-		break;
-	}
-# ifdef YMF_DEBUG
-	printk(PFX "set MPU401 I/O at 0x%x\n",mpu_data[cards].io_base);
-# endif
-#endif
-
-	switch(opl3_data[cards].io_base) {
-	case 0x388:
-		oplio = 0;
-		break;
-	case 0x398:
-		oplio = 1;
-		break;
-	case 0x3a0:
-		oplio = 2;
-		break;
-	case 0x3a8:
-		oplio = 3;
-		break;
-	default:
-		return -1;
-		break;
-	}
-#ifdef YMF_DEBUG
-	printk(PFX "set OPL3 I/O at 0x%x\n",opl3_data[cards].io_base);
-#endif
-
-	dma = sb_data[cards].dma;
-#ifdef YMF_DEBUG
-	printk(PFX "set DMA address at 0x%x\n",sb_data[cards].dma);
-#endif
-
-	v = 0x0000 | ((dma & 0x03) << 6) | 0x003f;
-	pci_write_config_word(pcidev, YMFSB_PCIR_LEGCTRL, v);
-#ifdef YMF_DEBUG
-	printk(PFX "LEGCTRL: 0x%x\n",v);
-#endif
-	switch( pcidev->device ) {
-	case PCI_DEVICE_ID_YMF724:
-	case PCI_DEVICE_ID_YMF740:
-	case PCI_DEVICE_ID_YMF724F:
-	case PCI_DEVICE_ID_YMF740C:
-		v = 0x8800 | ((mpuio & 0x03) << 4)
-			   | ((sbio & 0x03) << 2)
-			   | (oplio & 0x03);
-		pci_write_config_word(pcidev, YMFSB_PCIR_ELEGCTRL, v);
-#ifdef YMF_DEBUG
-		printk(PFX "ELEGCTRL: 0x%x\n",v);
-#endif
-		break;
-
-	case PCI_DEVICE_ID_YMF744:
-	case PCI_DEVICE_ID_YMF754:
-		v = 0x8800;
-		pci_write_config_word(pcidev, YMFSB_PCIR_ELEGCTRL, v);
-#ifdef YMF_DEBUG
-		printk(PFX "ELEGCTRL: 0x%x\n",v);
-#endif
-		pci_write_config_word(pcidev, YMFSB_PCIR_OPLADR, opl3_data[cards].io_base);
-		pci_write_config_word(pcidev, YMFSB_PCIR_SBADR,  sb_data[cards].
-io_base);
-#ifdef SUPPORT_UART401_MIDI
-		pci_write_config_word(pcidev, YMFSB_PCIR_MPUADR, mpu_data[cards].io_base);
-#endif
-		break;
-
-	default:
-		printk(KERN_ERR PFX "Invalid device ID: %d\n",pcidev->device);
-		return -1;
-		break;
-	}
-
-	return 0;
-}
-
-/* ---------------------------------------------------------------------- */
-
-static void enableDSP( void )
-{
-	writeRegDWord( YMFSB_CONFIG, 0x00000001 );
-	return;
-}
-
-static void disableDSP( void )
-{
-	int val;
-	int i;
-
-	val = readRegDWord( YMFSB_CONFIG );
-	if ( val ) {
-		writeRegDWord( YMFSB_CONFIG, 0 );
-	}
-
-	i=0;
-	while( ++i < YMFSB_WORKBITTIMEOUT ) {
-		val = readRegDWord(YMFSB_STATUS);
-		if ( (val & 0x00000002) == 0x00000000 ) break;
-	}
-
-	return;
-}
-
-static int __init setupInstruction( struct pci_dev *pcidev )
-{
-	int i;
-	int val;
-
-	writeRegDWord( YMFSB_NATIVEDACOUTVOL, 0 ); /* mute dac */
-	disableDSP();
-
-	writeRegDWord( YMFSB_MODE, 0x00010000 );
-
-	/* DS-XG Software Reset */
-	writeRegDWord( YMFSB_MODE,         0x00000000 );
-	writeRegDWord( YMFSB_MAPOFREC,     0x00000000 );
-	writeRegDWord( YMFSB_MAPOFEFFECT,  0x00000000 );
-	writeRegDWord( YMFSB_PLAYCTRLBASE, 0x00000000 );
-	writeRegDWord( YMFSB_RECCTRLBASE,  0x00000000 );
-	writeRegDWord( YMFSB_EFFCTRLBASE,  0x00000000 );
-
-	val = readRegWord( YMFSB_GLOBALCTRL );
-	writeRegWord( YMFSB_GLOBALCTRL, (val&~0x0007) );
-
-	/* setup DSP instruction code */
-	for ( i=0 ; i<YMFSB_DSPLENGTH ; i+=4 ) {
-	  writeRegDWord( YMFSB_DSPINSTRAM+i, DspInst[i>>2] );
-	}
-
-	switch( pcidev->device ) {
-	case PCI_DEVICE_ID_YMF724:
-	case PCI_DEVICE_ID_YMF740:
-		/* setup Control instruction code */
-		for ( i=0 ; i<YMFSB_CTRLLENGTH ; i+=4 ) {
-			writeRegDWord( YMFSB_CTRLINSTRAM+i, CntrlInst[i>>2] );
-		}
-		break;
-
-	case PCI_DEVICE_ID_YMF724F:
-	case PCI_DEVICE_ID_YMF740C:
-	case PCI_DEVICE_ID_YMF744:
-	case PCI_DEVICE_ID_YMF754:
-		/* setup Control instruction code */
-		for ( i=0 ; i<YMFSB_CTRLLENGTH ; i+=4 ) {
-			writeRegDWord( YMFSB_CTRLINSTRAM+i, CntrlInst1E[i>>2] );
-		}
-		break;
-
-	default:
-		return -1;
-	}
-
-	enableDSP();
-
-	return 0;
-}
-
-/* ---------------------------------------------------------------------- */
-
-static int __init ymf7xx_init(struct pci_dev *pcidev)
-{
-	unsigned short v;
-
-	/* Read hardware information */
-#ifdef YMF_DEBUG
-	unsigned int   dv;
-	pci_read_config_word(pcidev, YMFSB_PCIR_VENDORID, &v);
-	printk(KERN_INFO PFX "Vendor ID = 0x%x\n",v);
-	pci_read_config_word(pcidev, YMFSB_PCIR_DEVICEID, &v);
-	printk(KERN_INFO PFX "Device ID = 0x%x\n",v);
-	pci_read_config_word(pcidev, YMFSB_PCIR_REVISIONID, &v);
-	printk(KERN_INFO PFX "Revision ID = 0x%x\n",v&0xff);
-	pci_read_config_dword(pcidev, YMFSB_PCIR_BASEADDR, &dv);
-	printk(KERN_INFO PFX "Base address = 0x%x\n",dv);
-	pci_read_config_word(pcidev, YMFSB_PCIR_IRQ, &v);
-	printk(KERN_INFO PFX "IRQ line = 0x%x\n",v&0xff);
-#endif
-
-	/* enables memory space access / bus mastering */
-	pci_read_config_word(pcidev, YMFSB_PCIR_CMD, &v);
-	pci_write_config_word(pcidev, YMFSB_PCIR_CMD, v|0x06);
-
-	/* check codec */
-#ifdef YMF_DEBUG
-	printk(KERN_INFO PFX "check codec...\n");
-#endif
-	if (checkCodec(pcidev)) return -1;
-
-	/* setup legacy I/O */
-#ifdef YMF_DEBUG
-	printk(KERN_INFO PFX "setup legacy I/O...\n");
-#endif
-	if (setupLegacyIO(pcidev)) return -1;
-	
-	/* setup instruction code */	
-#ifdef YMF_DEBUG
-	printk(KERN_INFO PFX "setup instructions...\n");
-#endif
-	if (setupInstruction(pcidev)) return -1;
-
-	/* AC'97 setup */	
-#ifdef YMF_DEBUG
-	printk(KERN_INFO PFX "setup AC'97...\n");
-#endif
-	if ( writeAc97(AC97_RESET            ,0x0000) )  /* Reset */
-		return -1;
-	if ( writeAc97(AC97_MASTER_VOL_STEREO,0x0000) )  /* Master Volume */
-		return -1;
-
-	v = 31*(100-master_vol)/100;
-	v = (v<<8 | v)&0x7fff;
-	if ( writeAc97(AC97_PCMOUT_VOL       ,v     ) )  /* PCM out Volume */
-		return -1;
-
-#ifdef YMF_DEBUG
-	printk(KERN_INFO PFX "setup Legacy Volume...\n");
-#endif
-	/* Legacy Audio Output Volume L & R ch */
-	writeRegDWord( YMFSB_LEGACYOUTVOL, 0x3fff3fff );
-
-#ifdef YMF_DEBUG
-	printk(KERN_INFO PFX "setup SPDIF output control...\n");
-#endif
-	/* SPDIF Output control */
-	v = spdif_out != 0 ? 0x0001 : 0x0000;
-	writeRegWord( YMFSB_SPDIFOUTCTRL, v );
-	/* no copyright protection, 
-	   sample-rate converted,
-	   re-recorded software comercially available (the 1st generation),
-	   original */
-	writeRegWord( YMFSB_SPDIFOUTSTATUS, 0x9a04 );
-
-	return 0;
-}
-
-/* ---------------------------------------------------------------------- */
-
-static void __init ymf7xxsb_attach_sb(struct address_info *hw_config)
-{
-	if(!sb_dsp_init(hw_config, THIS_MODULE))
-		hw_config->slots[0] = -1;
-}
-
-static int __init ymf7xxsb_probe_sb(struct address_info *hw_config)
-{
-	if (check_region(hw_config->io_base, 16))
-	{
-		printk(KERN_DEBUG PFX "SBPro port 0x%x is already in use\n",
-		       hw_config->io_base);
-		return 0;
-	}
-	return sb_dsp_detect(hw_config, SB_PCI_YAMAHA, 0, NULL);
-}
-
-
-static void ymf7xxsb_unload_sb(struct address_info *hw_config, int unload_mpu)
-{
-	if(hw_config->slots[0]!=-1)
-		sb_dsp_unload(hw_config, unload_mpu);
-}
-
-/* ---------------------------------------------------------------------- */
-
-enum chip_types {
-	CH_YMF724 = 0,
-	CH_YMF724F,
-	CH_YMF740,
-	CH_YMF740C,
-	CH_YMF744,
-	CH_YMF754,
-};
-
-/* directly indexed by chip_types enum above */
-/* note we keep this a struct to ease adding
- * other per-board or per-chip info here */
-struct {
-	const char           *devicename;
-} devicetable[] __initdata = 
-{
-	{ "YMF724A-E" },
-	{ "YMF724F" },
-	{ "YMF740A-B" },
-	{ "YMF740C" },
-	{ "YMF744" },
-	{ "YMF754" },
-};
-
-static struct pci_device_id ymf7xxsb_pci_tbl[] __initdata = {
-	{ PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF724,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF724 },
-	{ PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF724F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF724F },
-	{ PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF740,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF740 },
-	{ PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF740C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF740C },
-	{ PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF744,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF744 },
-	{ PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF754,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF754 },
-	{ 0, }
-};
-MODULE_DEVICE_TABLE(pci, ymf7xxsb_pci_tbl);
-
-static int __init ymf7xxsb_init_one (struct pci_dev *pcidev, const struct pci_device_id *ent)
-{
-
-	const char	*devicename;
-	unsigned long   iobase;
-
-	if (cards == MAX_CARDS) {
-	  	printk (KERN_DEBUG PFX "maximum number of cards reached\n");
-		return -ENODEV;
-	}
-
-	if ( pcidev->irq == 0 ) return -ENODEV;
-	iobase = pci_resource_start (pcidev, 0);
-	if ( iobase == 0x00000000 ) return -ENODEV;
-
-	devicename = devicetable[ent->driver_data].devicename;
-
-	/* remap memory mapped I/O onto kernel virtual memory */
-	if ( (ymfbase[cards] = ioremap_nocache(iobase, YMFSB_REGSIZE)) == 0 )
-	{
-		printk(KERN_ERR PFX "ioremap (0x%lx) returns zero\n", iobase);
-		return -ENODEV;
-	}
-	printk(KERN_INFO PFX "found %s at 0x%lx\n", devicename, iobase);
-#ifdef YMF_DEBUG
-	printk(KERN_INFO PFX "remappling to 0x%p\n", ymfbase[cards]);
-#endif
-
-	memset (&sb_data[cards], 0, sizeof (struct address_info));
-	memset (&opl3_data[cards], 0, sizeof (struct address_info));
-#ifdef SUPPORT_UART401_MIDI
-	memset (&mpu_data[cards], 0, sizeof (struct address_info));
-#endif
-
-	sb_data[cards].name   = YMFSB_CARD_NAME;
-	opl3_data[cards].name = YMFSB_CARD_NAME;
-#ifdef SUPPORT_UART401_MIDI
-	mpu_data[cards].name  = YMFSB_CARD_NAME;
-#endif
-
-	sb_data[cards].card_subtype = MDL_YMPCI;
-
-	if ( io == 0 ) io      = 0x220;
-	sb_data[cards].io_base = io;
-	sb_data[cards].irq     = pcidev->irq;
-	sb_data[cards].dma     = dma;
-
-	if ( synth_io == 0 ) synth_io = 0x388;
-	opl3_data[cards].io_base = synth_io;
-	opl3_data[cards].irq     = -1;
-
-#ifdef SUPPORT_UART401_MIDI
-	if ( mpu_io == 0 ) mpu_io = 0x330;
-	mpu_data[cards].io_base = mpu_io;
-	mpu_data[cards].irq     = -1;
-#endif
-
-	if ( ymf7xx_init(pcidev) ) {
-		printk (KERN_ERR PFX
-			"Cannot initialize %s, aborting\n",
-			devicename);
-		return -ENODEV;
-	}
-
-	/* register legacy SoundBlaster Pro */
-	if (!ymf7xxsb_probe_sb(&sb_data[cards])) {
-		printk (KERN_ERR PFX
-			"SB probe at 0x%X failed, aborting\n",
-			io);
-		return -ENODEV;
-	}
-	ymf7xxsb_attach_sb (&sb_data[cards]);
-
-#ifdef SUPPORT_UART401_MIDI
-	/* register legacy MIDI */
-	if ( mpu_io > 0 && 0)
-	{
-		if (!ymf7xxsb_probe_midi (&mpu_data[cards], THIS_MODULE)) {
-			printk (KERN_ERR PFX
-				"MIDI probe @ 0x%X failed, aborting\n",
-				mpu_io);
-			ymf7xxsb_unload_sb (&sb_data[cards], 0);
-			return -ENODEV;
-		}
-	}
-#endif
-
-	/* register legacy OPL3 */
-
-	cards++;	
-	return 0;
-}
-
-static struct pci_driver ymf7xxsb_driver = {
-	name:		"ymf7xxsb",
-	id_table:	ymf7xxsb_pci_tbl,
-	probe:		ymf7xxsb_init_one,
-};
-
-static int __init init_ymf7xxsb_module(void)
-{
-	int i;
-
-	if ( master_vol < 0 ) master_vol  = 50;
-	if ( master_vol > 100 ) master_vol = 100;
-
-	for (i=0 ; i<MAX_CARDS ; i++ )
-		ymfbase[i] = NULL;
-
-	i = pci_module_init (&ymf7xxsb_driver);
-	if (i < 0)
-		return i;
-
-	printk (KERN_INFO PFX YMFSB_CARD_NAME " loaded\n");
-	
-	return 0;
-}
-
-static void __exit free_iomaps( void )
-{
-	int i;
-
-	for ( i=0 ; i<MAX_CARDS ; i++ ) {
-		if ( ymfbase[i]!=NULL )
-			iounmap(ymfbase[i]);
-	}
-
-	return;
-}
-
-static void __exit cleanup_ymf7xxsb_module(void)
-{
-	int i;
-	
-	for (i = 0; i < cards; i++) {
-#ifdef SUPPORT_UART401_MIDI
-		ymf7xxsb_unload_sb (&sb_data[i], 0);
-		ymf7xxsb_unload_midi (&mpu_data[i]);
-#else
-		ymf7xxsb_unload_sb (&sb_data[i], 1);
-#endif
-	}
-
-	free_iomaps();
-	pci_unregister_driver(&ymf7xxsb_driver);
-
-}
-
-MODULE_AUTHOR("Daisuke Nagano, breeze.nagano@nifty.ne.jp");
-MODULE_DESCRIPTION("YMF7xx Legacy Audio Driver");
-
-module_init(init_ymf7xxsb_module);
-module_exit(cleanup_ymf7xxsb_module);
-
diff -urN linux-2.4.2-pre1/drivers/telephony/ixj.c linux/drivers/telephony/ixj.c
--- linux-2.4.2-pre1/drivers/telephony/ixj.c	Fri Dec 29 14:35:47 2000
+++ linux/drivers/telephony/ixj.c	Mon Dec  3 22:27:48 2001
@@ -20,6 +20,7 @@
  *    
  * Fixes:
  *                  Marc Boucher, <marc@mbsi.ca>
+ *		    David Huggins-Daines <dhd@cepstral.com>
  * 
  * More information about the hardware related to this driver can be found  
  * at our website:    http://www.quicknet.net
@@ -90,7 +91,7 @@
 
 MODULE_PARM(ixjdebug, "i");
 
-static IXJ ixj[IXJMAX];
+static IXJ* ixj[IXJMAX];
 
 static struct timer_list ixj_timer;
 
@@ -103,7 +104,7 @@
 *
 ************************************************************************/
 
-static int Stub(IXJ * J, unsigned long arg)
+static int Stub(IXJ * j, unsigned long arg)
 {
 	return 0;
 }
@@ -117,60 +118,62 @@
 static IXJ_REGFUNC ixj_PreIoctl = &Stub;
 static IXJ_REGFUNC ixj_PostIoctl = &Stub;
 
-static void ixj_read_frame(int board);
-static void ixj_write_frame(int board);
+static void ixj_read_frame(IXJ *j);
+static void ixj_write_frame(IXJ *j);
 static void ixj_init_timer(void);
 static void ixj_add_timer(void);
 static void ixj_timeout(unsigned long ptr);
-static int read_filters(int board);
-static int LineMonitor(int board);
+static int read_filters(IXJ *j);
+static int LineMonitor(IXJ *j);
 static int ixj_fasync(int fd, struct file *, int mode);
-static int ixj_set_port(int board, int arg);
-static int ixj_set_pots(int board, int arg);
-static int ixj_hookstate(int board);
-static int ixj_record_start(int board);
-static void ixj_record_stop(int board);
-static void set_rec_volume(int board, int volume);
-static void ixj_vad(int board, int arg);
-static int ixj_play_start(int board);
-static void ixj_play_stop(int board);
-static int ixj_set_tone_on(unsigned short arg, int board);
-static int ixj_set_tone_off(unsigned short, int board);
-static int ixj_play_tone(int board, char tone);
-static int idle(int board);
-static void ixj_ring_on(int board);
-static void ixj_ring_off(int board);
-static void aec_stop(int board);
-static void ixj_ringback(int board);
-static void ixj_busytone(int board);
-static void ixj_dialtone(int board);
-static void ixj_cpt_stop(int board);
-static char daa_int_read(int board);
-static int daa_set_mode(int board, int mode);
-static int ixj_linetest(int board);
-static int ixj_daa_write(int board);
-static int ixj_daa_cid_read(int board);
-static void DAA_Coeff_US(int board);
-static void DAA_Coeff_UK(int board);
-static void DAA_Coeff_France(int board);
-static void DAA_Coeff_Germany(int board);
-static void DAA_Coeff_Australia(int board);
-static void DAA_Coeff_Japan(int board);
-static int ixj_init_filter(int board, IXJ_FILTER * jf);
-static int ixj_init_tone(int board, IXJ_TONE * ti);
-static int ixj_build_cadence(int board, IXJ_CADENCE * cp);
-static int ixj_build_filter_cadence(int board, IXJ_FILTER_CADENCE * cp);
+static int ixj_set_port(IXJ *j, int arg);
+static int ixj_set_pots(IXJ *j, int arg);
+static int ixj_hookstate(IXJ *j);
+static int ixj_record_start(IXJ *j);
+static void ixj_record_stop(IXJ *j);
+static void set_rec_volume(IXJ *j, int volume);
+static void ixj_vad(IXJ *j, int arg);
+static int ixj_play_start(IXJ *j);
+static void ixj_play_stop(IXJ *j);
+static int ixj_set_tone_on(unsigned short arg, IXJ *j);
+static int ixj_set_tone_off(unsigned short, IXJ *j);
+static int ixj_play_tone(IXJ *j, char tone);
+static int idle(IXJ *j);
+static void ixj_ring_on(IXJ *j);
+static void ixj_ring_off(IXJ *j);
+static void aec_stop(IXJ *j);
+static void ixj_ringback(IXJ *j);
+static void ixj_busytone(IXJ *j);
+static void ixj_dialtone(IXJ *j);
+static void ixj_cpt_stop(IXJ *j);
+static char daa_int_read(IXJ *j);
+static int daa_set_mode(IXJ *j, int mode);
+static int ixj_linetest(IXJ *j);
+static int ixj_daa_write(IXJ *j);
+static int ixj_daa_cid_read(IXJ *j);
+static void DAA_Coeff_US(IXJ *j);
+static void DAA_Coeff_UK(IXJ *j);
+static void DAA_Coeff_France(IXJ *j);
+static void DAA_Coeff_Germany(IXJ *j);
+static void DAA_Coeff_Australia(IXJ *j);
+static void DAA_Coeff_Japan(IXJ *j);
+static int ixj_init_filter(IXJ *j, IXJ_FILTER * jf);
+static int ixj_init_tone(IXJ *j, IXJ_TONE * ti);
+static int ixj_build_cadence(IXJ *j, IXJ_CADENCE * cp);
+static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE * cp);
 // Serial Control Interface funtions
-static int SCI_Control(int board, int control);
-static int SCI_Prepare(int board);
-static int SCI_WaitHighSCI(int board);
-static int SCI_WaitLowSCI(int board);
+static int SCI_Control(IXJ *j, int control);
+static int SCI_Prepare(IXJ *j);
+static int SCI_WaitHighSCI(IXJ *j);
+static int SCI_WaitLowSCI(IXJ *j);
 static DWORD PCIEE_GetSerialNumber(WORD wAddress);
-static int ixj_PCcontrol_wait(int board);
-static void ixj_write_cid(int board);
-static void ixj_write_cid_bit(int board, int bit);
-static int set_base_frame(int board, int size);
-static int set_play_codec(int board, int rate);
+static int ixj_PCcontrol_wait(IXJ *j);
+static void ixj_write_cid(IXJ *j);
+static void ixj_write_cid_bit(IXJ *j, int bit);
+static int set_base_frame(IXJ *j, int size);
+static int set_play_codec(IXJ *j, int rate);
+static void set_rec_depth(IXJ *j, int depth);
+static void set_play_depth(IXJ *j, int depth);
 
 /************************************************************************
 CT8020/CT8021 Host Programmers Model
@@ -186,72 +189,79 @@
 E-F Host Recieve (Read) Data Buffer Access Port (buffer input)	Read Only
 ************************************************************************/
 
-extern __inline__ void ixj_read_HSR(int board)
+extern __inline__ void ixj_read_HSR(IXJ *j)
 {
-	ixj[board].hsr.bytes.low = inb_p(ixj[board].DSPbase + 8);
-	ixj[board].hsr.bytes.high = inb_p(ixj[board].DSPbase + 9);
+	j->hsr.bytes.low = inb_p(j->DSPbase + 8);
+	j->hsr.bytes.high = inb_p(j->DSPbase + 9);
 }
 
-extern __inline__ int IsControlReady(int board)
+extern __inline__ int IsControlReady(IXJ *j)
 {
-	ixj_read_HSR(board);
-	return ixj[board].hsr.bits.controlrdy ? 1 : 0;
+	ixj_read_HSR(j);
+	return j->hsr.bits.controlrdy ? 1 : 0;
 }
 
-extern __inline__ int IsPCControlReady(int board)
+extern __inline__ int IsPCControlReady(IXJ *j)
 {
-	ixj[board].pccr1.byte = inb_p(ixj[board].XILINXbase + 3);
-	return ixj[board].pccr1.bits.crr ? 1 : 0;
+	j->pccr1.byte = inb_p(j->XILINXbase + 3);
+	return j->pccr1.bits.crr ? 1 : 0;
 }
 
-extern __inline__ int IsStatusReady(int board)
+extern __inline__ int IsStatusReady(IXJ *j)
 {
-	ixj_read_HSR(board);
-	return ixj[board].hsr.bits.statusrdy ? 1 : 0;
+	ixj_read_HSR(j);
+	return j->hsr.bits.statusrdy ? 1 : 0;
 }
 
-extern __inline__ int IsRxReady(int board)
+extern __inline__ int IsRxReady(IXJ *j)
 {
-	ixj_read_HSR(board);
+	ixj_read_HSR(j);
 #ifdef PERFMON_STATS
-	++ixj[board].rxreadycheck;
+	++j->rxreadycheck;
 #endif
-	return ixj[board].hsr.bits.rxrdy ? 1 : 0;
+	return j->hsr.bits.rxrdy ? 1 : 0;
 }
 
-extern __inline__ int IsTxReady(int board)
+extern __inline__ int IsTxReady(IXJ *j)
 {
-	ixj_read_HSR(board);
+	ixj_read_HSR(j);
 #ifdef PERFMON_STATS
-	++ixj[board].txreadycheck;
+	++j->txreadycheck;
 #endif
-	return ixj[board].hsr.bits.txrdy ? 1 : 0;
+	return j->hsr.bits.txrdy ? 1 : 0;
 }
 
-extern __inline__ void set_play_volume(int board, int volume)
+extern __inline__ void set_play_volume(IXJ *j, int volume)
 {
-	ixj_WriteDSPCommand(0xCF02, board);
-	ixj_WriteDSPCommand(volume, board);
+	ixj_WriteDSPCommand(0xCF02, j);
+	ixj_WriteDSPCommand(volume, j);
 }
 
-extern __inline__ int get_play_volume(int board)
+extern __inline__ void set_play_depth(IXJ *j, int depth)
 {
-	ixj_WriteDSPCommand(0xCF00, board);
-	return ixj[board].ssr.high << 8 | ixj[board].ssr.low;
+	if (depth > 60)
+		depth = 60;
+	if (depth < 0)
+		depth = 0;
+	ixj_WriteDSPCommand(0x5280 + depth, j);
 }
 
-extern __inline__ BYTE SLIC_GetState(int board)
+extern __inline__ int get_play_volume(IXJ *j)
 {
-	IXJ *j = &ixj[board];
+	ixj_WriteDSPCommand(0xCF00, j);
+	return j->ssr.high << 8 | j->ssr.low;
+}
 
-	if (j->cardtype == 600) {
+extern __inline__ BYTE SLIC_GetState(IXJ *j)
+{
+	if (j->cardtype == QTI_PHONECARD) {
 		j->pccr1.byte = 0;
 		j->psccr.bits.dev = 3;
 		j->psccr.bits.rw = 1;
 		outw_p(j->psccr.byte << 8, j->XILINXbase + 0x00);
-		ixj_PCcontrol_wait(board);
+		ixj_PCcontrol_wait(j);
 		j->pslic.byte = inw_p(j->XILINXbase + 0x00) & 0xFF;
-		ixj_PCcontrol_wait(board);
+		ixj_PCcontrol_wait(j);
 		if (j->pslic.bits.powerdown)
 			return PLD_SLIC_STATE_OC;
 		else if (!j->pslic.bits.ring0 && !j->pslic.bits.ring1)
@@ -264,12 +274,11 @@
 	return j->pld_slicr.bits.state;
 }
 
-static BOOL SLIC_SetState(BYTE byState, int board)
+static BOOL SLIC_SetState(BYTE byState, IXJ *j)
 {
 	BOOL fRetVal = FALSE;
-	IXJ *j = &ixj[board];
 
-	if (j->cardtype == 600) {
+	if (j->cardtype == QTI_PHONECARD) {
 		if (j->flags.pcmciasct) {
 			switch (byState) {
 			case PLD_SLIC_STATE_TIPOPEN:
@@ -309,7 +318,7 @@
 			j->psccr.bits.dev = 3;
 			j->psccr.bits.rw = 0;
 			outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00);
-			ixj_PCcontrol_wait(board);
+			ixj_PCcontrol_wait(j);
 		}
 	} else {
 		// Set the C1, C2, C3 & B2EN signals.
@@ -398,12 +407,14 @@
 	case G729LOADER:
 		ixj_DownloadG729 = regfunc;
 		for (cnt = 0; cnt < IXJMAX; cnt++)
-			ixj_DownloadG729(&ixj[cnt], 0L);
+			if (ixj[cnt] != NULL)
+				ixj_DownloadG729(ixj[cnt], 0L);
 		break;
 	case TS85LOADER:
 		ixj_DownloadTS85 = regfunc;
 		for (cnt = 0; cnt < IXJMAX; cnt++)
-			ixj_DownloadTS85(&ixj[cnt], 0L);
+			if (ixj[cnt] != NULL)
+				ixj_DownloadTS85(ixj[cnt], 0L);
 		break;
 	case PRE_READ:
 		ixj_PreRead = regfunc;
@@ -476,9 +487,8 @@
 	add_timer(&ixj_timer);
 }
 
-static void ixj_tone_timeout(int board)
+static void ixj_tone_timeout(IXJ *j)
 {
-	IXJ *j = &ixj[board];
 	IXJ_TONE ti;
 
 	j->tone_state++;
@@ -489,11 +499,11 @@
 			if (j->tone_cadence_state >= j->cadence_t->elements_used) {
 				switch (j->cadence_t->termination) {
 				case PLAY_ONCE:
-					ixj_cpt_stop(board);
+					ixj_cpt_stop(j);
 					break;
 				case REPEAT_LAST_ELEMENT:
 					j->tone_cadence_state--;
-					ixj_play_tone(board, j->cadence_t->ce[j->tone_cadence_state].index);
+					ixj_play_tone(j, j->cadence_t->ce[j->tone_cadence_state].index);
 					break;
 				case REPEAT_ALL:
 					j->tone_cadence_state = 0;
@@ -503,11 +513,11 @@
 						ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0;
 						ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1;
 						ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1;
-						ixj_init_tone(board, &ti);
+						ixj_init_tone(j, &ti);
 					}
-					ixj_set_tone_on(j->cadence_t->ce[0].tone_on_time, board);
-					ixj_set_tone_off(j->cadence_t->ce[0].tone_off_time, board);
-					ixj_play_tone(board, j->cadence_t->ce[0].index);
+					ixj_set_tone_on(j->cadence_t->ce[0].tone_on_time, j);
+					ixj_set_tone_off(j->cadence_t->ce[0].tone_off_time, j);
+					ixj_play_tone(j, j->cadence_t->ce[0].index);
 					break;
 				}
 			} else {
@@ -517,41 +527,43 @@
 					ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0;
 					ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1;
 					ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1;
-					ixj_init_tone(board, &ti);
+					ixj_init_tone(j, &ti);
 				}
-				ixj_set_tone_on(j->cadence_t->ce[j->tone_cadence_state].tone_on_time, board);
-				ixj_set_tone_off(j->cadence_t->ce[j->tone_cadence_state].tone_off_time, board);
-				ixj_play_tone(board, j->cadence_t->ce[j->tone_cadence_state].index);
+				ixj_set_tone_on(j->cadence_t->ce[j->tone_cadence_state].tone_on_time, j);
+				ixj_set_tone_off(j->cadence_t->ce[j->tone_cadence_state].tone_off_time, j);
+				ixj_play_tone(j, j->cadence_t->ce[j->tone_cadence_state].index);
 			}
 		}
 	}
 }
 
-extern __inline__ void ixj_kill_fasync(int board, int dir)
+extern __inline__ void ixj_kill_fasync(IXJ *j, int band)
 {
-	kill_fasync(&ixj[board].async_queue, SIGIO, dir);	// Send apps notice of change
-
+	kill_fasync(&j->async_queue, SIGIO, band);
 }
+
 static void ixj_timeout(unsigned long ptr)
 {
 	int board;
 	unsigned long jifon;
-	IXJ *j;
 
 	for (board = 0; board < IXJMAX; board++) {
-		j = &ixj[board];
+		IXJ *j = ixj[board];
+
+		if (j == NULL)
+			continue;
 
 		if (j->DSPbase) {
 #ifdef PERFMON_STATS
 			j->timerchecks++;
 #endif
 			if (j->tone_state) {
-				if (!ixj_hookstate(board)) {
-					ixj_cpt_stop(board);
+				if (!ixj_hookstate(j)) {
+					ixj_cpt_stop(j);
 					if (j->m_hook) {
 						j->m_hook = 0;
 						j->ex.bits.hookstate = 1;
-						ixj_kill_fasync(board, POLL_IN);
+						ixj_kill_fasync(j, POLL_PRI);
 					}
 					continue;
 				}
@@ -562,60 +574,60 @@
 					    (hertz * j->tone_off_time * 25 / 100000);
 				if (time_before(jiffies, j->tone_start_jif + jifon)) {
 					if (j->tone_state == 1) {
-						ixj_play_tone(board, j->tone_index);
+						ixj_play_tone(j, j->tone_index);
 						if (j->dsp.low == 0x20) {
 							continue;
 						}
 					} else {
-						ixj_play_tone(board, 0);
+						ixj_play_tone(j, 0);
 						if (j->dsp.low == 0x20) {
 							continue;
 						}
 					}
 				} else {
-					ixj_tone_timeout(board);
+					ixj_tone_timeout(j);
 					if (j->flags.dialtone) {
-						ixj_dialtone(board);
+						ixj_dialtone(j);
 					}
 					if (j->flags.busytone) {
-						ixj_busytone(board);
+						ixj_busytone(j);
 						if (j->dsp.low == 0x20) {
 							continue;
 						}
 					}
 					if (j->flags.ringback) {
-						ixj_ringback(board);
+						ixj_ringback(j);
 						if (j->dsp.low == 0x20) {
 							continue;
 						}
 					}
 					if (!j->tone_state) {
 						if (j->dsp.low == 0x20 || (j->play_mode == -1 && j->rec_mode == -1))
-							idle(board);
+							idle(j);
 						if (j->dsp.low == 0x20 && j->play_mode != -1)
-							ixj_play_start(board);
+							ixj_play_start(j);
 						if (j->dsp.low == 0x20 && j->rec_mode != -1)
-							ixj_record_start(board);
+							ixj_record_start(j);
 					}
 				}
 			}
-			if (!j->tone_state || j->dsp.low != 0x20) {
-				if (IsRxReady(board)) {
-					ixj_read_frame(board);
+			if (!(j->tone_state && j->dsp.low == 0x20)) {
+				if (IsRxReady(j)) {
+					ixj_read_frame(j);
 				}
-				if (IsTxReady(board) && !j->flags.cidplay) {
-					ixj_write_frame(board);
+				if (IsTxReady(j) && !j->flags.cidplay) {
+					ixj_write_frame(j);
 				}
 			}
 			if (j->flags.cringing) {
-				if (ixj_hookstate(board) & 1) {
+				if (ixj_hookstate(j) & 1) {
 					j->flags.cringing = 0;
-					ixj_ring_off(board);
+					ixj_ring_off(j);
 				} else {
 					if (jiffies - j->ring_cadence_jif >= (hertz/2)) {
 						if (j->flags.cidring && !j->flags.cidsent) {
 							j->flags.cidsent = 1;
-							ixj_write_cid(board);
+							ixj_write_cid(j);
 							j->flags.cidring = 0;
 						}
 						j->ring_cadence_t--;
@@ -624,34 +636,34 @@
 						j->ring_cadence_jif = jiffies;
 					}
 					if (j->ring_cadence & 1 << j->ring_cadence_t) {
-						ixj_ring_on(board);
+						ixj_ring_on(j);
 					} else {
-						ixj_ring_off(board);
+						ixj_ring_off(j);
 						j->flags.cidring = 1;
 					}
 					continue;
 				}
 			}
 			if (!j->flags.ringing) {
-				if (ixj_hookstate(board)) {
+				if (ixj_hookstate(j)) {
 					if (j->dsp.low != 0x20 &&
-					    SLIC_GetState(board) != PLD_SLIC_STATE_ACTIVE) {
-						SLIC_SetState(PLD_SLIC_STATE_ACTIVE, board);
+					    SLIC_GetState(j) != PLD_SLIC_STATE_ACTIVE) {
+						SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j);
 					}
-					LineMonitor(board);
-					read_filters(board);
-					ixj_WriteDSPCommand(0x511B, board);
+					LineMonitor(j);
+					read_filters(j);
+					ixj_WriteDSPCommand(0x511B, j);
 					j->proc_load = j->ssr.high << 8 | j->ssr.low;
 					if (!j->m_hook) {
 						j->m_hook = j->ex.bits.hookstate = 1;
-						ixj_kill_fasync(board, POLL_IN);
+						ixj_kill_fasync(j, POLL_PRI);
 					}
 				} else {
 					if (j->dsp.low != 0x20 &&
-					    SLIC_GetState(board) == PLD_SLIC_STATE_ACTIVE)
+					    SLIC_GetState(j) == PLD_SLIC_STATE_ACTIVE)
 						// Internet LineJACK
 					{
-						SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);
+						SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
 					}
 					if (j->ex.bits.dtmf_ready) {
 						j->dtmf_wp = j->dtmf_rp = j->ex.bits.dtmf_ready = 0;
@@ -659,7 +671,7 @@
 					if (j->m_hook) {
 						j->m_hook = 0;
 						j->ex.bits.hookstate = 1;
-						ixj_kill_fasync(board, POLL_IN);
+						ixj_kill_fasync(j, POLL_PRI);
 					}
 				}
 			}
@@ -667,34 +679,34 @@
 				if (j->flags.pstn_present) {
 					j->pld_scrr.byte = inb_p(j->XILINXbase);
 					if (j->pld_scrr.bits.daaflag) {
-						daa_int_read(board);
+						daa_int_read(j);
 						if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.RING) {
 							if (!j->flags.pstn_ringing) {
 								j->flags.pstn_ringing = 1;
 								if (j->daa_mode != SOP_PU_RINGING)
-									daa_set_mode(board, SOP_PU_RINGING);
+									daa_set_mode(j, SOP_PU_RINGING);
 							}
 						}
 						if (time_after(jiffies, j->pstn_sleeptil) && j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
 							j->pstn_winkstart = 0;
 							j->pstn_ring_stop = 0;
-							ixj[board].pld_scrw.bits.led1 = 1;
+							j->pld_scrw.bits.led1 = 1;
 							if (j->flags.pstn_ringing && !j->pstn_envelope) {
 								if (j->daa_mode != SOP_PU_RINGING) {
 									j->flags.pstn_ringing = 0;
 								} else {
-									ixj[board].pld_scrw.bits.led2 = 0;
+									j->pld_scrw.bits.led2 = 0;
 									j->pstn_envelope = 1;
 									j->pstn_ring_start = jiffies;
 									j->pstn_ring_stop = 0;
 								}
 								j->ex.bits.pstn_ring = 0;
 							}
-							outb_p(ixj[board].pld_scrw.byte, ixj[board].XILINXbase);
+							outb_p(j->pld_scrw.byte, j->XILINXbase);
 						} else {
-							ixj[board].pld_scrw.bits.led1 = 0;
-							ixj[board].pld_scrw.bits.led2 = 1;
-							outb_p(ixj[board].pld_scrw.byte, ixj[board].XILINXbase);
+							j->pld_scrw.bits.led1 = 0;
+							j->pld_scrw.bits.led2 = 1;
+							outb_p(j->pld_scrw.byte, j->XILINXbase);
 							if (j->flags.pstn_ringing && j->pstn_envelope) {
 								if(!j->pstn_ring_stop) {
 									j->pstn_ring_stop = jiffies;
@@ -707,7 +719,7 @@
 								if (!j->pstn_winkstart) {
 									j->pstn_winkstart = jiffies;
 								} else if (time_after(jiffies, j->pstn_winkstart + (hertz * j->winktime / 1000))) {
-									daa_set_mode(board, SOP_PU_SLEEP);
+									daa_set_mode(j, SOP_PU_SLEEP);
 									j->pstn_winkstart = 0;
 									j->ex.bits.pstn_wink = 1;
 								}
@@ -717,7 +729,7 @@
 						}
 						if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Cadence) {
 							if (j->daa_mode == SOP_PU_RINGING) {
-								daa_set_mode(board, SOP_PU_SLEEP);
+								daa_set_mode(j, SOP_PU_SLEEP);
 								j->flags.pstn_ringing = 0;
 								j->ex.bits.pstn_ring = 0;
 							}
@@ -730,12 +742,12 @@
 						}
 					} else {
 						if (j->pld_scrr.bits.daaflag) {
-							daa_int_read(board);
+							daa_int_read(j);
 						}
 						j->ex.bits.pstn_ring = 0;
 						if (j->pstn_cid_intr && jiffies > j->pstn_cid_received + (hertz * 3)) {
 							if (j->daa_mode == SOP_PU_RINGING) {
-								ixj_daa_cid_read(board);
+								ixj_daa_cid_read(j);
 								j->ex.bits.caller_id = 1;
 							}
 							j->pstn_cid_intr = 0;
@@ -743,9 +755,9 @@
 							j->ex.bits.caller_id = 0;
 						}
 						if (!j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
-							ixj[board].pld_scrw.bits.led1 = 0;
-							ixj[board].pld_scrw.bits.led2 = 1;
-							outb_p(ixj[board].pld_scrw.byte, ixj[board].XILINXbase);
+							j->pld_scrw.bits.led1 = 0;
+							j->pld_scrw.bits.led2 = 1;
+							outb_p(j->pld_scrw.byte, j->XILINXbase);
 							if (j->flags.pstn_ringing && j->pstn_envelope) {
 								if(!j->pstn_ring_stop) {
 									j->pstn_ring_stop = jiffies;
@@ -754,13 +766,13 @@
 									j->ex.bits.pstn_ring = 1;
 									j->pstn_envelope = 0;
 								}
-								ixj[board].pld_scrw.bits.led1 = 0;
-								outb_p(ixj[board].pld_scrw.byte, ixj[board].XILINXbase);
+								j->pld_scrw.bits.led1 = 0;
+								outb_p(j->pld_scrw.byte, j->XILINXbase);
 							} else if (j->daa_mode == SOP_PU_CONVERSATION) {
 								if (!j->pstn_winkstart) {
 									j->pstn_winkstart = jiffies;
 								} else if (time_after(jiffies, j->pstn_winkstart + (hertz * j->winktime / 1000))) {
-									daa_set_mode(board, SOP_PU_SLEEP);
+									daa_set_mode(j, SOP_PU_SLEEP);
 									j->pstn_winkstart = 0;
 									j->ex.bits.pstn_wink = 1;
 								}
@@ -771,8 +783,7 @@
 			}
 			if (j->ex.bytes) {
 				wake_up_interruptible(&j->poll_q);	// Wake any blocked selects
-
-				ixj_kill_fasync(board, POLL_IN);
+				ixj_kill_fasync(j, POLL_PRI);
 			}
 		} else {
 			break;
@@ -781,12 +792,12 @@
 	ixj_add_timer();
 }
 
-static int ixj_status_wait(int board)
+static int ixj_status_wait(IXJ *j)
 {
 	unsigned long jif;
 
 	jif = jiffies;
-	while (!IsStatusReady(board)) {
+	while (!IsStatusReady(j)) {
 		if (jiffies - jif > (60 * (hertz / 100))) {
 			return -1;
 		}
@@ -794,12 +805,12 @@
 	return 0;
 }
 
-static int ixj_PCcontrol_wait(int board)
+static int ixj_PCcontrol_wait(IXJ *j)
 {
 	unsigned long jif;
 
 	jif = jiffies;
-	while (!IsPCControlReady(board)) {
+	while (!IsPCControlReady(j)) {
 		if (jiffies - jif > (60 * (hertz / 100))) {
 			return -1;
 		}
@@ -807,7 +818,7 @@
 	return 0;
 }
 
-int ixj_WriteDSPCommand(unsigned short cmd, int board)
+int ixj_WriteDSPCommand(unsigned short cmd, IXJ *j)
 {
 	BYTES bytes;
 	unsigned long jif;
@@ -815,22 +826,22 @@
 	bytes.high = (cmd & 0xFF00) >> 8;
 	bytes.low = cmd & 0x00FF;
 	jif = jiffies;
-	while (!IsControlReady(board)) {
+	while (!IsControlReady(j)) {
 		if (jiffies - jif > (60 * (hertz / 100))) {
 			return -1;
 		}
 	}
-	outb_p(bytes.low, ixj[board].DSPbase + 6);
-	outb_p(bytes.high, ixj[board].DSPbase + 7);
+	outb_p(bytes.low, j->DSPbase + 6);
+	outb_p(bytes.high, j->DSPbase + 7);
 
-	if (ixj_status_wait(board)) {
-		ixj[board].ssr.low = 0xFF;
-		ixj[board].ssr.high = 0xFF;
+	if (ixj_status_wait(j)) {
+		j->ssr.low = 0xFF;
+		j->ssr.high = 0xFF;
 		return -1;
 	}
 /* Read Software Status Register */
-	ixj[board].ssr.low = inb_p(ixj[board].DSPbase + 2);
-	ixj[board].ssr.high = inb_p(ixj[board].DSPbase + 3);
+	j->ssr.low = inb_p(j->DSPbase + 2);
+	j->ssr.high = inb_p(j->DSPbase + 3);
 	return 0;
 }
 
@@ -839,26 +850,26 @@
 *  General Purpose IO Register read routine
 *
 ***************************************************************************/
-extern __inline__ int ixj_gpio_read(int board)
+extern __inline__ int ixj_gpio_read(IXJ *j)
 {
-	if (ixj_WriteDSPCommand(0x5143, board))
+	if (ixj_WriteDSPCommand(0x5143, j))
 		return -1;
 
-	ixj[board].gpio.bytes.low = ixj[board].ssr.low;
-	ixj[board].gpio.bytes.high = ixj[board].ssr.high;
+	j->gpio.bytes.low = j->ssr.low;
+	j->gpio.bytes.high = j->ssr.high;
 
 	return 0;
 }
 
-extern __inline__ void LED_SetState(int state, int board)
+extern __inline__ void LED_SetState(int state, IXJ *j)
 {
-	if (ixj[board].cardtype == 300) {
-		ixj[board].pld_scrw.bits.led1 = state & 0x1 ? 1 : 0;
-		ixj[board].pld_scrw.bits.led2 = state & 0x2 ? 1 : 0;
-		ixj[board].pld_scrw.bits.led3 = state & 0x4 ? 1 : 0;
-		ixj[board].pld_scrw.bits.led4 = state & 0x8 ? 1 : 0;
+	if (j->cardtype == QTI_LINEJACK) {
+		j->pld_scrw.bits.led1 = state & 0x1 ? 1 : 0;
+		j->pld_scrw.bits.led2 = state & 0x2 ? 1 : 0;
+		j->pld_scrw.bits.led3 = state & 0x4 ? 1 : 0;
+		j->pld_scrw.bits.led4 = state & 0x8 ? 1 : 0;
 
-		outb_p(ixj[board].pld_scrw.byte, ixj[board].XILINXbase);
+		outb_p(j->pld_scrw.byte, j->XILINXbase);
 	}
 }
 
@@ -876,11 +887,9 @@
 *
 * Hook Switch changes reported on GPIO_3
 *********************************************************************/
-static int ixj_set_port(int board, int arg)
+static int ixj_set_port(IXJ *j, int arg)
 {
-	IXJ *j = &ixj[board];
-
-	if (j->cardtype == 400) {
+	if (j->cardtype == QTI_PHONEJACK_LITE) {
 		if (arg != PORT_POTS)
 			return 10;
 		else
@@ -890,20 +899,20 @@
 	case PORT_POTS:
 		j->port = PORT_POTS;
 		switch (j->cardtype) {
-		case 600:
+		case QTI_PHONECARD:
 			if (j->flags.pcmciasct == 1)
-				SLIC_SetState(PLD_SLIC_STATE_ACTIVE, board);
+				SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j);
 			else
 				return 11;
 			break;
-		case 500:
+		case QTI_PHONEJACK_PCI:
 			j->pld_slicw.pcib.mic = 0;
 			j->pld_slicw.pcib.spk = 0;
 			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
 			break;
-		case 300:
-			ixj_set_pots(board, 0);
-			if (ixj_WriteDSPCommand(0xC528, board))		/* Write CODEC config to
+		case QTI_LINEJACK:
+			ixj_set_pots(j, 0);
+			if (ixj_WriteDSPCommand(0xC528, j))		/* Write CODEC config to
 									   Software Control Register */
 				return 2;
 			j->pld_scrw.bits.daafsyncen = 0;	// Turn off DAA Frame Sync
@@ -914,19 +923,19 @@
 			j->pld_slicw.bits.rly1 = 1;
 			j->pld_slicw.bits.spken = 0;
 			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-			SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);
+			SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
 			break;
-		case 100:
+		case QTI_PHONEJACK:
 			j->gpio.bytes.high = 0x0B;
 			j->gpio.bits.gpio6 = 0;
 			j->gpio.bits.gpio7 = 0;
-			ixj_WriteDSPCommand(j->gpio.word, board);
+			ixj_WriteDSPCommand(j->gpio.word, j);
 			break;
 		}
 		break;
 	case PORT_PSTN:
-		if (j->cardtype == 300) {
-			ixj_WriteDSPCommand(0xC534, board);	/* Write CODEC config to Software Control Register */
+		if (j->cardtype == QTI_LINEJACK) {
+			ixj_WriteDSPCommand(0xC534, j);	/* Write CODEC config to Software Control Register */
 
 			j->pld_slicw.bits.rly3 = 0;
 			j->pld_slicw.bits.rly1 = 1;
@@ -940,38 +949,35 @@
 	case PORT_SPEAKER:
 		j->port = PORT_SPEAKER;
 		switch (j->cardtype) {
-		case 600:
+		case QTI_PHONECARD:
 			if (j->flags.pcmciasct) {
-				SLIC_SetState(PLD_SLIC_STATE_OC, board);
-//                              while(SLIC_GetState(board) != PLD_SLIC_STATE_OC) {
-				//                                      SLIC_SetState(PLD_SLIC_STATE_OC,board);
-				//                              }
+				SLIC_SetState(PLD_SLIC_STATE_OC, j);
 			}
 			break;
-		case 500:
+		case QTI_PHONEJACK_PCI:
 			j->pld_slicw.pcib.mic = 1;
 			j->pld_slicw.pcib.spk = 1;
 			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
 			break;
-		case 300:
-			ixj_set_pots(board, 0);
+		case QTI_LINEJACK:
+			ixj_set_pots(j, 0);
 			break;
-		case 100:
+		case QTI_PHONEJACK:
 			j->gpio.bytes.high = 0x0B;
 			j->gpio.bits.gpio6 = 0;
 			j->gpio.bits.gpio7 = 1;
-			ixj_WriteDSPCommand(j->gpio.word, board);
+			ixj_WriteDSPCommand(j->gpio.word, j);
 			break;
 		}
 		break;
 	case PORT_HANDSET:
-		if (j->cardtype == 300 || j->cardtype == 500) {
+		if (j->cardtype == QTI_LINEJACK || j->cardtype == QTI_PHONEJACK_PCI) {
 			return 5;
 		} else {
 			j->gpio.bytes.high = 0x0B;
 			j->gpio.bits.gpio6 = 1;
 			j->gpio.bits.gpio7 = 0;
-			ixj_WriteDSPCommand(j->gpio.word, board);
+			ixj_WriteDSPCommand(j->gpio.word, j);
 			j->port = PORT_HANDSET;
 		}
 		break;
@@ -982,11 +988,9 @@
 	return 0;
 }
 
-static int ixj_set_pots(int board, int arg)
+static int ixj_set_pots(IXJ *j, int arg)
 {
-	IXJ *j = &ixj[board];
-
-	if (j->cardtype == 300) {
+	if (j->cardtype == QTI_LINEJACK) {
 		if (arg) {
 			if (j->port == PORT_PSTN) {
 				j->pld_slicw.bits.rly1 = 0;
@@ -1005,33 +1009,22 @@
 	}
 }
 
-static void ixj_ring_on(int board)
+static void ixj_ring_on(IXJ *j)
 {
-	IXJ *j = &ixj[board];
-	if (j->dsp.low == 0x20)	// Internet PhoneJACK
-	 {
-		if (ixjdebug > 0)
-			printk(KERN_INFO "IXJ Ring On /dev/phone%d\n", board);
-
+	if (j->dsp.low == 0x20) { // Internet PhoneJACK
 		j->gpio.bytes.high = 0x0B;
 		j->gpio.bytes.low = 0x00;
 		j->gpio.bits.gpio1 = 1;
 		j->gpio.bits.gpio2 = 1;
 		j->gpio.bits.gpio5 = 0;
-		ixj_WriteDSPCommand(j->gpio.word, board);	/* send the ring signal */
-	} else			// Internet LineJACK, Internet PhoneJACK Lite or Internet PhoneJACK PCI
-	 {
-		if (ixjdebug > 0)
-			printk(KERN_INFO "IXJ Ring On /dev/phone%d\n", board);
-
-		SLIC_SetState(PLD_SLIC_STATE_RINGING, board);
+		ixj_WriteDSPCommand(j->gpio.word, j);	/* send the ring signal */
+	} else {			// Internet LineJACK, Internet PhoneJACK Lite or Internet PhoneJACK PCI
+		SLIC_SetState(PLD_SLIC_STATE_RINGING, j);
 	}
 }
 
-static int ixj_pcmcia_cable_check(int board)
+static int ixj_pcmcia_cable_check(IXJ *j)
 {
-	IXJ *j = &ixj[board];
-
 	j->pccr1.byte = inb_p(j->XILINXbase + 0x03);
 	if (!j->flags.pcmciastate) {
 		j->pccr2.byte = inb_p(j->XILINXbase + 0x02);
@@ -1044,13 +1037,13 @@
 			j->psccr.bits.dev = 3;
 			j->psccr.bits.rw = 1;
 			outw_p(j->psccr.byte << 8, j->XILINXbase + 0x00);
-			ixj_PCcontrol_wait(board);
+			ixj_PCcontrol_wait(j);
 			j->pslic.byte = inw_p(j->XILINXbase + 0x00) & 0xFF;
 			j->pslic.bits.led2 = j->pslic.bits.det ? 1 : 0;
 			j->psccr.bits.dev = 3;
 			j->psccr.bits.rw = 0;
 			outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00);
-			ixj_PCcontrol_wait(board);
+			ixj_PCcontrol_wait(j);
 			return j->pslic.bits.led2 ? 1 : 0;
 		} else if (j->flags.pcmciasct) {
 			return j->r_hook;
@@ -1089,7 +1082,7 @@
 			j->psccr.bits.dev = 3;
 			j->psccr.bits.rw = 1;
 			outb_p(j->psccr.byte, j->XILINXbase + 0x01);
-			ixj_PCcontrol_wait(board);
+			ixj_PCcontrol_wait(j);
 			j->flags.pcmciascp = 1;		// Set Cable Present Flag
 
 			j->flags.pcmciasct = (inw_p(j->XILINXbase + 0x00) >> 8) & 0x03;		// Get Cable Type
@@ -1122,7 +1115,7 @@
 			j->psccr.bits.dev = 0;
 			outb(j->sic1.byte, j->XILINXbase + 0x00);
 			outb(j->psccr.byte, j->XILINXbase + 0x01);
-			ixj_PCcontrol_wait(board);
+			ixj_PCcontrol_wait(j);
 			j->sic2.bits.al = 0;	// Analog Loopback DAC analog -> ADC analog
 
 			j->sic2.bits.dl2 = 0;	// Digital Loopback DAC -> ADC one bit
@@ -1140,7 +1133,7 @@
 			j->psccr.bits.dev = 0;
 			outb(j->sic2.byte, j->XILINXbase + 0x00);
 			outb(j->psccr.byte, j->XILINXbase + 0x01);
-			ixj_PCcontrol_wait(board);
+			ixj_PCcontrol_wait(j);
 			j->psccr.bits.addr = 3;		// R/W Smart Cable Register Address
 
 			j->psccr.bits.rw = 0;	// Read / Write flag
@@ -1149,7 +1142,7 @@
 			outb(0x00, j->XILINXbase + 0x00);	// PLL Divide N1
 
 			outb(j->psccr.byte, j->XILINXbase + 0x01);
-			ixj_PCcontrol_wait(board);
+			ixj_PCcontrol_wait(j);
 			j->psccr.bits.addr = 4;		// R/W Smart Cable Register Address
 
 			j->psccr.bits.rw = 0;	// Read / Write flag
@@ -1158,7 +1151,7 @@
 			outb(0x09, j->XILINXbase + 0x00);	// PLL Multiply M1
 
 			outb(j->psccr.byte, j->XILINXbase + 0x01);
-			ixj_PCcontrol_wait(board);
+			ixj_PCcontrol_wait(j);
 			j->sirxg.bits.lig = 1;	// Line In Gain
 
 			j->sirxg.bits.lim = 1;	// Line In Mute
@@ -1178,7 +1171,7 @@
 			j->psccr.bits.dev = 0;
 			outb(j->sirxg.byte, j->XILINXbase + 0x00);
 			outb(j->psccr.byte, j->XILINXbase + 0x01);
-			ixj_PCcontrol_wait(board);
+			ixj_PCcontrol_wait(j);
 			j->siadc.bits.hom = 0;	// Handset Out Mute
 
 			j->siadc.bits.lom = 0;	// Line Out Mute
@@ -1192,7 +1185,7 @@
 			j->psccr.bits.dev = 0;
 			outb(j->siadc.byte, j->XILINXbase + 0x00);
 			outb(j->psccr.byte, j->XILINXbase + 0x01);
-			ixj_PCcontrol_wait(board);
+			ixj_PCcontrol_wait(j);
 			j->sidac.bits.srm = 1;	// Speaker Right Mute
 
 			j->sidac.bits.slm = 1;	// Speaker Left Mute
@@ -1206,7 +1199,7 @@
 			j->psccr.bits.dev = 0;
 			outb(j->sidac.byte, j->XILINXbase + 0x00);
 			outb(j->psccr.byte, j->XILINXbase + 0x01);
-			ixj_PCcontrol_wait(board);
+			ixj_PCcontrol_wait(j);
 			j->siaatt.bits.sot = 0;
 			j->psccr.bits.addr = 9;		// R/W Smart Cable Register Address
 
@@ -1215,7 +1208,7 @@
 			j->psccr.bits.dev = 0;
 			outb(j->siaatt.byte, j->XILINXbase + 0x00);
 			outb(j->psccr.byte, j->XILINXbase + 0x01);
-			ixj_PCcontrol_wait(board);
+			ixj_PCcontrol_wait(j);
 
 			if (j->flags.pcmciasct == 1 && !j->readers && !j->writers) {
 				j->psccr.byte = j->pslic.byte = 0;
@@ -1223,7 +1216,7 @@
 				j->psccr.bits.dev = 3;
 				j->psccr.bits.rw = 0;
 				outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00);
-				ixj_PCcontrol_wait(board);
+				ixj_PCcontrol_wait(j);
 			}
 		}
 		return 0;
@@ -1234,21 +1227,20 @@
 	return 0;
 }
 
-static int ixj_hookstate(int board)
+static int ixj_hookstate(IXJ *j)
 {
 	unsigned long det;
-	IXJ *j = &ixj[board];
 	int fOffHook = 0;
 
 	switch (j->cardtype) {
-	case 100:
-		ixj_gpio_read(board);
+	case QTI_PHONEJACK:
+		ixj_gpio_read(j);
 		fOffHook = j->gpio.bits.gpio3read ? 1 : 0;
 		break;
-	case 300:
-	case 400:
-	case 500:
-		SLIC_GetState(board);
+	case QTI_LINEJACK:
+	case QTI_PHONEJACK_LITE:
+	case QTI_PHONEJACK_PCI:
+		SLIC_GetState(j);
 		if (j->pld_slicr.bits.state == PLD_SLIC_STATE_ACTIVE ||
 		    j->pld_slicr.bits.state == PLD_SLIC_STATE_STANDBY) {
 			if (j->flags.ringing) {
@@ -1259,27 +1251,27 @@
 						schedule_timeout(1);
 					}
 				}
-				SLIC_GetState(board);
+				SLIC_GetState(j);
 				if (j->pld_slicr.bits.state == PLD_SLIC_STATE_RINGING) {
-					ixj_ring_on(board);
+					ixj_ring_on(j);
 				}
 			}
-			if (j->cardtype == 500) {
+			if (j->cardtype == QTI_PHONEJACK_PCI) {
 				j->pld_scrr.byte = inb_p(j->XILINXbase);
 				fOffHook = j->pld_scrr.pcib.det ? 1 : 0;
 			} else
 				fOffHook = j->pld_slicr.bits.det ? 1 : 0;
 		}
 		break;
-	case 600:
-		fOffHook = ixj_pcmcia_cable_check(board);
+	case QTI_PHONECARD:
+		fOffHook = ixj_pcmcia_cable_check(j);
 		break;
 	}
 	if (j->r_hook != fOffHook) {
 		j->r_hook = fOffHook;
 		if (j->port != PORT_POTS) {
 			j->ex.bits.hookstate = 1;
-			ixj_kill_fasync(board, POLL_IN);
+			ixj_kill_fasync(j, POLL_PRI);
 		} else if (!fOffHook) {
 			j->flash_end = jiffies + (hertz / 10 * 6);
 		}
@@ -1299,9 +1291,8 @@
 		return fOffHook;
 }
 
-static void ixj_ring_off(board)
+static void ixj_ring_off(IXJ *j)
 {
-	IXJ *j = &ixj[board];
 
 	if (j->dsp.low == 0x20)	// Internet PhoneJACK
 	 {
@@ -1312,57 +1303,54 @@
 		j->gpio.bits.gpio1 = 0;
 		j->gpio.bits.gpio2 = 1;
 		j->gpio.bits.gpio5 = 0;
-		ixj_WriteDSPCommand(j->gpio.word, board);
+		ixj_WriteDSPCommand(j->gpio.word, j);
 	} else			// Internet LineJACK
 	 {
 		if (ixjdebug > 0)
 			printk(KERN_INFO "IXJ Ring Off\n");
 
-		SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);
+		SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
 
-		SLIC_GetState(board);
+		SLIC_GetState(j);
 	}
 }
 
-static void ixj_ring_start(int board)
+static void ixj_ring_start(IXJ *j)
 {
-	IXJ *j = &ixj[board];
-
 	j->flags.cringing = 1;
-	if (ixj_hookstate(board) & 1) {
+	if (ixj_hookstate(j) & 1) {
 		if (j->port == PORT_POTS)
-			ixj_ring_off(board);
+			ixj_ring_off(j);
 		j->flags.cringing = 0;
 	} else {
 		j->ring_cadence_jif = jiffies;
 		j->ring_cadence_t = 15;
 		if (j->ring_cadence & 1 << j->ring_cadence_t) {
-			ixj_ring_on(board);
+			ixj_ring_on(j);
 		} else {
-			ixj_ring_off(board);
+			ixj_ring_off(j);
 		}
 	}
 }
 
-static int ixj_ring(int board)
+static int ixj_ring(IXJ *j)
 {
 	char cntr;
 	unsigned long jif, det;
-	IXJ *j = &ixj[board];
 
 	j->flags.ringing = 1;
-	if (ixj_hookstate(board) & 1) {
-		ixj_ring_off(board);
+	if (ixj_hookstate(j) & 1) {
+		ixj_ring_off(j);
 		j->flags.ringing = 0;
 		return 1;
 	}
 	det = 0;
 	for (cntr = 0; cntr < j->maxrings; cntr++) {
 		jif = jiffies + (1 * hertz);
-		ixj_ring_on(board);
+		ixj_ring_on(j);
 		while (time_before(jiffies, jif)) {
-			if (ixj_hookstate(board) & 1) {
-				ixj_ring_off(board);
+			if (ixj_hookstate(j) & 1) {
+				ixj_ring_off(j);
 				j->flags.ringing = 0;
 				return 1;
 			}
@@ -1372,9 +1360,9 @@
 				break;
 		}
 		jif = jiffies + (3 * hertz);
-		ixj_ring_off(board);
+		ixj_ring_off(j);
 		while (time_before(jiffies, jif)) {
-			if (ixj_hookstate(board) & 1) {
+			if (ixj_hookstate(j) & 1) {
 				det = jiffies + (hertz / 100);
 				while (time_before(jiffies, det)) {
 					set_current_state(TASK_INTERRUPTIBLE);
@@ -1382,7 +1370,7 @@
 					if (signal_pending(current))
 						break;
 				}
-				if (ixj_hookstate(board) & 1) {
+				if (ixj_hookstate(j) & 1) {
 					j->flags.ringing = 0;
 					return 1;
 				}
@@ -1393,14 +1381,17 @@
 				break;
 		}
 	}
-	ixj_ring_off(board);
+	ixj_ring_off(j);
 	j->flags.ringing = 0;
 	return 0;
 }
 
 int ixj_open(struct phone_device *p, struct file *file_p)
 {
-	IXJ *j = file_p->private_data = &ixj[p->board];
+	IXJ *j = file_p->private_data = ixj[p->board];
+
+	if (j == NULL)
+		return -ENODEV;
 
 	if (!j->DSPbase)
 		return -ENODEV;
@@ -1424,14 +1415,13 @@
 		}
 	}
 
-	if (j->cardtype == 600) {
+	if (j->cardtype == QTI_PHONECARD) {
 		j->pslic.bits.powerdown = 0;
 		j->psccr.bits.dev = 3;
 		j->psccr.bits.rw = 0;
 		outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00);
-		ixj_PCcontrol_wait(p->board);
+		ixj_PCcontrol_wait(j);
 	}
-	MOD_INC_USE_COUNT;
 
 	if (ixjdebug > 0)
 		printk(KERN_INFO "Opening board %d\n", p->board);
@@ -1443,25 +1433,22 @@
 int ixj_release(struct inode *inode, struct file *file_p)
 {
 	IXJ_TONE ti;
-//	int board = NUM(inode->i_rdev);
+	int cnt;
 	IXJ *j = file_p->private_data;
-	int board = j->p.board;
-//	IXJ *j = &ixj[board];
 
 	if (ixjdebug > 0)
 		printk(KERN_INFO "Closing board %d\n", NUM(inode->i_rdev));
 
-	daa_set_mode(board, SOP_PU_SLEEP);
-	if (j->cardtype == 600)
-		ixj_set_port(board, PORT_SPEAKER);
+	if (j->cardtype == QTI_PHONECARD)
+		ixj_set_port(j, PORT_SPEAKER);
 	else
-		ixj_set_port(board, PORT_POTS);
-	aec_stop(board);
-	ixj_play_stop(board);
-	ixj_record_stop(board);
-	set_play_volume(board, 0x100);
-	set_rec_volume(board, 0x100);
-	ixj_ring_off(board);
+		ixj_set_port(j, PORT_POTS);
+	aec_stop(j);
+	ixj_play_stop(j);
+	ixj_record_stop(j);
+	set_play_volume(j, 0x100);
+	set_rec_volume(j, 0x100);
+	ixj_ring_off(j);
 
 	// Restore the tone table to default settings.
 	ti.tone_index = 10;
@@ -1484,97 +1471,114 @@
 	ti.freq0 = hz800;
 	ti.gain1 = 0;
 	ti.freq1 = 0;
-	ixj_init_tone(board, &ti);
+	ixj_init_tone(j, &ti);
 	ti.tone_index = 14;
 	ti.gain0 = 1;
 	ti.freq0 = hz1000;
 	ti.gain1 = 0;
 	ti.freq1 = 0;
-	ixj_init_tone(board, &ti);
+	ixj_init_tone(j, &ti);
 	ti.tone_index = 15;
 	ti.gain0 = 1;
 	ti.freq0 = hz1250;
 	ti.gain1 = 0;
 	ti.freq1 = 0;
-	ixj_init_tone(board, &ti);
+	ixj_init_tone(j, &ti);
 	ti.tone_index = 16;
 	ti.gain0 = 1;
 	ti.freq0 = hz950;
 	ti.gain1 = 0;
 	ti.freq1 = 0;
-	ixj_init_tone(board, &ti);
+	ixj_init_tone(j, &ti);
 	ti.tone_index = 17;
 	ti.gain0 = 1;
 	ti.freq0 = hz1100;
 	ti.gain1 = 0;
 	ti.freq1 = 0;
-	ixj_init_tone(board, &ti);
+	ixj_init_tone(j, &ti);
 	ti.tone_index = 18;
 	ti.gain0 = 1;
 	ti.freq0 = hz1400;
 	ti.gain1 = 0;
 	ti.freq1 = 0;
-	ixj_init_tone(board, &ti);
+	ixj_init_tone(j, &ti);
 	ti.tone_index = 19;
 	ti.gain0 = 1;
 	ti.freq0 = hz1500;
 	ti.gain1 = 0;
 	ti.freq1 = 0;
-	ixj_init_tone(board, &ti);
+	ixj_init_tone(j, &ti);
 	ti.tone_index = 20;
 	ti.gain0 = 1;
 	ti.freq0 = hz1600;
 	ti.gain1 = 0;
 	ti.freq1 = 0;
-	ixj_init_tone(board, &ti);
+	ixj_init_tone(j, &ti);
 	ti.tone_index = 21;
 	ti.gain0 = 1;
 	ti.freq0 = hz1800;
 	ti.gain1 = 0;
 	ti.freq1 = 0;
-	ixj_init_tone(board, &ti);
+	ixj_init_tone(j, &ti);
 	ti.tone_index = 22;
 	ti.gain0 = 1;
 	ti.freq0 = hz2100;
 	ti.gain1 = 0;
 	ti.freq1 = 0;
-	ixj_init_tone(board, &ti);
+	ixj_init_tone(j, &ti);
 	ti.tone_index = 23;
 	ti.gain0 = 1;
 	ti.freq0 = hz1300;
 	ti.gain1 = 0;
 	ti.freq1 = 0;
-	ixj_init_tone(board, &ti);
+	ixj_init_tone(j, &ti);
 	ti.tone_index = 24;
 	ti.gain0 = 1;
 	ti.freq0 = hz2450;
 	ti.gain1 = 0;
 	ti.freq1 = 0;
-	ixj_init_tone(board, &ti);
+	ixj_init_tone(j, &ti);
 	ti.tone_index = 25;
 	ti.gain0 = 1;
 	ti.freq0 = hz350;
 	ti.gain1 = 0;
 	ti.freq1 = hz440;
-	ixj_init_tone(board, &ti);
+	ixj_init_tone(j, &ti);
 	ti.tone_index = 26;
 	ti.gain0 = 1;
 	ti.freq0 = hz440;
 	ti.gain1 = 0;
 	ti.freq1 = hz480;
-	ixj_init_tone(board, &ti);
+	ixj_init_tone(j, &ti);
 	ti.tone_index = 27;
 	ti.gain0 = 1;
 	ti.freq0 = hz480;
 	ti.gain1 = 0;
 	ti.freq1 = hz620;
-	ixj_init_tone(board, &ti);
+	ixj_init_tone(j, &ti);
 
-	idle(board);
+	set_rec_depth(j, 2);	// Set Record Channel Limit to 2 frames
 
-//        if(j->cardtype == 600) { // && j->flags.pcmciasct == 1 && j->readers == 1 && j->writers == 1) {
-	SLIC_SetState(PLD_SLIC_STATE_OC, board);
-//      }
+	set_play_depth(j, 2);	// Set Playback Channel Limit to 2 frames
+
+	j->ex.bits.dtmf_ready = 0;
+	j->dtmf_state = 0;
+	j->dtmf_wp = j->dtmf_rp = 0;
+	j->rec_mode = j->play_mode = -1;
+	j->flags.ringing = 0;
+	j->maxrings = MAXRINGS;
+	j->ring_cadence = USA_RING_CADENCE;
+	j->drybuffer = 0;
+	j->winktime = 320;
+	j->flags.dtmf_oob = 0;
+	for (cnt = 0; cnt < 4; cnt++)
+		j->cadence_f[cnt].enable = 0;
+
+	idle(j);
+
+	if(j->cardtype == QTI_PHONECARD) {
+		SLIC_SetState(PLD_SLIC_STATE_OC, j);
+	}
 
 	if (file_p->f_mode & FMODE_READ)
 		j->readers--;
@@ -1596,24 +1600,23 @@
 	j->flags.cidsent = j->flags.cidring = 0;
 	ixj_fasync(-1, file_p, 0);	// remove from list of async notification
 
-	if(j->cardtype == 300 && !j->readers && !j->writers) {
-		ixj_set_port(board, PORT_PSTN);
-		ixj_set_pots(board, 1);
+	if(j->cardtype == QTI_LINEJACK && !j->readers && !j->writers) {
+		ixj_set_port(j, PORT_PSTN);
+		daa_set_mode(j, SOP_PU_SLEEP);
+		ixj_set_pots(j, 1);
 	}
-	ixj_WriteDSPCommand(0x0FE3, board);	// Put the DSP in 1/5 power mode.
+	ixj_WriteDSPCommand(0x0FE3, j);	// Put the DSP in 1/5 power mode.
 
 	file_p->private_data = NULL;
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
-static int read_filters(int board)
+static int read_filters(IXJ *j)
 {
 	unsigned short fc, cnt;
 	int var;
-	IXJ *j = &ixj[board];
 
-	if (ixj_WriteDSPCommand(0x5144, board))
+	if (ixj_WriteDSPCommand(0x5144, j))
 		return -1;
 
 	fc = j->ssr.high << 8 | j->ssr.low;
@@ -1628,10 +1631,10 @@
 	var = 10;
 
 	for (cnt = 0; cnt < 4; cnt++) {
-		if (ixj_WriteDSPCommand(0x5154 + cnt, board))
+		if (ixj_WriteDSPCommand(0x5154 + cnt, j))
 			return -1;
 
-		if (ixj_WriteDSPCommand(0x515C, board))
+		if (ixj_WriteDSPCommand(0x515C, j))
 			return -1;
 
 		j->filter_hist[cnt] = j->ssr.high << 8 | j->ssr.low;
@@ -1756,17 +1759,14 @@
 	return 0;
 }
 
-static int LineMonitor(int board)
+static int LineMonitor(IXJ *j)
 {
-	IXJ *j = &ixj[board];
-
 	if (j->dtmf_proc) {
 		return -1;
 	}
 	j->dtmf_proc = 1;
 
-	if (ixj_WriteDSPCommand(0x7000, board))		// Line Monitor
-
+	if (ixj_WriteDSPCommand(0x7000, j))		// Line Monitor
 		return -1;
 
 	j->dtmf.bytes.high = j->ssr.high;
@@ -1797,9 +1797,12 @@
 ssize_t ixj_read(struct file * file_p, char *buf, size_t length, loff_t * ppos)
 {
 	unsigned long i = *ppos;
-	IXJ *j = &ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
+	IXJ *j = ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
 	DECLARE_WAITQUEUE(wait, current);
 
+	if (j == NULL) /* shouldn't happen! */
+		return -ENODEV;
+
 	if (j->flags.inread)
 		return -EALREADY;
 
@@ -1823,7 +1826,7 @@
 			j->flags.inread = 0;
 			return -EAGAIN;
 		}
-		if (!ixj_hookstate(NUM(file_p->f_dentry->d_inode->i_rdev))) {
+		if (!ixj_hookstate(j)) {
 			set_current_state(TASK_RUNNING);
 			remove_wait_queue(&j->read_q, &wait);
 			j->flags.inread = 0;
@@ -1857,7 +1860,10 @@
 {
 	int pre_retval;
 	ssize_t read_retval = 0;
-	IXJ *j = &ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
+	IXJ *j = ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
+
+	if (j == NULL) /* shouldn't happen! */
+		return -ENODEV;
 
 	pre_retval = ixj_PreRead(j, 0L);
 	switch (pre_retval) {
@@ -1883,6 +1889,9 @@
 	IXJ *j = file_p->private_data;
 	DECLARE_WAITQUEUE(wait, current);
 
+	if (j == NULL) /* shouldn't happen! */
+		return -ENODEV;
+
 	if (j->flags.inwrite)
 		return -EALREADY;
 
@@ -1907,7 +1916,7 @@
 			j->flags.inwrite = 0;
 			return -EAGAIN;
 		}
-		if (!ixj_hookstate(NUM(file_p->f_dentry->d_inode->i_rdev))) {
+		if (!ixj_hookstate(j)) {
 			set_current_state(TASK_RUNNING);
 			remove_wait_queue(&j->write_q, &wait);
 			j->flags.inwrite = 0;
@@ -1938,7 +1947,10 @@
 {
 	int pre_retval;
 	ssize_t write_retval = 0;
-	IXJ *j = &ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
+	IXJ *j = ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
+
+	if (j == NULL) /* shouldn't happen! */
+		return -ENODEV;
 
 	pre_retval = ixj_PreWrite(j, 0L);
 	switch (pre_retval) {
@@ -1946,14 +1958,14 @@
 		write_retval = ixj_write(file_p, buf, count, ppos);
 		if (write_retval != -EFAULT) {
 			ixj_PostWrite(j, 0L);
-			j->write_buffer_wp += count;
+			j->write_buffer_wp += write_retval;
 			j->write_buffers_empty--;
 		}
 		break;
 	case NOPOST:
 		write_retval = ixj_write(file_p, buf, count, ppos);
 		if (write_retval != -EFAULT) {
-			j->write_buffer_wp += count;
+			j->write_buffer_wp += write_retval;
 			j->write_buffers_empty--;
 		}
 		break;
@@ -1966,16 +1978,15 @@
 	return write_retval;
 }
 
-static void ixj_read_frame(int board)
+static void ixj_read_frame(IXJ *j)
 {
 	int cnt, dly;
-	IXJ *j = &ixj[board];
 
 	if (j->read_buffer) {
 		for (cnt = 0; cnt < j->rec_frame_size * 2; cnt += 2) {
-			if (!(cnt % 16) && !IsRxReady(board)) {
+			if (!(cnt % 16) && !IsRxReady(j)) {
 				dly = 0;
-				while (!IsRxReady(board)) {
+				while (!IsRxReady(j)) {
 					if (dly++ > 5) {
 						dly = 0;
 						break;
@@ -1993,11 +2004,19 @@
 		}
 		++j->framesread;
 		if (j->intercom != -1) {
-			if (IsTxReady(j->intercom)) {
+			IXJ *icom = ixj[j->intercom];
+
+			if (icom == NULL) { /* shouldn't happen! */
+				printk(KERN_ERR "ixj_read_frame(): j->intercom = %d = NULL!",
+				       j->intercom);
+				return;
+			}
+
+			if (IsTxReady(icom)) {
 				for (cnt = 0; cnt < j->rec_frame_size * 2; cnt += 2) {
-					if (!(cnt % 16) && !IsTxReady(board)) {
+					if (!(cnt % 16) && !IsTxReady(j)) {
 						dly = 0;
-						while (!IsTxReady(board)) {
+						while (!IsTxReady(j)) {
 							if (dly++ > 5) {
 								dly = 0;
 								break;
@@ -2005,10 +2024,10 @@
 							udelay(10);
 						}
 					}
-					outb_p(*(j->read_buffer + cnt), ixj[j->intercom].DSPbase + 0x0C);
-					outb_p(*(j->read_buffer + cnt + 1), ixj[j->intercom].DSPbase + 0x0D);
+					outb_p(*(j->read_buffer + cnt), icom->DSPbase + 0x0C);
+					outb_p(*(j->read_buffer + cnt + 1), icom->DSPbase + 0x0D);
 				}
-				++ixj[j->intercom].frameswritten;
+				++icom->frameswritten;
 			}
 		} else {
 			j->read_buffer_ready = 1;
@@ -2016,7 +2035,7 @@
 
 			wake_up_interruptible(&j->poll_q);	// Wake any blocked selects
 
-			ixj_kill_fasync(board, POLL_OUT);
+			ixj_kill_fasync(j, POLL_IN);
 		}
 	}
 }
@@ -2078,16 +2097,15 @@
 };
 
 
-static void ixj_write_cid_bit(int board, int bit)
+static void ixj_write_cid_bit(IXJ *j, int bit)
 {
 	int dly;
 	IXJ_WORD dat;
-	IXJ *j = &ixj[board];
 
 	while (j->fskcnt < 20) {
-		if (!IsTxReady(board)) {
+		if (!IsTxReady(j)) {
 			dly = 0;
-			while (!IsTxReady(board)) {
+			while (!IsTxReady(j)) {
 				if (dly++ > 5) {
 					dly = 0;
 					//      break;
@@ -2111,7 +2129,7 @@
 
 }
 
-static void ixj_write_cid_byte(int board, char byte)
+static void ixj_write_cid_byte(IXJ *board, char byte)
 {
 	IXJ_CBYTE cb;
 
@@ -2129,7 +2147,7 @@
 	ixj_write_cid_bit(board, 1);
 }
 
-static void ixj_write_cid_seize(int board)
+static void ixj_write_cid_seize(IXJ *board)
 {
 	int cnt;
 
@@ -2142,7 +2160,7 @@
 	}
 }
 
-static void ixj_write_cidcw_seize(int board)
+static void ixj_write_cidcw_seize(IXJ *board)
 {
 	int cnt;
 
@@ -2151,7 +2169,7 @@
 	}
 }
 
-static int ixj_write_cid_string(int board, char *s, int checksum)
+static int ixj_write_cid_string(IXJ *board, char *s, int checksum)
 {
 	int cnt;
 
@@ -2162,15 +2180,14 @@
 	return checksum;
 }
 
-static void ixj_pad_fsk(int board, int pad)
+static void ixj_pad_fsk(IXJ *j, int pad)
 {
 	int cnt, dly;
-	IXJ *j = &ixj[board];
 
 	for (cnt = 0; cnt < pad; cnt++) {
-		if (!IsTxReady(board)) {
+		if (!IsTxReady(j)) {
 			dly = 0;
-			while (!IsTxReady(board)) {
+			while (!IsTxReady(j)) {
 				if (dly++ > 5) {
 					dly = 0;
 				}
@@ -2181,9 +2198,9 @@
 		outb_p(0x00, j->DSPbase + 0x0D);
 	}
 	for (cnt = 0; cnt < 720; cnt++) {
-		if (!IsTxReady(board)) {
+		if (!IsTxReady(j)) {
 			dly = 0;
-			while (!IsTxReady(board)) {
+			while (!IsTxReady(j)) {
 				if (dly++ > 5) {
 					dly = 0;
 				}
@@ -2195,10 +2212,8 @@
 	}
 }
 
-static void ixj_write_cid(int board)
+static void ixj_write_cid(IXJ *j)
 {
-	IXJ *j = &ixj[board];
-
 	char sdmf1[50];
 	char sdmf2[50];
 	char sdmf3[80];
@@ -2207,13 +2222,13 @@
 
 	int checksum = 0;
 
-	if (ixj[board].dsp.low == 0x20)
+	if (j->dsp.low == 0x20)
 		return;
 
-	ixj[board].fskz = ixj[board].fskphase = ixj[board].fskcnt =
-	    ixj[board].fskdcnt = 0;
+	j->fskz = j->fskphase = j->fskcnt =
+	    j->fskdcnt = 0;
 
-	ixj[board].flags.cidplay = 1;
+	j->flags.cidplay = 1;
 
 	strcpy(sdmf1, j->cid_send.month);
 	strcat(sdmf1, j->cid_send.day);
@@ -2227,65 +2242,60 @@
 	len3 = strlen(sdmf3);
 	mdmflen = len1 + len2 + len3 + 6;
 
-	printk("CID Lengths = %d %d %d %d\n", len1, len2, len3, mdmflen);
-
-	set_base_frame(board, 30);
-	set_play_codec(board, LINEAR16);
+	set_base_frame(j, 30);
+	set_play_codec(j, LINEAR16);
 
-	if (ixj[board].port == PORT_POTS)
+	if (j->port == PORT_POTS)
 		if(!j->r_hook)
-			SLIC_SetState(PLD_SLIC_STATE_OHT, board);
+			SLIC_SetState(PLD_SLIC_STATE_OHT, j);
 
-	set_play_volume(board, 0x1B);
-	ixj_play_start(board);
-	ixj_write_cid_seize(board);
+	set_play_volume(j, 0x1B);
+	ixj_play_start(j);
+	ixj_write_cid_seize(j);
 
-	ixj_write_cid_byte(board, 0x80);
+	ixj_write_cid_byte(j, 0x80);
 	checksum = 0x80;
-	ixj_write_cid_byte(board, mdmflen);
+	ixj_write_cid_byte(j, mdmflen);
 	checksum = checksum + mdmflen;
 
-	ixj_write_cid_byte(board, 0x01);
+	ixj_write_cid_byte(j, 0x01);
 	checksum = checksum + 0x01;
-	ixj_write_cid_byte(board, len1);
+	ixj_write_cid_byte(j, len1);
 	checksum = checksum + len1;
-	checksum = ixj_write_cid_string(board, sdmf1, checksum);
+	checksum = ixj_write_cid_string(j, sdmf1, checksum);
 
-	ixj_write_cid_byte(board, 0x02);
+	ixj_write_cid_byte(j, 0x02);
 	checksum = checksum + 0x02;
-	ixj_write_cid_byte(board, len2);
+	ixj_write_cid_byte(j, len2);
 	checksum = checksum + len2;
-	checksum = ixj_write_cid_string(board, sdmf2, checksum);
+	checksum = ixj_write_cid_string(j, sdmf2, checksum);
 
-	ixj_write_cid_byte(board, 0x07);
+	ixj_write_cid_byte(j, 0x07);
 	checksum = checksum + 0x07;
-	ixj_write_cid_byte(board, len3);
+	ixj_write_cid_byte(j, len3);
 	checksum = checksum + len3;
-	checksum = ixj_write_cid_string(board, sdmf3, checksum);
+	checksum = ixj_write_cid_string(j, sdmf3, checksum);
 
 	checksum %= 256;
 	checksum ^= 0xFF;
 	checksum += 1;
-	printk("14Checksum = %d\n", checksum);
 
-	ixj_write_cid_byte(board, (char) checksum);
+	ixj_write_cid_byte(j, (char) checksum);
 
 	pad = j->fskdcnt % 240;
 	if (pad) {
 		pad = 240 - pad;
 	}
-	ixj_pad_fsk(board, pad);
-	SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);
-	ixj[board].flags.cidplay = 0;
-	ixj_play_stop(board);
+	ixj_pad_fsk(j, pad);
+	SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
+	j->flags.cidplay = 0;
+	ixj_play_stop(j);
 }
 
-static void ixj_write_cidcw(int board)
+static void ixj_write_cidcw(IXJ *j)
 {
 	IXJ_TONE ti;
 
-	IXJ *j = &ixj[board];
-
 	char sdmf1[50];
 	char sdmf2[50];
 	char sdmf3[80];
@@ -2294,37 +2304,37 @@
 
 	int checksum = 0;
 
-	if (ixj[board].dsp.low == 0x20)
+	if (j->dsp.low == 0x20)
 		return;
 
-	ixj[board].fskz = ixj[board].fskphase = ixj[board].fskcnt = ixj[board].fskdcnt = 0;
+	j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0;
 
-	ixj[board].flags.cidplay = 1;
+	j->flags.cidplay = 1;
 
 	ti.tone_index = 23;
 	ti.gain0 = 1;
 	ti.freq0 = hz440;
 	ti.gain1 = 0;
 	ti.freq1 = 0;
-	ixj_init_tone(board, &ti);
+	ixj_init_tone(j, &ti);
 
 	ti.tone_index = 24;
 	ti.gain0 = 1;
 	ti.freq0 = hz2130;
 	ti.gain1 = 0;
 	ti.freq1 = hz2750;
-	ixj_init_tone(board, &ti);
+	ixj_init_tone(j, &ti);
 
-	ixj_set_tone_on(1200, board);
-	ixj_play_tone(board, 23);
+	ixj_set_tone_on(1200, j);
+	ixj_play_tone(j, 23);
 
 	while(j->tone_state) {
 		set_current_state(TASK_INTERRUPTIBLE);
 		schedule_timeout(1);
 	}
 
-	ixj_set_tone_on(320, board);
-	ixj_play_tone(board, 24);
+	ixj_set_tone_on(320, j);
+	ixj_play_tone(j, 24);
 
 	while(j->tone_state) {
 		set_current_state(TASK_INTERRUPTIBLE);
@@ -2354,10 +2364,8 @@
 	len3 = strlen(sdmf3);
 	mdmflen = len1 + len2 + len3 + 6;
 
-	printk("CID Lengths = %d %d %d %d\n", len1, len2, len3, mdmflen);
-
 	j->cid_play_codec = j->play_codec;
-	ixj_play_stop(board);
+	ixj_play_stop(j);
 
 	switch(j->baseframe.low) {
 		case 0xA0:
@@ -2370,99 +2378,96 @@
 			j->cid_base_frame_size = 30;
 			break;
 	}
-	set_base_frame(board, 30);
-	set_play_codec(board, LINEAR16);
+	set_base_frame(j, 30);
+	set_play_codec(j, LINEAR16);
 
-	set_play_volume(board, 0x1B);
-	ixj_play_start(board);
-	ixj_write_cidcw_seize(board);
+	set_play_volume(j, 0x1B);
+	ixj_play_start(j);
+	ixj_write_cidcw_seize(j);
 
-	ixj_write_cid_byte(board, 0x80);
+	ixj_write_cid_byte(j, 0x80);
 	checksum = 0x80;
-	ixj_write_cid_byte(board, mdmflen);
+	ixj_write_cid_byte(j, mdmflen);
 	checksum = checksum + mdmflen;
 
-	ixj_write_cid_byte(board, 0x01);
+	ixj_write_cid_byte(j, 0x01);
 	checksum = checksum + 0x01;
-	ixj_write_cid_byte(board, len1);
+	ixj_write_cid_byte(j, len1);
 	checksum = checksum + len1;
-	checksum = ixj_write_cid_string(board, sdmf1, checksum);
+	checksum = ixj_write_cid_string(j, sdmf1, checksum);
 
-	ixj_write_cid_byte(board, 0x02);
+	ixj_write_cid_byte(j, 0x02);
 	checksum = checksum + 0x02;
-	ixj_write_cid_byte(board, len2);
+	ixj_write_cid_byte(j, len2);
 	checksum = checksum + len2;
-	checksum = ixj_write_cid_string(board, sdmf2, checksum);
+	checksum = ixj_write_cid_string(j, sdmf2, checksum);
 
-	ixj_write_cid_byte(board, 0x07);
+	ixj_write_cid_byte(j, 0x07);
 	checksum = checksum + 0x07;
-	ixj_write_cid_byte(board, len3);
+	ixj_write_cid_byte(j, len3);
 	checksum = checksum + len3;
-	checksum = ixj_write_cid_string(board, sdmf3, checksum);
+	checksum = ixj_write_cid_string(j, sdmf3, checksum);
 
 	checksum %= 256;
 	checksum ^= 0xFF;
 	checksum += 1;
-	printk("14Checksum = %d\n", checksum);
 
-	ixj_write_cid_byte(board, (char) checksum);
+	ixj_write_cid_byte(j, (char) checksum);
 
 	pad = j->fskdcnt % 240;
 	if (pad) {
 		pad = 240 - pad;
 	}
-	ixj_pad_fsk(board, pad);
-	ixj[board].flags.cidplay = 0;
-	ixj_play_stop(board);
+	ixj_pad_fsk(j, pad);
+	j->flags.cidplay = 0;
+	ixj_play_stop(j);
 
-	set_base_frame(board, j->cid_base_frame_size);
-	set_play_codec(board, j->cid_play_codec);
+	set_base_frame(j, j->cid_base_frame_size);
+	set_play_codec(j, j->cid_play_codec);
 }
 
-static void ixj_write_vmwi(int board, int msg)
+static void ixj_write_vmwi(IXJ *j, int msg)
 {
-	IXJ *j = &ixj[board];
-
 	char mdmflen;
 	int pad;
 
 	int checksum = 0;
 
-	if (ixj[board].dsp.low == 0x20)
+	if (j->dsp.low == 0x20)
 		return;
 
-	ixj[board].fskz = ixj[board].fskphase = ixj[board].fskcnt = ixj[board].fskdcnt = 0;
+	j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0;
 
-	ixj[board].flags.cidplay = 1;
+	j->flags.cidplay = 1;
 
 	mdmflen = 3;
 
-	set_base_frame(board, 30);
-	set_play_codec(board, LINEAR16);
+	set_base_frame(j, 30);
+	set_play_codec(j, LINEAR16);
 
-	if (ixj[board].port == PORT_POTS)
-		SLIC_SetState(PLD_SLIC_STATE_OHT, board);
+	if (j->port == PORT_POTS)
+		SLIC_SetState(PLD_SLIC_STATE_OHT, j);
 
-	set_play_volume(board, 0x1B);
-	ixj_play_start(board);
-	ixj_write_cid_seize(board);
+	set_play_volume(j, 0x1B);
+	ixj_play_start(j);
+	ixj_write_cid_seize(j);
 
-	ixj_write_cid_byte(board, 0x82);
+	ixj_write_cid_byte(j, 0x82);
 	checksum = 0x82;
-	ixj_write_cid_byte(board, mdmflen);
+	ixj_write_cid_byte(j, mdmflen);
 	checksum = checksum + mdmflen;
 
-	ixj_write_cid_byte(board, 0x0B);
+	ixj_write_cid_byte(j, 0x0B);
 	checksum = checksum + 0x0B;
-	ixj_write_cid_byte(board, 1);
+	ixj_write_cid_byte(j, 1);
 	checksum = checksum + 1;
 
 	if(msg) {
-		ixj_write_cid_byte(board, 0xFF);
+		ixj_write_cid_byte(j, 0xFF);
 		checksum = checksum + 0xFF;
 	}
 	else {
-		ixj_write_cid_byte(board, 0x00);
+		ixj_write_cid_byte(j, 0x00);
 		checksum = checksum + 0x00;
 	}
 
@@ -2470,23 +2475,22 @@
 	checksum ^= 0xFF;
 	checksum += 1;
 
-	ixj_write_cid_byte(board, (char) checksum);
+	ixj_write_cid_byte(j, (char) checksum);
 
 	pad = j->fskdcnt % 240;
 	if (pad) {
 		pad = 240 - pad;
 	}
-	ixj_pad_fsk(board, pad);
-	SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);
-	ixj[board].flags.cidplay = 0;
-	ixj_play_stop(board);
+	ixj_pad_fsk(j, pad);
+	SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
+	j->flags.cidplay = 0;
+	ixj_play_stop(j);
 }
 
-static void ixj_write_frame(int board)
+static void ixj_write_frame(IXJ *j)
 {
 	int cnt, frame_count, dly;
 	BYTES blankword;
-	IXJ *j = &ixj[board];
 
 	frame_count = 0;
 	if (j->write_buffer && j->write_buffers_empty < 2) {
@@ -2515,9 +2519,9 @@
 					break;
 				}
 				for (cnt = 0; cnt < 16; cnt++) {
-					if (!(cnt % 16) && !IsTxReady(board)) {
+					if (!(cnt % 16) && !IsTxReady(j)) {
 						dly = 0;
-						while (!IsTxReady(board)) {
+						while (!IsTxReady(j)) {
 							if (dly++ > 5) {
 								dly = 0;
 								break;
@@ -2531,9 +2535,9 @@
 				j->flags.play_first_frame = 0;
 			}
 			for (cnt = 0; cnt < j->play_frame_size * 2; cnt += 2) {
-				if (!(cnt % 16) && !IsTxReady(board)) {
+				if (!(cnt % 16) && !IsTxReady(j)) {
 					dly = 0;
-					while (!IsTxReady(board)) {
+					while (!IsTxReady(j)) {
 						if (dly++ > 5) {
 							dly = 0;
 							break;
@@ -2561,7 +2565,7 @@
 
 			wake_up_interruptible(&j->poll_q);	// Wake any blocked selects
 
-			ixj_kill_fasync(board, POLL_OUT);
+			ixj_kill_fasync(j, POLL_OUT);
 			++j->frameswritten;
 		}
 	} else {
@@ -2569,11 +2573,9 @@
 	}
 }
 
-static int idle(int board)
+static int idle(IXJ *j)
 {
-	IXJ *j = &ixj[board];
-
-	if (ixj_WriteDSPCommand(0x0000, board))		// DSP Idle
+	if (ixj_WriteDSPCommand(0x0000, j))		// DSP Idle
 
 		return 0;
 	if (j->ssr.high || j->ssr.low)
@@ -2582,15 +2584,14 @@
 		return 1;
 }
 
-static int set_base_frame(int board, int size)
+static int set_base_frame(IXJ *j, int size)
 {
 	unsigned short cmd;
 	int cnt;
-	IXJ *j = &ixj[board];
 
-	aec_stop(board);
+	aec_stop(j);
 	for (cnt = 0; cnt < 10; cnt++) {
-		if (idle(board))
+		if (idle(j))
 			break;
 	}
 	if (j->ssr.high || j->ssr.low)
@@ -2618,7 +2619,7 @@
 		else
 			return -1;
 	}
-	if (ixj_WriteDSPCommand(cmd, board)) {
+	if (ixj_WriteDSPCommand(cmd, j)) {
 		j->baseframe.high = j->baseframe.low = 0xFF;
 		return -1;
 	} else {
@@ -2628,10 +2629,9 @@
 	return size;
 }
 
-static int set_rec_codec(int board, int rate)
+static int set_rec_codec(IXJ *j, int rate)
 {
 	int retval = 0;
-	IXJ *j = &ixj[board];
 
 	j->rec_codec = rate;
 
@@ -2790,16 +2790,15 @@
 	return retval;
 }
 
-static int ixj_record_start(int board)
+static int ixj_record_start(IXJ *j)
 {
 	unsigned short cmd = 0x0000;
-	IXJ *j = &ixj[board];
 
 	if (j->read_buffer) {
-		ixj_record_stop(board);
+		ixj_record_stop(j);
 	}
 	j->flags.recording = 1;
-	ixj_WriteDSPCommand(0x0FE0, board);	// Put the DSP in full power mode.
+	ixj_WriteDSPCommand(0x0FE0, j);	// Put the DSP in full power mode.
 
 	if (!j->rec_mode) {
 		switch (j->rec_codec) {
@@ -2830,20 +2829,21 @@
 		default:
 			return 1;
 		}
-		if (ixj_WriteDSPCommand(cmd, board))
+		if (ixj_WriteDSPCommand(cmd, j))
 			return -1;
 	}
 	if (!j->read_buffer) {
 		if (!j->read_buffer)
 			j->read_buffer = kmalloc(j->rec_frame_size * 2, GFP_ATOMIC);
 		if (!j->read_buffer) {
-			printk("Read buffer allocation for ixj board %d failed!\n", board);
+			printk("Read buffer allocation for ixj board %d failed!\n",
+			       j->p.board);
 			return -ENOMEM;
 		}
 	}
 	j->read_buffer_size = j->rec_frame_size * 2;
 
-	if (ixj_WriteDSPCommand(0x5102, board))		// Set Poll sync mode
+	if (ixj_WriteDSPCommand(0x5102, j))		// Set Poll sync mode
 
 		return -1;
 
@@ -2889,149 +2889,140 @@
 		}
 		break;
 	}
-	if (ixj_WriteDSPCommand(cmd, board))
+	if (ixj_WriteDSPCommand(cmd, j))
 		return -1;
 
 	return 0;
 }
 
-static void ixj_record_stop(int board)
+static void ixj_record_stop(IXJ *j)
 {
-	IXJ *j = &ixj[board];
-
 	if (j->read_buffer) {
 		kfree(j->read_buffer);
 		j->read_buffer = NULL;
 		j->read_buffer_size = 0;
 	}
 	if (j->rec_mode > -1) {
-		ixj_WriteDSPCommand(0x5120, board);
+		ixj_WriteDSPCommand(0x5120, j);
 		j->rec_mode = -1;
 	}
 	j->flags.recording = 0;
 	if (!j->flags.playing)
-		ixj_WriteDSPCommand(0x0FE3, board);	// Put the DSP in 1/5 power mode.
+		ixj_WriteDSPCommand(0x0FE3, j);	// Put the DSP in 1/5 power mode.
 
 }
-static void ixj_vad(int board, int arg)
+static void ixj_vad(IXJ *j, int arg)
 {
 	if (arg)
-		ixj_WriteDSPCommand(0x513F, board);
+		ixj_WriteDSPCommand(0x513F, j);
 	else
-		ixj_WriteDSPCommand(0x513E, board);
+		ixj_WriteDSPCommand(0x513E, j);
 }
 
-static void set_rec_depth(int board, int depth)
+static void set_rec_depth(IXJ *j, int depth)
 {
 	if (depth > 60)
 		depth = 60;
 	if (depth < 0)
 		depth = 0;
-	ixj_WriteDSPCommand(0x5180 + depth, board);
+	ixj_WriteDSPCommand(0x5180 + depth, j);
 }
 
-static void set_rec_volume(int board, int volume)
+static void set_rec_volume(IXJ *j, int volume)
 {
-	ixj_WriteDSPCommand(0xCF03, board);
-	ixj_WriteDSPCommand(volume, board);
+	ixj_WriteDSPCommand(0xCF03, j);
+	ixj_WriteDSPCommand(volume, j);
 }
 
-static int get_rec_volume(int board)
+static int get_rec_volume(IXJ *j)
 {
-	ixj_WriteDSPCommand(0xCF03, board);
-	return ixj[board].ssr.high << 8 | ixj[board].ssr.low;
+	ixj_WriteDSPCommand(0xCF01, j);
+	return j->ssr.high << 8 | j->ssr.low;
 }
 
-static int get_rec_level(int board)
+static int get_rec_level(IXJ *j)
 {
 	int retval;
 
-	IXJ *j = &ixj[board];
-
-	ixj_WriteDSPCommand(0xCF88, board);
+	ixj_WriteDSPCommand(0xCF88, j);
 
 	retval = j->ssr.high << 8 | j->ssr.low;
 	retval = (retval * 256) / 240;
 	return retval;
 }
 
-static void ixj_aec_start(int board, int level)
+static void ixj_aec_start(IXJ *j, int level)
 {
-	IXJ *j = &ixj[board];
-
 	j->aec_level = level;
 	if (!level) {
-		aec_stop(board);
+		aec_stop(j);
 	} else {
 		if (j->rec_codec == G729 || j->play_codec == G729) {
-			ixj_WriteDSPCommand(0xE022, board);	// Move AEC filter buffer
+			ixj_WriteDSPCommand(0xE022, j);	// Move AEC filter buffer
 
-			ixj_WriteDSPCommand(0x0300, board);
+			ixj_WriteDSPCommand(0x0300, j);
 		}
-		ixj_WriteDSPCommand(0xB001, board);	// AEC On
+		ixj_WriteDSPCommand(0xB001, j);	// AEC On
 
-		ixj_WriteDSPCommand(0xE013, board);	// Advanced AEC C1
+		ixj_WriteDSPCommand(0xE013, j);	// Advanced AEC C1
 
 		switch (level) {
 		case AEC_LOW:
-			ixj_WriteDSPCommand(0x0000, board);	// Advanced AEC C2 = off
+			ixj_WriteDSPCommand(0x0000, j);	// Advanced AEC C2 = off
 
-			ixj_WriteDSPCommand(0xE011, board);
-			ixj_WriteDSPCommand(0xFFFF, board);
+			ixj_WriteDSPCommand(0xE011, j);
+			ixj_WriteDSPCommand(0xFFFF, j);
 			break;
 
 		case AEC_MED:
-			ixj_WriteDSPCommand(0x0600, board);	// Advanced AEC C2 = on medium
+			ixj_WriteDSPCommand(0x0600, j);	// Advanced AEC C2 = on medium
 
-			ixj_WriteDSPCommand(0xE011, board);
-			ixj_WriteDSPCommand(0x0080, board);
+			ixj_WriteDSPCommand(0xE011, j);
+			ixj_WriteDSPCommand(0x0080, j);
 			break;
 
 		case AEC_HIGH:
-			ixj_WriteDSPCommand(0x0C00, board);	// Advanced AEC C2 = on high
+			ixj_WriteDSPCommand(0x0C00, j);	// Advanced AEC C2 = on high
 
-			ixj_WriteDSPCommand(0xE011, board);
-			ixj_WriteDSPCommand(0x0080, board);
+			ixj_WriteDSPCommand(0xE011, j);
+			ixj_WriteDSPCommand(0x0080, j);
 			break;
 
 		case AEC_AUTO:
-			ixj_WriteDSPCommand(0x0002, board);	// Attenuation scaling factor of 2
+			ixj_WriteDSPCommand(0x0002, j);	// Attenuation scaling factor of 2
 
-			ixj_WriteDSPCommand(0xE011, board);
-			ixj_WriteDSPCommand(0x0100, board);	// Higher Threshold Floor
+			ixj_WriteDSPCommand(0xE011, j);
+			ixj_WriteDSPCommand(0x0100, j);	// Higher Threshold Floor
 
-			ixj_WriteDSPCommand(0xE012, board);	// Set Train and Lock
+			ixj_WriteDSPCommand(0xE012, j);	// Set Train and Lock
 
-			ixj_WriteDSPCommand(0x0023, board);
+			ixj_WriteDSPCommand(0x0023, j);
 
-			ixj_WriteDSPCommand(0xE014, board);
-			ixj_WriteDSPCommand(0x0003, board);	// Lock threashold at 3dB
+			ixj_WriteDSPCommand(0xE014, j);
+			ixj_WriteDSPCommand(0x0003, j);	// Lock threashold at 3dB
 
 			break;
 		}
 	}
 }
 
-static void aec_stop(int board)
+static void aec_stop(IXJ *j)
 {
-	IXJ *j = &ixj[board];
-
 	if (j->rec_codec == G729 || j->play_codec == G729) {
-		ixj_WriteDSPCommand(0xE022, board);	// Move AEC filter buffer back
+		ixj_WriteDSPCommand(0xE022, j);	// Move AEC filter buffer back
 
-		ixj_WriteDSPCommand(0x0700, board);
+		ixj_WriteDSPCommand(0x0700, j);
 	}
-	if (ixj[board].play_mode != -1 && ixj[board].rec_mode != -1)
+	if (j->play_mode != -1 && j->rec_mode != -1)
 	{
-		ixj_WriteDSPCommand(0xB002, board);	// AEC Stop
+		ixj_WriteDSPCommand(0xB002, j);	// AEC Stop
 
 	}
 }
 
-static int set_play_codec(int board, int rate)
+static int set_play_codec(IXJ *j, int rate)
 {
 	int retval = 0;
-	IXJ *j = &ixj[board];
 
 	j->play_codec = rate;
 
@@ -3190,16 +3181,15 @@
 	return retval;
 }
 
-static int ixj_play_start(int board)
+static int ixj_play_start(IXJ *j)
 {
 	unsigned short cmd = 0x0000;
-	IXJ *j = &ixj[board];
 
 	if (j->write_buffer) {
-		ixj_play_stop(board);
+		ixj_play_stop(j);
 	}
 	j->flags.playing = 1;
-	ixj_WriteDSPCommand(0x0FE0, board);	// Put the DSP in full power mode.
+	ixj_WriteDSPCommand(0x0FE0, j);	// Put the DSP in full power mode.
 
 	j->flags.play_first_frame = 1;
 	j->drybuffer = 0;
@@ -3233,12 +3223,13 @@
 		default:
 			return 1;
 		}
-		if (ixj_WriteDSPCommand(cmd, board))
+		if (ixj_WriteDSPCommand(cmd, j))
 			return -1;
 	}
 	j->write_buffer = kmalloc(j->play_frame_size * 2, GFP_ATOMIC);
 	if (!j->write_buffer) {
-		printk("Write buffer allocation for ixj board %d failed!\n", board);
+		printk("Write buffer allocation for ixj board %d failed!\n",
+		       j->p.board);
 		return -ENOMEM;
 	}
 	j->write_buffers_empty = 2;
@@ -3246,7 +3237,7 @@
 	j->write_buffer_end = j->write_buffer + j->play_frame_size * 2;
 	j->write_buffer_rp = j->write_buffer_wp = j->write_buffer;
 
-	if (ixj_WriteDSPCommand(0x5202, board))		// Set Poll sync mode
+	if (ixj_WriteDSPCommand(0x5202, j))		// Set Poll sync mode
 
 		return -1;
 
@@ -3283,56 +3274,47 @@
 		}
 		break;
 	}
-	if (ixj_WriteDSPCommand(cmd, board))
+	if (ixj_WriteDSPCommand(cmd, j))
 		return -1;
 
-	if (ixj_WriteDSPCommand(0x2000, board))		// Playback C2
+	if (ixj_WriteDSPCommand(0x2000, j))		// Playback C2
 
 		return -1;
 
-	if (ixj_WriteDSPCommand(0x2000 + ixj[board].play_frame_size, board))	// Playback C3
+	if (ixj_WriteDSPCommand(0x2000 + j->play_frame_size, j))	// Playback C3
 
 		return -1;
 
+
+	ixj_kill_fasync(j, POLL_OUT);
 	return 0;
 }
 
-static void ixj_play_stop(int board)
+static void ixj_play_stop(IXJ *j)
 {
-	IXJ *j = &ixj[board];
-
 	if (j->write_buffer) {
 		kfree(j->write_buffer);
 		j->write_buffer = NULL;
 		j->write_buffer_size = 0;
 	}
 	if (j->play_mode > -1) {
-		ixj_WriteDSPCommand(0x5221, board);	// Stop playback and flush buffers.  8022 reference page 9-40
+		ixj_WriteDSPCommand(0x5221, j);	// Stop playback and flush buffers.  8022 reference page 9-40
 
 		j->play_mode = -1;
 	}
 	j->flags.playing = 0;
 	if (!j->flags.recording)
-		ixj_WriteDSPCommand(0x0FE3, board);	// Put the DSP in 1/5 power mode.
+		ixj_WriteDSPCommand(0x0FE3, j);	// Put the DSP in 1/5 power mode.
 
 }
 
-extern __inline__ void set_play_depth(int board, int depth)
-{
-	if (depth > 60)
-		depth = 60;
-	if (depth < 0)
-		depth = 0;
-	ixj_WriteDSPCommand(0x5280 + depth, board);
-}
-
-extern __inline__ int get_play_level(int board)
+extern __inline__ int get_play_level(IXJ *j)
 {
 	int retval;
 
-	ixj_WriteDSPCommand(0xCF8F, board); // 8022 Reference page 9-38
-	return ixj[board].ssr.high << 8 | ixj[board].ssr.low;
-	retval = ixj[board].ssr.high << 8 | ixj[board].ssr.low;
+	ixj_WriteDSPCommand(0xCF8F, j); // 8022 Reference page 9-38
+	return j->ssr.high << 8 | j->ssr.low;
+	retval = j->ssr.high << 8 | j->ssr.low;
 	retval = (retval * 256) / 240;
 	return retval;
 }
@@ -3340,7 +3322,10 @@
 static unsigned int ixj_poll(struct file *file_p, poll_table * wait)
 {
 	unsigned int mask = 0;
-	IXJ *j = &ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
+	IXJ *j = ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
+
+	if (j == NULL) /* shouldn't happen! */
+		return -ENODEV;
 
 	poll_wait(file_p, &(j->poll_q), wait);
 	if (j->read_buffer_ready > 0)
@@ -3352,15 +3337,13 @@
 	return mask;
 }
 
-static int ixj_play_tone(int board, char tone)
+static int ixj_play_tone(IXJ *j, char tone)
 {
-	IXJ *j = &ixj[board];
-
-	if (!j->tone_state)
-		idle(board);
+	if (!j->tone_state && j->dsp.low == 0x20)
+		idle(j);
 
 	j->tone_index = tone;
-	if (ixj_WriteDSPCommand(0x6000 + j->tone_index, board))
+	if (ixj_WriteDSPCommand(0x6000 + j->tone_index, j))
 		return -1;
 
 	if (!j->tone_state) {
@@ -3371,26 +3354,23 @@
 	return 0;
 }
 
-static int ixj_set_tone_on(unsigned short arg, int board)
+static int ixj_set_tone_on(unsigned short arg, IXJ *j)
 {
-	IXJ *j = &ixj[board];
-
 	j->tone_on_time = arg;
 
-	if (ixj_WriteDSPCommand(0x6E04, board))		// Set Tone On Period
+	if (ixj_WriteDSPCommand(0x6E04, j))		// Set Tone On Period
 
 		return -1;
 
-	if (ixj_WriteDSPCommand(arg, board))
+	if (ixj_WriteDSPCommand(arg, j))
 		return -1;
 
 	return 0;
 }
 
-static int SCI_WaitHighSCI(int board)
+static int SCI_WaitHighSCI(IXJ *j)
 {
 	int cnt;
-	IXJ *j = &ixj[board];
 
 	j->pld_scrr.byte = inb_p(j->XILINXbase);
 	if (!j->pld_scrr.bits.sci) {
@@ -3408,10 +3388,9 @@
 		return 1;
 }
 
-static int SCI_WaitLowSCI(int board)
+static int SCI_WaitLowSCI(IXJ *j)
 {
 	int cnt;
-	IXJ *j = &ixj[board];
 
 	j->pld_scrr.byte = inb_p(j->XILINXbase);
 	if (j->pld_scrr.bits.sci) {
@@ -3429,10 +3408,8 @@
 		return 1;
 }
 
-static int SCI_Control(int board, int control)
+static int SCI_Control(IXJ *j, int control)
 {
-	IXJ *j = &ixj[board];
-
 	switch (control) {
 	case SCI_End:
 		j->pld_scrw.bits.c0 = 0;	// Set PLD Serial control interface
@@ -3471,7 +3448,7 @@
 	case SCI_Enable_DAA:
 	case SCI_Enable_Mixer:
 	case SCI_Enable_EEPROM:
-		if (!SCI_WaitHighSCI(board))
+		if (!SCI_WaitHighSCI(j))
 			return 0;
 		break;
 	default:
@@ -3481,21 +3458,20 @@
 	return 1;
 }
 
-static int SCI_Prepare(int board)
+static int SCI_Prepare(IXJ *j)
 {
-	if (!SCI_Control(board, SCI_End))
+	if (!SCI_Control(j, SCI_End))
 		return 0;
 
-	if (!SCI_WaitLowSCI(board))
+	if (!SCI_WaitLowSCI(j))
 		return 0;
 
 	return 1;
 }
 
-static int ixj_mixer(long val, int board)
+static int ixj_mixer(long val, IXJ *j)
 {
 	BYTES bytes;
-	IXJ *j = &ixj[board];
 
 	bytes.high = (val & 0xFF00) >> 8;
 	bytes.low = val & 0x00FF;
@@ -3504,28 +3480,25 @@
 
 	outb_p(bytes.low, j->XILINXbase + 0x02);	// Load Mixer Data
 
-	SCI_Control(board, SCI_Enable_Mixer);
+	SCI_Control(j, SCI_Enable_Mixer);
 
-	SCI_Control(board, SCI_End);
+	SCI_Control(j, SCI_End);
 
 	return 0;
 }
 
-static int daa_load(BYTES * p_bytes, int board)
+static int daa_load(BYTES * p_bytes, IXJ *j)
 {
-	IXJ *j = &ixj[board];
-
 	outb_p(p_bytes->high, j->XILINXbase + 0x03);
 	outb_p(p_bytes->low, j->XILINXbase + 0x02);
-	if (!SCI_Control(board, SCI_Enable_DAA))
+	if (!SCI_Control(j, SCI_Enable_DAA))
 		return 0;
 	else
 		return 1;
 }
 
-static int ixj_daa_cr4(int board, char reg)
+static int ixj_daa_cr4(IXJ *j, char reg)
 {
-	IXJ *j = &ixj[board];
 	BYTES bytes;
 
 	switch (j->daa_mode) {
@@ -3562,21 +3535,20 @@
 
 	bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg;
 
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
-	if (!SCI_Prepare(board))
+	if (!SCI_Prepare(j))
 		return 0;
 
 	return 1;
 }
 
-static char daa_int_read(int board)
+static char daa_int_read(IXJ *j)
 {
 	BYTES bytes;
-	IXJ *j = &ixj[board];
 
-	if (!SCI_Prepare(board))
+	if (!SCI_Prepare(j))
 		return 0;
 
 	bytes.high = 0x38;
@@ -3584,7 +3556,7 @@
 	outb_p(bytes.high, j->XILINXbase + 0x03);
 	outb_p(bytes.low, j->XILINXbase + 0x02);
 
-	if (!SCI_Control(board, SCI_Enable_DAA))
+	if (!SCI_Control(j, SCI_Enable_DAA))
 		return 0;
 
 	bytes.high = inb_p(j->XILINXbase + 0x03);
@@ -3594,9 +3566,9 @@
 			printk("Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
 		return 0;
 	}
-	if (!SCI_Control(board, SCI_Enable_DAA))
+	if (!SCI_Control(j, SCI_Enable_DAA))
 		return 0;
-	if (!SCI_Control(board, SCI_End))
+	if (!SCI_Control(j, SCI_End))
 		return 0;
 
 	bytes.high = inb_p(j->XILINXbase + 0x03);
@@ -3606,13 +3578,12 @@
 	return 1;
 }
 
-static int ixj_daa_cid_reset(int board)
+static int ixj_daa_cid_reset(IXJ *j)
 {
 	int i;
 	BYTES bytes;
-	IXJ *j = &ixj[board];
 
-	if (!SCI_Prepare(board))
+	if (!SCI_Prepare(j))
 		return 0;
 
 	bytes.high = 0x58;
@@ -3620,10 +3591,10 @@
 	outb_p(bytes.high, j->XILINXbase + 0x03);
 	outb_p(bytes.low, j->XILINXbase + 0x02);
 
-	if (!SCI_Control(board, SCI_Enable_DAA))
+	if (!SCI_Control(j, SCI_Enable_DAA))
 		return 0;
 
-	if (!SCI_WaitHighSCI(board))
+	if (!SCI_WaitHighSCI(j))
 		return 0;
 
 	for (i = 0; i < ALISDAA_CALLERID_SIZE - 1; i += 2) {
@@ -3633,29 +3604,28 @@
 		if (i < ALISDAA_CALLERID_SIZE - 1)
 			outb_p(bytes.low, j->XILINXbase + 0x02);
 
-		if (!SCI_Control(board, SCI_Enable_DAA))
+		if (!SCI_Control(j, SCI_Enable_DAA))
 			return 0;
 
-		if (!SCI_WaitHighSCI(board))
+		if (!SCI_WaitHighSCI(j))
 			return 0;
 
 	}
 
-	if (!SCI_Control(board, SCI_End))
+	if (!SCI_Control(j, SCI_End))
 		return 0;
 
 	return 1;
 }
 
-static int ixj_daa_cid_read(int board)
+static int ixj_daa_cid_read(IXJ *j)
 {
 	int i;
 	BYTES bytes;
 	char CID[ALISDAA_CALLERID_SIZE], mContinue;
 	char *pIn, *pOut;
-	IXJ *j = &ixj[board];
 
-	if (!SCI_Prepare(board))
+	if (!SCI_Prepare(j))
 		return 0;
 
 	bytes.high = 0x78;
@@ -3663,10 +3633,10 @@
 	outb_p(bytes.high, j->XILINXbase + 0x03);
 	outb_p(bytes.low, j->XILINXbase + 0x02);
 
-	if (!SCI_Control(board, SCI_Enable_DAA))
+	if (!SCI_Control(j, SCI_Enable_DAA))
 		return 0;
 
-	if (!SCI_WaitHighSCI(board))
+	if (!SCI_WaitHighSCI(j))
 		return 0;
 
 	bytes.high = inb_p(j->XILINXbase + 0x03);
@@ -3681,17 +3651,17 @@
 		outb_p(bytes.high, j->XILINXbase + 0x03);
 		outb_p(bytes.low, j->XILINXbase + 0x02);
 
-		if (!SCI_Control(board, SCI_Enable_DAA))
+		if (!SCI_Control(j, SCI_Enable_DAA))
 			return 0;
 
-		if (!SCI_WaitHighSCI(board))
+		if (!SCI_WaitHighSCI(j))
 			return 0;
 
 		CID[i + 0] = inb_p(j->XILINXbase + 0x03);
 		CID[i + 1] = inb_p(j->XILINXbase + 0x02);
 	}
 
-	if (!SCI_Control(board, SCI_End))
+	if (!SCI_Control(j, SCI_End))
 		return 0;
 
 	pIn = CID;
@@ -3733,16 +3703,15 @@
 	pOut += 1;
 	strncpy(j->cid.name, pOut, j->cid.namelen);
 
-	ixj_daa_cid_reset(board);
+	ixj_daa_cid_reset(j);
 	return 1;
 }
 
-static char daa_get_version(int board)
+static char daa_get_version(IXJ *j)
 {
 	BYTES bytes;
-	IXJ *j = &ixj[board];
 
-	if (!SCI_Prepare(board))
+	if (!SCI_Prepare(j))
 		return 0;
 
 	bytes.high = 0x35;
@@ -3750,7 +3719,7 @@
 	outb_p(bytes.high, j->XILINXbase + 0x03);
 	outb_p(bytes.low, j->XILINXbase + 0x02);
 
-	if (!SCI_Control(board, SCI_Enable_DAA))
+	if (!SCI_Control(j, SCI_Enable_DAA))
 		return 0;
 
 	bytes.high = inb_p(j->XILINXbase + 0x03);
@@ -3760,10 +3729,10 @@
 			printk("DAA Get Version Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
 		return 0;
 	}
-	if (!SCI_Control(board, SCI_Enable_DAA))
+	if (!SCI_Control(j, SCI_Enable_DAA))
 		return 0;
 
-	if (!SCI_Control(board, SCI_End))
+	if (!SCI_Control(j, SCI_End))
 		return 0;
 
 	bytes.high = inb_p(j->XILINXbase + 0x03);
@@ -3774,7 +3743,7 @@
 	return bytes.high;
 }
 
-static int daa_set_mode(int board, int mode)
+static int daa_set_mode(IXJ *j, int mode)
 {
 	// NOTE:
 	//      The DAA *MUST* be in the conversation mode if the
@@ -3791,9 +3760,8 @@
 	//
 
 	BYTES bytes;
-	IXJ *j = &ixj[board];
 
-	if (!SCI_Prepare(board))
+	if (!SCI_Prepare(j))
 		return 0;
 
 	switch (mode) {
@@ -3807,8 +3775,8 @@
 			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
 			bytes.high = 0x10;
 			bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
-			daa_load(&bytes, board);
-			if (!SCI_Prepare(board))
+			daa_load(&bytes, j);
+			if (!SCI_Prepare(j))
 				return 0;
 		}
 		j->pld_scrw.bits.daafsyncen = 0;	// Turn off DAA Frame Sync
@@ -3818,8 +3786,8 @@
 		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
 		bytes.high = 0x10;
 		bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
-		daa_load(&bytes, board);
-		if (!SCI_Prepare(board))
+		daa_load(&bytes, j);
+		if (!SCI_Prepare(j))
 			return 0;
 
 		j->daa_mode = SOP_PU_SLEEP;
@@ -3838,19 +3806,21 @@
 		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
 		bytes.high = 0x50;
 		bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
-		daa_load(&bytes, board);
-		if (!SCI_Prepare(board))
+		daa_load(&bytes, j);
+		if (!SCI_Prepare(j))
 			return 0;
 		j->daa_mode = SOP_PU_RINGING;
 		break;
 	case SOP_PU_CONVERSATION:
 		bytes.high = 0x90;
 		bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
-		daa_load(&bytes, board);
-		if (!SCI_Prepare(board))
+		daa_load(&bytes, j);
+		if (!SCI_Prepare(j))
 			return 0;
 		j->pld_slicw.bits.rly2 = 1;
 		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+		j->pld_scrw.bits.led1 = 0;
+		j->pld_scrw.bits.led2 = 1;
 		j->pld_scrw.bits.daafsyncen = 1;	// Turn on DAA Frame Sync
 
 		outb_p(j->pld_scrw.byte, j->XILINXbase);
@@ -3866,8 +3836,8 @@
 		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
 		bytes.high = 0xD0;
 		bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
-		daa_load(&bytes, board);
-		if (!SCI_Prepare(board))
+		daa_load(&bytes, j);
+		if (!SCI_Prepare(j))
 			return 0;
 		j->daa_mode = SOP_PU_PULSEDIALING;
 		break;
@@ -3877,555 +3847,552 @@
 	return 1;
 }
 
-static int ixj_daa_write(int board)
+static int ixj_daa_write(IXJ *j)
 {
 	BYTES bytes;
-	IXJ *j = &ixj[board];
 
-	if (!SCI_Prepare(board))
+	if (!SCI_Prepare(j))
 		return 0;
 
 	bytes.high = 0x14;
 	bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg;
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg;
 	bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg;
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg;
 	bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
-	if (!SCI_Prepare(board))
+	if (!SCI_Prepare(j))
 		return 0;
 
 	bytes.high = 0x1F;
 	bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg;
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.XOP_xr6_W.reg;
 	bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg;
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg;
 	bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg;
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg;
 	bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg;
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.XOP_xr0_W.reg;
 	bytes.low = 0x00;
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
-	if (!SCI_Prepare(board))
+	if (!SCI_Prepare(j))
 		return 0;
 
 	bytes.high = 0x00;
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0];
 	bytes.low = 0x00;
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
-	if (!SCI_Control(board, SCI_End))
+	if (!SCI_Control(j, SCI_End))
 		return 0;
-	if (!SCI_WaitLowSCI(board))
+	if (!SCI_WaitLowSCI(j))
 		return 0;
 
 	bytes.high = 0x01;
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0];
 	bytes.low = 0x00;
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
-	if (!SCI_Control(board, SCI_End))
+	if (!SCI_Control(j, SCI_End))
 		return 0;
-	if (!SCI_WaitLowSCI(board))
+	if (!SCI_WaitLowSCI(j))
 		return 0;
 
 	bytes.high = 0x02;
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0];
 	bytes.low = 0x00;
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
-	if (!SCI_Control(board, SCI_End))
+	if (!SCI_Control(j, SCI_End))
 		return 0;
-	if (!SCI_WaitLowSCI(board))
+	if (!SCI_WaitLowSCI(j))
 		return 0;
 
 	bytes.high = 0x03;
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0];
 	bytes.low = 0x00;
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
-	if (!SCI_Control(board, SCI_End))
+	if (!SCI_Control(j, SCI_End))
 		return 0;
-	if (!SCI_WaitLowSCI(board))
+	if (!SCI_WaitLowSCI(j))
 		return 0;
 
 	bytes.high = 0x04;
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0];
 	bytes.low = 0x00;
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
-	if (!SCI_Control(board, SCI_End))
+	if (!SCI_Control(j, SCI_End))
 		return 0;
-	if (!SCI_WaitLowSCI(board))
+	if (!SCI_WaitLowSCI(j))
 		return 0;
 
 	bytes.high = 0x05;
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0];
 	bytes.low = 0x00;
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
-	if (!SCI_Control(board, SCI_End))
+	if (!SCI_Control(j, SCI_End))
 		return 0;
-	if (!SCI_WaitLowSCI(board))
+	if (!SCI_WaitLowSCI(j))
 		return 0;
 
 	bytes.high = 0x06;
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0];
 	bytes.low = 0x00;
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
-	if (!SCI_Control(board, SCI_End))
+	if (!SCI_Control(j, SCI_End))
 		return 0;
-	if (!SCI_WaitLowSCI(board))
+	if (!SCI_WaitLowSCI(j))
 		return 0;
 
 	bytes.high = 0x07;
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0];
 	bytes.low = 0x00;
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
-	if (!SCI_Control(board, SCI_End))
+	if (!SCI_Control(j, SCI_End))
 		return 0;
-	if (!SCI_WaitLowSCI(board))
+	if (!SCI_WaitLowSCI(j))
 		return 0;
 
 	bytes.high = 0x08;
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0];
 	bytes.low = 0x00;
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
-	if (!SCI_Control(board, SCI_End))
+	if (!SCI_Control(j, SCI_End))
 		return 0;
-	if (!SCI_WaitLowSCI(board))
+	if (!SCI_WaitLowSCI(j))
 		return 0;
 
 	bytes.high = 0x09;
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0];
 	bytes.low = 0x00;
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
-	if (!SCI_Control(board, SCI_End))
+	if (!SCI_Control(j, SCI_End))
 		return 0;
-	if (!SCI_WaitLowSCI(board))
+	if (!SCI_WaitLowSCI(j))
 		return 0;
 
 	bytes.high = 0x0A;
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0];
 	bytes.low = 0x00;
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
-	if (!SCI_Control(board, SCI_End))
+	if (!SCI_Control(j, SCI_End))
 		return 0;
-	if (!SCI_WaitLowSCI(board))
+	if (!SCI_WaitLowSCI(j))
 		return 0;
 
 	bytes.high = 0x0B;
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0];
 	bytes.low = 0x00;
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
-	if (!SCI_Control(board, SCI_End))
+	if (!SCI_Control(j, SCI_End))
 		return 0;
-	if (!SCI_WaitLowSCI(board))
+	if (!SCI_WaitLowSCI(j))
 		return 0;
 
 	bytes.high = 0x0C;
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0];
 	bytes.low = 0x00;
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
-	if (!SCI_Control(board, SCI_End))
+	if (!SCI_Control(j, SCI_End))
 		return 0;
-	if (!SCI_WaitLowSCI(board))
+	if (!SCI_WaitLowSCI(j))
 		return 0;
 
 	bytes.high = 0x0D;
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0];
 	bytes.low = 0x00;
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
-	if (!SCI_Control(board, SCI_End))
+	if (!SCI_Control(j, SCI_End))
 		return 0;
-	if (!SCI_WaitLowSCI(board))
+	if (!SCI_WaitLowSCI(j))
 		return 0;
 
 	bytes.high = 0x0E;
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0];
 	bytes.low = 0x00;
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
-	if (!SCI_Control(board, SCI_End))
+	if (!SCI_Control(j, SCI_End))
 		return 0;
-	if (!SCI_WaitLowSCI(board))
+	if (!SCI_WaitLowSCI(j))
 		return 0;
 
 	bytes.high = 0x0F;
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2];
 	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1];
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0];
 	bytes.low = 0x00;
-	if (!daa_load(&bytes, board))
+	if (!daa_load(&bytes, j))
 		return 0;
 
 	udelay(32);
 	j->pld_scrr.byte = inb_p(j->XILINXbase);
-	if (!SCI_Control(board, SCI_End))
+	if (!SCI_Control(j, SCI_End))
 		return 0;
 
 	return 1;
 }
 
-int ixj_set_tone_off(unsigned short arg, int board)
+int ixj_set_tone_off(unsigned short arg, IXJ *j)
 {
-	ixj[board].tone_off_time = arg;
-	if (ixj_WriteDSPCommand(0x6E05, board))		// Set Tone Off Period
+	j->tone_off_time = arg;
+	if (ixj_WriteDSPCommand(0x6E05, j))		// Set Tone Off Period
 
 		return -1;
-	if (ixj_WriteDSPCommand(arg, board))
+	if (ixj_WriteDSPCommand(arg, j))
 		return -1;
 	return 0;
 }
 
-static int ixj_get_tone_on(int board)
+static int ixj_get_tone_on(IXJ *j)
 {
-	if (ixj_WriteDSPCommand(0x6E06, board))		// Get Tone On Period
+	if (ixj_WriteDSPCommand(0x6E06, j))		// Get Tone On Period
 
 		return -1;
 	return 0;
 }
 
-static int ixj_get_tone_off(int board)
+static int ixj_get_tone_off(IXJ *j)
 {
-	if (ixj_WriteDSPCommand(0x6E07, board))		// Get Tone Off Period
-
+	if (ixj_WriteDSPCommand(0x6E07, j))		// Get Tone Off Period
 		return -1;
 	return 0;
 }
 
-static void ixj_busytone(int board)
+static void ixj_busytone(IXJ *j)
+{
+	j->flags.ringback = 0;
+	j->flags.dialtone = 0;
+	j->flags.busytone = 1;
+	ixj_set_tone_on(0x07D0, j);
+	ixj_set_tone_off(0x07D0, j);
+	ixj_play_tone(j, 27);
+}
+
+static void ixj_dialtone(IXJ *j)
 {
-	ixj[board].flags.ringback = 0;
-	ixj[board].flags.dialtone = 0;
-	ixj[board].flags.busytone = 1;
-	ixj_set_tone_on(0x07D0, board);
-	ixj_set_tone_off(0x07D0, board);
-	ixj_play_tone(board, 27);
-}
-
-static void ixj_dialtone(int board)
-{
-	ixj[board].flags.ringback = 0;
-	ixj[board].flags.dialtone = 1;
-	ixj[board].flags.busytone = 0;
-	if (ixj[board].dsp.low == 0x20) {
+	j->flags.ringback = 0;
+	j->flags.dialtone = 1;
+	j->flags.busytone = 0;
+	if (j->dsp.low == 0x20) {
 		return;
 	} else {
-		ixj_set_tone_on(0xFFFF, board);
-		ixj_set_tone_off(0x0000, board);
-		ixj_play_tone(board, 25);
+		ixj_set_tone_on(0xFFFF, j);
+		ixj_set_tone_off(0x0000, j);
+		ixj_play_tone(j, 25);
 	}
 }
 
-static void ixj_cpt_stop(board)
+static void ixj_cpt_stop(IXJ *j)
 {
-	IXJ *j = &ixj[board];
 	if(j->tone_state)
 	{
 		j->flags.dialtone = 0;
 		j->flags.busytone = 0;
 		j->flags.ringback = 0;
-		ixj_set_tone_on(0x0001, board);
-		ixj_set_tone_off(0x0000, board);
-		ixj_play_tone(board, 0);
+		ixj_set_tone_on(0x0001, j);
+		ixj_set_tone_off(0x0000, j);
+		ixj_play_tone(j, 0);
 		j->tone_state = 0;
 		if (j->cadence_t) {
 			if (j->cadence_t->ce) {
@@ -4436,34 +4403,34 @@
 		}
 	}
 	if (j->play_mode == -1 && j->rec_mode == -1)
-		idle(board);
-	if (j->play_mode != -1)
-		ixj_play_start(board);
-	if (j->rec_mode != -1)
-		ixj_record_start(board);
+		idle(j);
+	if (j->play_mode != -1 && j->dsp.low == 0x20)
+		ixj_play_start(j);
+	if (j->rec_mode != -1 && j->dsp.low == 0x20)
+		ixj_record_start(j);
 }
 
-static void ixj_ringback(int board)
+static void ixj_ringback(IXJ *j)
 {
-	ixj[board].flags.busytone = 0;
-	ixj[board].flags.dialtone = 0;
-	ixj[board].flags.ringback = 1;
-	ixj_set_tone_on(0x0FA0, board);
-	ixj_set_tone_off(0x2EE0, board);
-	ixj_play_tone(board, 26);
+	j->flags.busytone = 0;
+	j->flags.dialtone = 0;
+	j->flags.ringback = 1;
+	ixj_set_tone_on(0x0FA0, j);
+	ixj_set_tone_off(0x2EE0, j);
+	ixj_play_tone(j, 26);
 }
 
-static void ixj_testram(int board)
+static void ixj_testram(IXJ *j)
 {
-	ixj_WriteDSPCommand(0x3001, board);	/* Test External SRAM */
+	ixj_WriteDSPCommand(0x3001, j);	/* Test External SRAM */
 }
 
-static int ixj_build_cadence(int board, IXJ_CADENCE * cp)
+static int ixj_build_cadence(IXJ *j, IXJ_CADENCE * cp)
 {
 	IXJ_CADENCE *lcp;
 	IXJ_CADENCE_ELEMENT *lcep;
 	IXJ_TONE ti;
-	IXJ *j = &ixj[board];
+
 	lcp = kmalloc(sizeof(IXJ_CADENCE), GFP_KERNEL);
 	if (lcp == NULL)
 		return -ENOMEM;
@@ -4490,30 +4457,30 @@
 	lcp->ce = (void *) lcep;
 	j->cadence_t = lcp;
 	j->tone_cadence_state = 0;
-	ixj_set_tone_on(lcp->ce[0].tone_on_time, board);
-	ixj_set_tone_off(lcp->ce[0].tone_off_time, board);
+	ixj_set_tone_on(lcp->ce[0].tone_on_time, j);
+	ixj_set_tone_off(lcp->ce[0].tone_off_time, j);
 	if (j->cadence_t->ce[j->tone_cadence_state].freq0) {
 		ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index;
 		ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0;
 		ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0;
 		ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1;
 		ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1;
-		ixj_init_tone(board, &ti);
+		ixj_init_tone(j, &ti);
 	}
-	ixj_play_tone(board, lcp->ce[0].index);
+	ixj_play_tone(j, lcp->ce[0].index);
 	return 1;
 }
 
-static int ixj_build_filter_cadence(int board, IXJ_FILTER_CADENCE * cp)
+static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE * cp)
 {
 	IXJ_FILTER_CADENCE *lcp;
-	IXJ *j = &ixj[board];
+
 	lcp = kmalloc(sizeof(IXJ_CADENCE), GFP_KERNEL);
 	if (lcp == NULL)
 		return -ENOMEM;
 	if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_FILTER_CADENCE)))
 		return -EFAULT;
-	if (lcp->filter > 4)
+	if (lcp->filter >= 4)
 		return -1;
 	j->cadence_f[lcp->filter].state = 0;
 	j->cadence_f[lcp->filter].enable = lcp->enable;
@@ -4540,9 +4507,8 @@
 	return 0;
 }
 
-static void add_caps(int board)
+static void add_caps(IXJ *j)
 {
-	IXJ *j = &ixj[board];
 	j->caps = 0;
 	j->caplist[j->caps].cap = PHONE_VENDOR_QUICKNET;
 	strcpy(j->caplist[j->caps].desc, "Quicknet Technologies, Inc. (www.quicknet.net)");
@@ -4550,95 +4516,139 @@
 	j->caplist[j->caps].handle = j->caps++;
 	j->caplist[j->caps].captype = device;
 	switch (j->cardtype) {
-	case 100:
+	case QTI_PHONEJACK:
 		strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneJACK");
-		j->caplist[j->caps].cap = 100;
 		break;
-	case 300:
+	case QTI_LINEJACK:
 		strcpy(j->caplist[j->caps].desc, "Quicknet Internet LineJACK");
-		j->caplist[j->caps].cap = 300;
 		break;
-	case 400:
+	case QTI_PHONEJACK_LITE:
 		strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneJACK Lite");
-		j->caplist[j->caps].cap = 400;
 		break;
-	case 500:
+	case QTI_PHONEJACK_PCI:
 		strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneJACK PCI");
-		j->caplist[j->caps].cap = 500;
+		break;
+	case QTI_PHONECARD:
+		strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneCARD");
 		break;
 	}
+	j->caplist[j->caps].cap = j->cardtype;
 	j->caplist[j->caps].handle = j->caps++;
 	strcpy(j->caplist[j->caps].desc, "POTS");
 	j->caplist[j->caps].captype = port;
 	j->caplist[j->caps].cap = pots;
 	j->caplist[j->caps].handle = j->caps++;
-	switch (ixj[board].cardtype) {
-	case 100:
+
+ 	// add devices that can do speaker/mic
+	switch (j->cardtype) {
+	case QTI_PHONEJACK:
+	case QTI_LINEJACK:
+	case QTI_PHONEJACK_PCI:
+	case QTI_PHONECARD:
 		strcpy(j->caplist[j->caps].desc, "SPEAKER");
 		j->caplist[j->caps].captype = port;
 		j->caplist[j->caps].cap = speaker;
 		j->caplist[j->caps].handle = j->caps++;
+        default:
+     		break;
+	}
+
+ 	// add devices that can do handset
+	switch (j->cardtype) {
+	case QTI_PHONEJACK:
 		strcpy(j->caplist[j->caps].desc, "HANDSET");
 		j->caplist[j->caps].captype = port;
 		j->caplist[j->caps].cap = handset;
 		j->caplist[j->caps].handle = j->caps++;
 		break;
-	case 300:
-		strcpy(j->caplist[j->caps].desc, "SPEAKER");
-		j->caplist[j->caps].captype = port;
-		j->caplist[j->caps].cap = speaker;
-		j->caplist[j->caps].handle = j->caps++;
+        default:
+     		break;
+	}
+
+ 	// add devices that can do PSTN
+	switch (j->cardtype) {
+	case QTI_LINEJACK:
 		strcpy(j->caplist[j->caps].desc, "PSTN");
 		j->caplist[j->caps].captype = port;
 		j->caplist[j->caps].cap = pstn;
 		j->caplist[j->caps].handle = j->caps++;
 		break;
+        default:
+     		break;
 	}
+
+	// add codecs - all cards can do uLaw, linear 8/16, and Windows sound system
 	strcpy(j->caplist[j->caps].desc, "ULAW");
 	j->caplist[j->caps].captype = codec;
 	j->caplist[j->caps].cap = ULAW;
 	j->caplist[j->caps].handle = j->caps++;
+
 	strcpy(j->caplist[j->caps].desc, "LINEAR 16 bit");
 	j->caplist[j->caps].captype = codec;
 	j->caplist[j->caps].cap = LINEAR16;
 	j->caplist[j->caps].handle = j->caps++;
+
 	strcpy(j->caplist[j->caps].desc, "LINEAR 8 bit");
 	j->caplist[j->caps].captype = codec;
 	j->caplist[j->caps].cap = LINEAR8;
 	j->caplist[j->caps].handle = j->caps++;
+
 	strcpy(j->caplist[j->caps].desc, "Windows Sound System");
 	j->caplist[j->caps].captype = codec;
 	j->caplist[j->caps].cap = WSS;
 	j->caplist[j->caps].handle = j->caps++;
-	if (j->ver.low != 0x12) {
+
+	// version 12 of the 8020 does the following codecs in a broken way
+	if (j->dsp.low != 0x20 || j->ver.low != 0x12) {
 		strcpy(j->caplist[j->caps].desc, "G.723.1 6.3Kbps");
 		j->caplist[j->caps].captype = codec;
 		j->caplist[j->caps].cap = G723_63;
 		j->caplist[j->caps].handle = j->caps++;
+
 		strcpy(j->caplist[j->caps].desc, "G.723.1 5.3Kbps");
 		j->caplist[j->caps].captype = codec;
 		j->caplist[j->caps].cap = G723_53;
 		j->caplist[j->caps].handle = j->caps++;
+
 		strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.8Kbps");
 		j->caplist[j->caps].captype = codec;
 		j->caplist[j->caps].cap = TS48;
 		j->caplist[j->caps].handle = j->caps++;
+
 		strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.1Kbps");
 		j->caplist[j->caps].captype = codec;
 		j->caplist[j->caps].cap = TS41;
 		j->caplist[j->caps].handle = j->caps++;
 	}
-	if (j->cardtype == 100) {
+
+	// 8020 chips can do TS8.5 native, and 8021/8022 can load it
+	if (j->dsp.low == 0x20 || j->flags.ts85_loaded) {
 		strcpy(j->caplist[j->caps].desc, "TrueSpeech 8.5Kbps");
 		j->caplist[j->caps].captype = codec;
 		j->caplist[j->caps].cap = TS85;
 		j->caplist[j->caps].handle = j->caps++;
 	}
+
+	// 8021 chips can do G728
+	if (j->dsp.low == 0x21) {
+		strcpy(j->caplist[j->caps].desc, "G.728 16Kbps");
+		j->caplist[j->caps].captype = codec;
+		j->caplist[j->caps].cap = G728;
+		j->caplist[j->caps].handle = j->caps++;
+	}
+
+	// 8021/8022 chips can do G729 if loaded
+	if (j->dsp.low != 0x20 && j->flags.g729_loaded) {
+		strcpy(j->caplist[j->caps].desc, "G.729A/B");
+		j->caplist[j->caps].captype = codec;
+		j->caplist[j->caps].cap = G728;
+		j->caplist[j->caps].handle = j->caps++;
+	}
 }
-static int capabilities_check(int board, struct phone_capability *pcreq)
+
+static int capabilities_check(IXJ *j, struct phone_capability *pcreq)
 {
 	int cnt;
-	IXJ *j = &ixj[board];
 	int retval = 0;
 	for (cnt = 0; cnt < j->caps; cnt++) {
 		if (pcreq->captype == j->caplist[cnt].captype
@@ -4655,13 +4665,18 @@
 	IXJ_TONE ti;
 	IXJ_FILTER jf;
 	unsigned int minor = MINOR(inode->i_rdev);
-	int board = NUM(inode->i_rdev);
-	IXJ *j = &ixj[NUM(inode->i_rdev)];
+	unsigned int board = NUM(inode->i_rdev);
+	IXJ *j = ixj[board];
 	int retval = 0;
+
 	if (ixjdebug > 1)
 		printk(KERN_DEBUG "phone%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);
 	if (minor >= IXJMAX)
 		return -ENODEV;
+
+	if (j == NULL) /* shouldn't happen! */
+		return -ENODEV;
+
 	/*
 	 *    Check ioctls only root can use.
 	 */
@@ -4674,7 +4689,7 @@
 	}
 	switch (cmd) {
 	case IXJCTL_TESTRAM:
-		ixj_testram(board);
+		ixj_testram(j);
 		retval = (j->ssr.high << 8) + j->ssr.low;
 		break;
 	case IXJCTL_CARDTYPE:
@@ -4697,7 +4712,7 @@
 		else {
 			memset(&j->cid_send, 0, sizeof(PHONE_CID));
 		}
-		ixj_write_cidcw(board);
+		ixj_write_cidcw(j);
 		break;
 	/* Binary compatbility */
 	case OLD_PHONE_RING_START:
@@ -4710,14 +4725,14 @@
 		else {
 			memset(&j->cid_send, 0, sizeof(PHONE_CID));
 		}
-		ixj_ring_start(board);
+		ixj_ring_start(j);
 		break;
 	case PHONE_RING_STOP:
 		j->flags.cringing = 0;
-		ixj_ring_off(board);
+		ixj_ring_off(j);
 		break;
 	case PHONE_RING:
-		retval = ixj_ring(board);
+		retval = ixj_ring(j);
 		break;
 	case PHONE_EXCEPTION:
 		retval = j->ex.bytes;
@@ -4740,70 +4755,70 @@
 		retval = j->r_hook;
 		break;
 	case IXJCTL_SET_LED:
-		LED_SetState(arg, board);
+		LED_SetState(arg, j);
 		break;
 	case PHONE_FRAME:
-		retval = set_base_frame(board, arg);
+		retval = set_base_frame(j, arg);
 		break;
 	case PHONE_REC_CODEC:
-		retval = set_rec_codec(board, arg);
+		retval = set_rec_codec(j, arg);
 		break;
 	case PHONE_VAD:
-		ixj_vad(board, arg);
+		ixj_vad(j, arg);
 		break;
 	case PHONE_REC_START:
-		ixj_record_start(board);
+		ixj_record_start(j);
 		break;
 	case PHONE_REC_STOP:
-		ixj_record_stop(board);
+		ixj_record_stop(j);
 		break;
 	case PHONE_REC_DEPTH:
-		set_rec_depth(board, arg);
+		set_rec_depth(j, arg);
 		break;
 	case PHONE_REC_VOLUME:
 		if(arg == -1) {
-			retval = get_rec_volume(board);
+			retval = get_rec_volume(j);
 		}
 		else {
-			set_rec_volume(board, arg);
+			set_rec_volume(j, arg);
 			retval = arg;
 		}
 		break;
 	case PHONE_REC_LEVEL:
-		retval = get_rec_level(board);
+		retval = get_rec_level(j);
 		break;
 	case IXJCTL_AEC_START:
-		ixj_aec_start(board, arg);
+		ixj_aec_start(j, arg);
 		break;
 	case IXJCTL_AEC_STOP:
-		aec_stop(board);
+		aec_stop(j);
 		break;
 	case IXJCTL_AEC_GET_LEVEL:
 		retval = j->aec_level;
 		break;
 	case PHONE_PLAY_CODEC:
-		retval = set_play_codec(board, arg);
+		retval = set_play_codec(j, arg);
 		break;
 	case PHONE_PLAY_START:
-		retval = ixj_play_start(board);
+		retval = ixj_play_start(j);
 		break;
 	case PHONE_PLAY_STOP:
-		ixj_play_stop(board);
+		ixj_play_stop(j);
 		break;
 	case PHONE_PLAY_DEPTH:
-		set_play_depth(board, arg);
+		set_play_depth(j, arg);
 		break;
 	case PHONE_PLAY_VOLUME:
 		if(arg == -1) {
-			retval = get_play_volume(board);
+			retval = get_play_volume(j);
 		}
 		else {
-			set_play_volume(board, arg);
+			set_play_volume(j, arg);
 			retval = arg;
 		}
 		break;
 	case PHONE_PLAY_LEVEL:
-		retval = get_play_level(board);
+		retval = get_play_level(j);
 		break;
 	case IXJCTL_DSP_TYPE:
 		retval = (j->dsp.high << 8) + j->dsp.low;
@@ -4842,20 +4857,20 @@
 		j->maxrings = arg;
 		break;
 	case PHONE_SET_TONE_ON_TIME:
-		ixj_set_tone_on(arg, board);
+		ixj_set_tone_on(arg, j);
 		break;
 	case PHONE_SET_TONE_OFF_TIME:
-		ixj_set_tone_off(arg, board);
+		ixj_set_tone_off(arg, j);
 		break;
 	case PHONE_GET_TONE_ON_TIME:
-		if (ixj_get_tone_on(board)) {
+		if (ixj_get_tone_on(j)) {
 			retval = -1;
 		} else {
 			retval = (j->ssr.high << 8) + j->ssr.low;
 		}
 		break;
 	case PHONE_GET_TONE_OFF_TIME:
-		if (ixj_get_tone_off(board)) {
+		if (ixj_get_tone_off(j)) {
 			retval = -1;
 		} else {
 			retval = (j->ssr.high << 8) + j->ssr.low;
@@ -4863,7 +4878,9 @@
 		break;
 	case PHONE_PLAY_TONE:
 		if (!j->tone_state)
-			ixj_play_tone(board, arg);
+			retval = ixj_play_tone(j, arg);
+		else
+			retval = -1;
 		break;
 	case PHONE_GET_TONE_STATE:
 		retval = j->tone_state;
@@ -4872,7 +4889,7 @@
 		retval = j->ex.bits.dtmf_ready;
 		break;
 	case PHONE_GET_DTMF:
-		if (ixj_hookstate(board)) {
+		if (ixj_hookstate(j)) {
 			if (j->dtmf_rp != j->dtmf_wp) {
 				retval = j->dtmfbuffer[j->dtmf_rp];
 				j->dtmf_rp++;
@@ -4885,7 +4902,7 @@
 		}
 		break;
 	case PHONE_GET_DTMF_ASCII:
-		if (ixj_hookstate(board)) {
+		if (ixj_hookstate(j)) {
 			if (j->dtmf_rp != j->dtmf_wp) {
 				switch (j->dtmfbuffer[j->dtmf_rp]) {
 				case 10:
@@ -4934,16 +4951,16 @@
 		j->flags.dtmf_oob = arg;
 		break;
 	case PHONE_DIALTONE:
-		ixj_dialtone(board);
+		ixj_dialtone(j);
 		break;
 	case PHONE_BUSY:
-		ixj_busytone(board);
+		ixj_busytone(j);
 		break;
 	case PHONE_RINGBACK:
-		ixj_ringback(board);
+		ixj_ringback(j);
 		break;
 	case PHONE_CPT_STOP:
-		ixj_cpt_stop(board);
+		ixj_cpt_stop(j);
 		break;
 	case PHONE_QUERY_CODEC:
 	{
@@ -4972,36 +4989,36 @@
 		return 0;
 	}
 	case IXJCTL_DSP_IDLE:
-		idle(board);
+		idle(j);
 		break;
 	case IXJCTL_MIXER:
-		ixj_mixer(arg, board);
+		ixj_mixer(arg, j);
 		break;
 	case IXJCTL_DAA_COEFF_SET:
 		switch (arg) {
 		case DAA_US:
-			DAA_Coeff_US(board);
-			retval = ixj_daa_write(board);
+			DAA_Coeff_US(j);
+			retval = ixj_daa_write(j);
 			break;
 		case DAA_UK:
-			DAA_Coeff_UK(board);
-			retval = ixj_daa_write(board);
+			DAA_Coeff_UK(j);
+			retval = ixj_daa_write(j);
 			break;
 		case DAA_FRANCE:
-			DAA_Coeff_France(board);
-			retval = ixj_daa_write(board);
+			DAA_Coeff_France(j);
+			retval = ixj_daa_write(j);
 			break;
 		case DAA_GERMANY:
-			DAA_Coeff_Germany(board);
-			retval = ixj_daa_write(board);
+			DAA_Coeff_Germany(j);
+			retval = ixj_daa_write(j);
 			break;
 		case DAA_AUSTRALIA:
-			DAA_Coeff_Australia(board);
-			retval = ixj_daa_write(board);
+			DAA_Coeff_Australia(j);
+			retval = ixj_daa_write(j);
 			break;
 		case DAA_JAPAN:
-			DAA_Coeff_Japan(board);
-			retval = ixj_daa_write(board);
+			DAA_Coeff_Japan(j);
+			retval = ixj_daa_write(j);
 			break;
 		default:
 			retval = 1;
@@ -5010,13 +5027,13 @@
 		j->country = arg;
 		break;
 	case IXJCTL_DAA_AGAIN:
-		ixj_daa_cr4(board, arg | 0x02);
+		ixj_daa_cr4(j, arg | 0x02);
 		break;
 	case IXJCTL_PSTN_LINETEST:
-		retval = ixj_linetest(board);
+		retval = ixj_linetest(j);
 		break;
 	case IXJCTL_VMWI:
-		ixj_write_vmwi(board, arg);
+		ixj_write_vmwi(j, arg);
 		break;
 	case IXJCTL_CID:
 		if (copy_to_user((char *) arg, &j->cid, sizeof(PHONE_CID)))
@@ -5028,12 +5045,12 @@
 		break;
 	case IXJCTL_PORT:
 		if (arg)
-			retval = ixj_set_port(board, arg);
+			retval = ixj_set_port(j, arg);
 		else
 			retval = j->port;
 		break;
 	case IXJCTL_POTS_PSTN:
-		retval = ixj_set_pots(board, arg);
+		retval = ixj_set_pots(j, arg);
 		break;
 	case PHONE_CAPABILITIES:
 		retval = j->caps;
@@ -5043,10 +5060,10 @@
 			 return -EFAULT;
 		break;
 	case PHONE_CAPABILITIES_CHECK:
-		retval = capabilities_check(board, (struct phone_capability *) arg);
+		retval = capabilities_check(j, (struct phone_capability *) arg);
 		break;
 	case PHONE_PSTN_SET_STATE:
-		daa_set_mode(board, arg);
+		daa_set_mode(j, arg);
 		break;
 	case PHONE_PSTN_GET_STATE:
 		retval = j->daa_mode;
@@ -5055,40 +5072,47 @@
 	case IXJCTL_SET_FILTER:
 		if (copy_from_user(&jf, (char *) arg, sizeof(jf)))
 			return -EFAULT;
-		retval = ixj_init_filter(board, &jf);
+		retval = ixj_init_filter(j, &jf);
 		break;
 	case IXJCTL_GET_FILTER_HIST:
 		retval = j->filter_hist[arg];
 		break;
 	case IXJCTL_INIT_TONE:
 		copy_from_user(&ti, (char *) arg, sizeof(ti));
-		retval = ixj_init_tone(board, &ti);
+		retval = ixj_init_tone(j, &ti);
 		break;
 	case IXJCTL_TONE_CADENCE:
-		retval = ixj_build_cadence(board, (IXJ_CADENCE *) arg);
+		retval = ixj_build_cadence(j, (IXJ_CADENCE *) arg);
 		break;
 	case IXJCTL_FILTER_CADENCE:
-		retval = ixj_build_filter_cadence(board, (IXJ_FILTER_CADENCE *) arg);
+		retval = ixj_build_filter_cadence(j, (IXJ_FILTER_CADENCE *) arg);
 		break;
 	case IXJCTL_INTERCOM_STOP:
-		ixj[board].intercom = -1;
-		ixj[arg].intercom = -1;
-		ixj_record_stop(board);
-		ixj_record_stop(arg);
-		ixj_play_stop(board);
-		ixj_play_stop(arg);
-		idle(board);
-		idle(arg);
+		if (arg != j->intercom
+		    || ixj[arg]->intercom != board)
+			return -EINVAL;
+
+		j->intercom = -1;
+		ixj[arg]->intercom = -1;
+		ixj_record_stop(j);
+		ixj_record_stop(ixj[arg]);
+		ixj_play_stop(j);
+		ixj_play_stop(ixj[arg]);
+		idle(j);
+		idle(ixj[arg]);
 		break;
 	case IXJCTL_INTERCOM_START:
-		ixj[board].intercom = arg;
-		ixj[arg].intercom = board;
-		ixj_play_start(arg);
-		ixj_record_start(board);
-		ixj_play_start(board);
-		ixj_record_start(arg);
-		idle(board);
-		idle(arg);
+		if (ixj[arg] == NULL)
+			return -ENODEV;
+
+		j->intercom = arg;
+		ixj[arg]->intercom = board;
+		ixj_play_start(ixj[arg]);
+		ixj_record_start(j);
+		ixj_play_start(j);
+		ixj_record_start(ixj[arg]);
+		idle(j);
+		idle(ixj[arg]);
 		break;
 	}
 	return retval;
@@ -5096,7 +5120,11 @@
 
 static int ixj_fasync(int fd, struct file *file_p, int mode)
 {
-	IXJ *j = &ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
+	IXJ *j = ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
+
+	if (j == NULL) /* shouldn't happen! */
+		return -ENODEV;
+
 	return fasync_helper(fd, file_p, mode, &j->async_queue);
 }
 
@@ -5111,16 +5139,15 @@
 	fasync:		ixj_fasync
 };
 
-static int ixj_linetest(int board)
+static int ixj_linetest(IXJ *j)
 {
 	unsigned long jifwait;
-	IXJ *j = &ixj[board];
 
 	j->flags.incheck = 1;	// Testing
 	if (!j->flags.pots_correct) {
 		j->flags.pots_correct = 1;
 
-		daa_int_read(board);	//Clear DAA Interrupt flags
+		daa_int_read(j);	//Clear DAA Interrupt flags
 		//
 		// Hold all relays in the normally de-energized position.
 		//
@@ -5136,7 +5163,7 @@
 		if (j->pld_slicr.bits.potspstn) {
 			j->flags.pots_pstn = 1;
 			j->flags.pots_correct = 0;
-			LED_SetState(0x4, board);
+			LED_SetState(0x4, j);
 		} else {
 			j->flags.pots_pstn = 0;
 			j->pld_slicw.bits.rly1 = 0;
@@ -5146,23 +5173,23 @@
 			j->pld_scrw.bits.daafsyncen = 0;	// Turn off DAA Frame Sync
 
 			outb_p(j->pld_scrw.byte, j->XILINXbase);
-			daa_set_mode(board, SOP_PU_CONVERSATION);
+			daa_set_mode(j, SOP_PU_CONVERSATION);
 			jifwait = jiffies + hertz;
 			while (time_before(jiffies, jifwait)) {
 				set_current_state(TASK_INTERRUPTIBLE);
 				schedule_timeout(1);
 			}
-			daa_int_read(board);
-			daa_set_mode(board, SOP_PU_SLEEP);
+			daa_int_read(j);
+			daa_set_mode(j, SOP_PU_SLEEP);
 			if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
 				j->flags.pots_correct = 0;	// Should not be line voltage on POTS port.
 
-				LED_SetState(0x4, board);
+				LED_SetState(0x4, j);
 				j->pld_slicw.bits.rly3 = 0;
 				outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
 			} else {
 				j->flags.pots_correct = 1;
-				LED_SetState(0x8, board);
+				LED_SetState(0x8, j);
 				j->pld_slicw.bits.rly1 = 1;
 				j->pld_slicw.bits.rly2 = 0;
 				j->pld_slicw.bits.rly3 = 0;
@@ -5173,14 +5200,14 @@
 //      if (!j->flags.pstn_present) {
 	j->pld_slicw.bits.rly3 = 0;
 	outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-	daa_set_mode(board, SOP_PU_CONVERSATION);
+	daa_set_mode(j, SOP_PU_CONVERSATION);
 	jifwait = jiffies + hertz;
 	while (time_before(jiffies, jifwait)) {
 		set_current_state(TASK_INTERRUPTIBLE);
 		schedule_timeout(1);
 	}
-	daa_int_read(board);
-	daa_set_mode(board, SOP_PU_SLEEP);
+	daa_int_read(j);
+	daa_set_mode(j, SOP_PU_SLEEP);
 	if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
 		j->flags.pstn_present = 1;
 	} else {
@@ -5189,50 +5216,49 @@
 //      }
 	if (j->flags.pstn_present) {
 		if (j->flags.pots_correct) {
-			LED_SetState(0xA, board);
+			LED_SetState(0xA, j);
 		} else {
-			LED_SetState(0x6, board);
+			LED_SetState(0x6, j);
 		}
 	} else {
 		if (j->flags.pots_correct) {
-			LED_SetState(0x9, board);
+			LED_SetState(0x9, j);
 		} else {
-			LED_SetState(0x5, board);
+			LED_SetState(0x5, j);
 		}
 	}
 	j->flags.incheck = 0;	// Testing
 	return j->flags.pstn_present;
 }
 
-static int ixj_selfprobe(int board)
+static int ixj_selfprobe(IXJ *j, int cnt)
 {
 	unsigned short cmd;
 	unsigned long jif;
-	int cnt;
+	int i;
 	BYTES bytes;
-	IXJ *j = &ixj[board];
 	
 	init_waitqueue_head(&j->poll_q);
 	init_waitqueue_head(&j->read_q);
 	init_waitqueue_head(&j->write_q);
 	if (ixjdebug > 0)
 		printk(KERN_INFO "Write IDLE to Software Control Register\n");
-	ixj_WriteDSPCommand(0x0FE0, board);	// Put the DSP in full power mode.
+	ixj_WriteDSPCommand(0x0FE0, j);	// Put the DSP in full power mode.
 
-	if (ixj_WriteDSPCommand(0x0000, board))		/* Write IDLE to Software Control Register */
+	if (ixj_WriteDSPCommand(0x0000, j))		/* Write IDLE to Software Control Register */
 		return -1;
 // The read values of the SSR should be 0x00 for the IDLE command
 	if (j->ssr.low || j->ssr.high)
 		return -1;
 	if (ixjdebug > 0)
 		printk(KERN_INFO "Get Device ID Code\n");
-	if (ixj_WriteDSPCommand(0x3400, board))		/* Get Device ID Code */
+	if (ixj_WriteDSPCommand(0x3400, j))		/* Get Device ID Code */
 		return -1;
 	j->dsp.low = j->ssr.low;
 	j->dsp.high = j->ssr.high;
 	if (ixjdebug > 0)
 		printk(KERN_INFO "Get Device Version Code\n");
-	if (ixj_WriteDSPCommand(0x3800, board))		/* Get Device Version Code */
+	if (ixj_WriteDSPCommand(0x3800, j))		/* Get Device Version Code */
 		return -1;
 	j->ver.low = j->ssr.low;
 	j->ver.high = j->ssr.high;
@@ -5246,8 +5272,7 @@
 			if (bytes.low == bytes.high)	//  Register is read only on
 				//  Internet PhoneJack Lite
 			 {
-				j->cardtype = 400;	// Internet PhoneJACK Lite
-
+				j->cardtype = QTI_PHONEJACK_LITE;
 				if (check_region(j->XILINXbase, 4)) {
 					printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase);
 					return -1;
@@ -5256,7 +5281,7 @@
 				j->pld_slicw.pcib.e1 = 1;
 				outb_p(j->pld_slicw.byte, j->XILINXbase);
 			} else {
-				j->cardtype = 300;	// Internet LineJACK
+				j->cardtype = QTI_LINEJACK;
 
 				if (check_region(j->XILINXbase, 8)) {
 					printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase);
@@ -5265,38 +5290,32 @@
 				request_region(j->XILINXbase, 8, "ixj control");
 			}
 		} else if (j->dsp.low == 0x22) {
-			j->cardtype = 500;	// Internet PhoneJACK PCI
-
+			j->cardtype = QTI_PHONEJACK_PCI;
 			request_region(j->XILINXbase, 4, "ixj control");
 			j->pld_slicw.pcib.e1 = 1;
 			outb_p(j->pld_slicw.byte, j->XILINXbase);
 		} else
-			j->cardtype = 100;	// Internet PhoneJACK
-
+			j->cardtype = QTI_PHONEJACK;
 	} else {
 		switch (j->cardtype) {
-		case 100:	// Internet PhoneJACK
-
+		case QTI_PHONEJACK:
 			if (!j->dsp.low != 0x20) {
 				j->dsp.high = 0x80;
 				j->dsp.low = 0x20;
-				ixj_WriteDSPCommand(0x3800, board);
+				ixj_WriteDSPCommand(0x3800, j);
 				j->ver.low = j->ssr.low;
 				j->ver.high = j->ssr.high;
 			}
 			break;
-		case 300:	// Internet LineJACK
-
+		case QTI_LINEJACK:
 			if (check_region(j->XILINXbase, 8)) {
 				printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase);
 				return -1;
 			}
 			request_region(j->XILINXbase, 8, "ixj control");
 			break;
-		case 400:	//Internet PhoneJACK Lite
-
-		case 500:	//Internet PhoneJACK PCI
-
+		case QTI_PHONEJACK_LITE:
+		case QTI_PHONEJACK_PCI:
 			if (check_region(j->XILINXbase, 4)) {
 				printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase);
 				return -1;
@@ -5305,36 +5324,37 @@
 			j->pld_slicw.pcib.e1 = 1;
 			outb_p(j->pld_slicw.byte, j->XILINXbase);
 			break;
-		case 600:	//Internet PhoneCARD
-
+		case QTI_PHONECARD:
 			break;
 		}
 	}
-	if (j->dsp.low == 0x20 || j->cardtype == 400 || j->cardtype == 500) {
+	if (j->dsp.low == 0x20
+	    || j->cardtype == QTI_PHONEJACK_LITE
+	    || j->cardtype == QTI_PHONEJACK_PCI) {
 		if (ixjdebug > 0)
 			printk(KERN_INFO "Write CODEC config to Software Control Register\n");
-		if (ixj_WriteDSPCommand(0xC462, board))		/* Write CODEC config to Software Control Register */
+		if (ixj_WriteDSPCommand(0xC462, j))		/* Write CODEC config to Software Control Register */
 			return -1;
 		if (ixjdebug > 0)
 			printk(KERN_INFO "Write CODEC timing to Software Control Register\n");
-		if (j->cardtype == 100) {
+		if (j->cardtype == QTI_PHONEJACK) {
 			cmd = 0x9FF2;
 		} else {
 			cmd = 0x9FF5;
 		}
-		if (ixj_WriteDSPCommand(cmd, board))	/* Write CODEC timing to Software Control Register */
+		if (ixj_WriteDSPCommand(cmd, j))	/* Write CODEC timing to Software Control Register */
 			return -1;
 	} else {
-		if (set_base_frame(board, 30) != 30)
+		if (set_base_frame(j, 30) != 30)
 			return -1;
 		if (ixjdebug > 0)
 			printk(KERN_INFO "Write CODEC config to Software Control Register\n");
-		if (j->cardtype == 600) {
-			if (ixj_WriteDSPCommand(0xC528, board))		/* Write CODEC config to Software Control Register */
+		if (j->cardtype == QTI_PHONECARD) {
+			if (ixj_WriteDSPCommand(0xC528, j))		/* Write CODEC config to Software Control Register */
 				return -1;
 		}
-		if (j->cardtype == 300) {
-			if (ixj_WriteDSPCommand(0xC528, board))		/* Write CODEC config to Software Control Register */
+		if (j->cardtype == QTI_LINEJACK) {
+			if (ixj_WriteDSPCommand(0xC528, j))		/* Write CODEC config to Software Control Register */
 				return -1;
 			if (ixjdebug > 0)
 				printk(KERN_INFO "Turn on the PLD Clock at 8Khz\n");
@@ -5355,7 +5375,7 @@
 		j->gpio.bits.gpio5 = 1;
 		j->gpio.bits.gpio6 = 1;
 		j->gpio.bits.gpio7 = 1;
-		ixj_WriteDSPCommand(ixj[board].gpio.word, board);	/* Set GPIO pin directions */
+		ixj_WriteDSPCommand(j->gpio.word, j);	/* Set GPIO pin directions */
 		if (ixjdebug > 0)
 			printk(KERN_INFO "Enable SLIC\n");
 		j->gpio.bytes.high = 0x0B;
@@ -5363,45 +5383,46 @@
 		j->gpio.bits.gpio1 = 0;
 		j->gpio.bits.gpio2 = 1;
 		j->gpio.bits.gpio5 = 0;
-		ixj_WriteDSPCommand(ixj[board].gpio.word, board);	/* send the ring stop signal */
+		ixj_WriteDSPCommand(j->gpio.word, j);	/* send the ring stop signal */
 		j->port = PORT_POTS;
 	} else {
-		if (j->cardtype == 300) {
-			LED_SetState(0x1, board);
+		if (j->cardtype == QTI_LINEJACK) {
+			LED_SetState(0x1, j);
 			jif = jiffies + (hertz / 10);
 			while (time_before(jiffies, jif)) {
 				set_current_state(TASK_INTERRUPTIBLE);
 				schedule_timeout(1);
 			}
-			LED_SetState(0x2, board);
+			LED_SetState(0x2, j);
 			jif = jiffies + (hertz / 10);
 			while (time_before(jiffies, jif)) {
 				set_current_state(TASK_INTERRUPTIBLE);
 				schedule_timeout(1);
 			}
-			LED_SetState(0x4, board);
+			LED_SetState(0x4, j);
 			jif = jiffies + (hertz / 10);
 			while (time_before(jiffies, jif)) {
 				set_current_state(TASK_INTERRUPTIBLE);
 				schedule_timeout(1);
 			}
-			LED_SetState(0x8, board);
+			LED_SetState(0x8, j);
 			jif = jiffies + (hertz / 10);
 			while (time_before(jiffies, jif)) {
 				set_current_state(TASK_INTERRUPTIBLE);
 				schedule_timeout(1);
 			}
-			LED_SetState(0x0, board);
-			daa_get_version(board);
+			LED_SetState(0x0, j);
+			daa_get_version(j);
 			if (ixjdebug > 0)
 				printk("Loading DAA Coefficients\n");
-			DAA_Coeff_US(board);
-			if (!ixj_daa_write(board))
-				printk("DAA write failed on board %d\n", board);
-			ixj_daa_cid_reset(board);
+			DAA_Coeff_US(j);
+			if (!ixj_daa_write(j))
+				printk("DAA write failed on board %d\n",
+				       j->p.board);
+			ixj_daa_cid_reset(j);
 			j->flags.pots_correct = 0;
 			j->flags.pstn_present = 0;
-			ixj_linetest(board);
+			ixj_linetest(j);
 			if (j->flags.pots_correct) {
 				j->pld_scrw.bits.daafsyncen = 0;	// Turn off DAA Frame Sync
 
@@ -5409,43 +5430,43 @@
 				j->pld_slicw.bits.rly1 = 1;
 				j->pld_slicw.bits.spken = 1;
 				outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-				SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);
+				SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
 				j->port = PORT_POTS;
 			}
-			ixj_set_port(board, PORT_PSTN);
-			ixj_set_pots(board, 1);
+			ixj_set_port(j, PORT_PSTN);
+			ixj_set_pots(j, 1);
 			if (ixjdebug > 0)
 				printk(KERN_INFO "Enable Mixer\n");
-			ixj_mixer(0x0000, board);	//Master Volume Left unmute 0db
+			ixj_mixer(0x0000, j);	//Master Volume Left unmute 0db
 
-			ixj_mixer(0x0100, board);	//Master Volume Right unmute 0db
+			ixj_mixer(0x0100, j);	//Master Volume Right unmute 0db
 
-			ixj_mixer(0x0F00, board);	//Mono Out Volume unmute 0db
+			ixj_mixer(0x0F00, j);	//Mono Out Volume unmute 0db
 
-			ixj_mixer(0x0C00, board);	//Mono1 Volume unmute 0db
+			ixj_mixer(0x0C00, j);	//Mono1 Volume unmute 0db
 
-			ixj_mixer(0x0200, board);	//Voice Left Volume unmute 0db
+			ixj_mixer(0x0200, j);	//Voice Left Volume unmute 0db
 
-			ixj_mixer(0x0300, board);	//Voice Right Volume unmute 0db
+			ixj_mixer(0x0300, j);	//Voice Right Volume unmute 0db
 
-			ixj_mixer(0x110C, board);	//Voice Left and Right out
+			ixj_mixer(0x110C, j);	//Voice Left and Right out
 
-			ixj_mixer(0x1401, board);	//Mono1 switch on mixer left
+			ixj_mixer(0x1401, j);	//Mono1 switch on mixer left
 
-			ixj_mixer(0x1501, board);	//Mono1 switch on mixer right
+			ixj_mixer(0x1501, j);	//Mono1 switch on mixer right
 
-			ixj_mixer(0x1700, board);	//Clock select
+			ixj_mixer(0x1700, j);	//Clock select
 
-			ixj_mixer(0x1800, board);	//ADC Source select
+			ixj_mixer(0x1800, j);	//ADC Source select
 
 		} else {
-			if (j->cardtype == 600) {
-				ixj_WriteDSPCommand(0xCF07, board);
-				ixj_WriteDSPCommand(0x00B0, board);
-				ixj_set_port(board, PORT_SPEAKER);
+			if (j->cardtype == QTI_PHONECARD) {
+				ixj_WriteDSPCommand(0xCF07, j);
+				ixj_WriteDSPCommand(0x00B0, j);
+				ixj_set_port(j, PORT_SPEAKER);
 			} else {
-				ixj_set_port(board, PORT_POTS);
-				SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);
+				ixj_set_port(j, PORT_POTS);
+				SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
 			}
 		}
 	}
@@ -5454,9 +5475,9 @@
 	j->framesread = j->frameswritten = 0;
 	j->read_wait = j->write_wait = 0;
 	j->rxreadycheck = j->txreadycheck = 0;
-	set_play_volume(board, 0x100);
-	set_rec_volume(board, 0x100);
-	if (ixj_WriteDSPCommand(0x0000, board))		/* Write IDLE to Software Control Register */
+	set_play_volume(j, 0x100);
+	set_rec_volume(j, 0x100);
+	if (ixj_WriteDSPCommand(0x0000, j))		/* Write IDLE to Software Control Register */
 		return -1;
 // The read values of the SSR should be 0x00 for the IDLE command
 	if (j->ssr.low || j->ssr.high)
@@ -5465,41 +5486,41 @@
 		printk(KERN_INFO "Enable Line Monitor\n");
 	if (ixjdebug > 0)
 		printk(KERN_INFO "Set Line Monitor to Asyncronous Mode\n");
-	if (ixj_WriteDSPCommand(0x7E01, board))		// Asynchronous Line Monitor
+	if (ixj_WriteDSPCommand(0x7E01, j))		// Asynchronous Line Monitor
 
 		return -1;
 	if (ixjdebug > 0)
 		printk(KERN_INFO "Enable DTMF Detectors\n");
-	if (ixj_WriteDSPCommand(0x5151, board))		// Enable DTMF detection
+	if (ixj_WriteDSPCommand(0x5151, j))		// Enable DTMF detection
 
 		return -1;
-	if (ixj_WriteDSPCommand(0x6E01, board))		// Set Asyncronous Tone Generation
+	if (ixj_WriteDSPCommand(0x6E01, j))		// Set Asyncronous Tone Generation
 
 		return -1;
-	set_rec_depth(board, 2);	// Set Record Channel Limit to 2 frames
+	set_rec_depth(j, 2);	// Set Record Channel Limit to 2 frames
 
-	set_play_depth(board, 2);	// Set Playback Channel Limit to 2 frames
+	set_play_depth(j, 2);	// Set Playback Channel Limit to 2 frames
 
 	j->ex.bits.dtmf_ready = 0;
 	j->dtmf_state = 0;
-	j->dtmf_wp = ixj[board].dtmf_rp = 0;
-	j->rec_mode = ixj[board].play_mode = -1;
+	j->dtmf_wp = j->dtmf_rp = 0;
+	j->rec_mode = j->play_mode = -1;
 	j->flags.ringing = 0;
 	j->maxrings = MAXRINGS;
 	j->ring_cadence = USA_RING_CADENCE;
 	j->drybuffer = 0;
 	j->winktime = 320;
 	j->flags.dtmf_oob = 0;
-	for (cnt = 0; cnt < 4; cnt++)
-		j->cadence_f[cnt].enable = 0;
+	for (i = 0; i < 4; i++)
+		j->cadence_f[i].enable = 0;
 	/* must be a device on the specified address */
-	ixj_WriteDSPCommand(0x0FE3, board);	// Put the DSP in 1/5 power mode.
+	ixj_WriteDSPCommand(0x0FE3, j);	// Put the DSP in 1/5 power mode.
 	/* Register with the Telephony for Linux subsystem */
 	j->p.f_op = &ixj_fops;
 	j->p.open = ixj_open;
-	j->p.board = board;
+	j->p.board = cnt;
 	phone_register_device(&j->p, PHONE_UNIT_ANY);
-	add_caps(board);
+	add_caps(j);
 	return 0;
 }
 
@@ -5513,36 +5534,40 @@
 	len += sprintf(buf + len, "\n%s", ixj_h_rcsid);
 	len += sprintf(buf + len, "\n%s", ixjuser_h_rcsid);
 	for (cnt = 0; cnt < IXJMAX; cnt++) {
-		j = &ixj[cnt];
+		j = ixj[cnt];
+
+		if (j == NULL)
+			continue;
+
 		if (j->DSPbase) {
 			len += sprintf(buf + len, "\nCard Num %d", cnt);
 			len += sprintf(buf + len, "\nDSP Base Address 0x%4.4x", j->DSPbase);
-			if (j->cardtype != 100)
+			if (j->cardtype != QTI_PHONEJACK)
 				len += sprintf(buf + len, "\nXILINX Base Address 0x%4.4x", j->XILINXbase);
 			len += sprintf(buf + len, "\nDSP Type %2.2x%2.2x", j->dsp.high, j->dsp.low);
 			len += sprintf(buf + len, "\nDSP Version %2.2x.%2.2x", j->ver.high, j->ver.low);
 			len += sprintf(buf + len, "\nSerial Number %8.8x", j->serial);
 			switch (j->cardtype) {
-			case (100):
+			case (QTI_PHONEJACK):
 				len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK");
 				break;
-			case (300):
+			case (QTI_LINEJACK):
 				len += sprintf(buf + len, "\nCard Type = Internet LineJACK");
 				if (j->flags.g729_loaded)
 					len += sprintf(buf + len, " w/G.729 A/B");
 				len += sprintf(buf + len, " Country = %d", j->country);
 				break;
-			case (400):
+			case (QTI_PHONEJACK_LITE):
 				len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK Lite");
 				if (j->flags.g729_loaded)
 					len += sprintf(buf + len, " w/G.729 A/B");
 				break;
-			case (500):
+			case (QTI_PHONEJACK_PCI):
 				len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK PCI");
 				if (j->flags.g729_loaded)
 					len += sprintf(buf + len, " w/G.729 A/B");
 				break;
-			case (600):
+			case (QTI_PHONECARD):
 				len += sprintf(buf + len, "\nCard Type = Internet PhoneCARD");
 				if (j->flags.g729_loaded)
 					len += sprintf(buf + len, " w/G.729 A/B");
@@ -5557,7 +5582,8 @@
 			}
 			len += sprintf(buf + len, "\nReaders %d", j->readers);
 			len += sprintf(buf + len, "\nWriters %d", j->writers);
-			len += sprintf(buf + len, "\nFSK words %d", ixj[2].fskdcnt);
+			/* FIXME: This makes no sense! */
+			len += sprintf(buf + len, "\nFSK words %d", ixj[2] ? ixj[2]->fskdcnt : 0);
 			len += sprintf(buf + len, "\nCapabilities %d", j->caps);
 			if (j->dsp.low != 0x20)
 				len += sprintf(buf + len, "\nDSP Processor load %d", j->proc_load);
@@ -5671,7 +5697,7 @@
 			}
 			len += sprintf(buf + len, "\nHook state %d", j->r_hook);	// ixj_hookstate(cnt));
 
-			if (j->cardtype == 300) {
+			if (j->cardtype == QTI_LINEJACK) {
 				len += sprintf(buf + len, "\nPOTS Correct %d", j->flags.pots_correct);
 				len += sprintf(buf + len, "\nPSTN Present %d", j->flags.pstn_present);
 				len += sprintf(buf + len, "\nPOTS to PSTN %d", j->flags.pots_pstn);
@@ -5707,7 +5733,7 @@
 			}
 			if (j->dsp.low == 0x21 || j->dsp.low == 0x22) {
 				len += sprintf(buf + len, "\nSLIC state ");
-				switch (SLIC_GetState(cnt)) {
+				switch (SLIC_GetState(j)) {
 				case PLD_SLIC_STATE_OC:
 					len += sprintf(buf + len, "OC");
 					break;
@@ -5736,7 +5762,7 @@
 					len += sprintf(buf + len, "OHTPR");
 					break;
 				default:
-					len += sprintf(buf + len, "%d", SLIC_GetState(cnt));
+					len += sprintf(buf + len, "%d", SLIC_GetState(j));
 					break;
 				}
 			}
@@ -5756,13 +5782,16 @@
 	}
 	return len;
 }
+
 int ixj_get_status_proc_fsk(char *buf)
 {
 	int len;
 	len = 0;
-	if (ixj[2].fskdcnt) {
-		memcpy(buf, &ixj[2].fskdata, (ixj[2].fskdcnt) * 2);
-		len += ixj[2].fskdcnt * 2;
+
+	/* This makes no sense - why is ixj[2] special? */
+	if (ixj[2] != NULL && ixj[2]->fskdcnt) {
+		memcpy(buf, &ixj[2]->fskdata, (ixj[2]->fskdcnt) * 2);
+		len += ixj[2]->fskdcnt * 2;
 	}
 	return len;
 }
@@ -5793,14 +5822,17 @@
 
 MODULE_DESCRIPTION("Internet Phone/Internet LineJack module - www.quicknet.net");
 MODULE_AUTHOR("Ed Okerson <eokerson@quicknet.net>");
+
 #ifdef CONFIG_PCMCIA
+
 #ifdef PCMCIA_DEBUG
 static int pc_debug = PCMCIA_DEBUG;
 MODULE_PARM(pc_debug, "i");
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
 #else
 #define DEBUG(n, args...)
-#endif
+#endif /* PCMCIA_DEBUG */
+
 typedef struct ixj_info_t {
 	int ndev;
 	dev_node_t node;
@@ -5830,6 +5862,8 @@
 	DEBUG(0, "ixj_attach()\n");
 	/* Create new ixj device */
 	link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+	if (!link)
+		return NULL;
 	memset(link, 0, sizeof(struct dev_link_t));
 	link->release.function = &ixj_cs_release;
 	link->release.data = (u_long) link;
@@ -5839,6 +5873,8 @@
 	link->conf.Vcc = 50;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 	link->priv = kmalloc(sizeof(struct ixj_info_t), GFP_KERNEL);
+	if (!link->priv)
+		return NULL;
 	memset(link->priv, 0, sizeof(struct ixj_info_t));
 	/* Register with Card Services */
 	link->next = dev_list;
@@ -6016,16 +6052,25 @@
 	}
 
 	CS_CHECK(RequestConfiguration, handle, &link->conf);
-	ixj[0].DSPbase = link->io.BasePort1;
-	ixj[0].XILINXbase = link->io.BasePort1 + 0x10;
-	ixj[0].cardtype = 600;
-	ixj_selfprobe(0);
+
+	
+	if ((j = kmalloc(sizeof(*j), GFP_KERNEL)) == NULL)
+		goto cs_failed;
+
+	ixj[0] = j;
+
+	j->DSPbase = link->io.BasePort1;
+	j->XILINXbase = link->io.BasePort1 + 0x10;
+	j->cardtype = QTI_PHONECARD;
+	ixj_selfprobe(j, 0);
+
 	info->ndev = 1;
 	info->node.major = PHONE_MAJOR;
 	link->dev = &info->node;
-	ixj_get_serial(link, &ixj[0]);
+	ixj_get_serial(link, j);
 	link->state &= ~DEV_CONFIG_PENDING;
 	return;
+
       cs_failed:
 	cs_error(link->handle, last_fn, last_ret);
 	ixj_cs_release((u_long) link);
@@ -6041,6 +6086,9 @@
 	CardServices(ReleaseConfiguration, link->handle);
 	CardServices(ReleaseIO, link->handle, &link->io);
 	link->state &= ~DEV_CONFIG;
+
+	kfree(ixj[0]);
+	ixj[0] = NULL;
 }
 
 int ixj_event(event_t event, int priority, event_callback_args_t * args)
@@ -6078,38 +6126,44 @@
 	return 0;
 }
 
-#endif				// PCMCIA
+#endif /* CONFIG_PCMCIA */
 
 static void cleanup(void)
 {
 	int cnt;
 	del_timer(&ixj_timer);
 	for (cnt = 0; cnt < IXJMAX; cnt++) {
-		if (ixj[cnt].cardtype == 300) {
-			ixj[cnt].pld_scrw.bits.daafsyncen = 0;	// Turn off DAA Frame Sync
+		IXJ *j = ixj[cnt];
+
+		if (j == NULL)
+			continue;
 
-			outb_p(ixj[cnt].pld_scrw.byte, ixj[cnt].XILINXbase);
-			ixj[cnt].pld_slicw.bits.rly1 = 0;
-			ixj[cnt].pld_slicw.bits.rly2 = 0;
-			ixj[cnt].pld_slicw.bits.rly3 = 0;
-			outb_p(ixj[cnt].pld_slicw.byte, ixj[cnt].XILINXbase + 0x01);
-			LED_SetState(0x0, cnt);
-			release_region(ixj[cnt].XILINXbase, 8);
-		}
-		if (ixj[cnt].cardtype == 400 || ixj[cnt].cardtype == 500) {
-			release_region(ixj[cnt].XILINXbase, 4);
-		}
-		if (ixj[cnt].DSPbase) {
-			release_region(ixj[cnt].DSPbase, 16);
-			phone_unregister_device(&ixj[cnt].p);
-		}
-		if (ixj[cnt].read_buffer)
-			kfree(ixj[cnt].read_buffer);
-		if (ixj[cnt].write_buffer)
-			kfree(ixj[cnt].write_buffer);
+		if (j->cardtype == QTI_LINEJACK) {
+			j->pld_scrw.bits.daafsyncen = 0;	// Turn off DAA Frame Sync
+
+			outb_p(j->pld_scrw.byte, j->XILINXbase);
+			j->pld_slicw.bits.rly1 = 0;
+			j->pld_slicw.bits.rly2 = 0;
+			j->pld_slicw.bits.rly3 = 0;
+			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			LED_SetState(0x0, j);
+			release_region(j->XILINXbase, 8);
+		}
+		if (j->cardtype == QTI_PHONEJACK_LITE
+		    || j->cardtype == QTI_PHONEJACK_PCI) {
+			release_region(j->XILINXbase, 4);
+		}
+		if (j->DSPbase) {
+			release_region(j->DSPbase, 16);
+			phone_unregister_device(&j->p);
+		}
+		if (j->read_buffer)
+			kfree(j->read_buffer);
+		if (j->write_buffer)
+			kfree(j->write_buffer);
 #ifdef CONFIG_ISAPNP
-		if (ixj[cnt].dev)
-			ixj[cnt].dev->deactivate(ixj[cnt].dev);
+		if (j->dev)
+			j->dev->deactivate(j->dev);
 #endif
 #ifdef CONFIG_PCMCIA
 		DEBUG(0, "ixj_cs: unloading\n");
@@ -6117,6 +6171,9 @@
 		while (dev_list != NULL)
 			ixj_detach(dev_list);
 #endif
+
+		kfree(j);
+		ixj[cnt] = NULL;
 	}
 	remove_proc_entry ("ixj", NULL);
 	remove_proc_entry ("ixjfsk", NULL);
@@ -6223,36 +6280,46 @@
 	cleanup();
 }
 
-int __init ixj_init(void)
+#if defined(CONFIG_PCMCIA)
+int __init ixj_register_pcmcia(void)
 {
-	int result;
-	int i = 0;
-	int cnt = 0;
-	int probe = 0;
-#ifdef CONFIG_ISAPNP
-	int func = 0x110;
-	struct pci_dev *dev = NULL, *old_dev = NULL;
-#endif
-#ifdef CONFIG_PCI
-	struct pci_dev *pci = NULL;
-#endif
-#ifdef CONFIG_PCMCIA
 	servinfo_t serv;
+
 	DEBUG(0, "%s\n", version);
 	CardServices(GetCardServicesInfo, &serv);
 	if (serv.Revision != CS_RELEASE_CODE) {
 		printk(KERN_NOTICE "ixj_cs: Card Services release does not match!\n");
-		return -1;
+		return -EINVAL;
 	}
 	register_pcmcia_driver(&dev_info, &ixj_attach, &ixj_detach);
-	probe = 0;
+	return 0;
+}
 #else
-#ifdef CONFIG_ISAPNP
+extern __inline__ int ixj_register_pcmcia(void)
+{
+	return 0;
+}
+
+#if defined(CONFIG_ISAPNP)
+extern __inline__ int ixj_probe_isa(int *cnt)
+{
+	return 0;
+}
+
+int __init ixj_probe_isapnp(int *cnt)
+{
+	int probe = 0;
+	int func = 0x110;
+	struct pci_dev *dev = NULL, *old_dev = NULL;
+
 	while (1) {
 		do {
+			IXJ *j;
+			int result;
+
 			old_dev = dev;
 			dev = isapnp_find_dev(NULL, ISAPNP_VENDOR('Q', 'T', 'I'),
-					 ISAPNP_FUNCTION(func), old_dev);
+					      ISAPNP_FUNCTION(func), old_dev);
 			if (!dev)
 				break;
 			result = dev->prepare(dev);
@@ -6260,8 +6327,10 @@
 				printk("preparing failed %d \n", result);
 				break;
 			}
+
 			if (!(dev->resource[0].flags & IORESOURCE_IO))
 				return -ENODEV;
+
 			dev->resource[0].flags |= IORESOURCE_AUTO;
 			if (func != 0x110)
 				dev->resource[1].flags |= IORESOURCE_AUTO;
@@ -6269,42 +6338,60 @@
 				printk("isapnp configure failed (out of resources?)\n");
 				return -ENOMEM;
 			}
-			ixj[cnt].DSPbase = dev->resource[0].start;	/* get real port */
-			if (func != 0x110)
-				ixj[cnt].XILINXbase = dev->resource[1].start;	/* get real port */
-			result = check_region(ixj[cnt].DSPbase, 16);
-			if (result) {
-				printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", ixj[cnt].DSPbase);
+
+			/* DSP base */
+			if ((result = check_region(dev->resource[0].start, 16)) < 0) {
+				printk(KERN_INFO "ixj: can't get I/O address 0x%lx\n",
+				       dev->resource[0].start);
 				cleanup();
 				return result;
 			}
-			request_region(ixj[cnt].DSPbase, 16, "ixj DSP");
+
+			if ((j = kmalloc(sizeof(*j), GFP_KERNEL)) == NULL) {
+				cleanup();
+				return -ENOMEM;
+			}
+
+			ixj[*cnt] = j;
+
+			j->DSPbase = dev->resource[0].start;
+
+			/* XXX is this racy? */
+			request_region(j->DSPbase, 16, "ixj DSP");
+
+			if (func != 0x110)
+				j->XILINXbase = dev->resource[1].start;
+
 			switch (func) {
 			case (0x110):
-				ixj[cnt].cardtype = 100;
+				j->cardtype = QTI_PHONEJACK;
 				break;
 			case (0x310):
-				ixj[cnt].cardtype = 300;
+				j->cardtype = QTI_LINEJACK;
 				break;
 			case (0x410):
-				ixj[cnt].cardtype = 400;
+				j->cardtype = QTI_PHONEJACK_LITE;
 				break;
 			}
-			probe = ixj_selfprobe(cnt);
-			ixj[cnt].serial = dev->bus->serial;
-			ixj[cnt].dev = dev;
+			probe = ixj_selfprobe(j, *cnt);
+			
+			j->serial = dev->bus->serial;
+			j->dev = dev;
 			switch (func) {
 			case 0x110:
-				printk(KERN_INFO "ixj: found Internet PhoneJACK at 0x%x\n", ixj[cnt].DSPbase);
+				printk(KERN_INFO "ixj: found Internet PhoneJACK at 0x%x\n",
+				       j->DSPbase);
 				break;
 			case 0x310:
-				printk(KERN_INFO "ixj: found Internet LineJACK at 0x%x\n", ixj[cnt].DSPbase);
+				printk(KERN_INFO "ixj: found Internet LineJACK at 0x%x\n",
+				       j->DSPbase);
 				break;
 			case 0x410:
-				printk(KERN_INFO "ixj: found Internet PhoneJACK Lite at 0x%x\n", ixj[cnt].DSPbase);
+				printk(KERN_INFO "ixj: found Internet PhoneJACK Lite at 0x%x\n",
+				       j->DSPbase);
 				break;
 			}
-			cnt++;
+			++*cnt;
 		} while (dev);
 		if (func == 0x410)
 			break;
@@ -6314,69 +6401,143 @@
 			func = 0x310;
 		dev = NULL;
 	}
-#else				//CONFIG_ISAPNP
+
+	return probe;
+}
+#else
+extern __inline__ int ixj_probe_isapnp(int *cnt)
+{
+	return 0;
+}
+
+int __init ixj_probe_isa(int *cnt)
+{
+	int i, result, probe;
+
 	/* Use passed parameters for older kernels without PnP */
 	for (i = 0; i < IXJMAX; i++) {
 		if (dspio[i]) {
-			ixj[cnt].DSPbase = dspio[i];
-			ixj[cnt].XILINXbase = xio[i];
-			ixj[cnt].cardtype = 0;
-			result = check_region(ixj[cnt].DSPbase, 16);
-			if (result) {
-				printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", ixj[cnt].DSPbase);
+			IXJ *j;
+
+			if ((result = check_region(dspio[i], 16)) < 0) {
+				printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", dspio[i]);
 				cleanup();
 				return result;
 			}
-			request_region(ixj[cnt].DSPbase, 16, "ixj DSP");
-			probe = ixj_selfprobe(cnt);
-			ixj[cnt].dev = NULL;
-			cnt++;
+
+			if ((j = kmalloc(sizeof(*j), GFP_KERNEL)) == NULL) {
+				cleanup();
+				return -ENOMEM;
+			}
+			ixj[*cnt] = j;
+
+			j->DSPbase = dspio[i];
+			request_region(j->DSPbase, 16, "ixj DSP");
+
+			j->XILINXbase = xio[i];
+			j->cardtype = 0;
+
+			probe = ixj_selfprobe(j, *cnt);
+			j->dev = NULL;
+
+			++*cnt;
 		}
 	}
-#endif				// !CONFIG_ISAPNP
-#endif				// CONFIG_PCMCIA
-#ifdef CONFIG_PCI
-	if (pci_present()) {
-		for (i = 0; i < IXJMAX - cnt; i++) {
-			pci = pci_find_device(0x15E2, 0x0500, pci);
-			if (!pci)
-				break;
-			if (pci_enable_device(pci))
-				break;
-			{
-				ixj[cnt].DSPbase = pci_resource_start(pci, 0);
-				ixj[cnt].XILINXbase = ixj[cnt].DSPbase + 0x10;
-				ixj[cnt].serial = (PCIEE_GetSerialNumber)pci_resource_start(pci, 2);
-				result = check_region(ixj[cnt].DSPbase, 16);
-				if (result) {
-					printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", ixj[cnt].DSPbase);
-					cleanup();
-					return result;
-				}
-				request_region(ixj[cnt].DSPbase, 16, "ixj DSP");
-				ixj[cnt].cardtype = 500;
-				probe = ixj_selfprobe(cnt);
-				if (probe)
-					printk(KERN_INFO "ixj: found Internet PhoneJACK PCI at 0x%x\n", ixj[cnt].DSPbase);
-				cnt++;
+
+	return 0;
+}
+#endif /* CONFIG_ISAPNP */
+#endif /* CONFIG_PCMCIA */
+
+#if defined(CONFIG_PCI)
+int __init ixj_probe_pci(int *cnt)
+{
+	struct pci_dev *pci = NULL;
+	int i, probe = 0;
+
+	for (i = 0; i < IXJMAX - *cnt; i++) {
+		pci = pci_find_device(0x15E2, 0x0500, pci);
+		if (!pci)
+			break;
+		if (pci_enable_device(pci))
+			break;
+		{
+			IXJ *j;
+			int result;
+
+			if ((result = check_region(pci_resource_start(pci, 0), 16)) < 0) {
+				printk(KERN_INFO "ixj: can't get I/O address 0x%lx\n",
+				       pci_resource_start(pci, 0));
+				cleanup();
+				return result;
 			}
+
+			if ((j = kmalloc(sizeof(*j), GFP_KERNEL)) == NULL) {
+				cleanup();
+				return -ENOMEM;
+			}
+			ixj[*cnt] = j;
+
+			j->DSPbase = pci_resource_start(pci, 0);
+			request_region(j->DSPbase, 16, "ixj DSP");
+
+			j->XILINXbase = j->DSPbase + 0x10;
+			j->serial = (PCIEE_GetSerialNumber)pci_resource_start(pci, 2);
+			j->cardtype = QTI_PHONEJACK_PCI;
+
+			probe = ixj_selfprobe(j, *cnt);
+			if (probe)
+				printk(KERN_INFO "ixj: found Internet PhoneJACK PCI at 0x%x\n", j->DSPbase);
+			++*cnt;
 		}
 	}
-#endif
+
+	return probe;
+}
+#else
+extern __inline__ int ixj_probe_pci(int *cnt)
+{
+	return 0;
+}
+#endif /* CONFIG_PCI */
+
+int __init ixj_init(void)
+{
+	int cnt = 0;
+	int probe = 0;
+
+	/* These might be no-ops, see above. */
+	if ((probe = ixj_register_pcmcia()) < 0) {
+		return probe;
+	}
+	if ((probe = ixj_probe_isapnp(&cnt)) < 0) {
+		return probe;
+	}
+	if ((probe = ixj_probe_isa(&cnt)) < 0) {
+		return probe;
+	}
+	if (pci_present()) {
+		if ((probe = ixj_probe_pci(&cnt)) < 0) {
+			return probe;
+		}
+      	}
+
 	printk("%s\n", ixj_c_rcsid);
+
 	create_proc_read_entry ("ixj", 0, NULL, ixj_read_proc, NULL);
 	create_proc_read_entry ("ixjfsk", 0, NULL, ixj_read_proc_fsk, NULL);
+
 	ixj_init_timer();
 	ixj_add_timer();
+
 	return probe;
 }
 
 module_init(ixj_init);
 module_exit(ixj_exit);
 
-static void DAA_Coeff_US(int board)
+static void DAA_Coeff_US(IXJ *j)
 {
-	IXJ *j = &ixj[board];
 	int i;
 
 	j->daa_country = DAA_US;
@@ -6559,9 +6720,8 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
 }
 
-static void DAA_Coeff_UK(int board)
+static void DAA_Coeff_UK(IXJ *j)
 {
-	IXJ *j = &ixj[board];
 	int i;
 
 	j->daa_country = DAA_UK;
@@ -6740,9 +6900,8 @@
 }
 
 
-static void DAA_Coeff_France(int board)
+static void DAA_Coeff_France(IXJ *j)
 {
-	IXJ *j = &ixj[board];
 	int i;
 
 	j->daa_country = DAA_FRANCE;
@@ -6921,9 +7080,8 @@
 }
 
 
-static void DAA_Coeff_Germany(int board)
+static void DAA_Coeff_Germany(IXJ *j)
 {
-	IXJ *j = &ixj[board];
 	int i;
 
 	j->daa_country = DAA_GERMANY;
@@ -7102,9 +7260,8 @@
 }
 
 
-static void DAA_Coeff_Australia(int board)
+static void DAA_Coeff_Australia(IXJ *j)
 {
-	IXJ *j = &ixj[board];
 	int i;
 
 	j->daa_country = DAA_AUSTRALIA;
@@ -7282,9 +7439,8 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
 }
 
-static void DAA_Coeff_Japan(int board)
+static void DAA_Coeff_Japan(IXJ *j)
 {
-	IXJ *j = &ixj[board];
 	int i;
 
 	j->daa_country = DAA_JAPAN;
@@ -8998,34 +9154,34 @@
 		 0x0FF5		// shift-mask 0x0FF (look at 16 half-frames) bit count = 5
 	},
 };
-static int ixj_init_filter(int board, IXJ_FILTER * jf)
+static int ixj_init_filter(IXJ *j, IXJ_FILTER * jf)
 {
 	unsigned short cmd;
 	int cnt, max;
-	IXJ *j = &ixj[board];
+
 	if (jf->filter > 3) {
 		return -1;
 	}
-	if (ixj_WriteDSPCommand(0x5154 + jf->filter, board))	// Select Filter
+	if (ixj_WriteDSPCommand(0x5154 + jf->filter, j))	// Select Filter
 
 		return -1;
 	if (!jf->enable) {
-		if (ixj_WriteDSPCommand(0x5152, board))		// Disable Filter
+		if (ixj_WriteDSPCommand(0x5152, j))		// Disable Filter
 
 			return -1;
 		else
 			return 0;
 	} else {
-		if (ixj_WriteDSPCommand(0x5153, board))		// Enable Filter
+		if (ixj_WriteDSPCommand(0x5153, j))		// Enable Filter
 
 			return -1;
 		// Select the filter (f0 - f3) to use.
-		if (ixj_WriteDSPCommand(0x5154 + jf->filter, board))
+		if (ixj_WriteDSPCommand(0x5154 + jf->filter, j))
 			return -1;
 	}
 	if (jf->freq < 12 && jf->freq > 3) {
 		// Select the frequency for the selected filter.
-		if (ixj_WriteDSPCommand(0x5170 + jf->freq, board))
+		if (ixj_WriteDSPCommand(0x5170 + jf->freq, j))
 			return -1;
 	} else if (jf->freq > 11) {
 		// We need to load a programmable filter set for undefined
@@ -9033,7 +9189,7 @@
 		// Since there are only 4 filters and 4 programmable sets, we will
 		// just point the filter to the same number set and program it for the
 		// frequency we want.
-		if (ixj_WriteDSPCommand(0x5170 + jf->filter, board))
+		if (ixj_WriteDSPCommand(0x5170 + jf->filter, j))
 			return -1;
 		if (j->ver.low != 0x12) {
 			cmd = 0x515B;
@@ -9042,10 +9198,10 @@
 			cmd = 0x515E;
 			max = 15;
 		}
-		if (ixj_WriteDSPCommand(cmd, board))
+		if (ixj_WriteDSPCommand(cmd, j))
 			return -1;
 		for (cnt = 0; cnt < max; cnt++) {
-			if (ixj_WriteDSPCommand(tone_table[jf->freq - 12][cnt], board))
+			if (ixj_WriteDSPCommand(tone_table[jf->freq - 12][cnt], j))
 				return -1;
 		}
 	}
@@ -9053,7 +9209,7 @@
 	return 0;
 }
 
-static int ixj_init_tone(int board, IXJ_TONE * ti)
+static int ixj_init_tone(IXJ *j, IXJ_TONE * ti)
 {
 	int freq0, freq1;
 	unsigned short data;
@@ -9071,15 +9227,15 @@
 
 	if(ti->tone_index > 12 && ti->tone_index < 28)
 	{
-		if (ixj_WriteDSPCommand(0x6800 + ti->tone_index, board))
+		if (ixj_WriteDSPCommand(0x6800 + ti->tone_index, j))
 			return -1;
-		if (ixj_WriteDSPCommand(0x6000 + (ti->gain0 << 4) + ti->gain1, board))
+		if (ixj_WriteDSPCommand(0x6000 + (ti->gain0 << 4) + ti->gain1, j))
 			return -1;
 		data = freq0;
-		if (ixj_WriteDSPCommand(data, board))
+		if (ixj_WriteDSPCommand(data, j))
 			return -1;
 		data = freq1;
-		if (ixj_WriteDSPCommand(data, board))
+		if (ixj_WriteDSPCommand(data, j))
 			return -1;
 	}
 	return freq0;
diff -urN linux-2.4.2-pre1/drivers/telephony/ixj.h linux/drivers/telephony/ixj.h
--- linux-2.4.2-pre1/drivers/telephony/ixj.h	Fri Dec 29 14:35:47 2000
+++ linux/drivers/telephony/ixj.h	Mon Dec  3 22:27:48 2001
@@ -93,8 +93,6 @@
 	  char  cbyte;
 } IXJ_CBYTE;
 
-int ixj_WriteDSPCommand(unsigned short, int board);
-
 /******************************************************************************
 *
 *  This structure represents the Hardware Control Register of the CT8020/8021
@@ -1280,6 +1278,8 @@
 	short fskdata[8000];
 	int fskdcnt;
 } IXJ;
+
+int ixj_WriteDSPCommand(unsigned short, IXJ *);
 
 typedef int (*IXJ_REGFUNC) (IXJ * j, unsigned long arg);
 
diff -urN linux-2.4.2-pre1/drivers/usb/serial/empeg.c linux/drivers/usb/serial/empeg.c
--- linux-2.4.2-pre1/drivers/usb/serial/empeg.c	Thu Jan  4 13:15:32 2001
+++ linux/drivers/usb/serial/empeg.c	Mon Dec  3 22:27:48 2001
@@ -13,9 +13,16 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  * 
+ * (01/22/2001) gb
+ *	Added write_room() and chars_in_buffer() support. 
+ * 
+ * (12/21/2000) gb
+ *	Moved termio stuff inside the port->active check.
+ *	Moved MOD_DEC_USE_COUNT to end of empeg_close().
+ * 
  * (12/03/2000) gb
  *	Added port->tty->ldisc.set_termios(port->tty, NULL) to empeg_open()
- *      This notifies the tty driver that the termios have changed.
+ *	This notifies the tty driver that the termios have changed.
  * 
  * (11/13/2000) gb
  *	Moved tty->low_latency = 1 from empeg_read_bulk_callback() to empeg_open()
@@ -57,27 +64,35 @@
 
 #include "usb-serial.h"
 
-#define EMPEG_VENDOR_ID                 0x084f
-#define EMPEG_PRODUCT_ID                0x0001
+#define EMPEG_VENDOR_ID			0x084f
+#define EMPEG_PRODUCT_ID		0x0001
 
 #define MIN(a,b)		(((a)<(b))?(a):(b))
 
 /* function prototypes for an empeg-car player */
-static int  empeg_open		(struct usb_serial_port *port, struct file *filp);
-static void empeg_close		(struct usb_serial_port *port, struct file *filp);
-static int  empeg_write		(struct usb_serial_port *port, int from_user, const unsigned char *buf, int count);
-static void empeg_throttle	(struct usb_serial_port *port);
-static void empeg_unthrottle	(struct usb_serial_port *port);
-static int  empeg_startup	(struct usb_serial *serial);
-static void empeg_shutdown	(struct usb_serial *serial);
-static int  empeg_ioctl		(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
-static void empeg_set_termios	(struct usb_serial_port *port, struct termios *old_termios);
+static int  empeg_open			(struct usb_serial_port *port, struct file *filp);
+static void empeg_close			(struct usb_serial_port *port, struct file *filp);
+static int  empeg_write			(struct usb_serial_port *port,
+					int from_user,
+					const unsigned char *buf,
+					int count);
+static int  empeg_write_room		(struct usb_serial_port *port);
+static int  empeg_chars_in_buffer	(struct usb_serial_port *port);
+static void empeg_throttle		(struct usb_serial_port *port);
+static void empeg_unthrottle		(struct usb_serial_port *port);
+static int  empeg_startup		(struct usb_serial *serial);
+static void empeg_shutdown		(struct usb_serial *serial);
+static int  empeg_ioctl			(struct usb_serial_port *port,
+					struct file * file,
+					unsigned int cmd,
+					unsigned long arg);
+static void empeg_set_termios		(struct usb_serial_port *port, struct termios *old_termios);
 static void empeg_write_bulk_callback	(struct urb *urb);
 static void empeg_read_bulk_callback	(struct urb *urb);
 
 static __devinitdata struct usb_device_id id_table [] = {
 	{ USB_DEVICE(EMPEG_VENDOR_ID, EMPEG_PRODUCT_ID) },
-        { }                                     /* Terminating entry */
+	{ }					/* Terminating entry */
 };
 
 MODULE_DEVICE_TABLE (usb, id_table);
@@ -101,6 +116,8 @@
 	ioctl:			empeg_ioctl,
 	set_termios:		empeg_set_termios,
 	write:			empeg_write,
+	write_room:		empeg_write_room,
+	chars_in_buffer:	empeg_chars_in_buffer,
 	write_bulk_callback:	empeg_write_bulk_callback,
 	read_bulk_callback:	empeg_read_bulk_callback,
 };
@@ -132,64 +149,58 @@
 	++port->open_count;
 	MOD_INC_USE_COUNT;
 
-	/* gb - 2000/11/05
-	 *
-	 * personally, I think these termios should be set in
-	 * empeg_startup(), but it appears doing so leads to one
-	 * of those chicken/egg problems. :)
-	 *
-	 */
-	port->tty->termios->c_iflag
-		&= ~(IGNBRK
-		| BRKINT
-		| PARMRK
-		| ISTRIP
-		| INLCR
-		| IGNCR
-		| ICRNL
-		| IXON);
-
-	port->tty->termios->c_oflag
-		&= ~OPOST;
-
-	port->tty->termios->c_lflag
-		&= ~(ECHO
-		| ECHONL
-		| ICANON
-		| ISIG
-		| IEXTEN);
-
-	port->tty->termios->c_cflag
-		&= ~(CSIZE
-		| PARENB);
-
-	port->tty->termios->c_cflag
-		|= CS8;
-
-	/* gb - 2000/12/03
-	 *
-	 * Contributed by Borislav Deianov
-	 *
-	 * Notify the tty driver that the termios have changed!!
-	 *
-	 */
-        port->tty->ldisc.set_termios(port->tty, NULL);
-
-	/* gb - 2000/11/05
-	 *
-	 * force low_latency on
-	 *
-	 * The tty_flip_buffer_push()'s in empeg_read_bulk_callback() will actually
-	 * force the data through if low_latency is set.  Otherwise the pushes are
-	 * scheduled; this is bad as it opens up the possibility of dropping bytes
-	 * on the floor.  We are trying to sustain high data transfer rates; and
-	 * don't want to drop bytes on the floor.
-	 * Moral: use low_latency - drop no bytes - life is good. :)
-	 *
-	 */
-	port->tty->low_latency = 1;
-
 	if (!port->active) {
+
+		/* gb - 2000/11/05
+		 * personally, I think these termios should be set in
+		 * empeg_startup(), but it appears doing so leads to one
+		 * of those chicken/egg problems. :)
+		 */
+		port->tty->termios->c_iflag
+			&= ~(IGNBRK
+			| BRKINT
+			| PARMRK
+			| ISTRIP
+			| INLCR
+			| IGNCR
+			| ICRNL
+			| IXON);
+
+		port->tty->termios->c_oflag
+			&= ~OPOST;
+
+		port->tty->termios->c_lflag
+			&= ~(ECHO
+			| ECHONL
+			| ICANON
+			| ISIG
+			| IEXTEN);
+
+		port->tty->termios->c_cflag
+			&= ~(CSIZE
+			| PARENB);
+
+		port->tty->termios->c_cflag
+			|= CS8;
+
+		/* gb - 2000/12/03
+		 * Contributed by Borislav Deianov
+		 * Notify the tty driver that the termios have changed!!
+		 */
+		port->tty->ldisc.set_termios(port->tty, NULL);
+
+		/* gb - 2000/11/05
+		 * force low_latency on
+		 *
+		 * The tty_flip_buffer_push()'s in empeg_read_bulk_callback() will actually
+		 * force the data through if low_latency is set.  Otherwise the pushes are
+		 * scheduled; this is bad as it opens up the possibility of dropping bytes
+		 * on the floor.  We are trying to sustain high data transfer rates; and
+		 * don't want to drop bytes on the floor.
+		 * Moral: use low_latency - drop no bytes - life is good. :)
+		 */
+		port->tty->low_latency = 1;
+
 		port->active = 1;
 		bytes_in = 0;
 		bytes_out = 0;
@@ -238,7 +249,6 @@
 	spin_lock_irqsave (&port->port_lock, flags);
 
 	--port->open_count;
-	MOD_DEC_USE_COUNT;
 
 	if (port->open_count <= 0) {
 		transfer_buffer =  kmalloc (0x12, GFP_KERNEL);
@@ -260,6 +270,8 @@
 	/* Uncomment the following line if you want to see some statistics in your syslog */
 	/* info ("Bytes In = %d  Bytes Out = %d", bytes_in, bytes_out); */
 
+	MOD_DEC_USE_COUNT;
+
 }
 
 
@@ -315,8 +327,6 @@
 			memcpy (urb->transfer_buffer, current_position, transfer_size);
 		}
 
-		count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
-
 		/* build up our urb */
 		FILL_BULK_URB (
 			urb,
@@ -348,6 +358,58 @@
 } 
 
 
+static int empeg_write_room (struct usb_serial_port *port)
+{
+	unsigned long flags;
+	int i;
+	int room = 0;
+
+	dbg(__FUNCTION__ " - port %d", port->number);
+
+	spin_lock_irqsave (&port->port_lock, flags);
+
+	/* tally up the number of bytes available */
+	for (i = 0; i < NUM_URBS; ++i) {
+		if (write_urb_pool[i]->status != -EINPROGRESS) {
+			room += URB_TRANSFER_BUFFER_SIZE;
+		}
+	} 
+
+	spin_unlock_irqrestore (&port->port_lock, flags);
+
+	dbg(__FUNCTION__ " - returns %d", room);
+
+	return (room);
+
+}
+
+
+static int empeg_chars_in_buffer (struct usb_serial_port *port)
+{
+	unsigned long flags;
+	int i;
+	int chars = 0;
+
+	dbg(__FUNCTION__ " - port %d", port->number);
+
+	spin_lock_irqsave (&port->port_lock, flags);
+
+	/* tally up the number of bytes waiting */
+	for (i = 0; i < NUM_URBS; ++i) {
+		if (write_urb_pool[i]->status == -EINPROGRESS) {
+			chars += URB_TRANSFER_BUFFER_SIZE;
+		}
+	}
+
+	spin_unlock_irqrestore (&port->port_lock, flags);
+
+	dbg (__FUNCTION__ " - returns %d", chars);
+
+	return (chars);
+
+}
+
+
 static void empeg_write_bulk_callback (struct urb *urb)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
@@ -407,9 +469,6 @@
 			if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
 				tty_flip_buffer_push(tty);
 				}
-			/* gb - 2000/11/13
-			 * This doesn't push the data through unless tty->low_latency is set.
-			 */
 			tty_insert_flip_char(tty, data[i], 0);
 		}
 		/* gb - 2000/11/13
diff -urN linux-2.4.2-pre1/drivers/usb/serial/mct_u232.c linux/drivers/usb/serial/mct_u232.c
--- linux-2.4.2-pre1/drivers/usb/serial/mct_u232.c	Thu Dec  7 16:13:38 2000
+++ linux/drivers/usb/serial/mct_u232.c	Mon Dec  3 22:27:48 2001
@@ -24,6 +24,10 @@
  *   Basic tests have been performed with minicom/zmodem transfers and
  *   modem dialing under Linux 2.4.0-test10 (for me it works fine).
  *
+ * 06-Jan-2001 Cornel Ciocirlan 
+ *   - Added support for Sitecom U232-P25 model (Product Id 0x0230)
+ *   - Added support for D-Link DU-H3SP USB BAY (Product Id 0x0200)
+ *
  * 29-Nov-2000 Greg Kroah-Hartman
  *   - Added device id table to fit with 2.4.0-test11 structure.
  *   - took out DEAL_WITH_TWO_INT_IN_ENDPOINTS #define as it's not needed
@@ -101,17 +105,34 @@
 /*
  * All of the device info needed for the MCT USB-RS232 converter.
  */
-static __devinitdata struct usb_device_id id_table [] = {
-	{ idVendor: MCT_U232_VID, idProduct: MCT_U232_PID },
-	{ }					/* Terminating entry */
+static __devinitdata struct usb_device_id id_table_combined [] = {
+	{ USB_DEVICE(MCT_U232_VID, MCT_U232_PID) },
+	{ USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) },
+	{ USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) },
+	{ }		/* Terminating entry */
 };
 
-MODULE_DEVICE_TABLE (usb, id_table);
+static __devinitdata struct usb_device_id mct_u232_table [] = {
+        { USB_DEVICE(MCT_U232_VID, MCT_U232_PID) },
+        { }                        /* Terminating entry */
+};
+
+static __devinitdata struct usb_device_id mct_u232_sitecom_table [] = {
+        { USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) },
+        { }                        /* Terminating entry */
+};
+
+static __devinitdata struct usb_device_id mct_u232_du_h3sp_table [] = {
+        { USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) },
+        { }                        /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 
 struct usb_serial_device_type mct_u232_device = {
 	name:		     "Magic Control Technology USB-RS232",
-	id_table:	     id_table,
+	id_table:	     mct_u232_table,
 	needs_interrupt_in:  MUST_HAVE,	 /* 2 interrupt-in endpoints */
 	needs_bulk_in:	     MUST_HAVE_NOT,   /* no bulk-in endpoint */
 	needs_bulk_out:	     MUST_HAVE,	      /* 1 bulk-out endpoint */
@@ -133,6 +154,57 @@
 	shutdown:	     mct_u232_shutdown,
 };
 
+struct usb_serial_device_type mct_u232_sitecom_device = {
+	name:		     "MCT/Sitecom USB-RS232",
+	id_table:	     mct_u232_sitecom_table,
+	needs_interrupt_in:  MUST_HAVE,	 /* 2 interrupt-in endpoints */
+	needs_bulk_in:	     MUST_HAVE_NOT,   /* no bulk-in endpoint */
+	needs_bulk_out:	     MUST_HAVE,	      /* 1 bulk-out endpoint */
+	num_interrupt_in:    2,
+	num_bulk_in:	     0,
+	num_bulk_out:	     1,
+	num_ports:	     1,
+	open:		     mct_u232_open,
+	close:		     mct_u232_close,
+#ifdef FIX_WRITE_RETURN_CODE_PROBLEM
+	write:		     mct_u232_write,
+	write_bulk_callback: mct_u232_write_bulk_callback,
+#endif
+	read_int_callback:   mct_u232_read_int_callback,
+	ioctl:		     mct_u232_ioctl,
+	set_termios:	     mct_u232_set_termios,
+	break_ctl:	     mct_u232_break_ctl,
+	startup:	     mct_u232_startup,
+	shutdown:	     mct_u232_shutdown,
+};
+
+struct usb_serial_device_type mct_u232_du_h3sp_device = {
+        name:                "MCT/D-Link DU-H3SP USB BAY",
+        id_table:            mct_u232_du_h3sp_table,
+        needs_interrupt_in:  MUST_HAVE,  /* 2 interrupt-in endpoints */
+        needs_bulk_in:       MUST_HAVE_NOT,   /* no bulk-in endpoint */
+        needs_bulk_out:      MUST_HAVE,       /* 1 bulk-out endpoint */
+        num_interrupt_in:    2,
+        num_bulk_in:         0,
+        num_bulk_out:        1,
+        num_ports:           1,
+        open:                mct_u232_open,
+        close:               mct_u232_close,
+#ifdef FIX_WRITE_RETURN_CODE_PROBLEM
+        write:               mct_u232_write,
+        write_bulk_callback: mct_u232_write_bulk_callback,
+#endif
+        read_int_callback:   mct_u232_read_int_callback,
+        ioctl:               mct_u232_ioctl,
+        set_termios:         mct_u232_set_termios,
+        break_ctl:           mct_u232_break_ctl,
+        startup:             mct_u232_startup,
+        shutdown:            mct_u232_shutdown,
+};
+
+
+
+
 struct mct_u232_private {
 	unsigned long	     control_state; /* Modem Line Setting (TIOCM) */
 	unsigned char        last_lcr;      /* Line Control Register */
@@ -750,6 +822,8 @@
 static int __init mct_u232_init (void)
 {
 	usb_serial_register (&mct_u232_device);
+	usb_serial_register (&mct_u232_sitecom_device);
+	usb_serial_register (&mct_u232_du_h3sp_device);
 	
 	return 0;
 }
@@ -758,6 +832,8 @@
 static void __exit mct_u232_exit (void)
 {
 	usb_serial_deregister (&mct_u232_device);
+	usb_serial_deregister (&mct_u232_sitecom_device);
+	usb_serial_deregister (&mct_u232_du_h3sp_device);
 }
 
 
diff -urN linux-2.4.2-pre1/drivers/usb/serial/mct_u232.h linux/drivers/usb/serial/mct_u232.h
--- linux-2.4.2-pre1/drivers/usb/serial/mct_u232.h	Thu Dec  7 16:13:38 2000
+++ linux/drivers/usb/serial/mct_u232.h	Mon Dec  3 22:27:48 2001
@@ -24,7 +24,14 @@
 #define __LINUX_USB_SERIAL_MCT_U232_H
 
 #define MCT_U232_VID	                0x0711	/* Vendor Id */
-#define MCT_U232_PID	                0x0210	/* Product Id */
+#define MCT_U232_PID	                0x0210	/* Original MCT Product Id */
+
+/* U232-P25, Sitecom */
+#define MCT_U232_SITECOM_PID		0x0230	/* Sitecom Product Id */
+
+/* DU-H3SP USB BAY hub */
+
+#define MCT_U232_DU_H3SP_PID		0x0200	/* D-Link DU-H3SP USB BAY */
 
 /*
  * Vendor Request Interface
diff -urN linux-2.4.2-pre1/drivers/usb/serial/usbserial.c linux/drivers/usb/serial/usbserial.c
--- linux-2.4.2-pre1/drivers/usb/serial/usbserial.c	Tue Jan 16 14:29:54 2001
+++ linux/drivers/usb/serial/usbserial.c	Mon Dec  3 22:27:48 2001
@@ -15,6 +15,14 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
+ * 2001_02_05 gkh
+ *	Fixed buffer overflows bug with the generic serial driver.  Thanks to
+ *	Todd Squires <squirest@ct0.com> for fixing this.
+ *
+ * (01/10/2001) gkh
+ *	Fixed bug where the generic serial adaptor grabbed _any_ device that was
+ *	offered to it.
+ *
  * (12/12/2000) gkh
  *	Removed MOD_INC and MOD_DEC from poll and disconnect functions, and
  *	moved them to the serial_open and serial_close functions.
@@ -742,6 +750,11 @@
 	if (!port->active) {
 		port->active = 1;
 
+		/* force low_latency on so that our tty_push actually forces the data through, 
+		   otherwise it is scheduled, and with high data rates (like with OHCI) data
+		   can get lost. */
+		port->tty->low_latency = 1;
+		
 		/* if we have a bulk interrupt, start reading from it */
 		if (serial->num_bulk_in) {
 			/* Start reading from the device */
@@ -907,8 +920,13 @@
 	tty = port->tty;
 	if (urb->actual_length) {
 		for (i = 0; i < urb->actual_length ; ++i) {
-			 tty_insert_flip_char(tty, data[i], 0);
-	  	}
+			/* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
+			if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
+				tty_flip_buffer_push(tty);
+			}
+			/* this doesn't actually push the data through unless tty->low_latency is set */
+			tty_insert_flip_char(tty, data[i], 0);
+		}
 	  	tty_flip_buffer_push(tty);
 	}
 
@@ -1361,6 +1379,7 @@
 #ifdef CONFIG_USB_SERIAL_GENERIC
 	generic_device_ids[0].idVendor = vendor;
 	generic_device_ids[0].idProduct = product;
+	generic_device_ids[0].match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT;
 	/* register our generic driver with ourselves */
 	usb_serial_register (&generic_device);
 #endif
diff -urN linux-2.4.2-pre1/drivers/usb/serial/visor.c linux/drivers/usb/serial/visor.c
--- linux-2.4.2-pre1/drivers/usb/serial/visor.c	Tue Jan 16 14:29:54 2001
+++ linux/drivers/usb/serial/visor.c	Mon Dec  3 22:27:48 2001
@@ -11,6 +11,13 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
+ * (01/21/2000) gkh
+ *	Added write_room and chars_in_buffer, as they were previously using the
+ *	generic driver versions which is all wrong now that we are using an urb
+ *	pool.  Thanks to Wolfgang Grandegger for pointing this out to me.
+ *	Removed count assignment in the write function, which was not needed anymore
+ *	either.  Thanks to Al Borchers for pointing this out.
+ *
  * (12/12/2000) gkh
  *	Moved MOD_DEC to end of visor_close to be nicer, as the final write 
  *	message can sleep.
@@ -103,6 +110,8 @@
 static int  visor_open		(struct usb_serial_port *port, struct file *filp);
 static void visor_close		(struct usb_serial_port *port, struct file *filp);
 static int  visor_write		(struct usb_serial_port *port, int from_user, const unsigned char *buf, int count);
+static int  visor_write_room		(struct usb_serial_port *port);
+static int  visor_chars_in_buffer	(struct usb_serial_port *port);
 static void visor_throttle	(struct usb_serial_port *port);
 static void visor_unthrottle	(struct usb_serial_port *port);
 static int  visor_startup	(struct usb_serial *serial);
@@ -142,6 +151,8 @@
 	ioctl:			visor_ioctl,
 	set_termios:		visor_set_termios,
 	write:			visor_write,
+	write_room:		visor_write_room,
+	chars_in_buffer:	visor_chars_in_buffer,
 	write_bulk_callback:	visor_write_bulk_callback,
 	read_bulk_callback:	visor_read_bulk_callback,
 };
@@ -289,8 +300,6 @@
 		else
 			memcpy (urb->transfer_buffer, current_position, transfer_size);
 		
-		count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
-
 		/* build up our urb */
 		FILL_BULK_URB (urb, serial->dev, usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), 
 				urb->transfer_buffer, transfer_size, visor_write_bulk_callback, port);
@@ -310,6 +319,52 @@
 exit:
 	return bytes_sent;
 } 
+
+
+static int visor_write_room (struct usb_serial_port *port)
+{
+	unsigned long flags;
+	int i;
+	int room = 0;
+
+	dbg(__FUNCTION__ " - port %d", port->number);
+	
+	spin_lock_irqsave (&port->port_lock, flags);
+
+	for (i = 0; i < NUM_URBS; ++i) {
+		if (write_urb_pool[i]->status != -EINPROGRESS) {
+			room += URB_TRANSFER_BUFFER_SIZE;
+		}
+	}
+	
+	spin_unlock_irqrestore (&port->port_lock, flags);
+	
+	dbg(__FUNCTION__ " - returns %d", room);
+	return (room);
+}
+
+
+static int visor_chars_in_buffer (struct usb_serial_port *port)
+{
+	unsigned long flags;
+	int i;
+	int chars = 0;
+
+	dbg(__FUNCTION__ " - port %d", port->number);
+	
+	spin_lock_irqsave (&port->port_lock, flags);
+
+	for (i = 0; i < NUM_URBS; ++i) {
+		if (write_urb_pool[i]->status == -EINPROGRESS) {
+			chars += URB_TRANSFER_BUFFER_SIZE;
+		}
+	}
+	
+	spin_unlock_irqrestore (&port->port_lock, flags);
+
+	dbg (__FUNCTION__ " - returns %d", chars);
+	return (chars);
+}
 
 
 static void visor_write_bulk_callback (struct urb *urb)
diff -urN linux-2.4.2-pre1/drivers/usb/wacom.c linux/drivers/usb/wacom.c
--- linux-2.4.2-pre1/drivers/usb/wacom.c	Thu Jan  4 13:15:32 2001
+++ linux/drivers/usb/wacom.c	Mon Dec  3 22:27:48 2001
@@ -285,7 +285,7 @@
 
 struct wacom_features wacom_features[] = {
 	{ "Wacom Graphire",      8, 10206,  7422,  511, 32, wacom_graphire_irq,
-		BIT(EV_REL), 0, REL_WHEEL, 0 },
+		BIT(EV_REL), 0, BIT(REL_WHEEL), 0 },
 	{ "Wacom Intuos 4x5",   10, 12700, 10360, 1023, 15, wacom_intuos_irq,
 		0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
 	{ "Wacom Intuos 6x8",   10, 20320, 15040, 1023, 15, wacom_intuos_irq,
diff -urN linux-2.4.2-pre1/drivers/video/amifb.c linux/drivers/video/amifb.c
--- linux-2.4.2-pre1/drivers/video/amifb.c	Fri Dec 29 14:07:23 2000
+++ linux/drivers/video/amifb.c	Mon Dec  3 22:27:48 2001
@@ -1534,7 +1534,7 @@
 			}
 			return i;
 		}
-#endif */ DEBUG */
+#endif	/* DEBUG */
 	}
 	return -EINVAL;
 }
diff -urN linux-2.4.2-pre1/drivers/video/fbmem.c linux/drivers/video/fbmem.c
--- linux-2.4.2-pre1/drivers/video/fbmem.c	Thu Jan  4 13:00:55 2001
+++ linux/drivers/video/fbmem.c	Mon Dec  3 22:27:48 2001
@@ -598,12 +598,9 @@
 	pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;
 	pgprot_val(vma->vm_page_prot) |= _CACHE_UNCACHED;
 #elif defined(__arm__)
-#if defined(CONFIG_CPU_32) && !defined(CONFIG_ARCH_ACORN)
-	/* On Acorn architectures, we want to keep the framebuffer
-	 * cached.
-	 */
-	pgprot_val(vma->vm_page_prot) &= ~(PTE_CACHEABLE | PTE_BUFFERABLE);
-#endif
+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+	/* This is an IO map - tell maydump to skip this VMA */
+	vma->vm_flags |= VM_IO;
 #elif defined(__sh__)
 	pgprot_val(vma->vm_page_prot) &= ~_PAGE_CACHABLE;
 #else
diff -urN linux-2.4.2-pre1/drivers/video/hgafb.c linux/drivers/video/hgafb.c
--- linux-2.4.2-pre1/drivers/video/hgafb.c	Thu Aug 17 23:07:55 2000
+++ linux/drivers/video/hgafb.c	Mon Dec  3 22:27:48 2001
@@ -7,6 +7,8 @@
  *
  * History:
  *
+ * - Revision 0.1.7 (23 Jan 2001): fix crash resulting from MDA only cards 
+ *				   being detected as Hercules.	 (Paul G.)
  * - Revision 0.1.6 (17 Aug 2000): new style structs
  *                                 documentation
  * - Revision 0.1.5 (13 Mar 2000): spinlocks instead of saveflags();cli();etc
@@ -358,21 +360,22 @@
 		udelay(2);
 	}
 
-	if (p_save != q_save) {
-		switch (inb_p(HGA_STATUS_PORT) & 0x70) {
-			case 0x10:
-				hga_type = TYPE_HERCPLUS;
-				hga_type_name = "HerculesPlus";
-				break;
-			case 0x50:
-				hga_type = TYPE_HERCCOLOR;
-				hga_type_name = "HerculesColor";
-				break;
-			default:
-				hga_type = TYPE_HERC;
-				hga_type_name = "Hercules";
-				break;
-		}
+	if (p_save == q_save) 
+		return 0;
+
+	switch (inb_p(HGA_STATUS_PORT) & 0x70) {
+		case 0x10:
+			hga_type = TYPE_HERCPLUS;
+			hga_type_name = "HerculesPlus";
+			break;
+		case 0x50:
+			hga_type = TYPE_HERCCOLOR;
+			hga_type_name = "HerculesColor";
+			break;
+		default:
+			hga_type = TYPE_HERC;
+			hga_type_name = "Hercules";
+			break;
 	}
 	return 1;
 }
diff -urN linux-2.4.2-pre1/drivers/video/matrox/matroxfb_DAC1064.c linux/drivers/video/matrox/matroxfb_DAC1064.c
--- linux-2.4.2-pre1/drivers/video/matrox/matroxfb_DAC1064.c	Fri Dec 29 14:07:23 2000
+++ linux/drivers/video/matrox/matroxfb_DAC1064.c	Mon Dec  3 22:27:48 2001
@@ -1,81 +1,12 @@
 /*
  *
- * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400
+ * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450.
  *
- * (c) 1998,1999,2000 Petr Vandrovec <vandrove@vc.cvut.cz>
+ * (c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz>
  *
- * Version: 1.50 2000/08/10
+ * Version: 1.52 2001/02/02
  *
- * MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org>
- *
- * Contributors: "menion?" <menion@mindless.com>
- *                     Betatesting, fixes, ideas
- *
- *               "Kurt Garloff" <garloff@suse.de>
- *                     Betatesting, fixes, ideas, videomodes, videomodes timmings
- *
- *               "Tom Rini" <trini@kernel.crashing.org>
- *                     MTRR stuff, PPC cleanups, betatesting, fixes, ideas
- *
- *               "Bibek Sahu" <scorpio@dodds.net>
- *                     Access device through readb|w|l and write b|w|l
- *                     Extensive debugging stuff
- *
- *               "Daniel Haun" <haund@usa.net>
- *                     Testing, hardware cursor fixes
- *
- *               "Scott Wood" <sawst46+@pitt.edu>
- *                     Fixes
- *
- *               "Gerd Knorr" <kraxel@goldbach.isdn.cs.tu-berlin.de>
- *                     Betatesting
- *
- *               "Kelly French" <targon@hazmat.com>
- *               "Fernando Herrera" <fherrera@eurielec.etsit.upm.es>
- *                     Betatesting, bug reporting
- *
- *               "Pablo Bianucci" <pbian@pccp.com.ar>
- *                     Fixes, ideas, betatesting
- *
- *               "Inaky Perez Gonzalez" <inaky@peloncho.fis.ucm.es>
- *                     Fixes, enhandcements, ideas, betatesting
- *
- *               "Ryuichi Oikawa" <roikawa@rr.iiij4u.or.jp>
- *                     PPC betatesting, PPC support, backward compatibility
- *
- *               "Paul Womar" <Paul@pwomar.demon.co.uk>
- *               "Owen Waller" <O.Waller@ee.qub.ac.uk>
- *                     PPC betatesting
- *
- *               "Thomas Pornin" <pornin@bolet.ens.fr>
- *                     Alpha betatesting
- *
- *               "Pieter van Leuven" <pvl@iae.nl>
- *               "Ulf Jaenicke-Roessler" <ujr@physik.phy.tu-dresden.de>
- *                     G100 testing
- *
- *               "H. Peter Arvin" <hpa@transmeta.com>
- *                     Ideas
- *
- *               "Cort Dougan" <cort@cs.nmt.edu>
- *                     CHRP fixes and PReP cleanup
- *
- *               "Mark Vojkovich" <mvojkovi@ucsd.edu>
- *                     G400 support
- *
- *               "Ken Aaker" <kdaaker@rchland.vnet.ibm.com>
- *                     memtype extension (needed for GXT130P RS/6000 adapter)
- *
- * (following author is not in any relation with this code, but his code
- *  is included in this driver)
- *
- * Based on framebuffer driver for VBE 2.0 compliant graphic boards
- *     (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
- *
- * (following author is not in any relation with this code, but his ideas
- *  were used when writting this driver)
- *
- *		 FreeVBE/AF (Matrox), "Shawn Hargreaves" <shawn@talula.demon.co.uk>
+ * See matroxfb_base.c for contributors.
  *
  */
 
@@ -787,6 +718,11 @@
 
 	ACCESS_FBINFO(primout) = &m1064;
 
+	if (ACCESS_FBINFO(devflags.g450dac)) {
+		/* we must do this always, BIOS does not do it for us
+		   and accelerator dies without it */
+		mga_outl(0x1C0C, 0);
+	}
 	if (ACCESS_FBINFO(devflags.noinit))
 		return 0;
 	hw->MXoptionReg &= 0xC0000100;
diff -urN linux-2.4.2-pre1/drivers/video/matrox/matroxfb_base.c linux/drivers/video/matrox/matroxfb_base.c
--- linux-2.4.2-pre1/drivers/video/matrox/matroxfb_base.c	Fri Dec 29 14:07:23 2000
+++ linux/drivers/video/matrox/matroxfb_base.c	Mon Dec  3 22:27:49 2001
@@ -2,9 +2,9 @@
  *
  * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400
  *
- * (c) 1998,1999,2000 Petr Vandrovec <vandrove@vc.cvut.cz>
+ * (c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz>
  *
- * Version: 1.50 2000/08/10
+ * Version: 1.52 2001/02/02
  *
  * MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org>
  *
@@ -1409,12 +1409,12 @@
 
 #define DEVF_VIDEO64BIT		0x0001
 #define	DEVF_SWAPS		0x0002
-#define DEVF_MILLENNIUM		0x0004
-#define	DEVF_MILLENNIUM2	0x0008
+/* #define DEVF_recycled	0x0004 */
+/* #define DEVF_recycled	0x0008 */
 #define DEVF_CROSS4MB		0x0010
 #define DEVF_TEXT4B		0x0020
 #define DEVF_DDC_8_2		0x0040
-#define DEVF_DMA		0x0080
+/* #define DEVF_recycled	0x0080 */
 #define DEVF_SUPPORT32MB	0x0100
 #define DEVF_ANY_VXRES		0x0200
 #define DEVF_TEXT16B		0x0400
@@ -1441,19 +1441,19 @@
 #ifdef CONFIG_FB_MATROX_MILLENIUM
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_MIL,	0xFF,
 		0,			0,
-		DEVF_MILLENNIUM | DEVF_TEXT4B,
+		DEVF_TEXT4B,
 		230000,
 		&vbMillennium,
 		"Millennium (PCI)"},
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_MIL_2,	0xFF,
 		0,			0,
-		DEVF_MILLENNIUM | DEVF_MILLENNIUM2 | DEVF_SWAPS,
+		DEVF_SWAPS,
 		220000,
 		&vbMillennium2,
 		"Millennium II (PCI)"},
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_MIL_2_AGP,	0xFF,
 		0,			0,
-		DEVF_MILLENNIUM | DEVF_MILLENNIUM2 | DEVF_SWAPS,
+		DEVF_SWAPS,
 		250000,
 		&vbMillennium2A,
 		"Millennium II (AGP)"},
@@ -1461,13 +1461,13 @@
 #ifdef CONFIG_FB_MATROX_MYSTIQUE
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_MYS,	0x02,
 		0,			0,
-		DEVF_VIDEO64BIT,
+		DEVF_VIDEO64BIT | DEVF_CROSS4MB,
 		180000,
 		&vbMystique,
 		"Mystique (PCI)"},
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_MYS,	0xFF,
 		0,			0,
-		DEVF_VIDEO64BIT | DEVF_SWAPS,
+		DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
 		220000,
 		&vbMystique,
 		"Mystique 220 (PCI)"},
@@ -1842,33 +1842,33 @@
 	}
 
 	/* FIXME: Where to move this?! */
-#if defined(CONFIG_PPC)
+#if defined(CONFIG_ALL_PPC)
 #if defined(CONFIG_FB_COMPAT_XPMAC)
 	strcpy(ACCESS_FBINFO(matrox_name), "MTRX,");	/* OpenFirmware naming convension */
 	strncat(ACCESS_FBINFO(matrox_name), b->name, 26);
 	if (!console_fb_info)
 		console_fb_info = &ACCESS_FBINFO(fbcon);
 #endif
-	if ((xres <= 640) && (yres <= 480)) {
+#ifndef MODULE
+	if (_machine == _MACH_Pmac) {
 		struct fb_var_screeninfo var;
-		if (default_vmode == VMODE_NVRAM) {
-			default_vmode = nvram_read_byte(NV_VMODE);
-			if (default_vmode <= 0 || default_vmode > VMODE_MAX)
-				default_vmode = VMODE_CHOOSE;
-		}
 		if (default_vmode <= 0 || default_vmode > VMODE_MAX)
 			default_vmode = VMODE_640_480_60;
+#ifdef CONFIG_NVRAM
 		if (default_cmode == CMODE_NVRAM)
 			default_cmode = nvram_read_byte(NV_CMODE);
+#endif
 		if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
 			default_cmode = CMODE_8;
 		if (!mac_vmode_to_var(default_vmode, default_cmode, &var)) {
 			var.accel_flags = vesafb_defined.accel_flags;
 			var.xoffset = var.yoffset = 0;
-			vesafb_defined = var; /* Note: mac_vmode_to_var() doesnot set all parameters */
+			/* Note: mac_vmode_to_var() does not set all parameters */
+			vesafb_defined = var;
 		}
 	}
-#endif /* CONFIG_PPC */
+#endif /* !MODULE */
+#endif /* CONFIG_ALL_PPC */
 	vesafb_defined.xres_virtual = vesafb_defined.xres;
 	if (nopan) {
 		vesafb_defined.yres_virtual = vesafb_defined.yres;
@@ -2005,6 +2005,7 @@
 	u_int32_t cmd;
 #ifndef CONFIG_FB_MATROX_MULTIHEAD
 	static int registered = 0;
+	static struct display global_disp;
 #endif
 	DBG("matroxfb_probe")
 
@@ -2502,8 +2503,8 @@
 
 /* *************************** init module code **************************** */
 
-MODULE_AUTHOR("(c) 1998,1999 Petr Vandrovec <vandrove@vc.cvut.cz>");
-MODULE_DESCRIPTION("Accelerated FBDev driver for Matrox Millennium/Mystique/G100/G200/G400");
+MODULE_AUTHOR("(c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz>");
+MODULE_DESCRIPTION("Accelerated FBDev driver for Matrox Millennium/Mystique/G100/G200/G400/G450");
 MODULE_PARM(mem, "i");
 MODULE_PARM_DESC(mem, "Size of available memory in MB, KB or B (2,4,8,12,16MB, default=autodetect)");
 MODULE_PARM(disabled, "i");
diff -urN linux-2.4.2-pre1/drivers/video/matrox/matroxfb_base.h linux/drivers/video/matrox/matroxfb_base.h
--- linux-2.4.2-pre1/drivers/video/matrox/matroxfb_base.h	Fri Dec 29 14:07:23 2000
+++ linux/drivers/video/matrox/matroxfb_base.h	Mon Dec  3 22:27:49 2001
@@ -589,7 +589,6 @@
 #else
 
 extern struct matrox_fb_info matroxfb_global_mxinfo;
-struct display global_disp;
 
 #define ACCESS_FBINFO(x) (matroxfb_global_mxinfo.x)
 #define ACCESS_FBINFO2(info, x) (matroxfb_global_mxinfo.x)
@@ -787,11 +786,7 @@
 #define mga_setr(addr,port,val) do { mga_outb(addr, port); mga_outb((addr)+1, val); } while (0)
 #endif
 
-#ifdef __LITTLE_ENDIAN
-#define mga_fifo(n)	do {} while (mga_inb(M_FIFOSTATUS) < (n))
-#else
 #define mga_fifo(n)	do {} while ((mga_inl(M_FIFOSTATUS) & 0xFF) < (n))
-#endif
 
 #define WaitTillIdle()	do {} while (mga_inl(M_STATUS) & 0x10000)
 
diff -urN linux-2.4.2-pre1/fs/dcache.c linux/fs/dcache.c
--- linux-2.4.2-pre1/fs/dcache.c	Wed Jan  3 11:03:35 2001
+++ linux/fs/dcache.c	Mon Dec  3 22:27:49 2001
@@ -52,13 +52,8 @@
 static struct list_head *dentry_hashtable;
 static LIST_HEAD(dentry_unused);
 
-struct {
-	int nr_dentry;
-	int nr_unused;
-	int age_limit;		/* age in seconds */
-	int want_pages;		/* pages requested by system */
-	int dummy[2];
-} dentry_stat = {0, 0, 45, 0,};
+/* Statistics gathering. */
+struct dentry_stat_t dentry_stat = {0, 0, 45, 0,};
 
 /* no dcache_lock, please */
 static inline void d_free(struct dentry *dentry)
diff -urN linux-2.4.2-pre1/fs/inode.c linux/fs/inode.c
--- linux-2.4.2-pre1/fs/inode.c	Mon Dec  3 22:27:36 2001
+++ linux/fs/inode.c	Mon Dec  3 22:27:49 2001
@@ -67,11 +67,7 @@
 /*
  * Statistics gathering..
  */
-struct {
-	int nr_inodes;
-	int nr_unused;
-	int dummy[5];
-} inodes_stat;
+struct inodes_stat_t inodes_stat;
 
 static kmem_cache_t * inode_cachep;
 
diff -urN linux-2.4.2-pre1/fs/reiserfs/namei.c linux/fs/reiserfs/namei.c
--- linux-2.4.2-pre1/fs/reiserfs/namei.c	Mon Jan 15 15:31:19 2001
+++ linux/fs/reiserfs/namei.c	Mon Dec  3 22:27:49 2001
@@ -1,5 +1,14 @@
 /*
  * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
+ *
+ * Trivial changes by Alan Cox to remove EHASHCOLLISION for compatibility
+ *
+ * Trivial Changes:
+ * Rights granted to Hans Reiser to redistribute under other terms providing
+ * he accepts all liability including but not limited to patent, fitness
+ * for purpose, and direct or indirect claims arising from failure to perform.
+ *
+ * NO WARRANTY
  */
 
 #ifdef __KERNEL__
@@ -472,7 +481,7 @@
 	    if (buffer != small_buf)
 		reiserfs_kfree (buffer, buflen, dir->i_sb);
 	    pathrelse (&path);
-	    return -EHASHCOLLISION;//EBADSLT
+	    return -EBUSY; //HASHCOLLISION;//EBADSLT
 	}
 	/* adjust offset of directory enrty */
 	deh->deh_offset = cpu_to_le32 (SET_GENERATION_NUMBER (deh_offset (deh), gen_number));
@@ -485,7 +494,7 @@
 	    if (buffer != small_buf)
 		reiserfs_kfree (buffer, buflen, dir->i_sb);
 	    pathrelse (&path);
-	    return -EHASHCOLLISION;
+	    return -EBUSY;
 	}
     } else {
 	deh->deh_offset = cpu_to_le32 (SET_GENERATION_NUMBER (le32_to_cpu (deh->deh_offset), 0));
diff -urN linux-2.4.2-pre1/include/asm-alpha/page.h linux/include/asm-alpha/page.h
--- linux-2.4.2-pre1/include/asm-alpha/page.h	Wed Aug  9 13:46:01 2000
+++ linux/include/asm-alpha/page.h	Mon Dec  3 22:27:49 2001
@@ -12,64 +12,10 @@
 
 #define STRICT_MM_TYPECHECKS
 
-/*
- * A _lot_ of the kernel time is spent clearing pages, so
- * do this as fast as we possibly can. Also, doing this
- * as a separate inline function (rather than memset())
- * results in clearer kernel profiles as we see _who_ is
- * doing page clearing or copying.
- */
-static inline void clear_page(void * page)
-{
-	unsigned long count = PAGE_SIZE/64;
-	unsigned long *ptr = (unsigned long *)page;
-
-	do {
-		ptr[0] = 0;
-		ptr[1] = 0;
-		ptr[2] = 0;
-		ptr[3] = 0;
-		count--;
-		ptr[4] = 0;
-		ptr[5] = 0;
-		ptr[6] = 0;
-		ptr[7] = 0;
-		ptr += 8;
-	} while (count);
-}
-
+extern void clear_page(void *page);
 #define clear_user_page(page, vaddr)	clear_page(page)
 
-static inline void copy_page(void * _to, void * _from)
-{
-	unsigned long count = PAGE_SIZE/64;
-	unsigned long *to = (unsigned long *)_to;
-	unsigned long *from = (unsigned long *)_from;
-
-	do {
-		unsigned long a,b,c,d,e,f,g,h;
-		a = from[0];
-		b = from[1];
-		c = from[2];
-		d = from[3];
-		e = from[4];
-		f = from[5];
-		g = from[6];
-		h = from[7];
-		count--;
-		from += 8;
-		to[0] = a;
-		to[1] = b;
-		to[2] = c;
-		to[3] = d;
-		to[4] = e;
-		to[5] = f;
-		to[6] = g;
-		to[7] = h;
-		to += 8;
-	} while (count);
-}
-
+extern void copy_page(void * _to, void * _from);
 #define copy_user_page(to, from, vaddr)	copy_page(to, from)
 
 #ifdef STRICT_MM_TYPECHECKS
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-arc/io.h linux/include/asm-arm/arch-arc/io.h
--- linux-2.4.2-pre1/include/asm-arm/arch-arc/io.h	Mon Sep 18 15:15:22 2000
+++ linux/include/asm-arm/arch-arc/io.h	Mon Dec  3 22:27:49 2001
@@ -16,6 +16,49 @@
 #define IO_SPACE_LIMIT 0xffffffff
 
 /*
+ * GCC is totally crap at loading/storing data.  We try to persuade it
+ * to do the right thing by using these whereever possible instead of
+ * the above.
+ */
+#define __arch_base_getb(b,o)			\
+ ({						\
+	unsigned int v, r = (b);		\
+	__asm__ __volatile__(			\
+		"ldrb	%0, [%1, %2]"		\
+		: "=r" (v)			\
+		: "r" (r), "Ir" (o));		\
+	v;					\
+ })
+
+#define __arch_base_getl(b,o)			\
+ ({						\
+	unsigned int v, r = (b);		\
+	__asm__ __volatile__(			\
+		"ldr	%0, [%1, %2]"		\
+		: "=r" (v)			\
+		: "r" (r), "Ir" (o));		\
+	v;					\
+ })
+
+#define __arch_base_putb(v,b,o)			\
+ ({						\
+	unsigned int r = (b);			\
+	__asm__ __volatile__(			\
+		"strb	%0, [%1, %2]"		\
+		:				\
+		: "r" (v), "r" (r), "Ir" (o));	\
+ })
+
+#define __arch_base_putl(v,b,o)			\
+ ({						\
+	unsigned int r = (b);			\
+	__asm__ __volatile__(			\
+		"str	%0, [%1, %2]"		\
+		:				\
+		: "r" (v), "r" (r), "Ir" (o));	\
+ })
+
+/*
  * We use two different types of addressing - PC style addresses, and ARM
  * addresses.  PC style accesses the PC hardware with the normal PC IO
  * addresses, eg 0x3f8 for serial#1.  ARM addresses are 0x80000000+
@@ -75,7 +118,7 @@
 	"tst	%2, #0x80000000\n\t"						\
 	"mov	%0, %4\n\t"							\
 	"addeq	%0, %0, %3\n\t"							\
-	"ldr" ##instr## "	%1, [%0, %2, lsl #2]	@ in"###fnsuffix	\
+	"ldr" instr "	%1, [%0, %2, lsl #2]	@ in" #fnsuffix			\
 	: "=&r" (temp), "=r" (value)						\
 	: "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)		\
 	: "cc");								\
@@ -203,22 +246,7 @@
 #define outw(v,p)	(__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))
 #define outl(v,p)	(__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
 #define __ioaddr(p)	(__builtin_constant_p((p)) ? __ioaddr(p)  : __ioaddrc(p))
-
-/*
- * Translated address IO functions
- *
- * IO address has already been translated to a virtual address
- */
-#define outb_t(v,p)								\
-	(*(volatile unsigned char *)(p) = (v))
-
-#define inb_t(p)								\
-	(*(volatile unsigned char *)(p))
-
-#define outl_t(v,p)								\
-	(*(volatile unsigned long *)(p) = (v))
-
-#define inl_t(p)								\
-	(*(volatile unsigned long *)(p))
+/* the following macro is depreciated */
+#define ioaddr(port)			__ioaddr((port))
 
 #endif
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-arc/irqs.h linux/include/asm-arm/arch-arc/irqs.h
--- linux-2.4.2-pre1/include/asm-arm/arch-arc/irqs.h	Mon Sep 18 15:15:22 2000
+++ linux/include/asm-arm/arch-arc/irqs.h	Mon Dec  3 22:27:49 2001
@@ -52,4 +52,9 @@
 
 #define IRQ_TIMER		IRQ_TIMER0
 
+/*
+ * This is the offset of the FIQ "IRQ" numbers
+ */
+#define FIQ_START		64
+
 #define irq_cannonicalize(i)	(i)
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-cl7500/io.h linux/include/asm-arm/arch-cl7500/io.h
--- linux-2.4.2-pre1/include/asm-arm/arch-cl7500/io.h	Thu Feb 24 22:44:47 2000
+++ linux/include/asm-arm/arch-cl7500/io.h	Mon Dec  3 22:27:49 2001
@@ -13,6 +13,49 @@
 #define IO_SPACE_LIMIT 0xffffffff
 
 /*
+ * GCC is totally crap at loading/storing data.  We try to persuade it
+ * to do the right thing by using these whereever possible instead of
+ * the above.
+ */
+#define __arch_base_getb(b,o)			\
+ ({						\
+	unsigned int v, r = (b);		\
+	__asm__ __volatile__(			\
+		"ldrb	%0, [%1, %2]"		\
+		: "=r" (v)			\
+		: "r" (r), "Ir" (o));		\
+	v;					\
+ })
+
+#define __arch_base_getl(b,o)			\
+ ({						\
+	unsigned int v, r = (b);		\
+	__asm__ __volatile__(			\
+		"ldr	%0, [%1, %2]"		\
+		: "=r" (v)			\
+		: "r" (r), "Ir" (o));		\
+	v;					\
+ })
+
+#define __arch_base_putb(v,b,o)			\
+ ({						\
+	unsigned int r = (b);			\
+	__asm__ __volatile__(			\
+		"strb	%0, [%1, %2]"		\
+		:				\
+		: "r" (v), "r" (r), "Ir" (o));	\
+ })
+
+#define __arch_base_putl(v,b,o)			\
+ ({						\
+	unsigned int r = (b);			\
+	__asm__ __volatile__(			\
+		"str	%0, [%1, %2]"		\
+		:				\
+		: "r" (v), "r" (r), "Ir" (o));	\
+ })
+
+/*
  * We use two different types of addressing - PC style addresses, and ARM
  * addresses.  PC style accesses the PC hardware with the normal PC IO
  * addresses, eg 0x3f8 for serial#1.  ARM addresses are 0x80000000+
@@ -72,7 +115,7 @@
 	"tst	%2, #0x80000000\n\t"						\
 	"mov	%0, %4\n\t"							\
 	"addeq	%0, %0, %3\n\t"							\
-	"ldr" ##instr## "	%1, [%0, %2, lsl #2]	@ in"###fnsuffix	\
+	"ldr" instr "	%1, [%0, %2, lsl #2]	@ in" #fnsuffix			\
 	: "=&r" (temp), "=r" (value)						\
 	: "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)		\
 	: "cc");								\
@@ -193,22 +236,7 @@
 #define outw(v,p)	(__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))
 #define outl(v,p)	(__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
 #define __ioaddr(p)	(__builtin_constant_p((p)) ? __ioaddr(p)  : __ioaddrc(p))
-
-/*
- * Translated address IO functions
- *
- * IO address has already been translated to a virtual address
- */
-#define outb_t(v,p)								\
-	(*(volatile unsigned char *)(p) = (v))
-
-#define inb_t(p)								\
-	(*(volatile unsigned char *)(p))
-
-#define outl_t(v,p)								\
-	(*(volatile unsigned long *)(p) = (v))
-
-#define inl_t(p)								\
-	(*(volatile unsigned long *)(p))
+/* the following macro is depreciated */
+#define ioaddr(port)			__ioaddr((port))
 
 #endif
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-cl7500/irqs.h linux/include/asm-arm/arch-cl7500/irqs.h
--- linux-2.4.2-pre1/include/asm-arm/arch-cl7500/irqs.h	Tue Nov 23 22:23:11 1999
+++ linux/include/asm-arm/arch-cl7500/irqs.h	Mon Dec  3 22:27:49 2001
@@ -56,4 +56,9 @@
 #define FIQ_INT8		6
 #define FIQ_FORCE		7
 
+/*
+ * This is the offset of the FIQ "IRQ" numbers
+ */
+#define FIQ_START		64
+
 #define IRQ_TIMER		IRQ_TIMER0
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-ebsa110/io.h linux/include/asm-arm/arch-ebsa110/io.h
--- linux-2.4.2-pre1/include/asm-arm/arch-ebsa110/io.h	Mon Sep 18 15:15:23 2000
+++ linux/include/asm-arm/arch-ebsa110/io.h	Mon Dec  3 22:27:49 2001
@@ -16,186 +16,11 @@
 #define IO_SPACE_LIMIT 0xffffffff
 
 /*
- * We use two different types of addressing - PC style addresses, and ARM
- * addresses.  PC style accesses the PC hardware with the normal PC IO
- * addresses, eg 0x3f8 for serial#1.  ARM addresses are 0x80000000+
- * and are translated to the start of IO.  Note that all addresses are
- * shifted left!
+ * Generic virtual read/write
  */
-#define __PORT_PCIO(x)	(!((x) & 0x80000000))
+#define __arch_getw(a)		(*(volatile unsigned short *)(a))
+#define __arch_putw(v,a)	(*(volatile unsigned short *)(a) = (v))
 
-/*
- * Dynamic IO functions - let the compiler
- * optimize the expressions
- */
-#define DECLARE_DYN_OUT(fnsuffix,instr)						\
-extern __inline__ void __out##fnsuffix (unsigned int value, unsigned int port)	\
-{										\
-	unsigned long temp;							\
-	__asm__ __volatile__(							\
-	"tst	%2, #0x80000000\n\t"						\
-	"mov	%0, %4\n\t"							\
-	"addeq	%0, %0, %3\n\t"							\
-	"str" ##instr## "	%1, [%0, %2, lsl #2]	@ out"###fnsuffix	\
-	: "=&r" (temp)								\
-	: "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)	\
-	: "cc");								\
-}
-
-#define DECLARE_DYN_IN(sz,fnsuffix,instr)					\
-extern __inline__ unsigned sz __in##fnsuffix (unsigned int port)		\
-{										\
-	unsigned long temp, value;						\
-	__asm__ __volatile__(							\
-	"tst	%2, #0x80000000\n\t"						\
-	"mov	%0, %4\n\t"							\
-	"addeq	%0, %0, %3\n\t"							\
-	"ldr" ##instr## "	%1, [%0, %2, lsl #2]	@ in"###fnsuffix	\
-	: "=&r" (temp), "=r" (value)						\
-	: "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)		\
-	: "cc");								\
-	return (unsigned sz)value;						\
-}
-
-extern __inline__ unsigned int __ioaddr (unsigned int port)			\
-{										\
-	if (__PORT_PCIO(port))							\
-		return (unsigned int)(PCIO_BASE + (port << 2));			\
-	else									\
-		return (unsigned int)(IO_BASE + (port << 2));			\
-}
-
-#define DECLARE_IO(sz,fnsuffix,instr)	\
-	DECLARE_DYN_OUT(fnsuffix,instr)	\
-	DECLARE_DYN_IN(sz,fnsuffix,instr)
-
-DECLARE_IO(char,b,"b")
-DECLARE_IO(short,w,"")
-DECLARE_IO(int,l,"")
-
-#undef DECLARE_IO
-#undef DECLARE_DYN_OUT
-#undef DECLARE_DYN_IN
-
-/*
- * Constant address IO functions
- *
- * These have to be macros for the 'J' constraint to work -
- * +/-4096 immediate operand.
- */
-#define __outbc(value,port)							\
-({										\
-	if (__PORT_PCIO((port)))						\
-		__asm__ __volatile__(						\
-		"strb	%0, [%1, %2]		@ outbc"			\
-		: : "r" (value), "r" (PCIO_BASE), "Jr" ((port) << 2));		\
-	else									\
-		__asm__ __volatile__(						\
-		"strb	%0, [%1, %2]		@ outbc"			\
-		: : "r" (value), "r" (IO_BASE), "r" ((port) << 2));		\
-})
-
-#define __inbc(port)								\
-({										\
-	unsigned char result;							\
-	if (__PORT_PCIO((port)))						\
-		__asm__ __volatile__(						\
-		"ldrb	%0, [%1, %2]		@ inbc"				\
-		: "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2));		\
-	else									\
-		__asm__ __volatile__(						\
-		"ldrb	%0, [%1, %2]		@ inbc"				\
-		: "=r" (result) : "r" (IO_BASE), "r" ((port) << 2));		\
-	result;									\
-})
-
-#define __outwc(value,port)							\
-({										\
-	unsigned long v = value;						\
-	if (__PORT_PCIO((port)))						\
-		__asm__ __volatile__(						\
-		"str	%0, [%1, %2]		@ outwc"			\
-		: : "r" (v|v<<16), "r" (PCIO_BASE), "Jr" ((port) << 2));	\
-	else									\
-		__asm__ __volatile__(						\
-		"str	%0, [%1, %2]		@ outwc"			\
-		: : "r" (v|v<<16), "r" (IO_BASE), "r" ((port) << 2));		\
-})
-
-#define __inwc(port)								\
-({										\
-	unsigned short result;							\
-	if (__PORT_PCIO((port)))						\
-		__asm__ __volatile__(						\
-		"ldr	%0, [%1, %2]		@ inwc"				\
-		: "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2));		\
-	else									\
-		__asm__ __volatile__(						\
-		"ldr	%0, [%1, %2]		@ inwc"				\
-		: "=r" (result) : "r" (IO_BASE), "r" ((port) << 2));		\
-	result & 0xffff;							\
-})
-
-#define __outlc(v,p)								\
-({										\
-	unsigned long v = value;						\
-	if (__PORT_PCIO((port)))						\
-		__asm__ __volatile__(						\
-		"str	%0, [%1, %2]		@ outlc"			\
-		: : "r" (v), "r" (PCIO_BASE), "Jr" ((port) << 2));		\
-	else									\
-		__asm__ __volatile__(						\
-		"str	%0, [%1, %2]		@ outlc"			\
-		: : "r" (v), "r" (IO_BASE), "r" ((port) << 2));			\
-})
-
-#define __inlc(port)								\
-({										\
-	unsigned long result;							\
-	if (__PORT_PCIO((port)))						\
-		__asm__ __volatile__(						\
-		"ldr	%0, [%1, %2]		@ inlc"				\
-		: "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2));		\
-	else									\
-		__asm__ __volatile__(						\
-		"ldr	%0, [%1, %2]		@ inlc"				\
-		: "=r" (result) : "r" (IO_BASE), "r" ((port) << 2));		\
-	result;									\
-})
-
-#define __ioaddrc(port)								\
-({										\
-	unsigned long addr;							\
-	if (__PORT_PCIO((port)))						\
-		addr = PCIO_BASE + ((port) << 2);				\
-	else									\
-		addr = IO_BASE + ((port) << 2);					\
-	addr;									\
-})
-
-#define inb(p)	 	(__builtin_constant_p((p)) ? __inbc(p)    : __inb(p))
-#define inw(p)	 	(__builtin_constant_p((p)) ? __inwc(p)    : __inw(p))
-#define inl(p)	 	(__builtin_constant_p((p)) ? __inlc(p)    : __inl(p))
-#define outb(v,p)	(__builtin_constant_p((p)) ? __outbc(v,p) : __outb(v,p))
-#define outw(v,p)	(__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))
-#define outl(v,p)	(__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
-#define __ioaddr(p)	(__builtin_constant_p((p)) ? __ioaddr(p)  : __ioaddrc(p))
-
-/*
- * Translated address IO functions
- *
- * IO address has already been translated to a virtual address
- */
-#define outb_t(v,p)								\
-	(*(volatile unsigned char *)(p) = (v))
-
-#define inb_t(p)								\
-	(*(volatile unsigned char *)(p))
-
-#define outl_t(v,p)								\
-	(*(volatile unsigned long *)(p) = (v))
-
-#define inl_t(p)								\
-	(*(volatile unsigned long *)(p))
+#define __io(p)		(ISAIO_BASE + ((p) << 2))
 
 #endif
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-ebsa110/memory.h linux/include/asm-arm/arch-ebsa110/memory.h
--- linux-2.4.2-pre1/include/asm-arm/arch-ebsa110/memory.h	Mon Sep 18 15:15:23 2000
+++ linux/include/asm-arm/arch-ebsa110/memory.h	Mon Dec  3 22:27:49 2001
@@ -23,6 +23,12 @@
 #define TASK_SIZE_26	(0x04000000UL)
 
 /*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
+
+/*
  * Page offset: 3GB
  */
 #define PAGE_OFFSET	(0xc0000000UL)
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-ebsa110/processor.h linux/include/asm-arm/arch-ebsa110/processor.h
--- linux-2.4.2-pre1/include/asm-arm/arch-ebsa110/processor.h	Mon Sep 18 15:15:23 2000
+++ linux/include/asm-arm/arch-ebsa110/processor.h	Wed Dec 31 16:00:00 1969
@@ -1,30 +0,0 @@
-/*
- *  linux/include/asm-arm/arch-ebsa110/processor.h
- *
- *  Copyright (C) 1996-1999 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- *  Changelog:
- *   21-Mar-1999 RMK	Added asm/arch/memory.h
- */
-
-#ifndef __ASM_ARCH_PROCESSOR_H
-#define __ASM_ARCH_PROCESSOR_H
-
-/*
- * Bus types
- */
-#define EISA_bus 0
-#define EISA_bus__is_a_macro /* for versions in ksyms.c */
-#define MCA_bus 0
-#define MCA_bus__is_a_macro /* for versions in ksyms.c */
-
-/* This decides where the kernel will search for a free chunk of vm
- * space during mmap's.
- */
-#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
-
-#endif
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-ebsa285/io.h linux/include/asm-arm/arch-ebsa285/io.h
--- linux-2.4.2-pre1/include/asm-arm/arch-ebsa285/io.h	Mon Sep 18 15:15:23 2000
+++ linux/include/asm-arm/arch-ebsa285/io.h	Mon Dec  3 22:27:49 2001
@@ -19,7 +19,7 @@
 /*
  * Translation of various region addresses to virtual addresses
  */
-#define __io_pci(a)		(PCIO_BASE + (a))
+#define __io(a)			(PCIO_BASE + (a))
 #if 1
 #define __mem_pci(a)		((unsigned long)(a))
 #define __mem_isa(a)		(PCIMEM_BASE + (unsigned long)(a))
@@ -42,41 +42,11 @@
 #define __mem_isa(a)		___mem_isa((unsigned long)(a))
 #endif
 
-/* the following macro is depreciated */
-#define __ioaddr(p)		__io_pci(p)
-
 /*
  * Generic virtual read/write
  */
-#define __arch_getb(a)		(*(volatile unsigned char *)(a))
-#define __arch_getl(a)		(*(volatile unsigned int  *)(a))
-
-extern __inline__ unsigned int __arch_getw(unsigned long a)
-{
-	unsigned int value;
-	__asm__ __volatile__("ldr%?h	%0, [%1, #0]	@ getw"
-		: "=&r" (value)
-		: "r" (a));
-	return value;
-}
-
-
-#define __arch_putb(v,a)	(*(volatile unsigned char *)(a) = (v))
-#define __arch_putl(v,a)	(*(volatile unsigned int  *)(a) = (v))
-
-extern __inline__ void __arch_putw(unsigned int value, unsigned long a)
-{
-	__asm__ __volatile__("str%?h	%0, [%1, #0]	@ putw"
-		: : "r" (value), "r" (a));
-}
-
-#define inb(p)			__arch_getb(__io_pci(p))
-#define inw(p)			__arch_getw(__io_pci(p))
-#define inl(p)			__arch_getl(__io_pci(p))
-
-#define outb(v,p)		__arch_putb(v,__io_pci(p))
-#define outw(v,p)		__arch_putw(v,__io_pci(p))
-#define outl(v,p)		__arch_putl(v,__io_pci(p))
+#define __arch_getw(a)		(*(volatile unsigned short *)(a))
+#define __arch_putw(v,a)	(*(volatile unsigned short *)(a) = (v))
 
 #include <asm/hardware/dec21285.h>
 
@@ -85,20 +55,9 @@
  * and convert a PCI memory address to a physical
  * address for the page tables.
  */
-#define valid_ioaddr(off,sz)	((off) < 0x80000000 && (off) + (sz) <= 0x80000000)
-#define io_to_phys(off)		((off) + DC21285_PCI_MEM)
+#define iomem_valid_addr(iomem,sz) \
+	((iomem) < 0x80000000 && (iomem) + (sz) <= 0x80000000)
 
-/*
- * ioremap takes a PCI memory address, as specified in
- * linux/Documentation/IO-mapping.txt
- */
-#define __arch_ioremap(off,size,nocache)			\
-({								\
-	unsigned long _off = (off), _size = (size);		\
-	void *_ret = (void *)0;					\
-	if (valid_ioaddr(_off, _size))				\
-		_ret = __ioremap(io_to_phys(_off), _size, 0);	\
-	_ret;							\
-})
+#define iomem_to_phys(iomem)	((iomem) + DC21285_PCI_MEM)
 
 #endif
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-nexuspci/io.h linux/include/asm-arm/arch-nexuspci/io.h
--- linux-2.4.2-pre1/include/asm-arm/arch-nexuspci/io.h	Mon Feb 28 14:16:37 2000
+++ linux/include/asm-arm/arch-nexuspci/io.h	Mon Dec  3 22:27:49 2001
@@ -12,7 +12,7 @@
 /*
  * Translation of various region addresses to virtual addresses
  */
-#define __io_pci(a)		(PCIO_BASE + (a))
+#define __io(a)			(PCIO_BASE + (a))
 #if 1
 #define __mem_pci(a)		((unsigned long)(a))
 #define __mem_isa(a)		(PCIMEM_BASE + (unsigned long)(a))
@@ -36,61 +36,19 @@
 #define __mem_isa(a)		___mem_isa((unsigned long)(a))
 #endif
 
-/* the following macro is depreciated */
-#define __ioaddr(p)		__io_pci(p)
-
 /*
  * Generic virtual read/write
  */
-#define __arch_getb(a)		(*(volatile unsigned char *)(a))
-#define __arch_getl(a)		(*(volatile unsigned int *)(a))
-
-extern __inline__ unsigned int __arch_getw(unsigned long a)
-{
-	unsigned int value;
-	__asm__ __volatile__("ldr%?h	%0, [%1, #0]	@ getw"
-		: "=&r" (value)
-		: "r" (a));
-	return value;
-}
-
-
-#define __arch_putb(v,a)	(*(volatile unsigned char *)(a) = (v))
-#define __arch_putl(v,a)	(*(volatile unsigned int *)(a) = (v))
-
-extern __inline__ void __arch_putw(unsigned int value, unsigned long a)
-{
-	__asm__ __volatile__("str%?h	%0, [%1, #0]	@ putw"
-		: : "r" (value), "r" (a));
-}
-
-#define inb(p)			__arch_getb(__io_pci(p))
-#define inw(p)			__arch_getw(__io_pci(p))
-#define inl(p)			__arch_getl(__io_pci(p))
-
-#define outb(v,p)		__arch_putb(v,__io_pci(p))
-#define outw(v,p)		__arch_putw(v,__io_pci(p))
-#define outl(v,p)		__arch_putl(v,__io_pci(p))
+#define __arch_getw(a)		(*(volatile unsigned short *)(a))
+#define __arch_putw(v,a)	(*(volatile unsigned short *)(a) = (v))
 
 /*
  * ioremap support - validate a PCI memory address,
  * and convert a PCI memory address to a physical
  * address for the page tables.
  */
-#define valid_ioaddr(off,sz)	((off) < 0x80000000 && (off) + (sz) <= 0x80000000)
-#define io_to_phys(off)		((off) + PLX_MEM_START)
-
-/*
- * ioremap takes a PCI memory address, as specified in
- * linux/Documentation/IO-mapping.txt
- */
-#define __arch_ioremap(off,size,nocache)			\
-({								\
-	unsigned long _off = (off), _size = (size);		\
-	void *_ret = (void *)0;					\
-	if (valid_ioaddr(_off, _size))				\
-		_ret = __ioremap(io_to_phys(_off), _size, 0);	\
-	_ret;							\
-})
+#define iomem_valid_addr(iomem,sz)	\
+	((iomem) < 0x80000000 && (iomem) + (sz) <= 0x80000000)
+#define iomem_to_phys(iomem)	((iomem) + PLX_MEM_START)
 
 #endif
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-rpc/io.h linux/include/asm-arm/arch-rpc/io.h
--- linux-2.4.2-pre1/include/asm-arm/arch-rpc/io.h	Mon Sep 18 15:15:23 2000
+++ linux/include/asm-arm/arch-rpc/io.h	Mon Dec  3 22:27:49 2001
@@ -16,6 +16,49 @@
 #define IO_SPACE_LIMIT 0xffffffff
 
 /*
+ * GCC is totally crap at loading/storing data.  We try to persuade it
+ * to do the right thing by using these whereever possible instead of
+ * the above.
+ */
+#define __arch_base_getb(b,o)			\
+ ({						\
+	unsigned int v, r = (b);		\
+	__asm__ __volatile__(			\
+		"ldrb	%0, [%1, %2]"		\
+		: "=r" (v)			\
+		: "r" (r), "Ir" (o));		\
+	v;					\
+ })
+
+#define __arch_base_getl(b,o)			\
+ ({						\
+	unsigned int v, r = (b);		\
+	__asm__ __volatile__(			\
+		"ldr	%0, [%1, %2]"		\
+		: "=r" (v)			\
+		: "r" (r), "Ir" (o));		\
+	v;					\
+ })
+
+#define __arch_base_putb(v,b,o)			\
+ ({						\
+	unsigned int r = (b);			\
+	__asm__ __volatile__(			\
+		"strb	%0, [%1, %2]"		\
+		:				\
+		: "r" (v), "r" (r), "Ir" (o));	\
+ })
+
+#define __arch_base_putl(v,b,o)			\
+ ({						\
+	unsigned int r = (b);			\
+	__asm__ __volatile__(			\
+		"str	%0, [%1, %2]"		\
+		:				\
+		: "r" (v), "r" (r), "Ir" (o));	\
+ })
+
+/*
  * We use two different types of addressing - PC style addresses, and ARM
  * addresses.  PC style accesses the PC hardware with the normal PC IO
  * addresses, eg 0x3f8 for serial#1.  ARM addresses are 0x80000000+
@@ -74,7 +117,7 @@
 	"tst	%2, #0x80000000\n\t"						\
 	"mov	%0, %4\n\t"							\
 	"addeq	%0, %0, %3\n\t"							\
-	"ldr" ##instr## "	%1, [%0, %2, lsl #2]	@ in"###fnsuffix	\
+	"ldr" instr "	%1, [%0, %2, lsl #2]	@ in" #fnsuffix			\
 	: "=&r" (temp), "=r" (value)						\
 	: "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)		\
 	: "cc");								\
@@ -195,22 +238,7 @@
 #define outw(v,p)	(__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))
 #define outl(v,p)	(__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
 #define __ioaddr(p)	(__builtin_constant_p((p)) ? __ioaddr(p)  : __ioaddrc(p))
-
-/*
- * Translated address IO functions
- *
- * IO address has already been translated to a virtual address
- */
-#define outb_t(v,p)								\
-	(*(volatile unsigned char *)(p) = (v))
-
-#define inb_t(p)								\
-	(*(volatile unsigned char *)(p))
-
-#define outl_t(v,p)								\
-	(*(volatile unsigned long *)(p) = (v))
-
-#define inl_t(p)								\
-	(*(volatile unsigned long *)(p))
+/* the following macro is depreciated */
+#define ioaddr(port)			__ioaddr((port))
 
 #endif
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-rpc/irqs.h linux/include/asm-arm/arch-rpc/irqs.h
--- linux-2.4.2-pre1/include/asm-arm/arch-rpc/irqs.h	Mon Sep 18 15:15:23 2000
+++ linux/include/asm-arm/arch-rpc/irqs.h	Mon Dec  3 22:27:49 2001
@@ -37,5 +37,10 @@
 #define FIQ_EXPANSIONCARD	6
 #define FIQ_FORCE		7
 
+/*
+ * This is the offset of the FIQ "IRQ" numbers
+ */
+#define FIQ_START		64
+
 #define IRQ_TIMER		IRQ_TIMER0
 
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-sa1100/SA-1111.h linux/include/asm-arm/arch-sa1100/SA-1111.h
--- linux-2.4.2-pre1/include/asm-arm/arch-sa1100/SA-1111.h	Tue Jul 18 22:43:25 2000
+++ linux/include/asm-arm/arch-sa1100/SA-1111.h	Mon Dec  3 22:27:49 2001
@@ -11,6 +11,8 @@
 #ifndef _ASM_ARCH_SA1111
 #define _ASM_ARCH_SA1111
 
+#include <asm/arch/bitfield.h>
+
 /*
  * Macro that calculates real address for registers in the SA-1111
  */
@@ -18,7 +20,21 @@
 #define _SA1111( x )    ((x) + SA1111_BASE)
 
 /*
- * System Bus Interface (SBI)
+ * 26 bits of the SA-1110 address bus are available to the SA-1111.
+ * Use these when feeding target addresses to the DMA engines.
+ */
+
+#define SA1111_ADDR_WIDTH	(26)
+#define SA1111_ADDR_MASK	((1<<SA1111_ADDR_WIDTH)-1)
+#define SA1111_DMA_ADDR(x)	((x)&SA1111_ADDR_MASK)
+
+/*
+ * Don't ask the (SAC) DMA engines to move less than this amount.
+ */
+
+#define SA1111_SAC_DMA_MIN_XFER	(0x800)
+
+/* System Bus Interface (SBI)
  *
  * Registers
  *    SKCR	Control Register
@@ -57,6 +73,7 @@
 #define SMCR_DRAC_0	(1<<2)
 #define SMCR_DRAC_1	(1<<3)
 #define SMCR_DRAC_2	(1<<4)
+#define SMCR_DRAC	Fld(3, 2)
 #define SMCR_CLAT	(1<<5)
 
 #define SKID_SIREV_MASK	(0x000000f0)
@@ -103,6 +120,186 @@
 
 #endif  /* LANGUAGE == C */
 
+#define SKPCR_UCLKEN	(1<<0)
+#define SKPCR_ACCLKEN	(1<<1)
+#define SKPCR_I2SCLKEN	(1<<2)
+#define SKPCR_L3CLKEN	(1<<3)
+#define SKPCR_SCLKEN	(1<<4)
+#define SKPCR_PMCLKEN	(1<<5)
+#define SKPCR_PTCLKEN	(1<<6)
+#define SKPCR_DCLKEN	(1<<7)
+#define SKPCR_PWMCLKEN	(1<<8)
+
+/*
+ * Serial Audio Controller
+ *
+ * Registers
+ *    SACR0             Serial Audio Common Control Register
+ *    SACR1             Serial Audio Alternate Mode (I2C/MSB) Control Register
+ *    SACR2             Serial Audio AC-link Control Register
+ *    SASR0             Serial Audio I2S/MSB Interface & FIFO Status Register
+ *    SASR1             Serial Audio AC-link Interface & FIFO Status Register
+ *    SASCR             Serial Audio Status Clear Register
+ *    L3_CAR            L3 Control Bus Address Register
+ *    L3_CDR            L3 Control Bus Data Register
+ *    ACCAR             AC-link Command Address Register
+ *    ACCDR             AC-link Command Data Register
+ *    ACSAR             AC-link Status Address Register
+ *    ACSDR             AC-link Status Data Register
+ *    SADTCS            Serial Audio DMA Transmit Control/Status Register
+ *    SADTSA            Serial Audio DMA Transmit Buffer Start Address A
+ *    SADTCA            Serial Audio DMA Transmit Buffer Count Register A
+ *    SADTSB            Serial Audio DMA Transmit Buffer Start Address B
+ *    SADTCB            Serial Audio DMA Transmit Buffer Count Register B
+ *    SADRCS            Serial Audio DMA Receive Control/Status Register
+ *    SADRSA            Serial Audio DMA Receive Buffer Start Address A
+ *    SADRCA            Serial Audio DMA Receive Buffer Count Register A
+ *    SADRSB            Serial Audio DMA Receive Buffer Start Address B
+ *    SADRCB            Serial Audio DMA Receive Buffer Count Register B
+ *    SAITR             Serial Audio Interrupt Test Register
+ *    SADR              Serial Audio Data Register (16 x 32-bit)
+ */
+
+#define _SACR0          _SA1111( 0x0600 )
+#define _SACR1          _SA1111( 0x0604 )
+#define _SACR2          _SA1111( 0x0608 )
+#define _SASR0          _SA1111( 0x060c )
+#define _SASR1          _SA1111( 0x0610 )
+#define _SASCR          _SA1111( 0x0618 )
+#define _L3_CAR         _SA1111( 0x061c )
+#define _L3_CDR         _SA1111( 0x0620 )
+#define _ACCAR          _SA1111( 0x0624 )
+#define _ACCDR          _SA1111( 0x0628 )
+#define _ACSAR          _SA1111( 0x062c )
+#define _ACSDR          _SA1111( 0x0630 )
+#define _SADTCS         _SA1111( 0x0634 )
+#define _SADTSA         _SA1111( 0x0638 )
+#define _SADTCA         _SA1111( 0x063c )
+#define _SADTSB         _SA1111( 0x0640 )
+#define _SADTCB         _SA1111( 0x0644 )
+#define _SADRCS         _SA1111( 0x0648 )
+#define _SADRSA         _SA1111( 0x064c )
+#define _SADRCA         _SA1111( 0x0650 )
+#define _SADRSB         _SA1111( 0x0654 )
+#define _SADRCB         _SA1111( 0x0658 )
+#define _SAITR          _SA1111( 0x065c )
+#define _SADR           _SA1111( 0x0680 )
+
+#if LANGUAGE == C
+
+#define SACR0		(*((volatile Word *) SA1111_p2v (_SACR0)))
+#define SACR1		(*((volatile Word *) SA1111_p2v (_SACR1)))
+#define SACR2		(*((volatile Word *) SA1111_p2v (_SACR2)))
+#define SASR0		(*((volatile Word *) SA1111_p2v (_SASR0)))
+#define SASR1		(*((volatile Word *) SA1111_p2v (_SASR1)))
+#define SASCR		(*((volatile Word *) SA1111_p2v (_SASCR)))
+#define L3_CAR		(*((volatile Word *) SA1111_p2v (_L3_CAR)))
+#define L3_CDR		(*((volatile Word *) SA1111_p2v (_L3_CDR)))
+#define ACCAR		(*((volatile Word *) SA1111_p2v (_ACCAR)))
+#define ACCDR		(*((volatile Word *) SA1111_p2v (_ACCDR)))
+#define ACSAR		(*((volatile Word *) SA1111_p2v (_ACSAR)))
+#define ACSDR		(*((volatile Word *) SA1111_p2v (_ACSDR)))
+#define SADTCS		(*((volatile Word *) SA1111_p2v (_SADTCS)))
+#define SADTSA		(*((volatile Word *) SA1111_p2v (_SADTSA)))
+#define SADTCA		(*((volatile Word *) SA1111_p2v (_SADTCA)))
+#define SADTSB		(*((volatile Word *) SA1111_p2v (_SADTSB)))
+#define SADTCB		(*((volatile Word *) SA1111_p2v (_SADTCB)))
+#define SADRCS		(*((volatile Word *) SA1111_p2v (_SADRCS)))
+#define SADRSA		(*((volatile Word *) SA1111_p2v (_SADRSA)))
+#define SADRCA		(*((volatile Word *) SA1111_p2v (_SADRCA)))
+#define SADRSB		(*((volatile Word *) SA1111_p2v (_SADRSB)))
+#define SADRCB		(*((volatile Word *) SA1111_p2v (_SADRCB)))
+#define SAITR		(*((volatile Word *) SA1111_p2v (_SAITR)))
+#define SADR		(*((volatile Word *) SA1111_p2v (_SADR)))
+
+#endif  /* LANGUAGE == C */
+
+#define SACR0_ENB	(1<<0)
+#define SACR0_BCKD	(1<<2)
+#define SACR0_RST	(1<<3)
+
+#define SACR1_AMSL	(1<<0)
+#define SACR1_L3EN	(1<<1)
+#define SACR1_L3MB	(1<<2)
+#define SACR1_DREC	(1<<3)
+#define SACR1_DRPL	(1<<4)
+#define SACR1_ENLBF	(1<<5)
+
+#define SACR2_TS3V	(1<<0)
+#define SACR2_TS4V	(1<<1)
+#define SACR2_WKUP	(1<<2)
+#define SACR2_DREC	(1<<3)
+#define SACR2_DRPL	(1<<4)
+#define SACR2_ENLBF	(1<<5)
+#define SACR2_RESET	(1<<5)
+
+#define SASR0_TNF	(1<<0)
+#define SASR0_RNE	(1<<1)
+#define SASR0_BSY	(1<<2)
+#define SASR0_TFS	(1<<3)
+#define SASR0_RFS	(1<<4)
+#define SASR0_TUR	(1<<5)
+#define SASR0_ROR	(1<<6)
+#define SASR0_L3WD	(1<<16)
+#define SASR0_L3RD	(1<<17)
+
+#define SASR1_TNF	(1<<0)
+#define SASR1_RNE	(1<<1)
+#define SASR1_BSY	(1<<2)
+#define SASR1_TFS	(1<<3)
+#define SASR1_RFS	(1<<4)
+#define SASR1_TUR	(1<<5)
+#define SASR1_ROR	(1<<6)
+#define SASR1_CADT	(1<<16)
+#define SASR1_SADR	(1<<17)
+#define SASR1_RSTO	(1<<18)
+#define SASR1_CLPM	(1<<19)
+#define SASR1_CRDY	(1<<20)
+#define SASR1_RS3V	(1<<21)
+#define SASR1_RS4V	(1<<22)
+
+#define SASCR_TUR	(1<<5)
+#define SASCR_ROR	(1<<6)
+#define SASCR_DTS	(1<<16)
+#define SASCR_RDD	(1<<17)
+#define SASCR_STO	(1<<18)
+
+#define SADTCS_TDEN	(1<<0)
+#define SADTCS_TDIE	(1<<1)
+#define SADTCS_TDBDA	(1<<3)
+#define SADTCS_TDSTA	(1<<4)
+#define SADTCS_TDBDB	(1<<5)
+#define SADTCS_TDSTB	(1<<6)
+#define SADTCS_TBIU	(1<<7)
+
+#define SADRCS_RDEN	(1<<0)
+#define SADRCS_RDIE	(1<<1)
+#define SADRCS_RDBDA	(1<<3)
+#define SADRCS_RDSTA	(1<<4)
+#define SADRCS_RDBDB	(1<<5)
+#define SADRCS_RDSTB	(1<<6)
+#define SADRCS_RBIU	(1<<7)
+
+#define SAD_CS_DEN	(1<<0)
+#define SAD_CS_DIE	(1<<1)	/* Not functional on metal 1 */
+#define SAD_CS_DBDA	(1<<3)	/* Not functional on metal 1 */
+#define SAD_CS_DSTA	(1<<4)
+#define SAD_CS_DBDB	(1<<5)	/* Not functional on metal 1 */
+#define SAD_CS_DSTB	(1<<6)
+#define SAD_CS_BIU	(1<<7)	/* Not functional on metal 1 */
+
+#define SAITR_TFS	(1<<0)
+#define SAITR_RFS	(1<<1)
+#define SAITR_TUR	(1<<2)
+#define SAITR_ROR	(1<<3)
+#define SAITR_CADT	(1<<4)
+#define SAITR_SADR	(1<<5)
+#define SAITR_RSTO	(1<<6)
+#define SAITR_TDBDA	(1<<8)
+#define SAITR_TDBDB	(1<<9)
+#define SAITR_RDBDA	(1<<10)
+#define SAITR_RDBDB	(1<<11)
+
 /*
  * General-Purpose I/O Interface
  *
@@ -211,6 +408,154 @@
 #define WAKE_EN1	(*((volatile Word *) SA1111_p2v (_WAKE_EN1)))
 #define WAKE_POL0	(*((volatile Word *) SA1111_p2v (_WAKE_POL0)))
 #define WAKE_POL1	(*((volatile Word *) SA1111_p2v (_WAKE_POL1)))
+
+#endif  /* LANGUAGE == C */
+
+/*
+ * PS/2 Trackpad and Mouse Interfaces
+ *
+ * Registers   (prefix kbd applies to trackpad interface, mse to mouse)
+ *    KBDCR     Control Register
+ *    KBDSTAT       Status Register
+ *    KBDDATA       Transmit/Receive Data register
+ *    KBDCLKDIV     Clock Division Register
+ *    KBDPRECNT     Clock Precount Register
+ *    KBDTEST1      Test register 1
+ *    KBDTEST2      Test register 2
+ *    KBDTEST3      Test register 3
+ *    KBDTEST4      Test register 4
+ *    MSECR
+ *    MSESTAT
+ *    MSEDATA
+ *    MSECLKDIV
+ *    MSEPRECNT
+ *    MSETEST1
+ *    MSETEST2
+ *    MSETEST3
+ *    MSETEST4
+ *
+ */
+
+#define _KBD( x )   _SA1111( 0x0A00 )
+#define _MSE( x )   _SA1111( 0x0C00 )
+
+#define _KBDCR      _SA1111( 0x0A00 )
+#define _KBDSTAT    _SA1111( 0x0A04 )
+#define _KBDDATA    _SA1111( 0x0A08 )
+#define _KBDCLKDIV  _SA1111( 0x0A0C )
+#define _KBDPRECNT  _SA1111( 0x0A10 )
+#define _MSECR      _SA1111( 0x0C00 )
+#define _MSESTAT    _SA1111( 0x0C04 )
+#define _MSEDATA    _SA1111( 0x0C08 )
+#define _MSECLKDIV  _SA1111( 0x0C10 )
+#define _MSEPRECNT  _SA1111( 0x0C14 )
+
+#if ( LANGUAGE == C )
+
+#define KBDCR       (*((volatile Word *) SA1111_p2v (_KBDCR)))
+#define KBDSTAT     (*((volatile Word *) SA1111_p2v (_KBDSTAT)))
+#define KBDDATA     (*((volatile Word *) SA1111_p2v (_KBDDATA)))
+#define KBDCLKDIV   (*((volatile Word *) SA1111_p2v (_KBDCLKDIV)))
+#define KBDPRECNT   (*((volatile Word *) SA1111_p2v (_KBDPRECNT)))
+#define KBDTEST1    (*((volatile Word *) SA1111_p2v (_KBDTEST1)))
+#define KBDTEST2    (*((volatile Word *) SA1111_p2v (_KBDTEST2)))
+#define KBDTEST3    (*((volatile Word *) SA1111_p2v (_KBDTEST3)))
+#define KBDTEST4    (*((volatile Word *) SA1111_p2v (_KBDTEST4)))
+#define MSECR       (*((volatile Word *) SA1111_p2v (_MSECR)))
+#define MSESTAT     (*((volatile Word *) SA1111_p2v (_MSESTAT)))
+#define MSEDATA     (*((volatile Word *) SA1111_p2v (_MSEDATA)))
+#define MSECLKDIV   (*((volatile Word *) SA1111_p2v (_MSECLKDIV)))
+#define MSEPRECNT   (*((volatile Word *) SA1111_p2v (_MSEPRECNT)))
+#define MSETEST1    (*((volatile Word *) SA1111_p2v (_MSETEST1)))
+#define MSETEST2    (*((volatile Word *) SA1111_p2v (_MSETEST2)))
+#define MSETEST3    (*((volatile Word *) SA1111_p2v (_MSETEST3)))
+#define MSETEST4    (*((volatile Word *) SA1111_p2v (_MSETEST4)))
+
+#define KBDCR_ENA        0x08
+#define KBDCR_FKD        0x02
+#define KBDCR_FKC        0x01
+
+#define KBDSTAT_TXE      0x80
+#define KBDSTAT_TXB      0x40
+#define KBDSTAT_RXF      0x20
+#define KBDSTAT_RXB      0x10
+#define KBDSTAT_ENA      0x08
+#define KBDSTAT_RXP      0x04
+#define KBDSTAT_KBD      0x02
+#define KBDSTAT_KBC      0x01
+
+#define KBDCLKDIV_DivVal     Fld(4,0)
+
+#define MSECR_ENA        0x08
+#define MSECR_FKD        0x02
+#define MSECR_FKC        0x01
+
+#define MSESTAT_TXE      0x80
+#define MSESTAT_TXB      0x40
+#define MSESTAT_RXF      0x20
+#define MSESTAT_RXB      0x10
+#define MSESTAT_ENA      0x08
+#define MSESTAT_RXP      0x04
+#define MSESTAT_MSD      0x02
+#define MSESTAT_MSC      0x01
+
+#define MSECLKDIV_DivVal     Fld(4,0)
+
+#define KBDTEST1_CD      0x80
+#define KBDTEST1_RC1         0x40
+#define KBDTEST1_MC      0x20
+#define KBDTEST1_C       Fld(2,3)
+#define KBDTEST1_T2      0x40
+#define KBDTEST1_T1      0x20
+#define KBDTEST1_T0      0x10
+#define KBDTEST2_TICBnRES    0x08
+#define KBDTEST2_RKC         0x04
+#define KBDTEST2_RKD         0x02
+#define KBDTEST2_SEL         0x01
+#define KBDTEST3_ms_16       0x80
+#define KBDTEST3_us_64       0x40
+#define KBDTEST3_us_16       0x20
+#define KBDTEST3_DIV8        0x10
+#define KBDTEST3_DIn         0x08
+#define KBDTEST3_CIn         0x04
+#define KBDTEST3_KD      0x02
+#define KBDTEST3_KC      0x01
+#define KBDTEST4_BC12        0x80
+#define KBDTEST4_BC11        0x40
+#define KBDTEST4_TRES        0x20
+#define KBDTEST4_CLKOE       0x10
+#define KBDTEST4_CRES        0x08
+#define KBDTEST4_RXB         0x04
+#define KBDTEST4_TXB         0x02
+#define KBDTEST4_SRX         0x01
+
+#define MSETEST1_CD      0x80
+#define MSETEST1_RC1         0x40
+#define MSETEST1_MC      0x20
+#define MSETEST1_C       Fld(2,3)
+#define MSETEST1_T2      0x40
+#define MSETEST1_T1      0x20
+#define MSETEST1_T0      0x10
+#define MSETEST2_TICBnRES    0x08
+#define MSETEST2_RKC         0x04
+#define MSETEST2_RKD         0x02
+#define MSETEST2_SEL         0x01
+#define MSETEST3_ms_16       0x80
+#define MSETEST3_us_64       0x40
+#define MSETEST3_us_16       0x20
+#define MSETEST3_DIV8        0x10
+#define MSETEST3_DIn         0x08
+#define MSETEST3_CIn         0x04
+#define MSETEST3_KD      0x02
+#define MSETEST3_KC      0x01
+#define MSETEST4_BC12        0x80
+#define MSETEST4_BC11        0x40
+#define MSETEST4_TRES        0x20
+#define MSETEST4_CLKOE       0x10
+#define MSETEST4_CRES        0x08
+#define MSETEST4_RXB         0x04
+#define MSETEST4_TXB         0x02
+#define MSETEST4_SRX         0x01
 
 #endif  /* LANGUAGE == C */
 
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-sa1100/graphicsclient.h linux/include/asm-arm/arch-sa1100/graphicsclient.h
--- linux-2.4.2-pre1/include/asm-arm/arch-sa1100/graphicsclient.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/arch-sa1100/graphicsclient.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,88 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/graphicsclient.h
+ *
+ * Created 2000/06/11 by Nicolas Pitre <nico@cam.org>
+ * Modified 7/27/00 by Woojung <whuh@applieddata.net>
+ *
+ * This file contains the hardware specific definitions for the 
+ * ADS GraphicsClient/ThinClient boards.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#error "include <asm/hardware.h> instead"
+#endif
+
+
+#define ADS_CPLD_BASE		(0x10000000)
+#define ADS_p2v( x )		((x) - ADS_CPLD_BASE + 0xf0000000)
+#define ADS_v2p( x )		((x) - 0xf0000000 + ADS_CPLD_BASE)
+
+
+/* Parallel Port */
+
+#define _ADS_PPDR		0x10020000	/* parallel port data reg */
+#define _ADS_PPSR		0x10020004	/* parallel port status reg */
+
+
+/* PCMCIA */
+
+#define _ADS_CS_STATUS		0x10040000	/* PCMCIA status reg */
+#define ADS_CS_ST_A_READY	(1 << 0)	/* Socket A Card Ready */
+#define ADS_CS_ST_A_CD		(1 << 2)	/* Socket A Card Detect */
+#define ADS_CS_ST_A_BUSY	(1 << 4)	/* Socket A Card Busy */
+#define ADS_CS_ST_A_STS		(1 << 6)	/* Socket A Card STS */
+
+#define _ADS_CS_PR		0x10040004	/* PCMCIA Power/Reset */
+#define ADS_CS_PR_A_5V_POWER	(1 << 0)	/* Socket A Enable 5V Power */
+#define ADS_CS_PR_A_3V_POWER	(1 << 0)	/* Socket A Enable 3.3V Power */
+#define ADS_CS_PR_A_RESET		(1 << 2)	/* Socket A Reset */
+
+
+#define _ADS_SW_SWITCHES	0x10060000	/* Software Switches */
+
+
+/* Extra IRQ Controller */
+
+#define _ADS_INT_ST1		0x10080000	/* IRQ Status #1 */
+#define _ADS_INT_ST2		0x10080004	/* IRQ Status #2 */
+#define _ADS_INT_EN1		0x10080008	/* IRQ Enable #1 */
+#define _ADS_INT_EN2		0x1008000c	/* IRQ Enable #2 */
+
+/* Discrete Controller (AVR:Atmel AT90LS8535) */
+#define _ADS_AVR_REG		0x10080018
+
+/* On-Board Ethernet */
+
+#define _ADS_ETHERNET		0x100e0000	/* Ethernet */
+
+
+/* Extra UARTs */
+
+#define _ADS_UARTA		0x10100000	/* UART A */
+#define _ADS_UARTB		0x10120000	/* UART B */
+#define _ADS_UARTC		0x10140000	/* UART C */
+#define _ADS_UARTD		0x10160000	/* UART D */
+
+
+/* LEDs */
+
+#define ADS_LED0	GPIO_GPIO20		/* on-board D22 */
+#define ADS_LED1	GPIO_GPIO21		/* on-board D21 */
+#define ADS_LED2	GPIO_GPIO22		/* on-board D20 */
+#define ADS_LED3	GPIO_GPIO23		/* external */
+#define ADS_LED4	GPIO_GPIO24		/* external */
+#define ADS_LED5	GPIO_GPIO25		/* external */
+#define ADS_LED6	GPIO_GPIO26		/* external */
+#define ADS_LED7	GPIO_GPIO27		/* external */
+
+
+/* Virtual register addresses */
+
+#ifndef __ASSEMBLY__
+#define ADS_INT_ST1	(*((volatile u_char *) ADS_p2v(_ADS_INT_ST1)))
+#define ADS_INT_ST2	(*((volatile u_char *) ADS_p2v(_ADS_INT_ST2)))
+#define ADS_INT_EN1	(*((volatile u_char *) ADS_p2v(_ADS_INT_EN1)))
+#define ADS_INT_EN2	(*((volatile u_char *) ADS_p2v(_ADS_INT_EN2)))
+#define ADS_ETHERNET	((int) ADS_p2v(_ADS_ETHERNET))
+#define ADS_AVR_REG	(*((volatile u_char *) ADS_p2v(_ADS_AVR_REG)))
+#endif
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-sa1100/hardware.h linux/include/asm-arm/arch-sa1100/hardware.h
--- linux-2.4.2-pre1/include/asm-arm/arch-sa1100/hardware.h	Mon Sep 18 15:15:23 2000
+++ linux/include/asm-arm/arch-sa1100/hardware.h	Mon Dec  3 22:27:49 2001
@@ -80,6 +80,10 @@
  * Implementation specifics
  */
 
+#ifdef CONFIG_SA1100_PANGOLIN
+#include "pangolin.h"
+#endif
+
 #ifdef CONFIG_SA1100_ASSABET
 #include "assabet.h"
 #else
@@ -96,10 +100,6 @@
 
 #ifdef CONFIG_SA1100_BITSY
 #include "bitsy.h"
-#endif
-
-#if defined(CONFIG_SA1100_THINCLIENT)
-#include "thinclient.h"
 #endif
 
 #if defined(CONFIG_SA1100_GRAPHICSCLIENT)
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-sa1100/ide.h linux/include/asm-arm/arch-sa1100/ide.h
--- linux-2.4.2-pre1/include/asm-arm/arch-sa1100/ide.h	Mon Sep 18 15:15:23 2000
+++ linux/include/asm-arm/arch-sa1100/ide.h	Mon Dec  3 22:27:49 2001
@@ -15,10 +15,6 @@
 #include <asm/mach-types.h>
 
 
-#define PCMCIA_IO_0_BASE 0xe0000000
-#define PCMCIA_IO_1_BASE 0xe4000000
-
-
 /*
  * Set up a hw structure for a specified data port, control port and IRQ.
  * This should follow whatever the default interface uses.
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-sa1100/io.h linux/include/asm-arm/arch-sa1100/io.h
--- linux-2.4.2-pre1/include/asm-arm/arch-sa1100/io.h	Tue Jul 18 22:43:25 2000
+++ linux/include/asm-arm/arch-sa1100/io.h	Mon Dec  3 22:27:49 2001
@@ -16,45 +16,17 @@
  * We don't actually have real ISA nor PCI buses, but there is so many 
  * drivers out there that might just work if we fake them...
  */
-#define __io_pci(a)		(PCIO_BASE + (a))
+#define __io(a)			(PCIO_BASE + (a))
 #define __mem_pci(a)		((unsigned long)(a))
 #define __mem_isa(a)		((unsigned long)(a))
 
-#define __ioaddr(p)		__io_pci(p)
-
 /*
  * Generic virtual read/write
  */
-#define __arch_getb(a)		(*(volatile unsigned char *)(a))
-#define __arch_getl(a)		(*(volatile unsigned int  *)(a))
-
-extern __inline__ unsigned int __arch_getw(unsigned long a)
-{
-	unsigned int value;
-	__asm__ __volatile__("ldr%?h	%0, [%1, #0]	@ getw"
-		: "=&r" (value)
-		: "r" (a));
-	return value;
-}
-
-
-#define __arch_putb(v,a)	(*(volatile unsigned char *)(a) = (v))
-#define __arch_putl(v,a)	(*(volatile unsigned int  *)(a) = (v))
-
-extern __inline__ void __arch_putw(unsigned int value, unsigned long a)
-{
-	__asm__ __volatile__("str%?h	%0, [%1, #0]	@ putw"
-		: : "r" (value), "r" (a));
-}
-
-#define inb(p)			__arch_getb(__io_pci(p))
-#define inw(p)			__arch_getw(__io_pci(p))
-#define inl(p)			__arch_getl(__io_pci(p))
-
-#define outb(v,p)		__arch_putb(v,__io_pci(p))
-#define outw(v,p)		__arch_putw(v,__io_pci(p))
-#define outl(v,p)		__arch_putl(v,__io_pci(p))
+#define __arch_getw(a)		(*(volatile unsigned short *)(a))
+#define __arch_putw(v,a)	(*(volatile unsigned short *)(a) = (v))
 
-#define __arch_ioremap		__ioremap
+#define iomem_valid_addr(iomem,sz)	(1)
+#define iomem_to_phys(iomem)		(iomem)
 
 #endif
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-sa1100/irq.h linux/include/asm-arm/arch-sa1100/irq.h
--- linux-2.4.2-pre1/include/asm-arm/arch-sa1100/irq.h	Sun Aug 13 09:54:15 2000
+++ linux/include/asm-arm/arch-sa1100/irq.h	Mon Dec  3 22:27:49 2001
@@ -11,11 +11,14 @@
  *   17-02-1999	NP	empeg henry ugly hacks now in a separate file ;)
  *   11-08-1999	PD	SA1101 support added
  *   25-09-1999	RMK	Merged into main ARM tree, cleaned up
- *   12-05-2000 NP	IRQ dispatcher handler for GPIO 11 to 27.
+ *   12-05-2000 NP	IRQ dispatcher handler for GPIOs 11 to 27.
  *   26-05-2000 JD	SA-1111 support added
+ *   01-06-2000 NP	GraphicsClient external IRQ dispatcher
+ *   09-10-2000 NP	Fixed lost interrupts on GPIOs 11 to 27.
  */
 #include <linux/config.h>
 #include <asm/irq.h>
+#include <asm/hardware.h>
 #include <asm/mach-types.h>
 
 #define fixup_irq(x)	(x)
@@ -85,7 +88,7 @@
 		 * unmasked.  However, such situation should happen only
 		 * during the loop below.  Thus all IRQs which aren't 
 		 * enabled at this point are considered spurious.  Those 
-		 * are cleared but only de-activated if they happened twice.
+		 * are cleared but only de-activated if they happen twice.
 		 */
 		spurious = irq & ~GPIO_11_27_enabled;
 		if (spurious) {
@@ -114,20 +117,35 @@
 static void sa1100_mask_and_ack_GPIO11_27_irq(unsigned int irq)
 {
 	int mask = (1 << GPIO_11_27_IRQ(irq));
+	GPIO_11_27_spurious &= ~mask;
 	GPIO_11_27_enabled &= ~mask;
 	GEDR = mask;
 }
 
 static void sa1100_mask_GPIO11_27_irq(unsigned int irq)
 {
-	GPIO_11_27_enabled &= ~(1 << GPIO_11_27_IRQ(irq));
+	int mask = (1 << GPIO_11_27_IRQ(irq));
+	GPIO_11_27_spurious &= ~mask;
+	GPIO_11_27_enabled &= ~mask;
 }
 
 static void sa1100_unmask_GPIO11_27_irq(unsigned int irq)
 {
 	int mask = (1 << GPIO_11_27_IRQ(irq));
+	if (GPIO_11_27_spurious & mask) {
+		/* 
+		 * We don't want to miss an interrupt that would have occured
+		 * while it was masked.  Simulate it if it is the case.
+		 */
+		int state = GPLR;
+		if (((state & GPIO_IRQ_rising_edge) | 
+		     (~state & GPIO_IRQ_falling_edge)) & mask) {
+			do_IRQ(irq, NULL);
+			/* we are being called again from do_IRQ() so ... */
+			return;
+		}
+	}
 	GPIO_11_27_enabled |= mask;
-	GPIO_11_27_spurious &= ~mask;
 	GRER = (GRER & ~mask) | (GPIO_IRQ_rising_edge & mask);
 	GFER = (GFER & ~mask) | (GPIO_IRQ_falling_edge & mask);
 }
@@ -245,7 +263,7 @@
 #endif
 
 
-#if defined(CONFIG_SA1100_GRAPHICSCLIENT) || defined(CONFIG_SA1100_THINCLIENT)
+#if defined(CONFIG_SA1100_GRAPHICSCLIENT)
 
 /*
  * IRQ handler for the ThinClient/GraphicsClient external IRQ controller
@@ -399,8 +417,8 @@
 	}
 #endif
 
-#if defined(CONFIG_SA1100_GRAPHICSCLIENT) || defined(CONFIG_SA1100_THINCLIENT)
-	if( machine_is_graphicsclient()  || machine_is_thinclient() ){
+#if defined(CONFIG_SA1100_GRAPHICSCLIENT)
+	if( machine_is_graphicsclient() ){
 		/* disable all IRQs */
 		ADS_INT_EN1 = 0;
 		ADS_INT_EN2 = 0;
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-sa1100/irqs.h linux/include/asm-arm/arch-sa1100/irqs.h
--- linux-2.4.2-pre1/include/asm-arm/arch-sa1100/irqs.h	Mon Jun 19 17:59:35 2000
+++ linux/include/asm-arm/arch-sa1100/irqs.h	Mon Dec  3 22:27:49 2001
@@ -72,7 +72,7 @@
 #define	NR_IRQS		(IRQ_GPIO27 + 1)
 
 
-#if defined(CONFIG_SA1100_GRAPHICSCLIENT) || defined(CONFIG_SA1100_THINCLIENT)
+#if defined(CONFIG_SA1100_GRAPHICSCLIENT)
 #define ADS_EXT_IRQ(x)	(IRQ_GPIO27 + 1 + (x))
 #undef NR_IRQS
 #define NR_IRQS		(ADS_EXT_IRQ(15) + 1)
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-sa1100/memory.h linux/include/asm-arm/arch-sa1100/memory.h
--- linux-2.4.2-pre1/include/asm-arm/arch-sa1100/memory.h	Mon Sep 18 15:15:23 2000
+++ linux/include/asm-arm/arch-sa1100/memory.h	Mon Dec  3 22:27:49 2001
@@ -15,6 +15,12 @@
 #define TASK_SIZE_26	(0x04000000UL)
 
 /*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
+
+/*
  * Page offset: 3GB
  */
 #define PAGE_OFFSET	(0xc0000000UL)
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-sa1100/mmzone.h linux/include/asm-arm/arch-sa1100/mmzone.h
--- linux-2.4.2-pre1/include/asm-arm/arch-sa1100/mmzone.h	Mon Sep 18 15:15:23 2000
+++ linux/include/asm-arm/arch-sa1100/mmzone.h	Mon Dec  3 22:27:49 2001
@@ -41,11 +41,11 @@
  * Given a kernel address, find the home node of the underlying memory.
  */
 #define KVADDR_TO_NID(addr) \
-		(((unsigned long)(addr) & 0x18000000) >> 27)
+		(((unsigned long)(addr) - 0xc0000000) >> 27)
 
 /*
  * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
- * and returns the the mem_map of that node.
+ * and returns the mem_map of that node.
  */
 #define ADDR_TO_MAPBASE(kaddr) \
 			NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(kaddr)))
@@ -66,7 +66,12 @@
 	(ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr))
 
 /*
- * Didn't find the best way to validate a page pointer yet...
+ * VALID_PAGE returns a non-zero value if given page pointer is valid.
+ * This assumes all node's mem_maps are stored within the node they refer to.
  */
+#define VALID_PAGE(page) \
+({ unsigned int node = KVADDR_TO_NID(page); \
+   ( (node < 4) && \
+     ((unsigned)((page) - NODE_MEM_MAP(node)) < NODE_DATA(node)->node_size) ); \
+})
 
-#define VALID_PAGE(page)	(1)
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-sa1100/pangolin.h linux/include/asm-arm/arch-sa1100/pangolin.h
--- linux-2.4.2-pre1/include/asm-arm/arch-sa1100/pangolin.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/arch-sa1100/pangolin.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,22 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/pangolin.h
+ *
+ * Created 2000/08/25 by Murphy Chen <murphy@mail.dialogue.com.tw>
+ *
+ * This file contains the hardware specific definitions for Pangolin
+ *
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#error "include <asm/hardware.h> instead"
+#endif
+
+
+/* GPIOs for which the generic definition doesn't say much */
+#define GPIO_CF_BUS_ON		GPIO_GPIO (3)
+#define GPIO_CF_RESET		GPIO_GPIO (2)
+#define GPIO_CF_CD		GPIO_GPIO (22)
+#define GPIO_CF_IRQ		GPIO_GPIO (21)
+
+#define IRQ_GPIO_CF_IRQ		IRQ_GPIO21
+#define IRQ_GPIO_CF_CD		IRQ_GPIO22
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-sa1100/processor.h linux/include/asm-arm/arch-sa1100/processor.h
--- linux-2.4.2-pre1/include/asm-arm/arch-sa1100/processor.h	Wed Oct 20 16:29:08 1999
+++ linux/include/asm-arm/arch-sa1100/processor.h	Wed Dec 31 16:00:00 1969
@@ -1,28 +0,0 @@
-/*
- * linux/include/asm-arm/arch-sa1100/processor.h
- *
- * Copyright (c) 1996 Russell King.
- *
- * Changelog:
- *  10-09-1996	RMK	Created
- *  05-01-1999  HBF     Mods for SA1100
- *  21-09-1999  NP	SWAPPER_PG_DIR readjusted for SA1100
- */
-
-#ifndef __ASM_ARCH_PROCESSOR_H
-#define __ASM_ARCH_PROCESSOR_H
-
-/*
- * Bus types
- */
-#define EISA_bus 0
-#define EISA_bus__is_a_macro /* for versions in ksyms.c */
-#define MCA_bus 0
-#define MCA_bus__is_a_macro /* for versions in ksyms.c */
-
-/* This decides where the kernel will search for a free chunk of vm
- * space during mmap's.
- */
-#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
-
-#endif
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-sa1100/system.h linux/include/asm-arm/arch-sa1100/system.h
--- linux-2.4.2-pre1/include/asm-arm/arch-sa1100/system.h	Mon Sep 18 15:15:23 2000
+++ linux/include/asm-arm/arch-sa1100/system.h	Mon Dec  3 22:27:49 2001
@@ -24,13 +24,9 @@
 		/* Jump into ROM at address 0 */
 		cpu_reset(0);
 	} else {
-		/* Activate SA1100 watchdog and wait for the trigger... */
-		OSMR3 = OSCR + 3686400/2;	/* in 1/2 sec */
-		OWER |= OWER_WME;
-		OIER |= OIER_E3;
+		/* Use on-chip reset capability */
+		RSRR = RSRR_SWR;
 	}
 }
-
-#define arch_power_off()	do { } while (0)
 
 #endif
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-sa1100/thinclient.h linux/include/asm-arm/arch-sa1100/thinclient.h
--- linux-2.4.2-pre1/include/asm-arm/arch-sa1100/thinclient.h	Mon Sep 18 15:15:23 2000
+++ linux/include/asm-arm/arch-sa1100/thinclient.h	Wed Dec 31 16:00:00 1969
@@ -1,89 +0,0 @@
-/*
- * linux/include/asm-arm/arch-sa1100/thinclient.h
- *
- * Created 2000/06/11 by Nicolas Pitre <nico@cam.org>
- *
- * This file contains the hardware specific definitions for the ADS
- * ThinClient/GraphicsClient boards.
- */
-
-#ifndef __ASM_ARCH_HARDWARE_H
-#error "include <asm/hardware.h> instead"
-#endif
-
-
-#define ADS_CPLD_BASE		(0x10000000)
-#define ADS_p2v( x )		((x) - ADS_CPLD_BASE + 0xf0000000)
-#define ADS_v2p( x )		((x) - 0xf0000000 + ADS_CPLD_BASE)
-
-
-/* Parallel Port */
-
-#define _ADS_PPDR		0x10020000	/* parallel port data reg */
-#define _ADS_PPSR		0x10020004	/* parallel port status reg */
-
-
-/* PCMCIA */
-
-#define _ADS_CS_STATUS		0x10040000	/* PCMCIA status reg */
-#define ADS_CS_ST_A_READY	(1 << 0)	/* Socket A Card Ready */
-#define ADS_CS_ST_B_READY	(1 << 1)	/* Socket B Card Ready */
-#define ADS_CS_ST_A_CD		(1 << 2)	/* Socket A Card Detect */
-#define ADS_CS_ST_B_CD		(1 << 3)	/* Socket B Card Detect */
-#define ADS_CS_ST_A_BUSY	(1 << 4)	/* Socket A Card Busy */
-#define ADS_CS_ST_B_BUSY	(1 << 5)	/* Socket B Card Busy */
-#define ADS_CS_ST_A_STS		(1 << 6)	/* Socket A Card STS */
-#define ADS_CS_ST_B_STS		(1 << 7)	/* Socket B Card STS */
-
-#define _ADS_CS_PR		0x10040004	/* PCMCIA Power/Reset */
-#define ADS_CS_PR_A_POWER	(1 << 0)	/* Socket A Enable Power */
-#define ADS_CS_PR_B_POWER	(1 << 1)	/* Socket B Enable Power */
-#define ADS_CS_PR_A_RESET	(1 << 2)	/* Socket A Reset */
-#define ADS_CS_PR_B_RESET	(1 << 3)	/* Socket B Reset */
-
-
-#define _ADS_SW_SWITCHES	0x10060000	/* Software Switches */
-
-
-/* Extra IRQ Controller */
-
-#define _ADS_INT_ST1		0x10080000	/* IRQ Status #1 */
-#define _ADS_INT_ST2		0x10080004	/* IRQ Status #2 */
-#define _ADS_INT_EN1		0x10080008	/* IRQ Enable #1 */
-#define _ADS_INT_EN2		0x1008000c	/* IRQ Enable #2 */
-
-
-/* On-Board Ethernet */
-
-#define _ADS_ETHERNET		0x100e0000	/* Ethernet */
-
-
-/* Extra UARTs */
-
-#define _ADS_UARTA		0x10100000	/* UART A */
-#define _ADS_UARTB		0x10120000	/* UART B */
-#define _ADS_UARTC		0x10140000	/* UART C */
-#define _ADS_UARTD		0x10160000	/* UART D */
-
-
-/* LEDs */
-
-#define ADS_LED0	GPIO_GPIO20		/* on-board D22 */
-#define ADS_LED1	GPIO_GPIO21		/* on-board D21 */
-#define ADS_LED2	GPIO_GPIO22		/* on-board D20 */
-#define ADS_LED3	GPIO_GPIO23		/* external */
-#define ADS_LED4	GPIO_GPIO24		/* external */
-#define ADS_LED5	GPIO_GPIO25		/* external */
-#define ADS_LED6	GPIO_GPIO26		/* external */
-#define ADS_LED7	GPIO_GPIO27		/* external */
-
-
-/* Virtual register addresses */
-
-#ifndef __ASSEMBLY__
-#define ADS_INT_ST1	(*((volatile u_char *) ADS_p2v(_ADS_INT_ST1)))
-#define ADS_INT_ST2	(*((volatile u_char *) ADS_p2v(_ADS_INT_ST2)))
-#define ADS_INT_EN1	(*((volatile u_char *) ADS_p2v(_ADS_INT_EN1)))
-#define ADS_INT_EN2	(*((volatile u_char *) ADS_p2v(_ADS_INT_EN2)))
-#define ADS_ETHERNET	((int) ADS_p2v(_ADS_ETHERNET))
-#endif
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-sa1100/uncompress.h linux/include/asm-arm/arch-sa1100/uncompress.h
--- linux-2.4.2-pre1/include/asm-arm/arch-sa1100/uncompress.h	Sun Aug 13 09:54:15 2000
+++ linux/include/asm-arm/arch-sa1100/uncompress.h	Mon Dec  3 22:27:49 2001
@@ -31,10 +31,12 @@
 			serial_port = (unsigned long *)_Ser3UTCR0;
 		else
 			serial_port = (unsigned long *)_Ser1UTCR0;
-	} else if (machine_is_brutus()||machine_is_nanoengine())
+	} else if (machine_is_brutus()||machine_is_nanoengine() ||
+		machine_is_pangolin())
 		serial_port = (unsigned long *)_Ser1UTCR0;
 	else if (machine_is_empeg() || machine_is_bitsy() ||
-		 machine_is_victor() || machine_is_lart())
+		 machine_is_victor() || machine_is_lart() ||
+		 machine_is_sherman() )
 		serial_port = (unsigned long *)_Ser3UTCR0;
 	else
 		return;
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-shark/io.h linux/include/asm-arm/arch-shark/io.h
--- linux-2.4.2-pre1/include/asm-arm/arch-shark/io.h	Mon Sep 18 15:15:23 2000
+++ linux/include/asm-arm/arch-shark/io.h	Mon Dec  3 22:27:49 2001
@@ -35,7 +35,7 @@
 	"tst	%2, #0x80000000\n\t"						\
 	"mov	%0, %4\n\t"							\
 	"addeq	%0, %0, %3\n\t"							\
-	"str" ##instr## "	%1, [%0, %2]	@ out"###fnsuffix	\
+	"str" instr "	%1, [%0, %2]	@ out" #fnsuffix			\
 	: "=&r" (temp)								\
 	: "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)	\
 	: "cc");								\
@@ -49,7 +49,7 @@
 	"tst	%2, #0x80000000\n\t"						\
 	"mov	%0, %4\n\t"							\
 	"addeq	%0, %0, %3\n\t"							\
-	"ldr" ##instr## "	%1, [%0, %2]	@ in"###fnsuffix	\
+	"ldr" instr "	%1, [%0, %2]	@ in" #fnsuffix				\
 	: "=&r" (temp), "=r" (value)						\
 	: "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)		\
 	: "cc");								\
@@ -181,13 +181,8 @@
 #define outw(v,p)	(__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))
 #define outl(v,p)	(__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
 
-#define __arch_getb(addr)	(*(volatile unsigned char *)(addr))
 #define __arch_getw(addr)	(*(volatile unsigned short *)(addr))
-#define __arch_getl(addr)	(*(volatile unsigned long *)(addr))
-
-#define __arch_putb(b,addr)	(*(volatile unsigned char *)(addr) = (b))
 #define __arch_putw(b,addr)	(*(volatile unsigned short *)(addr) = (b))
-#define __arch_putl(b,addr)	(*(volatile unsigned long *)(addr) = (b))
 
 /*
  * Translated address IO functions
diff -urN linux-2.4.2-pre1/include/asm-arm/arch-tbox/io.h linux/include/asm-arm/arch-tbox/io.h
--- linux-2.4.2-pre1/include/asm-arm/arch-tbox/io.h	Mon Sep 18 15:15:23 2000
+++ linux/include/asm-arm/arch-tbox/io.h	Mon Dec  3 22:27:49 2001
@@ -10,14 +10,11 @@
 
 #define IO_SPACE_LIMIT 0xffffffff
 
-#define __io_pc(_x)	((_x) << 2)
+#define __io(_x)		((_x) << 2)
 
 /*
  * Generic virtual read/write
  */
-#define __arch_getb(a)		(*(volatile unsigned char *)(a))
-#define __arch_getl(a)		(*(volatile unsigned long *)(a))
-
 extern __inline__ unsigned int __arch_getw(unsigned long a)
 {
 	unsigned int value;
@@ -27,23 +24,11 @@
 	return value;
 }
 
-
-#define __arch_putb(v,a)	(*(volatile unsigned char *)(a) = (v))
-#define __arch_putl(v,a)	(*(volatile unsigned long *)(a) = (v))
-
 extern __inline__ void __arch_putw(unsigned int value, unsigned long a)
 {
 	__asm__ __volatile__("str%?h	%0, [%1, #0]	@ putw"
 		: : "r" (value), "r" (a));
 }
-
-#define inb(p)			__arch_getb(__io_pc(p))
-#define inw(p)			__arch_getw(__io_pc(p))
-#define inl(p)			__arch_getl(__io_pc(p))
-
-#define outb(v,p)		__arch_putb(v,__io_pc(p))
-#define outw(v,p)		__arch_putw(v,__io_pc(p))
-#define outl(v,p)		__arch_putl(v,__io_pc(p))
 
 /* Idem, for devices on the upper byte lanes */
 #define inb_u(p)		__arch_getb(__io_pc(p) + 2)
diff -urN linux-2.4.2-pre1/include/asm-arm/ecard.h linux/include/asm-arm/ecard.h
--- linux-2.4.2-pre1/include/asm-arm/ecard.h	Sat May  8 11:06:57 1999
+++ linux/include/asm-arm/ecard.h	Mon Dec  3 22:27:49 2001
@@ -41,8 +41,8 @@
 #define PROD_MORLEY_SCSI_UNCACHED	0x0067
 
 #define MANU_CUMANA		0x003a
-#define PROD_CUMANA_SCSI_1		0x00a0
 #define PROD_CUMANA_SCSI_2		0x003a
+#define PROD_CUMANA_SCSI_1		0x00a0
 
 #define MANU_ICS		0x003c
 #define PROD_ICS_IDE			0x00ae
@@ -59,6 +59,7 @@
 #define PROD_I3_ETHERLAN600A		0x011e
 
 #define MANU_ANT		0x0053
+#define PROD_ANT_ETHERM			0x00d8
 #define PROD_ANT_ETHERB			0x00e4
 
 #define MANU_ALSYSTEMS		0x005b
diff -urN linux-2.4.2-pre1/include/asm-arm/fiq.h linux/include/asm-arm/fiq.h
--- linux-2.4.2-pre1/include/asm-arm/fiq.h	Sat May  8 11:06:57 1999
+++ linux/include/asm-arm/fiq.h	Mon Dec  3 22:27:49 2001
@@ -31,5 +31,7 @@
 extern void set_fiq_handler(void *start, unsigned int length);
 extern void set_fiq_regs(struct pt_regs *regs);
 extern void get_fiq_regs(struct pt_regs *regs);
+extern void enable_fiq(int fiq);
+extern void disable_fiq(int fiq);
 
 #endif
diff -urN linux-2.4.2-pre1/include/asm-arm/io.h linux/include/asm-arm/io.h
--- linux-2.4.2-pre1/include/asm-arm/io.h	Mon Sep 18 15:15:23 2000
+++ linux/include/asm-arm/io.h	Mon Dec  3 22:27:49 2001
@@ -20,10 +20,43 @@
 #ifndef __ASM_ARM_IO_H
 #define __ASM_ARM_IO_H
 
+#ifdef __KERNEL__
+
 #include <linux/types.h>
+#include <asm/memory.h>
 #include <asm/arch/hardware.h>
+
+/*
+ * Generic virtual read/write.  Note that we don't support half-word
+ * read/writes.  We define __arch_*[bl] here, and leave __arch_*w
+ * to the architecture specific code.
+ */
+#define __arch_getb(a)		(*(volatile unsigned char *)(a))
+#define __arch_getl(a)		(*(volatile unsigned int  *)(a))
+
+#define __arch_putb(v,a)	(*(volatile unsigned char *)(a) = (v))
+#define __arch_putl(v,a)	(*(volatile unsigned int  *)(a) = (v))
+
+/*
+ * Now, pick up the machine-defined IO definitions
+ */
 #include <asm/arch/io.h>
 
+/*
+ * IO definitions.  We define {out,in}[bwl] if __io is defined by
+ * the machine.  Otherwise, these definitions are left for the
+ * machine specific header files to pick up.
+ */
+#ifdef __io
+#define outb(v,p)			__arch_putb(v,__io(p))
+#define outw(v,p)			__arch_putw(v,__io(p))
+#define outl(v,p)			__arch_putl(v,__io(p))
+
+#define inb(p)				__arch_getb(__io(p))
+#define inw(p)				__arch_getw(__io(p))
+#define inl(p)				__arch_getl(__io(p))
+#endif
+
 #define outb_p(val,port)		outb((val),(port))
 #define outw_p(val,port)		outw((val),(port))
 #define outl_p(val,port)		outl((val),(port))
@@ -45,19 +78,34 @@
 #define insw_p(port,to,len)		insw(port,to,len)
 #define insl_p(port,to,len)		insl(port,to,len)
 
-#ifdef __KERNEL__
-
-#include <asm/memory.h>
-
-/* the following macro is depreciated */
-#define ioaddr(port)			__ioaddr((port))
-
 /*
- * ioremap and friends
+ * ioremap and friends.
+ *
+ * ioremap takes a PCI memory address, as specified in
+ * linux/Documentation/IO-mapping.txt.  If you want a
+ * physical address, use __ioremap instead.
  */
 extern void * __ioremap(unsigned long offset, size_t size, unsigned long flags);
 extern void __iounmap(void *addr);
 
+/*
+ * Generic ioremap support.
+ *
+ * Define:
+ *  iomem_valid_addr(off,size)
+ *  iomem_to_phys(off)
+ */
+#ifdef iomem_valid_addr
+#define __arch_ioremap(off,sz,nocache)				\
+ ({								\
+	unsigned long _off = (off), _size = (sz);		\
+	void *_ret = (void *)0;					\
+	if (iomem_valid_addr(_off, _size))			\
+		_ret = __ioremap(iomem_to_phys(_off),_size,0);	\
+	_ret;							\
+ })
+#endif
+
 #define ioremap(off,sz)			__arch_ioremap((off),(sz),0)
 #define ioremap_nocache(off,sz)		__arch_ioremap((off),(sz),1)
 #define iounmap(_addr)			__iounmap(_addr)
@@ -72,7 +120,26 @@
 extern void consistent_free(void *vaddr);
 extern void consistent_sync(void *vaddr, size_t size, int rw);
 
-extern void __readwrite_bug(const char *fn);
+#define __raw_writeb(v,a)		__arch_putb(v,a)
+#define __raw_writew(v,a)		__arch_putw(v,a)
+#define __raw_writel(v,a)		__arch_putl(v,a)
+
+#define __raw_readb(a)			__arch_getb(a)
+#define __raw_readw(a)			__arch_getw(a)
+#define __raw_readl(a)			__arch_getl(a)
+
+/*
+ * The compiler seems to be incapable of optimising constants
+ * properly.  Spell it out to the compiler in some cases.
+ * These are only valid for small values of "off" (< 1<<12)
+ */
+#define __raw_base_writeb(val,base,off)	__arch_base_putb(val,base,off)
+#define __raw_base_writew(val,base,off)	__arch_base_putw(val,base,off)
+#define __raw_base_writel(val,base,off)	__arch_base_putl(val,base,off)
+
+#define __raw_base_readb(base,off)	__arch_base_getb(base,off)
+#define __raw_base_readw(base,off)	__arch_base_getw(base,off)
+#define __raw_base_readl(base,off)	__arch_base_getl(base,off)
 
 /*
  * String version of IO memory access ops:
@@ -81,26 +148,21 @@
 extern void _memcpy_toio(unsigned long, const void *, size_t);
 extern void _memset_io(unsigned long, int, size_t);
 
-#define __raw_writeb(val,addr)		__arch_putb(val,addr)
-#define __raw_writew(val,addr)		__arch_putw(val,addr)
-#define __raw_writel(val,addr)		__arch_putl(val,addr)
-
-#define __raw_readb(addr)		__arch_getb(addr)
-#define __raw_readw(addr)		__arch_getw(addr)
-#define __raw_readl(addr)		__arch_getl(addr)
+extern void __readwrite_bug(const char *fn);
 
 /*
  * If this architecture has PCI memory IO, then define the read/write
- * macros.
+ * macros.  These should only be used with the cookie passed from
+ * ioremap.
  */
 #ifdef __mem_pci
 
-#define readb(addr)			__arch_getb(__mem_pci(addr))
-#define readw(addr)			__arch_getw(__mem_pci(addr))
-#define readl(addr)			__arch_getl(__mem_pci(addr))
-#define writeb(val,addr)		__arch_putb(val,__mem_pci(addr))
-#define writew(val,addr)		__arch_putw(val,__mem_pci(addr))
-#define writel(val,addr)		__arch_putl(val,__mem_pci(addr))
+#define readb(addr)			__raw_readb(__mem_pci(addr))
+#define readw(addr)			__raw_readw(__mem_pci(addr))
+#define readl(addr)			__raw_readl(__mem_pci(addr))
+#define writeb(val,addr)		__raw_writeb(val,__mem_pci(addr))
+#define writew(val,addr)		__raw_writew(val,__mem_pci(addr))
+#define writel(val,addr)		__raw_writel(val,__mem_pci(addr))
 
 #define memset_io(a,b,c)		_memset_io(__mem_pci(a),(b),(c))
 #define memcpy_fromio(a,b,c)		_memcpy_fromio((a),__mem_pci(b),(c))
@@ -142,17 +204,25 @@
 #endif	/* __mem_pci */
 
 /*
+ * remap a physical address `phys' of size `size' with page protection `prot'
+ * into virtual address `from'
+ */
+#define io_remap_page_range(from,phys,size,prot) \
+		remap_page_range(from,phys,size,prot)
+
+
+/*
  * If this architecture has ISA IO, then define the isa_read/isa_write
  * macros.
  */
 #ifdef __mem_isa
 
-#define isa_readb(addr)			__arch_getb(__mem_isa(addr))
-#define isa_readw(addr)			__arch_getw(__mem_isa(addr))
-#define isa_readl(addr)			__arch_getl(__mem_isa(addr))
-#define isa_writeb(val,addr)		__arch_putb(val,__mem_isa(addr))
-#define isa_writew(val,addr)		__arch_putw(val,__mem_isa(addr))
-#define isa_writel(val,addr)		__arch_putl(val,__mem_isa(addr))
+#define isa_readb(addr)			__raw_readb(__mem_isa(addr))
+#define isa_readw(addr)			__raw_readw(__mem_isa(addr))
+#define isa_readl(addr)			__raw_readl(__mem_isa(addr))
+#define isa_writeb(val,addr)		__raw_writeb(val,__mem_isa(addr))
+#define isa_writew(val,addr)		__raw_writew(val,__mem_isa(addr))
+#define isa_writel(val,addr)		__raw_writel(val,__mem_isa(addr))
 #define isa_memset_io(a,b,c)		_memset_io(__mem_isa(a),(b),(c))
 #define isa_memcpy_fromio(a,b,c)	_memcpy_fromio((a),__mem_isa(b),(c))
 #define isa_memcpy_toio(a,b,c)		_memcpy_toio(__mem_isa((a)),(b),(c))
diff -urN linux-2.4.2-pre1/include/asm-arm/ioctls.h linux/include/asm-arm/ioctls.h
--- linux-2.4.2-pre1/include/asm-arm/ioctls.h	Thu Feb 12 16:25:04 1998
+++ linux/include/asm-arm/ioctls.h	Mon Dec  3 22:27:49 2001
@@ -65,6 +65,7 @@
 
 #define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
 #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+#define FIOQSIZE	0x545E
 
 /* Used for packet mode */
 #define TIOCPKT_DATA		 0
diff -urN linux-2.4.2-pre1/include/asm-arm/linux_logo.h linux/include/asm-arm/linux_logo.h
--- linux-2.4.2-pre1/include/asm-arm/linux_logo.h	Mon Sep 18 15:15:23 2000
+++ linux/include/asm-arm/linux_logo.h	Mon Dec  3 22:27:49 2001
@@ -32,9 +32,6 @@
 extern unsigned char linux_logo_blue[];
 extern unsigned char linux_logo[];
 extern unsigned char linux_logo_bw[];
-extern unsigned char linux_logo16_red[];
-extern unsigned char linux_logo16_green[];
-extern unsigned char linux_logo16_blue[];
 extern unsigned char linux_logo16[];
 extern unsigned char *linux_serial_image;
 
diff -urN linux-2.4.2-pre1/include/asm-arm/mach/arch.h linux/include/asm-arm/mach/arch.h
--- linux-2.4.2-pre1/include/asm-arm/mach/arch.h	Mon Sep 18 15:15:23 2000
+++ linux/include/asm-arm/mach/arch.h	Mon Dec  3 22:27:49 2001
@@ -12,35 +12,42 @@
  * The size of struct machine_desc
  *   (for assembler code)
  */
-#define SIZEOF_MACHINE_DESC	44
+#define SIZEOF_MACHINE_DESC	56
 
 #ifndef __ASSEMBLY__
 
+extern void setup_initrd(unsigned int start, unsigned int size);
+extern void setup_ramdisk(int doload, int prompt, int start, unsigned int rd_sz);
+
+struct tagtable;
+
 struct machine_desc {
 	/*
 	 * Note! The first four elements are used
 	 * by assembler code in head-armv.S
 	 */
-	unsigned int	nr;		/* architecture number	*/
-	unsigned int	phys_ram;	/* start of physical ram */
-	unsigned int	phys_io;	/* start of physical io	*/
-	unsigned int	virt_io;	/* start of virtual io	*/
-
-	const char	*name;		/* architecture name	*/
-	unsigned int	param_offset;	/* parameter page	*/
-
-	unsigned int	video_start;	/* start of video RAM	*/
-	unsigned int	video_end;	/* end of video RAM	*/
-
-	unsigned int	reserve_lp0 :1;	/* never has lp0	*/
-	unsigned int	reserve_lp1 :1;	/* never has lp1	*/
-	unsigned int	reserve_lp2 :1;	/* never has lp2	*/
-	unsigned int	broken_hlt  :1;	/* hlt is broken	*/
-	unsigned int	soft_reboot :1;	/* soft reboot		*/
-	void		(*fixup)(struct machine_desc *,
-				 struct param_struct *, char **,
-				 struct meminfo *);
-	void		(*map_io)(void);/* IO mapping function	*/
+	unsigned int		nr;		/* architecture number	*/
+	unsigned int		phys_ram;	/* start of physical ram */
+	unsigned int		phys_io;	/* start of physical io	*/
+	unsigned int		virt_io;	/* start of virtual io	*/
+
+	const char		*name;		/* architecture name	*/
+	unsigned int		param_offset;	/* parameter page	*/
+
+	unsigned int		video_start;	/* start of video RAM	*/
+	unsigned int		video_end;	/* end of video RAM	*/
+
+	unsigned int		reserve_lp0 :1;	/* never has lp0	*/
+	unsigned int		reserve_lp1 :1;	/* never has lp1	*/
+	unsigned int		reserve_lp2 :1;	/* never has lp2	*/
+	unsigned int		soft_reboot :1;	/* soft reboot		*/
+	const struct tagtable *	tagtable;	/* tag table		*/
+	int			tagsize;	/* tag table size	*/
+	void			(*fixup)(struct machine_desc *,
+					 struct param_struct *, char **,
+					 struct meminfo *);
+	void			(*map_io)(void);/* IO mapping function	*/
+	void			(*init_irq)(void);
 };
 
 /*
@@ -50,7 +57,7 @@
 #define MACHINE_START(_type,_name)		\
 const struct machine_desc __mach_desc_##_type	\
  __attribute__((__section__(".arch.info"))) = {	\
-	nr:		MACH_TYPE_##_type##,	\
+	nr:		MACH_TYPE_##_type,	\
 	name:		_name,
 
 #define MAINTAINER(n)
@@ -68,10 +75,9 @@
 	video_end:	_end,
 
 #define DISABLE_PARPORT(_n)			\
-	reserve_lp##_n##:	1,
+	reserve_lp##_n:	1,
 
-#define BROKEN_HLT				\
-	broken_hlt:	1,
+#define BROKEN_HLT /* unused */
 
 #define SOFT_REBOOT				\
 	soft_reboot:	1,
@@ -81,6 +87,9 @@
 
 #define MAPIO(_func)				\
 	map_io:		_func,
+
+#define INITIRQ(_func)				\
+	init_irq:	_func,
 
 #define MACHINE_END				\
 };
diff -urN linux-2.4.2-pre1/include/asm-arm/mach/irq.h linux/include/asm-arm/mach/irq.h
--- linux-2.4.2-pre1/include/asm-arm/mach/irq.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/mach/irq.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,41 @@
+/*
+ *  linux/include/asm-arm/mach/irq.h
+ *
+ *  Copyright (C) 1995-2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_ARM_MACH_IRQ_H
+#define __ASM_ARM_MACH_IRQ_H
+
+struct irqdesc {
+	unsigned int	 nomask   : 1;		/* IRQ does not mask in IRQ   */
+	unsigned int	 enabled  : 1;		/* IRQ is currently enabled   */
+	unsigned int	 triggered: 1;		/* IRQ has occurred	      */
+	unsigned int	 probing  : 1;		/* IRQ in use for a probe     */
+	unsigned int	 probe_ok : 1;		/* IRQ can be used for probe  */
+	unsigned int	 valid    : 1;		/* IRQ claimable	      */
+	unsigned int	 noautoenable : 1;	/* don't automatically enable IRQ */
+	unsigned int	 unused   :25;
+	void (*mask_ack)(unsigned int irq);	/* Mask and acknowledge IRQ   */
+	void (*mask)(unsigned int irq);		/* Mask IRQ		      */
+	void (*unmask)(unsigned int irq);	/* Unmask IRQ		      */
+	struct irqaction *action;
+	/*
+	 * IRQ lock detection
+	 */
+	unsigned int	 lck_cnt;
+	unsigned int	 lck_pc;
+	unsigned int	 lck_jif;
+};
+
+extern struct irqdesc irq_desc[];
+
+extern void (*init_arch_irq)(void);
+extern int setup_arm_irq(int, struct irqaction *);
+extern int get_fiq_list(char *);
+extern void init_FIQ(void);
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-arm/proc-armo/pgtable.h linux/include/asm-arm/proc-armo/pgtable.h
--- linux-2.4.2-pre1/include/asm-arm/proc-armo/pgtable.h	Mon Sep 18 15:15:24 2000
+++ linux/include/asm-arm/proc-armo/pgtable.h	Mon Dec  3 22:27:49 2001
@@ -96,4 +96,9 @@
 
 #define pte_alloc_kernel        pte_alloc
 
+/*
+ * We don't store cache state bits in the page table here.
+ */
+#define pgprot_noncached(prot)	(prot)
+
 #endif /* __ASM_PROC_PGTABLE_H */
diff -urN linux-2.4.2-pre1/include/asm-arm/proc-armv/pgtable.h linux/include/asm-arm/proc-armv/pgtable.h
--- linux-2.4.2-pre1/include/asm-arm/proc-armv/pgtable.h	Mon Sep 18 15:15:24 2000
+++ linux/include/asm-arm/proc-armv/pgtable.h	Mon Dec  3 22:27:49 2001
@@ -149,7 +149,7 @@
 #define pte_young(pte)			(pte_val(pte) & L_PTE_YOUNG)
 
 #define PTE_BIT_FUNC(fn,op)			\
-extern inline pte_t pte_##fn##(pte_t pte) { pte_val(pte) op##; return pte; }
+extern inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
 
 /*PTE_BIT_FUNC(rdprotect, &= ~L_PTE_USER);*/
 /*PTE_BIT_FUNC(mkread,    |= L_PTE_USER);*/
@@ -162,5 +162,10 @@
 PTE_BIT_FUNC(mkold,     &= ~L_PTE_YOUNG);
 PTE_BIT_FUNC(mkyoung,   |= L_PTE_YOUNG);
 PTE_BIT_FUNC(nocache,   &= ~L_PTE_CACHEABLE);
+
+/*
+ * Mark the prot value as uncacheable and unbufferable.
+ */
+#define pgprot_noncached(prot)	__pgprot(pgprot_val(prot) & ~(L_PTE_CACHEABLE | L_PTE_BUFFERABLE))
 
 #endif /* __ASM_PROC_PGTABLE_H */
diff -urN linux-2.4.2-pre1/include/asm-arm/setup.h linux/include/asm-arm/setup.h
--- linux-2.4.2-pre1/include/asm-arm/setup.h	Mon Sep 18 15:15:24 2000
+++ linux/include/asm-arm/setup.h	Mon Dec  3 22:27:49 2001
@@ -68,6 +68,143 @@
 };
 
 /*
+ * New idea - a list of tagged entries
+ */
+#define ATAG_NONE	0x00000000
+
+struct tag_header {
+	u32 size;
+	u32 tag;
+};
+
+#define ATAG_CORE	0x54410001
+
+struct tag_core {
+	u32 flags;		/* bit 0 = read-only */
+	u32 pagesize;
+	u32 rootdev;
+};
+
+#define ATAG_MEM		0x54410002
+
+struct tag_mem32 {
+	u32	size;
+	u32	start;
+};
+
+#define ATAG_VIDEOTEXT	0x54410003
+
+struct tag_videotext {
+	u8		x;
+	u8		y;
+	u16		video_page;
+	u8		video_mode;
+	u8		video_cols;
+	u16		video_ega_bx;
+	u8		video_lines;
+	u8		video_isvga;
+	u16		video_points;
+};
+
+#define ATAG_RAMDISK	0x54410004
+
+struct tag_ramdisk {
+	u32 flags;		/* b0 = load, b1 = prompt */
+	u32 size;
+	u32 start;
+};
+
+#define ATAG_INITRD	0x54410005
+
+struct tag_initrd {
+	u32 start;
+	u32 size;
+};
+
+#define ATAG_SERIAL	0x54410006
+
+struct tag_serialnr {
+	u32 low;
+	u32 high;
+};
+
+#define ATAG_REVISION	0x54410007
+
+struct tag_revision {
+	u32 rev;
+};
+
+#define ATAG_VIDEOLFB	0x54410008
+
+struct tag_videolfb {
+	u16		lfb_width;
+	u16		lfb_height;
+	u16		lfb_depth;
+	u16		lfb_linelength;
+	u32		lfb_base;
+	u32		lfb_size;
+	u8		red_size;
+	u8		red_pos;
+	u8		green_size;
+	u8		green_pos;
+	u8		blue_size;
+	u8		blue_pos;
+	u8		rsvd_size;
+	u8		rsvd_pos;
+};
+
+#define ATAG_CMDLINE	0x54410009
+
+struct tag_cmdline {
+	char	cmdline[1];
+};
+
+#define ATAG_ACORN	0x41000101
+
+struct tag_acorn {
+	u32 memc_control_reg;
+	u32 vram_pages;
+	u8 sounddefault;
+	u8 adfsdrives;
+};
+
+#define ATAG_MEMCLK	0x41000402
+
+struct tag_memclk {
+	u32 fmemclk;
+};
+
+struct tag {
+	struct tag_header hdr;
+	union {
+		struct tag_core		core;
+		struct tag_mem32	mem;
+		struct tag_videotext	videotext;
+		struct tag_ramdisk	ramdisk;
+		struct tag_initrd	initrd;
+		struct tag_serialnr	serialnr;
+		struct tag_revision	revision;
+		struct tag_videolfb	videolfb;
+		struct tag_cmdline	cmdline;
+
+		/*
+		 * Acorn specific
+		 */
+		struct tag_acorn	acorn;
+
+		/*
+		 * DC21285 specific
+		 */
+		struct tag_memclk	memclk;
+	} u;
+};
+
+struct tagtable {
+	u32 tag;
+	int (*parse)(const struct tag *);
+};
+
+/*
  * Memory map description
  */
 #define NR_BANKS 4
diff -urN linux-2.4.2-pre1/include/asm-cris/a.out.h linux/include/asm-cris/a.out.h
--- linux-2.4.2-pre1/include/asm-cris/a.out.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/a.out.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,31 @@
+#ifndef __CRIS_A_OUT_H__
+#define __CRIS_A_OUT_H__
+
+/* we don't support a.out binaries on Linux/CRIS anyway, so this is
+ * not really used but still needed because binfmt_elf.c for some reason
+ * wants to know about a.out even if there is no interpreter available...
+ */
+
+/* grabbed from the intel stuff  */   
+#define STACK_TOP TASK_SIZE
+
+
+struct exec
+{
+  unsigned long a_info;		/* Use macros N_MAGIC, etc for access */
+  unsigned a_text;		/* length of text, in bytes */
+  unsigned a_data;		/* length of data, in bytes */
+  unsigned a_bss;		/* length of uninitialized data area for file, in bytes */
+  unsigned a_syms;		/* length of symbol table data in file, in bytes */
+  unsigned a_entry;		/* start address */
+  unsigned a_trsize;		/* length of relocation info for text, in bytes */
+  unsigned a_drsize;		/* length of relocation info for data, in bytes */
+};
+
+
+#define N_TRSIZE(a)	((a).a_trsize)
+#define N_DRSIZE(a)	((a).a_drsize)
+#define N_SYMSIZE(a)	((a).a_syms)
+
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/atomic.h linux/include/asm-cris/atomic.h
--- linux-2.4.2-pre1/include/asm-cris/atomic.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/atomic.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,142 @@
+/* $Id: atomic.h,v 1.2 2000/07/13 16:51:57 bjornw Exp $ */
+
+#ifndef __ASM_CRIS_ATOMIC__
+#define __ASM_CRIS_ATOMIC__
+
+#include <asm/system.h>
+
+/*
+ * Atomic operations that C can't guarantee us.  Useful for
+ * resource counting etc..
+ */
+
+/*
+ * Make sure gcc doesn't try to be clever and move things around
+ * on us. We need to use _exactly_ the address the user gave us,
+ * not some alias that contains the same information.
+ */
+
+#define __atomic_fool_gcc(x) (*(struct { int a[100]; } *)x)
+
+typedef struct { int counter; } atomic_t;
+
+#define ATOMIC_INIT(i)  { (i) }
+
+#define atomic_read(v) ((v)->counter)
+#define atomic_set(v,i) (((v)->counter) = (i))
+
+/* These should be written in asm but we do it in C for now. */
+
+static __inline__ void atomic_add(int i, volatile atomic_t *v)
+{
+	unsigned long flags;
+	save_flags(flags);
+	cli();
+	v->counter += i;
+	restore_flags(flags);
+}
+
+static __inline__ void atomic_sub(int i, volatile atomic_t *v)
+{
+	unsigned long flags;
+	save_flags(flags);
+	cli();
+	v->counter -= i;
+	restore_flags(flags);
+}
+
+static __inline__ int atomic_add_return(int i, volatile atomic_t *v)
+{
+	unsigned long flags;
+	int retval;
+	save_flags(flags);
+	cli();
+	retval = (v->counter += i);
+	restore_flags(flags);
+	return retval;
+}
+
+static __inline__ int atomic_sub_return(int i, volatile atomic_t *v)
+{
+	unsigned long flags;
+	int retval;
+	save_flags(flags);
+	cli();
+	retval = (v->counter -= i);
+	restore_flags(flags);
+	return retval;
+}
+
+static __inline__ int atomic_sub_and_test(int i, volatile atomic_t *v)
+{
+	int retval;
+	unsigned long flags;
+	save_flags(flags);
+	cli();
+	retval = (v->counter -= i) == 0;
+	restore_flags(flags);
+	return retval;
+}
+
+static __inline__ void atomic_inc(volatile atomic_t *v)
+{
+	unsigned long flags;
+	save_flags(flags);
+	cli();
+	(v->counter)++;
+	restore_flags(flags);
+}
+
+static __inline__ void atomic_dec(volatile atomic_t *v)
+{
+	unsigned long flags;
+	save_flags(flags);
+	cli();
+	(v->counter)--;
+	restore_flags(flags);
+}
+
+static __inline__ int atomic_inc_return(volatile atomic_t *v)
+{
+	unsigned long flags;
+	int retval;
+	save_flags(flags);
+	cli();
+	retval = (v->counter)++;
+	restore_flags(flags);
+	return retval;
+}
+
+static __inline__ int atomic_dec_return(volatile atomic_t *v)
+{
+	unsigned long flags;
+	int retval;
+	save_flags(flags);
+	cli();
+	retval = (v->counter)--;
+	restore_flags(flags);
+	return retval;
+}
+static __inline__ int atomic_dec_and_test(volatile atomic_t *v)
+{
+	int retval;
+	unsigned long flags;
+	save_flags(flags);
+	cli();
+	retval = --(v->counter) == 0;
+	restore_flags(flags);
+	return retval;
+}
+
+static __inline__ int atomic_inc_and_test(volatile atomic_t *v)
+{
+	int retval;
+	unsigned long flags;
+	save_flags(flags);
+	cli();
+	retval = ++(v->counter) == 0;
+	restore_flags(flags);
+	return retval;
+}
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/axisflashmap.h linux/include/asm-cris/axisflashmap.h
--- linux-2.4.2-pre1/include/asm-cris/axisflashmap.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/axisflashmap.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,59 @@
+#ifndef __ASM_AXISFLASHMAP_H
+#define __ASM_AXISFLASHMAP_H
+
+/* Bootblock parameters are stored at 0xc000 and has the FLASH_BOOT_MAGIC 
+ * as start, it ends with 0xFFFFFFFF */
+#define FLASH_BOOT_MAGIC 0xbeefcace
+#define BOOTPARAM_OFFSET 0xc000
+/* apps/bootblocktool is used to read and write the parameters,
+ * and it has nothing to do with the partition table. 
+ */
+
+
+/* the partitiontable consists of some "jump over" code, a head and
+ * then the actual entries.
+ * tools/mkptable is used to generate the ptable. 
+ */
+
+/* The partition table start with kod to "jump over" it: */
+#define PARTITIONTABLE_CODE_START { \
+ 0x0f, 0x05, /* nop 0 */\
+ 0x25, 0xf0, /* di  2 */\
+ 0xed, 0xff  /* ba  4 */ }
+
+/* The actual offset depend on the number of entries */
+#define PARTITIONTABLE_CODE_END { \
+ 0x00, 0x00, /* ba offset 6 */\
+ 0x0f, 0x0f  /* nop 8 */}
+
+#define PARTITION_TABLE_OFFSET 10
+#define PARTITION_TABLE_MAGIC 0xbeef /* Not a good magic */
+
+/* The partitiontable_head is located at offset +10: */
+struct partitiontable_head {
+	__u16 magic; /* PARTITION_TABLE_MAGIC */ 
+	__u16 size;  /* Length of ptable block (not header) */
+	__u32 checksum; /* simple longword sum */
+};
+
+/* And followed by partition table entries */
+struct partitiontable_entry {
+	__u32 offset;   /* Offset is relative to the sector the ptable is in */
+	__u32 size;
+	__u32 checksum; /* simple longword sum */
+	__u16 type;
+	__u16 flags;   /* bit 0: ro/rw = 1/0 */
+	__u32 future0; /* 16 bytes reserved for future use */
+	__u32 future1;
+	__u32 future2;
+	__u32 future3;
+};
+/* ended by an end marker: */
+#define PARTITIONTABLE_END_MARKER 0xFFFFFFFF
+
+/*#define PARTITION_TYPE_RESCUE 0x0000?*/  /* Not used, maybe it should? */
+#define PARTITION_TYPE_PARAM  0x0001 /* Hmm.. */
+#define PARTITION_TYPE_KERNEL 0x0002
+#define PARTITION_TYPE_JFFS   0x0003
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/bitops.h linux/include/asm-cris/bitops.h
--- linux-2.4.2-pre1/include/asm-cris/bitops.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/bitops.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,184 @@
+/* $Id: bitops.h,v 1.3 2000/10/17 14:56:27 bjornw Exp $ */
+/* all of these should probably be rewritten in assembler for speed. */
+
+#ifndef _CRIS_BITOPS_H
+#define _CRIS_BITOPS_H
+
+#include <asm/system.h>
+
+/*
+ * These have to be done with inline assembly: that way the bit-setting
+ * is guaranteed to be atomic. All bit operations return 0 if the bit
+ * was cleared before the operation and != 0 if it was not.
+ *
+ * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
+ */
+
+/*
+ * Some hacks to defeat gcc over-optimizations..
+ */
+struct __dummy { unsigned long a[100]; };
+#define ADDR (*(struct __dummy *) addr)
+#define CONST_ADDR (*(const struct __dummy *) addr)
+
+#define set_bit(nr, addr)    (void)test_and_set_bit(nr, addr)
+#define clear_bit(nr, addr)  (void)test_and_clear_bit(nr, addr)
+#define change_bit(nr, addr) (void)test_and_change_bit(nr, addr)
+
+extern __inline__ int test_and_set_bit(int nr, void *addr)
+{
+	unsigned int mask, retval;
+	unsigned long flags;
+	unsigned int *adr = (unsigned int *)addr;
+	
+	adr += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_flags(flags);
+	cli();
+	retval = (mask & *adr) != 0;
+	*adr |= mask;
+	restore_flags(flags);
+	return retval;
+}
+
+/*
+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+#define smp_mb__before_clear_bit()      barrier()
+#define smp_mb__after_clear_bit()       barrier()
+
+extern __inline__ int test_and_clear_bit(int nr, void *addr)
+{
+	unsigned int mask, retval;
+	unsigned long flags;
+	unsigned int *adr = (unsigned int *)addr;
+	
+	adr += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_flags(flags);
+	cli();
+	retval = (mask & *adr) != 0;
+	*adr &= ~mask;
+	restore_flags(flags);
+	return retval;
+}
+
+extern __inline__ int test_and_change_bit(int nr, void *addr)
+{
+	unsigned int mask, retval;
+	unsigned long flags;
+	unsigned int *adr = (unsigned int *)addr;
+	adr += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_flags(flags);
+	cli();
+	retval = (mask & *adr) != 0;
+	*adr ^= mask;
+	restore_flags(flags);
+	return retval;
+}
+
+/*
+ * This routine doesn't need to be atomic.
+ */
+extern __inline__ int test_bit(int nr, const void *addr)
+{
+	unsigned int mask;
+	unsigned int *adr = (unsigned int *)addr;
+	
+	adr += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	return ((mask & *adr) != 0);
+}
+
+/*
+ * Find-bit routines..
+ */
+
+/*
+ * ffz = Find First Zero in word. Undefined if no zero exists,
+ * so code should check against ~0UL first..
+ */
+extern __inline__ unsigned long ffz(unsigned long word)
+{
+	unsigned long result = 0;
+	
+	while(word & 1) {
+		result++;
+		word >>= 1;
+	}
+	return result;
+}
+
+/*
+ * Find first one in word. Undefined if no one exists,
+ * so code should check against 0UL first..
+ */
+extern __inline__ unsigned long find_first_one(unsigned long word)
+{
+	unsigned long result = 0;
+	
+	while(!(word & 1)) {
+		result++;
+		word >>= 1;
+	}
+	return result;
+}
+
+extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
+{
+	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+	
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if (offset) {
+		tmp = *(p++);
+		tmp |= ~0UL >> (32-offset);
+		if (size < 32)
+			goto found_first;
+		if (~tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while (size & ~31UL) {
+		if (~(tmp = *(p++)))
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if (!size)
+		return result;
+	tmp = *p;
+	
+ found_first:
+	tmp |= ~0UL >> size;
+ found_middle:
+	return result + ffz(tmp);
+}
+
+#define find_first_zero_bit(addr, size) \
+        find_next_zero_bit((addr), (size), 0)
+
+#ifdef __KERNEL__ 
+
+#define ext2_set_bit                 test_and_set_bit
+#define ext2_clear_bit               test_and_clear_bit
+#define ext2_test_bit                test_bit
+#define ext2_find_first_zero_bit     find_first_zero_bit
+#define ext2_find_next_zero_bit      find_next_zero_bit
+
+/* Bitmap functions for the minix filesystem.  */
+#define minix_set_bit(nr,addr) test_and_set_bit(nr,addr)
+#define minix_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
+#define minix_test_bit(nr,addr) test_bit(nr,addr)
+#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
+
+#endif /* __KERNEL__ */
+
+
+#endif /* _CRIS_BITOPS_H */
diff -urN linux-2.4.2-pre1/include/asm-cris/bugs.h linux/include/asm-cris/bugs.h
--- linux-2.4.2-pre1/include/asm-cris/bugs.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/bugs.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,21 @@
+/* $Id: bugs.h,v 1.2 2001/01/17 17:03:18 bjornw Exp $
+ *
+ *  include/asm-cris/bugs.h
+ *
+ *  Copyright (C) 2001 Axis Communications AB
+ */
+
+/*
+ * This is included by init/main.c to check for architecture-dependent bugs.
+ *
+ * Needs:
+ *	void check_bugs(void);
+ */
+
+static void check_bugs(void)
+{
+}
+
+
+
+
diff -urN linux-2.4.2-pre1/include/asm-cris/byteorder.h linux/include/asm-cris/byteorder.h
--- linux-2.4.2-pre1/include/asm-cris/byteorder.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/byteorder.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,47 @@
+/* $Id: byteorder.h,v 1.1 2000/07/10 16:32:31 bjornw Exp $ */
+
+#ifndef _CRIS_BYTEORDER_H
+#define _CRIS_BYTEORDER_H
+
+#include <asm/types.h>
+
+#ifdef __GNUC__
+
+/* we just define these two (as we can do the swap in a single
+ * asm instruction in CRIS) and the arch-independent files will put
+ * them together into ntohl etc.
+ */
+
+static __inline__ __const__ __u32 ___arch__swab32(__u32 x)
+{
+	__asm__ ("swapwb %0" : "=r" (x) : "0" (x));
+  
+	return(x);
+}
+
+static __inline__ __const__ __u16 ___arch__swab16(__u16 x)
+{
+	__asm__ ("swapb %0" : "=r" (x) : "0" (x));
+	
+	return(x);
+}
+
+/* defines are necessary because the other files detect the presence
+ * of a defined __arch_swab32, not an inline
+ */
+
+#define __arch__swab32(x) ___arch__swab32(x)
+#define __arch__swab16(x) ___arch__swab16(x)
+
+#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#  define __BYTEORDER_HAS_U64__
+#  define __SWAB_64_THRU_32__
+#endif
+
+#endif /* __GNUC__ */
+
+#include <linux/byteorder/little_endian.h>
+
+#endif
+
+
diff -urN linux-2.4.2-pre1/include/asm-cris/cache.h linux/include/asm-cris/cache.h
--- linux-2.4.2-pre1/include/asm-cris/cache.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/cache.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,10 @@
+#ifndef _ASM_CACHE_H
+#define _ASM_CACHE_H
+
+/* Etrax 100LX have 32-byte cache-lines. When we add support for future chips
+ * here should be a check for CPU type.
+ */
+
+#define L1_CACHE_BYTES 32
+
+#endif /* _ASM_CACHE_H */
diff -urN linux-2.4.2-pre1/include/asm-cris/checksum.h linux/include/asm-cris/checksum.h
--- linux-2.4.2-pre1/include/asm-cris/checksum.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/checksum.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,119 @@
+/* $Id: checksum.h,v 1.3 2000/11/15 17:35:16 bjornw Exp $ */
+/* TODO: csum_tcpudp_magic could be speeded up, and csum_fold as well */
+
+#ifndef _CRIS_CHECKSUM_H
+#define _CRIS_CHECKSUM_H
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+unsigned int csum_partial_copy_nocheck(const char *src, char *dst,
+				       int len, unsigned int sum);
+
+/*
+ *	Fold a partial checksum into a word
+ */
+
+static inline unsigned int csum_fold(unsigned int sum)
+{
+	/* the while loop is unnecessary really, it's always enough with two
+	   iterations */
+	
+	while(sum >> 16)
+		sum = (sum & 0xffff) + (sum >> 16); /* add in end-around carry */
+	
+	return ~sum;
+}
+
+/* Checksum some values used in TCP/UDP headers.
+ *
+ * The gain by doing this in asm is that C will not generate carry-additions
+ * for the 32-bit components of the checksum, so otherwise we would have had
+ * to split all of those into 16-bit components, then add.
+ */
+
+static inline unsigned int
+csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len,
+		   unsigned short proto, unsigned int sum)
+{
+	int res;
+	__asm__ ("add.d %2, %0\n\t"
+		 "ax\n\t"
+		 "add.d %3, %0\n\t"
+		 "ax\n\t"
+		 "add.d %4, %0\n\t"
+		 "ax\n\t"
+		 "addq 0, %0\n"
+	: "=r" (res)
+	: "0" (sum), "r" (daddr), "r" (saddr), "r" ((ntohs(len) << 16) + (proto << 8)));
+
+	return res;
+}	
+
+
+/* TODO we need to write this properly to handle userland VM exceptions!! */
+
+#define csum_partial_copy_from_user(a,b,c,d,errptr) csum_partial_copy_nocheck(a,b,c,d)
+
+#if 0
+unsigned int csum_partial_copy_from_user(const char *src, char *dst,
+					int len, unsigned int sum);
+#endif
+
+
+
+/*
+ *	This is a version of ip_compute_csum() optimized for IP headers,
+ *	which always checksum on 4 octet boundaries.
+ *
+ */
+
+static inline unsigned short ip_fast_csum(unsigned char * iph,
+					  unsigned int ihl)
+{
+	return csum_fold(csum_partial(iph, ihl * 4, 0));
+}
+ 
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+
+static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
+						   unsigned long daddr,
+						   unsigned short len,
+						   unsigned short proto,
+						   unsigned int sum)
+{
+	return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+
+static inline unsigned short ip_compute_csum(unsigned char * buff, int len) {
+	return csum_fold (csum_partial(buff, len, 0));
+}
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/current.h linux/include/asm-cris/current.h
--- linux-2.4.2-pre1/include/asm-cris/current.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/current.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,15 @@
+#ifndef _CRIS_CURRENT_H
+#define _CRIS_CURRENT_H
+
+struct task_struct;
+
+static inline struct task_struct * get_current(void)
+{
+        struct task_struct *current;
+        __asm__("and.d sp,%0; ":"=r" (current) : "0" (~8191UL));
+        return current;
+ }
+ 
+#define current get_current()
+
+#endif /* !(_CRIS_CURRENT_H) */
diff -urN linux-2.4.2-pre1/include/asm-cris/delay.h linux/include/asm-cris/delay.h
--- linux-2.4.2-pre1/include/asm-cris/delay.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/delay.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,67 @@
+/* $Id: delay.h,v 1.2 2000/08/08 16:36:41 bjornw Exp $ */
+
+#ifndef _CRIS_DELAY_H
+#define _CRIS_DELAY_H
+
+/*
+ * Copyright (C) 1998, 1999, 2000 Axis Communications AB
+ *
+ * Delay routines, using a pre-computed "loops_per_second" value.
+ */
+
+#include <linux/config.h>
+#include <linux/linkage.h>
+
+#ifdef CONFIG_SMP
+#include <asm/smp.h>
+#endif 
+
+extern void __do_delay(void);	/* Special register call calling convention */
+
+extern __inline__ void __delay(int loops)
+{
+	/* need to be a great deal of nops, because Etrax shuts off IRQ's during a branch
+	   and we depend on the irq's to measure the time! */
+	
+	__asm__ __volatile__ (
+			      "move.d %0,r0\n"
+			      "1:\n\t"
+			      "nop\n\t"
+			      "nop\n\t"
+			      "nop\n\t"
+			      "nop\n\t"
+			      "nop\n\t"
+			      "nop\n\t"
+			      "nop\n\t"
+			      "subq 1,r0\n\t"
+			      "bne 1b\n\t"
+			      "nop\n\t"
+			      : : "r" (loops) : "r0", "cc");
+}
+
+
+/*
+ * Use only for very small delays ( < 1 msec).  Should probably use a
+ * lookup table, really, as the multiplications take much too long with
+ * short delays.  This is a "reasonable" implementation, though (and the
+ * first constant multiplications gets optimized away if the delay is
+ * a constant)
+ */
+
+extern unsigned long loops_per_usec; /* arch/cris/mm/init.c */
+
+extern __inline__ void udelay(unsigned long usecs)
+{
+	__delay(usecs * loops_per_usec);
+}
+
+extern __inline__ unsigned long muldiv(unsigned long a, unsigned long b, unsigned long c)
+{
+	printk("muldiv called!\n");
+	return 0;
+}
+
+#endif /* defined(_ETRAX_DELAY_H) */
+
+
+
diff -urN linux-2.4.2-pre1/include/asm-cris/div64.h linux/include/asm-cris/div64.h
--- linux-2.4.2-pre1/include/asm-cris/div64.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/div64.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,16 @@
+#ifndef __ASM_CRIS_DIV64
+#define __ASM_CRIS_DIV64
+
+/* copy from asm-arm */
+
+/* We're not 64-bit, but... */
+#define do_div(n,base)						\
+({								\
+	int __res;						\
+	__res = ((unsigned long)n) % (unsigned int)base;	\
+	n = ((unsigned long)n) / (unsigned int)base;		\
+	__res;							\
+})
+
+#endif
+
diff -urN linux-2.4.2-pre1/include/asm-cris/dma.h linux/include/asm-cris/dma.h
--- linux-2.4.2-pre1/include/asm-cris/dma.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/dma.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,21 @@
+/* $Id: dma.h,v 1.1 2000/07/10 16:32:31 bjornw Exp $
+ * linux/include/asm/dma.h: Defines for using and allocating dma channels.
+ */
+
+#ifndef _ASM_DMA_H
+#define _ASM_DMA_H
+
+/* it's useless on the Etrax, but unfortunately needed by the new
+   bootmem allocator (but this should do it for this) */
+
+#define MAX_DMA_ADDRESS PAGE_OFFSET
+
+/* TODO: check nbr of channels on Etrax-100LX */
+
+#define MAX_DMA_CHANNELS	10
+
+/* These are in kernel/dma.c: */
+extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */
+extern void free_dma(unsigned int dmanr);	                    /* release it */
+
+#endif /* _ASM_DMA_H */
diff -urN linux-2.4.2-pre1/include/asm-cris/elf.h linux/include/asm-cris/elf.h
--- linux-2.4.2-pre1/include/asm-cris/elf.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/elf.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,68 @@
+#ifndef __ASMCRIS_ELF_H
+#define __ASMCRIS_ELF_H
+
+/*
+ * ELF register definitions..
+ */
+
+#include <asm/ptrace.h>
+
+typedef unsigned long elf_greg_t;
+
+/* These probably need fixing.  */
+#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+/* A placeholder; CRIS does not have any fp regs.  */
+typedef unsigned long elf_fpregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ( (x)->e_machine == EM_CRIS )
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS	ELFCLASS32
+#define ELF_DATA	ELFDATA2LSB;
+#define ELF_ARCH	EM_CRIS
+
+	/* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program
+	   starts (a register; assume first param register for CRIS)
+	   contains a pointer to a function which might be
+	   registered using `atexit'.  This provides a mean for the
+	   dynamic linker to call DT_FINI functions for shared libraries
+	   that have been loaded before the code runs.
+
+	   A value of 0 tells we have no such handler.  */
+#define ELF_PLAT_INIT(_r)	((_r)->r10 = 0)
+
+#undef USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE	8192
+
+/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
+   use of this is to invoke "./ld.so someprog" to test out a new version of
+   the loader.  We need to make sure that it is out of the way of the program
+   that it will "exec", and that there is sufficient room for the brk.  */
+
+#define ELF_ET_DYN_BASE         (2 * TASK_SIZE / 3)
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this CPU supports.  This could be done in user space,
+   but it's not easy, and we've already done it here.  */
+
+#define ELF_HWCAP       (0)
+
+/* This yields a string that ld.so will use to load implementation
+   specific libraries for optimization.  This is more specific in
+   intent than poking at uname or /proc/cpuinfo.
+*/
+
+#define ELF_PLATFORM  (NULL)
+
+#ifdef __KERNEL__
+#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#endif
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/errno.h linux/include/asm-cris/errno.h
--- linux-2.4.2-pre1/include/asm-cris/errno.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/errno.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,134 @@
+/* verbatim copy of asm-i386/errno.h */
+
+#ifndef _CRIS_ERRNO_H
+#define _CRIS_ERRNO_H
+
+#define	EPERM		 1	/* Operation not permitted */
+#define	ENOENT		 2	/* No such file or directory */
+#define	ESRCH		 3	/* No such process */
+#define	EINTR		 4	/* Interrupted system call */
+#define	EIO		 5	/* I/O error */
+#define	ENXIO		 6	/* No such device or address */
+#define	E2BIG		 7	/* Arg list too long */
+#define	ENOEXEC		 8	/* Exec format error */
+#define	EBADF		 9	/* Bad file number */
+#define	ECHILD		10	/* No child processes */
+#define	EAGAIN		11	/* Try again */
+#define	ENOMEM		12	/* Out of memory */
+#define	EACCES		13	/* Permission denied */
+#define	EFAULT		14	/* Bad address */
+#define	ENOTBLK		15	/* Block device required */
+#define	EBUSY		16	/* Device or resource busy */
+#define	EEXIST		17	/* File exists */
+#define	EXDEV		18	/* Cross-device link */
+#define	ENODEV		19	/* No such device */
+#define	ENOTDIR		20	/* Not a directory */
+#define	EISDIR		21	/* Is a directory */
+#define	EINVAL		22	/* Invalid argument */
+#define	ENFILE		23	/* File table overflow */
+#define	EMFILE		24	/* Too many open files */
+#define	ENOTTY		25	/* Not a typewriter */
+#define	ETXTBSY		26	/* Text file busy */
+#define	EFBIG		27	/* File too large */
+#define	ENOSPC		28	/* No space left on device */
+#define	ESPIPE		29	/* Illegal seek */
+#define	EROFS		30	/* Read-only file system */
+#define	EMLINK		31	/* Too many links */
+#define	EPIPE		32	/* Broken pipe */
+#define	EDOM		33	/* Math argument out of domain of func */
+#define	ERANGE		34	/* Math result not representable */
+#define	EDEADLK		35	/* Resource deadlock would occur */
+#define	ENAMETOOLONG	36	/* File name too long */
+#define	ENOLCK		37	/* No record locks available */
+#define	ENOSYS		38	/* Function not implemented */
+#define	ENOTEMPTY	39	/* Directory not empty */
+#define	ELOOP		40	/* Too many symbolic links encountered */
+#define	EWOULDBLOCK	EAGAIN	/* Operation would block */
+#define	ENOMSG		42	/* No message of desired type */
+#define	EIDRM		43	/* Identifier removed */
+#define	ECHRNG		44	/* Channel number out of range */
+#define	EL2NSYNC	45	/* Level 2 not synchronized */
+#define	EL3HLT		46	/* Level 3 halted */
+#define	EL3RST		47	/* Level 3 reset */
+#define	ELNRNG		48	/* Link number out of range */
+#define	EUNATCH		49	/* Protocol driver not attached */
+#define	ENOCSI		50	/* No CSI structure available */
+#define	EL2HLT		51	/* Level 2 halted */
+#define	EBADE		52	/* Invalid exchange */
+#define	EBADR		53	/* Invalid request descriptor */
+#define	EXFULL		54	/* Exchange full */
+#define	ENOANO		55	/* No anode */
+#define	EBADRQC		56	/* Invalid request code */
+#define	EBADSLT		57	/* Invalid slot */
+
+#define	EDEADLOCK	EDEADLK
+
+#define	EBFONT		59	/* Bad font file format */
+#define	ENOSTR		60	/* Device not a stream */
+#define	ENODATA		61	/* No data available */
+#define	ETIME		62	/* Timer expired */
+#define	ENOSR		63	/* Out of streams resources */
+#define	ENONET		64	/* Machine is not on the network */
+#define	ENOPKG		65	/* Package not installed */
+#define	EREMOTE		66	/* Object is remote */
+#define	ENOLINK		67	/* Link has been severed */
+#define	EADV		68	/* Advertise error */
+#define	ESRMNT		69	/* Srmount error */
+#define	ECOMM		70	/* Communication error on send */
+#define	EPROTO		71	/* Protocol error */
+#define	EMULTIHOP	72	/* Multihop attempted */
+#define	EDOTDOT		73	/* RFS specific error */
+#define	EBADMSG		74	/* Not a data message */
+#define	EOVERFLOW	75	/* Value too large for defined data type */
+#define	ENOTUNIQ	76	/* Name not unique on network */
+#define	EBADFD		77	/* File descriptor in bad state */
+#define	EREMCHG		78	/* Remote address changed */
+#define	ELIBACC		79	/* Can not access a needed shared library */
+#define	ELIBBAD		80	/* Accessing a corrupted shared library */
+#define	ELIBSCN		81	/* .lib section in a.out corrupted */
+#define	ELIBMAX		82	/* Attempting to link in too many shared libraries */
+#define	ELIBEXEC	83	/* Cannot exec a shared library directly */
+#define	EILSEQ		84	/* Illegal byte sequence */
+#define	ERESTART	85	/* Interrupted system call should be restarted */
+#define	ESTRPIPE	86	/* Streams pipe error */
+#define	EUSERS		87	/* Too many users */
+#define	ENOTSOCK	88	/* Socket operation on non-socket */
+#define	EDESTADDRREQ	89	/* Destination address required */
+#define	EMSGSIZE	90	/* Message too long */
+#define	EPROTOTYPE	91	/* Protocol wrong type for socket */
+#define	ENOPROTOOPT	92	/* Protocol not available */
+#define	EPROTONOSUPPORT	93	/* Protocol not supported */
+#define	ESOCKTNOSUPPORT	94	/* Socket type not supported */
+#define	EOPNOTSUPP	95	/* Operation not supported on transport endpoint */
+#define	EPFNOSUPPORT	96	/* Protocol family not supported */
+#define	EAFNOSUPPORT	97	/* Address family not supported by protocol */
+#define	EADDRINUSE	98	/* Address already in use */
+#define	EADDRNOTAVAIL	99	/* Cannot assign requested address */
+#define	ENETDOWN	100	/* Network is down */
+#define	ENETUNREACH	101	/* Network is unreachable */
+#define	ENETRESET	102	/* Network dropped connection because of reset */
+#define	ECONNABORTED	103	/* Software caused connection abort */
+#define	ECONNRESET	104	/* Connection reset by peer */
+#define	ENOBUFS		105	/* No buffer space available */
+#define	EISCONN		106	/* Transport endpoint is already connected */
+#define	ENOTCONN	107	/* Transport endpoint is not connected */
+#define	ESHUTDOWN	108	/* Cannot send after transport endpoint shutdown */
+#define	ETOOMANYREFS	109	/* Too many references: cannot splice */
+#define	ETIMEDOUT	110	/* Connection timed out */
+#define	ECONNREFUSED	111	/* Connection refused */
+#define	EHOSTDOWN	112	/* Host is down */
+#define	EHOSTUNREACH	113	/* No route to host */
+#define	EALREADY	114	/* Operation already in progress */
+#define	EINPROGRESS	115	/* Operation now in progress */
+#define	ESTALE		116	/* Stale NFS file handle */
+#define	EUCLEAN		117	/* Structure needs cleaning */
+#define	ENOTNAM		118	/* Not a XENIX named type file */
+#define	ENAVAIL		119	/* No XENIX semaphores available */
+#define	EISNAM		120	/* Is a named type file */
+#define	EREMOTEIO	121	/* Remote I/O error */
+#define	EDQUOT		122	/* Quota exceeded */
+
+#define	ENOMEDIUM	123	/* No medium found */
+#define	EMEDIUMTYPE	124	/* Wrong medium type */
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/eshlibld.h linux/include/asm-cris/eshlibld.h
--- linux-2.4.2-pre1/include/asm-cris/eshlibld.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/eshlibld.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,114 @@
+/*!**************************************************************************
+*!
+*! FILE NAME  : eshlibld.h
+*!
+*! DESCRIPTION: Prototypes for exported shared library functions
+*!
+*! FUNCTIONS  : perform_cris_aout_relocations, shlibmod_fork, shlibmod_exit
+*! (EXPORTED)
+*!
+*!---------------------------------------------------------------------------
+*!
+*! (C) Copyright 1998, 1999 Axis Communications AB, LUND, SWEDEN
+*!
+*!**************************************************************************/
+/* $Id: eshlibld.h,v 1.1 2000/07/10 16:32:31 bjornw Exp $ */
+
+#ifndef _cris_relocate_h
+#define _cris_relocate_h
+
+/* Please note that this file is also compiled into the xsim simulator.
+   Try to avoid breaking its double use (only works on a little-endian
+   32-bit machine such as the i386 anyway).
+
+   Use __KERNEL__ when you're about to use kernel functions,
+       (which you should not do here anyway, since this file is
+       used by glibc).
+   Use defined(__KERNEL__) || defined(__elinux__) when doing
+       things that only makes sense on an elinux system.
+   Use __CRIS__ when you're about to do (really) CRIS-specific code.
+*/
+
+/* We have dependencies all over the place for the host system
+   for xsim being a linux system, so let's not pretend anything
+   else with #ifdef:s here until fixed.  */
+#include <linux/config.h>
+#include <linux/limits.h>
+
+/* Maybe do sanity checking if file input. */
+#undef SANITYCHECK_RELOC
+
+/* Maybe output debug messages. */
+#undef RELOC_DEBUG
+
+/* Maybe we want to share core as well as disk space.
+   Mainly depends on the config macro CONFIG_SHARE_SHLIB_CORE, but it is
+   assumed that we want to share code when debugging (exposes more
+   trouble). */
+#ifndef SHARE_LIB_CORE
+# if (defined(__KERNEL__) || !defined(RELOC_DEBUG)) \
+     && !defined(CONFIG_SHARE_SHLIB_CORE)
+#  define SHARE_LIB_CORE 0
+# else
+#  define SHARE_LIB_CORE 1
+# endif /* __KERNEL__ etc */
+#endif /* SHARE_LIB_CORE */
+
+
+/* Main exported function; supposed to be called when the program a.out
+   has been read in. */
+extern int
+perform_cris_aout_relocations(unsigned long text, unsigned long tlength,
+			      unsigned long data, unsigned long dlength,
+			      unsigned long baddr, unsigned long blength,
+
+			      /* These may be zero when there's "perfect"
+				 position-independent code. */
+			      unsigned char *trel, unsigned long tsrel,
+			      unsigned long dsrel,
+
+			      /* These will be zero at a first try, to see
+				 if code is statically linked.  Else a
+				 second try, with the symbol table and
+				 string table nonzero should be done. */
+			      unsigned char *symbols, unsigned long symlength,
+			      unsigned char *strings, unsigned long stringlength,
+
+			      /* These will only be used when symbol table
+			       information is present. */
+			      char **env, int envc,
+			      int euid, int is_suid);
+
+
+#ifdef RELOC_DEBUG
+/* Task-specific debug stuff. */
+struct task_reloc_debug {
+	struct memdebug *alloclast;
+	unsigned long alloc_total;
+	unsigned long export_total;
+};
+#endif /* RELOC_DEBUG */
+
+#if SHARE_LIB_CORE
+
+/* When code (and some very specific data) is shared and not just
+   dynamically linked, we need to export hooks for exec beginning and
+   end. */
+
+struct shlibdep;
+
+extern void
+shlibmod_exit(struct shlibdep **deps);
+
+/* Returns 0 if failure, nonzero for ok. */
+extern int
+shlibmod_fork(struct shlibdep **deps);
+
+#else  /* ! SHARE_LIB_CORE */
+# define shlibmod_exit(x)
+# define shlibmod_fork(x) 1
+#endif /* ! SHARE_LIB_CORE */
+
+#endif _cris_relocate_h
+/********************** END OF FILE eshlibld.h *****************************/
+
diff -urN linux-2.4.2-pre1/include/asm-cris/fcntl.h linux/include/asm-cris/fcntl.h
--- linux-2.4.2-pre1/include/asm-cris/fcntl.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/fcntl.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,89 @@
+#ifndef _CRIS_FCNTL_H
+#define _CRIS_FCNTL_H
+
+/* verbatim copy of i386 version */
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+   located on an ext2 file system */
+#define O_ACCMODE	   0003
+#define O_RDONLY	     00
+#define O_WRONLY	     01
+#define O_RDWR		     02
+#define O_CREAT		   0100	/* not fcntl */
+#define O_EXCL		   0200	/* not fcntl */
+#define O_NOCTTY	   0400	/* not fcntl */
+#define O_TRUNC		  01000	/* not fcntl */
+#define O_APPEND	  02000
+#define O_NONBLOCK	  04000
+#define O_NDELAY	O_NONBLOCK
+#define O_SYNC		 010000
+#define FASYNC		 020000	/* fcntl, for BSD compatibility */
+#define O_DIRECT	 040000	/* direct disk access hint - currently ignored */
+#define O_LARGEFILE	0100000
+#define O_DIRECTORY	0200000	/* must be a directory */
+#define O_NOFOLLOW	0400000 /* don't follow links */
+
+#define F_DUPFD		0	/* dup */
+#define F_GETFD		1	/* get f_flags */
+#define F_SETFD		2	/* set f_flags */
+#define F_GETFL		3	/* more flags (cloexec) */
+#define F_SETFL		4
+#define F_GETLK		5
+#define F_SETLK		6
+#define F_SETLKW	7
+
+#define F_SETOWN	8	/*  for sockets. */
+#define F_GETOWN	9	/*  for sockets. */
+#define F_SETSIG	10	/*  for sockets. */
+#define F_GETSIG	11	/*  for sockets. */
+
+#define F_GETLK64      12      /*  using 'struct flock64' */
+#define F_SETLK64      13
+#define F_SETLKW64     14
+
+/* for F_[GET|SET]FL */
+#define FD_CLOEXEC	1	/* actually anything with low bit set goes */
+
+/* for posix fcntl() and lockf() */
+#define F_RDLCK		0
+#define F_WRLCK		1
+#define F_UNLCK		2
+
+/* for old implementation of bsd flock () */
+#define F_EXLCK		4	/* or 3 */
+#define F_SHLCK		8	/* or 4 */
+
+/* for leases */
+#define F_INPROGRESS   16
+
+/* operations for bsd flock(), also used by the kernel implementation */
+#define LOCK_SH		1	/* shared lock */
+#define LOCK_EX		2	/* exclusive lock */
+#define LOCK_NB		4	/* or'd with one of the above to prevent
+				   blocking */
+#define LOCK_UN		8	/* remove lock */
+
+#define LOCK_MAND      32      /* This is a mandatory flock */
+#define LOCK_READ      64      /* ... Which allows concurrent read operations */
+#define LOCK_WRITE     128     /* ... Which allows concurrent write operations */
+#define LOCK_RW        192     /* ... Which allows concurrent read & write ops */
+
+struct flock {
+	short l_type;
+	short l_whence;
+	off_t l_start;
+	off_t l_len;
+	pid_t l_pid;
+};
+
+struct flock64 {
+	short  l_type;
+	short  l_whence;
+	loff_t l_start;
+	loff_t l_len;
+	pid_t  l_pid;
+};
+
+#define F_LINUX_SPECIFIC_BASE  1024
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/hardirq.h linux/include/asm-cris/hardirq.h
--- linux-2.4.2-pre1/include/asm-cris/hardirq.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/hardirq.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,35 @@
+#ifndef __ASM_HARDIRQ_H
+#define __ASM_HARDIRQ_H
+
+/* only non-SMP supported */
+
+#include <linux/threads.h>
+
+/* entry.S is sensitive to the offsets of these fields */
+typedef struct {
+	unsigned int __softirq_active;
+	unsigned int __softirq_mask;
+	unsigned int __local_irq_count;
+	unsigned int __local_bh_count;
+	unsigned int __syscall_count;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
+
+/*
+ * Are we in an interrupt context? Either doing bottom half
+ * or hardware interrupt processing?
+ */
+#define in_interrupt()  ((local_irq_count(smp_processor_id()) + \
+			  local_bh_count(smp_processor_id())) != 0)
+#define in_irq()        (local_irq_count(smp_processor_id()) != 0)
+
+#define hardirq_trylock(cpu)    (local_irq_count(cpu) == 0)
+#define hardirq_endlock(cpu)    do { (void)(cpu); } while (0)
+
+#define irq_enter(cpu)      (local_irq_count(cpu)++)
+#define irq_exit(cpu)       (local_irq_count(cpu)--)
+
+#define synchronize_irq()       barrier()
+
+#endif /* __ASM_HARDIRQ_H */
diff -urN linux-2.4.2-pre1/include/asm-cris/hdreg.h linux/include/asm-cris/hdreg.h
--- linux-2.4.2-pre1/include/asm-cris/hdreg.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/hdreg.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,11 @@
+/*
+ *  linux/include/asm-cris/hdreg.h
+ *
+ */
+
+#ifndef __ASMCRIS_HDREG_H
+#define __ASMCRIS_HDREG_H
+
+typedef unsigned long ide_ioreg_t;
+
+#endif /* __ASMCRIS_HDREG_H */
diff -urN linux-2.4.2-pre1/include/asm-cris/ide.h linux/include/asm-cris/ide.h
--- linux-2.4.2-pre1/include/asm-cris/ide.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/ide.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,142 @@
+/*
+ *  linux/include/asm-cris/ide.h
+ *
+ *  Copyright (C) 2000  Axis Communications AB
+ *
+ *  Authors:    Bjorn Wesen
+ *
+ */
+
+/*
+ *  This file contains the ETRAX 100LX specific IDE code.
+ */
+
+#ifndef __ASMCRIS_IDE_H
+#define __ASMCRIS_IDE_H
+
+#ifdef __KERNEL__
+
+#include <asm/svinto.h>
+
+/* ETRAX 100 can support 4 IDE busses on the same pins (serialized) */
+
+#define MAX_HWIFS	4
+
+#define ide__sti()	__sti()
+
+static __inline__ int ide_default_irq(ide_ioreg_t base)
+{
+	/* all IDE busses share the same IRQ, number 4.
+	 * this has the side-effect that ide-probe.c will cluster our 4 interfaces
+	 * together in a hwgroup, and will serialize accesses. this is good, because
+	 * we can't access more than one interface at the same time on ETRAX100.
+	 */
+	return 4; 
+}
+
+static __inline__ ide_ioreg_t ide_default_io_base(int index)
+{
+	/* we have no real I/O base address per interface, since all go through the
+	 * same register. but in a bitfield in that register, we have the i/f number.
+	 * so we can use the io_base to remember that bitfield.
+	 */
+	static const unsigned long io_bases[MAX_HWIFS] = {
+		IO_FIELD(R_ATA_CTRL_DATA, sel, 0),
+		IO_FIELD(R_ATA_CTRL_DATA, sel, 1),
+		IO_FIELD(R_ATA_CTRL_DATA, sel, 2),
+		IO_FIELD(R_ATA_CTRL_DATA, sel, 3)
+	};
+	return io_bases[index];
+}
+
+/* this is called once for each interface, to setup the port addresses. data_port is the result
+ * of the ide_default_io_base call above. ctrl_port will be 0, but that is don't care for us.
+ */
+
+static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
+{
+	int i;
+
+	/* fill in ports for ATA addresses 0 to 7 */
+
+	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
+		hw->io_ports[i] = data_port | 
+			IO_FIELD(R_ATA_CTRL_DATA, addr, i) | 
+			IO_STATE(R_ATA_CTRL_DATA, cs0, active);
+	}
+
+	/* the IDE control register is at ATA address 6, with CS1 active instead of CS0 */
+
+	hw->io_ports[IDE_CONTROL_OFFSET] = data_port |
+			IO_FIELD(R_ATA_CTRL_DATA, addr, 6) | 
+			IO_STATE(R_ATA_CTRL_DATA, cs1, active);
+
+	/* whats this for ? */
+
+	hw->io_ports[IDE_IRQ_OFFSET] = 0;
+}
+
+static __inline__ void ide_init_default_hwifs(void)
+{
+	hw_regs_t hw;
+	int index;
+
+	for(index = 0; index < MAX_HWIFS; index++) {
+		ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL);
+		hw.irq = ide_default_irq(ide_default_io_base(index));
+		ide_register_hw(&hw, NULL);
+	}
+}
+
+typedef union {
+	unsigned all			: 8;	/* all of the bits together */
+	struct {
+		unsigned head		: 4;	/* always zeros here */
+		unsigned unit		: 1;	/* drive select number, 0 or 1 */
+		unsigned bit5		: 1;	/* always 1 */
+		unsigned lba		: 1;	/* using LBA instead of CHS */
+		unsigned bit7		: 1;	/* always 1 */
+	} b;
+	} select_t;
+
+/* some configuration options we don't need */
+
+#undef SUPPORT_VLB_SYNC
+#define SUPPORT_VLB_SYNC 0
+
+#undef SUPPORT_SLOW_DATA_PORTS
+#define SUPPORT_SLOW_DATA_PORTS	0
+
+/* request and free a normal interrupt */
+
+#define ide_request_irq(irq,hand,flg,dev,id)	request_irq((irq),(hand),(flg),(dev),(id))
+#define ide_free_irq(irq,dev_id)		free_irq((irq), (dev_id))
+
+/* ide-probe.c calls ide_request_region and stuff on the io_ports defined,
+ * but since they are not actually memory-mapped in the ETRAX driver, we don't
+ * do anything.
+ */
+
+#define ide_check_region(from,extent)		(0)
+#define ide_request_region(from,extent,name)	do {} while(0)
+#define ide_release_region(from,extent)		do {} while(0)
+
+/*
+ * The following are not needed for the non-m68k ports
+ */
+#define ide_ack_intr(hwif)		(1)
+#define ide_fix_driveid(id)		do {} while (0)
+#define ide_release_lock(lock)		do {} while (0)
+#define ide_get_lock(lock, hdlr, data)	do {} while (0)
+
+/* the drive adressing is done through a controller register on the Etrax CPU */
+void OUT_BYTE(unsigned char data, ide_ioreg_t reg);
+unsigned char IN_BYTE(ide_ioreg_t reg);
+
+/* this tells ide.h not to define the standard macros */
+#define HAVE_ARCH_OUT_BYTE
+#define HAVE_ARCH_IN_BYTE
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASMCRIS_IDE_H */
diff -urN linux-2.4.2-pre1/include/asm-cris/io.h linux/include/asm-cris/io.h
--- linux-2.4.2-pre1/include/asm-cris/io.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/io.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,178 @@
+#ifndef _ASM_CRIS_IO_H
+#define _ASM_CRIS_IO_H
+
+#include <asm/page.h>   /* for __va, __pa */
+#include <asm/svinto.h>
+#include <linux/config.h>
+
+/* Console I/O for simulated etrax100.  Use #ifdef so erroneous
+   use will be evident. */
+#ifdef CONFIG_SVINTO_SIM
+  /* Let's use the ucsim interface since it lets us do write(2, ...) */
+#define SIMCOUT(s,len) asm ("moveq 4,r1\n\tmoveq 2,r10\n\tmove.d %0,r11\n\tmove.d %1,r12\
+\n\tpush irp\n\t.word 0xae3f\n\t.dword 0f\n\tjump -6809\n0:\n\tpop irp" \
+       : : "rm" (s), "rm" (len) : "r1","r10","r11","r12","memory")
+#define TRACE_ON() __extension__ \
+ ({ int _Foofoo; __asm__ volatile ("bmod [%0],%0" : "=r" (_Foofoo) : "0" \
+			       (255)); _Foofoo; })
+
+#define TRACE_OFF() do { __asm__ volatile ("bmod [%0],%0" :: "r" (254)); } while (0)
+#define SIM_END() do { __asm__ volatile ("bmod [%0],%0" :: "r" (28)); } while (0)
+#define CRIS_CYCLES() __extension__ \
+ ({ unsigned long c; asm ("bmod [%1],%0" : "=r" (c) : "r" (27)); c;})
+#else  /* ! defined CONFIG_SVINTO_SIM */
+/* FIXME: Is there a reliable cycle counter available in some chip?  Use
+   that then. */
+#define CRIS_CYCLES() 0
+#endif /* ! defined CONFIG_SVINTO_SIM */
+
+/* Etrax shadow registers - which live in arch/cris/kernel/shadows.c */
+
+extern unsigned long port_g_data_shadow;
+extern unsigned char port_pa_dir_shadow;
+extern unsigned char port_pa_data_shadow;
+extern unsigned char port_pb_i2c_shadow;
+extern unsigned char port_pb_config_shadow;
+extern unsigned char port_pb_dir_shadow;
+extern unsigned char port_pb_data_shadow;
+extern unsigned long r_timer_ctrl_shadow;
+extern unsigned long port_90000000_shadow;
+
+/* macro for setting regs through a shadow - 
+ * r = register name (like R_PORT_PA_DATA)
+ * s = shadow name (like port_pa_data_shadow)
+ * b = bit number
+ * v = value (0 or 1)
+ */
+
+#define REG_SHADOW_SET(r,s,b,v) *r = s = (s & ~(1 << b)) | ((v) << b) 
+
+/* The LED's on various Etrax-based products are set differently. */
+
+#if defined(CONFIG_ETRAX_NO_LEDS) || defined(CONFIG_SVINTO_SIM)
+#undef CONFIG_ETRAX_PA_LEDS
+#undef CONFIG_ETRAX_PB_LEDS
+#undef CONFIG_ETRAX_90000000_LEDS
+#define LED_NETWORK_RX_SET(x)
+#define LED_NETWORK_TX_SET(x)
+#define LED_ACTIVE_SET(x)
+#define LED_ACTIVE_SET_G(x)
+#define LED_ACTIVE_SET_R(x)
+#define LED_DISK_WRITE(x)
+#define LED_DISK_READ(x)
+#endif
+
+#ifdef CONFIG_ETRAX_PA_LEDS
+#define LED_NETWORK_RX_SET(x) \
+         REG_SHADOW_SET(R_PORT_PA_DATA, port_pa_data_shadow, CONFIG_ETRAX_LED1G, !x)
+#define LED_NETWORK_TX_SET(x) \
+         REG_SHADOW_SET(R_PORT_PA_DATA, port_pa_data_shadow, CONFIG_ETRAX_LED1R, !x)
+#define LED_ACTIVE_SET(x) \
+         REG_SHADOW_SET(R_PORT_PA_DATA, port_pa_data_shadow, CONFIG_ETRAX_LED2G, !x)
+#define LED_ACTIVE_SET_G(x) \
+         REG_SHADOW_SET(R_PORT_PA_DATA, port_pa_data_shadow, CONFIG_ETRAX_LED2G, !x)
+#define LED_ACTIVE_SET_R(x) \
+         REG_SHADOW_SET(R_PORT_PA_DATA, port_pa_data_shadow, CONFIG_ETRAX_LED2R, !x)
+#define LED_DISK_WRITE(x) \
+         REG_SHADOW_SET(R_PORT_PA_DATA, port_pa_data_shadow, CONFIG_ETRAX_LED3R, !x)
+#define LED_DISK_READ(x) \
+         REG_SHADOW_SET(R_PORT_PA_DATA, port_pa_data_shadow, CONFIG_ETRAX_LED3G, !x) 
+#endif
+
+#ifdef CONFIG_ETRAX_PB_LEDS
+#define LED_NETWORK_RX_SET(x) \
+         REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_LED1G, !x)
+#define LED_NETWORK_TX_SET(x) \
+         REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_LED1R, !x)
+#define LED_ACTIVE_SET(x) \
+         REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_LED2G, !x)
+#define LED_ACTIVE_SET_G(x) \
+         REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_LED2G, !x)
+#define LED_ACTIVE_SET_R(x) \
+         REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_LED2R, !x)
+#define LED_DISK_WRITE(x) \
+         REG_SHADOW_SET(R_PORT_PB_DATA, port_pa_data_shadow, CONFIG_ETRAX_LED3R, !x)
+#define LED_DISK_READ(x) \
+         REG_SHADOW_SET(R_PORT_PB_DATA, port_pa_data_shadow, CONFIG_ETRAX_LED3G, !x)     
+#endif
+
+#ifdef CONFIG_ETRAX_90000000_LEDS
+/* TODO: this won't work, need a vremap into kernel virtual memory of 90000000 */
+#define LED_PORT_90 (volatile unsigned long*)0x90000000
+#define LED_ACTIVE_SET(x) \
+         REG_SHADOW_SET(LED_PORT_90, port_90000000_shadow, CONFIG_ETRAX_LED2G, !x)
+#define LED_NETWORK_RX_SET(x) \
+         REG_SHADOW_SET(LED_PORT_90, port_90000000_shadow, CONFIG_ETRAX_LED1G, !x)
+#define LED_NETWORK_TX_SET(x) \
+         REG_SHADOW_SET(LED_PORT_90, port_90000000_shadow, CONFIG_ETRAX_LED1R, !x)
+#define LED_ACTIVE_SET_G(x) \
+         REG_SHADOW_SET(LED_PORT_90, port_90000000_shadow, CONFIG_ETRAX_LED2G, !x)
+#define LED_ACTIVE_SET_R(x) \
+         REG_SHADOW_SET(LED_PORT_90, port_90000000_shadow, CONFIG_ETRAX_LED2R, !x)
+#define LED_DISK_WRITE(x) \
+         REG_SHADOW_SET(LED_PORT_90, port_90000000_shadow, CONFIG_ETRAX_LED3R, !x)
+#define LED_DISK_READ(x) \
+         REG_SHADOW_SET(LED_PORT_90, port_90000000_shadow, CONFIG_ETRAX_LED3G, !x)           
+#endif
+
+/*
+ * Change virtual addresses to physical addresses and vv.
+ */
+
+static inline unsigned long virt_to_phys(volatile void * address)
+{
+	return __pa(address);
+}
+
+static inline void * phys_to_virt(unsigned long address)
+{
+	return __va(address);
+}
+
+/*
+ * IO bus memory addresses are also 1:1 with the physical address
+ */
+#define virt_to_bus virt_to_phys
+#define bus_to_virt phys_to_virt
+
+/*
+ * readX/writeX() are used to access memory mapped devices. On some
+ * architectures the memory mapped IO stuff needs to be accessed
+ * differently. On the CRIS architecture, we just read/write the
+ * memory location directly.
+ */
+#define readb(addr) (*(volatile unsigned char *) (addr))
+#define readw(addr) (*(volatile unsigned short *) (addr))
+#define readl(addr) (*(volatile unsigned int *) (addr))
+
+#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
+#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b))
+#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
+
+#define memset_io(a,b,c)	memset((void *)(a),(b),(c))
+#define memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
+#define memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
+
+/*
+ * Again, CRIS does not require mem IO specific function.
+ */
+
+#define eth_io_copy_and_sum(a,b,c,d)	eth_copy_and_sum((a),(void *)(b),(c),(d))
+
+/* The following is junk needed for the arch-independant code but which
+ * we never use in the CRIS port
+ */
+
+#define IO_SPACE_LIMIT 0xffff
+#define inb(x) (0)
+#define outb(x,y)
+#define outw(x,y)
+#define outl(x,y)
+#define insb(x,y,z)
+#define insw(x,y,z)
+#define insl(x,y,z)
+#define outsb(x,y,z)
+#define outsw(x,y,z)
+#define outsl(x,y,z)
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/ioctl.h linux/include/asm-cris/ioctl.h
--- linux-2.4.2-pre1/include/asm-cris/ioctl.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/ioctl.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,76 @@
+/*
+ * linux/ioctl.h for Linux by H.H. Bergman.
+ *
+ * This is the same as the i386 version.
+ */
+
+#ifndef _ASMCRIS_IOCTL_H
+#define _ASMCRIS_IOCTL_H
+
+/* ioctl command encoding: 32 bits total, command in lower 16 bits,
+ * size of the parameter structure in the lower 14 bits of the
+ * upper 16 bits.
+ * Encoding the size of the parameter structure in the ioctl request
+ * is useful for catching programs compiled with old versions
+ * and to avoid overwriting user space outside the user buffer area.
+ * The highest 2 bits are reserved for indicating the ``access mode''.
+ * NOTE: This limits the max parameter size to 16kB -1 !
+ */
+
+/*
+ * The following is for compatibility across the various Linux
+ * platforms.  The i386 ioctl numbering scheme doesn't really enforce
+ * a type field.  De facto, however, the top 8 bits of the lower 16
+ * bits are indeed used as a type field, so we might just as well make
+ * this explicit here.  Please be sure to use the decoding macros
+ * below from now on.
+ */
+#define _IOC_NRBITS	8
+#define _IOC_TYPEBITS	8
+#define _IOC_SIZEBITS	14
+#define _IOC_DIRBITS	2
+
+#define _IOC_NRMASK	((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK	((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK	((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK	((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT	0
+#define _IOC_TYPESHIFT	(_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT	(_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT	(_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits.
+ */
+#define _IOC_NONE	0U
+#define _IOC_WRITE	1U
+#define _IOC_READ	2U
+
+#define _IOC(dir,type,nr,size) \
+	(((dir)  << _IOC_DIRSHIFT) | \
+	 ((type) << _IOC_TYPESHIFT) | \
+	 ((nr)   << _IOC_NRSHIFT) | \
+	 ((size) << _IOC_SIZESHIFT))
+
+/* used to create numbers */
+#define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+/* used to decode ioctl numbers.. */
+#define _IOC_DIR(nr)		(((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr)		(((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr)		(((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr)		(((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+/* ...and for the drivers/sound files... */
+
+#define IOC_IN		(_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT		(_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT	((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK	(_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT	(_IOC_SIZESHIFT)
+
+#endif /* _ASMCRIS_IOCTL_H */
diff -urN linux-2.4.2-pre1/include/asm-cris/ioctls.h linux/include/asm-cris/ioctls.h
--- linux-2.4.2-pre1/include/asm-cris/ioctls.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/ioctls.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,84 @@
+#ifndef __ARCH_CRIS_IOCTLS_H__
+#define __ARCH_CRIS_IOCTLS_H__
+
+/* verbatim copy of asm-i386/ioctls.h */
+
+#include <asm/ioctl.h>
+
+/* 0x54 is just a magic number to make these relatively unique ('T') */
+
+#define TCGETS		0x5401
+#define TCSETS		0x5402
+#define TCSETSW		0x5403
+#define TCSETSF		0x5404
+#define TCGETA		0x5405
+#define TCSETA		0x5406
+#define TCSETAW		0x5407
+#define TCSETAF		0x5408
+#define TCSBRK		0x5409
+#define TCXONC		0x540A
+#define TCFLSH		0x540B
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+#define TIOCGPGRP	0x540F
+#define TIOCSPGRP	0x5410
+#define TIOCOUTQ	0x5411
+#define TIOCSTI		0x5412
+#define TIOCGWINSZ	0x5413
+#define TIOCSWINSZ	0x5414
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define FIONREAD	0x541B
+#define TIOCINQ		FIONREAD
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT		0x5420
+#define FIONBIO		0x5421
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425	/* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT	0x5426  /* For debugging only */
+#define TIOCSBRK	0x5427  /* BSD compatibility */
+#define TIOCCBRK	0x5428  /* BSD compatibility */
+#define TIOCGSID	0x5429  /* Return the session ID of FD */
+#define TIOCGPTN	_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define TIOCSPTLCK	_IOW('T',0x31, int)  /* Lock/unlock Pty */
+
+#define FIONCLEX	0x5450  /* these numbers need to be adjusted. */
+#define FIOCLEX		0x5451
+#define FIOASYNC	0x5452
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
+#define TIOCSERGETLSR   0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
+#define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+#define TIOCGHAYESESP   0x545E  /* Get Hayes ESP configuration */
+#define TIOCSHAYESESP   0x545F  /* Set Hayes ESP configuration */
+
+/* Used for packet mode */
+#define TIOCPKT_DATA		 0
+#define TIOCPKT_FLUSHREAD	 1
+#define TIOCPKT_FLUSHWRITE	 2
+#define TIOCPKT_STOP		 4
+#define TIOCPKT_START		 8
+#define TIOCPKT_NOSTOP		16
+#define TIOCPKT_DOSTOP		32
+
+#define TIOCSER_TEMT    0x01	/* Transmitter physically empty */
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/ipc.h linux/include/asm-cris/ipc.h
--- linux-2.4.2-pre1/include/asm-cris/ipc.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/ipc.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,34 @@
+#ifndef __CRIS_IPC_H__
+#define __CRIS_IPC_H__
+
+/* 
+ * These are used to wrap system calls on CRIS.
+ *
+ * See arch/cris/kernel/sys_cris.c for ugly details..
+ *
+ * Same as x86 version.
+ *
+ */
+struct ipc_kludge {
+	struct msgbuf *msgp;
+	long msgtyp;
+};
+
+#define SEMOP		 1
+#define SEMGET		 2
+#define SEMCTL		 3
+#define MSGSND		11
+#define MSGRCV		12
+#define MSGGET		13
+#define MSGCTL		14
+#define SHMAT		21
+#define SHMDT		22
+#define SHMGET		23
+#define SHMCTL		24
+
+/* Used by the DIPC package, try and avoid reusing it */
+#define DIPC            25
+
+#define IPCCALL(version,op)	((version)<<16 | (op))
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/ipcbuf.h linux/include/asm-cris/ipcbuf.h
--- linux-2.4.2-pre1/include/asm-cris/ipcbuf.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/ipcbuf.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,29 @@
+#ifndef __CRIS_IPCBUF_H__
+#define __CRIS_IPCBUF_H__
+
+/*
+ * The user_ipc_perm structure for CRIS architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct ipc64_perm
+{
+	__kernel_key_t		key;
+	__kernel_uid32_t	uid;
+	__kernel_gid32_t	gid;
+	__kernel_uid32_t	cuid;
+	__kernel_gid32_t	cgid;
+	__kernel_mode_t		mode;
+	unsigned short		__pad1;
+	unsigned short		seq;
+	unsigned short		__pad2;
+	unsigned long		__unused1;
+	unsigned long		__unused2;
+};
+
+#endif /* __CRIS_IPCBUF_H__ */
diff -urN linux-2.4.2-pre1/include/asm-cris/irq.h linux/include/asm-cris/irq.h
--- linux-2.4.2-pre1/include/asm-cris/irq.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/irq.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,102 @@
+/*
+ * Interrupt handling assembler for Linux/CRIS
+ *
+ * Copyright (c) 2000 Axis Communications AB
+ *
+ * Authors:   Bjorn Wesen (bjornw@axis.com)
+ *
+ */
+
+#ifndef _ASM_IRQ_H
+#define _ASM_IRQ_H
+
+/*
+ *	linux/include/asm-cris/irq.h
+ */
+
+#include <linux/linkage.h>
+#include <asm/segment.h>
+
+#include <asm/sv_addr_ag.h>
+
+#define NR_IRQS 26     /* TODO: what is this for Etrax100/LX ? */
+
+extern void disable_irq(unsigned int);
+extern void enable_irq(unsigned int);
+
+#define disable_irq_nosync      disable_irq
+#define enable_irq_nosync       enable_irq
+
+/* our fine, global, etrax irq vector! the pointer lives in the head.S file. */
+
+typedef void (*irqvectptr)(void);
+
+struct etrax_interrupt_vector {
+	irqvectptr v[256];
+};
+
+extern struct etrax_interrupt_vector *etrax_irv;
+void set_int_vector(int n, irqvectptr addr, irqvectptr saddr);
+void set_break_vector(int n, irqvectptr addr);
+
+#define __STR(x) #x
+#define STR(x) __STR(x)
+ 
+/* SAVE_ALL saves registers so they match pt_regs */
+
+#define SAVE_ALL \
+  "push irp\n\t"       /* push instruction pointer */ \
+  "push srp\n\t"       /* push subroutine return pointer */ \
+  "push dccr\n\t"      /* push condition codes */ \
+  "push mof\n\t"       /* push multiply overflow reg */ \
+  "di\n\t"             /* need to disable irq's at this point */\
+  "subq 14*4,sp\n\t"   /* make room for r0-r13 */ \
+  "movem r13,[sp]\n\t" /* push the r0-r13 registers */ \
+  "push r10\n\t"       /* push orig_r10 */ \
+  "clear.d [sp=sp-4]\n\t"  /* frametype - this is a normal stackframe */
+
+  /* BLOCK_IRQ and UNBLOCK_IRQ do the same as mask_irq and unmask_irq in irq.c */
+
+#define BLOCK_IRQ(mask,nr) \
+  "move.d " #mask ",r0\n\t" \
+  "move.d r0,[0xb00000d8]\n\t" 
+  
+#define UNBLOCK_IRQ(mask) \
+  "move.d " #mask ",r0\n\t" \
+  "move.d r0,[0xb00000dc]\n\t" 
+
+#define IRQ_NAME2(nr) nr##_interrupt(void)
+#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
+#define sIRQ_NAME(nr) IRQ_NAME2(sIRQ##nr)
+#define BAD_IRQ_NAME(nr) IRQ_NAME2(bad_IRQ##nr)
+
+  /* the asm IRQ handler makes sure the causing IRQ is blocked, then it calls
+   * do_IRQ (with irq disabled still). after that it unblocks and jumps to
+   * ret_from_intr (entry.S)
+   */
+
+#define BUILD_IRQ(nr,mask) \
+void IRQ_NAME(nr); \
+void sIRQ_NAME(nr); \
+void BAD_IRQ_NAME(nr); \
+__asm__ ( \
+          ".text\n\t" \
+          "_IRQ" #nr "_interrupt:\n\t" \
+	  SAVE_ALL \
+	  "_sIRQ" #nr "_interrupt:\n\t" /* shortcut for the multiple irq handler */ \
+	  BLOCK_IRQ(mask,nr) /* this must be done to prevent irq loops when we ei later */ \
+	  "moveq "#nr",r10\n\t" \
+	  "move.d sp,r11\n\t" \
+	  "jsr _do_IRQ\n\t" /* irq.c, r10 and r11 are arguments */ \
+	  UNBLOCK_IRQ(mask) \
+	  "moveq 0,r9\n\t" /* make ret_from_intr realise we came from an irq */ \
+	  "jump _ret_from_intr\n\t" \
+          "_bad_IRQ" #nr "_interrupt:\n\t" \
+	  "push r0\n\t" \
+	  BLOCK_IRQ(mask,nr) \
+	  "pop r0\n\t");
+
+
+#endif  /* _ASM_IRQ_H */
+
+
diff -urN linux-2.4.2-pre1/include/asm-cris/locks.h linux/include/asm-cris/locks.h
--- linux-2.4.2-pre1/include/asm-cris/locks.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/locks.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,133 @@
+/*
+ *	SMP locks primitives for building ix86 locks
+ *	(not yet used).
+ *
+ *		Alan Cox, alan@cymru.net, 1995
+ */
+ 
+/*
+ *	This would be much easier but far less clear and easy
+ *	to borrow for other processors if it was just assembler.
+ */
+
+extern __inline__ void prim_spin_lock(struct spinlock *sp)
+{
+	int processor=smp_processor_id();
+	
+	/*
+	 *	Grab the lock bit
+	 */
+	 
+	while(lock_set_bit(0,&sp->lock))
+	{
+		/*
+		 *	Failed, but that's cos we own it!
+		 */
+		 
+		if(sp->cpu==processor)
+		{
+			sp->users++;
+			return 0;
+		}
+		/*
+		 *	Spin in the cache S state if possible
+		 */
+		while(sp->lock)
+		{
+			/*
+			 *	Wait for any invalidates to go off
+			 */
+			 
+			if(smp_invalidate_needed&(1<<processor))
+				while(lock_clear_bit(processor,&smp_invalidate_needed))
+					local_flush_tlb();
+			sp->spins++;
+		}
+		/*
+		 *	Someone wrote the line, we go 'I' and get
+		 *	the cache entry. Now try to regrab
+		 */
+	}
+	sp->users++;sp->cpu=processor;
+	return 1;
+}
+
+/*
+ *	Release a spin lock
+ */
+ 
+extern __inline__ int prim_spin_unlock(struct spinlock *sp)
+{
+	/* This is safe. The decrement is still guarded by the lock. A multilock would
+	   not be safe this way */
+	if(!--sp->users)
+	{
+		lock_clear_bit(0,&sp->lock);sp->cpu= NO_PROC_ID;
+		return 1;
+	}
+	return 0;
+}
+
+
+/*
+ *	Non blocking lock grab
+ */
+ 
+extern __inline__ int prim_spin_lock_nb(struct spinlock *sp)
+{
+	if(lock_set_bit(0,&sp->lock))
+		return 0;		/* Locked already */
+	sp->users++;
+	return 1;			/* We got the lock */
+}
+
+
+/*
+ *	These wrap the locking primitives up for usage
+ */
+ 
+extern __inline__ void spinlock(struct spinlock *sp)
+{
+	if(sp->priority<current->lock_order)
+		panic("lock order violation: %s (%d)\n", sp->name, current->lock_order);
+	if(prim_spin_lock(sp))
+	{
+		/*
+		 *	We got a new lock. Update the priority chain
+		 */
+		sp->oldpri=current->lock_order;
+		current->lock_order=sp->priority;
+	}
+}
+
+extern __inline__ void spinunlock(struct spinlock *sp)
+{
+	if(current->lock_order!=sp->priority)
+		panic("lock release order violation %s (%d)\n", sp->name, current->lock_order);
+	if(prim_spin_unlock(sp))
+	{
+		/*
+		 *	Update the debugging lock priority chain. We dumped
+		 *	our last right to the lock.
+		 */
+		current->lock_order=sp->oldpri;
+	}	
+}
+
+extern __inline__ void spintestlock(struct spinlock *sp)
+{
+	/*
+	 *	We do no sanity checks, it's legal to optimistically
+	 *	get a lower lock.
+	 */
+	prim_spin_lock_nb(sp);
+}
+
+extern __inline__ void spintestunlock(struct spinlock *sp)
+{
+	/*
+	 *	A testlock doesn't update the lock chain so we
+	 *	must not update it on free
+	 */
+	prim_spin_unlock(sp);
+}
diff -urN linux-2.4.2-pre1/include/asm-cris/mman.h linux/include/asm-cris/mman.h
--- linux-2.4.2-pre1/include/asm-cris/mman.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/mman.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,40 @@
+#ifndef __CRIS_MMAN_H__
+#define __CRIS_MMAN_H__
+
+/* verbatim copy of asm-i386/ version */
+
+#define PROT_READ	0x1		/* page can be read */
+#define PROT_WRITE	0x2		/* page can be written */
+#define PROT_EXEC	0x4		/* page can be executed */
+#define PROT_NONE	0x0		/* page can not be accessed */
+
+#define MAP_SHARED	0x01		/* Share changes */
+#define MAP_PRIVATE	0x02		/* Changes are private */
+#define MAP_TYPE	0x0f		/* Mask for type of mapping */
+#define MAP_FIXED	0x10		/* Interpret addr exactly */
+#define MAP_ANONYMOUS	0x20		/* don't use a file */
+
+#define MAP_GROWSDOWN	0x0100		/* stack-like segment */
+#define MAP_DENYWRITE	0x0800		/* ETXTBSY */
+#define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
+#define MAP_LOCKED	0x2000		/* pages are locked */
+#define MAP_NORESERVE	0x4000		/* don't check for reservations */
+
+#define MS_ASYNC	1		/* sync memory asynchronously */
+#define MS_INVALIDATE	2		/* invalidate the caches */
+#define MS_SYNC		4		/* synchronous memory sync */
+
+#define MCL_CURRENT	1		/* lock all current mappings */
+#define MCL_FUTURE	2		/* lock all future mappings */
+
+#define MADV_NORMAL	0x0		/* default page-in behavior */
+#define MADV_RANDOM	0x1		/* page-in minimum required */
+#define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
+#define MADV_WILLNEED	0x3		/* pre-fault pages */
+#define MADV_DONTNEED	0x4		/* discard these pages */
+
+/* compatibility flags */
+#define MAP_ANON	MAP_ANONYMOUS
+#define MAP_FILE	0
+
+#endif /* __CRIS_MMAN_H__ */
diff -urN linux-2.4.2-pre1/include/asm-cris/mmu.h linux/include/asm-cris/mmu.h
--- linux-2.4.2-pre1/include/asm-cris/mmu.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/mmu.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,62 @@
+/*
+ * CRIS MMU constants and PTE layout
+ */
+
+#ifndef _CRIS_MMU_H
+#define _CRIS_MMU_H
+
+/* type used in struct mm to couple an MMU context to an active mm */
+
+typedef unsigned int mm_context_t;
+
+/* kernel memory segments */
+
+#define KSEG_F 0xf0000000UL
+#define KSEG_E 0xe0000000UL
+#define KSEG_D 0xd0000000UL
+#define KSEG_C 0xc0000000UL
+#define KSEG_B 0xb0000000UL
+#define KSEG_A 0xa0000000UL
+#define KSEG_9 0x90000000UL
+#define KSEG_8 0x80000000UL
+#define KSEG_7 0x70000000UL
+#define KSEG_6 0x60000000UL
+#define KSEG_5 0x50000000UL
+#define KSEG_4 0x40000000UL
+#define KSEG_3 0x30000000UL
+#define KSEG_2 0x20000000UL
+#define KSEG_1 0x10000000UL
+#define KSEG_0 0x00000000UL
+
+/* CRIS PTE bits (see R_TLB_LO in the register description)
+ *
+ *   Bit:  31-13 12-------4    3        2       1       0  
+ *         ________________________________________________
+ *        | pfn | reserved | global | valid | kernel | we  |
+ *        |_____|__________|________|_______|________|_____|
+ *
+ * (pfn = physical frame number)
+ */
+
+/* Real HW-based PTE bits. We use some synonym names so that
+ * things become less confusing in combination with the SW-based
+ * bits further below.
+ *
+ */
+
+#define _PAGE_WE	   (1<<0) /* page is write-enabled */
+#define _PAGE_SILENT_WRITE (1<<0) /* synonym */
+#define _PAGE_KERNEL	   (1<<1) /* page is kernel only */
+#define _PAGE_VALID	   (1<<2) /* page is valid */
+#define _PAGE_SILENT_READ  (1<<2) /* synonym */
+#define _PAGE_GLOBAL       (1<<3) /* global page - context is ignored */
+
+/* Bits the HW doesn't care about but the kernel uses them in SW */
+
+#define _PAGE_PRESENT   (1<<4)  /* page present in memory */
+#define _PAGE_ACCESSED	(1<<5)  /* simulated in software using valid bit */
+#define _PAGE_MODIFIED	(1<<6)  /* simulated in software using we bit */
+#define _PAGE_READ      (1<<7)  /* read-enabled */
+#define _PAGE_WRITE     (1<<8)  /* write-enabled */
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/mmu_context.h linux/include/asm-cris/mmu_context.h
--- linux-2.4.2-pre1/include/asm-cris/mmu_context.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/mmu_context.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,16 @@
+#ifndef __CRIS_MMU_CONTEXT_H
+#define __CRIS_MMU_CONTEXT_H
+
+extern int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
+extern void get_mmu_context(struct mm_struct *mm);
+extern void destroy_context(struct mm_struct *mm);
+extern void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+		      struct task_struct *tsk, int cpu);
+
+#define activate_mm(prev,next) switch_mm((prev),(next),NULL,smp_processor_id())
+
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
+{
+}
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/module.h linux/include/asm-cris/module.h
--- linux-2.4.2-pre1/include/asm-cris/module.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/module.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,11 @@
+#ifndef _ASM_CRIS_MODULE_H
+#define _ASM_CRIS_MODULE_H
+/*
+ * This file contains the CRIS architecture specific module code.
+ */
+
+#define module_map(x)		vmalloc(x)
+#define module_unmap(x)		vfree(x)
+#define module_arch_init(x)	(0)
+
+#endif /* _ASM_CRIS_MODULE_H */
diff -urN linux-2.4.2-pre1/include/asm-cris/msgbuf.h linux/include/asm-cris/msgbuf.h
--- linux-2.4.2-pre1/include/asm-cris/msgbuf.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/msgbuf.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,33 @@
+#ifndef _CRIS_MSGBUF_H
+#define _CRIS_MSGBUF_H
+
+/* verbatim copy of asm-i386 version */
+
+/* 
+ * The msqid64_ds structure for CRIS architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct msqid64_ds {
+	struct ipc64_perm msg_perm;
+	__kernel_time_t msg_stime;	/* last msgsnd time */
+	unsigned long	__unused1;
+	__kernel_time_t msg_rtime;	/* last msgrcv time */
+	unsigned long	__unused2;
+	__kernel_time_t msg_ctime;	/* last change time */
+	unsigned long	__unused3;
+	unsigned long  msg_cbytes;	/* current number of bytes on queue */
+	unsigned long  msg_qnum;	/* number of messages in queue */
+	unsigned long  msg_qbytes;	/* max number of bytes on queue */
+	__kernel_pid_t msg_lspid;	/* pid of last msgsnd */
+	__kernel_pid_t msg_lrpid;	/* last receive pid */
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+#endif /* _CRIS_MSGBUF_H */
diff -urN linux-2.4.2-pre1/include/asm-cris/namei.h linux/include/asm-cris/namei.h
--- linux-2.4.2-pre1/include/asm-cris/namei.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/namei.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,17 @@
+/* $Id: namei.h,v 1.1 2000/07/10 16:32:31 bjornw Exp $
+ * linux/include/asm-cris/namei.h
+ *
+ * Included from linux/fs/namei.c
+ */
+
+#ifndef __CRIS_NAMEI_H
+#define __CRIS_NAMEI_H
+
+/* used to find file-system prefixes for doing emulations
+ * see for example asm-sparc/namei.h
+ * we dont use it...
+ */
+
+#define __emul_prefix() NULL
+
+#endif /* __CRIS_NAMEI_H */
diff -urN linux-2.4.2-pre1/include/asm-cris/page.h linux/include/asm-cris/page.h
--- linux-2.4.2-pre1/include/asm-cris/page.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/page.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,118 @@
+#ifndef _CRIS_PAGE_H
+#define _CRIS_PAGE_H
+
+#include <linux/config.h>
+#include <asm/mmu.h>
+
+/* PAGE_SHIFT determines the page size */
+#define PAGE_SHIFT	13
+#define PAGE_SIZE	(1UL << PAGE_SHIFT)
+#define PAGE_MASK	(~(PAGE_SIZE-1))
+
+#ifdef __KERNEL__
+
+#define clear_page(page)        memset((void *)(page), 0, PAGE_SIZE)
+#define copy_page(to,from)      memcpy((void *)(to), (void *)(from), PAGE_SIZE)
+
+#define clear_user_page(page, vaddr)    clear_page(page)
+#define copy_user_page(to, from, vaddr) copy_page(to, from)
+
+#define STRICT_MM_TYPECHECKS
+
+#ifdef STRICT_MM_TYPECHECKS
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long pmd; } pmd_t;
+typedef struct { unsigned long pgd; } pgd_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+#define pte_val(x)	((x).pte)
+#define pmd_val(x)	((x).pmd)
+#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) } )
+
+#else
+/*
+ * .. while these make it easier on the compiler
+ */
+typedef unsigned long pte_t;
+typedef unsigned long pmd_t;
+typedef unsigned long pgd_t;
+typedef unsigned long pgprot_t;
+
+#define pte_val(x)	(x)
+#define pmd_val(x)	(x)
+#define pgd_val(x)	(x)
+#define pgprot_val(x)	(x)
+
+#define __pte(x)	(x)
+#define __pmd(x)	(x)
+#define __pgd(x)	(x)
+#define __pgprot(x)	(x)
+
+#endif
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE-1)&PAGE_MASK)
+
+/* This handles the memory map.. */
+
+#ifdef CONFIG_CRIS_LOW_MAP
+#define PAGE_OFFSET		KSEG_6   /* kseg_6 is mapped to physical ram */
+#else
+#define PAGE_OFFSET		KSEG_C   /* kseg_c is mapped to physical ram */
+#endif
+
+#ifndef __ASSEMBLY__
+
+#define BUG() do { \
+  printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+} while (0)
+
+#define PAGE_BUG(page) do { \
+         BUG(); \
+} while (0)
+
+#endif /* __ASSEMBLY__ */
+
+/* macros to convert between really physical and virtual addresses
+ * by stripping a selected bit, we can convert between KSEG_x and 0x40000000 where
+ * the DRAM really resides
+ */
+
+#ifdef CONFIG_CRIS_LOW_MAP
+/* we have DRAM virtually at 0x6 */
+#define __pa(x)                 ((unsigned long)(x) & 0xdfffffff)
+#define __va(x)                 ((void *)((unsigned long)(x) | 0x20000000))
+#else
+/* we have DRAM virtually at 0xc */
+#define __pa(x)                 ((unsigned long)(x) & 0x7fffffff)
+#define __va(x)                 ((void *)((unsigned long)(x) | 0x80000000))
+#endif
+
+/* to index into the page map. our pages all start at physical addr PAGE_OFFSET so
+ * we can let the map start there. notice that we subtract PAGE_OFFSET because
+ * we start our mem_map there - in other ports they map mem_map physically and
+ * use __pa instead. in our system both the physical and virtual adress of DRAM
+ * is too high to let mem_map start at 0, so we do it this way instead (similar
+ * to arm and m68k I think)
+ */ 
+
+#define virt_to_page(kaddr)    (mem_map + (((unsigned long)kaddr - PAGE_OFFSET) >> PAGE_SHIFT))
+#define VALID_PAGE(page)       ((page - mem_map) < max_mapnr)
+
+/* from linker script */
+
+extern unsigned long dram_start, dram_end;
+
+#endif /* __KERNEL__ */
+
+#endif /* _CRIS_PAGE_H */
+
diff -urN linux-2.4.2-pre1/include/asm-cris/param.h linux/include/asm-cris/param.h
--- linux-2.4.2-pre1/include/asm-cris/param.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/param.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,24 @@
+#ifndef _ASMCRIS_PARAM_H
+#define _ASMCRIS_PARAM_H
+
+#ifndef HZ
+#define HZ 100
+#endif
+
+#define EXEC_PAGESIZE	8192
+
+#ifndef NGROUPS
+#define NGROUPS		32
+#endif
+
+#ifndef NOGROUP
+#define NOGROUP		(-1)
+#endif
+
+#define MAXHOSTNAMELEN	64	/* max length of hostname */
+
+#ifdef __KERNEL__
+# define CLOCKS_PER_SEC        100     /* frequency at which times() counts */
+#endif
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/pci.h linux/include/asm-cris/pci.h
--- linux-2.4.2-pre1/include/asm-cris/pci.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/pci.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,9 @@
+#ifndef __ASM_CRIS_PCI_H
+#define __ASM_CRIS_PCI_H
+
+/* ETRAX chips don't have a PCI bus. This file is just here because some stupid .c code
+ * includes it even if CONFIG_PCI is not set.
+ */
+
+#endif /* __ASM_CRIS_PCI_H */
+
diff -urN linux-2.4.2-pre1/include/asm-cris/pgalloc.h linux/include/asm-cris/pgalloc.h
--- linux-2.4.2-pre1/include/asm-cris/pgalloc.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/pgalloc.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,200 @@
+#ifndef _CRIS_PGALLOC_H
+#define _CRIS_PGALLOC_H
+
+#include <linux/config.h>
+#include <asm/page.h>
+#include <linux/threads.h>
+
+/* bunch of protos */
+
+extern pgd_t *get_pgd_slow(void);
+extern void free_pgd_slow(pgd_t *pgd);
+extern __inline__ void free_pmd_slow(pmd_t *pmd) { }
+extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted);
+extern pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long address_preadjusted);
+
+/* first the non-cached versions */
+
+extern __inline__ void free_pte_slow(pte_t *pte)
+{
+        free_page((unsigned long)pte);
+}
+
+extern __inline__ pgd_t *get_pgd_slow(void)
+{
+        pgd_t *ret = (pgd_t *)__get_free_page(GFP_KERNEL);
+
+        if (ret) {
+                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));
+        }
+        return ret;
+}
+
+extern __inline__ void free_pgd_slow(pgd_t *pgd)
+{
+        free_page((unsigned long)pgd);
+}
+
+/*
+ * Now for the page table cache versions
+ */
+
+#ifndef CONFIG_NO_PGT_CACHE
+
+#ifdef CONFIG_SMP
+#error Pgtable caches have to be per-CPU, so that no locking is needed.
+#endif  /* CONFIG_SMP */
+
+extern struct pgtable_cache_struct {
+        unsigned long *pgd_cache;
+        unsigned long *pte_cache;
+        unsigned long pgtable_cache_sz;
+} quicklists;
+
+#define pgd_quicklist           (quicklists.pgd_cache)
+#define pmd_quicklist           ((unsigned long *)0)
+#define pte_quicklist           (quicklists.pte_cache)
+#define pgtable_cache_size      (quicklists.pgtable_cache_sz)
+
+extern __inline__ pgd_t *get_pgd_fast(void)
+{
+        unsigned long *ret;
+
+        if ((ret = pgd_quicklist) != NULL) {
+                pgd_quicklist = (unsigned long *)(*ret);
+                ret[0] = 0;
+                pgtable_cache_size--;
+        } else
+                ret = (unsigned long *)get_pgd_slow();
+        return (pgd_t *)ret;
+}
+
+extern __inline__ void free_pgd_fast(pgd_t *pgd)
+{
+        *(unsigned long *)pgd = (unsigned long) pgd_quicklist;
+        pgd_quicklist = (unsigned long *) pgd;
+        pgtable_cache_size++;
+}
+
+/* We don't use pmd cache, so this is a dummy routine */
+
+extern __inline__ pmd_t *get_pmd_fast(void)
+{
+        return (pmd_t *)0;
+}
+
+extern __inline__ void free_pmd_fast(pmd_t *pmd) { }
+
+extern __inline__ pte_t *get_pte_fast(void)
+{
+        unsigned long *ret;
+
+        if((ret = (unsigned long *)pte_quicklist) != NULL) {
+                pte_quicklist = (unsigned long *)(*ret);
+                ret[0] = ret[1];
+                pgtable_cache_size--;
+        }
+        return (pte_t *)ret;
+}
+
+extern __inline__ void free_pte_fast(pte_t *pte)
+{
+        *(unsigned long *)pte = (unsigned long) pte_quicklist;
+        pte_quicklist = (unsigned long *) pte;
+        pgtable_cache_size++;
+}
+
+#else   /* CONFIG_NO_PGT_CACHE */
+
+#define pgd_quicklist           ((unsigned long *)0)
+#define pmd_quicklist           ((unsigned long *)0)
+#define pte_quicklist           ((unsigned long *)0)
+
+#define get_pgd_fast()          ((pgd_t *)0)
+#define get_pmd_fast()          ((pmd_t *)0)
+#define get_pte_fast()          ((pte_t *)0)
+
+#define free_pgd_fast(pgd)      free_pgd_slow(pgd)
+#define free_pmd_fast(pmd)      free_pmd_slow(pmd)
+#define free_pte_fast(pte)      free_pte_slow(pte)
+
+#endif  /* CONFIG_NO_PGT_CACHE */
+
+/*
+ * Allocate and free page tables. The xxx_kernel() versions are
+ * used to allocate a kernel page table - this turns on ASN bits
+ * if any.
+ */
+
+#define pte_free_kernel(pte)    free_pte_slow(pte)
+#define pte_free(pte)           free_pte_slow(pte)
+
+extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address)
+{
+        if (!pmd)
+                BUG();
+        address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
+        if (pmd_none(*pmd)) {
+                pte_t * page = (pte_t *) get_pte_fast();
+                if (!page)
+                        return get_pte_kernel_slow(pmd, address);
+		pmd_set_kernel(pmd, page);
+                return page + address;
+        }
+        if (pmd_bad(*pmd)) {
+                __handle_bad_pmd_kernel(pmd);
+                return NULL;
+        }
+        return (pte_t *) pmd_page(*pmd) + address;
+}
+
+extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address)
+{
+        address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
+
+        if (pmd_none(*pmd))
+                goto getnew;
+        if (pmd_bad(*pmd))
+                goto fix;
+        return (pte_t *)pmd_page(*pmd) + address;
+ getnew:
+	{
+		pte_t * page = (pte_t *) get_pte_fast();
+		if (!page)
+			return get_pte_slow(pmd, address);
+		pmd_set(pmd, page);
+		return page + address;
+	}
+ fix:
+        __handle_bad_pmd(pmd);
+        return NULL;
+}
+
+/*
+ * allocating and freeing a pmd is trivial: the 1-entry pmd is
+ * inside the pgd, so has no extra memory associated with it.
+ */
+
+#define pmd_free(pmd)      free_pmd_slow(pmd)
+#define pmd_free_kernel    pmd_free
+#define pmd_alloc_kernel   pmd_alloc
+
+extern inline pmd_t * pmd_alloc(pgd_t *pgd, unsigned long address)
+{
+        if (!pgd)
+                BUG();
+        return (pmd_t *) pgd;
+}
+
+/* pgd handling */
+
+#define pgd_free(pgd)      free_pgd_slow(pgd)
+#define pgd_alloc()        get_pgd_fast()
+
+/* other stuff */
+
+extern int do_check_pgt_cache(int, int);
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/pgtable.h linux/include/asm-cris/pgtable.h
--- linux-2.4.2-pre1/include/asm-cris/pgtable.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/pgtable.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,518 @@
+/* CRIS pgtable.h - macros and functions to manipulate page tables
+ *
+ * HISTORY:
+ *
+ * $Log: pgtable.h,v $
+ * Revision 1.9  2000/11/22 14:57:53  bjornw
+ * * extern inline -> static inline
+ * * include asm-generic/pgtable.h
+ *
+ * Revision 1.8  2000/11/21 13:56:16  bjornw
+ * Use CONFIG_CRIS_LOW_MAP for the low VM map instead of explicit CPU type
+ *
+ * Revision 1.7  2000/10/06 15:05:32  bjornw
+ * VMALLOC area changed in memory mapping change
+ *
+ * Revision 1.6  2000/10/04 16:59:14  bjornw
+ * Changed comments
+ *
+ * Revision 1.5  2000/09/13 14:39:53  bjornw
+ * New macros
+ *
+ * Revision 1.4  2000/08/17 15:38:48  bjornw
+ * 2.4.0-test6 modifications:
+ *   * flush_dcache_page added
+ *   * MAP_NR removed
+ *   * virt_to_page added
+ *
+ * Plus some comments and type-clarifications.
+ *
+ * Revision 1.3  2000/08/15 16:33:35  bjornw
+ * pmd_bad should recognize both kernel and user page-tables
+ *
+ * Revision 1.2  2000/07/10 17:06:01  bjornw
+ * Fixed warnings
+ *
+ * Revision 1.1.1.1  2000/07/10 16:32:31  bjornw
+ * CRIS architecture, working draft
+ *
+ *
+ * Revision 1.11  2000/05/29 14:55:56  bjornw
+ * Small tweaks of pte_mk routines
+ *
+ * Revision 1.10  2000/01/27 01:49:06  bjornw
+ * * Ooops. The physical frame number in a PTE entry needs to point to the
+ *   DRAM directly, not to what the kernel thinks is DRAM (due to KSEG mapping).
+ *   Hence we need to strip bit 31 so 0xcXXXXXXX -> 0x4XXXXXXX.
+ *
+ * Revision 1.9  2000/01/26 16:25:50  bjornw
+ * Fixed PAGE_KERNEL bits
+ *
+ * Revision 1.8  2000/01/23 22:53:22  bjornw
+ * Correct flush_tlb_* macros and externs
+ *
+ * Revision 1.7  2000/01/18 16:22:55  bjornw
+ * Use PAGE_MASK instead of PFN_MASK.
+ *
+ * Revision 1.6  2000/01/17 02:42:53  bjornw
+ * Added the pmd_set macro.
+ *
+ * Revision 1.5  2000/01/16 19:53:42  bjornw
+ * Removed VMALLOC_OFFSET. Changed definitions of swapper_pg_dir and zero_page.
+ *
+ * Revision 1.4  2000/01/14 16:38:20  bjornw
+ * PAGE_DIRTY -> PAGE_SILENT_WRITE, removed PAGE_COW from PAGE_COPY.
+ *
+ * Revision 1.3  1999/12/04 20:12:21  bjornw
+ * * PTE bits have moved to asm/mmu.h
+ * * Fixed definitions of the higher level page protection bits
+ * * Added the pte_* functions, including dirty/accessed SW simulation
+ *   (these are exactly the same as for the MIPS port)
+ *
+ * Revision 1.2  1999/12/04 00:41:54  bjornw
+ * * Fixed page table offsets, sizes and shifts
+ * * Removed reference to i386 SMP stuff
+ * * Added stray comments about Linux/CRIS mm design
+ * * Include asm/mmu.h which will contain MMU details
+ *
+ * Revision 1.1  1999/12/03 15:04:02  bjornw
+ * Copied from include/asm-etrax100. For the new CRIS architecture.
+ */
+
+#ifndef _CRIS_PGTABLE_H
+#define _CRIS_PGTABLE_H
+
+#include <linux/config.h>
+#include <asm/mmu.h>
+
+/*
+ * The Linux memory management assumes a three-level page table setup. On
+ * CRIS, we use that, but "fold" the mid level into the top-level page
+ * table. Since the MMU TLB is software loaded through an interrupt, it
+ * supports any page table structure, so we could have used a three-level
+ * setup, but for the amounts of memory we normally use, a two-level is
+ * probably more efficient.
+ *
+ * This file contains the functions and defines necessary to modify and use
+ * the CRIS page table tree.
+ */
+
+/* The cache doesn't need to be flushed when TLB entries change (I think!) */
+#define flush_cache_all()			do { } while (0)
+#define flush_cache_mm(mm)			do { } while (0)
+#define flush_cache_range(mm, start, end)	do { } while (0)
+#define flush_cache_page(vma, vmaddr)		do { } while (0)
+#define flush_page_to_ram(page)			do { } while (0)
+#define flush_dcache_page(page)                 do { } while (0)
+#define flush_icache_range(start, end)          do { } while (0)
+#define flush_icache_page(vma,pg)               do { } while (0)
+
+/*
+ * TLB flushing (implemented in arch/cris/mm/tlb.c):
+ *
+ *  - flush_tlb() flushes the current mm struct TLBs
+ *  - flush_tlb_all() flushes all processes TLBs
+ *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
+ *  - flush_tlb_page(vma, vmaddr) flushes one page
+ *  - flush_tlb_range(mm, start, end) flushes a range of pages
+ *
+ */
+
+extern void flush_tlb_all(void);
+extern void flush_tlb_mm(struct mm_struct *mm);
+extern void flush_tlb_page(struct vm_area_struct *vma, 
+			   unsigned long addr);
+extern void flush_tlb_range(struct mm_struct *mm,
+			    unsigned long start,
+			    unsigned long end);
+
+static inline void flush_tlb_pgtables(struct mm_struct *mm,
+                                      unsigned long start, unsigned long end)
+{
+        /* CRIS does not keep any page table caches in TLB */
+}
+
+
+static inline void flush_tlb(void) 
+{
+	flush_tlb_mm(current->mm);
+}
+
+/* Certain architectures need to do special things when pte's
+ * within a page table are directly modified.  Thus, the following
+ * hook is made available.
+ */
+#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
+/*
+ * (pmds are folded into pgds so this doesnt get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
+#define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval)
+
+/* PMD_SHIFT determines the size of the area a second-level page table can
+ * map. It is equal to the page size times the number of PTE's that fit in
+ * a PMD page. A PTE is 4-bytes in CRIS. Hence the following number.
+ */
+
+#define PMD_SHIFT	(PAGE_SHIFT + (PAGE_SHIFT-2))
+#define PMD_SIZE	(1UL << PMD_SHIFT)
+#define PMD_MASK	(~(PMD_SIZE-1))
+
+/* PGDIR_SHIFT determines what a third-level page table entry can map.
+ * Since we fold into a two-level structure, this is the same as PMD_SHIFT.
+ */
+
+#define PGDIR_SHIFT	PMD_SHIFT
+#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
+#define PGDIR_MASK	(~(PGDIR_SIZE-1))
+
+/*
+ * entries per page directory level: we use a two-level, so
+ * we don't really have any PMD directory physically.
+ * pointers are 4 bytes so we can use the page size and 
+ * divide it by 4 (shift by 2).
+ */
+#define PTRS_PER_PTE	(1UL << (PAGE_SHIFT-2))
+#define PTRS_PER_PMD	1
+#define PTRS_PER_PGD	(1UL << (PAGE_SHIFT-2))
+
+/* calculate how many PGD entries a user-level program can use
+ * the first mappable virtual address is 0
+ * (TASK_SIZE is the maximum virtual address space)
+ */
+
+#define USER_PTRS_PER_PGD       (TASK_SIZE/PGDIR_SIZE)
+#define FIRST_USER_PGD_NR       0
+
+/*
+ * Kernels own virtual memory area. 
+ */
+
+#ifdef CONFIG_CRIS_LOW_MAP
+#define VMALLOC_START     KSEG_7
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       KSEG_8
+#else
+#define VMALLOC_START     KSEG_D
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       KSEG_E
+#endif
+
+/* Define some higher level generic page attributes. The PTE bits are
+ * defined in asm-cris/mmu.h, and these are just combinations of those.
+ */
+
+#define __READABLE      (_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED)
+#define __WRITEABLE     (_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED)
+
+#define _PAGE_TABLE     (_PAGE_PRESENT | __READABLE | __WRITEABLE)
+#define _PAGE_CHG_MASK  (PAGE_MASK | _PAGE_ACCESSED | _PAGE_SILENT_WRITE)
+
+#define PAGE_NONE       __pgprot(_PAGE_PRESENT | __READABLE)
+#define PAGE_SHARED     __pgprot(_PAGE_PRESENT | __READABLE | _PAGE_WRITE | \
+				 _PAGE_ACCESSED)
+#define PAGE_COPY       __pgprot(_PAGE_PRESENT | __READABLE)  // | _PAGE_COW
+#define PAGE_READONLY   __pgprot(_PAGE_PRESENT | __READABLE)
+#define PAGE_KERNEL     __pgprot(_PAGE_GLOBAL | _PAGE_KERNEL | \
+				 _PAGE_PRESENT | __READABLE | __WRITEABLE)
+#define _KERNPG_TABLE   (_PAGE_TABLE | _PAGE_KERNEL)
+
+/*
+ * CRIS can't do page protection for execute, and considers read the same.
+ * Also, write permissions imply read permissions. This is the closest we can
+ * get..
+ */
+
+#define __P000	PAGE_NONE
+#define __P001	PAGE_READONLY
+#define __P010	PAGE_COPY
+#define __P011	PAGE_COPY
+#define __P100	PAGE_READONLY
+#define __P101	PAGE_READONLY
+#define __P110	PAGE_COPY
+#define __P111	PAGE_COPY
+
+#define __S000	PAGE_NONE
+#define __S001	PAGE_READONLY
+#define __S010	PAGE_SHARED
+#define __S011	PAGE_SHARED
+#define __S100	PAGE_READONLY
+#define __S101	PAGE_READONLY
+#define __S110	PAGE_SHARED
+#define __S111	PAGE_SHARED
+
+/* zero page used for uninitialized stuff */
+extern unsigned long empty_zero_page;
+
+/*
+ * BAD_PAGETABLE is used when we need a bogus page-table, while
+ * BAD_PAGE is used for a bogus page.
+ *
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+extern pte_t __bad_page(void);
+extern pte_t * __bad_pagetable(void);
+
+#define BAD_PAGETABLE    __bad_pagetable()
+#define BAD_PAGE         __bad_page()
+#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
+
+/*
+ * Handling allocation failures during page table setup.
+ */
+extern void __handle_bad_pmd(pmd_t * pmd);
+extern void __handle_bad_pmd_kernel(pmd_t * pmd);
+
+/* number of bits that fit into a memory pointer */
+#define BITS_PER_PTR			(8*sizeof(unsigned long))
+
+/* to align the pointer to a pointer address */
+#define PTR_MASK			(~(sizeof(void*)-1))
+
+/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */
+/* 64-bit machines, beware!  SRB. */
+#define SIZEOF_PTR_LOG2			2
+
+/* to find an entry in a page-table */
+#define PAGE_PTR(address) \
+((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
+
+/* to set the page-dir */
+#define SET_PAGE_DIR(tsk,pgdir)
+
+#define pte_none(x)	(!pte_val(x))
+#define pte_present(x)	(pte_val(x) & _PAGE_PRESENT)
+#define pte_clear(xp)	do { pte_val(*(xp)) = 0; } while (0)
+
+#define pmd_none(x)	(!pmd_val(x))
+/* by removing the _PAGE_KERNEL bit from the comparision, the same pmd_bad
+ * works for both _PAGE_TABLE and _KERNPG_TABLE pmd entries.
+ */
+#define	pmd_bad(x)	((pmd_val(x) & (~PAGE_MASK & ~_PAGE_KERNEL)) != _PAGE_TABLE)
+#define pmd_present(x)	(pmd_val(x) & _PAGE_PRESENT)
+#define pmd_clear(xp)	do { pmd_val(*(xp)) = 0; } while (0)
+
+/*
+ * The "pgd_xxx()" functions here are trivial for a folded two-level
+ * setup: the pgd is never bad, and a pmd always exists (as it's folded
+ * into the pgd entry)
+ */
+static inline int pgd_none(pgd_t pgd)		{ return 0; }
+static inline int pgd_bad(pgd_t pgd)		{ return 0; }
+static inline int pgd_present(pgd_t pgd)	{ return 1; }
+static inline void pgd_clear(pgd_t * pgdp)	{ }
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+
+static inline int pte_read(pte_t pte)           { return pte_val(pte) & _PAGE_READ; }
+static inline int pte_write(pte_t pte)          { return pte_val(pte) & _PAGE_WRITE; }
+static inline int pte_exec(pte_t pte)           { return pte_val(pte) & _PAGE_READ; }
+static inline int pte_dirty(pte_t pte)          { return pte_val(pte) & _PAGE_MODIFIED; }
+static inline int pte_young(pte_t pte)          { return pte_val(pte) & _PAGE_ACCESSED; }
+
+static inline pte_t pte_wrprotect(pte_t pte)
+{
+        pte_val(pte) &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
+        return pte;
+}
+
+static inline pte_t pte_rdprotect(pte_t pte)
+{
+        pte_val(pte) &= ~(_PAGE_READ | _PAGE_SILENT_READ);
+	return pte;
+}
+
+static inline pte_t pte_exprotect(pte_t pte)
+{
+        pte_val(pte) &= ~(_PAGE_READ | _PAGE_SILENT_READ);
+	return pte;
+}
+
+static inline pte_t pte_mkclean(pte_t pte)
+{
+	pte_val(pte) &= ~(_PAGE_MODIFIED | _PAGE_SILENT_WRITE); 
+	return pte; 
+}
+
+static inline pte_t pte_mkold(pte_t pte)
+{
+	pte_val(pte) &= ~(_PAGE_ACCESSED | _PAGE_SILENT_READ);
+	return pte;
+}
+
+static inline pte_t pte_mkwrite(pte_t pte)
+{
+        pte_val(pte) |= _PAGE_WRITE;
+        if (pte_val(pte) & _PAGE_MODIFIED)
+                pte_val(pte) |= _PAGE_SILENT_WRITE;
+        return pte;
+}
+
+static inline pte_t pte_mkread(pte_t pte)
+{
+        pte_val(pte) |= _PAGE_READ;
+        if (pte_val(pte) & _PAGE_ACCESSED)
+                pte_val(pte) |= _PAGE_SILENT_READ;
+        return pte;
+}
+
+static inline pte_t pte_mkexec(pte_t pte)
+{
+        pte_val(pte) |= _PAGE_READ;
+        if (pte_val(pte) & _PAGE_ACCESSED)
+                pte_val(pte) |= _PAGE_SILENT_READ;
+        return pte;
+}
+
+static inline pte_t pte_mkdirty(pte_t pte)
+{
+        pte_val(pte) |= _PAGE_MODIFIED;
+        if (pte_val(pte) & _PAGE_WRITE)
+                pte_val(pte) |= _PAGE_SILENT_WRITE;
+        return pte;
+}
+
+static inline pte_t pte_mkyoung(pte_t pte)
+{
+        pte_val(pte) |= _PAGE_ACCESSED;
+        if (pte_val(pte) & _PAGE_READ)
+        {
+                pte_val(pte) |= _PAGE_SILENT_READ;
+                if ((pte_val(pte) & (_PAGE_WRITE | _PAGE_MODIFIED)) ==
+		    (_PAGE_WRITE | _PAGE_MODIFIED))
+                        pte_val(pte) |= _PAGE_SILENT_WRITE;
+        }
+        return pte;
+}
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+
+/* What actually goes as arguments to the various functions is less than
+ * obvious, but a rule of thumb is that struct page's goes as struct page *,
+ * really physical DRAM addresses are unsigned long's, and DRAM "virtual"
+ * addresses (the 0xc0xxxxxx's) goes as void *'s.
+ */
+
+static inline pte_t __mk_pte(void * page, pgprot_t pgprot)
+{
+	pte_t pte;
+	/* the PTE needs a physical address */
+	pte_val(pte) = __pa(page) | pgprot_val(pgprot);
+	return pte;
+}
+
+#define mk_pte(page, pgprot) __mk_pte(page_address(page), (pgprot))
+
+#define mk_pte_phys(physpage, pgprot) \
+({                                                                      \
+        pte_t __pte;                                                    \
+                                                                        \
+        pte_val(__pte) = (physpage) + pgprot_val(pgprot);               \
+        __pte;                                                          \
+})
+
+static 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; }
+
+
+/* pte_val refers to a page in the 0x4xxxxxxx physical DRAM interval
+ * __pte_page(pte_val) refers to the "virtual" DRAM interval
+ * pte_pagenr refers to the page-number counted starting from the virtual DRAM start
+ */
+
+static inline unsigned long __pte_page(pte_t pte)
+{
+	/* the PTE contains a physical address */
+	return (unsigned long)__va(pte_val(pte) & PAGE_MASK);
+}
+
+#define pte_pagenr(pte)         ((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT)
+
+/* permanent address of a page */
+
+#define page_address(page)      ((page)->virtual)
+#define __page_address(page)    (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
+#define pte_page(pte)           (mem_map+pte_pagenr(pte))
+
+/* only the pte's themselves need to point to physical DRAM (see above)
+ * the pagetable links are purely handled within the kernel SW and thus
+ * don't need the __pa and __va transformations.
+ */
+
+static inline unsigned long pmd_page(pmd_t pmd)
+{ return pmd_val(pmd) & PAGE_MASK; }
+
+static inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
+{ pmd_val(*pmdp) = _PAGE_TABLE | (unsigned long) ptep; }
+
+static inline void pmd_set_kernel(pmd_t * pmdp, pte_t * ptep)
+{ pmd_val(*pmdp) = _KERNPG_TABLE | (unsigned long) ptep; }
+
+/* to find an entry in a page-table-directory. */
+#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+
+/* to find an entry in a page-table-directory */
+static inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
+{
+	return mm->pgd + pgd_index(address);
+}
+
+/* to find an entry in a kernel page-table-directory */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
+/* Find an entry in the second-level page table.. */
+static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
+{
+	return (pmd_t *) dir;
+}
+
+/* Find an entry in the third-level page table.. */ 
+static inline pte_t * pte_offset(pmd_t * dir, unsigned long address)
+{
+	return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
+}
+
+#define pte_ERROR(e) \
+        printk("%s:%d: bad pte %p(%08lx).\n", __FILE__, __LINE__, &(e), pte_val(e))
+#define pmd_ERROR(e) \
+        printk("%s:%d: bad pmd %p(%08lx).\n", __FILE__, __LINE__, &(e), pmd_val(e))
+#define pgd_ERROR(e) \
+        printk("%s:%d: bad pgd %p(%08lx).\n", __FILE__, __LINE__, &(e), pgd_val(e))
+
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; /* defined in head.S */
+
+/*
+ * CRIS doesn't have any external MMU info: the kernel page
+ * tables contain all the necessary information.
+ * 
+ * Actually I am not sure on what this could be used for.
+ */
+static inline void update_mmu_cache(struct vm_area_struct * vma,
+	unsigned long address, pte_t pte)
+{
+}
+
+/* Encode and de-code a swap entry (must be !pte_none(e) && !pte_present(e)) */
+/* Since the PAGE_PRESENT bit is bit 4, we can use the bits above */
+
+#define SWP_TYPE(x)                     (((x).val >> 5) & 0x7f)
+#define SWP_OFFSET(x)                   ((x).val >> 12)
+#define SWP_ENTRY(type, offset)         ((swp_entry_t) { ((type) << 5) | ((offset) << 12) })
+#define pte_to_swp_entry(pte)           ((swp_entry_t) { pte_val(pte) })
+#define swp_entry_to_pte(x)             ((pte_t) { (x).val })
+
+/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
+#define PageSkip(page)          (0)
+#define kern_addr_valid(addr)   (1)
+
+#include <asm-generic/pgtable.h>
+
+#endif /* _CRIS_PGTABLE_H */
diff -urN linux-2.4.2-pre1/include/asm-cris/poll.h linux/include/asm-cris/poll.h
--- linux-2.4.2-pre1/include/asm-cris/poll.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/poll.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,24 @@
+#ifndef __ASM_CRIS_POLL_H
+#define __ASM_CRIS_POLL_H
+
+/* taken from asm-alpha */
+
+#define POLLIN		1
+#define POLLPRI		2
+#define POLLOUT		4
+#define POLLERR		8
+#define POLLHUP		16
+#define POLLNVAL	32
+#define POLLRDNORM	64
+#define POLLRDBAND	128
+#define POLLWRNORM	256
+#define POLLWRBAND	512
+#define POLLMSG		1024
+
+struct pollfd {
+	int fd;
+	short events;
+	short revents;
+};
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/posix_types.h linux/include/asm-cris/posix_types.h
--- linux-2.4.2-pre1/include/asm-cris/posix_types.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/posix_types.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,72 @@
+/* $Id: posix_types.h,v 1.1 2000/07/10 16:32:31 bjornw Exp $ */
+
+/* We cheat a bit and use our C-coded bitops functions from asm/bitops.h */
+/* I guess we should write these in assembler because they are used often. */
+
+#ifndef __ARCH_CRIS_POSIX_TYPES_H
+#define __ARCH_CRIS_POSIX_TYPES_H
+
+#include <asm/bitops.h>
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned short	__kernel_dev_t;
+typedef unsigned long	__kernel_ino_t;
+typedef unsigned short	__kernel_mode_t;
+typedef unsigned short	__kernel_nlink_t;
+typedef long		__kernel_off_t;
+typedef int		__kernel_pid_t;
+typedef unsigned short  __kernel_ipc_pid_t;
+typedef unsigned short	__kernel_uid_t;
+typedef unsigned short	__kernel_gid_t;
+typedef unsigned long	__kernel_size_t;
+typedef long		__kernel_ssize_t;
+typedef int		__kernel_ptrdiff_t;
+typedef long		__kernel_time_t;
+typedef long            __kernel_suseconds_t;
+typedef long		__kernel_clock_t;
+typedef int		__kernel_daddr_t;
+typedef char *		__kernel_caddr_t;
+typedef unsigned short  __kernel_uid16_t;
+typedef unsigned short  __kernel_gid16_t;
+typedef unsigned int    __kernel_uid32_t;
+typedef unsigned int    __kernel_gid32_t;
+
+typedef unsigned short  __kernel_old_uid_t;
+typedef unsigned short  __kernel_old_gid_t;
+
+#ifdef __GNUC__
+typedef long long	__kernel_loff_t;
+#endif
+
+typedef struct {
+#if defined(__KERNEL__) || defined(__USE_ALL)
+	int	val[2];
+#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+	int	__val[2];
+#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+} __kernel_fsid_t;
+
+/* should this ifdef be here ?  */
+
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+
+#undef	__FD_SET
+#define __FD_SET(fd,fdsetp) set_bit(fd, (void *)(fdsetp))
+
+#undef	__FD_CLR
+#define __FD_CLR(fd,fdsetp) clear_bit(fd, (void *)(fdsetp))
+
+#undef	__FD_ISSET
+#define __FD_ISSET(fd,fdsetp) test_bit(fd, (void *)(fdsetp))
+
+#undef	__FD_ZERO
+#define __FD_ZERO(fdsetp) memset((void *)(fdsetp), 0, __FDSET_LONGS << 2)
+
+#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+
+#endif /* __ARCH_CRIS_POSIX_TYPES_H */
diff -urN linux-2.4.2-pre1/include/asm-cris/processor.h linux/include/asm-cris/processor.h
--- linux-2.4.2-pre1/include/asm-cris/processor.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/processor.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,147 @@
+/*
+ * include/asm-cris/processor.h
+ *
+ * Copyright (C) 2000 Axis Communications AB
+ *
+ * Authors:         Bjorn Wesen        Initial version
+ *
+ */
+
+#ifndef __ASM_CRIS_PROCESSOR_H
+#define __ASM_CRIS_PROCESSOR_H
+
+#include <linux/config.h>
+#include <asm/system.h>
+#include <asm/ptrace.h>
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+
+/* CRIS has no problems with write protection */
+
+#define wp_works_ok 1
+
+/*
+ * User space process size. This is hardcoded into a few places,
+ * so don't change it unless you know what you are doing.
+ */
+
+#ifdef CONFIG_CRIS_LOW_MAP
+#define TASK_SIZE       (0x50000000UL)   /* 1.25 GB */
+#else
+#define TASK_SIZE       (0xB0000000UL)   /* 2.75 GB */
+#endif
+
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE      (TASK_SIZE / 3)
+
+/* CRIS thread_struct. this really has nothing to do with the processor itself, since
+ * CRIS does not do any hardware task-switching, but it's here for legacy reasons.
+ * The thread_struct here is used when task-switching using _resume defined in entry.S.
+ * The offsets here are hardcoded into _resume - if you change this struct, you need to
+ * change them as well!!!
+*/
+
+struct thread_struct {
+	unsigned long ksp;     /* kernel stack pointer */
+	unsigned long usp;     /* user stack pointer */
+	unsigned long esp0;    /* points to start of saved stack frame, set in entry.S */  
+	unsigned long dccr;    /* saved flag register */
+};
+
+/* saved stack-frame upon syscall entry, points to registers */
+
+#define current_regs() (current->thread.esp0)
+
+/* this lives in process.c */
+asmlinkage void set_esp0(unsigned long ssp);
+
+/* INIT_MMAP is the kernels map of memory, between KSEG_C and KSEG_D */
+
+#ifdef CONFIG_CRIS_LOW_MAP
+#define INIT_MMAP { &init_mm, KSEG_6, KSEG_7, NULL, PAGE_SHARED, \
+			     VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
+#else
+#define INIT_MMAP { &init_mm, KSEG_C, KSEG_D, NULL, PAGE_SHARED, \
+			     VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
+#endif
+
+#define INIT_THREAD  { \
+   0, 0, 0, 0x20 }  /* ccr = int enable, nothing else */
+
+/* TODO: REMOVE */
+#define alloc_kernel_stack()    __get_free_page(GFP_KERNEL)
+#define free_kernel_stack(page) free_page((page))
+
+extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
+/* give the thread a program location
+ * set user-mode (The 'U' flag (User mode flag) is CCR/DCCR bit 8) 
+ * switch user-stackpointer
+ */
+
+#define start_thread(regs, ip, usp) do { \
+	set_fs(USER_DS);      \
+	regs->irp = ip;       \
+	regs->dccr |= 1 << 8; \
+	wrusp(usp);           \
+} while(0)
+
+unsigned long get_wchan(struct task_struct *p);
+
+#define KSTK_EIP(tsk)   \
+    ({                  \
+        unsigned long eip = 0;   \
+        if ((tsk)->thread.esp0 > PAGE_SIZE && \
+            VALID_PAGE(virt_to_page((tsk)->thread.esp0))) \
+              eip = ((struct pt_regs *) (tsk)->thread.esp0)->irp; \
+        eip; })
+
+#define KSTK_ESP(tsk)   ((tsk) == current ? rdusp() : (tsk)->thread.usp)
+
+#define copy_segments(tsk, mm)          do { } while (0)
+#define release_segments(mm)            do { } while (0)
+#define forget_segments()               do { } while (0)
+ 
+/*
+ * Free current thread data structures etc..
+ */
+
+static inline void exit_thread(void)
+{
+}
+
+/* Free all resources held by a thread. */
+static inline void release_thread(struct task_struct *dead_task)
+{
+}
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+extern inline unsigned long thread_saved_pc(struct thread_struct *t)
+{
+	return (unsigned long)((struct pt_regs *)t->esp0)->irp;
+}
+
+/* THREAD_SIZE is the size of the task_struct/kernel_stack combo.
+ * normally, the stack is found by doing something like p + THREAD_SIZE
+ * in CRIS, a page is 8192 bytes, which seems like a sane size
+ */
+
+#define THREAD_SIZE     PAGE_SIZE
+#define KERNEL_STACK_SIZE PAGE_SIZE
+
+#define alloc_task_struct()  ((struct task_struct *) __get_free_pages(GFP_KERNEL,1))
+#define free_task_struct(p)  free_pages((unsigned long) (p), 1)
+#define get_task_struct(tsk) atomic_inc(&virt_to_page(tsk)->count)
+
+#define init_task       (init_task_union.task)
+#define init_stack      (init_task_union.stack)
+
+#endif /* __ASM_CRIS_PROCESSOR_H */
diff -urN linux-2.4.2-pre1/include/asm-cris/ptrace.h linux/include/asm-cris/ptrace.h
--- linux-2.4.2-pre1/include/asm-cris/ptrace.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/ptrace.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,99 @@
+#ifndef _CRIS_PTRACE_H
+#define _CRIS_PTRACE_H
+
+/* Register numbers in the ptrace system call interface */
+
+#define PT_FRAMETYPE 0
+#define PT_ORIG_R10  1
+#define PT_R13       2
+#define PT_R12       3
+#define PT_R11       4
+#define PT_R10       5
+#define PT_R9        6
+#define PT_R8        7
+#define PT_R7        8
+#define PT_R6        9
+#define PT_R5        10
+#define PT_R4        11
+#define PT_R3        12
+#define PT_R2        13
+#define PT_R1        14
+#define PT_R0        15
+#define PT_MOF       16
+#define PT_DCCR      17
+#define PT_SRP       18
+#define PT_IRP       19
+#define PT_MAX       19
+
+#define PT_USP       42    /* special case - USP is not in the pt_regs */
+
+/* Frame types */
+
+#define CRIS_FRAME_NORMAL   0  /* normal frame like pt_regs struct */
+#define CRIS_FRAME_BUSFAULT 1  /* SBFS frame of 4 longwords on top, including irp */
+#define CRIS_FRAME_FIXUP    2  /* SBFS frame which should do a normal return, not RBF */
+
+/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
+#define PTRACE_GETREGS            12
+#define PTRACE_SETREGS            13
+
+/* pt_regs not only specifices the format in the user-struct during
+ * ptrace but is also the frame format used in the kernel prologue/epilogues 
+ * themselves
+ */
+
+struct pt_regs {
+	unsigned long frametype;  /* type of stackframe */
+	unsigned long orig_r10;
+	/* pushed by movem r13, [sp] in SAVE_ALL, movem pushes backwards */
+	unsigned long r13; /* 8 */
+	unsigned long r12; /* 12 */
+	unsigned long r11; /* 16 */
+	unsigned long r10; /* 20 */
+	unsigned long r9;
+	unsigned long r8;
+	unsigned long r7;
+	unsigned long r6;
+	unsigned long r5;
+	unsigned long r4;
+	unsigned long r3;
+	unsigned long r2;
+	unsigned long r1;
+	unsigned long r0;
+	unsigned long mof;
+	unsigned long dccr;
+	unsigned long srp;
+	unsigned long irp;
+};
+
+/* switch_stack is the extra stuff pushed onto the stack in _resume (entry.S) when
+   doing a context-switch. it is used (apart from in resume) when a new thread is made 
+   and we need to make _resume (which is starting it for the first time) realise what
+   is going on. 
+
+   actually, the use is very close to the thread struct (TSS) in that both the switch_stack
+   and the TSS are used to keep thread stuff when switching in _resume.
+*/
+
+struct switch_stack {
+	unsigned long r9;
+	unsigned long r8;
+	unsigned long r7;
+	unsigned long r6;
+	unsigned long r5;
+	unsigned long r4;
+	unsigned long r3;
+	unsigned long r2;
+	unsigned long r1;
+	unsigned long r0;
+	unsigned long return_ip; /* ip that _resume will return to */
+};
+
+#ifdef __KERNEL__
+/* bit 8 is user-mode flag */
+#define user_mode(regs) ((regs)->dccr & 0x100)
+#define instruction_pointer(regs) ((regs)->irp)
+extern void show_regs(struct pt_regs *);
+#endif
+
+#endif /* _CRIS_PTRACE_H */
diff -urN linux-2.4.2-pre1/include/asm-cris/resource.h linux/include/asm-cris/resource.h
--- linux-2.4.2-pre1/include/asm-cris/resource.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/resource.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,47 @@
+#ifndef _CRIS_RESOURCE_H
+#define _CRIS_RESOURCE_H
+
+/*
+ * Resource limits
+ */
+
+#define RLIMIT_CPU	0		/* CPU time in ms */
+#define RLIMIT_FSIZE	1		/* Maximum filesize */
+#define RLIMIT_DATA	2		/* max data size */
+#define RLIMIT_STACK	3		/* max stack size */
+#define RLIMIT_CORE	4		/* max core file size */
+#define RLIMIT_RSS	5		/* max resident set size */
+#define RLIMIT_NPROC	6		/* max number of processes */
+#define RLIMIT_NOFILE	7		/* max number of open files */
+#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
+#define RLIMIT_AS	9		/* address space limit */
+#define RLIMIT_LOCKS   10              /* maximum file locks held */
+
+#define RLIM_NLIMITS	11
+
+/*
+ * SuS says limits have to be unsigned.
+ * Which makes a ton more sense anyway.
+ */
+#define RLIM_INFINITY	(~0UL)
+
+#ifdef __KERNEL__
+
+#define INIT_RLIMITS					\
+{							\
+	{ 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 },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+}
+
+#endif /* __KERNEL__ */
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/rtc.h linux/include/asm-cris/rtc.h
--- linux-2.4.2-pre1/include/asm-cris/rtc.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/rtc.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,59 @@
+/* $Id: rtc.h,v 1.1 2000/07/10 16:32:31 bjornw Exp $ */
+
+#ifndef RTC_H
+#define RTC_H
+
+#include <linux/config.h>
+
+/* Dallas DS1302 clock/calendar register numbers */
+
+#define RTC_SECONDS 0
+#define RTC_MINUTES 1
+#define RTC_HOURS 2
+#define RTC_DAY_OF_MONTH 3
+#define RTC_MONTH 4
+#define RTC_WEEKDAY 5
+#define RTC_YEAR 6
+
+#ifdef CONFIG_DS1302
+#define CMOS_READ(x) ds1302_readreg(x)
+#define CMOS_WRITE(val,reg) ds1302_writereg(reg,val)
+#define RTC_INIT() ds1302_init()
+#else
+/* no RTC configured so we shouldn't try to access any */
+#define CMOS_READ(x) 42
+#define CMOS_WRITE(x,y)
+#define RTC_INIT() (-1)
+#endif
+
+/* conversions to and from the stupid RTC internal format */
+
+#define BCD_TO_BIN(x) x = (((x & 0xf0) >> 3) * 5 + (x & 0xf))
+#define BIN_TO_BCD(x) x = (x % 10) | ((x / 10) << 4) 
+
+/*
+ * The struct used to pass data via the following ioctl. Similar to the
+ * struct tm in <time.h>, but it needs to be here so that the kernel 
+ * source is self contained, allowing cross-compiles, etc. etc.
+ */
+
+struct rtc_time {
+	int tm_sec;
+	int tm_min;
+	int tm_hour;
+	int tm_mday;
+	int tm_mon;
+	int tm_year;
+	int tm_wday;
+	int tm_yday;
+	int tm_isdst;
+};
+
+/*
+ * ioctl calls that are permitted to the /dev/rtc interface
+ */
+
+#define RTC_RD_TIME	_IOR('p', 0x09, struct rtc_time) /* Read RTC time   */
+#define RTC_SET_TIME	_IOW('p', 0x0a, struct rtc_time) /* Set RTC time    */
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/segment.h linux/include/asm-cris/segment.h
--- linux-2.4.2-pre1/include/asm-cris/segment.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/segment.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,16 @@
+#ifndef _ASM_SEGMENT_H
+#define _ASM_SEGMENT_H
+
+/* argh. really legacy. totally misnomed. */
+
+#define __KERNEL_CS	0x10
+#define __KERNEL_DS	0x18
+
+#define __USER_CS	0x23
+#define __USER_DS	0x2B
+
+typedef struct {
+  unsigned long seg;
+} mm_segment_t;
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/semaphore-helper.h linux/include/asm-cris/semaphore-helper.h
--- linux-2.4.2-pre1/include/asm-cris/semaphore-helper.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/semaphore-helper.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,77 @@
+/* $Id: semaphore-helper.h,v 1.1 2000/07/13 16:52:42 bjornw Exp $
+ *
+ * SMP- and interrupt-safe semaphores helper functions. Generic versions, no
+ * optimizations whatsoever... 
+ *
+ */
+
+#ifndef _ASM_SEMAPHORE_HELPER_H
+#define _ASM_SEMAPHORE_HELPER_H
+
+#include <asm/atomic.h>
+
+/*
+ * These two _must_ execute atomically wrt each other.
+ */
+static inline void wake_one_more(struct semaphore * sem)
+{
+	atomic_inc(&sem->waking);
+}
+
+#define read(a) ((a)->counter)
+#define inc(a) (((a)->counter)++)
+#define dec(a) (((a)->counter)--)
+
+#define count_inc(a) ((*(a))++)
+
+static inline int waking_non_zero(struct semaphore *sem)
+{
+	unsigned long flags;
+	int ret = 0;
+
+	save_and_cli(flags);
+	if (read(&sem->waking) > 0) {
+		dec(&sem->waking);
+		ret = 1;
+	}
+	restore_flags(flags);
+	return ret;
+}
+
+static inline int waking_non_zero_interruptible(struct semaphore *sem,
+						struct task_struct *tsk)
+{
+	int ret = 0;
+	unsigned long flags;
+
+	save_and_cli(flags);
+	if (read(&sem->waking) > 0) {
+		dec(&sem->waking);
+		ret = 1;
+	} else if (signal_pending(tsk)) {
+		count_inc(&sem->count);
+		ret = -EINTR;
+	}
+	restore_flags(flags);
+	return ret;
+}
+
+static inline int waking_non_zero_trylock(struct semaphore *sem)
+{
+        int ret = 1;
+	unsigned long flags;
+
+	save_and_cli(flags);
+	if (read(&sem->waking) <= 0)
+		count_inc(&sem->count);
+	else {
+		dec(&sem->waking);
+		ret = 0;
+	}
+	restore_flags(flags);
+	return ret;
+}
+
+#endif /* _ASM_SEMAPHORE_HELPER_H */
+
+
diff -urN linux-2.4.2-pre1/include/asm-cris/semaphore.h linux/include/asm-cris/semaphore.h
--- linux-2.4.2-pre1/include/asm-cris/semaphore.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/semaphore.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,321 @@
+/* $Id: semaphore.h,v 1.2 2000/07/13 16:52:46 bjornw Exp $ */
+
+/* On the i386 these are coded in asm, perhaps we should as well. Later.. */
+
+#ifndef _CRIS_SEMAPHORE_H
+#define _CRIS_SEMAPHORE_H
+
+#define RW_LOCK_BIAS             0x01000000
+
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+
+#include <asm/system.h>
+#include <asm/atomic.h>
+
+/*
+ * CRIS semaphores, implemented in C-only so far. 
+ */
+
+int printk(const char *fmt, ...);
+
+struct semaphore {
+	int count; /* not atomic_t since we do the atomicity here already */
+	atomic_t waking;
+	wait_queue_head_t wait;
+#if WAITQUEUE_DEBUG
+	long __magic;
+#endif
+};
+
+#if WAITQUEUE_DEBUG
+# define __SEM_DEBUG_INIT(name)         , (long)&(name).__magic
+#else
+# define __SEM_DEBUG_INIT(name)
+#endif
+
+#define __SEMAPHORE_INITIALIZER(name,count)             \
+        { count, ATOMIC_INIT(0),          \
+          __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
+          __SEM_DEBUG_INIT(name) }
+
+#define __MUTEX_INITIALIZER(name) \
+        __SEMAPHORE_INITIALIZER(name,1)
+
+#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+        struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+
+#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
+#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
+
+extern inline void sema_init(struct semaphore *sem, int val)
+{
+	*sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
+}
+
+static inline void init_MUTEX (struct semaphore *sem)
+{
+        sema_init(sem, 1);
+}
+
+static inline void init_MUTEX_LOCKED (struct semaphore *sem)
+{
+        sema_init(sem, 0);
+}
+
+extern void __down(struct semaphore * sem);
+extern int __down_interruptible(struct semaphore * sem);
+extern int __down_trylock(struct semaphore * sem);
+extern void __up(struct semaphore * sem);
+
+/* notice - we probably can do cli/sti here instead of saving */
+
+extern inline void down(struct semaphore * sem)
+{
+	unsigned long flags;
+	int failed;
+
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	/* atomically decrement the semaphores count, and if its negative, we wait */
+	save_flags(flags);
+	cli();
+	failed = --(sem->count) < 0;
+	restore_flags(flags);
+	if(failed) {
+		__down(sem);
+	}
+}
+
+/*
+ * This version waits in interruptible state so that the waiting
+ * process can be killed.  The down_interruptible routine
+ * returns negative for signalled and zero for semaphore acquired.
+ */
+
+extern inline int down_interruptible(struct semaphore * sem)
+{
+	unsigned long flags;
+	int failed;
+
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	/* atomically decrement the semaphores count, and if its negative, we wait */
+	save_flags(flags);
+	cli();
+	failed = --(sem->count) < 0;
+	restore_flags(flags);
+	if(failed)
+		failed = __down_interruptible(sem);
+	return(failed);
+}
+
+extern inline int down_trylock(struct semaphore * sem)
+{
+	unsigned long flags;
+	int failed;
+
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	save_flags(flags);
+	cli();
+	failed = --(sem->count) < 0;
+	restore_flags(flags);
+	if(failed)
+		failed = __down_trylock(sem);
+	return(failed);
+}
+
+/*
+ * Note! This is subtle. We jump to wake people up only if
+ * the semaphore was negative (== somebody was waiting on it).
+ * The default case (no contention) will result in NO
+ * jumps for both down() and up().
+ */
+extern inline void up(struct semaphore * sem)
+{  
+	unsigned long flags;
+	int wakeup;
+
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	/* atomically increment the semaphores count, and if it was negative, we wake people */
+	save_flags(flags);
+	cli();
+	wakeup = ++(sem->count) <= 0;
+	restore_flags(flags);
+	if(wakeup) {
+		__up(sem);
+	}
+}
+
+/* rw mutexes (should that be mutices? =) -- throw rw
+ * spinlocks and semaphores together, and this is what we
+ * end up with...
+ *
+ * The lock is initialized to BIAS.  This way, a writer
+ * subtracts BIAS ands gets 0 for the case of an uncontended
+ * lock.  Readers decrement by 1 and see a positive value
+ * when uncontended, negative if there are writers waiting
+ * (in which case it goes to sleep).
+ *
+ * In terms of fairness, this should result in the lock
+ * flopping back and forth between readers and writers
+ * under heavy use.
+ *
+ *              -ben
+ */
+
+struct rw_semaphore {
+        atomic_t                count;
+	/* bit 0 means read bias granted;
+	   bit 1 means write bias granted.  */
+        unsigned granted;
+        wait_queue_head_t       wait;
+        wait_queue_head_t       write_bias_wait;
+#if WAITQUEUE_DEBUG
+        long                    __magic;
+        atomic_t                readers;
+        atomic_t                writers;
+#endif
+};
+
+#if WAITQUEUE_DEBUG
+#define __RWSEM_DEBUG_INIT      , ATOMIC_INIT(0), ATOMIC_INIT(0)
+#else
+#define __RWSEM_DEBUG_INIT      /* */
+#endif
+
+#define __RWSEM_INITIALIZER(name,count) \
+{ ATOMIC_INIT(count), 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \
+        __WAIT_QUEUE_HEAD_INITIALIZER((name).write_bias_wait) \
+        __SEM_DEBUG_INIT(name) __RWSEM_DEBUG_INIT }
+
+#define __DECLARE_RWSEM_GENERIC(name,count) \
+        struct rw_semaphore name = __RWSEM_INITIALIZER(name,count)
+
+#define DECLARE_RWSEM(name) __DECLARE_RWSEM_GENERIC(name,RW_LOCK_BIAS)
+#define DECLARE_RWSEM_READ_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,RW_LOCK_BIAS-1)
+#define DECLARE_RWSEM_WRITE_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,0)
+
+extern inline void init_rwsem(struct rw_semaphore *sem)
+{
+        atomic_set(&sem->count, RW_LOCK_BIAS);
+        sem->granted = 0;
+        init_waitqueue_head(&sem->wait);
+        init_waitqueue_head(&sem->write_bias_wait);
+#if WAITQUEUE_DEBUG
+        sem->__magic = (long)&sem->__magic;
+        atomic_set(&sem->readers, 0);
+        atomic_set(&sem->writers, 0);
+#endif
+}
+
+/* The expensive part is outlined.  */
+extern void __down_read(struct rw_semaphore *sem, int count);
+extern void __down_write(struct rw_semaphore *sem, int count);
+extern void __rwsem_wake(struct rw_semaphore *sem, unsigned long readers);
+
+extern inline void down_read(struct rw_semaphore *sem)
+{
+        int count;
+
+#if WAITQUEUE_DEBUG
+        CHECK_MAGIC(sem->__magic);
+#endif
+
+        count = atomic_dec_return(&sem->count);
+        if (count < 0) {
+                __down_read(sem, count);
+        }
+        mb();
+
+#if WAITQUEUE_DEBUG
+        if (sem->granted & 2)
+                BUG();
+        if (atomic_read(&sem->writers))
+                BUG();
+        atomic_inc(&sem->readers);
+#endif
+}
+
+extern inline void down_write(struct rw_semaphore *sem)
+{
+        int count;
+
+#if WAITQUEUE_DEBUG
+        CHECK_MAGIC(sem->__magic);
+#endif
+
+        count = atomic_sub_return(RW_LOCK_BIAS, &sem->count);
+        if (count) {
+                __down_write(sem, count);
+        }
+        mb();
+
+#if WAITQUEUE_DEBUG
+        if (atomic_read(&sem->writers))
+                BUG();
+        if (atomic_read(&sem->readers))
+                BUG();
+        if (sem->granted & 3)
+                BUG();
+        atomic_inc(&sem->writers);
+#endif
+}
+
+/* When a reader does a release, the only significant case is when
+   there was a writer waiting, and we've bumped the count to 0: we must
+   wake the writer up.  */
+
+extern inline void up_read(struct rw_semaphore *sem)
+{
+#if WAITQUEUE_DEBUG
+        CHECK_MAGIC(sem->__magic);
+        if (sem->granted & 2)
+                BUG();
+        if (atomic_read(&sem->writers))
+                BUG();
+        atomic_dec(&sem->readers);
+#endif
+
+        mb();
+        if (atomic_inc_return(&sem->count) == 0)
+                __rwsem_wake(sem, 0);
+}
+
+/*
+ * Releasing the writer is easy -- just release it and wake up any sleepers.
+ */
+extern inline void up_write(struct rw_semaphore *sem)
+{
+        int count;
+
+#if WAITQUEUE_DEBUG
+        CHECK_MAGIC(sem->__magic);
+        if (sem->granted & 3)
+                BUG();
+        if (atomic_read(&sem->readers))
+                BUG();
+        if (atomic_read(&sem->writers) != 1)
+                BUG();
+        atomic_dec(&sem->writers);
+#endif
+
+        mb();
+        count = atomic_add_return(RW_LOCK_BIAS, &sem->count);
+        if (count - RW_LOCK_BIAS < 0 && count >= 0) {
+                /* Only do the wake if we're no longer negative.  */
+                __rwsem_wake(sem, count);
+        }
+}
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/sembuf.h linux/include/asm-cris/sembuf.h
--- linux-2.4.2-pre1/include/asm-cris/sembuf.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/sembuf.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,25 @@
+#ifndef _CRIS_SEMBUF_H
+#define _CRIS_SEMBUF_H
+
+/* 
+ * The semid64_ds structure for CRIS architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct semid64_ds {
+	struct ipc64_perm sem_perm;		/* permissions .. see ipc.h */
+	__kernel_time_t	sem_otime;		/* last semop time */
+	unsigned long	__unused1;
+	__kernel_time_t	sem_ctime;		/* last change time */
+	unsigned long	__unused2;
+	unsigned long	sem_nsems;		/* no. of semaphores in array */
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* _CRIS_SEMBUF_H */
diff -urN linux-2.4.2-pre1/include/asm-cris/setup.h linux/include/asm-cris/setup.h
--- linux-2.4.2-pre1/include/asm-cris/setup.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/setup.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,405 @@
+/*
+** asm/setup.h -- Definition of the Linux/m68k boot information structure
+**
+** Copyright 1992 by Greg Harp
+**
+** This file is subject to the terms and conditions of the GNU General Public
+** License.  See the file COPYING in the main directory of this archive
+** for more details.
+**
+** Created 09/29/92 by Greg Harp
+**
+** 5/2/94 Roman Hodek:
+**   Added bi_atari part of the machine dependent union bi_un; for now it
+**   contains just a model field to distinguish between TT and Falcon.
+** 26/7/96 Roman Zippel:
+**   Renamed to setup.h; added some useful macros to allow gcc some
+**   optimizations if possible.
+*/
+
+#ifndef _M68K_SETUP_H
+#define _M68K_SETUP_H
+
+#include <linux/config.h>
+
+#define CL_SIZE	(256)
+
+#if 0
+
+#include <asm/zorro.h>
+
+/*
+ * Amiga specific part of bootinfo structure.
+ */
+
+#define NUM_AUTO    16
+
+#ifndef __ASSEMBLY__
+
+#define AMIGAHW_DECLARE(name)	unsigned name : 1
+#define AMIGAHW_SET(name)	(boot_info.bi_amiga.hw_present.name = 1)
+#define AMIGAHW_PRESENT(name)	(boot_info.bi_amiga.hw_present.name)
+
+struct bi_Amiga {
+	int model;				/* Amiga Model (3000?) */
+	int num_autocon;			/* # of autoconfig devices found */
+	struct ConfigDev autocon[NUM_AUTO];	/* up to 16 autoconfig devices */
+#ifdef HACKER_KERNEL
+	void (*exit_func)(void);		/* addr of function to exit kernel */
+	unsigned long chip_addr;		/* start of chip memory (bytes) */
+#endif
+	unsigned long chip_size;		/* size of chip memory (bytes) */
+	unsigned char vblank;	 		/* VBLANK frequency */
+	unsigned char psfreq; 			/* power supply frequency */
+	unsigned long eclock; 			/* EClock frequency */
+	unsigned long chipset;			/* native chipset present */
+	struct {
+		/* video hardware */
+		AMIGAHW_DECLARE(AMI_VIDEO);	/* Amiga Video */
+		AMIGAHW_DECLARE(AMI_BLITTER);	/* Amiga Blitter */
+		AMIGAHW_DECLARE(AMBER_FF);	/* Amber Flicker Fixer */
+		/* sound hardware */
+		AMIGAHW_DECLARE(AMI_AUDIO);	/* Amiga Audio */
+		/* disk storage interfaces */
+		AMIGAHW_DECLARE(AMI_FLOPPY);	/* Amiga Floppy */
+		AMIGAHW_DECLARE(A3000_SCSI);	/* SCSI (wd33c93, A3000 alike) */
+		AMIGAHW_DECLARE(A4000_SCSI);	/* SCSI (ncr53c710, A4000T alike) */
+		AMIGAHW_DECLARE(A1200_IDE);	/* IDE (A1200 alike) */
+		AMIGAHW_DECLARE(A4000_IDE);	/* IDE (A4000 alike) */
+		AMIGAHW_DECLARE(CD_ROM);	/* CD ROM drive */
+		/* other I/O hardware */
+		AMIGAHW_DECLARE(AMI_KEYBOARD);	/* Amiga Keyboard */
+		AMIGAHW_DECLARE(AMI_MOUSE);	/* Amiga Mouse */
+		AMIGAHW_DECLARE(AMI_SERIAL);	/* Amiga Serial */
+		AMIGAHW_DECLARE(AMI_PARALLEL);	/* Amiga Parallel */
+		/* real time clocks */
+		AMIGAHW_DECLARE(A2000_CLK);	/* Hardware Clock (A2000 alike) */
+		AMIGAHW_DECLARE(A3000_CLK);	/* Hardware Clock (A3000 alike) */
+		/* supporting hardware */
+		AMIGAHW_DECLARE(CHIP_RAM);	/* Chip RAM */
+		AMIGAHW_DECLARE(PAULA);		/* Paula (8364) */
+		AMIGAHW_DECLARE(DENISE);	/* Denise (8362) */
+		AMIGAHW_DECLARE(DENISE_HR);	/* Denise (8373) */
+		AMIGAHW_DECLARE(LISA);		/* Lisa (8375) */
+		AMIGAHW_DECLARE(AGNUS_PAL);	/* Normal/Fat PAL Agnus (8367/8371) */
+		AMIGAHW_DECLARE(AGNUS_NTSC);	/* Normal/Fat NTSC Agnus (8361/8370) */
+		AMIGAHW_DECLARE(AGNUS_HR_PAL);	/* Fat Hires PAL Agnus (8372) */
+		AMIGAHW_DECLARE(AGNUS_HR_NTSC);	/* Fat Hires NTSC Agnus (8372) */
+		AMIGAHW_DECLARE(ALICE_PAL);	/* PAL Alice (8374) */
+		AMIGAHW_DECLARE(ALICE_NTSC);	/* NTSC Alice (8374) */
+		AMIGAHW_DECLARE(MAGIC_REKICK);	/* A3000 Magic Hard Rekick */
+		AMIGAHW_DECLARE(ZORRO);		/* Zorro AutoConfig */
+	} hw_present;
+};
+
+#else	/* __ASSEMBLY__ */
+ 
+BI_amiga_model		= BI_un
+BI_amiga_num_autcon	= BI_amiga_model+4
+BI_amiga_autocon	= BI_amiga_num_autcon+4
+#ifdef HACKER_KERNEL
+BI_amiga_exit_func	= BI_amiga_autocon+(CD_sizeof*NUM_AUTO)
+BI_amiga_chip_addr	= BI_amiga_exit_func+4
+BI_amiga_chip_size	= BI_amiga_chip_addr+4
+#else
+BI_amiga_chip_size	= BI_amiga_autocon+(CD_sizeof*NUM_AUTO)
+#endif
+BI_amiga_vblank		= BI_amiga_chip_size+4
+BI_amiga_psfreq		= BI_amiga_vblank+1
+BI_amiga_eclock		= BI_amiga_psfreq+1
+BI_amiga_chipset	= BI_amiga_eclock+4
+BI_amiga_hw_present	= BI_amiga_chipset+4
+
+#endif	/* __ASSEMBLY__ */
+
+/* Atari specific part of bootinfo */
+
+/*
+ * Define several Hardware-Chips for indication so that for the ATARI we do
+ * no longer decide whether it is a Falcon or other machine . It's just
+ * important what hardware the machine uses
+ */
+
+/* ++roman 08/08/95: rewritten from ORing constants to a C bitfield */
+
+#ifndef __ASSEMBLY__
+
+#define ATARIHW_DECLARE(name)	unsigned name : 1
+#define ATARIHW_SET(name)	(boot_info.bi_atari.hw_present.name = 1)
+#define ATARIHW_PRESENT(name)	(boot_info.bi_atari.hw_present.name)
+
+struct bi_Atari {
+	struct {
+		/* video hardware */
+		ATARIHW_DECLARE(STND_SHIFTER);	/* ST-Shifter - no base low ! */
+		ATARIHW_DECLARE(EXTD_SHIFTER);	/* STe-Shifter - 24 bit address */
+		ATARIHW_DECLARE(TT_SHIFTER);	/* TT-Shifter */
+		ATARIHW_DECLARE(VIDEL_SHIFTER);	/* Falcon-Shifter */
+		/* sound hardware */
+		ATARIHW_DECLARE(YM_2149);	/* Yamaha YM 2149 */
+		ATARIHW_DECLARE(PCM_8BIT);	/* PCM-Sound in STe-ATARI */
+		ATARIHW_DECLARE(CODEC);		/* CODEC Sound (Falcon) */
+		/* disk storage interfaces */
+		ATARIHW_DECLARE(TT_SCSI);	/* Directly mapped NCR5380 */
+		ATARIHW_DECLARE(ST_SCSI);	/* NCR5380 via ST-DMA (Falcon) */
+		ATARIHW_DECLARE(ACSI);		/* Standard ACSI like in STs */
+		ATARIHW_DECLARE(IDE);		/* IDE Interface */
+		ATARIHW_DECLARE(FDCSPEED);	/* 8/16 MHz switch for FDC */
+		/* other I/O hardware */
+		ATARIHW_DECLARE(ST_MFP);	/* The ST-MFP (there should
+						   be no Atari without
+						   it... but who knows?) */
+		ATARIHW_DECLARE(TT_MFP);	/* 2nd MFP */
+		ATARIHW_DECLARE(SCC);		/* Serial Communications Contr. */
+		ATARIHW_DECLARE(ST_ESCC);	/* SCC Z83230 in an ST */
+		ATARIHW_DECLARE(ANALOG_JOY);	/* Paddle Interface for STe
+						   and Falcon */
+		ATARIHW_DECLARE(MICROWIRE);	/* Microwire Interface */
+		/* DMA */
+		ATARIHW_DECLARE(STND_DMA);	/* 24 Bit limited ST-DMA */
+		ATARIHW_DECLARE(EXTD_DMA);	/* 32 Bit ST-DMA */
+		ATARIHW_DECLARE(SCSI_DMA);	/* DMA for the NCR5380 */
+		ATARIHW_DECLARE(SCC_DMA);	/* DMA for the SCC */
+		/* real time clocks */
+		ATARIHW_DECLARE(TT_CLK);	/* TT compatible clock chip */
+		ATARIHW_DECLARE(MSTE_CLK);	/* Mega ST(E) clock chip */
+		/* supporting hardware */
+		ATARIHW_DECLARE(SCU);		/* System Control Unit */
+		ATARIHW_DECLARE(BLITTER);	/* Blitter */
+		ATARIHW_DECLARE(VME);		/* VME Bus */
+	} hw_present;
+	unsigned long mch_cookie;		/* _MCH cookie from TOS */
+};
+
+/* mch_cookie values (upper word) */
+#define	ATARI_MCH_ST		0
+#define	ATARI_MCH_STE		1
+#define	ATARI_MCH_TT		2
+#define	ATARI_MCH_FALCON	3
+
+struct mem_info {
+	unsigned long addr;			/* physical address of memory chunk */
+	unsigned long size;			/* length of memory chunk (in bytes) */
+};
+
+#else	/* __ASSEMBLY__ */
+
+MI_addr		= 0
+MI_size		= MI_addr+4
+MI_sizeof	= MI_size+4
+
+#endif /* __ASSEMBLY__ */
+
+#define NUM_MEMINFO  4
+
+#define MACH_AMIGA   1
+#define MACH_ATARI   2
+#define MACH_MAC     3
+
+/*
+ * CPU and FPU types
+ */
+
+#define CPUB_68020 0
+#define CPUB_68030 1
+#define CPUB_68040 2
+#define CPUB_68060 3
+#define FPUB_68881 5
+#define FPUB_68882 6
+#define FPUB_68040 7				/* Internal FPU */
+#define FPUB_68060 8				/* Internal FPU */
+
+#define CPU_68020    (1<<CPUB_68020)
+#define CPU_68030    (1<<CPUB_68030)
+#define CPU_68040    (1<<CPUB_68040)
+#define CPU_68060    (1<<CPUB_68060)
+#define CPU_MASK     (31)
+#define FPU_68881    (1<<FPUB_68881)
+#define FPU_68882    (1<<FPUB_68882)
+#define FPU_68040    (1<<FPUB_68040)		/* Internal FPU */
+#define FPU_68060    (1<<FPUB_68060)		/* Internal FPU */
+#define FPU_MASK     (0xfe0)
+
+#define CL_SIZE      (256)
+
+/*
+ * machine type definitions
+ */
+
+#if !defined(CONFIG_AMIGA)
+#  define MACH_IS_AMIGA (0)
+#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC)
+#  define MACH_IS_AMIGA (boot_info.machtype == MACH_AMIGA)
+#else
+#  define CONFIG_AMIGA_ONLY
+#  define MACH_IS_AMIGA (1)
+#  define MACH_TYPE (MACH_AMIGA)
+#endif
+
+#if !defined(CONFIG_ATARI)
+#  define MACH_IS_ATARI (0)
+#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
+#  define MACH_IS_ATARI (boot_info.machtype == MACH_ATARI)
+#else
+#  define CONFIG_ATARI_ONLY
+#  define MACH_IS_ATARI (1)
+#  define MACH_TYPE (MACH_ATARI)
+#endif
+
+#if defined(CONFIG_MAC)
+#  error Currently no Mac support!
+#endif
+
+#ifndef MACH_TYPE
+#  define MACH_TYPE (boot_info.machtype)
+#endif
+
+/*
+ * cpu type definitions
+ */
+
+#if !defined(CONFIG_M68020)
+#  define CPU_IS_020 (0)
+#elif defined(CONFIG_M68030) || defined(CONFIG_M68040) || defined(CONFIG_M68060)
+#  define CPU_IS_020 (boot_info.cputype & CPU_68020)
+#else
+#  define CONFIG_M68020_ONLY
+#  define CPU_IS_020 (1)
+#endif
+
+#if !defined(CONFIG_M68030)
+#  define CPU_IS_030 (0)
+#elif defined(CONFIG_M68020) || defined(CONFIG_M68040) || defined(CONFIG_M68060)
+#  define CPU_IS_030 (boot_info.cputype & CPU_68030)
+#else
+#  define CONFIG_M68030_ONLY
+#  define CPU_IS_030 (1)
+#endif
+
+#if !defined(CONFIG_M68040)
+#  define CPU_IS_040 (0)
+#elif defined(CONFIG_M68020) || defined(CONFIG_M68030) || defined(CONFIG_M68060)
+#  define CPU_IS_040 (boot_info.cputype & CPU_68040)
+#else
+#  define CONFIG_M68040_ONLY
+#  define CPU_IS_040 (1)
+#endif
+
+#if !defined(CONFIG_M68060)
+#  define CPU_IS_060 (0)
+#elif defined(CONFIG_M68020) || defined(CONFIG_M68030) || defined(CONFIG_M68040)
+#  define CPU_IS_060 (boot_info.cputype & CPU_68060)
+#else
+#  define CONFIG_M68060_ONLY
+#  define CPU_IS_060 (1)
+#endif
+
+#if !defined(CONFIG_M68020) && !defined(CONFIG_M68030)
+#  define CPU_IS_020_OR_030 (0)
+#else
+#  define CONFIG_M68020_OR_M68030
+#  if defined(CONFIG_M68040) || defined(CONFIG_M68060)
+#    define CPU_IS_020_OR_030 (!m68k_is040or060)
+#  else
+#    define CONFIG_M68020_OR_M68030_ONLY
+#    define CPU_IS_020_OR_030 (1)
+#  endif
+#endif
+
+#if !defined(CONFIG_M68040) && !defined(CONFIG_M68060)
+#  define CPU_IS_040_OR_060 (0)
+#else
+#  define CONFIG_M68040_OR_M68060
+#  if defined(CONFIG_M68020) || defined(CONFIG_M68030)
+#    define CPU_IS_040_OR_060 (m68k_is040or060)
+#  else
+#    define CONFIG_M68040_OR_M68060_ONLY
+#    define CPU_IS_040_OR_060 (1)
+#  endif
+#endif
+
+#define CPU_TYPE (boot_info.cputype)
+
+#ifndef __ASSEMBLY__
+#ifdef __KERNEL__
+	/*
+	 * m68k_is040or060 is != 0 for a '040 or higher;
+	 * used numbers are 4 for 68040 and 6 for 68060.
+	 */
+
+extern int m68k_is040or060;
+#endif
+
+struct bootinfo {
+	unsigned long machtype;			/* machine type */
+	unsigned long cputype;			/* system CPU & FPU */
+	struct mem_info memory[NUM_MEMINFO];	/* memory description */
+	int num_memory;				/* # of memory blocks found */
+	unsigned long ramdisk_size;		/* ramdisk size in 1024 byte blocks */
+	unsigned long ramdisk_addr;		/* address of the ram disk in mem */
+	char command_line[CL_SIZE];		/* kernel command line parameters */
+	union {
+		struct bi_Amiga bi_ami; 	/* Amiga specific information */
+		struct bi_Atari bi_ata; 	/* Atari specific information */
+	} bi_un;
+};
+#define bi_amiga bi_un.bi_ami
+#define bi_atari bi_un.bi_ata
+#define bi_mac	 bi_un.bi_mac
+
+extern struct bootinfo
+    boot_info;
+
+#else	/* __ASSEMBLY__ */
+
+BI_machtype	= 0
+BI_cputype	= BI_machtype+4
+BI_memory	= BI_cputype+4
+BI_num_memory	= BI_memory+(MI_sizeof*NUM_MEMINFO)
+BI_ramdisk_size	= BI_num_memory+4
+BI_ramdisk_addr	= BI_ramdisk_size+4
+BI_command_line	= BI_ramdisk_addr+4
+BI_un		= BI_command_line+CL_SIZE
+
+#endif /* __ASSEMBLY__ */
+
+
+/*
+ * Stuff for bootinfo interface versioning
+ *
+ * At the start of kernel code, a 'struct bootversion' is located. bootstrap
+ * checks for a matching version of the interface before booting a kernel, to
+ * avoid user confusion if kernel and bootstrap don't work together :-)
+ *
+ * If incompatible changes are made to the bootinfo interface, the major
+ * number below should be stepped (and the minor reset to 0) for the
+ * appropriate machine. If a change is backward-compatible, the minor should
+ * be stepped. "Backwards-compatible" means that booting will work, but
+ * certain features may not.
+ */
+
+#define BOOTINFOV_MAGIC			0x4249561A	/* 'BIV^Z' */
+#define MK_BI_VERSION(major,minor)	(((major)<<16)+(minor))
+#define BI_VERSION_MAJOR(v)		(((v) >> 16) & 0xffff)
+#define BI_VERSION_MINOR(v)		((v) & 0xffff)
+
+#ifndef __ASSEMBLY__
+
+struct bootversion {
+	unsigned short branch;
+	unsigned long magic;
+	struct {
+		unsigned long machtype;
+		unsigned long version;
+	} machversions[0];
+};
+
+#endif /* __ASSEMBLY__ */
+
+#define AMIGA_BOOTI_VERSION    MK_BI_VERSION( 1, 0 )
+#define ATARI_BOOTI_VERSION    MK_BI_VERSION( 1, 0 )
+
+#endif
+
+
+#endif /* _M68K_SETUP_H */
diff -urN linux-2.4.2-pre1/include/asm-cris/shmbuf.h linux/include/asm-cris/shmbuf.h
--- linux-2.4.2-pre1/include/asm-cris/shmbuf.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/shmbuf.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,42 @@
+#ifndef _CRIS_SHMBUF_H
+#define _CRIS_SHMBUF_H
+
+/* 
+ * The shmid64_ds structure for CRIS architecture (same as for i386)
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct shmid64_ds {
+	struct ipc64_perm	shm_perm;	/* operation perms */
+	size_t			shm_segsz;	/* size of segment (bytes) */
+	__kernel_time_t		shm_atime;	/* last attach time */
+	unsigned long		__unused1;
+	__kernel_time_t		shm_dtime;	/* last detach time */
+	unsigned long		__unused2;
+	__kernel_time_t		shm_ctime;	/* last change time */
+	unsigned long		__unused3;
+	__kernel_pid_t		shm_cpid;	/* pid of creator */
+	__kernel_pid_t		shm_lpid;	/* pid of last operator */
+	unsigned long		shm_nattch;	/* no. of current attaches */
+	unsigned long		__unused4;
+	unsigned long		__unused5;
+};
+
+struct shminfo64 {
+	unsigned long	shmmax;
+	unsigned long	shmmin;
+	unsigned long	shmmni;
+	unsigned long	shmseg;
+	unsigned long	shmall;
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* _CRIS_SHMBUF_H */
diff -urN linux-2.4.2-pre1/include/asm-cris/shmparam.h linux/include/asm-cris/shmparam.h
--- linux-2.4.2-pre1/include/asm-cris/shmparam.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/shmparam.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,8 @@
+#ifndef _ASM_CRIS_SHMPARAM_H
+#define _ASM_CRIS_SHMPARAM_H
+
+/* same as asm-i386/ version.. */
+
+#define	SHMLBA PAGE_SIZE		 /* attach addr a multiple of this */
+
+#endif /* _ASM_CRIS_SHMPARAM_H */
diff -urN linux-2.4.2-pre1/include/asm-cris/sigcontext.h linux/include/asm-cris/sigcontext.h
--- linux-2.4.2-pre1/include/asm-cris/sigcontext.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/sigcontext.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,24 @@
+/* $Id: sigcontext.h,v 1.1 2000/07/10 16:32:31 bjornw Exp $ */
+
+#ifndef _ASM_CRIS_SIGCONTEXT_H
+#define _ASM_CRIS_SIGCONTEXT_H
+
+#include <asm/ptrace.h>
+
+/* This struct is saved by setup_frame in signal.c, to keep the current context while
+   a signal handler is executed. It's restored by sys_sigreturn.
+   
+   To keep things simple, we use pt_regs here even though normally you just specify
+   the list of regs to save. Then we can use copy_from_user on the entire regs instead
+   of a bunch of get_user's as well...
+
+*/
+
+struct sigcontext {
+	struct pt_regs regs;  /* needs to be first */
+	unsigned long oldmask;
+	unsigned long usp;    /* usp before stacking this gunk on it */
+};
+
+#endif
+
diff -urN linux-2.4.2-pre1/include/asm-cris/siginfo.h linux/include/asm-cris/siginfo.h
--- linux-2.4.2-pre1/include/asm-cris/siginfo.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/siginfo.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,232 @@
+#ifndef _CRIS_SIGINFO_H
+#define _CRIS_SIGINFO_H
+
+#include <linux/types.h>
+
+/* This is copied from asm-m68k/siginfo.h.  */
+
+typedef union sigval {
+	int sival_int;
+	void *sival_ptr;
+} sigval_t;
+
+#define SI_MAX_SIZE	128
+#define SI_PAD_SIZE	((SI_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct siginfo {
+	int si_signo;
+	int si_errno;
+	int si_code;
+
+	union {
+		int _pad[SI_PAD_SIZE];
+
+		/* kill() */
+		struct {
+			pid_t _pid;		/* sender's pid */
+			uid_t _uid;		/* sender's uid */
+		} _kill;
+
+		/* POSIX.1b timers */
+		struct {
+			unsigned int _timer1;
+			unsigned int _timer2;
+		} _timer;
+
+		/* POSIX.1b signals */
+		struct {
+			pid_t _pid;		/* sender's pid */
+			uid_t _uid;		/* sender's uid */
+			sigval_t _sigval;
+		} _rt;
+
+		/* SIGCHLD */
+		struct {
+			pid_t _pid;		/* which child */
+			uid_t _uid;		/* sender's uid */
+			int _status;		/* exit code */
+			clock_t _utime;
+			clock_t _stime;
+		} _sigchld;
+
+		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+		struct {
+			void *_addr; /* faulting insn/memory ref. */
+		} _sigfault;
+
+		/* SIGPOLL */
+		struct {
+			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			int _fd;
+		} _sigpoll;
+	} _sifields;
+} siginfo_t;
+
+/*
+ * How these fields are to be accessed.
+ */
+#define si_pid		_sifields._kill._pid
+#define si_uid		_sifields._kill._uid
+#define si_status	_sifields._sigchld._status
+#define si_utime	_sifields._sigchld._utime
+#define si_stime	_sifields._sigchld._stime
+#define si_value	_sifields._rt._sigval
+#define si_int		_sifields._rt._sigval.sival_int
+#define si_ptr		_sifields._rt._sigval.sival_ptr
+#define si_addr		_sifields._sigfault._addr
+#define si_band		_sifields._sigpoll._band
+#define si_fd		_sifields._sigpoll._fd
+
+#ifdef __KERNEL__
+#define __SI_MASK	0xffff0000
+#define __SI_KILL	(0 << 16)
+#define __SI_TIMER	(1 << 16)
+#define __SI_POLL	(2 << 16)
+#define __SI_FAULT	(3 << 16)
+#define __SI_CHLD	(4 << 16)
+#define __SI_RT		(5 << 16)
+#define __SI_CODE(T,N)	((T) << 16 | ((N) & 0xffff))
+#else
+#define __SI_KILL	0
+#define __SI_TIMER	0
+#define __SI_POLL	0
+#define __SI_FAULT	0
+#define __SI_CHLD	0
+#define __SI_RT		0
+#define __SI_CODE(T,N)	(N)
+#endif
+
+/*
+ * si_code values
+ * Digital reserves positive values for kernel-generated signals.
+ */
+#define SI_USER		0		/* sent by kill, sigsend, raise */
+#define SI_KERNEL	0x80		/* sent by the kernel from somewhere */
+#define SI_QUEUE	-1		/* sent by sigqueue */
+#define SI_TIMER __SI_CODE(__SI_TIMER,-2) /* sent by timer expiration */
+#define SI_MESGQ	-3		/* sent by real time mesq state change */
+#define SI_ASYNCIO	-4		/* sent by AIO completion */
+#define SI_SIGIO	-5		/* sent by queued SIGIO */
+
+#define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
+#define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
+
+/*
+ * SIGILL si_codes
+ */
+#define ILL_ILLOPC	(__SI_FAULT|1)	/* illegal opcode */
+#define ILL_ILLOPN	(__SI_FAULT|2)	/* illegal operand */
+#define ILL_ILLADR	(__SI_FAULT|3)	/* illegal addressing mode */
+#define ILL_ILLTRP	(__SI_FAULT|4)	/* illegal trap */
+#define ILL_PRVOPC	(__SI_FAULT|5)	/* privileged opcode */
+#define ILL_PRVREG	(__SI_FAULT|6)	/* privileged register */
+#define ILL_COPROC	(__SI_FAULT|7)	/* coprocessor error */
+#define ILL_BADSTK	(__SI_FAULT|8)	/* internal stack error */
+#define NSIGILL		8
+
+/*
+ * SIGFPE si_codes
+ */
+#define FPE_INTDIV	(__SI_FAULT|1)	/* integer divide by zero */
+#define FPE_INTOVF	(__SI_FAULT|2)	/* integer overflow */
+#define FPE_FLTDIV	(__SI_FAULT|3)	/* floating point divide by zero */
+#define FPE_FLTOVF	(__SI_FAULT|4)	/* floating point overflow */
+#define FPE_FLTUND	(__SI_FAULT|5)	/* floating point underflow */
+#define FPE_FLTRES	(__SI_FAULT|6)	/* floating point inexact result */
+#define FPE_FLTINV	(__SI_FAULT|7)	/* floating point invalid operation */
+#define FPE_FLTSUB	(__SI_FAULT|8)	/* subscript out of range */
+#define NSIGFPE		8
+
+/*
+ * SIGSEGV si_codes
+ */
+#define SEGV_MAPERR	(__SI_FAULT|1)	/* address not mapped to object */
+#define SEGV_ACCERR	(__SI_FAULT|2)	/* invalid permissions for mapped object */
+#define NSIGSEGV	2
+
+/*
+ * SIGBUS si_codes
+ */
+#define BUS_ADRALN	(__SI_FAULT|1)	/* invalid address alignment */
+#define BUS_ADRERR	(__SI_FAULT|2)	/* non-existant physical address */
+#define BUS_OBJERR	(__SI_FAULT|3)	/* object specific hardware error */
+#define NSIGBUS		3
+
+/*
+ * SIGTRAP si_codes
+ */
+#define TRAP_BRKPT	(__SI_FAULT|1)	/* process breakpoint */
+#define TRAP_TRACE	(__SI_FAULT|2)	/* process trace trap */
+#define NSIGTRAP	2
+
+/*
+ * SIGCHLD si_codes
+ */
+#define CLD_EXITED	(__SI_CHLD|1)	/* child has exited */
+#define CLD_KILLED	(__SI_CHLD|2)	/* child was killed */
+#define CLD_DUMPED	(__SI_CHLD|3)	/* child terminated abnormally */
+#define CLD_TRAPPED	(__SI_CHLD|4)	/* traced child has trapped */
+#define CLD_STOPPED	(__SI_CHLD|5)	/* child has stopped */
+#define CLD_CONTINUED	(__SI_CHLD|6)	/* stopped child has continued */
+#define NSIGCHLD	6
+
+/*
+ * SIGPOLL si_codes
+ */
+#define POLL_IN		(__SI_POLL|1)	/* data input available */
+#define POLL_OUT	(__SI_POLL|2)	/* output buffers available */
+#define POLL_MSG	(__SI_POLL|3)	/* input message available */
+#define POLL_ERR	(__SI_POLL|4)	/* i/o error */
+#define POLL_PRI	(__SI_POLL|5)	/* high priority input available */
+#define POLL_HUP	(__SI_POLL|6)	/* device disconnected */
+#define NSIGPOLL	6
+
+/*
+ * sigevent definitions
+ * 
+ * It seems likely that SIGEV_THREAD will have to be handled from 
+ * userspace, libpthread transmuting it to SIGEV_SIGNAL, which the
+ * thread manager then catches and does the appropriate nonsense.
+ * However, everything is written out here so as to not get lost.
+ */
+#define SIGEV_SIGNAL	0	/* notify via signal */
+#define SIGEV_NONE	1	/* other notification: meaningless */
+#define SIGEV_THREAD	2	/* deliver via thread creation */
+
+#define SIGEV_MAX_SIZE	64
+#define SIGEV_PAD_SIZE	((SIGEV_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct sigevent {
+	sigval_t sigev_value;
+	int sigev_signo;
+	int sigev_notify;
+	union {
+		int _pad[SIGEV_PAD_SIZE];
+
+		struct {
+			void (*_function)(sigval_t);
+			void *_attribute;	/* really pthread_attr_t */
+		} _sigev_thread;
+	} _sigev_un;
+} sigevent_t;
+
+#define sigev_notify_function	_sigev_un._sigev_thread._function
+#define sigev_notify_attributes	_sigev_un._sigev_thread._attribute
+
+#ifdef __KERNEL__
+#include <linux/string.h>
+
+extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
+{
+	if (from->si_code < 0)
+		memcpy(to, from, sizeof(siginfo_t));
+	else
+		/* _sigchld is currently the largest know union member */
+		memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
+}
+
+extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
+
+#endif /* __KERNEL__ */
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/signal.h linux/include/asm-cris/signal.h
--- linux-2.4.2-pre1/include/asm-cris/signal.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/signal.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,187 @@
+#ifndef _ASM_CRIS_SIGNAL_H
+#define _ASM_CRIS_SIGNAL_H
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+
+#ifdef __KERNEL__
+/* Most things should be clean enough to redefine this at will, if care
+   is taken to make libc match.  */
+
+#define _NSIG		64
+#define _NSIG_BPW	32
+#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t;		/* at least 32 bits */
+
+typedef struct {
+	unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+#define NSIG		32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+#define SIGBUS		 7
+#define SIGFPE		 8
+#define SIGKILL		 9
+#define SIGUSR1		10
+#define SIGSEGV		11
+#define SIGUSR2		12
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGSTKFLT	16
+#define SIGCHLD		17
+#define SIGCONT		18
+#define SIGSTOP		19
+#define SIGTSTP		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGURG		23
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGIO		29
+#define SIGPOLL		SIGIO
+/*
+#define SIGLOST		29
+*/
+#define SIGPWR		30
+#define SIGSYS          31
+#define	SIGUNUSED	31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN        32
+#define SIGRTMAX        (_NSIG-1)
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+
+#define SA_NOCLDSTOP	0x00000001
+#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_SIGINFO	0x00000004
+#define SA_ONSTACK	0x08000000
+#define SA_RESTART	0x10000000
+#define SA_NODEFER	0x40000000
+#define SA_RESETHAND	0x80000000
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+#define SA_INTERRUPT	0x20000000 /* dummy -- ignored */
+
+#define SA_RESTORER	0x04000000
+
+/* 
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	2048
+#define SIGSTKSZ	8192
+
+#ifdef __KERNEL__
+
+/*
+ * These values of sa_flags are used only by the kernel as part of the
+ * irq handling routines.
+ *
+ * SA_INTERRUPT is also used by the irq handling routines.
+ * SA_SHIRQ is for shared interrupt support
+ */
+#define SA_PROBE		SA_ONESHOT
+#define SA_SAMPLE_RANDOM	SA_RESTART
+#define SA_SHIRQ		0x04000000
+#endif
+
+#define SIG_BLOCK          0	/* for blocking signals */
+#define SIG_UNBLOCK        1	/* for unblocking signals */
+#define SIG_SETMASK        2	/* for setting the signal mask */
+
+/* Type of a signal handler.  */
+typedef void (*__sighandler_t)(int);
+
+#define SIG_DFL	((__sighandler_t)0)	/* default signal handling */
+#define SIG_IGN	((__sighandler_t)1)	/* ignore signal */
+#define SIG_ERR	((__sighandler_t)-1)	/* error return from signal */
+
+#ifdef __KERNEL__
+struct old_sigaction {
+	__sighandler_t sa_handler;
+	old_sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+struct sigaction {
+	__sighandler_t sa_handler;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+	sigset_t sa_mask;		/* mask last for extensibility */
+};
+
+struct k_sigaction {
+	struct sigaction sa;
+};
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+struct sigaction {
+	union {
+	  __sighandler_t _sa_handler;
+	  void (*_sa_sigaction)(int, struct siginfo *, void *);
+	} _u;
+	sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+#define sa_handler	_u._sa_handler
+#define sa_sigaction	_u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+} stack_t;
+
+#ifdef __KERNEL__
+#include <asm/sigcontext.h>
+
+/* here we could define asm-optimized sigaddset, sigdelset etc. operations. 
+ * if we don't, generic ones are used from linux/signal.h
+ */
+
+#endif /* __KERNEL__ */
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/smp.h linux/include/asm-cris/smp.h
--- linux-2.4.2-pre1/include/asm-cris/smp.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/smp.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,4 @@
+#ifndef __ASM_SMP_H
+#define __ASM_SMP_H
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/smp_lock.h linux/include/asm-cris/smp_lock.h
--- linux-2.4.2-pre1/include/asm-cris/smp_lock.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/smp_lock.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,73 @@
+#ifndef __CRIS_SMPLOCK_H
+#define __CRIS_SMPLOCK_H
+
+#include <linux/config.h>
+
+#ifdef CONFIG_SMP
+
+#error "SMP is not supported for CRIS"
+
+/*
+ *	Locking the kernel 
+ */
+ 
+extern __inline void lock_kernel(void)
+{
+	unsigned long flags;
+	int proc = smp_processor_id();
+
+	save_flags(flags);
+	cli();
+	/* set_bit works atomic in SMP machines */
+	while(set_bit(0, (void *)&kernel_flag)) 
+	{
+		/*
+		 *	We just start another level if we have the lock 
+		 */
+		if (proc == active_kernel_processor)
+			break;
+		do 
+		{
+#ifdef __SMP_PROF__		
+			smp_spins[smp_processor_id()]++;
+#endif			
+			/*
+			 *	Doing test_bit here doesn't lock the bus 
+			 */
+			if (test_bit(proc, (void *)&smp_invalidate_needed))
+				if (clear_bit(proc, (void *)&smp_invalidate_needed))
+					local_flush_tlb();
+		}
+		while(test_bit(0, (void *)&kernel_flag));
+	}
+	/* 
+	 *	We got the lock, so tell the world we are here and increment
+	 *	the level counter 
+	 */
+	active_kernel_processor = proc;
+	kernel_counter++;
+	restore_flags(flags);
+}
+
+extern __inline void unlock_kernel(void)
+{
+	unsigned long flags;
+	save_flags(flags);
+	cli();
+	/*
+	 *	If it's the last level we have in the kernel, then
+	 *	free the lock 
+	 */
+	if (kernel_counter == 0)
+		panic("Kernel counter wrong.\n"); /* FIXME: Why is kernel_counter sometimes 0 here? */
+	
+	if(! --kernel_counter) 
+	{
+		active_kernel_processor = NO_PROC_ID;
+		clear_bit(0, (void *)&kernel_flag);
+	}
+	restore_flags(flags);
+}
+
+#endif
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/smplock.h linux/include/asm-cris/smplock.h
--- linux-2.4.2-pre1/include/asm-cris/smplock.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/smplock.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,25 @@
+#ifndef __ASM_CRIS_SMPLOCK_H
+#define __ASM_CRIS_SMPLOCK_H
+
+/*
+ * 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/config.h>
+
+#ifndef CONFIG_SMP
+
+#define lock_kernel()                           do { } while(0)
+#define unlock_kernel()                         do { } while(0)
+#define release_kernel_lock(task, cpu, depth)   ((depth) = 1)
+#define reacquire_kernel_lock(task, cpu, depth) do { } while(0)
+
+#else
+
+#error "We do not support SMP on CRIS"
+
+#endif
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/socket.h linux/include/asm-cris/socket.h
--- linux-2.4.2-pre1/include/asm-cris/socket.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/socket.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,64 @@
+#ifndef _ASM_SOCKET_H
+#define _ASM_SOCKET_H
+
+/* almost the same as asm-i386/socket.h */
+
+#include <asm/sockios.h>
+
+/* For setsockoptions(2) */
+#define SOL_SOCKET	1
+
+#define SO_DEBUG	1
+#define SO_REUSEADDR	2
+#define SO_TYPE		3
+#define SO_ERROR	4
+#define SO_DONTROUTE	5
+#define SO_BROADCAST	6
+#define SO_SNDBUF	7
+#define SO_RCVBUF	8
+#define SO_KEEPALIVE	9
+#define SO_OOBINLINE	10
+#define SO_NO_CHECK	11
+#define SO_PRIORITY	12
+#define SO_LINGER	13
+#define SO_BSDCOMPAT	14
+/* To add :#define SO_REUSEPORT 15 */
+#define SO_PASSCRED	16
+#define SO_PEERCRED	17
+#define SO_RCVLOWAT	18
+#define SO_SNDLOWAT	19
+#define SO_RCVTIMEO	20
+#define SO_SNDTIMEO	21
+
+/* Security levels - as per NRL IPv6 - don't actually do anything */
+#define SO_SECURITY_AUTHENTICATION		22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT	23
+#define SO_SECURITY_ENCRYPTION_NETWORK		24
+
+#define SO_BINDTODEVICE	25
+
+/* Socket filtering */
+#define SO_ATTACH_FILTER        26
+#define SO_DETACH_FILTER        27
+
+#define SO_PEERNAME		28
+#define SO_TIMESTAMP           29
+#define SCM_TIMESTAMP          SO_TIMESTAMP
+
+#if defined(__KERNEL__)
+/* Socket types. */
+#define SOCK_STREAM     1               /* stream (connection) socket   */
+#define SOCK_DGRAM      2               /* datagram (conn.less) socket  */
+#define SOCK_RAW        3               /* raw socket                   */
+#define SOCK_RDM        4               /* reliably-delivered message   */
+#define SOCK_SEQPACKET  5               /* sequential packet socket     */
+#define SOCK_PACKET     10              /* linux specific way of        */
+                                        /* getting packets at the dev   */
+                                        /* level.  For writing rarp and */
+                                        /* other similar things on the  */
+                                        /* user level.                  */
+#endif
+
+#endif /* _ASM_SOCKET_H */
+
+
diff -urN linux-2.4.2-pre1/include/asm-cris/sockios.h linux/include/asm-cris/sockios.h
--- linux-2.4.2-pre1/include/asm-cris/sockios.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/sockios.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,12 @@
+#ifndef __ARCH_CRIS_SOCKIOS__
+#define __ARCH_CRIS_SOCKIOS__
+
+/* Socket-level I/O control calls. */
+#define FIOSETOWN 	0x8901
+#define SIOCSPGRP	0x8902
+#define FIOGETOWN	0x8903
+#define SIOCGPGRP	0x8904
+#define SIOCATMARK	0x8905
+#define SIOCGSTAMP	0x8906		/* Get stamp */
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/softirq.h linux/include/asm-cris/softirq.h
--- linux-2.4.2-pre1/include/asm-cris/softirq.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/softirq.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,12 @@
+#ifndef __ASM_SOFTIRQ_H
+#define __ASM_SOFTIRQ_H
+
+#include <asm/atomic.h>
+#include <asm/hardirq.h>
+
+#define local_bh_disable()      (local_bh_count(smp_processor_id())++)
+#define local_bh_enable()       (local_bh_count(smp_processor_id())--)
+
+#define in_softirq() (local_bh_count(smp_processor_id()) != 0)
+
+#endif	/* __ASM_SOFTIRQ_H */
diff -urN linux-2.4.2-pre1/include/asm-cris/stat.h linux/include/asm-cris/stat.h
--- linux-2.4.2-pre1/include/asm-cris/stat.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/stat.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,79 @@
+#ifndef _CRIS_STAT_H
+#define _CRIS_STAT_H
+
+/* verbatim copy of i386 version */
+
+struct __old_kernel_stat {
+	unsigned short st_dev;
+	unsigned short st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned long  st_size;
+	unsigned long  st_atime;
+	unsigned long  st_mtime;
+	unsigned long  st_ctime;
+};
+
+struct stat {
+	unsigned short st_dev;
+	unsigned short __pad1;
+	unsigned long st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned short __pad2;
+	unsigned long  st_size;
+	unsigned long  st_blksize;
+	unsigned long  st_blocks;
+	unsigned long  st_atime;
+	unsigned long  __unused1;
+	unsigned long  st_mtime;
+	unsigned long  __unused2;
+	unsigned long  st_ctime;
+	unsigned long  __unused3;
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct stat64 {
+	unsigned short	st_dev;
+	unsigned char	__pad0[10];
+
+	unsigned long	st_ino;
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned long	st_uid;
+	unsigned long	st_gid;
+
+	unsigned short	st_rdev;
+	unsigned char	__pad3[10];
+
+	long long	st_size;
+	unsigned long	st_blksize;
+
+	unsigned long	st_blocks;	/* Number 512-byte blocks allocated. */
+	unsigned long	__pad4;		/* future possible st_blocks high bits */
+
+	unsigned long	st_atime;
+	unsigned long	__pad5;
+
+	unsigned long	st_mtime;
+	unsigned long	__pad6;
+
+	unsigned long	st_ctime;
+	unsigned long	__pad7;		/* will be high 32 bits of ctime someday */
+
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+};
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/statfs.h linux/include/asm-cris/statfs.h
--- linux-2.4.2-pre1/include/asm-cris/statfs.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/statfs.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,25 @@
+#ifndef _CRIS_STATFS_H
+#define _CRIS_STATFS_H
+
+#ifndef __KERNEL_STRICT_NAMES
+
+#include <linux/types.h>
+
+typedef __kernel_fsid_t	fsid_t;
+
+#endif
+
+struct statfs {
+	long f_type;
+	long f_bsize;
+	long f_blocks;
+	long f_bfree;
+	long f_bavail;
+	long f_files;
+	long f_ffree;
+	__kernel_fsid_t f_fsid;
+	long f_namelen;
+	long f_spare[6];
+};
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/string.h linux/include/asm-cris/string.h
--- linux-2.4.2-pre1/include/asm-cris/string.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/string.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,14 @@
+#ifndef _ASM_CRIS_STRING_H
+#define _ASM_CRIS_STRING_H
+
+/* the optimized memcpy is in arch/cris/lib/string.c */
+
+#define __HAVE_ARCH_MEMCPY
+extern void *memcpy(void *, const void *, size_t);
+
+/* New and improved.  In arch/cris/lib/memset.c */
+
+#define __HAVE_ARCH_MEMSET
+extern void *memset(void *, int, size_t);
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/sv_addr.agh linux/include/asm-cris/sv_addr.agh
--- linux-2.4.2-pre1/include/asm-cris/sv_addr.agh	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/sv_addr.agh	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,7008 @@
+/*
+!* This file was automatically generated by /n/asic/bin/reg_macro_gen
+!* from the file `etrax_ng_regs.rd'.
+!* Editing within this file is thus not recommended,
+!* make the changes in `etrax_ng_regs.rd' instead.
+!*/
+
+
+/*
+!* Bus interface configuration registers
+!*/
+
+#define R_WAITSTATES (IO_TYPECAST_UDWORD 0xb0000000)
+#define R_WAITSTATES__pcs4_7_zw__BITNR 30
+#define R_WAITSTATES__pcs4_7_zw__WIDTH 2
+#define R_WAITSTATES__pcs4_7_ew__BITNR 28
+#define R_WAITSTATES__pcs4_7_ew__WIDTH 2
+#define R_WAITSTATES__pcs4_7_lw__BITNR 24
+#define R_WAITSTATES__pcs4_7_lw__WIDTH 4
+#define R_WAITSTATES__pcs0_3_zw__BITNR 22
+#define R_WAITSTATES__pcs0_3_zw__WIDTH 2
+#define R_WAITSTATES__pcs0_3_ew__BITNR 20
+#define R_WAITSTATES__pcs0_3_ew__WIDTH 2
+#define R_WAITSTATES__pcs0_3_lw__BITNR 16
+#define R_WAITSTATES__pcs0_3_lw__WIDTH 4
+#define R_WAITSTATES__sram_zw__BITNR 14
+#define R_WAITSTATES__sram_zw__WIDTH 2
+#define R_WAITSTATES__sram_ew__BITNR 12
+#define R_WAITSTATES__sram_ew__WIDTH 2
+#define R_WAITSTATES__sram_lw__BITNR 8
+#define R_WAITSTATES__sram_lw__WIDTH 4
+#define R_WAITSTATES__flash_zw__BITNR 6
+#define R_WAITSTATES__flash_zw__WIDTH 2
+#define R_WAITSTATES__flash_ew__BITNR 4
+#define R_WAITSTATES__flash_ew__WIDTH 2
+#define R_WAITSTATES__flash_lw__BITNR 0
+#define R_WAITSTATES__flash_lw__WIDTH 4
+
+#define R_BUS_CONFIG (IO_TYPECAST_UDWORD 0xb0000004)
+#define R_BUS_CONFIG__sram_type__BITNR 9
+#define R_BUS_CONFIG__sram_type__WIDTH 1
+#define R_BUS_CONFIG__sram_type__cwe 1
+#define R_BUS_CONFIG__sram_type__bwe 0
+#define R_BUS_CONFIG__dma_burst__BITNR 8
+#define R_BUS_CONFIG__dma_burst__WIDTH 1
+#define R_BUS_CONFIG__dma_burst__burst16 1
+#define R_BUS_CONFIG__dma_burst__burst32 0
+#define R_BUS_CONFIG__pcs4_7_wr__BITNR 7
+#define R_BUS_CONFIG__pcs4_7_wr__WIDTH 1
+#define R_BUS_CONFIG__pcs4_7_wr__ext 1
+#define R_BUS_CONFIG__pcs4_7_wr__norm 0
+#define R_BUS_CONFIG__pcs0_3_wr__BITNR 6
+#define R_BUS_CONFIG__pcs0_3_wr__WIDTH 1
+#define R_BUS_CONFIG__pcs0_3_wr__ext 1
+#define R_BUS_CONFIG__pcs0_3_wr__norm 0
+#define R_BUS_CONFIG__sram_wr__BITNR 5
+#define R_BUS_CONFIG__sram_wr__WIDTH 1
+#define R_BUS_CONFIG__sram_wr__ext 1
+#define R_BUS_CONFIG__sram_wr__norm 0
+#define R_BUS_CONFIG__flash_wr__BITNR 4
+#define R_BUS_CONFIG__flash_wr__WIDTH 1
+#define R_BUS_CONFIG__flash_wr__ext 1
+#define R_BUS_CONFIG__flash_wr__norm 0
+#define R_BUS_CONFIG__pcs4_7_bw__BITNR 3
+#define R_BUS_CONFIG__pcs4_7_bw__WIDTH 1
+#define R_BUS_CONFIG__pcs4_7_bw__bw32 1
+#define R_BUS_CONFIG__pcs4_7_bw__bw16 0
+#define R_BUS_CONFIG__pcs0_3_bw__BITNR 2
+#define R_BUS_CONFIG__pcs0_3_bw__WIDTH 1
+#define R_BUS_CONFIG__pcs0_3_bw__bw32 1
+#define R_BUS_CONFIG__pcs0_3_bw__bw16 0
+#define R_BUS_CONFIG__sram_bw__BITNR 1
+#define R_BUS_CONFIG__sram_bw__WIDTH 1
+#define R_BUS_CONFIG__sram_bw__bw32 1
+#define R_BUS_CONFIG__sram_bw__bw16 0
+#define R_BUS_CONFIG__flash_bw__BITNR 0
+#define R_BUS_CONFIG__flash_bw__WIDTH 1
+#define R_BUS_CONFIG__flash_bw__bw32 1
+#define R_BUS_CONFIG__flash_bw__bw16 0
+
+#define R_BUS_STATUS (IO_TYPECAST_RO_UDWORD 0xb0000004)
+#define R_BUS_STATUS__pll_lock_tm__BITNR 5
+#define R_BUS_STATUS__pll_lock_tm__WIDTH 1
+#define R_BUS_STATUS__pll_lock_tm__expired 0
+#define R_BUS_STATUS__pll_lock_tm__counting 1
+#define R_BUS_STATUS__both_faults__BITNR 4
+#define R_BUS_STATUS__both_faults__WIDTH 1
+#define R_BUS_STATUS__both_faults__no 0
+#define R_BUS_STATUS__both_faults__yes 1
+#define R_BUS_STATUS__bsen___BITNR 3
+#define R_BUS_STATUS__bsen___WIDTH 1
+#define R_BUS_STATUS__bsen___enable 0
+#define R_BUS_STATUS__bsen___disable 1
+#define R_BUS_STATUS__boot__BITNR 1
+#define R_BUS_STATUS__boot__WIDTH 2
+#define R_BUS_STATUS__boot__uncached 0
+#define R_BUS_STATUS__boot__serial 1
+#define R_BUS_STATUS__boot__network 2
+#define R_BUS_STATUS__boot__parallel 3
+#define R_BUS_STATUS__flashw__BITNR 0
+#define R_BUS_STATUS__flashw__WIDTH 1
+#define R_BUS_STATUS__flashw__bw32 1
+#define R_BUS_STATUS__flashw__bw16 0
+
+#define R_DRAM_TIMING (IO_TYPECAST_UDWORD 0xb0000008)
+#define R_DRAM_TIMING__ref__BITNR 14
+#define R_DRAM_TIMING__ref__WIDTH 2
+#define R_DRAM_TIMING__ref__e52us 0
+#define R_DRAM_TIMING__ref__e13us 1
+#define R_DRAM_TIMING__ref__e8700ns 2
+#define R_DRAM_TIMING__ref__disable 3
+#define R_DRAM_TIMING__rp__BITNR 12
+#define R_DRAM_TIMING__rp__WIDTH 2
+#define R_DRAM_TIMING__rs__BITNR 10
+#define R_DRAM_TIMING__rs__WIDTH 2
+#define R_DRAM_TIMING__rh__BITNR 8
+#define R_DRAM_TIMING__rh__WIDTH 2
+#define R_DRAM_TIMING__w__BITNR 7
+#define R_DRAM_TIMING__w__WIDTH 1
+#define R_DRAM_TIMING__w__norm 0
+#define R_DRAM_TIMING__w__ext 1
+#define R_DRAM_TIMING__c__BITNR 6
+#define R_DRAM_TIMING__c__WIDTH 1
+#define R_DRAM_TIMING__c__norm 0
+#define R_DRAM_TIMING__c__ext 1
+#define R_DRAM_TIMING__cz__BITNR 4
+#define R_DRAM_TIMING__cz__WIDTH 2
+#define R_DRAM_TIMING__cp__BITNR 2
+#define R_DRAM_TIMING__cp__WIDTH 2
+#define R_DRAM_TIMING__cw__BITNR 0
+#define R_DRAM_TIMING__cw__WIDTH 2
+
+#define R_SDRAM_TIMING (IO_TYPECAST_UDWORD 0xb0000008)
+#define R_SDRAM_TIMING__sdram__BITNR 31
+#define R_SDRAM_TIMING__sdram__WIDTH 1
+#define R_SDRAM_TIMING__sdram__enable 1
+#define R_SDRAM_TIMING__sdram__disable 0
+#define R_SDRAM_TIMING__mrs_data__BITNR 16
+#define R_SDRAM_TIMING__mrs_data__WIDTH 15
+#define R_SDRAM_TIMING__ref__BITNR 14
+#define R_SDRAM_TIMING__ref__WIDTH 2
+#define R_SDRAM_TIMING__ref__e52us 0
+#define R_SDRAM_TIMING__ref__e13us 1
+#define R_SDRAM_TIMING__ref__e6500ns 2
+#define R_SDRAM_TIMING__ref__disable 3
+#define R_SDRAM_TIMING__ddr__BITNR 13
+#define R_SDRAM_TIMING__ddr__WIDTH 1
+#define R_SDRAM_TIMING__ddr__on 1
+#define R_SDRAM_TIMING__ddr__off 0
+#define R_SDRAM_TIMING__clk100__BITNR 12
+#define R_SDRAM_TIMING__clk100__WIDTH 1
+#define R_SDRAM_TIMING__clk100__on 1
+#define R_SDRAM_TIMING__clk100__off 0
+#define R_SDRAM_TIMING__ps__BITNR 11
+#define R_SDRAM_TIMING__ps__WIDTH 1
+#define R_SDRAM_TIMING__ps__on 1
+#define R_SDRAM_TIMING__ps__off 0
+#define R_SDRAM_TIMING__cmd__BITNR 9
+#define R_SDRAM_TIMING__cmd__WIDTH 2
+#define R_SDRAM_TIMING__cmd__pre 3
+#define R_SDRAM_TIMING__cmd__ref 2
+#define R_SDRAM_TIMING__cmd__mrs 1
+#define R_SDRAM_TIMING__cmd__nop 0
+#define R_SDRAM_TIMING__pde__BITNR 8
+#define R_SDRAM_TIMING__pde__WIDTH 1
+#define R_SDRAM_TIMING__rc__BITNR 6
+#define R_SDRAM_TIMING__rc__WIDTH 2
+#define R_SDRAM_TIMING__rp__BITNR 4
+#define R_SDRAM_TIMING__rp__WIDTH 2
+#define R_SDRAM_TIMING__rcd__BITNR 2
+#define R_SDRAM_TIMING__rcd__WIDTH 2
+#define R_SDRAM_TIMING__cl__BITNR 0
+#define R_SDRAM_TIMING__cl__WIDTH 2
+
+#define R_DRAM_CONFIG (IO_TYPECAST_UDWORD 0xb000000c)
+#define R_DRAM_CONFIG__wmm1__BITNR 31
+#define R_DRAM_CONFIG__wmm1__WIDTH 1
+#define R_DRAM_CONFIG__wmm1__wmm 1
+#define R_DRAM_CONFIG__wmm1__norm 0
+#define R_DRAM_CONFIG__wmm0__BITNR 30
+#define R_DRAM_CONFIG__wmm0__WIDTH 1
+#define R_DRAM_CONFIG__wmm0__wmm 1
+#define R_DRAM_CONFIG__wmm0__norm 0
+#define R_DRAM_CONFIG__sh1__BITNR 27
+#define R_DRAM_CONFIG__sh1__WIDTH 3
+#define R_DRAM_CONFIG__sh0__BITNR 24
+#define R_DRAM_CONFIG__sh0__WIDTH 3
+#define R_DRAM_CONFIG__w__BITNR 23
+#define R_DRAM_CONFIG__w__WIDTH 1
+#define R_DRAM_CONFIG__w__bw16 0
+#define R_DRAM_CONFIG__w__bw32 1
+#define R_DRAM_CONFIG__c__BITNR 22
+#define R_DRAM_CONFIG__c__WIDTH 1
+#define R_DRAM_CONFIG__c__byte 0
+#define R_DRAM_CONFIG__c__bank 1
+#define R_DRAM_CONFIG__e__BITNR 21
+#define R_DRAM_CONFIG__e__WIDTH 1
+#define R_DRAM_CONFIG__e__fast 0
+#define R_DRAM_CONFIG__e__edo 1
+#define R_DRAM_CONFIG__group_sel__BITNR 16
+#define R_DRAM_CONFIG__group_sel__WIDTH 5
+#define R_DRAM_CONFIG__group_sel__grp0 0
+#define R_DRAM_CONFIG__group_sel__grp1 1
+#define R_DRAM_CONFIG__group_sel__bit9 9
+#define R_DRAM_CONFIG__group_sel__bit10 10
+#define R_DRAM_CONFIG__group_sel__bit11 11
+#define R_DRAM_CONFIG__group_sel__bit12 12
+#define R_DRAM_CONFIG__group_sel__bit13 13
+#define R_DRAM_CONFIG__group_sel__bit14 14
+#define R_DRAM_CONFIG__group_sel__bit15 15
+#define R_DRAM_CONFIG__group_sel__bit16 16
+#define R_DRAM_CONFIG__group_sel__bit17 17
+#define R_DRAM_CONFIG__group_sel__bit18 18
+#define R_DRAM_CONFIG__group_sel__bit19 19
+#define R_DRAM_CONFIG__group_sel__bit20 20
+#define R_DRAM_CONFIG__group_sel__bit21 21
+#define R_DRAM_CONFIG__group_sel__bit22 22
+#define R_DRAM_CONFIG__group_sel__bit23 23
+#define R_DRAM_CONFIG__group_sel__bit24 24
+#define R_DRAM_CONFIG__group_sel__bit25 25
+#define R_DRAM_CONFIG__group_sel__bit26 26
+#define R_DRAM_CONFIG__group_sel__bit27 27
+#define R_DRAM_CONFIG__group_sel__bit28 28
+#define R_DRAM_CONFIG__group_sel__bit29 29
+#define R_DRAM_CONFIG__ca1__BITNR 13
+#define R_DRAM_CONFIG__ca1__WIDTH 3
+#define R_DRAM_CONFIG__bank23sel__BITNR 8
+#define R_DRAM_CONFIG__bank23sel__WIDTH 5
+#define R_DRAM_CONFIG__bank23sel__bank0 0
+#define R_DRAM_CONFIG__bank23sel__bank1 1
+#define R_DRAM_CONFIG__bank23sel__bit9 9
+#define R_DRAM_CONFIG__bank23sel__bit10 10
+#define R_DRAM_CONFIG__bank23sel__bit11 11
+#define R_DRAM_CONFIG__bank23sel__bit12 12
+#define R_DRAM_CONFIG__bank23sel__bit13 13
+#define R_DRAM_CONFIG__bank23sel__bit14 14
+#define R_DRAM_CONFIG__bank23sel__bit15 15
+#define R_DRAM_CONFIG__bank23sel__bit16 16
+#define R_DRAM_CONFIG__bank23sel__bit17 17
+#define R_DRAM_CONFIG__bank23sel__bit18 18
+#define R_DRAM_CONFIG__bank23sel__bit19 19
+#define R_DRAM_CONFIG__bank23sel__bit20 20
+#define R_DRAM_CONFIG__bank23sel__bit21 21
+#define R_DRAM_CONFIG__bank23sel__bit22 22
+#define R_DRAM_CONFIG__bank23sel__bit23 23
+#define R_DRAM_CONFIG__bank23sel__bit24 24
+#define R_DRAM_CONFIG__bank23sel__bit25 25
+#define R_DRAM_CONFIG__bank23sel__bit26 26
+#define R_DRAM_CONFIG__bank23sel__bit27 27
+#define R_DRAM_CONFIG__bank23sel__bit28 28
+#define R_DRAM_CONFIG__bank23sel__bit29 29
+#define R_DRAM_CONFIG__ca0__BITNR 5
+#define R_DRAM_CONFIG__ca0__WIDTH 3
+#define R_DRAM_CONFIG__bank01sel__BITNR 0
+#define R_DRAM_CONFIG__bank01sel__WIDTH 5
+#define R_DRAM_CONFIG__bank01sel__bank0 0
+#define R_DRAM_CONFIG__bank01sel__bank1 1
+#define R_DRAM_CONFIG__bank01sel__bit9 9
+#define R_DRAM_CONFIG__bank01sel__bit10 10
+#define R_DRAM_CONFIG__bank01sel__bit11 11
+#define R_DRAM_CONFIG__bank01sel__bit12 12
+#define R_DRAM_CONFIG__bank01sel__bit13 13
+#define R_DRAM_CONFIG__bank01sel__bit14 14
+#define R_DRAM_CONFIG__bank01sel__bit15 15
+#define R_DRAM_CONFIG__bank01sel__bit16 16
+#define R_DRAM_CONFIG__bank01sel__bit17 17
+#define R_DRAM_CONFIG__bank01sel__bit18 18
+#define R_DRAM_CONFIG__bank01sel__bit19 19
+#define R_DRAM_CONFIG__bank01sel__bit20 20
+#define R_DRAM_CONFIG__bank01sel__bit21 21
+#define R_DRAM_CONFIG__bank01sel__bit22 22
+#define R_DRAM_CONFIG__bank01sel__bit23 23
+#define R_DRAM_CONFIG__bank01sel__bit24 24
+#define R_DRAM_CONFIG__bank01sel__bit25 25
+#define R_DRAM_CONFIG__bank01sel__bit26 26
+#define R_DRAM_CONFIG__bank01sel__bit27 27
+#define R_DRAM_CONFIG__bank01sel__bit28 28
+#define R_DRAM_CONFIG__bank01sel__bit29 29
+
+#define R_SDRAM_CONFIG (IO_TYPECAST_UDWORD 0xb000000c)
+#define R_SDRAM_CONFIG__wmm1__BITNR 31
+#define R_SDRAM_CONFIG__wmm1__WIDTH 1
+#define R_SDRAM_CONFIG__wmm1__wmm 1
+#define R_SDRAM_CONFIG__wmm1__norm 0
+#define R_SDRAM_CONFIG__wmm0__BITNR 30
+#define R_SDRAM_CONFIG__wmm0__WIDTH 1
+#define R_SDRAM_CONFIG__wmm0__wmm 1
+#define R_SDRAM_CONFIG__wmm0__norm 0
+#define R_SDRAM_CONFIG__sh1__BITNR 27
+#define R_SDRAM_CONFIG__sh1__WIDTH 3
+#define R_SDRAM_CONFIG__sh0__BITNR 24
+#define R_SDRAM_CONFIG__sh0__WIDTH 3
+#define R_SDRAM_CONFIG__w__BITNR 23
+#define R_SDRAM_CONFIG__w__WIDTH 1
+#define R_SDRAM_CONFIG__w__bw16 0
+#define R_SDRAM_CONFIG__w__bw32 1
+#define R_SDRAM_CONFIG__type1__BITNR 22
+#define R_SDRAM_CONFIG__type1__WIDTH 1
+#define R_SDRAM_CONFIG__type1__bank2 0
+#define R_SDRAM_CONFIG__type1__bank4 1
+#define R_SDRAM_CONFIG__type0__BITNR 21
+#define R_SDRAM_CONFIG__type0__WIDTH 1
+#define R_SDRAM_CONFIG__type0__bank2 0
+#define R_SDRAM_CONFIG__type0__bank4 1
+#define R_SDRAM_CONFIG__group_sel__BITNR 16
+#define R_SDRAM_CONFIG__group_sel__WIDTH 5
+#define R_SDRAM_CONFIG__group_sel__grp0 0
+#define R_SDRAM_CONFIG__group_sel__grp1 1
+#define R_SDRAM_CONFIG__group_sel__bit9 9
+#define R_SDRAM_CONFIG__group_sel__bit10 10
+#define R_SDRAM_CONFIG__group_sel__bit11 11
+#define R_SDRAM_CONFIG__group_sel__bit12 12
+#define R_SDRAM_CONFIG__group_sel__bit13 13
+#define R_SDRAM_CONFIG__group_sel__bit14 14
+#define R_SDRAM_CONFIG__group_sel__bit15 15
+#define R_SDRAM_CONFIG__group_sel__bit16 16
+#define R_SDRAM_CONFIG__group_sel__bit17 17
+#define R_SDRAM_CONFIG__group_sel__bit18 18
+#define R_SDRAM_CONFIG__group_sel__bit19 19
+#define R_SDRAM_CONFIG__group_sel__bit20 20
+#define R_SDRAM_CONFIG__group_sel__bit21 21
+#define R_SDRAM_CONFIG__group_sel__bit22 22
+#define R_SDRAM_CONFIG__group_sel__bit23 23
+#define R_SDRAM_CONFIG__group_sel__bit24 24
+#define R_SDRAM_CONFIG__group_sel__bit25 25
+#define R_SDRAM_CONFIG__group_sel__bit26 26
+#define R_SDRAM_CONFIG__group_sel__bit27 27
+#define R_SDRAM_CONFIG__group_sel__bit28 28
+#define R_SDRAM_CONFIG__group_sel__bit29 29
+#define R_SDRAM_CONFIG__ca1__BITNR 13
+#define R_SDRAM_CONFIG__ca1__WIDTH 3
+#define R_SDRAM_CONFIG__bank_sel1__BITNR 8
+#define R_SDRAM_CONFIG__bank_sel1__WIDTH 5
+#define R_SDRAM_CONFIG__bank_sel1__bit9 9
+#define R_SDRAM_CONFIG__bank_sel1__bit10 10
+#define R_SDRAM_CONFIG__bank_sel1__bit11 11
+#define R_SDRAM_CONFIG__bank_sel1__bit12 12
+#define R_SDRAM_CONFIG__bank_sel1__bit13 13
+#define R_SDRAM_CONFIG__bank_sel1__bit14 14
+#define R_SDRAM_CONFIG__bank_sel1__bit15 15
+#define R_SDRAM_CONFIG__bank_sel1__bit16 16
+#define R_SDRAM_CONFIG__bank_sel1__bit17 17
+#define R_SDRAM_CONFIG__bank_sel1__bit18 18
+#define R_SDRAM_CONFIG__bank_sel1__bit19 19
+#define R_SDRAM_CONFIG__bank_sel1__bit20 20
+#define R_SDRAM_CONFIG__bank_sel1__bit21 21
+#define R_SDRAM_CONFIG__bank_sel1__bit22 22
+#define R_SDRAM_CONFIG__bank_sel1__bit23 23
+#define R_SDRAM_CONFIG__bank_sel1__bit24 24
+#define R_SDRAM_CONFIG__bank_sel1__bit25 25
+#define R_SDRAM_CONFIG__bank_sel1__bit26 26
+#define R_SDRAM_CONFIG__bank_sel1__bit27 27
+#define R_SDRAM_CONFIG__bank_sel1__bit28 28
+#define R_SDRAM_CONFIG__bank_sel1__bit29 29
+#define R_SDRAM_CONFIG__ca0__BITNR 5
+#define R_SDRAM_CONFIG__ca0__WIDTH 3
+#define R_SDRAM_CONFIG__bank_sel0__BITNR 0
+#define R_SDRAM_CONFIG__bank_sel0__WIDTH 5
+#define R_SDRAM_CONFIG__bank_sel0__bit9 9
+#define R_SDRAM_CONFIG__bank_sel0__bit10 10
+#define R_SDRAM_CONFIG__bank_sel0__bit11 11
+#define R_SDRAM_CONFIG__bank_sel0__bit12 12
+#define R_SDRAM_CONFIG__bank_sel0__bit13 13
+#define R_SDRAM_CONFIG__bank_sel0__bit14 14
+#define R_SDRAM_CONFIG__bank_sel0__bit15 15
+#define R_SDRAM_CONFIG__bank_sel0__bit16 16
+#define R_SDRAM_CONFIG__bank_sel0__bit17 17
+#define R_SDRAM_CONFIG__bank_sel0__bit18 18
+#define R_SDRAM_CONFIG__bank_sel0__bit19 19
+#define R_SDRAM_CONFIG__bank_sel0__bit20 20
+#define R_SDRAM_CONFIG__bank_sel0__bit21 21
+#define R_SDRAM_CONFIG__bank_sel0__bit22 22
+#define R_SDRAM_CONFIG__bank_sel0__bit23 23
+#define R_SDRAM_CONFIG__bank_sel0__bit24 24
+#define R_SDRAM_CONFIG__bank_sel0__bit25 25
+#define R_SDRAM_CONFIG__bank_sel0__bit26 26
+#define R_SDRAM_CONFIG__bank_sel0__bit27 27
+#define R_SDRAM_CONFIG__bank_sel0__bit28 28
+#define R_SDRAM_CONFIG__bank_sel0__bit29 29
+
+/*
+!* External DMA registers
+!*/
+
+#define R_EXT_DMA_0_CMD (IO_TYPECAST_UDWORD 0xb0000010)
+#define R_EXT_DMA_0_CMD__cnt__BITNR 23
+#define R_EXT_DMA_0_CMD__cnt__WIDTH 1
+#define R_EXT_DMA_0_CMD__cnt__enable 1
+#define R_EXT_DMA_0_CMD__cnt__disable 0
+#define R_EXT_DMA_0_CMD__rqpol__BITNR 22
+#define R_EXT_DMA_0_CMD__rqpol__WIDTH 1
+#define R_EXT_DMA_0_CMD__rqpol__ahigh 0
+#define R_EXT_DMA_0_CMD__rqpol__alow 1
+#define R_EXT_DMA_0_CMD__apol__BITNR 21
+#define R_EXT_DMA_0_CMD__apol__WIDTH 1
+#define R_EXT_DMA_0_CMD__apol__ahigh 0
+#define R_EXT_DMA_0_CMD__apol__alow 1
+#define R_EXT_DMA_0_CMD__rq_ack__BITNR 20
+#define R_EXT_DMA_0_CMD__rq_ack__WIDTH 1
+#define R_EXT_DMA_0_CMD__rq_ack__burst 0
+#define R_EXT_DMA_0_CMD__rq_ack__handsh 1
+#define R_EXT_DMA_0_CMD__wid__BITNR 18
+#define R_EXT_DMA_0_CMD__wid__WIDTH 2
+#define R_EXT_DMA_0_CMD__wid__byte 0
+#define R_EXT_DMA_0_CMD__wid__word 1
+#define R_EXT_DMA_0_CMD__wid__dword 2
+#define R_EXT_DMA_0_CMD__dir__BITNR 17
+#define R_EXT_DMA_0_CMD__dir__WIDTH 1
+#define R_EXT_DMA_0_CMD__dir__input 0
+#define R_EXT_DMA_0_CMD__dir__output 1
+#define R_EXT_DMA_0_CMD__run__BITNR 16
+#define R_EXT_DMA_0_CMD__run__WIDTH 1
+#define R_EXT_DMA_0_CMD__run__start 1
+#define R_EXT_DMA_0_CMD__run__stop 0
+#define R_EXT_DMA_0_CMD__trf_count__BITNR 0
+#define R_EXT_DMA_0_CMD__trf_count__WIDTH 16
+
+#define R_EXT_DMA_0_STAT (IO_TYPECAST_RO_UDWORD 0xb0000010)
+#define R_EXT_DMA_0_STAT__run__BITNR 16
+#define R_EXT_DMA_0_STAT__run__WIDTH 1
+#define R_EXT_DMA_0_STAT__run__start 1
+#define R_EXT_DMA_0_STAT__run__stop 0
+#define R_EXT_DMA_0_STAT__trf_count__BITNR 0
+#define R_EXT_DMA_0_STAT__trf_count__WIDTH 16
+
+#define R_EXT_DMA_0_ADDR (IO_TYPECAST_UDWORD 0xb0000014)
+#define R_EXT_DMA_0_ADDR__ext0_addr__BITNR 2
+#define R_EXT_DMA_0_ADDR__ext0_addr__WIDTH 28
+
+#define R_EXT_DMA_1_CMD (IO_TYPECAST_UDWORD 0xb0000018)
+#define R_EXT_DMA_1_CMD__cnt__BITNR 23
+#define R_EXT_DMA_1_CMD__cnt__WIDTH 1
+#define R_EXT_DMA_1_CMD__cnt__enable 1
+#define R_EXT_DMA_1_CMD__cnt__disable 0
+#define R_EXT_DMA_1_CMD__rqpol__BITNR 22
+#define R_EXT_DMA_1_CMD__rqpol__WIDTH 1
+#define R_EXT_DMA_1_CMD__rqpol__ahigh 0
+#define R_EXT_DMA_1_CMD__rqpol__alow 1
+#define R_EXT_DMA_1_CMD__apol__BITNR 21
+#define R_EXT_DMA_1_CMD__apol__WIDTH 1
+#define R_EXT_DMA_1_CMD__apol__ahigh 0
+#define R_EXT_DMA_1_CMD__apol__alow 1
+#define R_EXT_DMA_1_CMD__rq_ack__BITNR 20
+#define R_EXT_DMA_1_CMD__rq_ack__WIDTH 1
+#define R_EXT_DMA_1_CMD__rq_ack__burst 0
+#define R_EXT_DMA_1_CMD__rq_ack__handsh 1
+#define R_EXT_DMA_1_CMD__wid__BITNR 18
+#define R_EXT_DMA_1_CMD__wid__WIDTH 2
+#define R_EXT_DMA_1_CMD__wid__byte 0
+#define R_EXT_DMA_1_CMD__wid__word 1
+#define R_EXT_DMA_1_CMD__wid__dword 2
+#define R_EXT_DMA_1_CMD__dir__BITNR 17
+#define R_EXT_DMA_1_CMD__dir__WIDTH 1
+#define R_EXT_DMA_1_CMD__dir__input 0
+#define R_EXT_DMA_1_CMD__dir__output 1
+#define R_EXT_DMA_1_CMD__run__BITNR 16
+#define R_EXT_DMA_1_CMD__run__WIDTH 1
+#define R_EXT_DMA_1_CMD__run__start 1
+#define R_EXT_DMA_1_CMD__run__stop 0
+#define R_EXT_DMA_1_CMD__trf_count__BITNR 0
+#define R_EXT_DMA_1_CMD__trf_count__WIDTH 16
+
+#define R_EXT_DMA_1_STAT (IO_TYPECAST_RO_UDWORD 0xb0000018)
+#define R_EXT_DMA_1_STAT__run__BITNR 16
+#define R_EXT_DMA_1_STAT__run__WIDTH 1
+#define R_EXT_DMA_1_STAT__run__start 1
+#define R_EXT_DMA_1_STAT__run__stop 0
+#define R_EXT_DMA_1_STAT__trf_count__BITNR 0
+#define R_EXT_DMA_1_STAT__trf_count__WIDTH 16
+
+#define R_EXT_DMA_1_ADDR (IO_TYPECAST_UDWORD 0xb000001c)
+#define R_EXT_DMA_1_ADDR__ext0_addr__BITNR 2
+#define R_EXT_DMA_1_ADDR__ext0_addr__WIDTH 28
+
+/*
+!* Timer registers
+!*/
+
+#define R_TIMER_CTRL (IO_TYPECAST_UDWORD 0xb0000020)
+#define R_TIMER_CTRL__timerdiv1__BITNR 24
+#define R_TIMER_CTRL__timerdiv1__WIDTH 8
+#define R_TIMER_CTRL__timerdiv0__BITNR 16
+#define R_TIMER_CTRL__timerdiv0__WIDTH 8
+#define R_TIMER_CTRL__presc_timer1__BITNR 15
+#define R_TIMER_CTRL__presc_timer1__WIDTH 1
+#define R_TIMER_CTRL__presc_timer1__normal 0
+#define R_TIMER_CTRL__presc_timer1__prescale 1
+#define R_TIMER_CTRL__i1__BITNR 14
+#define R_TIMER_CTRL__i1__WIDTH 1
+#define R_TIMER_CTRL__i1__clr 1
+#define R_TIMER_CTRL__i1__nop 0
+#define R_TIMER_CTRL__tm1__BITNR 12
+#define R_TIMER_CTRL__tm1__WIDTH 2
+#define R_TIMER_CTRL__tm1__stop_ld 0
+#define R_TIMER_CTRL__tm1__freeze 1
+#define R_TIMER_CTRL__tm1__run 2
+#define R_TIMER_CTRL__tm1__reserved 3
+#define R_TIMER_CTRL__clksel1__BITNR 8
+#define R_TIMER_CTRL__clksel1__WIDTH 4
+#define R_TIMER_CTRL__clksel1__c300Hz 0
+#define R_TIMER_CTRL__clksel1__c600Hz 1
+#define R_TIMER_CTRL__clksel1__c1200Hz 2
+#define R_TIMER_CTRL__clksel1__c2400Hz 3
+#define R_TIMER_CTRL__clksel1__c4800Hz 4
+#define R_TIMER_CTRL__clksel1__c9600Hz 5
+#define R_TIMER_CTRL__clksel1__c19k2Hz 6
+#define R_TIMER_CTRL__clksel1__c38k4Hz 7
+#define R_TIMER_CTRL__clksel1__c57k6Hz 8
+#define R_TIMER_CTRL__clksel1__c115k2Hz 9
+#define R_TIMER_CTRL__clksel1__c230k4Hz 10
+#define R_TIMER_CTRL__clksel1__c460k8Hz 11
+#define R_TIMER_CTRL__clksel1__c921k6Hz 12
+#define R_TIMER_CTRL__clksel1__c1843k2Hz 13
+#define R_TIMER_CTRL__clksel1__c6250kHz 14
+#define R_TIMER_CTRL__clksel1__cascade0 15
+#define R_TIMER_CTRL__presc_ext__BITNR 7
+#define R_TIMER_CTRL__presc_ext__WIDTH 1
+#define R_TIMER_CTRL__presc_ext__prescale 0
+#define R_TIMER_CTRL__presc_ext__external 1
+#define R_TIMER_CTRL__i0__BITNR 6
+#define R_TIMER_CTRL__i0__WIDTH 1
+#define R_TIMER_CTRL__i0__clr 1
+#define R_TIMER_CTRL__i0__nop 0
+#define R_TIMER_CTRL__tm0__BITNR 4
+#define R_TIMER_CTRL__tm0__WIDTH 2
+#define R_TIMER_CTRL__tm0__stop_ld 0
+#define R_TIMER_CTRL__tm0__freeze 1
+#define R_TIMER_CTRL__tm0__run 2
+#define R_TIMER_CTRL__tm0__reserved 3
+#define R_TIMER_CTRL__clksel0__BITNR 0
+#define R_TIMER_CTRL__clksel0__WIDTH 4
+#define R_TIMER_CTRL__clksel0__c300Hz 0
+#define R_TIMER_CTRL__clksel0__c600Hz 1
+#define R_TIMER_CTRL__clksel0__c1200Hz 2
+#define R_TIMER_CTRL__clksel0__c2400Hz 3
+#define R_TIMER_CTRL__clksel0__c4800Hz 4
+#define R_TIMER_CTRL__clksel0__c9600Hz 5
+#define R_TIMER_CTRL__clksel0__c19k2Hz 6
+#define R_TIMER_CTRL__clksel0__c38k4Hz 7
+#define R_TIMER_CTRL__clksel0__c57k6Hz 8
+#define R_TIMER_CTRL__clksel0__c115k2Hz 9
+#define R_TIMER_CTRL__clksel0__c230k4Hz 10
+#define R_TIMER_CTRL__clksel0__c460k8Hz 11
+#define R_TIMER_CTRL__clksel0__c921k6Hz 12
+#define R_TIMER_CTRL__clksel0__c1843k2Hz 13
+#define R_TIMER_CTRL__clksel0__c6250kHz 14
+#define R_TIMER_CTRL__clksel0__flexible 15
+
+#define R_TIMER_DATA (IO_TYPECAST_RO_UDWORD 0xb0000020)
+#define R_TIMER_DATA__timer1__BITNR 24
+#define R_TIMER_DATA__timer1__WIDTH 8
+#define R_TIMER_DATA__timer0__BITNR 16
+#define R_TIMER_DATA__timer0__WIDTH 8
+#define R_TIMER_DATA__clkdiv_high__BITNR 8
+#define R_TIMER_DATA__clkdiv_high__WIDTH 8
+#define R_TIMER_DATA__clkdiv_low__BITNR 0
+#define R_TIMER_DATA__clkdiv_low__WIDTH 8
+
+#define R_TIMER01_DATA (IO_TYPECAST_RO_UWORD 0xb0000022)
+#define R_TIMER01_DATA__count__BITNR 0
+#define R_TIMER01_DATA__count__WIDTH 16
+
+#define R_TIMER0_DATA (IO_TYPECAST_RO_BYTE 0xb0000022)
+#define R_TIMER0_DATA__count__BITNR 0
+#define R_TIMER0_DATA__count__WIDTH 8
+
+#define R_TIMER1_DATA (IO_TYPECAST_RO_BYTE 0xb0000023)
+#define R_TIMER1_DATA__count__BITNR 0
+#define R_TIMER1_DATA__count__WIDTH 8
+
+#define R_WATCHDOG (IO_TYPECAST_UDWORD 0xb0000024)
+#define R_WATCHDOG__key__BITNR 1
+#define R_WATCHDOG__key__WIDTH 3
+#define R_WATCHDOG__enable__BITNR 0
+#define R_WATCHDOG__enable__WIDTH 1
+#define R_WATCHDOG__enable__stop 0
+#define R_WATCHDOG__enable__start 1
+
+#define R_CLOCK_PRESCALE (IO_TYPECAST_UDWORD 0xb00000f0)
+#define R_CLOCK_PRESCALE__ser_presc__BITNR 16
+#define R_CLOCK_PRESCALE__ser_presc__WIDTH 16
+#define R_CLOCK_PRESCALE__tim_presc__BITNR 0
+#define R_CLOCK_PRESCALE__tim_presc__WIDTH 16
+
+#define R_SERIAL_PRESCALE (IO_TYPECAST_UWORD 0xb00000f2)
+#define R_SERIAL_PRESCALE__ser_presc__BITNR 0
+#define R_SERIAL_PRESCALE__ser_presc__WIDTH 16
+
+#define R_TIMER_PRESCALE (IO_TYPECAST_UWORD 0xb00000f0)
+#define R_TIMER_PRESCALE__tim_presc__BITNR 0
+#define R_TIMER_PRESCALE__tim_presc__WIDTH 16
+
+#define R_PRESCALE_STATUS (IO_TYPECAST_RO_UDWORD 0xb00000f0)
+#define R_PRESCALE_STATUS__ser_status__BITNR 16
+#define R_PRESCALE_STATUS__ser_status__WIDTH 16
+#define R_PRESCALE_STATUS__tim_status__BITNR 0
+#define R_PRESCALE_STATUS__tim_status__WIDTH 16
+
+#define R_SER_PRESC_STATUS (IO_TYPECAST_RO_UWORD 0xb00000f2)
+#define R_SER_PRESC_STATUS__ser_status__BITNR 0
+#define R_SER_PRESC_STATUS__ser_status__WIDTH 16
+
+#define R_TIM_PRESC_STATUS (IO_TYPECAST_RO_UWORD 0xb00000f0)
+#define R_TIM_PRESC_STATUS__tim_status__BITNR 0
+#define R_TIM_PRESC_STATUS__tim_status__WIDTH 16
+
+#define R_SYNC_SERIAL_PRESCALE (IO_TYPECAST_UDWORD 0xb00000f4)
+#define R_SYNC_SERIAL_PRESCALE__clk_sel_u3__BITNR 23
+#define R_SYNC_SERIAL_PRESCALE__clk_sel_u3__WIDTH 1
+#define R_SYNC_SERIAL_PRESCALE__clk_sel_u3__codec 0
+#define R_SYNC_SERIAL_PRESCALE__clk_sel_u3__baudrate 1
+#define R_SYNC_SERIAL_PRESCALE__word_stb_sel_u3__BITNR 22
+#define R_SYNC_SERIAL_PRESCALE__word_stb_sel_u3__WIDTH 1
+#define R_SYNC_SERIAL_PRESCALE__word_stb_sel_u3__external 0
+#define R_SYNC_SERIAL_PRESCALE__word_stb_sel_u3__internal 1
+#define R_SYNC_SERIAL_PRESCALE__clk_sel_u1__BITNR 21
+#define R_SYNC_SERIAL_PRESCALE__clk_sel_u1__WIDTH 1
+#define R_SYNC_SERIAL_PRESCALE__clk_sel_u1__codec 0
+#define R_SYNC_SERIAL_PRESCALE__clk_sel_u1__baudrate 1
+#define R_SYNC_SERIAL_PRESCALE__word_stb_sel_u1__BITNR 20
+#define R_SYNC_SERIAL_PRESCALE__word_stb_sel_u1__WIDTH 1
+#define R_SYNC_SERIAL_PRESCALE__word_stb_sel_u1__external 0
+#define R_SYNC_SERIAL_PRESCALE__word_stb_sel_u1__internal 1
+#define R_SYNC_SERIAL_PRESCALE__prescaler__BITNR 16
+#define R_SYNC_SERIAL_PRESCALE__prescaler__WIDTH 3
+#define R_SYNC_SERIAL_PRESCALE__prescaler__div1 0
+#define R_SYNC_SERIAL_PRESCALE__prescaler__div2 1
+#define R_SYNC_SERIAL_PRESCALE__prescaler__div4 2
+#define R_SYNC_SERIAL_PRESCALE__prescaler__div8 3
+#define R_SYNC_SERIAL_PRESCALE__prescaler__div16 4
+#define R_SYNC_SERIAL_PRESCALE__prescaler__div32 5
+#define R_SYNC_SERIAL_PRESCALE__prescaler__div64 6
+#define R_SYNC_SERIAL_PRESCALE__prescaler__div128 7
+#define R_SYNC_SERIAL_PRESCALE__warp_mode__BITNR 15
+#define R_SYNC_SERIAL_PRESCALE__warp_mode__WIDTH 1
+#define R_SYNC_SERIAL_PRESCALE__warp_mode__normal 0
+#define R_SYNC_SERIAL_PRESCALE__warp_mode__enabled 1
+#define R_SYNC_SERIAL_PRESCALE__frame_rate__BITNR 11
+#define R_SYNC_SERIAL_PRESCALE__frame_rate__WIDTH 4
+#define R_SYNC_SERIAL_PRESCALE__word_rate__BITNR 0
+#define R_SYNC_SERIAL_PRESCALE__word_rate__WIDTH 10
+
+/*
+!* Shared RAM interface registers
+!*/
+
+#define R_SHARED_RAM_CONFIG (IO_TYPECAST_UDWORD 0xb0000040)
+#define R_SHARED_RAM_CONFIG__width__BITNR 3
+#define R_SHARED_RAM_CONFIG__width__WIDTH 1
+#define R_SHARED_RAM_CONFIG__width__byte 0
+#define R_SHARED_RAM_CONFIG__width__word 1
+#define R_SHARED_RAM_CONFIG__enable__BITNR 2
+#define R_SHARED_RAM_CONFIG__enable__WIDTH 1
+#define R_SHARED_RAM_CONFIG__enable__yes 1
+#define R_SHARED_RAM_CONFIG__enable__no 0
+#define R_SHARED_RAM_CONFIG__pint__BITNR 1
+#define R_SHARED_RAM_CONFIG__pint__WIDTH 1
+#define R_SHARED_RAM_CONFIG__pint__int 1
+#define R_SHARED_RAM_CONFIG__pint__nop 0
+#define R_SHARED_RAM_CONFIG__clri__BITNR 0
+#define R_SHARED_RAM_CONFIG__clri__WIDTH 1
+#define R_SHARED_RAM_CONFIG__clri__clr 1
+#define R_SHARED_RAM_CONFIG__clri__nop 0
+
+#define R_SHARED_RAM_ADDR (IO_TYPECAST_UDWORD 0xb0000044)
+#define R_SHARED_RAM_ADDR__base_addr__BITNR 8
+#define R_SHARED_RAM_ADDR__base_addr__WIDTH 22
+
+/*
+!* General config registers
+!*/
+
+#define R_GEN_CONFIG (IO_TYPECAST_UDWORD 0xb000002c)
+#define R_GEN_CONFIG__par_w__BITNR 31
+#define R_GEN_CONFIG__par_w__WIDTH 1
+#define R_GEN_CONFIG__par_w__select 1
+#define R_GEN_CONFIG__par_w__disable 0
+#define R_GEN_CONFIG__usb2__BITNR 30
+#define R_GEN_CONFIG__usb2__WIDTH 1
+#define R_GEN_CONFIG__usb2__select 1
+#define R_GEN_CONFIG__usb2__disable 0
+#define R_GEN_CONFIG__usb1__BITNR 29
+#define R_GEN_CONFIG__usb1__WIDTH 1
+#define R_GEN_CONFIG__usb1__select 1
+#define R_GEN_CONFIG__usb1__disable 0
+#define R_GEN_CONFIG__p21__BITNR 28
+#define R_GEN_CONFIG__p21__WIDTH 1
+#define R_GEN_CONFIG__p21__select 1
+#define R_GEN_CONFIG__p21__disable 0
+#define R_GEN_CONFIG__g24dir__BITNR 27
+#define R_GEN_CONFIG__g24dir__WIDTH 1
+#define R_GEN_CONFIG__g24dir__in 0
+#define R_GEN_CONFIG__g24dir__out 1
+#define R_GEN_CONFIG__g16_20dir__BITNR 26
+#define R_GEN_CONFIG__g16_20dir__WIDTH 1
+#define R_GEN_CONFIG__g16_20dir__in 0
+#define R_GEN_CONFIG__g16_20dir__out 1
+#define R_GEN_CONFIG__g8_15dir__BITNR 25
+#define R_GEN_CONFIG__g8_15dir__WIDTH 1
+#define R_GEN_CONFIG__g8_15dir__in 0
+#define R_GEN_CONFIG__g8_15dir__out 1
+#define R_GEN_CONFIG__g0dir__BITNR 24
+#define R_GEN_CONFIG__g0dir__WIDTH 1
+#define R_GEN_CONFIG__g0dir__in 0
+#define R_GEN_CONFIG__g0dir__out 1
+#define R_GEN_CONFIG__dma9__BITNR 23
+#define R_GEN_CONFIG__dma9__WIDTH 1
+#define R_GEN_CONFIG__dma9__usb 0
+#define R_GEN_CONFIG__dma9__serial1 1
+#define R_GEN_CONFIG__dma8__BITNR 22
+#define R_GEN_CONFIG__dma8__WIDTH 1
+#define R_GEN_CONFIG__dma8__usb 0
+#define R_GEN_CONFIG__dma8__serial1 1
+#define R_GEN_CONFIG__dma7__BITNR 20
+#define R_GEN_CONFIG__dma7__WIDTH 2
+#define R_GEN_CONFIG__dma7__unused 0
+#define R_GEN_CONFIG__dma7__serial0 1
+#define R_GEN_CONFIG__dma7__extdma1 2
+#define R_GEN_CONFIG__dma7__intdma6 3
+#define R_GEN_CONFIG__dma6__BITNR 18
+#define R_GEN_CONFIG__dma6__WIDTH 2
+#define R_GEN_CONFIG__dma6__unused 0
+#define R_GEN_CONFIG__dma6__serial0 1
+#define R_GEN_CONFIG__dma6__extdma1 2
+#define R_GEN_CONFIG__dma6__intdma7 3
+#define R_GEN_CONFIG__dma5__BITNR 16
+#define R_GEN_CONFIG__dma5__WIDTH 2
+#define R_GEN_CONFIG__dma5__par1 0
+#define R_GEN_CONFIG__dma5__scsi1 1
+#define R_GEN_CONFIG__dma5__serial3 2
+#define R_GEN_CONFIG__dma5__extdma0 3
+#define R_GEN_CONFIG__dma4__BITNR 14
+#define R_GEN_CONFIG__dma4__WIDTH 2
+#define R_GEN_CONFIG__dma4__par1 0
+#define R_GEN_CONFIG__dma4__scsi1 1
+#define R_GEN_CONFIG__dma4__serial3 2
+#define R_GEN_CONFIG__dma4__extdma0 3
+#define R_GEN_CONFIG__dma3__BITNR 12
+#define R_GEN_CONFIG__dma3__WIDTH 2
+#define R_GEN_CONFIG__dma3__par0 0
+#define R_GEN_CONFIG__dma3__scsi0 1
+#define R_GEN_CONFIG__dma3__serial2 2
+#define R_GEN_CONFIG__dma3__ata 3
+#define R_GEN_CONFIG__dma2__BITNR 10
+#define R_GEN_CONFIG__dma2__WIDTH 2
+#define R_GEN_CONFIG__dma2__par0 0
+#define R_GEN_CONFIG__dma2__scsi0 1
+#define R_GEN_CONFIG__dma2__serial2 2
+#define R_GEN_CONFIG__dma2__ata 3
+#define R_GEN_CONFIG__mio_w__BITNR 9
+#define R_GEN_CONFIG__mio_w__WIDTH 1
+#define R_GEN_CONFIG__mio_w__select 1
+#define R_GEN_CONFIG__mio_w__disable 0
+#define R_GEN_CONFIG__ser3__BITNR 8
+#define R_GEN_CONFIG__ser3__WIDTH 1
+#define R_GEN_CONFIG__ser3__select 1
+#define R_GEN_CONFIG__ser3__disable 0
+#define R_GEN_CONFIG__par1__BITNR 7
+#define R_GEN_CONFIG__par1__WIDTH 1
+#define R_GEN_CONFIG__par1__select 1
+#define R_GEN_CONFIG__par1__disable 0
+#define R_GEN_CONFIG__scsi0w__BITNR 6
+#define R_GEN_CONFIG__scsi0w__WIDTH 1
+#define R_GEN_CONFIG__scsi0w__select 1
+#define R_GEN_CONFIG__scsi0w__disable 0
+#define R_GEN_CONFIG__scsi1__BITNR 5
+#define R_GEN_CONFIG__scsi1__WIDTH 1
+#define R_GEN_CONFIG__scsi1__select 1
+#define R_GEN_CONFIG__scsi1__disable 0
+#define R_GEN_CONFIG__mio__BITNR 4
+#define R_GEN_CONFIG__mio__WIDTH 1
+#define R_GEN_CONFIG__mio__select 1
+#define R_GEN_CONFIG__mio__disable 0
+#define R_GEN_CONFIG__ser2__BITNR 3
+#define R_GEN_CONFIG__ser2__WIDTH 1
+#define R_GEN_CONFIG__ser2__select 1
+#define R_GEN_CONFIG__ser2__disable 0
+#define R_GEN_CONFIG__par0__BITNR 2
+#define R_GEN_CONFIG__par0__WIDTH 1
+#define R_GEN_CONFIG__par0__select 1
+#define R_GEN_CONFIG__par0__disable 0
+#define R_GEN_CONFIG__ata__BITNR 1
+#define R_GEN_CONFIG__ata__WIDTH 1
+#define R_GEN_CONFIG__ata__select 1
+#define R_GEN_CONFIG__ata__disable 0
+#define R_GEN_CONFIG__scsi0__BITNR 0
+#define R_GEN_CONFIG__scsi0__WIDTH 1
+#define R_GEN_CONFIG__scsi0__select 1
+#define R_GEN_CONFIG__scsi0__disable 0
+
+#define R_GEN_CONFIG_II (IO_TYPECAST_UDWORD 0xb0000034)
+#define R_GEN_CONFIG_II__sermode3__BITNR 6
+#define R_GEN_CONFIG_II__sermode3__WIDTH 1
+#define R_GEN_CONFIG_II__sermode3__async 0
+#define R_GEN_CONFIG_II__sermode3__sync 1
+#define R_GEN_CONFIG_II__sermode1__BITNR 4
+#define R_GEN_CONFIG_II__sermode1__WIDTH 1
+#define R_GEN_CONFIG_II__sermode1__async 0
+#define R_GEN_CONFIG_II__sermode1__sync 1
+#define R_GEN_CONFIG_II__ext_clk__BITNR 2
+#define R_GEN_CONFIG_II__ext_clk__WIDTH 1
+#define R_GEN_CONFIG_II__ext_clk__select 1
+#define R_GEN_CONFIG_II__ext_clk__disable 0
+#define R_GEN_CONFIG_II__ser2__BITNR 1
+#define R_GEN_CONFIG_II__ser2__WIDTH 1
+#define R_GEN_CONFIG_II__ser2__select 1
+#define R_GEN_CONFIG_II__ser2__disable 0
+#define R_GEN_CONFIG_II__ser3__BITNR 0
+#define R_GEN_CONFIG_II__ser3__WIDTH 1
+#define R_GEN_CONFIG_II__ser3__select 1
+#define R_GEN_CONFIG_II__ser3__disable 0
+
+#define R_PORT_G_DATA (IO_TYPECAST_UDWORD 0xb0000028)
+#define R_PORT_G_DATA__data__BITNR 0
+#define R_PORT_G_DATA__data__WIDTH 32
+
+/*
+!* General port configuration registers
+!*/
+
+#define R_PORT_PA_SET (IO_TYPECAST_UDWORD 0xb0000030)
+#define R_PORT_PA_SET__dir7__BITNR 15
+#define R_PORT_PA_SET__dir7__WIDTH 1
+#define R_PORT_PA_SET__dir7__input 0
+#define R_PORT_PA_SET__dir7__output 1
+#define R_PORT_PA_SET__dir6__BITNR 14
+#define R_PORT_PA_SET__dir6__WIDTH 1
+#define R_PORT_PA_SET__dir6__input 0
+#define R_PORT_PA_SET__dir6__output 1
+#define R_PORT_PA_SET__dir5__BITNR 13
+#define R_PORT_PA_SET__dir5__WIDTH 1
+#define R_PORT_PA_SET__dir5__input 0
+#define R_PORT_PA_SET__dir5__output 1
+#define R_PORT_PA_SET__dir4__BITNR 12
+#define R_PORT_PA_SET__dir4__WIDTH 1
+#define R_PORT_PA_SET__dir4__input 0
+#define R_PORT_PA_SET__dir4__output 1
+#define R_PORT_PA_SET__dir3__BITNR 11
+#define R_PORT_PA_SET__dir3__WIDTH 1
+#define R_PORT_PA_SET__dir3__input 0
+#define R_PORT_PA_SET__dir3__output 1
+#define R_PORT_PA_SET__dir2__BITNR 10
+#define R_PORT_PA_SET__dir2__WIDTH 1
+#define R_PORT_PA_SET__dir2__input 0
+#define R_PORT_PA_SET__dir2__output 1
+#define R_PORT_PA_SET__dir1__BITNR 9
+#define R_PORT_PA_SET__dir1__WIDTH 1
+#define R_PORT_PA_SET__dir1__input 0
+#define R_PORT_PA_SET__dir1__output 1
+#define R_PORT_PA_SET__dir0__BITNR 8
+#define R_PORT_PA_SET__dir0__WIDTH 1
+#define R_PORT_PA_SET__dir0__input 0
+#define R_PORT_PA_SET__dir0__output 1
+#define R_PORT_PA_SET__data_out__BITNR 0
+#define R_PORT_PA_SET__data_out__WIDTH 8
+
+#define R_PORT_PA_DATA (IO_TYPECAST_BYTE 0xb0000030)
+#define R_PORT_PA_DATA__data_out__BITNR 0
+#define R_PORT_PA_DATA__data_out__WIDTH 8
+
+#define R_PORT_PA_DIR (IO_TYPECAST_BYTE 0xb0000031)
+#define R_PORT_PA_DIR__dir7__BITNR 7
+#define R_PORT_PA_DIR__dir7__WIDTH 1
+#define R_PORT_PA_DIR__dir7__input 0
+#define R_PORT_PA_DIR__dir7__output 1
+#define R_PORT_PA_DIR__dir6__BITNR 6
+#define R_PORT_PA_DIR__dir6__WIDTH 1
+#define R_PORT_PA_DIR__dir6__input 0
+#define R_PORT_PA_DIR__dir6__output 1
+#define R_PORT_PA_DIR__dir5__BITNR 5
+#define R_PORT_PA_DIR__dir5__WIDTH 1
+#define R_PORT_PA_DIR__dir5__input 0
+#define R_PORT_PA_DIR__dir5__output 1
+#define R_PORT_PA_DIR__dir4__BITNR 4
+#define R_PORT_PA_DIR__dir4__WIDTH 1
+#define R_PORT_PA_DIR__dir4__input 0
+#define R_PORT_PA_DIR__dir4__output 1
+#define R_PORT_PA_DIR__dir3__BITNR 3
+#define R_PORT_PA_DIR__dir3__WIDTH 1
+#define R_PORT_PA_DIR__dir3__input 0
+#define R_PORT_PA_DIR__dir3__output 1
+#define R_PORT_PA_DIR__dir2__BITNR 2
+#define R_PORT_PA_DIR__dir2__WIDTH 1
+#define R_PORT_PA_DIR__dir2__input 0
+#define R_PORT_PA_DIR__dir2__output 1
+#define R_PORT_PA_DIR__dir1__BITNR 1
+#define R_PORT_PA_DIR__dir1__WIDTH 1
+#define R_PORT_PA_DIR__dir1__input 0
+#define R_PORT_PA_DIR__dir1__output 1
+#define R_PORT_PA_DIR__dir0__BITNR 0
+#define R_PORT_PA_DIR__dir0__WIDTH 1
+#define R_PORT_PA_DIR__dir0__input 0
+#define R_PORT_PA_DIR__dir0__output 1
+
+#define R_PORT_PA_READ (IO_TYPECAST_RO_UDWORD 0xb0000030)
+#define R_PORT_PA_READ__data_in__BITNR 0
+#define R_PORT_PA_READ__data_in__WIDTH 8
+
+#define R_PORT_PB_SET (IO_TYPECAST_UDWORD 0xb0000038)
+#define R_PORT_PB_SET__syncser3__BITNR 29
+#define R_PORT_PB_SET__syncser3__WIDTH 1
+#define R_PORT_PB_SET__syncser3__port_cs 0
+#define R_PORT_PB_SET__syncser3__ss3extra 1
+#define R_PORT_PB_SET__syncser1__BITNR 28
+#define R_PORT_PB_SET__syncser1__WIDTH 1
+#define R_PORT_PB_SET__syncser1__port_cs 0
+#define R_PORT_PB_SET__syncser1__ss1extra 1
+#define R_PORT_PB_SET__i2c_en__BITNR 27
+#define R_PORT_PB_SET__i2c_en__WIDTH 1
+#define R_PORT_PB_SET__i2c_en__off 0
+#define R_PORT_PB_SET__i2c_en__on 1
+#define R_PORT_PB_SET__i2c_d__BITNR 26
+#define R_PORT_PB_SET__i2c_d__WIDTH 1
+#define R_PORT_PB_SET__i2c_clk__BITNR 25
+#define R_PORT_PB_SET__i2c_clk__WIDTH 1
+#define R_PORT_PB_SET__i2c_oe___BITNR 24
+#define R_PORT_PB_SET__i2c_oe___WIDTH 1
+#define R_PORT_PB_SET__i2c_oe___enable 0
+#define R_PORT_PB_SET__i2c_oe___disable 1
+#define R_PORT_PB_SET__cs7__BITNR 23
+#define R_PORT_PB_SET__cs7__WIDTH 1
+#define R_PORT_PB_SET__cs7__port 0
+#define R_PORT_PB_SET__cs7__cs 1
+#define R_PORT_PB_SET__cs6__BITNR 22
+#define R_PORT_PB_SET__cs6__WIDTH 1
+#define R_PORT_PB_SET__cs6__port 0
+#define R_PORT_PB_SET__cs6__cs 1
+#define R_PORT_PB_SET__cs5__BITNR 21
+#define R_PORT_PB_SET__cs5__WIDTH 1
+#define R_PORT_PB_SET__cs5__port 0
+#define R_PORT_PB_SET__cs5__cs 1
+#define R_PORT_PB_SET__cs4__BITNR 20
+#define R_PORT_PB_SET__cs4__WIDTH 1
+#define R_PORT_PB_SET__cs4__port 0
+#define R_PORT_PB_SET__cs4__cs 1
+#define R_PORT_PB_SET__cs3__BITNR 19
+#define R_PORT_PB_SET__cs3__WIDTH 1
+#define R_PORT_PB_SET__cs3__port 0
+#define R_PORT_PB_SET__cs3__cs 1
+#define R_PORT_PB_SET__cs2__BITNR 18
+#define R_PORT_PB_SET__cs2__WIDTH 1
+#define R_PORT_PB_SET__cs2__port 0
+#define R_PORT_PB_SET__cs2__cs 1
+#define R_PORT_PB_SET__scsi1__BITNR 17
+#define R_PORT_PB_SET__scsi1__WIDTH 1
+#define R_PORT_PB_SET__scsi1__port_cs 0
+#define R_PORT_PB_SET__scsi1__enph 1
+#define R_PORT_PB_SET__scsi0__BITNR 16
+#define R_PORT_PB_SET__scsi0__WIDTH 1
+#define R_PORT_PB_SET__scsi0__port_cs 0
+#define R_PORT_PB_SET__scsi0__enph 1
+#define R_PORT_PB_SET__dir7__BITNR 15
+#define R_PORT_PB_SET__dir7__WIDTH 1
+#define R_PORT_PB_SET__dir7__input 0
+#define R_PORT_PB_SET__dir7__output 1
+#define R_PORT_PB_SET__dir6__BITNR 14
+#define R_PORT_PB_SET__dir6__WIDTH 1
+#define R_PORT_PB_SET__dir6__input 0
+#define R_PORT_PB_SET__dir6__output 1
+#define R_PORT_PB_SET__dir5__BITNR 13
+#define R_PORT_PB_SET__dir5__WIDTH 1
+#define R_PORT_PB_SET__dir5__input 0
+#define R_PORT_PB_SET__dir5__output 1
+#define R_PORT_PB_SET__dir4__BITNR 12
+#define R_PORT_PB_SET__dir4__WIDTH 1
+#define R_PORT_PB_SET__dir4__input 0
+#define R_PORT_PB_SET__dir4__output 1
+#define R_PORT_PB_SET__dir3__BITNR 11
+#define R_PORT_PB_SET__dir3__WIDTH 1
+#define R_PORT_PB_SET__dir3__input 0
+#define R_PORT_PB_SET__dir3__output 1
+#define R_PORT_PB_SET__dir2__BITNR 10
+#define R_PORT_PB_SET__dir2__WIDTH 1
+#define R_PORT_PB_SET__dir2__input 0
+#define R_PORT_PB_SET__dir2__output 1
+#define R_PORT_PB_SET__dir1__BITNR 9
+#define R_PORT_PB_SET__dir1__WIDTH 1
+#define R_PORT_PB_SET__dir1__input 0
+#define R_PORT_PB_SET__dir1__output 1
+#define R_PORT_PB_SET__dir0__BITNR 8
+#define R_PORT_PB_SET__dir0__WIDTH 1
+#define R_PORT_PB_SET__dir0__input 0
+#define R_PORT_PB_SET__dir0__output 1
+#define R_PORT_PB_SET__data_out__BITNR 0
+#define R_PORT_PB_SET__data_out__WIDTH 8
+
+#define R_PORT_PB_DATA (IO_TYPECAST_BYTE 0xb0000038)
+#define R_PORT_PB_DATA__data_out__BITNR 0
+#define R_PORT_PB_DATA__data_out__WIDTH 8
+
+#define R_PORT_PB_DIR (IO_TYPECAST_BYTE 0xb0000039)
+#define R_PORT_PB_DIR__dir7__BITNR 7
+#define R_PORT_PB_DIR__dir7__WIDTH 1
+#define R_PORT_PB_DIR__dir7__input 0
+#define R_PORT_PB_DIR__dir7__output 1
+#define R_PORT_PB_DIR__dir6__BITNR 6
+#define R_PORT_PB_DIR__dir6__WIDTH 1
+#define R_PORT_PB_DIR__dir6__input 0
+#define R_PORT_PB_DIR__dir6__output 1
+#define R_PORT_PB_DIR__dir5__BITNR 5
+#define R_PORT_PB_DIR__dir5__WIDTH 1
+#define R_PORT_PB_DIR__dir5__input 0
+#define R_PORT_PB_DIR__dir5__output 1
+#define R_PORT_PB_DIR__dir4__BITNR 4
+#define R_PORT_PB_DIR__dir4__WIDTH 1
+#define R_PORT_PB_DIR__dir4__input 0
+#define R_PORT_PB_DIR__dir4__output 1
+#define R_PORT_PB_DIR__dir3__BITNR 3
+#define R_PORT_PB_DIR__dir3__WIDTH 1
+#define R_PORT_PB_DIR__dir3__input 0
+#define R_PORT_PB_DIR__dir3__output 1
+#define R_PORT_PB_DIR__dir2__BITNR 2
+#define R_PORT_PB_DIR__dir2__WIDTH 1
+#define R_PORT_PB_DIR__dir2__input 0
+#define R_PORT_PB_DIR__dir2__output 1
+#define R_PORT_PB_DIR__dir1__BITNR 1
+#define R_PORT_PB_DIR__dir1__WIDTH 1
+#define R_PORT_PB_DIR__dir1__input 0
+#define R_PORT_PB_DIR__dir1__output 1
+#define R_PORT_PB_DIR__dir0__BITNR 0
+#define R_PORT_PB_DIR__dir0__WIDTH 1
+#define R_PORT_PB_DIR__dir0__input 0
+#define R_PORT_PB_DIR__dir0__output 1
+
+#define R_PORT_PB_CONFIG (IO_TYPECAST_BYTE 0xb000003a)
+#define R_PORT_PB_CONFIG__cs7__BITNR 7
+#define R_PORT_PB_CONFIG__cs7__WIDTH 1
+#define R_PORT_PB_CONFIG__cs7__port 0
+#define R_PORT_PB_CONFIG__cs7__cs 1
+#define R_PORT_PB_CONFIG__cs6__BITNR 6
+#define R_PORT_PB_CONFIG__cs6__WIDTH 1
+#define R_PORT_PB_CONFIG__cs6__port 0
+#define R_PORT_PB_CONFIG__cs6__cs 1
+#define R_PORT_PB_CONFIG__cs5__BITNR 5
+#define R_PORT_PB_CONFIG__cs5__WIDTH 1
+#define R_PORT_PB_CONFIG__cs5__port 0
+#define R_PORT_PB_CONFIG__cs5__cs 1
+#define R_PORT_PB_CONFIG__cs4__BITNR 4
+#define R_PORT_PB_CONFIG__cs4__WIDTH 1
+#define R_PORT_PB_CONFIG__cs4__port 0
+#define R_PORT_PB_CONFIG__cs4__cs 1
+#define R_PORT_PB_CONFIG__cs3__BITNR 3
+#define R_PORT_PB_CONFIG__cs3__WIDTH 1
+#define R_PORT_PB_CONFIG__cs3__port 0
+#define R_PORT_PB_CONFIG__cs3__cs 1
+#define R_PORT_PB_CONFIG__cs2__BITNR 2
+#define R_PORT_PB_CONFIG__cs2__WIDTH 1
+#define R_PORT_PB_CONFIG__cs2__port 0
+#define R_PORT_PB_CONFIG__cs2__cs 1
+#define R_PORT_PB_CONFIG__scsi1__BITNR 1
+#define R_PORT_PB_CONFIG__scsi1__WIDTH 1
+#define R_PORT_PB_CONFIG__scsi1__port_cs 0
+#define R_PORT_PB_CONFIG__scsi1__enph 1
+#define R_PORT_PB_CONFIG__scsi0__BITNR 0
+#define R_PORT_PB_CONFIG__scsi0__WIDTH 1
+#define R_PORT_PB_CONFIG__scsi0__port_cs 0
+#define R_PORT_PB_CONFIG__scsi0__enph 1
+
+#define R_PORT_PB_I2C (IO_TYPECAST_BYTE 0xb000003b)
+#define R_PORT_PB_I2C__syncser3__BITNR 5
+#define R_PORT_PB_I2C__syncser3__WIDTH 1
+#define R_PORT_PB_I2C__syncser3__port_cs 0
+#define R_PORT_PB_I2C__syncser3__ss3extra 1
+#define R_PORT_PB_I2C__syncser1__BITNR 4
+#define R_PORT_PB_I2C__syncser1__WIDTH 1
+#define R_PORT_PB_I2C__syncser1__port_cs 0
+#define R_PORT_PB_I2C__syncser1__ss1extra 1
+#define R_PORT_PB_I2C__i2c_en__BITNR 3
+#define R_PORT_PB_I2C__i2c_en__WIDTH 1
+#define R_PORT_PB_I2C__i2c_en__off 0
+#define R_PORT_PB_I2C__i2c_en__on 1
+#define R_PORT_PB_I2C__i2c_d__BITNR 2
+#define R_PORT_PB_I2C__i2c_d__WIDTH 1
+#define R_PORT_PB_I2C__i2c_clk__BITNR 1
+#define R_PORT_PB_I2C__i2c_clk__WIDTH 1
+#define R_PORT_PB_I2C__i2c_oe___BITNR 0
+#define R_PORT_PB_I2C__i2c_oe___WIDTH 1
+#define R_PORT_PB_I2C__i2c_oe___enable 0
+#define R_PORT_PB_I2C__i2c_oe___disable 1
+
+#define R_PORT_PB_READ (IO_TYPECAST_RO_UDWORD 0xb0000038)
+#define R_PORT_PB_READ__data_in__BITNR 0
+#define R_PORT_PB_READ__data_in__WIDTH 8
+
+/*
+!* Serial port registers
+!*/
+
+#define R_SERIAL0_CTRL (IO_TYPECAST_UDWORD 0xb0000060)
+#define R_SERIAL0_CTRL__tr_baud__BITNR 28
+#define R_SERIAL0_CTRL__tr_baud__WIDTH 4
+#define R_SERIAL0_CTRL__tr_baud__c300Hz 0
+#define R_SERIAL0_CTRL__tr_baud__c600Hz 1
+#define R_SERIAL0_CTRL__tr_baud__c1200Hz 2
+#define R_SERIAL0_CTRL__tr_baud__c2400Hz 3
+#define R_SERIAL0_CTRL__tr_baud__c4800Hz 4
+#define R_SERIAL0_CTRL__tr_baud__c9600Hz 5
+#define R_SERIAL0_CTRL__tr_baud__c19k2Hz 6
+#define R_SERIAL0_CTRL__tr_baud__c38k4Hz 7
+#define R_SERIAL0_CTRL__tr_baud__c57k6Hz 8
+#define R_SERIAL0_CTRL__tr_baud__c115k2Hz 9
+#define R_SERIAL0_CTRL__tr_baud__c230k4Hz 10
+#define R_SERIAL0_CTRL__tr_baud__c460k8Hz 11
+#define R_SERIAL0_CTRL__tr_baud__c921k6Hz 12
+#define R_SERIAL0_CTRL__tr_baud__c1843k2Hz 13
+#define R_SERIAL0_CTRL__tr_baud__c6250kHz 14
+#define R_SERIAL0_CTRL__tr_baud__reserved 15
+#define R_SERIAL0_CTRL__rec_baud__BITNR 24
+#define R_SERIAL0_CTRL__rec_baud__WIDTH 4
+#define R_SERIAL0_CTRL__rec_baud__c300Hz 0
+#define R_SERIAL0_CTRL__rec_baud__c600Hz 1
+#define R_SERIAL0_CTRL__rec_baud__c1200Hz 2
+#define R_SERIAL0_CTRL__rec_baud__c2400Hz 3
+#define R_SERIAL0_CTRL__rec_baud__c4800Hz 4
+#define R_SERIAL0_CTRL__rec_baud__c9600Hz 5
+#define R_SERIAL0_CTRL__rec_baud__c19k2Hz 6
+#define R_SERIAL0_CTRL__rec_baud__c38k4Hz 7
+#define R_SERIAL0_CTRL__rec_baud__c57k6Hz 8
+#define R_SERIAL0_CTRL__rec_baud__c115k2Hz 9
+#define R_SERIAL0_CTRL__rec_baud__c230k4Hz 10
+#define R_SERIAL0_CTRL__rec_baud__c460k8Hz 11
+#define R_SERIAL0_CTRL__rec_baud__c921k6Hz 12
+#define R_SERIAL0_CTRL__rec_baud__c1843k2Hz 13
+#define R_SERIAL0_CTRL__rec_baud__c6250kHz 14
+#define R_SERIAL0_CTRL__rec_baud__reserved 15
+#define R_SERIAL0_CTRL__dma_err__BITNR 23
+#define R_SERIAL0_CTRL__dma_err__WIDTH 1
+#define R_SERIAL0_CTRL__dma_err__stop 0
+#define R_SERIAL0_CTRL__dma_err__ignore 1
+#define R_SERIAL0_CTRL__rec_enable__BITNR 22
+#define R_SERIAL0_CTRL__rec_enable__WIDTH 1
+#define R_SERIAL0_CTRL__rec_enable__disable 0
+#define R_SERIAL0_CTRL__rec_enable__enable 1
+#define R_SERIAL0_CTRL__rts___BITNR 21
+#define R_SERIAL0_CTRL__rts___WIDTH 1
+#define R_SERIAL0_CTRL__rts___active 0
+#define R_SERIAL0_CTRL__rts___inactive 1
+#define R_SERIAL0_CTRL__sampling__BITNR 20
+#define R_SERIAL0_CTRL__sampling__WIDTH 1
+#define R_SERIAL0_CTRL__sampling__middle 0
+#define R_SERIAL0_CTRL__sampling__majority 1
+#define R_SERIAL0_CTRL__rec_stick_par__BITNR 19
+#define R_SERIAL0_CTRL__rec_stick_par__WIDTH 1
+#define R_SERIAL0_CTRL__rec_stick_par__normal 0
+#define R_SERIAL0_CTRL__rec_stick_par__stick 1
+#define R_SERIAL0_CTRL__rec_par__BITNR 18
+#define R_SERIAL0_CTRL__rec_par__WIDTH 1
+#define R_SERIAL0_CTRL__rec_par__even 0
+#define R_SERIAL0_CTRL__rec_par__odd 1
+#define R_SERIAL0_CTRL__rec_par_en__BITNR 17
+#define R_SERIAL0_CTRL__rec_par_en__WIDTH 1
+#define R_SERIAL0_CTRL__rec_par_en__disable 0
+#define R_SERIAL0_CTRL__rec_par_en__enable 1
+#define R_SERIAL0_CTRL__rec_bitnr__BITNR 16
+#define R_SERIAL0_CTRL__rec_bitnr__WIDTH 1
+#define R_SERIAL0_CTRL__rec_bitnr__rec_8bit 0
+#define R_SERIAL0_CTRL__rec_bitnr__rec_7bit 1
+#define R_SERIAL0_CTRL__txd__BITNR 15
+#define R_SERIAL0_CTRL__txd__WIDTH 1
+#define R_SERIAL0_CTRL__tr_enable__BITNR 14
+#define R_SERIAL0_CTRL__tr_enable__WIDTH 1
+#define R_SERIAL0_CTRL__tr_enable__disable 0
+#define R_SERIAL0_CTRL__tr_enable__enable 1
+#define R_SERIAL0_CTRL__auto_cts__BITNR 13
+#define R_SERIAL0_CTRL__auto_cts__WIDTH 1
+#define R_SERIAL0_CTRL__auto_cts__disabled 0
+#define R_SERIAL0_CTRL__auto_cts__active 1
+#define R_SERIAL0_CTRL__stop_bits__BITNR 12
+#define R_SERIAL0_CTRL__stop_bits__WIDTH 1
+#define R_SERIAL0_CTRL__stop_bits__one_bit 0
+#define R_SERIAL0_CTRL__stop_bits__two_bits 1
+#define R_SERIAL0_CTRL__tr_stick_par__BITNR 11
+#define R_SERIAL0_CTRL__tr_stick_par__WIDTH 1
+#define R_SERIAL0_CTRL__tr_stick_par__normal 0
+#define R_SERIAL0_CTRL__tr_stick_par__stick 1
+#define R_SERIAL0_CTRL__tr_par__BITNR 10
+#define R_SERIAL0_CTRL__tr_par__WIDTH 1
+#define R_SERIAL0_CTRL__tr_par__even 0
+#define R_SERIAL0_CTRL__tr_par__odd 1
+#define R_SERIAL0_CTRL__tr_par_en__BITNR 9
+#define R_SERIAL0_CTRL__tr_par_en__WIDTH 1
+#define R_SERIAL0_CTRL__tr_par_en__disable 0
+#define R_SERIAL0_CTRL__tr_par_en__enable 1
+#define R_SERIAL0_CTRL__tr_bitnr__BITNR 8
+#define R_SERIAL0_CTRL__tr_bitnr__WIDTH 1
+#define R_SERIAL0_CTRL__tr_bitnr__tr_8bit 0
+#define R_SERIAL0_CTRL__tr_bitnr__tr_7bit 1
+#define R_SERIAL0_CTRL__data_out__BITNR 0
+#define R_SERIAL0_CTRL__data_out__WIDTH 8
+
+#define R_SERIAL0_BAUD (IO_TYPECAST_BYTE 0xb0000063)
+#define R_SERIAL0_BAUD__tr_baud__BITNR 4
+#define R_SERIAL0_BAUD__tr_baud__WIDTH 4
+#define R_SERIAL0_BAUD__tr_baud__c300Hz 0
+#define R_SERIAL0_BAUD__tr_baud__c600Hz 1
+#define R_SERIAL0_BAUD__tr_baud__c1200Hz 2
+#define R_SERIAL0_BAUD__tr_baud__c2400Hz 3
+#define R_SERIAL0_BAUD__tr_baud__c4800Hz 4
+#define R_SERIAL0_BAUD__tr_baud__c9600Hz 5
+#define R_SERIAL0_BAUD__tr_baud__c19k2Hz 6
+#define R_SERIAL0_BAUD__tr_baud__c38k4Hz 7
+#define R_SERIAL0_BAUD__tr_baud__c57k6Hz 8
+#define R_SERIAL0_BAUD__tr_baud__c115k2Hz 9
+#define R_SERIAL0_BAUD__tr_baud__c230k4Hz 10
+#define R_SERIAL0_BAUD__tr_baud__c460k8Hz 11
+#define R_SERIAL0_BAUD__tr_baud__c921k6Hz 12
+#define R_SERIAL0_BAUD__tr_baud__c1843k2Hz 13
+#define R_SERIAL0_BAUD__tr_baud__c6250kHz 14
+#define R_SERIAL0_BAUD__tr_baud__reserved 15
+#define R_SERIAL0_BAUD__rec_baud__BITNR 0
+#define R_SERIAL0_BAUD__rec_baud__WIDTH 4
+#define R_SERIAL0_BAUD__rec_baud__c300Hz 0
+#define R_SERIAL0_BAUD__rec_baud__c600Hz 1
+#define R_SERIAL0_BAUD__rec_baud__c1200Hz 2
+#define R_SERIAL0_BAUD__rec_baud__c2400Hz 3
+#define R_SERIAL0_BAUD__rec_baud__c4800Hz 4
+#define R_SERIAL0_BAUD__rec_baud__c9600Hz 5
+#define R_SERIAL0_BAUD__rec_baud__c19k2Hz 6
+#define R_SERIAL0_BAUD__rec_baud__c38k4Hz 7
+#define R_SERIAL0_BAUD__rec_baud__c57k6Hz 8
+#define R_SERIAL0_BAUD__rec_baud__c115k2Hz 9
+#define R_SERIAL0_BAUD__rec_baud__c230k4Hz 10
+#define R_SERIAL0_BAUD__rec_baud__c460k8Hz 11
+#define R_SERIAL0_BAUD__rec_baud__c921k6Hz 12
+#define R_SERIAL0_BAUD__rec_baud__c1843k2Hz 13
+#define R_SERIAL0_BAUD__rec_baud__c6250kHz 14
+#define R_SERIAL0_BAUD__rec_baud__reserved 15
+
+#define R_SERIAL0_REC_CTRL (IO_TYPECAST_BYTE 0xb0000062)
+#define R_SERIAL0_REC_CTRL__dma_err__BITNR 7
+#define R_SERIAL0_REC_CTRL__dma_err__WIDTH 1
+#define R_SERIAL0_REC_CTRL__dma_err__stop 0
+#define R_SERIAL0_REC_CTRL__dma_err__ignore 1
+#define R_SERIAL0_REC_CTRL__rec_enable__BITNR 6
+#define R_SERIAL0_REC_CTRL__rec_enable__WIDTH 1
+#define R_SERIAL0_REC_CTRL__rec_enable__disable 0
+#define R_SERIAL0_REC_CTRL__rec_enable__enable 1
+#define R_SERIAL0_REC_CTRL__rts___BITNR 5
+#define R_SERIAL0_REC_CTRL__rts___WIDTH 1
+#define R_SERIAL0_REC_CTRL__rts___active 0
+#define R_SERIAL0_REC_CTRL__rts___inactive 1
+#define R_SERIAL0_REC_CTRL__sampling__BITNR 4
+#define R_SERIAL0_REC_CTRL__sampling__WIDTH 1
+#define R_SERIAL0_REC_CTRL__sampling__middle 0
+#define R_SERIAL0_REC_CTRL__sampling__majority 1
+#define R_SERIAL0_REC_CTRL__rec_stick_par__BITNR 3
+#define R_SERIAL0_REC_CTRL__rec_stick_par__WIDTH 1
+#define R_SERIAL0_REC_CTRL__rec_stick_par__normal 0
+#define R_SERIAL0_REC_CTRL__rec_stick_par__stick 1
+#define R_SERIAL0_REC_CTRL__rec_par__BITNR 2
+#define R_SERIAL0_REC_CTRL__rec_par__WIDTH 1
+#define R_SERIAL0_REC_CTRL__rec_par__even 0
+#define R_SERIAL0_REC_CTRL__rec_par__odd 1
+#define R_SERIAL0_REC_CTRL__rec_par_en__BITNR 1
+#define R_SERIAL0_REC_CTRL__rec_par_en__WIDTH 1
+#define R_SERIAL0_REC_CTRL__rec_par_en__disable 0
+#define R_SERIAL0_REC_CTRL__rec_par_en__enable 1
+#define R_SERIAL0_REC_CTRL__rec_bitnr__BITNR 0
+#define R_SERIAL0_REC_CTRL__rec_bitnr__WIDTH 1
+#define R_SERIAL0_REC_CTRL__rec_bitnr__rec_8bit 0
+#define R_SERIAL0_REC_CTRL__rec_bitnr__rec_7bit 1
+
+#define R_SERIAL0_TR_CTRL (IO_TYPECAST_BYTE 0xb0000061)
+#define R_SERIAL0_TR_CTRL__txd__BITNR 7
+#define R_SERIAL0_TR_CTRL__txd__WIDTH 1
+#define R_SERIAL0_TR_CTRL__tr_enable__BITNR 6
+#define R_SERIAL0_TR_CTRL__tr_enable__WIDTH 1
+#define R_SERIAL0_TR_CTRL__tr_enable__disable 0
+#define R_SERIAL0_TR_CTRL__tr_enable__enable 1
+#define R_SERIAL0_TR_CTRL__auto_cts__BITNR 5
+#define R_SERIAL0_TR_CTRL__auto_cts__WIDTH 1
+#define R_SERIAL0_TR_CTRL__auto_cts__disabled 0
+#define R_SERIAL0_TR_CTRL__auto_cts__active 1
+#define R_SERIAL0_TR_CTRL__stop_bits__BITNR 4
+#define R_SERIAL0_TR_CTRL__stop_bits__WIDTH 1
+#define R_SERIAL0_TR_CTRL__stop_bits__one_bit 0
+#define R_SERIAL0_TR_CTRL__stop_bits__two_bits 1
+#define R_SERIAL0_TR_CTRL__tr_stick_par__BITNR 3
+#define R_SERIAL0_TR_CTRL__tr_stick_par__WIDTH 1
+#define R_SERIAL0_TR_CTRL__tr_stick_par__normal 0
+#define R_SERIAL0_TR_CTRL__tr_stick_par__stick 1
+#define R_SERIAL0_TR_CTRL__tr_par__BITNR 2
+#define R_SERIAL0_TR_CTRL__tr_par__WIDTH 1
+#define R_SERIAL0_TR_CTRL__tr_par__even 0
+#define R_SERIAL0_TR_CTRL__tr_par__odd 1
+#define R_SERIAL0_TR_CTRL__tr_par_en__BITNR 1
+#define R_SERIAL0_TR_CTRL__tr_par_en__WIDTH 1
+#define R_SERIAL0_TR_CTRL__tr_par_en__disable 0
+#define R_SERIAL0_TR_CTRL__tr_par_en__enable 1
+#define R_SERIAL0_TR_CTRL__tr_bitnr__BITNR 0
+#define R_SERIAL0_TR_CTRL__tr_bitnr__WIDTH 1
+#define R_SERIAL0_TR_CTRL__tr_bitnr__tr_8bit 0
+#define R_SERIAL0_TR_CTRL__tr_bitnr__tr_7bit 1
+
+#define R_SERIAL0_TR_DATA (IO_TYPECAST_BYTE 0xb0000060)
+#define R_SERIAL0_TR_DATA__data_out__BITNR 0
+#define R_SERIAL0_TR_DATA__data_out__WIDTH 8
+
+#define R_SERIAL0_READ (IO_TYPECAST_RO_UDWORD 0xb0000060)
+#define R_SERIAL0_READ__xoff_detect__BITNR 15
+#define R_SERIAL0_READ__xoff_detect__WIDTH 1
+#define R_SERIAL0_READ__xoff_detect__no_xoff 0
+#define R_SERIAL0_READ__xoff_detect__xoff 1
+#define R_SERIAL0_READ__cts___BITNR 14
+#define R_SERIAL0_READ__cts___WIDTH 1
+#define R_SERIAL0_READ__cts___active 0
+#define R_SERIAL0_READ__cts___inactive 1
+#define R_SERIAL0_READ__tr_ready__BITNR 13
+#define R_SERIAL0_READ__tr_ready__WIDTH 1
+#define R_SERIAL0_READ__tr_ready__full 0
+#define R_SERIAL0_READ__tr_ready__ready 1
+#define R_SERIAL0_READ__rxd__BITNR 12
+#define R_SERIAL0_READ__rxd__WIDTH 1
+#define R_SERIAL0_READ__overrun__BITNR 11
+#define R_SERIAL0_READ__overrun__WIDTH 1
+#define R_SERIAL0_READ__overrun__no 0
+#define R_SERIAL0_READ__overrun__yes 1
+#define R_SERIAL0_READ__par_err__BITNR 10
+#define R_SERIAL0_READ__par_err__WIDTH 1
+#define R_SERIAL0_READ__par_err__no 0
+#define R_SERIAL0_READ__par_err__yes 1
+#define R_SERIAL0_READ__framing_err__BITNR 9
+#define R_SERIAL0_READ__framing_err__WIDTH 1
+#define R_SERIAL0_READ__framing_err__no 0
+#define R_SERIAL0_READ__framing_err__yes 1
+#define R_SERIAL0_READ__data_avail__BITNR 8
+#define R_SERIAL0_READ__data_avail__WIDTH 1
+#define R_SERIAL0_READ__data_avail__no 0
+#define R_SERIAL0_READ__data_avail__yes 1
+#define R_SERIAL0_READ__data_in__BITNR 0
+#define R_SERIAL0_READ__data_in__WIDTH 8
+
+#define R_SERIAL0_STATUS (IO_TYPECAST_RO_BYTE 0xb0000061)
+#define R_SERIAL0_STATUS__xoff_detect__BITNR 7
+#define R_SERIAL0_STATUS__xoff_detect__WIDTH 1
+#define R_SERIAL0_STATUS__xoff_detect__no_xoff 0
+#define R_SERIAL0_STATUS__xoff_detect__xoff 1
+#define R_SERIAL0_STATUS__cts___BITNR 6
+#define R_SERIAL0_STATUS__cts___WIDTH 1
+#define R_SERIAL0_STATUS__cts___active 0
+#define R_SERIAL0_STATUS__cts___inactive 1
+#define R_SERIAL0_STATUS__tr_ready__BITNR 5
+#define R_SERIAL0_STATUS__tr_ready__WIDTH 1
+#define R_SERIAL0_STATUS__tr_ready__full 0
+#define R_SERIAL0_STATUS__tr_ready__ready 1
+#define R_SERIAL0_STATUS__rxd__BITNR 4
+#define R_SERIAL0_STATUS__rxd__WIDTH 1
+#define R_SERIAL0_STATUS__overrun__BITNR 3
+#define R_SERIAL0_STATUS__overrun__WIDTH 1
+#define R_SERIAL0_STATUS__overrun__no 0
+#define R_SERIAL0_STATUS__overrun__yes 1
+#define R_SERIAL0_STATUS__par_err__BITNR 2
+#define R_SERIAL0_STATUS__par_err__WIDTH 1
+#define R_SERIAL0_STATUS__par_err__no 0
+#define R_SERIAL0_STATUS__par_err__yes 1
+#define R_SERIAL0_STATUS__framing_err__BITNR 1
+#define R_SERIAL0_STATUS__framing_err__WIDTH 1
+#define R_SERIAL0_STATUS__framing_err__no 0
+#define R_SERIAL0_STATUS__framing_err__yes 1
+#define R_SERIAL0_STATUS__data_avail__BITNR 0
+#define R_SERIAL0_STATUS__data_avail__WIDTH 1
+#define R_SERIAL0_STATUS__data_avail__no 0
+#define R_SERIAL0_STATUS__data_avail__yes 1
+
+#define R_SERIAL0_REC_DATA (IO_TYPECAST_RO_BYTE 0xb0000060)
+#define R_SERIAL0_REC_DATA__data_in__BITNR 0
+#define R_SERIAL0_REC_DATA__data_in__WIDTH 8
+
+#define R_SERIAL0_XOFF (IO_TYPECAST_UDWORD 0xb0000064)
+#define R_SERIAL0_XOFF__tx_stop__BITNR 9
+#define R_SERIAL0_XOFF__tx_stop__WIDTH 1
+#define R_SERIAL0_XOFF__tx_stop__enable 0
+#define R_SERIAL0_XOFF__tx_stop__stop 1
+#define R_SERIAL0_XOFF__auto_xoff__BITNR 8
+#define R_SERIAL0_XOFF__auto_xoff__WIDTH 1
+#define R_SERIAL0_XOFF__auto_xoff__disable 0
+#define R_SERIAL0_XOFF__auto_xoff__enable 1
+#define R_SERIAL0_XOFF__xoff_char__BITNR 0
+#define R_SERIAL0_XOFF__xoff_char__WIDTH 8
+
+#define R_SERIAL1_CTRL (IO_TYPECAST_UDWORD 0xb0000068)
+#define R_SERIAL1_CTRL__tr_baud__BITNR 28
+#define R_SERIAL1_CTRL__tr_baud__WIDTH 4
+#define R_SERIAL1_CTRL__tr_baud__c300Hz 0
+#define R_SERIAL1_CTRL__tr_baud__c600Hz 1
+#define R_SERIAL1_CTRL__tr_baud__c1200Hz 2
+#define R_SERIAL1_CTRL__tr_baud__c2400Hz 3
+#define R_SERIAL1_CTRL__tr_baud__c4800Hz 4
+#define R_SERIAL1_CTRL__tr_baud__c9600Hz 5
+#define R_SERIAL1_CTRL__tr_baud__c19k2Hz 6
+#define R_SERIAL1_CTRL__tr_baud__c38k4Hz 7
+#define R_SERIAL1_CTRL__tr_baud__c57k6Hz 8
+#define R_SERIAL1_CTRL__tr_baud__c115k2Hz 9
+#define R_SERIAL1_CTRL__tr_baud__c230k4Hz 10
+#define R_SERIAL1_CTRL__tr_baud__c460k8Hz 11
+#define R_SERIAL1_CTRL__tr_baud__c921k6Hz 12
+#define R_SERIAL1_CTRL__tr_baud__c1843k2Hz 13
+#define R_SERIAL1_CTRL__tr_baud__c6250kHz 14
+#define R_SERIAL1_CTRL__tr_baud__reserved 15
+#define R_SERIAL1_CTRL__rec_baud__BITNR 24
+#define R_SERIAL1_CTRL__rec_baud__WIDTH 4
+#define R_SERIAL1_CTRL__rec_baud__c300Hz 0
+#define R_SERIAL1_CTRL__rec_baud__c600Hz 1
+#define R_SERIAL1_CTRL__rec_baud__c1200Hz 2
+#define R_SERIAL1_CTRL__rec_baud__c2400Hz 3
+#define R_SERIAL1_CTRL__rec_baud__c4800Hz 4
+#define R_SERIAL1_CTRL__rec_baud__c9600Hz 5
+#define R_SERIAL1_CTRL__rec_baud__c19k2Hz 6
+#define R_SERIAL1_CTRL__rec_baud__c38k4Hz 7
+#define R_SERIAL1_CTRL__rec_baud__c57k6Hz 8
+#define R_SERIAL1_CTRL__rec_baud__c115k2Hz 9
+#define R_SERIAL1_CTRL__rec_baud__c230k4Hz 10
+#define R_SERIAL1_CTRL__rec_baud__c460k8Hz 11
+#define R_SERIAL1_CTRL__rec_baud__c921k6Hz 12
+#define R_SERIAL1_CTRL__rec_baud__c1843k2Hz 13
+#define R_SERIAL1_CTRL__rec_baud__c6250kHz 14
+#define R_SERIAL1_CTRL__rec_baud__reserved 15
+#define R_SERIAL1_CTRL__dma_err__BITNR 23
+#define R_SERIAL1_CTRL__dma_err__WIDTH 1
+#define R_SERIAL1_CTRL__dma_err__stop 0
+#define R_SERIAL1_CTRL__dma_err__ignore 1
+#define R_SERIAL1_CTRL__rec_enable__BITNR 22
+#define R_SERIAL1_CTRL__rec_enable__WIDTH 1
+#define R_SERIAL1_CTRL__rec_enable__disable 0
+#define R_SERIAL1_CTRL__rec_enable__enable 1
+#define R_SERIAL1_CTRL__rts___BITNR 21
+#define R_SERIAL1_CTRL__rts___WIDTH 1
+#define R_SERIAL1_CTRL__rts___active 0
+#define R_SERIAL1_CTRL__rts___inactive 1
+#define R_SERIAL1_CTRL__sampling__BITNR 20
+#define R_SERIAL1_CTRL__sampling__WIDTH 1
+#define R_SERIAL1_CTRL__sampling__middle 0
+#define R_SERIAL1_CTRL__sampling__majority 1
+#define R_SERIAL1_CTRL__rec_stick_par__BITNR 19
+#define R_SERIAL1_CTRL__rec_stick_par__WIDTH 1
+#define R_SERIAL1_CTRL__rec_stick_par__normal 0
+#define R_SERIAL1_CTRL__rec_stick_par__stick 1
+#define R_SERIAL1_CTRL__rec_par__BITNR 18
+#define R_SERIAL1_CTRL__rec_par__WIDTH 1
+#define R_SERIAL1_CTRL__rec_par__even 0
+#define R_SERIAL1_CTRL__rec_par__odd 1
+#define R_SERIAL1_CTRL__rec_par_en__BITNR 17
+#define R_SERIAL1_CTRL__rec_par_en__WIDTH 1
+#define R_SERIAL1_CTRL__rec_par_en__disable 0
+#define R_SERIAL1_CTRL__rec_par_en__enable 1
+#define R_SERIAL1_CTRL__rec_bitnr__BITNR 16
+#define R_SERIAL1_CTRL__rec_bitnr__WIDTH 1
+#define R_SERIAL1_CTRL__rec_bitnr__rec_8bit 0
+#define R_SERIAL1_CTRL__rec_bitnr__rec_7bit 1
+#define R_SERIAL1_CTRL__txd__BITNR 15
+#define R_SERIAL1_CTRL__txd__WIDTH 1
+#define R_SERIAL1_CTRL__tr_enable__BITNR 14
+#define R_SERIAL1_CTRL__tr_enable__WIDTH 1
+#define R_SERIAL1_CTRL__tr_enable__disable 0
+#define R_SERIAL1_CTRL__tr_enable__enable 1
+#define R_SERIAL1_CTRL__auto_cts__BITNR 13
+#define R_SERIAL1_CTRL__auto_cts__WIDTH 1
+#define R_SERIAL1_CTRL__auto_cts__disabled 0
+#define R_SERIAL1_CTRL__auto_cts__active 1
+#define R_SERIAL1_CTRL__stop_bits__BITNR 12
+#define R_SERIAL1_CTRL__stop_bits__WIDTH 1
+#define R_SERIAL1_CTRL__stop_bits__one_bit 0
+#define R_SERIAL1_CTRL__stop_bits__two_bits 1
+#define R_SERIAL1_CTRL__tr_stick_par__BITNR 11
+#define R_SERIAL1_CTRL__tr_stick_par__WIDTH 1
+#define R_SERIAL1_CTRL__tr_stick_par__normal 0
+#define R_SERIAL1_CTRL__tr_stick_par__stick 1
+#define R_SERIAL1_CTRL__tr_par__BITNR 10
+#define R_SERIAL1_CTRL__tr_par__WIDTH 1
+#define R_SERIAL1_CTRL__tr_par__even 0
+#define R_SERIAL1_CTRL__tr_par__odd 1
+#define R_SERIAL1_CTRL__tr_par_en__BITNR 9
+#define R_SERIAL1_CTRL__tr_par_en__WIDTH 1
+#define R_SERIAL1_CTRL__tr_par_en__disable 0
+#define R_SERIAL1_CTRL__tr_par_en__enable 1
+#define R_SERIAL1_CTRL__tr_bitnr__BITNR 8
+#define R_SERIAL1_CTRL__tr_bitnr__WIDTH 1
+#define R_SERIAL1_CTRL__tr_bitnr__tr_8bit 0
+#define R_SERIAL1_CTRL__tr_bitnr__tr_7bit 1
+#define R_SERIAL1_CTRL__data_out__BITNR 0
+#define R_SERIAL1_CTRL__data_out__WIDTH 8
+
+#define R_SERIAL1_BAUD (IO_TYPECAST_BYTE 0xb000006b)
+#define R_SERIAL1_BAUD__tr_baud__BITNR 4
+#define R_SERIAL1_BAUD__tr_baud__WIDTH 4
+#define R_SERIAL1_BAUD__tr_baud__c300Hz 0
+#define R_SERIAL1_BAUD__tr_baud__c600Hz 1
+#define R_SERIAL1_BAUD__tr_baud__c1200Hz 2
+#define R_SERIAL1_BAUD__tr_baud__c2400Hz 3
+#define R_SERIAL1_BAUD__tr_baud__c4800Hz 4
+#define R_SERIAL1_BAUD__tr_baud__c9600Hz 5
+#define R_SERIAL1_BAUD__tr_baud__c19k2Hz 6
+#define R_SERIAL1_BAUD__tr_baud__c38k4Hz 7
+#define R_SERIAL1_BAUD__tr_baud__c57k6Hz 8
+#define R_SERIAL1_BAUD__tr_baud__c115k2Hz 9
+#define R_SERIAL1_BAUD__tr_baud__c230k4Hz 10
+#define R_SERIAL1_BAUD__tr_baud__c460k8Hz 11
+#define R_SERIAL1_BAUD__tr_baud__c921k6Hz 12
+#define R_SERIAL1_BAUD__tr_baud__c1843k2Hz 13
+#define R_SERIAL1_BAUD__tr_baud__c6250kHz 14
+#define R_SERIAL1_BAUD__tr_baud__reserved 15
+#define R_SERIAL1_BAUD__rec_baud__BITNR 0
+#define R_SERIAL1_BAUD__rec_baud__WIDTH 4
+#define R_SERIAL1_BAUD__rec_baud__c300Hz 0
+#define R_SERIAL1_BAUD__rec_baud__c600Hz 1
+#define R_SERIAL1_BAUD__rec_baud__c1200Hz 2
+#define R_SERIAL1_BAUD__rec_baud__c2400Hz 3
+#define R_SERIAL1_BAUD__rec_baud__c4800Hz 4
+#define R_SERIAL1_BAUD__rec_baud__c9600Hz 5
+#define R_SERIAL1_BAUD__rec_baud__c19k2Hz 6
+#define R_SERIAL1_BAUD__rec_baud__c38k4Hz 7
+#define R_SERIAL1_BAUD__rec_baud__c57k6Hz 8
+#define R_SERIAL1_BAUD__rec_baud__c115k2Hz 9
+#define R_SERIAL1_BAUD__rec_baud__c230k4Hz 10
+#define R_SERIAL1_BAUD__rec_baud__c460k8Hz 11
+#define R_SERIAL1_BAUD__rec_baud__c921k6Hz 12
+#define R_SERIAL1_BAUD__rec_baud__c1843k2Hz 13
+#define R_SERIAL1_BAUD__rec_baud__c6250kHz 14
+#define R_SERIAL1_BAUD__rec_baud__reserved 15
+
+#define R_SERIAL1_REC_CTRL (IO_TYPECAST_BYTE 0xb000006a)
+#define R_SERIAL1_REC_CTRL__dma_err__BITNR 7
+#define R_SERIAL1_REC_CTRL__dma_err__WIDTH 1
+#define R_SERIAL1_REC_CTRL__dma_err__stop 0
+#define R_SERIAL1_REC_CTRL__dma_err__ignore 1
+#define R_SERIAL1_REC_CTRL__rec_enable__BITNR 6
+#define R_SERIAL1_REC_CTRL__rec_enable__WIDTH 1
+#define R_SERIAL1_REC_CTRL__rec_enable__disable 0
+#define R_SERIAL1_REC_CTRL__rec_enable__enable 1
+#define R_SERIAL1_REC_CTRL__rts___BITNR 5
+#define R_SERIAL1_REC_CTRL__rts___WIDTH 1
+#define R_SERIAL1_REC_CTRL__rts___active 0
+#define R_SERIAL1_REC_CTRL__rts___inactive 1
+#define R_SERIAL1_REC_CTRL__sampling__BITNR 4
+#define R_SERIAL1_REC_CTRL__sampling__WIDTH 1
+#define R_SERIAL1_REC_CTRL__sampling__middle 0
+#define R_SERIAL1_REC_CTRL__sampling__majority 1
+#define R_SERIAL1_REC_CTRL__rec_stick_par__BITNR 3
+#define R_SERIAL1_REC_CTRL__rec_stick_par__WIDTH 1
+#define R_SERIAL1_REC_CTRL__rec_stick_par__normal 0
+#define R_SERIAL1_REC_CTRL__rec_stick_par__stick 1
+#define R_SERIAL1_REC_CTRL__rec_par__BITNR 2
+#define R_SERIAL1_REC_CTRL__rec_par__WIDTH 1
+#define R_SERIAL1_REC_CTRL__rec_par__even 0
+#define R_SERIAL1_REC_CTRL__rec_par__odd 1
+#define R_SERIAL1_REC_CTRL__rec_par_en__BITNR 1
+#define R_SERIAL1_REC_CTRL__rec_par_en__WIDTH 1
+#define R_SERIAL1_REC_CTRL__rec_par_en__disable 0
+#define R_SERIAL1_REC_CTRL__rec_par_en__enable 1
+#define R_SERIAL1_REC_CTRL__rec_bitnr__BITNR 0
+#define R_SERIAL1_REC_CTRL__rec_bitnr__WIDTH 1
+#define R_SERIAL1_REC_CTRL__rec_bitnr__rec_8bit 0
+#define R_SERIAL1_REC_CTRL__rec_bitnr__rec_7bit 1
+
+#define R_SERIAL1_TR_CTRL (IO_TYPECAST_BYTE 0xb0000069)
+#define R_SERIAL1_TR_CTRL__txd__BITNR 7
+#define R_SERIAL1_TR_CTRL__txd__WIDTH 1
+#define R_SERIAL1_TR_CTRL__tr_enable__BITNR 6
+#define R_SERIAL1_TR_CTRL__tr_enable__WIDTH 1
+#define R_SERIAL1_TR_CTRL__tr_enable__disable 0
+#define R_SERIAL1_TR_CTRL__tr_enable__enable 1
+#define R_SERIAL1_TR_CTRL__auto_cts__BITNR 5
+#define R_SERIAL1_TR_CTRL__auto_cts__WIDTH 1
+#define R_SERIAL1_TR_CTRL__auto_cts__disabled 0
+#define R_SERIAL1_TR_CTRL__auto_cts__active 1
+#define R_SERIAL1_TR_CTRL__stop_bits__BITNR 4
+#define R_SERIAL1_TR_CTRL__stop_bits__WIDTH 1
+#define R_SERIAL1_TR_CTRL__stop_bits__one_bit 0
+#define R_SERIAL1_TR_CTRL__stop_bits__two_bits 1
+#define R_SERIAL1_TR_CTRL__tr_stick_par__BITNR 3
+#define R_SERIAL1_TR_CTRL__tr_stick_par__WIDTH 1
+#define R_SERIAL1_TR_CTRL__tr_stick_par__normal 0
+#define R_SERIAL1_TR_CTRL__tr_stick_par__stick 1
+#define R_SERIAL1_TR_CTRL__tr_par__BITNR 2
+#define R_SERIAL1_TR_CTRL__tr_par__WIDTH 1
+#define R_SERIAL1_TR_CTRL__tr_par__even 0
+#define R_SERIAL1_TR_CTRL__tr_par__odd 1
+#define R_SERIAL1_TR_CTRL__tr_par_en__BITNR 1
+#define R_SERIAL1_TR_CTRL__tr_par_en__WIDTH 1
+#define R_SERIAL1_TR_CTRL__tr_par_en__disable 0
+#define R_SERIAL1_TR_CTRL__tr_par_en__enable 1
+#define R_SERIAL1_TR_CTRL__tr_bitnr__BITNR 0
+#define R_SERIAL1_TR_CTRL__tr_bitnr__WIDTH 1
+#define R_SERIAL1_TR_CTRL__tr_bitnr__tr_8bit 0
+#define R_SERIAL1_TR_CTRL__tr_bitnr__tr_7bit 1
+
+#define R_SERIAL1_TR_DATA (IO_TYPECAST_BYTE 0xb0000068)
+#define R_SERIAL1_TR_DATA__data_out__BITNR 0
+#define R_SERIAL1_TR_DATA__data_out__WIDTH 8
+
+#define R_SERIAL1_READ (IO_TYPECAST_RO_UDWORD 0xb0000068)
+#define R_SERIAL1_READ__xoff_detect__BITNR 15
+#define R_SERIAL1_READ__xoff_detect__WIDTH 1
+#define R_SERIAL1_READ__xoff_detect__no_xoff 0
+#define R_SERIAL1_READ__xoff_detect__xoff 1
+#define R_SERIAL1_READ__cts___BITNR 14
+#define R_SERIAL1_READ__cts___WIDTH 1
+#define R_SERIAL1_READ__cts___active 0
+#define R_SERIAL1_READ__cts___inactive 1
+#define R_SERIAL1_READ__tr_ready__BITNR 13
+#define R_SERIAL1_READ__tr_ready__WIDTH 1
+#define R_SERIAL1_READ__tr_ready__full 0
+#define R_SERIAL1_READ__tr_ready__ready 1
+#define R_SERIAL1_READ__rxd__BITNR 12
+#define R_SERIAL1_READ__rxd__WIDTH 1
+#define R_SERIAL1_READ__overrun__BITNR 11
+#define R_SERIAL1_READ__overrun__WIDTH 1
+#define R_SERIAL1_READ__overrun__no 0
+#define R_SERIAL1_READ__overrun__yes 1
+#define R_SERIAL1_READ__par_err__BITNR 10
+#define R_SERIAL1_READ__par_err__WIDTH 1
+#define R_SERIAL1_READ__par_err__no 0
+#define R_SERIAL1_READ__par_err__yes 1
+#define R_SERIAL1_READ__framing_err__BITNR 9
+#define R_SERIAL1_READ__framing_err__WIDTH 1
+#define R_SERIAL1_READ__framing_err__no 0
+#define R_SERIAL1_READ__framing_err__yes 1
+#define R_SERIAL1_READ__data_avail__BITNR 8
+#define R_SERIAL1_READ__data_avail__WIDTH 1
+#define R_SERIAL1_READ__data_avail__no 0
+#define R_SERIAL1_READ__data_avail__yes 1
+#define R_SERIAL1_READ__data_in__BITNR 0
+#define R_SERIAL1_READ__data_in__WIDTH 8
+
+#define R_SERIAL1_STATUS (IO_TYPECAST_RO_BYTE 0xb0000069)
+#define R_SERIAL1_STATUS__xoff_detect__BITNR 7
+#define R_SERIAL1_STATUS__xoff_detect__WIDTH 1
+#define R_SERIAL1_STATUS__xoff_detect__no_xoff 0
+#define R_SERIAL1_STATUS__xoff_detect__xoff 1
+#define R_SERIAL1_STATUS__cts___BITNR 6
+#define R_SERIAL1_STATUS__cts___WIDTH 1
+#define R_SERIAL1_STATUS__cts___active 0
+#define R_SERIAL1_STATUS__cts___inactive 1
+#define R_SERIAL1_STATUS__tr_ready__BITNR 5
+#define R_SERIAL1_STATUS__tr_ready__WIDTH 1
+#define R_SERIAL1_STATUS__tr_ready__full 0
+#define R_SERIAL1_STATUS__tr_ready__ready 1
+#define R_SERIAL1_STATUS__rxd__BITNR 4
+#define R_SERIAL1_STATUS__rxd__WIDTH 1
+#define R_SERIAL1_STATUS__overrun__BITNR 3
+#define R_SERIAL1_STATUS__overrun__WIDTH 1
+#define R_SERIAL1_STATUS__overrun__no 0
+#define R_SERIAL1_STATUS__overrun__yes 1
+#define R_SERIAL1_STATUS__par_err__BITNR 2
+#define R_SERIAL1_STATUS__par_err__WIDTH 1
+#define R_SERIAL1_STATUS__par_err__no 0
+#define R_SERIAL1_STATUS__par_err__yes 1
+#define R_SERIAL1_STATUS__framing_err__BITNR 1
+#define R_SERIAL1_STATUS__framing_err__WIDTH 1
+#define R_SERIAL1_STATUS__framing_err__no 0
+#define R_SERIAL1_STATUS__framing_err__yes 1
+#define R_SERIAL1_STATUS__data_avail__BITNR 0
+#define R_SERIAL1_STATUS__data_avail__WIDTH 1
+#define R_SERIAL1_STATUS__data_avail__no 0
+#define R_SERIAL1_STATUS__data_avail__yes 1
+
+#define R_SERIAL1_REC_DATA (IO_TYPECAST_RO_BYTE 0xb0000068)
+#define R_SERIAL1_REC_DATA__data_in__BITNR 0
+#define R_SERIAL1_REC_DATA__data_in__WIDTH 8
+
+#define R_SERIAL1_XOFF (IO_TYPECAST_UDWORD 0xb000006c)
+#define R_SERIAL1_XOFF__tx_stop__BITNR 9
+#define R_SERIAL1_XOFF__tx_stop__WIDTH 1
+#define R_SERIAL1_XOFF__tx_stop__enable 0
+#define R_SERIAL1_XOFF__tx_stop__stop 1
+#define R_SERIAL1_XOFF__auto_xoff__BITNR 8
+#define R_SERIAL1_XOFF__auto_xoff__WIDTH 1
+#define R_SERIAL1_XOFF__auto_xoff__disable 0
+#define R_SERIAL1_XOFF__auto_xoff__enable 1
+#define R_SERIAL1_XOFF__xoff_char__BITNR 0
+#define R_SERIAL1_XOFF__xoff_char__WIDTH 8
+
+#define R_SERIAL2_CTRL (IO_TYPECAST_UDWORD 0xb0000070)
+#define R_SERIAL2_CTRL__tr_baud__BITNR 28
+#define R_SERIAL2_CTRL__tr_baud__WIDTH 4
+#define R_SERIAL2_CTRL__tr_baud__c300Hz 0
+#define R_SERIAL2_CTRL__tr_baud__c600Hz 1
+#define R_SERIAL2_CTRL__tr_baud__c1200Hz 2
+#define R_SERIAL2_CTRL__tr_baud__c2400Hz 3
+#define R_SERIAL2_CTRL__tr_baud__c4800Hz 4
+#define R_SERIAL2_CTRL__tr_baud__c9600Hz 5
+#define R_SERIAL2_CTRL__tr_baud__c19k2Hz 6
+#define R_SERIAL2_CTRL__tr_baud__c38k4Hz 7
+#define R_SERIAL2_CTRL__tr_baud__c57k6Hz 8
+#define R_SERIAL2_CTRL__tr_baud__c115k2Hz 9
+#define R_SERIAL2_CTRL__tr_baud__c230k4Hz 10
+#define R_SERIAL2_CTRL__tr_baud__c460k8Hz 11
+#define R_SERIAL2_CTRL__tr_baud__c921k6Hz 12
+#define R_SERIAL2_CTRL__tr_baud__c1843k2Hz 13
+#define R_SERIAL2_CTRL__tr_baud__c6250kHz 14
+#define R_SERIAL2_CTRL__tr_baud__reserved 15
+#define R_SERIAL2_CTRL__rec_baud__BITNR 24
+#define R_SERIAL2_CTRL__rec_baud__WIDTH 4
+#define R_SERIAL2_CTRL__rec_baud__c300Hz 0
+#define R_SERIAL2_CTRL__rec_baud__c600Hz 1
+#define R_SERIAL2_CTRL__rec_baud__c1200Hz 2
+#define R_SERIAL2_CTRL__rec_baud__c2400Hz 3
+#define R_SERIAL2_CTRL__rec_baud__c4800Hz 4
+#define R_SERIAL2_CTRL__rec_baud__c9600Hz 5
+#define R_SERIAL2_CTRL__rec_baud__c19k2Hz 6
+#define R_SERIAL2_CTRL__rec_baud__c38k4Hz 7
+#define R_SERIAL2_CTRL__rec_baud__c57k6Hz 8
+#define R_SERIAL2_CTRL__rec_baud__c115k2Hz 9
+#define R_SERIAL2_CTRL__rec_baud__c230k4Hz 10
+#define R_SERIAL2_CTRL__rec_baud__c460k8Hz 11
+#define R_SERIAL2_CTRL__rec_baud__c921k6Hz 12
+#define R_SERIAL2_CTRL__rec_baud__c1843k2Hz 13
+#define R_SERIAL2_CTRL__rec_baud__c6250kHz 14
+#define R_SERIAL2_CTRL__rec_baud__reserved 15
+#define R_SERIAL2_CTRL__dma_err__BITNR 23
+#define R_SERIAL2_CTRL__dma_err__WIDTH 1
+#define R_SERIAL2_CTRL__dma_err__stop 0
+#define R_SERIAL2_CTRL__dma_err__ignore 1
+#define R_SERIAL2_CTRL__rec_enable__BITNR 22
+#define R_SERIAL2_CTRL__rec_enable__WIDTH 1
+#define R_SERIAL2_CTRL__rec_enable__disable 0
+#define R_SERIAL2_CTRL__rec_enable__enable 1
+#define R_SERIAL2_CTRL__rts___BITNR 21
+#define R_SERIAL2_CTRL__rts___WIDTH 1
+#define R_SERIAL2_CTRL__rts___active 0
+#define R_SERIAL2_CTRL__rts___inactive 1
+#define R_SERIAL2_CTRL__sampling__BITNR 20
+#define R_SERIAL2_CTRL__sampling__WIDTH 1
+#define R_SERIAL2_CTRL__sampling__middle 0
+#define R_SERIAL2_CTRL__sampling__majority 1
+#define R_SERIAL2_CTRL__rec_stick_par__BITNR 19
+#define R_SERIAL2_CTRL__rec_stick_par__WIDTH 1
+#define R_SERIAL2_CTRL__rec_stick_par__normal 0
+#define R_SERIAL2_CTRL__rec_stick_par__stick 1
+#define R_SERIAL2_CTRL__rec_par__BITNR 18
+#define R_SERIAL2_CTRL__rec_par__WIDTH 1
+#define R_SERIAL2_CTRL__rec_par__even 0
+#define R_SERIAL2_CTRL__rec_par__odd 1
+#define R_SERIAL2_CTRL__rec_par_en__BITNR 17
+#define R_SERIAL2_CTRL__rec_par_en__WIDTH 1
+#define R_SERIAL2_CTRL__rec_par_en__disable 0
+#define R_SERIAL2_CTRL__rec_par_en__enable 1
+#define R_SERIAL2_CTRL__rec_bitnr__BITNR 16
+#define R_SERIAL2_CTRL__rec_bitnr__WIDTH 1
+#define R_SERIAL2_CTRL__rec_bitnr__rec_8bit 0
+#define R_SERIAL2_CTRL__rec_bitnr__rec_7bit 1
+#define R_SERIAL2_CTRL__txd__BITNR 15
+#define R_SERIAL2_CTRL__txd__WIDTH 1
+#define R_SERIAL2_CTRL__tr_enable__BITNR 14
+#define R_SERIAL2_CTRL__tr_enable__WIDTH 1
+#define R_SERIAL2_CTRL__tr_enable__disable 0
+#define R_SERIAL2_CTRL__tr_enable__enable 1
+#define R_SERIAL2_CTRL__auto_cts__BITNR 13
+#define R_SERIAL2_CTRL__auto_cts__WIDTH 1
+#define R_SERIAL2_CTRL__auto_cts__disabled 0
+#define R_SERIAL2_CTRL__auto_cts__active 1
+#define R_SERIAL2_CTRL__stop_bits__BITNR 12
+#define R_SERIAL2_CTRL__stop_bits__WIDTH 1
+#define R_SERIAL2_CTRL__stop_bits__one_bit 0
+#define R_SERIAL2_CTRL__stop_bits__two_bits 1
+#define R_SERIAL2_CTRL__tr_stick_par__BITNR 11
+#define R_SERIAL2_CTRL__tr_stick_par__WIDTH 1
+#define R_SERIAL2_CTRL__tr_stick_par__normal 0
+#define R_SERIAL2_CTRL__tr_stick_par__stick 1
+#define R_SERIAL2_CTRL__tr_par__BITNR 10
+#define R_SERIAL2_CTRL__tr_par__WIDTH 1
+#define R_SERIAL2_CTRL__tr_par__even 0
+#define R_SERIAL2_CTRL__tr_par__odd 1
+#define R_SERIAL2_CTRL__tr_par_en__BITNR 9
+#define R_SERIAL2_CTRL__tr_par_en__WIDTH 1
+#define R_SERIAL2_CTRL__tr_par_en__disable 0
+#define R_SERIAL2_CTRL__tr_par_en__enable 1
+#define R_SERIAL2_CTRL__tr_bitnr__BITNR 8
+#define R_SERIAL2_CTRL__tr_bitnr__WIDTH 1
+#define R_SERIAL2_CTRL__tr_bitnr__tr_8bit 0
+#define R_SERIAL2_CTRL__tr_bitnr__tr_7bit 1
+#define R_SERIAL2_CTRL__data_out__BITNR 0
+#define R_SERIAL2_CTRL__data_out__WIDTH 8
+
+#define R_SERIAL2_BAUD (IO_TYPECAST_BYTE 0xb0000073)
+#define R_SERIAL2_BAUD__tr_baud__BITNR 4
+#define R_SERIAL2_BAUD__tr_baud__WIDTH 4
+#define R_SERIAL2_BAUD__tr_baud__c300Hz 0
+#define R_SERIAL2_BAUD__tr_baud__c600Hz 1
+#define R_SERIAL2_BAUD__tr_baud__c1200Hz 2
+#define R_SERIAL2_BAUD__tr_baud__c2400Hz 3
+#define R_SERIAL2_BAUD__tr_baud__c4800Hz 4
+#define R_SERIAL2_BAUD__tr_baud__c9600Hz 5
+#define R_SERIAL2_BAUD__tr_baud__c19k2Hz 6
+#define R_SERIAL2_BAUD__tr_baud__c38k4Hz 7
+#define R_SERIAL2_BAUD__tr_baud__c57k6Hz 8
+#define R_SERIAL2_BAUD__tr_baud__c115k2Hz 9
+#define R_SERIAL2_BAUD__tr_baud__c230k4Hz 10
+#define R_SERIAL2_BAUD__tr_baud__c460k8Hz 11
+#define R_SERIAL2_BAUD__tr_baud__c921k6Hz 12
+#define R_SERIAL2_BAUD__tr_baud__c1843k2Hz 13
+#define R_SERIAL2_BAUD__tr_baud__c6250kHz 14
+#define R_SERIAL2_BAUD__tr_baud__reserved 15
+#define R_SERIAL2_BAUD__rec_baud__BITNR 0
+#define R_SERIAL2_BAUD__rec_baud__WIDTH 4
+#define R_SERIAL2_BAUD__rec_baud__c300Hz 0
+#define R_SERIAL2_BAUD__rec_baud__c600Hz 1
+#define R_SERIAL2_BAUD__rec_baud__c1200Hz 2
+#define R_SERIAL2_BAUD__rec_baud__c2400Hz 3
+#define R_SERIAL2_BAUD__rec_baud__c4800Hz 4
+#define R_SERIAL2_BAUD__rec_baud__c9600Hz 5
+#define R_SERIAL2_BAUD__rec_baud__c19k2Hz 6
+#define R_SERIAL2_BAUD__rec_baud__c38k4Hz 7
+#define R_SERIAL2_BAUD__rec_baud__c57k6Hz 8
+#define R_SERIAL2_BAUD__rec_baud__c115k2Hz 9
+#define R_SERIAL2_BAUD__rec_baud__c230k4Hz 10
+#define R_SERIAL2_BAUD__rec_baud__c460k8Hz 11
+#define R_SERIAL2_BAUD__rec_baud__c921k6Hz 12
+#define R_SERIAL2_BAUD__rec_baud__c1843k2Hz 13
+#define R_SERIAL2_BAUD__rec_baud__c6250kHz 14
+#define R_SERIAL2_BAUD__rec_baud__reserved 15
+
+#define R_SERIAL2_REC_CTRL (IO_TYPECAST_BYTE 0xb0000072)
+#define R_SERIAL2_REC_CTRL__dma_err__BITNR 7
+#define R_SERIAL2_REC_CTRL__dma_err__WIDTH 1
+#define R_SERIAL2_REC_CTRL__dma_err__stop 0
+#define R_SERIAL2_REC_CTRL__dma_err__ignore 1
+#define R_SERIAL2_REC_CTRL__rec_enable__BITNR 6
+#define R_SERIAL2_REC_CTRL__rec_enable__WIDTH 1
+#define R_SERIAL2_REC_CTRL__rec_enable__disable 0
+#define R_SERIAL2_REC_CTRL__rec_enable__enable 1
+#define R_SERIAL2_REC_CTRL__rts___BITNR 5
+#define R_SERIAL2_REC_CTRL__rts___WIDTH 1
+#define R_SERIAL2_REC_CTRL__rts___active 0
+#define R_SERIAL2_REC_CTRL__rts___inactive 1
+#define R_SERIAL2_REC_CTRL__sampling__BITNR 4
+#define R_SERIAL2_REC_CTRL__sampling__WIDTH 1
+#define R_SERIAL2_REC_CTRL__sampling__middle 0
+#define R_SERIAL2_REC_CTRL__sampling__majority 1
+#define R_SERIAL2_REC_CTRL__rec_stick_par__BITNR 3
+#define R_SERIAL2_REC_CTRL__rec_stick_par__WIDTH 1
+#define R_SERIAL2_REC_CTRL__rec_stick_par__normal 0
+#define R_SERIAL2_REC_CTRL__rec_stick_par__stick 1
+#define R_SERIAL2_REC_CTRL__rec_par__BITNR 2
+#define R_SERIAL2_REC_CTRL__rec_par__WIDTH 1
+#define R_SERIAL2_REC_CTRL__rec_par__even 0
+#define R_SERIAL2_REC_CTRL__rec_par__odd 1
+#define R_SERIAL2_REC_CTRL__rec_par_en__BITNR 1
+#define R_SERIAL2_REC_CTRL__rec_par_en__WIDTH 1
+#define R_SERIAL2_REC_CTRL__rec_par_en__disable 0
+#define R_SERIAL2_REC_CTRL__rec_par_en__enable 1
+#define R_SERIAL2_REC_CTRL__rec_bitnr__BITNR 0
+#define R_SERIAL2_REC_CTRL__rec_bitnr__WIDTH 1
+#define R_SERIAL2_REC_CTRL__rec_bitnr__rec_8bit 0
+#define R_SERIAL2_REC_CTRL__rec_bitnr__rec_7bit 1
+
+#define R_SERIAL2_TR_CTRL (IO_TYPECAST_BYTE 0xb0000071)
+#define R_SERIAL2_TR_CTRL__txd__BITNR 7
+#define R_SERIAL2_TR_CTRL__txd__WIDTH 1
+#define R_SERIAL2_TR_CTRL__tr_enable__BITNR 6
+#define R_SERIAL2_TR_CTRL__tr_enable__WIDTH 1
+#define R_SERIAL2_TR_CTRL__tr_enable__disable 0
+#define R_SERIAL2_TR_CTRL__tr_enable__enable 1
+#define R_SERIAL2_TR_CTRL__auto_cts__BITNR 5
+#define R_SERIAL2_TR_CTRL__auto_cts__WIDTH 1
+#define R_SERIAL2_TR_CTRL__auto_cts__disabled 0
+#define R_SERIAL2_TR_CTRL__auto_cts__active 1
+#define R_SERIAL2_TR_CTRL__stop_bits__BITNR 4
+#define R_SERIAL2_TR_CTRL__stop_bits__WIDTH 1
+#define R_SERIAL2_TR_CTRL__stop_bits__one_bit 0
+#define R_SERIAL2_TR_CTRL__stop_bits__two_bits 1
+#define R_SERIAL2_TR_CTRL__tr_stick_par__BITNR 3
+#define R_SERIAL2_TR_CTRL__tr_stick_par__WIDTH 1
+#define R_SERIAL2_TR_CTRL__tr_stick_par__normal 0
+#define R_SERIAL2_TR_CTRL__tr_stick_par__stick 1
+#define R_SERIAL2_TR_CTRL__tr_par__BITNR 2
+#define R_SERIAL2_TR_CTRL__tr_par__WIDTH 1
+#define R_SERIAL2_TR_CTRL__tr_par__even 0
+#define R_SERIAL2_TR_CTRL__tr_par__odd 1
+#define R_SERIAL2_TR_CTRL__tr_par_en__BITNR 1
+#define R_SERIAL2_TR_CTRL__tr_par_en__WIDTH 1
+#define R_SERIAL2_TR_CTRL__tr_par_en__disable 0
+#define R_SERIAL2_TR_CTRL__tr_par_en__enable 1
+#define R_SERIAL2_TR_CTRL__tr_bitnr__BITNR 0
+#define R_SERIAL2_TR_CTRL__tr_bitnr__WIDTH 1
+#define R_SERIAL2_TR_CTRL__tr_bitnr__tr_8bit 0
+#define R_SERIAL2_TR_CTRL__tr_bitnr__tr_7bit 1
+
+#define R_SERIAL2_TR_DATA (IO_TYPECAST_BYTE 0xb0000070)
+#define R_SERIAL2_TR_DATA__data_out__BITNR 0
+#define R_SERIAL2_TR_DATA__data_out__WIDTH 8
+
+#define R_SERIAL2_READ (IO_TYPECAST_RO_UDWORD 0xb0000070)
+#define R_SERIAL2_READ__xoff_detect__BITNR 15
+#define R_SERIAL2_READ__xoff_detect__WIDTH 1
+#define R_SERIAL2_READ__xoff_detect__no_xoff 0
+#define R_SERIAL2_READ__xoff_detect__xoff 1
+#define R_SERIAL2_READ__cts___BITNR 14
+#define R_SERIAL2_READ__cts___WIDTH 1
+#define R_SERIAL2_READ__cts___active 0
+#define R_SERIAL2_READ__cts___inactive 1
+#define R_SERIAL2_READ__tr_ready__BITNR 13
+#define R_SERIAL2_READ__tr_ready__WIDTH 1
+#define R_SERIAL2_READ__tr_ready__full 0
+#define R_SERIAL2_READ__tr_ready__ready 1
+#define R_SERIAL2_READ__rxd__BITNR 12
+#define R_SERIAL2_READ__rxd__WIDTH 1
+#define R_SERIAL2_READ__overrun__BITNR 11
+#define R_SERIAL2_READ__overrun__WIDTH 1
+#define R_SERIAL2_READ__overrun__no 0
+#define R_SERIAL2_READ__overrun__yes 1
+#define R_SERIAL2_READ__par_err__BITNR 10
+#define R_SERIAL2_READ__par_err__WIDTH 1
+#define R_SERIAL2_READ__par_err__no 0
+#define R_SERIAL2_READ__par_err__yes 1
+#define R_SERIAL2_READ__framing_err__BITNR 9
+#define R_SERIAL2_READ__framing_err__WIDTH 1
+#define R_SERIAL2_READ__framing_err__no 0
+#define R_SERIAL2_READ__framing_err__yes 1
+#define R_SERIAL2_READ__data_avail__BITNR 8
+#define R_SERIAL2_READ__data_avail__WIDTH 1
+#define R_SERIAL2_READ__data_avail__no 0
+#define R_SERIAL2_READ__data_avail__yes 1
+#define R_SERIAL2_READ__data_in__BITNR 0
+#define R_SERIAL2_READ__data_in__WIDTH 8
+
+#define R_SERIAL2_STATUS (IO_TYPECAST_RO_BYTE 0xb0000071)
+#define R_SERIAL2_STATUS__xoff_detect__BITNR 7
+#define R_SERIAL2_STATUS__xoff_detect__WIDTH 1
+#define R_SERIAL2_STATUS__xoff_detect__no_xoff 0
+#define R_SERIAL2_STATUS__xoff_detect__xoff 1
+#define R_SERIAL2_STATUS__cts___BITNR 6
+#define R_SERIAL2_STATUS__cts___WIDTH 1
+#define R_SERIAL2_STATUS__cts___active 0
+#define R_SERIAL2_STATUS__cts___inactive 1
+#define R_SERIAL2_STATUS__tr_ready__BITNR 5
+#define R_SERIAL2_STATUS__tr_ready__WIDTH 1
+#define R_SERIAL2_STATUS__tr_ready__full 0
+#define R_SERIAL2_STATUS__tr_ready__ready 1
+#define R_SERIAL2_STATUS__rxd__BITNR 4
+#define R_SERIAL2_STATUS__rxd__WIDTH 1
+#define R_SERIAL2_STATUS__overrun__BITNR 3
+#define R_SERIAL2_STATUS__overrun__WIDTH 1
+#define R_SERIAL2_STATUS__overrun__no 0
+#define R_SERIAL2_STATUS__overrun__yes 1
+#define R_SERIAL2_STATUS__par_err__BITNR 2
+#define R_SERIAL2_STATUS__par_err__WIDTH 1
+#define R_SERIAL2_STATUS__par_err__no 0
+#define R_SERIAL2_STATUS__par_err__yes 1
+#define R_SERIAL2_STATUS__framing_err__BITNR 1
+#define R_SERIAL2_STATUS__framing_err__WIDTH 1
+#define R_SERIAL2_STATUS__framing_err__no 0
+#define R_SERIAL2_STATUS__framing_err__yes 1
+#define R_SERIAL2_STATUS__data_avail__BITNR 0
+#define R_SERIAL2_STATUS__data_avail__WIDTH 1
+#define R_SERIAL2_STATUS__data_avail__no 0
+#define R_SERIAL2_STATUS__data_avail__yes 1
+
+#define R_SERIAL2_REC_DATA (IO_TYPECAST_RO_BYTE 0xb0000070)
+#define R_SERIAL2_REC_DATA__data_in__BITNR 0
+#define R_SERIAL2_REC_DATA__data_in__WIDTH 8
+
+#define R_SERIAL2_XOFF (IO_TYPECAST_UDWORD 0xb0000074)
+#define R_SERIAL2_XOFF__tx_stop__BITNR 9
+#define R_SERIAL2_XOFF__tx_stop__WIDTH 1
+#define R_SERIAL2_XOFF__tx_stop__enable 0
+#define R_SERIAL2_XOFF__tx_stop__stop 1
+#define R_SERIAL2_XOFF__auto_xoff__BITNR 8
+#define R_SERIAL2_XOFF__auto_xoff__WIDTH 1
+#define R_SERIAL2_XOFF__auto_xoff__disable 0
+#define R_SERIAL2_XOFF__auto_xoff__enable 1
+#define R_SERIAL2_XOFF__xoff_char__BITNR 0
+#define R_SERIAL2_XOFF__xoff_char__WIDTH 8
+
+#define R_SERIAL3_CTRL (IO_TYPECAST_UDWORD 0xb0000078)
+#define R_SERIAL3_CTRL__tr_baud__BITNR 28
+#define R_SERIAL3_CTRL__tr_baud__WIDTH 4
+#define R_SERIAL3_CTRL__tr_baud__c300Hz 0
+#define R_SERIAL3_CTRL__tr_baud__c600Hz 1
+#define R_SERIAL3_CTRL__tr_baud__c1200Hz 2
+#define R_SERIAL3_CTRL__tr_baud__c2400Hz 3
+#define R_SERIAL3_CTRL__tr_baud__c4800Hz 4
+#define R_SERIAL3_CTRL__tr_baud__c9600Hz 5
+#define R_SERIAL3_CTRL__tr_baud__c19k2Hz 6
+#define R_SERIAL3_CTRL__tr_baud__c38k4Hz 7
+#define R_SERIAL3_CTRL__tr_baud__c57k6Hz 8
+#define R_SERIAL3_CTRL__tr_baud__c115k2Hz 9
+#define R_SERIAL3_CTRL__tr_baud__c230k4Hz 10
+#define R_SERIAL3_CTRL__tr_baud__c460k8Hz 11
+#define R_SERIAL3_CTRL__tr_baud__c921k6Hz 12
+#define R_SERIAL3_CTRL__tr_baud__c1843k2Hz 13
+#define R_SERIAL3_CTRL__tr_baud__c6250kHz 14
+#define R_SERIAL3_CTRL__tr_baud__reserved 15
+#define R_SERIAL3_CTRL__rec_baud__BITNR 24
+#define R_SERIAL3_CTRL__rec_baud__WIDTH 4
+#define R_SERIAL3_CTRL__rec_baud__c300Hz 0
+#define R_SERIAL3_CTRL__rec_baud__c600Hz 1
+#define R_SERIAL3_CTRL__rec_baud__c1200Hz 2
+#define R_SERIAL3_CTRL__rec_baud__c2400Hz 3
+#define R_SERIAL3_CTRL__rec_baud__c4800Hz 4
+#define R_SERIAL3_CTRL__rec_baud__c9600Hz 5
+#define R_SERIAL3_CTRL__rec_baud__c19k2Hz 6
+#define R_SERIAL3_CTRL__rec_baud__c38k4Hz 7
+#define R_SERIAL3_CTRL__rec_baud__c57k6Hz 8
+#define R_SERIAL3_CTRL__rec_baud__c115k2Hz 9
+#define R_SERIAL3_CTRL__rec_baud__c230k4Hz 10
+#define R_SERIAL3_CTRL__rec_baud__c460k8Hz 11
+#define R_SERIAL3_CTRL__rec_baud__c921k6Hz 12
+#define R_SERIAL3_CTRL__rec_baud__c1843k2Hz 13
+#define R_SERIAL3_CTRL__rec_baud__c6250kHz 14
+#define R_SERIAL3_CTRL__rec_baud__reserved 15
+#define R_SERIAL3_CTRL__dma_err__BITNR 23
+#define R_SERIAL3_CTRL__dma_err__WIDTH 1
+#define R_SERIAL3_CTRL__dma_err__stop 0
+#define R_SERIAL3_CTRL__dma_err__ignore 1
+#define R_SERIAL3_CTRL__rec_enable__BITNR 22
+#define R_SERIAL3_CTRL__rec_enable__WIDTH 1
+#define R_SERIAL3_CTRL__rec_enable__disable 0
+#define R_SERIAL3_CTRL__rec_enable__enable 1
+#define R_SERIAL3_CTRL__rts___BITNR 21
+#define R_SERIAL3_CTRL__rts___WIDTH 1
+#define R_SERIAL3_CTRL__rts___active 0
+#define R_SERIAL3_CTRL__rts___inactive 1
+#define R_SERIAL3_CTRL__sampling__BITNR 20
+#define R_SERIAL3_CTRL__sampling__WIDTH 1
+#define R_SERIAL3_CTRL__sampling__middle 0
+#define R_SERIAL3_CTRL__sampling__majority 1
+#define R_SERIAL3_CTRL__rec_stick_par__BITNR 19
+#define R_SERIAL3_CTRL__rec_stick_par__WIDTH 1
+#define R_SERIAL3_CTRL__rec_stick_par__normal 0
+#define R_SERIAL3_CTRL__rec_stick_par__stick 1
+#define R_SERIAL3_CTRL__rec_par__BITNR 18
+#define R_SERIAL3_CTRL__rec_par__WIDTH 1
+#define R_SERIAL3_CTRL__rec_par__even 0
+#define R_SERIAL3_CTRL__rec_par__odd 1
+#define R_SERIAL3_CTRL__rec_par_en__BITNR 17
+#define R_SERIAL3_CTRL__rec_par_en__WIDTH 1
+#define R_SERIAL3_CTRL__rec_par_en__disable 0
+#define R_SERIAL3_CTRL__rec_par_en__enable 1
+#define R_SERIAL3_CTRL__rec_bitnr__BITNR 16
+#define R_SERIAL3_CTRL__rec_bitnr__WIDTH 1
+#define R_SERIAL3_CTRL__rec_bitnr__rec_8bit 0
+#define R_SERIAL3_CTRL__rec_bitnr__rec_7bit 1
+#define R_SERIAL3_CTRL__txd__BITNR 15
+#define R_SERIAL3_CTRL__txd__WIDTH 1
+#define R_SERIAL3_CTRL__tr_enable__BITNR 14
+#define R_SERIAL3_CTRL__tr_enable__WIDTH 1
+#define R_SERIAL3_CTRL__tr_enable__disable 0
+#define R_SERIAL3_CTRL__tr_enable__enable 1
+#define R_SERIAL3_CTRL__auto_cts__BITNR 13
+#define R_SERIAL3_CTRL__auto_cts__WIDTH 1
+#define R_SERIAL3_CTRL__auto_cts__disabled 0
+#define R_SERIAL3_CTRL__auto_cts__active 1
+#define R_SERIAL3_CTRL__stop_bits__BITNR 12
+#define R_SERIAL3_CTRL__stop_bits__WIDTH 1
+#define R_SERIAL3_CTRL__stop_bits__one_bit 0
+#define R_SERIAL3_CTRL__stop_bits__two_bits 1
+#define R_SERIAL3_CTRL__tr_stick_par__BITNR 11
+#define R_SERIAL3_CTRL__tr_stick_par__WIDTH 1
+#define R_SERIAL3_CTRL__tr_stick_par__normal 0
+#define R_SERIAL3_CTRL__tr_stick_par__stick 1
+#define R_SERIAL3_CTRL__tr_par__BITNR 10
+#define R_SERIAL3_CTRL__tr_par__WIDTH 1
+#define R_SERIAL3_CTRL__tr_par__even 0
+#define R_SERIAL3_CTRL__tr_par__odd 1
+#define R_SERIAL3_CTRL__tr_par_en__BITNR 9
+#define R_SERIAL3_CTRL__tr_par_en__WIDTH 1
+#define R_SERIAL3_CTRL__tr_par_en__disable 0
+#define R_SERIAL3_CTRL__tr_par_en__enable 1
+#define R_SERIAL3_CTRL__tr_bitnr__BITNR 8
+#define R_SERIAL3_CTRL__tr_bitnr__WIDTH 1
+#define R_SERIAL3_CTRL__tr_bitnr__tr_8bit 0
+#define R_SERIAL3_CTRL__tr_bitnr__tr_7bit 1
+#define R_SERIAL3_CTRL__data_out__BITNR 0
+#define R_SERIAL3_CTRL__data_out__WIDTH 8
+
+#define R_SERIAL3_BAUD (IO_TYPECAST_BYTE 0xb000007b)
+#define R_SERIAL3_BAUD__tr_baud__BITNR 4
+#define R_SERIAL3_BAUD__tr_baud__WIDTH 4
+#define R_SERIAL3_BAUD__tr_baud__c300Hz 0
+#define R_SERIAL3_BAUD__tr_baud__c600Hz 1
+#define R_SERIAL3_BAUD__tr_baud__c1200Hz 2
+#define R_SERIAL3_BAUD__tr_baud__c2400Hz 3
+#define R_SERIAL3_BAUD__tr_baud__c4800Hz 4
+#define R_SERIAL3_BAUD__tr_baud__c9600Hz 5
+#define R_SERIAL3_BAUD__tr_baud__c19k2Hz 6
+#define R_SERIAL3_BAUD__tr_baud__c38k4Hz 7
+#define R_SERIAL3_BAUD__tr_baud__c57k6Hz 8
+#define R_SERIAL3_BAUD__tr_baud__c115k2Hz 9
+#define R_SERIAL3_BAUD__tr_baud__c230k4Hz 10
+#define R_SERIAL3_BAUD__tr_baud__c460k8Hz 11
+#define R_SERIAL3_BAUD__tr_baud__c921k6Hz 12
+#define R_SERIAL3_BAUD__tr_baud__c1843k2Hz 13
+#define R_SERIAL3_BAUD__tr_baud__c6250kHz 14
+#define R_SERIAL3_BAUD__tr_baud__reserved 15
+#define R_SERIAL3_BAUD__rec_baud__BITNR 0
+#define R_SERIAL3_BAUD__rec_baud__WIDTH 4
+#define R_SERIAL3_BAUD__rec_baud__c300Hz 0
+#define R_SERIAL3_BAUD__rec_baud__c600Hz 1
+#define R_SERIAL3_BAUD__rec_baud__c1200Hz 2
+#define R_SERIAL3_BAUD__rec_baud__c2400Hz 3
+#define R_SERIAL3_BAUD__rec_baud__c4800Hz 4
+#define R_SERIAL3_BAUD__rec_baud__c9600Hz 5
+#define R_SERIAL3_BAUD__rec_baud__c19k2Hz 6
+#define R_SERIAL3_BAUD__rec_baud__c38k4Hz 7
+#define R_SERIAL3_BAUD__rec_baud__c57k6Hz 8
+#define R_SERIAL3_BAUD__rec_baud__c115k2Hz 9
+#define R_SERIAL3_BAUD__rec_baud__c230k4Hz 10
+#define R_SERIAL3_BAUD__rec_baud__c460k8Hz 11
+#define R_SERIAL3_BAUD__rec_baud__c921k6Hz 12
+#define R_SERIAL3_BAUD__rec_baud__c1843k2Hz 13
+#define R_SERIAL3_BAUD__rec_baud__c6250kHz 14
+#define R_SERIAL3_BAUD__rec_baud__reserved 15
+
+#define R_SERIAL3_REC_CTRL (IO_TYPECAST_BYTE 0xb000007a)
+#define R_SERIAL3_REC_CTRL__dma_err__BITNR 7
+#define R_SERIAL3_REC_CTRL__dma_err__WIDTH 1
+#define R_SERIAL3_REC_CTRL__dma_err__stop 0
+#define R_SERIAL3_REC_CTRL__dma_err__ignore 1
+#define R_SERIAL3_REC_CTRL__rec_enable__BITNR 6
+#define R_SERIAL3_REC_CTRL__rec_enable__WIDTH 1
+#define R_SERIAL3_REC_CTRL__rec_enable__disable 0
+#define R_SERIAL3_REC_CTRL__rec_enable__enable 1
+#define R_SERIAL3_REC_CTRL__rts___BITNR 5
+#define R_SERIAL3_REC_CTRL__rts___WIDTH 1
+#define R_SERIAL3_REC_CTRL__rts___active 0
+#define R_SERIAL3_REC_CTRL__rts___inactive 1
+#define R_SERIAL3_REC_CTRL__sampling__BITNR 4
+#define R_SERIAL3_REC_CTRL__sampling__WIDTH 1
+#define R_SERIAL3_REC_CTRL__sampling__middle 0
+#define R_SERIAL3_REC_CTRL__sampling__majority 1
+#define R_SERIAL3_REC_CTRL__rec_stick_par__BITNR 3
+#define R_SERIAL3_REC_CTRL__rec_stick_par__WIDTH 1
+#define R_SERIAL3_REC_CTRL__rec_stick_par__normal 0
+#define R_SERIAL3_REC_CTRL__rec_stick_par__stick 1
+#define R_SERIAL3_REC_CTRL__rec_par__BITNR 2
+#define R_SERIAL3_REC_CTRL__rec_par__WIDTH 1
+#define R_SERIAL3_REC_CTRL__rec_par__even 0
+#define R_SERIAL3_REC_CTRL__rec_par__odd 1
+#define R_SERIAL3_REC_CTRL__rec_par_en__BITNR 1
+#define R_SERIAL3_REC_CTRL__rec_par_en__WIDTH 1
+#define R_SERIAL3_REC_CTRL__rec_par_en__disable 0
+#define R_SERIAL3_REC_CTRL__rec_par_en__enable 1
+#define R_SERIAL3_REC_CTRL__rec_bitnr__BITNR 0
+#define R_SERIAL3_REC_CTRL__rec_bitnr__WIDTH 1
+#define R_SERIAL3_REC_CTRL__rec_bitnr__rec_8bit 0
+#define R_SERIAL3_REC_CTRL__rec_bitnr__rec_7bit 1
+
+#define R_SERIAL3_TR_CTRL (IO_TYPECAST_BYTE 0xb0000079)
+#define R_SERIAL3_TR_CTRL__txd__BITNR 7
+#define R_SERIAL3_TR_CTRL__txd__WIDTH 1
+#define R_SERIAL3_TR_CTRL__tr_enable__BITNR 6
+#define R_SERIAL3_TR_CTRL__tr_enable__WIDTH 1
+#define R_SERIAL3_TR_CTRL__tr_enable__disable 0
+#define R_SERIAL3_TR_CTRL__tr_enable__enable 1
+#define R_SERIAL3_TR_CTRL__auto_cts__BITNR 5
+#define R_SERIAL3_TR_CTRL__auto_cts__WIDTH 1
+#define R_SERIAL3_TR_CTRL__auto_cts__disabled 0
+#define R_SERIAL3_TR_CTRL__auto_cts__active 1
+#define R_SERIAL3_TR_CTRL__stop_bits__BITNR 4
+#define R_SERIAL3_TR_CTRL__stop_bits__WIDTH 1
+#define R_SERIAL3_TR_CTRL__stop_bits__one_bit 0
+#define R_SERIAL3_TR_CTRL__stop_bits__two_bits 1
+#define R_SERIAL3_TR_CTRL__tr_stick_par__BITNR 3
+#define R_SERIAL3_TR_CTRL__tr_stick_par__WIDTH 1
+#define R_SERIAL3_TR_CTRL__tr_stick_par__normal 0
+#define R_SERIAL3_TR_CTRL__tr_stick_par__stick 1
+#define R_SERIAL3_TR_CTRL__tr_par__BITNR 2
+#define R_SERIAL3_TR_CTRL__tr_par__WIDTH 1
+#define R_SERIAL3_TR_CTRL__tr_par__even 0
+#define R_SERIAL3_TR_CTRL__tr_par__odd 1
+#define R_SERIAL3_TR_CTRL__tr_par_en__BITNR 1
+#define R_SERIAL3_TR_CTRL__tr_par_en__WIDTH 1
+#define R_SERIAL3_TR_CTRL__tr_par_en__disable 0
+#define R_SERIAL3_TR_CTRL__tr_par_en__enable 1
+#define R_SERIAL3_TR_CTRL__tr_bitnr__BITNR 0
+#define R_SERIAL3_TR_CTRL__tr_bitnr__WIDTH 1
+#define R_SERIAL3_TR_CTRL__tr_bitnr__tr_8bit 0
+#define R_SERIAL3_TR_CTRL__tr_bitnr__tr_7bit 1
+
+#define R_SERIAL3_TR_DATA (IO_TYPECAST_BYTE 0xb0000078)
+#define R_SERIAL3_TR_DATA__data_out__BITNR 0
+#define R_SERIAL3_TR_DATA__data_out__WIDTH 8
+
+#define R_SERIAL3_READ (IO_TYPECAST_RO_UDWORD 0xb0000078)
+#define R_SERIAL3_READ__xoff_detect__BITNR 15
+#define R_SERIAL3_READ__xoff_detect__WIDTH 1
+#define R_SERIAL3_READ__xoff_detect__no_xoff 0
+#define R_SERIAL3_READ__xoff_detect__xoff 1
+#define R_SERIAL3_READ__cts___BITNR 14
+#define R_SERIAL3_READ__cts___WIDTH 1
+#define R_SERIAL3_READ__cts___active 0
+#define R_SERIAL3_READ__cts___inactive 1
+#define R_SERIAL3_READ__tr_ready__BITNR 13
+#define R_SERIAL3_READ__tr_ready__WIDTH 1
+#define R_SERIAL3_READ__tr_ready__full 0
+#define R_SERIAL3_READ__tr_ready__ready 1
+#define R_SERIAL3_READ__rxd__BITNR 12
+#define R_SERIAL3_READ__rxd__WIDTH 1
+#define R_SERIAL3_READ__overrun__BITNR 11
+#define R_SERIAL3_READ__overrun__WIDTH 1
+#define R_SERIAL3_READ__overrun__no 0
+#define R_SERIAL3_READ__overrun__yes 1
+#define R_SERIAL3_READ__par_err__BITNR 10
+#define R_SERIAL3_READ__par_err__WIDTH 1
+#define R_SERIAL3_READ__par_err__no 0
+#define R_SERIAL3_READ__par_err__yes 1
+#define R_SERIAL3_READ__framing_err__BITNR 9
+#define R_SERIAL3_READ__framing_err__WIDTH 1
+#define R_SERIAL3_READ__framing_err__no 0
+#define R_SERIAL3_READ__framing_err__yes 1
+#define R_SERIAL3_READ__data_avail__BITNR 8
+#define R_SERIAL3_READ__data_avail__WIDTH 1
+#define R_SERIAL3_READ__data_avail__no 0
+#define R_SERIAL3_READ__data_avail__yes 1
+#define R_SERIAL3_READ__data_in__BITNR 0
+#define R_SERIAL3_READ__data_in__WIDTH 8
+
+#define R_SERIAL3_STATUS (IO_TYPECAST_RO_BYTE 0xb0000079)
+#define R_SERIAL3_STATUS__xoff_detect__BITNR 7
+#define R_SERIAL3_STATUS__xoff_detect__WIDTH 1
+#define R_SERIAL3_STATUS__xoff_detect__no_xoff 0
+#define R_SERIAL3_STATUS__xoff_detect__xoff 1
+#define R_SERIAL3_STATUS__cts___BITNR 6
+#define R_SERIAL3_STATUS__cts___WIDTH 1
+#define R_SERIAL3_STATUS__cts___active 0
+#define R_SERIAL3_STATUS__cts___inactive 1
+#define R_SERIAL3_STATUS__tr_ready__BITNR 5
+#define R_SERIAL3_STATUS__tr_ready__WIDTH 1
+#define R_SERIAL3_STATUS__tr_ready__full 0
+#define R_SERIAL3_STATUS__tr_ready__ready 1
+#define R_SERIAL3_STATUS__rxd__BITNR 4
+#define R_SERIAL3_STATUS__rxd__WIDTH 1
+#define R_SERIAL3_STATUS__overrun__BITNR 3
+#define R_SERIAL3_STATUS__overrun__WIDTH 1
+#define R_SERIAL3_STATUS__overrun__no 0
+#define R_SERIAL3_STATUS__overrun__yes 1
+#define R_SERIAL3_STATUS__par_err__BITNR 2
+#define R_SERIAL3_STATUS__par_err__WIDTH 1
+#define R_SERIAL3_STATUS__par_err__no 0
+#define R_SERIAL3_STATUS__par_err__yes 1
+#define R_SERIAL3_STATUS__framing_err__BITNR 1
+#define R_SERIAL3_STATUS__framing_err__WIDTH 1
+#define R_SERIAL3_STATUS__framing_err__no 0
+#define R_SERIAL3_STATUS__framing_err__yes 1
+#define R_SERIAL3_STATUS__data_avail__BITNR 0
+#define R_SERIAL3_STATUS__data_avail__WIDTH 1
+#define R_SERIAL3_STATUS__data_avail__no 0
+#define R_SERIAL3_STATUS__data_avail__yes 1
+
+#define R_SERIAL3_REC_DATA (IO_TYPECAST_RO_BYTE 0xb0000078)
+#define R_SERIAL3_REC_DATA__data_in__BITNR 0
+#define R_SERIAL3_REC_DATA__data_in__WIDTH 8
+
+#define R_SERIAL3_XOFF (IO_TYPECAST_UDWORD 0xb000007c)
+#define R_SERIAL3_XOFF__tx_stop__BITNR 9
+#define R_SERIAL3_XOFF__tx_stop__WIDTH 1
+#define R_SERIAL3_XOFF__tx_stop__enable 0
+#define R_SERIAL3_XOFF__tx_stop__stop 1
+#define R_SERIAL3_XOFF__auto_xoff__BITNR 8
+#define R_SERIAL3_XOFF__auto_xoff__WIDTH 1
+#define R_SERIAL3_XOFF__auto_xoff__disable 0
+#define R_SERIAL3_XOFF__auto_xoff__enable 1
+#define R_SERIAL3_XOFF__xoff_char__BITNR 0
+#define R_SERIAL3_XOFF__xoff_char__WIDTH 8
+
+#define R_ALT_SER_BAUDRATE (IO_TYPECAST_UDWORD 0xb000005c)
+#define R_ALT_SER_BAUDRATE__ser3_tr__BITNR 28
+#define R_ALT_SER_BAUDRATE__ser3_tr__WIDTH 2
+#define R_ALT_SER_BAUDRATE__ser3_tr__normal 0
+#define R_ALT_SER_BAUDRATE__ser3_tr__prescale 1
+#define R_ALT_SER_BAUDRATE__ser3_tr__extern 2
+#define R_ALT_SER_BAUDRATE__ser3_tr__timer 3
+#define R_ALT_SER_BAUDRATE__ser3_rec__BITNR 24
+#define R_ALT_SER_BAUDRATE__ser3_rec__WIDTH 2
+#define R_ALT_SER_BAUDRATE__ser3_rec__normal 0
+#define R_ALT_SER_BAUDRATE__ser3_rec__prescale 1
+#define R_ALT_SER_BAUDRATE__ser3_rec__extern 2
+#define R_ALT_SER_BAUDRATE__ser3_rec__timer 3
+#define R_ALT_SER_BAUDRATE__ser2_tr__BITNR 20
+#define R_ALT_SER_BAUDRATE__ser2_tr__WIDTH 2
+#define R_ALT_SER_BAUDRATE__ser2_tr__normal 0
+#define R_ALT_SER_BAUDRATE__ser2_tr__prescale 1
+#define R_ALT_SER_BAUDRATE__ser2_tr__extern 2
+#define R_ALT_SER_BAUDRATE__ser2_tr__timer 3
+#define R_ALT_SER_BAUDRATE__ser2_rec__BITNR 16
+#define R_ALT_SER_BAUDRATE__ser2_rec__WIDTH 2
+#define R_ALT_SER_BAUDRATE__ser2_rec__normal 0
+#define R_ALT_SER_BAUDRATE__ser2_rec__prescale 1
+#define R_ALT_SER_BAUDRATE__ser2_rec__extern 2
+#define R_ALT_SER_BAUDRATE__ser2_rec__timer 3
+#define R_ALT_SER_BAUDRATE__ser1_tr__BITNR 12
+#define R_ALT_SER_BAUDRATE__ser1_tr__WIDTH 2
+#define R_ALT_SER_BAUDRATE__ser1_tr__normal 0
+#define R_ALT_SER_BAUDRATE__ser1_tr__prescale 1
+#define R_ALT_SER_BAUDRATE__ser1_tr__extern 2
+#define R_ALT_SER_BAUDRATE__ser1_tr__timer 3
+#define R_ALT_SER_BAUDRATE__ser1_rec__BITNR 8
+#define R_ALT_SER_BAUDRATE__ser1_rec__WIDTH 2
+#define R_ALT_SER_BAUDRATE__ser1_rec__normal 0
+#define R_ALT_SER_BAUDRATE__ser1_rec__prescale 1
+#define R_ALT_SER_BAUDRATE__ser1_rec__extern 2
+#define R_ALT_SER_BAUDRATE__ser1_rec__timer 3
+#define R_ALT_SER_BAUDRATE__ser0_tr__BITNR 4
+#define R_ALT_SER_BAUDRATE__ser0_tr__WIDTH 2
+#define R_ALT_SER_BAUDRATE__ser0_tr__normal 0
+#define R_ALT_SER_BAUDRATE__ser0_tr__prescale 1
+#define R_ALT_SER_BAUDRATE__ser0_tr__extern 2
+#define R_ALT_SER_BAUDRATE__ser0_tr__timer 3
+#define R_ALT_SER_BAUDRATE__ser0_rec__BITNR 0
+#define R_ALT_SER_BAUDRATE__ser0_rec__WIDTH 2
+#define R_ALT_SER_BAUDRATE__ser0_rec__normal 0
+#define R_ALT_SER_BAUDRATE__ser0_rec__prescale 1
+#define R_ALT_SER_BAUDRATE__ser0_rec__extern 2
+#define R_ALT_SER_BAUDRATE__ser0_rec__timer 3
+
+/*
+!* Network interface registers
+!*/
+
+#define R_NETWORK_SA_0 (IO_TYPECAST_UDWORD 0xb0000080)
+#define R_NETWORK_SA_0__ma0_low__BITNR 0
+#define R_NETWORK_SA_0__ma0_low__WIDTH 32
+
+#define R_NETWORK_SA_1 (IO_TYPECAST_UDWORD 0xb0000084)
+#define R_NETWORK_SA_1__ma1_low__BITNR 16
+#define R_NETWORK_SA_1__ma1_low__WIDTH 16
+#define R_NETWORK_SA_1__ma0_high__BITNR 0
+#define R_NETWORK_SA_1__ma0_high__WIDTH 16
+
+#define R_NETWORK_SA_2 (IO_TYPECAST_UDWORD 0xb0000088)
+#define R_NETWORK_SA_2__ma1_high__BITNR 0
+#define R_NETWORK_SA_2__ma1_high__WIDTH 32
+
+#define R_NETWORK_GA_0 (IO_TYPECAST_UDWORD 0xb000008c)
+#define R_NETWORK_GA_0__ga_low__BITNR 0
+#define R_NETWORK_GA_0__ga_low__WIDTH 32
+
+#define R_NETWORK_GA_1 (IO_TYPECAST_UDWORD 0xb0000090)
+#define R_NETWORK_GA_1__ga_high__BITNR 0
+#define R_NETWORK_GA_1__ga_high__WIDTH 32
+
+#define R_NETWORK_REC_CONFIG (IO_TYPECAST_UDWORD 0xb0000094)
+#define R_NETWORK_REC_CONFIG__duplex__BITNR 9
+#define R_NETWORK_REC_CONFIG__duplex__WIDTH 1
+#define R_NETWORK_REC_CONFIG__duplex__full 1
+#define R_NETWORK_REC_CONFIG__duplex__half 0
+#define R_NETWORK_REC_CONFIG__bad_crc__BITNR 8
+#define R_NETWORK_REC_CONFIG__bad_crc__WIDTH 1
+#define R_NETWORK_REC_CONFIG__bad_crc__receive 1
+#define R_NETWORK_REC_CONFIG__bad_crc__discard 0
+#define R_NETWORK_REC_CONFIG__oversize__BITNR 7
+#define R_NETWORK_REC_CONFIG__oversize__WIDTH 1
+#define R_NETWORK_REC_CONFIG__oversize__receive 1
+#define R_NETWORK_REC_CONFIG__oversize__discard 0
+#define R_NETWORK_REC_CONFIG__undersize__BITNR 6
+#define R_NETWORK_REC_CONFIG__undersize__WIDTH 1
+#define R_NETWORK_REC_CONFIG__undersize__receive 1
+#define R_NETWORK_REC_CONFIG__undersize__discard 0
+#define R_NETWORK_REC_CONFIG__all_roots__BITNR 5
+#define R_NETWORK_REC_CONFIG__all_roots__WIDTH 1
+#define R_NETWORK_REC_CONFIG__all_roots__receive 1
+#define R_NETWORK_REC_CONFIG__all_roots__discard 0
+#define R_NETWORK_REC_CONFIG__tr_broadcast__BITNR 4
+#define R_NETWORK_REC_CONFIG__tr_broadcast__WIDTH 1
+#define R_NETWORK_REC_CONFIG__tr_broadcast__receive 1
+#define R_NETWORK_REC_CONFIG__tr_broadcast__discard 0
+#define R_NETWORK_REC_CONFIG__broadcast__BITNR 3
+#define R_NETWORK_REC_CONFIG__broadcast__WIDTH 1
+#define R_NETWORK_REC_CONFIG__broadcast__receive 1
+#define R_NETWORK_REC_CONFIG__broadcast__discard 0
+#define R_NETWORK_REC_CONFIG__individual__BITNR 2
+#define R_NETWORK_REC_CONFIG__individual__WIDTH 1
+#define R_NETWORK_REC_CONFIG__individual__receive 1
+#define R_NETWORK_REC_CONFIG__individual__discard 0
+#define R_NETWORK_REC_CONFIG__ma1__BITNR 1
+#define R_NETWORK_REC_CONFIG__ma1__WIDTH 1
+#define R_NETWORK_REC_CONFIG__ma1__enable 1
+#define R_NETWORK_REC_CONFIG__ma1__disable 0
+#define R_NETWORK_REC_CONFIG__ma0__BITNR 0
+#define R_NETWORK_REC_CONFIG__ma0__WIDTH 1
+#define R_NETWORK_REC_CONFIG__ma0__enable 1
+#define R_NETWORK_REC_CONFIG__ma0__disable 0
+
+#define R_NETWORK_GEN_CONFIG (IO_TYPECAST_UDWORD 0xb0000098)
+#define R_NETWORK_GEN_CONFIG__loopback__BITNR 5
+#define R_NETWORK_GEN_CONFIG__loopback__WIDTH 1
+#define R_NETWORK_GEN_CONFIG__loopback__on 1
+#define R_NETWORK_GEN_CONFIG__loopback__off 0
+#define R_NETWORK_GEN_CONFIG__frame__BITNR 4
+#define R_NETWORK_GEN_CONFIG__frame__WIDTH 1
+#define R_NETWORK_GEN_CONFIG__frame__tokenr 1
+#define R_NETWORK_GEN_CONFIG__frame__ether 0
+#define R_NETWORK_GEN_CONFIG__vg__BITNR 3
+#define R_NETWORK_GEN_CONFIG__vg__WIDTH 1
+#define R_NETWORK_GEN_CONFIG__vg__on 1
+#define R_NETWORK_GEN_CONFIG__vg__off 0
+#define R_NETWORK_GEN_CONFIG__phy__BITNR 1
+#define R_NETWORK_GEN_CONFIG__phy__WIDTH 2
+#define R_NETWORK_GEN_CONFIG__phy__sni 0
+#define R_NETWORK_GEN_CONFIG__phy__mii_clk 1
+#define R_NETWORK_GEN_CONFIG__phy__mii_err 2
+#define R_NETWORK_GEN_CONFIG__phy__mii_req 3
+#define R_NETWORK_GEN_CONFIG__enable__BITNR 0
+#define R_NETWORK_GEN_CONFIG__enable__WIDTH 1
+#define R_NETWORK_GEN_CONFIG__enable__on 1
+#define R_NETWORK_GEN_CONFIG__enable__off 0
+
+#define R_NETWORK_TR_CTRL (IO_TYPECAST_UDWORD 0xb000009c)
+#define R_NETWORK_TR_CTRL__clr_error__BITNR 8
+#define R_NETWORK_TR_CTRL__clr_error__WIDTH 1
+#define R_NETWORK_TR_CTRL__clr_error__clr 1
+#define R_NETWORK_TR_CTRL__clr_error__nop 0
+#define R_NETWORK_TR_CTRL__delay__BITNR 5
+#define R_NETWORK_TR_CTRL__delay__WIDTH 1
+#define R_NETWORK_TR_CTRL__delay__d2us 1
+#define R_NETWORK_TR_CTRL__delay__none 0
+#define R_NETWORK_TR_CTRL__cancel__BITNR 4
+#define R_NETWORK_TR_CTRL__cancel__WIDTH 1
+#define R_NETWORK_TR_CTRL__cancel__do 1
+#define R_NETWORK_TR_CTRL__cancel__dont 0
+#define R_NETWORK_TR_CTRL__cd__BITNR 3
+#define R_NETWORK_TR_CTRL__cd__WIDTH 1
+#define R_NETWORK_TR_CTRL__cd__enable 0
+#define R_NETWORK_TR_CTRL__cd__disable 1
+#define R_NETWORK_TR_CTRL__cd__ack_col 0
+#define R_NETWORK_TR_CTRL__cd__ack_crs 1
+#define R_NETWORK_TR_CTRL__retry__BITNR 2
+#define R_NETWORK_TR_CTRL__retry__WIDTH 1
+#define R_NETWORK_TR_CTRL__retry__enable 0
+#define R_NETWORK_TR_CTRL__retry__disable 1
+#define R_NETWORK_TR_CTRL__pad__BITNR 1
+#define R_NETWORK_TR_CTRL__pad__WIDTH 1
+#define R_NETWORK_TR_CTRL__pad__enable 1
+#define R_NETWORK_TR_CTRL__pad__disable 0
+#define R_NETWORK_TR_CTRL__crc__BITNR 0
+#define R_NETWORK_TR_CTRL__crc__WIDTH 1
+#define R_NETWORK_TR_CTRL__crc__enable 0
+#define R_NETWORK_TR_CTRL__crc__disable 1
+
+#define R_NETWORK_MGM_CTRL (IO_TYPECAST_UDWORD 0xb00000a0)
+#define R_NETWORK_MGM_CTRL__txd_pins__BITNR 4
+#define R_NETWORK_MGM_CTRL__txd_pins__WIDTH 4
+#define R_NETWORK_MGM_CTRL__txer_pin__BITNR 3
+#define R_NETWORK_MGM_CTRL__txer_pin__WIDTH 1
+#define R_NETWORK_MGM_CTRL__mdck__BITNR 2
+#define R_NETWORK_MGM_CTRL__mdck__WIDTH 1
+#define R_NETWORK_MGM_CTRL__mdoe__BITNR 1
+#define R_NETWORK_MGM_CTRL__mdoe__WIDTH 1
+#define R_NETWORK_MGM_CTRL__mdoe__enable 1
+#define R_NETWORK_MGM_CTRL__mdoe__disable 0
+#define R_NETWORK_MGM_CTRL__mdio__BITNR 0
+#define R_NETWORK_MGM_CTRL__mdio__WIDTH 1
+
+#define R_NETWORK_STAT (IO_TYPECAST_RO_UDWORD 0xb00000a0)
+#define R_NETWORK_STAT__rxd_pins__BITNR 4
+#define R_NETWORK_STAT__rxd_pins__WIDTH 4
+#define R_NETWORK_STAT__rxer__BITNR 3
+#define R_NETWORK_STAT__rxer__WIDTH 1
+#define R_NETWORK_STAT__underrun__BITNR 2
+#define R_NETWORK_STAT__underrun__WIDTH 1
+#define R_NETWORK_STAT__underrun__yes 1
+#define R_NETWORK_STAT__underrun__no 0
+#define R_NETWORK_STAT__exc_col__BITNR 1
+#define R_NETWORK_STAT__exc_col__WIDTH 1
+#define R_NETWORK_STAT__exc_col__yes 1
+#define R_NETWORK_STAT__exc_col__no 0
+#define R_NETWORK_STAT__mdio__BITNR 0
+#define R_NETWORK_STAT__mdio__WIDTH 1
+
+#define R_REC_COUNTERS (IO_TYPECAST_RO_UDWORD 0xb00000a4)
+#define R_REC_COUNTERS__congestion__BITNR 24
+#define R_REC_COUNTERS__congestion__WIDTH 8
+#define R_REC_COUNTERS__oversize__BITNR 16
+#define R_REC_COUNTERS__oversize__WIDTH 8
+#define R_REC_COUNTERS__alignment_error__BITNR 8
+#define R_REC_COUNTERS__alignment_error__WIDTH 8
+#define R_REC_COUNTERS__crc_error__BITNR 0
+#define R_REC_COUNTERS__crc_error__WIDTH 8
+
+#define R_TR_COUNTERS (IO_TYPECAST_RO_UDWORD 0xb00000a8)
+#define R_TR_COUNTERS__deferred__BITNR 24
+#define R_TR_COUNTERS__deferred__WIDTH 8
+#define R_TR_COUNTERS__late_col__BITNR 16
+#define R_TR_COUNTERS__late_col__WIDTH 8
+#define R_TR_COUNTERS__multiple_col__BITNR 8
+#define R_TR_COUNTERS__multiple_col__WIDTH 8
+#define R_TR_COUNTERS__single_col__BITNR 0
+#define R_TR_COUNTERS__single_col__WIDTH 8
+
+#define R_PHY_COUNTERS (IO_TYPECAST_RO_UDWORD 0xb00000ac)
+#define R_PHY_COUNTERS__sqe_test_error__BITNR 8
+#define R_PHY_COUNTERS__sqe_test_error__WIDTH 8
+#define R_PHY_COUNTERS__carrier_loss__BITNR 0
+#define R_PHY_COUNTERS__carrier_loss__WIDTH 8
+
+/*
+!* Parallel printer port registers
+!*/
+
+#define R_PAR0_CTRL_DATA (IO_TYPECAST_UDWORD 0xb0000040)
+#define R_PAR0_CTRL_DATA__peri_int__BITNR 24
+#define R_PAR0_CTRL_DATA__peri_int__WIDTH 1
+#define R_PAR0_CTRL_DATA__peri_int__ack 1
+#define R_PAR0_CTRL_DATA__peri_int__nop 0
+#define R_PAR0_CTRL_DATA__oe__BITNR 20
+#define R_PAR0_CTRL_DATA__oe__WIDTH 1
+#define R_PAR0_CTRL_DATA__oe__enable 1
+#define R_PAR0_CTRL_DATA__oe__disable 0
+#define R_PAR0_CTRL_DATA__seli__BITNR 19
+#define R_PAR0_CTRL_DATA__seli__WIDTH 1
+#define R_PAR0_CTRL_DATA__seli__active 1
+#define R_PAR0_CTRL_DATA__seli__inactive 0
+#define R_PAR0_CTRL_DATA__autofd__BITNR 18
+#define R_PAR0_CTRL_DATA__autofd__WIDTH 1
+#define R_PAR0_CTRL_DATA__autofd__active 1
+#define R_PAR0_CTRL_DATA__autofd__inactive 0
+#define R_PAR0_CTRL_DATA__strb__BITNR 17
+#define R_PAR0_CTRL_DATA__strb__WIDTH 1
+#define R_PAR0_CTRL_DATA__strb__active 1
+#define R_PAR0_CTRL_DATA__strb__inactive 0
+#define R_PAR0_CTRL_DATA__init__BITNR 16
+#define R_PAR0_CTRL_DATA__init__WIDTH 1
+#define R_PAR0_CTRL_DATA__init__active 1
+#define R_PAR0_CTRL_DATA__init__inactive 0
+#define R_PAR0_CTRL_DATA__ecp_cmd__BITNR 8
+#define R_PAR0_CTRL_DATA__ecp_cmd__WIDTH 1
+#define R_PAR0_CTRL_DATA__ecp_cmd__command 1
+#define R_PAR0_CTRL_DATA__ecp_cmd__data 0
+#define R_PAR0_CTRL_DATA__data__BITNR 0
+#define R_PAR0_CTRL_DATA__data__WIDTH 8
+
+#define R_PAR0_CTRL (IO_TYPECAST_BYTE 0xb0000042)
+#define R_PAR0_CTRL__ctrl__BITNR 0
+#define R_PAR0_CTRL__ctrl__WIDTH 5
+
+#define R_PAR0_STATUS_DATA (IO_TYPECAST_RO_UDWORD 0xb0000040)
+#define R_PAR0_STATUS_DATA__mode__BITNR 29
+#define R_PAR0_STATUS_DATA__mode__WIDTH 3
+#define R_PAR0_STATUS_DATA__mode__manual 0
+#define R_PAR0_STATUS_DATA__mode__centronics 1
+#define R_PAR0_STATUS_DATA__mode__fastbyte 2
+#define R_PAR0_STATUS_DATA__mode__nibble 3
+#define R_PAR0_STATUS_DATA__mode__byte 4
+#define R_PAR0_STATUS_DATA__mode__ecp_fwd 5
+#define R_PAR0_STATUS_DATA__mode__ecp_rev 6
+#define R_PAR0_STATUS_DATA__mode__off 7
+#define R_PAR0_STATUS_DATA__perr__BITNR 28
+#define R_PAR0_STATUS_DATA__perr__WIDTH 1
+#define R_PAR0_STATUS_DATA__perr__active 1
+#define R_PAR0_STATUS_DATA__perr__inactive 0
+#define R_PAR0_STATUS_DATA__ack__BITNR 27
+#define R_PAR0_STATUS_DATA__ack__WIDTH 1
+#define R_PAR0_STATUS_DATA__ack__active 0
+#define R_PAR0_STATUS_DATA__ack__inactive 1
+#define R_PAR0_STATUS_DATA__busy__BITNR 26
+#define R_PAR0_STATUS_DATA__busy__WIDTH 1
+#define R_PAR0_STATUS_DATA__busy__active 1
+#define R_PAR0_STATUS_DATA__busy__inactive 0
+#define R_PAR0_STATUS_DATA__fault__BITNR 25
+#define R_PAR0_STATUS_DATA__fault__WIDTH 1
+#define R_PAR0_STATUS_DATA__fault__active 0
+#define R_PAR0_STATUS_DATA__fault__inactive 1
+#define R_PAR0_STATUS_DATA__sel__BITNR 24
+#define R_PAR0_STATUS_DATA__sel__WIDTH 1
+#define R_PAR0_STATUS_DATA__sel__active 1
+#define R_PAR0_STATUS_DATA__sel__inactive 0
+#define R_PAR0_STATUS_DATA__tr_rdy__BITNR 17
+#define R_PAR0_STATUS_DATA__tr_rdy__WIDTH 1
+#define R_PAR0_STATUS_DATA__tr_rdy__ready 1
+#define R_PAR0_STATUS_DATA__tr_rdy__busy 0
+#define R_PAR0_STATUS_DATA__dav__BITNR 16
+#define R_PAR0_STATUS_DATA__dav__WIDTH 1
+#define R_PAR0_STATUS_DATA__dav__data 1
+#define R_PAR0_STATUS_DATA__dav__nodata 0
+#define R_PAR0_STATUS_DATA__ecp_cmd__BITNR 8
+#define R_PAR0_STATUS_DATA__ecp_cmd__WIDTH 1
+#define R_PAR0_STATUS_DATA__ecp_cmd__command 1
+#define R_PAR0_STATUS_DATA__ecp_cmd__data 0
+#define R_PAR0_STATUS_DATA__data__BITNR 0
+#define R_PAR0_STATUS_DATA__data__WIDTH 8
+
+#define R_PAR_ECP16_DATA (IO_TYPECAST_RO_UWORD 0xb0000040)
+#define R_PAR_ECP16_DATA__data__BITNR 0
+#define R_PAR_ECP16_DATA__data__WIDTH 16
+
+#define R_PAR0_CONFIG (IO_TYPECAST_UDWORD 0xb0000044)
+#define R_PAR0_CONFIG__ioe__BITNR 25
+#define R_PAR0_CONFIG__ioe__WIDTH 1
+#define R_PAR0_CONFIG__ioe__inv 1
+#define R_PAR0_CONFIG__ioe__noninv 0
+#define R_PAR0_CONFIG__iseli__BITNR 24
+#define R_PAR0_CONFIG__iseli__WIDTH 1
+#define R_PAR0_CONFIG__iseli__inv 1
+#define R_PAR0_CONFIG__iseli__noninv 0
+#define R_PAR0_CONFIG__iautofd__BITNR 23
+#define R_PAR0_CONFIG__iautofd__WIDTH 1
+#define R_PAR0_CONFIG__iautofd__inv 1
+#define R_PAR0_CONFIG__iautofd__noninv 0
+#define R_PAR0_CONFIG__istrb__BITNR 22
+#define R_PAR0_CONFIG__istrb__WIDTH 1
+#define R_PAR0_CONFIG__istrb__inv 1
+#define R_PAR0_CONFIG__istrb__noninv 0
+#define R_PAR0_CONFIG__iinit__BITNR 21
+#define R_PAR0_CONFIG__iinit__WIDTH 1
+#define R_PAR0_CONFIG__iinit__inv 1
+#define R_PAR0_CONFIG__iinit__noninv 0
+#define R_PAR0_CONFIG__iperr__BITNR 20
+#define R_PAR0_CONFIG__iperr__WIDTH 1
+#define R_PAR0_CONFIG__iperr__inv 1
+#define R_PAR0_CONFIG__iperr__noninv 0
+#define R_PAR0_CONFIG__iack__BITNR 19
+#define R_PAR0_CONFIG__iack__WIDTH 1
+#define R_PAR0_CONFIG__iack__inv 1
+#define R_PAR0_CONFIG__iack__noninv 0
+#define R_PAR0_CONFIG__ibusy__BITNR 18
+#define R_PAR0_CONFIG__ibusy__WIDTH 1
+#define R_PAR0_CONFIG__ibusy__inv 1
+#define R_PAR0_CONFIG__ibusy__noninv 0
+#define R_PAR0_CONFIG__ifault__BITNR 17
+#define R_PAR0_CONFIG__ifault__WIDTH 1
+#define R_PAR0_CONFIG__ifault__inv 1
+#define R_PAR0_CONFIG__ifault__noninv 0
+#define R_PAR0_CONFIG__isel__BITNR 16
+#define R_PAR0_CONFIG__isel__WIDTH 1
+#define R_PAR0_CONFIG__isel__inv 1
+#define R_PAR0_CONFIG__isel__noninv 0
+#define R_PAR0_CONFIG__ext_mode__BITNR 11
+#define R_PAR0_CONFIG__ext_mode__WIDTH 1
+#define R_PAR0_CONFIG__ext_mode__enable 1
+#define R_PAR0_CONFIG__ext_mode__disable 0
+#define R_PAR0_CONFIG__wide__BITNR 10
+#define R_PAR0_CONFIG__wide__WIDTH 1
+#define R_PAR0_CONFIG__wide__enable 1
+#define R_PAR0_CONFIG__wide__disable 0
+#define R_PAR0_CONFIG__dma__BITNR 9
+#define R_PAR0_CONFIG__dma__WIDTH 1
+#define R_PAR0_CONFIG__dma__enable 1
+#define R_PAR0_CONFIG__dma__disable 0
+#define R_PAR0_CONFIG__rle_in__BITNR 8
+#define R_PAR0_CONFIG__rle_in__WIDTH 1
+#define R_PAR0_CONFIG__rle_in__enable 1
+#define R_PAR0_CONFIG__rle_in__disable 0
+#define R_PAR0_CONFIG__rle_out__BITNR 7
+#define R_PAR0_CONFIG__rle_out__WIDTH 1
+#define R_PAR0_CONFIG__rle_out__enable 1
+#define R_PAR0_CONFIG__rle_out__disable 0
+#define R_PAR0_CONFIG__enable__BITNR 6
+#define R_PAR0_CONFIG__enable__WIDTH 1
+#define R_PAR0_CONFIG__enable__on 1
+#define R_PAR0_CONFIG__enable__reset 0
+#define R_PAR0_CONFIG__force__BITNR 5
+#define R_PAR0_CONFIG__force__WIDTH 1
+#define R_PAR0_CONFIG__force__on 1
+#define R_PAR0_CONFIG__force__off 0
+#define R_PAR0_CONFIG__ign_ack__BITNR 4
+#define R_PAR0_CONFIG__ign_ack__WIDTH 1
+#define R_PAR0_CONFIG__ign_ack__ignore 1
+#define R_PAR0_CONFIG__ign_ack__wait 0
+#define R_PAR0_CONFIG__oe_ack__BITNR 3
+#define R_PAR0_CONFIG__oe_ack__WIDTH 1
+#define R_PAR0_CONFIG__oe_ack__wait_oe 1
+#define R_PAR0_CONFIG__oe_ack__dont_wait 0
+#define R_PAR0_CONFIG__oe_ack__epp_addr 1
+#define R_PAR0_CONFIG__oe_ack__epp_data 0
+#define R_PAR0_CONFIG__epp_addr_data__BITNR 3
+#define R_PAR0_CONFIG__epp_addr_data__WIDTH 1
+#define R_PAR0_CONFIG__epp_addr_data__wait_oe 1
+#define R_PAR0_CONFIG__epp_addr_data__dont_wait 0
+#define R_PAR0_CONFIG__epp_addr_data__epp_addr 1
+#define R_PAR0_CONFIG__epp_addr_data__epp_data 0
+#define R_PAR0_CONFIG__mode__BITNR 0
+#define R_PAR0_CONFIG__mode__WIDTH 3
+#define R_PAR0_CONFIG__mode__manual 0
+#define R_PAR0_CONFIG__mode__centronics 1
+#define R_PAR0_CONFIG__mode__fastbyte 2
+#define R_PAR0_CONFIG__mode__nibble 3
+#define R_PAR0_CONFIG__mode__byte 4
+#define R_PAR0_CONFIG__mode__ecp_fwd 5
+#define R_PAR0_CONFIG__mode__ecp_rev 6
+#define R_PAR0_CONFIG__mode__off 7
+
+#define R_PAR0_DELAY (IO_TYPECAST_UDWORD 0xb0000048)
+#define R_PAR0_DELAY__fine_hold__BITNR 21
+#define R_PAR0_DELAY__fine_hold__WIDTH 3
+#define R_PAR0_DELAY__hold__BITNR 16
+#define R_PAR0_DELAY__hold__WIDTH 5
+#define R_PAR0_DELAY__fine_strb__BITNR 13
+#define R_PAR0_DELAY__fine_strb__WIDTH 3
+#define R_PAR0_DELAY__strobe__BITNR 8
+#define R_PAR0_DELAY__strobe__WIDTH 5
+#define R_PAR0_DELAY__fine_setup__BITNR 5
+#define R_PAR0_DELAY__fine_setup__WIDTH 3
+#define R_PAR0_DELAY__setup__BITNR 0
+#define R_PAR0_DELAY__setup__WIDTH 5
+
+#define R_PAR1_CTRL_DATA (IO_TYPECAST_UDWORD 0xb0000050)
+#define R_PAR1_CTRL_DATA__peri_int__BITNR 24
+#define R_PAR1_CTRL_DATA__peri_int__WIDTH 1
+#define R_PAR1_CTRL_DATA__peri_int__ack 1
+#define R_PAR1_CTRL_DATA__peri_int__nop 0
+#define R_PAR1_CTRL_DATA__oe__BITNR 20
+#define R_PAR1_CTRL_DATA__oe__WIDTH 1
+#define R_PAR1_CTRL_DATA__oe__enable 1
+#define R_PAR1_CTRL_DATA__oe__disable 0
+#define R_PAR1_CTRL_DATA__seli__BITNR 19
+#define R_PAR1_CTRL_DATA__seli__WIDTH 1
+#define R_PAR1_CTRL_DATA__seli__active 1
+#define R_PAR1_CTRL_DATA__seli__inactive 0
+#define R_PAR1_CTRL_DATA__autofd__BITNR 18
+#define R_PAR1_CTRL_DATA__autofd__WIDTH 1
+#define R_PAR1_CTRL_DATA__autofd__active 1
+#define R_PAR1_CTRL_DATA__autofd__inactive 0
+#define R_PAR1_CTRL_DATA__strb__BITNR 17
+#define R_PAR1_CTRL_DATA__strb__WIDTH 1
+#define R_PAR1_CTRL_DATA__strb__active 1
+#define R_PAR1_CTRL_DATA__strb__inactive 0
+#define R_PAR1_CTRL_DATA__init__BITNR 16
+#define R_PAR1_CTRL_DATA__init__WIDTH 1
+#define R_PAR1_CTRL_DATA__init__active 1
+#define R_PAR1_CTRL_DATA__init__inactive 0
+#define R_PAR1_CTRL_DATA__ecp_cmd__BITNR 8
+#define R_PAR1_CTRL_DATA__ecp_cmd__WIDTH 1
+#define R_PAR1_CTRL_DATA__ecp_cmd__command 1
+#define R_PAR1_CTRL_DATA__ecp_cmd__data 0
+#define R_PAR1_CTRL_DATA__data__BITNR 0
+#define R_PAR1_CTRL_DATA__data__WIDTH 8
+
+#define R_PAR1_CTRL (IO_TYPECAST_BYTE 0xb0000052)
+#define R_PAR1_CTRL__ctrl__BITNR 0
+#define R_PAR1_CTRL__ctrl__WIDTH 5
+
+#define R_PAR1_STATUS_DATA (IO_TYPECAST_RO_UDWORD 0xb0000050)
+#define R_PAR1_STATUS_DATA__mode__BITNR 29
+#define R_PAR1_STATUS_DATA__mode__WIDTH 3
+#define R_PAR1_STATUS_DATA__mode__manual 0
+#define R_PAR1_STATUS_DATA__mode__centronics 1
+#define R_PAR1_STATUS_DATA__mode__fastbyte 2
+#define R_PAR1_STATUS_DATA__mode__nibble 3
+#define R_PAR1_STATUS_DATA__mode__byte 4
+#define R_PAR1_STATUS_DATA__mode__ecp_fwd 5
+#define R_PAR1_STATUS_DATA__mode__ecp_rev 6
+#define R_PAR1_STATUS_DATA__mode__off 7
+#define R_PAR1_STATUS_DATA__perr__BITNR 28
+#define R_PAR1_STATUS_DATA__perr__WIDTH 1
+#define R_PAR1_STATUS_DATA__perr__active 1
+#define R_PAR1_STATUS_DATA__perr__inactive 0
+#define R_PAR1_STATUS_DATA__ack__BITNR 27
+#define R_PAR1_STATUS_DATA__ack__WIDTH 1
+#define R_PAR1_STATUS_DATA__ack__active 0
+#define R_PAR1_STATUS_DATA__ack__inactive 1
+#define R_PAR1_STATUS_DATA__busy__BITNR 26
+#define R_PAR1_STATUS_DATA__busy__WIDTH 1
+#define R_PAR1_STATUS_DATA__busy__active 1
+#define R_PAR1_STATUS_DATA__busy__inactive 0
+#define R_PAR1_STATUS_DATA__fault__BITNR 25
+#define R_PAR1_STATUS_DATA__fault__WIDTH 1
+#define R_PAR1_STATUS_DATA__fault__active 0
+#define R_PAR1_STATUS_DATA__fault__inactive 1
+#define R_PAR1_STATUS_DATA__sel__BITNR 24
+#define R_PAR1_STATUS_DATA__sel__WIDTH 1
+#define R_PAR1_STATUS_DATA__sel__active 1
+#define R_PAR1_STATUS_DATA__sel__inactive 0
+#define R_PAR1_STATUS_DATA__tr_rdy__BITNR 17
+#define R_PAR1_STATUS_DATA__tr_rdy__WIDTH 1
+#define R_PAR1_STATUS_DATA__tr_rdy__ready 1
+#define R_PAR1_STATUS_DATA__tr_rdy__busy 0
+#define R_PAR1_STATUS_DATA__dav__BITNR 16
+#define R_PAR1_STATUS_DATA__dav__WIDTH 1
+#define R_PAR1_STATUS_DATA__dav__data 1
+#define R_PAR1_STATUS_DATA__dav__nodata 0
+#define R_PAR1_STATUS_DATA__ecp_cmd__BITNR 8
+#define R_PAR1_STATUS_DATA__ecp_cmd__WIDTH 1
+#define R_PAR1_STATUS_DATA__ecp_cmd__command 1
+#define R_PAR1_STATUS_DATA__ecp_cmd__data 0
+#define R_PAR1_STATUS_DATA__data__BITNR 0
+#define R_PAR1_STATUS_DATA__data__WIDTH 8
+
+#define R_PAR1_CONFIG (IO_TYPECAST_UDWORD 0xb0000054)
+#define R_PAR1_CONFIG__ioe__BITNR 25
+#define R_PAR1_CONFIG__ioe__WIDTH 1
+#define R_PAR1_CONFIG__ioe__inv 1
+#define R_PAR1_CONFIG__ioe__noninv 0
+#define R_PAR1_CONFIG__iseli__BITNR 24
+#define R_PAR1_CONFIG__iseli__WIDTH 1
+#define R_PAR1_CONFIG__iseli__inv 1
+#define R_PAR1_CONFIG__iseli__noninv 0
+#define R_PAR1_CONFIG__iautofd__BITNR 23
+#define R_PAR1_CONFIG__iautofd__WIDTH 1
+#define R_PAR1_CONFIG__iautofd__inv 1
+#define R_PAR1_CONFIG__iautofd__noninv 0
+#define R_PAR1_CONFIG__istrb__BITNR 22
+#define R_PAR1_CONFIG__istrb__WIDTH 1
+#define R_PAR1_CONFIG__istrb__inv 1
+#define R_PAR1_CONFIG__istrb__noninv 0
+#define R_PAR1_CONFIG__iinit__BITNR 21
+#define R_PAR1_CONFIG__iinit__WIDTH 1
+#define R_PAR1_CONFIG__iinit__inv 1
+#define R_PAR1_CONFIG__iinit__noninv 0
+#define R_PAR1_CONFIG__iperr__BITNR 20
+#define R_PAR1_CONFIG__iperr__WIDTH 1
+#define R_PAR1_CONFIG__iperr__inv 1
+#define R_PAR1_CONFIG__iperr__noninv 0
+#define R_PAR1_CONFIG__iack__BITNR 19
+#define R_PAR1_CONFIG__iack__WIDTH 1
+#define R_PAR1_CONFIG__iack__inv 1
+#define R_PAR1_CONFIG__iack__noninv 0
+#define R_PAR1_CONFIG__ibusy__BITNR 18
+#define R_PAR1_CONFIG__ibusy__WIDTH 1
+#define R_PAR1_CONFIG__ibusy__inv 1
+#define R_PAR1_CONFIG__ibusy__noninv 0
+#define R_PAR1_CONFIG__ifault__BITNR 17
+#define R_PAR1_CONFIG__ifault__WIDTH 1
+#define R_PAR1_CONFIG__ifault__inv 1
+#define R_PAR1_CONFIG__ifault__noninv 0
+#define R_PAR1_CONFIG__isel__BITNR 16
+#define R_PAR1_CONFIG__isel__WIDTH 1
+#define R_PAR1_CONFIG__isel__inv 1
+#define R_PAR1_CONFIG__isel__noninv 0
+#define R_PAR1_CONFIG__ext_mode__BITNR 11
+#define R_PAR1_CONFIG__ext_mode__WIDTH 1
+#define R_PAR1_CONFIG__ext_mode__enable 1
+#define R_PAR1_CONFIG__ext_mode__disable 0
+#define R_PAR1_CONFIG__dma__BITNR 9
+#define R_PAR1_CONFIG__dma__WIDTH 1
+#define R_PAR1_CONFIG__dma__enable 1
+#define R_PAR1_CONFIG__dma__disable 0
+#define R_PAR1_CONFIG__rle_in__BITNR 8
+#define R_PAR1_CONFIG__rle_in__WIDTH 1
+#define R_PAR1_CONFIG__rle_in__enable 1
+#define R_PAR1_CONFIG__rle_in__disable 0
+#define R_PAR1_CONFIG__rle_out__BITNR 7
+#define R_PAR1_CONFIG__rle_out__WIDTH 1
+#define R_PAR1_CONFIG__rle_out__enable 1
+#define R_PAR1_CONFIG__rle_out__disable 0
+#define R_PAR1_CONFIG__enable__BITNR 6
+#define R_PAR1_CONFIG__enable__WIDTH 1
+#define R_PAR1_CONFIG__enable__on 1
+#define R_PAR1_CONFIG__enable__reset 0
+#define R_PAR1_CONFIG__force__BITNR 5
+#define R_PAR1_CONFIG__force__WIDTH 1
+#define R_PAR1_CONFIG__force__on 1
+#define R_PAR1_CONFIG__force__off 0
+#define R_PAR1_CONFIG__ign_ack__BITNR 4
+#define R_PAR1_CONFIG__ign_ack__WIDTH 1
+#define R_PAR1_CONFIG__ign_ack__ignore 1
+#define R_PAR1_CONFIG__ign_ack__wait 0
+#define R_PAR1_CONFIG__oe_ack__BITNR 3
+#define R_PAR1_CONFIG__oe_ack__WIDTH 1
+#define R_PAR1_CONFIG__oe_ack__wait_oe 1
+#define R_PAR1_CONFIG__oe_ack__dont_wait 0
+#define R_PAR1_CONFIG__oe_ack__epp_addr 1
+#define R_PAR1_CONFIG__oe_ack__epp_data 0
+#define R_PAR1_CONFIG__epp_addr_data__BITNR 3
+#define R_PAR1_CONFIG__epp_addr_data__WIDTH 1
+#define R_PAR1_CONFIG__epp_addr_data__wait_oe 1
+#define R_PAR1_CONFIG__epp_addr_data__dont_wait 0
+#define R_PAR1_CONFIG__epp_addr_data__epp_addr 1
+#define R_PAR1_CONFIG__epp_addr_data__epp_data 0
+#define R_PAR1_CONFIG__mode__BITNR 0
+#define R_PAR1_CONFIG__mode__WIDTH 3
+#define R_PAR1_CONFIG__mode__manual 0
+#define R_PAR1_CONFIG__mode__centronics 1
+#define R_PAR1_CONFIG__mode__fastbyte 2
+#define R_PAR1_CONFIG__mode__nibble 3
+#define R_PAR1_CONFIG__mode__byte 4
+#define R_PAR1_CONFIG__mode__ecp_fwd 5
+#define R_PAR1_CONFIG__mode__ecp_rev 6
+#define R_PAR1_CONFIG__mode__off 7
+
+#define R_PAR1_DELAY (IO_TYPECAST_UDWORD 0xb0000058)
+#define R_PAR1_DELAY__fine_hold__BITNR 21
+#define R_PAR1_DELAY__fine_hold__WIDTH 3
+#define R_PAR1_DELAY__hold__BITNR 16
+#define R_PAR1_DELAY__hold__WIDTH 5
+#define R_PAR1_DELAY__fine_strb__BITNR 13
+#define R_PAR1_DELAY__fine_strb__WIDTH 3
+#define R_PAR1_DELAY__strobe__BITNR 8
+#define R_PAR1_DELAY__strobe__WIDTH 5
+#define R_PAR1_DELAY__fine_setup__BITNR 5
+#define R_PAR1_DELAY__fine_setup__WIDTH 3
+#define R_PAR1_DELAY__setup__BITNR 0
+#define R_PAR1_DELAY__setup__WIDTH 5
+
+/*
+!* ATA interface registers
+!*/
+
+#define R_ATA_CTRL_DATA (IO_TYPECAST_UDWORD 0xb0000040)
+#define R_ATA_CTRL_DATA__sel__BITNR 30
+#define R_ATA_CTRL_DATA__sel__WIDTH 2
+#define R_ATA_CTRL_DATA__cs1__BITNR 29
+#define R_ATA_CTRL_DATA__cs1__WIDTH 1
+#define R_ATA_CTRL_DATA__cs1__active 1
+#define R_ATA_CTRL_DATA__cs1__inactive 0
+#define R_ATA_CTRL_DATA__cs0__BITNR 28
+#define R_ATA_CTRL_DATA__cs0__WIDTH 1
+#define R_ATA_CTRL_DATA__cs0__active 1
+#define R_ATA_CTRL_DATA__cs0__inactive 0
+#define R_ATA_CTRL_DATA__addr__BITNR 25
+#define R_ATA_CTRL_DATA__addr__WIDTH 3
+#define R_ATA_CTRL_DATA__rw__BITNR 24
+#define R_ATA_CTRL_DATA__rw__WIDTH 1
+#define R_ATA_CTRL_DATA__rw__read 1
+#define R_ATA_CTRL_DATA__rw__write 0
+#define R_ATA_CTRL_DATA__src_dst__BITNR 23
+#define R_ATA_CTRL_DATA__src_dst__WIDTH 1
+#define R_ATA_CTRL_DATA__src_dst__dma 1
+#define R_ATA_CTRL_DATA__src_dst__register 0
+#define R_ATA_CTRL_DATA__handsh__BITNR 22
+#define R_ATA_CTRL_DATA__handsh__WIDTH 1
+#define R_ATA_CTRL_DATA__handsh__dma 1
+#define R_ATA_CTRL_DATA__handsh__pio 0
+#define R_ATA_CTRL_DATA__multi__BITNR 21
+#define R_ATA_CTRL_DATA__multi__WIDTH 1
+#define R_ATA_CTRL_DATA__multi__on 1
+#define R_ATA_CTRL_DATA__multi__off 0
+#define R_ATA_CTRL_DATA__dma_size__BITNR 20
+#define R_ATA_CTRL_DATA__dma_size__WIDTH 1
+#define R_ATA_CTRL_DATA__dma_size__byte 1
+#define R_ATA_CTRL_DATA__dma_size__word 0
+#define R_ATA_CTRL_DATA__data__BITNR 0
+#define R_ATA_CTRL_DATA__data__WIDTH 16
+
+#define R_ATA_STATUS_DATA (IO_TYPECAST_RO_UDWORD 0xb0000040)
+#define R_ATA_STATUS_DATA__busy__BITNR 18
+#define R_ATA_STATUS_DATA__busy__WIDTH 1
+#define R_ATA_STATUS_DATA__busy__yes 1
+#define R_ATA_STATUS_DATA__busy__no 0
+#define R_ATA_STATUS_DATA__tr_rdy__BITNR 17
+#define R_ATA_STATUS_DATA__tr_rdy__WIDTH 1
+#define R_ATA_STATUS_DATA__tr_rdy__ready 1
+#define R_ATA_STATUS_DATA__tr_rdy__busy 0
+#define R_ATA_STATUS_DATA__dav__BITNR 16
+#define R_ATA_STATUS_DATA__dav__WIDTH 1
+#define R_ATA_STATUS_DATA__dav__data 1
+#define R_ATA_STATUS_DATA__dav__nodata 0
+#define R_ATA_STATUS_DATA__data__BITNR 0
+#define R_ATA_STATUS_DATA__data__WIDTH 16
+
+#define R_ATA_CONFIG (IO_TYPECAST_UDWORD 0xb0000044)
+#define R_ATA_CONFIG__enable__BITNR 25
+#define R_ATA_CONFIG__enable__WIDTH 1
+#define R_ATA_CONFIG__enable__on 1
+#define R_ATA_CONFIG__enable__off 0
+#define R_ATA_CONFIG__dma_strobe__BITNR 20
+#define R_ATA_CONFIG__dma_strobe__WIDTH 5
+#define R_ATA_CONFIG__dma_hold__BITNR 15
+#define R_ATA_CONFIG__dma_hold__WIDTH 5
+#define R_ATA_CONFIG__pio_setup__BITNR 10
+#define R_ATA_CONFIG__pio_setup__WIDTH 5
+#define R_ATA_CONFIG__pio_strobe__BITNR 5
+#define R_ATA_CONFIG__pio_strobe__WIDTH 5
+#define R_ATA_CONFIG__pio_hold__BITNR 0
+#define R_ATA_CONFIG__pio_hold__WIDTH 5
+
+#define R_ATA_TRANSFER_CNT (IO_TYPECAST_UDWORD 0xb0000048)
+#define R_ATA_TRANSFER_CNT__count__BITNR 0
+#define R_ATA_TRANSFER_CNT__count__WIDTH 17
+
+/*
+!* SCSI registers
+!*/
+
+#define R_SCSI0_CTRL (IO_TYPECAST_UDWORD 0xb0000044)
+#define R_SCSI0_CTRL__id_type__BITNR 31
+#define R_SCSI0_CTRL__id_type__WIDTH 1
+#define R_SCSI0_CTRL__id_type__software 1
+#define R_SCSI0_CTRL__id_type__hardware 0
+#define R_SCSI0_CTRL__sel_timeout__BITNR 24
+#define R_SCSI0_CTRL__sel_timeout__WIDTH 7
+#define R_SCSI0_CTRL__synch_per__BITNR 16
+#define R_SCSI0_CTRL__synch_per__WIDTH 8
+#define R_SCSI0_CTRL__rst__BITNR 15
+#define R_SCSI0_CTRL__rst__WIDTH 1
+#define R_SCSI0_CTRL__rst__yes 1
+#define R_SCSI0_CTRL__rst__no 0
+#define R_SCSI0_CTRL__atn__BITNR 14
+#define R_SCSI0_CTRL__atn__WIDTH 1
+#define R_SCSI0_CTRL__atn__yes 1
+#define R_SCSI0_CTRL__atn__no 0
+#define R_SCSI0_CTRL__my_id__BITNR 9
+#define R_SCSI0_CTRL__my_id__WIDTH 4
+#define R_SCSI0_CTRL__target_id__BITNR 4
+#define R_SCSI0_CTRL__target_id__WIDTH 4
+#define R_SCSI0_CTRL__fast_20__BITNR 3
+#define R_SCSI0_CTRL__fast_20__WIDTH 1
+#define R_SCSI0_CTRL__fast_20__yes 1
+#define R_SCSI0_CTRL__fast_20__no 0
+#define R_SCSI0_CTRL__bus_width__BITNR 2
+#define R_SCSI0_CTRL__bus_width__WIDTH 1
+#define R_SCSI0_CTRL__bus_width__wide 1
+#define R_SCSI0_CTRL__bus_width__narrow 0
+#define R_SCSI0_CTRL__synch__BITNR 1
+#define R_SCSI0_CTRL__synch__WIDTH 1
+#define R_SCSI0_CTRL__synch__synch 1
+#define R_SCSI0_CTRL__synch__asynch 0
+#define R_SCSI0_CTRL__enable__BITNR 0
+#define R_SCSI0_CTRL__enable__WIDTH 1
+#define R_SCSI0_CTRL__enable__on 1
+#define R_SCSI0_CTRL__enable__off 0
+
+#define R_SCSI0_CMD_DATA (IO_TYPECAST_UDWORD 0xb0000040)
+#define R_SCSI0_CMD_DATA__parity_in__BITNR 26
+#define R_SCSI0_CMD_DATA__parity_in__WIDTH 1
+#define R_SCSI0_CMD_DATA__parity_in__on 0
+#define R_SCSI0_CMD_DATA__parity_in__off 1
+#define R_SCSI0_CMD_DATA__skip__BITNR 25
+#define R_SCSI0_CMD_DATA__skip__WIDTH 1
+#define R_SCSI0_CMD_DATA__skip__on 1
+#define R_SCSI0_CMD_DATA__skip__off 0
+#define R_SCSI0_CMD_DATA__clr_status__BITNR 24
+#define R_SCSI0_CMD_DATA__clr_status__WIDTH 1
+#define R_SCSI0_CMD_DATA__clr_status__yes 1
+#define R_SCSI0_CMD_DATA__clr_status__nop 0
+#define R_SCSI0_CMD_DATA__asynch_setup__BITNR 20
+#define R_SCSI0_CMD_DATA__asynch_setup__WIDTH 4
+#define R_SCSI0_CMD_DATA__command__BITNR 16
+#define R_SCSI0_CMD_DATA__command__WIDTH 4
+#define R_SCSI0_CMD_DATA__command__full_din_1 0
+#define R_SCSI0_CMD_DATA__command__full_dout_1 1
+#define R_SCSI0_CMD_DATA__command__full_stat_1 2
+#define R_SCSI0_CMD_DATA__command__resel_din 3
+#define R_SCSI0_CMD_DATA__command__resel_dout 4
+#define R_SCSI0_CMD_DATA__command__resel_stat 5
+#define R_SCSI0_CMD_DATA__command__arb_only 6
+#define R_SCSI0_CMD_DATA__command__full_din_3 8
+#define R_SCSI0_CMD_DATA__command__full_dout_3 9
+#define R_SCSI0_CMD_DATA__command__full_stat_3 10
+#define R_SCSI0_CMD_DATA__command__man_data_in 11
+#define R_SCSI0_CMD_DATA__command__man_data_out 12
+#define R_SCSI0_CMD_DATA__command__man_rat 13
+#define R_SCSI0_CMD_DATA__data_out__BITNR 0
+#define R_SCSI0_CMD_DATA__data_out__WIDTH 16
+
+#define R_SCSI0_DATA (IO_TYPECAST_UWORD 0xb0000040)
+#define R_SCSI0_DATA__data_out__BITNR 0
+#define R_SCSI0_DATA__data_out__WIDTH 16
+
+#define R_SCSI0_CMD (IO_TYPECAST_BYTE 0xb0000042)
+#define R_SCSI0_CMD__asynch_setup__BITNR 4
+#define R_SCSI0_CMD__asynch_setup__WIDTH 4
+#define R_SCSI0_CMD__command__BITNR 0
+#define R_SCSI0_CMD__command__WIDTH 4
+#define R_SCSI0_CMD__command__full_din_1 0
+#define R_SCSI0_CMD__command__full_dout_1 1
+#define R_SCSI0_CMD__command__full_stat_1 2
+#define R_SCSI0_CMD__command__resel_din 3
+#define R_SCSI0_CMD__command__resel_dout 4
+#define R_SCSI0_CMD__command__resel_stat 5
+#define R_SCSI0_CMD__command__arb_only 6
+#define R_SCSI0_CMD__command__full_din_3 8
+#define R_SCSI0_CMD__command__full_dout_3 9
+#define R_SCSI0_CMD__command__full_stat_3 10
+#define R_SCSI0_CMD__command__man_data_in 11
+#define R_SCSI0_CMD__command__man_data_out 12
+#define R_SCSI0_CMD__command__man_rat 13
+
+#define R_SCSI0_STATUS_CTRL (IO_TYPECAST_BYTE 0xb0000043)
+#define R_SCSI0_STATUS_CTRL__parity_in__BITNR 2
+#define R_SCSI0_STATUS_CTRL__parity_in__WIDTH 1
+#define R_SCSI0_STATUS_CTRL__parity_in__on 0
+#define R_SCSI0_STATUS_CTRL__parity_in__off 1
+#define R_SCSI0_STATUS_CTRL__skip__BITNR 1
+#define R_SCSI0_STATUS_CTRL__skip__WIDTH 1
+#define R_SCSI0_STATUS_CTRL__skip__on 1
+#define R_SCSI0_STATUS_CTRL__skip__off 0
+#define R_SCSI0_STATUS_CTRL__clr_status__BITNR 0
+#define R_SCSI0_STATUS_CTRL__clr_status__WIDTH 1
+#define R_SCSI0_STATUS_CTRL__clr_status__yes 1
+#define R_SCSI0_STATUS_CTRL__clr_status__nop 0
+
+#define R_SCSI0_STATUS (IO_TYPECAST_RO_UDWORD 0xb0000048)
+#define R_SCSI0_STATUS__tst_arb_won__BITNR 23
+#define R_SCSI0_STATUS__tst_arb_won__WIDTH 1
+#define R_SCSI0_STATUS__tst_resel__BITNR 22
+#define R_SCSI0_STATUS__tst_resel__WIDTH 1
+#define R_SCSI0_STATUS__parity_error__BITNR 21
+#define R_SCSI0_STATUS__parity_error__WIDTH 1
+#define R_SCSI0_STATUS__bus_reset__BITNR 20
+#define R_SCSI0_STATUS__bus_reset__WIDTH 1
+#define R_SCSI0_STATUS__bus_reset__yes 1
+#define R_SCSI0_STATUS__bus_reset__no 0
+#define R_SCSI0_STATUS__resel_target__BITNR 15
+#define R_SCSI0_STATUS__resel_target__WIDTH 4
+#define R_SCSI0_STATUS__resel__BITNR 14
+#define R_SCSI0_STATUS__resel__WIDTH 1
+#define R_SCSI0_STATUS__resel__yes 1
+#define R_SCSI0_STATUS__resel__no 0
+#define R_SCSI0_STATUS__curr_phase__BITNR 11
+#define R_SCSI0_STATUS__curr_phase__WIDTH 3
+#define R_SCSI0_STATUS__curr_phase__ph_undef 0
+#define R_SCSI0_STATUS__curr_phase__ph_msg_in 7
+#define R_SCSI0_STATUS__curr_phase__ph_msg_out 6
+#define R_SCSI0_STATUS__curr_phase__ph_status 3
+#define R_SCSI0_STATUS__curr_phase__ph_command 2
+#define R_SCSI0_STATUS__curr_phase__ph_data_in 5
+#define R_SCSI0_STATUS__curr_phase__ph_data_out 4
+#define R_SCSI0_STATUS__curr_phase__ph_resel 1
+#define R_SCSI0_STATUS__last_seq_step__BITNR 6
+#define R_SCSI0_STATUS__last_seq_step__WIDTH 5
+#define R_SCSI0_STATUS__last_seq_step__st_bus_free 24
+#define R_SCSI0_STATUS__last_seq_step__st_arbitrate 8
+#define R_SCSI0_STATUS__last_seq_step__st_resel_req 29
+#define R_SCSI0_STATUS__last_seq_step__st_msg_1 2
+#define R_SCSI0_STATUS__last_seq_step__st_manual 28
+#define R_SCSI0_STATUS__last_seq_step__st_transf_cmd 30
+#define R_SCSI0_STATUS__last_seq_step__st_msg_2 6
+#define R_SCSI0_STATUS__last_seq_step__st_msg_3 22
+#define R_SCSI0_STATUS__last_seq_step__st_answer 3
+#define R_SCSI0_STATUS__last_seq_step__st_synch_din_perr 1
+#define R_SCSI0_STATUS__last_seq_step__st_transfer_done 15
+#define R_SCSI0_STATUS__last_seq_step__st_synch_dout 0
+#define R_SCSI0_STATUS__last_seq_step__st_asynch_dout 25
+#define R_SCSI0_STATUS__last_seq_step__st_synch_din 13
+#define R_SCSI0_STATUS__last_seq_step__st_asynch_din 9
+#define R_SCSI0_STATUS__last_seq_step__st_synch_dout_ack 4
+#define R_SCSI0_STATUS__last_seq_step__st_synch_din_ack 12
+#define R_SCSI0_STATUS__last_seq_step__st_synch_din_ack_perr 5
+#define R_SCSI0_STATUS__last_seq_step__st_asynch_dout_end 11
+#define R_SCSI0_STATUS__last_seq_step__st_iwr 27
+#define R_SCSI0_STATUS__last_seq_step__st_wait_free_disc 21
+#define R_SCSI0_STATUS__last_seq_step__st_sdp_disc 7
+#define R_SCSI0_STATUS__last_seq_step__st_cc 31
+#define R_SCSI0_STATUS__last_seq_step__st_iwr_good 14
+#define R_SCSI0_STATUS__last_seq_step__st_iwr_cc 23
+#define R_SCSI0_STATUS__last_seq_step__st_wait_free_iwr_cc 17
+#define R_SCSI0_STATUS__last_seq_step__st_wait_free_cc 20
+#define R_SCSI0_STATUS__last_seq_step__st_wait_free_sdp_disc 16
+#define R_SCSI0_STATUS__last_seq_step__st_manual_req 10
+#define R_SCSI0_STATUS__last_seq_step__st_manual_din_prot 18
+#define R_SCSI0_STATUS__valid_status__BITNR 5
+#define R_SCSI0_STATUS__valid_status__WIDTH 1
+#define R_SCSI0_STATUS__valid_status__yes 1
+#define R_SCSI0_STATUS__valid_status__no 0
+#define R_SCSI0_STATUS__seq_status__BITNR 0
+#define R_SCSI0_STATUS__seq_status__WIDTH 5
+#define R_SCSI0_STATUS__seq_status__info_seq_complete 0
+#define R_SCSI0_STATUS__seq_status__info_parity_error 1
+#define R_SCSI0_STATUS__seq_status__info_unhandled_msg_in 2
+#define R_SCSI0_STATUS__seq_status__info_unexp_ph_change 3
+#define R_SCSI0_STATUS__seq_status__info_arb_lost 4
+#define R_SCSI0_STATUS__seq_status__info_sel_timeout 5
+#define R_SCSI0_STATUS__seq_status__info_unexp_bf 6
+#define R_SCSI0_STATUS__seq_status__info_illegal_op 7
+#define R_SCSI0_STATUS__seq_status__info_rec_recvd 8
+#define R_SCSI0_STATUS__seq_status__info_reselected 9
+#define R_SCSI0_STATUS__seq_status__info_unhandled_status 10
+#define R_SCSI0_STATUS__seq_status__info_bus_reset 11
+#define R_SCSI0_STATUS__seq_status__info_illegal_bf 12
+#define R_SCSI0_STATUS__seq_status__info_bus_free 13
+
+#define R_SCSI0_DATA_IN (IO_TYPECAST_RO_UWORD 0xb0000040)
+#define R_SCSI0_DATA_IN__data_in__BITNR 0
+#define R_SCSI0_DATA_IN__data_in__WIDTH 16
+
+#define R_SCSI1_CTRL (IO_TYPECAST_UDWORD 0xb0000054)
+#define R_SCSI1_CTRL__id_type__BITNR 31
+#define R_SCSI1_CTRL__id_type__WIDTH 1
+#define R_SCSI1_CTRL__id_type__software 1
+#define R_SCSI1_CTRL__id_type__hardware 0
+#define R_SCSI1_CTRL__sel_timeout__BITNR 24
+#define R_SCSI1_CTRL__sel_timeout__WIDTH 7
+#define R_SCSI1_CTRL__synch_per__BITNR 16
+#define R_SCSI1_CTRL__synch_per__WIDTH 8
+#define R_SCSI1_CTRL__rst__BITNR 15
+#define R_SCSI1_CTRL__rst__WIDTH 1
+#define R_SCSI1_CTRL__rst__yes 1
+#define R_SCSI1_CTRL__rst__no 0
+#define R_SCSI1_CTRL__atn__BITNR 14
+#define R_SCSI1_CTRL__atn__WIDTH 1
+#define R_SCSI1_CTRL__atn__yes 1
+#define R_SCSI1_CTRL__atn__no 0
+#define R_SCSI1_CTRL__my_id__BITNR 9
+#define R_SCSI1_CTRL__my_id__WIDTH 4
+#define R_SCSI1_CTRL__target_id__BITNR 4
+#define R_SCSI1_CTRL__target_id__WIDTH 4
+#define R_SCSI1_CTRL__fast_20__BITNR 3
+#define R_SCSI1_CTRL__fast_20__WIDTH 1
+#define R_SCSI1_CTRL__fast_20__yes 1
+#define R_SCSI1_CTRL__fast_20__no 0
+#define R_SCSI1_CTRL__bus_width__BITNR 2
+#define R_SCSI1_CTRL__bus_width__WIDTH 1
+#define R_SCSI1_CTRL__bus_width__wide 1
+#define R_SCSI1_CTRL__bus_width__narrow 0
+#define R_SCSI1_CTRL__synch__BITNR 1
+#define R_SCSI1_CTRL__synch__WIDTH 1
+#define R_SCSI1_CTRL__synch__synch 1
+#define R_SCSI1_CTRL__synch__asynch 0
+#define R_SCSI1_CTRL__enable__BITNR 0
+#define R_SCSI1_CTRL__enable__WIDTH 1
+#define R_SCSI1_CTRL__enable__on 1
+#define R_SCSI1_CTRL__enable__off 0
+
+#define R_SCSI1_CMD_DATA (IO_TYPECAST_UDWORD 0xb0000050)
+#define R_SCSI1_CMD_DATA__parity_in__BITNR 26
+#define R_SCSI1_CMD_DATA__parity_in__WIDTH 1
+#define R_SCSI1_CMD_DATA__parity_in__on 0
+#define R_SCSI1_CMD_DATA__parity_in__off 1
+#define R_SCSI1_CMD_DATA__skip__BITNR 25
+#define R_SCSI1_CMD_DATA__skip__WIDTH 1
+#define R_SCSI1_CMD_DATA__skip__on 1
+#define R_SCSI1_CMD_DATA__skip__off 0
+#define R_SCSI1_CMD_DATA__clr_status__BITNR 24
+#define R_SCSI1_CMD_DATA__clr_status__WIDTH 1
+#define R_SCSI1_CMD_DATA__clr_status__yes 1
+#define R_SCSI1_CMD_DATA__clr_status__nop 0
+#define R_SCSI1_CMD_DATA__asynch_setup__BITNR 20
+#define R_SCSI1_CMD_DATA__asynch_setup__WIDTH 4
+#define R_SCSI1_CMD_DATA__command__BITNR 16
+#define R_SCSI1_CMD_DATA__command__WIDTH 4
+#define R_SCSI1_CMD_DATA__command__full_din_1 0
+#define R_SCSI1_CMD_DATA__command__full_dout_1 1
+#define R_SCSI1_CMD_DATA__command__full_stat_1 2
+#define R_SCSI1_CMD_DATA__command__resel_din 3
+#define R_SCSI1_CMD_DATA__command__resel_dout 4
+#define R_SCSI1_CMD_DATA__command__resel_stat 5
+#define R_SCSI1_CMD_DATA__command__arb_only 6
+#define R_SCSI1_CMD_DATA__command__full_din_3 8
+#define R_SCSI1_CMD_DATA__command__full_dout_3 9
+#define R_SCSI1_CMD_DATA__command__full_stat_3 10
+#define R_SCSI1_CMD_DATA__command__man_data_in 11
+#define R_SCSI1_CMD_DATA__command__man_data_out 12
+#define R_SCSI1_CMD_DATA__command__man_rat 13
+#define R_SCSI1_CMD_DATA__data_out__BITNR 0
+#define R_SCSI1_CMD_DATA__data_out__WIDTH 16
+
+#define R_SCSI1_DATA (IO_TYPECAST_UWORD 0xb0000050)
+#define R_SCSI1_DATA__data_out__BITNR 0
+#define R_SCSI1_DATA__data_out__WIDTH 16
+
+#define R_SCSI1_CMD (IO_TYPECAST_BYTE 0xb0000052)
+#define R_SCSI1_CMD__asynch_setup__BITNR 4
+#define R_SCSI1_CMD__asynch_setup__WIDTH 4
+#define R_SCSI1_CMD__command__BITNR 0
+#define R_SCSI1_CMD__command__WIDTH 4
+#define R_SCSI1_CMD__command__full_din_1 0
+#define R_SCSI1_CMD__command__full_dout_1 1
+#define R_SCSI1_CMD__command__full_stat_1 2
+#define R_SCSI1_CMD__command__resel_din 3
+#define R_SCSI1_CMD__command__resel_dout 4
+#define R_SCSI1_CMD__command__resel_stat 5
+#define R_SCSI1_CMD__command__arb_only 6
+#define R_SCSI1_CMD__command__full_din_3 8
+#define R_SCSI1_CMD__command__full_dout_3 9
+#define R_SCSI1_CMD__command__full_stat_3 10
+#define R_SCSI1_CMD__command__man_data_in 11
+#define R_SCSI1_CMD__command__man_data_out 12
+#define R_SCSI1_CMD__command__man_rat 13
+
+#define R_SCSI1_STATUS_CTRL (IO_TYPECAST_BYTE 0xb0000053)
+#define R_SCSI1_STATUS_CTRL__parity_in__BITNR 2
+#define R_SCSI1_STATUS_CTRL__parity_in__WIDTH 1
+#define R_SCSI1_STATUS_CTRL__parity_in__on 0
+#define R_SCSI1_STATUS_CTRL__parity_in__off 1
+#define R_SCSI1_STATUS_CTRL__skip__BITNR 1
+#define R_SCSI1_STATUS_CTRL__skip__WIDTH 1
+#define R_SCSI1_STATUS_CTRL__skip__on 1
+#define R_SCSI1_STATUS_CTRL__skip__off 0
+#define R_SCSI1_STATUS_CTRL__clr_status__BITNR 0
+#define R_SCSI1_STATUS_CTRL__clr_status__WIDTH 1
+#define R_SCSI1_STATUS_CTRL__clr_status__yes 1
+#define R_SCSI1_STATUS_CTRL__clr_status__nop 0
+
+#define R_SCSI1_STATUS (IO_TYPECAST_RO_UDWORD 0xb0000058)
+#define R_SCSI1_STATUS__tst_arb_won__BITNR 23
+#define R_SCSI1_STATUS__tst_arb_won__WIDTH 1
+#define R_SCSI1_STATUS__tst_resel__BITNR 22
+#define R_SCSI1_STATUS__tst_resel__WIDTH 1
+#define R_SCSI1_STATUS__parity_error__BITNR 21
+#define R_SCSI1_STATUS__parity_error__WIDTH 1
+#define R_SCSI1_STATUS__bus_reset__BITNR 20
+#define R_SCSI1_STATUS__bus_reset__WIDTH 1
+#define R_SCSI1_STATUS__bus_reset__yes 1
+#define R_SCSI1_STATUS__bus_reset__no 0
+#define R_SCSI1_STATUS__resel_target__BITNR 15
+#define R_SCSI1_STATUS__resel_target__WIDTH 4
+#define R_SCSI1_STATUS__resel__BITNR 14
+#define R_SCSI1_STATUS__resel__WIDTH 1
+#define R_SCSI1_STATUS__resel__yes 1
+#define R_SCSI1_STATUS__resel__no 0
+#define R_SCSI1_STATUS__curr_phase__BITNR 11
+#define R_SCSI1_STATUS__curr_phase__WIDTH 3
+#define R_SCSI1_STATUS__curr_phase__ph_undef 0
+#define R_SCSI1_STATUS__curr_phase__ph_msg_in 7
+#define R_SCSI1_STATUS__curr_phase__ph_msg_out 6
+#define R_SCSI1_STATUS__curr_phase__ph_status 3
+#define R_SCSI1_STATUS__curr_phase__ph_command 2
+#define R_SCSI1_STATUS__curr_phase__ph_data_in 5
+#define R_SCSI1_STATUS__curr_phase__ph_data_out 4
+#define R_SCSI1_STATUS__curr_phase__ph_resel 1
+#define R_SCSI1_STATUS__last_seq_step__BITNR 6
+#define R_SCSI1_STATUS__last_seq_step__WIDTH 5
+#define R_SCSI1_STATUS__last_seq_step__st_bus_free 24
+#define R_SCSI1_STATUS__last_seq_step__st_arbitrate 8
+#define R_SCSI1_STATUS__last_seq_step__st_resel_req 29
+#define R_SCSI1_STATUS__last_seq_step__st_msg_1 2
+#define R_SCSI1_STATUS__last_seq_step__st_manual 28
+#define R_SCSI1_STATUS__last_seq_step__st_transf_cmd 30
+#define R_SCSI1_STATUS__last_seq_step__st_msg_2 6
+#define R_SCSI1_STATUS__last_seq_step__st_msg_3 22
+#define R_SCSI1_STATUS__last_seq_step__st_answer 3
+#define R_SCSI1_STATUS__last_seq_step__st_synch_din_perr 1
+#define R_SCSI1_STATUS__last_seq_step__st_transfer_done 15
+#define R_SCSI1_STATUS__last_seq_step__st_synch_dout 0
+#define R_SCSI1_STATUS__last_seq_step__st_asynch_dout 25
+#define R_SCSI1_STATUS__last_seq_step__st_synch_din 13
+#define R_SCSI1_STATUS__last_seq_step__st_asynch_din 9
+#define R_SCSI1_STATUS__last_seq_step__st_synch_dout_ack 4
+#define R_SCSI1_STATUS__last_seq_step__st_synch_din_ack 12
+#define R_SCSI1_STATUS__last_seq_step__st_synch_din_ack_perr 5
+#define R_SCSI1_STATUS__last_seq_step__st_asynch_dout_end 11
+#define R_SCSI1_STATUS__last_seq_step__st_iwr 27
+#define R_SCSI1_STATUS__last_seq_step__st_wait_free_disc 21
+#define R_SCSI1_STATUS__last_seq_step__st_sdp_disc 7
+#define R_SCSI1_STATUS__last_seq_step__st_cc 31
+#define R_SCSI1_STATUS__last_seq_step__st_iwr_good 14
+#define R_SCSI1_STATUS__last_seq_step__st_iwr_cc 23
+#define R_SCSI1_STATUS__last_seq_step__st_wait_free_iwr_cc 17
+#define R_SCSI1_STATUS__last_seq_step__st_wait_free_cc 20
+#define R_SCSI1_STATUS__last_seq_step__st_wait_free_sdp_disc 16
+#define R_SCSI1_STATUS__last_seq_step__st_manual_req 10
+#define R_SCSI1_STATUS__last_seq_step__st_manual_din_prot 18
+#define R_SCSI1_STATUS__valid_status__BITNR 5
+#define R_SCSI1_STATUS__valid_status__WIDTH 1
+#define R_SCSI1_STATUS__valid_status__yes 1
+#define R_SCSI1_STATUS__valid_status__no 0
+#define R_SCSI1_STATUS__seq_status__BITNR 0
+#define R_SCSI1_STATUS__seq_status__WIDTH 5
+#define R_SCSI1_STATUS__seq_status__info_seq_complete 0
+#define R_SCSI1_STATUS__seq_status__info_parity_error 1
+#define R_SCSI1_STATUS__seq_status__info_unhandled_msg_in 2
+#define R_SCSI1_STATUS__seq_status__info_unexp_ph_change 3
+#define R_SCSI1_STATUS__seq_status__info_arb_lost 4
+#define R_SCSI1_STATUS__seq_status__info_sel_timeout 5
+#define R_SCSI1_STATUS__seq_status__info_unexp_bf 6
+#define R_SCSI1_STATUS__seq_status__info_illegal_op 7
+#define R_SCSI1_STATUS__seq_status__info_rec_recvd 8
+#define R_SCSI1_STATUS__seq_status__info_reselected 9
+#define R_SCSI1_STATUS__seq_status__info_unhandled_status 10
+#define R_SCSI1_STATUS__seq_status__info_bus_reset 11
+#define R_SCSI1_STATUS__seq_status__info_illegal_bf 12
+#define R_SCSI1_STATUS__seq_status__info_bus_free 13
+
+#define R_SCSI1_DATA_IN (IO_TYPECAST_RO_UWORD 0xb0000050)
+#define R_SCSI1_DATA_IN__data_in__BITNR 0
+#define R_SCSI1_DATA_IN__data_in__WIDTH 16
+
+/*
+!* Interrupt mask and status registers
+!*/
+
+#define R_IRQ_MASK0_RD (IO_TYPECAST_RO_UDWORD 0xb00000c0)
+#define R_IRQ_MASK0_RD__nmi_pin__BITNR 31
+#define R_IRQ_MASK0_RD__nmi_pin__WIDTH 1
+#define R_IRQ_MASK0_RD__nmi_pin__active 1
+#define R_IRQ_MASK0_RD__nmi_pin__inactive 0
+#define R_IRQ_MASK0_RD__watchdog_nmi__BITNR 30
+#define R_IRQ_MASK0_RD__watchdog_nmi__WIDTH 1
+#define R_IRQ_MASK0_RD__watchdog_nmi__active 1
+#define R_IRQ_MASK0_RD__watchdog_nmi__inactive 0
+#define R_IRQ_MASK0_RD__sqe_test_error__BITNR 29
+#define R_IRQ_MASK0_RD__sqe_test_error__WIDTH 1
+#define R_IRQ_MASK0_RD__sqe_test_error__active 1
+#define R_IRQ_MASK0_RD__sqe_test_error__inactive 0
+#define R_IRQ_MASK0_RD__carrier_loss__BITNR 28
+#define R_IRQ_MASK0_RD__carrier_loss__WIDTH 1
+#define R_IRQ_MASK0_RD__carrier_loss__active 1
+#define R_IRQ_MASK0_RD__carrier_loss__inactive 0
+#define R_IRQ_MASK0_RD__deferred__BITNR 27
+#define R_IRQ_MASK0_RD__deferred__WIDTH 1
+#define R_IRQ_MASK0_RD__deferred__active 1
+#define R_IRQ_MASK0_RD__deferred__inactive 0
+#define R_IRQ_MASK0_RD__late_col__BITNR 26
+#define R_IRQ_MASK0_RD__late_col__WIDTH 1
+#define R_IRQ_MASK0_RD__late_col__active 1
+#define R_IRQ_MASK0_RD__late_col__inactive 0
+#define R_IRQ_MASK0_RD__multiple_col__BITNR 25
+#define R_IRQ_MASK0_RD__multiple_col__WIDTH 1
+#define R_IRQ_MASK0_RD__multiple_col__active 1
+#define R_IRQ_MASK0_RD__multiple_col__inactive 0
+#define R_IRQ_MASK0_RD__single_col__BITNR 24
+#define R_IRQ_MASK0_RD__single_col__WIDTH 1
+#define R_IRQ_MASK0_RD__single_col__active 1
+#define R_IRQ_MASK0_RD__single_col__inactive 0
+#define R_IRQ_MASK0_RD__congestion__BITNR 23
+#define R_IRQ_MASK0_RD__congestion__WIDTH 1
+#define R_IRQ_MASK0_RD__congestion__active 1
+#define R_IRQ_MASK0_RD__congestion__inactive 0
+#define R_IRQ_MASK0_RD__oversize__BITNR 22
+#define R_IRQ_MASK0_RD__oversize__WIDTH 1
+#define R_IRQ_MASK0_RD__oversize__active 1
+#define R_IRQ_MASK0_RD__oversize__inactive 0
+#define R_IRQ_MASK0_RD__alignment_error__BITNR 21
+#define R_IRQ_MASK0_RD__alignment_error__WIDTH 1
+#define R_IRQ_MASK0_RD__alignment_error__active 1
+#define R_IRQ_MASK0_RD__alignment_error__inactive 0
+#define R_IRQ_MASK0_RD__crc_error__BITNR 20
+#define R_IRQ_MASK0_RD__crc_error__WIDTH 1
+#define R_IRQ_MASK0_RD__crc_error__active 1
+#define R_IRQ_MASK0_RD__crc_error__inactive 0
+#define R_IRQ_MASK0_RD__overrun__BITNR 19
+#define R_IRQ_MASK0_RD__overrun__WIDTH 1
+#define R_IRQ_MASK0_RD__overrun__active 1
+#define R_IRQ_MASK0_RD__overrun__inactive 0
+#define R_IRQ_MASK0_RD__underrun__BITNR 18
+#define R_IRQ_MASK0_RD__underrun__WIDTH 1
+#define R_IRQ_MASK0_RD__underrun__active 1
+#define R_IRQ_MASK0_RD__underrun__inactive 0
+#define R_IRQ_MASK0_RD__excessive_col__BITNR 17
+#define R_IRQ_MASK0_RD__excessive_col__WIDTH 1
+#define R_IRQ_MASK0_RD__excessive_col__active 1
+#define R_IRQ_MASK0_RD__excessive_col__inactive 0
+#define R_IRQ_MASK0_RD__mdio__BITNR 16
+#define R_IRQ_MASK0_RD__mdio__WIDTH 1
+#define R_IRQ_MASK0_RD__mdio__active 1
+#define R_IRQ_MASK0_RD__mdio__inactive 0
+#define R_IRQ_MASK0_RD__ata_drq3__BITNR 15
+#define R_IRQ_MASK0_RD__ata_drq3__WIDTH 1
+#define R_IRQ_MASK0_RD__ata_drq3__active 1
+#define R_IRQ_MASK0_RD__ata_drq3__inactive 0
+#define R_IRQ_MASK0_RD__ata_drq2__BITNR 14
+#define R_IRQ_MASK0_RD__ata_drq2__WIDTH 1
+#define R_IRQ_MASK0_RD__ata_drq2__active 1
+#define R_IRQ_MASK0_RD__ata_drq2__inactive 0
+#define R_IRQ_MASK0_RD__ata_drq1__BITNR 13
+#define R_IRQ_MASK0_RD__ata_drq1__WIDTH 1
+#define R_IRQ_MASK0_RD__ata_drq1__active 1
+#define R_IRQ_MASK0_RD__ata_drq1__inactive 0
+#define R_IRQ_MASK0_RD__ata_drq0__BITNR 12
+#define R_IRQ_MASK0_RD__ata_drq0__WIDTH 1
+#define R_IRQ_MASK0_RD__ata_drq0__active 1
+#define R_IRQ_MASK0_RD__ata_drq0__inactive 0
+#define R_IRQ_MASK0_RD__par0_ecp_cmd__BITNR 11
+#define R_IRQ_MASK0_RD__par0_ecp_cmd__WIDTH 1
+#define R_IRQ_MASK0_RD__par0_ecp_cmd__active 1
+#define R_IRQ_MASK0_RD__par0_ecp_cmd__inactive 0
+#define R_IRQ_MASK0_RD__ata_irq3__BITNR 11
+#define R_IRQ_MASK0_RD__ata_irq3__WIDTH 1
+#define R_IRQ_MASK0_RD__ata_irq3__active 1
+#define R_IRQ_MASK0_RD__ata_irq3__inactive 0
+#define R_IRQ_MASK0_RD__par0_peri__BITNR 10
+#define R_IRQ_MASK0_RD__par0_peri__WIDTH 1
+#define R_IRQ_MASK0_RD__par0_peri__active 1
+#define R_IRQ_MASK0_RD__par0_peri__inactive 0
+#define R_IRQ_MASK0_RD__ata_irq2__BITNR 10
+#define R_IRQ_MASK0_RD__ata_irq2__WIDTH 1
+#define R_IRQ_MASK0_RD__ata_irq2__active 1
+#define R_IRQ_MASK0_RD__ata_irq2__inactive 0
+#define R_IRQ_MASK0_RD__p21_irq2__BITNR 10
+#define R_IRQ_MASK0_RD__p21_irq2__WIDTH 1
+#define R_IRQ_MASK0_RD__p21_irq2__active 1
+#define R_IRQ_MASK0_RD__p21_irq2__inactive 0
+#define R_IRQ_MASK0_RD__par0_data__BITNR 9
+#define R_IRQ_MASK0_RD__par0_data__WIDTH 1
+#define R_IRQ_MASK0_RD__par0_data__active 1
+#define R_IRQ_MASK0_RD__par0_data__inactive 0
+#define R_IRQ_MASK0_RD__ata_irq1__BITNR 9
+#define R_IRQ_MASK0_RD__ata_irq1__WIDTH 1
+#define R_IRQ_MASK0_RD__ata_irq1__active 1
+#define R_IRQ_MASK0_RD__ata_irq1__inactive 0
+#define R_IRQ_MASK0_RD__p21_irq1__BITNR 9
+#define R_IRQ_MASK0_RD__p21_irq1__WIDTH 1
+#define R_IRQ_MASK0_RD__p21_irq1__active 1
+#define R_IRQ_MASK0_RD__p21_irq1__inactive 0
+#define R_IRQ_MASK0_RD__par0_ready__BITNR 8
+#define R_IRQ_MASK0_RD__par0_ready__WIDTH 1
+#define R_IRQ_MASK0_RD__par0_ready__active 1
+#define R_IRQ_MASK0_RD__par0_ready__inactive 0
+#define R_IRQ_MASK0_RD__ata_irq0__BITNR 8
+#define R_IRQ_MASK0_RD__ata_irq0__WIDTH 1
+#define R_IRQ_MASK0_RD__ata_irq0__active 1
+#define R_IRQ_MASK0_RD__ata_irq0__inactive 0
+#define R_IRQ_MASK0_RD__mio__BITNR 8
+#define R_IRQ_MASK0_RD__mio__WIDTH 1
+#define R_IRQ_MASK0_RD__mio__active 1
+#define R_IRQ_MASK0_RD__mio__inactive 0
+#define R_IRQ_MASK0_RD__scsi0__BITNR 8
+#define R_IRQ_MASK0_RD__scsi0__WIDTH 1
+#define R_IRQ_MASK0_RD__scsi0__active 1
+#define R_IRQ_MASK0_RD__scsi0__inactive 0
+#define R_IRQ_MASK0_RD__p21_irq0__BITNR 8
+#define R_IRQ_MASK0_RD__p21_irq0__WIDTH 1
+#define R_IRQ_MASK0_RD__p21_irq0__active 1
+#define R_IRQ_MASK0_RD__p21_irq0__inactive 0
+#define R_IRQ_MASK0_RD__ata_dmaend__BITNR 7
+#define R_IRQ_MASK0_RD__ata_dmaend__WIDTH 1
+#define R_IRQ_MASK0_RD__ata_dmaend__active 1
+#define R_IRQ_MASK0_RD__ata_dmaend__inactive 0
+#define R_IRQ_MASK0_RD__irq_ext_vector_nr__BITNR 5
+#define R_IRQ_MASK0_RD__irq_ext_vector_nr__WIDTH 1
+#define R_IRQ_MASK0_RD__irq_ext_vector_nr__active 1
+#define R_IRQ_MASK0_RD__irq_ext_vector_nr__inactive 0
+#define R_IRQ_MASK0_RD__irq_int_vector_nr__BITNR 4
+#define R_IRQ_MASK0_RD__irq_int_vector_nr__WIDTH 1
+#define R_IRQ_MASK0_RD__irq_int_vector_nr__active 1
+#define R_IRQ_MASK0_RD__irq_int_vector_nr__inactive 0
+#define R_IRQ_MASK0_RD__ext_dma1__BITNR 3
+#define R_IRQ_MASK0_RD__ext_dma1__WIDTH 1
+#define R_IRQ_MASK0_RD__ext_dma1__active 1
+#define R_IRQ_MASK0_RD__ext_dma1__inactive 0
+#define R_IRQ_MASK0_RD__ext_dma0__BITNR 2
+#define R_IRQ_MASK0_RD__ext_dma0__WIDTH 1
+#define R_IRQ_MASK0_RD__ext_dma0__active 1
+#define R_IRQ_MASK0_RD__ext_dma0__inactive 0
+#define R_IRQ_MASK0_RD__timer1__BITNR 1
+#define R_IRQ_MASK0_RD__timer1__WIDTH 1
+#define R_IRQ_MASK0_RD__timer1__active 1
+#define R_IRQ_MASK0_RD__timer1__inactive 0
+#define R_IRQ_MASK0_RD__timer0__BITNR 0
+#define R_IRQ_MASK0_RD__timer0__WIDTH 1
+#define R_IRQ_MASK0_RD__timer0__active 1
+#define R_IRQ_MASK0_RD__timer0__inactive 0
+
+#define R_IRQ_MASK0_CLR (IO_TYPECAST_UDWORD 0xb00000c0)
+#define R_IRQ_MASK0_CLR__nmi_pin__BITNR 31
+#define R_IRQ_MASK0_CLR__nmi_pin__WIDTH 1
+#define R_IRQ_MASK0_CLR__nmi_pin__clr 1
+#define R_IRQ_MASK0_CLR__nmi_pin__nop 0
+#define R_IRQ_MASK0_CLR__watchdog_nmi__BITNR 30
+#define R_IRQ_MASK0_CLR__watchdog_nmi__WIDTH 1
+#define R_IRQ_MASK0_CLR__watchdog_nmi__clr 1
+#define R_IRQ_MASK0_CLR__watchdog_nmi__nop 0
+#define R_IRQ_MASK0_CLR__sqe_test_error__BITNR 29
+#define R_IRQ_MASK0_CLR__sqe_test_error__WIDTH 1
+#define R_IRQ_MASK0_CLR__sqe_test_error__clr 1
+#define R_IRQ_MASK0_CLR__sqe_test_error__nop 0
+#define R_IRQ_MASK0_CLR__carrier_loss__BITNR 28
+#define R_IRQ_MASK0_CLR__carrier_loss__WIDTH 1
+#define R_IRQ_MASK0_CLR__carrier_loss__clr 1
+#define R_IRQ_MASK0_CLR__carrier_loss__nop 0
+#define R_IRQ_MASK0_CLR__deferred__BITNR 27
+#define R_IRQ_MASK0_CLR__deferred__WIDTH 1
+#define R_IRQ_MASK0_CLR__deferred__clr 1
+#define R_IRQ_MASK0_CLR__deferred__nop 0
+#define R_IRQ_MASK0_CLR__late_col__BITNR 26
+#define R_IRQ_MASK0_CLR__late_col__WIDTH 1
+#define R_IRQ_MASK0_CLR__late_col__clr 1
+#define R_IRQ_MASK0_CLR__late_col__nop 0
+#define R_IRQ_MASK0_CLR__multiple_col__BITNR 25
+#define R_IRQ_MASK0_CLR__multiple_col__WIDTH 1
+#define R_IRQ_MASK0_CLR__multiple_col__clr 1
+#define R_IRQ_MASK0_CLR__multiple_col__nop 0
+#define R_IRQ_MASK0_CLR__single_col__BITNR 24
+#define R_IRQ_MASK0_CLR__single_col__WIDTH 1
+#define R_IRQ_MASK0_CLR__single_col__clr 1
+#define R_IRQ_MASK0_CLR__single_col__nop 0
+#define R_IRQ_MASK0_CLR__congestion__BITNR 23
+#define R_IRQ_MASK0_CLR__congestion__WIDTH 1
+#define R_IRQ_MASK0_CLR__congestion__clr 1
+#define R_IRQ_MASK0_CLR__congestion__nop 0
+#define R_IRQ_MASK0_CLR__oversize__BITNR 22
+#define R_IRQ_MASK0_CLR__oversize__WIDTH 1
+#define R_IRQ_MASK0_CLR__oversize__clr 1
+#define R_IRQ_MASK0_CLR__oversize__nop 0
+#define R_IRQ_MASK0_CLR__alignment_error__BITNR 21
+#define R_IRQ_MASK0_CLR__alignment_error__WIDTH 1
+#define R_IRQ_MASK0_CLR__alignment_error__clr 1
+#define R_IRQ_MASK0_CLR__alignment_error__nop 0
+#define R_IRQ_MASK0_CLR__crc_error__BITNR 20
+#define R_IRQ_MASK0_CLR__crc_error__WIDTH 1
+#define R_IRQ_MASK0_CLR__crc_error__clr 1
+#define R_IRQ_MASK0_CLR__crc_error__nop 0
+#define R_IRQ_MASK0_CLR__overrun__BITNR 19
+#define R_IRQ_MASK0_CLR__overrun__WIDTH 1
+#define R_IRQ_MASK0_CLR__overrun__clr 1
+#define R_IRQ_MASK0_CLR__overrun__nop 0
+#define R_IRQ_MASK0_CLR__underrun__BITNR 18
+#define R_IRQ_MASK0_CLR__underrun__WIDTH 1
+#define R_IRQ_MASK0_CLR__underrun__clr 1
+#define R_IRQ_MASK0_CLR__underrun__nop 0
+#define R_IRQ_MASK0_CLR__excessive_col__BITNR 17
+#define R_IRQ_MASK0_CLR__excessive_col__WIDTH 1
+#define R_IRQ_MASK0_CLR__excessive_col__clr 1
+#define R_IRQ_MASK0_CLR__excessive_col__nop 0
+#define R_IRQ_MASK0_CLR__mdio__BITNR 16
+#define R_IRQ_MASK0_CLR__mdio__WIDTH 1
+#define R_IRQ_MASK0_CLR__mdio__clr 1
+#define R_IRQ_MASK0_CLR__mdio__nop 0
+#define R_IRQ_MASK0_CLR__ata_drq3__BITNR 15
+#define R_IRQ_MASK0_CLR__ata_drq3__WIDTH 1
+#define R_IRQ_MASK0_CLR__ata_drq3__clr 1
+#define R_IRQ_MASK0_CLR__ata_drq3__nop 0
+#define R_IRQ_MASK0_CLR__ata_drq2__BITNR 14
+#define R_IRQ_MASK0_CLR__ata_drq2__WIDTH 1
+#define R_IRQ_MASK0_CLR__ata_drq2__clr 1
+#define R_IRQ_MASK0_CLR__ata_drq2__nop 0
+#define R_IRQ_MASK0_CLR__ata_drq1__BITNR 13
+#define R_IRQ_MASK0_CLR__ata_drq1__WIDTH 1
+#define R_IRQ_MASK0_CLR__ata_drq1__clr 1
+#define R_IRQ_MASK0_CLR__ata_drq1__nop 0
+#define R_IRQ_MASK0_CLR__ata_drq0__BITNR 12
+#define R_IRQ_MASK0_CLR__ata_drq0__WIDTH 1
+#define R_IRQ_MASK0_CLR__ata_drq0__clr 1
+#define R_IRQ_MASK0_CLR__ata_drq0__nop 0
+#define R_IRQ_MASK0_CLR__par0_ecp_cmd__BITNR 11
+#define R_IRQ_MASK0_CLR__par0_ecp_cmd__WIDTH 1
+#define R_IRQ_MASK0_CLR__par0_ecp_cmd__clr 1
+#define R_IRQ_MASK0_CLR__par0_ecp_cmd__nop 0
+#define R_IRQ_MASK0_CLR__ata_irq3__BITNR 11
+#define R_IRQ_MASK0_CLR__ata_irq3__WIDTH 1
+#define R_IRQ_MASK0_CLR__ata_irq3__clr 1
+#define R_IRQ_MASK0_CLR__ata_irq3__nop 0
+#define R_IRQ_MASK0_CLR__par0_peri__BITNR 10
+#define R_IRQ_MASK0_CLR__par0_peri__WIDTH 1
+#define R_IRQ_MASK0_CLR__par0_peri__clr 1
+#define R_IRQ_MASK0_CLR__par0_peri__nop 0
+#define R_IRQ_MASK0_CLR__ata_irq2__BITNR 10
+#define R_IRQ_MASK0_CLR__ata_irq2__WIDTH 1
+#define R_IRQ_MASK0_CLR__ata_irq2__clr 1
+#define R_IRQ_MASK0_CLR__ata_irq2__nop 0
+#define R_IRQ_MASK0_CLR__p21_irq2__BITNR 10
+#define R_IRQ_MASK0_CLR__p21_irq2__WIDTH 1
+#define R_IRQ_MASK0_CLR__p21_irq2__clr 1
+#define R_IRQ_MASK0_CLR__p21_irq2__nop 0
+#define R_IRQ_MASK0_CLR__par0_data__BITNR 9
+#define R_IRQ_MASK0_CLR__par0_data__WIDTH 1
+#define R_IRQ_MASK0_CLR__par0_data__clr 1
+#define R_IRQ_MASK0_CLR__par0_data__nop 0
+#define R_IRQ_MASK0_CLR__ata_irq1__BITNR 9
+#define R_IRQ_MASK0_CLR__ata_irq1__WIDTH 1
+#define R_IRQ_MASK0_CLR__ata_irq1__clr 1
+#define R_IRQ_MASK0_CLR__ata_irq1__nop 0
+#define R_IRQ_MASK0_CLR__p21_irq1__BITNR 9
+#define R_IRQ_MASK0_CLR__p21_irq1__WIDTH 1
+#define R_IRQ_MASK0_CLR__p21_irq1__clr 1
+#define R_IRQ_MASK0_CLR__p21_irq1__nop 0
+#define R_IRQ_MASK0_CLR__par0_ready__BITNR 8
+#define R_IRQ_MASK0_CLR__par0_ready__WIDTH 1
+#define R_IRQ_MASK0_CLR__par0_ready__clr 1
+#define R_IRQ_MASK0_CLR__par0_ready__nop 0
+#define R_IRQ_MASK0_CLR__ata_irq0__BITNR 8
+#define R_IRQ_MASK0_CLR__ata_irq0__WIDTH 1
+#define R_IRQ_MASK0_CLR__ata_irq0__clr 1
+#define R_IRQ_MASK0_CLR__ata_irq0__nop 0
+#define R_IRQ_MASK0_CLR__mio__BITNR 8
+#define R_IRQ_MASK0_CLR__mio__WIDTH 1
+#define R_IRQ_MASK0_CLR__mio__clr 1
+#define R_IRQ_MASK0_CLR__mio__nop 0
+#define R_IRQ_MASK0_CLR__scsi0__BITNR 8
+#define R_IRQ_MASK0_CLR__scsi0__WIDTH 1
+#define R_IRQ_MASK0_CLR__scsi0__clr 1
+#define R_IRQ_MASK0_CLR__scsi0__nop 0
+#define R_IRQ_MASK0_CLR__p21_irq0__BITNR 8
+#define R_IRQ_MASK0_CLR__p21_irq0__WIDTH 1
+#define R_IRQ_MASK0_CLR__p21_irq0__clr 1
+#define R_IRQ_MASK0_CLR__p21_irq0__nop 0
+#define R_IRQ_MASK0_CLR__ata_dmaend__BITNR 7
+#define R_IRQ_MASK0_CLR__ata_dmaend__WIDTH 1
+#define R_IRQ_MASK0_CLR__ata_dmaend__clr 1
+#define R_IRQ_MASK0_CLR__ata_dmaend__nop 0
+#define R_IRQ_MASK0_CLR__irq_ext_vector_nr__BITNR 5
+#define R_IRQ_MASK0_CLR__irq_ext_vector_nr__WIDTH 1
+#define R_IRQ_MASK0_CLR__irq_ext_vector_nr__clr 1
+#define R_IRQ_MASK0_CLR__irq_ext_vector_nr__nop 0
+#define R_IRQ_MASK0_CLR__irq_int_vector_nr__BITNR 4
+#define R_IRQ_MASK0_CLR__irq_int_vector_nr__WIDTH 1
+#define R_IRQ_MASK0_CLR__irq_int_vector_nr__clr 1
+#define R_IRQ_MASK0_CLR__irq_int_vector_nr__nop 0
+#define R_IRQ_MASK0_CLR__ext_dma1__BITNR 3
+#define R_IRQ_MASK0_CLR__ext_dma1__WIDTH 1
+#define R_IRQ_MASK0_CLR__ext_dma1__clr 1
+#define R_IRQ_MASK0_CLR__ext_dma1__nop 0
+#define R_IRQ_MASK0_CLR__ext_dma0__BITNR 2
+#define R_IRQ_MASK0_CLR__ext_dma0__WIDTH 1
+#define R_IRQ_MASK0_CLR__ext_dma0__clr 1
+#define R_IRQ_MASK0_CLR__ext_dma0__nop 0
+#define R_IRQ_MASK0_CLR__timer1__BITNR 1
+#define R_IRQ_MASK0_CLR__timer1__WIDTH 1
+#define R_IRQ_MASK0_CLR__timer1__clr 1
+#define R_IRQ_MASK0_CLR__timer1__nop 0
+#define R_IRQ_MASK0_CLR__timer0__BITNR 0
+#define R_IRQ_MASK0_CLR__timer0__WIDTH 1
+#define R_IRQ_MASK0_CLR__timer0__clr 1
+#define R_IRQ_MASK0_CLR__timer0__nop 0
+
+#define R_IRQ_READ0 (IO_TYPECAST_RO_UDWORD 0xb00000c4)
+#define R_IRQ_READ0__nmi_pin__BITNR 31
+#define R_IRQ_READ0__nmi_pin__WIDTH 1
+#define R_IRQ_READ0__nmi_pin__active 1
+#define R_IRQ_READ0__nmi_pin__inactive 0
+#define R_IRQ_READ0__watchdog_nmi__BITNR 30
+#define R_IRQ_READ0__watchdog_nmi__WIDTH 1
+#define R_IRQ_READ0__watchdog_nmi__active 1
+#define R_IRQ_READ0__watchdog_nmi__inactive 0
+#define R_IRQ_READ0__sqe_test_error__BITNR 29
+#define R_IRQ_READ0__sqe_test_error__WIDTH 1
+#define R_IRQ_READ0__sqe_test_error__active 1
+#define R_IRQ_READ0__sqe_test_error__inactive 0
+#define R_IRQ_READ0__carrier_loss__BITNR 28
+#define R_IRQ_READ0__carrier_loss__WIDTH 1
+#define R_IRQ_READ0__carrier_loss__active 1
+#define R_IRQ_READ0__carrier_loss__inactive 0
+#define R_IRQ_READ0__deferred__BITNR 27
+#define R_IRQ_READ0__deferred__WIDTH 1
+#define R_IRQ_READ0__deferred__active 1
+#define R_IRQ_READ0__deferred__inactive 0
+#define R_IRQ_READ0__late_col__BITNR 26
+#define R_IRQ_READ0__late_col__WIDTH 1
+#define R_IRQ_READ0__late_col__active 1
+#define R_IRQ_READ0__late_col__inactive 0
+#define R_IRQ_READ0__multiple_col__BITNR 25
+#define R_IRQ_READ0__multiple_col__WIDTH 1
+#define R_IRQ_READ0__multiple_col__active 1
+#define R_IRQ_READ0__multiple_col__inactive 0
+#define R_IRQ_READ0__single_col__BITNR 24
+#define R_IRQ_READ0__single_col__WIDTH 1
+#define R_IRQ_READ0__single_col__active 1
+#define R_IRQ_READ0__single_col__inactive 0
+#define R_IRQ_READ0__congestion__BITNR 23
+#define R_IRQ_READ0__congestion__WIDTH 1
+#define R_IRQ_READ0__congestion__active 1
+#define R_IRQ_READ0__congestion__inactive 0
+#define R_IRQ_READ0__oversize__BITNR 22
+#define R_IRQ_READ0__oversize__WIDTH 1
+#define R_IRQ_READ0__oversize__active 1
+#define R_IRQ_READ0__oversize__inactive 0
+#define R_IRQ_READ0__alignment_error__BITNR 21
+#define R_IRQ_READ0__alignment_error__WIDTH 1
+#define R_IRQ_READ0__alignment_error__active 1
+#define R_IRQ_READ0__alignment_error__inactive 0
+#define R_IRQ_READ0__crc_error__BITNR 20
+#define R_IRQ_READ0__crc_error__WIDTH 1
+#define R_IRQ_READ0__crc_error__active 1
+#define R_IRQ_READ0__crc_error__inactive 0
+#define R_IRQ_READ0__overrun__BITNR 19
+#define R_IRQ_READ0__overrun__WIDTH 1
+#define R_IRQ_READ0__overrun__active 1
+#define R_IRQ_READ0__overrun__inactive 0
+#define R_IRQ_READ0__underrun__BITNR 18
+#define R_IRQ_READ0__underrun__WIDTH 1
+#define R_IRQ_READ0__underrun__active 1
+#define R_IRQ_READ0__underrun__inactive 0
+#define R_IRQ_READ0__excessive_col__BITNR 17
+#define R_IRQ_READ0__excessive_col__WIDTH 1
+#define R_IRQ_READ0__excessive_col__active 1
+#define R_IRQ_READ0__excessive_col__inactive 0
+#define R_IRQ_READ0__mdio__BITNR 16
+#define R_IRQ_READ0__mdio__WIDTH 1
+#define R_IRQ_READ0__mdio__active 1
+#define R_IRQ_READ0__mdio__inactive 0
+#define R_IRQ_READ0__ata_drq3__BITNR 15
+#define R_IRQ_READ0__ata_drq3__WIDTH 1
+#define R_IRQ_READ0__ata_drq3__active 1
+#define R_IRQ_READ0__ata_drq3__inactive 0
+#define R_IRQ_READ0__ata_drq2__BITNR 14
+#define R_IRQ_READ0__ata_drq2__WIDTH 1
+#define R_IRQ_READ0__ata_drq2__active 1
+#define R_IRQ_READ0__ata_drq2__inactive 0
+#define R_IRQ_READ0__ata_drq1__BITNR 13
+#define R_IRQ_READ0__ata_drq1__WIDTH 1
+#define R_IRQ_READ0__ata_drq1__active 1
+#define R_IRQ_READ0__ata_drq1__inactive 0
+#define R_IRQ_READ0__ata_drq0__BITNR 12
+#define R_IRQ_READ0__ata_drq0__WIDTH 1
+#define R_IRQ_READ0__ata_drq0__active 1
+#define R_IRQ_READ0__ata_drq0__inactive 0
+#define R_IRQ_READ0__par0_ecp_cmd__BITNR 11
+#define R_IRQ_READ0__par0_ecp_cmd__WIDTH 1
+#define R_IRQ_READ0__par0_ecp_cmd__active 1
+#define R_IRQ_READ0__par0_ecp_cmd__inactive 0
+#define R_IRQ_READ0__ata_irq3__BITNR 11
+#define R_IRQ_READ0__ata_irq3__WIDTH 1
+#define R_IRQ_READ0__ata_irq3__active 1
+#define R_IRQ_READ0__ata_irq3__inactive 0
+#define R_IRQ_READ0__par0_peri__BITNR 10
+#define R_IRQ_READ0__par0_peri__WIDTH 1
+#define R_IRQ_READ0__par0_peri__active 1
+#define R_IRQ_READ0__par0_peri__inactive 0
+#define R_IRQ_READ0__ata_irq2__BITNR 10
+#define R_IRQ_READ0__ata_irq2__WIDTH 1
+#define R_IRQ_READ0__ata_irq2__active 1
+#define R_IRQ_READ0__ata_irq2__inactive 0
+#define R_IRQ_READ0__p21_irq2__BITNR 10
+#define R_IRQ_READ0__p21_irq2__WIDTH 1
+#define R_IRQ_READ0__p21_irq2__active 1
+#define R_IRQ_READ0__p21_irq2__inactive 0
+#define R_IRQ_READ0__par0_data__BITNR 9
+#define R_IRQ_READ0__par0_data__WIDTH 1
+#define R_IRQ_READ0__par0_data__active 1
+#define R_IRQ_READ0__par0_data__inactive 0
+#define R_IRQ_READ0__ata_irq1__BITNR 9
+#define R_IRQ_READ0__ata_irq1__WIDTH 1
+#define R_IRQ_READ0__ata_irq1__active 1
+#define R_IRQ_READ0__ata_irq1__inactive 0
+#define R_IRQ_READ0__p21_irq1__BITNR 9
+#define R_IRQ_READ0__p21_irq1__WIDTH 1
+#define R_IRQ_READ0__p21_irq1__active 1
+#define R_IRQ_READ0__p21_irq1__inactive 0
+#define R_IRQ_READ0__par0_ready__BITNR 8
+#define R_IRQ_READ0__par0_ready__WIDTH 1
+#define R_IRQ_READ0__par0_ready__active 1
+#define R_IRQ_READ0__par0_ready__inactive 0
+#define R_IRQ_READ0__ata_irq0__BITNR 8
+#define R_IRQ_READ0__ata_irq0__WIDTH 1
+#define R_IRQ_READ0__ata_irq0__active 1
+#define R_IRQ_READ0__ata_irq0__inactive 0
+#define R_IRQ_READ0__mio__BITNR 8
+#define R_IRQ_READ0__mio__WIDTH 1
+#define R_IRQ_READ0__mio__active 1
+#define R_IRQ_READ0__mio__inactive 0
+#define R_IRQ_READ0__scsi0__BITNR 8
+#define R_IRQ_READ0__scsi0__WIDTH 1
+#define R_IRQ_READ0__scsi0__active 1
+#define R_IRQ_READ0__scsi0__inactive 0
+#define R_IRQ_READ0__p21_irq0__BITNR 8
+#define R_IRQ_READ0__p21_irq0__WIDTH 1
+#define R_IRQ_READ0__p21_irq0__active 1
+#define R_IRQ_READ0__p21_irq0__inactive 0
+#define R_IRQ_READ0__ata_dmaend__BITNR 7
+#define R_IRQ_READ0__ata_dmaend__WIDTH 1
+#define R_IRQ_READ0__ata_dmaend__active 1
+#define R_IRQ_READ0__ata_dmaend__inactive 0
+#define R_IRQ_READ0__irq_ext_vector_nr__BITNR 5
+#define R_IRQ_READ0__irq_ext_vector_nr__WIDTH 1
+#define R_IRQ_READ0__irq_ext_vector_nr__active 1
+#define R_IRQ_READ0__irq_ext_vector_nr__inactive 0
+#define R_IRQ_READ0__irq_int_vector_nr__BITNR 4
+#define R_IRQ_READ0__irq_int_vector_nr__WIDTH 1
+#define R_IRQ_READ0__irq_int_vector_nr__active 1
+#define R_IRQ_READ0__irq_int_vector_nr__inactive 0
+#define R_IRQ_READ0__ext_dma1__BITNR 3
+#define R_IRQ_READ0__ext_dma1__WIDTH 1
+#define R_IRQ_READ0__ext_dma1__active 1
+#define R_IRQ_READ0__ext_dma1__inactive 0
+#define R_IRQ_READ0__ext_dma0__BITNR 2
+#define R_IRQ_READ0__ext_dma0__WIDTH 1
+#define R_IRQ_READ0__ext_dma0__active 1
+#define R_IRQ_READ0__ext_dma0__inactive 0
+#define R_IRQ_READ0__timer1__BITNR 1
+#define R_IRQ_READ0__timer1__WIDTH 1
+#define R_IRQ_READ0__timer1__active 1
+#define R_IRQ_READ0__timer1__inactive 0
+#define R_IRQ_READ0__timer0__BITNR 0
+#define R_IRQ_READ0__timer0__WIDTH 1
+#define R_IRQ_READ0__timer0__active 1
+#define R_IRQ_READ0__timer0__inactive 0
+
+#define R_IRQ_MASK0_SET (IO_TYPECAST_UDWORD 0xb00000c4)
+#define R_IRQ_MASK0_SET__nmi_pin__BITNR 31
+#define R_IRQ_MASK0_SET__nmi_pin__WIDTH 1
+#define R_IRQ_MASK0_SET__nmi_pin__set 1
+#define R_IRQ_MASK0_SET__nmi_pin__nop 0
+#define R_IRQ_MASK0_SET__watchdog_nmi__BITNR 30
+#define R_IRQ_MASK0_SET__watchdog_nmi__WIDTH 1
+#define R_IRQ_MASK0_SET__watchdog_nmi__set 1
+#define R_IRQ_MASK0_SET__watchdog_nmi__nop 0
+#define R_IRQ_MASK0_SET__sqe_test_error__BITNR 29
+#define R_IRQ_MASK0_SET__sqe_test_error__WIDTH 1
+#define R_IRQ_MASK0_SET__sqe_test_error__set 1
+#define R_IRQ_MASK0_SET__sqe_test_error__nop 0
+#define R_IRQ_MASK0_SET__carrier_loss__BITNR 28
+#define R_IRQ_MASK0_SET__carrier_loss__WIDTH 1
+#define R_IRQ_MASK0_SET__carrier_loss__set 1
+#define R_IRQ_MASK0_SET__carrier_loss__nop 0
+#define R_IRQ_MASK0_SET__deferred__BITNR 27
+#define R_IRQ_MASK0_SET__deferred__WIDTH 1
+#define R_IRQ_MASK0_SET__deferred__set 1
+#define R_IRQ_MASK0_SET__deferred__nop 0
+#define R_IRQ_MASK0_SET__late_col__BITNR 26
+#define R_IRQ_MASK0_SET__late_col__WIDTH 1
+#define R_IRQ_MASK0_SET__late_col__set 1
+#define R_IRQ_MASK0_SET__late_col__nop 0
+#define R_IRQ_MASK0_SET__multiple_col__BITNR 25
+#define R_IRQ_MASK0_SET__multiple_col__WIDTH 1
+#define R_IRQ_MASK0_SET__multiple_col__set 1
+#define R_IRQ_MASK0_SET__multiple_col__nop 0
+#define R_IRQ_MASK0_SET__single_col__BITNR 24
+#define R_IRQ_MASK0_SET__single_col__WIDTH 1
+#define R_IRQ_MASK0_SET__single_col__set 1
+#define R_IRQ_MASK0_SET__single_col__nop 0
+#define R_IRQ_MASK0_SET__congestion__BITNR 23
+#define R_IRQ_MASK0_SET__congestion__WIDTH 1
+#define R_IRQ_MASK0_SET__congestion__set 1
+#define R_IRQ_MASK0_SET__congestion__nop 0
+#define R_IRQ_MASK0_SET__oversize__BITNR 22
+#define R_IRQ_MASK0_SET__oversize__WIDTH 1
+#define R_IRQ_MASK0_SET__oversize__set 1
+#define R_IRQ_MASK0_SET__oversize__nop 0
+#define R_IRQ_MASK0_SET__alignment_error__BITNR 21
+#define R_IRQ_MASK0_SET__alignment_error__WIDTH 1
+#define R_IRQ_MASK0_SET__alignment_error__set 1
+#define R_IRQ_MASK0_SET__alignment_error__nop 0
+#define R_IRQ_MASK0_SET__crc_error__BITNR 20
+#define R_IRQ_MASK0_SET__crc_error__WIDTH 1
+#define R_IRQ_MASK0_SET__crc_error__set 1
+#define R_IRQ_MASK0_SET__crc_error__nop 0
+#define R_IRQ_MASK0_SET__overrun__BITNR 19
+#define R_IRQ_MASK0_SET__overrun__WIDTH 1
+#define R_IRQ_MASK0_SET__overrun__set 1
+#define R_IRQ_MASK0_SET__overrun__nop 0
+#define R_IRQ_MASK0_SET__underrun__BITNR 18
+#define R_IRQ_MASK0_SET__underrun__WIDTH 1
+#define R_IRQ_MASK0_SET__underrun__set 1
+#define R_IRQ_MASK0_SET__underrun__nop 0
+#define R_IRQ_MASK0_SET__excessive_col__BITNR 17
+#define R_IRQ_MASK0_SET__excessive_col__WIDTH 1
+#define R_IRQ_MASK0_SET__excessive_col__set 1
+#define R_IRQ_MASK0_SET__excessive_col__nop 0
+#define R_IRQ_MASK0_SET__mdio__BITNR 16
+#define R_IRQ_MASK0_SET__mdio__WIDTH 1
+#define R_IRQ_MASK0_SET__mdio__set 1
+#define R_IRQ_MASK0_SET__mdio__nop 0
+#define R_IRQ_MASK0_SET__ata_drq3__BITNR 15
+#define R_IRQ_MASK0_SET__ata_drq3__WIDTH 1
+#define R_IRQ_MASK0_SET__ata_drq3__set 1
+#define R_IRQ_MASK0_SET__ata_drq3__nop 0
+#define R_IRQ_MASK0_SET__ata_drq2__BITNR 14
+#define R_IRQ_MASK0_SET__ata_drq2__WIDTH 1
+#define R_IRQ_MASK0_SET__ata_drq2__set 1
+#define R_IRQ_MASK0_SET__ata_drq2__nop 0
+#define R_IRQ_MASK0_SET__ata_drq1__BITNR 13
+#define R_IRQ_MASK0_SET__ata_drq1__WIDTH 1
+#define R_IRQ_MASK0_SET__ata_drq1__set 1
+#define R_IRQ_MASK0_SET__ata_drq1__nop 0
+#define R_IRQ_MASK0_SET__ata_drq0__BITNR 12
+#define R_IRQ_MASK0_SET__ata_drq0__WIDTH 1
+#define R_IRQ_MASK0_SET__ata_drq0__set 1
+#define R_IRQ_MASK0_SET__ata_drq0__nop 0
+#define R_IRQ_MASK0_SET__par0_ecp_cmd__BITNR 11
+#define R_IRQ_MASK0_SET__par0_ecp_cmd__WIDTH 1
+#define R_IRQ_MASK0_SET__par0_ecp_cmd__set 1
+#define R_IRQ_MASK0_SET__par0_ecp_cmd__nop 0
+#define R_IRQ_MASK0_SET__ata_irq3__BITNR 11
+#define R_IRQ_MASK0_SET__ata_irq3__WIDTH 1
+#define R_IRQ_MASK0_SET__ata_irq3__set 1
+#define R_IRQ_MASK0_SET__ata_irq3__nop 0
+#define R_IRQ_MASK0_SET__par0_peri__BITNR 10
+#define R_IRQ_MASK0_SET__par0_peri__WIDTH 1
+#define R_IRQ_MASK0_SET__par0_peri__set 1
+#define R_IRQ_MASK0_SET__par0_peri__nop 0
+#define R_IRQ_MASK0_SET__ata_irq2__BITNR 10
+#define R_IRQ_MASK0_SET__ata_irq2__WIDTH 1
+#define R_IRQ_MASK0_SET__ata_irq2__set 1
+#define R_IRQ_MASK0_SET__ata_irq2__nop 0
+#define R_IRQ_MASK0_SET__p21_irq2__BITNR 10
+#define R_IRQ_MASK0_SET__p21_irq2__WIDTH 1
+#define R_IRQ_MASK0_SET__p21_irq2__set 1
+#define R_IRQ_MASK0_SET__p21_irq2__nop 0
+#define R_IRQ_MASK0_SET__par0_data__BITNR 9
+#define R_IRQ_MASK0_SET__par0_data__WIDTH 1
+#define R_IRQ_MASK0_SET__par0_data__set 1
+#define R_IRQ_MASK0_SET__par0_data__nop 0
+#define R_IRQ_MASK0_SET__ata_irq1__BITNR 9
+#define R_IRQ_MASK0_SET__ata_irq1__WIDTH 1
+#define R_IRQ_MASK0_SET__ata_irq1__set 1
+#define R_IRQ_MASK0_SET__ata_irq1__nop 0
+#define R_IRQ_MASK0_SET__p21_irq1__BITNR 9
+#define R_IRQ_MASK0_SET__p21_irq1__WIDTH 1
+#define R_IRQ_MASK0_SET__p21_irq1__set 1
+#define R_IRQ_MASK0_SET__p21_irq1__nop 0
+#define R_IRQ_MASK0_SET__par0_ready__BITNR 8
+#define R_IRQ_MASK0_SET__par0_ready__WIDTH 1
+#define R_IRQ_MASK0_SET__par0_ready__set 1
+#define R_IRQ_MASK0_SET__par0_ready__nop 0
+#define R_IRQ_MASK0_SET__ata_irq0__BITNR 8
+#define R_IRQ_MASK0_SET__ata_irq0__WIDTH 1
+#define R_IRQ_MASK0_SET__ata_irq0__set 1
+#define R_IRQ_MASK0_SET__ata_irq0__nop 0
+#define R_IRQ_MASK0_SET__mio__BITNR 8
+#define R_IRQ_MASK0_SET__mio__WIDTH 1
+#define R_IRQ_MASK0_SET__mio__set 1
+#define R_IRQ_MASK0_SET__mio__nop 0
+#define R_IRQ_MASK0_SET__scsi0__BITNR 8
+#define R_IRQ_MASK0_SET__scsi0__WIDTH 1
+#define R_IRQ_MASK0_SET__scsi0__set 1
+#define R_IRQ_MASK0_SET__scsi0__nop 0
+#define R_IRQ_MASK0_SET__p21_irq0__BITNR 8
+#define R_IRQ_MASK0_SET__p21_irq0__WIDTH 1
+#define R_IRQ_MASK0_SET__p21_irq0__set 1
+#define R_IRQ_MASK0_SET__p21_irq0__nop 0
+#define R_IRQ_MASK0_SET__ata_dmaend__BITNR 7
+#define R_IRQ_MASK0_SET__ata_dmaend__WIDTH 1
+#define R_IRQ_MASK0_SET__ata_dmaend__set 1
+#define R_IRQ_MASK0_SET__ata_dmaend__nop 0
+#define R_IRQ_MASK0_SET__irq_ext_vector_nr__BITNR 5
+#define R_IRQ_MASK0_SET__irq_ext_vector_nr__WIDTH 1
+#define R_IRQ_MASK0_SET__irq_ext_vector_nr__set 1
+#define R_IRQ_MASK0_SET__irq_ext_vector_nr__nop 0
+#define R_IRQ_MASK0_SET__irq_int_vector_nr__BITNR 4
+#define R_IRQ_MASK0_SET__irq_int_vector_nr__WIDTH 1
+#define R_IRQ_MASK0_SET__irq_int_vector_nr__set 1
+#define R_IRQ_MASK0_SET__irq_int_vector_nr__nop 0
+#define R_IRQ_MASK0_SET__ext_dma1__BITNR 3
+#define R_IRQ_MASK0_SET__ext_dma1__WIDTH 1
+#define R_IRQ_MASK0_SET__ext_dma1__set 1
+#define R_IRQ_MASK0_SET__ext_dma1__nop 0
+#define R_IRQ_MASK0_SET__ext_dma0__BITNR 2
+#define R_IRQ_MASK0_SET__ext_dma0__WIDTH 1
+#define R_IRQ_MASK0_SET__ext_dma0__set 1
+#define R_IRQ_MASK0_SET__ext_dma0__nop 0
+#define R_IRQ_MASK0_SET__timer1__BITNR 1
+#define R_IRQ_MASK0_SET__timer1__WIDTH 1
+#define R_IRQ_MASK0_SET__timer1__set 1
+#define R_IRQ_MASK0_SET__timer1__nop 0
+#define R_IRQ_MASK0_SET__timer0__BITNR 0
+#define R_IRQ_MASK0_SET__timer0__WIDTH 1
+#define R_IRQ_MASK0_SET__timer0__set 1
+#define R_IRQ_MASK0_SET__timer0__nop 0
+
+#define R_IRQ_MASK1_RD (IO_TYPECAST_RO_UDWORD 0xb00000c8)
+#define R_IRQ_MASK1_RD__sw_int7__BITNR 31
+#define R_IRQ_MASK1_RD__sw_int7__WIDTH 1
+#define R_IRQ_MASK1_RD__sw_int7__active 1
+#define R_IRQ_MASK1_RD__sw_int7__inactive 0
+#define R_IRQ_MASK1_RD__sw_int6__BITNR 30
+#define R_IRQ_MASK1_RD__sw_int6__WIDTH 1
+#define R_IRQ_MASK1_RD__sw_int6__active 1
+#define R_IRQ_MASK1_RD__sw_int6__inactive 0
+#define R_IRQ_MASK1_RD__sw_int5__BITNR 29
+#define R_IRQ_MASK1_RD__sw_int5__WIDTH 1
+#define R_IRQ_MASK1_RD__sw_int5__active 1
+#define R_IRQ_MASK1_RD__sw_int5__inactive 0
+#define R_IRQ_MASK1_RD__sw_int4__BITNR 28
+#define R_IRQ_MASK1_RD__sw_int4__WIDTH 1
+#define R_IRQ_MASK1_RD__sw_int4__active 1
+#define R_IRQ_MASK1_RD__sw_int4__inactive 0
+#define R_IRQ_MASK1_RD__sw_int3__BITNR 27
+#define R_IRQ_MASK1_RD__sw_int3__WIDTH 1
+#define R_IRQ_MASK1_RD__sw_int3__active 1
+#define R_IRQ_MASK1_RD__sw_int3__inactive 0
+#define R_IRQ_MASK1_RD__sw_int2__BITNR 26
+#define R_IRQ_MASK1_RD__sw_int2__WIDTH 1
+#define R_IRQ_MASK1_RD__sw_int2__active 1
+#define R_IRQ_MASK1_RD__sw_int2__inactive 0
+#define R_IRQ_MASK1_RD__sw_int1__BITNR 25
+#define R_IRQ_MASK1_RD__sw_int1__WIDTH 1
+#define R_IRQ_MASK1_RD__sw_int1__active 1
+#define R_IRQ_MASK1_RD__sw_int1__inactive 0
+#define R_IRQ_MASK1_RD__sw_int0__BITNR 24
+#define R_IRQ_MASK1_RD__sw_int0__WIDTH 1
+#define R_IRQ_MASK1_RD__sw_int0__active 1
+#define R_IRQ_MASK1_RD__sw_int0__inactive 0
+#define R_IRQ_MASK1_RD__par1_ecp_cmd__BITNR 19
+#define R_IRQ_MASK1_RD__par1_ecp_cmd__WIDTH 1
+#define R_IRQ_MASK1_RD__par1_ecp_cmd__active 1
+#define R_IRQ_MASK1_RD__par1_ecp_cmd__inactive 0
+#define R_IRQ_MASK1_RD__par1_peri__BITNR 18
+#define R_IRQ_MASK1_RD__par1_peri__WIDTH 1
+#define R_IRQ_MASK1_RD__par1_peri__active 1
+#define R_IRQ_MASK1_RD__par1_peri__inactive 0
+#define R_IRQ_MASK1_RD__par1_data__BITNR 17
+#define R_IRQ_MASK1_RD__par1_data__WIDTH 1
+#define R_IRQ_MASK1_RD__par1_data__active 1
+#define R_IRQ_MASK1_RD__par1_data__inactive 0
+#define R_IRQ_MASK1_RD__par1_ready__BITNR 16
+#define R_IRQ_MASK1_RD__par1_ready__WIDTH 1
+#define R_IRQ_MASK1_RD__par1_ready__active 1
+#define R_IRQ_MASK1_RD__par1_ready__inactive 0
+#define R_IRQ_MASK1_RD__scsi1__BITNR 16
+#define R_IRQ_MASK1_RD__scsi1__WIDTH 1
+#define R_IRQ_MASK1_RD__scsi1__active 1
+#define R_IRQ_MASK1_RD__scsi1__inactive 0
+#define R_IRQ_MASK1_RD__ser3_ready__BITNR 15
+#define R_IRQ_MASK1_RD__ser3_ready__WIDTH 1
+#define R_IRQ_MASK1_RD__ser3_ready__active 1
+#define R_IRQ_MASK1_RD__ser3_ready__inactive 0
+#define R_IRQ_MASK1_RD__ser3_data__BITNR 14
+#define R_IRQ_MASK1_RD__ser3_data__WIDTH 1
+#define R_IRQ_MASK1_RD__ser3_data__active 1
+#define R_IRQ_MASK1_RD__ser3_data__inactive 0
+#define R_IRQ_MASK1_RD__ser2_ready__BITNR 13
+#define R_IRQ_MASK1_RD__ser2_ready__WIDTH 1
+#define R_IRQ_MASK1_RD__ser2_ready__active 1
+#define R_IRQ_MASK1_RD__ser2_ready__inactive 0
+#define R_IRQ_MASK1_RD__ser2_data__BITNR 12
+#define R_IRQ_MASK1_RD__ser2_data__WIDTH 1
+#define R_IRQ_MASK1_RD__ser2_data__active 1
+#define R_IRQ_MASK1_RD__ser2_data__inactive 0
+#define R_IRQ_MASK1_RD__ser1_ready__BITNR 11
+#define R_IRQ_MASK1_RD__ser1_ready__WIDTH 1
+#define R_IRQ_MASK1_RD__ser1_ready__active 1
+#define R_IRQ_MASK1_RD__ser1_ready__inactive 0
+#define R_IRQ_MASK1_RD__ser1_data__BITNR 10
+#define R_IRQ_MASK1_RD__ser1_data__WIDTH 1
+#define R_IRQ_MASK1_RD__ser1_data__active 1
+#define R_IRQ_MASK1_RD__ser1_data__inactive 0
+#define R_IRQ_MASK1_RD__ser0_ready__BITNR 9
+#define R_IRQ_MASK1_RD__ser0_ready__WIDTH 1
+#define R_IRQ_MASK1_RD__ser0_ready__active 1
+#define R_IRQ_MASK1_RD__ser0_ready__inactive 0
+#define R_IRQ_MASK1_RD__ser0_data__BITNR 8
+#define R_IRQ_MASK1_RD__ser0_data__WIDTH 1
+#define R_IRQ_MASK1_RD__ser0_data__active 1
+#define R_IRQ_MASK1_RD__ser0_data__inactive 0
+#define R_IRQ_MASK1_RD__pa7__BITNR 7
+#define R_IRQ_MASK1_RD__pa7__WIDTH 1
+#define R_IRQ_MASK1_RD__pa7__active 1
+#define R_IRQ_MASK1_RD__pa7__inactive 0
+#define R_IRQ_MASK1_RD__pa6__BITNR 6
+#define R_IRQ_MASK1_RD__pa6__WIDTH 1
+#define R_IRQ_MASK1_RD__pa6__active 1
+#define R_IRQ_MASK1_RD__pa6__inactive 0
+#define R_IRQ_MASK1_RD__pa5__BITNR 5
+#define R_IRQ_MASK1_RD__pa5__WIDTH 1
+#define R_IRQ_MASK1_RD__pa5__active 1
+#define R_IRQ_MASK1_RD__pa5__inactive 0
+#define R_IRQ_MASK1_RD__pa4__BITNR 4
+#define R_IRQ_MASK1_RD__pa4__WIDTH 1
+#define R_IRQ_MASK1_RD__pa4__active 1
+#define R_IRQ_MASK1_RD__pa4__inactive 0
+#define R_IRQ_MASK1_RD__pa3__BITNR 3
+#define R_IRQ_MASK1_RD__pa3__WIDTH 1
+#define R_IRQ_MASK1_RD__pa3__active 1
+#define R_IRQ_MASK1_RD__pa3__inactive 0
+#define R_IRQ_MASK1_RD__pa2__BITNR 2
+#define R_IRQ_MASK1_RD__pa2__WIDTH 1
+#define R_IRQ_MASK1_RD__pa2__active 1
+#define R_IRQ_MASK1_RD__pa2__inactive 0
+#define R_IRQ_MASK1_RD__pa1__BITNR 1
+#define R_IRQ_MASK1_RD__pa1__WIDTH 1
+#define R_IRQ_MASK1_RD__pa1__active 1
+#define R_IRQ_MASK1_RD__pa1__inactive 0
+#define R_IRQ_MASK1_RD__pa0__BITNR 0
+#define R_IRQ_MASK1_RD__pa0__WIDTH 1
+#define R_IRQ_MASK1_RD__pa0__active 1
+#define R_IRQ_MASK1_RD__pa0__inactive 0
+
+#define R_IRQ_MASK1_CLR (IO_TYPECAST_UDWORD 0xb00000c8)
+#define R_IRQ_MASK1_CLR__sw_int7__BITNR 31
+#define R_IRQ_MASK1_CLR__sw_int7__WIDTH 1
+#define R_IRQ_MASK1_CLR__sw_int7__clr 1
+#define R_IRQ_MASK1_CLR__sw_int7__nop 0
+#define R_IRQ_MASK1_CLR__sw_int6__BITNR 30
+#define R_IRQ_MASK1_CLR__sw_int6__WIDTH 1
+#define R_IRQ_MASK1_CLR__sw_int6__clr 1
+#define R_IRQ_MASK1_CLR__sw_int6__nop 0
+#define R_IRQ_MASK1_CLR__sw_int5__BITNR 29
+#define R_IRQ_MASK1_CLR__sw_int5__WIDTH 1
+#define R_IRQ_MASK1_CLR__sw_int5__clr 1
+#define R_IRQ_MASK1_CLR__sw_int5__nop 0
+#define R_IRQ_MASK1_CLR__sw_int4__BITNR 28
+#define R_IRQ_MASK1_CLR__sw_int4__WIDTH 1
+#define R_IRQ_MASK1_CLR__sw_int4__clr 1
+#define R_IRQ_MASK1_CLR__sw_int4__nop 0
+#define R_IRQ_MASK1_CLR__sw_int3__BITNR 27
+#define R_IRQ_MASK1_CLR__sw_int3__WIDTH 1
+#define R_IRQ_MASK1_CLR__sw_int3__clr 1
+#define R_IRQ_MASK1_CLR__sw_int3__nop 0
+#define R_IRQ_MASK1_CLR__sw_int2__BITNR 26
+#define R_IRQ_MASK1_CLR__sw_int2__WIDTH 1
+#define R_IRQ_MASK1_CLR__sw_int2__clr 1
+#define R_IRQ_MASK1_CLR__sw_int2__nop 0
+#define R_IRQ_MASK1_CLR__sw_int1__BITNR 25
+#define R_IRQ_MASK1_CLR__sw_int1__WIDTH 1
+#define R_IRQ_MASK1_CLR__sw_int1__clr 1
+#define R_IRQ_MASK1_CLR__sw_int1__nop 0
+#define R_IRQ_MASK1_CLR__sw_int0__BITNR 24
+#define R_IRQ_MASK1_CLR__sw_int0__WIDTH 1
+#define R_IRQ_MASK1_CLR__sw_int0__clr 1
+#define R_IRQ_MASK1_CLR__sw_int0__nop 0
+#define R_IRQ_MASK1_CLR__par1_ecp_cmd__BITNR 19
+#define R_IRQ_MASK1_CLR__par1_ecp_cmd__WIDTH 1
+#define R_IRQ_MASK1_CLR__par1_ecp_cmd__clr 1
+#define R_IRQ_MASK1_CLR__par1_ecp_cmd__nop 0
+#define R_IRQ_MASK1_CLR__par1_peri__BITNR 18
+#define R_IRQ_MASK1_CLR__par1_peri__WIDTH 1
+#define R_IRQ_MASK1_CLR__par1_peri__clr 1
+#define R_IRQ_MASK1_CLR__par1_peri__nop 0
+#define R_IRQ_MASK1_CLR__par1_data__BITNR 17
+#define R_IRQ_MASK1_CLR__par1_data__WIDTH 1
+#define R_IRQ_MASK1_CLR__par1_data__clr 1
+#define R_IRQ_MASK1_CLR__par1_data__nop 0
+#define R_IRQ_MASK1_CLR__par1_ready__BITNR 16
+#define R_IRQ_MASK1_CLR__par1_ready__WIDTH 1
+#define R_IRQ_MASK1_CLR__par1_ready__clr 1
+#define R_IRQ_MASK1_CLR__par1_ready__nop 0
+#define R_IRQ_MASK1_CLR__scsi1__BITNR 16
+#define R_IRQ_MASK1_CLR__scsi1__WIDTH 1
+#define R_IRQ_MASK1_CLR__scsi1__clr 1
+#define R_IRQ_MASK1_CLR__scsi1__nop 0
+#define R_IRQ_MASK1_CLR__ser3_ready__BITNR 15
+#define R_IRQ_MASK1_CLR__ser3_ready__WIDTH 1
+#define R_IRQ_MASK1_CLR__ser3_ready__clr 1
+#define R_IRQ_MASK1_CLR__ser3_ready__nop 0
+#define R_IRQ_MASK1_CLR__ser3_data__BITNR 14
+#define R_IRQ_MASK1_CLR__ser3_data__WIDTH 1
+#define R_IRQ_MASK1_CLR__ser3_data__clr 1
+#define R_IRQ_MASK1_CLR__ser3_data__nop 0
+#define R_IRQ_MASK1_CLR__ser2_ready__BITNR 13
+#define R_IRQ_MASK1_CLR__ser2_ready__WIDTH 1
+#define R_IRQ_MASK1_CLR__ser2_ready__clr 1
+#define R_IRQ_MASK1_CLR__ser2_ready__nop 0
+#define R_IRQ_MASK1_CLR__ser2_data__BITNR 12
+#define R_IRQ_MASK1_CLR__ser2_data__WIDTH 1
+#define R_IRQ_MASK1_CLR__ser2_data__clr 1
+#define R_IRQ_MASK1_CLR__ser2_data__nop 0
+#define R_IRQ_MASK1_CLR__ser1_ready__BITNR 11
+#define R_IRQ_MASK1_CLR__ser1_ready__WIDTH 1
+#define R_IRQ_MASK1_CLR__ser1_ready__clr 1
+#define R_IRQ_MASK1_CLR__ser1_ready__nop 0
+#define R_IRQ_MASK1_CLR__ser1_data__BITNR 10
+#define R_IRQ_MASK1_CLR__ser1_data__WIDTH 1
+#define R_IRQ_MASK1_CLR__ser1_data__clr 1
+#define R_IRQ_MASK1_CLR__ser1_data__nop 0
+#define R_IRQ_MASK1_CLR__ser0_ready__BITNR 9
+#define R_IRQ_MASK1_CLR__ser0_ready__WIDTH 1
+#define R_IRQ_MASK1_CLR__ser0_ready__clr 1
+#define R_IRQ_MASK1_CLR__ser0_ready__nop 0
+#define R_IRQ_MASK1_CLR__ser0_data__BITNR 8
+#define R_IRQ_MASK1_CLR__ser0_data__WIDTH 1
+#define R_IRQ_MASK1_CLR__ser0_data__clr 1
+#define R_IRQ_MASK1_CLR__ser0_data__nop 0
+#define R_IRQ_MASK1_CLR__pa7__BITNR 7
+#define R_IRQ_MASK1_CLR__pa7__WIDTH 1
+#define R_IRQ_MASK1_CLR__pa7__clr 1
+#define R_IRQ_MASK1_CLR__pa7__nop 0
+#define R_IRQ_MASK1_CLR__pa6__BITNR 6
+#define R_IRQ_MASK1_CLR__pa6__WIDTH 1
+#define R_IRQ_MASK1_CLR__pa6__clr 1
+#define R_IRQ_MASK1_CLR__pa6__nop 0
+#define R_IRQ_MASK1_CLR__pa5__BITNR 5
+#define R_IRQ_MASK1_CLR__pa5__WIDTH 1
+#define R_IRQ_MASK1_CLR__pa5__clr 1
+#define R_IRQ_MASK1_CLR__pa5__nop 0
+#define R_IRQ_MASK1_CLR__pa4__BITNR 4
+#define R_IRQ_MASK1_CLR__pa4__WIDTH 1
+#define R_IRQ_MASK1_CLR__pa4__clr 1
+#define R_IRQ_MASK1_CLR__pa4__nop 0
+#define R_IRQ_MASK1_CLR__pa3__BITNR 3
+#define R_IRQ_MASK1_CLR__pa3__WIDTH 1
+#define R_IRQ_MASK1_CLR__pa3__clr 1
+#define R_IRQ_MASK1_CLR__pa3__nop 0
+#define R_IRQ_MASK1_CLR__pa2__BITNR 2
+#define R_IRQ_MASK1_CLR__pa2__WIDTH 1
+#define R_IRQ_MASK1_CLR__pa2__clr 1
+#define R_IRQ_MASK1_CLR__pa2__nop 0
+#define R_IRQ_MASK1_CLR__pa1__BITNR 1
+#define R_IRQ_MASK1_CLR__pa1__WIDTH 1
+#define R_IRQ_MASK1_CLR__pa1__clr 1
+#define R_IRQ_MASK1_CLR__pa1__nop 0
+#define R_IRQ_MASK1_CLR__pa0__BITNR 0
+#define R_IRQ_MASK1_CLR__pa0__WIDTH 1
+#define R_IRQ_MASK1_CLR__pa0__clr 1
+#define R_IRQ_MASK1_CLR__pa0__nop 0
+
+#define R_IRQ_READ1 (IO_TYPECAST_RO_UDWORD 0xb00000cc)
+#define R_IRQ_READ1__sw_int7__BITNR 31
+#define R_IRQ_READ1__sw_int7__WIDTH 1
+#define R_IRQ_READ1__sw_int7__active 1
+#define R_IRQ_READ1__sw_int7__inactive 0
+#define R_IRQ_READ1__sw_int6__BITNR 30
+#define R_IRQ_READ1__sw_int6__WIDTH 1
+#define R_IRQ_READ1__sw_int6__active 1
+#define R_IRQ_READ1__sw_int6__inactive 0
+#define R_IRQ_READ1__sw_int5__BITNR 29
+#define R_IRQ_READ1__sw_int5__WIDTH 1
+#define R_IRQ_READ1__sw_int5__active 1
+#define R_IRQ_READ1__sw_int5__inactive 0
+#define R_IRQ_READ1__sw_int4__BITNR 28
+#define R_IRQ_READ1__sw_int4__WIDTH 1
+#define R_IRQ_READ1__sw_int4__active 1
+#define R_IRQ_READ1__sw_int4__inactive 0
+#define R_IRQ_READ1__sw_int3__BITNR 27
+#define R_IRQ_READ1__sw_int3__WIDTH 1
+#define R_IRQ_READ1__sw_int3__active 1
+#define R_IRQ_READ1__sw_int3__inactive 0
+#define R_IRQ_READ1__sw_int2__BITNR 26
+#define R_IRQ_READ1__sw_int2__WIDTH 1
+#define R_IRQ_READ1__sw_int2__active 1
+#define R_IRQ_READ1__sw_int2__inactive 0
+#define R_IRQ_READ1__sw_int1__BITNR 25
+#define R_IRQ_READ1__sw_int1__WIDTH 1
+#define R_IRQ_READ1__sw_int1__active 1
+#define R_IRQ_READ1__sw_int1__inactive 0
+#define R_IRQ_READ1__sw_int0__BITNR 24
+#define R_IRQ_READ1__sw_int0__WIDTH 1
+#define R_IRQ_READ1__sw_int0__active 1
+#define R_IRQ_READ1__sw_int0__inactive 0
+#define R_IRQ_READ1__par1_ecp_cmd__BITNR 19
+#define R_IRQ_READ1__par1_ecp_cmd__WIDTH 1
+#define R_IRQ_READ1__par1_ecp_cmd__active 1
+#define R_IRQ_READ1__par1_ecp_cmd__inactive 0
+#define R_IRQ_READ1__par1_peri__BITNR 18
+#define R_IRQ_READ1__par1_peri__WIDTH 1
+#define R_IRQ_READ1__par1_peri__active 1
+#define R_IRQ_READ1__par1_peri__inactive 0
+#define R_IRQ_READ1__par1_data__BITNR 17
+#define R_IRQ_READ1__par1_data__WIDTH 1
+#define R_IRQ_READ1__par1_data__active 1
+#define R_IRQ_READ1__par1_data__inactive 0
+#define R_IRQ_READ1__par1_ready__BITNR 16
+#define R_IRQ_READ1__par1_ready__WIDTH 1
+#define R_IRQ_READ1__par1_ready__active 1
+#define R_IRQ_READ1__par1_ready__inactive 0
+#define R_IRQ_READ1__scsi1__BITNR 16
+#define R_IRQ_READ1__scsi1__WIDTH 1
+#define R_IRQ_READ1__scsi1__active 1
+#define R_IRQ_READ1__scsi1__inactive 0
+#define R_IRQ_READ1__ser3_ready__BITNR 15
+#define R_IRQ_READ1__ser3_ready__WIDTH 1
+#define R_IRQ_READ1__ser3_ready__active 1
+#define R_IRQ_READ1__ser3_ready__inactive 0
+#define R_IRQ_READ1__ser3_data__BITNR 14
+#define R_IRQ_READ1__ser3_data__WIDTH 1
+#define R_IRQ_READ1__ser3_data__active 1
+#define R_IRQ_READ1__ser3_data__inactive 0
+#define R_IRQ_READ1__ser2_ready__BITNR 13
+#define R_IRQ_READ1__ser2_ready__WIDTH 1
+#define R_IRQ_READ1__ser2_ready__active 1
+#define R_IRQ_READ1__ser2_ready__inactive 0
+#define R_IRQ_READ1__ser2_data__BITNR 12
+#define R_IRQ_READ1__ser2_data__WIDTH 1
+#define R_IRQ_READ1__ser2_data__active 1
+#define R_IRQ_READ1__ser2_data__inactive 0
+#define R_IRQ_READ1__ser1_ready__BITNR 11
+#define R_IRQ_READ1__ser1_ready__WIDTH 1
+#define R_IRQ_READ1__ser1_ready__active 1
+#define R_IRQ_READ1__ser1_ready__inactive 0
+#define R_IRQ_READ1__ser1_data__BITNR 10
+#define R_IRQ_READ1__ser1_data__WIDTH 1
+#define R_IRQ_READ1__ser1_data__active 1
+#define R_IRQ_READ1__ser1_data__inactive 0
+#define R_IRQ_READ1__ser0_ready__BITNR 9
+#define R_IRQ_READ1__ser0_ready__WIDTH 1
+#define R_IRQ_READ1__ser0_ready__active 1
+#define R_IRQ_READ1__ser0_ready__inactive 0
+#define R_IRQ_READ1__ser0_data__BITNR 8
+#define R_IRQ_READ1__ser0_data__WIDTH 1
+#define R_IRQ_READ1__ser0_data__active 1
+#define R_IRQ_READ1__ser0_data__inactive 0
+#define R_IRQ_READ1__pa7__BITNR 7
+#define R_IRQ_READ1__pa7__WIDTH 1
+#define R_IRQ_READ1__pa7__active 1
+#define R_IRQ_READ1__pa7__inactive 0
+#define R_IRQ_READ1__pa6__BITNR 6
+#define R_IRQ_READ1__pa6__WIDTH 1
+#define R_IRQ_READ1__pa6__active 1
+#define R_IRQ_READ1__pa6__inactive 0
+#define R_IRQ_READ1__pa5__BITNR 5
+#define R_IRQ_READ1__pa5__WIDTH 1
+#define R_IRQ_READ1__pa5__active 1
+#define R_IRQ_READ1__pa5__inactive 0
+#define R_IRQ_READ1__pa4__BITNR 4
+#define R_IRQ_READ1__pa4__WIDTH 1
+#define R_IRQ_READ1__pa4__active 1
+#define R_IRQ_READ1__pa4__inactive 0
+#define R_IRQ_READ1__pa3__BITNR 3
+#define R_IRQ_READ1__pa3__WIDTH 1
+#define R_IRQ_READ1__pa3__active 1
+#define R_IRQ_READ1__pa3__inactive 0
+#define R_IRQ_READ1__pa2__BITNR 2
+#define R_IRQ_READ1__pa2__WIDTH 1
+#define R_IRQ_READ1__pa2__active 1
+#define R_IRQ_READ1__pa2__inactive 0
+#define R_IRQ_READ1__pa1__BITNR 1
+#define R_IRQ_READ1__pa1__WIDTH 1
+#define R_IRQ_READ1__pa1__active 1
+#define R_IRQ_READ1__pa1__inactive 0
+#define R_IRQ_READ1__pa0__BITNR 0
+#define R_IRQ_READ1__pa0__WIDTH 1
+#define R_IRQ_READ1__pa0__active 1
+#define R_IRQ_READ1__pa0__inactive 0
+
+#define R_IRQ_MASK1_SET (IO_TYPECAST_UDWORD 0xb00000cc)
+#define R_IRQ_MASK1_SET__sw_int7__BITNR 31
+#define R_IRQ_MASK1_SET__sw_int7__WIDTH 1
+#define R_IRQ_MASK1_SET__sw_int7__set 1
+#define R_IRQ_MASK1_SET__sw_int7__nop 0
+#define R_IRQ_MASK1_SET__sw_int6__BITNR 30
+#define R_IRQ_MASK1_SET__sw_int6__WIDTH 1
+#define R_IRQ_MASK1_SET__sw_int6__set 1
+#define R_IRQ_MASK1_SET__sw_int6__nop 0
+#define R_IRQ_MASK1_SET__sw_int5__BITNR 29
+#define R_IRQ_MASK1_SET__sw_int5__WIDTH 1
+#define R_IRQ_MASK1_SET__sw_int5__set 1
+#define R_IRQ_MASK1_SET__sw_int5__nop 0
+#define R_IRQ_MASK1_SET__sw_int4__BITNR 28
+#define R_IRQ_MASK1_SET__sw_int4__WIDTH 1
+#define R_IRQ_MASK1_SET__sw_int4__set 1
+#define R_IRQ_MASK1_SET__sw_int4__nop 0
+#define R_IRQ_MASK1_SET__sw_int3__BITNR 27
+#define R_IRQ_MASK1_SET__sw_int3__WIDTH 1
+#define R_IRQ_MASK1_SET__sw_int3__set 1
+#define R_IRQ_MASK1_SET__sw_int3__nop 0
+#define R_IRQ_MASK1_SET__sw_int2__BITNR 26
+#define R_IRQ_MASK1_SET__sw_int2__WIDTH 1
+#define R_IRQ_MASK1_SET__sw_int2__set 1
+#define R_IRQ_MASK1_SET__sw_int2__nop 0
+#define R_IRQ_MASK1_SET__sw_int1__BITNR 25
+#define R_IRQ_MASK1_SET__sw_int1__WIDTH 1
+#define R_IRQ_MASK1_SET__sw_int1__set 1
+#define R_IRQ_MASK1_SET__sw_int1__nop 0
+#define R_IRQ_MASK1_SET__sw_int0__BITNR 24
+#define R_IRQ_MASK1_SET__sw_int0__WIDTH 1
+#define R_IRQ_MASK1_SET__sw_int0__set 1
+#define R_IRQ_MASK1_SET__sw_int0__nop 0
+#define R_IRQ_MASK1_SET__par1_ecp_cmd__BITNR 19
+#define R_IRQ_MASK1_SET__par1_ecp_cmd__WIDTH 1
+#define R_IRQ_MASK1_SET__par1_ecp_cmd__set 1
+#define R_IRQ_MASK1_SET__par1_ecp_cmd__nop 0
+#define R_IRQ_MASK1_SET__par1_peri__BITNR 18
+#define R_IRQ_MASK1_SET__par1_peri__WIDTH 1
+#define R_IRQ_MASK1_SET__par1_peri__set 1
+#define R_IRQ_MASK1_SET__par1_peri__nop 0
+#define R_IRQ_MASK1_SET__par1_data__BITNR 17
+#define R_IRQ_MASK1_SET__par1_data__WIDTH 1
+#define R_IRQ_MASK1_SET__par1_data__set 1
+#define R_IRQ_MASK1_SET__par1_data__nop 0
+#define R_IRQ_MASK1_SET__par1_ready__BITNR 16
+#define R_IRQ_MASK1_SET__par1_ready__WIDTH 1
+#define R_IRQ_MASK1_SET__par1_ready__set 1
+#define R_IRQ_MASK1_SET__par1_ready__nop 0
+#define R_IRQ_MASK1_SET__scsi1__BITNR 16
+#define R_IRQ_MASK1_SET__scsi1__WIDTH 1
+#define R_IRQ_MASK1_SET__scsi1__set 1
+#define R_IRQ_MASK1_SET__scsi1__nop 0
+#define R_IRQ_MASK1_SET__ser3_ready__BITNR 15
+#define R_IRQ_MASK1_SET__ser3_ready__WIDTH 1
+#define R_IRQ_MASK1_SET__ser3_ready__set 1
+#define R_IRQ_MASK1_SET__ser3_ready__nop 0
+#define R_IRQ_MASK1_SET__ser3_data__BITNR 14
+#define R_IRQ_MASK1_SET__ser3_data__WIDTH 1
+#define R_IRQ_MASK1_SET__ser3_data__set 1
+#define R_IRQ_MASK1_SET__ser3_data__nop 0
+#define R_IRQ_MASK1_SET__ser2_ready__BITNR 13
+#define R_IRQ_MASK1_SET__ser2_ready__WIDTH 1
+#define R_IRQ_MASK1_SET__ser2_ready__set 1
+#define R_IRQ_MASK1_SET__ser2_ready__nop 0
+#define R_IRQ_MASK1_SET__ser2_data__BITNR 12
+#define R_IRQ_MASK1_SET__ser2_data__WIDTH 1
+#define R_IRQ_MASK1_SET__ser2_data__set 1
+#define R_IRQ_MASK1_SET__ser2_data__nop 0
+#define R_IRQ_MASK1_SET__ser1_ready__BITNR 11
+#define R_IRQ_MASK1_SET__ser1_ready__WIDTH 1
+#define R_IRQ_MASK1_SET__ser1_ready__set 1
+#define R_IRQ_MASK1_SET__ser1_ready__nop 0
+#define R_IRQ_MASK1_SET__ser1_data__BITNR 10
+#define R_IRQ_MASK1_SET__ser1_data__WIDTH 1
+#define R_IRQ_MASK1_SET__ser1_data__set 1
+#define R_IRQ_MASK1_SET__ser1_data__nop 0
+#define R_IRQ_MASK1_SET__ser0_ready__BITNR 9
+#define R_IRQ_MASK1_SET__ser0_ready__WIDTH 1
+#define R_IRQ_MASK1_SET__ser0_ready__set 1
+#define R_IRQ_MASK1_SET__ser0_ready__nop 0
+#define R_IRQ_MASK1_SET__ser0_data__BITNR 8
+#define R_IRQ_MASK1_SET__ser0_data__WIDTH 1
+#define R_IRQ_MASK1_SET__ser0_data__set 1
+#define R_IRQ_MASK1_SET__ser0_data__nop 0
+#define R_IRQ_MASK1_SET__pa7__BITNR 7
+#define R_IRQ_MASK1_SET__pa7__WIDTH 1
+#define R_IRQ_MASK1_SET__pa7__set 1
+#define R_IRQ_MASK1_SET__pa7__nop 0
+#define R_IRQ_MASK1_SET__pa6__BITNR 6
+#define R_IRQ_MASK1_SET__pa6__WIDTH 1
+#define R_IRQ_MASK1_SET__pa6__set 1
+#define R_IRQ_MASK1_SET__pa6__nop 0
+#define R_IRQ_MASK1_SET__pa5__BITNR 5
+#define R_IRQ_MASK1_SET__pa5__WIDTH 1
+#define R_IRQ_MASK1_SET__pa5__set 1
+#define R_IRQ_MASK1_SET__pa5__nop 0
+#define R_IRQ_MASK1_SET__pa4__BITNR 4
+#define R_IRQ_MASK1_SET__pa4__WIDTH 1
+#define R_IRQ_MASK1_SET__pa4__set 1
+#define R_IRQ_MASK1_SET__pa4__nop 0
+#define R_IRQ_MASK1_SET__pa3__BITNR 3
+#define R_IRQ_MASK1_SET__pa3__WIDTH 1
+#define R_IRQ_MASK1_SET__pa3__set 1
+#define R_IRQ_MASK1_SET__pa3__nop 0
+#define R_IRQ_MASK1_SET__pa2__BITNR 2
+#define R_IRQ_MASK1_SET__pa2__WIDTH 1
+#define R_IRQ_MASK1_SET__pa2__set 1
+#define R_IRQ_MASK1_SET__pa2__nop 0
+#define R_IRQ_MASK1_SET__pa1__BITNR 1
+#define R_IRQ_MASK1_SET__pa1__WIDTH 1
+#define R_IRQ_MASK1_SET__pa1__set 1
+#define R_IRQ_MASK1_SET__pa1__nop 0
+#define R_IRQ_MASK1_SET__pa0__BITNR 0
+#define R_IRQ_MASK1_SET__pa0__WIDTH 1
+#define R_IRQ_MASK1_SET__pa0__set 1
+#define R_IRQ_MASK1_SET__pa0__nop 0
+
+#define R_IRQ_MASK2_RD (IO_TYPECAST_RO_UDWORD 0xb00000d0)
+#define R_IRQ_MASK2_RD__dma8_sub3_descr__BITNR 23
+#define R_IRQ_MASK2_RD__dma8_sub3_descr__WIDTH 1
+#define R_IRQ_MASK2_RD__dma8_sub3_descr__active 1
+#define R_IRQ_MASK2_RD__dma8_sub3_descr__inactive 0
+#define R_IRQ_MASK2_RD__dma8_sub2_descr__BITNR 22
+#define R_IRQ_MASK2_RD__dma8_sub2_descr__WIDTH 1
+#define R_IRQ_MASK2_RD__dma8_sub2_descr__active 1
+#define R_IRQ_MASK2_RD__dma8_sub2_descr__inactive 0
+#define R_IRQ_MASK2_RD__dma8_sub1_descr__BITNR 21
+#define R_IRQ_MASK2_RD__dma8_sub1_descr__WIDTH 1
+#define R_IRQ_MASK2_RD__dma8_sub1_descr__active 1
+#define R_IRQ_MASK2_RD__dma8_sub1_descr__inactive 0
+#define R_IRQ_MASK2_RD__dma8_sub0_descr__BITNR 20
+#define R_IRQ_MASK2_RD__dma8_sub0_descr__WIDTH 1
+#define R_IRQ_MASK2_RD__dma8_sub0_descr__active 1
+#define R_IRQ_MASK2_RD__dma8_sub0_descr__inactive 0
+#define R_IRQ_MASK2_RD__dma9_eop__BITNR 19
+#define R_IRQ_MASK2_RD__dma9_eop__WIDTH 1
+#define R_IRQ_MASK2_RD__dma9_eop__active 1
+#define R_IRQ_MASK2_RD__dma9_eop__inactive 0
+#define R_IRQ_MASK2_RD__dma9_descr__BITNR 18
+#define R_IRQ_MASK2_RD__dma9_descr__WIDTH 1
+#define R_IRQ_MASK2_RD__dma9_descr__active 1
+#define R_IRQ_MASK2_RD__dma9_descr__inactive 0
+#define R_IRQ_MASK2_RD__dma8_eop__BITNR 17
+#define R_IRQ_MASK2_RD__dma8_eop__WIDTH 1
+#define R_IRQ_MASK2_RD__dma8_eop__active 1
+#define R_IRQ_MASK2_RD__dma8_eop__inactive 0
+#define R_IRQ_MASK2_RD__dma8_descr__BITNR 16
+#define R_IRQ_MASK2_RD__dma8_descr__WIDTH 1
+#define R_IRQ_MASK2_RD__dma8_descr__active 1
+#define R_IRQ_MASK2_RD__dma8_descr__inactive 0
+#define R_IRQ_MASK2_RD__dma7_eop__BITNR 15
+#define R_IRQ_MASK2_RD__dma7_eop__WIDTH 1
+#define R_IRQ_MASK2_RD__dma7_eop__active 1
+#define R_IRQ_MASK2_RD__dma7_eop__inactive 0
+#define R_IRQ_MASK2_RD__dma7_descr__BITNR 14
+#define R_IRQ_MASK2_RD__dma7_descr__WIDTH 1
+#define R_IRQ_MASK2_RD__dma7_descr__active 1
+#define R_IRQ_MASK2_RD__dma7_descr__inactive 0
+#define R_IRQ_MASK2_RD__dma6_eop__BITNR 13
+#define R_IRQ_MASK2_RD__dma6_eop__WIDTH 1
+#define R_IRQ_MASK2_RD__dma6_eop__active 1
+#define R_IRQ_MASK2_RD__dma6_eop__inactive 0
+#define R_IRQ_MASK2_RD__dma6_descr__BITNR 12
+#define R_IRQ_MASK2_RD__dma6_descr__WIDTH 1
+#define R_IRQ_MASK2_RD__dma6_descr__active 1
+#define R_IRQ_MASK2_RD__dma6_descr__inactive 0
+#define R_IRQ_MASK2_RD__dma5_eop__BITNR 11
+#define R_IRQ_MASK2_RD__dma5_eop__WIDTH 1
+#define R_IRQ_MASK2_RD__dma5_eop__active 1
+#define R_IRQ_MASK2_RD__dma5_eop__inactive 0
+#define R_IRQ_MASK2_RD__dma5_descr__BITNR 10
+#define R_IRQ_MASK2_RD__dma5_descr__WIDTH 1
+#define R_IRQ_MASK2_RD__dma5_descr__active 1
+#define R_IRQ_MASK2_RD__dma5_descr__inactive 0
+#define R_IRQ_MASK2_RD__dma4_eop__BITNR 9
+#define R_IRQ_MASK2_RD__dma4_eop__WIDTH 1
+#define R_IRQ_MASK2_RD__dma4_eop__active 1
+#define R_IRQ_MASK2_RD__dma4_eop__inactive 0
+#define R_IRQ_MASK2_RD__dma4_descr__BITNR 8
+#define R_IRQ_MASK2_RD__dma4_descr__WIDTH 1
+#define R_IRQ_MASK2_RD__dma4_descr__active 1
+#define R_IRQ_MASK2_RD__dma4_descr__inactive 0
+#define R_IRQ_MASK2_RD__dma3_eop__BITNR 7
+#define R_IRQ_MASK2_RD__dma3_eop__WIDTH 1
+#define R_IRQ_MASK2_RD__dma3_eop__active 1
+#define R_IRQ_MASK2_RD__dma3_eop__inactive 0
+#define R_IRQ_MASK2_RD__dma3_descr__BITNR 6
+#define R_IRQ_MASK2_RD__dma3_descr__WIDTH 1
+#define R_IRQ_MASK2_RD__dma3_descr__active 1
+#define R_IRQ_MASK2_RD__dma3_descr__inactive 0
+#define R_IRQ_MASK2_RD__dma2_eop__BITNR 5
+#define R_IRQ_MASK2_RD__dma2_eop__WIDTH 1
+#define R_IRQ_MASK2_RD__dma2_eop__active 1
+#define R_IRQ_MASK2_RD__dma2_eop__inactive 0
+#define R_IRQ_MASK2_RD__dma2_descr__BITNR 4
+#define R_IRQ_MASK2_RD__dma2_descr__WIDTH 1
+#define R_IRQ_MASK2_RD__dma2_descr__active 1
+#define R_IRQ_MASK2_RD__dma2_descr__inactive 0
+#define R_IRQ_MASK2_RD__dma1_eop__BITNR 3
+#define R_IRQ_MASK2_RD__dma1_eop__WIDTH 1
+#define R_IRQ_MASK2_RD__dma1_eop__active 1
+#define R_IRQ_MASK2_RD__dma1_eop__inactive 0
+#define R_IRQ_MASK2_RD__dma1_descr__BITNR 2
+#define R_IRQ_MASK2_RD__dma1_descr__WIDTH 1
+#define R_IRQ_MASK2_RD__dma1_descr__active 1
+#define R_IRQ_MASK2_RD__dma1_descr__inactive 0
+#define R_IRQ_MASK2_RD__dma0_eop__BITNR 1
+#define R_IRQ_MASK2_RD__dma0_eop__WIDTH 1
+#define R_IRQ_MASK2_RD__dma0_eop__active 1
+#define R_IRQ_MASK2_RD__dma0_eop__inactive 0
+#define R_IRQ_MASK2_RD__dma0_descr__BITNR 0
+#define R_IRQ_MASK2_RD__dma0_descr__WIDTH 1
+#define R_IRQ_MASK2_RD__dma0_descr__active 1
+#define R_IRQ_MASK2_RD__dma0_descr__inactive 0
+
+#define R_IRQ_MASK2_CLR (IO_TYPECAST_UDWORD 0xb00000d0)
+#define R_IRQ_MASK2_CLR__dma8_sub3_descr__BITNR 23
+#define R_IRQ_MASK2_CLR__dma8_sub3_descr__WIDTH 1
+#define R_IRQ_MASK2_CLR__dma8_sub3_descr__clr 1
+#define R_IRQ_MASK2_CLR__dma8_sub3_descr__nop 0
+#define R_IRQ_MASK2_CLR__dma8_sub2_descr__BITNR 22
+#define R_IRQ_MASK2_CLR__dma8_sub2_descr__WIDTH 1
+#define R_IRQ_MASK2_CLR__dma8_sub2_descr__clr 1
+#define R_IRQ_MASK2_CLR__dma8_sub2_descr__nop 0
+#define R_IRQ_MASK2_CLR__dma8_sub1_descr__BITNR 21
+#define R_IRQ_MASK2_CLR__dma8_sub1_descr__WIDTH 1
+#define R_IRQ_MASK2_CLR__dma8_sub1_descr__clr 1
+#define R_IRQ_MASK2_CLR__dma8_sub1_descr__nop 0
+#define R_IRQ_MASK2_CLR__dma8_sub0_descr__BITNR 20
+#define R_IRQ_MASK2_CLR__dma8_sub0_descr__WIDTH 1
+#define R_IRQ_MASK2_CLR__dma8_sub0_descr__clr 1
+#define R_IRQ_MASK2_CLR__dma8_sub0_descr__nop 0
+#define R_IRQ_MASK2_CLR__dma9_eop__BITNR 19
+#define R_IRQ_MASK2_CLR__dma9_eop__WIDTH 1
+#define R_IRQ_MASK2_CLR__dma9_eop__clr 1
+#define R_IRQ_MASK2_CLR__dma9_eop__nop 0
+#define R_IRQ_MASK2_CLR__dma9_descr__BITNR 18
+#define R_IRQ_MASK2_CLR__dma9_descr__WIDTH 1
+#define R_IRQ_MASK2_CLR__dma9_descr__clr 1
+#define R_IRQ_MASK2_CLR__dma9_descr__nop 0
+#define R_IRQ_MASK2_CLR__dma8_eop__BITNR 17
+#define R_IRQ_MASK2_CLR__dma8_eop__WIDTH 1
+#define R_IRQ_MASK2_CLR__dma8_eop__clr 1
+#define R_IRQ_MASK2_CLR__dma8_eop__nop 0
+#define R_IRQ_MASK2_CLR__dma8_descr__BITNR 16
+#define R_IRQ_MASK2_CLR__dma8_descr__WIDTH 1
+#define R_IRQ_MASK2_CLR__dma8_descr__clr 1
+#define R_IRQ_MASK2_CLR__dma8_descr__nop 0
+#define R_IRQ_MASK2_CLR__dma7_eop__BITNR 15
+#define R_IRQ_MASK2_CLR__dma7_eop__WIDTH 1
+#define R_IRQ_MASK2_CLR__dma7_eop__clr 1
+#define R_IRQ_MASK2_CLR__dma7_eop__nop 0
+#define R_IRQ_MASK2_CLR__dma7_descr__BITNR 14
+#define R_IRQ_MASK2_CLR__dma7_descr__WIDTH 1
+#define R_IRQ_MASK2_CLR__dma7_descr__clr 1
+#define R_IRQ_MASK2_CLR__dma7_descr__nop 0
+#define R_IRQ_MASK2_CLR__dma6_eop__BITNR 13
+#define R_IRQ_MASK2_CLR__dma6_eop__WIDTH 1
+#define R_IRQ_MASK2_CLR__dma6_eop__clr 1
+#define R_IRQ_MASK2_CLR__dma6_eop__nop 0
+#define R_IRQ_MASK2_CLR__dma6_descr__BITNR 12
+#define R_IRQ_MASK2_CLR__dma6_descr__WIDTH 1
+#define R_IRQ_MASK2_CLR__dma6_descr__clr 1
+#define R_IRQ_MASK2_CLR__dma6_descr__nop 0
+#define R_IRQ_MASK2_CLR__dma5_eop__BITNR 11
+#define R_IRQ_MASK2_CLR__dma5_eop__WIDTH 1
+#define R_IRQ_MASK2_CLR__dma5_eop__clr 1
+#define R_IRQ_MASK2_CLR__dma5_eop__nop 0
+#define R_IRQ_MASK2_CLR__dma5_descr__BITNR 10
+#define R_IRQ_MASK2_CLR__dma5_descr__WIDTH 1
+#define R_IRQ_MASK2_CLR__dma5_descr__clr 1
+#define R_IRQ_MASK2_CLR__dma5_descr__nop 0
+#define R_IRQ_MASK2_CLR__dma4_eop__BITNR 9
+#define R_IRQ_MASK2_CLR__dma4_eop__WIDTH 1
+#define R_IRQ_MASK2_CLR__dma4_eop__clr 1
+#define R_IRQ_MASK2_CLR__dma4_eop__nop 0
+#define R_IRQ_MASK2_CLR__dma4_descr__BITNR 8
+#define R_IRQ_MASK2_CLR__dma4_descr__WIDTH 1
+#define R_IRQ_MASK2_CLR__dma4_descr__clr 1
+#define R_IRQ_MASK2_CLR__dma4_descr__nop 0
+#define R_IRQ_MASK2_CLR__dma3_eop__BITNR 7
+#define R_IRQ_MASK2_CLR__dma3_eop__WIDTH 1
+#define R_IRQ_MASK2_CLR__dma3_eop__clr 1
+#define R_IRQ_MASK2_CLR__dma3_eop__nop 0
+#define R_IRQ_MASK2_CLR__dma3_descr__BITNR 6
+#define R_IRQ_MASK2_CLR__dma3_descr__WIDTH 1
+#define R_IRQ_MASK2_CLR__dma3_descr__clr 1
+#define R_IRQ_MASK2_CLR__dma3_descr__nop 0
+#define R_IRQ_MASK2_CLR__dma2_eop__BITNR 5
+#define R_IRQ_MASK2_CLR__dma2_eop__WIDTH 1
+#define R_IRQ_MASK2_CLR__dma2_eop__clr 1
+#define R_IRQ_MASK2_CLR__dma2_eop__nop 0
+#define R_IRQ_MASK2_CLR__dma2_descr__BITNR 4
+#define R_IRQ_MASK2_CLR__dma2_descr__WIDTH 1
+#define R_IRQ_MASK2_CLR__dma2_descr__clr 1
+#define R_IRQ_MASK2_CLR__dma2_descr__nop 0
+#define R_IRQ_MASK2_CLR__dma1_eop__BITNR 3
+#define R_IRQ_MASK2_CLR__dma1_eop__WIDTH 1
+#define R_IRQ_MASK2_CLR__dma1_eop__clr 1
+#define R_IRQ_MASK2_CLR__dma1_eop__nop 0
+#define R_IRQ_MASK2_CLR__dma1_descr__BITNR 2
+#define R_IRQ_MASK2_CLR__dma1_descr__WIDTH 1
+#define R_IRQ_MASK2_CLR__dma1_descr__clr 1
+#define R_IRQ_MASK2_CLR__dma1_descr__nop 0
+#define R_IRQ_MASK2_CLR__dma0_eop__BITNR 1
+#define R_IRQ_MASK2_CLR__dma0_eop__WIDTH 1
+#define R_IRQ_MASK2_CLR__dma0_eop__clr 1
+#define R_IRQ_MASK2_CLR__dma0_eop__nop 0
+#define R_IRQ_MASK2_CLR__dma0_descr__BITNR 0
+#define R_IRQ_MASK2_CLR__dma0_descr__WIDTH 1
+#define R_IRQ_MASK2_CLR__dma0_descr__clr 1
+#define R_IRQ_MASK2_CLR__dma0_descr__nop 0
+
+#define R_IRQ_READ2 (IO_TYPECAST_RO_UDWORD 0xb00000d4)
+#define R_IRQ_READ2__dma8_sub3_descr__BITNR 23
+#define R_IRQ_READ2__dma8_sub3_descr__WIDTH 1
+#define R_IRQ_READ2__dma8_sub3_descr__active 1
+#define R_IRQ_READ2__dma8_sub3_descr__inactive 0
+#define R_IRQ_READ2__dma8_sub2_descr__BITNR 22
+#define R_IRQ_READ2__dma8_sub2_descr__WIDTH 1
+#define R_IRQ_READ2__dma8_sub2_descr__active 1
+#define R_IRQ_READ2__dma8_sub2_descr__inactive 0
+#define R_IRQ_READ2__dma8_sub1_descr__BITNR 21
+#define R_IRQ_READ2__dma8_sub1_descr__WIDTH 1
+#define R_IRQ_READ2__dma8_sub1_descr__active 1
+#define R_IRQ_READ2__dma8_sub1_descr__inactive 0
+#define R_IRQ_READ2__dma8_sub0_descr__BITNR 20
+#define R_IRQ_READ2__dma8_sub0_descr__WIDTH 1
+#define R_IRQ_READ2__dma8_sub0_descr__active 1
+#define R_IRQ_READ2__dma8_sub0_descr__inactive 0
+#define R_IRQ_READ2__dma9_eop__BITNR 19
+#define R_IRQ_READ2__dma9_eop__WIDTH 1
+#define R_IRQ_READ2__dma9_eop__active 1
+#define R_IRQ_READ2__dma9_eop__inactive 0
+#define R_IRQ_READ2__dma9_descr__BITNR 18
+#define R_IRQ_READ2__dma9_descr__WIDTH 1
+#define R_IRQ_READ2__dma9_descr__active 1
+#define R_IRQ_READ2__dma9_descr__inactive 0
+#define R_IRQ_READ2__dma8_eop__BITNR 17
+#define R_IRQ_READ2__dma8_eop__WIDTH 1
+#define R_IRQ_READ2__dma8_eop__active 1
+#define R_IRQ_READ2__dma8_eop__inactive 0
+#define R_IRQ_READ2__dma8_descr__BITNR 16
+#define R_IRQ_READ2__dma8_descr__WIDTH 1
+#define R_IRQ_READ2__dma8_descr__active 1
+#define R_IRQ_READ2__dma8_descr__inactive 0
+#define R_IRQ_READ2__dma7_eop__BITNR 15
+#define R_IRQ_READ2__dma7_eop__WIDTH 1
+#define R_IRQ_READ2__dma7_eop__active 1
+#define R_IRQ_READ2__dma7_eop__inactive 0
+#define R_IRQ_READ2__dma7_descr__BITNR 14
+#define R_IRQ_READ2__dma7_descr__WIDTH 1
+#define R_IRQ_READ2__dma7_descr__active 1
+#define R_IRQ_READ2__dma7_descr__inactive 0
+#define R_IRQ_READ2__dma6_eop__BITNR 13
+#define R_IRQ_READ2__dma6_eop__WIDTH 1
+#define R_IRQ_READ2__dma6_eop__active 1
+#define R_IRQ_READ2__dma6_eop__inactive 0
+#define R_IRQ_READ2__dma6_descr__BITNR 12
+#define R_IRQ_READ2__dma6_descr__WIDTH 1
+#define R_IRQ_READ2__dma6_descr__active 1
+#define R_IRQ_READ2__dma6_descr__inactive 0
+#define R_IRQ_READ2__dma5_eop__BITNR 11
+#define R_IRQ_READ2__dma5_eop__WIDTH 1
+#define R_IRQ_READ2__dma5_eop__active 1
+#define R_IRQ_READ2__dma5_eop__inactive 0
+#define R_IRQ_READ2__dma5_descr__BITNR 10
+#define R_IRQ_READ2__dma5_descr__WIDTH 1
+#define R_IRQ_READ2__dma5_descr__active 1
+#define R_IRQ_READ2__dma5_descr__inactive 0
+#define R_IRQ_READ2__dma4_eop__BITNR 9
+#define R_IRQ_READ2__dma4_eop__WIDTH 1
+#define R_IRQ_READ2__dma4_eop__active 1
+#define R_IRQ_READ2__dma4_eop__inactive 0
+#define R_IRQ_READ2__dma4_descr__BITNR 8
+#define R_IRQ_READ2__dma4_descr__WIDTH 1
+#define R_IRQ_READ2__dma4_descr__active 1
+#define R_IRQ_READ2__dma4_descr__inactive 0
+#define R_IRQ_READ2__dma3_eop__BITNR 7
+#define R_IRQ_READ2__dma3_eop__WIDTH 1
+#define R_IRQ_READ2__dma3_eop__active 1
+#define R_IRQ_READ2__dma3_eop__inactive 0
+#define R_IRQ_READ2__dma3_descr__BITNR 6
+#define R_IRQ_READ2__dma3_descr__WIDTH 1
+#define R_IRQ_READ2__dma3_descr__active 1
+#define R_IRQ_READ2__dma3_descr__inactive 0
+#define R_IRQ_READ2__dma2_eop__BITNR 5
+#define R_IRQ_READ2__dma2_eop__WIDTH 1
+#define R_IRQ_READ2__dma2_eop__active 1
+#define R_IRQ_READ2__dma2_eop__inactive 0
+#define R_IRQ_READ2__dma2_descr__BITNR 4
+#define R_IRQ_READ2__dma2_descr__WIDTH 1
+#define R_IRQ_READ2__dma2_descr__active 1
+#define R_IRQ_READ2__dma2_descr__inactive 0
+#define R_IRQ_READ2__dma1_eop__BITNR 3
+#define R_IRQ_READ2__dma1_eop__WIDTH 1
+#define R_IRQ_READ2__dma1_eop__active 1
+#define R_IRQ_READ2__dma1_eop__inactive 0
+#define R_IRQ_READ2__dma1_descr__BITNR 2
+#define R_IRQ_READ2__dma1_descr__WIDTH 1
+#define R_IRQ_READ2__dma1_descr__active 1
+#define R_IRQ_READ2__dma1_descr__inactive 0
+#define R_IRQ_READ2__dma0_eop__BITNR 1
+#define R_IRQ_READ2__dma0_eop__WIDTH 1
+#define R_IRQ_READ2__dma0_eop__active 1
+#define R_IRQ_READ2__dma0_eop__inactive 0
+#define R_IRQ_READ2__dma0_descr__BITNR 0
+#define R_IRQ_READ2__dma0_descr__WIDTH 1
+#define R_IRQ_READ2__dma0_descr__active 1
+#define R_IRQ_READ2__dma0_descr__inactive 0
+
+#define R_IRQ_MASK2_SET (IO_TYPECAST_UDWORD 0xb00000d4)
+#define R_IRQ_MASK2_SET__dma8_sub3_descr__BITNR 23
+#define R_IRQ_MASK2_SET__dma8_sub3_descr__WIDTH 1
+#define R_IRQ_MASK2_SET__dma8_sub3_descr__set 1
+#define R_IRQ_MASK2_SET__dma8_sub3_descr__nop 0
+#define R_IRQ_MASK2_SET__dma8_sub2_descr__BITNR 22
+#define R_IRQ_MASK2_SET__dma8_sub2_descr__WIDTH 1
+#define R_IRQ_MASK2_SET__dma8_sub2_descr__set 1
+#define R_IRQ_MASK2_SET__dma8_sub2_descr__nop 0
+#define R_IRQ_MASK2_SET__dma8_sub1_descr__BITNR 21
+#define R_IRQ_MASK2_SET__dma8_sub1_descr__WIDTH 1
+#define R_IRQ_MASK2_SET__dma8_sub1_descr__set 1
+#define R_IRQ_MASK2_SET__dma8_sub1_descr__nop 0
+#define R_IRQ_MASK2_SET__dma8_sub0_descr__BITNR 20
+#define R_IRQ_MASK2_SET__dma8_sub0_descr__WIDTH 1
+#define R_IRQ_MASK2_SET__dma8_sub0_descr__set 1
+#define R_IRQ_MASK2_SET__dma8_sub0_descr__nop 0
+#define R_IRQ_MASK2_SET__dma9_eop__BITNR 19
+#define R_IRQ_MASK2_SET__dma9_eop__WIDTH 1
+#define R_IRQ_MASK2_SET__dma9_eop__set 1
+#define R_IRQ_MASK2_SET__dma9_eop__nop 0
+#define R_IRQ_MASK2_SET__dma9_descr__BITNR 18
+#define R_IRQ_MASK2_SET__dma9_descr__WIDTH 1
+#define R_IRQ_MASK2_SET__dma9_descr__set 1
+#define R_IRQ_MASK2_SET__dma9_descr__nop 0
+#define R_IRQ_MASK2_SET__dma8_eop__BITNR 17
+#define R_IRQ_MASK2_SET__dma8_eop__WIDTH 1
+#define R_IRQ_MASK2_SET__dma8_eop__set 1
+#define R_IRQ_MASK2_SET__dma8_eop__nop 0
+#define R_IRQ_MASK2_SET__dma8_descr__BITNR 16
+#define R_IRQ_MASK2_SET__dma8_descr__WIDTH 1
+#define R_IRQ_MASK2_SET__dma8_descr__set 1
+#define R_IRQ_MASK2_SET__dma8_descr__nop 0
+#define R_IRQ_MASK2_SET__dma7_eop__BITNR 15
+#define R_IRQ_MASK2_SET__dma7_eop__WIDTH 1
+#define R_IRQ_MASK2_SET__dma7_eop__set 1
+#define R_IRQ_MASK2_SET__dma7_eop__nop 0
+#define R_IRQ_MASK2_SET__dma7_descr__BITNR 14
+#define R_IRQ_MASK2_SET__dma7_descr__WIDTH 1
+#define R_IRQ_MASK2_SET__dma7_descr__set 1
+#define R_IRQ_MASK2_SET__dma7_descr__nop 0
+#define R_IRQ_MASK2_SET__dma6_eop__BITNR 13
+#define R_IRQ_MASK2_SET__dma6_eop__WIDTH 1
+#define R_IRQ_MASK2_SET__dma6_eop__set 1
+#define R_IRQ_MASK2_SET__dma6_eop__nop 0
+#define R_IRQ_MASK2_SET__dma6_descr__BITNR 12
+#define R_IRQ_MASK2_SET__dma6_descr__WIDTH 1
+#define R_IRQ_MASK2_SET__dma6_descr__set 1
+#define R_IRQ_MASK2_SET__dma6_descr__nop 0
+#define R_IRQ_MASK2_SET__dma5_eop__BITNR 11
+#define R_IRQ_MASK2_SET__dma5_eop__WIDTH 1
+#define R_IRQ_MASK2_SET__dma5_eop__set 1
+#define R_IRQ_MASK2_SET__dma5_eop__nop 0
+#define R_IRQ_MASK2_SET__dma5_descr__BITNR 10
+#define R_IRQ_MASK2_SET__dma5_descr__WIDTH 1
+#define R_IRQ_MASK2_SET__dma5_descr__set 1
+#define R_IRQ_MASK2_SET__dma5_descr__nop 0
+#define R_IRQ_MASK2_SET__dma4_eop__BITNR 9
+#define R_IRQ_MASK2_SET__dma4_eop__WIDTH 1
+#define R_IRQ_MASK2_SET__dma4_eop__set 1
+#define R_IRQ_MASK2_SET__dma4_eop__nop 0
+#define R_IRQ_MASK2_SET__dma4_descr__BITNR 8
+#define R_IRQ_MASK2_SET__dma4_descr__WIDTH 1
+#define R_IRQ_MASK2_SET__dma4_descr__set 1
+#define R_IRQ_MASK2_SET__dma4_descr__nop 0
+#define R_IRQ_MASK2_SET__dma3_eop__BITNR 7
+#define R_IRQ_MASK2_SET__dma3_eop__WIDTH 1
+#define R_IRQ_MASK2_SET__dma3_eop__set 1
+#define R_IRQ_MASK2_SET__dma3_eop__nop 0
+#define R_IRQ_MASK2_SET__dma3_descr__BITNR 6
+#define R_IRQ_MASK2_SET__dma3_descr__WIDTH 1
+#define R_IRQ_MASK2_SET__dma3_descr__set 1
+#define R_IRQ_MASK2_SET__dma3_descr__nop 0
+#define R_IRQ_MASK2_SET__dma2_eop__BITNR 5
+#define R_IRQ_MASK2_SET__dma2_eop__WIDTH 1
+#define R_IRQ_MASK2_SET__dma2_eop__set 1
+#define R_IRQ_MASK2_SET__dma2_eop__nop 0
+#define R_IRQ_MASK2_SET__dma2_descr__BITNR 4
+#define R_IRQ_MASK2_SET__dma2_descr__WIDTH 1
+#define R_IRQ_MASK2_SET__dma2_descr__set 1
+#define R_IRQ_MASK2_SET__dma2_descr__nop 0
+#define R_IRQ_MASK2_SET__dma1_eop__BITNR 3
+#define R_IRQ_MASK2_SET__dma1_eop__WIDTH 1
+#define R_IRQ_MASK2_SET__dma1_eop__set 1
+#define R_IRQ_MASK2_SET__dma1_eop__nop 0
+#define R_IRQ_MASK2_SET__dma1_descr__BITNR 2
+#define R_IRQ_MASK2_SET__dma1_descr__WIDTH 1
+#define R_IRQ_MASK2_SET__dma1_descr__set 1
+#define R_IRQ_MASK2_SET__dma1_descr__nop 0
+#define R_IRQ_MASK2_SET__dma0_eop__BITNR 1
+#define R_IRQ_MASK2_SET__dma0_eop__WIDTH 1
+#define R_IRQ_MASK2_SET__dma0_eop__set 1
+#define R_IRQ_MASK2_SET__dma0_eop__nop 0
+#define R_IRQ_MASK2_SET__dma0_descr__BITNR 0
+#define R_IRQ_MASK2_SET__dma0_descr__WIDTH 1
+#define R_IRQ_MASK2_SET__dma0_descr__set 1
+#define R_IRQ_MASK2_SET__dma0_descr__nop 0
+
+#define R_VECT_MASK_RD (IO_TYPECAST_RO_UDWORD 0xb00000d8)
+#define R_VECT_MASK_RD__usb__BITNR 31
+#define R_VECT_MASK_RD__usb__WIDTH 1
+#define R_VECT_MASK_RD__usb__active 1
+#define R_VECT_MASK_RD__usb__inactive 0
+#define R_VECT_MASK_RD__dma9__BITNR 25
+#define R_VECT_MASK_RD__dma9__WIDTH 1
+#define R_VECT_MASK_RD__dma9__active 1
+#define R_VECT_MASK_RD__dma9__inactive 0
+#define R_VECT_MASK_RD__dma8__BITNR 24
+#define R_VECT_MASK_RD__dma8__WIDTH 1
+#define R_VECT_MASK_RD__dma8__active 1
+#define R_VECT_MASK_RD__dma8__inactive 0
+#define R_VECT_MASK_RD__dma7__BITNR 23
+#define R_VECT_MASK_RD__dma7__WIDTH 1
+#define R_VECT_MASK_RD__dma7__active 1
+#define R_VECT_MASK_RD__dma7__inactive 0
+#define R_VECT_MASK_RD__dma6__BITNR 22
+#define R_VECT_MASK_RD__dma6__WIDTH 1
+#define R_VECT_MASK_RD__dma6__active 1
+#define R_VECT_MASK_RD__dma6__inactive 0
+#define R_VECT_MASK_RD__dma5__BITNR 21
+#define R_VECT_MASK_RD__dma5__WIDTH 1
+#define R_VECT_MASK_RD__dma5__active 1
+#define R_VECT_MASK_RD__dma5__inactive 0
+#define R_VECT_MASK_RD__dma4__BITNR 20
+#define R_VECT_MASK_RD__dma4__WIDTH 1
+#define R_VECT_MASK_RD__dma4__active 1
+#define R_VECT_MASK_RD__dma4__inactive 0
+#define R_VECT_MASK_RD__dma3__BITNR 19
+#define R_VECT_MASK_RD__dma3__WIDTH 1
+#define R_VECT_MASK_RD__dma3__active 1
+#define R_VECT_MASK_RD__dma3__inactive 0
+#define R_VECT_MASK_RD__dma2__BITNR 18
+#define R_VECT_MASK_RD__dma2__WIDTH 1
+#define R_VECT_MASK_RD__dma2__active 1
+#define R_VECT_MASK_RD__dma2__inactive 0
+#define R_VECT_MASK_RD__dma1__BITNR 17
+#define R_VECT_MASK_RD__dma1__WIDTH 1
+#define R_VECT_MASK_RD__dma1__active 1
+#define R_VECT_MASK_RD__dma1__inactive 0
+#define R_VECT_MASK_RD__dma0__BITNR 16
+#define R_VECT_MASK_RD__dma0__WIDTH 1
+#define R_VECT_MASK_RD__dma0__active 1
+#define R_VECT_MASK_RD__dma0__inactive 0
+#define R_VECT_MASK_RD__ext_dma1__BITNR 13
+#define R_VECT_MASK_RD__ext_dma1__WIDTH 1
+#define R_VECT_MASK_RD__ext_dma1__active 1
+#define R_VECT_MASK_RD__ext_dma1__inactive 0
+#define R_VECT_MASK_RD__ext_dma0__BITNR 12
+#define R_VECT_MASK_RD__ext_dma0__WIDTH 1
+#define R_VECT_MASK_RD__ext_dma0__active 1
+#define R_VECT_MASK_RD__ext_dma0__inactive 0
+#define R_VECT_MASK_RD__pa__BITNR 11
+#define R_VECT_MASK_RD__pa__WIDTH 1
+#define R_VECT_MASK_RD__pa__active 1
+#define R_VECT_MASK_RD__pa__inactive 0
+#define R_VECT_MASK_RD__irq_intnr__BITNR 10
+#define R_VECT_MASK_RD__irq_intnr__WIDTH 1
+#define R_VECT_MASK_RD__irq_intnr__active 1
+#define R_VECT_MASK_RD__irq_intnr__inactive 0
+#define R_VECT_MASK_RD__sw__BITNR 9
+#define R_VECT_MASK_RD__sw__WIDTH 1
+#define R_VECT_MASK_RD__sw__active 1
+#define R_VECT_MASK_RD__sw__inactive 0
+#define R_VECT_MASK_RD__serial__BITNR 8
+#define R_VECT_MASK_RD__serial__WIDTH 1
+#define R_VECT_MASK_RD__serial__active 1
+#define R_VECT_MASK_RD__serial__inactive 0
+#define R_VECT_MASK_RD__snmp__BITNR 7
+#define R_VECT_MASK_RD__snmp__WIDTH 1
+#define R_VECT_MASK_RD__snmp__active 1
+#define R_VECT_MASK_RD__snmp__inactive 0
+#define R_VECT_MASK_RD__network__BITNR 6
+#define R_VECT_MASK_RD__network__WIDTH 1
+#define R_VECT_MASK_RD__network__active 1
+#define R_VECT_MASK_RD__network__inactive 0
+#define R_VECT_MASK_RD__scsi1__BITNR 5
+#define R_VECT_MASK_RD__scsi1__WIDTH 1
+#define R_VECT_MASK_RD__scsi1__active 1
+#define R_VECT_MASK_RD__scsi1__inactive 0
+#define R_VECT_MASK_RD__par1__BITNR 5
+#define R_VECT_MASK_RD__par1__WIDTH 1
+#define R_VECT_MASK_RD__par1__active 1
+#define R_VECT_MASK_RD__par1__inactive 0
+#define R_VECT_MASK_RD__scsi0__BITNR 4
+#define R_VECT_MASK_RD__scsi0__WIDTH 1
+#define R_VECT_MASK_RD__scsi0__active 1
+#define R_VECT_MASK_RD__scsi0__inactive 0
+#define R_VECT_MASK_RD__par0__BITNR 4
+#define R_VECT_MASK_RD__par0__WIDTH 1
+#define R_VECT_MASK_RD__par0__active 1
+#define R_VECT_MASK_RD__par0__inactive 0
+#define R_VECT_MASK_RD__ata__BITNR 4
+#define R_VECT_MASK_RD__ata__WIDTH 1
+#define R_VECT_MASK_RD__ata__active 1
+#define R_VECT_MASK_RD__ata__inactive 0
+#define R_VECT_MASK_RD__mio__BITNR 4
+#define R_VECT_MASK_RD__mio__WIDTH 1
+#define R_VECT_MASK_RD__mio__active 1
+#define R_VECT_MASK_RD__mio__inactive 0
+#define R_VECT_MASK_RD__p21__BITNR 4
+#define R_VECT_MASK_RD__p21__WIDTH 1
+#define R_VECT_MASK_RD__p21__active 1
+#define R_VECT_MASK_RD__p21__inactive 0
+#define R_VECT_MASK_RD__timer1__BITNR 3
+#define R_VECT_MASK_RD__timer1__WIDTH 1
+#define R_VECT_MASK_RD__timer1__active 1
+#define R_VECT_MASK_RD__timer1__inactive 0
+#define R_VECT_MASK_RD__timer0__BITNR 2
+#define R_VECT_MASK_RD__timer0__WIDTH 1
+#define R_VECT_MASK_RD__timer0__active 1
+#define R_VECT_MASK_RD__timer0__inactive 0
+#define R_VECT_MASK_RD__nmi__BITNR 1
+#define R_VECT_MASK_RD__nmi__WIDTH 1
+#define R_VECT_MASK_RD__nmi__active 1
+#define R_VECT_MASK_RD__nmi__inactive 0
+#define R_VECT_MASK_RD__some__BITNR 0
+#define R_VECT_MASK_RD__some__WIDTH 1
+#define R_VECT_MASK_RD__some__active 1
+#define R_VECT_MASK_RD__some__inactive 0
+
+#define R_VECT_MASK_CLR (IO_TYPECAST_UDWORD 0xb00000d8)
+#define R_VECT_MASK_CLR__usb__BITNR 31
+#define R_VECT_MASK_CLR__usb__WIDTH 1
+#define R_VECT_MASK_CLR__usb__clr 1
+#define R_VECT_MASK_CLR__usb__nop 0
+#define R_VECT_MASK_CLR__dma9__BITNR 25
+#define R_VECT_MASK_CLR__dma9__WIDTH 1
+#define R_VECT_MASK_CLR__dma9__clr 1
+#define R_VECT_MASK_CLR__dma9__nop 0
+#define R_VECT_MASK_CLR__dma8__BITNR 24
+#define R_VECT_MASK_CLR__dma8__WIDTH 1
+#define R_VECT_MASK_CLR__dma8__clr 1
+#define R_VECT_MASK_CLR__dma8__nop 0
+#define R_VECT_MASK_CLR__dma7__BITNR 23
+#define R_VECT_MASK_CLR__dma7__WIDTH 1
+#define R_VECT_MASK_CLR__dma7__clr 1
+#define R_VECT_MASK_CLR__dma7__nop 0
+#define R_VECT_MASK_CLR__dma6__BITNR 22
+#define R_VECT_MASK_CLR__dma6__WIDTH 1
+#define R_VECT_MASK_CLR__dma6__clr 1
+#define R_VECT_MASK_CLR__dma6__nop 0
+#define R_VECT_MASK_CLR__dma5__BITNR 21
+#define R_VECT_MASK_CLR__dma5__WIDTH 1
+#define R_VECT_MASK_CLR__dma5__clr 1
+#define R_VECT_MASK_CLR__dma5__nop 0
+#define R_VECT_MASK_CLR__dma4__BITNR 20
+#define R_VECT_MASK_CLR__dma4__WIDTH 1
+#define R_VECT_MASK_CLR__dma4__clr 1
+#define R_VECT_MASK_CLR__dma4__nop 0
+#define R_VECT_MASK_CLR__dma3__BITNR 19
+#define R_VECT_MASK_CLR__dma3__WIDTH 1
+#define R_VECT_MASK_CLR__dma3__clr 1
+#define R_VECT_MASK_CLR__dma3__nop 0
+#define R_VECT_MASK_CLR__dma2__BITNR 18
+#define R_VECT_MASK_CLR__dma2__WIDTH 1
+#define R_VECT_MASK_CLR__dma2__clr 1
+#define R_VECT_MASK_CLR__dma2__nop 0
+#define R_VECT_MASK_CLR__dma1__BITNR 17
+#define R_VECT_MASK_CLR__dma1__WIDTH 1
+#define R_VECT_MASK_CLR__dma1__clr 1
+#define R_VECT_MASK_CLR__dma1__nop 0
+#define R_VECT_MASK_CLR__dma0__BITNR 16
+#define R_VECT_MASK_CLR__dma0__WIDTH 1
+#define R_VECT_MASK_CLR__dma0__clr 1
+#define R_VECT_MASK_CLR__dma0__nop 0
+#define R_VECT_MASK_CLR__ext_dma1__BITNR 13
+#define R_VECT_MASK_CLR__ext_dma1__WIDTH 1
+#define R_VECT_MASK_CLR__ext_dma1__clr 1
+#define R_VECT_MASK_CLR__ext_dma1__nop 0
+#define R_VECT_MASK_CLR__ext_dma0__BITNR 12
+#define R_VECT_MASK_CLR__ext_dma0__WIDTH 1
+#define R_VECT_MASK_CLR__ext_dma0__clr 1
+#define R_VECT_MASK_CLR__ext_dma0__nop 0
+#define R_VECT_MASK_CLR__pa__BITNR 11
+#define R_VECT_MASK_CLR__pa__WIDTH 1
+#define R_VECT_MASK_CLR__pa__clr 1
+#define R_VECT_MASK_CLR__pa__nop 0
+#define R_VECT_MASK_CLR__irq_intnr__BITNR 10
+#define R_VECT_MASK_CLR__irq_intnr__WIDTH 1
+#define R_VECT_MASK_CLR__irq_intnr__clr 1
+#define R_VECT_MASK_CLR__irq_intnr__nop 0
+#define R_VECT_MASK_CLR__sw__BITNR 9
+#define R_VECT_MASK_CLR__sw__WIDTH 1
+#define R_VECT_MASK_CLR__sw__clr 1
+#define R_VECT_MASK_CLR__sw__nop 0
+#define R_VECT_MASK_CLR__serial__BITNR 8
+#define R_VECT_MASK_CLR__serial__WIDTH 1
+#define R_VECT_MASK_CLR__serial__clr 1
+#define R_VECT_MASK_CLR__serial__nop 0
+#define R_VECT_MASK_CLR__snmp__BITNR 7
+#define R_VECT_MASK_CLR__snmp__WIDTH 1
+#define R_VECT_MASK_CLR__snmp__clr 1
+#define R_VECT_MASK_CLR__snmp__nop 0
+#define R_VECT_MASK_CLR__network__BITNR 6
+#define R_VECT_MASK_CLR__network__WIDTH 1
+#define R_VECT_MASK_CLR__network__clr 1
+#define R_VECT_MASK_CLR__network__nop 0
+#define R_VECT_MASK_CLR__scsi1__BITNR 5
+#define R_VECT_MASK_CLR__scsi1__WIDTH 1
+#define R_VECT_MASK_CLR__scsi1__clr 1
+#define R_VECT_MASK_CLR__scsi1__nop 0
+#define R_VECT_MASK_CLR__par1__BITNR 5
+#define R_VECT_MASK_CLR__par1__WIDTH 1
+#define R_VECT_MASK_CLR__par1__clr 1
+#define R_VECT_MASK_CLR__par1__nop 0
+#define R_VECT_MASK_CLR__scsi0__BITNR 4
+#define R_VECT_MASK_CLR__scsi0__WIDTH 1
+#define R_VECT_MASK_CLR__scsi0__clr 1
+#define R_VECT_MASK_CLR__scsi0__nop 0
+#define R_VECT_MASK_CLR__par0__BITNR 4
+#define R_VECT_MASK_CLR__par0__WIDTH 1
+#define R_VECT_MASK_CLR__par0__clr 1
+#define R_VECT_MASK_CLR__par0__nop 0
+#define R_VECT_MASK_CLR__ata__BITNR 4
+#define R_VECT_MASK_CLR__ata__WIDTH 1
+#define R_VECT_MASK_CLR__ata__clr 1
+#define R_VECT_MASK_CLR__ata__nop 0
+#define R_VECT_MASK_CLR__mio__BITNR 4
+#define R_VECT_MASK_CLR__mio__WIDTH 1
+#define R_VECT_MASK_CLR__mio__clr 1
+#define R_VECT_MASK_CLR__mio__nop 0
+#define R_VECT_MASK_CLR__p21__BITNR 4
+#define R_VECT_MASK_CLR__p21__WIDTH 1
+#define R_VECT_MASK_CLR__p21__clr 1
+#define R_VECT_MASK_CLR__p21__nop 0
+#define R_VECT_MASK_CLR__timer1__BITNR 3
+#define R_VECT_MASK_CLR__timer1__WIDTH 1
+#define R_VECT_MASK_CLR__timer1__clr 1
+#define R_VECT_MASK_CLR__timer1__nop 0
+#define R_VECT_MASK_CLR__timer0__BITNR 2
+#define R_VECT_MASK_CLR__timer0__WIDTH 1
+#define R_VECT_MASK_CLR__timer0__clr 1
+#define R_VECT_MASK_CLR__timer0__nop 0
+#define R_VECT_MASK_CLR__nmi__BITNR 1
+#define R_VECT_MASK_CLR__nmi__WIDTH 1
+#define R_VECT_MASK_CLR__nmi__clr 1
+#define R_VECT_MASK_CLR__nmi__nop 0
+#define R_VECT_MASK_CLR__some__BITNR 0
+#define R_VECT_MASK_CLR__some__WIDTH 1
+#define R_VECT_MASK_CLR__some__clr 1
+#define R_VECT_MASK_CLR__some__nop 0
+
+#define R_VECT_READ (IO_TYPECAST_RO_UDWORD 0xb00000dc)
+#define R_VECT_READ__usb__BITNR 31
+#define R_VECT_READ__usb__WIDTH 1
+#define R_VECT_READ__usb__active 1
+#define R_VECT_READ__usb__inactive 0
+#define R_VECT_READ__dma9__BITNR 25
+#define R_VECT_READ__dma9__WIDTH 1
+#define R_VECT_READ__dma9__active 1
+#define R_VECT_READ__dma9__inactive 0
+#define R_VECT_READ__dma8__BITNR 24
+#define R_VECT_READ__dma8__WIDTH 1
+#define R_VECT_READ__dma8__active 1
+#define R_VECT_READ__dma8__inactive 0
+#define R_VECT_READ__dma7__BITNR 23
+#define R_VECT_READ__dma7__WIDTH 1
+#define R_VECT_READ__dma7__active 1
+#define R_VECT_READ__dma7__inactive 0
+#define R_VECT_READ__dma6__BITNR 22
+#define R_VECT_READ__dma6__WIDTH 1
+#define R_VECT_READ__dma6__active 1
+#define R_VECT_READ__dma6__inactive 0
+#define R_VECT_READ__dma5__BITNR 21
+#define R_VECT_READ__dma5__WIDTH 1
+#define R_VECT_READ__dma5__active 1
+#define R_VECT_READ__dma5__inactive 0
+#define R_VECT_READ__dma4__BITNR 20
+#define R_VECT_READ__dma4__WIDTH 1
+#define R_VECT_READ__dma4__active 1
+#define R_VECT_READ__dma4__inactive 0
+#define R_VECT_READ__dma3__BITNR 19
+#define R_VECT_READ__dma3__WIDTH 1
+#define R_VECT_READ__dma3__active 1
+#define R_VECT_READ__dma3__inactive 0
+#define R_VECT_READ__dma2__BITNR 18
+#define R_VECT_READ__dma2__WIDTH 1
+#define R_VECT_READ__dma2__active 1
+#define R_VECT_READ__dma2__inactive 0
+#define R_VECT_READ__dma1__BITNR 17
+#define R_VECT_READ__dma1__WIDTH 1
+#define R_VECT_READ__dma1__active 1
+#define R_VECT_READ__dma1__inactive 0
+#define R_VECT_READ__dma0__BITNR 16
+#define R_VECT_READ__dma0__WIDTH 1
+#define R_VECT_READ__dma0__active 1
+#define R_VECT_READ__dma0__inactive 0
+#define R_VECT_READ__ext_dma1__BITNR 13
+#define R_VECT_READ__ext_dma1__WIDTH 1
+#define R_VECT_READ__ext_dma1__active 1
+#define R_VECT_READ__ext_dma1__inactive 0
+#define R_VECT_READ__ext_dma0__BITNR 12
+#define R_VECT_READ__ext_dma0__WIDTH 1
+#define R_VECT_READ__ext_dma0__active 1
+#define R_VECT_READ__ext_dma0__inactive 0
+#define R_VECT_READ__pa__BITNR 11
+#define R_VECT_READ__pa__WIDTH 1
+#define R_VECT_READ__pa__active 1
+#define R_VECT_READ__pa__inactive 0
+#define R_VECT_READ__irq_intnr__BITNR 10
+#define R_VECT_READ__irq_intnr__WIDTH 1
+#define R_VECT_READ__irq_intnr__active 1
+#define R_VECT_READ__irq_intnr__inactive 0
+#define R_VECT_READ__sw__BITNR 9
+#define R_VECT_READ__sw__WIDTH 1
+#define R_VECT_READ__sw__active 1
+#define R_VECT_READ__sw__inactive 0
+#define R_VECT_READ__serial__BITNR 8
+#define R_VECT_READ__serial__WIDTH 1
+#define R_VECT_READ__serial__active 1
+#define R_VECT_READ__serial__inactive 0
+#define R_VECT_READ__snmp__BITNR 7
+#define R_VECT_READ__snmp__WIDTH 1
+#define R_VECT_READ__snmp__active 1
+#define R_VECT_READ__snmp__inactive 0
+#define R_VECT_READ__network__BITNR 6
+#define R_VECT_READ__network__WIDTH 1
+#define R_VECT_READ__network__active 1
+#define R_VECT_READ__network__inactive 0
+#define R_VECT_READ__scsi1__BITNR 5
+#define R_VECT_READ__scsi1__WIDTH 1
+#define R_VECT_READ__scsi1__active 1
+#define R_VECT_READ__scsi1__inactive 0
+#define R_VECT_READ__par1__BITNR 5
+#define R_VECT_READ__par1__WIDTH 1
+#define R_VECT_READ__par1__active 1
+#define R_VECT_READ__par1__inactive 0
+#define R_VECT_READ__scsi0__BITNR 4
+#define R_VECT_READ__scsi0__WIDTH 1
+#define R_VECT_READ__scsi0__active 1
+#define R_VECT_READ__scsi0__inactive 0
+#define R_VECT_READ__par0__BITNR 4
+#define R_VECT_READ__par0__WIDTH 1
+#define R_VECT_READ__par0__active 1
+#define R_VECT_READ__par0__inactive 0
+#define R_VECT_READ__ata__BITNR 4
+#define R_VECT_READ__ata__WIDTH 1
+#define R_VECT_READ__ata__active 1
+#define R_VECT_READ__ata__inactive 0
+#define R_VECT_READ__mio__BITNR 4
+#define R_VECT_READ__mio__WIDTH 1
+#define R_VECT_READ__mio__active 1
+#define R_VECT_READ__mio__inactive 0
+#define R_VECT_READ__p21__BITNR 4
+#define R_VECT_READ__p21__WIDTH 1
+#define R_VECT_READ__p21__active 1
+#define R_VECT_READ__p21__inactive 0
+#define R_VECT_READ__timer1__BITNR 3
+#define R_VECT_READ__timer1__WIDTH 1
+#define R_VECT_READ__timer1__active 1
+#define R_VECT_READ__timer1__inactive 0
+#define R_VECT_READ__timer0__BITNR 2
+#define R_VECT_READ__timer0__WIDTH 1
+#define R_VECT_READ__timer0__active 1
+#define R_VECT_READ__timer0__inactive 0
+#define R_VECT_READ__nmi__BITNR 1
+#define R_VECT_READ__nmi__WIDTH 1
+#define R_VECT_READ__nmi__active 1
+#define R_VECT_READ__nmi__inactive 0
+#define R_VECT_READ__some__BITNR 0
+#define R_VECT_READ__some__WIDTH 1
+#define R_VECT_READ__some__active 1
+#define R_VECT_READ__some__inactive 0
+
+#define R_VECT_MASK_SET (IO_TYPECAST_UDWORD 0xb00000dc)
+#define R_VECT_MASK_SET__usb__BITNR 31
+#define R_VECT_MASK_SET__usb__WIDTH 1
+#define R_VECT_MASK_SET__usb__set 1
+#define R_VECT_MASK_SET__usb__nop 0
+#define R_VECT_MASK_SET__dma9__BITNR 25
+#define R_VECT_MASK_SET__dma9__WIDTH 1
+#define R_VECT_MASK_SET__dma9__set 1
+#define R_VECT_MASK_SET__dma9__nop 0
+#define R_VECT_MASK_SET__dma8__BITNR 24
+#define R_VECT_MASK_SET__dma8__WIDTH 1
+#define R_VECT_MASK_SET__dma8__set 1
+#define R_VECT_MASK_SET__dma8__nop 0
+#define R_VECT_MASK_SET__dma7__BITNR 23
+#define R_VECT_MASK_SET__dma7__WIDTH 1
+#define R_VECT_MASK_SET__dma7__set 1
+#define R_VECT_MASK_SET__dma7__nop 0
+#define R_VECT_MASK_SET__dma6__BITNR 22
+#define R_VECT_MASK_SET__dma6__WIDTH 1
+#define R_VECT_MASK_SET__dma6__set 1
+#define R_VECT_MASK_SET__dma6__nop 0
+#define R_VECT_MASK_SET__dma5__BITNR 21
+#define R_VECT_MASK_SET__dma5__WIDTH 1
+#define R_VECT_MASK_SET__dma5__set 1
+#define R_VECT_MASK_SET__dma5__nop 0
+#define R_VECT_MASK_SET__dma4__BITNR 20
+#define R_VECT_MASK_SET__dma4__WIDTH 1
+#define R_VECT_MASK_SET__dma4__set 1
+#define R_VECT_MASK_SET__dma4__nop 0
+#define R_VECT_MASK_SET__dma3__BITNR 19
+#define R_VECT_MASK_SET__dma3__WIDTH 1
+#define R_VECT_MASK_SET__dma3__set 1
+#define R_VECT_MASK_SET__dma3__nop 0
+#define R_VECT_MASK_SET__dma2__BITNR 18
+#define R_VECT_MASK_SET__dma2__WIDTH 1
+#define R_VECT_MASK_SET__dma2__set 1
+#define R_VECT_MASK_SET__dma2__nop 0
+#define R_VECT_MASK_SET__dma1__BITNR 17
+#define R_VECT_MASK_SET__dma1__WIDTH 1
+#define R_VECT_MASK_SET__dma1__set 1
+#define R_VECT_MASK_SET__dma1__nop 0
+#define R_VECT_MASK_SET__dma0__BITNR 16
+#define R_VECT_MASK_SET__dma0__WIDTH 1
+#define R_VECT_MASK_SET__dma0__set 1
+#define R_VECT_MASK_SET__dma0__nop 0
+#define R_VECT_MASK_SET__ext_dma1__BITNR 13
+#define R_VECT_MASK_SET__ext_dma1__WIDTH 1
+#define R_VECT_MASK_SET__ext_dma1__set 1
+#define R_VECT_MASK_SET__ext_dma1__nop 0
+#define R_VECT_MASK_SET__ext_dma0__BITNR 12
+#define R_VECT_MASK_SET__ext_dma0__WIDTH 1
+#define R_VECT_MASK_SET__ext_dma0__set 1
+#define R_VECT_MASK_SET__ext_dma0__nop 0
+#define R_VECT_MASK_SET__pa__BITNR 11
+#define R_VECT_MASK_SET__pa__WIDTH 1
+#define R_VECT_MASK_SET__pa__set 1
+#define R_VECT_MASK_SET__pa__nop 0
+#define R_VECT_MASK_SET__irq_intnr__BITNR 10
+#define R_VECT_MASK_SET__irq_intnr__WIDTH 1
+#define R_VECT_MASK_SET__irq_intnr__set 1
+#define R_VECT_MASK_SET__irq_intnr__nop 0
+#define R_VECT_MASK_SET__sw__BITNR 9
+#define R_VECT_MASK_SET__sw__WIDTH 1
+#define R_VECT_MASK_SET__sw__set 1
+#define R_VECT_MASK_SET__sw__nop 0
+#define R_VECT_MASK_SET__serial__BITNR 8
+#define R_VECT_MASK_SET__serial__WIDTH 1
+#define R_VECT_MASK_SET__serial__set 1
+#define R_VECT_MASK_SET__serial__nop 0
+#define R_VECT_MASK_SET__snmp__BITNR 7
+#define R_VECT_MASK_SET__snmp__WIDTH 1
+#define R_VECT_MASK_SET__snmp__set 1
+#define R_VECT_MASK_SET__snmp__nop 0
+#define R_VECT_MASK_SET__network__BITNR 6
+#define R_VECT_MASK_SET__network__WIDTH 1
+#define R_VECT_MASK_SET__network__set 1
+#define R_VECT_MASK_SET__network__nop 0
+#define R_VECT_MASK_SET__scsi1__BITNR 5
+#define R_VECT_MASK_SET__scsi1__WIDTH 1
+#define R_VECT_MASK_SET__scsi1__set 1
+#define R_VECT_MASK_SET__scsi1__nop 0
+#define R_VECT_MASK_SET__par1__BITNR 5
+#define R_VECT_MASK_SET__par1__WIDTH 1
+#define R_VECT_MASK_SET__par1__set 1
+#define R_VECT_MASK_SET__par1__nop 0
+#define R_VECT_MASK_SET__scsi0__BITNR 4
+#define R_VECT_MASK_SET__scsi0__WIDTH 1
+#define R_VECT_MASK_SET__scsi0__set 1
+#define R_VECT_MASK_SET__scsi0__nop 0
+#define R_VECT_MASK_SET__par0__BITNR 4
+#define R_VECT_MASK_SET__par0__WIDTH 1
+#define R_VECT_MASK_SET__par0__set 1
+#define R_VECT_MASK_SET__par0__nop 0
+#define R_VECT_MASK_SET__ata__BITNR 4
+#define R_VECT_MASK_SET__ata__WIDTH 1
+#define R_VECT_MASK_SET__ata__set 1
+#define R_VECT_MASK_SET__ata__nop 0
+#define R_VECT_MASK_SET__mio__BITNR 4
+#define R_VECT_MASK_SET__mio__WIDTH 1
+#define R_VECT_MASK_SET__mio__set 1
+#define R_VECT_MASK_SET__mio__nop 0
+#define R_VECT_MASK_SET__p21__BITNR 4
+#define R_VECT_MASK_SET__p21__WIDTH 1
+#define R_VECT_MASK_SET__p21__set 1
+#define R_VECT_MASK_SET__p21__nop 0
+#define R_VECT_MASK_SET__timer1__BITNR 3
+#define R_VECT_MASK_SET__timer1__WIDTH 1
+#define R_VECT_MASK_SET__timer1__set 1
+#define R_VECT_MASK_SET__timer1__nop 0
+#define R_VECT_MASK_SET__timer0__BITNR 2
+#define R_VECT_MASK_SET__timer0__WIDTH 1
+#define R_VECT_MASK_SET__timer0__set 1
+#define R_VECT_MASK_SET__timer0__nop 0
+#define R_VECT_MASK_SET__nmi__BITNR 1
+#define R_VECT_MASK_SET__nmi__WIDTH 1
+#define R_VECT_MASK_SET__nmi__set 1
+#define R_VECT_MASK_SET__nmi__nop 0
+#define R_VECT_MASK_SET__some__BITNR 0
+#define R_VECT_MASK_SET__some__WIDTH 1
+#define R_VECT_MASK_SET__some__set 1
+#define R_VECT_MASK_SET__some__nop 0
+
+/*
+!* DMA registers
+!*/
+
+#define R_SET_EOP (IO_TYPECAST_UDWORD 0xb000003c)
+#define R_SET_EOP__ch9_eop__BITNR 3
+#define R_SET_EOP__ch9_eop__WIDTH 1
+#define R_SET_EOP__ch9_eop__set 1
+#define R_SET_EOP__ch9_eop__nop 0
+#define R_SET_EOP__ch7_eop__BITNR 2
+#define R_SET_EOP__ch7_eop__WIDTH 1
+#define R_SET_EOP__ch7_eop__set 1
+#define R_SET_EOP__ch7_eop__nop 0
+#define R_SET_EOP__ch5_eop__BITNR 1
+#define R_SET_EOP__ch5_eop__WIDTH 1
+#define R_SET_EOP__ch5_eop__set 1
+#define R_SET_EOP__ch5_eop__nop 0
+#define R_SET_EOP__ch3_eop__BITNR 0
+#define R_SET_EOP__ch3_eop__WIDTH 1
+#define R_SET_EOP__ch3_eop__set 1
+#define R_SET_EOP__ch3_eop__nop 0
+
+#define R_DMA_CH0_HWSW (IO_TYPECAST_UDWORD 0xb0000100)
+#define R_DMA_CH0_HWSW__hw__BITNR 16
+#define R_DMA_CH0_HWSW__hw__WIDTH 16
+#define R_DMA_CH0_HWSW__sw__BITNR 0
+#define R_DMA_CH0_HWSW__sw__WIDTH 16
+
+#define R_DMA_CH0_DESCR (IO_TYPECAST_UDWORD 0xb000010c)
+#define R_DMA_CH0_DESCR__descr__BITNR 0
+#define R_DMA_CH0_DESCR__descr__WIDTH 32
+
+#define R_DMA_CH0_NEXT (IO_TYPECAST_UDWORD 0xb0000104)
+#define R_DMA_CH0_NEXT__next__BITNR 0
+#define R_DMA_CH0_NEXT__next__WIDTH 32
+
+#define R_DMA_CH0_BUF (IO_TYPECAST_UDWORD 0xb0000108)
+#define R_DMA_CH0_BUF__buf__BITNR 0
+#define R_DMA_CH0_BUF__buf__WIDTH 32
+
+#define R_DMA_CH0_FIRST (IO_TYPECAST_UDWORD 0xb00001a0)
+#define R_DMA_CH0_FIRST__first__BITNR 0
+#define R_DMA_CH0_FIRST__first__WIDTH 32
+
+#define R_DMA_CH0_CMD (IO_TYPECAST_BYTE 0xb00001d0)
+#define R_DMA_CH0_CMD__cmd__BITNR 0
+#define R_DMA_CH0_CMD__cmd__WIDTH 3
+#define R_DMA_CH0_CMD__cmd__hold 0
+#define R_DMA_CH0_CMD__cmd__start 1
+#define R_DMA_CH0_CMD__cmd__restart 3
+#define R_DMA_CH0_CMD__cmd__continue 3
+#define R_DMA_CH0_CMD__cmd__reset 4
+
+#define R_DMA_CH0_CLR_INTR (IO_TYPECAST_BYTE 0xb00001d1)
+#define R_DMA_CH0_CLR_INTR__clr_eop__BITNR 1
+#define R_DMA_CH0_CLR_INTR__clr_eop__WIDTH 1
+#define R_DMA_CH0_CLR_INTR__clr_eop__do 1
+#define R_DMA_CH0_CLR_INTR__clr_eop__dont 0
+#define R_DMA_CH0_CLR_INTR__clr_descr__BITNR 0
+#define R_DMA_CH0_CLR_INTR__clr_descr__WIDTH 1
+#define R_DMA_CH0_CLR_INTR__clr_descr__do 1
+#define R_DMA_CH0_CLR_INTR__clr_descr__dont 0
+
+#define R_DMA_CH0_STATUS (IO_TYPECAST_RO_BYTE 0xb00001d2)
+#define R_DMA_CH0_STATUS__avail__BITNR 0
+#define R_DMA_CH0_STATUS__avail__WIDTH 7
+
+#define R_DMA_CH1_HWSW (IO_TYPECAST_UDWORD 0xb0000110)
+#define R_DMA_CH1_HWSW__hw__BITNR 16
+#define R_DMA_CH1_HWSW__hw__WIDTH 16
+#define R_DMA_CH1_HWSW__sw__BITNR 0
+#define R_DMA_CH1_HWSW__sw__WIDTH 16
+
+#define R_DMA_CH1_DESCR (IO_TYPECAST_UDWORD 0xb000011c)
+#define R_DMA_CH1_DESCR__descr__BITNR 0
+#define R_DMA_CH1_DESCR__descr__WIDTH 32
+
+#define R_DMA_CH1_NEXT (IO_TYPECAST_UDWORD 0xb0000114)
+#define R_DMA_CH1_NEXT__next__BITNR 0
+#define R_DMA_CH1_NEXT__next__WIDTH 32
+
+#define R_DMA_CH1_BUF (IO_TYPECAST_UDWORD 0xb0000118)
+#define R_DMA_CH1_BUF__buf__BITNR 0
+#define R_DMA_CH1_BUF__buf__WIDTH 32
+
+#define R_DMA_CH1_FIRST (IO_TYPECAST_UDWORD 0xb00001a4)
+#define R_DMA_CH1_FIRST__first__BITNR 0
+#define R_DMA_CH1_FIRST__first__WIDTH 32
+
+#define R_DMA_CH1_CMD (IO_TYPECAST_BYTE 0xb00001d4)
+#define R_DMA_CH1_CMD__cmd__BITNR 0
+#define R_DMA_CH1_CMD__cmd__WIDTH 3
+#define R_DMA_CH1_CMD__cmd__hold 0
+#define R_DMA_CH1_CMD__cmd__start 1
+#define R_DMA_CH1_CMD__cmd__restart 3
+#define R_DMA_CH1_CMD__cmd__continue 3
+#define R_DMA_CH1_CMD__cmd__reset 4
+
+#define R_DMA_CH1_CLR_INTR (IO_TYPECAST_BYTE 0xb00001d5)
+#define R_DMA_CH1_CLR_INTR__clr_eop__BITNR 1
+#define R_DMA_CH1_CLR_INTR__clr_eop__WIDTH 1
+#define R_DMA_CH1_CLR_INTR__clr_eop__do 1
+#define R_DMA_CH1_CLR_INTR__clr_eop__dont 0
+#define R_DMA_CH1_CLR_INTR__clr_descr__BITNR 0
+#define R_DMA_CH1_CLR_INTR__clr_descr__WIDTH 1
+#define R_DMA_CH1_CLR_INTR__clr_descr__do 1
+#define R_DMA_CH1_CLR_INTR__clr_descr__dont 0
+
+#define R_DMA_CH1_STATUS (IO_TYPECAST_RO_BYTE 0xb00001d6)
+#define R_DMA_CH1_STATUS__avail__BITNR 0
+#define R_DMA_CH1_STATUS__avail__WIDTH 7
+
+#define R_DMA_CH2_HWSW (IO_TYPECAST_UDWORD 0xb0000120)
+#define R_DMA_CH2_HWSW__hw__BITNR 16
+#define R_DMA_CH2_HWSW__hw__WIDTH 16
+#define R_DMA_CH2_HWSW__sw__BITNR 0
+#define R_DMA_CH2_HWSW__sw__WIDTH 16
+
+#define R_DMA_CH2_DESCR (IO_TYPECAST_UDWORD 0xb000012c)
+#define R_DMA_CH2_DESCR__descr__BITNR 0
+#define R_DMA_CH2_DESCR__descr__WIDTH 32
+
+#define R_DMA_CH2_NEXT (IO_TYPECAST_UDWORD 0xb0000124)
+#define R_DMA_CH2_NEXT__next__BITNR 0
+#define R_DMA_CH2_NEXT__next__WIDTH 32
+
+#define R_DMA_CH2_BUF (IO_TYPECAST_UDWORD 0xb0000128)
+#define R_DMA_CH2_BUF__buf__BITNR 0
+#define R_DMA_CH2_BUF__buf__WIDTH 32
+
+#define R_DMA_CH2_FIRST (IO_TYPECAST_UDWORD 0xb00001a8)
+#define R_DMA_CH2_FIRST__first__BITNR 0
+#define R_DMA_CH2_FIRST__first__WIDTH 32
+
+#define R_DMA_CH2_CMD (IO_TYPECAST_BYTE 0xb00001d8)
+#define R_DMA_CH2_CMD__cmd__BITNR 0
+#define R_DMA_CH2_CMD__cmd__WIDTH 3
+#define R_DMA_CH2_CMD__cmd__hold 0
+#define R_DMA_CH2_CMD__cmd__start 1
+#define R_DMA_CH2_CMD__cmd__restart 3
+#define R_DMA_CH2_CMD__cmd__continue 3
+#define R_DMA_CH2_CMD__cmd__reset 4
+
+#define R_DMA_CH2_CLR_INTR (IO_TYPECAST_BYTE 0xb00001d9)
+#define R_DMA_CH2_CLR_INTR__clr_eop__BITNR 1
+#define R_DMA_CH2_CLR_INTR__clr_eop__WIDTH 1
+#define R_DMA_CH2_CLR_INTR__clr_eop__do 1
+#define R_DMA_CH2_CLR_INTR__clr_eop__dont 0
+#define R_DMA_CH2_CLR_INTR__clr_descr__BITNR 0
+#define R_DMA_CH2_CLR_INTR__clr_descr__WIDTH 1
+#define R_DMA_CH2_CLR_INTR__clr_descr__do 1
+#define R_DMA_CH2_CLR_INTR__clr_descr__dont 0
+
+#define R_DMA_CH2_STATUS (IO_TYPECAST_RO_BYTE 0xb00001da)
+#define R_DMA_CH2_STATUS__avail__BITNR 0
+#define R_DMA_CH2_STATUS__avail__WIDTH 7
+
+#define R_DMA_CH3_HWSW (IO_TYPECAST_UDWORD 0xb0000130)
+#define R_DMA_CH3_HWSW__hw__BITNR 16
+#define R_DMA_CH3_HWSW__hw__WIDTH 16
+#define R_DMA_CH3_HWSW__sw__BITNR 0
+#define R_DMA_CH3_HWSW__sw__WIDTH 16
+
+#define R_DMA_CH3_DESCR (IO_TYPECAST_UDWORD 0xb000013c)
+#define R_DMA_CH3_DESCR__descr__BITNR 0
+#define R_DMA_CH3_DESCR__descr__WIDTH 32
+
+#define R_DMA_CH3_NEXT (IO_TYPECAST_UDWORD 0xb0000134)
+#define R_DMA_CH3_NEXT__next__BITNR 0
+#define R_DMA_CH3_NEXT__next__WIDTH 32
+
+#define R_DMA_CH3_BUF (IO_TYPECAST_UDWORD 0xb0000138)
+#define R_DMA_CH3_BUF__buf__BITNR 0
+#define R_DMA_CH3_BUF__buf__WIDTH 32
+
+#define R_DMA_CH3_FIRST (IO_TYPECAST_UDWORD 0xb00001ac)
+#define R_DMA_CH3_FIRST__first__BITNR 0
+#define R_DMA_CH3_FIRST__first__WIDTH 32
+
+#define R_DMA_CH3_CMD (IO_TYPECAST_BYTE 0xb00001dc)
+#define R_DMA_CH3_CMD__cmd__BITNR 0
+#define R_DMA_CH3_CMD__cmd__WIDTH 3
+#define R_DMA_CH3_CMD__cmd__hold 0
+#define R_DMA_CH3_CMD__cmd__start 1
+#define R_DMA_CH3_CMD__cmd__restart 3
+#define R_DMA_CH3_CMD__cmd__continue 3
+#define R_DMA_CH3_CMD__cmd__reset 4
+
+#define R_DMA_CH3_CLR_INTR (IO_TYPECAST_BYTE 0xb00001dd)
+#define R_DMA_CH3_CLR_INTR__clr_eop__BITNR 1
+#define R_DMA_CH3_CLR_INTR__clr_eop__WIDTH 1
+#define R_DMA_CH3_CLR_INTR__clr_eop__do 1
+#define R_DMA_CH3_CLR_INTR__clr_eop__dont 0
+#define R_DMA_CH3_CLR_INTR__clr_descr__BITNR 0
+#define R_DMA_CH3_CLR_INTR__clr_descr__WIDTH 1
+#define R_DMA_CH3_CLR_INTR__clr_descr__do 1
+#define R_DMA_CH3_CLR_INTR__clr_descr__dont 0
+
+#define R_DMA_CH3_STATUS (IO_TYPECAST_RO_BYTE 0xb00001de)
+#define R_DMA_CH3_STATUS__avail__BITNR 0
+#define R_DMA_CH3_STATUS__avail__WIDTH 7
+
+#define R_DMA_CH4_HWSW (IO_TYPECAST_UDWORD 0xb0000140)
+#define R_DMA_CH4_HWSW__hw__BITNR 16
+#define R_DMA_CH4_HWSW__hw__WIDTH 16
+#define R_DMA_CH4_HWSW__sw__BITNR 0
+#define R_DMA_CH4_HWSW__sw__WIDTH 16
+
+#define R_DMA_CH4_DESCR (IO_TYPECAST_UDWORD 0xb000014c)
+#define R_DMA_CH4_DESCR__descr__BITNR 0
+#define R_DMA_CH4_DESCR__descr__WIDTH 32
+
+#define R_DMA_CH4_NEXT (IO_TYPECAST_UDWORD 0xb0000144)
+#define R_DMA_CH4_NEXT__next__BITNR 0
+#define R_DMA_CH4_NEXT__next__WIDTH 32
+
+#define R_DMA_CH4_BUF (IO_TYPECAST_UDWORD 0xb0000148)
+#define R_DMA_CH4_BUF__buf__BITNR 0
+#define R_DMA_CH4_BUF__buf__WIDTH 32
+
+#define R_DMA_CH4_FIRST (IO_TYPECAST_UDWORD 0xb00001b0)
+#define R_DMA_CH4_FIRST__first__BITNR 0
+#define R_DMA_CH4_FIRST__first__WIDTH 32
+
+#define R_DMA_CH4_CMD (IO_TYPECAST_BYTE 0xb00001e0)
+#define R_DMA_CH4_CMD__cmd__BITNR 0
+#define R_DMA_CH4_CMD__cmd__WIDTH 3
+#define R_DMA_CH4_CMD__cmd__hold 0
+#define R_DMA_CH4_CMD__cmd__start 1
+#define R_DMA_CH4_CMD__cmd__restart 3
+#define R_DMA_CH4_CMD__cmd__continue 3
+#define R_DMA_CH4_CMD__cmd__reset 4
+
+#define R_DMA_CH4_CLR_INTR (IO_TYPECAST_BYTE 0xb00001e1)
+#define R_DMA_CH4_CLR_INTR__clr_eop__BITNR 1
+#define R_DMA_CH4_CLR_INTR__clr_eop__WIDTH 1
+#define R_DMA_CH4_CLR_INTR__clr_eop__do 1
+#define R_DMA_CH4_CLR_INTR__clr_eop__dont 0
+#define R_DMA_CH4_CLR_INTR__clr_descr__BITNR 0
+#define R_DMA_CH4_CLR_INTR__clr_descr__WIDTH 1
+#define R_DMA_CH4_CLR_INTR__clr_descr__do 1
+#define R_DMA_CH4_CLR_INTR__clr_descr__dont 0
+
+#define R_DMA_CH4_STATUS (IO_TYPECAST_RO_BYTE 0xb00001e2)
+#define R_DMA_CH4_STATUS__avail__BITNR 0
+#define R_DMA_CH4_STATUS__avail__WIDTH 7
+
+#define R_DMA_CH5_HWSW (IO_TYPECAST_UDWORD 0xb0000150)
+#define R_DMA_CH5_HWSW__hw__BITNR 16
+#define R_DMA_CH5_HWSW__hw__WIDTH 16
+#define R_DMA_CH5_HWSW__sw__BITNR 0
+#define R_DMA_CH5_HWSW__sw__WIDTH 16
+
+#define R_DMA_CH5_DESCR (IO_TYPECAST_UDWORD 0xb000015c)
+#define R_DMA_CH5_DESCR__descr__BITNR 0
+#define R_DMA_CH5_DESCR__descr__WIDTH 32
+
+#define R_DMA_CH5_NEXT (IO_TYPECAST_UDWORD 0xb0000154)
+#define R_DMA_CH5_NEXT__next__BITNR 0
+#define R_DMA_CH5_NEXT__next__WIDTH 32
+
+#define R_DMA_CH5_BUF (IO_TYPECAST_UDWORD 0xb0000158)
+#define R_DMA_CH5_BUF__buf__BITNR 0
+#define R_DMA_CH5_BUF__buf__WIDTH 32
+
+#define R_DMA_CH5_FIRST (IO_TYPECAST_UDWORD 0xb00001b4)
+#define R_DMA_CH5_FIRST__first__BITNR 0
+#define R_DMA_CH5_FIRST__first__WIDTH 32
+
+#define R_DMA_CH5_CMD (IO_TYPECAST_BYTE 0xb00001e4)
+#define R_DMA_CH5_CMD__cmd__BITNR 0
+#define R_DMA_CH5_CMD__cmd__WIDTH 3
+#define R_DMA_CH5_CMD__cmd__hold 0
+#define R_DMA_CH5_CMD__cmd__start 1
+#define R_DMA_CH5_CMD__cmd__restart 3
+#define R_DMA_CH5_CMD__cmd__continue 3
+#define R_DMA_CH5_CMD__cmd__reset 4
+
+#define R_DMA_CH5_CLR_INTR (IO_TYPECAST_BYTE 0xb00001e5)
+#define R_DMA_CH5_CLR_INTR__clr_eop__BITNR 1
+#define R_DMA_CH5_CLR_INTR__clr_eop__WIDTH 1
+#define R_DMA_CH5_CLR_INTR__clr_eop__do 1
+#define R_DMA_CH5_CLR_INTR__clr_eop__dont 0
+#define R_DMA_CH5_CLR_INTR__clr_descr__BITNR 0
+#define R_DMA_CH5_CLR_INTR__clr_descr__WIDTH 1
+#define R_DMA_CH5_CLR_INTR__clr_descr__do 1
+#define R_DMA_CH5_CLR_INTR__clr_descr__dont 0
+
+#define R_DMA_CH5_STATUS (IO_TYPECAST_RO_BYTE 0xb00001e6)
+#define R_DMA_CH5_STATUS__avail__BITNR 0
+#define R_DMA_CH5_STATUS__avail__WIDTH 7
+
+#define R_DMA_CH6_HWSW (IO_TYPECAST_UDWORD 0xb0000160)
+#define R_DMA_CH6_HWSW__hw__BITNR 16
+#define R_DMA_CH6_HWSW__hw__WIDTH 16
+#define R_DMA_CH6_HWSW__sw__BITNR 0
+#define R_DMA_CH6_HWSW__sw__WIDTH 16
+
+#define R_DMA_CH6_DESCR (IO_TYPECAST_UDWORD 0xb000016c)
+#define R_DMA_CH6_DESCR__descr__BITNR 0
+#define R_DMA_CH6_DESCR__descr__WIDTH 32
+
+#define R_DMA_CH6_NEXT (IO_TYPECAST_UDWORD 0xb0000164)
+#define R_DMA_CH6_NEXT__next__BITNR 0
+#define R_DMA_CH6_NEXT__next__WIDTH 32
+
+#define R_DMA_CH6_BUF (IO_TYPECAST_UDWORD 0xb0000168)
+#define R_DMA_CH6_BUF__buf__BITNR 0
+#define R_DMA_CH6_BUF__buf__WIDTH 32
+
+#define R_DMA_CH6_FIRST (IO_TYPECAST_UDWORD 0xb00001b8)
+#define R_DMA_CH6_FIRST__first__BITNR 0
+#define R_DMA_CH6_FIRST__first__WIDTH 32
+
+#define R_DMA_CH6_CMD (IO_TYPECAST_BYTE 0xb00001e8)
+#define R_DMA_CH6_CMD__cmd__BITNR 0
+#define R_DMA_CH6_CMD__cmd__WIDTH 3
+#define R_DMA_CH6_CMD__cmd__hold 0
+#define R_DMA_CH6_CMD__cmd__start 1
+#define R_DMA_CH6_CMD__cmd__restart 3
+#define R_DMA_CH6_CMD__cmd__continue 3
+#define R_DMA_CH6_CMD__cmd__reset 4
+
+#define R_DMA_CH6_CLR_INTR (IO_TYPECAST_BYTE 0xb00001e9)
+#define R_DMA_CH6_CLR_INTR__clr_eop__BITNR 1
+#define R_DMA_CH6_CLR_INTR__clr_eop__WIDTH 1
+#define R_DMA_CH6_CLR_INTR__clr_eop__do 1
+#define R_DMA_CH6_CLR_INTR__clr_eop__dont 0
+#define R_DMA_CH6_CLR_INTR__clr_descr__BITNR 0
+#define R_DMA_CH6_CLR_INTR__clr_descr__WIDTH 1
+#define R_DMA_CH6_CLR_INTR__clr_descr__do 1
+#define R_DMA_CH6_CLR_INTR__clr_descr__dont 0
+
+#define R_DMA_CH6_STATUS (IO_TYPECAST_RO_BYTE 0xb00001ea)
+#define R_DMA_CH6_STATUS__avail__BITNR 0
+#define R_DMA_CH6_STATUS__avail__WIDTH 7
+
+#define R_DMA_CH7_HWSW (IO_TYPECAST_UDWORD 0xb0000170)
+#define R_DMA_CH7_HWSW__hw__BITNR 16
+#define R_DMA_CH7_HWSW__hw__WIDTH 16
+#define R_DMA_CH7_HWSW__sw__BITNR 0
+#define R_DMA_CH7_HWSW__sw__WIDTH 16
+
+#define R_DMA_CH7_DESCR (IO_TYPECAST_UDWORD 0xb000017c)
+#define R_DMA_CH7_DESCR__descr__BITNR 0
+#define R_DMA_CH7_DESCR__descr__WIDTH 32
+
+#define R_DMA_CH7_NEXT (IO_TYPECAST_UDWORD 0xb0000174)
+#define R_DMA_CH7_NEXT__next__BITNR 0
+#define R_DMA_CH7_NEXT__next__WIDTH 32
+
+#define R_DMA_CH7_BUF (IO_TYPECAST_UDWORD 0xb0000178)
+#define R_DMA_CH7_BUF__buf__BITNR 0
+#define R_DMA_CH7_BUF__buf__WIDTH 32
+
+#define R_DMA_CH7_FIRST (IO_TYPECAST_UDWORD 0xb00001bc)
+#define R_DMA_CH7_FIRST__first__BITNR 0
+#define R_DMA_CH7_FIRST__first__WIDTH 32
+
+#define R_DMA_CH7_CMD (IO_TYPECAST_BYTE 0xb00001ec)
+#define R_DMA_CH7_CMD__cmd__BITNR 0
+#define R_DMA_CH7_CMD__cmd__WIDTH 3
+#define R_DMA_CH7_CMD__cmd__hold 0
+#define R_DMA_CH7_CMD__cmd__start 1
+#define R_DMA_CH7_CMD__cmd__restart 3
+#define R_DMA_CH7_CMD__cmd__continue 3
+#define R_DMA_CH7_CMD__cmd__reset 4
+
+#define R_DMA_CH7_CLR_INTR (IO_TYPECAST_BYTE 0xb00001ed)
+#define R_DMA_CH7_CLR_INTR__clr_eop__BITNR 1
+#define R_DMA_CH7_CLR_INTR__clr_eop__WIDTH 1
+#define R_DMA_CH7_CLR_INTR__clr_eop__do 1
+#define R_DMA_CH7_CLR_INTR__clr_eop__dont 0
+#define R_DMA_CH7_CLR_INTR__clr_descr__BITNR 0
+#define R_DMA_CH7_CLR_INTR__clr_descr__WIDTH 1
+#define R_DMA_CH7_CLR_INTR__clr_descr__do 1
+#define R_DMA_CH7_CLR_INTR__clr_descr__dont 0
+
+#define R_DMA_CH7_STATUS (IO_TYPECAST_RO_BYTE 0xb00001ee)
+#define R_DMA_CH7_STATUS__avail__BITNR 0
+#define R_DMA_CH7_STATUS__avail__WIDTH 7
+
+#define R_DMA_CH8_HWSW (IO_TYPECAST_UDWORD 0xb0000180)
+#define R_DMA_CH8_HWSW__hw__BITNR 16
+#define R_DMA_CH8_HWSW__hw__WIDTH 16
+#define R_DMA_CH8_HWSW__sw__BITNR 0
+#define R_DMA_CH8_HWSW__sw__WIDTH 16
+
+#define R_DMA_CH8_DESCR (IO_TYPECAST_UDWORD 0xb000018c)
+#define R_DMA_CH8_DESCR__descr__BITNR 0
+#define R_DMA_CH8_DESCR__descr__WIDTH 32
+
+#define R_DMA_CH8_NEXT (IO_TYPECAST_UDWORD 0xb0000184)
+#define R_DMA_CH8_NEXT__next__BITNR 0
+#define R_DMA_CH8_NEXT__next__WIDTH 32
+
+#define R_DMA_CH8_BUF (IO_TYPECAST_UDWORD 0xb0000188)
+#define R_DMA_CH8_BUF__buf__BITNR 0
+#define R_DMA_CH8_BUF__buf__WIDTH 32
+
+#define R_DMA_CH8_FIRST (IO_TYPECAST_UDWORD 0xb00001c0)
+#define R_DMA_CH8_FIRST__first__BITNR 0
+#define R_DMA_CH8_FIRST__first__WIDTH 32
+
+#define R_DMA_CH8_CMD (IO_TYPECAST_BYTE 0xb00001f0)
+#define R_DMA_CH8_CMD__cmd__BITNR 0
+#define R_DMA_CH8_CMD__cmd__WIDTH 3
+#define R_DMA_CH8_CMD__cmd__hold 0
+#define R_DMA_CH8_CMD__cmd__start 1
+#define R_DMA_CH8_CMD__cmd__restart 3
+#define R_DMA_CH8_CMD__cmd__continue 3
+#define R_DMA_CH8_CMD__cmd__reset 4
+
+#define R_DMA_CH8_CLR_INTR (IO_TYPECAST_BYTE 0xb00001f1)
+#define R_DMA_CH8_CLR_INTR__clr_eop__BITNR 1
+#define R_DMA_CH8_CLR_INTR__clr_eop__WIDTH 1
+#define R_DMA_CH8_CLR_INTR__clr_eop__do 1
+#define R_DMA_CH8_CLR_INTR__clr_eop__dont 0
+#define R_DMA_CH8_CLR_INTR__clr_descr__BITNR 0
+#define R_DMA_CH8_CLR_INTR__clr_descr__WIDTH 1
+#define R_DMA_CH8_CLR_INTR__clr_descr__do 1
+#define R_DMA_CH8_CLR_INTR__clr_descr__dont 0
+
+#define R_DMA_CH8_STATUS (IO_TYPECAST_RO_BYTE 0xb00001f2)
+#define R_DMA_CH8_STATUS__avail__BITNR 0
+#define R_DMA_CH8_STATUS__avail__WIDTH 7
+
+#define R_DMA_CH8_SUB (IO_TYPECAST_UDWORD 0xb000018c)
+#define R_DMA_CH8_SUB__sub__BITNR 0
+#define R_DMA_CH8_SUB__sub__WIDTH 32
+
+#define R_DMA_CH8_NEP (IO_TYPECAST_UDWORD 0xb00001c0)
+#define R_DMA_CH8_NEP__nep__BITNR 0
+#define R_DMA_CH8_NEP__nep__WIDTH 32
+
+#define R_DMA_CH8_SUB0_EP (IO_TYPECAST_UDWORD 0xb00001c8)
+#define R_DMA_CH8_SUB0_EP__ep__BITNR 0
+#define R_DMA_CH8_SUB0_EP__ep__WIDTH 32
+
+#define R_DMA_CH8_SUB0_CMD (IO_TYPECAST_BYTE 0xb00001d3)
+#define R_DMA_CH8_SUB0_CMD__cmd__BITNR 0
+#define R_DMA_CH8_SUB0_CMD__cmd__WIDTH 1
+#define R_DMA_CH8_SUB0_CMD__cmd__stop 0
+#define R_DMA_CH8_SUB0_CMD__cmd__start 1
+
+#define R_DMA_CH8_SUB0_CLR_INTR (IO_TYPECAST_BYTE 0xb00001e3)
+#define R_DMA_CH8_SUB0_CLR_INTR__clr_descr__BITNR 0
+#define R_DMA_CH8_SUB0_CLR_INTR__clr_descr__WIDTH 1
+#define R_DMA_CH8_SUB0_CLR_INTR__clr_descr__dont 0
+#define R_DMA_CH8_SUB0_CLR_INTR__clr_descr__do 1
+
+#define R_DMA_CH8_SUB1_EP (IO_TYPECAST_UDWORD 0xb00001cc)
+#define R_DMA_CH8_SUB1_EP__ep__BITNR 0
+#define R_DMA_CH8_SUB1_EP__ep__WIDTH 32
+
+#define R_DMA_CH8_SUB1_CMD (IO_TYPECAST_BYTE 0xb00001d7)
+#define R_DMA_CH8_SUB1_CMD__cmd__BITNR 0
+#define R_DMA_CH8_SUB1_CMD__cmd__WIDTH 1
+#define R_DMA_CH8_SUB1_CMD__cmd__stop 0
+#define R_DMA_CH8_SUB1_CMD__cmd__start 1
+
+#define R_DMA_CH8_SUB1_CLR_INTR (IO_TYPECAST_BYTE 0xb00001e7)
+#define R_DMA_CH8_SUB1_CLR_INTR__clr_descr__BITNR 0
+#define R_DMA_CH8_SUB1_CLR_INTR__clr_descr__WIDTH 1
+#define R_DMA_CH8_SUB1_CLR_INTR__clr_descr__dont 0
+#define R_DMA_CH8_SUB1_CLR_INTR__clr_descr__do 1
+
+#define R_DMA_CH8_SUB2_EP (IO_TYPECAST_UDWORD 0xb00001f8)
+#define R_DMA_CH8_SUB2_EP__ep__BITNR 0
+#define R_DMA_CH8_SUB2_EP__ep__WIDTH 32
+
+#define R_DMA_CH8_SUB2_CMD (IO_TYPECAST_BYTE 0xb00001db)
+#define R_DMA_CH8_SUB2_CMD__cmd__BITNR 0
+#define R_DMA_CH8_SUB2_CMD__cmd__WIDTH 1
+#define R_DMA_CH8_SUB2_CMD__cmd__stop 0
+#define R_DMA_CH8_SUB2_CMD__cmd__start 1
+
+#define R_DMA_CH8_SUB2_CLR_INTR (IO_TYPECAST_BYTE 0xb00001eb)
+#define R_DMA_CH8_SUB2_CLR_INTR__clr_descr__BITNR 0
+#define R_DMA_CH8_SUB2_CLR_INTR__clr_descr__WIDTH 1
+#define R_DMA_CH8_SUB2_CLR_INTR__clr_descr__dont 0
+#define R_DMA_CH8_SUB2_CLR_INTR__clr_descr__do 1
+
+#define R_DMA_CH8_SUB3_EP (IO_TYPECAST_UDWORD 0xb00001fc)
+#define R_DMA_CH8_SUB3_EP__ep__BITNR 0
+#define R_DMA_CH8_SUB3_EP__ep__WIDTH 32
+
+#define R_DMA_CH8_SUB3_CMD (IO_TYPECAST_BYTE 0xb00001df)
+#define R_DMA_CH8_SUB3_CMD__cmd__BITNR 0
+#define R_DMA_CH8_SUB3_CMD__cmd__WIDTH 1
+#define R_DMA_CH8_SUB3_CMD__cmd__stop 0
+#define R_DMA_CH8_SUB3_CMD__cmd__start 1
+
+#define R_DMA_CH8_SUB3_CLR_INTR (IO_TYPECAST_BYTE 0xb00001ef)
+#define R_DMA_CH8_SUB3_CLR_INTR__clr_descr__BITNR 0
+#define R_DMA_CH8_SUB3_CLR_INTR__clr_descr__WIDTH 1
+#define R_DMA_CH8_SUB3_CLR_INTR__clr_descr__dont 0
+#define R_DMA_CH8_SUB3_CLR_INTR__clr_descr__do 1
+
+#define R_DMA_CH9_HWSW (IO_TYPECAST_UDWORD 0xb0000190)
+#define R_DMA_CH9_HWSW__hw__BITNR 16
+#define R_DMA_CH9_HWSW__hw__WIDTH 16
+#define R_DMA_CH9_HWSW__sw__BITNR 0
+#define R_DMA_CH9_HWSW__sw__WIDTH 16
+
+#define R_DMA_CH9_DESCR (IO_TYPECAST_UDWORD 0xb000019c)
+#define R_DMA_CH9_DESCR__descr__BITNR 0
+#define R_DMA_CH9_DESCR__descr__WIDTH 32
+
+#define R_DMA_CH9_NEXT (IO_TYPECAST_UDWORD 0xb0000194)
+#define R_DMA_CH9_NEXT__next__BITNR 0
+#define R_DMA_CH9_NEXT__next__WIDTH 32
+
+#define R_DMA_CH9_BUF (IO_TYPECAST_UDWORD 0xb0000198)
+#define R_DMA_CH9_BUF__buf__BITNR 0
+#define R_DMA_CH9_BUF__buf__WIDTH 32
+
+#define R_DMA_CH9_FIRST (IO_TYPECAST_UDWORD 0xb00001c4)
+#define R_DMA_CH9_FIRST__first__BITNR 0
+#define R_DMA_CH9_FIRST__first__WIDTH 32
+
+#define R_DMA_CH9_CMD (IO_TYPECAST_BYTE 0xb00001f4)
+#define R_DMA_CH9_CMD__cmd__BITNR 0
+#define R_DMA_CH9_CMD__cmd__WIDTH 3
+#define R_DMA_CH9_CMD__cmd__hold 0
+#define R_DMA_CH9_CMD__cmd__start 1
+#define R_DMA_CH9_CMD__cmd__restart 3
+#define R_DMA_CH9_CMD__cmd__continue 3
+#define R_DMA_CH9_CMD__cmd__reset 4
+
+#define R_DMA_CH9_CLR_INTR (IO_TYPECAST_BYTE 0xb00001f5)
+#define R_DMA_CH9_CLR_INTR__clr_eop__BITNR 1
+#define R_DMA_CH9_CLR_INTR__clr_eop__WIDTH 1
+#define R_DMA_CH9_CLR_INTR__clr_eop__do 1
+#define R_DMA_CH9_CLR_INTR__clr_eop__dont 0
+#define R_DMA_CH9_CLR_INTR__clr_descr__BITNR 0
+#define R_DMA_CH9_CLR_INTR__clr_descr__WIDTH 1
+#define R_DMA_CH9_CLR_INTR__clr_descr__do 1
+#define R_DMA_CH9_CLR_INTR__clr_descr__dont 0
+
+#define R_DMA_CH9_STATUS (IO_TYPECAST_RO_BYTE 0xb00001f6)
+#define R_DMA_CH9_STATUS__avail__BITNR 0
+#define R_DMA_CH9_STATUS__avail__WIDTH 7
+
+/*
+!* Test mode registers
+!*/
+
+#define R_TEST_MODE (IO_TYPECAST_UDWORD 0xb00000fc)
+#define R_TEST_MODE__single_step__BITNR 19
+#define R_TEST_MODE__single_step__WIDTH 1
+#define R_TEST_MODE__single_step__on 1
+#define R_TEST_MODE__single_step__off 0
+#define R_TEST_MODE__step_wr__BITNR 18
+#define R_TEST_MODE__step_wr__WIDTH 1
+#define R_TEST_MODE__step_wr__on 1
+#define R_TEST_MODE__step_wr__off 0
+#define R_TEST_MODE__step_rd__BITNR 17
+#define R_TEST_MODE__step_rd__WIDTH 1
+#define R_TEST_MODE__step_rd__on 1
+#define R_TEST_MODE__step_rd__off 0
+#define R_TEST_MODE__step_fetch__BITNR 16
+#define R_TEST_MODE__step_fetch__WIDTH 1
+#define R_TEST_MODE__step_fetch__on 1
+#define R_TEST_MODE__step_fetch__off 0
+#define R_TEST_MODE__mmu_test__BITNR 12
+#define R_TEST_MODE__mmu_test__WIDTH 1
+#define R_TEST_MODE__mmu_test__on 1
+#define R_TEST_MODE__mmu_test__off 0
+#define R_TEST_MODE__usb_test__BITNR 11
+#define R_TEST_MODE__usb_test__WIDTH 1
+#define R_TEST_MODE__usb_test__on 1
+#define R_TEST_MODE__usb_test__off 0
+#define R_TEST_MODE__scsi_timer_test__BITNR 10
+#define R_TEST_MODE__scsi_timer_test__WIDTH 1
+#define R_TEST_MODE__scsi_timer_test__on 1
+#define R_TEST_MODE__scsi_timer_test__off 0
+#define R_TEST_MODE__backoff__BITNR 9
+#define R_TEST_MODE__backoff__WIDTH 1
+#define R_TEST_MODE__backoff__on 1
+#define R_TEST_MODE__backoff__off 0
+#define R_TEST_MODE__snmp_test__BITNR 8
+#define R_TEST_MODE__snmp_test__WIDTH 1
+#define R_TEST_MODE__snmp_test__on 1
+#define R_TEST_MODE__snmp_test__off 0
+#define R_TEST_MODE__snmp_inc__BITNR 7
+#define R_TEST_MODE__snmp_inc__WIDTH 1
+#define R_TEST_MODE__snmp_inc__do 1
+#define R_TEST_MODE__snmp_inc__dont 0
+#define R_TEST_MODE__ser_loop__BITNR 6
+#define R_TEST_MODE__ser_loop__WIDTH 1
+#define R_TEST_MODE__ser_loop__on 1
+#define R_TEST_MODE__ser_loop__off 0
+#define R_TEST_MODE__baudrate__BITNR 5
+#define R_TEST_MODE__baudrate__WIDTH 1
+#define R_TEST_MODE__baudrate__on 1
+#define R_TEST_MODE__baudrate__off 0
+#define R_TEST_MODE__timer__BITNR 3
+#define R_TEST_MODE__timer__WIDTH 2
+#define R_TEST_MODE__timer__off 0
+#define R_TEST_MODE__timer__even 1
+#define R_TEST_MODE__timer__odd 2
+#define R_TEST_MODE__timer__all 3
+#define R_TEST_MODE__cache_test__BITNR 2
+#define R_TEST_MODE__cache_test__WIDTH 1
+#define R_TEST_MODE__cache_test__normal 0
+#define R_TEST_MODE__cache_test__test 1
+#define R_TEST_MODE__tag_test__BITNR 1
+#define R_TEST_MODE__tag_test__WIDTH 1
+#define R_TEST_MODE__tag_test__normal 0
+#define R_TEST_MODE__tag_test__test 1
+#define R_TEST_MODE__cache_enable__BITNR 0
+#define R_TEST_MODE__cache_enable__WIDTH 1
+#define R_TEST_MODE__cache_enable__enable 1
+#define R_TEST_MODE__cache_enable__disable 0
+
+#define R_SINGLE_STEP (IO_TYPECAST_BYTE 0xb00000fe)
+#define R_SINGLE_STEP__single_step__BITNR 3
+#define R_SINGLE_STEP__single_step__WIDTH 1
+#define R_SINGLE_STEP__single_step__on 1
+#define R_SINGLE_STEP__single_step__off 0
+#define R_SINGLE_STEP__step_wr__BITNR 2
+#define R_SINGLE_STEP__step_wr__WIDTH 1
+#define R_SINGLE_STEP__step_wr__on 1
+#define R_SINGLE_STEP__step_wr__off 0
+#define R_SINGLE_STEP__step_rd__BITNR 1
+#define R_SINGLE_STEP__step_rd__WIDTH 1
+#define R_SINGLE_STEP__step_rd__on 1
+#define R_SINGLE_STEP__step_rd__off 0
+#define R_SINGLE_STEP__step_fetch__BITNR 0
+#define R_SINGLE_STEP__step_fetch__WIDTH 1
+#define R_SINGLE_STEP__step_fetch__on 1
+#define R_SINGLE_STEP__step_fetch__off 0
+
+/*
+!* USB interface control registers
+!*/
+
+#define R_USB_REVISION (IO_TYPECAST_RO_BYTE 0xb0000200)
+#define R_USB_REVISION__major__BITNR 4
+#define R_USB_REVISION__major__WIDTH 4
+#define R_USB_REVISION__minor__BITNR 0
+#define R_USB_REVISION__minor__WIDTH 4
+
+#define R_USB_COMMAND (IO_TYPECAST_BYTE 0xb0000201)
+#define R_USB_COMMAND__port_sel__BITNR 6
+#define R_USB_COMMAND__port_sel__WIDTH 2
+#define R_USB_COMMAND__port_sel__nop 0
+#define R_USB_COMMAND__port_sel__port1 1
+#define R_USB_COMMAND__port_sel__port2 2
+#define R_USB_COMMAND__port_sel__both 3
+#define R_USB_COMMAND__port_cmd__BITNR 4
+#define R_USB_COMMAND__port_cmd__WIDTH 2
+#define R_USB_COMMAND__port_cmd__reset 0
+#define R_USB_COMMAND__port_cmd__disable 1
+#define R_USB_COMMAND__port_cmd__suspend 2
+#define R_USB_COMMAND__port_cmd__resume 3
+#define R_USB_COMMAND__ctrl_cmd__BITNR 0
+#define R_USB_COMMAND__ctrl_cmd__WIDTH 3
+#define R_USB_COMMAND__ctrl_cmd__nop 0
+#define R_USB_COMMAND__ctrl_cmd__reset 1
+#define R_USB_COMMAND__ctrl_cmd__deconfig 2
+#define R_USB_COMMAND__ctrl_cmd__host_config 3
+#define R_USB_COMMAND__ctrl_cmd__dev_config 4
+#define R_USB_COMMAND__ctrl_cmd__host_reset 5
+#define R_USB_COMMAND__ctrl_cmd__host_run 6
+#define R_USB_COMMAND__ctrl_cmd__host_stop 7
+
+#define R_USB_STATUS (IO_TYPECAST_RO_BYTE 0xb0000202)
+#define R_USB_STATUS__busy__BITNR 7
+#define R_USB_STATUS__busy__WIDTH 1
+#define R_USB_STATUS__busy__no 0
+#define R_USB_STATUS__busy__yes 1
+#define R_USB_STATUS__device_mode__BITNR 3
+#define R_USB_STATUS__device_mode__WIDTH 1
+#define R_USB_STATUS__device_mode__no 0
+#define R_USB_STATUS__device_mode__yes 1
+#define R_USB_STATUS__host_mode__BITNR 2
+#define R_USB_STATUS__host_mode__WIDTH 1
+#define R_USB_STATUS__host_mode__no 0
+#define R_USB_STATUS__host_mode__yes 1
+#define R_USB_STATUS__started__BITNR 1
+#define R_USB_STATUS__started__WIDTH 1
+#define R_USB_STATUS__started__no 0
+#define R_USB_STATUS__started__yes 1
+#define R_USB_STATUS__running__BITNR 0
+#define R_USB_STATUS__running__WIDTH 1
+#define R_USB_STATUS__running__no 0
+#define R_USB_STATUS__running__yes 1
+
+#define R_USB_IRQ_MASK_SET (IO_TYPECAST_UWORD 0xb0000204)
+#define R_USB_IRQ_MASK_SET__intr_eof__BITNR 13
+#define R_USB_IRQ_MASK_SET__intr_eof__WIDTH 1
+#define R_USB_IRQ_MASK_SET__intr_eof__nop 0
+#define R_USB_IRQ_MASK_SET__intr_eof__set 1
+#define R_USB_IRQ_MASK_SET__iso_eof__BITNR 12
+#define R_USB_IRQ_MASK_SET__iso_eof__WIDTH 1
+#define R_USB_IRQ_MASK_SET__iso_eof__nop 0
+#define R_USB_IRQ_MASK_SET__iso_eof__set 1
+#define R_USB_IRQ_MASK_SET__bulk_eot__BITNR 11
+#define R_USB_IRQ_MASK_SET__bulk_eot__WIDTH 1
+#define R_USB_IRQ_MASK_SET__bulk_eot__nop 0
+#define R_USB_IRQ_MASK_SET__bulk_eot__set 1
+#define R_USB_IRQ_MASK_SET__ctl_eot__BITNR 10
+#define R_USB_IRQ_MASK_SET__ctl_eot__WIDTH 1
+#define R_USB_IRQ_MASK_SET__ctl_eot__nop 0
+#define R_USB_IRQ_MASK_SET__ctl_eot__set 1
+#define R_USB_IRQ_MASK_SET__intr_eot__BITNR 9
+#define R_USB_IRQ_MASK_SET__intr_eot__WIDTH 1
+#define R_USB_IRQ_MASK_SET__intr_eot__nop 0
+#define R_USB_IRQ_MASK_SET__intr_eot__set 1
+#define R_USB_IRQ_MASK_SET__iso_eot__BITNR 8
+#define R_USB_IRQ_MASK_SET__iso_eot__WIDTH 1
+#define R_USB_IRQ_MASK_SET__iso_eot__nop 0
+#define R_USB_IRQ_MASK_SET__iso_eot__set 1
+#define R_USB_IRQ_MASK_SET__sof__BITNR 2
+#define R_USB_IRQ_MASK_SET__sof__WIDTH 1
+#define R_USB_IRQ_MASK_SET__sof__nop 0
+#define R_USB_IRQ_MASK_SET__sof__set 1
+#define R_USB_IRQ_MASK_SET__port_status__BITNR 1
+#define R_USB_IRQ_MASK_SET__port_status__WIDTH 1
+#define R_USB_IRQ_MASK_SET__port_status__nop 0
+#define R_USB_IRQ_MASK_SET__port_status__set 1
+#define R_USB_IRQ_MASK_SET__ctl_status__BITNR 0
+#define R_USB_IRQ_MASK_SET__ctl_status__WIDTH 1
+#define R_USB_IRQ_MASK_SET__ctl_status__nop 0
+#define R_USB_IRQ_MASK_SET__ctl_status__set 1
+
+#define R_USB_IRQ_MASK_READ (IO_TYPECAST_RO_UWORD 0xb0000204)
+#define R_USB_IRQ_MASK_READ__intr_eof__BITNR 13
+#define R_USB_IRQ_MASK_READ__intr_eof__WIDTH 1
+#define R_USB_IRQ_MASK_READ__intr_eof__no_pend 0
+#define R_USB_IRQ_MASK_READ__intr_eof__pend 1
+#define R_USB_IRQ_MASK_READ__iso_eof__BITNR 12
+#define R_USB_IRQ_MASK_READ__iso_eof__WIDTH 1
+#define R_USB_IRQ_MASK_READ__iso_eof__no_pend 0
+#define R_USB_IRQ_MASK_READ__iso_eof__pend 1
+#define R_USB_IRQ_MASK_READ__bulk_eot__BITNR 11
+#define R_USB_IRQ_MASK_READ__bulk_eot__WIDTH 1
+#define R_USB_IRQ_MASK_READ__bulk_eot__no_pend 0
+#define R_USB_IRQ_MASK_READ__bulk_eot__pend 1
+#define R_USB_IRQ_MASK_READ__ctl_eot__BITNR 10
+#define R_USB_IRQ_MASK_READ__ctl_eot__WIDTH 1
+#define R_USB_IRQ_MASK_READ__ctl_eot__no_pend 0
+#define R_USB_IRQ_MASK_READ__ctl_eot__pend 1
+#define R_USB_IRQ_MASK_READ__intr_eot__BITNR 9
+#define R_USB_IRQ_MASK_READ__intr_eot__WIDTH 1
+#define R_USB_IRQ_MASK_READ__intr_eot__no_pend 0
+#define R_USB_IRQ_MASK_READ__intr_eot__pend 1
+#define R_USB_IRQ_MASK_READ__iso_eot__BITNR 8
+#define R_USB_IRQ_MASK_READ__iso_eot__WIDTH 1
+#define R_USB_IRQ_MASK_READ__iso_eot__no_pend 0
+#define R_USB_IRQ_MASK_READ__iso_eot__pend 1
+#define R_USB_IRQ_MASK_READ__sof__BITNR 2
+#define R_USB_IRQ_MASK_READ__sof__WIDTH 1
+#define R_USB_IRQ_MASK_READ__sof__no_pend 0
+#define R_USB_IRQ_MASK_READ__sof__pend 1
+#define R_USB_IRQ_MASK_READ__port_status__BITNR 1
+#define R_USB_IRQ_MASK_READ__port_status__WIDTH 1
+#define R_USB_IRQ_MASK_READ__port_status__no_pend 0
+#define R_USB_IRQ_MASK_READ__port_status__pend 1
+#define R_USB_IRQ_MASK_READ__ctl_status__BITNR 0
+#define R_USB_IRQ_MASK_READ__ctl_status__WIDTH 1
+#define R_USB_IRQ_MASK_READ__ctl_status__no_pend 0
+#define R_USB_IRQ_MASK_READ__ctl_status__pend 1
+
+#define R_USB_IRQ_MASK_CLR (IO_TYPECAST_UWORD 0xb0000206)
+#define R_USB_IRQ_MASK_CLR__intr_eof__BITNR 13
+#define R_USB_IRQ_MASK_CLR__intr_eof__WIDTH 1
+#define R_USB_IRQ_MASK_CLR__intr_eof__nop 0
+#define R_USB_IRQ_MASK_CLR__intr_eof__clr 1
+#define R_USB_IRQ_MASK_CLR__iso_eof__BITNR 12
+#define R_USB_IRQ_MASK_CLR__iso_eof__WIDTH 1
+#define R_USB_IRQ_MASK_CLR__iso_eof__nop 0
+#define R_USB_IRQ_MASK_CLR__iso_eof__clr 1
+#define R_USB_IRQ_MASK_CLR__bulk_eot__BITNR 11
+#define R_USB_IRQ_MASK_CLR__bulk_eot__WIDTH 1
+#define R_USB_IRQ_MASK_CLR__bulk_eot__nop 0
+#define R_USB_IRQ_MASK_CLR__bulk_eot__clr 1
+#define R_USB_IRQ_MASK_CLR__ctl_eot__BITNR 10
+#define R_USB_IRQ_MASK_CLR__ctl_eot__WIDTH 1
+#define R_USB_IRQ_MASK_CLR__ctl_eot__nop 0
+#define R_USB_IRQ_MASK_CLR__ctl_eot__clr 1
+#define R_USB_IRQ_MASK_CLR__intr_eot__BITNR 9
+#define R_USB_IRQ_MASK_CLR__intr_eot__WIDTH 1
+#define R_USB_IRQ_MASK_CLR__intr_eot__nop 0
+#define R_USB_IRQ_MASK_CLR__intr_eot__clr 1
+#define R_USB_IRQ_MASK_CLR__iso_eot__BITNR 8
+#define R_USB_IRQ_MASK_CLR__iso_eot__WIDTH 1
+#define R_USB_IRQ_MASK_CLR__iso_eot__nop 0
+#define R_USB_IRQ_MASK_CLR__iso_eot__clr 1
+#define R_USB_IRQ_MASK_CLR__sof__BITNR 2
+#define R_USB_IRQ_MASK_CLR__sof__WIDTH 1
+#define R_USB_IRQ_MASK_CLR__sof__nop 0
+#define R_USB_IRQ_MASK_CLR__sof__clr 1
+#define R_USB_IRQ_MASK_CLR__port_status__BITNR 1
+#define R_USB_IRQ_MASK_CLR__port_status__WIDTH 1
+#define R_USB_IRQ_MASK_CLR__port_status__nop 0
+#define R_USB_IRQ_MASK_CLR__port_status__clr 1
+#define R_USB_IRQ_MASK_CLR__ctl_status__BITNR 0
+#define R_USB_IRQ_MASK_CLR__ctl_status__WIDTH 1
+#define R_USB_IRQ_MASK_CLR__ctl_status__nop 0
+#define R_USB_IRQ_MASK_CLR__ctl_status__clr 1
+
+#define R_USB_IRQ_READ (IO_TYPECAST_RO_UWORD 0xb0000206)
+#define R_USB_IRQ_READ__intr_eof__BITNR 13
+#define R_USB_IRQ_READ__intr_eof__WIDTH 1
+#define R_USB_IRQ_READ__intr_eof__no_pend 0
+#define R_USB_IRQ_READ__intr_eof__pend 1
+#define R_USB_IRQ_READ__iso_eof__BITNR 12
+#define R_USB_IRQ_READ__iso_eof__WIDTH 1
+#define R_USB_IRQ_READ__iso_eof__no_pend 0
+#define R_USB_IRQ_READ__iso_eof__pend 1
+#define R_USB_IRQ_READ__bulk_eot__BITNR 11
+#define R_USB_IRQ_READ__bulk_eot__WIDTH 1
+#define R_USB_IRQ_READ__bulk_eot__no_pend 0
+#define R_USB_IRQ_READ__bulk_eot__pend 1
+#define R_USB_IRQ_READ__ctl_eot__BITNR 10
+#define R_USB_IRQ_READ__ctl_eot__WIDTH 1
+#define R_USB_IRQ_READ__ctl_eot__no_pend 0
+#define R_USB_IRQ_READ__ctl_eot__pend 1
+#define R_USB_IRQ_READ__intr_eot__BITNR 9
+#define R_USB_IRQ_READ__intr_eot__WIDTH 1
+#define R_USB_IRQ_READ__intr_eot__no_pend 0
+#define R_USB_IRQ_READ__intr_eot__pend 1
+#define R_USB_IRQ_READ__iso_eot__BITNR 8
+#define R_USB_IRQ_READ__iso_eot__WIDTH 1
+#define R_USB_IRQ_READ__iso_eot__no_pend 0
+#define R_USB_IRQ_READ__iso_eot__pend 1
+#define R_USB_IRQ_READ__sof__BITNR 2
+#define R_USB_IRQ_READ__sof__WIDTH 1
+#define R_USB_IRQ_READ__sof__no_pend 0
+#define R_USB_IRQ_READ__sof__pend 1
+#define R_USB_IRQ_READ__port_status__BITNR 1
+#define R_USB_IRQ_READ__port_status__WIDTH 1
+#define R_USB_IRQ_READ__port_status__no_pend 0
+#define R_USB_IRQ_READ__port_status__pend 1
+#define R_USB_IRQ_READ__ctl_status__BITNR 0
+#define R_USB_IRQ_READ__ctl_status__WIDTH 1
+#define R_USB_IRQ_READ__ctl_status__no_pend 0
+#define R_USB_IRQ_READ__ctl_status__pend 1
+
+#define R_USB_FM_NUMBER (IO_TYPECAST_RO_UDWORD 0xb000020c)
+#define R_USB_FM_NUMBER__value__BITNR 0
+#define R_USB_FM_NUMBER__value__WIDTH 32
+
+#define R_USB_FM_INTERVAL (IO_TYPECAST_UWORD 0xb0000210)
+#define R_USB_FM_INTERVAL__fixed__BITNR 6
+#define R_USB_FM_INTERVAL__fixed__WIDTH 8
+#define R_USB_FM_INTERVAL__adj__BITNR 0
+#define R_USB_FM_INTERVAL__adj__WIDTH 6
+
+#define R_USB_FM_REMAINING (IO_TYPECAST_RO_UWORD 0xb0000212)
+#define R_USB_FM_REMAINING__value__BITNR 0
+#define R_USB_FM_REMAINING__value__WIDTH 14
+
+#define R_USB_FM_PSTART (IO_TYPECAST_UWORD 0xb0000214)
+#define R_USB_FM_PSTART__value__BITNR 0
+#define R_USB_FM_PSTART__value__WIDTH 14
+
+#define R_USB_LS_THRESHOLD (IO_TYPECAST_UWORD 0xb0000216)
+#define R_USB_LS_THRESHOLD__value__BITNR 0
+#define R_USB_LS_THRESHOLD__value__WIDTH 14
+
+#define R_USB_RH_STATUS (IO_TYPECAST_RO_BYTE 0xb0000203)
+#define R_USB_RH_STATUS__bus1__BITNR 4
+#define R_USB_RH_STATUS__bus1__WIDTH 2
+#define R_USB_RH_STATUS__bus1__SE0 0
+#define R_USB_RH_STATUS__bus1__Diff0 1
+#define R_USB_RH_STATUS__bus1__Diff1 1
+#define R_USB_RH_STATUS__bus1__SE1 3
+#define R_USB_RH_STATUS__bus2__BITNR 2
+#define R_USB_RH_STATUS__bus2__WIDTH 2
+#define R_USB_RH_STATUS__bus2__SE0 0
+#define R_USB_RH_STATUS__bus2__Diff0 1
+#define R_USB_RH_STATUS__bus2__Diff1 1
+#define R_USB_RH_STATUS__bus2__SE1 3
+#define R_USB_RH_STATUS__nports__BITNR 0
+#define R_USB_RH_STATUS__nports__WIDTH 2
+
+#define R_USB_RH_PORT_STATUS_1 (IO_TYPECAST_RO_UWORD 0xb0000218)
+#define R_USB_RH_PORT_STATUS_1__speed__BITNR 9
+#define R_USB_RH_PORT_STATUS_1__speed__WIDTH 1
+#define R_USB_RH_PORT_STATUS_1__speed__full 0
+#define R_USB_RH_PORT_STATUS_1__speed__low 1
+#define R_USB_RH_PORT_STATUS_1__power__BITNR 8
+#define R_USB_RH_PORT_STATUS_1__power__WIDTH 1
+#define R_USB_RH_PORT_STATUS_1__reset__BITNR 4
+#define R_USB_RH_PORT_STATUS_1__reset__WIDTH 1
+#define R_USB_RH_PORT_STATUS_1__reset__no 0
+#define R_USB_RH_PORT_STATUS_1__reset__yes 1
+#define R_USB_RH_PORT_STATUS_1__overcurent__BITNR 3
+#define R_USB_RH_PORT_STATUS_1__overcurent__WIDTH 1
+#define R_USB_RH_PORT_STATUS_1__overcurent__no 0
+#define R_USB_RH_PORT_STATUS_1__overcurent__yes 1
+#define R_USB_RH_PORT_STATUS_1__suspended__BITNR 2
+#define R_USB_RH_PORT_STATUS_1__suspended__WIDTH 1
+#define R_USB_RH_PORT_STATUS_1__suspended__no 0
+#define R_USB_RH_PORT_STATUS_1__suspended__yes 1
+#define R_USB_RH_PORT_STATUS_1__enabled__BITNR 1
+#define R_USB_RH_PORT_STATUS_1__enabled__WIDTH 1
+#define R_USB_RH_PORT_STATUS_1__enabled__no 0
+#define R_USB_RH_PORT_STATUS_1__enabled__yes 1
+#define R_USB_RH_PORT_STATUS_1__connected__BITNR 0
+#define R_USB_RH_PORT_STATUS_1__connected__WIDTH 1
+#define R_USB_RH_PORT_STATUS_1__connected__no 0
+#define R_USB_RH_PORT_STATUS_1__connected__yes 1
+
+#define R_USB_RH_PORT_STATUS_2 (IO_TYPECAST_RO_UWORD 0xb000021a)
+#define R_USB_RH_PORT_STATUS_2__speed__BITNR 9
+#define R_USB_RH_PORT_STATUS_2__speed__WIDTH 1
+#define R_USB_RH_PORT_STATUS_2__speed__full 0
+#define R_USB_RH_PORT_STATUS_2__speed__low 1
+#define R_USB_RH_PORT_STATUS_2__power__BITNR 8
+#define R_USB_RH_PORT_STATUS_2__power__WIDTH 1
+#define R_USB_RH_PORT_STATUS_2__reset__BITNR 4
+#define R_USB_RH_PORT_STATUS_2__reset__WIDTH 1
+#define R_USB_RH_PORT_STATUS_2__reset__no 0
+#define R_USB_RH_PORT_STATUS_2__reset__yes 1
+#define R_USB_RH_PORT_STATUS_2__overcurent__BITNR 3
+#define R_USB_RH_PORT_STATUS_2__overcurent__WIDTH 1
+#define R_USB_RH_PORT_STATUS_2__overcurent__no 0
+#define R_USB_RH_PORT_STATUS_2__overcurent__yes 1
+#define R_USB_RH_PORT_STATUS_2__suspended__BITNR 2
+#define R_USB_RH_PORT_STATUS_2__suspended__WIDTH 1
+#define R_USB_RH_PORT_STATUS_2__suspended__no 0
+#define R_USB_RH_PORT_STATUS_2__suspended__yes 1
+#define R_USB_RH_PORT_STATUS_2__enabled__BITNR 1
+#define R_USB_RH_PORT_STATUS_2__enabled__WIDTH 1
+#define R_USB_RH_PORT_STATUS_2__enabled__no 0
+#define R_USB_RH_PORT_STATUS_2__enabled__yes 1
+#define R_USB_RH_PORT_STATUS_2__connected__BITNR 0
+#define R_USB_RH_PORT_STATUS_2__connected__WIDTH 1
+#define R_USB_RH_PORT_STATUS_2__connected__no 0
+#define R_USB_RH_PORT_STATUS_2__connected__yes 1
+
+#define R_USB_EPT_INDEX (IO_TYPECAST_BYTE 0xb0000208)
+#define R_USB_EPT_INDEX__value__BITNR 0
+#define R_USB_EPT_INDEX__value__WIDTH 5
+
+#define R_USB_EPT_DATA (IO_TYPECAST_UDWORD 0xb000021c)
+#define R_USB_EPT_DATA__valid__BITNR 31
+#define R_USB_EPT_DATA__valid__WIDTH 1
+#define R_USB_EPT_DATA__valid__no 0
+#define R_USB_EPT_DATA__valid__yes 1
+#define R_USB_EPT_DATA__hold__BITNR 30
+#define R_USB_EPT_DATA__hold__WIDTH 1
+#define R_USB_EPT_DATA__hold__no 0
+#define R_USB_EPT_DATA__hold__yes 1
+#define R_USB_EPT_DATA__error_count_in__BITNR 28
+#define R_USB_EPT_DATA__error_count_in__WIDTH 2
+#define R_USB_EPT_DATA__t_in__BITNR 27
+#define R_USB_EPT_DATA__t_in__WIDTH 1
+#define R_USB_EPT_DATA__low_speed__BITNR 26
+#define R_USB_EPT_DATA__low_speed__WIDTH 1
+#define R_USB_EPT_DATA__low_speed__no 0
+#define R_USB_EPT_DATA__low_speed__yes 1
+#define R_USB_EPT_DATA__port__BITNR 24
+#define R_USB_EPT_DATA__port__WIDTH 2
+#define R_USB_EPT_DATA__port__any 0
+#define R_USB_EPT_DATA__port__p1 1
+#define R_USB_EPT_DATA__port__p2 2
+#define R_USB_EPT_DATA__port__undef 3
+#define R_USB_EPT_DATA__error_code__BITNR 22
+#define R_USB_EPT_DATA__error_code__WIDTH 2
+#define R_USB_EPT_DATA__error_code__no_error 0
+#define R_USB_EPT_DATA__error_code__stall 1
+#define R_USB_EPT_DATA__error_code__bus_error 2
+#define R_USB_EPT_DATA__error_code__TBD3 3
+#define R_USB_EPT_DATA__t_out__BITNR 21
+#define R_USB_EPT_DATA__t_out__WIDTH 1
+#define R_USB_EPT_DATA__error_count_out__BITNR 19
+#define R_USB_EPT_DATA__error_count_out__WIDTH 2
+#define R_USB_EPT_DATA__max_len__BITNR 11
+#define R_USB_EPT_DATA__max_len__WIDTH 7
+#define R_USB_EPT_DATA__ep__BITNR 7
+#define R_USB_EPT_DATA__ep__WIDTH 4
+#define R_USB_EPT_DATA__dev__BITNR 0
+#define R_USB_EPT_DATA__dev__WIDTH 7
+
+#define R_USB_EPT_DATA_ISO (IO_TYPECAST_UDWORD 0xb000021c)
+#define R_USB_EPT_DATA_ISO__valid__BITNR 31
+#define R_USB_EPT_DATA_ISO__valid__WIDTH 1
+#define R_USB_EPT_DATA_ISO__valid__no 0
+#define R_USB_EPT_DATA_ISO__valid__yes 1
+#define R_USB_EPT_DATA_ISO__port__BITNR 24
+#define R_USB_EPT_DATA_ISO__port__WIDTH 2
+#define R_USB_EPT_DATA_ISO__port__any 0
+#define R_USB_EPT_DATA_ISO__port__p1 1
+#define R_USB_EPT_DATA_ISO__port__p2 2
+#define R_USB_EPT_DATA_ISO__port__undef 3
+#define R_USB_EPT_DATA_ISO__error_code__BITNR 22
+#define R_USB_EPT_DATA_ISO__error_code__WIDTH 2
+#define R_USB_EPT_DATA_ISO__error_code__no_error 0
+#define R_USB_EPT_DATA_ISO__error_code__stall 1
+#define R_USB_EPT_DATA_ISO__error_code__bus_error 2
+#define R_USB_EPT_DATA_ISO__error_code__TBD3 3
+#define R_USB_EPT_DATA_ISO__max_len__BITNR 11
+#define R_USB_EPT_DATA_ISO__max_len__WIDTH 10
+#define R_USB_EPT_DATA_ISO__ep__BITNR 7
+#define R_USB_EPT_DATA_ISO__ep__WIDTH 4
+#define R_USB_EPT_DATA_ISO__dev__BITNR 0
+#define R_USB_EPT_DATA_ISO__dev__WIDTH 7
+
+#define R_USB_EPT_DATA_DEV (IO_TYPECAST_UDWORD 0xb000021c)
+#define R_USB_EPT_DATA_DEV__valid__BITNR 31
+#define R_USB_EPT_DATA_DEV__valid__WIDTH 1
+#define R_USB_EPT_DATA_DEV__valid__no 0
+#define R_USB_EPT_DATA_DEV__valid__yes 1
+#define R_USB_EPT_DATA_DEV__hold__BITNR 30
+#define R_USB_EPT_DATA_DEV__hold__WIDTH 1
+#define R_USB_EPT_DATA_DEV__hold__no 0
+#define R_USB_EPT_DATA_DEV__hold__yes 1
+#define R_USB_EPT_DATA_DEV__stall__BITNR 29
+#define R_USB_EPT_DATA_DEV__stall__WIDTH 1
+#define R_USB_EPT_DATA_DEV__stall__no 0
+#define R_USB_EPT_DATA_DEV__stall__yes 1
+#define R_USB_EPT_DATA_DEV__quiet__BITNR 28
+#define R_USB_EPT_DATA_DEV__quiet__WIDTH 1
+#define R_USB_EPT_DATA_DEV__quiet__no 0
+#define R_USB_EPT_DATA_DEV__quiet__yes 1
+#define R_USB_EPT_DATA_DEV__ctrl__BITNR 27
+#define R_USB_EPT_DATA_DEV__ctrl__WIDTH 1
+#define R_USB_EPT_DATA_DEV__ctrl__no 0
+#define R_USB_EPT_DATA_DEV__ctrl__yes 1
+#define R_USB_EPT_DATA_DEV__iso__BITNR 26
+#define R_USB_EPT_DATA_DEV__iso__WIDTH 1
+#define R_USB_EPT_DATA_DEV__iso__no 0
+#define R_USB_EPT_DATA_DEV__iso__yes 1
+#define R_USB_EPT_DATA_DEV__port__BITNR 24
+#define R_USB_EPT_DATA_DEV__port__WIDTH 2
+#define R_USB_EPT_DATA_DEV__t__BITNR 21
+#define R_USB_EPT_DATA_DEV__t__WIDTH 1
+#define R_USB_EPT_DATA_DEV__max_len__BITNR 11
+#define R_USB_EPT_DATA_DEV__max_len__WIDTH 10
+#define R_USB_EPT_DATA_DEV__ep__BITNR 7
+#define R_USB_EPT_DATA_DEV__ep__WIDTH 4
+#define R_USB_EPT_DATA_DEV__dev__BITNR 0
+#define R_USB_EPT_DATA_DEV__dev__WIDTH 7
+
+#define R_USB_SNMP_TERROR (IO_TYPECAST_UDWORD 0xb0000220)
+#define R_USB_SNMP_TERROR__value__BITNR 0
+#define R_USB_SNMP_TERROR__value__WIDTH 32
+
+/*
+!* MMU registers
+!*/
+
+#define R_MMU_CONFIG (IO_TYPECAST_UDWORD 0xb0000240)
+#define R_MMU_CONFIG__mmu_enable__BITNR 31
+#define R_MMU_CONFIG__mmu_enable__WIDTH 1
+#define R_MMU_CONFIG__mmu_enable__enable 1
+#define R_MMU_CONFIG__mmu_enable__disable 0
+#define R_MMU_CONFIG__inv_excp__BITNR 18
+#define R_MMU_CONFIG__inv_excp__WIDTH 1
+#define R_MMU_CONFIG__inv_excp__enable 1
+#define R_MMU_CONFIG__inv_excp__disable 0
+#define R_MMU_CONFIG__acc_excp__BITNR 17
+#define R_MMU_CONFIG__acc_excp__WIDTH 1
+#define R_MMU_CONFIG__acc_excp__enable 1
+#define R_MMU_CONFIG__acc_excp__disable 0
+#define R_MMU_CONFIG__we_excp__BITNR 16
+#define R_MMU_CONFIG__we_excp__WIDTH 1
+#define R_MMU_CONFIG__we_excp__enable 1
+#define R_MMU_CONFIG__we_excp__disable 0
+#define R_MMU_CONFIG__seg_f__BITNR 15
+#define R_MMU_CONFIG__seg_f__WIDTH 1
+#define R_MMU_CONFIG__seg_f__seg 1
+#define R_MMU_CONFIG__seg_f__page 0
+#define R_MMU_CONFIG__seg_e__BITNR 14
+#define R_MMU_CONFIG__seg_e__WIDTH 1
+#define R_MMU_CONFIG__seg_e__seg 1
+#define R_MMU_CONFIG__seg_e__page 0
+#define R_MMU_CONFIG__seg_d__BITNR 13
+#define R_MMU_CONFIG__seg_d__WIDTH 1
+#define R_MMU_CONFIG__seg_d__seg 1
+#define R_MMU_CONFIG__seg_d__page 0
+#define R_MMU_CONFIG__seg_c__BITNR 12
+#define R_MMU_CONFIG__seg_c__WIDTH 1
+#define R_MMU_CONFIG__seg_c__seg 1
+#define R_MMU_CONFIG__seg_c__page 0
+#define R_MMU_CONFIG__seg_b__BITNR 11
+#define R_MMU_CONFIG__seg_b__WIDTH 1
+#define R_MMU_CONFIG__seg_b__seg 1
+#define R_MMU_CONFIG__seg_b__page 0
+#define R_MMU_CONFIG__seg_a__BITNR 10
+#define R_MMU_CONFIG__seg_a__WIDTH 1
+#define R_MMU_CONFIG__seg_a__seg 1
+#define R_MMU_CONFIG__seg_a__page 0
+#define R_MMU_CONFIG__seg_9__BITNR 9
+#define R_MMU_CONFIG__seg_9__WIDTH 1
+#define R_MMU_CONFIG__seg_9__seg 1
+#define R_MMU_CONFIG__seg_9__page 0
+#define R_MMU_CONFIG__seg_8__BITNR 8
+#define R_MMU_CONFIG__seg_8__WIDTH 1
+#define R_MMU_CONFIG__seg_8__seg 1
+#define R_MMU_CONFIG__seg_8__page 0
+#define R_MMU_CONFIG__seg_7__BITNR 7
+#define R_MMU_CONFIG__seg_7__WIDTH 1
+#define R_MMU_CONFIG__seg_7__seg 1
+#define R_MMU_CONFIG__seg_7__page 0
+#define R_MMU_CONFIG__seg_6__BITNR 6
+#define R_MMU_CONFIG__seg_6__WIDTH 1
+#define R_MMU_CONFIG__seg_6__seg 1
+#define R_MMU_CONFIG__seg_6__page 0
+#define R_MMU_CONFIG__seg_5__BITNR 5
+#define R_MMU_CONFIG__seg_5__WIDTH 1
+#define R_MMU_CONFIG__seg_5__seg 1
+#define R_MMU_CONFIG__seg_5__page 0
+#define R_MMU_CONFIG__seg_4__BITNR 4
+#define R_MMU_CONFIG__seg_4__WIDTH 1
+#define R_MMU_CONFIG__seg_4__seg 1
+#define R_MMU_CONFIG__seg_4__page 0
+#define R_MMU_CONFIG__seg_3__BITNR 3
+#define R_MMU_CONFIG__seg_3__WIDTH 1
+#define R_MMU_CONFIG__seg_3__seg 1
+#define R_MMU_CONFIG__seg_3__page 0
+#define R_MMU_CONFIG__seg_2__BITNR 2
+#define R_MMU_CONFIG__seg_2__WIDTH 1
+#define R_MMU_CONFIG__seg_2__seg 1
+#define R_MMU_CONFIG__seg_2__page 0
+#define R_MMU_CONFIG__seg_1__BITNR 1
+#define R_MMU_CONFIG__seg_1__WIDTH 1
+#define R_MMU_CONFIG__seg_1__seg 1
+#define R_MMU_CONFIG__seg_1__page 0
+#define R_MMU_CONFIG__seg_0__BITNR 0
+#define R_MMU_CONFIG__seg_0__WIDTH 1
+#define R_MMU_CONFIG__seg_0__seg 1
+#define R_MMU_CONFIG__seg_0__page 0
+
+#define R_MMU_KSEG (IO_TYPECAST_UWORD 0xb0000240)
+#define R_MMU_KSEG__seg_f__BITNR 15
+#define R_MMU_KSEG__seg_f__WIDTH 1
+#define R_MMU_KSEG__seg_f__seg 1
+#define R_MMU_KSEG__seg_f__page 0
+#define R_MMU_KSEG__seg_e__BITNR 14
+#define R_MMU_KSEG__seg_e__WIDTH 1
+#define R_MMU_KSEG__seg_e__seg 1
+#define R_MMU_KSEG__seg_e__page 0
+#define R_MMU_KSEG__seg_d__BITNR 13
+#define R_MMU_KSEG__seg_d__WIDTH 1
+#define R_MMU_KSEG__seg_d__seg 1
+#define R_MMU_KSEG__seg_d__page 0
+#define R_MMU_KSEG__seg_c__BITNR 12
+#define R_MMU_KSEG__seg_c__WIDTH 1
+#define R_MMU_KSEG__seg_c__seg 1
+#define R_MMU_KSEG__seg_c__page 0
+#define R_MMU_KSEG__seg_b__BITNR 11
+#define R_MMU_KSEG__seg_b__WIDTH 1
+#define R_MMU_KSEG__seg_b__seg 1
+#define R_MMU_KSEG__seg_b__page 0
+#define R_MMU_KSEG__seg_a__BITNR 10
+#define R_MMU_KSEG__seg_a__WIDTH 1
+#define R_MMU_KSEG__seg_a__seg 1
+#define R_MMU_KSEG__seg_a__page 0
+#define R_MMU_KSEG__seg_9__BITNR 9
+#define R_MMU_KSEG__seg_9__WIDTH 1
+#define R_MMU_KSEG__seg_9__seg 1
+#define R_MMU_KSEG__seg_9__page 0
+#define R_MMU_KSEG__seg_8__BITNR 8
+#define R_MMU_KSEG__seg_8__WIDTH 1
+#define R_MMU_KSEG__seg_8__seg 1
+#define R_MMU_KSEG__seg_8__page 0
+#define R_MMU_KSEG__seg_7__BITNR 7
+#define R_MMU_KSEG__seg_7__WIDTH 1
+#define R_MMU_KSEG__seg_7__seg 1
+#define R_MMU_KSEG__seg_7__page 0
+#define R_MMU_KSEG__seg_6__BITNR 6
+#define R_MMU_KSEG__seg_6__WIDTH 1
+#define R_MMU_KSEG__seg_6__seg 1
+#define R_MMU_KSEG__seg_6__page 0
+#define R_MMU_KSEG__seg_5__BITNR 5
+#define R_MMU_KSEG__seg_5__WIDTH 1
+#define R_MMU_KSEG__seg_5__seg 1
+#define R_MMU_KSEG__seg_5__page 0
+#define R_MMU_KSEG__seg_4__BITNR 4
+#define R_MMU_KSEG__seg_4__WIDTH 1
+#define R_MMU_KSEG__seg_4__seg 1
+#define R_MMU_KSEG__seg_4__page 0
+#define R_MMU_KSEG__seg_3__BITNR 3
+#define R_MMU_KSEG__seg_3__WIDTH 1
+#define R_MMU_KSEG__seg_3__seg 1
+#define R_MMU_KSEG__seg_3__page 0
+#define R_MMU_KSEG__seg_2__BITNR 2
+#define R_MMU_KSEG__seg_2__WIDTH 1
+#define R_MMU_KSEG__seg_2__seg 1
+#define R_MMU_KSEG__seg_2__page 0
+#define R_MMU_KSEG__seg_1__BITNR 1
+#define R_MMU_KSEG__seg_1__WIDTH 1
+#define R_MMU_KSEG__seg_1__seg 1
+#define R_MMU_KSEG__seg_1__page 0
+#define R_MMU_KSEG__seg_0__BITNR 0
+#define R_MMU_KSEG__seg_0__WIDTH 1
+#define R_MMU_KSEG__seg_0__seg 1
+#define R_MMU_KSEG__seg_0__page 0
+
+#define R_MMU_CTRL (IO_TYPECAST_BYTE 0xb0000242)
+#define R_MMU_CTRL__inv_excp__BITNR 2
+#define R_MMU_CTRL__inv_excp__WIDTH 1
+#define R_MMU_CTRL__inv_excp__enable 1
+#define R_MMU_CTRL__inv_excp__disable 0
+#define R_MMU_CTRL__acc_excp__BITNR 1
+#define R_MMU_CTRL__acc_excp__WIDTH 1
+#define R_MMU_CTRL__acc_excp__enable 1
+#define R_MMU_CTRL__acc_excp__disable 0
+#define R_MMU_CTRL__we_excp__BITNR 0
+#define R_MMU_CTRL__we_excp__WIDTH 1
+#define R_MMU_CTRL__we_excp__enable 1
+#define R_MMU_CTRL__we_excp__disable 0
+
+#define R_MMU_ENABLE (IO_TYPECAST_BYTE 0xb0000243)
+#define R_MMU_ENABLE__mmu_enable__BITNR 7
+#define R_MMU_ENABLE__mmu_enable__WIDTH 1
+#define R_MMU_ENABLE__mmu_enable__enable 1
+#define R_MMU_ENABLE__mmu_enable__disable 0
+
+#define R_MMU_KBASE_LO (IO_TYPECAST_UDWORD 0xb0000244)
+#define R_MMU_KBASE_LO__base_7__BITNR 28
+#define R_MMU_KBASE_LO__base_7__WIDTH 4
+#define R_MMU_KBASE_LO__base_6__BITNR 24
+#define R_MMU_KBASE_LO__base_6__WIDTH 4
+#define R_MMU_KBASE_LO__base_5__BITNR 20
+#define R_MMU_KBASE_LO__base_5__WIDTH 4
+#define R_MMU_KBASE_LO__base_4__BITNR 16
+#define R_MMU_KBASE_LO__base_4__WIDTH 4
+#define R_MMU_KBASE_LO__base_3__BITNR 12
+#define R_MMU_KBASE_LO__base_3__WIDTH 4
+#define R_MMU_KBASE_LO__base_2__BITNR 8
+#define R_MMU_KBASE_LO__base_2__WIDTH 4
+#define R_MMU_KBASE_LO__base_1__BITNR 4
+#define R_MMU_KBASE_LO__base_1__WIDTH 4
+#define R_MMU_KBASE_LO__base_0__BITNR 0
+#define R_MMU_KBASE_LO__base_0__WIDTH 4
+
+#define R_MMU_KBASE_HI (IO_TYPECAST_UDWORD 0xb0000248)
+#define R_MMU_KBASE_HI__base_f__BITNR 28
+#define R_MMU_KBASE_HI__base_f__WIDTH 4
+#define R_MMU_KBASE_HI__base_e__BITNR 24
+#define R_MMU_KBASE_HI__base_e__WIDTH 4
+#define R_MMU_KBASE_HI__base_d__BITNR 20
+#define R_MMU_KBASE_HI__base_d__WIDTH 4
+#define R_MMU_KBASE_HI__base_c__BITNR 16
+#define R_MMU_KBASE_HI__base_c__WIDTH 4
+#define R_MMU_KBASE_HI__base_b__BITNR 12
+#define R_MMU_KBASE_HI__base_b__WIDTH 4
+#define R_MMU_KBASE_HI__base_a__BITNR 8
+#define R_MMU_KBASE_HI__base_a__WIDTH 4
+#define R_MMU_KBASE_HI__base_9__BITNR 4
+#define R_MMU_KBASE_HI__base_9__WIDTH 4
+#define R_MMU_KBASE_HI__base_8__BITNR 0
+#define R_MMU_KBASE_HI__base_8__WIDTH 4
+
+#define R_MMU_CONTEXT (IO_TYPECAST_BYTE 0xb000024c)
+#define R_MMU_CONTEXT__page_id__BITNR 0
+#define R_MMU_CONTEXT__page_id__WIDTH 6
+
+#define R_MMU_CAUSE (IO_TYPECAST_RO_UDWORD 0xb0000250)
+#define R_MMU_CAUSE__vpn__BITNR 13
+#define R_MMU_CAUSE__vpn__WIDTH 19
+#define R_MMU_CAUSE__miss_excp__BITNR 12
+#define R_MMU_CAUSE__miss_excp__WIDTH 1
+#define R_MMU_CAUSE__miss_excp__yes 1
+#define R_MMU_CAUSE__miss_excp__no 0
+#define R_MMU_CAUSE__inv_excp__BITNR 11
+#define R_MMU_CAUSE__inv_excp__WIDTH 1
+#define R_MMU_CAUSE__inv_excp__yes 1
+#define R_MMU_CAUSE__inv_excp__no 0
+#define R_MMU_CAUSE__acc_excp__BITNR 10
+#define R_MMU_CAUSE__acc_excp__WIDTH 1
+#define R_MMU_CAUSE__acc_excp__yes 1
+#define R_MMU_CAUSE__acc_excp__no 0
+#define R_MMU_CAUSE__we_excp__BITNR 9
+#define R_MMU_CAUSE__we_excp__WIDTH 1
+#define R_MMU_CAUSE__we_excp__yes 1
+#define R_MMU_CAUSE__we_excp__no 0
+#define R_MMU_CAUSE__page_id__BITNR 0
+#define R_MMU_CAUSE__page_id__WIDTH 6
+
+#define R_TLB_SELECT (IO_TYPECAST_BYTE 0xb0000254)
+#define R_TLB_SELECT__index__BITNR 0
+#define R_TLB_SELECT__index__WIDTH 6
+
+#define R_TLB_LO (IO_TYPECAST_UDWORD 0xb0000258)
+#define R_TLB_LO__pfn__BITNR 13
+#define R_TLB_LO__pfn__WIDTH 19
+#define R_TLB_LO__global__BITNR 3
+#define R_TLB_LO__global__WIDTH 1
+#define R_TLB_LO__global__yes 1
+#define R_TLB_LO__global__no 0
+#define R_TLB_LO__valid__BITNR 2
+#define R_TLB_LO__valid__WIDTH 1
+#define R_TLB_LO__valid__yes 1
+#define R_TLB_LO__valid__no 0
+#define R_TLB_LO__kernel__BITNR 1
+#define R_TLB_LO__kernel__WIDTH 1
+#define R_TLB_LO__kernel__yes 1
+#define R_TLB_LO__kernel__no 0
+#define R_TLB_LO__we__BITNR 0
+#define R_TLB_LO__we__WIDTH 1
+#define R_TLB_LO__we__yes 1
+#define R_TLB_LO__we__no 0
+
+#define R_TLB_HI (IO_TYPECAST_UDWORD 0xb000025c)
+#define R_TLB_HI__vpn__BITNR 13
+#define R_TLB_HI__vpn__WIDTH 19
+#define R_TLB_HI__page_id__BITNR 0
+#define R_TLB_HI__page_id__WIDTH 6
+
+/*
+!* Syncrounous serial port registers
+!*/
+
+#define R_SYNC_SERIAL1_REC_DATA (IO_TYPECAST_RO_UDWORD 0xb000006c)
+#define R_SYNC_SERIAL1_REC_DATA__data_in__BITNR 0
+#define R_SYNC_SERIAL1_REC_DATA__data_in__WIDTH 32
+
+#define R_SYNC_SERIAL1_REC_WORD (IO_TYPECAST_RO_UWORD 0xb000006c)
+#define R_SYNC_SERIAL1_REC_WORD__data_in__BITNR 0
+#define R_SYNC_SERIAL1_REC_WORD__data_in__WIDTH 16
+
+#define R_SYNC_SERIAL1_REC_BYTE (IO_TYPECAST_RO_BYTE 0xb000006c)
+#define R_SYNC_SERIAL1_REC_BYTE__data_in__BITNR 0
+#define R_SYNC_SERIAL1_REC_BYTE__data_in__WIDTH 8
+
+#define R_SYNC_SERIAL1_STATUS (IO_TYPECAST_RO_UDWORD 0xb0000068)
+#define R_SYNC_SERIAL1_STATUS__rec_status__BITNR 15
+#define R_SYNC_SERIAL1_STATUS__rec_status__WIDTH 1
+#define R_SYNC_SERIAL1_STATUS__rec_status__running 0
+#define R_SYNC_SERIAL1_STATUS__rec_status__idle 1
+#define R_SYNC_SERIAL1_STATUS__tr_empty__BITNR 14
+#define R_SYNC_SERIAL1_STATUS__tr_empty__WIDTH 1
+#define R_SYNC_SERIAL1_STATUS__tr_empty__empty 1
+#define R_SYNC_SERIAL1_STATUS__tr_empty__not_empty 0
+#define R_SYNC_SERIAL1_STATUS__tr_ready__BITNR 13
+#define R_SYNC_SERIAL1_STATUS__tr_ready__WIDTH 1
+#define R_SYNC_SERIAL1_STATUS__tr_ready__full 0
+#define R_SYNC_SERIAL1_STATUS__tr_ready__ready 1
+#define R_SYNC_SERIAL1_STATUS__pin_1__BITNR 12
+#define R_SYNC_SERIAL1_STATUS__pin_1__WIDTH 1
+#define R_SYNC_SERIAL1_STATUS__pin_1__low 0
+#define R_SYNC_SERIAL1_STATUS__pin_1__high 1
+#define R_SYNC_SERIAL1_STATUS__pin_0__BITNR 11
+#define R_SYNC_SERIAL1_STATUS__pin_0__WIDTH 1
+#define R_SYNC_SERIAL1_STATUS__pin_0__low 0
+#define R_SYNC_SERIAL1_STATUS__pin_0__high 1
+#define R_SYNC_SERIAL1_STATUS__underflow__BITNR 10
+#define R_SYNC_SERIAL1_STATUS__underflow__WIDTH 1
+#define R_SYNC_SERIAL1_STATUS__underflow__no 0
+#define R_SYNC_SERIAL1_STATUS__underflow__yes 1
+#define R_SYNC_SERIAL1_STATUS__overrun__BITNR 9
+#define R_SYNC_SERIAL1_STATUS__overrun__WIDTH 1
+#define R_SYNC_SERIAL1_STATUS__overrun__no 0
+#define R_SYNC_SERIAL1_STATUS__overrun__yes 1
+#define R_SYNC_SERIAL1_STATUS__data_avail__BITNR 8
+#define R_SYNC_SERIAL1_STATUS__data_avail__WIDTH 1
+#define R_SYNC_SERIAL1_STATUS__data_avail__no 0
+#define R_SYNC_SERIAL1_STATUS__data_avail__yes 1
+#define R_SYNC_SERIAL1_STATUS__data__BITNR 0
+#define R_SYNC_SERIAL1_STATUS__data__WIDTH 8
+
+#define R_SYNC_SERIAL1_TR_DATA (IO_TYPECAST_UDWORD 0xb000006c)
+#define R_SYNC_SERIAL1_TR_DATA__data_out__BITNR 0
+#define R_SYNC_SERIAL1_TR_DATA__data_out__WIDTH 32
+
+#define R_SYNC_SERIAL1_TR_WORD (IO_TYPECAST_UWORD 0xb000006c)
+#define R_SYNC_SERIAL1_TR_WORD__data_out__BITNR 0
+#define R_SYNC_SERIAL1_TR_WORD__data_out__WIDTH 16
+
+#define R_SYNC_SERIAL1_TR_BYTE (IO_TYPECAST_BYTE 0xb000006c)
+#define R_SYNC_SERIAL1_TR_BYTE__data_out__BITNR 0
+#define R_SYNC_SERIAL1_TR_BYTE__data_out__WIDTH 8
+
+#define R_SYNC_SERIAL1_CTRL (IO_TYPECAST_UDWORD 0xb0000068)
+#define R_SYNC_SERIAL1_CTRL__tr_baud__BITNR 28
+#define R_SYNC_SERIAL1_CTRL__tr_baud__WIDTH 4
+#define R_SYNC_SERIAL1_CTRL__tr_baud__c150Hz 0
+#define R_SYNC_SERIAL1_CTRL__tr_baud__c300Hz 1
+#define R_SYNC_SERIAL1_CTRL__tr_baud__c600Hz 2
+#define R_SYNC_SERIAL1_CTRL__tr_baud__c1200Hz 3
+#define R_SYNC_SERIAL1_CTRL__tr_baud__c2400Hz 4
+#define R_SYNC_SERIAL1_CTRL__tr_baud__c4800Hz 5
+#define R_SYNC_SERIAL1_CTRL__tr_baud__c9600Hz 6
+#define R_SYNC_SERIAL1_CTRL__tr_baud__c19k2Hz 7
+#define R_SYNC_SERIAL1_CTRL__tr_baud__c28k8Hz 8
+#define R_SYNC_SERIAL1_CTRL__tr_baud__c57k6Hz 9
+#define R_SYNC_SERIAL1_CTRL__tr_baud__c115k2Hz 10
+#define R_SYNC_SERIAL1_CTRL__tr_baud__c230k4Hz 11
+#define R_SYNC_SERIAL1_CTRL__tr_baud__c460k8Hz 12
+#define R_SYNC_SERIAL1_CTRL__tr_baud__c921k6Hz 13
+#define R_SYNC_SERIAL1_CTRL__tr_baud__c3125kHz 14
+#define R_SYNC_SERIAL1_CTRL__tr_baud__reserved 15
+#define R_SYNC_SERIAL1_CTRL__dma_enable__BITNR 27
+#define R_SYNC_SERIAL1_CTRL__dma_enable__WIDTH 1
+#define R_SYNC_SERIAL1_CTRL__dma_enable__on 1
+#define R_SYNC_SERIAL1_CTRL__dma_enable__off 0
+#define R_SYNC_SERIAL1_CTRL__mode__BITNR 24
+#define R_SYNC_SERIAL1_CTRL__mode__WIDTH 3
+#define R_SYNC_SERIAL1_CTRL__mode__master_output 0
+#define R_SYNC_SERIAL1_CTRL__mode__slave_output 1
+#define R_SYNC_SERIAL1_CTRL__mode__master_input 2
+#define R_SYNC_SERIAL1_CTRL__mode__slave_input 3
+#define R_SYNC_SERIAL1_CTRL__mode__master_bidir 4
+#define R_SYNC_SERIAL1_CTRL__mode__slave_bidir 5
+#define R_SYNC_SERIAL1_CTRL__error__BITNR 23
+#define R_SYNC_SERIAL1_CTRL__error__WIDTH 1
+#define R_SYNC_SERIAL1_CTRL__error__normal 0
+#define R_SYNC_SERIAL1_CTRL__error__ignore 1
+#define R_SYNC_SERIAL1_CTRL__rec_enable__BITNR 22
+#define R_SYNC_SERIAL1_CTRL__rec_enable__WIDTH 1
+#define R_SYNC_SERIAL1_CTRL__rec_enable__disable 0
+#define R_SYNC_SERIAL1_CTRL__rec_enable__enable 1
+#define R_SYNC_SERIAL1_CTRL__f_synctype__BITNR 21
+#define R_SYNC_SERIAL1_CTRL__f_synctype__WIDTH 1
+#define R_SYNC_SERIAL1_CTRL__f_synctype__normal 0
+#define R_SYNC_SERIAL1_CTRL__f_synctype__early 1
+#define R_SYNC_SERIAL1_CTRL__f_syncsize__BITNR 19
+#define R_SYNC_SERIAL1_CTRL__f_syncsize__WIDTH 2
+#define R_SYNC_SERIAL1_CTRL__f_syncsize__bit 0
+#define R_SYNC_SERIAL1_CTRL__f_syncsize__word 1
+#define R_SYNC_SERIAL1_CTRL__f_syncsize__extended 2
+#define R_SYNC_SERIAL1_CTRL__f_syncsize__reserved 3
+#define R_SYNC_SERIAL1_CTRL__f_sync__BITNR 18
+#define R_SYNC_SERIAL1_CTRL__f_sync__WIDTH 1
+#define R_SYNC_SERIAL1_CTRL__f_sync__on 0
+#define R_SYNC_SERIAL1_CTRL__f_sync__off 1
+#define R_SYNC_SERIAL1_CTRL__clk_mode__BITNR 17
+#define R_SYNC_SERIAL1_CTRL__clk_mode__WIDTH 1
+#define R_SYNC_SERIAL1_CTRL__clk_mode__normal 0
+#define R_SYNC_SERIAL1_CTRL__clk_mode__gated 1
+#define R_SYNC_SERIAL1_CTRL__clk_halt__BITNR 16
+#define R_SYNC_SERIAL1_CTRL__clk_halt__WIDTH 1
+#define R_SYNC_SERIAL1_CTRL__clk_halt__running 0
+#define R_SYNC_SERIAL1_CTRL__clk_halt__stopped 1
+#define R_SYNC_SERIAL1_CTRL__bitorder__BITNR 15
+#define R_SYNC_SERIAL1_CTRL__bitorder__WIDTH 1
+#define R_SYNC_SERIAL1_CTRL__bitorder__lsb 0
+#define R_SYNC_SERIAL1_CTRL__bitorder__msb 1
+#define R_SYNC_SERIAL1_CTRL__tr_enable__BITNR 14
+#define R_SYNC_SERIAL1_CTRL__tr_enable__WIDTH 1
+#define R_SYNC_SERIAL1_CTRL__tr_enable__disable 0
+#define R_SYNC_SERIAL1_CTRL__tr_enable__enable 1
+#define R_SYNC_SERIAL1_CTRL__wordsize__BITNR 11
+#define R_SYNC_SERIAL1_CTRL__wordsize__WIDTH 3
+#define R_SYNC_SERIAL1_CTRL__wordsize__size8bit 0
+#define R_SYNC_SERIAL1_CTRL__wordsize__size12bit 1
+#define R_SYNC_SERIAL1_CTRL__wordsize__size16bit 2
+#define R_SYNC_SERIAL1_CTRL__wordsize__size24bit 3
+#define R_SYNC_SERIAL1_CTRL__wordsize__size32bit 4
+#define R_SYNC_SERIAL1_CTRL__buf_empty__BITNR 10
+#define R_SYNC_SERIAL1_CTRL__buf_empty__WIDTH 1
+#define R_SYNC_SERIAL1_CTRL__buf_empty__lmt_8 0
+#define R_SYNC_SERIAL1_CTRL__buf_empty__lmt_0 1
+#define R_SYNC_SERIAL1_CTRL__buf_full__BITNR 9
+#define R_SYNC_SERIAL1_CTRL__buf_full__WIDTH 1
+#define R_SYNC_SERIAL1_CTRL__buf_full__lmt_32 0
+#define R_SYNC_SERIAL1_CTRL__buf_full__lmt_8 1
+#define R_SYNC_SERIAL1_CTRL__flow_ctrl__BITNR 8
+#define R_SYNC_SERIAL1_CTRL__flow_ctrl__WIDTH 1
+#define R_SYNC_SERIAL1_CTRL__flow_ctrl__disabled 0
+#define R_SYNC_SERIAL1_CTRL__flow_ctrl__enabled 1
+#define R_SYNC_SERIAL1_CTRL__clk_polarity__BITNR 6
+#define R_SYNC_SERIAL1_CTRL__clk_polarity__WIDTH 1
+#define R_SYNC_SERIAL1_CTRL__clk_polarity__pos 0
+#define R_SYNC_SERIAL1_CTRL__clk_polarity__neg 1
+#define R_SYNC_SERIAL1_CTRL__frame_polarity__BITNR 5
+#define R_SYNC_SERIAL1_CTRL__frame_polarity__WIDTH 1
+#define R_SYNC_SERIAL1_CTRL__frame_polarity__normal 0
+#define R_SYNC_SERIAL1_CTRL__frame_polarity__inverted 1
+#define R_SYNC_SERIAL1_CTRL__status_polarity__BITNR 4
+#define R_SYNC_SERIAL1_CTRL__status_polarity__WIDTH 1
+#define R_SYNC_SERIAL1_CTRL__status_polarity__normal 0
+#define R_SYNC_SERIAL1_CTRL__status_polarity__inverted 1
+#define R_SYNC_SERIAL1_CTRL__clk_driver__BITNR 3
+#define R_SYNC_SERIAL1_CTRL__clk_driver__WIDTH 1
+#define R_SYNC_SERIAL1_CTRL__clk_driver__normal 0
+#define R_SYNC_SERIAL1_CTRL__clk_driver__inverted 1
+#define R_SYNC_SERIAL1_CTRL__frame_driver__BITNR 2
+#define R_SYNC_SERIAL1_CTRL__frame_driver__WIDTH 1
+#define R_SYNC_SERIAL1_CTRL__frame_driver__normal 0
+#define R_SYNC_SERIAL1_CTRL__frame_driver__inverted 1
+#define R_SYNC_SERIAL1_CTRL__status_driver__BITNR 1
+#define R_SYNC_SERIAL1_CTRL__status_driver__WIDTH 1
+#define R_SYNC_SERIAL1_CTRL__status_driver__normal 0
+#define R_SYNC_SERIAL1_CTRL__status_driver__inverted 1
+#define R_SYNC_SERIAL1_CTRL__def_out0__BITNR 0
+#define R_SYNC_SERIAL1_CTRL__def_out0__WIDTH 1
+#define R_SYNC_SERIAL1_CTRL__def_out0__high 1
+#define R_SYNC_SERIAL1_CTRL__def_out0__low 0
+
+#define R_SYNC_SERIAL3_REC_DATA (IO_TYPECAST_RO_UDWORD 0xb000007c)
+#define R_SYNC_SERIAL3_REC_DATA__data_in__BITNR 0
+#define R_SYNC_SERIAL3_REC_DATA__data_in__WIDTH 32
+
+#define R_SYNC_SERIAL3_REC_WORD (IO_TYPECAST_RO_UWORD 0xb000007c)
+#define R_SYNC_SERIAL3_REC_WORD__data_in__BITNR 0
+#define R_SYNC_SERIAL3_REC_WORD__data_in__WIDTH 16
+
+#define R_SYNC_SERIAL3_REC_BYTE (IO_TYPECAST_RO_BYTE 0xb000007c)
+#define R_SYNC_SERIAL3_REC_BYTE__data_in__BITNR 0
+#define R_SYNC_SERIAL3_REC_BYTE__data_in__WIDTH 8
+
+#define R_SYNC_SERIAL3_STATUS (IO_TYPECAST_RO_UDWORD 0xb0000078)
+#define R_SYNC_SERIAL3_STATUS__rec_status__BITNR 15
+#define R_SYNC_SERIAL3_STATUS__rec_status__WIDTH 1
+#define R_SYNC_SERIAL3_STATUS__rec_status__running 0
+#define R_SYNC_SERIAL3_STATUS__rec_status__idle 1
+#define R_SYNC_SERIAL3_STATUS__tr_empty__BITNR 14
+#define R_SYNC_SERIAL3_STATUS__tr_empty__WIDTH 1
+#define R_SYNC_SERIAL3_STATUS__tr_empty__empty 1
+#define R_SYNC_SERIAL3_STATUS__tr_empty__not_empty 0
+#define R_SYNC_SERIAL3_STATUS__tr_ready__BITNR 13
+#define R_SYNC_SERIAL3_STATUS__tr_ready__WIDTH 1
+#define R_SYNC_SERIAL3_STATUS__tr_ready__full 0
+#define R_SYNC_SERIAL3_STATUS__tr_ready__ready 1
+#define R_SYNC_SERIAL3_STATUS__pin_1__BITNR 12
+#define R_SYNC_SERIAL3_STATUS__pin_1__WIDTH 1
+#define R_SYNC_SERIAL3_STATUS__pin_1__low 0
+#define R_SYNC_SERIAL3_STATUS__pin_1__high 1
+#define R_SYNC_SERIAL3_STATUS__pin_0__BITNR 11
+#define R_SYNC_SERIAL3_STATUS__pin_0__WIDTH 1
+#define R_SYNC_SERIAL3_STATUS__pin_0__low 0
+#define R_SYNC_SERIAL3_STATUS__pin_0__high 1
+#define R_SYNC_SERIAL3_STATUS__underflow__BITNR 10
+#define R_SYNC_SERIAL3_STATUS__underflow__WIDTH 1
+#define R_SYNC_SERIAL3_STATUS__underflow__no 0
+#define R_SYNC_SERIAL3_STATUS__underflow__yes 1
+#define R_SYNC_SERIAL3_STATUS__overrun__BITNR 9
+#define R_SYNC_SERIAL3_STATUS__overrun__WIDTH 1
+#define R_SYNC_SERIAL3_STATUS__overrun__no 0
+#define R_SYNC_SERIAL3_STATUS__overrun__yes 1
+#define R_SYNC_SERIAL3_STATUS__data_avail__BITNR 8
+#define R_SYNC_SERIAL3_STATUS__data_avail__WIDTH 1
+#define R_SYNC_SERIAL3_STATUS__data_avail__no 0
+#define R_SYNC_SERIAL3_STATUS__data_avail__yes 1
+#define R_SYNC_SERIAL3_STATUS__data__BITNR 0
+#define R_SYNC_SERIAL3_STATUS__data__WIDTH 8
+
+#define R_SYNC_SERIAL3_TR_DATA (IO_TYPECAST_UDWORD 0xb000007c)
+#define R_SYNC_SERIAL3_TR_DATA__data_out__BITNR 0
+#define R_SYNC_SERIAL3_TR_DATA__data_out__WIDTH 32
+
+#define R_SYNC_SERIAL3_TR_WORD (IO_TYPECAST_UWORD 0xb000007c)
+#define R_SYNC_SERIAL3_TR_WORD__data_out__BITNR 0
+#define R_SYNC_SERIAL3_TR_WORD__data_out__WIDTH 16
+
+#define R_SYNC_SERIAL3_TR_BYTE (IO_TYPECAST_BYTE 0xb000007c)
+#define R_SYNC_SERIAL3_TR_BYTE__data_out__BITNR 0
+#define R_SYNC_SERIAL3_TR_BYTE__data_out__WIDTH 8
+
+#define R_SYNC_SERIAL3_CTRL (IO_TYPECAST_UDWORD 0xb0000078)
+#define R_SYNC_SERIAL3_CTRL__tr_baud__BITNR 28
+#define R_SYNC_SERIAL3_CTRL__tr_baud__WIDTH 4
+#define R_SYNC_SERIAL3_CTRL__tr_baud__c150Hz 0
+#define R_SYNC_SERIAL3_CTRL__tr_baud__c300Hz 1
+#define R_SYNC_SERIAL3_CTRL__tr_baud__c600Hz 2
+#define R_SYNC_SERIAL3_CTRL__tr_baud__c1200Hz 3
+#define R_SYNC_SERIAL3_CTRL__tr_baud__c2400Hz 4
+#define R_SYNC_SERIAL3_CTRL__tr_baud__c4800Hz 5
+#define R_SYNC_SERIAL3_CTRL__tr_baud__c9600Hz 6
+#define R_SYNC_SERIAL3_CTRL__tr_baud__c19k2Hz 7
+#define R_SYNC_SERIAL3_CTRL__tr_baud__c28k8Hz 8
+#define R_SYNC_SERIAL3_CTRL__tr_baud__c57k6Hz 9
+#define R_SYNC_SERIAL3_CTRL__tr_baud__c115k2Hz 10
+#define R_SYNC_SERIAL3_CTRL__tr_baud__c230k4Hz 11
+#define R_SYNC_SERIAL3_CTRL__tr_baud__c460k8Hz 12
+#define R_SYNC_SERIAL3_CTRL__tr_baud__c921k6Hz 13
+#define R_SYNC_SERIAL3_CTRL__tr_baud__c3125kHz 14
+#define R_SYNC_SERIAL3_CTRL__tr_baud__reserved 15
+#define R_SYNC_SERIAL3_CTRL__dma_enable__BITNR 27
+#define R_SYNC_SERIAL3_CTRL__dma_enable__WIDTH 1
+#define R_SYNC_SERIAL3_CTRL__dma_enable__on 1
+#define R_SYNC_SERIAL3_CTRL__dma_enable__off 0
+#define R_SYNC_SERIAL3_CTRL__mode__BITNR 24
+#define R_SYNC_SERIAL3_CTRL__mode__WIDTH 3
+#define R_SYNC_SERIAL3_CTRL__mode__master_output 0
+#define R_SYNC_SERIAL3_CTRL__mode__slave_output 1
+#define R_SYNC_SERIAL3_CTRL__mode__master_input 2
+#define R_SYNC_SERIAL3_CTRL__mode__slave_input 3
+#define R_SYNC_SERIAL3_CTRL__mode__master_bidir 4
+#define R_SYNC_SERIAL3_CTRL__mode__slave_bidir 5
+#define R_SYNC_SERIAL3_CTRL__error__BITNR 23
+#define R_SYNC_SERIAL3_CTRL__error__WIDTH 1
+#define R_SYNC_SERIAL3_CTRL__error__normal 0
+#define R_SYNC_SERIAL3_CTRL__error__ignore 1
+#define R_SYNC_SERIAL3_CTRL__rec_enable__BITNR 22
+#define R_SYNC_SERIAL3_CTRL__rec_enable__WIDTH 1
+#define R_SYNC_SERIAL3_CTRL__rec_enable__disable 0
+#define R_SYNC_SERIAL3_CTRL__rec_enable__enable 1
+#define R_SYNC_SERIAL3_CTRL__f_synctype__BITNR 21
+#define R_SYNC_SERIAL3_CTRL__f_synctype__WIDTH 1
+#define R_SYNC_SERIAL3_CTRL__f_synctype__normal 0
+#define R_SYNC_SERIAL3_CTRL__f_synctype__early 1
+#define R_SYNC_SERIAL3_CTRL__f_syncsize__BITNR 19
+#define R_SYNC_SERIAL3_CTRL__f_syncsize__WIDTH 2
+#define R_SYNC_SERIAL3_CTRL__f_syncsize__bit 0
+#define R_SYNC_SERIAL3_CTRL__f_syncsize__word 1
+#define R_SYNC_SERIAL3_CTRL__f_syncsize__extended 2
+#define R_SYNC_SERIAL3_CTRL__f_syncsize__reserved 3
+#define R_SYNC_SERIAL3_CTRL__f_sync__BITNR 18
+#define R_SYNC_SERIAL3_CTRL__f_sync__WIDTH 1
+#define R_SYNC_SERIAL3_CTRL__f_sync__on 0
+#define R_SYNC_SERIAL3_CTRL__f_sync__off 1
+#define R_SYNC_SERIAL3_CTRL__clk_mode__BITNR 17
+#define R_SYNC_SERIAL3_CTRL__clk_mode__WIDTH 1
+#define R_SYNC_SERIAL3_CTRL__clk_mode__normal 0
+#define R_SYNC_SERIAL3_CTRL__clk_mode__gated 1
+#define R_SYNC_SERIAL3_CTRL__clk_halt__BITNR 16
+#define R_SYNC_SERIAL3_CTRL__clk_halt__WIDTH 1
+#define R_SYNC_SERIAL3_CTRL__clk_halt__running 0
+#define R_SYNC_SERIAL3_CTRL__clk_halt__stopped 1
+#define R_SYNC_SERIAL3_CTRL__bitorder__BITNR 15
+#define R_SYNC_SERIAL3_CTRL__bitorder__WIDTH 1
+#define R_SYNC_SERIAL3_CTRL__bitorder__lsb 0
+#define R_SYNC_SERIAL3_CTRL__bitorder__msb 1
+#define R_SYNC_SERIAL3_CTRL__tr_enable__BITNR 14
+#define R_SYNC_SERIAL3_CTRL__tr_enable__WIDTH 1
+#define R_SYNC_SERIAL3_CTRL__tr_enable__disable 0
+#define R_SYNC_SERIAL3_CTRL__tr_enable__enable 1
+#define R_SYNC_SERIAL3_CTRL__wordsize__BITNR 11
+#define R_SYNC_SERIAL3_CTRL__wordsize__WIDTH 3
+#define R_SYNC_SERIAL3_CTRL__wordsize__size8bit 0
+#define R_SYNC_SERIAL3_CTRL__wordsize__size12bit 1
+#define R_SYNC_SERIAL3_CTRL__wordsize__size16bit 2
+#define R_SYNC_SERIAL3_CTRL__wordsize__size24bit 3
+#define R_SYNC_SERIAL3_CTRL__wordsize__size32bit 4
+#define R_SYNC_SERIAL3_CTRL__buf_empty__BITNR 10
+#define R_SYNC_SERIAL3_CTRL__buf_empty__WIDTH 1
+#define R_SYNC_SERIAL3_CTRL__buf_empty__lmt_8 0
+#define R_SYNC_SERIAL3_CTRL__buf_empty__lmt_0 1
+#define R_SYNC_SERIAL3_CTRL__buf_full__BITNR 9
+#define R_SYNC_SERIAL3_CTRL__buf_full__WIDTH 1
+#define R_SYNC_SERIAL3_CTRL__buf_full__lmt_32 0
+#define R_SYNC_SERIAL3_CTRL__buf_full__lmt_8 1
+#define R_SYNC_SERIAL3_CTRL__flow_ctrl__BITNR 8
+#define R_SYNC_SERIAL3_CTRL__flow_ctrl__WIDTH 1
+#define R_SYNC_SERIAL3_CTRL__flow_ctrl__disabled 0
+#define R_SYNC_SERIAL3_CTRL__flow_ctrl__enabled 1
+#define R_SYNC_SERIAL3_CTRL__clk_polarity__BITNR 6
+#define R_SYNC_SERIAL3_CTRL__clk_polarity__WIDTH 1
+#define R_SYNC_SERIAL3_CTRL__clk_polarity__pos 0
+#define R_SYNC_SERIAL3_CTRL__clk_polarity__neg 1
+#define R_SYNC_SERIAL3_CTRL__frame_polarity__BITNR 5
+#define R_SYNC_SERIAL3_CTRL__frame_polarity__WIDTH 1
+#define R_SYNC_SERIAL3_CTRL__frame_polarity__normal 0
+#define R_SYNC_SERIAL3_CTRL__frame_polarity__inverted 1
+#define R_SYNC_SERIAL3_CTRL__status_polarity__BITNR 4
+#define R_SYNC_SERIAL3_CTRL__status_polarity__WIDTH 1
+#define R_SYNC_SERIAL3_CTRL__status_polarity__normal 0
+#define R_SYNC_SERIAL3_CTRL__status_polarity__inverted 1
+#define R_SYNC_SERIAL3_CTRL__clk_driver__BITNR 3
+#define R_SYNC_SERIAL3_CTRL__clk_driver__WIDTH 1
+#define R_SYNC_SERIAL3_CTRL__clk_driver__normal 0
+#define R_SYNC_SERIAL3_CTRL__clk_driver__inverted 1
+#define R_SYNC_SERIAL3_CTRL__frame_driver__BITNR 2
+#define R_SYNC_SERIAL3_CTRL__frame_driver__WIDTH 1
+#define R_SYNC_SERIAL3_CTRL__frame_driver__normal 0
+#define R_SYNC_SERIAL3_CTRL__frame_driver__inverted 1
+#define R_SYNC_SERIAL3_CTRL__status_driver__BITNR 1
+#define R_SYNC_SERIAL3_CTRL__status_driver__WIDTH 1
+#define R_SYNC_SERIAL3_CTRL__status_driver__normal 0
+#define R_SYNC_SERIAL3_CTRL__status_driver__inverted 1
+#define R_SYNC_SERIAL3_CTRL__def_out0__BITNR 0
+#define R_SYNC_SERIAL3_CTRL__def_out0__WIDTH 1
+#define R_SYNC_SERIAL3_CTRL__def_out0__high 1
+#define R_SYNC_SERIAL3_CTRL__def_out0__low 0
+
diff -urN linux-2.4.2-pre1/include/asm-cris/sv_addr_ag.h linux/include/asm-cris/sv_addr_ag.h
--- linux-2.4.2-pre1/include/asm-cris/sv_addr_ag.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/sv_addr_ag.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,129 @@
+/*!**************************************************************************
+*!                                                            
+*! MACROS:
+*!   IO_MASK(reg,field)
+*!   IO_STATE(reg,field,state)
+*!   IO_EXTRACT(reg,field,val)
+*!   IO_STATE_VALUE(reg,field,state)
+*!   IO_BITNR(reg,field)
+*!   IO_WIDTH(reg,field)
+*!   IO_FIELD(reg,field,val)
+*!   IO_RD(reg)
+*!   All moderegister addresses and fields of these.
+*!
+*!**************************************************************************/
+
+#ifndef __sv_addr_ag_h__
+#define __sv_addr_ag_h__
+
+
+#define __test_sv_addr__ 0
+
+/*------------------------------------------------------------
+!* General macros to manipulate moderegisters.
+!*-----------------------------------------------------------*/
+
+/* IO_MASK returns a mask for a specified bitfield in a register.
+   Note that this macro doesn't work when field width is 32 bits. */
+#define IO_MASK(reg,field) \
+    ( ( ( 1 << reg##__##field##__WIDTH ) - 1 ) << reg##__##field##__BITNR )
+
+/* IO_STATE returns a constant corresponding to a one of the symbolic
+   states that the bitfield can have. (Shifted to correct position)  */
+#define IO_STATE(reg,field,state) \
+    ( reg##__##field##__##state << reg##__##field##__BITNR )
+
+/* IO_EXTRACT returns the masked and shifted value corresponding to the
+   bitfield can have. */
+#define IO_EXTRACT(reg,field,val) ( (( ( ( 1 << reg##__##field##__WIDTH ) \
+     - 1 ) << reg##__##field##__BITNR ) & (val)) >> reg##__##field##__BITNR )
+
+/* IO_STATE_VALUE returns a constant corresponding to a one of the symbolic
+   states that the bitfield can have. (Not shifted)  */
+#define IO_STATE_VALUE(reg,field,state) ( reg##__##field##__##state )
+
+/* IO_FIELD shifts the val parameter to be aligned with the bitfield
+   specified. */
+#define IO_FIELD(reg,field,val) ((val) << reg##__##field##__BITNR)
+
+/* IO_BITNR returns the starting bitnumber of a bitfield. Bit 0 is
+   LSB and the returned bitnumber is LSB of the field. */
+#define IO_BITNR(reg,field) (reg##__##field##__BITNR)
+
+/* IO_WIDTH returns the width, in bits, of a bitfield. */
+#define IO_WIDTH(reg,field) (reg##__##field##__WIDTH)
+
+/*--- Obsolete. Kept for backw compatibility. ---*/
+/* Reads (or writes) a byte/uword/udword from the specified mode
+   register. */
+#define IO_RD(reg) (*(volatile u32*)(reg))
+#define IO_RD_B(reg) (*(volatile u8*)(reg))
+#define IO_RD_W(reg) (*(volatile u16*)(reg))
+#define IO_RD_D(reg) (*(volatile u32*)(reg))
+
+/*------------------------------------------------------------
+!* Start addresses of the different memory areas.
+!*-----------------------------------------------------------*/
+
+#define MEM_CSE0_START (0x00000000)
+#define MEM_CSE1_START (0x04000000)
+#define MEM_CSR0_START (0x08000000)
+#define MEM_CSR1_START (0x0c000000)
+#define MEM_CSP0_START (0x10000000)
+#define MEM_CSP1_START (0x14000000)
+#define MEM_CSP2_START (0x18000000)
+#define MEM_CSP3_START (0x1c000000)
+#define MEM_CSP4_START (0x20000000)
+#define MEM_CSP5_START (0x24000000)
+#define MEM_CSP6_START (0x28000000)
+#define MEM_CSP7_START (0x2c000000)
+#define MEM_DRAM_START (0x40000000)
+
+#define MEM_NON_CACHEABLE (0x80000000)
+
+/*------------------------------------------------------------
+!* Type casts used in mode register macros, making pointer
+!* dereferencing possible. Empty in assembler.
+!*-----------------------------------------------------------*/
+
+#ifndef __ASSEMBLER__
+# define  IO_TYPECAST_UDWORD  (volatile u32*)
+# define  IO_TYPECAST_RO_UDWORD  (const volatile u32*)
+# define  IO_TYPECAST_UWORD  (volatile u16*)
+# define  IO_TYPECAST_RO_UWORD  (const volatile u16*)
+# define  IO_TYPECAST_BYTE  (volatile u8*)
+# define  IO_TYPECAST_RO_BYTE  (const volatile u8*)
+#else
+# define  IO_TYPECAST_UDWORD
+# define  IO_TYPECAST_RO_UDWORD
+# define  IO_TYPECAST_UWORD
+# define  IO_TYPECAST_RO_UWORD
+# define  IO_TYPECAST_BYTE
+# define  IO_TYPECAST_RO_BYTE
+#endif
+
+/*------------------------------------------------------------*/
+
+#include "sv_addr.agh"
+
+#if __test_sv_addr__
+/* IO_MASK( R_BUS_CONFIG , CE ) */
+IO_MASK( R_WAITSTATES , SRAM_WS )
+IO_MASK( R_TEST , W32 )
+
+IO_STATE( R_BUS_CONFIG, CE, DISABLE )
+IO_STATE( R_BUS_CONFIG, CE, ENABLE )
+
+IO_STATE( R_DRAM_TIMING, REF, IVAL2 )
+
+IO_MASK( R_DRAM_TIMING, REF )
+
+IO_MASK( R_EXT_DMA_0_STAT, TFR_COUNT ) >> IO_BITNR( R_EXT_DMA_0_STAT, TFR_COUNT )
+
+IO_RD(R_EXT_DMA_0_STAT) & IO_MASK( R_EXT_DMA_0_STAT, S ) 
+   == IO_STATE( R_EXT_DMA_0_STAT, S, STARTED )
+#endif
+
+
+#endif  /* ifndef __sv_addr_ag_h__ */
+
diff -urN linux-2.4.2-pre1/include/asm-cris/svinto.h linux/include/asm-cris/svinto.h
--- linux-2.4.2-pre1/include/asm-cris/svinto.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/svinto.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,46 @@
+#ifndef _ASM_CRIS_SVINTO_H
+#define _ASM_CRIS_SVINTO_H
+
+#include "sv_addr_ag.h"
+
+extern unsigned int genconfig_shadow; /* defined and set in head.S */
+
+/* dma stuff */
+
+enum {                          /* Available in:  */
+	d_eol      = (1 << 0),  /* flags          */
+	d_eop      = (1 << 1),  /* flags & status */
+	d_wait     = (1 << 2),  /* flags          */
+	d_int      = (1 << 3),  /* flags          */
+	d_txerr    = (1 << 4),  /* flags          */
+	d_stop     = (1 << 4),  /*         status */
+	d_ecp      = (1 << 4),  /* flags & status */
+	d_pri      = (1 << 5),  /* flags & status */
+	d_alignerr = (1 << 6),  /*         status */
+	d_crcerr   = (1 << 7)   /*         status */
+};
+
+/* Do remember that DMA does not go through the MMU and needs
+ * a real physical address, not an address virtually mapped or
+ * paged. Therefore the buf/next ptrs below are unsigned long instead
+ * of void * to give a warning if you try to put a pointer directly
+ * to them instead of going through virt_to_phys/phys_to_virt.
+ */
+
+typedef struct etrax_dma_descr {
+	unsigned short sw_len;                /* 0-1 */
+	unsigned short ctrl;                  /* 2-3 */
+	unsigned long  next;                  /* 4-7 */
+	unsigned long  buf;                   /* 8-11 */
+	unsigned short hw_len;                /* 12-13 */
+	unsigned short status;                /* 14-15 */
+} etrax_dma_descr;
+
+#define RESET_DMA( n ) \
+  *R_DMA_CH##n##_CMD = IO_STATE( R_DMA_CH0_CMD, cmd, reset )
+
+#define WAIT_DMA( n ) \
+  while( (*R_DMA_CH##n##_CMD & IO_MASK( R_DMA_CH0_CMD, cmd )) != \
+         IO_STATE( R_DMA_CH0_CMD, cmd, hold ) )
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/system.h linux/include/asm-cris/system.h
--- linux-2.4.2-pre1/include/asm-cris/system.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/system.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,170 @@
+/* $Id: system.h,v 1.3 2000/10/17 14:56:27 bjornw Exp $ */
+
+#ifndef __ASM_CRIS_SYSTEM_H
+#define __ASM_CRIS_SYSTEM_H
+
+#include <asm/segment.h>
+
+/* I need a task-specific debug struct (and the define for #ifdef
+   RELOC_DEBUG) to kludge into task_struct. */
+#include <linux/config.h>
+#include <asm/eshlibld.h>
+
+/* the switch_to macro calls resume, an asm function in entry.S which does the actual
+ * task switching.
+ */
+
+extern struct task_struct *resume(struct task_struct *prev, struct task_struct *next, int);
+#define prepare_to_switch()     do { } while(0)
+#define switch_to(prev,next,last) last = resume(prev,next, \
+					 (int)&((struct task_struct *)0)->thread)
+
+/* read/write the user-mode stackpointer */
+
+extern inline unsigned long rdusp(void) {
+	unsigned long usp;
+	__asm__ __volatile__("move usp,%0" : "=rm" (usp));
+	return usp;
+}
+
+#define wrusp(usp) \
+	__asm__ __volatile__("move %0,usp" : /* no outputs */ : "rm" (usp))
+
+/* read the current stackpointer */
+
+extern inline unsigned long rdsp(void) {
+	unsigned long sp;
+	__asm__ __volatile__("move.d sp,%0" : "=rm" (sp));
+	return sp;
+}
+
+static inline unsigned long _get_base(char * addr)
+{
+  return 0;
+}
+
+#define nop() __asm__ __volatile__ ("nop");
+
+#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+#define tas(ptr) (xchg((ptr),1))
+
+struct __xchg_dummy { unsigned long a[100]; };
+#define __xg(x) ((struct __xchg_dummy *)(x))
+
+#if 0
+/* use these and an oscilloscope to see the fraction of time we're running with IRQ's disabled */
+/* it assumes the LED's are on port 0x90000000 of course. */
+#define sti() __asm__ __volatile__ ( "ei\n\tpush r0\n\tmoveq 0,r0\n\tmove.d r0,[0x90000000]\n\tpop r0" );
+#define cli() __asm__ __volatile__ ( "di\n\tpush r0\n\tmove.d 0x40000,r0\n\tmove.d r0,[0x90000000]\n\tpop r0");
+#define save_flags(x) __asm__ __volatile__ ("move ccr,%0" : "=rm" (x) : : "memory");
+#define restore_flags(x) __asm__ __volatile__ ("move %0,ccr\n\tbtstq 5,%0\n\tbpl 1f\n\tnop\n\tpush r0\n\tmoveq 0,r0\n\tmove.d r0,[0x90000000]\n\tpop r0\n1:\n" : : "r" (x) : "memory");
+#else
+#define __cli() __asm__ __volatile__ ( "di");
+#define __sti() __asm__ __volatile__ ( "ei" );
+#define __save_flags(x) __asm__ __volatile__ ("move ccr,%0" : "=rm" (x) : : "memory");
+#define __restore_flags(x) __asm__ __volatile__ ("move %0,ccr" : : "rm" (x) : "memory");
+
+/* For spinlocks etc */
+#define local_irq_save(x) __asm__ __volatile__ ("move ccr,%0\n\tdi" : "=rm" (x) : : "memory"); 
+#define local_irq_restore(x) restore_flags(x)
+
+#define local_irq_disable()  cli()
+#define local_irq_enable()   sti()
+
+#endif
+
+#define cli() __cli()
+#define sti() __sti()
+#define save_flags(x) __save_flags(x)
+#define restore_flags(x) __restore_flags(x)
+#define save_and_cli(x) do { __save_flags(x); cli(); } while(0)
+
+static inline unsigned long __xchg(unsigned long x, void * ptr, int size)
+{
+  /* since Etrax doesn't have any atomic xchg instructions, we need to disable
+     irq's (if enabled) and do it with move.d's */
+#if 0
+  unsigned int flags;
+  save_flags(flags); /* save flags, including irq enable bit */
+  cli();             /* shut off irq's */
+  switch (size) {
+  case 1:
+    __asm__ __volatile__ (
+       "move.b %0,r0\n\t"
+       "move.b %1,%0\n\t"
+       "move.b r0,%1\n\t"
+       : "=r" (x)
+       : "m" (*__xg(ptr)), "r" (x)
+       : "memory","r0");    
+    break;
+  case 2:
+    __asm__ __volatile__ (
+       "move.w %0,r0\n\t"
+       "move.w %1,%0\n\t"
+       "move.w r0,%1\n\t"
+       : "=r" (x)
+       : "m" (*__xg(ptr)), "r" (x)
+       : "memory","r0");
+    break;
+  case 4:
+    __asm__ __volatile__ (
+       "move.d %0,r0\n\t"
+       "move.d %1,%0\n\t"
+       "move.d r0,%1\n\t"
+       : "=r" (x)
+       : "m" (*__xg(ptr)), "r" (x)
+       : "memory","r0");
+    break;
+  }
+  restore_flags(flags); /* restore irq enable bit */
+  return x;
+#else
+  unsigned long flags,temp;
+  save_flags(flags); /* save flags, including irq enable bit */
+  cli();             /* shut off irq's */
+  switch (size) {
+  case 1:
+    *((unsigned char *)&temp) = x;
+    x = *(unsigned char *)ptr;
+    *(unsigned char *)ptr = *((unsigned char *)&temp);
+    break;
+  case 2:
+    *((unsigned short *)&temp) = x;
+    x = *(unsigned short *)ptr;
+    *(unsigned short *)ptr = *((unsigned short *)&temp);
+    break;
+  case 4:
+    temp = x;
+    x = *(unsigned long *)ptr;
+    *(unsigned long *)ptr = temp;
+    break;
+  }
+  restore_flags(flags); /* restore irq enable bit */
+  return x;
+#endif
+}
+
+#define mb() __asm__ __volatile__ ("" : : : "memory")
+#define rmb() mb()
+#define wmb() mb()
+
+#ifdef CONFIG_SMP
+#define smp_mb()        mb()
+#define smp_rmb()       rmb()
+#define smp_wmb()       wmb()
+#else
+#define smp_mb()        barrier()
+#define smp_rmb()       barrier()
+#define smp_wmb()       barrier()
+#endif
+
+#define iret()
+
+/*
+ * disable hlt during certain critical i/o operations
+ */
+#define HAVE_DISABLE_HLT
+void disable_hlt(void);
+void enable_hlt(void);
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/termbits.h linux/include/asm-cris/termbits.h
--- linux-2.4.2-pre1/include/asm-cris/termbits.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/termbits.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,166 @@
+/* $Id: termbits.h,v 1.1 2000/07/10 16:32:31 bjornw Exp $ */
+
+#ifndef __ARCH_ETRAX100_TERMBITS_H__
+#define __ARCH_ETRAX100_TERMBITS_H__
+
+#include <linux/posix_types.h>
+
+typedef unsigned char	cc_t;
+typedef unsigned int	speed_t;
+typedef unsigned int	tcflag_t;
+
+#define NCCS 19
+struct termios {
+	tcflag_t c_iflag;		/* input mode flags */
+	tcflag_t c_oflag;		/* output mode flags */
+	tcflag_t c_cflag;		/* control mode flags */
+	tcflag_t c_lflag;		/* local mode flags */
+	cc_t c_line;			/* line discipline */
+	cc_t c_cc[NCCS];		/* control characters */
+};
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+/* c_iflag bits */
+#define IGNBRK	0000001
+#define BRKINT	0000002
+#define IGNPAR	0000004
+#define PARMRK	0000010
+#define INPCK	0000020
+#define ISTRIP	0000040
+#define INLCR	0000100
+#define IGNCR	0000200
+#define ICRNL	0000400
+#define IUCLC	0001000
+#define IXON	0002000
+#define IXANY	0004000
+#define IXOFF	0010000
+#define IMAXBEL	0020000
+
+/* c_oflag bits */
+#define OPOST	0000001
+#define OLCUC	0000002
+#define ONLCR	0000004
+#define OCRNL	0000010
+#define ONOCR	0000020
+#define ONLRET	0000040
+#define OFILL	0000100
+#define OFDEL	0000200
+#define NLDLY	0000400
+#define   NL0	0000000
+#define   NL1	0000400
+#define CRDLY	0003000
+#define   CR0	0000000
+#define   CR1	0001000
+#define   CR2	0002000
+#define   CR3	0003000
+#define TABDLY	0014000
+#define   TAB0	0000000
+#define   TAB1	0004000
+#define   TAB2	0010000
+#define   TAB3	0014000
+#define   XTABS	0014000
+#define BSDLY	0020000
+#define   BS0	0000000
+#define   BS1	0020000
+#define VTDLY	0040000
+#define   VT0	0000000
+#define   VT1	0040000
+#define FFDLY	0100000
+#define   FF0	0000000
+#define   FF1	0100000
+
+/* c_cflag bit meaning */
+#define CBAUD	0010017
+#define  B0	0000000		/* hang up */
+#define  B50	0000001
+#define  B75	0000002
+#define  B110	0000003
+#define  B134	0000004
+#define  B150	0000005
+#define  B200	0000006
+#define  B300	0000007
+#define  B600	0000010
+#define  B1200	0000011
+#define  B1800	0000012
+#define  B2400	0000013
+#define  B4800	0000014
+#define  B9600	0000015
+#define  B19200	0000016
+#define  B38400	0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE	0000060
+#define   CS5	0000000
+#define   CS6	0000020
+#define   CS7	0000040
+#define   CS8	0000060
+#define CSTOPB	0000100
+#define CREAD	0000200
+#define PARENB	0000400
+#define PARODD	0001000
+#define HUPCL	0002000
+#define CLOCAL	0004000
+#define CBAUDEX 0010000
+#define  B57600  0010001
+#define  B115200 0010002
+#define  B230400 0010003
+#define  B460800 0010004
+/* etrax100 supports these additional three baud rates */
+#define  B921600 0010005
+#define  B1843200 0010006
+#define  B6250000 0010007
+#define CIBAUD	  002003600000	/* input baud rate (not used) */
+#define CRTSCTS	  020000000000		/* flow control */
+
+/* c_lflag bits */
+#define ISIG	0000001
+#define ICANON	0000002
+#define XCASE	0000004
+#define ECHO	0000010
+#define ECHOE	0000020
+#define ECHOK	0000040
+#define ECHONL	0000100
+#define NOFLSH	0000200
+#define TOSTOP	0000400
+#define ECHOCTL	0001000
+#define ECHOPRT	0002000
+#define ECHOKE	0004000
+#define FLUSHO	0010000
+#define PENDIN	0040000
+#define IEXTEN	0100000
+
+/* tcflow() and TCXONC use these */
+#define	TCOOFF		0
+#define	TCOON		1
+#define	TCIOFF		2
+#define	TCION		3
+
+/* tcflush() and TCFLSH use these */
+#define	TCIFLUSH	0
+#define	TCOFLUSH	1
+#define	TCIOFLUSH	2
+
+/* tcsetattr uses these */
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/termios.h linux/include/asm-cris/termios.h
--- linux-2.4.2-pre1/include/asm-cris/termios.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/termios.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,106 @@
+#ifndef _CRIS_TERMIOS_H
+#define _CRIS_TERMIOS_H
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+	unsigned short c_iflag;		/* input mode flags */
+	unsigned short c_oflag;		/* output mode flags */
+	unsigned short c_cflag;		/* control mode flags */
+	unsigned short c_lflag;		/* local mode flags */
+	unsigned char c_line;		/* line discipline */
+	unsigned char c_cc[NCC];	/* control characters */
+};
+
+/* modem lines */
+#define TIOCM_LE	0x001
+#define TIOCM_DTR	0x002
+#define TIOCM_RTS	0x004
+#define TIOCM_ST	0x008
+#define TIOCM_SR	0x010
+#define TIOCM_CTS	0x020
+#define TIOCM_CAR	0x040
+#define TIOCM_RNG	0x080
+#define TIOCM_DSR	0x100
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RI	TIOCM_RNG
+#define TIOCM_OUT1	0x2000
+#define TIOCM_OUT2	0x4000
+#define TIOCM_LOOP	0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+/* line disciplines */
+#define N_TTY		0
+#define N_SLIP		1
+#define N_MOUSE		2
+#define N_PPP		3
+#define N_STRIP		4
+#define N_AX25		5
+#define N_X25		6	/* X.25 async */
+#define N_6PACK		7
+#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
+#define N_R3964		9	/* Reserved for Simatic R3964 module */
+#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
+#define N_IRDA		11	/* Linux IR - http://www.cs.uit.no/~dagb/irda/irda.html */
+#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
+#define N_HDLC		13	/* synchronous HDLC */
+#define N_SYNC_PPP	14	/* synchronous PPP */
+#define N_BT		15	/* bluetooth */
+
+#ifdef __KERNEL__
+
+/*	intr=^C		quit=^\		erase=del	kill=^U
+	eof=^D		vtime=\0	vmin=\1		sxtc=\0
+	start=^Q	stop=^S		susp=^Z		eol=\0
+	reprint=^R	discard=^U	werase=^W	lnext=^V
+	eol2=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
+	unsigned short __tmp; \
+	get_user(__tmp,&(termio)->x); \
+	*(unsigned short *) &(termios)->x = __tmp; \
+}
+
+#define user_termio_to_kernel_termios(termios, termio) \
+({ \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
+	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+})
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ */
+#define kernel_termios_to_user_termio(termio, termios) \
+({ \
+	put_user((termios)->c_iflag, &(termio)->c_iflag); \
+	put_user((termios)->c_oflag, &(termio)->c_oflag); \
+	put_user((termios)->c_cflag, &(termio)->c_cflag); \
+	put_user((termios)->c_lflag, &(termio)->c_lflag); \
+	put_user((termios)->c_line,  &(termio)->c_line); \
+	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+})
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
+
+#endif	/* __KERNEL__ */
+
+#endif	/* _CRIS_TERMIOS_H */
diff -urN linux-2.4.2-pre1/include/asm-cris/timex.h linux/include/asm-cris/timex.h
--- linux-2.4.2-pre1/include/asm-cris/timex.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/timex.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,23 @@
+/*
+ * linux/include/asm-cris/timex.h
+ *
+ * CRIS architecture timex specifications
+ */
+#ifndef _ASM_CRIS_TIMEX_H
+#define _ASM_CRIS_TIMEX_H
+
+#define CLOCK_TICK_RATE 9600 /* Underlying frequency of the HZ timer */
+
+/*
+ * We don't have a cycle-counter.. but we do not support SMP anyway where this is
+ * used so it does not matter.
+ */
+
+typedef unsigned int cycles_t;
+
+static inline cycles_t get_cycles(void)
+{
+        return 0;
+}
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/types.h linux/include/asm-cris/types.h
--- linux-2.4.2-pre1/include/asm-cris/types.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/types.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,50 @@
+#ifndef _ETRAX_TYPES_H
+#define _ETRAX_TYPES_H
+
+typedef unsigned short umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+#define BITS_PER_LONG 32
+
+/* Dma addresses are 32-bits wide, just like our other addresses.  */
+ 
+typedef u32 dma_addr_t;
+
+#endif /* __KERNEL__ */
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/uaccess.h linux/include/asm-cris/uaccess.h
--- linux-2.4.2-pre1/include/asm-cris/uaccess.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/uaccess.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,1075 @@
+/* 
+ * Authors:    Bjorn Wesen (bjornw@axis.com)
+ *	       Hans-Peter Nilsson (hp@axis.com)
+ *
+ * $Log: uaccess.h,v $
+ * Revision 1.5  2000/10/25 03:33:21  hp
+ * - Provide implementation for everything else but get_user and put_user;
+ *   copying inline to/from user for constant length 0..16, 20, 24, and
+ *   clearing for 0..4, 8, 12, 16, 20, 24, strncpy_from_user and strnlen_user
+ *   always inline.
+ * - Constraints for destination addr in get_user cannot be memory, only reg.
+ * - Correct labels for PC at expected fault points.
+ * - Nits with assembly code.
+ * - Don't use statement expressions without value; use "do {} while (0)".
+ * - Return correct values from __generic_... functions.
+ *
+ * Revision 1.4  2000/09/12 16:28:25  bjornw
+ * * Removed comments from the get/put user asm code
+ * * Constrains for destination addr in put_user cannot be memory, only reg
+ *
+ * Revision 1.3  2000/09/12 14:30:20  bjornw
+ * MAX_ADDR_USER does not exist anymore
+ *
+ * Revision 1.2  2000/07/13 15:52:48  bjornw
+ * New user-access functions
+ *
+ * Revision 1.1.1.1  2000/07/10 16:32:31  bjornw
+ * CRIS architecture, working draft
+ *
+ *
+ *
+ */
+
+/* Asm:s have been tweaked (within the domain of correctness) to give
+   satisfactory results for "gcc version 2.96 20000427 (experimental)".
+
+   Check regularly...
+
+   Register r9 is chosen for temporaries, being a call-clobbered register
+   first in line to be used (notably for local blocks), not colliding with
+   parameter registers.  */
+
+#ifndef _CRIS_UACCESS_H
+#define _CRIS_UACCESS_H
+
+#ifndef __ASSEMBLY__
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+
+#define VERIFY_READ	0
+#define VERIFY_WRITE	1
+
+/*
+ * The fs value determines whether argument validity checking should be
+ * performed or not.  If get_fs() == USER_DS, checking is performed, with
+ * get_fs() == KERNEL_DS, checking is bypassed.
+ *
+ * For historical reasons, these macros are grossly misnamed.
+ */
+
+#define MAKE_MM_SEG(s)	((mm_segment_t) { (s) })
+
+/* addr_limit is the maximum accessible address for the task. we misuse
+ * the KERNEL_DS and USER_DS values to both assign and compare the 
+ * addr_limit values through the equally misnamed get/set_fs macros.
+ * (see above)
+ */
+
+#define KERNEL_DS	MAKE_MM_SEG(0xFFFFFFFF)
+#define USER_DS		MAKE_MM_SEG(TASK_SIZE)
+
+#define get_ds()	(KERNEL_DS)
+#define get_fs()	(current->addr_limit)
+#define set_fs(x)	(current->addr_limit = (x))
+
+#define segment_eq(a,b)	((a).seg == (b).seg)
+
+#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
+#define __user_ok(addr,size) (((size) <= TASK_SIZE)&&((addr) <= TASK_SIZE-(size)))
+#define __access_ok(addr,size) (__kernel_ok || __user_ok((addr),(size)))
+#define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
+
+extern inline int verify_area(int type, const void * addr, unsigned long size)
+{
+	return access_ok(type,addr,size) ? 0 : -EFAULT;
+}
+
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry
+{
+	unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long);
+
+
+/*
+ * These are the main single-value transfer routines.  They automatically
+ * use the right size if we just have the right pointer type.
+ *
+ * This gets kind of ugly. We want to return _two_ values in "get_user()"
+ * and yet we don't want to do any pointers, because that is too much
+ * of a performance impact. Thus we have a few rather ugly macros here,
+ * and hide all the uglyness from the user.
+ *
+ * The "__xxx" versions of the user access functions are versions that
+ * do not verify the address space, that must have been done previously
+ * with a separate "access_ok()" call (this is used when we do multiple
+ * accesses to the same area of user memory).
+ *
+ * As we use the same address space for kernel and user data on
+ * CRIS, we can just do these as direct assignments.  (Of course, the
+ * exception handling means that it's no longer "just"...)
+ */
+#define get_user(x,ptr) \
+  __get_user_check((x),(ptr),sizeof(*(ptr)))
+#define put_user(x,ptr) \
+  __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+
+#define __get_user(x,ptr) \
+  __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
+#define __put_user(x,ptr) \
+  __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+
+/*
+ * The "xxx_ret" versions return constant specified in third argument, if
+ * something bad happens. These macros can be optimized for the
+ * case of just returning from the function xxx_ret is used.
+ */
+
+#define put_user_ret(x,ptr,ret) \
+	do { if (put_user(x,ptr)) return ret; } while (0)
+
+#define get_user_ret(x,ptr,ret) \
+	do { if (get_user(x,ptr)) return ret; } while (0)
+
+#define __put_user_ret(x,ptr,ret) \
+	do { if (__put_user(x,ptr)) return ret; } while (0)
+
+#define __get_user_ret(x,ptr,ret) \
+	do { if (__get_user(x,ptr)) return ret; } while (0)
+
+
+extern long __put_user_bad(void);
+
+#define __put_user_nocheck(x,ptr,size)			\
+({							\
+	long __pu_err;					\
+	__put_user_size((x),(ptr),(size),__pu_err);	\
+	__pu_err;					\
+})
+
+#define __put_user_check(x,ptr,size)				\
+({								\
+	long __pu_err = -EFAULT;				\
+	__typeof__(*(ptr)) *__pu_addr = (ptr);			\
+	if (access_ok(VERIFY_WRITE,__pu_addr,size))		\
+		__put_user_size((x),__pu_addr,(size),__pu_err);	\
+	__pu_err;						\
+})
+
+#define __put_user_size(x,ptr,size,retval)			\
+do {								\
+	retval = 0;						\
+	switch (size) {						\
+	  case 1: __put_user_asm(x,ptr,retval,"move.b"); break;	\
+	  case 2: __put_user_asm(x,ptr,retval,"move.w"); break;	\
+	  case 4: __put_user_asm(x,ptr,retval,"move.d"); break;	\
+	  default: __put_user_bad();				\
+	}							\
+} while (0)
+
+struct __large_struct { unsigned long buf[100]; };
+#define __m(x) (*(struct __large_struct *)(x))
+
+/*
+ * We don't tell gcc that we are accessing memory, but this is OK
+ * because we do not write to any memory gcc knows about, so there
+ * are no aliasing issues.
+ *
+ * Note that PC at a fault is the address *after* the faulting
+ * instruction.
+ */
+#define __put_user_asm(x, addr, err, op)			\
+	__asm__ __volatile__(					\
+		"	"op" %1,[%2]\n"				\
+		"2:\n"						\
+		"	.section .fixup,\"ax\"\n"		\
+		"3:	move.d %3,%0\n"				\
+		"	jump 2b\n"				\
+		"	.previous\n"				\
+		"	.section __ex_table,\"a\"\n"		\
+		"	.dword 2b,3b\n"				\
+		"	.previous\n"				\
+		: "=r" (err)					\
+		: "r" (x), "r" (addr), "g" (-EFAULT), "0" (err))
+
+
+#define __get_user_nocheck(x,ptr,size)				\
+({								\
+	long __gu_err, __gu_val;				\
+	__get_user_size(__gu_val,(ptr),(size),__gu_err);	\
+	(x) = (__typeof__(*(ptr)))__gu_val;			\
+	__gu_err;						\
+})
+
+#define __get_user_check(x,ptr,size)					\
+({									\
+	long __gu_err = -EFAULT, __gu_val = 0;				\
+	const __typeof__(*(ptr)) *__gu_addr = (ptr);			\
+	if (access_ok(VERIFY_READ,__gu_addr,size))			\
+		__get_user_size(__gu_val,__gu_addr,(size),__gu_err);	\
+	(x) = (__typeof__(*(ptr)))__gu_val;				\
+	__gu_err;							\
+})
+
+extern long __get_user_bad(void);
+
+#define __get_user_size(x,ptr,size,retval)			\
+do {								\
+	retval = 0;						\
+	switch (size) {						\
+	  case 1: __get_user_asm(x,ptr,retval,"move.b"); break;	\
+	  case 2: __get_user_asm(x,ptr,retval,"move.w"); break;	\
+	  case 4: __get_user_asm(x,ptr,retval,"move.d"); break;	\
+	  default: (x) = __get_user_bad();			\
+	}							\
+} while (0)
+
+/* See comment before __put_user_asm.  */
+
+#define __get_user_asm(x, addr, err, op)		\
+	__asm__ __volatile__(				\
+		"	"op" [%2],%1\n"			\
+		"2:\n"					\
+		"	.section .fixup,\"ax\"\n"	\
+		"3:	move.d %3,%0\n"			\
+		"	moveq 0,%1\n"			\
+		"	jump 2b\n"			\
+		"	.previous\n"			\
+		"	.section __ex_table,\"a\"\n"	\
+		"	.dword 2b,3b\n"			\
+		"	.previous\n"			\
+		: "=r" (err), "=r" (x)			\
+		: "r" (addr), "g" (-EFAULT), "0" (err))
+
+/* More complex functions.  Most are inline, but some call functions that
+   live in lib/usercopy.c  */
+
+extern unsigned long __copy_user(void *to, const void *from, unsigned long n);
+extern unsigned long __copy_user_zeroing(void *to, const void *from, unsigned long n);
+extern unsigned long __do_clear_user(void *to, unsigned long n);
+
+/*
+ * Copy a null terminated string from userspace.
+ *
+ * Must return:
+ * -EFAULT		for an exception
+ * count		if we hit the buffer limit
+ * bytes copied		if we hit a null byte
+ * (without the null byte)
+ */
+
+static inline long         
+__do_strncpy_from_user(char *dst, const char *src, long count)
+{
+	long res;
+
+	if (count == 0)
+		return 0;
+
+	/*
+	 * Currently, in 2.4.0-test9, most ports use a simple byte-copy loop.
+	 *  So do we.
+	 *
+	 *  This code is deduced from:
+	 *
+	 *	char tmp2;
+	 *	long tmp1, tmp3	
+	 *	tmp1 = count;
+	 *	while ((*dst++ = (tmp2 = *src++)) != 0
+	 *	       && --tmp1)
+	 *	  ;
+	 *
+	 *	res = count - tmp1;
+	 *
+	 *  with tweaks.
+	 */
+
+	__asm__ __volatile__ (
+		"	move.d %3,%0\n"
+		"	move.b [%2+],r9\n"
+		"1:	beq 2f\n"
+		"	move.b r9,[%1+]\n"
+
+		"	subq 1,%0\n"
+		"	bne 1b\n"
+		"	move.b [%2+],r9\n"
+
+		"2:	sub.d %3,%0\n"
+		"	neg.d %0,%0\n"
+		"3:\n"
+		"	.section .fixup,\"ax\"\n"
+		"4:	move.d %7,%0\n"
+		"	jump 3b\n"
+
+		/* There's one address for a fault at the first move, and
+		   two possible PC values for a fault at the second move,
+		   being a delay-slot filler.  However, the branch-target
+		   for the second move is the same as the first address.
+		   Just so you don't get confused...  */
+		"	.previous\n"
+		"	.section __ex_table,\"a\"\n"
+		"	.dword 1b,4b\n"
+		"	.dword 2b,4b\n"
+		"	.previous"
+		: "=r" (res), "=r" (dst), "=r" (src), "=r" (count)
+		: "3" (count), "1" (dst), "2" (src), "g" (-EFAULT)
+		: "r9");
+
+	return res;
+}
+
+static inline unsigned long
+__generic_copy_to_user(void *to, const void *from, unsigned long n)
+{
+	if (access_ok(VERIFY_WRITE, to, n))
+		return __copy_user(to,from,n);
+	return n;
+}
+
+static inline unsigned long
+__generic_copy_from_user(void *to, const void *from, unsigned long n)
+{
+	if (access_ok(VERIFY_READ, from, n))
+		return __copy_user_zeroing(to,from,n);
+	return n;
+}
+
+static inline unsigned long
+__generic_clear_user(void *to, unsigned long n)
+{
+	if (access_ok(VERIFY_WRITE, to, n))
+		return __do_clear_user(to,n);
+	return n;
+}
+
+static inline long
+__strncpy_from_user(char *dst, const char *src, long count)
+{
+	return __do_strncpy_from_user(dst, src, count);
+}
+
+static inline long
+strncpy_from_user(char *dst, const char *src, long count)
+{
+	long res = -EFAULT;
+	if (access_ok(VERIFY_READ, src, 1))
+		res = __do_strncpy_from_user(dst, src, count);
+	return res;
+}
+
+/* A few copy asms to build up the more complex ones from.
+
+   Note again, a post-increment is performed regardless of whether a bus
+   fault occurred in that instruction, and PC for a faulted insn is the
+   address *after* the insn.  */
+
+#define __asm_copy_user_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm__ __volatile__ (				\
+			COPY				\
+		"1:\n"					\
+		"	.section .fixup,\"ax\"\n"	\
+			FIXUP				\
+		"	jump 1b\n"			\
+		"	.previous\n"			\
+		"	.section __ex_table,\"a\"\n"	\
+			TENTRY				\
+		"	.previous\n"			\
+		: "=r" (to), "=r" (from), "=r" (ret)	\
+		: "0" (to), "1" (from), "2" (ret)	\
+		: "r9", "memory")
+
+#define __asm_copy_from_user_1(to, from, ret) \
+	__asm_copy_user_cont(to, from, ret,	\
+		"	move.b [%1+],r9\n"	\
+		"2:	move.b r9,[%0+]\n",	\
+		"3:	addq 1,%2\n"		\
+		"	clear.b [%0+]\n",	\
+		"	.dword 2b,3b\n")
+
+#define __asm_copy_from_user_2x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_user_cont(to, from, ret,		\
+		"	move.w [%1+],r9\n"		\
+		"2:	move.w r9,[%0+]\n" COPY,	\
+		"3:	addq 2,%2\n"			\
+		"	clear.w [%0+]\n" FIXUP,		\
+		"	.dword 2b,3b\n" TENTRY)
+
+#define __asm_copy_from_user_2(to, from, ret) \
+	__asm_copy_from_user_2x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_from_user_3(to, from, ret)		\
+	__asm_copy_from_user_2x_cont(to, from, ret,	\
+		"	move.b [%1+],r9\n"		\
+		"4:	move.b r9,[%0+]\n",		\
+		"5:	addq 1,%2\n"			\
+		"	clear.b [%0+]\n",		\
+		"	.dword 4b,5b\n")
+
+#define __asm_copy_from_user_4x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_user_cont(to, from, ret,		\
+		"	move.d [%1+],r9\n"		\
+		"2:	move.d r9,[%0+]\n" COPY,	\
+		"3:	addq 4,%2\n"			\
+		"	clear.d [%0+]\n" FIXUP,		\
+		"	.dword 2b,3b\n" TENTRY)
+
+#define __asm_copy_from_user_4(to, from, ret) \
+	__asm_copy_from_user_4x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_from_user_5(to, from, ret) \
+	__asm_copy_from_user_4x_cont(to, from, ret,	\
+		"	move.b [%1+],r9\n"		\
+		"4:	move.b r9,[%0+]\n",		\
+		"5:	addq 1,%2\n"			\
+		"	clear.b [%0+]\n",		\
+		"	.dword 4b,5b\n")
+
+#define __asm_copy_from_user_6x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_from_user_4x_cont(to, from, ret,	\
+		"	move.w [%1+],r9\n"		\
+		"4:	move.w r9,[%0+]\n" COPY,	\
+		"5:	addq 2,%2\n"			\
+		"	clear.w [%0+]\n" FIXUP,		\
+		"	.dword 4b,5b\n" TENTRY)
+
+#define __asm_copy_from_user_6(to, from, ret) \
+	__asm_copy_from_user_6x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_from_user_7(to, from, ret) \
+	__asm_copy_from_user_6x_cont(to, from, ret,	\
+		"	move.b [%1+],r9\n"		\
+		"6:	move.b r9,[%0+]\n",		\
+		"7:	addq 1,%2\n"			\
+		"	clear.b [%0+]\n",		\
+		"	.dword 6b,7b\n")
+
+#define __asm_copy_from_user_8x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_from_user_4x_cont(to, from, ret,	\
+		"	move.d [%1+],r9\n"		\
+		"4:	move.d r9,[%0+]\n" COPY,	\
+		"5:	addq 4,%2\n"			\
+		"	clear.d [%0+]\n" FIXUP,		\
+		"	.dword 4b,5b\n" TENTRY)
+
+#define __asm_copy_from_user_8(to, from, ret) \
+	__asm_copy_from_user_8x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_from_user_9(to, from, ret) \
+	__asm_copy_from_user_8x_cont(to, from, ret,	\
+		"	move.b [%1+],r9\n"		\
+		"6:	move.b r9,[%0+]\n",		\
+		"7:	addq 1,%2\n"			\
+		"	clear.b [%0+]\n",		\
+		"	.dword 6b,7b\n")
+
+#define __asm_copy_from_user_10x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_from_user_8x_cont(to, from, ret,	\
+		"	move.w [%1+],r9\n"		\
+		"6:	move.w r9,[%0+]\n" COPY,	\
+		"7:	addq 2,%2\n"			\
+		"	clear.w [%0+]\n" FIXUP,		\
+		"	.dword 6b,7b\n" TENTRY)
+
+#define __asm_copy_from_user_10(to, from, ret) \
+	__asm_copy_from_user_10x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_from_user_11(to, from, ret)		\
+	__asm_copy_from_user_10x_cont(to, from, ret,	\
+		"	move.b [%1+],r9\n"		\
+		"8:	move.b r9,[%0+]\n",		\
+		"9:	addq 1,%2\n"			\
+		"	clear.b [%0+]\n",		\
+		"	.dword 8b,9b\n")
+
+#define __asm_copy_from_user_12x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_from_user_8x_cont(to, from, ret,	\
+		"	move.d [%1+],r9\n"		\
+		"6:	move.d r9,[%0+]\n" COPY,	\
+		"7:	addq 4,%2\n"			\
+		"	clear.d [%0+]\n" FIXUP,		\
+		"	.dword 6b,7b\n" TENTRY)
+
+#define __asm_copy_from_user_12(to, from, ret) \
+	__asm_copy_from_user_12x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_from_user_13(to, from, ret) \
+	__asm_copy_from_user_12x_cont(to, from, ret,	\
+		"	move.b [%1+],r9\n"		\
+		"8:	move.b r9,[%0+]\n",		\
+		"9:	addq 1,%2\n"			\
+		"	clear.b [%0+]\n",		\
+		"	.dword 8b,9b\n")
+
+#define __asm_copy_from_user_14x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_from_user_12x_cont(to, from, ret,	\
+		"	move.w [%1+],r9\n"		\
+		"8:	move.w r9,[%0+]\n" COPY,	\
+		"9:	addq 2,%2\n"			\
+		"	clear.w [%0+]\n" FIXUP,		\
+		"	.dword 8b,9b\n" TENTRY)
+
+#define __asm_copy_from_user_14(to, from, ret) \
+	__asm_copy_from_user_14x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_from_user_15(to, from, ret) \
+	__asm_copy_from_user_14x_cont(to, from, ret,	\
+		"	move.b [%1+],r9\n"		\
+		"10:	move.b r9,[%0+]\n",		\
+		"11:	addq 1,%2\n"			\
+		"	clear.b [%0+]\n",		\
+		"	.dword 10b,11b\n")
+
+#define __asm_copy_from_user_16x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_from_user_12x_cont(to, from, ret,	\
+		"	move.d [%1+],r9\n"		\
+		"8:	move.d r9,[%0+]\n" COPY,	\
+		"9:	addq 4,%2\n"			\
+		"	clear.d [%0+]\n" FIXUP,		\
+		"	.dword 8b,9b\n" TENTRY)
+
+#define __asm_copy_from_user_16(to, from, ret) \
+	__asm_copy_from_user_16x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_from_user_20x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_from_user_16x_cont(to, from, ret,	\
+		"	move.d [%1+],r9\n"		\
+		"10:	move.d r9,[%0+]\n" COPY,	\
+		"11:	addq 4,%2\n"			\
+		"	clear.d [%0+]\n" FIXUP,		\
+		"	.dword 10b,11b\n" TENTRY)
+
+#define __asm_copy_from_user_20(to, from, ret) \
+	__asm_copy_from_user_20x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_from_user_24x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_from_user_20x_cont(to, from, ret,	\
+		"	move.d [%1+],r9\n"		\
+		"12:	move.d r9,[%0+]\n" COPY,	\
+		"13:	addq 4,%2\n"			\
+		"	clear.d [%0+]\n" FIXUP,		\
+		"	.dword 12b,13b\n" TENTRY)
+
+#define __asm_copy_from_user_24(to, from, ret) \
+	__asm_copy_from_user_24x_cont(to, from, ret, "", "", "")
+
+/* And now, the to-user ones.  */
+
+#define __asm_copy_to_user_1(to, from, ret)	\
+	__asm_copy_user_cont(to, from, ret,	\
+		"	move.b [%1+],r9\n"	\
+		"	move.b r9,[%0+]\n2:\n",	\
+		"3:	addq 1,%2\n",		\
+		"	.dword 2b,3b\n")
+
+#define __asm_copy_to_user_2x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_user_cont(to, from, ret,		\
+		"	move.w [%1+],r9\n"		\
+		"	move.w r9,[%0+]\n2:\n" COPY,	\
+		"3:	addq 2,%2\n" FIXUP,		\
+		"	.dword 2b,3b\n" TENTRY)
+
+#define __asm_copy_to_user_2(to, from, ret) \
+	__asm_copy_to_user_2x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_to_user_3(to, from, ret) \
+	__asm_copy_to_user_2x_cont(to, from, ret,	\
+		"	move.b [%1+],r9\n"		\
+		"	move.b r9,[%0+]\n4:\n",		\
+		"5:	addq 1,%2\n",			\
+		"	.dword 4b,5b\n")
+
+#define __asm_copy_to_user_4x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_user_cont(to, from, ret,		\
+		"	move.d [%1+],r9\n"		\
+		"	move.d r9,[%0+]\n2:\n" COPY,	\
+		"3:	addq 4,%2\n" FIXUP,		\
+		"	.dword 2b,3b\n" TENTRY)
+
+#define __asm_copy_to_user_4(to, from, ret) \
+	__asm_copy_to_user_4x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_to_user_5(to, from, ret) \
+	__asm_copy_to_user_4x_cont(to, from, ret,	\
+		"	move.b [%1+],r9\n"		\
+		"	move.b r9,[%0+]\n4:\n",		\
+		"5:	addq 1,%2\n",			\
+		"	.dword 4b,5b\n")
+
+#define __asm_copy_to_user_6x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_to_user_4x_cont(to, from, ret,	\
+		"	move.w [%1+],r9\n"		\
+		"	move.w r9,[%0+]\n4:\n" COPY,	\
+		"5:	addq 2,%2\n" FIXUP,		\
+		"	.dword 4b,5b\n" TENTRY)
+
+#define __asm_copy_to_user_6(to, from, ret) \
+	__asm_copy_to_user_6x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_to_user_7(to, from, ret) \
+	__asm_copy_to_user_6x_cont(to, from, ret,	\
+		"	move.b [%1+],r9\n"		\
+		"	move.b r9,[%0+]\n6:\n",		\
+		"7:	addq 1,%2\n",			\
+		"	.dword 6b,7b\n")
+
+#define __asm_copy_to_user_8x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_to_user_4x_cont(to, from, ret,	\
+		"	move.d [%1+],r9\n"		\
+		"	move.d r9,[%0+]\n4:\n" COPY,	\
+		"5:	addq 4,%2\n"  FIXUP,		\
+		"	.dword 4b,5b\n" TENTRY)
+
+#define __asm_copy_to_user_8(to, from, ret) \
+	__asm_copy_to_user_8x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_to_user_9(to, from, ret) \
+	__asm_copy_to_user_8x_cont(to, from, ret,	\
+		"	move.b [%1+],r9\n"		\
+		"	move.b r9,[%0+]\n6:\n",		\
+		"7:	addq 1,%2\n",			\
+		"	.dword 6b,7b\n")
+
+#define __asm_copy_to_user_10x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_to_user_8x_cont(to, from, ret,	\
+		"	move.w [%1+],r9\n"		\
+		"	move.w r9,[%0+]\n6:\n" COPY,	\
+		"7:	addq 2,%2\n" FIXUP,		\
+		"	.dword 6b,7b\n" TENTRY)
+
+#define __asm_copy_to_user_10(to, from, ret) \
+	__asm_copy_to_user_10x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_to_user_11(to, from, ret) \
+	__asm_copy_to_user_10x_cont(to, from, ret,	\
+		"	move.b [%1+],r9\n"		\
+		"	move.b r9,[%0+]\n8:\n",		\
+		"9:	addq 1,%2\n",			\
+		"	.dword 8b,9b\n")
+
+#define __asm_copy_to_user_12x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_to_user_8x_cont(to, from, ret,	\
+		"	move.d [%1+],r9\n"		\
+		"	move.d r9,[%0+]\n6:\n" COPY,	\
+		"7:	addq 4,%2\n" FIXUP,		\
+		"	.dword 6b,7b\n" TENTRY)
+
+#define __asm_copy_to_user_12(to, from, ret) \
+	__asm_copy_to_user_12x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_to_user_13(to, from, ret) \
+	__asm_copy_to_user_12x_cont(to, from, ret,	\
+		"	move.b [%1+],r9\n"		\
+		"	move.b r9,[%0+]\n8:\n",		\
+		"9:	addq 1,%2\n",			\
+		"	.dword 8b,9b\n")
+
+#define __asm_copy_to_user_14x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_to_user_12x_cont(to, from, ret,	\
+		"	move.w [%1+],r9\n"		\
+		"	move.w r9,[%0+]\n8:\n" COPY,	\
+		"9:	addq 2,%2\n" FIXUP,		\
+		"	.dword 8b,9b\n" TENTRY)
+
+#define __asm_copy_to_user_14(to, from, ret)	\
+	__asm_copy_to_user_14x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_to_user_15(to, from, ret) \
+	__asm_copy_to_user_14x_cont(to, from, ret,	\
+		"	move.b [%1+],r9\n"		\
+		"	move.b r9,[%0+]\n10:\n",		\
+		"11:	addq 1,%2\n",			\
+		"	.dword 10b,11b\n")
+
+#define __asm_copy_to_user_16x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_to_user_12x_cont(to, from, ret,	\
+		"	move.d [%1+],r9\n"		\
+		"	move.d r9,[%0+]\n8:\n" COPY,	\
+		"9:	addq 4,%2\n" FIXUP,		\
+		"	.dword 8b,9b\n" TENTRY)
+
+#define __asm_copy_to_user_16(to, from, ret) \
+	__asm_copy_to_user_16x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_to_user_20x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_to_user_16x_cont(to, from, ret,	\
+		"	move.d [%1+],r9\n"		\
+		"	move.d r9,[%0+]\n10:\n" COPY,	\
+		"11:	addq 4,%2\n" FIXUP,		\
+		"	.dword 10b,11b\n" TENTRY)
+
+#define __asm_copy_to_user_20(to, from, ret) \
+	__asm_copy_to_user_20x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_to_user_24x_cont(to, from, ret, COPY, FIXUP, TENTRY)	\
+	__asm_copy_to_user_20x_cont(to, from, ret,	\
+		"	move.d [%1+],r9\n"		\
+		"	move.d r9,[%0+]\n12:\n" COPY,	\
+		"13:	addq 4,%2\n" FIXUP,		\
+		"	.dword 12b,13b\n" TENTRY)
+
+#define __asm_copy_to_user_24(to, from, ret)	\
+	__asm_copy_to_user_24x_cont(to, from, ret, "", "", "")
+
+/* Define a few clearing asms with exception handlers.  */
+
+/* This frame-asm is like the __asm_copy_user_cont one, but has one less
+   input.  */
+
+#define __asm_clear(to, ret, CLEAR, FIXUP, TENTRY) \
+	__asm__ __volatile__ (				\
+			CLEAR				\
+		"1:\n"					\
+		"	.section .fixup,\"ax\"\n"	\
+			FIXUP				\
+		"	jump 1b\n"			\
+		"	.previous\n"			\
+		"	.section __ex_table,\"a\"\n"	\
+			TENTRY				\
+		"	.previous"			\
+		: "=r" (to), "=r" (ret)			\
+		: "0" (to), "1" (ret)			\
+		: "r9", "memory")
+
+#define __asm_clear_1(to, ret) \
+	__asm_clear(to, ret,			\
+		"	clear.b [%0+]\n2:\n",	\
+		"3:	addq 1,%1\n",		\
+		"	.dword 2b,3b\n")
+
+#define __asm_clear_2(to, ret) \
+	__asm_clear(to, ret,			\
+		"	clear.w [%0+]\n2:\n",	\
+		"3:	addq 2,%1\n",		\
+		"	.dword 2b,3b\n")
+
+#define __asm_clear_3(to, ret) \
+     __asm_clear(to, ret,			\
+		 "	clear.w [%0+]\n"	\
+		 "2:	clear.b [%0+]\n3:\n",	\
+		 "4:	addq 2,%1\n"		\
+		 "5:	addq 1,%1\n",		\
+		 "	.dword 2b,4b\n"		\
+		 "	.dword 3b,5b\n")
+
+#define __asm_clear_4x_cont(to, ret, CLEAR, FIXUP, TENTRY) \
+	__asm_clear(to, ret,				\
+		"	clear.d [%0+]\n2:\n" CLEAR,	\
+		"3:	addq 4,%1\n" FIXUP,		\
+		"	.dword 2b,3b\n" TENTRY)
+
+#define __asm_clear_4(to, ret) \
+	__asm_clear_4x_cont(to, ret, "", "", "")
+
+#define __asm_clear_8x_cont(to, ret, CLEAR, FIXUP, TENTRY) \
+	__asm_clear_4x_cont(to, ret,			\
+		"	clear.d [%0+]\n4:\n" CLEAR,	\
+		"5:	addq 4,%1\n" FIXUP,		\
+		"	.dword 4b,5b\n" TENTRY)
+
+#define __asm_clear_8(to, ret) \
+	__asm_clear_8x_cont(to, ret, "", "", "")
+
+#define __asm_clear_12x_cont(to, ret, CLEAR, FIXUP, TENTRY) \
+	__asm_clear_8x_cont(to, ret,			\
+		"	clear.d [%0+]\n6:\n" CLEAR,	\
+		"7:	addq 4,%1\n" FIXUP,		\
+		"	.dword 6b,7b\n" TENTRY)
+
+#define __asm_clear_12(to, ret) \
+	__asm_clear_12x_cont(to, ret, "", "", "")
+
+#define __asm_clear_16x_cont(to, ret, CLEAR, FIXUP, TENTRY) \
+	__asm_clear_12x_cont(to, ret,			\
+		"	clear.d [%0+]\n8:\n" CLEAR,	\
+		"9:	addq 4,%1\n" FIXUP,		\
+		"	.dword 8b,9b\n" TENTRY)
+
+#define __asm_clear_16(to, ret) \
+	__asm_clear_16x_cont(to, ret, "", "", "")
+
+#define __asm_clear_20x_cont(to, ret, CLEAR, FIXUP, TENTRY) \
+	__asm_clear_16x_cont(to, ret,			\
+		"	clear.d [%0+]\n10:\n" CLEAR,	\
+		"11:	addq 4,%1\n" FIXUP,		\
+		"	.dword 10b,11b\n" TENTRY)
+
+#define __asm_clear_20(to, ret) \
+	__asm_clear_20x_cont(to, ret, "", "", "")
+
+#define __asm_clear_24x_cont(to, ret, CLEAR, FIXUP, TENTRY) \
+	__asm_clear_20x_cont(to, ret,			\
+		"	clear.d [%0+]\n12:\n" CLEAR,	\
+		"13:	addq 4,%1\n" FIXUP,		\
+		"	.dword 12b,13b\n" TENTRY)
+
+#define __asm_clear_24(to, ret) \
+	__asm_clear_24x_cont(to, ret, "", "", "")
+
+/* Note that if these expand awfully if made into switch constructs, so
+   don't do that.  */
+
+static inline unsigned long
+__constant_copy_from_user(void *to, const void *from, unsigned long n)
+{
+	unsigned long ret = 0;
+	if (n == 0)
+		;
+	else if (n == 1)
+		__asm_copy_from_user_1(to, from, ret);
+	else if (n == 2)
+		__asm_copy_from_user_2(to, from, ret);
+	else if (n == 3)
+		__asm_copy_from_user_3(to, from, ret);
+	else if (n == 4)
+		__asm_copy_from_user_4(to, from, ret);
+	else if (n == 5)
+		__asm_copy_from_user_5(to, from, ret);
+	else if (n == 6)
+		__asm_copy_from_user_6(to, from, ret);
+	else if (n == 7)
+		__asm_copy_from_user_7(to, from, ret);
+	else if (n == 8)
+		__asm_copy_from_user_8(to, from, ret);
+	else if (n == 9)
+		__asm_copy_from_user_9(to, from, ret);
+	else if (n == 10)
+		__asm_copy_from_user_10(to, from, ret);
+	else if (n == 11)
+		__asm_copy_from_user_11(to, from, ret);
+	else if (n == 12)
+		__asm_copy_from_user_12(to, from, ret);
+	else if (n == 13)
+		__asm_copy_from_user_13(to, from, ret);
+	else if (n == 14)
+		__asm_copy_from_user_14(to, from, ret);
+	else if (n == 15)
+		__asm_copy_from_user_15(to, from, ret);
+	else if (n == 16)
+		__asm_copy_from_user_16(to, from, ret);
+	else if (n == 20)
+		__asm_copy_from_user_20(to, from, ret);
+	else if (n == 24)
+		__asm_copy_from_user_24(to, from, ret);
+	else
+		ret = __generic_copy_from_user(to, from, n);
+
+	return ret;
+}
+
+/* Ditto, don't make a switch out of this.  */
+
+static inline unsigned long
+__constant_copy_to_user(void *to, const void *from, unsigned long n)
+{
+	unsigned long ret = 0;
+	if (n == 0)
+		;
+	else if (n == 1)
+		__asm_copy_to_user_1(to, from, ret);
+	else if (n == 2)
+		__asm_copy_to_user_2(to, from, ret);
+	else if (n == 3)
+		__asm_copy_to_user_3(to, from, ret);
+	else if (n == 4)
+		__asm_copy_to_user_4(to, from, ret);
+	else if (n == 5)
+		__asm_copy_to_user_5(to, from, ret);
+	else if (n == 6)
+		__asm_copy_to_user_6(to, from, ret);
+	else if (n == 7)
+		__asm_copy_to_user_7(to, from, ret);
+	else if (n == 8)
+		__asm_copy_to_user_8(to, from, ret);
+	else if (n == 9)
+		__asm_copy_to_user_9(to, from, ret);
+	else if (n == 10)
+		__asm_copy_to_user_10(to, from, ret);
+	else if (n == 11)
+		__asm_copy_to_user_11(to, from, ret);
+	else if (n == 12)
+		__asm_copy_to_user_12(to, from, ret);
+	else if (n == 13)
+		__asm_copy_to_user_13(to, from, ret);
+	else if (n == 14)
+		__asm_copy_to_user_14(to, from, ret);
+	else if (n == 15)
+		__asm_copy_to_user_15(to, from, ret);
+	else if (n == 16)
+		__asm_copy_to_user_16(to, from, ret);
+	else if (n == 20)
+		__asm_copy_to_user_20(to, from, ret);
+	else if (n == 24)
+		__asm_copy_to_user_24(to, from, ret);
+	else
+		ret = __generic_copy_to_user(to, from, n);
+
+	return ret;
+}
+
+/* No switch, please.  */
+
+static inline unsigned long
+__constant_clear_user(void *to, unsigned long n)
+{
+	unsigned long ret = 0;
+	if (n == 0)
+		;
+	else if (n == 1)
+		__asm_clear_1(to, ret);
+	else if (n == 2)
+		__asm_clear_2(to, ret);
+	else if (n == 3)
+		__asm_clear_3(to, ret);
+	else if (n == 4)
+		__asm_clear_4(to, ret);
+	else if (n == 8)
+		__asm_clear_8(to, ret);
+	else if (n == 12)
+		__asm_clear_12(to, ret);
+	else if (n == 16)
+		__asm_clear_16(to, ret);
+	else if (n == 20)
+		__asm_clear_20(to, ret);
+	else if (n == 24)
+		__asm_clear_24(to, ret);
+	else
+		ret = __generic_clear_user(to, n);
+
+	return ret;
+}
+
+
+#define clear_user(to, n)			\
+(__builtin_constant_p(n) ?			\
+ __constant_clear_user(to, n) :			\
+ __generic_clear_user(to, n))
+
+#define copy_from_user(to, from, n)		\
+(__builtin_constant_p(n) ?			\
+ __constant_copy_from_user(to, from, n) :	\
+ __generic_copy_from_user(to, from, n))
+
+#define copy_to_user(to, from, n)		\
+(__builtin_constant_p(n) ?			\
+ __constant_copy_to_user(to, from, n) :		\
+ __generic_copy_to_user(to, from, n))
+
+#define copy_to_user_ret(to,from,n,retval) \
+	do { if (copy_to_user(to,from,n)) return retval; } while (0)
+#define copy_from_user_ret(to,from,n,retval) \
+	do { if (copy_from_user(to,from,n)) return retval; } while (0)
+
+/* We let the __ versions of copy_from/to_user inline, because they're often
+ * used in fast paths and have only a small space overhead.
+ */
+
+static inline unsigned long
+__generic_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
+{
+	return __copy_user_zeroing(to,from,n);
+}
+
+static inline unsigned long
+__generic_copy_to_user_nocheck(void *to, const void *from, unsigned long n)
+{
+	return __copy_user(to,from,n);
+}
+
+static inline unsigned long
+__generic_clear_user_nocheck(void *to, unsigned long n)
+{
+	return __do_clear_user(to,n);
+}
+
+/* without checking */
+
+#define __copy_to_user(to,from,n)   __generic_copy_to_user_nocheck((to),(from),(n))
+#define __copy_from_user(to,from,n) __generic_copy_from_user_nocheck((to),(from),(n))
+#define __clear_user(to,n) __generic_clear_user_nocheck((to),(n))
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return length of string in userspace including terminating 0
+ * or 0 for error.  Return a value greater than N if too long.
+ */
+
+static inline long
+strnlen_user(const char *s, long n)
+{
+	long res, tmp1, tmp2;
+
+	if (!access_ok(VERIFY_READ, s, 0))
+		return 0;
+
+	/*
+	 * This code is deduced from:
+	 *
+	 *	tmp1 = n;
+	 *	while (tmp1-- > 0 && *s++)
+	 *	  ;
+	 *
+	 *	res = n - tmp1;
+	 *
+	 *  (with tweaks).
+	 */
+
+	__asm__ __volatile__ (
+		"	move.d %1,r9\n"
+		"0:\n"
+		"	ble 1f\n"
+		"	subq 1,r9\n"
+
+		"	test.b [%0+]\n"
+		"	bne 0b\n"
+		"	test.d r9\n"
+		"1:\n"
+		"	move.d %1,%0\n"
+		"	sub.d r9,%0\n"
+		"2:\n"
+		"	.section .fixup,\"ax\"\n"
+
+		"3:	clear.d %0\n"
+		"	jump 2b\n"
+
+		/* There's one address for a fault at the first move, and
+		   two possible PC values for a fault at the second move,
+		   being a delay-slot filler.  However, the branch-target
+		   for the second move is the same as the first address.
+		   Just so you don't get confused...  */
+		"	.previous\n"
+		"	.section __ex_table,\"a\"\n"
+		"	.dword 0b,3b\n"
+		"	.dword 1b,3b\n"
+		"	.previous\n"
+		: "=r" (res), "=r" (tmp1)
+		: "0" (s), "1" (n)
+		: "r9");
+
+	return res;
+}
+
+#define strlen_user(str)	strnlen_user((str), 0x7ffffffe)
+
+#endif  /* __ASSEMBLY__ */
+
+#endif	/* _CRIS_UACCESS_H */
diff -urN linux-2.4.2-pre1/include/asm-cris/ucontext.h linux/include/asm-cris/ucontext.h
--- linux-2.4.2-pre1/include/asm-cris/ucontext.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/ucontext.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,12 @@
+#ifndef _ASM_CRIS_UCONTEXT_H
+#define _ASM_CRIS_UCONTEXT_H
+
+struct ucontext {
+	unsigned long	  uc_flags;
+	struct ucontext  *uc_link;
+	stack_t		  uc_stack;
+	struct sigcontext uc_mcontext;
+	sigset_t	  uc_sigmask;	/* mask last for extensibility */
+};
+
+#endif /* !_ASM_CRIS_UCONTEXT_H */
diff -urN linux-2.4.2-pre1/include/asm-cris/unaligned.h linux/include/asm-cris/unaligned.h
--- linux-2.4.2-pre1/include/asm-cris/unaligned.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/unaligned.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,16 @@
+#ifndef __CRIS_UNALIGNED_H
+#define __CRIS_UNALIGNED_H
+
+/*
+ * CRIS can do unaligned accesses itself. 
+ *
+ * The strange macros are there to make sure these can't
+ * be misused in a way that makes them not work on other
+ * architectures where unaligned accesses aren't as simple.
+ */
+
+#define get_unaligned(ptr) (*(ptr))
+
+#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) ))
+
+#endif
diff -urN linux-2.4.2-pre1/include/asm-cris/unistd.h linux/include/asm-cris/unistd.h
--- linux-2.4.2-pre1/include/asm-cris/unistd.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/unistd.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,373 @@
+#ifndef _ASM_CRIS_UNISTD_H_
+#define _ASM_CRIS_UNISTD_H_
+
+/*
+ * This file contains the system call numbers, and stub macros for libc.
+ */
+
+#define __NR_setup		  0	/* used only by init, to get system going */
+#define __NR_exit		  1
+#define __NR_fork		  2
+#define __NR_read		  3
+#define __NR_write		  4
+#define __NR_open		  5
+#define __NR_close		  6
+#define __NR_waitpid		  7
+#define __NR_creat		  8
+#define __NR_link		  9
+#define __NR_unlink		 10
+#define __NR_execve		 11
+#define __NR_chdir		 12
+#define __NR_time		 13
+#define __NR_mknod		 14
+#define __NR_chmod		 15
+#define __NR_lchown		 16
+#define __NR_break		 17
+#define __NR_oldstat		 18
+#define __NR_lseek		 19
+#define __NR_getpid		 20
+#define __NR_mount		 21
+#define __NR_umount		 22
+#define __NR_setuid		 23
+#define __NR_getuid		 24
+#define __NR_stime		 25
+#define __NR_ptrace		 26
+#define __NR_alarm		 27
+#define __NR_oldfstat		 28
+#define __NR_pause		 29
+#define __NR_utime		 30
+#define __NR_stty		 31
+#define __NR_gtty		 32
+#define __NR_access		 33
+#define __NR_nice		 34
+#define __NR_ftime		 35
+#define __NR_sync		 36
+#define __NR_kill		 37
+#define __NR_rename		 38
+#define __NR_mkdir		 39
+#define __NR_rmdir		 40
+#define __NR_dup		 41
+#define __NR_pipe		 42
+#define __NR_times		 43
+#define __NR_prof		 44
+#define __NR_brk		 45
+#define __NR_setgid		 46
+#define __NR_getgid		 47
+#define __NR_signal		 48
+#define __NR_geteuid		 49
+#define __NR_getegid		 50
+#define __NR_acct		 51
+#define __NR_phys		 52
+#define __NR_lock		 53
+#define __NR_ioctl		 54
+#define __NR_fcntl		 55
+#define __NR_mpx		 56
+#define __NR_setpgid		 57
+#define __NR_ulimit		 58
+#define __NR_oldolduname	 59
+#define __NR_umask		 60
+#define __NR_chroot		 61
+#define __NR_ustat		 62
+#define __NR_dup2		 63
+#define __NR_getppid		 64
+#define __NR_getpgrp		 65
+#define __NR_setsid		 66
+#define __NR_sigaction		 67
+#define __NR_sgetmask		 68
+#define __NR_ssetmask		 69
+#define __NR_setreuid		 70
+#define __NR_setregid		 71
+#define __NR_sigsuspend		 72
+#define __NR_sigpending		 73
+#define __NR_sethostname	 74
+#define __NR_setrlimit		 75
+#define __NR_getrlimit		 76
+#define __NR_getrusage		 77
+#define __NR_gettimeofday	 78
+#define __NR_settimeofday	 79
+#define __NR_getgroups		 80
+#define __NR_setgroups		 81
+#define __NR_select		 82
+#define __NR_symlink		 83
+#define __NR_oldlstat		 84
+#define __NR_readlink		 85
+#define __NR_uselib		 86
+#define __NR_swapon		 87
+#define __NR_reboot		 88
+#define __NR_readdir		 89
+#define __NR_mmap		 90
+#define __NR_munmap		 91
+#define __NR_truncate		 92
+#define __NR_ftruncate		 93
+#define __NR_fchmod		 94
+#define __NR_fchown		 95
+#define __NR_getpriority	 96
+#define __NR_setpriority	 97
+#define __NR_profil		 98
+#define __NR_statfs		 99
+#define __NR_fstatfs		100
+#define __NR_ioperm		101
+#define __NR_socketcall		102
+#define __NR_syslog		103
+#define __NR_setitimer		104
+#define __NR_getitimer		105
+#define __NR_stat		106
+#define __NR_lstat		107
+#define __NR_fstat		108
+#define __NR_olduname		109
+#define __NR_iopl		110
+#define __NR_vhangup		111
+#define __NR_idle		112
+#define __NR_vm86		113
+#define __NR_wait4		114
+#define __NR_swapoff		115
+#define __NR_sysinfo		116
+#define __NR_ipc		117
+#define __NR_fsync		118
+#define __NR_sigreturn		119
+#define __NR_clone		120
+#define __NR_setdomainname	121
+#define __NR_uname		122
+#define __NR_modify_ldt		123
+#define __NR_adjtimex		124
+#define __NR_mprotect		125
+#define __NR_sigprocmask	126
+#define __NR_create_module	127
+#define __NR_init_module	128
+#define __NR_delete_module	129
+#define __NR_get_kernel_syms	130
+#define __NR_quotactl		131
+#define __NR_getpgid		132
+#define __NR_fchdir		133
+#define __NR_bdflush		134
+#define __NR_sysfs		135
+#define __NR_personality	136
+#define __NR_afs_syscall	137 /* Syscall for Andrew File System */
+#define __NR_setfsuid		138
+#define __NR_setfsgid		139
+#define __NR__llseek		140
+#define __NR_getdents		141
+#define __NR__newselect		142
+#define __NR_flock		143
+#define __NR_msync		144
+#define __NR_readv		145
+#define __NR_writev		146
+#define __NR_getsid		147
+#define __NR_fdatasync		148
+#define __NR__sysctl		149
+#define __NR_mlock		150
+#define __NR_munlock		151
+#define __NR_mlockall		152
+#define __NR_munlockall		153
+#define __NR_sched_setparam		154
+#define __NR_sched_getparam		155
+#define __NR_sched_setscheduler		156
+#define __NR_sched_getscheduler		157
+#define __NR_sched_yield		158
+#define __NR_sched_get_priority_max	159
+#define __NR_sched_get_priority_min	160
+#define __NR_sched_rr_get_interval	161
+#define __NR_nanosleep		162
+#define __NR_mremap		163
+#define __NR_setresuid		164
+#define __NR_getresuid		165
+
+#define __NR_query_module	167
+#define __NR_poll		168
+#define __NR_nfsservctl		169
+#define __NR_setresgid		170
+#define __NR_getresgid		171
+#define __NR_prctl              172
+#define __NR_rt_sigreturn	173
+#define __NR_rt_sigaction	174
+#define __NR_rt_sigprocmask	175
+#define __NR_rt_sigpending	176
+#define __NR_rt_sigtimedwait	177
+#define __NR_rt_sigqueueinfo	178
+#define __NR_rt_sigsuspend	179
+#define __NR_pread		180
+#define __NR_pwrite		181
+#define __NR_chown		182
+#define __NR_getcwd		183
+#define __NR_capget		184
+#define __NR_capset		185
+#define __NR_sigaltstack	186
+#define __NR_sendfile		187
+#define __NR_getpmsg		188	/* some people actually want streams */
+#define __NR_putpmsg		189	/* some people actually want streams */
+#define __NR_vfork		190
+#define __NR_ugetrlimit		191	/* SuS compliant getrlimit */
+#define __NR_mmap2		192
+#define __NR_truncate64		193
+#define __NR_ftruncate64	194
+#define __NR_stat64		195
+#define __NR_lstat64		196
+#define __NR_fstat64		197
+#define __NR_lchown32		198
+#define __NR_getuid32		199
+#define __NR_getgid32		200
+#define __NR_geteuid32		201
+#define __NR_getegid32		202
+#define __NR_setreuid32		203
+#define __NR_setregid32		204
+#define __NR_getgroups32	205
+#define __NR_setgroups32	206
+#define __NR_fchown32		207
+#define __NR_setresuid32	208
+#define __NR_getresuid32	209
+#define __NR_setresgid32	210
+#define __NR_getresgid32	211
+#define __NR_chown32		212
+#define __NR_setuid32		213
+#define __NR_setgid32		214
+#define __NR_setfsuid32		215
+#define __NR_setfsgid32		216
+#define __NR_pivot_root		217
+#define __NR_mincore		218
+#define __NR_madvise		219
+#define __NR_getdents64		220
+#define __NR_fcntl64		221
+
+/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
+#define _syscall0(type,name) \
+type name(void) \
+{ \
+  register long __a __asm__ ("r10"); \
+  __asm__ __volatile__ ("move.d %1,r1\n\tbreak 13" \
+			: "=r" (__a) \
+			: "g" (__NR_##name) \
+			: "r10", "r1"); \
+  if(__a >= 0) \
+     return (type) __a; \
+  errno = -__a; \
+  return -1; \
+}
+
+#define _syscall1(type,name,type1,arg1) \
+type name(type1 arg1) \
+{ \
+  register long __a __asm__ ("r10") = (long) arg1; \
+  __asm__ __volatile__ ("move.d %1,r1\n\tbreak 13" \
+			: "=r" (__a) \
+			: "g" (__NR_##name), "0" (__a) \
+			: "r10", "r1"); \
+  if(__a >= 0) \
+     return (type) __a; \
+  errno = -__a; \
+  return -1; \
+}
+
+#define _syscall2(type,name,type1,arg1,type2,arg2) \
+type name(type1 arg1,type2 arg2) \
+{ \
+  register long __a __asm__ ("r10") = (long) arg1; \
+  register long __b __asm__ ("r11") = (long) arg2; \
+  __asm__ __volatile__ ("move.d %1,r1\n\tbreak 13" \
+			: "=r" (__a) \
+			: "g" (__NR_##name), "0" (__a), "r" (__b) \
+			: "r10", "r1"); \
+  if(__a >= 0) \
+     return (type) __a; \
+  errno = -__a; \
+  return -1; \
+}
+
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
+type name(type1 arg1,type2 arg2,type3 arg3) \
+{ \
+  register long __a __asm__ ("r10") = (long) arg1; \
+  register long __b __asm__ ("r11") = (long) arg2; \
+  register long __c __asm__ ("r12") = (long) arg3; \
+  __asm__ __volatile__ ("move.d %1,r1\n\tbreak 13" \
+			: "=r" (__a) \
+			: "g" (__NR_##name), "0" (__a), "r" (__b), "r" (__c) \
+			: "r10", "r1"); \
+  if(__a >= 0) \
+     return (type) __a; \
+  errno = -__a; \
+  return -1; \
+}
+
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
+{ \
+  register long __a __asm__ ("r10") = (long) arg1; \
+  register long __b __asm__ ("r11") = (long) arg2; \
+  register long __c __asm__ ("r12") = (long) arg3; \
+  register long __d __asm__ ("r13") = (long) arg4; \
+  __asm__ __volatile__ ("move.d %1,r1\n\tbreak 13" \
+			: "=r" (__a) \
+			: "g" (__NR_##name), "0" (__a), "r" (__b), \
+			  "r" (__c), "r" (__d) \
+			: "r10", "r1"); \
+  if(__a >= 0) \
+     return (type) __a; \
+  errno = -__a; \
+  return -1; \
+} 
+
+#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+	  type5,arg5) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
+{ \
+  register long __a __asm__ ("r10") = (long) arg1; \
+  register long __b __asm__ ("r11") = (long) arg2; \
+  register long __c __asm__ ("r12") = (long) arg3; \
+  register long __d __asm__ ("r13") = (long) arg4; \
+  register long __e __asm__ ("r0") = (long) arg5; \
+  __asm__ __volatile__ ("move.d %1,r1\n\tbreak 13" \
+			: "=r" (__a) \
+			: "g" (__NR_##name), "0" (__a), "r" (__b), \
+			  "r" (__c), "r" (__d), "r" (__e) \
+			: "r10", "r1"); \
+  if(__a >= 0) \
+     return (type) __a; \
+  errno = -__a; \
+  return -1; \
+}
+
+#ifdef __KERNEL_SYSCALLS__
+
+/*
+ * we need this inline - forking from kernel space will result
+ * in NO COPY ON WRITE (!!!), until an execve is executed. This
+ * is no problem, but for the stack. This is handled by not letting
+ * main() use the stack at all after fork(). Thus, no function
+ * calls - which means inline code for fork too, as otherwise we
+ * would use the stack upon exit from 'fork()'.
+ *
+ * Actually only pause and fork are needed inline, so that there
+ * won't be any messing with the stack from main(), but we define
+ * some others too.
+ */
+#define __NR__exit __NR_exit
+static inline _syscall0(int,idle)
+static inline _syscall0(int,fork)
+static inline _syscall2(int,clone,unsigned long,flags,char *,esp)
+static inline _syscall0(int,pause)
+static inline _syscall0(int,setup)
+static inline _syscall0(int,sync)
+static inline _syscall0(pid_t,setsid)
+static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
+static inline _syscall1(int,dup,int,fd)
+static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
+static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
+static inline _syscall1(int,close,int,fd)
+static inline _syscall1(int,_exit,int,exitcode)
+static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+
+  /* the following are just while developing the elinux port! */
+
+static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
+static inline _syscall2(int,socketcall,int,call,unsigned long *,args)
+static inline _syscall3(int,ioctl,unsigned int,fd,unsigned int,cmd,unsigned long,arg)
+static inline _syscall5(int,mount,const char *,a,const char *,b,const char *,c,unsigned long,rwflag,const void *,data)
+
+static inline pid_t wait(int * wait_stat)
+{
+	return waitpid(-1,wait_stat,0);
+}
+
+#endif
+
+#endif /* _ASM_CRIS_UNISTD_H_ */
diff -urN linux-2.4.2-pre1/include/asm-cris/user.h linux/include/asm-cris/user.h
--- linux-2.4.2-pre1/include/asm-cris/user.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/user.h	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,51 @@
+#ifndef __ASM_CRIS_USER_H
+#define __ASM_CRIS_USER_H
+
+#include <linux/types.h>
+#include <asm/ptrace.h>
+#include <asm/page.h>
+
+/*
+ * Core file format: The core file is written in such a way that gdb
+ * can understand it and provide useful information to the user (under
+ * linux we use the `trad-core' bfd).  The file contents are as follows:
+ *
+ *  upage: 1 page consisting of a user struct that tells gdb
+ *	what is present in the file.  Directly after this is a
+ *	copy of the task_struct, which is currently not used by gdb,
+ *	but it may come in handy at some point.  All of the registers
+ *	are stored as part of the upage.  The upage should always be
+ *	only one page long.
+ *  data: The data segment follows next.  We use current->end_text to
+ *	current->brk to pick up all of the user variables, plus any memory
+ *	that may have been sbrk'ed.  No attempt is made to determine if a
+ *	page is demand-zero or if a page is totally unused, we just cover
+ *	the entire range.  All of the addresses are rounded in such a way
+ *	that an integral number of pages is written.
+ *  stack: We need the stack information in order to get a meaningful
+ *	backtrace.  We need to write the data from usp to
+ *	current->start_stack, so we round each of these in order to be able
+ *	to write an integer number of pages.
+ */
+
+struct user {
+	struct pt_regs	regs;			/* entire machine state */
+	size_t		u_tsize;		/* text size (pages) */
+	size_t		u_dsize;		/* data size (pages) */
+	size_t		u_ssize;		/* stack size (pages) */
+	unsigned long	start_code;		/* text starting address */
+	unsigned long	start_data;		/* data starting address */
+	unsigned long	start_stack;		/* stack starting address */
+	long int	signal;			/* signal causing core dump */
+	struct regs *	u_ar0;			/* help gdb find registers */
+	unsigned long	magic;			/* identifies a core file */
+	char		u_comm[32];		/* user command name */
+};
+
+#define NBPG			PAGE_SIZE
+#define UPAGES			1
+#define HOST_TEXT_START_ADDR	(u.start_code)
+#define HOST_DATA_START_ADDR	(u.start_data)
+#define HOST_STACK_END_ADDR	(u.start_stack + u.u_ssize * NBPG)
+
+#endif /* __ASM_CRIS_USER_H */
diff -urN linux-2.4.2-pre1/include/asm-mips64/delay.h linux/include/asm-mips64/delay.h
--- linux-2.4.2-pre1/include/asm-mips64/delay.h	Tue Jul 11 11:18:53 2000
+++ linux/include/asm-mips64/delay.h	Mon Dec  3 22:27:49 2001
@@ -12,6 +12,8 @@
 
 #include <linux/config.h>
 
+extern unsigned long loops_per_sec;
+
 extern __inline__ void
 __delay(unsigned long loops)
 {
diff -urN linux-2.4.2-pre1/include/asm-mips64/errno.h linux/include/asm-mips64/errno.h
--- linux-2.4.2-pre1/include/asm-mips64/errno.h	Sat May 13 08:31:25 2000
+++ linux/include/asm-mips64/errno.h	Mon Dec  3 22:27:49 2001
@@ -1,10 +1,10 @@
-/* $Id: errno.h,v 1.1 1999/08/18 23:37:51 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1995 by Ralf Baechle
+ * Copyright (C) 1995, 2001 by Ralf Baechle
+ * Copyright (C) 2001 Silicon Graphics, Inc.
  */
 #ifndef _ASM_ERRNO_H
 #define _ASM_ERRNO_H
@@ -142,6 +142,7 @@
  */
 #define ENOMEDIUM	159	/* No medium found */
 #define EMEDIUMTYPE	160	/* Wrong medium type */
+#define EHASHCOLLISION	125	/* Number of hash collisons exceeds maximum generation counter value.  */
 
 #define EDQUOT		1133	/* Quota exceeded */
 
diff -urN linux-2.4.2-pre1/include/asm-mips64/sn/mapped_kernel.h linux/include/asm-mips64/sn/mapped_kernel.h
--- linux-2.4.2-pre1/include/asm-mips64/sn/mapped_kernel.h	Tue Nov 28 21:42:04 2000
+++ linux/include/asm-mips64/sn/mapped_kernel.h	Mon Dec  3 22:27:49 2001
@@ -52,4 +52,4 @@
 #define MAPPED_KERN_RO_TO_K0(x)	PHYS_TO_K0(MAPPED_KERN_RO_TO_PHYS(x))
 #define MAPPED_KERN_RW_TO_K0(x)	PHYS_TO_K0(MAPPED_KERN_RW_TO_PHYS(x))
 
-#endif __ASM_SN_MAPPED_KERNEL_H
+#endif /* __ASM_SN_MAPPED_KERNEL_H  */
diff -urN linux-2.4.2-pre1/include/asm-mips64/watch.h linux/include/asm-mips64/watch.h
--- linux-2.4.2-pre1/include/asm-mips64/watch.h	Sat May 13 08:31:25 2000
+++ linux/include/asm-mips64/watch.h	Mon Dec  3 22:27:49 2001
@@ -1,10 +1,9 @@
-/* $Id: watch.h,v 1.1 1999/09/27 16:01:41 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 1997, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 by Ralf Baechle
  */
 #ifndef _ASM_WATCH_H
 #define _ASM_WATCH_H
@@ -35,4 +34,4 @@
 	if (watch_available)					\
 		__watch_reenable()
 
-#endif _ASM_WATCH_H
+#endif /* _ASM_WATCH_H  */
diff -urN linux-2.4.2-pre1/include/linux/dcache.h linux/include/linux/dcache.h
--- linux-2.4.2-pre1/include/linux/dcache.h	Mon Jan 29 23:24:55 2001
+++ linux/include/linux/dcache.h	Mon Dec  3 22:27:49 2001
@@ -27,6 +27,15 @@
 	unsigned int hash;
 };
 
+struct dentry_stat_t {
+	int nr_dentry;
+	int nr_unused;
+	int age_limit;          /* age in seconds */
+	int want_pages;         /* pages requested by system */
+	int dummy[2];
+};
+extern struct dentry_stat_t dentry_stat;
+
 /* Name hashing routines. Initial hash value */
 #define init_name_hash()		0
 
diff -urN linux-2.4.2-pre1/include/linux/elf.h linux/include/linux/elf.h
--- linux-2.4.2-pre1/include/linux/elf.h	Mon Jan 29 23:25:58 2001
+++ linux/include/linux/elf.h	Mon Dec  3 22:27:49 2001
@@ -74,6 +74,8 @@
 
 #define EM_X8664	62	/* AMD x86-64 */
 
+#define EM_CRIS         76      /* Axis Communications 32-bit embedded processor */
+
 /*
  * This is an interim value that we will use until the committee comes
  * up with a final number.
diff -urN linux-2.4.2-pre1/include/linux/fs.h linux/include/linux/fs.h
--- linux-2.4.2-pre1/include/linux/fs.h	Mon Jan 29 23:24:56 2001
+++ linux/include/linux/fs.h	Mon Dec  3 22:27:49 2001
@@ -53,6 +53,14 @@
 	int max_files;		/* tunable */
 };
 extern struct files_stat_struct files_stat;
+
+struct inodes_stat_t {
+	int nr_inodes;
+	int nr_unused;
+	int dummy[5];
+};
+extern struct inodes_stat_t inodes_stat;
+
 extern int max_super_blocks, nr_super_blocks;
 extern int leases_enable, dir_notify_enable, lease_break_time;
 
diff -urN linux-2.4.2-pre1/include/linux/isdn.h linux/include/linux/isdn.h
--- linux-2.4.2-pre1/include/linux/isdn.h	Mon Dec 11 13:21:27 2000
+++ linux/include/linux/isdn.h	Mon Dec  3 22:27:49 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn.h,v 1.111 2000/11/25 17:01:02 kai Exp $
+/* $Id: isdn.h,v 1.111.6.1 2001/02/07 11:31:31 kai Exp $
 
  * Main header for the Linux ISDN subsystem (linklevel).
  *
@@ -592,23 +592,6 @@
 	char *private;
 } infostruct;
 
-typedef struct isdn_module {
-	struct isdn_module *prev;
-	struct isdn_module *next;
-	char *name;
-	int (*get_free_channel)(int, int, int, int, int);
-	int (*free_channel)(int, int, int);
-	int (*status_callback)(isdn_ctrl *);
-	int (*command)(isdn_ctrl *);
-	int (*receive_callback)(int, int, struct sk_buff *);
-	int (*writebuf_skb)(int, int, int, struct sk_buff *);
-	int (*net_start_xmit)(struct sk_buff *, struct net_device *);
-	int (*net_receive)(struct net_device *, struct sk_buff *);
-	int (*net_open)(struct net_device *);
-	int (*net_close)(struct net_device *);
-	int priority;
-} isdn_module;
-
 #define DRV_FLAG_RUNNING 1
 #define DRV_FLAG_REJBUS  2
 #define DRV_FLAG_LOADED  4
@@ -668,7 +651,6 @@
 	atomic_t          v110use[ISDN_MAX_CHANNELS];/* Usage-Semaphore for stream */
 	isdn_v110_stream  *v110[ISDN_MAX_CHANNELS];  /* V.110 private data         */
 	struct semaphore  sem;                       /* serialize list access*/
-	isdn_module       *modules;
 	unsigned long     global_features;
 #ifdef CONFIG_DEVFS_FS
 	devfs_handle_t devfs_handle_isdninfo;
diff -urN linux-2.4.2-pre1/include/linux/kernelcapi.h linux/include/linux/kernelcapi.h
--- linux-2.4.2-pre1/include/linux/kernelcapi.h	Tue Nov 28 21:43:13 2000
+++ linux/include/linux/kernelcapi.h	Mon Dec  3 22:27:49 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: kernelcapi.h,v 1.8.6.1 2000/11/28 09:36:56 kai Exp $
+ * $Id: kernelcapi.h,v 1.8.6.2 2001/02/07 11:31:31 kai Exp $
  * 
  * Kernel CAPI 2.0 Interface for Linux
  * 
@@ -10,8 +10,8 @@
 #ifndef __KERNELCAPI_H__
 #define __KERNELCAPI_H__
 
-#define CAPI_MAXAPPL	20	/* maximum number of applications  */
-#define CAPI_MAXCONTR	10	/* maximum number of controller    */
+#define CAPI_MAXAPPL	128	/* maximum number of applications  */
+#define CAPI_MAXCONTR	16	/* maximum number of controller    */
 #define CAPI_MAXDATAWINDOW	8
 
 
diff -urN linux-2.4.2-pre1/include/linux/mtd/ftl.h linux/include/linux/mtd/ftl.h
--- linux-2.4.2-pre1/include/linux/mtd/ftl.h	Tue Jul  4 10:10:52 2000
+++ linux/include/linux/mtd/ftl.h	Mon Dec  3 22:27:49 2001
@@ -16,7 +16,7 @@
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
  * Alternatively, the contents of this file may be used under the
- * terms of the GNU Public License version 2 (the "GPL"), in which
+ * terms of the GNU General Public License version 2 (the "GPL"), in which
  * case the provisions of the GPL are applicable instead of the
  * above.  If you wish to allow the use of your version of this file
  * only under the terms of the GPL and not to allow others to use
diff -urN linux-2.4.2-pre1/include/linux/mtd/map.h linux/include/linux/mtd/map.h
--- linux-2.4.2-pre1/include/linux/mtd/map.h	Fri Dec 29 14:07:24 2000
+++ linux/include/linux/mtd/map.h	Mon Dec  3 22:27:49 2001
@@ -1,6 +1,6 @@
 
 /* Overhauled routines for dealing with different mmap regions of flash */
-/* $Id: map.h,v 1.10 2000/12/04 13:18:33 dwmw2 Exp $ */
+/* $Id: map.h,v 1.10.2.2 2001/01/09 00:44:51 dwmw2 Exp $ */
 
 #ifndef __LINUX_MTD_MAP_H__
 #define __LINUX_MTD_MAP_H__
@@ -44,7 +44,7 @@
 	void (*write32)(struct map_info *, __u32, unsigned long);
 	void (*copy_to)(struct map_info *, unsigned long, const void *, ssize_t);
 
-	void (*set_vpp)(int);
+	void (*set_vpp)(struct map_info *, int);
 	/* We put these two here rather than a single void *map_priv, 
 	   because we want mappers to be able to have quickly-accessible
 	   cache for the 'currently-mapped page' without the _extra_
@@ -108,7 +108,7 @@
 	kfree(mtd);
 }
 
-#define ENABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(1); } while(0)
-#define DISABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(0); } while(0)
+#define ENABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 1); } while(0)
+#define DISABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 0); } while(0)
 
 #endif /* __LINUX_MTD_MAP_H__ */
diff -urN linux-2.4.2-pre1/include/linux/parport.h linux/include/linux/parport.h
--- linux-2.4.2-pre1/include/linux/parport.h	Mon Dec 11 12:50:09 2000
+++ linux/include/linux/parport.h	Mon Dec  3 22:27:49 2001
@@ -229,7 +229,7 @@
 	unsigned long int time;
 	unsigned long int timeslice;
 	volatile long int timeout;
-	unsigned int waiting;
+	unsigned long waiting;		 /* long req'd for set_bit --RR */
 	struct pardevice *waitprev;
 	struct pardevice *waitnext;
 	void * sysctl_table;
diff -urN linux-2.4.2-pre1/include/linux/sched.h linux/include/linux/sched.h
--- linux-2.4.2-pre1/include/linux/sched.h	Mon Jan 29 23:24:56 2001
+++ linux/include/linux/sched.h	Mon Dec  3 22:27:49 2001
@@ -551,7 +551,7 @@
 extern void FASTCALL(interruptible_sleep_on(wait_queue_head_t *q));
 extern long FASTCALL(interruptible_sleep_on_timeout(wait_queue_head_t *q,
 						    signed long timeout));
-extern void FASTCALL(wake_up_process(struct task_struct * tsk));
+extern int FASTCALL(wake_up_process(struct task_struct * tsk));
 
 #define wake_up(x)			__wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 1)
 #define wake_up_nr(x, nr)		__wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, nr)
diff -urN linux-2.4.2-pre1/include/linux/telephony.h linux/include/linux/telephony.h
--- linux-2.4.2-pre1/include/linux/telephony.h	Sat Dec 30 18:16:13 2000
+++ linux/include/linux/telephony.h	Mon Dec  3 22:27:49 2001
@@ -43,6 +43,11 @@
  *  the telephony products they support under Linux)
  *
  *****************************************************************************/
+#define QTI_PHONEJACK		100
+#define QTI_LINEJACK		300
+#define QTI_PHONEJACK_LITE	400
+#define QTI_PHONEJACK_PCI	500
+#define QTI_PHONECARD		600
 
 /******************************************************************************
 *
@@ -91,7 +96,7 @@
         int namelen;
         char name[80];
 } PHONE_CID;
-
+ 
 #define PHONE_RING			_IO  ('q', 0x83)
 #define PHONE_HOOKSTATE			_IO  ('q', 0x84)
 #define PHONE_MAXRINGS			_IOW ('q', 0x85, char)
diff -urN linux-2.4.2-pre1/include/linux/wait.h linux/include/linux/wait.h
--- linux-2.4.2-pre1/include/linux/wait.h	Mon Jan 29 23:24:56 2001
+++ linux/include/linux/wait.h	Mon Dec  3 22:27:49 2001
@@ -19,30 +19,10 @@
 #include <asm/processor.h>
 
 /*
- * Temporary debugging help until all code is converted to the new
- * waitqueue usage.
+ * Debug control.  Slow but useful.
  */
 #define WAITQUEUE_DEBUG 0
 
-#if WAITQUEUE_DEBUG
-extern int printk(const char *fmt, ...);
-#define WQ_BUG() do { \
-	printk("wq bug, forcing oops.\n"); \
-	BUG(); \
-} while (0)
-
-#define CHECK_MAGIC(x) if (x != (long)&(x)) \
-	{ printk("bad magic %lx (should be %lx), ", (long)x, (long)&(x)); WQ_BUG(); }
-
-#define CHECK_MAGIC_WQHEAD(x) do { \
-	if (x->__magic != (long)&(x->__magic)) { \
-		printk("bad magic %lx (should be %lx, creator %lx), ", \
-			x->__magic, (long)&(x->__magic), x->__creator); \
-		WQ_BUG(); \
-	} \
-} while (0)
-#endif
-
 struct __wait_queue {
 	unsigned int flags;
 #define WQ_FLAG_EXCLUSIVE	0x01
@@ -99,24 +79,70 @@
 };
 typedef struct __wait_queue_head wait_queue_head_t;
 
+
+/*
+ * Debugging macros.  We eschew `do { } while (0)' because gcc can generate
+ * spurious .aligns.
+ */
+#if WAITQUEUE_DEBUG
+#define WQ_BUG()	BUG()
+#define CHECK_MAGIC(x)							\
+	do {									\
+		if ((x) != (long)&(x)) {					\
+			printk("bad magic %lx (should be %lx), ",		\
+				(long)x, (long)&(x));				\
+			WQ_BUG();						\
+		}								\
+	} while (0)
+#define CHECK_MAGIC_WQHEAD(x)							\
+	do {									\
+		if ((x)->__magic != (long)&((x)->__magic)) {			\
+			printk("bad magic %lx (should be %lx, creator %lx), ",	\
+			(x)->__magic, (long)&((x)->__magic), (x)->__creator);	\
+			WQ_BUG();						\
+		}								\
+	} while (0)
+#define WQ_CHECK_LIST_HEAD(list) 						\
+	do {									\
+		if (!list->next || !list->prev)					\
+			WQ_BUG();						\
+	} while(0)
+#define WQ_NOTE_WAKER(tsk)							\
+	do {									\
+		tsk->__waker = (long)__builtin_return_address(0);		\
+	} while (0)
+#else
+#define WQ_BUG()
+#define CHECK_MAGIC(x)
+#define CHECK_MAGIC_WQHEAD(x)
+#define WQ_CHECK_LIST_HEAD(list)
+#define WQ_NOTE_WAKER(tsk)
+#endif
+
+/*
+ * Macros for declaration and initialisaton of the datatypes
+ */
+
 #if WAITQUEUE_DEBUG
-# define __WAITQUEUE_DEBUG_INIT(name) \
-		, (long)&(name).__magic, 0
-# define __WAITQUEUE_HEAD_DEBUG_INIT(name) \
-		, (long)&(name).__magic, (long)&(name).__magic
+# define __WAITQUEUE_DEBUG_INIT(name) (long)&(name).__magic, 0
+# define __WAITQUEUE_HEAD_DEBUG_INIT(name) (long)&(name).__magic, (long)&(name).__magic
 #else
 # define __WAITQUEUE_DEBUG_INIT(name)
 # define __WAITQUEUE_HEAD_DEBUG_INIT(name)
 #endif
 
-#define __WAITQUEUE_INITIALIZER(name,task) \
-	{ 0x0, task, { NULL, NULL } __WAITQUEUE_DEBUG_INIT(name)}
-#define DECLARE_WAITQUEUE(name,task) \
-	wait_queue_t name = __WAITQUEUE_INITIALIZER(name,task)
-
-#define __WAIT_QUEUE_HEAD_INITIALIZER(name) \
-{ WAITQUEUE_RW_LOCK_UNLOCKED, { &(name).task_list, &(name).task_list } \
-		__WAITQUEUE_HEAD_DEBUG_INIT(name)}
+#define __WAITQUEUE_INITIALIZER(name, tsk) {				\
+	task:		tsk,						\
+	task_list:	{ NULL, NULL },					\
+			 __WAITQUEUE_DEBUG_INIT(name)}
+
+#define DECLARE_WAITQUEUE(name, tsk)					\
+	wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk)
+
+#define __WAIT_QUEUE_HEAD_INITIALIZER(name) {				\
+	lock:		WAITQUEUE_RW_LOCK_UNLOCKED,			\
+	task_list:	{ &(name).task_list, &(name).task_list },	\
+			__WAITQUEUE_HEAD_DEBUG_INIT(name)}
 
 #define DECLARE_WAIT_QUEUE_HEAD(name) \
 	wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)
@@ -135,8 +161,7 @@
 #endif
 }
 
-static inline void init_waitqueue_entry(wait_queue_t *q,
-				 struct task_struct *p)
+static inline void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p)
 {
 #if WAITQUEUE_DEBUG
 	if (!q || !p)
diff -urN linux-2.4.2-pre1/include/net/irda/irda.h linux/include/net/irda/irda.h
--- linux-2.4.2-pre1/include/net/irda/irda.h	Mon Jan 29 23:25:32 2001
+++ linux/include/net/irda/irda.h	Mon Dec  3 22:27:49 2001
@@ -177,9 +177,10 @@
  */
 struct irda_skb_cb {
 	magic_t magic;       /* Be sure that we can trust the information */
-	__u32   speed;       /* The Speed this frame should be sent with */
+	__u32   next_speed;  /* The Speed to be set *after* this frame */
 	__u16   mtt;         /* Minimum turn around time */
 	__u16   xbofs;       /* Number of xbofs required, used by SIR mode */
+	__u16   next_xbofs;  /* Number of xbofs required *after* this frame */
 	void    *context;    /* May be used by drivers */
 	void    (*destructor)(struct sk_buff *skb); /* Used for flow control */
 	__u16   xbofs_delay; /* Number of xbofs used for generating the mtt */
diff -urN linux-2.4.2-pre1/include/net/irda/irda_device.h linux/include/net/irda/irda_device.h
--- linux-2.4.2-pre1/include/net/irda/irda_device.h	Mon Jan 29 23:24:54 2001
+++ linux/include/net/irda/irda_device.h	Mon Dec  3 22:27:49 2001
@@ -218,29 +218,54 @@
 #endif
 
 /*
- * Function irda_get_speed (skb)
+ * Function irda_get_next_speed (skb)
  *
- *    Extact the speed this frame should be sent out with from the skb
+ *    Extract the speed that should be set *after* this frame from the skb
  *
+ * Note : return -1 for user space frames
  */
-#define irda_get_speed(skb) (	                                        \
+#define irda_get_next_speed(skb) (	                                        \
 	(((struct irda_skb_cb*) skb->cb)->magic == LAP_MAGIC) ? 	\
-                  ((struct irda_skb_cb *)(skb->cb))->speed : 9600 	\
+                  ((struct irda_skb_cb *)(skb->cb))->next_speed : -1 	\
 )
 
 #if 0
-extern inline __u32 irda_get_speed(struct sk_buff *skb)
+extern inline __u32 irda_get_next_speed(struct sk_buff *skb)
 {
 	__u32 speed;
 
 	if (((struct irda_skb_cb *)(skb->cb))->magic != LAP_MAGIC)
-		speed = 9600;
+		speed = -1;
 	else
-		speed = ((struct irda_skb_cb *)(skb->cb))->speed;
+		speed = ((struct irda_skb_cb *)(skb->cb))->next_speed;
 
 	return speed;
 }
 #endif
+
+/*
+ * Function irda_get_next_xbofs (skb)
+ *
+ *    Extract the xbofs that should be set for this frame from the skb
+ *
+ * Note : default to 10 for user space frames
+ */
+#define irda_get_xbofs(skb) (	                                        \
+	(((struct irda_skb_cb*) skb->cb)->magic == LAP_MAGIC) ? 	\
+                  ((struct irda_skb_cb *)(skb->cb))->xbofs : 10 	\
+)
+
+/*
+ * Function irda_get_next_xbofs (skb)
+ *
+ *    Extract the xbofs that should be set *after* this frame from the skb
+ *
+ * Note : return -1 for user space frames
+ */
+#define irda_get_next_xbofs(skb) (	                                        \
+	(((struct irda_skb_cb*) skb->cb)->magic == LAP_MAGIC) ? 	\
+                  ((struct irda_skb_cb *)(skb->cb))->next_xbofs : -1 	\
+)
 
 #endif /* IRDA_DEVICE_H */
 
diff -urN linux-2.4.2-pre1/include/net/irda/irlap.h linux/include/net/irda/irlap.h
--- linux-2.4.2-pre1/include/net/irda/irlap.h	Mon Jan 29 23:24:54 2001
+++ linux/include/net/irda/irlap.h	Mon Dec  3 22:27:49 2001
@@ -168,7 +168,7 @@
 	hashbin_t   *discovery_log;
  	discovery_t *discovery_cmd;
 
-	__u32 speed; 
+	__u32 speed;		/* Link speed */
 
 	struct qos_info  qos_tx;   /* QoS requested by peer */
 	struct qos_info  qos_rx;   /* QoS requested by self */
@@ -179,6 +179,7 @@
 	int    mtt_required;  /* Minumum turnaround time required */
 	int    xbofs_delay;   /* Nr of XBOF's used to MTT */
 	int    bofs_count;    /* Negotiated extra BOFs */
+	int    next_bofs;     /* Negotiated extra BOFs after next frame */
 
 #ifdef CONFIG_IRDA_COMPRESSION
 	struct irda_compressor compressor;
@@ -237,7 +238,7 @@
 
 void irlap_init_qos_capabilities(struct irlap_cb *, struct qos_info *);
 void irlap_apply_default_connection_parameters(struct irlap_cb *self);
-void irlap_apply_connection_parameters(struct irlap_cb *self);
+void irlap_apply_connection_parameters(struct irlap_cb *self, int now);
 void irlap_set_local_busy(struct irlap_cb *self, int status);
 
 #define IRLAP_GET_HEADER_SIZE(self) 2 /* Will be different when we get VFIR */
diff -urN linux-2.4.2-pre1/include/net/irda/irlap_frame.h linux/include/net/irda/irlap_frame.h
--- linux-2.4.2-pre1/include/net/irda/irlap_frame.h	Mon Jan 29 23:24:54 2001
+++ linux/include/net/irda/irlap_frame.h	Mon Dec  3 22:27:49 2001
@@ -110,6 +110,7 @@
 	__u8  ncaddr;
 } PACK;
 
+void irlap_queue_xmit(struct irlap_cb *self, struct sk_buff *skb);
 void irlap_send_discovery_xid_frame(struct irlap_cb *, int S, __u8 s, 
 				    __u8 command, discovery_t *discovery);
 void irlap_send_snrm_frame(struct irlap_cb *, struct qos_info *);
diff -urN linux-2.4.2-pre1/include/net/irda/qos.h linux/include/net/irda/qos.h
--- linux-2.4.2-pre1/include/net/irda/qos.h	Mon Jan 29 23:25:32 2001
+++ linux/include/net/irda/qos.h	Mon Dec  3 22:27:49 2001
@@ -100,10 +100,19 @@
 
 __u32 irlap_max_line_capacity(__u32 speed, __u32 max_turn_time);
 __u32 irlap_requested_line_capacity(struct qos_info *qos);
-__u32 irlap_min_turn_time_in_bytes(__u32 speed, __u32 min_turn_time);
 
 int msb_index(__u16 byte);
 void irda_qos_bits_to_value(struct qos_info *qos);
+
+/* So simple, how could we not inline those two ?
+ * Note : one byte is 10 bits if you include start and stop bits
+ * Jean II */
+#define irlap_min_turn_time_in_bytes(speed, min_turn_time) (	\
+	speed * min_turn_time / 10000000			\
+)
+#define irlap_xbofs_in_usec(speed, xbofs) (			\
+	xbofs * 10000000 / speed				\
+)
 
 #endif
 
diff -urN linux-2.4.2-pre1/kernel/printk.c linux/kernel/printk.c
--- linux-2.4.2-pre1/kernel/printk.c	Sat Dec 30 18:16:13 2000
+++ linux/kernel/printk.c	Mon Dec  3 22:27:49 2001
@@ -125,9 +125,8 @@
 	unsigned long i, j, limit, count;
 	int do_clear = 0;
 	char c;
-	int error = -EPERM;
+	int error = 0;
 
-	error = 0;
 	switch (type) {
 	case 0:		/* Close log */
 		break;
diff -urN linux-2.4.2-pre1/kernel/sched.c linux/kernel/sched.c
--- linux-2.4.2-pre1/kernel/sched.c	Mon Jan 15 13:08:15 2001
+++ linux/kernel/sched.c	Mon Dec  3 22:27:49 2001
@@ -326,9 +326,10 @@
  * "current->state = TASK_RUNNING" to mark yourself runnable
  * without the overhead of this.
  */
-inline void wake_up_process(struct task_struct * p)
+static inline int try_to_wake_up(struct task_struct * p, int synchronous)
 {
 	unsigned long flags;
+	int success = 0;
 
 	/*
 	 * We want the common case fall through straight, thus the goto.
@@ -338,25 +339,17 @@
 	if (task_on_runqueue(p))
 		goto out;
 	add_to_runqueue(p);
-	reschedule_idle(p);
+	if (!synchronous)
+		reschedule_idle(p);
+	success = 1;
 out:
 	spin_unlock_irqrestore(&runqueue_lock, flags);
+	return success;
 }
 
-static inline void wake_up_process_synchronous(struct task_struct * p)
+inline int wake_up_process(struct task_struct * p)
 {
-	unsigned long flags;
-
-	/*
-	 * We want the common case fall through straight, thus the goto.
-	 */
-	spin_lock_irqsave(&runqueue_lock, flags);
-	p->state = TASK_RUNNING;
-	if (task_on_runqueue(p))
-		goto out;
-	add_to_runqueue(p);
-out:
-	spin_unlock_irqrestore(&runqueue_lock, flags);
+	return try_to_wake_up(p, 0);
 }
 
 static void process_timeout(unsigned long __data)
@@ -689,64 +682,59 @@
 	return;
 }
 
+/*
+ * The core wakeup function.  Non-exclusive wakeups (nr_exclusive == 0) just wake everything
+ * up.  If it's an exclusive wakeup (nr_exclusive == small +ve number) then we wake all the
+ * non-exclusive tasks and one exclusive task.
+ *
+ * There are circumstances in which we can try to wake a task which has already
+ * started to run but is not in state TASK_RUNNING.  try_to_wake_up() returns zero
+ * in this (rare) case, and we handle it by contonuing to scan the queue.
+ */
 static inline void __wake_up_common (wait_queue_head_t *q, unsigned int mode,
 			 	     int nr_exclusive, const int sync)
 {
 	struct list_head *tmp, *head;
 	struct task_struct *p;
-	unsigned long flags;
 
-	if (!q)
-		goto out;
-
-	wq_write_lock_irqsave(&q->lock, flags);
-
-#if WAITQUEUE_DEBUG
 	CHECK_MAGIC_WQHEAD(q);
-#endif
-
 	head = &q->task_list;
-#if WAITQUEUE_DEBUG
-        if (!head->next || !head->prev)
-                WQ_BUG();
-#endif
+	WQ_CHECK_LIST_HEAD(head);
 	tmp = head->next;
 	while (tmp != head) {
 		unsigned int state;
                 wait_queue_t *curr = list_entry(tmp, wait_queue_t, task_list);
 
 		tmp = tmp->next;
-
-#if WAITQUEUE_DEBUG
 		CHECK_MAGIC(curr->__magic);
-#endif
 		p = curr->task;
 		state = p->state;
 		if (state & mode) {
-#if WAITQUEUE_DEBUG
-			curr->__waker = (long)__builtin_return_address(0);
-#endif
-			if (sync)
-				wake_up_process_synchronous(p);
-			else
-				wake_up_process(p);
-			if ((curr->flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive)
+			WQ_NOTE_WAKER(curr);
+			if (try_to_wake_up(p, sync) && curr->flags && !--nr_exclusive)
 				break;
 		}
 	}
-	wq_write_unlock_irqrestore(&q->lock, flags);
-out:
-	return;
 }
 
 void __wake_up(wait_queue_head_t *q, unsigned int mode, int nr)
 {
-	__wake_up_common(q, mode, nr, 0);
+	if (q) {
+		unsigned long flags;
+		wq_read_lock_irqsave(&q->lock, flags);
+		__wake_up_common(q, mode, nr, 0);
+		wq_read_unlock_irqrestore(&q->lock, flags);
+	}
 }
 
 void __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr)
 {
-	__wake_up_common(q, mode, nr, 1);
+	if (q) {
+		unsigned long flags;
+		wq_read_lock_irqsave(&q->lock, flags);
+		__wake_up_common(q, mode, nr, 1);
+		wq_read_unlock_irqrestore(&q->lock, flags);
+	}
 }
 
 #define	SLEEP_ON_VAR				\
diff -urN linux-2.4.2-pre1/kernel/sysctl.c linux/kernel/sysctl.c
--- linux-2.4.2-pre1/kernel/sysctl.c	Fri Dec 29 14:07:24 2000
+++ linux/kernel/sysctl.c	Mon Dec  3 22:27:49 2001
@@ -130,9 +130,6 @@
 static void unregister_proc_table(ctl_table *, struct proc_dir_entry *);
 #endif
 
-extern int inodes_stat[];
-extern int dentry_stat[];
-
 /* The default sysctl tables: */
 
 static ctl_table root_table[] = {
diff -urN linux-2.4.2-pre1/mm/memory.c linux/mm/memory.c
--- linux-2.4.2-pre1/mm/memory.c	Mon Dec  3 22:27:36 2001
+++ linux/mm/memory.c	Mon Dec  3 22:27:49 2001
@@ -858,6 +858,8 @@
 		UnlockPage(old_page);
 		/* FallThrough */
 	case 1:
+		if (PageReserved(old_page))
+			break;
 		flush_cache_page(vma, address);
 		establish_pte(vma, address, page_table, pte_mkyoung(pte_mkdirty(pte_mkwrite(pte))));
 		spin_unlock(&mm->page_table_lock);
diff -urN linux-2.4.2-pre1/mm/mmap.c linux/mm/mmap.c
--- linux-2.4.2-pre1/mm/mmap.c	Mon Jan 29 08:10:41 2001
+++ linux/mm/mmap.c	Mon Dec  3 22:27:49 2001
@@ -12,6 +12,7 @@
 #include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/file.h>
+#include <linux/fs.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgalloc.h>
@@ -63,6 +64,15 @@
 	free += atomic_read(&page_cache_size);
 	free += nr_free_pages();
 	free += nr_swap_pages;
+	/*
+	 * The code below doesn't account for free space in the inode
+	 * and dentry slab cache, slab cache fragmentation, inodes and
+	 * dentries which will become freeable under VM load, etc.
+	 * Lets just hope all these (complex) factors balance out...
+	 */
+	free += (dentry_stat.nr_unused * sizeof(struct dentry)) >> PAGE_SHIFT;
+	free += (inodes_stat.nr_unused * sizeof(struct inode)) >> PAGE_SHIFT;
+
 	return free > pages;
 }
 
diff -urN linux-2.4.2-pre1/net/ipv4/netfilter/ip_fw_compat.c linux/net/ipv4/netfilter/ip_fw_compat.c
--- linux-2.4.2-pre1/net/ipv4/netfilter/ip_fw_compat.c	Mon Sep 18 15:09:55 2000
+++ linux/net/ipv4/netfilter/ip_fw_compat.c	Mon Dec  3 22:27:49 2001
@@ -132,7 +132,7 @@
 		if (ret == FW_ACCEPT || ret == FW_SKIP) {
 			if (fwops->fw_acct_out)
 				fwops->fw_acct_out(fwops, PF_INET,
-						   (struct net_device *)in,
+						   (struct net_device *)out,
 						   (*pskb)->nh.raw, &redirpt,
 						   pskb);
 			confirm_connection(*pskb);
diff -urN linux-2.4.2-pre1/net/irda/irlan/irlan_client.c linux/net/irda/irlan/irlan_client.c
--- linux-2.4.2-pre1/net/irda/irlan/irlan_client.c	Sat Nov 11 18:11:23 2000
+++ linux/net/irda/irlan/irlan_client.c	Mon Dec  3 22:27:49 2001
@@ -120,8 +120,9 @@
 			return;
 	}
 
-	/* Address may have changed! */
+	/* Addresses may have changed! */
 	self->saddr = saddr;
+	self->daddr = daddr;
 
 	if (self->disconnect_reason == LM_USER_REQUEST) {
 			IRDA_DEBUG(0, __FUNCTION__ "(), still stopped by user\n");
diff -urN linux-2.4.2-pre1/net/irda/irlan/irlan_eth.c linux/net/irda/irlan/irlan_eth.c
--- linux-2.4.2-pre1/net/irda/irlan/irlan_eth.c	Sat Nov 11 18:11:23 2000
+++ linux/net/irda/irlan/irlan_eth.c	Mon Dec  3 22:27:49 2001
@@ -61,6 +61,7 @@
 	dev->hard_start_xmit    = irlan_eth_xmit; 
 	dev->get_stats	        = irlan_eth_get_stats;
 	dev->set_multicast_list = irlan_eth_set_multicast_list;
+	dev->features          |= NETIF_F_DYNALLOC;
 
 	ether_setup(dev);
 	
diff -urN linux-2.4.2-pre1/net/irda/irlap.c linux/net/irda/irlap.c
--- linux-2.4.2-pre1/net/irda/irlap.c	Sat Nov 11 18:11:23 2000
+++ linux/net/irda/irlap.c	Mon Dec  3 22:27:49 2001
@@ -998,7 +998,7 @@
 }
 
 /*
- * Function irlap_apply_default_connection_parameters (void)
+ * Function irlap_apply_default_connection_parameters (void, now)
  *
  *    Use the default connection and transmission parameters
  * 
@@ -1010,14 +1010,16 @@
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
 
+	/* xbofs : Default value in NDM */
+	self->next_bofs   = 12;
+	self->bofs_count  = 12;
+
+	/* NDM Speed is 9600 */
 	irlap_change_speed(self, 9600, TRUE);
 
 	/* Set mbusy when going to NDM state */
 	irda_device_set_media_busy(self->netdev, TRUE);
 
-	/* Default value in NDM */
-	self->bofs_count = 12;
-
 	/* 
 	 * Generate random connection address for this session, which must
 	 * be 7 bits wide and different from 0x00 and 0xfe 
@@ -1056,23 +1058,31 @@
 }
 
 /*
- * Function irlap_apply_connection_parameters (qos)
+ * Function irlap_apply_connection_parameters (qos, now)
  *
  *    Initialize IrLAP with the negotiated QoS values
  *
+ * If 'now' is false, the speed and xbofs will be changed after the next
+ * frame is sent.
+ * If 'now' is true, the speed and xbofs is changed immediately
  */
-void irlap_apply_connection_parameters(struct irlap_cb *self) 
+void irlap_apply_connection_parameters(struct irlap_cb *self, int now) 
 {
 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 	
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
 
-	irlap_change_speed(self, self->qos_tx.baud_rate.value, FALSE);
+	/* Set the negociated xbofs value */
+	self->next_bofs   = self->qos_tx.additional_bofs.value;
+	if(now)
+		self->bofs_count = self->next_bofs;
+
+	/* Set the negociated link speed (may need the new xbofs value) */
+	irlap_change_speed(self, self->qos_tx.baud_rate.value, now);
 
 	self->window_size = self->qos_tx.window_size.value;
 	self->window      = self->qos_tx.window_size.value;
-	self->bofs_count  = self->qos_tx.additional_bofs.value;
 
 	/*
 	 *  Calculate how many bytes it is possible to transmit before the
diff -urN linux-2.4.2-pre1/net/irda/irlap_event.c linux/net/irda/irlap_event.c
--- linux-2.4.2-pre1/net/irda/irlap_event.c	Mon Nov 27 18:07:31 2000
+++ linux/net/irda/irlap_event.c	Mon Dec  3 22:27:49 2001
@@ -684,25 +684,26 @@
 
 		irlap_initiate_connection_state(self);
 
-#if 0
 		/* 
-		 * We are allowed to send two frames, but this may increase
-		 * the connect latency, so lets not do it for now.
+		 * Applying the parameters now will make sure we change speed
+		 * *after* we have sent the next frame
 		 */
-		irlap_send_ua_response_frame(self, &self->qos_rx);
-#endif
+		irlap_apply_connection_parameters(self, FALSE);
 
 		/* 
-		 * Applying the parameters now will make sure we change speed
-		 * after we have sent the next frame
+		 * Sending this frame will force a speed change after it has
+		 * been sent (i.e. the frame will be sent at 9600).
 		 */
-		irlap_apply_connection_parameters(self);
+		irlap_send_ua_response_frame(self, &self->qos_rx);
 
+#if 0
 		/* 
-		 * Sending this frame will force a speed change after it has
-		 * been sent
+		 * We are allowed to send two frames, but this may increase
+		 * the connect latency, so lets not do it for now.
 		 */
+		/* What the hell is this ? - Jean II */
 		irlap_send_ua_response_frame(self, &self->qos_rx);
+#endif
 
 		/*
 		 *  The WD-timer could be set to the duration of the P-timer 
@@ -794,8 +795,9 @@
 
 			irlap_qos_negotiate(self, skb);
 			
+			/* Send UA frame and then change link settings */
+			irlap_apply_connection_parameters(self, FALSE);
 			irlap_send_ua_response_frame(self, &self->qos_rx);
-			irlap_apply_connection_parameters(self);
 
 			irlap_next_state(self, LAP_NRM_S);
 			irlap_connect_confirm(self, skb);
@@ -827,10 +829,19 @@
 
 		irlap_qos_negotiate(self, skb);
 
-		irlap_apply_connection_parameters(self);
+		/* Set the new link setting *now* (before the rr frame) */
+		irlap_apply_connection_parameters(self, TRUE);
 		self->retry_count = 0;
 		
-		/* This frame will actually force the speed change */
+		/* Wait for turnaround time to give a chance to the other
+		 * device to be ready to receive us.
+		 * Note : the time to switch speed is typically larger
+		 * than the turnaround time, but as we don't have the other
+		 * side speed switch time, that's our best guess...
+		 * Jean II */
+		irlap_wait_min_turn_around(self, &self->qos_tx);
+
+		/* This frame will actually be sent at the new speed */
 		irlap_send_rr_frame(self, CMD_FRAME);
 
 		irlap_start_final_timer(self, self->final_timeout/2);
@@ -991,7 +1002,8 @@
 	case RECV_UA_RSP: /* FALLTHROUGH */
 	case RECV_DM_RSP:
 		del_timer(&self->final_timer);
-		
+
+		/* Set new link parameters */
 		irlap_apply_default_connection_parameters(self);
 
 		/* Always switch state before calling upper layers */
@@ -1944,10 +1956,13 @@
 		/* Always switch state before calling upper layers */
 		irlap_next_state(self, LAP_NDM);
 
+		/* Send disconnect response */
 		irlap_wait_min_turn_around(self, &self->qos_tx);
 		irlap_send_ua_response_frame(self, NULL);
+
 		del_timer(&self->wd_timer);
 		irlap_flush_all_queues(self);
+		/* Set default link parameters */
 		irlap_apply_default_connection_parameters(self);
 
 		irlap_disconnect_indication(self, LAP_DISC_INDICATION);
@@ -2000,10 +2015,13 @@
 	case RECV_DISC_CMD:
 		/* Always switch state before calling upper layers */
 		irlap_next_state(self, LAP_NDM);
-		
+
+		/* Send disconnect response */
 		irlap_wait_min_turn_around(self, &self->qos_tx);
 		irlap_send_ua_response_frame(self, NULL);
+
 		del_timer(&self->wd_timer);
+		/* Set default link parameters */
 		irlap_apply_default_connection_parameters(self);
 
 		irlap_disconnect_indication(self, LAP_DISC_INDICATION);
diff -urN linux-2.4.2-pre1/net/irda/irlap_frame.c linux/net/irda/irlap_frame.c
--- linux-2.4.2-pre1/net/irda/irlap_frame.c	Sat Nov 11 18:11:23 2000
+++ linux/net/irda/irlap_frame.c	Mon Dec  3 22:27:49 2001
@@ -60,7 +60,7 @@
 	 */
 	cb->magic = LAP_MAGIC;
 	cb->mtt = self->mtt_required;
-	cb->speed = self->speed;
+	cb->next_speed = self->speed;
 
 	/* Reset */
 	self->mtt_required = 0;
@@ -70,10 +70,13 @@
 	 * force the negotiated minimum turnaround time 
 	 */
 	cb->xbofs = self->bofs_count;
+	cb->next_xbofs = self->next_bofs;
 	cb->xbofs_delay = self->xbofs_delay;
 	
 	/* Reset XBOF's delay (used only for getting min turn time) */
 	self->xbofs_delay = 0;
+	/* Put the correct xbofs value for the next packet */
+	self->bofs_count = self->next_bofs;
 }
 
 /*
diff -urN linux-2.4.2-pre1/net/irda/irttp.c linux/net/irda/irttp.c
--- linux-2.4.2-pre1/net/irda/irttp.c	Sat Nov 11 18:11:23 2000
+++ linux/net/irda/irttp.c	Mon Dec  3 22:27:49 2001
@@ -139,6 +139,15 @@
 	ASSERT(irttp != NULL, return NULL;);
 	ASSERT(irttp->magic == TTP_MAGIC, return NULL;);
 
+	/* The IrLMP spec (IrLMP 1.1 p10) says that we have the right to
+	 * use only 0x01-0x6F. Of course, we can use LSAP_ANY as well.
+	 * JeanII */
+	if((stsap_sel != LSAP_ANY) &&
+	   ((stsap_sel < 0x01) || (stsap_sel >= 0x70))) {
+		IRDA_DEBUG(0, __FUNCTION__ "(), invalid tsap!\n");
+		return NULL;
+	}
+
 	self = kmalloc(sizeof(struct tsap_cb), GFP_ATOMIC);
 	if (self == NULL) {
 		IRDA_DEBUG(0, __FUNCTION__ "(), unable to kmalloc!\n");
@@ -1564,9 +1573,9 @@
 			       self->remote_credit);
 		len += sprintf(buf+len, "send credit: %d\n",
 			       self->send_credit);
-		len += sprintf(buf+len, "  tx packets: %d, ",
+		len += sprintf(buf+len, "  tx packets: %ld, ",
 			       self->stats.tx_packets);
-		len += sprintf(buf+len, "rx packets: %d, ",
+		len += sprintf(buf+len, "rx packets: %ld, ",
 			       self->stats.rx_packets);
 		len += sprintf(buf+len, "tx_queue len: %d ", 
 			       skb_queue_len(&self->tx_queue));
diff -urN linux-2.4.2-pre1/net/irda/qos.c linux/net/irda/qos.c
--- linux-2.4.2-pre1/net/irda/qos.c	Sat Nov 11 18:11:23 2000
+++ linux/net/irda/qos.c	Mon Dec  3 22:27:49 2001
@@ -70,10 +70,6 @@
 				       int get);
 static int irlap_param_min_turn_time(void *instance, irda_param_t *param, 
 				     int get);
-static int value_index(__u32 value, __u32 *array, int size);
-static __u32 byte_value(__u8 byte, __u32 *array);
-static __u32 index_value(int index, __u32 *array);
-static int value_lower_bits(__u32 value, __u32 *array, int size, __u16 *field);
 
 __u32 min_turn_times[]  = { 10000, 5000, 1000, 500, 100, 50, 10, 0 }; /* us */
 __u32 baud_rates[]      = { 2400, 9600, 19200, 38400, 57600, 115200, 576000, 
@@ -130,6 +126,98 @@
 
 static pi_param_info_t irlap_param_info = { pi_major_call_table, 2, 0x7f, 7 };
 
+/* ---------------------- LOCAL SUBROUTINES ---------------------- */
+/* Note : we start with a bunch of local subroutines.
+ * As the compiler is "one pass", this is the only way to get them to
+ * inline properly...
+ * Jean II
+ */
+/*
+ * Function value_index (value, array, size)
+ *
+ *    Returns the index to the value in the specified array
+ */
+static inline int value_index(__u32 value, __u32 *array, int size)
+{
+	int i;
+	
+	for (i=0; i < size; i++)
+		if (array[i] == value)
+			break;
+	return i;
+}
+
+/*
+ * Function index_value (index, array)
+ *
+ *    Returns value to index in array, easy!
+ *
+ */
+static inline __u32 index_value(int index, __u32 *array) 
+{
+	return array[index];
+}
+
+/*
+ * Function msb_index (word)
+ *
+ *    Returns index to most significant bit (MSB) in word
+ *
+ */
+int msb_index (__u16 word) 
+{
+	__u16 msb = 0x8000;
+	int index = 15;   /* Current MSB */
+	
+	while (msb) {
+		if (word & msb)
+			break;   /* Found it! */
+		msb >>=1;
+		index--;
+	}
+	return index;
+}
+
+static inline __u32 byte_value(__u8 byte, __u32 *array) 
+{
+	int index;
+
+	ASSERT(array != NULL, return -1;);
+
+	index = msb_index(byte);
+
+	return index_value(index, array);
+}
+
+/*
+ * Function value_lower_bits (value, array)
+ *
+ *    Returns a bit field marking all possibility lower than value.
+ *    We may need a "value_higher_bits" in the future...
+ */
+static inline int value_lower_bits(__u32 value, __u32 *array, int size, __u16 *field)
+{
+	int	i;
+	__u16	mask = 0x1;
+	__u16	result = 0x0;
+
+	for (i=0; i < size; i++) {
+		/* Add the current value to the bit field, shift mask */
+		result |= mask;
+		mask <<= 1;
+		/* Finished ? */
+		if (array[i] >= value)
+			break;
+	}
+	/* Send back a valid index */
+	if(i >= size)
+	  i = size - 1;	/* Last item */
+	*field = result;
+	return i;
+}
+
+/* -------------------------- MAIN CALLS -------------------------- */
+
 /*
  * Function irda_qos_compute_intersection (qos, new)
  *
@@ -594,99 +682,6 @@
 		   line_capacity);
 	
 	return line_capacity;			       		  
-}
-
-__u32 irlap_min_turn_time_in_bytes(__u32 speed, __u32 min_turn_time)
-{
-	__u32 bytes;
-	
-	bytes = speed * min_turn_time / 10000000;
-	
-	return bytes;
-}
-
-static __u32 byte_value(__u8 byte, __u32 *array) 
-{
-	int index;
-
-	ASSERT(array != NULL, return -1;);
-
-	index = msb_index(byte);
-
-	return index_value(index, array);
-}
-
-/*
- * Function msb_index (word)
- *
- *    Returns index to most significant bit (MSB) in word
- *
- */
-int msb_index (__u16 word) 
-{
-	__u16 msb = 0x8000;
-	int index = 15;   /* Current MSB */
-	
-	while (msb) {
-		if (word & msb)
-			break;   /* Found it! */
-		msb >>=1;
-		index--;
-	}
-	return index;
-}
-
-/*
- * Function value_index (value, array, size)
- *
- *    Returns the index to the value in the specified array
- */
-static int value_index(__u32 value, __u32 *array, int size)
-{
-	int i;
-	
-	for (i=0; i < size; i++)
-		if (array[i] == value)
-			break;
-	return i;
-}
-
-/*
- * Function index_value (index, array)
- *
- *    Returns value to index in array, easy!
- *
- */
-static __u32 index_value(int index, __u32 *array) 
-{
-	return array[index];
-}
-
-/*
- * Function value_lower_bits (value, array)
- *
- *    Returns a bit field marking all possibility lower than value.
- *    We may need a "value_higher_bits" in the future...
- */
-static int value_lower_bits(__u32 value, __u32 *array, int size, __u16 *field)
-{
-	int	i;
-	__u16	mask = 0x1;
-	__u16	result = 0x0;
-
-	for (i=0; i < size; i++) {
-		/* Add the current value to the bit field, shift mask */
-		result |= mask;
-		mask <<= 1;
-		/* Finished ? */
-		if (array[i] >= value)
-			break;
-	}
-	/* Send back a valid index */
-	if(i >= size)
-	  i = size - 1;	/* Last item */
-	*field = result;
-	return i;
 }
 
 void irda_qos_bits_to_value(struct qos_info *qos)
diff -urN linux-2.4.2-pre1/scripts/Lindent linux/scripts/Lindent
--- linux-2.4.2-pre1/scripts/Lindent	Wed Dec 31 16:00:00 1969
+++ linux/scripts/Lindent	Mon Dec  3 22:27:49 2001
@@ -0,0 +1,2 @@
+#!/bin/bash
+indent -kr -i8 -ts8 -br -ce -bap -sob -l80 -pcs -cs -ss -bs -di1 -nbc -lp -psl $@
diff -urN linux-2.4.2-pre1/scripts/lxdialog/checklist.c linux/scripts/lxdialog/checklist.c
--- linux-2.4.2-pre1/scripts/lxdialog/checklist.c	Mon Feb  1 12:03:20 1999
+++ linux/scripts/lxdialog/checklist.c	Mon Dec  3 22:27:49 2001
@@ -51,6 +51,10 @@
     mvwaddch(win, choice, item_x, item[0]);
     wattrset (win, selected ? item_selected_attr : item_attr);
     waddstr (win, (char *)item+1);
+    if (selected) {
+    	wmove (win, choice, check_x+1);
+    	wrefresh (win);
+    }
 }
 
 /*
diff -urN linux-2.4.2-pre1/scripts/lxdialog/menubox.c linux/scripts/lxdialog/menubox.c
--- linux-2.4.2-pre1/scripts/lxdialog/menubox.c	Mon Feb  1 12:03:20 1999
+++ linux/scripts/lxdialog/menubox.c	Mon Dec  3 22:27:49 2001
@@ -91,6 +91,10 @@
     	wattrset (win, selected ? tag_key_selected_attr : tag_key_attr);
     	mvwaddch(win, choice, item_x+j, menu_item[j]);
     }
+    if (selected) {
+	wmove (win, choice, item_x+1);
+	wrefresh (win);
+    }
 }
 
 /*
@@ -267,9 +271,11 @@
 		 box_y, box_x+item_x+1, menu_height);
 
     print_buttons (dialog, height, width, 0);
+    wmove (menu, choice, item_x+1);
+    wrefresh (menu);
 
     while (key != ESC) {
-	key = wgetch(dialog);
+	key = wgetch(menu);
 
 	if (key < 256 && isalpha(key)) key = tolower(key);
 
@@ -372,8 +378,8 @@
             print_arrows(dialog, item_no, scroll,
                          box_y, box_x+item_x+1, menu_height);
 
-            wnoutrefresh (menu);
-            wrefresh (dialog);
+            wnoutrefresh (dialog);
+            wrefresh (menu);
 
 	    continue;		/* wait for another key press */
         }
@@ -386,7 +392,7 @@
 			? 2 : (button > 2 ? 0 : button);
 
 	    print_buttons(dialog, height, width, button);
-	    wrefresh (dialog);
+	    wrefresh (menu);
 	    break;
 	case ' ':
 	case 's':
diff -urN linux-2.4.2-pre1/scripts/makelst linux/scripts/makelst
--- linux-2.4.2-pre1/scripts/makelst	Mon Sep 18 14:59:23 2000
+++ linux/scripts/makelst	Mon Dec  3 22:27:49 2001
@@ -2,7 +2,8 @@
 # A script to dump mixed source code & assembly
 # with correct relocations from System.map
 # Requires the following lines in Rules.make.
-#
+# Author(s): DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) 
+#            William Stearns <wstearns@pobox.com>
 #%.lst: %.c
 #	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -g -c -o $*.o $<
 #	$(TOPDIR)/scripts/makelst $* $(TOPDIR) $(OBJDUMP)
@@ -16,6 +17,6 @@
 t3=`grep $t2 $2/System.map`
 t4=`echo $t3 | gawk '{ print $1 }'`
 t5=`echo $t1 | gawk '{ print $1 }'`
-t6=`echo $t4 - $t5 | sed s/a/A/g | sed s/b/B/g | sed s/c/C/g | sed s/d/D/g | sed s/e/E/g | sed s/f/F/g`
+t6=`echo $t4 - $t5 | sed -e s/a/A/g -e s/b/B/g -e s/c/C/g -e s/d/D/g -e s/e/E/g -e s/f/F/g`
 t7=`( echo  ibase=16 ; echo $t6 ) | bc`
 $3 --source --adjust-vma=$t7 $2/$1.o > $2/$1.lst
