diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/CREDITS linux-bk/CREDITS
--- linux-2.4.19/CREDITS	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/CREDITS	2002-08-17 00:48:53.000000000 +0000
@@ -704,6 +704,11 @@
 S: Warrendale, Pennsylvania 15086
 S: USA
 
+N: Martin Devera
+E: devik@cdi.cz
+W: http://luxik.cdi.cz/~devik/qos/
+D: HTB qdisc and random networking hacks
+
 N: Alex deVries
 E: adevries@thepuffingroup.com
 D: Various SGI parts, bits of HAL2 and Newport, PA-RISC Linux.
@@ -1329,6 +1334,12 @@
 S: Provo, Utah 84606-5607
 S: USA
 
+N: Marcel Holtmann
+E: marcel@holtmann.org
+W: http://www.holtmann.org
+D: Author of the Linux Bluetooth Subsystem PC Card drivers
+S: Germany
+
 N: Rob W. W. Hooft
 E: hooft@EMBL-Heidelberg.DE
 D: Shared libs for graphics-tools and for the f2c compiler
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/Changes linux-bk/Documentation/Changes
--- linux-2.4.19/Documentation/Changes	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/Changes	2002-08-17 00:49:13.000000000 +0000
@@ -55,7 +55,7 @@
 o  modutils               2.4.2                   # insmod -V
 o  e2fsprogs              1.25                    # tune2fs
 o  jfsutils               1.0.12                  # fsck.jfs -V
-o  reiserfsprogs          3.x.1b                  # reiserfsck 2>&1|grep reiserfsprogs
+o  reiserfsprogs          3.6.3                   # reiserfsck 2>&1|grep reiserfsprogs
 o  pcmcia-cs              3.1.21                  # cardmgr -V
 o  PPP                    2.4.0                   # pppd --version
 o  isdn4k-utils           3.1pre1                 # isdnctrl 2>&1|grep version
@@ -225,7 +225,6 @@
 version v0.99.0 or higher. Running old versions may cause problems
 with programs using shared memory.
 
-
 Networking
 ==========
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/Configure.help linux-bk/Documentation/Configure.help
--- linux-2.4.19/Documentation/Configure.help	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/Configure.help	2002-08-17 00:49:13.000000000 +0000
@@ -2,10 +2,7 @@
 #	Eric S. Raymond <mailto:esr@thyrsus.com>
 #	Steven Cole <mailto:elenstev@mesatop.com>
 #
-# Version 3.00: current with 2.4.19
-#
-# This version of the Linux kernel configuration help texts
-# corresponds to kernel versions 2.4.x and 2.5.x.
+# Version 3.01: current with 2.4.19+
 #
 # Translations of this file available on the WWW:
 #
@@ -376,6 +373,12 @@
   Select this if you have a 32-bit processor and more than 4
   gigabytes of physical RAM.
 
+HIGHMEM I/O support
+CONFIG_HIGHIO
+  If you want to be able to do I/O to high memory pages, say Y.
+  Otherwise low memory pages are used as bounce buffers causing a
+  degrade in performance.
+
 Normal floppy disk support
 CONFIG_BLK_DEV_FD
   If you want to use the floppy disk drive(s) of your PC under Linux,
@@ -534,6 +537,17 @@
 
   If unsure, say N.
 
+Per partition statistics in /proc/partitions
+CONFIG_BLK_STATS
+  If you say yes here, your kernel will keep statistical information
+  for every partition. The information includes things as numbers of
+  read and write accesses, the number of merged requests etc.
+
+  This is required for the full functionality of sar(8) and interesting
+  if you want to do performance tuning, by tweaking the elevator, e.g.
+
+  If unsure, say N.
+
 ATA/IDE/MFM/RLL support
 CONFIG_IDE
   If you say Y here, your kernel will be able to manage low cost mass
@@ -1067,10 +1081,10 @@
   This effect can be also invoked by calling "idex=ata66"
   If unsure, say N.
 
-CMD64X chipset support
+CMD64X and CMD680 chipset support
 CONFIG_BLK_DEV_CMD64X
   Say Y here if you have an IDE controller which uses any of these
-  chipsets: CMD643, CMD646, or CMD648.
+  chipsets: CMD643, CMD646, CMD648, CMD649 or CMD680.
 
 CY82C693 chipset support
 CONFIG_BLK_DEV_CY82C693
@@ -2493,6 +2507,17 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+skb->pkt_type packet match support
+CONFIG_IP_NF_MATCH_PKTTYPE
+  This patch allows you to match packet in accrodance
+  to its "class", eg. BROADCAST, MULTICAST, ...
+  
+  Typical usage:
+  iptables -A INPUT -m pkttype --pkt-type broadcast -j LOG
+  
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
 MAC address match support
 CONFIG_IP_NF_MATCH_MAC
   MAC matching allows you to match packets based on the source
@@ -2543,6 +2568,28 @@
   If you want to compile it as a module, say M here and read
   Documentation/modules.txt.  If unsure, say `N'.
 
+DSCP match support
+CONFIG_IP_NF_TARGET_DSCP
+  This option adds a `DSCP' match, which allows you to match against
+  the IPv4 header DSCP field (DSCP codepoint).
+
+  The DSCP codepoint can have any value between 0x0 and 0x4f.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
+ 
+
+ECN match support
+CONFIG_IP_NF_MATCH_ECN
+  This option adds a `ECN' match, which allows you to match against
+  the IPv4 and TCP header ECN fields.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
+ 
+
 TOS match support
 CONFIG_IP_NF_MATCH_TOS
   TOS matching allows you to match packets based on the Type Of
@@ -2551,6 +2598,18 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+conntrack match support
+CONFIG_IP_NF_MATCH_CONNTRACK
+  This is a general conntrack match module, a superset of the state match.
+
+  It allows matching on additional conntrack information, which is
+  useful in complex configurations, such as NAT gateways with multiple
+  internet links or tunnels.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
+
 Connection state match support
 CONFIG_IP_NF_MATCH_STATE
   Connection state matching allows you to match packets based on their
@@ -2668,6 +2727,36 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+DSCP target support
+CONFIG_IP_NF_TARGET_DSCP
+  This option adds a `DSCP' target, which allows you to create rules in
+  the iptables mangle table. The selected packet has the DSCP field set
+  to the hex value provided on the command line; unlike the TOS target
+  which will only set the legal values within ip.h.
+
+  The DSCP field can be set to any value between 0x0 and 0x4f. It does
+  take into account that bits 6 and 7 are used by ECN.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
+ 
+
+ECN target support
+CONFIG_IP_NF_TARGET_ECN
+  This option adds a `ECN' target, which can be used in the iptables mangle
+  table.  
+
+  You can use this target to remove the ECN bits from the IPv4 header of
+  an IP packet.  This is particularly useful, if you need to work around
+  existing ECN blackholes on the internet, but don't want to disable
+  ECN support in general.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
+ 
+
 TOS target support
 CONFIG_IP_NF_TARGET_TOS
   This option adds a `TOS' target, which allows you to create rules in
@@ -2714,6 +2803,14 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+Helper match support
+CONFIG_IP_NF_MATCH_HELPER
+  Helper matching allows you to match packets in dynamic connections
+  tracked by a conntrack-helper, ie. ip_conntrack_ftp
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `Y'.
+
 TCPMSS match support
 CONFIG_IP_NF_MATCH_TCPMSS
   This option adds a `tcpmss' match, which allows you to examine the
@@ -2766,6 +2863,15 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+EUI64 address check (EXPERIMENTAL)
+CONFIG_IP6_NF_MATCH_EUI64
+  This module performs checking on the IPv6 source address
+  Compares the last 64 bits with the EUI64 (delivered
+  from the MAC address) address
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
 MAC address match support
 CONFIG_IP6_NF_MATCH_MAC
   mac matching allows you to match packets based on the source
@@ -2774,6 +2880,14 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+length match support
+CONFIG_IP6_NF_MATCH_LENGTH
+  This option allows you to match the length of a packet against a
+  specific value or range of values.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
 Netfilter MARK match support
 CONFIG_IP6_NF_MATCH_MARK
   Netfilter mark matching allows you to match packets based on the
@@ -9558,6 +9672,20 @@
   whenever you want).  If you want to compile it as a module, say M
   here and read <file:Documentation/modules.txt>.
 
+CONFIG_NET_SCH_HTB
+  Say Y here if you want to use the Hierarchical Token Buckets (HTB)
+  packet scheduling algorithm for some of your network devices. See
+  URL http://luxik.cdi.cz/~devik/qos/htb/ for complete manual and
+  in-depth articles.
+
+  HTB is very similar to the CBQ regarding its goals however is has 
+  different properties and different algorithm.
+
+  This code is also available as a module called sch_htb.o ( = code
+  which can be inserted in and removed from the running kernel
+  whenever you want).  If you want to compile it as a module, say M
+  here and read <file:Documentation/modules.txt>.
+
 CSZ packet scheduler
 CONFIG_NET_SCH_CSZ
   Say Y here if you want to use the Clark-Shenker-Zhang (CSZ) packet
@@ -10474,12 +10602,14 @@
   in case your mainboard has memory consistency issues.  If unsure,
   say N.
 
-Support for automatic channel equalization
+Support for uncommon RTL-8139 rev. K (automatic channel equalization)
 CONFIG_8139TOO_TUNE_TWISTER
-  This implements a function which might come in handy in case you are
-  using low quality on long cabling. It tries to match the transceiver
-  to the cable characteristics. This is experimental since hardly
-  documented by the manufacturer.  If unsure, say N.
+  This implements a function which might come in handy in case you
+  are using low quality on long cabling. It is required for RealTek
+  RTL-8139 revision K boards, and totally unused otherwise.  It tries
+  to match the transceiver to the cable characteristics. This is
+  experimental since hardly documented by the manufacturer.
+  If unsure, say Y.
 
 Support for older RTL-8129/8130 boards
 CONFIG_8139TOO_8129
@@ -10488,6 +10618,14 @@
   instead of an internal one.  Disabling this option will save some
   memory by making the code size smaller.  If unsure, say Y.
 
+Use older RX-reset method
+CONFIG_8139_OLD_RX_RESET
+  The 8139too driver was recently updated to contain a more rapid
+  reset sequence, in the face of severe receive errors.  This "new"
+  RX-reset method should be adequate for all boards.  But if you
+  experience problems, you can enable this option to restore the
+  old RX-reset behavior.  If unsure, say N.
+
 SiS 900/7016 PCI Fast Ethernet Adapter support
 CONFIG_SIS900
   This is a driver for the Fast Ethernet PCI network cards based on
@@ -13108,9 +13246,9 @@
   The module will be called wacom.o.  If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
 
-Aiptek 8000U tablet support
+Aiptek 6000U/8000U tablet support
 CONFIG_USB_AIPTEK
-  Say Y here if you want to use the USB version of the Aiptek 8000U
+  Say Y here if you want to use the USB version of the Aiptek 6000U/8000U
   tablet.  Make sure to say Y to "Event interface support"
   (CONFIG_INPUT_EVDEV) as well.
 
@@ -13242,7 +13380,6 @@
   inserted in and removed from the running kernel whenever you want).
   The module will be called audio.o. If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
-			
 
 USB Modem (CDC ACM) support
 CONFIG_USB_ACM
@@ -13951,15 +14088,24 @@
   The module will be called rio500.o. If you want to compile it as
   a module, say M here and read <file:Documentation/modules.txt>.
 
-USB Auerswald ISDN device support
-CONFIG_USB_AUERSWALD
-  Say Y here if you want to connect an Auerswald USB ISDN Device
-  to your computer's USB port.
+CONFIG_USB_TIGL
+  If you own a Texas Instruments graphing calculator and use a 
+  TI-GRAPH LINK USB cable (aka SilverLink), then you might be 
+  interested in this driver.
+
+  If you enable this driver, you will be able to communicate with
+  your calculator through a set of device nodes under /dev.
 
   This code is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
-  The module will be called auerswald.o. If you want to compile it as
-  a module, say M here and read <file:Documentation/modules.txt>.
+  The module will be called tiglusb.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
+
+  If you don't know what the SilverLink cable is or what a Texas
+  Instruments graphing calculator is, then you probably don't need this
+  driver.
+
+  If unsure, say N.
 
 Tieman Voyager USB Braille display support
 CONFIG_USB_BRLVOYAGER
@@ -14314,12 +14460,13 @@
 
 Publish some reiserfs-specific info under /proc/fs/reiserfs
 CONFIG_REISERFS_PROC_INFO
-  Create under /proc/fs/reiserfs hierarchy of files, displaying
-  various ReiserFS statistics and internal data on the expense of
-  making your kernel or module slightly larger (+8 KB).  This also
-  increases amount of kernel memory required for each mount.  Almost
-  everyone but ReiserFS developers and people fine-tuning reiserfs or
-  tracing problems should say N.
+  Create under /proc/fs/reiserfs a hierarchy of files, displaying
+  various ReiserFS statistics and internal data at the expense of making
+  your kernel or module slightly larger (+8 KB). This also increases the
+  amount of kernel memory required for each mount by 440 bytes.
+  It isn't useful to average persons, and you probably can't measure the
+  performance cost of it.  If you are fine-tuning reiserfs, say Y,
+  otherwise say N.
 
 Second extended fs support
 CONFIG_EXT2_FS
@@ -14884,13 +15031,10 @@
   If you would like to include the NFSv3 server as well as the NFSv2
   server, say Y here.  If unsure, say Y.
 
-Provide NFS over TCP server support DEVELOPER ONLY
+Provide NFS over TCP server support EXPERIMENTAL
 CONFIG_NFSD_TCP
-  If you are a developer and want to work on fixing problems with
-  NFS server over TCP support, say Y here.  If unsure, say N.
-
-  Some problems can be found by looking for FIXME in
-  <file:net/sunrpc/svcsock.c>.
+  Enable NFS service over TCP connections.  This the officially
+  still experimental, but seems to work well.
 
 OS/2 HPFS file system support
 CONFIG_HPFS_FS
@@ -15345,9 +15489,11 @@
 
 IBM disk label and partition support
 CONFIG_IBM_PARTITION
-  Say Y here if you would like to be able to read the hard disk
-  partition table format used by IBM DASD disks operating under CMS.
-  Otherwise, say N.
+  You have to say Y here if you would like to be able to read volume 
+  labels of IBM DASD disks. These can be ECKD DASD disks with 
+  compatible disk layout (cdl) and standard Linux disk layout (ldl), 
+  FBA DASD disks and CMS reserved minidisks.
+  Otherwise, say N and you will not be able to access these disks.
 
 ADFS file system support
 CONFIG_ADFS_FS
@@ -17929,20 +18075,6 @@
   computer, say `Y' here to support its built-in watchdog timer
   feature.  See the help for CONFIG_WATCHDOG for discussion.
 
-W83877F Watchdog Timer
-CONFIG_W83877F_WDT
-  This is the driver for the hardware watchdog on the W83877F chipset
-  as used in EMACS PC-104 motherboards (and likely others).  This
-  watchdog simply watches your kernel to make sure it doesn't freeze,
-  and if it does, it reboots your computer after a certain amount of
-  time.
-
-  This driver is also available as a module ( = code which can be
-  inserted in and removed from the running kernel whenever you want).
-  The module is called mixcomwd.o.  If you want to compile it as a
-  module, say M here and read <file:Documentation/modules.txt>.  Most
-  people will say N.
-
 ALi M7101 Watchdog Timer
 CONFIG_ALIM7101_WDT
   This is the driver for the hardware watchdog on the ALi M7101 PMU
@@ -19581,16 +19713,6 @@
   hardware debugging with a logic analyzer and need to see all traffic
   on the bus.
 
-AU1000 serial console
-CONFIG_AU1000_SERIAL_CONSOLE
-  If you have an Alchemy AU1000 processor (MIPS based) and you want
-  to use a console on a serial port, say Y.  Otherwise, say N.
-
-AU1000 serial support
-CONFIG_AU1000_UART
-  If you have an Alchemy AU1000 processor (MIPS based) and you want
-  to use serial ports, say Y.  Otherwise, say N.
-
 AU1000 ethernet controller on SGI MIPS system
 CONFIG_MIPS_AU1000_ENET
   If you have an Alchemy Semi AU1000 ethernet controller
@@ -20283,7 +20405,7 @@
 
 Kernel support for 32-bit ELF binaries
 CONFIG_BINFMT_ELF32
-  This allows you to run 32-bit Linux/ELF binaries on your Ultra.
+  This allows you to run 32-bit Linux/ELF binaries on your machine.
   Everybody wants this; say Y.
 
 Kernel support for 32-bit (ie. SunOS) a.out binaries
@@ -20369,7 +20491,7 @@
 DBRI Lowlevel Driver
 CONFIG_SPARCAUDIO_DBRI
   This driver supports the DBRI audio interface found on the SS10,
-  SS20, Sparcbook 3, and Voyager systems.
+  SS20, LX, Sparcbook 3, and Voyager systems.
 
 Dummy Lowlevel Driver
 CONFIG_SPARCAUDIO_DUMMY
@@ -20436,6 +20558,19 @@
   Say Y here to compile SCO support into the kernel or say M to
   compile it as module (sco.o).
 
+BNEP protocol support
+CONFIG_BLUEZ_BNEP
+  BNEP (Bluetooth Network Encapsulation Protocol) is Ethernet
+  emulation layer on top of Bluetooth. BNEP is required for Bluetooth
+  PAN (Personal Area Network).
+
+  To use BNEP, you will need user-space utilities provided in the 
+  BlueZ-PAN package.
+  For more information, see <http://bluez.sourceforge.net>.
+
+  Say Y here to compile BNEP support into the kernel or say M to
+  compile it as module (bnep.o).
+
 HCI UART driver
 CONFIG_BLUEZ_HCIUART
   Bluetooth HCI UART driver.
@@ -20464,18 +20599,9 @@
   Say Y here to compile support for Bluetooth USB devices into the
   kernel or say M to compile it as module (hci_usb.o).
 
-HCI USB firmware download support
-CONFIG_BLUEZ_USB_FW_LOAD
-  Firmware download support for Bluetooth USB devices.
-  This support is required for devices like Broadcom BCM2033.
-
-  HCI USB driver uses external firmware downloader program provided 
-  in BlueFW package.
-  For more information, see <http://bluez.sf.net/>.
-
 HCI USB zero packet support
 CONFIG_BLUEZ_USB_ZERO_PACKET
-  Support for USB zero packets. 
+  Support for USB zero packets.
   This option is provided only as a work around for buggy Bluetooth USB 
   devices. Do _not_ enable it unless you know for sure that your device 
   requires zero packets.
@@ -20494,11 +20620,37 @@
   Bluetooth HCI DTL1 (PC Card) driver.
   This driver provides support for Bluetooth PCMCIA devices with
   Nokia DTL1 interface:
-     Nokia Bluetooth PC Card, Socketcom Bluetooth CF module
+     Nokia Bluetooth Card
+     Socket Bluetooth CF Card
 
   Say Y here to compile support for HCI DTL1 devices into the
   kernel or say M to compile it as module (dtl1_cs.o).
 
+HCI BT3C (PC Card) device driver
+CONFIG_BLUEZ_HCIBT3C
+  Bluetooth HCI BT3C (PC Card) driver.
+  This driver provides support for Bluetooth PCMCIA devices with
+  3Com BT3C interface:
+     3Com Bluetooth Card (3CRWB6096)
+     HP Bluetooth Card
+
+  The HCI BT3C driver uses external firmware loader program provided in
+  the BlueFW package. For more information, see <http://bluez.sf.net>.
+
+  Say Y here to compile support for HCI BT3C devices into the
+  kernel or say M to compile it as module (bt3c_cs.o).
+
+HCI BlueCard (PC Card) device driver
+CONFIG_BLUEZ_HCIBLUECARD
+  Bluetooth HCI BlueCard (PC Card) driver.
+  This driver provides support for Bluetooth PCMCIA devices with
+  Anycom BlueCard interface:
+     Anycom Bluetooth PC Card
+     Anycom Bluetooth CF Card
+
+  Say Y here to compile support for HCI BlueCard devices into the
+  kernel or say M to compile it as module (bluecard_cs.o).
+
 # The following options are for Linux when running on the Hitachi
 # SuperH family of RISC microprocessors.
 
@@ -20931,12 +21083,6 @@
   Hades. This increases the SCSI transfer rates at least ten times
   compared to PIO transfers.
 
-Sun3 NCR5380 OBIO SCSI
-CONFIG_SUN3_SCSI
-  This option will enable support for the OBIO (onboard io) NCR5380
-  SCSI controller found in the Sun 3/50 and 3/60.  Note that this
-  driver does not provide support for VME SCSI boards.
-
 Sun3x ESP SCSI
 CONFIG_SUN3X_ESP
   This option will enable support for the ESP SCSI controller found
@@ -20990,11 +21136,6 @@
   General Linux information on the Sun 3 series (now discontinued)
   is at <http://www.angelfire.com/ca2/tech68k/sun3.html>.
 
-Sun3x ESP SCSI driver
-CONFIG_SUN3X_ESP
-  The ESP was an on-board SCSI controller used on Sun 3/80
-  machines.  Say Y here to compile in support for it.
-
 PCMCIA NE2000 and compatibles support
 CONFIG_APNE
   If you have a PCMCIA NE2000 compatible adapter, say Y.  Otherwise,
@@ -21005,19 +21146,6 @@
   want). The module is called apne.o. If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
 
-Sun3/Sun3x on-board LANCE support
-CONFIG_SUN3LANCE
-  This driver enables support for the on-board LANCE ethernet adapter
-  found on the Sun 3/50, 3/60, and 3/80 workstations.  If you have 
-  one of these workstations, and would like Ethernet, say Y. 
-  Otherwise, say N.
-
-Sun3 on-board Intel 82586 support
-CONFIG_SUN3_82586
-  This driver enables support for the on-board Intel 82586 based Ethernet
-  adapter found on Sun 3/1xx and 3/2xx motherboards.  Note that this driver
-  does not support 82586-based adapters on additional VME boards.
-
 Atari Lance support
 CONFIG_ATARILANCE
   Say Y to include support for several Atari Ethernet adapters based
@@ -22398,7 +22526,7 @@
   IPL device on another question, that pops up, when you select
   CONFIG_IPL.
 
-IPL from a /390 tape unit
+IPL from a S/390 tape unit
 CONFIG_IPL_TAPE
   Select this option if you want to IPL the image from a Tape.
 
@@ -22407,18 +22535,22 @@
   Select this option if you are running under VM/ESA and want 
   to IPL the image from the emulated card reader.
 
-Support for DASD hard disks
-CONFIG_DASD
-  Enable this option if you want to access DASDs directly utilizing
-  S/390s channel subsystem commands. This is necessary for running
-  natively on a single image or an LPAR.
+CONFIG_PFAULT
+  Select this option, if you want to use PFAULT pseudo page fault
+  handling under VM. If running native or in LPAR, this option
+  has no effect. If your VM does not support PFAULT, PAGEEX
+  pseudo page fault handling will be used.
+  Note that VM 4.2 supports PFAULT but has a bug in its
+  implementation that causes some problems.
+  Everybody who wants to run Linux under VM != VM4.2 should select
+  this option.
 
-Enable DASD fast write
-CONFIG_DASD_FAST_IO
-  Enable fast I/O for DASDs. That means that the next I/O command
-  is already issued at interrupt time, if an I/O request is pending.
-  This option gives significant speedup of I/O, because we don't
-  schedule the bottom-halves as often as Intel.
+CONFIG_SHARED_KERNEL
+  Select this option, if you want to share the text segment of the
+  Linux kernel between different VM guests. This reduces memory
+  usage with lots of guests but greatly increases kernel size.
+  You should only select this option if you know what you are
+  doing and want to exploit this feature.
 
 Support for IBM-style disk-labels (S/390)
 CONFIG_S390_PARTITION
@@ -22427,18 +22559,40 @@
   attached to another IBM mainframe operation system (OS/390, 
   VM/ESA, VSE/ESA).
 
+Support for DASD hard disks
+CONFIG_DASD
+  Enable this option if you want to access DASDs directly utilizing
+  S/390s channel subsystem commands. This is necessary for running
+  natively on a single image or an LPAR.
+
 Support for ECKD hard disks
 CONFIG_DASD_ECKD
-  ECKD devices are the most commonly used devices. You should enable
-  this option unless you are very sure you have no ECKD device.
+  ECKD (Extended Count Key Data) devices are the most commonly used 
+  devices on S/390s. You should enable this option unless you are 
+  very sure you have no ECKD device.
 
-CKD devices
-CONFIG_DASD_CKD
-  CKD devices are currently unsupported.
+ECKD demand loading
+CONFIG_DASD_AUTO_ECKD
+  This option enables demand loading of the ECKD module. 
 
 Support for FBA hard disks
 CONFIG_DASD_FBA
-  FBA devices are currently unsupported.
+  Select this option if you want to use FBA (Fixed Block) devices.
+  If you are not sure what it is, say "Y".
+
+FBA demand loading
+CONFIG_DASD_AUTO_FBA
+  This option enables demand loading of the FBA module. 
+
+Support for DIAG access to CMS reserved Disks
+CONFIG_DASD_DIAG
+  Select this option if you want to use CMS reserved Disks under VM
+  with the Diagnose250 command.  If you are not running under VM or
+  unsure what it is, say "N".
+
+DIAG demand loading
+CONFIG_DASD_AUTO_DIAG
+  This option enables demand loading of the DIAG module. 
 
 Merge some code into the kernel to make the image IPLable
 CONFIG_IPLABLE
@@ -22476,6 +22630,16 @@
   Include support for using an IBM HWC line-mode terminal as the Linux
   system console.
 
+Control Program Identification
+CONFIG_HWC_CPI
+  Allows for Control Program Identification via the HWC interface,
+  i.e. provides a mean to pass an OS instance name (system name)
+  to the machine.
+
+  This option should only be selected as a module since the
+  system name has to be passed as module parameter. The module
+  will be called hwc_cpi.o.
+
 S/390 tape device support
 CONFIG_S390_TAPE
   Select this option if you want to access channel-attached tape
@@ -22484,8 +22648,9 @@
   least one of the tape interface options and one of the tape
   hardware options in order to access a tape device.
   This option is also available as a module. The module will be
-  called tape390.o and include all selected interfaces and
-  hardware drivers.
+  called tape390.o and include all selected interfaces.
+  The hardware drivers will be seperate modules.
+  If unsure, say "Y".
 
 Support for tape character devices
 CONFIG_S390_TAPE_CHAR
@@ -22506,14 +22671,23 @@
 
 Support for 3490 tape hardware
 CONFIG_S390_TAPE_3490
-  Select this option if you want to access IBM 3480 magnetic
+  Select this option if you want to access IBM 3490 magnetic
   tape subsystems and 100% compatibles.
+  This option is also available as a module. The module will be
+  called tape3490.o. If CONFIG_S390_TAPE is selected as a module,
+  this hardware driver cannot be built-in but is only available
+  as a module.
   It is safe to say "Y" here.
 
 Support for 3480 tape hardware
 CONFIG_S390_TAPE_3480
-  Select this option if you want to access IBM 3490 magnetic
+  Select this option if you want to access IBM 3480 magnetic
   tape subsystems and 100% compatibles.
+  This option is also available as a module. The module will be
+  called tape3480.o. If CONFIG_S390_TAPE is selected as a module,
+  this hardware driver cannot be built-in but is only available
+  as a module.
+  It is safe to say "Y" here.
 
 CTC device support
 CONFIG_CTC
@@ -22524,12 +22698,6 @@
   available.  This option is also available as a module which will be
   called ctc.o.  If you do not know what it is, it's safe to say "Y".
 
-Support for DIAG access to CMS reserved Disks
-CONFIG_DASD_DIAG
-  Select this option if you want to use CMS reserved Disks under VM
-  with the Diagnose250 command.  If you are not running under VM or
-  unsure what it is, say "N".
-
 XPRAM disk support
 CONFIG_BLK_DEV_XPRAM
   Select this option if you want to use your expanded storage on S/390
@@ -22552,6 +22720,20 @@
   vehicle networking under VM or VIF.  This option is also available
   as a module which will be called iucv.o. If unsure, say "Y".
 
+Process warning machine checks
+CONFIG_MACHCHK_WARNING
+  Select this option if you want the machine check handler on IBM S/390 or 
+  zSeries to process warning machine checks (e.g. on power failures). 
+  If unsure, say "Y".
+
+Use chscs for Common I/O
+CONFIG_CHSC
+  Select this option if you want the s390 common I/O layer to use information
+  obtained by channel subsystem calls. This will enable Linux to process link
+  failures and resource accessibility events. Moreover, if you have procfs
+  enabled, you'll be able to toggle chpids logically offline and online. Even
+  if you don't understand what this means, you should say "Y".
+
 Kernel support for 31 bit ELF binaries
 CONFIG_S390_SUPPORT
   Select this option if you want to enable your system kernel to
@@ -23014,6 +23196,11 @@
   It is recommended to be used on a NetWinder, but it is not a
   necessity.
 
+Check for stack overflows
+CONFIG_DEBUG_STACKOVERFLOW
+  This option make do_IRQ() check for enough stack space beeing left.
+  This is safe to enable.
+
 Debug high memory support
 CONFIG_DEBUG_HIGHMEM
   This options enables addition error checking for high memory systems.
@@ -23542,6 +23729,18 @@
   used by IrTTY.  To activate support for Parallax dongles you will
   have to start irattach like this "irattach -d litelink".
 
+Microchip MCP2120 dongle
+CONFIG_MCP2120_DONGLE
+  Say Y here if you want to build support for the Microchip MCP2120
+  dongle.  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>.  The MCP2120 dongle attaches to
+  the normal 9-pin serial port connector, and can currently only be
+  used by IrTTY.  To activate support for MCP2120 dongles you will
+  have to insert "irattach -d mcp2120" in the /etc/irda/drivers script.
+
+  You must build this dongle yourself.  For more information see:
+  <http://www.eyetap.org/~tangf/irda_sir_linux.html>
+
 Old Belkin dongle
 CONFIG_OLD_BELKIN_DONGLE
   Say Y here if you want to build support for the Adaptec Airport 1000
@@ -23549,6 +23748,30 @@
   and read <file:Documentation/modules.txt>.  The module will be
   called old_belkin.o.  Some information is contained in the comments
   at the top of <file:drivers/net/irda/old_belkin.c>.
+ 
+ACTiSYS IR-200L dongle (Experimental)
+CONFIG_ACT200L_DONGLE
+  Say Y here if you want to build support for the ACTiSYS IR-200L
+  dongle. If you want to compile it as a module, say M here and read
+  Documentation/modules.txt. The ACTiSYS IR-200L dongle attaches to
+  the normal 9-pin serial port connector, and can currently only be
+  used by IrTTY. To activate support for ACTiSYS IR-200L dongles
+  you will have to start irattach like this: "irattach -d act200l".
+
+Mobile Action MA600 dongle (Experimental)
+CONFIG_MA600_DONGLE
+  Say Y here if you want to build support for the Mobile Action MA600
+  dongle.  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>.  The MA600 dongle attaches to
+  the normal 9-pin serial port connector, and can currently only be
+  tested on IrCOMM.  To activate support for MA600 dongles you will
+  have to insert "irattach -d ma600" in the /etc/irda/drivers script.
+  Note: irutils 0.9.15 requires no modification. irutils 0.9.9 needs
+  modification. For more information, download the following tar gzip
+  file.
+
+  There is a pre-compiled module on
+  <http://engsvr.ust.hk/~eetwl95/download/ma600-2.4.x.tar.gz>
 
 VME (Motorola and BVM) support
 CONFIG_VME
@@ -24526,15 +24749,6 @@
   the IA32 instruction set.  Say Y here to build in kernel support for
   this.  If in doubt, say Y.
 
-/proc/efi/vars support
-CONFIG_EFI_VARS
-  If you say Y here, you are able to get EFI (Extensible Firmware
-  Interface) variable information in /proc/efi/vars.  You may read,
-  write, create, and destroy EFI variables through this interface.
-
-  To use this option, you have to check that the "/proc file system
-  support" (CONFIG_PROC_FS) is enabled, too.
-
 Physical memory granularity (16 MB)
 CONFIG_IA64_GRANULE_16MB
   IA64 identity-mapped regions use a large page size.  We'll call such
@@ -25020,14 +25234,6 @@
   <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
   board at <http://www.mvista.com/allies/semiconductor/ite.html>.
 
-Use chscs for Common I/O
-CONFIG_CHSC
-  Select this option if you want the s390 common I/O layer to use information
-  obtained by channel subsystem calls. This will enable Linux to process link
-  failures and resource accessibility events. Moreover, if you have procfs
-  enabled, you'll be able to toggle chpids logically offline and online. Even
-  if you don't understand what this means, you should say "Y".
-
 Support ARM926T processor
 CONFIG_CPU_ARM926T
   This is a variant of the ARM920.  It has slightly different
@@ -25047,21 +25253,6 @@
   written) to implement the policy. If you don't understand what this
   is all about, it's safe to say 'N'.
 
-Automatic activation of DIAG module
-CONFIG_DASD_AUTO_DIAG
-  Enable this option if you want your DIAG discipline module loaded
-  on DASD driver startup.
-
-Automatic activation of ECKD module
-CONFIG_DASD_AUTO_ECKD
-  Enable this option if you want your ECKD discipline module loaded
-  on DASD driver startup.
-
-Automatic activation of FBA  module
-CONFIG_DASD_AUTO_FBA
-  Enable this option if you want your FBA discipline module loaded
-  on DASD driver startup.
-
 SiS
 CONFIG_DRM_SIS
   Choose this option if you have a SIS graphics card. AGP support is
@@ -25155,16 +25346,6 @@
 
   When in doubt, say N.
 
-Control-Program Identification
-CONFIG_HWC_CPI
-  This option enables the hardware console interface for system
-  identification This is commonly used for workload management and
-  gives you a nice name for the system on the service element.
-  Please select this option as a module since built-in operation is
-  completely untested.
-  You should only select this option if you know what you are doing,
-  need this feature and intend to run your kernel in LPAR.
-
 Enable autotest (llsc). Option to run cache test instead of booting
 CONFIG_IA64_SGI_AUTOTEST
   Build a kernel used for hardware validation. If you include the
@@ -25240,37 +25421,12 @@
   Say Y here to support tuning the ITE8172's IDE interface.  This makes
   it possible to set DMA channel or PIO opration and the transfer rate.
 
-Process warning machine checks
-CONFIG_MACHCHK_WARNING
-  Select this option if you want the machine check handler on IBM S/390 or
-  zSeries to process warning machine checks (e.g. on power failures).
-  If unsure, say "Y".
-
-Pseudo page fault support
-CONFIG_PFAULT
-  Select this option, if you want to use PFAULT pseudo page fault
-  handling under VM. If running native or in LPAR, this option
-  has no effect. If your VM does not support PFAULT, PAGEEX
-  pseudo page fault handling will be used.
-  Note that VM 4.2 supports PFAULT but has a bug in its
-  implementation that causes some problems.
-  Everybody who wants to run Linux under VM != VM4.2 should select
-  this option.
-
 Enable protocol mode for the L1 console
 CONFIG_SERIAL_SGI_L1_PROTOCOL
   Uses protocol mode instead of raw mode for the level 1 console on the
   SGI SN (Scalable NUMA) platform for IA64.  If you are compiling for
   an SGI SN box then Y is the recommended value, otherwise say N.
 
-VM shared kernel support
-CONFIG_SHARED_KERNEL
-  Select this option, if you want to share the text segment of the
-  Linux kernel between different VM guests. This reduces memory
-  usage with lots of guests but greatly increases kernel size.
-  You should only select this option if you know what you are
-  doing and want to exploit this feature.
-
 New bus configuration (EXPERIMENTAL)  
 CONFIG_TULIP_MWI
   This configures your Tulip card specifically for the card and
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/DocBook/kernel-hacking.tmpl linux-bk/Documentation/DocBook/kernel-hacking.tmpl
--- linux-2.4.19/Documentation/DocBook/kernel-hacking.tmpl	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/DocBook/kernel-hacking.tmpl	2002-08-17 00:49:09.000000000 +0000
@@ -1091,18 +1091,17 @@
    <title>Initializing structure members</title>
 
    <para>
-    The preferred method of initializing structures is to use the
-    gcc Labeled Elements extension, eg:
+    The preferred method of initializing structures is to use
+    designated initialisers, as defined by ISO C99, eg:
    </para>
    <programlisting>
 static struct block_device_operations opt_fops = {
-        open:                   opt_open,
-        release:                opt_release,
-        ioctl:                  opt_ioctl,
-        check_media_change:     opt_media_change,
+        .open               = opt_open,
+        .release            = opt_release,
+        .ioctl              = opt_ioctl,
+        .check_media_change = opt_media_change,
 };
    </programlisting>
-
    <para>
     This makes it easy to grep for, and makes it clear which
     structure fields are set.  You should do this because it looks
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/SubmittingPatches linux-bk/Documentation/SubmittingPatches
--- linux-2.4.19/Documentation/SubmittingPatches	2000-12-04 01:48:18.000000000 +0000
+++ linux-bk/Documentation/SubmittingPatches	2002-08-17 00:48:48.000000000 +0000
@@ -161,7 +161,7 @@
 When sending patches to Linus, always follow step #6.
 
 Large changes are not appropriate for mailing lists, and some
-maintainers.  If your patch, uncompressed, exceeds 40Kb in size,
+maintainers.  If your patch, uncompressed, exceeds 40 kB in size,
 it is preferred that you store your patch on an Internet-accessible
 server, and provide instead a URL (link) pointing to your patch.
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/filesystems/00-INDEX linux-bk/Documentation/filesystems/00-INDEX
--- linux-2.4.19/Documentation/filesystems/00-INDEX	2001-06-20 18:10:27.000000000 +0000
+++ linux-bk/Documentation/filesystems/00-INDEX	2002-08-17 00:49:08.000000000 +0000
@@ -6,6 +6,8 @@
 	- info and mount options for the Acorn Advanced Disc Filing System.
 affs.txt
 	- info and mount options for the Amiga Fast File System.
+befs.txt
+	- info for the BeOS file system (BFS)
 bfs.txt
 	- info for the SCO UnixWare Boot Filesystem (BFS).
 coda.txt
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/filesystems/befs.txt linux-bk/Documentation/filesystems/befs.txt
--- linux-2.4.19/Documentation/filesystems/befs.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/filesystems/befs.txt	2002-08-17 00:48:54.000000000 +0000
@@ -0,0 +1,111 @@
+BeOS filesystem for Linux
+
+Document last updated: Dec 6, 2001
+
+WARNING
+=======
+Make sure you understand that this is alpha software.  This means that the
+implementation is neither complete nor well-tested. 
+
+I DISCLAIM ALL RESPONSIBILTY FOR ANY POSSIBLE BAD EFFECTS OF THIS CODE!
+
+LICENSE
+=====
+This software is covered by the GNU General Public License. 
+See the file COPYING for the complete text of the license.
+Or the GNU website: <http://www.gnu.org/licenses/licenses.html>
+
+AUTHOR
+=====
+Current maintainer: Will Dyson <will_dyson@pobox.com>
+Has been working on the code since Aug 13, 2001. See the changelog for details.
+
+Original Author: Makoto Kato <m_kato@ga2.so-net.ne.jp>
+His orriginal code can still be found at: <http://hp.vector.co.jp/authors/VA008030/bfs/>
+Does anyone know of a more current email address for Makoto? He doesn't respond
+to the address given above...
+
+WHAT IS THIS DRIVER?
+==================
+This module implements the native filesystem of BeOS <http://www.be.com/>
+for the linux 2.4.1 and later kernels. Currently it is a read-only implementation.
+
+Which is it, BFS or BEFS?
+================
+Be, Inc said, "BeOS Filesystem is officially called BFS, not BeFS". 
+But Unixware Boot Filesystem is called bfs, too. And they are already in the
+kernel.
+Because of this nameing conflict, on Linux the BeOS filesystem is called befs.
+
+HOW TO INSTALL
+==============
+step 1.  Install the BeFS  patch into the source code tree of linux.
+
+Apply the patchfile to your kernel source tree.
+Assuming that your kernel source is in /foo/bar/linux and the patchfile is called
+patch-befs-xxx, you would do the following:
+
+	cd /foo/bar/linux
+	patch -p1 < /path/to/patch-befs-xxx
+
+if the patching step fails (i.e. there are rejected hunks), you can try to
+figure it out yourself (it shouldn't be hard), or mail the maintainer 
+(Will Dyson <will_dyson@pobox.com>) for help.
+
+step 2.  Configuretion & make kernel
+
+The linux kernel has many compile-time options. Most of them are beyond the
+scope of this document. I suggest the Kernel-HOWTO document as a good general
+reference on this topic. <http://www.linux.com/howto/Kernel-HOWTO.html>
+
+However, to use the BeFS module, you must enable it at configure time.
+
+	cd /foo/bar/linux
+	make menuconfig (or xconfig)
+
+The BeFS module is not a standard part of the linux kernel, so you must first
+enable support for experimental code under the "Code maturity level" menu.
+
+Then, under the "Filesystems" menu will be an option called "BeFS filesystem (experimental)",
+or something like that. Enable that option (it is fine to make it a module).
+
+Save your kernel configuration and then build your kernel.
+
+step 3.  Install
+
+See the kernel howto <http://www.linux.com/howto/Kernel-HOWTO.html> for
+instructions on this critical step.
+
+USING BFS
+=========
+To use the BeOS filesystem, use filesystem type 'befs'.
+
+ex)
+    mount -t befs /dev/fd0 /beos
+
+MOUNT OPTIONS
+=============
+uid=nnn        All files in the partition will be owned by user id nnn.
+gid=nnn	       All files in the partition will be in group nnn.
+iocharset=xxx  Use xxx as the name of the NLS translation table.
+debug          The driver will output debugging information to the syslog.
+
+HOW TO GET LASTEST VERSION
+==========================
+
+The latest version is currently available at:
+<http://befs-driver.sourceforge.net/>
+
+ANY KNOWN BUGS?
+===========
+As of Jan 20, 2002:
+	
+	None
+
+SPECIAL THANKS
+==============
+Dominic Giampalo ... Writing "Practical file system design with Be filesystem"
+Hiroyuki Yamada  ... Testing LinuxPPC.
+
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/filesystems/isofs.txt linux-bk/Documentation/filesystems/isofs.txt
--- linux-2.4.19/Documentation/filesystems/isofs.txt	1999-05-26 17:01:43.000000000 +0000
+++ linux-bk/Documentation/filesystems/isofs.txt	2002-08-17 00:48:52.000000000 +0000
@@ -29,3 +29,10 @@
   unhide        Show hidden files.
   session=x     Select number of session on multisession CD
   sbsector=xxx  Session begins from sector xxx
+
+Recommended documents about ISO 9660 standard are located at:
+http://www.y-adagio.com/public/standards/iso_cdromr/tocont.htm
+ftp://ftp.ecma.ch/ecma-st/Ecma-119.pdf
+Quoting from the PDF "This 2nd Edition of Standard ECMA-119 is technically 
+identical with ISO 9660.", so it is a valid and gratis substitute of the
+official ISO specification.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/ide.txt linux-bk/Documentation/ide.txt
--- linux-2.4.19/Documentation/ide.txt	2001-09-07 16:28:38.000000000 +0000
+++ linux-bk/Documentation/ide.txt	2002-08-17 00:48:52.000000000 +0000
@@ -306,6 +306,9 @@
  "idex=serialize"	: do not overlap operations on idex and ide(x^1)
  "idex=reset"		: reset interface after probe
  "idex=dma"		: automatically configure/use DMA if possible.
+ "idex=nohighio"	: don't use i/o to high memory addresses on this
+			 	interface. i/o to memory locations higher
+				than ~860MiB will be bounced.
 
  The following are valid ONLY on ide0,
  and the defaults for the base,ctl ports must not be altered.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/isdn/README.HiSax linux-bk/Documentation/isdn/README.HiSax
--- linux-2.4.19/Documentation/isdn/README.HiSax	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/isdn/README.HiSax	2002-08-17 00:48:52.000000000 +0000
@@ -41,9 +41,10 @@
 ELSA Quickstep 3000PCI
 ELSA PCMCIA
 ITK ix1-micro Rev.2
-Eicon.Diehl Diva 2.0 ISA and PCI (S0 and U interface, no PRO version)
-Eicon.Diehl Diva 2.01 ISA and PCI
-Eicon.Diehl Diva Piccola
+Eicon Diva 2.0 ISA and PCI (S0 and U interface, no PRO version)
+Eicon Diva 2.01 ISA and PCI
+Eicon Diva 2.02 PCI
+Eicon Diva Piccola
 ASUSCOM NETWORK INC. ISDNLink 128K PC adapter (order code I-IN100-ST-D)
 Dynalink IS64PH (OEM version of ASUSCOM NETWORK INC. ISDNLink 128K adapter)
 PCBIT-DP (OEM version of ASUSCOM NETWORK INC. ISDNLink)
@@ -67,13 +68,14 @@
 HFC-PCI based cards
 Winbond W6692 based cards
 HFC-S+, HFC-SP/PCMCIA cards
+formula-n enternow
+Gerdes Power ISDN
 
 Note: PCF, PCF-Pro: up to now, only the ISDN part is supported
       PCC-8: not tested yet
       Eicon.Diehl Diva U interface not tested
 
 If you know other passive cards with the Siemens chipset, please let me know.
-To use the PNP cards you need the isapnptools.
 You can combine any card, if there is no conflict between the resources
 (io, mem, irq).
 
@@ -89,8 +91,15 @@
 modules. It is included in the normal "make [menu]config" target at the
 kernel. Don't forget it, especially to select the right D-channel protocol.
 
-Please note: All PnP cards need to be configured with isapnp and will work
-only with the HiSax driver used as a module.
+Please note: In older versions of the HiSax driver, all PnP cards
+needed to be configured with isapnp and worked only with the HiSax
+driver used as a module.
+
+In the current version, HiSax will automatically use the in-kernel
+ISAPnP support, provided you selected it during kernel configuration
+(CONFIG_ISAPNP), if you don't give the io=, irq= command line parameters.
+
+The affected card types are: 4,7,12,14,19,27-30
 
 a) when built as a module
 -------------------------
@@ -191,6 +200,8 @@
    37	HFC 2BDS0 S+, SP         irq,io 
    38	NETspider U PCI card     none
    39	HFC 2BDS0 SP/PCMCIA      irq,io (set with cardmgr)
+   40   hotplug interface
+   41   Formula-n enter:now PCI  none
 
 At the moment IRQ sharing is only possible with PCI cards. Please make sure
 that your IRQ is free and enabled for ISA use.
@@ -216,6 +227,13 @@
                    (IO 1 (BASE 0x0180))
    modprobe hisax type=4 protocol=2 irq=10 io0=0x580 io1=0x180
 
+   In the current version of HiSax, you can instead simply use
+
+   modprobe hisax type=4 protocol=2
+
+   if you configured your kernel for ISAPnP. Don't run isapnp in
+   this case!
+
 6. Teles 16.3, Euro ISDN, I/O base 280 hex, IRQ 12 and
    Teles 16.0, 1TR6, IRQ 5, Memory d0000 hex
    modprobe hisax type=3,1 protocol=2,1 io=0x280 mem=0,0xd0000
@@ -296,7 +314,9 @@
    36	W6692 based PCI cards   none
    37	HFC 2BDS0 S+,SP/PCMCIA  ONLY WORKS AS A MODULE !
    38	NETspider U PCI card    none
-
+   39	HFC 2BDS0 SP/PCMCIA     ONLY WORKS AS A MODULE !
+   40   hotplug interface	ONLY WORKS AS A MODULE !
+   41   Formula-n enter:now PCI none
 
 Running the driver
 ------------------
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/00-INDEX linux-bk/Documentation/networking/00-INDEX
--- linux-2.4.19/Documentation/networking/00-INDEX	2001-02-09 00:32:44.000000000 +0000
+++ linux-bk/Documentation/networking/00-INDEX	2002-08-17 00:48:57.000000000 +0000
@@ -44,6 +44,10 @@
 	- the Digi International RightSwitch SE-X Ethernet driver
 dmfe.txt
 	- info on the Davicom DM9102(A)/DM9132/DM9801 fast ethernet driver.
+e100.txt
+	- info on Intel's EtherExpress PRO/100 line of 10/100 boards
+e1000.txt
+	- info on Intel's E1000 line of gigabit ethernet boards
 eql.txt
 	- serial IP load balancing
 ethertap.txt
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/8139too.txt linux-bk/Documentation/networking/8139too.txt
--- linux-2.4.19/Documentation/networking/8139too.txt	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/networking/8139too.txt	2002-08-17 00:48:49.000000000 +0000
@@ -185,9 +185,22 @@
 Change History
 --------------
 
-Version 0.9.23 - January 16, 2002
+Version 0.9.26 - August 9, 2002
 
-* New, compile-time conditional for testing better RX reset
+* Fix MII ioctl phy id corruption.
+* Fix big-endian multicast bug.
+* Support register dumps via ethtool.
+* Fix several uses of 'len' after potential skb free, in dev->hard_start_xmit
+* Replace several "magic numbers" with their proper representation
+  constants in linux/mii.h.
+* Support ethtool media interface via generic kernel MII API
+* Export NIC-specific statistics via ethtool.
+* Proper support for RTL8139 rev K. (can be disabled via
+  compile-time conditional)
+* Add PCI ids for new 8139 boards.
+* Use ethernet crc via generic linux/crc32.h kernel API.
+* Better RX reset.  Old rx-reset method still available via
+  a compile-time conditional.
 * Only account specific RX errors if rx_status is !OK
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/NAPI_HOWTO.txt linux-bk/Documentation/networking/NAPI_HOWTO.txt
--- linux-2.4.19/Documentation/networking/NAPI_HOWTO.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/networking/NAPI_HOWTO.txt	2002-08-17 00:48:47.000000000 +0000
@@ -0,0 +1,749 @@
+HISTORY:
+February 16/2002 -- revision 0.2.1:
+COR typo corrected
+February 10/2002 -- revision 0.2:
+some spell checking ;->
+January 12/2002 -- revision 0.1
+This is still work in progress so may change.
+To keep up to date please watch this space.
+
+Introduction to NAPI
+====================
+
+NAPI is a proven (www.cyberus.ca/~hadi/usenix-paper.tgz) technique
+to improve network performance on Linux. For more details please
+read that paper.
+NAPI provides a "inherent mitigation" which is bound by system capacity
+as can be seen from the following data collected by Robert on Gigabit 
+ethernet (e1000):
+
+ Psize    Ipps       Tput     Rxint     Txint    Done     Ndone
+ ---------------------------------------------------------------
+   60    890000     409362        17     27622        7     6823
+  128    758150     464364        21      9301       10     7738
+  256    445632     774646        42     15507       21    12906
+  512    232666     994445    241292     19147   241192     1062
+ 1024    119061    1000003    872519     19258   872511        0
+ 1440     85193    1000003    946576     19505   946569        0
+ 
+
+Legend:
+"Ipps" stands for input packets per second. 
+"Tput" == packets out of total 1M that made it out.
+"txint" == transmit completion interrupts seen
+"Done" == The number of times that the poll() managed to pull all
+packets out of the rx ring. Note from this that the lower the
+load the more we could clean up the rxring
+"Ndone" == is the converse of "Done". Note again, that the higher
+the load the more times we couldnt clean up the rxring.
+
+Observe that:
+when the NIC receives 890Kpackets/sec only 17 rx interrupts are generated. 
+The system cant handle the processing at 1 interrupt/packet at that load level. 
+At lower rates on the other hand, rx interrupts go up and therefore the
+interrupt/packet ratio goes up (as observable from that table). So there is
+possibility that under low enough input, you get one poll call for each
+input packet caused by a single interrupt each time. And if the system 
+cant handle interrupt per packet ratio of 1, then it will just have to 
+chug along ....
+
+
+0) Prerequisites:
+==================
+A driver MAY continue using the old 2.4 technique for interfacing
+to the network stack and not benefit from the NAPI changes.
+NAPI additions to the kernel do not break backward compatibility.
+NAPI, however, requires the following features to be available:
+
+A) DMA ring or enough RAM to store packets in software devices.
+
+B) Ability to turn off interrupts or maybe events that send packets up 
+the stack.
+
+NAPI processes packet events in what is known as dev->poll() method.
+Typically, only packet receive events are processed in dev->poll(). 
+The rest of the events MAY be processed by the regular interrupt handler 
+to reduce processing latency (justified also because there are not that 
+many of them).
+Note, however, NAPI does not enforce that dev->poll() only processes 
+receive events. 
+Tests with the tulip driver indicated slightly increased latency if
+all of the interrupt handler is moved to dev->poll(). Also MII handling
+gets a little trickier.
+The example used in this document is to move the receive processing only
+to dev->poll(); this is shown with the patch for the tulip driver.
+For an example of code that moves all the interrupt driver to 
+dev->poll() look at the ported e1000 code.
+
+There are caveats that might force you to go with moving everything to 
+dev->poll(). Different NICs work differently depending on their status/event 
+acknowledgement setup. 
+There are two types of event register ACK mechanisms.
+	I)  what is known as Clear-on-read (COR).
+	when you read the status/event register, it clears everything!
+	The natsemi and sunbmac NICs are known to do this.
+	In this case your only choice is to move all to dev->poll()
+
+	II) Clear-on-write (COW)
+	 i) you clear the status by writting a 1 in the bit-location you want.
+		These are the majority of the NICs and work the best with NAPI.
+		Put only receive events in dev->poll(); leave the rest in
+		the old interrupt handler.
+	 ii) whatever you write in the status register clears every thing ;->
+		Cant seem to find any supported by Linux which do this. If
+		someone knows such a chip email us please.
+		Move all to dev->poll()
+
+C) Ability to detect new work correctly.
+NAPI works by shutting down event interrupts when theres work and
+turning them on when theres none. 
+New packets might show up in the small window while interrupts were being 
+re-enabled (refer to appendix 2).  A packet might sneak in during the period 
+we are enabling interrupts. We only get to know about such a packet when the 
+next new packet arrives and generates an interrupt. 
+Essentially, there is a small window of opportunity for a race condition
+which for clarity we'll refer to as the "rotting packet".
+
+This is a very important topic and appendix 2 is dedicated for more 
+discussion.
+
+Locking rules and environmental guarantees
+==========================================
+
+-Guarantee: Only one CPU at any time can call dev->poll(); this is because
+only one CPU can pick the initial interrupt and hence the initial
+netif_rx_schedule(dev);
+- The core layer invokes devices to send packets in a round robin format.
+This implies receive is totaly lockless because of the guarantee only that 
+one CPU is executing it.
+-  contention can only be the result of some other CPU accessing the rx
+ring. This happens only in close() and suspend() (when these methods
+try to clean the rx ring); 
+****guarantee: driver authors need not worry about this; synchronization 
+is taken care for them by the top net layer.
+-local interrupts are enabled (if you dont move all to dev->poll()). For 
+example link/MII and txcomplete continue functioning just same old way. 
+This improves the latency of processing these events. It is also assumed that 
+the receive interrupt is the largest cause of noise. Note this might not 
+always be true. 
+[according to Manfred Spraul, the winbond insists on sending one 
+txmitcomplete interrupt for each packet (although this can be mitigated)].
+For these broken drivers, move all to dev->poll().
+
+For the rest of this text, we'll assume that dev->poll() only
+processes receive events.
+
+new methods introduce by NAPI
+=============================
+
+a) netif_rx_schedule(dev)
+Called by an IRQ handler to schedule a poll for device
+
+b) netif_rx_schedule_prep(dev)
+puts the device in a state which allows for it to be added to the
+CPU polling list if it is up and running. You can look at this as
+the first half of  netif_rx_schedule(dev) above; the second half
+being c) below.
+
+c) __netif_rx_schedule(dev)
+Add device to the poll list for this CPU; assuming that _prep above
+has already been called and returned 1.
+
+d) netif_rx_reschedule(dev, undo)
+Called to reschedule polling for device specifically for some
+deficient hardware. Read Appendix 2 for more details.
+
+e) netif_rx_complete(dev)
+
+Remove interface from the CPU poll list: it must be in the poll list
+on current cpu. This primitive is called by dev->poll(), when
+it completes its work. The device cannot be out of poll list at this
+call, if it is then clearly it is a BUG(). You'll know ;->
+
+All these above nethods are used below. So keep reading for clarity.
+
+Device driver changes to be made when porting NAPI
+==================================================
+
+Below we describe what kind of changes are required for NAPI to work.
+
+1) introduction of dev->poll() method 
+=====================================
+
+This is the method that is invoked by the network core when it requests
+for new packets from the driver. A driver is allowed to send upto
+dev->quota packets by the current CPU before yielding to the network
+subsystem (so other devices can also get opportunity to send to the stack).
+
+dev->poll() prototype looks as follows:
+int my_poll(struct net_device *dev, int *budget)
+
+budget is the remaining number of packets the network subsystem on the
+current CPU can send up the stack before yielding to other system tasks.
+*Each driver is responsible for decrementing budget by the total number of
+packets sent.
+	Total number of packets cannot exceed dev->quota.
+
+dev->poll() method is invoked by the top layer, the driver just sends if it 
+can to the stack the packet quantity requested.
+
+more on dev->poll() below after the interrupt changes are explained.
+
+2) registering dev->poll() method
+===================================
+
+dev->poll should be set in the dev->probe() method. 
+e.g:
+dev->open = my_open;
+.
+.
+/* two new additions */
+/* first register my poll method */
+dev->poll = my_poll;
+/* next register my weight/quanta; can be overriden in /proc */
+dev->weight = 16;
+.
+.
+dev->stop = my_close;
+
+
+
+3) scheduling dev->poll()
+=============================
+This involves modifying the interrupt handler and the code
+path which takes the packet off the NIC and sends them to the 
+stack.
+
+it's important at this point to introduce the classical D Becker 
+interrupt processor:
+
+------------------
+static void
+netdevice_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+
+	struct net_device *dev = (struct net_device *)dev_instance;
+	struct my_private *tp = (struct my_private *)dev->priv;
+
+	int work_count = my_work_count;
+        status = read_interrupt_status_reg();
+        if (status == 0)
+                return;         /* Shared IRQ: not us */
+        if (status == 0xffff)
+                return;         /* Hot unplug */
+        if (status & error)
+		do_some_error_handling()
+        
+	do {
+		acknowledge_ints_ASAP();
+
+		if (status & link_interrupt) {
+			spin_lock(&tp->link_lock);
+			do_some_link_stat_stuff();
+			spin_unlock(&tp->link_lock);
+		}
+		
+		if (status & rx_interrupt) {
+			receive_packets(dev);
+		}
+
+		if (status & rx_nobufs) {
+			make_rx_buffs_avail();
+		}
+			
+		if (status & tx_related) {
+			spin_lock(&tp->lock);
+			tx_ring_free(dev);
+			if (tx_died)
+				restart_tx();
+			spin_unlock(&tp->lock);
+		}
+
+		status = read_interrupt_status_reg();
+
+	} while (!(status & error) || more_work_to_be_done);
+
+}
+
+----------------------------------------------------------------------
+
+We now change this to what is shown below to NAPI-enable it:
+
+----------------------------------------------------------------------
+static void
+netdevice_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct net_device *dev = (struct net_device *)dev_instance;
+	struct my_private *tp = (struct my_private *)dev->priv;
+
+        status = read_interrupt_status_reg();
+        if (status == 0)
+                return;         /* Shared IRQ: not us */
+        if (status == 0xffff)
+                return;         /* Hot unplug */
+        if (status & error)
+		do_some_error_handling();
+        
+	do {
+/************************ start note *********************************/		
+		acknowledge_ints_ASAP();  // dont ack rx and rxnobuff here
+/************************ end note *********************************/		
+
+		if (status & link_interrupt) {
+			spin_lock(&tp->link_lock);
+			do_some_link_stat_stuff();
+			spin_unlock(&tp->link_lock);
+		}
+/************************ start note *********************************/		
+		if (status & rx_interrupt || (status & rx_nobuffs)) {
+			if (netif_rx_schedule_prep(dev)) {
+
+				/* disable interrupts caused 
+			         *	by arriving packets */
+				disable_rx_and_rxnobuff_ints();
+				/* tell system we have work to be done. */
+				__netif_rx_schedule(dev);
+			} else {
+				printk("driver bug! interrupt while in poll\n");
+				/* FIX by disabling interrupts  */
+				disable_rx_and_rxnobuff_ints();
+			}
+		}
+/************************ end note note *********************************/		
+			
+		if (status & tx_related) {
+			spin_lock(&tp->lock);
+			tx_ring_free(dev);
+
+			if (tx_died)
+				restart_tx();
+			spin_unlock(&tp->lock);
+		}
+
+		status = read_interrupt_status_reg();
+
+/************************ start note *********************************/		
+	} while (!(status & error) || more_work_to_be_done(status));
+/************************ end note note *********************************/		
+
+}
+
+---------------------------------------------------------------------
+
+
+We note several things from above:
+
+I) Any interrupt source which is caused by arriving packets is now
+turned off when it occurs. Depending on the hardware, there could be
+several reasons that arriving packets would cause interrupts; these are the
+interrupt sources we wish to avoid. The two common ones are a) a packet 
+arriving (rxint) b) a packet arriving and finding no DMA buffers available
+(rxnobuff) .
+This means also acknowledge_ints_ASAP() will not clear the status
+register for those two items above; clearing is done in the place where 
+proper work is done within NAPI; at the poll() and refill_rx_ring() 
+discussed further below.
+netif_rx_schedule_prep() returns 1 if device is in running state and
+gets successfully added to the core poll list. If we get a zero value
+we can _almost_ assume are already added to the list (instead of not running. 
+Logic based on the fact that you shouldnt get interrupt if not running)
+We rectify this by disabling rx and rxnobuf interrupts.
+
+II) that receive_packets(dev) and make_rx_buffs_avail() may have dissapeared.
+These functionalities are still around actually......
+
+infact, receive_packets(dev) is very close to my_poll() and 
+make_rx_buffs_avail() is invoked from my_poll()
+
+4) converting receive_packets() to dev->poll()
+===============================================
+
+We need to convert the classical D Becker receive_packets(dev) to my_poll()
+
+First the typical receive_packets() below:
+-------------------------------------------------------------------
+
+/* this is called by interrupt handler */
+static void receive_packets (struct net_device *dev)
+{
+
+	struct my_private *tp = (struct my_private *)dev->priv;
+	rx_ring = tp->rx_ring;
+	cur_rx = tp->cur_rx;
+	int entry = cur_rx % RX_RING_SIZE;
+	int received = 0;
+	int rx_work_limit = tp->dirty_rx + RX_RING_SIZE - tp->cur_rx;
+
+	while (rx_ring_not_empty) {
+		u32 rx_status;
+		unsigned int rx_size;
+		unsigned int pkt_size;
+		struct sk_buff *skb;
+                /* read size+status of next frame from DMA ring buffer */
+		/* the number 16 and 4 are just examples */
+                rx_status = le32_to_cpu (*(u32 *) (rx_ring + ring_offset));
+                rx_size = rx_status >> 16;
+                pkt_size = rx_size - 4;
+
+		/* process errors */
+                if ((rx_size > (MAX_ETH_FRAME_SIZE+4)) ||
+                    (!(rx_status & RxStatusOK))) {
+                        netdrv_rx_err (rx_status, dev, tp, ioaddr);
+                        return;
+                }
+
+                if (--rx_work_limit < 0)
+                        break;
+
+		/* grab a skb */
+                skb = dev_alloc_skb (pkt_size + 2);
+                if (skb) {
+			.
+			.
+			netif_rx (skb);
+			.
+			.
+                } else {  /* OOM */
+			/*seems very driver specific ... some just pass
+			whatever is on the ring already. */
+                }
+
+		/* move to the next skb on the ring */
+		entry = (++tp->cur_rx) % RX_RING_SIZE;
+		received++ ;
+
+        }
+
+	/* store current ring pointer state */
+        tp->cur_rx = cur_rx;
+
+        /* Refill the Rx ring buffers if they are needed */
+	refill_rx_ring();
+	.
+	.
+
+}
+-------------------------------------------------------------------
+We change it to a new one below; note the additional parameter in
+the call.
+
+-------------------------------------------------------------------
+
+/* this is called by the network core */
+static void my_poll (struct net_device *dev, int *budget)
+{
+
+	struct my_private *tp = (struct my_private *)dev->priv;
+	rx_ring = tp->rx_ring;
+	cur_rx = tp->cur_rx;
+	int entry = cur_rx % RX_BUF_LEN;
+	/* maximum packets to send to the stack */
+/************************ note note *********************************/		
+	int rx_work_limit = dev->quota;
+
+/************************ end note note *********************************/		
+    do {  // outer beggining loop starts here
+
+	clear_rx_status_register_bit();
+
+	while (rx_ring_not_empty) {
+		u32 rx_status;
+		unsigned int rx_size;
+		unsigned int pkt_size;
+		struct sk_buff *skb;
+                /* read size+status of next frame from DMA ring buffer */
+		/* the number 16 and 4 are just examples */
+                rx_status = le32_to_cpu (*(u32 *) (rx_ring + ring_offset));
+                rx_size = rx_status >> 16;
+                pkt_size = rx_size - 4;
+
+		/* process errors */
+                if ((rx_size > (MAX_ETH_FRAME_SIZE+4)) ||
+                    (!(rx_status & RxStatusOK))) {
+                        netdrv_rx_err (rx_status, dev, tp, ioaddr);
+                        return;
+                }
+
+/************************ note note *********************************/		
+                if (--rx_work_limit < 0) { /* we got packets, but no quota */
+			/* store current ring pointer state */
+			tp->cur_rx = cur_rx;
+
+			/* Refill the Rx ring buffers if they are needed */
+			refill_rx_ring(dev);
+                        goto not_done;
+		}
+/**********************  end note **********************************/
+
+		/* grab a skb */
+                skb = dev_alloc_skb (pkt_size + 2);
+                if (skb) {
+			.
+			.
+/************************ note note *********************************/		
+			netif_receive_skb (skb);
+/**********************  end note **********************************/
+			.
+			.
+                } else {  /* OOM */
+			/*seems very driver specific ... common is just pass
+			whatever is on the ring already. */
+                }
+
+		/* move to the next skb on the ring */
+		entry = (++tp->cur_rx) % RX_RING_SIZE;
+		received++ ;
+
+        }
+
+	/* store current ring pointer state */
+        tp->cur_rx = cur_rx;
+
+        /* Refill the Rx ring buffers if they are needed */
+	refill_rx_ring(dev);
+	
+	/* no packets on ring; but new ones can arrive since we last 
+	   checked  */
+	status = read_interrupt_status_reg();
+	if (rx status is not set) {
+                        /* If something arrives in this narrow window,
+			an interrupt will be generated */
+                        goto done;
+	}
+	/* done! at least thats what it looks like ;->
+	if new packets came in after our last check on status bits
+	they'll be caught by the while check and we go back and clear them 
+	since we havent exceeded our quota */
+    } while (rx_status_is_set); 
+
+done:
+
+/************************ note note *********************************/		
+        dev->quota -= received;
+        *budget -= received;
+
+        /* If RX ring is not full we are out of memory. */
+        if (tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL)
+                goto oom;
+
+	/* we are happy/done, no more packets on ring; put us back
+	to where we can start processing interrupts again */
+        netif_rx_complete(dev);
+	enable_rx_and_rxnobuf_ints();
+
+       /* The last op happens after poll completion. Which means the following:
+        * 1. it can race with disabling irqs in irq handler (which are done to 
+	* schedule polls)
+        * 2. it can race with dis/enabling irqs in other poll threads
+        * 3. if an irq raised after the begining of the outer  beginning 
+        * loop(marked in the code above), it will be immediately
+        * triggered here.
+        *
+        * Summarizing: the logic may results in some redundant irqs both
+        * due to races in masking and due to too late acking of already
+        * processed irqs. The good news: no events are ever lost.
+        */
+
+        return 0;   /* done */
+
+not_done:
+        if (tp->cur_rx - tp->dirty_rx > RX_RING_SIZE/2 ||
+            tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL)
+                refill_rx_ring(dev);
+
+        if (!received) {
+                printk("received==0\n");
+                received = 1;
+        }
+        dev->quota -= received;
+        *budget -= received;
+        return 1;  /* not_done */
+
+oom:
+        /* Start timer, stop polling, but do not enable rx interrupts. */
+	start_poll_timer(dev);
+        return 0;  /* we'll take it from here so tell core "done"*/
+
+/************************ End note note *********************************/		
+}
+-------------------------------------------------------------------
+
+From above we note that:
+0) rx_work_limit = dev->quota 
+1) refill_rx_ring() is in charge of clearing the bit for rxnobuff when
+it does the work.
+2) We have a done and not_done state.
+3) instead of netif_rx() we call netif_receive_skb() to pass the skb.
+4) we have a new way of handling oom condition
+5) A new outer for (;;) loop has been added. This serves the purpose of
+ensuring that if a new packet has come in, after we are all set and done,
+and we have not exceeded our quota that we continue sending packets up.
+ 
+
+-----------------------------------------------------------
+Poll timer code will need to do the following:
+
+a) 
+
+        if (tp->cur_rx - tp->dirty_rx > RX_RING_SIZE/2 ||
+            tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL) 
+                refill_rx_ring(dev);
+
+        /* If RX ring is not full we are still out of memory.
+	   Restart the timer again. Else we re-add ourselves 
+           to the master poll list.
+         */
+
+        if (tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL)
+                restart_timer();
+
+	else netif_rx_schedule(dev);  /* we are back on the poll list */
+	
+5) dev->close() and dev->suspend() issues
+==========================================
+The driver writter neednt worry about this. The top net layer takes
+care of it.
+
+6) Adding new Stats to /proc 
+=============================
+In order to debug some of the new features, we introduce new stats
+that need to be collected.
+TODO: Fill this later.
+
+APPENDIX 1: discussion on using ethernet HW FC
+==============================================
+Most chips with FC only send a pause packet when they run out of Rx buffers.
+Since packets are pulled off the DMA ring by a softirq in NAPI,
+if the system is slow in grabbing them and we have a high input
+rate (faster than the system's capacity to remove packets), then theoretically
+there will only be one rx interrupt for all packets during a given packetstorm.
+Under low load, we might have a single interrupt per packet.
+FC should be programmed to apply in the case when the system cant pull out
+packets fast enough i.e send a pause only when you run out of rx buffers.
+Note FC in itself is a good solution but we have found it to not be
+much of a commodity feature (both in NICs and switches) and hence falls
+under the same category as using NIC based mitigation. Also experiments
+indicate that its much harder to resolve the resource allocation
+issue (aka lazy receiving that NAPI offers) and hence quantify its usefullness
+proved harder. In any case, FC works even better with NAPI but is not
+necessary.
+
+
+APPENDIX 2: the "rotting packet" race-window avoidance scheme 
+=============================================================
+
+There are two types of associations seen here
+
+1) status/int which honors level triggered IRQ
+
+If a status bit for receive or rxnobuff is set and the corresponding 
+interrupt-enable bit is not on, then no interrupts will be generated. However, 
+as soon as the "interrupt-enable" bit is unmasked, an immediate interrupt is 
+generated.  [assuming the status bit was not turned off].
+Generally the concept of level triggered IRQs in association with a status and
+interrupt-enable CSR register set is used to avoid the race.
+
+If we take the example of the tulip:
+"pending work" is indicated by the status bit(CSR5 in tulip).
+the corresponding interrupt bit (CSR7 in tulip) might be turned off (but
+the CSR5 will continue to be turned on with new packet arrivals even if
+we clear it the first time)
+Very important is the fact that if we turn on the interrupt bit on when
+status is set that an immediate irq is triggered.
+ 
+If we cleared the rx ring and proclaimed there was "no more work
+to be done" and then went on to do a few other things;  then when we enable
+interrupts, there is a possibility that a new packet might sneak in during
+this phase. It helps to look at the pseudo code for the tulip poll
+routine:
+
+--------------------------
+        do {
+                ACK;
+                while (ring_is_not_empty()) {
+                        work-work-work
+                        if quota is exceeded: exit, no touching irq status/mask
+                }
+                /* No packets, but new can arrive while we are doing this*/
+                CSR5 := read
+                if (CSR5 is not set) {
+                        /* If something arrives in this narrow window here,
+                        *  where the comments are ;-> irq will be generated */
+                        unmask irqs;
+                        exit poll;
+                }
+        } while (rx_status_is_set);
+------------------------
+
+CSR5 bit of interest is only the rx status. 
+If you look at the last if statement: 
+you just finished grabbing all the packets from the rx ring .. you check if
+status bit says theres more packets just in ... it says none; you then
+enable rx interrupts again; if a new packet just came in during this check,
+we are counting that CSR5 will be set in that small window of opportunity
+and that by re-enabling interrupts, we would actually triger an interrupt
+to register the new packet for processing.
+
+[The above description nay be very verbose, if you have better wording 
+that will make this more understandable, please suggest it.]
+
+2) non-capable hardware
+
+These do not generally respect level triggered IRQs. Normally,
+irqs may be lost while being masked and the only way to leave poll is to do
+a double check for new input after netif_rx_complete() is invoked
+and re-enable polling (after seeing this new input).
+
+Sample code:
+
+---------
+	.
+	.
+restart_poll:
+	while (ring_is_not_empty()) {
+		work-work-work
+		if quota is exceeded: exit, not touching irq status/mask
+	}
+	.
+	.
+	.
+	enable_rx_interrupts()
+	netif_rx_complete(dev);
+	if (ring_has_new_packet() && netif_rx_reschedule(dev, received)) {
+		disable_rx_and_rxnobufs()
+		goto restart_poll
+	} while (rx_status_is_set);
+---------
+		
+Basically netif_rx_complete() removes us from the poll list, but because a
+new packet which will never be caught due to the possibility of a race
+might come in, we attempt to re-add ourselves to the poll list. 
+
+
+
+--------------------------------------------------------------------
+
+relevant sites:
+==================
+ftp://robur.slu.se/pub/Linux/net-development/NAPI/
+
+
+--------------------------------------------------------------------
+TODO: Write net-skeleton.c driver.
+-------------------------------------------------------------
+
+Authors:
+========
+Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
+Jamal Hadi Salim <hadi@cyberus.ca>
+Robert Olsson <Robert.Olsson@data.slu.se>
+
+Acknowledgements:
+================
+People who made this document better:
+
+Lennert Buytenhek <buytenh@gnu.org>
+Andrew Morton  <akpm@zip.com.au>
+Manfred Spraul <manfred@colorfullife.com>
+Donald Becker <becker@scyld.com>
+Jeff Garzik 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/dl2k.txt linux-bk/Documentation/networking/dl2k.txt
--- linux-2.4.19/Documentation/networking/dl2k.txt	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/networking/dl2k.txt	2002-08-17 00:48:52.000000000 +0000
@@ -1,7 +1,7 @@
 
     D-Link DL2000-based Gigabit Ethernet Adapter Installation
     for Linux
-    Jan 29, 2002
+    May 23, 2002
 
 Contents
 ========
@@ -202,7 +202,7 @@
 				  1000mbps_fd and 1000mbps_hd types are only
 				  available for fiber adapter.
 
-vlan=[0|1]			- Specifies the VLAN ID. If vlan=0, the
+vlan=n				- Specifies the VLAN ID. If vlan=0, the
 				  Virtual Local Area Network (VLAN) function is
 				  disable.
 
@@ -211,24 +211,34 @@
 				  function is disabled.
 				  Jumbo frame usually improve the performance
 				  int gigabit.
+				  This feature need jumbo frame compatible 
+				  remote.
 				  
-rx_coalesce=n			- Rx frame count each interrupt.
-rx_timeout=n			- Rx DMA wait time for an interrupt. Proper 
-				  values of rx_coalesce and rx_timeout bring 
-				  a conspicuous performance in the fast machine.
-				  Ex. rx_coalesce=5 and rx_timeout=750 
-
-tx_coalesce=n			- Tx transmit count each TxComp interrupt.
-				  Setting value larger than 1 will improve 
-				  performance, but this is possible to lower 
-				  stability in slow UP machines. By default, 
-				  tx_coalesce=1. (dl2k)
+rx_coalesce=m			- Number of rx frame handled each interrupt.
+rx_timeout=n			- Rx DMA wait time for an interrupt. 
+				  If set rx_coalesce > 0, hardware only assert 
+				  an interrupt for m frames. Hardware won't 
+				  assert rx interrupt until m frames received or
+				  reach timeout of n * 640 nano seconds. 
+				  Set proper rx_coalesce and rx_timeout can 
+				  reduce congestion collapse and overload which
+				  has been a bottlenect for high speed network.
 				  
-tx_flow=[1|0]			- Specifies the Tx flow control. If tx_flow=1, 
-				  the Tx flow control enable.
+				  For example, rx_coalesce=10 rx_timeout=800.
+				  that is, hardware assert only 1 interrupt 
+				  for 10 frames received or timeout of 512 us. 
+
+tx_coalesce=n			- Number of tx frame handled each interrupt.
+				  Set n > 1 can reduce the interrupts 
+				  congestion usually lower performance of
+				  high speed network card. Default is 16.
 				  
-rx_flow=[1|0]			- Specifies the Rx flow control. If rx_flow=1, 
-				  the Rx flow control enable.
+tx_flow=[1|0]			- Specifies the Tx flow control. If tx_flow=0, 
+				  the Tx flow control disable else driver
+				  autodetect.
+rx_flow=[1|0]			- Specifies the Rx flow control. If rx_flow=0, 
+				  the Rx flow control enable else driver
+				  autodetect.
 
 
 Configuration Script Sample
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/e100.txt linux-bk/Documentation/networking/e100.txt
--- linux-2.4.19/Documentation/networking/e100.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/networking/e100.txt	2002-08-17 00:49:00.000000000 +0000
@@ -0,0 +1,272 @@
+Linux* Base Driver for the Intel(R) PRO/100 Family of Adapters
+==============================================================
+
+April 9, 2002
+
+
+Contents
+========
+
+- In This Release
+- Supported Adapters
+- Command Line Parameters
+- CPU Cycle Saver
+- Additional Configurations
+- Support
+
+
+In This Release
+===============
+
+This file describes the Linux* Base Driver for the Intel(R) PRO/100 Family of
+Adapters, version 2.0.x.  This driver includes support for Itanium(TM)-based 
+systems.
+
+New for this release:
+
+   - Additional ethtool functionality, including link status test and EEPROM 
+     read/write. A third-party application can use the ethtool interface to 
+     get and set driver parameters.
+
+   - Support for Zero copy on 82550-based adapters. This feature provides 
+     faster data throughput and significant CPU usage improvement in systems 
+     that use the relevant system call (sendfile(2)).
+
+   - Support for large MTU-enabling interface (1504 bytes) with kernel's 
+     VLAN module
+
+   - Support for polling on RX
+
+   - Support for Wake On LAN* on 82550 and 82559-based adapters
+
+
+Supported Adapters
+==================
+
+The following Intel network adapters are compatible with the drivers 
+in this release:
+
+Controller  Adapter Name                            Board IDs
+----------  ------------                            ---------
+
+82558       PRO/100+ PCI Adapter                    668081-xxx, 689661-xxx
+
+82558       PRO/100+ Management Adapter             691334-xxx, 701738-xxx,
+                                                    721383-xxx
+
+82558       PRO/100+ Dual Port Server Adapter       714303-xxx, 711269-xxx, 
+                                                    A28276-xxx
+
+82558       PRO/100+ PCI Server Adapter             710550-xxx
+
+82550       PRO/100 S Server Adapter                752438-xxx (82550)
+82559                                               A56831-xxx, A10563-xxx,
+                                                    A12171-xxx, A12321-xxx, 
+                                                    A12320-xxx, A12170-xxx
+                                                    748568-xxx (82559)
+                                                    748565-xxx (82559)
+
+
+82550       PRO/100 S Desktop Adapter               751767-xxx (82550)
+82559                                               748592-xxx, A12167-xxx, 
+                                                    A12318-xxx, A12317-xxx, 
+                                                    A12165-xxx
+                                                    748569-xxx (82559)
+
+
+
+82559       PRO/100+ Server Adapter                 729757-xxx
+
+82559       PRO/100 S Management Adapter            748566-xxx, 748564-xxx
+
+82550       PRO/100 S Dual Port Server Adapter      A56831-xxx
+
+82551       PRO/100 M Desktop Adapter               A80897-xxx
+
+            PRO/100 S Advanced Management Adapter   747842-xxx, 745171-xxx
+
+CNR         PRO/100 VE Desktop Adapter              A10386-xxx, A10725-xxx, 
+                                                    A23801-xxx, A19716-xxx
+
+
+            PRO/100 VM Desktop Adapter              A14323-xxx, A19725-xxx, 
+                                                    A23801-xxx, A22220-xxx, 
+                                                    A23796-xxx
+   
+
+To verify that your adapter is supported, find the board ID number on the 
+adapter. Look for a label that has a barcode and a number in the format 
+123456-001 (six digits hyphen three digits). Match this to the list of 
+numbers above.
+
+For more information on how to identify your adapter, go to the Adapter & 
+Driver ID Guide at:
+
+  http://support.intel.com/support/network/adapter/pro100/21397.htm
+
+For the latest Intel PRO/100 network driver for Linux, see:
+
+  http://appsr.intel.com/scripts-df/support_intel.asp
+
+
+Command Line Parameters
+=======================
+
+The following parameters are used by entering them on the command line with 
+the modprobe or insmod command. For example, with two Intel PRO/100 PCI 
+adapters, entering:
+	
+     modprobe e100 TxDescriptors=32,128
+
+loads the e100 driver with 32 TX resources for the first adapter and 128 TX 
+resources for the second adapter. This configuration favors the second 
+adapter. The driver supports up to 16 network adapters concurrently.
+
+NOTE: Giving any command line option the value "-1" causes the driver to use 
+      the appropriate default value for that option, as if no value was 
+      specified.
+
+
+BundleMax
+Valid Range: 0x1-0xFFFF
+Default Value: 6
+   This parameter holds the maximum number of packets in a bundle. Suggested 
+   values range from 2 to 10. See "CPU Cycle Saver."
+
+BundleSmallFr
+Valid Range: 0-1 (0=off, 1=on)
+Default Value: 0
+   The value 1 (on) causes small packets (less than 128 bytes) to be bundled. 
+   See "CPU Cycle Saver."
+
+e100_speed_duplex
+Valid Range: 0-4 (1=10half;2=10full;3=100half;4=100full)
+Default Value: 0
+   The default value of 0 is set to auto-negotiate if the link partner is set
+   to auto-negotiate. If the link partner is forced, e100_speed_duplex 
+   defaults to half-duplex. 
+   Example usage: insmod e100.o e100_speed_duplex=4,4 (for two adapters)
+
+flow_control
+Valid Range: 0-1 (0=off, 1=on)
+Default Value: 0
+   This parameter controls the automatic generation(Tx) and response(Rx) to 
+   Ethernet PAUSE frames. flow_control should NOT be set to 1 when the e100 
+   adapter is connected to an interface that does not support Ethernet PAUSE 
+   frames and when the e100_speed_duplex parameter is NOT set to zero. 
+
+IntDelay
+Valid Range: 0-0xFFFF (0=off)
+Default Value: 1536
+   This parameter holds the number of time units (in adapter terminology)
+   until the adapter generates an interrupt. The recommended value for 
+   IntDelay is 0x600 (upon initialization). Suggested values range from 
+   0x200h to 0x800. See "CPU Cycle Saver."
+
+IFS
+Valid Range: 0-1 (0=off, 1=on)
+Default Value: 1
+  Inter Frame Spacing (IFS) aims to reduce the number of Ethernet frame
+  collisions by altering the time between frame transmissions. When IFS is 
+  enabled the driver tries to find an optimal IFS value. However, some 
+  switches function better when IFS is disabled.
+
+PollingMaxWork
+Valid Range: 1-1024 (max number of RxDescriptors)
+Default Value: Specified number of RxDescriptors
+  This value specifies the maximum number of receive packets that are 
+  processed on a single polling call. This parameter is invalid if 
+  RxCongestionControl is set to 0.
+
+RxCongestionControl
+Valid Range: 0-1 (0=off, 1=on)
+Default Value: 1
+  1 enables polling mode. When the link is congested, the driver can decide 
+  to handle received packets by polling them, instead of waiting until 
+  interrupts occur.
+
+RxDescriptors
+Valid Range: 8-1024
+Default Value: 64
+   This parameter defines the number of receive descriptors allocated by 
+   the driver. Increasing this value allows the driver to buffer more 
+   incoming packets before the driver is required to service an interrupt. 
+   The maximum value for Itanium-based systems is 64.
+
+TxDescriptors
+Valid Range: 19-1024
+Default Value: 64
+   This value is the number of transmit descriptors allocated by the driver. 
+   Increasing this value allows the protocol stack to queue more transmits at
+   the driver level. The maximum value for Itanium-based systems is 64.
+
+ucode (not available for 82557-based adapters)
+Valid Range: 0-1 (0=off, 1=on)
+Default Value: 0 for 82558-based adapters
+               1 for 82559(and higher)-based adapters
+   On uploads the micro code to the adapter, which enables CPU Cycle Saver. 
+   See the section "CPU Cycle Saver" below.
+   Example usage: insmod e100.o ucode=0  (does not reduce CPU usage)
+
+XsumRX
+Valid Range: 0-1 (0=off, 1=on)
+Default Value: 1
+   On allows Rx checksum offloading for TCP/UDP packets. Requires that the 
+   hardware support this feature.
+
+
+CPU Cycle Saver
+================
+
+CPU Cycle Saver reduces CPU utilization by reducing the number of interrupts 
+that the adapter generates.
+
+When CPU Cycle Saver is turned off, the adapter generates one interrupt for 
+every frame that is received. This means that the operating system stops what
+it is doing and switches to the network driver in order to process the 
+receive.
+
+When CPU Cycle Saver is on, the adapter does not generate an interrupt for 
+every frame it receives. Instead, it waits until it receives several frames 
+before generating an interrupt. This reduces the amount of time spent 
+switching to and from the driver. 
+
+CPU Cycle Saver consists of these arguments: IntDelay, BundleMax and 
+BundleSmallFr. When IntDelay is increased, the adapter waits longer for 
+frames to arrive before generating the interrupt. By increasing BundleMax, 
+the network adapter waits for the number of frames specified to arrive before 
+generating the interrupt. When BundleSmallFr is disabled, the adapter does 
+not bundle packets that are smaller than 128 bytes. Such small packets are 
+often, but not always, control packets that are better served immediately.
+
+For most users, it is recommended that CPU Cycle Saver be used with the 
+default values specified in the Command Line Parameters section. However, in 
+some cases, performance problems may occur with CPU Cycle Saver. If such 
+problems are observed, we recommend turning off this feature by setting 
+ucode=0.
+
+
+Support
+=======
+
+For general information and support, go to the Intel support website at:
+
+    http://support.intel.com
+
+If an issue is identified with the released source code on the supported
+kernel with a supported adapter, email the specific information related to 
+the issue to linux.nics@intel.com.
+
+
+License
+=======
+
+This software program is released under the terms of a license agreement 
+between you ('Licensee') and Intel. Do not use or load this software or any 
+associated materials (collectively, the 'Software') until you have carefully 
+read the full terms and conditions of the LICENSE located in this software 
+package. By loading or using the Software, you agree to the terms of this 
+Agreement. If you do not agree with the terms of this Agreement, do not 
+install or use the Software.
+
+* Other names and brands may be claimed as the property of others.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/e1000.txt linux-bk/Documentation/networking/e1000.txt
--- linux-2.4.19/Documentation/networking/e1000.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/networking/e1000.txt	2002-08-17 00:49:09.000000000 +0000
@@ -0,0 +1,272 @@
+Linux* Base Driver for the Intel(R) PRO/1000 Family of Adapters
+===============================================================
+
+June 11, 2002
+
+
+Contents
+========
+
+- In This Release
+- Supported Adapters
+- Command Line Parameters
+- Speed and Duplex Configuration
+- Additional Configurations
+- Known Issues
+- Support
+
+
+In This Release
+===============
+
+This file describes the Linux* Base Driver for the Intel(R) PRO/1000 Family
+of Adapters, version 4.2.x.  This driver includes support for 
+Itanium(TM)-based systems.
+
+This release version includes the following:
+
+   - Support for the ethtool 1.5 interface. A third-party application can use
+     the ethtool interface to get and set driver parameters.
+
+   - Zero copy. This feature provides faster data throughput. Enabled by
+     default in supporting kernels. It is not supported on the Intel(R)
+     PRO/1000 Gigabit Server Adapter.
+
+New features include:
+
+   - Support for the 82545 and 82546-based adapters listed below
+
+   - Wake on LAN* support via ethtool for 82540, 82544, 82545, and 82546-
+     based adapters
+
+   - Adaptive IFS for increased performance at half duplex
+
+
+
+Supported Adapters
+==================
+
+The following Intel network adapters are compatible with the drivers in this
+release:
+
+   Controller  Adapter Name                         Board IDs
+   ----------  ------------                         ---------
+
+   82542       PRO/1000 Gigabit Server Adapter      700262-xxx, 717037-xxx
+
+   82543       PRO/1000 F Server Adapter            738640-xxx, A38888-xxx
+
+   82543       PRO/1000 T Server Adapter            A19845-xxx, A33948-xxx
+
+   82544       PRO/1000 XT Server Adapter           A51580-xxx
+
+   82544       PRO/1000 XF Server Adapter           A50484-xxx
+
+   82544       PRO/1000 T Desktop Adapter           A62947-xxx
+
+   82540       PRO/1000 MT Desktop Adapter          A78408-xxx
+
+   82545       PRO/1000 MT Server Adapter           A92165-xxx
+
+   82546       PRO/1000 MT Dual Port Server Adapter A92111-xxx
+
+   82545       PRO/1000 MF Server Adapter           A91622-xxx
+
+   82545       PRO/1000 MF Server Adapter(LX)       A91624-xxx
+
+   82546       PRO/1000 MF Dual Port Server Adapter A91620-xxx
+
+
+To verify your Intel adapter is supported, find the board ID number on the
+adapter. Look for a label that has a barcode and a number in the format of
+123456-001 (six digits hyphen three digits). Match this to the list of
+numbers above.
+
+For more information on how to identify your adapter, go to the Adapter &
+Driver ID Guide at:
+
+    http://support.intel.com/support/network/adapter/pro100/21397.htm
+
+For the latest Intel network drivers for Linux, go to:
+
+    http://appsr.intel.com/scripts-df/support_intel.asp
+
+
+Command Line Parameters
+=======================
+
+If the driver is built as a module, the following optional parameters are 
+used by entering them on the command line with the modprobe or insmod command. 
+For example, with two PRO/1000 PCI adapters, entering:
+
+    insmod e1000 TxDescriptors=80,128
+
+loads the e1000 driver with 80 TX resources for the first adapter and 128 TX
+resources for the second adapter.
+
+For more information about the AutoNeg, Duplex, and Speed parameters, see the
+"Speed and Duplex Configuration" section in this document.
+
+
+AutoNeg (adapters using copper connections only)
+Valid Range: 0x01-0x0F, 0x20-0x2F
+Default Value: 0x2F
+    This parameter is a bit mask that specifies which speed and duplex
+    settings the board advertises. When this parameter is used, the Speed and
+    Duplex parameters must not be specified.
+
+Duplex (adapters using copper connections only)
+Valid Range: 0-2 (0=auto-negotiate, 1=half, 2=full)
+Default Value: 0
+    Defines the direction in which data is allowed to flow. Can by either one
+    or two-directional. If both Duplex and the link partner are set to auto-
+    negotiate, the board auto-detects the correct duplex. If the link partner
+    is forced (either full or half), Duplex defaults to half-duplex.
+
+FlowControl
+Valid Range: 0-3 (0=none, 1=Rx only, 2=Tx only, 3=Rx&Tx)
+Default: Read flow control settings from the EEPROM
+    This parameter controls the automatic generation(Tx) and response(Rx) to
+    Ethernet PAUSE frames.
+
+RxDescriptors
+Valid Range: 80-256 for 82542 and 82543-based adapters
+             80-4096 for 82540, 82544, 82545, and 82546-based adapters
+Default Value: 80
+    This value is the number of receive descriptors allocated by the driver.
+    Increasing this value allows the driver to buffer more incoming packets.
+    Each descriptor is 16 bytes.  A receive buffer is also allocated for each
+    descriptor and can be either 2048, 4096, 8192, or 16384 bytes, depending
+    on the MTU setting. The maximum MTU size is 16110.
+
+RxIntDelay
+Valid Range: 0-65535 (0=off)
+Default Value: 0 (82542, 82543, and 82544-based adapters)
+               128 (82540, 82545, and 82546-based adapters)
+    This value delays the generation of receive interrupts in units of 1.024
+    microseconds.  Receive interrupt reduction can improve CPU efficiency if
+    properly tuned for specific network traffic. Increasing this value adds
+    extra latency to frame reception and can end up decreasing the throughput
+    of TCP traffic. If the system is reporting dropped receives, this value
+    may be set too high, causing the driver to run out of available receive
+    descriptors.
+
+    CAUTION: When setting RxIntDelay to a value other than 0, adapters based
+             on the Intel 82543 and 82544 LAN controllers may hang (stop
+             transmitting) under certain network conditions. If this occurs a
+             message is logged in the system event log. In addition, the
+             controller is automatically reset, restoring the network
+             connection. To eliminate the potential for the hang ensure that
+             RxIntDelay is set to 0.
+
+Speed (adapters using copper connections only)
+Valid Settings: 0, 10, 100, 1000
+Default Value: 0 (auto-negotiate at all supported speeds)
+    Speed forces the line speed to the specified value in megabits per second
+    (Mbps). If this parameter is not specified or is set to 0 and the link
+    partner is set to auto-negotiate, the board will auto-detect the correct
+    speed. Duplex must also be set when Speed is set to either 10 or 100.
+
+TxDescriptors
+Valid Range: 80-256 for 82542 and 82543-based adapters
+             80-4096 for 82540, 82544, 82545, and 82546-based adapters
+Default Value: 256
+    This value is the number of transmit descriptors allocated by the driver.
+    Increasing this value allows the driver to queue more transmits. Each
+    descriptor is 16 bytes.
+
+XsumRX (not available on the PRO/1000 Gigabit Server Adapter)
+Valid Range: 0-1
+Default Value: 1
+    A value of '1' indicates that the driver should enable IP checksum
+    offload for received packets (both UDP and TCP) to the adapter hardware.
+
+
+Speed and Duplex Configuration
+==============================
+
+Three keywords are used to control the speed and duplex configuration. These
+keywords are Speed, Duplex, and AutoNeg.
+
+If the board uses a fiber interface, these keywords are ignored, and the
+fiber interface board only links at 1000 Mbps full-duplex.
+
+For copper-based boards, the keywords interact as follows:
+
+  The default operation is auto-negotiate. The board advertises all supported
+  speed and duplex combinations, and it links at the highest common speed and
+  duplex mode IF the link partner is set to auto-negotiate.
+
+  If Speed = 1000, limited auto-negotiation is enabled and only 1000 Mbps is
+  advertised (The 1000BaseT spec requires auto-negotiation.)
+
+  If Speed = 10 or 100, then both Speed and Duplex must be set. Auto-
+  negotiation is disabled, and the AutoNeg parameter is ignored. Partner MUST
+  also be forced.
+
+The AutoNeg parameter is used when more control is required over the auto-
+negotiation process.  When this parameter is used, Speed and Duplex must not
+be specified.  This parameter is a bitmap that specifies which speed and
+duplex settings are advertised to the link partner.
+
+Bit            7      6      5       4       3      2      1       0
+Speed (Mbps)   N/A    N/A    1000    N/A     100    100    10      10
+Duplex                       Full            Full   Half   Full    Half
+
+Note that setting AutoNeg does not guarantee that the board will link at the
+highest specified speed or duplex mode, but the board will link at the
+highest possible speed/duplex of the link partner IF the link partner is also
+set to auto-negotiate. If the link partner is forced speed/duplex, the
+adapter MUST be forced to the same speed/duplex.
+
+
+Additional Configurations
+=========================
+
+  Jumbo Frames
+  ------------
+
+  The driver supports Jumbo Frames for all adapters except 82542-based
+  adapters.  Jumbo Frames support is enabled by changing the MTU to a value
+  larger than the default of 1500.  Use the ifconfig command to increase the
+  MTU size. For example:
+
+        ifconfig ethx mtu 9000 up
+
+
+Known Issues
+============
+
+  Jumbo Frames System Requirement
+  -------------------------------
+
+  Memory allocation failures have been observed on Linux systems with 64 MB
+  of RAM or less that are running Jumbo Frames. If you are using Jumbo
+  Frames, your system may require more than the advertised minimum
+  requirement of 64 MB of system memory.
+
+
+Support
+=======
+
+For general information and support, go to the Intel support website at:
+
+    http://support.intel.com
+
+If an issue is identified with the released source code on the supported
+kernel with a supported adapter, email the specific information related to
+the issue to linux.nics@intel.com.
+
+
+License
+=======
+
+This software program is released under the terms of a license agreement
+between you ('Licensee') and Intel. Do not use or load this software or any
+associated materials (collectively, the 'Software') until you have carefully
+read the full terms and conditions of the LICENSE located in this software
+package. By loading or using the Software, you agree to the terms of this
+Agreement. If you do not agree with the terms of this Agreement, do not
+install or use the Software.
+
+* Other names and brands may be claimed as the property of others.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/pktgen.txt linux-bk/Documentation/networking/pktgen.txt
--- linux-2.4.19/Documentation/networking/pktgen.txt	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/networking/pktgen.txt	2002-08-17 00:49:01.000000000 +0000
@@ -4,6 +4,9 @@
    in the place where insmod may find it.
 2. Cut script "ipg" (see below).
 3. Edit script to set preferred device and destination IP address.
+3a.  Create more scripts for different interfaces.  Up to thirty-two
+     pktgen processes can be configured and run at once by using the
+     32 /proc/net/pg* files.
 4. Run in shell: ". ipg"
 5. After this two commands are defined:
    A. "pg" to start generator and to get results.
@@ -12,12 +15,33 @@
       pgset "multiskb 0"      use single SKB for all transmits
       pgset "pkt_size 9014"   sets packet size to 9014
       pgset "frags 5"         packet will consist of 5 fragments
-      pgset "count 200000"    sets number of packets to send
+      pgset "count 200000"    sets number of packets to send, set to zero
+                              for continious sends untill explicitly
+                              stopped.
       pgset "ipg 5000"        sets artificial gap inserted between packets
                               to 5000 nanoseconds
       pgset "dst 10.0.0.1"    sets IP destination address
                               (BEWARE! This generator is very aggressive!)
+      pgset "dst_min 10.0.0.1"            Same as dst
+      pgset "dst_max 10.0.0.254"          Set the maximum destination IP.
+      pgset "src_min 10.0.0.1"            Set the minimum (or only) source IP.
+      pgset "src_max 10.0.0.254"          Set the maximum source IP.
       pgset "dstmac 00:00:00:00:00:00"    sets MAC destination address
+      pgset "srcmac 00:00:00:00:00:00"    sets MAC source address
+      pgset "src_mac_count 1" Sets the number of MACs we'll range through.  The
+                              'minimum' MAC is what you set with srcmac.
+      pgset "dst_mac_count 1" Sets the number of MACs we'll range through.  The
+                              'minimum' MAC is what you set with dstmac.
+      pgset "flag [name]"     Set a flag to determine behaviour.  Current flags
+                              are: IPSRC_RND #IP Source is random (between min/max),
+                                   IPDST_RND, UDPSRC_RND,
+                                   UDPDST_RND, MACSRC_RND, MACDST_RND 
+      pgset "udp_src_min 9"   set UDP source port min, If < udp_src_max, then
+                              cycle through the port range.
+      pgset "udp_src_max 9"   set UDP source port max.
+      pgset "udp_dst_min 9"   set UDP destination port min, If < udp_dst_max, then
+                              cycle through the port range.
+      pgset "udp_dst_max 9"   set UDP destination port max.
       pgset stop    	      aborts injection
       
   Also, ^C aborts generator.
@@ -26,22 +50,24 @@
 
 #! /bin/sh
 
-modprobe pktgen.o
+modprobe pktgen
+
+PGDEV=/proc/net/pg/pg0
 
 function pgset() {
     local result
 
-    echo $1 > /proc/net/pg
+    echo $1 > $PGDEV
 
-    result=`cat /proc/net/pg | fgrep "Result: OK:"`
+    result=`cat $PGDEV | fgrep "Result: OK:"`
     if [ "$result" = "" ]; then
-         cat /proc/net/pg | fgrep Result:
+         cat $PGDEV | fgrep Result:
     fi
 }
 
 function pg() {
-    echo inject > /proc/net/pg
-    cat /proc/net/pg
+    echo inject > $PGDEV
+    cat $PGDEV
 }
 
 pgset "odev eth0"
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/parisc/00-INDEX linux-bk/Documentation/parisc/00-INDEX
--- linux-2.4.19/Documentation/parisc/00-INDEX	2000-12-05 20:29:38.000000000 +0000
+++ linux-bk/Documentation/parisc/00-INDEX	2002-08-17 00:49:10.000000000 +0000
@@ -1,10 +1,10 @@
 00-INDEX
 	- this file.
 IODC.txt
-	- Documentation IODC
+	- Documentation for IODC
 debugging
 	- some debugging hints for real-mode code
-mm
-	- Documentation on parisc mm status
+unwritten
+	- list of unwritten / incomplete functions
 registers
 	- current/planned usage of registers
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/parisc/registers linux-bk/Documentation/parisc/registers
--- linux-2.4.19/Documentation/parisc/registers	2001-09-14 21:04:06.000000000 +0000
+++ linux-bk/Documentation/parisc/registers	2002-08-17 00:48:47.000000000 +0000
@@ -25,8 +25,8 @@
 CR27 (TR 3)			Thread descriptor pointer
 CR28 (TR 4)			not used
 CR29 (TR 5)			not used
-CR30 (TR 6)			current / 0
-CR31 (TR 7)			Temporary register, used in various places
+CR30 (TR 6)			current
+CR31 (TR 7)			interrupt stack base
 
 	Space Registers (kernel mode)
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/sysctl/vm.txt linux-bk/Documentation/sysctl/vm.txt
--- linux-2.4.19/Documentation/sysctl/vm.txt	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/sysctl/vm.txt	2002-08-17 00:49:11.000000000 +0000
@@ -1,4 +1,4 @@
-Documentation for /proc/sys/vm/*	kernel version 2.2.10
+Documentation for /proc/sys/vm/*	kernel version 2.4.19
 	(c) 1998, 1999,  Rik van Riel <riel@nl.linux.org>
 
 For general info and legal blurb, please look in README.
@@ -6,7 +6,7 @@
 ==============================================================
 
 This file contains the documentation for the sysctl files in
-/proc/sys/vm and is valid for Linux kernel version 2.2.
+/proc/sys/vm and is valid for Linux kernel version 2.4.
 
 The files in this directory can be used to tune the operation
 of the virtual memory (VM) subsystem of the Linux kernel, and
@@ -34,26 +34,27 @@
 This file controls the operation of the bdflush kernel
 daemon. The source code to this struct can be found in
 linux/fs/buffer.c. It currently contains 9 integer values,
-of which 4 are actually used by the kernel.
+of which 6 are actually used by the kernel.
 
 From linux/fs/buffer.c:
 --------------------------------------------------------------
 union bdflush_param {
 	struct {
-		int nfract;	/* Percentage of buffer cache dirty to 
+		int nfract;	/* Percentage of buffer cache dirty to
 				   activate bdflush */
-		int dummy1;	/* old "ndirty" */
+		int ndirty;	/* Maximum number of dirty blocks to write out per
+				   wake-cycle */
 		int dummy2;	/* old "nrefill" */
 		int dummy3;	/* unused */
 		int interval;	/* jiffies delay between kupdate flushes */
-		int age_buffer;	/* Time for normal buffer to age */
-		int nfract_sync;/* Percentage of buffer cache dirty to 
+		int age_buffer;	/* Time for normal buffer to age before we flush it */
+		int nfract_sync;/* Percentage of buffer cache dirty to
 				   activate bdflush synchronously */
-		int dummy4;	/* unused */
+		int nfract_stop_bdflush; /* Percentage of buffer cache dirty to stop bdflush */
 		int dummy5;	/* unused */
 	} b_un;
 	unsigned int data[N_PARAM];
-} bdf_prm = {{30, 64, 64, 256, 5*HZ, 30*HZ, 60, 0, 0}};
+} bdf_prm = {{30, 500, 0, 0, 5*HZ, 30*HZ, 60, 20, 0}};
 --------------------------------------------------------------
 
 int nfract:
@@ -68,6 +69,13 @@
 more frequent I/O operations.  The default value is 30%,
 the minimum is 0%, and the maximum is 100%.
 
+int ndirty:
+The second parameter (ndirty) gives the maximum number of
+dirty buffers that bdflush can write to the disk in one time.
+A high value will mean delayed, bursty I/O, while a small
+value can lead to memory shortage when bdflush isn't woken
+up often enough.
+
 int interval:
 The fifth parameter, interval, is the minimum rate at
 which kupdate will wake and flush.  The value is expressed in
@@ -88,7 +96,11 @@
 synchronously.  This can be viewed as the hard limit before
 bdflush forces buffers to disk.  The default is 60%, the
 minimum is 0%, and the maximum is 100%.
- 
+
+int nfract_stop_bdflush:
+The eighth parameter, nfract_stop_bdflush, governs the percentage
+of buffer cache that is dirty which will stop bdflush.
+The default is 20%, the miniumum is 0%, and the maxiumum is 100%.
 ==============================================================
 buffermem:
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/usb/silverlink.txt linux-bk/Documentation/usb/silverlink.txt
--- linux-2.4.19/Documentation/usb/silverlink.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/usb/silverlink.txt	2002-08-17 00:48:52.000000000 +0000
@@ -0,0 +1,76 @@
+-------------------------------------------------------------------------
+Readme for Linux device driver for the Texas Instruments SilverLink cable
+-------------------------------------------------------------------------
+
+Author: Romain Liévin & Julien Blache
+Homepage: http://lpg.ticalc.org/prj_usb
+
+INTRODUCTION:
+
+This is a driver for the TI-GRAPH LINK USB (aka SilverLink) cable, a cable 
+designed by TI for connecting their TI8x/9x calculators to a computer 
+(PC or Mac usually).
+
+If you need more information, please visit the 'SilverLink drivers' homepage 
+at the above URL.
+
+WHAT YOU NEED:
+
+A TI calculator of course and a program capable to communicate with your 
+calculator.
+TiLP will work for sure (since I am his developer !). yal92 may be able to use
+it by changing tidev for tiglusb (may require some hacking...).
+
+HOW TO USE IT:
+
+You must have first compiled USB support, support for your specific USB host
+controller (UHCI or OHCI).
+
+Next, (as root) from your appropriate modules directory (lib/modules/2.5.XX):
+
+       insmod usb/usbcore.o
+       insmod usb/usb-uhci.o  <OR>  insmod usb/ohci-hcd.o
+       insmod tiglusb.o
+
+If it is not already there (it usually is), create the device:
+
+       mknod /dev/tiglusb0 c 115 16
+
+You will have to set permissions on this device to allow you to read/write
+from it:
+
+       chmod 666 /dev/tiglusb0
+       
+Now you are ready to run a linking program such as TiLP. Be sure to configure 
+it properly (RTFM).
+       
+MODULE PARAMETERS:
+
+  You can set these with:  insmod tiglusb NAME=VALUE
+  There is currently no way to set these on a per-cable basis.
+
+  NAME: timeout
+  TYPE: integer
+  DEFAULT: 15
+  DESC: Timeout value in tenth of seconds. If no data is available once this 
+       time has expired then the driver will return with a timeout error.
+
+QUIRKS:
+
+The following problem seems to be specific to the link cable since it appears 
+on all platforms (Linux, Windows, Mac OS-X). 
+
+In some very particular cases, the driver returns with success but
+without any data. The application should retry a read operation at least once.
+
+HOW TO CONTACT US:
+
+You can email me at roms@lpg.ticalc.org. Please prefix the subject line
+with "TIGLUSB: " so that I am certain to notice your message.
+You can also mail JB at jb@jblache.org: he has written the first release of 
+this driver but he better knows the Mac OS-X driver.
+
+CREDITS:
+
+The code is based on dabusb.c, printer.c and scanner.c !
+The driver has been developed independantly of Texas Instruments.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/video4linux/bttv/CARDLIST linux-bk/Documentation/video4linux/bttv/CARDLIST
--- linux-2.4.19/Documentation/video4linux/bttv/CARDLIST	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/video4linux/bttv/CARDLIST	2002-08-17 00:48:51.000000000 +0000
@@ -3,41 +3,41 @@
   card=1 - MIRO PCTV
   card=2 - Hauppauge (bt848)
   card=3 - STB
-  card=4 - Intel
+  card=4 - Intel Create and Share PCI/ Smart Video Recorder III
   card=5 - Diamond DTV2000
   card=6 - AVerMedia TVPhone
   card=7 - MATRIX-Vision MV-Delta
-  card=8 - FlyVideo II (Bt848) LR26
-  card=9 - IXMicro TurboTV
+  card=8 - Lifeview FlyVideo II (Bt848) LR26
+  card=9 - IMS/IXmicro TurboTV
   card=10 - Hauppauge (bt878)
   card=11 - MIRO PCTV pro
-  card=12 - ADS Technologies Channel Surfer TV
+  card=12 - ADS Technologies Channel Surfer TV (bt848)
   card=13 - AVerMedia TVCapture 98
   card=14 - Aimslab Video Highway Xtreme (VHX)
   card=15 - Zoltrix TV-Max
-  card=16 - Pixelview PlayTV (bt878)
+  card=16 - Prolink Pixelview PlayTV (bt878)
   card=17 - Leadtek WinView 601
   card=18 - AVEC Intercapture
-  card=19 - LifeView FlyKit w/o Tuner
+  card=19 - Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)
   card=20 - CEI Raffles Card
-  card=21 - Lucky Star Image World ConferenceTV
-  card=22 - Phoebe Tv Master + FM (CPH050)
+  card=21 - Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50
+  card=22 - Askey CPH050/ Phoebe Tv Master + FM
   card=23 - Modular Technology MM205 PCTV, bt878
-  card=24 - [many vendors] CPH05X/06X (bt878)
-  card=25 - Terratec/Vobis TV-Boostar
-  card=26 - Newer Hauppauge WinCam (bt878)
-  card=27 - MAXI TV Video PCI2
+  card=24 - Askey CPH05X/06X (bt878) [many vendors]
+  card=25 - Terratec Terra TV+ Version 1.0 (Bt848)/Vobis TV-Boostar
+  card=26 - Hauppauge WinCam newer (bt878)
+  card=27 - Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50
   card=28 - Terratec TerraTV+
   card=29 - Imagenation PXC200
-  card=30 - FlyVideo 98
-  card=31 - iProTV
-  card=32 - Intel Create and Share PCI
+  card=30 - Lifeview FlyVideo 98 LR50
+  card=31 - Formac iProTV
+  card=32 - Intel Create and Share PCI/ Smart Video Recorder III
   card=33 - Terratec TerraTValue
   card=34 - Leadtek WinFast 2000
-  card=35 - Flyvideo 98 (LR50Q) / Chronos Video Shuttle II
-  card=36 - Flyvideo 98FM (LR50Q) / Typhoon TView TV/FM Tuner
-  card=37 - PixelView PlayTV pro
-  card=38 - TView99 CPH06X
+  card=35 - Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II
+  card=36 - Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner
+  card=37 - Prolink PixelView PlayTV pro
+  card=38 - Askey CPH06X TView99
   card=39 - Pinnacle PCTV Studio/Rave
   card=40 - STB2
   card=41 - AVerMedia TVPhone 98
@@ -47,45 +47,47 @@
   card=45 - MATRIX-Vision MV-Delta 2
   card=46 - Zoltrix Genie TV/FM
   card=47 - Terratec TV/Radio+
-  card=48 - Dynalink Magic TView 
-  card=49 - GV-BCTV3
+  card=48 - Askey CPH03x/ Dynalink Magic TView
+  card=49 - IODATA GV-BCTV3/PCI
   card=50 - Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP
   card=51 - Eagle Wireless Capricorn2 (bt878A)
   card=52 - Pinnacle PCTV Studio Pro
   card=53 - Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS
-  card=54 - Lifetec LT 9415 TV (LR90 Rev.F)
-  card=55 - BESTBUY Easy TV (CPH031)
-  card=56 - FlyVideo '98/FM
+  card=54 - Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]
+  card=55 - Askey CPH031/ BESTBUY Easy TV
+  card=56 - Lifeview FlyVideo 98FM LR50
   card=57 - GrandTec 'Grand Video Capture' (Bt848)
-  card=58 - Phoebe TV Master Only (No FM) CPH060
-  card=59 - TV Capturer (CPH03X)
+  card=58 - Askey CPH060/ Phoebe TV Master Only (No FM)
+  card=59 - Askey CPH03x TV Capturer
   card=60 - Modular Technology MM100PCTV
   card=61 - AG Electronics GMV1
-  card=62 - BESTBUY Easy TV (bt878)
+  card=62 - Askey CPH061/ BESTBUY Easy TV (bt878)
   card=63 - ATI TV-Wonder
   card=64 - ATI TV-Wonder VE
-  card=65 - FlyVideo 2000S
+  card=65 - Lifeview FlyVideo 2000S LR90
   card=66 - Terratec TValueRadio
-  card=67 - GV-BCTV4/PCI
+  card=67 - IODATA GV-BCTV4/PCI
   card=68 - 3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)
   card=69 - Active Imaging AIMMS
-  card=70 - PV-BT878P+
-  card=71 - Flyvideo 98EZ (capture only)
-  card=72 - Prolink PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)
+  card=70 - Prolink Pixelview PV-BT878P+ (Rev.4C)
+  card=71 - Lifeview FlyVideo 98EZ (capture only) LR51
+  card=72 - Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)
   card=73 - Sensoray 311
   card=74 - RemoteVision MX (RV605)
   card=75 - Powercolor MTV878/ MTV878R/ MTV878F
   card=76 - Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)
   card=77 - GrandTec Multi Capture Card (Bt878)
-  card=78 - AOPEN VA1000
+  card=78 - Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF
+  card=79 - DSP Design TCVIDEO
+  card=80 - Hauppauge WinTV PVR
 
 tuner.o
   type=0 - Temic PAL (4002 FH5)
-  type=1 - Philips PAL_I
-  type=2 - Philips NTSC
-  type=3 - Philips SECAM
+  type=1 - Philips PAL_I (FI1246 and compatibles)
+  type=2 - Philips NTSC (FI1236 and compatibles)
+  type=3 - Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)
   type=4 - NoTuner
-  type=5 - Philips PAL
+  type=5 - Philips PAL_BG (FI1216 and compatibles)
   type=6 - Temic NTSC (4032 FY5)
   type=7 - Temic PAL_I (4062 FY5)
   type=8 - Temic NTSC (4036 FY5)
@@ -103,7 +105,7 @@
   type=20 - Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)
   type=21 - Temic NTSC (4039 FR5)
   type=22 - Temic PAL/SECAM multi (4046 FM5)
-  type=23 - Philips PAL_DK
+  type=23 - Philips PAL_DK (FI1256 and compatibles)
   type=24 - Philips PAL/SECAM multi (FQ1216ME)
   type=25 - LG PAL_I+FM (TAPC-I001D)
   type=26 - LG PAL_I (TAPC-I701D)
@@ -118,3 +120,5 @@
   type=35 - Temic PAL_DK/SECAM_L (4012 FY5)
   type=36 - Temic NTSC (4136 FY5)
   type=37 - LG PAL (newer TAPC series)
+  type=38 - Philips PAL/SECAM multi (FM1216ME MK3)
+  type=39 - LG NTSC (newer TAPC series)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/video4linux/bttv/Cards linux-bk/Documentation/video4linux/bttv/Cards
--- linux-2.4.19/Documentation/video4linux/bttv/Cards	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/video4linux/bttv/Cards	2002-08-17 00:48:54.000000000 +0000
@@ -1,3 +1,8 @@
+
+Gunther Mayer's bttv card gallery (graphical version of this text file :-)
+is available at: http://mayerg.gmxhome.de/bttv/bttv-gallery.html
+
+
 Suppported cards:
 
 
@@ -91,10 +96,9 @@
 - sound decoder: TDA9800, MSP34xx (stereo cards) 
 
 
-CPH-Series (CPH050, ...)
-------------------------
-Developed by TelSignal(?), OEMed by many vendors (Askey, Typhoon, 
-  Anubis, Dynalink)
+Askey CPH-Series
+----------------
+Developed by TelSignal(?), OEMed by many vendors (Typhoon, Anubis, Dynalink)
 
   Card series:
     CPH01x: BT848 capture only
@@ -149,9 +153,13 @@
       LR50 Rev.Q = Flyvideo 98 (w/eeprom and PCI subsystem ID)
            Rev.W = Flyvideo 98 (no eeprom)
       LR51 Rev.E = Flyvideo 98 EZ (capture only)
-      LR90       = Flyvideo 2000 series
+      LR90       = Flyvideo 2000 (Bt878)
+		   Flyvideo 2000S (Bt878) w/Stereo TV (Package incl. LR91 daughterboard)
       LR91       = Stereo daughter card for LR90
       LR97       = Flyvideo DVBS
+      LR99 Rev.E = Low profile card for OEM integration (only internal audio!) bt878
+      LR136	 = Flyvideo 2100/3100 (Low profile, SAA7130/SAA7134)
+      LR137      = Flyvideo DV2000/DV3000 (SAA7130/SAA7134 + IEEE1394)
       LR138 Rev.C= Flyvideo 2000 (SAA7130)
 	        or Flyvideo 3000 (SAA7134) w/Stereo TV
 		   These exist in variations w/FM and w/Remote sometimes denoted
@@ -162,15 +170,14 @@
       Their Bt8x8 cards are listed as discontinued.
       Flyvideo 2000S was probably sold as Flyvideo 3000 in some contries(Europe?).
       The new Flyvideo 2000/3000 are SAA7130/SAA7134 based. 
-      Flyvideo 2100/3100 are half-sized cards (for system integrators etc.)
 
   "Flyvideo II" had been the name for the 848 cards, nowadays (in Germany)
   this name is re-used for LR50 Rev.W.
   The Lifeview website mentioned Flyvideo III at some time, but such a card
-  has never been seen. 
+  has not yet been seen (perhaps it was the german name for LR90 [stereo]).
   These cards are sold by many OEMs too.
 
-  FlyVideo A2 = LR90 Rev.F (w/Remote, w/o FM, stereo TV by tda9821)
+  FlyVideo A2 = LR90 Rev.F (w/Remote, w/o FM, stereo TV by tda9821) {Germany}
 
 
 Typhoon TV card series:
@@ -190,7 +197,12 @@
   50686 "TV Tuner"                       = KNC1 TV Station
   50687 "TV Tuner stereo"                = KNC1 TV Station pro
   50688 "TV Tuner RDS" (black package)   = KNC1 TV Station RDS
+  50689  TV SAT DVB-S CARD CI PCI (SAA7146AH)
   50692 "TV/FM Tuner" (small PCB)
+  50694  TV TUNER CARD RDS (PHILIPS CHIPSET SAA7134HL)
+  50696  TV TUNER STEREO (PHILIPS CHIPSET SAA7134HL, MK3ME Tuner)
+  50804  PC-SAT TV/Audio Karte = Techni-PC-Sat (ZORAN 36120PQC, Tuner:Alps)
+  50866  TVIEW SAT RECEIVER+ADR
   50868 "TV/FM Tuner Pal I" (variant of 50682)
   50999 "TV/FM Tuner Secam" (variant of 50682)
 
@@ -207,16 +219,31 @@
 
 Prolink
 -------
-   Pixelview Play TV Pro:
-     PV-BT878P+rev.9B (Play TV Pro w/FM w/NICAM)
-     PV-BT878P+rev.8X 
-     PV-BT878P+rev.4C (Play TV Pro) 
-     PV-BT878P+rev.4E (Play TV Pak) 
-     PV-BT878P+rev.2F 
-     PV-BT878TV 
-
-   PixelView Play TV 
-     PV-BT848P+
+   TV cards:
+   PixelView Play TV pro - (Model: PV-BT878P+ REV 8E)
+   PixelView Play TV pro - (Model: PV-BT878P+ REV 9D)
+   PixelView Play TV pro - (Model: PV-BT878P+ REV 4C / 8D / 10A )
+   PixelView Play TV - (Model: PV-BT848P+)
+   878TV - (Model: PV-BT878TV)
+
+   Multimedia TV packages (card + software pack):
+   PixelView Play TV Theater - (Model: PV-M4200) =  PixelView Play TV pro + Software
+   PixelView Play TV PAK -     (Model: PV-BT878P+ REV 4E)
+   PixelView Play TV/VCR -     (Model: PV-M3200 REV 4C / 8D / 10A ) 
+   PixelView Studio PAK -      (Model:    M2200 REV 4C / 8D / 10A )
+   PixelView PowerStudio PAK - (Model: PV-M3600 REV 4E)
+   PixelView DigitalVCR PAK -  (Model: PV-M2400 REV 4C / 8D / 10A )
+
+   Further Cards:
+   PV-BT878P+rev.9B (Play TV Pro, opt. w/FM w/NICAM)
+   PV-BT878P+rev.2F
+   PV-BT878P Rev.1D (bt878, capture only)
+   
+   Video Conferencing:
+   PixelView Meeting PAK - (Model: PV-BT878P)
+   PixelView Meeting PAK Lite - (Model: PV-BT878P)
+   PixelView Meeting PAK plus - (Model: PV-BT878P+rev 4C/8D/10A)
+   PixelView Capture - (Model: PV-BT848P)
 
 Dynalink
 --------
@@ -235,7 +262,7 @@
 Tekram
 ------
    VideoCap C205 (Bt848)
-   VideoCap C210 (Zoran ZR36120 +Philips)
+   VideoCap C210 (zr36120 +Philips)
    CaptureTV M200 (ISA)
    CaptureTV M205 (Bt848)
 
@@ -257,8 +284,10 @@
    TV-Station FM (+Radio)
    TV-Station RDS (+RDS)
 
-PV951 cards:
-------------
+   newer Cards have saa7134, but model name stayed the same?
+
+Provideo PV951 
+--------------
   These are sold as:
    Boeder TV-FM Video Capture Card
    Titanmedia Supervision TV-2400
@@ -270,12 +299,14 @@
 Highscreen
 ----------
    TV Karte = LR50 Rev.S
-   TV-Boostar = Terratec Terra TV+ Version 1.0 (Bt848, TDA9821) "ceb105.pcb"
+   TV-Boostar = Terratec Terra TV+ Version 1.0 (Bt848, tda9821) "ceb105.pcb"
 
 Zoltrix
 -------
+   Face to Face Capture (Bt848 capture only) (PCB "VP-2848")
    Face To Face TV MAX (Bt848) (PCB "VP-8482 Rev1.3")
    Genie TV (Bt878) (PCB "VP-8790 Rev 2.1")
+   Genie Wonder Pro
 
 AVerMedia
 ---------
@@ -302,21 +333,24 @@
 
 Aimslab
 -------
+   Video Highway or "Video Highway TR200" (ISA)
    Video Highway Xtreme (aka "VHX") (Bt848, FM w/ TEA5757)
 
-IXMicro
+IXMicro (former: IMS=Integrated Micro Solutions)
 -------
    IXTV BT848
    IXTV BT878
    TurboTV (Bt848)
 
 Lifetec/Medion/Tevion/Aldi
--------
-   LT9415/MD9415 = LR90 Rev. F
+--------------------------
+   LT9306/MD9306 = CPH061
+   LT9415/MD9415 = LR90 Rev.F or Rev.G
           MD9592 = Avermedia TVphone98 (PCI_ID=1461:0003), PCB-Rev=M168II-B (w/TDA9873H)
+          MD9717 = KNC One (Rev D4, saa7134)
 
 Modular Technologies (www.modulartech.com) UK
---------------------
+---------------------------------------------
    MM100 PCTV (Bt848)
    MM205 PCTV (Bt878)
    MM210 PCTV (Bt878) (Galaxy TV)
@@ -326,19 +360,28 @@
    Terra TV+ Version 1.0 (Bt848), "ceb105.PCB" printed on the PCB, TDA9821
    Terra TV+ Version 1.1 (Bt878), "LR74 Rev.E" printed on the PCB, TDA9821
    Terra TValueRadio,             "LR102 Rev.C" printed on the PCB
-   Terra TV/Radio+ Version 1.0,   "80-CP2830100-0" TTTV3 printed on the PCB, i
+   Terra TV/Radio+ Version 1.0,   "80-CP2830100-0" TTTV3 printed on the PCB,
 				     "CPH010-E83" on the back, SAA6588T, TDA9873H
    Terra TValue Version BT878,    "80-CP2830110-0 TTTV4" printed on the PCB, 
 				     "CPH011-D83" on back
    Terra TValue Version 1.0       "ceb105.PCB" (really identical to Terra TV+ Version 1.0)
+   Terra Active Radio Upgrade (tea5757h, saa6588t)
 
    LR74 is a newer PCB revision of ceb105 (both incl. connector for Active Radio Upgrade)
 
+   Cinergy 400 (saa7134), "E877 11(S)", "PM820092D" printed on PCB
 
 Technisat
 ---------
-   Mediafocus I (ZR36120/ZR36125)
-   Mediafocus II (SAA7146)
+   Discos ADR PC-Karte ISA (no TV!)
+   Discos ADR PC-Karte PCI (probably no TV?)
+   Techni-PC-Sat (Sat. analog)
+         Rev 1.2 (zr36120, vpx3220, stv0030, saa5246, BSJE3-494A)
+   Mediafocus I (zr36120/zr36125, drp3510, Sat. analog + ADR Radio)
+   Mediafocus II (saa7146, Sat. analog)
+         SatADR Rev 2.1 (saa7146a, saa7113h, stv0056a, msp3400c, drp3510a, BSKE3-307A)
+   SkyStar 1 DVB  (AV7110)
+   SkyStar 2 DVB  (B2C2) (=Sky2PC)
 
 Siemens
 -------
@@ -359,34 +402,262 @@
    Mirovideo PCTV (Bt848)
    Mirovideo PCTV SE (Bt848)
    Mirovideo PCTV Pro (Bt848 + Daughterboard)
-   Studio PCTV Rave (Bt878 w/o infrared)
-   Studio PCTV
-   Studio PCTV Pro (Bt878 stereo w/ FM)
+   Studio PCTV Rave (Bt878 package w/o infrared)
+   Studio PCTV      (Bt878)
+   Studio PCTV Pro  (Bt878 stereo w/ FM)
 
+   M(J)PEG capture and playback:
    DC1+ (ISA)
-   DC10  (zr36057 + zr36060 + saa7110 + adv7176)
-   DC10+ (zr36067 + zr36060 + saa7110 + adv7176)
-   DC20
-   DC30
-   DC30+ (zr36067 + zr36050 + zr36016 + vpx3220 + adv7176)
+   DC10  (zr36057,     zr36060,      saa7110, adv7176)
+   DC10+ (zr36067,     zr36060,      saa7110, adv7176)
+   DC20  (ql16x24b,zr36050, zr36016, saa7110, saa7187 ...)
+   DC30  (zr36057, zr36050, zr36016, vpx3220, adv7176, ad1843, tea6415, miro FST97A1)
+   DC30+ (zr36067, zr36050, zr36016, vpx3220, adv7176)
+   DC50  (zr36067, zr36050, zr36016, saa7112, adv7176 (2 pcs.?), ad1843, miro FST97A1, Lattice ???)
 
 Lenco
 -----
    MXR-9565 (=Technisat Mediafocus?)
-   MXR-9571 (Bt848)
+   MXR-9571 (Bt848) (=CPH031?)
    MXR-9575
-   MXR-9477 (Bt878)
-   MXTV-9578CP (= Prolink PV-BT878P+4E)
+   MXR-9577 (Bt878) (=Prolink 878TV Rev.3x)
+   MXTV-9578CP (Bt878) (= Prolink PV-BT878P+4E)
 
 Iomega
 ------
-   Buz (Zoran zr36067 + zr36060 + SAA7111 + SAA7185)
+   Buz (zr36067, zr36060, saa7111, saa7185)
 
 LML
 ---
-   LML33 (zr36067 + zr36060 + bt819+ bt856)
+   LML33 (zr36067, zr36060, bt819, bt856)
 
 Grandtec
 --------
    Grand Video Capture (Bt848)
    Multi Capture Card  (Bt878)
+
+Koutech
+-------
+   KW-606 (Bt848)
+   KW-607 (Bt848 capture only)
+   KW-606RSF
+   KW-607A (capture only)
+   KW-608 (Zoran capture only)
+ 
+IODATA (jp)
+------
+   GV-BCTV/PCI
+   GV-BCTV2/PCI
+   GV-BCTV3/PCI
+   GV-BCTV4/PCI
+   GV-VCP/PCI (capture only)
+   GV-VCP2/PCI (capture only)
+
+Canopus (jp)
+-------
+   WinDVR	= Kworld "KW-TVL878RF"
+
+www.sigmacom.co.kr 
+------------------
+   Sigma Cyber TV II 
+
+www.sasem.co.kr
+---------------
+   Litte OnAir TV
+
+hama 
+----
+   TV/Radio-Tuner Card, PCI (Model 44677) = CPH051
+
+Sigma Designs
+-------------
+   Hollywood plus (em8300, em9010, adv7175), (PCB "M340-10") MPEG DVD decoder
+
+Formac
+------
+   iProTV (Card for iMac Mezzanine slot, Bt848+SCSI)
+   ProTV (Bt848)
+   ProTV II = ProTV Stereo (Bt878)
+
+ATI
+---
+   TV-Wonder
+   TV-Wonder VE
+
+Diamond Multimedia
+------------------
+   DTV2000 (Bt848, tda9875)
+
+Aopen
+-----
+   VA1000 Plus (w/ Stereo)
+   VA1000 Lite
+   VA1000 (=LR90)
+
+Intel
+-----
+   Smart Video Recorder (ISA full-length)
+   Smart Video Recorder pro (ISA half-length)
+   Smart Video Recorder III (Bt848)
+
+STB
+---
+   TV PCI (Temic4032FY5, tda9850??)
+   other variants?
+
+Videologic
+----------
+   Captivator Pro/TV (ISA?)
+   Captivator PCI/VC (Bt848 bundled with camera) (capture only)
+
+Technotrend
+------------
+   TT-SAT PCI (PCB "Sat-PCI Rev.:1.3.1"; zr36125, vpx3225d, stc0056a, Tuner:BSKE6-155A
+   TT-DVB-Sat
+   TT-DVB-C PCI
+
+Teles
+-----
+   DVB-s (Rev. 2.2, BSRV2-301A, data only?)
+
+Remote Vision
+-------------
+   MX RV605 (Bt848 capture only)
+
+Boeder
+------
+   PC ChatCam (Model 68252) (Bt848 capture only)
+   Tv/Fm Capture Card  (Model 68404) = PV951
+
+Media-Surfer  (esc-kathrein.de)
+-------------------------------
+   Sat-Surfer (ISA)
+   Sat-Surfer PCI = Techni-PC-Sat
+   Cable-Surfer 1
+   Cable-Surfer 2
+   Cable-Surfer PCI (zr36120)
+   Audio-Surfer (ISA Radio card)
+
+Jetway (www.jetway.com.tw)
+--------------------------
+   JW-TV 878M 
+   JW-TV 878  = KWorld KW-TV878RF
+
+Galaxis
+-------
+   Galaxis DVB Card S CI
+   Galaxis DVB Card C CI
+   Galaxis DVB Card S
+   Galaxis DVB Card C
+
+Hauppauge
+---------
+   many many WinTV models ...
+   WinTV DVBs
+   WinTV NOVA
+   WinTV NOVA-CI
+   WinTV-Nexus-s
+
+Matrix-Vision
+-------------
+   MATRIX-Vision MV-Delta
+   MATRIX-Vision MV-Delta 2
+   MVsigma-SLC (Bt848)
+
+Conceptronic (.net)
+------------
+   TVCON FM,  TV card w/ FM = CPH05x
+
+BestData
+--------
+   HCC100 = VCC100rev1 + camera
+   VCC100 rev1 (bt848)
+   VCC100 rev2 (bt878)
+
+Gallant  (www.gallantcom.com) www.minton.com.tw
+-----------------------------------------------
+   Intervision IV-510 (capture only bt8x8)
+   Intervision IV-550 (bt8x8)
+   Intervision IV-100 (zoran)
+   Intervision IV-1000 (bt8x8)
+   
+Asonic (www.asonic.com.cn) (website down)
+-----------------------------------------
+   SkyEye tv 878
+
+Hoontech
+--------
+   878TV/FM
+
+Teppro (www.itcteppro.com.tw)
+-----------------------------
+   ITC PCITV (Card Ver 1.0) "Teppro TV1/TVFM1 Card"
+   ITC PCITV (Card Ver 2.0)
+   ITC PCITV (Card Ver 3.0) = "PV-BT878P+ (REV.9D)"
+   ITC PCITV (Card Ver 4.0)
+   TEPPRO IV-550 (For BT848 Main Chip)
+   ITC DSTTV (bt878, satellite)
+   ITC VideoMaker (saa7146, StreamMachine sm2110, tvtuner) "PV-SM2210P+ (REV:1C)"
+
+Kworld (www.kworld.com.tw)
+--------------------------
+   KWORLD KW-TV878RF-Pro TV Capture with FM Radio
+   KWORLD KW-TV878R-Pro TV
+   KWORLD KW-TVL878RF  (low profile)
+   KWORLD KW-TV878R TV Capture (No FM Radio)
+   KWORLD KW-TV878RF TV
+
+JTT/ Justy Corp.http://www.justy.co.jp/ (www.jtt.com.jp website down)
+---------------------------------------------------------------------
+   JTT-02 (JTT TV) "TV watchmate pro" (bt848) 
+
+ADS www.adstech.com
+-------------------
+   Channel Surfer TV ( CHX-950 ) 
+   Channel Surfer TV+FM ( CHX-960FM )
+
+AVEC www.prochips.com
+---------------------
+   AVEC Intercapture (bt848, tea6320)
+
+NoBrand
+-------
+   TV Excel = Australian Name for "PV-BT878P+ 8E" or so
+
+Mach www.machspeed.com
+----
+   Mach TV 878
+
+Eline www.eline-net.com/
+-----
+   Eline Vision TVMaster / TVMaster FM (ELV-TVM/ ELV-TVM-FM) = LR26  (bt878)
+   Eline Vision TVMaster-2000 (ELV-TVM-2000, ELV-TVM-2000-FM)= LR138 (saa713x)
+
+Spirit http://www.spiritmodems.com.au/
+------
+   Spirit TV Tuner/Video Capture Card (bt848)
+
+Boser www.boser.com.tw
+-----
+   HS-878 Mini PCI Capture Add-on Card
+   HS-879 Mini PCI 3D Audio and Capture Add-on Card (w/ ES1938 Solo-1)
+
+Satelco
+-------
+   TV-FM =KNC1 saa7134
+
+Sensoray www.sensoray.com
+--------
+   Sensoray 311 (PC/104 bus)
+   Sensoray 611 (PCI)
+
+CEI (Chartered Electronics Industries Pte Ltd [CEI] [FCC ID HBY])
+---
+  TV Tuner  -  HBY-33A-RAFFLES  Brooktree Bt848KPF + Philips
+  TV Tuner MG9910  -  HBY33A-TVO  CEI + Philips SAA7110 + OKI M548262 + ST STV8438CV
+  Primetime TV (ISA)
+   acquired by Singapore Technologies
+   now operating as Chartered Semiconductor Manufacturing
+   Manufacturer of video cards is listed as:
+   Cogent Electronics Industries [CEI]
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/video4linux/bttv/Insmod-options linux-bk/Documentation/video4linux/bttv/Insmod-options
--- linux-2.4.19/Documentation/video4linux/bttv/Insmod-options	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/video4linux/bttv/Insmod-options	2002-08-17 00:48:52.000000000 +0000
@@ -29,7 +29,7 @@
 		irq_debug=0/1	irq handler debug messages.
 				default is 0 (off).
 		gbuffers=2-32	number of capture buffers for mmap'ed capture.
-				default is 2.
+				default is 4.
 		gbufsize=	size of capture buffers. default and
 				maximum value is 0x208000 (~2MB)
 		no_overlay=0	Enable overlay on broken hardware.  There
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/video4linux/bttv/README linux-bk/Documentation/video4linux/bttv/README
--- linux-2.4.19/Documentation/video4linux/bttv/README	2001-08-05 20:15:05.000000000 +0000
+++ linux-bk/Documentation/video4linux/bttv/README	2002-08-17 00:48:49.000000000 +0000
@@ -58,6 +58,9 @@
 		the helper modules.
 MAKEDEV:	a script to create the special files for v4l
 CARDLIST:	List of all supported cards
+Cards:		more detailed descriptions of known TV cards:
+		OEM name variants, used i2c chips, ...
+		also includes non-bttv cards.
 
 Loading just the bttv modules isn't enouth for most cards.  The
 drivers for the i2c tuner/sound chips must also be loaded.  bttv tries
@@ -73,6 +76,12 @@
 video but no sound you've very likely specified the wrong (or no)
 card type.  A list of supported cards is in CARDLIST.
 
+For the WinTV/PVR you need one firmware file from the driver CD:
+hcwamc.rbf.  The file is in the pvr45xxx.exe archive (self-extracting
+zip file, unzip can unpack it).  Put it into the /etc/pvr directory or
+use the firm_altera=<path> insmod option to point the driver to the
+location of the file.
+
 If your card isn't listed in CARDLIST or if you have trouble making
 audio work, you should read the Sound-FAQ.
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/video4linux/bttv/README.freeze linux-bk/Documentation/video4linux/bttv/README.freeze
--- linux-2.4.19/Documentation/video4linux/bttv/README.freeze	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/video4linux/bttv/README.freeze	2002-08-17 00:48:57.000000000 +0000
@@ -46,6 +46,11 @@
 the PCI bus. The bt848/878 chips have a few workarounds for known
 incompatibilities, see README.quirks.
 
+Some folks report that increasing the pci latency helps too,
+althrought I'm not sure whenever this really fixes the problems or
+only makes it less likely to happen.  Both bttv and btaudio have a
+insmod option to set the PCI latency of the device.
+
 Some mainboard have problems to deal correctly with multiple devices
 doing DMA at the same time.  bttv + ide seems to cause this sometimes,
 if this is the case you likely see freezes only with video and hard disk
@@ -56,6 +61,9 @@
 other
 -----
 
+If you use some binary-only yunk (like nvidia module) try to reproduce
+the problem without.
+
 IRQ sharing is known to cause problems in some cases.  It works just
 fine in theory and many configurations.  Neverless it might be worth a
 try to shuffle around the PCI cards to give bttv another IRQ or make
@@ -63,3 +71,4 @@
 VGA cards seems to cause trouble sometimes.  I've also seen funny
 effects with bttv sharing the IRQ with the ACPI bridge (and
 apci-enabled kernel).
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/video4linux/bttv/Tuners linux-bk/Documentation/video4linux/bttv/Tuners
--- linux-2.4.19/Documentation/video4linux/bttv/Tuners	2001-10-17 21:19:20.000000000 +0000
+++ linux-bk/Documentation/video4linux/bttv/Tuners	2002-08-17 00:48:46.000000000 +0000
@@ -1,3 +1,16 @@
+1) Tuner Programming
+====================
+There are some flavors of Tuner programming APIs.
+These differ mainly by the bandswitch byte.
+
+    L= LG_API       (VHF_LO=0x01, VHF_HI=0x02, UHF=0x08, radio=0x04)
+    P= PHILIPS_API  (VHF_LO=0xA0, VHF_HI=0x90, UHF=0x30, radio=0x04)
+    T= TEMIC_API    (VHF_LO=0x02, VHF_HI=0x04, UHF=0x01)
+    A= ALPS_API     (VHF_LO=0x14, VHF_HI=0x12, UHF=0x11)
+    M= PHILIPS_MK3  (VHF_LO=0x01, VHF_HI=0x02, UHF=0x04, radio=0x19)
+
+2) Tuner Manufacturers
+======================
 
 SAMSUNG Tuner identification: (e.g. TCPM9091PD27)
   TCP [ABCJLMNQ] 90[89][125] [DP] [ACD] 27 [ABCD]
@@ -10,6 +23,7 @@
    M= BG+I+DK
    N= NTSC 
    Q= BG+I+DK+LL
+ [89]: ?
  [125]:
    2: No FM
    5: With FM
@@ -23,43 +37,49 @@
  [ABCD]:
    3-wire/I2C tuning, 2-band/3-band
 
+ These Tuners are PHILIPS_API compatible.
+
 Philips Tuner identification: (e.g. FM1216MF)
-  F[IRMQ]12[1345]{MF|ME|MP}
-  [IRMQ]:
-   I: Tuner Series
-   R: Tuner + Radio IF
-   M: Tuner + FM
-   Q,MR: specials
+  F[IRMQ]12[1345]6{MF|ME|MP}
+  F[IRMQ]:
+   FI12x6: Tuner Series
+   FR12x6: Tuner + Radio IF
+   FM12x6: Tuner + FM
+   FQ12x6: special
+   FMR12x6: special
    TD15xx: Digital Tuner ATSC
-  [1345]
-   1: PAL BG
-   3: NTSC
-   4: PAL I
-   5: Pal DK
+  12[1345]6:
+   1216: PAL BG
+   1236: NTSC
+   1246: PAL I
+   1256: Pal DK
   {MF|ME|MP}
-   MF: w/ Secam
-   ME: BD DK I LL
-   MP: BG DK I
+   MF: BG LL w/ Secam (Multi France)
+   ME: BG DK I LL   (Multi Europe)
+   MP: BG DK I      (Multi PAL)
    MR: BG DK M (?)
    MG: BG DKI M (?)
+  MK2 series PHILIPS_API, most tuners are compatible to this one !
+  MK3 series introduced in 2002 w/ PHILIPS_MK3_API
 
 Temic Tuner identification: (.e.g 4006FH5)
    4[01][0136][269]F[HYNR]5
-    40x2: Tuner (5V/33V), different I2C programming from Philips !
+    40x2: Tuner (5V/33V), TEMIC_API.
     40x6: Tuner 5V
     41xx: Tuner compact
     40x9: Tuner+FM compact
    [0136]
-    0: PAL BG
-    1: Pal DK, Secam LL
-    3: NTSC
-    6: PAL I
+    xx0x: PAL BG
+    xx1x: Pal DK, Secam LL
+    xx3x: NTSC
+    xx6x: PAL I
    F[HYNR]5
     FH5: Pal BG
     FY5: others
     FN5: multistandard
     FR5: w/ FM radio
    3X xxxx: order number with specific connector
+  Note: Only 40x2 series has TEMIC_API, all newer tuners have PHILIPS_API.
 
 LG Innotek Tuner:
   TPI8NSR11 : NTSC J/M    (TPI8NSR01 w/FM)  (P,210/497)
@@ -76,13 +96,20 @@
   TADC-H002F: NTSC (L,175/410?; 2-B, C-W+11, W+12-69)
   TADC-M201D: PAL D/K+B/G+I (L,143/425)  (sound control at I2C address 0xc8)
   TADC-T003F: NTSC Taiwan  (L,175/410?; 2-B, C-W+11, W+12-69)
-
-  (API,Lo-Hi-takeover/Hi-UHF-takeover)
-   I2C APIs:
-    L= LG programming (VHF_LO=0x01, VHF_HI=0x02, UHF=0x08, radio=0x04)
-    P= Philips progr. (VHF_LO=0xA0, VHF_HI=0x90, UHF=0x30, radio=0x04)
-    T= Temic progr.   (VHF_LO=0x02, VHF_HI=0x04, UHF=0x01)
   Suffix: 
     P= Standard phono female socket
     D= IEC female socket
     F= F-connector
+
+Other Tuners:
+TCL2002MB-1 : PAL BG + DK       =TUNER_LG_PAL_NEW_TAPC
+TCL2002MB-1F: PAL BG + DK w/FM  =PHILIPS_PAL
+TCL2002MI-2 : PAL I		= ??
+
+ALPS Tuners:
+   Most are LG_API compatible
+   TSCH6 has ALPS_API (TSCH5 ?)
+   TSBE1 has extra API 05,02,08 Control_byte=0xCB Source:(1)
+
+Lit.
+(1) conexant100029b-PCI-Decoder-ApplicationNote.pdf
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/video4linux/meye.txt linux-bk/Documentation/video4linux/meye.txt
--- linux-2.4.19/Documentation/video4linux/meye.txt	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/video4linux/meye.txt	2002-08-17 00:48:55.000000000 +0000
@@ -86,7 +86,7 @@
 
 	MEYEIOC_SYNC
 		Takes as an argument the buffer number you want to sync.
-		This ioctl blocks untils the buffer is filled and ready
+		This ioctl blocks until the buffer is filled and ready
 		for the application to use. It returns the buffer size.
 
 	MEYEIOC_STILLCAPT
@@ -106,7 +106,7 @@
 		
 	- mjpeg hardware playback doesn't work (depends on overlay...)
 
-	- rewrite the driver to use some commun video4linux API for snapshot
+	- rewrite the driver to use some common video4linux API for snapshot
 	  and mjpeg capture. Unfortunately, video4linux1 does not permit it,
 	  the BUZ API seems to be targeted to TV cards only. The video4linux 2
 	  API may be an option, if it goes into the kernel (maybe 2.5 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/x86_64/BUGS linux-bk/Documentation/x86_64/BUGS
--- linux-2.4.19/Documentation/x86_64/BUGS	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/x86_64/BUGS	2002-08-17 00:48:53.000000000 +0000
@@ -0,0 +1,10 @@
+Some known problems:
+
+-- Compiling the kernel with -j for parallel makes is not completely safe
+due to missing dependencies with offset.h. Usually it is safe when it 
+already exists, but not always.
+
+Current hack is to rerun make depend manually when you change anything
+that would touch offset.h (see arch/x86-64/tools/offset.c on what that is).
+Do not use -j with depend. 
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/x86_64/mm.txt linux-bk/Documentation/x86_64/mm.txt
--- linux-2.4.19/Documentation/x86_64/mm.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/x86_64/mm.txt	2002-08-17 00:48:58.000000000 +0000
@@ -0,0 +1,194 @@
+The paging design used on the x86-64 linux kernel port in 2.4.x provides:
+
+o	per process virtual address space limit of 512 Gigabytes
+o	top of userspace stack located at address 0x0000007fffffffff
+o	PAGE_OFFSET = 0xffff800000000000
+o	start of the kernel mapping =  0x0000010000000000
+o	global RAM per system 508*512GB=254 Terabytes
+o	no need of any common code change
+o       512GB of vmalloc/ioremap space
+
+Description:
+        x86-64 has a 4 level page structure, similar to ia32 PSE but with
+        some extensions. Each level consits of a 4K page with 512 64bit
+        entries. The levels are named in Linux PML4, PGD, PMD, PTE; AMD calls them
+        PML4E, PDPE, PDE, PTE respectively. For direct and kernel mapping
+        only 3 levels are used with the PMD pointing to 2MB pages.
+          
+	Userspace is able to modify and it sees only the 3rd/2nd/1st level
+	pagetables (pgd_offset() implicitly walks the 1st slot of the 4th
+	level pagetable and it returns an entry into the 3rd level pagetable).
+	This is where the per-process 512 Gigabytes limit cames from.
+
+	The common code pgd is the PDPE, the pmd is the PDE, the
+	pte is the PTE. The PML4 remains invisible to the common
+	code.
+
+	Since the per-process limit is 512 Gigabytes (due to kernel common
+	code 3 level pagetable limitation), the higher virtual address mapped
+	into userspace is 0x7fffffffff and it makes sense to use it
+	as the top of the userspace stack to allow the stack to grow as
+	much as possible.
+
+	The kernel mapping and the direct memory mapping are split. Direct memory
+	mapping starts directly after userspace after a 512GB gap, while 
+	kernel mapping is at the end of (negative) virtual address space to exploit 
+	the kernel code model. There is no support for discontig memory, this
+	implies that kernel mapping/vmalloc/ioremap/module mapping are not 
+	represented in their "real" mapping in mem_map, but only with their
+	direct mapped (but normally not used) alias.
+	
+Future:
+
+	During 2.5.x we can break the 512 Gigabytes per-process limit
+	possibly by removing from the common code any knowledge about the
+	architectural dependent physical layout of the virtual to physical
+	mapping.
+
+	Once the 512 Gigabytes limit will be removed the kernel stack will
+	be moved (most probably to virtual address 0x00007fffffffffff).
+	Nothing	will break in userspace due that move, as nothing breaks
+	in IA32 compiling the kernel with CONFIG_2G.
+
+Linus agreed on not breaking common code and to live with the 512 Gigabytes
+per-process limitation for the 2.4.x timeframe and he has given me and Andi
+some very useful hints... (thanks! :)
+
+Thanks also to H. Peter Anvin for his interesting and useful suggestions on
+the x86-64-discuss lists!
+
+Current PML4 Layout:
+	Each CPU has an PML4 page that never changes. 
+	Each slot is 512GB of virtual memory. 
+ 
+        0    user space pgd or 40MB low mapping at bootup.  Changed at context switch.
+        1    unmapped
+        2    __PAGE_OFFSET - start of direct mapping of physical memory
+        ...  direct mapping in further slots as needed.
+        510  vmalloc and ioremap space
+	511  kernel code mapping, fixmaps and modules.  
+
+Other memory management related issues follows:
+
+PAGE_SIZE:
+
+	If somebody is wondering why these days we still have a so small
+	4k pagesize (16 or 32 kbytes would be much better for performance
+	of course), the PAGE_SIZE have to remain 4k for 32bit apps to
+	provide 100% backwards compatible IA32 API (we can't allow silent
+	fs corruption or as best a loss of coherency with the page cache
+	by allocating MAP_SHARED areas in MAP_ANONYMOUS memory with a
+	do_mmap_fake). I think it could be possible to have a dynamic page
+	size between 32bit and 64bit apps but it would need extremely
+	intrusive changes in the common code as first for page cache and
+	we sure don't want to depend on them right now even if the
+	hardware would support that.
+
+PAGETABLE SIZE:
+
+	In turn we can't afford to have pagetables larger than 4k because
+	we could not be able to allocate them due physical memory
+	fragmentation, and failing to allocate the kernel stack is a minor
+	issue compared to failing the allocation of a pagetable. If we
+	fail the allocation of a pagetable the only thing we can do is to
+	sched_yield polling the freelist (deadlock prone) or to segfault
+	the task (not even the sighandler would be sure to run).
+
+KERNEL STACK:
+
+	1st stage:
+
+	The kernel stack will be at first allocated with an order 2 allocation
+	(16k) (the utilization of the stack for a 64bit platform really
+	isn't exactly the double of a 32bit platform because the local
+	variables may not be all 64bit wide, but not much less). This will
+	make things even worse than they are right now on IA32 with
+	respect of failing fork/clone due memory fragmentation.
+
+	2nd stage:
+
+	We'll benchmark if reserving one register as task_struct
+	pointer will improve performance of the kernel (instead of
+	recalculating the task_struct pointer starting from the stack
+	pointer each time). My guess is that recalculating will be faster
+	but it worth a try.
+
+		If reserving one register for the task_struct pointer
+		will be faster we can as well split task_struct and kernel
+		stack. task_struct can be a slab allocation or a
+		PAGE_SIZEd allocation, and the kernel stack can then be
+		allocated in a order 1 allocation. Really this is risky,
+		since 8k on a 64bit platform is going to be less than 7k
+		on a 32bit platform but we could try it out. This would
+		reduce the fragmentation problem of an order of magnitude
+		making it equal to the current IA32.
+
+		We must also consider the x86-64 seems to provide in hardware a
+		per-irq stack that could allow us to remove the irq handler
+		footprint from the regular per-process-stack, so it could allow
+		us to live with a smaller kernel stack compared to the other
+		linux architectures.
+
+	3rd stage:
+
+	Before going into production if we still have the order 2
+	allocation we can add a sysctl that allows the kernel stack to be
+	allocated with vmalloc during memory fragmentation. This have to
+	remain turned off during benchmarks :) but it should be ok in real
+	life.
+
+Order of PAGE_CACHE_SIZE and other allocations:
+
+	On the long run we can increase the PAGE_CACHE_SIZE to be
+	an order 2 allocations and also the slab/buffercache etc.ec..
+	could be all done with order 2 allocations. To make the above
+	to work we should change lots of common code thus it can be done
+	only once the basic port will be in a production state. Having
+	a working PAGE_CACHE_SIZE would be a benefit also for
+	IA32 and other architectures of course.
+
+vmalloc:
+	vmalloc should be outside the first 512GB to keep that space free
+	for the user space. It needs an own pgd to work on in common code. 
+	It currently gets an own pgd in the 510th slot of the per CPU PML4.
+	
+PML4: 
+        Each CPU as an own PML4 (=top level of the 4 level page hierarchy). On 
+        context switch the first slot is rewritten to the pgd of the new process 
+        and CR3 is flushed.
+    
+Modules: 
+	Modules need to be in the same 4GB range as the core kernel. Otherwise
+	a GOT would be needed. Modules are currently at 0xffffffffa0000000
+        to 0xffffffffafffffff. This is inbetween the kernel text and the 
+        vsyscall/fixmap mappings.
+
+Vsyscalls: 
+        Vsyscalls have a reserved space near the end of user space that is 
+        acessible by user space. This address is part of the ABI and cannot be
+        changed. They have ffffffffff600000 to ffffffffffe00000 (but only 
+        some small space at the beginning is allocated and known to user space 
+        currently). See vsyscall.c for more details. 
+
+Fixmaps: 
+        Fixed mappings set up at boot. Used to access IO APIC and some other hardware. 
+        These are at the end of vsyscall space (ffffffffffe00000) downwards, 
+        but are not accessible by user space of course.
+
+Early mapping:
+        On a 120TB memory system bootmem could use upto 3.5GB
+        of memory for its bootmem bitmap. To avoid having to map 3.5GB by hand
+        for bootmem's purposes the full direct mapping is created before bootmem
+        is initialized. The direct mapping needs some memory for its page tables,
+        these are directly taken from the physical memory after the kernel. To
+        access these pages they need to be mapped, this is done by a temporary 
+        mapping with a few spare static 2MB PMD entries.
+
+Unsolved issues: 
+	 2MB pages for user space - may need to add a highmem zone for that again to 
+	 avoid fragmentation.
+  
+Andrea <andrea@suse.de> SuSE
+Andi Kleen <ak@suse.de> SuSE
+
+$Id$
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/MAINTAINERS linux-bk/MAINTAINERS
--- linux-2.4.19/MAINTAINERS	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/MAINTAINERS	2002-08-17 00:48:49.000000000 +0000
@@ -1,3 +1,4 @@
+	
 	List of maintainers and how to submit kernel changes
 
 Please try to follow the guidelines below.  This will make things
@@ -241,6 +242,12 @@
 W:	http://www.ife.ee.ethz.ch/~sailer/ham/ham.html
 S:	Maintained
 
+BEFS FILE SYSTEM
+P:	Will Dyson
+M:	will@cs.earlham.edu
+W:	http://cs.earlham.edu/~will/software/linux/kernel/BeFS.html
+S:	Maintained
+
 BERKSHIRE PRODUCTS PC WATCHDOG DRIVER
 P:	Kenji Hollis
 M:	kenji@bitgate.com
@@ -266,6 +273,12 @@
 W:	http://bluez.sf.net
 S:	Maintained
 
+BLUETOOTH SUBSYSTEM (PC Card Drivers)
+P:	Marcel Holtmann
+M:	marcel@holtmann.org
+W:	http://www.holtmann.org/linux/bluetooth/
+S:	Maintained
+
 BTTV VIDEO4LINUX DRIVER
 P:	Gerd Knorr
 M:	kraxel@bytesex.org
@@ -626,8 +639,8 @@
 S:	Maintained
 
 HFS FILESYSTEM
-P:      Adrian Sun
-M:      asun@cobaltnet.com
+P:      Oliver Neukum
+M:      oliver@neukum.org
 L:      linux-kernel@vger.kernel.org
 S:      Maintained
 
@@ -704,8 +717,10 @@
 S:	Maintained
 
 IBM ServeRAID RAID DRIVER
-P:      Keith Mitchell
-M:      ipslinux@us.ibm.com
+P:      Jack Hammer
+M:      ipslinux@adaptec.com
+P:      David Jeffery
+M:      ipslinux@adaptec.com
 W:      http://www.developer.ibm.com/welcome/netfinity/serveraid.html
 S:      Supported 
 
@@ -1095,14 +1110,11 @@
 P:	Networking Team
 M:	netdev@oss.sgi.com
 L:	linux-net@vger.kernel.org
-W:	http://www.uk.linux.org/NetNews.html (2.0 only)
 S:	Maintained
 
 NETWORKING [IPv4/IPv6]
 P:	David S. Miller
 M:	davem@redhat.com
-P:	Andi Kleen
-M:	ak@muc.de
 P:	Alexey Kuznetsov
 M:	kuznet@ms2.inr.ac.ru
 P:	Pekka Savola (ipv6)
@@ -1353,10 +1365,10 @@
 S:	Maintained
 
 RME96XX MULTICHANNEL SOUND DRIVER
-P:      Guenter Geiger
-M:      geiger@epy.co.at  
-L:      linux-kernel@vger.kernel.org
-S:      Maintained
+P:	Guenter Geiger
+M:	geiger@epy.co.at  
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
 
 RTLINUX  REALTIME  LINUX
 P:	Victor Yodaiken
@@ -1541,6 +1553,13 @@
 M:	hch@infradead.org
 S:	Maintained
 
+TI GRAPH LINK USB (SilverLink) CABLE DRIVER
+P:      Romain Lievin
+M:      roms@lpg.ticalc.org
+P:      Julien Blache
+M:      jb@technologeek.org
+S:      Maintained
+
 TIEMAN VOYAGER USB BRAILLE DISPLAY DRIVER
 P:	Stephane Dalton
 M:	sdalton@videotron.ca
@@ -1856,6 +1875,13 @@
 M:	mingo@redhat.com
 S:	Maintained
 
+X86-64 port
+P:	Andi Kleen
+M:	ak@suse.de
+L:	discuss@x86-64.org
+W:	http://www.x86-64.org
+S:	Maintained
+
 YAM DRIVER FOR AX.25
 P:	Jean-Paul Roubelat
 M:	jpr@f6fbb.org
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Makefile linux-bk/Makefile
--- linux-2.4.19/Makefile	2002-08-03 00:39:46.000000000 +0000
+++ linux-bk/Makefile	2002-08-17 00:48:51.000000000 +0000
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
-SUBLEVEL = 19
-EXTRAVERSION =
+SUBLEVEL = 20
+EXTRAVERSION = -pre3
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
@@ -170,7 +170,7 @@
 DRIVERS-$(CONFIG_SBUS) += drivers/sbus/sbus_all.o
 DRIVERS-$(CONFIG_ZORRO) += drivers/zorro/driver.o
 DRIVERS-$(CONFIG_FC4) += drivers/fc4/fc4.a
-DRIVERS-$(CONFIG_PPC) += drivers/macintosh/macintosh.o
+DRIVERS-$(CONFIG_PPC32) += drivers/macintosh/macintosh.o
 DRIVERS-$(CONFIG_MAC) += drivers/macintosh/macintosh.o
 DRIVERS-$(CONFIG_ISAPNP) += drivers/pnp/pnp.o
 DRIVERS-$(CONFIG_SGI_IP22) += drivers/sgi/sgi.a
@@ -180,11 +180,13 @@
 DRIVERS-$(CONFIG_TC) += drivers/tc/tc.a
 DRIVERS-$(CONFIG_USB) += drivers/usb/usbdrv.o
 DRIVERS-$(CONFIG_INPUT) += drivers/input/inputdrv.o
+DRIVERS-$(CONFIG_HIL) += drivers/hil/hil.o
 DRIVERS-$(CONFIG_I2O) += drivers/message/i2o/i2o.o
 DRIVERS-$(CONFIG_IRDA) += drivers/net/irda/irda.o
 DRIVERS-$(CONFIG_I2C) += drivers/i2c/i2c.o
 DRIVERS-$(CONFIG_PHONE) += drivers/telephony/telephony.o
 DRIVERS-$(CONFIG_MD) += drivers/md/mddev.o
+DRIVERS-$(CONFIG_GSC) += drivers/gsc/gscbus.o
 DRIVERS-$(CONFIG_BLUEZ) += drivers/bluetooth/bluetooth.o
 DRIVERS-$(CONFIG_HOTPLUG_PCI) += drivers/hotplug/vmlinux-obj.o
 DRIVERS-$(CONFIG_ISDN_BOOL) += drivers/isdn/vmlinux-obj.o
@@ -369,7 +371,7 @@
 TAGS: dummy
 	{ find include/asm-${ARCH} -name '*.h' -print ; \
 	find include -type d \( -name "asm-*" -o -name config \) -prune -o -name '*.h' -print ; \
-	find $(SUBDIRS) init arch/${ARCH} -name '*.[chS]' ; } | grep -v SCCS | etags -
+	find $(SUBDIRS) init arch/${ARCH} -name '*.[chS]' ; } | grep -v SCCS | grep -v '\.svn' | etags -
 
 # Exuberant ctags works better with -I
 tags: dummy
@@ -487,7 +489,7 @@
 
 dep-files: scripts/mkdep archdep include/linux/version.h
 	scripts/mkdep -- init/*.c > .depend
-	scripts/mkdep -- `find $(FINDHPATH) -name SCCS -prune -o -follow -name \*.h ! -name modversions.h -print` > .hdepend
+	scripts/mkdep -- `find $(FINDHPATH) \( -name SCCS -o -name .svn \) -prune -o -follow -name \*.h ! -name modversions.h -print` > .hdepend
 	$(MAKE) $(patsubst %,_sfdep_%,$(SUBDIRS)) _FASTDEP_ALL_SUB_DIRS="$(SUBDIRS)"
 ifdef CONFIG_MODVERSIONS
 	$(MAKE) update-modverfile
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/alpha/config.in linux-bk/arch/alpha/config.in
--- linux-2.4.19/arch/alpha/config.in	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/alpha/config.in	2002-08-17 00:48:55.000000000 +0000
@@ -250,9 +250,9 @@
 fi
 
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-   bool 'Discontiguous Memory Support' CONFIG_DISCONTIGMEM
+   bool 'Discontiguous Memory Support (EXPERIMENTAL)' CONFIG_DISCONTIGMEM
    if [ "$CONFIG_DISCONTIGMEM" = "y" ]; then
-      bool ' NUMA Support' CONFIG_NUMA
+      bool ' NUMA Support (EXPERIMENTAL)' CONFIG_NUMA
    fi
 fi
 
@@ -360,7 +360,7 @@
 mainmenu_option next_comment
 comment 'Old CD-ROM drivers (not SCSI, not IDE)'
 
-bool 'Support non-SCSI/IDE/ATAPI drives' CONFIG_CD_NO_IDESCSI
+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
@@ -423,3 +423,5 @@
 fi
 
 endmenu
+
+source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/alpha/kernel/pci.c linux-bk/arch/alpha/kernel/pci.c
--- linux-2.4.19/arch/alpha/kernel/pci.c	2001-11-03 01:39:20.000000000 +0000
+++ linux-bk/arch/alpha/kernel/pci.c	2002-08-17 00:48:50.000000000 +0000
@@ -351,7 +351,7 @@
 }
 
 int
-pcibios_enable_device(struct pci_dev *dev)
+pcibios_enable_device(struct pci_dev *dev, int mask)
 {
 	/* Nothing to do, since we enable all devices at startup.  */
 	return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/alpha/kernel/traps.c linux-bk/arch/alpha/kernel/traps.c
--- linux-2.4.19/arch/alpha/kernel/traps.c	2001-11-20 23:49:31.000000000 +0000
+++ linux-bk/arch/alpha/kernel/traps.c	2002-08-17 00:48:58.000000000 +0000
@@ -167,6 +167,11 @@
 	dik_show_trace(sp);
 }
 
+void dump_stack(void)
+{
+	show_stack(NULL);
+}
+
 void
 die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/alpha/mm/fault.c linux-bk/arch/alpha/mm/fault.c
--- linux-2.4.19/arch/alpha/mm/fault.c	2001-09-17 23:15:02.000000000 +0000
+++ linux-bk/arch/alpha/mm/fault.c	2002-08-17 00:48:59.000000000 +0000
@@ -88,6 +88,7 @@
 	struct mm_struct *mm = current->mm;
 	unsigned int fixup;
 	int fault;
+	siginfo_t info;
 
 	/* As of EV6, a load into $31/$f31 is a prefetch, and never faults
 	   (or is suppressed by the PALcode).  Support that for older CPUs
@@ -108,6 +109,8 @@
 	if (!mm || in_interrupt())
 		goto no_context;
 
+	info.si_code = SEGV_MAPERR;
+
 #ifdef CONFIG_ALPHA_LARGE_VMALLOC
 	if (address >= TASK_SIZE)
 		goto vmalloc_fault;
@@ -128,6 +131,7 @@
  * we can handle it..
  */
 good_area:
+	info.si_code = SEGV_ACCERR;
 	if (cause < 0) {
 		if (!(vma->vm_flags & VM_EXEC))
 			goto bad_area;
@@ -164,7 +168,12 @@
 	up_read(&mm->mmap_sem);
 
 	if (user_mode(regs)) {
-		force_sig(SIGSEGV, current);
+			
+		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,current);
 		return;
 	}
 
@@ -196,8 +205,7 @@
  */
 out_of_memory:
 	if (current->pid == 1) {
-		current->policy |= SCHED_YIELD;
-		schedule();
+		yield();
 		down_read(&mm->mmap_sem);
 		goto survive;
 	}
@@ -212,7 +220,12 @@
 	 * Send a sigbus, regardless of whether we were in kernel
 	 * or user mode.
 	 */
-	force_sig(SIGBUS, current);
+	info.si_signo = SIGBUS;
+	info.si_errno = 0;
+	/* not sure si_code value here  */
+	info.si_code =  BUS_ADRERR;
+	info.si_addr = (void *)address;
+	force_sig_info(SIGBUS,&info,current);
 	if (!user_mode(regs))
 		goto no_context;
 	return;
@@ -220,7 +233,11 @@
 #ifdef CONFIG_ALPHA_LARGE_VMALLOC
 vmalloc_fault:
 	if (user_mode(regs)) {
-		force_sig(SIGSEGV, current);
+		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,current);
 		return;
 	} else {
 		/* Synchronize this task's top level page-table
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/arm/config.in linux-bk/arch/arm/config.in
--- linux-2.4.19/arch/arm/config.in	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/arm/config.in	2002-08-17 00:48:54.000000000 +0000
@@ -417,7 +417,7 @@
 fi
 
 source drivers/pci/Config.in
-bool 'Support hot-pluggable devices' CONFIG_HOTPLUG
+bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
 if [ "$CONFIG_HOTPLUG" = "y" ]; then
    source drivers/pcmcia/Config.in
 else
@@ -503,7 +503,7 @@
    mainmenu_option next_comment
    comment 'Network device support'
 
-   bool 'Network device support?' CONFIG_NETDEVICES
+   bool 'Network device support' CONFIG_NETDEVICES
    if [ "$CONFIG_NETDEVICES" = "y" ]; then
       source drivers/net/Config.in
    fi
@@ -530,7 +530,7 @@
 mainmenu_option next_comment
 comment 'SCSI support'
 
-tristate 'SCSI support?' CONFIG_SCSI
+tristate 'SCSI support' CONFIG_SCSI
 
 if [ "$CONFIG_SCSI" != "n" ]; then
    source drivers/scsi/Config.in
@@ -618,7 +618,7 @@
    mainmenu_option next_comment
    comment 'Sound'
 
-   tristate 'Sound support' CONFIG_SOUND
+   tristate 'Sound card support' CONFIG_SOUND
    if [ "$CONFIG_SOUND" != "n" ]; then
       source drivers/sound/Config.in
    fi
@@ -655,3 +655,5 @@
 dep_bool '    Kernel low-level debugging messages via footbridge serial port' CONFIG_DEBUG_DC21285_PORT $CONFIG_DEBUG_LL $CONFIG_FOOTBRIDGE
 dep_bool '    Kernel low-level debugging messages via UART2' CONFIG_DEBUG_CLPS711X_UART2 $CONFIG_DEBUG_LL $CONFIG_ARCH_CLPS711X
 endmenu
+
+source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/arm/mach-integrator/cpu.c linux-bk/arch/arm/mach-integrator/cpu.c
--- linux-2.4.19/arch/arm/mach-integrator/cpu.c	2001-10-11 16:04:57.000000000 +0000
+++ linux-bk/arch/arm/mach-integrator/cpu.c	2002-08-17 00:49:07.000000000 +0000
@@ -121,7 +121,7 @@
 	cpu_freq_khz = vco_to_freq(vco, 1);
 
 #ifdef CONFIG_CPU_FREQ
-	cpufreq_init(cpu_freq_khz);
+	cpufreq_init(cpu_freq_khz, 1000, 0);
 	cpufreq_setfunctions(integrator_validatespeed, integrator_setspeed);
 #endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/arm/mach-sa1100/generic.c linux-bk/arch/arm/mach-sa1100/generic.c
--- linux-2.4.19/arch/arm/mach-sa1100/generic.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/arm/mach-sa1100/generic.c	2002-08-17 00:48:58.000000000 +0000
@@ -86,7 +86,7 @@
 
 static int __init sa11x0_init_clock(void)
 {
-	cpufreq_init(cclk_frequency_100khz[PPCR & 0xf] * 100);
+	cpufreq_init(cclk_frequency_100khz[PPCR & 0xf] * 100, 0, 0);
 	return 0;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/arm/mm/fault-common.c linux-bk/arch/arm/mm/fault-common.c
--- linux-2.4.19/arch/arm/mm/fault-common.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/arm/mm/fault-common.c	2002-08-17 00:48:49.000000000 +0000
@@ -225,8 +225,7 @@
 	 * If we are out of memory for pid1,
 	 * sleep for a while and retry
 	 */
-	tsk->policy |= SCHED_YIELD;
-	schedule();
+	yield();
 	goto survive;
 
 check_stack:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/config.in linux-bk/arch/cris/config.in
--- linux-2.4.19/arch/cris/config.in	2002-02-25 19:37:52.000000000 +0000
+++ linux-bk/arch/cris/config.in	2002-08-17 00:48:48.000000000 +0000
@@ -39,6 +39,8 @@
 	bool 'Disable watchdog during Oops printouts' CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
 fi
 
+bool 'Enable ETRAX fast timer API' CONFIG_ETRAX_FAST_TIMER
+
 endmenu
 
 mainmenu_option next_comment
@@ -253,4 +255,6 @@
 if [ "$CONFIG_PROFILE" = "y" ]; then
   int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
 fi
+
+source lib/Config.in
 endmenu
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/Config.in linux-bk/arch/cris/drivers/Config.in
--- linux-2.4.19/arch/cris/drivers/Config.in	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/cris/drivers/Config.in	2002-08-17 00:48:55.000000000 +0000
@@ -23,8 +23,7 @@
 
 bool 'Serial-port support' CONFIG_ETRAX_SERIAL
 if [ "$CONFIG_ETRAX_SERIAL" = "y" ]; then
-#  bool '  Use fast timers for DMA flush and RS-485 timing' CONFIG_ETRAX_SERIAL_FAST_TIMER n
-  define_bool CONFIG_ETRAX_SERIAL_FAST_TIMER n
+  bool '  Use fast timers for serial DMA flush (experimental)' CONFIG_ETRAX_SERIAL_FAST_TIMER
   if [ "$CONFIG_ETRAX_SERIAL_FAST_TIMER" = "n" ]; then
     bool '  Fast serial port DMA flush' CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST
     if [ "$CONFIG_ETRAX100_SERIAL_FLUSH_DMA_FAST" = "n" ]; then
@@ -156,6 +155,11 @@
 # this is true for most products since PB-I2C seems to be somewhat
 # flawed.. 
 	bool 'I2C uses PB not PB-I2C' CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C
+
+	if [ "$CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C" = "y" ]; then
+          int '  I2C SDA bit number' CONFIG_ETRAX_I2C_DATA_PORT 0
+          int '  I2C SCL bit number' CONFIG_ETRAX_I2C_CLK_PORT 1
+	fi
 fi
 
 bool 'I2C EEPROM (non-volatile RAM) support' CONFIG_ETRAX_I2C_EEPROM
@@ -182,6 +186,8 @@
 
 fi
 
+bool 'VIRTEX FPGA support' CONFIG_ETRAX_VIRTEX_FPGA
+
 bool 'USB host' CONFIG_ETRAX_USB_HOST
 if [ "$CONFIG_ETRAX_USB_HOST" = "y" ]; then
 	define_bool CONFIG_USB y
@@ -191,7 +197,13 @@
 	define_bool CONFIG_USB n
 fi
 
-bool 'DS1302 Real Time Clock support' CONFIG_ETRAX_DS1302
+bool 'Real Time Clock support' CONFIG_ETRAX_RTC
+if [ "$CONFIG_ETRAX_RTC" = "y" ]; then
+  choice '  RTC chip' \
+    "DS1302 CONFIG_ETRAX_DS1302 \
+     PCF8563  CONFIG_ETRAX_PCF8563" DS1302
+fi
+
 if [ "$CONFIG_ETRAX_DS1302" = "y" ]; then
   bool '  DS1302 RST on Generic Port' CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
   int '  DS1302 RST bit number' CONFIG_ETRAX_DS1302_RSTBIT 2
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/Makefile linux-bk/arch/cris/drivers/Makefile
--- linux-2.4.19/arch/cris/drivers/Makefile	2001-07-04 18:50:38.000000000 +0000
+++ linux-bk/arch/cris/drivers/Makefile	2002-08-17 00:48:47.000000000 +0000
@@ -6,7 +6,7 @@
 
 obj-y :=
 
-
+obj-$(CONFIG_ETRAX_VIRTEX_FPGA)         += virtex.o
 obj-$(CONFIG_ETRAX_ETHERNET)            += ethernet.o
 obj-$(CONFIG_ETRAX_SERIAL)              += serial.o
 obj-$(CONFIG_ETRAX_IDE)                 += ide.o
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/ds1302.c linux-bk/arch/cris/drivers/ds1302.c
--- linux-2.4.19/arch/cris/drivers/ds1302.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/cris/drivers/ds1302.c	2002-08-17 00:49:12.000000000 +0000
@@ -7,6 +7,9 @@
 *! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init, get_rtc_status
 *!
 *! $Log: ds1302.c,v $
+*! Revision 1.13  2002/05/29 15:16:08  johana
+*! Removed unused variables.
+*!
 *! Revision 1.12  2002/04/10 15:35:25  johana
 *! Moved probe function closer to init function and marked it __init.
 *!
@@ -85,7 +88,7 @@
 *!
 *! (C) Copyright 1999, 2000, 2001  Axis Communications AB, LUND, SWEDEN
 *!
-*! $Id: ds1302.c,v 1.12 2002/04/10 15:35:25 johana Exp $
+*! $Id: ds1302.c,v 1.13 2002/05/29 15:16:08 johana Exp $
 *!
 *!***************************************************************************/
 
@@ -322,7 +325,6 @@
 		{
 			struct rtc_time rtc_tm;
 			unsigned char mon, day, hrs, min, sec, leap_yr;
-			unsigned char save_control, save_freq_select;
 			unsigned int yrs;
 
 			if (!capable(CAP_SYS_TIME))
@@ -386,7 +388,6 @@
 		case RTC_SET_CHARGE: /* set the RTC TRICKLE CHARGE register */
 		{
 			int tcs_val;                        
-			unsigned char save_control, save_freq_select;
 
 			if (!capable(CAP_SYS_TIME))
 				return -EPERM;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/gpio.c linux-bk/arch/cris/drivers/gpio.c
--- linux-2.4.19/arch/cris/drivers/gpio.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/cris/drivers/gpio.c	2002-08-17 00:48:47.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: gpio.c,v 1.15 2002/05/06 13:19:13 johana Exp $
+/* $Id: gpio.c,v 1.17 2002/06/17 15:53:01 johana Exp $
  *
  * Etrax general port I/O device
  *
@@ -9,6 +9,18 @@
  *             Johan Adolfsson  (read/set directions, write, port G)
  *
  * $Log: gpio.c,v $
+ * Revision 1.17  2002/06/17 15:53:01  johana
+ * Added IO_READ_INBITS, IO_READ_OUTBITS, IO_SETGET_INPUT and IO_SETGET_OUTPUT
+ * that take a pointer as argument and thus can handle 32 bit ports (G)
+ * correctly.
+ * These should be used instead of IO_READBITS, IO_SETINPUT and IO_SETOUTPUT.
+ * (especially if Port G bit 31 is used)
+ *
+ * Revision 1.16  2002/06/17 09:59:51  johana
+ * Returning 32 bit values in the ioctl return value doesn't work if bit
+ * 31 is set (could happen for port G), so mask it of with 0x7FFFFFFF.
+ * A new set of ioctl's will be added.
+ *
  * Revision 1.15  2002/05/06 13:19:13  johana
  * IO_SETINPUT returns mask with bit set = inputs for PA and PB as well.
  *
@@ -330,6 +342,107 @@
  * set alarms to wait for using a subsequent select().
  */
 
+unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg)
+{
+	/* Set direction 0=unchanged 1=input, 
+	 * return mask with 1=input 
+	 */
+	unsigned long flags;
+	if (USE_PORTS(priv)) {
+		save_flags(flags); cli();
+		*priv->dir = *priv->dir_shadow &= 
+		~((unsigned char)arg & priv->changeable_dir);
+		restore_flags(flags);
+		return ~(*priv->dir_shadow);
+	} else if (priv->minor == GPIO_MINOR_G) {
+		/* We must fiddle with R_GEN_CONFIG to change dir */
+		if (((arg & dir_g_in_bits) != arg) && 
+		    (arg & changeable_dir_g)) {
+			arg &= changeable_dir_g;
+			/* Clear bits in genconfig to set to input */
+			if (arg & (1<<0)) {
+				genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g0dir);
+				dir_g_in_bits |= (1<<0);
+				dir_g_out_bits &= ~(1<<0);
+			}
+			if ((arg & 0x0000FF00) == 0x0000FF00) {
+				genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g8_15dir);
+				dir_g_in_bits |= 0x0000FF00;
+				dir_g_out_bits &= ~0x0000FF00;
+			}
+			if ((arg & 0x00FF0000) == 0x00FF0000) {
+				genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g16_23dir);
+				dir_g_in_bits |= 0x00FF0000;
+				dir_g_out_bits &= ~0x00FF0000;
+			}
+			if (arg & (1<<24)) {
+				genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g24dir);
+				dir_g_in_bits |= (1<<24);
+				dir_g_out_bits &= ~(1<<24);
+			}
+			printk("gpio: SETINPUT on port G set "
+				"genconfig to 0x%08lX "
+				"in_bits: 0x%08lX "
+				"out_bits: 0x%08lX\n", 
+			       (unsigned long)genconfig_shadow, 
+			       dir_g_in_bits, dir_g_out_bits);
+			*R_GEN_CONFIG = genconfig_shadow;
+			/* Must be a >120 ns delay before writing this again */
+				
+		}
+		return dir_g_in_bits;
+	}
+	return 0;
+} /* setget_input */
+
+unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg)
+{
+	unsigned long flags;
+	if (USE_PORTS(priv)) {
+		save_flags(flags); cli();
+		*priv->dir = *priv->dir_shadow |= 
+		  ((unsigned char)arg & priv->changeable_dir);
+		restore_flags(flags);
+		return *priv->dir_shadow;
+	} else if (priv->minor == GPIO_MINOR_G) {
+		/* We must fiddle with R_GEN_CONFIG to change dir */			
+		if (((arg & dir_g_out_bits) != arg) &&
+		    (arg & changeable_dir_g)) {
+			/* Set bits in genconfig to set to output */
+			if (arg & (1<<0)) {
+				genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g0dir);
+				dir_g_out_bits |= (1<<0);
+				dir_g_in_bits &= ~(1<<0);
+			}
+			if ((arg & 0x0000FF00) == 0x0000FF00) {
+				genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g8_15dir);
+				dir_g_out_bits |= 0x0000FF00;
+				dir_g_in_bits &= ~0x0000FF00;
+			}
+			if ((arg & 0x00FF0000) == 0x00FF0000) {
+				genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g16_23dir);
+				dir_g_out_bits |= 0x00FF0000;
+				dir_g_in_bits &= ~0x00FF0000;
+			}
+			if (arg & (1<<24)) {
+				genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g24dir);
+				dir_g_out_bits |= (1<<24);
+				dir_g_in_bits &= ~(1<<24);
+			}
+			printk("gpio: SETOUTPUT on port G set "
+				"genconfig to 0x%08lX "
+				"in_bits: 0x%08lX "
+				"out_bits: 0x%08lX\n", 
+			       (unsigned long)genconfig_shadow, 
+			       dir_g_in_bits, dir_g_out_bits);
+			*R_GEN_CONFIG = genconfig_shadow;
+			/* Must be a >120 ns delay before writing this again */
+		}
+		return dir_g_out_bits & 0x7FFFFFFF;
+	}
+	return 0;
+} /* setget_output */
+
 static int
 gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
 
@@ -338,18 +451,19 @@
 	   unsigned int cmd, unsigned long arg)
 {
 	unsigned long flags;
+	unsigned long val;
 	struct gpio_private *priv = (struct gpio_private *)file->private_data;
 	if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE) {
 		return -EINVAL;
 	}
 
 	switch (_IOC_NR(cmd)) {
-	case IO_READBITS:
+	case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
 		// read the port
 		if (USE_PORTS(priv)) {
 			return *priv->port;
 		} else if (priv->minor == GPIO_MINOR_G) {
-			return *R_PORT_G_DATA;
+			return (*R_PORT_G_DATA) & 0x7FFFFFFF;
 		}
 		break;
 	case IO_SETBITS:
@@ -387,113 +501,28 @@
 		priv->highalarm &= ~arg;
 		priv->lowalarm  &= ~arg;
 		break;
-	case IO_READDIR:
+	case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
 		/* Read direction 0=input 1=output */
 		if (USE_PORTS(priv)) {
 			return *priv->dir_shadow;
 		} else if (priv->minor == GPIO_MINOR_G) {
 			/* Note: Some bits are both in and out,
-			 * Those that are dual is set hare as well.
+			 * Those that are dual is set here as well.
 			 */
-			return dir_g_shadow | dir_g_out_bits;
+			return (dir_g_shadow | dir_g_out_bits) & 0x7FFFFFFF;
 		}
-	case IO_SETINPUT:
+	case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */
 		/* Set direction 0=unchanged 1=input, 
 		 * return mask with 1=input 
 		 */
-		if (USE_PORTS(priv)) {
-			save_flags(flags); cli();
-			*priv->dir = *priv->dir_shadow &= 
-			~((unsigned char)arg & priv->changeable_dir);
-			restore_flags(flags);
-			return ~(*priv->dir_shadow);
-		} else if (priv->minor == GPIO_MINOR_G) {
-			/* We must fiddle with R_GEN_CONFIG to change dir */
-			if (((arg & dir_g_in_bits) != arg) && 
-			    (arg & changeable_dir_g)) {
-				arg &= changeable_dir_g;
-				/* Clear bits in genconfig to set to input */
-				if (arg & (1<<0)) {
-					genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g0dir);
-					dir_g_in_bits |= (1<<0);
-					dir_g_out_bits &= ~(1<<0);
-				}
-				if ((arg & 0x0000FF00) == 0x0000FF00) {
-					genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g8_15dir);
-					dir_g_in_bits |= 0x0000FF00;
-					dir_g_out_bits &= ~0x0000FF00;
-				}
-				if ((arg & 0x00FF0000) == 0x00FF0000) {
-					genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g16_23dir);
-					dir_g_in_bits |= 0x00FF0000;
-					dir_g_out_bits &= ~0x00FF0000;
-				}
-				if (arg & (1<<24)) {
-					genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g24dir);
-					dir_g_in_bits |= (1<<24);
-					dir_g_out_bits &= ~(1<<24);
-				}
-				printk("gpio: SETINPUT on port G set "
-					"genconfig to 0x%08lX "
-					"in_bits: 0x%08lX "
-					"out_bits: 0x%08lX\n", 
-				       (unsigned long)genconfig_shadow, 
-				       dir_g_in_bits, dir_g_out_bits);
-				*R_GEN_CONFIG = genconfig_shadow;
-				/* Must be a >120 ns delay before writing this again */
-				
-			}
-			return dir_g_in_bits;
-		}
-		return 0;
-
-	case IO_SETOUTPUT:
+		return setget_input(priv, arg) & 0x7FFFFFFF;
+		break;
+	case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */
 		/* Set direction 0=unchanged 1=output, 
 		 * return mask with 1=output 
 		 */
-		if (USE_PORTS(priv)) {
-			save_flags(flags); cli();
-			*priv->dir = *priv->dir_shadow |= 
-			  ((unsigned char)arg & priv->changeable_dir);
-			restore_flags(flags);
-			return *priv->dir_shadow;
-		} else if (priv->minor == GPIO_MINOR_G) {
-			/* We must fiddle with R_GEN_CONFIG to change dir */			
-			if (((arg & dir_g_out_bits) != arg) &&
-			    (arg & changeable_dir_g)) {
-				/* Set bits in genconfig to set to output */
-				if (arg & (1<<0)) {
-					genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g0dir);
-					dir_g_out_bits |= (1<<0);
-					dir_g_in_bits &= ~(1<<0);
-				}
-				if ((arg & 0x0000FF00) == 0x0000FF00) {
-					genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g8_15dir);
-					dir_g_out_bits |= 0x0000FF00;
-					dir_g_in_bits &= ~0x0000FF00;
-				}
-				if ((arg & 0x00FF0000) == 0x00FF0000) {
-					genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g16_23dir);
-					dir_g_out_bits |= 0x00FF0000;
-					dir_g_in_bits &= ~0x00FF0000;
-				}
-				if (arg & (1<<24)) {
-					genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g24dir);
-					dir_g_out_bits |= (1<<24);
-					dir_g_in_bits &= ~(1<<24);
-				}
-				printk("gpio: SETOUTPUT on port G set "
-					"genconfig to 0x%08lX "
-					"in_bits: 0x%08lX "
-					"out_bits: 0x%08lX\n", 
-				       (unsigned long)genconfig_shadow, 
-				       dir_g_in_bits, dir_g_out_bits);
-				*R_GEN_CONFIG = genconfig_shadow;
-				/* Must be a >120 ns delay before writing this again */
-			}
-			return dir_g_out_bits;
-		}
-		return 0;
+		return setget_output(priv, arg) & 0x7FFFFFFF;
+
 	case IO_SHUTDOWN:
 		SOFT_SHUTDOWN();
 		break;
@@ -521,6 +550,47 @@
 			return -EPERM;
 		}
 		break;
+	case IO_READ_INBITS: 
+		/* *arg is result of reading the input pins */
+		if (USE_PORTS(priv)) {
+			val = *priv->port;
+		} else if (priv->minor == GPIO_MINOR_G) {
+			val = *R_PORT_G_DATA;
+		}
+		if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
+			return -EFAULT;
+		return 0;
+		break;
+	case IO_READ_OUTBITS:
+		 /* *arg is result of reading the output shadow */
+		if (USE_PORTS(priv)) {
+			val = *priv->shadow;
+		} else if (priv->minor == GPIO_MINOR_G) {
+			val = port_g_data_shadow;
+		}
+		if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
+			return -EFAULT;
+		break;
+	case IO_SETGET_INPUT: 
+		/* bits set in *arg is set to input,
+		 * *arg updated with current input pins.
+		 */
+		if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
+			return -EFAULT;
+		val = setget_input(priv, val);
+		if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
+			return -EFAULT;
+		break;
+	case IO_SETGET_OUTPUT:
+		/* bits set in *arg is set to output,
+		 * *arg updated with current output pins.
+		 */
+		if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
+			return -EFAULT;
+		val = setget_output(priv, val);
+		if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
+			return -EFAULT;
+		break;
 	default:
 		if (priv->minor == GPIO_MINOR_LEDS)
 			return gpio_leds_ioctl(cmd, arg);
@@ -690,7 +760,7 @@
 
 #endif
 	gpio_init_port_g();
-	printk("ETRAX 100LX GPIO driver v2.3, (c) 2001, 2002 Axis Communications AB\n");
+	printk("ETRAX 100LX GPIO driver v2.4, (c) 2001, 2002 Axis Communications AB\n");
 
 	return res;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/i2c.c linux-bk/arch/cris/drivers/i2c.c
--- linux-2.4.19/arch/cris/drivers/i2c.c	2001-05-20 00:43:05.000000000 +0000
+++ linux-bk/arch/cris/drivers/i2c.c	2002-08-17 00:48:50.000000000 +0000
@@ -12,6 +12,10 @@
 *!                                 don't use PB_I2C if DS1302 uses same bits,
 *!                                 use PB.
 *! $Log: i2c.c,v $
+*! Revision 1.8  2002/08/13 06:31:53  starvik
+*! Made SDA and SCL line configurable
+*! Modified i2c_inbyte to work with PCF8563
+*!
 *! Revision 1.7  2001/04/04 13:11:36  markusl
 *! Updated according to review remarks
 *!
@@ -40,10 +44,10 @@
 *!
 *! ---------------------------------------------------------------------------
 *!
-*! (C) Copyright 1999, 2000, 2001 Axis Communications AB, LUND, SWEDEN
+*! (C) Copyright 1999-2002 Axis Communications AB, LUND, SWEDEN
 *!
 *!***************************************************************************/
-/* $Id: i2c.c,v 1.7 2001/04/04 13:11:36 markusl Exp $ */
+/* $Id: i2c.c,v 1.8 2002/08/13 06:31:53 starvik Exp $ */
 /****************** INCLUDE FILES SECTION ***********************************/
 
 #include <linux/module.h>
@@ -93,8 +97,15 @@
 
 #ifdef CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C
 /* Use PB and not PB_I2C */
-#define SDABIT 0
-#define SCLBIT 1
+#ifndef CONFIG_ETRAX_I2C_DATA_PORT
+#define CONFIG_ETRAX_I2C_DATA_PORT 0
+#endif
+#ifndef CONFIG_ETRAX_I2C_CLK_PORT
+#define CONFIG_ETRAX_I2C_CLK_PORT 1
+#endif
+
+#define SDABIT CONFIG_ETRAX_I2C_DATA_PORT
+#define SCLBIT CONFIG_ETRAX_I2C_CLK_PORT
 #define i2c_enable() 
 #define i2c_disable() 
 
@@ -114,7 +125,7 @@
 
 /* read a bit from the i2c interface */
 
-#define i2c_getbit() (*R_PORT_PB_READ & (1 << SDABIT))
+#define i2c_getbit() (((*R_PORT_PB_READ & (1 << SDABIT))) >> SDABIT)
 
 #else
 /* enable or disable the i2c interface */
@@ -206,7 +217,7 @@
 i2c_outbyte(unsigned char x)
 {
 	int i;
-	
+
 	i2c_dir_out();
 
 	for (i = 0; i < 8; i++) {
@@ -238,65 +249,44 @@
 {
 	unsigned char aBitByte = 0;
 	int i;
-	int iaa;
 
-	/*
-	 * enable output
-	 */
-	i2c_dir_out();
-	/*
-	 * Release data bus by setting
-	 * data high
-	 */
-	i2c_data(I2C_DATA_HIGH);
-	/*
-	 * enable input
-	 */
+	/* Switch off I2C to get bit */
+	i2c_disable();
 	i2c_dir_in();
-	/*
-	 * Use PORT PB instead of I2C
-	 * for input. (I2C not working)
-	 */
-	i2c_clk(1);
-	i2c_data(1);
-	/*
-	 * get bits
-	 */
-	for (i = 0; i < 8; i++) {
-		i2c_delay(CLOCK_LOW_TIME/2);
-		/*
-		 * low clock period
-		 */
+	i2c_delay(CLOCK_HIGH_TIME/2);
+
+	/* Get bit */
+	aBitByte |= i2c_getbit();
+
+	/* Enable I2C */
+	i2c_enable();
+	i2c_dir_out();
+	i2c_delay(CLOCK_LOW_TIME/2);
+
+	for (i = 1; i < 8; i++) {
+		aBitByte <<= 1;
+		/* Clock pulse */
 		i2c_clk(I2C_CLOCK_HIGH);
-		/*
-		 * switch off I2C
-		 */
-		i2c_data(1);
+		i2c_delay(CLOCK_HIGH_TIME);
+		i2c_clk(I2C_CLOCK_LOW);
+		i2c_delay(CLOCK_LOW_TIME);
+
+		/* Switch off I2C to get bit */
 		i2c_disable();
 		i2c_dir_in();
-		/*
-		 * wait before getting bit
-		 */
-		i2c_delay(CLOCK_HIGH_TIME/2);
-		aBitByte = (aBitByte << 1);
-		iaa = i2c_getbit();
-		aBitByte = aBitByte | iaa ;
-		/*
-		 * wait
-		 */
 		i2c_delay(CLOCK_HIGH_TIME/2);
-		/*
-		 * end clock puls
-		 */
+
+		/* Get bit */
+		aBitByte |= i2c_getbit();
+
+		/* Enable I2C */
 		i2c_enable();
 		i2c_dir_out();
-		i2c_clk(I2C_CLOCK_LOW);
-		/*
-		 * low clock period
-		 */
 		i2c_delay(CLOCK_LOW_TIME/2);
 	}
-	i2c_dir_out();
+	i2c_clk(I2C_CLOCK_HIGH);
+	i2c_delay(CLOCK_HIGH_TIME);
+	i2c_clk(I2C_CLOCK_LOW);
 	return aBitByte;
 }
 
@@ -421,7 +411,7 @@
 *#
 *#--------------------------------------------------------------------------*/
 int
-i2c_writereg(unsigned char theSlave, unsigned char theReg,
+i2c_writereg(unsigned char theSlave, unsigned char theReg, 
 	     unsigned char theValue)
 {
 	int error, cntr = 3;
@@ -434,31 +424,12 @@
 		 */
 		save_flags(flags);
 		cli();
-		/*
-		 * generate start condition
-		 */
-		i2c_start();
-		/*
-		 * dummy preamble
-		 */
-		i2c_outbyte(0x01);
-		i2c_data(I2C_DATA_HIGH);
-		i2c_clk(I2C_CLOCK_HIGH);
-		i2c_delay(CLOCK_HIGH_TIME); /* Dummy Acknowledge */
-		i2c_clk(I2C_CLOCK_LOW);
-		i2c_delay(CLOCK_LOW_TIME);
-		i2c_clk(I2C_CLOCK_HIGH);
-		i2c_delay(CLOCK_LOW_TIME); /* Repeated Start Condition */
-		i2c_data(I2C_DATA_LOW);
-		i2c_delay(CLOCK_HIGH_TIME);
-		i2c_clk(I2C_CLOCK_LOW);
-		i2c_delay(CLOCK_LOW_TIME);
 
 		i2c_start();
 		/*
 		 * send slave address
 		 */
-		i2c_outbyte(theSlave);
+		i2c_outbyte((theSlave & 0xfe));
 		/*
 		 * wait for ack
 		 */
@@ -493,7 +464,7 @@
 		restore_flags(flags);
 		
 	} while(error && cntr--);
-	
+
 	i2c_delay(CLOCK_LOW_TIME);
 	
 	return -error;
@@ -512,7 +483,7 @@
 	unsigned char b = 0;
 	int error, cntr = 3;
 	unsigned long flags;
-		
+
 	do {
 		error = 0;
 		/*
@@ -524,28 +495,11 @@
 		 * generate start condition
 		 */
 		i2c_start();
-		/*
-		 * dummy preamble
-		 */
-		i2c_outbyte(0x01);
-		i2c_data(I2C_DATA_HIGH);
-		i2c_clk(I2C_CLOCK_HIGH);
-		i2c_delay(CLOCK_HIGH_TIME); /* Dummy Acknowledge */
-		i2c_clk(I2C_CLOCK_LOW);
-		i2c_delay(CLOCK_LOW_TIME);
-		i2c_clk(I2C_CLOCK_HIGH);
-		i2c_delay(CLOCK_LOW_TIME); /* Repeated Start Condition */
-		i2c_data(I2C_DATA_LOW);
-		i2c_delay(CLOCK_HIGH_TIME);
-		i2c_clk(I2C_CLOCK_LOW);
-		i2c_delay(CLOCK_LOW_TIME);
-    
-		i2c_start();
     
 		/*
 		 * send slave address
 		 */
-		i2c_outbyte(theSlave);
+		i2c_outbyte((theSlave & 0xfe));
 		/*
 		 * wait for ack
 		 */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/pcf8563.c linux-bk/arch/cris/drivers/pcf8563.c
--- linux-2.4.19/arch/cris/drivers/pcf8563.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/cris/drivers/pcf8563.c	2002-08-17 00:49:08.000000000 +0000
@@ -0,0 +1,258 @@
+/*
+ * PCF8563 RTC
+ *
+ * From Phillips' datasheet:
+ *
+ * The PCF8563 is a CMOS real-time clock/calendar optimized for low power
+ * consumption. A programmable clock output, interupt output and voltage
+ * low detector are also provided. All address and data are transferred
+ * serially via two-line bidirectional I2C-bus. Maximum bus speed is
+ * 400 kbits/s. The built-in word address register is incremented
+ * automatically after each written or read bute.
+ *
+ * Copyright (c) 2002, Axis Communications AB
+ * All rights reserved.
+ *
+ * Author: Tobias Anderberg <tobiasa@axis.com>.
+ *
+ * $Id: pcf8563.c,v 1.1 2002/08/12 13:46:02 starvik Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/ioctl.h>
+#include <linux/delay.h>
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/svinto.h>
+#include <asm/rtc.h>
+#include "i2c.h"
+
+#define PCF8563_MAJOR 121		/* Local major number. */
+#define DEVICE_NAME "rtc"		/* Name which is registered in /proc/devices. */
+#define PCF8563_NAME "PCF8563"
+#define DRIVER_VERSION "$Rev$"
+
+/* Two simple wrapper macros, saves a few keystrokes. */
+#define rtc_read(x) i2c_readreg(RTC_I2C_READ, x)
+#define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y)
+	
+static const unsigned char days_in_month[] =
+	{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
+int pcf8563_open(struct inode *, struct file *);
+int pcf8563_release(struct inode *, struct file *);
+
+static struct file_operations pcf8563_fops = {
+	owner: THIS_MODULE,
+	ioctl: pcf8563_ioctl,
+	open: pcf8563_open,
+	release: pcf8563_release,
+};
+
+void
+get_rtc_time(struct rtc_time *tm)
+{
+	unsigned long flags;
+	
+	tm->tm_sec = rtc_read(RTC_SECONDS);
+	tm->tm_min = rtc_read(RTC_MINUTES);
+	tm->tm_hour = rtc_read(RTC_HOURS);
+	tm->tm_mday = rtc_read(RTC_DAY_OF_MONTH);
+	tm->tm_mon = rtc_read(RTC_MONTH);
+	tm->tm_year = rtc_read(RTC_YEAR);
+
+	if (tm->tm_sec & 0x80)
+		printk(KERN_WARNING "%s: RTC Low Voltage - date/time is not reliable!\n", PCF8563_NAME);
+
+        tm->tm_year = BCD_TO_BIN(tm->tm_year) + ((tm->tm_mon & 0x80) ? 100 : 0);
+	tm->tm_sec &= 0x7f;
+	tm->tm_min &= 0x7f;
+	tm->tm_hour &= 0x3f;
+	tm->tm_mday &= 0x3f;
+	tm->tm_mon &= 0x1f;
+
+	BCD_TO_BIN(tm->tm_sec);
+	BCD_TO_BIN(tm->tm_min);
+	BCD_TO_BIN(tm->tm_hour);
+	BCD_TO_BIN(tm->tm_mday);
+	BCD_TO_BIN(tm->tm_mon);
+	tm->tm_mon--; /* Month is 1..12 in RTC but 0..11 in linux */
+}
+
+int __init
+pcf8563_init(void)
+{
+	unsigned char ret;
+        struct rtc_time tm;
+        
+	/*
+	 * First of all we need to reset the chip. This is done by
+	 * clearing control1, control2 and clk freq, clear the 
+	 * Voltage Low bit, and resetting all alarms.
+	 */
+	if (rtc_write(RTC_CONTROL1, 0x00) < 0)
+		goto err;
+
+	if (rtc_write(RTC_CONTROL2, 0x00) < 0)
+		goto err;
+
+	if (rtc_write(RTC_CLOCKOUT_FREQ, 0x00) < 0)
+		goto err;
+
+	/* Clear the VL bit in the seconds register. */
+	ret = rtc_read(RTC_SECONDS);
+	
+	if (rtc_write(RTC_SECONDS, (ret & 0x7f)) < 0)
+		goto err;
+		
+	/* Reset the alarms. */
+	if (rtc_write(RTC_MINUTE_ALARM, 0x00) < 0)
+		goto err;
+	
+	if (rtc_write(RTC_HOUR_ALARM, 0x00) < 0)
+		goto err;
+	
+	if (rtc_write(RTC_DAY_ALARM, 0x00) < 0)
+		goto err;
+	
+	if (rtc_write(RTC_WEEKDAY_ALARM, 0x00) < 0)
+		goto err;
+
+	if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) {
+		printk(KERN_INFO "%s: Unable to get major numer %d for RTC device.\n", 
+		       PCF8563_NAME, PCF8563_MAJOR);
+		return -1;
+	}
+
+	printk(KERN_INFO "%s Real-Time Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
+        
+	/* Check for low voltage, and warn about it.. */
+	if (rtc_read(RTC_SECONDS) & 0x80)
+		printk(KERN_WARNING "%s: RTC Low Voltage - date/time is not reliable!\n", PCF8563_NAME);
+	
+	return 0;
+
+err:
+	printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME);
+	return -1;
+}
+
+void __exit
+pcf8563_exit(void)
+{
+	if (unregister_chrdev(PCF8563_MAJOR, DEVICE_NAME) < 0) {
+		printk(KERN_INFO "%s: Unable to unregister device.\n", PCF8563_NAME);
+	}
+}
+
+/*
+ * ioctl calls for this driver. Why return -ENOTTY upon error? Because
+ * POSIX says so!
+ */
+int
+pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	/* Some sanity checks. */
+	if (_IOC_TYPE(cmd) != PCF8563_MAGIC)
+		return -ENOTTY;
+
+	if (_IOC_NR(cmd) > RTC_MAX_IOCTL)
+		return -ENOTTY;
+
+	switch (cmd) {
+		case RTC_RD_TIME:
+			{
+				struct rtc_time tm;
+
+				get_rtc_time(&tm);
+
+				if (copy_to_user((struct rtc_time *) arg, &tm, sizeof(struct rtc_time))) {
+					return -EFAULT;
+				}
+
+				return 0;
+			}
+			break;
+		case RTC_SET_TIME:
+			{
+				int leap;
+				int century;
+				unsigned long flags;
+				struct rtc_time tm;
+
+				if (!capable(CAP_SYS_TIME))
+					return -EPERM;
+
+				if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof(struct rtc_time)))
+					return -EFAULT;
+
+				/* Convert from struct tm to struct rtc_time. */
+				tm.tm_year += 1900;
+				tm.tm_mon += 1;
+				
+				leap = ((tm.tm_mon == 2) && ((tm.tm_year % 4) == 0)) ? 1 : 0;
+
+				/* Perform some sanity checks. */
+				if ((tm.tm_year < 1970) ||
+				    (tm.tm_mon > 12) ||
+				    (tm.tm_mday == 0) ||
+				    (tm.tm_mday > days_in_month[tm.tm_mon] + leap) ||
+				    (tm.tm_hour >= 24) ||
+				    (tm.tm_min >= 60) ||
+				    (tm.tm_sec >= 60))
+					return -EINVAL;
+
+				century = (tm.tm_year >= 2000) ? 0x80 : 0;
+				tm.tm_year = tm.tm_year % 100;
+
+				BIN_TO_BCD(tm.tm_year);
+				BIN_TO_BCD(tm.tm_mday);
+				BIN_TO_BCD(tm.tm_hour);
+				BIN_TO_BCD(tm.tm_min);
+				BIN_TO_BCD(tm.tm_sec);
+				tm.tm_mon |= century;
+				
+				rtc_write(RTC_YEAR, tm.tm_year);
+				rtc_write(RTC_MONTH, tm.tm_mon);
+				rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday);
+				rtc_write(RTC_HOURS, tm.tm_hour);
+				rtc_write(RTC_MINUTES, tm.tm_min);
+				rtc_write(RTC_SECONDS, tm.tm_sec);
+
+				return 0;
+			}
+			break;
+		default:
+				return -ENOTTY;
+	}
+
+	return 0;
+}
+
+int 
+pcf8563_open(struct inode *inode, struct file *filp)
+{
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+int
+pcf8563_release(struct inode *inode, struct file *filp)
+{
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+EXPORT_NO_SYMBOLS;
+module_init(pcf8563_init);
+module_exit(pcf8563_exit);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/serial.c linux-bk/arch/cris/drivers/serial.c
--- linux-2.4.19/arch/cris/drivers/serial.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/cris/drivers/serial.c	2002-08-17 00:48:52.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: serial.c,v 1.32 2002/05/22 13:58:00 johana Exp $
+/* $Id: serial.c,v 1.37 2002/08/13 13:02:37 bjornw Exp $
  *
  * Serial port driver for the ETRAX 100LX chip
  *
@@ -7,6 +7,24 @@
  *      Many, many authors. Based once upon a time on serial.c for 16x50.
  *
  * $Log: serial.c,v $
+ * Revision 1.37  2002/08/13 13:02:37  bjornw
+ * Removed some warnings because of unused code
+ *
+ * Revision 1.36  2002/08/08 12:50:01  starvik
+ * Serial interrupt is shared with synchronous serial port driver
+ *
+ * Revision 1.35  2002/06/03 10:40:49  starvik
+ * Increased RS-485 RTS toggle timer to 2 characters
+ *
+ * Revision 1.34  2002/05/28 18:59:36  johana
+ * Whitespace and comment fixing to be more like etrax100ser.c 1.71.
+ *
+ * Revision 1.33  2002/05/28 17:55:43  johana
+ * RS-485 uses FAST_TIMER if enabled, and starts a short (one char time)
+ * timer from tranismit_chars (interrupt context).
+ * The timer toggles RTS in interrupt context when expired giving minimum
+ * latencies.
+ *
  * Revision 1.32  2002/05/22 13:58:00  johana
  * Renamed rs_write() to raw_write() and made it inline.
  * New rs_write() handles RS-485 if configured and enabled
@@ -303,7 +321,7 @@
  *
  */
 
-static char *serial_version = "$Revision: 1.32 $";
+static char *serial_version = "$Revision: 1.37 $";
 
 #include <linux/config.h>
 #include <linux/version.h>
@@ -342,7 +360,16 @@
 #include <linux/serial.h>
 /* while we keep our own stuff (struct e100_serial) in a local .h file */
 #include "serial.h"
+#include <asm/fasttimer.h>
 
+#ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER
+#ifdef CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST
+#error "Disable SERIAL_FLUSH_DMA_FAST to use SERIAL_FAST_TIMER"
+#endif
+#ifndef CONFIG_ETRAX_FAST_TIMER
+#error "Enable FAST_TIMER to use SERIAL_FAST_TIMER"
+#endif
+#endif
 /*
  * All of the compatibilty code so we can compile serial.c against
  * older kernels is hidden in serial_compat.h
@@ -404,8 +431,10 @@
                     const unsigned char *buf, int count);
 static inline int raw_write(struct tty_struct * tty, int from_user,
                             const unsigned char *buf, int count);
+#ifdef CONFIG_ETRAX_RS485
 static int e100_write_rs485(struct tty_struct * tty, int from_user,
                             const unsigned char *buf, int count);
+#endif
 static int 
 get_lsr_info(struct e100_serial * info, unsigned int *value);
 
@@ -519,6 +548,9 @@
 static struct tty_struct *serial_table[NR_PORTS]; 
 static struct termios *serial_termios[NR_PORTS];
 static struct termios *serial_termios_locked[NR_PORTS];
+#ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER
+static struct fast_timer fast_timers[NR_PORTS];
+#endif
 
 #ifdef CONFIG_ETRAX_SERIAL_PROC_ENTRY
 #define PROCSTAT(x) x
@@ -538,7 +570,7 @@
 
 static struct ser_statistics_type ser_stat[NR_PORTS];
 
-#else 
+#else
 
 #define PROCSTAT(x)
 
@@ -546,6 +578,9 @@
 
 /* RS-485 */
 #if defined(CONFIG_ETRAX_RS485)
+#ifdef CONFIG_ETRAX_FAST_TIMER
+static struct fast_timer fast_timers_rs485[NR_PORTS];
+#endif
 #if defined(CONFIG_ETRAX_RS485_ON_PA)
 static int rs485_pa_bit = CONFIG_ETRAX_RS485_ON_PA_BIT;
 #endif
@@ -578,7 +613,7 @@
 	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;
@@ -872,11 +907,6 @@
 		*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 
@@ -895,11 +925,6 @@
 		*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
 }
 
@@ -1014,7 +1039,7 @@
 }
 
 static int
-e100_write_rs485(struct tty_struct *tty, int from_user, 
+e100_write_rs485(struct tty_struct *tty, int from_user,
                  const unsigned char *buf, int count)
 {
 	struct e100_serial * info = (struct e100_serial *)tty->driver_data;
@@ -1031,7 +1056,22 @@
 	info->rs485.enabled = old_enabled;
 	return count;
 }
+
+#ifdef CONFIG_ETRAX_FAST_TIMER
+/* Timer function to toggle RTS when using FAST_TIMER */
+static void rs485_toggle_rts_timer_function(unsigned long data)
+{
+	struct e100_serial *info = (struct e100_serial *)data;
+
+	fast_timers_rs485[info->line].function = NULL;
+	e100_rts(info, info->rs485.rts_after_sent);
+#if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER)
+	e100_enable_rx(info);
+	e100_enable_rxdma_irq(info);
+#endif
+}
 #endif
+#endif /* CONFIG_ETRAX_RS485 */
 
 /*
  * ------------------------------------------------------------
@@ -1174,6 +1214,16 @@
 		/* our job here is done, don't schedule any new DMA transfer */
 		info->tr_running = 0;
 
+#if defined(CONFIG_ETRAX_RS485) && defined(CONFIG_ETRAX_FAST_TIMER)
+		if (info->rs485.enabled) {
+			/* Set a short timer to toggle RTS */
+			start_one_shot_timer(&fast_timers_rs485[info->line],
+			                     rs485_toggle_rts_timer_function,
+			                     (unsigned long)info,
+			                     info->char_time_usec*2,
+			                     "RS-485");
+		}
+#endif /* RS485 */
 		return;
 	}
 
@@ -1189,7 +1239,7 @@
 	*info->ocmdadr = 1;       /* dma command start -> R_DMAx_CMD */
 	
 	/* DMA is now running (hopefully) */
-}
+} /* transmit_chars */
 
 static void 
 start_transmit(struct e100_serial *info)
@@ -1205,7 +1255,7 @@
 	info->tr_running = 1;
 
 	transmit_chars(info);
-}
+} /* start_transmit */
 
 #ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER
 static int serial_fast_timer_started = 0;
@@ -1461,7 +1511,7 @@
 #endif
 
 	/* reset the input dma channel to be sure it works */
-	
+
 	*info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
 	while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->icmdadr) ==
 	       IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset));
@@ -1636,7 +1686,7 @@
 	cli();
 
 	length = tty->flip.count;
-	
+
 	while ((buffer = info->first_recv_buffer) && length < TTY_FLIPBUF_SIZE) {
 		unsigned int count = buffer->length;
 
@@ -1889,7 +1939,7 @@
 			}
 			info->break_detected_cnt = 0;
 			DEBUG_LOG(info->line, "#iERR s d %04X\n",
-				  ((rstat & SER_ERROR_MASK) << 8) | data);
+			          ((rstat & SER_ERROR_MASK) << 8) | data);
 		}
 		PROCSTAT(ser_stat[info->line].early_errors_cnt++);
 	} else { /* It was a valid byte, now let the DMA do the rest */
@@ -1903,8 +1953,8 @@
 			 * previous interrupt we should discard it.
 			 */
 			long elapsed_usec = 
-				(curr_time - info->last_rx_active) * (1000000/HZ) + 
-				curr_time_u - info->last_rx_active_usec;
+			  (curr_time - info->last_rx_active) * (1000000/HZ) + 
+			  curr_time_u - info->last_rx_active_usec;
 			if (elapsed_usec < 2*info->char_time_usec) {
 				DEBUG_LOG(info->line, "FBRK %i\n", info->line);
 				/* Report as BREAK (error) and let
@@ -1942,7 +1992,7 @@
 	for (i = 0; i < NR_PORTS; i++) {
 		info = rs_table + i;
 
-		if (!info->uses_dma) 
+		if (!info->enabled || !info->uses_dma) 
 			continue; 
 
 		/* Which line caused the irq? */
@@ -1992,28 +2042,6 @@
 	}
 }
 
-/*
- * 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)
 {
@@ -2025,7 +2053,8 @@
 	if (!xmit_page)
 		return -ENOMEM;
 
-	save_flags(flags); cli();
+	save_flags(flags); 
+	cli();
 
 	/* if it was already initialized, skip this */
 
@@ -2322,7 +2351,7 @@
 
 static inline int 
 raw_write(struct tty_struct * tty, int from_user,
-	 const unsigned char *buf, int count)
+	  const unsigned char *buf, int count)
 {
 	int	c, ret = 0;
 	struct e100_serial *info = (struct e100_serial *)tty->driver_data;
@@ -2435,6 +2464,11 @@
 		/* If we are in RS-485 mode, we need to toggle RTS and disable
 		 * the receiver before initiating a DMA transfer
 		 */
+#ifdef CONFIG_ETRAX_FAST_TIMER
+		/* Abort any started timer */
+		fast_timers_rs485[info->line].function = NULL;
+		del_fast_timer(&fast_timers_rs485[info->line]);
+#endif
 		e100_rts(info, info->rs485.rts_on_send);
 #if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER)
 		e100_disable_rx(info);
@@ -2482,7 +2516,7 @@
 #endif /* CONFIG_ETRAX_RS485 */
 
 	return count;
-}
+} /* rs_write */
 
 
 /* how much space is available in the xmit buffer? */
@@ -2563,16 +2597,16 @@
 	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);
@@ -2586,20 +2620,20 @@
 	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);
@@ -2722,8 +2756,8 @@
 #ifdef SERIAL_DEBUG_IO 
 struct state_str
 {
-  int state;
-  const char *str;
+	int state;
+	const char *str;
 };
 
 const struct state_str control_state_str[] = {
@@ -3678,6 +3712,15 @@
 			       serial_driver.name, info->line, (unsigned int)info->port);
 		}
 	}
+#ifdef CONFIG_ETRAX_FAST_TIMER
+#ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER
+	memset(fast_timers, 0, sizeof(fast_timers));
+#endif
+#ifdef CONFIG_ETRAX_RS485
+	memset(fast_timers_rs485, 0, sizeof(fast_timers_rs485));
+#endif
+	fast_timer_init();
+#endif
 
 #ifndef CONFIG_SVINTO_SIM
 	/* Not needed in simulator.  May only complicate stuff. */
@@ -3689,7 +3732,7 @@
 		panic("irq23");
 #endif
 #ifdef SERIAL_HANDLE_EARLY_ERRORS
-	if (request_irq(SERIAL_IRQ_NBR, ser_interrupt, SA_INTERRUPT, "serial ", NULL))
+	if (request_irq(SERIAL_IRQ_NBR, ser_interrupt, SA_SHIRQ | SA_INTERRUPT, "serial ", NULL))
 		panic("irq8");
 #endif
 #ifdef CONFIG_ETRAX_SERIAL_PORT1
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/sync_serial.c linux-bk/arch/cris/drivers/sync_serial.c
--- linux-2.4.19/arch/cris/drivers/sync_serial.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/cris/drivers/sync_serial.c	2002-08-17 00:48:51.000000000 +0000
@@ -227,7 +227,7 @@
 #else
 	ports[0].use_dma = 0;
 	initialize_port(0);
-	if (request_irq(8, manual_interrupt, SA_SHIRQ, "synchronous serial manual irq", &ports[0]))
+	if (request_irq(8, manual_interrupt, SA_SHIRQ | SA_INTERRUPT, "synchronous serial manual irq", &ports[0]))
 		panic("Can't allocate sync serial manual irq");
 	*R_IRQ_MASK1_SET = IO_STATE(R_IRQ_MASK1_SET, ser1_data, set);	 
 #endif
@@ -258,9 +258,9 @@
 #else
 	ports[1].use_dma = 0;	
 	initialize_port(1);
-	if (port[0].use_dma) /* Port 0 uses dma, we must manual allocate IRQ */
+	if (ports[0].use_dma) /* Port 0 uses dma, we must manual allocate IRQ */
 	{
-		if (request_irq(8, manual_interrupt, SA_SHIRQ, "synchronous serial manual irq", &ports[1]))
+		if (request_irq(8, manual_interrupt, SA_SHIRQ | SA_INTERRUPT, "synchronous serial manual irq", &ports[1]))
 			panic("Can't allocate sync serial manual irq");
 	}
 	*R_IRQ_MASK1_SET = IO_STATE(R_IRQ_MASK1_SET, ser3_data, set);	 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/usb-host.c linux-bk/arch/cris/drivers/usb-host.c
--- linux-2.4.19/arch/cris/drivers/usb-host.c	2002-02-25 19:37:52.000000000 +0000
+++ linux-bk/arch/cris/drivers/usb-host.c	2002-08-17 00:49:00.000000000 +0000
@@ -193,17 +193,17 @@
 static USB_EP_Desc_t TxIntrEPList[MAX_INTR_INTERVAL] __attribute__ ((aligned (4)));
 static USB_SB_Desc_t TxIntrSB_zout __attribute__ ((aligned (4)));
 
-static urb_t *URB_List[NBR_OF_EP_DESC];
+static struct urb *URB_List[NBR_OF_EP_DESC];
 static kmem_cache_t *usb_desc_cache;
 static struct usb_bus *etrax_usb_bus;
 
 #ifdef USB_DEBUG_DESC
-static void dump_urb (purb_t purb);
+static void dump_urb (struct urb *urb);
 #endif
 static void init_rx_buffers(void);
-static int etrax_rh_unlink_urb (urb_t *urb);
-static void etrax_rh_send_irq(urb_t *urb);
-static void etrax_rh_init_int_timer(urb_t *urb);
+static int etrax_rh_unlink_urb (struct urb *urb);
+static void etrax_rh_send_irq(struct urb *urb);
+static void etrax_rh_init_int_timer(struct urb *urb);
 static void etrax_rh_int_timer_do(unsigned long ptr);
 
 static void etrax_usb_setup_epid(int epid, char devnum, char endpoint,
@@ -214,13 +214,13 @@
 static void etrax_usb_free_epid(int epid);
 static void cleanup_sb(USB_SB_Desc_t *sb);
 
-static void etrax_usb_do_ctrl_hw_add(urb_t *urb, int epid, char maxlen);
-static void etrax_usb_do_bulk_hw_add(urb_t *urb, int epid, char maxlen);
+static void etrax_usb_do_ctrl_hw_add(struct urb *urb, int epid, char maxlen);
+static void etrax_usb_do_bulk_hw_add(struct urb *urb, int epid, char maxlen);
 
-static int etrax_usb_submit_ctrl_urb(urb_t *urb);
+static int etrax_usb_submit_ctrl_urb(struct urb *urb);
 
-static int etrax_usb_submit_urb(urb_t *urb);
-static int etrax_usb_unlink_urb(urb_t *urb);
+static int etrax_usb_submit_urb(struct urb *urb);
+static int etrax_usb_unlink_urb(struct urb *urb);
 static int etrax_usb_get_frame_number(struct usb_device *usb_dev);
 static int etrax_usb_allocate_dev(struct usb_device *usb_dev);
 static int etrax_usb_deallocate_dev(struct usb_device *usb_dev);
@@ -229,7 +229,7 @@
 static void etrax_usb_rx_interrupt(int irq, void *vhc, struct pt_regs *regs);
 static void etrax_usb_hc_intr_top_half(int irq, void *vhc, struct pt_regs *regs);
 
-static int etrax_rh_submit_urb (urb_t *urb);
+static int etrax_rh_submit_urb (struct urb *urb);
 
 static int etrax_usb_hc_init(void);
 static void etrax_usb_hc_cleanup(void);
@@ -244,24 +244,24 @@
 };
 
 #ifdef USB_DEBUG_DESC
-static void dump_urb(purb_t purb)
+static void dump_urb(struct urb *urb)
 {
-	printk("\nurb                   :0x%08X\n", purb);
-	printk("next                  :0x%08X\n", purb->next);
-	printk("dev                   :0x%08X\n", purb->dev);
-	printk("pipe                  :0x%08X\n", purb->pipe);
-	printk("status                :%d\n", purb->status);
-	printk("transfer_flags        :0x%08X\n", purb->transfer_flags);
-	printk("transfer_buffer       :0x%08X\n", purb->transfer_buffer);
-	printk("transfer_buffer_length:%d\n", purb->transfer_buffer_length);
-	printk("actual_length         :%d\n", purb->actual_length);
-	printk("setup_packet          :0x%08X\n", purb->setup_packet);
-	printk("start_frame           :%d\n", purb->start_frame);
-	printk("number_of_packets     :%d\n", purb->number_of_packets);
-	printk("interval              :%d\n", purb->interval);
-	printk("error_count           :%d\n", purb->error_count);
-	printk("context               :0x%08X\n", purb->context);
-	printk("complete              :0x%08X\n\n", purb->complete);
+	printk("\nurb                   :0x%08X\n", urb);
+	printk("next                  :0x%08X\n", urb->next);
+	printk("dev                   :0x%08X\n", urb->dev);
+	printk("pipe                  :0x%08X\n", urb->pipe);
+	printk("status                :%d\n", urb->status);
+	printk("transfer_flags        :0x%08X\n", urb->transfer_flags);
+	printk("transfer_buffer       :0x%08X\n", urb->transfer_buffer);
+	printk("transfer_buffer_length:%d\n", urb->transfer_buffer_length);
+	printk("actual_length         :%d\n", urb->actual_length);
+	printk("setup_packet          :0x%08X\n", urb->setup_packet);
+	printk("start_frame           :%d\n", urb->start_frame);
+	printk("number_of_packets     :%d\n", urb->number_of_packets);
+	printk("interval              :%d\n", urb->interval);
+	printk("error_count           :%d\n", urb->error_count);
+	printk("context               :0x%08X\n", urb->context);
+	printk("complete              :0x%08X\n\n", urb->complete);
 }
 
 static void dump_in_desc(USB_IN_Desc_t *in)
@@ -425,7 +425,7 @@
 }
 
 
-static int etrax_usb_unlink_intr_urb(urb_t *urb)
+static int etrax_usb_unlink_intr_urb(struct urb *urb)
 {
 	USB_EP_Desc_t *tmp_ep;
 	USB_EP_Desc_t *first_ep;
@@ -511,7 +511,7 @@
 	} while (tmp_ep != first_ep);
 }
 
-static int etrax_usb_submit_intr_urb(urb_t *urb)
+static int etrax_usb_submit_intr_urb(struct urb *urb)
 {
 	USB_EP_Desc_t *tmp_ep;
 	USB_EP_Desc_t *first_ep;
@@ -641,7 +641,7 @@
 
 static void handle_intr_transfer_attn(int epid, int status)
 {
-	urb_t *old_urb;
+	struct urb *old_urb;
 
 	DBFENTER;
 
@@ -694,7 +694,7 @@
 	DBFEXIT;
 }
 
-static int etrax_rh_unlink_urb (urb_t *urb)
+static int etrax_rh_unlink_urb (struct urb *urb)
 {
 	etrax_hc_t *hc;
 	
@@ -711,7 +711,7 @@
 	return 0;
 }
 
-static void etrax_rh_send_irq(urb_t *urb)
+static void etrax_rh_send_irq(struct urb *urb)
 {
 	__u16 data = 0;
 	etrax_hc_t *hc = urb->dev->bus->hcpriv;
@@ -744,7 +744,7 @@
 /*	DBFEXIT; */
 }
 
-static void etrax_rh_init_int_timer(urb_t *urb)
+static void etrax_rh_init_int_timer(struct urb *urb)
 {
 	etrax_hc_t *hc;
 	
@@ -763,12 +763,12 @@
 
 static void etrax_rh_int_timer_do(unsigned long ptr)
 {
-	urb_t *urb;
+	struct urb *urb;
 	etrax_hc_t *hc;
 	
 /*	DBFENTER; */
 	
-	urb = (urb_t*)ptr;
+	urb = (struct urb*)ptr;
 	hc = urb->dev->bus->hcpriv;
 	
 	if (hc->rh.send) {
@@ -910,7 +910,7 @@
 	return -1;
 }
 
-static int etrax_usb_submit_bulk_urb(urb_t *urb)
+static int etrax_usb_submit_bulk_urb(struct urb *urb)
 {
 	int epid;
 	char devnum;
@@ -919,7 +919,7 @@
 	char out_traffic;
 	char slow;
 
-	urb_t *tmp_urb;
+	struct urb *tmp_urb;
 	
 	unsigned long flags;
 	
@@ -969,7 +969,7 @@
 	return 0;
 }
 
-static void etrax_usb_do_bulk_hw_add(urb_t *urb, int epid, char maxlen)
+static void etrax_usb_do_bulk_hw_add(struct urb *urb, int epid, char maxlen)
 {
 	USB_SB_Desc_t *sb_desc_1;
 
@@ -1086,7 +1086,7 @@
 
 static void handle_bulk_transfer_attn(int epid, int status)
 {
-	urb_t *old_urb;
+	struct urb *old_urb;
 	etrax_urb_priv_t *hc_priv;
 	unsigned long flags;
 
@@ -1166,7 +1166,7 @@
 
 /* ---------------------------------------------------------------------------- */
 
-static int etrax_usb_submit_ctrl_urb(urb_t *urb)
+static int etrax_usb_submit_ctrl_urb(struct urb *urb)
 {
 	int epid;
 	char devnum;
@@ -1175,7 +1175,7 @@
 	char out_traffic;
 	char slow;
 
-	urb_t *tmp_urb;
+	struct urb *tmp_urb;
 	
 	unsigned long flags;
 	
@@ -1225,7 +1225,7 @@
 	return 0;
 }
 
-static void etrax_usb_do_ctrl_hw_add(urb_t *urb, int epid, char maxlen)
+static void etrax_usb_do_ctrl_hw_add(struct urb *urb, int epid, char maxlen)
 {
 	USB_SB_Desc_t *sb_desc_1;
 	USB_SB_Desc_t *sb_desc_2;
@@ -1364,7 +1364,7 @@
 	DBFEXIT;
 }
 
-static int etrax_usb_submit_urb(urb_t *urb)
+static int etrax_usb_submit_urb(struct urb *urb)
 {
 	etrax_hc_t *hc;
 	int rval = -EINVAL;
@@ -1411,7 +1411,7 @@
 	return rval;
 }
 
-static int etrax_usb_unlink_urb(urb_t *urb)
+static int etrax_usb_unlink_urb(struct urb *urb)
 {
 	etrax_hc_t *hc = urb->dev->bus->hcpriv;
 	int epid;
@@ -1455,8 +1455,8 @@
 	cli();
 	
 	for (epid = 0; epid < 32; epid++) {
-		urb_t *u = URB_List[epid];
-		urb_t *prev = NULL;
+		struct urb *u = URB_List[epid];
+		struct urb *prev = NULL;
 		int pos = 0;
 
 		for (; u; u = u->next) {
@@ -1557,7 +1557,7 @@
 static void etrax_usb_rx_interrupt(int irq, void *vhc, struct pt_regs *regs)
 {
 	int epid = 0;
-	urb_t *urb;
+	struct urb *urb;
 	etrax_urb_priv_t *urb_priv;
 		
 	*R_DMA_CH9_CLR_INTR = IO_STATE(R_DMA_CH9_CLR_INTR, clr_eop, do);
@@ -1655,7 +1655,7 @@
 
 static void handle_control_transfer_attn(int epid, int status)
 {
-	urb_t *old_urb;
+	struct urb *old_urb;
 	etrax_urb_priv_t *hc_priv;	
 
 	DBFENTER;
@@ -1981,12 +1981,12 @@
 	DBFEXIT;
 }
 
-static int etrax_rh_submit_urb(urb_t *urb)
+static int etrax_rh_submit_urb(struct urb *urb)
 {
 	struct usb_device *usb_dev = urb->dev;
 	etrax_hc_t *hc = usb_dev->bus->hcpriv;
 	unsigned int pipe = urb->pipe;
-	devrequest *cmd = (devrequest *) urb->setup_packet;
+	struct usb_ctrlrequest *cmd = (struct usb_ctrlrequest *) urb->setup_packet;
 	void *data = urb->transfer_buffer;
 	int leni = urb->transfer_buffer_length;
 	int len = 0;
@@ -2010,10 +2010,10 @@
 		return 0;
 	}
 
-	bmRType_bReq = cmd->requesttype | cmd->request << 8;
-	wValue = le16_to_cpu(cmd->value);
-	wIndex = le16_to_cpu(cmd->index);
-	wLength = le16_to_cpu(cmd->length);
+	bmRType_bReq = cmd->bRequestType | cmd->bRequest << 8;
+	wValue = le16_to_cpu(cmd->wValue);
+	wIndex = le16_to_cpu(cmd->wIndex);
+	wLength = le16_to_cpu(cmd->wLength);
 
 	dbg_rh("bmRType_bReq : 0x%04X (%d)", bmRType_bReq, bmRType_bReq);
 	dbg_rh("wValue       : 0x%04X (%d)", wValue, wValue);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/virtex.c linux-bk/arch/cris/drivers/virtex.c
--- linux-2.4.19/arch/cris/drivers/virtex.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/cris/drivers/virtex.c	2002-08-17 00:48:46.000000000 +0000
@@ -0,0 +1,405 @@
+/*!***************************************************************************
+*!
+*! FILE NAME  : vertex.c
+*!
+*! DESCRIPTION: Implements an interface towards virtex FPGA (mounted on one of our
+*!              evaluation boards) from userspace using ioctl()'s
+*!
+*!              The FPGA can be programmed by copying the bit-file to /dev/fpga.
+*!
+*!                cp fpga.bit > /dev/fpga
+*!
+*!                Kernel log should look like:
+*!                  69900 bytes written
+*!                  FPGA-configuration completed, no errors
+*!
+*!              Number of bytes written depends on the FPGA
+*!
+*!                From Xilinx data sheet:
+*!                XCV50    559,200 bits
+*!                XCV100   781,216 bits
+*!                XCV800 4,715,616 bits
+*!
+*!              Accepted file type is the design.bit generated by Alliance
+*!              Design Manager.
+*!              This software just sends the bitfile into the device without
+*!              checking device type etc.
+*!
+*!              Sync-header 0xff 0xff 0xff 0xff defines the start for the
+*!              byte stream, everything from that position is written to the FPGA.
+*!
+*!  
+*! Jul 19 2002  Stefan Lundberg    Initial version.
+*! $Log: virtex.c,v $
+*! Revision 1.1  2002/06/25 09:58:58  stefanl
+*! New FPGA driver for Platoon
+*!
+*!
+*! ---------------------------------------------------------------------------
+*!
+*! (C) Copyright 2002 Axis Communications AB, LUND, SWEDEN
+*!
+*!***************************************************************************/
+/* $Id: virtex.c,v 1.1 2002/06/25 09:58:58 stefanl Exp $ */
+/****************** INCLUDE FILES SECTION ***********************************/
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/major.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/config.h>
+
+#include <linux/hdreg.h>
+#include <linux/mm.h>
+
+#include <asm/etraxvirtex.h>
+
+#include <asm/system.h>
+#include <asm/svinto.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/delay.h>
+
+#include "virtex.h"
+
+/******************* VIRTEX DEFINITION SECTION **************************/
+
+#define VIRTEX_DEBUG(x)
+
+#define VIRTEX_MAJOR 246  /* EXPERIMENTAL */
+
+static const char virtex_name[] = "virtex";
+
+/****************** FUNCTION DEFINITION SECTION *************************/
+
+
+
+//
+// Read register interface for FPGA programming:
+//
+//   FPGA_DONE is connected to S1CD_N G28
+//   FPGA_INIT_N is connected to S1IO_N G27
+//
+
+// Write register interface for FPGA programming:
+//
+//  Bit:       15         14      13    12      9   8   7   0
+//        ____________________________________________________
+//       | fpga_write | program | cclk | reserved | cs | data |
+//       |____________|_________|______|__________|____|______|
+//
+
+
+// csp0 = cs_fpga1 = FPGA programming interface
+// csr0 = cs_fpga2 = register interface towards FPGA construction
+
+static volatile short *port_csp0_word_addr;
+static volatile short *port_csr0_word_addr;
+
+static volatile unsigned char open_count;
+static volatile unsigned char bytes_written;
+static volatile unsigned long bytes_written_cnt;
+static volatile unsigned char sync_found;
+static volatile unsigned char sync_count;
+static volatile unsigned char sync_ff_count;
+
+#define WRITE_FPGA_PROG_REG(data) *port_csp0_word_addr=(data)
+#define SET_PROGRAM_BIT(data) (data)|(1<<14)
+
+#define SET_WRITE_BIT(data) (data)|(1<<15)
+#define CLR_WRITE_BIT(data) (data)&(~(1<<15))
+
+#define SET_CS_BIT(data) (data)|(1<<8)
+#define CLR_CS_BIT(data) (data)&(~(1<<8))
+
+#define SET_CCLK_BIT(data) (data)|(1<<13)
+#define CLR_CCLK_BIT(data) (data)&(~(1<<13))
+
+// Bit in read port G (always inputs)
+#define READ_INIT  (*R_PORT_G_DATA)&(1<<27)
+#define READ_DONE  (*R_PORT_G_DATA)&(1<<28)
+
+
+void start_virtex_program(void)
+{
+  unsigned short reg_data=0;
+
+  printk("Start writing to FPGA\n");
+  reg_data = SET_CS_BIT(reg_data); // FPGA unselected
+
+  reg_data = SET_PROGRAM_BIT(reg_data);
+  WRITE_FPGA_PROG_REG(reg_data);
+
+  while(!READ_INIT); // Wait for init
+  
+  reg_data = SET_WRITE_BIT(reg_data);
+  WRITE_FPGA_PROG_REG(reg_data);
+
+  reg_data = CLR_CS_BIT(reg_data); // FPGA selected, CS is active low
+  WRITE_FPGA_PROG_REG(reg_data);
+  return;
+}
+
+// According to datasheet, bytes should be reversed, it is unknown to me why.
+unsigned char bit_reverse(unsigned char data) 
+{
+  unsigned char in=data;
+  unsigned short out=0;
+  unsigned int i=0;
+
+  for(i=0;i<8;i++) {
+    if(in&0x1) {
+      out|=0x1;
+    }
+    in=in>>1;
+    out=out<<1;
+  }
+
+  return(out>>1);
+  
+}
+
+void virtex_program(char* ptr,size_t count)
+{
+  int c;
+  char *p;
+  unsigned char data;  
+  unsigned short reg_data=0;
+//  short tmp_cnt;
+  
+  c=count;
+  p=ptr;
+
+  if(!sync_found) {
+    c=count;
+    p=ptr;
+    while(c--) {
+      data=(unsigned char)*p++;
+      sync_count++;
+
+      if(sync_count>=256) {
+        printk("Sync not found, aborting\n");
+        return;
+      }
+
+      if(data==0xff) {
+        sync_ff_count++;
+      } else {
+        sync_ff_count=0;
+      }
+      if(sync_ff_count==4) {
+        sync_found=1;
+        VIRTEX_DEBUG(printk("Sync found at offset %d\n",sync_count));
+        p--;p--;p--;p--;
+        c++;c++;c++;c++;
+        break;
+      }
+    }
+  }
+
+  if(sync_found) {
+    if(bytes_written==0) {
+      start_virtex_program();
+    }
+    bytes_written=1;
+  
+    reg_data = SET_PROGRAM_BIT(reg_data);
+    reg_data = SET_WRITE_BIT(reg_data);
+    reg_data = CLR_CS_BIT(reg_data);
+  
+//    tmp_cnt=0;
+    
+    printk("*");
+    while(c--) {
+      data=(unsigned char)*p++;
+      data=bit_reverse(data);
+
+/* debug
+      tmp_cnt++;
+      if(tmp_cnt<=32 || c<=32 ) {
+        printk("0x%x ",data); 
+      }
+      if(tmp_cnt==32 || c==0 ) {
+        printk("\n"); 
+      }
+*/
+      bytes_written_cnt++;
+      reg_data = CLR_CCLK_BIT(reg_data);
+      WRITE_FPGA_PROG_REG(reg_data|(data&0xff));
+      reg_data = SET_CCLK_BIT(reg_data);
+      WRITE_FPGA_PROG_REG(reg_data|(data&0xff));
+      reg_data = CLR_CCLK_BIT(reg_data);
+      WRITE_FPGA_PROG_REG(reg_data|(data&0xff));
+  
+    }
+  }
+   
+  return;
+}
+
+void stop_virtex_program(void)
+{
+  unsigned short reg_data=0;
+
+  reg_data = SET_PROGRAM_BIT(reg_data);
+  reg_data = SET_WRITE_BIT(reg_data);
+  reg_data = CLR_CCLK_BIT(reg_data);
+
+  reg_data = SET_CS_BIT(reg_data); // release CS
+  WRITE_FPGA_PROG_REG(reg_data);
+
+  reg_data = CLR_WRITE_BIT(reg_data); // release write, important to do!
+  WRITE_FPGA_PROG_REG(reg_data);
+  printk("%d bytes written\n",bytes_written_cnt);
+  if(READ_DONE) {
+    printk("FPGA-configuration completed, no errors\n");
+  } else {
+    printk("Error, FPGA-configuration failed\n");
+  }
+  return;
+}
+
+static int
+virtex_open(struct inode *inode, struct file *filp)
+{
+  port_csp0_word_addr = port_csp0_addr;
+  if(open_count>=1) {
+    printk("FPGA Device busy, aborting\n");
+    return(-EBUSY);
+  }
+  open_count++;
+  bytes_written=0;
+  sync_found=0;
+  sync_count=0;
+  sync_ff_count=0;
+  bytes_written_cnt=0;
+  return(0);
+}
+
+static int
+virtex_release(struct inode *inode, struct file *filp)
+{
+  open_count--;
+  if(bytes_written!=0)stop_virtex_program();
+  return 0;
+}
+
+// FPGA programming interface
+
+static ssize_t virtex_write(struct file * file, const char * buf, 
+                                 size_t count, loff_t *ppos)
+{
+  char *ptr;
+  VIRTEX_DEBUG(printk("Write FPGA count %d\n", count));
+  
+  ptr=kmalloc(count, GFP_KERNEL);
+  if(!ptr) {
+    printk("FPGA device, kernel malloc failed (%d) bytes\n",count);
+    return -EFAULT;
+  }
+  if(copy_from_user(ptr, buf, count)) {
+    printk("copy_from_user failed\n");
+    return -EFAULT;
+  }
+  
+  virtex_program(ptr,count);
+  
+  kfree(ptr);
+  return count;
+}
+
+/* Main device API. ioctl's to write or read to/from registers.
+ */
+
+int virtex_writereg(unsigned short theReg, unsigned short theValue)
+{
+  port_csr0_word_addr[theReg]=theValue;
+  return(0);
+}
+
+unsigned short virtex_readreg(unsigned short theReg)
+{
+  return(port_csr0_word_addr[theReg]);
+}
+
+
+static int
+virtex_ioctl(struct inode *inode, struct file *file,
+	  unsigned int cmd, unsigned long arg)
+{
+  if(_IOC_TYPE(cmd) != ETRAXVIRTEX_FPGA_IOCTYPE) {
+    return -EINVAL;
+  }
+  
+  switch (_IOC_NR(cmd)) {
+    case VIRTEX_FPGA_WRITEREG:
+      /* write to an FPGA register */
+      VIRTEX_DEBUG(printk("virtex wr %d %d\n", 
+               VIRTEX_FPGA_ARGREG(arg),
+               VIRTEX_FPGA_ARGVALUE(arg)));
+      
+      return virtex_writereg(VIRTEX_FPGA_ARGREG(arg),
+                             VIRTEX_FPGA_ARGVALUE(arg));
+    case VIRTEX_FPGA_READREG:
+    {
+      unsigned char val;
+      /* read from an FPGA register */
+      VIRTEX_DEBUG(printk("virtex rd %d ", 
+              VIRTEX_FPGA_ARGREG(arg)));
+      val = virtex_readreg(VIRTEX_FPGA_ARGREG(arg));
+      VIRTEX_DEBUG(printk("= %d\n", val));
+      return val;
+    }					    
+    default:
+      return -EINVAL;
+    }
+
+return 0;
+}
+
+static struct file_operations virtex_fops = {
+	owner:    THIS_MODULE,
+	ioctl:    virtex_ioctl,
+	open:     virtex_open,
+        write:    virtex_write,
+	release:  virtex_release,
+};
+
+static int __init
+virtex_init(void)
+{
+  int res;
+  
+  /* register char device */
+  res = register_chrdev(VIRTEX_MAJOR, virtex_name, &virtex_fops);
+  if(res < 0) {
+          printk(KERN_ERR "virtex: couldn't get a major number.\n");
+          return res;
+  }
+  
+  port_csr0_word_addr = (volatile unsigned short *) 
+                        ioremap((unsigned long)(MEM_CSR0_START |
+                                                MEM_NON_CACHEABLE), 16);
+     
+// see ~/platoon/rel2/platoon/os/linux/arch/cris/mm/init.c
+//              port_csp0_addr = (volatile unsigned long *)
+//                 ioremap((unsigned long)(MEM_CSP0_START |
+//                                         MEM_NON_CACHEABLE), 16);
+  
+  open_count=0;
+  
+  printk("VIRTEX(TM) FPGA driver v1.0, (c) 2002 Axis Communications AB\n");
+  
+  return 0;
+}
+
+/* this makes sure that virtex_init is called during boot */
+
+module_init(virtex_init);
+
+/****************** END OF FILE virtex.c ********************************/
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/virtex.h linux-bk/arch/cris/drivers/virtex.h
--- linux-2.4.19/arch/cris/drivers/virtex.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/cris/drivers/virtex.h	2002-08-17 00:49:09.000000000 +0000
@@ -0,0 +1,7 @@
+/* $Id: virtex.h,v 1.1 2002/06/25 09:58:58 stefanl Exp $ */
+
+int virtex_writereg(unsigned short theReg, unsigned short theValue);
+unsigned short virtex_readreg(unsigned short theReg);
+
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/kernel/Makefile linux-bk/arch/cris/kernel/Makefile
--- linux-2.4.19/arch/cris/kernel/Makefile	2001-11-09 21:58:02.000000000 +0000
+++ linux-bk/arch/cris/kernel/Makefile	2002-08-17 00:48:49.000000000 +0000
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.9 2001/10/22 13:10:21 pkj Exp $
+# $Id: Makefile,v 1.10 2002/05/27 15:41:40 johana Exp $
 #
 # Makefile for the linux kernel.
 #
@@ -25,6 +25,7 @@
 
 obj-$(CONFIG_MODULES)    += ksyms.o
 obj-$(CONFIG_ETRAX_KGDB) += kgdb.o
+obj-$(CONFIG_ETRAX_FAST_TIMER) += fasttimer.o
 
 # This dependency isn't caught by mkdep.  See entry.S.
 entry.o: entryoffsets.s
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/kernel/fasttimer.c linux-bk/arch/cris/kernel/fasttimer.c
--- linux-2.4.19/arch/cris/kernel/fasttimer.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/cris/kernel/fasttimer.c	2002-08-17 00:49:00.000000000 +0000
@@ -0,0 +1,974 @@
+/* $Id: fasttimer.c,v 1.4 2002/05/28 17:47:59 johana Exp $
+ * linux/arch/cris/kernel/fasttimer.c
+ *
+ * Fast timers for ETRAX100/ETRAX100LX
+ * This may be useful in other OS than Linux so use 2 space indentation...
+ *
+ * $Log: fasttimer.c,v $
+ * Revision 1.4  2002/05/28 17:47:59  johana
+ * Added del_fast_timer()
+ *
+ * Revision 1.3  2002/05/28 16:16:07  johana
+ * Handle empty fast_timer_list
+ *
+ * Revision 1.2  2002/05/27 15:38:42  johana
+ * Made it compile without warnings on Linux 2.4.
+ * (includes, wait_queue, PROC_FS and snprintf)
+ *
+ * Revision 1.1  2002/05/27 15:32:25  johana
+ * arch/etrax100/kernel/fasttimer.c v1.8 from the elinux tree.
+ *
+ * Revision 1.8  2001/11/27 13:50:40  pkj
+ * Disable interrupts while stopping the timer and while modifying the
+ * list of active timers in timer1_handler() as it may be interrupted
+ * by other interrupts (e.g., the serial interrupt) which may add fast
+ * timers.
+ *
+ * Revision 1.7  2001/11/22 11:50:32  pkj
+ * * Only store information about the last 16 timers.
+ * * proc_fasttimer_read() now uses an allocated buffer, since it
+ *   requires more space than just a page even for only writing the
+ *   last 16 timers. The buffer is only allocated on request, so
+ *   unless /proc/fasttimer is read, it is never allocated.
+ * * Renamed fast_timer_started to fast_timers_started to match
+ *   fast_timers_added and fast_timers_expired.
+ * * Some clean-up.
+ *
+ * Revision 1.6  2000/12/13 14:02:08  johana
+ * Removed volatile for fast_timer_list
+ *
+ * Revision 1.5  2000/12/13 13:55:35  johana
+ * Added DEBUG_LOG, added som cli() and cleanup
+ *
+ * Revision 1.4  2000/12/05 13:48:50  johana
+ * Added range check when writing proc file, modified timer int handling
+ *
+ * Revision 1.3  2000/11/23 10:10:20  johana
+ * More debug/logging possibilities.
+ * Moved GET_JIFFIES_USEC() to timex.h and time.c
+ *
+ * Revision 1.2  2000/11/01 13:41:04  johana
+ * Clean up and bugfixes.
+ * Created new do_gettimeofday_fast() that gets a timeval struct
+ * with time based on jiffies and *R_TIMER0_DATA, uses a table
+ * for fast conversion of timer value to microseconds.
+ * (Much faster the standard do_gettimeofday() and we don't really
+ * wan't to use the true time - we wan't the "uptime" so timers don't screw up
+ * when we change the time.
+ * TODO: Add efficient support for continuous timers as well.
+ *
+ * Revision 1.1  2000/10/26 15:49:16  johana
+ * Added fasttimer, highresolution timers.
+ *
+ * Copyright (C) 2000,2001 2002 Axis Communications AB, Lund, Sweden
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.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/config.h>
+#include <linux/version.h>
+
+#include <asm/svinto.h>
+#include <asm/fasttimer.h>
+#include <linux/proc_fs.h>
+
+
+#define DEBUG_LOG_INCLUDED
+#define FAST_TIMER_LOG
+//#define FAST_TIMER_TEST
+
+#define FAST_TIMER_SANITY_CHECKS
+
+#ifdef FAST_TIMER_SANITY_CHECKS
+#define SANITYCHECK(x) x
+static int sanity_failed = 0;
+#else
+#define SANITYCHECK(x)
+#endif
+
+#define D1(x)
+#define D2(x)
+#define DP(x)
+
+#define __INLINE__ inline
+
+static int fast_timer_running = 0;
+static int fast_timers_added = 0;
+static int fast_timers_started = 0;
+static int fast_timers_expired = 0;
+static int fast_timers_deleted = 0;
+static int fast_timer_is_init = 0;
+static int fast_timer_ints = 0;
+
+static struct fast_timer *fast_timer_list = NULL;
+
+#ifdef DEBUG_LOG_INCLUDED
+#define DEBUG_LOG_MAX 128
+static const char * debug_log_string[DEBUG_LOG_MAX];
+static unsigned long debug_log_value[DEBUG_LOG_MAX];
+static int debug_log_cnt = 0;
+static int debug_log_cnt_wrapped = 0;
+
+#define DEBUG_LOG(string, value) \
+{ \
+  unsigned long log_flags; \
+  save_flags(log_flags); \
+  cli(); \
+  debug_log_string[debug_log_cnt] = (string); \
+  debug_log_value[debug_log_cnt] = (unsigned long)(value); \
+  if (++debug_log_cnt >= DEBUG_LOG_MAX) \
+  { \
+    debug_log_cnt = debug_log_cnt % DEBUG_LOG_MAX; \
+    debug_log_cnt_wrapped = 1; \
+  } \
+  restore_flags(log_flags); \
+}
+#else
+#define DEBUG_LOG(string, value)
+#endif
+
+
+/* The frequencies for index = clkselx number in R_TIMER_CTRL */
+#define NUM_TIMER_FREQ 15
+#define MAX_USABLE_TIMER_FREQ 7
+#define MAX_DELAY_US  853333L
+const unsigned long timer_freq_100[NUM_TIMER_FREQ] =
+{
+  3,   /* 0 3333 - 853333 us */
+  6,   /* 1 1666 - 426666 us */
+  12,  /* 2  833 - 213333 us */
+  24,  /* 3  416 - 106666 us */
+  48,  /* 4  208 -  53333 us */
+  96,  /* 5  104 -  26666 us */
+  192, /* 6   52 -  13333 us */
+  384, /* 7   26 -   6666 us */
+  576,
+  1152,
+  2304,
+  4608,
+  9216,
+  18432,
+  62500,
+  /* 15 = cascade */
+};
+#define NUM_TIMER_STATS 16
+#ifdef FAST_TIMER_LOG
+struct fast_timer timer_added_log[NUM_TIMER_STATS];
+struct fast_timer timer_started_log[NUM_TIMER_STATS];
+struct fast_timer timer_expired_log[NUM_TIMER_STATS];
+#endif
+
+int timer_div_settings[NUM_TIMER_STATS];
+int timer_freq_settings[NUM_TIMER_STATS];
+int timer_delay_settings[NUM_TIMER_STATS];
+
+/* Not true gettimeofday, only checks the jiffies (uptime) + useconds */
+void __INLINE__ do_gettimeofday_fast(struct timeval *tv)
+{
+  unsigned long sec = jiffies;
+  unsigned long usec = GET_JIFFIES_USEC();
+
+  usec += (sec % HZ) * (1000000 / HZ);
+  sec = sec / HZ;
+
+  if (usec > 1000000)
+  {
+    usec -= 1000000;
+    sec++;
+  }
+  tv->tv_sec = sec;
+  tv->tv_usec = usec;
+}
+
+int __INLINE__ timeval_cmp(struct timeval *t0, struct timeval *t1)
+{
+  if (t0->tv_sec < t1->tv_sec)
+  {
+    return -1;
+  }
+  else if (t0->tv_sec > t1->tv_sec)
+  {
+    return 1;
+  }
+  if (t0->tv_usec < t1->tv_usec)
+  {
+    return -1;
+  }
+  else if (t0->tv_usec > t1->tv_usec)
+  {
+    return 1;
+  }
+  return 0;
+}
+
+void __INLINE__ start_timer1(unsigned long delay_us)
+{
+  int freq_index = 0; /* This is the lowest resolution */
+  unsigned long upper_limit = MAX_DELAY_US;
+
+  unsigned long div;
+  /* Start/Restart the timer to the new shorter value */
+  /* t = 1/freq = 1/19200 = 53us
+   * T=div*t,  div = T/t = delay_us*freq/1000000
+   */
+#if 1 /* Adaptive timer settings */
+  while (delay_us < upper_limit && freq_index < MAX_USABLE_TIMER_FREQ)
+  {
+    freq_index++;
+    upper_limit >>= 1; /* Divide by 2 using shift */
+  }
+  if (freq_index > 0)
+  {
+    freq_index--;
+  }
+#else
+  freq_index = 6;
+#endif
+  div = delay_us * timer_freq_100[freq_index]/10000;
+  if (div < 2)
+  {
+    /* Maybe increase timer freq? */
+    div = 2;
+  }
+  if (div > 255)
+  {
+    div = 0; /* This means 256, the max the timer takes */
+    /* If a longer timeout than the timer can handle is used,
+     * then we must restart it when it goes off.
+     */
+  }
+
+  timer_div_settings[fast_timers_started % NUM_TIMER_STATS] = div;
+  timer_freq_settings[fast_timers_started % NUM_TIMER_STATS] = freq_index;
+  timer_delay_settings[fast_timers_started % NUM_TIMER_STATS] = delay_us;
+
+  D1(printk("start_timer1 : %d us freq: %i div: %i\n",
+            delay_us, freq_index, div));
+  /* Clear timer1 irq */
+  *R_IRQ_MASK0_CLR = IO_STATE(R_IRQ_MASK0_CLR, timer1, clr);
+
+  /* Set timer values */
+  *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, div) |
+    IO_STATE(R_TIMER_CTRL, tm1, stop_ld) |
+    IO_FIELD(R_TIMER_CTRL, clksel1, freq_index ); /* 6=c19k2Hz */
+
+  /* Ack interrupt */
+  *R_TIMER_CTRL =  r_timer_ctrl_shadow |
+    IO_STATE(R_TIMER_CTRL, i1, clr);
+
+  /* Start timer */
+  *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_timers_started++;
+  fast_timer_running = 1;
+}
+
+/* In version 1.4 this function takes 27 - 50 us */
+void start_one_shot_timer(struct fast_timer *t,
+                          fast_timer_function_type *function,
+                          unsigned long data,
+                          unsigned long delay_us,
+                          const char *name)
+{
+  unsigned long flags;
+  struct fast_timer *tmp;
+
+  D1(printk("sft %s %d us\n", name, delay_us));
+
+  save_flags(flags);
+  cli();
+
+  do_gettimeofday_fast(&t->tv_set);
+  tmp = fast_timer_list;
+
+  SANITYCHECK({ /* Check so this is not in the list already... */
+    while (tmp != NULL)
+    {
+      if (tmp == t)
+      {
+        printk("timer name: %s data: 0x%08lX already in list!\n", name, data);
+        sanity_failed++;
+        return;
+      }
+      else
+      {
+        tmp = tmp->next;
+      }
+    }
+    tmp = fast_timer_list;
+  });
+
+  t->delay_us = delay_us;
+  t->function = function;
+  t->data = data;
+  t->name = name;
+
+  t->tv_expires.tv_usec = t->tv_set.tv_usec + delay_us % 1000000;
+  t->tv_expires.tv_sec  = t->tv_set.tv_sec  + delay_us / 1000000;
+  if (t->tv_expires.tv_usec > 1000000)
+  {
+    t->tv_expires.tv_usec -= 1000000;
+    t->tv_expires.tv_sec++;
+  }
+#ifdef FAST_TIMER_LOG
+  timer_added_log[fast_timers_added % NUM_TIMER_STATS] = *t;
+#endif
+  fast_timers_added++;
+
+  /* Check if this should timeout before anything else */
+  if (tmp == NULL || timeval_cmp(&t->tv_expires, &tmp->tv_expires) < 0)
+  {
+    /* Put first in list and modify the timer value */
+    t->prev = NULL;
+    t->next = fast_timer_list;
+    if (fast_timer_list)
+    {
+      fast_timer_list->prev = t;
+    }
+    fast_timer_list = t;
+#ifdef FAST_TIMER_LOG
+    timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t;
+#endif
+    start_timer1(delay_us);
+  } else {
+    /* Put in correct place in list */
+    while (tmp->next &&
+           timeval_cmp(&t->tv_expires, &tmp->next->tv_expires) > 0)
+    {
+      tmp = tmp->next;
+    }
+    /* Insert t after tmp */
+    t->prev = tmp;
+    t->next = tmp->next;
+    if (tmp->next)
+    {
+      tmp->next->prev = t;
+    }
+    tmp->next = t;
+  }
+
+  D2(printk("start_one_shot_timer: %d us done\n", delay_us));
+
+  restore_flags(flags);
+} /* start_one_shot_timer */
+
+static inline int fast_timer_pending (const struct fast_timer * t)
+{
+  return (t->next != NULL) || (t->prev != NULL) || (t == fast_timer_list);
+}
+
+static inline int detach_fast_timer (struct fast_timer *t)
+{
+  struct fast_timer *next, *prev;
+  if (!fast_timer_pending(t))
+    return 0;
+  next = t->next;
+  prev = t->prev;
+  if (next)
+    next->prev = prev;
+  if (prev)
+    prev->next = next;
+  else
+    fast_timer_list = next;
+  fast_timers_deleted++;
+  return 1;
+}
+
+int del_fast_timer(struct fast_timer * t)
+{
+  unsigned long flags;
+  int ret;
+  
+  save_flags(flags);
+  cli();
+  ret = detach_fast_timer(t);
+  t->next = t->prev = NULL;
+  restore_flags(flags);
+  return ret;
+} /* del_fast_timer */
+
+
+/* Interrupt routines or functions called in interrupt context */
+
+/* Timer 1 interrupt handler */
+
+static void
+timer1_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+  struct fast_timer *t;
+  unsigned long flags;
+
+  save_flags(flags);
+  cli();
+
+  /* Clear timer1 irq */
+  *R_IRQ_MASK0_CLR = IO_STATE(R_IRQ_MASK0_CLR, timer1, clr);
+
+  /* First stop timer, then ack interrupt */
+  /* Stop timer */
+  *R_TIMER_CTRL = r_timer_ctrl_shadow =
+    (r_timer_ctrl_shadow & ~IO_MASK(R_TIMER_CTRL, tm1)) |
+    IO_STATE(R_TIMER_CTRL, tm1, stop_ld);
+
+  /* Ack interrupt */
+  *R_TIMER_CTRL =  r_timer_ctrl_shadow | IO_STATE(R_TIMER_CTRL, i1, clr);
+
+  fast_timer_running = 0;
+  fast_timer_ints++;
+
+  restore_flags(flags);
+
+  t = fast_timer_list;
+  while (t)
+  {
+    struct timeval tv;
+
+    /* Has it really expired? */
+    do_gettimeofday_fast(&tv);
+    D1(printk("t: %is %06ius\n", tv.tv_sec, tv.tv_usec));
+
+    if (timeval_cmp(&t->tv_expires, &tv) <= 0)
+    {
+      /* Yes it has expired */
+#ifdef FAST_TIMER_LOG
+      timer_expired_log[fast_timers_expired % NUM_TIMER_STATS] = *t;
+#endif
+      fast_timers_expired++;
+
+      /* Remove this timer before call, since it may reuse the timer */
+      save_flags(flags);
+      cli();
+      if (t->prev)
+      {
+        t->prev->next = t->next;
+      }
+      else
+      {
+        fast_timer_list = t->next;
+      }
+      if (t->next)
+      {
+        t->next->prev = t->prev;
+      }
+      t->prev = NULL;
+      t->next = NULL;
+      restore_flags(flags);
+
+      if (t->function != NULL)
+      {
+        t->function(t->data);
+      }
+      else
+      {
+        DEBUG_LOG("!timer1 %i function==NULL!\n", fast_timer_ints);
+      }
+    }
+    else
+    {
+      /* Timer is to early, let's set it again using the normal routines */
+      D1(printk(".\n"));
+    }
+
+    save_flags(flags);
+    cli();
+    if ((t = fast_timer_list) != NULL)
+    {
+      /* Start next timer.. */
+      long us;
+      struct timeval tv;
+
+      do_gettimeofday_fast(&tv);
+      us = ((t->tv_expires.tv_sec - tv.tv_sec) * 1000000 +
+            t->tv_expires.tv_usec - tv.tv_usec);
+      if (us > 0)
+      {
+        if (!fast_timer_running)
+        {
+#ifdef FAST_TIMER_LOG
+          timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t;
+#endif
+          start_timer1(us);
+        }
+        restore_flags(flags);
+        break;
+      }
+      else
+      {
+        /* Timer already expired, let's handle it better late than never.
+         * The normal loop handles it
+         */
+        D1(printk("e! %d\n", us));
+      }
+    }
+    restore_flags(flags);
+  }
+
+  if (!t)
+  {
+    D1(printk("t1 stop!\n"));
+  }
+}
+
+static void wake_up_func(unsigned long data)
+{
+#ifdef DECLARE_WAITQUEUE
+  wait_queue_head_t  *sleep_wait_p = (wait_queue_head_t*)data;
+#else
+  struct wait_queue **sleep_wait_p = (struct wait_queue **)data;
+#endif
+  wake_up(sleep_wait_p);
+}
+
+
+/* Useful API */
+
+void schedule_usleep(unsigned long us)
+{
+  struct fast_timer t;
+#ifdef DECLARE_WAITQUEUE
+  wait_queue_head_t sleep_wait;
+  DECLARE_WAITQUEUE(wait, current);
+#else
+  struct wait_queue *sleep_wait = NULL;
+  struct wait_queue wait = { current, NULL };
+#endif
+
+  D1(printk("schedule_usleep(%d)\n", us));
+  add_wait_queue(&sleep_wait, &wait);
+  set_current_state(TASK_INTERRUPTIBLE);
+  start_one_shot_timer(&t, wake_up_func, (unsigned long)&sleep_wait, us,
+                       "usleep");
+  schedule();
+  set_current_state(TASK_RUNNING);
+  remove_wait_queue(&sleep_wait, &wait);
+  D1(printk("done schedule_usleep(%d)\n", us));
+}
+
+#ifdef CONFIG_PROC_FS
+static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+                       ,int *eof, void *data_unused
+#else
+                        ,int unused
+#endif
+                               );
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+static struct proc_dir_entry *fasttimer_proc_entry;
+#else
+static struct proc_dir_entry fasttimer_proc_entry =
+{
+  0, 9, "fasttimer",
+  S_IFREG | S_IRUGO, 1, 0, 0,
+  0, NULL /* ops -- default to array */,
+  &proc_fasttimer_read /* get_info */,
+};
+#endif
+#endif /* CONFIG_PROC_FS */
+
+#ifdef CONFIG_PROC_FS
+
+/* This value is very much based on testing */
+#define BIG_BUF_SIZE (500 + NUM_TIMER_STATS * 300)
+
+static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+                       ,int *eof, void *data_unused
+#else
+                        ,int unused
+#endif
+                               )
+{
+  unsigned long flags;
+  int i = 0;
+  int num_to_show;
+  struct timeval tv;
+  struct fast_timer *t, *nextt;
+  static char *bigbuf = NULL;
+  static unsigned long used;
+
+  if (!bigbuf && !(bigbuf = vmalloc(BIG_BUF_SIZE)))
+  {
+    used = 0;
+    bigbuf[0] = '\0';
+    return 0;
+  }
+
+  if (!offset || !used)
+  {
+    do_gettimeofday_fast(&tv);
+
+    used = 0;
+    used += sprintf(bigbuf + used, "Fast timers added:     %i\n",
+                    fast_timers_added);
+    used += sprintf(bigbuf + used, "Fast timers started:   %i\n",
+                    fast_timers_started);
+    used += sprintf(bigbuf + used, "Fast timer interrupts: %i\n",
+                    fast_timer_ints);
+    used += sprintf(bigbuf + used, "Fast timers expired:   %i\n",
+                    fast_timers_expired);
+    used += sprintf(bigbuf + used, "Fast timers deleted:   %i\n",
+                    fast_timers_deleted);
+    used += sprintf(bigbuf + used, "Fast timer running:    %s\n",
+                    fast_timer_running ? "yes" : "no");
+    used += sprintf(bigbuf + used, "Current time:          %lu.%06lu\n",
+                    (unsigned long)tv.tv_sec,
+                    (unsigned long)tv.tv_usec);
+#ifdef FAST_TIMER_SANITY_CHECKS
+    used += sprintf(bigbuf + used, "Sanity failed:         %i\n",
+                    sanity_failed);
+#endif
+    used += sprintf(bigbuf + used, "\n");
+
+#ifdef DEBUG_LOG_INCLUDED
+    {
+      int end_i = debug_log_cnt;
+      i = 0;
+
+      if (debug_log_cnt_wrapped)
+      {
+        i = debug_log_cnt;
+      }
+
+      while ((i != end_i || (debug_log_cnt_wrapped && !used)) &&
+             used+100 < BIG_BUF_SIZE)
+      {
+        used += sprintf(bigbuf + used, debug_log_string[i],
+                        debug_log_value[i]);
+        i = (i+1) % DEBUG_LOG_MAX;
+      }
+    }
+    used += sprintf(bigbuf + used, "\n");
+#endif
+
+    num_to_show = (fast_timers_started < NUM_TIMER_STATS ? fast_timers_started:
+                   NUM_TIMER_STATS);
+    used += sprintf(bigbuf + used, "Timers started: %i\n", fast_timers_started);
+    for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE) ; i++)
+    {
+      int cur = (fast_timers_started - i - 1) % NUM_TIMER_STATS;
+
+#if 1 //ndef FAST_TIMER_LOG
+      used += sprintf(bigbuf + used, "div: %i freq: %i delay: %i"
+                      "\n",
+                      timer_div_settings[cur],
+                      timer_freq_settings[cur],
+                      timer_delay_settings[cur]
+                      );
+#endif
+#ifdef FAST_TIMER_LOG
+      t = &timer_started_log[cur];
+      used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
+                      "d: %6li us data: 0x%08lX"
+                      "\n",
+                      t->name,
+                      (unsigned long)t->tv_set.tv_sec,
+                      (unsigned long)t->tv_set.tv_usec,
+                      (unsigned long)t->tv_expires.tv_sec,
+                      (unsigned long)t->tv_expires.tv_usec,
+                      t->delay_us,
+                      t->data
+                      );
+#endif
+    }
+    used += sprintf(bigbuf + used, "\n");
+
+#ifdef FAST_TIMER_LOG
+    num_to_show = (fast_timers_added < NUM_TIMER_STATS ? fast_timers_added:
+                   NUM_TIMER_STATS);
+    used += sprintf(bigbuf + used, "Timers added: %i\n", fast_timers_added);
+    for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE); i++)
+    {
+      t = &timer_added_log[(fast_timers_added - i - 1) % NUM_TIMER_STATS];
+      used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
+                      "d: %6li us data: 0x%08lX"
+                      "\n",
+                      t->name,
+                      (unsigned long)t->tv_set.tv_sec,
+                      (unsigned long)t->tv_set.tv_usec,
+                      (unsigned long)t->tv_expires.tv_sec,
+                      (unsigned long)t->tv_expires.tv_usec,
+                      t->delay_us,
+                      t->data
+                      );
+    }
+    used += sprintf(bigbuf + used, "\n");
+
+    num_to_show = (fast_timers_expired < NUM_TIMER_STATS ? fast_timers_expired:
+                   NUM_TIMER_STATS);
+    used += sprintf(bigbuf + used, "Timers expired: %i\n", fast_timers_expired);
+    for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE); i++)
+    {
+      t = &timer_expired_log[(fast_timers_expired - i - 1) % NUM_TIMER_STATS];
+      used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
+                      "d: %6li us data: 0x%08lX"
+                      "\n",
+                      t->name,
+                      (unsigned long)t->tv_set.tv_sec,
+                      (unsigned long)t->tv_set.tv_usec,
+                      (unsigned long)t->tv_expires.tv_sec,
+                      (unsigned long)t->tv_expires.tv_usec,
+                      t->delay_us,
+                      t->data
+                      );
+    }
+    used += sprintf(bigbuf + used, "\n");
+#endif
+
+    used += sprintf(bigbuf + used, "Active timers:\n");
+    save_flags(flags);
+    cli();
+    t = fast_timer_list;
+    while (t != NULL && (used+100 < BIG_BUF_SIZE))
+    {
+      nextt = t->next;
+      restore_flags(flags);
+      used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
+                      "d: %6li us data: 0x%08lX"
+/*                      " func: 0x%08lX" */
+                      "\n",
+                      t->name,
+                      (unsigned long)t->tv_set.tv_sec,
+                      (unsigned long)t->tv_set.tv_usec,
+                      (unsigned long)t->tv_expires.tv_sec,
+                      (unsigned long)t->tv_expires.tv_usec,
+                      t->delay_us,
+                      t->data
+/*                      , t->function */
+                      );
+      cli();
+      if (t->next != nextt)
+      {
+        printk("timer removed!\n");
+      }
+      t = nextt;
+    }
+    restore_flags(flags);
+  }
+
+  if (used - offset < len)
+  {
+    len = used - offset;
+  }
+
+  memcpy(buf, bigbuf + offset, len);
+  *start = buf;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+  *eof = 1;
+#endif
+
+  return len;
+}
+#endif /* PROC_FS */
+
+#ifdef FAST_TIMER_TEST
+static volatile unsigned long i = 0;
+static volatile int num_test_timeout = 0;
+static struct fast_timer tr[10];
+static int exp_num[10];
+
+static struct timeval tv_exp[100];
+
+static void test_timeout(unsigned long data)
+{
+  do_gettimeofday_fast(&tv_exp[data]);
+  exp_num[data] = num_test_timeout;
+
+  num_test_timeout++;
+}
+
+static void test_timeout1(unsigned long data)
+{
+  do_gettimeofday_fast(&tv_exp[data]);
+  exp_num[data] = num_test_timeout;
+  if (data < 7)
+  {
+    start_one_shot_timer(&tr[i], test_timeout1, i, 1000, "timeout1");
+    i++;
+  }
+  num_test_timeout++;
+}
+
+DP(
+static char buf0[2000];
+static char buf1[2000];
+static char buf2[2000];
+static char buf3[2000];
+static char buf4[2000];
+);
+
+static char buf5[6000];
+static int j_u[1000];
+
+static void fast_timer_test(void)
+{
+  int prev_num;
+  int j;
+
+  struct timeval tv, tv0, tv1, tv2;
+
+  printk("fast_timer_test() start\n");
+  do_gettimeofday_fast(&tv);
+
+  for (j = 0; j < 1000; j++)
+  {
+    j_u[j] = GET_JIFFIES_USEC();
+  }
+  for (j = 0; j < 100; j++)
+  {
+    do_gettimeofday_fast(&tv_exp[j]);
+  }
+  printk("fast_timer_test() %is %06i\n", tv.tv_sec, tv.tv_usec);
+
+  for (j = 0; j < 1000; j++)
+  {
+    printk("%i %i %i %i %i\n",j_u[j], j_u[j+1], j_u[j+2], j_u[j+3], j_u[j+4]);
+    j += 4;
+  }
+  for (j = 0; j < 100; j++)
+  {
+    printk("%i.%i %i.%i %i.%i %i.%i %i.%i\n",
+           tv_exp[j].tv_sec,tv_exp[j].tv_usec,
+           tv_exp[j+1].tv_sec,tv_exp[j+1].tv_usec,
+           tv_exp[j+2].tv_sec,tv_exp[j+2].tv_usec,
+           tv_exp[j+3].tv_sec,tv_exp[j+3].tv_usec,
+           tv_exp[j+4].tv_sec,tv_exp[j+4].tv_usec);
+    j += 4;
+  }
+  do_gettimeofday_fast(&tv0);
+  start_one_shot_timer(&tr[i], test_timeout, i, 50000, "test0");
+  DP(proc_fasttimer_read(buf0, NULL, 0, 0, 0));
+  i++;
+  start_one_shot_timer(&tr[i], test_timeout, i, 70000, "test1");
+  DP(proc_fasttimer_read(buf1, NULL, 0, 0, 0));
+  i++;
+  start_one_shot_timer(&tr[i], test_timeout, i, 40000, "test2");
+  DP(proc_fasttimer_read(buf2, NULL, 0, 0, 0));
+  i++;
+  start_one_shot_timer(&tr[i], test_timeout, i, 60000, "test3");
+  DP(proc_fasttimer_read(buf3, NULL, 0, 0, 0));
+  i++;
+  start_one_shot_timer(&tr[i], test_timeout1, i, 55000, "test4xx");
+  DP(proc_fasttimer_read(buf4, NULL, 0, 0, 0));
+  i++;
+  do_gettimeofday_fast(&tv1);
+
+  proc_fasttimer_read(buf5, NULL, 0, 0, 0);
+
+  prev_num = num_test_timeout;
+  while (num_test_timeout < i)
+  {
+    if (num_test_timeout != prev_num)
+    {
+      prev_num = num_test_timeout;
+    }
+  }
+  do_gettimeofday_fast(&tv2);
+  printk("Timers started    %is %06i\n", tv0.tv_sec, tv0.tv_usec);
+  printk("Timers started at %is %06i\n", tv1.tv_sec, tv1.tv_usec);
+  printk("Timers done       %is %06i\n", tv2.tv_sec, tv2.tv_usec);
+  DP(printk("buf0:\n");
+     printk(buf0);
+     printk("buf1:\n");
+     printk(buf1);
+     printk("buf2:\n");
+     printk(buf2);
+     printk("buf3:\n");
+     printk(buf3);
+     printk("buf4:\n");
+     printk(buf4);
+  );
+  printk("buf5:\n");
+  printk(buf5);
+
+  printk("timers set:\n");
+  for(j = 0; j<i; j++)
+  {
+    struct fast_timer *t = &tr[j];
+    printk("%-10s set: %6is %06ius exp: %6is %06ius "
+           "data: 0x%08X func: 0x%08X\n",
+           t->name,
+           t->tv_set.tv_sec,
+           t->tv_set.tv_usec,
+           t->tv_expires.tv_sec,
+           t->tv_expires.tv_usec,
+           t->data,
+           t->function
+           );
+
+    printk("           del: %6ius     did exp: %6is %06ius as #%i error: %6li\n",
+           t->delay_us,
+           tv_exp[j].tv_sec,
+           tv_exp[j].tv_usec,
+           exp_num[j],
+           (tv_exp[j].tv_sec - t->tv_expires.tv_sec)*1000000 + tv_exp[j].tv_usec - t->tv_expires.tv_usec);
+  }
+  proc_fasttimer_read(buf5, NULL, 0, 0, 0);
+  printk("buf5 after all done:\n");
+  printk(buf5);
+  printk("fast_timer_test() done\n");
+}
+#endif
+
+
+void fast_timer_init(void)
+{
+  /* For some reason, request_irq() hangs when called froom time_init() */
+  if (!fast_timer_is_init)
+  {
+#if 0 && defined(FAST_TIMER_TEST)
+    int i;
+#endif
+
+    printk("fast_timer_init()\n");
+
+#if 0 && defined(FAST_TIMER_TEST)
+    for (i = 0; i <= TIMER0_DIV; i++)
+    {
+      /* We must be careful not to get overflow... */
+      printk("%3i %6u\n", i, timer0_value_us[i]);
+    }
+#endif
+#ifdef CONFIG_PROC_FS
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+   if ((fasttimer_proc_entry = create_proc_entry( "fasttimer", 0, 0 )))
+     fasttimer_proc_entry->read_proc = proc_fasttimer_read;
+#else
+    proc_register_dynamic(&proc_root, &fasttimer_proc_entry);
+#endif
+#endif /* PROC_FS */
+    if(request_irq(TIMER1_IRQ_NBR, timer1_handler, SA_SHIRQ,
+                   "fast timer int", NULL))
+    {
+      printk("err: timer1 irq\n");
+    }
+    fast_timer_is_init = 1;
+#ifdef FAST_TIMER_TEST
+    printk("do test\n");
+    fast_timer_test();
+#endif
+  }
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/kernel/kgdb.c linux-bk/arch/cris/kernel/kgdb.c
--- linux-2.4.19/arch/cris/kernel/kgdb.c	2001-11-09 21:58:02.000000000 +0000
+++ linux-bk/arch/cris/kernel/kgdb.c	2002-08-17 00:49:13.000000000 +0000
@@ -18,6 +18,9 @@
 *! Jul 21 1999  Bjorn Wesen     eLinux port
 *!
 *! $Log: kgdb.c,v $
+*! Revision 1.7  2002/07/12 09:14:56  bjornw
+*! Corrected typo
+*!
 *! Revision 1.6  2001/10/09 13:10:03  matsfg
 *! Added $ on registers and removed some underscores
 *!
@@ -55,7 +58,7 @@
 *!
 *!---------------------------------------------------------------------------
 *!
-*! $Id: kgdb.c,v 1.6 2001/10/09 13:10:03 matsfg Exp $
+*! $Id: kgdb.c,v 1.7 2002/07/12 09:14:56 bjornw Exp $
 *!
 *! (C) Copyright 1999, Axis Communications AB, LUND, SWEDEN
 *!
@@ -1064,7 +1067,7 @@
 					int regno = gdb_cris_strtol (&remcomInBuffer[1], &suffix, 16);
 					int status;
 #ifdef PROCESS_SUPPORT
-					if (current_thread_g =! executing_task)
+					if (current_thread_g != executing_task)
 						status = write_stack_register (current_thread_g, regno, suffix+1);
 					else
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/kernel/setup.c linux-bk/arch/cris/kernel/setup.c
--- linux-2.4.19/arch/cris/kernel/setup.c	2002-02-25 19:37:52.000000000 +0000
+++ linux-bk/arch/cris/kernel/setup.c	2002-08-17 00:49:12.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.24 2001/12/07 17:03:19 bjornw Exp $
+/* $Id: setup.c,v 1.26 2002/06/04 07:57:56 jonashg Exp $
  *
  *  linux/arch/cris/kernel/setup.c
  *
@@ -169,20 +169,18 @@
 
 	*cmdline_p = command_line;
 
-	if (romfs_in_flash) {
-		strncpy(command_line, "root=", COMMAND_LINE_SIZE);
-		strncpy(command_line+5, CONFIG_ETRAX_ROOT_DEVICE,
+	strncpy(command_line, "root=", COMMAND_LINE_SIZE);
+	strncpy(command_line+5, CONFIG_ETRAX_ROOT_DEVICE,
 			COMMAND_LINE_SIZE-5);
 
-		/* Save command line copy for /proc/cmdline */
-
-		memcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
-		saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
-	}
+	/* Save command line copy for /proc/cmdline */
+	
+	memcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
+	saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
 
 	/* give credit for the CRIS port */
 
-	printk("Linux/CRIS port on ETRAX 100LX (c) 2001 Axis Communications AB\n");
+	printk("Linux/CRIS port on ETRAX 100LX (c) 2001, 2002 Axis Communications AB\n");
 
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/kernel/traps.c linux-bk/arch/cris/kernel/traps.c
--- linux-2.4.19/arch/cris/kernel/traps.c	2002-02-25 19:37:52.000000000 +0000
+++ linux-bk/arch/cris/kernel/traps.c	2002-08-17 00:49:12.000000000 +0000
@@ -230,8 +230,12 @@
 #endif	
 }
 
-/* This is normally the 'Oops' routine */
+void dump_stack(void)
+{
+	show_stack(NULL);
+}
 
+/* This is normally the 'Oops' routine */
 void 
 die_if_kernel(const char * str, struct pt_regs * regs, long err)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/lib/dram_init.S linux-bk/arch/cris/lib/dram_init.S
--- linux-2.4.19/arch/cris/lib/dram_init.S	2001-10-08 18:43:54.000000000 +0000
+++ linux-bk/arch/cris/lib/dram_init.S	2002-08-17 00:49:00.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: dram_init.S,v 1.10 2001/10/04 12:00:21 martinnn Exp $
+/* $Id: dram_init.S,v 1.12 2002/08/09 11:37:37 orjanf Exp $
  * 
  * DRAM/SDRAM initialization - alter with care
  * This file is intended to be included from other assembler files
@@ -11,6 +11,12 @@
  * Authors:  Mikael Starvik (starvik@axis.com)	
  * 
  * $Log: dram_init.S,v $
+ * Revision 1.12  2002/08/09 11:37:37  orjanf
+ * Added double initialization work-around for Samsung SDRAMs.
+ *
+ * Revision 1.11  2002/06/04 11:43:21  starvik
+ * Check if mrs_data is specified in kernelconfig (necessary for MCM)
+ *
  * Revision 1.10  2001/10/04 12:00:21  martinnn
  * Added missing underscores.
  *
@@ -70,7 +76,11 @@
 
 	move.d   CONFIG_ETRAX_DEF_R_DRAM_TIMING, $r0
 	move.d   $r0, [R_DRAM_TIMING]
-#else	
+#else
+	;; Samsung SDRAMs seem to require to be initialized twice to work properly.
+	moveq    2, $r6	
+_sdram_init:
+	
 	; Refer to ETRAX 100LX Designers Reference for a description of SDRAM initialization
 	
 	; Bank configuration
@@ -82,6 +92,12 @@
 	; CAS latency = 3 && bus_width = 32 => 0x60
 	; CAS latency = 2 && bus_width = 16 => 0x20
 	; CAS latency = 3 && bus_width = 16 => 0x30
+
+	; Check if value is already supplied in kernel config
+	move.d   CONFIG_ETRAX_DEF_R_SDRAM_TIMING, $r2
+	and.d    0x00ff0000, $r2
+	bne	 _set_timing
+	lsrq     16, $r2
 	
 	move.d   0x40, $r2       ; Assume 32 bits and CAS latency = 2
 	move.d   CONFIG_ETRAX_DEF_R_SDRAM_TIMING, $r1
@@ -142,6 +158,9 @@
 	bne      1b
 	nop
 	move.d   $r5, [R_SDRAM_TIMING]
+	subq     1, $r6
+	bne      _sdram_init
+	nop
 	ba       _sdram_commands_end
 	nop
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/lib/hw_settings.S linux-bk/arch/cris/lib/hw_settings.S
--- linux-2.4.19/arch/cris/lib/hw_settings.S	2001-07-04 18:50:39.000000000 +0000
+++ linux-bk/arch/cris/lib/hw_settings.S	2002-08-17 00:49:05.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * $Id: hw_settings.S,v 1.3 2001/04/21 17:02:46 bjornw Exp $
+ * $Id: hw_settings.S,v 1.4 2002/07/04 16:58:56 pkj Exp $
  * 
  * This table is used by some tools to extract hardware parameters.
  * The table should be included in the kernel and the decompressor.
@@ -16,8 +16,8 @@
 		(CONFIG_ETRAX_DEF_R_PORT_PB_DIR << 8) | \
 		(CONFIG_ETRAX_DEF_R_PORT_PB_DATA))
 	
-	.ascii "HW_PARAM_MAGIC" ; Magic number
-	.dword 0xc0004000	; Kernel start address
+	.ascii "HW_PARAM_MAGIC"					; Magic number
+	.dword CONFIG_ETRAX_DRAM_VIRTUAL_BASE | 0x80004000	; Kernel start address
 
 	; Debug port
 #ifdef CONFIG_ETRAX_DEBUG_PORT0
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/mm/fault.c linux-bk/arch/cris/mm/fault.c
--- linux-2.4.19/arch/cris/mm/fault.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/cris/mm/fault.c	2002-08-17 00:49:00.000000000 +0000
@@ -6,6 +6,9 @@
  *  Authors:  Bjorn Wesen 
  * 
  *  $Log: fault.c,v $
+ *  Revision 1.21  2002/05/28 14:24:56  bjornw
+ *  Corrected typo
+ *
  *  Revision 1.20  2001/11/22 13:34:06  bjornw
  *  * Bug workaround (LX TR89): force a rerun of the whole of an interrupted
  *    unaligned write, because the second half of the write will be corrupted
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/boot/compressed/misc.c linux-bk/arch/i386/boot/compressed/misc.c
--- linux-2.4.19/arch/i386/boot/compressed/misc.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/boot/compressed/misc.c	2002-08-17 00:49:10.000000000 +0000
@@ -9,6 +9,8 @@
  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
  */
 
+#define STANDALONE
+
 #include <linux/linkage.h>
 #include <linux/vmalloc.h>
 #include <linux/tty.h>
@@ -124,10 +126,6 @@
 static int vidport;
 static int lines, cols;
 
-#ifdef CONFIG_MULTIQUAD
-static void * const xquad_portio = NULL;
-#endif
-
 #include "../../../../lib/inflate.c"
 
 static void *malloc(int size)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/config.in linux-bk/arch/i386/config.in
--- linux-2.4.19/arch/i386/config.in	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/config.in	2002-08-17 00:49:00.000000000 +0000
@@ -5,7 +5,6 @@
 mainmenu_name "Linux Kernel Configuration"
 
 define_bool CONFIG_X86 y
-define_bool CONFIG_ISA y
 define_bool CONFIG_SBUS n
 
 define_bool CONFIG_UID16 y
@@ -54,6 +53,7 @@
    define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
    define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
    define_bool CONFIG_X86_PPRO_FENCE y
+   define_bool CONFIG_X86_F00F_WORKS_OK n
 else
    define_bool CONFIG_X86_WP_WORKS_OK y
    define_bool CONFIG_X86_INVLPG y
@@ -69,12 +69,14 @@
    define_bool CONFIG_X86_USE_STRING_486 y
    define_bool CONFIG_X86_ALIGNMENT_16 y
    define_bool CONFIG_X86_PPRO_FENCE y
+   define_bool CONFIG_X86_F00F_WORKS_OK n
 fi
 if [ "$CONFIG_M586" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
    define_bool CONFIG_X86_USE_STRING_486 y
    define_bool CONFIG_X86_ALIGNMENT_16 y
    define_bool CONFIG_X86_PPRO_FENCE y
+   define_bool CONFIG_X86_F00F_WORKS_OK n
 fi
 if [ "$CONFIG_M586TSC" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
@@ -82,6 +84,7 @@
    define_bool CONFIG_X86_ALIGNMENT_16 y
    define_bool CONFIG_X86_TSC y
    define_bool CONFIG_X86_PPRO_FENCE y
+   define_bool CONFIG_X86_F00F_WORKS_OK n
 fi
 if [ "$CONFIG_M586MMX" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
@@ -90,6 +93,7 @@
    define_bool CONFIG_X86_TSC y
    define_bool CONFIG_X86_GOOD_APIC y
    define_bool CONFIG_X86_PPRO_FENCE y
+   define_bool CONFIG_X86_F00F_WORKS_OK n
 fi
 if [ "$CONFIG_M686" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
@@ -98,6 +102,7 @@
    define_bool CONFIG_X86_PGE y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
    define_bool CONFIG_X86_PPRO_FENCE y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 if [ "$CONFIG_MPENTIUMIII" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
@@ -105,6 +110,7 @@
    define_bool CONFIG_X86_GOOD_APIC y
    define_bool CONFIG_X86_PGE y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 if [ "$CONFIG_MPENTIUM4" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 7
@@ -112,6 +118,7 @@
    define_bool CONFIG_X86_GOOD_APIC y
    define_bool CONFIG_X86_PGE y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 if [ "$CONFIG_MK6" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
@@ -126,11 +133,13 @@
    define_bool CONFIG_X86_USE_3DNOW y
    define_bool CONFIG_X86_PGE y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 if [ "$CONFIG_MELAN" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 4
    define_bool CONFIG_X86_USE_STRING_486 y
    define_bool CONFIG_X86_ALIGNMENT_16 y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 if [ "$CONFIG_MCYRIXIII" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
@@ -142,12 +151,14 @@
 if [ "$CONFIG_MCRUSOE" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
    define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 if [ "$CONFIG_MWINCHIPC6" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
    define_bool CONFIG_X86_ALIGNMENT_16 y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
    define_bool CONFIG_X86_OOSTORE y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 if [ "$CONFIG_MWINCHIP2" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
@@ -155,6 +166,7 @@
    define_bool CONFIG_X86_TSC y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
    define_bool CONFIG_X86_OOSTORE y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 if [ "$CONFIG_MWINCHIP3D" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
@@ -162,6 +174,7 @@
    define_bool CONFIG_X86_TSC y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
    define_bool CONFIG_X86_OOSTORE y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 
 bool 'Machine Check Exception' CONFIG_X86_MCE
@@ -177,14 +190,19 @@
 	"off    CONFIG_NOHIGHMEM \
 	 4GB    CONFIG_HIGHMEM4G \
 	 64GB   CONFIG_HIGHMEM64G" off
-if [ "$CONFIG_HIGHMEM4G" = "y" ]; then
+if [ "$CONFIG_HIGHMEM4G" = "y" -o "$CONFIG_HIGHMEM64G" = "y" ]; then
    define_bool CONFIG_HIGHMEM y
+else
+   define_bool CONFIG_HIGHMEM n
 fi
 if [ "$CONFIG_HIGHMEM64G" = "y" ]; then
-   define_bool CONFIG_HIGHMEM y
    define_bool CONFIG_X86_PAE y
 fi
 
+if [ "$CONFIG_HIGHMEM" = "y" ]; then
+   bool 'HIGHMEM I/O support' CONFIG_HIGHIO
+fi
+
 bool 'Math emulation' CONFIG_MATH_EMULATION
 bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR
 bool 'Symmetric multi-processing support' CONFIG_SMP
@@ -218,6 +236,7 @@
    define_bool CONFIG_X86_VISWS_APIC y
    define_bool CONFIG_X86_LOCAL_APIC y
    define_bool CONFIG_PCI y
+   define_bool CONFIG_ISA n
 else
    if [ "$CONFIG_SMP" = "y" ]; then
       define_bool CONFIG_X86_IO_APIC y
@@ -236,6 +255,7 @@
          define_bool CONFIG_PCI_DIRECT y
       fi
    fi
+   bool 'ISA bus support' CONFIG_ISA
 fi
 
 source drivers/pci/Config.in
@@ -366,14 +386,16 @@
 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
+if [ "$CONFIG_ISA" = "y" ]; then
+    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
 fi
-endmenu
 
 #
 # input before char - char/joystick depends on it. As does USB.
@@ -417,6 +439,7 @@
 
 bool 'Kernel debugging' CONFIG_DEBUG_KERNEL
 if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then
+   bool '  Check for stack overflows' CONFIG_DEBUG_STACKOVERFLOW
    bool '  Debug high memory support' CONFIG_DEBUG_HIGHMEM
    bool '  Debug memory allocations' CONFIG_DEBUG_SLAB
    bool '  Memory mapped I/O debugging' CONFIG_DEBUG_IOVIRT
@@ -426,3 +449,5 @@
 fi
 
 endmenu
+
+source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/apic.c linux-bk/arch/i386/kernel/apic.c
--- linux-2.4.19/arch/i386/kernel/apic.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/kernel/apic.c	2002-08-17 00:49:07.000000000 +0000
@@ -1050,7 +1050,7 @@
 /*
  * Local APIC timer interrupt. This is the most natural way for doing
  * local interrupts, but local timer interrupts can be emulated by
- * broadcast interrupts too. [in case the hw doesnt support APIC timers]
+ * broadcast interrupts too. [in case the hw doesn't support APIC timers]
  *
  * [ if a single-CPU system runs an SMP kernel then we call the local
  *   interrupt as well. Thus we cannot inline the local irq ... ]
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/apm.c linux-bk/arch/i386/kernel/apm.c
--- linux-2.4.19/arch/i386/kernel/apm.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/kernel/apm.c	2002-08-17 00:48:49.000000000 +0000
@@ -847,6 +847,7 @@
 			case 1: apm_idle_done = 1;
 				break;
 			default: /* BIOS refused */
+				break;
 			}
 		}
 		if (original_pm_idle)
@@ -862,14 +863,6 @@
 		apm_do_busy();
 }
 
-#ifdef CONFIG_SMP
-static int apm_magic(void * unused)
-{
-	while (1)
-		schedule();
-}
-#endif
-
 /**
  *	apm_power_off	-	ask the BIOS to power off
  *
@@ -897,10 +890,11 @@
 	 */
 #ifdef CONFIG_SMP
 	/* Some bioses don't like being called from CPU != 0 */
-	while (cpu_number_map(smp_processor_id()) != 0) {
-		kernel_thread(apm_magic, NULL,
-			CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
+	if (cpu_number_map(smp_processor_id()) != 0) {
+		current->cpus_allowed = 1;
 		schedule();
+		if (unlikely(cpu_number_map(smp_processor_id()) != 0))
+			BUG();
 	}
 #endif
 	if (apm_info.realmode_power_off)
@@ -1661,6 +1655,21 @@
 	strcpy(current->comm, "kapmd");
 	sigfillset(&current->blocked);
 
+#ifdef CONFIG_SMP
+	/* 2002/08/01 - WT
+	 * This is to avoid random crashes at boot time during initialization
+	 * on SMP systems in case of "apm=power-off" mode. Seen on ASUS A7M266D.
+	 * Some bioses don't like being called from CPU != 0.
+	 * Method suggested by Ingo Molnar.
+	 */
+	if (cpu_number_map(smp_processor_id()) != 0) {
+		current->cpus_allowed = 1;
+		schedule();
+		if (unlikely(cpu_number_map(smp_processor_id()) != 0))
+			BUG();
+	}
+#endif
+	
 	if (apm_info.connection_version == 0) {
 		apm_info.connection_version = apm_info.bios.version;
 		if (apm_info.connection_version > 0x100) {
@@ -1707,7 +1716,7 @@
 		}
 	}
 
-	if (debug && (smp_num_cpus == 1)) {
+	if (debug) {
 		error = apm_get_power_status(&bx, &cx, &dx);
 		if (error)
 			printk(KERN_INFO "apm: power status not available\n");
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/dmi_scan.c linux-bk/arch/i386/kernel/dmi_scan.c
--- linux-2.4.19/arch/i386/kernel/dmi_scan.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/kernel/dmi_scan.c	2002-08-17 00:49:02.000000000 +0000
@@ -190,7 +190,6 @@
  *	KT7 series. On these it seems the newer BIOS has fixed them. The
  *	rule needs to be improved to match specific BIOS revisions with
  *	corruption problems
- */ 
  
 static __init int disable_ide_dma(struct dmi_blacklist *d)
 {
@@ -204,6 +203,7 @@
 #endif	
 	return 0;
 }
+ */ 
 
 /* 
  * Reboot options and system auto-detection code provided by
@@ -635,6 +635,12 @@
 			MATCH(DMI_BIOS_DATE, "05/12/01"), NO_MATCH
 			} },
 	
+	{ swab_apm_power_in_minutes, "Sony VAIO", {	/* Handle problems with APM on Sony Vaio PCG-Z505LS (with updated BIOS) */
+			MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
+			MATCH(DMI_BIOS_VERSION, "R0209Z3"),
+			MATCH(DMI_BIOS_DATE, "05/12/01"), NO_MATCH
+			} },
+	
 	{ swab_apm_power_in_minutes, "Sony VAIO", {	/* Handle problems with APM on Sony Vaio PCG-F104K */
 			MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
 			MATCH(DMI_BIOS_VERSION, "R0204K2"),
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/io_apic.c linux-bk/arch/i386/kernel/io_apic.c
--- linux-2.4.19/arch/i386/kernel/io_apic.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/kernel/io_apic.c	2002-08-17 00:49:00.000000000 +0000
@@ -716,7 +716,7 @@
 	entry.vector = vector;
 
 	/*
-	 * The timer IRQ doesnt have to know that behind the
+	 * The timer IRQ doesn't have to know that behind the
 	 * scene we have a 8259A-master in AEOI mode ...
 	 */
 	irq_desc[0].handler = &ioapic_edge_irq_type;
@@ -1586,7 +1586,7 @@
 	printk(" failed.\n");
 
 	if (nmi_watchdog) {
-		printk(KERN_WARNING "timer doesnt work through the IO-APIC - disabling NMI Watchdog!\n");
+		printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n");
 		nmi_watchdog = 0;
 	}
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/irq.c linux-bk/arch/i386/kernel/irq.c
--- linux-2.4.19/arch/i386/kernel/irq.c	2001-10-25 20:53:46.000000000 +0000
+++ linux-bk/arch/i386/kernel/irq.c	2002-08-17 00:48:50.000000000 +0000
@@ -577,6 +577,20 @@
 	irq_desc_t *desc = irq_desc + irq;
 	struct irqaction * action;
 	unsigned int status;
+#ifdef CONFIG_DEBUG_STACKOVERFLOW
+	long esp;
+
+	/* Debugging check for stack overflow: is there less than 1KB free? */
+	__asm__ __volatile__("andl %%esp,%0" : "=r" (esp) : "0" (8191));
+	if (unlikely(esp < (sizeof(struct task_struct) + 1024))) {
+		extern void show_stack(unsigned long *);
+
+		printk("do_IRQ: stack overflow: %ld\n",
+			esp - sizeof(struct task_struct));
+		__asm__ __volatile__("movl %%esp,%0" : "=r" (esp));
+		show_stack((void *)esp);
+	}
+#endif
 
 	kstat.irqs[cpu][irq]++;
 	spin_lock(&desc->lock);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/mpparse.c linux-bk/arch/i386/kernel/mpparse.c
--- linux-2.4.19/arch/i386/kernel/mpparse.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/kernel/mpparse.c	2002-08-17 00:49:00.000000000 +0000
@@ -115,6 +115,8 @@
 		case 0x0F:
 			if (model == 0x00)
 				return("Pentium 4(tm)");
+			if (model == 0x02)
+				return("Pentium 4(tm) XEON(tm)");
 			if (model == 0x0F)
 				return("Special controller");
 	}
@@ -815,7 +817,7 @@
 
 /*
  * The Visual Workstation is Intel MP compliant in the hardware
- * sense, but it doesnt have a BIOS(-configuration table).
+ * sense, but it doesn't have a BIOS(-configuration table).
  * No problem for Linux.
  */
 void __init find_visws_smp(void)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/pci-i386.c linux-bk/arch/i386/kernel/pci-i386.c
--- linux-2.4.19/arch/i386/kernel/pci-i386.c	2001-11-04 17:31:58.000000000 +0000
+++ linux-bk/arch/i386/kernel/pci-i386.c	2002-08-17 00:48:57.000000000 +0000
@@ -303,7 +303,7 @@
 	pcibios_assign_resources();
 }
 
-int pcibios_enable_resources(struct pci_dev *dev)
+int pcibios_enable_resources(struct pci_dev *dev, int mask)
 {
 	u16 cmd, old_cmd;
 	int idx;
@@ -312,6 +312,10 @@
 	pci_read_config_word(dev, PCI_COMMAND, &cmd);
 	old_cmd = cmd;
 	for(idx=0; idx<6; idx++) {
+		/* Only set up the requested stuff */
+		if (!(mask & (1<<idx)))
+			continue;
+			
 		r = &dev->resource[idx];
 		if (!r->start && r->end) {
 			printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/pci-i386.h linux-bk/arch/i386/kernel/pci-i386.h
--- linux-2.4.19/arch/i386/kernel/pci-i386.h	2001-11-11 18:09:32.000000000 +0000
+++ linux-bk/arch/i386/kernel/pci-i386.h	2002-08-17 00:48:48.000000000 +0000
@@ -29,7 +29,7 @@
 extern unsigned int pcibios_max_latency;
 
 void pcibios_resource_survey(void);
-int pcibios_enable_resources(struct pci_dev *);
+int pcibios_enable_resources(struct pci_dev *, int);
 
 /* pci-pc.c */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/pci-pc.c linux-bk/arch/i386/kernel/pci-pc.c
--- linux-2.4.19/arch/i386/kernel/pci-pc.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/kernel/pci-pc.c	2002-08-17 00:49:03.000000000 +0000
@@ -1393,11 +1393,11 @@
 	return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
 }
 
-int pcibios_enable_device(struct pci_dev *dev)
+int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
 	int err;
 
-	if ((err = pcibios_enable_resources(dev)) < 0)
+	if ((err = pcibios_enable_resources(dev, mask)) < 0)
 		return err;
 	pcibios_enable_irq(dev);
 	return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/pci-visws.c linux-bk/arch/i386/kernel/pci-visws.c
--- linux-2.4.19/arch/i386/kernel/pci-visws.c	2001-11-04 17:31:58.000000000 +0000
+++ linux-bk/arch/i386/kernel/pci-visws.c	2002-08-17 00:48:54.000000000 +0000
@@ -131,9 +131,9 @@
 	return str;
 }
 
-int pcibios_enable_device(struct pci_dev *dev)
+int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
-	return pcibios_enable_resources(dev);
+	return pcibios_enable_resources(dev, mask);
 }
 
 void __init pcibios_penalize_isa_irq(irq)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/semaphore.c linux-bk/arch/i386/kernel/semaphore.c
--- linux-2.4.19/arch/i386/kernel/semaphore.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/kernel/semaphore.c	2002-08-17 00:49:03.000000000 +0000
@@ -262,31 +262,30 @@
  */
 #if defined(CONFIG_SMP)
 asm(
-"
-.align	4
-.globl	__write_lock_failed
-__write_lock_failed:
-	" LOCK "addl	$" RW_LOCK_BIAS_STR ",(%eax)
-1:	rep; nop
-	cmpl	$" RW_LOCK_BIAS_STR ",(%eax)
-	jne	1b
-
-	" LOCK "subl	$" RW_LOCK_BIAS_STR ",(%eax)
-	jnz	__write_lock_failed
-	ret
-
-
-.align	4
-.globl	__read_lock_failed
-__read_lock_failed:
-	lock ; incl	(%eax)
-1:	rep; nop
-	cmpl	$1,(%eax)
-	js	1b
+".text\n"
+".align	4\n"
+".globl	__write_lock_failed\n"
+"__write_lock_failed:\n\t"
+	LOCK "addl	$" RW_LOCK_BIAS_STR ",(%eax)\n"
+"1:	rep; nop\n\t"
+	"cmpl	$" RW_LOCK_BIAS_STR ",(%eax)\n\t"
+	"jne	1b\n\t"
+	LOCK "subl	$" RW_LOCK_BIAS_STR ",(%eax)\n\t"
+	"jnz	__write_lock_failed\n\t"
+	"ret"
+);
 
-	lock ; decl	(%eax)
-	js	__read_lock_failed
-	ret
-"
+asm(
+".text\n"
+".align	4\n"
+".globl	__read_lock_failed\n"
+"__read_lock_failed:\n\t"
+	LOCK "incl	(%eax)\n"
+"1:	rep; nop\n\t"
+	"cmpl	$1,(%eax)\n\t"
+	"js	1b\n\t"
+	LOCK "decl	(%eax)\n\t"
+	"js	__read_lock_failed\n\t"
+	"ret"
 );
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/setup.c linux-bk/arch/i386/kernel/setup.c
--- linux-2.4.19/arch/i386/kernel/setup.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/kernel/setup.c	2002-08-17 00:49:06.000000000 +0000
@@ -71,13 +71,6 @@
  *  CacheSize bug workaround updates for AMD, Intel & VIA Cyrix.
  *  Dave Jones <davej@suse.de>, September, October 2001.
  *
- *  Short-term fix for a conflicting cache attribute bug in the kernel
- *  that is exposed by advanced speculative caching on new AMD Athlon
- *  processors.
- *  Richard Brunner <richard.brunner@amd.com> and Mark Langsdorf
- *  <mark.langsdorf@amd.com>, June 2002 
- *  Adapted to work with uniprocessor APIC by Bryan O'Sullivan
- *  <bos@serpentine.com>, June 2002.
  */
 
 /*
@@ -171,17 +164,15 @@
 extern int root_mountflags;
 extern char _text, _etext, _edata, _end;
 
+static int have_cpuid_p(void) __init;
+
 static int disable_x86_serial_nr __initdata = 1;
 static int disable_x86_fxsr __initdata = 0;
 static int disable_x86_ht __initdata = 0;
 
-int enable_acpi_smp_table;
+extern int blk_nohighio;
 
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-int disable_adv_spec_cache __initdata = 1;
-#else
-int disable_adv_spec_cache __initdata = 0;
-#endif /* CONFIG_AGP */
+int enable_acpi_smp_table;
 
 /*
  * This is set up by the setup-routine at boot-time
@@ -741,41 +732,6 @@
 } /* setup_memory_region */
 
 
-int __init amd_adv_spec_cache_feature(void)
-{
-	char vendor_id[16];
-	int ident;
-	int family, model;
- 
-	/* Must have CPUID */
-	if(!have_cpuid_p())
-		goto donthave;
-	if(cpuid_eax(0)<1)
-		goto donthave;
-	
-	/* Must be x86 architecture */
-	cpuid(0, &ident,  
-		(int *)&vendor_id[0],
-		(int *)&vendor_id[8],
-		(int *)&vendor_id[4]);
-
-	if (memcmp(vendor_id, "AuthenticAMD", 12)) 
-	       goto donthave;
-
-	ident = cpuid_eax(1);
-	family = (ident >> 8) & 0xf;
-	model  = (ident >> 4) & 0xf;
-	if (((family == 6)  && (model >= 6)) || (family == 15)) {
-		printk(KERN_INFO "Advanced speculative caching feature present\n");
-		return 1;
-	}
-
-donthave:
-	printk(KERN_INFO "Advanced speculative caching feature not present\n");
-	return 0;
-}
-
-
 static void __init parse_cmdline_early (char ** cmdline_p)
 {
 	char c = ' ', *to = command_line, *from = COMMAND_LINE;
@@ -841,17 +797,6 @@
 		 */
 		else if (!memcmp(from, "highmem=", 8))
 			highmem_pages = memparse(from+8, &from) >> PAGE_SHIFT;
-		/*
-		 * unsafe-gart-alias overrides the short-term fix for a
-		 * conflicting cache attribute bug in the kernel that is
-		 * exposed by advanced speculative caching in newer AMD
-		 * Athlon processors.  Overriding the fix will allow
-		 * higher performance but the kernel bug can cause system
-		 * lock-ups if the system uses an AGP card.  unsafe-gart-alias
-		 * can be turned on for higher performance in servers.
-		 */
-		else if (!memcmp(from, "unsafe-gart-alias", 17))
-			disable_adv_spec_cache = 0;
 nextchar:
 		c = *(from++);
 		if (!c)
@@ -871,13 +816,17 @@
 void __init setup_arch(char **cmdline_p)
 {
 	unsigned long bootmap_size, low_mem_size;
-	unsigned long start_pfn, max_pfn, max_low_pfn;
+	unsigned long start_pfn, max_low_pfn;
 	int i;
 
 #ifdef CONFIG_VISWS
 	visws_get_board_type_and_rev();
 #endif
 
+#ifndef CONFIG_HIGHIO
+	blk_nohighio = 1;
+#endif
+
  	ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV);
  	drive_info = DRIVE_INFO;
  	screen_info = SCREEN_INFO;
@@ -1116,14 +1065,6 @@
 #ifdef CONFIG_SMP
 	smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
 #endif
-	/*
-	 * short-term fix for a conflicting cache attribute bug in the 
-	 * kernel that is exposed by advanced speculative caching on
-	 * newer AMD Athlon processors.
-	 */
-	if (disable_adv_spec_cache && amd_adv_spec_cache_feature())
-		clear_bit(X86_FEATURE_PSE, &boot_cpu_data.x86_capability);
-
 	paging_init();
 #ifdef CONFIG_X86_LOCAL_APIC
 	/*
@@ -1206,6 +1147,14 @@
 __setup("notsc", tsc_setup);
 #endif
 
+static int __init highio_setup(char *str)
+{
+	printk("i386: disabling HIGHMEM block I/O\n");
+	blk_nohighio = 1;
+	return 1;
+}
+__setup("nohighio", highio_setup);
+
 static int __init get_model_name(struct cpuinfo_x86 *c)
 {
 	unsigned int *v;
@@ -1292,31 +1241,6 @@
 	       l2size, ecx & 0xFF);
 }
 
-
-/*=======================================================================
- * amd_adv_spec_cache_disable
- * Setting a special MSR big that disables a small part of advanced
- * speculative caching as part of a short-term fix for a conflicting cache
- * attribute bug in the kernel that is exposed by advanced speculative
- * caching in newer AMD Athlon processors.
- =======================================================================*/
-static void amd_adv_spec_cache_disable(void)
-{
-	printk(KERN_INFO "Disabling advanced speculative caching\n");
-
-	__asm__ __volatile__ (
-		" movl	 $0x9c5a203a,%%edi   \n" /* msr enable */
-		" movl	 $0xc0011022,%%ecx   \n" /* msr addr	 */
-		" rdmsr			     \n" /* get reg val	 */
-		" orl	 $0x00010000,%%eax   \n" /* set bit 16	 */
-		" wrmsr			     \n" /* put it back	 */
-		" xorl	%%edi, %%edi	     \n" /* clear msr enable */
-		: /* no outputs */
-		: /* no inputs, either */
-		: "%eax","%ecx","%edx","%edi" /* clobbered regs */ );
-}
-
-
 /*
  *	B step AMD K6 before B 9730xxxx have hardware bugs that can cause
  *	misexecution of code under Linux. Owners of such processors should
@@ -1450,21 +1374,10 @@
  			 * to enable SSE on Palomino/Morgan CPU's.
 			 * If the BIOS didn't enable it already, enable it
 			 * here.
-			 *
-			 * Avoiding the use of 4MB/2MB pages along with
-			 * setting a special MSR bit that disables a small
-			 * part of advanced speculative caching as part of a
-			 * short-term fix for a conflicting cache attribute
-			 * bug in the kernel that is exposed by advanced
-			 * speculative caching in newer AMD Atlon processors.
-			 *
-			 * If we cleared the PSE bit earlier as part
-			 * of the workaround for this problem, we need
-			 * to clear it again, as our caller may have
-			 * clobbered it if uniprocessor APIC is enabled.
 			 */
-			if (c->x86_model >= 6) {
-				if (!cpu_has_xmm) {
+			if (c->x86_model == 6 || c->x86_model == 7) {
+				if (!test_bit(X86_FEATURE_XMM,
+					      &c->x86_capability)) {
 					printk(KERN_INFO
 					       "Enabling Disabled K7/SSE Support...\n");
 					rdmsr(MSR_K7_HWCR, l, h);
@@ -1473,18 +1386,6 @@
 					set_bit(X86_FEATURE_XMM,
                                                 &c->x86_capability);
 				}
-				if (disable_adv_spec_cache &&
-				    amd_adv_spec_cache_feature()) {
-					clear_bit(X86_FEATURE_PSE,
-						  &c->x86_capability);
-					amd_adv_spec_cache_disable();
-				}
-			}
-			break;
-		case 15: 
-			if (disable_adv_spec_cache && amd_adv_spec_cache_feature()) {
-				clear_bit(X86_FEATURE_PSE, &c->x86_capability);
-				amd_adv_spec_cache_disable();
 			}
 			break;
 
@@ -1534,7 +1435,7 @@
  * Cx86_dir0_msb is a HACK needed by check_cx686_cpuid/slop in bugs.h in
  * order to identify the Cyrix CPU model after we're out of setup.c
  *
- * Actually since bugs.h doesnt even reference this perhaps someone should
+ * Actually since bugs.h doesn't even reference this perhaps someone should
  * fix the documentation ???
  */
 static unsigned char Cx86_dir0_msb __initdata = 0;
@@ -2227,31 +2128,69 @@
 
 extern void trap_init_f00f_bug(void);
 
+#define LVL_1_INST      1
+#define LVL_1_DATA      2
+#define LVL_2           3
+#define LVL_3           4
+
+struct _cache_table
+{
+        unsigned char descriptor;
+        char cache_type;
+        short size;
+};
+
+/* all the cache descriptor types we care about (no TLB or trace cache entries) */
+static struct _cache_table cache_table[] __initdata =
+{
+	{ 0x06, LVL_1_INST, 8 },
+	{ 0x08, LVL_1_INST, 16 },
+	{ 0x0A, LVL_1_DATA, 8 },
+	{ 0x0C, LVL_1_DATA, 16 },
+	{ 0x22, LVL_3,      512 },
+	{ 0x23, LVL_3,      1024 },
+	{ 0x25, LVL_3,      2048 },
+	{ 0x29, LVL_3,      4096 },
+	{ 0x41, LVL_2,      128 },
+	{ 0x42, LVL_2,      256 },
+	{ 0x43, LVL_2,      512 },
+	{ 0x44, LVL_2,      1024 },
+	{ 0x45, LVL_2,      2048 },
+	{ 0x66, LVL_1_DATA, 8 },
+	{ 0x67, LVL_1_DATA, 16 },
+	{ 0x68, LVL_1_DATA, 32 },
+	{ 0x79, LVL_2,      128 },
+	{ 0x7A, LVL_2,      256 },
+	{ 0x7B, LVL_2,      512 },
+	{ 0x7C, LVL_2,      1024 },
+	{ 0x82, LVL_2,      256 },
+	{ 0x84, LVL_2,      1024 },
+	{ 0x85, LVL_2,      2048 },
+	{ 0x00, 0, 0}
+};
+
 static void __init init_intel(struct cpuinfo_x86 *c)
 {
-#ifndef CONFIG_M686
-	static int f00f_workaround_enabled = 0;
-#endif
-	char *p = NULL;
 	unsigned int l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
+	char *p = NULL;
+#ifndef CONFIG_X86_F00F_WORKS_OK
+	static int f00f_workaround_enabled = 0;
 
-#ifndef CONFIG_M686
 	/*
 	 * All current models of Pentium and Pentium with MMX technology CPUs
 	 * have the F0 0F bug, which lets nonpriviledged users lock up the system.
 	 * Note that the workaround only should be initialized once...
 	 */
 	c->f00f_bug = 0;
-	if ( c->x86 == 5 ) {
+	if (c->x86 == 5) {
 		c->f00f_bug = 1;
-		if ( !f00f_workaround_enabled ) {
+		if (!f00f_workaround_enabled) {
 			trap_init_f00f_bug();
 			printk(KERN_NOTICE "Intel Pentium with F0 0F bug - workaround enabled.\n");
 			f00f_workaround_enabled = 1;
 		}
 	}
-#endif
-
+#endif /* CONFIG_X86_F00F_WORKS_OK */
 
 	if (c->cpuid_level > 1) {
 		/* supports eax=2  call */
@@ -2273,83 +2212,31 @@
 			/* Byte 0 is level count, not a descriptor */
 			for ( j = 1 ; j < 16 ; j++ ) {
 				unsigned char des = dp[j];
-				unsigned char dl, dh;
-				unsigned int cs;
-
-				dh = des >> 4;
-				dl = des & 0x0F;
-
-				/* Black magic... */
+				unsigned char k = 0;
 
-				switch ( dh )
+				/* look up this descriptor in the table */
+				while (cache_table[k].descriptor != 0)
 				{
-				case 0:
-					switch ( dl ) {
-					case 6:
-						/* L1 I cache */
-						l1i += 8;
-						break;
-					case 8:
-						/* L1 I cache */
-						l1i += 16;
-						break;
-					case 10:
-						/* L1 D cache */
-						l1d += 8;
-						break;
-					case 12:
-						/* L1 D cache */
-						l1d += 16;
-						break;
-					default:;
-						/* TLB, or unknown */
-					}
-					break;
-				case 2:
-					if ( dl ) {
-						/* L3 cache */
-						cs = (dl-1) << 9;
-						l3 += cs;
-					}
-					break;
-				case 4:
-					if ( c->x86 > 6 && dl ) {
-						/* P4 family */
-						/* L3 cache */
-						cs = 128 << (dl-1);
-						l3 += cs;
+					if (cache_table[k].descriptor == des) {
+						switch (cache_table[k].cache_type) {
+						case LVL_1_INST:
+							l1i += cache_table[k].size;
+							break;
+						case LVL_1_DATA:
+							l1d += cache_table[k].size;
+							break;
+						case LVL_2:
+							l2 += cache_table[k].size;
+							break;
+						case LVL_3:
+							l3 += cache_table[k].size;
+							break;
+						}
+
 						break;
 					}
-					/* else same as 8 - fall through */
-				case 8:
-					if ( dl ) {
-						/* L2 cache */
-						cs = 128 << (dl-1);
-						l2 += cs;
-					}
-					break;
-				case 6:
-					if (dl > 5) {
-						/* L1 D cache */
-						cs = 8<<(dl-6);
-						l1d += cs;
-					}
-					break;
-				case 7:
-					if ( dl >= 8 ) 
-					{
-						/* L2 cache */
-						cs = 64<<(dl-8);
-						l2 += cs;
-					} else {
-						/* L0 I cache, count as L1 */
-						cs = dl ? (16 << (dl-1)) : 12;
-						l1i += cs;
-					}
-					break;
-				default:
-					/* TLB, or something else we don't know about */
-					break;
+
+					k++;
 				}
 			}
 		}
@@ -2426,7 +2313,7 @@
 			if (smp_num_siblings != NR_SIBLINGS) {
 				printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings);
 				smp_num_siblings = 1;
-				goto too_many_siblings;
+				return;
 			}
 			tmp = smp_num_siblings;
 			while ((tmp & 1) == 0) {
@@ -2448,7 +2335,6 @@
 		}
 
 	}
-too_many_siblings:
 #endif
 }
 
@@ -2749,12 +2635,6 @@
 			      &c->x86_capability[0]);
 			c->x86 = (tfms >> 8) & 15;
 			c->x86_model = (tfms >> 4) & 15;
-			if ( (c->x86_vendor == X86_VENDOR_AMD) &&
-				(c->x86 == 0xf)) {
-				/* AMD Extended Family and Model Values */
-				c->x86 += (tfms >> 20) & 0xff;
-				c->x86_model += (tfms >> 12) & 0xf0;
-			}
 			c->x86_mask = tfms & 15;
 		} else {
 			/* Have CPUID level 0 only - unheard of */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/smp.c linux-bk/arch/i386/kernel/smp.c
--- linux-2.4.19/arch/i386/kernel/smp.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/kernel/smp.c	2002-08-17 00:48:51.000000000 +0000
@@ -66,7 +66,7 @@
  *	an L1cache=Writethrough or L1cache=off option.
  *
  *		B stepping CPUs may hang. There are hardware work arounds
- *	for this. We warn about it in case your board doesnt have the work
+ *	for this. We warn about it in case your board doesn't have the work
  *	arounds. Basically thats so I can tell anyone with a B stepping
  *	CPU and SMP problems "tough".
  *
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/trampoline.S linux-bk/arch/i386/kernel/trampoline.S
--- linux-2.4.19/arch/i386/kernel/trampoline.S	2001-10-05 01:42:54.000000000 +0000
+++ linux-bk/arch/i386/kernel/trampoline.S	2002-08-17 00:49:02.000000000 +0000
@@ -36,9 +36,7 @@
 
 ENTRY(trampoline_data)
 r_base = .
-#ifdef CONFIG_MULTIQUAD
-	wbinvd
-#endif /* CONFIG_MULTIQUAD */
+	wbinvd			# Needed for NUMA-Q should be harmless for others
 	mov	%cs, %ax	# Code and data in the same place
 	mov	%ax, %ds
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/traps.c linux-bk/arch/i386/kernel/traps.c
--- linux-2.4.19/arch/i386/kernel/traps.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/kernel/traps.c	2002-08-17 00:48:53.000000000 +0000
@@ -40,9 +40,9 @@
 
 #include <asm/smp.h>
 #include <asm/pgalloc.h>
+#include <asm/fixmap.h>
 
 #ifdef CONFIG_X86_VISWS_APIC
-#include <asm/fixmap.h>
 #include <asm/cobalt.h>
 #include <asm/lithium.h>
 #endif
@@ -186,6 +186,14 @@
 	show_trace(esp);
 }
 
+/*
+ * The architecture-independent backtrace generator
+ */
+void dump_stack(void)
+{
+	show_stack(0);
+}
+
 void show_registers(struct pt_regs *regs)
 {
 	int i;
@@ -305,8 +313,13 @@
 static void inline do_trap(int trapnr, int signr, char *str, int vm86,
 			   struct pt_regs * regs, long error_code, siginfo_t *info)
 {
-	if (vm86 && regs->eflags & VM_MASK)
-		goto vm86_trap;
+	if (regs->eflags & VM_MASK) {
+		if (vm86)
+			goto vm86_trap;
+		else
+			goto trap_signal;
+	}
+
 	if (!(regs->xcs & 3))
 		goto kernel_trap;
 
@@ -514,10 +527,15 @@
 {
 	unsigned int condition;
 	struct task_struct *tsk = current;
+	unsigned long eip = regs->eip;
 	siginfo_t info;
 
 	__asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
 
+	/* If the user set TF, it's simplest to clear it right away. */
+	if ((eip >=PAGE_OFFSET) && (regs->eflags & TF_MASK))
+		goto clear_TF;
+
 	/* Mask out spurious debug traps due to lazy DR7 setting */
 	if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
 		if (!tsk->thread.debugreg[7])
@@ -758,35 +776,17 @@
 
 #endif /* CONFIG_MATH_EMULATION */
 
-#ifndef CONFIG_M686
+#ifndef CONFIG_X86_F00F_WORKS_OK
 void __init trap_init_f00f_bug(void)
 {
-	unsigned long page;
-	pgd_t * pgd;
-	pmd_t * pmd;
-	pte_t * pte;
-
-	/*
-	 * Allocate a new page in virtual address space, 
-	 * move the IDT into it and write protect this page.
-	 */
-	page = (unsigned long) vmalloc(PAGE_SIZE);
-	pgd = pgd_offset(&init_mm, page);
-	pmd = pmd_offset(pgd, page);
-	pte = pte_offset(pmd, page);
-	__free_page(pte_page(*pte));
-	*pte = mk_pte_phys(__pa(&idt_table), PAGE_KERNEL_RO);
-	/*
-	 * Not that any PGE-capable kernel should have the f00f bug ...
-	 */
-	__flush_tlb_all();
-
 	/*
 	 * "idt" is magic - it overlaps the idt_descr
 	 * variable so that updating idt will automatically
 	 * update the idt descriptor..
 	 */
-	idt = (struct desc_struct *)page;
+	__set_fixmap(FIX_F00F, __pa(&idt_table), PAGE_KERNEL_RO);
+	idt = (struct desc_struct *)__fix_to_virt(FIX_F00F);
+
 	__asm__ __volatile__("lidt %0": "=m" (idt_descr));
 }
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/mm/Makefile linux-bk/arch/i386/mm/Makefile
--- linux-2.4.19/arch/i386/mm/Makefile	2000-12-29 22:07:20.000000000 +0000
+++ linux-bk/arch/i386/mm/Makefile	2002-08-17 00:48:57.000000000 +0000
@@ -9,6 +9,7 @@
 
 O_TARGET := mm.o
 
-obj-y	 := init.o fault.o ioremap.o extable.o
+obj-y	 := init.o fault.o ioremap.o extable.o pageattr.o
+export-objs := pageattr.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/mm/fault.c linux-bk/arch/i386/mm/fault.c
--- linux-2.4.19/arch/i386/mm/fault.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/mm/fault.c	2002-08-17 00:48:47.000000000 +0000
@@ -86,8 +86,7 @@
 
 out_of_memory:
 	if (current->pid == 1) {
-		current->policy |= SCHED_YIELD;
-		schedule();
+		yield();
 		goto survive;
 	}
 	goto bad_area;
@@ -336,8 +335,7 @@
 out_of_memory:
 	up_read(&mm->mmap_sem);
 	if (tsk->pid == 1) {
-		tsk->policy |= SCHED_YIELD;
-		schedule();
+		yield();
 		down_read(&mm->mmap_sem);
 		goto survive;
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/mm/pageattr.c linux-bk/arch/i386/mm/pageattr.c
--- linux-2.4.19/arch/i386/mm/pageattr.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/i386/mm/pageattr.c	2002-08-17 00:49:00.000000000 +0000
@@ -0,0 +1,172 @@
+/* 
+ * Copyright 2002 Andi Kleen, SuSE Labs. 
+ * Thanks to Ben LaHaise for precious feedback.
+ */ 
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/highmem.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+#include <asm/processor.h>
+
+/* Should move most of this stuff into the appropiate includes */
+#define PAGE_LARGE (_PAGE_PSE|_PAGE_PRESENT) 
+#define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1))
+#define LARGE_PAGE_SIZE (1UL << PMD_SHIFT)
+
+static inline pte_t *lookup_address(unsigned long address) 
+{ 
+	pmd_t *pmd;	
+	pgd_t *pgd = pgd_offset(&init_mm, address); 
+
+	if ((pgd_val(*pgd) & PAGE_LARGE) == PAGE_LARGE)
+		return (pte_t *)pgd; 
+	pmd = pmd_offset(pgd, address); 	       
+	if ((pmd_val(*pmd) & PAGE_LARGE) == PAGE_LARGE)
+		return (pte_t *)pmd; 
+
+        return pte_offset(pmd, address);
+} 
+
+static struct page *split_large_page(unsigned long address, pgprot_t prot)
+{ 
+	int i; 
+	unsigned long addr;
+	struct page *base = alloc_pages(GFP_KERNEL, 0);
+	pte_t *pbase;
+	if (!base) 
+		return NULL;
+	address = __pa(address);
+	addr = address & LARGE_PAGE_MASK; 
+	pbase = (pte_t *)page_address(base);
+	for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) {
+		pbase[i] = mk_pte_phys(addr, 
+				      addr == address ? prot : PAGE_KERNEL);
+	}
+	return base;
+} 
+
+static void flush_kernel_map(void * address) 
+{ 
+	if (!test_bit(X86_FEATURE_SELFSNOOP, &boot_cpu_data.x86_capability)) {
+		/* Could use CLFLUSH here if the CPU supports it (Hammer,P4) */
+		if (boot_cpu_data.x86_model >= 4) 
+			asm volatile("wbinvd":::"memory"); 	
+	} 
+
+	/* Do global flush here to work around large page flushing errata 
+	   in some early Athlons */
+	__flush_tlb_all(); 	
+}
+
+static void set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte) 
+{ 
+	set_pte_atomic(kpte, pte); 	/* change init_mm */
+#ifndef CONFIG_X86_PAE
+	{
+		struct list_head *l;
+		spin_lock(&mmlist_lock);
+		list_for_each(l, &init_mm.mmlist) { 
+			struct mm_struct *mm = list_entry(l, struct mm_struct, mmlist);
+			pmd_t *pmd = pmd_offset(pgd_offset(mm, address), address);
+			set_pte_atomic((pte_t *)pmd, pte);
+		} 
+		spin_unlock(&mmlist_lock);
+	}
+#endif
+}
+
+/* no more special protections in this 2/4MB area - revert to a
+   large page again. */
+static inline void revert_page(struct page *kpte_page, unsigned long address)
+{
+	pte_t *linear = (pte_t *) 
+		pmd_offset(pgd_offset(&init_mm, address), address);
+	set_pmd_pte(linear,  address,
+		mk_pte_phys(__pa(address & LARGE_PAGE_MASK),
+			    MAKE_GLOBAL(_KERNPG_TABLE|_PAGE_PSE)));
+}	
+ 
+/*
+ * Change the page attributes of an page in the linear mapping.
+ *
+ * This should be used when a page is mapped with a different caching policy
+ * than write-back somewhere - some CPUs do not like it when mappings with
+ * different caching policies exist. This changes the page attributes of the
+ * in kernel linear mapping too.
+ * 
+ * The caller needs to ensure that there are no conflicting mappings elsewhere.
+ * This function only deals with the kernel linear map.
+ * When page is in highmem it must never be kmap'ed.
+ */
+static int 
+__change_page_attr(struct page *page, pgprot_t prot, struct page **oldpage) 
+{ 
+	pte_t *kpte; 
+	unsigned long address;
+	struct page *kpte_page;
+
+#ifdef CONFIG_HIGHMEM
+	if (page >= highmem_start_page) 
+		BUG(); 
+#endif
+	address = (unsigned long)page_address(page);
+
+	kpte = lookup_address(address);
+	kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK);
+	if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) { 
+		if ((pte_val(*kpte) & _PAGE_PSE) == 0) { 
+			pte_t old = *kpte;
+			pte_t standard = mk_pte(page, PAGE_KERNEL); 
+
+			set_pte_atomic(kpte, mk_pte(page, prot)); 
+			if (pte_same(old,standard))
+				atomic_inc(&kpte_page->count);
+		} else {
+			struct page *split = split_large_page(address, prot); 
+			if (!split)
+				return -ENOMEM;
+			set_pmd_pte(kpte,address,mk_pte(split, PAGE_KERNEL));
+		}	
+	} else if ((pte_val(*kpte) & _PAGE_PSE) == 0) { 
+		set_pte_atomic(kpte, mk_pte(page, PAGE_KERNEL));
+		atomic_dec(&kpte_page->count); 
+	}
+
+	if (test_bit(X86_FEATURE_PSE, &boot_cpu_data.x86_capability) && 
+	    (atomic_read(&kpte_page->count) == 1)) { 
+		*oldpage = kpte_page;
+		revert_page(kpte_page, address);
+	} 
+	return 0;
+} 
+
+int change_page_attr(struct page *page, int numpages, pgprot_t prot)
+{
+	int err = 0; 
+	struct page *fpage; 
+	int i; 
+
+	down_write(&init_mm.mmap_sem);
+	for (i = 0; i < numpages; i++, page++) { 
+		fpage = NULL;
+		err = __change_page_attr(page, prot, &fpage); 
+		if (err) 
+			break; 
+		if (fpage || i == numpages-1) { 
+			void *address = page_address(page);
+#ifdef CONFIG_SMP 
+			smp_call_function(flush_kernel_map, address, 1, 1);
+#endif	
+			flush_kernel_map(address);
+			if (fpage)
+				__free_page(fpage);
+		} 
+	} 	
+	up_write(&init_mm.mmap_sem); 
+	return err;
+}
+
+EXPORT_SYMBOL(change_page_attr);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/config.in linux-bk/arch/ia64/config.in
--- linux-2.4.19/arch/ia64/config.in	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/config.in	2002-08-17 00:49:08.000000000 +0000
@@ -75,15 +75,15 @@
 
 if [ "$CONFIG_IA64_SGI_SN1" = "y" ] || [ "$CONFIG_IA64_SGI_SN2" = "y" ]; then
 	define_bool CONFIG_IA64_SGI_SN y
-	bool '  Enable extra debugging code' CONFIG_IA64_SGI_SN_DEBUG n
+	bool '  Enable extra debugging code' CONFIG_IA64_SGI_SN_DEBUG
 	bool '  Enable SGI Medusa Simulator Support' CONFIG_IA64_SGI_SN_SIM
 	bool '  Enable autotest (llsc). Option to run cache test instead of booting' \
-			CONFIG_IA64_SGI_AUTOTEST n
+			CONFIG_IA64_SGI_AUTOTEST
 	define_bool CONFIG_DEVFS_FS y
 	if [ "$CONFIG_DEVFS_FS" = "y" ]; then
-	  bool '    Enable DEVFS Debug Code' CONFIG_DEVFS_DEBUG n
+	  bool '    Enable DEVFS Debug Code' CONFIG_DEVFS_DEBUG
 	fi
-	bool '  Enable protocol mode for the L1 console' CONFIG_SERIAL_SGI_L1_PROTOCOL y
+	bool '  Enable protocol mode for the L1 console' CONFIG_SERIAL_SGI_L1_PROTOCOL
 	define_bool CONFIG_DISCONTIGMEM y
 	define_bool CONFIG_IA64_MCA y
 	define_bool CONFIG_NUMA y
@@ -195,7 +195,7 @@
 mainmenu_option next_comment
 comment 'CD-ROM drivers (not for SCSI or IDE/ATAPI drives)'
 
-bool 'Support non-SCSI/IDE/ATAPI drives' CONFIG_CD_NO_IDESCSI
+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
@@ -239,6 +239,8 @@
 
 source drivers/usb/Config.in
 
+source lib/Config.in
+
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
    source net/bluetooth/Config.in
 fi
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/mm/fault.c linux-bk/arch/ia64/mm/fault.c
--- linux-2.4.19/arch/ia64/mm/fault.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/mm/fault.c	2002-08-17 00:49:13.000000000 +0000
@@ -196,8 +196,7 @@
   out_of_memory:
 	up_read(&mm->mmap_sem);
 	if (current->pid == 1) {
-		current->policy |= SCHED_YIELD;
-		schedule();
+		yield();
 		down_read(&mm->mmap_sem);
 		goto survive;
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/sn/fakeprom/README linux-bk/arch/ia64/sn/fakeprom/README
--- linux-2.4.19/arch/ia64/sn/fakeprom/README	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/sn/fakeprom/README	2002-08-17 00:49:07.000000000 +0000
@@ -71,7 +71,7 @@
     1GB*<dn>, where dn is the digit number. The amount of memory
     is 8MB*2**<d>. (If <d> = 0, the memory size is 0).
 
-    SN1 doesnt support dimms this small but small memory systems 
+    SN1 doesn't support dimms this small but small memory systems 
     boot faster on Medusa.
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/config.in linux-bk/arch/m68k/config.in
--- linux-2.4.19/arch/m68k/config.in	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/m68k/config.in	2002-08-17 00:49:11.000000000 +0000
@@ -141,7 +141,7 @@
    fi
    dep_tristate '  Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT
    if [ "$CONFIG_PRINTER" != "n" ]; then
-      bool '    Support IEEE1284 status readback' CONFIG_PARPORT_1284
+      bool '    IEEE 1284 transfer modes' CONFIG_PARPORT_1284
    fi
 fi
 
@@ -539,7 +539,7 @@
 mainmenu_option next_comment
 comment 'Sound support'
 
-tristate 'Sound support' CONFIG_SOUND
+tristate 'Sound card support' CONFIG_SOUND
 if [ "$CONFIG_SOUND" != "n" ]; then
    source drivers/sound/dmasound/Config.in
 fi
@@ -565,3 +565,5 @@
 fi
 
 endmenu
+
+source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/mm/fault.c linux-bk/arch/m68k/mm/fault.c
--- linux-2.4.19/arch/m68k/mm/fault.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/m68k/mm/fault.c	2002-08-17 00:49:05.000000000 +0000
@@ -181,8 +181,7 @@
 out_of_memory:
 	up_read(&mm->mmap_sem);
 	if (current->pid == 1) {
-		current->policy |= SCHED_YIELD;
-		schedule();
+		yield();
 		down_read(&mm->mmap_sem);
 		goto survive;
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/usbdev.c linux-bk/arch/mips/au1000/common/usbdev.c
--- linux-2.4.19/arch/mips/au1000/common/usbdev.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/au1000/common/usbdev.c	2002-08-17 00:48:50.000000000 +0000
@@ -866,7 +866,7 @@
 
 // SETUP packet request parser
 static void
-process_setup (struct usb_serial* serial, devrequest* setup)
+process_setup (struct usb_serial* serial, struct usb_ctrlrequest* setup)
 {
 	int desc_len, strnum;
 
@@ -874,7 +874,7 @@
 
 	switch (setup->request) {
 	case USB_REQ_SET_ADDRESS:
-		serial->address = le16_to_cpu(setup->value);
+		serial->address = le16_to_cpu(setup->wValue);
 		dbg(__FUNCTION__ ": our address=%d", serial->address);
 		if (serial->address > 127 || serial->state == CONFIGURED) {
 			// usb spec doesn't tell us what to do, so just go to
@@ -887,8 +887,8 @@
 			serial->state = DEFAULT;
 		break;
 	case USB_REQ_GET_DESCRIPTOR:
-		desc_len = le16_to_cpu(setup->length);
-		switch (le16_to_cpu(setup->value) >> 8) {
+		desc_len = le16_to_cpu(setup->wLength);
+		switch (le16_to_cpu(setup->wValue) >> 8) {
 		case USB_DT_DEVICE:
 			// send device descriptor!
 			desc_len = desc_len > serial->dev_desc->bLength ?
@@ -901,7 +901,7 @@
 			// If the config descr index in low-byte of
 			// setup->value	is valid, send config descr,
 			// otherwise stall ep0.
-			if ((le16_to_cpu(setup->value) & 0xff) == 0) {
+			if ((le16_to_cpu(setup->wValue) & 0xff) == 0) {
 				// send config descriptor!
 				if (desc_len <= USB_DT_CONFIG_SIZE) {
 					dbg("sending partial config desc, size=%d",
@@ -943,7 +943,7 @@
 		case USB_DT_STRING:
 			// If the string descr index in low-byte of setup->value
 			// is valid, send string descr, otherwise stall ep0.
-			strnum = le16_to_cpu(setup->value) & 0xff;
+			strnum = le16_to_cpu(setup->wValue) & 0xff;
 			if (strnum >= 0 && strnum < 6) {
 				struct usb_string_descriptor *desc =
 				    serial->str_desc[strnum];
@@ -957,7 +957,7 @@
 			break;
 		default:	// Invalid request
 			dbg("invalid get desc=%d, stalled",
-			    le16_to_cpu(setup->value) >> 8);
+			    le16_to_cpu(setup->wValue) >> 8);
 			endpoint_stall(&serial->ep_ctrl);	// Stall endpoint 0
 			break;
 		}
@@ -967,7 +967,7 @@
 		break;
 	case USB_REQ_GET_INTERFACE:
 		// interface must be zero.
-		if ((le16_to_cpu(setup->index) & 0xff) ||
+		if ((le16_to_cpu(setup->wIndex) & 0xff) ||
 		    serial->state == ADDRESS) {
 			// FIXME: respond with "request error". how?
 		} else if (serial->state == CONFIGURED) {
@@ -981,9 +981,9 @@
 		if (serial->state == ADDRESS) {
 			// FIXME: respond with "request error". how?
 		} else if (serial->state == CONFIGURED) {
-			serial->interface = le16_to_cpu(setup->index) & 0xff;
+			serial->interface = le16_to_cpu(setup->wIndex) & 0xff;
 			serial->alternate_setting =
-			    le16_to_cpu(setup->value) & 0xff;
+			    le16_to_cpu(setup->wValue) & 0xff;
 			// interface and alternate_setting must be zero
 			if (serial->interface || serial->alternate_setting) {
 				// FIXME: respond with "request error". how?
@@ -992,7 +992,7 @@
 		break;
 	case USB_REQ_SET_CONFIGURATION:
 		// set active config to low-byte of serial.value
-		serial->configuration = le16_to_cpu(setup->value) & 0xff;
+		serial->configuration = le16_to_cpu(setup->wValue) & 0xff;
 		dbg("set config, config=%d", serial->configuration);
 		if (!serial->configuration && serial->state > DEFAULT)
 			serial->state = ADDRESS;
@@ -1009,7 +1009,7 @@
 		break;
 	case USB_REQ_GET_STATUS:
 		// FIXME: looks like the h/w handles this one
-		switch (setup->requesttype) {
+		switch (setup->bRequestType) {
 		case 0x80:	// Device
 			// FIXME: send device status
 			break;
@@ -1027,16 +1027,16 @@
 	case USB_REQ_CLEAR_FEATURE:
 		switch (setup->requesttype) {
 		case 0x00:	// Device
-			if ((le16_to_cpu(setup->value) & 0xff) == 1)
+			if ((le16_to_cpu(setup->wValue) & 0xff) == 1)
 				serial->remote_wakeup_en = 0;
 			else
 				endpoint_stall(&serial->ep_ctrl);
 			break;
 		case 0x02:	// End Point
-			if ((le16_to_cpu(setup->value) & 0xff) == 0) {
+			if ((le16_to_cpu(setup->wValue) & 0xff) == 0) {
 				endpoint_t *ep =
 				    epnum_to_ep(serial,
-						    le16_to_cpu(setup->index) & 0xff);
+						    le16_to_cpu(setup->wIndex) & 0xff);
 
 				endpoint_unstall(ep);
 				endpoint_reset_datatoggle(ep);
@@ -1046,18 +1046,18 @@
 		}
 		break;
 	case USB_REQ_SET_FEATURE:
-		switch (setup->requesttype) {
+		switch (setup->bRequestType) {
 		case 0x00:	// Device
-			if ((le16_to_cpu(setup->value) & 0xff) == 1)
+			if ((le16_to_cpu(setup->wValue) & 0xff) == 1)
 				serial->remote_wakeup_en = 1;
 			else
 				endpoint_stall(&serial->ep_ctrl);
 			break;
 		case 0x02:	// End Point
-			if ((le16_to_cpu(setup->value) & 0xff) == 0) {
+			if ((le16_to_cpu(setup->wValue) & 0xff) == 0) {
 				endpoint_t *ep =
 				    epnum_to_ep(serial,
-						    le16_to_cpu(setup->index) & 0xff);
+						    le16_to_cpu(setup->wIndex) & 0xff);
 
 				endpoint_stall(ep);
 			} else
@@ -1100,14 +1100,14 @@
 	
 		// SETUP packet received ?
 		//if (cs & USBDEV_CS_SU) { FIXME: uncomment!
-			if (pkt->size == sizeof(devrequest)) {
-				devrequest setup;
+			if (pkt->size == sizeof(struct usb_ctrlrequest)) {
+				struct usb_ctrlrequest setup;
 			if ((cs & (USBDEV_CS_NAK | USBDEV_CS_ACK)) ==
 			    USBDEV_CS_ACK)
 					dbg("got SETUP");
 				else
 					dbg("got NAK SETUP, cs=%08x", cs);
-			memcpy(&setup, pkt->bufptr, sizeof(devrequest));
+			memcpy(&setup, pkt->bufptr, sizeof(struct usb_ctrlrequest));
 				process_setup(serial, &setup);
 			//} else  FIXME: uncomment!
 			//dbg(__FUNCTION__ ": wrong size SETUP received");
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/config.in linux-bk/arch/mips/config.in
--- linux-2.4.19/arch/mips/config.in	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/config.in	2002-08-17 00:49:10.000000000 +0000
@@ -632,3 +632,5 @@
    bool 'Run uncached' CONFIG_MIPS_UNCACHED
 fi
 endmenu
+
+source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/dec/wbflush.c linux-bk/arch/mips/dec/wbflush.c
--- linux-2.4.19/arch/mips/dec/wbflush.c	2001-10-05 19:06:51.000000000 +0000
+++ linux-bk/arch/mips/dec/wbflush.c	2002-08-17 00:49:12.000000000 +0000
@@ -97,7 +97,7 @@
 }
 
 /*
- * The DS500/2x0 doesnt need to write back the WB.
+ * The DS500/2x0 doesn't need to write back the WB.
  */
 static void wbflush_kn03(void)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mm/fault.c linux-bk/arch/mips/mm/fault.c
--- linux-2.4.19/arch/mips/mm/fault.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/mm/fault.c	2002-08-17 00:48:58.000000000 +0000
@@ -213,8 +213,7 @@
 out_of_memory:
 	up_read(&mm->mmap_sem);
 	if (tsk->pid == 1) {
-		tsk->policy |= SCHED_YIELD;
-		schedule();
+		yield();
 		down_read(&mm->mmap_sem);
 		goto survive;
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/config.in linux-bk/arch/mips64/config.in
--- linux-2.4.19/arch/mips64/config.in	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips64/config.in	2002-08-17 00:48:52.000000000 +0000
@@ -336,3 +336,5 @@
    bool 'Run uncached' CONFIG_MIPS_UNCACHED
 fi
 endmenu
+
+source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/irq.c linux-bk/arch/mips64/kernel/irq.c
--- linux-2.4.19/arch/mips64/kernel/irq.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips64/kernel/irq.c	2002-08-17 00:48:46.000000000 +0000
@@ -48,7 +48,7 @@
 {
 	/*
 	 * 'what should we do if we get a hw irq event on an illegal vector'.
-	 * each architecture has to answer this themselves, it doesnt deserve
+	 * each architecture has to answer this themselves, it doesn't deserve
 	 * a generic callback i think.
 	 */
 	printk("unexpected interrupt %d\n", irq);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/ieee754.c linux-bk/arch/mips64/math-emu/ieee754.c
--- linux-2.4.19/arch/mips64/math-emu/ieee754.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-bk/arch/mips64/math-emu/ieee754.c	2002-08-17 00:48:57.000000000 +0000
@@ -3,7 +3,7 @@
  *
  * BUGS
  * not much dp done
- * doesnt generate IEEE754_INEXACT
+ * doesn't generate IEEE754_INEXACT
  *
  */
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/mm/fault.c linux-bk/arch/mips64/mm/fault.c
--- linux-2.4.19/arch/mips64/mm/fault.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips64/mm/fault.c	2002-08-17 00:48:48.000000000 +0000
@@ -238,8 +238,7 @@
 out_of_memory:
 	up_read(&mm->mmap_sem);
 	if (tsk->pid == 1) {
-		tsk->policy |= SCHED_YIELD;
-		schedule();
+		yield();
 		down_read(&mm->mmap_sem);
 		goto survive;
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/Makefile linux-bk/arch/parisc/Makefile
--- linux-2.4.19/arch/parisc/Makefile	2000-12-05 20:29:39.000000000 +0000
+++ linux-bk/arch/parisc/Makefile	2002-08-17 00:49:01.000000000 +0000
@@ -17,12 +17,28 @@
 # Mike Shaver, Helge Deller and Martin K. Petersen
 #
 
+ifdef CONFIG_PARISC64
+LINKFLAGS =-T $(TOPDIR)/arch/parisc/vmlinux64.lds $(LDFLAGS)
+CROSS_COMPILE := hppa64-linux-
+UTS_MACHINE := parisc64
+#CFLAGS += -b hppa64-linux
+
+else
+LINKFLAGS =-T $(TOPDIR)/arch/parisc/vmlinux.lds $(LDFLAGS)
+MACHINE	:= $(subst 64,,$(shell uname -m))
+ifneq (${MACHINE},parisc)
+# cross compilation
+CROSS_COMPILE := hppa-linux-
+endif
+endif
+
+OFFSET_H := $(TOPDIR)/include/asm-parisc/offset.h
 FINAL_LD=$(CROSS_COMPILE)ld --warn-common --warn-section-align 
 
 CPP=$(CC) -E
 OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S
 LDFLAGS =
-LINKFLAGS =-T $(TOPDIR)/arch/parisc/vmlinux.lds $(LDFLAGS)
+
 
 CFLAGS_PIPE := -pipe
 CFLAGS_NSR  := -fno-strength-reduce
@@ -32,25 +48,48 @@
 # enable them by default.
 CFLAGS += -mno-space-regs -mfast-indirect-calls
 
-# If we become able to compile for specific platforms, this should be
-# conditional on that.
-CFLAGS += -mschedule=7200
-
 # No fixed-point multiply
 CFLAGS += -mdisable-fpregs
 
-HEAD = arch/parisc/kernel/head.o 
+# Without this, "ld -r" results in .text sections that are too big
+# (> 0x40000) for branches to reach stubs.
+CFLAGS += -ffunction-sections
+
+# select which processor to optimise for
+ifdef CONFIG_PA7100
+CFLAGS += -march=1.1 -mschedule=7100
+endif
+
+ifdef CONFIG_PA7200
+CFLAGS += -march=1.1 -mschedule=7200
+endif
+
+ifdef CONFIG_PA7100LC
+CFLAGS += -march=1.1 -mschedule=7100LC
+endif
+
+ifdef CONFIG_PA8X00
+CFLAGS += -march=2.0 -mschedule=8000
+endif
+
+ASFLAGS := -D__ASSEMBLY__ -traditional
+
+HEAD := arch/parisc/kernel/head.o 
 
 SUBDIRS := $(SUBDIRS) $(addprefix arch/parisc/, tools kernel mm lib hpux)
 CORE_FILES :=  $(addprefix arch/parisc/, kernel/pdc_cons.o kernel/process.o \
 	lib/lib.a mm/mm.o kernel/kernel.o hpux/hpux.o) \
 	$(CORE_FILES) arch/parisc/kernel/init_task.o
+CLEAN_FILES := $(CLEAN_FILES) arch/parisc/tools/offset.[hs] 
+
+ifdef CONFIG_PARISC64
+HEAD := arch/parisc/kernel/head64.o
+endif
+
 LIBS := `$(CC) -print-libgcc-file-name` $(TOPDIR)/arch/parisc/lib/lib.a $(LIBS) 
 
-ifdef CONFIG_MATH_EMULATION
 SUBDIRS := $(SUBDIRS) arch/parisc/math-emu
-DRIVERS := $(DRIVERS) arch/parisc/math-emu/math.a
-endif
+DRIVERS := $(DRIVERS) arch/parisc/math-emu/math.o
 
 ifdef CONFIG_KWDB
 SUBDIRS := $(SUBDIRS) arch/parisc/kdb
@@ -67,7 +106,7 @@
 	$(MAKE) linuxsubdirs SUBDIRS=arch/parisc/mm
 
 palo: vmlinux
-	export TOPDIR=`pwd`; export CONFIG_STI_CONSOLE=$(CONFIG_STI_CONSOLE); \
+	export TOPDIR=`pwd`; \
 	unset STRIP LDFLAGS CPP CPPFLAGS AFLAGS CFLAGS CC LD; cd ../palo && make lifimage
 
 Image: palo
@@ -84,8 +123,14 @@
 
 install: 
 
+archmrproper:
+	rm -f $(OFFSET_H)
+
 archclean:
 
-archmrproper:
+archdep: $(OFFSET_H)
+
+$(OFFSET_H): include/linux/version.h
+	$(MAKE) -C $(TOPDIR)/arch/$(ARCH)/tools all
 
-archdep:
+.PHONY: $(OFFSET_H)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/config.in linux-bk/arch/parisc/config.in
--- linux-2.4.19/arch/parisc/config.in	2001-04-18 00:19:25.000000000 +0000
+++ linux-bk/arch/parisc/config.in	2002-08-17 00:49:14.000000000 +0000
@@ -52,7 +52,7 @@
 comment 'Loadable module support'
 bool 'Enable loadable module support' CONFIG_MODULES
 if [ "$CONFIG_MODULES" = "y" ]; then
-  bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
+  bool 'Set version information on all module symbols' CONFIG_MODVERSIONS
   bool 'Kernel module loader' CONFIG_KMOD
 fi
 endmenu
@@ -208,3 +208,4 @@
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
 endmenu
 
+source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/defconfig linux-bk/arch/parisc/defconfig
--- linux-2.4.19/arch/parisc/defconfig	2000-12-05 20:29:39.000000000 +0000
+++ linux-bk/arch/parisc/defconfig	2002-08-17 00:48:49.000000000 +0000
@@ -1,8 +1,10 @@
 #
-# Automatically generated by make menuconfig: don't edit
+# Automatically generated make config: don't edit
 #
 CONFIG_PARISC=y
 # CONFIG_UID16 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 
 #
 # Code maturity level options
@@ -10,44 +12,70 @@
 CONFIG_EXPERIMENTAL=y
 
 #
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Processor type
+#
+# CONFIG_PA7100 is not set
+# CONFIG_PA7200 is not set
+# CONFIG_PA7100LC is not set
+# CONFIG_PA8X00 is not set
+# CONFIG_PA11 is not set
+
+#
 # General options
 #
 # CONFIG_SMP is not set
+CONFIG_CHASSIS_LCD_LED=y
 # CONFIG_KWDB is not set
-CONFIG_GSC=y
 CONFIG_IOMMU_CCIO=y
+CONFIG_GSC=y
 CONFIG_GSC_LASI=y
+CONFIG_GSC_WAX=y
+CONFIG_EISA=y
+CONFIG_ISA=y
 CONFIG_PCI=y
 CONFIG_GSC_DINO=y
 CONFIG_PCI_LBA=y
 CONFIG_IOSAPIC=y
 CONFIG_IOMMU_SBA=y
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
+CONFIG_SUPERIO=y
+CONFIG_PCI_NAMES=y
 
 #
 # General setup
 #
+CONFIG_HOTPLUG=y
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
-CONFIG_BINFMT_SOM=y
+CONFIG_KCORE_ELF=y
 CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_SOM=y
 # CONFIG_BINFMT_MISC is not set
-# CONFIG_BINFMT_JAVA is not set
+# CONFIG_PM is not set
 
 #
 # Parallel port support
 #
 CONFIG_PARPORT=y
-# CONFIG_PARPORT_PC is not set
+CONFIG_PARPORT_PC=y
+CONFIG_PARPORT_PC_CML1=y
+# CONFIG_PARPORT_SERIAL is not set
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+# CONFIG_PARPORT_PC_PCMCIA is not set
+# CONFIG_PARPORT_AMIGA is not set
+# CONFIG_PARPORT_MFC3 is not set
+# CONFIG_PARPORT_ATARI is not set
 CONFIG_PARPORT_GSC=y
+# CONFIG_PARPORT_SUNBPP is not set
 # CONFIG_PARPORT_OTHER is not set
 # CONFIG_PARPORT_1284 is not set
 
@@ -60,33 +88,54 @@
 # 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_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_BLK_DEV_INITRD=y
 
 #
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=y
+CONFIG_MD_RAID0=y
+CONFIG_MD_RAID1=y
+CONFIG_MD_RAID5=y
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
 # Networking options
 #
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=y
 # CONFIG_NETFILTER is not set
-# CONFIG_FILTER is not set
+CONFIG_FILTER=y
 CONFIG_UNIX=y
 CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
 CONFIG_IP_PNP_BOOTP=y
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_IPV6 is not set
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
 # CONFIG_DECNET is not set
@@ -106,36 +155,181 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# ATA/IDE/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDEDISK is not set
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
+# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_PCI_WIP is not set
+# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_AEC62XX_TUNING is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_WDC_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_AMD74XX_OVERRIDE is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_HPT34X_AUTODMA is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+CONFIG_BLK_DEV_NS87415=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_PDC202XX is not set
+# CONFIG_PDC202XX_BURST is not set
+# CONFIG_PDC202XX_FORCE is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIS5513 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_DMA_NONPCI is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+
+#
 # SCSI support
 #
 CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
 CONFIG_BLK_DEV_SD=y
 CONFIG_SD_EXTRA_DEVS=40
 CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
 CONFIG_BLK_DEV_SR=y
 # CONFIG_BLK_DEV_SR_VENDOR is not set
 CONFIG_SR_EXTRA_DEVS=2
 CONFIG_CHR_DEV_SG=y
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_DEBUG_QUEUES is not set
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
 
 #
 # SCSI low-level drivers
 #
-CONFIG_SCSI_LASI=y
-CONFIG_SCSI_ZALON=y
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_CPQFCTS is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_DMA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_IMM is not set
+# CONFIG_SCSI_NCR53C406A is not set
+CONFIG_SCSI_LASI700=y
+CONFIG_53C700_MEM_MAPPED=y
+CONFIG_53C700_LE_ON_BE=y
+CONFIG_53C700_USE_CONSISTENT=y
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_NCR53C8XX is not set
 CONFIG_SCSI_SYM53C8XX=y
+CONFIG_SCSI_ZALON=y
 CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
 CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
 CONFIG_SCSI_NCR53C8XX_SYNC=20
 # CONFIG_SCSI_NCR53C8XX_PROFILE is not set
 # CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set
+# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_SCSI_PCMCIA is not set
 
 #
 # Network device support
 #
 CONFIG_NETDEVICES=y
-CONFIG_LASI_82596=y
 
 #
 # ARCnet devices
@@ -145,12 +339,18 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-# CONFIG_NET_SB1000 is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
+CONFIG_LASI_82596=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
 # CONFIG_NET_VENDOR_SMC is not set
@@ -165,23 +365,31 @@
 # CONFIG_AC3200 is not set
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
-# CONFIG_DE4X5 is not set
 CONFIG_TULIP=y
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
+# CONFIG_DE4X5 is not set
 # CONFIG_DGRS is not set
 # CONFIG_DM9102 is not set
 # CONFIG_EEPRO100 is not set
 # CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
-# CONFIG_RTL8129 is not set
+# CONFIG_8139CP is not set
 # CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
 # CONFIG_WINBOND_840 is not set
 # CONFIG_NET_POCKET is not set
 
@@ -189,6 +397,9 @@
 # Ethernet (1000 Mbit)
 #
 # CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
@@ -217,12 +428,27 @@
 # CONFIG_WAN is not set
 
 #
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# Input core support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_KEYBDEV=y
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+
+#
 # Character devices
 #
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_GSC_PS2=y
-CONFIG_HIL=y
 CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
 CONFIG_SERIAL_GSC=y
@@ -243,12 +469,45 @@
 # Mice
 #
 # CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+CONFIG_INPUT_SERIO=y
+# CONFIG_INPUT_SERPORT is not set
 
 #
 # Joysticks
 #
-# CONFIG_JOYSTICK is not set
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
 # CONFIG_QIC02_TAPE is not set
 
 #
@@ -271,27 +530,67 @@
 # CONFIG_DRM is not set
 
 #
+# PCMCIA character devices
+#
+# CONFIG_PCMCIA_SERIAL_CS is not set
+
+#
+# HIL support
+#
+CONFIG_HIL=y
+# CONFIG_HIL_KBD_BASIC is not set
+
+#
+#  HIL driver core support
+#
+CONFIG_HP_SDC=y
+# CONFIG_HP_SDC_RTC is not set
+CONFIG_HIL_MLC=y
+CONFIG_HP_SDC_MLC=y
+
+#
+#  HIL device driver
+#
+CONFIG_HIL_KBD=y
+CONFIG_HIL_PTR=y
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # File systems
 #
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO 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_EXT3_FS=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG 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_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
 # CONFIG_RAMFS is not set
 CONFIG_ISO9660_FS=y
-# CONFIG_JOLIET is not set
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
@@ -299,13 +598,12 @@
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVFS_MOUNT is not set
 # CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS is not set
+CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_QNX4FS_RW is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_EXT2_FS=y
 # CONFIG_SYSV_FS is not set
-# CONFIG_SYSV_FS_WRITE is not set
 # CONFIG_UDF_FS is not set
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
@@ -315,13 +613,15 @@
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
+CONFIG_NFS_V3=y
 CONFIG_ROOT_NFS=y
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
 # CONFIG_SMB_FS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_NCPFS_PACKET_SIGNING is not set
@@ -330,22 +630,60 @@
 # 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
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-# CONFIG_NLS is not set
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
 
 #
-# Sound Drivers
+# Native Language Support
 #
-# CONFIG_SOUND is not set
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
 
 #
 # Console drivers
@@ -354,8 +692,171 @@
 #
 # Frame-buffer support
 #
-# CONFIG_FB is not set
-# CONFIG_STI_CONSOLE is not set
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_CLGEN is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+CONFIG_FB_STI=y
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB32=y
+CONFIG_FBCON_STI=y
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_STI_CONSOLE=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FBCON=y
+CONFIG_FBCON_FONT=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_6x11=y
+CONFIG_FONT_SUN12x22=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_ICH is not set
+CONFIG_SOUND_HARMONY=y
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+# CONFIG_SOUND_OSS is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+# CONFIG_USB_HID is not set
+# CONFIG_USB_HIDDEV is not set
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_WACOM is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
 
 #
 # Kernel hacking
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/hpux/Makefile linux-bk/arch/parisc/hpux/Makefile
--- linux-2.4.19/arch/parisc/hpux/Makefile	2000-12-05 20:29:39.000000000 +0000
+++ linux-bk/arch/parisc/hpux/Makefile	2002-08-17 00:48:57.000000000 +0000
@@ -7,10 +7,7 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-all: hpux.o
 O_TARGET = hpux.o
-O_OBJS = entry_hpux.o gate.o wrappers.o fs.o ioctl.o sys_hpux.o
-
-.o.S:	$(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $*.S -o $*.o
+obj-y := entry_hpux.o gate.o wrappers.o fs.o ioctl.o sys_hpux.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/hpux/entry_hpux.S linux-bk/arch/parisc/hpux/entry_hpux.S
--- linux-2.4.19/arch/parisc/hpux/entry_hpux.S	2001-10-05 19:22:07.000000000 +0000
+++ linux-bk/arch/parisc/hpux/entry_hpux.S	2002-08-17 00:49:01.000000000 +0000
@@ -1,6 +1,6 @@
-/* -----------------------------------------------------------------------------
+/*
  *
- * Native PARISC/Linux Project (http://www.puffingroup.com/parisc)
+ * Linux/PARISC Project (http://www.parisc-linux.org/)
  *
  * modified by Matthew Wilcox <willy@bofh.ai> 1999-07-26
  */
@@ -10,13 +10,13 @@
 #include <linux/linkage.h>
 #include <asm/unistd.h>
 
-
 	.text
 
 #define ENTRY_NAME(_name_) .word _name_
 
 	.align 4
 	.export hpux_call_table
+	.import hpux_unimplemented_wrapper
 hpux_call_table:
 	ENTRY_NAME(sys_ni_syscall)	/* 0 */
 	ENTRY_NAME(sys_exit)
@@ -36,7 +36,7 @@
 	ENTRY_NAME(sys_chmod)	/* 15 */
 	ENTRY_NAME(sys_chown)
 	ENTRY_NAME(hpux_brk)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_lseek)
 	ENTRY_NAME(sys_getpid)	/* 20 */
 	ENTRY_NAME(hpux_mount)
@@ -46,34 +46,34 @@
 	ENTRY_NAME(sys_stime)	/* 25 */
 	ENTRY_NAME(hpux_ptrace)
 	ENTRY_NAME(sys_alarm)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_pause)
 	ENTRY_NAME(sys_utime)	/* 30 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_access)
 	ENTRY_NAME(hpux_nice)
-	ENTRY_NAME(sys_ni_syscall)	/* 35 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 35 */
 	ENTRY_NAME(sys_sync)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_newstat)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_setpgrp3)
 	ENTRY_NAME(sys_newlstat)	/* 40 */
 	ENTRY_NAME(sys_dup)
 	ENTRY_NAME(hpux_pipe_wrapper)
 	ENTRY_NAME(sys_times)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 45 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 45 */
 	ENTRY_NAME(sys_setgid)
 	ENTRY_NAME(sys_getgid)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 50 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 50 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(hpux_ioctl)
-	ENTRY_NAME(sys_ni_syscall)	/* 55 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 55 */
 	ENTRY_NAME(sys_symlink)
 	ENTRY_NAME(hpux_utssys)
 	ENTRY_NAME(sys_readlink)
@@ -81,218 +81,218 @@
 	ENTRY_NAME(sys_umask)	/* 60 */
 	ENTRY_NAME(sys_chroot)
 	ENTRY_NAME(sys_fcntl)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 65 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 65 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(hpux_sbrk)
-	ENTRY_NAME(sys_ni_syscall)	/* 70 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 70 */
 	ENTRY_NAME(sys_mmap)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 75 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 80 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 75 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 80 */
 	ENTRY_NAME(sys_getpgid)
 	ENTRY_NAME(sys_setpgid)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 85 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(sys_setitimer)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 85 */
+	ENTRY_NAME(sys_getitimer)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_dup2)		/* 90 */
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_newfstat)
 	ENTRY_NAME(sys_select)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 95 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 100 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 105 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 110 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 115 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 95 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 100 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 105 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 110 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 115 */
 	ENTRY_NAME(sys_gettimeofday)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 120 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 120 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_fchown)
 	ENTRY_NAME(sys_fchmod)
-	ENTRY_NAME(sys_ni_syscall)	/* 125 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 125 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_rename)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 130 */
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 130 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(hpux_sysconf)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 135 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 135 */
 	ENTRY_NAME(sys_mkdir)
 	ENTRY_NAME(sys_rmdir)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 140 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 145 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 150 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 155 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 160 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 165 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 170 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 175 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 180 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 185 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 190 */
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 140 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(sys_getrlimit)
+	ENTRY_NAME(sys_setrlimit)      /* 145 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 150 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_lockf)      /* 155 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 160 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 165 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 170 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 175 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 180 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(sys_sigprocmask)      /* 185 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 190 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(hpux_getdomainname)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 195 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 195 */
+	ENTRY_NAME(hpux_statfs)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_waitpid)	/* 200 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 205 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 210 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 215 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 220 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 225 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 230 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 235 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 240 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 245 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 250 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 255 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 260 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 265 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 270 */
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 205 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 210 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 215 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 220 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 225 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 230 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 235 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 240 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 245 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 250 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 255 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 260 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 265 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 270 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_fchdir)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_accept)		/* 275 */
 	ENTRY_NAME(sys_bind)
 	ENTRY_NAME(sys_connect)
@@ -309,227 +309,227 @@
 	ENTRY_NAME(sys_setsockopt)
 	ENTRY_NAME(sys_shutdown)
 	ENTRY_NAME(sys_socket)		/* 290 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 295 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 300 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 305 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 310 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 315 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 320 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 325 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 330 */
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 295 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 300 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 305 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 310 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 315 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 320 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 325 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 330 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_lchown)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 335 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 340 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 345 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 350 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_sysfs)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 335 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 340 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 345 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 350 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_nanosleep)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 355 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 355 */
 	ENTRY_NAME(hpux_getdents)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 360 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 360 */
 	ENTRY_NAME(hpux_fstat64)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 365 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 365 */
 	ENTRY_NAME(hpux_lstat64)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(hpux_stat64)
-	ENTRY_NAME(sys_ni_syscall)	/* 370 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 375 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 380 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 385 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 390 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 395 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 400 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 405 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 410 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 415 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 420 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 425 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 430 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 435 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 440 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 445 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 450 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 455 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 460 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 465 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 470 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 475 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 480 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 485 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 490 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 495 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 500 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 505 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 510 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 370 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 375 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 380 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_setpgrp)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 385 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 390 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 395 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 400 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 405 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 410 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 415 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 420 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 425 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 430 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 435 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 440 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 445 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 450 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 455 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 460 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 465 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 470 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 475 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 480 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 485 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 490 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 495 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 500 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 505 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 510 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 .end
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/hpux/fs.c linux-bk/arch/parisc/hpux/fs.c
--- linux-2.4.19/arch/parisc/hpux/fs.c	2001-08-12 22:07:55.000000000 +0000
+++ linux-bk/arch/parisc/hpux/fs.c	2002-08-17 00:48:55.000000000 +0000
@@ -52,7 +52,8 @@
 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
 #define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1))
 
-static int filldir(void * __buf, const char * name, int namlen, loff_t offset, ino_t ino)
+static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
+		ino_t ino, unsigned int d_type)
 {
 	struct hpux_dirent * dirent;
 	struct getdents_callback * buf = (struct getdents_callback *) __buf;
@@ -83,42 +84,21 @@
 int hpux_getdents(unsigned int fd, struct hpux_dirent *dirent, unsigned int count)
 {
 	struct file * file;
-	struct dentry * dentry;
-	struct inode * inode;
 	struct hpux_dirent * lastdirent;
 	struct getdents_callback buf;
 	int error;
 
-	lock_kernel();
 	error = -EBADF;
 	file = fget(fd);
 	if (!file)
 		goto out;
 
-	dentry = file->f_dentry;
-	if (!dentry)
-		goto out_putf;
-
-	inode = dentry->d_inode;
-	if (!inode)
-		goto out_putf;
-
 	buf.current_dir = dirent;
 	buf.previous = NULL;
 	buf.count = count;
 	buf.error = 0;
 
-	error = -ENOTDIR;
-	if (!file->f_op || !file->f_op->readdir)
-		goto out_putf;
-
-	/*
-	 * Get the inode's semaphore to prevent changes
-	 * to the directory while we read it.
-	 */
-	down(&inode->i_sem);
-	error = file->f_op->readdir(file, &buf, filldir);
-	up(&inode->i_sem);
+	error = vfs_readdir(file, filldir, &buf);
 	if (error < 0)
 		goto out_putf;
 	error = buf.error;
@@ -131,7 +111,6 @@
 out_putf:
 	fput(file);
 out:
-	unlock_kernel();
 	return error;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/hpux/gate.S linux-bk/arch/parisc/hpux/gate.S
--- linux-2.4.19/arch/parisc/hpux/gate.S	2000-12-06 19:46:39.000000000 +0000
+++ linux-bk/arch/parisc/hpux/gate.S	2002-08-17 00:48:52.000000000 +0000
@@ -1,6 +1,6 @@
-/* ------------------------------------------------------------------------------
+/*
  *
- * Linux/PARISC Project (http://www.thepuffingroup.com/parisc)
+ * Linux/PARISC Project (http://www.parisc-linux.org/)
  *
  * System call entry code Copyright (c) Matthew Wilcox 1999 <willy@bofh.ai>
  * Licensed under the GNU GPL.
@@ -8,14 +8,23 @@
  * sorry about the wall, puffin..
  */
 
-#define __ASSEMBLY__
 #include <asm/assembly.h>
 #include <asm/offset.h>
 #include <asm/unistd.h>
 #include <asm/errno.h>
 
+#ifdef __LP64__
+	.level          2.0w
+#else
+	.level		1.1
+#endif
 	.text
 
+#ifdef __LP64__
+#define FRAME_SIZE	128
+#else
+#define FRAME_SIZE	64
+#endif
 	.import hpux_call_table
 	.import hpux_syscall_exit,code
 	.export hpux_gateway_page
@@ -23,35 +32,70 @@
 	.align 4096
 hpux_gateway_page:
 	nop
-	mfsp	%sr7,%r1			;! we must set sr3 to the space
-	mtsp	%r1,%sr3			;! of the user before the gate
 #ifdef __LP64__
 #warning NEEDS WORK for 64-bit
 #endif
-	ldw	-64(%r30), %r28			;! 8th argument
+	ldw     -64(%r30), %r29                 ;! 8th argument
 	ldw	-60(%r30), %r19			;! 7th argument
 	ldw	-56(%r30), %r20			;! 6th argument
 	ldw	-52(%r30), %r21			;! 5th argument
-	gate	.+8, %r0			;! become privileged
-	mtsp	%r0,%sr4			;! get kernel space into sr4
-	mtsp	%r0,%sr5			;! get kernel space into sr5
-	mtsp	%r0,%sr6			;! get kernel space into sr6
-	mtsp	%r0,%sr7			;! get kernel space into sr7
-	mfctl	%cr30,%r1			;! get the kernel task ptr
-	mtctl	%r0,%cr30			;! zero it (flag)
-	STREG	%r30,TASK_PT_GR30(%r1)		;! preserve userspace sp
-	STREG	%r2,TASK_PT_GR2(%r1)		;! preserve rp
-	STREG	%r27,TASK_PT_GR27(%r1)		;! user dp
-	STREG	%r31,TASK_PT_GR31(%r1)		;! preserve syscall return ptr
+	gate	.+8, %r0			/* become privileged */
+	mtsp	%r0,%sr4			/* get kernel space into sr4 */
+	mtsp	%r0,%sr5			/* get kernel space into sr5 */
+	mtsp	%r0,%sr6			/* get kernel space into sr6 */
+	mfsp    %sr7,%r1                        /* save user sr7 */
+	mtsp    %r1,%sr3                        /* and store it in sr3 */
+
+	mtctl   %r30,%cr28
+	mfctl   %cr30,%r1
+	xor     %r1,%r30,%r30                   /* ye olde xor trick */
+	xor     %r1,%r30,%r1
+	xor     %r1,%r30,%r30
+	ldo     TASK_SZ_ALGN+FRAME_SIZE(%r30),%r30  /* set up kernel stack */
+
+	/* N.B.: It is critical that we don't set sr7 to 0 until r30
+	 *       contains a valid kernel stack pointer. It is also
+	 *       critical that we don't start using the kernel stack
+	 *       until after sr7 has been set to 0.
+	 */
+
+	mtsp	%r0,%sr7			/* get kernel space into sr7 */
+	STREG   %r1,TASK_PT_GR30-TASK_SZ_ALGN-FRAME_SIZE(%r30) /* save usp */
+	ldo     -TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1   /* get task ptr in %r1 */
+
+	/* Save some registers for sigcontext and potential task
+	   switch (see entry.S for the details of which ones are
+	   saved/restored).  TASK_PT_PSW is zeroed so we can see whether
+	   a process is on a syscall or not.  For an interrupt the real
+	   PSW value is stored.  This is needed for gdb and sys_ptrace. */
+	STREG	%r0,  TASK_PT_PSW(%r1)
+	STREG	%r2,  TASK_PT_GR2(%r1)		/* preserve rp */
+	STREG   %r19, TASK_PT_GR19(%r1)         /* 7th argument */
+	STREG   %r20, TASK_PT_GR20(%r1)         /* 6th argument */
+	STREG   %r21, TASK_PT_GR21(%r1)         /* 5th argument */
+	STREG   %r22, TASK_PT_GR22(%r1)         /* syscall # */
+	STREG	%r23, TASK_PT_GR23(%r1)		/* 4th argument */
+	STREG	%r24, TASK_PT_GR24(%r1)		/* 3rd argument */
+	STREG	%r25, TASK_PT_GR25(%r1)		/* 2nd argument */
+	STREG	%r26, TASK_PT_GR26(%r1)	 	/* 1st argument */
+	STREG	%r27, TASK_PT_GR27(%r1)		/* user dp */
+	STREG   %r28, TASK_PT_GR28(%r1)         /* return value 0 */
+	STREG   %r28, TASK_PT_ORIG_R28(%r1)     /* return value 0 (saved for signals) */
+	STREG   %r29, TASK_PT_GR29(%r1)         /* 8th argument */
+	STREG	%r31, TASK_PT_GR31(%r1)		/* preserve syscall return ptr */
+	
+	ldo	TASK_PT_FR0(%r1), %r27		/* save fpregs from the kernel */
+	save_fp	%r27				/* or potential task switch  */
 
-	loadgp					;! setup kernel dp
+	mfctl	%cr11, %r27			/* i.e. SAR */
+	STREG	%r27, TASK_PT_SAR(%r1)
 
-	ldo	TASK_SZ_ALGN+64(%r1),%r30	;! set up kernel stack
+	loadgp
 
 	stw	%r21, -52(%r30)			;! 5th argument
 	stw	%r20, -56(%r30)			;! 6th argument
 	stw	%r19, -60(%r30)			;! 7th argument
-	stw	%r28, -64(%r30)			;! 8th argument
+	stw     %r29, -64(%r30)                 ;! 8th argument
 
 	ldil	L%hpux_call_table, %r21
 	ldo	R%hpux_call_table(%r21), %r21
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/hpux/ioctl.c linux-bk/arch/parisc/hpux/ioctl.c
--- linux-2.4.19/arch/parisc/hpux/ioctl.c	2000-12-05 20:29:39.000000000 +0000
+++ linux-bk/arch/parisc/hpux/ioctl.c	2002-08-17 00:48:55.000000000 +0000
@@ -19,6 +19,7 @@
  *   TIOCSPGRP
  */
 
+#include <linux/sched.h>
 #include <linux/smp_lock.h>
 #include <asm/errno.h>
 #include <asm/ioctl.h>
@@ -54,10 +55,6 @@
 	case 't':
 		result = hpux_ioctl_t(fd, cmd, arg);
 		break;
-	default:
-		/* If my mother ever sees this, I hope she disowns me.
-		 * Take this out after NYLWE. */
-		result = sys_ioctl(fd, cmd, arg);
 	}
 	return result;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/hpux/sys_hpux.c linux-bk/arch/parisc/hpux/sys_hpux.c
--- linux-2.4.19/arch/parisc/hpux/sys_hpux.c	2001-08-09 23:41:36.000000000 +0000
+++ linux-bk/arch/parisc/hpux/sys_hpux.c	2002-08-17 00:49:09.000000000 +0000
@@ -9,6 +9,9 @@
 #include <linux/utsname.h>
 #include <asm/errno.h>
 #include <asm/uaccess.h>
+#include <linux/vmalloc.h>
+#include <asm/pgalloc.h>
+#include <linux/slab.h>
 
 unsigned long sys_brk(unsigned long addr);
  
@@ -41,6 +44,17 @@
 	return sys_waitpid(-1, stat_loc, 0);
 }
 
+int hpux_setpgrp(void)
+{
+	extern int sys_setpgid(int, int);
+	return sys_setpgid(0,0);
+}
+
+int hpux_setpgrp3(void)
+{
+	return hpux_setpgrp();
+}
+
 #define _SC_CPU_VERSION	10001
 #define _SC_OPEN_MAX	4
 #define CPU_PA_RISC1_1	0x210
@@ -129,6 +143,66 @@
 	return err;
 }
 
+/*
+ * Wrapper for hpux statfs call. At the moment, just calls the linux native one
+ * and ignores the extra fields at the end of the hpux statfs struct.
+ *
+ */
+
+typedef int32_t hpux_fsid_t[2];              /* file system ID type */
+typedef uint16_t hpux_site_t;
+
+struct hpux_statfs {
+     int32_t f_type;                    /* type of info, zero for now */
+     int32_t f_bsize;                   /* fundamental file system block size */
+     int32_t f_blocks;                  /* total blocks in file system */
+     int32_t f_bfree;                   /* free block in fs */
+     int32_t f_bavail;                  /* free blocks avail to non-superuser */
+     int32_t f_files;                   /* total file nodes in file system */
+     int32_t f_ffree;                   /* free file nodes in fs */
+     hpux_fsid_t  f_fsid;                    /* file system ID */
+     int32_t f_magic;                   /* file system magic number */
+     int32_t f_featurebits;             /* file system features */
+     int32_t f_spare[4];                /* spare for later */
+     hpux_site_t  f_cnode;                   /* cluster node where mounted */
+     int16_t f_pad;
+};
+
+/* hpux statfs */
+int hpux_statfs(const char *path, struct hpux_statfs *buf)
+{
+	int error;
+	int len;
+	char *kpath;
+
+	len = strlen_user((char *)path); 
+
+	kpath = (char *) kmalloc(len+1, GFP_KERNEL);
+	if ( !kpath ) {
+	printk(KERN_DEBUG "failed to kmalloc kpath\n");
+	return 0;
+	}
+
+	if ( copy_from_user(kpath, (char *)path, len+1) ) {
+	printk(KERN_DEBUG "failed to copy_from_user kpath\n");
+	kfree(kpath);
+	return 0;
+	}
+
+	printk(KERN_DEBUG "hpux_statfs(\"%s\",-)\n", kpath);
+
+	kfree(kpath);
+
+	/* just fake it, beginning of structures match */
+	extern int sys_statfs(const char *, struct statfs *);
+	error = sys_statfs(path, (struct statfs *) buf);
+
+	/* ignoring rest of statfs struct, but it should be zeros. Need to do 
+		something with f_fsid[1], which is the fstype for sysfs */
+
+	return error;
+}
+
 
 /*  This function is called from hpux_utssys(); HP-UX implements
  *  uname() as an option to utssys().
@@ -333,3 +407,541 @@
 	unlock_kernel();
 	return error;
 }
+
+/* lies - says it works, but it really didn't lock anything */
+int hpux_lockf(int fildes, int function, off_t size)
+{
+	return 0;
+}
+
+int hpux_sysfs(int opcode, unsigned long arg1, unsigned long arg2)
+{
+	char *fsname = NULL;
+	int len = 0;
+	int fstype;
+
+/*Unimplemented HP-UX syscall emulation. Syscall #334 (sysfs)
+  Args: 1 80057bf4 0 400179f0 0 0 0 */
+	printk(KERN_DEBUG "in hpux_sysfs\n");
+	printk(KERN_DEBUG "hpux_sysfs called with opcode = %d\n", opcode);
+	printk(KERN_DEBUG "hpux_sysfs called with arg1='%lx'\n", arg1);
+
+	if ( opcode == 1 ) { /* GETFSIND */	
+		len = strlen_user((char *)arg1);
+		printk(KERN_DEBUG "len of arg1 = %d\n", len);
+
+		fsname = (char *) kmalloc(len+1, GFP_KERNEL);
+		if ( !fsname ) {
+			printk(KERN_DEBUG "failed to kmalloc fsname\n");
+			return 0;
+		}
+
+		if ( copy_from_user(fsname, (char *)arg1, len+1) ) {
+			printk(KERN_DEBUG "failed to copy_from_user fsname\n");
+			kfree(fsname);
+			return 0;
+		}
+
+		printk(KERN_DEBUG "that is '%s' as (char *)\n", fsname);
+		if ( !strcmp(fsname, "hfs") ) {
+			fstype = 0;
+		} else {
+			fstype = 0;
+		};
+
+		kfree(fsname);
+
+		printk(KERN_DEBUG "returning fstype=%d\n", fstype);
+		return fstype; /* something other than default */
+	}
+
+
+	return 0;
+}
+
+
+/* Table of syscall names and handle for unimplemented routines */
+static const char *syscall_names[] = {
+	"nosys",                  /* 0 */
+	"exit",                  
+	"fork",                  
+	"read",                  
+	"write",                 
+	"open",                   /* 5 */
+	"close",                 
+	"wait",                  
+	"creat",                 
+	"link",                  
+	"unlink",                 /* 10 */
+	"execv",                 
+	"chdir",                 
+	"time",                  
+	"mknod",                 
+	"chmod",                  /* 15 */
+	"chown",                 
+	"brk",                   
+	"lchmod",                
+	"lseek",                 
+	"getpid",                 /* 20 */
+	"mount",                 
+	"umount",                
+	"setuid",                
+	"getuid",                
+	"stime",                  /* 25 */
+	"ptrace",                
+	"alarm",                 
+	NULL,                    
+	"pause",                 
+	"utime",                  /* 30 */
+	"stty",                  
+	"gtty",                  
+	"access",                
+	"nice",                  
+	"ftime",                  /* 35 */
+	"sync",                  
+	"kill",                  
+	"stat",                  
+	"setpgrp3",              
+	"lstat",                  /* 40 */
+	"dup",                   
+	"pipe",                  
+	"times",                 
+	"profil",                
+	"ki_call",                /* 45 */
+	"setgid",                
+	"getgid",                
+	NULL,                    
+	NULL,                    
+	NULL,                     /* 50 */
+	"acct",                  
+	"set_userthreadid",      
+	NULL,                    
+	"ioctl",                 
+	"reboot",                 /* 55 */
+	"symlink",               
+	"utssys",                
+	"readlink",              
+	"execve",                
+	"umask",                  /* 60 */
+	"chroot",                
+	"fcntl",                 
+	"ulimit",                
+	NULL,                    
+	NULL,                     /* 65 */
+	"vfork",                 
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                     /* 70 */
+	"mmap",                  
+	NULL,                    
+	"munmap",                
+	"mprotect",              
+	"madvise",                /* 75 */
+	"vhangup",               
+	"swapoff",               
+	NULL,                    
+	"getgroups",             
+	"setgroups",              /* 80 */
+	"getpgrp2",              
+	"setpgid/setpgrp2",      
+	"setitimer",             
+	"wait3",                 
+	"swapon",                 /* 85 */
+	"getitimer",             
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	"dup2",                   /* 90 */
+	NULL,                    
+	"fstat",                 
+	"select",                
+	NULL,                    
+	"fsync",                  /* 95 */
+	"setpriority",           
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	"getpriority",            /* 100 */
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                     /* 105 */
+	NULL,                    
+	NULL,                    
+	"sigvector",             
+	"sigblock",              
+	"sigsetmask",             /* 110 */
+	"sigpause",              
+	"sigstack",              
+	NULL,                    
+	NULL,                    
+	NULL,                     /* 115 */
+	"gettimeofday",          
+	"getrusage",             
+	NULL,                    
+	NULL,                    
+	"readv",                  /* 120 */
+	"writev",                
+	"settimeofday",          
+	"fchown",                
+	"fchmod",                
+	NULL,                     /* 125 */
+	"setresuid",             
+	"setresgid",             
+	"rename",                
+	"truncate",              
+	"ftruncate",              /* 130 */
+	NULL,                    
+	"sysconf",               
+	NULL,                    
+	NULL,                    
+	NULL,                     /* 135 */
+	"mkdir",                 
+	"rmdir",                 
+	NULL,                    
+	"sigcleanup",            
+	"setcore",                /* 140 */
+	NULL,                    
+	"gethostid",             
+	"sethostid",             
+	"getrlimit",             
+	"setrlimit",              /* 145 */
+	NULL,                    
+	NULL,                    
+	"quotactl",              
+	"get_sysinfo",           
+	NULL,                     /* 150 */
+	"privgrp",               
+	"rtprio",                
+	"plock",                 
+	NULL,                    
+	"lockf",                  /* 155 */
+	"semget",                
+	NULL,                    
+	"semop",                 
+	"msgget",                
+	NULL,                     /* 160 */
+	"msgsnd",                
+	"msgrcv",                
+	"shmget",                
+	NULL,                    
+	"shmat",                  /* 165 */
+	"shmdt",                 
+	NULL,                    
+	"csp/nsp_init",          
+	"cluster",               
+	"mkrnod",                 /* 170 */
+	"test",                  
+	"unsp_open",             
+	NULL,                    
+	"getcontext",            
+	"osetcontext",            /* 175 */
+	"bigio",                 
+	"pipenode",              
+	"lsync",                 
+	"getmachineid",          
+	"cnodeid/mysite",         /* 180 */
+	"cnodes/sitels",         
+	"swapclients",           
+	"rmtprocess",            
+	"dskless_stats",         
+	"sigprocmask",            /* 185 */
+	"sigpending",            
+	"sigsuspend",            
+	"sigaction",             
+	NULL,                    
+	"nfssvc",                 /* 190 */
+	"getfh",                 
+	"getdomainname",         
+	"setdomainname",         
+	"async_daemon",          
+	"getdirentries",          /* 195 */
+	"statfs",                
+	"fstatfs",               
+	"vfsmount",              
+	NULL,                    
+	"waitpid",                /* 200 */
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                     /* 205 */
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                     /* 210 */
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                     /* 215 */
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                     /* 220 */
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	"sigsetreturn",          
+	"sigsetstatemask",        /* 225 */
+	"bfactl",                
+	"cs",                    
+	"cds",                   
+	NULL,                    
+	"pathconf",               /* 230 */
+	"fpathconf",             
+	NULL,                    
+	NULL,                    
+	"nfs_fcntl",             
+	"ogetacl",                /* 235 */
+	"ofgetacl",              
+	"osetacl",               
+	"ofsetacl",              
+	"pstat",                 
+	"getaudid",               /* 240 */
+	"setaudid",              
+	"getaudproc",            
+	"setaudproc",            
+	"getevent",              
+	"setevent",               /* 245 */
+	"audwrite",              
+	"audswitch",             
+	"audctl",                
+	"ogetaccess",            
+	"fsctl",                  /* 250 */
+	"ulconnect",             
+	"ulcontrol",             
+	"ulcreate",              
+	"uldest",                
+	"ulrecv",                 /* 255 */
+	"ulrecvcn",              
+	"ulsend",                
+	"ulshutdown",            
+	"swapfs",                
+	"fss",                    /* 260 */
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                     /* 265 */
+	NULL,                    
+	"tsync",                 
+	"getnumfds",             
+	"poll",                  
+	"getmsg",                 /* 270 */
+	"putmsg",                
+	"fchdir",                
+	"getmount_cnt",          
+	"getmount_entry",        
+	"accept",                 /* 275 */
+	"bind",                  
+	"connect",               
+	"getpeername",           
+	"getsockname",           
+	"getsockopt",             /* 280 */
+	"listen",                
+	"recv",                  
+	"recvfrom",              
+	"recvmsg",               
+	"send",                   /* 285 */
+	"sendmsg",               
+	"sendto",                
+	"setsockopt",            
+	"shutdown",              
+	"socket",                 /* 290 */
+	"socketpair",            
+	"proc_open",             
+	"proc_close",            
+	"proc_send",             
+	"proc_recv",              /* 295 */
+	"proc_sendrecv",         
+	"proc_syscall",          
+	"ipccreate",             
+	"ipcname",               
+	"ipcnamerase",            /* 300 */
+	"ipclookup",             
+	"ipcselect",             
+	"ipcconnect",            
+	"ipcrecvcn",             
+	"ipcsend",                /* 305 */
+	"ipcrecv",               
+	"ipcgetnodename",        
+	"ipcsetnodename",        
+	"ipccontrol",            
+	"ipcshutdown",            /* 310 */
+	"ipcdest",               
+	"semctl",                
+	"msgctl",                
+	"shmctl",                
+	"mpctl",                  /* 315 */
+	"exportfs",              
+	"getpmsg",               
+	"putpmsg",               
+	"strioctl",              
+	"msync",                  /* 320 */
+	"msleep",                
+	"mwakeup",               
+	"msem_init",             
+	"msem_remove",           
+	"adjtime",                /* 325 */
+	"kload",                 
+	"fattach",               
+	"fdetach",               
+	"serialize",             
+	"statvfs",                /* 330 */
+	"fstatvfs",              
+	"lchown",                
+	"getsid",                
+	"sysfs",                 
+	NULL,                     /* 335 */
+	NULL,                    
+	"sched_setparam",        
+	"sched_getparam",        
+	"sched_setscheduler",    
+	"sched_getscheduler",     /* 340 */
+	"sched_yield",           
+	"sched_get_priority_max",
+	"sched_get_priority_min",
+	"sched_rr_get_interval", 
+	"clock_settime",          /* 345 */
+	"clock_gettime",         
+	"clock_getres",          
+	"timer_create",          
+	"timer_delete",          
+	"timer_settime",          /* 350 */
+	"timer_gettime",         
+	"timer_getoverrun",      
+	"nanosleep",             
+	"toolbox",               
+	NULL,                     /* 355 */
+	"getdents",              
+	"getcontext",            
+	"sysinfo",               
+	"fcntl64",               
+	"ftruncate64",            /* 360 */
+	"fstat64",               
+	"getdirentries64",       
+	"getrlimit64",           
+	"lockf64",               
+	"lseek64",                /* 365 */
+	"lstat64",               
+	"mmap64",                
+	"setrlimit64",           
+	"stat64",                
+	"truncate64",             /* 370 */
+	"ulimit64",              
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                     /* 375 */
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	"setcontext",             /* 380 */
+	"sigaltstack",           
+	"waitid",                
+	"setpgrp",               
+	"recvmsg2",              
+	"sendmsg2",               /* 385 */
+	"socket2",               
+	"socketpair2",           
+	"setregid",              
+	"lwp_create",            
+	"lwp_terminate",          /* 390 */
+	"lwp_wait",              
+	"lwp_suspend",           
+	"lwp_resume",            
+	"lwp_self",              
+	"lwp_abort_syscall",      /* 395 */
+	"lwp_info",              
+	"lwp_kill",              
+	"ksleep",                
+	"kwakeup",               
+	"ksleep_abort",           /* 400 */
+	"lwp_proc_info",         
+	"lwp_exit",              
+	"lwp_continue",          
+	"getacl",                
+	"fgetacl",                /* 405 */
+	"setacl",                
+	"fsetacl",               
+	"getaccess",             
+	"lwp_mutex_init",        
+	"lwp_mutex_lock_sys",     /* 410 */
+	"lwp_mutex_unlock",      
+	"lwp_cond_init",         
+	"lwp_cond_signal",       
+	"lwp_cond_broadcast",    
+	"lwp_cond_wait_sys",      /* 415 */
+	"lwp_getscheduler",      
+	"lwp_setscheduler",      
+	"lwp_getprivate",        
+	"lwp_setprivate",        
+	"lwp_detach",             /* 420 */
+	"mlock",                 
+	"munlock",               
+	"mlockall",              
+	"munlockall",            
+	"shm_open",               /* 425 */
+	"shm_unlink",            
+	"sigqueue",              
+	"sigwaitinfo",           
+	"sigtimedwait",          
+	"sigwait",                /* 430 */
+	"aio_read",              
+	"aio_write",             
+	"lio_listio",            
+	"aio_error",             
+	"aio_return",             /* 435 */
+	"aio_cancel",            
+	"aio_suspend",           
+	"aio_fsync",             
+	"mq_open",               
+	"mq_unlink",              /* 440 */
+	"mq_send",               
+	"mq_receive",            
+	"mq_notify",             
+	"mq_setattr",            
+	"mq_getattr",             /* 445 */
+	"ksem_open",             
+	"ksem_unlink",           
+	"ksem_close",            
+	"ksem_destroy",          
+	"lw_sem_incr",            /* 450 */
+	"lw_sem_decr",           
+	"lw_sem_read",           
+	"mq_close",              
+};
+static const int syscall_names_max = 453;
+
+int
+hpux_unimplemented(unsigned long arg1,unsigned long arg2,unsigned long arg3,
+		   unsigned long arg4,unsigned long arg5,unsigned long arg6,
+		   unsigned long arg7,unsigned long sc_num)
+{
+	/* NOTE: sc_num trashes arg8 for the few syscalls that actually
+	 * have a valid 8th argument.
+	 */
+	const char *name = NULL;
+	if ( sc_num <= syscall_names_max && sc_num >= 0 ) {
+		name = syscall_names[sc_num];
+	}
+
+	if ( name ) {
+		printk(KERN_DEBUG "Unimplemented HP-UX syscall emulation. Syscall #%lu (%s)\n",
+		sc_num, name);
+	} else {
+		printk(KERN_DEBUG "Unimplemented unknown HP-UX syscall emulation. Syscall #%lu\n",
+		sc_num);
+	}
+	
+	printk(KERN_DEBUG "  Args: %lx %lx %lx %lx %lx %lx %lx\n",
+		arg1, arg2, arg3, arg4, arg5, arg6, arg7);
+
+	return -ENOSYS;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/hpux/wrappers.S linux-bk/arch/parisc/hpux/wrappers.S
--- linux-2.4.19/arch/parisc/hpux/wrappers.S	2000-12-05 20:29:39.000000000 +0000
+++ linux-bk/arch/parisc/hpux/wrappers.S	2002-08-17 00:49:01.000000000 +0000
@@ -1,5 +1,5 @@
-/*------------------------------------------------------------------------------
- * Native PARISC/Linux Project (http://www.puffingroup.com/parisc)
+/*
+ * Linux/PARISC Project (http://www.parisc-linux.org/)
  *
  * HP-UX System Call Wrapper routines and System Call Return Path
  *
@@ -29,7 +29,6 @@
 	.level		1.1
 	.text
 
-#define __ASSEMBLY__
 #include <asm/assembly.h>
 #include <asm/signal.h>
 
@@ -81,6 +80,7 @@
 
 
 	.export hpux_fork_wrapper
+	.export hpux_child_return
 	.import sys_fork
 
 hpux_fork_wrapper:
@@ -91,12 +91,10 @@
 	stw	%r2,-20(%r30)
 	ldo	64(%r30),%r30
 	stw	%r2,PT_GR19(%r1)	;! save for child
-	stw	%r30,PT_GR20(%r1)	;! save for child
-	ldil	L%child_return,%r3
-	ldo	R%child_return(%r3),%r3
-	stw	%r3,PT_GR21(%r1)	;! save for child
+	stw	%r30,PT_GR21(%r1)	;! save for child
 
-	ldw	TASK_PT_GR30(%r1),%r25
+	ldw     PT_GR30(%r1),%r25
+	mtctl   %r25,%cr29
 	copy	%r1,%r24
 	bl	sys_clone,%r2
 	ldi	SIGCHLD,%r26
@@ -130,7 +128,10 @@
 
 	/* Set the return value for the child */
 
-child_return:
+hpux_child_return:
+	bl	schedule_tail, %r2
+	nop
+
 	ldw TASK_PT_GR19-TASK_SZ_ALGN-128(%r30),%r2
 	b fork_return
 	copy %r0,%r28
@@ -242,3 +243,10 @@
 no_error:
 	b syscall_exit
 	nop
+
+	.export hpux_unimplemented_wrapper
+	.import hpux_unimplemented
+
+hpux_unimplemented_wrapper:
+	b hpux_unimplemented
+	stw %r22,-64(%r30)  /* overwrite arg8 with syscall number */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/Makefile linux-bk/arch/parisc/kernel/Makefile
--- linux-2.4.19/arch/parisc/kernel/Makefile	2000-12-05 20:29:39.000000000 +0000
+++ linux-bk/arch/parisc/kernel/Makefile	2002-08-17 00:49:00.000000000 +0000
@@ -7,26 +7,30 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-all: kernel.o init_task.o pdc_cons.o process.o head.o
-O_TARGET = kernel.o
-O_OBJS = 
+ifdef CONFIG_PARISC64
+all: kernel.o init_task.o pdc_cons.o process.o head64.o unaligned.o perf.o perf_asm.o
+else
+all: kernel.o init_task.o pdc_cons.o process.o head.o unaligned.o
+endif
 
-# Object file lists.
+O_TARGET = kernel.o
 
 obj-y		:=
 obj-m		:=
 obj-n		:=
 obj-		:=
 
-obj-y		+= cache.o setup.o traps.o time.o irq.o \
-		syscall.o entry.o sys_parisc.o pdc.o ptrace.o hardware.o \
-		inventory.o drivers.o semaphore.o pa7300lc.o pci-dma.o \
-		signal.o hpmc.o \
-		real1.o real2.o led.o parisc_ksyms.o
+obj-y           += cache.o pacache.o setup.o traps.o time.o irq.o \
+		pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \
+		ptrace.o hardware.o inventory.o drivers.o semaphore.o \
+		signal.o hpmc.o real2.o parisc_ksyms.o unaligned.o \
+		processor.o power.o
 
-export-objs	:= parisc_ksyms.o
+export-objs	:= parisc_ksyms.o superio.o keyboard.o
 
 
+obj-$(CONFIG_SMP) += smp.o irq_smp.o
+obj-$(CONFIG_PA11) += pci-dma.o
 obj-$(CONFIG_PCI) += pci.o
 obj-$(CONFIG_VT) += keyboard.o
 obj-$(CONFIG_PCI_LBA) += lba_pci.o
@@ -37,16 +41,11 @@
 # Only use one of them: ccio-rm-dma is for PCX-W systems *only*
 # obj-$(CONFIG_IOMMU_CCIO) += ccio-rm-dma.o
 obj-$(CONFIG_IOMMU_CCIO) += ccio-dma.o
-
-.o.S:	$(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $*.S -o $*.o
-
-# 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)))
-MI_OBJS		:= $(sort $(filter-out $(export-objs), $(int-m)))
-MIX_OBJS	:= $(sort $(filter     $(export-objs), $(int-m)))
+obj-$(CONFIG_CHASSIS_LCD_LED) += led.o 
+obj-$(CONFIG_SUPERIO) += superio.o
+obj-$(CONFIG_PARISC64) += binfmt_elf32.o sys_parisc32.o \
+		ioctl32.o signal32.o
+# only supported for PCX-W/U in 64-bit mode at the moment
+obj-$(CONFIG_PARISC64) += perf.o perf_asm.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/binfmt_elf32.c linux-bk/arch/parisc/kernel/binfmt_elf32.c
--- linux-2.4.19/arch/parisc/kernel/binfmt_elf32.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/parisc/kernel/binfmt_elf32.c	2002-08-17 00:49:09.000000000 +0000
@@ -0,0 +1,93 @@
+/*
+ * Support for 32-bit Linux/Parisc ELF binaries on 64 bit kernels
+ *
+ * Copyright (C) 2000 John Marvin
+ * Copyright (C) 2000 Hewlett Packard Co.
+ *
+ * Heavily inspired from various other efforts to do the same thing
+ * (ia64,sparc64/mips64)
+ */
+
+/* Make sure include/asm-parisc/elf.h does the right thing */
+
+#define ELF_CLASS	ELFCLASS32
+
+typedef unsigned int elf_greg_t;
+
+#include <linux/spinlock.h>
+#include <asm/processor.h>
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/elfcore.h>
+#include "sys32.h"		/* struct timeval32 */
+
+#define elf_prstatus elf_prstatus32
+struct elf_prstatus32
+{
+	struct elf_siginfo pr_info;	/* Info associated with signal */
+	short	pr_cursig;		/* Current signal */
+	unsigned int pr_sigpend;	/* Set of pending signals */
+	unsigned int pr_sighold;	/* Set of held signals */
+	pid_t	pr_pid;
+	pid_t	pr_ppid;
+	pid_t	pr_pgrp;
+	pid_t	pr_sid;
+	struct timeval32 pr_utime;	/* User time */
+	struct timeval32 pr_stime;	/* System time */
+	struct timeval32 pr_cutime;	/* Cumulative user time */
+	struct timeval32 pr_cstime;	/* Cumulative system time */
+	elf_gregset_t pr_reg;	/* GP registers */
+	int pr_fpvalid;		/* True if math co-processor being used.  */
+};
+
+#define elf_prpsinfo elf_prpsinfo32
+struct elf_prpsinfo32
+{
+	char	pr_state;	/* numeric process state */
+	char	pr_sname;	/* char for pr_state */
+	char	pr_zomb;	/* zombie */
+	char	pr_nice;	/* nice val */
+	unsigned int pr_flag;	/* flags */
+	u16	pr_uid;
+	u16	pr_gid;
+	pid_t	pr_pid, pr_ppid, pr_pgrp, pr_sid;
+	/* Lots missing */
+	char	pr_fname[16];	/* filename of executable */
+	char	pr_psargs[ELF_PRARGSZ];	/* initial part of arg list */
+};
+
+#define elf_addr_t	unsigned int
+typedef unsigned int elf_caddr_t;
+#define init_elf_binfmt init_elf32_binfmt
+
+#define ELF_PLATFORM  ("PARISC32\0")
+
+#define ELF_CORE_COPY_REGS(dst, pt)	\
+	memset(dst, 0, sizeof(dst));	/* don't leak any "random" bits */ \
+	{	int i; \
+		for (i = 0; i < 32; i++) dst[i] = (elf_greg_t) pt->gr[i]; \
+		for (i = 0; i < 8; i++) dst[32 + i] = (elf_greg_t) pt->sr[i]; \
+	} \
+	dst[40] = (elf_greg_t) pt->iaoq[0]; dst[41] = (elf_greg_t) pt->iaoq[1]; \
+	dst[42] = (elf_greg_t) pt->iasq[0]; dst[43] = (elf_greg_t) pt->iasq[1]; \
+	dst[44] = (elf_greg_t) pt->sar;   dst[45] = (elf_greg_t) pt->iir; \
+	dst[46] = (elf_greg_t) pt->isr;   dst[47] = (elf_greg_t) pt->ior; \
+	dst[48] = (elf_greg_t) mfctl(22); dst[49] = (elf_greg_t) mfctl(0); \
+	dst[50] = (elf_greg_t) mfctl(24); dst[51] = (elf_greg_t) mfctl(25); \
+	dst[52] = (elf_greg_t) mfctl(26); dst[53] = (elf_greg_t) mfctl(27); \
+	dst[54] = (elf_greg_t) mfctl(28); dst[55] = (elf_greg_t) mfctl(29); \
+	dst[56] = (elf_greg_t) mfctl(30); dst[57] = (elf_greg_t) mfctl(31); \
+	dst[58] = (elf_greg_t) mfctl( 8); dst[59] = (elf_greg_t) mfctl( 9); \
+	dst[60] = (elf_greg_t) mfctl(12); dst[61] = (elf_greg_t) mfctl(13); \
+	dst[62] = (elf_greg_t) mfctl(10); dst[63] = (elf_greg_t) mfctl(15);
+
+/*
+ * We should probably use this macro to set a flag somewhere to indicate
+ * this is a 32 on 64 process. We could use PER_LINUX_32BIT, or we
+ * could set a processor dependent flag in the thread_struct.
+ */
+
+#define SET_PERSONALITY(ex, ibcs2) \
+	current->personality = PER_LINUX_32BIT
+
+#include "../../../fs/binfmt_elf.c"
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/cache.c linux-bk/arch/parisc/kernel/cache.c
--- linux-2.4.19/arch/parisc/kernel/cache.c	2000-12-05 20:29:39.000000000 +0000
+++ linux-bk/arch/parisc/kernel/cache.c	2002-08-17 00:49:04.000000000 +0000
@@ -15,202 +15,85 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/seq_file.h>
 
 #include <asm/pdc.h>
 #include <asm/cache.h>
 #include <asm/system.h>
 #include <asm/page.h>
 #include <asm/pgalloc.h>
+#include <asm/processor.h>
+
+int split_tlb;
+int dcache_stride;
+int icache_stride;
 
 struct pdc_cache_info cache_info;
-#ifndef __LP64__
+#ifndef CONFIG_PA20
 static struct pdc_btlb_info btlb_info;
 #endif
 
-
-void __flush_page_to_ram(unsigned long address)
-{
-	__flush_dcache_range(address, PAGE_SIZE);
-	__flush_icache_range(address, PAGE_SIZE);
-}
-
-
-
-void flush_data_cache(void)
+#ifdef CONFIG_SMP
+void
+flush_data_cache(void)
 {
-	register unsigned long base   = cache_info.dc_base;
-	register unsigned long count  = cache_info.dc_count;
-	register unsigned long loop   = cache_info.dc_loop;
-	register unsigned long stride = cache_info.dc_stride;
-	register unsigned long addr;
-	register long i, j;
-
-	for(i=0,addr=base; i<count; i++,addr+=stride)
-		for(j=0; j<loop; j++)
-			fdce(addr);
-}
-		
-static inline void flush_data_tlb_space(void)
-{
-	unsigned long base   = cache_info.dt_off_base;
-	unsigned long count  = cache_info.dt_off_count;
-	unsigned long stride = cache_info.dt_off_stride;
-	unsigned long loop   = cache_info.dt_loop;
-
-	unsigned long addr;
-	long i,j;
-	
-	for(i=0,addr=base; i<count; i++,addr+=stride)
-		for(j=0; j<loop; j++)
-			pdtlbe(addr);
-}
-
-
-
-void flush_data_tlb(void)
-{
-	unsigned long base   = cache_info.dt_sp_base;
-	unsigned long count  = cache_info.dt_sp_count;
-	unsigned long stride = cache_info.dt_sp_stride;
-	unsigned long space;
-	unsigned long old_sr1;
-	long i;
-	
-	old_sr1 = mfsp(1);
-	
-	for(i=0,space=base; i<count; i++, space+=stride) {
-		mtsp(space,1);
-		flush_data_tlb_space();
-	}
-
-	mtsp(old_sr1, 1);
+	smp_call_function((void (*)(void *))flush_data_cache_local, NULL, 1, 1);
+	flush_data_cache_local();
 }
+#endif
 
-static inline void flush_instruction_tlb_space(void)
+void
+flush_cache_all_local(void)
 {
-	unsigned long base   = cache_info.it_off_base;
-	unsigned long count  = cache_info.it_off_count;
-	unsigned long stride = cache_info.it_off_stride;
-	unsigned long loop   = cache_info.it_loop;
-
-	unsigned long addr;
-	long i,j;
-	
-	for(i=0,addr=base; i<count; i++,addr+=stride)
-		for(j=0; j<loop; j++)
-			pitlbe(addr);
-}
-
-void flush_instruction_tlb(void)
-{
-	unsigned long base   = cache_info.it_sp_base;
-	unsigned long count  = cache_info.it_sp_count;
-	unsigned long stride = cache_info.it_sp_stride;
-	unsigned long space;
-	unsigned long old_sr1;
-	unsigned int i;
-	
-	old_sr1 = mfsp(1);
-	
-	for(i=0,space=base; i<count; i++, space+=stride) {
-		mtsp(space,1);
-		flush_instruction_tlb_space();
-	}
-
-	mtsp(old_sr1, 1);
+	flush_instruction_cache_local();
+	flush_data_cache_local();
 }
 
+/* flushes EVERYTHING (tlb & cache) */
 
-void __flush_tlb_space(unsigned long space)
+void
+flush_all_caches(void)
 {
-	unsigned long old_sr1;
-
-	old_sr1 = mfsp(1);
-	mtsp(space, 1);
-	
-	flush_data_tlb_space();
-	flush_instruction_tlb_space();
-
-	mtsp(old_sr1, 1);
+	flush_cache_all();
+	flush_tlb_all();
 }
 
-
-void flush_instruction_cache(void)
+void
+update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
 {
-	register unsigned long base   = cache_info.ic_base;
-	register unsigned long count  = cache_info.ic_count;
-	register unsigned long loop   = cache_info.ic_loop;
-	register unsigned long stride = cache_info.ic_stride;
-	register unsigned long addr;
-	register long i, j;
-	unsigned long old_sr1;
-	
-	old_sr1 = mfsp(1);
-	mtsp(0,1);
+	struct page *page = pte_page(pte);
 
-	/*
-	 * Note: fice instruction has 3 bit space field, so one must
-	 *       be specified (otherwise you are justing using whatever
-	 *       happens to be in sr0).
-	 */
+	if (VALID_PAGE(page) && page->mapping &&
+	    test_bit(PG_dcache_dirty, &page->flags)) {
 
-	for(i=0,addr=base; i<count; i++,addr+=stride)
-		for(j=0; j<loop; j++)
-			fice(addr);
-
-	mtsp(old_sr1, 1);
-}
-
-/* not yet ... fdc() needs to be implemented in cache.h !
-void flush_datacache_range( unsigned int base, unsigned int end )
-{
-    register long offset,offset_add;
-    offset_add = ( (1<<(cache_info.dc_conf.cc_block-1)) * 
-		    cache_info.dc_conf.cc_line ) << 4;
-    for (offset=base; offset<=end; offset+=offset_add)
-	fdc(space,offset);
-    fdc(space,end);
-}
-*/
-
-/* flushes code and data-cache */
-void flush_all_caches(void)
-{
-	flush_instruction_cache();
-	flush_data_cache();
-
-	flush_instruction_tlb();
-	flush_data_tlb();
-
-	asm volatile("sync");
-	asm volatile("syncdma");
-	asm volatile("sync");
+		flush_kernel_dcache_page(page_address(page));
+		clear_bit(PG_dcache_dirty, &page->flags);
+	}
 }
 
-int get_cache_info(char *buffer)
+void
+show_cache_info(struct seq_file *m)
 {
-	char *p = buffer;
-
-	p += sprintf(p, "I-cache\t\t: %ld KB\n", 
+	seq_printf(m, "I-cache\t\t: %ld KB\n", 
 		cache_info.ic_size/1024 );
-	p += sprintf(p, "D-cache\t\t: %ld KB (%s)%s\n", 
+	seq_printf(m, "D-cache\t\t: %ld KB (%s)%s\n", 
 		cache_info.dc_size/1024,
 		(cache_info.dc_conf.cc_wt ? "WT":"WB"),
 		(cache_info.dc_conf.cc_sh ? " - shared I/D":"")
 	);
 
-	p += sprintf(p, "ITLB entries\t: %ld\n" "DTLB entries\t: %ld%s\n",
+	seq_printf(m, "ITLB entries\t: %ld\n" "DTLB entries\t: %ld%s\n",
 		cache_info.it_size,
 		cache_info.dt_size,
 		cache_info.dt_conf.tc_sh ? " - shared with ITLB":""
 	);
 		
-#ifndef __LP64__
+#ifndef CONFIG_PA20
 	/* BTLB - Block TLB */
 	if (btlb_info.max_size==0) {
-		p += sprintf(p, "BTLB\t\t: not supported\n" );
+		seq_printf(m, "BTLB\t\t: not supported\n" );
 	} else {
-		p += sprintf(p, 
+		seq_printf(m, 
 		"BTLB fixed\t: max. %d pages, pagesize=%d (%dMB)\n"
 		"BTLB fix-entr.\t: %d instruction, %d data (%d combined)\n"
 		"BTLB var-entr.\t: %d instruction, %d data (%d combined)\n",
@@ -225,11 +108,8 @@
 		);
 	}
 #endif
-
-	return p - buffer;
 }
 
-
 void __init 
 cache_init(void)
 {
@@ -237,17 +117,108 @@
 		panic("cache_init: pdc_cache_info failed");
 
 #if 0
-	printk("ic_size %lx dc_size %lx it_size %lx pdc_cache_info %d*long pdc_cache_cf %d\n",
+	printk(KERN_DEBUG "ic_size %lx dc_size %lx it_size %lx pdc_cache_info %d*long pdc_cache_cf %d\n",
 	    cache_info.ic_size,
 	    cache_info.dc_size,
 	    cache_info.it_size,
 	    sizeof (struct pdc_cache_info) / sizeof (long),
 	    sizeof (struct pdc_cache_cf)
 	);
+
+	printk(KERN_DEBUG "dc base %x dc stride %x dc count %x dc loop %d\n",
+	    cache_info.dc_base,
+	    cache_info.dc_stride,
+	    cache_info.dc_count,
+	    cache_info.dc_loop);
+
+	printk(KERN_DEBUG "dc conf: alias %d block %d line %d wt %d sh %d cst %d assoc %d\n",
+	    cache_info.dc_conf.cc_alias,
+	    cache_info.dc_conf.cc_block,
+	    cache_info.dc_conf.cc_line,
+	    cache_info.dc_conf.cc_wt,
+	    cache_info.dc_conf.cc_sh,
+	    cache_info.dc_conf.cc_cst,
+	    cache_info.dc_conf.cc_assoc);
+
+	printk(KERN_DEBUG "ic conf: alias %d block %d line %d wt %d sh %d cst %d assoc %d\n",
+	    cache_info.ic_conf.cc_alias,
+	    cache_info.ic_conf.cc_block,
+	    cache_info.ic_conf.cc_line,
+	    cache_info.ic_conf.cc_wt,
+	    cache_info.ic_conf.cc_sh,
+	    cache_info.ic_conf.cc_cst,
+	    cache_info.ic_conf.cc_assoc);
+
+	printk(KERN_DEBUG "dt conf: sh %d page %d cst %d aid %d pad1 %d \n",
+	    cache_info.dt_conf.tc_sh,
+	    cache_info.dt_conf.tc_page,
+	    cache_info.dt_conf.tc_cst,
+	    cache_info.dt_conf.tc_aid,
+	    cache_info.dt_conf.tc_pad1);
+
+	printk(KERN_DEBUG "it conf: sh %d page %d cst %d aid %d pad1 %d \n",
+	    cache_info.it_conf.tc_sh,
+	    cache_info.it_conf.tc_page,
+	    cache_info.it_conf.tc_cst,
+	    cache_info.it_conf.tc_aid,
+	    cache_info.it_conf.tc_pad1);
 #endif
-#ifndef __LP64__
+
+	split_tlb = 0;
+	if (cache_info.dt_conf.tc_sh == 0 || cache_info.dt_conf.tc_sh == 2) {
+
+	    if (cache_info.dt_conf.tc_sh == 2)
+		printk(KERN_WARNING "Unexpected TLB configuration. "
+			"Will flush I/D separately (could be optimized).\n");
+
+	    split_tlb = 1;
+	}
+
+	dcache_stride = ( (1<<(cache_info.dc_conf.cc_block+3)) *
+			 cache_info.dc_conf.cc_line );
+	icache_stride = ( (1<<(cache_info.ic_conf.cc_block+3)) *
+			 cache_info.ic_conf.cc_line );
+#ifndef CONFIG_PA20
 	if(pdc_btlb_info(&btlb_info)<0) {
 		memset(&btlb_info, 0, sizeof btlb_info);
 	}
 #endif
+
+	if ((boot_cpu_data.pdc.capabilities & PDC_MODEL_NVA_MASK) == PDC_MODEL_NVA_UNSUPPORTED) {
+		printk(KERN_WARNING "Only equivalent aliasing supported\n");
+#ifndef CONFIG_SMP
+		panic("SMP kernel required to avoid non-equivalent aliasing");
+#endif
+	}
+}
+
+void disable_sr_hashing(void)
+{
+    int srhash_type;
+
+    if (boot_cpu_data.cpu_type == pcxl2)
+	return; /* pcxl2 doesn't support space register hashing */
+
+    switch (boot_cpu_data.cpu_type) {
+
+    case pcx:
+	BUG(); /* We shouldn't get here. code in setup.c should prevent it */
+	return;
+
+    case pcxs:
+    case pcxt:
+    case pcxt_:
+	srhash_type = SRHASH_PCXST;
+	break;
+
+    case pcxl:
+	srhash_type = SRHASH_PCXL;
+	break;
+
+    default: /* Currently all PA2.0 machines use the same ins. sequence */
+	srhash_type = SRHASH_PA20;
+	break;
+    }
+
+    disable_sr_hashing_asm(srhash_type);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/ccio-dma.c linux-bk/arch/parisc/kernel/ccio-dma.c
--- linux-2.4.19/arch/parisc/kernel/ccio-dma.c	2001-10-12 22:35:53.000000000 +0000
+++ linux-bk/arch/parisc/kernel/ccio-dma.c	2002-08-17 00:48:54.000000000 +0000
@@ -38,16 +38,19 @@
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/string.h>
+#define PCI_DEBUG
 #include <linux/pci.h>
+#undef PCI_DEBUG
 
 #include <asm/byteorder.h>
 #include <asm/cache.h>		/* for L1_CACHE_BYTES */
 #include <asm/uaccess.h>
 #include <asm/pgalloc.h>
 #include <asm/page.h>
-
+#include <asm/dma.h>
 #include <asm/io.h>
 #include <asm/gsc.h>		/* for gsc_writeN()... */
+#include <asm/hardware.h>       /* for register_module() */
 
 /* 
 ** Choose "ccio" since that's what HP-UX calls it.
@@ -55,12 +58,10 @@
 */
 #define MODULE_NAME "ccio"
 
-/*
-#define DEBUG_CCIO_RES
-#define DEBUG_CCIO_RUN
-#define DEBUG_CCIO_INIT
-#define DUMP_RESMAP
-*/
+#undef DEBUG_CCIO_RES
+#undef DEBUG_CCIO_RUN
+#undef DEBUG_CCIO_INIT
+#undef DEBUG_CCIO_RUN_SG
 
 #include <linux/proc_fs.h>
 #include <asm/runway.h>		/* for proc_runway_root */
@@ -83,68 +84,20 @@
 #define DBG_RES(x...)
 #endif
 
+#ifdef DEBUG_CCIO_RUN_SG
+#define DBG_RUN_SG(x...) printk(x)
+#else
+#define DBG_RUN_SG(x...)
+#endif
+
 #define CCIO_INLINE	/* inline */
-#define WRITE_U32(value, addr) gsc_writel(value, (u32 *) (addr))
+#define WRITE_U32(value, addr) gsc_writel(value, (u32 *)(addr))
+#define READ_U32(addr) gsc_readl((u32 *)(addr))
 
 #define U2_IOA_RUNWAY 0x580
 #define U2_BC_GSC     0x501
 #define UTURN_IOA_RUNWAY 0x581
 #define UTURN_BC_GSC     0x502
-/* We *can't* support JAVA (T600). Venture there at your own risk. */
-
-static void dump_resmap(void);
-
-static int ccio_driver_callback(struct hp_device *, struct pa_iodc_driver *);
-
-static struct pa_iodc_driver ccio_drivers_for[] = {
-
-   {HPHW_IOA, U2_IOA_RUNWAY, 0x0, 0xb, 0, 0x10,
-		DRIVER_CHECK_HVERSION +
-		DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
-                MODULE_NAME, "U2 I/O MMU", (void *) ccio_driver_callback},
-
-   {HPHW_IOA, UTURN_IOA_RUNWAY, 0x0, 0xb, 0, 0x10,
-		DRIVER_CHECK_HVERSION +
-		DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
-                MODULE_NAME, "Uturn I/O MMU", (void *) ccio_driver_callback},
-
-/*
-** FIXME: The following claims the GSC bus port, not the IOA.
-**        And there are two busses below a single I/O TLB.
-**
-** These should go away once we have a real PA bus walk.
-** Firmware wants to tell the PA bus walk code about the GSC ports
-** since they are not "architected" PA I/O devices. Ie a PA bus walk
-** wouldn't discover them. But the PA bus walk code could check
-** the "fixed module table" to add such devices to an I/O Tree
-** and proceed with the recursive, depth first bus walk.
-*/
-   {HPHW_BCPORT, U2_BC_GSC, 0x0, 0xc, 0, 0x10,
-		DRIVER_CHECK_HVERSION +
-		DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
-                MODULE_NAME, "U2 GSC+ BC", (void *) ccio_driver_callback},
-
-   {HPHW_BCPORT, UTURN_BC_GSC, 0x0, 0xc, 0, 0x10,
-		DRIVER_CHECK_HVERSION +
-		DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
-                MODULE_NAME, "Uturn GSC+ BC", (void *) ccio_driver_callback},
-
-   {0,0,0,0,0,0,
-   0,
-   (char *) NULL, (char *) NULL, (void *) NULL }
-};
-
-
-#define IS_U2(id) ( \
-    (((id)->hw_type == HPHW_IOA) && ((id)->hversion == U2_IOA_RUNWAY)) || \
-    (((id)->hw_type == HPHW_BCPORT) && ((id)->hversion == U2_BC_GSC))  \
-)
-
-#define IS_UTURN(id) ( \
-    (((id)->hw_type == HPHW_IOA) && ((id)->hversion == UTURN_IOA_RUNWAY)) || \
-    (((id)->hw_type == HPHW_BCPORT) && ((id)->hversion == UTURN_BC_GSC))  \
-)
-
 
 #define IOA_NORMAL_MODE      0x00020080 /* IO_CONTROL to turn on CCIO        */
 #define CMD_TLB_DIRECT_WRITE 35         /* IO_COMMAND for I/O TLB Writes     */
@@ -176,41 +129,46 @@
         volatile uint32_t   io_io_high;             /* Offset 15 */
 };
 
+struct ioc {
+	struct ioa_registers *ioc_hpa;  /* I/O MMU base address */
+	u8  *res_map;	                /* resource map, bit == pdir entry */
+	u64 *pdir_base;	                /* physical base address */
+	u32 res_hint;	                /* next available IOVP - 
+					   circular search */
+	u32 res_size;		    	/* size of resource map in bytes */
+	spinlock_t res_lock;
+
+#ifdef CONFIG_PROC_FS
+#define CCIO_SEARCH_SAMPLE 0x100
+	unsigned long avg_search[CCIO_SEARCH_SAMPLE];
+	unsigned long avg_idx;		  /* current index into avg_search */
+	unsigned long used_pages;
+	unsigned long msingle_calls;
+	unsigned long msingle_pages;
+	unsigned long msg_calls;
+	unsigned long msg_pages;
+	unsigned long usingle_calls;
+	unsigned long usingle_pages;
+	unsigned long usg_calls;
+	unsigned long usg_pages;
 
-struct ccio_device {
-	struct ccio_device    *next;  /* list of LBA's in system */
-	struct hp_device      *iodc;  /* data about dev from firmware */
-	spinlock_t            ccio_lock;
-
-	struct ioa_registers   *ccio_hpa; /* base address */
-	u64   *pdir_base;   /* physical base address */
-	char  *res_map;     /* resource map, bit == pdir entry */
-
-	int   res_hint;	/* next available IOVP - circular search */
-	int   res_size;	/* size of resource map in bytes */
-	int   chainid_shift; /* specify bit location of chain_id */
-	int   flags;         /* state/functionality enabled */
-#ifdef DELAYED_RESOURCE_CNT
-	dma_addr_t res_delay[DELAYED_RESOURCE_CNT];
+	unsigned short cujo20_bug;
 #endif
 
 	/* STUFF We don't need in performance path */
-	int  pdir_size;     /* in bytes, determined by IOV Space size */
-	int  hw_rev;        /* HW revision of chip */
+	u32 pdir_size; 			/* in bytes, determined by IOV Space size */
+	u32 chainid_shift; 		/* specify bit location of chain_id */
+	struct ioc *next;		/* Linked list of discovered iocs */
+	const char *name;		/* device name from firmware */
+	unsigned int hw_path;           /* the hardware path this ioc is associatd with */
+	struct pci_dev *fake_pci_dev;   /* the fake pci_dev for non-pci devs */
+	struct resource mmio_region[2]; /* The "routed" MMIO regions */
 };
 
-
 /* Ratio of Host MEM to IOV Space size */
 static unsigned long ccio_mem_ratio = 4;
-static struct ccio_device *ccio_list = NULL;
-
-static int ccio_proc_info(char *buffer, char **start, off_t offset, int length);
-static unsigned long ccio_used_bytes = 0;
-static unsigned long ccio_used_pages = 0;
-static int ccio_cujo_bug = 0;
-
-static unsigned long ccio_alloc_size = 0;
-static unsigned long ccio_free_size = 0;
+static struct ioc *ioc_list;
+static int ioc_count;
 
 /**************************************************************
 *
@@ -227,55 +185,41 @@
 *   match the I/O TLB replacement policy.
 *
 ***************************************************************/
-#define PAGES_PER_RANGE 1	/* could increase this to 4 or 8 if needed */
 #define IOVP_SIZE PAGE_SIZE
 #define IOVP_SHIFT PAGE_SHIFT
 #define IOVP_MASK PAGE_MASK
 
 /* Convert from IOVP to IOVA and vice versa. */
 #define CCIO_IOVA(iovp,offset) ((iovp) | (offset))
-#define CCIO_IOVP(iova) ((iova) & ~(IOVP_SIZE-1) )
+#define CCIO_IOVP(iova) ((iova) & IOVP_MASK)
 
 #define PDIR_INDEX(iovp)    ((iovp)>>IOVP_SHIFT)
 #define MKIOVP(pdir_idx)    ((long)(pdir_idx) << IOVP_SHIFT)
 #define MKIOVA(iovp,offset) (dma_addr_t)((long)iovp | (long)offset)
-
-/* CUJO20 KLUDGE start */
-#define CUJO_20_BITMASK    0x0ffff000	/* upper nibble is a don't care   */
-#define CUJO_20_STEP       0x10000000	/* inc upper nibble */
-#define CUJO_20_BADPAGE1   0x01003000	/* pages that hpmc on raven U+    */
-#define CUJO_20_BADPAGE2   0x01607000	/* pages that hpmc on firehawk U+ */
-#define CUJO_20_BADHVERS   0x6821	/* low nibble 1 is cujo rev 2.0 */
-#define CUJO_RAVEN_LOC     0xf1000000UL	/* cujo location on raven U+ */
-#define CUJO_FIREHAWK_LOC  0xf1604000UL	/* cujo location on firehawk U+ */
-/* CUJO20 KLUDGE end */
+#define ROUNDUP(x,y) ((x + ((y)-1)) & ~((y)-1))
 
 /*
 ** Don't worry about the 150% average search length on a miss.
 ** If the search wraps around, and passes the res_hint, it will
 ** cause the kernel to panic anyhow.
 */
-
-/* ioa->res_hint = idx + (size >> 3); \ */
-
-#define CCIO_SEARCH_LOOP(ioa, idx, mask, size)  \
-       for(; res_ptr < res_end; ++res_ptr) \
-       { \
-               if(0 == ((*res_ptr) & mask)) { \
-                       *res_ptr |= mask; \
-                       idx = (int)((unsigned long)res_ptr - (unsigned long)ioa->res_map); \
-                       ioa->res_hint = 0;\
+#define CCIO_SEARCH_LOOP(ioc, res_idx, mask_ptr, size)  \
+       for(; res_ptr < res_end; ++res_ptr) { \
+               if(0 == (*res_ptr & *mask_ptr)) { \
+                       *res_ptr |= *mask_ptr; \
+                       res_idx = (int)((unsigned long)res_ptr - (unsigned long)ioc->res_map); \
+                       ioc->res_hint = res_idx + (size >> 3); \
                        goto resource_found; \
                } \
        }
 
-#define CCIO_FIND_FREE_MAPPING(ioa, idx, mask, size)  { \
-       u##size *res_ptr = (u##size *)&((ioa)->res_map[ioa->res_hint & ~((size >> 3) - 1)]); \
-       u##size *res_end = (u##size *)&(ioa)->res_map[ioa->res_size]; \
-       CCIO_SEARCH_LOOP(ioa, idx, mask, size); \
-       res_ptr = (u##size *)&(ioa)->res_map[0]; \
-       CCIO_SEARCH_LOOP(ioa, idx, mask, size); \
-}
+#define CCIO_FIND_FREE_MAPPING(ioa, res_idx, mask, size) \
+       u##size *res_ptr = (u##size *)&((ioc)->res_map[ioa->res_hint & ~((size >> 3) - 1)]); \
+       u##size *res_end = (u##size *)&(ioc)->res_map[ioa->res_size]; \
+       u##size *mask_ptr = (u##size *)&mask; \
+       CCIO_SEARCH_LOOP(ioc, res_idx, mask_ptr, size); \
+       res_ptr = (u##size *)&(ioc)->res_map[0]; \
+       CCIO_SEARCH_LOOP(ioa, res_idx, mask_ptr, size);
 
 /*
 ** Find available bit in this ioa's resource map.
@@ -290,123 +234,132 @@
 ** o use different search for "large" (eg > 4 pages) or "very large"
 **   (eg > 16 pages) mappings.
 */
+
+/**
+ * ccio_alloc_range - Allocate pages in the ioc's resource map.
+ * @ioc: The I/O Controller.
+ * @pages_needed: The requested number of pages to be mapped into the
+ * I/O Pdir...
+ *
+ * This function searches the resource map of the ioc to locate a range
+ * of available pages for the requested size.
+ */
 static int
-ccio_alloc_range(struct ccio_device *ioa, size_t size)
+ccio_alloc_range(struct ioc *ioc, unsigned long pages_needed)
 {
 	int res_idx;
-	unsigned long mask, flags;
-	unsigned int pages_needed = size >> PAGE_SHIFT;
-
+	unsigned long mask;
+#ifdef CONFIG_PROC_FS
+	unsigned long cr_start = mfctl(16);
+#endif
+	
 	ASSERT(pages_needed);
-	ASSERT((pages_needed * IOVP_SIZE) < DMA_CHUNK_SIZE);
-	ASSERT(pages_needed < (BITS_PER_LONG - IOVP_SHIFT));
+	ASSERT((pages_needed * IOVP_SIZE) <= DMA_CHUNK_SIZE);
+	ASSERT(pages_needed <= BITS_PER_LONG);
 
-	mask = (unsigned long) -1L;
- 	mask >>= BITS_PER_LONG - pages_needed;
-
-	DBG_RES(__FUNCTION__ " size: %d pages_needed %d pages_mask 0x%08lx\n", 
-		size, pages_needed, mask);
-
-	spin_lock_irqsave(&ioa->ccio_lock, flags);
+	mask = ~(~0UL >> pages_needed);
+     
+	DBG_RES("%s() size: %d pages_needed %d mask 0x%08lx\n", 
+		__FUNCTION__, size, pages_needed, mask);
 
 	/*
 	** "seek and ye shall find"...praying never hurts either...
-	** ggg sacrafices another 710 to the computer gods.
+	** ggg sacrifices another 710 to the computer gods.
 	*/
 
 	if(pages_needed <= 8) {
-		CCIO_FIND_FREE_MAPPING(ioa, res_idx, mask, 8);
+		CCIO_FIND_FREE_MAPPING(ioc, res_idx, mask, 8);
 	} else if(pages_needed <= 16) {
-		CCIO_FIND_FREE_MAPPING(ioa, res_idx, mask, 16);
+		CCIO_FIND_FREE_MAPPING(ioc, res_idx, mask, 16);
 	} else if(pages_needed <= 32) {
-		CCIO_FIND_FREE_MAPPING(ioa, res_idx, mask, 32);
+		CCIO_FIND_FREE_MAPPING(ioc, res_idx, mask, 32);
 #ifdef __LP64__
 	} else if(pages_needed <= 64) {
-		CCIO_FIND_FREE_MAPPING(ioa, res_idx, mask, 64)
+		CCIO_FIND_FREE_MAPPING(ioc, res_idx, mask, 64);
 #endif
 	} else {
-		panic(__FILE__ ":" __FUNCTION__ "() Too many pages to map.\n");
+		panic(__FILE__ ": %s() Too many pages to map. pages_needed: %ld\n", 
+		      __FUNCTION__, pages_needed);
 	}
 
-#ifdef DUMP_RESMAP
-	dump_resmap();
-#endif
-	panic(__FILE__ ":" __FUNCTION__ "() I/O MMU is out of mapping resources\n");
+	panic(__FILE__ ": %s() I/O MMU is out of mapping resources.\n", 
+	      __FUNCTION__);
 	
 resource_found:
 	
-	DBG_RES(__FUNCTION__ " res_idx %d mask 0x%08lx res_hint: %d\n",
-		res_idx, mask, ioa->res_hint);
+	DBG_RES("%s() res_idx %d mask 0x%08lx res_hint: %d\n",
+		__FUNCTION__, res_idx, mask, ioc->res_hint);
 
-	ccio_used_pages += pages_needed;
-	ccio_used_bytes += ((pages_needed >> 3) ? (pages_needed >> 3) : 1);
-
-	spin_unlock_irqrestore(&ioa->ccio_lock, flags);
+#ifdef CONFIG_PROC_FS
+	{
+		unsigned long cr_end = mfctl(16);
+		unsigned long tmp = cr_end - cr_start;
+		/* check for roll over */
+		cr_start = (cr_end < cr_start) ?  -(tmp) : (tmp);
+	}
+	ioc->avg_search[ioc->avg_idx++] = cr_start;
+	ioc->avg_idx &= CCIO_SEARCH_SAMPLE - 1;
 
-#ifdef DUMP_RESMAP
-	dump_resmap();
+	ioc->used_pages += pages_needed;
 #endif
 
 	/* 
-	** return the bit address (convert from byte to bit).
+	** return the bit address.
 	*/
-	return (res_idx << 3);
+	return res_idx << 3;
 }
 
-
-#define CCIO_FREE_MAPPINGS(ioa, idx, mask, size) \
-        u##size *res_ptr = (u##size *)&((ioa)->res_map[idx + (((size >> 3) - 1) & ~((size >> 3) - 1))]); \
-        ASSERT((*res_ptr & mask) == mask); \
-        *res_ptr &= ~mask;
-
-/*
-** clear bits in the ioa's resource map
-*/
+#define CCIO_FREE_MAPPINGS(ioc, res_idx, mask, size) \
+        u##size *res_ptr = (u##size *)&((ioc)->res_map[res_idx]); \
+	u##size *mask_ptr = (u##size *)&mask; \
+        ASSERT((*res_ptr & *mask_ptr) == *mask_ptr); \
+        *res_ptr &= ~(*mask_ptr);
+
+/**
+ * ccio_free_range - Free pages from the ioc's resource map.
+ * @ioc: The I/O Controller.
+ * @iova: The I/O Virtual Address.
+ * @pages_mapped: The requested number of pages to be freed from the
+ * I/O Pdir.
+ *
+ * This function frees the resouces allocated for the iova.
+ */
 static void
-ccio_free_range(struct ccio_device *ioa, dma_addr_t iova, size_t size)
+ccio_free_range(struct ioc *ioc, dma_addr_t iova, unsigned long pages_mapped)
 {
-	unsigned long mask, flags;
+	unsigned long mask;
 	unsigned long iovp = CCIO_IOVP(iova);
-	unsigned int res_idx = PDIR_INDEX(iovp)>>3;
-	unsigned int pages_mapped = (size >> IOVP_SHIFT) + !!(size & ~IOVP_MASK);
+	unsigned int res_idx = PDIR_INDEX(iovp) >> 3;
 
-	ASSERT(pages_needed);
-	ASSERT((pages_needed * IOVP_SIZE) < DMA_CHUNK_SIZE);
-	ASSERT(pages_needed < (BITS_PER_LONG - IOVP_SHIFT));
+	ASSERT(pages_mapped);
+	ASSERT((pages_mapped * IOVP_SIZE) <= DMA_CHUNK_SIZE);
+	ASSERT(pages_mapped <= BITS_PER_LONG);
 
-	mask = (unsigned long) -1L;
- 	mask >>= BITS_PER_LONG - pages_mapped;
+	mask = ~(~0UL >> pages_mapped);
 
-	DBG_RES(__FUNCTION__ " res_idx: %d size: %d pages_mapped %d mask 0x%08lx\n", 
-		res_idx, size, pages_mapped, mask);
+	DBG_RES("%s():  res_idx: %d pages_mapped %d mask 0x%08lx\n", 
+		__FUNCTION__, res_idx, pages_mapped, mask);
 
-	spin_lock_irqsave(&ioa->ccio_lock, flags);
+#ifdef CONFIG_PROC_FS
+	ioc->used_pages -= pages_mapped;
+#endif
 
 	if(pages_mapped <= 8) {
-		CCIO_FREE_MAPPINGS(ioa, res_idx, mask, 8);
+		CCIO_FREE_MAPPINGS(ioc, res_idx, mask, 8);
 	} else if(pages_mapped <= 16) {
-		CCIO_FREE_MAPPINGS(ioa, res_idx, mask, 16);
+		CCIO_FREE_MAPPINGS(ioc, res_idx, mask, 16);
 	} else if(pages_mapped <= 32) {
-		CCIO_FREE_MAPPINGS(ioa, res_idx, mask, 32);
+		CCIO_FREE_MAPPINGS(ioc, res_idx, mask, 32);
 #ifdef __LP64__
 	} else if(pages_mapped <= 64) {
-		CCIO_FREE_MAPPINGS(ioa, res_idx, mask, 64);
+		CCIO_FREE_MAPPINGS(ioc, res_idx, mask, 64);
 #endif
 	} else {
-		panic(__FILE__ ":" __FUNCTION__ "() Too many pages to unmap.\n");
+		panic(__FILE__ ":%s() Too many pages to unmap.\n", 
+		      __FUNCTION__);
 	}
-	
-	ccio_used_pages -= (pages_mapped ? pages_mapped : 1);
-	ccio_used_bytes -= ((pages_mapped >> 3) ? (pages_mapped >> 3) : 1);
-
-	spin_unlock_irqrestore(&ioa->ccio_lock, flags);
-
-#ifdef DUMP_RESMAP
-	dump_resmap();
-#endif
 }
 
-
 /****************************************************************
 **
 **          CCIO dma_ops support routines
@@ -416,7 +369,6 @@
 typedef unsigned long space_t;
 #define KERNEL_SPACE 0
 
-
 /*
 ** DMA "Page Type" and Hints 
 ** o if SAFE_DMA isn't set, mapping is for FAST_DMA. SAFE_DMA should be
@@ -466,32 +418,35 @@
 	[PCI_DMA_NONE]           0,            /* not valid */
 };
 
-/*
-** Initialize an I/O Pdir entry
-**
-** Given a virtual address (vba, arg2) and space id, (sid, arg1),
-** load the I/O PDIR entry pointed to by pdir_ptr (arg0). Each IO Pdir
-** entry consists of 8 bytes as shown below (MSB == bit 0):
-**
-**
-** WORD 0:
-** +------+----------------+-----------------------------------------------+
-** | Phys | Virtual Index  |               Phys                            |
-** | 0:3  |     0:11       |               4:19                            |
-** |4 bits|   12 bits      |              16 bits                          |
-** +------+----------------+-----------------------------------------------+
-** WORD 1:
-** +-----------------------+-----------------------------------------------+
-** |      Phys    |  Rsvd  | Prefetch |Update |Rsvd  |Lock  |Safe  |Valid  |
-** |     20:39    |        | Enable   |Enable |      |Enable|DMA   |       |
-** |    20 bits   | 5 bits | 1 bit    |1 bit  |2 bits|1 bit |1 bit |1 bit  |
-** +-----------------------+-----------------------------------------------+
-**
-** The virtual index field is filled with the results of the LCI
-** (Load Coherence Index) instruction.  The 8 bits used for the virtual
-** index are bits 12:19 of the value returned by LCI.
-*/
-
+/**
+ * ccio_io_pdir_entry - Initialize an I/O Pdir.
+ * @pdir_ptr: A pointer into I/O Pdir.
+ * @sid: The Space Identifier.
+ * @vba: The virtual address.
+ * @hints: The DMA Hint.
+ *
+ * Given a virtual address (vba, arg2) and space id, (sid, arg1),
+ * load the I/O PDIR entry pointed to by pdir_ptr (arg0). Each IO Pdir
+ * entry consists of 8 bytes as shown below (MSB == bit 0):
+ *
+ *
+ * WORD 0:
+ * +------+----------------+-----------------------------------------------+
+ * | Phys | Virtual Index  |               Phys                            |
+ * | 0:3  |     0:11       |               4:19                            |
+ * |4 bits|   12 bits      |              16 bits                          |
+ * +------+----------------+-----------------------------------------------+
+ * WORD 1:
+ * +-----------------------+-----------------------------------------------+
+ * |      Phys    |  Rsvd  | Prefetch |Update |Rsvd  |Lock  |Safe  |Valid  |
+ * |     20:39    |        | Enable   |Enable |      |Enable|DMA   |       |
+ * |    20 bits   | 5 bits | 1 bit    |1 bit  |2 bits|1 bit |1 bit |1 bit  |
+ * +-----------------------+-----------------------------------------------+
+ *
+ * The virtual index field is filled with the results of the LCI
+ * (Load Coherence Index) instruction.  The 8 bits used for the virtual
+ * index are bits 12:19 of the value returned by LCI.
+ */ 
 void CCIO_INLINE
 ccio_io_pdir_entry(u64 *pdir_ptr, space_t sid, void * vba, unsigned long hints)
 {
@@ -499,8 +454,7 @@
 	register unsigned long ci; /* coherent index */
 
 	/* We currently only support kernel addresses */
-	ASSERT(sid == 0);
-	ASSERT(((unsigned long) vba & 0xf0000000UL) == 0xc0000000UL);
+	ASSERT(sid == KERNEL_SPACE);
 
 	mtsp(sid,1);
 
@@ -524,7 +478,7 @@
 	** and deposit them
 	*/
 	asm volatile ("extrd,u %1,15,4,%0" : "=r" (ci) : "r" (pa));
-	asm volatile ("extrd,u %1,31,16,%0" : "+r" (ci) : "r" (ci));
+	asm volatile ("extrd,u %1,31,16,%0" : "+r" (pa) : "r" (pa));
 	asm volatile ("depd  %1,35,4,%0" : "+r" (pa) : "r" (ci));
 #else
 	pa = 0;
@@ -556,31 +510,39 @@
 	asm volatile("sync");
 }
 
-
-/*
-** Remove stale entries from the I/O TLB.
-** Need to do this whenever an entry in the PDIR is marked invalid.
-*/
+/**
+ * ccio_clear_io_tlb - Remove stale entries from the I/O TLB.
+ * @ioc: The I/O Controller.
+ * @iovp: The I/O Virtual Page.
+ * @byte_cnt: The requested number of bytes to be freed from the I/O Pdir.
+ *
+ * Purge invalid I/O PDIR entries from the I/O TLB.
+ *
+ * FIXME: Can we change the byte_cnt to pages_mapped?
+ */
 static CCIO_INLINE void
-ccio_clear_io_tlb( struct ccio_device *d, dma_addr_t iovp, size_t byte_cnt)
+ccio_clear_io_tlb(struct ioc *ioc, dma_addr_t iovp, size_t byte_cnt)
 {
-	u32 chain_size = 1 << d->chainid_shift;
+	u32 chain_size = 1 << ioc->chainid_shift;
 
-	iovp &= ~(IOVP_SIZE-1);	/* clear offset bits, just want pagenum */
+	iovp &= IOVP_MASK;	/* clear offset bits, just want pagenum */
 	byte_cnt += chain_size;
 
-        while (byte_cnt > chain_size) {
-		WRITE_U32(CMD_TLB_PURGE | iovp, &d->ccio_hpa->io_command);
-                iovp += chain_size;
+	while(byte_cnt > chain_size) {
+		WRITE_U32(CMD_TLB_PURGE | iovp, &ioc->ioc_hpa->io_command);
+		iovp += chain_size;
 		byte_cnt -= chain_size;
-        }
+      }
 }
 
-
-/***********************************************************
+/**
+ * ccio_mark_invalid - Mark the I/O Pdir entries invalid.
+ * @ioc: The I/O Controller.
+ * @iova: The I/O Virtual Address.
+ * @byte_cnt: The requested number of bytes to be freed from the I/O Pdir.
  *
- * Mark the I/O Pdir entries invalid and blow away the
- * corresponding I/O TLB entries.
+ * Mark the I/O Pdir entries invalid and blow away the corresponding I/O
+ * TLB entries.
  *
  * FIXME: at some threshhold it might be "cheaper" to just blow
  *        away the entire I/O TLB instead of individual entries.
@@ -588,25 +550,25 @@
  * FIXME: Uturn has 256 TLB entries. We don't need to purge every
  *        PDIR entry - just once for each possible TLB entry.
  *        (We do need to maker I/O PDIR entries invalid regardless).
- ***********************************************************/
+ *
+ * FIXME: Can we change byte_cnt to pages_mapped?
+ */ 
 static CCIO_INLINE void
-ccio_mark_invalid(struct ccio_device *d, dma_addr_t iova, size_t byte_cnt)
+ccio_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt)
 {
-	u32 iovp = (u32) CCIO_IOVP(iova);
+	u32 iovp = (u32)CCIO_IOVP(iova);
 	size_t saved_byte_cnt;
 
 	/* round up to nearest page size */
-	saved_byte_cnt = byte_cnt = (byte_cnt + IOVP_SIZE - 1) & IOVP_MASK;
+	saved_byte_cnt = byte_cnt = ROUNDUP(byte_cnt, IOVP_SIZE);
 
-	while (byte_cnt > 0) {
+	while(byte_cnt > 0) {
 		/* invalidate one page at a time */
 		unsigned int idx = PDIR_INDEX(iovp);
-		char *pdir_ptr = (char *) &(d->pdir_base[idx]);
-
-		ASSERT( idx < (d->pdir_size/sizeof(u64)));
-
-		pdir_ptr[7] = 0;	/* clear only VALID bit */
+		char *pdir_ptr = (char *) &(ioc->pdir_base[idx]);
 
+		ASSERT(idx < (ioc->pdir_size / sizeof(u64)));
+		pdir_ptr[7] = 0;	/* clear only VALID bit */ 
 		/*
 		** FIXME: PCX_W platforms don't need FDC/SYNC. (eg C360)
 		**   PCX-U/U+ do. (eg C200/C240)
@@ -622,232 +584,485 @@
 	}
 
 	asm volatile("sync");
-	ccio_clear_io_tlb(d, CCIO_IOVP(iova), saved_byte_cnt);
+	ccio_clear_io_tlb(ioc, CCIO_IOVP(iova), saved_byte_cnt);
 }
 
-
 /****************************************************************
 **
 **          CCIO dma_ops
 **
 *****************************************************************/
 
-void __init ccio_init(void)
-{
-	register_driver(ccio_drivers_for);
-}
-
-
-static int ccio_dma_supported( struct pci_dev *dev, u64 mask)
+/**
+ * ccio_dma_supported - Verify the IOMMU supports the DMA address range.
+ * @dev: The PCI device.
+ * @mask: A bit mask describing the DMA address range of the device.
+ *
+ * This function implements the pci_dma_supported function.
+ */
+static int 
+ccio_dma_supported(struct pci_dev *dev, u64 mask)
 {
-	if (dev == NULL) {
-		printk(MODULE_NAME ": EISA/ISA/et al not supported\n");
+	if(dev == NULL) {
+		printk(KERN_ERR MODULE_NAME ": EISA/ISA/et al not supported\n");
 		BUG();
-		return(0);
+		return 0;
 	}
 
 	dev->dma_mask = mask;   /* save it */
 
 	/* only support 32-bit devices (ie PCI/GSC) */
-	return((int) (mask >= 0xffffffffUL));
+	return (int)(mask == 0xffffffffUL);
 }
 
-/*
-** Dump a hex representation of the resource map.
-*/
-
-#ifdef DUMP_RESMAP
-static 
-void dump_resmap()
-{
-	struct ccio_device *ioa = ccio_list;
-	unsigned long *res_ptr = (unsigned long *)ioa->res_map;
-	unsigned long i = 0;
-
-	printk("res_map: ");
-	for(; i < (ioa->res_size / sizeof(unsigned long)); ++i, ++res_ptr)
-		printk("%08lx ", *res_ptr);
-
-	printk("\n");
-}
-#endif
-
-/*
-** map_single returns a fully formed IOVA
-*/
-static dma_addr_t ccio_map_single(struct pci_dev *dev, void *addr, size_t size, int direction)
+/**
+ * ccio_map_single - Map an address range into the IOMMU.
+ * @dev: The PCI device.
+ * @addr: The start address of the DMA region.
+ * @size: The length of the DMA region.
+ * @direction: The direction of the DMA transaction (to/from device).
+ *
+ * This function implements the pci_map_single function.
+ */
+static dma_addr_t 
+ccio_map_single(struct pci_dev *dev, void *addr, size_t size, int direction)
 {
-	struct ccio_device *ioa = ccio_list;  /* FIXME : see Multi-IOC below */
+	int idx;
+	struct ioc *ioc;
+	unsigned long flags;
 	dma_addr_t iovp;
 	dma_addr_t offset;
 	u64 *pdir_start;
 	unsigned long hint = hint_lookup[direction];
-	int idx;
+
+	ASSERT(dev);
+	ASSERT(dev->sysdata);
+	ASSERT(HBA_DATA(dev->sysdata)->iommu);
+	ioc = GET_IOC(dev);
 
 	ASSERT(size > 0);
 
 	/* save offset bits */
-	offset = ((dma_addr_t) addr) & ~IOVP_MASK;
+	offset = ((unsigned long) addr) & ~IOVP_MASK;
 
 	/* round up to nearest IOVP_SIZE */
-	size = (size + offset + IOVP_SIZE - 1) & IOVP_MASK;
+	size = ROUNDUP(size + offset, IOVP_SIZE);
+	spin_lock_irqsave(&ioc->res_lock, flags);
+
+#ifdef CONFIG_PROC_FS
+	ioc->msingle_calls++;
+	ioc->msingle_pages += size >> IOVP_SHIFT;
+#endif
 
-	idx = ccio_alloc_range(ioa, size);
-	iovp = (dma_addr_t) MKIOVP(idx);
+	idx = ccio_alloc_range(ioc, (size >> IOVP_SHIFT));
+	iovp = (dma_addr_t)MKIOVP(idx);
 
-	DBG_RUN(__FUNCTION__ " 0x%p -> 0x%lx", addr, (long) iovp | offset);
+	pdir_start = &(ioc->pdir_base[idx]);
 
-	pdir_start = &(ioa->pdir_base[idx]);
+	DBG_RUN("%s() 0x%p -> 0x%lx size: %0x%x\n",
+		__FUNCTION__, addr, (long)iovp | offset, size);
 
 	/* If not cacheline aligned, force SAFE_DMA on the whole mess */
-	if ((size % L1_CACHE_BYTES) || ((unsigned long) addr % L1_CACHE_BYTES))
+	if((size % L1_CACHE_BYTES) || ((unsigned long)addr % L1_CACHE_BYTES))
 		hint |= HINT_SAFE_DMA;
 
-	/* round up to nearest IOVP_SIZE */
-	size = (size + IOVP_SIZE - 1) & IOVP_MASK;
-
-	while (size > 0) {
-
+	while(size > 0) {
 		ccio_io_pdir_entry(pdir_start, KERNEL_SPACE, addr, hint);
 
 		DBG_RUN(" pdir %p %08x%08x\n",
 			pdir_start,
 			(u32) (((u32 *) pdir_start)[0]),
-			(u32) (((u32 *) pdir_start)[1])
-			);
+			(u32) (((u32 *) pdir_start)[1]));
+		++pdir_start;
 		addr += IOVP_SIZE;
 		size -= IOVP_SIZE;
-		pdir_start++;
 	}
+
+	spin_unlock_irqrestore(&ioc->res_lock, flags);
+
 	/* form complete address */
 	return CCIO_IOVA(iovp, offset);
 }
 
-
-static void ccio_unmap_single(struct pci_dev *dev, dma_addr_t iova, size_t size, int direction)
-{
-#ifdef FIXME
-/* Multi-IOC (ie N-class) :  need to lookup IOC from dev
-** o If we can't know about lba PCI data structs, that eliminates ->sysdata.
-** o walking up pcidev->parent dead ends at elroy too
-** o leaves hashing dev->bus->number into some lookup.
-**   (may only work for N-class)
-*/
-	struct ccio_device *ioa = dev->sysdata
-#else
-	struct ccio_device *ioa = ccio_list;
-#endif
-	dma_addr_t offset;
+/**
+ * ccio_unmap_single - Unmap an address range from the IOMMU.
+ * @dev: The PCI device.
+ * @addr: The start address of the DMA region.
+ * @size: The length of the DMA region.
+ * @direction: The direction of the DMA transaction (to/from device).
+ *
+ * This function implements the pci_unmap_single function.
+ */
+static void 
+ccio_unmap_single(struct pci_dev *dev, dma_addr_t iova, size_t size, 
+		  int direction)
+{
+	struct ioc *ioc;
+	unsigned long flags; 
+	dma_addr_t offset = iova & ~IOVP_MASK;
 	
-	offset = iova & ~IOVP_MASK;
-
-	/* round up to nearest IOVP_SIZE */
-	size = (size + offset + IOVP_SIZE - 1) & IOVP_MASK;
+	ASSERT(dev);
+	ASSERT(dev->sysdata);
+	ASSERT(HBA_DATA(dev->sysdata)->iommu);
+	ioc = GET_IOC(dev);
+
+	DBG_RUN("%s() iovp 0x%lx/%x\n",
+		__FUNCTION__, (long)iova, size);
+
+	iova ^= offset;        /* clear offset bits */
+	size += offset;
+	size = ROUNDUP(size, IOVP_SIZE);
 
-	/* Mask off offset */
-	iova &= IOVP_MASK;
+	spin_lock_irqsave(&ioc->res_lock, flags);
 
-	DBG_RUN(__FUNCTION__ " iovp 0x%lx\n", (long) iova);
-
-#ifdef DELAYED_RESOURCE_CNT
-	if (ioa->saved_cnt < DELAYED_RESOURCE_CNT) {
-		ioa->saved_iova[ioa->saved_cnt] = iova;
-		ioa->saved_size[ioa->saved_cnt] = size;
-		ccio_saved_cnt++;
-	} else {
-		do {
+#ifdef CONFIG_PROC_FS
+	ioc->usingle_calls++;
+	ioc->usingle_pages += size >> IOVP_SHIFT;
 #endif
-			ccio_mark_invalid(ioa, iova, size);
-			ccio_free_range(ioa, iova, size);
 
-#ifdef DELAYED_RESOURCE_CNT
-			d->saved_cnt--;
-			iova = ioa->saved_iova[ioa->saved_cnt];
-			size = ioa->saved_size[ioa->saved_cnt];
-		} while (ioa->saved_cnt)
-	}
-#endif
+	ccio_mark_invalid(ioc, iova, size);
+	ccio_free_range(ioc, iova, (size >> IOVP_SHIFT));
+	spin_unlock_irqrestore(&ioc->res_lock, flags);
 }
 
-
-static void * ccio_alloc_consistent (struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle)
+/**
+ * ccio_alloc_consistent - Allocate a consistent DMA mapping.
+ * @dev: The PCI device.
+ * @size: The length of the DMA region.
+ * @dma_handle: The DMA address handed back to the device (not the cpu).
+ *
+ * This function implements the pci_alloc_consistent function.
+ */
+static void * 
+ccio_alloc_consistent(struct pci_dev *dev, size_t size, dma_addr_t *dma_handle)
 {
-	void *ret;
-	unsigned long flags;
-	struct ccio_device *ioa = ccio_list;
-
-	DBG_RUN(__FUNCTION__ " size 0x%x\n",  size);
-
+      void *ret;
 #if 0
 /* GRANT Need to establish hierarchy for non-PCI devs as well
 ** and then provide matching gsc_map_xxx() functions for them as well.
 */
-	if (!hwdev) {
+	if(!hwdev) {
 		/* only support PCI */
 		*dma_handle = 0;
 		return 0;
 	}
 #endif
-	spin_lock_irqsave(&ioa->ccio_lock, flags);
-	ccio_alloc_size += get_order(size);
-	spin_unlock_irqrestore(&ioa->ccio_lock, flags);
-
         ret = (void *) __get_free_pages(GFP_ATOMIC, get_order(size));
 
 	if (ret) {
 		memset(ret, 0, size);
-		*dma_handle = ccio_map_single(hwdev, ret, size, PCI_DMA_BIDIRECTIONAL);
+		*dma_handle = ccio_map_single(dev, ret, size, PCI_DMA_BIDIRECTIONAL);
 	}
-	DBG_RUN(__FUNCTION__ " ret %p\n",  ret);
 
 	return ret;
 }
 
-
-static void ccio_free_consistent (struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
+/**
+ * ccio_free_consistent - Free a consistent DMA mapping.
+ * @dev: The PCI device.
+ * @size: The length of the DMA region.
+ * @cpu_addr: The cpu address returned from the ccio_alloc_consistent.
+ * @dma_handle: The device address returned from the ccio_alloc_consistent.
+ *
+ * This function implements the pci_free_consistent function.
+ */
+static void 
+ccio_free_consistent(struct pci_dev *dev, size_t size, void *cpu_addr, 
+		     dma_addr_t dma_handle)
 {
-	unsigned long flags;
-	struct ccio_device *ioa = ccio_list;
+	ccio_unmap_single(dev, dma_handle, size, 0);
+	free_pages((unsigned long)cpu_addr, get_order(size));
+}
 
-	spin_lock_irqsave(&ioa->ccio_lock, flags);
-	ccio_free_size += get_order(size);
-	spin_unlock_irqrestore(&ioa->ccio_lock, flags);
+/*
+** Since 0 is a valid pdir_base index value, can't use that
+** to determine if a value is valid or not. Use a flag to indicate
+** the SG list entry contains a valid pdir index.
+*/
+#define PIDE_FLAG 0x80000000UL
 
-	ccio_unmap_single(hwdev, dma_handle, size, 0);
-	free_pages((unsigned long) vaddr, get_order(size));
+/**
+ * ccio_fill_pdir - Insert coalesced scatter/gather chunks into the I/O Pdir.
+ * @ioc: The I/O Controller.
+ * @startsg: The scatter/gather list of coalesced chunks.
+ * @nents: The number of entries in the scatter/gather list.
+ * @hint: The DMA Hint.
+ *
+ * This function inserts the coalesced scatter/gather list chunks into the
+ * I/O Controller's I/O Pdir.
+ */ 
+static CCIO_INLINE int
+ccio_fill_pdir(struct ioc *ioc, struct scatterlist *startsg, int nents, 
+	       unsigned long hint)
+{
+	struct scatterlist *dma_sg = startsg;	/* pointer to current DMA */
+	int n_mappings = 0;
+	u64 *pdirp = 0;
+	unsigned long dma_offset = 0;
+
+	dma_sg--;
+	while (nents-- > 0) {
+		int cnt = sg_dma_len(startsg);
+		sg_dma_len(startsg) = 0;
+
+		DBG_RUN_SG(" %d : %08lx/%05x %p/%05x\n", nents,
+			   (unsigned long)sg_dma_address(startsg), cnt,
+			   startsg->address, startsg->length
+		);
+
+		/*
+		** Look for the start of a new DMA stream
+		*/
+		if(sg_dma_address(startsg) & PIDE_FLAG) {
+			u32 pide = sg_dma_address(startsg) & ~PIDE_FLAG;
+			dma_offset = (unsigned long) pide & ~IOVP_MASK;
+			sg_dma_address(startsg) = 0;
+			dma_sg++;
+			sg_dma_address(dma_sg) = pide;
+			pdirp = &(ioc->pdir_base[pide >> IOVP_SHIFT]);
+			n_mappings++;
+		}
+
+		/*
+		** Look for a VCONTIG chunk
+		*/
+		if (cnt) {
+			unsigned long vaddr = (unsigned long)startsg->address;
+			ASSERT(pdirp);
+
+			/* Since multiple Vcontig blocks could make up
+			** one DMA stream, *add* cnt to dma_len.
+			*/
+			sg_dma_len(dma_sg) += cnt;
+			cnt += dma_offset;
+			dma_offset=0;	/* only want offset on first chunk */
+			cnt = ROUNDUP(cnt, IOVP_SIZE);
+#ifdef CONFIG_PROC_FS
+			ioc->msg_pages += cnt >> IOVP_SHIFT;
+#endif
+			do {
+				ccio_io_pdir_entry(pdirp, KERNEL_SPACE, 
+						   (void *)vaddr, hint);
+				vaddr += IOVP_SIZE;
+				cnt -= IOVP_SIZE;
+				pdirp++;
+			} while (cnt > 0);
+		}
+		startsg++;
+	}
+	return(n_mappings);
 }
 
+/*
+** First pass is to walk the SG list and determine where the breaks are
+** in the DMA stream. Allocates PDIR entries but does not fill them.
+** Returns the number of DMA chunks.
+**
+** Doing the fill seperate from the coalescing/allocation keeps the
+** code simpler. Future enhancement could make one pass through
+** the sglist do both.
+*/
 
-static int ccio_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
+static CCIO_INLINE int
+ccio_coalesce_chunks(struct ioc *ioc, struct scatterlist *startsg, int nents)
 {
-	int tmp = nents;
+	struct scatterlist *vcontig_sg;    /* VCONTIG chunk head */
+	unsigned long vcontig_len;         /* len of VCONTIG chunk */
+	unsigned long vcontig_end;
+	struct scatterlist *dma_sg;        /* next DMA stream head */
+	unsigned long dma_offset, dma_len; /* start/len of DMA stream */
+	int n_mappings = 0;
+
+	while (nents > 0) {
+
+		/*
+		** Prepare for first/next DMA stream
+		*/
+		dma_sg = vcontig_sg = startsg;
+		dma_len = vcontig_len = vcontig_end = startsg->length;
+		vcontig_end += (unsigned long) startsg->address;
+		dma_offset = (unsigned long) startsg->address & ~IOVP_MASK;
+
+		/* PARANOID: clear entries */
+		sg_dma_address(startsg) = 0;
+		sg_dma_len(startsg) = 0;
+
+		/*
+		** This loop terminates one iteration "early" since
+		** it's always looking one "ahead".
+		*/
+		while(--nents > 0) {
+			unsigned long startsg_end;
 
-	DBG_RUN(KERN_WARNING __FUNCTION__ " START\n");
+			startsg++;
+			startsg_end = (unsigned long)startsg->address + 
+				startsg->length;
+
+			/* PARANOID: clear entries */
+			sg_dma_address(startsg) = 0;
+			sg_dma_len(startsg) = 0;
+
+			/*
+			** First make sure current dma stream won't
+			** exceed DMA_CHUNK_SIZE if we coalesce the
+			** next entry.
+			*/   
+			if(ROUNDUP(dma_len + dma_offset + startsg->length,
+				   IOVP_SIZE) > DMA_CHUNK_SIZE)
+				break;
+
+			/*
+			** Append the next transaction?
+			*/
+			if(vcontig_end == (unsigned long) startsg->address) {
+				vcontig_len += startsg->length;
+				vcontig_end += startsg->length;
+				dma_len     += startsg->length;
+				continue;
+			}
+
+			/*
+			** Not virtually contigous.
+			** Terminate prev chunk.
+			** Start a new chunk.
+			**
+			** Once we start a new VCONTIG chunk, dma_offset
+			** can't change. And we need the offset from the first
+			** chunk - not the last one. Ergo Successive chunks
+			** must start on page boundaries and dove tail
+			** with it's predecessor.
+			*/
+			sg_dma_len(vcontig_sg) = vcontig_len;
+
+			vcontig_sg = startsg;
+			vcontig_len = startsg->length;
+			break;
+		}
 
-        /* KISS: map each buffer seperately. */
-	while (nents) {
-		sg_dma_address(sglist) = ccio_map_single(dev, sglist->address, sglist->length, direction);
-		sg_dma_len(sglist) = sglist->length;
-		nents--;
-		sglist++;
+		/*
+		** End of DMA Stream
+		** Terminate last VCONTIG block.
+		** Allocate space for DMA stream.
+		*/
+		sg_dma_len(vcontig_sg) = vcontig_len;
+		dma_len = ROUNDUP(dma_len + dma_offset, IOVP_SIZE);
+		sg_dma_address(dma_sg) =
+			PIDE_FLAG 
+			| (ccio_alloc_range(ioc, (dma_len >> IOVP_SHIFT)) << IOVP_SHIFT)
+			| dma_offset;
+		n_mappings++;
 	}
 
-	DBG_RUN(KERN_WARNING __FUNCTION__ " DONE\n");
-	return tmp;
+	return n_mappings;
 }
 
-
-static void ccio_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
+/**
+ * ccio_map_sg - Map the scatter/gather list into the IOMMU.
+ * @dev: The PCI device.
+ * @sglist: The scatter/gather list to be mapped in the IOMMU.
+ * @nents: The number of entries in the scatter/gather list.
+ * @direction: The direction of the DMA transaction (to/from device).
+ *
+ * This function implements the pci_map_sg function.
+ */
+static int
+ccio_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, 
+	    int direction)
 {
-	DBG_RUN(KERN_WARNING __FUNCTION__ " : unmapping %d entries\n", nents);
-	while (nents) {
-		ccio_unmap_single(dev, sg_dma_address(sglist), sg_dma_len(sglist), direction);
-		nents--;
-		sglist++;
+	struct ioc *ioc;
+	int coalesced, filled = 0;
+	unsigned long flags;
+	unsigned long hint = hint_lookup[direction];
+	
+	ASSERT(dev);
+	ASSERT(dev->sysdata);
+	ASSERT(HBA_DATA(dev->sysdata)->iommu);
+	ioc = GET_IOC(dev);
+	
+	DBG_RUN_SG("%s() START %d entries\n", __FUNCTION__, nents);
+
+	/* Fast path single entry scatterlists. */
+	if(nents == 1) {
+		sg_dma_address(sglist)= ccio_map_single(dev, sglist->address,
+							sglist->length, 
+							direction);
+		sg_dma_len(sglist)= sglist->length;
+		return 1;
 	}
-	return;
+	
+	spin_lock_irqsave(&ioc->res_lock, flags);
+
+#ifdef CONFIG_PROC_FS
+	ioc->msg_calls++;
+#endif
+
+	/*
+	** First coalesce the chunks and allocate I/O pdir space
+	**
+	** If this is one DMA stream, we can properly map using the
+	** correct virtual address associated with each DMA page.
+	** w/o this association, we wouldn't have coherent DMA!
+	** Access to the virtual address is what forces a two pass algorithm.
+	*/
+	coalesced = ccio_coalesce_chunks(ioc, sglist, nents);
+
+	/*
+	** Program the I/O Pdir
+	**
+	** map the virtual addresses to the I/O Pdir
+	** o dma_address will contain the pdir index
+	** o dma_len will contain the number of bytes to map 
+	** o address contains the virtual address.
+	*/
+	filled = ccio_fill_pdir(ioc, sglist, nents, hint);
+
+	spin_unlock_irqrestore(&ioc->res_lock, flags);
+
+	ASSERT(coalesced == filled);
+	DBG_RUN_SG("%s() DONE %d mappings\n", __FUNCTION__, filled);
+
+	return filled;
 }
 
+/**
+ * ccio_unmap_sg - Unmap the scatter/gather list from the IOMMU.
+ * @dev: The PCI device.
+ * @sglist: The scatter/gather list to be unmapped from the IOMMU.
+ * @nents: The number of entries in the scatter/gather list.
+ * @direction: The direction of the DMA transaction (to/from device).
+ *
+ * This function implements the pci_unmap_sg function.
+ */
+static void 
+ccio_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, 
+	      int direction)
+{
+	struct ioc *ioc;
+
+	ASSERT(dev);
+	ASSERT(dev->sysdata);
+	ASSERT(HBA_DATA(dev->sysdata)->iommu);
+	ioc = GET_IOC(dev);
+
+	DBG_RUN_SG("%s() START %d entries,  %p,%x\n",
+		__FUNCTION__, nents, sglist->address, sglist->length);
+
+#ifdef CONFIG_PROC_FS
+	ioc->usg_calls++;
+#endif
+
+	while(sg_dma_len(sglist) && nents--) {
+
+#ifdef CONFIG_PROC_FS
+		ioc->usg_pages += sg_dma_len(sglist) >> PAGE_SHIFT;
+#endif
+		ccio_unmap_single(dev, sg_dma_address(sglist),
+				  sg_dma_len(sglist), direction);
+		++sglist;
+	}
+
+	DBG_RUN_SG("%s() DONE (nents %d)\n", __FUNCTION__, nents);
+}
 
 static struct pci_dma_ops ccio_ops = {
 	ccio_dma_supported,
@@ -861,6 +1076,201 @@
 	NULL,                   /* dma_sync_sg     : ditto */
 };
 
+#ifdef CONFIG_PROC_FS
+static int proc_append(char *src, int len, char **dst, off_t *offset, int *max)
+{
+	if (len < *offset) {
+		*offset -= len;
+		return 0;
+	}
+	if (*offset > 0) {
+		src += *offset;
+		len -= *offset;
+		*offset = 0;
+	}
+	if (len > *max) {
+		len = *max;
+	}
+	memcpy(*dst, src, len);
+	*dst += len;
+	*max -= len;
+	return (*max == 0);
+}
+
+static int ccio_proc_info(char *buf, char **start, off_t offset, int count,
+			  int *eof, void *data)
+{
+	int max = count;
+	char tmp[80]; /* width of an ANSI-standard terminal */
+	struct ioc *ioc = ioc_list;
+
+	while (ioc != NULL) {
+		unsigned int total_pages = ioc->res_size << 3;
+		unsigned long avg = 0, min, max;
+		int j, len;
+
+		len = sprintf(tmp, "%s\n", ioc->name);
+		if (proc_append(tmp, len, &buf, &offset, &count))
+			break;
+		
+		len = sprintf(tmp, "Cujo 2.0 bug    : %s\n",
+			      (ioc->cujo20_bug ? "yes" : "no"));
+		if (proc_append(tmp, len, &buf, &offset, &count))
+			break;
+		
+		len = sprintf(tmp, "IO PDIR size    : %d bytes (%d entries)\n",
+			      total_pages * 8, total_pages);
+		if (proc_append(tmp, len, &buf, &offset, &count))
+			break;
+		
+		len = sprintf(tmp, "IO PDIR entries : %ld free  %ld used (%d%%)\n",
+			      total_pages - ioc->used_pages, ioc->used_pages,
+			      (int)(ioc->used_pages * 100 / total_pages));
+		if (proc_append(tmp, len, &buf, &offset, &count))
+			break;
+		
+		len = sprintf(tmp, "Resource bitmap : %d bytes (%d pages)\n", 
+			ioc->res_size, total_pages);
+		if (proc_append(tmp, len, &buf, &offset, &count))
+			break;
+		
+		min = max = ioc->avg_search[0];
+		for(j = 0; j < CCIO_SEARCH_SAMPLE; ++j) {
+			avg += ioc->avg_search[j];
+			if(ioc->avg_search[j] > max) 
+				max = ioc->avg_search[j];
+			if(ioc->avg_search[j] < min) 
+				min = ioc->avg_search[j];
+		}
+		avg /= CCIO_SEARCH_SAMPLE;
+		len = sprintf(tmp, "  Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n",
+			      min, avg, max);
+		if (proc_append(tmp, len, &buf, &offset, &count))
+			break;
+
+		len = sprintf(tmp, "pci_map_single(): %8ld calls  %8ld pages (avg %d/1000)\n",
+			      ioc->msingle_calls, ioc->msingle_pages,
+			      (int)((ioc->msingle_pages * 1000)/ioc->msingle_calls));
+		if (proc_append(tmp, len, &buf, &offset, &count))
+			break;
+		
+
+		/* KLUGE - unmap_sg calls unmap_single for each mapped page */
+		min = ioc->usingle_calls - ioc->usg_calls;
+		max = ioc->usingle_pages - ioc->usg_pages;
+		len = sprintf(tmp, "pci_unmap_single: %8ld calls  %8ld pages (avg %d/1000)\n",
+			      min, max, (int)((max * 1000)/min));
+		if (proc_append(tmp, len, &buf, &offset, &count))
+			break;
+ 
+		len = sprintf(tmp, "pci_map_sg()    : %8ld calls  %8ld pages (avg %d/1000)\n",
+			      ioc->msg_calls, ioc->msg_pages,
+			      (int)((ioc->msg_pages * 1000)/ioc->msg_calls));
+		if (proc_append(tmp, len, &buf, &offset, &count))
+			break;
+		len = sprintf(tmp, "pci_unmap_sg()  : %8ld calls  %8ld pages (avg %d/1000)\n\n\n",
+			      ioc->usg_calls, ioc->usg_pages,
+			      (int)((ioc->usg_pages * 1000)/ioc->usg_calls));
+		if (proc_append(tmp, len, &buf, &offset, &count))
+			break;
+
+		ioc = ioc->next;
+	}
+
+	if (count == 0) {
+		*eof = 1;
+	}
+	return (max - count);
+}
+
+static int ccio_resource_map(char *buf, char **start, off_t offset, int len,
+			     int *eof, void *data)
+{
+	struct ioc *ioc = ioc_list;
+
+	buf[0] = '\0';
+	while (ioc != NULL) {
+		u32 *res_ptr = (u32 *)ioc->res_map;
+		int j;
+
+		for (j = 0; j < (ioc->res_size / sizeof(u32)); j++) {
+			if ((j & 7) == 0)
+				strcat(buf,"\n   ");
+			sprintf(buf, "%s %08x", buf, *res_ptr);
+			res_ptr++;
+		}
+		strcat(buf, "\n\n");
+		ioc = ioc->next;
+		break; /* XXX - remove me */
+	}
+
+	return strlen(buf);
+}
+#endif
+
+/**
+ * ccio_find_ioc - Find the ioc in the ioc_list
+ * @hw_path: The hardware path of the ioc.
+ *
+ * This function searches the ioc_list for an ioc that matches
+ * the provide hardware path.
+ */
+static struct ioc * ccio_find_ioc(int hw_path)
+{
+	int i;
+	struct ioc *ioc;
+
+	ioc = ioc_list;
+	for (i = 0; i < ioc_count; i++) {
+		if (ioc->hw_path == hw_path)
+			return ioc;
+
+		ioc = ioc->next;
+	}
+
+	return NULL;
+}
+
+/**
+ * ccio_get_iommu - Find the iommu which controls this device
+ * @dev: The parisc device.
+ *
+ * This function searches through the registerd IOMMU's and returns the
+ * appropriate IOMMU for the device based upon the devices hardware path.
+ */
+void * ccio_get_iommu(const struct parisc_device *dev)
+{
+	dev = find_pa_parent_type(dev, HPHW_IOA);
+	if (!dev)
+		return NULL;
+
+	return ccio_find_ioc(dev->hw_path);
+}
+
+#define CUJO_20_STEP       0x10000000	/* inc upper nibble */
+
+/* Cujo 2.0 has a bug which will silently corrupt data being transferred
+ * to/from certain pages.  To avoid this happening, we mark these pages
+ * as `used', and ensure that nothing will try to allocate from them.
+ */
+void ccio_cujo20_fixup(struct parisc_device *dev, u32 iovp)
+{
+	unsigned int idx;
+	struct ioc *ioc = ccio_get_iommu(dev);
+	u8 *res_ptr;
+
+#ifdef CONFIG_PROC_FS
+	ioc->cujo20_bug = 1;
+#endif
+	res_ptr = ioc->res_map;
+	idx = PDIR_INDEX(iovp) >> 3;
+
+	while (idx < ioc->res_size) {
+ 		res_ptr[idx] |= 0xff;
+		idx += PDIR_INDEX(CUJO_20_STEP) >> 3;
+	}
+}
+
 #if 0
 /* GRANT -  is this needed for U2 or not? */
 
@@ -875,38 +1285,37 @@
 ** I think only Java (K/D/R-class too?) systems don't do this.
 */
 static int
-ccio_get_iotlb_size(struct hp_device *d)
+ccio_get_iotlb_size(struct parisc_device *dev)
 {
-	if(d->spa_shift == 0) {
-		panic(__FUNCTION__ ": Can't determine I/O TLB size.\n");
+	if (dev->spa_shift == 0) {
+		panic("%s() : Can't determine I/O TLB size.\n", __FUNCTION__);
 	}
-	return(1 << d->spa_shift);
+	return (1 << dev->spa_shift);
 }
 #else
 
 /* Uturn supports 256 TLB entries */
 #define CCIO_CHAINID_SHIFT	8
 #define CCIO_CHAINID_MASK	0xff
-
 #endif /* 0 */
 
-
-/*
-** Figure out how big the I/O PDIR should be and alloc it.
-** Also sets variables which depend on pdir size.
-*/
+/**
+ * ccio_ioc_init - Initalize the I/O Controller
+ * @ioc: The I/O Controller.
+ *
+ * Initalize the I/O Controller which includes setting up the
+ * I/O Page Directory, the resource map, and initalizing the
+ * U2/Uturn chip into virtual mode.
+ */
 static void
-ccio_alloc_pdir(struct ccio_device *ioa)
+ccio_ioc_init(struct ioc *ioc)
 {
-	extern unsigned long mem_max;          /* arch.../setup.c */
-
-	u32 iova_space_size = 0;
-	void * pdir_base;
-	int pdir_size, iov_order;
+	int i, iov_order;
+	u32 iova_space_size;
+	unsigned long physmem;
 
 	/*
 	** Determine IOVA Space size from memory size.
-	** Using "mem_max" is a kluge.
 	**
 	** Ideally, PCI drivers would register the maximum number
 	** of DMA they can have outstanding for each device they
@@ -915,15 +1324,18 @@
 	** methods still require some "extra" to support PCI
 	** Hot-Plug/Removal of PCI cards. (aka PCI OLARD).
 	*/
+
 	/* limit IOVA space size to 1MB-1GB */
-	if (mem_max < (ccio_mem_ratio*1024*1024)) {
-		iova_space_size = 1024*1024;
+
+	physmem = num_physpages << PAGE_SHIFT;
+	if(physmem < (ccio_mem_ratio * 1024 * 1024)) {
+		iova_space_size = 1024 * 1024;
 #ifdef __LP64__
-	} else if (mem_max > (ccio_mem_ratio*512*1024*1024)) {
-		iova_space_size = 512*1024*1024;
+	} else if(physmem > (ccio_mem_ratio * 512 * 1024 * 1024)) {
+		iova_space_size = 512 * 1024 * 1024;
 #endif
 	} else {
-		iova_space_size = (u32) (mem_max/ccio_mem_ratio);
+		iova_space_size = (u32)(physmem / ccio_mem_ratio);
 	}
 
 	/*
@@ -933,277 +1345,271 @@
 
 	/* We could use larger page sizes in order to *decrease* the number
 	** of mappings needed.  (ie 8k pages means 1/2 the mappings).
-        **
+	**
 	** Note: Grant Grunder says "Using 8k I/O pages isn't trivial either
 	**   since the pages must also be physically contiguous - typically
 	**   this is the case under linux."
 	*/
 
-	iov_order = get_order(iova_space_size);
+	iov_order = get_order(iova_space_size) >> (IOVP_SHIFT - PAGE_SHIFT);
 	ASSERT(iov_order <= (30 - IOVP_SHIFT));   /* iova_space_size <= 1GB */
 	ASSERT(iov_order >= (20 - IOVP_SHIFT));   /* iova_space_size >= 1MB */
 	iova_space_size = 1 << (iov_order + IOVP_SHIFT);
 
-	ioa->pdir_size = pdir_size = (iova_space_size/IOVP_SIZE) * sizeof(u64);
+	ioc->pdir_size = (iova_space_size / IOVP_SIZE) * sizeof(u64);
 
-	ASSERT(pdir_size < 4*1024*1024);   /* max pdir size < 4MB */
+	ASSERT(ioc->pdir_size < 4 * 1024 * 1024);   /* max pdir size < 4MB */
 
 	/* Verify it's a power of two */
-	ASSERT((1 << get_order(pdir_size)) == (pdir_size >> PAGE_SHIFT));
+	ASSERT((1 << get_order(ioc->pdir_size)) == (ioc->pdir_size >> PAGE_SHIFT));
 
-	DBG_INIT(__FUNCTION__ " hpa 0x%p mem %dMB IOV %dMB (%d bits)\n    PDIR size 0x%0x",
-		ioa->ccio_hpa, (int) (mem_max>>20), iova_space_size>>20,
-		iov_order + PAGE_SHIFT, pdir_size);
-
-	ioa->pdir_base =
-	pdir_base = (void *) __get_free_pages(GFP_KERNEL, get_order(pdir_size));
-	if (NULL == pdir_base)
-	{
-		panic(__FILE__ ":" __FUNCTION__ "() could not allocate I/O Page Table\n");
+	DBG_INIT("%s() hpa 0x%p mem %luMB IOV %dMB (%d bits) PDIR size 0x%0x",
+		__FUNCTION__, ioc->ioc_hpa, physmem>>20, iova_space_size>>20,
+		 iov_order + PAGE_SHIFT, ioc->pdir_size);
+
+	ioc->pdir_base = (u64 *)__get_free_pages(GFP_KERNEL, 
+						 get_order(ioc->pdir_size));
+	if(NULL == ioc->pdir_base) {
+		panic(__FILE__ ":%s() could not allocate I/O Page Table\n", __FUNCTION__);
 	}
-	memset(pdir_base, 0, pdir_size);
+	memset(ioc->pdir_base, 0, ioc->pdir_size);
 
-	ASSERT((((unsigned long) pdir_base) & PAGE_MASK) == (unsigned long) pdir_base);
+	ASSERT((((unsigned long)ioc->pdir_base) & PAGE_MASK) == (unsigned long)ioc->pdir_base);
+	DBG_INIT(" base %p", ioc->pdir_base);
 
-	DBG_INIT(" base %p", pdir_base);
+	/* resource map size dictated by pdir_size */
+ 	ioc->res_size = (ioc->pdir_size / sizeof(u64)) >> 3;
+	DBG_INIT("%s() res_size 0x%x\n", __FUNCTION__, ioc->res_size);
+	
+	ioc->res_map = (u8 *)__get_free_pages(GFP_KERNEL, 
+					      get_order(ioc->res_size));
+	if(NULL == ioc->res_map) {
+		panic(__FILE__ ":%s() could not allocate resource map\n", __FUNCTION__);
+	}
+	memset(ioc->res_map, 0, ioc->res_size);
+
+	/* Initialize the res_hint to 16 */
+	ioc->res_hint = 16;
+
+	/* Initialize the spinlock */
+	spin_lock_init(&ioc->res_lock);
 
 	/*
 	** Chainid is the upper most bits of an IOVP used to determine
 	** which TLB entry an IOVP will use.
 	*/
-	ioa->chainid_shift = get_order(iova_space_size)+PAGE_SHIFT-CCIO_CHAINID_SHIFT;
-
-	DBG_INIT(" chainid_shift 0x%x\n", ioa->chainid_shift);
-}
-
-
-static void
-ccio_hw_init(struct ccio_device *ioa)
-{
-	int i;
+	ioc->chainid_shift = get_order(iova_space_size) + PAGE_SHIFT - CCIO_CHAINID_SHIFT;
+	DBG_INIT(" chainid_shift 0x%x\n", ioc->chainid_shift);
 
 	/*
 	** Initialize IOA hardware
 	*/
-	WRITE_U32(CCIO_CHAINID_MASK << ioa->chainid_shift, &ioa->ccio_hpa->io_chain_id_mask);
-	WRITE_U32(virt_to_phys(ioa->pdir_base), &ioa->ccio_hpa->io_pdir_base);
+	WRITE_U32(CCIO_CHAINID_MASK << ioc->chainid_shift, 
+		  &ioc->ioc_hpa->io_chain_id_mask);
 
+	WRITE_U32(virt_to_phys(ioc->pdir_base), 
+		  &ioc->ioc_hpa->io_pdir_base);
 
 	/*
 	** Go to "Virtual Mode"
 	*/
-	WRITE_U32(IOA_NORMAL_MODE, &ioa->ccio_hpa->io_control);
+	WRITE_U32(IOA_NORMAL_MODE, &ioc->ioc_hpa->io_control);
 
 	/*
 	** Initialize all I/O TLB entries to 0 (Valid bit off).
 	*/
-	WRITE_U32(0, &ioa->ccio_hpa->io_tlb_entry_m);
-	WRITE_U32(0, &ioa->ccio_hpa->io_tlb_entry_l);
+	WRITE_U32(0, &ioc->ioc_hpa->io_tlb_entry_m);
+	WRITE_U32(0, &ioc->ioc_hpa->io_tlb_entry_l);
 
-	for (i = 1 << CCIO_CHAINID_SHIFT; i ; i--) {
-		WRITE_U32((CMD_TLB_DIRECT_WRITE | (i << ioa->chainid_shift)),
-					&ioa->ccio_hpa->io_command);
+	for(i = 1 << CCIO_CHAINID_SHIFT; i ; i--) {
+		WRITE_U32((CMD_TLB_DIRECT_WRITE | (i << ioc->chainid_shift)),
+			  &ioc->ioc_hpa->io_command);
 	}
-
 }
 
-
 static void
-ccio_resmap_init(struct ccio_device *ioa)
+ccio_init_resource(struct resource *res, char *name, unsigned long ioaddr)
 {
-	u32 res_size;
-
-	/*
-	** Ok...we do more than just init resource map
-	*/
-	ioa->ccio_lock = SPIN_LOCK_UNLOCKED;
+	int result;
 
-	ioa->res_hint = 16;    /* next available IOVP - circular search */
-
-	/* resource map size dictated by pdir_size */
-	res_size = ioa->pdir_size/sizeof(u64); /* entries */
-	res_size >>= 3;	/* convert bit count to byte count */
-	DBG_INIT(__FUNCTION__ "() res_size 0x%x\n", res_size);
-
-	ioa->res_size = res_size;
-	ioa->res_map = (char *) __get_free_pages(GFP_KERNEL, get_order(res_size));
-	if (NULL == ioa->res_map)
-	{
-		panic(__FILE__ ":" __FUNCTION__ "() could not allocate resource map\n");
+	res->flags = IORESOURCE_MEM;
+	res->start = (unsigned long)(signed) __raw_readl(ioaddr) << 16;
+	res->end = (unsigned long)(signed) (__raw_readl(ioaddr + 4) << 16) - 1;
+	if (res->end + 1 == res->start)
+		return;
+	res->name = name;
+	result = request_resource(&iomem_resource, res);
+	if (result < 0) {
+		printk(KERN_ERR 
+		       "%s: failed to claim CCIO bus address space (%p,%p)\n", 
+		       __FILE__, res->start, res->end);
 	}
-	memset(ioa->res_map, 0, res_size);
 }
 
-/* CUJO20 KLUDGE start */
-static struct {
-		u16 hversion;
-		u8  spa;
-		u8  type;
-		u32     foo[3];	/* 16 bytes total */
-} cujo_iodc __attribute__ ((aligned (64)));
-static unsigned long cujo_result[32] __attribute__ ((aligned (16))) = {0,0,0,0};
+static void __init ccio_init_resources(struct ioc *ioc)
+{
+	struct resource *res = ioc->mmio_region;
+	char *name = kmalloc(14, GFP_KERNEL);
 
-/*
-** CUJO 2.0 incorrectly decodes a memory access for specific
-** pages (every page at specific iotlb locations dependent
-** upon where the cujo is flexed - diff on raven/firehawk.
-** resulting in an hpmc and/or silent data corruption.
-** Workaround is to prevent use of those I/O TLB entries
-** by marking the suspect bitmap range entries as busy.
-*/
-static void
-ccio_cujo20_hack(struct ccio_device *ioa)
+	sprintf(name, "GSC Bus [%d/]", ioc->hw_path);
+
+	ccio_init_resource(res, name, (unsigned long)&ioc->ioc_hpa->io_io_low);
+	ccio_init_resource(res + 1, name,
+			(unsigned long)&ioc->ioc_hpa->io_io_low_hv);
+}
+
+static void expand_ioc_area(struct ioc *ioc, unsigned long size,
+		unsigned long min, unsigned long max, unsigned long align)
 {
-	unsigned long status;
-	unsigned int idx;
-	u8 *res_ptr = ioa->res_map;
-	u32 iovp=0x0;
-	unsigned long mask;
+#ifdef NASTY_HACK_FOR_K_CLASS
+	__raw_writel(0xfffff600, (unsigned long)&(ioc->ioc_hpa->io_io_high));
+	ioc->mmio_region[0].end = 0xf5ffffff;
+#endif
+}
 
-	status = pdc_iodc_read( &cujo_result, (void *) CUJO_RAVEN_LOC, 0, &cujo_iodc, 16);
-	if (status == 0) {
-		if (cujo_iodc.hversion==CUJO_20_BADHVERS)
-			iovp = CUJO_20_BADPAGE1;
+static struct resource *ccio_get_resource(struct ioc* ioc,
+		const struct parisc_device *dev)
+{
+	if (!ioc) {
+		return &iomem_resource;
+	} else if ((ioc->mmio_region->start <= dev->hpa) &&
+			(dev->hpa < ioc->mmio_region->end)) {
+		return ioc->mmio_region;
+	} else if (((ioc->mmio_region + 1)->start <= dev->hpa) &&
+			(dev->hpa < (ioc->mmio_region + 1)->end)) {
+		return ioc->mmio_region + 1;
 	} else {
-		status = pdc_iodc_read( &cujo_result, (void *) CUJO_FIREHAWK_LOC, 0, &cujo_iodc, 16);
-		if (status == 0) {
-			if (cujo_iodc.hversion==CUJO_20_BADHVERS)
-				iovp = CUJO_20_BADPAGE2;
-		} else {
-			/* not a defective system */
-			return;
-		}
+		return NULL;
 	}
+}
 
-	printk(MODULE_NAME ": Cujo 2.0 bug needs a work around\n");
-	ccio_cujo_bug = 1;
+int ccio_allocate_resource(const struct parisc_device *dev,
+		struct resource *res, unsigned long size,
+		unsigned long min, unsigned long max, unsigned long align,
+		void (*alignf)(void *, struct resource *, unsigned long),
+		void *alignf_data)
+{
+	struct ioc *ioc = ccio_get_iommu(dev);
+	struct resource *parent = ccio_get_resource(ioc, dev);
+	if (!parent)
+		return -EBUSY;
 
-	/*
-	** mark bit entries that match "bad page"
-	*/
-	idx = PDIR_INDEX(iovp)>>3;
-	mask = 0xff;
-	
-	while(idx * sizeof(u8) < ioa->res_size) {
-		res_ptr[idx] |= mask;
-		idx += (PDIR_INDEX(CUJO_20_STEP)>>3);
-		ccio_used_pages += 8;
-		ccio_used_bytes += 1;
-	}
+	if (!allocate_resource(parent, res, size, min, max, align, alignf,
+			alignf_data))
+		return 0;
+
+	expand_ioc_area(ioc, size, min, max, align);
+	return allocate_resource(parent, res, size, min, max, align, alignf,
+			alignf_data);
 }
-/* CUJO20 KLUDGE end */
 
-#ifdef CONFIG_PROC_FS
-static int ccio_proc_info(char *buf, char **start, off_t offset, int len)
+int ccio_request_resource(const struct parisc_device *dev,
+		struct resource *res)
 {
-	unsigned long i = 0;
-	struct ccio_device *ioa = ccio_list;
-	unsigned long *res_ptr = (unsigned long *)ioa->res_map;
-	unsigned long total_pages = ioa->res_size << 3;            /* 8 bits per byte */
-
-	sprintf(buf, "%s\nCujo 2.0 bug    : %s\n",
-		parisc_getHWdescription(ioa->iodc->hw_type, ioa->iodc->hversion,
-					ioa->iodc->sversion),
-		(ccio_cujo_bug ? "yes" : "no"));
-
-	sprintf(buf, "%sIO pdir size    : %d bytes (%d entries)\n",
-		buf, ((ioa->res_size << 3) * sizeof(u64)), /* 8 bits per byte */
-		ioa->res_size << 3);                       /* 8 bits per byte */
+	struct ioc *ioc = ccio_get_iommu(dev);
+	struct resource *parent = ccio_get_resource(ioc, dev);
+
+	return request_resource(parent, res);
+}
+/**
+ * ccio_probe - Determine if ccio should claim this device.
+ * @dev: The device which has been found
+ *
+ * Determine if ccio should claim this chip (return 0) or not (return 1).
+ * If so, initialize the chip and tell other partners in crime they
+ * have work to do.
+ */
+static int ccio_probe(struct parisc_device *dev)
+{
+	int i;
+	struct ioc *ioc, **ioc_p = &ioc_list;
 	
-	sprintf(buf, "%sResource bitmap : %d bytes (%d pages)\n", 
-		buf, ioa->res_size, ioa->res_size << 3);   /* 8 bits per byte */
+	ioc = kmalloc(sizeof(struct ioc), GFP_KERNEL);
+	if (ioc == NULL) {
+		printk(KERN_ERR MODULE_NAME ": memory allocation failure\n");
+		return 1;
+	}
+	memset(ioc, 0, sizeof(struct ioc));
 
-	strcat(buf,  "     	  total:    free:    used:   % used:\n");
-	sprintf(buf, "%sblocks  %8d %8ld %8ld %8ld%%\n", buf, ioa->res_size,
-		ioa->res_size - ccio_used_bytes, ccio_used_bytes,
-		(ccio_used_bytes * 100) / ioa->res_size);
-
-	sprintf(buf, "%spages   %8ld %8ld %8ld %8ld%%\n", buf, total_pages,
-		total_pages - ccio_used_pages, ccio_used_pages,
-		(ccio_used_pages * 100 / total_pages));
+	ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn";
 
-	sprintf(buf, "%sconsistent       %8ld %8ld\n", buf,
-		ccio_alloc_size, ccio_free_size);
- 
-	strcat(buf, "\nResource bitmap:\n");
+	printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name, dev->hpa);
 
-	for(; i < (ioa->res_size / sizeof(unsigned long)); ++i, ++res_ptr)
-		len += sprintf(buf, "%s%08lx ", buf, *res_ptr);
+	for (i = 0; i < ioc_count; i++) {
+		ioc_p = &(*ioc_p)->next;
+	}
+	*ioc_p = ioc;
 
-	strcat(buf, "\n");
-	return strlen(buf);
+	ioc->hw_path = dev->hw_path;
+	ioc->ioc_hpa = (struct ioa_registers *)dev->hpa;
+	ccio_ioc_init(ioc);
+	ccio_init_resources(ioc);
+	hppa_dma_ops = &ccio_ops;
+
+	if (ioc_count == 0) {
+		/* XXX: Create separate entries for each ioc */
+		create_proc_read_entry(MODULE_NAME, S_IRWXU, proc_runway_root,
+				       ccio_proc_info, NULL);
+		create_proc_read_entry(MODULE_NAME"-bitmap", S_IRWXU,
+				       proc_runway_root, ccio_resource_map, NULL);
+	}
+
+	ioc_count++;
+	return 0;
 }
-#endif
 
-/*
-** Determine if ccio should claim this chip (return 0) or not (return 1).
-** If so, initialize the chip and tell other partners in crime they
-** have work to do.
-*/
-static int
-ccio_driver_callback(struct hp_device *d, struct pa_iodc_driver *dri)
+struct pci_dev * ccio_get_fake(const struct parisc_device *dev)
 {
-	struct ccio_device *ioa;
+	struct ioc *ioc;
 
-	printk("%s found %s at 0x%p\n", dri->name, dri->version, d->hpa);
+	dev = find_pa_parent_type(dev, HPHW_IOA);
+	if(!dev)
+		return NULL;
 
-	if (ccio_list) {
-		printk(MODULE_NAME ": already initialized one device\n");
-		return(0);
-	}
+	ioc = ccio_find_ioc(dev->hw_path);
+	if(!ioc)
+		return NULL;
 
-	ioa = kmalloc(sizeof(struct ccio_device), GFP_KERNEL);
-	if (NULL == ioa)
-	{
-		printk(MODULE_NAME " - couldn't alloc ccio_device\n");
-		return(1);
-	}
-	memset(ioa, 0, sizeof(struct ccio_device));
+	if(ioc->fake_pci_dev)
+		return ioc->fake_pci_dev;
 
-	/*
-	** ccio list is used mainly as a kluge to support a single instance. 
-	** Eventually, with core dumps, it'll be useful for debugging.
-	*/
-	ccio_list = ioa;
-	ioa->iodc = d;
+	ioc->fake_pci_dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
+	if(ioc->fake_pci_dev == NULL) {
+		printk(KERN_ERR MODULE_NAME ": memory allocation failure\n");
+		return NULL;
+	}
+	memset(ioc->fake_pci_dev, 0, sizeof(struct pci_dev));
 
-#if 1
-/* KLUGE: determine IOA hpa based on GSC port value.
-** Needed until we have a PA bus walk. Can only discover IOA via
-** walking the architected PA MMIO space as described by the I/O ACD.
-** "Legacy" PA Firmware only tells us about unarchitected devices
-** that can't be detected by PA/EISA/PCI bus walks.
-*/
-	switch((long) d->hpa) {
-	case 0xf3fbf000L:       /* C110 IOA0 LBC (aka GSC port) */
-		/* ccio_hpa same as C200 IOA0 */
-	case 0xf203f000L:       /* C180/C200/240/C360 IOA0 LBC (aka GSC port) */
-		ioa->ccio_hpa = (struct ioa_registers *) 0xfff88000L;
-		break;
-	case 0xf103f000L:       /* C180/C200/240/C360 IOA1 LBC (aka GSC port) */
-		ioa->ccio_hpa = (struct ioa_registers *) 0xfff8A000L;
-		break;
-	default:
-		panic("ccio-dma.c doesn't know this GSC port Address!\n");
-		break;
-	};
-#else
-	ioa->ccio_hpa = d->hpa;
-#endif
+	ioc->fake_pci_dev->sysdata = kmalloc(sizeof(struct pci_hba_data), GFP_KERNEL);
+	if(ioc->fake_pci_dev->sysdata == NULL) {
+		printk(KERN_ERR MODULE_NAME ": memory allocation failure\n");
+		return NULL;
+	}
 
-	ccio_alloc_pdir(ioa);
-	ccio_hw_init(ioa);
-	ccio_resmap_init(ioa);
+	HBA_DATA(ioc->fake_pci_dev->sysdata)->iommu = ioc;
+	return ioc->fake_pci_dev;
+}
 
-	/* CUJO20 KLUDGE start */
-	ccio_cujo20_hack(ioa);
-	/* CUJO20 KLUDGE end */
+/* We *can't* support JAVA (T600). Venture there at your own risk. */
+static struct parisc_device_id ccio_tbl[] = {
+	{ HPHW_IOA, HVERSION_REV_ANY_ID, U2_IOA_RUNWAY, 0xb }, /* U2 */
+	{ HPHW_IOA, HVERSION_REV_ANY_ID, UTURN_IOA_RUNWAY, 0xb }, /* UTurn */
+	{ 0, }
+};
 
-	hppa_dma_ops = &ccio_ops;
+static struct parisc_driver ccio_driver = {
+	name:		"U2/Uturn",
+	id_table:	ccio_tbl,
+	probe:		ccio_probe,
+};
 
-	create_proc_info_entry(MODULE_NAME, 0, proc_runway_root, ccio_proc_info);
-	return(0);
+/**
+ * ccio_init - ccio initalization procedure.
+ *
+ * Register this driver.
+ */
+void __init ccio_init(void)
+{
+	register_parisc_driver(&ccio_driver);
 }
 
-
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/ccio-rm-dma.c linux-bk/arch/parisc/kernel/ccio-rm-dma.c
--- linux-2.4.19/arch/parisc/kernel/ccio-rm-dma.c	2001-10-12 22:35:53.000000000 +0000
+++ linux-bk/arch/parisc/kernel/ccio-rm-dma.c	2002-08-17 00:48:55.000000000 +0000
@@ -56,26 +56,6 @@
 #define UTURN_IOA_RUNWAY 0x581
 #define UTURN_BC_GSC     0x502
 
-static int ccio_driver_callback(struct hp_device *, struct pa_iodc_driver *);
-
-static struct pa_iodc_driver ccio_drivers_for[] = {
-
-   {HPHW_BCPORT, U2_BC_GSC, 0x0, 0xb, 0, 0x10,
-		DRIVER_CHECK_HVERSION +
-		DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
-                MODULE_NAME, "U2 I/O MMU", (void *) ccio_driver_callback},
-
-   {HPHW_BCPORT, UTURN_BC_GSC, 0x0, 0xb, 0, 0x10,
-		DRIVER_CHECK_HVERSION +
-		DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
-                MODULE_NAME, "Uturn I/O MMU", (void *) ccio_driver_callback},
-
-   {0,0,0,0,0,0,
-   0,
-   (char *) NULL, (char *) NULL, (void *) NULL }
-};
-
-
 #define IS_U2(id) ( \
     (((id)->hw_type == HPHW_IOA) && ((id)->hversion == U2_IOA_RUNWAY)) || \
     (((id)->hw_type == HPHW_BCPORT) && ((id)->hversion == U2_BC_GSC))  \
@@ -86,17 +66,10 @@
     (((id)->hw_type == HPHW_BCPORT) && ((id)->hversion == UTURN_BC_GSC))  \
 )
 
-
-void __init ccio_init(void)
-{
-	register_driver(ccio_drivers_for);
-}
-
-
 static int ccio_dma_supported( struct pci_dev *dev, u64 mask)
 {
 	if (dev == NULL) {
-		printk(MODULE_NAME ": EISA/ISA/et al not supported\n");
+		printk(KERN_ERR MODULE_NAME ": EISA/ISA/et al not supported\n");
 		BUG();
 		return(0);
 	}
@@ -182,8 +155,6 @@
 	ccio_unmap_sg,
 	NULL,                   /* dma_sync_single : NOP for U2 */
 	NULL,                   /* dma_sync_sg     : ditto */
-
-
 };
 
 
@@ -193,9 +164,11 @@
 ** have work to do.
 */
 static int
-ccio_driver_callback(struct hp_device *d, struct pa_iodc_driver *dri)
+ccio_probe(struct parisc_device *dev)
 {
-	printk("%s found %s at 0x%p\n", dri->name, dri->version, d->hpa);
+	printk(KERN_INFO "%s found %s at 0x%lx\n", MODULE_NAME,
+			dev->id.hversion == U2_BC_GSC ? "U2" : "UTurn",
+			dev->hpa);
 
 /*
 ** FIXME - should check U2 registers to verify it's really running
@@ -210,3 +183,20 @@
 	hppa_dma_ops = &ccio_ops;
 	return 0;
 }
+
+static struct parisc_device_id ccio_tbl[] = {
+	{ HPHW_BCPORT, HVERSION_REV_ANY_ID, U2_BC_GSC, 0xc },
+	{ HPHW_BCPORT, HVERSION_REV_ANY_ID, UTURN_BC_GSC, 0xc },
+	{ 0, }
+};
+
+static struct parisc_driver ccio_driver = {
+        name:           "U2/Uturn",
+        id_table:       ccio_tbl,
+        probe:          ccio_probe,
+};
+
+void __init ccio_init(void)
+{
+	register_parisc_driver(&ccio_driver);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/drivers.c linux-bk/arch/parisc/kernel/drivers.c
--- linux-2.4.19/arch/parisc/kernel/drivers.c	2000-12-06 19:46:39.000000000 +0000
+++ linux-bk/arch/parisc/kernel/drivers.c	2002-08-17 00:49:00.000000000 +0000
@@ -1,134 +1,591 @@
 /*
-
-drivers.c
-
-Copyright (c) 1999 The Puffin Group 
-
-This is a collection of routines intended to register all the devices
-in a system, and register device drivers.
-
-*/
+ * drivers.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Copyright (c) 1999 The Puffin Group
+ * Copyright (c) 2001 Matthew Wilcox for Hewlett Packard
+ * Copyright (c) 2001 Helge Deller <deller@gmx.de>
+ * 
+ * The file handles registering devices and drivers, then matching them.
+ * It's the closest we get to a dating agency.
+ */
 
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/pdc.h>
+#include <asm/gsc.h>
 
+/* See comments in include/asm-parisc/pci.h */
+struct pci_dma_ops *hppa_dma_ops;
 
-extern struct hp_hardware *parisc_get_reference(
-	unsigned short hw_type, unsigned long hversion, 
-	unsigned long sversion );
+static struct parisc_driver *pa_drivers;
+static struct parisc_device root;
 
+/* This lock protects the pa_drivers list _only_ since all parisc_devices
+ * are registered before smp_init() is called.  If you wish to add devices
+ * after that, this muct be serialised somehow.  I recommend a semaphore
+ * rather than a spinlock since driver ->probe functions are allowed to
+ * sleep (for example when allocating memory).
+ */
+static spinlock_t pa_lock = SPIN_LOCK_UNLOCKED;
 
-/* I'm assuming there'll never be 64 devices.  We should probably make 
-   this more flexible.  */
+#define for_each_padev(dev) \
+	for (dev = root.child; dev != NULL; dev = next_dev(dev))
 
-#define MAX_DEVICES 64
+#define check_dev(dev) \
+	(dev->id.hw_type != HPHW_FAULTY) ? dev : next_dev(dev)
 
-unsigned int num_devices = 0;
+/**
+ * next_dev - enumerates registered devices
+ * @dev: the previous device returned from next_dev
+ *
+ * next_dev does a depth-first search of the tree, returning parents
+ * before children.  Returns NULL when there are no more devices.
+ */
+struct parisc_device *next_dev(struct parisc_device *dev)
+{
+	if (dev->child) {
+		return check_dev(dev->child);
+	} else if (dev->sibling) {
+		return dev->sibling;
+	}
 
-struct hp_device devices[MAX_DEVICES];
+	/* Exhausted tree at this level, time to go up. */
+	do {
+		dev = dev->parent;
+		if (dev && dev->sibling)
+			return dev->sibling;
+	} while (dev != &root);
 
-static unsigned long pdc_result[32] __attribute__ ((aligned (16))) = {0,0,0,0};
-static  u8 iodc_data[32] __attribute__ ((aligned (64)));
+	return NULL;
+}
 
-/*
- *	XXX should we be using a locked array ?
+/**
+ * match_device - Report whether this driver can handle this device
+ * @driver: the PA-RISC driver to try
+ * @dev: the PA-RISC device to try
  */
- 
-int register_driver(struct pa_iodc_driver *driver)
+static int match_device(struct parisc_driver *driver, struct parisc_device *dev)
 {
-	unsigned int i;
-	struct hp_device * device;
+	const struct parisc_device_id *ids;
 
-	for (;driver->check;driver++)  {
+	for (ids = driver->id_table; ids->sversion; ids++) {
+		if ((ids->sversion != SVERSION_ANY_ID) &&
+		    (ids->sversion != dev->id.sversion))
+			continue;
+
+		if ((ids->hw_type != HWTYPE_ANY_ID) &&
+		    (ids->hw_type != dev->id.hw_type))
+			continue;
+
+		if ((ids->hversion != HVERSION_ANY_ID) &&
+		    (ids->hversion != dev->id.hversion))
+			continue;
 
-		for (i=0;i<num_devices;i++) {
-			device = &devices[i];
+		return 1;
+	}
+	return 0;
+}
 
-			if (device->managed) continue;
+static void claim_device(struct parisc_driver *driver, struct parisc_device *dev)
+{
+	dev->driver = driver;
+	request_mem_region(dev->hpa, 0x1000, driver->name);
+}
 
-			if ((driver->check & DRIVER_CHECK_HWTYPE) &&
-			    (driver->hw_type != device->hw_type))
-				continue;
-			if ((driver->check & DRIVER_CHECK_HVERSION) &&
-			    (driver->hversion != device->hversion))
-				continue;
-			if ((driver->check & DRIVER_CHECK_HVERSION_REV) &&
-			    (driver->hversion_rev != device->hversion_rev))
-				continue;
-			if ((driver->check & DRIVER_CHECK_SVERSION) &&
-			    (driver->sversion != device->sversion))
-				continue;
-			if ((driver->check & DRIVER_CHECK_SVERSION_REV) &&
-			    (driver->sversion_rev != device->sversion_rev))
-				continue;
-			if ((driver->check & DRIVER_CHECK_OPT) &&
-			    (driver->opt != device->opt))
-				continue;
-			if ( (*driver->callback)(device,driver) ==0) {
-				device->managed=1;
-			} else {
-				printk("Warning : device (%d, 0x%x, 0x%x, 0x%x, 0x%x) NOT claimed by %s %s\n",
-					device->hw_type,
-					device->hversion, device->hversion_rev,
-					device->sversion, device->sversion_rev,
-					driver->name, driver->version);
-			}
+/**
+ * register_parisc_driver - Register this driver if it can handle a device
+ * @driver: the PA-RISC driver to try
+ */
+int register_parisc_driver(struct parisc_driver *driver)
+{
+	struct parisc_device *device;
+
+	if (driver->next) {
+		printk(KERN_WARNING 
+		       "BUG: Skipping previously registered driver: %s\n",
+		       driver->name);
+		return 1;
+	}
+
+	for_each_padev(device) {
+		if (device->driver)
+			continue;
+		if (!match_device(driver, device))
+			continue;
+
+		if (driver->probe(device) < 0)
+			continue;
+		claim_device(driver, device);
+	}
+
+	/* Note that the list is in reverse order of registration.  This
+	 * may be significant if we ever actually support hotplug and have
+	 * multiple drivers capable of claiming the same chip.
+	 */
+
+	spin_lock(&pa_lock);
+	driver->next = pa_drivers;
+	pa_drivers = driver;
+	spin_unlock(&pa_lock);
+
+	return 0;
+}
+
+/**
+ * count_parisc_driver - count # of devices this driver would match
+ * @driver: the PA-RISC driver to try
+ *
+ * Use by IOMMU support to "guess" the right size IOPdir.
+ * Formula is something like memsize/(num_iommu * entry_size).
+ */
+int count_parisc_driver(struct parisc_driver *driver)
+{
+	struct parisc_device *device;
+	int cnt = 0;
+
+	for_each_padev(device) {
+		if (match_device(driver, device))
+			cnt++;
+	}
+
+	return cnt;
+}
+
+
+
+/**
+ * unregister_parisc_driver - Unregister this driver from the list of drivers
+ * @driver: the PA-RISC driver to unregister
+ */
+int unregister_parisc_driver(struct parisc_driver *driver)
+{
+	struct parisc_device *dev;
+
+	spin_lock(&pa_lock);
+
+	if (pa_drivers == driver) {
+		/* was head of list - update head */
+		pa_drivers = driver->next;
+	} else {
+		struct parisc_driver *prev = pa_drivers;
+
+		while (prev && driver != prev->next) {
+			prev = prev->next;
+		}
+
+		if (!prev) {
+			printk(KERN_WARNING "unregister_parisc_driver: %s wasn't registered\n", driver->name);
+		} else {
+			/* Drop driver from list */
+			prev->next = driver->next;
+			driver->next = NULL;
 		}
+
 	}
+
+	spin_unlock(&pa_lock);
+
+	for_each_padev(dev) {
+		if (dev->driver != driver)
+			continue;
+		dev->driver = NULL;
+		release_mem_region(dev->hpa, 0x1000);
+	}
+
 	return 0;
 }
 
+static struct parisc_device *find_device_by_addr(unsigned long hpa)
+{
+	struct parisc_device *dev;
+	for_each_padev(dev) {
+		if (dev->hpa == hpa)
+			return dev;
+	}
+	return NULL;
+}
 
-struct hp_device * register_module(void *hpa)
+/**
+ * find_pa_parent_type - Find a parent of a specific type
+ * @dev: The device to start searching from
+ * @type: The device type to search for.
+ *
+ * Walks up the device tree looking for a device of the specified type.
+ * If it finds it, it returns it.  If not, it returns NULL.
+ */
+const struct parisc_device *find_pa_parent_type(const struct parisc_device *dev, int type)
 {
+	while (dev != &root) {
+		if (dev->id.hw_type == type)
+			return dev;
+		dev = dev->parent;
+	}
 
-	struct hp_device * d;
+	return NULL;
+}
+
+static void
+get_node_path(struct parisc_device *dev, struct hardware_path *path)
+{
+	int i = 5;
+	memset(&path->bc, -1, 6);
+	while (dev != &root) {
+		path->bc[i--] = dev->hw_path;
+		dev = dev->parent;
+	}
+}
+
+static char *print_hwpath(struct hardware_path *path, char *output)
+{
+	int i;
+	for (i = 0; i < 6; i++) {
+		if (path->bc[i] == -1)
+			continue;
+		output += sprintf(output, "%u/", (unsigned char) path->bc[i]);
+	}
+	output += sprintf(output, "%u", (unsigned char) path->mod);
+	return output;
+}
+
+/**
+ * print_pa_hwpath - Returns hardware path for PA devices
+ * dev: The device to return the path for
+ * output: Pointer to a previously-allocated array to place the path in.
+ *
+ * This function fills in the output array with a human-readable path
+ * to a PA device.  This string is compatible with that used by PDC, and
+ * may be printed on the outside of the box.
+ */
+char *print_pa_hwpath(struct parisc_device *dev, char *output)
+{
+	struct hardware_path path;
+
+	get_node_path(dev->parent, &path);
+	path.mod = dev->hw_path;
+	return print_hwpath(&path, output);
+}
+
+
+#if defined(CONFIG_PCI) || defined(CONFIG_ISA)
+/**
+ * get_pci_node_path - Returns hardware path for PCI devices
+ * dev: The device to return the path for
+ * output: Pointer to a previously-allocated array to place the path in.
+ *
+ * This function fills in the hardware_path structure with the route to
+ * the specified PCI device.  This structure is suitable for passing to
+ * PDC calls.
+ */
+void get_pci_node_path(struct pci_dev *dev, struct hardware_path *path)
+{
+	struct pci_bus *bus;
+	const struct parisc_device *padev;
+	int i = 5;
+
+	memset(&path->bc, -1, 6);
+	path->mod = PCI_FUNC(dev->devfn);
+	path->bc[i--] = PCI_SLOT(dev->devfn);
+	for (bus = dev->bus; bus->parent; bus = bus->parent) {
+		unsigned int devfn = bus->self->devfn;
+		path->bc[i--] = PCI_SLOT(devfn) | (PCI_FUNC(devfn) << 5);
+	}
+
+	padev = HBA_DATA(bus->sysdata)->dev;
+	while (padev != &root) {
+		path->bc[i--] = padev->hw_path;
+		padev = padev->parent;
+	}
+}
+
+/**
+ * print_pci_hwpath - Returns hardware path for PCI devices
+ * dev: The device to return the path for
+ * output: Pointer to a previously-allocated array to place the path in.
+ *
+ * This function fills in the output array with a human-readable path
+ * to a PCI device.  This string is compatible with that used by PDC, and
+ * may be printed on the outside of the box.
+ */
+char *print_pci_hwpath(struct pci_dev *dev, char *output)
+{
+	struct hardware_path path;
+
+	get_pci_node_path(dev, &path);
+	return print_hwpath(&path, output);
+}
+#endif /* defined(CONFIG_PCI) || defined(CONFIG_ISA) */
+
+
+struct parisc_device * create_tree_node(char id, struct parisc_device *parent,
+		struct parisc_device **insert)
+{
+	struct parisc_device *dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return NULL;
+	memset(dev, 0, sizeof(*dev));
+	dev->hw_path = id;
+	dev->id.hw_type = HPHW_FAULTY;
+	dev->parent = parent;
+	dev->sibling = *insert;
+	*insert = dev;
+	return dev;
+}
+
+/**
+ * alloc_tree_node - returns a device entry in the iotree
+ * @parent: the parent node in the tree
+ * @id: the element of the module path for this entry
+ *
+ * Checks all the children of @parent for a matching @id.  If none
+ * found, it allocates a new device and returns it.
+ */
+struct parisc_device *
+alloc_tree_node(struct parisc_device *parent, char id)
+{
+	struct parisc_device *prev;
+	if ((!parent->child) || (parent->child->hw_path > id)) {
+		return create_tree_node(id, parent, &parent->child);
+	}
+
+	prev = parent->child;
+	if (prev->hw_path == id)
+		return prev;
+
+	while (prev->sibling && prev->sibling->hw_path < id) {
+		prev = prev->sibling;
+	}
+
+	if ((prev->sibling) && (prev->sibling->hw_path == id))
+		return prev->sibling;
+
+	return create_tree_node(id, parent, &prev->sibling);
+}
+
+static struct parisc_device *find_parisc_device(struct hardware_path *modpath)
+{
+	int i;
+	struct parisc_device *parent = &root;
+	for (i = 0; i < 6; i++) {
+		if (modpath->bc[i] == -1)
+			continue;
+		parent = alloc_tree_node(parent, modpath->bc[i]);
+	}
+	return alloc_tree_node(parent, modpath->mod);
+}
+
+struct parisc_device *
+alloc_pa_dev(unsigned long hpa, struct hardware_path *mod_path)
+{
 	int status;
+	unsigned long bytecnt;
+	u8 iodc_data[32];
+	struct parisc_device *dev;
+	const char *name;
+
+	/* Check to make sure this device has not already been added - Ryan */
+	if (find_device_by_addr(hpa) != NULL)
+		return NULL;
+
+	status = pdc_iodc_read(&bytecnt, hpa, 0, &iodc_data, 32);
+	if (status != PDC_OK)
+		return NULL;
+
+	dev = find_parisc_device(mod_path);
+	if (dev->id.hw_type != HPHW_FAULTY) {
+		char p[64];
+		print_pa_hwpath(dev, p);
+		printk("Two devices have hardware path %s.  Please file a bug with HP.\n"
+			"In the meantime, you could try rearranging your cards.\n", p);
+		return NULL;
+	}
+
+	dev->id.hw_type = iodc_data[3] & 0x1f;
+	dev->id.hversion = (iodc_data[0] << 4) | ((iodc_data[1] & 0xf0) >> 4);
+	dev->id.hversion_rev = iodc_data[1] & 0x0f;
+	dev->id.sversion = ((iodc_data[4] & 0x0f) << 16) |
+			(iodc_data[5] << 8) | iodc_data[6];
+	dev->hpa = hpa;
+	name = parisc_hardware_description(&dev->id);
+	if (name) {
+		strncpy(dev->name, name, sizeof(dev->name)-1);
+	}
+
+	return dev;
+}
 
-	d = &devices[num_devices];
-	status = pdc_iodc_read(&pdc_result,hpa,0,&iodc_data,32 );
-	if (status !=PDC_RET_OK) {
-		/* There is no device here, so we'll skip it */
+/**
+ * register_parisc_device - Locate a driver to manage this device.
+ * @dev: The parisc device.
+ *
+ * Search the driver list for a driver that is willing to manage
+ * this device.
+ */
+int register_parisc_device(struct parisc_device *dev)
+{
+	struct parisc_driver *driver;
+
+	if (!dev)
 		return 0;
+
+	if (dev->driver)
+		return 1;
+	
+	spin_lock(&pa_lock);
+
+	/* Locate a driver which agrees to manage this device.  */
+	for (driver = pa_drivers; driver; driver = driver->next) {
+		if (!match_device(driver,dev))
+			continue;
+		if (driver->probe(dev) == 0)
+			break;
 	}
 
-	d->hw_type = iodc_data[3]&0x1f;
-	d->hversion = (iodc_data[0]<<4)|((iodc_data[1]&0xf0)>>4);
-	d->sversion = 
-		((iodc_data[4]&0x0f)<<16)|(iodc_data[5]<<8)|(iodc_data[6]);
-	d->hversion_rev = iodc_data[1]&0x0f;
-	d->sversion_rev = iodc_data[4]>>4;
-	d->opt = iodc_data[7];
-	d->hpa = hpa;
-	d->managed=0;
-	d->reference = parisc_get_reference(d->hw_type, d->hversion, 
-								d->sversion);
-		
-	num_devices++;	
+	if (driver != NULL) {
+		claim_device(driver, dev);
+	}
+	spin_unlock(&pa_lock);
+	return driver != NULL;
+}
+
+#define BC_PORT_MASK 0x8
+#define BC_LOWER_PORT 0x8
+
+#define BUS_CONVERTER(dev) \
+        ((dev->id.hw_type == HPHW_IOA) || (dev->id.hw_type == HPHW_BCPORT))
+
+#define IS_LOWER_PORT(dev) \
+        ((gsc_readl(&((struct bc_module *)dev->hpa)->io_status) \
+                & BC_PORT_MASK) == BC_LOWER_PORT)
+
+#define READ_IO_IO_LOW(dev) \
+	(dev->id.hw_type == HPHW_IOA ? \
+	        __raw_readl((unsigned long)&((struct bc_module *)dev->hpa)->io_io_low) << 16 : \
+	        __raw_readl((unsigned long)&((struct bc_module *)dev->hpa)->io_io_low))
 
-	return d;
-}	
+static void walk_native_bus(unsigned long addr, struct parisc_device *parent);
+void walk_lower_bus(struct parisc_device *dev)
+{
+
+	if(!BUS_CONVERTER(dev) || IS_LOWER_PORT(dev))
+		return;
 
-void print_devices(char * buf) {
+	walk_native_bus((unsigned long)(signed int)READ_IO_IO_LOW(dev), dev);
+}
 
+#define MAX_NATIVE_DEVICES 64
+#define NATIVE_DEVICE_OFFSET 0x1000
+
+/**
+ * walk_native_bus -- Probe a bus for devices
+ * @addr: Base address of this bus.
+ * 
+ * A native bus (eg Runway or GSC) may have up to 64 devices on it,
+ * spaced at intervals of 0x1000 bytes.  PDC may not inform us of these
+ * devices, so we have to probe for them.  Unfortunately, we may find
+ * devices which are not physically connected (such as extra serial &
+ * keyboard ports).  This problem is not yet solved.
+ */
+static void walk_native_bus(unsigned long addr, struct parisc_device *parent)
+{
 	int i;
-	struct hp_device *d;
-	printk("Found devices:\n");
-	for (i=0;i<num_devices;i++) {	
-		d = &devices[i];
-		printk(KERN_INFO 
-		"%d. %s (%d) at 0x%p, versions 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", 
-		i+1,
-		(d->reference) ? d->reference->name : "Unknown device",
-		d->hw_type,d->hpa, d->hversion, d->hversion_rev,
-		d->sversion, d->sversion_rev, d->opt);
+	struct hardware_path path;
+
+	get_node_path(parent, &path);
+	for (i = 0; i < MAX_NATIVE_DEVICES; i++) {
+		unsigned long hpa = (addr + i * NATIVE_DEVICE_OFFSET);
+		struct parisc_device *dev;
+
+		/* Was the device already added by Firmware? */
+		dev = find_device_by_addr(hpa);
+		if (!dev) {
+			path.mod = i;
+			dev = alloc_pa_dev(hpa, &path);
+			if (!dev)
+				continue;
+
+			register_parisc_device(dev);
+		}
+		walk_lower_bus(dev);
+	}
+}
+
+#define CENTRAL_BUS_ADDR (unsigned long) 0xfffffffffff80000
+
+/**
+ * walk_central_bus - Find devices attached to the central bus
+ *
+ * PDC doesn't tell us about all devices in the system.  This routine
+ * finds devices connected to the central bus.
+ */
+void walk_central_bus(void)
+{
+	walk_native_bus(CENTRAL_BUS_ADDR, &root);
+}
+
+void fixup_child_irqs(struct parisc_device *parent, int base,
+			int (*choose_irq)(struct parisc_device *))
+{
+	struct parisc_device *dev;
 
+	if (!parent->child)
+		return;
+
+	for (dev = check_dev(parent->child); dev; dev = dev->sibling) {
+		int irq = choose_irq(dev);
+		if (irq > 0) {
+#ifdef __LP64__
+			irq += 32;
+#endif
+			dev->irq = base + irq;
+		}
 	}
-	printk("That's a total of %d devices.\n",num_devices);
 }
 
+static void print_parisc_device(struct parisc_device *dev)
+{
+	char hw_path[64];
+	static int count;
 
+	print_pa_hwpath(dev, hw_path);
+	printk(KERN_INFO "%d. %s (%d) at 0x%lx [%s], versions 0x%x, 0x%x, 0x%x",
+		++count, dev->name, dev->id.hw_type, dev->hpa, hw_path,
+		dev->id.hversion, dev->id.hversion_rev, dev->id.sversion);
+
+	if (dev->num_addrs) {
+		int k;
+		printk(",  additional addresses: ");
+		for (k = 0; k < dev->num_addrs; k++)
+			printk("0x%lx ", dev->addr[k]);
+	}
+	printk("\n");
+}
+
+void print_subdevices(struct parisc_device *parent)
+{
+	struct parisc_device *dev;
+	for (dev = parent->child; dev != parent->sibling; dev = next_dev(dev)) {
+		print_parisc_device(dev);
+	}
+}
+
+/**
+ * print_parisc_devices - Print out a list of devices found in this system
+ */
+void print_parisc_devices(void)
+{
+	struct parisc_device *dev;
+	for_each_padev(dev) {
+		print_parisc_device(dev);
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/entry.S linux-bk/arch/parisc/kernel/entry.S
--- linux-2.4.19/arch/parisc/kernel/entry.S	2000-12-06 19:46:39.000000000 +0000
+++ linux-bk/arch/parisc/kernel/entry.S	2002-08-17 00:48:55.000000000 +0000
@@ -1,5 +1,5 @@
-/*------------------------------------------------------------------------------
- * Native PARISC/Linux Project (http://www.puffingroup.com/parisc)
+/*
+ * Linux/PA-RISC Project (http://www.parisc-linux.org/)
  *
  * kernel entry points (interruptions, system call wrappers)
  *  Copyright (C) 1999,2000 Philipp Rumpf 
@@ -25,39 +25,51 @@
 #include <linux/config.h>
 #include <asm/offset.h>
 
-/* the following is the setup i think we should follow:
- * whenever the CPU is interruptible, the following has to be true:
- *  CR30 is the kernel sp or 0 if we currently use the kernel stack
- *  CR31 is the kernel gp */ 
-
 /* we have the following possibilities to act on an interruption:
  *  - handle in assembly and use shadowed registers only
  *  - save registers to kernel stack and handle in assembly or C */
 
-	.text
-
-#ifdef __LP64__
-	.level 2.0w
-#endif
 
-#define __ASSEMBLY__
 #include <asm/assembly.h>	/* for LDREG/STREG defines */
 #include <asm/pgtable.h>
 #include <asm/psw.h>
 #include <asm/signal.h>
+#include <asm/unistd.h>
 
 #ifdef __LP64__
-#define FRAME_SIZE	64
+#define FRAME_SIZE	128
+#define CMPIB           cmpib,*
+#define CMPB            cmpb,*
+
+	.level 2.0w
 #else
 #define FRAME_SIZE	64
+#define CMPIB           cmpib,
+#define CMPB            cmpb,
+
+	.level 2.0
+#endif
+
+	.import         pa_dbit_lock,data
+
+	/* space_to_prot macro creates a prot id from a space id */
+
+#if (SPACEID_SHIFT) == 0
+	.macro  space_to_prot spc prot
+	depd,z  \spc,62,31,\prot
+	.endm
+#else
+	.macro  space_to_prot spc prot
+	extrd,u \spc,(64 - (SPACEID_SHIFT)),32,\prot
+	.endm
 #endif
 
 	/* Switch to virtual mapping, trashing only %r1 */
-	.macro	virt_map rfi_type
-	mtsm	%r0
-	tovirt	%r29
-	tovirt	%r30
+	.macro  virt_map
+	rsm     PSW_SM_Q,%r0
+	tovirt_r1 %r29
 	mfsp	%sr7, %r1
+	or,=    %r0,%r1,%r0 /* Only save sr7 in sr3 if sr7 != 0 */
 	mtsp	%r1, %sr3
 	mtsp	%r0, %sr4
 	mtsp	%r0, %sr5
@@ -65,95 +77,114 @@
 	mtsp	%r0, %sr7
 	ldil	L%KERNEL_PSW, %r1
 	ldo	R%KERNEL_PSW(%r1), %r1
-	LDIL_FIXUP(%r1)
 	mtctl	%r1, %cr22
 	mtctl	%r0, %cr17
 	mtctl	%r0, %cr17
-	ldil	L%.+28, %r1
-	ldo	R%.+24(%r1), %r1
-	LDIL_FIXUP(%r1)
+	ldil	L%4f, %r1
+	ldo	R%4f(%r1), %r1
 	mtctl	%r1, %cr18
 	ldo	4(%r1), %r1
 	mtctl	%r1, %cr18
-	\rfi_type
+	rfir
 	nop
+4:
 	.endm
 
-	.macro	get_stack
-	mfctl	%cr30, %r1 
-	comib,=,n 0, %r1, 0f   /* forward so predicted not taken */
+	/*
+	 * The "get_stack" macros are responsible for determining the
+	 * kernel stack value.
+	 *
+	 * For Faults:
+	 *      If sr7 == 0
+	 *          Already using a kernel stack, so call the
+	 *          get_stack_use_r30 macro to push a pt_regs structure
+	 *          on the stack, and store registers there.
+	 *      else
+	 *          Need to set up a kernel stack, so call the
+	 *          get_stack_use_cr30 macro to set up a pointer
+	 *          to the pt_regs structure contained within the
+	 *          task pointer pointed to by cr30. Set the stack
+	 *          pointer to point to the end of the task structure.
+	 *
+	 * For Interrupts:
+	 *      If sr7 == 0
+	 *          Already using a kernel stack, check to see if r30
+	 *          is already pointing to the per processor interrupt
+	 *          stack. If it is, call the get_stack_use_r30 macro
+	 *          to push a pt_regs structure on the stack, and store
+	 *          registers there. Otherwise, call get_stack_use_cr31
+	 *          to get a pointer to the base of the interrupt stack
+	 *          and push a pt_regs structure on that stack.
+	 *      else
+	 *          Need to set up a kernel stack, so call the
+	 *          get_stack_use_cr30 macro to set up a pointer
+	 *          to the pt_regs structure contained within the
+	 *          task pointer pointed to by cr30. Set the stack
+	 *          pointer to point to the end of the task structure.
+	 *          N.B: We don't use the interrupt stack for the
+	 *          first interrupt from userland, because signals/
+	 *          resched's are processed when returning to userland,
+	 *          and we can sleep in those cases.
+	 *
+	 * Note that we use shadowed registers for temps until
+	 * we can save %r26 and %r29. %r26 is used to preserve
+	 * %r8 (a shadowed register) which temporarily contained
+	 * either the fault type ("code") or the eirr. We need
+	 * to use a non-shadowed register to carry the value over
+	 * the rfir in virt_map. We use %r26 since this value winds
+	 * up being passed as the argument to either do_cpu_irq_mask
+	 * or handle_interruption. %r29 is used to hold a pointer
+	 * the register save area, and once again, it needs to
+	 * be a non-shadowed register so that it survives the rfir.
+	 *
+	 * N.B. TASK_SZ_ALGN and PT_SZ_ALGN include space for a stack frame.
+	 */
+
+	.macro  get_stack_use_cr30
 
 	/* we save the registers in the task struct */
-	ldo	TASK_REGS(%r1), %r29
-	tophys	%r29
-	STREG	%r30, PT_GR30(%r29)
-	STREG	%r1,  PT_CR30(%r29)
+
+	mfctl   %cr30, %r1
+	tophys  %r1,%r9
+	ldo     TASK_REGS(%r9),%r9
+	STREG   %r30, PT_GR30(%r9)
 	ldo	TASK_SZ_ALGN(%r1), %r30
-	b	1f		    /* unconditional so predicted taken */	
-	mtctl	%r0,%cr30
-0:
-	/* we put a struct pt_regs on the stack and save the registers there */
-	copy	%r30,%r29
-	ldo	PT_SZ_ALGN(%r30),%r30
-	tophys	%r29
-	STREG	%r30,PT_GR30(%r29)
-	STREG	%r0,PT_CR30(%r29)
-1:
+	STREG   %r29,PT_GR29(%r9)
+	STREG   %r26,PT_GR26(%r9)
+	copy    %r9,%r29
 	.endm
 
-	.macro	rest_stack regs
-	LDREG	PT_CR30(\regs), %r1
-	comib,=,n 0, %r1, 2f/* forward so predicted not taken */
-
-	/* we restore the registers out of the task struct */
-	mtctl	%r1, %cr30
-	LDREG	PT_GR1(\regs), %r1
-	LDREG	PT_GR30(\regs),%r30
-	b	3f
-	LDREG	PT_GR29(\regs),%r29
-2:
-	/* we take a struct pt_regs off the stack */
-	LDREG	PT_GR1(\regs),  %r1
-	LDREG	PT_GR29(\regs), %r29
-	ldo	-PT_SZ_ALGN(%r30), %r30
-3:
-	.endm
+	.macro  get_stack_use_r30
 
-#ifdef OLD
-	/* fixme interruption handler */
-	.macro	def code
-	/* WARNING!!! THIS IS DEBUG CODE ONLY!!! */
-	b	unimplemented_64bitirq
-	ldi	\code, %r1
-	.align	32
+	/* we put a struct pt_regs on the stack and save the registers there */
+
+	tophys  %r30,%r9
+	STREG   %r30,PT_GR30(%r9)
+	ldo	PT_SZ_ALGN(%r30),%r30
+	STREG   %r29,PT_GR29(%r9)
+	STREG   %r26,PT_GR26(%r9)
+	copy    %r9,%r29
 	.endm
 
-	/* Use def to enable break - KWDB wants em
-	 * (calls traps.c:handle_interruption) */
-	.macro	pass_break code
+	.macro  rest_stack
+	LDREG   PT_GR1(%r29), %r1
+	LDREG   PT_GR30(%r29),%r30
+	LDREG   PT_GR29(%r29),%r29
+	.endm
 
-#else
 	/* default interruption handler
 	 * (calls traps.c:handle_interruption) */
 	.macro	def code
-#endif
-	mtctl	%r29, %cr31
-	mtctl	%r1,  %cr28
-	ldi	\code, %r1
 	b	intr_save
-	mtctl   %r1, %cr29
+	ldi     \code, %r8
 	.align	32
 	.endm
 
 	/* Interrupt interruption handler
-	 * (calls irq.c:do_irq_mask) */
+	 * (calls irq.c:do_cpu_irq_mask) */
 	.macro	extint code
-	mtctl	%r29, %cr31
-	mtctl	%r1,  %cr28
-	mfctl	%cr23, %r1
-	mtctl	%r1, %cr23
 	b	intr_extint
-	mtctl	%r1, %cr29
+	mfsp    %sr7,%r16
 	.align	32
 	.endm	
 
@@ -203,7 +234,6 @@
 	 */
 
 	.macro	itlb_20 code
-
 	mfctl	%pcsq, spc
 #ifdef __LP64__
 	b       itlb_miss_20w
@@ -298,37 +328,27 @@
 	.endm
 	
 #ifndef __LP64__
-	/* nadtlb miss interruption handler (parisc 1.1 - 32 bit)
-	 *
-	 * Note: nadtlb misses will be treated
-	 * as an ordinary dtlb miss for now.
-	 *
-	 */
+	/* nadtlb miss interruption handler (parisc 1.1 - 32 bit) */
 
 	.macro	nadtlb_11 code
 
 	mfctl	%isr,spc
-	b	dtlb_miss_11
+	b       nadtlb_miss_11
 	mfctl	%ior,va
 
 	.align		32
 	.endm
 #endif
 	
-	/* nadtlb miss interruption handler (parisc 2.0)
-	 *
-	 * Note: nadtlb misses will be treated
-	 * as an ordinary dtlb miss for now.
-	 *
-	 */
+	/* nadtlb miss interruption handler (parisc 2.0) */
 
 	.macro	nadtlb_20 code
 
 	mfctl	%isr,spc
 #ifdef __LP64__
-	b       dtlb_miss_20w
+	b       nadtlb_miss_20w
 #else
-	b	dtlb_miss_20
+	b       nadtlb_miss_20
 #endif
 	mfctl	%ior,va
 
@@ -372,13 +392,14 @@
 	 * fault_vector_11 and fault_vector_20 are on the
 	 * same page. This is only necessary as long as we
 	 * write protect the kernel text, which we may stop
-	 * doing once we use large parge translations to cover
+	 * doing once we use large page translations to cover
 	 * the static part of the kernel address space.
 	 */
 
-
 	.export fault_vector_20
 
+	.text
+
 	.align 4096
 
 fault_vector_20:
@@ -402,7 +423,11 @@
 	def		13
 	def		14
 	dtlb_20		15
+#if 0
 	naitlb_20	16
+#else
+	def             16
+#endif
 	nadtlb_20	17
 	def		18
 	def		19
@@ -446,7 +471,11 @@
 	def		13
 	def		14
 	dtlb_11		15
+#if 0
 	naitlb_11	16
+#else
+	def             16
+#endif
 	nadtlb_11	17
 	def		18
 	def		19
@@ -467,7 +496,7 @@
 
 	.import		handle_interruption,code
 	.import		handle_real_interruption,code
-	.import		do_irq_mask,code
+	.import		do_cpu_irq_mask,code
 	.import		parisc_stopkernel,code
 	.import		cpu_irq_region,data
 
@@ -492,7 +521,8 @@
 	ldo	PT_SZ_ALGN(%r30),%r30
 #ifdef __LP64__
 	/* Yo, function pointers in wide mode are little structs... -PB */
-	/* XXX FIXME do we need to honor the fptr's %dp value too? */
+	ldd	24(%r26), %r2
+	STREG	%r2, PT_GR27(%r1)	/* Store childs %dp */
 	ldd	16(%r26), %r26
 #endif
 	STREG	%r26, PT_GR26(%r1)  /* Store function & argument for child */
@@ -500,15 +530,17 @@
 	ldo	CLONE_VM(%r0), %r26   /* Force CLONE_VM since only init_mm */
 	or	%r26, %r24, %r26      /* will have kernel mappings.	 */
 	copy	%r0, %r25
+#ifdef __LP64__
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#endif
 	bl	do_fork, %r2
 	copy	%r1, %r24
 
 	/* Parent Returns here */
 
-	ldo	-PT_SZ_ALGN(%r30), %r30
-	LDREG	-RP_OFFSET(%r30), %r2
+	LDREG	-PT_SZ_ALGN-RP_OFFSET(%r30), %r2
 	bv	%r0(%r2)
-	nop
+	ldo	-PT_SZ_ALGN(%r30), %r30
 
 	/*
 	 * Child Returns here
@@ -520,11 +552,22 @@
 	.export	ret_from_kernel_thread
 ret_from_kernel_thread:
 
+	/* Call schedule_tail first though */
+	bl	schedule_tail, %r2
+	nop
+
 	LDREG	TASK_PT_GR26-TASK_SZ_ALGN(%r30), %r1
 	LDREG	TASK_PT_GR25-TASK_SZ_ALGN(%r30), %r26
+#ifdef __LP64__
+	LDREG	TASK_PT_GR27-TASK_SZ_ALGN(%r30), %r27
+#endif
 	ble	0(%sr7, %r1)
 	copy	%r31, %r2
 
+#ifdef __LP64__
+	ldo	-16(%r30),%r29		/* Reference param save area */
+	loadgp				/* Thread could have been in a module */
+#endif
 	b	sys_exit
 	ldi	0, %r26
 
@@ -532,23 +575,22 @@
 	.export	__execve, code
 __execve:
 	copy	%r2, %r15
-	copy	%r23, %r17
 	copy	%r30, %r16
 	ldo	PT_SZ_ALGN(%r30), %r30
 	STREG	%r26, PT_GR26(%r16)
 	STREG	%r25, PT_GR25(%r16)
 	STREG	%r24, PT_GR24(%r16)
+#ifdef __LP64__
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#endif
 	bl	sys_execve, %r2
 	copy	%r16, %r26
 
-	comib,<>,n 0,%r28,__execve_failed
-
-	b	intr_return
-	STREG	%r17, PT_CR30(%r16)
+	cmpib,=,n 0,%r28,intr_return    /* forward */
 
-__execve_failed:
 	/* yes, this will trap and die. */
 	copy	%r15, %r2
+	copy	%r16, %r30
 	bv	%r0(%r2)
 	nop
 
@@ -567,16 +609,14 @@
 
 	ldil	L%_switch_to_ret, %r2
 	ldo	R%_switch_to_ret(%r2), %r2
-	LDIL_FIXUP(%r2)
 
 	STREG	%r2, TASK_PT_KPC(%r26)
 	LDREG	TASK_PT_KPC(%r25), %r2
 
 	STREG	%r30, TASK_PT_KSP(%r26)
 	LDREG	TASK_PT_KSP(%r25), %r30
-
 	bv	%r0(%r2)
-	nop
+	mtctl   %r25,%cr30
 
 _switch_to_ret:
 	mtctl	%r0, %cr0		/* Needed for single stepping */
@@ -587,27 +627,30 @@
 	copy	%r26, %r28
 
 	/*
-	 * Common rfi return path for interruptions, kernel execve, and some
-	 * syscalls.  The sys_rt_sigreturn syscall will return via this path
-	 * if the signal was received when the process was running; if the
-	 * process was blocked on a syscall then the normal syscall_exit
-	 * path is used.  All syscalls for traced proceses exit via
-	 * intr_restore.
-	 * Note that the following code uses a "relied upon translation". See
-	 * the parisc ACD for details. The ssm is necessary due to a PCXT bug.
+	 * Common rfi return path for interruptions, kernel execve, and
+	 * sys_rt_sigreturn (sometimes).  The sys_rt_sigreturn syscall will
+	 * return via this path if the signal was received when the process
+	 * was running; if the process was blocked on a syscall then the
+	 * normal syscall_exit path is used.  All syscalls for traced
+	 * proceses exit via intr_restore.
+	 *
+	 * XXX If any syscalls that change a processes space id ever exit
+	 * this way, then we will need to copy %sr3 in to PT_SR[3..7], and
+	 * adjust IASQ[0..1].
+	 *
+	 * Note that the following code uses a "relied upon translation".
+	 * See the parisc ACD for details. The ssm is necessary due to a
+	 * PCXT bug.
 	 */
 
 	.align 4096
 
 	.export	syscall_exit_rfi
 syscall_exit_rfi:
-	copy    %r30,%r16
-	/* FIXME! depi below has hardcoded dependency on kernel stack size */
-	depi    0,31,14,%r16 /* get task pointer */
+	mfctl   %cr30,%r16
 	ldo	TASK_REGS(%r16),%r16
 	/* Force iaoq to userspace, as the user has had access to our current
-	 * context via sigcontext.
-	 * XXX do we need any other protection here?
+	 * context via sigcontext. Also Filter the PSW for the same reason.
 	 */
 	LDREG	PT_IAOQ0(%r16),%r19
 	depi	3,31,2,%r19
@@ -615,57 +658,84 @@
 	LDREG	PT_IAOQ1(%r16),%r19
 	depi	3,31,2,%r19
 	STREG	%r19,PT_IAOQ1(%r16)
-	
+	LDREG   PT_PSW(%r16),%r19
+	ldil    L%USER_PSW_MASK,%r1
+	ldo     R%USER_PSW_MASK(%r1),%r1
+#ifdef __LP64__
+	ldil    L%USER_PSW_HI_MASK,%r20
+	ldo     R%USER_PSW_HI_MASK(%r20),%r20
+	depd    %r20,31,32,%r1
+#endif
+	and     %r19,%r1,%r19 /* Mask out bits that user shouldn't play with */
+	ldil    L%USER_PSW,%r1
+	ldo     R%USER_PSW(%r1),%r1
+	or      %r19,%r1,%r19 /* Make sure default USER_PSW bits are set */
+	STREG   %r19,PT_PSW(%r16)
+
+	/*
+	 * If we aren't being traced, we never saved space registers
+	 * (we don't store them in the sigcontext), so set them
+	 * to "proper" values now (otherwise we'll wind up restoring
+	 * whatever was last stored in the task structure, which might
+	 * be inconsistant if an interrupt occured while on the gateway
+	 * page) Note that we may be "trashing" values the user put in
+	 * them, but we don't support the the user changing them.
+	 */
+
+	STREG   %r0,PT_SR2(%r16)
+	mfsp    %sr3,%r19
+	STREG   %r19,PT_SR0(%r16)
+	STREG   %r19,PT_SR1(%r16)
+	STREG   %r19,PT_SR3(%r16)
+	STREG   %r19,PT_SR4(%r16)
+	STREG   %r19,PT_SR5(%r16)
+	STREG   %r19,PT_SR6(%r16)
+	STREG   %r19,PT_SR7(%r16)
+
 intr_return:
+	ssm     PSW_SM_I, %r0
 
 	/* Check for software interrupts */
 
 	.import irq_stat,data
 
-	ldil    L%irq_stat,%r19
-	ldo     R%irq_stat(%r19),%r19
-	LDIL_FIXUP(%r19)
-
+	ldil	L%irq_stat,%r19
+	ldo	R%irq_stat(%r19),%r19
 #ifdef CONFIG_SMP
-	copy    %r30,%r1
-	/* FIXME! depi below has hardcoded dependency on kernel stack size */
-	depi    0,31,14,%r1 /* get task pointer */
-	ldw     TASK_PROCESSOR(%r1),%r20 /* get cpu # - int */
-#if (IRQSTAT_SZ == 32)
-	dep     %r20,26,27,%r20 /* shift left 5 bits */
-#else
-#error IRQSTAT_SZ changed, fix dep
-#endif /* IRQSTAT_SZ */
-	add     %r19,%r20,%r19
+	mfctl   %cr30,%r1
+	ldw	TASK_PROCESSOR(%r1),%r1 /* get cpu # - int */
+	/* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) amount
+	** irq_stat[] is defined using ____cacheline_aligned.
+	*/
+#ifdef __LP64__
+	shld	%r1, 6, %r20
+#else
+	shlw	%r1, 5, %r20
+#endif
+	add     %r19,%r20,%r19	/* now have &irq_stat[smp_processor_id()] */
 #endif /* CONFIG_SMP */
 
-	ldw     IRQSTAT_SI_ACTIVE(%r19),%r20	/* hardirq.h: unsigned int */
-	ldw     IRQSTAT_SI_MASK(%r19),%r19	/* hardirq.h: unsigned int */
-	and     %r19,%r20,%r20
-	comib,<>,n 0,%r20,intr_do_softirq /* forward */
+	LDREG   IRQSTAT_SIRQ_PEND(%r19),%r20    /* hardirq.h: unsigned long */
+	cmpib,<>,n 0,%r20,intr_do_softirq /* forward */
 
 intr_check_resched:
 
 	/* check for reschedule */
-	copy    %r30,%r1
-	/* FIXME! depi below has hardcoded dependency on kernel stack size */
-	depi    0,31,14,%r1 /* get task pointer */
+	mfctl   %cr30,%r1
 	LDREG     TASK_NEED_RESCHED(%r1),%r19	/* sched.h: long need_resched */
-	comib,<>,n 0,%r19,intr_do_resched /* forward */
+	CMPIB<>,n 0,%r19,intr_do_resched /* forward */
 
 intr_check_sig:
 	/* As above */
-	copy    %r30,%r1
-	depi    0,31,14,%r1 /* get task pointer */
+	mfctl   %cr30,%r1
 	ldw	TASK_SIGPENDING(%r1),%r19	/* sched.h: int sigpending */
-	comib,<>,n 0,%r19,intr_do_signal /* forward */
+	cmpib,<>,n 0,%r19,intr_do_signal /* forward */
 
 intr_restore:
-	copy	    	%r16, %r29
-	ldo		PT_FR31(%r29), %r29
-	rest_fp		%r29
-	copy    	%r16, %r29
-	rest_general 	%r29
+	copy            %r16,%r29
+	ldo             PT_FR31(%r29),%r1
+	rest_fp         %r1
+	rest_general    %r29
 	ssm		0,%r0
 	nop
 	nop
@@ -674,10 +744,10 @@
 	nop
 	nop
 	nop
-	tophys		%r29
-	mtsm		%r0
+	tophys_r1       %r29
+	rsm             (PSW_SM_Q|PSW_SM_P|PSW_SM_D|PSW_SM_I),%r0
 	rest_specials	%r29
-	rest_stack	%r29
+	rest_stack
 	rfi
 	nop
 	nop
@@ -691,88 +761,175 @@
 	.import do_softirq,code
 intr_do_softirq:
 	bl      do_softirq,%r2
+#ifdef __LP64__
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#else
 	nop
+#endif
 	b       intr_check_resched
 	nop
 
 	.import schedule,code
 intr_do_resched:
 	/* Only do reschedule if we are returning to user space */
-	LDREG     PT_SR7(%r16), %r20
-	comib,= 0,%r20,intr_restore /* backward */
+	LDREG   PT_IASQ0(%r16), %r20
+	CMPIB= 0,%r20,intr_restore /* backward */
+	nop
+	LDREG   PT_IASQ1(%r16), %r20
+	CMPIB= 0,%r20,intr_restore /* backward */
 	nop
 
-	bl      schedule,%r2
-	ssm     PSW_SM_I, %r0
+#ifdef __LP64__
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#endif
+
+	ldil	L%intr_return, %r2
+	b	schedule
+	ldo	R%intr_return(%r2), %r2	/* return to intr_return, not here */
 
-	/* It's OK to leave I bit on */
-	b       intr_return /* start over if we got a resched */
-	nop
 
 	.import do_signal,code
 intr_do_signal:
 	/* Only do signals if we are returning to user space */
-	LDREG   PT_SR7(%r16), %r20
-	comib,= 0,%r20,intr_restore /* backward */
+	LDREG   PT_IASQ0(%r16), %r20
+	CMPIB= 0,%r20,intr_restore /* backward */
+	nop
+	LDREG   PT_IASQ1(%r16), %r20
+	CMPIB= 0,%r20,intr_restore /* backward */
 	nop
 
 	copy	%r0, %r24			/* unsigned long in_syscall */
 	copy	%r16, %r25			/* struct pt_regs *regs */
 	ssm     PSW_SM_I, %r0
+#ifdef __LP64__
+	ldo	-16(%r30),%r29			/* Reference param save area */
+#endif
 	bl	do_signal,%r2
 	copy	%r0, %r26			/* sigset_t *oldset = NULL */
 
 	b	intr_restore
 	nop
 
-	/* CR28 - saved GR1
-	 * CR29 - argument for do_irq_mask */
+	/*
+	 * External interrupts.
+	 */
 
-	/* External interrupts */
 intr_extint:
-	get_stack
+	CMPIB=,n 0,%r16,1f
+	get_stack_use_cr30
+	b,n 3f
+
+1:
+#if 0  /* Interrupt Stack support not working yet! */
+	mfctl	%cr31,%r1
+	copy	%r30,%r17
+	/* FIXME! depi below has hardcoded idea of interrupt stack size (32k)*/
+#ifdef __LP64__
+	depdi	0,63,15,%r17
+#else
+	depi	0,31,15,%r17
+#endif
+	CMPB=,n	%r1,%r17,2f
+	get_stack_use_cr31
+	b,n 3f
+#endif
+2:
+	get_stack_use_r30
+
+3:
 	save_specials	%r29
-	virt_map	rfi
+	virt_map
 	save_general	%r29
 
-	ldo		PT_FR0(%r29), %r24
-	save_fp		%r24
+	ldo	PT_FR0(%r29), %r24
+	save_fp	%r24
 	
 	loadgp
 
-	copy		%r29, %r24	/* arg2 is pt_regs */
-	copy		%r29, %r16	/* save pt_regs */
+	copy	%r29, %r25	/* arg1 is pt_regs */
+	copy	%r29, %r16	/* save pt_regs */
 #ifdef CONFIG_KWDB
-	copy		%r29, %r3	/* KWDB - update frame pointer (gr3) */
+	copy	%r29, %r3	/* KWDB - update frame pointer (gr3) */
 #endif
 
-	/* sorry to put this cruft in the interrupt path */
-	ldil		L%cpu_irq_region, %r25
-	ldo		R%cpu_irq_region(%r25), %r25
-	bl		do_irq_mask,%r2
 #ifdef __LP64__
-	LDIL_FIXUP(%r25)
+	ldo	-16(%r30),%r29	/* Reference param save area */
 #else
 	nop
 #endif
-
-	b		intr_return
-	nop
+	
+	/*
+	 * We need to either load the CPU's ID or IRQ region.
+	 * Until we have "per CPU" IRQ regions, this is easy.
+	 */
+	ldil	L%cpu_irq_region, %r26
+	ldil	L%intr_return, %r2
+	ldo	R%cpu_irq_region(%r26), %r26
+	
+	b	do_cpu_irq_mask
+	ldo	R%intr_return(%r2), %r2	/* return to intr_return, not here */
 
 	/* Generic interruptions (illegal insn, unaligned, page fault, etc) */
 
 	.export         intr_save, code /* for os_hpmc */
 
 intr_save:
-	get_stack
+	mfsp    %sr7,%r16
+	CMPIB=,n 0,%r16,1f
+	get_stack_use_cr30
+	b	2f
+	copy    %r8,%r26
+
+1:
+	get_stack_use_r30
+	copy    %r8,%r26
+
+2:
 	save_specials	%r29
 
-	mfctl		%cr20, %r1
-	STREG		%r1, PT_ISR(%r29)
-	mfctl		%cr21, %r1
-	STREG		%r1, PT_IOR(%r29)
+	/* If this trap is a itlb miss, skip saving/adjusting isr/ior */
+
+	/*
+	 * FIXME: 1) Use a #define for the hardwired "6" below (and in
+	 *           traps.c.
+	 *        2) Once we start executing code above 4 Gb, we need
+	 *           to adjust iasq/iaoq here in the same way we
+	 *           adjust isr/ior below.
+	 */
+
+	CMPIB=,n        6,%r26,skip_save_ior
+
+	/* save_specials left ipsw value in r8 for us to test */
+
+	mfctl           %cr20, %r16 /* isr */
+	mfctl           %cr21, %r17 /* ior */
+
+#ifdef __LP64__
+	/*
+	 * If the interrupted code was running with W bit off (32 bit),
+	 * clear the b bits (bits 0 & 1) in the ior.
+	 */
+	extrd,u,*<>     %r8,PSW_W_BIT,1,%r0
+	depdi           0,1,2,%r17
+
+	/*
+	 * FIXME: This code has hardwired assumptions about the split
+	 *        between space bits and offset bits. This will change
+	 *        when we allow alternate page sizes.
+	 */
+
+	/* adjust isr/ior. */
+
+	extrd,u         %r16,63,7,%r1    /* get high bits from isr for ior */
+	depd            %r1,31,7,%r17    /* deposit them into ior */
+	depdi           0,63,7,%r16      /* clear them from isr */
+#endif
+	STREG           %r16, PT_ISR(%r29)
+	STREG           %r17, PT_IOR(%r29)
+
 
-	virt_map	rfi
+skip_save_ior:
+	virt_map
 	save_general	%r29
 
 	ldo		PT_FR0(%r29), %r25
@@ -785,11 +942,16 @@
 	copy		%r29, %r3	/* KWDB - update frame pointer (gr3) */
 #endif
 
-	bl		handle_interruption,%r2
-	copy		%r29, %r16	/* save pt_regs */
+#ifdef __LP64__
+	ldo		-16(%r30),%r29	/* Reference param save area */
+#endif
+
+	ldil		L%intr_return, %r2
+	copy		%r25, %r16	/* save pt_regs */
+
+	b		handle_interruption
+	ldo		R%intr_return(%r2), %r2	/* return to intr_return */
 
-	b		intr_return
-	nop
 
 	/*
 	 * Note for all tlb miss handlers:
@@ -821,10 +983,9 @@
 #ifdef __LP64__
 
 dtlb_miss_20w:
-
-	extrd,u         spc,31,7,t1     /* adjust va */
+	extrd,u         spc,63,7,t1     /* adjust va */
 	depd            t1,31,7,va      /* adjust va */
-	depdi           0,31,7,spc      /* adjust space */
+	depdi           0,63,7,spc      /* adjust space */
 	mfctl           %cr25,ptp	/* Assume user space miss */
 	or,*<>          %r0,spc,%r0     /* If it is user space, nullify */
 	mfctl           %cr24,ptp	/* Load kernel pgd instead */
@@ -832,20 +993,20 @@
 
 	mfsp            %sr7,t0		/* Get current space */
 	or,*=           %r0,t0,%r0      /* If kernel, nullify following test */
-	comb,<>,n       t0,spc,dtlb_fault /* forward */
+	cmpb,*<>,n       t0,spc,dtlb_fault /* forward */
 
 	/* First level page table lookup */
 
 	ldd,s           t1(ptp),ptp
 	extrd,u         va,42,9,t0     /* get second-level index */
-	bb,>=,n 	ptp,_PAGE_PRESENT_BIT,dtlb_fault
+	bb,>=,n         ptp,_PAGE_PRESENT_BIT,dtlb_check_alias_20w
 	depdi           0,63,12,ptp     /* clear prot bits */
 
 	/* Second level page table lookup */
 
 	ldd,s           t0(ptp),ptp
 	extrd,u         va,51,9,t0     /* get third-level index */
-	bb,>=,n 	ptp,_PAGE_PRESENT_BIT,dtlb_fault
+	bb,>=,n         ptp,_PAGE_PRESENT_BIT,dtlb_check_alias_20w
 	depdi           0,63,12,ptp     /* clear prot bits */
 
 	/* Third level page table lookup */
@@ -853,7 +1014,7 @@
 	shladd           t0,3,ptp,ptp
 	ldi		_PAGE_ACCESSED,t1
 	ldd              0(ptp),pte
-	bb,>=,n          pte,_PAGE_PRESENT_BIT,dtlb_fault
+	bb,>=,n          pte,_PAGE_PRESENT_BIT,dtlb_check_alias_20w
 
 	/* Check whether the "accessed" bit was set, otherwise do so */
 
@@ -861,11 +1022,9 @@
 	and,*<>         t1,pte,%r0      /* test and nullify if already set */
 	std             t0,0(ptp)       /* write back pte */
 
-	copy            spc,prot	/* init prot with faulting space */
-	
-	depd		pte,8,7,prot
-	extrd,u,*=	pte,_PAGE_NO_CACHE_BIT+32,1,r0
-	depdi		1,12,1,prot
+	space_to_prot   spc prot        /* create prot id from space */
+	depd            pte,8,7,prot    /* add in prot bits from pte */
+
 	extrd,u,*=      pte,_PAGE_USER_BIT+32,1,r0
 	depdi		7,11,3,prot   /* Set for user space (1 rsvd for read) */
 	extrd,u,*= 	pte,_PAGE_GATEWAY_BIT+32,1,r0
@@ -874,11 +1033,106 @@
 	/* Get rid of prot bits and convert to page addr for idtlbt */
 
 	depdi		0,63,12,pte
-	extrd,u         pte,56,32,pte
-	idtlbt		%r16,%r17
+	extrd,u         pte,56,52,pte
+	idtlbt          pte,prot
 
 	rfir
 	nop
+
+dtlb_check_alias_20w:
+
+	/* Check to see if fault is in the temporary alias region */
+
+	cmpib,*<>,n     0,spc,dtlb_fault /* forward */
+	ldil            L%(TMPALIAS_MAP_START),t0
+	copy            va,t1
+	depdi           0,63,23,t1
+	cmpb,*<>,n      t0,t1,dtlb_fault /* forward */
+	ldi             (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),prot
+	depd,z          prot,8,7,prot
+
+	/*
+	 * OK, it is in the temp alias region, check whether "from" or "to".
+	 * Check "subtle" note in pacache.S re: r23/r26.
+	 */
+
+	extrd,u,*=      va,41,1,r0
+	or,*tr          %r23,%r0,pte    /* If "from" use "from" page */
+	or,*            %r26,%r0,pte    /* else "to", use "to" page  */
+
+	idtlbt          pte,prot
+
+	rfir
+	nop
+
+nadtlb_miss_20w:
+	extrd,u         spc,63,7,t1     /* adjust va */
+	depd            t1,31,7,va      /* adjust va */
+	depdi           0,63,7,spc      /* adjust space */
+	mfctl           %cr25,ptp	/* Assume user space miss */
+	or,*<>          %r0,spc,%r0     /* If it is user space, nullify */
+	mfctl           %cr24,ptp	/* Load kernel pgd instead */
+	extrd,u         va,33,9,t1      /* Get pgd index */
+
+	mfsp            %sr7,t0		/* Get current space */
+	or,*=           %r0,t0,%r0      /* If kernel, nullify following test */
+	cmpb,*<>,n       t0,spc,nadtlb_fault /* forward */
+
+	/* First level page table lookup */
+
+	ldd,s           t1(ptp),ptp
+	extrd,u         va,42,9,t0     /* get second-level index */
+	bb,>=,n         ptp,_PAGE_PRESENT_BIT,nadtlb_emulate
+	depdi           0,63,12,ptp     /* clear prot bits */
+
+	/* Second level page table lookup */
+
+	ldd,s           t0(ptp),ptp
+	extrd,u         va,51,9,t0     /* get third-level index */
+	bb,>=,n         ptp,_PAGE_PRESENT_BIT,nadtlb_emulate
+	depdi           0,63,12,ptp     /* clear prot bits */
+
+	/* Third level page table lookup */
+
+	shladd           t0,3,ptp,ptp
+	ldi		_PAGE_ACCESSED,t1
+	ldd              0(ptp),pte
+	bb,>=,n          pte,_PAGE_PRESENT_BIT,nadtlb_check_flush_20w
+
+	space_to_prot   spc prot        /* create prot id from space */
+	depd            pte,8,7,prot    /* add in prot bits from pte */
+
+	extrd,u,*=      pte,_PAGE_USER_BIT+32,1,r0
+	depdi		7,11,3,prot   /* Set for user space (1 rsvd for read) */
+	extrd,u,*= 	pte,_PAGE_GATEWAY_BIT+32,1,r0
+	depdi		0,11,2,prot	/* If Gateway, Set PL2 to 0 */
+
+	/* Get rid of prot bits and convert to page addr for idtlbt */
+
+	depdi		0,63,12,pte
+	extrd,u         pte,56,52,pte
+	idtlbt          pte,prot
+
+	rfir
+	nop
+
+nadtlb_check_flush_20w:
+	bb,>=,n          pte,_PAGE_FLUSH_BIT,nadtlb_emulate
+
+	/* Insert a "flush only" translation */
+
+	depdi,z         7,7,3,prot
+	depdi           1,10,1,prot
+
+	/* Get rid of prot bits and convert to page addr for idtlbt */
+
+	depdi		0,63,12,pte
+	extrd,u         pte,56,52,pte
+	idtlbt          pte,prot
+
+	rfir
+	nop
+
 #else
 
 dtlb_miss_11:
@@ -889,13 +1143,13 @@
 
 	mfsp            %sr7,t0		/* Get current space */
 	or,=            %r0,t0,%r0	/* If kernel, nullify following test */
-	comb,<>,n       t0,spc,dtlb_fault /* forward */
+	cmpb,<>,n       t0,spc,dtlb_fault /* forward */
 
 	/* First level page table lookup */
 
 	ldwx,s		t1(ptp),ptp
 	extru		va,19,10,t0	/* get second-level index */
-	bb,>=,n 	ptp,_PAGE_PRESENT_BIT,dtlb_fault
+	bb,>=,n         ptp,_PAGE_PRESENT_BIT,dtlb_check_alias_11
 	depi		0,31,12,ptp	/* clear prot bits */
 
 	/* Second level page table lookup */
@@ -903,7 +1157,7 @@
 	sh2addl 	 t0,ptp,ptp
 	ldi		_PAGE_ACCESSED,t1
 	ldw		 0(ptp),pte
-	bb,>=,n 	 pte,_PAGE_PRESENT_BIT,dtlb_fault
+	bb,>=,n          pte,_PAGE_PRESENT_BIT,dtlb_check_alias_11
 
 	/* Check whether the "accessed" bit was set, otherwise do so */
 
@@ -911,8 +1165,8 @@
 	and,<>		t1,pte,%r0	/* test and nullify if already set */
 	stw		t0,0(ptp)	/* write back pte */
 
-	copy            spc,prot	/* init prot with faulting space */
-	dep		pte,8,7,prot
+	zdep            spc,30,15,prot  /* create prot id from space */
+	dep             pte,8,7,prot    /* add in prot bits from pte */
 
 	extru,=		pte,_PAGE_NO_CACHE_BIT,1,r0
 	depi		1,12,1,prot
@@ -937,9 +1191,108 @@
 	rfir
 	nop
 
-dtlb_miss_20:
-	.level 2.0
+dtlb_check_alias_11:
+
+	/* Check to see if fault is in the temporary alias region */
+
+	cmpib,<>,n      0,spc,dtlb_fault /* forward */
+	ldil            L%(TMPALIAS_MAP_START),t0
+	copy            va,t1
+	depwi           0,31,23,t1
+	cmpb,<>,n       t0,t1,dtlb_fault /* forward */
+	ldi             (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),prot
+	depw,z          prot,8,7,prot
+
+	/*
+	 * OK, it is in the temp alias region, check whether "from" or "to".
+	 * Check "subtle" note in pacache.S re: r23/r26.
+	 */
+
+	extrw,u,=       va,9,1,r0
+	or,tr           %r23,%r0,pte    /* If "from" use "from" page */
+	or              %r26,%r0,pte    /* else "to", use "to" page  */
+
+	idtlba          pte,(va)
+	idtlbp          prot,(va)
+
+	rfir
+	nop
+
+nadtlb_miss_11:
+	mfctl           %cr25,ptp	/* Assume user space miss */
+	or,<>           %r0,spc,%r0	/* If it is user space, nullify */
+	mfctl           %cr24,ptp	/* Load kernel pgd instead */
+	extru		va,9,10,t1	/* Get pgd index */
+
+	mfsp            %sr7,t0		/* Get current space */
+	or,=            %r0,t0,%r0	/* If kernel, nullify following test */
+	cmpb,<>,n       t0,spc,nadtlb_fault /* forward */
+
+	/* First level page table lookup */
+
+	ldwx,s		t1(ptp),ptp
+	extru		va,19,10,t0	/* get second-level index */
+	bb,>=,n         ptp,_PAGE_PRESENT_BIT,nadtlb_emulate
+	depi		0,31,12,ptp	/* clear prot bits */
+
+	/* Second level page table lookup */
+
+	sh2addl 	 t0,ptp,ptp
+	ldi		_PAGE_ACCESSED,t1
+	ldw		 0(ptp),pte
+	bb,>=,n          pte,_PAGE_PRESENT_BIT,nadtlb_check_flush_11
+
+	zdep            spc,30,15,prot  /* create prot id from space */
+	dep             pte,8,7,prot    /* add in prot bits from pte */
+
+	extru,=		pte,_PAGE_NO_CACHE_BIT,1,r0
+	depi		1,12,1,prot
+	extru,=         pte,_PAGE_USER_BIT,1,r0
+	depi		7,11,3,prot   /* Set for user space (1 rsvd for read) */
+	extru,= 	pte,_PAGE_GATEWAY_BIT,1,r0
+	depi		0,11,2,prot	/* If Gateway, Set PL2 to 0 */
+
+	/* Get rid of prot bits and convert to page addr for idtlba */
+
+	depi		0,31,12,pte
+	extru		pte,24,25,pte
+
+	mfsp		%sr1,t0  /* Save sr1 so we can use it in tlb inserts */
+	mtsp		spc,%sr1
+
+	idtlba		pte,(%sr1,va)
+	idtlbp		prot,(%sr1,va)
+
+	mtsp		t0, %sr1	/* Restore sr1 */
+
+	rfir
+	nop
+
+nadtlb_check_flush_11:
+	bb,>=,n          pte,_PAGE_FLUSH_BIT,nadtlb_emulate
+
+	/* Insert a "flush only" translation */
+
+	zdepi           7,7,3,prot
+	depi            1,10,1,prot
+
+	/* Get rid of prot bits and convert to page addr for idtlba */
+
+	depi		0,31,12,pte
+	extru		pte,24,25,pte
 
+	mfsp		%sr1,t0  /* Save sr1 so we can use it in tlb inserts */
+	mtsp		spc,%sr1
+
+	idtlba		pte,(%sr1,va)
+	idtlbp		prot,(%sr1,va)
+
+	mtsp		t0, %sr1	/* Restore sr1 */
+
+	rfir
+	nop
+
+dtlb_miss_20:
 	mfctl           %cr25,ptp	/* Assume user space miss */
 	or,<>           %r0,spc,%r0	/* If it is user space, nullify */
 	mfctl           %cr24,ptp	/* Load kernel pgd instead */
@@ -947,13 +1300,13 @@
 
 	mfsp            %sr7,t0		/* Get current space */
 	or,=            %r0,t0,%r0	/* If kernel, nullify following test */
-	comb,<>,n       t0,spc,dtlb_fault /* forward */
+	cmpb,<>,n       t0,spc,dtlb_fault /* forward */
 
 	/* First level page table lookup */
 
 	ldwx,s		t1(ptp),ptp
 	extru		va,19,10,t0	/* get second-level index */
-	bb,>=,n 	ptp,_PAGE_PRESENT_BIT,dtlb_fault
+	bb,>=,n         ptp,_PAGE_PRESENT_BIT,dtlb_check_alias_20
 	depi		0,31,12,ptp	/* clear prot bits */
 
 	/* Second level page table lookup */
@@ -961,7 +1314,7 @@
 	sh2addl 	 t0,ptp,ptp
 	ldi		_PAGE_ACCESSED,t1
 	ldw		 0(ptp),pte
-	bb,>=,n 	 pte,_PAGE_PRESENT_BIT,dtlb_fault
+	bb,>=,n          pte,_PAGE_PRESENT_BIT,dtlb_check_alias_20
 
 	/* Check whether the "accessed" bit was set, otherwise do so */
 
@@ -969,11 +1322,9 @@
 	and,<>		t1,pte,%r0	/* test and nullify if already set */
 	stw		t0,0(ptp)	/* write back pte */
 
-	copy            spc,prot	/* init prot with faulting space */
-	
-	depd		pte,8,7,prot
-	extrd,u,*=	pte,_PAGE_NO_CACHE_BIT+32,1,r0
-	depdi		1,12,1,prot
+	space_to_prot   spc prot        /* create prot id from space */
+	depd            pte,8,7,prot    /* add in prot bits from pte */
+
 	extrd,u,*=      pte,_PAGE_USER_BIT+32,1,r0
 	depdi		7,11,3,prot   /* Set for user space (1 rsvd for read) */
 	extrd,u,*= 	pte,_PAGE_GATEWAY_BIT+32,1,r0
@@ -981,16 +1332,145 @@
 
 	/* Get rid of prot bits and convert to page addr for idtlbt */
 
-	depdi		0,63,12,pte
-	extrd,u		pte,56,25,pte
-	idtlbt		%r16,%r17
+	extrd,s         pte,35,4,t0
+	depdi		0,63,12,pte	/* clear lower 12 bits */
+        addi,=          1,t0,0 
+        extrd,u,*tr     pte,56,25,pte 
+	extrd,s		pte,56,25,pte	/* bit 31:8 >> 8  */ 
+	idtlbt          pte,prot
+
+	rfir
+	nop
+
+dtlb_check_alias_20:
+
+	/* Check to see if fault is in the temporary alias region */
 
-	.level		1.1
+	cmpib,<>,n      0,spc,dtlb_fault /* forward */
+	ldil            L%(TMPALIAS_MAP_START),t0
+	copy            va,t1
+	depwi           0,31,23,t1
+	cmpb,<>,n       t0,t1,dtlb_fault /* forward */
+	ldi             (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),prot
+	depd,z          prot,8,7,prot
+
+	/*
+	 * OK, it is in the temp alias region, check whether "from" or "to".
+	 * Check "subtle" note in pacache.S re: r23/r26.
+	 */
+
+	extrw,u,=       va,9,1,r0
+	or,tr           %r23,%r0,pte    /* If "from" use "from" page */
+	or              %r26,%r0,pte    /* else "to", use "to" page  */
+
+	idtlbt          pte,prot
+
+	rfir
+	nop
+
+nadtlb_miss_20:
+	mfctl           %cr25,ptp	/* Assume user space miss */
+	or,<>           %r0,spc,%r0	/* If it is user space, nullify */
+	mfctl           %cr24,ptp	/* Load kernel pgd instead */
+	extru		va,9,10,t1	/* Get pgd index */
+
+	mfsp            %sr7,t0		/* Get current space */
+	or,=            %r0,t0,%r0	/* If kernel, nullify following test */
+	cmpb,<>,n       t0,spc,nadtlb_fault /* forward */
+
+	/* First level page table lookup */
+
+	ldwx,s		t1(ptp),ptp
+	extru		va,19,10,t0	/* get second-level index */
+	bb,>=,n         ptp,_PAGE_PRESENT_BIT,nadtlb_emulate
+	depi		0,31,12,ptp	/* clear prot bits */
+
+	/* Second level page table lookup */
+
+	sh2addl 	 t0,ptp,ptp
+	ldi		_PAGE_ACCESSED,t1
+	ldw		 0(ptp),pte
+	bb,>=,n          pte,_PAGE_PRESENT_BIT,nadtlb_check_flush_20
+
+	space_to_prot   spc prot        /* create prot id from space */
+	depd            pte,8,7,prot    /* add in prot bits from pte */
+
+	extrd,u,*=      pte,_PAGE_USER_BIT+32,1,r0
+	depdi		7,11,3,prot   /* Set for user space (1 rsvd for read) */
+	extrd,u,*= 	pte,_PAGE_GATEWAY_BIT+32,1,r0
+	depdi		0,11,2,prot	/* If Gateway, Set PL2 to 0 */
+
+	/* Get rid of prot bits and convert to page addr for idtlbt */
+
+        extrd,s         pte,35,4,t0
+        depdi           0,63,12,pte     /* clear lower 12 bits */
+        addi,=          1,t0,0
+        extrd,u,*tr     pte,56,25,pte
+        extrd,s         pte,56,25,pte   /* bit 31:8 >> 8  */
+        idtlbt          pte,prot
+
+	rfir
+	nop
+
+nadtlb_check_flush_20:
+	bb,>=,n          pte,_PAGE_FLUSH_BIT,nadtlb_emulate
+
+	/* Insert a "flush only" translation */
+
+	depdi,z         7,7,3,prot
+	depdi           1,10,1,prot
+
+	/* Get rid of prot bits and convert to page addr for idtlbt */
+
+	depdi		0,63,12,pte
+	extrd,u         pte,56,32,pte
+	idtlbt          pte,prot
 
 	rfir
 	nop
 #endif
 
+nadtlb_emulate:
+
+	/*
+	 * Non access misses can be caused by fdc,fic,pdc,lpa,probe and
+	 * probei instructions. We don't want to fault for these
+	 * instructions (not only does it not make sense, it can cause
+	 * deadlocks, since some flushes are done with the mmap
+	 * semaphore held). If the translation doesn't exist, we can't
+	 * insert a translation, so have to emulate the side effects
+	 * of the instruction. Since we don't insert a translation
+	 * we can get a lot of faults during a flush loop, so it makes
+	 * sense to try to do it here with minimum overhead. We only
+	 * emulate fdc,fic & pdc instructions whose base and index
+	 * registers are not shadowed. We defer everything else to the
+	 * "slow" path.
+	 */
+
+	mfctl           %cr19,%r9 /* Get iir */
+	ldi             0x280,%r16
+	and             %r9,%r16,%r17
+	cmpb,<>,n       %r16,%r17,nadtlb_fault /* Not fdc,fic,pdc */
+	bb,>=,n         %r9,26,nadtlb_nullify  /* m bit not set, just nullify */
+	b,l             get_register,%r25
+	extrw,u         %r9,15,5,%r8           /* Get index register # */
+	CMPIB=,n        -1,%r1,nadtlb_fault    /* have to use slow path */
+	copy            %r1,%r24
+	b,l             get_register,%r25
+	extrw,u         %r9,10,5,%r8           /* Get base register # */
+	CMPIB=,n        -1,%r1,nadtlb_fault    /* have to use slow path */
+	b,l             set_register,%r25
+	add,l           %r1,%r24,%r1           /* doesn't affect c/b bits */
+
+nadtlb_nullify:
+	mfctl           %cr22,%r8              /* Get ipsw */
+	ldil            L%PSW_N,%r9
+	or              %r8,%r9,%r8            /* Set PSW_N */
+	mtctl           %r8,%cr22
+
+	rfir
+	nop
+
 #ifdef __LP64__
 itlb_miss_20w:
 
@@ -999,9 +1479,9 @@
 	 * on the gateway page which is in the kernel address space.
 	 */
 
-	extrd,u         spc,31,7,t1     /* adjust va */
+	extrd,u         spc,63,7,t1     /* adjust va */
 	depd            t1,31,7,va      /* adjust va */
-	depdi           0,31,7,spc      /* adjust space */
+	depdi           0,63,7,spc      /* adjust space */
 	cmpib,*=        0,spc,itlb_miss_kernel_20w
 	extrd,u         va,33,9,t1      /* Get pgd index */
 
@@ -1039,11 +1519,9 @@
 	and,*<>         t1,pte,%r0      /* test and nullify if already set */
 	std             t0,0(ptp)       /* write back pte */
 
-	copy            spc,prot        /* init prot with faulting space */
-	
-	depd		pte,8,7,prot
-	extrd,u,*=	pte,_PAGE_NO_CACHE_BIT+32,1,r0
-	depdi		1,12,1,prot
+	space_to_prot   spc prot        /* create prot id from space */
+	depd            pte,8,7,prot    /* add in prot bits from pte */
+
 	extrd,u,*=      pte,_PAGE_USER_BIT+32,1,r0
 	depdi		7,11,3,prot   /* Set for user space (1 rsvd for read) */
 	extrd,u,*= 	pte,_PAGE_GATEWAY_BIT+32,1,r0
@@ -1053,7 +1531,7 @@
 
 	depdi		0,63,12,pte
 	extrd,u         pte,56,32,pte
-	iitlbt          %r16,%r17
+	iitlbt          pte,prot
 
 	rfir
 	nop
@@ -1070,14 +1548,14 @@
 	 * on the gateway page which is in the kernel address space.
 	 */
 
-	comib,=         0,spc,itlb_miss_kernel_11
+	cmpib,=         0,spc,itlb_miss_kernel_11
 	extru		va,9,10,t1	/* Get pgd index */
 
 	mfctl           %cr25,ptp	/* load user pgd */
 
 	mfsp            %sr7,t0		/* Get current space */
 	or,=            %r0,t0,%r0	/* If kernel, nullify following test */
-	comb,<>,n       t0,spc,itlb_fault /* forward */
+	cmpb,<>,n       t0,spc,itlb_fault /* forward */
 
 	/* First level page table lookup */
 
@@ -1100,8 +1578,8 @@
 	and,<>		t1,pte,%r0	/* test and nullify if already set */
 	stw		t0,0(ptp)	/* write back pte */
 
-	copy            spc,prot        /* init prot with faulting space */
-	dep		pte,8,7,prot
+	zdep            spc,30,15,prot  /* create prot id from space */
+	dep             pte,8,7,prot    /* add in prot bits from pte */
 
 	extru,=		pte,_PAGE_NO_CACHE_BIT,1,r0
 	depi		1,12,1,prot
@@ -1137,14 +1615,14 @@
 	 * on the gateway page which is in the kernel address space.
 	 */
 
-	comib,=         0,spc,itlb_miss_kernel_20
+	cmpib,=         0,spc,itlb_miss_kernel_20
 	extru		va,9,10,t1	/* Get pgd index */
 
 	mfctl           %cr25,ptp	/* load user pgd */
 
 	mfsp            %sr7,t0		/* Get current space */
 	or,=            %r0,t0,%r0	/* If kernel, nullify following test */
-	comb,<>,n       t0,spc,itlb_fault /* forward */
+	cmpb,<>,n       t0,spc,itlb_fault /* forward */
 
 	/* First level page table lookup */
 
@@ -1167,13 +1645,9 @@
 	and,<>		t1,pte,%r0	/* test and nullify if already set */
 	stw		t0,0(ptp)	/* write back pte */
 
-	copy            spc,prot        /* init prot with faulting space */
-	
-	.level 2.0
+	space_to_prot   spc prot        /* create prot id from space */
+	depd            pte,8,7,prot    /* add in prot bits from pte */
 
-	depd		pte,8,7,prot
-	extrd,u,*=	pte,_PAGE_NO_CACHE_BIT+32,1,r0
-	depdi		1,12,1,prot
 	extrd,u,*=      pte,_PAGE_USER_BIT+32,1,r0
 	depdi		7,11,3,prot   /* Set for user space (1 rsvd for read) */
 	extrd,u,*= 	pte,_PAGE_GATEWAY_BIT+32,1,r0
@@ -1181,10 +1655,12 @@
 
 	/* Get rid of prot bits and convert to page addr for iitlbt */
 
-	depdi		0,63,12,pte
-	extrd,u		pte,56,25,pte
-	iitlbt          %r16,%r17
-	.level		1.1
+        extrd,s         pte,35,4,t0 
+        depdi           0,63,12,pte     /* clear lower 12 bits */
+        addi,=          1,t0,0
+        extrd,u,*tr     pte,56,25,pte 
+        extrd,s         pte,56,25,pte   /* bit 31:8 >> 8  */
+	iitlbt          pte,prot
 
 	rfir
 	nop
@@ -1198,11 +1674,10 @@
 #ifdef __LP64__
 
 dbit_trap_20w:
-
-	extrd,u         spc,31,7,t1     /* adjust va */
+	extrd,u         spc,63,7,t1     /* adjust va */
 	depd            t1,31,7,va      /* adjust va */
 	depdi           0,1,2,va        /* adjust va */
-	depdi           0,31,7,spc      /* adjust space */
+	depdi           0,63,7,spc      /* adjust space */
 	mfctl           %cr25,ptp	/* Assume user space miss */
 	or,*<>          %r0,spc,%r0     /* If it is user space, nullify */
 	mfctl           %cr24,ptp	/* Load kernel pgd instead */
@@ -1210,7 +1685,7 @@
 
 	mfsp            %sr7,t0		/* Get current space */
 	or,*=           %r0,t0,%r0      /* If kernel, nullify following test */
-	comb,<>,n       t0,spc,dbit_fault /* forward */
+	cmpb,*<>,n       t0,spc,dbit_fault /* forward */
 
 	/* First level page table lookup */
 
@@ -1229,6 +1704,18 @@
 	/* Third level page table lookup */
 
 	shladd           t0,3,ptp,ptp
+#ifdef CONFIG_SMP
+	CMPIB=,n        0,spc,dbit_nolock_20w
+	ldil            L%PA(pa_dbit_lock),t0
+	ldo             R%PA(pa_dbit_lock)(t0),t0
+
+dbit_spin_20w:
+	ldcw            0(t0),t1
+	cmpib,=         0,t1,dbit_spin_20w
+	nop
+
+dbit_nolock_20w:
+#endif
 	ldi		(_PAGE_ACCESSED|_PAGE_DIRTY),t1
 	ldd              0(ptp),pte
 	bb,>=,n          pte,_PAGE_PRESENT_BIT,dbit_fault
@@ -1238,11 +1725,9 @@
 	or		t1,pte,pte
 	std             pte,0(ptp)      /* write back pte */
 
-	copy            spc,prot	/* init prot with faulting space */
-	
-	depd		pte,8,7,prot
-	extrd,u,*=	pte,_PAGE_NO_CACHE_BIT+32,1,r0
-	depdi		1,12,1,prot
+	space_to_prot   spc prot        /* create prot id from space */
+	depd            pte,8,7,prot    /* add in prot bits from pte */
+
 	extrd,u,*=      pte,_PAGE_USER_BIT+32,1,r0
 	depdi		7,11,3,prot   /* Set for user space (1 rsvd for read) */
 	extrd,u,*= 	pte,_PAGE_GATEWAY_BIT+32,1,r0
@@ -1251,8 +1736,15 @@
 	/* Get rid of prot bits and convert to page addr for idtlbt */
 
 	depdi		0,63,12,pte
-	extrd,u         pte,56,32,pte
-	idtlbt		%r16,%r17
+	extrd,u         pte,56,52,pte
+	idtlbt          pte,prot
+#ifdef CONFIG_SMP
+	CMPIB=,n        0,spc,dbit_nounlock_20w
+	ldi             1,t1
+	stw             t1,0(t0)
+
+dbit_nounlock_20w:
+#endif
 
 	rfir
 	nop
@@ -1266,7 +1758,7 @@
 
 	mfsp            %sr7,t0		/* Get current space */
 	or,=            %r0,t0,%r0	/* If kernel, nullify following test */
-	comb,<>,n       t0,spc,dbit_fault /* forward */
+	cmpb,<>,n       t0,spc,dbit_fault /* forward */
 
 	/* First level page table lookup */
 
@@ -1278,6 +1770,18 @@
 	/* Second level page table lookup */
 
 	sh2addl 	 t0,ptp,ptp
+#ifdef CONFIG_SMP
+	CMPIB=,n        0,spc,dbit_nolock_11
+	ldil            L%PA(pa_dbit_lock),t0
+	ldo             R%PA(pa_dbit_lock)(t0),t0
+
+dbit_spin_11:
+	ldcw            0(t0),t1
+	cmpib,=         0,t1,dbit_spin_11
+	nop
+
+dbit_nolock_11:
+#endif
 	ldi		(_PAGE_ACCESSED|_PAGE_DIRTY),t1
 	ldw		 0(ptp),pte
 	bb,>=,n 	 pte,_PAGE_PRESENT_BIT,dbit_fault
@@ -1287,8 +1791,8 @@
 	or		t1,pte,pte
 	stw		pte,0(ptp)	/* write back pte */
 
-	copy            spc,prot        /* init prot with faulting space */
-	dep		pte,8,7,prot
+	zdep            spc,30,15,prot  /* create prot id from space */
+	dep             pte,8,7,prot    /* add in prot bits from pte */
 
 	extru,=		pte,_PAGE_NO_CACHE_BIT,1,r0
 	depi		1,12,1,prot
@@ -1302,13 +1806,20 @@
 	depi		0,31,12,pte
 	extru		pte,24,25,pte
 
-	mfsp		%sr1,t0  /* Save sr1 so we can use it in tlb inserts */
+	mfsp            %sr1,t1  /* Save sr1 so we can use it in tlb inserts */
 	mtsp		spc,%sr1
 
 	idtlba		pte,(%sr1,va)
 	idtlbp		prot,(%sr1,va)
 
-	mtsp		t0, %sr1     /* Restore sr1 */
+	mtsp            t1, %sr1     /* Restore sr1 */
+#ifdef CONFIG_SMP
+	CMPIB=,n        0,spc,dbit_nounlock_11
+	ldi             1,t1
+	stw             t1,0(t0)
+
+dbit_nounlock_11:
+#endif
 
 	rfir
 	nop
@@ -1321,7 +1832,7 @@
 
 	mfsp            %sr7,t0		/* Get current space */
 	or,=            %r0,t0,%r0	/* If kernel, nullify following test */
-	comb,<>,n       t0,spc,dbit_fault /* forward */
+	cmpb,<>,n       t0,spc,dbit_fault /* forward */
 
 	/* First level page table lookup */
 
@@ -1333,6 +1844,18 @@
 	/* Second level page table lookup */
 
 	sh2addl 	 t0,ptp,ptp
+#ifdef CONFIG_SMP
+	CMPIB=,n        0,spc,dbit_nolock_20
+	ldil            L%PA(pa_dbit_lock),t0
+	ldo             R%PA(pa_dbit_lock)(t0),t0
+
+dbit_spin_20:
+	ldcw            0(t0),t1
+	cmpib,=         0,t1,dbit_spin_20
+	nop
+
+dbit_nolock_20:
+#endif
 	ldi		(_PAGE_ACCESSED|_PAGE_DIRTY),t1
 	ldw		 0(ptp),pte
 	bb,>=,n 	 pte,_PAGE_PRESENT_BIT,dbit_fault
@@ -1342,25 +1865,28 @@
 	or		t1,pte,pte
 	stw		pte,0(ptp)	/* write back pte */
 
-	copy            spc,prot        /* init prot with faulting space */
-	
-	.level 2.0
+	space_to_prot   spc prot        /* create prot id from space */
+	depd            pte,8,7,prot    /* add in prot bits from pte */
 
-	depd		pte,8,7,prot
-	extrd,u,*=	pte,_PAGE_NO_CACHE_BIT+32,1,r0
-	depdi		1,12,1,prot
 	extrd,u,*=      pte,_PAGE_USER_BIT+32,1,r0
 	depdi		7,11,3,prot   /* Set for user space (1 rsvd for read) */
 	extrd,u,*= 	pte,_PAGE_GATEWAY_BIT+32,1,r0
 	depdi		0,11,2,prot	/* If Gateway, Set PL2 to 0 */
 
-	/* Get rid of prot bits and convert to page addr for idtlbt */
+        extrd,s         pte,35,4,t0 
+        depdi           0,63,12,pte     /* clear lower 12 bits */
+        addi,=          1,t0,0
+        extrd,u,*tr     pte,56,25,pte 
+        extrd,s         pte,56,25,pte   /* bit 31:8 >> 8  */
+        idtlbt          pte,prot
 
-	depdi		0,63,12,pte
-	extrd,u		pte,56,25,pte
-	idtlbt		%r16,%r17
+#ifdef CONFIG_SMP
+	CMPIB=,n        0,spc,dbit_nounlock_20
+	ldi             1,t1
+	stw             t1,0(t0)
 
-	.level		1.1
+dbit_nounlock_20:
+#endif
 
 	rfir
 	nop
@@ -1369,50 +1895,24 @@
 	.import handle_interruption,code
 
 kernel_bad_space:
-	b		tlb_fault
-	ldi		31,%r1	/* Use an unused code */
+	b               intr_save
+	ldi             31,%r8  /* Use an unused code */
 
 dbit_fault:
-	b		tlb_fault
-	ldi		20,%r1
+	b               intr_save
+	ldi             20,%r8
 
 itlb_fault:
-	b		tlb_fault
-	ldi		6,%r1
-
-dtlb_fault:
-	ldi		15,%r1
+	b               intr_save
+	ldi             6,%r8
 
-	/* Fall Through */
+nadtlb_fault:
+	b               intr_save
+	ldi             17,%r8
 
-tlb_fault:
-	mtctl		%r1,%cr29
-	mtctl		%r29,%cr31
-
-	get_stack
-	save_specials	%r29		/* Note this saves a trashed r1 */
-
-	SAVE_CR		(%cr20, PT_ISR(%r29))
-	SAVE_CR		(%cr21, PT_IOR(%r29))
-
-	virt_map	rfir
-
-	STREG		%r1,PT_GR1(%r29)	/* save good value after rfir */
-
-	save_general	%r29
-
-	ldo	PT_FR0(%r29), %r25
-	save_fp		%r25
-	
-	loadgp
-
-	copy		%r29, %r25
-
-	bl		handle_interruption, %r2
-	copy		%r29, %r16
-
-	b		intr_return
-	nop
+dtlb_fault:
+	b               intr_save
+	ldi             15,%r8
 
 	/* Register saving semantics for system calls:
 
@@ -1475,21 +1975,23 @@
 	.endm
 
 	.export sys_fork_wrapper
+	.export child_return
 sys_fork_wrapper:
 	ldo	TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1	/* get pt regs */
 	reg_save %r1
+	mfctl	%cr27, %r3
+	STREG	%r3, PT_CR27(%r1)
 
 	STREG	%r2,-RP_OFFSET(%r30)
 	ldo	FRAME_SIZE(%r30),%r30
+#ifdef __LP64__
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#endif
 
 	/* These are call-clobbered registers and therefore
 	   also syscall-clobbered (we hope). */
 	STREG	%r2,PT_GR19(%r1)	/* save for child */
-	STREG	%r30,PT_GR20(%r1)
-	ldil	L%child_return, %r3
-	ldo	R%child_return(%r3), %r3
-	LDIL_FIXUP(%r3)
-	STREG	%r3,PT_GR21(%r1)	/* save for child */
+	STREG	%r30,PT_GR21(%r1)
 
 	LDREG	PT_GR30(%r1),%r25
 	copy	%r1,%r24
@@ -1501,14 +2003,21 @@
 	ldo	-FRAME_SIZE(%r30),%r30		/* get the stackframe */
 	ldo	TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1    /* get pt regs */
 
+	LDREG	PT_CR27(%r1), %r3
+	mtctl	%r3, %cr27
 	reg_restore %r1
 
+	/* strace expects syscall # to be preserved in r20 */
+	ldi	__NR_fork,%r20
 	bv %r0(%r2)
-	nop
+	STREG	%r20,PT_GR20(%r1)
 
 	/* Set the return value for the child */
 child_return:
-	LDREG	TASK_PT_GR19-TASK_SZ_ALGN-128(%r30),%r2
+	bl	schedule_tail, %r2
+	nop
+
+	LDREG	TASK_PT_GR19-TASK_SZ_ALGN-FRAME_SIZE-FRAME_SIZE(%r30),%r2
 	b	wrapper_exit
 	copy	%r0,%r28
 
@@ -1517,35 +2026,38 @@
 sys_clone_wrapper:
 	ldo	TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1	/* get pt regs */
 	reg_save %r1
+	mfctl	%cr27, %r3
+	STREG	%r3, PT_CR27(%r1)
 
 	STREG	%r2,-RP_OFFSET(%r30)
 	ldo	FRAME_SIZE(%r30),%r30
+#ifdef __LP64__
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#endif
 
-	STREG	%r30,PT_GR20(%r1)
-	ldil	L%child_return,%r3
-	ldo	R%child_return(%r3),%r3
-	LDIL_FIXUP(%r3)
-
+	STREG	%r2,PT_GR19(%r1)	/* save for child */
+	STREG	%r30,PT_GR21(%r1)
 	bl	sys_clone,%r2
-	STREG	%r3,PT_GR21(%r1)	/* save for child */
+	copy	%r1,%r24
 
 	b	wrapper_exit
 	LDREG	-RP_OFFSET-FRAME_SIZE(%r30),%r2
 
-
 	.export sys_vfork_wrapper
 sys_vfork_wrapper:
 	ldo	TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1	/* get pt regs */
 	reg_save %r1
+	mfctl	%cr27, %r3
+	STREG	%r3, PT_CR27(%r1)
 
 	STREG	%r2,-RP_OFFSET(%r30)
 	ldo	FRAME_SIZE(%r30),%r30
+#ifdef __LP64__
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#endif
 
-	STREG	%r30,PT_GR20(%r1)
-	ldil	L%child_return,%r3
-	ldo	R%child_return(%r3),%r3
-	LDIL_FIXUP(%r3)
-	STREG	%r3,PT_GR21(%r1)	/* save for child */
+	STREG	%r2,PT_GR19(%r1)	/* save for child */
+	STREG	%r30,PT_GR21(%r1)
 
 	bl	sys_vfork,%r2
 	copy	%r1,%r26
@@ -1567,6 +2079,9 @@
 
 	STREG %r2,-RP_OFFSET(%r30)
 	ldo FRAME_SIZE(%r30),%r30
+#ifdef __LP64__
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#endif
 	bl \execve,%r2
 	copy %r1,%arg0
 
@@ -1576,7 +2091,7 @@
 	/* If exec succeeded we need to load the args */
 
 	ldo -1024(%r0),%r1
-	comb,>>= %r28,%r1,error_\execve
+	cmpb,>>= %r28,%r1,error_\execve
 	copy %r2,%r19
 
 error_\execve:
@@ -1603,8 +2118,14 @@
 	ldo	TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30), %r26
 	/* Don't save regs, we are going to restore them from sigcontext. */
 	STREG	%r2, -RP_OFFSET(%r30)
+#ifdef __LP64__
+	ldo	FRAME_SIZE(%r30), %r30
+	bl	sys_rt_sigreturn,%r2
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#else
 	bl	sys_rt_sigreturn,%r2
 	ldo	FRAME_SIZE(%r30), %r30
+#endif
 
 	ldo	-FRAME_SIZE(%r30), %r30
 	LDREG	-RP_OFFSET(%r30), %r2
@@ -1625,22 +2146,50 @@
 	/* Get the user stack pointer */
 	LDREG	-TASK_SZ_ALGN-FRAME_SIZE+TASK_PT_GR30(%r30), %r24
 	STREG	%r2, -RP_OFFSET(%r30)
+#ifdef __LP64__
+	ldo	FRAME_SIZE(%r30), %r30
+	bl	do_sigaltstack,%r2
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#else
 	bl	do_sigaltstack,%r2
 	ldo	FRAME_SIZE(%r30), %r30
+#endif
 
 	ldo	-FRAME_SIZE(%r30), %r30
 	LDREG	-RP_OFFSET(%r30), %r2
 	bv	%r0(%r2)
 	nop
 
+#ifdef __LP64__
+	.export sys32_sigaltstack_wrapper
+sys32_sigaltstack_wrapper:
+	/* Get the user stack pointer */
+	LDREG	-TASK_SZ_ALGN-FRAME_SIZE+TASK_PT_GR30(%r30), %r24
+	STREG	%r2, -RP_OFFSET(%r30)
+	ldo	FRAME_SIZE(%r30), %r30
+	bl	do_sigaltstack32,%r2
+	ldo	-16(%r30),%r29		/* Reference param save area */
+
+	ldo	-FRAME_SIZE(%r30), %r30
+	LDREG	-RP_OFFSET(%r30), %r2
+	bv	%r0(%r2)
+	nop
+#endif
+
 	.export sys_rt_sigsuspend_wrapper
 sys_rt_sigsuspend_wrapper:
 	ldo	TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30), %r24
 	reg_save %r24
 
 	STREG	%r2, -RP_OFFSET(%r30)
+#ifdef __LP64__
+	ldo	FRAME_SIZE(%r30), %r30
+	bl	sys_rt_sigsuspend,%r2
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#else
 	bl	sys_rt_sigsuspend,%r2
 	ldo	FRAME_SIZE(%r30), %r30
+#endif
 
 	ldo	-FRAME_SIZE(%r30), %r30
 	LDREG	-RP_OFFSET(%r30), %r2
@@ -1658,66 +2207,80 @@
 	   values. */
 	/* NOTE: Not all syscalls exit this way.  rt_sigreturn will exit
 	 * via syscall_exit_rfi if the signal was received while the process
-	 * was running.  All traced processes will probably exit via
-	 * syscall_exit_rfi in the future.
+	 * was running.
 	 */
 
 	/* save return value now */
 
 	STREG     %r28,TASK_PT_GR28-TASK_SZ_ALGN-FRAME_SIZE(%r30)
 
+	/* Save other hpux returns if personality is PER_HPUX */
+
+#define PER_HPUX 0xe /* <linux/personality.h> cannot be easily included */
+
+	LDREG     TASK_PERSONALITY-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r19
+	CMPIB<>,n PER_HPUX,%r19,1f
+	STREG     %r22,TASK_PT_GR22-TASK_SZ_ALGN-FRAME_SIZE(%r30)
+	STREG     %r29,TASK_PT_GR29-TASK_SZ_ALGN-FRAME_SIZE(%r30)
+1:
+
+	/* Seems to me that dp could be wrong here, if the syscall involved
+	 * calling a module, and nothing got round to restoring dp on return.
+	 */
+	loadgp
+
 syscall_check_bh:
 
-/* #ifdef NOTNOW */
 	/* Check for software interrupts */
 
 	.import irq_stat,data
 
 	ldil    L%irq_stat,%r19
 	ldo     R%irq_stat(%r19),%r19
-	LDIL_FIXUP(%r19)
 
 #ifdef CONFIG_SMP
 	/* sched.h: int processor */
-	ldw     TASK_PROCESSOR-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r20 /* get cpu # */
-#if (IRQSTAT_SZ == 32)
-	dep     %r20,26,27,%r20 /* shift left 5 bits */
-#else
-#error IRQSTAT_SZ changed, fix dep
-#endif /* IRQSTAT_SZ */
-	add     %r19,%r20,%r19
-#endif /* CONFIG_SMP */
+	/* %r26 is used as scratch register to index into irq_stat[] */
+	ldw     TASK_PROCESSOR-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r26 /* cpu # */
 
-	ldw     IRQSTAT_SI_ACTIVE(%r19),%r20	/* hardirq.h: unsigned int */
-	ldw     IRQSTAT_SI_MASK(%r19),%r19	/* hardirq.h: unsigned int */
-	and     %r19,%r20,%r20
-	comib,<>,n 0,%r20,syscall_do_softirq /* forward */
-/* #endif */
+	/* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) bits */
+#ifdef __LP64__
+	shld	%r26, 6, %r20
+#else
+	shlw	%r26, 5, %r20
+#endif
+	add     %r19,%r20,%r19	/* now have &irq_stat[smp_processor_id()] */
+#endif /* CONFIG_SMP */
 
+	LDREG   IRQSTAT_SIRQ_PEND(%r19),%r20    /* hardirq.h: unsigned long */
+	cmpib,<>,n 0,%r20,syscall_do_softirq /* forward */
 
 syscall_check_resched:
 
 	/* check for reschedule */
 
 	LDREG  TASK_NEED_RESCHED-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r19	/* long */
-	comib,<>,n 0,%r19,syscall_do_resched /* forward */
+	CMPIB<>,n 0,%r19,syscall_do_resched /* forward */
 
 syscall_check_sig:
 	ldo     -TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1         /* get task ptr */
 	/* check for pending signals */
 	ldw     TASK_SIGPENDING(%r1),%r19
-	comib,<>,n 0,%r19,syscall_do_signal  /* forward */
+	cmpib,<>,n 0,%r19,syscall_do_signal  /* forward */
 
 syscall_restore:
-	/* disable interrupts while dicking with the kernel stack, */
-	/* or life can become unpleasant */
-	rsm	PSW_SM_I, %r20
 	LDREG	TASK_PTRACE(%r1), %r19		/* Are we being ptraced? */
 	bb,<,n	%r19,31,syscall_restore_rfi
-	LDREG	TASK_PT_GR20(%r1),%r19
-	mtctl	%r19, %cr27
+
+	ldo	TASK_PT_FR31(%r1),%r19		   /* reload fpregs */
+	rest_fp	%r19
+
+	LDREG	TASK_PT_SAR(%r1),%r19		   /* restore SAR */
+	mtsar	%r19
 
 	LDREG	TASK_PT_GR2(%r1),%r2		   /* restore user rp */
+	LDREG	TASK_PT_GR19(%r1),%r19
+	LDREG   TASK_PT_GR20(%r1),%r20
 	LDREG	TASK_PT_GR21(%r1),%r21
 	LDREG	TASK_PT_GR22(%r1),%r22
 	LDREG	TASK_PT_GR23(%r1),%r23
@@ -1727,43 +2290,31 @@
 	LDREG	TASK_PT_GR27(%r1),%r27	   /* restore user dp */
 	LDREG	TASK_PT_GR28(%r1),%r28	   /* syscall return value */
 	LDREG	TASK_PT_GR29(%r1),%r29
-	LDREG	TASK_PT_GR30(%r1),%r30	   /* restore user sp */
 	LDREG	TASK_PT_GR31(%r1),%r31	   /* restore syscall rp */
-	ldo	TASK_PT_FR31(%r1),%r19		   /* reload fpregs */
-	rest_fp	%r19
-	LDREG	TASK_PT_SAR(%r1),%r19		   /* restore SAR */
-	mtsar	%r19
-	LDREG	TASK_PT_GR19(%r1),%r19
 
-	mtctl	%r1,%cr30			   /* intrhandler okay. */
+	rsm     PSW_SM_I, %r0
+	LDREG   TASK_PT_GR30(%r1),%r30             /* restore user sp */
 	mfsp	%sr3,%r1			   /* Get users space id */
+	mtsp    %r1,%sr7                           /* Restore sr7 */
+	ssm     PSW_SM_I, %r0
 	mtsp	%r1,%sr4			   /* Restore sr4 */
 	mtsp	%r1,%sr5			   /* Restore sr5 */
 	mtsp	%r1,%sr6			   /* Restore sr6 */
 
 	depi	3,31,2,%r31			   /* ensure return to user mode. */
 
-	mtsm	%r20				   /* restore irq state  */
-	mfctl	%cr27,%r20
-	
-	/*
-	 * Due to a dependency in the tlb miss handlers on sr7, it
-	 * is essential that sr7 get set in the delay slot.
-	 */
-
 #ifdef __LP64__
-
-	/* Note the be (and mtsp) is executed in narrow mode. This is OK
-	 * for 32 bit processes, but won't work once we support 64 bit
-	 * processes.
+	/* Since we are returning to a 32 bit user process, we always
+	 * clear the W bit. This means that the be (and mtsp) gets
+	 * executed in narrow mode, but that is OK, since we are
+	 * returning to a 32 bit process. When we support 64 bit processes
+	 * we won't clear the W bit, so the be will run in wide mode.
 	 */
 
-	rsm	PSW_SM_W, %r0
 	be	0(%sr3,%r31)			   /* return to user space */
-	mtsp	%r1,%sr7			   /* Restore sr7 */
+	rsm	PSW_SM_W, %r0
 #else
-	be	0(%sr3,%r31)			   /* return to user space */
-	mtsp	%r1,%sr7			   /* Restore sr7 */
+	be,n    0(%sr3,%r31)                       /* return to user space */
 #endif
 
 	/* We have to return via an RFI, so that PSW T and R bits can be set
@@ -1774,43 +2325,52 @@
 syscall_restore_rfi:
 	ldo	-1(%r0),%r2			   /* Set recovery cntr to -1 */
 	mtctl	%r2,%cr0			   /*   for immediate trap */
-	copy	%r0,%r2				   /* Create a reasonable PSW */
+	LDREG	TASK_PT_PSW(%r1),%r2		   /* Get old PSW */
+	ldi	0x0b,%r20			   /* Create new PSW */
+	depi	-1,13,1,%r20			   /* C, Q, D, and I bits */
+	bb,>=,n	%r19,15,try_tbit		   /* PT_SINGLESTEP */
+	depi	-1,27,1,%r20			   /* R bit */
+try_tbit:
+	bb,>=,n	%r19,14,psw_setup		   /* PT_BLOCKSTEP, see ptrace.c */
+	depi	-1,7,1,%r20			   /* T bit */
+psw_setup:
+	STREG	%r20,TASK_PT_PSW(%r1)
+
+	/* Always store space registers, since sr3 can be changed (e.g. fork) */
+
+	mfsp    %sr3,%r25
+	STREG   %r25,TASK_PT_SR3(%r1)
+	STREG   %r25,TASK_PT_SR4(%r1)
+	STREG   %r25,TASK_PT_SR5(%r1)
+	STREG   %r25,TASK_PT_SR6(%r1)
+	STREG   %r25,TASK_PT_SR7(%r1)
+	STREG   %r25,TASK_PT_IASQ0(%r1)
+	STREG   %r25,TASK_PT_IASQ1(%r1)
+
 	/* XXX W bit??? */
-	depi	-1,13,1,%r2
-	depi	-1,28,1,%r2
-	depi	-1,30,1,%r2
-	depi	-1,31,1,%r2
-	bb,<,n	%r19,15,set_rbit		   /* PT_SINGLESTEP */
-	bb,>=,n	%r19,14,set_nobit		   /* PT_BLOCKSTEP, see ptrace.c */
-set_tbit:
-	depi	-1,7,1,%r2
-	b,n	set_nobit
-set_rbit:
-	depi	-1,27,1,%r2
-set_nobit:
-	STREG	%r2,TASK_PT_PSW(%r1)
-	STREG	%r1,TASK_PT_CR30(%r1)
+	/* Now if old D bit is clear, it means we didn't save all registers
+	 * on syscall entry, so do that now.  This only happens on TRACEME
+	 * calls, or if someone attached to us while we were on a syscall.
+	 * We could make this more efficient by not saving r3-r18, but
+	 * then we wouldn't be able to use the common intr_restore path.
+	 * It is only for traced processes anyway, so performance is not
+	 * an issue.
+	 */
+	bb,<	%r2,30,pt_regs_ok		   /* Branch if D set */
+	ldo	TASK_REGS(%r1),%r25
+	reg_save %r25				   /* Save r3 to r18 */
 	mfsp	%sr0,%r2
 	STREG	%r2,TASK_PT_SR0(%r1)
 	mfsp	%sr1,%r2
 	STREG	%r2,TASK_PT_SR1(%r1)
 	mfsp	%sr2,%r2
 	STREG	%r2,TASK_PT_SR2(%r1)
-	mfsp	%sr3,%r2
-	STREG	%r2,TASK_PT_SR3(%r1)
-	STREG	%r2,TASK_PT_SR4(%r1)
-	STREG	%r2,TASK_PT_SR5(%r1)
-	STREG	%r2,TASK_PT_SR6(%r1)
-	STREG	%r2,TASK_PT_SR7(%r1)
-	STREG	%r2,TASK_PT_IASQ0(%r1)
-	STREG	%r2,TASK_PT_IASQ1(%r1)
+pt_regs_ok:
 	LDREG	TASK_PT_GR31(%r1),%r2
 	depi	3,31,2,%r2			   /* ensure return to user mode. */
 	STREG	%r2,TASK_PT_IAOQ0(%r1)
 	ldo	4(%r2),%r2
 	STREG	%r2,TASK_PT_IAOQ1(%r1)
-	ldo	TASK_REGS(%r1),%r25
-	reg_save %r25				   /* Save r3 to r18 */
 	copy	%r25,%r16
 	b	intr_restore
 	nop
@@ -1825,7 +2385,11 @@
 	.import schedule,code
 syscall_do_resched:
 	bl	schedule,%r2
+#ifdef __LP64__
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#else
 	nop
+#endif
 	b       syscall_check_bh  /* if resched, we start over again */
 	nop
 
@@ -1840,6 +2404,9 @@
 
 	ldi	1, %r24				/* unsigned long in_syscall */
 
+#ifdef __LP64__
+	ldo	-16(%r30),%r29			/* Reference param save area */
+#endif
 	bl	do_signal,%r2
 	copy	%r0, %r26			/* sigset_t *oldset = NULL */
 
@@ -1849,19 +2416,155 @@
 
 	b,n     syscall_restore
 
-#ifdef __LP64__
-unimplemented_64bitirq:
-	ssm PSW_SM_Q+PSW_SM_I, %r0
-	/* indicate that we had an interrupt */
-	ldi	0x77, %r28
-	ldi	0x77, %r29
-	/* save interrupt registers in GRs for diagnosis */
-	mfctl %cr17, %r17
-	mfctl %cr18, %r18
-	mfctl %cr19, %r19
-	mfctl %cr20, %r20
-	mfctl %cr21, %r21
-	mfctl %cr22, %r22
-	b,n .
-	nop
-#endif
+	/*
+	 * get_register is used by the non access tlb miss handlers to
+	 * copy the value of the general register specified in r8 into
+	 * r1. This routine can't be used for shadowed registers, since
+	 * the rfir will restore the original value. So, for the shadowed
+	 * registers we put a -1 into r1 to indicate that the register
+	 * should not be used (the register being copied could also have
+	 * a -1 in it, but that is OK, it just means that we will have
+	 * to use the slow path instead).
+	 */
+
+get_register:
+	blr     %r8,%r0
+	nop
+	bv      %r0(%r25)    /* r0 */
+	copy    %r0,%r1
+	bv      %r0(%r25)    /* r1 - shadowed */
+	ldi     -1,%r1
+	bv      %r0(%r25)    /* r2 */
+	copy    %r2,%r1
+	bv      %r0(%r25)    /* r3 */
+	copy    %r3,%r1
+	bv      %r0(%r25)    /* r4 */
+	copy    %r4,%r1
+	bv      %r0(%r25)    /* r5 */
+	copy    %r5,%r1
+	bv      %r0(%r25)    /* r6 */
+	copy    %r6,%r1
+	bv      %r0(%r25)    /* r7 */
+	copy    %r7,%r1
+	bv      %r0(%r25)    /* r8 - shadowed */
+	ldi     -1,%r1
+	bv      %r0(%r25)    /* r9 - shadowed */
+	ldi     -1,%r1
+	bv      %r0(%r25)    /* r10 */
+	copy    %r10,%r1
+	bv      %r0(%r25)    /* r11 */
+	copy    %r11,%r1
+	bv      %r0(%r25)    /* r12 */
+	copy    %r12,%r1
+	bv      %r0(%r25)    /* r13 */
+	copy    %r13,%r1
+	bv      %r0(%r25)    /* r14 */
+	copy    %r14,%r1
+	bv      %r0(%r25)    /* r15 */
+	copy    %r15,%r1
+	bv      %r0(%r25)    /* r16 - shadowed */
+	ldi     -1,%r1
+	bv      %r0(%r25)    /* r17 - shadowed */
+	ldi     -1,%r1
+	bv      %r0(%r25)    /* r18 */
+	copy    %r18,%r1
+	bv      %r0(%r25)    /* r19 */
+	copy    %r19,%r1
+	bv      %r0(%r25)    /* r20 */
+	copy    %r20,%r1
+	bv      %r0(%r25)    /* r21 */
+	copy    %r21,%r1
+	bv      %r0(%r25)    /* r22 */
+	copy    %r22,%r1
+	bv      %r0(%r25)    /* r23 */
+	copy    %r23,%r1
+	bv      %r0(%r25)    /* r24 - shadowed */
+	ldi     -1,%r1
+	bv      %r0(%r25)    /* r25 - shadowed */
+	ldi     -1,%r1
+	bv      %r0(%r25)    /* r26 */
+	copy    %r26,%r1
+	bv      %r0(%r25)    /* r27 */
+	copy    %r27,%r1
+	bv      %r0(%r25)    /* r28 */
+	copy    %r28,%r1
+	bv      %r0(%r25)    /* r29 */
+	copy    %r29,%r1
+	bv      %r0(%r25)    /* r30 */
+	copy    %r30,%r1
+	bv      %r0(%r25)    /* r31 */
+	copy    %r31,%r1
+
+	/*
+	 * set_register is used by the non access tlb miss handlers to
+	 * copy the value of r1 into the general register specified in
+	 * r8.
+	 */
+
+set_register:
+	blr     %r8,%r0
+	nop
+	bv      %r0(%r25)    /* r0 (silly, but it is a place holder) */
+	copy    %r1,%r0
+	bv      %r0(%r25)    /* r1 */
+	copy    %r1,%r1
+	bv      %r0(%r25)    /* r2 */
+	copy    %r1,%r2
+	bv      %r0(%r25)    /* r3 */
+	copy    %r1,%r3
+	bv      %r0(%r25)    /* r4 */
+	copy    %r1,%r4
+	bv      %r0(%r25)    /* r5 */
+	copy    %r1,%r5
+	bv      %r0(%r25)    /* r6 */
+	copy    %r1,%r6
+	bv      %r0(%r25)    /* r7 */
+	copy    %r1,%r7
+	bv      %r0(%r25)    /* r8 */
+	copy    %r1,%r8
+	bv      %r0(%r25)    /* r9 */
+	copy    %r1,%r9
+	bv      %r0(%r25)    /* r10 */
+	copy    %r1,%r10
+	bv      %r0(%r25)    /* r11 */
+	copy    %r1,%r11
+	bv      %r0(%r25)    /* r12 */
+	copy    %r1,%r12
+	bv      %r0(%r25)    /* r13 */
+	copy    %r1,%r13
+	bv      %r0(%r25)    /* r14 */
+	copy    %r1,%r14
+	bv      %r0(%r25)    /* r15 */
+	copy    %r1,%r15
+	bv      %r0(%r25)    /* r16 */
+	copy    %r1,%r16
+	bv      %r0(%r25)    /* r17 */
+	copy    %r1,%r17
+	bv      %r0(%r25)    /* r18 */
+	copy    %r1,%r18
+	bv      %r0(%r25)    /* r19 */
+	copy    %r1,%r19
+	bv      %r0(%r25)    /* r20 */
+	copy    %r1,%r20
+	bv      %r0(%r25)    /* r21 */
+	copy    %r1,%r21
+	bv      %r0(%r25)    /* r22 */
+	copy    %r1,%r22
+	bv      %r0(%r25)    /* r23 */
+	copy    %r1,%r23
+	bv      %r0(%r25)    /* r24 */
+	copy    %r1,%r24
+	bv      %r0(%r25)    /* r25 */
+	copy    %r1,%r25
+	bv      %r0(%r25)    /* r26 */
+	copy    %r1,%r26
+	bv      %r0(%r25)    /* r27 */
+	copy    %r1,%r27
+	bv      %r0(%r25)    /* r28 */
+	copy    %r1,%r28
+	bv      %r0(%r25)    /* r29 */
+	copy    %r1,%r29
+	bv      %r0(%r25)    /* r30 */
+	copy    %r1,%r30
+	bv      %r0(%r25)    /* r31 */
+	copy    %r1,%r31
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/firmware.c linux-bk/arch/parisc/kernel/firmware.c
--- linux-2.4.19/arch/parisc/kernel/firmware.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/parisc/kernel/firmware.c	2002-08-17 00:48:59.000000000 +0000
@@ -0,0 +1,1111 @@
+/* arch/parisc/kernel/pdc.c  - safe pdc access routines
+ *
+ * Copyright 1999 SuSE GmbH Nuernberg (Philipp Rumpf, prumpf@tux.org)
+ * portions Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy)
+ *
+ * only these routines should be used out of the real kernel (i.e. everything
+ * using virtual addresses) for obvious reasons */
+
+/*	I think it would be in everyone's best interest to follow this
+ *	guidelines when writing PDC wrappers:
+ *
+ *	 - the name of the pdc wrapper should match one of the macros
+ *	   used for the first two arguments
+ *	 - don't use caps for random parts of the name
+ *	 - use the static PDC result buffers and "copyout" to structs
+ *	   supplied by the caller to encapsulate alignment restrictions
+ *	 - hold pdc_lock while in PDC or using static result buffers
+ *	 - use __pa() to convert virtual (kernel) pointers to physical
+ *	   ones.
+ *	 - the name of the struct used for pdc return values should equal
+ *	   one of the macros used for the first two arguments to the
+ *	   corresponding PDC call
+ *	 - keep the order of arguments
+ *	 - don't be smart (setting trailing NUL bytes for strings, return
+ *	   something useful even if the call failed) unless you are sure
+ *	   it's not going to affect functionality or performance
+ *
+ *	Example:
+ *	int pdc_cache_info(struct pdc_cache_info *cache_info )
+ *	{
+ *		int retval;
+ *
+ *		spin_lock_irq(&pdc_lock);
+ *		retval = mem_pdc_call(PDC_CACHE,PDC_CACHE_INFO,__pa(cache_info),0);
+ *		convert_to_wide(pdc_result);
+ *		memcpy(cache_info, pdc_result, sizeof(*cache_info));
+ *		spin_unlock_irq(&pdc_lock);
+ *
+ *		return retval;
+ *	}
+ *					prumpf	991016	
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include <asm/page.h>
+#include <asm/pdc.h>
+#include <asm/system.h>
+#include <asm/processor.h>	/* for boot_cpu_data */
+
+#include <stdarg.h>
+
+static spinlock_t pdc_lock = SPIN_LOCK_UNLOCKED;
+static unsigned long pdc_result[32] __attribute__ ((aligned (8)));
+static unsigned long pdc_result2[32] __attribute__ ((aligned (8)));
+
+/* on all currently-supported platforms, IODC I/O calls are always
+ * 32-bit calls, and MEM_PDC calls are always the same width as the OS.
+ * This means Cxxx boxes can't run wide kernels right now. -PB
+ *
+ * CONFIG_PDC_NARROW has been added to allow 64-bit kernels to run on
+ * systems with 32-bit MEM_PDC calls. This will allow wide kernels to
+ * run on Cxxx boxes now. -RB
+ *
+ * Note that some PAT boxes may have 64-bit IODC I/O...
+ */
+
+#ifdef __LP64__
+static long real64_call(unsigned long function, ...);
+#endif
+static long real32_call(unsigned long function, ...);
+
+#if defined(__LP64__) && ! defined(CONFIG_PDC_NARROW)
+#define MEM_PDC (unsigned long)(PAGE0->mem_pdc_hi) << 32 | PAGE0->mem_pdc
+#   define mem_pdc_call(args...) real64_call(MEM_PDC, args)
+#else
+#define MEM_PDC (unsigned long)PAGE0->mem_pdc
+#   define mem_pdc_call(args...) real32_call(MEM_PDC, args)
+#endif
+
+
+/**
+ * f_extend - Convert PDC addresses to kernel addresses.
+ * @address: Address returned from PDC.
+ *
+ * This function is used to convert PDC addresses into kernel addresses
+ * when the PDC address size and kernel address size are different.
+ */
+static unsigned long f_extend(unsigned long address)
+{
+#ifdef CONFIG_PDC_NARROW
+	if((address & 0xff000000) == 0xf0000000)
+		return 0xf0f0f0f000000000 | (u32)address;
+
+	if((address & 0xf0000000) == 0xf0000000)
+		return 0xffffffff00000000 | (u32)address;
+#endif
+	return address;
+}
+
+/**
+ * convert_to_wide - Convert the return buffer addresses into kernel addresses.
+ * @address: The return buffer from PDC.
+ *
+ * This function is used to convert the return buffer addresses retrieved from PDC
+ * into kernel addresses when the PDC address size and kernel address size are
+ * different.
+ */
+static void convert_to_wide(unsigned long *addr)
+{
+#ifdef CONFIG_PDC_NARROW
+	int i;
+	unsigned *p = (unsigned int *)addr;
+	for(i = 31; i >= 0; --i)
+		addr[i] = p[i];
+#endif
+}
+
+/**
+ * pdc_emergency_unlock - Unlock the linux pdc lock
+ *
+ * This call unlocks the linux pdc lock in case we need some PDC functions
+ * (like pdc_add_valid) during kernel stack dump.
+ */
+void pdc_emergency_unlock(void)
+{
+        spin_unlock(&pdc_lock);
+}
+
+
+/**
+ * pdc_add_valid - Verify address can be accessed without causing a HPMC.
+ * @address: Address to be verified.
+ *
+ * This PDC call attempts to read from the specified address and verifies
+ * if the address is valid.
+ * 
+ * The return value is PDC_OK (0) in case accessing this address is valid.
+ */
+int pdc_add_valid(unsigned long address)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        retval = mem_pdc_call(PDC_ADD_VALID, PDC_ADD_VALID_VERIFY, address);
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+/**
+ * pdc_chassis_info - Return chassis information.
+ * @result: The return buffer.
+ * @chassis_info: The memory buffer address.
+ * @len: The size of the memory buffer address.
+ *
+ * An HVERSION dependent call for returning the chassis information.
+ */
+int __init pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        memcpy(&pdc_result, chassis_info, sizeof(*chassis_info));
+        memcpy(&pdc_result2, led_info, len);
+        retval = mem_pdc_call(PDC_CHASSIS, PDC_RETURN_CHASSIS_INFO,
+                              __pa(pdc_result), __pa(pdc_result2), len);
+        memcpy(chassis_info, pdc_result, sizeof(*chassis_info));
+        memcpy(led_info, pdc_result2, len);
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+/**
+ * pdc_coproc_cfg - To identify coprocessors attached to the processor.
+ * @pdc_coproc_info: Return buffer address.
+ *
+ * This PDC call returns the presence and status of all the coprocessors
+ * attached to the processor.
+ */
+int __init pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        retval = mem_pdc_call(PDC_COPROC, PDC_COPROC_CFG, __pa(pdc_result));
+        convert_to_wide(pdc_result);
+        pdc_coproc_info->ccr_functional = pdc_result[0];
+        pdc_coproc_info->ccr_present = pdc_result[1];
+        pdc_coproc_info->revision = pdc_result[17];
+        pdc_coproc_info->model = pdc_result[18];
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+/**
+ * pdc_iodc_read - Read data from the modules IODC.
+ * @actcnt: The actual number of bytes.
+ * @hpa: The HPA of the module for the iodc read.
+ * @index: The iodc entry point.
+ * @iodc_data: A buffer memory for the iodc options.
+ * @iodc_data_size: Size of the memory buffer.
+ *
+ * This PDC call reads from the IODC of the module specified by the hpa
+ * argument.
+ */
+int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index,
+		  void *iodc_data, unsigned int iodc_data_size)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_IODC, PDC_IODC_READ, __pa(pdc_result), hpa, 
+			      index, __pa(pdc_result2), iodc_data_size);
+	convert_to_wide(pdc_result);
+	*actcnt = pdc_result[0];
+	memcpy(iodc_data, pdc_result2, iodc_data_size);
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+
+/**
+ * pdc_system_map_find_mods - Locate unarchitected modules.
+ * @pdc_mod_info: Return buffer address.
+ * @mod_path: pointer to dev path structure.
+ * @mod_index: fixed address module index.
+ *
+ * To locate and identify modules which reside at fixed I/O addresses, which
+ * do not self-identify via architected bus walks.
+ */
+int pdc_system_map_find_mods(struct pdc_system_map_mod_info *pdc_mod_info,
+			     struct pdc_module_path *mod_path, long mod_index)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_MODULE, __pa(pdc_result), 
+			      __pa(pdc_result2), mod_index);
+	convert_to_wide(pdc_result);
+	memcpy(pdc_mod_info, pdc_result, sizeof(*pdc_mod_info));
+	memcpy(mod_path, pdc_result2, sizeof(*mod_path));
+	spin_unlock_irq(&pdc_lock);
+
+	pdc_mod_info->mod_addr = f_extend(pdc_mod_info->mod_addr);
+	return retval;
+}
+
+/**
+ * pdc_system_map_find_addrs - Retrieve additional address ranges.
+ * @pdc_addr_info: Return buffer address.
+ * @mod_index: Fixed address module index.
+ * @addr_index: Address range index.
+ * 
+ * Retrieve additional information about subsequent address ranges for modules
+ * with multiple address ranges.  
+ */
+int pdc_system_map_find_addrs(struct pdc_system_map_addr_info *pdc_addr_info, 
+			      long mod_index, long addr_index)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_ADDRESS, __pa(pdc_result),
+			      mod_index, addr_index);
+	convert_to_wide(pdc_result);
+	memcpy(pdc_addr_info, pdc_result, sizeof(*pdc_addr_info));
+	spin_unlock_irq(&pdc_lock);
+
+	pdc_addr_info->mod_addr = f_extend(pdc_addr_info->mod_addr);
+	return retval;
+}
+
+/**
+ * pdc_model_info - Return model information about the processor.
+ * @model: The return buffer.
+ *
+ * Returns the version numbers, identifiers, and capabilities from the processor module.
+ */
+int pdc_model_info(struct pdc_model *model) 
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_INFO, __pa(pdc_result), 0);
+	convert_to_wide(pdc_result);
+	memcpy(model, pdc_result, sizeof(*model));
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+
+/**
+ * pdc_model_sysmodel - Get the system model name.
+ * @name: A char array of at least 81 characters.
+ *
+ * Get system model name from PDC ROM (e.g. 9000/715 or 9000/778/B160L)
+ */
+int pdc_model_sysmodel(char *name)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_SYSMODEL, __pa(pdc_result),
+                              OS_ID_HPUX, __pa(name));
+        convert_to_wide(pdc_result);
+
+        if (retval == PDC_OK) {
+                name[pdc_result[0]] = '\0'; /* add trailing '\0' */
+        } else {
+                name[0] = 0;
+        }
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+/**
+ * pdc_model_versions - Identify the version number of each processor.
+ * @cpu_id: The return buffer.
+ * @id: The id of the processor to check.
+ *
+ * Returns the version number for each processor component.
+ *
+ * This comment was here before, but I do not know what it means :( -RB
+ * id: 0 = cpu revision, 1 = boot-rom-version
+ */
+int pdc_model_versions(unsigned long *versions, int id)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_VERSIONS, __pa(pdc_result), id);
+        convert_to_wide(pdc_result);
+        *versions = pdc_result[0];
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+/**
+ * pdc_model_cpuid - Returns the CPU_ID.
+ * @cpu_id: The return buffer.
+ *
+ * Returns the CPU_ID value which uniquely identifies the cpu portion of
+ * the processor module.
+ */
+int pdc_model_cpuid(unsigned long *cpu_id)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        pdc_result[0] = 0; /* preset zero (call may not be implemented!) */
+        retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CPU_ID, __pa(pdc_result), 0);
+        convert_to_wide(pdc_result);
+        *cpu_id = pdc_result[0];
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+/**
+ * pdc_model_capabilities - Returns the platform capabilities.
+ * @capabilities: The return buffer.
+ *
+ * Returns information about platform support for 32- and/or 64-bit
+ * OSes, IO-PDIR coherency, and virtual aliasing.
+ */
+int pdc_model_capabilities(unsigned long *capabilities)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        pdc_result[0] = 0; /* preset zero (call may not be implemented!) */
+        retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES, __pa(pdc_result), 0);
+        convert_to_wide(pdc_result);
+        *capabilities = pdc_result[0];
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+/**
+ * pdc_cache_info - Return cache and TLB information.
+ * @cache_info: The return buffer.
+ *
+ * Returns information about the processor's cache and TLB.
+ */
+int pdc_cache_info(struct pdc_cache_info *cache_info)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        retval = mem_pdc_call(PDC_CACHE, PDC_CACHE_INFO, __pa(pdc_result), 0);
+        convert_to_wide(pdc_result);
+        memcpy(cache_info, pdc_result, sizeof(*cache_info));
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+#ifndef CONFIG_PA20
+/**
+ * pdc_btlb_info - Return block TLB information.
+ * @btlb: The return buffer.
+ *
+ * Returns information about the hardware Block TLB.
+ */
+int pdc_btlb_info(struct pdc_btlb_info *btlb) 
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        retval = mem_pdc_call(PDC_BLOCK_TLB, PDC_BTLB_INFO, __pa(pdc_result), 0);
+        memcpy(btlb, pdc_result, sizeof(*btlb));
+        spin_unlock_irq(&pdc_lock);
+
+        if(retval < 0) {
+                btlb->max_size = 0;
+        }
+        return retval;
+}
+
+/**
+ * pdc_mem_map_hpa - Find fixed module information.  
+ * @address: The return buffer
+ * @mod_path: pointer to dev path structure.
+ *
+ * This call was developed for S700 workstations to allow the kernel to find
+ * the I/O devices (Core I/O). In the future (Kittyhawk and beyond) this
+ * call will be replaced (on workstations) by the architected PDC_SYSTEM_MAP
+ * call.
+ *
+ * This call is supported by all existing S700 workstations (up to  Gecko).
+ */
+int pdc_mem_map_hpa(struct pdc_memory_map *address,
+		struct pdc_module_path *mod_path)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        memcpy(pdc_result2, mod_path, sizeof(*mod_path));
+        retval = mem_pdc_call(PDC_MEM_MAP, PDC_MEM_MAP_HPA, __pa(pdc_result),
+				__pa(pdc_result2));
+        memcpy(address, pdc_result, sizeof(*address));
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+#endif	/* !CONFIG_PA20 */
+
+/**
+ * pdc_lan_station_id - Get the LAN address.
+ * @lan_addr: The return buffer.
+ * @hpa: The network device HPA.
+ *
+ * Get the LAN station address when it is not directly available from the LAN hardware.
+ */
+int pdc_lan_station_id(char *lan_addr, unsigned long hpa)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_LAN_STATION_ID, PDC_LAN_STATION_ID_READ,
+			__pa(pdc_result), hpa);
+	if (retval < 0) {
+		/* FIXME: else read MAC from NVRAM */
+		memset(lan_addr, 0, PDC_LAN_STATION_ID_SIZE);
+	} else {
+		memcpy(lan_addr, pdc_result, PDC_LAN_STATION_ID_SIZE);
+	}
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+
+
+/**
+ * pdc_get_initiator - Get the SCSI Interface Card params (SCSI ID, SDTR, SE or LVD)
+ * @hwpath: fully bc.mod style path to the device.
+ * @scsi_id: what someone told firmware the ID should be.
+ * @period: time in cycles 
+ * @width: 8 or 16-bit wide bus
+ * @mode: 0,1,2 -> SE,HVD,LVD signalling mode
+ *
+ * Get the SCSI operational parameters from PDC.
+ * Needed since HPUX never used BIOS or symbios card NVRAM.
+ * Most ncr/sym cards won't have an entry and just use whatever
+ * capabilities of the card are (eg Ultra, LVD). But there are
+ * several cases where it's useful:
+ *    o set SCSI id for Multi-initiator clusters,
+ *    o cable too long (ie SE scsi 10Mhz won't support 6m length),
+ *    o bus width exported is less than what the interface chip supports.
+ */
+int pdc_get_initiator( struct hardware_path *hwpath, unsigned char *scsi_id,
+	unsigned long *period, char *width, char *mode)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+
+/* BCJ-XXXX series boxes. E.G. "9000/785/C3000" */
+#define IS_SPROCKETS() (strlen(boot_cpu_data.pdc.sys_model_name) == 14 && \
+	strncmp(boot_cpu_data.pdc.sys_model_name, "9000/785", 9) == 0)
+
+	retval = mem_pdc_call(PDC_INITIATOR, PDC_GET_INITIATOR, 
+			      __pa(pdc_result), __pa(hwpath));
+
+
+	if (retval >= PDC_OK) {
+		*scsi_id = (unsigned char) pdc_result[0];
+
+		/* convert Bus speed in Mhz to period (in 1/10 ns) */
+		switch(pdc_result[1]) {
+		/*
+		** case  0:   driver determines rate
+		** case -1:   Settings are uninitialized.
+		*/
+		case  5:  *period = 2000; break;
+		case 10:  *period = 1000; break;
+		case 20:  *period = 500; break;
+		case 40:  *period = 250; break;
+		default: /* Do nothing */ break;
+		}
+
+		/* 
+		** pdc_result[2]	PDC suggested SCSI id
+		** pdc_result[3]	PDC suggested SCSI rate
+		*/
+
+		if (IS_SPROCKETS()) {
+			/*
+			** Revisit: PAT PDC do the same thing?
+			** A500 also exports 50-pin SE SCSI.
+			**	0 == 8-bit
+			**	1 == 16-bit
+			*/
+			*width = (char) pdc_result[4];
+
+			/* ...in case someone needs it in the future.
+			** sym53c8xx.c comments say it can't autodetect
+			** for 825/825A/875 chips.
+			**	0 == SE, 1 == HVD, 2 == LVD
+			*/
+			*mode = (char) pdc_result[5]; 
+		}
+	}
+
+	spin_unlock_irq(&pdc_lock);
+	return retval >= PDC_OK;
+}
+
+
+/**
+ * pdc_pci_irt_size - Get the number of entries in the interrupt routing table.
+ * @num_entries: The return value.
+ * @hpa: The HPA for the device.
+ *
+ * This PDC function returns the number of entries in the specified cell's
+ * interrupt table.
+ * Similar to PDC_PAT stuff - but added for Forte/Allegro boxes
+ */ 
+int pdc_pci_irt_size(unsigned long *num_entries, unsigned long hpa)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL_SIZE, 
+			      __pa(pdc_result), hpa);
+	convert_to_wide(pdc_result);
+	*num_entries = pdc_result[0];
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+
+/** 
+ * pdc_pci_irt - Get the PCI interrupt routing table.
+ * @num_entries: The number of entries in the table.
+ * @hpa: The Hard Physical Address of the device.
+ * @tbl: 
+ *
+ * Get the PCI interrupt routing table for the device at the given HPA.
+ * Similar to PDC_PAT stuff - but added for Forte/Allegro boxes
+ */
+int pdc_pci_irt(unsigned long num_entries, unsigned long hpa, void *tbl)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	pdc_result[0] = num_entries;
+	retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL, 
+			      __pa(pdc_result), hpa, __pa(tbl));
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+
+
+/**
+ * pdc_tod_read - Read the Time-Of-Day clock.
+ * @tod: The return buffer:
+ *
+ * Read the Time-Of-Day clock
+ */
+int pdc_tod_read(struct pdc_tod *tod)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        retval = mem_pdc_call(PDC_TOD, PDC_TOD_READ, __pa(pdc_result), 0);
+        convert_to_wide(pdc_result);
+        memcpy(tod, pdc_result, sizeof(*tod));
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+/**
+ * pdc_tod_set - Set the Time-Of-Day clock.
+ * @sec: The number of seconds since epoch.
+ * @usec: The number of micro seconds.
+ *
+ * Set the Time-Of-Day clock.
+ */ 
+int pdc_tod_set(unsigned long sec, unsigned long usec)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        retval = mem_pdc_call(PDC_TOD, PDC_TOD_WRITE, sec, usec);
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+#ifdef __LP64__
+int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr,
+		struct pdc_memory_table *tbl, unsigned long entries)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_MEM, PDC_MEM_TABLE, __pa(pdc_result), __pa(pdc_result2), entries);
+	convert_to_wide(pdc_result);
+	memcpy(r_addr, pdc_result, sizeof(*r_addr));
+	memcpy(tbl, pdc_result2, entries * sizeof(*tbl));
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+#endif /* __LP64__ */
+
+/* FIXME: Is this pdc used?  I could not find type reference to ftc_bitmap
+ * so I guessed at unsigned long.  Someone who knows what this does, can fix
+ * it later. :)
+ */
+int pdc_do_firm_test_reset(unsigned long ftc_bitmap)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        retval = mem_pdc_call(PDC_BROADCAST_RESET, PDC_DO_FIRM_TEST_RESET,
+                              PDC_FIRM_TEST_MAGIC, ftc_bitmap);
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+/*
+ * pdc_do_reset - Reset the system.
+ *
+ * Reset the system.
+ */
+int pdc_do_reset()
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        retval = mem_pdc_call(PDC_BROADCAST_RESET, PDC_DO_RESET);
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+/*
+ * pdc_soft_power_info - Enable soft power switch.
+ * @power_reg: address of soft power register
+ *
+ * Return the absolute address of the soft power switch register
+ */
+int __init pdc_soft_power_info(unsigned long *power_reg)
+{
+	int retval;
+
+	*power_reg = (unsigned long) (-1);
+	
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_SOFT_POWER, PDC_SOFT_POWER_INFO, __pa(pdc_result), 0);
+	if (retval == PDC_OK) {
+                convert_to_wide(pdc_result);
+                *power_reg = f_extend(pdc_result[0]);
+	}
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+
+/*
+ * pdc_soft_power_button - Control the soft power button behaviour
+ * @sw_control: 0 for hardware control, 1 for software control 
+ *
+ *
+ * This PDC function places the soft power button under software or
+ * hardware control.
+ * Under software control the OS may control to when to allow to shut 
+ * down the system. Under hardware control pressing the power button 
+ * powers off the system immediately.
+ */
+int pdc_soft_power_button(int sw_control)
+{
+	int retval;
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_SOFT_POWER, PDC_SOFT_POWER_ENABLE, __pa(pdc_result), sw_control);
+	spin_unlock_irq(&pdc_lock);
+	return retval;
+}
+
+/*
+ * pdc_suspend_usb - Stop USB controller
+ *
+ * If PDC used the usb controller, the usb controller
+ * is still running and will crash the machines during iommu 
+ * setup, because of still running DMA. This PDC call
+ * stops the USB controller
+ */
+void pdc_suspend_usb(void)
+{
+	spin_lock_irq(&pdc_lock);  
+	mem_pdc_call(PDC_IO, PDC_IO_SUSPEND_USB, 0);
+	spin_unlock_irq(&pdc_lock);
+}
+
+/**
+ * pdc_iodc_putc - Console character print using IODC.
+ * @c: the character to output.
+ *
+ * Note that only these special chars are architected for console IODC io:
+ * BEL, BS, CR, and LF. Others are passed through.
+ * Since the HP console requires CR+LF to perform a 'newline', we translate
+ * "\n" to "\r\n".
+ */
+void pdc_iodc_putc(unsigned char c)
+{
+        /* XXX Should we spinlock posx usage */
+        static int posx;        /* for simple TAB-Simulation... */
+        static int __attribute__((aligned(8)))   iodc_retbuf[32];
+        static char __attribute__((aligned(64))) iodc_dbuf[4096];
+        unsigned int n;
+	unsigned int flags;
+
+        switch (c) {
+        case '\n':
+                iodc_dbuf[0] = '\r';
+                iodc_dbuf[1] = '\n';
+                n = 2;
+                posx = 0;
+                break;
+        case '\t':
+                pdc_iodc_putc(' ');
+                while (posx & 7)        /* expand TAB */
+                        pdc_iodc_putc(' ');
+                return;         /* return since IODC can't handle this */
+        case '\b':
+                posx-=2;                /* BS */
+        default:
+                iodc_dbuf[0] = c;
+                n = 1;
+                posx++;
+                break;
+        }
+
+        spin_lock_irqsave(&pdc_lock, flags);
+        real32_call(PAGE0->mem_cons.iodc_io,
+                    (unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT,
+                    PAGE0->mem_cons.spa, __pa(PAGE0->mem_cons.dp.layers),
+                    __pa(iodc_retbuf), 0, __pa(iodc_dbuf), n, 0);
+        spin_unlock_irqrestore(&pdc_lock, flags);
+}
+
+/**
+ * pdc_iodc_outc - Console character print using IODC (without conversions).
+ * @c: the character to output.
+ *
+ * Write the character directly to the IODC console.
+ */
+void pdc_iodc_outc(unsigned char c)
+{
+	unsigned int n, flags;
+
+	/* fill buffer with one caracter and print it */
+        static int __attribute__((aligned(8)))   iodc_retbuf[32];
+        static char __attribute__((aligned(64))) iodc_dbuf[4096];
+
+	n = 1;
+	iodc_dbuf[0] = c;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	real32_call(PAGE0->mem_cons.iodc_io,
+		    (unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT,
+		    PAGE0->mem_cons.spa, __pa(PAGE0->mem_cons.dp.layers),
+		    __pa(iodc_retbuf), 0, __pa(iodc_dbuf), n, 0);
+	spin_unlock_irqrestore(&pdc_lock, flags);
+}
+
+/**
+ * pdc_iodc_getc - Read a character (non-blocking) from the PDC console.
+ *
+ * Read a character (non-blocking) from the PDC console, returns -1 if
+ * key is not present.
+ */
+int pdc_iodc_getc(void)
+{
+	unsigned int flags;
+        static int __attribute__((aligned(8)))   iodc_retbuf[32];
+        static char __attribute__((aligned(64))) iodc_dbuf[4096];
+	int ch;
+	int status;
+
+	/* Bail if no console input device. */
+	if (!PAGE0->mem_kbd.iodc_io)
+		return 0;
+	
+	/* wait for a keyboard (rs232)-input */
+	spin_lock_irqsave(&pdc_lock, flags);
+	real32_call(PAGE0->mem_kbd.iodc_io,
+		    (unsigned long)PAGE0->mem_kbd.hpa, ENTRY_IO_CIN,
+		    PAGE0->mem_kbd.spa, __pa(PAGE0->mem_kbd.dp.layers), 
+		    __pa(iodc_retbuf), 0, __pa(iodc_dbuf), 1, 0);
+
+	ch = *iodc_dbuf;
+	status = *iodc_retbuf;
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	if (status == 0)
+	    return -1;
+	
+	return ch;
+}
+
+int pdc_sti_call(unsigned long func, unsigned long flags,
+                 unsigned long inptr, unsigned long outputr,
+                 unsigned long glob_cfg)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);  
+        retval = real32_call(func, flags, inptr, outputr, glob_cfg);
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+#ifdef __LP64__
+/**
+ * pdc_pat_cell_get_number - Returns the cell number.
+ * @cell_info: The return buffer.
+ *
+ * This PDC call returns the cell number of the cell from which the call
+ * is made.
+ */
+int pdc_pat_cell_get_number(struct pdc_pat_cell_num *cell_info)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_PAT_CELL, PDC_PAT_CELL_GET_NUMBER, __pa(pdc_result));
+	memcpy(cell_info, pdc_result, sizeof(*cell_info));
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+
+/**
+ * pdc_pat_cell_module - Retrieve the cell's module information.
+ * @actcnt: The number of bytes written to mem_addr.
+ * @ploc: The physical location.
+ * @mod: The module index.
+ * @view_type: The view of the address type.
+ * @mem_addr: The return buffer.
+ *
+ * This PDC call returns information about each module attached to the cell
+ * at the specified location.
+ */
+int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, unsigned long mod,
+			unsigned long view_type, void *mem_addr)
+{
+	int retval;
+	static struct pdc_pat_cell_mod_maddr_block result __attribute__ ((aligned (8)));
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_PAT_CELL, PDC_PAT_CELL_MODULE, __pa(pdc_result), 
+			      ploc, mod, view_type, __pa(&result));
+	if(!retval) {
+		*actcnt = pdc_result[0];
+		memcpy(mem_addr, &result, *actcnt);
+	}
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+
+/**
+ * pdc_pat_cpu_get_number - Retrieve the cpu number.
+ * @cpu_info: The return buffer.
+ * @hpa: The Hard Physical Address of the CPU.
+ *
+ * Retrieve the cpu number for the cpu at the specified HPA.
+ */
+int pdc_pat_cpu_get_number(struct pdc_pat_cpu_num *cpu_info, void *hpa)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_PAT_CPU, PDC_PAT_CPU_GET_NUMBER,
+			      __pa(&pdc_result), hpa);
+	memcpy(cpu_info, pdc_result, sizeof(*cpu_info));
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+
+/**
+ * pdc_pat_get_irt_size - Retrieve the number of entries in the cell's interrupt table.
+ * @num_entries: The return value.
+ * @cell_num: The target cell.
+ *
+ * This PDC function returns the number of entries in the specified cell's
+ * interrupt table.
+ */
+int pdc_pat_get_irt_size(unsigned long *num_entries, unsigned long cell_num)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_GET_PCI_ROUTING_TABLE_SIZE,
+			      __pa(pdc_result), cell_num);
+	*num_entries = pdc_result[0];
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+
+/**
+ * pdc_pat_get_irt - Retrieve the cell's interrupt table.
+ * @r_addr: The return buffer.
+ * @cell_num: The target cell.
+ *
+ * This PDC function returns the actual interrupt table for the specified cell.
+ */
+int pdc_pat_get_irt(void *r_addr, unsigned long cell_num)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_GET_PCI_ROUTING_TABLE,
+			      __pa(r_addr), cell_num);
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+
+/**
+ * pdc_pat_pd_get_addr_map - Retrieve information about memory address ranges.
+ * @actlen: The return buffer.
+ * @mem_addr: Pointer to the memory buffer.
+ * @count: The number of bytes to read from the buffer.
+ * @offset: The offset with respect to the beginning of the buffer.
+ *
+ */
+int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr, 
+			    unsigned long count, unsigned long offset)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_PAT_PD, PDC_PAT_PD_GET_ADDR_MAP, __pa(pdc_result), 
+			      __pa(pdc_result2), count, offset);
+	*actual_len = pdc_result[0];
+	memcpy(mem_addr, pdc_result2, *actual_len);
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+#endif /* __LP64__ */
+
+
+/***************** 32-bit real-mode calls ***********/
+/* The struct below is used
+ * to overlay real_stack (real2.S), preparing a 32-bit call frame.
+ * real32_call_asm() then uses this stack in narrow real mode
+ */
+
+struct narrow_stack {
+	/* use int, not long which is 64 bits */
+	unsigned int arg13;
+	unsigned int arg12;
+	unsigned int arg11;
+	unsigned int arg10;
+	unsigned int arg9;
+	unsigned int arg8;
+	unsigned int arg7;
+	unsigned int arg6;
+	unsigned int arg5;
+	unsigned int arg4;
+	unsigned int arg3;
+	unsigned int arg2;
+	unsigned int arg1;
+	unsigned int arg0;
+	unsigned int frame_marker[8];
+	unsigned int sp;
+	/* in reality, there's nearly 8k of stack after this */
+};
+
+static long real32_call(unsigned long fn, ...)
+{
+	va_list args;
+	extern struct narrow_stack real_stack;
+	extern unsigned long real32_call_asm(unsigned int *,
+					     unsigned int *, 
+					     unsigned int);
+	
+	va_start(args, fn);
+	real_stack.arg0 = va_arg(args, unsigned int);
+	real_stack.arg1 = va_arg(args, unsigned int);
+	real_stack.arg2 = va_arg(args, unsigned int);
+	real_stack.arg3 = va_arg(args, unsigned int);
+	real_stack.arg4 = va_arg(args, unsigned int);
+	real_stack.arg5 = va_arg(args, unsigned int);
+	real_stack.arg6 = va_arg(args, unsigned int);
+	real_stack.arg7 = va_arg(args, unsigned int);
+	real_stack.arg8 = va_arg(args, unsigned int);
+	real_stack.arg9 = va_arg(args, unsigned int);
+	real_stack.arg10 = va_arg(args, unsigned int);
+	real_stack.arg11 = va_arg(args, unsigned int);
+	real_stack.arg12 = va_arg(args, unsigned int);
+	real_stack.arg13 = va_arg(args, unsigned int);
+	va_end(args);
+	
+	return real32_call_asm(&real_stack.sp, &real_stack.arg0, fn);
+}
+
+#ifdef __LP64__
+/***************** 64-bit real-mode calls ***********/
+
+struct wide_stack {
+	unsigned long arg0;
+	unsigned long arg1;
+	unsigned long arg2;
+	unsigned long arg3;
+	unsigned long arg4;
+	unsigned long arg5;
+	unsigned long arg6;
+	unsigned long arg7;
+	unsigned long arg8;
+	unsigned long arg9;
+	unsigned long arg10;
+	unsigned long arg11;
+	unsigned long arg12;
+	unsigned long arg13;
+	unsigned long frame_marker[2];	/* rp, previous sp */
+	unsigned long sp;
+	/* in reality, there's nearly 8k of stack after this */
+};
+
+static long real64_call(unsigned long fn, ...)
+{
+	va_list args;
+	extern struct wide_stack real_stack;
+	extern unsigned long real64_call_asm(unsigned long *,
+					     unsigned long *, 
+					     unsigned long);
+    
+	va_start(args, fn);
+	real_stack.arg0 = va_arg(args, unsigned long);
+	real_stack.arg1 = va_arg(args, unsigned long);
+	real_stack.arg2 = va_arg(args, unsigned long);
+	real_stack.arg3 = va_arg(args, unsigned long);
+	real_stack.arg4 = va_arg(args, unsigned long);
+	real_stack.arg5 = va_arg(args, unsigned long);
+	real_stack.arg6 = va_arg(args, unsigned long);
+	real_stack.arg7 = va_arg(args, unsigned long);
+	real_stack.arg8 = va_arg(args, unsigned long);
+	real_stack.arg9 = va_arg(args, unsigned long);
+	real_stack.arg10 = va_arg(args, unsigned long);
+	real_stack.arg11 = va_arg(args, unsigned long);
+	real_stack.arg12 = va_arg(args, unsigned long);
+	real_stack.arg13 = va_arg(args, unsigned long);
+	va_end(args);
+	
+	return real64_call_asm(&real_stack.sp, &real_stack.arg0, fn);
+}
+
+#endif /* __LP64__ */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/hardware.c linux-bk/arch/parisc/kernel/hardware.c
--- linux-2.4.19/arch/parisc/kernel/hardware.c	2000-12-05 20:29:39.000000000 +0000
+++ linux-bk/arch/parisc/kernel/hardware.c	2002-08-17 00:49:04.000000000 +0000
@@ -5,7 +5,7 @@
  * 
  *    Based on the document "PA-RISC 1.1 I/O Firmware Architecture 
  *    Reference Specification", March 7, 1999, version 0.96.  This
- *    is available at ?.
+ *    is available at http://parisc-linux.org/documentation/
  *
  *    Copyright 1999 by Alex deVries <adevries@thepuffingroup.com>
  *    and copyright 1999 The Puffin Group Inc.
@@ -30,32 +30,15 @@
 #include <asm/hardware.h>
 #include <linux/stddef.h>
 #include <linux/kernel.h>
-
-#define HPHW_NUM_TYPES 3431
-
-static char * hw_type_name[16] = {
-	"Processor",
-	"Memory",
-	"B DMA",
-	"Obsolete",
-	"A DMA",
-	"A Direct",
-	"Obsolete",
-	"Bus Converter Port",
-	"HP CIO Adapter",
-	"Console",
-	"Foreign I/O Module",
-	"Bus Adapter",
-	"IOA (?)",
-	"Bus Bridge to Foreign Bus",
-	"HP Clothing: Fabric Component"
-};
+#include <linux/init.h>
 
 /*
- *	XXX	Could this be __init ??
+ *	HP PARISC Hardware Database
+ *	Access to this database is only possible during bootup
+ *	so don't reference this table after starting the init process
  */
  
-static struct hp_hardware hp_hardware_list[] = {
+static struct hp_hardware hp_hardware_list[] __initdata = {
 	{HPHW_NPROC,0x01,0x4,0x0,"Indigo (840, 930)"},
 	{HPHW_NPROC,0x8,0x4,0x01,"Firefox(825,925)"},
 	{HPHW_NPROC,0xA,0x4,0x01,"Top Gun (835,834,935,635)"},
@@ -169,9 +152,10 @@
 	{HPHW_NPROC,0x59A,0x4,0x91,"Unlisted but reserved"},
 	{HPHW_NPROC,0x59A,0x4,0x81,"Unlisted but reserved"},
 	{HPHW_NPROC,0x59B,0x4,0x81,"Raven U 160 (9000/780/C160)"},
+	{HPHW_NPROC,0x59C,0x4,0x81,"Raven U 180 (9000/780/C180)"},
 	{HPHW_NPROC,0x59D,0x4,0x81,"Raven U 200 (9000/780/C200)"},
 	{HPHW_NPROC,0x59E,0x4,0x91,"ThunderHawk T' 120"},
-	{HPHW_NPROC,0x59F,0x4,0x91,"Raven U 180+ (9000/780/\?\?\?\?)"},
+	{HPHW_NPROC,0x59F,0x4,0x91,"Raven U 180+ (9000/780)"},
 	{HPHW_NPROC,0x5A0,0x4,0x81,"UL 1w T120 1MB/1MB (841/D260,D360)"},
 	{HPHW_NPROC,0x5A1,0x4,0x91,"UL 2w T120 1MB/1MB (851/D260,D360)"},
 	{HPHW_NPROC,0x5A2,0x4,0x81,"UL 1w U160 512K/512K (861/D270,D370)"},
@@ -201,7 +185,7 @@
 	{HPHW_NPROC,0x5B8,0x4,0x91,"SPP2250 240 MHz"},
 	{HPHW_NPROC,0x5B9,0x4,0x81,"UL 1w U+/240 (350/550)"},
 	{HPHW_NPROC,0x5BA,0x4,0x91,"UL 2w U+/240 (350/550)"},
-	{HPHW_NPROC,0x5BB,0x4,0x81,"AllegroHigh W "},
+	{HPHW_NPROC,0x5BB,0x4,0x81,"AllegroHigh W"},
 	{HPHW_NPROC,0x5BC,0x4,0x91,"AllegroLow W"},
 	{HPHW_NPROC,0x5BD,0x4,0x91,"Forte W 2-way"},
 	{HPHW_NPROC,0x5BE,0x4,0x91,"Prelude W"},
@@ -212,12 +196,41 @@
 	{HPHW_NPROC,0x5C3,0x4,0x91,"Sonata 360"},
 	{HPHW_NPROC,0x5C4,0x4,0x91,"Rhapsody 440"},
 	{HPHW_NPROC,0x5C5,0x4,0x91,"Rhapsody 360"},
-	{HPHW_NPROC,0x5C6,0x4,0x91,"Raven W 360 (9000/780/\?\?\?\?)"},
+	{HPHW_NPROC,0x5C6,0x4,0x91,"Raven W 360 (9000/780)"},
 	{HPHW_NPROC,0x5C7,0x4,0x91,"Halfdome W 440"},
 	{HPHW_NPROC,0x5C8,0x4,0x81,"Lego 360 processor"},
 	{HPHW_NPROC,0x5C9,0x4,0x91,"Rhapsody DC- 440"},
 	{HPHW_NPROC,0x5CA,0x4,0x91,"Rhapsody DC- 360"},
 	{HPHW_NPROC,0x5CB,0x4,0x91,"Crescendo 440"},
+	{HPHW_NPROC,0x5CC,0x4,0x91,"Prelude W 440"},
+	{HPHW_NPROC,0x5CD,0x4,0x91,"SPP2600"},
+	{HPHW_NPROC,0x5CE,0x4,0x91,"M2600"},
+	{HPHW_NPROC,0x5CF,0x4,0x81,"Allegro W+"},
+	{HPHW_NPROC,0x5D0,0x4,0x81,"Kazoo W+"},
+	{HPHW_NPROC,0x5D1,0x4,0x91,"Forte W+ 2w"},
+	{HPHW_NPROC,0x5D2,0x4,0x91,"Forte W+ 4w"},
+	{HPHW_NPROC,0x5D3,0x4,0x91,"Prelude W+ 540"},
+	{HPHW_NPROC,0x5D4,0x4,0x91,"Duet W+"},
+	{HPHW_NPROC,0x5D5,0x4,0x91,"Crescendo 550"},
+	{HPHW_NPROC,0x5D6,0x4,0x81,"Crescendo DC- 440"},
+	{HPHW_NPROC,0x5D7,0x4,0x91,"Keystone W+"},
+	{HPHW_NPROC,0x5D8,0x4,0x91,"Rhapsody wave 2 W+ DC-"},
+	{HPHW_NPROC,0x5D9,0x4,0x91,"Rhapsody wave 2 W+"},
+	{HPHW_NPROC,0x5DA,0x4,0x91,"Marcato W+ DC-"},
+	{HPHW_NPROC,0x5DB,0x4,0x91,"Marcato W+"},
+	{HPHW_NPROC,0x5DC,0x4,0x91,"Allegro W2"},
+	{HPHW_NPROC,0x5DD,0x4,0x81,"Duet W2"},
+	{HPHW_NPROC,0x5DE,0x4,0x81,"Piccolo W+"},
+	{HPHW_NPROC,0x5DF,0x4,0x81,"Cantata W2"},
+	{HPHW_NPROC,0x5E0,0x4,0x91,"Cantata DC- W2"},
+	{HPHW_NPROC,0x5E1,0x4,0x91,"Crescendo DC- W2"},
+	{HPHW_NPROC,0x5E2,0x4,0x91,"Crescendo 650 W2"},
+	{HPHW_NPROC,0x5E3,0x4,0x91,"Crescendo 750 W2"},
+	{HPHW_NPROC,0x5E4,0x4,0x91,"Keystone/Matterhorn W2 750"},
+	{HPHW_NPROC,0x5E5,0x4,0x91,"PowerBar W+"},
+	{HPHW_NPROC,0x5E6,0x4,0x91,"Keystone/Matterhorn W2 650"},
+	{HPHW_NPROC,0x5E7,0x4,0x91,"Caribe W2 800"},
+	{HPHW_NPROC,0x5E8,0x4,0x91,"Pikes Peak W2"},
 	{HPHW_NPROC,0x5FF,0x4,0x91,"Hitachi W"},
 	{HPHW_NPROC,0x600,0x4,0x81,"Gecko (712/60)"},
 	{HPHW_NPROC,0x601,0x4,0x81,"Gecko 80 (712/80)"},
@@ -243,7 +256,7 @@
 	{HPHW_NPROC,0x616,0x4,0x81,"Piranha 120"},
 	{HPHW_NPROC,0x617,0x4,0x81,"Jason 50"},
 	{HPHW_NPROC,0x618,0x4,0x81,"Jason 100"},
-	{HPHW_NPROC,0x619,0x4,0x81,"Mirage 80 "},
+	{HPHW_NPROC,0x619,0x4,0x81,"Mirage 80"},
 	{HPHW_NPROC,0x61A,0x4,0x81,"SAIC L-80"},
 	{HPHW_NPROC,0x61B,0x4,0x81,"Rocky1 L-60"},
 	{HPHW_NPROC,0x61C,0x4,0x81,"Anole T (743/T)"},
@@ -311,6 +324,7 @@
 	{HPHW_A_DMA, 0x004, 0x00050, 0x80, "Lanbrusca 802.3 (36967A)"}, 
 	{HPHW_A_DMA, 0x004, 0x00056, 0x80, "HP-PB LoQuix FDDI"}, 
 	{HPHW_A_DMA, 0x004, 0x00057, 0x80, "HP-PB LoQuix FDDI (28670A)"}, 
+	{HPHW_A_DMA, 0x004, 0x0005E, 0x00, "Gecko Add-on Token Ring"}, 
 	{HPHW_A_DMA, 0x012, 0x00089, 0x80, "Barracuda Add-on FW-SCSI"}, 
 	{HPHW_A_DMA, 0x013, 0x00089, 0x80, "Bluefish Add-on FW-SCSI"}, 
 	{HPHW_A_DMA, 0x014, 0x00089, 0x80, "Shrike Add-on FW-SCSI"}, 
@@ -319,6 +333,7 @@
 	{HPHW_A_DMA, 0x01F, 0x00089, 0x80, "SkyHawk 100/120 FW-SCSI"}, 
 	{HPHW_A_DMA, 0x027, 0x00089, 0x80, "Piranha 100 FW-SCSI"}, 
 	{HPHW_A_DMA, 0x032, 0x00089, 0x80, "Raven T' Core FW-SCSI"}, 
+	{HPHW_A_DMA, 0x03b, 0x00089, 0x80, "Raven U/L2 Core FW-SCSI"}, 
 	{HPHW_A_DMA, 0x03d, 0x00089, 0x80, "Merlin 160 Core FW-SCSI"},
 	{HPHW_A_DMA, 0x044, 0x00089, 0x80, "Mohawk Core FW-SCSI"}, 
 	{HPHW_A_DMA, 0x051, 0x00089, 0x80, "Firehawk FW-SCSI"}, 
@@ -440,6 +455,8 @@
 	{HPHW_BA, 0x801, 0x00081, 0x0, "Hitachi Tiny 80 Core BA"}, 
 	{HPHW_BA, 0x004, 0x0008B, 0x0, "Anole Optional PCMCIA BA"}, 
 	{HPHW_BA, 0x004, 0x0008E, 0x0, "GSC ITR Wax BA"}, 
+	{HPHW_BA, 0x00C, 0x0008E, 0x0, "Gecko Optional Wax BA"}, 
+	{HPHW_BA, 0x010, 0x0008E, 0x0, "Pace Wax BA"}, 
 	{HPHW_BA, 0x011, 0x0008E, 0x0, "SuperPace Wax BA"}, 
 	{HPHW_BA, 0x012, 0x0008E, 0x0, "Mirage Jr Wax BA"}, 
 	{HPHW_BA, 0x013, 0x0008E, 0x0, "Mirage Wax BA"}, 
@@ -489,7 +506,7 @@
 	{HPHW_BA, 0x800, 0x00090, 0x0, "Hitachi Tiny 64 Wax EISA BA"}, 
 	{HPHW_BA, 0x801, 0x00090, 0x0, "Hitachi Tiny 80 Wax EISA BA"}, 
 	{HPHW_BA, 0x01A, 0x00093, 0x0, "Anole 64 TIMI BA"}, 
-	{HPHW_BA, 0x01B, 0x00093, 0x0, "Anole 64 TIMI BA"}, 
+	{HPHW_BA, 0x01B, 0x00093, 0x0, "Anole 100 TIMI BA"}, 
 	{HPHW_BA, 0x034, 0x00093, 0x0, "Anole T TIMI BA"}, 
 	{HPHW_BA, 0x04A, 0x00093, 0x0, "Anole L2 132 TIMI BA"}, 
 	{HPHW_BA, 0x04C, 0x00093, 0x0, "Anole L2 165 TIMI BA"}, 
@@ -551,6 +568,7 @@
 	{HPHW_CONSOLE, 0x01A, 0x0001F, 0x00, "Jason/Anole 64 Null Console"}, 
 	{HPHW_CONSOLE, 0x01B, 0x0001F, 0x00, "Jason/Anole 100 Null Console"}, 
 	{HPHW_FABRIC, 0x004, 0x000AA, 0x80, "Halfdome DNA Central Agent"}, 
+	{HPHW_FABRIC, 0x007, 0x000AA, 0x80, "Caribe DNA Central Agent"}, 
 	{HPHW_FABRIC, 0x004, 0x000AB, 0x00, "Halfdome TOGO Fabric Crossbar"}, 
 	{HPHW_FABRIC, 0x004, 0x000AC, 0x00, "Halfdome Sakura Fabric Router"}, 
 	{HPHW_FIO, 0x025, 0x0002E, 0x80, "Armyknife Optional X.25"}, 
@@ -588,14 +606,14 @@
 	{HPHW_FIO, 0x00D, 0x00072, 0x0, "Strider-33 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x00E, 0x00072, 0x0, "Trailways-50 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x00F, 0x00072, 0x0, "Trailways-33 Core LAN (802.3)"}, 
-	{HPHW_FIO, 0x010, 0x00072, 0x0, "Pace Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x011, 0x00072, 0x0, "Sidewinder Core Lan (802.3)"}, 
+	{HPHW_FIO, 0x010, 0x00072, 0x0, "Pace Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x011, 0x00072, 0x0, "Sidewinder Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x019, 0x00072, 0x0, "Scorpio Sr. Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x020, 0x00072, 0x0, "Scorpio 100 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x021, 0x00072, 0x0, "Spectra 50 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x022, 0x00072, 0x0, "Spectra 75 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x023, 0x00072, 0x0, "Spectra 100 Core LAN (802.3)"}, 
-	{HPHW_FIO, 0x024, 0x00072, 0x0, "Fast Pace Core Lan (802.3)"}, 
+	{HPHW_FIO, 0x024, 0x00072, 0x0, "Fast Pace Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x026, 0x00072, 0x0, "CoralII Jaguar Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x004, 0x00073, 0x0, "Cobra Core HIL"}, 
 	{HPHW_FIO, 0x005, 0x00073, 0x0, "Coral Core HIL"}, 
@@ -694,8 +712,8 @@
 	{HPHW_FIO, 0x04D, 0x00074, 0x0, "Anole L2 165 Core Centronics"}, 
 	{HPHW_FIO, 0x050, 0x00074, 0x0, "Merlin Jr 132 Core Centronics"}, 
 	{HPHW_FIO, 0x051, 0x00074, 0x0, "Firehawk Core Centronics"}, 
-	{HPHW_FIO, 0x056, 0x00074, 0x0, "Raven+ wSE FWSCSI Core Centronics"}, 
-	{HPHW_FIO, 0x057, 0x00074, 0x0, "Raven+ wDiff FWSCSI Core Centronics"}, 
+	{HPHW_FIO, 0x056, 0x00074, 0x0, "Raven+ w SE FWSCSI Core Centronics"}, 
+	{HPHW_FIO, 0x057, 0x00074, 0x0, "Raven+ w Diff FWSCSI Core Centronics"}, 
 	{HPHW_FIO, 0x058, 0x00074, 0x0, "FireHawk 200 Core Centronics"}, 
 	{HPHW_FIO, 0x05C, 0x00074, 0x0, "SummitHawk 230 Core Centronics"}, 
 	{HPHW_FIO, 0x800, 0x00074, 0x0, "Hitachi Tiny 64 Core Centronics"}, 
@@ -861,66 +879,66 @@
 	{HPHW_FIO, 0x02E, 0x00083, 0x0, "UL 350 Core PC Floppy"}, 
 	{HPHW_FIO, 0x02F, 0x00083, 0x0, "UL 550 Core PC Floppy"}, 
 	{HPHW_FIO, 0x032, 0x00083, 0x0, "Raven T' Core PC Floppy"}, 
-	{HPHW_FIO, 0x034, 0x00083, 0x0, "SAIC L-80 Core PC Floopy"}, 
-	{HPHW_FIO, 0x035, 0x00083, 0x0, "PCX-L2 712/132 Core Floopy"}, 
-	{HPHW_FIO, 0x036, 0x00083, 0x0, "PCX-L2 712/160 Core Floopy"}, 
-	{HPHW_FIO, 0x03B, 0x00083, 0x0, "Raven U/L2 Core PC Floopy"}, 
-	{HPHW_FIO, 0x03C, 0x00083, 0x0, "Merlin 132 Core PC Floopy"}, 
-	{HPHW_FIO, 0x03D, 0x00083, 0x0, "Merlin 160 Core PC Floopy"}, 
-	{HPHW_FIO, 0x03E, 0x00083, 0x0, "Merlin+ 132 Core PC Floopy"}, 
-	{HPHW_FIO, 0x03F, 0x00083, 0x0, "Merlin+ 180 Core PC Floopy"}, 
-	{HPHW_FIO, 0x045, 0x00083, 0x0, "Rocky1 Core PC Floopy"}, 
-	{HPHW_FIO, 0x046, 0x00083, 0x0, "Rocky2 120 Core PC Floopy"}, 
-	{HPHW_FIO, 0x047, 0x00083, 0x0, "Rocky2 150 Core PC Floopy"}, 
-	{HPHW_FIO, 0x04E, 0x00083, 0x0, "Kiji L2 132 Core PC Floopy"}, 
-	{HPHW_FIO, 0x050, 0x00083, 0x0, "Merlin Jr 132 Core PC Floopy"}, 
-	{HPHW_FIO, 0x056, 0x00083, 0x0, "Raven+ w SE FWSCSI Core PC Floopy"}, 
-	{HPHW_FIO, 0x057, 0x00083, 0x0, "Raven+ w Diff FWSCSI Core PC Floopy"}, 
-	{HPHW_FIO, 0x800, 0x00083, 0x0, "Hitachi Tiny 64 Core PC Floopy"}, 
-	{HPHW_FIO, 0x801, 0x00083, 0x0, "Hitachi Tiny 80 Core PC Floopy"}, 
-	{HPHW_FIO, 0x015, 0x00084, 0x0, "KittyHawk GSY Core PC Keyboard"}, 
-	{HPHW_FIO, 0x016, 0x00084, 0x0, "Gecko Core PC Keyboard"}, 
-	{HPHW_FIO, 0x018, 0x00084, 0x0, "Gecko Optional PC Keyboard"}, 
-	{HPHW_FIO, 0x01A, 0x00084, 0x0, "Anole 64 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x01B, 0x00084, 0x0, "Anole 100 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x01C, 0x00084, 0x0, "Gecko 80 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x01D, 0x00084, 0x0, "Gecko 100 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x01F, 0x00084, 0x0, "SkyHawk 100/120 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x027, 0x00084, 0x0, "Piranha 100 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x028, 0x00084, 0x0, "Mirage Jr Core PC Keyboard"}, 
-	{HPHW_FIO, 0x029, 0x00084, 0x0, "Mirage Core PC Keyboard"}, 
-	{HPHW_FIO, 0x02A, 0x00084, 0x0, "Electra Core PC Keyboard"}, 
-	{HPHW_FIO, 0x02B, 0x00084, 0x0, "Mirage 80 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x02C, 0x00084, 0x0, "Mirage 100+ Core PC Keyboard"}, 
-	{HPHW_FIO, 0x02E, 0x00084, 0x0, "UL 350 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x02F, 0x00084, 0x0, "UL 550 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x032, 0x00084, 0x0, "Raven T' Core PC Keyboard"}, 
-	{HPHW_FIO, 0x033, 0x00084, 0x0, "Anole T Core PC Keyboard"}, 
-	{HPHW_FIO, 0x034, 0x00084, 0x0, "SAIC L-80 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x035, 0x00084, 0x0, "PCX-L2 712/132 Core Keyboard"}, 
-	{HPHW_FIO, 0x036, 0x00084, 0x0, "PCX-L2 712/160 Core Keyboard"}, 
-	{HPHW_FIO, 0x03B, 0x00084, 0x0, "Raven U/L2 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x03C, 0x00084, 0x0, "Merlin 132 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x03D, 0x00084, 0x0, "Merlin 160 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x03E, 0x00084, 0x0, "Merlin+ 132 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x03F, 0x00084, 0x0, "Merlin+ 180 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x044, 0x00084, 0x0, "Mohawk Core PC Keyboard"}, 
-	{HPHW_FIO, 0x045, 0x00084, 0x0, "Rocky1 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x046, 0x00084, 0x0, "Rocky2 120 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x047, 0x00084, 0x0, "Rocky2 150 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x048, 0x00084, 0x0, "Rocky2 120 Dino PC Keyboard"}, 
-	{HPHW_FIO, 0x049, 0x00084, 0x0, "Rocky2 150 Dino PC Keyboard"}, 
-	{HPHW_FIO, 0x04B, 0x00084, 0x0, "Anole L2 132 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x04D, 0x00084, 0x0, "Anole L2 165 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x04E, 0x00084, 0x0, "Kiji L2 132 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x050, 0x00084, 0x0, "Merlin Jr 132 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x051, 0x00084, 0x0, "Firehawk Core PC Keyboard"}, 
-	{HPHW_FIO, 0x056, 0x00084, 0x0, "Raven+ w SE FWSCSI Core PC Keyboard"}, 
-	{HPHW_FIO, 0x057, 0x00084, 0x0, "Raven+ w Diff FWSCSI Core PC Keyboard"}, 
-	{HPHW_FIO, 0x058, 0x00084, 0x0, "FireHawk 200 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x05C, 0x00084, 0x0, "SummitHawk 230 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x800, 0x00084, 0x0, "Hitachi Tiny 64 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x801, 0x00084, 0x0, "Hitachi Tiny 80 Core PC Keyboard"}, 
+	{HPHW_FIO, 0x034, 0x00083, 0x0, "SAIC L-80 Core PC Floppy"}, 
+	{HPHW_FIO, 0x035, 0x00083, 0x0, "PCX-L2 712/132 Core Floppy"}, 
+	{HPHW_FIO, 0x036, 0x00083, 0x0, "PCX-L2 712/160 Core Floppy"}, 
+	{HPHW_FIO, 0x03B, 0x00083, 0x0, "Raven U/L2 Core PC Floppy"}, 
+	{HPHW_FIO, 0x03C, 0x00083, 0x0, "Merlin 132 Core PC Floppy"}, 
+	{HPHW_FIO, 0x03D, 0x00083, 0x0, "Merlin 160 Core PC Floppy"}, 
+	{HPHW_FIO, 0x03E, 0x00083, 0x0, "Merlin+ 132 Core PC Floppy"}, 
+	{HPHW_FIO, 0x03F, 0x00083, 0x0, "Merlin+ 180 Core PC Floppy"}, 
+	{HPHW_FIO, 0x045, 0x00083, 0x0, "Rocky1 Core PC Floppy"}, 
+	{HPHW_FIO, 0x046, 0x00083, 0x0, "Rocky2 120 Core PC Floppy"}, 
+	{HPHW_FIO, 0x047, 0x00083, 0x0, "Rocky2 150 Core PC Floppy"}, 
+	{HPHW_FIO, 0x04E, 0x00083, 0x0, "Kiji L2 132 Core PC Floppy"}, 
+	{HPHW_FIO, 0x050, 0x00083, 0x0, "Merlin Jr 132 Core PC Floppy"}, 
+	{HPHW_FIO, 0x056, 0x00083, 0x0, "Raven+ w SE FWSCSI Core PC Floppy"}, 
+	{HPHW_FIO, 0x057, 0x00083, 0x0, "Raven+ w Diff FWSCSI Core PC Floppy"}, 
+	{HPHW_FIO, 0x800, 0x00083, 0x0, "Hitachi Tiny 64 Core PC Floppy"}, 
+	{HPHW_FIO, 0x801, 0x00083, 0x0, "Hitachi Tiny 80 Core PC Floppy"},
+	{HPHW_FIO, 0x015, 0x00084, 0x0, "KittyHawk GSY Core PS/2 Port"}, 
+	{HPHW_FIO, 0x016, 0x00084, 0x0, "Gecko Core PS/2 Port"}, 
+	{HPHW_FIO, 0x018, 0x00084, 0x0, "Gecko Optional PS/2 Port"}, 
+	{HPHW_FIO, 0x01A, 0x00084, 0x0, "Anole 64 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x01B, 0x00084, 0x0, "Anole 100 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x01C, 0x00084, 0x0, "Gecko 80 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x01D, 0x00084, 0x0, "Gecko 100 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x01F, 0x00084, 0x0, "SkyHawk 100/120 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x027, 0x00084, 0x0, "Piranha 100 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x028, 0x00084, 0x0, "Mirage Jr Core PS/2 Port"}, 
+	{HPHW_FIO, 0x029, 0x00084, 0x0, "Mirage Core PS/2 Port"}, 
+	{HPHW_FIO, 0x02A, 0x00084, 0x0, "Electra Core PS/2 Port"}, 
+	{HPHW_FIO, 0x02B, 0x00084, 0x0, "Mirage 80 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x02C, 0x00084, 0x0, "Mirage 100+ Core PS/2 Port"}, 
+	{HPHW_FIO, 0x02E, 0x00084, 0x0, "UL 350 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x02F, 0x00084, 0x0, "UL 550 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x032, 0x00084, 0x0, "Raven T' Core PS/2 Port"}, 
+	{HPHW_FIO, 0x033, 0x00084, 0x0, "Anole T Core PS/2 Port"}, 
+	{HPHW_FIO, 0x034, 0x00084, 0x0, "SAIC L-80 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x035, 0x00084, 0x0, "PCX-L2 712/132 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x036, 0x00084, 0x0, "PCX-L2 712/160 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x03B, 0x00084, 0x0, "Raven U/L2 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x03C, 0x00084, 0x0, "Merlin 132 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x03D, 0x00084, 0x0, "Merlin 160 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x03E, 0x00084, 0x0, "Merlin+ 132 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x03F, 0x00084, 0x0, "Merlin+ 180 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x044, 0x00084, 0x0, "Mohawk Core PS/2 Port"}, 
+	{HPHW_FIO, 0x045, 0x00084, 0x0, "Rocky1 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x046, 0x00084, 0x0, "Rocky2 120 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x047, 0x00084, 0x0, "Rocky2 150 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x048, 0x00084, 0x0, "Rocky2 120 Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x049, 0x00084, 0x0, "Rocky2 150 Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x04B, 0x00084, 0x0, "Anole L2 132 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x04D, 0x00084, 0x0, "Anole L2 165 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x04E, 0x00084, 0x0, "Kiji L2 132 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x050, 0x00084, 0x0, "Merlin Jr 132 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x051, 0x00084, 0x0, "Firehawk Core PS/2 Port"}, 
+	{HPHW_FIO, 0x056, 0x00084, 0x0, "Raven+ w SE FWSCSI Core PS/2 Port"}, 
+	{HPHW_FIO, 0x057, 0x00084, 0x0, "Raven+ w Diff FWSCSI Core PS/2 Port"}, 
+	{HPHW_FIO, 0x058, 0x00084, 0x0, "FireHawk 200 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x05C, 0x00084, 0x0, "SummitHawk 230 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x800, 0x00084, 0x0, "Hitachi Tiny 64 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x801, 0x00084, 0x0, "Hitachi Tiny 80 Core PS/2 Port"}, 
 	{HPHW_FIO, 0x004, 0x00085, 0x0, "Solo GSC Optional Graphics"}, 
 	{HPHW_FIO, 0x005, 0x00085, 0x0, "Duet GSC Optional Graphics"}, 
 	{HPHW_FIO, 0x008, 0x00085, 0x0, "Anole Artist Optional Graphics"}, 
@@ -969,18 +987,17 @@
 	{HPHW_FIO, 0x034, 0x00088, 0x0, "Anole T VME Networking"}, 
 	{HPHW_FIO, 0x04A, 0x00088, 0x0, "Anole L2 132 VME Networking"}, 
 	{HPHW_FIO, 0x04C, 0x00088, 0x0, "Anole L2 165 VME Networking"}, 
-	{HPHW_FIO, 0x03B, 0x00089, 0x0, "Raven U/L2 Core FW-SCSI"}, 
-	{HPHW_FIO, 0x011, 0x0008A, 0x0, "WB-96 Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x012, 0x0008A, 0x0, "Orville Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x013, 0x0008A, 0x0, "Wilbur Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x014, 0x0008A, 0x0, "WB-80 Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x015, 0x0008A, 0x0, "KittyHawk GSY Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x016, 0x0008A, 0x0, "Gecko Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x018, 0x0008A, 0x0, "Gecko Optional Lan (802.3)"}, 
-	{HPHW_FIO, 0x01A, 0x0008A, 0x0, "Anole 64 Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x01B, 0x0008A, 0x0, "Anole 100 Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x01C, 0x0008A, 0x0, "Gecko 80 Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x01D, 0x0008A, 0x0, "Gecko 100 Core Lan (802.3)"}, 
+	{HPHW_FIO, 0x011, 0x0008A, 0x0, "WB-96 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x012, 0x0008A, 0x0, "Orville Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x013, 0x0008A, 0x0, "Wilbur Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x014, 0x0008A, 0x0, "WB-80 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x015, 0x0008A, 0x0, "KittyHawk GSY Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x016, 0x0008A, 0x0, "Gecko Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x018, 0x0008A, 0x0, "Gecko Optional LAN (802.3)"}, 
+	{HPHW_FIO, 0x01A, 0x0008A, 0x0, "Anole 64 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x01B, 0x0008A, 0x0, "Anole 100 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x01C, 0x0008A, 0x0, "Gecko 80 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x01D, 0x0008A, 0x0, "Gecko 100 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x01F, 0x0008A, 0x0, "SkyHawk 100/120 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x027, 0x0008A, 0x0, "Piranha 100 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x028, 0x0008A, 0x0, "Mirage Jr Core LAN (802.3)"}, 
@@ -991,24 +1008,24 @@
 	{HPHW_FIO, 0x02E, 0x0008A, 0x0, "UL 350 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x02F, 0x0008A, 0x0, "UL 350 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x032, 0x0008A, 0x0, "Raven T' Core LAN (802.3)"}, 
-	{HPHW_FIO, 0x033, 0x0008A, 0x0, "Anole T Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x034, 0x0008A, 0x0, "SAIC L-80 Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x035, 0x0008A, 0x0, "PCX-L2 712/132 Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x036, 0x0008A, 0x0, "PCX-L2 712/160 Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x03B, 0x0008A, 0x0, "Raven U/L2 Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x03C, 0x0008A, 0x0, "Merlin 132 Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x03D, 0x0008A, 0x0, "Merlin 160 Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x044, 0x0008A, 0x0, "Mohawk Core Lan (802.3)"}, 
+	{HPHW_FIO, 0x033, 0x0008A, 0x0, "Anole T Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x034, 0x0008A, 0x0, "SAIC L-80 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x035, 0x0008A, 0x0, "PCX-L2 712/132 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x036, 0x0008A, 0x0, "PCX-L2 712/160 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x03B, 0x0008A, 0x0, "Raven U/L2 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x03C, 0x0008A, 0x0, "Merlin 132 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x03D, 0x0008A, 0x0, "Merlin 160 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x044, 0x0008A, 0x0, "Mohawk Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x045, 0x0008A, 0x0, "Rocky1 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x046, 0x0008A, 0x0, "Rocky2 120 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x047, 0x0008A, 0x0, "Rocky2 150 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x04B, 0x0008A, 0x0, "Anole L2 132 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x04D, 0x0008A, 0x0, "Anole L2 165 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x04E, 0x0008A, 0x0, "Kiji L2 132 Core LAN (802.3)"}, 
-	{HPHW_FIO, 0x050, 0x0008A, 0x0, "Merlin Jr 132 Core Lan (802.3)"}, 
+	{HPHW_FIO, 0x050, 0x0008A, 0x0, "Merlin Jr 132 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x058, 0x0008A, 0x0, "FireHawk 200 Core LAN (802.3)"}, 
-	{HPHW_FIO, 0x800, 0x0008A, 0x0, "Hitachi Tiny 64 Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x801, 0x0008A, 0x0, "Hitachi Tiny 80 Core Lan (802.3)"}, 
+	{HPHW_FIO, 0x800, 0x0008A, 0x0, "Hitachi Tiny 64 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x801, 0x0008A, 0x0, "Hitachi Tiny 80 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x004, 0x0008C, 0x0, "SkyHawk 100/120 Wax RS-232"}, 
 	{HPHW_FIO, 0x005, 0x0008C, 0x0, "SAIC L-80 Wax RS-232"}, 
 	{HPHW_FIO, 0x006, 0x0008C, 0x0, "Raven U/L2 Dino RS-232"}, 
@@ -1099,14 +1116,15 @@
 	{HPHW_FIO, 0x005, 0x0008F, 0x0, "Rocky1 Boot Rom"}, 
 	{HPHW_FIO, 0x006, 0x0008F, 0x0, "Rocky2 120 Boot Rom"}, 
 	{HPHW_FIO, 0x007, 0x0008F, 0x0, "Rocky2 150 Boot Rom"}, 
-	{HPHW_FIO, 0x006, 0x00096, 0x0, "Raven U/L2 Dino PS2 Keyboard"}, 
-	{HPHW_FIO, 0x007, 0x00096, 0x0, "Dino PS2 Keyboard"}, 
-	{HPHW_FIO, 0x008, 0x00096, 0x0, "Merlin 132 Dino PS2 Keyboard"}, 
-	{HPHW_FIO, 0x009, 0x00096, 0x0, "Merlin 160 Dino PS2 Keyboard"}, 
-	{HPHW_FIO, 0x00A, 0x00096, 0x0, "Merlin Jr 132 Dino PS2 Keyboard"}, 
-	{HPHW_FIO, 0x019, 0x00096, 0x0, "Merlin+ 180 Dino PS2 Keyboard"}, 
-	{HPHW_FIO, 0x022, 0x00096, 0x0, "Merlin+ 132 Dino PS2 Keyboard"}, 
-	{HPHW_FIO, 0x004, 0x00097, 0x0, "Cascade EISA 100VG lan"}, 
+	{HPHW_FIO, 0x01B, 0x0008F, 0x0, "Anole 100 Boot Rom"}, 
+	{HPHW_FIO, 0x006, 0x00096, 0x0, "Raven U/L2 Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x007, 0x00096, 0x0, "Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x008, 0x00096, 0x0, "Merlin 132 Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x009, 0x00096, 0x0, "Merlin 160 Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x00A, 0x00096, 0x0, "Merlin Jr 132 Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x019, 0x00096, 0x0, "Merlin+ 180 Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x022, 0x00096, 0x0, "Merlin+ 132 Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x004, 0x00097, 0x0, "Cascade EISA 100VG LAN"}, 
 	{HPHW_FIO, 0x023, 0x00099, 0x0, "Rocky1 Wax HPIB"}, 
 	{HPHW_FIO, 0x048, 0x00099, 0x0, "Rocky2 120 Clark/Dino HPIB"}, 
 	{HPHW_FIO, 0x049, 0x00099, 0x0, "Rocky2 150 Clark/Dino HPIB"}, 
@@ -1114,14 +1132,14 @@
 	{HPHW_FIO, 0x004, 0x000A2, 0x0, "Forte Core PCI 10/100BT LAN"}, 
 	{HPHW_FIO, 0x005, 0x000A2, 0x0, "AllegroLow PCI 10/100BT LAN"}, 
 	{HPHW_FIO, 0x006, 0x000A2, 0x0, "AllegroHIgh Core PCI 10/100BT LAN"}, 
-	{HPHW_FIO, 0x007, 0x000A2, 0x0, "PCI Plug-in Lan"}, 
-	{HPHW_FIO, 0x00A, 0x000A2, 0x0, "Lego 360 Core PCI 10/100BT Lan"}, 
-	{HPHW_FIO, 0x03E, 0x000A2, 0x0, "Merlin+ 132 Core PCI Lan"}, 
-	{HPHW_FIO, 0x03F, 0x000A2, 0x0, "Merlin+ 180 Core PCI Lan"}, 
-	{HPHW_FIO, 0x056, 0x000A2, 0x0, "Raven+ w SE FWSCSI Core PCI Lan"}, 
-	{HPHW_FIO, 0x057, 0x000A2, 0x0, "Raven+ w Diff FWSCSI Core PCI Lan"}, 
-	{HPHW_FIO, 0x05E, 0x000A2, 0x0, "Staccato 132 PCI Lan"}, 
-	{HPHW_FIO, 0x05F, 0x000A2, 0x0, "Staccato 180 PCI Lan"}, 
+	{HPHW_FIO, 0x007, 0x000A2, 0x0, "PCI Plug-in LAN"}, 
+	{HPHW_FIO, 0x00A, 0x000A2, 0x0, "Lego 360 Core PCI 10/100BT LAN"}, 
+	{HPHW_FIO, 0x03E, 0x000A2, 0x0, "Merlin+ 132 Core PCI LAN"}, 
+	{HPHW_FIO, 0x03F, 0x000A2, 0x0, "Merlin+ 180 Core PCI LAN"}, 
+	{HPHW_FIO, 0x056, 0x000A2, 0x0, "Raven+ w SE FWSCSI Core PCI LAN"}, 
+	{HPHW_FIO, 0x057, 0x000A2, 0x0, "Raven+ w Diff FWSCSI Core PCI LAN"}, 
+	{HPHW_FIO, 0x05E, 0x000A2, 0x0, "Staccato 132 PCI LAN"}, 
+	{HPHW_FIO, 0x05F, 0x000A2, 0x0, "Staccato 180 PCI LAN"}, 
 	{HPHW_FIO, 0x004, 0x000A3, 0x0, "Forte Core PCI LVD Ultra2 SCSI"}, 
 	{HPHW_FIO, 0x004, 0x000A3, 0x0, "Forte Core PCI SE UltraSCSI"}, 
 	{HPHW_FIO, 0x004, 0x000A3, 0x0, "Forte Core PCI IDE/ATAPI CD-ROM"}, 
@@ -1157,160 +1175,19 @@
 	{HPHW_IOA, 0x185, 0x0000B, 0x00, "Java BC Summit Port"}, 
 	{HPHW_IOA, 0x1FF, 0x0000B, 0x00, "Hitachi Ghostview Summit Port"}, 
 	{HPHW_IOA, 0x580, 0x0000B, 0x10, "U2-IOA BC Runway Port"}, 
-	{HPHW_IOA, 0x581, 0x0000B, 0x10, "Uturn-IOA BC Runway Port"}, 
-	{HPHW_IOA, 0x582, 0x0000B, 0x10, "Astro BC Runway Port"}, 
-	{HPHW_IOA, 0x700, 0x0000B, 0x00, "NEC-IOS BC System Bus Port"}, 
+	{HPHW_IOA, 0x581, 0x0000B, 0x10, "Uturn-IOA BC Runway Port"},
+	{HPHW_IOA, 0x582, 0x0000B, 0x10, "Astro BC Runway Port"},
+	{HPHW_IOA, 0x700, 0x0000B, 0x00, "NEC-IOS BC System Bus Port"},
 	{HPHW_MEMORY, 0x002, 0x00008, 0x00, "MID_BUS"}, 
-	{HPHW_MEMORY, 0x00C, 0x00008, 0x08, "Kahlua 8MB"}, 
-	{HPHW_MEMORY, 0x00D, 0x00008, 0x08, "Kahlua 4MB"}, 
-	{HPHW_MEMORY, 0x00E, 0x00008, 0x08, "Tequila 16MB"}, 
-	{HPHW_MEMORY, 0x00F, 0x00008, 0x08, "Tequila 32MB"}, 
-	{HPHW_MEMORY, 0x040, 0x00008, 0x00, "Hitachi"}, 
-	{HPHW_MEMORY, 0x004, 0x00009, 0x00, "Cheetah"}, 
-	{HPHW_MEMORY, 0x005, 0x00009, 0x00, "Emerald"}, 
-	{HPHW_MEMORY, 0x008, 0x00009, 0x00, "Indigo 3MB/5MB"}, 
-	{HPHW_MEMORY, 0x00C, 0x00009, 0x00, "Indigo 8MB"}, 
-	{HPHW_MEMORY, 0x00D, 0x00009, 0x00, "Paradise 4MB"}, 
-	{HPHW_MEMORY, 0x00E, 0x00009, 0x00, "Burgundy Onboard"}, 
-	{HPHW_MEMORY, 0x012, 0x00009, 0x00, "Indigo 12MB/20MB"}, 
-	{HPHW_MEMORY, 0x013, 0x00009, 0x00, "Cobra"}, 
-	{HPHW_MEMORY, 0x014, 0x00009, 0x00, "Nova"}, 
-	{HPHW_MEMORY, 0x015, 0x00009, 0x00, "Coral"}, 
-	{HPHW_MEMORY, 0x016, 0x00009, 0x00, "Bushmaster"}, 
-	{HPHW_MEMORY, 0x017, 0x00009, 0x00, "Scorpio"}, 
-	{HPHW_MEMORY, 0x018, 0x00009, 0x00, "Flounder"}, 
-	{HPHW_MEMORY, 0x019, 0x00009, 0x00, "Hardball"}, 
-	{HPHW_MEMORY, 0x01A, 0x00009, 0x00, "CoralII 99"}, 
-	{HPHW_MEMORY, 0x01B, 0x00009, 0x00, "Scorpio Jr."}, 
-	{HPHW_MEMORY, 0x01C, 0x00009, 0x00, "Strider-50 (715T)"}, 
-	{HPHW_MEMORY, 0x01D, 0x00009, 0x00, "Strider-33 (707T)"}, 
-	{HPHW_MEMORY, 0x01E, 0x00009, 0x00, "Trailways-50 (715S)"}, 
-	{HPHW_MEMORY, 0x01F, 0x00009, 0x00, "Trailways-33 (707S)"}, 
-	{HPHW_MEMORY, 0x020, 0x00009, 0x00, "Pace"}, 
-	{HPHW_MEMORY, 0x021, 0x00009, 0x00, "Sidewinder"}, 
-	{HPHW_MEMORY, 0x022, 0x00009, 0x00, "Orville"}, 
-	{HPHW_MEMORY, 0x023, 0x00009, 0x00, "Wilbur"}, 
-	{HPHW_MEMORY, 0x026, 0x00009, 0x00, "Gecko"}, 
-	{HPHW_MEMORY, 0x027, 0x00009, 0x00, "Scorpio Sr."}, 
-	{HPHW_MEMORY, 0x028, 0x00009, 0x00, "Scorpio 100"}, 
-	{HPHW_MEMORY, 0x029, 0x00009, 0x00, "Spectra 50"}, 
-	{HPHW_MEMORY, 0x02A, 0x00009, 0x00, "CoralII 132"}, 
-	{HPHW_MEMORY, 0x02F, 0x00009, 0x00, "KittyHawk DC2-"}, 
-	{HPHW_MEMORY, 0x030, 0x00009, 0x00, "Spectra 75"}, 
-	{HPHW_MEMORY, 0x031, 0x00009, 0x00, "Spectra 100"}, 
-	{HPHW_MEMORY, 0x032, 0x00009, 0x00, "KittyHawk DC3"}, 
-	{HPHW_MEMORY, 0x033, 0x00009, 0x00, "Fast Pace"}, 
-	{HPHW_MEMORY, 0x034, 0x00009, 0x00, "Snake Eagle"}, 
-	{HPHW_MEMORY, 0x035, 0x00009, 0x00, "Anole 64"}, 
-	{HPHW_MEMORY, 0x036, 0x00009, 0x00, "Anole 100"}, 
-	{HPHW_MEMORY, 0x037, 0x00009, 0x00, "Snake Cheetah"}, 
-	{HPHW_MEMORY, 0x038, 0x00009, 0x00, "Gecko 80"}, 
-	{HPHW_MEMORY, 0x039, 0x00009, 0x00, "Gecko 100"}, 
-	{HPHW_MEMORY, 0x03A, 0x00009, 0x00, "Gecko 120"}, 
-	{HPHW_MEMORY, 0x03B, 0x00009, 0x00, "Gila 80"}, 
-	{HPHW_MEMORY, 0x03C, 0x00009, 0x00, "Gila 100"}, 
-	{HPHW_MEMORY, 0x03D, 0x00009, 0x00, "Gila 120"}, 
-	{HPHW_MEMORY, 0x03E, 0x00009, 0x00, "Scorpio-L 80"}, 
-	{HPHW_MEMORY, 0x03F, 0x00009, 0x00, "Scorpio-L 100"}, 
-	{HPHW_MEMORY, 0x040, 0x00009, 0x00, "Scorpio-L 120"}, 
-	{HPHW_MEMORY, 0x041, 0x00009, 0x00, "Spectra-L 80"}, 
-	{HPHW_MEMORY, 0x042, 0x00009, 0x00, "Spectra-L 100"}, 
-	{HPHW_MEMORY, 0x043, 0x00009, 0x00, "Spectra-L 120"}, 
-	{HPHW_MEMORY, 0x044, 0x00009, 0x00, "Piranha 100"}, 
-	{HPHW_MEMORY, 0x045, 0x00009, 0x00, "Piranha 120"}, 
-	{HPHW_MEMORY, 0x046, 0x00009, 0x00, "Jason 50"}, 
-	{HPHW_MEMORY, 0x047, 0x00009, 0x00, "Jason 100"}, 
-	{HPHW_MEMORY, 0x049, 0x00009, 0x00, "SkyHawk 100/120"}, 
-	{HPHW_MEMORY, 0x04A, 0x00009, 0x00, "Mirage Jr"}, 
-	{HPHW_MEMORY, 0x04B, 0x00009, 0x00, "Mirage 100"}, 
-	{HPHW_MEMORY, 0x04C, 0x00009, 0x00, "Mirage 100+"}, 
-	{HPHW_MEMORY, 0x04D, 0x00009, 0x00, "Electra 100"}, 
-	{HPHW_MEMORY, 0x04E, 0x00009, 0x00, "Electra 120"}, 
-	{HPHW_MEMORY, 0x04F, 0x00009, 0x00, "Mirage 80"}, 
-	{HPHW_MEMORY, 0x050, 0x00009, 0x00, "UL Proc 1 way T'100"}, 
-	{HPHW_MEMORY, 0x051, 0x00009, 0x00, "UL Proc 1 way T'120"}, 
-	{HPHW_MEMORY, 0x052, 0x00009, 0x00, "UL Proc 2 way T'100"}, 
-	{HPHW_MEMORY, 0x053, 0x00009, 0x00, "KittyHawk DC3-"}, 
-	{HPHW_MEMORY, 0x054, 0x00009, 0x00, "UL Proc 2 way T'120"}, 
-	{HPHW_MEMORY, 0x055, 0x00009, 0x00, "Raven 120 mem"}, 
-	{HPHW_MEMORY, 0x056, 0x00009, 0x00, "UL Proc L 75"}, 
-	{HPHW_MEMORY, 0x057, 0x00009, 0x00, "UL Proc L 100"}, 
-	{HPHW_MEMORY, 0x058, 0x00009, 0x00, "Anole T"}, 
-	{HPHW_MEMORY, 0x059, 0x00009, 0x00, "SAIC L-80"}, 
-	{HPHW_MEMORY, 0x05A, 0x00009, 0x00, "Merlin+ L2 180"}, 
-	{HPHW_MEMORY, 0x05B, 0x00009, 0x00, "Raven U 200 2-way"}, 
-	{HPHW_MEMORY, 0x05C, 0x00009, 0x00, "Raven U 180+"}, 
-	{HPHW_MEMORY, 0x05D, 0x00009, 0x00, "Raven U 200"}, 
-	{HPHW_MEMORY, 0x05E, 0x00009, 0x00, "Rocky2 150 Memory"}, 
-	{HPHW_MEMORY, 0x08A, 0x00009, 0x00, "Staccato L2 132 Memory"}, 
-	{HPHW_MEMORY, 0x08B, 0x00009, 0x00, "Staccato L2 180 Memory"}, 
-	{HPHW_MEMORY, 0x05F, 0x00009, 0x00, "SPP2000 Memory"}, 
-	{HPHW_MEMORY, 0x060, 0x00009, 0x00, "Merlin L2 132"}, 
-	{HPHW_MEMORY, 0x061, 0x00009, 0x00, "Merlin+ L2 132"}, 
 	{HPHW_MEMORY, 0x063, 0x00009, 0x00, "712/132 L2 Upgrade"}, 
 	{HPHW_MEMORY, 0x064, 0x00009, 0x00, "712/160 L2 Upgrade"}, 
 	{HPHW_MEMORY, 0x065, 0x00009, 0x00, "715/132 L2 Upgrade"}, 
-	{HPHW_MEMORY, 0x066, 0x00009, 0x00, "715/160 L2 Upgrade"}, 
-	{HPHW_MEMORY, 0x067, 0x00009, 0x00, "Merlin 160/ThunderHawk Memory"}, 
-	{HPHW_MEMORY, 0x068, 0x00009, 0x00, "LightningHawk Memory"}, 
-	{HPHW_MEMORY, 0x069, 0x00009, 0x00, "Rocky1 Memory"}, 
-	{HPHW_MEMORY, 0x06A, 0x00009, 0x00, "Raven L2 132"}, 
-	{HPHW_MEMORY, 0x06B, 0x00009, 0x00, "Raven L2 160"}, 
-	{HPHW_MEMORY, 0x06C, 0x00009, 0x00, "Raven L2 187"}, 
-	{HPHW_MEMORY, 0x06D, 0x00009, 0x00, "Raven L2 200"}, 
-	{HPHW_MEMORY, 0x06E, 0x00009, 0x00, "Raven U 230"}, 
-	{HPHW_MEMORY, 0x06F, 0x00009, 0x00, "Raven U 240"}, 
-	{HPHW_MEMORY, 0x070, 0x00009, 0x00, "Rocky2 120 Memory"}, 
-	{HPHW_MEMORY, 0x071, 0x00009, 0x00, "Raven U 160"}, 
-	{HPHW_MEMORY, 0x072, 0x00009, 0x00, "Raven U 180"}, 
-	{HPHW_MEMORY, 0x072, 0x00009, 0x00, "UL Proc 1 way T'120 1MB/1MB"}, 
-	{HPHW_MEMORY, 0x073, 0x00009, 0x00, "UL Proc 2 way T'120 1MB/1MB"}, 
-	{HPHW_MEMORY, 0x074, 0x00009, 0x00, "Anole L2 132 memory"}, 
-	{HPHW_MEMORY, 0x075, 0x00009, 0x00, "Anole L2 165 memory"}, 
-	{HPHW_MEMORY, 0x076, 0x00009, 0x00, "UL 1 way U160 512K/512K memory"}, 
-	{HPHW_MEMORY, 0x077, 0x00009, 0x00, "UL 2 way U160 512K/512K memory"}, 
-	{HPHW_MEMORY, 0x078, 0x00009, 0x00, "Kiji L2 132 memory"}, 
-	{HPHW_MEMORY, 0x079, 0x00009, 0x00, "UL 1 way U160 1M/1M memory"}, 
-	{HPHW_MEMORY, 0x07A, 0x00009, 0x00, "UL 2 way U160 1M/1M memory"}, 
-	{HPHW_MEMORY, 0x07B, 0x00009, 0x00, "UL 1 way U180 1M/1M memory"}, 
-	{HPHW_MEMORY, 0x07C, 0x00009, 0x00, "UL 2 way U180 1M/1M memory"}, 
-	{HPHW_MEMORY, 0x07D, 0x00009, 0x00, "UL 1 way U240 U+ 2M/2M memory"}, 
-	{HPHW_MEMORY, 0x07E, 0x00009, 0x00, "UL 2 way U240 U+ 2M/2M memory"}, 
-	{HPHW_MEMORY, 0x07F, 0x00009, 0x00, "UL L2 132 memory"}, 
-	{HPHW_MEMORY, 0x080, 0x00009, 0x00, "UL L2 160 memory"}, 
-	{HPHW_MEMORY, 0x081, 0x00009, 0x00, "Merlin Jr 132 memory"}, 
-	{HPHW_MEMORY, 0x082, 0x00009, 0x00, "FireHawk 200 Memory"}, 
-	{HPHW_MEMORY, 0x083, 0x00009, 0x00, "SummitHawk Memory"}, 
-	{HPHW_MEMORY, 0x084, 0x00009, 0x00, "Jade Upgrade Memory"}, 
-	{HPHW_MEMORY, 0x085, 0x00009, 0x00, "SPP2500 Memory"}, 
-	{HPHW_MEMORY, 0x086, 0x00009, 0x00, "AllegroHigh Memory"}, 
-	{HPHW_MEMORY, 0x087, 0x00009, 0x00, "AllegroLow Memory"}, 
-	{HPHW_MEMORY, 0x088, 0x00009, 0x00, "Forte 2w Memory"}, 
-	{HPHW_MEMORY, 0x089, 0x00009, 0x00, "Forte 4w Memory"}, 
-	{HPHW_MEMORY, 0x08A, 0x00009, 0x00, "Staccato L2 132 Memory"}, 
-	{HPHW_MEMORY, 0x08B, 0x00009, 0x00, "Staccato L2 180 Memory"}, 
-	{HPHW_MEMORY, 0x090, 0x00009, 0x00, "Prelude SMC Memory"}, 
-	{HPHW_MEMORY, 0x091, 0x00009, 0x00, "Lego 360 Memory"}, 
-	{HPHW_MEMORY, 0x7FF, 0x00009, 0x00, "NEC Aska memory"}, 
-	{HPHW_MEMORY, 0x800, 0x00009, 0x00, "Hitachi Tiny 64"}, 
-	{HPHW_MEMORY, 0x801, 0x00009, 0x00, "Hitachi Tiny 80"}, 
-	{HPHW_MEMORY, 0x8FF, 0x00009, 0x00, "Hitachi X memory"}, 
-	{HPHW_MEMORY, 0x091, 0x00009, 0x00, "M2250 Memory"}, 
-	{HPHW_MEMORY, 0x092, 0x00009, 0x00, "M2500 Memory"}, 
-	{HPHW_MEMORY, 0x093, 0x00009, 0x00, "Sonata 440 Memory"}, 
-	{HPHW_MEMORY, 0x094, 0x00009, 0x00, "Sonata 360 Memory"}, 
-	{HPHW_MEMORY, 0x095, 0x00009, 0x00, "Rhapsody 440 Memory"}, 
-	{HPHW_MEMORY, 0x096, 0x00009, 0x00, "Rhapsody 360 Memory"}, 
-	{HPHW_MEMORY, 0x097, 0x00009, 0x00, "Raven W 360 Memory"}, 
-	{HPHW_MEMORY, 0x098, 0x00009, 0x00, "Halfdome W 440 Memory"}, 
-	{HPHW_MEMORY, 0x099, 0x00009, 0x00, "Rhapsody DC- 440 Memory"}, 
-	{HPHW_MEMORY, 0x09A, 0x00009, 0x00, "Rhapsody DC- 360 Memory"}, 
-	{HPHW_MEMORY, 0x09B, 0x00009, 0x00, "Crescendo Memory"}, 
+	{HPHW_MEMORY, 0x066, 0x00009, 0x00, "715/160 L2 Upgrade"},
 	{HPHW_OTHER, 0x004, 0x00030, 0x00, "Master"}, 
 	{HPHW_OTHER, 0x004, 0x00034, 0x00, "Slave"}, 
 	{HPHW_OTHER, 0x004, 0x00038, 0x00, "EDU"}, 
 	{HPHW_OTHER, 0x004, 0x00049, 0x00, "LGB Control"}, 
-        {0, }			/* leave the last entry empty ! */
+	{HPHW_FAULTY, 0, }  /* Special Marker for last entry */
 };
 
 
@@ -1318,7 +1195,7 @@
 	unsigned short model;
 	unsigned short mask;
 	enum cpu_type cpu;
-} hp_cpu_type_mask_list[] = {
+} hp_cpu_type_mask_list[] __initdata = {
 
 	{ 0x0000, 0x0ff0, pcx    },  /* 0x0000 - 0x000f */
 	{ 0x0048, 0x0ff0, pcxl   },  /* 0x0040 - 0x004f */
@@ -1350,8 +1227,10 @@
 	{ 0x0592, 0x0fff, pcxt_  },  /* 0x0592 - 0x0592 */
 	{ 0x0593, 0x0fff, pcxu   },  /* 0x0593 - 0x0593 */
 	{ 0x0594, 0x0ffc, pcxu   },  /* 0x0594 - 0x0597 */
-	{ 0x0598, 0x0ffc, pcxu   },  /* 0x0598 - 0x059b */
-	{ 0x059c, 0x0ffe, pcxu_  },  /* 0x059c - 0x059d */
+	{ 0x0598, 0x0ffe, pcxu_  },  /* 0x0598 - 0x0599 */
+	{ 0x059a, 0x0ffe, pcxu   },  /* 0x059a - 0x059b */
+	{ 0x059c, 0x0fff, pcxu   },  /* 0x059c - 0x059c */
+	{ 0x059d, 0x0fff, pcxu_  },  /* 0x059d - 0x059d */
 	{ 0x059e, 0x0fff, pcxt_  },  /* 0x059e - 0x059e */
 	{ 0x059f, 0x0fff, pcxu   },  /* 0x059f - 0x059f */
 	{ 0x05a0, 0x0ffe, pcxt_  },  /* 0x05a0 - 0x05a1 */
@@ -1370,7 +1249,27 @@
 	{ 0x05ba, 0x0fff, pcxu_  },  /* 0x05ba - 0x05ba */
 	{ 0x05bb, 0x0fff, pcxw   },  /* 0x05bb - 0x05bb */
 	{ 0x05bc, 0x0ffc, pcxw   },  /* 0x05bc - 0x05bf */
-	{ 0x05c0, 0x0fc0, pcxw   },  /* 0x05c0 - 0x05ff */
+	{ 0x05c0, 0x0ffc, pcxw 	 },  /* 0x05c0 - 0x05c3 */
+	{ 0x05c4, 0x0ffe, pcxw 	 },  /* 0x05c4 - 0x05c5 */
+	{ 0x05c6, 0x0fff, pcxw 	 },  /* 0x05c6 - 0x05c6 */
+	{ 0x05c7, 0x0fff, pcxw_  },  /* 0x05c7 - 0x05c7 */
+	{ 0x05c8, 0x0ffc, pcxw 	 },  /* 0x05c8 - 0x05cb */
+	{ 0x05cc, 0x0ffe, pcxw 	 },  /* 0x05cc - 0x05cd */
+	{ 0x05ce, 0x0ffe, pcxw_  },  /* 0x05ce - 0x05cf */
+	{ 0x05d0, 0x0ffc, pcxw_  },  /* 0x05d0 - 0x05d3 */
+	{ 0x05d4, 0x0ffe, pcxw_  },  /* 0x05d4 - 0x05d5 */
+	{ 0x05d6, 0x0fff, pcxw 	 },  /* 0x05d6 - 0x05d6 */
+	{ 0x05d7, 0x0fff, pcxw_  },  /* 0x05d7 - 0x05d7 */
+	{ 0x05d8, 0x0ffc, pcxw_  },  /* 0x05d8 - 0x05db */
+	{ 0x05dc, 0x0ffe, pcxw2  },  /* 0x05dc - 0x05dd */
+	{ 0x05de, 0x0fff, pcxw_  },  /* 0x05de - 0x05de */
+	{ 0x05df, 0x0fff, pcxw2  },  /* 0x05df - 0x05df */
+	{ 0x05e0, 0x0ffc, pcxw2  },  /* 0x05e0 - 0x05e3 */
+	{ 0x05e4, 0x0fff, pcxw2  },  /* 0x05e4 - 0x05e4 */
+	{ 0x05e5, 0x0fff, pcxw_  },  /* 0x05e5 - 0x05e5 */
+	{ 0x05e6, 0x0ffe, pcxw2  },  /* 0x05e6 - 0x05e7 */
+	{ 0x05e8, 0x0ff8, pcxw2  },  /* 0x05e8 - 0x05ef */
+	{ 0x05f0, 0x0ff0, pcxw2  },  /* 0x05f0 - 0x05ff */
 	{ 0x0600, 0x0ff0, pcxl   },  /* 0x0600 - 0x060f */
 	{ 0x0610, 0x0ff0, pcxl   },  /* 0x0610 - 0x061f */
 	{ 0x0000, 0x0000, pcx    }	/* terminate table */
@@ -1386,36 +1285,51 @@
 	[pcxu]	{ "PA8000 (PCX-U)",	"2.0" },
 	[pcxu_]	{ "PA8200 (PCX-U+)",	"2.0" },
 	[pcxw]	{ "PA8500 (PCX-W)",	"2.0" },
-	[pcxw_]	{ "PA8600 (PCX-W+)",	"2.0" }
+	[pcxw_]	{ "PA8600 (PCX-W+)",	"2.0" },
+	[pcxw2]	{ "PA8700 (PCX-W2)",	"2.0" }
 };
 
-char *parisc_getHWtype(unsigned short hw_type)
-{
-	if (hw_type <= HPHW_CIO) {
-		return hw_type_name[hw_type];
-	} else {
-		return "Unknown Type";
-	}
-}
-
-char *parisc_getHWdescription(unsigned short hw_type, unsigned long hversion,
-		unsigned long sversion)
+const char * __init
+parisc_hardware_description(struct parisc_device_id *id)
 {
 	struct hp_hardware *listptr;
 	
-	for (listptr = hp_hardware_list; listptr->name; listptr++) {
-		if ((listptr->hw_type==hw_type) &&
-				(listptr->hversion==hversion) &&
-				(listptr->sversion==sversion)){
+	for (listptr = hp_hardware_list; listptr->hw_type != HPHW_FAULTY; listptr++) {
+		if ((listptr->hw_type == id->hw_type) &&
+				(listptr->hversion == id->hversion) &&
+				(listptr->sversion == id->sversion)){
 			return listptr->name;
 		}
 	}
+
+	/*
+	 * ok, the above hardware table isn't complete, and we haven't found
+	 * our device in this table. So let's now try to find a generic name
+	 * to describe the given hardware...
+	 */
+	switch (id->hw_type) {
+		case HPHW_NPROC:
+			return "Unknown machine";
+
+		case HPHW_A_DIRECT:
+			switch (id->sversion) {
+				case 0x0D: return "MUX port";
+				case 0x0E: return "RS-232 port";
+			}
+			break;
+			
+		case HPHW_MEMORY:
+			return "Memory";
+			
+	}
+	
 	return "unknown device";
 }
 
 
 /* Interpret hversion (ret[0]) from PDC_MODEL(4)/PDC_MODEL_INFO(0) */
-enum cpu_type parisc_get_cpu_type(unsigned long hversion)
+enum cpu_type __init
+parisc_get_cpu_type(unsigned long hversion)
 {
 	struct hp_cpu_type_mask *ptr;
 	unsigned short model = ((unsigned short) (hversion)) >> 4;
@@ -1424,23 +1338,8 @@
 		if (ptr->model == (model & ptr->mask))
 			return ptr->cpu;
 	}
-	panic("parisc_get_cpu_type() could not identify CPU type\n");
+	panic("could not identify CPU type\n");
 
 	return pcx;	/* not reached: */
 }
 
-
-struct hp_hardware *parisc_get_reference(unsigned short hw_type,
-		unsigned long hversion, unsigned long sversion)
-{
-	struct hp_hardware *listptr = hp_hardware_list;
-
-	for (listptr = hp_hardware_list; listptr->name; listptr++) {
-		if ((listptr->hw_type == hw_type) &&
-				(listptr->hversion == hversion) &&
-				(listptr->sversion == sversion)) {
-			return listptr;
-		}
-	}
-	return NULL;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/head.S linux-bk/arch/parisc/kernel/head.S
--- linux-2.4.19/arch/parisc/kernel/head.S	2000-12-05 20:29:39.000000000 +0000
+++ linux-bk/arch/parisc/kernel/head.S	2002-08-17 00:49:12.000000000 +0000
@@ -8,17 +8,14 @@
  * Copyright 1999 SuSE GmbH (Philipp Rumpf)
  * Copyright 1999 Philipp Rumpf (prumpf@tux.org)
  *
- * Initial Version 04-23-1999 by Helge Deller (helge.deller@ruhr-uni-bochum.de)
+ * Initial Version 04-23-1999 by Helge Deller <deller@gmx.de>
  */
 
+#include <linux/autoconf.h>	/* for CONFIG_SMP */
 
 #include <asm/offset.h>
 #include <asm/psw.h>
 
-#define __ASSEMBLY__
-/*********
-#include <asm/pdc.h>
-*********/
 #include <asm/assembly.h>
 #include <asm/pgtable.h>
 
@@ -36,6 +33,15 @@
 	.export __setup_end
 __setup_end:
 
+	.data
+
+	.export boot_args
+boot_args:
+	.word 0 /* arg0 */
+	.word 0 /* arg1 */
+	.word 0 /* arg2 */
+	.word 0 /* arg3 */
+
 	.text
 	.align	4	
 	.import init_task_union,data
@@ -52,43 +58,129 @@
 	.callinfo
 
 	/* Make sure sr4-sr7 are set to zero for the kernel address space */
-
-	mtsp		%r0,%sr4
-	mtsp		%r0,%sr5
-	mtsp		%r0,%sr6
-	mtsp		%r0,%sr7
+	mtsp	%r0,%sr4
+	mtsp	%r0,%sr5
+	mtsp	%r0,%sr6
+	mtsp	%r0,%sr7
+
+	/* Clear BSS (shouldn't the boot loader do this?) */
+
+	.import _edata,data
+	.import _end,data
+
+	ldil            L%PA(_edata),%r3
+	ldo             R%PA(_edata)(%r3),%r3
+	ldil            L%PA(_end),%r4
+	ldo             R%PA(_end)(%r4),%r4
+$bss_loop:
+	cmpb,<<,n       %r3,%r4,$bss_loop
+	stb,ma          %r0,1(%r3)
+
+	/* Save away the arguments the boot loader passed in (32 bit args) */
+
+	ldil            L%PA(boot_args),%r1
+	ldo             R%PA(boot_args)(%r1),%r1
+	stw,ma          %arg0,4(%r1)
+	stw,ma          %arg1,4(%r1)
+	stw,ma          %arg2,4(%r1)
+	stw,ma          %arg3,4(%r1)
 
 	/* Initialize startup VM. Just map first 8 MB of memory */
-
 	ldil		L%PA(pg0),%r1
 	ldo		R%PA(pg0)(%r1),%r1
 	ldo		_PAGE_TABLE(%r1),%r3
+
 	ldil		L%PA(swapper_pg_dir),%r4
 	ldo		R%PA(swapper_pg_dir)(%r4),%r4
 	mtctl		%r4,%cr24	/* Initialize kernel root pointer */
 	mtctl		%r4,%cr25	/* Initialize user root pointer */
-	stw		%r3,0xc00(%r4)	/* Hardwired 0xc0000000 kernel vaddr start */
+
+#if (__PAGE_OFFSET != 0x10000000UL)
+Error! Code below (the next two stw's) needs to be changed
+#endif
+
+	stw             %r3,0x100(%r4)  /* Hardwired 0x1... kernel Vaddr start*/
 	ldo		0x1000(%r3),%r3
-	stw		%r3,0xc04(%r4)
-	ldo		_PAGE_KERNEL(%r0),%r3 /* Hardwired 0x0 phys addr start */
+	stw             %r3,0x104(%r4)
+	ldo		_PAGE_KERNEL(%r0),%r3 /* Hardwired 0 phys addr start */
 $pgt_fill_loop:
 	stwm		%r3,4(%r1)
 	ldo		0x1000(%r3),%r3
 	bb,>=		%r3,8,$pgt_fill_loop
 	nop
 
+
+	/* Load the return address...er...crash 'n burn */
+	copy		%r0,%r2
+
+	/* And the RFI Target address too */
+	ldil            L%start_kernel,%r11
+	ldo             R%start_kernel(%r11),%r11
+
+	/* And the initial task pointer */
+
+	ldil            L%init_task_union,%r6
+	ldo             R%init_task_union(%r6),%r6
+	mtctl           %r6,%cr30
+
+	/* And the stack pointer too */
+
+	ldo             TASK_SZ_ALGN(%r6),%sp
+
+	/* And the interrupt stack */
+
+	ldil            L%interrupt_stack,%r6
+	ldo             R%interrupt_stack(%r6),%r6
+	mtctl           %r6,%cr31
+
+#ifdef CONFIG_SMP
+	/* Set the smp rendevous address into page zero.
+	** It would be safer to do this in init_smp_config() but
+	** it's just way easier to deal with here because
+	** of 64-bit function ptrs and the address is local to this file.
+	*/
+	ldil		L%PA(smp_slave_stext),%r10
+	ldo		R%PA(smp_slave_stext)(%r10),%r10
+	stw		%r10,0x10(%r0)	/* MEM_RENDEZ */
+	stw		%r0,0x28(%r0)	/* MEM_RENDEZ_HI - assume addr < 4GB */
+
+	/* FALLTHROUGH */
+	.procend
+
+	/*
+	** Code Common to both Monarch and Slave processors.
+	** Entry:
+	**    %r11 must contain RFI target address.
+	**    %r25/%r26 args to pass to target function
+	**    %r2  in case rfi target decides it didn't like something
+	**
+	** Caller must init: SR4-7, %sp, %r10, %cr24/25, 
+	*/
+common_stext:
+	.proc
+	.callinfo
+#else
+	/* Clear PDC entry point - we won't use it */
+	stw		%r0,0x10(%r0)	/* MEM_RENDEZ */
+	stw		%r0,0x28(%r0)	/* MEM_RENDEZ_HI */
+#endif
+
+	/* PARANOID: clear user scratch/user space SR's */
+	mtsp	%r0,%sr0
+	mtsp	%r0,%sr1
+	mtsp	%r0,%sr2
+	mtsp	%r0,%sr3
+
+	/* Initialize Protection Registers */
+	mtctl	%r0,%cr8
+	mtctl	%r0,%cr9
+	mtctl	%r0,%cr12
+	mtctl	%r0,%cr13
+
 	/* Initialize the global data pointer */
 	ldil		L%$global$,%dp
 	ldo		R%$global$(%dp),%dp
-	
-	/* And the stack pointer, physical too */
-	ldil		L%init_task_union+TASK_SZ_ALGN,%sp
-	ldo		R%init_task_union+TASK_SZ_ALGN(%sp),%sp
-
-	/* we need this to take interruptions directly after the rfi below */
-	/* (which we need for PA2.0 boxes) */
-	mtctl		%r0, %cr30
-	
+
 	/*
 	 * Set up our interrupt table.  HPMCs might not work after this! 
 	 *
@@ -96,7 +188,6 @@
 	 * following short sequence of instructions can determine this
 	 * (without being illegal on a PA1.1 machine).
 	 */
-	
 	ldi		32,%r10
 	mtctl		%r10,%cr11
 	.level 2.0
@@ -114,30 +205,30 @@
 $install_iva:
 	mtctl		%r10,%cr14
 
-	/* Disable (most) interruptions */
-	mtsm		%r0			
-	
+	/* Disable Q bit so we can load the iia queue */
+	rsm            PSW_SM_Q,%r0
+
 	/* kernel PSW:
-	 *  - no interruptions except for HPMC and TOC (which are handled by PDC)
+	 *  - no interruptions except HPMC and TOC (which are handled by PDC)
 	 *  - Q bit set (IODC / PDC interruptions)
 	 *  - big-endian
 	 *  - virtually mapped
 	 */
-
 	ldil		L%KERNEL_PSW,%r10
 	ldo		R%KERNEL_PSW(%r10),%r10
 	mtctl		%r10,%ipsw
-	
-	/* Set the space pointers for the post-RFI world */
-	mtctl		%r0,%cr17		/* Clear two-level IIA Space Queue */
-	mtctl		%r0,%cr17		/*    effectively setting kernel space. */
-
-	/* And the return address(es) too */
-	ldil		L%start_parisc,%r10
-	ldo		R%start_parisc(%r10),%r10
-	mtctl		%r10,%cr18
-	ldo		4(%r10),%r10
-	mtctl		%r10,%cr18
+
+	/* Set the space pointers for the post-RFI world
+	** Clear the two-level IIA Space Queue, effectively setting
+	** Kernel space.
+	*/
+	mtctl		%r0,%cr17
+	mtctl		%r0,%cr17
+
+	/* Load RFI target into PC queue */
+	mtctl		%r11,%cr18
+	ldo		4(%r11),%r11
+	mtctl		%r11,%cr18
 
 	/* Jump to hyperspace */
 	rfi
@@ -145,6 +236,71 @@
 
 	.procend
 
+#ifdef CONFIG_SMP
+
+	.import smp_init_current_idle_task,data
+	.import	smp_callin,code
+
+smp_callin_rtn:
+        .proc
+	.callinfo
+	break	1,1		/*  Break if returned from start_secondary */
+	nop
+	nop
+        .procend
+
+/***************************************************************************
+*
+* smp_slave_stext is executed by all non-monarch Processors when the Monarch
+* pokes the slave CPUs in smp.c:smp_boot_cpus().
+*
+* Once here, registers values are initialized in order to branch to virtual
+* mode. Once all available/eligible CPUs are in virtual mode, all are
+* released and start out by executing their own idle task.
+*****************************************************************************/
+
+
+smp_slave_stext:
+        .proc
+	.callinfo
+
+	/*
+	** Initialize Space registers
+	*/
+	mtsp	   %r0,%sr4
+	mtsp	   %r0,%sr5
+	mtsp	   %r0,%sr6
+	mtsp	   %r0,%sr7
+
+	/*  Initialize the SP - monarch sets up smp_init_current_idle_task */
+	ldil		L%PA(smp_init_current_idle_task),%sp
+	ldo		R%PA(smp_init_current_idle_task)(%sp),%sp
+	ldw		0(%sp),%sp	/* load task address */
+	mtctl           %sp,%cr30       /* store in cr30 */
+	addil		L%TASK_SZ_ALGN,%sp	/* stack is above task */
+	ldo		R%TASK_SZ_ALGN(%r1),%sp
+
+	/* point CPU to kernel page tables */
+	ldil		L%PA(swapper_pg_dir),%r4
+	ldo		R%PA(swapper_pg_dir)(%r4),%r4
+	mtctl		%r4,%cr24	/* Initialize kernel root pointer */
+	mtctl		%r4,%cr25	/* Initialize user root pointer */
+
+	/* Load RFI *return* address in case smp_callin bails */
+	ldil		L%smp_callin_rtn,%r2
+	ldo		R%smp_callin_rtn(%r2),%r2
+
+	/* Load RFI target address.  */
+	ldil		L%smp_callin,%r11
+	ldo		R%smp_callin(%r11),%r11
+	
+	/* ok...common code can handle the rest */
+	b		common_stext
+	nop
+
+	.procend
+#endif /* CONFIG_SMP */
+
 	.data
 
 	.align	4
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/head64.S linux-bk/arch/parisc/kernel/head64.S
--- linux-2.4.19/arch/parisc/kernel/head64.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/parisc/kernel/head64.S	2002-08-17 00:49:07.000000000 +0000
@@ -0,0 +1,333 @@
+/*
+ *
+ * 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) 1999 by Helge Deller
+ * Copyright 1999 SuSE GmbH (Philipp Rumpf)
+ * Copyright 1999 Philipp Rumpf (prumpf@tux.org)
+ * Copyright 2000 Hewlett Packard (Paul Bame, bame@puffin.external.hp.com)
+ * Copyright (C) 2001 Grant Grundler (Hewlett Packard)
+ *
+ * Initial Version 04-23-1999 by Helge Deller <deller@gmx.de>
+ */
+
+
+#include <linux/autoconf.h>	/* for CONFIG_SMP */
+
+#include <asm/offset.h>
+#include <asm/psw.h>
+
+#include <asm/assembly.h>
+#include <asm/pgtable.h>
+#include <asm/pdc.h>		/* for PDC_PSW defines */
+
+
+	.level 2.0
+
+	.section	.initcall.init
+	.align		4
+	.export __initcall_start
+__initcall_start:
+	.export __initcall_end
+__initcall_end:
+	.export __setup_start
+__setup_start:
+	.export __setup_end
+__setup_end:
+
+	.data
+
+	.export boot_args
+boot_args:
+	.word 0 /* arg0 */
+	.word 0 /* arg1 */
+	.word 0 /* arg2 */
+	.word 0 /* arg3 */
+
+	.text
+	.align	4	
+
+	.export stext
+	.export _stext,data		/* Kernel want it this way! */
+_stext:
+stext:
+	.proc
+	.callinfo
+
+	/* Make sure sr4-sr7 are set to zero for the kernel address space */
+	mtsp	%r0,%sr4
+	mtsp	%r0,%sr5
+	mtsp	%r0,%sr6
+	mtsp	%r0,%sr7
+
+	/* Clear BSS (shouldn't the boot loader do this?) */
+
+	.import _edata,data
+	.import _end,data
+
+	ldil            L%PA(_edata),%r3
+	ldo             R%PA(_edata)(%r3),%r3
+	ldil            L%PA(_end),%r4
+	ldo             R%PA(_end)(%r4),%r4
+$bss_loop:
+	cmpb,<<,n       %r3,%r4,$bss_loop
+	stb,ma          %r0,1(%r3)
+
+	/* Save away the arguments the boot loader passed in (32 bit args) */
+
+	ldil            L%PA(boot_args),%r1
+	ldo             R%PA(boot_args)(%r1),%r1
+	stw,ma          %arg0,4(%r1)
+	stw,ma          %arg1,4(%r1)
+	stw,ma          %arg2,4(%r1)
+	stw,ma          %arg3,4(%r1)
+
+	/* Initialize startup VM. Just map first 8 MB of memory */
+
+	ldil		L%PA(pg0),%r1
+	ldo		R%PA(pg0)(%r1),%r1
+
+	ldil		L%PA(pmd0),%r5
+	ldo		R%PA(pmd0)(%r5),%r5
+	ldo		_PAGE_TABLE(%r5),%r3
+
+	ldil		L%PA(swapper_pg_dir),%r4
+	ldo		R%PA(swapper_pg_dir)(%r4),%r4
+
+	mtctl		%r4,%cr24	/* Initialize kernel root pointer */
+	mtctl		%r4,%cr25	/* Initialize user root pointer */
+
+#if (__PAGE_OFFSET != 0x10000000UL)
+Error! Code below (the next five std's) needs to be changed
+#endif
+
+	std             %r3,0x00(%r4)   /* Hardwired 0x1... kernel Vaddr start*/
+
+	ldo		_PAGE_TABLE(%r1),%r3
+	std             %r3,0x400(%r5)  /* Hardwired 0x1... kernel Vaddr start*/
+	ldo		0x1000(%r3),%r3
+	std             %r3,0x408(%r5)
+	ldo		0x1000(%r3),%r3
+	std             %r3,0x410(%r5)
+	ldo		0x1000(%r3),%r3
+	std             %r3,0x418(%r5)
+
+	ldo		_PAGE_KERNEL(%r0),%r3 /* Hardwired 0 phys addr start */
+$pgt_fill_loop:
+	std,ma		%r3,8(%r1)
+	ldo		0x1000(%r3),%r3
+	bb,>=		%r3,8,$pgt_fill_loop
+	nop
+
+	/* And the RFI Target address too */
+	load32          start_kernel, %r11
+
+	/* And the stack pointer too */
+	load32		PA(init_task_union+TASK_SZ_ALGN),%sp
+
+	/* And the initial task pointer */
+
+	load32          init_task_union,%r6
+	mtctl           %r6,%cr30
+
+	/* And the interrupt stack */
+
+	load32          interrupt_stack,%r6
+	mtctl           %r6,%cr31
+
+	/* Act like PDC just called us - that's how slave CPUs enter */
+#define MEM_PDC_LO 0x388
+#define MEM_PDC_HI 0x35C
+	ldw		MEM_PDC_LO(%r0),%r3
+	ldw		MEM_PDC_HI(%r0),%r6
+	depd		%r6, 31, 32, %r3	/* move to upper word */
+
+#ifdef CONFIG_SMP
+	/* Set the smp rendevous address into page zero.
+	** It would be safer to do this in init_smp_config() but
+	** it's just way easier to deal with here because
+	** of 64-bit function ptrs and the address is local to this file.
+	*/
+	ldil		L%PA(smp_slave_stext),%r10
+	ldo		R%PA(smp_slave_stext)(%r10),%r10
+	stw		%r10,0x10(%r0)	/* MEM_RENDEZ */
+	stw		%r0,0x28(%r0)	/* MEM_RENDEZ_HI - assume addr < 4GB */
+
+	/* FALLTHROUGH */
+	.procend
+
+	/*
+	** Code Common to both Monarch and Slave processors.
+	** Entry:
+	**    %r3	PDCE_PROC address
+	**    %r11	RFI target address.
+	**
+	** Caller must init: SR4-7, %sp, %r10, %cr24/25, 
+	*/
+common_stext:
+	.proc
+	.callinfo
+#else /* CONFIG_SMP */
+	/* Clear PDC's CPU handoff address - we won't use it */
+	stw		%r0,0x10(%r0)	/* MEM_RENDEZ */
+	stw		%r0,0x28(%r0)	/* MEM_RENDEZ_HI */
+#endif /* CONFIG_SMP */
+
+	/* Save the rfi target address */
+	std		%r11,  TASK_PT_GR11-TASK_SZ_ALGN(%sp)
+
+#ifndef CONFIG_PDC_NARROW
+	/* Switch to wide mode; Superdome doesn't support narrow PDC
+	** calls.
+	*/
+1:	mfia		%rp		/* clear upper part of pcoq */
+	ldo		2f-1b(%rp),%rp
+	depdi		0,31,32,%rp
+	bv		(%rp)
+	ssm		PSW_SM_W,%r0
+2:
+#endif /* CONFIG_PDC_NARROW */
+
+	/* Set Wide mode as the "Default" (eg for traps)
+	** First trap occurs *right* after (or part of) rfi for slave CPUs.
+	** Someday, palo might not do this for the Monarch either.
+	*/
+
+	ldo		PDC_PSW(%r0),%arg0		/* 21 */
+	ldo		PDC_PSW_SET_DEFAULTS(%r0),%arg1	/* 2 */
+	ldo		PDC_PSW_WIDE_BIT(%r0),%arg2	/* 2 */
+
+	load32		PA(stext_pdc_ret), %rp
+
+	bv		(%r3)
+	copy		%r0,%arg3
+
+stext_pdc_ret:
+	/* restore rfi target address*/
+	ldd		TASK_PT_GR11-TASK_SZ_ALGN(%sp), %r11
+
+	/* PARANOID: clear user scratch/user space SR's */
+	mtsp	%r0,%sr0
+	mtsp	%r0,%sr1
+	mtsp	%r0,%sr2
+	mtsp	%r0,%sr3
+
+	/* Initialize Protection Registers */
+	mtctl	%r0,%cr8
+	mtctl	%r0,%cr9
+	mtctl	%r0,%cr12
+	mtctl	%r0,%cr13
+
+	/* Prepare to RFI! Man all the cannons! */
+	tovirt_r1       %sp
+
+	/* Initialize the global data pointer */
+	load32		__gp,%dp
+
+	/* Set up our interrupt table.  HPMCs might not work after this! */
+	ldil		L%PA(fault_vector_20),%r10
+	ldo		R%PA(fault_vector_20)(%r10),%r10
+	mtctl		%r10,%cr14
+
+	b		aligned_rfi
+	nop
+
+	/* the magic spell */
+	.align          256
+aligned_rfi:
+	ssm		0,0
+	nop		/* 1 */
+	nop		/* 2 */
+	nop		/* 3 */
+	nop		/* 4 */
+	nop		/* 5 */
+	nop		/* 6 */
+	nop		/* 7 */
+	nop		/* 8 */
+
+	/* turn off troublesome PSW bits */
+	rsm		PSW_Q+PSW_I+PSW_D+PSW_P+PSW_R, %r0
+
+	/* kernel PSW:
+	 *  - no interruptions except HPMC and TOC (which are handled by PDC)
+	 *  - Q bit set (IODC / PDC interruptions)
+	 *  - big-endian
+	 *  - virtually mapped
+	 */
+	load32		KERNEL_PSW,%r10
+	mtctl		%r10,%ipsw
+
+	/* Set the space pointers for the post-RFI world
+	** Clear the two-level IIA Space Queue, effectively setting
+	** Kernel space.
+	*/
+	mtctl		%r0,%cr17
+	mtctl		%r0,%cr17
+
+	/* Load RFI target into PC queue */
+	mtctl		%r11,%cr18
+	ldo		4(%r11),%r11
+	mtctl		%r11,%cr18
+
+	/* Jump to hyperspace */
+	rfi
+	nop
+
+	.procend
+
+
+#ifdef CONFIG_SMP
+
+	.import smp_init_current_idle_task,data
+	.import	smp_callin,code
+
+/***************************************************************************
+*
+* smp_slave_stext is executed by all non-monarch Processors when the Monarch
+* pokes the slave CPUs in smp.c:smp_boot_cpus().
+*
+* Once here, registers values are initialized in order to branch to virtual
+* mode. Once all available/eligible CPUs are in virtual mode, all are
+* released and start out by executing their own idle task.
+*****************************************************************************/
+
+
+smp_slave_stext:
+        .proc
+	.callinfo
+
+	/*
+	** Initialize Space registers
+	*/
+	mtsp	   %r0,%sr4
+	mtsp	   %r0,%sr5
+	mtsp	   %r0,%sr6
+	mtsp	   %r0,%sr7
+
+	/*  Initialize the SP - monarch sets up smp_init_current_idle_task */
+	load32		PA(smp_init_current_idle_task),%sp
+	ldd		0(%sp),%sp	/* load task address */
+	mtctl           %sp,%cr30       /* store in cr30 */
+	ldo             TASK_SZ_ALGN(%sp),%sp
+	tophys_r1       %sp
+
+	/* point CPU to kernel page tables */
+	load32		PA(swapper_pg_dir),%r4
+	mtctl		%r4,%cr24	/* Initialize kernel root pointer */
+	mtctl		%r4,%cr25	/* Initialize user root pointer */
+
+	/* Setup PDCE_PROC entry */
+	copy		%arg0,%r3
+
+	/* Load RFI target address.  */
+	load32		smp_callin, %r11
+	
+	/* ok...common code can handle the rest */
+	b		common_stext
+	nop
+
+	.procend
+#endif /* CONFIG_SMP */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/hpmc.S linux-bk/arch/parisc/kernel/hpmc.S
--- linux-2.4.19/arch/parisc/kernel/hpmc.S	2000-12-05 20:29:39.000000000 +0000
+++ linux-bk/arch/parisc/kernel/hpmc.S	2002-08-17 00:49:00.000000000 +0000
@@ -43,7 +43,6 @@
 	.level		1.1
 	.data
 
-#define __ASSEMBLY__
 #include <asm/assembly.h>
 #include <asm/pdc.h>
 
@@ -262,12 +261,10 @@
 	mtsp	%r0, %sr6
 	mtsp	%r0, %sr7
 
-	tovirt  %r30        /* make sp virtual */
+	tovirt_r1 %r30      /* make sp virtual */
 
 	rsm 8,%r0           /* Clear Q bit */
-	ldi     1,%r1
-	mtctl   %r1,%cr29   /* Set trap code to "1" for HPMC */
-	mtctl   %r0,%cr30   /* Force interruptions to use hpmc stack */
+	ldi     1,%r8       /* Set trap code to "1" for HPMC */
 	ldil    L%PA(intr_save), %r1
 	ldo     R%PA(intr_save)(%r1), %r1
 	be      0(%sr7,%r1)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/init_task.c linux-bk/arch/parisc/kernel/init_task.c
--- linux-2.4.19/arch/parisc/kernel/init_task.c	2001-09-17 22:29:09.000000000 +0000
+++ linux-bk/arch/parisc/kernel/init_task.c	2002-08-17 00:48:47.000000000 +0000
@@ -18,10 +18,11 @@
  * way process stacks are handled. This is done by having a special
  * "init_task" linker map entry..
  */
+unsigned char interrupt_stack[ISTACK_SIZE] __attribute__ ((section("init_istack"), aligned(4096)));
 union task_union init_task_union 
 	__attribute__((section("init_task"), aligned(4096))) = { INIT_TASK(init_task_union.task) };
 
-unsigned long swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((aligned(4096))) = { 0, };
+pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((aligned(4096))) = { {0}, };
 #ifdef __LP64__
 unsigned long pmd0[PTRS_PER_PMD] __attribute__ ((aligned(4096))) = { 0, };
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/inventory.c linux-bk/arch/parisc/kernel/inventory.c
--- linux-2.4.19/arch/parisc/kernel/inventory.c	2000-12-06 19:46:39.000000000 +0000
+++ linux-bk/arch/parisc/kernel/inventory.c	2002-08-17 00:48:51.000000000 +0000
@@ -1,40 +1,157 @@
-
-/* Copyright (c) 1999 The Puffin Group */
-/* Written by David Kennedy and Alex deVries */
+/*
+ * inventory.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Copyright (c) 1999 The Puffin Group (David Kennedy and Alex deVries)
+ * Copyright (c) 2001 Matthew Wilcox for Hewlett-Packard
+ *
+ * These are the routines to discover what hardware exists in this box.
+ * This task is complicated by there being 3 different ways of
+ * performing an inventory, depending largely on the age of the box.
+ * The recommended way to do this is to check to see whether the machine
+ * is a `Snake' first, then try System Map, then try PAT.  We try System
+ * Map before checking for a Snake -- this probably doesn't cause any
+ * problems, but...
+ */
 
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/pdc.h>
+#include <asm/processor.h>
+#include <asm/page.h>
 
 /*
 ** Debug options
-**    DEBUG_PAT	Dump details which PDC PAT provides about ranges/devices.
+** DEBUG_PAT Dump details which PDC PAT provides about ranges/devices.
 */
 #undef DEBUG_PAT
 
-extern char *parisc_getHWtype(unsigned short hw_type);
+int pdc_type = PDC_TYPE_ILLEGAL;
+
+void __init setup_pdc(void)
+{
+	long status;
+	unsigned int bus_id;
+	struct pdc_system_map_mod_info module_result;
+	struct pdc_module_path module_path;
+	struct pdc_model model;
+#ifdef __LP64__
+	struct pdc_pat_cell_num cell_info;
+#endif
 
-extern struct hp_device * register_module(void *hpa);
-extern void print_devices(char * buf);
+	/* Determine the pdc "type" used on this machine */
 
+	printk(KERN_INFO "Determining PDC firmware type: ");
 
-int pdc_hpa_processor(void *address);
+	status = pdc_system_map_find_mods(&module_result, &module_path, 0);
+	if (status == PDC_OK) {
+		pdc_type = PDC_TYPE_SYSTEM_MAP;
+		printk("System Map.\n");
+		return;
+	}
 
-#ifndef __LP64__ 
-static	u8 iodc_data[32] __attribute__ ((aligned (64)));
-static	struct pdc_model model __attribute__ ((aligned (8)));
+	/*
+	 * If the machine doesn't support PDC_SYSTEM_MAP then either it
+	 * is a pdc pat box, or it is an older box. All 64 bit capable
+	 * machines are either pdc pat boxes or they support PDC_SYSTEM_MAP.
+	 */
+
+	/*
+	 * TODO: We should test for 64 bit capability and give a
+	 * clearer message.
+	 */
+
+#ifdef __LP64__
+	status = pdc_pat_cell_get_number(&cell_info);
+	if (status == PDC_OK) {
+		pdc_type = PDC_TYPE_PAT;
+		printk("64 bit PAT.\n");
+		return;
+	}
 #endif
-static	unsigned long pdc_result[32] __attribute__ ((aligned (8))) = {0,0,0,0};
-static	struct pdc_hpa processor_hpa __attribute__ ((aligned (8)));
-static	struct pdc_system_map module_result __attribute__ ((aligned (8)));
-static	struct pdc_module_path module_path __attribute__ ((aligned (8)));
+
+	/* Check the CPU's bus ID.  There's probably a better test.  */
+
+	status = pdc_model_info(&model);
+
+	bus_id = (model.hversion >> (4 + 7)) & 0x1f;
+
+	switch (bus_id) {
+	case 0x4:		/* 720, 730, 750, 735, 755 */
+	case 0x6:		/* 705, 710 */
+	case 0x7:		/* 715, 725 */
+	case 0x8:		/* 745, 747, 742 */
+	case 0xA:		/* 712 and similiar */
+	case 0xC:		/* 715/64, at least */
+
+		pdc_type = PDC_TYPE_SNAKE;
+		printk("Snake.\n");
+		return;
+
+	default:		/* Everything else */
+
+		printk("Unsupported.\n");
+		panic("If this is a 64-bit machine, please try a 64-bit kernel.\n");
+	}
+}
+
+#define PDC_PAGE_ADJ_SHIFT (PAGE_SHIFT - 12) /* pdc pages are always 4k */
+
+static void __init
+set_pmem_entry(physmem_range_t *pmem_ptr, unsigned long start,
+	       unsigned long pages4k)
+{
+	/* Rather than aligning and potentially throwing away
+	 * memory, we'll assume that any ranges are already
+	 * nicely aligned with any reasonable page size, and
+	 * panic if they are not (it's more likely that the
+	 * pdc info is bad in this case).
+	 */
+
+	if (   ((start & (PAGE_SIZE - 1)) != 0)
+	    || ((pages4k & ((1UL << PDC_PAGE_ADJ_SHIFT) - 1)) != 0) ) {
+
+		panic("Memory range doesn't align with page size!\n");
+	}
+
+	pmem_ptr->start_pfn = (start >> PAGE_SHIFT);
+	pmem_ptr->pages = (pages4k >> PDC_PAGE_ADJ_SHIFT);
+}
+
+static void __init pagezero_memconfig(void)
+{
+	unsigned long npages;
+
+	/* Use the 32 bit information from page zero to create a single
+	 * entry in the pmem_ranges[] table.
+	 *
+	 * We currently don't support machines with contiguous memory
+	 * >= 4 Gb, who report that memory using 64 bit only fields
+	 * on page zero. It's not worth doing until it can be tested,
+	 * and it is not clear we can support those machines for other
+	 * reasons.
+	 *
+	 * If that support is done in the future, this is where it
+	 * should be done.
+	 */
+
+	npages = (PAGE_ALIGN(PAGE0->imm_max_mem) >> PAGE_SHIFT);
+	set_pmem_entry(pmem_ranges,0UL,npages);
+	npmem_ranges = 1;
+}
 
 #ifdef __LP64__
-#include <asm/pdcpat.h>
 
-int pdc_pat = 0;
+/* All of the PDC PAT specific code is 64-bit only */
 
 /*
 **  The module object is filled via PDC_PAT_CELL[Return Cell Module].
@@ -47,30 +164,37 @@
 **
 */
 
-static int
-pat_query_module( ulong pcell_loc, ulong mod_index)
+static int __init 
+pat_query_module(ulong pcell_loc, ulong mod_index)
 {
-	extern int num_devices;
-	extern struct hp_device devices[];
-
 	pdc_pat_cell_mod_maddr_block_t pa_pdc_cell;
-        struct hp_device * dev = &devices[num_devices];
-	uint64_t temp;             /* 64-bit scratch value */
-	long status;               /* PDC return value status */
+	pdc_pat_cell_mod_maddr_block_t io_pdc_cell;
+	unsigned long bytecnt;
+	unsigned long temp;	/* 64-bit scratch value */
+	long status;		/* PDC return value status */
+	struct parisc_device *dev;
 
 	/* return cell module (PA or Processor view) */
-	status = pdc_pat_cell_module(& pdc_result, pcell_loc, mod_index,
-		PA_VIEW, & pa_pdc_cell);
+	status = pdc_pat_cell_module(&bytecnt, pcell_loc, mod_index,
+				     PA_VIEW, &pa_pdc_cell);
 
-	if (status != PDC_RET_OK) {
+	if (status != PDC_OK) {
 		/* no more cell modules or error */
 		return status;
 	}
 
+	temp = pa_pdc_cell.cba;
+	dev = alloc_pa_dev(PAT_GET_CBA(temp), &pa_pdc_cell.mod_path);
+	if (!dev) {
+		return PDC_NE_MOD;
+	}
+
+	/* alloc_pa_dev sets dev->hpa */
+
 	/*
-	** save parameters in the hp_device
+	** save parameters in the parisc_device
 	** (The idea being the device driver will call pdc_pat_cell_module()
-	** and store the results in it's own data structure.)
+	** and store the results in its own data structure.)
 	*/
 	dev->pcell_loc = pcell_loc;
 	dev->mod_index = mod_index;
@@ -79,319 +203,410 @@
 	/* REVISIT: who is the consumer of this? not sure yet... */
 	dev->mod_info = pa_pdc_cell.mod_info;	/* pass to PAT_GET_ENTITY() */
 	dev->pmod_loc = pa_pdc_cell.mod_location;
-	dev->mod_path = pa_pdc_cell.mod_path;
 
-	temp = pa_pdc_cell.cba;
-	register_module((void *) PAT_GET_CBA(temp));	/* fills in dev->hpa */
+	register_parisc_device(dev);	/* advertise device */
 
 #ifdef DEBUG_PAT
 	/* dump what we see so far... */
 	switch (PAT_GET_ENTITY(dev->mod_info)) {
-		ulong i;
+		unsigned long i;
 
 	case PAT_ENTITY_PROC:
-		printk ("PAT_ENTITY_PROC: id_eid 0x%lx\n", pa_pdc_cell.mod[0]);
+		printk(KERN_DEBUG "PAT_ENTITY_PROC: id_eid 0x%lx\n",
+			pa_pdc_cell.mod[0]);
 		break;
 
 	case PAT_ENTITY_MEM:
-		printk ("PAT_ENTITY_MEM: amount 0x%lx min_gni_base 0x%lx min_gni_len 0x%lx\n",
-			pa_pdc_cell.mod[0],
-			pa_pdc_cell.mod[1],
+		printk(KERN_DEBUG 
+			"PAT_ENTITY_MEM: amount 0x%lx min_gni_base 0x%lx min_gni_len 0x%lx\n",
+			pa_pdc_cell.mod[0], pa_pdc_cell.mod[1], 
 			pa_pdc_cell.mod[2]);
 		break;
 	case PAT_ENTITY_CA:
-		printk ("PAT_ENTITY_CA: %ld\n",pcell_loc);
+		printk(KERN_DEBUG "PAT_ENTITY_CA: %ld\n", pcell_loc);
 		break;
 
 	case PAT_ENTITY_PBC:
-		printk ("PAT_ENTITY_PBC: ");
+		printk(KERN_DEBUG "PAT_ENTITY_PBC: ");
 		goto print_ranges;
 
 	case PAT_ENTITY_SBA:
-		printk ("PAT_ENTITY_SBA: ");
+		printk(KERN_DEBUG "PAT_ENTITY_SBA: ");
 		goto print_ranges;
 
 	case PAT_ENTITY_LBA:
-		printk ("PAT_ENTITY_LBA: ");
+		printk(KERN_DEBUG "PAT_ENTITY_LBA: ");
 
-print_ranges:
-		printk ("ranges %ld\n", pa_pdc_cell.mod[1]);
+ print_ranges:
+		pdc_pat_cell_module(&bytecnt, pcell_loc, mod_index,
+				    IO_VIEW, &io_pdc_cell);
+		printk(KERN_DEBUG "ranges %ld\n", pa_pdc_cell.mod[1]);
 		for (i = 0; i < pa_pdc_cell.mod[1]; i++) {
-			printk ("	%ld: 0x%016lx 0x%016lx 0x%016lx\n", i,
-				pa_pdc_cell.mod[2+i*3],	/* type */
-				pa_pdc_cell.mod[3+i*3],	/* start */
-				pa_pdc_cell.mod[4+i*3]);	/* finish (ie end) */
+			printk(KERN_DEBUG 
+				"  PA_VIEW %ld: 0x%016lx 0x%016lx 0x%016lx\n", 
+				i, pa_pdc_cell.mod[2 + i * 3],	/* type */
+				pa_pdc_cell.mod[3 + i * 3],	/* start */
+				pa_pdc_cell.mod[4 + i * 3]);	/* finish (ie end) */
+			printk(KERN_DEBUG 
+				"  IO_VIEW %ld: 0x%016lx 0x%016lx 0x%016lx\n", 
+				i, io_pdc_cell.mod[2 + i * 3],	/* type */
+				io_pdc_cell.mod[3 + i * 3],	/* start */
+				io_pdc_cell.mod[4 + i * 3]);	/* finish (ie end) */
 		}
-		printk("\n");
+		printk(KERN_DEBUG "\n");
 		break;
 	}
 #endif /* DEBUG_PAT */
-	return PDC_RET_OK;
+	return PDC_OK;
 }
 
 
-static int do_pat_inventory(void)
-{
-	ulong mod_index=0;
-	int status;
-	ulong cell_num;
-	ulong pcell_loc;
+/* pat pdc can return information about a variety of different
+ * types of memory (e.g. firmware,i/o, etc) but we only care about
+ * the usable physical ram right now. Since the firmware specific
+ * information is allocated on the stack, we'll be generous, in
+ * case there is a lot of other information we don't care about.
+ */
 
-	pdc_pat = (pdc_pat_cell_get_number(&pdc_result) == PDC_OK);
-	if (!pdc_pat)
-	{
-		return 0;
-	}
-
-	cell_num = pdc_result[0];	/* Cell number call was made */
-
-	/* As of PDC PAT ARS 2.5, ret[1] is NOT architected! */
-	pcell_loc = pdc_result[1];	/* Physical location of the cell */
-
-#ifdef DEBUG_PAT
-	printk("CELL_GET_NUMBER: 0x%lx 0x%lx\n", cell_num, pcell_loc);
-#endif
-
-        status = pdc_pat_cell_num_to_loc(&pdc_result, cell_num);
-        if (status == PDC_BAD_OPTION)
-	{
-		/* Prelude (and it's successors: Lclass, A400/500) only
-		** implement PDC_PAT_CELL sub-options 0 and 2.
-		** "Home cook'n is best anyhow!"
-		*/
-	} else if (PDC_OK == status) {
-		/* so far only Halfdome supports this */
-		pcell_loc = pdc_result[0];
-	} else {
-		panic("WTF? CELL_GET_NUMBER give me invalid cell number?");
-	}
-
-	while (PDC_RET_OK == pat_query_module(pcell_loc, mod_index))
-	{
-		mod_index++;
-	}
-
-	return mod_index;
-}
-#endif /* __LP64__ */
+#define PAT_MAX_RANGES (4 * MAX_PHYSMEM_RANGES)
 
-static int do_newer_workstation_inventory(void)
+static void __init pat_memconfig(void)
 {
+	unsigned long actual_len;
+	struct pdc_pat_pd_addr_map_entry mem_table[PAT_MAX_RANGES+1];
+	struct pdc_pat_pd_addr_map_entry *mtbl_ptr;
+	physmem_range_t *pmem_ptr;
 	long status;
-	int i, num = 0;
+	int entries;
+	unsigned long length;
+	int i;
+
+	length = (PAT_MAX_RANGES + 1) * sizeof(struct pdc_pat_pd_addr_map_entry);
+
+	status = pdc_pat_pd_get_addr_map(&actual_len, mem_table, length, 0L);
+
+	if ((status != PDC_OK)
+	    || ((actual_len % sizeof(struct pdc_pat_pd_addr_map_entry)) != 0)) {
+
+		/* The above pdc call shouldn't fail, but, just in
+		 * case, just use the PAGE0 info.
+		 */
+
+		printk("\n\n\n");
+		printk(KERN_WARNING "WARNING! Could not get full memory configuration. "
+			"All memory may not be used!\n\n\n");
+		pagezero_memconfig();
+		return;
+	}
 
-	/* So the idea here is to simply try one SYSTEM_MAP call.  If 
-	   that one works, great, otherwise do it another way */
+	entries = actual_len / sizeof(struct pdc_pat_pd_addr_map_entry);
 
-	status = pdc_system_map_find_mods(&module_result,&module_path,0);
+	if (entries > PAT_MAX_RANGES) {
+		printk(KERN_WARNING "This Machine has more memory ranges than we support!\n");
+		printk(KERN_WARNING "Some memory may not be used!\n");
+	}
 
-	if (status == PDC_RET_OK) {
-		/* This is for newer non-PDC-PAT boxes */
+	/* Copy information into the firmware independent pmem_ranges
+	 * array, skipping types we don't care about. Notice we said
+	 * "may" above. We'll use all the entries that were returned.
+	 */
+
+	npmem_ranges = 0;
+	mtbl_ptr = mem_table;
+	pmem_ptr = pmem_ranges; /* Global firmware independent table */
+	for (i = 0; i < entries; i++,mtbl_ptr++) {
+		if (   (mtbl_ptr->entry_type != PAT_MEMORY_DESCRIPTOR)
+		    || (mtbl_ptr->memory_type != PAT_MEMTYPE_MEMORY)
+		    || (mtbl_ptr->pages == 0)
+		    || (   (mtbl_ptr->memory_usage != PAT_MEMUSE_GENERAL)
+			&& (mtbl_ptr->memory_usage != PAT_MEMUSE_GI)
+			&& (mtbl_ptr->memory_usage != PAT_MEMUSE_GNI) ) ) {
 
-		printk("a newer box...\n");
-		for(i=0, status=PDC_RET_OK; status != PDC_RET_NE_PROC && 
-			status != PDC_RET_NE_MOD ;i++) {
+			continue;
+		}
 
-			status = pdc_system_map_find_mods(&module_result,&module_path,i);
-			if (status == PDC_RET_OK) {
-				num++;
-				register_module(module_result.mod_addr);
-			}
+		if (npmem_ranges == MAX_PHYSMEM_RANGES) {
+			printk(KERN_WARNING "This Machine has more memory ranges than we support!\n");
+			printk(KERN_WARNING "Some memory will not be used!\n");
+			break;
 		}
-	}
 
-	return (num > 0);
+		set_pmem_entry(pmem_ptr++,mtbl_ptr->paddr,mtbl_ptr->pages);
+		npmem_ranges++;
+	}
 }
 
-#ifndef __LP64__
-static	struct  pdc_memory_map r_addr __attribute__ ((aligned (8)));
-
-static int really_do_oldhw_inventory(void)
+static int __init pat_inventory(void)
 {
-	int i, mod, num = 0;
 	int status;
-	unsigned int hw_type;
-	unsigned int func;
+	ulong mod_index = 0;
+	struct pdc_pat_cell_num cell_info;
 
-	/* This is undocumented at the time of writing, but basically 
-	   we're setting up mod_path so that bc[0..4]=0xff, and step
-	   through mod to get the "Path Structure for GSC Modules".  If
-	   it works, use the returned HPA and determine the hardware type.  */
+	/*
+	** Note:  Prelude (and it's successors: Lclass, A400/500) only
+	**        implement PDC_PAT_CELL sub-options 0 and 2.
+	*/
+	status = pdc_pat_cell_get_number(&cell_info);
+	if (status != PDC_OK) {
+		return 0;
+	}
 
-	for (i=0;i<6;i++) module_path.bc[i]=0xff;
+#ifdef DEBUG_PAT
+	printk(KERN_DEBUG "CELL_GET_NUMBER: 0x%lx 0x%lx\n", cell_info.cell_num, 
+	       cell_info.cell_loc);
+#endif
 
-	for (mod=0;mod<16;mod++) {
-		char *stype = NULL;
+	while (PDC_OK == pat_query_module(cell_info.cell_loc, mod_index)) {
+		mod_index++;
+	}
 
-		module_path.mod=mod;
-		status = pdc_mem_map_hpa(&r_addr, &module_path);
-		if (status!=PDC_RET_OK) continue;
-	
-		status = pdc_iodc_read(&pdc_result,(void *) r_addr.hpa,
-			0, &iodc_data,32 );
-		if (status!=PDC_RET_OK) continue;
-		hw_type = iodc_data[3]&0x1f;
+	return mod_index;
+}
 
-		switch (hw_type)
-		{
-		case HPHW_NPROC:	/* 0 */
-			stype="Processor"; break;
+/* We only look for extended memory ranges on a 64 bit capable box */
+static void __init sprockets_memconfig(void)
+{
+	struct pdc_memory_table_raddr r_addr;
+	struct pdc_memory_table mem_table[MAX_PHYSMEM_RANGES];
+	struct pdc_memory_table *mtbl_ptr;
+	physmem_range_t *pmem_ptr;
+	long status;
+	int entries;
+	int i;
 
-		case HPHW_MEMORY:	/* 1 */
-			stype="Memory"; break;
+	status = pdc_mem_mem_table(&r_addr,mem_table,
+				(unsigned long)MAX_PHYSMEM_RANGES);
 
-		case HPHW_B_DMA:	/* 2 */
-			stype="Type B DMA"; break;
+	if (status != PDC_OK) {
 
-		case HPHW_A_DMA:	/* 4 */
-			stype="Type A DMA"; break;
+		/* The above pdc call only works on boxes with sprockets
+		 * firmware (newer B,C,J class). Other non PAT PDC machines
+		 * do support more than 3.75 Gb of memory, but we don't
+		 * support them yet.
+		 */
 
-		case HPHW_A_DIRECT:	/* 5 */
-			stype="Type A Direct"; break;
+		pagezero_memconfig();
+		return;
+	}
+
+	if (r_addr.entries_total > MAX_PHYSMEM_RANGES) {
+		printk(KERN_WARNING "This Machine has more memory ranges than we support!\n");
+		printk(KERN_WARNING "Some memory will not be used!\n");
+	}
 
-		case HPHW_BCPORT:	/* 7 */
-			stype="Bus Converter Port"; break;
+	entries = (int)r_addr.entries_returned;
 
-		case HPHW_CONSOLE:	/* 9 */
-			stype="Console"; break;
+	npmem_ranges = 0;
+	mtbl_ptr = mem_table;
+	pmem_ptr = pmem_ranges; /* Global firmware independent table */
+	for (i = 0; i < entries; i++,mtbl_ptr++) {
+		set_pmem_entry(pmem_ptr++,mtbl_ptr->paddr,mtbl_ptr->pages);
+		npmem_ranges++;
+	}
+}
 
-		case HPHW_FIO:		/* 10 - Graphics */
-			stype="Foreign I/O (Graphics)"; break;
+#else   /* !__LP64__ */
 
-		case HPHW_BA:		/* 11 - Bus Adapter */
-			stype="Bus Adapter"; break;
+#define pat_inventory() do { } while (0)
+#define pat_memconfig() do { } while (0)
+#define sprockets_memconfig() pagezero_memconfig()
 
-		case HPHW_IOA:		/* 12 */
-			stype="I/O Adapter"; break;
+#endif	/* !__LP64__ */
 
-		case HPHW_BRIDGE:	/* 13 */
-			stype="Bridge"; break;
 
-		case HPHW_FABRIC:	/* 14 */
-			stype="Fabric"; break;
+#ifndef CONFIG_PA20
 
-		case HPHW_FAULTY:	/* 31 */
-			stype="Faulty HW"; break;
+/* Code to support Snake machines (7[2350], 7[235]5, 715/Scorpio) */
 
-		case HPHW_OTHER:	/* 42 */
-		default:	
-			printk("Don't know this hw_type: %d\n", hw_type);
-			break;
-		}
+static struct parisc_device * __init
+legacy_create_device(struct pdc_memory_map *r_addr,
+		struct pdc_module_path *module_path)
+{
+	struct parisc_device *dev;
+	int status = pdc_mem_map_hpa(r_addr, module_path);
+	if (status != PDC_OK)
+		return NULL;
+
+	dev = alloc_pa_dev(r_addr->hpa, &module_path->path);
+	if (dev == NULL)
+		return NULL;
 
-		// This is kluged. But don't want to replicate code for
-		// most of the above cases.
-		if (stype) {
-#ifdef DBG_PDC_QUERY
-			// parisc/kernel/drivers.c
-			extern int num_devices; 
-			extern struct hp_device devices[];
-			struct hp_hardware *h;
-#endif
+	register_parisc_device(dev);
+	return dev;
+}
 
-			status = pdc_mem_map_hpa(&r_addr, &module_path);
-			if (status==PDC_RET_OK && register_module((void *) r_addr.hpa) != NULL)
-					num++;
-
-
-		    if (hw_type == HPHW_BA) {
-			/* Now, we're checking for devices for each
-			   module.  I seem to think that the
-			   modules in question are Lasi (2), 2nd Lasi (6)
-			   Wax (5).  To do this, set bc[5]=0, and set
-			   bc[4] to the module, and step through the
-			   functions. */
-
-			for (i=0;i<4;i++) module_path.bc[i]=0xff;
-			module_path.bc[4]=mod;
-			for (func=0;func<16;func++) {
-				module_path.mod = func;
-				module_path.bc[5]=0;
-				status = pdc_mem_map_hpa(&r_addr, &module_path);
-				if (status!=PDC_RET_OK) continue;
-				if (register_module((void *) r_addr.hpa) != NULL) 
-					num++;
-			}
+/**
+ * snake_inventory
+ *
+ * Before PDC_SYSTEM_MAP was invented, the PDC_MEM_MAP call was used.
+ * To use it, we initialise the mod_path.bc to 0xff and try all values of
+ * mod to get the HPA for the top-level devices.  Bus adapters may have
+ * sub-devices which are discovered by setting bc[5] to 0 and bc[4] to the
+ * module, then trying all possible functions.
+ */
+static void __init snake_inventory(void)
+{
+	int mod;
+	for (mod = 0; mod < 16; mod++) {
+		struct parisc_device *dev;
+		struct pdc_module_path module_path;
+		struct pdc_memory_map r_addr;
+		unsigned int func;
+
+		memset(module_path.path.bc, 0xff, 6);
+		module_path.path.mod = mod;
+		dev = legacy_create_device(&r_addr, &module_path);
+		if ((!dev) || (dev->id.hw_type != HPHW_BA))
+			continue;
+
+		memset(module_path.path.bc, 0xff, 4);
+		module_path.path.bc[4] = mod;
+
+		for (func = 0; func < 16; func++) {
+			module_path.path.bc[5] = 0;
+			module_path.path.mod = func;
+			legacy_create_device(&r_addr, &module_path);
 		}
-		// reset module_path.bc[]
-		for (i=0;i<6;i++) module_path.bc[i]=0xff;
+	}
+}
 
+#else /* CONFIG_PA20 */
+#define snake_inventory() do { } while (0)
+#endif  /* CONFIG_PA20 */
+
+/* Common 32/64 bit based code goes here */
+
+/**
+ * add_system_map_addresses - Add additional addresses to the parisc device.
+ * @dev: The parisc device.
+ * @num_addrs: Then number of addresses to add;
+ * @module_instance: The system_map module instance.
+ *
+ * This function adds any additional addresses reported by the system_map
+ * firmware to the parisc device.
+ */
+static void __init
+add_system_map_addresses(struct parisc_device *dev, int num_addrs, 
+			 int module_instance)
+{
+	int i;
+	long status;
+	struct pdc_system_map_addr_info addr_result;
 
-#ifdef DBG_PDC_QUERY
-//
-// Let print_devices() dump everything which is registered.
-//
-			h = devices[num_devices-1].reference;
+	dev->addr = kmalloc(num_addrs * sizeof(unsigned long), GFP_KERNEL);
+	if(!dev->addr) {
+		printk(KERN_ERR "%s %s(): memory allocation failure\n",
+		       __FILE__, __FUNCTION__);
+		return;
+	}
 
-			if (h) stype = h->name;
-			printk("Found %s at %d\n", stype, module_path.mod);
-#endif
+	for(i = 1; i <= num_addrs; ++i) {
+		status = pdc_system_map_find_addrs(&addr_result, 
+						   module_instance, i);
+		if(PDC_OK == status) {
+			dev->addr[dev->num_addrs] = (unsigned long)addr_result.mod_addr;
+			dev->num_addrs++;
+		} else {
+			printk(KERN_WARNING 
+			       "Bad PDC_FIND_ADDRESS status return (%ld) for index %d\n",
+			       status, i);
 		}
 	}
-	return num;
 }
 
-static int
-do_old_inventory(void)
+/**
+ * do_system_map_inventory - Retrieve firmware devices via SYSTEM_MAP.
+ *
+ * This function attempts to retrieve and register all the devices firmware
+ * knows about via the SYSTEM_MAP PDC call.
+ */
+static void __init system_map_inventory(void)
 {
-        unsigned int bus_id;
-	long status;
-	int ok = 0;
-
-	printk(" an older box...\n");
+	int i;
+	long status = PDC_OK;
+    
+	/*
+	 * first stop the usb controller, otherwise the machine
+	 * might crash during iommu setup
+	 */
+	pdc_suspend_usb();
+
+	for (i = 0; status != PDC_BAD_PROC && status != PDC_NE_MOD; i++) {
+		struct parisc_device *dev;
+		struct pdc_system_map_mod_info module_result;
+		struct pdc_module_path module_path;
+
+		status = pdc_system_map_find_mods(&module_result,
+				&module_path, i);
+		if (status != PDC_OK)
+			continue;
+		
+		dev = alloc_pa_dev(module_result.mod_addr, &module_path.path);
+		if (!dev)
+			continue;
+		
+		register_parisc_device(dev);
+
+		/* if available, get the additional addresses for a module */
+		if (!module_result.add_addrs)
+			continue;
 
-	/* Here, we're going to check the model, and decide
-	   if we should even bother trying. */
+		add_system_map_addresses(dev, module_result.add_addrs, i);
+	}
 
-	status = pdc_model_info(&model);
+	walk_central_bus();
+	return;
+}
 
-	bus_id = (model.hversion >> (4+7) ) &0x1f;
+void __init do_memory_inventory(void)
+{
+	switch (pdc_type) {
 
-	/* Here, we're checking the HVERSION of the CPU.
-	   We're only checking the 0th CPU, since it'll
-	   be the same on an SMP box. */
+	case PDC_TYPE_PAT:
+		pat_memconfig();
+		break;
 
-	switch (bus_id) {
-		case 0x4: 	/* 720, 730, 750, 735, 755 */
-		case 0x6: 	/* 705, 710 */
-		case 0x7: 	/* 715, 725 */
-		case 0x8: 	/* 745, 747, 742 */
-		case 0xA: 	/* 712 and similiar */
-		case 0xC: 	/* 715/64, at least */
-
-		/* Do inventory using MEM_MAP */
-		really_do_oldhw_inventory();
-		ok = 1;
+	case PDC_TYPE_SYSTEM_MAP:
+		sprockets_memconfig();
 		break;
-	default: 	/* Everything else */
-		printk("This is a very very old machine, with a bus_id of 0x%x.\n",bus_id);
-		panic("This will probably never run Linux.\n");
+
+	case PDC_TYPE_SNAKE:
+		pagezero_memconfig();
+		return;
+
+	default:
+		panic("Unknown PDC type!\n");
 	}
 
-	return ok;
+	if (npmem_ranges == 0 || pmem_ranges[0].start_pfn != 0) {
+		printk(KERN_WARNING "Bad memory configuration returned!\n");
+		printk(KERN_WARNING "Some memory may not be used!\n");
+		pagezero_memconfig();
+	}
 }
 
-#endif /* !__LP64__ */
+void __init do_device_inventory(void)
+{
+	printk(KERN_INFO "Searching for devices...\n");
 
-void do_inventory(void){
-	if((pdc_hpa_processor(&processor_hpa))<0){
-		printk(KERN_INFO "Couldn't get the HPA of the processor.\n" );
-	}
+	switch (pdc_type) {
+
+	case PDC_TYPE_PAT:
+		pat_inventory();
+		break;
 
-	printk("Searching for devices in PDC firmware... ");
-	printk("processor hpa 0x%lx\n", processor_hpa.hpa);
+	case PDC_TYPE_SYSTEM_MAP:
+		system_map_inventory();
+		break;
 
-	if (!(
-		do_newer_workstation_inventory()
-#ifdef __LP64__
-		|| do_pat_inventory()
-#else /* __LP64__ */
-		|| do_old_inventory()
-#endif /* __LP64__ */
-	    ))
-	{
-	    panic("I can't get the hardware inventory on this machine");
+	case PDC_TYPE_SNAKE:
+		snake_inventory();
+		break;
+
+	default:
+		panic("Unknown PDC type!\n");
 	}
-	print_devices(NULL);
-}
 
+	printk(KERN_INFO "Found devices:\n");
+	print_parisc_devices();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/ioctl32.c linux-bk/arch/parisc/kernel/ioctl32.c
--- linux-2.4.19/arch/parisc/kernel/ioctl32.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/parisc/kernel/ioctl32.c	2002-08-17 00:49:07.000000000 +0000
@@ -0,0 +1,3758 @@
+/* $Id: ioctl32.c,v 1.12 2002/07/08 20:52:15 grundler Exp $
+ * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
+ *
+ * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
+ * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
+ *
+ * These routines maintain argument size conversion between 32bit and 64bit
+ * ioctls.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include "sys32.h"
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/ioctl.h>
+#include <linux/if.h>
+#include <linux/slab.h>
+#include <linux/hdreg.h>
+#include <linux/raid/md.h>
+#include <linux/kd.h>
+#include <linux/route.h>
+#include <linux/skbuff.h>
+#include <linux/netlink.h>
+#include <linux/vt.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/fd.h>
+#include <linux/ppp_defs.h>
+#include <linux/if_ppp.h>
+#include <linux/if_pppox.h>
+#include <linux/mtio.h>
+#include <linux/cdrom.h>
+#include <linux/loop.h>
+#include <linux/auto_fs.h>
+#include <linux/devfs_fs.h>
+#include <linux/tty.h>
+#include <linux/vt_kern.h>
+#include <linux/fb.h>
+#include <linux/ext2_fs.h>
+#include <linux/videodev.h>
+#include <linux/netdevice.h>
+#include <linux/raw.h>
+#include <linux/smb_fs.h>
+#include <linux/blkpg.h>
+#include <linux/blk.h>
+#include <linux/elevator.h>
+#include <linux/rtc.h>
+#include <linux/serial.h>
+#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
+/* Ugh. This header really is not clean */
+/* #define min min
+#define max max */
+#include <linux/lvm.h>
+#endif /* LVM */
+
+#include <scsi/scsi.h>
+/* Ugly hack. */
+#undef __KERNEL__
+#include <scsi/scsi_ioctl.h>
+#define __KERNEL__
+#include <scsi/sg.h>
+
+#include <asm/types.h>
+#include <asm/uaccess.h>
+#include <asm/perf.h>
+#include <linux/ethtool.h>
+#include <linux/soundcard.h>
+
+#include <linux/atm.h>
+#include <linux/atmarp.h>
+#include <linux/atmclip.h>
+#include <linux/atmdev.h>
+#include <linux/atmioc.h>
+#include <linux/atmlec.h>
+#include <linux/atmmpc.h>
+#include <linux/atmsvc.h>
+#include <linux/atm_tcp.h>
+#include <linux/sonet.h>
+#include <linux/atm_suni.h>
+
+#include <asm/module.h>	/* get #define module_map() */
+
+/* Use this to get at 32-bit user passed pointers. 
+   See sys_sparc32.c for description about these. */
+#define A(__x) ((unsigned long)(__x))
+
+/* Aiee. Someone does not find a difference between int and long */
+#define EXT2_IOC32_GETFLAGS               _IOR('f', 1, int)
+#define EXT2_IOC32_SETFLAGS               _IOW('f', 2, int)
+#define EXT2_IOC32_GETVERSION             _IOR('v', 1, int)
+#define EXT2_IOC32_SETVERSION             _IOW('v', 2, int)
+
+extern asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
+
+static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	int err;
+	unsigned long val;
+	
+	set_fs (KERNEL_DS);
+	err = sys_ioctl(fd, cmd, (unsigned long)&val);
+	set_fs (old_fs);
+	if (!err && put_user(val, (u32 *)arg))
+		return -EFAULT;
+	return err;
+}
+ 
+static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	int err;
+	unsigned long val;
+	
+	if(get_user(val, (u32 *)arg))
+		return -EFAULT;
+	set_fs (KERNEL_DS);
+	err = sys_ioctl(fd, cmd, (unsigned long)&val);
+	set_fs (old_fs);
+	if (!err && put_user(val, (u32 *)arg))
+		return -EFAULT;
+	return err;
+}
+
+static int siocprivate(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	int err = sys_ioctl(fd, cmd, arg);
+	if ((unsigned) err > -4095)
+		printk(KERN_WARNING 
+			"ioctl(%d, 0x%x, %p) -- SIOCDEVPRIVATE-based ioctls aren't really\n"
+			"supported, though some will work by accident.\n",
+		    fd, cmd, (void *)arg);
+	return err;
+}
+
+static int do_ext2_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	/* These are just misnamed, they actually get/put from/to user an int */
+	switch (cmd) {
+	case EXT2_IOC32_GETFLAGS: cmd = EXT2_IOC_GETFLAGS; break;
+	case EXT2_IOC32_SETFLAGS: cmd = EXT2_IOC_SETFLAGS; break;
+	case EXT2_IOC32_GETVERSION: cmd = EXT2_IOC_GETVERSION; break;
+	case EXT2_IOC32_SETVERSION: cmd = EXT2_IOC_SETVERSION; break;
+	}
+	return sys_ioctl(fd, cmd, arg);
+}
+ 
+static int do_siocgstamp(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct timeval32 *up = (struct timeval32 *)arg;
+	struct timeval ktv;
+	mm_segment_t old_fs = get_fs();
+	int err;
+
+	set_fs(KERNEL_DS);
+	err = sys_ioctl(fd, cmd, (unsigned long)&ktv);
+	set_fs(old_fs);
+	if(!err) {
+		err = put_user(ktv.tv_sec, &up->tv_sec);
+		err |= __put_user(ktv.tv_usec, &up->tv_usec);
+	}
+	return err;
+}
+
+struct ifmap32 {
+	u32 mem_start;
+	u32 mem_end;
+	unsigned short base_addr;
+	unsigned char irq;
+	unsigned char dma;
+	unsigned char port;
+};
+
+struct ifreq32 {
+#define IFHWADDRLEN     6
+#define IFNAMSIZ        16
+        union {
+                char    ifrn_name[IFNAMSIZ];            /* if name, e.g. "en0" */
+        } ifr_ifrn;
+        union {
+                struct  sockaddr ifru_addr;
+                struct  sockaddr ifru_dstaddr;
+                struct  sockaddr ifru_broadaddr;
+                struct  sockaddr ifru_netmask;
+                struct  sockaddr ifru_hwaddr;
+                short   ifru_flags;
+                int     ifru_ivalue;
+                int     ifru_mtu;
+                struct  ifmap32 ifru_map;
+                char    ifru_slave[IFNAMSIZ];   /* Just fits the size */
+		char	ifru_newname[IFNAMSIZ];
+                __kernel_caddr_t32 ifru_data;
+        } ifr_ifru;
+};
+
+struct ifconf32 {
+        int     ifc_len;                        /* size of buffer       */
+        __kernel_caddr_t32  ifcbuf;
+};
+
+static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct net_device *dev;
+	struct ifreq32 ifr32;
+	int err;
+
+	if (copy_from_user(&ifr32, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
+		return -EFAULT;
+
+	dev = dev_get_by_index(ifr32.ifr_ifindex);
+	if (!dev)
+		return -ENODEV;
+
+	strcpy(ifr32.ifr_name, dev->name);
+
+	err = copy_to_user((struct ifreq32 *)arg, &ifr32, sizeof(struct ifreq32));
+	return (err ? -EFAULT : 0);
+}
+
+static inline int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct ifconf32 ifc32;
+	struct ifconf ifc;
+	struct ifreq32 *ifr32;
+	struct ifreq *ifr;
+	mm_segment_t old_fs;
+	unsigned int i, j;
+	int err;
+
+	if (copy_from_user(&ifc32, (struct ifconf32 *)arg, sizeof(struct ifconf32)))
+		return -EFAULT;
+
+	if(ifc32.ifcbuf == 0) {
+		ifc32.ifc_len = 0;
+		ifc.ifc_len = 0;
+		ifc.ifc_buf = NULL;
+	} else {
+		ifc.ifc_len = ((ifc32.ifc_len / sizeof (struct ifreq32)) + 1) *
+			sizeof (struct ifreq);
+		ifc.ifc_buf = kmalloc (ifc.ifc_len, GFP_KERNEL);
+		if (!ifc.ifc_buf)
+			return -ENOMEM;
+	}
+	ifr = ifc.ifc_req;
+	ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf);
+	for (i = 0; i < ifc32.ifc_len; i += sizeof (struct ifreq32)) {
+		if (copy_from_user(ifr++, ifr32++, sizeof (struct ifreq32))) {
+			kfree (ifc.ifc_buf);
+			return -EFAULT;
+		}
+	}
+	old_fs = get_fs(); set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)&ifc);	
+	set_fs (old_fs);
+	if (!err) {
+		ifr = ifc.ifc_req;
+		ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf);
+		for (i = 0, j = 0; i < ifc32.ifc_len && j < ifc.ifc_len;
+		     i += sizeof (struct ifreq32), j += sizeof (struct ifreq)) {
+			if (copy_to_user(ifr32++, ifr++, sizeof (struct ifreq32))) {
+				err = -EFAULT;
+				break;
+			}
+		}
+		if (!err) {
+			if (i <= ifc32.ifc_len)
+				ifc32.ifc_len = i;
+			else
+				ifc32.ifc_len = i - sizeof (struct ifreq32);
+			if (copy_to_user((struct ifconf32 *)arg, &ifc32, sizeof(struct ifconf32)))
+				err = -EFAULT;
+		}
+	}
+	if(ifc.ifc_buf != NULL)
+		kfree (ifc.ifc_buf);
+	return err;
+}
+
+static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct ifreq ifr;
+	mm_segment_t old_fs;
+	int err;
+	
+	switch (cmd) {
+	case SIOCSIFMAP:
+		err = copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(ifr.ifr_name));
+		err |= __get_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start));
+		err |= __get_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end));
+		err |= __get_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr));
+		err |= __get_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq));
+		err |= __get_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma));
+		err |= __get_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port));
+		if (err)
+			return -EFAULT;
+		break;
+	case SIOCGPPPSTATS:
+	case SIOCGPPPCSTATS:
+	case SIOCGPPPVER:
+	case SIOCETHTOOL:
+		if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
+			return -EFAULT;
+		ifr.ifr_data = (__kernel_caddr_t)get_free_page(GFP_KERNEL);
+		if (!ifr.ifr_data)
+			return -EAGAIN;
+		if(cmd == SIOCETHTOOL) {
+			u32 data;
+
+			__get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
+			if(copy_from_user(ifr.ifr_data,
+					  (char *)A(data),
+					  sizeof(struct ethtool_cmd))) {
+				free_page((unsigned long)ifr.ifr_data);
+				return -EFAULT;
+			}
+		}
+		break;
+	default:
+		if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
+			return -EFAULT;
+		break;
+	}
+	old_fs = get_fs();
+	set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
+	set_fs (old_fs);
+	if (!err) {
+		switch (cmd) {
+		case SIOCGIFFLAGS:
+		case SIOCGIFMETRIC:
+		case SIOCGIFMTU:
+		case SIOCGIFMEM:
+		case SIOCGIFHWADDR:
+		case SIOCGIFINDEX:
+		case SIOCGIFADDR:
+		case SIOCGIFBRDADDR:
+		case SIOCGIFDSTADDR:
+		case SIOCGIFNETMASK:
+		case SIOCGIFTXQLEN:
+			if (copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(struct ifreq32)))
+				return -EFAULT;
+			break;
+		case SIOCGPPPSTATS:
+		case SIOCGPPPCSTATS:
+		case SIOCGPPPVER:
+		case SIOCETHTOOL:
+		{
+			u32 data;
+			int len;
+
+			__get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
+			if(cmd == SIOCETHTOOL)
+				len = sizeof(struct ethtool_cmd);
+			if(cmd == SIOCGPPPVER)
+				len = strlen((char *)ifr.ifr_data) + 1;
+			else if(cmd == SIOCGPPPCSTATS)
+				len = sizeof(struct ppp_comp_stats);
+			else
+				len = sizeof(struct ppp_stats);
+
+			len = copy_to_user((char *)A(data), ifr.ifr_data, len);
+			free_page((unsigned long)ifr.ifr_data);
+			if(len)
+				return -EFAULT;
+			break;
+		}
+		case SIOCGIFMAP:
+			err = copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(ifr.ifr_name));
+			err |= __put_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start));
+			err |= __put_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end));
+			err |= __put_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr));
+			err |= __put_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq));
+			err |= __put_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma));
+			err |= __put_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port));
+			if (err)
+				err = -EFAULT;
+			break;
+		}
+	}
+	return err;
+}
+
+struct rtentry32 {
+        u32   		rt_pad1;
+        struct sockaddr rt_dst;         /* target address               */
+        struct sockaddr rt_gateway;     /* gateway addr (RTF_GATEWAY)   */
+        struct sockaddr rt_genmask;     /* target network mask (IP)     */
+        unsigned short  rt_flags;
+        short           rt_pad2;
+        u32   		rt_pad3;
+        unsigned char   rt_tos;
+        unsigned char   rt_class;
+        short           rt_pad4;
+        short           rt_metric;      /* +1 for binary compatibility! */
+        /* char * */ u32 rt_dev;        /* forcing the device at add    */
+        u32   		rt_mtu;         /* per route MTU/Window         */
+        u32   		rt_window;      /* Window clamping              */
+        unsigned short  rt_irtt;        /* Initial RTT                  */
+
+};
+
+static inline int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct rtentry r;
+	char devname[16];
+	u32 rtdev;
+	int ret;
+	mm_segment_t old_fs = get_fs();
+	
+	ret = copy_from_user (&r.rt_dst, &(((struct rtentry32 *)arg)->rt_dst), 3 * sizeof(struct sockaddr));
+	ret |= __get_user (r.rt_flags, &(((struct rtentry32 *)arg)->rt_flags));
+	ret |= __get_user (r.rt_metric, &(((struct rtentry32 *)arg)->rt_metric));
+	ret |= __get_user (r.rt_mtu, &(((struct rtentry32 *)arg)->rt_mtu));
+	ret |= __get_user (r.rt_window, &(((struct rtentry32 *)arg)->rt_window));
+	ret |= __get_user (r.rt_irtt, &(((struct rtentry32 *)arg)->rt_irtt));
+	ret |= __get_user (rtdev, &(((struct rtentry32 *)arg)->rt_dev));
+	if (rtdev) {
+		ret |= copy_from_user (devname, (char *)A(rtdev), 15);
+		r.rt_dev = devname; devname[15] = 0;
+	} else
+		r.rt_dev = 0;
+	if (ret)
+		return -EFAULT;
+	set_fs (KERNEL_DS);
+	ret = sys_ioctl (fd, cmd, (long)&r);
+	set_fs (old_fs);
+	return ret;
+}
+
+struct hd_geometry32 {
+	unsigned char heads;
+	unsigned char sectors;
+	unsigned short cylinders;
+	u32 start;
+};
+                        
+static inline int hdio_getgeo(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	struct hd_geometry geo;
+	int err;
+	
+	set_fs (KERNEL_DS);
+	err = sys_ioctl(fd, HDIO_GETGEO, (unsigned long)&geo);
+	set_fs (old_fs);
+	if (!err) {
+		err = copy_to_user ((struct hd_geometry32 *)arg, &geo, 4);
+		err |= __put_user (geo.start, &(((struct hd_geometry32 *)arg)->start));
+	}
+	return err ? -EFAULT : 0;
+}
+
+
+#if 0
+/* looks like SPARC only - eg sbus video */
+struct  fbcmap32 {
+	int             index;          /* first element (0 origin) */
+	int             count;
+	u32		red;
+	u32		green;
+	u32		blue;
+};
+
+
+static inline int fbiogetputcmap(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct fbcmap f;
+	int ret;
+	char red[256], green[256], blue[256];
+	u32 r, g, b;
+	mm_segment_t old_fs = get_fs();
+	
+	ret = get_user(f.index, &(((struct fbcmap32 *)arg)->index));
+	ret |= __get_user(f.count, &(((struct fbcmap32 *)arg)->count));
+	ret |= __get_user(r, &(((struct fbcmap32 *)arg)->red));
+	ret |= __get_user(g, &(((struct fbcmap32 *)arg)->green));
+	ret |= __get_user(b, &(((struct fbcmap32 *)arg)->blue));
+	if (ret)
+		return -EFAULT;
+	if ((f.index < 0) || (f.index > 255)) return -EINVAL;
+	if (f.index + f.count > 256)
+		f.count = 256 - f.index;
+	if (cmd == FBIOPUTCMAP32) {
+		ret = copy_from_user (red, (char *)A(r), f.count);
+		ret |= copy_from_user (green, (char *)A(g), f.count);
+		ret |= copy_from_user (blue, (char *)A(b), f.count);
+		if (ret)
+			return -EFAULT;
+	}
+	f.red = red; f.green = green; f.blue = blue;
+	set_fs (KERNEL_DS);
+	ret = sys_ioctl (fd, (cmd == FBIOPUTCMAP32) ? FBIOPUTCMAP_SPARC : FBIOGETCMAP_SPARC, (long)&f);
+	set_fs (old_fs);
+	if (!ret && cmd == FBIOGETCMAP32) {
+		ret = copy_to_user ((char *)A(r), red, f.count);
+		ret |= copy_to_user ((char *)A(g), green, f.count);
+		ret |= copy_to_user ((char *)A(b), blue, f.count);
+	}
+	return ret ? -EFAULT : 0;
+}
+
+struct fbcursor32 {
+	short set;		/* what to set, choose from the list above */
+	short enable;		/* cursor on/off */
+	struct fbcurpos pos;	/* cursor position */
+	struct fbcurpos hot;	/* cursor hot spot */
+	struct fbcmap32 cmap;	/* color map info */
+	struct fbcurpos size;	/* cursor bit map size */
+	u32	image;		/* cursor image bits */
+	u32	mask;		/* cursor mask bits */
+};
+	
+static inline int fbiogscursor(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct fbcursor f;
+	int ret;
+	char red[2], green[2], blue[2];
+	char image[128], mask[128];
+	u32 r, g, b;
+	u32 m, i;
+	mm_segment_t old_fs = get_fs();
+	
+	ret = copy_from_user (&f, (struct fbcursor32 *)arg, 2 * sizeof (short) + 2 * sizeof(struct fbcurpos));
+	ret |= __get_user(f.size.fbx, &(((struct fbcursor32 *)arg)->size.fbx));
+	ret |= __get_user(f.size.fby, &(((struct fbcursor32 *)arg)->size.fby));
+	ret |= __get_user(f.cmap.index, &(((struct fbcursor32 *)arg)->cmap.index));
+	ret |= __get_user(f.cmap.count, &(((struct fbcursor32 *)arg)->cmap.count));
+	ret |= __get_user(r, &(((struct fbcursor32 *)arg)->cmap.red));
+	ret |= __get_user(g, &(((struct fbcursor32 *)arg)->cmap.green));
+	ret |= __get_user(b, &(((struct fbcursor32 *)arg)->cmap.blue));
+	ret |= __get_user(m, &(((struct fbcursor32 *)arg)->mask));
+	ret |= __get_user(i, &(((struct fbcursor32 *)arg)->image));
+	if (ret)
+		return -EFAULT;
+	if (f.set & FB_CUR_SETCMAP) {
+		if ((uint) f.size.fby > 32)
+			return -EINVAL;
+		ret = copy_from_user (mask, (char *)A(m), f.size.fby * 4);
+		ret |= copy_from_user (image, (char *)A(i), f.size.fby * 4);
+		if (ret)
+			return -EFAULT;
+		f.image = image; f.mask = mask;
+	}
+	if (f.set & FB_CUR_SETCMAP) {
+		ret = copy_from_user (red, (char *)A(r), 2);
+		ret |= copy_from_user (green, (char *)A(g), 2);
+		ret |= copy_from_user (blue, (char *)A(b), 2);
+		if (ret)
+			return -EFAULT;
+		f.cmap.red = red; f.cmap.green = green; f.cmap.blue = blue;
+	}
+	set_fs (KERNEL_DS);
+	ret = sys_ioctl (fd, FBIOSCURSOR, (long)&f);
+	set_fs (old_fs);
+	return ret;
+}
+#endif /* 0 */
+
+struct fb_fix_screeninfo32 {
+	char			id[16];
+        __kernel_caddr_t32	smem_start;
+	__u32			smem_len;
+	__u32			type;
+	__u32			type_aux;
+	__u32			visual;
+	__u16			xpanstep;
+	__u16			ypanstep;
+	__u16			ywrapstep;
+	__u32			line_length;
+        __kernel_caddr_t32	mmio_start;
+	__u32			mmio_len;
+	__u32			accel;
+	__u16			reserved[3];
+};
+
+struct fb_cmap32 {
+	__u32			start;
+	__u32			len;
+	__kernel_caddr_t32	red;
+	__kernel_caddr_t32	green;
+	__kernel_caddr_t32	blue;
+	__kernel_caddr_t32	transp;
+};
+
+static int fb_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	u32 red = 0, green = 0, blue = 0, transp = 0;
+	struct fb_fix_screeninfo fix;
+	struct fb_cmap cmap;
+	void *karg;
+	int err = 0;
+
+	memset(&cmap, 0, sizeof(cmap));
+	switch (cmd) {
+	case FBIOGET_FSCREENINFO:
+		karg = &fix;
+		break;
+	case FBIOGETCMAP:
+	case FBIOPUTCMAP:
+		karg = &cmap;
+		err = __get_user(cmap.start, &((struct fb_cmap32 *)arg)->start);
+		err |= __get_user(cmap.len, &((struct fb_cmap32 *)arg)->len);
+		err |= __get_user(red, &((struct fb_cmap32 *)arg)->red);
+		err |= __get_user(green, &((struct fb_cmap32 *)arg)->green);
+		err |= __get_user(blue, &((struct fb_cmap32 *)arg)->blue);
+		err |= __get_user(transp, &((struct fb_cmap32 *)arg)->transp);
+		if (err) {
+			err = -EFAULT;
+			goto out;
+		}
+		err = -ENOMEM;
+		cmap.red = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL);
+		if (!cmap.red)
+			goto out;
+		cmap.green = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL);
+		if (!cmap.green)
+			goto out;
+		cmap.blue = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL);
+		if (!cmap.blue)
+			goto out;
+		if (transp) {
+			cmap.transp = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL);
+			if (!cmap.transp)
+				goto out;
+		}
+			
+		if (cmd == FBIOGETCMAP)
+			break;
+
+		err = __copy_from_user(cmap.red, (char *)A(red), cmap.len * sizeof(__u16));
+		err |= __copy_from_user(cmap.green, (char *)A(green), cmap.len * sizeof(__u16));
+		err |= __copy_from_user(cmap.blue, (char *)A(blue), cmap.len * sizeof(__u16));
+		if (cmap.transp) err |= __copy_from_user(cmap.transp, (char *)A(transp), cmap.len * sizeof(__u16));
+		if (err) {
+			err = -EFAULT;
+			goto out;
+		}
+		break;
+	default:
+		do {
+			static int count = 0;
+			if (++count <= 20)
+				printk(KERN_WARNING
+					"%s: Unknown fb ioctl cmd fd(%d) "
+					"cmd(%08x) arg(%08lx)\n",
+					__FUNCTION__, fd, cmd, arg);
+		} while(0);
+		return -ENOSYS;
+	}
+	set_fs(KERNEL_DS);
+	err = sys_ioctl(fd, cmd, (unsigned long)karg);
+	set_fs(old_fs);
+	if (err)
+		goto out;
+	switch (cmd) {
+		struct fb_fix_screeninfo32 fix32;
+	case FBIOGET_FSCREENINFO:
+		memset(&fix32, 0, sizeof(fix32));
+		memcpy(fix32.id, fix.id, sizeof(fix32.id));
+		fix32.smem_start = (__u32)(unsigned long)fix.smem_start;
+		fix32.smem_len	= fix.smem_len;
+		fix32.type	= fix.type;
+		fix32.type_aux	= fix.type_aux;
+		fix32.visual	= fix.visual;
+		fix32.xpanstep	= fix.xpanstep;
+		fix32.ypanstep	= fix.ypanstep;
+		fix32.ywrapstep = fix.ywrapstep;
+		fix32.line_length = fix.line_length;
+		fix32.mmio_start = (__u32)(unsigned long)fix.mmio_start;
+		fix32.mmio_len	= fix.mmio_len;
+		fix32.accel	= fix.accel;
+		memcpy(fix32.reserved, fix.reserved, sizeof(fix32.reserved));
+		err = __copy_to_user((void *) arg, (const void *) &fix32, sizeof(fix32));
+
+printk("fix  : %lx %x  %x %x %x  %x %x %x %x  %lx %x %x\n",
+	fix.smem_start, fix.smem_len,
+	fix.type, fix.type_aux, fix.visual,
+	fix.xpanstep, fix.ypanstep, fix.ywrapstep, fix.line_length,
+	fix.mmio_start, fix.mmio_len, fix.accel);
+printk("fix32: %x %x  %x %x %x  %x %x %x %x  %x %x %x\n",
+	fix32.smem_start, fix32.smem_len,
+	fix32.type, fix32.type_aux, fix32.visual,
+	fix32.xpanstep, fix32.ypanstep, fix32.ywrapstep, fix32.line_length,
+	fix32.mmio_start, fix32.mmio_len, fix32.accel);
+
+		break;
+	case FBIOGETCMAP:
+		err = __copy_to_user((char *)A(red), cmap.red, cmap.len * sizeof(__u16));
+		err |= __copy_to_user((char *)A(green), cmap.blue, cmap.len * sizeof(__u16));
+		err |= __copy_to_user((char *)A(blue), cmap.blue, cmap.len * sizeof(__u16));
+		if (cmap.transp)
+			err |= __copy_to_user((char *)A(transp), cmap.transp, cmap.len * sizeof(__u16));
+		break;
+	case FBIOPUTCMAP:
+		break;
+	}
+	if (err)
+		err = -EFAULT;
+
+out:	if (cmap.red) kfree(cmap.red);
+	if (cmap.green) kfree(cmap.green);
+	if (cmap.blue) kfree(cmap.blue);
+	if (cmap.transp) kfree(cmap.transp);
+	return err;
+}
+
+static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	unsigned long kval;
+	unsigned int *uvp;
+	int error;
+
+	set_fs(KERNEL_DS);
+	error = sys_ioctl(fd, cmd, (long)&kval);
+	set_fs(old_fs);
+
+	if(error == 0) {
+		uvp = (unsigned int *)arg;
+		if(put_user(kval, uvp))
+			error = -EFAULT;
+	}
+	return error;
+}
+
+struct floppy_struct32 {
+	unsigned int	size;
+	unsigned int	sect;
+	unsigned int	head;
+	unsigned int	track;
+	unsigned int	stretch;
+	unsigned char	gap;
+	unsigned char	rate;
+	unsigned char	spec1;
+	unsigned char	fmt_gap;
+	const __kernel_caddr_t32 name;
+};
+
+struct floppy_drive_params32 {
+	char		cmos;
+	u32		max_dtr;
+	u32		hlt;
+	u32		hut;
+	u32		srt;
+	u32		spinup;
+	u32		spindown;
+	unsigned char	spindown_offset;
+	unsigned char	select_delay;
+	unsigned char	rps;
+	unsigned char	tracks;
+	u32		timeout;
+	unsigned char	interleave_sect;
+	struct floppy_max_errors max_errors;
+	char		flags;
+	char		read_track;
+	short		autodetect[8];
+	int		checkfreq;
+	int		native_format;
+};
+
+struct floppy_drive_struct32 {
+	signed char	flags;
+	u32		spinup_date;
+	u32		select_date;
+	u32		first_read_date;
+	short		probed_format;
+	short		track;
+	short		maxblock;
+	short		maxtrack;
+	int		generation;
+	int		keep_data;
+	int		fd_ref;
+	int		fd_device;
+	int		last_checked;
+	__kernel_caddr_t32 dmabuf;
+	int		bufblocks;
+};
+
+struct floppy_fdc_state32 {
+	int		spec1;
+	int		spec2;
+	int		dtr;
+	unsigned char	version;
+	unsigned char	dor;
+	u32		address;
+	unsigned int	rawcmd:2;
+	unsigned int	reset:1;
+	unsigned int	need_configure:1;
+	unsigned int	perp_mode:2;
+	unsigned int	has_fifo:1;
+	unsigned int	driver_version;
+	unsigned char	track[4];
+};
+
+struct floppy_write_errors32 {
+	unsigned int	write_errors;
+	u32		first_error_sector;
+	int		first_error_generation;
+	u32		last_error_sector;
+	int		last_error_generation;
+	unsigned int	badness;
+};
+
+#define FDSETPRM32 _IOW(2, 0x42, struct floppy_struct32)
+#define FDDEFPRM32 _IOW(2, 0x43, struct floppy_struct32)
+#define FDGETPRM32 _IOR(2, 0x04, struct floppy_struct32)
+#define FDSETDRVPRM32 _IOW(2, 0x90, struct floppy_drive_params32)
+#define FDGETDRVPRM32 _IOR(2, 0x11, struct floppy_drive_params32)
+#define FDGETDRVSTAT32 _IOR(2, 0x12, struct floppy_drive_struct32)
+#define FDPOLLDRVSTAT32 _IOR(2, 0x13, struct floppy_drive_struct32)
+#define FDGETFDCSTAT32 _IOR(2, 0x15, struct floppy_fdc_state32)
+#define FDWERRORGET32  _IOR(2, 0x17, struct floppy_write_errors32)
+
+static struct {
+	unsigned int	cmd32;
+	unsigned int	cmd;
+} fd_ioctl_trans_table[] = {
+	{ FDSETPRM32, FDSETPRM },
+	{ FDDEFPRM32, FDDEFPRM },
+	{ FDGETPRM32, FDGETPRM },
+	{ FDSETDRVPRM32, FDSETDRVPRM },
+	{ FDGETDRVPRM32, FDGETDRVPRM },
+	{ FDGETDRVSTAT32, FDGETDRVSTAT },
+	{ FDPOLLDRVSTAT32, FDPOLLDRVSTAT },
+	{ FDGETFDCSTAT32, FDGETFDCSTAT },
+	{ FDWERRORGET32, FDWERRORGET }
+};
+
+#define NR_FD_IOCTL_TRANS (sizeof(fd_ioctl_trans_table)/sizeof(fd_ioctl_trans_table[0]))
+
+static int fd_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	void *karg = NULL;
+	unsigned int kcmd = 0;
+	int i, err;
+
+	for (i = 0; i < NR_FD_IOCTL_TRANS; i++)
+		if (cmd == fd_ioctl_trans_table[i].cmd32) {
+			kcmd = fd_ioctl_trans_table[i].cmd;
+			break;
+		}
+	if (!kcmd)
+		return -EINVAL;
+
+	switch (cmd) {
+		case FDSETPRM32:
+		case FDDEFPRM32:
+		case FDGETPRM32:
+		{
+			struct floppy_struct *f;
+
+			f = karg = kmalloc(sizeof(struct floppy_struct), GFP_KERNEL);
+			if (!karg)
+				return -ENOMEM;
+			if (cmd == FDGETPRM32)
+				break;
+			err = __get_user(f->size, &((struct floppy_struct32 *)arg)->size);
+			err |= __get_user(f->sect, &((struct floppy_struct32 *)arg)->sect);
+			err |= __get_user(f->head, &((struct floppy_struct32 *)arg)->head);
+			err |= __get_user(f->track, &((struct floppy_struct32 *)arg)->track);
+			err |= __get_user(f->stretch, &((struct floppy_struct32 *)arg)->stretch);
+			err |= __get_user(f->gap, &((struct floppy_struct32 *)arg)->gap);
+			err |= __get_user(f->rate, &((struct floppy_struct32 *)arg)->rate);
+			err |= __get_user(f->spec1, &((struct floppy_struct32 *)arg)->spec1);
+			err |= __get_user(f->fmt_gap, &((struct floppy_struct32 *)arg)->fmt_gap);
+			err |= __get_user((u64)f->name, &((struct floppy_struct32 *)arg)->name);
+			if (err) {
+				err = -EFAULT;
+				goto out;
+			}
+			break;
+		}
+		case FDSETDRVPRM32:
+		case FDGETDRVPRM32:
+		{
+			struct floppy_drive_params *f;
+
+			f = karg = kmalloc(sizeof(struct floppy_drive_params), GFP_KERNEL);
+			if (!karg)
+				return -ENOMEM;
+			if (cmd == FDGETDRVPRM32)
+				break;
+			err = __get_user(f->cmos, &((struct floppy_drive_params32 *)arg)->cmos);
+			err |= __get_user(f->max_dtr, &((struct floppy_drive_params32 *)arg)->max_dtr);
+			err |= __get_user(f->hlt, &((struct floppy_drive_params32 *)arg)->hlt);
+			err |= __get_user(f->hut, &((struct floppy_drive_params32 *)arg)->hut);
+			err |= __get_user(f->srt, &((struct floppy_drive_params32 *)arg)->srt);
+			err |= __get_user(f->spinup, &((struct floppy_drive_params32 *)arg)->spinup);
+			err |= __get_user(f->spindown, &((struct floppy_drive_params32 *)arg)->spindown);
+			err |= __get_user(f->spindown_offset, &((struct floppy_drive_params32 *)arg)->spindown_offset);
+			err |= __get_user(f->select_delay, &((struct floppy_drive_params32 *)arg)->select_delay);
+			err |= __get_user(f->rps, &((struct floppy_drive_params32 *)arg)->rps);
+			err |= __get_user(f->tracks, &((struct floppy_drive_params32 *)arg)->tracks);
+			err |= __get_user(f->timeout, &((struct floppy_drive_params32 *)arg)->timeout);
+			err |= __get_user(f->interleave_sect, &((struct floppy_drive_params32 *)arg)->interleave_sect);
+			err |= __copy_from_user(&f->max_errors, &((struct floppy_drive_params32 *)arg)->max_errors, sizeof(f->max_errors));
+			err |= __get_user(f->flags, &((struct floppy_drive_params32 *)arg)->flags);
+			err |= __get_user(f->read_track, &((struct floppy_drive_params32 *)arg)->read_track);
+			err |= __copy_from_user(f->autodetect, ((struct floppy_drive_params32 *)arg)->autodetect, sizeof(f->autodetect));
+			err |= __get_user(f->checkfreq, &((struct floppy_drive_params32 *)arg)->checkfreq);
+			err |= __get_user(f->native_format, &((struct floppy_drive_params32 *)arg)->native_format);
+			if (err) {
+				err = -EFAULT;
+				goto out;
+			}
+			break;
+		}
+		case FDGETDRVSTAT32:
+		case FDPOLLDRVSTAT32:
+			karg = kmalloc(sizeof(struct floppy_drive_struct), GFP_KERNEL);
+			if (!karg)
+				return -ENOMEM;
+			break;
+		case FDGETFDCSTAT32:
+			karg = kmalloc(sizeof(struct floppy_fdc_state), GFP_KERNEL);
+			if (!karg)
+				return -ENOMEM;
+			break;
+		case FDWERRORGET32:
+			karg = kmalloc(sizeof(struct floppy_write_errors), GFP_KERNEL);
+			if (!karg)
+				return -ENOMEM;
+			break;
+		default:
+			return -EINVAL;
+	}
+	set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, kcmd, (unsigned long)karg);
+	set_fs (old_fs);
+	if (err)
+		goto out;
+	switch (cmd) {
+		case FDGETPRM32:
+		{
+			struct floppy_struct *f = karg;
+
+			err = __put_user(f->size, &((struct floppy_struct32 *)arg)->size);
+			err |= __put_user(f->sect, &((struct floppy_struct32 *)arg)->sect);
+			err |= __put_user(f->head, &((struct floppy_struct32 *)arg)->head);
+			err |= __put_user(f->track, &((struct floppy_struct32 *)arg)->track);
+			err |= __put_user(f->stretch, &((struct floppy_struct32 *)arg)->stretch);
+			err |= __put_user(f->gap, &((struct floppy_struct32 *)arg)->gap);
+			err |= __put_user(f->rate, &((struct floppy_struct32 *)arg)->rate);
+			err |= __put_user(f->spec1, &((struct floppy_struct32 *)arg)->spec1);
+			err |= __put_user(f->fmt_gap, &((struct floppy_struct32 *)arg)->fmt_gap);
+			err |= __put_user((u64)f->name, &((struct floppy_struct32 *)arg)->name);
+			break;
+		}
+		case FDGETDRVPRM32:
+		{
+			struct floppy_drive_params *f = karg;
+
+			err = __put_user(f->cmos, &((struct floppy_drive_params32 *)arg)->cmos);
+			err |= __put_user(f->max_dtr, &((struct floppy_drive_params32 *)arg)->max_dtr);
+			err |= __put_user(f->hlt, &((struct floppy_drive_params32 *)arg)->hlt);
+			err |= __put_user(f->hut, &((struct floppy_drive_params32 *)arg)->hut);
+			err |= __put_user(f->srt, &((struct floppy_drive_params32 *)arg)->srt);
+			err |= __put_user(f->spinup, &((struct floppy_drive_params32 *)arg)->spinup);
+			err |= __put_user(f->spindown, &((struct floppy_drive_params32 *)arg)->spindown);
+			err |= __put_user(f->spindown_offset, &((struct floppy_drive_params32 *)arg)->spindown_offset);
+			err |= __put_user(f->select_delay, &((struct floppy_drive_params32 *)arg)->select_delay);
+			err |= __put_user(f->rps, &((struct floppy_drive_params32 *)arg)->rps);
+			err |= __put_user(f->tracks, &((struct floppy_drive_params32 *)arg)->tracks);
+			err |= __put_user(f->timeout, &((struct floppy_drive_params32 *)arg)->timeout);
+			err |= __put_user(f->interleave_sect, &((struct floppy_drive_params32 *)arg)->interleave_sect);
+			err |= __copy_to_user(&((struct floppy_drive_params32 *)arg)->max_errors, &f->max_errors, sizeof(f->max_errors));
+			err |= __put_user(f->flags, &((struct floppy_drive_params32 *)arg)->flags);
+			err |= __put_user(f->read_track, &((struct floppy_drive_params32 *)arg)->read_track);
+			err |= __copy_to_user(((struct floppy_drive_params32 *)arg)->autodetect, f->autodetect, sizeof(f->autodetect));
+			err |= __put_user(f->checkfreq, &((struct floppy_drive_params32 *)arg)->checkfreq);
+			err |= __put_user(f->native_format, &((struct floppy_drive_params32 *)arg)->native_format);
+			break;
+		}
+		case FDGETDRVSTAT32:
+		case FDPOLLDRVSTAT32:
+		{
+			struct floppy_drive_struct *f = karg;
+
+			err = __put_user(f->flags, &((struct floppy_drive_struct32 *)arg)->flags);
+			err |= __put_user(f->spinup_date, &((struct floppy_drive_struct32 *)arg)->spinup_date);
+			err |= __put_user(f->select_date, &((struct floppy_drive_struct32 *)arg)->select_date);
+			err |= __put_user(f->first_read_date, &((struct floppy_drive_struct32 *)arg)->first_read_date);
+			err |= __put_user(f->probed_format, &((struct floppy_drive_struct32 *)arg)->probed_format);
+			err |= __put_user(f->track, &((struct floppy_drive_struct32 *)arg)->track);
+			err |= __put_user(f->maxblock, &((struct floppy_drive_struct32 *)arg)->maxblock);
+			err |= __put_user(f->maxtrack, &((struct floppy_drive_struct32 *)arg)->maxtrack);
+			err |= __put_user(f->generation, &((struct floppy_drive_struct32 *)arg)->generation);
+			err |= __put_user(f->keep_data, &((struct floppy_drive_struct32 *)arg)->keep_data);
+			err |= __put_user(f->fd_ref, &((struct floppy_drive_struct32 *)arg)->fd_ref);
+			err |= __put_user(f->fd_device, &((struct floppy_drive_struct32 *)arg)->fd_device);
+			err |= __put_user(f->last_checked, &((struct floppy_drive_struct32 *)arg)->last_checked);
+			err |= __put_user((u64)f->dmabuf, &((struct floppy_drive_struct32 *)arg)->dmabuf);
+			err |= __put_user((u64)f->bufblocks, &((struct floppy_drive_struct32 *)arg)->bufblocks);
+			break;
+		}
+		case FDGETFDCSTAT32:
+		{
+			struct floppy_fdc_state *f = karg;
+
+			err = __put_user(f->spec1, &((struct floppy_fdc_state32 *)arg)->spec1);
+			err |= __put_user(f->spec2, &((struct floppy_fdc_state32 *)arg)->spec2);
+			err |= __put_user(f->dtr, &((struct floppy_fdc_state32 *)arg)->dtr);
+			err |= __put_user(f->version, &((struct floppy_fdc_state32 *)arg)->version);
+			err |= __put_user(f->dor, &((struct floppy_fdc_state32 *)arg)->dor);
+			err |= __put_user(f->address, &((struct floppy_fdc_state32 *)arg)->address);
+			err |= __copy_to_user((char *)&((struct floppy_fdc_state32 *)arg)->address
+			    		   + sizeof(((struct floppy_fdc_state32 *)arg)->address),
+					   (char *)&f->address + sizeof(f->address), sizeof(int));
+			err |= __put_user(f->driver_version, &((struct floppy_fdc_state32 *)arg)->driver_version);
+			err |= __copy_to_user(((struct floppy_fdc_state32 *)arg)->track, f->track, sizeof(f->track));
+			break;
+		}
+		case FDWERRORGET32:
+		{
+			struct floppy_write_errors *f = karg;
+
+			err = __put_user(f->write_errors, &((struct floppy_write_errors32 *)arg)->write_errors);
+			err |= __put_user(f->first_error_sector, &((struct floppy_write_errors32 *)arg)->first_error_sector);
+			err |= __put_user(f->first_error_generation, &((struct floppy_write_errors32 *)arg)->first_error_generation);
+			err |= __put_user(f->last_error_sector, &((struct floppy_write_errors32 *)arg)->last_error_sector);
+			err |= __put_user(f->last_error_generation, &((struct floppy_write_errors32 *)arg)->last_error_generation);
+			err |= __put_user(f->badness, &((struct floppy_write_errors32 *)arg)->badness);
+			break;
+		}
+		default:
+			break;
+	}
+	if (err)
+		err = -EFAULT;
+
+out:	if (karg) kfree(karg);
+	return err;
+}
+
+struct ppp_option_data32 {
+	__kernel_caddr_t32	ptr;
+	__u32			length;
+	int			transmit;
+};
+#define PPPIOCSCOMPRESS32	_IOW('t', 77, struct ppp_option_data32)
+
+struct ppp_idle32 {
+	__kernel_time_t32 xmit_idle;
+	__kernel_time_t32 recv_idle;
+};
+#define PPPIOCGIDLE32		_IOR('t', 63, struct ppp_idle32)
+
+static int ppp_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	struct ppp_option_data32 data32;
+	struct ppp_option_data data;
+	struct ppp_idle32 idle32;
+	struct ppp_idle idle;
+	unsigned int kcmd;
+	void *karg;
+	int err = 0;
+
+	switch (cmd) {
+	case PPPIOCGIDLE32:
+		kcmd = PPPIOCGIDLE;
+		karg = &idle;
+		break;
+	case PPPIOCSCOMPRESS32:
+		if (copy_from_user(&data32, (struct ppp_option_data32 *)arg, sizeof(struct ppp_option_data32)))
+			return -EFAULT;
+		data.ptr = kmalloc (data32.length, GFP_KERNEL);
+		if (!data.ptr)
+			return -ENOMEM;
+		if (copy_from_user(data.ptr, (__u8 *)A(data32.ptr), data32.length)) {
+			kfree(data.ptr);
+			return -EFAULT;
+		}
+		data.length = data32.length;
+		data.transmit = data32.transmit;
+		kcmd = PPPIOCSCOMPRESS;
+		karg = &data;
+		break;
+	default:
+		do {
+			static int count = 0;
+			if (++count <= 20)
+				printk(KERN_WARNING
+					"ppp_ioctl: Unknown cmd fd(%d) "
+					"cmd(%08x) arg(%08x)\n",
+					(int)fd, (unsigned int)cmd, (unsigned int)arg);
+		} while(0);
+		return -EINVAL;
+	}
+	set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, kcmd, (unsigned long)karg);
+	set_fs (old_fs);
+	switch (cmd) {
+	case PPPIOCGIDLE32:
+		if (err)
+			return err;
+		idle32.xmit_idle = idle.xmit_idle;
+		idle32.recv_idle = idle.recv_idle;
+		if (copy_to_user((struct ppp_idle32 *)arg, &idle32, sizeof(struct ppp_idle32)))
+			return -EFAULT;
+		break;
+	case PPPIOCSCOMPRESS32:
+		kfree(data.ptr);
+		break;
+	default:
+		break;
+	}
+	return err;
+}
+
+
+struct mtget32 {
+	__u32	mt_type;
+	__u32	mt_resid;
+	__u32	mt_dsreg;
+	__u32	mt_gstat;
+	__u32	mt_erreg;
+	__kernel_daddr_t32	mt_fileno;
+	__kernel_daddr_t32	mt_blkno;
+};
+#define MTIOCGET32	_IOR('m', 2, struct mtget32)
+
+struct mtpos32 {
+	__u32	mt_blkno;
+};
+#define MTIOCPOS32	_IOR('m', 3, struct mtpos32)
+
+struct mtconfiginfo32 {
+	__u32	mt_type;
+	__u32	ifc_type;
+	__u16	irqnr;
+	__u16	dmanr;
+	__u16	port;
+	__u32	debug;
+	__u32	have_dens:1;
+	__u32	have_bsf:1;
+	__u32	have_fsr:1;
+	__u32	have_bsr:1;
+	__u32	have_eod:1;
+	__u32	have_seek:1;
+	__u32	have_tell:1;
+	__u32	have_ras1:1;
+	__u32	have_ras2:1;
+	__u32	have_ras3:1;
+	__u32	have_qfa:1;
+	__u32	pad1:5;
+	char	reserved[10];
+};
+#define	MTIOCGETCONFIG32	_IOR('m', 4, struct mtconfiginfo32)
+#define	MTIOCSETCONFIG32	_IOW('m', 5, struct mtconfiginfo32)
+
+static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	struct mtconfiginfo info;
+	struct mtget get;
+	struct mtpos pos;
+	unsigned long kcmd;
+	void *karg;
+	int err = 0;
+
+	switch(cmd) {
+	case MTIOCPOS32:
+		kcmd = MTIOCPOS;
+		karg = &pos;
+		break;
+	case MTIOCGET32:
+		kcmd = MTIOCGET;
+		karg = &get;
+		break;
+	case MTIOCGETCONFIG32:
+		kcmd = MTIOCGETCONFIG;
+		karg = &info;
+		break;
+	case MTIOCSETCONFIG32:
+		kcmd = MTIOCSETCONFIG;
+		karg = &info;
+		err = __get_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type);
+		err |= __get_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type);
+		err |= __get_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr);
+		err |= __get_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr);
+		err |= __get_user(info.port, &((struct mtconfiginfo32 *)arg)->port);
+		err |= __get_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug);
+		err |= __copy_from_user((char *)&info.debug + sizeof(info.debug),
+				     (char *)&((struct mtconfiginfo32 *)arg)->debug
+				     + sizeof(((struct mtconfiginfo32 *)arg)->debug), sizeof(__u32));
+		if (err)
+			return -EFAULT;
+		break;
+	default:
+		do {
+			static int count = 0;
+			if (++count <= 20)
+				printk(KERN_WARNING
+					"mt_ioctl: Unknown cmd fd(%d) "
+					"cmd(%08x) arg(%08x)\n",
+					(int)fd, (unsigned int)cmd, (unsigned int)arg);
+		} while(0);
+		return -EINVAL;
+	}
+	set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, kcmd, (unsigned long)karg);
+	set_fs (old_fs);
+	if (err)
+		return err;
+	switch (cmd) {
+	case MTIOCPOS32:
+		err = __put_user(pos.mt_blkno, &((struct mtpos32 *)arg)->mt_blkno);
+		break;
+	case MTIOCGET32:
+		err = __put_user(get.mt_type, &((struct mtget32 *)arg)->mt_type);
+		err |= __put_user(get.mt_resid, &((struct mtget32 *)arg)->mt_resid);
+		err |= __put_user(get.mt_dsreg, &((struct mtget32 *)arg)->mt_dsreg);
+		err |= __put_user(get.mt_gstat, &((struct mtget32 *)arg)->mt_gstat);
+		err |= __put_user(get.mt_erreg, &((struct mtget32 *)arg)->mt_erreg);
+		err |= __put_user(get.mt_fileno, &((struct mtget32 *)arg)->mt_fileno);
+		err |= __put_user(get.mt_blkno, &((struct mtget32 *)arg)->mt_blkno);
+		break;
+	case MTIOCGETCONFIG32:
+		err = __put_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type);
+		err |= __put_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type);
+		err |= __put_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr);
+		err |= __put_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr);
+		err |= __put_user(info.port, &((struct mtconfiginfo32 *)arg)->port);
+		err |= __put_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug);
+		err |= __copy_to_user((char *)&((struct mtconfiginfo32 *)arg)->debug
+			    		   + sizeof(((struct mtconfiginfo32 *)arg)->debug),
+					   (char *)&info.debug + sizeof(info.debug), sizeof(__u32));
+		break;
+	case MTIOCSETCONFIG32:
+		break;
+	}
+	return err ? -EFAULT: 0;
+}
+
+struct cdrom_read32 {
+	int			cdread_lba;
+	__kernel_caddr_t32	cdread_bufaddr;
+	int			cdread_buflen;
+};
+
+struct cdrom_read_audio32 {
+	union cdrom_addr	addr;
+	u_char			addr_format;
+	int			nframes;
+	__kernel_caddr_t32	buf;
+};
+
+struct cdrom_generic_command32 {
+	unsigned char		cmd[CDROM_PACKET_SIZE];
+	__kernel_caddr_t32	buffer;
+	unsigned int		buflen;
+	int			stat;
+	__kernel_caddr_t32	sense;
+	__kernel_caddr_t32	reserved[3];
+};
+
+static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	struct cdrom_read cdread;
+	struct cdrom_read_audio cdreadaudio;
+	struct cdrom_generic_command cgc;
+	__kernel_caddr_t32 addr;
+	char *data = 0;
+	void *karg;
+	int err = 0;
+
+	switch(cmd) {
+	case CDROMREADMODE2:
+	case CDROMREADMODE1:
+	case CDROMREADRAW:
+	case CDROMREADCOOKED:
+		karg = &cdread;
+		err = __get_user(cdread.cdread_lba, &((struct cdrom_read32 *)arg)->cdread_lba);
+		err |= __get_user(addr, &((struct cdrom_read32 *)arg)->cdread_bufaddr);
+		err |= __get_user(cdread.cdread_buflen, &((struct cdrom_read32 *)arg)->cdread_buflen);
+		if (err)
+			return -EFAULT;
+		data = kmalloc(cdread.cdread_buflen, GFP_KERNEL);
+		if (!data)
+			return -ENOMEM;
+		cdread.cdread_bufaddr = data;
+		break;
+	case CDROMREADAUDIO:
+		karg = &cdreadaudio;
+		err = copy_from_user(&cdreadaudio.addr, &((struct cdrom_read_audio32 *)arg)->addr, sizeof(cdreadaudio.addr));
+		err |= __get_user(cdreadaudio.addr_format, &((struct cdrom_read_audio32 *)arg)->addr_format);
+		err |= __get_user(cdreadaudio.nframes, &((struct cdrom_read_audio32 *)arg)->nframes); 
+		err |= __get_user(addr, &((struct cdrom_read_audio32 *)arg)->buf);
+		if (err)
+			return -EFAULT;
+		data = kmalloc(cdreadaudio.nframes * 2352, GFP_KERNEL);
+		if (!data)
+			return -ENOMEM;
+		cdreadaudio.buf = data;
+		break;
+	case CDROM_SEND_PACKET:
+		karg = &cgc;
+		err = copy_from_user(cgc.cmd, &((struct cdrom_generic_command32 *)arg)->cmd, sizeof(cgc.cmd));
+		err |= __get_user(addr, &((struct cdrom_generic_command32 *)arg)->buffer);
+		err |= __get_user(cgc.buflen, &((struct cdrom_generic_command32 *)arg)->buflen);
+		if (err)
+			return -EFAULT;
+		if ((data = kmalloc(cgc.buflen, GFP_KERNEL)) == NULL)
+			return -ENOMEM;
+		cgc.buffer = data;
+		break;
+	default:
+		do {
+			static int count = 0;
+			if (++count <= 20)
+				printk(KERN_WARNING
+					"cdrom_ioctl: Unknown cmd fd(%d) "
+					"cmd(%08x) arg(%08x)\n",
+					(int)fd, (unsigned int)cmd, (unsigned int)arg);
+		} while(0);
+		return -EINVAL;
+	}
+	set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, cmd, (unsigned long)karg);
+	set_fs (old_fs);
+	if (err)
+		goto out;
+	switch (cmd) {
+	case CDROMREADMODE2:
+	case CDROMREADMODE1:
+	case CDROMREADRAW:
+	case CDROMREADCOOKED:
+		err = copy_to_user((char *)A(addr), data, cdread.cdread_buflen);
+		break;
+	case CDROMREADAUDIO:
+		err = copy_to_user((char *)A(addr), data, cdreadaudio.nframes * 2352);
+		break;
+	case CDROM_SEND_PACKET:
+		err = copy_to_user((char *)A(addr), data, cgc.buflen);
+		break;
+	default:
+		break;
+	}
+out:	if (data)
+		kfree(data);
+	return err ? -EFAULT : 0;
+}
+
+struct loop_info32 {
+	int			lo_number;      /* ioctl r/o */
+	__kernel_dev_t32	lo_device;      /* ioctl r/o */
+	unsigned int		lo_inode;       /* ioctl r/o */
+	__kernel_dev_t32	lo_rdevice;     /* ioctl r/o */
+	int			lo_offset;
+	int			lo_encrypt_type;
+	int			lo_encrypt_key_size;    /* ioctl w/o */
+	int			lo_flags;       /* ioctl r/o */
+	char			lo_name[LO_NAME_SIZE];
+	unsigned char		lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
+	unsigned int		lo_init[2];
+	char			reserved[4];
+};
+
+static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	struct loop_info l;
+	int err = -EINVAL;
+
+	switch(cmd) {
+	case LOOP_SET_STATUS:
+		err = get_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number);
+		err |= __get_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device);
+		err |= __get_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode);
+		err |= __get_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice);
+		err |= __copy_from_user((char *)&l.lo_offset, (char *)&((struct loop_info32 *)arg)->lo_offset,
+					   8 + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset);
+		if (err) {
+			err = -EFAULT;
+		} else {
+			set_fs (KERNEL_DS);
+			err = sys_ioctl (fd, cmd, (unsigned long)&l);
+			set_fs (old_fs);
+		}
+		break;
+	case LOOP_GET_STATUS:
+		set_fs (KERNEL_DS);
+		err = sys_ioctl (fd, cmd, (unsigned long)&l);
+		set_fs (old_fs);
+		if (!err) {
+			err = put_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number);
+			err |= __put_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device);
+			err |= __put_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode);
+			err |= __put_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice);
+			err |= __copy_to_user((char *)&((struct loop_info32 *)arg)->lo_offset,
+					   (char *)&l.lo_offset, (unsigned long)l.lo_init - (unsigned long)&l.lo_offset);
+			if (err)
+				err = -EFAULT;
+		}
+		break;
+	default: {
+		static int count = 0;
+		if (++count <= 20)
+			printk(KERN_WARNING
+				"%s: Unknown loop ioctl cmd, fd(%d) "
+				"cmd(%08x) arg(%08lx)\n",
+				__FUNCTION__, fd, cmd, arg);
+	}
+	}
+	return err;
+}
+
+#ifdef CONFIG_VT
+extern int tty_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg);
+
+static int vt_check(struct file *file)
+{
+	struct tty_struct *tty;
+	struct inode *inode = file->f_dentry->d_inode;
+	
+	if (file->f_op->ioctl != tty_ioctl)
+		return -EINVAL;
+	                
+	tty = (struct tty_struct *)file->private_data;
+	if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl"))
+		return -EINVAL;
+	                                                
+	if (tty->driver.ioctl != vt_ioctl)
+		return -EINVAL;
+	
+	/*
+	 * To have permissions to do most of the vt ioctls, we either have
+	 * to be the owner of the tty, or super-user.
+	 */
+	if (current->tty == tty || suser())
+		return 1;
+	return 0;                                                    
+}
+
+struct consolefontdesc32 {
+	unsigned short charcount;       /* characters in font (256 or 512) */
+	unsigned short charheight;      /* scan lines per character (1-32) */
+	u32 chardata;			/* font data in expanded form */
+};
+
+static int do_fontx_ioctl(unsigned int fd, int cmd, struct consolefontdesc32 *user_cfd, struct file *file)
+{
+	struct consolefontdesc cfdarg;
+	struct console_font_op op;
+	int i, perm;
+
+	perm = vt_check(file);
+	if (perm < 0) return perm;
+	
+	if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc32)))
+		return -EFAULT;
+	
+	cfdarg.chardata = (unsigned char *)A(((struct consolefontdesc32 *)&cfdarg)->chardata);
+ 	
+	switch (cmd) {
+	case PIO_FONTX:
+		if (!perm)
+			return -EPERM;
+		op.op = KD_FONT_OP_SET;
+		op.flags = 0;
+		op.width = 8;
+		op.height = cfdarg.charheight;
+		op.charcount = cfdarg.charcount;
+		op.data = cfdarg.chardata;
+		return con_font_op(fg_console, &op);
+	case GIO_FONTX:
+		if (!cfdarg.chardata)
+			return 0;
+		op.op = KD_FONT_OP_GET;
+		op.flags = 0;
+		op.width = 8;
+		op.height = cfdarg.charheight;
+		op.charcount = cfdarg.charcount;
+		op.data = cfdarg.chardata;
+		i = con_font_op(fg_console, &op);
+		if (i)
+			return i;
+		cfdarg.charheight = op.height;
+		cfdarg.charcount = op.charcount;
+		((struct consolefontdesc32 *)&cfdarg)->chardata	= (unsigned long)cfdarg.chardata;
+		if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc32)))
+			return -EFAULT;
+		return 0;
+	}
+	return -EINVAL;
+}
+
+struct console_font_op32 {
+	unsigned int op;        /* operation code KD_FONT_OP_* */
+	unsigned int flags;     /* KD_FONT_FLAG_* */
+	unsigned int width, height;     /* font size */
+	unsigned int charcount;
+	u32 data;    /* font data with height fixed to 32 */
+};
+                                        
+static int do_kdfontop_ioctl(unsigned int fd, unsigned int cmd, struct console_font_op32 *fontop, struct file *file)
+{
+	struct console_font_op op;
+	int perm = vt_check(file), i;
+	struct vt_struct *vt;
+	
+	if (perm < 0) return perm;
+	
+	if (copy_from_user(&op, (void *) fontop, sizeof(struct console_font_op32)))
+		return -EFAULT;
+	if (!perm && op.op != KD_FONT_OP_GET)
+		return -EPERM;
+	op.data = (unsigned char *)A(((struct console_font_op32 *)&op)->data);
+	op.flags |= KD_FONT_FLAG_OLD;
+	vt = (struct vt_struct *)((struct tty_struct *)file->private_data)->driver_data;
+	i = con_font_op(vt->vc_num, &op);
+	if (i) return i;
+	((struct console_font_op32 *)&op)->data = (unsigned long)op.data;
+	if (copy_to_user((void *) fontop, &op, sizeof(struct console_font_op32)))
+		return -EFAULT;
+	return 0;
+}
+
+struct unimapdesc32 {
+	unsigned short entry_ct;
+	u32 entries;
+};
+
+static int do_unimap_ioctl(unsigned int fd, unsigned int cmd, struct unimapdesc32 *user_ud, struct file *file)
+{
+	struct unimapdesc32 tmp;
+	int perm = vt_check(file);
+	
+	if (perm < 0) return perm;
+	if (copy_from_user(&tmp, user_ud, sizeof tmp))
+		return -EFAULT;
+	switch (cmd) {
+	case PIO_UNIMAP:
+		if (!perm) return -EPERM;
+		return con_set_unimap(fg_console, tmp.entry_ct, (struct unipair *)A(tmp.entries));
+	case GIO_UNIMAP:
+		return con_get_unimap(fg_console, tmp.entry_ct, &(user_ud->entry_ct), (struct unipair *)A(tmp.entries));
+	}
+	return 0;
+}
+#endif
+
+#if 0
+static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	__kernel_uid_t kuid;
+	int err;
+
+	cmd = SMB_IOC_GETMOUNTUID;
+
+	set_fs(KERNEL_DS);
+	err = sys_ioctl(fd, cmd, (unsigned long)&kuid);
+	set_fs(old_fs);
+
+	if (err >= 0)
+		err = put_user(kuid, (__kernel_uid_t32 *)arg);
+
+	return err;
+}
+#endif
+
+struct atmif_sioc32 {
+        int                number;
+        int                length;
+        __kernel_caddr_t32 arg;
+};
+
+struct atm_iobuf32 {
+	int                length;
+	__kernel_caddr_t32 buffer;
+};
+
+#define ATM_GETLINKRATE32 _IOW('a', ATMIOC_ITF+1, struct atmif_sioc32)
+#define ATM_GETNAMES32    _IOW('a', ATMIOC_ITF+3, struct atm_iobuf32)
+#define ATM_GETTYPE32     _IOW('a', ATMIOC_ITF+4, struct atmif_sioc32)
+#define ATM_GETESI32	  _IOW('a', ATMIOC_ITF+5, struct atmif_sioc32)
+#define ATM_GETADDR32	  _IOW('a', ATMIOC_ITF+6, struct atmif_sioc32)
+#define ATM_RSTADDR32	  _IOW('a', ATMIOC_ITF+7, struct atmif_sioc32)
+#define ATM_ADDADDR32	  _IOW('a', ATMIOC_ITF+8, struct atmif_sioc32)
+#define ATM_DELADDR32	  _IOW('a', ATMIOC_ITF+9, struct atmif_sioc32)
+#define ATM_GETCIRANGE32  _IOW('a', ATMIOC_ITF+10, struct atmif_sioc32)
+#define ATM_SETCIRANGE32  _IOW('a', ATMIOC_ITF+11, struct atmif_sioc32)
+#define ATM_SETESI32      _IOW('a', ATMIOC_ITF+12, struct atmif_sioc32)
+#define ATM_SETESIF32     _IOW('a', ATMIOC_ITF+13, struct atmif_sioc32)
+#define ATM_GETSTAT32     _IOW('a', ATMIOC_SARCOM+0, struct atmif_sioc32)
+#define ATM_GETSTATZ32    _IOW('a', ATMIOC_SARCOM+1, struct atmif_sioc32)
+#define ATM_GETLOOP32	  _IOW('a', ATMIOC_SARCOM+2, struct atmif_sioc32)
+#define ATM_SETLOOP32	  _IOW('a', ATMIOC_SARCOM+3, struct atmif_sioc32)
+#define ATM_QUERYLOOP32	  _IOW('a', ATMIOC_SARCOM+4, struct atmif_sioc32)
+
+static struct {
+        unsigned int cmd32;
+        unsigned int cmd;
+} atm_ioctl_map[] = {
+        { ATM_GETLINKRATE32, ATM_GETLINKRATE },
+	{ ATM_GETNAMES32,    ATM_GETNAMES },
+        { ATM_GETTYPE32,     ATM_GETTYPE },
+        { ATM_GETESI32,      ATM_GETESI },
+        { ATM_GETADDR32,     ATM_GETADDR },
+        { ATM_RSTADDR32,     ATM_RSTADDR },
+        { ATM_ADDADDR32,     ATM_ADDADDR },
+        { ATM_DELADDR32,     ATM_DELADDR },
+        { ATM_GETCIRANGE32,  ATM_GETCIRANGE },
+	{ ATM_SETCIRANGE32,  ATM_SETCIRANGE },
+	{ ATM_SETESI32,      ATM_SETESI },
+	{ ATM_SETESIF32,     ATM_SETESIF },
+	{ ATM_GETSTAT32,     ATM_GETSTAT },
+	{ ATM_GETSTATZ32,    ATM_GETSTATZ },
+	{ ATM_GETLOOP32,     ATM_GETLOOP },
+	{ ATM_SETLOOP32,     ATM_SETLOOP },
+	{ ATM_QUERYLOOP32,   ATM_QUERYLOOP }
+};
+
+#define NR_ATM_IOCTL (sizeof(atm_ioctl_map)/sizeof(atm_ioctl_map[0]))
+
+
+static int do_atm_iobuf(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct atm_iobuf32 iobuf32;
+	struct atm_iobuf   iobuf = { 0, NULL };
+	mm_segment_t old_fs;
+	int err;
+
+	err = copy_from_user(&iobuf32, (struct atm_iobuf32*)arg,
+	    sizeof(struct atm_iobuf32));
+	if (err)
+		return -EFAULT;
+
+	iobuf.length = iobuf32.length;
+
+	if (iobuf32.buffer == (__kernel_caddr_t32) NULL || iobuf32.length == 0) {
+		iobuf.buffer = (void*)(unsigned long)iobuf32.buffer;
+	} else {
+		iobuf.buffer = kmalloc(iobuf.length, GFP_KERNEL);
+		if (iobuf.buffer == NULL) {
+			err = -ENOMEM;
+			goto out;
+		}
+
+		err = copy_from_user(iobuf.buffer, A(iobuf32.buffer), iobuf.length);
+		if (err) {
+			err = -EFAULT;
+			goto out;
+		}
+	}
+
+	old_fs = get_fs(); set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, cmd, (unsigned long)&iobuf);      
+	set_fs (old_fs);
+        if(err)
+		goto out;
+
+        if(iobuf.buffer && iobuf.length > 0) {
+		err = copy_to_user(A(iobuf32.buffer), iobuf.buffer, iobuf.length);
+		if (err) {
+			err = -EFAULT;
+			goto out;
+		}
+	}
+	err = __put_user(iobuf.length, &(((struct atm_iobuf32*)arg)->length));
+
+ out:
+        if(iobuf32.buffer && iobuf32.length > 0)
+		kfree(iobuf.buffer);
+
+	return err;
+}
+
+
+static int do_atmif_sioc(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+        struct atmif_sioc32 sioc32;
+        struct atmif_sioc   sioc = { 0, 0, NULL };
+        mm_segment_t old_fs;
+        int err;
+        
+        err = copy_from_user(&sioc32, (struct atmif_sioc32*)arg,
+			     sizeof(struct atmif_sioc32));
+        if (err)
+                return -EFAULT;
+
+        sioc.number = sioc32.number;
+        sioc.length = sioc32.length;
+        
+	if (sioc32.arg == (__kernel_caddr_t32) NULL || sioc32.length == 0) {
+		sioc.arg = (void*)(unsigned long)sioc32.arg;
+        } else {
+                sioc.arg = kmalloc(sioc.length, GFP_KERNEL);
+                if (sioc.arg == NULL) {
+                        err = -ENOMEM;
+			goto out;
+		}
+                
+                err = copy_from_user(sioc.arg, A(sioc32.arg), sioc32.length);
+                if (err) {
+                        err = -EFAULT;
+                        goto out;
+                }
+        }
+        
+        old_fs = get_fs(); set_fs (KERNEL_DS);
+        err = sys_ioctl (fd, cmd, (unsigned long)&sioc);	
+        set_fs (old_fs);
+        if(err) {
+                goto out;
+	}
+        
+        if(sioc.arg && sioc.length > 0) {
+                err = copy_to_user(A(sioc32.arg), sioc.arg, sioc.length);
+                if (err) {
+                        err = -EFAULT;
+                        goto out;
+                }
+        }
+        err = __put_user(sioc.length, &(((struct atmif_sioc32*)arg)->length));
+        
+ out:
+        if(sioc32.arg && sioc32.length > 0)
+		kfree(sioc.arg);
+        
+	return err;
+}
+
+
+static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg)
+{
+        int i;
+        unsigned int cmd = 0;
+        
+	switch (cmd32) {
+	case SONET_GETSTAT:
+	case SONET_GETSTATZ:
+	case SONET_GETDIAG:
+	case SONET_SETDIAG:
+	case SONET_CLRDIAG:
+	case SONET_SETFRAMING:
+	case SONET_GETFRAMING:
+	case SONET_GETFRSENSE:
+		return do_atmif_sioc(fd, cmd32, arg);
+	}
+
+		for (i = 0; i < NR_ATM_IOCTL; i++) {
+			if (cmd32 == atm_ioctl_map[i].cmd32) {
+				cmd = atm_ioctl_map[i].cmd;
+				break;
+			}
+		}
+	        if (i == NR_ATM_IOCTL) {
+	        return -EINVAL;
+	        }
+        
+        switch (cmd) {
+	case ATM_GETNAMES:
+		return do_atm_iobuf(fd, cmd, arg);
+	    
+	case ATM_GETLINKRATE:
+        case ATM_GETTYPE:
+        case ATM_GETESI:
+        case ATM_GETADDR:
+        case ATM_RSTADDR:
+        case ATM_ADDADDR:
+        case ATM_DELADDR:
+        case ATM_GETCIRANGE:
+	case ATM_SETCIRANGE:
+	case ATM_SETESI:
+	case ATM_SETESIF:
+	case ATM_GETSTAT:
+	case ATM_GETSTATZ:
+	case ATM_GETLOOP:
+	case ATM_SETLOOP:
+	case ATM_QUERYLOOP:
+                return do_atmif_sioc(fd, cmd, arg);
+        }
+
+        return -EINVAL;
+}
+
+#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
+/* Ugh, LVM. Pitty it was not cleaned up before accepted :((. */
+typedef struct {
+	uint8_t vg_name[NAME_LEN];
+	uint32_t vg_number;
+	uint32_t vg_access;
+	uint32_t vg_status;
+	uint32_t lv_max;
+	uint32_t lv_cur;
+	uint32_t lv_open;
+	uint32_t pv_max;
+	uint32_t pv_cur;
+	uint32_t pv_act;
+	uint32_t dummy;
+	uint32_t vgda;
+	uint32_t pe_size;
+	uint32_t pe_total;
+	uint32_t pe_allocated;
+	uint32_t pvg_total;
+	u32 proc;
+	u32 pv[ABS_MAX_PV + 1];
+	u32 lv[ABS_MAX_LV + 1];
+    	uint8_t vg_uuid[UUID_LEN+1];	/* volume group UUID */
+	uint8_t dummy1[200];
+} vg32_t;
+
+typedef struct {
+	uint8_t id[2];
+	uint16_t version;
+	lvm_disk_data_t pv_on_disk;
+	lvm_disk_data_t vg_on_disk;
+	lvm_disk_data_t pv_namelist_on_disk;
+	lvm_disk_data_t lv_on_disk;
+	lvm_disk_data_t pe_on_disk;
+	uint8_t pv_name[NAME_LEN];
+	uint8_t vg_name[NAME_LEN];
+	uint8_t system_id[NAME_LEN];
+	kdev_t pv_dev;
+	uint32_t pv_number;
+	uint32_t pv_status;
+	uint32_t pv_allocatable;
+	uint32_t pv_size;
+	uint32_t lv_cur;
+	uint32_t pe_size;
+	uint32_t pe_total;
+	uint32_t pe_allocated;
+	uint32_t pe_stale;
+	u32 pe;
+	u32 inode;
+	uint8_t pv_uuid[UUID_LEN+1];
+} pv32_t;
+
+typedef struct {
+	char lv_name[NAME_LEN];
+	u32 lv;
+} lv_req32_t;
+
+typedef struct {
+	u32 lv_index;
+	u32 lv;
+	/* Transfer size because user space and kernel space differ */
+	uint16_t size;
+} lv_status_byindex_req32_t;
+
+typedef struct {
+	__kernel_dev_t32 dev;
+	u32   lv;
+} lv_status_bydev_req32_t;
+
+typedef struct {
+	uint8_t lv_name[NAME_LEN];
+	kdev_t old_dev;
+	kdev_t new_dev;
+	u32 old_pe;
+	u32 new_pe;
+} le_remap_req32_t;
+
+typedef struct {
+	char pv_name[NAME_LEN];
+	u32 pv;
+} pv_status_req32_t;
+
+typedef struct {
+	uint8_t lv_name[NAME_LEN];
+	uint8_t vg_name[NAME_LEN];
+	uint32_t lv_access;
+	uint32_t lv_status;
+	uint32_t lv_open;
+	kdev_t lv_dev;
+	uint32_t lv_number;
+	uint32_t lv_mirror_copies;
+	uint32_t lv_recovery;
+	uint32_t lv_schedule;
+	uint32_t lv_size;
+	u32 lv_current_pe;
+	uint32_t lv_current_le;
+	uint32_t lv_allocated_le;
+	uint32_t lv_stripes;
+	uint32_t lv_stripesize;
+	uint32_t lv_badblock;
+	uint32_t lv_allocation;
+	uint32_t lv_io_timeout;
+	uint32_t lv_read_ahead;
+	/* delta to version 1 starts here */
+	u32 lv_snapshot_org;
+	u32 lv_snapshot_prev;
+	u32 lv_snapshot_next;
+	u32 lv_block_exception;
+	uint32_t lv_remap_ptr;
+	uint32_t lv_remap_end;
+	uint32_t lv_chunk_size;
+	uint32_t lv_snapshot_minor;
+	char dummy[200];
+} lv32_t;
+
+typedef struct {
+	u32 hash[2];
+	u32 rsector_org;
+	kdev_t rdev_org;
+	u32 rsector_new;
+	kdev_t rdev_new;
+} lv_block_exception32_t;
+
+static void put_lv_t(lv_t *l)
+{
+	if (l->lv_current_pe) vfree(l->lv_current_pe);
+	if (l->lv_block_exception) vfree(l->lv_block_exception);
+	kfree(l);
+}
+
+static lv_t *get_lv_t(u32 p, int *errp)
+{
+	int err, i;
+	u32 ptr1, ptr2;
+	size_t size;
+	lv_block_exception32_t *lbe32;
+	lv_block_exception_t *lbe;
+	lv32_t *ul = (lv32_t *)A(p);
+	lv_t *l = (lv_t *) kmalloc(sizeof(lv_t), GFP_KERNEL);
+
+	if (!l) {
+		*errp = -ENOMEM;
+		return NULL;
+	}
+	memset(l, 0, sizeof(lv_t));
+	err = copy_from_user(l, ul, (long)&((lv32_t *)0)->lv_current_pe);
+	err |= __copy_from_user(&l->lv_current_le, &ul->lv_current_le,
+				((long)&ul->lv_snapshot_org) - ((long)&ul->lv_current_le));
+	err |= __copy_from_user(&l->lv_remap_ptr, &ul->lv_remap_ptr,
+				((long)&ul->dummy[0]) - ((long)&ul->lv_remap_ptr));
+	err |= __get_user(ptr1, &ul->lv_current_pe);
+	err |= __get_user(ptr2, &ul->lv_block_exception);
+	if (err) {
+		kfree(l);
+		*errp = -EFAULT;
+		return NULL;
+	}
+	if (ptr1) {
+		size = l->lv_allocated_le * sizeof(pe_t);
+		l->lv_current_pe = vmalloc(size);
+		if (l->lv_current_pe)
+			err = copy_from_user(l->lv_current_pe, (void *)A(ptr1), size);
+	}
+	if (!err && ptr2) {
+		size = l->lv_remap_end * sizeof(lv_block_exception_t);
+		l->lv_block_exception = lbe = vmalloc(size);
+		if (l->lv_block_exception) {
+			lbe32 = (lv_block_exception32_t *)A(ptr2);
+			memset(lbe, 0, size);
+			for (i = 0; i < l->lv_remap_end; i++, lbe++, lbe32++) {
+				err |= get_user(lbe->rsector_org, &lbe32->rsector_org);
+				err |= __get_user(lbe->rdev_org, &lbe32->rdev_org);
+				err |= __get_user(lbe->rsector_new, &lbe32->rsector_new);
+				err |= __get_user(lbe->rdev_new, &lbe32->rdev_new);
+			}
+		}
+	}
+	if (err || (ptr1 && !l->lv_current_pe) || (ptr2 && !l->lv_block_exception)) {
+		if (!err)
+			*errp = -ENOMEM;
+		else
+			*errp = -EFAULT;
+		put_lv_t(l);
+		return NULL;
+	}
+	return l;
+}
+
+static int copy_lv_t(u32 ptr, lv_t *l)
+{
+	int err;
+	lv32_t *ul = (lv32_t *)A(ptr);
+	u32 ptr1;
+	size_t size;
+
+	err = get_user(ptr1, &ul->lv_current_pe);
+	if (err)
+		return -EFAULT;
+	err = copy_to_user(ul, l, (long)&((lv32_t *)0)->lv_current_pe);
+	err |= __copy_to_user(&ul->lv_current_le, &l->lv_current_le,
+				((long)&ul->lv_snapshot_org) - ((long)&ul->lv_current_le));
+	err |= __copy_to_user(&ul->lv_remap_ptr, &l->lv_remap_ptr,
+				((long)&ul->dummy[0]) - ((long)&ul->lv_remap_ptr));
+	size = l->lv_allocated_le * sizeof(pe_t);
+	if (ptr1)
+		err |= __copy_to_user((void *)A(ptr1), l->lv_current_pe, size);
+	return err ? -EFAULT : 0;
+}
+
+static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	vg_t *v = NULL;
+	union {
+		lv_req_t lv_req;
+		le_remap_req_t le_remap;
+		lv_status_byindex_req_t lv_byindex;
+	        lv_status_bydev_req_t lv_bydev;
+		pv_status_req_t pv_status;
+	} u;
+	pv_t p;
+	int err;
+	u32 ptr = 0;
+	int i;
+	mm_segment_t old_fs;
+	void *karg = &u;
+
+	switch (cmd) {
+	case VG_STATUS:
+		v = kmalloc(sizeof(vg_t), GFP_KERNEL);
+		if (!v)
+			return -ENOMEM;
+		karg = v;
+		break;
+
+	case VG_CREATE_OLD:
+	case VG_CREATE:
+		v = kmalloc(sizeof(vg_t), GFP_KERNEL);
+		if (!v)
+			return -ENOMEM;
+		if (copy_from_user(v, (void *)arg, (long)&((vg32_t *)0)->proc)) {
+			kfree(v);
+			return -EFAULT;
+		}
+		/* 'proc' field is unused, just NULL it out. */
+		v->proc = NULL;
+		if (copy_from_user(v->vg_uuid, ((vg32_t *)arg)->vg_uuid, UUID_LEN+1)) {
+			kfree(v);
+			return -EFAULT;
+		}
+		    
+		karg = v;
+		memset(v->pv, 0, sizeof(v->pv) + sizeof(v->lv));
+		if (v->pv_max > ABS_MAX_PV || v->lv_max > ABS_MAX_LV)
+			return -EPERM;
+		for (i = 0; i < v->pv_max; i++) {
+			err = __get_user(ptr, &((vg32_t *)arg)->pv[i]);
+			if (err)
+				break;
+			if (ptr) {
+				v->pv[i] = kmalloc(sizeof(pv_t), GFP_KERNEL);
+				if (!v->pv[i]) {
+					err = -ENOMEM;
+					break;
+				}
+				err = copy_from_user(v->pv[i], (void *)A(ptr),
+						     sizeof(pv32_t) - 8 - UUID_LEN+1);
+				if (err) {
+					err = -EFAULT;
+					break;
+				}
+				err = copy_from_user(v->pv[i]->pv_uuid,
+						     ((pv32_t *)A(ptr))->pv_uuid,
+						     UUID_LEN+1);
+				if (err) {
+				        err = -EFAULT;
+					break;
+				}
+
+				v->pv[i]->pe = NULL;
+				v->pv[i]->bd = NULL;
+			}
+		}
+		if (!err) {
+			for (i = 0; i < v->lv_max; i++) {
+				err = __get_user(ptr, &((vg32_t *)arg)->lv[i]);
+				if (err)
+					break;
+				if (ptr) {
+					v->lv[i] = get_lv_t(ptr, &err);
+					if (err)
+						break;
+				}
+			}
+		}
+		break;
+
+	case LV_CREATE:
+	case LV_EXTEND:
+	case LV_REDUCE:
+	case LV_REMOVE:
+	case LV_RENAME:
+	case LV_STATUS_BYNAME:
+	        err = copy_from_user(&u.pv_status, arg, sizeof(u.pv_status.pv_name));
+		if (err)
+			return -EFAULT;
+		if (cmd != LV_REMOVE) {
+			err = __get_user(ptr, &((lv_req32_t *)arg)->lv);
+			if (err)
+				return err;
+			u.lv_req.lv = get_lv_t(ptr, &err);
+		} else
+			u.lv_req.lv = NULL;
+		break;
+
+	case LV_STATUS_BYINDEX:
+		err = get_user(u.lv_byindex.lv_index,
+			       &((lv_status_byindex_req32_t *)arg)->lv_index);
+		err |= __get_user(ptr, &((lv_status_byindex_req32_t *)arg)->lv);
+		if (err)
+			return err;
+		u.lv_byindex.lv = get_lv_t(ptr, &err);
+		break;
+
+	case LV_STATUS_BYDEV:
+	        err = get_user(u.lv_bydev.dev, &((lv_status_bydev_req32_t *)arg)->dev);
+		err |= __get_user(ptr, &((lv_status_bydev_req32_t *)arg)->lv);
+		if (err)
+			return err;
+		u.lv_bydev.lv = get_lv_t(ptr, &err);
+		break;
+
+	case VG_EXTEND:
+		err = copy_from_user(&p, (void *)arg, sizeof(pv32_t) - 8 - UUID_LEN+1);
+		if (err)
+			return -EFAULT;
+		err = copy_from_user(p.pv_uuid, ((pv32_t *)arg)->pv_uuid, UUID_LEN+1);
+		if (err)
+			return -EFAULT;
+		p.pe = NULL;
+		p.bd = NULL;
+		karg = &p;
+		break;
+
+	case PV_CHANGE:
+	case PV_STATUS:
+		err = copy_from_user(&u.pv_status, arg, sizeof(u.lv_req.lv_name));
+		if (err)
+			return -EFAULT;
+		err = __get_user(ptr, &((pv_status_req32_t *)arg)->pv);
+		if (err)
+			return err;
+		u.pv_status.pv = &p;
+		if (cmd == PV_CHANGE) {
+			err = copy_from_user(&p, (void *)A(ptr),
+					     sizeof(pv32_t) - 8 - UUID_LEN+1);
+			if (err)
+				return -EFAULT;
+			p.pe = NULL;
+			p.bd = NULL;
+		}
+		break;
+	};
+
+        old_fs = get_fs(); set_fs (KERNEL_DS);
+        err = sys_ioctl (fd, cmd, (unsigned long)karg);
+        set_fs (old_fs);
+
+	switch (cmd) {
+	case VG_STATUS:
+		if (!err) {
+			if (copy_to_user((void *)arg, v, (long)&((vg32_t *)0)->proc) ||
+			    clear_user(&((vg32_t *)arg)->proc, sizeof(vg32_t) - (long)&((vg32_t *)0)->proc))
+				err = -EFAULT;
+		}
+		if (copy_to_user(((vg32_t *)arg)->vg_uuid, v->vg_uuid, UUID_LEN+1)) {
+		        err = -EFAULT;
+		}
+		kfree(v);
+		break;
+
+	case VG_CREATE_OLD:
+	case VG_CREATE:
+		for (i = 0; i < v->pv_max; i++) {
+			if (v->pv[i])
+				kfree(v->pv[i]);
+		}
+		for (i = 0; i < v->lv_max; i++) {
+			if (v->lv[i])
+				put_lv_t(v->lv[i]);
+		}
+		kfree(v);
+		break;
+
+	case LV_STATUS_BYNAME:
+		if (!err && u.lv_req.lv)
+			err = copy_lv_t(ptr, u.lv_req.lv);
+		/* Fall through */
+
+        case LV_CREATE:
+	case LV_EXTEND:
+	case LV_REDUCE:
+		if (u.lv_req.lv)
+			put_lv_t(u.lv_req.lv);
+		break;
+
+	case LV_STATUS_BYINDEX:
+		if (u.lv_byindex.lv) {
+			if (!err)
+				err = copy_lv_t(ptr, u.lv_byindex.lv);
+			put_lv_t(u.lv_byindex.lv);
+		}
+		break;
+
+	case LV_STATUS_BYDEV:
+	        if (u.lv_bydev.lv) {
+			if (!err)
+				err = copy_lv_t(ptr, u.lv_bydev.lv);
+			put_lv_t(u.lv_byindex.lv);
+	        }
+	        break;
+
+	case PV_STATUS:
+		if (!err) {
+			err = copy_to_user((void *)A(ptr), &p, sizeof(pv32_t) - 8 - UUID_LEN+1);
+			if (err)
+				return -EFAULT;
+			err = copy_to_user(((pv_t *)A(ptr))->pv_uuid, p.pv_uuid, UUID_LEN + 1);
+			if (err)
+				return -EFAULT;
+		}
+		break;
+	};
+
+	return err;
+}
+#endif
+
+#ifdef CONFIG_GENRTC
+#endif
+
+#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
+/* This really belongs in include/linux/drm.h -DaveM */
+#include "../../../drivers/char/drm/drm.h"
+
+typedef struct drm32_version {
+	int    version_major;	  /* Major version			    */
+	int    version_minor;	  /* Minor version			    */
+	int    version_patchlevel;/* Patch level			    */
+	int    name_len;	  /* Length of name buffer		    */
+	u32    name;		  /* Name of driver			    */
+	int    date_len;	  /* Length of date buffer		    */
+	u32    date;		  /* User-space buffer to hold date	    */
+	int    desc_len;	  /* Length of desc buffer		    */
+	u32    desc;		  /* User-space buffer to hold desc	    */
+} drm32_version_t;
+#define DRM32_IOCTL_VERSION    DRM_IOWR(0x00, drm32_version_t)
+
+static int drm32_version(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	drm32_version_t *uversion = (drm32_version_t *)arg;
+	char *name_ptr, *date_ptr, *desc_ptr;
+	u32 tmp1, tmp2, tmp3;
+	drm_version_t kversion;
+	mm_segment_t old_fs;
+	int ret;
+
+	memset(&kversion, 0, sizeof(kversion));
+	if (get_user(kversion.name_len, &uversion->name_len) ||
+	    get_user(kversion.date_len, &uversion->date_len) ||
+	    get_user(kversion.desc_len, &uversion->desc_len) ||
+	    get_user(tmp1, &uversion->name) ||
+	    get_user(tmp2, &uversion->date) ||
+	    get_user(tmp3, &uversion->desc))
+		return -EFAULT;
+
+	name_ptr = (char *) A(tmp1);
+	date_ptr = (char *) A(tmp2);
+	desc_ptr = (char *) A(tmp3);
+
+	ret = -ENOMEM;
+	if (kversion.name_len && name_ptr) {
+		kversion.name = kmalloc(kversion.name_len, GFP_KERNEL);
+		if (!kversion.name)
+			goto out;
+	}
+	if (kversion.date_len && date_ptr) {
+		kversion.date = kmalloc(kversion.date_len, GFP_KERNEL);
+		if (!kversion.date)
+			goto out;
+	}
+	if (kversion.desc_len && desc_ptr) {
+		kversion.desc = kmalloc(kversion.desc_len, GFP_KERNEL);
+		if (!kversion.desc)
+			goto out;
+	}
+
+        old_fs = get_fs();
+	set_fs(KERNEL_DS);
+        ret = sys_ioctl (fd, DRM_IOCTL_VERSION, (unsigned long)&kversion);
+        set_fs(old_fs);
+
+	if (!ret) {
+		if ((kversion.name &&
+		     copy_to_user(name_ptr, kversion.name, kversion.name_len)) ||
+		    (kversion.date &&
+		     copy_to_user(date_ptr, kversion.date, kversion.date_len)) ||
+		    (kversion.desc &&
+		     copy_to_user(desc_ptr, kversion.desc, kversion.desc_len)))
+			ret = -EFAULT;
+		if (put_user(kversion.version_major, &uversion->version_major) ||
+		    put_user(kversion.version_minor, &uversion->version_minor) ||
+		    put_user(kversion.version_patchlevel, &uversion->version_patchlevel) ||
+		    put_user(kversion.name_len, &uversion->name_len) ||
+		    put_user(kversion.date_len, &uversion->date_len) ||
+		    put_user(kversion.desc_len, &uversion->desc_len))
+			ret = -EFAULT;
+	}
+
+out:
+	if (kversion.name)
+		kfree(kversion.name);
+	if (kversion.date)
+		kfree(kversion.date);
+	if (kversion.desc)
+		kfree(kversion.desc);
+	return ret;
+}
+
+typedef struct drm32_unique {
+	int	unique_len;	  /* Length of unique			    */
+	u32	unique;		  /* Unique name for driver instantiation   */
+} drm32_unique_t;
+#define DRM32_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm32_unique_t)
+#define DRM32_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm32_unique_t)
+
+static int drm32_getsetunique(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	drm32_unique_t *uarg = (drm32_unique_t *)arg;
+	drm_unique_t karg;
+	mm_segment_t old_fs;
+	char *uptr;
+	u32 tmp;
+	int ret;
+
+	if (get_user(karg.unique_len, &uarg->unique_len))
+		return -EFAULT;
+	karg.unique = NULL;
+
+	if (get_user(tmp, &uarg->unique))
+		return -EFAULT;
+
+	uptr = (char *) A(tmp);
+
+	if (uptr) {
+		karg.unique = kmalloc(karg.unique_len, GFP_KERNEL);
+		if (!karg.unique)
+			return -ENOMEM;
+		if (cmd == DRM32_IOCTL_SET_UNIQUE &&
+		    copy_from_user(karg.unique, uptr, karg.unique_len)) {
+			kfree(karg.unique);
+			return -EFAULT;
+		}
+	}
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	if (cmd == DRM32_IOCTL_GET_UNIQUE)
+		ret = sys_ioctl (fd, DRM_IOCTL_GET_UNIQUE, (unsigned long)&karg);
+	else
+		ret = sys_ioctl (fd, DRM_IOCTL_SET_UNIQUE, (unsigned long)&karg);
+        set_fs(old_fs);
+
+	if (!ret) {
+		if (cmd == DRM32_IOCTL_GET_UNIQUE &&
+		    uptr != NULL &&
+		    copy_to_user(uptr, karg.unique, karg.unique_len))
+			ret = -EFAULT;
+		if (put_user(karg.unique_len, &uarg->unique_len))
+			ret = -EFAULT;
+	}
+
+	if (karg.unique != NULL)
+		kfree(karg.unique);
+
+	return ret;
+}
+
+typedef struct drm32_map {
+	u32		offset;	 /* Requested physical address (0 for SAREA)*/
+	u32		size;	 /* Requested physical size (bytes)	    */
+	drm_map_type_t	type;	 /* Type of memory to map		    */
+	drm_map_flags_t flags;	 /* Flags				    */
+	u32		handle;  /* User-space: "Handle" to pass to mmap    */
+				 /* Kernel-space: kernel-virtual address    */
+	int		mtrr;	 /* MTRR slot used			    */
+				 /* Private data			    */
+} drm32_map_t;
+#define DRM32_IOCTL_ADD_MAP    DRM_IOWR(0x15, drm32_map_t)
+
+static int drm32_addmap(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	drm32_map_t *uarg = (drm32_map_t *) arg;
+	drm_map_t karg;
+	mm_segment_t old_fs;
+	u32 tmp;
+	int ret;
+
+	ret  = get_user(karg.offset, &uarg->offset);
+	ret |= get_user(karg.size, &uarg->size);
+	ret |= get_user(karg.type, &uarg->type);
+	ret |= get_user(karg.flags, &uarg->flags);
+	ret |= get_user(tmp, &uarg->handle);
+	ret |= get_user(karg.mtrr, &uarg->mtrr);
+	if (ret)
+		return -EFAULT;
+
+	karg.handle = (void *) A(tmp);
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = sys_ioctl(fd, DRM_IOCTL_ADD_MAP, (unsigned long) &karg);
+	set_fs(old_fs);
+
+	if (!ret) {
+		ret  = put_user(karg.offset, &uarg->offset);
+		ret |= put_user(karg.size, &uarg->size);
+		ret |= put_user(karg.type, &uarg->type);
+		ret |= put_user(karg.flags, &uarg->flags);
+		tmp = (u32) (long)karg.handle;
+		ret |= put_user(tmp, &uarg->handle);
+		ret |= put_user(karg.mtrr, &uarg->mtrr);
+		if (ret)
+			ret = -EFAULT;
+	}
+
+	return ret;
+}
+
+typedef struct drm32_buf_info {
+	int	       count;	/* Entries in list			     */
+	u32	       list;    /* (drm_buf_desc_t *) */ 
+} drm32_buf_info_t;
+#define DRM32_IOCTL_INFO_BUFS  DRM_IOWR(0x18, drm32_buf_info_t)
+
+static int drm32_info_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	drm32_buf_info_t *uarg = (drm32_buf_info_t *)arg;
+	drm_buf_desc_t *ulist;
+	drm_buf_info_t karg;
+	mm_segment_t old_fs;
+	int orig_count, ret;
+	u32 tmp;
+
+	if (get_user(karg.count, &uarg->count) ||
+	    get_user(tmp, &uarg->list))
+		return -EFAULT;
+
+	ulist = (drm_buf_desc_t *) A(tmp);
+
+	orig_count = karg.count;
+
+	karg.list = kmalloc(karg.count * sizeof(drm_buf_desc_t), GFP_KERNEL);
+	if (!karg.list)
+		return -EFAULT;
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = sys_ioctl(fd, DRM_IOCTL_INFO_BUFS, (unsigned long) &karg);
+	set_fs(old_fs);
+
+	if (!ret) {
+		if (karg.count <= orig_count &&
+		    (copy_to_user(ulist, karg.list,
+				  karg.count * sizeof(drm_buf_desc_t))))
+			ret = -EFAULT;
+		if (put_user(karg.count, &uarg->count))
+			ret = -EFAULT;
+	}
+
+	kfree(karg.list);
+
+	return ret;
+}
+
+typedef struct drm32_buf_free {
+	int	       count;
+	u32	       list;	/* (int *) */
+} drm32_buf_free_t;
+#define DRM32_IOCTL_FREE_BUFS  DRM_IOW( 0x1a, drm32_buf_free_t)
+
+static int drm32_free_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	drm32_buf_free_t *uarg = (drm32_buf_free_t *)arg;
+	drm_buf_free_t karg;
+	mm_segment_t old_fs;
+	int *ulist;
+	int ret;
+	u32 tmp;
+
+	if (get_user(karg.count, &uarg->count) ||
+	    get_user(tmp, &uarg->list))
+		return -EFAULT;
+
+	ulist = (int *) A(tmp);
+
+	karg.list = kmalloc(karg.count * sizeof(int), GFP_KERNEL);
+	if (!karg.list)
+		return -ENOMEM;
+
+	ret = -EFAULT;
+	if (copy_from_user(karg.list, ulist, (karg.count * sizeof(int))))
+		goto out;
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = sys_ioctl(fd, DRM_IOCTL_FREE_BUFS, (unsigned long) &karg);
+	set_fs(old_fs);
+
+out:
+	kfree(karg.list);
+
+	return ret;
+}
+
+typedef struct drm32_buf_pub {
+	int		  idx;	       /* Index into master buflist	     */
+	int		  total;       /* Buffer size			     */
+	int		  used;	       /* Amount of buffer in use (for DMA)  */
+	u32		  address;     /* Address of buffer (void *)	     */
+} drm32_buf_pub_t;
+
+typedef struct drm32_buf_map {
+	int	      count;	/* Length of buflist			    */
+	u32	      virtual;	/* Mmaped area in user-virtual (void *)	    */
+	u32 	      list;	/* Buffer information (drm_buf_pub_t *)	    */
+} drm32_buf_map_t;
+#define DRM32_IOCTL_MAP_BUFS   DRM_IOWR(0x19, drm32_buf_map_t)
+
+static int drm32_map_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	drm32_buf_map_t *uarg = (drm32_buf_map_t *)arg;
+	drm32_buf_pub_t *ulist;
+	drm_buf_map_t karg;
+	mm_segment_t old_fs;
+	int orig_count, ret, i;
+	u32 tmp1, tmp2;
+
+	if (get_user(karg.count, &uarg->count) ||
+	    get_user(tmp1, &uarg->virtual) ||
+	    get_user(tmp2, &uarg->list))
+		return -EFAULT;
+
+	karg.virtual = (void *) A(tmp1);
+	ulist = (drm32_buf_pub_t *) A(tmp2);
+
+	orig_count = karg.count;
+
+	karg.list = kmalloc(karg.count * sizeof(drm_buf_pub_t), GFP_KERNEL);
+	if (!karg.list)
+		return -ENOMEM;
+
+	ret = -EFAULT;
+	for (i = 0; i < karg.count; i++) {
+		if (get_user(karg.list[i].idx, &ulist[i].idx) ||
+		    get_user(karg.list[i].total, &ulist[i].total) ||
+		    get_user(karg.list[i].used, &ulist[i].used) ||
+		    get_user(tmp1, &ulist[i].address))
+			goto out;
+
+		karg.list[i].address = (void *) A(tmp1);
+	}
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = sys_ioctl(fd, DRM_IOCTL_MAP_BUFS, (unsigned long) &karg);
+	set_fs(old_fs);
+
+	if (!ret) {
+		for (i = 0; i < orig_count; i++) {
+			tmp1 = (u32) (long) karg.list[i].address;
+			if (put_user(karg.list[i].idx, &ulist[i].idx) ||
+			    put_user(karg.list[i].total, &ulist[i].total) ||
+			    put_user(karg.list[i].used, &ulist[i].used) ||
+			    put_user(tmp1, &ulist[i].address)) {
+				ret = -EFAULT;
+				goto out;
+			}
+		}
+		if (put_user(karg.count, &uarg->count))
+			ret = -EFAULT;
+	}
+
+out:
+	kfree(karg.list);
+	return ret;
+}
+
+typedef struct drm32_dma {
+				/* Indices here refer to the offset into
+				   buflist in drm_buf_get_t.  */
+	int		context;	  /* Context handle		    */
+	int		send_count;	  /* Number of buffers to send	    */
+	u32		send_indices;	  /* List of handles to buffers (int *) */
+	u32		send_sizes;	  /* Lengths of data to send (int *) */
+	drm_dma_flags_t flags;		  /* Flags			    */
+	int		request_count;	  /* Number of buffers requested    */
+	int		request_size;	  /* Desired size for buffers	    */
+	u32		request_indices;  /* Buffer information (int *)	    */
+	u32		request_sizes;    /* (int *) */
+	int		granted_count;	  /* Number of buffers granted	    */
+} drm32_dma_t;
+#define DRM32_IOCTL_DMA	     DRM_IOWR(0x29, drm32_dma_t)
+
+/* RED PEN	The DRM layer blindly dereferences the send/request
+ * 		indice/size arrays even though they are userland
+ * 		pointers.  -DaveM
+ */
+static int drm32_dma(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	drm32_dma_t *uarg = (drm32_dma_t *) arg;
+	int *u_si, *u_ss, *u_ri, *u_rs;
+	drm_dma_t karg;
+	mm_segment_t old_fs;
+	int ret;
+	u32 tmp1, tmp2, tmp3, tmp4;
+
+	karg.send_indices = karg.send_sizes = NULL;
+	karg.request_indices = karg.request_sizes = NULL;
+
+	if (get_user(karg.context, &uarg->context) ||
+	    get_user(karg.send_count, &uarg->send_count) ||
+	    get_user(tmp1, &uarg->send_indices) ||
+	    get_user(tmp2, &uarg->send_sizes) ||
+	    get_user(karg.flags, &uarg->flags) ||
+	    get_user(karg.request_count, &uarg->request_count) ||
+	    get_user(karg.request_size, &uarg->request_size) ||
+	    get_user(tmp3, &uarg->request_indices) ||
+	    get_user(tmp4, &uarg->request_sizes) ||
+	    get_user(karg.granted_count, &uarg->granted_count))
+		return -EFAULT;
+
+	u_si = (int *) A(tmp1);
+	u_ss = (int *) A(tmp2);
+	u_ri = (int *) A(tmp3);
+	u_rs = (int *) A(tmp4);
+
+	if (karg.send_count) {
+		karg.send_indices = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
+		karg.send_sizes = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
+
+		ret = -ENOMEM;
+		if (!karg.send_indices || !karg.send_sizes)
+			goto out;
+
+		ret = -EFAULT;
+		if (copy_from_user(karg.send_indices, u_si,
+				   (karg.send_count * sizeof(int))) ||
+		    copy_from_user(karg.send_sizes, u_ss,
+				   (karg.send_count * sizeof(int))))
+			goto out;
+	}
+
+	if (karg.request_count) {
+		karg.request_indices = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
+		karg.request_sizes = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
+
+		ret = -ENOMEM;
+		if (!karg.request_indices || !karg.request_sizes)
+			goto out;
+
+		ret = -EFAULT;
+		if (copy_from_user(karg.request_indices, u_ri,
+				   (karg.request_count * sizeof(int))) ||
+		    copy_from_user(karg.request_sizes, u_rs,
+				   (karg.request_count * sizeof(int))))
+			goto out;
+	}
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = sys_ioctl(fd, DRM_IOCTL_DMA, (unsigned long) &karg);
+	set_fs(old_fs);
+
+	if (!ret) {
+		if (put_user(karg.context, &uarg->context) ||
+		    put_user(karg.send_count, &uarg->send_count) ||
+		    put_user(karg.flags, &uarg->flags) ||
+		    put_user(karg.request_count, &uarg->request_count) ||
+		    put_user(karg.request_size, &uarg->request_size) ||
+		    put_user(karg.granted_count, &uarg->granted_count))
+			ret = -EFAULT;
+
+		if (karg.send_count) {
+			if (copy_to_user(u_si, karg.send_indices,
+					 (karg.send_count * sizeof(int))) ||
+			    copy_to_user(u_ss, karg.send_sizes,
+					 (karg.send_count * sizeof(int))))
+				ret = -EFAULT;
+		}
+		if (karg.request_count) {
+			if (copy_to_user(u_ri, karg.request_indices,
+					 (karg.request_count * sizeof(int))) ||
+			    copy_to_user(u_rs, karg.request_sizes,
+					 (karg.request_count * sizeof(int))))
+				ret = -EFAULT;
+		}
+	}
+
+out:
+	if (karg.send_indices)
+		kfree(karg.send_indices);
+	if (karg.send_sizes)
+		kfree(karg.send_sizes);
+	if (karg.request_indices)
+		kfree(karg.request_indices);
+	if (karg.request_sizes)
+		kfree(karg.request_sizes);
+
+	return ret;
+}
+
+typedef struct drm32_ctx_res {
+	int		count;
+	u32		contexts; /* (drm_ctx_t *) */
+} drm32_ctx_res_t;
+#define DRM32_IOCTL_RES_CTX    DRM_IOWR(0x26, drm32_ctx_res_t)
+
+static int drm32_res_ctx(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	drm32_ctx_res_t *uarg = (drm32_ctx_res_t *) arg;
+	drm_ctx_t *ulist;
+	drm_ctx_res_t karg;
+	mm_segment_t old_fs;
+	int orig_count, ret;
+	u32 tmp;
+
+	karg.contexts = NULL;
+	if (get_user(karg.count, &uarg->count) ||
+	    get_user(tmp, &uarg->contexts))
+		return -EFAULT;
+
+	ulist = (drm_ctx_t *) A(tmp);
+
+	orig_count = karg.count;
+	if (karg.count && ulist) {
+		karg.contexts = kmalloc((karg.count * sizeof(drm_ctx_t)), GFP_KERNEL);
+		if (!karg.contexts)
+			return -ENOMEM;
+		if (copy_from_user(karg.contexts, ulist,
+				   (karg.count * sizeof(drm_ctx_t)))) {
+			kfree(karg.contexts);
+			return -EFAULT;
+		}
+	}
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = sys_ioctl(fd, DRM_IOCTL_RES_CTX, (unsigned long) &karg);
+	set_fs(old_fs);
+
+	if (!ret) {
+		if (orig_count) {
+			if (copy_to_user(ulist, karg.contexts,
+					 (orig_count * sizeof(drm_ctx_t))))
+				ret = -EFAULT;
+		}
+		if (put_user(karg.count, &uarg->count))
+			ret = -EFAULT;
+	}
+
+	if (karg.contexts)
+		kfree(karg.contexts);
+
+	return ret;
+}
+
+#endif
+
+static int ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	return -EINVAL;
+}
+
+static int broken_blkgetsize(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	/* The mkswap binary hard codes it to Intel value :-((( */
+	return w_long(fd, BLKGETSIZE, arg);
+}
+
+struct blkpg_ioctl_arg32 {
+	int op;
+	int flags;
+	int datalen;
+	u32 data;
+};
+                                
+static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd, struct blkpg_ioctl_arg32 *arg)
+{
+	struct blkpg_ioctl_arg a;
+	struct blkpg_partition p;
+	int err;
+	mm_segment_t old_fs = get_fs();
+	
+	err = get_user(a.op, &arg->op);
+	err |= __get_user(a.flags, &arg->flags);
+	err |= __get_user(a.datalen, &arg->datalen);
+	err |= __get_user((long)a.data, &arg->data);
+	if (err) return err;
+	switch (a.op) {
+	case BLKPG_ADD_PARTITION:
+	case BLKPG_DEL_PARTITION:
+		if (a.datalen < sizeof(struct blkpg_partition))
+			return -EINVAL;
+                if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition)))
+			return -EFAULT;
+		a.data = &p;
+		set_fs (KERNEL_DS);
+		err = sys_ioctl(fd, cmd, (unsigned long)&a);
+		set_fs (old_fs);
+	default:
+		return -EINVAL;
+	}                                        
+	return err;
+}
+
+static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg);
+}
+
+
+struct serial_struct32 {
+	int	type;
+	int	line;
+	unsigned int	port;
+	int	irq;
+	int	flags;
+	int	xmit_fifo_size;
+	int	custom_divisor;
+	int	baud_base;
+	unsigned short	close_delay;
+	char	io_type;
+	char	reserved_char[1];
+	int	hub6;
+	unsigned short	closing_wait; /* time to wait before closing */
+	unsigned short	closing_wait2; /* no longer used... */
+	unsigned int	iomem_base;	/* char * really */
+	unsigned short	iomem_reg_shift;
+	unsigned int	port_high;
+	int	reserved[1];
+};
+
+static int do_tiocgserial(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct serial_struct ss;
+	int ret;
+	struct serial_struct32 * uptr = (struct serial_struct32 *)arg;
+	mm_segment_t old_fs = get_fs();
+
+	set_fs (KERNEL_DS);
+	ret = sys_ioctl(fd, cmd, (unsigned long) &ss);
+	set_fs(old_fs);
+
+	if (!ret) {
+		/* structs match up to iomem_base */
+		ret = copy_to_user(uptr, &ss, sizeof(struct serial_struct32));
+		ret |= put_user(ss.iomem_base, &uptr->iomem_base);
+		ret |= put_user(ss.iomem_reg_shift, &uptr->iomem_reg_shift);
+		ret |= put_user(ss.port_high, &uptr->port_high);
+		if (ret)
+			ret = -EFAULT;
+	}
+	return ret;
+}
+
+
+struct ioctl_trans {
+	unsigned long handler;
+	unsigned int cmd;
+	unsigned int next;
+};
+#define HANDLE_IOCTL(cmd, handler) asm volatile(".dword %1\n.word %0, 0" : : "i" (cmd), "i" (handler));
+
+#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd, sys_ioctl) 
+
+
+#define IOCTL_TABLE_START void ioctl32_foo(void) { asm volatile(".data\nioctl_translations:");
+#define IOCTL_TABLE_END asm volatile("\nioctl_translations_end:\n\t.previous"); }
+
+IOCTL_TABLE_START
+/* List here exlicitly which ioctl's are known to have
+ * compatable types passed or none at all...
+ */
+/* Big T */
+COMPATIBLE_IOCTL(TCGETA)
+COMPATIBLE_IOCTL(TCSETA)
+COMPATIBLE_IOCTL(TCSETAW)
+COMPATIBLE_IOCTL(TCSETAF)
+COMPATIBLE_IOCTL(TCSBRK)
+COMPATIBLE_IOCTL(TCXONC)
+COMPATIBLE_IOCTL(TCFLSH)
+COMPATIBLE_IOCTL(TCGETS)
+COMPATIBLE_IOCTL(TCSETS)
+COMPATIBLE_IOCTL(TCSETSW)
+COMPATIBLE_IOCTL(TCSETSF)
+COMPATIBLE_IOCTL(TIOCLINUX)
+/* Little t */
+COMPATIBLE_IOCTL(TIOCGETD)
+COMPATIBLE_IOCTL(TIOCSETD)
+COMPATIBLE_IOCTL(TIOCEXCL)
+COMPATIBLE_IOCTL(TIOCNXCL)
+COMPATIBLE_IOCTL(TIOCCONS)
+COMPATIBLE_IOCTL(TIOCGSOFTCAR)
+COMPATIBLE_IOCTL(TIOCSSOFTCAR)
+COMPATIBLE_IOCTL(TIOCSWINSZ)
+COMPATIBLE_IOCTL(TIOCGWINSZ)
+COMPATIBLE_IOCTL(TIOCMGET)
+COMPATIBLE_IOCTL(TIOCMBIC)
+COMPATIBLE_IOCTL(TIOCMBIS)
+COMPATIBLE_IOCTL(TIOCMSET)
+COMPATIBLE_IOCTL(TIOCPKT)
+COMPATIBLE_IOCTL(TIOCNOTTY)
+COMPATIBLE_IOCTL(TIOCSTI)
+COMPATIBLE_IOCTL(TIOCOUTQ)
+COMPATIBLE_IOCTL(TIOCSPGRP)
+COMPATIBLE_IOCTL(TIOCGPGRP)
+COMPATIBLE_IOCTL(TIOCSCTTY)
+COMPATIBLE_IOCTL(TIOCGPTN)
+COMPATIBLE_IOCTL(TIOCSPTLCK)
+COMPATIBLE_IOCTL(TIOCSSERIAL)
+COMPATIBLE_IOCTL(TIOCSERGETLSR)
+/* Big F */
+#if 0
+COMPATIBLE_IOCTL(FBIOGTYPE)
+COMPATIBLE_IOCTL(FBIOSATTR)
+COMPATIBLE_IOCTL(FBIOGATTR)
+COMPATIBLE_IOCTL(FBIOSVIDEO)
+COMPATIBLE_IOCTL(FBIOGVIDEO)
+COMPATIBLE_IOCTL(FBIOGCURSOR32)  /* This is not implemented yet. Later it should be converted... */
+COMPATIBLE_IOCTL(FBIOSCURPOS)
+COMPATIBLE_IOCTL(FBIOGCURPOS)
+COMPATIBLE_IOCTL(FBIOGCURMAX)
+#endif
+COMPATIBLE_IOCTL(FBIOGET_VSCREENINFO)
+COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO)
+
+COMPATIBLE_IOCTL(FBIOPAN_DISPLAY)
+COMPATIBLE_IOCTL(FBIOGET_FCURSORINFO)
+COMPATIBLE_IOCTL(FBIOGET_VCURSORINFO)
+COMPATIBLE_IOCTL(FBIOPUT_VCURSORINFO)
+COMPATIBLE_IOCTL(FBIOGET_CURSORSTATE)
+COMPATIBLE_IOCTL(FBIOPUT_CURSORSTATE)
+COMPATIBLE_IOCTL(FBIOGET_CON2FBMAP)
+COMPATIBLE_IOCTL(FBIOPUT_CON2FBMAP)
+/* Little f */
+COMPATIBLE_IOCTL(FIOCLEX)
+COMPATIBLE_IOCTL(FIONCLEX)
+COMPATIBLE_IOCTL(FIOASYNC)
+COMPATIBLE_IOCTL(FIONBIO)
+COMPATIBLE_IOCTL(FIONREAD)  /* This is also TIOCINQ */
+/* 0x00 */
+COMPATIBLE_IOCTL(FIBMAP)
+COMPATIBLE_IOCTL(FIGETBSZ)
+/* 0x03 -- HD/IDE ioctl's used by hdparm and friends.
+ *         Some need translations, these do not.
+ */
+COMPATIBLE_IOCTL(HDIO_GET_IDENTITY)
+COMPATIBLE_IOCTL(HDIO_SET_DMA)
+COMPATIBLE_IOCTL(HDIO_SET_KEEPSETTINGS)
+COMPATIBLE_IOCTL(HDIO_SET_UNMASKINTR)
+COMPATIBLE_IOCTL(HDIO_SET_NOWERR)
+COMPATIBLE_IOCTL(HDIO_SET_32BIT)
+COMPATIBLE_IOCTL(HDIO_SET_MULTCOUNT)
+COMPATIBLE_IOCTL(HDIO_DRIVE_CMD)
+COMPATIBLE_IOCTL(HDIO_SET_PIO_MODE)
+COMPATIBLE_IOCTL(HDIO_SCAN_HWIF)
+COMPATIBLE_IOCTL(HDIO_SET_NICE)
+/* 0x02 -- Floppy ioctls */
+COMPATIBLE_IOCTL(FDMSGON)
+COMPATIBLE_IOCTL(FDMSGOFF)
+COMPATIBLE_IOCTL(FDSETEMSGTRESH)
+COMPATIBLE_IOCTL(FDFLUSH)
+COMPATIBLE_IOCTL(FDWERRORCLR)
+COMPATIBLE_IOCTL(FDSETMAXERRS)
+COMPATIBLE_IOCTL(FDGETMAXERRS)
+COMPATIBLE_IOCTL(FDGETDRVTYP)
+COMPATIBLE_IOCTL(FDEJECT)
+COMPATIBLE_IOCTL(FDCLRPRM)
+COMPATIBLE_IOCTL(FDFMTBEG)
+COMPATIBLE_IOCTL(FDFMTEND)
+COMPATIBLE_IOCTL(FDRESET)
+COMPATIBLE_IOCTL(FDTWADDLE)
+COMPATIBLE_IOCTL(FDFMTTRK)
+COMPATIBLE_IOCTL(FDRAWCMD)
+/* 0x12 */
+COMPATIBLE_IOCTL(BLKROSET)
+COMPATIBLE_IOCTL(BLKROGET)
+COMPATIBLE_IOCTL(BLKRRPART)
+COMPATIBLE_IOCTL(BLKFLSBUF)
+COMPATIBLE_IOCTL(BLKRASET)
+COMPATIBLE_IOCTL(BLKFRASET)
+COMPATIBLE_IOCTL(BLKSECTSET)
+COMPATIBLE_IOCTL(BLKSSZGET)
+
+/* RAID */
+COMPATIBLE_IOCTL(RAID_VERSION)
+COMPATIBLE_IOCTL(GET_ARRAY_INFO)
+COMPATIBLE_IOCTL(GET_DISK_INFO)
+COMPATIBLE_IOCTL(PRINT_RAID_DEBUG)
+COMPATIBLE_IOCTL(CLEAR_ARRAY)
+COMPATIBLE_IOCTL(ADD_NEW_DISK)
+COMPATIBLE_IOCTL(HOT_REMOVE_DISK)
+COMPATIBLE_IOCTL(SET_ARRAY_INFO)
+COMPATIBLE_IOCTL(SET_DISK_INFO)
+COMPATIBLE_IOCTL(WRITE_RAID_INFO)
+COMPATIBLE_IOCTL(UNPROTECT_ARRAY)
+COMPATIBLE_IOCTL(PROTECT_ARRAY)
+COMPATIBLE_IOCTL(HOT_ADD_DISK)
+COMPATIBLE_IOCTL(SET_DISK_FAULTY)
+COMPATIBLE_IOCTL(RUN_ARRAY)
+COMPATIBLE_IOCTL(START_ARRAY)
+COMPATIBLE_IOCTL(STOP_ARRAY)
+COMPATIBLE_IOCTL(STOP_ARRAY_RO)
+COMPATIBLE_IOCTL(RESTART_ARRAY_RW)
+
+/* Big K */
+COMPATIBLE_IOCTL(PIO_FONT)
+COMPATIBLE_IOCTL(GIO_FONT)
+COMPATIBLE_IOCTL(KDSIGACCEPT)
+COMPATIBLE_IOCTL(KDGETKEYCODE)
+COMPATIBLE_IOCTL(KDSETKEYCODE)
+COMPATIBLE_IOCTL(KIOCSOUND)
+COMPATIBLE_IOCTL(KDMKTONE)
+COMPATIBLE_IOCTL(KDGKBTYPE)
+COMPATIBLE_IOCTL(KDSETMODE)
+COMPATIBLE_IOCTL(KDGETMODE)
+COMPATIBLE_IOCTL(KDSKBMODE)
+COMPATIBLE_IOCTL(KDGKBMODE)
+COMPATIBLE_IOCTL(KDSKBMETA)
+COMPATIBLE_IOCTL(KDGKBMETA)
+COMPATIBLE_IOCTL(KDGKBENT)
+COMPATIBLE_IOCTL(KDSKBENT)
+COMPATIBLE_IOCTL(KDGKBSENT)
+COMPATIBLE_IOCTL(KDSKBSENT)
+COMPATIBLE_IOCTL(KDGKBDIACR)
+COMPATIBLE_IOCTL(KDSKBDIACR)
+COMPATIBLE_IOCTL(KDGKBLED)
+COMPATIBLE_IOCTL(KDSKBLED)
+COMPATIBLE_IOCTL(KDGETLED)
+COMPATIBLE_IOCTL(KDSETLED)
+COMPATIBLE_IOCTL(GIO_SCRNMAP)
+COMPATIBLE_IOCTL(PIO_SCRNMAP)
+COMPATIBLE_IOCTL(GIO_UNISCRNMAP)
+COMPATIBLE_IOCTL(PIO_UNISCRNMAP)
+COMPATIBLE_IOCTL(PIO_FONTRESET)
+COMPATIBLE_IOCTL(PIO_UNIMAPCLR)
+/* Little k */
+#if 0
+COMPATIBLE_IOCTL(KIOCTYPE)
+COMPATIBLE_IOCTL(KIOCLAYOUT)
+COMPATIBLE_IOCTL(KIOCGTRANS)
+COMPATIBLE_IOCTL(KIOCTRANS)
+COMPATIBLE_IOCTL(KIOCCMD)
+COMPATIBLE_IOCTL(KIOCSDIRECT)
+COMPATIBLE_IOCTL(KIOCSLED)
+COMPATIBLE_IOCTL(KIOCGLED)
+COMPATIBLE_IOCTL(KIOCSRATE)
+COMPATIBLE_IOCTL(KIOCGRATE)
+#endif
+/* Big S */
+COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN)
+COMPATIBLE_IOCTL(SCSI_IOCTL_DOORLOCK)
+COMPATIBLE_IOCTL(SCSI_IOCTL_DOORUNLOCK)
+COMPATIBLE_IOCTL(SCSI_IOCTL_TEST_UNIT_READY)
+COMPATIBLE_IOCTL(SCSI_IOCTL_TAGGED_ENABLE)
+COMPATIBLE_IOCTL(SCSI_IOCTL_TAGGED_DISABLE)
+COMPATIBLE_IOCTL(SCSI_IOCTL_GET_BUS_NUMBER)
+COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAND)
+/* Big V */
+COMPATIBLE_IOCTL(VT_SETMODE)
+COMPATIBLE_IOCTL(VT_GETMODE)
+COMPATIBLE_IOCTL(VT_GETSTATE)
+COMPATIBLE_IOCTL(VT_OPENQRY)
+COMPATIBLE_IOCTL(VT_ACTIVATE)
+COMPATIBLE_IOCTL(VT_WAITACTIVE)
+COMPATIBLE_IOCTL(VT_RELDISP)
+COMPATIBLE_IOCTL(VT_DISALLOCATE)
+COMPATIBLE_IOCTL(VT_RESIZE)
+COMPATIBLE_IOCTL(VT_RESIZEX)
+COMPATIBLE_IOCTL(VT_LOCKSWITCH)
+COMPATIBLE_IOCTL(VT_UNLOCKSWITCH)
+/* Little v, the video4linux ioctls */
+COMPATIBLE_IOCTL(VIDIOCGCAP)
+COMPATIBLE_IOCTL(VIDIOCGCHAN)
+COMPATIBLE_IOCTL(VIDIOCSCHAN)
+COMPATIBLE_IOCTL(VIDIOCGPICT)
+COMPATIBLE_IOCTL(VIDIOCSPICT)
+COMPATIBLE_IOCTL(VIDIOCCAPTURE)
+COMPATIBLE_IOCTL(VIDIOCKEY)
+COMPATIBLE_IOCTL(VIDIOCGAUDIO)
+COMPATIBLE_IOCTL(VIDIOCSAUDIO)
+COMPATIBLE_IOCTL(VIDIOCSYNC)
+COMPATIBLE_IOCTL(VIDIOCMCAPTURE)
+COMPATIBLE_IOCTL(VIDIOCGMBUF)
+COMPATIBLE_IOCTL(VIDIOCGUNIT)
+COMPATIBLE_IOCTL(VIDIOCGCAPTURE)
+COMPATIBLE_IOCTL(VIDIOCSCAPTURE)
+/* BTTV specific... */
+COMPATIBLE_IOCTL(_IOW('v',  BASE_VIDIOCPRIVATE+0, char [256]))
+COMPATIBLE_IOCTL(_IOR('v',  BASE_VIDIOCPRIVATE+1, char [256]))
+COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int))
+COMPATIBLE_IOCTL(_IOW('v' , BASE_VIDIOCPRIVATE+3, char [16])) /* struct bttv_pll_info */
+COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+4, int))
+COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+5, int))
+COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+6, int))
+COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+7, int))
+/* Little m */
+COMPATIBLE_IOCTL(MTIOCTOP)
+/* Socket level stuff */
+COMPATIBLE_IOCTL(FIOSETOWN)
+COMPATIBLE_IOCTL(SIOCSPGRP)
+COMPATIBLE_IOCTL(FIOGETOWN)
+COMPATIBLE_IOCTL(SIOCGPGRP)
+COMPATIBLE_IOCTL(SIOCATMARK)
+COMPATIBLE_IOCTL(SIOCSIFLINK)
+COMPATIBLE_IOCTL(SIOCSIFENCAP)
+COMPATIBLE_IOCTL(SIOCGIFENCAP)
+COMPATIBLE_IOCTL(SIOCSIFBR)
+COMPATIBLE_IOCTL(SIOCGIFBR)
+COMPATIBLE_IOCTL(SIOCSARP)
+COMPATIBLE_IOCTL(SIOCGARP)
+COMPATIBLE_IOCTL(SIOCDARP)
+COMPATIBLE_IOCTL(SIOCSRARP)
+COMPATIBLE_IOCTL(SIOCGRARP)
+COMPATIBLE_IOCTL(SIOCDRARP)
+COMPATIBLE_IOCTL(SIOCADDDLCI)
+COMPATIBLE_IOCTL(SIOCDELDLCI)
+/* SG stuff */
+COMPATIBLE_IOCTL(SG_SET_TIMEOUT)
+COMPATIBLE_IOCTL(SG_GET_TIMEOUT)
+COMPATIBLE_IOCTL(SG_EMULATED_HOST)
+COMPATIBLE_IOCTL(SG_SET_TRANSFORM)
+COMPATIBLE_IOCTL(SG_GET_TRANSFORM)
+COMPATIBLE_IOCTL(SG_SET_RESERVED_SIZE)
+COMPATIBLE_IOCTL(SG_GET_RESERVED_SIZE)
+COMPATIBLE_IOCTL(SG_GET_SCSI_ID)
+COMPATIBLE_IOCTL(SG_SET_FORCE_LOW_DMA)
+COMPATIBLE_IOCTL(SG_GET_LOW_DMA)
+COMPATIBLE_IOCTL(SG_SET_FORCE_PACK_ID)
+COMPATIBLE_IOCTL(SG_GET_PACK_ID)
+COMPATIBLE_IOCTL(SG_GET_NUM_WAITING)
+COMPATIBLE_IOCTL(SG_SET_DEBUG)
+COMPATIBLE_IOCTL(SG_GET_SG_TABLESIZE)
+COMPATIBLE_IOCTL(SG_GET_COMMAND_Q)
+COMPATIBLE_IOCTL(SG_SET_COMMAND_Q)
+COMPATIBLE_IOCTL(SG_GET_VERSION_NUM)
+COMPATIBLE_IOCTL(SG_NEXT_CMD_LEN)
+COMPATIBLE_IOCTL(SG_SCSI_RESET)
+COMPATIBLE_IOCTL(SG_IO)
+COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE)
+COMPATIBLE_IOCTL(SG_SET_KEEP_ORPHAN)
+COMPATIBLE_IOCTL(SG_GET_KEEP_ORPHAN)
+/* PPP stuff */
+COMPATIBLE_IOCTL(PPPIOCGFLAGS)
+COMPATIBLE_IOCTL(PPPIOCSFLAGS)
+COMPATIBLE_IOCTL(PPPIOCGASYNCMAP)
+COMPATIBLE_IOCTL(PPPIOCSASYNCMAP)
+COMPATIBLE_IOCTL(PPPIOCGUNIT)
+COMPATIBLE_IOCTL(PPPIOCGRASYNCMAP)
+COMPATIBLE_IOCTL(PPPIOCSRASYNCMAP)
+COMPATIBLE_IOCTL(PPPIOCGMRU)
+COMPATIBLE_IOCTL(PPPIOCSMRU)
+COMPATIBLE_IOCTL(PPPIOCSMAXCID)
+COMPATIBLE_IOCTL(PPPIOCGXASYNCMAP)
+COMPATIBLE_IOCTL(PPPIOCSXASYNCMAP)
+COMPATIBLE_IOCTL(PPPIOCXFERUNIT)
+COMPATIBLE_IOCTL(PPPIOCGNPMODE)
+COMPATIBLE_IOCTL(PPPIOCSNPMODE)
+COMPATIBLE_IOCTL(PPPIOCGDEBUG)
+COMPATIBLE_IOCTL(PPPIOCSDEBUG)
+COMPATIBLE_IOCTL(PPPIOCNEWUNIT)
+COMPATIBLE_IOCTL(PPPIOCATTACH)
+COMPATIBLE_IOCTL(PPPIOCDETACH)
+COMPATIBLE_IOCTL(PPPIOCSMRRU)
+COMPATIBLE_IOCTL(PPPIOCCONNECT)
+COMPATIBLE_IOCTL(PPPIOCDISCONN)
+COMPATIBLE_IOCTL(PPPIOCATTCHAN)
+/* PPPOX */
+COMPATIBLE_IOCTL(PPPOEIOCSFWD);
+COMPATIBLE_IOCTL(PPPOEIOCDFWD);
+/* CDROM stuff */
+COMPATIBLE_IOCTL(CDROMPAUSE)
+COMPATIBLE_IOCTL(CDROMRESUME)
+COMPATIBLE_IOCTL(CDROMPLAYMSF)
+COMPATIBLE_IOCTL(CDROMPLAYTRKIND)
+COMPATIBLE_IOCTL(CDROMREADTOCHDR)
+COMPATIBLE_IOCTL(CDROMREADTOCENTRY)
+COMPATIBLE_IOCTL(CDROMSTOP)
+COMPATIBLE_IOCTL(CDROMSTART)
+COMPATIBLE_IOCTL(CDROMEJECT)
+COMPATIBLE_IOCTL(CDROMVOLCTRL)
+COMPATIBLE_IOCTL(CDROMSUBCHNL)
+COMPATIBLE_IOCTL(CDROMEJECT_SW)
+COMPATIBLE_IOCTL(CDROMMULTISESSION)
+COMPATIBLE_IOCTL(CDROM_GET_MCN)
+COMPATIBLE_IOCTL(CDROMRESET)
+COMPATIBLE_IOCTL(CDROMVOLREAD)
+COMPATIBLE_IOCTL(CDROMSEEK)
+COMPATIBLE_IOCTL(CDROMPLAYBLK)
+COMPATIBLE_IOCTL(CDROMCLOSETRAY)
+COMPATIBLE_IOCTL(CDROM_SET_OPTIONS)
+COMPATIBLE_IOCTL(CDROM_CLEAR_OPTIONS)
+COMPATIBLE_IOCTL(CDROM_SELECT_SPEED)
+COMPATIBLE_IOCTL(CDROM_SELECT_DISC)
+COMPATIBLE_IOCTL(CDROM_MEDIA_CHANGED)
+COMPATIBLE_IOCTL(CDROM_DRIVE_STATUS)
+COMPATIBLE_IOCTL(CDROM_DISC_STATUS)
+COMPATIBLE_IOCTL(CDROM_CHANGER_NSLOTS)
+COMPATIBLE_IOCTL(CDROM_LOCKDOOR)
+COMPATIBLE_IOCTL(CDROM_DEBUG)
+COMPATIBLE_IOCTL(CDROM_GET_CAPABILITY)
+/* Big L */
+COMPATIBLE_IOCTL(LOOP_SET_FD)
+COMPATIBLE_IOCTL(LOOP_CLR_FD)
+/* Big Q for sound/OSS */
+COMPATIBLE_IOCTL(SNDCTL_SEQ_RESET)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_SYNC)
+COMPATIBLE_IOCTL(SNDCTL_SYNTH_INFO)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_CTRLRATE)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_GETOUTCOUNT)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_GETINCOUNT)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_PERCMODE)
+COMPATIBLE_IOCTL(SNDCTL_FM_LOAD_INSTR)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_TESTMIDI)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_RESETSAMPLES)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_NRSYNTHS)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_NRMIDIS)
+COMPATIBLE_IOCTL(SNDCTL_MIDI_INFO)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_THRESHOLD)
+COMPATIBLE_IOCTL(SNDCTL_SYNTH_MEMAVL)
+COMPATIBLE_IOCTL(SNDCTL_FM_4OP_ENABLE)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_PANIC)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_OUTOFBAND)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_GETTIME)
+COMPATIBLE_IOCTL(SNDCTL_SYNTH_ID)
+COMPATIBLE_IOCTL(SNDCTL_SYNTH_CONTROL)
+COMPATIBLE_IOCTL(SNDCTL_SYNTH_REMOVESAMPLE)
+/* Big T for sound/OSS */
+COMPATIBLE_IOCTL(SNDCTL_TMR_TIMEBASE)
+COMPATIBLE_IOCTL(SNDCTL_TMR_START)
+COMPATIBLE_IOCTL(SNDCTL_TMR_STOP)
+COMPATIBLE_IOCTL(SNDCTL_TMR_CONTINUE)
+COMPATIBLE_IOCTL(SNDCTL_TMR_TEMPO)
+COMPATIBLE_IOCTL(SNDCTL_TMR_SOURCE)
+COMPATIBLE_IOCTL(SNDCTL_TMR_METRONOME)
+COMPATIBLE_IOCTL(SNDCTL_TMR_SELECT)
+/* Little m for sound/OSS */
+COMPATIBLE_IOCTL(SNDCTL_MIDI_PRETIME)
+COMPATIBLE_IOCTL(SNDCTL_MIDI_MPUMODE)
+COMPATIBLE_IOCTL(SNDCTL_MIDI_MPUCMD)
+/* Big P for sound/OSS */
+COMPATIBLE_IOCTL(SNDCTL_DSP_RESET)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SYNC)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SPEED)
+COMPATIBLE_IOCTL(SNDCTL_DSP_STEREO)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETBLKSIZE)
+COMPATIBLE_IOCTL(SNDCTL_DSP_CHANNELS)
+COMPATIBLE_IOCTL(SOUND_PCM_WRITE_FILTER)
+COMPATIBLE_IOCTL(SNDCTL_DSP_POST)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SUBDIVIDE)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SETFRAGMENT)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETFMTS)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SETFMT)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETOSPACE)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETISPACE)
+COMPATIBLE_IOCTL(SNDCTL_DSP_NONBLOCK)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETCAPS)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETTRIGGER)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SETTRIGGER)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETIPTR)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETOPTR)
+/* SNDCTL_DSP_MAPINBUF,  XXX needs translation */
+/* SNDCTL_DSP_MAPOUTBUF,  XXX needs translation */
+COMPATIBLE_IOCTL(SNDCTL_DSP_SETSYNCRO)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SETDUPLEX)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETODELAY)
+COMPATIBLE_IOCTL(SNDCTL_DSP_PROFILE)
+COMPATIBLE_IOCTL(SOUND_PCM_READ_RATE)
+COMPATIBLE_IOCTL(SOUND_PCM_READ_CHANNELS)
+COMPATIBLE_IOCTL(SOUND_PCM_READ_BITS)
+COMPATIBLE_IOCTL(SOUND_PCM_READ_FILTER)
+/* Big C for sound/OSS */
+COMPATIBLE_IOCTL(SNDCTL_COPR_RESET)
+COMPATIBLE_IOCTL(SNDCTL_COPR_LOAD)
+COMPATIBLE_IOCTL(SNDCTL_COPR_RDATA)
+COMPATIBLE_IOCTL(SNDCTL_COPR_RCODE)
+COMPATIBLE_IOCTL(SNDCTL_COPR_WDATA)
+COMPATIBLE_IOCTL(SNDCTL_COPR_WCODE)
+COMPATIBLE_IOCTL(SNDCTL_COPR_RUN)
+COMPATIBLE_IOCTL(SNDCTL_COPR_HALT)
+COMPATIBLE_IOCTL(SNDCTL_COPR_SENDMSG)
+COMPATIBLE_IOCTL(SNDCTL_COPR_RCVMSG)
+/* Big M for sound/OSS */
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_VOLUME)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_BASS)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_TREBLE)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_SYNTH)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_PCM)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_SPEAKER)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_MIC)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_CD)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_IMIX)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_ALTPCM)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECLEV)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_IGAIN)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_OGAIN)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE1)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE2)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE3)
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL1))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL2))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL3))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_PHONEIN))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_PHONEOUT))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_VIDEO))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_RADIO))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_MONITOR))
+COMPATIBLE_IOCTL(SOUND_MIXER_MUTE)
+/* SOUND_MIXER_READ_ENHANCE,  same value as READ_MUTE */
+/* SOUND_MIXER_READ_LOUD,  same value as READ_MUTE */
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECSRC)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_DEVMASK)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECMASK)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_STEREODEVS)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_CAPS)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_VOLUME)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_BASS)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_TREBLE)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_SYNTH)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_PCM)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_SPEAKER)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_MIC)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_CD)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_IMIX)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_ALTPCM)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_RECLEV)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_IGAIN)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_OGAIN)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE1)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE2)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE3)
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL1))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL2))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL3))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_PHONEIN))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_PHONEOUT))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_VIDEO))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_RADIO))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_MONITOR))
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_MUTE)
+/* SOUND_MIXER_WRITE_ENHANCE,  same value as WRITE_MUTE */
+/* SOUND_MIXER_WRITE_LOUD,  same value as WRITE_MUTE */
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_RECSRC)
+COMPATIBLE_IOCTL(SOUND_MIXER_INFO)
+COMPATIBLE_IOCTL(SOUND_OLD_MIXER_INFO)
+COMPATIBLE_IOCTL(SOUND_MIXER_ACCESS)
+COMPATIBLE_IOCTL(SOUND_MIXER_AGC)
+COMPATIBLE_IOCTL(SOUND_MIXER_3DSE)
+COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE1)
+COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE2)
+COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE3)
+COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE4)
+COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE5)
+COMPATIBLE_IOCTL(SOUND_MIXER_GETLEVELS)
+COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS)
+COMPATIBLE_IOCTL(OSS_GETVERSION)
+/* AUTOFS */
+COMPATIBLE_IOCTL(AUTOFS_IOC_READY)
+COMPATIBLE_IOCTL(AUTOFS_IOC_FAIL)
+COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC)
+COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER)
+COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE)
+/* DEVFS */
+COMPATIBLE_IOCTL(DEVFSDIOC_GET_PROTO_REV)
+COMPATIBLE_IOCTL(DEVFSDIOC_SET_EVENT_MASK)
+COMPATIBLE_IOCTL(DEVFSDIOC_RELEASE_EVENT_QUEUE)
+COMPATIBLE_IOCTL(DEVFSDIOC_SET_DEBUG_MASK)
+/* Raw devices */
+COMPATIBLE_IOCTL(RAW_SETBIND)
+COMPATIBLE_IOCTL(RAW_GETBIND)
+/* SMB ioctls which do not need any translations */
+COMPATIBLE_IOCTL(SMB_IOC_NEWCONN)
+/* Little a */
+COMPATIBLE_IOCTL(ATMSIGD_CTRL)
+COMPATIBLE_IOCTL(ATMARPD_CTRL)
+COMPATIBLE_IOCTL(ATMLEC_CTRL)
+COMPATIBLE_IOCTL(ATMLEC_MCAST)
+COMPATIBLE_IOCTL(ATMLEC_DATA)
+COMPATIBLE_IOCTL(ATM_SETSC)
+COMPATIBLE_IOCTL(SIOCSIFATMTCP)
+COMPATIBLE_IOCTL(SIOCMKCLIP)
+COMPATIBLE_IOCTL(ATMARP_MKIP)
+COMPATIBLE_IOCTL(ATMARP_SETENTRY)
+COMPATIBLE_IOCTL(ATMARP_ENCAP)
+COMPATIBLE_IOCTL(ATMTCP_CREATE)
+COMPATIBLE_IOCTL(ATMTCP_REMOVE)
+COMPATIBLE_IOCTL(ATMMPC_CTRL)
+COMPATIBLE_IOCTL(ATMMPC_DATA)
+#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
+/* 0xfe - lvm */
+COMPATIBLE_IOCTL(VG_SET_EXTENDABLE)
+COMPATIBLE_IOCTL(VG_STATUS_GET_COUNT)
+COMPATIBLE_IOCTL(VG_STATUS_GET_NAMELIST)
+COMPATIBLE_IOCTL(VG_REMOVE)
+COMPATIBLE_IOCTL(VG_RENAME)
+COMPATIBLE_IOCTL(VG_REDUCE)
+COMPATIBLE_IOCTL(PE_LOCK_UNLOCK)
+COMPATIBLE_IOCTL(PV_FLUSH)
+COMPATIBLE_IOCTL(LVM_LOCK_LVM)
+COMPATIBLE_IOCTL(LVM_GET_IOP_VERSION)
+#ifdef LVM_TOTAL_RESET
+COMPATIBLE_IOCTL(LVM_RESET)
+#endif
+COMPATIBLE_IOCTL(LV_SET_ACCESS)
+COMPATIBLE_IOCTL(LV_SET_STATUS)
+COMPATIBLE_IOCTL(LV_SET_ALLOCATION)
+COMPATIBLE_IOCTL(LE_REMAP)
+COMPATIBLE_IOCTL(LV_BMAP)
+COMPATIBLE_IOCTL(LV_SNAPSHOT_USE_RATE)
+#endif /* LVM */
+#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
+COMPATIBLE_IOCTL(DRM_IOCTL_GET_MAGIC)
+COMPATIBLE_IOCTL(DRM_IOCTL_IRQ_BUSID)
+COMPATIBLE_IOCTL(DRM_IOCTL_AUTH_MAGIC)
+COMPATIBLE_IOCTL(DRM_IOCTL_BLOCK)
+COMPATIBLE_IOCTL(DRM_IOCTL_UNBLOCK)
+COMPATIBLE_IOCTL(DRM_IOCTL_CONTROL)
+COMPATIBLE_IOCTL(DRM_IOCTL_ADD_BUFS)
+COMPATIBLE_IOCTL(DRM_IOCTL_MARK_BUFS)
+COMPATIBLE_IOCTL(DRM_IOCTL_ADD_CTX)
+COMPATIBLE_IOCTL(DRM_IOCTL_RM_CTX)
+COMPATIBLE_IOCTL(DRM_IOCTL_MOD_CTX)
+COMPATIBLE_IOCTL(DRM_IOCTL_GET_CTX)
+COMPATIBLE_IOCTL(DRM_IOCTL_SWITCH_CTX)
+COMPATIBLE_IOCTL(DRM_IOCTL_NEW_CTX)
+COMPATIBLE_IOCTL(DRM_IOCTL_ADD_DRAW)
+COMPATIBLE_IOCTL(DRM_IOCTL_RM_DRAW)
+COMPATIBLE_IOCTL(DRM_IOCTL_LOCK)
+COMPATIBLE_IOCTL(DRM_IOCTL_UNLOCK)
+COMPATIBLE_IOCTL(DRM_IOCTL_FINISH)
+#endif /* DRM */
+/* elevator */
+COMPATIBLE_IOCTL(BLKELVGET)
+COMPATIBLE_IOCTL(BLKELVSET)
+/* And these ioctls need translation */
+HANDLE_IOCTL(TIOCGSERIAL, do_tiocgserial)
+HANDLE_IOCTL(SIOCGIFNAME, dev_ifname32)
+HANDLE_IOCTL(SIOCGIFCONF, dev_ifconf)
+HANDLE_IOCTL(SIOCGIFFLAGS, dev_ifsioc)
+HANDLE_IOCTL(SIOCSIFFLAGS, dev_ifsioc)
+HANDLE_IOCTL(SIOCGIFMETRIC, dev_ifsioc)
+HANDLE_IOCTL(SIOCSIFMETRIC, dev_ifsioc)
+HANDLE_IOCTL(SIOCGIFMTU, dev_ifsioc)
+HANDLE_IOCTL(SIOCSIFMTU, dev_ifsioc)
+HANDLE_IOCTL(SIOCGIFMEM, dev_ifsioc)
+HANDLE_IOCTL(SIOCSIFMEM, dev_ifsioc)
+HANDLE_IOCTL(SIOCGIFHWADDR, dev_ifsioc)
+HANDLE_IOCTL(SIOCSIFHWADDR, dev_ifsioc)
+HANDLE_IOCTL(SIOCADDMULTI, dev_ifsioc)
+HANDLE_IOCTL(SIOCDELMULTI, dev_ifsioc)
+HANDLE_IOCTL(SIOCGIFINDEX, dev_ifsioc)
+HANDLE_IOCTL(SIOCGIFMAP, dev_ifsioc)
+HANDLE_IOCTL(SIOCSIFMAP, dev_ifsioc)
+HANDLE_IOCTL(SIOCGIFADDR, dev_ifsioc)
+HANDLE_IOCTL(SIOCSIFADDR, dev_ifsioc)
+HANDLE_IOCTL(SIOCGIFBRDADDR, dev_ifsioc)
+HANDLE_IOCTL(SIOCSIFBRDADDR, dev_ifsioc)
+HANDLE_IOCTL(SIOCGIFDSTADDR, dev_ifsioc)
+HANDLE_IOCTL(SIOCSIFDSTADDR, dev_ifsioc)
+HANDLE_IOCTL(SIOCGIFNETMASK, dev_ifsioc)
+HANDLE_IOCTL(SIOCSIFNETMASK, dev_ifsioc)
+HANDLE_IOCTL(SIOCSIFPFLAGS, dev_ifsioc)
+HANDLE_IOCTL(SIOCGIFPFLAGS, dev_ifsioc)
+HANDLE_IOCTL(SIOCGPPPSTATS, dev_ifsioc)
+HANDLE_IOCTL(SIOCGPPPCSTATS, dev_ifsioc)
+HANDLE_IOCTL(SIOCGPPPVER, dev_ifsioc)
+HANDLE_IOCTL(SIOCGIFTXQLEN, dev_ifsioc)
+HANDLE_IOCTL(SIOCSIFTXQLEN, dev_ifsioc)
+HANDLE_IOCTL(SIOCADDRT, routing_ioctl)
+HANDLE_IOCTL(SIOCDELRT, routing_ioctl)
+/* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */
+HANDLE_IOCTL(SIOCRTMSG, ret_einval)
+HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp)
+HANDLE_IOCTL(HDIO_GETGEO, hdio_getgeo)
+HANDLE_IOCTL(BLKRAGET, w_long)
+HANDLE_IOCTL(BLKGETSIZE, w_long)
+HANDLE_IOCTL(0x1260, broken_blkgetsize)
+HANDLE_IOCTL(BLKFRAGET, w_long)
+HANDLE_IOCTL(BLKSECTGET, w_long)
+HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans)
+
+HANDLE_IOCTL(FBIOGET_FSCREENINFO, fb_ioctl_trans)
+HANDLE_IOCTL(FBIOGETCMAP, fb_ioctl_trans)
+HANDLE_IOCTL(FBIOPUTCMAP, fb_ioctl_trans)
+
+HANDLE_IOCTL(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans)
+HANDLE_IOCTL(HDIO_GET_UNMASKINTR, hdio_ioctl_trans)
+HANDLE_IOCTL(HDIO_GET_DMA, hdio_ioctl_trans)
+HANDLE_IOCTL(HDIO_GET_32BIT, hdio_ioctl_trans)
+HANDLE_IOCTL(HDIO_GET_MULTCOUNT, hdio_ioctl_trans)
+HANDLE_IOCTL(HDIO_GET_NOWERR, hdio_ioctl_trans)
+HANDLE_IOCTL(HDIO_GET_NICE, hdio_ioctl_trans)
+HANDLE_IOCTL(FDSETPRM32, fd_ioctl_trans)
+HANDLE_IOCTL(FDDEFPRM32, fd_ioctl_trans)
+HANDLE_IOCTL(FDGETPRM32, fd_ioctl_trans)
+HANDLE_IOCTL(FDSETDRVPRM32, fd_ioctl_trans)
+HANDLE_IOCTL(FDGETDRVPRM32, fd_ioctl_trans)
+HANDLE_IOCTL(FDGETDRVSTAT32, fd_ioctl_trans)
+HANDLE_IOCTL(FDPOLLDRVSTAT32, fd_ioctl_trans)
+HANDLE_IOCTL(FDGETFDCSTAT32, fd_ioctl_trans)
+HANDLE_IOCTL(FDWERRORGET32, fd_ioctl_trans)
+HANDLE_IOCTL(PPPIOCGIDLE32, ppp_ioctl_trans)
+HANDLE_IOCTL(PPPIOCSCOMPRESS32, ppp_ioctl_trans)
+HANDLE_IOCTL(MTIOCGET32, mt_ioctl_trans)
+HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans)
+HANDLE_IOCTL(MTIOCGETCONFIG32, mt_ioctl_trans)
+HANDLE_IOCTL(MTIOCSETCONFIG32, mt_ioctl_trans)
+HANDLE_IOCTL(CDROMREADMODE2, cdrom_ioctl_trans)
+HANDLE_IOCTL(CDROMREADMODE1, cdrom_ioctl_trans)
+HANDLE_IOCTL(CDROMREADRAW, cdrom_ioctl_trans)
+HANDLE_IOCTL(CDROMREADCOOKED, cdrom_ioctl_trans)
+HANDLE_IOCTL(CDROMREADAUDIO, cdrom_ioctl_trans)
+HANDLE_IOCTL(CDROMREADALL, cdrom_ioctl_trans)
+HANDLE_IOCTL(CDROM_SEND_PACKET, cdrom_ioctl_trans)
+HANDLE_IOCTL(LOOP_SET_STATUS, loop_status)
+HANDLE_IOCTL(LOOP_GET_STATUS, loop_status)
+#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int)
+HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout)
+#ifdef CONFIG_VT
+HANDLE_IOCTL(PIO_FONTX, do_fontx_ioctl)
+HANDLE_IOCTL(GIO_FONTX, do_fontx_ioctl)
+HANDLE_IOCTL(PIO_UNIMAP, do_unimap_ioctl)
+HANDLE_IOCTL(GIO_UNIMAP, do_unimap_ioctl)
+HANDLE_IOCTL(KDFONTOP, do_kdfontop_ioctl)
+#endif
+HANDLE_IOCTL(EXT2_IOC32_GETFLAGS, do_ext2_ioctl)
+HANDLE_IOCTL(EXT2_IOC32_SETFLAGS, do_ext2_ioctl)
+HANDLE_IOCTL(EXT2_IOC32_GETVERSION, do_ext2_ioctl)
+HANDLE_IOCTL(EXT2_IOC32_SETVERSION, do_ext2_ioctl)
+#if 0
+/* One SMB ioctl needs translations. */
+#define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, __kernel_uid_t32)
+HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid)
+#endif
+HANDLE_IOCTL(ATM_GETLINKRATE32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_GETNAMES32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_GETTYPE32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_GETESI32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_GETADDR32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_RSTADDR32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_ADDADDR32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_DELADDR32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_GETCIRANGE32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_SETCIRANGE32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_SETESI32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_SETESIF32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_GETSTAT32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_GETSTATZ32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_GETLOOP32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_SETLOOP32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_QUERYLOOP32, do_atm_ioctl)
+HANDLE_IOCTL(SONET_GETSTAT, do_atm_ioctl)
+HANDLE_IOCTL(SONET_GETSTATZ, do_atm_ioctl)
+HANDLE_IOCTL(SONET_GETDIAG, do_atm_ioctl)
+HANDLE_IOCTL(SONET_SETDIAG, do_atm_ioctl)
+HANDLE_IOCTL(SONET_CLRDIAG, do_atm_ioctl)
+HANDLE_IOCTL(SONET_SETFRAMING, do_atm_ioctl)
+HANDLE_IOCTL(SONET_GETFRAMING, do_atm_ioctl)
+HANDLE_IOCTL(SONET_GETFRSENSE, do_atm_ioctl)
+#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
+HANDLE_IOCTL(VG_STATUS, do_lvm_ioctl)
+HANDLE_IOCTL(VG_CREATE_OLD, do_lvm_ioctl)
+HANDLE_IOCTL(VG_CREATE, do_lvm_ioctl)
+HANDLE_IOCTL(VG_EXTEND, do_lvm_ioctl)
+HANDLE_IOCTL(LV_CREATE, do_lvm_ioctl)
+HANDLE_IOCTL(LV_REMOVE, do_lvm_ioctl)
+HANDLE_IOCTL(LV_EXTEND, do_lvm_ioctl)
+HANDLE_IOCTL(LV_REDUCE, do_lvm_ioctl)
+HANDLE_IOCTL(LV_RENAME, do_lvm_ioctl)
+HANDLE_IOCTL(LV_STATUS_BYNAME, do_lvm_ioctl)
+HANDLE_IOCTL(LV_STATUS_BYINDEX, do_lvm_ioctl)
+HANDLE_IOCTL(LV_STATUS_BYDEV, do_lvm_ioctl)
+HANDLE_IOCTL(PV_CHANGE, do_lvm_ioctl)
+HANDLE_IOCTL(PV_STATUS, do_lvm_ioctl)
+#endif /* LVM */
+#if defined(CONFIG_GENRTC)
+COMPATIBLE_IOCTL(RTC_AIE_ON)
+COMPATIBLE_IOCTL(RTC_AIE_OFF)
+COMPATIBLE_IOCTL(RTC_UIE_ON)
+COMPATIBLE_IOCTL(RTC_UIE_OFF)
+COMPATIBLE_IOCTL(RTC_PIE_ON)
+COMPATIBLE_IOCTL(RTC_PIE_OFF)
+COMPATIBLE_IOCTL(RTC_WIE_ON)
+COMPATIBLE_IOCTL(RTC_WIE_OFF)
+COMPATIBLE_IOCTL(RTC_ALM_SET)   /* struct rtc_time only has ints */
+COMPATIBLE_IOCTL(RTC_ALM_READ)  /* struct rtc_time only has ints */
+COMPATIBLE_IOCTL(RTC_RD_TIME)   /* struct rtc_time only has ints */
+COMPATIBLE_IOCTL(RTC_SET_TIME)  /* struct rtc_time only has ints */
+HANDLE_IOCTL(RTC_IRQP_READ, w_long)
+COMPATIBLE_IOCTL(RTC_IRQP_SET)
+HANDLE_IOCTL(RTC_EPOCH_READ, w_long)
+COMPATIBLE_IOCTL(RTC_EPOCH_SET)
+#endif
+#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
+HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version);
+HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique);
+HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique);
+HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap);
+HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs);
+HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs);
+HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs);
+HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma);
+HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx);
+#endif /* DRM */
+COMPATIBLE_IOCTL(PA_PERF_ON)
+COMPATIBLE_IOCTL(PA_PERF_OFF)
+COMPATIBLE_IOCTL(PA_PERF_VERSION)
+IOCTL_TABLE_END
+
+unsigned int ioctl32_hash_table[1024];
+
+extern inline unsigned long ioctl32_hash(unsigned long cmd)
+{
+	return ((cmd >> 6) ^ (cmd >> 4) ^ cmd) & 0x3ff;
+}
+
+static void ioctl32_insert_translation(struct ioctl_trans *trans)
+{
+	unsigned long hash;
+	struct ioctl_trans *t;
+
+	hash = ioctl32_hash (trans->cmd);
+	if (!ioctl32_hash_table[hash])
+		ioctl32_hash_table[hash] = (u32)(long)trans;
+	else {
+		t = (struct ioctl_trans *)(long)ioctl32_hash_table[hash];
+		while (t->next)
+			t = (struct ioctl_trans *)(long)t->next;
+		trans->next = 0;
+		t->next = (u32)(long)trans;
+	}
+}
+
+static int __init init_sys32_ioctl(void)
+{
+	int i;
+	extern struct ioctl_trans ioctl_translations[], ioctl_translations_end[];
+
+	for (i = 0; &ioctl_translations[i] < &ioctl_translations_end[0]; i++)
+		ioctl32_insert_translation(&ioctl_translations[i]);
+	return 0;
+}
+
+__initcall(init_sys32_ioctl);
+
+static struct ioctl_trans *additional_ioctls;
+
+/* Always call these with kernel lock held! */
+
+int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, unsigned int, unsigned long, struct file *))
+{
+	int i;
+
+panic("register_ioctl32_conversion() is B0RKEN! Called by %p\n", __builtin_return_address(0));
+
+	if (!additional_ioctls) {
+		additional_ioctls = module_map(PAGE_SIZE);
+		if (!additional_ioctls)
+			return -ENOMEM;
+		memset(additional_ioctls, 0, PAGE_SIZE);
+	}
+	for (i = 0; i < PAGE_SIZE/sizeof(struct ioctl_trans); i++)
+		if (!additional_ioctls[i].cmd)
+			break;
+	if (i == PAGE_SIZE/sizeof(struct ioctl_trans))
+		return -ENOMEM;
+	additional_ioctls[i].cmd = cmd;
+	if (!handler)
+		additional_ioctls[i].handler = (u32)(long)sys_ioctl;
+	else
+		additional_ioctls[i].handler = (u32)(long)handler;
+	ioctl32_insert_translation(&additional_ioctls[i]);
+	return 0;
+}
+
+int unregister_ioctl32_conversion(unsigned int cmd)
+{
+	unsigned long hash = ioctl32_hash(cmd);
+	struct ioctl_trans *t, *t1;
+
+	t = (struct ioctl_trans *)(long)ioctl32_hash_table[hash];
+	if (!t) return -EINVAL;
+	if (t->cmd == cmd && t >= additional_ioctls &&
+	    (unsigned long)t < ((unsigned long)additional_ioctls) + PAGE_SIZE) {
+		ioctl32_hash_table[hash] = t->next;
+		t->cmd = 0;
+		return 0;
+	} else while (t->next) {
+		t1 = (struct ioctl_trans *)(long)t->next;
+		if (t1->cmd == cmd && t1 >= additional_ioctls &&
+		    (unsigned long)t1 < ((unsigned long)additional_ioctls) + PAGE_SIZE) {
+			t1->cmd = 0;
+			t->next = t1->next;
+			return 0;
+		}
+		t = t1;
+	}
+	return -EINVAL;
+}
+
+asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct file * filp;
+	int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp);
+	unsigned long pafnptr[4];
+	extern char __gp;
+	struct ioctl_trans *t;
+	int error = -EBADF;
+
+	filp = fget(fd);
+	if(!filp)
+		goto out2;
+
+	if (!filp->f_op || !filp->f_op->ioctl) {
+		error = sys_ioctl (fd, cmd, arg);
+		goto out;
+	}
+
+	/* intercept private networking ioctl() calls here since it is
+	 * an onerous task to figure out which ones of the HANDLE_IOCTL
+	 * list map to these values.
+	 */
+	if (cmd >= SIOCDEVPRIVATE && cmd <= SIOCDEVPRIVATE + 0xf) {
+		error = siocprivate(fd, cmd, arg);
+		goto out;
+	}
+
+	t = (struct ioctl_trans *)(long)ioctl32_hash_table [ioctl32_hash (cmd)];
+
+	while (t && t->cmd != cmd)
+		t = (struct ioctl_trans *)(long)t->next;
+	if (t) {
+		handler = (void *) pafnptr;
+		pafnptr[0] = pafnptr[1] = 0UL;
+		pafnptr[2] = (unsigned long) t->handler;
+		pafnptr[3] = A(&__gp);
+		error = handler(fd, cmd, arg, filp);
+	} else {
+		static int count = 0;
+		if (++count <= 20)
+			printk(KERN_WARNING
+				"sys32_ioctl: Unknown cmd fd(%d) "
+				"cmd(%08x) arg(%08x)\n",
+				(int)fd, (unsigned int)cmd, (unsigned int)arg);
+		error = -EINVAL;
+	}
+out:
+	fput(filp);
+out2:
+	return error;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/iosapic.c linux-bk/arch/parisc/kernel/iosapic.c
--- linux-2.4.19/arch/parisc/kernel/iosapic.c	2001-02-09 19:29:44.000000000 +0000
+++ linux-bk/arch/parisc/kernel/iosapic.c	2002-08-17 00:48:54.000000000 +0000
@@ -169,11 +169,13 @@
 
 #include <asm/byteorder.h>	/* get in-line asm for swab */
 #include <asm/pdc.h>
-#include <asm/pdcpat.h>
 #include <asm/page.h>
 #include <asm/segment.h>
 #include <asm/system.h>
 #include <asm/gsc.h>		/* gsc_read/write functions */
+#ifdef CONFIG_SUPERIO
+#include <asm/superio.h>
+#endif
 
 #include <asm/iosapic.h>
 #include "./iosapic_private.h"
@@ -181,7 +183,6 @@
 #define MODULE_NAME "iosapic"
 
 /* "local" compile flags */
-#undef IOSAPIC_CALLBACK
 #undef PCI_BRIDGE_FUNCS
 #undef DEBUG_IOSAPIC
 #undef DEBUG_IOSAPIC_IRT
@@ -282,28 +283,6 @@
 
 #define	IOSAPIC_EOI(eoi_addr, eoi_data) gsc_writel(eoi_data, eoi_addr)
 
-#if IOSAPIC_CALLBACK
-/*
-** Shouldn't use callback since SAPIC doesn't have an officially assigned
-** H or S version numbers. Slight long term risk the number chosen would
-** collide with something else.
-** But benefit is cleaner lba/sapic interface.
-** Might be worth it but for just use direct calls for now.
-**
-** Entry below is copied from lba driver.
-** Only thing different is hw_type.
-*/
-static struct pa_iodc_driver iosapic_driver_for[] = {
-	{HPHW_OTHER, 0x782, 0, 0x0000A, 0, 0x00,
-	DRIVER_CHECK_HWTYPE + DRIVER_CHECK_HVERSION + DRIVER_CHECK_SVERSION,
-	"I/O Sapic", "",(void *) iosapic_callback},     
-	{0,0,0,0,0,0,
-	0,
-	(char *) NULL,(char *) NULL,(void *) NULL}                     
-};
-#endif /* IOSAPIO_CALLBACK */
-
-
 static struct iosapic_info *iosapic_list;
 static spinlock_t iosapic_lock;
 static int iosapic_count;
@@ -350,25 +329,22 @@
 static int __init /* return number of entries as success/fail flag */
 iosapic_load_irt(unsigned long cell_num, struct irt_entry **irt)
 {
-	struct pdc_pat_io_num pdc_io_num; /* PAT PDC return block */
 	long status;              /* PDC return value status */
-	struct irt_entry *table = NULL;  /* start of interrupt routing tbl */
+	struct irt_entry *table;  /* start of interrupt routing tbl */
 	unsigned long num_entries = 0UL;
 
 	ASSERT(NULL != irt);
-	/* FIXME ASSERT(((&pdc_io_num) & (0x3f)) == 0);  enforce 32-byte alignment */
 
-	/* Try PAT_PDC to get interrupt routing table size */
-	DBG(KERN_DEBUG "calling get_irt_size\n");
-	status = pdc_pat_get_irt_size( &pdc_io_num, cell_num);
-	DBG(KERN_DEBUG "get_irt_size: %ld\n", status);
+	if (is_pdc_pat()) {
 
-	switch(status) {
+		/* Use pat pdc routine to get interrupt routing table size */
+		DBG("calling get_irt_size (cell %ld)\n", cell_num);
+		status = pdc_pat_get_irt_size(&num_entries, cell_num);
+		DBG("get_irt_size: %ld\n", status);
 
-	case PDC_RET_OK:	/* PAT box. Proceed to get the IRT */
+		ASSERT(status == PDC_OK);
 
 		/* save the number of entries in the table */
-		num_entries = pdc_io_num.num;
 		ASSERT(0UL != num_entries);
 
 		/*
@@ -384,30 +360,27 @@
 		}
 
 		/* get PCI INT routing table */
-		status = pdc_pat_get_irt( (void *) table, cell_num);
-		DBG(KERN_DEBUG "pdc_pat_get_irt: %ld\n", status);
-		ASSERT(status == PDC_RET_OK);
-		break;
-
-	case PDC_RET_NE_PROC: /* Not a PAT platform. Try PDC_PCI extensions */
+		status = pdc_pat_get_irt(table, cell_num);
+		DBG("pdc_pat_get_irt: %ld\n", status);
+		ASSERT(status == PDC_OK);
+	} else {
 		/*
-		** C3000/J5000 (and similar) platforms with "legacy" PDC
-		** will return exactly one IRT.
+		** C3000/J5000 (and similar) platforms with Sprockets PDC
+		** will return exactly one IRT for all iosapics.
 		** So if we have one, don't need to get it again.
 		*/
 		if (NULL != irt_cell)
-			break;
+			return 0;
 
-		status = pdc_pci_irt_size( (void *)&pdc_io_num,
-				/* elroy HPA (really a NOP) */ 0);
-		DBG(KERN_WARNING "pdc_pci_irt_size: %ld\n", status);
+		/* Should be using the Elroy's HPA, but it's ignored anyway */
+		status = pdc_pci_irt_size(&num_entries, 0);
+		DBG("pdc_pci_irt_size: %ld\n", status);
 
-		if (PDC_RET_OK != status) {
+		if (PDC_OK != status) {
 			/* Not a "legacy" system with I/O SAPIC either */
 			return 0;
 		}
 
-		num_entries = pdc_io_num.num;
 		ASSERT(0UL != num_entries);
 
 		table = IOSAPIC_KALLOC(struct irt_entry, num_entries);
@@ -416,36 +389,27 @@
 			return 0;
 		}
 
-		status = pdc_pci_irt( (void *) &pdc_io_num,
-				(void *) NULL, /* Elroy HPA - not used */
-				(void *) table);
-
-		ASSERT(PDC_RET_OK == status);
-		break;
-
-	default:
-		printk(KERN_WARNING MODULE_NAME ": PDC_PAT_IO call failed with %ld\n", status);
-		break;
+		/* HPA ignored by this call too. */
+		status = pdc_pci_irt(num_entries, 0, table);
+		ASSERT(PDC_OK == status);
 	}
 
 	/* return interrupt table address */
 	*irt = table;
 
-
 #ifdef DEBUG_IOSAPIC_IRT
-	{
+{
 	struct irt_entry *p = table;
 	int i;
 
-	printk(MODULE_NAME " Interrupt Routing Table (cell %ld)\n", cell_num);
-	printk(MODULE_NAME " start = 0x%p num_entries %ld entry_size %d\n",
+	printk(KERN_DEBUG MODULE_NAME " Interrupt Routing Table (cell %ld)\n", cell_num);
+	printk(KERN_DEBUG MODULE_NAME " start = 0x%p num_entries %ld entry_size %d\n",
 		table,
 		num_entries,
 		(int) sizeof(struct irt_entry));
 
-	for (i = 0 ; i < num_entries ; i++, p++)
-	{
-		printk(MODULE_NAME " %02x %02x %02x %02x %02x %02x %02x %02x %08x%08x\n",
+	for (i = 0 ; i < num_entries ; i++, p++) {
+		printk(KERN_DEBUG MODULE_NAME " %02x %02x %02x %02x %02x %02x %02x %02x %08x%08x\n",
 		p->entry_type, p->entry_length, p->interrupt_type,
 		p->polarity_trigger, p->src_bus_irq_devno, p->src_bus_id,
 		p->src_seg_id, p->dest_iosapic_intin,
@@ -453,7 +417,7 @@
 		((u32 *) p)[3]
 		);
 	}
-	}
+}
 #endif /* DEBUG_IOSAPIC_IRT */
 
 	return num_entries;
@@ -464,6 +428,8 @@
 void __init
 iosapic_init(void)
 {
+	unsigned long cell = 0;
+
 	/* init global data */
 	iosapic_lock = SPIN_LOCK_UNLOCKED;
         iosapic_list = (struct iosapic_info *) NULL;
@@ -471,22 +437,24 @@
 
 	DBG("iosapic_init()\n");
 
+#ifdef __LP64__
+	if (is_pdc_pat()) {
+		int status;
+		struct pdc_pat_cell_num cell_info;
+
+		status = pdc_pat_cell_get_number(&cell_info);
+		if (status == PDC_OK) {
+			cell = cell_info.cell_num;
+		}
+	}
+#endif
+
 	/*
 	**  get IRT for this cell.
 	*/
-	irt_num_entry =  iosapic_load_irt(0L, &irt_cell);
+	irt_num_entry =  iosapic_load_irt(cell, &irt_cell);
 	if (0 == irt_num_entry)
 		irt_cell = NULL;	/* old PDC w/o iosapic */
-
-#ifdef IOSAPIC_CALLBACK
-	/*
-	** When new I/O SAPICs are discovered, this callback
-	** will get invoked. Implies lba driver will register
-	** I/O Sapic as a device it "discovered" with faked
-	** IODC data.
-	*/
-	register_driver(iosapic_driver_for);
-#endif /* IOSAPIC_CALLBACK */
 }
 
 
@@ -546,7 +514,7 @@
 		return i;
 	}
 
-	printk(KERN_WARNING MODULE_NAME ": 0x%p : no IRT entry for slot %d, pin %d\n",
+	printk(KERN_WARNING MODULE_NAME ": 0x%lx : no IRT entry for slot %d, pin %d\n",
 			isi->isi_hpa, slot, intr_pin);
 	return NULL;
 }
@@ -571,21 +539,18 @@
 {
 	u8 intr_pin, intr_slot;
 
-	(void) pci_read_config_byte(pcidev, PCI_INTERRUPT_PIN, &intr_pin);
+	pci_read_config_byte(pcidev, PCI_INTERRUPT_PIN, &intr_pin);
 
-	DBG_IRT("iosapic_xlate_pin() SLOT %d pin %d\n", PCI_SLOT(pcidev->devfn), intr_pin);
+	DBG_IRT("iosapic_xlate_pin() SLOT %d pin %d\n",
+		PCI_SLOT(pcidev->devfn), intr_pin);
 
-	if (0 == intr_pin)
-	{
-		/*
-		** The device does NOT support/use IRQ lines.
-		*/
+	if (0 == intr_pin) {
+		/* The device does NOT support/use IRQ lines.  */
 		return NULL;
 	}
 
 	/* Check if pcidev behind a PPB */
-	if (NULL != pcidev->bus->self)
-	{
+	if (NULL != pcidev->bus->self) {
 		/* Convert pcidev INTR_PIN into something we
 		** can lookup in the IRT.
 		*/
@@ -600,7 +565,7 @@
 		** or by some ambitous soul who wants to watch TV.
 		*/
 		if (pci_bridge_funcs->xlate_intr_line) {
-			intr_pin = (*pci_bridge_funcs->xlate_intr_line)(pcidev);
+			intr_pin = pci_bridge_funcs->xlate_intr_line(pcidev);
 		}
 #else	/* PCI_BRIDGE_FUNCS */
 		struct pci_bus *p = pcidev->bus;
@@ -646,8 +611,8 @@
 	extern void do_irq(struct irqaction *a, int i, struct pt_regs *p);
 	int irq_num = vi->vi_ios->isi_region->data.irqbase + vi->vi_irqline;
 
-	DBG("iosapic_interrupt(): irq %d line %d eoi %p\n", irq, vi->vi_irqline,
-				vi->vi_eoi_addr);
+	DBG("iosapic_interrupt(): irq %d line %d eoi %p\n",
+		irq, vi->vi_irqline, vi->vi_eoi_addr);
 
 /* FIXME: Need to mask/unmask? processor IRQ is already masked... */
 	do_irq(&vi->vi_ios->isi_region->action[vi->vi_irqline], irq_num, regs);
@@ -668,12 +633,39 @@
 	struct vector_info *vi;
 	int isi_line;	/* line used by device */
 	int tmp;
+	int return_irq;
+#ifdef CONFIG_SUPERIO
+	int superio_irq = -1;
+#endif
 
 	if (NULL == isi) {
-		printk(KERN_WARNING MODULE_NAME ": 0x%p hpa not registered\n", isi->isi_hpa);
+		printk(KERN_WARNING MODULE_NAME ": hpa not registered for %s\n",
+			pcidev->name);
 		return(-1);
 	}
 
+#ifdef CONFIG_SUPERIO
+	if (is_superio_device(pcidev)) {
+		superio_irq = superio_fixup_irq(pcidev);
+		if (superio_irq == -1)
+		    return(-1);
+
+		if (PCI_FUNC(pcidev->devfn) != SUPERIO_USB_FN) {
+
+			/*
+			 * SuperIO USB controller has an irt entry.
+			 * Only let the USB controller hookup the rest
+			 * of the interrupt routing when it comes through.
+			 * Note that interrupts for all three functions
+			 * actually come through the PIC's on function 1!
+			 */
+
+			pcidev->irq = superio_irq;
+			return superio_irq;
+		}
+	}
+#endif /* CONFIG_SUPERIO */
+
 	/* lookup IRT entry for isi/slot/pin set */
 	irte = iosapic_xlate_pin(isi, pcidev);
 	if (NULL == irte) {
@@ -714,22 +706,31 @@
 	vi->vi_txn_data = txn_alloc_data(vi->vi_txn_irq, 8);
         ASSERT(vi->vi_txn_data < 256);  /* matches 8 above */
 
-	tmp = request_irq(vi->vi_txn_irq, iosapic_interrupt, 0, "iosapic", vi);
+	tmp = request_irq(vi->vi_txn_irq, iosapic_interrupt, 0,
+						vi->vi_name, vi);
 	ASSERT(tmp == 0);
 
-	vi->vi_eoi_addr = ((void *) isi->isi_hpa) + IOSAPIC_REG_EOI;
+	vi->vi_eoi_addr = (u32 *) (isi->isi_hpa + IOSAPIC_REG_EOI);
 	vi->vi_eoi_data = cpu_to_le32(vi->vi_irqline);
 
 	ASSERT(NULL != isi->isi_region);
-	/*
-	** pcidev->irq still needs to be virtualized.
-	*/
-	pcidev->irq = isi->isi_region->data.irqbase + isi_line;
+	/* pcidev->irq still needs to be virtualized.  */
+
+	return_irq = isi->isi_region->data.irqbase + isi_line;
 
-	DBG_IRT("iosapic_fixup_irq() %d:%d %x %x line %d irq %d\n", PCI_SLOT(pcidev->devfn),
-	PCI_FUNC(pcidev->devfn), pcidev->vendor, pcidev->device, isi_line, pcidev->irq);
+#ifdef CONFIG_SUPERIO
+	if (superio_irq != -1) {
+		superio_inform_irq(return_irq);
+		return_irq = superio_irq;
+	}
+#endif
+	pcidev->irq = return_irq;
+
+	DBG_IRT("iosapic_fixup_irq() %d:%d %x %x line %d irq %d\n",
+		PCI_SLOT(pcidev->devfn),
+	PCI_FUNC(pcidev->devfn), pcidev->vendor, pcidev->device, isi_line, return_irq);
 
-	return(pcidev->irq);
+	return return_irq;
 }
 
 
@@ -755,7 +756,7 @@
 	struct iosapic_info *isp = vi->vi_ios;
 
 	ASSERT(NULL != isp);
-	ASSERT(NULL != isp->isi_hpa);
+	ASSERT(0 != isp->isi_hpa);
 	DBG_IRT("iosapic_wr_irt_entry(): irq %d hpa %p WINDOW %p  0x%x 0x%x\n",
 		vi->vi_irqline,
 		isp->isi_hpa, isp->isi_hpa+IOSAPIC_REG_WINDOW,
@@ -807,16 +808,13 @@
 	** Extracting id_eid isn't a real clean way of getting it.
 	** But the encoding is the same for both PA and IA64 platforms.
 	*/
-#ifdef __LP64__
-	if (pdc_pat) {
+	if (is_pdc_pat()) {
 		/*
 		** PAT PDC just hands it to us "right".
 		** vi_txn_addr comes from cpu_data[x].txn_addr.
 		*/
 		*dp1 = (u32) (vi->vi_txn_addr);
-	} else
-#endif
-	{
+	} else {
 		/* 
 		** eg if base_addr == 0xfffa0000),
 		**    we want to get 0xa0ff0000.
@@ -886,7 +884,6 @@
 
 	/* data is initialized by fixup_irq */
 	ASSERT(0 < vi->vi_txn_irq);
-	ASSERT(0UL != vi->vi_txn_addr);
 	ASSERT(0UL != vi->vi_txn_data);
 
 	iosapic_set_irt_data(vi, &d0, &d1);
@@ -895,10 +892,10 @@
 
 #ifdef DEBUG_IOSAPIC_IRT
 {
-u32 *t = (u32 *) ((ulong) vi->vi_eoi_addr & ~0xffUL);
-printk("iosapic_enable_irq(): regs %p", vi->vi_eoi_addr);
-while (t < vi->vi_eoi_addr) printk(" %x", READ_U32(t++));
-printk("\n");
+	u32 *t = (u32 *) ((ulong) vi->vi_eoi_addr & ~0xffUL);
+	printk("iosapic_enable_irq(): regs %p", vi->vi_eoi_addr);
+	while (t < vi->vi_eoi_addr) printk(" %x", READ_U32(t++));
+	printk("\n");
 }
 
 printk("iosapic_enable_irq(): sel ");
@@ -943,10 +940,10 @@
 
 
 static struct irq_region_ops iosapic_irq_ops = {
-	iosapic_disable_irq,
-	iosapic_enable_irq,
-	iosapic_mask_irq,
-	iosapic_unmask_irq
+	disable_irq:	iosapic_disable_irq,
+	enable_irq:	iosapic_enable_irq,
+	mask_irq:	iosapic_mask_irq,
+	unmask_irq:	iosapic_unmask_irq
 };
 
 
@@ -967,15 +964,9 @@
 }
 
 
-#ifndef IOSAPIC_CALLBACK
-/*
-** iosapic_register() is the alternative to iosapic_driver_for().
-** (Only one or the other should be implemented.)
-*/
-
 /*
 ** iosapic_register() is called by "drivers" with an integrated I/O SAPIC.
-** Caller must be certain they have an I/O SAPIC and know it's MMIO address.
+** Caller must be certain they have an I/O SAPIC and know its MMIO address.
 **
 **	o allocate iosapic_info and add it to the list
 **	o read iosapic version and squirrel that away
@@ -984,7 +975,7 @@
 **	o allocate isi_region (registers region handlers)
 */
 void *
-iosapic_register(void *hpa)
+iosapic_register(unsigned long hpa)
 {
 	struct iosapic_info *isi = NULL;
 	struct irt_entry *irte = irt_cell;
@@ -1021,7 +1012,7 @@
 
 	memset(isi, 0, sizeof(struct iosapic_info));
 
-	isi->isi_hpa         = (unsigned char *) hpa;
+	isi->isi_hpa         = hpa;
 	isi->isi_version     = iosapic_rd_version(isi);
 	isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1;
 
@@ -1034,6 +1025,7 @@
 	}
 
 	memset(vip, 0, sizeof(struct vector_info) * isi->isi_num_vectors);
+	sprintf(isi->isi_name, "IO-SAPIC%02d", iosapic_count++);
 
 	/*
 	** Initialize vector array
@@ -1041,17 +1033,16 @@
 	for (cnt=0; cnt < isi->isi_num_vectors; cnt++, vip++) {
 		vip->vi_irqline = (unsigned char) cnt;
 		vip->vi_ios = isi;
+		sprintf(vip->vi_name, "%s-L%d", isi->isi_name, cnt);
 	}
 
 	isi->isi_region = alloc_irq_region(isi->isi_num_vectors,
-				&iosapic_irq_ops, IRQ_REG_DIS|IRQ_REG_MASK,
-				"I/O Sapic", (void *) isi->isi_vector);
+				&iosapic_irq_ops, isi->isi_name,
+				(void *) isi->isi_vector);
 
 	ASSERT(NULL != isi->isi_region);
 	return ((void *) isi);
 }
-#endif /* !IOSAPIC_CALLBACK */
-
 
 
 #ifdef DEBUG_IOSAPIC
@@ -1092,8 +1083,8 @@
 {
 	ASSERT(NULL != isi);
 	printk(KERN_DEBUG MODULE_NAME ": io_sapic_info at %p\n", isi);
-	printk(KERN_DEBUG "\t\tisi_hpa: %p\n", isi->isi_hpa);
-	printk(KERN_DEBUG "\t\tisi_satus:     %x\n", isi->isi_status);
+	printk(KERN_DEBUG "\t\tisi_hpa:       %lx\n", isi->isi_hpa);
+	printk(KERN_DEBUG "\t\tisi_status:     %x\n", isi->isi_status);
 	printk(KERN_DEBUG "\t\tisi_version:   %x\n", isi->isi_version);
 	printk(KERN_DEBUG "\t\tisi_vector:    %p\n", isi->isi_vector);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/iosapic_private.h linux-bk/arch/parisc/kernel/iosapic_private.h
--- linux-2.4.19/arch/parisc/kernel/iosapic_private.h	2000-12-05 20:29:39.000000000 +0000
+++ linux-bk/arch/parisc/kernel/iosapic_private.h	2002-08-17 00:49:00.000000000 +0000
@@ -111,22 +111,25 @@
 	struct irt_entry *vi_irte;      /* IRT entry */
 	u32	*vi_eoi_addr;	/* precalculate EOI reg address */
 	u32	vi_eoi_data;	/* IA64: ?       PA: swapped txn_data */
-	u8	vi_status;	/* status/flags */
-	u8	vi_irqline;	/* INTINn(IRQ) */
 	int	vi_txn_irq;	/* virtual IRQ number for processor */
 	ulong	vi_txn_addr;    /* IA64: id_eid  PA: partial HPA */
 	ulong	vi_txn_data;    /* IA64: vector  PA: EIR bit */
+	u8	vi_status;	/* status/flags */
+	u8	vi_irqline;	/* INTINn(IRQ) */
+	char	vi_name[32];    /* user visible identity */
 };
 
 
 struct iosapic_info {
 	struct iosapic_info  *isi_next;      /* list of I/O SAPIC          */
-	volatile void        *isi_hpa;       /* physical base address      */
+	unsigned long	     isi_hpa;	     /* physical base address */
 	struct irq_region    *isi_region;    /* each I/O SAPIC is one region */
 	struct vector_info   *isi_vector;    /* IRdT (IRQ line) array  */
 	int                  isi_num_vectors; /* size of IRdT array */
 	int                  isi_status;     /* status/flags               */
 	unsigned int         isi_version;    /* DEBUG: data fr version reg */
+	/* round up to next cacheline */
+	char                 isi_name[20]; /* identify region for users */
 };
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/irq.c linux-bk/arch/parisc/kernel/irq.c
--- linux-2.4.19/arch/parisc/kernel/irq.c	2001-02-09 19:29:44.000000000 +0000
+++ linux-bk/arch/parisc/kernel/irq.c	2002-08-17 00:49:03.000000000 +0000
@@ -1,13 +1,10 @@
-/* $Id: irq.c,v 1.8 2000/02/08 02:01:17 grundler Exp $
- *
+/* 
  * Code to handle x86 style IRQs plus some generic interrupt stuff.
  *
- * This is not in any way SMP-clean.
- *
  * Copyright (C) 1992 Linus Torvalds
  * Copyright (C) 1994, 1995, 1996, 1997, 1998 Ralf Baechle
- * Copyright (C) 1999 SuSE GmbH (Author: Philipp Rumpf, prumpf@tux.org)
- * Copyright (C) 2000 Hewlett Packard Corp (Co-Author: Grant Grundler, grundler@cup.hp.com)
+ * Copyright (C) 1999 SuSE GmbH (Philipp Rumpf, prumpf@tux.org)
+ * Copyright (C) 1999-2000 Grant Grundler
  *
  *    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
@@ -23,138 +20,167 @@
  *    along with this program; if not, write to the Free Software
  *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-#include <linux/config.h>
 #include <linux/bitops.h>
 #include <asm/bitops.h>
+#include <linux/config.h>
 #include <asm/pdc.h>
 #include <linux/errno.h>
 #include <linux/init.h>
-#include <linux/kernel_stat.h>
 #include <linux/signal.h>
-#include <linux/sched.h>
 #include <linux/types.h>
 #include <linux/ioport.h>
 #include <linux/timex.h>
 #include <linux/slab.h>
 #include <linux/random.h>
+#include <linux/sched.h>
 #include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
 #include <linux/irq.h>
+#include <linux/spinlock.h>
 
 #include <asm/cache.h>
 
 #undef DEBUG_IRQ
+#undef PARISC_IRQ_CR16_COUNTS
 
 extern void timer_interrupt(int, void *, struct pt_regs *);
 extern void ipi_interrupt(int, void *, struct pt_regs *);
 
 #ifdef DEBUG_IRQ
-#define DBG_IRQ(x...)   printk(x)
+#define DBG_IRQ(irq, x)	if ((irq) != TIMER_IRQ) printk x
 #else /* DEBUG_IRQ */
-#define DBG_IRQ(x...)
+#define DBG_IRQ(irq, x)	do { } while (0)
 #endif /* DEBUG_IRQ */
 
-#define EIEM_MASK(irq) (1L<<(MAX_CPU_IRQ-IRQ_OFFSET(irq)))
-#define CLEAR_EIEM_BIT(irq) set_eiem(get_eiem() & ~EIEM_MASK(irq))
-#define SET_EIEM_BIT(irq) set_eiem(get_eiem() | EIEM_MASK(irq))
+#define EIEM_MASK(irq)       (1UL<<(MAX_CPU_IRQ-IRQ_OFFSET(irq)))
+
+/* Bits in EIEM correlate with cpu_irq_action[].
+** Numbered *Big Endian*! (ie bit 0 is MSB)
+*/
+static unsigned long cpu_eiem = 0;
+
+static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED;  /* protect IRQ regions */
+
+#ifdef CONFIG_SMP
+static void cpu_set_eiem(void *info)
+{
+	set_eiem((unsigned long) info);
+}
+#endif
 
-static void disable_cpu_irq(void *unused, int irq)
+static inline void disable_cpu_irq(void *unused, int irq)
 {
-	CLEAR_EIEM_BIT(irq);
+	unsigned long eirr_bit = EIEM_MASK(irq);
+
+	cpu_eiem &= ~eirr_bit;
+	set_eiem(cpu_eiem);
+        smp_call_function(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
 }
 
 static void enable_cpu_irq(void *unused, int irq)
 {
-	unsigned long mask = EIEM_MASK(irq);
+	unsigned long eirr_bit = EIEM_MASK(irq);
+
+	mtctl(eirr_bit, 23);	/* clear EIRR bit before unmasking */
+	cpu_eiem |= eirr_bit        smp_call_function(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
 }
 the performcpu_eiem |= eirr_b;
+			, &uversion->desc))
+		return 
 the pe+	mm_ performcpu_e)
 {
-	uns( */
+	cpu_eiem	mm_ performcpu_em_ performcpu_em_ performcpuIRdT (IRQ line 0HV
+			 * of RAX_RS485) PDC_OK