diff -Nru a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
--- a/Documentation/DocBook/Makefile	Mon Nov  4 14:31:01 2002
+++ b/Documentation/DocBook/Makefile	Mon Nov  4 14:31:01 2002
@@ -160,8 +160,6 @@
 	$(patsubst %.fig,%.png, $(IMG-parportbook)) \
 	$(C-procfs-example)
 
-ifneq ($(wildcard $(BOOKS)),)
-clean-rule := rm -rf $(wildcard $(BOOKS))
+ifneq ($(wildcard $(patsubst %.html,%,$(HTML))),)
+clean-rule := rm -rf $(wildcard $(patsubst %.html,%,$(HTML)))
 endif
-
-include $(TOPDIR)/Rules.make
diff -Nru a/Documentation/filesystems/driverfs.txt b/Documentation/filesystems/driverfs.txt
--- a/Documentation/filesystems/driverfs.txt	Mon Nov  4 14:31:02 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,336 +0,0 @@
-
-driverfs - The Device Driver Filesystem
-
-Patrick Mochel	<mochel@osdl.org>
-
-2 August 2002
-
-
-What it is:
-~~~~~~~~~~~
-driverfs is a ram-based filesystem. It was created by copying
-ramfs/inode.c to driverfs/inode.c and doing a little search-and-replace. 
-
-driverfs is a means to export kernel data structures, their
-attributes, and the linkages between them to userspace. 
-
-driverfs provides a unified interface for exporting attributes to
-userspace. Currently, this interface is available only to device and
-bus drivers. 
-
-
-Using driverfs
-~~~~~~~~~~~~~~
-driverfs is always compiled in. You can access it by doing something like:
-
-    mount -t driverfs driverfs /devices 
-
-
-Top Level Directory Layout
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-The driverfs directory arrangement exposes the relationship of kernel
-data structures. 
-
-The top level driverfs diretory looks like:
-
-bus/
-root/
-
-root/ contains a filesystem representation of the device tree. It maps
-directly to the internal kernel device tree, which is a hierarchy of
-struct device. 
-
-bus/ contains flat directory layout of the various bus types in the
-kernel. Each bus's directory contains two subdirectories:
-
-	devices/
-	drivers/
-
-devices/ contains symlinks for each device discovered in the system
-that point to the device's directory under root/.
-
-drivers/ contains a directory for each device driver that is loaded
-for devices on that particular bus (this assmumes that drivers do not
-span multiple bus types).
-
-
-More information can device-model specific features can be found in
-Documentation/device-model/. 
-
-
-Directory Contents
-~~~~~~~~~~~~~~~~~~
-Each object that is represented in driverfs gets a directory, rather
-than a file, to make it simple to export attributes of that object. 
-Attributes are exported via ASCII text files. The programming
-interface is discussed below. 
-
-Instead of having monolithic files that are difficult to parse, all
-files are intended to export one attribute. The name of the attribute
-is the name of the file. The value of the attribute are the contents
-of the file. 
-
-There should be few, if any, exceptions to this rule. You should not
-violate it, for fear of public humilation.
-
-
-The Two-Tier Model
-~~~~~~~~~~~~~~~~~~
-
-driverfs is a very simple, low-level interface. In order for kernel
-objects to use it, there must be an intermediate layer in place for
-each object type. 
-
-All calls in driverfs are intended to be as type-safe as possible. 
-In order to extend driverfs to support multiple data types, a layer of
-abstraction was required. This intermediate layer converts between the
-generic calls and data structures of the driverfs core to the
-subsystem-specific objects and calls. 
-
-
-The Subsystem Interface
-~~~~~~~~~~~~~~~~~~~~~~~
-
-The subsystems bear the responsibility of implementing driverfs
-extensions for the objects they control. Fortunately, it's intended to
-be really easy to do so. 
-
-It's divided into three sections: directories, files, and operations.
-
-
-Directories
-~~~~~~~~~~~
-
-struct driver_dir_entry {
-        char                    * name;
-        struct dentry           * dentry;
-        mode_t                  mode;
-        struct driverfs_ops     * ops;
-};
-
-
-int
-driverfs_create_dir(struct driver_dir_entry *, struct driver_dir_entry *);
-
-void
-driverfs_remove_dir(struct driver_dir_entry * entry);
-
-The directory structure should be statically allocated, and reside in
-a subsystem-specific data structure:
-
-struct device {
-       ...
-       struct driver_dir_entry	dir;
-};
-
-The subsystem is responsible for initializing the name, mode, and ops
-fields of the directory entry. (More on struct driverfs_ops later)
-
-
-Files
-~~~~~
-
-struct attribute {
-        char                    * name;
-        mode_t                  mode;
-};
-
-
-int
-driverfs_create_file(struct attribute * attr, struct driver_dir_entry * parent);
-
-void
-driverfs_remove_file(struct driver_dir_entry *, const char * name);
-
-
-The attribute structure is a simple, common token that the driverfs
-core handles. It has little use on its own outside of the
-core. Objects cannot use a plain struct attribute to export
-attributes, since there are no callbacks for reading and writing data.
-
-Therefore, the subsystem is required to define a data structure that
-encapsulates the attribute structure, and provides type-safe callbacks
-for reading and writing data.
-
-An example looks like this:
-
-struct device_attribute {
-        struct attribute        attr;
-        ssize_t (*show)(struct device * dev, char * buf, size_t count, loff_t off);
-        ssize_t (*store)(struct device * dev, const char * buf, size_t count, loff_t off);
-};
-
-
-Note that there is a struct attribute embedded in the structure. In
-order to relieve pain in declaring attributes, the subsystem should
-also define a macro, like:
-
-#define DEVICE_ATTR(_name,_mode,_show,_store)      \
-struct device_attribute dev_attr_##_name = {            \
-        .attr = {.name  = __stringify(_name) , .mode   = _mode },      \
-        .show   = _show,                                \
-        .store  = _store,                               \
-};
-
-This hides the initialization of the embedded struct, and in general,
-the internals of each structure. It yields a structure by the name of
-dev_attr_<name>.
-
-In order for objects to create files, the subsystem should create
-wrapper functions, like this:
-
-int device_create_file(struct device *device, struct device_attribute * entry);
-void device_remove_file(struct device * dev, struct device_attribute * attr);
-
-..and forward the call on to the driverfs functions.
-
-Note that there is no unique information in the attribute structures,
-so the same structure can be used to describe files of several
-different object instances. 
-
-
-Operations
-~~~~~~~~~~
-
-struct driverfs_ops {
-        int     (*open)(struct driver_dir_entry *);
-        int     (*close)(struct driver_dir_entry *);
-        ssize_t (*show)(struct driver_dir_entry *, struct attribute *,char *, size_t, loff_t);
-        ssize_t (*store)(struct driver_dir_entry *,struct attribute *,const char *, size_t, loff_t);
-};
-
-
-Subsystems are required to implement this set of callbacks. Their
-purpose is to translate the generic data structures into the specific
-objects, and operate on them. This can be done by defining macros like
-this:
-
-#define to_dev_attr(_attr) container_of(_attr,struct device_attribute,attr)
-
-#define to_device(d) container_of(d, struct device, dir)
-
-
-Since the directories are statically allocated in the object, you can
-derive the pointer to the object that owns the file. Ditto for the
-attribute structures. 
-
-Current Interfaces
-~~~~~~~~~~~~~~~~~~
-
-The following interface layers currently exist in driverfs:
-
-
-- devices (include/linux/device.h)
-----------------------------------
-Structure:
-
-struct device_attribute {
-        struct attribute        attr;
-        ssize_t (*show)(struct device * dev, char * buf, size_t count, loff_t off);
-        ssize_t (*store)(struct device * dev, const char * buf, size_t count, loff_t off);
-};
-
-Declaring:
-
-DEVICE_ATTR(_name,_str,_mode,_show,_store);
-
-Creation/Removal:
-
-int device_create_file(struct device *device, struct device_attribute * entry);
-void device_remove_file(struct device * dev, struct device_attribute * attr);
-
-
-- bus drivers (include/linux/device.h)
---------------------------------------
-Structure:
-
-struct bus_attribute {
-        struct attribute        attr;
-        ssize_t (*show)(struct bus_type *, char * buf, size_t count, loff_t off);
-        ssize_t (*store)(struct bus_type *, const char * buf, size_t count, loff_t off);
-};
-
-Declaring:
-
-BUS_ATTR(_name,_mode,_show,_store)
-
-Creation/Removal:
-
-int bus_create_file(struct bus_type *, struct bus_attribute *);
-void bus_remove_file(struct bus_type *, struct bus_attribute *);
-
-
-- device drivers (include/linux/device.h)
------------------------------------------
-
-Structure:
-
-struct driver_attribute {
-        struct attribute        attr;
-        ssize_t (*show)(struct device_driver *, char * buf, size_t count, loff_t off);
-        ssize_t (*store)(struct device_driver *, const char * buf, size_t count, loff_t off);
-};
-
-Declaring:
-
-DRIVER_ATTR(_name,_mode,_show,_store)
-
-Creation/Removal:
-
-int driver_create_file(struct device_driver *, struct driver_attribute *);
-void driver_remove_file(struct device_driver *, struct driver_attribute *);
-
-
-Reading/Writing Data
-~~~~~~~~~~~~~~~~~~~~
-The callback functionality is similar to the way procfs works. When a
-user performs a read(2) or write(2) on the file, it first calls a
-driverfs function. This calls to the subsystem, which then calls to
-the object's show() or store() function.
-
-The buffer pointer, offset, and length should be passed to each
-function. The downstream callback should fill the buffer and return
-the number of bytes read/written.
-
-
-What driverfs is not:
-~~~~~~~~~~~~~~~~~~~~~
-It is not a replacement for either devfs or procfs.
-
-It does not handle device nodes, like devfs is intended to do. I think
-this functionality is possible, but indeed think that integration of
-the device nodes and control files should be done. Whether driverfs or
-devfs, or something else, is the place to do it, I don't know.
-
-It is not intended to be a replacement for all of the procfs
-functionality. I think that many of the driver files should be moved
-out of /proc (and maybe a few other things as well ;).
-
-
-
-Limitations:
-~~~~~~~~~~~~
-The driverfs functions assume that at most a page is being either read
-or written each time.
-
-There is a race condition that is really, really hard to fix; if not 
-impossible. There exists a race between a driverfs file being opened
-and the object that owns the file going away. During the driverfs
-open() callback, the reference count for the owning object needs to be
-incremented. 
-
-For drivers, we can put a struct module * owner in struct driver_dir_entry 
-and do try_inc_mod_count() when we open a file. However, this won't
-work for devices, that aren't tied to a module. And, it is still not
-guaranteed to solve the race. 
-
-I'm looking into fixing this, but it may not be doable without making
-a separate filesystem instance for each object. It's fun stuff. Please
-mail me with creative ideas that you know will work. 
-
-
-Possible bugs:
-~~~~~~~~~~~~~~
-It may not deal with offsets and/or seeks very well, especially if
-they cross a page boundary.
-
diff -Nru a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
--- a/Documentation/filesystems/proc.txt	Mon Nov  4 14:31:01 2002
+++ b/Documentation/filesystems/proc.txt	Mon Nov  4 14:31:01 2002
@@ -130,6 +130,7 @@
  stat    Process status                                 
  statm   Process memory status information              
  status  Process status in human readable form          
+ wchan   If CONFIG_KALLSYMS is set, a pre-decoded wchan
 ..............................................................................
 
 For example, to get the status information of a process, all you have to do is
diff -Nru a/Documentation/video4linux/bttv/CARDLIST b/Documentation/video4linux/bttv/CARDLIST
--- a/Documentation/video4linux/bttv/CARDLIST	Mon Nov  4 14:31:00 2002
+++ b/Documentation/video4linux/bttv/CARDLIST	Mon Nov  4 14:31:00 2002
@@ -2,13 +2,13 @@
   card=0 -  *** UNKNOWN/GENERIC *** 
   card=1 - MIRO PCTV
   card=2 - Hauppauge (bt848)
-  card=3 - STB
+  card=3 - STB, Gateway P/N 6000699 (bt848)
   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 - Lifeview FlyVideo II (Bt848) LR26
-  card=9 - IXMicro TurboTV
+  card=9 - IMS/IXmicro TurboTV
   card=10 - Hauppauge (bt878)
   card=11 - MIRO PCTV pro
   card=12 - ADS Technologies Channel Surfer TV (bt848)
@@ -24,22 +24,22 @@
   card=22 - Askey CPH050/ Phoebe Tv Master + FM
   card=23 - Modular Technology MM205 PCTV, bt878
   card=24 - Askey CPH05X/06X (bt878) [many vendors]
-  card=25 - Terratec Terra TV+ Version 1.0 (Bt848)/Vobis TV-Boostar
+  card=25 - Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar
   card=26 - Hauppauge WinCam newer (bt878)
   card=27 - Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50
-  card=28 - Terratec TerraTV+
+  card=28 - Terratec TerraTV+ Version 1.1 (bt878)
   card=29 - Imagenation PXC200
   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=33 - Terratec TerraTValue Version Bt878
+  card=34 - Leadtek WinFast 2000/ WinFast 2000 XP
   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=40 - STB TV PCI FM, Gateway P/N 6000704 (bt878)
   card=41 - AVerMedia TVPhone 98
   card=42 - ProVideo PV951
   card=43 - Little OnAir TV
@@ -78,14 +78,17 @@
   card=76 - Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)
   card=77 - GrandTec Multi Capture Card (Bt878)
   card=78 - Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF
+  card=79 - DSP Design TCVIDEO
+  card=80 - Hauppauge WinTV PVR
+  card=81 - GV-BCTV5/PCI
 
 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 +106,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 +121,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 -Nru a/Documentation/video4linux/bttv/Cards b/Documentation/video4linux/bttv/Cards
--- a/Documentation/video4linux/bttv/Cards	Mon Nov  4 14:31:01 2002
+++ b/Documentation/video4linux/bttv/Cards	Mon Nov  4 14:31:01 2002
@@ -157,6 +157,7 @@
 		   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)
@@ -236,6 +237,7 @@
    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)
@@ -273,6 +275,7 @@
    WinView 601 (Bt848)
    WinView 610 (Zoran)
    WinFast2000
+   WinFast2000 XP
 
 KNC One
 -------
@@ -282,15 +285,19 @@
    TV-Station FM (+Radio)
    TV-Station RDS (+RDS)
 
-Provideo PV951 
---------------
-  These are sold as:
+   newer Cards have saa7134, but model name stayed the same?
+
+Provideo 
+--------
+  PV951 or PV-951 (also are sold as:
    Boeder TV-FM Video Capture Card
    Titanmedia Supervision TV-2400
    Provideo PV951 TF
    3DeMon PV951
    MediaForte TV-Vision PV951
    Yoko PV951
+  )
+  PV-148 (capture only)
 
 Highscreen
 ----------
@@ -320,15 +327,47 @@
 
    PCB      PCI-ID      Model-Name      Eeprom  Tuner  Sound    Country
    --------------------------------------------------------------------
-   M1A8-A      --       AVer TV-Phone           FM1216  --
+   M101.C   ISA !
+   M108-B      Bt848                     --     FR1236		 US   (2),(3)
+   M1A8-A      Bt848    AVer TV-Phone           FM1216  --
    M168-T   1461:0003   AVerTV Studio   48:17   FM1216 TDA9840T  D    (1) w/FM w/Remote
    M168-U   1461:0004   TVCapture98     40:11   FI1216   --      D    w/Remote
    M168II-B 1461:0003   Medion MD9592   48:16   FM1216 TDA9873H  D    w/FM
 
    (1) Daughterboard MB68-A with TDA9820T and TDA9840T
+   (2) Sony NE41S soldered (stereo sound?)
+   (3) Daughterboard M118-A w/ pic 16c54 and 4 MHz quartz
+ 
+   US site has different drivers for (as of 09/2002):
+   EZ Capture/InterCam PCI (BT-848 chip)
+   EZ Capture/InterCam PCI (BT-878 chip)
+   TV-Phone (BT-848 chip)
+   TV98 (BT-848 chip)
+   TV98 With Remote (BT-848 chip)
+   TV98 (BT-878 chip)
+   TV98 With Remote (BT-878)
+   TV/FM98 (BT-878 chip)
+   AVerTV
+   AverTV Stereo
+   AVerTV Studio
+
+   DE hat diverse Treiber fuer diese Modelle (Stand 09/2002):
+   TVPhone (848) mit Philips tuner FR12X6 (w/ FM radio)
+   TVPhone (848) mit Philips tuner FM12X6 (w/ FM radio)
+   TVCapture (848) w/Philips tuner FI12X6
+   TVCapture (848) non-Philips tuner
+   TVCapture98 (Bt878)
+   TVPhone98 (Bt878)
+   AVerTV und TVCapture98 w/VCR (Bt 878)
+   AVerTVStudio und TVPhone98 w/VCR (Bt878)
+   AVerTV GO Serie (Kein SVideo Input)
+   AVerTV98 (BT-878 chip)
+   AVerTV98 mit Fernbedienung (BT-878 chip)
+   AVerTV/FM98 (BT-878 chip)
 
 Aimslab
 -------
+   Video Highway or "Video Highway TR200" (ISA)
    Video Highway Xtreme (aka "VHX") (Bt848, FM w/ TEA5757)
 
 IXMicro (former: IMS=Integrated Micro Solutions)
@@ -364,6 +403,9 @@
 
    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
+   Cinergy 600 (saa7134)
+
 Technisat
 ---------
    Discos ADR PC-Karte ISA (no TV!)
@@ -373,7 +415,7 @@
    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 1 DVB  (AV7110) = Technotrend Premium
    SkyStar 2 DVB  (B2C2) (=Sky2PC)
 
 Siemens
@@ -387,6 +429,9 @@
 Powercolor
 ----------
    MTV878
+       Package comes with different contents:
+       a) pcb "MTV878" (CARD=75)
+       b) Pixelview Rev. 4_
    MTV878R w/Remote Control
    MTV878F w/Remote Control w/FM radio
 
@@ -394,10 +439,14 @@
 --------
    Mirovideo PCTV (Bt848)
    Mirovideo PCTV SE (Bt848)
-   Mirovideo PCTV Pro (Bt848 + Daughterboard)
+   Mirovideo PCTV Pro (Bt848 + Daughterboard for TV Stereo and FM)
+   Studio PCTV Rave (Bt848 Version = Mirovideo PCTV)
    Studio PCTV Rave (Bt878 package w/o infrared)
    Studio PCTV      (Bt878)
    Studio PCTV Pro  (Bt878 stereo w/ FM)
+   Pinnacle PCTV    (Bt878, MT2032)
+   Pinnacle PCTV Pro (Bt878, MT2032)
+   Pinncale PCTV Sat
 
    M(J)PEG capture and playback:
    DC1+ (ISA)
@@ -495,8 +544,10 @@
 
 STB
 ---
-   TV PCI (Temic4032FY5, tda9850??)
-   other variants?
+   STB bt878 == Gateway 6000704 
+   STB Gateway 6000699 (bt848)
+   STB Gateway 6000402 (bt848)
+   STB TV130 PCI
 
 Videologic
 ----------
@@ -507,6 +558,16 @@
 ------------
    TT-SAT PCI (PCB "Sat-PCI Rev.:1.3.1"; zr36125, vpx3225d, stc0056a, Tuner:BSKE6-155A
    TT-DVB-Sat
+    This card is sold as OEM from:
+	Siemens DVB-s Card
+	Hauppauge WinTV DVB-S
+	Technisat SkyStar 1 DVB
+	Galaxis DVB Sat
+    Now this card is called TT-PCline Premium Family
+   TT-Budget
+    This card is sold as OEM from:
+	Hauppauge WinTV Nova
+	Satelco Standard PCI (DVB-S)
    TT-DVB-C PCI
 
 Teles
@@ -546,10 +607,13 @@
 Hauppauge
 ---------
    many many WinTV models ...
-   WinTV DVBs
-   WinTV NOVA
+   WinTV DVBs = Tehcnotrend Premium
+   WinTV NOVA = Technotrend Budget
    WinTV NOVA-CI
    WinTV-Nexus-s
+   WinTV PVR
+   WinTV PVR 250
+   WinTV PVR 450
 
 Matrix-Vision
 -------------
@@ -615,7 +679,7 @@
 
 NoBrand
 -------
-   TV Excel = Australian Name for "PV-BT878P+ 8E" or so
+   TV Excel = Australian Name for "PV-BT878P+ 8E" or "878TV Rev.3_"
 
 Mach www.machspeed.com
 ----
@@ -638,9 +702,51 @@
 Satelco
 -------
    TV-FM =KNC1 saa7134
+   Standard PCI (DVB-S) = Technotrend Budget
+   Standard PCI (DVB-S) w/ CI
+   Satelco Hoghend PCI (DVB-S) = Technotrend Premium
+
 
 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]
+
+AITech
+------
+   AITech WaveWatcher TV-PCI = LR26
+   WaveWatcher TVR-202 TV/FM Radio Card (ISA)
+
+MAXRON
+------
+   Maxron MaxTV/FM Radio (KW-TV878-FNT) = Kworld or JW-TV878-FBK
+
+www.ids-imaging.de
+------------------
+   Falcon Series (capture only)
+ In USA: http://www.theimagingsource.com/
+   DFG/LC1	
+
+www.sknet-web.co.jp
+-------------------
+   SKnet Monster TV (saa7134)
+
+A-Max www.amaxhk.com (Colormax, Amax, Napa)
+-------------------
+   APAC Viewcomp 878
+
+Cybertainment
+-------------
+   CyberMail AV Video Email Kit w/ PCI Capture Card (capture only)
+   CyberMail Xtreme
+  These are Flyvideo
diff -Nru a/Documentation/video4linux/bttv/README b/Documentation/video4linux/bttv/README
--- a/Documentation/video4linux/bttv/README	Mon Nov  4 14:31:00 2002
+++ b/Documentation/video4linux/bttv/README	Mon Nov  4 14:31:00 2002
@@ -76,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 -Nru a/Documentation/video4linux/bttv/README.freeze b/Documentation/video4linux/bttv/README.freeze
--- a/Documentation/video4linux/bttv/README.freeze	Mon Nov  4 14:31:00 2002
+++ b/Documentation/video4linux/bttv/README.freeze	Mon Nov  4 14:31:00 2002
@@ -61,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
diff -Nru a/Documentation/video4linux/bttv/Tuners b/Documentation/video4linux/bttv/Tuners
--- a/Documentation/video4linux/bttv/Tuners	Mon Nov  4 14:31:00 2002
+++ b/Documentation/video4linux/bttv/Tuners	Mon Nov  4 14:31:00 2002
@@ -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]
@@ -24,6 +37,8 @@
  [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]6{MF|ME|MP}
   F[IRMQ]:
@@ -39,15 +54,17 @@
    1246: PAL I
    1256: Pal DK
   {MF|ME|MP}
-   MF: w/ Secam
+   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
@@ -62,6 +79,7 @@
     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)
@@ -78,12 +96,6 @@
   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
@@ -93,3 +105,11 @@
 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 -Nru a/MAINTAINERS b/MAINTAINERS
--- a/MAINTAINERS	Mon Nov  4 14:31:02 2002
+++ b/MAINTAINERS	Mon Nov  4 14:31:02 2002
@@ -444,6 +444,13 @@
 W:	http://www.debian.org/~dz/i8k/
 S:	Maintained
 
+DEVICE-MAPPER
+P:	Joe Thornber
+M:	dm@uk.sistina.com
+L:	linux-lvm@sistina.com
+W:	http://www.sistina.com/lvm
+S:	Maintained
+
 DEVICE NUMBER REGISTRY
 P:	H. Peter Anvin
 M:	hpa@zytor.com
@@ -457,23 +464,24 @@
 S:	Maintained
 
 DIGI INTL. EPCA DRIVER
-P:	Chad Schwartz
-M:	support@dgii.com
-L:	digilnux@dgii.com
+P:	Digi International, Inc
+M:	Eng.Linux@digi.com
+L:	Eng.Linux@digi.com
+W:	http://www.digi.com
 S:	Maintained
 
 DIGI RIGHTSWITCH NETWORK DRIVER
 P:	Rick Richardson
 L:	linux-net@vger.kernel.org
-W:	http://www.dgii.com/linux/
-S:	Maintained
+W:	http://www.digi.com
+S:	Orphaned
 
 DIGIBOARD PC/XE AND PC/XI DRIVER
 P:	Christoph Lameter
 M:	christoph@lameter.com
-W:	http://www.dgii.com/linux,http://lameter.com/digi
+W:	http://www.digi.com
 L:	digilnux@dgii.com
-S:	Maintained
+S:	Orphaned
 
 DIRECTORY NOTIFICATION
 P:	Stephen Rothwell
@@ -852,9 +860,8 @@
 S:	Maintained
 
 IRDA SUBSYSTEM
-P:	Dag Brattli
-M:	Dag Brattli <dag@brattli.net>
-L:	linux-irda@pasta.cs.uit.no
+P:	Jean Tourrilhes
+L:	irda-users@lists.sourceforge.net
 W:	http://irda.sourceforge.net/
 S:	Maintained
 
@@ -958,6 +965,12 @@
 W:	http://www.ibm.com/linux/ltc/projects/ppc
 S:	Supported
 
+LINUX FOR NCR VOYAGER
+P:	James Bottomley
+M:	James.Bottomley@HansenPartnership.com
+W:	http://www.hansenpartnership.com/voyager
+S:	Maintained
+
 LINUX FOR POWERPC
 P:	Paul Mackerras
 M:	paulus@samba.org
@@ -1571,6 +1584,13 @@
 W:	http://www.rr.iij4u.or.jp/~kkojima/linux-sh4.html
 S:	Maintained
 
+SUN3/3X
+P:	Sam Creasey
+M:	sammy@sammy.net
+L:	sun3-list@redhat.com
+W:	http://sammy.net/sun3/
+S:	Maintained
+
 SVGA HANDLING
 P:	Martin Mares
 M:	mj@ucw.cz
@@ -1895,6 +1915,24 @@
 P:	Jeff Garzik
 L:	linux-via@gtf.org
 S:	Odd fixes
+
+UCLINUX
+P:	Greg Ungerer
+M:	gerg@snapgear.com
+P:	David McCullough
+M:	davidm@snapgear.com
+P:	D. Jeff Dionne (created first uClinux port)
+M:	jeff@uclinux.org
+W:	http://www.uclinux.org/
+L:	uclinux-dev@uclinux.org
+S:	Maintained
+
+UCLINUX FOR NEC V850
+P:	Miles Bader
+M:	uclinux-v850@lsi.nec.co.jp
+W:	http://www.ic.nec.co.jp/micro/uclinux/eng/
+W:	http://www.ee.nec.de/uclinux/
+S:	Supported
 
 USB DIAMOND RIO500 DRIVER
 P:	Cesar Miquel
diff -Nru a/Makefile b/Makefile
--- a/Makefile	Mon Nov  4 14:31:00 2002
+++ b/Makefile	Mon Nov  4 14:31:00 2002
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 5
-SUBLEVEL = 45
+SUBLEVEL = 46
 EXTRAVERSION =
 
 # *DOCUMENTATION*
@@ -155,6 +155,7 @@
 STRIP		= $(CROSS_COMPILE)strip
 OBJCOPY		= $(CROSS_COMPILE)objcopy
 OBJDUMP		= $(CROSS_COMPILE)objdump
+AWK		= awk
 GENKSYMS	= /sbin/genksyms
 DEPMOD		= /sbin/depmod
 KALLSYMS	= /sbin/kallsyms
@@ -173,7 +174,7 @@
 
 export	VERSION PATCHLEVEL SUBLEVEL EXTRAVERSION KERNELRELEASE ARCH \
 	CONFIG_SHELL TOPDIR HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC \
-	CPP AR NM STRIP OBJCOPY OBJDUMP MAKE GENKSYMS PERL UTS_MACHINE \
+	CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE \
 	HOSTCXX HOSTCXXFLAGS
 
 export CPPFLAGS NOSTDINC_FLAGS OBJCOPYFLAGS LDFLAGS
@@ -209,12 +210,12 @@
 drivers-y	:= drivers/ sound/
 net-y		:= net/
 libs-y		:= lib/
-core-y		:=
+core-y		:= usr/
 SUBDIRS		:=
 
 ifeq ($(filter $(noconfig_targets),$(MAKECMDGOALS)),)
 
-export include-config := 1
+export include_config := 1
 
 -include .config
 
@@ -228,9 +229,10 @@
 		     $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
 		     $(net-y) $(net-m) $(libs-y) $(libs-m)))
 
-ALL_SUBDIRS     := $(SUBDIRS) $(patsubst %/,%,$(filter %/, $(init-n) $(init-) \
+ALL_SUBDIRS     := $(sort $(SUBDIRS) $(patsubst %/,%,$(filter %/, \
+		     $(init-n) $(init-) \
 		     $(core-n) $(core-) $(drivers-n) $(drivers-) \
-		     $(net-n) $(net-) $(libs-n) $(libs-)))
+		     $(net-n)  $(net-)  $(libs-n)    $(libs-))))
 
 init-y		:= $(patsubst %/, %/built-in.o, $(init-y))
 core-y		:= $(patsubst %/, %/built-in.o, $(core-y))
@@ -238,7 +240,7 @@
 net-y		:= $(patsubst %/, %/built-in.o, $(net-y))
 libs-y		:= $(patsubst %/, %/lib.a, $(libs-y))
 
-ifdef include-config
+ifdef include_config
 
 # Here goes the main Makefile
 # ===========================================================================
@@ -602,7 +604,7 @@
 	rpm -ta $(TOPDIR)/../$(KERNELPATH).tar.gz ; \
 	rm $(TOPDIR)/../$(KERNELPATH).tar.gz
 
-else # ifdef include-config
+else # ifdef include_config
 
 ifeq ($(filter-out $(noconfig_targets),$(MAKECMDGOALS)),)
 
@@ -764,8 +766,7 @@
 help:
 	@echo  'Cleaning targets:'
 	@echo  '  clean		- remove most generated files but keep the config'
-	@echo  '  mrproper	- remove all generated files including the config'
-	@echo  '  distclean	- mrproper + remove files generated by editors and patch'
+	@echo  '  mrproper	- remove all generated files + config + various backup files'
 	@echo  ''
 	@echo  'Configuration targets:'
 	@echo  '  oldconfig	- Update current config utilising a line-oriented program'
@@ -798,7 +799,7 @@
 # Documentation targets
 # ---------------------------------------------------------------------------
 sgmldocs psdocs pdfdocs htmldocs: scripts
-	$(Q)$(MAKE) -f Documentation/DocBook/Makefile $@
+	$(Q)$(MAKE) -f scripts/Makefile.build obj=Documentation/DocBook $@
 
 # Scripts to check various things for consistency
 # ---------------------------------------------------------------------------
@@ -828,7 +829,7 @@
 	$(MAKE) $@
 
 endif # ifeq ($(filter-out $(noconfig_targets),$(MAKECMDGOALS)),)
-endif # ifdef include-config
+endif # ifdef include_config
 
 # FIXME Should go into a make.lib or something 
 # ===========================================================================
diff -Nru a/arch/alpha/Kconfig b/arch/alpha/Kconfig
--- a/arch/alpha/Kconfig	Mon Nov  4 14:31:02 2002
+++ b/arch/alpha/Kconfig	Mon Nov  4 14:31:02 2002
@@ -12,6 +12,14 @@
 	  port. The Alpha Linux project has a home page at
 	  <http://www.alphalinux.org/>.
 
+config MMU
+	bool
+	default y
+
+config SWAP
+	bool
+	default y
+
 config UID16
 	bool
 
@@ -521,6 +529,9 @@
 	  much vmalloc space as is available.
 
 	  Say N unless you know you need gobs and gobs of vmalloc space.
+
+config VERBOSE_MCHECK
+	bool "Verbose Machine Checks"
 
 source "drivers/pci/Kconfig"
 
diff -Nru a/arch/alpha/Makefile b/arch/alpha/Makefile
--- a/arch/alpha/Makefile	Mon Nov  4 14:31:02 2002
+++ b/arch/alpha/Makefile	Mon Nov  4 14:31:02 2002
@@ -12,6 +12,7 @@
 
 LDFLAGS_vmlinux = -static -N #-relax
 CFLAGS := $(CFLAGS) -pipe -mno-fp-regs -ffixed-8
+ARCHBLOBLFLAGS := -I binary -O elf64-alpha -B alpha
 
 # Determine if we can use the BWX instructions with GAS.
 old_gas := $(shell if $(AS) --version 2>&1 | grep 'version 2.7' > /dev/null; then echo y; else echo n; fi)
diff -Nru a/arch/alpha/defconfig b/arch/alpha/defconfig
--- a/arch/alpha/defconfig	Mon Nov  4 14:31:02 2002
+++ b/arch/alpha/defconfig	Mon Nov  4 14:31:02 2002
@@ -59,6 +59,7 @@
 # CONFIG_ALPHA_TAKARA is not set
 # CONFIG_ALPHA_TITAN is not set
 # CONFIG_ALPHA_WILDFIRE is not set
+CONFIG_VERBOSE_MCHECK=y
 CONFIG_ISA=y
 CONFIG_EISA=y
 # CONFIG_SBUS is not set
diff -Nru a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile
--- a/arch/alpha/kernel/Makefile	Mon Nov  4 14:31:01 2002
+++ b/arch/alpha/kernel/Makefile	Mon Nov  4 14:31:01 2002
@@ -10,7 +10,7 @@
 
 obj-y    := entry.o traps.o process.o init_task.o osf_sys.o irq.o \
 	    irq_alpha.o signal.o setup.o ptrace.o time.o semaphore.o \
-	    alpha_ksyms.o systbls.o
+	    alpha_ksyms.o systbls.o err_common.o
 
 #
 # FIXME!
diff -Nru a/arch/alpha/kernel/asm-offsets.c b/arch/alpha/kernel/asm-offsets.c
--- a/arch/alpha/kernel/asm-offsets.c	Mon Nov  4 14:31:03 2002
+++ b/arch/alpha/kernel/asm-offsets.c	Mon Nov  4 14:31:03 2002
@@ -22,6 +22,7 @@
 	BLANK();
 	DEFINE(PT_PTRACED, PT_PTRACED);
 	DEFINE(CLONE_VM, CLONE_VM);
+	DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
 	DEFINE(SIGCHLD, SIGCHLD);
 	BLANK();
 	DEFINE(HAE_CACHE, offsetof(struct alpha_machine_vector, hae_cache));
diff -Nru a/arch/alpha/kernel/core_cia.c b/arch/alpha/kernel/core_cia.c
--- a/arch/alpha/kernel/core_cia.c	Mon Nov  4 14:31:02 2002
+++ b/arch/alpha/kernel/core_cia.c	Mon Nov  4 14:31:02 2002
@@ -47,6 +47,15 @@
 
 #define vip	volatile int  *
 
+/* Save CIA configuration data as the console had it set up.  */
+
+struct 
+{
+	unsigned int w_base;
+	unsigned int w_mask;
+	unsigned int t_base;
+} saved_config[4] __attribute((common));
+
 /*
  * Given a bus, device, and function number, compute resulting
  * configuration space address.  It is therefore not safe to have
@@ -648,6 +657,24 @@
 		hose->dense_io_base = CIA_BW_IO - IDENT_ADDR;
 	}
 
+	/* Save CIA configuration data as the console had it set up.  */
+
+	saved_config[0].w_base = *(vip)CIA_IOC_PCI_W0_BASE;
+	saved_config[0].w_mask = *(vip)CIA_IOC_PCI_W0_MASK;
+	saved_config[0].t_base = *(vip)CIA_IOC_PCI_T0_BASE;
+
+	saved_config[1].w_base = *(vip)CIA_IOC_PCI_W1_BASE;
+	saved_config[1].w_mask = *(vip)CIA_IOC_PCI_W1_MASK;
+	saved_config[1].t_base = *(vip)CIA_IOC_PCI_T1_BASE;
+
+	saved_config[2].w_base = *(vip)CIA_IOC_PCI_W2_BASE;
+	saved_config[2].w_mask = *(vip)CIA_IOC_PCI_W2_MASK;
+	saved_config[2].t_base = *(vip)CIA_IOC_PCI_T2_BASE;
+
+	saved_config[3].w_base = *(vip)CIA_IOC_PCI_W3_BASE;
+	saved_config[3].w_mask = *(vip)CIA_IOC_PCI_W3_MASK;
+	saved_config[3].t_base = *(vip)CIA_IOC_PCI_T3_BASE;
+
 	/*
 	 * Set up the PCI to main memory translation windows.
 	 *
@@ -736,6 +763,26 @@
 	do_init_arch(1);
 }
 
+void
+cia_kill_arch(int mode)
+{
+	*(vip)CIA_IOC_PCI_W0_BASE = saved_config[0].w_base;
+	*(vip)CIA_IOC_PCI_W0_MASK = saved_config[0].w_mask;
+	*(vip)CIA_IOC_PCI_T0_BASE = saved_config[0].t_base;
+
+	*(vip)CIA_IOC_PCI_W1_BASE = saved_config[1].w_base;
+	*(vip)CIA_IOC_PCI_W1_MASK = saved_config[1].w_mask;
+	*(vip)CIA_IOC_PCI_T1_BASE = saved_config[1].t_base;
+
+	*(vip)CIA_IOC_PCI_W2_BASE = saved_config[2].w_base;
+	*(vip)CIA_IOC_PCI_W2_MASK = saved_config[2].w_mask;
+	*(vip)CIA_IOC_PCI_T2_BASE = saved_config[2].t_base;
+
+	*(vip)CIA_IOC_PCI_W3_BASE = saved_config[3].w_base;
+	*(vip)CIA_IOC_PCI_W3_MASK = saved_config[3].w_mask;
+	*(vip)CIA_IOC_PCI_T3_BASE = saved_config[3].t_base;
+}
+
 void __init
 cia_init_pci(void)
 {
@@ -755,6 +802,7 @@
 	*(vip)CIA_IOC_CIA_ERR;		/* re-read to force write.  */
 }
 
+#ifdef CONFIG_VERBOSE_MCHECK
 static void
 cia_decode_pci_error(struct el_CIA_sysdata_mcheck *cia, const char *msg)
 {
@@ -1022,13 +1070,13 @@
 	printk(KERN_CRIT "  Command: %s, Parity bit: %d\n", cmd, par);
 	printk(KERN_CRIT "  Address: %#010lx, Mask: %#lx\n", addr, mask);
 }
+#endif
 
 static int
 cia_decode_mchk(unsigned long la_ptr)
 {
 	struct el_common *com;
 	struct el_CIA_sysdata_mcheck *cia;
-	int which;
 
 	com = (void *)la_ptr;
 	cia = (void *)(la_ptr + com->sys_offset);
@@ -1036,8 +1084,8 @@
 	if ((cia->cia_err & CIA_ERR_VALID) == 0)
 		return 0;
 
-	which = cia->cia_err & 0xfff;
-	switch (ffs(which) - 1) {
+#ifdef CONFIG_VERBOSE_MCHECK
+	switch (ffs(cia->cia_err & 0xfff) - 1) {
 	case 0: /* CIA_ERR_COR_ERR */
 		cia_decode_ecc_error(cia, "Corrected ECC error");
 		break;
@@ -1109,6 +1157,7 @@
 	if (cia->cia_err & CIA_ERR_LOST_IOA_TIMEOUT)
 		printk(KERN_CRIT "CIA lost machine check: "
 		       "I/O timeout\n");
+#endif
 
 	return 1;
 }
diff -Nru a/arch/alpha/kernel/core_titan.c b/arch/alpha/kernel/core_titan.c
--- a/arch/alpha/kernel/core_titan.c	Mon Nov  4 14:31:01 2002
+++ b/arch/alpha/kernel/core_titan.c	Mon Nov  4 14:31:01 2002
@@ -27,12 +27,14 @@
 
 unsigned TITAN_agp = 0;
 
-static struct
+/* Save Titan configuration data as the console had it set up.  */
+
+struct
 {
 	unsigned long wsba[4];
 	unsigned long wsm[4];
 	unsigned long tba[4];
-} saved_pachip_port[4];
+} saved_config[4] __attribute__((common));
 
 /*
  * BIOS32-style PCI interface:
@@ -289,21 +291,21 @@
 	 * Save the existing PCI window translations.  SRM will 
 	 * need them when we go to reboot.
 	 */
-	saved_pachip_port[index].wsba[0] = port->wsba[0].csr;
-	saved_pachip_port[index].wsm[0]  = port->wsm[0].csr;
-	saved_pachip_port[index].tba[0]  = port->tba[0].csr;
-
-	saved_pachip_port[index].wsba[1] = port->wsba[1].csr;
-	saved_pachip_port[index].wsm[1]  = port->wsm[1].csr;
-	saved_pachip_port[index].tba[1]  = port->tba[1].csr;
-
-	saved_pachip_port[index].wsba[2] = port->wsba[2].csr;
-	saved_pachip_port[index].wsm[2]  = port->wsm[2].csr;
-	saved_pachip_port[index].tba[2]  = port->tba[2].csr;
-
-	saved_pachip_port[index].wsba[3] = port->wsba[3].csr;
-	saved_pachip_port[index].wsm[3]  = port->wsm[3].csr;
-	saved_pachip_port[index].tba[3]  = port->tba[3].csr;
+	saved_config[index].wsba[0] = port->wsba[0].csr;
+	saved_config[index].wsm[0]  = port->wsm[0].csr;
+	saved_config[index].tba[0]  = port->tba[0].csr;
+
+	saved_config[index].wsba[1] = port->wsba[1].csr;
+	saved_config[index].wsm[1]  = port->wsm[1].csr;
+	saved_config[index].tba[1]  = port->tba[1].csr;
+
+	saved_config[index].wsba[2] = port->wsba[2].csr;
+	saved_config[index].wsm[2]  = port->wsm[2].csr;
+	saved_config[index].tba[2]  = port->tba[2].csr;
+
+	saved_config[index].wsba[3] = port->wsba[3].csr;
+	saved_config[index].wsm[3]  = port->wsm[3].csr;
+	saved_config[index].tba[3]  = port->tba[3].csr;
 
 	/*
 	 * Set up the PCI to main memory translation windows.
@@ -392,21 +394,21 @@
 static void
 titan_kill_one_pachip_port(titan_pachip_port *port, int index)
 {
-	port->wsba[0].csr = saved_pachip_port[index].wsba[0];
-	port->wsm[0].csr  = saved_pachip_port[index].wsm[0];
-	port->tba[0].csr  = saved_pachip_port[index].tba[0];
-
-	port->wsba[1].csr = saved_pachip_port[index].wsba[1];
-	port->wsm[1].csr  = saved_pachip_port[index].wsm[1];
-	port->tba[1].csr  = saved_pachip_port[index].tba[1];
-
-	port->wsba[2].csr = saved_pachip_port[index].wsba[2];
-	port->wsm[2].csr  = saved_pachip_port[index].wsm[2];
-	port->tba[2].csr  = saved_pachip_port[index].tba[2];
-
-	port->wsba[3].csr = saved_pachip_port[index].wsba[3];
-	port->wsm[3].csr  = saved_pachip_port[index].wsm[3];
-	port->tba[3].csr  = saved_pachip_port[index].tba[3];
+	port->wsba[0].csr = saved_config[index].wsba[0];
+	port->wsm[0].csr  = saved_config[index].wsm[0];
+	port->tba[0].csr  = saved_config[index].tba[0];
+
+	port->wsba[1].csr = saved_config[index].wsba[1];
+	port->wsm[1].csr  = saved_config[index].wsm[1];
+	port->tba[1].csr  = saved_config[index].tba[1];
+
+	port->wsba[2].csr = saved_config[index].wsba[2];
+	port->wsm[2].csr  = saved_config[index].wsm[2];
+	port->tba[2].csr  = saved_config[index].tba[2];
+
+	port->wsba[3].csr = saved_config[index].wsba[3];
+	port->wsm[3].csr  = saved_config[index].wsm[3];
+	port->tba[3].csr  = saved_config[index].tba[3];
 }
 
 static void
diff -Nru a/arch/alpha/kernel/core_tsunami.c b/arch/alpha/kernel/core_tsunami.c
--- a/arch/alpha/kernel/core_tsunami.c	Mon Nov  4 14:31:01 2002
+++ b/arch/alpha/kernel/core_tsunami.c	Mon Nov  4 14:31:01 2002
@@ -26,13 +26,14 @@
 #include "proto.h"
 #include "pci_impl.h"
 
+/* Save Tsunami configuration data as the console had it set up.  */
 
-static struct 
+struct 
 {
 	unsigned long wsba[4];
 	unsigned long wsm[4];
 	unsigned long tba[4];
-} saved_pchip[2];
+} saved_config[2] __attribute__((common));
 
 /*
  * NOTE: Herein lie back-to-back mb instructions.  They are magic. 
@@ -293,21 +294,21 @@
 	 * need them when we go to reboot.
 	 */
 
-	saved_pchip[index].wsba[0] = pchip->wsba[0].csr;
-	saved_pchip[index].wsm[0] = pchip->wsm[0].csr;
-	saved_pchip[index].tba[0] = pchip->tba[0].csr;
-
-	saved_pchip[index].wsba[1] = pchip->wsba[1].csr;
-	saved_pchip[index].wsm[1] = pchip->wsm[1].csr;
-	saved_pchip[index].tba[1] = pchip->tba[1].csr;
-
-	saved_pchip[index].wsba[2] = pchip->wsba[2].csr;
-	saved_pchip[index].wsm[2] = pchip->wsm[2].csr;
-	saved_pchip[index].tba[2] = pchip->tba[2].csr;
-
-	saved_pchip[index].wsba[3] = pchip->wsba[3].csr;
-	saved_pchip[index].wsm[3] = pchip->wsm[3].csr;
-	saved_pchip[index].tba[3] = pchip->tba[3].csr;
+	saved_config[index].wsba[0] = pchip->wsba[0].csr;
+	saved_config[index].wsm[0] = pchip->wsm[0].csr;
+	saved_config[index].tba[0] = pchip->tba[0].csr;
+
+	saved_config[index].wsba[1] = pchip->wsba[1].csr;
+	saved_config[index].wsm[1] = pchip->wsm[1].csr;
+	saved_config[index].tba[1] = pchip->tba[1].csr;
+
+	saved_config[index].wsba[2] = pchip->wsba[2].csr;
+	saved_config[index].wsm[2] = pchip->wsm[2].csr;
+	saved_config[index].tba[2] = pchip->tba[2].csr;
+
+	saved_config[index].wsba[3] = pchip->wsba[3].csr;
+	saved_config[index].wsm[3] = pchip->wsm[3].csr;
+	saved_config[index].tba[3] = pchip->tba[3].csr;
 
 	/*
 	 * Set up the PCI to main memory translation windows.
@@ -403,21 +404,21 @@
 static void
 tsunami_kill_one_pchip(tsunami_pchip *pchip, int index)
 {
-	pchip->wsba[0].csr = saved_pchip[index].wsba[0];
-	pchip->wsm[0].csr = saved_pchip[index].wsm[0];
-	pchip->tba[0].csr = saved_pchip[index].tba[0];
-
-	pchip->wsba[1].csr = saved_pchip[index].wsba[1];
-	pchip->wsm[1].csr = saved_pchip[index].wsm[1];
-	pchip->tba[1].csr = saved_pchip[index].tba[1];
-
-	pchip->wsba[2].csr = saved_pchip[index].wsba[2];
-	pchip->wsm[2].csr = saved_pchip[index].wsm[2];
-	pchip->tba[2].csr = saved_pchip[index].tba[2];
-
-	pchip->wsba[3].csr = saved_pchip[index].wsba[3];
-	pchip->wsm[3].csr = saved_pchip[index].wsm[3];
-	pchip->tba[3].csr = saved_pchip[index].tba[3];
+	pchip->wsba[0].csr = saved_config[index].wsba[0];
+	pchip->wsm[0].csr = saved_config[index].wsm[0];
+	pchip->tba[0].csr = saved_config[index].tba[0];
+
+	pchip->wsba[1].csr = saved_config[index].wsba[1];
+	pchip->wsm[1].csr = saved_config[index].wsm[1];
+	pchip->tba[1].csr = saved_config[index].tba[1];
+
+	pchip->wsba[2].csr = saved_config[index].wsba[2];
+	pchip->wsm[2].csr = saved_config[index].wsm[2];
+	pchip->tba[2].csr = saved_config[index].tba[2];
+
+	pchip->wsba[3].csr = saved_config[index].wsba[3];
+	pchip->wsm[3].csr = saved_config[index].wsm[3];
+	pchip->tba[3].csr = saved_config[index].tba[3];
 }
 
 void
diff -Nru a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
--- a/arch/alpha/kernel/entry.S	Mon Nov  4 14:31:00 2002
+++ b/arch/alpha/kernel/entry.S	Mon Nov  4 14:31:00 2002
@@ -212,7 +212,7 @@
 	stq	$2, 152($30)		/* HAE */
 
 	/* Shuffle FLAGS to the front; add CLONE_VM.  */
-	ldi	$1, CLONE_VM
+	ldi	$1, CLONE_VM|CLONE_UNTRACED
 	or	$18, $1, $16
 	bsr	$26, sys_clone
 
@@ -452,7 +452,8 @@
 	bsr	$1,do_switch_stack
 	bis	$31,SIGCHLD,$16
 	mov	$31,$17
-	mov	$30,$18
+	mov	$31,$18
+	mov	$30,$19
 	jsr	$26,alpha_clone
 	bsr	$1,undo_switch_stack
 	ret	$31,($26),1
@@ -463,8 +464,9 @@
 .ent	sys_clone
 sys_clone:
 	bsr	$1,do_switch_stack
-	/* arg1 and arg2 come from the user */
-	mov	$30,$18
+	/* $16, $17, $18, $19 come from the user; $19 is used later
+	   via pt_regs->r19.  */
+	mov	$30,$19
 	jsr	$26,alpha_clone
 	bsr	$1,undo_switch_stack
 	ret	$31,($26),1
diff -Nru a/arch/alpha/kernel/err_common.c b/arch/alpha/kernel/err_common.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/alpha/kernel/err_common.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,772 @@
+/*
+ *	linux/arch/alpha/kernel/err_common.c
+ *
+ *	Copyright (C) 2000 Jeff Wiedemeier (Compaq Computer Corporation)
+ *
+ *	Error handling code supporting Alpha systems
+ */
+
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+
+#include <asm/io.h>
+#include <asm/hwrpb.h>
+#include <asm/smp.h>
+
+#include "err_impl.h"
+#include "proto.h"
+
+/*
+ * err_print_prefix -- error handling print routines should prefix
+ * all prints with this
+ */
+char *err_print_prefix = KERN_NOTICE;
+
+/*
+ * Forward references
+ */
+static void el_print_timestamp(union el_timestamp);
+static void el_process_subpackets(struct el_subpacket *, int);
+
+
+/*
+ * Generic
+ */
+void
+mchk_dump_mem(void *data, int length, char **annotation)
+{
+	unsigned long *ldata = data;
+	int i;
+	
+	for(i = 0; (i * sizeof(*ldata)) < length; i++) {
+		if (annotation && !annotation[i]) 
+			annotation = NULL;
+		printk("%s    %08x: %016lx    %s\n",
+		       err_print_prefix,
+		       (unsigned)(i * sizeof(*ldata)), ldata[i],
+		       annotation ? annotation[i] : "");
+	}
+}
+
+void
+mchk_dump_logout_frame(struct el_common *mchk_header)
+{
+	printk("%s  -- Frame Header --\n"
+	         "    Frame Size:   %d (0x%x) bytes\n"
+	         "    Flags:        %s%s\n"
+	         "    MCHK Code:    0x%x\n"
+	         "    Frame Rev:    %d\n"
+	         "    Proc Offset:  0x%08x\n"
+	         "    Sys Offset:   0x%08x\n"
+  	         "  -- Processor Region --\n",
+	       err_print_prefix, 
+	       mchk_header->size, mchk_header->size,
+	       mchk_header->retry ? "RETRY " : "", 
+  	         mchk_header->err2 ? "SECOND_ERR " : "",
+	       mchk_header->code,
+	       mchk_header->frame_rev,
+	       mchk_header->proc_offset,
+	       mchk_header->sys_offset);
+
+	mchk_dump_mem((void *)
+		      ((unsigned long)mchk_header + mchk_header->proc_offset),
+		      mchk_header->sys_offset - mchk_header->proc_offset,
+		      NULL);
+	
+	printk("%s  -- System Region --\n", err_print_prefix);
+	mchk_dump_mem((void *)
+		      ((unsigned long)mchk_header + mchk_header->sys_offset),
+		      mchk_header->size - mchk_header->sys_offset,
+		      NULL);
+	printk("%s  -- End of Frame --\n", err_print_prefix);
+}
+
+
+/*
+ * EV7 generic
+ */
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EV7)
+
+void
+ev7_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs)
+{
+	/*
+	 * Sync the processor
+	 */
+	mb();
+	draina();
+
+	/*
+	 * Parse the logout frame without printing first. If the only error(s)
+	 * found are have a disposition of "dismiss", then just dismiss them
+	 * and don't print any message
+	 */
+	printk("%sEV7 MACHINE CHECK vector %lx\n", err_print_prefix, vector);
+
+	/* 
+	 * Release the logout frame 
+	 */
+	wrmces(0x7);
+	mb();
+}
+
+struct ev7_pal_subpacket {
+	union {
+		struct {
+			u32 mchk_code;
+			u32 subpacket_count;
+			u64 whami;
+			u64 rbox_whami;
+			u64 rbox_int;
+			u64 exc_addr;
+			union el_timestamp timestamp;
+			u64 halt_code;
+			u64 reserved;
+		} logout;
+	} by_type;
+};
+
+static char *el_ev7_processor_subpacket_annotation[] = {
+	"Subpacket Header",	"I_STAT",	"DC_STAT",
+	"C_ADDR",		"C_SYNDROME_1",	"C_SYNDROME_0",
+	"C_STAT",		"C_STS",	"MM_STAT",
+	"EXC_ADDR",		"IER_CM",	"ISUM",
+	"PAL_BASE",		"I_CTL",	"PROCESS_CONTEXT",
+	"CBOX_CTL",		"CBOX_STP_CTL",	"CBOX_ACC_CTL",
+	"CBOX_LCL_SET",		"CBOX_GLB_SET",	"BBOX_CTL",
+	"BBOX_ERR_STS",		"BBOX_ERR_IDX",	"CBOX_DDP_ERR_STS",
+	"BBOX_DAT_RMP",		NULL
+};
+
+static char *el_ev7_zbox_subpacket_annotation[] = {
+	"Subpacket Header", 	
+	"ZBOX(0): DRAM_ERR_STATUS_2 / DRAM_ERR_STATUS_1",
+	"ZBOX(0): DRAM_ERROR_CTL    / DRAM_ERR_STATUS_3",
+	"ZBOX(0): DIFT_TIMEOUT      / DRAM_ERR_ADR",
+	"ZBOX(0): FRC_ERR_ADR       / DRAM_MAPPER_CTL",
+	"ZBOX(0): reserved          / DIFT_ERR_STATUS",
+	"ZBOX(1): DRAM_ERR_STATUS_2 / DRAM_ERR_STATUS_1",
+	"ZBOX(1): DRAM_ERROR_CTL    / DRAM_ERR_STATUS_3",
+	"ZBOX(1): DIFT_TIMEOUT      / DRAM_ERR_ADR",
+	"ZBOX(1): FRC_ERR_ADR       / DRAM_MAPPER_CTL",
+	"ZBOX(1): reserved          / DIFT_ERR_STATUS",
+	"CBOX_CTL",		"CBOX_STP_CTL",
+	"ZBOX(0)_ERROR_PA",	"ZBOX(1)_ERROR_PA",
+	"ZBOX(0)_ORED_SYNDROME","ZBOX(1)_ORED_SYNDROME",
+	NULL
+};
+
+static char *el_ev7_rbox_subpacket_annotation[] = {
+	"Subpacket Header",	"RBOX_CFG",	"RBOX_N_CFG",
+	"RBOX_S_CFG",		"RBOX_E_CFG",	"RBOX_W_CFG",
+	"RBOX_N_ERR",		"RBOX_S_ERR",	"RBOX_E_ERR",
+	"RBOX_W_ERR",		"RBOX_IO_CFG",	"RBOX_IO_ERR",
+	"RBOX_L_ERR",		"RBOX_WHOAMI",	"RBOX_IMASL",
+	"RBOX_INTQ",		"RBOX_INT",	NULL
+};
+
+static char *el_ev7_io_subpacket_annotation[] = {
+	"Subpacket Header",	"IO_ASIC_REV",	"IO_SYS_REV",
+	"IO7_UPH",		"HPI_CTL",	"CRD_CTL",
+	"HEI_CTL",		"PO7_ERROR_SUM","PO7_UNCRR_SYM",
+	"PO7_CRRCT_SYM",	"PO7_UGBGE_SYM","PO7_ERR_PKT0",
+	"PO7_ERR_PKT1",		"reserved",	"reserved",
+	"PO0_ERR_SUM",		"PO0_TLB_ERR",	"PO0_SPL_COMPLT",
+	"PO0_TRANS_SUM",	"PO0_FIRST_ERR","PO0_MULT_ERR",
+	"DM CSR PH",		"DM CSR PH",	"DM CSR PH",
+	"DM CSR PH",		"reserved",
+	"PO1_ERR_SUM",		"PO1_TLB_ERR",	"PO1_SPL_COMPLT",
+	"PO1_TRANS_SUM",	"PO1_FIRST_ERR","PO1_MULT_ERR",
+	"DM CSR PH",		"DM CSR PH",	"DM CSR PH",
+	"DM CSR PH",		"reserved",
+	"PO2_ERR_SUM",		"PO2_TLB_ERR",	"PO2_SPL_COMPLT",
+	"PO2_TRANS_SUM",	"PO2_FIRST_ERR","PO2_MULT_ERR",
+	"DM CSR PH",		"DM CSR PH",	"DM CSR PH",
+	"DM CSR PH",		"reserved",
+	"PO3_ERR_SUM",		"PO3_TLB_ERR",	"PO3_SPL_COMPLT",
+	"PO3_TRANS_SUM",	"PO3_FIRST_ERR","PO3_MULT_ERR",
+	"DM CSR PH",		"DM CSR PH",	"DM CSR PH",
+	"DM CSR PH",		"reserved",	
+	NULL
+};
+	
+static struct el_subpacket_annotation el_ev7_pal_annotations[] = {
+	SUBPACKET_ANNOTATION(EL_CLASS__PAL,
+			     EL_TYPE__PAL__EV7_PROCESSOR,
+			     1,
+			     "EV7 Processor Subpacket",
+			     el_ev7_processor_subpacket_annotation),
+	SUBPACKET_ANNOTATION(EL_CLASS__PAL,
+			     EL_TYPE__PAL__EV7_ZBOX,
+			     1,
+			     "EV7 ZBOX Subpacket",
+			     el_ev7_zbox_subpacket_annotation),
+	SUBPACKET_ANNOTATION(EL_CLASS__PAL,
+			     EL_TYPE__PAL__EV7_RBOX,
+			     1,
+			     "EV7 RBOX Subpacket",
+			     el_ev7_rbox_subpacket_annotation),
+	SUBPACKET_ANNOTATION(EL_CLASS__PAL,
+			     EL_TYPE__PAL__EV7_IO,
+			     1,
+			     "EV7 IO Subpacket",
+			     el_ev7_io_subpacket_annotation)
+};
+
+static struct el_subpacket *
+ev7_process_pal_subpacket(struct el_subpacket *header)
+{
+	struct ev7_pal_subpacket *packet;
+
+	if (header->class != EL_CLASS__PAL) {
+		printk("%s  ** Unexpected header CLASS %d TYPE %d, aborting\n",
+		       err_print_prefix,
+		       header->class, header->type);
+		return NULL;
+	}
+
+	packet = (struct ev7_pal_subpacket *)header->by_type.raw.data_start;
+
+	switch(header->type) {
+	case EL_TYPE__PAL__LOGOUT_FRAME:
+		printk("%s*** MCHK occurred on LPID %ld (RBOX %lx)\n",
+		       err_print_prefix,
+		       packet->by_type.logout.whami, 
+		       packet->by_type.logout.rbox_whami);
+		el_print_timestamp(packet->by_type.logout.timestamp);
+		printk("%s  EXC_ADDR: %016lx\n"
+		         "  HALT_CODE: %lx\n", 
+		       err_print_prefix,
+		       packet->by_type.logout.exc_addr,
+		       packet->by_type.logout.halt_code);
+		el_process_subpackets(header,
+                                      packet->by_type.logout.subpacket_count);
+		break;
+	default:
+		printk("%s  ** PAL TYPE %d SUBPACKET\n", 
+		       err_print_prefix,
+		       header->type);
+		el_annotate_subpacket(header);
+		break;
+	}
+	
+	return (struct el_subpacket *)((unsigned long)header + header->length);
+}
+
+struct el_subpacket_handler ev7_pal_subpacket_handler =
+	SUBPACKET_HANDLER_INIT(EL_CLASS__PAL, ev7_process_pal_subpacket);
+
+void 
+ev7_register_error_handlers(void)
+{
+	int i;
+
+	for(i = 0;
+	    i<sizeof(el_ev7_pal_annotations)/sizeof(el_ev7_pal_annotations[1]);
+	    i++) {
+		cdl_register_subpacket_annotation(&el_ev7_pal_annotations[i]);
+	}	
+	cdl_register_subpacket_handler(&ev7_pal_subpacket_handler);
+}
+
+#endif /* CONFIG_ALPHA_GENERIC || CONFIG_ALPHA_EV7 */
+
+
+/*
+ * EV6 generic
+ */
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EV6)
+
+static int
+ev6_parse_ibox(u64 i_stat, int print)
+{
+	int status = MCHK_DISPOSITION_REPORT;
+
+#define EV6__I_STAT__PAR	(1UL << 29)
+#define EV6__I_STAT__ERRMASK	(EV6__I_STAT__PAR)
+
+	if (!(i_stat & EV6__I_STAT__ERRMASK))
+		return MCHK_DISPOSITION_UNKNOWN_ERROR;
+
+	if (!print)
+		return status;
+
+	if (i_stat & EV6__I_STAT__PAR)
+		printk("%s    Icache parity error\n", err_print_prefix);
+
+	return status;
+}
+
+static int
+ev6_parse_mbox(u64 mm_stat, u64 d_stat, u64 c_stat, int print)
+{
+	int status = MCHK_DISPOSITION_REPORT;
+
+#define EV6__MM_STAT__DC_TAG_PERR	(1UL << 10)
+#define EV6__MM_STAT__ERRMASK		(EV6__MM_STAT__DC_TAG_PERR)
+#define EV6__D_STAT__TPERR_P0		(1UL << 0)
+#define EV6__D_STAT__TPERR_P1		(1UL << 1)
+#define EV6__D_STAT__ECC_ERR_ST		(1UL << 2)
+#define EV6__D_STAT__ECC_ERR_LD		(1UL << 3)
+#define EV6__D_STAT__SEO		(1UL << 4)
+#define EV6__D_STAT__ERRMASK		(EV6__D_STAT__TPERR_P0 |	\
+                                         EV6__D_STAT__TPERR_P1 | 	\
+                                         EV6__D_STAT__ECC_ERR_ST | 	\
+                                         EV6__D_STAT__ECC_ERR_LD | 	\
+                                         EV6__D_STAT__SEO)
+
+	if (!(d_stat & EV6__D_STAT__ERRMASK) && 
+	    !(mm_stat & EV6__MM_STAT__ERRMASK))
+		return MCHK_DISPOSITION_UNKNOWN_ERROR;
+
+	if (!print)
+		return status;
+
+	if (mm_stat & EV6__MM_STAT__DC_TAG_PERR)
+		printk("%s    Dcache tag parity error on probe\n",
+		       err_print_prefix);
+	if (d_stat & EV6__D_STAT__TPERR_P0)
+		printk("%s    Dcache tag parity error - pipe 0\n",
+		       err_print_prefix);
+	if (d_stat & EV6__D_STAT__TPERR_P1)
+		printk("%s    Dcache tag parity error - pipe 1\n",
+		       err_print_prefix);
+	if (d_stat & EV6__D_STAT__ECC_ERR_ST)
+		printk("%s    ECC error occurred on a store\n", 
+		       err_print_prefix);
+	if (d_stat & EV6__D_STAT__ECC_ERR_LD)
+		printk("%s    ECC error occurred on a %s load\n",
+		       err_print_prefix,
+		       c_stat ? "" : "speculative ");
+	if (d_stat & EV6__D_STAT__SEO)
+		printk("%s    Dcache second error\n", err_print_prefix);
+
+	return status;
+}
+
+static int
+ev6_parse_cbox(u64 c_addr, u64 c1_syn, u64 c2_syn, 
+	       u64 c_stat, u64 c_sts, int print)
+{
+	char *sourcename[] = { "UNKNOWN", "UNKNOWN", "UNKNOWN",
+			       "MEMORY", "BCACHE", "DCACHE", 
+			       "BCACHE PROBE", "BCACHE PROBE" };
+	char *streamname[] = { "D", "I" };
+	char *bitsname[] = { "SINGLE", "DOUBLE" };
+	int status = MCHK_DISPOSITION_REPORT;
+	int source = -1, stream = -1, bits = -1;
+
+#define EV6__C_STAT__BC_PERR		(0x01)
+#define EV6__C_STAT__DC_PERR		(0x02)
+#define EV6__C_STAT__DSTREAM_MEM_ERR	(0x03)
+#define EV6__C_STAT__DSTREAM_BC_ERR	(0x04)
+#define EV6__C_STAT__DSTREAM_DC_ERR	(0x05)
+#define EV6__C_STAT__PROBE_BC_ERR0	(0x06)	/* both 6 and 7 indicate... */
+#define EV6__C_STAT__PROBE_BC_ERR1	(0x07)	/* ...probe bc error.       */
+#define EV6__C_STAT__ISTREAM_MEM_ERR	(0x0B)
+#define EV6__C_STAT__ISTREAM_BC_ERR	(0x0C)
+#define EV6__C_STAT__DSTREAM_MEM_DBL	(0x13)
+#define EV6__C_STAT__DSTREAM_BC_DBL	(0x14)
+#define EV6__C_STAT__ISTREAM_MEM_DBL	(0x1B)
+#define EV6__C_STAT__ISTREAM_BC_DBL	(0x1C)
+#define EV6__C_STAT__SOURCE_MEMORY	(0x03)
+#define EV6__C_STAT__SOURCE_BCACHE	(0x04)
+#define EV6__C_STAT__SOURCE__S		(0)
+#define EV6__C_STAT__SOURCE__M 		(0x07)
+#define EV6__C_STAT__ISTREAM__S		(3)
+#define EV6__C_STAT__ISTREAM__M		(0x01)
+#define EV6__C_STAT__DOUBLE__S		(4)
+#define EV6__C_STAT__DOUBLE__M		(0x01)
+#define EV6__C_STAT__ERRMASK		(0x1F)
+#define EV6__C_STS__SHARED		(1 << 0)
+#define EV6__C_STS__DIRTY		(1 << 1)
+#define EV6__C_STS__VALID		(1 << 2)
+#define EV6__C_STS__PARITY		(1 << 3)
+
+	if (!(c_stat & EV6__C_STAT__ERRMASK))
+		return MCHK_DISPOSITION_UNKNOWN_ERROR;
+
+	if (!print)
+		return status;
+
+	source = EXTRACT(c_stat, EV6__C_STAT__SOURCE);
+	stream = EXTRACT(c_stat, EV6__C_STAT__ISTREAM);
+	bits = EXTRACT(c_stat, EV6__C_STAT__DOUBLE);
+
+	if (c_stat & EV6__C_STAT__BC_PERR) {
+		printk("%s    Bcache tag parity error\n", err_print_prefix);
+		source = -1;
+	}
+
+	if (c_stat & EV6__C_STAT__DC_PERR) {
+		printk("%s    Dcache tag parity error\n", err_print_prefix);
+		source = -1;
+	}
+
+	if (c_stat == EV6__C_STAT__PROBE_BC_ERR0 ||
+	    c_stat == EV6__C_STAT__PROBE_BC_ERR1) {
+		printk("%s    Bcache single-bit error on a probe hit\n",
+		       err_print_prefix);
+		source = -1;
+	}
+
+	if (source != -1) 
+		printk("%s    %s-STREAM %s-BIT ECC error from %s\n",
+		       err_print_prefix,
+		       streamname[stream], bitsname[bits], sourcename[source]);
+
+	printk("%s    Address: 0x%016lx\n"
+	         "    Syndrome[upper.lower]: %02lx.%02lx\n", 
+	       err_print_prefix,
+	       c_addr,
+	       c2_syn, c1_syn);
+
+	if (source == EV6__C_STAT__SOURCE_MEMORY ||
+	    source == EV6__C_STAT__SOURCE_BCACHE) 
+		printk("%s    Block status: %s%s%s%s\n",
+		       err_print_prefix,
+		       (c_sts & EV6__C_STS__SHARED) ? "SHARED " : "",
+		       (c_sts & EV6__C_STS__DIRTY)  ? "DIRTY "  : "",
+		       (c_sts & EV6__C_STS__VALID)  ? "VALID "  : "",
+		       (c_sts & EV6__C_STS__PARITY) ? "PARITY " : "");
+		
+	return status;
+}
+
+int
+ev6_process_logout_frame(struct el_common *mchk_header, int print)
+{
+	struct el_common_EV6_mcheck *ev6mchk = 
+		(struct el_common_EV6_mcheck *)mchk_header;
+	int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
+
+	status |= ev6_parse_ibox(ev6mchk->I_STAT, print);
+	status |= ev6_parse_mbox(ev6mchk->MM_STAT, ev6mchk->DC_STAT, 
+				 ev6mchk->C_STAT, print);
+	status |= ev6_parse_cbox(ev6mchk->C_ADDR, ev6mchk->DC1_SYNDROME,
+				 ev6mchk->DC0_SYNDROME, ev6mchk->C_STAT,
+				 ev6mchk->C_STS, print);
+
+	if (!print)
+		return status;
+
+	if (status != MCHK_DISPOSITION_DISMISS) {
+		char *saved_err_prefix = err_print_prefix;
+
+		/*
+		 * Dump some additional information from the frame
+		 */
+		printk("%s    EXC_ADDR: 0x%016lx   IER_CM: 0x%016lx"
+		            "   ISUM: 0x%016lx\n"
+		         "    PAL_BASE: 0x%016lx   I_CTL:  0x%016lx"
+		            "   PCTX: 0x%016lx\n",
+		       err_print_prefix,
+		       ev6mchk->EXC_ADDR, ev6mchk->IER_CM, ev6mchk->ISUM,
+		       ev6mchk->PAL_BASE, ev6mchk->I_CTL, ev6mchk->PCTX);
+
+		if (status == MCHK_DISPOSITION_UNKNOWN_ERROR) {
+			printk("%s    UNKNOWN error, frame follows:\n",
+			       err_print_prefix);
+		} else {
+			/* had decode -- downgrade print level for frame */
+			err_print_prefix = KERN_NOTICE;
+		}
+
+		mchk_dump_logout_frame(mchk_header);
+
+		err_print_prefix = saved_err_prefix;
+	}
+
+	return status;
+}
+
+void
+ev6_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs)
+{
+	struct el_common *mchk_header = (struct el_common *)la_ptr;
+
+	/*
+	 * Sync the processor
+	 */
+	mb();
+	draina();
+
+	/*
+	 * Parse the logout frame without printing first. If the only error(s)
+	 * found are have a disposition of "dismiss", then just dismiss them
+	 * and don't print any message
+	 */
+	if (ev6_process_logout_frame(mchk_header, 0) != 
+	    MCHK_DISPOSITION_DISMISS) {
+		char *saved_err_prefix = err_print_prefix;
+		err_print_prefix = KERN_CRIT;
+
+		/*
+		 * Either a nondismissable error was detected or no
+		 * recognized error was detected  in the logout frame 
+		 * -- report the error in either case
+		 */
+		printk("%s*CPU %s Error (Vector 0x%x) reported on CPU %d:\n", 
+		       err_print_prefix,
+		       (vector == SCB_Q_PROCERR)?"Correctable":"Uncorrectable",
+		       (unsigned int)vector, (int)smp_processor_id());
+		
+		ev6_process_logout_frame(mchk_header, 1);
+		dik_show_regs(regs, NULL);
+
+		err_print_prefix = saved_err_prefix;
+	}
+
+	/* 
+	 * Release the logout frame 
+	 */
+	wrmces(0x7);
+	mb();
+}
+
+#endif /* CONFIG_ALPHA_GENERIC || CONFIG_ALPHA_EV6 */
+
+
+/*
+ * Console Data Log
+ */
+/* Data */
+static struct el_subpacket_handler *subpacket_handler_list = NULL;
+static struct el_subpacket_annotation *subpacket_annotation_list = NULL;
+
+static void
+el_print_timestamp(union el_timestamp timestamp)
+{
+	if (timestamp.as_int)
+		printk("%s  TIMESTAMP: %d/%d/%02d %d:%02d:%0d\n", 
+		       err_print_prefix,
+		       timestamp.b.month, timestamp.b.day,
+		       timestamp.b.year, timestamp.b.hour,
+		       timestamp.b.minute, timestamp.b.second);
+}
+
+static struct el_subpacket *
+el_process_header_subpacket(struct el_subpacket *header)
+{
+	union el_timestamp timestamp;
+	char *name = "UNKNOWN EVENT";
+	int packet_count = 0;
+	int length = 0;
+
+	if (header->class != EL_CLASS__HEADER) {
+		printk("%s** Unexpected header CLASS %d TYPE %d, aborting\n",
+		       err_print_prefix,
+		       header->class, header->type);
+		return NULL;
+	}
+
+	switch(header->type) {
+	case EL_TYPE__HEADER__SYSTEM_ERROR_FRAME:
+		name = "SYSTEM ERROR";
+		length = header->by_type.sys_err.frame_length;
+		packet_count = 
+			header->by_type.sys_err.frame_packet_count;
+		timestamp.as_int = 0;
+		break;
+	case EL_TYPE__HEADER__SYSTEM_EVENT_FRAME:
+		name = "SYSTEM EVENT";
+		length = header->by_type.sys_event.frame_length;
+		packet_count = 
+			header->by_type.sys_event.frame_packet_count;
+		timestamp = header->by_type.sys_event.timestamp;
+		break;
+	case EL_TYPE__HEADER__HALT_FRAME:
+		name = "ERROR HALT";
+		length = header->by_type.err_halt.frame_length;
+		packet_count = 
+			header->by_type.err_halt.frame_packet_count;
+		timestamp = header->by_type.err_halt.timestamp;
+		break;
+	case EL_TYPE__HEADER__LOGOUT_FRAME:
+		name = "LOGOUT FRAME";
+		length = header->by_type.logout_header.frame_length;
+		packet_count = 1;
+		timestamp.as_int = 0;
+		break;
+	default: /* Unknown */
+		printk("%s** Unknown header - CLASS %d TYPE %d, aborting\n",
+		       err_print_prefix,
+		       header->class, header->type);
+		return NULL;		
+	}
+
+	printk("%s*** %s:\n"
+	         "  CLASS %d, TYPE %d\n", 
+	       err_print_prefix,
+	       name,
+	       header->class, header->type);
+	el_print_timestamp(timestamp);
+	
+	/*
+	 * Process the subpackets
+	 */
+	el_process_subpackets(header, packet_count);
+
+	/* return the next header */
+	header = (struct el_subpacket *)
+		((unsigned long)header + header->length + length);
+	return header;
+}
+
+static void
+el_process_subpackets(struct el_subpacket *header, int packet_count)
+{
+	struct el_subpacket *subpacket;
+	int i;
+
+	subpacket = (struct el_subpacket *)
+		((unsigned long)header + header->length);
+
+	for(i = 0; subpacket && i < packet_count; i++) {
+		printk("%sPROCESSING SUBPACKET %d\n", err_print_prefix, i);
+		subpacket = el_process_subpacket(subpacket);
+	}
+}
+
+static struct el_subpacket *
+el_process_subpacket_reg(struct el_subpacket *header)
+{
+	struct el_subpacket *next = NULL;
+	struct el_subpacket_handler *h = subpacket_handler_list;
+
+	for(; h && h->class != header->class; h = h->next);
+	if (h) next = h->handler(header);
+
+	return next;
+}
+
+struct el_subpacket *
+el_process_subpacket(struct el_subpacket *header)
+{
+	struct el_subpacket *next = NULL;
+
+	switch(header->class) {
+	case EL_CLASS__TERMINATION:
+		/* Termination packet, there are no more */
+		break;
+	case EL_CLASS__HEADER: 
+		next = el_process_header_subpacket(header);
+		break;
+	default:
+		if (NULL == (next = el_process_subpacket_reg(header))) {
+			printk("%s** Unexpected header CLASS %d TYPE %d"
+			       " -- aborting.\n",
+			       err_print_prefix,
+			       header->class, header->type);
+		}
+		break;
+	}
+
+	return next;
+}
+
+void 
+el_annotate_subpacket(struct el_subpacket *header)
+{
+	struct el_subpacket_annotation *a;
+	char **annotation = NULL;
+
+	for(a = subpacket_annotation_list; a; a = a->next) {
+		if (a->class == header->class &&
+		    a->type == header->type &&
+		    a->revision == header->revision) {
+			/*
+			 * We found the annotation
+			 */
+			annotation = a->annotation;
+			printk("%s  %s\n", err_print_prefix, a->description);
+			break;
+		}
+	}
+
+	mchk_dump_mem(header, header->length, annotation);
+}
+
+static void __init
+cdl_process_console_data_log(int cpu, struct percpu_struct *pcpu)
+{
+	struct el_subpacket *header = (struct el_subpacket *)
+		(IDENT_ADDR | pcpu->console_data_log_pa);
+	int err;
+
+	printk("%s******* CONSOLE DATA LOG FOR CPU %d. *******\n"
+	         "*** Error(s) were logged on a previous boot\n",
+	       err_print_prefix, cpu);
+	
+	for(err = 0; header && (header->class != EL_CLASS__TERMINATION); err++)
+		header = el_process_subpacket(header);
+
+	/* let the console know it's ok to clear the error(s) at restart */
+	pcpu->console_data_log_pa = 0;
+
+	printk("%s*** %d total error(s) logged\n"
+	         "**** END OF CONSOLE DATA LOG FOR CPU %d ****\n", 
+	       err_print_prefix, err, cpu);
+}
+
+void __init
+cdl_check_console_data_log(void)
+{
+	struct percpu_struct *pcpu;
+	int cpu;
+
+	for(cpu = 0; cpu < hwrpb->nr_processors; cpu++) {
+		pcpu = (struct percpu_struct *)
+			((unsigned long)hwrpb + hwrpb->processor_offset 
+			 + cpu * hwrpb->processor_size);
+		if (pcpu->console_data_log_pa)
+			cdl_process_console_data_log(cpu, pcpu);
+	}
+
+}
+
+int __init
+cdl_register_subpacket_annotation(struct el_subpacket_annotation *new)
+{
+	struct el_subpacket_annotation *a = subpacket_annotation_list;
+
+	if (a == NULL) subpacket_annotation_list = new;
+	else {
+		for(; a->next != NULL; a = a->next) {
+			if ((a->class == new->class && a->type == new->type) ||
+			    a == new) {
+				printk("Attempted to re-register "
+				       "subpacket annotation\n");
+				return -EINVAL;
+			}
+		}
+		a->next = new;
+	}
+	new->next = NULL;
+
+	return 0;
+}
+
+int __init
+cdl_register_subpacket_handler(struct el_subpacket_handler *new)
+{
+	struct el_subpacket_handler *h = subpacket_handler_list;
+
+	if (h == NULL) subpacket_handler_list = new;
+	else {
+		for(; h->next != NULL; h = h->next) {
+			if (h->class == new->class || h == new) {
+				printk("Attempted to re-register "
+				       "subpacket handler\n");
+				return -EINVAL;
+			}
+		}
+		h->next = new;
+	}
+	new->next = NULL;
+
+	return 0;
+}
+
diff -Nru a/arch/alpha/kernel/err_impl.h b/arch/alpha/kernel/err_impl.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/alpha/kernel/err_impl.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,148 @@
+/*
+ *	linux/arch/alpha/kernel/err_impl.h
+ *
+ *	Copyright (C) 2000 Jeff Wiedemeier (Compaq Computer Corporation)
+ *
+ *	Contains declarations and macros to support Alpha error handling
+ * 	implementations.
+ */
+
+/*
+ * SCB Vector definitions
+ */
+#define SCB_Q_SYSERR	0x620
+#define SCB_Q_PROCERR	0x630
+#define SCB_Q_SYSMCHK	0x660
+#define SCB_Q_PROCMCHK	0x670
+#define SCB_Q_SYSEVENT	0x680
+
+/*
+ * Disposition definitions for logout frame parser
+ */
+#define MCHK_DISPOSITION_UNKNOWN_ERROR		0x00
+#define MCHK_DISPOSITION_REPORT			0x01
+#define MCHK_DISPOSITION_DISMISS		0x02
+
+/*
+ * Error Log definitions
+ */
+/*
+ * Types
+ */
+
+#define EL_CLASS__TERMINATION		(0)
+#  define EL_TYPE__TERMINATION__TERMINATION		(0)
+#define EL_CLASS__HEADER		(5)
+#  define EL_TYPE__HEADER__SYSTEM_ERROR_FRAME		(1)
+#  define EL_TYPE__HEADER__SYSTEM_EVENT_FRAME		(2)
+#  define EL_TYPE__HEADER__HALT_FRAME			(3)
+#  define EL_TYPE__HEADER__LOGOUT_FRAME			(19)
+#define EL_CLASS__GENERAL_NOTIFICATION	(9)
+#define EL_CLASS__PCI_ERROR_FRAME	(11)
+#define EL_CLASS__REGATTA_FAMILY	(12)
+#  define EL_TYPE__REGATTA__PROCESSOR_ERROR_FRAME	(1)
+#  define EL_TYPE__REGATTA__SYSTEM_ERROR_FRAME		(2)
+#  define EL_TYPE__REGATTA__ENVIRONMENTAL_FRAME		(3)
+#  define EL_TYPE__REGATTA__TITAN_PCHIP0_EXTENDED	(8)
+#  define EL_TYPE__REGATTA__TITAN_PCHIP1_EXTENDED	(9)
+#  define EL_TYPE__REGATTA__TITAN_MEMORY_EXTENDED	(10)
+#  define EL_TYPE__REGATTA__PROCESSOR_DBL_ERROR_HALT	(11)
+#  define EL_TYPE__REGATTA__SYSTEM_DBL_ERROR_HALT	(12)
+#define EL_CLASS__PAL                   (14)
+#  define EL_TYPE__PAL__LOGOUT_FRAME                    (1)
+#  define EL_TYPE__PAL__EV7_PROCESSOR			(4)
+#  define EL_TYPE__PAL__EV7_ZBOX			(5)
+#  define EL_TYPE__PAL__EV7_RBOX			(6)
+#  define EL_TYPE__PAL__EV7_IO				(7)
+
+union el_timestamp {
+	struct {
+		u8 second;
+		u8 minute;
+		u8 hour;
+		u8 day;
+		u8 month;
+		u8 year;
+	} b;
+	u64 as_int;
+};
+
+struct el_subpacket {
+	u16 length;		/* length of header (in bytes)	*/
+	u16 class;		/* header class and type...   	*/
+	u16 type;		/* ...determine content     	*/
+	u16 revision;		/* header revision 		*/
+	union {
+		struct {	/* Class 5, Type 1 - System Error	*/
+			u32 frame_length;
+			u32 frame_packet_count;			
+		} sys_err;			
+		struct {	/* Class 5, Type 2 - System Event 	*/
+			union el_timestamp timestamp;
+			u32 frame_length;
+			u32 frame_packet_count;			
+		} sys_event;
+		struct {	/* Class 5, Type 3 - Double Error Halt	*/
+			u16 halt_code;
+			u16 reserved;
+			union el_timestamp timestamp;
+			u32 frame_length;
+			u32 frame_packet_count;
+		} err_halt;
+		struct {	/* Clasee 5, Type 19 - Logout Frame Header */
+			u32 frame_length;
+			u32 frame_flags;
+			u32 cpu_offset;	
+			u32 system_offset;
+		} logout_header;
+		struct {	/* Class 12 - Regatta			*/
+			u64 cpuid;
+			u64 data_start[1];
+		} regatta_frame;
+		struct {	/* Raw 				        */
+			u64 data_start[1];
+		} raw;
+	} by_type;
+};
+
+struct el_subpacket_annotation {
+	struct el_subpacket_annotation *next;
+	u16 class;
+	u16 type;
+	u16 revision;
+	char *description;
+	char **annotation;
+};
+#define SUBPACKET_ANNOTATION(c, t, r, d, a) {NULL, (c), (t), (r), (d), (a)}
+
+struct el_subpacket_handler {
+	struct el_subpacket_handler *next;
+	u16 class;
+	struct el_subpacket *(*handler)(struct el_subpacket *);
+};
+#define SUBPACKET_HANDLER_INIT(c, h) {NULL, (c), (h)}
+
+/*
+ * Extract a field from a register given it's name. defines
+ * for the LSB (__S - shift count) and bitmask (__M) are required
+ */
+#define EXTRACT(u, f) (((u) >> f##__S) & f##__M)
+
+/*
+ * err_common.c
+ */
+extern char *err_print_prefix;
+
+extern void mchk_dump_mem(void *, int, char **);
+extern void mchk_dump_logout_frame(struct el_common *);
+extern void ev7_register_error_handlers(void);
+extern void ev7_machine_check(u64, u64, struct pt_regs *);
+extern void ev6_register_error_handlers(void);
+extern int ev6_process_logout_frame(struct el_common *, int);
+extern void ev6_machine_check(u64, u64, struct pt_regs *);
+extern struct el_subpacket *el_process_subpacket(struct el_subpacket *);
+extern void el_annotate_subpacket(struct el_subpacket *);
+extern void cdl_check_console_data_log(void);
+extern int cdl_register_subpacket_annotation(struct el_subpacket_annotation *);
+extern int cdl_register_subpacket_handler(struct el_subpacket_handler *);
+
diff -Nru a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
--- a/arch/alpha/kernel/irq.c	Mon Nov  4 14:31:02 2002
+++ b/arch/alpha/kernel/irq.c	Mon Nov  4 14:31:02 2002
@@ -528,7 +528,7 @@
 #else
 		for (j = 0; j < NR_CPUS; j++)
 			if (cpu_online(j))
-				seq_printf(p, "%10u ", kstat.irqs[j][i]);
+				seq_printf(p, "%10u ", kstat_cpu(i).irqs[j]);
 #endif
 		seq_printf(p, " %14s", irq_desc[i].handler->typename);
 		seq_printf(p, "  %c%s",
@@ -590,7 +590,7 @@
 	}
 
 	irq_enter();
-	kstat.irqs[cpu][irq]++;
+	kstat_cpu(cpu).irqs[irq]++;
 	spin_lock_irq(&desc->lock); /* mask also the higher prio events */
 	desc->handler->ack(irq);
 	/*
diff -Nru a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c
--- a/arch/alpha/kernel/irq_alpha.c	Mon Nov  4 14:31:01 2002
+++ b/arch/alpha/kernel/irq_alpha.c	Mon Nov  4 14:31:01 2002
@@ -59,7 +59,7 @@
 		smp_percpu_timer_interrupt(&regs);
 		cpu = smp_processor_id();
 		if (cpu != boot_cpuid) {
-		        kstat.irqs[cpu][RTC_IRQ]++;
+		        kstat_cpu(cpu).irqs[RTC_IRQ]++;
 		} else {
 			handle_irq(RTC_IRQ, &regs);
 		}
@@ -147,10 +147,10 @@
 
 	mchk_header = (struct el_common *)la_ptr;
 
-	printk(KERN_CRIT "%s machine check: vector=0x%lx pc=0x%lx code=0x%lx\n",
+	printk(KERN_CRIT "%s machine check: vector=0x%lx pc=0x%lx code=0x%x\n",
 	       machine, vector, regs->pc, mchk_header->code);
 
-	switch ((unsigned int) mchk_header->code) {
+	switch (mchk_header->code) {
 	/* Machine check reasons.  Defined according to PALcode sources.  */
 	case 0x80: reason = "tag parity error"; break;
 	case 0x82: reason = "tag control parity error"; break;
diff -Nru a/arch/alpha/kernel/irq_impl.h b/arch/alpha/kernel/irq_impl.h
--- a/arch/alpha/kernel/irq_impl.h	Mon Nov  4 14:31:03 2002
+++ b/arch/alpha/kernel/irq_impl.h	Mon Nov  4 14:31:03 2002
@@ -10,6 +10,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/profile.h>
 
 
 #define RTC_IRQ    8
diff -Nru a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
--- a/arch/alpha/kernel/osf_sys.c	Mon Nov  4 14:31:00 2002
+++ b/arch/alpha/kernel/osf_sys.c	Mon Nov  4 14:31:00 2002
@@ -844,7 +844,7 @@
 {
 	switch (op) {
 	case SSI_IEEE_FP_CONTROL: {
-		unsigned long swcr, fpcr;
+		unsigned long swcr, fpcr, fex;
 
 		/* 
 		 * Alpha Architecture Handbook 4.7.7.3:
@@ -867,9 +867,24 @@
 		wrfpcr(fpcr);
 
  		/* If any exceptions are now unmasked, send a signal.  */
- 		if (((swcr & IEEE_STATUS_MASK)
- 		     >> IEEE_STATUS_TO_EXCSUM_SHIFT) & swcr) {
- 			send_sig(SIGFPE, current, 1);
+		fex = ((swcr & IEEE_STATUS_MASK)
+		       >> IEEE_STATUS_TO_EXCSUM_SHIFT) & swcr;
+ 		if (fex) {
+			siginfo_t info;
+			int si_code = 0;
+
+			if (fex & IEEE_TRAP_ENABLE_DNO) si_code = FPE_FLTUND;
+			if (fex & IEEE_TRAP_ENABLE_INE) si_code = FPE_FLTRES;
+			if (fex & IEEE_TRAP_ENABLE_UNF) si_code = FPE_FLTUND;
+			if (fex & IEEE_TRAP_ENABLE_OVF) si_code = FPE_FLTOVF;
+			if (fex & IEEE_TRAP_ENABLE_DZE) si_code = FPE_FLTDIV;
+			if (fex & IEEE_TRAP_ENABLE_INV) si_code = FPE_FLTINV;
+
+			info.si_signo = SIGFPE;
+			info.si_errno = 0;
+			info.si_code = si_code;
+			info.si_addr = 0;  /* FIXME */
+ 			send_sig_info(SIGFPE, &info, current);
  		}
 
 		return 0;
diff -Nru a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
--- a/arch/alpha/kernel/pci.c	Mon Nov  4 14:31:00 2002
+++ b/arch/alpha/kernel/pci.c	Mon Nov  4 14:31:00 2002
@@ -117,6 +117,18 @@
 	}
 }
 
+/* Called for each device after PCI setup is done. */
+static void __init
+pcibios_fixup_final(struct pci_dev *dev)
+{
+	unsigned int class = dev->class >> 8;
+
+	if (class == PCI_CLASS_BRIDGE_ISA || class == PCI_CLASS_BRIDGE_ISA) {
+		dev->dma_mask = MAX_ISA_DMA_ADDRESS - 1;
+		isa_bridge = dev;
+	}
+}
+
 struct pci_fixup pcibios_fixups[] __initdata = {
 	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375,
 	  quirk_eisa_bridge },
@@ -126,6 +138,8 @@
 	  quirk_ali_ide_ports },
 	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693,
 	  quirk_cypress },
+	{ PCI_FIXUP_FINAL,  PCI_ANY_ID,	PCI_ANY_ID,
+	  pcibios_fixup_final },
 	{ 0 }
 };
 
diff -Nru a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
--- a/arch/alpha/kernel/pci_iommu.c	Mon Nov  4 14:31:02 2002
+++ b/arch/alpha/kernel/pci_iommu.c	Mon Nov  4 14:31:02 2002
@@ -30,9 +30,7 @@
 #define DEBUG_NODIRECT 0
 #define DEBUG_FORCEDAC 0
 
-/* Most Alphas support 32-bit ISA DMA. Exceptions are XL, Ruffian,
-   Nautilus, Sable, and Alcor (see asm-alpha/dma.h for details). */
-#define ISA_DMA_MASK	(MAX_DMA_ADDRESS - IDENT_ADDR - 1)
+#define ISA_DMA_MASK		0x00ffffff
 
 static inline unsigned long
 mk_iommu_pte(unsigned long paddr)
@@ -189,6 +187,7 @@
 	long npages, dma_ofs, i;
 	unsigned long paddr;
 	dma_addr_t ret;
+	unsigned int align = 0;
 
 	paddr = __pa(cpu_addr);
 
@@ -216,27 +215,27 @@
 	}
 
 	/* If the machine doesn't define a pci_tbi routine, we have to
-	   assume it doesn't support sg mapping.  */
+	   assume it doesn't support sg mapping, and, since we tried to
+	   use direct_map above, it now must be considered an error. */
 	if (! alpha_mv.mv_pci_tbi) {
-		static int been_here = 0;
+		static int been_here = 0; /* Only print the message once. */
 		if (!been_here) {
-		    printk(KERN_WARNING "pci_map_single: no hw sg, using "
-			   "direct map when possible\n");
+		    printk(KERN_WARNING "pci_map_single: no HW sg\n");
 		    been_here = 1;
 		}
-		if (paddr + size <= __direct_map_size)
-		    return (paddr + __direct_map_base);
-		else
-		    return 0;
+		return 0;
 	}
-		
+
 	arena = hose->sg_pci;
 	if (!arena || arena->dma_base + arena->size - 1 > max_dma)
 		arena = hose->sg_isa;
 
 	npages = calc_npages((paddr & ~PAGE_MASK) + size);
-	/* Force allocation to 64KB boundary for all ISA devices. */
-	dma_ofs = iommu_arena_alloc(arena, npages, pdev ? 8 : 0);
+
+	/* Force allocation to 64KB boundary for ISA bridges. */
+	if (pdev && pdev == isa_bridge)
+		align = 8;
+	dma_ofs = iommu_arena_alloc(arena, npages, align);
 	if (dma_ofs < 0) {
 		printk(KERN_WARNING "pci_map_single failed: "
 		       "could not allocate dma page tables\n");
@@ -364,8 +363,10 @@
 {
 	void *cpu_addr;
 	long order = get_order(size);
+	int gfp = GFP_ATOMIC;
 
-	cpu_addr = (void *)__get_free_pages(GFP_ATOMIC, order);
+try_again:
+	cpu_addr = (void *)__get_free_pages(gfp, order);
 	if (! cpu_addr) {
 		printk(KERN_INFO "pci_alloc_consistent: "
 		       "get_free_pages failed from %p\n",
@@ -379,7 +380,12 @@
 	*dma_addrp = pci_map_single_1(pdev, cpu_addr, size, 0);
 	if (*dma_addrp == 0) {
 		free_pages((unsigned long)cpu_addr, order);
-		return NULL;
+		if (alpha_mv.mv_pci_tbi || (gfp & GFP_DMA))
+			return NULL;
+		/* The address doesn't fit required mask and we
+		   do not have iommu. Try again with GFP_DMA. */
+		gfp |= GFP_DMA;
+		goto try_again;
 	}
 		
 	DBGA2("pci_alloc_consistent: %lx -> [%p,%x] from %p\n",
@@ -727,8 +733,8 @@
 	   the entire direct mapped space or the total system memory as
 	   shifted by the map base */
 	if (__direct_map_size != 0
-	    && (__direct_map_base + __direct_map_size - 1 <= mask
-		|| __direct_map_base + (max_low_pfn<<PAGE_SHIFT)-1 <= mask))
+	    && (__direct_map_base + __direct_map_size - 1 <= mask ||
+		__direct_map_base + (max_low_pfn << PAGE_SHIFT) - 1 <= mask))
 		return 1;
 
 	/* Check that we have a scatter-gather arena that fits.  */
@@ -738,6 +744,10 @@
 		return 1;
 	arena = hose->sg_pci;
 	if (arena && arena->dma_base + arena->size - 1 <= mask)
+		return 1;
+
+	/* As last resort try ZONE_DMA.  */
+	if (!__direct_map_base && MAX_DMA_ADDRESS - IDENT_ADDR - 1 <= mask)
 		return 1;
 
 	return 0;
diff -Nru a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
--- a/arch/alpha/kernel/process.c	Mon Nov  4 14:31:02 2002
+++ b/arch/alpha/kernel/process.c	Mon Nov  4 14:31:02 2002
@@ -245,11 +245,10 @@
  */
 int
 alpha_clone(unsigned long clone_flags, unsigned long usp,
-	    struct switch_stack * swstack)
+	    int *user_tid, struct switch_stack * swstack)
 {
 	struct task_struct *p;
 	struct pt_regs *u_regs = (struct pt_regs *) (swstack+1);
-	int *user_tid = (int *)u_regs->r19;
 
 	if (!usp)
 		usp = rdusp();
@@ -313,6 +312,16 @@
 	childti->pcb.usp = usp;
 	childti->pcb.ksp = (unsigned long) childstack;
 	childti->pcb.flags = 1;	/* set FEN, clear everything else */
+
+	/* Set a new TLS for the child thread?  Peek back into the
+	   syscall arguments that we saved on syscall entry.  */
+	/* Note: if CLONE_SETTLS is not set, then we must inherit the
+	   value from the parent, which will have been set by the block
+	   copy in dup_task_struct.  This is non-intuitive, but is
+	   required for proper operation in the case of a threaded
+	   application calling fork.  */
+	if (clone_flags & CLONE_SETTLS)
+		childti->pcb.unique = regs->r19;
 
 	return 0;
 }
diff -Nru a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h
--- a/arch/alpha/kernel/proto.h	Mon Nov  4 14:31:01 2002
+++ b/arch/alpha/kernel/proto.h	Mon Nov  4 14:31:01 2002
@@ -24,6 +24,7 @@
 extern void cia_init_pci(void);
 extern void cia_init_arch(void);
 extern void pyxis_init_arch(void);
+extern void cia_kill_arch(int);
 extern void cia_machine_check(u64, u64, struct pt_regs *);
 extern void cia_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 
diff -Nru a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
--- a/arch/alpha/kernel/ptrace.c	Mon Nov  4 14:31:02 2002
+++ b/arch/alpha/kernel/ptrace.c	Mon Nov  4 14:31:02 2002
@@ -383,7 +383,7 @@
 		goto out;
 
 	default:
-		ret = -EIO;
+		ret = ptrace_request(child, request, addr, data);
 		goto out;
 	}
  out:
@@ -400,7 +400,8 @@
 		return;
 	if (!(current->ptrace & PT_PTRACED))
 		return;
-	current->exit_code = SIGTRAP;
+	current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+					? 0x80 : 0);
 	current->state = TASK_STOPPED;
 	notify_parent(current, SIGCHLD);
 	schedule();
diff -Nru a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
--- a/arch/alpha/kernel/signal.c	Mon Nov  4 14:31:01 2002
+++ b/arch/alpha/kernel/signal.c	Mon Nov  4 14:31:01 2002
@@ -293,8 +293,16 @@
 		goto give_sigsegv;
 
 	/* Send SIGTRAP if we're single-stepping: */
-	if (ptrace_cancel_bpt (current))
-		send_sig(SIGTRAP, current, 1);
+	if (ptrace_cancel_bpt (current)) {
+		siginfo_t info;
+
+		info.si_signo = SIGTRAP;
+		info.si_errno = 0;
+		info.si_code = TRAP_BRKPT;
+		info.si_addr = (void *) regs->pc;
+		info.si_trapno = 0;
+		send_sig_info(SIGTRAP, &info, current);
+	}
 	return;
 
 give_sigsegv:
@@ -330,8 +338,16 @@
 	do_sigaltstack(&st, NULL, rdusp());
 
 	/* Send SIGTRAP if we're single-stepping: */
-	if (ptrace_cancel_bpt (current))
-		send_sig(SIGTRAP, current, 1);
+	if (ptrace_cancel_bpt (current)) {
+		siginfo_t info;
+
+		info.si_signo = SIGTRAP;
+		info.si_errno = 0;
+		info.si_code = TRAP_BRKPT;
+		info.si_addr = (void *) regs->pc;
+		info.si_trapno = 0;
+		send_sig_info(SIGTRAP, &info, current);
+	}
 	return;
 
 give_sigsegv:
diff -Nru a/arch/alpha/kernel/sys_alcor.c b/arch/alpha/kernel/sys_alcor.c
--- a/arch/alpha/kernel/sys_alcor.c	Mon Nov  4 14:31:01 2002
+++ b/arch/alpha/kernel/sys_alcor.c	Mon Nov  4 14:31:01 2002
@@ -221,6 +221,8 @@
 static void
 alcor_kill_arch(int mode)
 {
+	cia_kill_arch(mode);
+
 	switch(mode) {
 	case LINUX_REBOOT_CMD_RESTART:
 		/* Who said DEC engineer's have no sense of humor? ;-)  */
@@ -251,7 +253,7 @@
 	DO_CIA_IO,
 	DO_CIA_BUS,
 	.machine_check		= cia_machine_check,
-	.max_dma_address	= ALPHA_ALCOR_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_ALCOR_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= EISA_DEFAULT_IO_BASE,
 	.min_mem_address	= CIA_DEFAULT_MEM_BASE,
 
@@ -281,7 +283,7 @@
 	DO_CIA_IO,
 	DO_CIA_BUS,
 	.machine_check		= cia_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= EISA_DEFAULT_IO_BASE,
 	.min_mem_address	= CIA_DEFAULT_MEM_BASE,
 
diff -Nru a/arch/alpha/kernel/sys_cabriolet.c b/arch/alpha/kernel/sys_cabriolet.c
--- a/arch/alpha/kernel/sys_cabriolet.c	Mon Nov  4 14:31:01 2002
+++ b/arch/alpha/kernel/sys_cabriolet.c	Mon Nov  4 14:31:01 2002
@@ -327,7 +327,7 @@
 	DO_APECS_IO,
 	DO_APECS_BUS,
 	.machine_check		= apecs_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= APECS_AND_LCA_DEFAULT_MEM_BASE,
 
@@ -338,7 +338,6 @@
 	.init_irq		= cabriolet_init_irq,
 	.init_rtc		= common_init_rtc,
 	.init_pci		= cabriolet_init_pci,
-	.kill_arch		= NULL,
 	.pci_map_irq		= cabriolet_map_irq,
 	.pci_swizzle		= common_swizzle,
 };
@@ -355,7 +354,7 @@
 	DO_CIA_IO,
 	DO_CIA_BUS,
 	.machine_check		= cia_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= CIA_DEFAULT_MEM_BASE,
 
@@ -366,6 +365,7 @@
 	.init_irq		= cabriolet_init_irq,
 	.init_rtc		= common_init_rtc,
 	.init_pci		= cia_cab_init_pci,
+	.kill_arch		= cia_kill_arch,
 	.pci_map_irq		= cabriolet_map_irq,
 	.pci_swizzle		= common_swizzle,
 };
@@ -380,7 +380,7 @@
 	DO_LCA_IO,
 	DO_LCA_BUS,
 	.machine_check		= lca_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= APECS_AND_LCA_DEFAULT_MEM_BASE,
 
@@ -405,7 +405,7 @@
 	DO_PYXIS_IO,
 	DO_CIA_BUS,
 	.machine_check		= cia_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= DEFAULT_MEM_BASE,
 	.pci_dac_offset		= PYXIS_DAC_OFFSET,
@@ -417,6 +417,7 @@
 	.init_irq		= cabriolet_init_irq,
 	.init_rtc		= common_init_rtc,
 	.init_pci		= alphapc164_init_pci,
+	.kill_arch		= cia_kill_arch,
 	.pci_map_irq		= alphapc164_map_irq,
 	.pci_swizzle		= common_swizzle,
 };
@@ -431,7 +432,7 @@
 	DO_CIA_IO,
 	DO_CIA_BUS,
 	.machine_check		= cia_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= CIA_DEFAULT_MEM_BASE,
 
@@ -442,6 +443,7 @@
 	.init_irq		= pc164_init_irq,
 	.init_rtc		= common_init_rtc,
 	.init_pci		= alphapc164_init_pci,
+	.kill_arch		= cia_kill_arch,
 	.pci_map_irq		= alphapc164_map_irq,
 	.pci_swizzle		= common_swizzle,
 };
diff -Nru a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c
--- a/arch/alpha/kernel/sys_dp264.c	Mon Nov  4 14:31:01 2002
+++ b/arch/alpha/kernel/sys_dp264.c	Mon Nov  4 14:31:01 2002
@@ -572,7 +572,7 @@
 	DO_TSUNAMI_IO,
 	DO_TSUNAMI_BUS,
 	.machine_check		= tsunami_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= DEFAULT_MEM_BASE,
 	.pci_dac_offset		= TSUNAMI_DAC_OFFSET,
@@ -597,7 +597,7 @@
 	DO_TSUNAMI_IO,
 	DO_TSUNAMI_BUS,
 	.machine_check		= tsunami_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= DEFAULT_MEM_BASE,
 	.pci_dac_offset		= TSUNAMI_DAC_OFFSET,
@@ -621,7 +621,7 @@
 	DO_TSUNAMI_IO,
 	DO_TSUNAMI_BUS,
 	.machine_check		= tsunami_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= DEFAULT_MEM_BASE,
 	.pci_dac_offset		= TSUNAMI_DAC_OFFSET,
@@ -645,7 +645,7 @@
 	DO_TSUNAMI_IO,
 	DO_TSUNAMI_BUS,
 	.machine_check		= tsunami_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= DEFAULT_MEM_BASE,
 	.pci_dac_offset		= TSUNAMI_DAC_OFFSET,
@@ -674,7 +674,7 @@
 	DO_TSUNAMI_IO,
 	DO_TSUNAMI_BUS,
 	.machine_check		= tsunami_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= DEFAULT_MEM_BASE,
 	.pci_dac_offset		= TSUNAMI_DAC_OFFSET,
diff -Nru a/arch/alpha/kernel/sys_eb64p.c b/arch/alpha/kernel/sys_eb64p.c
--- a/arch/alpha/kernel/sys_eb64p.c	Mon Nov  4 14:31:02 2002
+++ b/arch/alpha/kernel/sys_eb64p.c	Mon Nov  4 14:31:02 2002
@@ -214,7 +214,7 @@
 	DO_APECS_IO,
 	DO_APECS_BUS,
 	.machine_check		= apecs_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= APECS_AND_LCA_DEFAULT_MEM_BASE,
 
@@ -240,7 +240,7 @@
 	DO_LCA_IO,
 	DO_LCA_BUS,
 	.machine_check		= lca_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= APECS_AND_LCA_DEFAULT_MEM_BASE,
 
diff -Nru a/arch/alpha/kernel/sys_eiger.c b/arch/alpha/kernel/sys_eiger.c
--- a/arch/alpha/kernel/sys_eiger.c	Mon Nov  4 14:31:00 2002
+++ b/arch/alpha/kernel/sys_eiger.c	Mon Nov  4 14:31:00 2002
@@ -231,7 +231,7 @@
 	DO_TSUNAMI_IO,
 	DO_TSUNAMI_BUS,
 	.machine_check		= tsunami_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= DEFAULT_MEM_BASE,
 	.pci_dac_offset		= TSUNAMI_DAC_OFFSET,
diff -Nru a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c
--- a/arch/alpha/kernel/sys_jensen.c	Mon Nov  4 14:31:02 2002
+++ b/arch/alpha/kernel/sys_jensen.c	Mon Nov  4 14:31:02 2002
@@ -219,6 +219,11 @@
 jensen_init_arch(void)
 {
 	struct pci_controller *hose;
+#ifdef CONFIG_PCI
+	static struct pci_dev fake_isa_bridge = { dma_mask: 0xffffffffUL, };
+
+	isa_bridge = &fake_isa_bridge;
+#endif
 
 	/* Create a hose so that we can report i/o base addresses to
 	   userland.  */
@@ -257,7 +262,7 @@
 	IO_LITE(JENSEN,jensen),
 	BUS(jensen),
 	.machine_check		= jensen_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.rtc_port		= 0x170,
 
 	.nr_irqs		= 16,
diff -Nru a/arch/alpha/kernel/sys_miata.c b/arch/alpha/kernel/sys_miata.c
--- a/arch/alpha/kernel/sys_miata.c	Mon Nov  4 14:31:02 2002
+++ b/arch/alpha/kernel/sys_miata.c	Mon Nov  4 14:31:02 2002
@@ -238,6 +238,8 @@
 static void
 miata_kill_arch(int mode)
 {
+	cia_kill_arch(mode);
+
 	switch(mode) {
 	case LINUX_REBOOT_CMD_RESTART:
 		/* Who said DEC engineers have no sense of humor? ;-)  */ 
@@ -267,7 +269,7 @@
 	DO_PYXIS_IO,
 	DO_CIA_BUS,
 	.machine_check		= cia_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= DEFAULT_MEM_BASE,
 	.pci_dac_offset		= PYXIS_DAC_OFFSET,
diff -Nru a/arch/alpha/kernel/sys_mikasa.c b/arch/alpha/kernel/sys_mikasa.c
--- a/arch/alpha/kernel/sys_mikasa.c	Mon Nov  4 14:31:02 2002
+++ b/arch/alpha/kernel/sys_mikasa.c	Mon Nov  4 14:31:02 2002
@@ -223,7 +223,7 @@
 	DO_APECS_IO,
 	DO_APECS_BUS,
 	.machine_check		= mikasa_apecs_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= APECS_AND_LCA_DEFAULT_MEM_BASE,
 
@@ -234,7 +234,6 @@
 	.init_irq		= mikasa_init_irq,
 	.init_rtc		= common_init_rtc,
 	.init_pci		= common_init_pci,
-	.kill_arch		= NULL,
 	.pci_map_irq		= mikasa_map_irq,
 	.pci_swizzle		= common_swizzle,
 };
@@ -249,7 +248,7 @@
 	DO_CIA_IO,
 	DO_CIA_BUS,
 	.machine_check		= cia_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= CIA_DEFAULT_MEM_BASE,
 
@@ -260,6 +259,7 @@
 	.init_irq		= mikasa_init_irq,
 	.init_rtc		= common_init_rtc,
 	.init_pci		= cia_init_pci,
+	.kill_arch		= cia_kill_arch,
 	.pci_map_irq		= mikasa_map_irq,
 	.pci_swizzle		= common_swizzle,
 };
diff -Nru a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c
--- a/arch/alpha/kernel/sys_nautilus.c	Mon Nov  4 14:31:01 2002
+++ b/arch/alpha/kernel/sys_nautilus.c	Mon Nov  4 14:31:01 2002
@@ -46,6 +46,7 @@
 #include <asm/tlbflush.h>
 
 #include "proto.h"
+#include "err_impl.h"
 #include "irq_impl.h"
 #include "pci_impl.h"
 #include "machvec_impl.h"
@@ -100,317 +101,6 @@
 	}
 }
 
-/* Machine check handler code
- *
- * Perform analysis of a machine check that was triggered by the EV6
- * CPU's fault-detection mechanism.
- */
-
-/* IPR structures for EV6, containing the necessary data for the
- * machine check handler to unpick the logout frame
- */
-
-/* I_STAT */
-
-#define EV6__I_STAT__PAR                ( 1 << 29 )
-
-/* MM_STAT */
-
-#define EV6__MM_STAT__DC_TAG_PERR       ( 1 << 10 )
-
-/* DC_STAT */
-
-#define EV6__DC_STAT__SEO               ( 1 << 4 )
-#define EV6__DC_STAT__ECC_ERR_LD        ( 1 << 3 )
-#define EV6__DC_STAT__ECC_ERR_ST        ( 1 << 2 )
-#define EV6__DC_STAT__TPERR_P1          ( 1 << 1 )
-#define EV6__DC_STAT__TPERR_P0          ( 1      )
-
-/* C_STAT */
-
-#define EV6__C_STAT__BC_PERR            ( 0x01 )
-#define EV6__C_STAT__DC_PERR            ( 0x02 )
-#define EV6__C_STAT__DSTREAM_MEM_ERR    ( 0x03 )
-#define EV6__C_STAT__DSTREAM_BC_ERR     ( 0x04 )
-#define EV6__C_STAT__DSTREAM_DC_ERR     ( 0x05 )
-#define EV6__C_STAT__PROBE_BC_ERR0      ( 0x06 )
-#define EV6__C_STAT__PROBE_BC_ERR1      ( 0x07 )
-#define EV6__C_STAT__ISTREAM_MEM_ERR    ( 0x0B )
-#define EV6__C_STAT__ISTREAM_BC_ERR     ( 0x0C )
-#define EV6__C_STAT__DSTREAM_MEM_DBL    ( 0x13 )
-#define EV6__C_STAT__DSTREAM_BC_DBL     ( 0x14 )
-#define EV6__C_STAT__ISTREAM_MEM_DBL    ( 0x1B )
-#define EV6__C_STAT__ISTREAM_BC_DBL     ( 0x1C )
-
-
-/* Take the two syndromes from the CBOX error chain and convert them
- * into a bit number.  */
-
-/* NOTE - since I don't know of any difference between C0 and C1 I
-   just ignore C1, since in all cases I've seen so far they are
-   identical.  */
-
-static const unsigned char ev6_bit_to_syndrome[72] =
-{
-	0xce, 0xcb, 0xd3, 0xd5, 0xd6, 0xd9, 0xda, 0xdc,     /* 0 */
-	0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x31, 0x34,     /* 8 */
-	0x0e, 0x0b, 0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c,     /* 16 */
-	0xe3, 0xe5, 0xe6, 0xe9, 0xea, 0xec, 0xf1, 0xf4,     /* 24 */
-	0x4f, 0x4a, 0x52, 0x54, 0x57, 0x58, 0x5b, 0x5d,     /* 32 */
-	0xa2, 0xa4, 0xa7, 0xa8, 0xab, 0xad, 0xb0, 0xb5,     /* 40 */
-	0x8f, 0x8a, 0x92, 0x94, 0x97, 0x98, 0x9b, 0x9d,     /* 48 */
-	0x62, 0x64, 0x67, 0x68, 0x6b, 0x6d, 0x70, 0x75,     /* 56 */
-	0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80      /* 64 */
-};
-
-
-static int ev6_syn2bit(unsigned long c0, unsigned long c1)
-{
-	int bit;
-
-	for (bit = 0; bit < 72; bit++)
-		if (ev6_bit_to_syndrome[bit] == c0)	return bit;
-	for (bit = 0; bit < 72; bit++)
-		if (ev6_bit_to_syndrome[bit] == c1)	return bit + 64;
-
-	return -1;                  /* not found */
-}
-
-
-/* Single bit ECC errors are categorized here.  */
-
-#if 0
-static const char *interr = "CPU internal error";
-static const char *slotb= "Slot-B error";
-static const char *membus= "Memory/EV6-bus error";
-#else
-static const char *interr = "";
-static const char *slotb = "";
-static const char *membus = "";
-#endif
-
-static void
-ev6_crd_interp(char *interp, struct el_common_EV6_mcheck * L)
-{
-	/* Icache data or tag parity error.  */
-	if (L->I_STAT & EV6__I_STAT__PAR) {
-		sprintf(interp, "%s: I_STAT[PAR]\n "
-			"Icache data or tag parity error", interr);
-		return;
-	}
-
-	/* Dcache tag parity error (on issue) (DFAULT).  */
-	if (L->MM_STAT & EV6__MM_STAT__DC_TAG_PERR) {
-		sprintf(interp, "%s: MM_STAT[DC_TAG_PERR]\n "
-			"Dcache tag parity error(on issue)", interr);
-		return;
-	}
-
-	/* Errors relating to D-stream set non-zero DC_STAT.
-	   Mask CRD bits.  */
-	switch (L->DC_STAT & (EV6__DC_STAT__ECC_ERR_ST
-			      | EV6__DC_STAT__ECC_ERR_LD)) {
-	case EV6__DC_STAT__ECC_ERR_ST:
-		/* Dcache single-bit ECC error on small store */
-		sprintf(interp, "%s: DC_STAT[ECC_ERR_ST]\n "
-			"Dcache single-bit ECC error on small store", interr);
-		return;
-
-	case EV6__DC_STAT__ECC_ERR_LD:
-		switch (L->C_STAT) {
-		case 0:
-			/* Dcache single-bit error on speculative load */
-			/* Bcache victim read on Dcache/Bcache miss */
-			sprintf(interp, "%s: DC_STAT[ECC_ERR_LD] C_STAT=0\n "
-				"Dcache single-bit ECC error on speculative load",
-				slotb);
-			return;
-
-		case EV6__C_STAT__DSTREAM_DC_ERR:
-			/* Dcache single bit error on load */
-			sprintf(interp, "%s: DC_STAT[ECC_ERR_LD] C_STAT[DSTREAM_DC_ERR]\n"
-				" Dcache single-bit ECC error on speculative load, bit %d",
-				interr, ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
-			return;
-
-		case EV6__C_STAT__DSTREAM_BC_ERR:
-			/* Bcache single-bit error on Dcache fill */
-			sprintf(interp, "%s: DC_STAT[ECC_ERR_LD] C_STAT[DSTREAM_BC_ERR]\n"
-				" Bcache single-bit error on Dcache fill, bit %d",
-				slotb, ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
-			return;
-
-		case EV6__C_STAT__DSTREAM_MEM_ERR:
-			/* Memory single-bit error on Dcache fill */
-			sprintf(interp, "%s (to Dcache): DC_STAT[ECC_ERR_LD] "
-				"C_STAT[DSTREAM_MEM_ERR]\n "
-				"Memory single-bit error on Dcache fill, "
-				"Address 0x%lX, bit %d",
-				membus, L->C_ADDR, ev6_syn2bit(L->DC0_SYNDROME,
-							       L->DC1_SYNDROME));
-			return;
-		}
-	}
-
-	/* I-stream, other misc errors go on C_STAT alone */
-	switch (L->C_STAT) {
-	case EV6__C_STAT__ISTREAM_BC_ERR:
-		/* Bcache single-bit error on Icache fill (also MCHK) */
-		sprintf(interp, "%s: C_STAT[ISTREAM_BC_ERR]\n "
-			"Bcache single-bit error on Icache fill, bit %d",
-			slotb, ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
-		return;
-
-	case EV6__C_STAT__ISTREAM_MEM_ERR:
-		/* Memory single-bit error on Icache fill (also MCHK) */
-		sprintf(interp, "%s : C_STATISTREAM_MEM_ERR]\n "
-			"Memory single-bit error on Icache fill "
-			"addr 0x%lX, bit %d",
-			membus, L->C_ADDR, ev6_syn2bit(L->DC0_SYNDROME,
-						       L->DC1_SYNDROME));
-		return;
-
-	case EV6__C_STAT__PROBE_BC_ERR0:
-	case EV6__C_STAT__PROBE_BC_ERR1:
-		/* Bcache single-bit error on a probe hit */
-		sprintf(interp, "%s: C_STAT[PROBE_BC_ERR]\n "
-			"Bcache single-bit error on a probe hit, "
-			"addr 0x%lx, bit %d",
-			slotb, L->C_ADDR, ev6_syn2bit(L->DC0_SYNDROME,
-						      L->DC1_SYNDROME));
-		return;
-	}
-}
-
-static void
-ev6_mchk_interp(char *interp, struct el_common_EV6_mcheck * L)
-{
-	/* Machine check errors described by DC_STAT */
-	switch (L->DC_STAT) {
-	case EV6__DC_STAT__TPERR_P0:
-	case EV6__DC_STAT__TPERR_P1:
-		/* Dcache tag parity error (on retry) */
-		sprintf(interp, "%s: DC_STAT[TPERR_P0|TPERR_P1]\n "
-			"Dcache tag parity error(on retry)", interr);
-		return;
-
-	case EV6__DC_STAT__SEO:
-		/* Dcache second error on store */
-		sprintf(interp, "%s: DC_STAT[SEO]\n "
-			"Dcache second error during mcheck", interr);
-		return;
-	}
-
-	/* Machine check errors described by C_STAT */
-	switch (L->C_STAT) {
-	case EV6__C_STAT__DC_PERR:
-		/* Dcache duplicate tag parity error */
-		sprintf(interp, "%s: C_STAT[DC_PERR]\n "
-			"Dcache duplicate tag parity error at 0x%lX",
-			interr, L->C_ADDR);
-		return;
-
-	case EV6__C_STAT__BC_PERR:
-		/* Bcache tag parity error */
-		sprintf(interp, "%s: C_STAT[BC_PERR]\n "
-			"Bcache tag parity error at 0x%lX",
-			slotb, L->C_ADDR);
-		return;
-
-	case EV6__C_STAT__ISTREAM_BC_ERR:
-		/* Bcache single-bit error on Icache fill (also CRD) */
-		sprintf(interp, "%s: C_STAT[ISTREAM_BC_ERR]\n "
-			"Bcache single-bit error on Icache fill 0x%lX bit %d",
-			slotb, L->C_ADDR,
-			ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
-		return;
-
-
-	case EV6__C_STAT__ISTREAM_MEM_ERR:
-		/* Memory single-bit error on Icache fill (also CRD) */
-		sprintf(interp, "%s: C_STAT[ISTREAM_MEM_ERR]\n "
-			"Memory single-bit error on Icache fill 0x%lX, bit %d",
-			membus, L->C_ADDR,
-			ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
-		return;
-
-
-	case EV6__C_STAT__ISTREAM_BC_DBL:
-		/* Bcache double-bit error on Icache fill */
-		sprintf(interp, "%s: C_STAT[ISTREAM_BC_DBL]\n "
-			"Bcache double-bit error on Icache fill at 0x%lX",
-			slotb, L->C_ADDR);
-		return;
-	case EV6__C_STAT__DSTREAM_BC_DBL:
-		/* Bcache double-bit error on Dcache fill */
-		sprintf(interp, "%s: C_STAT[DSTREAM_BC_DBL]\n "
-			"Bcache double-bit error on Dcache fill at 0x%lX",
-			slotb, L->C_ADDR);
-		return;
-
-	case EV6__C_STAT__ISTREAM_MEM_DBL:
-		/* Memory double-bit error on Icache fill */
-		sprintf(interp, "%s: C_STAT[ISTREAM_MEM_DBL]\n "
-			"Memory double-bit error on Icache fill at 0x%lX",
-			membus, L->C_ADDR);
-		return;
-
-	case EV6__C_STAT__DSTREAM_MEM_DBL:
-		/* Memory double-bit error on Dcache fill */
-		sprintf(interp, "%s: C_STAT[DSTREAM_MEM_DBL]\n "
-			"Memory double-bit error on Dcache fill at 0x%lX",
-			membus, L->C_ADDR);
-		return;
-	}
-}
-
-static void
-ev6_cpu_machine_check(unsigned long vector, struct el_common_EV6_mcheck *L,
-		      struct pt_regs *regs)
-{
-	char interp[80];
-
-	/* This is verbose and looks intimidating.  Should it be printed for
-	   corrected (CRD) machine checks? */
-
-	printk(KERN_CRIT "PALcode logout frame:  "
-	       "MCHK_Code       %d  "
-	       "MCHK_Frame_Rev  %d\n"
-	       "I_STAT  %016lx  "
-	       "DC_STAT %016lx  "
-	       "C_ADDR  %016lx\n"
-	       "SYND1   %016lx  "
-	       "SYND0   %016lx  "
-	       "C_STAT  %016lx\n"
-	       "C_STS   %016lx  "
-	       "RES     %016lx  "
-	       "EXC_ADDR%016lx\n"
-	       "IER_CM  %016lx  "
-	       "ISUM    %016lx  "
-	       "MM_STAT %016lx\n"
-	       "PALBASE %016lx  "
-	       "I_CTL   %016lx  "
-	       "PCTX    %016lx\n"
-	       "CPU registers: "
-	       "PC      %016lx  "
-	       "Return  %016lx\n",
-	       L->MCHK_Code, L->MCHK_Frame_Rev, L->I_STAT, L->DC_STAT,
-	       L->C_ADDR, L->DC1_SYNDROME, L->DC0_SYNDROME, L->C_STAT,
-	       L->C_STS, L->RESERVED0, L->EXC_ADDR, L->IER_CM, L->ISUM,
-	       L->MM_STAT, L->PAL_BASE, L->I_CTL, L->PCTX,
-	       regs->pc, regs->r26);
-
-	/* Attempt an interpretation on the meanings of the fields above.  */
-	sprintf(interp, "No interpretation available!" );
-	if (vector == SCB_Q_PROCERR)
-		ev6_crd_interp(interp, L);
-	else if (vector == SCB_Q_PROCMCHK)
-		ev6_mchk_interp(interp, L);
-
-	printk(KERN_CRIT "interpretation: %s\n\n", interp);
-}
-
-
 /* Perform analysis of a machine check that arrived from the system (NMI) */
 
 static void
@@ -430,7 +120,6 @@
 		       struct pt_regs *regs)
 {
 	char *mchk_class;
-	unsigned cpu_analysis=0, sys_analysis=0;
 
 	/* Now for some analysis.  Machine checks fall into two classes --
 	   those picked up by the system, and those picked up by the CPU.
@@ -463,39 +152,20 @@
 		return;
 	}
 
-	switch (vector) {
-	case SCB_Q_SYSERR:
-		mchk_class = "Correctable System Machine Check (NMI)";
-		sys_analysis = 1;
-		break;
-	case SCB_Q_SYSMCHK:
-		mchk_class = "Fatal System Machine Check (NMI)";
-		sys_analysis = 1;
-		break;
-
-	case SCB_Q_PROCERR:
-		mchk_class = "Correctable Processor Machine Check";
-		cpu_analysis = 1;
-		break;
-	case SCB_Q_PROCMCHK:
-		mchk_class = "Fatal Processor Machine Check";
-		cpu_analysis = 1;
-		break;
-
-	default:
-		mchk_class = "Unknown vector!";
-		break;
+	if (vector == SCB_Q_SYSERR)
+		mchk_class = "Correctable";
+	else if (vector == SCB_Q_SYSMCHK)
+		mchk_class = "Fatal";
+	else {
+		ev6_machine_check(vector, la_ptr, regs);
+		return;
 	}
 
-	printk(KERN_CRIT "NAUTILUS Machine check 0x%lx [%s]\n",
+	printk(KERN_CRIT "NAUTILUS Machine check 0x%lx "
+			 "[%s  System Machine Check (NMI)]\n",
 	       vector, mchk_class);
 
-	if (cpu_analysis)
-		ev6_cpu_machine_check(vector,
-				      (struct el_common_EV6_mcheck *)la_ptr,
-				      regs);
-	if (sys_analysis)
-		naut_sys_machine_check(vector, la_ptr, regs);
+	naut_sys_machine_check(vector, la_ptr, regs);
 
 	/* Tell the PALcode to clear the machine check */
 	draina();
@@ -504,7 +174,6 @@
 }
 
 
-
 /*
  * The System Vectors
  */
@@ -516,7 +185,7 @@
 	DO_IRONGATE_IO,
 	DO_IRONGATE_BUS,
 	.machine_check		= nautilus_machine_check,
-	.max_dma_address	= ALPHA_NAUTILUS_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= IRONGATE_DEFAULT_MEM_BASE,
 
diff -Nru a/arch/alpha/kernel/sys_noritake.c b/arch/alpha/kernel/sys_noritake.c
--- a/arch/alpha/kernel/sys_noritake.c	Mon Nov  4 14:31:01 2002
+++ b/arch/alpha/kernel/sys_noritake.c	Mon Nov  4 14:31:01 2002
@@ -305,7 +305,7 @@
 	DO_APECS_IO,
 	DO_APECS_BUS,
 	.machine_check		= noritake_apecs_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= EISA_DEFAULT_IO_BASE,
 	.min_mem_address	= APECS_AND_LCA_DEFAULT_MEM_BASE,
 
@@ -316,7 +316,6 @@
 	.init_irq		= noritake_init_irq,
 	.init_rtc		= common_init_rtc,
 	.init_pci		= common_init_pci,
-	.kill_arch		= NULL,
 	.pci_map_irq		= noritake_map_irq,
 	.pci_swizzle		= noritake_swizzle,
 };
@@ -331,7 +330,7 @@
 	DO_CIA_IO,
 	DO_CIA_BUS,
 	.machine_check		= cia_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= EISA_DEFAULT_IO_BASE,
 	.min_mem_address	= CIA_DEFAULT_MEM_BASE,
 
@@ -342,6 +341,7 @@
 	.init_irq		= noritake_init_irq,
 	.init_rtc		= common_init_rtc,
 	.init_pci		= cia_init_pci,
+	.kill_arch		= cia_kill_arch,
 	.pci_map_irq		= noritake_map_irq,
 	.pci_swizzle		= noritake_swizzle,
 };
diff -Nru a/arch/alpha/kernel/sys_rawhide.c b/arch/alpha/kernel/sys_rawhide.c
--- a/arch/alpha/kernel/sys_rawhide.c	Mon Nov  4 14:31:02 2002
+++ b/arch/alpha/kernel/sys_rawhide.c	Mon Nov  4 14:31:02 2002
@@ -252,7 +252,7 @@
 	DO_MCPCIA_IO,
 	DO_MCPCIA_BUS,
 	.machine_check		= mcpcia_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= MCPCIA_DEFAULT_MEM_BASE,
 	.pci_dac_offset		= MCPCIA_DAC_OFFSET,
diff -Nru a/arch/alpha/kernel/sys_ruffian.c b/arch/alpha/kernel/sys_ruffian.c
--- a/arch/alpha/kernel/sys_ruffian.c	Mon Nov  4 14:31:02 2002
+++ b/arch/alpha/kernel/sys_ruffian.c	Mon Nov  4 14:31:02 2002
@@ -85,6 +85,7 @@
 static void
 ruffian_kill_arch (int mode)
 {
+	cia_kill_arch(mode);
 #if 0
 	/* This only causes re-entry to ARCSBIOS */
 	/* Perhaps this works for other PYXIS as well?  */
@@ -218,7 +219,7 @@
 	DO_PYXIS_IO,
 	DO_CIA_BUS,
 	.machine_check		= cia_machine_check,
-	.max_dma_address	= ALPHA_RUFFIAN_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_RUFFIAN_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= DEFAULT_MEM_BASE,
 	.pci_dac_offset		= PYXIS_DAC_OFFSET,
diff -Nru a/arch/alpha/kernel/sys_rx164.c b/arch/alpha/kernel/sys_rx164.c
--- a/arch/alpha/kernel/sys_rx164.c	Mon Nov  4 14:31:00 2002
+++ b/arch/alpha/kernel/sys_rx164.c	Mon Nov  4 14:31:00 2002
@@ -203,7 +203,7 @@
 	DO_POLARIS_IO,
 	DO_POLARIS_BUS,
 	.machine_check		= polaris_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= DEFAULT_MEM_BASE,
 
diff -Nru a/arch/alpha/kernel/sys_sable.c b/arch/alpha/kernel/sys_sable.c
--- a/arch/alpha/kernel/sys_sable.c	Mon Nov  4 14:31:00 2002
+++ b/arch/alpha/kernel/sys_sable.c	Mon Nov  4 14:31:00 2002
@@ -290,7 +290,7 @@
 	DO_T2_IO,
 	DO_T2_BUS,
 	.machine_check		= t2_machine_check,
-	.max_dma_address	= ALPHA_SABLE_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_SABLE_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= EISA_DEFAULT_IO_BASE,
 	.min_mem_address	= T2_DEFAULT_MEM_BASE,
 
@@ -322,7 +322,7 @@
 	DO_T2_IO,
 	DO_T2_BUS,
 	.machine_check		= t2_machine_check,
-	.max_dma_address	= ALPHA_SABLE_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_SABLE_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= EISA_DEFAULT_IO_BASE,
 	.min_mem_address	= T2_DEFAULT_MEM_BASE,
 
diff -Nru a/arch/alpha/kernel/sys_sio.c b/arch/alpha/kernel/sys_sio.c
--- a/arch/alpha/kernel/sys_sio.c	Mon Nov  4 14:31:00 2002
+++ b/arch/alpha/kernel/sys_sio.c	Mon Nov  4 14:31:00 2002
@@ -258,7 +258,7 @@
 	DO_LCA_IO,
 	DO_LCA_BUS,
 	.machine_check		= lca_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= APECS_AND_LCA_DEFAULT_MEM_BASE,
 
@@ -289,7 +289,7 @@
 	DO_APECS_IO,
 	DO_APECS_BUS,
 	.machine_check		= apecs_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= APECS_AND_LCA_DEFAULT_MEM_BASE,
 
@@ -318,7 +318,7 @@
 	DO_LCA_IO,
 	DO_LCA_BUS,
 	.machine_check		= lca_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= APECS_AND_LCA_DEFAULT_MEM_BASE,
 
@@ -356,7 +356,7 @@
 	DO_LCA_IO,
 	DO_LCA_BUS,
 	.machine_check		= lca_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= APECS_AND_LCA_DEFAULT_MEM_BASE,
 
@@ -385,7 +385,7 @@
 	DO_APECS_IO,
 	BUS(apecs),
 	.machine_check		= apecs_machine_check,
-	.max_dma_address	= ALPHA_XL_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_XL_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= XL_DEFAULT_MEM_BASE,
 
diff -Nru a/arch/alpha/kernel/sys_sx164.c b/arch/alpha/kernel/sys_sx164.c
--- a/arch/alpha/kernel/sys_sx164.c	Mon Nov  4 14:31:01 2002
+++ b/arch/alpha/kernel/sys_sx164.c	Mon Nov  4 14:31:01 2002
@@ -160,7 +160,7 @@
 	DO_PYXIS_IO,
 	DO_CIA_BUS,
 	.machine_check		= cia_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= DEFAULT_MEM_BASE,
 	.pci_dac_offset		= PYXIS_DAC_OFFSET,
@@ -172,7 +172,7 @@
 	.init_irq		= sx164_init_irq,
 	.init_rtc		= common_init_rtc,
 	.init_pci		= sx164_init_pci,
-	.kill_arch		= NULL,
+	.kill_arch		= cia_kill_arch,
 	.pci_map_irq		= sx164_map_irq,
 	.pci_swizzle		= common_swizzle,
 };
diff -Nru a/arch/alpha/kernel/sys_takara.c b/arch/alpha/kernel/sys_takara.c
--- a/arch/alpha/kernel/sys_takara.c	Mon Nov  4 14:31:01 2002
+++ b/arch/alpha/kernel/sys_takara.c	Mon Nov  4 14:31:01 2002
@@ -275,7 +275,7 @@
 	DO_CIA_IO,
 	DO_CIA_BUS,
 	.machine_check		= cia_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= CIA_DEFAULT_MEM_BASE,
 
@@ -286,7 +286,7 @@
 	.init_irq		= takara_init_irq,
 	.init_rtc		= common_init_rtc,
 	.init_pci		= takara_init_pci,
-	.kill_arch		= NULL,
+	.kill_arch		= cia_kill_arch,
 	.pci_map_irq		= takara_map_irq,
 	.pci_swizzle		= takara_swizzle,
 };
diff -Nru a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c
--- a/arch/alpha/kernel/sys_titan.c	Mon Nov  4 14:31:02 2002
+++ b/arch/alpha/kernel/sys_titan.c	Mon Nov  4 14:31:02 2002
@@ -306,10 +306,7 @@
 {
 	u8 irq;
 	
-	pcibios_read_config_byte(dev->bus->number,
-				 dev->devfn,
-				 PCI_INTERRUPT_LINE,
-				 &irq);
+	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
 
 	/* is it routed through ISA? */
 	if ((irq & 0xF0) == 0xE0)
@@ -373,7 +370,7 @@
 	DO_TITAN_IO,
 	DO_TITAN_BUS,
 	.machine_check		= privateer_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= DEFAULT_MEM_BASE,
 	.pci_dac_offset		= TITAN_DAC_OFFSET,
diff -Nru a/arch/alpha/kernel/sys_wildfire.c b/arch/alpha/kernel/sys_wildfire.c
--- a/arch/alpha/kernel/sys_wildfire.c	Mon Nov  4 14:31:01 2002
+++ b/arch/alpha/kernel/sys_wildfire.c	Mon Nov  4 14:31:01 2002
@@ -339,7 +339,7 @@
 	DO_WILDFIRE_IO,
 	DO_WILDFIRE_BUS,
 	.machine_check		= wildfire_machine_check,
-	.max_dma_address	= ALPHA_MAX_DMA_ADDRESS,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
 	.min_io_address		= DEFAULT_IO_BASE,
 	.min_mem_address	= DEFAULT_MEM_BASE,
 
diff -Nru a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
--- a/arch/alpha/kernel/traps.c	Mon Nov  4 14:31:02 2002
+++ b/arch/alpha/kernel/traps.c	Mon Nov  4 14:31:02 2002
@@ -213,25 +213,25 @@
 	    unsigned long a2, unsigned long a3, unsigned long a4,
 	    unsigned long a5, struct pt_regs regs)
 {
+	long si_code = FPE_FLTINV;
+	siginfo_t info;
+
 	if (summary & 1) {
 		/* Software-completion summary bit is set, so try to
-		   emulate the instruction.  */
-		if (!amask(AMASK_PRECISE_TRAP)) {
-			/* 21264 (except pass 1) has precise exceptions.  */
-			if (alpha_fp_emul(regs.pc - 4))
-				return;
-		} else {
-			if (alpha_fp_emul_imprecise(&regs, write_mask))
-				return;
-		}
+		   emulate the instruction.  If the processor supports
+		   precise exceptions, we don't have to search.  */
+		if (!amask(AMASK_PRECISE_TRAP))
+			si_code = alpha_fp_emul(regs.pc - 4);
+		else
+			si_code = alpha_fp_emul_imprecise(&regs, write_mask);
 	}
-
-#if 0
-	printk("%s: arithmetic trap at %016lx: %02lx %016lx\n",
-		current->comm, regs.pc, summary, write_mask);
-#endif
 	die_if_kernel("Arithmetic fault", &regs, 0, 0);
-	send_sig(SIGFPE, current, 1);
+
+	info.si_signo = SIGFPE;
+	info.si_errno = 0;
+	info.si_code = si_code;
+	info.si_addr = (void *) regs.pc;
+	send_sig_info(SIGFPE, &info, current);
 }
 
 asmlinkage void
@@ -239,6 +239,9 @@
 	 unsigned long a2, unsigned long a3, unsigned long a4,
 	 unsigned long a5, struct pt_regs regs)
 {
+	siginfo_t info;
+	int signo, code;
+
 	if (!opDEC_testing || type != 4) {
 		if (type == 1) {
 			const unsigned int *data
@@ -253,55 +256,99 @@
 
 	switch (type) {
 	      case 0: /* breakpoint */
+		info.si_signo = SIGTRAP;
+		info.si_errno = 0;
+		info.si_code = TRAP_BRKPT;
+		info.si_trapno = 0;
+		info.si_addr = (void *) regs.pc;
+
 		if (ptrace_cancel_bpt(current)) {
 			regs.pc -= 4;	/* make pc point to former bpt */
 		}
-		send_sig(SIGTRAP, current, 1);
+
+		send_sig_info(SIGTRAP, &info, current);
 		return;
 
 	      case 1: /* bugcheck */
-		send_sig(SIGTRAP, current, 1);
+		info.si_signo = SIGTRAP;
+		info.si_errno = 0;
+		info.si_code = __SI_FAULT;
+		info.si_addr = (void *) regs.pc;
+		info.si_trapno = 0;
+		send_sig_info(SIGTRAP, &info, current);
 		return;
-
+		
 	      case 2: /* gentrap */
-		/*
-		 * The exception code should be passed on to the signal
-		 * handler as the second argument.  Linux doesn't do that
-		 * yet (also notice that Linux *always* behaves like
-		 * DEC Unix with SA_SIGINFO off; see DEC Unix man page
-		 * for sigaction(2)).
-		 */
+		info.si_addr = (void *) regs.pc;
+		info.si_trapno = regs.r16;
 		switch ((long) regs.r16) {
-		      case GEN_INTOVF: case GEN_INTDIV: case GEN_FLTOVF:
-		      case GEN_FLTDIV: case GEN_FLTUND: case GEN_FLTINV:
-		      case GEN_FLTINE: case GEN_ROPRAND:
-			send_sig(SIGFPE, current, 1);
-			return;
-
-		      case GEN_DECOVF:
-		      case GEN_DECDIV:
-		      case GEN_DECINV:
-		      case GEN_ASSERTERR:
-		      case GEN_NULPTRERR:
-		      case GEN_STKOVF:
-		      case GEN_STRLENERR:
-		      case GEN_SUBSTRERR:
-		      case GEN_RANGERR:
-		      case GEN_SUBRNG:
-		      case GEN_SUBRNG1:
-		      case GEN_SUBRNG2:
-		      case GEN_SUBRNG3:
-		      case GEN_SUBRNG4:
-		      case GEN_SUBRNG5:
-		      case GEN_SUBRNG6:
-		      case GEN_SUBRNG7:
-			send_sig(SIGTRAP, current, 1);
-			return;
+		case GEN_INTOVF:
+			signo = SIGFPE;
+			code = FPE_INTOVF;
+			break;
+		case GEN_INTDIV:
+			signo = SIGFPE;
+			code = FPE_INTDIV;
+			break;
+		case GEN_FLTOVF:
+			signo = SIGFPE;
+			code = FPE_FLTOVF;
+			break;
+		case GEN_FLTDIV:
+			signo = SIGFPE;
+			code = FPE_FLTDIV;
+			break;
+		case GEN_FLTUND:
+			signo = SIGFPE;
+			code = FPE_FLTUND;
+			break;
+		case GEN_FLTINV:
+			signo = SIGFPE;
+			code = FPE_FLTINV;
+			break;
+		case GEN_FLTINE:
+			signo = SIGFPE;
+			code = FPE_FLTRES;
+			break;
+		case GEN_ROPRAND:
+			signo = SIGFPE;
+			code = __SI_FAULT;
+			break;
+
+		case GEN_DECOVF:
+		case GEN_DECDIV:
+		case GEN_DECINV:
+		case GEN_ASSERTERR:
+		case GEN_NULPTRERR:
+		case GEN_STKOVF:
+		case GEN_STRLENERR:
+		case GEN_SUBSTRERR:
+		case GEN_RANGERR:
+		case GEN_SUBRNG:
+		case GEN_SUBRNG1:
+		case GEN_SUBRNG2:
+		case GEN_SUBRNG3:
+		case GEN_SUBRNG4:
+		case GEN_SUBRNG5:
+		case GEN_SUBRNG6:
+		case GEN_SUBRNG7:
+		default:
+			signo = SIGTRAP;
+			code = __SI_FAULT;
+			break;
 		}
-		break;
+
+		info.si_signo = signo;
+		info.si_errno = 0;
+		info.si_code = code;
+		info.si_addr = (void *) regs.pc;
+		send_sig_info(signo, &info, current);
+		return;
 
 	      case 4: /* opDEC */
 		if (implver() == IMPLVER_EV4) {
+			long si_code;
+
 			/* The some versions of SRM do not handle
 			   the opDEC properly - they return the PC of the
 			   opDEC fault, not the instruction after as the
@@ -309,8 +356,7 @@
 			   We do this by intentionally causing an opDEC
 			   fault during the boot sequence and testing if
 			   we get the correct PC.  If not, we set a flag
-			   to correct it every time through.
-			*/
+			   to correct it every time through.  */
 			if (opDEC_testing) {
 				if (regs.pc == opDEC_test_pc) {
 					opDEC_fix = 4;
@@ -324,8 +370,17 @@
 			/* EV4 does not implement anything except normal
 			   rounding.  Everything else will come here as
 			   an illegal instruction.  Emulate them.  */
-			if (alpha_fp_emul(regs.pc-4))
+			si_code = alpha_fp_emul(regs.pc - 4);
+			if (si_code == 0)
 				return;
+			if (si_code > 0) {
+				info.si_signo = SIGFPE;
+				info.si_errno = 0;
+				info.si_code = si_code;
+				info.si_addr = (void *) regs.pc;
+				send_sig_info(SIGFPE, &info, current);
+				return;
+			}
 		}
 		break;
 
@@ -347,7 +402,12 @@
 	      default: /* unexpected instruction-fault type */
 		      ;
 	}
-	send_sig(SIGILL, current, 1);
+
+	info.si_signo = SIGILL;
+	info.si_errno = 0;
+	info.si_code = ILL_ILLOPC;
+	info.si_addr = regs.pc;
+	send_sig_info(SIGILL, &info, current);
 }
 
 /* There is an ifdef in the PALcode in MILO that enables a 
@@ -362,8 +422,15 @@
 	  unsigned long a2, unsigned long a3, unsigned long a4,
 	  unsigned long a5, struct pt_regs regs)
 {
+	siginfo_t info;
+
 	die_if_kernel("Instruction fault", &regs, type, 0);
-	force_sig(SIGILL, current);
+
+	info.si_signo = SIGILL;
+	info.si_errno = 0;
+	info.si_code = ILL_ILLOPC;
+	info.si_addr = regs.pc;
+	force_sig_info(SIGILL, &info, current);
 }
 
 
@@ -720,6 +787,7 @@
 
 	unsigned long tmp1, tmp2, tmp3, tmp4;
 	unsigned long fake_reg, *reg_addr = &fake_reg;
+	siginfo_t info;
 	long error;
 
 	/* Check the UAC bits to decide what the user wants us to do
@@ -984,12 +1052,34 @@
 
 give_sigsegv:
 	regs->pc -= 4;  /* make pc point to faulting insn */
-	send_sig(SIGSEGV, current, 1);
+	info.si_signo = SIGSEGV;
+	info.si_errno = 0;
+
+	/* We need to replicate some of the logic in mm/fault.c,
+	   since we don't have access to the fault code in the
+	   exception handling return path.  */
+	if (!__access_ok((unsigned long)va, 0, USER_DS))
+		info.si_code = SEGV_ACCERR;
+	else {
+		struct mm_struct *mm = current->mm;
+		down_read(&mm->mmap_sem);
+		if (find_vma(mm, (unsigned long)va))
+			info.si_code = SEGV_ACCERR;
+		else
+			info.si_code = SEGV_MAPERR;
+		up_read(&mm->mmap_sem);
+	}
+	info.si_addr = va;
+	send_sig_info(SIGSEGV, &info, current);
 	return;
 
 give_sigbus:
 	regs->pc -= 4;
-	send_sig(SIGBUS, current, 1);
+	info.si_signo = SIGBUS;
+	info.si_errno = 0;
+	info.si_code = BUS_ADRALN;
+	info.si_addr = va;
+	send_sig_info(SIGBUS, &info, current);
 	return;
 }
 
diff -Nru a/arch/alpha/lib/dbg_current.S b/arch/alpha/lib/dbg_current.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/alpha/lib/dbg_current.S	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,29 @@
+/*
+ * arch/alpha/lib/dbg_current.S
+ * Contributed by Richard Henderson (rth@cygnus.com)
+ *
+ * Trap if we find current not correct.
+ */
+
+#include <asm/pal.h>
+
+	.text
+	.set noat
+
+	.globl _mcount
+	.ent _mcount
+_mcount:
+	.frame $30, 0, $28, 0
+	.prologue 0
+
+	lda	$0, -0x4000($30)
+	cmpult	$8, $30, $1
+	cmpule	$0, $30, $2
+	and	$1, $2, $3
+	bne	$3, 1f
+
+	call_pal PAL_bugchk
+
+1:	ret	$31, ($28), 1
+
+	.end _mcount
diff -Nru a/arch/alpha/math-emu/math.c b/arch/alpha/math-emu/math.c
--- a/arch/alpha/math-emu/math.c	Mon Nov  4 14:31:03 2002
+++ b/arch/alpha/math-emu/math.c	Mon Nov  4 14:31:03 2002
@@ -86,11 +86,13 @@
 
 
 /*
- * Emulate the floating point instruction at address PC.  Returns 0 if
- * emulation fails.  Notice that the kernel does not and cannot use FP
- * regs.  This is good because it means that instead of
- * saving/restoring all fp regs, we simply stick the result of the
- * operation into the appropriate register.
+ * Emulate the floating point instruction at address PC.  Returns -1 if the
+ * instruction to be emulated is illegal (such as with the opDEC trap), else
+ * the SI_CODE for a SIGFPE signal, else 0 if everything's ok.
+ *
+ * Notice that the kernel does not and cannot use FP regs.  This is good
+ * because it means that instead of saving/restoring all fp regs, we simply
+ * stick the result of the operation into the appropriate register.
  */
 long
 alpha_fp_emul (unsigned long pc)
@@ -102,6 +104,7 @@
 	unsigned long fa, fb, fc, func, mode, src;
 	unsigned long res, va, vb, vc, swcr, fpcr;
 	__u32 insn;
+	long si_code;
 
 	MOD_INC_USE_COUNT;
 
@@ -306,10 +309,19 @@
 		wrfpcr(fpcr);
 
 		/* Do we generate a signal?  */
-		if (_fex & swcr & IEEE_TRAP_ENABLE_MASK) {
-			MOD_DEC_USE_COUNT;
-			return 0;
+		_fex = _fex & swcr & IEEE_TRAP_ENABLE_MASK;
+		si_code = 0;
+		if (_fex) {
+			if (_fex & IEEE_TRAP_ENABLE_DNO) si_code = FPE_FLTUND;
+			if (_fex & IEEE_TRAP_ENABLE_INE) si_code = FPE_FLTRES;
+			if (_fex & IEEE_TRAP_ENABLE_UNF) si_code = FPE_FLTUND;
+			if (_fex & IEEE_TRAP_ENABLE_OVF) si_code = FPE_FLTOVF;
+			if (_fex & IEEE_TRAP_ENABLE_DZE) si_code = FPE_FLTDIV;
+			if (_fex & IEEE_TRAP_ENABLE_INV) si_code = FPE_FLTINV;
 		}
+
+		MOD_DEC_USE_COUNT;
+		return si_code;
 	}
 
 	/* We used to write the destination register here, but DEC FORTRAN
@@ -317,20 +329,20 @@
 	   immediately after the operations above.  */
 
 	MOD_DEC_USE_COUNT;
-	return 1;
+	return 0;
 
 bad_insn:
 	printk(KERN_ERR "alpha_fp_emul: Invalid FP insn %#x at %#lx\n",
 	       insn, pc);
 	MOD_DEC_USE_COUNT;
-	return 0;
+	return -1;
 }
 
 long
 alpha_fp_emul_imprecise (struct pt_regs *regs, unsigned long write_mask)
 {
 	unsigned long trigger_pc = regs->pc - 4;
-	unsigned long insn, opcode, rc, no_signal = 0;
+	unsigned long insn, opcode, rc, si_code = 0;
 
 	MOD_INC_USE_COUNT;
 
@@ -384,7 +396,7 @@
 		if (!write_mask) {
 			/* Re-execute insns in the trap-shadow.  */
 			regs->pc = trigger_pc + 4;
-			no_signal = alpha_fp_emul(trigger_pc);
+			si_code = alpha_fp_emul(trigger_pc);
 			goto egress;
 		}
 		trigger_pc -= 4;
@@ -392,5 +404,5 @@
 
 egress:
 	MOD_DEC_USE_COUNT;
-	return no_signal;
+	return si_code;
 }
diff -Nru a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
--- a/arch/alpha/mm/fault.c	Mon Nov  4 14:31:01 2002
+++ b/arch/alpha/mm/fault.c	Mon Nov  4 14:31:01 2002
@@ -89,7 +89,8 @@
 	struct vm_area_struct * vma;
 	struct mm_struct *mm = current->mm;
 	unsigned int fixup;
-	int fault;
+	int fault, si_code = SEGV_MAPERR;
+	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
@@ -129,6 +130,7 @@
 	/* Ok, we have a good vm_area for this memory access, so
 	   we can handle it.  */
  good_area:
+	si_code = SEGV_ACCERR;
 	if (cause < 0) {
 		if (!(vma->vm_flags & VM_EXEC))
 			goto bad_area;
@@ -148,10 +150,20 @@
 	fault = handle_mm_fault(mm, vma, address, cause > 0);
 	up_read(&mm->mmap_sem);
 
-	if (fault < 0)
-		goto out_of_memory;
-	if (fault == 0)
+	switch (fault) {
+	      case VM_FAULT_MINOR:
+		current->min_flt++;
+		break;
+	      case VM_FAULT_MAJOR:
+		current->maj_flt++;
+		break;
+	      case VM_FAULT_SIGBUS:
 		goto do_sigbus;
+	      case VM_FAULT_OOM:
+		goto out_of_memory;
+	      default:
+		BUG();
+	}
 	return;
 
 	/* Something tried to access memory that isn't in our memory map.
@@ -159,20 +171,14 @@
  bad_area:
 	up_read(&mm->mmap_sem);
 
-	if (user_mode(regs)) {
-		force_sig(SIGSEGV, current);
-		return;
-	}
+	if (user_mode(regs))
+		goto do_sigsegv;
 
  no_context:
 	/* Are we prepared to handle this fault as an exception?  */
 	if ((fixup = search_exception_table(regs->pc, regs->gp)) != 0) {
 		unsigned long newpc;
 		newpc = fixup_exception(dpf_reg, fixup, regs->pc);
-#if 0
-		printk("%s: Exception at [<%lx>] (%lx) handled successfully\n",
-		       current->comm, regs->pc, newpc);
-#endif
 		regs->pc = newpc;
 		return;
 	}
@@ -201,17 +207,28 @@
  do_sigbus:
 	/* 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;
+	info.si_code = BUS_ADRERR;
+	info.si_addr = (void *) address;
+	force_sig_info(SIGBUS, &info, current);
 	if (!user_mode(regs))
 		goto no_context;
 	return;
 
+ do_sigsegv:
+	info.si_signo = SIGSEGV;
+	info.si_errno = 0;
+	info.si_code = si_code;
+	info.si_addr = (void *) address;
+	force_sig_info(SIGSEGV, &info, current);
+	return;
+
 #ifdef CONFIG_ALPHA_LARGE_VMALLOC
  vmalloc_fault:
-	if (user_mode(regs)) {
-		force_sig(SIGSEGV, current);
-		return;
-	} else {
+	if (user_mode(regs))
+		goto do_sigsegv;
+	else {
 		/* Synchronize this task's top level page-table
 		   with the "reference" page table from init.  */
 		long offset = __pgd_offset(address);
diff -Nru a/arch/alpha/vmlinux.lds.S b/arch/alpha/vmlinux.lds.S
--- a/arch/alpha/vmlinux.lds.S	Mon Nov  4 14:31:02 2002
+++ b/arch/alpha/vmlinux.lds.S	Mon Nov  4 14:31:02 2002
@@ -31,18 +31,27 @@
 	*(__ksymtab)
 	__stop___ksymtab = .;
   }
+
+  /* All kernel symbols */
+  __kallsyms ALIGN(8) : {
+	__start___kallsyms = .;
+	*(__kallsyms)
+	__stop___kallsyms = .;
+  }
+
   .kstrtab : { *(.kstrtab) }
+  .rodata : { *(.rodata) *(.rodata.*) }
 
   /* Startup code */
-  .text.init ALIGN(8192) : {
+  .init.text ALIGN(8192) : {
 	__init_begin = .;
-	*(.text.init)
+	*(.init.text)
   }
-  .data.init : { *(.data.init) }
+  .init.data : { *(.init.data) }
 
-  .setup.init ALIGN(16): {
+  .init.setup ALIGN(16): {
 	__setup_start = .;
-	*(.setup.init)
+	*(.init.setup)
 	__setup_end = .;
   }
 
@@ -58,6 +67,12 @@
 	__initcall_end = .;
   }
 
+  .init.ramfs ALIGN(8192): {
+	__initramfs_start = .;
+	*(.init.initramfs)
+	__initramfs_end = .;
+  }
+
   .data.percpu ALIGN(64): {
 	__per_cpu_start = .;
 	*(.data.percpu)
@@ -71,11 +86,11 @@
   }
 
   /* Global data */
-  .data.cacheline_aligned : {
+  .data.page_aligned ALIGN(8192) : {
 	_data = .;
-	*(.data.cacheline_aligned)
+	*(.data.page_aligned) 
   }
-  .rodata : { *(.rodata) *(.rodata.*) }
+  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
   .data : { *(.data) CONSTRUCTORS }
   .got : { *(.got) }
   .sdata : {
@@ -120,5 +135,5 @@
   .debug_typenames 0 : { *(.debug_typenames) }
   .debug_varnames  0 : { *(.debug_varnames) }
 
-  /DISCARD/ : { *(.text.exit) *(.data.exit) *(.exitcall.exit) }
+  /DISCARD/ : { *(.exit.text) *(.exit.data) *(.exitcall.exit) }
 }
diff -Nru a/arch/arm/Kconfig b/arch/arm/Kconfig
--- a/arch/arm/Kconfig	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/Kconfig	Mon Nov  4 14:31:02 2002
@@ -16,6 +16,14 @@
 	  Europe.  There is an ARM Linux project with a web page at
 	  <http://www.arm.linux.org.uk/>.
 
+config MMU
+	bool
+	default y
+
+config SWAP
+	bool
+	default y
+
 config EISA
 	bool
 	---help---
@@ -1113,15 +1121,18 @@
 
 menu "Kernel hacking"
 
-# Always compile kernel with framepointer (until 2.4 real comes out)
-# Bug reports aren't much use without this.
-config NO_FRAME_POINTER
-	bool "Compile kernel without frame pointer"
+# RMK wants arm kernels compiled with frame pointers so hardwire this to y.
+# If you know what you are doing and are willing to live without stack
+# traces, you can get a slightly smaller kernel by setting this option to
+# n, but then RMK will have to kill you ;).
+config FRAME_POINTER
+	bool
+	default y
 	help
-	  If you say Y here, the resulting kernel will be slightly smaller and
+	  If you say N here, the resulting kernel will be slightly smaller and
 	  faster. However, when a problem occurs with the kernel, the
 	  information that is reported is severely limited. Most people
-	  should say N here.
+	  should say Y here.
 
 config DEBUG_USER
 	bool "Verbose user fault messages"
@@ -1132,7 +1143,7 @@
 	  production system. Most people should say N here.
 
 config DEBUG_INFO
-	bool "Include debugging information in kernel binary"
+	bool "Include GDB debugging information in kernel binary"
 	help
 	  Say Y here to include source-level debugging information in the
 	  `vmlinux' binary image. This is handy if you want to use gdb or
@@ -1200,6 +1211,14 @@
 	  but mostly meaningless to other people. It's safe to say Y unless
 	  you are concerned with the code size or don't want to see these
 	  messages.
+
+config KALLSYMS
+	bool "Load all symbols for debugging/kksymoops"
+	depends on DEBUG_KERNEL
+	help
+	  Say Y here to let the kernel print out symbolic crash information and
+	  symbolic stack backtraces. This increases the size of the kernel
+	  somewhat, as all symbols have to be loaded into the kernel image.
 
 # These options are only for real kernel hackers who want to get their hands dirty. 
 config DEBUG_LL
diff -Nru a/arch/arm/Makefile b/arch/arm/Makefile
--- a/arch/arm/Makefile	Mon Nov  4 14:31:01 2002
+++ b/arch/arm/Makefile	Mon Nov  4 14:31:01 2002
@@ -15,8 +15,8 @@
 
 CFLAGS		:=$(CFLAGS:-O2=-Os)
 
-ifneq ($(CONFIG_NO_FRAME_POINTER),y)
-CFLAGS		:=$(CFLAGS: -fomit-frame-pointer=)
+ifeq ($(CONFIG_FRAME_POINTER),y)
+CFLAGS		:=$(CFLAGS:-fomit-frame-pointer=-mapcs -mno-sched-prolog)
 endif
 
 ifeq ($(CONFIG_DEBUG_INFO),y)
@@ -179,8 +179,10 @@
 endif
 
 # If we have a machine-specific directory, then include it in the build.
-core-y				+= arch/arm/mach-$(MACHINE)/ \
-				   arch/arm/kernel/ arch/arm/mm/
+ifneq ($(MACHINE),)
+core-y				+= arch/arm/mach-$(MACHINE)/
+endif
+core-y				+= arch/arm/kernel/ arch/arm/mm/
 core-$(CONFIG_FPE_NWFPE)	+= arch/arm/nwfpe/
 core-$(CONFIG_FPE_FASTFPE)	+= $(FASTFPE_OBJ)
 
diff -Nru a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
--- a/arch/arm/boot/Makefile	Mon Nov  4 14:31:00 2002
+++ b/arch/arm/boot/Makefile	Mon Nov  4 14:31:00 2002
@@ -112,8 +112,8 @@
 # from ROM or Flash must define ZTEXTADDR (preferably via the config)
 #
 ifeq ($(CONFIG_ZBOOT_ROM),y)
-ZTEXTADDR	=0x$(CONFIG_ZBOOT_ROM_TEXT)
-ZBSSADDR	=0x$(CONFIG_ZBOOT_ROM_BSS)
+ZTEXTADDR	=$(CONFIG_ZBOOT_ROM_TEXT)
+ZBSSADDR	=$(CONFIG_ZBOOT_ROM_BSS)
 else
 ZTEXTADDR	=0
 ZBSSADDR	=ALIGN(4)
diff -Nru a/arch/arm/boot/compressed/head-sa1100.S b/arch/arm/boot/compressed/head-sa1100.S
--- a/arch/arm/boot/compressed/head-sa1100.S	Mon Nov  4 14:31:00 2002
+++ b/arch/arm/boot/compressed/head-sa1100.S	Mon Nov  4 14:31:00 2002
@@ -76,4 +76,3 @@
 		mov	r0, #0x00200000
 1:		subs	r0, r0, #1
 		bne	1b
-
diff -Nru a/arch/arm/def-configs/adi_evb b/arch/arm/def-configs/adi_evb
--- a/arch/arm/def-configs/adi_evb	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/def-configs/adi_evb	Mon Nov  4 14:31:02 2002
@@ -669,7 +669,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Nru a/arch/arm/def-configs/adsbitsy b/arch/arm/def-configs/adsbitsy
--- a/arch/arm/def-configs/adsbitsy	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/def-configs/adsbitsy	Mon Nov  4 14:31:02 2002
@@ -654,7 +654,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 # CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_INFO is not set
diff -Nru a/arch/arm/def-configs/anakin b/arch/arm/def-configs/anakin
--- a/arch/arm/def-configs/anakin	Mon Nov  4 14:31:00 2002
+++ b/arch/arm/def-configs/anakin	Mon Nov  4 14:31:00 2002
@@ -610,7 +610,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_KERNEL is not set
diff -Nru a/arch/arm/def-configs/assabet b/arch/arm/def-configs/assabet
--- a/arch/arm/def-configs/assabet	Mon Nov  4 14:31:01 2002
+++ b/arch/arm/def-configs/assabet	Mon Nov  4 14:31:01 2002
@@ -954,7 +954,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Nru a/arch/arm/def-configs/badge4 b/arch/arm/def-configs/badge4
--- a/arch/arm/def-configs/badge4	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/def-configs/badge4	Mon Nov  4 14:31:02 2002
@@ -1141,7 +1141,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_INFO=y
 CONFIG_DEBUG_KERNEL=y
diff -Nru a/arch/arm/def-configs/cerfcube b/arch/arm/def-configs/cerfcube
--- a/arch/arm/def-configs/cerfcube	Mon Nov  4 14:31:00 2002
+++ b/arch/arm/def-configs/cerfcube	Mon Nov  4 14:31:00 2002
@@ -863,7 +863,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Nru a/arch/arm/def-configs/cerfpda b/arch/arm/def-configs/cerfpda
--- a/arch/arm/def-configs/cerfpda	Mon Nov  4 14:31:01 2002
+++ b/arch/arm/def-configs/cerfpda	Mon Nov  4 14:31:01 2002
@@ -957,7 +957,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Nru a/arch/arm/def-configs/cerfpod b/arch/arm/def-configs/cerfpod
--- a/arch/arm/def-configs/cerfpod	Mon Nov  4 14:31:03 2002
+++ b/arch/arm/def-configs/cerfpod	Mon Nov  4 14:31:03 2002
@@ -884,7 +884,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Nru a/arch/arm/def-configs/ebsa110 b/arch/arm/def-configs/ebsa110
--- a/arch/arm/def-configs/ebsa110	Mon Nov  4 14:31:00 2002
+++ b/arch/arm/def-configs/ebsa110	Mon Nov  4 14:31:00 2002
@@ -595,7 +595,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 # CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_INFO is not set
diff -Nru a/arch/arm/def-configs/epxa10db b/arch/arm/def-configs/epxa10db
--- a/arch/arm/def-configs/epxa10db	Mon Nov  4 14:31:01 2002
+++ b/arch/arm/def-configs/epxa10db	Mon Nov  4 14:31:01 2002
@@ -678,7 +678,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 # CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_NO_PGT_CACHE is not set
diff -Nru a/arch/arm/def-configs/flexanet b/arch/arm/def-configs/flexanet
--- a/arch/arm/def-configs/flexanet	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/def-configs/flexanet	Mon Nov  4 14:31:02 2002
@@ -886,7 +886,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_NO_PGT_CACHE is not set
diff -Nru a/arch/arm/def-configs/fortunet b/arch/arm/def-configs/fortunet
--- a/arch/arm/def-configs/fortunet	Mon Nov  4 14:31:03 2002
+++ b/arch/arm/def-configs/fortunet	Mon Nov  4 14:31:03 2002
@@ -577,7 +577,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_NO_PGT_CACHE is not set
diff -Nru a/arch/arm/def-configs/freebird b/arch/arm/def-configs/freebird
--- a/arch/arm/def-configs/freebird	Mon Nov  4 14:31:01 2002
+++ b/arch/arm/def-configs/freebird	Mon Nov  4 14:31:01 2002
@@ -605,7 +605,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Nru a/arch/arm/def-configs/freebird_new b/arch/arm/def-configs/freebird_new
--- a/arch/arm/def-configs/freebird_new	Mon Nov  4 14:31:00 2002
+++ b/arch/arm/def-configs/freebird_new	Mon Nov  4 14:31:00 2002
@@ -625,7 +625,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 # CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_INFO is not set
diff -Nru a/arch/arm/def-configs/graphicsclient b/arch/arm/def-configs/graphicsclient
--- a/arch/arm/def-configs/graphicsclient	Mon Nov  4 14:31:03 2002
+++ b/arch/arm/def-configs/graphicsclient	Mon Nov  4 14:31:03 2002
@@ -722,7 +722,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Nru a/arch/arm/def-configs/graphicsmaster b/arch/arm/def-configs/graphicsmaster
--- a/arch/arm/def-configs/graphicsmaster	Mon Nov  4 14:31:00 2002
+++ b/arch/arm/def-configs/graphicsmaster	Mon Nov  4 14:31:00 2002
@@ -735,7 +735,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Nru a/arch/arm/def-configs/h3600 b/arch/arm/def-configs/h3600
--- a/arch/arm/def-configs/h3600	Mon Nov  4 14:31:01 2002
+++ b/arch/arm/def-configs/h3600	Mon Nov  4 14:31:01 2002
@@ -939,7 +939,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 # CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_INFO is not set
diff -Nru a/arch/arm/def-configs/integrator b/arch/arm/def-configs/integrator
--- a/arch/arm/def-configs/integrator	Mon Nov  4 14:31:00 2002
+++ b/arch/arm/def-configs/integrator	Mon Nov  4 14:31:00 2002
@@ -653,7 +653,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Nru a/arch/arm/def-configs/iq80310 b/arch/arm/def-configs/iq80310
--- a/arch/arm/def-configs/iq80310	Mon Nov  4 14:31:01 2002
+++ b/arch/arm/def-configs/iq80310	Mon Nov  4 14:31:01 2002
@@ -786,7 +786,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_NO_PGT_CACHE is not set
diff -Nru a/arch/arm/def-configs/jornada720 b/arch/arm/def-configs/jornada720
--- a/arch/arm/def-configs/jornada720	Mon Nov  4 14:31:01 2002
+++ b/arch/arm/def-configs/jornada720	Mon Nov  4 14:31:01 2002
@@ -881,7 +881,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 # CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_NO_PGT_CACHE is not set
diff -Nru a/arch/arm/def-configs/lart b/arch/arm/def-configs/lart
--- a/arch/arm/def-configs/lart	Mon Nov  4 14:31:01 2002
+++ b/arch/arm/def-configs/lart	Mon Nov  4 14:31:01 2002
@@ -883,7 +883,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Nru a/arch/arm/def-configs/lubbock b/arch/arm/def-configs/lubbock
--- a/arch/arm/def-configs/lubbock	Mon Nov  4 14:31:00 2002
+++ b/arch/arm/def-configs/lubbock	Mon Nov  4 14:31:00 2002
@@ -860,7 +860,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_INFO=y
 CONFIG_DEBUG_KERNEL=y
diff -Nru a/arch/arm/def-configs/lusl7200 b/arch/arm/def-configs/lusl7200
--- a/arch/arm/def-configs/lusl7200	Mon Nov  4 14:31:01 2002
+++ b/arch/arm/def-configs/lusl7200	Mon Nov  4 14:31:01 2002
@@ -466,7 +466,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_KERNEL is not set
diff -Nru a/arch/arm/def-configs/neponset b/arch/arm/def-configs/neponset
--- a/arch/arm/def-configs/neponset	Mon Nov  4 14:31:01 2002
+++ b/arch/arm/def-configs/neponset	Mon Nov  4 14:31:01 2002
@@ -1104,7 +1104,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
 CONFIG_DEBUG_KERNEL=y
diff -Nru a/arch/arm/def-configs/pangolin b/arch/arm/def-configs/pangolin
--- a/arch/arm/def-configs/pangolin	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/def-configs/pangolin	Mon Nov  4 14:31:02 2002
@@ -732,7 +732,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_INFO=y
diff -Nru a/arch/arm/def-configs/pfs168_mqtft b/arch/arm/def-configs/pfs168_mqtft
--- a/arch/arm/def-configs/pfs168_mqtft	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/def-configs/pfs168_mqtft	Mon Nov  4 14:31:02 2002
@@ -773,7 +773,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_INFO=y
diff -Nru a/arch/arm/def-configs/pfs168_mqvga b/arch/arm/def-configs/pfs168_mqvga
--- a/arch/arm/def-configs/pfs168_mqvga	Mon Nov  4 14:31:00 2002
+++ b/arch/arm/def-configs/pfs168_mqvga	Mon Nov  4 14:31:00 2002
@@ -773,7 +773,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_INFO=y
diff -Nru a/arch/arm/def-configs/pfs168_sastn b/arch/arm/def-configs/pfs168_sastn
--- a/arch/arm/def-configs/pfs168_sastn	Mon Nov  4 14:31:00 2002
+++ b/arch/arm/def-configs/pfs168_sastn	Mon Nov  4 14:31:00 2002
@@ -764,7 +764,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_INFO=y
diff -Nru a/arch/arm/def-configs/pfs168_satft b/arch/arm/def-configs/pfs168_satft
--- a/arch/arm/def-configs/pfs168_satft	Mon Nov  4 14:31:00 2002
+++ b/arch/arm/def-configs/pfs168_satft	Mon Nov  4 14:31:00 2002
@@ -773,7 +773,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_INFO=y
diff -Nru a/arch/arm/def-configs/pleb b/arch/arm/def-configs/pleb
--- a/arch/arm/def-configs/pleb	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/def-configs/pleb	Mon Nov  4 14:31:02 2002
@@ -525,7 +525,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Nru a/arch/arm/def-configs/rpc b/arch/arm/def-configs/rpc
--- a/arch/arm/def-configs/rpc	Mon Nov  4 14:31:00 2002
+++ b/arch/arm/def-configs/rpc	Mon Nov  4 14:31:00 2002
@@ -830,7 +830,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Nru a/arch/arm/def-configs/shannon b/arch/arm/def-configs/shannon
--- a/arch/arm/def-configs/shannon	Mon Nov  4 14:31:00 2002
+++ b/arch/arm/def-configs/shannon	Mon Nov  4 14:31:00 2002
@@ -726,7 +726,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Nru a/arch/arm/def-configs/shark b/arch/arm/def-configs/shark
--- a/arch/arm/def-configs/shark	Mon Nov  4 14:31:00 2002
+++ b/arch/arm/def-configs/shark	Mon Nov  4 14:31:00 2002
@@ -917,7 +917,7 @@
 #
 # Kernel hacking
 #
-CONFIG_NO_FRAME_POINTER=y
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_KERNEL is not set
diff -Nru a/arch/arm/def-configs/stork b/arch/arm/def-configs/stork
--- a/arch/arm/def-configs/stork	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/def-configs/stork	Mon Nov  4 14:31:02 2002
@@ -946,7 +946,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 # CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_NO_PGT_CACHE is not set
diff -Nru a/arch/arm/def-configs/system3 b/arch/arm/def-configs/system3
--- a/arch/arm/def-configs/system3	Mon Nov  4 14:31:01 2002
+++ b/arch/arm/def-configs/system3	Mon Nov  4 14:31:01 2002
@@ -952,7 +952,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_NO_PGT_CACHE is not set
diff -Nru a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
--- a/arch/arm/kernel/armksyms.c	Mon Nov  4 14:31:01 2002
+++ b/arch/arm/kernel/armksyms.c	Mon Nov  4 14:31:01 2002
@@ -127,6 +127,7 @@
 EXPORT_SYMBOL(__readwrite_bug);
 EXPORT_SYMBOL(enable_irq);
 EXPORT_SYMBOL(disable_irq);
+EXPORT_SYMBOL(probe_irq_mask);
 EXPORT_SYMBOL(set_irq_type);
 EXPORT_SYMBOL(pm_idle);
 EXPORT_SYMBOL(pm_power_off);
diff -Nru a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
--- a/arch/arm/kernel/bios32.c	Mon Nov  4 14:31:01 2002
+++ b/arch/arm/kernel/bios32.c	Mon Nov  4 14:31:01 2002
@@ -259,7 +259,7 @@
 	}, { 0 }
 };
 
-void __init
+void __devinit
 pcibios_update_resource(struct pci_dev *dev, struct resource *root,
 			struct resource *res, int resource)
 {
@@ -300,7 +300,7 @@
 	}
 }
 
-void __init pcibios_update_irq(struct pci_dev *dev, int irq)
+void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
 {
 	if (debug_pci)
 		printk("PCI: Assigning IRQ %02d to %s\n", irq, dev->name);
@@ -321,7 +321,7 @@
 /*
  * Adjust the device resources from bus-centric to Linux-centric.
  */
-static void __init
+static void __devinit
 pdev_fixup_device_resources(struct pci_sys_data *root, struct pci_dev *dev)
 {
 	unsigned long offset;
@@ -340,7 +340,7 @@
 	}
 }
 
-static void __init
+static void __devinit
 pbus_assign_bus_resources(struct pci_bus *bus, struct pci_sys_data *root)
 {
 	struct pci_dev *dev = bus->self;
@@ -359,7 +359,7 @@
  * pcibios_fixup_bus - Called after each bus is probed,
  * but before its children are examined.
  */
-void __init pcibios_fixup_bus(struct pci_bus *bus)
+void __devinit pcibios_fixup_bus(struct pci_bus *bus)
 {
 	struct pci_sys_data *root = bus->sysdata;
 	struct list_head *walk;
@@ -428,7 +428,7 @@
 /*
  * Convert from Linux-centric to bus-centric addresses for bridge devices.
  */
-void __init
+void __devinit
 pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *ranges)
 {
 	struct pci_sys_data *root = bus->sysdata;
@@ -587,12 +587,12 @@
 void pcibios_align_resource(void *data, struct resource *res,
 			    unsigned long size, unsigned long align)
 {
-	if (res->flags & IORESOURCE_IO) {
-		unsigned long start = res->start;
+	unsigned long start = res->start;
 
-		if (start & 0x300)
-			res->start = (start + 0x3ff) & ~0x3ff;
-	}
+	if (res->flags & IORESOURCE_IO && start & 0x300)
+		start = (start + 0x3ff) & ~0x3ff;
+
+	res->start = (start + align - 1) & ~(align - 1);
 }
 
 /**
@@ -623,6 +623,13 @@
 		if (r->flags & IORESOURCE_MEM)
 			cmd |= PCI_COMMAND_MEMORY;
 	}
+
+	/*
+	 * Bridges (eg, cardbus bridges) need to be fully enabled
+	 */
+	if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
+		cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
+
 	if (cmd != old_cmd) {
 		printk("PCI: enabling device %s (%04x -> %04x)\n",
 		       dev->slot_name, old_cmd, cmd);
diff -Nru a/arch/arm/kernel/entry-armo.S b/arch/arm/kernel/entry-armo.S
--- a/arch/arm/kernel/entry-armo.S	Mon Nov  4 14:31:01 2002
+++ b/arch/arm/kernel/entry-armo.S	Mon Nov  4 14:31:01 2002
@@ -26,6 +26,7 @@
  *  adhering to the above criteria.
  */
 #include <linux/config.h>
+#include <linux/init.h>
 #include "entry-header.S"
 
 		.text
@@ -597,7 +598,7 @@
  * What we need to put into 0-0x1c are branches to branch to the kernel.
  */
 
-		.section ".text.init",#alloc,#execinstr
+		__INIT
 
 .Ljump_addresses:
 		swi	SYS_ERROR0
diff -Nru a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
--- a/arch/arm/kernel/entry-armv.S	Mon Nov  4 14:31:01 2002
+++ b/arch/arm/kernel/entry-armv.S	Mon Nov  4 14:31:01 2002
@@ -14,6 +14,7 @@
  *  it to save wrong values...  Be aware!
  */
 #include <linux/config.h>
+#include <linux/init.h>
 #include "entry-header.S"
 #include <asm/thread_info.h>
 #include <asm/glue.h>
@@ -593,23 +594,12 @@
 		add	\base, \base, #0x00d00000
 		ldr	\irqstat, [\base, #0]		@ ICIP
 		ldr	\irqnr, [\base, #4]		@ ICMR
-		ands	\irqstat, \irqstat, \irqnr
-		mov	\irqnr, #0
+		ands	\irqnr, \irqstat, \irqnr
 		beq	1001f
-		tst	\irqstat, #0xff00
-		moveq	\irqstat, \irqstat, lsr #8
-		addeq	\irqnr, \irqnr, #8
-		tsteq	\irqstat, #0xff00
-		moveq	\irqstat, \irqstat, lsr #8
-		addeq	\irqnr, \irqnr, #8
-		tst	\irqstat, #0x0f00
-		moveq	\irqstat, \irqstat, lsr #4
-		addeq	\irqnr, \irqnr, #4
-		tst	\irqstat, #0x0300
-		moveq	\irqstat, \irqstat, lsr #2
-		addeq	\irqnr, \irqnr, #2
-		tst	\irqstat, #0x0100
-		addeqs	\irqnr, \irqnr, #1
+		rsb	\irqstat, \irqnr, #0
+		and	\irqstat, \irqstat, \irqnr
+		clz	\irqnr, \irqstat
+		rsb	\irqnr, \irqnr, #23
 1001:
 		.endm
 
@@ -1013,7 +1003,7 @@
 		mcr	p15, 0, r2, c3, c0		@ Set domain register
 		ldmib	r1, {r4 - sl, fp, sp, pc}	@ Load all regs saved previously
 
-		.section ".text.init",#alloc,#execinstr
+		__INIT
 /*
  * Vector stubs.  NOTE that we only align 'vector_IRQ' to a cache line boundary,
  * and we rely on each stub being exactly 48 (1.5 cache lines) in size.  This
diff -Nru a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
--- a/arch/arm/kernel/entry-header.S	Mon Nov  4 14:31:01 2002
+++ b/arch/arm/kernel/entry-header.S	Mon Nov  4 14:31:01 2002
@@ -12,7 +12,7 @@
 #endif
 
 	.macro	zero_fp
-#ifndef CONFIG_NO_FRAME_POINTER
+#ifdef CONFIG_FRAME_POINTER
 	mov	fp, #0
 #endif
 	.endm
diff -Nru a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
--- a/arch/arm/kernel/fiq.c	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/kernel/fiq.c	Mon Nov  4 14:31:02 2002
@@ -37,6 +37,7 @@
  */
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
 #include <linux/init.h>
@@ -203,9 +204,7 @@
 	if (current_fiq != f) {
 		printk(KERN_ERR "%s FIQ trying to release %s FIQ\n",
 		       f->name, current_fiq->name);
-#ifdef CONFIG_DEBUG_ERRORS
-		__backtrace();
-#endif
+		dump_stack();
 		return;
 	}
 
diff -Nru a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
--- a/arch/arm/kernel/head.S	Mon Nov  4 14:31:00 2002
+++ b/arch/arm/kernel/head.S	Mon Nov  4 14:31:00 2002
@@ -11,6 +11,7 @@
  */
 #include <linux/config.h>
 #include <linux/linkage.h>
+#include <linux/init.h>
 
 #include <asm/assembler.h>
 #include <asm/mach-types.h>
@@ -68,7 +69,7 @@
  * crap here - that's what the boot loader (or in extreme, well justified
  * circumstances, zImage) is for.
  */
-	.section ".text.init",#alloc,#execinstr
+	__INIT
 	.type	stext, #function
 ENTRY(stext)
 	mov	r12, r0
diff -Nru a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
--- a/arch/arm/kernel/irq.c	Mon Nov  4 14:31:00 2002
+++ b/arch/arm/kernel/irq.c	Mon Nov  4 14:31:00 2002
@@ -217,7 +217,7 @@
 
 	desc->triggered = 1;
 
-	kstat.irqs[cpu][irq]++;
+	kstat_cpu(cpu).irqs[irq]++;
 
 	action = desc->action;
 	if (action)
@@ -253,7 +253,7 @@
 	 */
 	desc->running = 1;
 
-	kstat.irqs[cpu][irq]++;
+	kstat_cpu(cpu).irqs[irq]++;
 
 	do {
 		struct irqaction *action;
@@ -305,7 +305,7 @@
 	desc->chip->ack(irq);
 
 	if (likely(desc->enabled)) {
-		kstat.irqs[cpu][irq]++;
+		kstat_cpu(cpu).irqs[irq]++;
 
 		/*
 		 * Return with this interrupt masked if no action
@@ -578,9 +578,7 @@
 
 	if (irq >= NR_IRQS || !irq_desc[irq].valid) {
 		printk(KERN_ERR "Trying to free IRQ%d\n",irq);
-#ifdef CONFIG_DEBUG_ERRORS
-		__backtrace();
-#endif
+		dump_stack();
 		return;
 	}
 
@@ -597,15 +595,15 @@
 
 	if (!action) {
 		printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
-#ifdef CONFIG_DEBUG_ERRORS
-		__backtrace();
-#endif
+		dump_stack();
 	} else {
 		synchronize_irq(irq);
 		kfree(action);
 	}
 }
 
+static DECLARE_MUTEX(probe_sem);
+
 /* Start the interrupt probing.  Unlike other architectures,
  * we don't return a mask of interrupts from probe_irq_on,
  * but return the number of interrupts enabled for the probe.
@@ -617,6 +615,8 @@
 	unsigned int i, irqs = 0;
 	unsigned long delay;
 
+	down(&probe_sem);
+
 	/*
 	 * first snaffle up any unassigned but
 	 * probe-able interrupts
@@ -656,6 +656,21 @@
 	return irqs;
 }
 
+unsigned int probe_irq_mask(unsigned long irqs)
+{
+	unsigned int mask = 0, i;
+
+	spin_lock_irq(&irq_controller_lock);
+	for(i = 0; i < 16 && i < NR_IRQS; i++)
+		if (irq_desc[i].probing && irq_desc[i].triggered)
+			mask |= 1 << i;
+	spin_unlock_irq(&irq_controller_lock);
+
+	up(&probe_sem);
+
+	return mask;
+}
+
 /*
  * Possible return values:
  *  >= 0 - interrupt number
@@ -686,6 +701,8 @@
 		irq_found = NO_IRQ;
 out:
 	spin_unlock_irq(&irq_controller_lock);
+
+	up(&probe_sem);
 
 	return irq_found;
 }
diff -Nru a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
--- a/arch/arm/kernel/process.c	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/kernel/process.c	Mon Nov  4 14:31:02 2002
@@ -11,6 +11,7 @@
 #include <stdarg.h>
 
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
@@ -158,6 +159,8 @@
 
 	flags = condition_codes(regs);
 
+	print_symbol("PC is at %s\n", instruction_pointer(regs));
+	print_symbol("LR is at %s\n", regs->ARM_lr);
 	printk("pc : [<%08lx>]    lr : [<%08lx>]    %s\n"
 	       "sp : %08lx  ip : %08lx  fp : %08lx\n",
 		instruction_pointer(regs),
@@ -403,7 +406,7 @@
 	b	sys_exit					\n\
 1:	"
         : "=r" (__ret)
-        : "Ir" (flags), "I" (CLONE_VM), "r" (fn), "r" (arg)
+        : "Ir" (flags), "r" (CLONE_VM | CLONE_UNTRACED), "r" (fn), "r" (arg)
 	: "r0", "r1", "lr");
 	return __ret;
 }
diff -Nru a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
--- a/arch/arm/kernel/ptrace.c	Mon Nov  4 14:31:00 2002
+++ b/arch/arm/kernel/ptrace.c	Mon Nov  4 14:31:00 2002
@@ -692,16 +692,8 @@
 			ret = ptrace_setfpregs(child, (void *)data);
 			break;
 
-		case PTRACE_SETOPTIONS:
-			if (data & PTRACE_O_TRACESYSGOOD)
-				child->ptrace |= PT_TRACESYSGOOD;
-			else
-				child->ptrace &= ~PT_TRACESYSGOOD;
-			ret = 0;
-			break;
-
 		default:
-			ret = -EIO;
+			ret = ptrace_request(child, request, addr, data);
 			break;
 	}
 
diff -Nru a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
--- a/arch/arm/kernel/setup.c	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/kernel/setup.c	Mon Nov  4 14:31:02 2002
@@ -170,6 +170,26 @@
 	"undefined 15",
 };
 
+static const char *proc_arch[] = {
+	"undefined/unknown",
+	"3",
+	"4",
+	"4T",
+	"5",
+	"5T",
+	"5TE",
+	"?(8)",
+	"?(9)",
+	"?(10)",
+	"?(11)",
+	"?(12)",
+	"?(13)",
+	"?(14)",
+	"?(15)",
+	"?(16)",
+	"?(17)",
+};
+
 #define CACHE_TYPE(x)	(((x) >> 25) & 15)
 #define CACHE_S(x)	((x) & (1 << 24))
 #define CACHE_DSIZE(x)	(((x) >> 12) & 4095)	/* only if S=1 */
@@ -214,6 +234,23 @@
 #define dump_cpu_info() do { } while (0)
 #endif
 
+int cpu_architecture(void)
+{
+	int cpu_arch;
+
+	if ((processor_id & 0x0000f000) == 0) {
+		cpu_arch = CPU_ARCH_UNKNOWN;
+	} else if ((processor_id & 0x0000f000) == 0x00007000) {
+		cpu_arch = (processor_id & (1 << 23)) ? CPU_ARCH_ARMv4T : CPU_ARCH_ARMv3;
+	} else {
+		cpu_arch = (processor_id >> 16) & 15;
+		if (cpu_arch)
+			cpu_arch += CPU_ARCH_ARMv3;
+	}
+
+	return cpu_arch;
+}
+
 static void __init setup_processor(void)
 {
 	extern struct proc_info_list __proc_info_begin, __proc_info_end;
@@ -250,9 +287,9 @@
 	cpu_user = *list->user;
 #endif
 
-	printk("CPU: %s %s revision %d\n",
+	printk("CPU: %s %s revision %d (ARMv%s)\n",
 	       proc_info.manufacturer, proc_info.cpu_name,
-	       (int)processor_id & 15);
+	       (int)processor_id & 15, proc_arch[cpu_architecture()]);
 
 	dump_cpu_info();
 
@@ -666,25 +703,6 @@
 	NULL
 };
 
-static const char *proc_arch[16] = {
-	"undefined 0",
-	"4",
-	"4T",
-	"5",
-	"5T",
-	"5TE",
-	"undefined 6",
-	"undefined 7",
-	"undefined 8",
-	"undefined 9",
-	"undefined 10",
-	"undefined 11",
-	"undefined 12",
-	"undefined 13",
-	"undefined 14",
-	"undefined 15"
-};
-
 static void
 c_show_cache(struct seq_file *m, const char *type, unsigned int cache)
 {
@@ -720,30 +738,23 @@
 		if (elf_hwcap & (1 << i))
 			seq_printf(m, "%s ", hwcap_str[i]);
 
-	seq_puts(m, "\n");
+	seq_printf(m, "\nCPU implementer\t: 0x%02x\n", processor_id >> 24);
+	seq_printf(m, "CPU architecture: %s\n", proc_arch[cpu_architecture()]);
 
 	if ((processor_id & 0x0000f000) == 0x00000000) {
 		/* pre-ARM7 */
 		seq_printf(m, "CPU part\t\t: %07x\n", processor_id >> 4);
-	} else if ((processor_id & 0x0000f000) == 0x00007000) {
-		/* ARM7 */
-		seq_printf(m, "CPU implementor\t: 0x%02x\n"
-			      "CPU architecture: %s\n"
-			      "CPU variant\t: 0x%02x\n"
-			      "CPU part\t: 0x%03x\n",
-			   processor_id >> 24,
-			   processor_id & (1 << 23) ? "4T" : "3",
-			   (processor_id >> 16) & 127,
-			   (processor_id >> 4) & 0xfff);
 	} else {
-		/* post-ARM7 */
-		seq_printf(m, "CPU implementor\t: 0x%02x\n"
-			      "CPU architecture: %s\n"
-			      "CPU variant\t: 0x%x\n"
-			      "CPU part\t: 0x%03x\n",
-			   processor_id >> 24,
-			   proc_arch[(processor_id >> 16) & 15],
-			   (processor_id >> 20) & 15,
+		if ((processor_id & 0x0000f000) == 0x00007000) {
+			/* ARM7 */
+			seq_printf(m, "CPU variant\t: 0x%02x\n",
+				   (processor_id >> 16) & 127);
+		} else {
+			/* post-ARM7 */
+			seq_printf(m, "CPU variant\t: 0x%x\n",
+				   (processor_id >> 20) & 15);
+		}
+		seq_printf(m, "CPU part\t: 0x%03x\n",
 			   (processor_id >> 4) & 0xfff);
 	}
 	seq_printf(m, "CPU revision\t: %d\n", processor_id & 15);
diff -Nru a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
--- a/arch/arm/kernel/traps.c	Mon Nov  4 14:31:01 2002
+++ b/arch/arm/kernel/traps.c	Mon Nov  4 14:31:01 2002
@@ -13,6 +13,7 @@
  *  kill the offending process.
  */
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
@@ -48,6 +49,12 @@
 
 static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
 
+void dump_backtrace_entry(unsigned long where, unsigned long from)
+{
+	printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
+	print_symbol("  %s\n", where);
+}
+
 /*
  * Stack pointers should always be within the kernels view of
  * physical memory.  If it is not there, then we can't dump
@@ -162,6 +169,13 @@
 		c_backtrace(fp, processor_mode(regs));
 }
 
+void dump_stack(void)
+{
+#ifdef CONFIG_DEBUG_ERRORS
+	__backtrace();
+#endif
+}
+
 /*
  * This is called from SysRq-T (show_task) to display the current call
  * trace for each process.  This version will also display the running
@@ -190,8 +204,10 @@
 
 	console_verbose();
 	spin_lock_irq(&die_lock);
+	bust_spinlocks(1);
 
 	printk("Internal error: %s: %x\n", str, err);
+	print_modules();
 	printk("CPU: %d\n", smp_processor_id());
 	show_regs(regs);
 	printk("Process %s (pid: %d, stack limit = 0x%p)\n",
@@ -203,6 +219,7 @@
 		dump_instr(regs);
 	}
 
+	bust_spinlocks(0);
 	spin_unlock_irq(&die_lock);
 	do_exit(SIGSEGV);
 }
@@ -517,7 +534,7 @@
 asmlinkage void __div0(void)
 {
 	printk("Division by zero in kernel.\n");
-	__backtrace();
+	dump_stack();
 }
 
 void abort(void)
diff -Nru a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
--- a/arch/arm/lib/Makefile	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/lib/Makefile	Mon Nov  4 14:31:02 2002
@@ -26,12 +26,12 @@
 
 obj-y		+= $(obj-$(MACHINE))
 
-ifeq ($(CONFIG_CPU_32v4),y)
-  v3		:= n
-  v4		:= y
-else
+ifeq ($(CONFIG_CPU_32v3),y)
   v3		:= y
   v4		:= n
+else
+  v3		:= n
+  v4		:= y
 endif
 
 obj-y		+= io-readsb.o io-writesb.o
diff -Nru a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S
--- a/arch/arm/lib/backtrace.S	Mon Nov  4 14:31:01 2002
+++ b/arch/arm/lib/backtrace.S	Mon Nov  4 14:31:01 2002
@@ -26,7 +26,7 @@
 
 ENTRY(c_backtrace)
 
-#ifdef CONFIG_NO_FRAME_POINTER
+#ifndef CONFIG_FRAME_POINTER
 		mov	pc, lr
 #else
 
@@ -62,10 +62,9 @@
 		ldr	r3, .Ldsi+4
 		teq	r1, r3
 		subeq	save, save, #4
-		adr	r0, .Lfe
-		mov	r1, save
-		bic	r2, r2, mask
-		bl	printk			@ print pc and link register
+		mov	r0, save
+		bic	r1, r2, mask
+		bl	dump_backtrace_entry
 
 		ldr	r0, [frame, #-8]	@ get sp
 		sub	r0, r0, #4
@@ -140,7 +139,6 @@
 		mov	r0, stack
 		LOADREGS(fd, sp!, {instr, reg, stack, r7, pc})
 
-.Lfe:		.asciz	"Function entered at [<%p>] from [<%p>]\n"
 .Lfp:		.asciz	" r%d = %08X%c"
 .Lcr:		.asciz	"\n"
 .Lbad:		.asciz	"Backtrace aborted due to bad frame pointer <%p>\n"
diff -Nru a/arch/arm/mach-arc/head.S b/arch/arm/mach-arc/head.S
--- a/arch/arm/mach-arc/head.S	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/mach-arc/head.S	Mon Nov  4 14:31:02 2002
@@ -11,6 +11,7 @@
  */
 #include <linux/config.h>
 #include <linux/linkage.h>
+#include <linux/init.h>
 #include <asm/mach-types.h>
 
 		.globl	swapper_pg_dir
@@ -19,7 +20,7 @@
 /*
  * Entry point.
  */
-		.section ".text.init",#alloc,#execinstr
+		__INIT
 ENTRY(stext)
 __entry:	cmp	pc, #0x02000000
 		ldrlt	pc, LC0			@ if 0x01800000, call at 0x02080000
diff -Nru a/arch/arm/mach-clps711x/time.c b/arch/arm/mach-clps711x/time.c
--- a/arch/arm/mach-clps711x/time.c	Mon Nov  4 14:31:00 2002
+++ b/arch/arm/mach-clps711x/time.c	Mon Nov  4 14:31:00 2002
@@ -35,7 +35,7 @@
 {
 	unsigned long hwticks;
 	hwticks = LATCH - (clps_readl(TC2D) & 0xffff);	/* since last underflow */
-	return (hwticks * tick) / LATCH;
+	return (hwticks * (tick_nsec / 1000)) / LATCH;
 }
 
 void __init clps711x_setup_timer(void)
diff -Nru a/arch/arm/mach-footbridge/mm.c b/arch/arm/mach-footbridge/mm.c
--- a/arch/arm/mach-footbridge/mm.c	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/mach-footbridge/mm.c	Mon Nov  4 14:31:02 2002
@@ -84,12 +84,8 @@
  */
 unsigned long __virt_to_bus(unsigned long res)
 {
-#ifdef CONFIG_DEBUG_ERRORS
-	if (res < PAGE_OFFSET || res >= (unsigned long)high_memory) {
-		printk("__virt_to_bus: invalid virtual address 0x%08lx\n", res);
-		__backtrace();
-	}
-#endif
+	WARN_ON(res < PAGE_OFFSET || res >= (unsigned long)high_memory);
+
 	return (res - PAGE_OFFSET) + (*CSR_PCISDRAMBASE & 0xfffffff0);
 }
 
@@ -98,12 +94,8 @@
 	res -= (*CSR_PCISDRAMBASE & 0xfffffff0);
 	res += PAGE_OFFSET;
 
-#ifdef CONFIG_DEBUG_ERRORS
-	if (res < PAGE_OFFSET || res >= (unsigned long)high_memory) {
-		printk("__bus_to_virt: invalid virtual address 0x%08lx\n", res);
-		__backtrace();
-	}
-#endif
+	WARN_ON(res < PAGE_OFFSET || res >= (unsigned long)high_memory);
+
 	return res;
 }
 
diff -Nru a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
--- a/arch/arm/mach-pxa/generic.c	Mon Nov  4 14:31:01 2002
+++ b/arch/arm/mach-pxa/generic.c	Mon Nov  4 14:31:01 2002
@@ -31,31 +31,63 @@
 #include "generic.h"
 
 /*
- * Return the current lclk requency in units of 10kHz
+ * Various clock factors driven by the CCCR register.
  */
-unsigned int get_lclk_frequency_10khz(void)
+
+/* Crystal Frequency to Memory Frequency Multiplier (L) */
+static unsigned char L_clk_mult[32] = { 0, 27, 32, 36, 40, 45, 0, };
+
+/* Memory Frequency to Run Mode Frequency Multiplier (M) */
+static unsigned char M_clk_mult[4] = { 0, 1, 2, 0 };
+
+/* Run Mode Frequency to Turbo Mode Frequency Multiplier (N) */
+/* Note: we store the value N * 2 here. */
+static unsigned char N2_clk_mult[8] = { 0, 0, 2, 3, 4, 0, 6, 0 };
+
+/* Crystal clock */
+#define BASE_CLK	3686400
+
+
+/*
+ * Display what we were booted with.
+ */
+static int __init pxa_display_clocks(void)
 {
-	unsigned int l;
+	unsigned long cccr, turbo;
+	unsigned int l, L, m, M, n2, N;
 
-	l = CCCR & 0x1f;
+	cccr = CCCR;
+	asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (turbo) );
 
-	switch(l)
-	{
-		case 1:
-			return 9953;
-		case 2:
-			return 11796;
-		case 3:
-			return 13271;
-		case 4:
-			return 14746;
-		case 5:
-			return 16589;
-		case 0xf:
-			return 3320;
-		default:
-			return 0;
-	}
+	l  =  L_clk_mult[(cccr >> 0) & 0x1f];
+	m  =  M_clk_mult[(cccr >> 5) & 0x03];
+	n2 = N2_clk_mult[(cccr >> 7) & 0x07];
+
+	L = l * BASE_CLK;
+	M = m * L;
+	N = n2 * M / 2;
+
+	L += 5000;
+	printk( KERN_INFO "Memory clock: %d.%02dMHz (*%d)\n",
+		L / 1000000, (L % 1000000) / 10000, l );
+	M += 5000;
+	printk( KERN_INFO "Run Mode clock: %d.%02dMHz (*%d)\n",
+		M / 1000000, (M % 1000000) / 10000, m );
+	N += 5000;
+	printk( KERN_INFO "Turbo Mode clock: %d.%02dMHz (*%d.%d, %sactive)\n",
+		N / 1000000, (N % 1000000) / 10000, n2 / 2, (n2 % 2) * 5,
+		(turbo & 1) ? "" : "in" );
+
+	return 0;
+}
+
+
+/*
+ * Return the current lclk requency in units of 10kHz
+ */
+unsigned int get_lclk_frequency_10khz(void)
+{
+	return L_clk_mult[(CCCR >> 0) & 0x1f] * BASE_CLK / 10000;
 }
 
 EXPORT_SYMBOL(get_lclk_frequency_10khz);
@@ -100,4 +132,5 @@
 void __init pxa_map_io(void)
 {
 	iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
+	pxa_display_clocks();
 }
diff -Nru a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c
--- a/arch/arm/mach-sa1100/badge4.c	Mon Nov  4 14:31:00 2002
+++ b/arch/arm/mach-sa1100/badge4.c	Mon Nov  4 14:31:00 2002
@@ -31,6 +31,8 @@
 #include <asm/hardware/sa1111.h>
 #include <asm/mach/serial_sa1100.h>
 
+#include <asm/arch/badge4.h>
+
 #include "generic.h"
 
 static int __init badge4_sa1111_init(void)
@@ -47,6 +49,17 @@
 	return sa1111_init(BADGE4_SA1111_BASE, BADGE4_IRQ_GPIO_SA1111);
 }
 
+
+static int five_v_on __initdata = 0;
+
+static int __init five_v_on_setup(char *ignore)
+{
+        five_v_on = 1;
+	return 1;
+}
+__setup("five_v_on", five_v_on_setup);
+
+
 static int __init badge4_init(void)
 {
 	int ret;
@@ -54,24 +67,18 @@
 	if (!machine_is_badge4())
 		return -ENODEV;
 
-	ret = badge4_sa1111_init();
-	if (ret < 0)
-		printk(KERN_ERR
-		       "%s: SA-1111 initialization failed (%d)\n",
-			__FUNCTION__, ret);
-
-	/* N.B, according to rmk this is the singular place that GPDR
-           should be set */
-
-	/* Video expansion */
-	GPCR  = (BADGE4_GPIO_INT_VID | BADGE4_GPIO_LGP2 | BADGE4_GPIO_LGP3 |
-		 BADGE4_GPIO_LGP4 | BADGE4_GPIO_LGP5 | BADGE4_GPIO_LGP6 |
-		 BADGE4_GPIO_LGP7 | BADGE4_GPIO_LGP8 | BADGE4_GPIO_LGP9 |
+	/* LCD */
+	GPCR  = (BADGE4_GPIO_LGP2 | BADGE4_GPIO_LGP3 |
+		 BADGE4_GPIO_LGP4 | BADGE4_GPIO_LGP5 |
+		 BADGE4_GPIO_LGP6 | BADGE4_GPIO_LGP7 |
+		 BADGE4_GPIO_LGP8 | BADGE4_GPIO_LGP9 |
 		 BADGE4_GPIO_GPA_VID | BADGE4_GPIO_GPB_VID |
 		 BADGE4_GPIO_GPC_VID);
-	GPDR |= (BADGE4_GPIO_INT_VID | BADGE4_GPIO_LGP2 | BADGE4_GPIO_LGP3 |
-		 BADGE4_GPIO_LGP4 | BADGE4_GPIO_LGP5 | BADGE4_GPIO_LGP6 |
-		 BADGE4_GPIO_LGP7 | BADGE4_GPIO_LGP8 | BADGE4_GPIO_LGP9 |
+	GPDR &= ~BADGE4_GPIO_INT_VID;
+	GPDR |= (BADGE4_GPIO_LGP2 | BADGE4_GPIO_LGP3 |
+		 BADGE4_GPIO_LGP4 | BADGE4_GPIO_LGP5 |
+		 BADGE4_GPIO_LGP6 | BADGE4_GPIO_LGP7 |
+		 BADGE4_GPIO_LGP8 | BADGE4_GPIO_LGP9 |
 		 BADGE4_GPIO_GPA_VID | BADGE4_GPIO_GPB_VID |
 		 BADGE4_GPIO_GPC_VID);
 
@@ -83,28 +90,55 @@
 	GPCR  = (BADGE4_GPIO_UART_HS1 | BADGE4_GPIO_UART_HS2);
 	GPDR |= (BADGE4_GPIO_UART_HS1 | BADGE4_GPIO_UART_HS2);
 
-	/* drives CPLD muxsel0 input */
+	/* CPLD muxsel0 input for mux/adc chip select */
 	GPCR  = BADGE4_GPIO_MUXSEL0;
 	GPDR |= BADGE4_GPIO_MUXSEL0;
 
-	/* test points */
-	GPCR  = (BADGE4_GPIO_TESTPT_J7 | BADGE4_GPIO_TESTPT_J6 |
-		 BADGE4_GPIO_TESTPT_J5);
-	GPDR |= (BADGE4_GPIO_TESTPT_J7 | BADGE4_GPIO_TESTPT_J6 |
-		 BADGE4_GPIO_TESTPT_J5);
-
-	/* drives CPLD sdram type inputs; this shouldn't be needed;
-           bootloader left it this way. */
-	GPDR |= (BADGE4_GPIO_SDTYP0 | BADGE4_GPIO_SDTYP1);
+	/* test points: J5, J6 as inputs, J7 outputs */
+	GPDR &= ~(BADGE4_GPIO_TESTPT_J5 | BADGE4_GPIO_TESTPT_J6);
+	GPCR  = BADGE4_GPIO_TESTPT_J7;
+	GPDR |= BADGE4_GPIO_TESTPT_J7;
 
  	/* 5V supply rail. */
  	GPCR  = BADGE4_GPIO_PCMEN5V;		/* initially off */
   	GPDR |= BADGE4_GPIO_PCMEN5V;
 
-	/* drives SA1111 reset pin; this shouldn't be needed;
-           bootloader left it this way. */
-	GPSR  = BADGE4_GPIO_SA1111_NRST;
-	GPDR |= BADGE4_GPIO_SA1111_NRST;
+	/* CPLD sdram type inputs; set up by blob */
+	//GPDR |= (BADGE4_GPIO_SDTYP1 | BADGE4_GPIO_SDTYP0);
+	printk(KERN_DEBUG __FILE__ ": SDRAM CPLD typ1=%d typ0=%d\n",
+	       !!(GPLR & BADGE4_GPIO_SDTYP1),
+	       !!(GPLR & BADGE4_GPIO_SDTYP0));
+
+	/* SA1111 reset pin; set up by blob */
+	//GPSR  = BADGE4_GPIO_SA1111_NRST;
+	//GPDR |= BADGE4_GPIO_SA1111_NRST;
+
+
+	/* power management cruft */
+	PGSR = 0;
+	PWER = 0;
+	PCFR = 0;
+	PSDR = 0;
+
+	PWER |= PWER_GPIO26;	/* wake up on an edge from TESTPT_J5 */
+	PWER |= PWER_RTC;	/* wake up if rtc fires */
+
+	/* drive sa1111_nrst during sleep */
+	PGSR |= BADGE4_GPIO_SA1111_NRST;
+	/* drive CPLD as is during sleep */
+	PGSR |= (GPLR & (BADGE4_GPIO_SDTYP0|BADGE4_GPIO_SDTYP1));
+
+
+	/* Now bring up the SA-1111. */
+	ret = badge4_sa1111_init();
+	if (ret < 0)
+		printk(KERN_ERR
+		       "%s: SA-1111 initialization failed (%d)\n",
+		       __FUNCTION__, ret);
+
+
+	/* maybe turn on 5v0 from the start */
+	badge4_set_5V(BADGE4_5V_INITIALLY, five_v_on);
 
 	return 0;
 }
diff -Nru a/arch/arm/mm/copypage-v3.S b/arch/arm/mm/copypage-v3.S
--- a/arch/arm/mm/copypage-v3.S	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/mm/copypage-v3.S	Mon Nov  4 14:31:02 2002
@@ -10,6 +10,7 @@
  *  ASM optimised string functions
  */
 #include <linux/linkage.h>
+#include <linux/init.h>
 #include <asm/assembler.h>
 #include <asm/constants.h>
 
@@ -57,7 +58,7 @@
 	bne	1b				@ 1
 	ldr	pc, [sp], #4
 
-	.section ".text.init", #alloc, #execinstr
+	__INIT
 
 ENTRY(v3_user_fns)
 	.long	v3_clear_user_page
diff -Nru a/arch/arm/mm/copypage-v4mc.S b/arch/arm/mm/copypage-v4mc.S
--- a/arch/arm/mm/copypage-v4mc.S	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/mm/copypage-v4mc.S	Mon Nov  4 14:31:02 2002
@@ -10,6 +10,7 @@
  *  ASM optimised string functions
  */
 #include <linux/linkage.h>
+#include <linux/init.h>
 #include <asm/constants.h>
 
 	.text
@@ -70,7 +71,7 @@
 	bne	1b				@ 1
 	ldr	pc, [sp], #4
 
-	.section ".text.init", #alloc, #execinstr
+	__INIT
 
 ENTRY(v4_mc_user_fns)
 	.long	v4_mc_clear_user_page
diff -Nru a/arch/arm/mm/copypage-v4wb.S b/arch/arm/mm/copypage-v4wb.S
--- a/arch/arm/mm/copypage-v4wb.S	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/mm/copypage-v4wb.S	Mon Nov  4 14:31:02 2002
@@ -10,6 +10,7 @@
  *  ASM optimised string functions
  */
 #include <linux/linkage.h>
+#include <linux/init.h>
 #include <asm/constants.h>
 
 	.text
@@ -69,7 +70,7 @@
 	mcr	p15, 0, r1, c7, c10, 4		@ 1   drain WB
 	ldr	pc, [sp], #4
 
-	.section ".text.init", #alloc, #execinstr
+	__INIT
 
 ENTRY(v4wb_user_fns)
 	.long	v4wb_clear_user_page
diff -Nru a/arch/arm/mm/copypage-v4wt.S b/arch/arm/mm/copypage-v4wt.S
--- a/arch/arm/mm/copypage-v4wt.S	Mon Nov  4 14:31:01 2002
+++ b/arch/arm/mm/copypage-v4wt.S	Mon Nov  4 14:31:01 2002
@@ -13,6 +13,7 @@
  *  the only supported cache operation.
  */
 #include <linux/linkage.h>
+#include <linux/init.h>
 #include <asm/constants.h>
 
 	.text
@@ -63,7 +64,7 @@
 	mcr	p15, 0, r2, c7, c7, 0		@ flush ID cache
 	ldr	pc, [sp], #4
 
-	.section ".text.init", #alloc, #execinstr
+	__INIT
 
 ENTRY(v4wt_user_fns)
 	.long	v4wt_clear_user_page
diff -Nru a/arch/arm/mm/copypage-xscale.S b/arch/arm/mm/copypage-xscale.S
--- a/arch/arm/mm/copypage-xscale.S	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/mm/copypage-xscale.S	Mon Nov  4 14:31:02 2002
@@ -8,6 +8,7 @@
  * published by the Free Software Foundation.
  */
 #include <linux/linkage.h>
+#include <linux/init.h>
 #include <asm/constants.h>
 
 /*
@@ -78,7 +79,7 @@
 	bne	1b
 	ldr	pc, [sp], #4
 
-	.section ".text.init", #alloc, #execinstr
+	__INIT
 
 ENTRY(xscale_mc_user_fns)
 	.long	xscale_mc_clear_user_page
diff -Nru a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
--- a/arch/arm/mm/ioremap.c	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/mm/ioremap.c	Mon Nov  4 14:31:02 2002
@@ -8,9 +8,7 @@
  * Hacked for ARM by Phil Blundell <philb@gnu.org>
  * Hacked to allow all architectures to build, and various cleanups
  * by Russell King
- */
-
-/*
+ *
  * This allows a driver to remap an arbitrary region of bus memory into
  * virtual space.  One should *only* use readl, writel, memcpy_toio and
  * so on with such remapped areas.
@@ -21,11 +19,6 @@
  * two 2GB chunks and mapping only one at a time into processor memory.
  * We use MMU protection domains to trap any attempt to access the bank
  * that is not currently mapped.  (This isn't fully implemented yet.)
- *
- * DC21285 currently has a bug in that the PCI address extension
- * register affects the address of any writes waiting in the outbound
- * FIFO.  Unfortunately, it is not possible to tell the DC21285 to
- * flush this - flushing the area causes the bus to lock.
  */
 #include <linux/errno.h>
 #include <linux/mm.h>
@@ -34,6 +27,7 @@
 #include <asm/page.h>
 #include <asm/pgalloc.h>
 #include <asm/io.h>
+#include <asm/tlbflush.h>
 
 static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
 	unsigned long phys_addr, pgprot_t pgprot)
@@ -76,7 +70,7 @@
 
 	pgprot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE | flags);
 	do {
-		pte_t * pte = pte_alloc(&init_mm, pmd, address);
+		pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
 		if (!pte)
 			return -ENOMEM;
 		remap_area_pte(pte, address, end - address, address + phys_addr, pgprot);
@@ -129,7 +123,9 @@
  * 'flags' are the extra L_PTE_ flags that you want to specify for this
  * mapping.  See include/asm-arm/proc-armv/pgtable.h for more information.
  */
-void * __ioremap(unsigned long phys_addr, size_t size, unsigned long flags)
+void *
+__ioremap(unsigned long phys_addr, size_t size, unsigned long flags,
+	  unsigned long align)
 {
 	void * addr;
 	struct vm_struct * area;
diff -Nru a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
--- a/arch/arm/mm/mm-armv.c	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/mm/mm-armv.c	Mon Nov  4 14:31:02 2002
@@ -169,7 +169,7 @@
 	pmd_t *pmdp, pmd;
 
 	pmdp = pmd_offset(pgd_offset_k(virt), virt);
-	if (virt & (1 << PMD_SHIFT))
+	if (virt & (1 << 20))
 		pmdp++;
 
 	pmd_val(pmd) = phys | prot;
@@ -184,7 +184,7 @@
  * the hardware pte table.
  */
 static inline void
-alloc_init_page(unsigned long virt, unsigned long phys, int domain, int prot)
+alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot)
 {
 	pmd_t *pmdp, pmd;
 	pte_t *ptep;
@@ -195,14 +195,14 @@
 		ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE *
 					       sizeof(pte_t));
 
-		pmd_val(pmd) = __pa(ptep) | PMD_TYPE_TABLE | PMD_DOMAIN(domain);
+		pmd_val(pmd) = __pa(ptep) | prot_l1;
 		set_pmd(pmdp, pmd);
 		pmd_val(pmd) += 256 * sizeof(pte_t);
 		set_pmd(pmdp + 1, pmd);
 	}
 	ptep = pte_offset_kernel(pmdp, virt);
 
-	set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, __pgprot(prot)));
+	set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot));
 }
 
 /*
@@ -217,6 +217,7 @@
 
 struct mem_types {
 	unsigned int	prot_pte;
+	unsigned int	prot_l1;
 	unsigned int	prot_sect;
 	unsigned int	domain;
 };
@@ -225,41 +226,83 @@
 	[MT_DEVICE] = {
 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
 				L_PTE_WRITE,
-		.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
+		.prot_l1   = PMD_TYPE_TABLE | PMD_BIT4,
+		.prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED |
+				PMD_SECT_AP_WRITE,
 		.domain    = DOMAIN_IO,
 	},
 	[MT_CACHECLEAN] = {
 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
 				L_PTE_CACHEABLE | L_PTE_BUFFERABLE,
-		.prot_sect = PMD_TYPE_SECT | PMD_SECT_CACHEABLE |
-				PMD_SECT_BUFFERABLE,
+		.prot_l1   = PMD_TYPE_TABLE | PMD_BIT4,
+		.prot_sect = PMD_TYPE_SECT | PMD_BIT4,
 		.domain    = DOMAIN_KERNEL,
 	},
 	[MT_MINICLEAN] = {
 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
 				L_PTE_CACHEABLE,
-		.prot_sect = PMD_TYPE_SECT | PMD_SECT_CACHEABLE,
+		.prot_l1   = PMD_TYPE_TABLE | PMD_BIT4,
+		.prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_MINICACHE,
 		.domain    = DOMAIN_KERNEL,
 	},
 	[MT_VECTORS] = {
 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
 				L_PTE_CACHEABLE | L_PTE_BUFFERABLE |
 				L_PTE_EXEC,
-		.prot_sect = PMD_TYPE_SECT | PMD_SECT_CACHEABLE |
-				PMD_SECT_BUFFERABLE,
+		.prot_l1   = PMD_TYPE_TABLE | PMD_BIT4,
+		.prot_sect = PMD_TYPE_SECT | PMD_BIT4,
 		.domain    = DOMAIN_USER,
 	},
 	[MT_MEMORY] = {
 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
 				L_PTE_CACHEABLE | L_PTE_BUFFERABLE |
 				L_PTE_EXEC | L_PTE_WRITE,
-		.prot_sect = PMD_TYPE_SECT | PMD_SECT_CACHEABLE |
-				PMD_SECT_BUFFERABLE | PMD_SECT_AP_WRITE,
+		.prot_l1   = PMD_TYPE_TABLE | PMD_BIT4,
+		.prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_AP_WRITE,
 		.domain    = DOMAIN_KERNEL,
 	}
 };
 
 /*
+ * Adjust the PMD section entries according to the CPU in use.
+ */
+static void __init build_mem_type_table(void)
+{
+	int cpu_arch = cpu_architecture();
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	int writethrough = 1;
+#else
+	int writethrough = 0;
+#endif
+	int writealloc = 0, ecc = 0;
+
+	if (cpu_arch < CPU_ARCH_ARMv5) {
+		writealloc = 0;
+		ecc = 0;
+		mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1);
+	}
+
+	if (writethrough) {
+		mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT;
+		mem_types[MT_VECTORS].prot_sect |= PMD_SECT_WT;
+		mem_types[MT_MEMORY].prot_sect |= PMD_SECT_WT;
+	} else {
+		mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WB;
+		mem_types[MT_VECTORS].prot_sect |= PMD_SECT_WB;
+
+		if (writealloc)
+			mem_types[MT_MEMORY].prot_sect |= PMD_SECT_WBWA;
+		else
+			mem_types[MT_MEMORY].prot_sect |= PMD_SECT_WB;
+	}
+
+	if (ecc) {
+		mem_types[MT_VECTORS].prot_sect |= PMD_PROTECTION;
+		mem_types[MT_MEMORY].prot_sect |= PMD_PROTECTION;
+	}
+}
+
+/*
  * Create the page directory entries and any necessary
  * page tables for the mapping specified by `md'.  We
  * are able to cope here with varying sizes and address
@@ -268,7 +311,8 @@
 static void __init create_mapping(struct map_desc *md)
 {
 	unsigned long virt, length;
-	int prot_sect, prot_pte, domain;
+	int prot_sect, prot_l1, domain;
+	pgprot_t prot_pte;
 	long off;
 
 	if (md->virtual != vectors_base() && md->virtual < PAGE_OFFSET) {
@@ -279,7 +323,8 @@
 	}
 
 	domain	  = mem_types[md->type].domain;
-	prot_pte  = mem_types[md->type].prot_pte;
+	prot_pte  = __pgprot(mem_types[md->type].prot_pte);
+	prot_l1   = mem_types[md->type].prot_l1 | PMD_DOMAIN(domain);
 	prot_sect = mem_types[md->type].prot_sect | PMD_DOMAIN(domain);
 
 	virt   = md->virtual;
@@ -287,7 +332,7 @@
 	length = md->length;
 
 	while ((virt & 0xfffff || (virt + off) & 0xfffff) && length >= PAGE_SIZE) {
-		alloc_init_page(virt, virt + off, domain, prot_pte);
+		alloc_init_page(virt, virt + off, prot_l1, prot_pte);
 
 		virt   += PAGE_SIZE;
 		length -= PAGE_SIZE;
@@ -301,7 +346,7 @@
 	}
 
 	while (length >= PAGE_SIZE) {
-		alloc_init_page(virt, virt + off, domain, prot_pte);
+		alloc_init_page(virt, virt + off, prot_l1, prot_pte);
 
 		virt   += PAGE_SIZE;
 		length -= PAGE_SIZE;
@@ -342,6 +387,8 @@
 	struct map_desc *init_maps, *p, *q;
 	unsigned long address = 0;
 	int i;
+
+	build_mem_type_table();
 
 	init_maps = p = alloc_bootmem_low_pages(PAGE_SIZE);
 
diff -Nru a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
--- a/arch/arm/mm/proc-arm1020.S	Mon Nov  4 14:31:00 2002
+++ b/arch/arm/mm/proc-arm1020.S	Mon Nov  4 14:31:00 2002
@@ -26,6 +26,7 @@
  */
 #include <linux/linkage.h>
 #include <linux/config.h>
+#include <linux/init.h>
 #include <asm/assembler.h>
 #include <asm/constants.h>
 #include <asm/procinfo.h>
@@ -374,11 +375,6 @@
  */
 	.align	5
 ENTRY(cpu_arm1020_set_pmd)
-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-	eor	r2, r1, #0x0a			@ C & Section
-	tst	r2, #0x0b
-	biceq	r1, r1, #4			@ clear bufferable bit
-#endif
 	str	r1, [r0]
 #ifndef CONFIG_CPU_DCACHE_DISABLE
 	mcr	p15, 0, r0, c7, c10, 4
@@ -450,7 +446,7 @@
 	.ascii	"\0"
 	.align
 
-	.section ".text.init", #alloc, #execinstr
+	__INIT
 
 __arm1020_setup:
 	mov	r0, #0
diff -Nru a/arch/arm/mm/proc-arm2_3.S b/arch/arm/mm/proc-arm2_3.S
--- a/arch/arm/mm/proc-arm2_3.S	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/mm/proc-arm2_3.S	Mon Nov  4 14:31:02 2002
@@ -13,6 +13,7 @@
  *  and memory functions on ARM2, ARM250 and ARM3 processors.
  */
 #include <linux/linkage.h>
+#include <linux/init.h>
 #include <asm/assembler.h>
 #include <asm/constants.h>
 #include <asm/procinfo.h>
@@ -280,7 +281,7 @@
 _arm250_name:	.asciz	"ARM 250"
 _arm3_name:	.asciz	"ARM 3"
 
-		.section ".text.init", #alloc, #execinstr
+		__INIT
 /*
  * Purpose : Function pointers used to access above functions - all calls
  *	     come through these
diff -Nru a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
--- a/arch/arm/mm/proc-arm6_7.S	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/mm/proc-arm6_7.S	Mon Nov  4 14:31:02 2002
@@ -11,6 +11,7 @@
  *  functions on the ARM610 & ARM710.
  */
 #include <linux/linkage.h>
+#include <linux/init.h>
 #include <asm/assembler.h>
 #include <asm/constants.h>
 #include <asm/procinfo.h>
@@ -316,7 +317,7 @@
 		.asciz	"ARM 710"
 		.align
 
-		.section ".text.init", #alloc, #execinstr
+		__INIT
 
 __arm6_setup:	mov	r0, #0
 		mcr	p15, 0, r0, c7, c0		@ flush caches on v3
diff -Nru a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
--- a/arch/arm/mm/proc-arm720.S	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/mm/proc-arm720.S	Mon Nov  4 14:31:02 2002
@@ -31,6 +31,7 @@
  *   08-25-2000	DBS	Updated for integration of ARM Ltd version.
  */
 #include <linux/linkage.h>
+#include <linux/init.h>
 #include <asm/assembler.h>
 #include <asm/constants.h>
 #include <asm/procinfo.h>
@@ -177,7 +178,7 @@
 		.asciz	"ARM720T"
 		.align
 
-		.section ".text.init", #alloc, #execinstr
+		__INIT
 
 __arm720_setup:	mov	r0, #0
 		mcr	p15, 0, r0, c7, c7, 0		@ invalidate caches
diff -Nru a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
--- a/arch/arm/mm/proc-arm920.S	Mon Nov  4 14:31:00 2002
+++ b/arch/arm/mm/proc-arm920.S	Mon Nov  4 14:31:00 2002
@@ -26,6 +26,7 @@
  */
 #include <linux/linkage.h>
 #include <linux/config.h>
+#include <linux/init.h>
 #include <asm/assembler.h>
 #include <asm/constants.h>
 #include <asm/procinfo.h>
@@ -377,11 +378,6 @@
  */
 	.align	5
 ENTRY(cpu_arm920_set_pmd)
-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-	eor	r2, r1, #0x0a			@ C & Section
-	tst	r2, #0x0b
-	biceq	r1, r1, #4			@ clear bufferable bit
-#endif
 	str	r1, [r0]
 	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
@@ -443,7 +439,7 @@
 	.ascii	"\0"
 	.align
 
-	.section ".text.init", #alloc, #execinstr
+	__INIT
 
 __arm920_setup:
 	mov	r0, #0
diff -Nru a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
--- a/arch/arm/mm/proc-arm922.S	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/mm/proc-arm922.S	Mon Nov  4 14:31:02 2002
@@ -27,6 +27,7 @@
  */
 #include <linux/linkage.h>
 #include <linux/config.h>
+#include <linux/init.h>
 #include <asm/assembler.h>
 #include <asm/constants.h>
 #include <asm/procinfo.h>
@@ -378,11 +379,6 @@
  */
 	.align	5
 ENTRY(cpu_arm922_set_pmd)
-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-	eor	r2, r1, #0x0a			@ C & Section
-	tst	r2, #0x0b
-	biceq	r1, r1, #4			@ clear bufferable bit
-#endif
 	str	r1, [r0]
 	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
@@ -442,7 +438,7 @@
 	.ascii	"\0"
 	.align
 
-	.section ".text.init", #alloc, #execinstr
+	__INIT
 
 __arm922_setup:
 	mov	r0, #0
diff -Nru a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
--- a/arch/arm/mm/proc-arm926.S	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/mm/proc-arm926.S	Mon Nov  4 14:31:02 2002
@@ -26,6 +26,7 @@
  */
 #include <linux/linkage.h>
 #include <linux/config.h>
+#include <linux/init.h>
 #include <asm/assembler.h>
 #include <asm/constants.h>
 #include <asm/procinfo.h>
@@ -359,11 +360,6 @@
  */
 	.align	5
 ENTRY(cpu_arm926_set_pmd)
-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-	eor	r2, r1, #0x0a			@ C & Section
-	tst	r2, #0x0b
-	biceq	r1, r1, #4			@ clear bufferable bit
-#endif
 	str	r1, [r0]
 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
 	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
@@ -430,7 +426,7 @@
 	.ascii	"\0"
 	.align
 
-	.section ".text.init", #alloc, #execinstr
+	__INIT
 
 __arm926_setup:
 	mov	r0, #0
diff -Nru a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
--- a/arch/arm/mm/proc-sa110.S	Mon Nov  4 14:31:01 2002
+++ b/arch/arm/mm/proc-sa110.S	Mon Nov  4 14:31:01 2002
@@ -18,6 +18,7 @@
  *    Flush the read buffer at context switches
  */
 #include <linux/linkage.h>
+#include <linux/init.h>
 #include <asm/assembler.h>
 #include <asm/constants.h>
 #include <asm/procinfo.h>
@@ -484,7 +485,7 @@
 	.asciz	"StrongARM-1110"
 	.align
 
-	.section ".text.init", #alloc, #execinstr
+	__INIT
 
 __sa1100_setup:	@ Allow read-buffer operations from userland
 	mcr	p15, 0, r0, c9, c0, 5
@@ -560,7 +561,7 @@
  */
 	.type	sa1100_processor_functions, #object
 ENTRY(sa1100_processor_functions)
-	.word	armv4_early_abort
+	.word	v4_early_abort
 	.word	cpu_sa1100_check_bugs
 	.word	cpu_sa1100_proc_init
 	.word	cpu_sa1100_proc_fin
diff -Nru a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
--- a/arch/arm/mm/proc-xscale.S	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/mm/proc-xscale.S	Mon Nov  4 14:31:02 2002
@@ -21,6 +21,7 @@
  */
 
 #include <linux/linkage.h>
+#include <linux/init.h>
 #include <asm/assembler.h>
 #include <asm/constants.h>
 #include <asm/procinfo.h>
@@ -582,11 +583,6 @@
  */
 	.align	5
 ENTRY(cpu_xscale_set_pmd)
-#if PMD_CACHE_WRITE_ALLOCATE
-	and	r2, r1, #PMD_TYPE_MASK|PMD_SECT_CACHEABLE|PMD_SECT_BUFFERABLE
-	cmp	r2, #PMD_TYPE_SECT|PMD_SECT_CACHEABLE|PMD_SECT_BUFFERABLE
-	orreq	r1, r1, #PMD_SECT_TEX(1)
-#endif
 	str	r1, [r0]
 	mov	ip, #0
 	mcr	p15, 0, r0, c7, c10, 1		@ Clean D cache line
@@ -666,9 +662,12 @@
 cpu_pxa250_name:
 	.asciz	"XScale-PXA250"
 
+cpu_pxa210_name:
+	.asciz	"XScale-PXA210"
+
 	.align
 
-	.section ".text.init", #alloc, #execinstr
+	__INIT
 
 __xscale_setup:
 	mov	r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
@@ -738,6 +737,12 @@
 	.long	cpu_pxa250_name
 	.size	cpu_pxa250_info, . - cpu_pxa250_info
 
+	.type	cpu_pxa210_info, #object
+cpu_pxa210_info:
+	.long	cpu_manu_name
+	.long	cpu_pxa210_name
+	.size	cpu_pxa210_info, . - cpu_pxa210_info
+
 	.type	cpu_arch_name, #object
 cpu_arch_name:
 	.asciz	"armv5te"
@@ -769,7 +774,7 @@
 	.type	__pxa250_proc_info,#object
 __pxa250_proc_info:
 	.long	0x69052100
-	.long	0xfffff7f0
+	.long	0xfffff3f0
 	.long	0x00000c0e
 	b	__xscale_setup
 	.long	cpu_arch_name
@@ -780,4 +785,20 @@
 	.long	v4wbi_tlb_fns
 	.long	xscale_mc_user_fns
 	.size	__pxa250_proc_info, . - __pxa250_proc_info
+
+	.type	__pxa210_proc_info,#object
+__pxa210_proc_info:
+	.long	0x69052120
+	.long	0xfffff3f0
+	.long	0x00000c0e
+	b	__xscale_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+	.long	cpu_pxa210_info
+	.long	xscale_processor_functions
+	.long	v4wbi_tlb_fns
+	.long	xscale_mc_user_fns
+	.long	xscale_cache_fns
+	.size	__pxa210_proc_info, . - __pxa210_proc_info
 
diff -Nru a/arch/arm/mm/tlb-v3.S b/arch/arm/mm/tlb-v3.S
--- a/arch/arm/mm/tlb-v3.S	Mon Nov  4 14:31:00 2002
+++ b/arch/arm/mm/tlb-v3.S	Mon Nov  4 14:31:00 2002
@@ -12,6 +12,7 @@
  * Processors: ARM610, ARM710.
  */
 #include <linux/linkage.h>
+#include <linux/init.h>
 #include <asm/constants.h>
 #include <asm/tlbflush.h>
 #include "proc-macros.S"
@@ -41,7 +42,7 @@
 	blo	1b
 	mov	pc, lr
 
-	.section ".text.init", #alloc, #execinstr
+	__INIT
 
 	.type	v3_tlb_fns, #object
 ENTRY(v3_tlb_fns)
diff -Nru a/arch/arm/mm/tlb-v4.S b/arch/arm/mm/tlb-v4.S
--- a/arch/arm/mm/tlb-v4.S	Mon Nov  4 14:31:01 2002
+++ b/arch/arm/mm/tlb-v4.S	Mon Nov  4 14:31:01 2002
@@ -13,6 +13,7 @@
  * Processors: ARM720T
  */
 #include <linux/linkage.h>
+#include <linux/init.h>
 #include <asm/constants.h>
 #include <asm/tlbflush.h>
 #include "proc-macros.S"
@@ -55,7 +56,7 @@
 .globl v4_flush_kern_tlb_range
 .equ v4_flush_kern_tlb_range, .v4_flush_kern_tlb_range
 
-	.section ".text.init", #alloc, #execinstr
+	__INIT
 
 	.type	v4_tlb_fns, #object
 ENTRY(v4_tlb_fns)
diff -Nru a/arch/arm/mm/tlb-v4wb.S b/arch/arm/mm/tlb-v4wb.S
--- a/arch/arm/mm/tlb-v4wb.S	Mon Nov  4 14:31:01 2002
+++ b/arch/arm/mm/tlb-v4wb.S	Mon Nov  4 14:31:01 2002
@@ -13,6 +13,7 @@
  *  Processors: ARM920 ARM922 ARM926 SA110 SA1100 SA1110 XScale
  */
 #include <linux/linkage.h>
+#include <linux/init.h>
 #include <asm/constants.h>
 #include <asm/tlbflush.h>
 #include "proc-macros.S"
@@ -110,7 +111,7 @@
 	blo	1b
 	mov	pc, lr
 
-	.section ".text.init", #alloc, #execinstr
+	__INIT
 
 	.type	v4wb_tlb_fns, #object
 ENTRY(v4wb_tlb_fns)
diff -Nru a/arch/arm/vmlinux-armo.lds.in b/arch/arm/vmlinux-armo.lds.in
--- a/arch/arm/vmlinux-armo.lds.in	Mon Nov  4 14:31:02 2002
+++ b/arch/arm/vmlinux-armo.lds.in	Mon Nov  4 14:31:02 2002
@@ -11,7 +11,7 @@
 	.init : {			/* Init code and data		*/
 		_stext = .;
 		__init_begin = .;
-			*(.text.init)
+			*(.init.text)
 		__proc_info_begin = .;
 			*(.proc.info)
 		__proc_info_end = .;
@@ -21,10 +21,10 @@
 		__tagtable_begin = .;
 			*(.taglist)
 		__tagtable_end = .;
-			*(.data.init)
+			*(.init.data)
 		. = ALIGN(16);
 		__setup_start = .;
-			*(.setup.init)
+			*(.init.setup)
 		__setup_end = .;
 		__initcall_start = .;
 			*(.initcall1.init)
@@ -44,8 +44,8 @@
 	}
 
 	/DISCARD/ : {			/* Exit code and data		*/
-		*(.text.exit)
-		*(.data.exit)
+		*(.exit.text)
+		*(.exit.data)
 		*(.exitcall.exit)
 	}
 
diff -Nru a/arch/arm/vmlinux-armv.lds.in b/arch/arm/vmlinux-armv.lds.in
--- a/arch/arm/vmlinux-armv.lds.in	Mon Nov  4 14:31:01 2002
+++ b/arch/arm/vmlinux-armv.lds.in	Mon Nov  4 14:31:01 2002
@@ -11,7 +11,7 @@
 	.init : {			/* Init code and data		*/
 		_stext = .;
 		__init_begin = .;
-			*(.text.init)
+			*(.init.text)
 		__proc_info_begin = .;
 			*(.proc.info)
 		__proc_info_end = .;
@@ -21,10 +21,10 @@
 		__tagtable_begin = .;
 			*(.taglist)
 		__tagtable_end = .;
-			*(.data.init)
+			*(.init.data)
 		. = ALIGN(16);
 		__setup_start = .;
-			*(.setup.init)
+			*(.init.setup)
 		__setup_end = .;
 		__initcall_start = .;
 			*(.initcall1.init)
@@ -35,13 +35,17 @@
 			*(.initcall6.init)
 			*(.initcall7.init)
 		__initcall_end = .;
+		. = ALIGN(32);
+		__initramfs_start = .;
+			*(.init.initramfs)
+		__initramfs_end = .;
 		. = ALIGN(4096);
 		__init_end = .;
 	}
 
 	/DISCARD/ : {			/* Exit code and data		*/
-		*(.text.exit)
-		*(.data.exit)
+		*(.exit.text)
+		*(.exit.data)
 		*(.exitcall.exit)
 	}
 
@@ -72,6 +76,12 @@
 		__start___ksymtab = .;
 			*(__ksymtab)
 		__stop___ksymtab = .;
+	}
+
+	__kallsyms : {			/* All kernel symbols		*/
+		__start___kallsyms = .;
+			*(__kallsyms)
+		__stop___kallsyms = .;
 	}
 
 	. = ALIGN(8192);
diff -Nru a/arch/cris/Kconfig b/arch/cris/Kconfig
--- a/arch/cris/Kconfig	Mon Nov  4 14:31:02 2002
+++ b/arch/cris/Kconfig	Mon Nov  4 14:31:02 2002
@@ -5,6 +5,14 @@
 
 mainmenu "Linux/CRIS Kernel Configuration"
 
+config MMU
+	bool
+	default y
+
+config SWAP
+	bool
+	default y
+
 config UID16
 	bool
 	default y
diff -Nru a/arch/cris/kernel/entry.S b/arch/cris/kernel/entry.S
--- a/arch/cris/kernel/entry.S	Mon Nov  4 14:31:01 2002
+++ b/arch/cris/kernel/entry.S	Mon Nov  4 14:31:01 2002
@@ -748,6 +748,7 @@
 	/* r11 is argument 2 to clone, the flags */
 	move.d  $r12, $r11
 	or.w	LCLONE_VM, $r11
+	or.w	LCLONE_UNTRACED, $r11
 
 	/* Save FN for later.  */
 	move.d	$r10, $r12
diff -Nru a/arch/cris/kernel/entryoffsets.c b/arch/cris/kernel/entryoffsets.c
--- a/arch/cris/kernel/entryoffsets.c	Mon Nov  4 14:31:02 2002
+++ b/arch/cris/kernel/entryoffsets.c	Mon Nov  4 14:31:02 2002
@@ -57,5 +57,6 @@
 
 /* linux/sched.h values - doesn't have an #ifdef __ASSEMBLY__ for these.  */
 VAL (LCLONE_VM, CLONE_VM)
+VAL (LCLONE_UNTRACED, CLONE_UNTRACED)
 
 __asm__ (".endif");
diff -Nru a/arch/cris/kernel/irq.c b/arch/cris/kernel/irq.c
--- a/arch/cris/kernel/irq.c	Mon Nov  4 14:31:03 2002
+++ b/arch/cris/kernel/irq.c	Mon Nov  4 14:31:03 2002
@@ -234,7 +234,7 @@
 		if (!action) 
 			continue;
 		seq_printf(p, "%2d: %10u %c %s",
-			i, kstat.irqs[0][i],
+			i, kstat_cpu(0).irqs[i],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
 			action->name);
 		for (action = action->next; action; action = action->next) {
@@ -261,7 +261,7 @@
 
         cpu = smp_processor_id();
         irq_enter(cpu);
-	kstat.irqs[cpu][irq]++;
+	kstat_cpu(cpu).irqs[irq]++;
 
 	action = irq_action[irq];
         if (action) {
diff -Nru a/arch/cris/kernel/ptrace.c b/arch/cris/kernel/ptrace.c
--- a/arch/cris/kernel/ptrace.c	Mon Nov  4 14:31:01 2002
+++ b/arch/cris/kernel/ptrace.c	Mon Nov  4 14:31:01 2002
@@ -292,7 +292,7 @@
 		}
 
 		default:
-			ret = -EIO;
+			ret = ptrace_request(child, request, addr, data);
 			break;
 	}
 out_tsk:
@@ -307,10 +307,8 @@
 	if ((current->ptrace & (PT_PTRACED | PT_TRACESYS)) !=
 	    (PT_PTRACED | PT_TRACESYS))
 		return;
-	/* TODO: make a way to distinguish between a syscall stop and SIGTRAP
-	 * delivery like in the i386 port ? 
-	 */
-	current->exit_code = SIGTRAP;
+	current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+					? 0x80 : 0);
 	current->state = TASK_STOPPED;
 	notify_parent(current, SIGCHLD);
 	schedule();
diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig
--- a/arch/i386/Kconfig	Mon Nov  4 14:31:01 2002
+++ b/arch/i386/Kconfig	Mon Nov  4 14:31:01 2002
@@ -14,6 +14,14 @@
 	  486, 586, Pentiums, and various instruction-set-compatible chips by
 	  AMD, Cyrix, and others.
 
+config MMU
+	bool
+	default y
+
+config SWAP
+	bool
+	default y
+
 config SBUS
 	bool
 
@@ -471,26 +479,19 @@
 	  If in doubt, say N.
 
 config CPU_FREQ_24_API
-	bool "/proc/sys/cpu/ interface (2.4.)"
+	bool "/proc/sys/cpu/ interface (2.4. / OLD)"
 	depends on CPU_FREQ
-	---help---
+	help
 	  This enables the /proc/sys/cpu/ sysctl interface for controlling
-	  CPUFreq, as known from the 2.4.-kernel patches for CPUFreq. Note
-	  that some drivers do not support this interface or offer less
-	  functionality. 
-
-	  If you say N here, you'll be able to control CPUFreq using the
-	  new /proc/cpufreq interface.
+	  CPUFreq, as known from the 2.4.-kernel patches for CPUFreq. 2.5
+	  uses /proc/cpufreq instead. Please note that some drivers do not 
+	  work well with the 2.4. /proc/sys/cpu sysctl interface, so if in
+	  doubt, say N here.
 
 	  For details, take a look at linux/Documentation/cpufreq. 
 
 	  If in doubt, say N.
 
-config CPU_FREQ_26_API
-	bool
-	depends on CPU_FREQ && !CPU_FREQ_24_API
-	default y
-
 config X86_POWERNOW_K6
 	tristate "AMD Mobile K6-2/K6-3 PowerNow!"
 	depends on CPU_FREQ
@@ -554,7 +555,7 @@
 
 config X86_LONGRUN
 	tristate "Transmeta LongRun"
-	depends on CPU_FREQ && !CPU_FREQ_24_API
+	depends on CPU_FREQ
 	help
 	  This adds the CPUFreq driver for Transmeta Crusoe processors which
 	  support LongRun.
diff -Nru a/arch/i386/Makefile b/arch/i386/Makefile
--- a/arch/i386/Makefile	Mon Nov  4 14:31:01 2002
+++ b/arch/i386/Makefile	Mon Nov  4 14:31:01 2002
@@ -18,6 +18,7 @@
 
 LDFLAGS		:= -m elf_i386
 OBJCOPYFLAGS	:= -O binary -R .note -R .comment -S
+ARCHBLOBLFLAGS	:= -I binary -O elf32-i386 -B i386
 LDFLAGS_vmlinux := -e stext
 
 CFLAGS += -pipe
diff -Nru a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
--- a/arch/i386/kernel/cpu/common.c	Mon Nov  4 14:31:00 2002
+++ b/arch/i386/kernel/cpu/common.c	Mon Nov  4 14:31:00 2002
@@ -1,7 +1,6 @@
 #include <linux/init.h>
 #include <linux/string.h>
 #include <linux/delay.h>
-#include <linux/cpu.h>
 #include <linux/smp.h>
 #include <asm/semaphore.h>
 #include <asm/processor.h>
@@ -51,9 +50,16 @@
 	tsc_disable = 1;
 	return 1;
 }
+#else
+#define tsc_disable 0
 
-__setup("notsc", tsc_setup);
+static int __init tsc_setup(char *str)
+{
+	printk("notsc: Kernel compiled with CONFIG_X86_TSC, cannot disable TSC.\n");
+	return 1;
+}
 #endif
+__setup("notsc", tsc_setup);
 
 int __init get_model_name(struct cpuinfo_x86 *c)
 {
@@ -304,10 +310,8 @@
 	 */
 
 	/* TSC disabled? */
-#ifndef CONFIG_X86_TSC
 	if ( tsc_disable )
 		clear_bit(X86_FEATURE_TSC, c->x86_capability);
-#endif
 
 	/* FXSR disabled? */
 	if (disable_x86_fxsr) {
@@ -315,9 +319,6 @@
 		clear_bit(X86_FEATURE_XMM, c->x86_capability);
 	}
 
-	/* Init Machine Check Exception if available. */
-	mcheck_init(c);
-
 	/* If the model name is still unset, do table lookup. */
 	if ( !c->x86_model_id[0] ) {
 		char *p;
@@ -355,6 +356,9 @@
 	       boot_cpu_data.x86_capability[1],
 	       boot_cpu_data.x86_capability[2],
 	       boot_cpu_data.x86_capability[3]);
+
+	/* Init Machine Check Exception if available. */
+	mcheck_init(c);
 }
 /*
  *	Perform early boot up checks for a valid TSC. See arch/i386/kernel/time.c
@@ -443,14 +447,12 @@
 
 	if (cpu_has_vme || cpu_has_tsc || cpu_has_de)
 		clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
-#ifndef CONFIG_X86_TSC
 	if (tsc_disable && cpu_has_tsc) {
 		printk(KERN_NOTICE "Disabling TSC...\n");
 		/**** FIX-HPA: DOES THIS REALLY BELONG HERE? ****/
 		clear_bit(X86_FEATURE_TSC, boot_cpu_data.x86_capability);
 		set_in_cr4(X86_CR4_TSD);
 	}
-#endif
 
 	/*
 	 * Initialize the per-CPU GDT with the boot GDT,
@@ -507,37 +509,3 @@
 	current->used_math = 0;
 	stts();
 }
-
-/*
- * Bulk registration of the cpu devices with the system.
- * Some of this stuff could possibly be moved into a shared 
- * location..
- * Also, these devices should be integrated with other CPU data..
- */
-
-static struct cpu cpu_devices[NR_CPUS];
-
-static struct device_driver cpu_driver = {
-	.name		= "cpu",
-	.bus		= &system_bus_type,
-	.devclass	= &cpu_devclass,
-};
-
-static int __init register_cpus(void)
-{
-	int i;
-
-	driver_register(&cpu_driver);
-
-	for (i = 0; i < NR_CPUS; i++) {
-		struct sys_device * sysdev = &cpu_devices[i].sysdev;
-		sysdev->name = "cpu";
-		sysdev->id = i;
-		sysdev->dev.driver = &cpu_driver;
-		if (cpu_possible(i))
-			sys_device_register(sysdev);
-	}
-	return 0;
-}
-
-subsys_initcall(register_cpus);
diff -Nru a/arch/i386/kernel/cpu/cpufreq/longrun.c b/arch/i386/kernel/cpu/cpufreq/longrun.c
--- a/arch/i386/kernel/cpu/cpufreq/longrun.c	Mon Nov  4 14:31:02 2002
+++ b/arch/i386/kernel/cpu/cpufreq/longrun.c	Mon Nov  4 14:31:02 2002
@@ -251,6 +251,11 @@
 
 	longrun_get_policy(&driver->policy[0]);
 
+#ifdef CONFIG_CPU_FREQ_24_API
+	driver->cpu_min_freq    = longrun_low_freq;
+	driver->cpu_cur_freq[0] = longrun_high_freq; /* dummy value */
+#endif
+
 	driver->verify         = &longrun_verify_policy;
 	driver->setpolicy      = &longrun_set_policy;
 	result = cpufreq_register(driver);
diff -Nru a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
--- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c	Mon Nov  4 14:31:02 2002
+++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c	Mon Nov  4 14:31:02 2002
@@ -50,32 +50,55 @@
 MODULE_PARM(stock_freq, "i");
 
 static struct cpufreq_driver *cpufreq_p4_driver;
-static unsigned int cpufreq_p4_old_state = 0;
 
 
 static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate)
 {
 	u32 l, h;
 	unsigned long cpus_allowed;
-	struct cpufreq_freqs    freqs;
+	struct cpufreq_freqs freqs;
+	int hyperthreading = 0;
+	int affected_cpu_map = 0;
+	int sibling = 0;
 
 	if (!cpu_online(cpu) || (newstate > DC_DISABLE) || 
 		(newstate == DC_RESV))
 		return -EINVAL;
-	cpu = cpu >> 1; /* physical CPU #nr */
+
+	/* switch to physical CPU where state is to be changed*/
+	cpus_allowed = current->cpus_allowed;
+
+	/* only run on CPU to be set, or on its sibling */
+	affected_cpu_map = 1 << cpu;
+#ifdef CONFIG_X86_HT
+	hyperthreading = ((cpu_has_ht) && (smp_num_siblings == 2));
+	if (hyperthreading) {
+		sibling = cpu_sibling_map[cpu];
+		affected_cpu_map |= (1 << sibling);
+	}
+#endif
+	set_cpus_allowed(current, affected_cpu_map);
+	BUG_ON(!(smp_processor_id() & affected_cpu_map));
+
+	/* get current state */
+	rdmsr(MSR_IA32_THERM_CONTROL, l, h);
+	l = l >> 1;
+	l &= 0x7;
+
+	if (l == newstate) {
+		set_cpus_allowed(current, cpus_allowed);
+		return 0;
+	}
 
 	/* notifiers */
-	freqs.old = stock_freq * cpufreq_p4_old_state / 8;
+	freqs.old = stock_freq * l / 8;
 	freqs.new = stock_freq * newstate / 8;
-	freqs.cpu = 2*cpu;
-	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-	freqs.cpu++;
+	freqs.cpu = cpu;
 	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-
-	/* switch to physical CPU where state is to be changed*/
-	cpus_allowed = current->cpus_allowed;
-	set_cpus_allowed(current, 3 << (2 * cpu));
-	BUG_ON(cpu != (smp_processor_id() >> 1));
+	if (hyperthreading) {
+		freqs.cpu = sibling;
+		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+	}
 
 	rdmsr(MSR_IA32_THERM_STATUS, l, h);
 	if (l & 0x01)
@@ -86,10 +109,10 @@
 
 	rdmsr(MSR_IA32_THERM_CONTROL, l, h);
 	if (newstate == DC_DISABLE) {
-		printk(KERN_INFO PFX "CPU#%d,%d disabling modulation\n", cpu, (cpu + 1));
+		printk(KERN_INFO PFX "CPU#%d disabling modulation\n", cpu);
 		wrmsr(MSR_IA32_THERM_CONTROL, l & ~(1<<4), h);
 	} else {
-		printk(KERN_INFO PFX "CPU#%d,%d setting duty cycle to %d%%\n", cpu, (cpu + 1), ((125 * newstate) / 10));
+		printk(KERN_INFO PFX "CPU#%d setting duty cycle to %d%%\n", cpu, ((125 * newstate) / 10));
 		/* bits 63 - 5	: reserved 
 		 * bit  4	: enable/disable
 		 * bits 3-1	: duty cycle
@@ -104,9 +127,10 @@
 
 	/* notifiers */
 	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-	freqs.cpu--;
-	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-	cpufreq_p4_old_state = newstate;
+	if (hyperthreading) {
+		freqs.cpu = cpu;
+		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+	}
 
 	return 0;
 }
@@ -123,7 +147,7 @@
 
 	if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
 	{
-		for (i=8; i>0; i++)
+		for (i=8; i>0; i--)
 			if ((policy->min <= ((stock_freq / 8) * i)) &&
 			    (policy->max >= ((stock_freq / 8) * i))) 
 			{
@@ -131,7 +155,7 @@
 				number_states++;
 			}
 	} else {
-		for (i=0; i<=8; i--)
+		for (i=1; i<=8; i++)
 			if ((policy->min <= ((stock_freq / 8) * i)) &&
 			    (policy->max >= ((stock_freq / 8) * i))) 
 			{
@@ -143,9 +167,9 @@
 	/* if (number_states == 1) */
 	{
 		if (policy->cpu == CPUFREQ_ALL_CPUS) {
-			for (i=0; i<(NR_CPUS/2); i++)
-				if (cpu_online(2*i))
-					cpufreq_p4_setdc((2*i), newstate);
+			for (i=0; i<NR_CPUS; i++)
+				if (cpu_online(i))
+					cpufreq_p4_setdc(i, newstate);
 		} else {
 			cpufreq_p4_setdc(policy->cpu, newstate);
 		}
@@ -235,7 +259,6 @@
 	for (i=0;i<NR_CPUS;i++)
 		driver->cpu_cur_freq[i] = stock_freq;
 #endif
-	cpufreq_p4_old_state  = DC_DISABLE;
 
 	driver->verify        = &cpufreq_p4_verify;
 	driver->setpolicy     = &cpufreq_p4_setpolicy;
diff -Nru a/arch/i386/kernel/cpu/mtrr/generic.c b/arch/i386/kernel/cpu/mtrr/generic.c
--- a/arch/i386/kernel/cpu/mtrr/generic.c	Mon Nov  4 14:31:02 2002
+++ b/arch/i386/kernel/cpu/mtrr/generic.c	Mon Nov  4 14:31:02 2002
@@ -312,8 +312,6 @@
 {
 	prepare_set();
 
-	printk("MTRR: setting reg %x\n",reg);
-
 	if (size == 0) {
 		/* The invalid bit is kept in the mask, so we simply clear the
 		   relevant mask register to disable a range. */
diff -Nru a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c
--- a/arch/i386/kernel/cpu/proc.c	Mon Nov  4 14:31:02 2002
+++ b/arch/i386/kernel/cpu/proc.c	Mon Nov  4 14:31:02 2002
@@ -74,6 +74,13 @@
 	/* Cache size */
 	if (c->x86_cache_size >= 0)
 		seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size);
+#ifdef CONFIG_SMP
+	if (cpu_has_ht) {
+		extern int phys_proc_id[NR_CPUS];
+		seq_printf(m, "physical id\t: %d\n", phys_proc_id[n]);
+		seq_printf(m, "siblings\t: %d\n", smp_num_siblings);
+	}
+#endif
 	
 	/* We use exception 16 if we have hardware math and we've either seen it or the CPU claims it is internal */
 	fpu_exception = c->hard_math && (ignore_irq13 || cpu_has_fpu);
diff -Nru a/arch/i386/kernel/edd.c b/arch/i386/kernel/edd.c
--- a/arch/i386/kernel/edd.c	Mon Nov  4 14:31:01 2002
+++ b/arch/i386/kernel/edd.c	Mon Nov  4 14:31:01 2002
@@ -44,7 +44,7 @@
 #include <linux/ctype.h>
 #include <linux/slab.h>
 #include <linux/limits.h>
-#include <linux/driverfs_fs.h>
+#include <linux/device.h>
 #include <linux/pci.h>
 #include <asm/edd.h>
 #include <linux/device.h>
@@ -63,20 +63,9 @@
 
 #define left (count - (p - buf) - 1)
 
-/*
- * bios_dir may go away completely,
- * and it definitely won't be at the root
- * of driverfs forever.
- */
-static struct driver_dir_entry bios_dir = {
-	.name = "bios",
-	.mode = (S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO),
-};
-
 struct edd_device {
-	char name[EDD_DEVICE_NAME_SIZE];
 	struct edd_info *info;
-	struct driver_dir_entry dir;
+	struct kobject kobj;
 };
 
 struct edd_attribute {
@@ -112,13 +101,13 @@
 }
 
 #define to_edd_attr(_attr) container_of(_attr,struct edd_attribute,attr)
-#define to_edd_device(_dir) container_of(_dir,struct edd_device,dir)
+#define to_edd_device(obj) container_of(obj,struct edd_device,kobj)
 
 static ssize_t
-edd_attr_show(struct driver_dir_entry *dir, struct attribute *attr,
+edd_attr_show(struct kobject * kobj, struct attribute *attr,
 	      char *buf, size_t count, loff_t off)
 {
-	struct edd_device *dev = to_edd_device(dir);
+	struct edd_device *dev = to_edd_device(kobj);
 	struct edd_attribute *edd_attr = to_edd_attr(attr);
 	ssize_t ret = 0;
 
@@ -127,7 +116,7 @@
 	return ret;
 }
 
-static struct driverfs_ops edd_attr_ops = {
+static struct sysfs_ops edd_attr_ops = {
 	.show = edd_attr_show,
 };
 
@@ -586,89 +575,26 @@
 static EDD_DEVICE_ATTR(host_bus, 0444, edd_show_host_bus, edd_has_edd30);
 
 
-static struct edd_attribute * def_attrs[] = {
-	&edd_attr_raw_data,
-	&edd_attr_version,
-	&edd_attr_extensions,
-	&edd_attr_info_flags,
-	&edd_attr_sectors,
-	&edd_attr_default_cylinders,
-	&edd_attr_default_heads,
-	&edd_attr_default_sectors_per_track,
-	&edd_attr_interface,
-	&edd_attr_host_bus,
+static struct attribute * def_attrs[] = {
+	&edd_attr_raw_data.attr,
+	&edd_attr_version.attr,
+	&edd_attr_extensions.attr,
+	&edd_attr_info_flags.attr,
+	&edd_attr_sectors.attr,
+	&edd_attr_default_cylinders.attr,
+	&edd_attr_default_heads.attr,
+	&edd_attr_default_sectors_per_track.attr,
+	&edd_attr_interface.attr,
+	&edd_attr_host_bus.attr,
 	NULL,
 };
 
-/* edd_get_devpath_length(), edd_fill_devpath(), and edd_device_link()
-   were taken from linux/drivers/base/fs/device.c.  When these
-   or similar are exported to generic code, remove these.
-*/
-
-static int
-edd_get_devpath_length(struct device *dev)
-{
-	int length = 1;
-	struct device *parent = dev;
-
-	/* walk up the ancestors until we hit the root.
-	 * Add 1 to strlen for leading '/' of each level.
-	 */
-	do {
-		length += strlen(parent->bus_id) + 1;
-		parent = parent->parent;
-	} while (parent);
-	return length;
-}
-
-static void
-edd_fill_devpath(struct device *dev, char *path, int length)
-{
-	struct device *parent;
-	--length;
-	for (parent = dev; parent; parent = parent->parent) {
-		int cur = strlen(parent->bus_id);
-
-		/* back up enough to print this bus id with '/' */
-		length -= cur;
-		strncpy(path + length, parent->bus_id, cur);
-		*(path + --length) = '/';
-	}
-}
-
-static int
-edd_device_symlink(struct edd_device *edev, struct device *dev, char *name)
-{
-	char *path;
-	int length;
-	int error = 0;
-
-	if (!dev->bus || !name)
-		return 0;
-
-	length = edd_get_devpath_length(dev);
-
-	/* now add the path from the edd_device directory
-	 * It should be '../..' (one to get to the 'bios' directory,
-	 * and one to get to the root of the fs.)
-	 */
-	length += strlen("../../root");
-
-	if (length > PATH_MAX)
-		return -ENAMETOOLONG;
-
-	if (!(path = kmalloc(length, GFP_KERNEL)))
-		return -ENOMEM;
-	memset(path, 0, length);
-
-	/* our relative position */
-	strcpy(path, "../../root");
+static struct subsystem edd_subsys = {
+	.kobj	= { .name = "edd" },
+	.sysfs_ops	= &edd_attr_ops,
+	.default_attrs	= def_attrs,
+};
 
-	edd_fill_devpath(dev, path, length);
-	error = driverfs_create_symlink(&edev->dir, name, path);
-	kfree(path);
-	return error;
-}
 
 /**
  * edd_dev_is_type() - is this EDD device a 'type' device?
@@ -721,7 +647,7 @@
 	struct pci_dev *pci_dev = edd_get_pci_dev(edev);
 	if (!pci_dev)
 		return 1;
-	return edd_device_symlink(edev, &pci_dev->dev, "pci_dev");
+	return sysfs_create_link(&edev->kobj,&pci_dev->dev.kobj,"pci_dev");
 }
 
 /**
@@ -833,61 +759,16 @@
 		return 1;
 
 	get_device(&sdev->sdev_driverfs_dev);
-	rc = edd_device_symlink(edev, &sdev->sdev_driverfs_dev, "disc");
+	rc = sysfs_create_link(&edev->kobj,&sdev->sdev_driverfs_dev.kobj, "disc");
 	put_device(&sdev->sdev_driverfs_dev);
 
 	return rc;
 }
 
-static inline int
-edd_create_file(struct edd_device *edev, struct edd_attribute *attr)
-{
-	return driverfs_create_file(&attr->attr, &edev->dir);
-}
-
 static inline void
 edd_device_unregister(struct edd_device *edev)
 {
-	driverfs_remove_dir(&edev->dir);
-}
-
-static int
-edd_populate_dir(struct edd_device *edev)
-{
-	struct edd_attribute *attr;
-	int i;
-	int error = 0;
-
-	for (i = 0; (attr=def_attrs[i]); i++) {
-		if (!attr->test || (attr->test && !attr->test(edev))) {
-			if ((error = edd_create_file(edev, attr))) {
-				break;
-			}
-		}
-	}
-
-	if (error)
-		return error;
-
-	edd_create_symlink_to_pcidev(edev);
-	edd_create_symlink_to_scsidev(edev);
-
-	return 0;
-}
-
-static int
-edd_make_dir(struct edd_device *edev)
-{
-	int error;
-
-	edev->dir.name = edev->name;
-	edev->dir.mode = (S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO);
-	edev->dir.ops = &edd_attr_ops;
-
-	error = driverfs_create_dir(&edev->dir, &bios_dir);
-	if (!error)
-		error = edd_populate_dir(edev);
-	return error;
+	kobject_unregister(&edev->kobj);
 }
 
 static int
@@ -899,9 +780,15 @@
 		return 1;
 	memset(edev, 0, sizeof (*edev));
 	edd_dev_set_info(edev, &edd[i]);
-	snprintf(edev->name, EDD_DEVICE_NAME_SIZE, "int13_dev%02x",
+	kobject_init(&edev->kobj);
+	snprintf(edev->kobj.name, EDD_DEVICE_NAME_SIZE, "int13_dev%02x",
 		 edd[i].device);
-	error = edd_make_dir(edev);
+	edev->kobj.subsys = &edd_subsys;
+	error = kobject_register(&edev->kobj);
+	if (!error) {
+		edd_create_symlink_to_pcidev(edev);
+		edd_create_symlink_to_scsidev(edev);
+	}
 	return error;
 }
 
@@ -926,7 +813,7 @@
 		return 1;
 	}
 
-	rc = driverfs_create_dir(&bios_dir, NULL);
+	rc = firmware_register(&edd_subsys);
 	if (rc)
 		return rc;
 
@@ -943,12 +830,9 @@
 		edd_devices[i] = edev;
 	}
 
-	if (rc) {
-		driverfs_remove_dir(&bios_dir);
-		return rc;
-	}
-
-	return 0;
+	if (rc)
+		firmware_unregister(&edd_subsys);
+	return rc;
 }
 
 static void __exit
@@ -963,8 +847,7 @@
 			kfree(edev);
 		}
 	}
-
-	driverfs_remove_dir(&bios_dir);
+	firmware_unregister(&edd_subsys);
 }
 
 late_initcall(edd_init);
diff -Nru a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
--- a/arch/i386/kernel/entry.S	Mon Nov  4 14:31:01 2002
+++ b/arch/i386/kernel/entry.S	Mon Nov  4 14:31:01 2002
@@ -740,6 +740,7 @@
 	.long sys_epoll_create
 	.long sys_epoll_ctl	/* 255 */
 	.long sys_epoll_wait
+ 	.long sys_remap_file_pages
 
 
 	.rept NR_syscalls-(.-sys_call_table)/4
diff -Nru a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c
--- a/arch/i386/kernel/i386_ksyms.c	Mon Nov  4 14:31:03 2002
+++ b/arch/i386/kernel/i386_ksyms.c	Mon Nov  4 14:31:03 2002
@@ -143,6 +143,11 @@
 EXPORT_SYMBOL(mmx_copy_page);
 #endif
 
+#ifdef CONFIG_X86_HT
+EXPORT_SYMBOL(smp_num_siblings);
+EXPORT_SYMBOL(cpu_sibling_map);
+#endif
+
 #ifdef CONFIG_SMP
 EXPORT_SYMBOL(cpu_data);
 EXPORT_SYMBOL(cpu_online_map);
diff -Nru a/arch/i386/kernel/ioport.c b/arch/i386/kernel/ioport.c
--- a/arch/i386/kernel/ioport.c	Mon Nov  4 14:31:01 2002
+++ b/arch/i386/kernel/ioport.c	Mon Nov  4 14:31:01 2002
@@ -110,7 +110,7 @@
 
 asmlinkage int sys_iopl(unsigned long unused)
 {
-	struct pt_regs * regs = (struct pt_regs *) &unused;
+	volatile struct pt_regs * regs = (struct pt_regs *) &unused;
 	unsigned int level = regs->ebx;
 	unsigned int old = (regs->eflags >> 12) & 3;
 
diff -Nru a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
--- a/arch/i386/kernel/irq.c	Mon Nov  4 14:31:00 2002
+++ b/arch/i386/kernel/irq.c	Mon Nov  4 14:31:00 2002
@@ -153,7 +153,7 @@
 		for (j = 0; j < NR_CPUS; j++)
 			if (cpu_online(j))
 				p += seq_printf(p, "%10u ",
-					     kstat.irqs[j][i]);
+					     kstat_cpu(j).irqs[i]);
 #endif
 		seq_printf(p, " %14s", irq_desc[i].handler->typename);
 		seq_printf(p, "  %s", action->name);
@@ -345,7 +345,7 @@
 		}
 	}
 #endif
-	kstat.irqs[cpu][irq]++;
+	kstat_cpu(cpu).irqs[irq]++;
 	spin_lock(&desc->lock);
 	desc->handler->ack(irq);
 	/*
diff -Nru a/arch/i386/kernel/ldt.c b/arch/i386/kernel/ldt.c
--- a/arch/i386/kernel/ldt.c	Mon Nov  4 14:31:02 2002
+++ b/arch/i386/kernel/ldt.c	Mon Nov  4 14:31:02 2002
@@ -104,7 +104,7 @@
 /*
  * No need to lock the MM as we are the last user
  */
-void release_segments(struct mm_struct *mm)
+void destroy_context(struct mm_struct *mm)
 {
 	if (mm->context.size) {
 		if (mm == current->active_mm)
diff -Nru a/arch/i386/kernel/numaq.c b/arch/i386/kernel/numaq.c
--- a/arch/i386/kernel/numaq.c	Mon Nov  4 14:31:02 2002
+++ b/arch/i386/kernel/numaq.c	Mon Nov  4 14:31:02 2002
@@ -52,6 +52,7 @@
 	numnodes = 0;
 	for(node = 0; node < MAX_NUMNODES; node++) {
 		if(scd->quads_present31_0 & (1 << node)) {
+			node_set_online(node);
 			numnodes++;
 			eq = &scd->eq[node];
 			/* Convert to pages */
diff -Nru a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
--- a/arch/i386/kernel/process.c	Mon Nov  4 14:31:00 2002
+++ b/arch/i386/kernel/process.c	Mon Nov  4 14:31:00 2002
@@ -224,7 +224,7 @@
 	regs.eflags = 0x286;
 
 	/* Ok, create the new process.. */
-	p = do_fork(flags | CLONE_VM, 0, &regs, 0, NULL);
+	p = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL);
 	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
@@ -247,6 +247,7 @@
 	struct task_struct *tsk = current;
 
 	memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
+	memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));	
 	/*
 	 * Forget coprocessor state..
 	 */
diff -Nru a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
--- a/arch/i386/kernel/ptrace.c	Mon Nov  4 14:31:01 2002
+++ b/arch/i386/kernel/ptrace.c	Mon Nov  4 14:31:01 2002
@@ -416,17 +416,8 @@
 		break;
 	}
 
-	case PTRACE_SETOPTIONS: {
-		if (data & PTRACE_O_TRACESYSGOOD)
-			child->ptrace |= PT_TRACESYSGOOD;
-		else
-			child->ptrace &= ~PT_TRACESYSGOOD;
-		ret = 0;
-		break;
-	}
-
 	default:
-		ret = -EIO;
+		ret = ptrace_request(child, request, addr, data);
 		break;
 	}
 out_tsk:
diff -Nru a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
--- a/arch/i386/kernel/smpboot.c	Mon Nov  4 14:31:01 2002
+++ b/arch/i386/kernel/smpboot.c	Mon Nov  4 14:31:01 2002
@@ -58,7 +58,7 @@
 
 /* Number of siblings per CPU package */
 int smp_num_siblings = 1;
-int __initdata phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */
+int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */
 
 /* Bitmask of currently online CPUs */
 unsigned long cpu_online_map;
@@ -118,7 +118,8 @@
 	struct cpuinfo_x86 *c = cpu_data + id;
 
 	*c = boot_cpu_data;
-	identify_cpu(c);
+	if (id!=0)
+		identify_cpu(c);
 	/*
 	 * Mask B, Pentium, but not Pentium MMX
 	 */
diff -Nru a/arch/i386/kernel/sys_i386.c b/arch/i386/kernel/sys_i386.c
--- a/arch/i386/kernel/sys_i386.c	Mon Nov  4 14:31:01 2002
+++ b/arch/i386/kernel/sys_i386.c	Mon Nov  4 14:31:01 2002
@@ -9,6 +9,7 @@
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/hugetlb.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/sem.h>
@@ -248,91 +249,68 @@
 }
 
 #ifdef CONFIG_HUGETLB_PAGE
-#define HPAGE_ALIGN(x)  (((unsigned long)x + (HPAGE_SIZE -1)) & HPAGE_MASK)
-extern long     sys_munmap(unsigned long, size_t);
 /* get_addr function gets the currently unused virtaul range in
- * current process's address space.  It returns the LARGE_PAGE_SIZE
+ * current process's address space.  It returns the HPAGE_SIZE
  * aligned address (in cases of success).  Other kernel generic
- * routines only could gurantee that allocated address is PAGE_SIZSE aligned.
+ * routines only could gurantee that allocated address is PAGE_SIZE aligned.
  */
-static unsigned long
-get_addr(unsigned long addr, unsigned long len)
+static unsigned long get_addr(unsigned long addr, unsigned long len)
 {
-	struct vm_area_struct   *vma;
+	struct vm_area_struct *vma;
 	if (addr) {
-		addr = HPAGE_ALIGN(addr);
+		addr = (addr + HPAGE_SIZE - 1) & HPAGE_MASK;
 		vma = find_vma(current->mm, addr);
-		if (((TASK_SIZE - len) >= addr) &&
-				(!vma || addr + len <= vma->vm_start))
+		if (TASK_SIZE > addr + len && !(vma && addr + len >= vma->vm_start))
 			goto found_addr;
 	}
-	addr = HPAGE_ALIGN(TASK_UNMAPPED_BASE);
-	for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
-		if (TASK_SIZE - len < addr)
-			return -ENOMEM;
-		if (!vma || ((addr + len) < vma->vm_start))
+	addr = TASK_UNMAPPED_BASE;
+	for (vma = find_vma(current->mm, addr); TASK_SIZE > addr + len; vma = vma->vm_next) {
+		if (!vma || addr + len < vma->vm_start)
 			goto found_addr;
-		addr = HPAGE_ALIGN(vma->vm_end);
+		addr = (vma->vm_end + HPAGE_SIZE - 1) & HPAGE_MASK;
 	}
+	return -ENOMEM;
 found_addr:
 	return addr;
 }
 
-asmlinkage unsigned long
-sys_alloc_hugepages(int key, unsigned long addr, unsigned long len, int prot, int flag)
+asmlinkage unsigned long sys_alloc_hugepages(int key, unsigned long addr, unsigned long len, int prot, int flag)
 {
 	struct mm_struct *mm = current->mm;
 	unsigned long   raddr;
 	int     retval = 0;
 	extern int alloc_hugetlb_pages(int, unsigned long, unsigned long, int, int);
-	if (!(cpu_has_pse))
-		return -EINVAL;
-	if (key < 0)
-		return -EINVAL;
-	if (len & (HPAGE_SIZE - 1))
+	if (!cpu_has_pse || key < 0 || len & ~HPAGE_MASK)
 		return -EINVAL;
 	down_write(&mm->mmap_sem);
 	raddr = get_addr(addr, len);
-	if (raddr == -ENOMEM)
-		goto raddr_out;
-	retval = alloc_hugetlb_pages(key, raddr, len, prot, flag);
-
-raddr_out: up_write(&mm->mmap_sem);
-	if (retval < 0)
-		return (unsigned long) retval;
-	return raddr;
+	if (raddr != -ENOMEM)
+		retval = alloc_hugetlb_pages(key, raddr, len, prot, flag);
+	up_write(&mm->mmap_sem);
+	return (retval < 0) ? (unsigned long)retval : raddr;
 }
 
-asmlinkage int
-sys_free_hugepages(unsigned long addr)
+asmlinkage int sys_free_hugepages(unsigned long addr)
 {
 	struct mm_struct *mm = current->mm;
-	struct vm_area_struct   *vma;
-	int	retval;
-	extern int free_hugepages(struct vm_area_struct *);
+	struct vm_area_struct *vma;
+	int retval;
 
 	vma = find_vma(current->mm, addr);
-	if ((!vma) || (!is_vm_hugetlb_page(vma)) || (vma->vm_start!=addr))
+	if (!vma || !(vma->vm_flags & VM_HUGETLB) || vma->vm_start != addr)
 		return -EINVAL;
 	down_write(&mm->mmap_sem);
-	spin_lock(&mm->page_table_lock);
-	retval =  free_hugepages(vma);
-	spin_unlock(&mm->page_table_lock);
+	retval = do_munmap(vma->vm_mm, addr, vma->vm_end - addr);
 	up_write(&mm->mmap_sem);
 	return retval;
 }
-
 #else
-
-asmlinkage unsigned long
-sys_alloc_hugepages(int key, unsigned long addr, size_t len, int prot, int flag)
+asmlinkage unsigned long sys_alloc_hugepages(int key, unsigned long addr, size_t len, int prot, int flag)
 {
 	return -ENOSYS;
 }
-asmlinkage int
-sys_free_hugepages(unsigned long addr)
+asmlinkage int sys_free_hugepages(unsigned long addr)
 {
 	return -ENOSYS;
 }
-
 #endif
diff -Nru a/arch/i386/kernel/timers/timer_pit.c b/arch/i386/kernel/timers/timer_pit.c
--- a/arch/i386/kernel/timers/timer_pit.c	Mon Nov  4 14:31:02 2002
+++ b/arch/i386/kernel/timers/timer_pit.c	Mon Nov  4 14:31:02 2002
@@ -6,6 +6,7 @@
 #include <linux/spinlock.h>
 #include <linux/module.h>
 #include <linux/device.h>
+#include <linux/irq.h>
 #include <asm/mpspec.h>
 #include <asm/timer.h>
 #include <asm/io.h>
diff -Nru a/arch/i386/mach-generic/Makefile b/arch/i386/mach-generic/Makefile
--- a/arch/i386/mach-generic/Makefile	Mon Nov  4 14:31:01 2002
+++ b/arch/i386/mach-generic/Makefile	Mon Nov  4 14:31:01 2002
@@ -4,6 +4,6 @@
 
 EXTRA_CFLAGS	+= -I../kernel
 
-obj-y				:= setup.o
+obj-y				:= setup.o topology.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/arch/i386/mach-generic/topology.c b/arch/i386/mach-generic/topology.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/mach-generic/topology.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,67 @@
+/*
+ * arch/i386/mach-generic/topology.c - Populate driverfs with topology information
+ *
+ * Written by: Matthew Dobson, IBM Corporation
+ * Original Code: Paul Dorwin, IBM Corporation, Patrick Mochel, OSDL
+ *
+ * Copyright (C) 2002, IBM Corp.
+ *
+ * All rights reserved.          
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <colpatch@us.ibm.com>
+ */
+#include <linux/init.h>
+#include <asm/cpu.h>
+
+struct i386_cpu cpu_devices[NR_CPUS];
+
+#ifdef CONFIG_NUMA
+#include <linux/mmzone.h>
+#include <asm/node.h>
+#include <asm/memblk.h>
+
+struct i386_node node_devices[MAX_NUMNODES];
+struct i386_memblk memblk_devices[MAX_NR_MEMBLKS];
+
+static int __init topology_init(void)
+{
+	int i;
+
+	for (i = 0; i < num_online_nodes(); i++)
+		arch_register_node(i);
+	for (i = 0; i < NR_CPUS; i++)
+		if (cpu_possible(i)) arch_register_cpu(i);
+	for (i = 0; i < num_online_memblks(); i++)
+		arch_register_memblk(i);
+	return 0;
+}
+
+#else /* !CONFIG_NUMA */
+
+static int __init topology_init(void)
+{
+	int i;
+
+	for (i = 0; i < NR_CPUS; i++)
+		if (cpu_possible(i)) arch_register_cpu(i);
+	return 0;
+}
+
+#endif /* CONFIG_NUMA */
+
+subsys_initcall(topology_init);
diff -Nru a/arch/i386/mach-visws/visws_apic.c b/arch/i386/mach-visws/visws_apic.c
--- a/arch/i386/mach-visws/visws_apic.c	Mon Nov  4 14:31:00 2002
+++ b/arch/i386/mach-visws/visws_apic.c	Mon Nov  4 14:31:00 2002
@@ -324,7 +324,7 @@
 	/*
 	 * handle this 'virtual interrupt' as a Cobalt one now.
 	 */
-	kstat.irqs[smp_processor_id()][irq]++;
+	kstat_cpu(smp_processor_id()).irqs[irq]++;
 	do_cobalt_IRQ(realirq, regs);
 
 	spin_lock(&irq_controller_lock);
diff -Nru a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c
--- a/arch/i386/mm/hugetlbpage.c	Mon Nov  4 14:31:02 2002
+++ b/arch/i386/mm/hugetlbpage.c	Mon Nov  4 14:31:02 2002
@@ -8,6 +8,7 @@
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
+#include <linux/hugetlb.h>
 #include <linux/pagemap.h>
 #include <linux/smp_lock.h>
 #include <linux/slab.h>
@@ -17,7 +18,7 @@
 #include <asm/tlb.h>
 #include <asm/tlbflush.h>
 
-static struct vm_operations_struct hugetlb_vm_ops;
+struct vm_operations_struct hugetlb_vm_ops;
 struct list_head htlbpage_freelist;
 spinlock_t htlbpage_lock = SPIN_LOCK_UNLOCKED;
 extern long htlbpagemem;
@@ -30,8 +31,7 @@
 	int key;
 } htlbpagek[MAX_ID];
 
-static struct inode *
-find_key_inode(int key)
+static struct inode *find_key_inode(int key)
 {
 	int i;
 
@@ -41,8 +41,8 @@
 	}
 	return NULL;
 }
-static struct page *
-alloc_hugetlb_page(void)
+
+static struct page *alloc_hugetlb_page(void)
 {
 	int i;
 	struct page *page;
@@ -63,36 +63,7 @@
 	return page;
 }
 
-static void
-free_hugetlb_page(struct page *page)
-{
-	spin_lock(&htlbpage_lock);
-	if ((page->mapping != NULL) && (page_count(page) == 2)) {
-		struct inode *inode = page->mapping->host;
-		int i;
-
-		ClearPageDirty(page);
-		remove_from_page_cache(page);
-		set_page_count(page, 1);
-		if ((inode->i_size -= HPAGE_SIZE) == 0) {
-			for (i = 0; i < MAX_ID; i++)
-				if (htlbpagek[i].key == inode->i_ino) {
-					htlbpagek[i].key = 0;
-					htlbpagek[i].in = NULL;
-					break;
-				}
-			kfree(inode);
-		}
-	}
-	if (put_page_testzero(page)) {
-		list_add(&page->list, &htlbpage_freelist);
-		htlbpagemem++;
-	}
-	spin_unlock(&htlbpage_lock);
-}
-
-static pte_t *
-huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
+static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
 {
 	pgd_t *pgd;
 	pmd_t *pmd = NULL;
@@ -102,8 +73,7 @@
 	return (pte_t *) pmd;
 }
 
-static pte_t *
-huge_pte_offset(struct mm_struct *mm, unsigned long addr)
+static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
 {
 	pgd_t *pgd;
 	pmd_t *pmd = NULL;
@@ -115,9 +85,7 @@
 
 #define mk_pte_huge(entry) {entry.pte_low |= (_PAGE_PRESENT | _PAGE_PSE);}
 
-static void
-set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma,
-	     struct page *page, pte_t * page_table, int write_access)
+static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma, struct page *page, pte_t * page_table, int write_access)
 {
 	pte_t entry;
 
@@ -130,24 +98,17 @@
 	entry = pte_mkyoung(entry);
 	mk_pte_huge(entry);
 	set_pte(page_table, entry);
-	return;
 }
 
-static int
-anon_get_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
-	       int write_access, pte_t * page_table)
+static int anon_get_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, int write_access, pte_t *page_table)
 {
-	struct page *page;
-
-	page = alloc_hugetlb_page();
-	if (page == NULL)
-		return -1;
-	set_huge_pte(mm, vma, page, page_table, write_access);
-	return 1;
+	struct page *page = alloc_hugetlb_page();
+	if (page)
+		set_huge_pte(mm, vma, page, page_table, write_access);
+	return page ? 1 : -1;
 }
 
-int
-make_hugetlb_pages_present(unsigned long addr, unsigned long end, int flags)
+int make_hugetlb_pages_present(unsigned long addr, unsigned long end, int flags)
 {
 	int write;
 	struct mm_struct *mm = current->mm;
@@ -253,31 +214,61 @@
 	return i;
 }
 
-void
-zap_hugetlb_resources(struct vm_area_struct *mpnt)
+void free_huge_page(struct page *page)
 {
-	struct mm_struct *mm = mpnt->vm_mm;
-	unsigned long len, addr, end;
-	pte_t *ptep;
+	BUG_ON(page_count(page));
+	BUG_ON(page->mapping);
+
+	INIT_LIST_HEAD(&page->list);
+
+	spin_lock(&htlbpage_lock);
+	list_add(&page->list, &htlbpage_freelist);
+	htlbpagemem++;
+	spin_unlock(&htlbpage_lock);
+}
+
+void huge_page_release(struct page *page)
+{
+	if (!put_page_testzero(page))
+		return;
+
+	free_huge_page(page);
+}
+
+void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long address;
+	pte_t *pte;
 	struct page *page;
 
-	addr = mpnt->vm_start;
-	end = mpnt->vm_end;
-	len = end - addr;
-	do {
-		ptep = huge_pte_offset(mm, addr);
-		page = pte_page(*ptep);
-		pte_clear(ptep);
-		free_hugetlb_page(page);
-		addr += HPAGE_SIZE;
-	} while (addr < end);
-	mm->rss -= (len >> PAGE_SHIFT);
-	mpnt->vm_ops = NULL;
-	flush_tlb_range(mpnt, end - len, end);
+	BUG_ON(start & (HPAGE_SIZE - 1));
+	BUG_ON(end & (HPAGE_SIZE - 1));
+
+	for (address = start; address < end; address += HPAGE_SIZE) {
+		pte = huge_pte_offset(mm, address);
+		page = pte_page(*pte);
+		huge_page_release(page);
+		pte_clear(pte);
+	}
+	mm->rss -= (end - start) >> PAGE_SHIFT;
+	flush_tlb_range(vma, start, end);
 }
 
-static void
-unlink_vma(struct vm_area_struct *mpnt)
+void zap_hugepage_range(struct vm_area_struct *vma, unsigned long start, unsigned long length)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	spin_lock(&mm->page_table_lock);
+	unmap_hugepage_range(vma, start, start + length);
+	spin_unlock(&mm->page_table_lock);
+}
+
+void zap_hugetlb_resources(struct vm_area_struct *vma)
+{
+	zap_hugepage_range(vma, vma->vm_start, vma->vm_end);
+}
+
+static void unlink_vma(struct vm_area_struct *mpnt)
 {
 	struct mm_struct *mm = current->mm;
 	struct vm_area_struct *vma;
@@ -296,17 +287,7 @@
 	mm->map_count--;
 }
 
-int
-free_hugepages(struct vm_area_struct *mpnt)
-{
-	unlink_vma(mpnt);
-	zap_hugetlb_resources(mpnt);
-	kmem_cache_free(vm_area_cachep, mpnt);
-	return 1;
-}
-
-static struct inode *
-set_new_inode(unsigned long len, int prot, int flag, int key)
+static struct inode *set_new_inode(unsigned long len, int prot, int flag, int key)
 {
 	struct inode *inode;
 	int i;
@@ -336,8 +317,7 @@
 	return inode;
 }
 
-static int
-check_size_prot(struct inode *inode, unsigned long len, int prot, int flag)
+static int check_size_prot(struct inode *inode, unsigned long len, int prot, int flag)
 {
 	if (inode->i_uid != current->fsuid)
 		return -1;
@@ -348,15 +328,12 @@
 	return 0;
 }
 
-static int
-alloc_shared_hugetlb_pages(int key, unsigned long addr, unsigned long len,
-			   int prot, int flag)
+static int alloc_shared_hugetlb_pages(int key, unsigned long addr, unsigned long len, int prot, int flag)
 {
 	struct mm_struct *mm = current->mm;
 	struct vm_area_struct *vma;
 	struct inode *inode;
 	struct address_space *mapping;
-	struct page *page;
 	int idx;
 	int retval = -ENOMEM;
 	int newalloc = 0;
@@ -404,25 +381,10 @@
 		goto freeinode;
 	}
 
-	spin_lock(&mm->page_table_lock);
-	do {
-		pte_t *pte = huge_pte_alloc(mm, addr);
-		if ((pte) && (pte_none(*pte))) {
-			idx = (addr - vma->vm_start) >> HPAGE_SHIFT;
-			page = find_get_page(mapping, idx);
-			if (page == NULL) {
-				page = alloc_hugetlb_page();
-				if (page == NULL)
-					goto out;
-				add_to_page_cache(page, mapping, idx);
-			}
-			set_huge_pte(mm, vma, page, pte,
-				     (vma->vm_flags & VM_WRITE));
-		} else
-			goto out;
-		addr += HPAGE_SIZE;
-	} while (addr < vma->vm_end);
-	retval = 0;
+	retval = hugetlb_prefault(mapping, vma);
+	if (retval)
+		goto out;
+
 	vma->vm_flags |= (VM_HUGETLB | VM_RESERVED);
 	vma->vm_ops = &hugetlb_vm_ops;
 	spin_unlock(&mm->page_table_lock);
@@ -457,9 +419,48 @@
 	 return retval;
 }
 
-static int
-alloc_private_hugetlb_pages(int key, unsigned long addr, unsigned long len,
-			    int prot, int flag)
+int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
+{
+	struct mm_struct *mm = current->mm;
+	unsigned long addr;
+	int ret = 0;
+
+	BUG_ON(vma->vm_start & ~HPAGE_MASK);
+	BUG_ON(vma->vm_end & ~HPAGE_MASK);
+
+	spin_lock(&mm->page_table_lock);
+	for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
+		unsigned long idx;
+		pte_t *pte = huge_pte_alloc(mm, addr);
+		struct page *page;
+
+		if (!pte) {
+			ret = -ENOMEM;
+			goto out;
+		}
+		if (!pte_none(*pte))
+			continue;
+
+		idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
+			+ (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
+		page = find_get_page(mapping, idx);
+		if (!page) {
+			page = alloc_hugetlb_page();
+			if (!page) {
+				ret = -ENOMEM;
+				goto out;
+			}
+			add_to_page_cache(page, mapping, idx);
+			unlock_page(page);
+		}
+		set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE);
+	}
+out:
+	spin_unlock(&mm->page_table_lock);
+	return ret;
+}
+
+static int alloc_private_hugetlb_pages(int key, unsigned long addr, unsigned long len, int prot, int flag)
 {
 	if (!capable(CAP_SYS_ADMIN)) {
 		if (!in_group_p(0))
@@ -476,17 +477,14 @@
 	return 0;
 }
 
-int
-alloc_hugetlb_pages(int key, unsigned long addr, unsigned long len, int prot,
-		    int flag)
+int alloc_hugetlb_pages(int key, unsigned long addr, unsigned long len, int prot, int flag)
 {
 	if (key > 0)
 		return alloc_shared_hugetlb_pages(key, addr, len, prot, flag);
 	return alloc_private_hugetlb_pages(key, addr, len, prot, flag);
 }
 
-int
-set_hugetlb_mem_size(int count)
+int set_hugetlb_mem_size(int count)
 {
 	int j, lcount;
 	struct page *page, *map;
@@ -529,7 +527,7 @@
 			map->flags &= ~(1 << PG_locked | 1 << PG_error | 1 << PG_referenced |
 					1 << PG_dirty | 1 << PG_active | 1 << PG_reserved |
 					1 << PG_private | 1<< PG_writeback);
-			set_page_count(page, 0);
+			set_page_count(map, 0);
 			map++;
 		}
 		set_page_count(page, 1);
@@ -538,6 +536,12 @@
 	return (int) htlbzone_pages;
 }
 
-static struct vm_operations_struct hugetlb_vm_ops = {
-	.close	= zap_hugetlb_resources,
+static struct page * hugetlb_nopage(struct vm_area_struct * area, unsigned long address, int unused)
+{
+	BUG();
+	return NULL;
+}
+
+struct vm_operations_struct hugetlb_vm_ops = {
+	.nopage = hugetlb_nopage,
 };
diff -Nru a/arch/i386/mm/init.c b/arch/i386/mm/init.c
--- a/arch/i386/mm/init.c	Mon Nov  4 14:31:02 2002
+++ b/arch/i386/mm/init.c	Mon Nov  4 14:31:02 2002
@@ -16,6 +16,7 @@
 #include <linux/ptrace.h>
 #include <linux/mman.h>
 #include <linux/mm.h>
+#include <linux/hugetlb.h>
 #include <linux/swap.h>
 #include <linux/smp.h>
 #include <linux/init.h>
diff -Nru a/arch/i386/oprofile/Makefile b/arch/i386/oprofile/Makefile
--- a/arch/i386/oprofile/Makefile	Mon Nov  4 14:31:02 2002
+++ b/arch/i386/oprofile/Makefile	Mon Nov  4 14:31:02 2002
@@ -1,5 +1,3 @@
-vpath %.c = . $(TOPDIR)/drivers/oprofile
-
 obj-$(CONFIG_OPROFILE) += oprofile.o
  
 DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
@@ -9,8 +7,6 @@
  
 oprofile-objs := $(DRIVER_OBJS) init.o timer_int.o
 
-ifdef CONFIG_X86_LOCAL_APIC
-oprofile-objs += nmi_int.o op_model_athlon.o op_model_ppro.o
-endif
+oprofile-$(CONFIG_X86_LOCAL_APIC) += nmi_int.o op_model_athlon.o op_model_ppro.o
  
 include $(TOPDIR)/Rules.make
diff -Nru a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c
--- a/arch/i386/oprofile/nmi_int.c	Mon Nov  4 14:31:02 2002
+++ b/arch/i386/oprofile/nmi_int.c	Mon Nov  4 14:31:02 2002
@@ -135,9 +135,19 @@
 
 static void nmi_cpu_shutdown(void * dummy)
 {
+	unsigned int v;
 	int cpu = smp_processor_id();
 	struct op_msrs * msrs = &cpu_msrs[cpu];
+ 
+	/* restoring APIC_LVTPC can trigger an apic error because the delivery
+	 * mode and vector nr combination can be illegal. That's by design: on
+	 * power on apic lvt contain a zero vector nr which are legal only for
+	 * NMI delivery mode. So inhibit apic err before restoring lvtpc
+	 */
+	v = apic_read(APIC_LVTERR);
+	apic_write(APIC_LVTERR, v | APIC_LVT_MASKED);
 	apic_write(APIC_LVTPC, saved_lvtpc[cpu]);
+	apic_write(APIC_LVTERR, v);
 	nmi_restore_registers(msrs);
 }
 
diff -Nru a/arch/i386/vmlinux.lds.S b/arch/i386/vmlinux.lds.S
--- a/arch/i386/vmlinux.lds.S	Mon Nov  4 14:31:01 2002
+++ b/arch/i386/vmlinux.lds.S	Mon Nov  4 14:31:01 2002
@@ -77,6 +77,10 @@
 	*(.initcall7.init)
   }
   __initcall_end = .;
+  . = ALIGN(4096);
+  __initramfs_start = .;
+  .init.ramfs : { *(.init.initramfs) }
+  __initramfs_end = .;
   . = ALIGN(32);
   __per_cpu_start = .;
   .data.percpu  : { *(.data.percpu) }
diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig
--- a/arch/ia64/Kconfig	Mon Nov  4 14:31:02 2002
+++ b/arch/ia64/Kconfig	Mon Nov  4 14:31:02 2002
@@ -1,61 +1,30 @@
-
 mainmenu "IA-64 Linux Kernel Configuration"
 
 source "init/Kconfig"
 
-
 menu "Processor type and features"
 
 config IA64
 	bool
 	default y
 	help
-	  The Itanium is Intel's 64-bit successor to the 32-bit X86 line.  As
-	  of early 2001 it is not yet in widespread production use.  The Linux
-	  IA-64 project has a home page at <http://www.linuxia64.org/>.
-
-config ISA
-	bool
-	help
-	  Find out whether you have ISA slots on your motherboard.  ISA is the
-	  name of a bus system, i.e. the way the CPU talks to the other stuff
-	  inside your box.  Other bus systems are PCI, EISA, MicroChannel
-	  (MCA) or VESA.  ISA is an older system, now being displaced by PCI;
-	  newer boards don't support it.  If you have ISA, say Y, otherwise N.
-
-config EISA
-	bool
-	---help---
-	  The Extended Industry Standard Architecture (EISA) bus was
-	  developed as an open alternative to the IBM MicroChannel bus.
-
-	  The EISA bus provided some of the features of the IBM MicroChannel
-	  bus while maintaining backward compatibility with cards made for
-	  the older ISA bus.  The EISA bus saw limited use between 1988 and
-	  1995 when it was made obsolete by the PCI bus.
+	  The Itanium Processor Family is Intel's 64-bit successor to
+	  the 32-bit X86 line.  The IA-64 Linux project has a home
+	  page at <http://www.linuxia64.org/> and a mailing list at
+	  linux-ia64@linuxia64.org.
 
-	  Say Y here if you are building a kernel for an EISA-based machine.
-
-	  Otherwise, say N.
-
-config MCA
+config MMU
 	bool
-	help
-	  MicroChannel Architecture is found in some IBM PS/2 machines and
-	  laptops.  It is a bus system similar to PCI or ISA. See
-	  <file:Documentation/mca.txt> (and especially the web page given
-	  there) before attempting to build an MCA bus kernel.
+	default y
 
-config SBUS
+config SWAP
 	bool
+	default y
 
 config RWSEM_GENERIC_SPINLOCK
 	bool
 	default y
 
-config RWSEM_XCHGADD_ALGORITHM
-	bool
-
 choice
 	prompt "IA-64 processor type"
 	default ITANIUM
@@ -63,10 +32,12 @@
 config ITANIUM
 	bool "Itanium"
 	help
-	  Select your IA64 processor type.  The default is Intel Itanium.
+	  Select your IA-64 processor type.  The default is Intel Itanium.
+	  This choice is safe for all IA-64 systems, but may not perform
+	  optimally on systems with, say, Itanium 2 or newer processors.
 
 config MCKINLEY
-	bool "Itanium-2"
+	bool "Itanium 2"
 	help
 	  Select this to configure for an Itanium 2 (McKinley) processor.
 
@@ -90,7 +61,7 @@
 
 	  HP-simulator   For the HP simulator
 	  (<http://software.hp.com/ia64linux/>).
-	  HP-zx1         For HP zx1 platforms.
+	  HP-zx1         For HP zx1-based systems.
 	  SN1-simulator  For the SGI SN1 simulator.
 	  DIG-compliant  For DIG ("Developer's Interface Guide") compliant
 	  systems.
@@ -107,8 +78,8 @@
 	bool "HP-zx1"
 	help
 	  Build a kernel that runs on HP zx1-based systems.  This adds support
-	  for the zx1 IOMMU and makes root bus bridges appear in PCI config space
-	  (required for zx1 agpgart support).
+	  for the zx1 I/O MMU and makes root bus bridges appear in PCI config
+	  space (required for zx1 agpgart support).
 
 config IA64_SGI_SN1
 	bool "SGI-SN1"
@@ -129,15 +100,15 @@
 	  performance, a page size of 8KB or 16KB is recommended.  For best
 	  IA-32 compatibility, a page size of 4KB should be selected (the vast
 	  majority of IA-32 binaries work perfectly fine with a larger page
-	  size).  For Itanium systems, do NOT chose a page size larger than
-	  16KB.
+	  size).  For Itanium 2 or newer systems, a page size of 64KB can also
+	  be selected.
 
 	  4KB                For best IA-32 compatibility
 	  8KB                For best IA-64 performance
 	  16KB               For best IA-64 performance
-	  64KB               Not for Itanium.
+	  64KB               Requires Itanium 2 or newer processor.
 
-	  If you don't know what to do, choose 8KB.
+	  If you don't know what to do, choose 16KB.
 
 config IA64_PAGE_SIZE_8KB
 	bool "8KB"
@@ -200,7 +171,7 @@
 	default y
 	help
 	  If you say `Y' here, Linux's ACPI support will use the
-	  hardware-level system descriptions found on IA64 machines.
+	  hardware-level system descriptions found on IA-64 systems.
 
 config IA64_BRL_EMU
 	bool
@@ -226,15 +197,15 @@
 	bool "Enable McKinley A-step specific code"
 	depends on MCKINLEY
 	help
-	  Select this option to build a kernel for an IA64 McKinley system
-	  with any A-stepping CPU.
+	  Select this option to build a kernel for an IA-64 McKinley prototype
+	  system with any A-stepping CPU.
 
 config MCKINLEY_A0_SPECIFIC
 	bool "Enable McKinley A0/A1-step specific code"
 	depends on MCKINLEY_ASTEP_SPECIFIC
 	help
-	  Select this option to build a kernel for an IA64 McKinley system
-	  with an A0 or A1 stepping CPU.
+	  Select this option to build a kernel for an IA-64 McKinley prototype
+	  system with an A0 or A1 stepping CPU.
 
 config NUMA
 	bool "Enable NUMA support" if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
@@ -242,14 +213,14 @@
 	help
 	  Say Y to compile the kernel to support NUMA (Non-Uniform Memory
 	  Access).  This option is for configuring high-end multiprocessor
-	  server machines.  If in doubt, say N.
+	  server systems.  If in doubt, say N.
 
 config DISCONTIGMEM
 	bool
 	depends on IA64_SGI_SN1 || IA64_SGI_SN2 || (IA64_GENERIC || IA64_DIG || IA64_HP_ZX1) && NUMA
 	default y
 	help
-	  Say Y to upport efficient handling of discontiguous physical memory,
+	  Say Y to support efficient handling of discontiguous physical memory,
 	  for architectures which are either NUMA (Non-Uniform Memory Access)
 	  or have huge holes in the physical address space for other reasons.
 	  See <file:Documentation/vm/numa> for more.
@@ -298,14 +269,14 @@
 	depends on IA64_SGI_SN1 || IA64_SGI_SN2
 	help
 	  Turns on extra debugging code in the SGI SN (Scalable NUMA) platform
-	  for IA64.  Unless you are debugging problems on an SGI SN IA64 box,
+	  for IA-64.  Unless you are debugging problems on an SGI SN IA-64 box,
 	  say N.
 
 config IA64_SGI_SN_SIM
 	bool "Enable SGI Medusa Simulator Support"
 	depends on IA64_SGI_SN1 || IA64_SGI_SN2
 	help
-	  If you are compiling a kernel that will run under SGI's IA64
+	  If you are compiling a kernel that will run under SGI's IA-64
 	  simulator (Medusa) then say Y, otherwise say N.
 
 config IA64_SGI_AUTOTEST
@@ -323,7 +294,7 @@
 	depends on IA64_SGI_SN1 || IA64_SGI_SN2
 	help
 	  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
+	  SGI SN (Scalable NUMA) platform for IA-64.  If you are compiling for
 	  an SGI SN box then Y is the recommended value, otherwise say N.
 
 config PERCPU_IRQ
@@ -336,8 +307,8 @@
 	depends on IA64_SGI_SN1 || IA64_SGI_SN2
 	help
 	  IRIX PCIBA-inspired user mode PCI interface for the SGI SN (Scalable
-	  NUMA) platform for IA64.  Unless you are compiling a kernel for an
-	  SGI SN IA64 box, say N.
+	  NUMA) platform for IA-64.  Unless you are compiling a kernel for an
+	  SGI SN IA-64 box, say N.
 
 # On IA-64, we always want an ELF /proc/kcore.
 config KCORE_ELF
@@ -402,27 +373,17 @@
 	bool "SMP support"
 	---help---
 	  This enables support for systems with more than one CPU. If you have
-	  a system with only one CPU, like most personal computers, say N. If
-	  you have a system with more than one CPU, say Y.
+	  a system with only one CPU say N. If you have a system with more than
+	  one CPU, say Y.
 
 	  If you say N here, the kernel will run on single and multiprocessor
-	  machines, but will use only one CPU of a multiprocessor machine. If
+	  systems, but will use only one CPU of a multiprocessor system. If
 	  you say Y here, the kernel will run on many, but not all,
-	  singleprocessor machines. On a singleprocessor machine, the kernel
+	  singleprocessor system. On a singleprocessor system, the kernel
 	  will run faster if you say N here.
 
-	  Note that if you say Y here and choose architecture "586" or
-	  "Pentium" under "Processor family", the kernel will not work on 486
-	  architectures. Similarly, multiprocessor kernels for the "PPro"
-	  architecture may not work on all Pentium based boards.
-
-	  People using multiprocessor machines who say Y here should also say
-	  Y to "Enhanced Real Time Clock Support", below. The "Advanced Power
-	  Management" code will be disabled if you say Y here.
-
 	  See also the <file:Documentation/smp.tex>,
-	  <file:Documentation/smp.txt>, <file:Documentation/i386/IO-APIC.txt>,
-	  <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at
+	  <file:Documentation/smp.txt>, and the SMP-HOWTO available at
 	  <http://www.linuxdoc.org/docs.html#howto>.
 
 	  If you don't know what to do here, say N.
@@ -430,17 +391,19 @@
 config IA32_SUPPORT
 	bool "Support running of Linux/x86 binaries"
 	help
-	  IA64 processors can run IA32 (that is, x86) binaries by emulating
-	  the IA32 instruction set.  Say Y here to build in kernel support for
-	  this.  If in doubt, say Y.
+	  IA-64 processors can execute IA-32 (X86) instructions.  By
+	  saying Y here, the kernel will include IA-32 system call
+	  emulation support which makes it possible to transparently
+	  run IA-32 Linux binaries on an IA-64 Linux system.
+	  If in doubt, say Y.
 
 config PERFMON
 	bool "Performance monitor support"
 	help
 	  Selects whether support for the IA-64 performance monitor hardware
 	  is included in the kernel.  This makes some kernel data-structures a
-	  little bigger and slows down execution a bit, but it is still
-	  usually a good idea to turn this on.  If you're unsure, say N.
+	  little bigger and slows down execution a bit, but it is generally
+	  a good idea to turn this on.  If you're unsure, say Y.
 
 config IA64_PALINFO
 	tristate "/proc/pal support"
@@ -450,7 +413,7 @@
 	  about the processors in your systems, such as cache and TLB sizes
 	  and the PAL firmware version in use.
 
-	  To use this option, you have to check that the "/proc file system
+	  To use this option, you have to ensure that the "/proc file system
 	  support" (CONFIG_PROC_FS) is enabled, too.
 
 config EFI_VARS
@@ -473,42 +436,21 @@
 	---help---
 	  ELF (Executable and Linkable Format) is a format for libraries and
 	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
+	  systems. Saying Y here will enable your kernel to run ELF binaries.
 
 	  Information about ELF is contained in the ELF HOWTO available from
 	  <http://www.linuxdoc.org/docs.html#howto>.
 
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  If you want to compile this as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want),
-	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf.o. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
-
 config BINFMT_MISC
 	tristate "Kernel support for MISC binaries"
 	---help---
 	  If you say Y here, it will be possible to plug wrapper-driven binary
 	  formats into the kernel. You will like this especially when you use
 	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.linuxdoc.org/docs.html#howto>). Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
+	  Emacs-Lisp.  Once you have registered such a binary class with the
+	  kernel, you can start one of those programs simply by typing in its
+	  name at a shell prompt; Linux will automatically feed it to the
+	  correct interpreter.
 
 	  You can do other nice things, too. Read the file
 	  <file:Documentation/binfmt_misc.txt> to learn how to use this
@@ -698,7 +640,7 @@
 	  CSLIP (compressed SLIP) or PPP (Point to Point Protocol, a better
 	  and newer replacement for SLIP) or PLIP (Parallel Line Internet
 	  Protocol is mainly used to create a mini network by connecting the
-	  parallel ports of two local machines) or AX.25/KISS (protocol for
+	  parallel ports of two local systems) or AX.25/KISS (protocol for
 	  sending Internet traffic over amateur radio links).
 
 	  Make sure to read the NET-3-HOWTO. Eventually, you will have to read
@@ -831,21 +773,6 @@
 	  <file:Documentation/sound/README.OSS> contains some slightly
 	  outdated but still useful information as well.
 
-	  If you have a PnP sound card and you want to configure it at boot
-	  time using the ISA PnP tools (read
-	  <http://www.roestock.demon.co.uk/isapnptools/>), then you need to
-	  compile the sound card support as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want)
-	  and load that module after the PnP configuration is finished.  To do
-	  this, say M here and read <file:Documentation/modules.txt> as well
-	  as <file:Documentation/sound/README.modules>; the module will be
-	  called soundcore.o.
-
-	  I'm told that even without a sound card, you can make your computer
-	  say more than an occasional beep, by programming the PC speaker.
-	  Kernel patches and supporting utilities to do that are in the pcsp
-	  package, available at <ftp://ftp.infradead.org/pub/pcsp/>.
-
 source "sound/Kconfig"
 
 endmenu
@@ -870,7 +797,7 @@
 config IA64_GRANULE_16MB
 	bool "16MB"
 	help
-	  IA64 identity-mapped regions use a large page size called "granules".
+	  IA-64 identity-mapped regions use a large page size called "granules".
 
 	  Select "16MB" for a small granule size.
 	  Select "64MB" for a large granule size.  This is the current default.
@@ -895,14 +822,14 @@
 	  somewhat, as all symbols have to be loaded into the kernel image.
 
 config IA64_PRINT_HAZARDS
-	bool "Print possible IA64 hazards to console"
+	bool "Print possible IA-64 dependency violations to console"
 	depends on DEBUG_KERNEL
 	help
 	  Selecting this option prints more information for Illegal Dependency
-	  Faults, that is, for Read after Write, Write after Write or Write
-	  after Read violations.  This option is ignored if you are compiling
-	  for an Itanium A step processor (CONFIG_ITANIUM_ASTEP_SPECIFIC).  If
-	  you're unsure, select Y.
+	  Faults, that is, for Read-after-Write (RAW), Write-after-Write (WAW),
+	  or Write-after-Read (WAR) violations.  This option is ignored if you
+	  are compiling for an Itanium A step processor
+	  (CONFIG_ITANIUM_ASTEP_SPECIFIC).  If you're unsure, select Y.
 
 config DISABLE_VHPT
 	bool "Disable VHPT"
@@ -931,10 +858,11 @@
 	bool "Early printk support"
 	depends on DEBUG_KERNEL
 	help
-	  Selecting this option uses the VGA screen for printk() output before
-	  the consoles are initialised.  It is useful for debugging problems
-	  early in the boot process, but only if you have a VGA screen
-	  attached.  If you're unsure, select N.
+	  Selecting this option uses the VGA screen or serial console for
+	  printk() output before the consoles are initialised.  It is useful
+	  for debugging problems early in the boot process, but only if you
+	  have a suitable VGA/serial console attached.  If you're unsure,
+	  select N.
 
 config IA64_EARLY_PRINTK_UART
 	bool "Early printk on MMIO serial port"
@@ -970,7 +898,7 @@
 	bool "Turn on compare-and-exchange bug checking (slow!)"
 	depends on DEBUG_KERNEL
 	help
-	  Selecting this option turns on bug checking for the IA64
+	  Selecting this option turns on bug checking for the IA-64
 	  compare-and-exchange instructions.  This is slow!  Itaniums
 	  from step B3 or later don't have this problem. If you're unsure,
 	  select N.
@@ -979,7 +907,7 @@
 	bool "Turn on irq debug checks (slow!)"
 	depends on DEBUG_KERNEL
 	help
-	  Selecting this option turns on bug checking for the IA64 irq_save
+	  Selecting this option turns on bug checking for the IA-64 irq_save
 	  and restore instructions.  It's useful for tracking down spinlock
 	  problems, but slow!  If you're unsure, select N.
 
@@ -988,4 +916,3 @@
 source "security/Kconfig"
 
 source "crypto/Kconfig"
-
diff -Nru a/arch/ia64/defconfig b/arch/ia64/defconfig
--- a/arch/ia64/defconfig	Mon Nov  4 14:31:00 2002
+++ b/arch/ia64/defconfig	Mon Nov  4 14:31:00 2002
@@ -26,12 +26,7 @@
 # Processor type and features
 #
 CONFIG_IA64=y
-# CONFIG_ISA is not set
-# CONFIG_EISA is not set
-# CONFIG_MCA is not set
-# CONFIG_SBUS is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_ITANIUM=y
 # CONFIG_MCKINLEY is not set
 # CONFIG_IA64_GENERIC is not set
@@ -43,6 +38,7 @@
 # CONFIG_IA64_PAGE_SIZE_4KB is not set
 # CONFIG_IA64_PAGE_SIZE_8KB is not set
 CONFIG_IA64_PAGE_SIZE_16KB=y
+# CONFIG_IA64_PAGE_SIZE_64KB is not set
 CONFIG_ACPI=y
 CONFIG_ACPI_EFI=y
 CONFIG_ACPI_INTERPRETER=y
@@ -69,23 +65,19 @@
 #
 # ACPI Support
 #
+CONFIG_ACPI_BOOT=y
 CONFIG_ACPI_BUTTON=y
 CONFIG_ACPI_FAN=m
 CONFIG_ACPI_PROCESSOR=m
 CONFIG_ACPI_THERMAL=m
 # CONFIG_ACPI_DEBUG is not set
-CONFIG_ACPI_PCI=y
-CONFIG_ACPI=y
-CONFIG_ACPI_EFI=y
-CONFIG_ACPI_BOOT=y
 CONFIG_ACPI_BUS=y
-CONFIG_ACPI_INTERPRETER=y
 CONFIG_ACPI_POWER=y
+CONFIG_ACPI_PCI=y
 CONFIG_ACPI_SYSTEM=y
 CONFIG_PCI=y
 CONFIG_PCI_NAMES=y
 # CONFIG_HOTPLUG is not set
-# CONFIG_PCMCIA is not set
 
 #
 # Parallel port support
@@ -101,30 +93,18 @@
 # Plug and Play configuration
 #
 # CONFIG_PNP is not set
-# CONFIG_PNP_NAMES is not set
-# CONFIG_PNP_DEBUG is not set
-
-#
-# Protocols
-#
-# CONFIG_ISAPNP is not set
-# CONFIG_PNPBIOS is not set
 
 #
 # Block devices
 #
 # CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
 
 #
 # IEEE 1394 (FireWire) support (EXPERIMENTAL)
@@ -135,32 +115,16 @@
 # I2O device support
 #
 # CONFIG_I2O is not set
-# CONFIG_I2O_PCI is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
 
 #
 # Multi-device support (RAID and LVM)
 #
 # CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_BLK_DEV_LVM is not set
 
 #
 # Fusion MPT device support
 #
 # CONFIG_FUSION is not set
-# CONFIG_FUSION_BOOT is not set
-# CONFIG_FUSION_ISENSE is not set
-# CONFIG_FUSION_CTL is not set
-# CONFIG_FUSION_LAN is not set
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -175,12 +139,10 @@
 #
 # 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=y
 CONFIG_IDEDISK_MULTI_MODE=y
 # CONFIG_IDEDISK_STROKE is not set
-# CONFIG_BLK_DEV_IDECS is not set
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_IDEFLOPPY=y
 CONFIG_BLK_DEV_IDESCSI=y
@@ -189,54 +151,37 @@
 #
 # 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_IDEPCI=y
 # CONFIG_BLK_DEV_GENERIC is not set
 CONFIG_IDEPCI_SHARE_IRQ=y
 CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDE_TCQ is not set
-# CONFIG_BLK_DEV_IDE_TCQ_DEFAULT is not set
 # CONFIG_BLK_DEV_OFFBOARD is not set
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 # CONFIG_IDEDMA_PCI_AUTO is not set
-# CONFIG_IDEDMA_ONLYDISK 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_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX 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_PIIX is not set
 # CONFIG_BLK_DEV_NFORCE is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
-# CONFIG_PDC202XX_BURST is not set
 # CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_PDC202XX_FORCE is not set
-# CONFIG_BLK_DEV_RZ1000 is not set
 # CONFIG_BLK_DEV_SVWKS is not set
 # CONFIG_BLK_DEV_SIIMAGE 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=y
 
 #
 # SCSI support
@@ -247,7 +192,6 @@
 # SCSI support type (disk, tape, CD-ROM)
 #
 CONFIG_BLK_DEV_SD=y
-CONFIG_SD_EXTRA_DEVS=40
 # CONFIG_CHR_DEV_ST is not set
 # CONFIG_CHR_DEV_OSST is not set
 # CONFIG_BLK_DEV_SR is not set
@@ -265,7 +209,6 @@
 # SCSI low-level drivers
 #
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_7000FASST is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -278,31 +221,25 @@
 # 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_GENERIC_NCR5380_MMIO is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_NCR53C406A is not set
 # CONFIG_SCSI_NCR53C7xx is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_NCR53C8XX is not set
 # CONFIG_SCSI_SYM53C8XX is not set
-# CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PCI2000 is not set
 # CONFIG_SCSI_PCI2220I is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
 # CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 CONFIG_SCSI_QLOGIC_1280=y
-# 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_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
@@ -328,16 +265,13 @@
 # CONFIG_IPV6 is not set
 
 #
-#    SCTP Configuration (EXPERIMENTAL)
+# SCTP Configuration (EXPERIMENTAL)
 #
 CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_LLC is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -372,13 +306,9 @@
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=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
 # CONFIG_NET_VENDOR_RACAL is not set
 
@@ -387,34 +317,22 @@
 #
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
-# CONFIG_NET_ISA is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_APRICOT is not set
-# CONFIG_CS89x0 is not set
 # CONFIG_DGRS is not set
 CONFIG_EEPRO100=y
 # CONFIG_E100 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_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_OLD_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
-# CONFIG_SUNDANCE_MMIO is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
-# CONFIG_VIA_RHINE_MMIO is not set
 # CONFIG_NET_POCKET is not set
 
 #
@@ -423,8 +341,6 @@
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
 # CONFIG_E1000 is not set
-# CONFIG_E1000_NAPI is not set
-# CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -432,7 +348,6 @@
 # CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
 
@@ -491,17 +406,10 @@
 #
 # CONFIG_GAMEPORT is not set
 CONFIG_SOUND_GAMEPORT=y
-# CONFIG_GAMEPORT_NS558 is not set
-# CONFIG_GAMEPORT_L4 is not set
-# CONFIG_GAMEPORT_EMU10K1 is not set
-# CONFIG_GAMEPORT_VORTEX is not set
-# CONFIG_GAMEPORT_FM801 is not set
-# CONFIG_GAMEPORT_CS461x is not set
 CONFIG_SERIO=y
 CONFIG_SERIO_I8042=y
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PARKBD is not set
 
 #
 # Input Device Drivers
@@ -514,34 +422,8 @@
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 # CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_INPORT is not set
-# CONFIG_MOUSE_LOGIBM is not set
-# CONFIG_MOUSE_PC110PAD is not set
 # CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_JOYSTICK_ANALOG is not set
-# CONFIG_JOYSTICK_A3D is not set
-# CONFIG_JOYSTICK_ADI is not set
-# CONFIG_JOYSTICK_COBRA is not set
-# CONFIG_JOYSTICK_GF2K is not set
-# CONFIG_JOYSTICK_GRIP is not set
-# CONFIG_JOYSTICK_GRIP_MP is not set
-# CONFIG_JOYSTICK_GUILLEMOT is not set
-# CONFIG_JOYSTICK_INTERACT is not set
-# CONFIG_JOYSTICK_SIDEWINDER is not set
-# CONFIG_JOYSTICK_TMDC is not set
-# CONFIG_JOYSTICK_IFORCE is not set
-# CONFIG_JOYSTICK_WARRIOR is not set
-# CONFIG_JOYSTICK_MAGELLAN is not set
-# CONFIG_JOYSTICK_SPACEORB is not set
-# CONFIG_JOYSTICK_SPACEBALL is not set
-# CONFIG_JOYSTICK_STINGER is not set
-# CONFIG_JOYSTICK_TWIDDLER is not set
-# CONFIG_JOYSTICK_DB9 is not set
-# CONFIG_JOYSTICK_GAMECON is not set
-# CONFIG_JOYSTICK_TURBOGRAFX is not set
-# CONFIG_INPUT_JOYDUMP is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_TOUCHSCREEN_GUNZE is not set
 CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_PCSPKR is not set
 # CONFIG_INPUT_UINPUT is not set
@@ -559,9 +441,6 @@
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_SERIAL_8250_CS is not set
-# CONFIG_SERIAL_8250_ACPI is not set
-# CONFIG_SERIAL_8250_HCDP is not set
 CONFIG_SERIAL_8250_EXTENDED=y
 # CONFIG_SERIAL_8250_MANY_PORTS is not set
 CONFIG_SERIAL_8250_SHARE_IRQ=y
@@ -582,10 +461,8 @@
 #
 CONFIG_I2C=y
 CONFIG_I2C_ALGOBIT=y
-# CONFIG_I2C_PHILIPSPAR is not set
 # CONFIG_I2C_ELV is not set
 # CONFIG_I2C_VELLEMAN is not set
-# CONFIG_SCx200_I2C is not set
 # CONFIG_SCx200_ACB is not set
 # CONFIG_I2C_ALGOPCF is not set
 CONFIG_I2C_CHARDEV=y
@@ -632,7 +509,6 @@
 CONFIG_DRM_I810=y
 CONFIG_DRM_I830=y
 CONFIG_DRM_MGA=y
-# CONFIG_SCx200_GPIO is not set
 # CONFIG_RAW_DRIVER is not set
 
 #
@@ -644,28 +520,21 @@
 # File systems
 #
 # CONFIG_QUOTA is not set
-# CONFIG_QFMT_V1 is not set
-# CONFIG_QFMT_V2 is not set
 CONFIG_AUTOFS_FS=y
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_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_BEFS_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=y
 CONFIG_MSDOS_FS=y
-# CONFIG_UMSDOS_FS is not set
 CONFIG_VFAT_FS=y
 # 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=y
@@ -673,31 +542,20 @@
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_JFS_DEBUG is not set
-# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_DEBUG is not set
-# CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
 CONFIG_PROC_FS=y
 # CONFIG_DEVFS_FS is not set
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
 CONFIG_DEVPTS_FS=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_UDF_FS is not set
-# CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
 # CONFIG_XFS_FS is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_QUOTA is not set
 
 #
 # Network File Systems
@@ -707,10 +565,9 @@
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 CONFIG_NFS_V4=y
-# CONFIG_ROOT_NFS is not set
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
-CONFIG_NFSD_V4=y
+# CONFIG_NFSD_V4 is not set
 # CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
@@ -719,16 +576,7 @@
 # CONFIG_CIFS is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_ZISOFS_FS is not set
 
 #
 # Partition Types
@@ -749,7 +597,6 @@
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
 CONFIG_EFI_PARTITION=y
-# CONFIG_SMB_NLS is not set
 CONFIG_NLS=y
 
 #
@@ -816,7 +663,6 @@
 # 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=y
 # CONFIG_SOUND_ES1370 is not set
@@ -831,7 +677,6 @@
 # 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
 
@@ -870,15 +715,6 @@
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER 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_SDDR55 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
 
 #
 # USB Human Interface Devices (HID)
@@ -886,8 +722,6 @@
 CONFIG_USB_HID=y
 CONFIG_USB_HIDINPUT=y
 # CONFIG_HID_FF is not set
-# CONFIG_HID_PID is not set
-# CONFIG_LOGITECH_FF is not set
 CONFIG_USB_HIDDEV=y
 # CONFIG_USB_AIPTEK is not set
 # CONFIG_USB_WACOM is not set
@@ -908,16 +742,8 @@
 # CONFIG_USB_DABUSB is not set
 
 #
-#   Video4Linux support is needed for USB Multimedia device support
+# Video4Linux support is needed for USB Multimedia device support
 #
-# CONFIG_USB_VICAM is not set
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_KONICAWC is not set
-# CONFIG_USB_OV511 is not set
-# CONFIG_USB_PWC is not set
-# CONFIG_USB_SE401 is not set
-# CONFIG_USB_STV680 is not set
 
 #
 # USB Network adaptors
@@ -932,62 +758,26 @@
 #
 # 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_EDGEPORT_TI 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_USA19QW is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-# CONFIG_USB_SERIAL_KLSI is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_SAFE is not set
-# CONFIG_USB_SERIAL_SAFE_PADDED 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_EMI26 is not set
 # CONFIG_USB_TIGL is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_BRLVGER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_SPEEDTOUCH is not set
 # CONFIG_USB_TEST is not set
 
 #
 # Library routines
 #
 # CONFIG_CRC32 is not set
-# CONFIG_ZLIB_INFLATE is not set
-# CONFIG_ZLIB_DEFLATE is not set
 
 #
 # Bluetooth support
@@ -1016,3 +806,8 @@
 # Security options
 #
 CONFIG_SECURITY_CAPABILITIES=y
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
diff -Nru a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c
--- a/arch/ia64/hp/sim/simscsi.c	Mon Nov  4 14:31:01 2002
+++ b/arch/ia64/hp/sim/simscsi.c	Mon Nov  4 14:31:01 2002
@@ -131,20 +131,6 @@
 }
 
 int
-simscsi_abort (Scsi_Cmnd *cmd)
-{
-	printk ("simscsi_abort: unimplemented\n");
-	return SCSI_ABORT_SUCCESS;
-}
-
-int
-simscsi_reset (Scsi_Cmnd *cmd, unsigned int reset_flags)
-{
-	printk ("simscsi_reset: unimplemented\n");
-	return SCSI_RESET_SUCCESS;
-}
-
-int
 simscsi_biosparam (struct scsi_device *sdev, struct block_device *n,
 		sector_t capacity, int ip[])
 {
diff -Nru a/arch/ia64/hp/sim/simscsi.h b/arch/ia64/hp/sim/simscsi.h
--- a/arch/ia64/hp/sim/simscsi.h	Mon Nov  4 14:31:00 2002
+++ b/arch/ia64/hp/sim/simscsi.h	Mon Nov  4 14:31:00 2002
@@ -20,21 +20,19 @@
 extern int simscsi_biosparam (struct scsi_device *, struct block_device *,
 		sector_t, int[]);
 
-#define SIMSCSI {					\
-	detect:			simscsi_detect,		\
-	release:		simscsi_release,	\
-	info:			simscsi_info,		\
-	queuecommand:		simscsi_queuecommand,	\
-	abort:			simscsi_abort,		\
-	reset:			simscsi_reset,		\
-	bios_param:		simscsi_biosparam,	\
-	can_queue:		SIMSCSI_REQ_QUEUE_LEN,	\
-	this_id:		-1,			\
-	sg_tablesize:		SG_ALL,			\
-	cmd_per_lun:		SIMSCSI_REQ_QUEUE_LEN,	\
-	present:		0,			\
-	unchecked_isa_dma:	0,			\
-	use_clustering:		DISABLE_CLUSTERING	\
+#define SIMSCSI {						\
+	.detect			= simscsi_detect,		\
+	.release		= simscsi_release,		\
+	.info			= simscsi_info,			\
+	.queuecommand		= simscsi_queuecommand,		\
+	.bios_param		= simscsi_biosparam,		\
+	.can_queue		= SIMSCSI_REQ_QUEUE_LEN,	\
+	.this_id		= -1,				\
+	.sg_tablesize		= SG_ALL,			\
+	.cmd_per_lun		= SIMSCSI_REQ_QUEUE_LEN,	\
+	.present		= 0,				\
+	.unchecked_isa_dma	= 0,				\
+	.use_clustering		= DISABLE_CLUSTERING		\
 }
 
 #endif /* SIMSCSI_H */
diff -Nru a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
--- a/arch/ia64/ia32/sys_ia32.c	Mon Nov  4 14:31:02 2002
+++ b/arch/ia64/ia32/sys_ia32.c	Mon Nov  4 14:31:02 2002
@@ -3076,7 +3076,7 @@
 		break;
 
 	      default:
-		ret = -EIO;
+		ret = ptrace_request(child, request, addr, data);
 		break;
 
 	}
diff -Nru a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
--- a/arch/ia64/kernel/entry.S	Mon Nov  4 14:31:01 2002
+++ b/arch/ia64/kernel/entry.S	Mon Nov  4 14:31:01 2002
@@ -1245,15 +1245,15 @@
 	data8 sys_alloc_hugepages
 	data8 sys_free_hugepages		// 1235
 	data8 sys_exit_group
-	data8 ia64_ni_syscall
+	data8 sys_lookup_dcookie
 	data8 sys_io_setup
 	data8 sys_io_destroy
 	data8 sys_io_getevents			// 1240
 	data8 sys_io_submit
 	data8 sys_io_cancel
-	data8 ia64_ni_syscall
-	data8 ia64_ni_syscall
-	data8 ia64_ni_syscall			// 1245
+	data8 sys_epoll_create
+	data8 sys_epoll_ctl
+	data8 sys_epoll_wait			// 1245
 	data8 ia64_ni_syscall
 	data8 ia64_ni_syscall
 	data8 ia64_ni_syscall
diff -Nru a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
--- a/arch/ia64/kernel/irq.c	Mon Nov  4 14:31:02 2002
+++ b/arch/ia64/kernel/irq.c	Mon Nov  4 14:31:02 2002
@@ -172,7 +172,7 @@
 #else
 		for (j = 0; j < NR_CPUS; j++)
 			if (cpu_online(j))
-				seq_printf(p, "%10u ", kstat.irqs[j][i]);
+				seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
 #endif
 		seq_printf(p, " %14s", idesc->handler->typename);
 		seq_printf(p, "  %s", action->name);
@@ -346,7 +346,7 @@
 	unsigned int status;
 
 	irq_enter();
-	kstat.irqs[cpu][irq]++;
+	kstat_cpu(cpu).irqs[irq]++;
 
 	if (desc->status & IRQ_PER_CPU) {
 		/* no locking required for CPU-local interrupts: */
diff -Nru a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
--- a/arch/ia64/kernel/process.c	Mon Nov  4 14:31:01 2002
+++ b/arch/ia64/kernel/process.c	Mon Nov  4 14:31:01 2002
@@ -516,7 +516,7 @@
 	struct task_struct *parent = current;
 	int result, tid;
 
-	tid = clone(flags | CLONE_VM, 0);
+	tid = clone(flags | CLONE_VM | CLONE_UNTRACED, 0);
 	if (parent != current) {
 		result = (*fn)(arg);
 		_exit(result);
diff -Nru a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
--- a/arch/ia64/kernel/ptrace.c	Mon Nov  4 14:31:03 2002
+++ b/arch/ia64/kernel/ptrace.c	Mon Nov  4 14:31:03 2002
@@ -1268,16 +1268,8 @@
 		ret = ptrace_setregs(child, (struct pt_all_user_regs*) data);
 		goto out_tsk;
 
-	      case PTRACE_SETOPTIONS:
-		if (data & PTRACE_O_TRACESYSGOOD)
-			child->ptrace |= PT_TRACESYSGOOD;
-		else
-			child->ptrace &= ~PT_TRACESYSGOOD;
-		ret = 0;
-		break;
-
 	      default:
-		ret = -EIO;
+		ret = ptrace_request(child, request, addr, data);
 		goto out_tsk;
 	}
   out_tsk:
diff -Nru a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
--- a/arch/ia64/kernel/setup.c	Mon Nov  4 14:31:01 2002
+++ b/arch/ia64/kernel/setup.c	Mon Nov  4 14:31:01 2002
@@ -625,21 +625,18 @@
 	extern char __per_cpu_end[];
 	int cpu;
 
-	if (__per_cpu_end - __per_cpu_start > PAGE_SIZE)
-		panic("Per-cpu data area too big! (%Zu > %Zu)",
-		      __per_cpu_end - __per_cpu_start, PAGE_SIZE);
-
-
 	/*
 	 * get_free_pages() cannot be used before cpu_init() done.  BSP allocates
 	 * "NR_CPUS" pages for all CPUs to avoid that AP calls get_zeroed_page().
 	 */
 	if (smp_processor_id() == 0) {
-		cpu_data = (unsigned long)alloc_bootmem_pages(PAGE_SIZE * NR_CPUS);
+		cpu_data = (unsigned long) __alloc_bootmem(PERCPU_PAGE_SIZE * NR_CPUS,
+							   PERCPU_PAGE_SIZE,
+							   __pa(MAX_DMA_ADDRESS));
 		for (cpu = 0; cpu < NR_CPUS; cpu++) {
 			memcpy(cpu_data, __phys_per_cpu_start, __per_cpu_end - __per_cpu_start);
 			__per_cpu_offset[cpu] = (char *) cpu_data - __per_cpu_start;
-			cpu_data += PAGE_SIZE;
+			cpu_data += PERCPU_PAGE_SIZE;
 		}
 	}
 	cpu_data = __per_cpu_start + __per_cpu_offset[smp_processor_id()];
@@ -650,7 +647,6 @@
 	cpu_info = cpu_data + ((char *) &__get_cpu_var(cpu_info) - __per_cpu_start);
 #ifdef CONFIG_NUMA
 	cpu_info->node_data = get_node_data_ptr();
-	cpu_info->nodeid = boot_get_local_nodeid();
 #endif
 
 	/*
diff -Nru a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
--- a/arch/ia64/kernel/smpboot.c	Mon Nov  4 14:31:01 2002
+++ b/arch/ia64/kernel/smpboot.c	Mon Nov  4 14:31:01 2002
@@ -430,30 +430,39 @@
 
 #ifdef CONFIG_NUMA
 
-char cpu_to_node_map[NR_CPUS] __cacheline_aligned;
+/* on which node is each logical CPU (one cacheline even for 64 CPUs) */
+volatile char cpu_to_node_map[NR_CPUS] __cacheline_aligned;
+/* which logical CPUs are on which nodes */
+volatile unsigned long node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
 
 /*
- * Build cpu to node mapping.
+ * Build cpu to node mapping and initialize the per node cpu masks.
  */
 void __init
 build_cpu_to_node_map (void)
 {
-	int cpu, i;
+	int cpu, i, node;
 
+	for(node=0; node<MAX_NUMNODES; node++)
+		node_to_cpu_mask[node] = 0;
 	for(cpu = 0; cpu < NR_CPUS; ++cpu) {
 		/*
 		 * All Itanium NUMA platforms I know use ACPI, so maybe we
 		 * can drop this ifdef completely.                    [EF]
 		 */
 #ifdef CONFIG_ACPI_NUMA
+		node = -1;
 		for (i = 0; i < NR_CPUS; ++i)
 			if (cpu_physical_id(cpu) == node_cpuid[i].phys_id) {
-				cpu_to_node_map[cpu] = node_cpuid[i].nid;
+				node = node_cpuid[i].nid;
 				break;
 			}
 #else
 #		error Fixme: Dunno how to build CPU-to-node map.
 #endif
+		cpu_to_node_map[cpu] = node;
+		if (node >= 0)
+			node_to_cpu_mask[node] |= (1UL << cpu);
 	}
 }
 
diff -Nru a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
--- a/arch/ia64/kernel/sys_ia64.c	Mon Nov  4 14:31:02 2002
+++ b/arch/ia64/kernel/sys_ia64.c	Mon Nov  4 14:31:02 2002
@@ -9,6 +9,7 @@
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
+#include <linux/hugetlb.h>
 #include <linux/mman.h>
 #include <linux/sched.h>
 #include <linux/file.h>		/* doh, must come after sched.h... */
diff -Nru a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c
--- a/arch/ia64/mm/hugetlbpage.c	Mon Nov  4 14:31:02 2002
+++ b/arch/ia64/mm/hugetlbpage.c	Mon Nov  4 14:31:02 2002
@@ -8,6 +8,7 @@
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
+#include <linux/hugetlb.h>
 #include <linux/pagemap.h>
 #include <linux/smp_lock.h>
 #include <linux/slab.h>
diff -Nru a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
--- a/arch/ia64/mm/init.c	Mon Nov  4 14:31:01 2002
+++ b/arch/ia64/mm/init.c	Mon Nov  4 14:31:01 2002
@@ -287,7 +287,8 @@
 	ia64_srlz_d();
 
 	ia64_itr(0x2, IA64_TR_PERCPU_DATA, PERCPU_ADDR,
-		 pte_val(pfn_pte(__pa(my_cpu_data) >> PAGE_SHIFT, PAGE_KERNEL)), PAGE_SHIFT);
+		 pte_val(pfn_pte(__pa(my_cpu_data) >> PAGE_SHIFT, PAGE_KERNEL)),
+		 PERCPU_PAGE_SHIFT);
 
 	ia64_set_psr(psr);
 	ia64_srlz_i();
@@ -454,8 +455,6 @@
 		num_pgt_pages = nr_free_pages() / 10;
 	if (num_pgt_pages > pgt_cache_water[1])
 		pgt_cache_water[1] = num_pgt_pages;
-
-	show_mem();
 
 	/* install the gate page in the global page table: */
 	put_gate_page(virt_to_page(__start_gate_section), GATE_ADDR);
diff -Nru a/arch/ia64/vmlinux.lds.S b/arch/ia64/vmlinux.lds.S
--- a/arch/ia64/vmlinux.lds.S	Mon Nov  4 14:31:02 2002
+++ b/arch/ia64/vmlinux.lds.S	Mon Nov  4 14:31:02 2002
@@ -137,7 +137,7 @@
 	{ *(.kstrtab) }
 
   /* Per-cpu data: */
-  . = ALIGN(PAGE_SIZE);
+  . = ALIGN(PERCPU_PAGE_SIZE);
   __phys_per_cpu_start = .;
   .data.percpu PERCPU_ADDR : AT(__phys_per_cpu_start - PAGE_OFFSET)
 	{
@@ -145,7 +145,7 @@
 		*(.data.percpu)
 		__per_cpu_end = .;
 	}
-  . = __phys_per_cpu_start + 4096;	/* ensure percpu fits into smallest page size (4KB) */
+  . = __phys_per_cpu_start + PERCPU_PAGE_SIZE;	/* ensure percpu data fits into percpu page size */
 
   .data : AT(ADDR(.data) - PAGE_OFFSET)
 	{ *(.data) *(.gnu.linkonce.d*) CONSTRUCTORS }
diff -Nru a/arch/m68k/Kconfig b/arch/m68k/Kconfig
--- a/arch/m68k/Kconfig	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/Kconfig	Mon Nov  4 14:31:02 2002
@@ -6,21 +6,25 @@
 	bool
 	default y
 
-config UID16
+config MMU
 	bool
 	default y
 
-config RWSEM_GENERIC_SPINLOCK
+config SWAP
 	bool
 	default y
 
-config RWSEM_XCHGADD_ALGORITHM
+config UID16
 	bool
+	default y
 
-config GENERIC_ISA_DMA
+config RWSEM_GENERIC_SPINLOCK
 	bool
 	default y
 
+config RWSEM_XCHGADD_ALGORITHM
+	bool
+
 
 mainmenu "Linux/68k Kernel Configuration"
 
@@ -193,7 +197,8 @@
 	help
 	  This option enables support for the Sun 3x series of workstations.
 	  Be warned that this support is very experimental. You will also want
-	  to say Y to 68020 support and N to the other processors below.
+	  to say Y to 68030 support and N to the other processors below.
+	  Note that Sun 3x kernels are not compatible with Sun 3 hardware.
 	  General Linux information on the Sun 3x series (now discontinued)
 	  is at <http://www.angelfire.com/ca2/tech68k/sun3.html>.
 
@@ -202,13 +207,14 @@
 config SUN3
 	bool "Sun3 support"
 	help
-	  This option enables support for the Sun 3 series of workstations.
-	  Currently, only the Sun 3/80 is supported within the Sun 3x family.
-	  You will also want to enable 68030 support.  General Linux
-	  information on the Sun 3x series (now discontinued) is at
-	  <http://www.angelfire.com/ca2/tech68k/sun3.html>.
+	  This option enables support for the Sun 3 series of workstations
+	  (3/50, 3/60, 3/1xx, 3/2xx systems). Enabling this option requires 
+	  that all other hardware types must be disabled, as Sun 3 kernels 
+	  are incompatible with all other m68k targets (including Sun 3x!).  
+	  Also, you will want to say Y to 68020 support and N to the other 
+	  processors below.
 
-	  If you don't want to compile a kernel for a Sun 3, say N.
+	  If you don't want to compile a kernel exclusively for a Sun 3, say N.
 
 config Q40
 	bool "Q40/Q60 support"
@@ -630,6 +636,11 @@
 	  (MCA) or VESA.  ISA is an older system, now being displaced by PCI;
 	  newer boards don't support it.  If you have ISA, say Y, otherwise N.
 
+config GENERIC_ISA_DMA
+	bool
+	depends on Q40 || AMIGA_PCMCIA || GG2
+	default y
+
 source "drivers/pci/Kconfig"
 
 source "drivers/zorro/Kconfig"
@@ -646,9 +657,7 @@
 
 source "drivers/md/Kconfig"
 
-if MAC
 source "drivers/input/Kconfig"
-endif
 
 
 menu "ATA/ATAPI/MFM/RLL device support"
@@ -1124,8 +1133,8 @@
 	depends on SUN3 && SCSI
 	help
 	  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.
+	  SCSI controller found in the Sun 3/50 and 3/60, as well as for
+	  "Sun3" type VME scsi controllers also based on the NCR5380.
 	  General Linux information on the Sun 3 series (now discontinued)
 	  is at <http://www.angelfire.com/ca2/tech68k/sun3.html>.
 
@@ -1766,6 +1775,11 @@
 
 	  If unsure, say Y.
 
+config HW_CONSOLE
+	bool
+	depends on VT
+	default y
+
 config NVRAM
 	bool
 	depends on ATARI
@@ -1792,51 +1806,6 @@
 	  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 will be called nvram.o. If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt>.
-
-config AMIGAMOUSE
-	tristate "Amiga mouse support"
-	depends on AMIGA
-	help
-	  If you want to be able to use an Amiga mouse in Linux, say Y.
-
-	  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 amigamouse.o. If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt>.
-
-config BUSMOUSE
-	bool
-	depends on SUN3X_ZS || ATARI && VT && ATARIMOUSE || AMIGA && AMIGAMOUSE
-	default y
-	---help---
-	  Say Y here if your machine has a bus mouse as opposed to a serial
-	  mouse. Most people have a regular serial MouseSystem or
-	  Microsoft mouse (made by Logitech) that plugs into a COM port
-	  (rectangular with 9 or 25 pins). These people say N here. 
-
-	  If you have a laptop, you either have to check the documentation or
-	  experiment a bit to find out whether the trackball is a serial mouse
-	  or not; it's best to say Y here for you.
-
-	  This is the generic bus mouse driver code. If you have a bus mouse,
-	  you will have to say Y here and also to the specific driver for your
-	  mouse below.
-
-	  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 busmouse.o. If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt>.
-
-config ATARIMOUSE
-	tristate "Atari mouse support"
-	depends on ATARI && VT
-	help
-	  If you want to be able to use an Atari mouse in Linux, say Y.
-
-	  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 atarimouse.o. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config ATARI_MFPSER
diff -Nru a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c
--- a/arch/m68k/amiga/amiints.c	Mon Nov  4 14:31:03 2002
+++ b/arch/m68k/amiga/amiints.c	Mon Nov  4 14:31:03 2002
@@ -128,8 +128,7 @@
 		printk("%s: Warning: dev_id of %s is zero\n",
 		       __FUNCTION__, node->devname);
 
-	save_flags(flags);
-	cli();
+	local_irq_save(flags);
 
 	cur = *list;
 
@@ -153,7 +152,7 @@
 	node->next = cur;
 	*list = node;
 
-	restore_flags(flags);
+	local_irq_restore(flags);
 	return 0;
 }
 
@@ -162,19 +161,18 @@
 	unsigned long flags;
 	irq_node_t *node;
 
-	save_flags(flags);
-	cli();
+	local_irq_save(flags);
 
 	for (node = *list; node; list = &node->next, node = *list) {
 		if (node->dev_id == dev_id) {
 			*list = node->next;
 			/* Mark it as free. */
 			node->handler = NULL;
-			restore_flags(flags);
+			local_irq_restore(flags);
 			return;
 		}
 	}
-	restore_flags(flags);
+	local_irq_restore(flags);
 	printk ("%s: tried to remove invalid irq\n", __FUNCTION__);
 }
 
@@ -350,7 +348,7 @@
 
 inline void amiga_do_irq(int irq, struct pt_regs *fp)
 {
-	kstat.irqs[0][SYS_IRQS + irq]++;
+	kstat_cpu(0).irqs[SYS_IRQS + irq]++;
 	ami_irq_list[irq]->handler(irq, ami_irq_list[irq]->dev_id, fp);
 }
 
@@ -358,7 +356,7 @@
 {
 	irq_node_t *node;
 
-	kstat.irqs[0][SYS_IRQS + irq]++;
+	kstat_cpu(0).irqs[SYS_IRQS + irq]++;
 
 	custom.intreq = amiga_intena_vals[irq];
 
@@ -479,7 +477,7 @@
 		if (!(node = ami_irq_list[i]))
 			continue;
 		seq_printf(p, "ami  %2d: %10u ", i,
-		               kstat.irqs[0][SYS_IRQS + i]);
+		               kstat_cpu(0).irqs[SYS_IRQS + i]);
 		do {
 			if (node->flags & SA_INTERRUPT)
 				seq_puts(p, "F ");
diff -Nru a/arch/m68k/amiga/amisound.c b/arch/m68k/amiga/amisound.c
--- a/arch/m68k/amiga/amisound.c	Mon Nov  4 14:31:03 2002
+++ b/arch/m68k/amiga/amisound.c	Mon Nov  4 14:31:03 2002
@@ -71,8 +71,7 @@
 	if (!snd_data)
 		return;
 
-	save_flags(flags);
-	cli();
+	local_irq_save(flags);
 	del_timer( &sound_timer );
 
 	if (hz > 20 && hz < 32767) {
@@ -100,7 +99,7 @@
 	} else
 		nosound( 0 );
 
-	restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 
diff -Nru a/arch/m68k/amiga/cia.c b/arch/m68k/amiga/cia.c
--- a/arch/m68k/amiga/cia.c	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/amiga/cia.c	Mon Nov  4 14:31:02 2002
@@ -131,7 +131,7 @@
 	custom.intreq = base->int_mask;
 	for (i = 0; i < CIA_IRQS; i++, irq++, mach_irq++) {
 		if (ints & 1) {
-			kstat.irqs[0][irq]++;
+			kstat_cpu(0).irqs[irq]++;
 			base->irq_list[i].handler(mach_irq, base->irq_list[i].dev_id, fp);
 		}
 		ints >>= 1;
@@ -166,7 +166,7 @@
 	j = base->cia_irq;
 	for (i = 0; i < CIA_IRQS; i++) {
 		seq_printf(p, "cia  %2d: %10d ", j + i,
-			       kstat.irqs[0][SYS_IRQS + j + i]);
+			       kstat_cpu(0).irqs[SYS_IRQS + j + i]);
 		seq_puts(p, "  ");
 		seq_printf(p, "%s\n", base->irq_list[i].devname);
 	}
diff -Nru a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c
--- a/arch/m68k/amiga/config.c	Mon Nov  4 14:31:00 2002
+++ b/arch/m68k/amiga/config.c	Mon Nov  4 14:31:00 2002
@@ -88,6 +88,7 @@
 static int a3000_hwclk (int, struct rtc_time *);
 static int a2000_hwclk (int, struct rtc_time *);
 static int amiga_set_clock_mmss (unsigned long);
+extern void amiga_mksound( unsigned int count, unsigned int ticks );
 #ifdef CONFIG_AMIGA_FLOPPY
 extern void amiga_floppy_setup(char *, int *);
 #endif
@@ -408,7 +409,7 @@
 #ifdef CONFIG_DUMMY_CONSOLE
   conswitchp           = &dummy_con;
 #endif
-#ifdef CONFIG_INPUT_M68K_BEEP
+#if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)
   mach_beep            = amiga_mksound;
 #endif
 
diff -Nru a/arch/m68k/apollo/config.c b/arch/m68k/apollo/config.c
--- a/arch/m68k/apollo/config.c	Mon Nov  4 14:31:01 2002
+++ b/arch/m68k/apollo/config.c	Mon Nov  4 14:31:01 2002
@@ -26,8 +26,6 @@
 u_long apollo_model;
 
 extern void dn_sched_init(void (*handler)(int,void *,struct pt_regs *));
-extern int dn_keyb_init(void);
-extern int dn_dummy_kbdrate(struct kbd_repeat *);
 extern void dn_init_IRQ(void);
 extern int dn_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id);
 extern void dn_free_irq(unsigned int irq, void *dev_id);
@@ -37,7 +35,6 @@
 extern unsigned long dn_gettimeoffset(void);
 extern int dn_dummy_hwclk(int, struct rtc_time *);
 extern int dn_dummy_set_clock_mmss(unsigned long);
-extern void dn_mksound(unsigned int count, unsigned int ticks);
 extern void dn_dummy_reset(void);
 extern void dn_dummy_waitbut(void);
 extern struct fb_info *dn_fb_init(long *);
@@ -165,10 +162,6 @@
 	dn_setup_model();	
 
 	mach_sched_init=dn_sched_init; /* */
-#ifdef CONFIG_VT
-	mach_keyb_init=dn_keyb_init;
-	mach_kbdrate=dn_dummy_kbdrate;
-#endif
 	mach_init_IRQ=dn_init_IRQ;
 	mach_default_handler=NULL;
 	mach_request_irq     = dn_request_irq;
@@ -188,9 +181,6 @@
 	mach_reset	     = dn_dummy_reset;  /* */
 #ifdef CONFIG_DUMMY_CONSOLE
         conswitchp           = &dummy_con;
-#endif
-#ifdef CONFIG_VT
-	kd_mksound	     = dn_mksound;
 #endif
 #ifdef CONFIG_HEARTBEAT
   	mach_heartbeat = dn_heartbeat;
diff -Nru a/arch/m68k/apollo/dn_ints.c b/arch/m68k/apollo/dn_ints.c
--- a/arch/m68k/apollo/dn_ints.c	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/apollo/dn_ints.c	Mon Nov  4 14:31:02 2002
@@ -117,35 +117,6 @@
 
 }
 
-#ifdef CONFIG_VT
-extern void write_keyb_cmd(u_short length, u_char *cmd);
-static char BellOnCommand[] =  { 0xFF, 0x21, 0x81 },
-		    BellOffCommand[] = { 0xFF, 0x21, 0x82 };
-
-static void dn_nosound (unsigned long ignored) {
-
-	write_keyb_cmd(sizeof(BellOffCommand),BellOffCommand);
-
-}
-
-void dn_mksound( unsigned int count, unsigned int ticks ) {
-
-	static struct timer_list sound_timer = { function: dn_nosound };
-
-	del_timer( &sound_timer );
-	if(count) {
-		write_keyb_cmd(sizeof(BellOnCommand),BellOnCommand);
-		if (ticks) {
-       		sound_timer.expires = jiffies + ticks;
-			add_timer( &sound_timer );
-		}
-	}
-	else
-		write_keyb_cmd(sizeof(BellOffCommand),BellOffCommand);
-}
-#endif /* CONFIG_VT */
-
-
 void dn_dummy_video_setup(char *options,int *ints) {
 
   printk("no video yet\n");
diff -Nru a/arch/m68k/atari/Makefile b/arch/m68k/atari/Makefile
--- a/arch/m68k/atari/Makefile	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/atari/Makefile	Mon Nov  4 14:31:02 2002
@@ -7,8 +7,6 @@
 obj-y		:= config.o time.o debug.o ataints.o stdma.o \
 			atasound.o stram.o atari_ksyms.o
 
-obj-$(CONFIG_VT)	+= atakeyb.o joystick.o
-
 ifeq ($(CONFIG_PCI),y)
 obj-$(CONFIG_HADES)	+= hades-pci.o
 endif
diff -Nru a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c
--- a/arch/m68k/atari/ataints.c	Mon Nov  4 14:31:01 2002
+++ b/arch/m68k/atari/ataints.c	Mon Nov  4 14:31:01 2002
@@ -37,7 +37,6 @@
 
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/ptrace.h>
 #include <linux/kernel_stat.h>
 #include <linux/init.h>
 #include <linux/seq_file.h>
@@ -191,7 +190,7 @@
 "	andw	#0xfeff,%%sr\n"		/* set IPL = 6 again */		   \
 "	orb 	#(1<<(%c3&7)),%a4:w\n"	/* now unmask the int again */	   \
 "	jbra	ret_from_interrupt\n"					   \
-	 : : "i" (&kstat.irqs[0][n+8]), "i" (&irq_handler[n+8]),	   \
+	 : : "i" (&kstat_cpu(0).irqs[n+8]), "i" (&irq_handler[n+8]),	   \
 	     "n" (PT_OFF_SR), "n" (n),					   \
 	     "i" (n & 8 ? (n & 16 ? &tt_mfp.int_mk_a : &mfp.int_mk_a)	   \
 		        : (n & 16 ? &tt_mfp.int_mk_b : &mfp.int_mk_b)),	   \
@@ -297,7 +296,7 @@
 	addql	#8,%%sp
 	addql	#4,%%sp
 	jbra	ret_from_interrupt"
-	 : : "i" (&kstat.irqs[0]), "n" (PT_OFF_FORMATVEC),
+	 : : "i" (&kstat_cpu(0).irqs), "n" (PT_OFF_FORMATVEC),
 	     "m" (local_irq_count(0))
 );
 	for (;;);
@@ -623,11 +622,11 @@
 			continue;
 		if (i < STMFP_SOURCE_BASE)
 			seq_printf(p, "auto %2d: %10u ",
-				       i, kstat.irqs[0][i]);
+				       i, kstat_cpu(0).irqs[i]);
 		else
 			seq_printf(p, "vec $%02x: %10u ",
 				       IRQ_SOURCE_TO_VECTOR(i),
-				       kstat.irqs[0][i]);
+				       kstat_cpu(0).irqs[i]);
 
 		if (irq_handler[i].handler != atari_call_irq_list) {
 			seq_printf(p, "%s\n", irq_param[i].devname);
diff -Nru a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c
--- a/arch/m68k/atari/config.c	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/atari/config.c	Mon Nov  4 14:31:02 2002
@@ -66,6 +66,7 @@
 extern void atari_enable_irq (unsigned int);
 extern void atari_disable_irq (unsigned int);
 extern int show_atari_interrupts (struct seq_file *, void *);
+extern void atari_mksound( unsigned int count, unsigned int ticks );
 #ifdef CONFIG_HEARTBEAT
 static void atari_heartbeat( int on );
 #endif
@@ -251,7 +252,7 @@
     conswitchp	         = &dummy_con;
 #endif
     mach_max_dma_address = 0xffffff;
-#ifdef CONFIG_INPUT_M68K_BEEP
+#if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)
     mach_beep          = atari_mksound;
 #endif
 #ifdef CONFIG_HEARTBEAT
diff -Nru a/arch/m68k/atari/hades-pci.c b/arch/m68k/atari/hades-pci.c
--- a/arch/m68k/atari/hades-pci.c	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/atari/hades-pci.c	Mon Nov  4 14:31:02 2002
@@ -311,26 +311,24 @@
 			slot = PCI_SLOT(dev->devfn);	/* Determine slot number. */
 			dev->irq = irq_tab[slot];
 			if (pci_modify)
-				pcibios_write_config_byte(dev->bus->number, dev->devfn,
-							  PCI_INTERRUPT_LINE, dev->irq);
+				pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
 		}
 	}
 }
 
 /*
- * static void hades_conf_device(unsigned char bus, unsigned char device_fn)
+ * static void hades_conf_device(struct pci_dev *dev)
  *
  * Machine dependent Configure the given device.
  *
  * Parameters:
  *
- * bus		- bus number of the device.
- * device_fn	- device and function number of the device.
+ * dev		- the pci device.
  */
 
-static void __init hades_conf_device(unsigned char bus, unsigned char device_fn)
+static void __init hades_conf_device(struct pci_dev *dev)
 {
-	pcibios_write_config_byte(bus, device_fn, PCI_CACHE_LINE_SIZE, 0);
+	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0);
 }
 
 static struct pci_ops hades_pci_ops = {
diff -Nru a/arch/m68k/defconfig b/arch/m68k/defconfig
--- a/arch/m68k/defconfig	Mon Nov  4 14:31:00 2002
+++ b/arch/m68k/defconfig	Mon Nov  4 14:31:00 2002
@@ -186,7 +186,6 @@
 #
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
-CONFIG_AMIGAMOUSE=y
 CONFIG_BUSMOUSE=y
 CONFIG_AMIGA_BUILTIN_SERIAL=y
 # CONFIG_GVPIOEXT is not set
diff -Nru a/arch/m68k/fpsp040/bindec.S b/arch/m68k/fpsp040/bindec.S
--- a/arch/m68k/fpsp040/bindec.S	Mon Nov  4 14:31:01 2002
+++ b/arch/m68k/fpsp040/bindec.S	Mon Nov  4 14:31:01 2002
@@ -137,7 +137,7 @@
 
 |BINDEC    idnt    2,1 | Motorola 040 Floating Point Software Package
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 	|section	8
 
diff -Nru a/arch/m68k/fpsp040/binstr.S b/arch/m68k/fpsp040/binstr.S
--- a/arch/m68k/fpsp040/binstr.S	Mon Nov  4 14:31:01 2002
+++ b/arch/m68k/fpsp040/binstr.S	Mon Nov  4 14:31:01 2002
@@ -68,7 +68,7 @@
 
 	|section	8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 	.global	binstr
 binstr:
diff -Nru a/arch/m68k/fpsp040/bugfix.S b/arch/m68k/fpsp040/bugfix.S
--- a/arch/m68k/fpsp040/bugfix.S	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/fpsp040/bugfix.S	Mon Nov  4 14:31:02 2002
@@ -160,7 +160,7 @@
 
 	|section	8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 	|xref	fpsp_fmt_error
 
diff -Nru a/arch/m68k/fpsp040/decbin.S b/arch/m68k/fpsp040/decbin.S
--- a/arch/m68k/fpsp040/decbin.S	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/fpsp040/decbin.S	Mon Nov  4 14:31:02 2002
@@ -77,7 +77,7 @@
 
 	|section	8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 |
 |	PTENRN, PTENRM, and PTENRP are arrays of powers of 10 rounded
diff -Nru a/arch/m68k/fpsp040/do_func.S b/arch/m68k/fpsp040/do_func.S
--- a/arch/m68k/fpsp040/do_func.S	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/fpsp040/do_func.S	Mon Nov  4 14:31:02 2002
@@ -30,7 +30,7 @@
 
 	|section	8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 	|xref	t_dz2
 	|xref	t_operr
diff -Nru a/arch/m68k/fpsp040/gen_except.S b/arch/m68k/fpsp040/gen_except.S
--- a/arch/m68k/fpsp040/gen_except.S	Mon Nov  4 14:31:01 2002
+++ b/arch/m68k/fpsp040/gen_except.S	Mon Nov  4 14:31:01 2002
@@ -37,7 +37,7 @@
 
 	|section 8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 	|xref	real_trace
 	|xref	fpsp_done
diff -Nru a/arch/m68k/fpsp040/get_op.S b/arch/m68k/fpsp040/get_op.S
--- a/arch/m68k/fpsp040/get_op.S	Mon Nov  4 14:31:01 2002
+++ b/arch/m68k/fpsp040/get_op.S	Mon Nov  4 14:31:01 2002
@@ -62,7 +62,7 @@
 
 	|section	8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 	.global	PIRN,PIRZRM,PIRP
 	.global	SMALRN,SMALRZRM,SMALRP
diff -Nru a/arch/m68k/fpsp040/kernel_ex.S b/arch/m68k/fpsp040/kernel_ex.S
--- a/arch/m68k/fpsp040/kernel_ex.S	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/fpsp040/kernel_ex.S	Mon Nov  4 14:31:02 2002
@@ -20,7 +20,7 @@
 
 	|section    8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 mns_inf:  .long 0xffff0000,0x00000000,0x00000000
 pls_inf:  .long 0x7fff0000,0x00000000,0x00000000
diff -Nru a/arch/m68k/fpsp040/res_func.S b/arch/m68k/fpsp040/res_func.S
--- a/arch/m68k/fpsp040/res_func.S	Mon Nov  4 14:31:00 2002
+++ b/arch/m68k/fpsp040/res_func.S	Mon Nov  4 14:31:00 2002
@@ -24,7 +24,7 @@
 
 	|section	8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 sp_bnds:	.short	0x3f81,0x407e
 		.short	0x3f6a,0x0000
diff -Nru a/arch/m68k/fpsp040/round.S b/arch/m68k/fpsp040/round.S
--- a/arch/m68k/fpsp040/round.S	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/fpsp040/round.S	Mon Nov  4 14:31:02 2002
@@ -16,7 +16,7 @@
 
 	|section	8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 |
 |	round --- round result according to precision/mode
diff -Nru a/arch/m68k/fpsp040/satan.S b/arch/m68k/fpsp040/satan.S
--- a/arch/m68k/fpsp040/satan.S	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/fpsp040/satan.S	Mon Nov  4 14:31:02 2002
@@ -51,7 +51,7 @@
 
 	|section	8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 	
 BOUNDS1:	.long 0x3FFB8000,0x4002FFFF
 
diff -Nru a/arch/m68k/fpsp040/scale.S b/arch/m68k/fpsp040/scale.S
--- a/arch/m68k/fpsp040/scale.S	Mon Nov  4 14:31:01 2002
+++ b/arch/m68k/fpsp040/scale.S	Mon Nov  4 14:31:01 2002
@@ -29,7 +29,7 @@
 
 	|section	8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 	|xref	t_ovfl2
 	|xref	t_unfl
diff -Nru a/arch/m68k/fpsp040/setox.S b/arch/m68k/fpsp040/setox.S
--- a/arch/m68k/fpsp040/setox.S	Mon Nov  4 14:31:01 2002
+++ b/arch/m68k/fpsp040/setox.S	Mon Nov  4 14:31:01 2002
@@ -339,7 +339,7 @@
 
 	|section	8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 L2:	.long	0x3FDC0000,0x82E30865,0x4361C4C6,0x00000000
 
diff -Nru a/arch/m68k/fpsp040/sgetem.S b/arch/m68k/fpsp040/sgetem.S
--- a/arch/m68k/fpsp040/sgetem.S	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/fpsp040/sgetem.S	Mon Nov  4 14:31:02 2002
@@ -32,7 +32,7 @@
 
 	|section 8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 	|xref	nrm_set
 
diff -Nru a/arch/m68k/fpsp040/sint.S b/arch/m68k/fpsp040/sint.S
--- a/arch/m68k/fpsp040/sint.S	Mon Nov  4 14:31:03 2002
+++ b/arch/m68k/fpsp040/sint.S	Mon Nov  4 14:31:03 2002
@@ -59,7 +59,7 @@
 
 	|section	8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 	|xref	dnrm_lp
 	|xref	nrm_set
diff -Nru a/arch/m68k/fpsp040/skeleton.S b/arch/m68k/fpsp040/skeleton.S
--- a/arch/m68k/fpsp040/skeleton.S	Mon Nov  4 14:31:01 2002
+++ b/arch/m68k/fpsp040/skeleton.S	Mon Nov  4 14:31:01 2002
@@ -51,7 +51,7 @@
 
 	|section 8
  
-	.include "fpsp.h"
+#include "fpsp.h"
 
 	|xref	b1238_fix
 
diff -Nru a/arch/m68k/fpsp040/slogn.S b/arch/m68k/fpsp040/slogn.S
--- a/arch/m68k/fpsp040/slogn.S	Mon Nov  4 14:31:00 2002
+++ b/arch/m68k/fpsp040/slogn.S	Mon Nov  4 14:31:00 2002
@@ -71,7 +71,7 @@
 
 	|section	8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 BOUNDS1:  .long 0x3FFEF07D,0x3FFF8841
 BOUNDS2:  .long 0x3FFE8000,0x3FFFC000
diff -Nru a/arch/m68k/fpsp040/smovecr.S b/arch/m68k/fpsp040/smovecr.S
--- a/arch/m68k/fpsp040/smovecr.S	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/fpsp040/smovecr.S	Mon Nov  4 14:31:02 2002
@@ -23,7 +23,7 @@
 
 	|section 8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 	|xref	nrm_set
 	|xref	round
diff -Nru a/arch/m68k/fpsp040/srem_mod.S b/arch/m68k/fpsp040/srem_mod.S
--- a/arch/m68k/fpsp040/srem_mod.S	Mon Nov  4 14:31:00 2002
+++ b/arch/m68k/fpsp040/srem_mod.S	Mon Nov  4 14:31:00 2002
@@ -74,7 +74,7 @@
 
 	|section    8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 	.set	Mod_Flag,L_SCR3
 	.set	SignY,FP_SCR3+4
diff -Nru a/arch/m68k/fpsp040/ssin.S b/arch/m68k/fpsp040/ssin.S
--- a/arch/m68k/fpsp040/ssin.S	Mon Nov  4 14:31:01 2002
+++ b/arch/m68k/fpsp040/ssin.S	Mon Nov  4 14:31:01 2002
@@ -91,7 +91,7 @@
 
 	|section	8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 BOUNDS1:	.long 0x3FD78000,0x4004BC7E
 TWOBYPI:	.long 0x3FE45F30,0x6DC9C883
diff -Nru a/arch/m68k/fpsp040/stan.S b/arch/m68k/fpsp040/stan.S
--- a/arch/m68k/fpsp040/stan.S	Mon Nov  4 14:31:00 2002
+++ b/arch/m68k/fpsp040/stan.S	Mon Nov  4 14:31:00 2002
@@ -58,7 +58,7 @@
 
 	|section	8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 BOUNDS1:	.long 0x3FD78000,0x4004BC7E
 TWOBYPI:	.long 0x3FE45F30,0x6DC9C883
diff -Nru a/arch/m68k/fpsp040/stanh.S b/arch/m68k/fpsp040/stanh.S
--- a/arch/m68k/fpsp040/stanh.S	Mon Nov  4 14:31:01 2002
+++ b/arch/m68k/fpsp040/stanh.S	Mon Nov  4 14:31:01 2002
@@ -57,7 +57,7 @@
 
 	|section	8
 	
-	.include "fpsp.h"
+#include "fpsp.h"
 
 	.set	X,FP_SCR5
 	.set	XDCARE,X+2
diff -Nru a/arch/m68k/fpsp040/sto_res.S b/arch/m68k/fpsp040/sto_res.S
--- a/arch/m68k/fpsp040/sto_res.S	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/fpsp040/sto_res.S	Mon Nov  4 14:31:02 2002
@@ -28,7 +28,7 @@
 
 	|section	8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 	.global	sto_cos
 sto_cos:
diff -Nru a/arch/m68k/fpsp040/stwotox.S b/arch/m68k/fpsp040/stwotox.S
--- a/arch/m68k/fpsp040/stwotox.S	Mon Nov  4 14:31:01 2002
+++ b/arch/m68k/fpsp040/stwotox.S	Mon Nov  4 14:31:01 2002
@@ -84,7 +84,7 @@
 
 	|section	8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 BOUNDS1:	.long 0x3FB98000,0x400D80C0 | ... 2^(-70),16480
 BOUNDS2:	.long 0x3FB98000,0x400B9B07 | ... 2^(-70),16480 LOG2/LOG10
diff -Nru a/arch/m68k/fpsp040/util.S b/arch/m68k/fpsp040/util.S
--- a/arch/m68k/fpsp040/util.S	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/fpsp040/util.S	Mon Nov  4 14:31:02 2002
@@ -24,7 +24,7 @@
 
 	|section	8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 	|xref	mem_read
 
diff -Nru a/arch/m68k/fpsp040/x_bsun.S b/arch/m68k/fpsp040/x_bsun.S
--- a/arch/m68k/fpsp040/x_bsun.S	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/fpsp040/x_bsun.S	Mon Nov  4 14:31:02 2002
@@ -21,7 +21,7 @@
 
 	|section	8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 	|xref	real_bsun
 
diff -Nru a/arch/m68k/fpsp040/x_fline.S b/arch/m68k/fpsp040/x_fline.S
--- a/arch/m68k/fpsp040/x_fline.S	Mon Nov  4 14:31:00 2002
+++ b/arch/m68k/fpsp040/x_fline.S	Mon Nov  4 14:31:00 2002
@@ -21,7 +21,7 @@
 
 	|section	8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 	|xref	real_fline
 	|xref	fpsp_unimp
diff -Nru a/arch/m68k/fpsp040/x_operr.S b/arch/m68k/fpsp040/x_operr.S
--- a/arch/m68k/fpsp040/x_operr.S	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/fpsp040/x_operr.S	Mon Nov  4 14:31:02 2002
@@ -51,7 +51,7 @@
 
 	|section	8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 	|xref	mem_write
 	|xref	real_operr
diff -Nru a/arch/m68k/fpsp040/x_ovfl.S b/arch/m68k/fpsp040/x_ovfl.S
--- a/arch/m68k/fpsp040/x_ovfl.S	Mon Nov  4 14:31:01 2002
+++ b/arch/m68k/fpsp040/x_ovfl.S	Mon Nov  4 14:31:01 2002
@@ -43,7 +43,7 @@
 
 	|section	8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 	|xref	ovf_r_x2
 	|xref	ovf_r_x3
diff -Nru a/arch/m68k/fpsp040/x_snan.S b/arch/m68k/fpsp040/x_snan.S
--- a/arch/m68k/fpsp040/x_snan.S	Mon Nov  4 14:31:03 2002
+++ b/arch/m68k/fpsp040/x_snan.S	Mon Nov  4 14:31:03 2002
@@ -30,7 +30,7 @@
 
 	|section	8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 	|xref	get_fline
 	|xref	mem_write
diff -Nru a/arch/m68k/fpsp040/x_store.S b/arch/m68k/fpsp040/x_store.S
--- a/arch/m68k/fpsp040/x_store.S	Mon Nov  4 14:31:03 2002
+++ b/arch/m68k/fpsp040/x_store.S	Mon Nov  4 14:31:03 2002
@@ -22,7 +22,7 @@
 fpreg_mask:
 	.byte	0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 	|xref	mem_write
 	|xref	get_fline
diff -Nru a/arch/m68k/fpsp040/x_unfl.S b/arch/m68k/fpsp040/x_unfl.S
--- a/arch/m68k/fpsp040/x_unfl.S	Mon Nov  4 14:31:01 2002
+++ b/arch/m68k/fpsp040/x_unfl.S	Mon Nov  4 14:31:01 2002
@@ -29,7 +29,7 @@
 
 	|section	8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 	|xref	denorm
 	|xref	round
diff -Nru a/arch/m68k/fpsp040/x_unimp.S b/arch/m68k/fpsp040/x_unimp.S
--- a/arch/m68k/fpsp040/x_unimp.S	Mon Nov  4 14:31:01 2002
+++ b/arch/m68k/fpsp040/x_unimp.S	Mon Nov  4 14:31:01 2002
@@ -30,7 +30,7 @@
 
 	|section	8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 	|xref	get_op
 	|xref	do_func
diff -Nru a/arch/m68k/fpsp040/x_unsupp.S b/arch/m68k/fpsp040/x_unsupp.S
--- a/arch/m68k/fpsp040/x_unsupp.S	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/fpsp040/x_unsupp.S	Mon Nov  4 14:31:02 2002
@@ -31,7 +31,7 @@
 
 	|section	8
 
-	.include "fpsp.h"
+#include "fpsp.h"
 
 	|xref	get_op
 	|xref	res_func
diff -Nru a/arch/m68k/hp300/Makefile b/arch/m68k/hp300/Makefile
--- a/arch/m68k/hp300/Makefile	Mon Nov  4 14:31:00 2002
+++ b/arch/m68k/hp300/Makefile	Mon Nov  4 14:31:00 2002
@@ -4,6 +4,4 @@
 
 obj-y		:= ksyms.o config.o ints.o time.o reboot.o
 
-obj-$(CONFIG_VT)	+= hil.o
-
 include $(TOPDIR)/Rules.make
diff -Nru a/arch/m68k/hp300/time.c b/arch/m68k/hp300/time.c
--- a/arch/m68k/hp300/time.c	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/hp300/time.c	Mon Nov  4 14:31:02 2002
@@ -40,7 +40,7 @@
 {
   unsigned long tmp;
   void (*vector)(int, void *, struct pt_regs *) = dev_id;
-  readb(CLOCKBASE + CLKSR);
+  in_8(CLOCKBASE + CLKSR);
   asm volatile ("movpw %1@(5),%0" : "=d" (tmp) : "a" (CLOCKBASE));
   vector(irq, NULL, regs);
 }
@@ -51,25 +51,25 @@
   unsigned char lsb, msb1, msb2;
   unsigned short ticks;
 
-  msb1 = readb(CLOCKBASE + 5);
-  lsb = readb(CLOCKBASE + 7);
-  msb2 = readb(CLOCKBASE + 5);
+  msb1 = in_8(CLOCKBASE + 5);
+  lsb = in_8(CLOCKBASE + 7);
+  msb2 = in_8(CLOCKBASE + 5);
   if (msb1 != msb2)
     /* A carry happened while we were reading.  Read it again */
-    lsb = readb(CLOCKBASE + 7);
+    lsb = in_8(CLOCKBASE + 7);
   ticks = INTVAL - ((msb2 << 8) | lsb);
   return (USECS_PER_JIFFY * ticks) / INTVAL;
 }
 
 void __init hp300_sched_init(void (*vector)(int, void *, struct pt_regs *))
 {
-  writeb(0x1, CLOCKBASE + CLKCR2);		/* select CR1 */
-  writeb(0x1, CLOCKBASE + CLKCR1);		/* reset */
+  out_8(CLOCKBASE + CLKCR2, 0x1);		/* select CR1 */
+  out_8(CLOCKBASE + CLKCR1, 0x1);		/* reset */
 
   asm volatile(" movpw %0,%1@(5)" : : "d" (INTVAL), "a" (CLOCKBASE));
 
   sys_request_irq(6, hp300_tick, IRQ_FLG_STD, "timer tick", vector);
 
-  writeb(0x1, CLOCKBASE + CLKCR2);		/* select CR1 */
-  writeb(0x40, CLOCKBASE + CLKCR1);		/* enable irq */
+  out_8(CLOCKBASE + CLKCR2, 0x1);		/* select CR1 */
+  out_8(CLOCKBASE + CLKCR1, 0x40);		/* enable irq */
 }
diff -Nru a/arch/m68k/ifpsp060/fskeleton.S b/arch/m68k/ifpsp060/fskeleton.S
--- a/arch/m68k/ifpsp060/fskeleton.S	Mon Nov  4 14:31:01 2002
+++ b/arch/m68k/ifpsp060/fskeleton.S	Mon Nov  4 14:31:01 2002
@@ -340,4 +340,4 @@
 
 | 060 FPSP KERNEL PACKAGE NEEDS TO GO HERE!!!
 
-	.include "fpsp.sa"
+#include "fpsp.sa"
diff -Nru a/arch/m68k/ifpsp060/iskeleton.S b/arch/m68k/ifpsp060/iskeleton.S
--- a/arch/m68k/ifpsp060/iskeleton.S	Mon Nov  4 14:31:00 2002
+++ b/arch/m68k/ifpsp060/iskeleton.S	Mon Nov  4 14:31:00 2002
@@ -304,4 +304,4 @@
 |###########################################################################
 
 | 060 INTEGER KERNEL PACKAGE MUST GO HERE!!!
-	.include "isp.sa"
+#include "isp.sa"
diff -Nru a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile
--- a/arch/m68k/kernel/Makefile	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/kernel/Makefile	Mon Nov  4 14:31:02 2002
@@ -19,18 +19,19 @@
 
 include $(TOPDIR)/Rules.make
 
-head.o: head.S m68k_defs.h
+$(obj)/head.o: $(obj)/head.S $(obj)/m68k_defs.h
 
-entry.o: entry.S m68k_defs.h
+$(obj)/entry.o: $(obj)/entry.S $(obj)/m68k_defs.h
 
-sun3-head.o: sun3-head.S m68k_defs.h
+$(obj)/sun3-head.o: $(obj)/sun3-head.S $(obj)/m68k_defs.h
 
-m68k_defs.h: m68k_defs.c m68k_defs.head
-	rm -f m68k_defs.d
-	SUNPRO_DEPENDENCIES="m68k_defs.d m68k_defs.h" \
-	$(CC) $(filter-out -MD,$(CFLAGS)) -S m68k_defs.c
-	cp m68k_defs.head m68k_defs.h
-	grep '^#define' m68k_defs.s >> m68k_defs.h
-	rm m68k_defs.s
--include m68k_defs.d
+$(obj)/m68k_defs.h: $(src)/m68k_defs.c $(src)/m68k_defs.head
+	rm -f $(obj)/m68k_defs.d
+	SUNPRO_DEPENDENCIES="$(obj)/m68k_defs.d $(obj)/m68k_defs.h" \
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S $(src)/m68k_defs.c -o \
+	$(obj)/m68k_defs.s
+	cp $(src)/m68k_defs.head $(obj)/m68k_defs.h
+	grep '^#define' $(obj)/m68k_defs.s >> $(obj)/m68k_defs.h
+	rm $(obj)/m68k_defs.s
+-include $(obj)/m68k_defs.d
 
diff -Nru a/arch/m68k/kernel/bios32.c b/arch/m68k/kernel/bios32.c
--- a/arch/m68k/kernel/bios32.c	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/kernel/bios32.c	Mon Nov  4 14:31:02 2002
@@ -95,7 +95,6 @@
 
 static void __init disable_dev(struct pci_dev *dev)
 {
-	struct pci_bus *bus;
 	unsigned short cmd;
 
 	if (((dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA) ||
@@ -103,11 +102,10 @@
 	     (dev->class >> 8 == PCI_CLASS_DISPLAY_XGA)) && skip_vga)
 		return;
 
-	bus = dev->bus;
-	pcibios_read_config_word(bus->number, dev->devfn, PCI_COMMAND, &cmd);
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
 
 	cmd &= (~PCI_COMMAND_IO & ~PCI_COMMAND_MEMORY & ~PCI_COMMAND_MASTER);
-	pcibios_write_config_word(bus->number, dev->devfn, PCI_COMMAND, cmd);
+	pci_write_config_word(dev, PCI_COMMAND, cmd);
 }
 
 /*
@@ -122,7 +120,6 @@
 
 static void __init layout_dev(struct pci_dev *dev)
 {
-	struct pci_bus *bus;
 	unsigned short cmd;
 	unsigned int base, mask, size, reg;
 	unsigned int alignto;
@@ -137,8 +134,7 @@
 	     (dev->class >> 8 == PCI_CLASS_DISPLAY_XGA)) && skip_vga)
 		return;
 
-	bus = dev->bus;
-	pcibios_read_config_word(bus->number, dev->devfn, PCI_COMMAND, &cmd);
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
 
 	for (reg = PCI_BASE_ADDRESS_0, i = 0; reg <= PCI_BASE_ADDRESS_5; reg += 4, i++)
 	{
@@ -147,9 +143,8 @@
 		 * device wants.
 		 */
 
-		pcibios_write_config_dword(bus->number, dev->devfn, reg,
-					   0xffffffff);
-		pcibios_read_config_dword(bus->number, dev->devfn, reg, &base);
+		pci_write_config_dword(dev, reg, 0xffffffff);
+		pci_read_config_dword(dev, reg, &base);
 
 		if (!base)
 		{
@@ -184,8 +179,7 @@
 			alignto = MAX(0x040, size) ;
 			base = ALIGN(io_base, alignto);
 			io_base = base + size;
-			pcibios_write_config_dword(bus->number, dev->devfn,
-						   reg, base | PCI_BASE_ADDRESS_SPACE_IO);
+			pci_write_config_dword(dev, reg, base | PCI_BASE_ADDRESS_SPACE_IO);
 
 			dev->resource[i].start = base;
 			dev->resource[i].end = dev->resource[i].start + size - 1;
@@ -228,8 +222,7 @@
 			alignto = MAX(0x1000, size) ;
 			base = ALIGN(mem_base, alignto);
 			mem_base = base + size;
-			pcibios_write_config_dword(bus->number, dev->devfn,
-						   reg, base);
+			pci_write_config_dword(dev, reg, base);
 
 			dev->resource[i].start = base;
 			dev->resource[i].end = dev->resource[i].start + size - 1;
@@ -243,8 +236,7 @@
 				 */
 
 				reg += 4;
-				pcibios_write_config_dword(bus->number, dev->devfn,
-							   reg, 0);
+				pci_write_config_dword(dev, reg, 0);
 
 				i++;
 				dev->resource[i].start = 0;
@@ -272,17 +264,15 @@
 		cmd |= PCI_COMMAND_IO;
 	}
 
-	pcibios_write_config_word(bus->number, dev->devfn, PCI_COMMAND,
-				  cmd | PCI_COMMAND_MASTER);
+	pci_write_config_word(dev, PCI_COMMAND, cmd | PCI_COMMAND_MASTER);
 
-	pcibios_write_config_byte(bus->number, dev->devfn, PCI_LATENCY_TIMER,
-				  (disable_pci_burst) ? 0 : 32);
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, (disable_pci_burst) ? 0 : 32);
 
 	if (bus_info != NULL)
-		bus_info->conf_device(bus->number, dev->devfn);	/* Machine dependent configuration. */
+		bus_info->conf_device(dev);	/* Machine dependent configuration. */
 
 	DBG_DEVS(("layout_dev: bus %d  slot 0x%x  VID 0x%x  DID 0x%x  class 0x%x\n",
-		  bus->number, PCI_SLOT(dev->devfn), dev->vendor, dev->device, dev->class));
+		  dev->bus->number, PCI_SLOT(dev->devfn), dev->vendor, dev->device, dev->class));
 }
 
 /*
diff -Nru a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
--- a/arch/m68k/kernel/entry.S	Mon Nov  4 14:31:00 2002
+++ b/arch/m68k/kernel/entry.S	Mon Nov  4 14:31:00 2002
@@ -222,7 +222,7 @@
 inthandler:
 	SAVE_ALL_INT
 	GET_CURRENT(%d0)
-	addql	#1,irq_stat+CPUSTAT_LOCAL_IRQ_COUNT
+	addqb	#1,%curptr@(TASK_INFO+TINFO_PREEMPT+2)
 					|  put exception # in d0
 	bfextu %sp@(PT_VECTOR){#4,#10},%d0
 
@@ -241,18 +241,15 @@
 3:     	addql	#8,%sp			|  pop parameters off stack
 
 ret_from_interrupt:
-	subql	#1,irq_stat+CPUSTAT_LOCAL_IRQ_COUNT
+	subqb	#1,%curptr@(TASK_INFO+TINFO_PREEMPT+2)
 	jeq	1f
 2:
 	RESTORE_ALL
 1:
-#if 1
-	bfextu  %sp@(PT_SR){#5,#3},%d0	| Check for nested interrupt.
-#if MAX_NOINT_IPL > 0
-	cmpiw	#MAX_NOINT_IPL,%d0
-#endif
-	jhi	2b
-#endif
+	moveq	#(~ALLOWINT>>8)&0xff,%d0
+	andb	%sp@(PT_SR),%d0
+	jne	2b
+
 	/* check if we need to do software interrupts */
 	tstl	irq_stat+CPUSTAT_SOFTIRQ_PENDING
 	jeq	ret_from_exception
diff -Nru a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c
--- a/arch/m68k/kernel/ints.c	Mon Nov  4 14:31:01 2002
+++ b/arch/m68k/kernel/ints.c	Mon Nov  4 14:31:01 2002
@@ -231,7 +231,7 @@
 {
 	if (vec >= VEC_INT1 && vec <= VEC_INT7 && !MACH_IS_BVME6000) {
 		vec -= VEC_SPUR;
-		kstat.irqs[0][vec]++;
+		kstat_cpu(0).irqs[vec]++;
 		irq_list[vec].handler(vec, irq_list[vec].dev_id, fp);
 	} else {
 		if (mach_process_int)
@@ -250,7 +250,7 @@
 	if (mach_default_handler) {
 		for (i = 0; i < SYS_IRQS; i++) {
 			seq_printf(p, "auto %2d: %10u ", i,
-			               i ? kstat.irqs[0][i] : num_spurious);
+			               i ? kstat_cpu(0).irqs[i] : num_spurious);
 			seq_puts(p, "  ");
 			seq_printf(p, "%s\n", irq_list[i].devname);
 		}
diff -Nru a/arch/m68k/kernel/m68k_defs.c b/arch/m68k/kernel/m68k_defs.c
--- a/arch/m68k/kernel/m68k_defs.c	Mon Nov  4 14:31:00 2002
+++ b/arch/m68k/kernel/m68k_defs.c	Mon Nov  4 14:31:00 2002
@@ -71,8 +71,6 @@
 
 	/* offsets into the irq_cpustat_t struct */
 	DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
-	DEFINE(CPUSTAT_LOCAL_IRQ_COUNT, offsetof(irq_cpustat_t, __local_irq_count));
-	DEFINE(CPUSTAT_LOCAL_BH_COUNT, offsetof(irq_cpustat_t, __local_bh_count));
 	DEFINE(CPUSTAT_SYSCALL_COUNT, offsetof(irq_cpustat_t, __syscall_count));
 
 	/* offsets into the bi_record struct */
diff -Nru a/arch/m68k/kernel/m68k_ksyms.c b/arch/m68k/kernel/m68k_ksyms.c
--- a/arch/m68k/kernel/m68k_ksyms.c	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/kernel/m68k_ksyms.c	Mon Nov  4 14:31:02 2002
@@ -42,13 +42,15 @@
 EXPORT_SYMBOL(mm_vtop);
 EXPORT_SYMBOL(mm_ptov);
 EXPORT_SYMBOL(mm_end_of_chunk);
+#else
+EXPORT_SYMBOL(m68k_memoffset);
 #endif /* !CONFIG_SINGLE_MEMORY_CHUNK */
-EXPORT_SYMBOL(mm_vtop_fallback);
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(iounmap);
 EXPORT_SYMBOL(kernel_set_cachemode);
 #endif /* !CONFIG_SUN3 */
 EXPORT_SYMBOL(m68k_debug_device);
+EXPORT_SYMBOL(mach_hwclk);
 EXPORT_SYMBOL(dump_fpu);
 EXPORT_SYMBOL(dump_thread);
 EXPORT_SYMBOL(strnlen);
diff -Nru a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
--- a/arch/m68k/kernel/process.c	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/kernel/process.c	Mon Nov  4 14:31:02 2002
@@ -41,7 +41,7 @@
  */
 static struct fs_struct init_fs = INIT_FS;
 static struct files_struct init_files = INIT_FILES;
-static struct signal_struct init_signals = INIT_SIGNALS;
+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
 struct mm_struct init_mm = INIT_MM(init_mm);
 
 union thread_union init_thread_union
@@ -152,7 +152,7 @@
 
 	{
 	register long retval __asm__ ("d0");
-	register long clone_arg __asm__ ("d1") = flags | CLONE_VM;
+	register long clone_arg __asm__ ("d1") = flags | CLONE_VM | CLONE_UNTRACED;
 
 	retval = __NR_clone;
 	__asm__ __volatile__
@@ -202,14 +202,14 @@
 asmlinkage int m68k_fork(struct pt_regs *regs)
 {
 	struct task_struct *p;
-	p = do_fork(SIGCHLD, rdusp(), regs, 0);
+	p = do_fork(SIGCHLD, rdusp(), regs, 0, NULL);
 	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
 asmlinkage int m68k_vfork(struct pt_regs *regs)
 {
 	struct task_struct *p;
-	p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0);
+	p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL);
 	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
@@ -218,13 +218,15 @@
 	unsigned long clone_flags;
 	unsigned long newsp;
 	struct task_struct *p;
+	int *user_tid;
 
 	/* syscall2 puts clone_flags in d1 and usp in d2 */
 	clone_flags = regs->d1;
 	newsp = regs->d2;
+	user_tid = (int *)regs->d3;
 	if (!newsp)
 		newsp = rdusp();
-	p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, regs, 0);
+	p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, regs, 0, user_tid);
 	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
diff -Nru a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
--- a/arch/m68k/kernel/ptrace.c	Mon Nov  4 14:31:01 2002
+++ b/arch/m68k/kernel/ptrace.c	Mon Nov  4 14:31:01 2002
@@ -355,7 +355,7 @@
 		}
 
 		default:
-			ret = -EIO;
+			ret = ptrace_request(child, request, addr, data);
 			break;
 	}
 out_tsk:
@@ -370,7 +370,8 @@
 	if (!current->thread.work.delayed_trace &&
 	    !current->thread.work.syscall_trace)
 		return;
-	current->exit_code = SIGTRAP;
+	current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+					? 0x80 : 0);
 	current->state = TASK_STOPPED;
 	notify_parent(current, SIGCHLD);
 	schedule();
diff -Nru a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c
--- a/arch/m68k/kernel/setup.c	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/kernel/setup.c	Mon Nov  4 14:31:02 2002
@@ -98,7 +98,7 @@
 #ifdef CONFIG_M68K_L2_CACHE
 void (*mach_l2_flush) (int) = NULL;
 #endif
-#ifdef CONFIG_INPUT_M68K_BEEP
+#if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)
 void (*mach_beep)(unsigned int, unsigned int) = NULL;
 #endif
 #if defined(CONFIG_ISA) && defined(MULTI_ISA)
@@ -536,11 +536,6 @@
 }
 
 #endif
-
-/* for "kbd-reset" cmdline param */
-void __init kbd_reset_setup(char *str, int *ints)
-{
-}
 
 void check_bugs(void)
 {
diff -Nru a/arch/m68k/kernel/sun3-head.S b/arch/m68k/kernel/sun3-head.S
--- a/arch/m68k/kernel/sun3-head.S	Mon Nov  4 14:31:00 2002
+++ b/arch/m68k/kernel/sun3-head.S	Mon Nov  4 14:31:00 2002
@@ -16,9 +16,6 @@
 .globl bootup_user_stack
 .globl bootup_kernel_stack
 .globl pg0
-.globl empty_bad_page
-.globl empty_bad_page_table
-.globl empty_zero_page
 .globl swapper_pg_dir
 .globl kernel_pmd_table
 .globl availmem
@@ -27,10 +24,7 @@
 | todo: all these should be in bss!
 swapper_pg_dir:                .skip 0x2000
 pg0:                           .skip 0x2000
-empty_bad_page:                .skip 0x2000
-empty_bad_page_table:          .skip 0x2000
 kernel_pmd_table:              .skip 0x2000
-empty_zero_page:               .skip 0x2000
 
 .globl kernel_pg_dir
 .equ    kernel_pg_dir,kernel_pmd_table
diff -Nru a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c
--- a/arch/m68k/kernel/time.c	Mon Nov  4 14:31:01 2002
+++ b/arch/m68k/kernel/time.c	Mon Nov  4 14:31:01 2002
@@ -23,6 +23,7 @@
 #include <asm/io.h>
 
 #include <linux/timex.h>
+#include <linux/profile.h>
 
 u64 jiffies_64;
 
@@ -70,15 +71,22 @@
 	 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
 	 * called as close as possible to 500 ms before the new second starts.
 	 */
+	/*
+	 * This code hopefully becomes obsolete in 2.5 or earlier
+	 * Should it ever be reenabled it must be serialized with
+	 * genrtc.c operation
+	 */
+#if 0
 	if ((time_status & STA_UNSYNC) == 0 &&
 	    xtime.tv_sec > last_rtc_update + 660 &&
-	    xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
-	    xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
+	    (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) tick) / 2 &&
+	    (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) tick) / 2) {
 	  if (set_rtc_mmss(xtime.tv_sec) == 0)
 	    last_rtc_update = xtime.tv_sec;
 	  else
 	    last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
 	}
+#endif
 #ifdef CONFIG_HEARTBEAT
 	/* use power LED as a heartbeat instead -- much more useful
 	   for debugging -- based on the version for PReP by Cort */
@@ -115,7 +123,7 @@
 			time.tm_year += 100;
 		xtime.tv_sec = mktime(time.tm_year, time.tm_mon, time.tm_mday,
 				      time.tm_hour, time.tm_min, time.tm_sec);
-		xtime.tv_usec = 0;
+		xtime.tv_nsec = 0;
 	}
 
 	mach_sched_init(timer_interrupt);
@@ -138,7 +146,7 @@
 	if (lost)
 		usec += lost * (1000000/HZ);
 	sec = xtime.tv_sec;
-	usec += xtime.tv_usec;
+	usec += xtime.tv_nsec/1000;
 	read_unlock_irqrestore(&xtime_lock, flags);
 
 	while (usec >= 1000000) {
@@ -152,21 +160,25 @@
 
 void do_settimeofday(struct timeval *tv)
 {
+	extern unsigned long wall_jiffies;
+
 	write_lock_irq(&xtime_lock);
-	/* This is revolting. We need to set the xtime.tv_usec
+	/* This is revolting. We need to set the xtime.tv_nsec
 	 * correctly. However, the value in this location is
 	 * is value at the last tick.
 	 * Discover what correction gettimeofday
 	 * would have done, and then undo it!
 	 */
 	tv->tv_usec -= mach_gettimeoffset();
+	tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ);
 
 	while (tv->tv_usec < 0) {
 		tv->tv_usec += 1000000;
 		tv->tv_sec--;
 	}
 
-	xtime = *tv;
+	xtime.tv_sec = tv->tv_sec;
+	xtime.tv_nsec = tv->tv_usec * 1000;
 	time_adjust = 0;		/* stop active adjtime() */
 	time_status |= STA_UNSYNC;
 	time_maxerror = NTP_PHASE_LIMIT;
diff -Nru a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c
--- a/arch/m68k/kernel/traps.c	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/kernel/traps.c	Mon Nov  4 14:31:02 2002
@@ -881,9 +881,10 @@
 	show_trace((unsigned long *)tsk->thread.esp0);
 }
 
-static void dump_stack(struct frame *fp)
+void show_registers(struct pt_regs *regs)
 {
-	unsigned long *stack, *endstack, addr;
+	struct frame *fp = (struct frame *)regs;
+	unsigned long addr;
 	int i;
 
 	addr = (unsigned long)&fp->un;
@@ -938,9 +939,22 @@
 	default:
 	    printk("\n");
 	}
+	show_stack((unsigned long *)addr);
 
-	stack = (unsigned long *)addr;
-	endstack = (unsigned long *)((addr + THREAD_SIZE - 1) & -THREAD_SIZE);
+	printk("Code: ");
+	for (i = 0; i < 10; i++)
+		printk("%04x ", 0xffff & ((short *) fp->ptregs.pc)[i]);
+	printk ("\n");
+}
+
+extern void show_stack(unsigned long *stack)
+{
+	unsigned long *endstack;
+	int i;
+
+	if (!stack)
+		stack = (unsigned long *)&stack;
+	endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1) & -THREAD_SIZE);
 
 	printk("Stack from %08lx:", (unsigned long)stack);
 	for (i = 0; i < kstack_depth_to_print; i++) {
@@ -951,12 +965,17 @@
 		printk(" %08lx", *stack++);
 	}
 	printk("\n");
-	show_trace((unsigned long *)addr);
+	show_trace(stack);
+}
 
-	printk("Code: ");
-	for (i = 0; i < 10; i++)
-		printk("%04x ", 0xffff & ((short *) fp->ptregs.pc)[i]);
-	printk ("\n");
+/*
+ * The architecture-independent backtrace generator
+ */
+void dump_stack(void)
+{
+	unsigned long stack;
+
+	show_trace(&stack);
 }
 
 void bad_super_trap (struct frame *fp)
@@ -1129,7 +1148,7 @@
 
 	printk("Process %s (pid: %d, stackpage=%08lx)\n",
 		current->comm, current->pid, PAGE_SIZE+(unsigned long)current);
-	dump_stack((struct frame *)fp);
+	show_stack((unsigned long *)fp);
 	do_exit(SIGSEGV);
 }
 
diff -Nru a/arch/m68k/lib/checksum.c b/arch/m68k/lib/checksum.c
--- a/arch/m68k/lib/checksum.c	Mon Nov  4 14:31:03 2002
+++ b/arch/m68k/lib/checksum.c	Mon Nov  4 14:31:03 2002
@@ -318,3 +318,103 @@
 
 	return(sum);
 }
+
+/*
+ * copy from kernel space while checksumming, otherwise like csum_partial
+ */
+
+unsigned int
+csum_partial_copy_nocheck(const char *src, char *dst, int len, int sum)
+{
+	unsigned long tmp1, tmp2;
+	__asm__("movel %2,%4\n\t"
+		"btst #1,%4\n\t"	/* Check alignment */
+		"jeq 2f\n\t"
+		"subql #2,%1\n\t"	/* buff%4==2: treat first word */
+		"jgt 1f\n\t"
+		"addql #2,%1\n\t"	/* len was == 2, treat only rest */
+		"jra 4f\n"
+	     "1:\t"
+		"movew %2@+,%4\n\t"	/* add first word to sum */
+		"addw %4,%0\n\t"
+		"movew %4,%3@+\n\t"
+		"clrl %4\n\t"
+		"addxl %4,%0\n"		/* add X bit */
+	     "2:\t"
+		/* unrolled loop for the main part: do 8 longs at once */
+		"movel %1,%4\n\t"	/* save len in tmp1 */
+		"lsrl #5,%1\n\t"	/* len/32 */
+		"jeq 2f\n\t"		/* not enough... */
+		"subql #1,%1\n"
+	     "1:\t"
+		"movel %2@+,%5\n\t"
+		"addxl %5,%0\n\t"
+		"movel %5,%3@+\n\t"
+		"movel %2@+,%5\n\t"
+		"addxl %5,%0\n\t"
+		"movel %5,%3@+\n\t"
+		"movel %2@+,%5\n\t"
+		"addxl %5,%0\n\t"
+		"movel %5,%3@+\n\t"
+		"movel %2@+,%5\n\t"
+		"addxl %5,%0\n\t"
+		"movel %5,%3@+\n\t"
+		"movel %2@+,%5\n\t"
+		"addxl %5,%0\n\t"
+		"movel %5,%3@+\n\t"
+		"movel %2@+,%5\n\t"
+		"addxl %5,%0\n\t"
+		"movel %5,%3@+\n\t"
+		"movel %2@+,%5\n\t"
+		"addxl %5,%0\n\t"
+		"movel %5,%3@+\n\t"
+		"movel %2@+,%5\n\t"
+		"addxl %5,%0\n\t"
+		"movel %5,%3@+\n\t"
+		"dbra %1,1b\n\t"
+		"clrl %5\n\t"
+		"addxl %5,%0\n\t"	/* add X bit */
+		"clrw %1\n\t"
+		"subql #1,%1\n\t"
+		"jcc 1b\n"
+	     "2:\t"
+		"movel %4,%1\n\t"	/* restore len from tmp1 */
+		"andw #0x1c,%4\n\t"	/* number of rest longs */
+		"jeq 4f\n\t"
+		"lsrw #2,%4\n\t"
+		"subqw #1,%4\n"
+	     "3:\t"
+		/* loop for rest longs */
+		"movel %2@+,%5\n\t"
+		"addxl %5,%0\n\t"
+		"movel %5,%3@+\n\t"
+		"dbra %4,3b\n\t"
+		"clrl %5\n\t"
+		"addxl %5,%0\n"		/* add X bit */
+	     "4:\t"
+		/* now check for rest bytes that do not fit into longs */
+		"andw #3,%1\n\t"
+		"jeq 7f\n\t"
+		"clrl %5\n\t"		/* clear tmp2 for rest bytes */
+		"subqw #2,%1\n\t"
+		"jlt 5f\n\t"
+		"movew %2@+,%5\n\t"	/* have rest >= 2: get word */
+		"movew %5,%3@+\n\t"
+		"swap %5\n\t"		/* into bits 16..31 */
+		"tstw %1\n\t"		/* another byte? */
+		"jeq 6f\n"
+	     "5:\t"
+		"moveb %2@,%5\n\t"	/* have odd rest: get byte */
+		"moveb %5,%3@+\n\t"
+		"lslw #8,%5\n"		/* into bits 8..15; 16..31 untouched */
+	     "6:\t"
+		"addl %5,%0\n\t"	/* now add rest long to sum */
+		"clrl %5\n\t"
+		"addxl %5,%0\n"		/* add X bit */
+	     "7:\t"
+		: "=d" (sum), "=d" (len), "=a" (src), "=a" (dst),
+		  "=&d" (tmp1), "=&d" (tmp2)
+		: "0" (sum), "1" (len), "2" (src), "3" (dst)
+	    );
+    return(sum);
+}
diff -Nru a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
--- a/arch/m68k/mac/config.c	Mon Nov  4 14:31:01 2002
+++ b/arch/m68k/mac/config.c	Mon Nov  4 14:31:01 2002
@@ -78,6 +78,8 @@
 extern void psc_init(void);
 extern void baboon_init(void);
 
+extern void mac_mksound(unsigned int, unsigned int);
+
 extern void nubus_sweep_video(void);
 
 /* Mac specific debug functions (in debug.c) */
@@ -217,7 +219,7 @@
 #if 0
 	mach_debug_init	 = mac_debug_init;
 #endif
-#ifdef CONFIG_INPUT_M68K_BEEP
+#if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)
         mach_beep            = mac_mksound;
 #endif
 #ifdef CONFIG_HEARTBEAT
diff -Nru a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c
--- a/arch/m68k/mac/macints.c	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/mac/macints.c	Mon Nov  4 14:31:02 2002
@@ -251,7 +251,7 @@
 #endif /* SHUTUP_SONIC */
 
 	/* 
-	 * Now register the handlers for the the master IRQ handlers
+	 * Now register the handlers for the master IRQ handlers
 	 * at levels 1-7. Most of the work is done elsewhere.
 	 */
 
@@ -345,7 +345,7 @@
 	irq_node_t *node, *slow_nodes;
 	unsigned long cpu_flags;
 
-	kstat.irqs[0][irq]++;
+	kstat_cpu(0).irqs[irq]++;
 
 #ifdef DEBUG_SPURIOUS
 	if (!mac_irq_list[irq] && (console_loglevel > 7)) {
@@ -620,7 +620,7 @@
 			case 8: base = "bbn";
 				break;
 		}
-		seq_printf(p, "%4s %2d: %10u ", base, i, kstat.irqs[0][i]);
+		seq_printf(p, "%4s %2d: %10u ", base, i, kstat_cpu(0).irqs[i]);
 
 		do {
 			if (node->flags & IRQ_FLG_FAST) {
diff -Nru a/arch/m68k/mm/Makefile b/arch/m68k/mm/Makefile
--- a/arch/m68k/mm/Makefile	Mon Nov  4 14:31:01 2002
+++ b/arch/m68k/mm/Makefile	Mon Nov  4 14:31:01 2002
@@ -7,7 +7,7 @@
 ifndef CONFIG_SUN3
 obj-y		+= kmap.o memory.o motorola.o
 else
-obj-y		+= sun3mmu.o
+obj-y		+= sun3kmap.o sun3mmu.o
 endif
 
 
diff -Nru a/arch/m68k/mm/memory.c b/arch/m68k/mm/memory.c
--- a/arch/m68k/mm/memory.c	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/mm/memory.c	Mon Nov  4 14:31:02 2002
@@ -133,34 +133,6 @@
 	return 0;
 }
 
-static unsigned long transp_transl_matches( unsigned long regval,
-					    unsigned long vaddr )
-{
-    unsigned long base, mask;
-
-    /* enabled? */
-    if (!(regval & 0x8000))
-	return( 0 );
-
-    if (CPU_IS_030) {
-	/* function code match? */
-	base = (regval >> 4) & 7;
-	mask = ~(regval & 7);
-	if (((SUPER_DATA ^ base) & mask) != 0)
-	    return 0;
-    }
-    else {
-	/* must not be user-only */
-	if ((regval & 0x6000) == 0)
-	    return( 0 );
-    }
-
-    /* address match? */
-    base = regval & 0xff000000;
-    mask = ~(regval << 8) & 0xff000000;
-    return (((unsigned long)vaddr ^ base) & mask) == 0;
-}
-
 #if DEBUG_INVALID_PTOV
 int mm_inv_cnt = 5;
 #endif
@@ -190,134 +162,9 @@
 	if (voff == 0)
 		return m68k_memory[i-1].addr + m68k_memory[i-1].size;
 
-	return mm_vtop_fallback(vaddr);
-}
-#endif
-
-/* Separate function to make the common case faster (needs to save less
-   registers) */
-unsigned long mm_vtop_fallback(unsigned long vaddr)
-{
-	/* not in one of the memory chunks; test for applying transparent
-	 * translation */
-
-	if (CPU_IS_030) {
-	    unsigned long ttreg;
-	    
-	    asm volatile( ".chip 68030\n\t"
-			  "pmove %/tt0,%0@\n\t"
-			  ".chip 68k"
-			  : : "a" (&ttreg) );
-	    if (transp_transl_matches( ttreg, vaddr ))
-		return (unsigned long)vaddr;
-	    asm volatile( ".chip 68030\n\t"
-			  "pmove %/tt1,%0@\n\t"
-			  ".chip 68k"
-			  : : "a" (&ttreg) );
-	    if (transp_transl_matches( ttreg, vaddr ))
-		return (unsigned long)vaddr;
-	}
-	else if (CPU_IS_040_OR_060) {
-	    unsigned long ttreg;
-	    
-	    asm volatile( ".chip 68040\n\t"
-			  "movec %%dtt0,%0\n\t"
-			  ".chip 68k"
-			  : "=d" (ttreg) );
-	    if (transp_transl_matches( ttreg, vaddr ))
-		return (unsigned long)vaddr;
-	    asm volatile( ".chip 68040\n\t"
-			  "movec %%dtt1,%0\n\t"
-			  ".chip 68k"
-			  : "=d" (ttreg) );
-	    if (transp_transl_matches( ttreg, vaddr ))
-		return (unsigned long)vaddr;
-	}
-
-	/* no match, too, so get the actual physical address from the MMU. */
-
-	if (CPU_IS_060) {
-	  mm_segment_t fs = get_fs();
-	  unsigned long  paddr;
-
-	  set_fs (MAKE_MM_SEG(SUPER_DATA));
-
-	  /* The PLPAR instruction causes an access error if the translation
-	   * is not possible. To catch this we use the same exception mechanism
-	   * as for user space accesses in <asm/uaccess.h>. */
-	  asm volatile (".chip 68060\n"
-			"1: plpar (%0)\n"
-			".chip 68k\n"
-			"2:\n"
-			".section .fixup,\"ax\"\n"
-			"   .even\n"
-			"3: lea -1,%0\n"
-			"   jra 2b\n"
-			".previous\n"
-			".section __ex_table,\"a\"\n"
-			"   .align 4\n"
-			"   .long 1b,3b\n"
-			".previous"
-			: "=a" (paddr)
-			: "0" (vaddr));
-	  set_fs (fs);
-
-	  return paddr;
-
-	} else if (CPU_IS_040) {
-	  unsigned long mmusr;
-	  mm_segment_t fs = get_fs();
-
-	  set_fs (MAKE_MM_SEG(SUPER_DATA));
-
-	  asm volatile (".chip 68040\n\t"
-			"ptestr (%1)\n\t"
-			"movec %%mmusr, %0\n\t"
-			".chip 68k"
-			: "=r" (mmusr)
-			: "a" (vaddr));
-	  set_fs (fs);
-
-	  if (mmusr & MMU_T_040) {
-	    return (unsigned long)vaddr;	/* Transparent translation */
-	  }
-	  if (mmusr & MMU_R_040)
-	    return (mmusr & PAGE_MASK) | ((unsigned long)vaddr & (PAGE_SIZE-1));
-
-	  printk("VTOP040: bad virtual address %lx (%lx)", vaddr, mmusr);
-	  return -1;
-	} else {
-	  volatile unsigned short temp;
-	  unsigned short mmusr;
-	  unsigned long *descaddr;
-
-	  asm volatile ("ptestr #5,%2@,#7,%0\n\t"
-			"pmove %/psr,%1@"
-			: "=a&" (descaddr)
-			: "a" (&temp), "a" (vaddr));
-	  mmusr = temp;
-
-	  if (mmusr & (MMU_I|MMU_B|MMU_L))
-	    printk("VTOP030: bad virtual address %lx (%x)\n", vaddr, mmusr);
-
-	  descaddr = phys_to_virt((unsigned long)descaddr);
-
-	  switch (mmusr & MMU_NUM) {
-	  case 1:
-	    return (*descaddr & 0xfe000000) | ((unsigned long)vaddr & 0x01ffffff);
-	  case 2:
-	    return (*descaddr & 0xfffc0000) | ((unsigned long)vaddr & 0x0003ffff);
-	  case 3:
-	    return (*descaddr & PAGE_MASK) | ((unsigned long)vaddr & (PAGE_SIZE-1));
-	  default:
-	    printk("VTOP: bad levels (%u) for virtual address %lx\n", 
-		   mmusr & MMU_NUM, vaddr);
-	  }
-	}
-
-	printk("VTOP: bad virtual address %lx\n", vaddr);
 	return -1;
 }
+#endif
 
 #ifndef CONFIG_SINGLE_MEMORY_CHUNK
 unsigned long mm_ptov (unsigned long paddr)
@@ -343,74 +190,56 @@
 			paddr, __builtin_return_address(0));
 	}
 #endif
-	/*
-	 * assume that the kernel virtual address is the same as the
-	 * physical address.
-	 *
-	 * This should be reasonable in most situations:
-	 *  1) They shouldn't be dereferencing the virtual address
-	 *     unless they are sure that it is valid from kernel space.
-	 *  2) The only usage I see so far is converting a page table
-	 *     reference to some non-FASTMEM address space when freeing
-         *     mmaped "/dev/mem" pages.  These addresses are just passed
-	 *     to "free_page", which ignores addresses that aren't in
-	 *     the memory list anyway.
-	 *
-	 */
-
-#ifdef CONFIG_AMIGA
-	/*
-	 * if on an amiga and address is in first 16M, move it 
-	 * to the ZTWO_VADDR range
-	 */
-	if (MACH_IS_AMIGA && paddr < 16*1024*1024)
-		return ZTWO_VADDR(paddr);
-#endif
 	return -1;
 }
 #endif
 
 /* invalidate page in both caches */
-#define	clear040(paddr)					\
-	__asm__ __volatile__ ("nop\n\t"			\
-			      ".chip 68040\n\t"		\
-			      "cinvp %%bc,(%0)\n\t"	\
-			      ".chip 68k"		\
-			      : : "a" (paddr))
+static inline void clear040(unsigned long paddr)
+{
+	asm volatile (
+		"nop\n\t"
+		".chip 68040\n\t"
+		"cinvp %%bc,(%0)\n\t"
+		".chip 68k"
+		: : "a" (paddr));
+}
 
 /* invalidate page in i-cache */
-#define	cleari040(paddr)				\
-	__asm__ __volatile__ ("nop\n\t"			\
-			      ".chip 68040\n\t"		\
-			      "cinvp %%ic,(%0)\n\t"	\
-			      ".chip 68k"		\
-			      : : "a" (paddr))
+static inline void cleari040(unsigned long paddr)
+{
+	asm volatile (
+		"nop\n\t"
+		".chip 68040\n\t"
+		"cinvp %%ic,(%0)\n\t"
+		".chip 68k"
+		: : "a" (paddr));
+}
 
 /* push page in both caches */
-#define	push040(paddr)					\
-	__asm__ __volatile__ ("nop\n\t"			\
-			      ".chip 68040\n\t"		\
-			      "cpushp %%bc,(%0)\n\t"	\
-			      ".chip 68k"		\
-			      : : "a" (paddr))
+/* RZ: cpush %bc DOES invalidate %ic, regardless of DPI */
+static inline void push040(unsigned long paddr)
+{
+	asm volatile (
+		"nop\n\t"
+		".chip 68040\n\t"
+		"cpushp %%bc,(%0)\n\t"
+		".chip 68k"
+		: : "a" (paddr));
+}
 
 /* push and invalidate page in both caches, must disable ints
  * to avoid invalidating valid data */
-#define	pushcl040(paddr)			\
-	do { unsigned long flags;               \
-             save_flags(flags);                 \
-	     cli();                             \
-             push040(paddr);			\
-	     if (CPU_IS_060) clear040(paddr);	\
-	     restore_flags(flags);              \
-	} while(0)
-
-/* push page in both caches, invalidate in i-cache */
-/* RZ: cpush %bc DOES invalidate %ic, regardless of DPI */
-#define	pushcli040(paddr)			\
-	do { push040(paddr);			\
-	} while(0)
+static inline void pushcl040(unsigned long paddr)
+{
+	unsigned long flags;
 
+	local_irq_save(flags);
+	push040(paddr);
+	if (CPU_IS_060)
+		clear040(paddr);
+	local_irq_restore(flags);
+}
 
 /*
  * 040: Hit every page containing an address in the range paddr..paddr+len-1.
@@ -504,7 +333,7 @@
 	paddr &= PAGE_MASK;
 
 	do {
-	    pushcli040(paddr);
+	    push040(paddr);
 	    paddr += tmp;
 	} while ((len -= tmp) > 0);
     }
@@ -529,12 +358,6 @@
 #endif
 }
 
-
-#undef clear040
-#undef cleari040
-#undef push040
-#undef pushcl040
-#undef pushcli040
 
 #ifndef CONFIG_SINGLE_MEMORY_CHUNK
 int mm_end_of_chunk (unsigned long addr, int len)
diff -Nru a/arch/m68k/mm/motorola.c b/arch/m68k/mm/motorola.c
--- a/arch/m68k/mm/motorola.c	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/mm/motorola.c	Mon Nov  4 14:31:02 2002
@@ -196,9 +196,6 @@
 	return virtaddr;
 }
 
-extern unsigned long empty_bad_page_table;
-extern unsigned long empty_bad_page;
-
 /*
  * paging_init() continues the virtual memory environment setup which
  * was begun by the code in arch/head.S.
diff -Nru a/arch/m68k/mm/sun3kmap.c b/arch/m68k/mm/sun3kmap.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68k/mm/sun3kmap.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,156 @@
+/*
+ * linux/arch/m68k/mm/sun3kmap.c
+ *
+ * Copyright (C) 2002 Sam Creasey <sammy@sammy.net>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/io.h>
+#include <asm/sun3mmu.h>
+
+#undef SUN3_KMAP_DEBUG
+
+#ifdef SUN3_KMAP_DEBUG
+extern void print_pte_vaddr(unsigned long vaddr);
+#endif
+
+extern void mmu_emu_map_pmeg (int context, int vaddr);
+
+static inline void do_page_mapin(unsigned long phys, unsigned long virt, 
+				 unsigned long type)
+{
+	unsigned long pte;
+	pte_t ptep;
+
+	ptep = pfn_pte(phys >> PAGE_SHIFT, PAGE_KERNEL);
+	pte = pte_val(ptep);
+	pte |= type;
+
+	sun3_put_pte(virt, pte);
+
+#ifdef SUN3_KMAP_DEBUG
+	print_pte_vaddr(virt);
+#endif
+
+}
+
+static inline void do_pmeg_mapin(unsigned long phys, unsigned long virt, 
+				 unsigned long type, int pages)
+{
+
+	if(sun3_get_segmap(virt & ~SUN3_PMEG_MASK) == SUN3_INVALID_PMEG) 
+		mmu_emu_map_pmeg(sun3_get_context(), virt);
+
+	while(pages) {
+		do_page_mapin(phys, virt, type);
+		phys += PAGE_SIZE;
+		virt += PAGE_SIZE;
+		pages--;
+	}
+}
+
+void *sun3_ioremap(unsigned long phys, unsigned long size, 
+		   unsigned long type)
+{
+	struct vm_struct *area;
+	unsigned long offset, virt, ret;
+	int pages;
+
+	if(!size)
+		return NULL;
+
+	/* page align */
+	offset = phys & (PAGE_SIZE-1);
+	phys &= ~(PAGE_SIZE-1);
+
+	size += offset;
+	size = PAGE_ALIGN(size);
+	if((area = get_vm_area(size, VM_IOREMAP)) == NULL)
+		return NULL;
+
+#ifdef SUN3_KMAP_DEBUG
+	printk("ioremap: got virt %p size %lx(%lx)\n", 
+	       area->addr, size, area->size);
+#endif
+
+	pages = size / PAGE_SIZE;
+	virt = (unsigned long)area->addr;
+	ret = virt + offset;
+
+	while(pages) {
+		int seg_pages;
+
+		seg_pages = (SUN3_PMEG_SIZE - (virt & SUN3_PMEG_MASK)) / PAGE_SIZE;
+		if(seg_pages > pages)
+			seg_pages = pages;
+		
+		do_pmeg_mapin(phys, virt, type, seg_pages);
+
+		pages -= seg_pages;
+		phys += seg_pages * PAGE_SIZE;
+		virt += seg_pages * PAGE_SIZE;
+	}
+		
+	return (void *)ret;
+
+}
+ 
+ 
+void *__ioremap(unsigned long phys, unsigned long size, int cache)
+{
+	
+	return sun3_ioremap(phys, size, SUN3_PAGE_TYPE_IO);
+	
+}
+
+void iounmap(void *addr)
+{
+	vfree((void *)(PAGE_MASK & (unsigned long)addr));	
+}
+
+/* sun3_map_test(addr, val) -- Reads a byte from addr, storing to val,
+ * trapping the potential read fault.  Returns 0 if the access faulted,
+ * 1 on success.
+ *  
+ * This function is primarily used to check addresses on the VME bus.
+ *
+ * Mucking with the page fault handler seems a little hackish to me, but
+ * SunOS, NetBSD, and Mach all implemented this check in such a manner, 
+ * so I figure we're allowed.
+ */
+int sun3_map_test(unsigned long addr, char *val)
+{
+	int ret = 0;
+
+	__asm__ __volatile__
+		(".globl _sun3_map_test_start\n"
+		 "_sun3_map_test_start:\n"
+		 "1: moveb (%2), (%0)\n"
+		 "   moveq #1, %1\n"
+		 "2:\n"
+		 ".section .fixup,\"ax\"\n"
+		 ".even\n"
+		 "3: moveq #0, %1\n"
+		 "   jmp 2b\n"
+		 ".previous\n"
+		 ".section __ex_table,\"a\"\n"
+		 ".align 4\n"
+		 ".long 1b,3b\n"
+		 ".previous\n"
+		 ".globl _sun3_map_test_end\n"
+		 "_sun3_map_test_end:\n"
+		 : "=a"(val), "=r"(ret)
+		 : "a"(addr));
+	
+	return ret;
+}
diff -Nru a/arch/m68k/mm/sun3mmu.c b/arch/m68k/mm/sun3mmu.c
--- a/arch/m68k/mm/sun3mmu.c	Mon Nov  4 14:31:01 2002
+++ b/arch/m68k/mm/sun3mmu.c	Mon Nov  4 14:31:01 2002
@@ -33,8 +33,6 @@
 
 const char bad_pmd_string[] = "Bad pmd in pte_alloc: %08lx\n";
 
-extern unsigned long empty_bad_page_table;
-extern unsigned long empty_bad_page;
 extern unsigned long num_pages;
 
 void free_initmem(void)
@@ -59,8 +57,8 @@
 #ifdef TEST_VERIFY_AREA
 	wp_works_ok = 0;
 #endif
-	empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
-	memset((void *)empty_zero_page, 0, PAGE_SIZE);
+	empty_zero_page = alloc_bootmem_pages(PAGE_SIZE);
+	memset(empty_zero_page, 0, PAGE_SIZE);
 
 	address = PAGE_OFFSET;
 	pg_dir = swapper_pg_dir;
diff -Nru a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c
--- a/arch/m68k/mvme147/config.c	Mon Nov  4 14:31:01 2002
+++ b/arch/m68k/mvme147/config.c	Mon Nov  4 14:31:01 2002
@@ -181,11 +181,6 @@
 	return 0;
 }
 
-int mvme147_keyb_init (void)
-{
-	return 0;
-}
-
 /*-------------------  Serial console stuff ------------------------*/
 
 static void scc_delay (void)
diff -Nru a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c
--- a/arch/m68k/q40/config.c	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/q40/config.c	Mon Nov  4 14:31:02 2002
@@ -59,6 +59,8 @@
 extern void q40_waitbut(void);
 void q40_set_vectors (void);
 
+extern void q40_mksound(unsigned int /*freq*/, unsigned int /*ticks*/ );
+
 extern char *saved_command_line;
 extern char m68k_debug_device[];
 static void q40_mem_console_write(struct console *co, const char *b,
@@ -181,7 +183,7 @@
     mach_get_model       = q40_get_model;
     mach_get_hardware_list = q40_get_hardware_list;
 
-#ifdef CONFIG_INPUT_M68K_BEEP
+#if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)
     mach_beep            = q40_mksound;
 #endif
 #ifdef CONFIG_HEARTBEAT
diff -Nru a/arch/m68k/q40/q40ints.c b/arch/m68k/q40/q40ints.c
--- a/arch/m68k/q40/q40ints.c	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/q40/q40ints.c	Mon Nov  4 14:31:02 2002
@@ -204,8 +204,9 @@
  * this stuff doesn't really belong here..
 */
 
-int ql_ticks=0;              /* 200Hz ticks since last jiffie */
-static int sound_ticks=0;
+int ql_ticks;              /* 200Hz ticks since last jiffie */
+static int sound_ticks;
+short q40rtc_oldsecs;
 
 #define SVOL 45
 
@@ -242,9 +243,9 @@
 	*DAC_RIGHT=sval;
       }
 #if defined(CONFIG_Q40RTC) || defined(CONFIG_GEN_RTC)
-    if (gen_rtc_irq_ctrl && (q40rtc_oldsecs != RTC_SECS))
+    if (gen_rtc_irq_ctrl && (q40rtc_oldsecs != Q40_RTC_SECS))
       {
-	q40rtc_oldsecs = RTC_SECS;
+	q40rtc_oldsecs = Q40_RTC_SECS;
 	gen_rtc_irq_flags = RTC_UIE;
 	gen_rtc_interrupt(0);
       }
diff -Nru a/arch/m68k/sun3/Makefile b/arch/m68k/sun3/Makefile
--- a/arch/m68k/sun3/Makefile	Mon Nov  4 14:31:00 2002
+++ b/arch/m68k/sun3/Makefile	Mon Nov  4 14:31:00 2002
@@ -4,9 +4,9 @@
 
 export-objs	:= sun3_ksyms.o
 
-obj-y	:= sun3_ksyms.o sun3ints.o sun3dvma.o sbus.o
+obj-y	:= sun3_ksyms.o sun3ints.o sun3dvma.o sbus.o idprom.o
 
-obj-$(CONFIG_SUN3) += config.o idprom.o mmu_emu.o leds.o dvma.o \
+obj-$(CONFIG_SUN3) += config.o mmu_emu.o leds.o dvma.o \
 			intersil.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/arch/m68k/sun3/config.c b/arch/m68k/sun3/config.c
--- a/arch/m68k/sun3/config.c	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/sun3/config.c	Mon Nov  4 14:31:02 2002
@@ -151,9 +151,6 @@
         mach_default_handler = &sun3_default_handler;
         mach_request_irq     =  sun3_request_irq;
         mach_free_irq        =  sun3_free_irq;
-#ifdef CONFIG_VT
-//	mach_keyb_init       =  sun3_keyb_init;
-#endif
 	enable_irq     	     =  sun3_enable_irq;
         disable_irq  	     =  sun3_disable_irq;
 	mach_process_int     =  sun3_process_int;
diff -Nru a/arch/m68k/sun3/idprom.c b/arch/m68k/sun3/idprom.c
--- a/arch/m68k/sun3/idprom.c	Mon Nov  4 14:31:01 2002
+++ b/arch/m68k/sun3/idprom.c	Mon Nov  4 14:31:01 2002
@@ -31,8 +31,8 @@
 { "Sun 3/60", (SM_SUN3 | SM_3_60) },
 { "Sun 3/E", (SM_SUN3 | SM_3_E) },
 /* Now, Sun3x's */
-{ "Sun 3/460 Series", (SM_SUN3 | SM_3_460) },
-{ "Sun 3/80", (SM_SUN3 | SM_3_80) },
+{ "Sun 3/460 Series", (SM_SUN3X | SM_3_460) },
+{ "Sun 3/80", (SM_SUN3X | SM_3_80) },
 /* Then, Sun4's */
 //{ "Sun 4/100 Series", (SM_SUN4 | SM_4_110) },
 //{ "Sun 4/200 Series", (SM_SUN4 | SM_4_260) },
diff -Nru a/arch/m68k/sun3/intersil.c b/arch/m68k/sun3/intersil.c
--- a/arch/m68k/sun3/intersil.c	Mon Nov  4 14:31:00 2002
+++ b/arch/m68k/sun3/intersil.c	Mon Nov  4 14:31:00 2002
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/rtc.h>
 
+#include <asm/errno.h>
 #include <asm/system.h>
 #include <asm/semaphore.h>
 #include <asm/rtc.h>
diff -Nru a/arch/m68k/sun3/mmu_emu.c b/arch/m68k/sun3/mmu_emu.c
--- a/arch/m68k/sun3/mmu_emu.c	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/sun3/mmu_emu.c	Mon Nov  4 14:31:02 2002
@@ -52,7 +52,8 @@
 
 /* pointers to the mm structs for each task in each
    context. 0xffffffff is a marker for kernel context */
-struct mm_struct *ctx_alloc[CONTEXTS_NUM] = {0xffffffff, 0, 0, 0, 0, 0, 0, 0};
+struct mm_struct *ctx_alloc[CONTEXTS_NUM] = {(struct mm_struct *)0xffffffff, 
+					     0, 0, 0, 0, 0, 0, 0};
 /* has this context been mmdrop'd? */
 static unsigned char ctx_avail = CONTEXTS_NUM-1;
 
@@ -176,7 +177,6 @@
 			pmeg_alloc[sun3_get_segmap(seg)] = 2;
 		}
 	}
-
 	
 	dvma_init();
 	
@@ -275,7 +275,7 @@
 //todo: better allocation scheme? but is extra complexity worthwhile?
 //todo: only clear old entries if necessary? how to tell?
 
-static inline void mmu_emu_map_pmeg (int context, int vaddr)
+inline void mmu_emu_map_pmeg (int context, int vaddr)
 {
 	static unsigned char curr_pmeg = 128;
 	int i;
diff -Nru a/arch/m68k/sun3/sun3dvma.c b/arch/m68k/sun3/sun3dvma.c
--- a/arch/m68k/sun3/sun3dvma.c	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/sun3/sun3dvma.c	Mon Nov  4 14:31:02 2002
@@ -14,6 +14,8 @@
 #include <asm/pgtable.h>
 #include <asm/dvma.h>
 
+#undef DVMA_DEBUG
+
 #ifdef CONFIG_SUN3X
 extern void dvma_unmap_iommu(unsigned long baddr, int len);
 #else
@@ -22,6 +24,10 @@
 }
 #endif
 
+#ifdef CONFIG_SUN3
+extern void sun3_dvma_init(void);
+#endif
+
 unsigned long iommu_use[IOMMU_TOTAL_ENTRIES];
 
 #define dvma_index(baddr) ((baddr - DVMA_START) >> DVMA_PAGE_SHIFT)
@@ -39,6 +45,60 @@
 static struct list_head hole_cache;
 static struct hole initholes[64];
 
+#ifdef DVMA_DEBUG
+
+static unsigned long dvma_allocs = 0;
+static unsigned long dvma_frees = 0;
+static unsigned long long dvma_alloc_bytes = 0;
+static unsigned long long dvma_free_bytes = 0;
+
+static void print_use(void) 
+{
+	
+	int i;
+	int j = 0;
+
+	printk("dvma entry usage:\n");
+	
+	for(i = 0; i < IOMMU_TOTAL_ENTRIES; i++) {
+		if(!iommu_use[i])
+			continue;
+		
+		j++;
+
+		printk("dvma entry: %08lx len %08lx\n", 
+		       ( i << DVMA_PAGE_SHIFT) + DVMA_START,
+		       iommu_use[i]);
+	}
+
+	printk("%d entries in use total\n", j);
+
+	printk("allocation/free calls: %lu/%lu\n", dvma_allocs, dvma_frees);
+	printk("allocation/free bytes: %Lx/%Lx\n", dvma_alloc_bytes, 
+	       dvma_free_bytes);
+}
+
+static void print_holes(struct list_head *holes)
+{
+	
+	struct list_head *cur;
+	struct hole *hole;
+
+	printk("listing dvma holes\n");
+	list_for_each(cur, holes) {
+		hole = list_entry(cur, struct hole, list);
+		
+		if((hole->start == 0) && (hole->end == 0) && (hole->size == 0))
+			continue;
+		
+		printk("hole: start %08lx end %08lx size %08lx\n", hole->start, hole->end, hole->size);
+	}
+	
+	printk("end of hole listing...\n");
+	
+}
+#endif DVMA_DEBUG
+
 static inline int refill(void)
 {
 
@@ -93,7 +153,11 @@
 	struct hole *hole;
 
 	if(list_empty(&hole_list)) {
-		printk("out of dvma holes!\n");
+#ifdef DVMA_DEBUG
+		printk("out of dvma holes! (printing hole cache)\n");
+		print_holes(&hole_cache);
+		print_use();
+#endif
 		BUG();
 	}
 
@@ -111,11 +175,19 @@
 			hole->end -= newlen;
 			hole->size -= newlen;
 			dvma_entry_use(hole->end) = newlen;
+#ifdef DVMA_DEBUG
+			dvma_allocs++;
+			dvma_alloc_bytes += newlen;
+#endif
 			return hole->end;
 		} else if(hole->size == newlen) {
 			list_del(&(hole->list));
 			list_add(&(hole->list), &hole_cache);
 			dvma_entry_use(hole->start) = newlen;
+#ifdef DVMA_DEBUG
+			dvma_allocs++;
+			dvma_alloc_bytes += newlen;
+#endif
 			return hole->start;
 		}
 
@@ -140,6 +212,11 @@
 	baddr &= DVMA_PAGE_MASK;
 	dvma_unmap_iommu(baddr, len);
 
+#ifdef DVMA_DEBUG
+	dvma_frees++;
+	dvma_free_bytes += len;
+#endif
+
 	list_for_each(cur, &hole_list) {
 		hole = list_entry(cur, struct hole, list);
 		
@@ -240,8 +317,14 @@
 
 void dvma_unmap(void *baddr)
 {
-
-	free_baddr((unsigned long)baddr);
+	unsigned long addr;
+	
+	addr = (unsigned long)baddr;
+	/* check if this is a vme mapping */
+	if(!(addr & 0x00f00000))
+		addr |= 0xf00000;
+	
+	free_baddr(addr);
 	
 	return;
 
diff -Nru a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c
--- a/arch/m68k/sun3/sun3ints.c	Mon Nov  4 14:31:03 2002
+++ b/arch/m68k/sun3/sun3ints.c	Mon Nov  4 14:31:03 2002
@@ -18,6 +18,7 @@
 #include <linux/seq_file.h>
 
 extern void sun3_leds (unsigned char);
+static void sun3_inthandle(int irq, void *dev_id, struct pt_regs *fp);
 
 void sun3_disable_interrupts(void)
 {
@@ -58,26 +59,22 @@
 
 inline void sun3_do_irq(int irq, struct pt_regs *fp)
 {
-	kstat.irqs[0][SYS_IRQS + irq]++;
+	kstat_cpu(0).irqs[SYS_IRQS + irq]++;
 	*sun3_intreg &= ~(1<<irq);
 	*sun3_intreg |=  (1<<irq);
 }
 
-int show_sun3_interrupts(struct seq_file *p, void *v)
-{
-	return 0;
-}
-
 static void sun3_int7(int irq, void *dev_id, struct pt_regs *fp)
 {
 	sun3_do_irq(irq,fp);
-	if(!(kstat.irqs[0][SYS_IRQS + irq] % 2000)) 
-		sun3_leds(led_pattern[(kstat.irqs[0][SYS_IRQS+irq]%16000)/2000]);
+	if(!(kstat_cpu(0).irqs[SYS_IRQS + irq] % 2000)) 
+		sun3_leds(led_pattern[(kstat_cpu(0).irqs[SYS_IRQS+irq]%16000)
+			  /2000]);
 }
 
 static void sun3_int5(int irq, void *dev_id, struct pt_regs *fp)
 {
-        kstat.irqs[0][SYS_IRQS + irq]++;
+        kstat_cpu(0).irqs[SYS_IRQS + irq]++;
 #ifdef CONFIG_SUN3
 	intersil_clear();
 #endif
@@ -87,27 +84,52 @@
 	intersil_clear();
 #endif
         do_timer(fp);
-        if(!(kstat.irqs[0][SYS_IRQS + irq] % 20))
-                sun3_leds(led_pattern[(kstat.irqs[0][SYS_IRQS+irq]%160)
+        if(!(kstat_cpu(0).irqs[SYS_IRQS + irq] % 20))
+                sun3_leds(led_pattern[(kstat_cpu(0).irqs[SYS_IRQS+irq]%160)
                 /20]);
 }
 
 /* handle requested ints, excepting 5 and 7, which always do the same
    thing */
+void (*sun3_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
+	sun3_inthandle, sun3_inthandle, sun3_inthandle, sun3_inthandle,
+	sun3_inthandle, sun3_int5, sun3_inthandle, sun3_int7
+};
+
+static const char *dev_names[SYS_IRQS] = { NULL, NULL, NULL, NULL, 
+				     NULL, "timer", NULL, "int7 handler" };
 static void *dev_ids[SYS_IRQS];
 static void (*sun3_inthandler[SYS_IRQS])(int, void *, struct pt_regs *) = {
 	NULL, NULL, NULL, NULL, NULL, sun3_int5, NULL, sun3_int7
 };
-static void (*sun3_vechandler[192])(int, void *, struct pt_regs *);
-static void *vec_ids[192];
-static char *vec_names[192];
+static void (*sun3_vechandler[SUN3_INT_VECS])(int, void *, struct pt_regs *);
+static void *vec_ids[SUN3_INT_VECS];
+static const char *vec_names[SUN3_INT_VECS];
+static int vec_ints[SUN3_INT_VECS];
+
+
+int show_sun3_interrupts(struct seq_file *p, void *v)
+{
+	int i;
+
+	for(i = 0; i < (SUN3_INT_VECS-1); i++) {
+		if(sun3_vechandler[i] != NULL) {
+			seq_printf(p, "vec %3d: %10u %s\n", i+64, 
+				   vec_ints[i],
+				   (vec_names[i]) ? vec_names[i] :
+				   "sun3_vechandler");
+		}
+	}
+
+	return 0;
+}
 
 static void sun3_inthandle(int irq, void *dev_id, struct pt_regs *fp)
 {
 	if(sun3_inthandler[irq] == NULL)
 		panic ("bad interrupt %d received (id %p)\n",irq, dev_id);
 
-        kstat.irqs[0][SYS_IRQS + irq]++;
+        kstat_cpu(0).irqs[SYS_IRQS + irq]++;
         *sun3_intreg &= ~(1<<irq);
 
 	sun3_inthandler[irq](irq, dev_ids[irq], fp);
@@ -118,14 +140,6 @@
 //	intersil_clear();
 }
 
-void (*sun3_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
-	sun3_inthandle, sun3_inthandle, sun3_inthandle, sun3_inthandle,
-	sun3_inthandle, sun3_int5, sun3_inthandle, sun3_int7
-};
-
-static char *dev_names[SYS_IRQS] = { NULL, NULL, NULL, NULL, 
-				     NULL, "timer", NULL, NULL };
-
 void sun3_init_IRQ(void)
 {
 	int i;
@@ -176,6 +190,7 @@
 			sun3_vechandler[vec] = handler;
 			vec_ids[vec] = dev_id;
 			vec_names[vec] = devname;
+			vec_ints[vec] = 0;
 			
 			return 0;
 		}
@@ -222,7 +237,8 @@
 		vec = irq - 64;
 		if(sun3_vechandler[vec] == NULL) 
 			panic ("bad interrupt vector %d received\n",irq);
-			
+
+		vec_ints[vec]++;
 		sun3_vechandler[vec](irq, vec_ids[vec], regs);
 		return;
 	} else {
diff -Nru a/arch/m68k/sun3x/config.c b/arch/m68k/sun3x/config.c
--- a/arch/m68k/sun3x/config.c	Mon Nov  4 14:31:00 2002
+++ b/arch/m68k/sun3x/config.c	Mon Nov  4 14:31:00 2002
@@ -17,37 +17,30 @@
 #include <asm/sun3xprom.h>
 #include <asm/sun3ints.h>
 #include <asm/setup.h>
+#include <asm/oplib.h>
 
 #include "time.h"
 
 volatile char *clock_va;
 extern volatile unsigned char *sun3_intreg;
 
+extern void sun3_get_model(char *model);
 
-int __init sun3x_keyb_init(void)
-{
-	return 0;
-}
-
-int sun3x_kbdrate(struct kbd_repeat *r)
-{
-	return 0;
-}
-
-void sun3x_kbd_leds(unsigned int i)
+void sun3_leds(unsigned int i)
 {
 
 }
 
-void sun3_leds(unsigned int i)
+static int sun3x_get_hardware_list(char *buffer)
 {
+	
+	int len = 0;
 
-}
+	len += sprintf(buffer + len, "PROM Revision:\t%s\n",
+		       romvec->pv_monid);
+	
+	return len;
 
-/* should probably detect types of these eventually. */
-static void sun3x_get_model(char *model)
-{
-	sprintf(model, "Sun3x");
 }
 
 /*
@@ -60,12 +53,6 @@
 
 	mach_get_irq_list	 = show_sun3_interrupts;
 	mach_max_dma_address = 0xffffffff; /* we can DMA anywhere, whee */
-
-#ifdef CONFIG_VT
-	mach_keyb_init       = sun3x_keyb_init;
-	mach_kbdrate         = sun3x_kbdrate;
-	mach_kbd_leds        = sun3x_kbd_leds;
-#endif
 
 	mach_default_handler = &sun3_default_handler;
 	mach_sched_init      = sun3x_sched_init;
diff -Nru a/arch/m68k/sun3x/prom.c b/arch/m68k/sun3x/prom.c
--- a/arch/m68k/sun3x/prom.c	Mon Nov  4 14:31:01 2002
+++ b/arch/m68k/sun3x/prom.c	Mon Nov  4 14:31:01 2002
@@ -26,8 +26,6 @@
 int (*sun3x_mayput)(int);
 void (*sun3x_prom_reboot)(void);
 e_vector sun3x_prom_abort;
-struct idprom *idprom;
-static struct idprom idprom_buffer;
 struct linux_romvec *romvec;
 
 /* prom vector table */
@@ -107,8 +105,6 @@
 void sun3x_prom_init(void)
 {
     /* Read the vector table */
-	int i;
-
 
     sun3x_putchar = *(void (**)(int)) (SUN3X_P_PUTCHAR);
     sun3x_getchar = *(int (**)(void)) (SUN3X_P_GETCHAR);
@@ -118,13 +114,11 @@
     sun3x_prom_abort = *(e_vector *)  (SUN3X_P_ABORT);
     romvec = (struct linux_romvec *)SUN3X_PROM_BASE;
 
-    /* make a copy of the idprom structure */
-    for(i = 0; i < sizeof(struct idprom); i++) 
-	    ((unsigned char *)(&idprom_buffer))[i] = ((unsigned char *)SUN3X_IDPROM)[i];
-    idprom = &idprom_buffer;
+    idprom_init();
 
-    if((idprom->id_machtype & SM_ARCH_MASK) != SM_SUN3X) {
-	    printk("Warning: machine reports strange type %02x\n");
+    if(!((idprom->id_machtype & SM_ARCH_MASK) == SM_SUN3X)) {
+	    printk("Warning: machine reports strange type %02x\n",
+		   idprom->id_machtype);
 	    printk("Pretending it's a 3/80, but very afraid...\n");
 	    idprom->id_machtype = SM_SUN3X | SM_3_80;
     }
@@ -161,4 +155,20 @@
 void prom_halt (void)
 {
 	sun3x_halt();
+}
+
+/* Get the idprom and stuff it into buffer 'idbuf'.  Returns the
+ * format type.  'num_bytes' is the number of bytes that your idbuf
+ * has space for.  Returns 0xff on error.
+ */
+unsigned char
+prom_get_idprom(char *idbuf, int num_bytes)
+{
+        int i;
+
+	/* make a copy of the idprom structure */
+	for(i = 0; i < num_bytes; i++) 
+		idbuf[i] = ((char *)SUN3X_IDPROM)[i];
+
+        return idbuf[0];
 }
diff -Nru a/arch/m68k/sun3x/time.c b/arch/m68k/sun3x/time.c
--- a/arch/m68k/sun3x/time.c	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/sun3x/time.c	Mon Nov  4 14:31:02 2002
@@ -79,6 +79,7 @@
     return 0L;
 }
 
+#if 0
 static void sun3x_timer_tick(int irq, void *dev_id, struct pt_regs *regs)
 {
     void (*vector)(int, void *, struct pt_regs *) = dev_id;
@@ -89,6 +90,7 @@
     
     vector(irq, NULL, regs);
 }
+#endif
 
 void __init sun3x_sched_init(void (*vector)(int, void *, struct pt_regs *))
 {
diff -Nru a/arch/m68k/vmlinux-std.lds b/arch/m68k/vmlinux-std.lds
--- a/arch/m68k/vmlinux-std.lds	Mon Nov  4 14:31:02 2002
+++ b/arch/m68k/vmlinux-std.lds	Mon Nov  4 14:31:02 2002
@@ -38,13 +38,14 @@
 
   _edata = .;			/* End of data section */
 
+  /* will be freed after init */
   . = ALIGN(4096);		/* Init code and data */
   __init_begin = .;
-  .text.init : { *(.text.init) }
-  .data.init : { *(.data.init) }
+  .init.text : { *(.init.text) }
+  .init.data : { *(.init.data) }
   . = ALIGN(16);
   __setup_start = .;
-  .setup.init : { *(.setup.init) }
+  .init.setup : { *(.init.setup) }
   __setup_end = .;
   __initcall_start = .;
   .initcall.init : {
@@ -60,9 +61,16 @@
   . = ALIGN(8192);
   __init_end = .;
 
-  init_task : { *(init_task) }	/* The initial task and kernel stack */
+  .data.init_task : { *(.data.init_task) }	/* The initial task and kernel stack */
 
   _end = . ;
+
+  /* Sections to be discarded */
+  /DISCARD/ : {
+	*(.exit.text)
+	*(.exit.data)
+	*(.exitcall.exit)
+	}
 
   /* Stabs debugging sections.  */
   .stab 0 : { *(.stab) }
diff -Nru a/arch/m68k/vmlinux-sun3.lds b/arch/m68k/vmlinux-sun3.lds
--- a/arch/m68k/vmlinux-sun3.lds	Mon Nov  4 14:31:00 2002
+++ b/arch/m68k/vmlinux-sun3.lds	Mon Nov  4 14:31:00 2002
@@ -34,13 +34,14 @@
   /* End of data goes *here* so that freeing init code works properly. */
   _edata = .;
 
+  /* will be freed after init */
   . = ALIGN(8192);	/* Init code and data */
 __init_begin = .;
-  	.text.init : { *(.text.init) }
-  	.data.init : { *(.data.init) }
+  	.init.text : { *(.init.text) }
+  	.init.data : { *(.init.data) }
 	. = ALIGN(16);
 	__setup_start = .;
-	.setup.init : { *(.setup.init) }
+	.init.setup : { *(.init.setup) }
 	__setup_end = .;
 	__initcall_start = .;
 	.initcall.init : {
@@ -61,6 +62,13 @@
   .bss : { *(.bss) }		/* BSS */
 
   _end = . ;
+
+  /* Sections to be discarded */
+  /DISCARD/ : {
+	*(.exit.text)
+	*(.exit.data)
+	*(.exitcall.exit)
+	}
 
   .crap : {
   	/* Stabs debugging sections.  */
diff -Nru a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/Kconfig	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,796 @@
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/config-language.txt.
+#
+
+mainmenu "uClinux/68k (w/o MMU) Kernel Configuration"
+
+config MMU
+	bool
+	default n
+
+config SWAP
+	bool
+	default n
+
+config FPU
+	bool
+	default n
+
+config UID16
+	bool
+	default y
+
+config RWSEM_GENERIC_SPINLOCK
+	bool
+	default y
+
+config RWSEM_XCHGADD_ALGORITHM
+	bool
+	default n
+
+
+source "init/Kconfig"
+
+menu "Processor type and features"
+
+choice
+	prompt "CPU"
+	default M68EZ328
+
+config M68328
+	bool "MC68328"
+	help
+	  Motorola 68328 processor support.
+
+config M68EZ328
+	bool "MC68EZ328"
+	help
+	  Motorola 68EX328 processor support.
+
+config M68VZ328
+	bool "MC68VZ328"
+	help
+	  Motorola 68VZ328 processor support.
+
+config M68360
+	bool "MC68360"
+	help
+	  Motorola 68360 processor support.
+
+config M5206
+	bool "MCF5206"
+	help
+	  Motorola ColdFire 5206 processor support.
+
+config M5206e
+	bool "MCF5206e"
+	help
+	  Motorola ColdFire 5206e processor support.
+
+config M5249
+	bool "MCF5249"
+	help
+	  Motorola ColdFire 5249 processor support.
+
+config M5272
+	bool "MCF5272"
+	help
+	  Motorola ColdFire 5272 processor support.
+
+config M5307
+	bool "MCF5307"
+	help
+	  Motorola ColdFire 5307 processor support.
+
+config M5407
+	bool "MCF5407"
+	help
+	  Motorola ColdFire 5407 processor support.
+
+endchoice
+
+config COLDFIRE
+	bool
+	depends on (M5206 || M5206e || M5249 || M5272 || M5307 || M5407)
+	default y
+
+choice
+	prompt "CPU CLOCK Frequency"
+	default AUTO
+
+config CLOCK_AUTO
+	bool "AUTO"
+	---help---
+	  Define the CPU clock frequency in use. On many boards you don't
+	  really need to know, so you can select the AUTO option. On some
+	  boards you need to know the real clock frequency to determine other
+	  system timing (for example baud rate dividors, etc). Some processors
+	  have an internal PLL and you can seletc a frequency to set that too.
+	  You need to know a little about the internals of your processor to
+	  set this. If in doubt choose the AUTO option.
+
+config CLOCK_11MHz
+	bool "11MHz"
+	help
+	  Select an 11MHz CPU clock frequency.
+
+config CLOCK_16MHz
+	bool "16MHz"
+	help
+	  Select an 16MHz CPU clock frequency.
+
+config CLOCK_20MHz
+	bool "20MHz"
+	help
+	  Select an 20MHz CPU clock frequency.
+
+config CLOCK_24MHz
+	bool "24MHz"
+	help
+	  Select an 24MHz CPU clock frequency.
+
+config CLOCK_25MHz
+	bool "25MHz"
+	help
+	  Select an 25MHz CPU clock frequency.
+
+config CLOCK_33MHz
+	bool "33MHz"
+	help
+	  Select an 33MHz CPU clock frequency.
+
+config CLOCK_40MHz
+	bool "40MHz"
+	help
+	  Select an 40MHz CPU clock frequency.
+
+config CLOCK_45MHz
+	bool "45MHz"
+	help
+	  Select an 45MHz CPU clock frequency.
+
+config CLOCK_48MHz
+	bool "48MHz"
+	help
+	  Select an 48MHz CPU clock frequency.
+
+config CLOCK_50MHz
+	bool "50MHz"
+	help
+	  Select an 50MHz CPU clock frequency.
+
+config CLOCK_54MHz
+	bool "54MHz"
+	help
+	  Select an 54MHz CPU clock frequency.
+
+config CLOCK_60MHz
+	bool "60MHz"
+	help
+	  Select an 60MHz CPU clock frequency.
+
+config CLOCK_66MHz
+	bool "66MHz"
+	help
+	  Select an 66MHz CPU clock frequency.
+
+config CLOCK_70MHz
+	bool "70MHz"
+	help
+	  Select an 70MHz CPU clock frequency.
+
+config CLOCK_140MHz
+	bool "140MHz"
+	help
+	  Select an 140MHz CPU clock frequency.
+
+endchoice
+
+config OLDMASK
+	bool "Old mask 5307 (1H55J) silicon"
+	depends on M5307
+	help
+	  Build support for the older revision ColdFire 5307 silicon.
+	  Specifically this is the 1H55J mask revision.
+
+comment "Platform"
+
+config PILOT3
+	bool "Pilot 1000/5000, PalmPilot Personal/Pro, or PalmIII support"
+	depends on M68328
+	help
+	  Support for the Palm Pilot 1000/5000, Personal/Pro and PalmIII.
+
+config XCOPILOT_BUGS
+	bool "  (X)Copilot support"
+	depends on PILOT3
+	help
+	  Support the bugs of Xcopilot.
+
+config UCSIMM
+	bool "uCsimm module support"
+	depends on M68EZ328
+	help
+	  Support for the Arcturus Networks uCsimm module.
+
+config UCDIMM
+	bool "uDsimm module support"
+	depends on M68VZ328
+	help
+	  Support for the Arcturus Networks uDsimm module.
+
+config DRAGEN2
+	bool "Dragen Engine II board support"
+	depends on M68VZ328
+	help
+	  Support for the Dragen Engine II board.
+
+config HWADDR_FROMEEPROM
+	bool "  Read ETH address from EEPROM"
+	depends on DRAGEN2
+	help
+	  Use MAC address from EEPROM.
+
+config HWADDR_OFFSET
+	int "  Offset from start of EEPROM"
+	default "2"
+	depends on HWADDR_FROMEEPROM
+
+config INIT_LCD
+	bool "  Initialize LCD"
+	depends on (UCSIMM || UCDIMM || DRAGEN2)
+	help
+	  Initialize the LCD controller of the 68x328 processor.
+
+config MEMORY_RESERVE
+	int "  Memory reservation (MiB)"
+	depends on (UCSIMM || UCDIMM || DRAGEN2)
+	help
+	  Reserve certain memory regions on 68x328 based boards.
+
+config UCQUICC
+	bool "Lineo uCquicc board support"
+	depends on M68360
+	help
+	  Support for the Lineo uCquicc board.
+
+config ARN5206
+	bool "Arnewsh 5206 board support"
+	depends on M5206
+	help
+	  Support for the Arnewsh 5206 board.
+
+config M5206eC3
+	bool "Motorola M5206eC3 board support"
+	depends on M5206e
+	help
+	  Support for the Motorola M5206eC3 board.
+
+config ELITE
+	bool "Motorola M5206eLITE board support"
+	depends on M5206e
+	help
+	  Support for the Motorola M5206eLITE board.
+
+config M5249C3
+	bool "Motorola M5249C3 board support"
+	depends on M5249
+	help
+	  Support for the Motorola M5249C3 board.
+
+config M5272C3
+	bool "Motorola M5272C3 board support"
+	depends on M5272
+	help
+	  Support for the Motorola M5272C3 board.
+
+config ARN5307
+	bool "Arnewsh 5307 board support"
+	depends on M5307
+	help
+	  Support for the Arnewsh 5307 board.
+
+config M5307C3
+	bool "Motorola M5307C3 board support"
+	depends on M5307
+	help
+	  Support for the Motorola M5307C3 board.
+
+config eLIA
+	bool "Moreton Bay eLIA board support"
+	depends on M5307
+	help
+	  Support for the Moreton Bay eLIA board.
+
+config SECUREEDGEMP3
+	bool "SnapGear SecureEdge/MP3 platform support"
+	depends on M5307
+	help
+	  Support for the SnapGear SecureEdge/MP3 platform.
+
+config M5407C3
+	bool "Motorola M5407C3 board support"
+	depends on M5407
+	help
+	  Support for the Motorola M5407C3 board.
+
+config CLEOPATRA
+	bool "Feith CLEOPATRA board support"
+	depends on (M5307 || M5407)
+	help
+	  Support for the Feith Cleopatra boards.
+
+config NETtel
+	bool "SecureEdge/NETtel board support"
+	depends on (M5206e || M5272 || M5307)
+	help
+	  Support for the SnapGear NETtel/SecureEdge/SnapGear boards.
+
+config SNAPGEAR
+	bool "SnapGear router board support"
+	depends on NETtel
+	help
+	  Special additional support for SnapGear router boards.
+
+config ROMFS_FROM_ROM
+	bool "  ROMFS image not RAM resident"
+	depends on (NETtel || SNAPGEAR)
+	help
+	  The ROMfs filesystem will stay resident in the FLASH/ROM, not be
+	  moved into RAM.
+
+config PILOT
+	bool
+	default y
+	depends on (PILOT3 || PILOT5)
+
+config ARNEWSH
+	bool
+	default y
+	depends on (ARN5206 || ARN5307)
+
+config MOTOROLA
+	bool
+	default y
+	depends on (M5206eC3 || M5249C3 || M5272C3 || M5307C3 || M5407C3)
+
+config LARGE_ALLOCS
+	bool "Allow allocating large blocks (> 1MB) of memory"
+	help
+	  Allow the slab memory allocator to keep chains for very large
+	  memory sizes - upto 32MB. You may need this if your system has
+	  a lot of RAM, and you need to able to allocate very large
+	  contiguous chunks. If unsure, say N.
+
+choice 
+	prompt "RAM size"
+	default AUTO
+
+config RAMAUTO
+	bool "AUTO"
+	---help---
+	  Configure the RAM size on your platform. Many platforms can auto
+	  detect this, on those choose the AUTO option. Otherwise set the
+	  RAM size you intend using.
+
+config RAM4MB
+	bool "4MiB"
+	help
+	  Set RAM size to be 4MiB.
+
+config RAM4MB
+	bool "4MiB"
+	help
+	  Set RAM size to be 4MiB.
+
+config RAM8MB
+	bool "8MiB"
+	help
+	  Set RAM size to be 8MiB.
+
+config RAM16MB
+	bool "16MiB"
+	help
+	  Set RAM size to be 16MiB.
+
+config RAM32MB
+	bool "32MiB"
+	help
+	  Set RAM size to be 32MiB.
+
+endchoice
+
+choice 
+	prompt "RAM bus width"
+	default RAMAUTOBIT
+
+config RAMAUTOBIT
+	bool "AUTO"
+	---help---
+	  Select the physical RAM data bus size. Not needed on most platforms,
+	  so you can generally choose AUTO.
+
+config RAM8BIT
+	bool "8bit"
+	help
+	  Configure RAM bus to be 8 bits wide.
+
+config RAM16BIT
+	bool "16bit"
+	help
+	  Configure RAM bus to be 16 bits wide.
+
+config RAM32BIT
+	bool "32bit"
+	help
+	  Configure RAM bus to be 32 bits wide.
+
+endchoice
+
+choice
+	prompt "Kernel executes from"
+	---help---
+	  Choose the memory type that the kernel will be running in.
+
+config RAMKERNEL
+	bool "RAM"
+	help
+	  The kernel will be resident in RAM when running.
+
+config ROMKERNEL
+	bool "ROM"
+	help
+	  The kernel will be resident in FLASH/ROM when running.
+
+config HIMEMKERNEL
+	bool "HIMEM"
+	help
+	  The kernel will be resident in high memory when running.
+
+endchoice
+
+endmenu
+
+
+menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)"
+
+config PCI
+	bool "PCI support"
+	help
+	  Support for PCI bus.
+
+config COMEMPCI
+	bool "CO-MEM lite PCI controller support"
+	depends on (M5307 || M5407)
+
+source "drivers/pci/Kconfig"
+
+config HOTPLUG
+	bool "Support for hot-pluggable device"
+	  ---help---
+	  Say Y here if you want to plug devices into your computer while
+	  the system is running, and be able to use them quickly.  In many
+	  cases, the devices can likewise be unplugged at any time too.
+
+	  One well known example of this is PCMCIA- or PC-cards, credit-card
+	  size devices such as network cards, modems or hard drives which are
+	  plugged into slots found on all modern laptop computers.  Another
+	  example, used on modern desktops as well as laptops, is USB.
+
+	  Enable HOTPLUG and KMOD, and build a modular kernel.  Get agent
+	  software (at <http://linux-hotplug.sourceforge.net/>) and install it.
+	  Then your kernel will automatically call out to a user mode "policy
+	  agent" (/sbin/hotplug) to load modules and set up software needed
+	  to use devices as you hotplug them.
+
+source "drivers/pcmcia/Kconfig"
+
+source "drivers/hotplug/Kconfig"
+
+endmenu
+
+menu "Executable file formats"
+
+config KCORE_AOUT
+	bool
+	default y
+
+config KCORE_ELF
+	default y
+
+config BINFMT_FLAT
+	tristate "Kernel support for flat binaries"
+	help
+	  Support uClinux FLAT format binaries.
+
+config BINFMT_ZFLAT
+	bool "  Enable ZFLAT support"
+	depends on BINFMT_FLAT
+	help
+	  Supoprt FLAT format compressed binaries
+
+endmenu
+
+menu "Power management options"
+
+config PM
+	bool "Power Management support"
+	help
+	  Support processor power management modes
+
+endmenu
+
+
+source "drivers/mtd/Kconfig"
+
+source "drivers/parport/Kconfig"
+
+source "drivers/pnp/Kconfig"
+
+source "drivers/block/Kconfig"
+
+
+menu "ATA/IDE/MFM/RLL support"
+
+config IDE
+	tristate "ATA/ATAPI/MFM/RLL device support"
+	---help---
+	  If you say Y here, your kernel will be able to manage low cost mass
+	  storage units such as ATA/(E)IDE and ATAPI units. The most common
+	  cases are IDE hard drives and ATAPI CD-ROM drives.
+
+	  It only makes sense to choose this option if your board actually
+	  has an IDE interface. If unsure, say N.
+
+source "drivers/ide/Kconfig"
+
+endmenu
+
+
+menu "SCSI device support"
+
+config SCSI
+	tristate "SCSI device support"
+	help
+	  If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or
+	  any other SCSI device under Linux, say Y and make sure that you know
+	  the name of your SCSI host adapter (the card inside your computer
+	  that "speaks" the SCSI protocol, also called SCSI controller),
+	  because you will be asked for it.
+
+source "drivers/scsi/Kconfig"
+
+endmenu
+
+
+menu "Old CD-ROM drivers (not SCSI, not IDE)"
+	depends on ISA
+
+config CD_NO_IDESCSI
+	bool "Support non-SCSI/IDE/ATAPI CDROM drives"
+	---help---
+	  If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y
+	  here, otherwise N. Read the CD-ROM-HOWTO, available from
+	  <http://www.linuxdoc.org/docs.html#howto>.
+
+	  Note that the answer to this question doesn't directly affect the
+	  kernel: saying N will just cause the configurator to skip all
+	  the questions about these CD-ROM drives. If you are unsure what you
+	  have, say Y and find out whether you have one of the following
+	  drives.
+
+	  For each of these drivers, a file Documentation/cdrom/{driver_name}
+	  exists. Especially in cases where you do not know exactly which kind
+	  of drive you have you should read there. Most of these drivers use a
+	  file drivers/cdrom/{driver_name}.h where you can define your
+	  interface parameters and switch some internal goodies.
+
+	  All these CD-ROM drivers are also usable as a module ( = code which
+	  can be inserted in and removed from the running kernel whenever you
+	  want). If you want to compile them as module, say M instead of Y and
+	  read <file:Documentation/modules.txt>.
+
+	  If you want to use any of these CD-ROM drivers, you also have to
+	  answer Y or M to "ISO 9660 CD-ROM file system support" below (this
+	  answer will get "defaulted" for you if you enable any of the Linux
+	  CD-ROM drivers).
+
+source "drivers/cdrom/Kconfig"
+
+endmenu
+
+
+source "drivers/md/Kconfig"
+
+source "drivers/message/fusion/Kconfig"
+
+source "drivers/ieee1394/Kconfig"
+
+source "drivers/message/i2o/Kconfig"
+
+source "net/Kconfig"
+
+
+menu "Network device support"
+	depends on NET
+
+config NETDEVICES
+	bool "Network device support"
+	---help---
+	  You can say N here if you don't intend to connect your Linux box to
+	  any other computer at all or if all your connections will be over a
+	  telephone line with a modem either via UUCP (UUCP is a protocol to
+	  forward mail and news between unix hosts over telephone lines; read
+	  the UUCP-HOWTO, available from
+	  <http://www.linuxdoc.org/docs.html#howto>) or dialing up a shell
+	  account or a BBS, even using term (term is a program which gives you
+	  almost full Internet connectivity if you have a regular dial up
+	  shell account on some Internet connected Unix computer. Read
+	  <http://www.bart.nl/~patrickr/term-howto/Term-HOWTO.html>).
+
+	  You'll have to say Y if your computer contains a network card that
+	  you want to use under Linux (make sure you know its name because you
+	  will be asked for it and read the Ethernet-HOWTO (especially if you
+	  plan to use more than one network card under Linux)) or if you want
+	  to use SLIP (Serial Line Internet Protocol is the protocol used to
+	  send Internet traffic over telephone lines or null modem cables) or
+	  CSLIP (compressed SLIP) or PPP (Point to Point Protocol, a better
+	  and newer replacement for SLIP) or PLIP (Parallel Line Internet
+	  Protocol is mainly used to create a mini network by connecting the
+	  parallel ports of two local machines) or AX.25/KISS (protocol for
+	  sending Internet traffic over amateur radio links).
+
+	  Make sure to read the NET-3-HOWTO. Eventually, you will have to read
+	  Olaf Kirch's excellent and free book "Network Administrator's
+	  Guide", to be found in <http://www.linuxdoc.org/docs.html#guide>. If
+	  unsure, say Y.
+
+source "drivers/net/Kconfig"
+
+source "drivers/atm/Kconfig"
+
+endmenu
+
+source "net/ax25/Kconfig"
+
+source "net/irda/Kconfig"
+
+source "drivers/isdn/Kconfig"
+
+source "drivers/telephony/Kconfig"
+
+#
+# input before char - char/joystick depends on it. As does USB.
+#
+source "drivers/input/Kconfig"
+
+source "drivers/char/Kconfig"
+
+#source drivers/misc/Config.in
+source "drivers/media/Kconfig"
+
+source "fs/Kconfig"
+
+
+menu "Console drivers"
+	depends on VT
+
+config VGA_CONSOLE
+	bool "VGA text console"
+	help
+	  Saying Y here will allow you to use Linux in text mode through a
+	  display that complies with the generic VGA standard. Virtually
+	  everyone wants that.
+
+	  The program SVGATextMode can be used to utilize SVGA video cards to
+	  their full potential in text mode. Download it from
+	  <ftp://ibiblio.org/pub/Linux/utils/console/>.
+
+	  If unsure, say N.
+
+config VIDEO_SELECT
+	bool "Video mode selection support"
+	---help---
+	  This enables support for text mode selection on kernel startup. If
+	  you want to take advantage of some high-resolution text mode your
+	  card's BIOS offers, but the traditional Linux utilities like
+	  SVGATextMode don't, you can say Y here and set the mode using the
+	  "vga=" option from your boot loader (lilo or loadlin) or set
+	  "vga=ask" which brings up a video mode menu on kernel startup. (Try
+	  "man bootparam" or see the documentation of your boot loader about
+	  how to pass options to the kernel.)
+
+	  Read the file <file:Documentation/svga.txt> for more information
+	  about the Video mode selection support. If unsure, say N.
+
+source "drivers/video/Kconfig"
+
+endmenu
+
+
+menu "Sound"
+
+config SOUND
+	tristate "Sound card support"
+	---help---
+	  If you have a sound card in your computer, i.e. if it can say more
+	  than an occasional beep, say Y.  Be sure to have all the information
+	  about your sound card and its configuration down (I/O port,
+	  interrupt and DMA channel), because you will be asked for it.
+
+	  You want to read the Sound-HOWTO, available from
+	  <http://www.linuxdoc.org/docs.html#howto>. General information about
+	  the modular sound system is contained in the files
+	  <file:Documentation/sound/Introduction>.  The file
+	  <file:Documentation/sound/README.OSS> contains some slightly
+	  outdated but still useful information as well.
+
+	  If you have a PnP sound card and you want to configure it at boot
+	  time using the ISA PnP tools (read
+	  <http://www.roestock.demon.co.uk/isapnptools/>), then you need to
+	  compile the sound card support as a module ( = code which can be
+	  inserted in and removed from the running kernel whenever you want)
+	  and load that module after the PnP configuration is finished.  To do
+	  this, say M here and read <file:Documentation/modules.txt> as well
+	  as <file:Documentation/sound/README.modules>; the module will be
+	  called soundcore.o.
+
+	  I'm told that even without a sound card, you can make your computer
+	  say more than an occasional beep, by programming the PC speaker.
+	  Kernel patches and supporting utilities to do that are in the pcsp
+	  package, available at <ftp://ftp.infradead.org/pub/pcsp/>.
+
+source "sound/Kconfig"
+
+endmenu
+
+source "drivers/usb/Kconfig"
+
+source "net/bluetooth/Kconfig"
+
+
+menu "Kernel hacking"
+
+config FULLDEBUG
+	bool "Full Symbolic/Source Debugging support"
+	help
+	  Enable debuging symbols on kernel build.
+
+config MAGIC_SYSRQ
+	bool "Magic SysRq key"
+	help
+	  Enables console device to interprent special characters as
+	  commands to dump state information.
+
+config HIGHPROFILE
+	bool "Use fast second timer for profiling"
+	help
+	  Use a fast secondary clock to produce profiling information.
+
+config DUMPTOFLASH
+	bool "Panic/Dump to FLASH"
+	depends on COLDFIRE
+	help
+	  Dump any panic of trap output into a flash memory segment
+	  for later analysis.
+
+config NO_KERNEL_MSG
+	bool "Suppress Kernel BUG Messages"
+	help
+	  Do not output any debug BUG messages within the kernel.
+
+config BDM_DISABLE
+	bool "Disable BDM signals"
+	depends on (EXPERIMENTAL && COLDFIRE)
+	help
+	  Disable the CPU's BDM signals.
+
+endmenu
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
+
diff -Nru a/arch/m68knommu/Makefile b/arch/m68knommu/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/Makefile	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,108 @@
+#
+# arch/m68knommu/Makefile
+#
+# 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.
+#
+# (C) Copyright 2002, Greg Ungerer <gerg@snapgear.com>
+#
+
+platform-$(CONFIG_M68328)	:= 68328
+platform-$(CONFIG_M68EZ328)	:= 68EZ328
+platform-$(CONFIG_M68VZ328)	:= 68VZ328
+platform-$(CONFIG_M68360)	:= 68360
+platform-$(CONFIG_M5206)	:= 5206
+platform-$(CONFIG_M5206e)	:= 5206e
+platform-$(CONFIG_M5249)	:= 5249
+platform-$(CONFIG_M5272)	:= 5272
+platform-$(CONFIG_M5307)	:= 5307
+platform-$(CONFIG_M5407)	:= 5407
+PLATFORM := $(platform-y)
+
+board-$(CONFIG_PILOT)		:= pilot
+board-$(CONFIG_UCSIMM)		:= ucsimm
+board-$(CONFIG_UCDIMM)		:= ucdimm
+board-$(CONFIG_UCQUICC)		:= uCquicc
+board-$(CONFIG_DRAGEN2)		:= de2
+board-$(CONFIG_ARNEWSH)		:= ARNEWSH
+board-$(CONFIG_MOTOROLA)	:= MOTOROLA
+board-$(CONFIG_ELITE)		:= eLITE
+board-$(CONFIG_eLIA)		:= eLIA
+board-$(CONFIG_NETtel)		:= NETtel
+board-$(CONFIG_SECUREEDGEMP3)	:= MP3
+board-$(CONFIG_CLEOPATRA)	:= CLEOPATRA
+BOARD := $(board-y)
+
+model-$(CONFIG_RAMKERNEL)	:= ram
+model-$(CONFIG_ROMKERNEL)	:= rom
+model-$(CONFIG_HIMEMKERNEL)	:= himem
+MODEL := $(model-y)
+
+#
+# Some code support is grouped together for a common cpu-subclass (for
+# example all ColdFire cpu's are very similar). Determine the sub-class
+# for the selected cpu. ONLY need to define this for the non-core member
+# of the family.
+#
+cpuclass-$(CONFIG_M5206)	:= 5307
+cpuclass-$(CONFIG_M5206e)	:= 5307
+cpuclass-$(CONFIG_M5249)	:= 5307
+cpuclass-$(CONFIG_M5272)	:= 5307
+cpuclass-$(CONFIG_M5407)	:= 5307
+cpuclass-$(CONFIG_M68EZ328)	:= 68328
+cpuclass-$(CONFIG_M68VZ328)	:= 68328
+CPUCLASS := $(cpuclass-y)
+CLASSDIR := arch/m68knommu/platform/$(cpuclass-y)/
+
+export PLATFORM BOARD MODEL CPUCLASS
+
+#
+# Some CFLAG additions based on specific CPU type.
+#
+cflags-$(CONFIG_M5206)		:= -m5200 -Wa,-S -Wa,-m5200
+cflags-$(CONFIG_M5206e)		:= -m5200 -Wa,-S -Wa,-m5200
+cflags-$(CONFIG_M5249)		:= -m5200 -Wa,-S -Wa,-m5200
+cflags-$(CONFIG_M5272)		:= -m5307 -Wa,-S -Wa,-m5307
+cflags-$(CONFIG_M5307)		:= -m5307 -Wa,-S -Wa,-m5307
+cflags-$(CONFIG_M5407)		:= -m5200 -Wa,-S -Wa,-m5200
+cflags-$(CONFIG_M68328)		:= -m68000
+cflags-$(CONFIG_M68EZ328)	:= -m68000
+cflags-$(CONFIG_M68VZ328)	:= -m68000
+cflags-$(CONFIG_M68360)		:= -m68332
+
+AFLAGS += $(cflags-y)
+
+CFLAGS += $(cflags-y)
+CFLAGS += -fno-builtin
+CFLAGS += -O2 -g
+CFLAGS += -D__linux__
+CFLAGS += -DUTS_SYSNAME=\"uClinux\"
+
+HEAD := arch/m68knommu/platform/$(platform-y)/$(board-y)/crt0_$(model-y).o
+
+clean-files := include/asm-$(ARCH)/asm-offsets.h.tmp \
+	       include/asm-$(ARCH)/asm-offsets.h \
+	       arch/$(ARCH)/kernel/asm-offsets.s
+
+core-y	+= arch/m68knommu/kernel/ \
+	   arch/m68knommu/mm/ \
+	   $(CLASSDIR) \
+	   arch/m68knommu/platform/$(PLATFORM)/
+libs-y	+= arch/m68knommu/lib/
+
+include $(TOPDIR)/Rules.make
+
+prepare: include/asm-$(ARCH)/asm-offsets.h
+
+archmrproper:
+
+archclean:
+	$(call descend arch/$(ARCH)/boot, subdirclean)
+
+include/asm-$(ARCH)/asm-offsets.h: arch/$(ARCH)/kernel/asm-offsets.s \
+				   include/asm include/linux/version.h \
+				   include/config/MARKER
+	@echo -n '  Generating $@'
+	@$(generate-asm-offsets.h) < $< > $@.tmp
+	@$(update-if-changed)
diff -Nru a/arch/m68knommu/defconfig b/arch/m68knommu/defconfig
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/defconfig	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,538 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+# CONFIG_MMU is not set
+# CONFIG_SWAP is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Processor type and features
+#
+# CONFIG_M68000 is not set
+# CONFIG_M68EN302 is not set
+# CONFIG_M68328 is not set
+# CONFIG_M68EZ328 is not set
+# CONFIG_M68VZ328 is not set
+# CONFIG_M68332 is not set
+# CONFIG_M68360 is not set
+# CONFIG_M5204 is not set
+# CONFIG_M5206 is not set
+# CONFIG_M5206e is not set
+# CONFIG_M5249 is not set
+CONFIG_M5272=y
+# CONFIG_M5307 is not set
+# CONFIG_M5407 is not set
+CONFIG_COLDFIRE=y
+# CONFIG_CLOCK_AUTO is not set
+# CONFIG_CLOCK_11MHz is not set
+# CONFIG_CLOCK_16MHz is not set
+# CONFIG_CLOCK_20MHz is not set
+# CONFIG_CLOCK_24MHz is not set
+# CONFIG_CLOCK_25MHz is not set
+# CONFIG_CLOCK_33MHz is not set
+# CONFIG_CLOCK_40MHz is not set
+# CONFIG_CLOCK_45MHz is not set
+# CONFIG_CLOCK_48MHz is not set
+# CONFIG_CLOCK_50MHz is not set
+# CONFIG_CLOCK_54MHz is not set
+# CONFIG_CLOCK_60MHz is not set
+CONFIG_CLOCK_66MHz=y
+# CONFIG_CLOCK_70MHz is not set
+# CONFIG_CLOCK_140MHz is not set
+CONFIG_M5272C3=y
+# CONFIG_GILBARCONAP is not set
+# CONFIG_NETtel is not set
+# CONFIG_SNAPGEAR is not set
+# CONFIG_ROMFS_FROM_ROM is not set
+CONFIG_MOTOROLA=y
+# CONFIG_LARGE_ALLOCS is not set
+# CONFIG_RAMAUTO is not set
+# CONFIG_RAM4MB is not set
+# CONFIG_RAM8MB is not set
+CONFIG_RAM16MB=y
+# CONFIG_RAM32MB is not set
+CONFIG_AUTOBIT=y
+# CONFIG_RAM8BIT is not set
+# CONFIG_RAM16BIT is not set
+# CONFIG_RAM32bit is not set
+CONFIG_RAMKERNEL=y
+# CONFIG_ROMKERNEL is not set
+# CONFIG_HIMEMKERNEL is not set
+
+#
+# General setup
+#
+CONFIG_NET=y
+# CONFIG_PCI is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+# CONFIG_KCORE_ELF is not set
+CONFIG_KCORE_AOUT=y
+CONFIG_BINFMT_FLAT=y
+# CONFIG_BINFMT_ZFLAT is not set
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_ELF is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+# CONFIG_MTD_GEN_PROBE is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+# CONFIG_MTD_CFI_AMDSTD is not set
+CONFIG_MTD_RAM=y
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PCMCIA is not set
+CONFIG_MTD_UCLINUX=y
+# CONFIG_MTD_SNAPGEARuC is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_PNP_NAMES is not set
+# CONFIG_PNP_DEBUG is not set
+# CONFIG_ISAPNP is not set
+# CONFIG_PNPBIOS is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_DEV_BLKMEM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+
+#
+#    SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IPV6_SCTP__=y
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_LLC is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_SUNLANCE 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
+# CONFIG_NET_VENDOR_RACAL is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+CONFIG_FEC=y
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000_NAPI 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
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+# CONFIG_PPP_ASYNC is not set
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN_BOOL is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_RESETSWITCH is not set
+# CONFIG_LEDMAN is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_CS is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_RSA is not set
+CONFIG_SERIAL_COLDFIRE=y
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_SCx200_GPIO is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_QFMT_V1 is not set
+# CONFIG_QFMT_V2 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 is not set
+# CONFIG_JBD is not set
+# 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=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_DEBUG is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+CONFIG_ROMFS_FS=y
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_QUOTA is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+# CONFIG_NFS_FS is not set
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_V4 is not set
+# CONFIG_NFSD_TCP is not set
+# CONFIG_SUNRPC is not set
+# CONFIG_LOCKD is not set
+# CONFIG_EXPORTFS is not set
+# CONFIG_CIFS is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_FULLDEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_PROFILE is not set
+# CONFIG_DUMPTOFLASH is not set
+# CONFIG_NO_KERNEL_MSG is not set
+# CONFIG_SMALL_TASKS is not set
+# CONFIG_BDM_DISABLE is not set
+
+#
+# Security options
+#
+CONFIG_SECURITY_CAPABILITIES=y
+
+#
+# Library routines
+#
+# CONFIG_CRC32 is not set
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -Nru a/arch/m68knommu/kernel/Makefile b/arch/m68knommu/kernel/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/kernel/Makefile	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,13 @@
+#
+# Makefile for arch/m68knommu/kernel.
+#
+
+export-objs := m68k_ksyms.o
+
+obj-y += init_task.o ints.o m68k_ksyms.o process.o ptrace.o semaphore.o \
+	 setup.o signal.o syscalltable.o sys_m68k.o time.o traps.o
+
+obj-$(CONFIG_COMEMPCI)	+= comempci.o
+
+include $(TOPDIR)/Rules.make
+
diff -Nru a/arch/m68knommu/kernel/asm-offsets.c b/arch/m68knommu/kernel/asm-offsets.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/kernel/asm-offsets.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,85 @@
+/*
+ * This program is used to generate definitions needed by
+ * assembly language modules.
+ *
+ * We use the technique used in the OSF Mach kernel code:
+ * generate asm statements containing #defines,
+ * compile this file to assembler, and then extract the
+ * #defines from the assembly-language output.
+ */
+
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/hardirq.h>
+
+#define DEFINE(sym, val) \
+        asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+#define BLANK() asm volatile("\n->" : : )
+
+int main(void)
+{
+	/* offsets into the task struct */
+	DEFINE(TASK_STATE, offsetof(struct task_struct, state));
+	DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
+	DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
+	DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked));
+	DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
+	DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, thread_info));
+	DEFINE(TASK_MM, offsetof(struct task_struct, mm));
+	DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
+
+	/* offsets into the irq_cpustat_t struct */
+	DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
+
+	/* offsets into the thread struct */
+	DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
+	DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));
+	DEFINE(THREAD_SR, offsetof(struct thread_struct, sr));
+	DEFINE(THREAD_FS, offsetof(struct thread_struct, fs));
+	DEFINE(THREAD_CRP, offsetof(struct thread_struct, crp));
+	DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0));
+	DEFINE(THREAD_FPREG, offsetof(struct thread_struct, fp));
+	DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl));
+	DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate));
+
+	/* offsets into the pt_regs */
+	DEFINE(PT_D0, offsetof(struct pt_regs, d0));
+	DEFINE(PT_ORIG_D0, offsetof(struct pt_regs, orig_d0));
+	DEFINE(PT_D1, offsetof(struct pt_regs, d1));
+	DEFINE(PT_D2, offsetof(struct pt_regs, d2));
+	DEFINE(PT_D3, offsetof(struct pt_regs, d3));
+	DEFINE(PT_D4, offsetof(struct pt_regs, d4));
+	DEFINE(PT_D5, offsetof(struct pt_regs, d5));
+	DEFINE(PT_A0, offsetof(struct pt_regs, a0));
+	DEFINE(PT_A1, offsetof(struct pt_regs, a1));
+	DEFINE(PT_A2, offsetof(struct pt_regs, a2));
+	DEFINE(PT_PC, offsetof(struct pt_regs, pc));
+	DEFINE(PT_SR, offsetof(struct pt_regs, sr));
+	/* bitfields are a bit difficult */
+	DEFINE(PT_VECTOR, offsetof(struct pt_regs, pc) + 4);
+
+#ifndef CONFIG_COLDFIRE
+	/* offsets into the irq_handler struct */
+	DEFINE(IRQ_HANDLER, offsetof(struct irq_node, handler));
+	DEFINE(IRQ_DEVID, offsetof(struct irq_node, dev_id));
+	DEFINE(IRQ_NEXT, offsetof(struct irq_node, next));
+#endif
+
+	/* offsets into the kernel_stat struct */
+	DEFINE(STAT_IRQ, offsetof(struct kernel_stat, irqs));
+
+	/* signal defines */
+	DEFINE(SIGSEGV, SIGSEGV);
+	DEFINE(SEGV_MAPERR, SEGV_MAPERR);
+	DEFINE(SIGTRAP, SIGTRAP);
+	DEFINE(TRAP_TRACE, TRAP_TRACE);
+
+	DEFINE(PT_PTRACED, PT_PTRACED);
+	DEFINE(PT_DTRACE, PT_DTRACE);
+
+	return 0;
+}
diff -Nru a/arch/m68knommu/kernel/comempci.c b/arch/m68knommu/kernel/comempci.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/kernel/comempci.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,1171 @@
+/*****************************************************************************/
+
+/*
+ *	comemlite.c -- PCI access code for embedded CO-MEM Lite PCI controller.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ *	(C) Copyright 2000, Lineo (www.lineo.com)
+ */
+
+/*****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/irq.h>
+#include <asm/anchor.h>
+
+#ifdef CONFIG_eLIA
+#include <asm/elia.h>
+#endif
+
+/*****************************************************************************/
+
+/*
+ *	Debug configuration defines. DEBUGRES sets debugging output for
+ *	the resource allocation phase. DEBUGPCI traces on pcibios_ function
+ *	calls, and DEBUGIO traces all accesses to devices on the PCI bus.
+ */
+/*#define	DEBUGRES	1*/
+/*#define	DEBUGPCI	1*/
+/*#define	DEBUGIO		1*/
+
+/*****************************************************************************/
+
+/*
+ *	PCI markers for bus present and active slots.
+ */
+int		pci_bus_is_present = 0;
+unsigned long	pci_slotmask = 0;
+
+/*
+ *	We may or may not need to swap the bytes of PCI bus tranfers.
+ *	The endianess is re-roder automatically by the CO-MEM, but it
+ *	will get the wrong byte order for a pure data stream.
+ */
+#define	pci_byteswap	0
+
+
+/*
+ *	Resource tracking. The CO-MEM part creates a virtual address
+ *	space that all the PCI devices live in - it is not in any way
+ *	directly mapped into the ColdFire address space. So we can
+ *	really assign any resources we like to devices, as long as
+ *	they do not clash with other PCI devices.
+ */
+unsigned int	pci_iobase = 0x100;		/* Arbitary start address */
+unsigned int	pci_membase = 0x00010000;	/* Arbitary start address */
+
+#define	PCI_MINIO	0x100			/* 256 byte minimum I/O */
+#define	PCI_MINMEM	0x00010000		/* 64k minimum chunk */
+
+/*
+ *	The CO-MEM's shared memory segment is visible inside the PCI
+ *	memory address space. We need to keep track of the address that
+ *	this is mapped at, to setup the bus masters pointers.
+ */
+unsigned int	pci_shmemaddr;
+
+/*****************************************************************************/
+
+void 		pci_interrupt(int irq, void *id, struct pt_regs *fp);
+
+/*****************************************************************************/
+
+/*
+ *	Some platforms have custom ways of reseting the PCI bus.
+ */
+
+void pci_resetbus(void)
+{
+#ifdef CONFIG_eLIA
+	int	i;
+
+#ifdef DEBUGPCI
+	printk("pci_resetbus()\n");
+#endif
+
+	*((volatile unsigned short *) (MCF_MBAR+MCFSIM_PADDR)) |= eLIA_PCIRESET;
+	for (i = 0; (i < 1000); i++) {
+		*((volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT)) = 
+			(ppdata | eLIA_PCIRESET);
+	}
+
+
+	*((volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT)) = ppdata;
+#endif
+}
+
+/*****************************************************************************/
+
+int pcibios_assignres(int slot)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned char	*ip;
+	unsigned int		idsel, addr, val, align, i;
+	int			bar;
+
+#ifdef DEBUGPCI
+	printk("pcibios_assignres(slot=%x)\n", slot);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	idsel = COMEM_DA_ADDR(0x1 << (slot + 16));
+
+	/* Try to assign resource to each BAR */
+	for (bar = 0; (bar < 6); bar++) {
+		addr = COMEM_PCIBUS + PCI_BASE_ADDRESS_0 + (bar * 4);
+		rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGRD | idsel;
+		val = rp[LREG(addr)];
+#ifdef DEBUGRES
+		printk("-----------------------------------"
+			"-------------------------------------\n");
+		printk("BAR[%d]: read=%08x ", bar, val);
+#endif
+
+		rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGWR | idsel;
+		rp[LREG(addr)] = 0xffffffff;
+
+		rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGRD | idsel;
+		val = rp[LREG(addr)];
+#ifdef DEBUGRES
+		printk("write=%08x ", val);
+#endif
+		if (val == 0) {
+#ifdef DEBUGRES
+			printk("\n");
+#endif
+			continue;
+		}
+
+		/* Determine space required by BAR */
+		/* FIXME: this should go backwords from 0x80000000... */
+		for (i = 0; (i < 32); i++) {
+			if ((0x1 << i) & (val & 0xfffffffc))
+				break;
+		}
+
+#ifdef DEBUGRES
+		printk("size=%08x(%d)\n", (0x1 << i), i);
+#endif
+		i = 0x1 << i;
+
+		/* Assign a resource */
+		if (val & PCI_BASE_ADDRESS_SPACE_IO) {
+			if (i < PCI_MINIO)
+				i = PCI_MINIO;
+#ifdef DEBUGRES
+			printk("BAR[%d]: IO size=%08x iobase=%08x\n",
+				bar, i, pci_iobase);
+#endif
+			if (i > 0xffff) {
+				/* Invalid size?? */
+				val = 0 | PCI_BASE_ADDRESS_SPACE_IO;
+#ifdef DEBUGRES
+				printk("BAR[%d]: too big for IO??\n", bar);
+#endif
+			} else {
+				/* Check for un-alignment */
+				if ((align = pci_iobase % i))
+					pci_iobase += (i - align);
+				val = pci_iobase | PCI_BASE_ADDRESS_SPACE_IO;
+				pci_iobase += i;
+			}
+		} else {
+			if (i < PCI_MINMEM)
+				i = PCI_MINMEM;
+#ifdef DEBUGRES
+			printk("BAR[%d]: MEMORY size=%08x membase=%08x\n",
+				bar, i, pci_membase);
+#endif
+			/* Check for un-alignment */
+			if ((align = pci_membase % i))
+				pci_membase += (i - align);
+			val = pci_membase | PCI_BASE_ADDRESS_SPACE_MEMORY;
+			pci_membase += i;
+		}
+
+		/* Write resource back into BAR register */
+		rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGWR | idsel;
+		rp[LREG(addr)] = val;
+#ifdef DEBUGRES
+		printk("BAR[%d]: assigned bar=%08x\n", bar, val);
+#endif
+	}
+
+#ifdef DEBUGRES
+	printk("-----------------------------------"
+			"-------------------------------------\n");
+#endif
+
+	/* Assign IRQ if one is wanted... */
+	ip = (volatile unsigned char *) (COMEM_BASE + COMEM_PCIBUS);
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGRD | idsel;
+
+	addr = (PCI_INTERRUPT_PIN & 0xfc) + (~PCI_INTERRUPT_PIN & 0x03);
+	if (ip[addr]) {
+		rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGWR | idsel;
+		addr = (PCI_INTERRUPT_LINE & 0xfc)+(~PCI_INTERRUPT_LINE & 0x03);
+		ip[addr] = 25;
+#ifdef DEBUGRES
+		printk("IRQ LINE=25\n");
+#endif
+	}
+
+	return(0);
+}
+
+/*****************************************************************************/
+
+int pcibios_enable(int slot)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned short	*wp;
+	unsigned int		idsel, addr;
+	unsigned short		cmd;
+
+#ifdef DEBUGPCI
+	printk("pcibios_enbale(slot=%x)\n", slot);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	wp = (volatile unsigned short *) COMEM_BASE;
+	idsel = COMEM_DA_ADDR(0x1 << (slot + 16));
+
+	/* Get current command settings */
+	addr = COMEM_PCIBUS + PCI_COMMAND;
+	addr = (addr & ~0x3) + (~addr & 0x02);
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGRD | idsel;
+	cmd = wp[WREG(addr)];
+	/*val = ((val & 0xff) << 8) | ((val >> 8) & 0xff);*/
+
+	/* Enable I/O and memory accesses to this device */
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGWR | idsel;
+	cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
+	wp[WREG(addr)] = cmd;
+
+	return(0);
+}
+
+/*****************************************************************************/
+
+unsigned long pcibios_init(unsigned long mem_start, unsigned long mem_end)
+{
+	volatile unsigned long	*rp;
+	unsigned long		sel, id;
+	int			slot;
+
+#ifdef DEBUGPCI
+	printk("pcibios_init()\n");
+#endif
+
+	pci_resetbus();
+
+	/*
+	 *	Do some sort of basic check to see if the CO-MEM part
+	 *	is present... This works ok, but I think we really need
+	 *	something better...
+	 */
+	rp = (volatile unsigned long *) COMEM_BASE;
+	if ((rp[LREG(COMEM_LBUSCFG)] & 0xff) != 0x50) {
+		printk("PCI: no PCI bus present\n");
+		return(mem_start);
+	}
+
+#ifdef COMEM_BRIDGEDEV
+	/*
+	 *	Setup the PCI bridge device first. It needs resources too,
+	 *	so that bus masters can get to its shared memory.
+	 */
+	slot = COMEM_BRIDGEDEV;
+	sel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << (slot + 16));
+	rp[LREG(COMEM_DAHBASE)] = sel;
+	rp[LREG(COMEM_PCIBUS)] = 0; /* Clear bus */
+	id = rp[LREG(COMEM_PCIBUS)];
+	if ((id == 0) || ((id & 0xffff0000) == (sel & 0xffff0000))) {
+		printk("PCI: no PCI bus bridge present\n");
+		return(mem_start);
+	}
+
+	printk("PCI: bridge device at slot=%d id=%08x\n", slot, (int) id);
+	pci_slotmask |= 0x1 << slot;
+	pci_shmemaddr = pci_membase;
+	pcibios_assignres(slot);
+	pcibios_enable(slot);
+#endif
+
+	pci_bus_is_present = 1;
+
+	/*
+	 *	Do a quick scan of the PCI bus and see what is here.
+	 */
+	for (slot = COMEM_MINDEV; (slot <= COMEM_MAXDEV); slot++) {
+		sel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << (slot + 16));
+		rp[LREG(COMEM_DAHBASE)] = sel;
+		rp[LREG(COMEM_PCIBUS)] = 0; /* Clear bus */
+		id = rp[LREG(COMEM_PCIBUS)];
+		if ((id != 0) && ((id & 0xffff0000) != (sel & 0xffff0000))) {
+			printk("PCI: slot=%d id=%08x\n", slot, (int) id);
+			pci_slotmask |= 0x1 << slot;
+			pcibios_assignres(slot);
+			pcibios_enable(slot);
+		}
+	}
+
+	/* Get PCI irq for local vectoring */
+	if (request_irq(COMEM_IRQ, pci_interrupt, 0, "PCI bridge", NULL)) {
+		printk("PCI: failed to acquire interrupt %d\n", COMEM_IRQ);
+	} else {
+		mcf_autovector(COMEM_IRQ);
+	}
+
+	return(mem_start);
+}
+
+/*****************************************************************************/
+
+unsigned long pcibios_fixup(unsigned long mem_start, unsigned long mem_end)
+{
+	return(mem_start);
+}
+
+/*****************************************************************************/
+
+int pcibios_present(void)
+{
+	return(pci_bus_is_present);
+}
+
+/*****************************************************************************/
+
+int pcibios_read_config_dword(unsigned char bus, unsigned char dev,
+	unsigned char offset, unsigned int *val)
+{
+	volatile unsigned long	*rp;
+	unsigned long		idsel, fnsel;
+
+#ifdef DEBUGPCI
+	printk("pcibios_read_config_dword(bus=%x,dev=%x,offset=%x,val=%x)\n",
+		 bus, dev, offset, val);
+#endif
+
+	if (bus || ((pci_slotmask & (0x1 << PCI_SLOT(dev))) == 0)) {
+		*val = 0xffffffff;
+		return(PCIBIOS_SUCCESSFUL);
+	}
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	idsel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << ((dev >> 3) + 16));
+	fnsel = (dev & 0x7) << 8;
+
+	rp[LREG(COMEM_DAHBASE)] = idsel;
+	*val = rp[LREG(COMEM_PCIBUS + (offset & 0xfc) + fnsel)];
+
+#if 1
+	/* If we get back what we wrote, then nothing there */
+	/* This is pretty dodgy, but, hey, what else do we do?? */
+	if (!offset && (*val == ((idsel & 0xfffff000) | (offset & 0x00000fff))))
+		*val = 0xffffffff;
+#endif
+
+	return(PCIBIOS_SUCCESSFUL);
+}
+
+/*****************************************************************************/
+
+int pcibios_read_config_word(unsigned char bus, unsigned char dev,
+	unsigned char offset, unsigned short *val)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned short	*bp;
+	unsigned long		idsel, fnsel;
+	unsigned char		swapoffset;
+
+#ifdef DEBUGPCI
+	printk("pcibios_read_config_word(bus=%x,dev=%x,offset=%x)\n",
+		bus, dev, offset);
+#endif
+
+	if (bus || ((pci_slotmask & (0x1 << PCI_SLOT(dev))) == 0)) {
+		*val = 0xffff;
+		return(PCIBIOS_SUCCESSFUL);
+	}
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	bp = (volatile unsigned short *) COMEM_BASE;
+	idsel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << ((dev >> 3) + 16));
+	fnsel = (dev & 0x7) << 8;
+	swapoffset = (offset & 0xfc) + (~offset & 0x02);
+
+	rp[LREG(COMEM_DAHBASE)] = idsel;
+	*val = bp[WREG(COMEM_PCIBUS + swapoffset + fnsel)];
+
+	return(PCIBIOS_SUCCESSFUL);
+}
+
+/*****************************************************************************/
+
+int pcibios_read_config_byte(unsigned char bus, unsigned char dev,
+	unsigned char offset, unsigned char *val)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned char	*bp;
+	unsigned long		idsel, fnsel;
+	unsigned char		swapoffset;
+
+#ifdef DEBUGPCI
+	printk("pcibios_read_config_byte(bus=%x,dev=%x,offset=%x)\n",
+		bus, dev, offset);
+#endif
+
+	if (bus || ((pci_slotmask & (0x1 << PCI_SLOT(dev))) == 0)) {
+		*val = 0xff;
+		return(PCIBIOS_SUCCESSFUL);
+	}
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	bp = (volatile unsigned char *) COMEM_BASE;
+	idsel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << ((dev >> 3) + 16));
+	fnsel = (dev & 0x7) << 8;
+	swapoffset = (offset & 0xfc) + (~offset & 0x03);
+
+	rp[LREG(COMEM_DAHBASE)] = idsel;
+	*val = bp[(COMEM_PCIBUS + swapoffset + fnsel)];
+
+	return(PCIBIOS_SUCCESSFUL);
+}
+
+/*****************************************************************************/
+
+int pcibios_write_config_dword(unsigned char bus, unsigned char dev,
+	unsigned char offset, unsigned int val)
+{
+	volatile unsigned long	*rp;
+	unsigned long		idsel, fnsel;
+
+#ifdef DEBUGPCI
+	printk("pcibios_write_config_dword(bus=%x,dev=%x,offset=%x,val=%x)\n",
+		 bus, dev, offset, val);
+#endif
+
+	if (bus || ((pci_slotmask & (0x1 << PCI_SLOT(dev))) == 0))
+		return(PCIBIOS_SUCCESSFUL);
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	idsel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << ((dev >> 3) + 16));
+	fnsel = (dev & 0x7) << 8;
+
+	rp[LREG(COMEM_DAHBASE)] = idsel;
+	rp[LREG(COMEM_PCIBUS + (offset & 0xfc) + fnsel)] = val;
+	return(PCIBIOS_SUCCESSFUL);
+}
+
+/*****************************************************************************/
+
+int pcibios_write_config_word(unsigned char bus, unsigned char dev,
+	unsigned char offset, unsigned short val)
+{
+
+	volatile unsigned long	*rp;
+	volatile unsigned short	*bp;
+	unsigned long		idsel, fnsel;
+	unsigned char		swapoffset;
+
+#ifdef DEBUGPCI
+	printk("pcibios_write_config_word(bus=%x,dev=%x,offset=%x,val=%x)\n",
+		 bus, dev, offset, val);
+#endif
+
+	if (bus || ((pci_slotmask & (0x1 << PCI_SLOT(dev))) == 0))
+		return(PCIBIOS_SUCCESSFUL);
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	bp = (volatile unsigned short *) COMEM_BASE;
+	idsel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << ((dev >> 3) + 16));
+	fnsel = (dev & 0x7) << 8;
+	swapoffset = (offset & 0xfc) + (~offset & 0x02);
+
+	rp[LREG(COMEM_DAHBASE)] = idsel;
+	bp[WREG(COMEM_PCIBUS + swapoffset + fnsel)] = val;
+	return(PCIBIOS_SUCCESSFUL);
+}
+
+/*****************************************************************************/
+
+int pcibios_write_config_byte(unsigned char bus, unsigned char dev,
+	unsigned char offset, unsigned char val)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned char	*bp;
+	unsigned long		idsel, fnsel;
+	unsigned char		swapoffset;
+
+#ifdef DEBUGPCI
+	printk("pcibios_write_config_byte(bus=%x,dev=%x,offset=%x,val=%x)\n",
+		 bus, dev, offset, val);
+#endif
+
+	if (bus || ((pci_slotmask & (0x1 << PCI_SLOT(dev))) == 0))
+		return(PCIBIOS_SUCCESSFUL);
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	bp = (volatile unsigned char *) COMEM_BASE;
+	idsel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << ((dev >> 3) + 16));
+	fnsel = (dev & 0x7) << 8;
+	swapoffset = (offset & 0xfc) + (~offset & 0x03);
+
+	rp[LREG(COMEM_DAHBASE)] = idsel;
+	bp[(COMEM_PCIBUS + swapoffset + fnsel)] = val;
+	return(PCIBIOS_SUCCESSFUL);
+}
+
+/*****************************************************************************/
+
+int pcibios_find_device(unsigned short vendor, unsigned short devid,
+	unsigned short index, unsigned char *bus, unsigned char *dev)
+{
+	unsigned int	vendev, val;
+	unsigned char	devnr;
+
+#ifdef DEBUGPCI
+	printk("pcibios_find_device(vendor=%04x,devid=%04x,index=%d)\n",
+		vendor, devid, index);
+#endif
+
+	if (vendor == 0xffff)
+		return(PCIBIOS_BAD_VENDOR_ID);
+
+	vendev = (devid << 16) | vendor;
+	for (devnr = 0; (devnr < 32); devnr++) {
+		pcibios_read_config_dword(0, devnr, PCI_VENDOR_ID, &val);
+		if (vendev == val) {
+			if (index-- == 0) {
+				*bus = 0;
+				*dev = devnr;
+				return(PCIBIOS_SUCCESSFUL);
+			}
+		}
+	}
+
+	return(PCIBIOS_DEVICE_NOT_FOUND);
+}
+
+/*****************************************************************************/
+
+int pcibios_find_class(unsigned int class, unsigned short index,
+	unsigned char *bus, unsigned char *dev)
+{
+	unsigned int	val;
+	unsigned char	devnr;
+
+#ifdef DEBUGPCI
+	printk("pcibios_find_class(class=%04x,index=%d)\n", class, index);
+#endif
+
+	/* FIXME: this ignores multi-function devices... */
+	for (devnr = 0; (devnr < 128); devnr += 8) {
+		pcibios_read_config_dword(0, devnr, PCI_CLASS_REVISION, &val);
+		if ((val >> 8) == class) {
+			if (index-- == 0) {
+				*bus = 0;
+				*dev = devnr;
+				return(PCIBIOS_SUCCESSFUL);
+			}
+		}
+	}
+
+	return(PCIBIOS_DEVICE_NOT_FOUND);
+}
+
+/*****************************************************************************/
+
+/*
+ *	Local routines to interrcept the standard I/O and vector handling
+ *	code. Don't include this 'till now - initialization code above needs
+ *	access to the real code too.
+ */
+#include <asm/mcfpci.h>
+
+/*****************************************************************************/
+
+void pci_outb(unsigned char val, unsigned int addr)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned char	*bp;
+
+#ifdef DEBUGIO
+	printk("pci_outb(val=%02x,addr=%x)\n", val, addr);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	bp = (volatile unsigned char *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(addr);
+	addr = (addr & ~0x3) + (~addr & 0x03);
+	bp[(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))] = val;
+}
+
+/*****************************************************************************/
+
+void pci_outw(unsigned short val, unsigned int addr)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned short	*sp;
+
+#ifdef DEBUGIO
+	printk("pci_outw(val=%04x,addr=%x)", val, addr);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	sp = (volatile unsigned short *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(addr);
+	addr = (addr & ~0x3) + (~addr & 0x02);
+	if (pci_byteswap)
+		val = ((val & 0xff) << 8) | ((val >> 8) & 0xff);
+	sp[WREG(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))] = val;
+}
+
+/*****************************************************************************/
+
+void pci_outl(unsigned int val, unsigned int addr)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned int	*lp;
+
+#ifdef DEBUGIO
+	printk("pci_outl(val=%08x,addr=%x)\n", val, addr);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	lp = (volatile unsigned int *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(addr);
+
+	if (pci_byteswap)
+		val = (val << 24) | ((val & 0x0000ff00) << 8) |
+			((val & 0x00ff0000) >> 8) | (val >> 24);
+
+	lp[LREG(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))] = val;
+}
+
+/*****************************************************************************/
+
+unsigned long	pci_blmask[] = {
+	0x000000e0,
+	0x000000d0,
+	0x000000b0,
+	0x00000070
+};
+
+unsigned char pci_inb(unsigned int addr)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned char	*bp;
+	unsigned long		r;
+	unsigned char		val;
+
+#ifdef DEBUGIO
+	printk("pci_inb(addr=%x)", addr);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	bp = (volatile unsigned char *) COMEM_BASE;
+
+	r = COMEM_DA_IORD | COMEM_DA_ADDR(addr) | pci_blmask[(addr & 0x3)];
+	rp[LREG(COMEM_DAHBASE)] = r;
+
+	addr = (addr & ~0x3) + (~addr & 0x3);
+	val = bp[(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))];
+	return(val);
+}
+
+/*****************************************************************************/
+
+unsigned long	pci_bwmask[] = {
+	0x000000c0,
+	0x000000c0,
+	0x00000030,
+	0x00000030
+};
+
+unsigned short pci_inw(unsigned int addr)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned short	*sp;
+	unsigned long		r;
+	unsigned short		val;
+
+#ifdef DEBUGIO
+	printk("pci_inw(addr=%x)", addr);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	r = COMEM_DA_IORD | COMEM_DA_ADDR(addr) | pci_bwmask[(addr & 0x3)];
+	rp[LREG(COMEM_DAHBASE)] = r;
+
+	sp = (volatile unsigned short *) COMEM_BASE;
+	addr = (addr & ~0x3) + (~addr & 0x02);
+	val = sp[WREG(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))];
+	if (pci_byteswap)
+		val = ((val & 0xff) << 8) | ((val >> 8) & 0xff);
+#ifdef DEBUGIO
+	printk("=%04x\n", val);
+#endif
+	return(val);
+}
+
+/*****************************************************************************/
+
+unsigned int pci_inl(unsigned int addr)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned int	*lp;
+	unsigned int		val;
+
+#ifdef DEBUGIO
+	printk("pci_inl(addr=%x)", addr);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	lp = (volatile unsigned int *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IORD | COMEM_DA_ADDR(addr);
+	val = lp[LREG(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))];
+
+	if (pci_byteswap)
+		val = (val << 24) | ((val & 0x0000ff00) << 8) |
+			((val & 0x00ff0000) >> 8) | (val >> 24);
+
+#ifdef DEBUGIO
+	printk("=%08x\n", val);
+#endif
+	return(val);
+}
+
+/*****************************************************************************/
+
+void pci_outsb(void *addr, void *buf, int len)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned char	*bp;
+	unsigned char		*dp = (unsigned char *) buf;
+	unsigned int		a = (unsigned int) addr;
+
+#ifdef DEBUGIO
+	printk("pci_outsb(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(a);
+
+	a = (a & ~0x3) + (~a & 0x03);
+	bp = (volatile unsigned char *)
+		(COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a));
+
+	while (len--)
+		*bp = *dp++;
+}
+
+/*****************************************************************************/
+
+void pci_outsw(void *addr, void *buf, int len)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned short	*wp;
+	unsigned short		w, *dp = (unsigned short *) buf;
+	unsigned int		a = (unsigned int) addr;
+
+#ifdef DEBUGIO
+	printk("pci_outsw(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(a);
+
+	a = (a & ~0x3) + (~a & 0x2);
+	wp = (volatile unsigned short *)
+		(COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a));
+
+	while (len--) {
+		w = *dp++;
+		if (pci_byteswap)
+			w = ((w & 0xff) << 8) | ((w >> 8) & 0xff);
+		*wp = w;
+	}
+}
+
+/*****************************************************************************/
+
+void pci_outsl(void *addr, void *buf, int len)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned long	*lp;
+	unsigned long		l, *dp = (unsigned long *) buf;
+	unsigned int		a = (unsigned int) addr;
+
+#ifdef DEBUGIO
+	printk("pci_outsl(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(a);
+
+	lp = (volatile unsigned long *)
+		(COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a));
+
+	while (len--) {
+		l = *dp++;
+		if (pci_byteswap)
+			l = (l << 24) | ((l & 0x0000ff00) << 8) |
+				((l & 0x00ff0000) >> 8) | (l >> 24);
+		*lp = l;
+	}
+}
+
+/*****************************************************************************/
+
+void pci_insb(void *addr, void *buf, int len)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned char	*bp;
+	unsigned char		*dp = (unsigned char *) buf;
+	unsigned int		a = (unsigned int) addr;
+
+#ifdef DEBUGIO
+	printk("pci_insb(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IORD | COMEM_DA_ADDR(a);
+
+	a = (a & ~0x3) + (~a & 0x03);
+	bp = (volatile unsigned char *)
+		(COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a));
+
+	while (len--)
+		*dp++ = *bp;
+}
+
+/*****************************************************************************/
+
+void pci_insw(void *addr, void *buf, int len)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned short	*wp;
+	unsigned short		w, *dp = (unsigned short *) buf;
+	unsigned int		a = (unsigned int) addr;
+
+#ifdef DEBUGIO
+	printk("pci_insw(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IORD | COMEM_DA_ADDR(a);
+
+	a = (a & ~0x3) + (~a & 0x2);
+	wp = (volatile unsigned short *)
+		(COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a));
+
+	while (len--) {
+		w = *wp;
+		if (pci_byteswap)
+			w = ((w & 0xff) << 8) | ((w >> 8) & 0xff);
+		*dp++ = w;
+	}
+}
+
+/*****************************************************************************/
+
+void pci_insl(void *addr, void *buf, int len)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned long	*lp;
+	unsigned long		l, *dp = (unsigned long *) buf;
+	unsigned int		a = (unsigned int) addr;
+
+#ifdef DEBUGIO
+	printk("pci_insl(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IORD | COMEM_DA_ADDR(a);
+
+	lp = (volatile unsigned long *)
+		(COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a));
+
+	while (len--) {
+		l = *lp;
+		if (pci_byteswap)
+			l = (l << 24) | ((l & 0x0000ff00) << 8) |
+				((l & 0x00ff0000) >> 8) | (l >> 24);
+		*dp++ = l;
+	}
+}
+
+/*****************************************************************************/
+
+struct pci_localirqlist {
+	void		(*handler)(int, void *, struct pt_regs *);
+	const char	*device;
+	void		*dev_id;
+};
+
+struct pci_localirqlist	pci_irqlist[COMEM_MAXPCI];
+
+/*****************************************************************************/
+
+int pci_request_irq(unsigned int irq,
+	void (*handler)(int, void *, struct pt_regs *),
+	unsigned long flags, const char *device, void *dev_id)
+{
+	int	i;
+
+#ifdef DEBUGIO
+	printk("pci_request_irq(irq=%d,handler=%x,flags=%x,device=%s,"
+		"dev_id=%x)\n", irq, (int) handler, (int) flags, device,
+		(int) dev_id);
+#endif
+
+	/* Check if this interrupt handler is already lodged */
+	for (i = 0; (i < COMEM_MAXPCI); i++) {
+		if (pci_irqlist[i].handler == handler)
+			return(0);
+	}
+
+	/* Find a free spot to put this handler */
+	for (i = 0; (i < COMEM_MAXPCI); i++) {
+		if (pci_irqlist[i].handler == 0) {
+			pci_irqlist[i].handler = handler;
+			pci_irqlist[i].device = device;
+			pci_irqlist[i].dev_id = dev_id;
+			return(0);
+		}
+	}
+
+	/* Couldn't fit?? */
+	return(1);
+}
+
+/*****************************************************************************/
+
+void pci_free_irq(unsigned int irq, void *dev_id)
+{
+	int	i;
+
+#ifdef DEBUGIO
+	printk("pci_free_irq(irq=%d,dev_id=%x)\n", irq, (int) dev_id);
+#endif
+
+	if (dev_id == (void *) NULL)
+		return;
+
+	/* Check if this interrupt handler is lodged */
+	for (i = 0; (i < COMEM_MAXPCI); i++) {
+		if (pci_irqlist[i].dev_id == dev_id) {
+			pci_irqlist[i].handler = NULL;
+			pci_irqlist[i].device = NULL;
+			pci_irqlist[i].dev_id = NULL;
+			break;
+		}
+	}
+}
+
+/*****************************************************************************/
+
+void pci_interrupt(int irq, void *id, struct pt_regs *fp)
+{
+	int	i;
+
+#ifdef DEBUGIO
+	printk("pci_interrupt(irq=%d,id=%x,fp=%x)\n", irq, (int) id, (int) fp);
+#endif
+
+	for (i = 0; (i < COMEM_MAXPCI); i++) {
+		if (pci_irqlist[i].handler)
+			(*pci_irqlist[i].handler)(irq,pci_irqlist[i].dev_id,fp);
+	}
+}
+
+/*****************************************************************************/
+
+/*
+ *	The shared memory region is broken up into contiguous 512 byte
+ *	regions for easy allocation... This is not an optimal solution
+ *	but it makes allocation and freeing regions really easy.
+ */
+
+#define	PCI_MEMSLOTSIZE		512
+#define	PCI_MEMSLOTS		(COMEM_SHMEMSIZE / PCI_MEMSLOTSIZE)
+
+char	pci_shmemmap[PCI_MEMSLOTS];
+
+
+void *pci_bmalloc(int size)
+{
+	int	i, j, nrslots;
+
+#ifdef DEBUGIO
+	printk("pci_bmalloc(size=%d)\n", size);
+#endif
+
+	if (size <= 0)
+		return((void *) NULL);
+
+	nrslots = (size - 1) / PCI_MEMSLOTSIZE;
+
+	for (i = 0; (i < (PCI_MEMSLOTS-nrslots)); i++) {
+		if (pci_shmemmap[i] == 0) {
+			for (j = i+1; (j < (i+nrslots)); j++) {
+				if (pci_shmemmap[j])
+					goto restart;
+			}
+
+			for (j = i; (j <= i+nrslots); j++)
+				pci_shmemmap[j] = 1;
+			break;
+		}
+restart:
+	}
+
+	return((void *) (COMEM_BASE + COMEM_SHMEM + (i * PCI_MEMSLOTSIZE)));
+}
+
+/*****************************************************************************/
+
+void pci_bmfree(void *mp, int size)
+{
+	int	i, j, nrslots;
+
+#ifdef DEBUGIO
+	printk("pci_bmfree(mp=%x,size=%d)\n", (int) mp, size);
+#endif
+
+	nrslots = size / PCI_MEMSLOTSIZE;
+	i = (((unsigned long) mp) - (COMEM_BASE + COMEM_SHMEM)) /
+		PCI_MEMSLOTSIZE;
+
+	for (j = i; (j < (i+nrslots)); j++)
+		pci_shmemmap[j] = 0;
+}
+
+/*****************************************************************************/
+
+unsigned long pci_virt_to_bus(volatile void *address)
+{
+	unsigned long	l;
+
+#ifdef DEBUGIO
+	printk("pci_virt_to_bus(address=%x)", (int) address);
+#endif
+
+	l = ((unsigned long) address) - COMEM_BASE;
+#ifdef DEBUGIO
+	printk("=%x\n", (int) (l+pci_shmemaddr));
+#endif
+	return(l + pci_shmemaddr);
+}
+
+/*****************************************************************************/
+
+void *pci_bus_to_virt(unsigned long address)
+{
+	unsigned long	l;
+
+#ifdef DEBUGIO
+	printk("pci_bus_to_virt(address=%x)", (int) address);
+#endif
+
+	l = address - pci_shmemaddr;
+#ifdef DEBUGIO
+	printk("=%x\n", (int) (address + COMEM_BASE));
+#endif
+	return((void *) (address + COMEM_BASE));
+}
+
+/*****************************************************************************/
+
+void pci_bmcpyto(void *dst, void *src, int len)
+{
+	unsigned long	*dp, *sp, val;
+	unsigned char	*dcp, *scp;
+	int		i, j;
+
+#ifdef DEBUGIO
+	printk("pci_bmcpyto(dst=%x,src=%x,len=%d)\n", (int)dst, (int)src, len);
+#endif
+
+	dp = (unsigned long *) dst;
+	sp = (unsigned long *) src;
+	i = len >> 2;
+
+#if 0
+	printk("DATA:");
+	scp = (unsigned char *) sp;
+	for (i = 0; (i < len); i++) {
+		if ((i % 16) == 0) printk("\n%04x: ", i);
+		printk("%02x ", *scp++);
+	}
+	printk("\n");
+#endif
+
+	for (j = 0; (i >= 0); i--, j++) {
+		val = *sp++;
+		val = (val << 24) | ((val & 0x0000ff00) << 8) |
+			((val & 0x00ff0000) >> 8) | (val >> 24);
+		*dp++ = val;
+	}
+
+	if (len & 0x3) {
+		dcp = (unsigned char *) dp;
+		scp = ((unsigned char *) sp) + 3;
+		for (i = 0; (i < (len & 0x3)); i++)
+			*dcp++ = *scp--;
+	}
+}
+
+/*****************************************************************************/
+
+void pci_bmcpyfrom(void *dst, void *src, int len)
+{
+	unsigned long	*dp, *sp, val;
+	unsigned char	*dcp, *scp;
+	int		i;
+
+#ifdef DEBUGIO
+	printk("pci_bmcpyfrom(dst=%x,src=%x,len=%d)\n",(int)dst,(int)src,len);
+#endif
+
+	dp = (unsigned long *) dst;
+	sp = (unsigned long *) src;
+	i = len >> 2;
+
+	for (; (i >= 0); i--) {
+		val = *sp++;
+		val = (val << 24) | ((val & 0x0000ff00) << 8) |
+			((val & 0x00ff0000) >> 8) | (val >> 24);
+		*dp++ = val;
+	}
+
+	if (len & 0x3) {
+		dcp = ((unsigned char *) dp) + 3;
+		scp = (unsigned char *) sp;
+		for (i = 0; (i < (len & 0x3)); i++)
+			*dcp++ = *scp--;
+	}
+
+#if 0
+	printk("DATA:");
+	dcp = (unsigned char *) dst;
+	for (i = 0; (i < len); i++) {
+		if ((i % 16) == 0) printk("\n%04x: ", i);
+		printk("%02x ", *dcp++);
+	}
+	printk("\n");
+#endif
+}
+
+/*****************************************************************************/
diff -Nru a/arch/m68knommu/kernel/init_task.c b/arch/m68knommu/kernel/init_task.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/kernel/init_task.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,37 @@
+/*
+ *  linux/arch/m68knommu/kernel/init_task.c
+ */
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/init_task.h>
+#include <linux/fs.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+
+static struct fs_struct init_fs = INIT_FS;
+static struct files_struct init_files = INIT_FILES;
+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+struct mm_struct init_mm = INIT_MM(init_mm);
+
+/*
+ * Initial task structure.
+ *
+ * All other task structs will be allocated on slabs in fork.c
+ */
+__asm__(".align 4");
+struct task_struct init_task = INIT_TASK(init_task);
+
+
+/*
+ * Initial thread structure.
+ *
+ * We need to make sure that this is 8192-byte aligned due to the
+ * way process stacks are handled. This is done by having a special
+ * "init_task" linker map entry..
+ */
+union thread_union init_thread_union
+	__attribute__((__section__(".data.init_task"))) =
+		{ INIT_THREAD_INFO(init_task) };
+
diff -Nru a/arch/m68knommu/kernel/ints.c b/arch/m68knommu/kernel/ints.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/kernel/ints.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,274 @@
+/*
+ * linux/arch/m68knommu/kernel/ints.c -- General interrupt handling code
+ *
+ * Copyright (C) 1999-2002  Greg Ungerer (gerg@snapgear.com)
+ * Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>,
+ *                     Kenneth Albanowski <kjahds@kjahds.com>,
+ * Copyright (C) 2000  Lineo Inc. (www.lineo.com) 
+ *
+ * Based on:
+ *
+ * linux/arch/m68k/kernel/ints.c -- Linux/m68k general interrupt handling code
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/errno.h>
+#include <linux/config.h>
+#include <linux/seq_file.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/page.h>
+#include <asm/machdep.h>
+
+/*
+ *	This table stores the address info for each vector handler.
+ */
+irq_handler_t irq_list[SYS_IRQS];
+unsigned int *mach_kstat_irqs;
+
+#define NUM_IRQ_NODES 16
+static irq_node_t nodes[NUM_IRQ_NODES];
+
+/* The number of spurious interrupts */
+volatile unsigned int num_spurious;
+
+unsigned int local_bh_count[NR_CPUS];
+unsigned int local_irq_count[NR_CPUS];
+
+static void default_irq_handler(int irq, void *ptr, struct pt_regs *regs)
+{
+#if 1
+	printk("%s(%d): default irq handler vec=%d [0x%x]\n",
+		__FILE__, __LINE__, irq, irq);
+#endif
+}
+
+/*
+ * void init_IRQ(void)
+ *
+ * Parameters:	None
+ *
+ * Returns:	Nothing
+ *
+ * This function should be called during kernel startup to initialize
+ * the IRQ handling routines.
+ */
+
+void __init init_IRQ(void)
+{
+	int i;
+
+	for (i = 0; i < SYS_IRQS; i++) {
+		if (mach_default_handler)
+			irq_list[i].handler = (*mach_default_handler)[i];
+		else
+			irq_list[i].handler = default_irq_handler;
+		irq_list[i].flags   = IRQ_FLG_STD;
+		irq_list[i].dev_id  = NULL;
+		irq_list[i].devname = NULL;
+	}
+
+	for (i = 0; i < NUM_IRQ_NODES; i++)
+		nodes[i].handler = NULL;
+
+	if (mach_init_IRQ)
+		mach_init_IRQ();
+
+	mach_kstat_irqs = &kstat.irqs[0][0];
+}
+
+irq_node_t *new_irq_node(void)
+{
+	irq_node_t *node;
+	short i;
+
+	for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--)
+		if (!node->handler)
+			return node;
+
+	printk("new_irq_node: out of nodes\n");
+	return NULL;
+}
+
+int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+                unsigned long flags, const char *devname, void *dev_id)
+{
+	if (irq < 0 || irq >= NR_IRQS) {
+		printk("%s: Incorrect IRQ %d from %s\n", __FUNCTION__,
+			irq, devname);
+		return -ENXIO;
+	}
+
+	if (!(irq_list[irq].flags & IRQ_FLG_STD)) {
+		if (irq_list[irq].flags & IRQ_FLG_LOCK) {
+			printk("%s: IRQ %d from %s is not replaceable\n",
+			       __FUNCTION__, irq, irq_list[irq].devname);
+			return -EBUSY;
+		}
+		if (flags & IRQ_FLG_REPLACE) {
+			printk("%s: %s can't replace IRQ %d from %s\n",
+			       __FUNCTION__, devname, irq, irq_list[irq].devname);
+			return -EBUSY;
+		}
+	}
+
+#ifdef CONFIG_COLDFIRE
+	if (flags & IRQ_FLG_FAST) {
+		extern asmlinkage void fasthandler(void);
+		extern void set_evector(int vecnum, void (*handler)(void));
+		set_evector(irq, fasthandler);
+	}
+#endif
+
+	irq_list[irq].handler = handler;
+	irq_list[irq].flags   = flags;
+	irq_list[irq].dev_id  = dev_id;
+	irq_list[irq].devname = devname;
+	return 0;
+}
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+	if (irq >= NR_IRQS) {
+		printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (irq_list[irq].dev_id != dev_id)
+		printk("%s: Removing probably wrong IRQ %d from %s\n",
+		       __FUNCTION__, irq, irq_list[irq].devname);
+
+#ifdef CONFIG_COLDFIRE
+	if (irq_list[irq].flags & IRQ_FLG_FAST) {
+		extern asmlinkage void inthandler(void);
+		extern void set_evector(int vecnum, void (*handler)(void));
+		set_evector(irq, inthandler);
+	}
+#endif
+
+	if (mach_default_handler)
+		irq_list[irq].handler = (*mach_default_handler)[irq];
+	else
+		irq_list[irq].handler = default_irq_handler;
+	irq_list[irq].flags   = IRQ_FLG_STD;
+	irq_list[irq].dev_id  = NULL;
+	irq_list[irq].devname = NULL;
+}
+
+
+int sys_request_irq(unsigned int irq, 
+                    void (*handler)(int, void *, struct pt_regs *), 
+                    unsigned long flags, const char *devname, void *dev_id)
+{
+	if (irq > IRQ7) {
+		printk("%s: Incorrect IRQ %d from %s\n",
+		       __FUNCTION__, irq, devname);
+		return -ENXIO;
+	}
+
+#if 0
+	if (!(irq_list[irq].flags & IRQ_FLG_STD)) {
+		if (irq_list[irq].flags & IRQ_FLG_LOCK) {
+			printk("%s: IRQ %d from %s is not replaceable\n",
+			       __FUNCTION__, irq, irq_list[irq].devname);
+			return -EBUSY;
+		}
+		if (!(flags & IRQ_FLG_REPLACE)) {
+			printk("%s: %s can't replace IRQ %d from %s\n",
+			       __FUNCTION__, devname, irq, irq_list[irq].devname);
+			return -EBUSY;
+		}
+	}
+#endif
+
+	irq_list[irq].handler = handler;
+	irq_list[irq].flags   = flags;
+	irq_list[irq].dev_id  = dev_id;
+	irq_list[irq].devname = devname;
+	return 0;
+}
+
+void sys_free_irq(unsigned int irq, void *dev_id)
+{
+	if (irq > IRQ7) {
+		printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (irq_list[irq].dev_id != dev_id)
+		printk("%s: Removing probably wrong IRQ %d from %s\n",
+		       __FUNCTION__, irq, irq_list[irq].devname);
+
+	irq_list[irq].handler = (*mach_default_handler)[irq];
+	irq_list[irq].flags   = 0;
+	irq_list[irq].dev_id  = NULL;
+	irq_list[irq].devname = NULL;
+}
+
+/*
+ * Do we need these probe functions on the m68k?
+ *
+ *  ... may be usefull with ISA devices
+ */
+unsigned long probe_irq_on (void)
+{
+	return 0;
+}
+
+int probe_irq_off (unsigned long irqs)
+{
+	return 0;
+}
+
+asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
+{
+	if (vec >= VEC_INT1 && vec <= VEC_INT7) {
+		vec -= VEC_SPUR;
+		kstat.irqs[0][vec]++;
+		irq_list[vec].handler(vec, irq_list[vec].dev_id, fp);
+	} else {
+		if (mach_process_int)
+			mach_process_int(vec, fp);
+		else
+			panic("Can't process interrupt vector %ld\n", vec);
+		return;
+	}
+}
+
+
+int show_interrupts(struct seq_file *p, void *v)
+{
+	int i;
+
+	for (i = 0; i < NR_IRQS; i++) {
+		if (irq_list[i].flags & IRQ_FLG_STD)
+			continue;
+
+		seq_printf(p, "%3d: %10u ", i,
+			(i ? kstat.irqs[0][i] : num_spurious));
+		if (irq_list[i].flags & IRQ_FLG_LOCK)
+			seq_printf(p, "L ");
+		else
+			seq_printf(p, "  ");
+		seq_printf(p, "%s\n", irq_list[i].devname);
+	}
+
+	if (mach_get_irq_list)
+		mach_get_irq_list(p, v);
+	return(0);
+}
+
+void init_irq_proc(void)
+{
+	/* Insert /proc/irq driver here */
+}
+
diff -Nru a/arch/m68knommu/kernel/m68k_ksyms.c b/arch/m68knommu/kernel/m68k_ksyms.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/kernel/m68k_ksyms.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,124 @@
+#include <linux/module.h>
+#include <linux/linkage.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/user.h>
+#include <linux/elfcore.h>
+#include <linux/in6.h>
+#include <linux/interrupt.h>
+#include <linux/config.h>
+
+#include <asm/setup.h>
+#include <asm/machdep.h>
+#include <asm/pgalloc.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/semaphore.h>
+#include <asm/checksum.h>
+#include <asm/hardirq.h>
+#include <asm/softirq.h>
+#include <asm/current.h>
+
+extern void dump_thread(struct pt_regs *, struct user *);
+extern int dump_fpu(elf_fpregset_t *);
+
+/* platform dependent support */
+
+EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(iounmap);
+EXPORT_SYMBOL(dump_fpu);
+EXPORT_SYMBOL(dump_thread);
+EXPORT_SYMBOL(strnlen);
+EXPORT_SYMBOL(strrchr);
+EXPORT_SYMBOL(strstr);
+EXPORT_SYMBOL(strchr);
+EXPORT_SYMBOL(strcat);
+EXPORT_SYMBOL(strlen);
+EXPORT_SYMBOL(strcmp);
+EXPORT_SYMBOL(strncmp);
+
+EXPORT_SYMBOL(ip_fast_csum);
+
+EXPORT_SYMBOL(mach_enable_irq);
+EXPORT_SYMBOL(mach_disable_irq);
+EXPORT_SYMBOL(kernel_thread);
+
+/* Networking helper routines. */
+EXPORT_SYMBOL(csum_partial_copy);
+
+/* The following are special because they're not called
+   explicitly (the C compiler generates them).  Fortunately,
+   their interface isn't gonna change any time soon now, so
+   it's OK to leave it out of version control.  */
+EXPORT_SYMBOL_NOVERS(memcpy);
+EXPORT_SYMBOL_NOVERS(memset);
+EXPORT_SYMBOL_NOVERS(memcmp);
+EXPORT_SYMBOL_NOVERS(memscan);
+EXPORT_SYMBOL_NOVERS(memmove);
+
+EXPORT_SYMBOL_NOVERS(__down_failed);
+EXPORT_SYMBOL_NOVERS(__down_failed_interruptible);
+EXPORT_SYMBOL_NOVERS(__down_failed_trylock);
+EXPORT_SYMBOL_NOVERS(__up_wakeup);
+
+EXPORT_SYMBOL(get_wchan);
+
+/*
+ * libgcc functions - functions that are used internally by the
+ * compiler...  (prototypes are not correct though, but that
+ * doesn't really matter since they're not versioned).
+ */
+extern void __gcc_bcmp(void);
+extern void __ashldi3(void);
+extern void __ashrdi3(void);
+extern void __cmpdi2(void);
+extern void __divdi3(void);
+extern void __divsi3(void);
+extern void __lshrdi3(void);
+extern void __moddi3(void);
+extern void __modsi3(void);
+extern void __muldi3(void);
+extern void __mulsi3(void);
+extern void __negdi2(void);
+extern void __ucmpdi2(void);
+extern void __udivdi3(void);
+extern void __udivmoddi4(void);
+extern void __udivsi3(void);
+extern void __umoddi3(void);
+extern void __umodsi3(void);
+
+        /* gcc lib functions */
+EXPORT_SYMBOL_NOVERS(__gcc_bcmp);
+EXPORT_SYMBOL_NOVERS(__ashldi3);
+EXPORT_SYMBOL_NOVERS(__ashrdi3);
+EXPORT_SYMBOL_NOVERS(__cmpdi2);
+EXPORT_SYMBOL_NOVERS(__divdi3);
+EXPORT_SYMBOL_NOVERS(__divsi3);
+EXPORT_SYMBOL_NOVERS(__lshrdi3);
+EXPORT_SYMBOL_NOVERS(__moddi3);
+EXPORT_SYMBOL_NOVERS(__modsi3);
+EXPORT_SYMBOL_NOVERS(__muldi3);
+EXPORT_SYMBOL_NOVERS(__mulsi3);
+EXPORT_SYMBOL_NOVERS(__negdi2);
+EXPORT_SYMBOL_NOVERS(__ucmpdi2);
+EXPORT_SYMBOL_NOVERS(__udivdi3);
+EXPORT_SYMBOL_NOVERS(__udivmoddi4);
+EXPORT_SYMBOL_NOVERS(__udivsi3);
+EXPORT_SYMBOL_NOVERS(__umoddi3);
+EXPORT_SYMBOL_NOVERS(__umodsi3);
+
+EXPORT_SYMBOL_NOVERS(is_in_rom);
+
+#ifdef CONFIG_COLDFIRE
+extern unsigned int *dma_device_address;
+extern unsigned long dma_base_addr, _ramend;
+EXPORT_SYMBOL_NOVERS(dma_base_addr);
+EXPORT_SYMBOL_NOVERS(dma_device_address);
+EXPORT_SYMBOL_NOVERS(_ramend);
+
+extern asmlinkage void trap(void);
+extern void	*_ramvec;
+EXPORT_SYMBOL_NOVERS(trap);
+EXPORT_SYMBOL_NOVERS(_ramvec);
+#endif /* CONFIG_COLDFIRE */
diff -Nru a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/kernel/process.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,450 @@
+/*
+ *  linux/arch/m68knommu/kernel/process.c
+ *
+ *  Copyright (C) 1995  Hamish Macdonald
+ *
+ *  68060 fixes by Jesper Skov
+ *
+ *  uClinux changes
+ *  Copyright (C) 2000-2002, David McCullough <davidm@snapgear.com>
+ */
+
+/*
+ * This file handles the architecture-dependent parts of process handling..
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/interrupt.h>
+#include <linux/reboot.h>
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+#include <asm/pgtable.h>
+
+asmlinkage void ret_from_fork(void);
+
+
+/*
+ * The idle loop on an m68knommu..
+ */
+void default_idle(void)
+{
+	while(1) {
+		if (need_resched())
+			__asm__("stop #0x2000" : : : "cc");
+		schedule();
+	}
+}
+
+void (*idle)(void) = default_idle;
+
+/*
+ * The idle thread. There's no useful work to be
+ * done, so just try to conserve power and have a
+ * low exit latency (ie sit in a loop waiting for
+ * somebody to say that they'd like to reschedule)
+ */
+void cpu_idle(void)
+{
+	/* endless idle loop with no priority at all */
+	idle();
+}
+
+void machine_restart(char * __unused)
+{
+	if (mach_reset)
+		mach_reset();
+	for (;;);
+}
+
+void machine_halt(void)
+{
+	if (mach_halt)
+		mach_halt();
+	for (;;);
+}
+
+void machine_power_off(void)
+{
+	if (mach_power_off)
+		mach_power_off();
+	for (;;);
+}
+
+void show_regs(struct pt_regs * regs)
+{
+	printk("\n");
+	printk("Format %02x  Vector: %04x  PC: %08lx  Status: %04x    %s\n",
+	       regs->format, regs->vector, regs->pc, regs->sr, print_tainted());
+	printk("ORIG_D0: %08lx  D0: %08lx  A2: %08lx  A1: %08lx\n",
+	       regs->orig_d0, regs->d0, regs->a2, regs->a1);
+	printk("A0: %08lx  D5: %08lx  D4: %08lx\n",
+	       regs->a0, regs->d5, regs->d4);
+	printk("D3: %08lx  D2: %08lx  D1: %08lx\n",
+	       regs->d3, regs->d2, regs->d1);
+	if (!(regs->sr & PS_S))
+		printk("USP: %08lx\n", rdusp());
+}
+
+/*
+ * Create a kernel thread
+ */
+int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+{
+	long retval;
+	long clone_arg = flags | CLONE_VM;
+	mm_segment_t fs;
+
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+
+	__asm__ __volatile__ (
+			"movel	%%sp, %%d2\n\t"
+			"movel	%5, %%d1\n\t"
+			"movel	%1, %%d0\n\t"
+			"trap	#0\n\t"
+			"cmpl	%%sp, %%d2\n\t"
+			"jeq	1f\n\t"
+			"movel	%3, %%sp@-\n\t"
+			"jsr	%4@\n\t"
+			"movel	%2, %%d0\n\t"
+			"trap	#0\n"
+			"1:"
+		: "=d" (retval)
+		: "i" (__NR_clone),
+		  "i" (__NR_exit),
+		  "a" (arg),
+		  "a" (fn),
+		  "a" (clone_arg)
+		: "cc", "%d0", "%d1", "%d2");
+
+	set_fs(fs);
+	return retval;
+}
+
+void flush_thread(void)
+{
+#ifdef CONFIG_FPU
+	unsigned long zero = 0;
+#endif
+	set_fs(USER_DS);
+	current->thread.fs = __USER_DS;
+#ifdef CONFIG_FPU
+	if (!FPU_IS_EMU)
+		asm volatile (".chip 68k/68881\n\t"
+			      "frestore %0@\n\t"
+			      ".chip 68k" : : "a" (&zero));
+#endif
+}
+
+/*
+ * "m68k_fork()".. By the time we get here, the
+ * non-volatile registers have also been saved on the
+ * stack. We do some ugly pointer stuff here.. (see
+ * also copy_thread)
+ */
+
+asmlinkage int m68k_fork(struct pt_regs *regs)
+{
+	/* fork almost works, enough to trick you into looking elsewhere :-( */
+	return(-EINVAL);
+}
+
+asmlinkage int m68k_vfork(struct pt_regs *regs)
+{
+	struct task_struct *p;
+	p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL);
+	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
+}
+
+asmlinkage int m68k_clone(struct pt_regs *regs)
+{
+	unsigned long clone_flags;
+	unsigned long newsp;
+	struct task_struct *p;
+
+	/* syscall2 puts clone_flags in d1 and usp in d2 */
+	clone_flags = regs->d1;
+	newsp = regs->d2;
+	if (!newsp)
+		newsp = rdusp();
+        p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, regs, 0, NULL);
+        return IS_ERR(p) ? PTR_ERR(p) : p->pid;
+}
+
+int copy_thread(int nr, unsigned long clone_flags,
+		unsigned long usp, unsigned long topstk,
+		struct task_struct * p, struct pt_regs * regs)
+{
+	struct pt_regs * childregs;
+	struct switch_stack * childstack, *stack;
+	unsigned long stack_offset, *retp;
+
+	stack_offset = KTHREAD_SIZE - sizeof(struct pt_regs);
+	childregs = (struct pt_regs *) ((unsigned long) p->thread_info + stack_offset);
+
+	*childregs = *regs;
+	childregs->d0 = 0;
+
+	retp = ((unsigned long *) regs);
+	stack = ((struct switch_stack *) retp) - 1;
+
+	childstack = ((struct switch_stack *) childregs) - 1;
+	*childstack = *stack;
+	childstack->retpc = (unsigned long)ret_from_fork;
+
+	p->thread.usp = usp;
+	p->thread.ksp = (unsigned long)childstack;
+	/*
+	 * Must save the current SFC/DFC value, NOT the value when
+	 * the parent was last descheduled - RGH  10-08-96
+	 */
+	p->thread.fs = get_fs().seg;
+
+#ifdef CONFIG_FPU
+	if (!FPU_IS_EMU) {
+		/* Copy the current fpu state */
+		asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0]) : "memory");
+
+		if (p->thread.fpstate[0])
+		  asm volatile ("fmovemx %/fp0-%/fp7,%0\n\t"
+				"fmoveml %/fpiar/%/fpcr/%/fpsr,%1"
+				: : "m" (p->thread.fp[0]), "m" (p->thread.fpcntl[0])
+				: "memory");
+		/* Restore the state in case the fpu was busy */
+		asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0]));
+	}
+#endif
+
+	return 0;
+}
+
+/* Fill in the fpu structure for a core dump.  */
+
+int dump_fpu(struct pt_regs *regs, struct user_m68kfp_struct *fpu)
+{
+#ifdef CONFIG_FPU
+	char fpustate[216];
+
+	if (FPU_IS_EMU) {
+		int i;
+
+		memcpy(fpu->fpcntl, current->thread.fpcntl, 12);
+		memcpy(fpu->fpregs, current->thread.fp, 96);
+		/* Convert internal fpu reg representation
+		 * into long double format
+		 */
+		for (i = 0; i < 24; i += 3)
+			fpu->fpregs[i] = ((fpu->fpregs[i] & 0xffff0000) << 15) |
+			                 ((fpu->fpregs[i] & 0x0000ffff) << 16);
+		return 1;
+	}
+
+	/* First dump the fpu context to avoid protocol violation.  */
+	asm volatile ("fsave %0" :: "m" (fpustate[0]) : "memory");
+	if (!fpustate[0])
+		return 0;
+
+	asm volatile ("fmovem %/fpiar/%/fpcr/%/fpsr,%0"
+		:: "m" (fpu->fpcntl[0])
+		: "memory");
+	asm volatile ("fmovemx %/fp0-%/fp7,%0"
+		:: "m" (fpu->fpregs[0])
+		: "memory");
+#endif
+	return 1;
+}
+
+/*
+ * fill in the user structure for a core dump..
+ */
+void dump_thread(struct pt_regs * regs, struct user * dump)
+{
+	struct switch_stack *sw;
+
+	/* changed the size calculations - should hopefully work better. lbt */
+	dump->magic = CMAGIC;
+	dump->start_code = 0;
+	dump->start_stack = rdusp() & ~(PAGE_SIZE - 1);
+	dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
+	dump->u_dsize = ((unsigned long) (current->mm->brk +
+					  (PAGE_SIZE-1))) >> PAGE_SHIFT;
+	dump->u_dsize -= dump->u_tsize;
+	dump->u_ssize = 0;
+
+	if (dump->start_stack < TASK_SIZE)
+		dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
+
+	dump->u_ar0 = (struct user_regs_struct *)((int)&dump->regs - (int)dump);
+	sw = ((struct switch_stack *)regs) - 1;
+	dump->regs.d1 = regs->d1;
+	dump->regs.d2 = regs->d2;
+	dump->regs.d3 = regs->d3;
+	dump->regs.d4 = regs->d4;
+	dump->regs.d5 = regs->d5;
+	dump->regs.d6 = sw->d6;
+	dump->regs.d7 = sw->d7;
+	dump->regs.a0 = regs->a0;
+	dump->regs.a1 = regs->a1;
+	dump->regs.a2 = regs->a2;
+	dump->regs.a3 = sw->a3;
+	dump->regs.a4 = sw->a4;
+	dump->regs.a5 = sw->a5;
+	dump->regs.a6 = sw->a6;
+	dump->regs.d0 = regs->d0;
+	dump->regs.orig_d0 = regs->orig_d0;
+	dump->regs.stkadj = regs->stkadj;
+	dump->regs.sr = regs->sr;
+	dump->regs.pc = regs->pc;
+	dump->regs.fmtvec = (regs->format << 12) | regs->vector;
+	/* dump floating point stuff */
+	dump->u_fpvalid = dump_fpu (regs, &dump->m68kfp);
+}
+
+/*
+ *	Generic dumping code. Used for panic and debug.
+ */
+void dump(struct pt_regs *fp)
+{
+	unsigned long	*sp;
+	unsigned char	*tp;
+	int		i;
+
+	printk("\nCURRENT PROCESS:\n\n");
+	printk("COMM=%s PID=%d\n", current->comm, current->pid);
+
+	if (current->mm) {
+		printk("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
+			(int) current->mm->start_code,
+			(int) current->mm->end_code,
+			(int) current->mm->start_data,
+			(int) current->mm->end_data,
+			(int) current->mm->end_data,
+			(int) current->mm->brk);
+		printk("USER-STACK=%08x  KERNEL-STACK=%08x\n\n",
+			(int) current->mm->start_stack,
+			(int)(((unsigned long) current) + KTHREAD_SIZE));
+	}
+
+	printk("PC: %08lx\n", fp->pc);
+	printk("SR: %08lx    SP: %08lx\n", (long) fp->sr, (long) fp);
+	printk("d0: %08lx    d1: %08lx    d2: %08lx    d3: %08lx\n",
+		fp->d0, fp->d1, fp->d2, fp->d3);
+	printk("d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
+		fp->d4, fp->d5, fp->a0, fp->a1);
+	printk("\nUSP: %08x   TRAPFRAME: %08x\n", (unsigned int) rdusp(),
+		(unsigned int) fp);
+
+	printk("\nCODE:");
+	tp = ((unsigned char *) fp->pc) - 0x20;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x40);  i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+
+	printk("\nKERNEL STACK:");
+	tp = ((unsigned char *) fp) - 0x40;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+	printk("\n");
+
+	printk("\nUSER STACK:");
+	tp = (unsigned char *) (rdusp() - 0x10);
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n\n");
+}
+
+/*
+ * sys_execve() executes a new program.
+ */
+asmlinkage int sys_execve(char *name, char **argv, char **envp)
+{
+	int error;
+	char * filename;
+	struct pt_regs *regs = (struct pt_regs *) &name;
+
+	lock_kernel();
+	filename = getname(name);
+	error = PTR_ERR(filename);
+	if (IS_ERR(filename))
+		goto out;
+	error = do_execve(filename, argv, envp, regs);
+	putname(filename);
+out:
+	unlock_kernel();
+	return error;
+}
+
+/*
+ * These bracket the sleeping functions..
+ */
+extern void scheduling_functions_start_here(void);
+extern void scheduling_functions_end_here(void);
+#define first_sched	((unsigned long) scheduling_functions_start_here)
+#define last_sched	((unsigned long) scheduling_functions_end_here)
+
+unsigned long get_wchan(struct task_struct *p)
+{
+	unsigned long fp, pc;
+	unsigned long stack_page;
+	int count = 0;
+	if (!p || p == current || p->state == TASK_RUNNING)
+		return 0;
+
+	stack_page = (unsigned long)p;
+	fp = ((struct switch_stack *)p->thread.ksp)->a6;
+	do {
+		if (fp < stack_page+sizeof(struct task_struct) ||
+		    fp >= 8184+stack_page)
+			return 0;
+		pc = ((unsigned long *)fp)[1];
+		/* FIXME: This depends on the order of these functions. */
+		if (pc < first_sched || pc >= last_sched)
+			return pc;
+		fp = *(unsigned long *) fp;
+	} while (count++ < 16);
+	return 0;
+}
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+unsigned long thread_saved_pc(struct task_struct *tsk)
+{
+	extern void scheduling_functions_start_here(void);
+	extern void scheduling_functions_end_here(void);
+	struct switch_stack *sw = (struct switch_stack *)tsk->thread.ksp;
+
+	/* Check whether the thread is blocked in resume() */
+	if (sw->retpc > (unsigned long)scheduling_functions_start_here &&
+	    sw->retpc < (unsigned long)scheduling_functions_end_here)
+		return ((unsigned long *)sw->a6)[1];
+	else
+		return sw->retpc;
+}
+
diff -Nru a/arch/m68knommu/kernel/ptrace.c b/arch/m68knommu/kernel/ptrace.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/kernel/ptrace.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,392 @@
+/*
+ *  linux/arch/m68knommu/kernel/ptrace.c
+ *
+ *  Copyright (C) 1994 by Hamish Macdonald
+ *  Taken from linux/kernel/ptrace.c and modified for M680x0.
+ *  linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of
+ * this archive for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+#include <linux/config.h>
+
+#include <asm/uaccess.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/processor.h>
+
+/*
+ * does not yet catch signals sent when the child dies.
+ * in exit.c or in signal.c.
+ */
+
+/* determines which bits in the SR the user has access to. */
+/* 1 = access 0 = no access */
+#define SR_MASK 0x001f
+
+/* sets the trace bits. */
+#define TRACE_BITS 0x8000
+
+/* Find the stack offset for a register, relative to thread.esp0. */
+#define PT_REG(reg)	((long)&((struct pt_regs *)0)->reg)
+#define SW_REG(reg)	((long)&((struct switch_stack *)0)->reg \
+			 - sizeof(struct switch_stack))
+/* Mapping from PT_xxx to the stack offset at which the register is
+   saved.  Notice that usp has no stack-slot and needs to be treated
+   specially (see get_reg/put_reg below). */
+static int regoff[] = {
+	PT_REG(d1), PT_REG(d2), PT_REG(d3), PT_REG(d4),
+	PT_REG(d5), SW_REG(d6), SW_REG(d7), PT_REG(a0),
+	PT_REG(a1), PT_REG(a2), SW_REG(a3), SW_REG(a4),
+	SW_REG(a5), SW_REG(a6), PT_REG(d0), -1,
+	PT_REG(orig_d0), PT_REG(sr), PT_REG(pc),
+};
+
+/*
+ * Get contents of register REGNO in task TASK.
+ */
+static inline long get_reg(struct task_struct *task, int regno)
+{
+	unsigned long *addr;
+
+	if (regno == PT_USP)
+		addr = &task->thread.usp;
+	else if (regno < sizeof(regoff)/sizeof(regoff[0]))
+		addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
+	else
+		return 0;
+	return *addr;
+}
+
+/*
+ * Write contents of register REGNO in task TASK.
+ */
+static inline int put_reg(struct task_struct *task, int regno,
+			  unsigned long data)
+{
+	unsigned long *addr;
+
+	if (regno == PT_USP)
+		addr = &task->thread.usp;
+	else if (regno < sizeof(regoff)/sizeof(regoff[0]))
+		addr = (unsigned long *) (task->thread.esp0 + regoff[regno]);
+	else
+		return -1;
+	*addr = data;
+	return 0;
+}
+
+/*
+ * Called by kernel/ptrace.c when detaching..
+ *
+ * Make sure the single step bit is not set.
+ */
+void ptrace_disable(struct task_struct *child)
+{
+	unsigned long tmp;
+	/* make sure the single step bit is not set. */
+	tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
+	put_reg(child, PT_SR, tmp);
+}
+
+asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+{
+	struct task_struct *child;
+	int ret;
+
+	lock_kernel();
+	ret = -EPERM;
+	if (request == PTRACE_TRACEME) {
+		/* are we already being traced? */
+		if (current->ptrace & PT_PTRACED)
+			goto out;
+		/* set the ptrace bit in the process flags. */
+		current->ptrace |= PT_PTRACED;
+		ret = 0;
+		goto out;
+	}
+	ret = -ESRCH;
+	read_lock(&tasklist_lock);
+	child = find_task_by_pid(pid);
+	if (child)
+		get_task_struct(child);
+	read_unlock(&tasklist_lock);
+	if (!child)
+		goto out;
+
+	ret = -EPERM;
+	if (pid == 1)		/* you may not mess with init */
+		goto out_tsk;
+
+	if (request == PTRACE_ATTACH) {
+		ret = ptrace_attach(child);
+		goto out_tsk;
+	}
+	ret = -ESRCH;
+	if (!(child->ptrace & PT_PTRACED))
+		goto out_tsk;
+	if (child->state != TASK_STOPPED) {
+		if (request != PTRACE_KILL)
+			goto out_tsk;
+	}
+	ret = ptrace_check_attach(child, request == PTRACE_KILL);
+	if (ret < 0)
+		goto out_tsk;
+
+	switch (request) {
+		/* when I and D space are separate, these will need to be fixed. */
+		case PTRACE_PEEKTEXT: /* read word at location addr. */ 
+		case PTRACE_PEEKDATA: {
+			unsigned long tmp;
+			int copied;
+
+			copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+			ret = -EIO;
+			if (copied != sizeof(tmp))
+				break;
+			ret = put_user(tmp,(unsigned long *) data);
+			break;
+		}
+
+		/* read the word at location addr in the USER area. */
+		case PTRACE_PEEKUSR: {
+			unsigned long tmp;
+			
+			ret = -EIO;
+			if ((addr & 3) || addr < 0 ||
+			    addr > sizeof(struct user) - 3)
+				break;
+			
+			tmp = 0;  /* Default return condition */
+			addr = addr >> 2; /* temporary hack. */
+			ret = -EIO;
+			if (addr < 19) {
+				tmp = get_reg(child, addr);
+				if (addr == PT_SR)
+					tmp >>= 16;
+			} else if (addr >= 21 && addr < 49) {
+				tmp = child->thread.fp[addr - 21];
+#ifdef CONFIG_M68KFPU_EMU
+				/* Convert internal fpu reg representation
+				 * into long double format
+				 */
+				if (FPU_IS_EMU && (addr < 45) && !(addr % 3))
+					tmp = ((tmp & 0xffff0000) << 15) |
+					      ((tmp & 0x0000ffff) << 16);
+#endif
+			} else if (addr == 49) {
+				tmp = child->mm->start_code;
+			} else if (addr == 50) {
+				tmp = child->mm->start_data;
+			} else if (addr == 51) {
+				tmp = child->mm->end_code;
+			} else
+				break;
+			ret = put_user(tmp,(unsigned long *) data);
+			break;
+		}
+
+		/* when I and D space are separate, this will have to be fixed. */
+		case PTRACE_POKETEXT: /* write the word at location addr. */
+		case PTRACE_POKEDATA:
+			ret = 0;
+			if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
+				break;
+			ret = -EIO;
+			break;
+
+		case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
+			ret = -EIO;
+			if ((addr & 3) || addr < 0 ||
+			    addr > sizeof(struct user) - 3)
+				break;
+
+			addr = addr >> 2; /* temporary hack. */
+			    
+			if (addr == PT_SR) {
+				data &= SR_MASK;
+				data <<= 16;
+				data |= get_reg(child, PT_SR) & ~(SR_MASK << 16);
+			}
+			if (addr < 19) {
+				if (put_reg(child, addr, data))
+					break;
+				ret = 0;
+				break;
+			}
+			if (addr >= 21 && addr < 48)
+			{
+#ifdef CONFIG_M68KFPU_EMU
+				/* Convert long double format
+				 * into internal fpu reg representation
+				 */
+				if (FPU_IS_EMU && (addr < 45) && !(addr % 3)) {
+					data = (unsigned long)data << 15;
+					data = (data & 0xffff0000) |
+					       ((data & 0x0000ffff) >> 1);
+				}
+#endif
+				child->thread.fp[addr - 21] = data;
+				ret = 0;
+			}
+			break;
+
+		case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+		case PTRACE_CONT: { /* restart after signal. */
+			long tmp;
+
+			ret = -EIO;
+			if ((unsigned long) data > _NSIG)
+				break;
+			if (request == PTRACE_SYSCALL)
+				set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+			else
+				clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+			child->exit_code = data;
+			/* make sure the single step bit is not set. */
+			tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
+			put_reg(child, PT_SR, tmp);
+			wake_up_process(child);
+			ret = 0;
+			break;
+		}
+
+		/*
+		 * make the child exit.  Best I can do is send it a sigkill. 
+		 * perhaps it should be put in the status that it wants to 
+		 * exit.
+		 */
+		case PTRACE_KILL: {
+			long tmp;
+
+			ret = 0;
+			if (child->state == TASK_ZOMBIE) /* already dead */
+				break;
+			child->exit_code = SIGKILL;
+			/* make sure the single step bit is not set. */
+			tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
+			put_reg(child, PT_SR, tmp);
+			wake_up_process(child);
+			break;
+		}
+
+		case PTRACE_SINGLESTEP: {  /* set the trap flag. */
+			long tmp;
+
+			ret = -EIO;
+			if ((unsigned long) data > _NSIG)
+				break;
+			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+			tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16);
+			put_reg(child, PT_SR, tmp);
+
+			child->exit_code = data;
+			/* give it a chance to run. */
+			wake_up_process(child);
+			ret = 0;
+			break;
+		}
+
+		case PTRACE_DETACH:	/* detach a process that was attached. */
+			ret = ptrace_detach(child, data);
+			break;
+
+		case PTRACE_GETREGS: { /* Get all gp regs from the child. */
+		  	int i;
+			unsigned long tmp;
+			for (i = 0; i < 19; i++) {
+			    tmp = get_reg(child, i);
+			    if (i == PT_SR)
+				tmp >>= 16;
+			    if (put_user(tmp, (unsigned long *) data)) {
+				ret = -EFAULT;
+				break;
+			    }
+			    data += sizeof(long);
+			}
+			ret = 0;
+			break;
+		}
+
+		case PTRACE_SETREGS: { /* Set all gp regs in the child. */
+			int i;
+			unsigned long tmp;
+			for (i = 0; i < 19; i++) {
+			    if (get_user(tmp, (unsigned long *) data)) {
+				ret = -EFAULT;
+				break;
+			    }
+			    if (i == PT_SR) {
+				tmp &= SR_MASK;
+				tmp <<= 16;
+				tmp |= get_reg(child, PT_SR) & ~(SR_MASK << 16);
+			    }
+			    put_reg(child, i, tmp);
+			    data += sizeof(long);
+			}
+			ret = 0;
+			break;
+		}
+
+#ifdef PTRACE_GETFPREGS
+		case PTRACE_GETFPREGS: { /* Get the child FPU state. */
+			ret = 0;
+			if (copy_to_user((void *)data, &child->thread.fp,
+					 sizeof(struct user_m68kfp_struct)))
+				ret = -EFAULT;
+			break;
+		}
+#endif
+
+#ifdef PTRACE_SETFPREGS
+		case PTRACE_SETFPREGS: { /* Set the child FPU state. */
+			ret = 0;
+			if (copy_from_user(&child->thread.fp, (void *)data,
+					   sizeof(struct user_m68kfp_struct)))
+				ret = -EFAULT;
+			break;
+		}
+#endif
+
+		default:
+			ret = -EIO;
+			break;
+	}
+out_tsk:
+	put_task_struct(child);
+out:
+	unlock_kernel();
+	return ret;
+}
+
+asmlinkage void syscall_trace(void)
+{
+	if (!test_thread_flag(TIF_SYSCALL_TRACE))
+		return;
+	if (!(current->ptrace & PT_PTRACED))
+		return;
+	current->exit_code = SIGTRAP;
+	current->state = TASK_STOPPED;
+	notify_parent(current, SIGCHLD);
+	schedule();
+	/*
+	 * this isn't the same as continuing with a signal, but it will do
+	 * for normal use.  strace only continues with a signal if the
+	 * stopping signal is not SIGTRAP.  -brl
+	 */
+	if (current->exit_code) {
+		send_sig(current->exit_code, current, 1);
+		current->exit_code = 0;
+	}
+}
diff -Nru a/arch/m68knommu/kernel/semaphore.c b/arch/m68knommu/kernel/semaphore.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/kernel/semaphore.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,133 @@
+/*
+ *  Generic semaphore code. Buyer beware. Do your own
+ * specific changes in <asm/semaphore-helper.h>
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/err.h>
+#include <asm/semaphore-helper.h>
+
+#ifndef CONFIG_RMW_INSNS
+spinlock_t semaphore_wake_lock;
+#endif
+
+/*
+ * Semaphores are implemented using a two-way counter:
+ * The "count" variable is decremented for each process
+ * that tries to sleep, while the "waking" variable is
+ * incremented when the "up()" code goes to wake up waiting
+ * processes.
+ *
+ * Notably, the inline "up()" and "down()" functions can
+ * efficiently test if they need to do any extra work (up
+ * needs to do something only if count was negative before
+ * the increment operation.
+ *
+ * waking_non_zero() (from asm/semaphore.h) must execute
+ * atomically.
+ *
+ * When __up() is called, the count was negative before
+ * incrementing it, and we need to wake up somebody.
+ *
+ * This routine adds one to the count of processes that need to
+ * wake up and exit.  ALL waiting processes actually wake up but
+ * only the one that gets to the "waking" field first will gate
+ * through and acquire the semaphore.  The others will go back
+ * to sleep.
+ *
+ * Note that these functions are only called when there is
+ * contention on the lock, and as such all this is the
+ * "non-critical" part of the whole semaphore business. The
+ * critical part is the inline stuff in <asm/semaphore.h>
+ * where we want to avoid any extra jumps and calls.
+ */
+void __up(struct semaphore *sem)
+{
+	wake_one_more(sem);
+	wake_up(&sem->wait);
+}
+
+/*
+ * Perform the "down" function.  Return zero for semaphore acquired,
+ * return negative for signalled out of the function.
+ *
+ * If called from __down, the return is ignored and the wait loop is
+ * not interruptible.  This means that a task waiting on a semaphore
+ * using "down()" cannot be killed until someone does an "up()" on
+ * the semaphore.
+ *
+ * If called from __down_interruptible, the return value gets checked
+ * upon return.  If the return value is negative then the task continues
+ * with the negative value in the return register (it can be tested by
+ * the caller).
+ *
+ * Either form may be used in conjunction with "up()".
+ *
+ */
+
+
+#define DOWN_HEAD(task_state)						\
+									\
+									\
+	current->state = (task_state);					\
+	add_wait_queue(&sem->wait, &wait);				\
+									\
+	/*								\
+	 * Ok, we're set up.  sem->count is known to be less than zero	\
+	 * so we must wait.						\
+	 *								\
+	 * We can let go the lock for purposes of waiting.		\
+	 * We re-acquire it after awaking so as to protect		\
+	 * all semaphore operations.					\
+	 *								\
+	 * If "up()" is called before we call waking_non_zero() then	\
+	 * we will catch it right away.  If it is called later then	\
+	 * we will have to go through a wakeup cycle to catch it.	\
+	 *								\
+	 * Multiple waiters contend for the semaphore lock to see	\
+	 * who gets to gate through and who has to wait some more.	\
+	 */								\
+	for (;;) {
+
+#define DOWN_TAIL(task_state)			\
+		current->state = (task_state);	\
+	}					\
+	current->state = TASK_RUNNING;		\
+	remove_wait_queue(&sem->wait, &wait);
+
+void __down(struct semaphore * sem)
+{
+	DECLARE_WAITQUEUE(wait, current);
+
+	DOWN_HEAD(TASK_UNINTERRUPTIBLE)
+	if (waking_non_zero(sem))
+		break;
+	schedule();
+	DOWN_TAIL(TASK_UNINTERRUPTIBLE)
+}
+
+int __down_interruptible(struct semaphore * sem)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	int ret = 0;
+
+	DOWN_HEAD(TASK_INTERRUPTIBLE)
+
+	ret = waking_non_zero_interruptible(sem, current);
+	if (ret)
+	{
+		if (ret == 1)
+			/* ret != 0 only if we get interrupted -arca */
+			ret = 0;
+		break;
+	}
+	schedule();
+	DOWN_TAIL(TASK_INTERRUPTIBLE)
+	return ret;
+}
+
+int __down_trylock(struct semaphore * sem)
+{
+	return waking_non_zero_trylock(sem);
+}
diff -Nru a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/kernel/setup.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,360 @@
+/*
+ *  linux/arch/m68knommu/kernel/setup.c
+ *
+ *  Copyright (C) 1999-2002  Greg Ungerer (gerg@snapgear.com)
+ *  Copyright (C) 1998,1999  D. Jeff Dionne <jeff@lineo.ca>
+ *  Copyleft  ()) 2000       James D. Schettine {james@telos-systems.com}
+ *  Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+ *  Copyright (C) 1995       Hamish Macdonald
+ *  Copyright (C) 2000       Lineo Inc. (www.lineo.com) 
+ *  Copyright (C) 2001 	     Lineo, Inc. <www.lineo.com>
+ *
+ *  68VZ328 Fixes/support    Evan Stawnyczy <e@lineo.ca>
+ */
+
+/*
+ * This file handles the architecture-dependent parts of system setup
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/fb.h>
+#include <linux/console.h>
+#include <linux/genhd.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/major.h>
+#include <linux/bootmem.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+
+#ifdef CONFIG_BLK_DEV_INITRD
+#include <linux/blk.h>
+#include <asm/pgtable.h>
+#endif
+
+#ifdef CONFIG_CONSOLE
+extern struct consw *conswitchp;
+#ifdef CONFIG_FRAMEBUFFER
+extern struct consw fb_con;
+#endif
+#endif
+
+unsigned long rom_length;
+unsigned long memory_start;
+unsigned long memory_end;
+
+char command_line[512];
+char saved_command_line[512];
+
+/* setup some dummy routines */
+static void dummy_waitbut(void)
+{
+}
+
+void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)) = NULL;
+void (*mach_tick)( void ) = NULL;
+/* machine dependent keyboard functions */
+int (*mach_keyb_init) (void) = NULL;
+int (*mach_kbdrate) (struct kbd_repeat *) = NULL;
+void (*mach_kbd_leds) (unsigned int) = NULL;
+/* machine dependent irq functions */
+void (*mach_init_IRQ) (void) = NULL;
+void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL;
+int (*mach_request_irq) (unsigned int, void (*)(int, void *, struct pt_regs *),
+                         unsigned long, const char *, void *);
+void (*mach_free_irq) (unsigned int irq, void *dev_id) = NULL;
+void (*mach_enable_irq) (unsigned int) = NULL;
+void (*mach_disable_irq) (unsigned int) = NULL;
+int (*mach_get_irq_list) (struct seq_file *, void *) = NULL;
+void (*mach_process_int) (int irq, struct pt_regs *fp) = NULL;
+void (*mach_trap_init) (void);
+/* machine dependent timer functions */
+unsigned long (*mach_gettimeoffset) (void) = NULL;
+void (*mach_gettod) (int*, int*, int*, int*, int*, int*) = NULL;
+int (*mach_hwclk) (int, struct hwclk_time*) = NULL;
+int (*mach_set_clock_mmss) (unsigned long) = NULL;
+void (*mach_mksound)( unsigned int count, unsigned int ticks ) = NULL;
+void (*mach_reset)( void ) = NULL;
+void (*waitbut)(void) = dummy_waitbut;
+void (*mach_debug_init)(void) = NULL;
+void (*mach_halt)( void ) = NULL;
+void (*mach_power_off)( void ) = NULL;
+
+
+#ifdef CONFIG_M68000
+	#define CPU "MC68000"
+#endif
+#ifdef CONFIG_M68328
+	#define CPU "MC68328"
+#endif
+#ifdef CONFIG_M68EZ328
+	#define CPU "MC68EZ328"
+#endif
+#ifdef CONFIG_M68VZ328
+	#define CPU "MC68VZ328"
+#endif
+#ifdef CONFIG_M68332
+	#define CPU "MC68332"
+#endif
+#ifdef CONFIG_M68360
+	#define CPU "MC68360"
+#endif
+#if defined(CONFIG_M5206)
+	#define	CPU "COLDFIRE(m5206)"
+#endif
+#if defined(CONFIG_M5206e)
+	#define	CPU "COLDFIRE(m5206e)"
+#endif
+#if defined(CONFIG_M5249)
+	#define CPU "COLDFIRE(m5249)"
+#endif
+#if defined(CONFIG_M5272)
+	#define CPU "COLDFIRE(m5272)"
+#endif
+#if defined(CONFIG_M5307)
+	#define	CPU "COLDFIRE(m5307)"
+#endif
+#if defined(CONFIG_M5407)
+	#define	CPU "COLDFIRE(m5407)"
+#endif
+#ifndef CPU
+	#define	CPU "UNKOWN"
+#endif
+
+/* (es) */
+/* note: why is this defined here?  the must be a better place to put this */
+#if defined( CONFIG_TELOS) || defined( CONFIG_UCDIMM ) || defined( CONFIG_UCSIMM ) || defined(CONFIG_DRAGEN2) || (defined( CONFIG_PILOT ) && defined( CONFIG_M68328 ))
+#define CAT_ROMARRAY
+#endif
+/* (/es) */
+
+extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end;
+extern int _ramstart, _ramend;
+
+void setup_arch(char **cmdline_p)
+{
+	int bootmap_size;
+
+#if defined(CAT_ROMARRAY) && defined(DEBUG)
+	extern int __data_rom_start;
+	extern int __data_start;
+	int *romarray = (int *)((int) &__data_rom_start +
+			      (int)&_edata - (int)&__data_start);
+#endif
+
+	memory_start = PAGE_ALIGN(_ramstart);
+	memory_end = _ramend; /* by now the stack is part of the init task */
+
+	init_mm.start_code = (unsigned long) &_stext;
+	init_mm.end_code = (unsigned long) &_etext;
+	init_mm.end_data = (unsigned long) &_edata;
+	init_mm.brk = (unsigned long) 0; 
+
+	config_BSP(&command_line[0], sizeof(command_line));
+
+	printk("\x0F\r\n\nuClinux/" CPU "\n");
+
+#ifdef CONFIG_UCDIMM
+	printk("uCdimm by Lineo, Inc. <www.lineo.com>\n");
+#endif
+#ifdef CONFIG_M68VZ328
+	printk("M68VZ328 support by Evan Stawnyczy <e@lineo.ca>\n");
+#endif
+#ifdef CONFIG_COLDFIRE
+	printk("COLDFIRE port done by Greg Ungerer, gerg@snapgear.com\n");
+#ifdef CONFIG_M5307
+	printk("Modified for M5307 by Dave Miller, dmiller@intellistor.com\n");
+#endif
+#ifdef CONFIG_ELITE
+	printk("Modified for M5206eLITE by Rob Scott, rscott@mtrob.fdns.net\n");
+#endif  
+#ifdef CONFIG_TELOS
+	printk("Modified for Omnia ToolVox by James D. Schettine, james@telos-systems.com\n");
+#endif
+#endif
+	printk("Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne\n");
+
+#if defined( CONFIG_PILOT ) && defined( CONFIG_M68328 )
+	printk("TRG SuperPilot FLASH card support <info@trgnet.com>\n");
+#endif
+
+#if defined( CONFIG_PILOT ) && defined( CONFIG_M68EZ328 )
+	printk("PalmV support by Lineo Inc. <jeff@uclinux.com>\n");
+#endif
+
+#ifdef CONFIG_M68EZ328ADS
+	printk("M68EZ328ADS board support (C) 1999 Vladimir Gurevich <vgurevic@cisco.com>\n");
+#endif
+
+#ifdef CONFIG_ALMA_ANS
+	printk("Alma Electronics board support (C) 1999 Vladimir Gurevich <vgurevic@cisco.com>\n");
+#endif
+#if defined (CONFIG_M68360)
+	printk("QUICC port done by SED Systems <hamilton@sedsystems.ca>,\n");
+	printk("based on 2.0.38 port by Lineo Inc. <mleslie@lineo.com>.\n");
+#endif
+#ifdef CONFIG_DRAGEN2
+	printk("Dragon Engine II board support by Georges Menie\n");
+#endif
+
+#ifdef DEBUG
+	printk("KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x "
+		"BSS=0x%06x-0x%06x\n", (int) &_stext, (int) &_etext,
+		(int) &_sdata, (int) &_edata,
+		(int) &_sbss, (int) &_ebss);
+	printk("KERNEL -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x "
+		"STACK=0x%06x-0x%06x\n",
+#ifdef CAT_ROMARRAY
+		(int) romarray, ((int) romarray) + romarray[2],
+#else
+		(int) &_ebss, (int) memory_start,
+#endif
+		(int) memory_start, (int) memory_end,
+		(int) memory_end, (int) _ramend);
+#endif
+
+#ifdef CONFIG_BLK_DEV_BLKMEM
+	ROOT_DEV = MKDEV(BLKMEM_MAJOR, 0);
+#endif
+
+	/* Keep a copy of command line */
+	*cmdline_p = &command_line[0];
+	memcpy(saved_command_line, command_line, sizeof(saved_command_line));
+	saved_command_line[sizeof(saved_command_line)-1] = 0;
+
+#ifdef DEBUG
+	if (strlen(*cmdline_p)) 
+		printk("Command line: '%s'\n", *cmdline_p);
+#endif
+
+#ifdef CONFIG_CONSOLE
+#ifdef CONFIG_FRAMEBUFFER
+	conswitchp = &fb_con;
+#else
+	conswitchp = 0;
+#endif
+#endif
+
+	/*
+	 * Give all the memory to the bootmap allocator, tell it to put the
+	 * boot mem_map at the start of memory.
+	 */
+	bootmap_size = init_bootmem_node(
+			NODE_DATA(0),
+			memory_start >> PAGE_SHIFT, /* map goes here */
+			PAGE_OFFSET >> PAGE_SHIFT,	/* 0 on coldfire */
+			memory_end >> PAGE_SHIFT);
+	/*
+	 * Free the usable memory, we have to make sure we do not free
+	 * the bootmem bitmap so we then reserve it after freeing it :-)
+	 */
+	free_bootmem(memory_start, memory_end - memory_start);
+	reserve_bootmem(memory_start, bootmap_size);
+
+	/*
+	 * Get kmalloc into gear.
+	 */
+	paging_init();
+}
+
+int get_cpuinfo(char * buffer)
+{
+    char *cpu, *mmu, *fpu;
+    u_long clockfreq;
+
+    cpu = CPU;
+    mmu = "none";
+    fpu = "none";
+
+#ifdef CONFIG_COLDFIRE
+    clockfreq = (loops_per_jiffy*HZ)*3;
+#else
+    clockfreq = (loops_per_jiffy*HZ)*16;
+#endif
+
+    return(sprintf(buffer, "CPU:\t\t%s\n"
+		   "MMU:\t\t%s\n"
+		   "FPU:\t\t%s\n"
+		   "Clocking:\t%lu.%1luMHz\n"
+		   "BogoMips:\t%lu.%02lu\n"
+		   "Calibration:\t%lu loops\n",
+		   cpu, mmu, fpu,
+		   clockfreq/1000000,(clockfreq/100000)%10,
+		   (loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100,
+		   (loops_per_jiffy*HZ)));
+
+}
+
+/*
+ *	Get CPU information for use by the procfs.
+ */
+
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+    char *cpu, *mmu, *fpu;
+    u_long clockfreq;
+
+    cpu = CPU;
+    mmu = "none";
+    fpu = "none";
+
+#ifdef CONFIG_COLDFIRE
+    clockfreq = (loops_per_jiffy*HZ)*3;
+#else
+    clockfreq = (loops_per_jiffy*HZ)*16;
+#endif
+
+    seq_printf(m, "CPU:\t\t%s\n"
+		   "MMU:\t\t%s\n"
+		   "FPU:\t\t%s\n"
+		   "Clocking:\t%lu.%1luMHz\n"
+		   "BogoMips:\t%lu.%02lu\n"
+		   "Calibration:\t%lu loops\n",
+		   cpu, mmu, fpu,
+		   clockfreq/1000000,(clockfreq/100000)%10,
+		   (loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100,
+		   (loops_per_jiffy*HZ));
+
+	return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+	return *pos < NR_CPUS ? ((void *) 0x12345678) : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	++*pos;
+	return c_start(m, pos);
+}
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+struct seq_operations cpuinfo_op = {
+	start:	c_start,
+	next:	c_next,
+	stop:	c_stop,
+	show:	show_cpuinfo,
+};
+
+void arch_gettod(int *year, int *mon, int *day, int *hour,
+		 int *min, int *sec)
+{
+	if (mach_gettod)
+		mach_gettod(year, mon, day, hour, min, sec);
+	else
+		*year = *mon = *day = *hour = *min = *sec = 0;
+}
+
diff -Nru a/arch/m68knommu/kernel/signal.c b/arch/m68knommu/kernel/signal.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/kernel/signal.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,886 @@
+/*
+ *  linux/arch/m68knommu/kernel/signal.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * 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.
+ */
+
+/*
+ * Linux/m68k support by Hamish Macdonald
+ *
+ * 68060 fixes by Jesper Skov
+ *
+ * 1997-12-01  Modified for POSIX.1b signals by Andreas Schwab
+ *
+ * mathemu support by Roman Zippel
+ *  (Note: fpstate in the signal context is completly ignored for the emulator
+ *         and the internal floating point format is put on stack)
+ */
+
+/*
+ * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
+ * Atari :-) Current limitation: Only one sigstack can be active at one time.
+ * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
+ * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
+ * signal handlers!
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/highuid.h>
+#include <linux/tty.h>
+#include <linux/personality.h>
+#include <linux/binfmts.h>
+
+#include <asm/setup.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/traps.h>
+#include <asm/ucontext.h>
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+asmlinkage long sys_wait4(pid_t pid, unsigned int * stat_addr, int options,
+			struct rusage * ru);
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+asmlinkage int do_sigsuspend(struct pt_regs *regs)
+{
+	old_sigset_t mask = regs->d3;
+	sigset_t saveset;
+
+	mask &= _BLOCKABLE;
+	saveset = current->blocked;
+	siginitset(&current->blocked, mask);
+	recalc_sigpending();
+
+	regs->d0 = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, regs))
+			return -EINTR;
+	}
+}
+
+asmlinkage int
+do_rt_sigsuspend(struct pt_regs *regs)
+{
+	sigset_t *unewset = (sigset_t *)regs->d1;
+	size_t sigsetsize = (size_t)regs->d2;
+	sigset_t saveset, newset;
+
+	/* XXX: Don't preclude handling different sized sigset_t's.  */
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	if (copy_from_user(&newset, unewset, sizeof(newset)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+
+	saveset = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending();
+
+	regs->d0 = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, regs))
+			return -EINTR;
+	}
+}
+
+asmlinkage int 
+sys_sigaction(int sig, const struct old_sigaction *act,
+	      struct old_sigaction *oact)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+
+	if (act) {
+		old_sigset_t mask;
+		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+			return -EFAULT;
+		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		__get_user(mask, &act->sa_mask);
+		siginitset(&new_ka.sa.sa_mask, mask);
+	}
+
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+	if (!ret && oact) {
+		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+			return -EFAULT;
+		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+	}
+
+	return ret;
+}
+
+asmlinkage int
+sys_sigaltstack(const stack_t *uss, stack_t *uoss)
+{
+	return do_sigaltstack(uss, uoss, rdusp());
+}
+
+
+/*
+ * Do a signal return; undo the signal stack.
+ *
+ * Keep the return code on the stack quadword aligned!
+ * That makes the cache flush below easier.
+ */
+
+struct sigframe
+{
+	char *pretcode;
+	int sig;
+	int code;
+	struct sigcontext *psc;
+	char retcode[8];
+	unsigned long extramask[_NSIG_WORDS-1];
+	struct sigcontext sc;
+};
+
+struct rt_sigframe
+{
+	char *pretcode;
+	int sig;
+	struct siginfo *pinfo;
+	void *puc;
+	char retcode[8];
+	struct siginfo info;
+	struct ucontext uc;
+};
+
+#ifdef CONFIG_FPU
+
+static unsigned char fpu_version = 0;	/* version number of fpu, set by setup_frame */
+
+static inline int restore_fpu_state(struct sigcontext *sc)
+{
+	int err = 1;
+
+	if (FPU_IS_EMU) {
+	    /* restore registers */
+	    memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12);
+	    memcpy(current->thread.fp, sc->sc_fpregs, 24);
+	    return 0;
+	}
+
+	if (sc->sc_fpstate[0]) {
+	    /* Verify the frame format.  */
+	    if (sc->sc_fpstate[0] != fpu_version)
+		goto out;
+
+	    __asm__ volatile (".chip 68k/68881\n\t"
+			      "fmovemx %0,%/fp0-%/fp1\n\t"
+			      "fmoveml %1,%/fpcr/%/fpsr/%/fpiar\n\t"
+			      ".chip 68k"
+			      : /* no outputs */
+			      : "m" (*sc->sc_fpregs), "m" (*sc->sc_fpcntl));
+	}
+	__asm__ volatile (".chip 68k/68881\n\t"
+			  "frestore %0\n\t"
+			  ".chip 68k" : : "m" (*sc->sc_fpstate));
+	err = 0;
+
+out:
+	return err;
+}
+
+#define FPCONTEXT_SIZE	216
+#define uc_fpstate	uc_filler[0]
+#define uc_formatvec	uc_filler[FPCONTEXT_SIZE/4]
+#define uc_extra	uc_filler[FPCONTEXT_SIZE/4+1]
+
+static inline int rt_restore_fpu_state(struct ucontext *uc)
+{
+	unsigned char fpstate[FPCONTEXT_SIZE];
+	int context_size = 0;
+	fpregset_t fpregs;
+	int err = 1;
+
+	if (FPU_IS_EMU) {
+		/* restore fpu control register */
+		if (__copy_from_user(current->thread.fpcntl,
+				&uc->uc_mcontext.fpregs.f_pcr, 12))
+			goto out;
+		/* restore all other fpu register */
+		if (__copy_from_user(current->thread.fp,
+				uc->uc_mcontext.fpregs.f_fpregs, 96))
+			goto out;
+		return 0;
+	}
+
+	if (__get_user(*(long *)fpstate, (long *)&uc->uc_fpstate))
+		goto out;
+	if (fpstate[0]) {
+		context_size = fpstate[1];
+
+		/* Verify the frame format.  */
+		if (fpstate[0] != fpu_version)
+			goto out;
+		if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs,
+		     sizeof(fpregs)))
+			goto out;
+		__asm__ volatile (".chip 68k/68881\n\t"
+				  "fmovemx %0,%/fp0-%/fp7\n\t"
+				  "fmoveml %1,%/fpcr/%/fpsr/%/fpiar\n\t"
+				  ".chip 68k"
+				  : /* no outputs */
+				  : "m" (*fpregs.f_fpregs),
+				    "m" (fpregs.f_pcr));
+	}
+	if (context_size &&
+	    __copy_from_user(fpstate + 4, (long *)&uc->uc_fpstate + 1,
+			     context_size))
+		goto out;
+	__asm__ volatile (".chip 68k/68881\n\t"
+			  "frestore %0\n\t"
+			  ".chip 68k" : : "m" (*fpstate));
+	err = 0;
+
+out:
+	return err;
+}
+
+#endif
+
+static inline int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc, void *fp,
+		   int *pd0)
+{
+	int formatvec;
+	struct sigcontext context;
+	int err = 0;
+
+	/* get previous context */
+	if (copy_from_user(&context, usc, sizeof(context)))
+		goto badframe;
+	
+	/* restore passed registers */
+	regs->d1 = context.sc_d1;
+	regs->a0 = context.sc_a0;
+	regs->a1 = context.sc_a1;
+	regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff);
+	regs->pc = context.sc_pc;
+	regs->orig_d0 = -1;		/* disable syscall checks */
+	wrusp(context.sc_usp);
+	formatvec = context.sc_formatvec;
+	regs->format = formatvec >> 12;
+	regs->vector = formatvec & 0xfff;
+
+#ifdef CONFIG_FPU
+	err = restore_fpu_state(&context);
+#endif
+
+	*pd0 = context.sc_d0;
+	return err;
+
+badframe:
+	return 1;
+}
+
+static inline int
+rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
+		    struct ucontext *uc, int *pd0)
+{
+	int temp;
+	greg_t *gregs = uc->uc_mcontext.gregs;
+	unsigned long usp;
+	int err;
+
+	err = __get_user(temp, &uc->uc_mcontext.version);
+	if (temp != MCONTEXT_VERSION)
+		goto badframe;
+	/* restore passed registers */
+	err |= __get_user(regs->d0, &gregs[0]);
+	err |= __get_user(regs->d1, &gregs[1]);
+	err |= __get_user(regs->d2, &gregs[2]);
+	err |= __get_user(regs->d3, &gregs[3]);
+	err |= __get_user(regs->d4, &gregs[4]);
+	err |= __get_user(regs->d5, &gregs[5]);
+	err |= __get_user(sw->d6, &gregs[6]);
+	err |= __get_user(sw->d7, &gregs[7]);
+	err |= __get_user(regs->a0, &gregs[8]);
+	err |= __get_user(regs->a1, &gregs[9]);
+	err |= __get_user(regs->a2, &gregs[10]);
+	err |= __get_user(sw->a3, &gregs[11]);
+	err |= __get_user(sw->a4, &gregs[12]);
+	err |= __get_user(sw->a5, &gregs[13]);
+	err |= __get_user(sw->a6, &gregs[14]);
+	err |= __get_user(usp, &gregs[15]);
+	wrusp(usp);
+	err |= __get_user(regs->pc, &gregs[16]);
+	err |= __get_user(temp, &gregs[17]);
+	regs->sr = (regs->sr & 0xff00) | (temp & 0xff);
+	regs->orig_d0 = -1;		/* disable syscall checks */
+	regs->format = temp >> 12;
+	regs->vector = temp & 0xfff;
+
+	if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)
+		goto badframe;
+
+	*pd0 = regs->d0;
+	return err;
+
+badframe:
+	return 1;
+}
+
+asmlinkage int do_sigreturn(unsigned long __unused)
+{
+	struct switch_stack *sw = (struct switch_stack *) &__unused;
+	struct pt_regs *regs = (struct pt_regs *) (sw + 1);
+	unsigned long usp = rdusp();
+	struct sigframe *frame = (struct sigframe *)(usp - 4);
+	sigset_t set;
+	int d0;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__get_user(set.sig[0], &frame->sc.sc_mask) ||
+	    (_NSIG_WORDS > 1 &&
+	     __copy_from_user(&set.sig[1], &frame->extramask,
+			      sizeof(frame->extramask))))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	current->blocked = set;
+	recalc_sigpending();
+	
+	if (restore_sigcontext(regs, &frame->sc, frame + 1, &d0))
+		goto badframe;
+	return d0;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+asmlinkage int do_rt_sigreturn(unsigned long __unused)
+{
+	struct switch_stack *sw = (struct switch_stack *) &__unused;
+	struct pt_regs *regs = (struct pt_regs *) (sw + 1);
+	unsigned long usp = rdusp();
+	struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4);
+	sigset_t set;
+	int d0;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	current->blocked = set;
+	recalc_sigpending();
+	
+	if (rt_restore_ucontext(regs, sw, &frame->uc, &d0))
+		goto badframe;
+	return d0;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+#ifdef CONFIG_FPU
+/*
+ * Set up a signal frame.
+ */
+
+static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
+{
+	if (FPU_IS_EMU) {
+		/* save registers */
+		memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12);
+		memcpy(sc->sc_fpregs, current->thread.fp, 24);
+		return;
+	}
+
+	__asm__ volatile (".chip 68k/68881\n\t"
+			  "fsave %0\n\t"
+			  ".chip 68k"
+			  : : "m" (*sc->sc_fpstate) : "memory");
+
+	if (sc->sc_fpstate[0]) {
+		fpu_version = sc->sc_fpstate[0];
+		__asm__ volatile (".chip 68k/68881\n\t"
+				  "fmovemx %/fp0-%/fp1,%0\n\t"
+				  "fmoveml %/fpcr/%/fpsr/%/fpiar,%1\n\t"
+				  ".chip 68k"
+				  : /* no outputs */
+				  : "m" (*sc->sc_fpregs),
+				    "m" (*sc->sc_fpcntl)
+				  : "memory");
+	}
+}
+
+static inline int rt_save_fpu_state(struct ucontext *uc, struct pt_regs *regs)
+{
+	unsigned char fpstate[FPCONTEXT_SIZE];
+	int context_size = 0;
+	int err = 0;
+
+	if (FPU_IS_EMU) {
+		/* save fpu control register */
+		err |= copy_to_user(&uc->uc_mcontext.fpregs.f_pcr,
+				current->thread.fpcntl, 12);
+		/* save all other fpu register */
+		err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs,
+				current->thread.fp, 96);
+		return err;
+	}
+
+	__asm__ volatile (".chip 68k/68881\n\t"
+			  "fsave %0\n\t"
+			  ".chip 68k"
+			  : : "m" (*fpstate) : "memory");
+
+	err |= __put_user(*(long *)fpstate, (long *)&uc->uc_fpstate);
+	if (fpstate[0]) {
+		fpregset_t fpregs;
+		context_size = fpstate[1];
+		fpu_version = fpstate[0];
+		__asm__ volatile (".chip 68k/68881\n\t"
+				  "fmovemx %/fp0-%/fp7,%0\n\t"
+				  "fmoveml %/fpcr/%/fpsr/%/fpiar,%1\n\t"
+				  ".chip 68k"
+				  : /* no outputs */
+				  : "m" (*fpregs.f_fpregs),
+				    "m" (fpregs.f_pcr)
+				  : "memory");
+		err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs,
+				    sizeof(fpregs));
+	}
+	if (context_size)
+		err |= copy_to_user((long *)&uc->uc_fpstate + 1, fpstate + 4,
+				    context_size);
+	return err;
+}
+
+#endif
+
+static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
+			     unsigned long mask)
+{
+	sc->sc_mask = mask;
+	sc->sc_usp = rdusp();
+	sc->sc_d0 = regs->d0;
+	sc->sc_d1 = regs->d1;
+	sc->sc_a0 = regs->a0;
+	sc->sc_a1 = regs->a1;
+	sc->sc_sr = regs->sr;
+	sc->sc_pc = regs->pc;
+	sc->sc_formatvec = regs->format << 12 | regs->vector;
+#ifdef CONFIG_FPU
+	save_fpu_state(sc, regs);
+#endif
+}
+
+static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
+{
+	struct switch_stack *sw = (struct switch_stack *)regs - 1;
+	greg_t *gregs = uc->uc_mcontext.gregs;
+	int err = 0;
+
+	err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
+	err |= __put_user(regs->d0, &gregs[0]);
+	err |= __put_user(regs->d1, &gregs[1]);
+	err |= __put_user(regs->d2, &gregs[2]);
+	err |= __put_user(regs->d3, &gregs[3]);
+	err |= __put_user(regs->d4, &gregs[4]);
+	err |= __put_user(regs->d5, &gregs[5]);
+	err |= __put_user(sw->d6, &gregs[6]);
+	err |= __put_user(sw->d7, &gregs[7]);
+	err |= __put_user(regs->a0, &gregs[8]);
+	err |= __put_user(regs->a1, &gregs[9]);
+	err |= __put_user(regs->a2, &gregs[10]);
+	err |= __put_user(sw->a3, &gregs[11]);
+	err |= __put_user(sw->a4, &gregs[12]);
+	err |= __put_user(sw->a5, &gregs[13]);
+	err |= __put_user(sw->a6, &gregs[14]);
+	err |= __put_user(rdusp(), &gregs[15]);
+	err |= __put_user(regs->pc, &gregs[16]);
+	err |= __put_user(regs->sr, &gregs[17]);
+#ifdef CONFIG_FPU
+	err |= rt_save_fpu_state(uc, regs);
+#endif
+	return err;
+}
+
+static inline void push_cache (unsigned long vaddr)
+{
+}
+
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+	unsigned long usp;
+
+	/* Default to using normal stack.  */
+	usp = rdusp();
+
+	/* This is the X/Open sanctioned signal stack switching.  */
+	if (ka->sa.sa_flags & SA_ONSTACK) {
+		if (!on_sig_stack(usp))
+			usp = current->sas_ss_sp + current->sas_ss_size;
+	}
+	return (void *)((usp - frame_size) & -8UL);
+}
+
+static void setup_frame (int sig, struct k_sigaction *ka,
+			 sigset_t *set, struct pt_regs *regs)
+{
+	struct sigframe *frame;
+	struct sigcontext context;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	err |= __put_user((current_thread_info()->exec_domain
+			   && current_thread_info()->exec_domain->signal_invmap
+			   && sig < 32
+			   ? current_thread_info()->exec_domain->signal_invmap[sig]
+			   : sig),
+			  &frame->sig);
+
+	err |= __put_user(regs->vector, &frame->code);
+	err |= __put_user(&frame->sc, &frame->psc);
+
+	if (_NSIG_WORDS > 1)
+		err |= copy_to_user(frame->extramask, &set->sig[1],
+				    sizeof(frame->extramask));
+
+	setup_sigcontext(&context, regs, set->sig[0]);
+	err |= copy_to_user (&frame->sc, &context, sizeof(context));
+
+	/* Set up to return from userspace.  */
+	err |= __put_user(frame->retcode, &frame->pretcode);
+	/* moveq #,d0; trap #0 */
+	err |= __put_user(0x70004e40 + (__NR_sigreturn << 16),
+			  (long *)(frame->retcode));
+
+	if (err)
+		goto give_sigsegv;
+
+	push_cache ((unsigned long) &frame->retcode);
+
+	/* Set up registers for signal handler */
+	wrusp ((unsigned long) frame);
+	regs->pc = (unsigned long) ka->sa.sa_handler;
+
+adjust_stack:
+	/* Prepare to skip over the extra stuff in the exception frame.  */
+	if (regs->stkadj) {
+		struct pt_regs *tregs =
+			(struct pt_regs *)((ulong)regs + regs->stkadj);
+#if DEBUG
+		printk("Performing stackadjust=%04x\n", regs->stkadj);
+#endif
+		/* This must be copied with decreasing addresses to
+                   handle overlaps.  */
+		tregs->vector = 0;
+		tregs->format = 0;
+		tregs->pc = regs->pc;
+		tregs->sr = regs->sr;
+	}
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+	goto adjust_stack;
+}
+
+static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
+			    sigset_t *set, struct pt_regs *regs)
+{
+	struct rt_sigframe *frame;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	err |= __put_user((current_thread_info()->exec_domain
+			   && current_thread_info()->exec_domain->signal_invmap
+			   && sig < 32
+			   ? current_thread_info()->exec_domain->signal_invmap[sig]
+			   : sig),
+			  &frame->sig);
+	err |= __put_user(&frame->info, &frame->pinfo);
+	err |= __put_user(&frame->uc, &frame->puc);
+	err |= copy_siginfo_to_user(&frame->info, info);
+
+	/* Create the ucontext.  */
+	err |= __put_user(0, &frame->uc.uc_flags);
+	err |= __put_user(0, &frame->uc.uc_link);
+	err |= __put_user((void *)current->sas_ss_sp,
+			  &frame->uc.uc_stack.ss_sp);
+	err |= __put_user(sas_ss_flags(rdusp()),
+			  &frame->uc.uc_stack.ss_flags);
+	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+	err |= rt_setup_ucontext(&frame->uc, regs);
+	err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
+
+	/* Set up to return from userspace.  */
+	err |= __put_user(frame->retcode, &frame->pretcode);
+	/* moveq #,d0; notb d0; trap #0 */
+	err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16),
+			  (long *)(frame->retcode + 0));
+	err |= __put_user(0x4e40, (short *)(frame->retcode + 4));
+
+	if (err)
+		goto give_sigsegv;
+
+	push_cache ((unsigned long) &frame->retcode);
+
+	/* Set up registers for signal handler */
+	wrusp ((unsigned long) frame);
+	regs->pc = (unsigned long) ka->sa.sa_handler;
+
+adjust_stack:
+	/* Prepare to skip over the extra stuff in the exception frame.  */
+	if (regs->stkadj) {
+		struct pt_regs *tregs =
+			(struct pt_regs *)((ulong)regs + regs->stkadj);
+#if DEBUG
+		printk("Performing stackadjust=%04x\n", regs->stkadj);
+#endif
+		/* This must be copied with decreasing addresses to
+                   handle overlaps.  */
+		tregs->vector = 0;
+		tregs->format = 0;
+		tregs->pc = regs->pc;
+		tregs->sr = regs->sr;
+	}
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+	goto adjust_stack;
+}
+
+static inline void
+handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
+{
+	switch (regs->d0) {
+	case -ERESTARTNOHAND:
+		if (!has_handler)
+			goto do_restart;
+		regs->d0 = -EINTR;
+		break;
+
+	case -ERESTARTSYS:
+		if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
+			regs->d0 = -EINTR;
+			break;
+		}
+	/* fallthrough */
+	case -ERESTARTNOINTR:
+	do_restart:
+		regs->d0 = regs->orig_d0;
+		regs->pc -= 2;
+		break;
+	}
+}
+
+/*
+ * OK, we're invoking a handler
+ */
+static void
+handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
+	      sigset_t *oldset, struct pt_regs *regs)
+{
+	/* are we from a system call? */
+	if (regs->orig_d0 >= 0)
+		/* If so, check system call restarting.. */
+		handle_restart(regs, ka, 1);
+
+	/* set up the stack frame */
+	if (ka->sa.sa_flags & SA_SIGINFO)
+		setup_rt_frame(sig, ka, info, oldset, regs);
+	else
+		setup_frame(sig, ka, oldset, regs);
+
+	if (ka->sa.sa_flags & SA_ONESHOT)
+		ka->sa.sa_handler = SIG_DFL;
+
+	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+	if (!(ka->sa.sa_flags & SA_NODEFER))
+		sigaddset(&current->blocked,sig);
+	recalc_sigpending();
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ *
+ * Note that we go through the signals twice: once to check the signals
+ * that the kernel can handle, and then we build all the user-level signal
+ * handling stack-frames in one go after that.
+ */
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
+{
+	siginfo_t info;
+	struct k_sigaction *ka;
+
+	current->thread.esp0 = (unsigned long) regs;
+
+	if (!oldset)
+		oldset = &current->blocked;
+
+	for (;;) {
+		int signr;
+
+		signr = get_signal_to_deliver(&info, regs);
+
+		if (!signr)
+			break;
+
+		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+			current->exit_code = signr;
+			current->state = TASK_STOPPED;
+			regs->sr &= ~PS_T;
+
+			/* Did we come from a system call? */
+			if (regs->orig_d0 >= 0) {
+				/* Restart the system call the same way as
+				   if the process were not traced.  */
+				struct k_sigaction *ka =
+					&current->sig->action[signr-1];
+				int has_handler =
+					(ka->sa.sa_handler != SIG_IGN &&
+					 ka->sa.sa_handler != SIG_DFL);
+				handle_restart(regs, ka, has_handler);
+			}
+			notify_parent(current, SIGCHLD);
+			schedule();
+
+			/* We're back.  Did the debugger cancel the sig?  */
+			if (!(signr = current->exit_code)) {
+			discard_frame:
+			    continue;
+			}
+			current->exit_code = 0;
+
+			/* The debugger continued.  Ignore SIGSTOP.  */
+			if (signr == SIGSTOP)
+				goto discard_frame;
+
+			/* Update the siginfo structure.  Is this good?  */
+			if (signr != info.si_signo) {
+				info.si_signo = signr;
+				info.si_errno = 0;
+				info.si_code = SI_USER;
+				info.si_pid = current->parent->pid;
+				info.si_uid = current->parent->uid;
+			}
+
+			/* If the (new) signal is now blocked, requeue it.  */
+			if (sigismember(&current->blocked, signr)) {
+				send_sig_info(signr, &info, current);
+				continue;
+			}
+		}
+
+		ka = &current->sig->action[signr-1];
+		if (ka->sa.sa_handler == SIG_IGN) {
+			if (signr != SIGCHLD)
+				continue;
+			/* Check for SIGCHLD: it's special.  */
+			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+				/* nothing */;
+			continue;
+		}
+
+		if (ka->sa.sa_handler == SIG_DFL) {
+			int exit_code = signr;
+
+			if (current->pid == 1)
+				continue;
+
+			switch (signr) {
+			case SIGCONT: case SIGCHLD:
+			case SIGWINCH: case SIGURG:
+				continue;
+
+			case SIGTSTP: case SIGTTIN: case SIGTTOU:
+				if (is_orphaned_pgrp(current->pgrp))
+					continue;
+				/* FALLTHRU */
+
+			case SIGSTOP:
+				current->state = TASK_STOPPED;
+				current->exit_code = signr;
+				if (!(current->parent->sig->action[SIGCHLD-1]
+				      .sa.sa_flags & SA_NOCLDSTOP))
+					notify_parent(current, SIGCHLD);
+				schedule();
+				continue;
+
+			case SIGQUIT: case SIGILL: case SIGTRAP:
+			case SIGIOT: case SIGFPE: case SIGSEGV:
+			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
+				if (do_coredump(signr, regs))
+					exit_code |= 0x80;
+				/* FALLTHRU */
+
+			default:
+				sigaddset(&current->pending.signal, signr);
+				recalc_sigpending();
+				current->flags |= PF_SIGNALED;
+				do_exit(exit_code);
+				/* NOTREACHED */
+			}
+		}
+
+		/* Whee!  Actually deliver the signal.  */
+		handle_signal(signr, ka, &info, oldset, regs);
+		return 1;
+	}
+
+	/* Did we come from a system call? */
+	if (regs->orig_d0 >= 0)
+		/* Restart the system call - no handlers present */
+		handle_restart(regs, NULL, 0);
+
+	/* If we are about to discard some frame stuff we must copy
+	   over the remaining frame. */
+	if (regs->stkadj) {
+		struct pt_regs *tregs =
+		  (struct pt_regs *) ((ulong) regs + regs->stkadj);
+
+		/* This must be copied with decreasing addresses to
+		   handle overlaps.  */
+		tregs->vector = 0;
+		tregs->format = 0;
+		tregs->pc = regs->pc;
+		tregs->sr = regs->sr;
+	}
+	return 0;
+}
diff -Nru a/arch/m68knommu/kernel/sys_m68k.c b/arch/m68knommu/kernel/sys_m68k.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/kernel/sys_m68k.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,215 @@
+/*
+ * linux/arch/m68knommu/kernel/sys_m68k.c
+ *
+ * This file contains various random system calls that
+ * have a non-standard calling sequence on the Linux/m68k
+ * platform.
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/mman.h>
+#include <linux/file.h>
+#include <linux/utsname.h>
+
+#include <asm/setup.h>
+#include <asm/uaccess.h>
+#include <asm/cachectl.h>
+#include <asm/traps.h>
+#include <asm/ipc.h>
+#include <asm/cacheflush.h>
+
+/*
+ * sys_pipe() is the normal C calling standard for creating
+ * a pipe. It's not the way unix traditionally does this, though.
+ */
+asmlinkage int sys_pipe(unsigned long * fildes)
+{
+	int fd[2];
+	int error;
+
+	error = do_pipe(fd);
+	if (!error) {
+		if (copy_to_user(fildes, fd, 2*sizeof(int)))
+			error = -EFAULT;
+	}
+	return error;
+}
+
+/* common code for old and new mmaps */
+static inline long do_mmap2(
+	unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags,
+	unsigned long fd, unsigned long pgoff)
+{
+	int error = -EBADF;
+	struct file * file = NULL;
+
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+	if (!(flags & MAP_ANONYMOUS)) {
+		file = fget(fd);
+		if (!file)
+			goto out;
+	}
+
+	down_write(&current->mm->mmap_sem);
+	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+	up_write(&current->mm->mmap_sem);
+
+	if (file)
+		fput(file);
+out:
+	return error;
+}
+
+asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags,
+	unsigned long fd, unsigned long pgoff)
+{
+	return do_mmap2(addr, len, prot, flags, fd, pgoff);
+}
+
+/*
+ * Perform the select(nd, in, out, ex, tv) and mmap() system
+ * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
+ * handle more than 4 system call parameters, so these system calls
+ * used a memory block for parameter passing..
+ */
+
+struct mmap_arg_struct {
+	unsigned long addr;
+	unsigned long len;
+	unsigned long prot;
+	unsigned long flags;
+	unsigned long fd;
+	unsigned long offset;
+};
+
+asmlinkage int old_mmap(struct mmap_arg_struct *arg)
+{
+	struct mmap_arg_struct a;
+	int error = -EFAULT;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		goto out;
+
+	error = -EINVAL;
+	if (a.offset & ~PAGE_MASK)
+		goto out;
+
+	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
+out:
+	return error;
+}
+
+extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+
+struct sel_arg_struct {
+	unsigned long n;
+	fd_set *inp, *outp, *exp;
+	struct timeval *tvp;
+};
+
+asmlinkage int old_select(struct sel_arg_struct *arg)
+{
+	struct sel_arg_struct a;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		return -EFAULT;
+	/* sys_select() does the appropriate kernel locking */
+	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
+}
+
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly.
+ */
+asmlinkage int sys_ipc (uint call, int first, int second,
+			int third, void *ptr, long fifth)
+{
+	int version;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	if (call <= SEMCTL)
+		switch (call) {
+		case SEMOP:
+			return sys_semop (first, (struct sembuf *)ptr, second);
+		case SEMGET:
+			return sys_semget (first, second, third);
+		case SEMCTL: {
+			union semun fourth;
+			if (!ptr)
+				return -EINVAL;
+			if (get_user(fourth.__pad, (void **) ptr))
+				return -EFAULT;
+			return sys_semctl (first, second, third, fourth);
+			}
+		default:
+			return -EINVAL;
+		}
+	if (call <= MSGCTL) 
+		switch (call) {
+		case MSGSND:
+			return sys_msgsnd (first, (struct msgbuf *) ptr, 
+					  second, third);
+		case MSGRCV:
+			switch (version) {
+			case 0: {
+				struct ipc_kludge tmp;
+				if (!ptr)
+					return -EINVAL;
+				if (copy_from_user (&tmp,
+						    (struct ipc_kludge *)ptr,
+						    sizeof (tmp)))
+					return -EFAULT;
+				return sys_msgrcv (first, tmp.msgp, second,
+						   tmp.msgtyp, third);
+				}
+			default:
+				return sys_msgrcv (first,
+						   (struct msgbuf *) ptr,
+						   second, fifth, third);
+			}
+		case MSGGET:
+			return sys_msgget ((key_t) first, second);
+		case MSGCTL:
+			return sys_msgctl (first, second,
+					   (struct msqid_ds *) ptr);
+		default:
+			return -EINVAL;
+		}
+
+	return -EINVAL;
+}
+
+asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on)
+{
+  return -ENOSYS;
+}
+
+
+/* sys_cacheflush -- flush (part of) the processor cache.  */
+asmlinkage int
+sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
+{
+	flush_cache_all();
+	return(0);
+}
+
+asmlinkage int sys_getpagesize(void)
+{
+	return PAGE_SIZE;
+}
+
diff -Nru a/arch/m68knommu/kernel/syscalltable.S b/arch/m68knommu/kernel/syscalltable.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/kernel/syscalltable.S	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,279 @@
+/*
+ *  linux/arch/m68knommu/kernel/syscalltable.S
+ *
+ *  Copyright (C) 2002, Greg Ungerer (gerg@snapgear.com)
+ *
+ *  Based on older entry.S files, the following copyrights apply:
+ *
+ *  Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>,
+ *                      Kenneth Albanowski <kjahds@kjahds.com>,
+ *  Copyright (C) 2000  Lineo Inc. (www.lineo.com) 
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+#include <linux/config.h>
+#include <linux/sys.h>
+#include <linux/linkage.h>
+
+.text
+ALIGN
+ENTRY(sys_call_table)
+	.long sys_ni_syscall	/* 0  -  old "setup()" system call*/
+	.long sys_exit
+	.long sys_fork
+	.long sys_read
+	.long sys_write
+	.long sys_open		/* 5 */
+	.long sys_close
+	.long sys_waitpid
+	.long sys_creat
+	.long sys_link
+	.long sys_unlink	/* 10 */
+	.long sys_execve
+	.long sys_chdir
+	.long sys_time
+	.long sys_mknod
+	.long sys_chmod		/* 15 */
+	.long sys_chown16
+	.long sys_ni_syscall	/* old break syscall holder */
+	.long sys_stat
+	.long sys_lseek
+	.long sys_getpid	/* 20 */
+	.long sys_mount
+	.long sys_oldumount
+	.long sys_setuid16
+	.long sys_getuid16
+	.long sys_stime		/* 25 */
+	.long sys_ptrace
+	.long sys_alarm
+	.long sys_fstat
+	.long sys_pause
+	.long sys_utime		/* 30 */
+	.long sys_ni_syscall	/* old stty syscall holder */
+	.long sys_ni_syscall	/* old gtty syscall holder */
+	.long sys_access
+	.long sys_nice
+	.long sys_ni_syscall	/* 35 */ /* old ftime syscall holder */
+	.long sys_sync
+	.long sys_kill
+	.long sys_rename
+	.long sys_mkdir
+	.long sys_rmdir		/* 40 */
+	.long sys_dup
+	.long sys_pipe
+	.long sys_times
+	.long sys_ni_syscall	/* old prof syscall holder */
+	.long sys_brk		/* 45 */
+	.long sys_setgid16
+	.long sys_getgid16
+	.long sys_signal
+	.long sys_geteuid16
+	.long sys_getegid16	/* 50 */
+	.long sys_acct
+	.long sys_umount	/* recycled never used phys() */
+	.long sys_ni_syscall	/* old lock syscall holder */
+	.long sys_ioctl
+	.long sys_fcntl		/* 55 */
+	.long sys_ni_syscall	/* old mpx syscall holder */
+	.long sys_setpgid
+	.long sys_ni_syscall	/* old ulimit syscall holder */
+	.long sys_ni_syscall
+	.long sys_umask		/* 60 */
+	.long sys_chroot
+	.long sys_ustat
+	.long sys_dup2
+	.long sys_getppid
+	.long sys_getpgrp	/* 65 */
+	.long sys_setsid
+	.long sys_sigaction
+	.long sys_sgetmask
+	.long sys_ssetmask
+	.long sys_setreuid16	/* 70 */
+	.long sys_setregid16
+	.long sys_sigsuspend
+	.long sys_sigpending
+	.long sys_sethostname
+	.long sys_setrlimit	/* 75 */
+	.long sys_old_getrlimit
+	.long sys_getrusage
+	.long sys_gettimeofday
+	.long sys_settimeofday
+	.long sys_getgroups16	/* 80 */
+	.long sys_setgroups16
+	.long old_select
+	.long sys_symlink
+	.long sys_lstat
+	.long sys_readlink	/* 85 */
+	.long sys_uselib
+	.long sys_ni_syscall	/* sys_swapon */
+	.long sys_reboot
+	.long old_readdir
+	.long old_mmap		/* 90 */
+	.long sys_munmap
+	.long sys_truncate
+	.long sys_ftruncate
+	.long sys_fchmod
+	.long sys_fchown16	/* 95 */
+	.long sys_getpriority
+	.long sys_setpriority
+	.long sys_ni_syscall	/* old profil syscall holder */
+	.long sys_statfs
+	.long sys_fstatfs	/* 100 */
+	.long sys_ioperm
+	.long sys_socketcall
+	.long sys_syslog
+	.long sys_setitimer
+	.long sys_getitimer	/* 105 */
+	.long sys_newstat
+	.long sys_newlstat
+	.long sys_newfstat
+	.long sys_ni_syscall
+	.long sys_ni_syscall	/* iopl for i386 */ /* 110 */
+	.long sys_vhangup
+	.long sys_ni_syscall	/* obsolete idle() syscall */
+	.long sys_ni_syscall	/* vm86old for i386 */
+	.long sys_wait4
+	.long sys_ni_syscall	/* 115 */ /* sys_swapoff */
+	.long sys_sysinfo
+	.long sys_ipc
+	.long sys_fsync
+	.long sys_sigreturn
+	.long sys_clone		/* 120 */
+	.long sys_setdomainname
+	.long sys_newuname
+	.long sys_cacheflush	/* modify_ldt for i386 */
+	.long sys_adjtimex
+	.long sys_ni_syscall	/* 125 */ /* sys_mprotect */
+	.long sys_sigprocmask
+	.long sys_create_module
+	.long sys_init_module
+	.long sys_delete_module
+	.long sys_get_kernel_syms /* 130 */
+	.long sys_quotactl
+	.long sys_getpgid
+	.long sys_fchdir
+	.long sys_bdflush
+	.long sys_sysfs		/* 135 */
+	.long sys_personality
+	.long sys_ni_syscall	/* for afs_syscall */
+	.long sys_setfsuid16
+	.long sys_setfsgid16
+	.long sys_llseek	/* 140 */
+	.long sys_getdents
+	.long sys_select
+	.long sys_flock
+	.long sys_ni_syscall	/* sys_msync */
+	.long sys_readv		/* 145 */
+	.long sys_writev
+	.long sys_getsid
+	.long sys_fdatasync
+	.long sys_sysctl
+	.long sys_ni_syscall	/* 150 */ /* sys_mlock */
+	.long sys_ni_syscall	/* sys_munlock */
+	.long sys_ni_syscall	/* sys_mlockall */
+	.long sys_ni_syscall	/* sys_munlockall */
+	.long sys_sched_setparam
+	.long sys_sched_getparam /* 155 */
+	.long sys_sched_setscheduler
+	.long sys_sched_getscheduler
+	.long sys_sched_yield
+	.long sys_sched_get_priority_max
+	.long sys_sched_get_priority_min  /* 160 */
+	.long sys_sched_rr_get_interval
+	.long sys_nanosleep
+	.long sys_ni_syscall	/* sys_mremap */
+	.long sys_setresuid16
+	.long sys_getresuid16	/* 165 */
+	.long sys_ni_syscall	/* for vm86 */
+	.long sys_query_module
+	.long sys_poll
+	.long sys_ni_syscall	/*sys_nfsservctl*/
+	.long sys_setresgid16	/* 170 */
+	.long sys_getresgid16
+	.long sys_prctl
+	.long sys_rt_sigreturn
+	.long sys_rt_sigaction
+	.long sys_rt_sigprocmask /* 175 */
+	.long sys_rt_sigpending
+	.long sys_rt_sigtimedwait
+	.long sys_rt_sigqueueinfo
+	.long sys_rt_sigsuspend
+	.long sys_pread64	/* 180 */
+	.long sys_pwrite64
+	.long sys_lchown16
+	.long sys_getcwd
+	.long sys_capget
+	.long sys_capset	/* 185 */
+	.long sys_sigaltstack
+	.long sys_sendfile
+	.long sys_ni_syscall	/* streams1 */
+	.long sys_ni_syscall	/* streams2 */
+	.long sys_vfork		/* 190 */
+	.long sys_getrlimit
+	.long sys_mmap2
+	.long sys_truncate64
+	.long sys_ftruncate64
+	.long sys_stat64	/* 195 */
+	.long sys_lstat64
+	.long sys_fstat64
+	.long sys_chown
+	.long sys_getuid
+	.long sys_getgid	/* 200 */
+	.long sys_geteuid
+	.long sys_getegid
+	.long sys_setreuid
+	.long sys_setregid
+	.long sys_getgroups	/* 205 */
+	.long sys_setgroups
+	.long sys_fchown
+	.long sys_setresuid
+	.long sys_getresuid
+	.long sys_setresgid	/* 210 */
+	.long sys_getresgid
+	.long sys_lchown
+	.long sys_setuid
+	.long sys_setgid
+	.long sys_setfsuid	/* 215 */
+	.long sys_setfsgid
+	.long sys_pivot_root
+	.long sys_mincore
+	.long sys_ni_syscall	/* sys_madvise */
+	.long sys_getdents64	/* 220 */
+	.long sys_fcntl64
+	.long sys_ni_syscall	/* reserved for TUX */
+	.long sys_security	/* reserved for Security */
+	.long sys_gettid
+	.long sys_ni_syscall	/* 225 */ /* sys_readahead */
+	.long sys_setxattr
+	.long sys_lsetxattr
+	.long sys_fsetxattr
+	.long sys_getxattr
+	.long sys_lgetxattr	/* 230 */
+	.long sys_fgetxattr
+	.long sys_listxattr
+	.long sys_llistxattr
+	.long sys_flistxattr
+	.long sys_removexattr	/* 235 */
+	.long sys_lremovexattr
+	.long sys_fremovexattr
+	.long sys_tkill
+	.long sys_sendfile64
+	.long sys_futex		/* 240 */
+	.long sys_sched_setaffinity
+	.long sys_sched_getaffinity
+	.long sys_ni_syscall	/* sys_set_thread_area */
+	.long sys_ni_syscall	/* sys_get_thread_area */
+	.long sys_io_setup	/* 245 */
+	.long sys_io_destroy
+	.long sys_io_getevents
+	.long sys_io_submit
+	.long sys_io_cancel
+	.long sys_ni_syscall	/* 250 */ /* sys_alloc_hugepages */
+	.long sys_ni_syscall	/* sys_freec_hugepages */
+	.long sys_exit_group
+	.long sys_lookup_dcookie
+
+	.rept NR_syscalls-(.-sys_call_table)/4
+		.long sys_ni_syscall
+	.endr
+
diff -Nru a/arch/m68knommu/kernel/time.c b/arch/m68knommu/kernel/time.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/kernel/time.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,178 @@
+/*
+ *  linux/arch/m68knommu/kernel/time.c
+ *
+ *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
+ *
+ * This file contains the m68k-specific time handling details.
+ * Most of the stuff is located in the machine specific files.
+ *
+ * 1997-09-10	Updated NTP code according to technical memorandum Jan '96
+ *		"A Kernel Model for Precision Timekeeping" by Dave Mills
+ */
+
+#include <linux/config.h>
+#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/profile.h>
+#include <linux/timex.h>
+
+#include <asm/machdep.h>
+#include <asm/io.h>
+
+#define	TICK_SIZE (tick_nsec / 1000)
+
+u64 jiffies_64;
+
+static inline int set_rtc_mmss(unsigned long nowtime)
+{
+	if (mach_set_clock_mmss)
+		return mach_set_clock_mmss (nowtime);
+	return -1;
+}
+
+static inline void do_profile (unsigned long pc)
+{
+	if (prof_buffer && current->pid) {
+		extern int _stext;
+		pc -= (unsigned long) &_stext;
+		pc >>= prof_shift;
+		if (pc < prof_len)
+			++prof_buffer[pc];
+		else
+		/*
+		 * Don't ignore out-of-bounds PC values silently,
+		 * put them into the last histogram slot, so if
+		 * present, they will show up as a sharp peak.
+		 */
+			++prof_buffer[prof_len-1];
+	}
+}
+
+/*
+ * timer_interrupt() needs to keep up the real-time clock,
+ * as well as call the "do_timer()" routine every clocktick
+ */
+static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
+{
+	/* last time the cmos clock got updated */
+	static long last_rtc_update=0;
+
+	/* may need to kick the hardware timer */
+	if (mach_tick)
+	  mach_tick();
+
+	do_timer(regs);
+
+	if (!user_mode(regs))
+		do_profile(regs->pc);
+
+	/*
+	 * If we have an externally synchronized Linux clock, then update
+	 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+	 * called as close as possible to 500 ms before the new second starts.
+	 */
+	if ((time_status & STA_UNSYNC) == 0 &&
+	    xtime.tv_sec > last_rtc_update + 660 &&
+	    (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
+	    (xtime.tv_nsec  / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
+	  if (set_rtc_mmss(xtime.tv_sec) == 0)
+	    last_rtc_update = xtime.tv_sec;
+	  else
+	    last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+	}
+#ifdef CONFIG_HEARTBEAT
+	/* use power LED as a heartbeat instead -- much more useful
+	   for debugging -- based on the version for PReP by Cort */
+	/* acts like an actual heart beat -- ie thump-thump-pause... */
+	if (mach_heartbeat) {
+	    static unsigned cnt = 0, period = 0, dist = 0;
+
+	    if (cnt == 0 || cnt == dist)
+		mach_heartbeat( 1 );
+	    else if (cnt == 7 || cnt == dist+7)
+		mach_heartbeat( 0 );
+
+	    if (++cnt > period) {
+		cnt = 0;
+		/* The hyperbolic function below modifies the heartbeat period
+		 * length in dependency of the current (5min) load. It goes
+		 * through the points f(0)=126, f(1)=86, f(5)=51,
+		 * f(inf)->30. */
+		period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
+		dist = period / 4;
+	    }
+	}
+#endif /* CONFIG_HEARTBEAT */
+}
+
+void time_init(void)
+{
+	unsigned int year, mon, day, hour, min, sec;
+
+	extern void arch_gettod(int *year, int *mon, int *day, int *hour,
+				int *min, int *sec);
+
+	arch_gettod(&year, &mon, &day, &hour, &min, &sec);
+
+	if ((year += 1900) < 1970)
+		year += 100;
+	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
+	xtime.tv_nsec = 0;
+
+	mach_sched_init(timer_interrupt);
+}
+
+extern rwlock_t xtime_lock;
+
+/*
+ * This version of gettimeofday has near microsecond resolution.
+ */
+void do_gettimeofday(struct timeval *tv)
+{
+	unsigned long flags;
+	unsigned long usec, sec;
+
+	read_lock_irqsave(&xtime_lock, flags);
+	usec = mach_gettimeoffset ? mach_gettimeoffset() : 0;
+	sec = xtime.tv_sec;
+	usec += (xtime.tv_nsec / 1000);
+	read_unlock_irqrestore(&xtime_lock, flags);
+
+	while (usec >= 1000000) {
+		usec -= 1000000;
+		sec++;
+	}
+
+	tv->tv_sec = sec;
+	tv->tv_usec = usec;
+}
+
+void do_settimeofday(struct timeval *tv)
+{
+	write_lock_irq(&xtime_lock);
+	/* This is revolting. We need to set the xtime.tv_usec
+	 * correctly. However, the value in this location is
+	 * is value at the last tick.
+	 * Discover what correction gettimeofday
+	 * would have done, and then undo it!
+	 */
+	if (mach_gettimeoffset)
+		tv->tv_usec -= mach_gettimeoffset();
+
+	while (tv->tv_usec < 0) {
+		tv->tv_usec += 1000000;
+		tv->tv_sec--;
+	}
+
+	xtime.tv_sec = tv->tv_sec;
+	xtime.tv_nsec = (tv->tv_usec * 1000);
+	time_adjust = 0;		/* stop active adjtime() */
+	time_status |= STA_UNSYNC;
+	time_maxerror = NTP_PHASE_LIMIT;
+	time_esterror = NTP_PHASE_LIMIT;
+	write_unlock_irq(&xtime_lock);
+}
diff -Nru a/arch/m68knommu/kernel/traps.c b/arch/m68knommu/kernel/traps.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/kernel/traps.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,313 @@
+/*
+ *  linux/arch/m68knommu/kernel/traps.c
+ *
+ *  Copyright (C) 1993, 1994 by Hamish Macdonald
+ *
+ *  68040 fixes by Michael Rausch
+ *  68040 fixes by Martin Apel
+ *  68060 fixes by Roman Hodek
+ *  68060 fixes by Jesper Skov
+ *
+ * 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.
+ */
+
+/*
+ * Sets up all exception vectors
+ */
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/types.h>
+#include <linux/a.out.h>
+#include <linux/user.h>
+#include <linux/string.h>
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+#include <asm/setup.h>
+#include <asm/fpu.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/traps.h>
+#include <asm/pgtable.h>
+#include <asm/machdep.h>
+#include <asm/siginfo.h>
+
+static char *vec_names[] = {
+	"RESET SP", "RESET PC", "BUS ERROR", "ADDRESS ERROR",
+	"ILLEGAL INSTRUCTION", "ZERO DIVIDE", "CHK", "TRAPcc",
+	"PRIVILEGE VIOLATION", "TRACE", "LINE 1010", "LINE 1111",
+	"UNASSIGNED RESERVED 12", "COPROCESSOR PROTOCOL VIOLATION",
+	"FORMAT ERROR", "UNINITIALIZED INTERRUPT",
+	"UNASSIGNED RESERVED 16", "UNASSIGNED RESERVED 17",
+	"UNASSIGNED RESERVED 18", "UNASSIGNED RESERVED 19",
+	"UNASSIGNED RESERVED 20", "UNASSIGNED RESERVED 21",
+	"UNASSIGNED RESERVED 22", "UNASSIGNED RESERVED 23",
+	"SPURIOUS INTERRUPT", "LEVEL 1 INT", "LEVEL 2 INT", "LEVEL 3 INT",
+	"LEVEL 4 INT", "LEVEL 5 INT", "LEVEL 6 INT", "LEVEL 7 INT",
+	"SYSCALL", "TRAP #1", "TRAP #2", "TRAP #3",
+	"TRAP #4", "TRAP #5", "TRAP #6", "TRAP #7",
+	"TRAP #8", "TRAP #9", "TRAP #10", "TRAP #11",
+	"TRAP #12", "TRAP #13", "TRAP #14", "TRAP #15",
+	"FPCP BSUN", "FPCP INEXACT", "FPCP DIV BY 0", "FPCP UNDERFLOW",
+	"FPCP OPERAND ERROR", "FPCP OVERFLOW", "FPCP SNAN",
+	"FPCP UNSUPPORTED OPERATION",
+	"MMU CONFIGURATION ERROR"
+};
+
+void __init trap_init(void)
+{
+	if (mach_trap_init)
+		mach_trap_init();
+}
+
+void die_if_kernel(char *str, struct pt_regs *fp, int nr)
+{
+	if (!(fp->sr & PS_S))
+		return;
+
+	console_verbose();
+	printk("%s: %08x\n",str,nr);
+	printk("PC: [<%08lx>]\nSR: %04x  SP: %p  a2: %08lx\n",
+	       fp->pc, fp->sr, fp, fp->a2);
+	printk("d0: %08lx    d1: %08lx    d2: %08lx    d3: %08lx\n",
+	       fp->d0, fp->d1, fp->d2, fp->d3);
+	printk("d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
+	       fp->d4, fp->d5, fp->a0, fp->a1);
+
+	printk("Process %s (pid: %d, stackpage=%08lx)\n",
+		current->comm, current->pid, PAGE_SIZE+(unsigned long)current);
+	show_stack((unsigned long *)fp);
+	do_exit(SIGSEGV);
+}
+
+asmlinkage void buserr_c(struct frame *fp)
+{
+	/* Only set esp0 if coming from user mode */
+	if (user_mode(&fp->ptregs))
+		current->thread.esp0 = (unsigned long) fp;
+
+#if DEBUG
+	printk ("*** Bus Error *** Format is %x\n", fp->ptregs.format);
+#endif
+
+	die_if_kernel("bad frame format",&fp->ptregs,0);
+#if DEBUG
+	printk("Unknown SIGSEGV - 4\n");
+#endif
+	force_sig(SIGSEGV, current);
+}
+
+
+int kstack_depth_to_print = 48;
+
+void show_stack(unsigned long *esp)
+{
+	unsigned long *stack, *endstack, addr;
+	extern char _start, _etext;
+	int i;
+
+	if (esp == NULL)
+		esp = (unsigned long *) &esp;
+
+	stack = esp;
+	addr = (unsigned long) esp;
+	endstack = (unsigned long *) PAGE_ALIGN(addr);
+
+	printk("Stack from %08lx:", (unsigned long)stack);
+	for (i = 0; i < kstack_depth_to_print; i++) {
+		if (stack + 1 > endstack)
+			break;
+		if (i % 8 == 0)
+			printk("\n       ");
+		printk(" %08lx", *stack++);
+	}
+
+	printk("\nCall Trace:");
+	i = 0;
+	while (stack + 1 <= endstack) {
+		addr = *stack++;
+		/*
+		 * If the address is either in the text segment of the
+		 * kernel, or in the region which contains vmalloc'ed
+		 * memory, it *may* be the address of a calling
+		 * routine; if so, print it so that someone tracing
+		 * down the cause of the crash will be able to figure
+		 * out the call path that was taken.
+		 */
+		if (((addr >= (unsigned long) &_start) &&
+		     (addr <= (unsigned long) &_etext))) {
+			if (i % 4 == 0)
+				printk("\n       ");
+			printk(" [<%08lx>]", addr);
+			i++;
+		}
+	}
+	printk("\n");
+}
+
+void bad_super_trap(struct frame *fp)
+{
+	console_verbose();
+	if (fp->ptregs.vector < 4*sizeof(vec_names)/sizeof(vec_names[0]))
+		printk ("*** %s ***   FORMAT=%X\n",
+			vec_names[(fp->ptregs.vector) >> 2],
+			fp->ptregs.format);
+	else
+		printk ("*** Exception %d ***   FORMAT=%X\n",
+			(fp->ptregs.vector) >> 2, 
+			fp->ptregs.format);
+	printk ("Current process id is %d\n", current->pid);
+	die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0);
+}
+
+asmlinkage void trap_c(struct frame *fp)
+{
+	int sig;
+	siginfo_t info;
+
+	if (fp->ptregs.sr & PS_S) {
+		if ((fp->ptregs.vector >> 2) == VEC_TRACE) {
+			/* traced a trapping instruction */
+			current->ptrace |= PT_DTRACE;
+		} else
+			bad_super_trap(fp);
+		return;
+	}
+
+	/* send the appropriate signal to the user program */
+	switch ((fp->ptregs.vector) >> 2) {
+	    case VEC_ADDRERR:
+		info.si_code = BUS_ADRALN;
+		sig = SIGBUS;
+		break;
+	    case VEC_ILLEGAL:
+	    case VEC_LINE10:
+	    case VEC_LINE11:
+		info.si_code = ILL_ILLOPC;
+		sig = SIGILL;
+		break;
+	    case VEC_PRIV:
+		info.si_code = ILL_PRVOPC;
+		sig = SIGILL;
+		break;
+	    case VEC_COPROC:
+		info.si_code = ILL_COPROC;
+		sig = SIGILL;
+		break;
+	    case VEC_TRAP1: /* gdbserver breakpoint */
+		fp->ptregs.pc -= 2;
+		info.si_code = TRAP_TRACE;
+		sig = SIGTRAP;
+		break;
+	    case VEC_TRAP2:
+	    case VEC_TRAP3:
+	    case VEC_TRAP4:
+	    case VEC_TRAP5:
+	    case VEC_TRAP6:
+	    case VEC_TRAP7:
+	    case VEC_TRAP8:
+	    case VEC_TRAP9:
+	    case VEC_TRAP10:
+	    case VEC_TRAP11:
+	    case VEC_TRAP12:
+	    case VEC_TRAP13:
+	    case VEC_TRAP14:
+		info.si_code = ILL_ILLTRP;
+		sig = SIGILL;
+		break;
+	    case VEC_FPBRUC:
+	    case VEC_FPOE:
+	    case VEC_FPNAN:
+		info.si_code = FPE_FLTINV;
+		sig = SIGFPE;
+		break;
+	    case VEC_FPIR:
+		info.si_code = FPE_FLTRES;
+		sig = SIGFPE;
+		break;
+	    case VEC_FPDIVZ:
+		info.si_code = FPE_FLTDIV;
+		sig = SIGFPE;
+		break;
+	    case VEC_FPUNDER:
+		info.si_code = FPE_FLTUND;
+		sig = SIGFPE;
+		break;
+	    case VEC_FPOVER:
+		info.si_code = FPE_FLTOVF;
+		sig = SIGFPE;
+		break;
+	    case VEC_ZERODIV:
+		info.si_code = FPE_INTDIV;
+		sig = SIGFPE;
+		break;
+	    case VEC_CHK:
+	    case VEC_TRAP:
+		info.si_code = FPE_INTOVF;
+		sig = SIGFPE;
+		break;
+	    case VEC_TRACE:		/* ptrace single step */
+		info.si_code = TRAP_TRACE;
+		sig = SIGTRAP;
+		break;
+	    case VEC_TRAP15:		/* breakpoint */
+		info.si_code = TRAP_BRKPT;
+		sig = SIGTRAP;
+		break;
+	    default:
+		info.si_code = ILL_ILLOPC;
+		sig = SIGILL;
+		break;
+	}
+	info.si_signo = sig;
+	info.si_errno = 0;
+	switch (fp->ptregs.format) {
+	    default:
+		info.si_addr = (void *) fp->ptregs.pc;
+		break;
+	    case 2:
+		info.si_addr = (void *) fp->un.fmt2.iaddr;
+		break;
+	    case 7:
+		info.si_addr = (void *) fp->un.fmt7.effaddr;
+		break;
+	    case 9:
+		info.si_addr = (void *) fp->un.fmt9.iaddr;
+		break;
+	    case 10:
+		info.si_addr = (void *) fp->un.fmta.daddr;
+		break;
+	    case 11:
+		info.si_addr = (void *) fp->un.fmtb.daddr;
+		break;
+	}
+	force_sig_info (sig, &info, current);
+}
+
+asmlinkage void set_esp0(unsigned long ssp)
+{
+	current->thread.esp0 = ssp;
+}
+
+void show_trace_task(struct task_struct *tsk)
+{
+	printk("STACK ksp=0x%lx, usp=0x%lx\n", tsk->thread.ksp, tsk->thread.usp);
+}
+
+#ifdef CONFIG_M68KFPU_EMU
+asmlinkage void fpemu_signal(int signal, int code, void *addr)
+{
+	siginfo_t info;
+
+	info.si_signo = signal;
+	info.si_errno = 0;
+	info.si_code = code;
+	info.si_addr = addr;
+	force_sig_info(signal, &info, current);
+}
+#endif
diff -Nru a/arch/m68knommu/lib/Makefile b/arch/m68knommu/lib/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/lib/Makefile	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,10 @@
+#
+# Makefile for m68knommu specific library files..
+#
+
+L_TARGET = lib.a
+obj-y	:= ashldi3.o ashrdi3.o lshrdi3.o \
+	   muldi3.o mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o \
+	   checksum.o semaphore.o memcpy.o memset.o
+
+include $(TOPDIR)/Rules.make
diff -Nru a/arch/m68knommu/lib/ashldi3.c b/arch/m68knommu/lib/ashldi3.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/lib/ashldi3.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,62 @@
+/* ashrdi3.c extracted from gcc-2.95.2/libgcc2.c which is: */
+/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#define BITS_PER_UNIT 8
+
+typedef 	 int SItype	__attribute__ ((mode (SI)));
+typedef unsigned int USItype	__attribute__ ((mode (SI)));
+typedef		 int DItype	__attribute__ ((mode (DI)));
+typedef int word_type __attribute__ ((mode (__word__)));
+
+struct DIstruct {SItype high, low;};
+
+typedef union
+{
+  struct DIstruct s;
+  DItype ll;
+} DIunion;
+
+DItype
+__ashldi3 (DItype u, word_type b)
+{
+  DIunion w;
+  word_type bm;
+  DIunion uu;
+
+  if (b == 0)
+    return u;
+
+  uu.ll = u;
+
+  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+  if (bm <= 0)
+    {
+      w.s.low = 0;
+      w.s.high = (USItype)uu.s.low << -bm;
+    }
+  else
+    {
+      USItype carries = (USItype)uu.s.low >> bm;
+      w.s.low = (USItype)uu.s.low << b;
+      w.s.high = ((USItype)uu.s.high << b) | carries;
+    }
+
+  return w.ll;
+}
diff -Nru a/arch/m68knommu/lib/ashrdi3.c b/arch/m68knommu/lib/ashrdi3.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/lib/ashrdi3.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,63 @@
+/* ashrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#define BITS_PER_UNIT 8
+
+typedef 	 int SItype	__attribute__ ((mode (SI)));
+typedef unsigned int USItype	__attribute__ ((mode (SI)));
+typedef		 int DItype	__attribute__ ((mode (DI)));
+typedef int word_type __attribute__ ((mode (__word__)));
+
+struct DIstruct {SItype high, low;};
+
+typedef union
+{
+  struct DIstruct s;
+  DItype ll;
+} DIunion;
+
+DItype
+__ashrdi3 (DItype u, word_type b)
+{
+  DIunion w;
+  word_type bm;
+  DIunion uu;
+
+  if (b == 0)
+    return u;
+
+  uu.ll = u;
+
+  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+  if (bm <= 0)
+    {
+      /* w.s.high = 1..1 or 0..0 */
+      w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
+      w.s.low = uu.s.high >> -bm;
+    }
+  else
+    {
+      USItype carries = (USItype)uu.s.high << bm;
+      w.s.high = uu.s.high >> b;
+      w.s.low = ((USItype)uu.s.low >> b) | carries;
+    }
+
+  return w.ll;
+}
diff -Nru a/arch/m68knommu/lib/checksum.c b/arch/m68knommu/lib/checksum.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/lib/checksum.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,156 @@
+/*
+ * INET		An implementation of the TCP/IP protocol suite for the LINUX
+ *		operating system.  INET is implemented using the  BSD Socket
+ *		interface as the means of communication with the user level.
+ *
+ *		IP/TCP/UDP checksumming routines
+ *
+ * Authors:	Jorge Cwik, <jorge@laser.satlink.net>
+ *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
+ *		Tom May, <ftom@netcom.com>
+ *		Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de>
+ *		Lots of code moved from tcp.c and ip.c; see those files
+ *		for more names.
+ *
+ * 03/02/96	Jes Sorensen, Andreas Schwab, Roman Hodek:
+ *		Fixed some nasty bugs, causing some horrible crashes.
+ *		A: At some points, the sum (%0) was used as
+ *		length-counter instead of the length counter
+ *		(%1). Thanks to Roman Hodek for pointing this out.
+ *		B: GCC seems to mess up if one uses too many
+ *		data-registers to hold input values and one tries to
+ *		specify d0 and d1 as scratch registers. Letting gcc choose these
+ *      registers itself solves the problem.
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ */
+ 
+/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access kills, so most
+   of the assembly has to go. */
+
+#include <net/checksum.h>
+
+static inline unsigned short from32to16(unsigned long x)
+{
+	/* add up 16-bit and 16-bit for 16+c bit */
+	x = (x & 0xffff) + (x >> 16);
+	/* add up carry.. */
+	x = (x & 0xffff) + (x >> 16);
+	return x;
+}
+
+static unsigned long do_csum(const unsigned char * buff, int len)
+{
+	int odd, count;
+	unsigned long result = 0;
+
+	if (len <= 0)
+		goto out;
+	odd = 1 & (unsigned long) buff;
+	if (odd) {
+		result = *buff;
+		len--;
+		buff++;
+	}
+	count = len >> 1;		/* nr of 16-bit words.. */
+	if (count) {
+		if (2 & (unsigned long) buff) {
+			result += *(unsigned short *) buff;
+			count--;
+			len -= 2;
+			buff += 2;
+		}
+		count >>= 1;		/* nr of 32-bit words.. */
+		if (count) {
+		        unsigned long carry = 0;
+			do {
+				unsigned long w = *(unsigned long *) buff;
+				count--;
+				buff += 4;
+				result += carry;
+				result += w;
+				carry = (w > result);
+			} while (count);
+			result += carry;
+			result = (result & 0xffff) + (result >> 16);
+		}
+		if (len & 2) {
+			result += *(unsigned short *) buff;
+			buff += 2;
+		}
+	}
+	if (len & 1)
+		result += (*buff << 8);
+	result = from32to16(result);
+	if (odd)
+		result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+out:
+	return result;
+}
+
+/*
+ *	This is a version of ip_compute_csum() optimized for IP headers,
+ *	which always checksum on 4 octet boundaries.
+ */
+unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl)
+{
+	return ~do_csum(iph,ihl*4);
+}
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
+{
+	unsigned int result = do_csum(buff, len);
+
+	/* add in old sum, and carry.. */
+	result += sum;
+	if (sum > result)
+		result += 1;
+	return result;
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+unsigned short ip_compute_csum(const unsigned char * buff, int len)
+{
+	return ~do_csum(buff,len);
+}
+
+/*
+ * copy from fs while checksumming, otherwise like csum_partial
+ */
+
+unsigned int
+csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *csum_err)
+{
+	if (csum_err) *csum_err = 0;
+	memcpy(dst, src, len);
+	return csum_partial(dst, len, sum);
+}
+
+/*
+ * copy from ds while checksumming, otherwise like csum_partial
+ */
+
+unsigned int
+csum_partial_copy(const char *src, char *dst, int len, int sum)
+{
+	memcpy(dst, src, len);
+	return csum_partial(dst, len, sum);
+}
diff -Nru a/arch/m68knommu/lib/divsi3.S b/arch/m68knommu/lib/divsi3.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/lib/divsi3.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,125 @@
+/* libgcc1 routines for 68000 w/o floating-point hardware.
+   Copyright (C) 1994, 1996, 1997, 1998 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file with other programs, and to distribute
+those programs without any restriction coming from the use of this
+file.  (The General Public License restrictions do apply in other
+respects; for example, they cover modification of the file, and
+distribution when not linked into another program.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, if you link this library with files
+   compiled with GCC to produce an executable, this does not cause
+   the resulting executable to be covered by the GNU General Public License.
+   This exception does not however invalidate any other reasons why
+   the executable file might be covered by the GNU General Public License.  */
+
+/* Use this one for any 680x0; assumes no floating point hardware.
+   The trailing " '" appearing on some lines is for ANSI preprocessors.  Yuk.
+   Some of this code comes from MINIX, via the folks at ericsson.
+   D. V. Henkel-Wallace (gumby@cygnus.com) Fete Bastille, 1992
+*/
+
+/* These are predefined by new versions of GNU cpp.  */
+
+#ifndef __USER_LABEL_PREFIX__
+#define __USER_LABEL_PREFIX__ _
+#endif
+
+#ifndef __REGISTER_PREFIX__
+#define __REGISTER_PREFIX__
+#endif
+
+#ifndef __IMMEDIATE_PREFIX__
+#define __IMMEDIATE_PREFIX__ #
+#endif
+
+/* ANSI concatenation macros.  */
+
+#define CONCAT1(a, b) CONCAT2(a, b)
+#define CONCAT2(a, b) a ## b
+
+/* Use the right prefix for global labels.  */
+
+#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+
+/* Use the right prefix for registers.  */
+
+#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
+
+/* Use the right prefix for immediate values.  */
+
+#define IMM(x) CONCAT1 (__IMMEDIATE_PREFIX__, x)
+
+#define d0 REG (d0)
+#define d1 REG (d1)
+#define d2 REG (d2)
+#define d3 REG (d3)
+#define d4 REG (d4)
+#define d5 REG (d5)
+#define d6 REG (d6)
+#define d7 REG (d7)
+#define a0 REG (a0)
+#define a1 REG (a1)
+#define a2 REG (a2)
+#define a3 REG (a3)
+#define a4 REG (a4)
+#define a5 REG (a5)
+#define a6 REG (a6)
+#define fp REG (fp)
+#define sp REG (sp)
+
+	.text
+	.proc
+	.globl	SYM (__divsi3)
+SYM (__divsi3):
+	movel	d2, sp@-
+
+	moveq	IMM (1), d2	/* sign of result stored in d2 (=1 or =-1) */
+	movel	sp@(12), d1	/* d1 = divisor */
+	jpl	L1
+	negl	d1
+#ifndef __mcf5200__
+	negb	d2		/* change sign because divisor <0  */
+#else
+	negl	d2		/* change sign because divisor <0  */
+#endif
+L1:	movel	sp@(8), d0	/* d0 = dividend */
+	jpl	L2
+	negl	d0
+#ifndef __mcf5200__
+	negb	d2
+#else
+	negl	d2
+#endif
+
+L2:	movel	d1, sp@-
+	movel	d0, sp@-
+	jbsr	SYM (__udivsi3)	/* divide abs(dividend) by abs(divisor) */
+	addql	IMM (8), sp
+
+	tstb	d2
+	jpl	L3
+	negl	d0
+
+L3:	movel	sp@+, d2
+	rts
+
diff -Nru a/arch/m68knommu/lib/lshrdi3.c b/arch/m68knommu/lib/lshrdi3.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/lib/lshrdi3.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,62 @@
+/* lshrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#define BITS_PER_UNIT 8
+
+typedef 	 int SItype	__attribute__ ((mode (SI)));
+typedef unsigned int USItype	__attribute__ ((mode (SI)));
+typedef		 int DItype	__attribute__ ((mode (DI)));
+typedef int word_type __attribute__ ((mode (__word__)));
+
+struct DIstruct {SItype high, low;};
+
+typedef union
+{
+  struct DIstruct s;
+  DItype ll;
+} DIunion;
+
+DItype
+__lshrdi3 (DItype u, word_type b)
+{
+  DIunion w;
+  word_type bm;
+  DIunion uu;
+
+  if (b == 0)
+    return u;
+
+  uu.ll = u;
+
+  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+  if (bm <= 0)
+    {
+      w.s.high = 0;
+      w.s.low = (USItype)uu.s.high >> -bm;
+    }
+  else
+    {
+      USItype carries = (USItype)uu.s.high << bm;
+      w.s.high = (USItype)uu.s.high >> b;
+      w.s.low = ((USItype)uu.s.low >> b) | carries;
+    }
+
+  return w.ll;
+}
diff -Nru a/arch/m68knommu/lib/memcpy.c b/arch/m68knommu/lib/memcpy.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/lib/memcpy.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,63 @@
+
+#include <linux/types.h>
+#include <linux/autoconf.h>
+
+void * memcpy(void * to, const void * from, size_t n)
+{
+#ifdef CONFIG_COLDFIRE
+  void *xto = to;
+  size_t temp;
+
+  if (!n)
+    return xto;
+  if ((long) to & 1)
+    {
+      char *cto = to;
+      const char *cfrom = from;
+      *cto++ = *cfrom++;
+      to = cto;
+      from = cfrom;
+      n--;
+    }
+  if (n > 2 && (long) to & 2)
+    {
+      short *sto = to;
+      const short *sfrom = from;
+      *sto++ = *sfrom++;
+      to = sto;
+      from = sfrom;
+      n -= 2;
+    }
+  temp = n >> 2;
+  if (temp)
+    {
+      long *lto = to;
+      const long *lfrom = from;
+      for (; temp; temp--)
+	*lto++ = *lfrom++;
+      to = lto;
+      from = lfrom;
+    }
+  if (n & 2)
+    {
+      short *sto = to;
+      const short *sfrom = from;
+      *sto++ = *sfrom++;
+      to = sto;
+      from = sfrom;
+    }
+  if (n & 1)
+    {
+      char *cto = to;
+      const char *cfrom = from;
+      *cto = *cfrom;
+    }
+  return xto;
+#else
+  const char *c_from = from;
+  char *c_to = to;
+  while (n-- > 0)
+    *c_to++ = *c_from++;
+  return((void *) to);
+#endif
+}
diff -Nru a/arch/m68knommu/lib/memset.c b/arch/m68knommu/lib/memset.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/lib/memset.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,47 @@
+#include <linux/types.h>
+
+void * memset(void * s, int c, size_t count)
+{
+  void *xs = s;
+  size_t temp;
+
+  if (!count)
+    return xs;
+  c &= 0xff;
+  c |= c << 8;
+  c |= c << 16;
+  if ((long) s & 1)
+    {
+      char *cs = s;
+      *cs++ = c;
+      s = cs;
+      count--;
+    }
+  if (count > 2 && (long) s & 2)
+    {
+      short *ss = s;
+      *ss++ = c;
+      s = ss;
+      count -= 2;
+    }
+  temp = count >> 2;
+  if (temp)
+    {
+      long *ls = s;
+      for (; temp; temp--)
+	*ls++ = c;
+      s = ls;
+    }
+  if (count & 2)
+    {
+      short *ss = s;
+      *ss++ = c;
+      s = ss;
+    }
+  if (count & 1)
+    {
+      char *cs = s;
+      *cs = c;
+    }
+  return xs;
+}
diff -Nru a/arch/m68knommu/lib/modsi3.S b/arch/m68knommu/lib/modsi3.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/lib/modsi3.S	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,113 @@
+/* libgcc1 routines for 68000 w/o floating-point hardware.
+   Copyright (C) 1994, 1996, 1997, 1998 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file with other programs, and to distribute
+those programs without any restriction coming from the use of this
+file.  (The General Public License restrictions do apply in other
+respects; for example, they cover modification of the file, and
+distribution when not linked into another program.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, if you link this library with files
+   compiled with GCC to produce an executable, this does not cause
+   the resulting executable to be covered by the GNU General Public License.
+   This exception does not however invalidate any other reasons why
+   the executable file might be covered by the GNU General Public License.  */
+
+/* Use this one for any 680x0; assumes no floating point hardware.
+   The trailing " '" appearing on some lines is for ANSI preprocessors.  Yuk.
+   Some of this code comes from MINIX, via the folks at ericsson.
+   D. V. Henkel-Wallace (gumby@cygnus.com) Fete Bastille, 1992
+*/
+
+/* These are predefined by new versions of GNU cpp.  */
+
+#ifndef __USER_LABEL_PREFIX__
+#define __USER_LABEL_PREFIX__ _
+#endif
+
+#ifndef __REGISTER_PREFIX__
+#define __REGISTER_PREFIX__
+#endif
+
+#ifndef __IMMEDIATE_PREFIX__
+#define __IMMEDIATE_PREFIX__ #
+#endif
+
+/* ANSI concatenation macros.  */
+
+#define CONCAT1(a, b) CONCAT2(a, b)
+#define CONCAT2(a, b) a ## b
+
+/* Use the right prefix for global labels.  */
+
+#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+
+/* Use the right prefix for registers.  */
+
+#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
+
+/* Use the right prefix for immediate values.  */
+
+#define IMM(x) CONCAT1 (__IMMEDIATE_PREFIX__, x)
+
+#define d0 REG (d0)
+#define d1 REG (d1)
+#define d2 REG (d2)
+#define d3 REG (d3)
+#define d4 REG (d4)
+#define d5 REG (d5)
+#define d6 REG (d6)
+#define d7 REG (d7)
+#define a0 REG (a0)
+#define a1 REG (a1)
+#define a2 REG (a2)
+#define a3 REG (a3)
+#define a4 REG (a4)
+#define a5 REG (a5)
+#define a6 REG (a6)
+#define fp REG (fp)
+#define sp REG (sp)
+
+	.text
+	.proc
+	.globl	SYM (__modsi3)
+SYM (__modsi3):
+	movel	sp@(8), d1	/* d1 = divisor */
+	movel	sp@(4), d0	/* d0 = dividend */
+	movel	d1, sp@-
+	movel	d0, sp@-
+	jbsr	SYM (__divsi3)
+	addql	IMM (8), sp
+	movel	sp@(8), d1	/* d1 = divisor */
+#ifndef __mcf5200__
+	movel	d1, sp@-
+	movel	d0, sp@-
+	jbsr	SYM (__mulsi3)	/* d0 = (a/b)*b */
+	addql	IMM (8), sp
+#else
+	mulsl	d1,d0
+#endif
+	movel	sp@(4), d1	/* d1 = dividend */
+	subl	d0, d1		/* d1 = a - (a/b)*b */
+	movel	d1, d0
+	rts
+
diff -Nru a/arch/m68knommu/lib/muldi3.c b/arch/m68knommu/lib/muldi3.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/lib/muldi3.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,86 @@
+/* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and 
+			   gcc-2.7.2.3/longlong.h which is: */
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#define BITS_PER_UNIT 8
+#define SI_TYPE_SIZE 32
+
+#define __BITS4 (SI_TYPE_SIZE / 4)
+#define __ll_B (1L << (SI_TYPE_SIZE / 2))
+#define __ll_lowpart(t) ((USItype) (t) % __ll_B)
+#define __ll_highpart(t) ((USItype) (t) / __ll_B)
+
+#define umul_ppmm(w1, w0, u, v)						\
+  do {									\
+    USItype __x0, __x1, __x2, __x3;					\
+    USItype __ul, __vl, __uh, __vh;					\
+									\
+    __ul = __ll_lowpart (u);						\
+    __uh = __ll_highpart (u);						\
+    __vl = __ll_lowpart (v);						\
+    __vh = __ll_highpart (v);						\
+									\
+    __x0 = (USItype) __ul * __vl;					\
+    __x1 = (USItype) __ul * __vh;					\
+    __x2 = (USItype) __uh * __vl;					\
+    __x3 = (USItype) __uh * __vh;					\
+									\
+    __x1 += __ll_highpart (__x0);/* this can't give carry */		\
+    __x1 += __x2;		/* but this indeed can */		\
+    if (__x1 < __x2)		/* did we get it? */			\
+      __x3 += __ll_B;		/* yes, add it in the proper pos. */	\
+									\
+    (w1) = __x3 + __ll_highpart (__x1);					\
+    (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0);		\
+  } while (0)
+
+#define __umulsidi3(u, v) \
+  ({DIunion __w;							\
+    umul_ppmm (__w.s.high, __w.s.low, u, v);				\
+    __w.ll; })
+
+typedef 	 int SItype	__attribute__ ((mode (SI)));
+typedef unsigned int USItype	__attribute__ ((mode (SI)));
+typedef		 int DItype	__attribute__ ((mode (DI)));
+typedef int word_type __attribute__ ((mode (__word__)));
+
+struct DIstruct {SItype high, low;};
+
+typedef union
+{
+  struct DIstruct s;
+  DItype ll;
+} DIunion;
+
+DItype
+__muldi3 (DItype u, DItype v)
+{
+  DIunion w;
+  DIunion uu, vv;
+
+  uu.ll = u,
+  vv.ll = v;
+
+  w.ll = __umulsidi3 (uu.s.low, vv.s.low);
+  w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
+	       + (USItype) uu.s.high * (USItype) vv.s.low);
+
+  return w.ll;
+}
diff -Nru a/arch/m68knommu/lib/mulsi3.S b/arch/m68knommu/lib/mulsi3.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/lib/mulsi3.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,110 @@
+/* libgcc1 routines for 68000 w/o floating-point hardware.
+   Copyright (C) 1994, 1996, 1997, 1998 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file with other programs, and to distribute
+those programs without any restriction coming from the use of this
+file.  (The General Public License restrictions do apply in other
+respects; for example, they cover modification of the file, and
+distribution when not linked into another program.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, if you link this library with files
+   compiled with GCC to produce an executable, this does not cause
+   the resulting executable to be covered by the GNU General Public License.
+   This exception does not however invalidate any other reasons why
+   the executable file might be covered by the GNU General Public License.  */
+
+/* Use this one for any 680x0; assumes no floating point hardware.
+   The trailing " '" appearing on some lines is for ANSI preprocessors.  Yuk.
+   Some of this code comes from MINIX, via the folks at ericsson.
+   D. V. Henkel-Wallace (gumby@cygnus.com) Fete Bastille, 1992
+*/
+
+/* These are predefined by new versions of GNU cpp.  */
+
+#ifndef __USER_LABEL_PREFIX__
+#define __USER_LABEL_PREFIX__ _
+#endif
+
+#ifndef __REGISTER_PREFIX__
+#define __REGISTER_PREFIX__
+#endif
+
+#ifndef __IMMEDIATE_PREFIX__
+#define __IMMEDIATE_PREFIX__ #
+#endif
+
+/* ANSI concatenation macros.  */
+
+#define CONCAT1(a, b) CONCAT2(a, b)
+#define CONCAT2(a, b) a ## b
+
+/* Use the right prefix for global labels.  */
+
+#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+
+/* Use the right prefix for registers.  */
+
+#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
+
+/* Use the right prefix for immediate values.  */
+
+#define IMM(x) CONCAT1 (__IMMEDIATE_PREFIX__, x)
+
+#define d0 REG (d0)
+#define d1 REG (d1)
+#define d2 REG (d2)
+#define d3 REG (d3)
+#define d4 REG (d4)
+#define d5 REG (d5)
+#define d6 REG (d6)
+#define d7 REG (d7)
+#define a0 REG (a0)
+#define a1 REG (a1)
+#define a2 REG (a2)
+#define a3 REG (a3)
+#define a4 REG (a4)
+#define a5 REG (a5)
+#define a6 REG (a6)
+#define fp REG (fp)
+#define sp REG (sp)
+
+	.text
+	.proc
+	.globl	SYM (__mulsi3)
+SYM (__mulsi3):
+	movew	sp@(4), d0	/* x0 -> d0 */
+	muluw	sp@(10), d0	/* x0*y1 */
+	movew	sp@(6), d1	/* x1 -> d1 */
+	muluw	sp@(8), d1	/* x1*y0 */
+#ifndef __mcf5200__
+	addw	d1, d0
+#else
+	addl	d1, d0
+#endif
+	swap	d0
+	clrw	d0
+	movew	sp@(6), d1	/* x1 -> d1 */
+	muluw	sp@(10), d1	/* x1*y1 */
+	addl	d1, d0
+
+	rts
+
diff -Nru a/arch/m68knommu/lib/semaphore.S b/arch/m68knommu/lib/semaphore.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/lib/semaphore.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,67 @@
+/*
+ *  linux/arch/m68k/lib/semaphore.S
+ *
+ *  Copyright (C) 1996  Linus Torvalds
+ *
+ *  m68k version by Andreas Schwab
+ *
+ *  MAR/1999 -- modified to support ColdFire (gerg@snapgear.com)
+ */
+
+#include <linux/linkage.h>
+#include <linux/config.h>
+#include <asm/semaphore.h>
+
+/*
+ * "down_failed" is called with the eventual return address
+ * in %a0, and the address of the semaphore in %a1. We need
+ * to increment the number of waiters on the semaphore,
+ * call "__down()", and then eventually return to try again.
+ */
+ENTRY(__down_failed)
+#ifdef CONFIG_COLDFIRE
+	subl #12,%sp
+	moveml %a0/%d0/%d1,(%sp)
+#else
+	moveml %a0/%d0/%d1,-(%sp)
+#endif
+	movel %a1,-(%sp)
+	jbsr __down
+	movel (%sp)+,%a1
+	movel (%sp)+,%d0
+	movel (%sp)+,%d1
+	rts
+
+ENTRY(__down_failed_interruptible)
+	movel %a0,-(%sp)
+	movel %d1,-(%sp)
+	movel %a1,-(%sp)
+	jbsr __down_interruptible
+	movel (%sp)+,%a1
+	movel (%sp)+,%d1
+	rts
+
+ENTRY(__up_wakeup)
+#ifdef CONFIG_COLDFIRE
+	subl #12,%sp
+	moveml %a0/%d0/%d1,(%sp)
+#else
+	moveml %a0/%d0/%d1,-(%sp)
+#endif
+	movel %a1,-(%sp)
+	jbsr __up
+	movel (%sp)+,%a1
+	movel (%sp)+,%d0
+	movel (%sp)+,%d1
+	rts
+
+ENTRY(__down_failed_trylock)
+	movel %a0,-(%sp)
+	movel %d1,-(%sp)
+	movel %a1,-(%sp)
+	jbsr __down_trylock
+	movel (%sp)+,%a1
+	movel (%sp)+,%d1
+	movel (%sp)+,%a0
+	rts
+
diff -Nru a/arch/m68knommu/lib/udivsi3.S b/arch/m68knommu/lib/udivsi3.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/lib/udivsi3.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,162 @@
+/* libgcc1 routines for 68000 w/o floating-point hardware.
+   Copyright (C) 1994, 1996, 1997, 1998 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file with other programs, and to distribute
+those programs without any restriction coming from the use of this
+file.  (The General Public License restrictions do apply in other
+respects; for example, they cover modification of the file, and
+distribution when not linked into another program.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, if you link this library with files
+   compiled with GCC to produce an executable, this does not cause
+   the resulting executable to be covered by the GNU General Public License.
+   This exception does not however invalidate any other reasons why
+   the executable file might be covered by the GNU General Public License.  */
+
+/* Use this one for any 680x0; assumes no floating point hardware.
+   The trailing " '" appearing on some lines is for ANSI preprocessors.  Yuk.
+   Some of this code comes from MINIX, via the folks at ericsson.
+   D. V. Henkel-Wallace (gumby@cygnus.com) Fete Bastille, 1992
+*/
+
+/* These are predefined by new versions of GNU cpp.  */
+
+#ifndef __USER_LABEL_PREFIX__
+#define __USER_LABEL_PREFIX__ _
+#endif
+
+#ifndef __REGISTER_PREFIX__
+#define __REGISTER_PREFIX__
+#endif
+
+#ifndef __IMMEDIATE_PREFIX__
+#define __IMMEDIATE_PREFIX__ #
+#endif
+
+/* ANSI concatenation macros.  */
+
+#define CONCAT1(a, b) CONCAT2(a, b)
+#define CONCAT2(a, b) a ## b
+
+/* Use the right prefix for global labels.  */
+
+#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+
+/* Use the right prefix for registers.  */
+
+#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
+
+/* Use the right prefix for immediate values.  */
+
+#define IMM(x) CONCAT1 (__IMMEDIATE_PREFIX__, x)
+
+#define d0 REG (d0)
+#define d1 REG (d1)
+#define d2 REG (d2)
+#define d3 REG (d3)
+#define d4 REG (d4)
+#define d5 REG (d5)
+#define d6 REG (d6)
+#define d7 REG (d7)
+#define a0 REG (a0)
+#define a1 REG (a1)
+#define a2 REG (a2)
+#define a3 REG (a3)
+#define a4 REG (a4)
+#define a5 REG (a5)
+#define a6 REG (a6)
+#define fp REG (fp)
+#define sp REG (sp)
+
+	.text
+	.proc
+	.globl	SYM (__udivsi3)
+SYM (__udivsi3):
+#ifndef __mcf5200__
+	movel	d2, sp@-
+	movel	sp@(12), d1	/* d1 = divisor */
+	movel	sp@(8), d0	/* d0 = dividend */
+
+	cmpl	IMM (0x10000), d1 /* divisor >= 2 ^ 16 ?   */
+	jcc	L3		/* then try next algorithm */
+	movel	d0, d2
+	clrw	d2
+	swap	d2
+	divu	d1, d2          /* high quotient in lower word */
+	movew	d2, d0		/* save high quotient */
+	swap	d0
+	movew	sp@(10), d2	/* get low dividend + high rest */
+	divu	d1, d2		/* low quotient */
+	movew	d2, d0
+	jra	L6
+
+L3:	movel	d1, d2		/* use d2 as divisor backup */
+L4:	lsrl	IMM (1), d1	/* shift divisor */
+	lsrl	IMM (1), d0	/* shift dividend */
+	cmpl	IMM (0x10000), d1 /* still divisor >= 2 ^ 16 ?  */
+	jcc	L4
+	divu	d1, d0		/* now we have 16 bit divisor */
+	andl	IMM (0xffff), d0 /* mask out divisor, ignore remainder */
+
+/* Multiply the 16 bit tentative quotient with the 32 bit divisor.  Because of
+   the operand ranges, this might give a 33 bit product.  If this product is
+   greater than the dividend, the tentative quotient was too large. */
+	movel	d2, d1
+	mulu	d0, d1		/* low part, 32 bits */
+	swap	d2
+	mulu	d0, d2		/* high part, at most 17 bits */
+	swap	d2		/* align high part with low part */
+	tstw	d2		/* high part 17 bits? */
+	jne	L5		/* if 17 bits, quotient was too large */
+	addl	d2, d1		/* add parts */
+	jcs	L5		/* if sum is 33 bits, quotient was too large */
+	cmpl	sp@(8), d1	/* compare the sum with the dividend */
+	jls	L6		/* if sum > dividend, quotient was too large */
+L5:	subql	IMM (1), d0	/* adjust quotient */
+
+L6:	movel	sp@+, d2
+	rts
+
+#else /* __mcf5200__ */
+
+/* Coldfire implementation of non-restoring division algorithm from
+   Hennessy & Patterson, Appendix A. */
+	link	a6,IMM (-12)
+	moveml	d2-d4,sp@
+	movel	a6@(8),d0
+	movel	a6@(12),d1
+	clrl	d2		| clear p
+	moveq	IMM (31),d4
+L1:	addl	d0,d0		| shift reg pair (p,a) one bit left
+	addxl	d2,d2
+	movl	d2,d3		| subtract b from p, store in tmp.
+	subl	d1,d3
+	jcs	L2		| if no carry,
+	bset	IMM (0),d0	| set the low order bit of a to 1,
+	movl	d3,d2		| and store tmp in p.
+L2:	subql	IMM (1),d4
+	jcc	L1
+	moveml	sp@,d2-d4	| restore data registers
+	unlk	a6		| and return
+	rts
+#endif /* __mcf5200__ */
+
diff -Nru a/arch/m68knommu/lib/umodsi3.S b/arch/m68knommu/lib/umodsi3.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/lib/umodsi3.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,113 @@
+/* libgcc1 routines for 68000 w/o floating-point hardware.
+   Copyright (C) 1994, 1996, 1997, 1998 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file with other programs, and to distribute
+those programs without any restriction coming from the use of this
+file.  (The General Public License restrictions do apply in other
+respects; for example, they cover modification of the file, and
+distribution when not linked into another program.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, if you link this library with files
+   compiled with GCC to produce an executable, this does not cause
+   the resulting executable to be covered by the GNU General Public License.
+   This exception does not however invalidate any other reasons why
+   the executable file might be covered by the GNU General Public License.  */
+
+/* Use this one for any 680x0; assumes no floating point hardware.
+   The trailing " '" appearing on some lines is for ANSI preprocessors.  Yuk.
+   Some of this code comes from MINIX, via the folks at ericsson.
+   D. V. Henkel-Wallace (gumby@cygnus.com) Fete Bastille, 1992
+*/
+
+/* These are predefined by new versions of GNU cpp.  */
+
+#ifndef __USER_LABEL_PREFIX__
+#define __USER_LABEL_PREFIX__ _
+#endif
+
+#ifndef __REGISTER_PREFIX__
+#define __REGISTER_PREFIX__
+#endif
+
+#ifndef __IMMEDIATE_PREFIX__
+#define __IMMEDIATE_PREFIX__ #
+#endif
+
+/* ANSI concatenation macros.  */
+
+#define CONCAT1(a, b) CONCAT2(a, b)
+#define CONCAT2(a, b) a ## b
+
+/* Use the right prefix for global labels.  */
+
+#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+
+/* Use the right prefix for registers.  */
+
+#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
+
+/* Use the right prefix for immediate values.  */
+
+#define IMM(x) CONCAT1 (__IMMEDIATE_PREFIX__, x)
+
+#define d0 REG (d0)
+#define d1 REG (d1)
+#define d2 REG (d2)
+#define d3 REG (d3)
+#define d4 REG (d4)
+#define d5 REG (d5)
+#define d6 REG (d6)
+#define d7 REG (d7)
+#define a0 REG (a0)
+#define a1 REG (a1)
+#define a2 REG (a2)
+#define a3 REG (a3)
+#define a4 REG (a4)
+#define a5 REG (a5)
+#define a6 REG (a6)
+#define fp REG (fp)
+#define sp REG (sp)
+
+	.text
+	.proc
+	.globl	SYM (__umodsi3)
+SYM (__umodsi3):
+	movel	sp@(8), d1	/* d1 = divisor */
+	movel	sp@(4), d0	/* d0 = dividend */
+	movel	d1, sp@-
+	movel	d0, sp@-
+	jbsr	SYM (__udivsi3)
+	addql	IMM (8), sp
+	movel	sp@(8), d1	/* d1 = divisor */
+#ifndef __mcf5200__
+	movel	d1, sp@-
+	movel	d0, sp@-
+	jbsr	SYM (__mulsi3)	/* d0 = (a/b)*b */
+	addql	IMM (8), sp
+#else
+	mulsl	d1,d0
+#endif
+	movel	sp@(4), d1	/* d1 = dividend */
+	subl	d0, d1		/* d1 = a - (a/b)*b */
+	movel	d1, d0
+	rts
+
diff -Nru a/arch/m68knommu/mm/Makefile b/arch/m68knommu/mm/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/mm/Makefile	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,7 @@
+#
+# Makefile for the linux m68knommu specific parts of the memory manager.
+#
+
+obj-y += init.o fault.o memory.o kmap.o
+
+include $(TOPDIR)/Rules.make
diff -Nru a/arch/m68knommu/mm/fault.c b/arch/m68knommu/mm/fault.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/mm/fault.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,57 @@
+/*
+ *  linux/arch/m68knommu/mm/fault.c
+ *
+ *  Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>,
+ *  Copyright (C) 2000  Lineo, Inc.  (www.lineo.com) 
+ *
+ *  Based on:
+ *
+ *  linux/arch/m68k/mm/fault.c
+ *
+ *  Copyright (C) 1995  Hamish Macdonald
+ */
+
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/ptrace.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+
+extern void die_if_kernel(char *, struct pt_regs *, long);
+
+/*
+ * This routine handles page faults.  It determines the problem, and
+ * then passes it off to one of the appropriate routines.
+ *
+ * error_code:
+ *	bit 0 == 0 means no page found, 1 means protection fault
+ *	bit 1 == 0 means read, 1 means write
+ *
+ * If this routine detects a bad access, it returns 1, otherwise it
+ * returns 0.
+ */
+asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
+			      unsigned long error_code)
+{
+#ifdef DEBUG
+	printk ("regs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld\n",
+		regs->sr, regs->pc, address, error_code);
+#endif
+
+	/*
+	 * Oops. The kernel tried to access some bad page. We'll have to
+	 * terminate things with extreme prejudice.
+	 */
+	if ((unsigned long) address < PAGE_SIZE) {
+		printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
+	} else
+		printk(KERN_ALERT "Unable to handle kernel access");
+	printk(" at virtual address %08lx\n",address);
+	die_if_kernel("Oops", regs, error_code);
+	do_exit(SIGKILL);
+
+	return 1;
+}
+
diff -Nru a/arch/m68knommu/mm/init.c b/arch/m68knommu/mm/init.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/mm/init.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,235 @@
+/*
+ *  linux/arch/m68knommu/mm/init.c
+ *
+ *  Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>,
+ *                      Kenneth Albanowski <kjahds@kjahds.com>,
+ *  Copyright (C) 2000  Lineo, Inc.  (www.lineo.com) 
+ *
+ *  Based on:
+ *
+ *  linux/arch/m68k/mm/init.c
+ *
+ *  Copyright (C) 1995  Hamish Macdonald
+ *
+ *  JAN/1999 -- hacked to support ColdFire (gerg@snapgear.com)
+ *  DEC/2000 -- linux 2.4 support <davidm@snapgear.com>
+ */
+
+#include <linux/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/init.h>
+#ifdef CONFIG_BLK_DEV_RAM
+#include <linux/blk.h>
+#endif
+#include <linux/highmem.h>
+#include <linux/pagemap.h>
+#include <linux/bootmem.h>
+#include <linux/slab.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/machdep.h>
+#include <asm/shglcore.h>
+
+#undef DEBUG
+
+extern void die_if_kernel(char *,struct pt_regs *,long);
+extern void free_initmem(void);
+
+/*
+ * BAD_PAGE is the page that is used for page faults when linux
+ * is out-of-memory. Older versions of linux just did a
+ * do_exit(), but using this instead means there is less risk
+ * for a process dying in kernel mode, possibly leaving a inode
+ * unused etc..
+ *
+ * BAD_PAGETABLE is the accompanying page-table: it is initialized
+ * to point to BAD_PAGE entries.
+ *
+ * ZERO_PAGE is a special page that is used for zero-initialized
+ * data and COW.
+ */
+static unsigned long empty_bad_page_table;
+
+static unsigned long empty_bad_page;
+
+unsigned long empty_zero_page;
+
+extern unsigned long rom_length;
+
+void show_mem(void)
+{
+    unsigned long i;
+    int free = 0, total = 0, reserved = 0, shared = 0;
+    int cached = 0;
+
+    printk("\nMem-info:\n");
+    show_free_areas();
+    i = max_mapnr;
+    while (i-- > 0) {
+	total++;
+	if (PageReserved(mem_map+i))
+	    reserved++;
+	else if (PageSwapCache(mem_map+i))
+	    cached++;
+	else if (!page_count(mem_map+i))
+	    free++;
+	else
+	    shared += page_count(mem_map+i) - 1;
+    }
+    printk("%d pages of RAM\n",total);
+    printk("%d free pages\n",free);
+    printk("%d reserved pages\n",reserved);
+    printk("%d pages shared\n",shared);
+    printk("%d pages swap cached\n",cached);
+}
+
+extern unsigned long memory_start;
+extern unsigned long memory_end;
+
+/*
+ * paging_init() continues the virtual memory environment setup which
+ * was begun by the code in arch/head.S.
+ * The parameters are pointers to where to stick the starting and ending
+ * addresses of available kernel virtual memory.
+ */
+void paging_init(void)
+{
+	/*
+	 * Make sure start_mem is page aligned, otherwise bootmem and
+	 * page_alloc get different views of the world.
+	 */
+#ifdef DEBUG
+	unsigned long start_mem = PAGE_ALIGN(memory_start);
+#endif
+	unsigned long end_mem   = memory_end & PAGE_MASK;
+
+#ifdef DEBUG
+	printk ("start_mem is %#lx\nvirtual_end is %#lx\n",
+		start_mem, end_mem);
+#endif
+
+	/*
+	 * Initialize the bad page table and bad page to point
+	 * to a couple of allocated pages.
+	 */
+	empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+	empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+	empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+	memset((void *)empty_zero_page, 0, PAGE_SIZE);
+
+	/*
+	 * Set up SFC/DFC registers (user data space).
+	 */
+	set_fs (USER_DS);
+
+#ifdef DEBUG
+	printk ("before free_area_init\n");
+
+	printk ("free_area_init -> start_mem is %#lx\nvirtual_end is %#lx\n",
+		start_mem, end_mem);
+#endif
+
+	{
+		unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+
+		zones_size[ZONE_DMA] = 0 >> PAGE_SHIFT;
+		zones_size[ZONE_NORMAL] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
+#ifdef CONFIG_HIGHMEM
+		zones_size[ZONE_HIGHMEM] = 0;
+#endif
+		free_area_init(zones_size);
+	}
+}
+
+void mem_init(void)
+{
+	int codek = 0, datak = 0, initk = 0;
+	unsigned long tmp;
+	extern char _etext, _stext, _sdata, _ebss, __init_begin, __init_end;
+	extern unsigned int _ramend, _rambase;
+	unsigned long len = _ramend - _rambase;
+	unsigned long start_mem = memory_start; /* DAVIDM - these must start at end of kernel */
+	unsigned long end_mem   = memory_end; /* DAVIDM - this must not include kernel stack at top */
+
+#ifdef DEBUG
+	printk("Mem_init: start=%lx, end=%lx\n", start_mem, end_mem);
+#endif
+
+	end_mem &= PAGE_MASK;
+	high_memory = (void *) end_mem;
+
+	start_mem = PAGE_ALIGN(start_mem);
+	max_mapnr = num_physpages = MAP_NR(high_memory);
+
+	/* this will put all memory onto the freelists */
+	totalram_pages = free_all_bootmem();
+
+	codek = (&_etext - &_stext) >> 10;
+	datak = (&_ebss - &_sdata) >> 10;
+	initk = (&__init_begin - &__init_end) >> 10;
+
+	tmp = nr_free_pages() << PAGE_SHIFT;
+	printk("Memory available: %luk/%luk RAM, %luk/%luk ROM (%dk kernel code, %dk data)\n",
+	       tmp >> 10,
+	       len >> 10,
+	       (rom_length > 0) ? ((rom_length >> 10) - codek) : 0,
+	       rom_length >> 10,
+	       codek,
+	       datak
+	       );
+}
+
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+	int pages = 0;
+	for (; start < end; start += PAGE_SIZE) {
+		ClearPageReserved(virt_to_page(start));
+		set_page_count(virt_to_page(start), 1);
+		free_page(start);
+		totalram_pages++;
+		pages++;
+	}
+	printk ("Freeing initrd memory: %dk freed\n", pages);
+}
+#endif
+
+void
+free_initmem()
+{
+#ifdef CONFIG_RAMKERNEL
+	unsigned long addr;
+	extern char __init_begin, __init_end;
+	/*
+	 * The following code should be cool even if these sections
+	 * are not page aligned.
+	 */
+	addr = PAGE_ALIGN((unsigned long)(&__init_begin));
+	/* next to check that the page we free is not a partial page */
+	for (; addr + PAGE_SIZE < (unsigned long)(&__init_end); addr +=PAGE_SIZE) {
+		ClearPageReserved(virt_to_page(addr));
+		set_page_count(virt_to_page(addr), 1);
+		free_page(addr);
+		totalram_pages++;
+	}
+	printk("Freeing unused kernel memory: %ldk freed (0x%x - 0x%x)\n",
+			(addr - PAGE_ALIGN((long) &__init_begin)) >> 10,
+			(int)(PAGE_ALIGN((unsigned long)(&__init_begin))),
+			(int)(addr - PAGE_SIZE));
+#endif
+}
+
diff -Nru a/arch/m68knommu/mm/kmap.c b/arch/m68knommu/mm/kmap.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/mm/kmap.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,56 @@
+/*
+ *  linux/arch/m68knommu/mm/kmap.c
+ *
+ *  Copyright (C) 2000 Lineo, <davidm@snapgear.com>
+ *  Copyright (C) 2000-2002 David McCullough <davidm@snapgear.com>
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+#undef DEBUG
+
+/*
+ * Map some physical address range into the kernel address space.
+ */
+void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
+{
+	return (void *)physaddr;
+}
+
+/*
+ * Unmap a ioremap()ed region again.
+ */
+void iounmap(void *addr)
+{
+}
+
+/*
+ * __iounmap unmaps nearly everything, so be careful
+ * it doesn't free currently pointer/page tables anymore but it
+ * wans't used anyway and might be added later.
+ */
+void __iounmap(void *addr, unsigned long size)
+{
+}
+
+/*
+ * Set new cache mode for some kernel address space.
+ * The caller must push data for that range itself, if such data may already
+ * be in the cache.
+ */
+void kernel_set_cachemode(void *addr, unsigned long size, int cmode)
+{
+}
diff -Nru a/arch/m68knommu/mm/memory.c b/arch/m68knommu/mm/memory.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/mm/memory.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,166 @@
+/*
+ *  linux/arch/m68knommu/mm/memory.c
+ *
+ *  Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *  Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
+ *
+ *  Based on:
+ *
+ *  linux/arch/m68k/mm/memory.c
+ *
+ *  Copyright (C) 1995  Hamish Macdonald
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/shglcore.h>
+#include <asm/io.h>
+
+/*
+ * cache_clear() semantics: Clear any cache entries for the area in question,
+ * without writing back dirty entries first. This is useful if the data will
+ * be overwritten anyway, e.g. by DMA to memory. The range is defined by a
+ * _physical_ address.
+ */
+
+void cache_clear (unsigned long paddr, int len)
+{
+}
+
+
+/*
+ *	Define cache invalidate functions. The ColdFire 5407 is really
+ *	the only processor that needs to do some work here. Anything
+ *	that has separate data and instruction caches will be a problem.
+ */
+#ifdef CONFIG_M5407
+
+static __inline__ void cache_invalidate_lines(unsigned long paddr, int len)
+{
+	unsigned long	sset, eset;
+
+	sset = (paddr & 0x00000ff0);
+	eset = ((paddr + len) & 0x0000ff0) + 0x10;
+
+	__asm__ __volatile__ (
+		"nop\n\t"
+		"clrl	%%d0\n\t"
+		"1:\n\t"
+		"movel	%0,%%a0\n\t"
+		"addl	%%d0,%%a0\n\t"
+		"2:\n\t"
+		".word	0xf4e8\n\t"
+		"addl	#0x10,%%a0\n\t"
+		"cmpl	%1,%%a0\n\t"
+		"blt	2b\n\t"
+		"addql	#1,%%d0\n\t"
+		"cmpil	#4,%%d0\n\t"
+		"bne	1b"
+		: : "a" (sset), "a" (eset) : "d0", "a0" );
+}
+
+#else
+#define	cache_invalidate_lines(a,b)
+#endif
+
+
+/*
+ * cache_push() semantics: Write back any dirty cache data in the given area,
+ * and invalidate the range in the instruction cache. It needs not (but may)
+ * invalidate those entries also in the data cache. The range is defined by a
+ * _physical_ address.
+ */
+
+void cache_push (unsigned long paddr, int len)
+{
+	cache_invalidate_lines(paddr, len);
+}
+
+
+/*
+ * cache_push_v() semantics: Write back any dirty cache data in the given
+ * area, and invalidate those entries at least in the instruction cache. This
+ * is intended to be used after data has been written that can be executed as
+ * code later. The range is defined by a _user_mode_ _virtual_ address  (or,
+ * more exactly, the space is defined by the %sfc/%dfc register.)
+ */
+
+void cache_push_v (unsigned long vaddr, int len)
+{
+	cache_invalidate_lines(vaddr, len);
+}
+
+/* Map some physical address range into the kernel address space. The
+ * code is copied and adapted from map_chunk().
+ */
+
+unsigned long kernel_map(unsigned long paddr, unsigned long size,
+			 int nocacheflag, unsigned long *memavailp )
+{
+	return paddr;
+}
+
+
+int is_in_rom(unsigned long addr)
+{
+
+#ifdef CONFIG_COLDFIRE
+	{
+		extern unsigned long    _ramstart, _ramend;
+
+		/* Anything not in operational RAM is returned as in rom! */
+		if (addr < _ramstart || addr >= _ramend)
+			return(1);
+	}
+#endif
+
+#if defined(CONFIG_PILOT) || defined(CONFIG_UCSIMM)
+	if (addr >= 0x10c00000)
+		return 1;
+#endif
+
+#ifdef CONFIG_M68EZ328ADS
+	if ( 0x00200000 <= addr && addr < 0x00400000)
+		return 1;
+#endif
+
+#ifdef CONFIG_M68332
+	extern char _etext;
+	
+ #ifdef SHGLCORE_ROM_BANK_0_ADDR
+	if ((addr >= SHGLCORE_ROM_BANK_0_ADDR) &&
+	    (addr < (SHGLCORE_ROM_BANK_0_ADDR+SHGLCORE_ROM_BANK_0_LENGTH)))
+		return 1;
+ #endif
+ #ifdef SHGLCORE_ROM_BANK_1_ADDR
+	else if ((addr >= SHGLCORE_ROM_BANK_1_ADDR) &&
+	    (addr < (SHGLCORE_ROM_BANK_1_ADDR+SHGLCORE_ROM_BANK_1_LENGTH)))
+		return 1;
+ #endif
+ #ifdef SHGLCORE_FLASH_BANK_0_ADDR
+	else if ((addr >= SHGLCORE_FLASH_BANK_0_ADDR) &&
+	    (addr < (SHGLCORE_FLASH_BANK_0_ADDR+SHGLCORE_FLASH_BANK_0_LENGTH)))
+		return 1;
+ #endif
+ #ifdef SHGLCORE_FLASH_BANK_1_ADDR
+	else if ((addr >= SHGLCORE_FLASH_BANK_1_ADDR) &&
+	    (addr < (SHGLCORE_FLASH_BANK_1_ADDR+SHGLCORE_FLASH_BANK_1_LENGTH)))
+		return 1;
+ #endif
+#endif
+
+	/* Default case, not in ROM */
+	return(0);
+}
+
diff -Nru a/arch/m68knommu/platform/5206/ARNEWSH/crt0_ram.S b/arch/m68knommu/platform/5206/ARNEWSH/crt0_ram.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5206/ARNEWSH/crt0_ram.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,206 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5206 ColdFire Arnewsh board.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	Arnewsh m5206 ColdFire eval board, chip select and memory setup.
+ */
+
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+/*
+ *	The following define the limits within which to search for
+ *	available RAM.
+ */
+#define	MEM_MIN		0x00100000	/* Search from 1Mb */
+#define	MEM_MAX		0x02000000	/* Max DRAM 32Mb! */
+#define	MEM_LUMP	0x00010000	/* 64 Kb chunks */
+
+#define MEM_TMPSTACK	0x00010000	/* At 64k - for exceptions */
+
+/*
+ *	Chip Select setup.
+ */
+#define	CS0_ADDR	0x0000f000	/* CS0 connected to Flash ROM */
+#define	CS0_MASK	0xf0000000	/*   is 1Mbyte */
+#define	CS0_CTRL	0x00000000	/*   read-only */
+#define	CS1_ADDR	0x00000000	/* CS1 not connected */
+#define	CS1_MASK	0x00000000
+#define	CS1_CTRL	0x00000000
+#define	CS2_ADDR	0x00003000	/* CS2 connected to SRAM */
+#define	CS2_MASK	0x0000f000	/*   is 1Mbyte */
+#define	CS2_CTRL	0x00001903	/*   read-write */
+#define	CS3_ADDR	0x00004000	/* CS3 connected to LED, par port */
+#define	CS3_MASK	0x0000f000	/*   is 1Mbyte */
+#define	CS3_CTRL	0x00000083	/*   read-write */
+#define	CS4_ADDR	0x00000000	/* CS4 not connected */
+#define	CS4_MASK	0x00000000
+#define	CS4_CTRL	0x00000123
+#define	CS5_ADDR	0x00000000	/* CS5 not connected */
+#define	CS5_MASK	0x00000000
+#define	CS5_CTRL	0x00000000
+#define	CS6_ADDR	0x00000000	/* CS6 not connected */
+#define	CS6_MASK	0x00000000
+#define	CS6_CTRL	0x00000000
+#define	CS7_ADDR	0x00000000	/* CS7 not connected */
+#define	CS7_MASK	0x00000000
+#define	CS7_CTRL	0x00000000
+#define	DMC_CTRL	0x00000000	/* default memory control */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Determine size of RAM, then set up initial stack.
+	 *
+	 *	On the Arnewsh 5206 board we can probe for the amount
+	 *	of DRAM present...
+	 */
+	move.l	#MEM_MIN, %a0			/* Start at bottom */
+	move.l	#MEM_MAX, %a1			/* Set stop point */
+	lea.l	MEM_TMPSTACK, %sp		/* Set up tmp stack ptr */
+
+	move.l	#VBR_BASE+8, %a2		/* Address of bus trap */
+	lea.l	_ram_buserr, %a3		/* Get RAM trap address */
+	move.l	%a3, (%a2)			/* Set trap to local ptr */
+
+_find_ram:
+	move.l	(%a0), %d0			/* Attempt read */
+	add.l	#MEM_LUMP, %a0			/* Try next bank */
+	cmp.l	%a1, %a0			/* Check more? */
+	bne	_find_ram
+
+	/*
+	 *	BUS error trap handler - used for RAM probing.
+	 */
+_ram_buserr:
+	bra	_found_ram
+
+_found_ram:					/* Vectored here on bus err */
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0		/* Invalidate cache cmd */
+	movec	%d0, %CACR			/* Invalidate cache */
+	move.l	#0x80000100, %d0		/* Setup cache mask */
+	movec	%d0, %CACR			/* Enable cache */
+
+
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+	move.l	8(%a0), %d0			/* Get size of ROMFS */
+	addq.l	#8, %d0				/* Allow for rounding */
+	and.l	#0xfffffffc, %d0		/* Whole words */
+
+	add.l	%d0, %a0			/* Copy from end */
+	add.l	%d0, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_thread_union, %a0
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -Nru a/arch/m68knommu/platform/5206/ARNEWSH/ram.ld b/arch/m68knommu/platform/5206/ARNEWSH/ram.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5206/ARNEWSH/ram.ld	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,72 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x10000, LENGTH = 0x200000
+}
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.exit.text)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+		*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		__init_begin = .;
+		*(.init.text)
+		*(.init.data)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.init.setup)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall1.init)
+		*(.initcall2.init)
+		*(.initcall3.init)
+		*(.initcall4.init)
+		*(.initcall5.init)
+		*(.initcall6.init)
+		*(.initcall7.init)
+		__initcall_end = .;
+		. = ALIGN(4) ;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -Nru a/arch/m68knommu/platform/5206/Makefile b/arch/m68knommu/platform/5206/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5206/Makefile	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,24 @@
+#
+# Makefile for the m68knommu linux kernel.
+#
+
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this,  which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs.  You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+ifdef CONFIG_FULLDEBUG
+AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+obj-y := config.o
+
+EXTRA_TARGETS := $(BOARD)/crt0_$(MODEL).o
+
+include $(TOPDIR)/Rules.make
+
diff -Nru a/arch/m68knommu/platform/5206/config.c b/arch/m68knommu/platform/5206/config.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5206/config.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,155 @@
+/***************************************************************************/
+
+/*
+ *	linux/arch/m68knommu/platform/5206/config.c
+ *
+ *	Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
+ * 	Copyright (C) 2000-2001, Lineo Inc. (www.lineo.com) 
+ */
+
+/***************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/init.h>
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/coldfire.h>
+#include <asm/mcftimer.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfdma.h>
+
+/***************************************************************************/
+
+/*
+ *	DMA channel base address table.
+ */
+unsigned int   dma_base_addr[MAX_M68K_DMA_CHANNELS] = {
+        MCF_MBAR + MCFDMA_BASE0,
+        MCF_MBAR + MCFDMA_BASE1,
+};
+
+unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+
+/***************************************************************************/
+
+void coldfire_tick(void)
+{
+	volatile unsigned char	*timerp;
+
+	/* Reset the ColdFire timer */
+	timerp = (volatile unsigned char *) (MCF_MBAR + MCFTIMER_BASE1);
+	timerp[MCFTIMER_TER] = MCFTIMER_TER_CAP | MCFTIMER_TER_REF;
+}
+
+/***************************************************************************/
+
+void coldfire_timer_init(void (*handler)(int, void *, struct pt_regs *))
+{
+	volatile unsigned short	*timerp;
+	volatile unsigned char	*icrp;
+
+	/* Set up TIMER 1 as poll clock */
+	timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE1);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_DISABLE;
+
+	timerp[MCFTIMER_TRR] = (unsigned short) ((MCF_CLK / 16) / HZ);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
+		MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE;
+
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_TIMER1ICR);
+
+	*icrp = MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL5 | MCFSIM_ICR_PRI3;
+	request_irq(29, handler, SA_INTERRUPT, "ColdFire Timer", NULL);
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_TIMER1);
+}
+
+/***************************************************************************/
+
+/*
+ *	Program the vector to be an auto-vectored.
+ */
+
+void mcf_autovector(unsigned int vec)
+{
+	volatile unsigned char  *mbar;
+	unsigned char		icr;
+
+	if ((vec >= 25) && (vec <= 31)) {
+		vec -= 25;
+		mbar = (volatile unsigned char *) MCF_MBAR;
+		icr = MCFSIM_ICR_AUTOVEC | (vec << 3);
+		*(mbar + MCFSIM_ICR1 + vec) = icr;
+		vec = 0x1 << (vec + 1);
+		mcf_setimr(mcf_getimr() & ~vec);
+	}
+}
+
+/***************************************************************************/
+
+extern e_vector	*_ramvec;
+
+void set_evector(int vecnum, void (*handler)(void))
+{
+	if (vecnum >= 0 && vecnum <= 255)
+		_ramvec[vecnum] = handler;
+}
+
+/***************************************************************************/
+
+/* assembler routines */
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void system_call(void);
+asmlinkage void inthandler(void);
+
+void coldfire_trap_init(void)
+{
+	int i;
+
+#ifndef ENABLE_dBUG
+	mcf_setimr(MCFSIM_IMR_MASKALL);
+#endif
+
+	/*
+	 *	There is a common trap handler and common interrupt
+	 *	handler that handle almost every vector. We treat
+	 *	the system call and bus error special, they get their
+	 *	own first level handlers.
+	 */
+#ifndef ENABLE_dBUG
+	for (i = 3; (i <= 23); i++)
+		_ramvec[i] = trap;
+	for (i = 33; (i <= 63); i++)
+		_ramvec[i] = trap;
+#endif
+
+	for (i = 24; (i <= 30); i++)
+		_ramvec[i] = inthandler;
+#ifndef ENABLE_dBUG
+	_ramvec[31] = inthandler;  // Disables the IRQ7 button
+#endif
+
+	for (i = 64; (i < 255); i++)
+		_ramvec[i] = inthandler;
+	_ramvec[255] = 0;
+
+	_ramvec[2] = buserr;
+	_ramvec[32] = system_call;
+}
+
+/***************************************************************************/
+
+void config_BSP(char *commandp, int size)
+{
+	memset(commandp, 0, size);
+	mach_sched_init = coldfire_timer_init;
+	mach_tick = coldfire_tick;
+	mach_trap_init = coldfire_trap_init;
+}
+
+/***************************************************************************/
diff -Nru a/arch/m68knommu/platform/5206e/MOTOROLA/crt0_ram.S b/arch/m68knommu/platform/5206e/MOTOROLA/crt0_ram.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5206e/MOTOROLA/crt0_ram.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,145 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5206e ColdFire based CADRE3 boards.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com)
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	Cadre-III M5206e ColdFire eval board, chip select and memory setup.
+ */
+
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	MEM_SIZE	0x00400000	/* Memory size 4Mb */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Set to 4 meg for the Cadre III board (m5206e).
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0		/* Invalidate cache cmd */
+	movec	%d0, %CACR			/* Invalidate cache */
+	move.l	#0x80000100, %d0		/* Setup cache mask */
+	movec	%d0, %CACR			/* Enable cache */
+
+
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+	move.l	8(%a0), %d0			/* Get size of ROMFS */
+	addq.l	#8, %d0				/* Allow for rounding */
+	and.l	#0xfffffffc, %d0		/* Whole words */
+
+	add.l	%d0, %a0			/* Copy from end */
+	add.l	%d0, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_thread_union, %a0
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -Nru a/arch/m68knommu/platform/5206e/MOTOROLA/ram.ld b/arch/m68knommu/platform/5206e/MOTOROLA/ram.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5206e/MOTOROLA/ram.ld	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,72 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x20000, LENGTH = 0x007E0000
+}
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.exit/text)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+		*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		__init_begin = .;
+		*(.init.text)
+		*(.init.data)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.init.setup)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall1.init)
+		*(.initcall2.init)
+		*(.initcall3.init)
+		*(.initcall4.init)
+		*(.initcall5.init)
+		*(.initcall6.init)
+		*(.initcall7.init)
+		__initcall_end = .;
+		. = ALIGN(4) ;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -Nru a/arch/m68knommu/platform/5206e/Makefile b/arch/m68knommu/platform/5206e/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5206e/Makefile	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,24 @@
+#
+# Makefile for the m68knommu linux kernel.
+#
+
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this,  which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs.  You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+ifdef CONFIG_FULLDEBUG
+AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+obj-y := config.o
+
+EXTRA_TARGETS := $(BOARD)/crt0_$(MODEL).o
+
+include $(TOPDIR)/Rules.make
+
diff -Nru a/arch/m68knommu/platform/5206e/config.c b/arch/m68knommu/platform/5206e/config.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5206e/config.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,233 @@
+/***************************************************************************/
+
+/*
+ *	linux/arch/m68knommu/platform/5206e/config.c
+ *
+ *	Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/***************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/coldfire.h>
+#include <asm/mcftimer.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfdma.h>
+
+#ifdef CONFIG_NETtel
+#include <asm/irq.h>
+#include <asm/delay.h>
+#endif
+
+/***************************************************************************/
+
+#ifdef CONFIG_NETtel
+void	reset_setupbutton(void);
+#endif
+
+/***************************************************************************/
+
+/*
+ *	DMA channel base address table.
+ */
+unsigned int   dma_base_addr[MAX_M68K_DMA_CHANNELS] = {
+        MCF_MBAR + MCFDMA_BASE0,
+        MCF_MBAR + MCFDMA_BASE1,
+};
+
+unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+
+/***************************************************************************/
+
+void coldfire_tick(void)
+{
+	volatile unsigned char	*timerp;
+
+	/* Reset the ColdFire timer */
+	timerp = (volatile unsigned char *) (MCF_MBAR + MCFTIMER_BASE1);
+	timerp[MCFTIMER_TER] = MCFTIMER_TER_CAP | MCFTIMER_TER_REF;
+}
+
+/***************************************************************************/
+
+void coldfire_timer_init(void (*handler)(int, void *, struct pt_regs *))
+{
+	volatile unsigned short	*timerp;
+	volatile unsigned char	*icrp;
+
+	/* Set up TIMER 1 as poll clock */
+	timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE1);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_DISABLE;
+
+	timerp[MCFTIMER_TRR] = (unsigned short) ((MCF_CLK / 16) / HZ);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
+		MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE;
+
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_TIMER1ICR);
+
+#ifdef CONFIG_NETtel
+	*icrp = MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3;
+	request_irq(30, handler, SA_INTERRUPT, "ColdFire Timer", NULL);
+	reset_setupbutton();
+#else
+	*icrp = MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL5 | MCFSIM_ICR_PRI3;
+	request_irq(29, handler, SA_INTERRUPT, "ColdFire Timer", NULL);
+#endif
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_TIMER1);
+}
+
+/***************************************************************************/
+
+/*
+ *	Program the vector to be an auto-vectored.
+ */
+
+void mcf_autovector(unsigned int vec)
+{
+	volatile unsigned char  *mbar;
+	unsigned char		icr;
+
+	if ((vec >= 25) && (vec <= 31)) {
+		vec -= 25;
+		mbar = (volatile unsigned char *) MCF_MBAR;
+		icr = MCFSIM_ICR_AUTOVEC | (vec << 3);
+		*(mbar + MCFSIM_ICR1 + vec) = icr;
+		vec = 0x1 << (vec + 1);
+		mcf_setimr(mcf_getimr() & ~vec);
+	}
+}
+
+/***************************************************************************/
+
+extern e_vector	*_ramvec;
+
+void set_evector(int vecnum, void (*handler)(void))
+{
+	if (vecnum >= 0 && vecnum <= 255)
+		_ramvec[vecnum] = handler;
+}
+
+/***************************************************************************/
+
+/* assembler routines */
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void system_call(void);
+asmlinkage void inthandler(void);
+
+void coldfire_trap_init(void)
+{
+	int i;
+#ifdef MCF_MEMORY_PROTECT
+	extern unsigned long _end;
+	extern unsigned long memory_end;
+#endif
+
+#ifndef ENABLE_dBUG
+	mcf_setimr(MCFSIM_IMR_MASKALL);
+#endif
+
+	/*
+	 *	There is a common trap handler and common interrupt
+	 *	handler that handle almost every vector. We treat
+	 *	the system call and bus error special, they get their
+	 *	own first level handlers.
+	 */
+#ifndef ENABLE_dBUG
+	for (i = 3; (i <= 23); i++)
+		_ramvec[i] = trap;
+	for (i = 33; (i <= 63); i++)
+		_ramvec[i] = trap;
+#endif
+
+	for (i = 24; (i <= 30); i++)
+		_ramvec[i] = inthandler;
+#ifndef ENABLE_dBUG
+	_ramvec[31] = inthandler;  // Disables the IRQ7 button
+#endif
+
+	for (i = 64; (i < 255); i++)
+		_ramvec[i] = inthandler;
+	_ramvec[255] = 0;
+
+	_ramvec[2] = buserr;
+	_ramvec[32] = system_call;
+}
+
+/***************************************************************************/
+
+#ifdef CONFIG_NETtel
+
+/*
+ *	Routines to support the NETtel software reset button.
+ */
+void reset_button(int irq, void *dev_id, struct pt_regs *regs)
+{
+	extern void	flash_eraseconfig(void);
+	static int	inbutton = 0;
+
+	/*
+	 *	IRQ7 is not maskable by the CPU core. It is possible
+	 *	that switch bounce may get us back here before we have
+	 *	really serviced the interrupt.
+	 */
+	if (inbutton)
+		return;
+	inbutton = 1;
+	/* Disable interrupt at SIM - best we can do... */
+	mcf_setimr(mcf_getimr() | MCFSIM_IMR_EINT7);
+	/* Try and de-bounce the switch a little... */
+	udelay(10000);
+
+	flash_eraseconfig();
+
+	/* Don't leave here 'till button is no longer pushed! */
+	for (;;) {
+		if ((mcf_getipr() & MCFSIM_IMR_EINT7) == 0)
+			break;
+	}
+
+	HARD_RESET_NOW();
+	/* Should never get here... */
+
+	inbutton = 0;
+	/* Interrupt service done, enable it again */
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT7);
+}
+
+/***************************************************************************/
+
+void reset_setupbutton(void)
+{
+	mcf_autovector(31);
+	request_irq(31, reset_button, (SA_INTERRUPT | IRQ_FLG_FAST),
+		"Reset Button", NULL);
+}
+
+#endif /* CONFIG_NETtel */
+
+/***************************************************************************/
+
+void config_BSP(char *commandp, int size)
+{
+#ifdef CONFIG_NETtel
+	/* Copy command line from FLASH to local buffer... */
+	memcpy(commandp, (char *) 0xf0004000, size);
+	commandp[size-1] = 0;
+#else
+	memset(commandp, 0, size);
+#endif /* CONFIG_NETtel */
+
+	mach_sched_init = coldfire_timer_init;
+	mach_tick = coldfire_tick;
+	mach_trap_init = coldfire_trap_init;
+}
+
+/***************************************************************************/
diff -Nru a/arch/m68knommu/platform/5206e/eLITE/crt0_ram.S b/arch/m68knommu/platform/5206e/eLITE/crt0_ram.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5206e/eLITE/crt0_ram.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,339 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5206e ColdFire based eLITE boards.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ *	Copyright (C) 1999 Rob Scott (rscott@mtrob.fdns.net)
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	M5206eLITE ColdFire eval board, chip select and memory setup.
+ */
+
+#ifdef CONFIG_SMALL
+#define	MEM_BASE	0x30000000      /* Base memory for M5206eLITE */
+#define	MEM_RESERVED	0x00020000      /* Don't use memory reserved by dBUG */
+#define	MEM_SIZE	0x00100000      /* 1 MB of SRAM on M5206eLITE */
+#else
+#define	MEM_BASE	0x00000000      /* Base memory for M5206eLITE */
+#define	MEM_RESERVED	0x00010000      /* Skip first MEM_LUMP for colilo */
+#define	MEM_SIZE	0x02000000      /* Max DRAM 32Mb */
+#endif
+#define	MEM_MIN		MEM_BASE+MEM_RESERVED
+/* Define end of probeable memory space */
+#define	MEM_MAX		MEM_BASE+MEM_SIZE
+#define	MEM_BUILTIN	0x20000000      /* Put built in SRAM at dBUG loc */
+#define	MEM_TMPSTACK	MEM_BUILTIN+0x800 /* Use built in SRAM for tmp stack */
+#define	MEM_LUMP	0x00010000	/* 64 Kb chunks */
+#define	VBR_BASE	MEM_BUILTIN     /* Use built in SRAM for vectors */
+
+#define	CS0_ADDR	0x0000ffe0	/* CS0 connected to Flash ROM */
+#define	CS0_MASK	0x000f0000	/*   is 1Mbyte */
+#define	CS0_CTRL	0x00001da3	/*   read-write (for flash) */
+#define	CS1_ADDR	0x00000000	/* CS1 not connected */
+#define	CS1_MASK	0x00000000
+#define	CS1_CTRL	0x00000000
+#define	CS2_ADDR	0x00003000	/* CS2 connected to SRAM */
+#define	CS2_MASK	0x000f0000	/*   is 1Mbyte */
+#define	CS2_CTRL	0x00001903	/*   read-write */
+#define	CS3_ADDR	0x00004000	/* CS3 connected to LED, par port */
+#define	CS3_MASK	0x000f0000	/*   is 1Mbyte */
+#define	CS3_CTRL	0x00000183	/*   read-write */
+#define	CS4_ADDR	0x00000000	/* CS4 not connected */
+#define	CS4_MASK	0x00000000
+#define	CS4_CTRL	0x00000000
+#define	CS5_ADDR	0x00000000	/* CS5 not connected */
+#define	CS5_MASK	0x00000000
+#define	CS5_CTRL	0x00000000
+#define	CS6_ADDR	0x00000000	/* CS6 not connected */
+#define	CS6_MASK	0x00000000
+#define	CS6_CTRL	0x00000000
+#define	CS7_ADDR	0x00000000	/* CS7 not connected */
+#define	CS7_MASK	0x00000000
+#define	CS7_CTRL	0x00000000
+#define	DMC_CTRL	0x00000000	/* default memory control */
+
+#define	DCRR		0x00000034	/* Refresh period  */
+/* DCTR definition:
+     <15>: DAEM, 1 = Drive Multiplexed Address During External Master DRAM xfer
+     <14>: EDO,  1 = EDO, 0 = Normal
+     <12>: RCD,  1 = 2 clk RAS-to-CAS, 0 = 1.0 clk RAS-to-CAS
+  <10:09>: RSH,  10 = 3.5 clk RAS low, 01 = 2.5 clk, 00 = 1.5 clk
+  <06:05>: RP,   10 = 3.5 clk RAS Precharge, 01 = 2.5 clk, 00 = 1.5 clk
+     <03>: CAS,  1 = 2.5 clk CAS assertion, 0 = 1.5 clk
+     <01>: CP,   1 = 1.5 CAS clk precharge, 0 = .5 clk
+     <00>: CSR,  1 = 2.0 clk CAS before RAS setup, 0 = 1.0 clk
+*/
+#define	DCTR		0x0000144B	/* Slow DRAM */
+#define	DCAR0		0x00000000	/* DRAM0 address, 0 base addr */
+#define	DCMR0		0x003e0000	/* DRAM0 mask, 4Mb DRAM */
+#define	DCCR0		0x00000007	/* DRAM0 control, R/W, burst pg mde */
+#define	DCAR1		0x00000000	/* DRAM1 address, 0 base addr */
+#define	DCMR1		0x00000000	/* DRAM1 mask, no DRAM */
+#define	DCCR1		0x00000000	/* DRAM1 control, off */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	move.l	#MCF_MBAR+1, %a0		/* Set I/O base addr */
+	movec	%a0, %MBAR			/* Note: bit 0 is Validate */
+	move.l	#MEM_BUILTIN+1,%a0		/* Set SRAM base addr */
+	movec	%a0, %RAMBAR0			/* Note: bit 0 is Validate */
+
+	move.l	#MCF_MBAR, %a0			/* Get I/O base addr */
+
+	/* ----------------------- CS1 ----------------------- */
+	move.w	#CS1_ADDR, %d0			/* CS1 address */
+	move.w	%d0, MCFSIM_CSAR1(%a0)		/* CS1 address */
+	move.l	#CS1_MASK, %d0			/* CS1 mask */
+	move.l	%d0, MCFSIM_CSMR1(%a0)		/* CS1 mask */
+	move.w	#CS1_CTRL, %d0			/* CS1 control */
+	move.w	%d0, MCFSIM_CSCR1(%a0)		/* CS1 control */
+
+	/* ----------------------- CS2 ----------------------- */
+	move.w	#CS2_ADDR, %d0			/* CS2 address */
+	move.w	%d0, MCFSIM_CSAR2(%a0)		/* CS2 address */
+	move.l	#CS2_MASK, %d0			/* CS2 mask */
+	move.l	%d0, MCFSIM_CSMR2(%a0)		/* CS2 mask */
+	move.w	#CS2_CTRL, %d0			/* CS2 control */
+	move.w	%d0, MCFSIM_CSCR2(%a0)		/* CS2 control */
+
+	/* ----------------------- CS3 ----------------------- */
+	move.w	#CS3_ADDR, %d0			/* CS3 address */
+	move.w	%d0, MCFSIM_CSAR3(%a0)		/* CS3 address */
+	move.l	#CS3_MASK, %d0			/* CS3 mask */
+	move.l	%d0, MCFSIM_CSMR3(%a0)		/* CS3 mask */
+	move.w	#CS3_CTRL, %d0			/* CS3 control */
+	move.w	%d0, MCFSIM_CSCR3(%a0)		/* CS3 control */
+
+	/* ----------------------- CS4 ----------------------- */
+	move.w	#CS4_ADDR, %d0			/* CS4 address */
+	move.w	%d0, MCFSIM_CSAR4(%a0)		/* CS4 address */
+	move.l	#CS4_MASK, %d0			/* CS4 mask */
+	move.l	%d0, MCFSIM_CSMR4(%a0)		/* CS4 mask */
+	move.w	#CS4_CTRL, %d0			/* CS4 control */
+	move.w	%d0, MCFSIM_CSCR4(%a0)		/* CS4 control */
+
+	/* ----------------------- CS5 ----------------------- */
+	move.w	#CS5_ADDR, %d0			/* CS5 address */
+	move.w	%d0, MCFSIM_CSAR5(%a0)		/* CS5 address */
+	move.l	#CS5_MASK, %d0			/* CS5 mask */
+	move.l	%d0, MCFSIM_CSMR5(%a0)		/* CS5 mask */
+	move.w	#CS5_CTRL, %d0			/* CS5 control */
+	move.w	%d0, MCFSIM_CSCR5(%a0)		/* CS5 control */
+
+	/* ----------------------- CS6 ----------------------- */
+	move.w	#CS6_ADDR, %d0			/* CS6 address */
+	move.w	%d0, MCFSIM_CSAR6(%a0)		/* CS6 address */
+	move.l	#CS6_MASK, %d0			/* CS6 mask */
+	move.l	%d0, MCFSIM_CSMR6(%a0)		/* CS6 mask */
+	move.w	#CS6_CTRL, %d0			/* CS6 control */
+	move.w	%d0, MCFSIM_CSCR6(%a0)		/* CS6 control */
+
+	/* ----------------------- CS7 ----------------------- */
+	move.w	#CS7_ADDR, %d0			/* CS7 address */
+	move.w	%d0, MCFSIM_CSAR7(%a0)		/* CS7 address */
+	move.l	#CS7_MASK, %d0			/* CS7 mask */
+	move.l	%d0, MCFSIM_CSMR7(%a0)		/* CS7 mask */
+	move.w	#CS7_CTRL, %d0			/* CS7 control */
+	move.w	%d0, MCFSIM_CSCR7(%a0)		/* CS7 control */
+
+	/* --------------------- Default --------------------- */
+	move.w	#DMC_CTRL, %d0			/* Default control */
+	move.w	%d0, MCFSIM_DMCR(%a0)		/* Default control */
+
+	/* ----------------------- DRAM ------------------------ */
+	move.w	#DCRR, %d0			/* Refresh period */
+	move.w	%d0, MCFSIM_DCRR(%a0)		/* Refresh period */
+	move.w	#DCTR, %d0			/* Timing address */
+	move.w	%d0, MCFSIM_DCTR(%a0)		/* Timing address */
+	move.w	#DCAR0, %d0			/* DRAM0 base address */
+	move.w	%d0, MCFSIM_DCAR0(%a0)		/* DRAM0 base address */
+	move.l	#DCMR0, %d0			/* DRAM0 mask */
+	move.l	%d0, MCFSIM_DCMR0(%a0)		/* DRAM0 mask */
+	move.b	#DCCR0, %d0			/* DRAM0 control */
+	move.b	%d0, MCFSIM_DCCR0(%a0)		/* DRAM0 control */
+	move.w	#DCAR1, %d0			/* DRAM1 base address */
+	move.w	%d0, MCFSIM_DCAR1(%a0)		/* DRAM1 base address */
+	move.l	#DCMR1, %d0			/* DRAM1 mask */
+	move.l	%d0, MCFSIM_DCMR1(%a0)		/* DRAM1 mask */
+	move.b	#DCCR1, %d0			/* DRAM1 control */
+	move.b	%d0, MCFSIM_DCCR1(%a0)		/* DRAM1 control */
+
+	/*
+	 * ChipSelect 0 - ROM cs
+	 *
+	 * ChipSelect 0 is the global chip select coming out of system reset.
+	 * CS0 is asserted for every access until CSMR0 is written.  Therefore,
+	 * the entire ChipSelect must be properly set prior to asserting
+	 * CSCR0_V.
+	 */
+	move.w	#CS0_ADDR, %d0			/* CS0 address */
+	move.w	%d0, MCFSIM_CSAR0(%a0)		/* CS0 address */
+	move.l	#CS0_MASK, %d0			/* CS0 mask */
+	move.l	%d0, MCFSIM_CSMR0(%a0)		/* CS0 mask */
+	move.w	#CS0_CTRL, %d0			/* CS0 control */
+	move.w	%d0, MCFSIM_CSCR0(%a0)		/* CS0 control */
+
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Determine size of RAM, then set up initial stack
+	 *	Done differently for different eval boards and cpus.
+	 */
+
+#if defined(CONFIG_SMALL)
+	/*
+	 *	Set to SRAM size when configuring a minimal system
+	 */
+	move.l	#MEM_MAX, %a0
+
+#else
+	/*
+	 *	On the Arnewsh 5206 board and the Motorola m5206eLITE board
+	 *	we can probe for the amount of DRAM present...
+	 */
+	move.l	#MEM_MIN, %a0			/* Start at bottom */
+	move.l	#MEM_MAX, %a1			/* Set stop point */
+	lea.l	MEM_TMPSTACK, %sp		/* Set up tmp stack ptr */
+
+	move.l	#VBR_BASE+8, %a2		/* Address of bus trap */
+	lea.l	_ram_buserr, %a3		/* Get RAM trap address */
+	move.l	%a3, (%a2)			/* Set trap to local ptr */
+
+_find_ram:
+	move.l	(%a0), %d0			/* Attempt read */
+	add.l	#MEM_LUMP, %a0			/* Try next bank */
+	cmp.l	%a1, %a0			/* Check more? */
+	bne	_find_ram
+
+	/*
+	 *	BUS error trap handler - used for RAM probing.
+	 */
+_ram_buserr:
+	bra	_found_ram
+
+_found_ram:					/* Vectored here on bus err */
+#endif
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0		/* Invalidate cache cmd */
+	movec	%d0, %CACR			/* Invalidate cache */
+	move.l	#0x80000100, %d0		/* Setup cache mask */
+	movec	%d0, %CACR			/* Enable cache */
+
+
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+	move.l	8(%a0), %d0			/* Get size of ROMFS */
+	addq.l	#8, %d0				/* Allow for rounding */
+	and.l	#0xfffffffc, %d0		/* Whole words */
+
+	add.l	%d0, %a0			/* Copy from end */
+	add.l	%d0, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+	/*
+	 *      Load the current task pointer and stack.
+	 */
+	lea	init_thread_union, %a0
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -Nru a/arch/m68knommu/platform/5206e/eLITE/ram.ld b/arch/m68knommu/platform/5206e/eLITE/ram.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5206e/eLITE/ram.ld	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,72 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x30020000, LENGTH = 0xe0000
+}
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS {
+
+	.text 0x30020000 : {
+		_stext = . ;
+        	*(.text)
+		*(.exit.text)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+		*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		__init_begin = .;
+		*(.init.text)
+		*(.init.data)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.init.setup)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall1.init)
+		*(.initcall2.init)
+		*(.initcall3.init)
+		*(.initcall4.init)
+		*(.initcall5.init)
+		*(.initcall6.init)
+		*(.initcall7.init)
+		__initcall_end = .;
+		. = ALIGN(4) ;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -Nru a/arch/m68knommu/platform/5249/MOTOROLA/crt0_ram.S b/arch/m68knommu/platform/5249/MOTOROLA/crt0_ram.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5249/MOTOROLA/crt0_ram.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,223 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for Motorola M5249C3 eval board.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	Motorola M5249C3 ColdFire eval board, chip select and memory setup.
+ */
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	MEM_SIZE	0x00800000	/* Memory size 8MB */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 *	Set MBAR1 and MBAR2, just incase they are not set.
+	 */
+	move.l  #0x10000001, %a0
+	movec   %a0, %MBAR			/* Map MBAR region */
+	subq.l  #1, %a0				/* Get MBAR address in a0 */
+
+	move.l  #0x80000001, %a1
+	movec   %a1, #3086			/* Map MBAR2 region */
+	subq.l  #1, %a1				/* Get MBAR2 address in a1 */
+
+	/*
+	 *      Move secondary interrupts to base at 128.
+	 */
+	move.b  #0x80, %d0
+	move.b  %d0, 0x16b(%a1)			/* Interrupt base register */
+
+#if 1
+	/*
+	 *      Work around broken CSMR0/DRAM vector problem.
+	 */
+	move.l  #0x001F0021, %d0		/* Disable C/I bit */
+	move.l  %d0, 0x84(%a0)			/* Set CSMR0 */
+#endif
+
+	/*
+	 *	Disable the PLL firstly. (Who knows what state it is
+	 *	in here!).
+	 */
+	move.l  0x180(%a1), %d0			/* Get current PLL value */
+	and.l   #0xfffffffe, %d0		/* PLL bypass first */
+	move.l  %d0, 0x180(%a1)			/* Set PLL register */
+	nop
+
+#if CONFIG_CLOCK_140MHz
+	/*
+	 *	Set initial clock frequency. This assumes M5249C3 board
+	 *	is fitted with 11.2896MHz crystal. It will program the
+	 *	PLL for 140MHz. Lets go fast :-)
+	 */
+	move.l  #0x125a40f0, %d0		/* Set for 140MHz */
+	move.l  %d0, 0x180(%a1)			/* Set PLL register */
+	or.l    #0x1, %d0
+	move.l  %d0, 0x180(%a1)			/* Set PLL register */
+#endif
+
+	/*
+	 *	Setup CS1 for ethernet controller.
+	 *	(Setup as per M5249C3 doco).
+	 */
+	move.l  #0xe0000000, %d0		/* CS1 mapped at 0xe0000000 */
+	move.l  %d0, 0x8c(%a0)
+	move.l  #0x001f0021, %d0		/* CS1 size of 1Mb */
+	move.l  %d0, 0x90(%a0)
+	move.w  #0x0080, %d0			/* CS1 = 16bit port, AA */
+	move.w  %d0, 0x96(%a0)
+
+	/*
+	 *	Setup CS2 for IDE interface.
+	 */
+	move.l	#0x50000000, %d0		/* CS2 mapped at 0x50000000 */
+	move.l	%d0, 0x98(%a0)
+	move.l	#0x001f0001, %d0		/* CS2 size of 1MB */
+	move.l	%d0, 0x9c(%a0)
+	move.w	#0x0080, %d0			/* CS2 = 16bit, TA */
+	move.w	%d0, 0xa2(%a0)
+
+	move.l	#0x00107000, %d0		/* IDEconfig1 */
+	move.l	%d0, 0x18c(%a1)
+	move.l	#0x000c0400, %d0		/* IDEconfig2 */
+	move.l	%d0, 0x190(%a1)
+
+	move.l	#0x00080000, %d0		/* GPIO19, IDE reset bit */
+	or.l	%d0, 0xc(%a1)			/* Function GPIO19 */
+	or.l	%d0, 0x8(%a1)			/* Enable GPIO19 as output */
+        or.l	%d0, 0x4(%a1)			/* De-assert IDE reset */
+
+
+	/*
+	 *	Setup VBR as per eval board (really dBUG does this).
+	 *	These settings must match it.
+	 */
+	move.l	#VBR_BASE, %a0			/* Note VBR can't be read */
+	movec   %a0, %VBR
+	move.l	%a0, _ramvec			/* Set up vector addr */
+	move.l	%a0, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Set the memory size, and then set a temporary stack.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l  #0x01000000, %d0		/* Invalidate whole cache */
+	movec   %d0, %CACR
+	nop
+
+	move.l  #0x0000c000, %d0		/* Set SDRAM cached only */
+	movec   %d0, %ACR0
+	move.l  #0x00000000, %d0		/* No other regions cached */
+	movec   %d0, %ACR1
+
+	move.l  #0xa0000200, %d0		/* Enable cache... */
+	movec   %d0, %CACR
+	nop
+
+
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+	move.l	8(%a0), %d0			/* Get size of ROMFS */
+	addq.l	#8, %d0				/* Allow for rounding */
+	and.l	#0xfffffffc, %d0		/* Whole words */
+
+	add.l	%d0, %a0			/* Copy from end */
+	add.l	%d0, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+	/*
+	 * Load the current thread pointer and stack.
+	 */
+	lea	init_thread_union, %a0
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -Nru a/arch/m68knommu/platform/5249/MOTOROLA/ram.ld b/arch/m68knommu/platform/5249/MOTOROLA/ram.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5249/MOTOROLA/ram.ld	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,76 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x20000, LENGTH = 0x3e0000
+}
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.exit.text)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+        	*(.modinfo)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sdata = . ;
+		__data_start = . ;
+		*(.data)
+		*(.data.exit)
+		. = ALIGN(8192) ;
+		*(.data.init_task)
+		. = ALIGN(8192) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		. = ALIGN(4096);
+		__init_begin = .;
+		*(.init.text)
+		*(.init.data)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.init.setup)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall1.init)
+		*(.initcall2.init)
+		*(.initcall3.init)
+		*(.initcall4.init)
+		*(.initcall5.init)
+		*(.initcall6.init)
+		*(.initcall7.init)
+		__initcall_end = .;
+		. = ALIGN(4);
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -Nru a/arch/m68knommu/platform/5249/Makefile b/arch/m68knommu/platform/5249/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5249/Makefile	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,24 @@
+#
+# Makefile for the m68knommu linux kernel.
+#
+
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this,  which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs.  You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+ifdef CONFIG_FULLDEBUG
+AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+obj-y := config.o
+
+EXTRA_TARGETS := $(BOARD)/crt0_$(MODEL).o
+
+include $(TOPDIR)/Rules.make
+
diff -Nru a/arch/m68knommu/platform/5249/config.c b/arch/m68knommu/platform/5249/config.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5249/config.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,229 @@
+/***************************************************************************/
+
+/*
+ *	linux/arch/m68knommu/platform/5249/config.c
+ *
+ *	Copyright (C) 2002, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/***************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/init.h>
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/coldfire.h>
+#include <asm/mcftimer.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfdma.h>
+#include <asm/delay.h>
+
+/***************************************************************************/
+
+void	coldfire_profile_init(void);
+
+/***************************************************************************/
+
+/*
+ *	DMA channel base address table.
+ */
+unsigned int   dma_base_addr[MAX_M68K_DMA_CHANNELS] = {
+        MCF_MBAR + MCFDMA_BASE0,
+        MCF_MBAR + MCFDMA_BASE1,
+        MCF_MBAR + MCFDMA_BASE2,
+        MCF_MBAR + MCFDMA_BASE3,
+};
+
+unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+
+/***************************************************************************/
+
+void coldfire_tick(void)
+{
+	volatile unsigned char	*timerp;
+
+	/* Reset the ColdFire timer */
+	timerp = (volatile unsigned char *) (MCF_MBAR + MCFTIMER_BASE1);
+	timerp[MCFTIMER_TER] = MCFTIMER_TER_CAP | MCFTIMER_TER_REF;
+}
+
+/***************************************************************************/
+
+void coldfire_timer_init(void (*handler)(int, void *, struct pt_regs *))
+{
+	volatile unsigned short	*timerp;
+	volatile unsigned char	*icrp;
+
+	/* Set up TIMER 1 as poll clock */
+	timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE1);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_DISABLE;
+
+	timerp[MCFTIMER_TRR] = (unsigned short) ((MCF_CLK / 16) / HZ);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
+		MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE;
+
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_TIMER1ICR);
+	*icrp = MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL5 | MCFSIM_ICR_PRI3;
+	request_irq(29, handler, SA_INTERRUPT, "ColdFire Timer", NULL);
+
+#ifdef CONFIG_HIGHPROFILE
+	coldfire_profile_init();
+#endif
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_TIMER1);
+}
+
+/***************************************************************************/
+#ifdef CONFIG_HIGHPROFILE
+/***************************************************************************/
+
+#define	PROFILEHZ	1013
+
+/*
+ *	Use the other timer to provide high accuracy profiling info.
+ */
+
+void coldfire_profile_tick(int irq, void *dummy, struct pt_regs *regs)
+{
+	volatile unsigned char	*timerp;
+
+	/* Reset the ColdFire timer2 */
+	timerp = (volatile unsigned char *) (MCF_MBAR + MCFTIMER_BASE2);
+	timerp[MCFTIMER_TER] = MCFTIMER_TER_CAP | MCFTIMER_TER_REF;
+
+        if (!user_mode(regs)) {
+                if (prof_buffer && current->pid) {
+                        extern int _stext;
+                        unsigned long ip = instruction_pointer(regs);
+                        ip -= (unsigned long) &_stext;
+                        ip >>= prof_shift;
+                        if (ip < prof_len)
+                                prof_buffer[ip]++;
+                }
+        }
+}
+
+void coldfire_profile_init(void)
+{
+	volatile unsigned short	*timerp;
+	volatile unsigned char	*icrp;
+
+	printk("PROFILE: lodging timer2=%d as profile timer\n", PROFILEHZ);
+
+	/* Set up TIMER 2 as poll clock */
+	timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE2);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_DISABLE;
+
+	timerp[MCFTIMER_TRR] = (unsigned short) ((MCF_CLK / 16) / PROFILEHZ);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
+		MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE;
+
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_TIMER2ICR);
+
+	*icrp = MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3;
+	request_irq(31, coldfire_profile_tick, (SA_INTERRUPT | IRQ_FLG_FAST),
+		"Profile Timer", NULL);
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_TIMER2);
+}
+
+/***************************************************************************/
+#endif	/* CONFIG_HIGHPROFILE */
+/***************************************************************************/
+
+/*
+ *	Program the vector to be an auto-vectored.
+ */
+
+void mcf_autovector(unsigned int vec)
+{
+	volatile unsigned char  *mbar;
+
+	if ((vec >= 25) && (vec <= 31)) {
+		mbar = (volatile unsigned char *) MCF_MBAR;
+		vec = 0x1 << (vec - 24);
+		*(mbar + MCFSIM_AVR) |= vec;
+		mcf_setimr(mcf_getimr() & ~vec);
+	}
+}
+
+/***************************************************************************/
+
+extern e_vector	*_ramvec;
+
+void set_evector(int vecnum, void (*handler)(void))
+{
+	if (vecnum >= 0 && vecnum <= 255)
+		_ramvec[vecnum] = handler;
+}
+
+/***************************************************************************/
+
+/* assembler routines */
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void system_call(void);
+asmlinkage void inthandler(void);
+
+void __init coldfire_trap_init(void)
+{
+	int i;
+
+#ifndef ENABLE_dBUG
+	mcf_setimr(MCFSIM_IMR_MASKALL);
+#endif
+
+	/*
+	 *	There is a common trap handler and common interrupt
+	 *	handler that handle almost every vector. We treat
+	 *	the system call and bus error special, they get their
+	 *	own first level handlers.
+	 */
+#ifndef ENABLE_dBUG
+	for (i = 3; (i <= 23); i++)
+		_ramvec[i] = trap;
+	for (i = 33; (i <= 63); i++)
+		_ramvec[i] = trap;
+#endif
+
+	for (i = 24; (i <= 30); i++)
+		_ramvec[i] = inthandler;
+#ifndef ENABLE_dBUG
+	_ramvec[31] = inthandler;  // Disables the IRQ7 button
+#endif
+
+	for (i = 64; (i < 255); i++)
+		_ramvec[i] = inthandler;
+	_ramvec[255] = 0;
+
+	_ramvec[2] = buserr;
+	_ramvec[32] = system_call;
+}
+
+/***************************************************************************/
+
+void config_BSP(char *commandp, int size)
+{
+	memset(commandp, 0, size);
+
+	mach_sched_init = coldfire_timer_init;
+	mach_tick = coldfire_tick;
+	mach_trap_init = coldfire_trap_init;
+}
+
+/***************************************************************************/
+#ifdef TRAP_DBG_INTERRUPT
+
+asmlinkage void dbginterrupt_c(struct frame *fp)
+{
+	extern void dump(struct pt_regs *fp);
+	printk("%s(%d): BUS ERROR TRAP\n", __FILE__, __LINE__);
+        dump((struct pt_regs *) fp);
+	asm("halt");
+}
+
+#endif
+/***************************************************************************/
diff -Nru a/arch/m68knommu/platform/5272/MOTOROLA/crt0_ram.S b/arch/m68knommu/platform/5272/MOTOROLA/crt0_ram.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5272/MOTOROLA/crt0_ram.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,152 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5272 ColdFire based MOTOROLA boards.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ *	(C) Copyright 2000, Lineo (www.lineo.com).
+ */
+
+/*****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/threads.h>
+#include <linux/linkage.h>
+#include <asm/segment.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+
+/*****************************************************************************/
+
+/*
+ *	Motorola M5272C3 ColdFire eval board, chip select and memory setup.
+ */
+
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+#if defined(CONFIG_RAM16MB)
+#define	MEM_SIZE	0x01000000	/* Memory size 16Mb */
+#elif defined(CONFIG_RAM8MB)
+#define	MEM_SIZE	0x00800000	/* Memory size 8Mb */
+#else
+#define	MEM_SIZE	0x00400000	/* Memory size 4Mb */
+#endif
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Set memory size.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0		/* Invalidate cache cmd */
+	movec	%d0, %CACR			/* Invalidate cache */
+	move.l	#0x80000100, %d0		/* Setup cache mask */
+	movec	%d0, %CACR			/* Enable cache */
+
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+	move.l	8(%a0), %d0			/* Get size of ROMFS */
+	addq.l	#8, %d0				/* Allow for rounding */
+	and.l	#0xfffffffc, %d0		/* Whole words */
+
+	add.l	%d0, %a0			/* Copy from end */
+	add.l	%d0, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+	/*
+	 *	Load the current thread pointer and stack.
+	 */
+	lea	init_thread_union, %a0
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -Nru a/arch/m68knommu/platform/5272/MOTOROLA/ram.ld b/arch/m68knommu/platform/5272/MOTOROLA/ram.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5272/MOTOROLA/ram.ld	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,76 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x20000, LENGTH = 0x3e0000
+}
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.exit.text)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+        	*(.modinfo)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sdata = . ;
+		__data_start = . ;
+		*(.data)
+		*(.data.exit)
+		. = ALIGN(8192) ;
+		*(.data.init_task)
+		. = ALIGN(8192) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		. = ALIGN(4096);
+		__init_begin = .;
+		*(.init.text)
+		*(.init.data)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.init.setup)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall1.init)
+		*(.initcall2.init)
+		*(.initcall3.init)
+		*(.initcall4.init)
+		*(.initcall5.init)
+		*(.initcall6.init)
+		*(.initcall7.init)
+		__initcall_end = .;
+		. = ALIGN(4);
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -Nru a/arch/m68knommu/platform/5272/Makefile b/arch/m68knommu/platform/5272/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5272/Makefile	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,24 @@
+#
+# Makefile for the linux kernel.
+#
+
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this,  which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs.  You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+ifdef CONFIG_FULLDEBUG
+AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+obj-y := config.o
+
+EXTRA_TARGETS := $(BOARD)/crt0_$(MODEL).o
+
+include $(TOPDIR)/Rules.make
+
diff -Nru a/arch/m68knommu/platform/5272/NETtel/crt0_ram.S b/arch/m68knommu/platform/5272/NETtel/crt0_ram.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5272/NETtel/crt0_ram.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,188 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5307 ColdFire based NETtel.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ * 	Copyright (C) 2000  Lineo Inc. (www.lineo.com) 
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+#include "asm/nettel.h"
+
+/*****************************************************************************/
+
+/*
+ *	Lineo NETtel board memory setup.
+ */
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+#if defined(CONFIG_RAM16MB)
+#define	MEM_SIZE	0x01000000	/* Memory size 16Mb */
+#elif defined(CONFIG_RAM8MB)
+#define	MEM_SIZE	0x00800000	/* Memory size 8Mb */
+#else
+#define	MEM_SIZE	0x00400000	/* Memory size 4Mb */
+#endif
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+/*****************************************************************************/
+
+/*
+ *	The NETtel platform has some funky LEDs!
+ */
+.global ppdata
+ppdata:
+.short	0x0000
+
+.global ledbank
+ledbank:
+.byte	0xff
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Determine size of RAM, then set up initial stack.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0		/* Invalidate cache cmd */
+	movec	%d0, %CACR			/* Invalidate cache */
+	move.l	#0x80000100, %d0		/* Setup cache mask */
+	movec	%d0, %CACR			/* Enable cache */
+	nop
+
+#ifdef CONFIG_ROMFS_FROM_ROM
+	/*
+	 *	check for an in RAM romfs
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	mov.l	(%a0), %d0
+	cmp.l	#0x2d726f6d, %d0	/* check for "-rom" */
+	bne		use_xip_romfs
+	add.l	#4, %a0
+	mov.l	(%a0), %d0
+	cmp.l	#0x3166732d, %d0	/* check for "1fs-" */
+	bne		use_xip_romfs
+#endif
+
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+	move.l	8(%a0), %d0			/* Get size of ROMFS */
+	addq.l	#8, %d0				/* Allow for rounding */
+	and.l	#0xfffffffc, %d0		/* Whole words */
+
+	add.l	%d0, %a0			/* Copy from end */
+	add.l	%d0, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#ifdef CONFIG_ROMFS_FROM_ROM
+	bra		done_romfs
+  use_xip_romfs:
+	lea.l	_ebss, %a1			/* Set up destination  */
+	mov.l	#0, (%a1)			/* make sure we don't use an old RAM version */
+	move.l	%a1, _ramstart		/* Set start of ram */
+  done_romfs:
+#endif
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+	/*
+	 * load the current task pointer and stack
+	 */
+	lea	init_thread_union, %a0
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -Nru a/arch/m68knommu/platform/5272/NETtel/ram.ld b/arch/m68knommu/platform/5272/NETtel/ram.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5272/NETtel/ram.ld	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,76 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x400, LENGTH = 0x400000
+}
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+		*(.text)
+		*(.exit.text)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		*(.modinfo)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sdata = . ;
+		__data_start = . ;
+		*(.data)
+		*(.data.exit)
+		. = ALIGN(8192) ;
+		*(.data.init_task)
+		. = ALIGN(8192) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		. = ALIGN(4096);
+		__init_begin = .;
+		*(.init.text)
+		*(.init.data)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.init.setup)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall1.init)
+		*(.initcall2.init)
+		*(.initcall3.init)
+		*(.initcall4.init)
+		*(.initcall5.init)
+		*(.initcall6.init)
+		*(.initcall7.init)
+		__initcall_end = .;
+		. = ALIGN(4);
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -Nru a/arch/m68knommu/platform/5272/config.c b/arch/m68knommu/platform/5272/config.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5272/config.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,247 @@
+/***************************************************************************/
+
+/*
+ *	linux/arch/m68knommu/platform/5272/config.c
+ *
+ *	Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
+ *	Copyright (C) 2001-2002, SnapGear Inc. (www.snapgear.com)
+ */
+
+/***************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/init.h>
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/coldfire.h>
+#include <asm/mcftimer.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfdma.h>
+#include <asm/delay.h>
+
+/***************************************************************************/
+
+void	reset_setupbutton(void);
+
+/***************************************************************************/
+
+/*
+ *	DMA channel base address table.
+ */
+unsigned int   dma_base_addr[MAX_M68K_DMA_CHANNELS] = {
+        MCF_MBAR + MCFDMA_BASE0,
+};
+
+unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+
+/***************************************************************************/
+
+void coldfire_tick(void)
+{
+	volatile unsigned char	*timerp;
+
+	/* Reset the ColdFire timer */
+	timerp = (volatile unsigned char *) (MCF_MBAR + MCFTIMER_BASE4);
+	timerp[MCFTIMER_TER] = MCFTIMER_TER_CAP | MCFTIMER_TER_REF;
+}
+
+/***************************************************************************/
+
+void coldfire_timer_init(void (*handler)(int, void *, struct pt_regs *))
+{
+	volatile unsigned short	*timerp;
+	volatile unsigned long	*icrp;
+
+	/* Set up TIMER 4 as poll clock */
+	timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE4);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_DISABLE;
+
+	timerp[MCFTIMER_TRR] = (unsigned short) ((MCF_CLK / 16) / HZ);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
+		MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE;
+
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+	*icrp = 0x0000000d; /* TMR4 with priority 5 */
+	request_irq(72, handler, SA_INTERRUPT, "ColdFire Timer", NULL);
+
+#ifdef CONFIG_RESETSWITCH
+	/* This is not really the right place to do this... */
+	reset_setupbutton();
+#endif
+}
+
+/***************************************************************************/
+
+/*
+ *	Program the vector to be an auto-vectored.
+ */
+
+void mcf_autovector(unsigned int vec)
+{
+	/* Everything is auto-vectored on the 5272 */
+}
+
+/***************************************************************************/
+
+extern e_vector	*_ramvec;
+
+void set_evector(int vecnum, void (*handler)(void))
+{
+	if (vecnum >= 0 && vecnum <= 255)
+		_ramvec[vecnum] = handler;
+}
+
+/***************************************************************************/
+
+/* assembler routines */
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void system_call(void);
+asmlinkage void inthandler(void);
+
+void coldfire_trap_init(void)
+{
+	int i;
+
+#ifndef ENABLE_dBUG
+	volatile unsigned long	*icrp;
+
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+	icrp[0] = 0x88888888;
+	icrp[1] = 0x88888888;
+	icrp[2] = 0x88888888;
+	icrp[3] = 0x88888888;
+#endif
+
+	/*
+	 *	There is a common trap handler and common interrupt
+	 *	handler that handle almost every vector. We treat
+	 *	the system call and bus error special, they get their
+	 *	own first level handlers.
+	 */
+#ifndef ENABLE_dBUG
+	for (i = 3; (i <= 23); i++)
+		_ramvec[i] = trap;
+	for (i = 33; (i <= 63); i++)
+		_ramvec[i] = trap;
+#endif
+
+	for (i = 24; (i <= 30); i++)
+		_ramvec[i] = inthandler;
+#ifndef ENABLE_dBUG
+	_ramvec[31] = inthandler;  // Disables the IRQ7 button
+#endif
+
+	for (i = 64; (i < 255); i++)
+		_ramvec[i] = inthandler;
+	_ramvec[255] = 0;
+
+	_ramvec[2] = buserr;
+	_ramvec[32] = system_call;
+}
+
+/***************************************************************************/
+
+void coldfire_reset(void)
+{
+	HARD_RESET_NOW();
+}
+
+/***************************************************************************/
+
+void config_BSP(char *commandp, int size)
+{
+#if 0
+	volatile unsigned long	*pivrp;
+
+	/* Set base of device vectors to be 64 */
+	pivrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_PIVR);
+	*pivrp = 0x40;
+#endif
+
+#if defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \
+    defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3)
+	/* Copy command line from FLASH to local buffer... */
+	memcpy(commandp, (char *) 0xf0004000, size);
+	commandp[size-1] = 0;
+#elif defined(CONFIG_MTD_KeyTechnology)
+	/* Copy command line from FLASH to local buffer... */
+	memcpy(commandp, (char *) 0xffe06000, size);
+	commandp[size-1] = 0;
+#else
+	memset(commandp, 0, size);
+#endif
+
+	mach_sched_init = coldfire_timer_init;
+	mach_tick = coldfire_tick;
+	mach_trap_init = coldfire_trap_init;
+	mach_reset = coldfire_reset;
+}
+
+/***************************************************************************/
+#ifdef CONFIG_RESETSWITCH
+/***************************************************************************/
+
+/*
+ *	Routines to support the NETtel software reset button.
+ */
+void reset_button(int irq, void *dev_id, struct pt_regs *regs)
+{
+	volatile unsigned long	*icrp, *isrp;
+	extern void		flash_eraseconfig(void);
+	static int		inbutton = 0;
+
+	/*
+	 *	IRQ7 is not maskable by the CPU core. It is possible
+	 *	that switch bounce mey get us back here before we have
+	 *	really serviced the interrupt.
+	 */
+	if (inbutton)
+		return;
+	inbutton = 1;
+
+	/* Disable interrupt at SIM - best we can do... */
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+	*icrp = (*icrp & 0x07777777) | 0x80000000;
+
+	/* Try and de-bounce the switch a little... */
+	udelay(10000);
+
+	flash_eraseconfig();
+
+	/* Don't leave here 'till button is no longer pushed! */
+	isrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ISR);
+	for (;;) {
+		if (*isrp & 0x80000000)
+			break;
+	}
+
+	HARD_RESET_NOW();
+	/* Should never get here... */
+
+	inbutton = 0;
+	/* Interrupt service done, acknowledge it */
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+	*icrp = (*icrp & 0x07777777) | 0xf0000000;
+}
+
+/***************************************************************************/
+
+void reset_setupbutton(void)
+{
+	volatile unsigned long	*icrp;
+
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+	*icrp = (*icrp & 0x07777777) | 0xf0000000;
+	request_irq(65, reset_button, (SA_INTERRUPT | IRQ_FLG_FAST),
+		"Reset Button", NULL);
+}
+
+/***************************************************************************/
+#endif /* CONFIG_RESETSWITCH */
+/***************************************************************************/
diff -Nru a/arch/m68knommu/platform/5307/ARNEWSH/crt0_ram.S b/arch/m68knommu/platform/5307/ARNEWSH/crt0_ram.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5307/ARNEWSH/crt0_ram.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,159 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5307 ColdFire Arnewsh board.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ * 	Copyright (C) 2000  Lineo Inc. (www.lineo.com) 
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+#include "asm/nettel.h"
+
+/*****************************************************************************/
+
+/*
+ *	SnapGear/NETtel board memory setup.
+ */
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	MEM_SIZE	0x00800000	/* Memory size 8Mb */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Determine size of RAM, then set up initial stack.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+	/* make region ROM cachable (turn off for flash programming?) */
+	/* 0xff000000 - 0xffffffff */
+#ifdef DEBUGGER_COMPATIBLE_CACHE
+	movl #(0xff<<ACR_BASE_POS)+(0<<ACR_MASK_POS)+ACR_ENABLE+ACR_ANY+ACR_CM_WTHRU+ACR_WPROTECT,%d0
+#else
+	movl #(0xff<<ACR_BASE_POS)+(0<<ACR_MASK_POS)+ACR_ENABLE+ACR_ANY+ACR_CM_WBACK+ACR_WPROTECT,%d0
+#endif
+	movc  %d0,%ACR0
+
+	/* make region RAM cachable *
+	/* 0x00000000 - 0x00ffffffff */
+#ifdef DEBUGGER_COMPATIBLE_CACHE
+	movl #(0x00<<ACR_BASE_POS)+(0<<ACR_MASK_POS)+ACR_ENABLE+ACR_ANY+ACR_CM_WTHRU,%d0
+#else
+	movl #(0x00<<ACR_BASE_POS)+(0<<ACR_MASK_POS)+ACR_ENABLE+ACR_ANY+ACR_CM_WBACK,%d0
+#endif
+	movc  %d0,%ACR1
+
+	/* make the default cache mode precise */
+	movl  #CACR_EC+CACR_ESB+CACR_DCM_OFF_PRE,%d0 /* enable cache */
+	movc  %d0,%CACR
+	nop
+
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+	move.l	8(%a0), %d0			/* Get size of ROMFS */
+	addq.l	#8, %d0				/* Allow for rounding */
+	and.l	#0xfffffffc, %d0		/* Whole words */
+
+	add.l	%d0, %a0			/* Copy from end */
+	add.l	%d0, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+	/*
+	 * load the current task pointer and stack
+	 */
+	lea	init_thread_union, %a0
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -Nru a/arch/m68knommu/platform/5307/ARNEWSH/ram.ld b/arch/m68knommu/platform/5307/ARNEWSH/ram.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5307/ARNEWSH/ram.ld	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,72 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x20000, LENGTH = 0x007E0000
+}
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.exit.text)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+		*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		__init_begin = .;
+		*(.init.text)
+		*(.init.data)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.init.setup)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall1.init)
+		*(.initcall2.init)
+		*(.initcall3.init)
+		*(.initcall4.init)
+		*(.initcall5.init)
+		*(.initcall6.init)
+		*(.initcall7.init)
+		__initcall_end = .;
+		. = ALIGN(4) ;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -Nru a/arch/m68knommu/platform/5307/CLEOPATRA/crt0_ram.S b/arch/m68knommu/platform/5307/CLEOPATRA/crt0_ram.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5307/CLEOPATRA/crt0_ram.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,176 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for Feith CLEOPATRA board.
+ *
+ *	(C) Copyright 2001, Roman Wagner.
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	Feith CLEOPATRA board, chip select and memory setup.
+*/
+
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+#if defined(CONFIG_RAM16MB)
+#define	MEM_SIZE	0x01000000	/* Memory size 16Mb */
+#else
+#define	MEM_SIZE	0x00800000	/* Memory size 8Mb */
+#endif
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Determine size of RAM, then set up initial stack.
+	 */
+/*
+ * The current version of the 5307 processor
+ * SWT does not work. Probing invalid addresses
+ * will hang the system.
+ *
+ * For now, set the memory size to 8 meg
+ */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+
+	/* now fire off the cache, remember to invalidate it first */
+	movl  #0,%d0
+	movc  %d0,%CACR
+	nop
+	movc  %d0,%CACR				/* cache is off */
+
+	movl  #CACR_CINVA,%d0			/* invalidate whole cache */
+	movc  %d0,%CACR
+	nop
+	movc  %d0,%CACR
+	nop                                    
+
+	/* make region ROM cachable (turn off for flash programming?) */
+	/* 0xff000000 - 0xffffffff */
+	movl #(0xff<<ACR_BASE_POS)+(0<<ACR_MASK_POS)+ACR_ENABLE+ACR_ANY+ACR_CM_WBACK+ACR_WPROTECT,%d0
+	movc  %d0,%ACR0
+
+	/* make region RAM cachable *
+	/* 0x00000000 - 0x00ffffffff */
+	movl #(0x00<<ACR_BASE_POS)+(0<<ACR_MASK_POS)+ACR_ENABLE+ACR_ANY+ACR_CM_WBACK,%d0
+	movc  %d0,%ACR1
+
+	/* make the default cache mode precise */
+	movl  #CACR_EC+CACR_ESB+CACR_DCM_OFF_PRE,%d0 /* enable cache */
+	movc  %d0,%CACR
+
+
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+	move.l	8(%a0), %d0			/* Get size of ROMFS */
+	addq.l	#8, %d0				/* Allow for rounding */
+	and.l	#0xfffffffc, %d0		/* Whole words */
+
+	add.l	%d0, %a0			/* Copy from end */
+	add.l	%d0, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+	/*
+	 * load the current task pointer and stack
+	 */
+	lea	init_thread_union, %a0
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -Nru a/arch/m68knommu/platform/5307/CLEOPATRA/ram.ld b/arch/m68knommu/platform/5307/CLEOPATRA/ram.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5307/CLEOPATRA/ram.ld	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,72 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x400, LENGTH = 0x1000000
+}
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.exit.text)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+		*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		__init_begin = .;
+		*(.init.text)
+		*(.init.data)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.init.setup)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall1.init)
+		*(.initcall2.init)
+		*(.initcall3.init)
+		*(.initcall4.init)
+		*(.initcall5.init)
+		*(.initcall6.init)
+		*(.initcall7.init)
+		__initcall_end = . ;
+		. = ALIGN(4);
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -Nru a/arch/m68knommu/platform/5307/MOTOROLA/crt0_ram.S b/arch/m68knommu/platform/5307/MOTOROLA/crt0_ram.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5307/MOTOROLA/crt0_ram.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,159 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5307C3 Cadre-III ColdFire board.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ * 	Copyright (C) 2000  Lineo Inc. (www.lineo.com) 
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+#include "asm/nettel.h"
+
+/*****************************************************************************/
+
+/*
+ *	SnapGear/NETtel board memory setup.
+ */
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	MEM_SIZE	0x00800000	/* Memory size 8Mb */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Determine size of RAM, then set up initial stack.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+	/* make region ROM cachable (turn off for flash programming?) */
+	/* 0xff000000 - 0xffffffff */
+#ifdef DEBUGGER_COMPATIBLE_CACHE
+	movl #(0xff<<ACR_BASE_POS)+(0<<ACR_MASK_POS)+ACR_ENABLE+ACR_ANY+ACR_CM_WTHRU+ACR_WPROTECT,%d0
+#else
+	movl #(0xff<<ACR_BASE_POS)+(0<<ACR_MASK_POS)+ACR_ENABLE+ACR_ANY+ACR_CM_WBACK+ACR_WPROTECT,%d0
+#endif
+	movc  %d0,%ACR0
+
+	/* make region RAM cachable *
+	/* 0x00000000 - 0x00ffffffff */
+#ifdef DEBUGGER_COMPATIBLE_CACHE
+	movl #(0x00<<ACR_BASE_POS)+(0<<ACR_MASK_POS)+ACR_ENABLE+ACR_ANY+ACR_CM_WTHRU,%d0
+#else
+	movl #(0x00<<ACR_BASE_POS)+(0<<ACR_MASK_POS)+ACR_ENABLE+ACR_ANY+ACR_CM_WBACK,%d0
+#endif
+	movc  %d0,%ACR1
+
+	/* make the default cache mode precise */
+	movl  #CACR_EC+CACR_ESB+CACR_DCM_OFF_PRE,%d0 /* enable cache */
+	movc  %d0,%CACR
+	nop
+
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+	move.l	8(%a0), %d0			/* Get size of ROMFS */
+	addq.l	#8, %d0				/* Allow for rounding */
+	and.l	#0xfffffffc, %d0		/* Whole words */
+
+	add.l	%d0, %a0			/* Copy from end */
+	add.l	%d0, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+	/*
+	 * load the current task pointer and stack
+	 */
+	lea	init_thread_union, %a0
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -Nru a/arch/m68knommu/platform/5307/MOTOROLA/ram.ld b/arch/m68knommu/platform/5307/MOTOROLA/ram.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5307/MOTOROLA/ram.ld	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,72 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x20000, LENGTH = 0x007E0000
+}
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.exit.text)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+		*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		__init_begin = .;
+		*(.init.text)
+		*(.init.data)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.init.setup)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall1.init)
+		*(.initcall2.init)
+		*(.initcall3.init)
+		*(.initcall4.init)
+		*(.initcall5.init)
+		*(.initcall6.init)
+		*(.initcall7.init)
+		__initcall_end = .;
+		. = ALIGN(4) ;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -Nru a/arch/m68knommu/platform/5307/MP3/crt0_ram.S b/arch/m68knommu/platform/5307/MP3/crt0_ram.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5307/MP3/crt0_ram.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,173 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5307 ColdFire based MP3.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ * 	Copyright (C) 2000-2001  Lineo Inc. (www.lineo.com) 
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+#include "asm/nettel.h"
+
+/*****************************************************************************/
+
+/*
+ *	SnapGear/NETtel board memory setup.
+ */
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+#if defined(CONFIG_RAM16MB)
+#define	MEM_SIZE	0x01000000	/* Memory size 16Mb */
+#else
+#define	MEM_SIZE	0x00800000	/* Memory size 8Mb */
+#endif
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 *	Disable watchdog timer.
+	 */
+	move.l	#MCF_MBAR, %a0			/* Get MBAR address */
+	clr.l	%d0				/* Disable SWT */
+	move.b	%d0, MCFSIM_SYPCR(%a0)
+	move.b	#0x55, %d0			/* Clear SWT as well */
+	move.b	%d0, MCFSIM_SWSR(%a0)
+	move.b	#0xaa, %d0
+	move.b	%d0, MCFSIM_SWSR(%a0)
+	move.l	#0xffffffff, %d0		/* Mask out all interrupts */
+	move.l	%d0, MCFSIM_IMR(%a0)
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Determine size of RAM, then set up initial stack.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0		/* invalidate whole cache */
+	movec	%d0,%CACR
+	nop
+
+	/* MUST be write-through for DMA to work... */
+	/* This also makes this debugger safe */
+	move.l	#0x0000c000, %d0		/* Set SDRAM cached only */
+	movec	%d0, %ACR0
+	move.l	#0x00000000, %d0		/* No other regions cached */
+	movec	%d0, %ACR1
+
+	/* Enable cache */
+	move.l	#0xa0000200, %d0
+	movec	%d0,%CACR
+	nop
+
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+	move.l	8(%a0), %d0			/* Get size of ROMFS */
+	addq.l	#8, %d0				/* Allow for rounding */
+	and.l	#0xfffffffc, %d0		/* Whole words */
+
+	add.l	%d0, %a0			/* Copy from end */
+	add.l	%d0, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+	/*
+	 * load the current task pointer and stack
+	 */
+	lea	init_thread_union, %a0
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -Nru a/arch/m68knommu/platform/5307/MP3/ram.ld b/arch/m68knommu/platform/5307/MP3/ram.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5307/MP3/ram.ld	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,72 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x400, LENGTH = 0x1000000
+}
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.exit.text)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+		*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		__init_begin = .;
+		*(.init.text)
+		*(.init.data)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.init.setup)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall1.init)
+		*(.initcall2.init)
+		*(.initcall3.init)
+		*(.initcall4.init)
+		*(.initcall5.init)
+		*(.initcall6.init)
+		*(.initcall7.init)
+		__initcall_end = . ;
+		. = ALIGN(4);
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -Nru a/arch/m68knommu/platform/5307/Makefile b/arch/m68knommu/platform/5307/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5307/Makefile	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,27 @@
+#
+# Makefile for the m68knommu kernel.
+#
+
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this,  which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs. You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+ifdef CONFIG_FULLDEBUG
+AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+obj-$(CONFIG_COLDFIRE)	+= entry.o
+obj-$(CONFIG_M5307)	+= config.o
+
+ifeq ($(CONFIG_M5307),y)
+EXTRA_TARGETS := $(BOARD)/crt0_$(MODEL).o
+endif
+
+include $(TOPDIR)/Rules.make
+
diff -Nru a/arch/m68knommu/platform/5307/NETtel/crt0_ram.S b/arch/m68knommu/platform/5307/NETtel/crt0_ram.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5307/NETtel/crt0_ram.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,196 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5307 ColdFire based NETtel.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ * 	Copyright (C) 2000  Lineo Inc. (www.lineo.com) 
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+#include "asm/nettel.h"
+
+/*****************************************************************************/
+
+/*
+ *	SnapGear/NETtel board memory setup.
+ */
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+#if defined(CONFIG_RAM16MB)
+#define	MEM_SIZE	0x01000000	/* Memory size 16Mb */
+#elif defined(CONFIG_RAM8MB)
+#define	MEM_SIZE	0x00800000	/* Memory size 8Mb */
+#else
+#define	MEM_SIZE	0x00400000	/* Memory size 4Mb */
+#endif
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+/*****************************************************************************/
+
+/*
+ *	The NETtel platform has some funky LEDs!
+ */
+.global ppdata
+ppdata:
+.short	0x0000
+
+.global ledbank
+ledbank:
+.byte	0xff
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 *	Set LEDs to known startup state.
+	 */
+	move.l	#NETtel_LEDADDR, %a5		/* Addr of LED bank */
+	move.b	#0xff, (%a5)			/* Turn them all off */
+
+
+	/*
+	 *	Disable watchdog timer.
+	 */
+	move.l	#MCF_MBAR, %a0			/* Get MBAR address */
+	clr.l	%d0				/* Disable SWT */
+	move.b	%d0, MCFSIM_SYPCR(%a0)
+	move.b	#0x55, %d0			/* Clear SWT as well */
+	move.b	%d0, MCFSIM_SWSR(%a0)
+	move.b	#0xaa, %d0
+	move.b	%d0, MCFSIM_SWSR(%a0)
+	move.l	#0xffffffff, %d0		/* Mask out all interrupts */
+	move.l	%d0, MCFSIM_IMR(%a0)
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Determine size of RAM, then set up initial stack.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0		/* invalidate whole cache */
+	movec	%d0,%CACR
+	nop
+#ifdef DEBUGGER_COMPATIBLE_CACHE
+	move.l	#0x0000c000, %d0		/* Set SDRAM cached only */
+#else
+	move.l	#0x0000c020, %d0		/* Set SDRAM cached only (copyback) */
+#endif
+	movec	%d0, %ACR0
+	move.l	#0x00000000, %d0		/* No other regions cached */
+	movec	%d0, %ACR1
+
+	/* Enable cache */
+	move.l	#0xa0000200, %d0
+	movec	%d0,%CACR
+	nop
+
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+	move.l	8(%a0), %d0			/* Get size of ROMFS */
+	addq.l	#8, %d0				/* Allow for rounding */
+	and.l	#0xfffffffc, %d0		/* Whole words */
+
+	add.l	%d0, %a0			/* Copy from end */
+	add.l	%d0, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+	/*
+	 * load the current task pointer and stack
+	 */
+	lea	init_thread_union, %a0
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -Nru a/arch/m68knommu/platform/5307/NETtel/ram.ld b/arch/m68knommu/platform/5307/NETtel/ram.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5307/NETtel/ram.ld	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,72 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x400, LENGTH = 0x400000
+}
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.exit.text)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+		*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		__init_begin = .;
+		*(.init.text)
+		*(.init.data)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.init.setup)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall1.init)
+		*(.initcall2.init)
+		*(.initcall3.init)
+		*(.initcall4.init)
+		*(.initcall5.init)
+		*(.initcall6.init)
+		*(.initcall7.init)
+		__initcall_end = .;
+		. = ALIGN(4) ;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -Nru a/arch/m68knommu/platform/5307/config.c b/arch/m68knommu/platform/5307/config.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5307/config.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,337 @@
+/***************************************************************************/
+
+/*
+ *	linux/arch/m68knommu/platform/5307/config.c
+ *
+ *	Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
+ *	Copyright (C) 2000, Lineo (www.lineo.com)
+ */
+
+/***************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/init.h>
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/coldfire.h>
+#include <asm/mcftimer.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfdma.h>
+#include <asm/delay.h>
+
+#if defined(CONFIG_eLIA)
+#include <asm/elia.h>
+#endif
+
+#include <asm/mcfwdebug.h>
+
+/***************************************************************************/
+
+void	reset_setupbutton(void);
+void	coldfire_profile_init(void);
+
+/***************************************************************************/
+
+/*
+ *	DMA channel base address table.
+ */
+unsigned int   dma_base_addr[MAX_M68K_DMA_CHANNELS] = {
+        MCF_MBAR + MCFDMA_BASE0,
+        MCF_MBAR + MCFDMA_BASE1,
+        MCF_MBAR + MCFDMA_BASE2,
+        MCF_MBAR + MCFDMA_BASE3,
+};
+
+unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+
+/***************************************************************************/
+
+void coldfire_tick(void)
+{
+	volatile unsigned char	*timerp;
+
+	/* Reset the ColdFire timer */
+	timerp = (volatile unsigned char *) (MCF_MBAR + MCFTIMER_BASE1);
+	timerp[MCFTIMER_TER] = MCFTIMER_TER_CAP | MCFTIMER_TER_REF;
+}
+
+/***************************************************************************/
+
+void coldfire_timer_init(void (*handler)(int, void *, struct pt_regs *))
+{
+	volatile unsigned short	*timerp;
+	volatile unsigned char	*icrp;
+
+	/* Set up TIMER 1 as poll clock */
+	timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE1);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_DISABLE;
+
+	timerp[MCFTIMER_TRR] = (unsigned short) ((MCF_CLK / 16) / HZ);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
+		MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE;
+
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_TIMER1ICR);
+
+#if defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \
+		defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3) || \
+		defined(CONFIG_CLEOPATRA) 
+	*icrp = MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3;
+	request_irq(30, handler, SA_INTERRUPT, "ColdFire Timer", NULL);
+#else
+	*icrp = MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL5 | MCFSIM_ICR_PRI3;
+	request_irq(29, handler, SA_INTERRUPT, "ColdFire Timer", NULL);
+#endif
+
+#if defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \
+		defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3)
+	/* This is not really the right place to do this... */
+	reset_setupbutton();
+#endif
+#ifdef CONFIG_HIGHPROFILE
+	coldfire_profile_init();
+#endif
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_TIMER1);
+}
+
+/***************************************************************************/
+#ifdef CONFIG_HIGHPROFILE
+/***************************************************************************/
+
+#define	PROFILEHZ	1013
+
+/*
+ *	Use the other timer to provide high accuracy profiling info.
+ */
+
+void coldfire_profile_tick(int irq, void *dummy, struct pt_regs *regs)
+{
+	volatile unsigned char	*timerp;
+
+	/* Reset the ColdFire timer2 */
+	timerp = (volatile unsigned char *) (MCF_MBAR + MCFTIMER_BASE2);
+	timerp[MCFTIMER_TER] = MCFTIMER_TER_CAP | MCFTIMER_TER_REF;
+
+        if (!user_mode(regs)) {
+                if (prof_buffer && current->pid) {
+                        extern int _stext;
+                        unsigned long ip = instruction_pointer(regs);
+                        ip -= (unsigned long) &_stext;
+                        ip >>= prof_shift;
+                        if (ip < prof_len)
+                                prof_buffer[ip]++;
+                }
+        }
+}
+
+void coldfire_profile_init(void)
+{
+	volatile unsigned short	*timerp;
+	volatile unsigned char	*icrp;
+
+	printk("PROFILE: lodging timer2=%d as profile timer\n", PROFILEHZ);
+
+	/* Set up TIMER 2 as poll clock */
+	timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE2);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_DISABLE;
+
+	timerp[MCFTIMER_TRR] = (unsigned short) ((MCF_CLK / 16) / PROFILEHZ);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
+		MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE;
+
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_TIMER2ICR);
+
+	*icrp = MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3;
+	request_irq(31, coldfire_profile_tick, (SA_INTERRUPT | IRQ_FLG_FAST),
+		"Profile Timer", NULL);
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_TIMER2);
+}
+
+/***************************************************************************/
+#endif	/* CONFIG_HIGHPROFILE */
+/***************************************************************************/
+
+/*
+ *	Program the vector to be an auto-vectored.
+ */
+
+void mcf_autovector(unsigned int vec)
+{
+	volatile unsigned char  *mbar;
+
+	if ((vec >= 25) && (vec <= 31)) {
+		mbar = (volatile unsigned char *) MCF_MBAR;
+		vec = 0x1 << (vec - 24);
+		*(mbar + MCFSIM_AVR) |= vec;
+		mcf_setimr(mcf_getimr() & ~vec);
+	}
+}
+
+/***************************************************************************/
+
+extern e_vector	*_ramvec;
+
+void set_evector(int vecnum, void (*handler)(void))
+{
+	if (vecnum >= 0 && vecnum <= 255)
+		_ramvec[vecnum] = handler;
+}
+
+/***************************************************************************/
+
+/* assembler routines */
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void system_call(void);
+asmlinkage void inthandler(void);
+
+#ifdef TRAP_DBG_INTERRUPT
+asmlinkage void dbginterrupt(void);
+#endif
+
+void __init coldfire_trap_init(void)
+{
+	int i;
+
+#ifndef ENABLE_dBUG
+	mcf_setimr(MCFSIM_IMR_MASKALL);
+#endif
+
+	/*
+	 *	There is a common trap handler and common interrupt
+	 *	handler that handle almost every vector. We treat
+	 *	the system call and bus error special, they get their
+	 *	own first level handlers.
+	 */
+#ifndef ENABLE_dBUG
+	for (i = 3; (i <= 23); i++)
+		_ramvec[i] = trap;
+	for (i = 33; (i <= 63); i++)
+		_ramvec[i] = trap;
+#endif
+#ifdef TRAP_DBG_INTERRUPT
+	_ramvec[12] = dbginterrupt;
+#endif
+
+	for (i = 24; (i <= 30); i++)
+		_ramvec[i] = inthandler;
+#ifndef ENABLE_dBUG
+	_ramvec[31] = inthandler;  // Disables the IRQ7 button
+#endif
+
+	for (i = 64; (i < 255); i++)
+		_ramvec[i] = inthandler;
+	_ramvec[255] = 0;
+
+	_ramvec[2] = buserr;
+	_ramvec[32] = system_call;
+#ifdef MCF_BDM_DISABLE
+	/* Disable the BDM clocking.  This also turns off most of the rest of
+	 * the BDM device.  This is good for EMC reasons.  This option is not
+	 * incompatible with the memory protection option.
+	 */
+	wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK);
+#endif
+
+}
+
+/***************************************************************************/
+
+#if defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \
+	defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3)
+
+/*
+ *	Routines to support the NETtel software reset button.
+ */
+void reset_button(int irq, void *dev_id, struct pt_regs *regs)
+{
+	extern void	flash_eraseconfig(void);
+	static int	inbutton = 0;
+
+	/*
+	 *	IRQ7 is not maskable by the CPU core. It is possible
+	 *	that switch bounce mey get us back here before we have
+	 *	really serviced the interrupt.
+	 */
+	if (inbutton)
+		return;
+	inbutton = 1;
+	/* Disable interrupt at SIM - best we can do... */
+	mcf_setimr(mcf_getimr() | MCFSIM_IMR_EINT7);
+	/* Try and de-bounce the switch a little... */
+	udelay(10000);
+
+	flash_eraseconfig();
+
+	/* Don't leave here 'till button is no longer pushed! */
+	for (;;) {
+		if ((mcf_getipr() & MCFSIM_IMR_EINT7) == 0)
+			break;
+	}
+
+	HARD_RESET_NOW();
+	/* Should never get here... */
+
+	inbutton = 0;
+	/* Interrupt service done, enable it again */
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT7);
+}
+
+/***************************************************************************/
+
+void reset_setupbutton(void)
+{
+	volatile unsigned char	*mbar;
+
+	mbar = (volatile unsigned char *) MCF_MBAR;
+	*(mbar + MCFSIM_AVR) |= MCFSIM_IMR_EINT7;
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT7);
+	request_irq(31, reset_button, (SA_INTERRUPT | IRQ_FLG_FAST),
+		"Reset Button", NULL);
+}
+
+#endif /* CONFIG_NETtel || CONFIG_eLIA || CONFIG_DISKtel || CONFIG_SECUREEDGEMP3 */
+
+/***************************************************************************/
+
+void coldfire_reset(void)
+{
+	HARD_RESET_NOW();
+}
+
+/***************************************************************************/
+
+void config_BSP(char *commandp, int size)
+{
+#if defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \
+    defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3)
+	/* Copy command line from FLASH to local buffer... */
+	memcpy(commandp, (char *) 0xf0004000, size);
+	commandp[size-1] = 0;
+#else
+	memset(commandp, 0, size);
+#endif /* CONFIG_NETtel || CONFIG_eLIA || CONFIG_DISKtel || CONFIG_SECUREEDGEMP3 */
+
+	mach_sched_init = coldfire_timer_init;
+	mach_tick = coldfire_tick;
+	mach_trap_init = coldfire_trap_init;
+	mach_reset = coldfire_reset;
+}
+
+/***************************************************************************/
+#ifdef TRAP_DBG_INTERRUPT
+
+asmlinkage void dbginterrupt_c(struct frame *fp)
+{
+	extern void dump(struct pt_regs *fp);
+	printk("%s(%d): BUS ERROR TRAP\n", __FILE__, __LINE__);
+	dump((struct pt_regs *) fp);
+	asm("halt");
+}
+
+#endif
+/***************************************************************************/
diff -Nru a/arch/m68knommu/platform/5307/entry.S b/arch/m68knommu/platform/5307/entry.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5307/entry.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,557 @@
+/* -*- mode: asm -*-
+ *
+ *  linux/arch/m68knommu/platform/5307/entry.S
+ *
+ *  Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
+ *  Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>,
+ *                      Kenneth Albanowski <kjahds@kjahds.com>,
+ *  Copyright (C) 2000  Lineo Inc. (www.lineo.com) 
+ *
+ * Based on:
+ *
+ *  linux/arch/m68k/kernel/entry.S
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file README.legal in the main directory of this archive
+ * for more details.
+ *
+ * Linux/m68k support by Hamish Macdonald
+ *
+ * 68060 fixes by Jesper Skov
+ * ColdFire support by Greg Ungerer (gerg@snapgear.com)
+ * 5307 fixes by David W. Miller
+ * linux 2.4 support David McCullough <davidm@snapgear.com>
+ */
+
+/*
+ * entry.S  contains the system-call and fault low-level handling routines.
+ * This also contains the timer-interrupt handler, as well as all interrupts
+ * and faults that can result in a task-switch.
+ *
+ * NOTE: This code handles signal-recognition, which happens every time
+ * after a timer-interrupt and after each system call.
+ *
+ * Stack layout in 'ret_from_exception':
+ *
+ *	This allows access to the syscall arguments in registers d1-d5
+ *
+ *	 0(sp) - d1
+ *	 4(sp) - d2
+ *	 8(sp) - d3
+ *	 C(sp) - d4
+ *	10(sp) - d5
+ *	14(sp) - a0
+ *	18(sp) - a1
+ *	1C(sp) - a2
+ *	20(sp) - d0
+ *	24(sp) - orig_d0
+ *	28(sp) - stack adjustment
+ *	2C(sp) - format & vector      }
+ *	2E(sp) - sr                   } different to m68k
+ *	30(sp) - pc                   }
+ */
+
+#include <linux/config.h>
+#include <linux/sys.h>
+#include <linux/linkage.h>
+#include <asm/thread_info.h>
+#include <asm/errno.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/asm-offsets.h>
+
+LENOSYS = 38
+
+/* the following macro is used when enabling interrupts */
+#define ALLOWINT 0xf8ff
+#define	MAX_NOINT_IPL	0
+
+
+LD0		= 0x20
+LORIG_D0	= 0x24
+LFORMATVEC	= 0x2c
+LSR		= 0x2e
+LPC		= 0x30
+
+/*
+ * This defines the normal kernel pt-regs layout.
+ *
+ * regs are a2-a6 and d6-d7 preserved by C code
+ * the kernel doesn't mess with usp unless it needs to
+ *
+ *	This is made a little more tricky on the ColdFire. There is no
+ *	separate kernel and user stack pointers. Need to artificially
+ *	construct a usp in software... When doing this we need to disable
+ *	interrupts, otherwise bad things could happen.
+ */
+#define SAVE_ALL						\
+	move	#0x2700,%sr;		/* disable intrs */	\
+	btst	#5,%sp@(2);		/* from user? */	\
+	bnes	6f;			/* no, skip */		\
+	movel	%sp,sw_usp;		/* save user sp */	\
+	addql	#8,sw_usp;		/* remove exception */	\
+	movel	sw_ksp,%sp;		/* kernel sp */		\
+	subql	#8,%sp;			/* room for exception */\
+	clrl	%sp@-;			/* stk_adj */		\
+	movel	%d0,%sp@-;		/* orig d0 */		\
+	movel	%d0,%sp@-;		/* d0 */		\
+	subl	#32,%sp;		/* space for 8 regs */	\
+	moveml	%d1-%d5/%a0-%a2,%sp@;				\
+	movel	sw_usp,%a0;		/* get usp */		\
+	moveml	%a0@(-8),%d1-%d2;	/* get exception */	\
+	moveml	%d1-%d2,%sp@(LFORMATVEC); /* copy exception */	\
+	bra	7f;						\
+	6:							\
+	clrl	%sp@-;			/* stk_adj */		\
+	movel	%d0,%sp@-;		/* orig d0 */		\
+	movel	%d0,%sp@-;		/* d0 */		\
+	subl	#32,%sp;		/* space for 7 regs */	\
+	moveml	%d1-%d5/%a0-%a2,%sp@;				\
+	7:
+
+#define RESTORE_ALL						\
+	btst	#5,%sp@(LSR);		/* going user? */	\
+	bnes	8f;			/* no, skip */		\
+	move	#0x2700,%sr;		/* disable intrs */	\
+	movel	sw_usp,%a0;		/* get usp */		\
+	moveml	%sp@(LFORMATVEC),%d1-%d2; /* copy exception */	\
+	moveml	%d1-%d2,%a0@(-8);				\
+	moveml	%sp@,%d1-%d5/%a0-%a2;				\
+	addl	#32,%sp;		/* space for 8 regs */	\
+	movel	%sp@+,%d0;					\
+	addql	#4,%sp;			/* orig d0 */		\
+	addl	%sp@+,%sp;		/* stk adj */		\
+	addql	#8,%sp;			/* remove exception */	\
+	movel	%sp,sw_ksp;		/* save ksp */		\
+	subql	#8,sw_usp;		/* set exception */	\
+	movel	sw_usp,%sp;		/* restore usp */	\
+	rte;							\
+	8:							\
+	moveml	%sp@,%d1-%d5/%a0-%a2;				\
+	addl	#32,%sp;		/* space for 8 regs */	\
+	movel	%sp@+,%d0;					\
+	addql	#4,%sp;			/* orig d0 */		\
+	addl	%sp@+,%sp;		/* stk adj */		\
+	rte
+
+/*
+ *	Quick exception save, use current stack only.
+ */
+#define SAVE_LOCAL						\
+	move	#0x2700,%sr;		/* disable intrs */	\
+	clrl	%sp@-;			/* stk_adj */		\
+	movel	%d0,%sp@-;		/* orig d0 */		\
+	movel	%d0,%sp@-;		/* d0 */		\
+	subl	#32,%sp;		/* space for 8 regs */	\
+	moveml	%d1-%d5/%a0-%a2,%sp@;
+
+#define RESTORE_LOCAL						\
+	moveml	%sp@,%d1-%d5/%a0-%a2;				\
+	addl	#32,%sp;		/* space for 8 regs */	\
+	movel	%sp@+,%d0;					\
+	addql	#4,%sp;			/* orig d0 */		\
+	addl	%sp@+,%sp;		/* stk adj */		\
+	rte
+
+
+#define SWITCH_STACK_SIZE (6*4+4)	/* includes return address */
+
+#define SAVE_SWITCH_STACK		\
+	subl    #24,%sp; /* 6 regs */	\
+	moveml	%a3-%a6/%d6-%d7,%sp@
+
+#define RESTORE_SWITCH_STACK		\
+	moveml	%sp@,%a3-%a6/%d6-%d7;	\
+	addl	#24,%sp /* 6 regs */
+
+/*
+ *	Software copy of the user and kernel stack pointers... Ugh...
+ *	Need these to get around ColdFire not having separate kernel
+ *	and user stack pointers.
+ */
+.globl sw_usp
+.globl sw_ksp
+
+.data
+
+sw_ksp:
+.long	0
+
+sw_usp:
+.long	0
+
+.text
+
+
+.globl buserr
+.globl trap
+.globl system_call
+.globl resume, ret_from_exception
+.globl ret_from_signal
+.globl sys_call_table
+.globl sys_fork, sys_clone, sys_vfork
+.globl ret_from_interrupt
+.globl inthandler
+.globl fasthandler
+
+#ifdef TRAP_DBG_INTERRUPT
+.globl dbginterrupt
+#endif
+
+/*--------------------------------------------------------------------------*/
+
+.text
+
+ENTRY(buserr)
+	SAVE_ALL
+	moveq	#-1,%d0
+	movel	%d0,%sp@(LORIG_D0)	| a -1 in the ORIG_D0 field
+					| signifies that the stack frame
+					| is NOT for syscall
+
+	movel	%sp,%sp@- 		| stack frame pointer argument
+	jsr	buserr_c
+	addql	#4,%sp
+	jra	ret_from_exception
+
+
+#ifdef TRAP_DBG_INTERRUPT
+ENTRY(dbginterrupt)
+	SAVE_ALL
+	moveq	#-1,%d0
+	movel	%d0,%sp@(LORIG_D0)	| a -1 in the ORIG_D0 field
+					| signifies that the stack frame
+					| is NOT for syscall
+
+	movel	%sp,%sp@- 		| stack frame pointer argument
+	jsr	dbginterrupt_c
+	addql	#4,%sp
+	jra	ret_from_exception
+#endif
+
+
+ENTRY(reschedule)
+	| save top of frame
+	pea	%sp@
+	jbsr	set_esp0
+	addql	#4,%sp
+
+	pea	ret_from_exception
+	jmp	schedule
+
+	| After a fork we jump here directly from resume,
+	| so that %d1 contains the previous task
+	| Theoretically only needed on SMP, but lets watch
+	| what happens in schedule_tail() in future...
+ENTRY(ret_from_fork)
+#ifdef CONFIG_SMP
+	movel	%d1,%sp@-
+	jsr	schedule_tail
+	addql	#4,%sp
+#endif
+	jra	ret_from_exception
+
+ENTRY(system_call)
+	SAVE_ALL
+	move	#0x2000,%sr;		| enable intrs again
+
+	movel	#-LENOSYS,%d2
+	movel	%d2,LD0(%sp)		| default return value in d0
+					| original D0 is in orig_d0
+	movel	%d0,%d2
+
+	| save top of frame
+	pea	%sp@
+	jbsr	set_esp0
+	addql	#4,%sp
+
+	cmpl	#NR_syscalls,%d2
+	jcc	ret_from_exception
+	lea	sys_call_table,%a0
+	lsll	#2,%d2			| movel	%a0@(%d2:l:4),%d3
+	movel	%a0@(%d2),%d3
+	jeq	ret_from_exception
+	lsrl	#2,%d2
+
+	movel	%sp,%d2			| get thread_info pointer
+	andl	#0xffffe000,%d2		| at start of 8k kernel stack
+	movel	%d2,%a0
+	btst	#TIF_SYSCALL_TRACE,%a0@(TI_FLAGS)
+	bnes	1f
+
+	movel	%d3,%a0
+	jbsr	%a0@
+	movel	%d0,%sp@(LD0)		| save the return value
+	jra	ret_from_exception
+1:
+	subql	#4,%sp
+	SAVE_SWITCH_STACK
+	jbsr	syscall_trace
+	RESTORE_SWITCH_STACK
+	addql	#4,%sp
+	movel	%d3,%a0
+	jbsr	%a0@
+	movel	%d0,%sp@(LD0)		| save the return value
+	subql	#4,%sp			| dummy return address
+	SAVE_SWITCH_STACK
+	jbsr	syscall_trace
+
+ret_from_signal:
+	RESTORE_SWITCH_STACK
+	addql	#4,%sp
+
+ret_from_exception:
+	btst	#5,%sp@(LSR)		| check if returning to kernel
+	jeq	Luser_return		| if so, skip resched, signals
+
+Lkernel_return:
+	moveml  %sp@,%d1-%d5/%a0-%a2
+	addl    #32,%sp			| space for 8 regs
+	movel   %sp@+,%d0
+	addql   #4,%sp			| orig d0
+	addl    %sp@+,%sp		| stk adj
+	rte
+
+Luser_return:
+	movel	%sp,%d1			| get thread_info pointer
+	andl	#0xffffe000,%d1		| at base of 8k kernel stack
+	movel	%d1,%a0
+	movel	%a0@(TI_FLAGS),%d1	| get thread_info->flags
+	andl	#_TIF_WORK_MASK,%d1
+	jne	Lwork_to_do		| still work to do
+
+Lreturn:
+	move    #0x2700,%sr		| disable intrs
+	movel   sw_usp,%a0		| get usp
+	moveml  %sp@(LFORMATVEC),%d1-%d2 | copy exception
+	moveml  %d1-%d2,%a0@(-8)
+	bclr    #5,%a0@(-8)		| clear format byte, bit 5 to make
+					| stack appear modulo 4 which it WILL
+					| be when we do the rte because it was
+					| generated in setup_frame
+	bclr    #4,%a0@(-8)		| clear format byte, bit 4 to make 
+					| stack appear modulo 4 which it WILL
+					| be when we do the rte because it was
+					| generated in setup_frame
+	moveml  %sp@,%d1-%d5/%a0-%a2
+	addl    #32,%sp			| space for 8 regs
+	movel   %sp@+,%d0                  
+	addql   #4,%sp			| orig d0
+	addl    %sp@+,%sp		| stk adj
+	addql   #8,%sp			| remove exception
+	movel   %sp,sw_ksp		| save ksp
+	movel   sw_usp,%sp		| restore usp
+	subql   #8,%sp			| set exception
+	rte
+
+Lwork_to_do:
+	movel	%a0@(TI_FLAGS),%d1	| get thread_info->flags
+	btst	#TIF_NEED_RESCHED,%d1
+	jne	reschedule
+
+	/* GERG: do we need something here for TRACEing?? */
+
+Lsignal_return:
+	subql	#4,%sp			| dummy return address
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	clr	%d1
+	movel	%d1,%sp@-
+	jsr	do_signal
+	addql	#8,%sp
+	RESTORE_SWITCH_STACK
+	addql	#4,%sp
+	jmp	Lreturn
+
+/*--------------------------------------------------------------------------*/
+
+/*
+ *	Common ColdFire trap handler. Most traps come through here first.
+ */
+ENTRY(trap)
+	SAVE_ALL
+	moveq	#-1,%d0
+	movel	%d0,%sp@(LORIG_D0)	| a -1 in the ORIG_D0 field
+					| signifies that the stack frame
+					| is NOT for syscall
+	movel	%sp,%sp@- 		| stack frame pointer argument
+	jsr	trap_c
+	addql	#4,%sp
+	jra	ret_from_exception
+
+/*
+ *	This is the generic interrupt handler (for all hardware interrupt
+ *	sources). It figures out the vector number and calls the appropriate
+ *	interrupt service routine directly.
+ */
+ENTRY(inthandler)
+	SAVE_ALL
+	moveq	#-1,%d0
+	movel	%d0,%sp@(LORIG_D0)	| a -1 in the ORIG_D0 field
+					| signifies that the stack frame
+					| is NOT for syscall
+	addql	#1,local_irq_count
+					| put exception # in d0
+	movew   %sp@(LFORMATVEC),%d0
+	andl	#0x03fc,%d0		| mask out vector only
+
+	movel	mach_kstat_irqs,%a0
+					| get addr of kstat struct
+	addql	#1,%a0@(%d0)		| incr irq intr count
+
+	lsrl	#2,%d0			| calculate real vector #
+	movel	%d0,%d1			| calculate array offset
+	lsll	#4,%d1
+	lea	irq_list,%a0
+	addl	%d1,%a0			| pointer to array struct
+
+	movel	%sp,%sp@-		| push regs arg onto stack
+	movel	%a0@(8),%sp@-		| push devid arg
+	movel	%d0,%sp@- 		| push vector # on stack
+
+	movel	%a0@,%a0		| get function to call
+	jbsr	%a0@			| call vector handler
+	addl	#12,%sp			| pop parameters off stack
+
+	bra	ret_from_interrupt	| this was fallthrough
+
+
+/*
+ *	This is the fast interrupt handler (for certain hardware interrupt
+ *	sources). Unlike the normal interrupt handler it just uses the
+ *	current stack (doesn't care if it is user or kernel). It also
+ *	doesn't bother doing the bottom half handlers.
+ */
+ENTRY(fasthandler)
+	SAVE_LOCAL
+
+	movew   %sp@(LFORMATVEC),%d0
+	andl	#0x03fc,%d0		| mask out vector only
+
+	movel	mach_kstat_irqs,%a0
+					| get addr of kstat struct
+	addql	#1,%a0@(%d0)		| incr irq intr count
+
+	movel	%sp,%sp@-		| push regs arg onto stack
+	clrl	%d1
+	movel	%d1,%sp@- 		| push devid arg
+	lsrl	#2,%d0			| calculate real vector #
+	movel	%d0,%sp@- 		| push vector # on stack
+
+	lsll	#4,%d0			| adjust for array offset
+	lea	irq_list,%a0
+	movel	%a0@(%d0),%a0		| get function to call
+	jbsr	%a0@			| call vector handler
+	addl	#12,%sp			| pop parameters off stack
+
+	RESTORE_LOCAL
+
+/*--------------------------------------------------------------------------*/
+
+ENTRY(ret_from_interrupt)
+	subql	#1,local_irq_count
+	jeq	2f
+1:
+	RESTORE_ALL
+2:
+	moveb	%sp@(LSR),%d0
+	andl	#0x7,%d0
+#if MAX_NOINT_IPL > 0
+	cmpiw	#MAX_NOINT_IPL,%d0
+#endif
+	jhi	1b
+
+	/* check if we need to do software interrupts */
+	movel	irq_stat+CPUSTAT_SOFTIRQ_PENDING,%d0
+	jeq	ret_from_exception
+
+	pea	ret_from_exception
+	jmp	do_softirq
+
+ENTRY(sys_fork)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	m68k_fork
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_vfork)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	m68k_vfork
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_clone)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	m68k_clone
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_sigsuspend)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	do_sigsuspend
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_rt_sigsuspend)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	do_rt_sigsuspend
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_sigreturn)
+	SAVE_SWITCH_STACK
+	jbsr	do_sigreturn
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_rt_sigreturn)
+	SAVE_SWITCH_STACK
+	jbsr	do_rt_sigreturn
+	RESTORE_SWITCH_STACK
+	rts
+
+/*--------------------------------------------------------------------------*/
+
+/*
+ *	Beware - when entering resume, prev (the current task) is
+ *	in a0, next (the new task) is in a1,so don't change these
+ *	registers until their contents are no longer needed.
+ */
+ENTRY(resume)
+
+	movel	%a0, %d1			| get prev thread in d1
+
+	movew	%sr,%d0				| save thread status reg
+	movew	%d0,%a0@(TASK_THREAD+THREAD_SR)
+
+	oril	#0x700,%d0			| disable interrupts
+	move	%d0,%sr
+
+	movel	sw_usp,%d0			| save usp
+	movel	%d0,%a0@(TASK_THREAD+THREAD_USP)
+
+	SAVE_SWITCH_STACK
+	movel	%sp,%a0@(TASK_THREAD+THREAD_KSP) | save kernel stack pointer
+	movel	%a1@(TASK_THREAD+THREAD_KSP),%sp | restore new thread stack
+	RESTORE_SWITCH_STACK
+
+	movel	%a1@(TASK_THREAD+THREAD_USP),%a0 | restore thread user stack
+	movel	%a0, sw_usp
+
+	movew	%a1@(TASK_THREAD+THREAD_SR),%d0	| restore thread status reg
+	movew	%d0, %sr
+	rts
+
+/*--------------------------------------------------------------------------*/
diff -Nru a/arch/m68knommu/platform/5407/CLEOPATRA/crt0_ram.S b/arch/m68knommu/platform/5407/CLEOPATRA/crt0_ram.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5407/CLEOPATRA/crt0_ram.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,173 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for Feith Cleopatra 2 board.
+ *
+ *	(C) Copyright 2001, Roman Wagner.
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	Feith CLEOPATRA board, chip select and memory setup.
+*/
+
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+#define	MEM_SIZE	0x01000000	/* Memory size 16Mb */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+	/*
+	 *	Determine size of RAM, then set up initial stack.
+	 */
+/*
+ * The current version of the 5307 processor
+ * SWT does not work. Probing invalid addresses
+ * will hang the system.
+ *
+ * For now, set the memory size to 8 meg
+ */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01040100, %d0		/* Invalidate whole cache */
+	movec	%d0,%CACR
+	nop
+
+	/* make region ROM cachable (turn off for flash programming?) */
+	/* 0xff000000 - 0xffffffff */
+	move.l #(0xff<<ACR_BASE_POS)+(0<<ACR_MASK_POS)+ACR_ENABLE+ACR_ANY+ACR_CM_CP+ACR_WPROTECT,%d0
+	movec  %d0,%ACR0
+
+	/* make region RAM cachable */
+	/* 0x00000000 - 0x00ffffffff */
+	move.l #(0x00<<ACR_BASE_POS)+(0<<ACR_MASK_POS)+ACR_ENABLE+ACR_ANY+ACR_CM_CP,%d0
+   movec  %d0,%ACR1
+
+	move.l #(0xff<<ACR_BASE_POS)+(0<<ACR_MASK_POS)+ACR_ENABLE+ACR_ANY+ACR_CM_CP+ACR_WPROTECT,%d0
+	movec  %d0,%ACR2
+
+	move.l #(0x00<<ACR_BASE_POS)+(0<<ACR_MASK_POS)+ACR_ENABLE+ACR_ANY+ACR_CM_CP,%d0
+   movec  %d0,%ACR3
+ 
+   /* Enable cache */
+	move.l	#0x86088400, %d0
+	movec	%d0,%CACR
+	nop
+
+
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+	move.l	8(%a0), %d0			/* Get size of ROMFS */
+	addq.l	#8, %d0				/* Allow for rounding */
+	and.l	#0xfffffffc, %d0		/* Whole words */
+
+	add.l	%d0, %a0			/* Copy from end */
+	add.l	%d0, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_thread_union, %a0
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -Nru a/arch/m68knommu/platform/5407/CLEOPATRA/ram.ld b/arch/m68knommu/platform/5407/CLEOPATRA/ram.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5407/CLEOPATRA/ram.ld	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,72 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x400, LENGTH = 0x800000
+}
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.exit.text)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+		*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		__init_begin = .;
+		*(.init.text)
+		*(.init.data)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.init.setup)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall1.init)
+		*(.initcall2.init)
+		*(.initcall3.init)
+		*(.initcall4.init)
+		*(.initcall5.init)
+		*(.initcall6.init)
+		*(.initcall7.init)
+		__initcall_end = . ;
+		. = ALIGN(4);
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -Nru a/arch/m68knommu/platform/5407/MOTOROLA/crt0_ram.S b/arch/m68knommu/platform/5407/MOTOROLA/crt0_ram.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5407/MOTOROLA/crt0_ram.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,152 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for Motorola 5407 eval board.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ *	(C) Copyright 2000, Lineo (www.lineo.com).
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	Board setup info.
+ */
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+#define	MEM_SIZE	0x02000000	/* Memory size 32 */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 *	Setup VBR as per eval board (really dBUG does this).
+	 *	These settings must match it.
+	 */
+	move.l	#VBR_BASE, %a0			/* Note VBR can't be read */
+	movec   %a0, %VBR
+	move.l	%a0, _ramvec			/* Set up vector addr */
+	move.l	%a0, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Determine size of RAM, then set up initial stack.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01040100, %d0		/* Invalidate whole cache */
+	movec	%d0,%CACR
+	nop
+	move.l	#0x000fc000, %d0		/* Set SDRAM cached only */
+	movec	%d0, %ACR0
+	move.l	#0x00000000, %d0		/* No other regions cached */
+	movec	%d0, %ACR1
+	move.l	#0x000fc000, %d0		/* Set SDRAM cached only */
+	movec	%d0, %ACR2
+	move.l	#0x00000000, %d0		/* No other regions cached */
+	movec	%d0, %ACR3
+
+	/* Enable cache */
+	move.l	#0x86088400, %d0
+	movec	%d0,%CACR
+	nop
+
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+	move.l	8(%a0), %d0			/* Get size of ROMFS */
+	addq.l	#8, %d0				/* Allow for rounding */
+	and.l	#0xfffffffc, %d0		/* Whole words */
+
+	add.l	%d0, %a0			/* Copy from end */
+	add.l	%d0, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_thread_union, %a0
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -Nru a/arch/m68knommu/platform/5407/MOTOROLA/ram.ld b/arch/m68knommu/platform/5407/MOTOROLA/ram.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5407/MOTOROLA/ram.ld	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,72 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x20000, LENGTH = 0x007E0000
+}
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.exit.text)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+		*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		__init_begin = .;
+		*(.init.text)
+		*(.init.data)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.init.setup)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall1.init)
+		*(.initcall2.init)
+		*(.initcall3.init)
+		*(.initcall4.init)
+		*(.initcall5.init)
+		*(.initcall6.init)
+		*(.initcall7.init)
+		__initcall_end = .;
+		. = ALIGN(4) ;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -Nru a/arch/m68knommu/platform/5407/Makefile b/arch/m68knommu/platform/5407/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5407/Makefile	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,24 @@
+#
+# Makefile for the m68knommu linux kernel.
+#
+
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this,  which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs. You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+ifdef CONFIG_FULLDEBUG
+AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+obj-y := config.o
+
+EXTRA_TARGETS := $(BOARD)/crt0_$(MODEL).o
+
+include $(TOPDIR)/Rules.make
+
diff -Nru a/arch/m68knommu/platform/5407/config.c b/arch/m68knommu/platform/5407/config.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5407/config.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,236 @@
+/***************************************************************************/
+
+/*
+ *	linux/arch/m68knommu/platform/5407/config.c
+ *
+ *	Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
+ *	Copyright (C) 2000, Lineo (www.lineo.com)
+ */
+
+/***************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/init.h>
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/coldfire.h>
+#include <asm/mcftimer.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfdma.h>
+#include <asm/delay.h>
+
+/***************************************************************************/
+
+void	coldfire_profile_init(void);
+
+/***************************************************************************/
+
+/*
+ *	DMA channel base address table.
+ */
+unsigned int   dma_base_addr[MAX_M68K_DMA_CHANNELS] = {
+        MCF_MBAR + MCFDMA_BASE0,
+        MCF_MBAR + MCFDMA_BASE1,
+        MCF_MBAR + MCFDMA_BASE2,
+        MCF_MBAR + MCFDMA_BASE3,
+};
+
+unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+
+/***************************************************************************/
+
+void coldfire_tick(void)
+{
+	volatile unsigned char	*timerp;
+
+	/* Reset the ColdFire timer */
+	timerp = (volatile unsigned char *) (MCF_MBAR + MCFTIMER_BASE1);
+	timerp[MCFTIMER_TER] = MCFTIMER_TER_CAP | MCFTIMER_TER_REF;
+}
+
+/***************************************************************************/
+
+void coldfire_timer_init(void (*handler)(int, void *, struct pt_regs *))
+{
+	volatile unsigned short	*timerp;
+	volatile unsigned char	*icrp;
+
+	/* Set up TIMER 1 as poll clock */
+	timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE1);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_DISABLE;
+
+	timerp[MCFTIMER_TRR] = (unsigned short) ((MCF_CLK / 16) / HZ);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
+		MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE;
+
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_TIMER1ICR);
+
+#if defined(CONFIG_CLEOPATRA)
+	*icrp = MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3;
+	request_irq(30, handler, SA_INTERRUPT, "ColdFire Timer", NULL);
+#else
+	*icrp = MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL5 | MCFSIM_ICR_PRI3;
+	request_irq(29, handler, SA_INTERRUPT, "ColdFire Timer", NULL);
+#endif
+
+#ifdef CONFIG_HIGHPROFILE
+	coldfire_profile_init();
+#endif
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_TIMER1);
+}
+
+/***************************************************************************/
+#ifdef CONFIG_HIGHPROFILE
+/***************************************************************************/
+
+#define	PROFILEHZ	1013
+
+/*
+ *	Use the other timer to provide high accuracy profiling info.
+ */
+
+void coldfire_profile_tick(int irq, void *dummy, struct pt_regs *regs)
+{
+	volatile unsigned char	*timerp;
+
+	/* Reset the ColdFire timer2 */
+	timerp = (volatile unsigned char *) (MCF_MBAR + MCFTIMER_BASE2);
+	timerp[MCFTIMER_TER] = MCFTIMER_TER_CAP | MCFTIMER_TER_REF;
+
+        if (!user_mode(regs)) {
+                if (prof_buffer && current->pid) {
+                        extern int _stext;
+                        unsigned long ip = instruction_pointer(regs);
+                        ip -= (unsigned long) &_stext;
+                        ip >>= prof_shift;
+                        if (ip < prof_len)
+                                prof_buffer[ip]++;
+                }
+        }
+}
+
+void coldfire_profile_init(void)
+{
+	volatile unsigned short	*timerp;
+	volatile unsigned char	*icrp;
+
+	printk("PROFILE: lodging timer2=%d as profile timer\n", PROFILEHZ);
+
+	/* Set up TIMER 2 as poll clock */
+	timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE2);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_DISABLE;
+
+	timerp[MCFTIMER_TRR] = (unsigned short) ((MCF_CLK / 16) / PROFILEHZ);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
+		MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE;
+
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_TIMER2ICR);
+
+	*icrp = MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3;
+	request_irq(31, coldfire_profile_tick, (SA_INTERRUPT | IRQ_FLG_FAST),
+		"Profile Timer", NULL);
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_TIMER2);
+}
+
+/***************************************************************************/
+#endif	/* CONFIG_HIGHPROFILE */
+/***************************************************************************/
+
+/*
+ *	Program the vector to be an auto-vectored.
+ */
+
+void mcf_autovector(unsigned int vec)
+{
+	volatile unsigned char  *mbar;
+
+	if ((vec >= 25) && (vec <= 31)) {
+		mbar = (volatile unsigned char *) MCF_MBAR;
+		vec = 0x1 << (vec - 24);
+		*(mbar + MCFSIM_AVR) |= vec;
+		mcf_setimr(mcf_getimr() & ~vec);
+	}
+}
+
+/***************************************************************************/
+
+extern e_vector	*_ramvec;
+
+void set_evector(int vecnum, void (*handler)(void))
+{
+	if (vecnum >= 0 && vecnum <= 255)
+		_ramvec[vecnum] = handler;
+}
+
+/***************************************************************************/
+
+/* assembler routines */
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void system_call(void);
+asmlinkage void inthandler(void);
+
+void __init coldfire_trap_init(void)
+{
+	int i;
+
+#ifndef ENABLE_dBUG
+	mcf_setimr(MCFSIM_IMR_MASKALL);
+#endif
+
+	/*
+	 *	There is a common trap handler and common interrupt
+	 *	handler that handle almost every vector. We treat
+	 *	the system call and bus error special, they get their
+	 *	own first level handlers.
+	 */
+#ifndef ENABLE_dBUG
+	for (i = 3; (i <= 23); i++)
+		_ramvec[i] = trap;
+	for (i = 33; (i <= 63); i++)
+		_ramvec[i] = trap;
+#endif
+
+	for (i = 24; (i <= 30); i++)
+		_ramvec[i] = inthandler;
+#ifndef ENABLE_dBUG
+	_ramvec[31] = inthandler;  // Disables the IRQ7 button
+#endif
+
+	for (i = 64; (i < 255); i++)
+		_ramvec[i] = inthandler;
+	_ramvec[255] = 0;
+
+	_ramvec[2] = buserr;
+	_ramvec[32] = system_call;
+}
+
+/***************************************************************************/
+
+void config_BSP(char *commandp, int size)
+{
+	memset(commandp, 0, size);
+
+	mach_sched_init = coldfire_timer_init;
+	mach_tick = coldfire_tick;
+	mach_trap_init = coldfire_trap_init;
+}
+
+/***************************************************************************/
+#ifdef TRAP_DBG_INTERRUPT
+
+asmlinkage void dbginterrupt_c(struct frame *fp)
+{
+	extern void dump(struct pt_regs *fp);
+	printk("%s(%d): BUS ERROR TRAP\n", __FILE__, __LINE__);
+        dump((struct pt_regs *) fp);
+	asm("halt");
+}
+
+#endif
+/***************************************************************************/
diff -Nru a/arch/m68knommu/platform/68328/Makefile b/arch/m68knommu/platform/68328/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68328/Makefile	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,17 @@
+#
+# Makefile for arch/m68knommu/platform/68328.
+#
+
+obj-$(CONFIG_M68328)	+= entry.o ints.o config.o
+obj-$(CONFIG_M68EZ328)	+= entry.o ints.o
+obj-$(CONFIG_M68VZ328)	+= entry.o ints.o
+
+ifeq ($(CONFIG_M68328),y)
+EXTRA_TARGETS := $(BOARD)/bootlogo.rh $(BOARD/crt0_$(MODEL).o
+endif
+
+include $(TOPDIR)/Rules.make
+
+$(obj)/$(BOARD)/bootlogo.rh: $(src)/bootlogo.h
+	perl $(src)/bootlogo.pl < $(src)/bootlogo.h > $(obj)/$(BOARD)/bootlogo.rh
+
diff -Nru a/arch/m68knommu/platform/68328/bootlogo.h b/arch/m68knommu/platform/68328/bootlogo.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68328/bootlogo.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,270 @@
+#define bootlogo_width 160
+#define bootlogo_height 160
+static unsigned char bootlogo_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x40, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x55,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x08, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00,
+  0x00, 0xff, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0xf8, 0x80, 0x0f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x50, 0x04, 0x00, 0x00, 0x00, 0x78, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x03, 0x00, 0x00,
+  0x00, 0x78, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x40,
+  0xa8, 0x02, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x70, 0x28, 0x01, 0x00, 0x00,
+  0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x20, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x70,
+  0x54, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x80, 0x01, 0x3a, 0x78, 0x80, 0x0e,
+  0x50, 0xc0, 0x03, 0x0e, 0x00, 0x20, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00,
+  0x00, 0x3e, 0xf0, 0x83, 0x1f, 0xfc, 0xe0, 0x0f, 0x78, 0xf8, 0x87, 0x1f,
+  0x00, 0x18, 0x00, 0x30, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xf8, 0xc3,
+  0x1f, 0xfc, 0xe0, 0x0f, 0x78, 0xf8, 0x87, 0x0f, 0x00, 0x20, 0x00, 0x10,
+  0x55, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xc0, 0x03, 0x9f, 0xf3, 0x80, 0x0f,
+  0x78, 0x80, 0xc7, 0x0e, 0x00, 0x18, 0x00, 0x20, 0xaa, 0x00, 0x00, 0x00,
+  0x00, 0x1e, 0xe0, 0x03, 0x9f, 0xf1, 0x80, 0x07, 0x78, 0x80, 0x67, 0x00,
+  0x00, 0x24, 0x00, 0x18, 0x55, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x01,
+  0x5e, 0xf0, 0x80, 0x07, 0x3c, 0x00, 0x2f, 0x00, 0x00, 0x14, 0x00, 0x20,
+  0xaa, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x01, 0x7f, 0xf0, 0x80, 0x07,
+  0x3c, 0x00, 0x3f, 0x00, 0x00, 0x08, 0x00, 0x18, 0x55, 0x00, 0x00, 0x00,
+  0x00, 0x0f, 0xe0, 0x00, 0x3f, 0xf0, 0xc0, 0x03, 0x1e, 0x00, 0x1f, 0x00,
+  0x00, 0x14, 0x00, 0x28, 0xaa, 0x00, 0x00, 0x00, 0x80, 0x0f, 0xf0, 0x00,
+  0x1f, 0xf0, 0xc0, 0x03, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x04, 0x00, 0x0c,
+  0x54, 0x00, 0x00, 0x00, 0x80, 0x07, 0x78, 0x00, 0x1f, 0x78, 0xc0, 0x03,
+  0x1f, 0x00, 0x1e, 0x00, 0x00, 0x0a, 0x00, 0x12, 0xa8, 0x00, 0x00, 0x00,
+  0x80, 0x07, 0x78, 0x00, 0x1f, 0x78, 0xe0, 0x03, 0x1f, 0x00, 0x1f, 0x00,
+  0x00, 0x04, 0x00, 0x0a, 0x54, 0x00, 0x00, 0x00, 0x80, 0x07, 0x78, 0x80,
+  0x0f, 0x78, 0xe0, 0x03, 0x1f, 0x00, 0x1e, 0x00, 0x00, 0x0a, 0x00, 0x08,
+  0x50, 0x01, 0x00, 0x00, 0x84, 0x03, 0x78, 0x80, 0x07, 0x3c, 0xe0, 0xc1,
+  0x0f, 0x00, 0x1f, 0x00, 0x00, 0x04, 0x00, 0x06, 0xa8, 0x00, 0x00, 0x00,
+  0xc0, 0x03, 0x78, 0xc0, 0x07, 0x3c, 0xe0, 0xc1, 0x0f, 0x00, 0x1f, 0x00,
+  0x00, 0x0a, 0x00, 0x08, 0x50, 0x01, 0x00, 0x00, 0xc2, 0x01, 0x38, 0xc0,
+  0x07, 0x3c, 0xe0, 0x60, 0x0f, 0x80, 0x1e, 0x00, 0x00, 0x05, 0x00, 0x07,
+  0xa0, 0x00, 0x00, 0x80, 0xe0, 0x01, 0x3c, 0xc0, 0x07, 0x3c, 0xf0, 0xa0,
+  0x07, 0xc0, 0x1c, 0x00, 0x00, 0x0a, 0x80, 0x08, 0xa0, 0x02, 0x00, 0xa0,
+  0xe0, 0x21, 0x1c, 0xc0, 0x03, 0x1c, 0x71, 0x90, 0x47, 0x40, 0x3c, 0x04,
+  0x00, 0x05, 0x80, 0x06, 0xa0, 0x02, 0x00, 0x20, 0xe0, 0x31, 0x1e, 0xc3,
+  0x03, 0x1e, 0x79, 0x98, 0x47, 0x60, 0x38, 0x04, 0x00, 0x15, 0x40, 0x0a,
+  0xa0, 0x0a, 0x00, 0x1a, 0xe0, 0x19, 0x9e, 0xe1, 0x01, 0x9e, 0x78, 0xcc,
+  0xa7, 0x32, 0x78, 0x02, 0x80, 0x2a, 0x40, 0x05, 0x80, 0x2a, 0x00, 0x05,
+  0xe0, 0x0d, 0x9e, 0xe0, 0x01, 0xde, 0x78, 0xc6, 0x97, 0x1b, 0x78, 0x03,
+  0x80, 0x52, 0x30, 0x0a, 0x00, 0x95, 0xd2, 0x0a, 0xe0, 0x0f, 0xfe, 0xe0,
+  0x00, 0x7e, 0xf8, 0x87, 0x9f, 0x0f, 0xf8, 0x01, 0x00, 0xa1, 0x0e, 0x15,
+  0x80, 0x55, 0x55, 0x01, 0xe0, 0x01, 0x3c, 0xf0, 0x00, 0x3c, 0xf0, 0x80,
+  0x8f, 0x0f, 0x70, 0x00, 0x00, 0x81, 0x02, 0x14, 0x00, 0x54, 0x55, 0x00,
+  0xc0, 0x01, 0x3c, 0x00, 0x00, 0x0c, 0x60, 0x00, 0x07, 0x03, 0x70, 0x00,
+  0x80, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x40, 0x01, 0x00, 0x11, 0x09, 0x00, 0x04, 0x00, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+  0x00, 0x20, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x49, 0x32, 0x49, 0x49, 0x91,
+  0x24, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x20, 0x49, 0x0a, 0x09, 0xc9, 0x92, 0x14, 0x81, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x49,
+  0x18, 0x01, 0x49, 0x92, 0x0c, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x49, 0x30, 0x01, 0x49, 0x92,
+  0x14, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x08, 0x69, 0x22, 0x09, 0x49, 0xd2, 0x24, 0x24, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x51,
+  0x1a, 0x09, 0x49, 0xa2, 0x44, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x87, 0x08, 0x00, 0x00, 0x00,
+  0xf2, 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0xf0, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x40, 0x88, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09,
+  0x09, 0x01, 0x10, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x24, 0x80,
+  0x88, 0x86, 0x48, 0x04, 0x09, 0x08, 0x01, 0x01, 0x09, 0x01, 0x10, 0x71,
+  0x88, 0x66, 0x00, 0x00, 0x00, 0x40, 0x24, 0x80, 0x88, 0x89, 0x48, 0x84,
+  0x08, 0x08, 0x01, 0x01, 0x09, 0x01, 0x10, 0x89, 0x88, 0x99, 0x00, 0x00,
+  0x00, 0x40, 0x24, 0x80, 0x88, 0x88, 0x88, 0x82, 0xf8, 0xf0, 0xe0, 0x80,
+  0xf0, 0xf8, 0x13, 0x81, 0x88, 0x88, 0x00, 0x00, 0x00, 0x40, 0x24, 0x80,
+  0x88, 0x88, 0x08, 0x81, 0x08, 0x09, 0x01, 0x41, 0x08, 0x01, 0xf0, 0xf0,
+  0x88, 0x88, 0x00, 0x00, 0x00, 0x40, 0x24, 0x80, 0x88, 0x88, 0x88, 0x42,
+  0x08, 0x09, 0x01, 0x21, 0x08, 0x01, 0x10, 0x88, 0x88, 0x88, 0x00, 0x00,
+  0x00, 0x40, 0x46, 0x88, 0x88, 0x88, 0x4c, 0x44, 0x08, 0x09, 0x09, 0x11,
+  0x08, 0x01, 0x10, 0x88, 0x88, 0x88, 0x00, 0x00, 0x00, 0x80, 0x85, 0x87,
+  0x88, 0x08, 0x4b, 0x24, 0xf0, 0xf0, 0xf0, 0xf8, 0xf1, 0x00, 0x10, 0x70,
+  0x89, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x3f, 0x0f, 0x00, 0x00, 0x08, 0x02, 0x04, 0x00,
+  0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0xff, 0x1f, 0x00, 0x00, 0x48, 0x62, 0xc4, 0x31, 0x4a, 0x18, 0x3c, 0x03,
+  0x21, 0x45, 0x92, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x1f, 0x00, 0x00,
+  0x48, 0x92, 0x24, 0x48, 0xb6, 0x24, 0x88, 0x04, 0x21, 0x4b, 0x92, 0x00,
+  0x00, 0x00, 0x80, 0xff, 0xff, 0x3f, 0x00, 0x00, 0xa8, 0xf2, 0x24, 0x48,
+  0x92, 0x3c, 0x88, 0x04, 0x21, 0x49, 0x62, 0x00, 0x00, 0x00, 0x80, 0xff,
+  0xff, 0x3f, 0x00, 0x00, 0x10, 0x11, 0x24, 0x48, 0x92, 0x04, 0x88, 0x04,
+  0x21, 0x49, 0x62, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x3f, 0x00, 0x00,
+  0x10, 0x11, 0x24, 0x48, 0x92, 0x04, 0x88, 0x04, 0x21, 0x49, 0x93, 0x00,
+  0x00, 0x00, 0x80, 0xff, 0xcf, 0x7e, 0x00, 0x00, 0x10, 0xe1, 0xc4, 0x31,
+  0x92, 0x38, 0x30, 0x03, 0x2f, 0x89, 0x92, 0x00, 0x00, 0x00, 0x80, 0xe3,
+  0x07, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc1, 0x03, 0x7e, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0xc9, 0x23, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x95,
+  0x33, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xdd, 0xfb, 0x7e, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x1d, 0xf8, 0x7e, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x40, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x9b,
+  0x70, 0x7e, 0x00, 0x00, 0x08, 0x00, 0xe0, 0x00, 0x02, 0x00, 0x47, 0x80,
+  0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x80, 0x03, 0x00, 0x7e, 0x00, 0x00,
+  0x3c, 0xa3, 0x20, 0x31, 0x52, 0x02, 0x49, 0xcc, 0x3f, 0xa3, 0x94, 0x08,
+  0x00, 0x00, 0x00, 0x27, 0x02, 0x7e, 0x00, 0x00, 0x88, 0xe4, 0x20, 0x41,
+  0xb2, 0x05, 0x49, 0x90, 0x88, 0xe4, 0x6c, 0x09, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x7e, 0x00, 0x00, 0x88, 0x24, 0xe0, 0x70, 0x92, 0x04, 0x47, 0x9c,
+  0x88, 0x24, 0x24, 0x09, 0x00, 0x00, 0x00, 0x13, 0x48, 0x7e, 0x00, 0x00,
+  0x88, 0x24, 0x20, 0x48, 0x92, 0x04, 0x41, 0x92, 0x88, 0x24, 0x24, 0x01,
+  0x00, 0x00, 0x00, 0x43, 0x00, 0xfe, 0x00, 0x00, 0x88, 0x24, 0x20, 0x48,
+  0x92, 0x04, 0x41, 0x92, 0x88, 0x24, 0x24, 0x09, 0x00, 0x00, 0x00, 0x07,
+  0x94, 0xce, 0x00, 0x00, 0x08, 0x23, 0x20, 0xb0, 0x92, 0x04, 0x41, 0x2c,
+  0x0b, 0x23, 0x24, 0x09, 0x00, 0x00, 0x00, 0x49, 0x02, 0xce, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x11, 0x08, 0xdc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+  0x01, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0xf8, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0x01, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01,
+  0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xf0, 0x1f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x70, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00,
+  0x00, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0xe0, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x3c, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00,
+  0x00, 0xc0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xc0, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x1f, 0x00, 0x00, 0x80, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00,
+  0x00, 0x80, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x00, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00,
+  0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0xfe, 0x0f,
+  0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x08, 0x00,
+  0x00, 0xc0, 0x03, 0x00, 0x78, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0x40, 0x10,
+  0x12, 0x10, 0x05, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00,
+  0x84, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0x20, 0x26, 0x0a, 0x10, 0x9d, 0x39,
+  0xa6, 0xb2, 0x0a, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x02, 0x00, 0xfe, 0x0f,
+  0x00, 0x00, 0x20, 0x21, 0x06, 0x28, 0x25, 0x4a, 0xa9, 0x8a, 0x09, 0x00,
+  0x00, 0xe0, 0x01, 0x22, 0x02, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x20, 0x21,
+  0x0e, 0x38, 0xa5, 0x4b, 0xa9, 0xb2, 0x09, 0x00, 0x00, 0xf0, 0x01, 0x22,
+  0x02, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x20, 0x21, 0x12, 0x44, 0xa5, 0x4a,
+  0x49, 0xa1, 0x0a, 0x00, 0x00, 0xf8, 0x01, 0x22, 0x02, 0x00, 0xfc, 0x1f,
+  0x00, 0x00, 0x20, 0x26, 0x52, 0x44, 0x9d, 0x4d, 0x46, 0x99, 0x0a, 0x00,
+  0x00, 0xfc, 0x01, 0x22, 0x02, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x40, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x01, 0xb2,
+  0x84, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x01, 0x6e, 0x78, 0x00, 0xfc, 0x1f,
+  0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xfc, 0x01, 0x02, 0x00, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x01, 0x02,
+  0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0xfc, 0x0f,
+  0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x20, 0x01, 0x02, 0x00, 0x00, 0x00,
+  0x00, 0x24, 0x06, 0x00, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0x40, 0x10,
+  0x1e, 0x20, 0x90, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00,
+  0x00, 0x80, 0xfc, 0x03, 0x00, 0x00, 0x20, 0x26, 0x22, 0x20, 0xf9, 0x89,
+  0x32, 0xe7, 0x08, 0x00, 0x00, 0x92, 0x38, 0x00, 0x00, 0x00, 0xfc, 0x01,
+  0x00, 0x00, 0x20, 0x21, 0x22, 0xa0, 0x92, 0x88, 0x4a, 0x29, 0x15, 0x00,
+  0x00, 0x00, 0x78, 0x00, 0x00, 0x40, 0xfa, 0x04, 0x00, 0x00, 0x20, 0x21,
+  0x22, 0xa0, 0x93, 0x88, 0x4a, 0x29, 0x1d, 0x00, 0x00, 0x11, 0xf2, 0x00,
+  0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x20, 0x21, 0x22, 0xa8, 0x90, 0x88,
+  0x4a, 0x29, 0x05, 0x00, 0x48, 0x40, 0xf0, 0x01, 0x00, 0x80, 0x14, 0x04,
+  0x00, 0x00, 0x20, 0x26, 0x9e, 0x10, 0x93, 0x78, 0x32, 0x29, 0x19, 0x00,
+  0x00, 0x09, 0xe0, 0x03, 0x00, 0x00, 0x80, 0x10, 0x00, 0x00, 0x40, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xc5, 0x03,
+  0x00, 0x40, 0x22, 0x00, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x40, 0x04, 0xc0, 0x07, 0x00, 0x20, 0x08, 0x04,
+  0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x50, 0x90, 0x03, 0x00, 0xb0, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00,
+  0x00, 0x38, 0x22, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x48, 0x04, 0x44, 0x00, 0x00, 0x3c, 0x08, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x20, 0x00, 0x00, 0x00, 0xbf, 0x40, 0x42, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x24, 0x80, 0x48, 0x02,
+  0xc0, 0x1f, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x05, 0xf0, 0x3f, 0x09, 0x00,
+  0x00, 0x10, 0x24, 0x48, 0x10, 0x12, 0x41, 0x52, 0x24, 0x09, 0x46, 0x71,
+  0x90, 0x20, 0x02, 0xfc, 0xff, 0x1f, 0x80, 0x22, 0x00, 0x90, 0x24, 0x49,
+  0x12, 0x92, 0x40, 0xb2, 0x24, 0x09, 0xc9, 0x49, 0x04, 0x80, 0x90, 0xfc,
+  0xff, 0xbf, 0x24, 0x00, 0x00, 0x90, 0x24, 0x49, 0x12, 0x92, 0x40, 0x92,
+  0x24, 0x06, 0x49, 0x48, 0x50, 0x0a, 0x02, 0xfe, 0xff, 0x3f, 0x00, 0x05,
+  0x00, 0x50, 0xa5, 0x4a, 0x15, 0x92, 0x40, 0x92, 0x24, 0x06, 0x49, 0x48,
+  0x80, 0x40, 0x48, 0xfe, 0xff, 0x3f, 0x49, 0x00, 0x00, 0x20, 0x42, 0x84,
+  0x88, 0x1a, 0x41, 0x92, 0x34, 0x49, 0x49, 0x68, 0x00, 0x38, 0x10, 0x07,
+  0x00, 0x60, 0x80, 0x00, 0x00, 0x20, 0x42, 0x84, 0x88, 0x14, 0x4e, 0x92,
+  0x28, 0x49, 0x46, 0x50, 0x00, 0x80, 0x83, 0x01, 0x00, 0xa0, 0x6a, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+  0x00, 0x00, 0xfc, 0x00, 0x00, 0xc0, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, };
diff -Nru a/arch/m68knommu/platform/68328/bootlogo.pl b/arch/m68knommu/platform/68328/bootlogo.pl
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68328/bootlogo.pl	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,10 @@
+
+$_ = join("", <>);
+
+s/(0x[0-9a-f]{2})/sprintf("0x%.2x",ord(pack("b8",unpack("B8",chr(hex($1))))))/gei;
+
+s/^ /	.byte /gm;
+s/[,};]+$//gm;
+s/^static.*//gm;
+
+print $_;
diff -Nru a/arch/m68knommu/platform/68328/config.c b/arch/m68knommu/platform/68328/config.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68328/config.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,127 @@
+/*
+ *  linux/arch/$(ARCH)/platform/$(PLATFORM)/config.c
+ *
+ *  Copyright (C) 1993 Hamish Macdonald
+ *  Copyright (C) 1999 D. Jeff Dionne
+ *
+ * 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.
+ *
+ * VZ Support/Fixes             Evan Stawnyczy <e@lineo.ca>
+ */
+
+#include <asm/dbg.h>
+#include <stdarg.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <asm/current.h>
+
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+#include <asm/MC68328.h>
+
+
+void BSP_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
+{
+
+#ifdef CONFIG_XCOPILOT_BUGS
+  /*
+   * The only thing I know is that CLK32 is not available on Xcopilot
+   * I have little idea about what frequency SYSCLK has on Xcopilot. 
+   * The values for prescaler and compare registers were simply 
+   * taken from the original source
+   */
+
+  /* Restart mode, Enable int, SYSCLK, Enable timer */
+  TCTL2 = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_SYSCLK | TCTL_TEN;
+  /* Set prescaler */
+  TPRER2 = 2;
+  /* Set compare register */
+  TCMP2 = 0xd7e4;
+#else
+  /* Restart mode, Enable int, 32KHz, Enable timer */
+  TCTL2 = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_32KHZ | TCTL_TEN;
+  /* Set prescaler (Divide 32KHz by 32)*/
+  TPRER2 = 31;
+  /* Set compare register  32Khz / 32 / 10 = 100 */
+  TCMP2 = 10;
+#endif
+                                                                    
+  request_irq(TMR2_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
+}
+
+void BSP_tick(void)
+{
+  /* Reset Timer2 */
+  TSTAT2 &= 0;
+}
+
+unsigned long BSP_gettimeoffset (void)
+{
+  return 0;
+}
+
+void BSP_gettod (int *yearp, int *monp, int *dayp,
+		   int *hourp, int *minp, int *secp)
+{
+}
+
+int BSP_hwclk(int op, struct hwclk_time *t)
+{
+  if (!op) {
+    /* read */
+  } else {
+    /* write */
+  }
+  return 0;
+}
+
+int BSP_set_clock_mmss (unsigned long nowtime)
+{
+#if 0
+  short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
+
+  tod->second1 = real_seconds / 10;
+  tod->second2 = real_seconds % 10;
+  tod->minute1 = real_minutes / 10;
+  tod->minute2 = real_minutes % 10;
+#endif
+  return 0;
+}
+
+void BSP_reset (void)
+{
+  local_irq_disable();
+  asm volatile ("
+    moveal #0x10c00000, %a0;
+    moveb #0, 0xFFFFF300;
+    moveal 0(%a0), %sp;
+    moveal 4(%a0), %a0;
+    jmp (%a0);
+    ");
+}
+
+void config_BSP(char *command, int len)
+{
+  printk("\n68328 support D. Jeff Dionne <jeff@uclinux.org>\n");
+  printk("68328 support Kenneth Albanowski <kjahds@kjshds.com>\n");
+  printk("68328/Pilot support Bernhard Kuhn <kuhn@lpr.e-technik.tu-muenchen.de>\n");
+
+  mach_sched_init      = BSP_sched_init;
+  mach_tick            = BSP_tick;
+  mach_gettimeoffset   = BSP_gettimeoffset;
+  mach_gettod          = BSP_gettod;
+  mach_hwclk           = NULL;
+  mach_set_clock_mmss  = NULL;
+  mach_reset           = BSP_reset;
+
+  config_M68328_irq();
+}
diff -Nru a/arch/m68knommu/platform/68328/entry.S b/arch/m68knommu/platform/68328/entry.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68328/entry.S	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,483 @@
+/* -*- mode: asm -*-
+ *
+ *  linux/arch/m68k/kernel/entry.S
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file README.legal in the main directory of this archive
+ * for more details.
+ *
+ * Linux/m68k support by Hamish Macdonald
+ *
+ */
+
+/*
+ * entry.S  contains the system-call and fault low-level handling routines.
+ * This also contains the timer-interrupt handler, as well as all interrupts
+ * and faults that can result in a task-switch.
+ *
+ * NOTE: This code handles signal-recognition, which happens every time
+ * after a timer-interrupt and after each system call.
+ *
+ */
+
+/*
+ * 12/03/96 Jes: Currently we only support m68k single-cpu systems, so
+ *               all pointers that used to be 'current' are now entry
+ *               number 0 in the 'current_set' list.
+ */
+
+#include <linux/config.h>
+#include <linux/sys.h>
+#include <linux/linkage.h>
+#include <asm/thread_info.h>
+#include <asm/entry.h>
+#include <asm/errno.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/traps.h>
+#include <asm/asm-offsets.h>
+
+#define IMMED #
+#define DBG_PUTC(x)	moveb IMMED x,0xfffff907; \
+			moveb IMMED '\r',0xfffff907; \
+			moveb IMMED '\n',0xfffff907
+
+.globl system_call, buserr, trap
+.globl resume, ret_from_exception
+.globl ret_from_signal
+.globl sys_call_table
+.globl sys_fork, sys_clone, sys_vfork
+.globl ret_from_interrupt, bad_interrupt
+.globl inthandler1, inthandler2, inthandler3, inthandler4
+.globl inthandler5, inthandler6, inthandler7
+
+.text
+ENTRY(buserr)
+	SAVE_ALL_INT
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	buserr_c
+	addql	#4,%sp
+	jra	ret_from_exception
+
+ENTRY(trap)
+	SAVE_ALL_INT
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	trap_c
+	addql	#4,%sp
+	jra	ret_from_exception
+
+ENTRY(reschedule)
+	/* save top of frame*/
+	pea     %sp@
+	jbsr    set_esp0
+	addql   #4,%sp
+
+	pea	ret_from_exception
+	jmp	schedule
+
+	/* After a fork we jump here directly from resume,*/
+	/* so that %d1 contains the previous task*/
+	/* Theoretically only needed on SMP, but let's watch*/
+	/* what happens in schedule_tail() in future...*/
+ENTRY(ret_from_fork)
+#ifdef CONFIG_SMP
+	movel	%d1,%sp@-
+	jsr	schedule_tail
+	addql	#4,%sp
+#endif
+	jra	ret_from_exception
+
+badsys:
+	movel	#-ENOSYS,%sp@(PT_D0)
+	jra	ret_from_exception
+
+do_trace:
+	movel	#-ENOSYS,%sp@(PT_D0)	/* needed for strace*/
+	subql	#4,%sp
+	SAVE_SWITCH_STACK
+	jbsr	syscall_trace
+	RESTORE_SWITCH_STACK
+	addql	#4,%sp
+	movel	%sp@(PT_ORIG_D0),%d1
+	movel	#-ENOSYS,%d0
+	cmpl	#NR_syscalls,%d1
+	jcc	1f
+	lsl	#2,%d1
+	lea	sys_call_table, %a0
+	jbsr	%a0@(%d1)
+
+1:	movel	%d0,%sp@(PT_D0)		/* save the return value*/
+	subql	#4,%sp			/* dummy return address*/
+	SAVE_SWITCH_STACK
+	jbsr	syscall_trace
+
+ret_from_signal:
+	RESTORE_SWITCH_STACK
+	addql	#4,%sp
+	jra	ret_from_exception
+
+ENTRY(system_call)
+	SAVE_ALL_SYS
+
+	GET_CURRENT(%d1)
+	/* save top of frame*/
+	pea     %sp@
+	jbsr    set_esp0
+	addql   #4,%sp
+
+	btst	#PF_TRACESYS_BIT,%a2@(TASK_FLAGS+PF_TRACESYS_OFF)
+	jne	do_trace
+	cmpl	#NR_syscalls,%d0
+	jcc	badsys
+	lsl	#2,%d0
+	lea	sys_call_table,%a0
+	movel	%a0@(%d0), %a0
+	jbsr	%a0@
+	movel	%d0,%sp@(PT_D0)		/* save the return value*/
+
+ret_from_exception:
+	btst	#5,%sp@(PT_SR)		/* check if returning to kernel*/
+	jeq	Luser_return		/* if so, skip resched, signals*/
+
+Lkernel_return:
+	RESTORE_ALL
+
+Luser_return:
+	/* only allow interrupts when we are really the last one on the*/
+	/* kernel stack, otherwise stack overflow can occur during*/
+	/* heavy interupt load*/
+	andw	#ALLOWINT,%sr
+
+	movel	%sp,%d1			/* get thread_info pointer */
+	andl	#0xffffe000,%d1
+	movel	%d1,%a2
+	move	%a2@(TI_FLAGS),%d1	/* thread_info->flags */
+	andl	#_TIF_WORK_MASK,%d1
+	jne	Lwork_to_do
+	RESTORE_ALL
+
+Lwork_to_do:
+	movel	%a2@(TI_FLAGS),%d1	/* thread_info->flags */
+	btst	#TIF_NEED_RESCHED,%d1
+	jne	reschedule
+
+Lsignal_return:
+	subql	#4,%sp			/* dummy return address*/
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	clrl	%sp@-
+	bsrw	do_signal
+	addql	#8,%sp
+	RESTORE_SWITCH_STACK
+	addql	#4,%sp
+Lreturn:
+	RESTORE_ALL
+
+/*
+** This is the main interrupt handler, responsible for calling process_int()
+*/
+inthandler1:
+	SAVE_ALL_INT
+	GET_CURRENT(%d0)
+	addql	#1,local_irq_count	/*  put exception # in d0*/
+/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
+	movew	%sp@(PT_VECTOR), %d0
+	and	#0x3ff, %d0
+
+	movel	%sp,%sp@-
+	movel	#65,%sp@- 		/*  put vector # on stack*/
+	jbsr	process_int		/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+
+inthandler2:
+	SAVE_ALL_INT
+	GET_CURRENT(%d0)
+	addql	#1,local_irq_count	/*  put exception # in d0*/
+/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
+	movew	%sp@(PT_VECTOR), %d0
+	and	#0x3ff, %d0
+
+	movel	%sp,%sp@-
+	movel	#66,%sp@- 		/*  put vector # on stack*/
+	jbsr	process_int		/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+
+inthandler3:
+	SAVE_ALL_INT
+	GET_CURRENT(%d0)
+	addql	#1,local_irq_count	/*  put exception # in d0*/
+/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
+	movew	%sp@(PT_VECTOR), %d0
+	and	#0x3ff, %d0
+
+	movel	%sp,%sp@-
+	movel	#67,%sp@- 		/*  put vector # on stack*/
+	jbsr	process_int		/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+
+inthandler4:
+	SAVE_ALL_INT
+	GET_CURRENT(%d0)
+	addql	#1,local_irq_count	/*  put exception # in d0*/
+/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
+	movew	%sp@(PT_VECTOR), %d0
+	and	#0x3ff, %d0
+
+	movel	%sp,%sp@-
+	movel	#68,%sp@- 		/*  put vector # on stack*/
+	jbsr	process_int		/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+
+inthandler5:
+	SAVE_ALL_INT
+	GET_CURRENT(%d0)
+	addql	#1,local_irq_count	/*  put exception # in d0*/
+/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
+	movew	%sp@(PT_VECTOR), %d0
+	and	#0x3ff, %d0
+
+	movel	%sp,%sp@-
+	movel	#69,%sp@- 		/*  put vector # on stack*/
+	jbsr	process_int		/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+
+inthandler6:
+	SAVE_ALL_INT
+	GET_CURRENT(%d0)
+	addql	#1,local_irq_count	/*  put exception # in d0*/
+/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
+	movew	%sp@(PT_VECTOR), %d0
+	and	#0x3ff, %d0
+
+	movel	%sp,%sp@-
+	movel	#70,%sp@- 		/*  put vector # on stack*/
+	jbsr	process_int		/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+
+inthandler7:
+	SAVE_ALL_INT
+	GET_CURRENT(%d0)
+	addql	#1,local_irq_count	/*  put exception # in d0*/
+/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
+	movew	%sp@(PT_VECTOR), %d0
+	and	#0x3ff, %d0
+
+	movel	%sp,%sp@-
+	movel	#71,%sp@- 		/*  put vector # on stack*/
+	jbsr	process_int		/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+
+inthandler8:
+	SAVE_ALL_INT
+	GET_CURRENT(%d0)
+	addql	#1,local_irq_count	/*  put exception # in d0*/
+/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
+	movew	%sp@(PT_VECTOR), %d0
+	and	#0x3ff, %d0
+
+	movel	%sp,%sp@-
+	movel	#72,%sp@- 		/*  put vector # on stack*/
+	jbsr	process_int		/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+
+timerhandler:
+	SAVE_ALL_INT
+	GET_CURRENT(%d0)
+	addql	#1,local_irq_count	/*  put exception # in d0*/
+/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
+	movew	%sp@(PT_VECTOR), %d0
+	and	#0x3ff, %d0
+
+	movel	%sp,%sp@-
+	movel	#0x40,%sp@- 		/*  put vector # on stack*/
+	jbsr	process_int		/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+
+serialhandler:
+	SAVE_ALL_INT
+	GET_CURRENT(%d0)
+	addql	#1,local_irq_count	/*  put exception # in d0*/
+/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
+	movew	%sp@(PT_VECTOR), %d0
+	and	#0x3ff, %d0
+
+	movel	%sp,%sp@-
+	movel	#0x42,%sp@- 		/*  put vector # on stack*/
+	jbsr	process_int		/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+
+inthandler_wrap:
+	SAVE_ALL_INT
+	GET_CURRENT(%d0)
+	addql	#1,local_irq_count	/*  put exception # in d0*/
+/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
+	movew	%sp@(PT_VECTOR), %d0
+	and	#0x3ff, %d0
+
+	movel	%sp,%sp@-
+	movel	%d0,%sp@- 		/*  put vector # on stack*/
+	jbsr	process_int		/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+
+inthandler:
+	SAVE_ALL_INT
+	GET_CURRENT(%d0)
+	addql	#1,local_irq_count	/*  put exception # in d0*/
+/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
+	movew	%sp@(PT_VECTOR), %d0
+	and	#0x3ff, %d0
+
+	movel	%sp,%sp@-
+	movel	%d0,%sp@- 		/*  put vector # on stack*/
+	jbsr	process_int		/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+
+ret_from_interrupt:
+	subql	#1,local_irq_count
+	jeq	1f
+2:
+	RESTORE_ALL
+1:
+#if 1
+/*	bfextu  %sp@(PT_SR){#5,#3},%d0 */	/* Check for nested interrupt.*/
+	moveb	%sp@(PT_SR), %d0
+	and	#7, %d0
+
+#if MAX_NOINT_IPL > 0
+	cmpiw	#MAX_NOINT_IPL,%d0
+#endif
+	jhi	2b
+#endif
+	/* check if we need to do software interrupts */
+
+	movel	local_irq_count,%d0
+	jeq	ret_from_exception
+
+	pea	ret_from_exception
+	jra	do_softirq
+
+
+/* Handler for uninitialized and spurious interrupts */
+
+bad_interrupt:
+	addql	#1,num_spurious
+	rte
+
+ENTRY(sys_fork)
+	SAVE_SWITCH_STACK	
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	m68k_fork
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_clone)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	m68k_clone
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_vfork)
+	SAVE_SWITCH_STACK	
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	m68k_vfork
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_sigsuspend)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	do_sigsuspend
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_rt_sigsuspend)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	do_rt_sigsuspend
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_sigreturn)
+	SAVE_SWITCH_STACK
+	jbsr	do_sigreturn
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_rt_sigreturn)
+	SAVE_SWITCH_STACK
+	jbsr	do_rt_sigreturn
+	RESTORE_SWITCH_STACK
+	rts
+
+resume:
+	/*
+	 * Beware - when entering resume, prev (the current task) is
+	 * in a0, next (the new task) is in a1,so don't change these
+	 * registers until their contents are no longer needed.
+	 */
+
+	/* save prev thread in d1 */
+	movel	%a0,%d1
+
+	/* save sr */
+	movew	%sr,%a0@(TASK_THREAD+THREAD_SR)
+#ifdef USE_SFC_DFC
+	/* save fs (sfc,%dfc) (may be pointing to kernel memory) */
+	movec	%sfc,%d0
+	movew	%d0,%a0@(TASK_THREAD+THREAD_FS)
+#endif
+
+	/* save non-scratch registers on stack */
+	SAVE_SWITCH_STACK
+
+	/* save usp */
+	/* it is better to use a movel here instead of a movew 8*) */
+	movel	%usp,%a2
+	movel	%a2,%a0@(TASK_THREAD+THREAD_USP)
+
+	/* save current kernel stack pointer */
+	movel	%sp,%a0@(TASK_THREAD+THREAD_KSP)
+
+	/* restore the kernel stack pointer */
+	movel	%a1@(TASK_THREAD+THREAD_KSP),%sp
+
+	/* restore non-scratch registers */
+	RESTORE_SWITCH_STACK
+
+	/* restore user stack pointer */
+	movel	%a1@(TASK_THREAD+THREAD_USP),%a0
+	movel	%a0,%usp
+
+#ifdef USE_SFC_DFC
+	/* restore fs (sfc,%dfc) */
+	movew	%a1@(TASK_THREAD+THREAD_FS),%a0
+	movec	%a0,%sfc
+	movec	%a0,%dfc
+#endif
+	/* restore status register */
+	movew	%a1@(TASK_THREAD+THREAD_SR),%sr
+
+	rts
+
diff -Nru a/arch/m68knommu/platform/68328/ints.c b/arch/m68knommu/platform/68328/ints.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68328/ints.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,354 @@
+/*
+ * linux/arch/m68knommu/platform/68328/ints.c
+ *
+ * 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 1996 Roman Zippel
+ * Copyright 1999 D. Jeff Dionne <jeff@rt-control.com>
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+
+#if defined(CONFIG_M68328)
+#include <asm/MC68328.h>
+#elif defined(CONFIG_M68EZ328)
+#include <asm/MC68EZ328.h>
+#elif defined(CONFIG_M68VZ328)
+#include <asm/MC68VZ328.h>
+#endif
+
+#define INTERNAL_IRQS (32)
+
+/* assembler routines */
+asmlinkage void system_call(void);
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void trap3(void);
+asmlinkage void trap4(void);
+asmlinkage void trap5(void);
+asmlinkage void trap6(void);
+asmlinkage void trap7(void);
+asmlinkage void trap8(void);
+asmlinkage void trap9(void);
+asmlinkage void trap10(void);
+asmlinkage void trap11(void);
+asmlinkage void trap12(void);
+asmlinkage void trap13(void);
+asmlinkage void trap14(void);
+asmlinkage void trap15(void);
+asmlinkage void trap33(void);
+asmlinkage void trap34(void);
+asmlinkage void trap35(void);
+asmlinkage void trap36(void);
+asmlinkage void trap37(void);
+asmlinkage void trap38(void);
+asmlinkage void trap39(void);
+asmlinkage void trap40(void);
+asmlinkage void trap41(void);
+asmlinkage void trap42(void);
+asmlinkage void trap43(void);
+asmlinkage void trap44(void);
+asmlinkage void trap45(void);
+asmlinkage void trap46(void);
+asmlinkage void trap47(void);
+asmlinkage void bad_interrupt(void);
+asmlinkage void inthandler(void);
+asmlinkage void inthandler1(void);
+asmlinkage void inthandler2(void);
+asmlinkage void inthandler3(void);
+asmlinkage void inthandler4(void);
+asmlinkage void inthandler5(void);
+asmlinkage void inthandler6(void);
+asmlinkage void inthandler7(void);
+
+extern e_vector *_ramvec;
+
+/* irq node variables for the 32 (potential) on chip sources */
+static irq_node_t *int_irq_list[INTERNAL_IRQS];
+
+static int int_irq_count[INTERNAL_IRQS];
+static short int_irq_ablecount[INTERNAL_IRQS];
+
+static void int_badint(int irq, void *dev_id, struct pt_regs *fp)
+{
+	num_spurious += 1;
+}
+
+/*
+ * This function should be called during kernel startup to initialize
+ * the amiga IRQ handling routines.
+ */
+void M68328_init_IRQ(void)
+{
+	int i;
+
+	/* set up the vectors */
+
+#ifdef CONFIG_DRAGON2
+	for (i=2; i < 32; ++i)
+                _ramvec[i] = bad_interrupt;
+
+	_ramvec[2] = buserr;
+	_ramvec[3] = trap3;
+	_ramvec[4] = trap4;
+	_ramvec[5] = trap5;
+	_ramvec[6] = trap6;
+	_ramvec[7] = trap7;
+	_ramvec[8] = trap8;
+	_ramvec[9] = trap9;
+	_ramvec[10] = trap10;
+	_ramvec[11] = trap11;
+	_ramvec[12] = trap12;
+	_ramvec[13] = trap13;
+	_ramvec[14] = trap14;
+	_ramvec[15] = trap15;
+#endif
+
+	_ramvec[32] = system_call;
+
+	_ramvec[64] = bad_interrupt;
+	_ramvec[65] = inthandler1;
+	_ramvec[66] = inthandler2;
+	_ramvec[67] = inthandler3;
+	_ramvec[68] = inthandler4;
+	_ramvec[69] = inthandler5;
+	_ramvec[70] = inthandler6;
+	_ramvec[71] = inthandler7;
+ 
+	IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */
+
+	/* initialize handlers */
+	for (i = 0; i < INTERNAL_IRQS; i++) {
+		int_irq_list[i] = NULL;
+
+		int_irq_ablecount[i] = 0;
+		int_irq_count[i] = 0;
+	}
+
+	/* turn off all interrupts */
+	IMR = ~0;
+}
+
+void M68328_insert_irq(irq_node_t **list, irq_node_t *node)
+{
+	unsigned long flags;
+	irq_node_t *cur;
+
+	if (!node->dev_id)
+		printk("%s: Warning: dev_id of %s is zero\n",
+		       __FUNCTION__, node->devname);
+
+	local_irq_save(flags);
+
+	cur = *list;
+	while (cur) {
+		list = &cur->next;
+		cur = cur->next;
+	}
+
+	node->next = cur;
+	*list = node;
+
+	local_irq_restore(flags);
+}
+
+void M68328_delete_irq(irq_node_t **list, void *dev_id)
+{
+	unsigned long flags;
+	irq_node_t *node;
+
+	local_irq_save(flags);
+
+	for (node = *list; node; list = &node->next, node = *list) {
+		if (node->dev_id == dev_id) {
+			*list = node->next;
+			/* Mark it as free. */
+			node->handler = NULL;
+			local_irq_restore(flags);
+			return;
+		}
+	}
+	local_irq_restore(flags);
+	printk("%s: tried to remove invalid irq\n", __FUNCTION__);
+}
+
+int M68328_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+                         unsigned long flags, const char *devname, void *dev_id)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk ("%s: Unknown IRQ %d from %s\n", __FUNCTION__, irq, devname);
+		return -ENXIO;
+	}
+
+	if (!int_irq_list[irq]) {
+		int_irq_list[irq] = new_irq_node();
+		int_irq_list[irq]->flags   = IRQ_FLG_STD;
+	}
+
+	if (!(int_irq_list[irq]->flags & IRQ_FLG_STD)) {
+		if (int_irq_list[irq]->flags & IRQ_FLG_LOCK) {
+			printk("%s: IRQ %d from %s is not replaceable\n",
+			       __FUNCTION__, irq, int_irq_list[irq]->devname);
+			return -EBUSY;
+		}
+		if (flags & IRQ_FLG_REPLACE) {
+			printk("%s: %s can't replace IRQ %d from %s\n",
+			       __FUNCTION__, devname, irq, int_irq_list[irq]->devname);
+			return -EBUSY;
+		}
+	}
+	int_irq_list[irq]->handler = handler;
+	int_irq_list[irq]->flags   = flags;
+	int_irq_list[irq]->dev_id  = dev_id;
+	int_irq_list[irq]->devname = devname;
+
+	/* enable in the IMR */
+	if (!int_irq_ablecount[irq])
+		IMR &= ~(1<<irq);
+
+	return 0;
+}
+
+void M68328_free_irq(unsigned int irq, void *dev_id)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk ("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (int_irq_list[irq]->dev_id != dev_id)
+		printk("%s: removing probably wrong IRQ %d from %s\n",
+		       __FUNCTION__, irq, int_irq_list[irq]->devname);
+	int_irq_list[irq]->handler = int_badint;
+	int_irq_list[irq]->flags   = IRQ_FLG_STD;
+	int_irq_list[irq]->dev_id  = NULL;
+	int_irq_list[irq]->devname = NULL;
+
+	IMR |= 1<<irq;
+}
+
+/*
+ * Enable/disable a particular machine specific interrupt source.
+ * Note that this may affect other interrupts in case of a shared interrupt.
+ * This function should only be called for a _very_ short time to change some
+ * internal data, that may not be changed by the interrupt at the same time.
+ * int_(enable|disable)_irq calls may also be nested.
+ */
+void M68328_enable_irq(unsigned int irq)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (--int_irq_ablecount[irq])
+		return;
+
+	/* enable the interrupt */
+	IMR &= ~(1<<irq);
+}
+
+void M68328_disable_irq(unsigned int irq)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (int_irq_ablecount[irq]++)
+		return;
+
+	/* disable the interrupt */
+	IMR |= 1<<irq;
+}
+
+/* The 68k family did not have a good way to determine the source
+ * of interrupts until later in the family.  The EC000 core does
+ * not provide the vector number on the stack, we vector everything
+ * into one vector and look in the blasted mask register...
+ * This code is designed to be fast, almost constant time, not clean!
+ */
+void M68328_do_irq(int vec, struct pt_regs *fp)
+{
+	int irq;
+	int mask;
+
+	unsigned long pend = ISR;
+
+	while (pend) {
+		if (pend & 0x0000ffff) {
+			if (pend & 0x000000ff) {
+				if (pend & 0x0000000f) {
+					mask = 0x00000001;
+					irq = 0;
+				} else {
+					mask = 0x00000010;
+					irq = 4;
+				}
+			} else {
+				if (pend & 0x00000f00) {
+					mask = 0x00000100;
+					irq = 8;
+				} else {
+					mask = 0x00001000;
+					irq = 12;
+				}
+			}
+		} else {
+			if (pend & 0x00ff0000) {
+				if (pend & 0x000f0000) {
+					mask = 0x00010000;
+					irq = 16;
+				} else {
+					mask = 0x00100000;
+					irq = 20;
+				}
+			} else {
+				if (pend & 0x0f000000) {
+					mask = 0x01000000;
+					irq = 24;
+				} else {
+					mask = 0x10000000;
+					irq = 28;
+				}
+			}
+		}
+
+		while (! (mask & pend)) {
+			mask <<=1;
+			irq++;
+		}
+
+		if (int_irq_list[irq] && int_irq_list[irq]->handler) {
+			int_irq_list[irq]->handler(irq, int_irq_list[irq]->dev_id, fp);
+			int_irq_count[irq]++;
+		} else {
+			printk("unregistered interrupt %d!\nTurning it off in the IMR...\n", irq);
+			IMR |= mask;
+		}
+		pend &= ~mask;
+	}
+}
+
+void config_M68328_irq(void)
+{
+	mach_default_handler = NULL;
+	mach_init_IRQ        = M68328_init_IRQ;
+	mach_request_irq     = M68328_request_irq;
+	mach_free_irq        = M68328_free_irq;
+	mach_enable_irq      = M68328_enable_irq;
+	mach_disable_irq     = M68328_disable_irq;
+	mach_process_int     = M68328_do_irq;
+}
diff -Nru a/arch/m68knommu/platform/68328/pilot/crt0_rom.S b/arch/m68knommu/platform/68328/pilot/crt0_rom.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68328/pilot/crt0_rom.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,228 @@
+/* linux/arch/m68knommu/kernel/head.S:  A startup file for the MC68332 
+ *
+ * Copyright (C) 1998  D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>,
+ *                     Kenneth Albanowski <kjahds@kjahds.com>,
+ *                     The Silver Hammer Group, Ltd.
+ *
+ * (c) 1995, Dionne & Associates
+ * (c) 1995, DKG Display Tech.
+ */
+
+#define ASSEMBLY
+
+#define IMMED #
+#define	DBG_PUTC(x)	moveb IMMED x, 0xfffff907
+
+#include <linux/config.h>
+
+.global _stext
+.global __bss_start
+
+.global _start
+
+.global _rambase
+.global __ramvec
+.global _ramvec
+.global _ramstart
+.global _ramend
+
+.global penguin_bits
+
+#ifdef CONFIG_PILOT
+
+#define IMR 0xFFFFF304
+
+	.data
+	.align 16
+
+penguin_bits:	
+#include "bootlogo.rh"
+
+#endif
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *      Set up the usable of RAM stuff. Size of RAM is determined then
+ *      an initial stack set up at the end.
+ */
+.align 4
+_ramvec:
+.long   0
+_rambase:
+.long   0
+_ramstart:
+.long   0
+_ramend:
+.long   0
+
+.text
+	
+_start:
+_stext:
+
+
+#ifdef CONFIG_M68328
+
+#ifdef CONFIG_PILOT
+	.byte 0x4e, 0xfa, 0x00, 0x0a /* Jmp +X bytes */
+	.byte 'b', 'o', 'o', 't'
+	.word 10000
+
+	nop
+#endif
+
+	moveq	#0, %d0
+	movew   %d0, 0xfffff618 /* Watchdog off */
+	movel	#0x00011f07, 0xfffff114 /* CS A1 Mask */
+
+	movew	#0x0800, 0xfffff906 /* Ignore CTS */
+	movew	#0x010b, 0xfffff902 /* BAUD to 9600 */
+
+	movew	#0x2410,	0xfffff200 /* PLLCR */
+	movew	#0x123,	0xfffff202 /* PLLFSR */
+
+#ifdef CONFIG_PILOT
+	moveb	#0,      0xfffffA27 /* LCKCON */
+	movel   #_start, 0xfffffA00 /* LSSA */
+	moveb   #0xa,    0xfffffA05 /* LVPW */
+	movew	#0x9f,   0xFFFFFa08 /* LXMAX */
+	movew	#0x9f,   0xFFFFFa0a /* LYMAX */
+	moveb   #9,      0xfffffa29 /* LBAR */
+	moveb   #0,      0xfffffa25 /* LPXCD */
+	moveb	#0x04,   0xFFFFFa20 /* LPICF */
+	moveb	#0x58,   0xfffffA27 /* LCKCON */
+	moveb	#0x85,	0xfffff429 /* PFDATA */
+	moveb	#0xd8,   0xfffffA27 /* LCKCON */
+	moveb	#0xc5,	0xfffff429 /* PFDATA */
+	moveb	#0xd5,	0xfffff429 /* PFDATA */
+
+	moveal	#0x00100000, %a3
+	moveal	#0x100ffc00, %a4
+
+#endif /* CONFIG_PILOT */
+
+
+#endif /* CONFIG_M68328 */
+
+	movew   #0x2700, %sr
+	lea	%a4@(-4), %sp
+
+	DBG_PUTC('\r')
+	DBG_PUTC('\n')
+	DBG_PUTC('A')
+
+   	moveq   #0,%d0
+	movew	#16384, %d0  /* PLL settle wait loop */
+L0:
+	subw	#1, %d0
+	bne	L0
+
+	DBG_PUTC('B')
+
+	/* Copy command line from beginning of RAM (+16) to end of bss */
+	movel	#__ramvec, %d7
+	addl	#16, %d7
+	moveal	%d7, %a0
+	moveal	#end, %a1
+	lea	%a1@(512), %a2
+
+	DBG_PUTC('C')
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+L2:
+	movel	%a0@+, %d0
+	movel	%d0, %a1@+
+	cmpal	%a1, %a2
+	bhi	L2
+
+	/* Copy data segment from ROM to RAM */
+	moveal	#__data_rom_start, %a0
+	moveal	#__data_start, %a1
+	moveal	#__data_end, %a2
+
+	DBG_PUTC('D')
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+LD1:
+	movel	%a0@+, %d0
+	movel	%d0, %a1@+
+	cmpal	%a1, %a2
+	bhi	LD1
+
+	DBG_PUTC('E')
+
+	moveal	#__bss_start, %a0
+	moveal	#end, %a1
+
+	/* Copy 0 to %a0 until %a0 == %a1 */
+L1:
+	movel	#0, %a0@+
+	cmpal	%a0, %a1
+	bhi	L1
+
+	DBG_PUTC('F')
+
+	/* Copy command line from end of bss to command line */
+	moveal	#end, %a0
+	moveal	#command_line, %a1
+	lea	%a1@(512), %a2
+
+	DBG_PUTC('G')
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+L3:
+	movel	%a0@+, %d0
+	movel	%d0, %a1@+
+	cmpal	%a1, %a2
+	bhi	L3
+
+	movel	#_sdata, %d0	
+	movel	%d0,	_rambase	
+	movel	#end,	%d0
+	movel	%d0,	_ramstart
+
+	movel	%a4,	%d0
+	subl	#4096,	%d0	/* Reserve 4K of stack */
+	moveq	#79, %d7
+	movel	%d0,	_ramend
+
+	movel	%a3,	%d0
+	movel	%d0,	rom_length
+
+	pea	0
+	pea	env
+	pea	%sp@(4)
+	pea	0
+
+	DBG_PUTC('H')
+
+#ifdef CONFIG_PILOT
+	
+	movel	#penguin_bits,	0xFFFFFA00
+	moveb	#10,		0xFFFFFA05
+	movew	#160,		0xFFFFFA08
+	movew	#160,		0xFFFFFA0A
+
+#endif /* CONFIG_PILOT */
+
+	DBG_PUTC('I')
+
+	lea	init_thread_union, %a0
+	lea	0x2000(%a0), %sp
+
+	DBG_PUTC('J')
+	DBG_PUTC('\r')
+	DBG_PUTC('\n')
+
+	jsr	start_kernel
+_exit:
+
+	jmp	_exit
+
+
+	.data
+env:
+	.long	0
diff -Nru a/arch/m68knommu/platform/68328/pilot/rom.ld b/arch/m68knommu/platform/68328/pilot/rom.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68328/pilot/rom.ld	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,105 @@
+OUTPUT_ARCH(m68k)
+ENTRY(_start)
+MEMORY {
+	romvec : ORIGIN = 0x10c00000, LENGTH = 0x10400
+	flash  : ORIGIN = 0x10c10400, LENGTH = 0xfec00
+	eflash : ORIGIN = 0x10d00000, LENGTH = 4
+	ramvec : ORIGIN = 0x00000000, LENGTH = 0x400
+	ram    : ORIGIN = 0x10000400, LENGTH = 0x100000-0x400
+	eram   : ORIGIN = 0x10100000, LENGTH = 4
+}
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS {
+  . = 0x10c00000 ;
+  .romvec : {
+	  _flashstart = . ;
+	  _romvec = . ;
+	} > romvec
+
+  . = 0x10c10400 ;
+  .text : {
+	  _text = .;                    /* Text and read-only data */
+	  text_start = . ;
+          *(.text)
+          *(.text.*)
+          *(.rodata)
+          *(.fixup)		
+          *(__ex_table)	
+	  . = ALIGN(4) ;
+	  _etext = . ;
+	  __data_rom_start = . ;
+	} > flash
+  
+  . = 0x10d00000 ;
+  .eflash :
+        {
+          _flashend = . ;
+        } > eflash
+	
+  . = 0 ;
+  .ramvec :
+	{
+	  __ramvec = . ;
+	} > ramvec
+	
+  /* . = 0x10000400 ; */
+  .data 0x10000400 :
+	{
+	  _sdata = . ;
+	  __data_start = . ;
+
+	  . = ALIGN(0x2000) ;
+	  *(.data.init_task)
+	  . = ALIGN(0x2000) ;
+
+      *(.data)
+      *(.data.*)	
+      *(.setup.init)		
+      *(.exitcall.exit)		
+	
+	  . = ALIGN(4096) ;
+	  __init_begin = .;
+	  *(.init.text)
+	  *(.init.data)
+	  . = ALIGN(16);
+	  __setup_start = .;
+	  *(.init.setup)
+	  __setup_end = .;
+	  __initcall_start = .;
+	  *(.initcall1.init)
+	  *(.initcall2.init)
+	  *(.initcall3.init)
+	  *(.initcall4.init)
+	  *(.initcall5.init)
+	  *(.initcall6.init)
+	  *(.initcall7.init)
+	  __initcall_end = .;
+	  . = ALIGN(4) ;
+	  __init_end = .;
+
+	  _edata = . ;
+	  edata = . ;
+	} > ram
+
+  .bss :
+    {
+	  . = ALIGN(16) ;
+	  _sbss = . ;
+	  __bss_start = . ;
+	  __data_end = . ;
+	  *(.bss)
+	  *(COMMON)
+	  . = ALIGN(16) ;
+	  end = . ;
+	  _ebss = . ;	  
+	  _end = . ;
+    } > ram
+
+  . = 0x10100000 ;
+  .eram :
+	{
+  	  __ramend = . ;
+	} > eram
+}
diff -Nru a/arch/m68knommu/platform/68360/Makefile b/arch/m68knommu/platform/68360/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68360/Makefile	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,10 @@
+#
+# Makefile for arch/m68knommu/platform/68360.
+#
+
+obj-y := config.o commproc.o entry.o ints.o
+
+EXTRA_TARGETS := $(BOARD)/crt0_$(MODEL).o
+
+include $(TOPDIR)/Rules.make
+
diff -Nru a/arch/m68knommu/platform/68360/commproc.c b/arch/m68knommu/platform/68360/commproc.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68360/commproc.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,308 @@
+/*
+ * General Purpose functions for the global management of the
+ * Communication Processor Module.
+ *
+ * Copyright (c) 2000 Michael Leslie <mleslie@lineo.com>
+ * Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
+ *
+ * In addition to the individual control of the communication
+ * channels, there are a few functions that globally affect the
+ * communication processor.
+ *
+ * Buffer descriptors must be allocated from the dual ported memory
+ * space.  The allocator for that is here.  When the communication
+ * process is reset, we reclaim the memory available.  There is
+ * currently no deallocator for this memory.
+ * The amount of space available is platform dependent.  On the
+ * MBX, the EPPC software loads additional microcode into the
+ * communication processor, and uses some of the DP ram for this
+ * purpose.  Current, the first 512 bytes and the last 256 bytes of
+ * memory are used.  Right now I am conservative and only use the
+ * memory that can never be used for microcode.  If there are
+ * applications that require more DP ram, we can expand the boundaries
+ * but then we have to be careful of any downloaded microcode.
+ *
+ */
+
+/*
+ * Michael Leslie <mleslie@lineo.com>
+ * adapted Dan Malek's ppc8xx drivers to M68360
+ *
+ */
+
+#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/interrupt.h>
+#include <asm/irq.h>
+#include <asm/m68360.h>
+#include <asm/commproc.h>
+
+/* #include <asm/page.h> */
+/* #include <asm/pgtable.h> */
+extern void *_quicc_base;
+extern unsigned int system_clock;
+
+
+static uint dp_alloc_base;	/* Starting offset in DP ram */
+static uint dp_alloc_top;	/* Max offset + 1 */
+
+#if 0
+static	void	*host_buffer;	/* One page of host buffer */
+static	void	*host_end;	    /* end + 1 */
+#endif
+
+/* struct  cpm360_t *cpmp; */         /* Pointer to comm processor space */
+
+QUICC  *pquicc;
+/* QUICC  *quicc_dpram; */ /* mleslie - temporary; use extern pquicc elsewhere instead */
+
+
+/* CPM interrupt vector functions. */
+struct	cpm_action {
+	void	(*handler)(void *);
+	void	*dev_id;
+};
+static	struct	cpm_action cpm_vecs[CPMVEC_NR];
+static	void	cpm_interrupt(int irq, void * dev, struct pt_regs * regs);
+static	void	cpm_error_interrupt(void *);
+
+/* prototypes: */
+void cpm_install_handler(int vec, void (*handler)(void *), void *dev_id);
+void m360_cpm_reset(void);
+
+
+
+
+void m360_cpm_reset()
+{
+/* 	pte_t		   *pte; */
+
+	pquicc = (struct quicc *)(_quicc_base); /* initialized in crt0_rXm.S */
+
+	/* Perform a CPM reset. */
+	pquicc->cp_cr = (SOFTWARE_RESET | CMD_FLAG);
+
+	/* Wait for CPM to become ready (should be 2 clocks). */
+	while (pquicc->cp_cr & CMD_FLAG);
+
+	/* On the recommendation of the 68360 manual, p. 7-60
+	 * - Set sdma interupt service mask to 7
+	 * - Set sdma arbitration ID to 4
+	 */
+	pquicc->sdma_sdcr = 0x0740;
+
+
+	/* Claim the DP memory for our use.
+	 */
+	dp_alloc_base = CPM_DATAONLY_BASE;
+	dp_alloc_top = dp_alloc_base + CPM_DATAONLY_SIZE;
+
+
+	/* Set the host page for allocation.
+	 */
+	/* 	host_buffer = host_page_addr; */
+	/* 	host_end = host_page_addr + PAGE_SIZE; */
+
+	/* 	pte = find_pte(&init_mm, host_page_addr); */
+	/* 	pte_val(*pte) |= _PAGE_NO_CACHE; */
+	/* 	flush_tlb_page(current->mm->mmap, host_buffer); */
+	
+	/* Tell everyone where the comm processor resides.
+	*/
+/* 	cpmp = (cpm360_t *)commproc; */
+}
+
+
+/* This is called during init_IRQ.  We used to do it above, but this
+ * was too early since init_IRQ was not yet called.
+ */
+void
+cpm_interrupt_init(void)
+{
+	/* Initialize the CPM interrupt controller.
+	 * NOTE THAT pquicc had better have been initialized!
+	 * reference: MC68360UM p. 7-377
+	 */
+	pquicc->intr_cicr =
+		(CICR_SCD_SCC4 | CICR_SCC_SCC3 | CICR_SCB_SCC2 | CICR_SCA_SCC1) |
+		(CPM_INTERRUPT << 13) |
+		CICR_HP_MASK |
+		(CPM_VECTOR_BASE << 5) |
+		CICR_SPS;
+
+	/* mask all CPM interrupts from reaching the cpu32 core: */
+	pquicc->intr_cimr = 0;
+
+
+	/* mles - If I understand correctly, the 360 just pops over to the CPM
+	 * specific vector, obviating the necessity to vector through the IRQ
+	 * whose priority the CPM is set to. This needs a closer look, though.
+	 */
+
+	/* Set our interrupt handler with the core CPU. */
+/* 	if (request_irq(CPM_INTERRUPT, cpm_interrupt, 0, "cpm", NULL) != 0) */
+/* 		panic("Could not allocate CPM IRQ!"); */
+
+	/* Install our own error handler.
+	 */
+	/* I think we want to hold off on this one for the moment - mles */
+	/* cpm_install_handler(CPMVEC_ERROR, cpm_error_interrupt, NULL); */
+
+	/* master CPM interrupt enable */
+	/* pquicc->intr_cicr |= CICR_IEN; */ /* no such animal for 360 */
+}
+
+
+
+/* CPM interrupt controller interrupt.
+*/
+static	void
+cpm_interrupt(int irq, void * dev, struct pt_regs * regs)
+{
+	/* uint	vec; */
+
+	/* mles: Note that this stuff is currently being performed by
+	 * M68360_do_irq(int vec, struct pt_regs *fp), in ../ints.c  */
+
+	/* figure out the vector */
+	/* call that vector's handler */
+	/* clear the irq's bit in the service register */
+
+#if 0 /* old 860 stuff: */
+	/* Get the vector by setting the ACK bit and then reading
+	 * the register.
+	 */
+	((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr = 1;
+	vec = ((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr;
+	vec >>= 11;
+
+
+	if (cpm_vecs[vec].handler != 0)
+		(*cpm_vecs[vec].handler)(cpm_vecs[vec].dev_id);
+	else
+		((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr &= ~(1 << vec);
+
+	/* After servicing the interrupt, we have to remove the status
+	 * indicator.
+	 */
+	((immap_t *)IMAP_ADDR)->im_cpic.cpic_cisr |= (1 << vec);
+#endif
+	
+}
+
+/* The CPM can generate the error interrupt when there is a race condition
+ * between generating and masking interrupts.  All we have to do is ACK it
+ * and return.  This is a no-op function so we don't need any special
+ * tests in the interrupt handler.
+ */
+static	void
+cpm_error_interrupt(void *dev)
+{
+}
+
+/* Install a CPM interrupt handler.
+*/
+void
+cpm_install_handler(int vec, void (*handler)(void *), void *dev_id)
+{
+
+	request_irq(vec, handler, IRQ_FLG_LOCK, "timer", dev_id);
+
+/* 	if (cpm_vecs[vec].handler != 0) */
+/* 		printk("CPM interrupt %x replacing %x\n", */
+/* 			(uint)handler, (uint)cpm_vecs[vec].handler); */
+/* 	cpm_vecs[vec].handler = handler; */
+/* 	cpm_vecs[vec].dev_id = dev_id; */
+
+	/*              ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr |= (1 << vec); */
+/* 	pquicc->intr_cimr |= (1 << vec); */
+
+}
+
+/* Free a CPM interrupt handler.
+*/
+void
+cpm_free_handler(int vec)
+{
+	cpm_vecs[vec].handler = NULL;
+	cpm_vecs[vec].dev_id = NULL;
+	/* ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr &= ~(1 << vec); */
+	pquicc->intr_cimr &= ~(1 << vec);
+}
+
+
+
+
+/* Allocate some memory from the dual ported ram.  We may want to
+ * enforce alignment restrictions, but right now everyone is a good
+ * citizen.
+ */
+uint
+m360_cpm_dpalloc(uint size)
+{
+        uint    retloc;
+
+        if ((dp_alloc_base + size) >= dp_alloc_top)
+                return(CPM_DP_NOSPACE);
+
+        retloc = dp_alloc_base;
+        dp_alloc_base += size;
+
+        return(retloc);
+}
+
+
+#if 0 /* mleslie - for now these are simply kmalloc'd */
+/* We also own one page of host buffer space for the allocation of
+ * UART "fifos" and the like.
+ */
+uint
+m360_cpm_hostalloc(uint size)
+{
+	uint	retloc;
+
+	if ((host_buffer + size) >= host_end)
+		return(0);
+
+	retloc = host_buffer;
+	host_buffer += size;
+
+	return(retloc);
+}
+#endif
+
+
+/* Set a baud rate generator.  This needs lots of work.  There are
+ * four BRGs, any of which can be wired to any channel.
+ * The internal baud rate clock is the system clock divided by 16.
+ * This assumes the baudrate is 16x oversampled by the uart.
+ */
+/* #define BRG_INT_CLK	(((bd_t *)__res)->bi_intfreq * 1000000) */
+#define BRG_INT_CLK		system_clock
+#define BRG_UART_CLK	(BRG_INT_CLK/16)
+
+void
+m360_cpm_setbrg(uint brg, uint rate)
+{
+	volatile uint	*bp;
+
+	/* This is good enough to get SMCs running.....
+	 */
+	/* bp = (uint *)&cpmp->cp_brgc1; */
+	bp = (volatile uint *)(&pquicc->brgc[0].l);
+	bp += brg;
+	*bp = ((BRG_UART_CLK / rate - 1) << 1) | CPM_BRG_EN;
+}
+
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 4
+ * End:
+ */
diff -Nru a/arch/m68knommu/platform/68360/config.c b/arch/m68knommu/platform/68360/config.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68360/config.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,213 @@
+/*
+ *  linux/arch/m68knommu/platform/68360/config.c
+ *
+ *  Copyright (c) 2000 Michael Leslie <mleslie@lineo.com>
+ *  Copyright (C) 1993 Hamish Macdonald
+ *  Copyright (C) 1999 D. Jeff Dionne <jeff@uclinux.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <stdarg.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+#include <asm/m68360.h>
+
+#ifdef CONFIG_UCQUICC
+#include <asm/bootstd.h>
+#endif
+
+extern void m360_cpm_reset(void);
+
+// Mask to select if the PLL prescaler is enabled.
+#define MCU_PREEN   ((unsigned short)(0x0001 << 13))
+
+#if defined(CONFIG_UCQUICC)
+#define OSCILLATOR  (unsigned long int)33000000
+#endif
+
+unsigned long int system_clock;
+
+void M68360_init_IRQ(void);
+
+extern QUICC *pquicc;
+
+/* TODO  DON"T Hard Code this */
+/* calculate properly using the right PLL and prescaller */
+// unsigned int system_clock = 33000000l;
+extern unsigned long int system_clock; //In kernel setup.c
+
+extern void config_M68360_irq(void);
+
+void BSP_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
+{
+  unsigned char prescaler;
+  unsigned short tgcr_save;
+  int return_value;
+
+#if 0
+  /* Restart mode, Enable int, 32KHz, Enable timer */
+  TCTL = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_32KHZ | TCTL_TEN;
+  /* Set prescaler (Divide 32KHz by 32)*/
+  TPRER = 31;
+  /* Set compare register  32Khz / 32 / 10 = 100 */
+  TCMP = 10;                                                              
+
+  request_irq(IRQ_MACHSPEC | 1, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
+#endif
+
+  /* General purpose quicc timers: MC68360UM p7-20 */
+
+  /* Set up timer 1 (in [1..4]) to do 100Hz */
+  tgcr_save = pquicc->timer_tgcr & 0xfff0;
+  pquicc->timer_tgcr  = tgcr_save; /* stop and reset timer 1 */
+  /* pquicc->timer_tgcr |= 0x4444; */ /* halt timers when FREEZE (ie bdm freeze) */
+
+  prescaler = 8;
+  pquicc->timer_tmr1 = 0x001a | /* or=1, frr=1, iclk=01b */
+                           (unsigned short)((prescaler - 1) << 8);
+    
+  pquicc->timer_tcn1 = 0x0000; /* initial count */
+  /* calculate interval for 100Hz based on the _system_clock: */
+  pquicc->timer_trr1 = (system_clock/ prescaler) / HZ; /* reference count */
+
+  pquicc->timer_ter1 = 0x0003; /* clear timer events */
+
+  /* enable timer 1 interrupt in CIMR */
+//  request_irq(IRQ_MACHSPEC | CPMVEC_TIMER1, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
+  //return_value = request_irq( CPMVEC_TIMER1, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
+  return_value = request_irq(CPMVEC_TIMER1 , timer_routine, IRQ_FLG_LOCK,
+          "Timer", NULL);
+
+  /* Start timer 1: */
+  tgcr_save = (pquicc->timer_tgcr & 0xfff0) | 0x0001;
+  pquicc->timer_tgcr  = tgcr_save;
+}
+
+
+void BSP_tick(void)
+{
+  /* Reset Timer1 */
+  /* TSTAT &= 0; */
+
+  pquicc->timer_ter1 = 0x0002; /* clear timer event */  
+}
+
+unsigned long BSP_gettimeoffset (void)
+{
+  return 0;
+}
+
+void BSP_gettod (int *yearp, int *monp, int *dayp,
+		   int *hourp, int *minp, int *secp)
+{
+}
+
+int BSP_hwclk(int op, struct hwclk_time *t)
+{
+  if (!op) {
+    /* read */
+  } else {
+    /* write */
+  }
+  return 0;
+}
+
+int BSP_set_clock_mmss (unsigned long nowtime)
+{
+#if 0
+  short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
+
+  tod->second1 = real_seconds / 10;
+  tod->second2 = real_seconds % 10;
+  tod->minute1 = real_minutes / 10;
+  tod->minute2 = real_minutes % 10;
+#endif
+  return 0;
+}
+
+void BSP_reset (void)
+{
+  local_irq_disable();
+  asm volatile ("
+    moveal #_start, %a0;
+    moveb #0, 0xFFFFF300;
+    moveal 0(%a0), %sp;
+    moveal 4(%a0), %a0;
+    jmp (%a0);
+    ");
+}
+
+unsigned char *scc1_hwaddr;
+static int errno;
+
+#if defined (CONFIG_UCQUICC)
+_bsc0(char *, getserialnum)
+_bsc1(unsigned char *, gethwaddr, int, a)
+_bsc1(char *, getbenv, char *, a)
+#endif
+
+
+void config_BSP(char *command, int len)
+{
+  unsigned char *p;
+
+  m360_cpm_reset();
+
+  /* Calculate the real system clock value. */
+  {
+     unsigned int local_pllcr = (unsigned int)(pquicc->sim_pllcr);
+     if( local_pllcr & MCU_PREEN ) // If the prescaler is dividing by 128
+     {
+         int mf = (int)(pquicc->sim_pllcr & 0x0fff);
+         system_clock = (OSCILLATOR / 128) * (mf + 1);
+     }
+     else
+     {
+         int mf = (int)(pquicc->sim_pllcr & 0x0fff);
+         system_clock = (OSCILLATOR) * (mf + 1);
+     }
+  }
+
+  printk("\n68360 QUICC support (C) 2000 Lineo Inc.\n");
+
+#if defined(CONFIG_UCQUICC) && 0
+  printk("uCquicc serial string [%s]\n",getserialnum());
+  p = scc1_hwaddr = gethwaddr(0);
+  printk("uCquicc hwaddr %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
+         p[0], p[1], p[2], p[3], p[4], p[5]);
+
+  p = getbenv("APPEND");
+  if (p)
+    strcpy(p,command);
+  else
+    command[0] = 0;
+#else
+  scc1_hwaddr = "\00\01\02\03\04\05";
+#endif
+ 
+  mach_sched_init      = BSP_sched_init;
+  mach_tick            = BSP_tick;
+  mach_gettimeoffset   = BSP_gettimeoffset;
+  mach_gettod          = BSP_gettod;
+  mach_hwclk           = NULL;
+  mach_set_clock_mmss  = NULL;
+  mach_reset           = BSP_reset;
+
+  //Kendrick's Change
+  mach_trap_init        = M68360_init_IRQ;
+
+  config_M68360_irq();
+}
diff -Nru a/arch/m68knommu/platform/68360/entry.S b/arch/m68knommu/platform/68360/entry.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68360/entry.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,344 @@
+/* -*- mode: asm -*-
+ *
+ *  linux/arch/m68knommu/platform/68360/entry.S
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *  Copyright (C) 2001 SED Systems, a Division of Calian Ltd.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file README.legal in the main directory of this archive
+ * for more details.
+ *
+ * Linux/m68k support by Hamish Macdonald
+ * M68360 Port by SED Systems, and Lineo.
+ *
+ */
+
+/*
+ * entry.S  contains the system-call and fault low-level handling routines.
+ * This also contains the timer-interrupt handler, as well as all interrupts
+ * and faults that can result in a task-switch.
+ *
+ * NOTE: This code handles signal-recognition, which happens every time
+ * after a timer-interrupt and after each system call.
+ *
+ */
+
+/*
+ * 12/03/96 Jes: Currently we only support m68k single-cpu systems, so
+ *               all pointers that used to be 'current' are now entry
+ *               number 0 in the 'current_set' list.
+ */
+
+#include <linux/config.h>
+#include <linux/sys.h>
+#include <linux/linkage.h>
+#include <asm/thread_info.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/entry.h>
+#include <asm/errno.h>
+#include <asm/traps.h>
+#include <asm/asm-offsets.h>
+
+#define IMMED #
+#define DBG_PUTC(x)	moveb IMMED x,0xfffff907; \
+			moveb IMMED '\r',0xfffff907; \
+			moveb IMMED '\n',0xfffff907
+LD0         =   0x20
+LORIG_D0    =   0x24
+
+.globl system_call
+.globl buserr
+.globl trap
+.globl resume
+.globl ret_from_exception
+.globl ret_from_signal
+.globl sys_call_table
+.globl sys_fork
+.globl sys_clone
+.globl sys_vfork
+.globl ret_from_interrupt
+.globl bad_interrupt
+.globl inthandler
+
+.text
+ENTRY(buserr)
+	SAVE_ALL_INT
+	/* GET_CURRENT(%d0) */
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	buserr_c
+	addql	#4,%sp
+	jra	ret_from_exception
+
+ENTRY(trap)
+	SAVE_ALL_INT
+	GET_CURRENT(%d0)
+    moveq.l #-1,%d0
+    move.l  %d0,%sp@(LORIG_D0)
+/* may have to test for LFORMATVEC here as was done in teh 2.0 module */
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	trap_c
+	addql	#4,%sp
+	jra	ret_from_exception
+
+
+ENTRY(reschedule)
+	/* save top of frame*/
+	pea	%sp@
+	jbsr	set_esp0
+	addql	#4,%sp
+
+	pea	ret_from_exception
+	jmp	schedule
+
+	/* After a fork we jump here directly from resume,*/
+	/* so that %d1 contains the previous task*/
+	/* Theoretically only needed on SMP, but let's watch*/
+	/* what happens in schedule_tail() in future...*/
+ENTRY(ret_from_fork)
+#ifdef CONFIG_SMP
+	movel	%d1,%sp@-
+	jsr	schedule_tail
+	addql	#4,%sp
+#endif
+	jra	ret_from_exception
+
+badsys:
+	movel	#-ENOSYS,%sp@(PT_D0)
+	jra	ret_from_exception
+
+do_trace:
+	movel	#-ENOSYS,%sp@(PT_D0)	/* needed for strace*/
+	subql	#4,%sp
+	SAVE_SWITCH_STACK
+	jbsr	syscall_trace
+	RESTORE_SWITCH_STACK
+	addql	#4,%sp
+	movel	%sp@(PT_ORIG_D0),%d1
+	movel	#-ENOSYS,%d0
+	cmpl	#NR_syscalls,%d1
+	jcc	1f
+	lsl	#2,%d1
+	lea	sys_call_table, %a0
+	jbsr	%a0@(%d1)
+
+1:	movel	%d0,%sp@(PT_D0)		/* save the return value*/
+	subql	#4,%sp			/* dummy return address*/
+	SAVE_SWITCH_STACK
+	jbsr	syscall_trace
+
+ret_from_signal:
+	RESTORE_SWITCH_STACK
+	addql	#4,%sp
+	jra	ret_from_exception
+
+ENTRY(system_call)
+	SAVE_ALL_SYS
+
+	GET_CURRENT(%d1)
+	/* save top of frame*/
+	pea	%sp@
+	jbsr	set_esp0
+	addql	#4,%sp
+
+	btst	#PF_TRACESYS_BIT,%a2@(TASK_FLAGS+PF_TRACESYS_OFF)
+	jne	do_trace
+	cmpl	#NR_syscalls,%d0
+	jcc	badsys
+	lsl	#2,%d0
+	lea	sys_call_table,%a0
+	movel	%a0@(%d0), %a0
+	jbsr	%a0@
+	movel	%d0,%sp@(PT_D0)		/* save the return value*/
+
+ret_from_exception:
+	btst	#5,%sp@(PT_SR)		/* check if returning to kernel*/
+	jeq	Luser_return		/* if so, skip resched, signals*/
+
+Lkernel_return:
+	RESTORE_ALL
+
+Luser_return:
+	/* only allow interrupts when we are really the last one on the*/
+	/* kernel stack, otherwise stack overflow can occur during*/
+	/* heavy interupt load*/
+	andw	#ALLOWINT,%sr
+
+	movel	%sp,%d1			/* get thread_info pointer */
+	andl	#0xffffe000,%d1
+	movel	%d1,%a2
+	move	%a2@(TI_FLAGS),%d1	/* thread_info->flags */
+	andl	#_TIF_WORK_MASK,%d1
+	jne	Lwork_to_do
+	RESTORE_ALL
+
+Lwork_to_do:
+	movel	%a2@(TI_FLAGS),%d1	/* thread_info->flags */
+	btst	#TIF_NEED_RESCHED,%d1
+	jne	reschedule
+
+Lsignal_return:
+	subql	#4,%sp			/* dummy return address*/
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	clrl	%sp@-
+	bsrw	do_signal
+	addql	#8,%sp
+	RESTORE_SWITCH_STACK
+	addql	#4,%sp
+Lreturn:
+	RESTORE_ALL
+
+/*
+** This is the main interrupt handler, responsible for calling process_int()
+*/
+
+inthandler:
+	SAVE_ALL_INT
+	GET_CURRENT(%d0)
+	addql	#1,local_irq_count	/*  put exception # in d0*/
+/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
+	movew	%sp@(PT_VECTOR), %d0
+	and.l	#0x3ff, %d0
+	lsr.l   #0x02,  %d0
+
+	movel	%sp,%sp@-
+	movel	%d0,%sp@- 		/*  put vector # on stack*/
+	jbsr	process_int		/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+
+ret_from_interrupt:
+	subql	#1,local_irq_count
+	jeq	1f
+2:
+	RESTORE_ALL
+1:
+#if 1
+/*	bfextu  %sp@(PT_SR){#5,#3},%d0 */	/* Check for nested interrupt.*/
+	moveb	%sp@(PT_SR), %d0
+	and	#7, %d0
+
+#if MAX_NOINT_IPL > 0
+	cmpiw	#MAX_NOINT_IPL,%d0
+#endif
+	jhi	2b
+#endif
+	/* check if we need to do software interrupts */
+
+	movel	irq_stat+CPUSTAT_SOFTIRQ_PENDING,%d0
+	jeq	ret_from_exception
+
+	pea	ret_from_exception
+	jra	do_softirq
+
+
+/* Handler for uninitialized and spurious interrupts */
+
+bad_interrupt:
+	addql	#1,num_spurious
+	rte
+
+ENTRY(sys_fork)
+	SAVE_SWITCH_STACK	
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	m68k_fork
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_clone)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	m68k_clone
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_vfork)
+	SAVE_SWITCH_STACK	
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	m68k_vfork
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_sigsuspend)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	do_sigsuspend
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_rt_sigsuspend)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	do_rt_sigsuspend
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_sigreturn)
+	SAVE_SWITCH_STACK
+	jbsr	do_sigreturn
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_rt_sigreturn)
+	SAVE_SWITCH_STACK
+	jbsr	do_rt_sigreturn
+	RESTORE_SWITCH_STACK
+	rts
+
+resume:
+	/*
+	 * Beware - when entering resume, prev (the current task) is
+	 * in a0, next (the new task) is in a1,so don't change these
+	 * registers until their contents are no longer needed.
+	 */
+
+	/* save prev thread in d1 */
+	movel	%a0,%d1
+
+	/* save sr */
+	movew	%sr,%a0@(TASK_THREAD+THREAD_SR)
+#ifdef USE_SFC_DFC
+	/* save fs (sfc,%dfc) (may be pointing to kernel memory) */
+	movec	%sfc,%d0
+	movew	%d0,%a0@(TASK_THREAD+THREAD_FS)
+#endif
+
+	/* save non-scratch registers on stack */
+	SAVE_SWITCH_STACK
+
+	/* save usp */
+	/* it is better to use a movel here instead of a movew 8*) */
+	movel	%usp,%a2
+	movel	%a2,%a0@(TASK_THREAD+THREAD_USP)
+
+	/* save current kernel stack pointer */
+	movel	%sp,%a0@(TASK_THREAD+THREAD_KSP)
+
+	/* restore the kernel stack pointer */
+	movel	%a1@(TASK_THREAD+THREAD_KSP),%sp
+
+	/* restore non-scratch registers */
+	RESTORE_SWITCH_STACK
+
+	/* restore user stack pointer */
+	movel	%a1@(TASK_THREAD+THREAD_USP),%a0
+	movel	%a0,%usp
+
+#ifdef USE_SFC_DFC
+	/* restore fs (sfc,%dfc) */
+	movew	%a1@(TASK_THREAD+THREAD_FS),%a0
+	movec	%a0,%sfc
+	movec	%a0,%dfc
+#endif
+	/* restore status register */
+	movew	%a1@(TASK_THREAD+THREAD_SR),%sr
+
+	rts
+
diff -Nru a/arch/m68knommu/platform/68360/ints.c b/arch/m68knommu/platform/68360/ints.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68360/ints.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,318 @@
+/*
+ * linux/arch/$(ARCH)/platform/$(PLATFORM)/ints.c
+ *
+ * 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) 2000  Michael Leslie <mleslie@lineo.com>
+ * Copyright (c) 1996 Roman Zippel
+ * Copyright (c) 1999 D. Jeff Dionne <jeff@uclinux.org>
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+#include <asm/m68360.h>
+
+/* from quicc/commproc.c: */
+extern QUICC *pquicc;
+extern void cpm_interrupt_init(void);
+
+#define INTERNAL_IRQS (96)
+
+/* assembler routines */
+asmlinkage void system_call(void);
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void bad_interrupt(void);
+asmlinkage void inthandler(void);
+
+extern void *_ramvec[];
+
+/* irq node variables for the 32 (potential) on chip sources */
+static irq_node_t *int_irq_list[INTERNAL_IRQS];
+
+static int int_irq_count[INTERNAL_IRQS];
+static short int_irq_ablecount[INTERNAL_IRQS];
+
+static void int_badint(int irq, void *dev_id, struct pt_regs *fp)
+{
+	num_spurious += 1;
+}
+
+/*
+ * This function should be called during kernel startup to initialize
+ * IRQ handling routines.
+ */
+
+void M68360_init_IRQ(void)
+{
+	int i;
+	int vba = (CPM_VECTOR_BASE<<4);
+
+	/* set up the vectors */
+	_ramvec[2] = buserr;
+	_ramvec[3] = trap;
+	_ramvec[4] = trap;
+	_ramvec[5] = trap;
+	_ramvec[6] = trap;
+	_ramvec[7] = trap;
+	_ramvec[8] = trap;
+	_ramvec[9] = trap;
+	_ramvec[10] = trap;
+	_ramvec[11] = trap;
+	_ramvec[12] = trap;
+	_ramvec[13] = trap;
+	_ramvec[14] = trap;
+	_ramvec[15] = trap;
+
+	_ramvec[32] = system_call;
+	_ramvec[33] = trap;
+
+
+	cpm_interrupt_init();
+
+	/* set up CICR for vector base address and irq level */
+	/* irl = 4, hp = 1f - see MC68360UM p 7-377 */
+	pquicc->intr_cicr = 0x00e49f00 | vba;
+
+	/* CPM interrupt vectors: (p 7-376) */
+	_ramvec[vba+CPMVEC_ERROR]       = bad_interrupt; /* Error */
+	_ramvec[vba+CPMVEC_PIO_PC11]    = inthandler;   /* pio - pc11 */
+	_ramvec[vba+CPMVEC_PIO_PC10]    = inthandler;   /* pio - pc10 */
+	_ramvec[vba+CPMVEC_SMC2]        = inthandler;   /* smc2/pip */
+	_ramvec[vba+CPMVEC_SMC1]        = inthandler;   /* smc1 */
+	_ramvec[vba+CPMVEC_SPI]         = inthandler;   /* spi */
+	_ramvec[vba+CPMVEC_PIO_PC9]     = inthandler;   /* pio - pc9 */
+	_ramvec[vba+CPMVEC_TIMER4]      = inthandler;   /* timer 4 */
+	_ramvec[vba+CPMVEC_RESERVED1]   = inthandler;   /* reserved */
+	_ramvec[vba+CPMVEC_PIO_PC8]     = inthandler;   /* pio - pc8 */
+	_ramvec[vba+CPMVEC_PIO_PC7]     = inthandler;  /* pio - pc7 */
+	_ramvec[vba+CPMVEC_PIO_PC6]     = inthandler;  /* pio - pc6 */
+	_ramvec[vba+CPMVEC_TIMER3]      = inthandler;  /* timer 3 */
+	_ramvec[vba+CPMVEC_RISCTIMER]   = inthandler;  /* reserved */
+	_ramvec[vba+CPMVEC_PIO_PC5]     = inthandler;  /* pio - pc5 */
+	_ramvec[vba+CPMVEC_PIO_PC4]     = inthandler;  /* pio - pc4 */
+	_ramvec[vba+CPMVEC_RESERVED2]   = inthandler;  /* reserved */
+	_ramvec[vba+CPMVEC_RISCTIMER]   = inthandler;  /* timer table */
+	_ramvec[vba+CPMVEC_TIMER2]      = inthandler;  /* timer 2 */
+	_ramvec[vba+CPMVEC_RESERVED3]   = inthandler;  /* reserved */
+	_ramvec[vba+CPMVEC_IDMA2]       = inthandler;  /* idma 2 */
+	_ramvec[vba+CPMVEC_IDMA1]       = inthandler;  /* idma 1 */
+	_ramvec[vba+CPMVEC_SDMA_CB_ERR] = inthandler;  /* sdma channel bus error */
+	_ramvec[vba+CPMVEC_PIO_PC3]     = inthandler;  /* pio - pc3 */
+	_ramvec[vba+CPMVEC_PIO_PC2]     = inthandler;  /* pio - pc2 */
+	/* _ramvec[vba+CPMVEC_TIMER1]      = cpm_isr_timer1; */  /* timer 1 */
+	_ramvec[vba+CPMVEC_TIMER1]      = inthandler;  /* timer 1 */
+	_ramvec[vba+CPMVEC_PIO_PC1]     = inthandler;  /* pio - pc1 */
+	_ramvec[vba+CPMVEC_SCC4]        = inthandler;  /* scc 4 */
+	_ramvec[vba+CPMVEC_SCC3]        = inthandler;  /* scc 3 */
+	_ramvec[vba+CPMVEC_SCC2]        = inthandler;  /* scc 2 */
+	_ramvec[vba+CPMVEC_SCC1]        = inthandler;  /* scc 1 */
+	_ramvec[vba+CPMVEC_PIO_PC0]     = inthandler;  /* pio - pc0 */
+
+
+	/* turn off all CPM interrupts */
+	pquicc->intr_cimr = 0x00000000;
+
+	/* initialize handlers */
+	for (i = 0; i < INTERNAL_IRQS; i++) {
+		int_irq_list[i] = NULL;
+
+		int_irq_ablecount[i] = 0;
+		int_irq_count[i] = 0;
+	}
+}
+
+void M68360_insert_irq(irq_node_t **list, irq_node_t *node)
+{
+	unsigned long flags;
+	irq_node_t *cur;
+
+	if (!node->dev_id)
+		printk("%s: Warning: dev_id of %s is zero\n",
+		       __FUNCTION__, node->devname);
+
+	local_irq_save(flags);
+
+	cur = *list;
+
+	while (cur) {
+		list = &cur->next;
+		cur = cur->next;
+	}
+
+	node->next = cur;
+	*list = node;
+
+	local_irq_restore(flags);
+}
+
+void M68360_delete_irq(irq_node_t **list, void *dev_id)
+{
+	unsigned long flags;
+	irq_node_t *node;
+
+	local_irq_save(flags);
+
+	for (node = *list; node; list = &node->next, node = *list) {
+		if (node->dev_id == dev_id) {
+			*list = node->next;
+			/* Mark it as free. */
+			node->handler = NULL;
+			local_irq_restore(flags);
+			return;
+		}
+	}
+	local_irq_restore(flags);
+	printk ("%s: tried to remove invalid irq\n", __FUNCTION__);
+}
+
+int M68360_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+                         unsigned long flags, const char *devname, void *dev_id)
+{
+	int mask = (1<<irq);
+
+	irq += (CPM_VECTOR_BASE<<4);
+
+	if (irq >= INTERNAL_IRQS) {
+		printk ("%s: Unknown IRQ %d from %s\n", __FUNCTION__, irq, devname);
+		return -ENXIO;
+	}
+
+	if (!int_irq_list[irq]) {
+		int_irq_list[irq] = new_irq_node();
+		int_irq_list[irq]->flags   = IRQ_FLG_STD;
+	}
+
+	if (!(int_irq_list[irq]->flags & IRQ_FLG_STD)) {
+		if (int_irq_list[irq]->flags & IRQ_FLG_LOCK) {
+			printk("%s: IRQ %d from %s is not replaceable\n",
+			       __FUNCTION__, irq, int_irq_list[irq]->devname);
+			return -EBUSY;
+		}
+		if (flags & IRQ_FLG_REPLACE) {
+			printk("%s: %s can't replace IRQ %d from %s\n",
+			       __FUNCTION__, devname, irq, int_irq_list[irq]->devname);
+			return -EBUSY;
+		}
+	}
+	int_irq_list[irq]->handler = handler;
+	int_irq_list[irq]->flags   = flags;
+	int_irq_list[irq]->dev_id  = dev_id;
+	int_irq_list[irq]->devname = devname;
+
+	/* enable in the CIMR */
+	if (!int_irq_ablecount[irq])
+		pquicc->intr_cimr |= mask;
+	/*      *(volatile unsigned long *)0xfffff304 &= ~(1<<irq); */
+
+	return 0;
+}
+
+void M68360_free_irq(unsigned int irq, void *dev_id)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk ("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (int_irq_list[irq]->dev_id != dev_id)
+		printk("%s: removing probably wrong IRQ %d from %s\n",
+		       __FUNCTION__, irq, int_irq_list[irq]->devname);
+	int_irq_list[irq]->handler = int_badint;
+	int_irq_list[irq]->flags   = IRQ_FLG_STD;
+	int_irq_list[irq]->dev_id  = NULL;
+	int_irq_list[irq]->devname = NULL;
+
+	*(volatile unsigned long *)0xfffff304 |= 1<<irq;
+}
+
+/*
+ * Enable/disable a particular machine specific interrupt source.
+ * Note that this may affect other interrupts in case of a shared interrupt.
+ * This function should only be called for a _very_ short time to change some
+ * internal data, that may not be changed by the interrupt at the same time.
+ * int_(enable|disable)_irq calls may also be nested.
+ */
+void M68360_enable_irq(unsigned int irq)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (--int_irq_ablecount[irq])
+		return;
+
+	/* enable the interrupt */
+	*(volatile unsigned long *)0xfffff304 &= ~(1<<irq);
+}
+
+void M68360_disable_irq(unsigned int irq)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (int_irq_ablecount[irq]++)
+		return;
+
+	/* disable the interrupt */
+	*(volatile unsigned long *)0xfffff304 |= 1<<irq;
+}
+
+/* The 68k family did not have a good way to determine the source
+ * of interrupts until later in the family.  The EC000 core does
+ * not provide the vector number on the stack, we vector everything
+ * into one vector and look in the blasted mask register...
+ * This code is designed to be fast, almost constant time, not clean!
+ */
+void M68360_do_irq(int vec, struct pt_regs *fp)
+{
+	int irq;
+	int mask;
+
+	/* unsigned long pend = *(volatile unsigned long *)0xfffff30c; */
+
+	/* irq = vec + (CPM_VECTOR_BASE<<4); */
+	irq = vec;
+
+	/* unsigned long pend = *(volatile unsigned long *)pquicc->intr_cipr; */
+
+	/* Bugger all that wierdness. For the moment, I seem to know where I came from;
+	 * vec is passed from a specific ISR, so I'll use it. */
+
+	if (int_irq_list[irq] && int_irq_list[irq]->handler) {
+		int_irq_list[irq]->handler(irq , int_irq_list[irq]->dev_id, fp);
+		int_irq_count[irq]++;
+		pquicc->intr_cisr = (1 << vec); /* indicate that irq has been serviced */
+	} else {
+		printk("unregistered interrupt %d!\nTurning it off in the CIMR...\n", irq);
+		/* *(volatile unsigned long *)0xfffff304 |= mask; */
+		pquicc->intr_cimr &= ~(1 << vec);
+	}
+}
+
+void config_M68360_irq(void)
+{
+	mach_default_handler = NULL;
+	mach_init_IRQ        = M68360_init_IRQ;
+	mach_request_irq     = M68360_request_irq;
+	mach_free_irq        = M68360_free_irq;
+	mach_enable_irq      = M68360_enable_irq;
+	mach_disable_irq     = M68360_disable_irq;
+	mach_process_int     = M68360_do_irq;
+}
+
diff -Nru a/arch/m68knommu/platform/68360/uCquicc/crt0_ram.S b/arch/m68knommu/platform/68360/uCquicc/crt0_ram.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68360/uCquicc/crt0_ram.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,415 @@
+/* arch/m68knommu/platform/68360/uCquicc/crt0_rom.S
+ *
+ * Startup code for Motorola 68360
+ *
+ * Copyright 2001 (C) SED Systems, a Division of Calian Ltd.
+ * Based on: arch/m68knommu/platform/68328/pilot/crt0_rom.S
+ * Based on: arch/m68knommu/platform/68360/uCquicc/crt0_rom.S, 2.0.38.1.pre7
+ *           uClinux Kernel
+ * Copyright (C) Michael Leslie <mleslie@lineo.com>
+ * Based on: arch/m68knommu/platform/68EZ328/ucsimm/crt0_rom.S
+ * Copyright (C) 1998  D. Jeff Dionne <jeff@uclinux.org>,
+ *
+ */
+#define ASSEMBLY
+#include <linux/config.h>
+
+.global _stext
+.global __bss_start
+.global _start
+
+.global _rambase
+.global __ramvec
+.global _ramvec
+.global _ramstart
+.global _ramend
+
+.global _quicc_base
+.global _periph_base
+.global _dprbase
+
+#define REGB                        0x1000
+#define PEPAR                       (_dprbase + REGB + 0x0016)
+#define GMR                         (_dprbase + REGB + 0x0040)
+#define OR0                         (_dprbase + REGB + 0x0054)
+#define BR0                         (_dprbase + REGB + 0x0050)
+#define OR1                         (_dprbase + REGB + 0x0064)
+#define BR1                         (_dprbase + REGB + 0x0060)
+#define OR4                         (_dprbase + REGB + 0x0094)
+#define BR4                         (_dprbase + REGB + 0x0090)
+#define OR6                         (_dprbase + REGB + 0x00b4)
+#define BR6                         (_dprbase + REGB + 0x00b0)
+#define OR7                         (_dprbase + REGB + 0x00c4)
+#define BR7                         (_dprbase + REGB + 0x00c0)
+
+#define MCR                         (_dprbase + REGB + 0x0000)
+#define AVR                         (_dprbase + REGB + 0x0008)
+
+#define SYPCR                       (_dprbase + REGB + 0x0022)
+
+#define PLLCR                       (_dprbase + REGB + 0x0010)
+#define CLKOCR                      (_dprbase + REGB + 0x000C)
+#define CDVCR                       (_dprbase + REGB + 0x0014)
+
+#define BKAR                        (_dprbase + REGB + 0x0030)
+#define BKCR                        (_dprbase + REGB + 0x0034)
+#define SWIV                        (_dprbase + REGB + 0x0023)
+#define PICR                        (_dprbase + REGB + 0x0026)
+#define PITR                        (_dprbase + REGB + 0x002A)
+
+/* Define for all memory configuration */
+#define MCU_SIM_GMR                 0x00000000
+#define SIM_OR_MASK                 0x0fffffff
+
+/* Defines for chip select zero - the flash */
+#define SIM_OR0_MASK                0x20000002
+#define SIM_BR0_MASK                0x00000001
+
+
+/* Defines for chip select one - the RAM */
+#define SIM_OR1_MASK                0x10000000
+#define SIM_BR1_MASK                0x00000001
+
+#define MCU_SIM_MBAR_ADRS           0x0003ff00
+#define MCU_SIM_MBAR_BA_MASK        0xfffff000
+#define MCU_SIM_MBAR_AS_MASK        0x00000001
+
+#define MCU_SIM_PEPAR               0x00B4
+    
+#define MCU_DISABLE_INTRPTS         0x2700
+#define MCU_SIM_AVR                 0x00
+    
+#define MCU_SIM_MCR                 0x00005cff
+
+#define MCU_SIM_CLKOCR              0x00
+#define MCU_SIM_PLLCR               0x8000
+#define MCU_SIM_CDVCR               0x0000
+
+#define MCU_SIM_SYPCR               0x0000
+#define MCU_SIM_SWIV                0x00
+#define MCU_SIM_PICR                0x0000
+#define MCU_SIM_PITR                0x0000
+
+
+#include <asm/m68360_regs.h>
+
+	
+/* By the time this RAM specific code begins to execute, DPRAM
+ * and DRAM should already be mapped and accessible. */
+
+	.text
+_start:
+_stext:
+    nop
+    ori.w   #MCU_DISABLE_INTRPTS,   %sr     /* disable interrupts: */
+    /* We should not need to setup the boot stack the reset should do it. */
+    movea.l	#_boot_stack,           %sp     /*set up stack at the end of DRAM:*/
+
+
+set_mbar_register:
+    moveq.l #0x07,                  %d1     /* Setup MBAR */
+    movec	%d1,                    %dfc
+
+    lea.l   MCU_SIM_MBAR_ADRS,      %a0
+    move.l  #_dprbase,              %d0
+    andi.l  #MCU_SIM_MBAR_BA_MASK,  %d0
+    ori.l   #MCU_SIM_MBAR_AS_MASK,  %d0
+    moves.l %d0,                    %a0@
+
+    moveq.l #0x05,                  %d1
+    movec.l %d1,                    %dfc
+
+/* Now we can begin to access registers in DPRAM */
+
+set_sim_mcr:
+    /* Set Module Configuration Register */
+    move.l  #MCU_SIM_MCR,           MCR
+
+/* to do:	Determine cause of reset */
+
+
+    /*
+    *       configure system clock MC68360 p. 6-40
+    *       (value +1)*osc/128 = system clock
+    */
+set_sim_clock:
+    move.w  #MCU_SIM_PLLCR,         PLLCR
+    move.b  #MCU_SIM_CLKOCR,        CLKOCR
+    move.w  #MCU_SIM_CDVCR,         CDVCR
+
+    // Wait for the PLL to settle
+    move.w      #16384, %d0
+pll_settle_wait:
+    subi.w       #1, %d0
+    bne	pll_settle_wait
+
+    /* Setup the system protection register, and watchdog timer register */
+
+    move.b      #MCU_SIM_SWIV,      SWIV
+    move.w      #MCU_SIM_PICR,      PICR
+    move.w      #MCU_SIM_PITR,      PITR
+    move.w      #MCU_SIM_SYPCR,     SYPCR
+
+/* Clear DPRAM - system + parameter */
+	movea.l	#_dprbase, %a0
+	movea.l	#_dprbase+0x2000, %a1
+
+	/* Copy 0 to %a0 until %a0 == %a1 */
+clear_dpram:
+	movel	#0, %a0@+
+	cmpal	%a0, %a1
+	bhi	clear_dpram
+
+configure_memory_controller:    
+    /*
+    *   Set up Global Memory Register (GMR)
+    */
+    move.l      #MCU_SIM_GMR,   %d0
+    move.l      %d0, GMR
+
+configure_chip_select_0:
+    move.l      #__ramend,      %d0
+    subi.l      #__ramstart,    %d0
+    subq.l      #0x01,          %d0
+    eori.l      #SIM_OR_MASK,   %d0
+    ori.l       #SIM_OR0_MASK,  %d0
+    move.l      %d0,            OR0
+
+    move.l      #__ramstart,    %d0
+    ori.l       #SIM_BR0_MASK,  %d0
+    move.l      %d0,            BR0
+
+
+configure_chip_select_1:
+    move.l      #__flashend,    %d0
+    subi.l      #__flashstart,  %d0
+    subq.l      #0x01,          %d0
+    eori.l      #SIM_OR_MASK,   %d0
+    ori.l       #SIM_OR1_MASK,  %d0
+    move.l      %d0,            OR1
+
+    move.l      #__flashstart,  %d0
+    ori.l       #SIM_BR1_MASK,  %d0
+    move.l      %d0,            BR1
+
+
+    move.w      #MCU_SIM_PEPAR, PEPAR 
+
+/* point to vector table: */
+    move.l  #_romvec,   %a0
+    move.l	#_ramvec,   %a1
+copy_vectors:
+    move.l  %a0@,       %d0
+    move.l  %d0,        %a1@
+    move.l  %a0@,       %a1@
+    addq.l  #0x04,      %a0
+    addq.l  #0x04,      %a1
+    cmp.l   #_start,    %a0
+    blt     copy_vectors
+
+    move.l	#_ramvec, %a1
+    movec	%a1, %vbr
+
+
+	/* Copy data segment from ROM to RAM */
+	moveal	#__data_rom_start, %a0
+	moveal	#__data_start, %a1
+	moveal	#__data_end, %a2
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+LD1:
+    move.l  %a0@,   %d0
+    addq.l  #0x04,  %a0
+    move.l  %d0,    %a1@
+    addq.l  #0x04,  %a1
+    cmp.l   #__data_end,    %a1
+    blt     LD1
+
+	moveal	#__bss_start, %a0
+	moveal	#end, %a1
+
+	/* Copy 0 to %a0 until %a0 == %a1 */
+L1:
+	movel	#0, %a0@+
+	cmpal	%a0, %a1
+	bhi	L1
+
+load_quicc:
+    move.l  #_dprbase,  _quicc_base
+
+store_ram_size:
+    /* Set ram size information */
+    move.l  #_sdata,    _rambase
+    move.l  #end,       _ramstart
+    move.l  #__ramend,  %d0
+    sub.l   #0x1000,    %d0     /* Reserve 4K for stack space.*/
+    move.l  %d0,        _ramend /* Different from __ramend.*/
+
+store_flash_size:
+    /* Set rom size information */
+    move.l  #__flashend,    %d0
+    sub.l   #__flashstart,  %d0
+    move.l  %d0,            rom_length
+    
+	pea	0
+	pea	env
+	pea	%sp@(4)
+	pea	0
+
+	lea	init_thread_union, %a2
+	lea	0x2000(%a2), %sp
+
+lp:
+    jsr	start_kernel
+ /*   jmp lp */
+
+_exit:
+
+	jmp	_exit
+
+
+
+	.data
+    .align 4
+env:
+	.long	0
+_quicc_base:
+	.long	0
+_periph_base:
+	.long	0
+_ramvec:
+    .long   0
+_rambase:
+    .long   0
+_ramstart:
+    .long   0
+_ramend:
+    .long   0
+	.text
+
+    /*
+     * These are the exception vectors at boot up, they are copied into RAM
+     * and then overwritten as needed.
+     */
+ 
+.section ".data.initvect","awx"
+    .long   _boot_stack /* Reset: Initial Stack Pointer                 - 0.  */
+    .long   _start      /* Reset: Initial Program Counter               - 1.  */
+    .long   buserr      /* Bus Error                                    - 2.  */
+    .long   trap        /* Address Error                                - 3.  */
+    .long   trap        /* Illegal Instruction                          - 4.  */
+    .long   trap        /* Divide by zero                               - 5.  */
+    .long   trap        /* CHK, CHK2 Instructions                       - 6.  */
+    .long   trap        /* TRAPcc, TRAPV Instructions                   - 7.  */
+    .long   trap        /* Privilege Violation                          - 8.  */
+    .long   trap        /* Trace                                        - 9.  */
+    .long   trap        /* Line 1010 Emulator                           - 10. */
+    .long   trap        /* Line 1111 Emualtor                           - 11. */
+    .long   trap        /* Harware Breakpoint                           - 12. */
+    .long   trap        /* (Reserved for Coprocessor Protocol Violation)- 13. */
+    .long   trap        /* Format Error                                 - 14. */
+    .long   trap        /* Uninitialized Interrupt                      - 15. */
+    .long   trap        /* (Unassigned, Reserver)                       - 16. */
+    .long   trap        /* (Unassigned, Reserver)                       - 17. */
+    .long   trap        /* (Unassigned, Reserver)                       - 18. */
+    .long   trap        /* (Unassigned, Reserver)                       - 19. */
+    .long   trap        /* (Unassigned, Reserver)                       - 20. */
+    .long   trap        /* (Unassigned, Reserver)                       - 21. */
+    .long   trap        /* (Unassigned, Reserver)                       - 22. */
+    .long   trap        /* (Unassigned, Reserver)                       - 23. */
+    .long   trap        /* Spurious Interrupt                           - 24. */
+    .long   trap        /* Level 1 Interrupt Autovector                 - 25. */
+    .long   trap        /* Level 2 Interrupt Autovector                 - 26. */
+    .long   trap        /* Level 3 Interrupt Autovector                 - 27. */
+    .long   trap        /* Level 4 Interrupt Autovector                 - 28. */
+    .long   trap        /* Level 5 Interrupt Autovector                 - 29. */
+    .long   trap        /* Level 6 Interrupt Autovector                 - 30. */
+    .long   trap        /* Level 7 Interrupt Autovector                 - 31. */
+    .long   system_call /* Trap Instruction Vectors 0                   - 32. */
+    .long   trap        /* Trap Instruction Vectors 1                   - 33. */
+    .long   trap        /* Trap Instruction Vectors 2                   - 34. */
+    .long   trap        /* Trap Instruction Vectors 3                   - 35. */
+    .long   trap        /* Trap Instruction Vectors 4                   - 36. */
+    .long   trap        /* Trap Instruction Vectors 5                   - 37. */
+    .long   trap        /* Trap Instruction Vectors 6                   - 38. */
+    .long   trap        /* Trap Instruction Vectors 7                   - 39. */
+    .long   trap        /* Trap Instruction Vectors 8                   - 40. */
+    .long   trap        /* Trap Instruction Vectors 9                   - 41. */
+    .long   trap        /* Trap Instruction Vectors 10                  - 42. */
+    .long   trap        /* Trap Instruction Vectors 11                  - 43. */
+    .long   trap        /* Trap Instruction Vectors 12                  - 44. */
+    .long   trap        /* Trap Instruction Vectors 13                  - 45. */
+    .long   trap        /* Trap Instruction Vectors 14                  - 46. */
+    .long   trap        /* Trap Instruction Vectors 15                  - 47. */
+    .long   0           /* (Reserved for Coprocessor)                   - 48. */
+    .long   0           /* (Reserved for Coprocessor)                   - 49. */
+    .long   0           /* (Reserved for Coprocessor)                   - 50. */
+    .long   0           /* (Reserved for Coprocessor)                   - 51. */
+    .long   0           /* (Reserved for Coprocessor)                   - 52. */
+    .long   0           /* (Reserved for Coprocessor)                   - 53. */
+    .long   0           /* (Reserved for Coprocessor)                   - 54. */
+    .long   0           /* (Reserved for Coprocessor)                   - 55. */
+    .long   0           /* (Reserved for Coprocessor)                   - 56. */
+    .long   0           /* (Reserved for Coprocessor)                   - 57. */
+    .long   0           /* (Reserved for Coprocessor)                   - 58. */
+    .long   0           /* (Unassigned, Reserved)                       - 59. */
+    .long   0           /* (Unassigned, Reserved)                       - 60. */
+    .long   0           /* (Unassigned, Reserved)                       - 61. */
+    .long   0           /* (Unassigned, Reserved)                       - 62. */
+    .long   0           /* (Unassigned, Reserved)                       - 63. */
+    /*                  The assignment of these vectors to the CPM is         */
+    /*                  dependant on the configuration of the CPM vba         */
+    /*                          fields.                                       */
+    .long   0           /* (User-Defined Vectors 1) CPM Error           - 64. */
+    .long   0           /* (User-Defined Vectors 2) CPM Parallel IO PC11- 65. */
+    .long   0           /* (User-Defined Vectors 3) CPM Parallel IO PC10- 66. */
+    .long   0           /* (User-Defined Vectors 4) CPM SMC2 / PIP      - 67. */
+    .long   0           /* (User-Defined Vectors 5) CPM SMC1            - 68. */
+    .long   0           /* (User-Defined Vectors 6) CPM SPI             - 69. */
+    .long   0           /* (User-Defined Vectors 7) CPM Parallel IO PC9 - 70. */
+    .long   0           /* (User-Defined Vectors 8) CPM Timer 4         - 71. */
+    .long   0           /* (User-Defined Vectors 9) CPM Reserved        - 72. */
+    .long   0           /* (User-Defined Vectors 10) CPM Parallel IO PC8- 73. */
+    .long   0           /* (User-Defined Vectors 11) CPM Parallel IO PC7- 74. */
+    .long   0           /* (User-Defined Vectors 12) CPM Parallel IO PC6- 75. */
+    .long   0           /* (User-Defined Vectors 13) CPM Timer 3        - 76. */
+    .long   0           /* (User-Defined Vectors 14) CPM Reserved       - 77. */
+    .long   0           /* (User-Defined Vectors 15) CPM Parallel IO PC5- 78. */
+    .long   0           /* (User-Defined Vectors 16) CPM Parallel IO PC4- 79. */
+    .long   0           /* (User-Defined Vectors 17) CPM Reserved       - 80. */
+    .long   0           /* (User-Defined Vectors 18) CPM RISC Timer Tbl - 81. */
+    .long   0           /* (User-Defined Vectors 19) CPM Timer 2        - 82. */
+    .long   0           /* (User-Defined Vectors 21) CPM Reserved       - 83. */
+    .long   0           /* (User-Defined Vectors 22) CPM IDMA2          - 84. */
+    .long   0           /* (User-Defined Vectors 23) CPM IDMA1          - 85. */
+    .long   0           /* (User-Defined Vectors 24) CPM SDMA Bus Err   - 86. */
+    .long   0           /* (User-Defined Vectors 25) CPM Parallel IO PC3- 87. */
+    .long   0           /* (User-Defined Vectors 26) CPM Parallel IO PC2- 88. */
+    .long   0           /* (User-Defined Vectors 27) CPM Timer 1        - 89. */
+    .long   0           /* (User-Defined Vectors 28) CPM Parallel IO PC1- 90. */
+    .long   0           /* (User-Defined Vectors 29) CPM SCC 4          - 91. */
+    .long   0           /* (User-Defined Vectors 30) CPM SCC 3          - 92. */
+    .long   0           /* (User-Defined Vectors 31) CPM SCC 2          - 93. */
+    .long   0           /* (User-Defined Vectors 32) CPM SCC 1          - 94. */
+    .long   0           /* (User-Defined Vectors 33) CPM Parallel IO PC0- 95. */
+    /*                  I don't think anything uses the vectors after here.   */
+    .long   0           /* (User-Defined Vectors 34)                    - 96. */
+    .long   0,0,0,0,0               /* (User-Defined Vectors 35  -  39). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 40  -  49). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 50  -  59). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 60  -  69). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 70  -  79). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 80  -  89). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 90  -  99). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 100 - 109). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 110 - 119). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 120 - 129). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 130 - 139). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 140 - 149). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 150 - 159). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 160 - 169). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 170 - 179). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 180 - 189). */
+    .long   0,0,0                   /* (User-Defined Vectors 190 - 192). */
+.text
+ignore: rte
diff -Nru a/arch/m68knommu/platform/68360/uCquicc/crt0_rom.S b/arch/m68knommu/platform/68360/uCquicc/crt0_rom.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68360/uCquicc/crt0_rom.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,424 @@
+/* arch/m68knommu/platform/68360/uCquicc/crt0_rom.S
+ *
+ * Startup code for Motorola 68360
+ *
+ * Copyright (C) SED Systems, a Division of Calian Ltd.
+ * Based on: arch/m68knommu/platform/68328/pilot/crt0_rom.S
+ * Based on: arch/m68knommu/platform/68360/uCquicc/crt0_rom.S, 2.0.38.1.pre7
+ *           uClinux Kernel
+ * Copyright (C) Michael Leslie <mleslie@lineo.com>
+ * Based on: arch/m68knommu/platform/68EZ328/ucsimm/crt0_rom.S
+ * Copyright (C) 1998  D. Jeff Dionne <jeff@uclinux.org>,
+ *
+ */
+#define ASSEMBLY
+#include <linux/config.h>
+
+.global _stext
+.global __bss_start
+.global _start
+
+.global _rambase
+.global __ramvec
+.global _ramvec
+.global _ramstart
+.global _ramend
+
+.global _quicc_base
+.global _periph_base
+.global _dprbase
+
+#define REGB                        0x1000
+#define PEPAR                       (_dprbase + REGB + 0x0016)
+#define GMR                         (_dprbase + REGB + 0x0040)
+#define OR0                         (_dprbase + REGB + 0x0054)
+#define BR0                         (_dprbase + REGB + 0x0050)
+
+#define OR1                         (_dprbase + REGB + 0x0064)
+#define BR1                         (_dprbase + REGB + 0x0060)
+
+#define OR2                         (_dprbase + REGB + 0x0074)
+#define BR2                         (_dprbase + REGB + 0x0070)
+
+#define OR3                         (_dprbase + REGB + 0x0084)
+#define BR3                         (_dprbase + REGB + 0x0080)
+
+#define OR4                         (_dprbase + REGB + 0x0094)
+#define BR4                         (_dprbase + REGB + 0x0090)
+
+#define OR5                         (_dprbase + REGB + 0x00A4)
+#define BR5                         (_dprbase + REGB + 0x00A0)
+
+#define OR6                         (_dprbase + REGB + 0x00b4)
+#define BR6                         (_dprbase + REGB + 0x00b0)
+
+#define OR7                         (_dprbase + REGB + 0x00c4)
+#define BR7                         (_dprbase + REGB + 0x00c0)
+
+#define MCR                         (_dprbase + REGB + 0x0000)
+#define AVR                         (_dprbase + REGB + 0x0008)
+
+#define SYPCR                       (_dprbase + REGB + 0x0022)
+
+#define PLLCR                       (_dprbase + REGB + 0x0010)
+#define CLKOCR                      (_dprbase + REGB + 0x000C)
+#define CDVCR                       (_dprbase + REGB + 0x0014)
+
+#define BKAR                        (_dprbase + REGB + 0x0030)
+#define BKCR                        (_dprbase + REGB + 0x0034)
+#define SWIV                        (_dprbase + REGB + 0x0023)
+#define PICR                        (_dprbase + REGB + 0x0026)
+#define PITR                        (_dprbase + REGB + 0x002A)
+
+/* Define for all memory configuration */
+#define MCU_SIM_GMR                 0x00000000
+#define SIM_OR_MASK                 0x0fffffff
+
+/* Defines for chip select zero - the flash */
+#define SIM_OR0_MASK                0x20000000
+#define SIM_BR0_MASK                0x00000001
+
+
+/* Defines for chip select one - the RAM */
+#define SIM_OR1_MASK                0x10000000
+#define SIM_BR1_MASK                0x00000001
+
+#define MCU_SIM_MBAR_ADRS           0x0003ff00
+#define MCU_SIM_MBAR_BA_MASK        0xfffff000
+#define MCU_SIM_MBAR_AS_MASK        0x00000001
+
+#define MCU_SIM_PEPAR               0x00B4
+    
+#define MCU_DISABLE_INTRPTS         0x2700
+#define MCU_SIM_AVR                 0x00
+    
+#define MCU_SIM_MCR                 0x00005cff
+
+#define MCU_SIM_CLKOCR              0x00
+#define MCU_SIM_PLLCR               0x8000
+#define MCU_SIM_CDVCR               0x0000
+
+#define MCU_SIM_SYPCR               0x0000
+#define MCU_SIM_SWIV                0x00
+#define MCU_SIM_PICR                0x0000
+#define MCU_SIM_PITR                0x0000
+
+
+#include <asm/m68360_regs.h>
+
+	
+/* By the time this RAM specific code begins to execute, DPRAM
+ * and DRAM should already be mapped and accessible. */
+
+	.text
+_start:
+_stext:
+    nop
+    ori.w   #MCU_DISABLE_INTRPTS,   %sr     /* disable interrupts: */
+    /* We should not need to setup the boot stack the reset should do it. */
+    movea.l	#_boot_stack,           %sp     /*set up stack at the end of DRAM:*/
+
+
+set_mbar_register:
+    moveq.l #0x07,                  %d1     /* Setup MBAR */
+    movec	%d1,                    %dfc
+
+    lea.l   MCU_SIM_MBAR_ADRS,      %a0
+    move.l  #_dprbase,              %d0
+    andi.l  #MCU_SIM_MBAR_BA_MASK,  %d0
+    ori.l   #MCU_SIM_MBAR_AS_MASK,  %d0
+    moves.l %d0,                    %a0@
+
+    moveq.l #0x05,                  %d1
+    movec.l %d1,                    %dfc
+
+/* Now we can begin to access registers in DPRAM */
+
+set_sim_mcr:
+    /* Set Module Configuration Register */
+    move.l  #MCU_SIM_MCR,           MCR
+
+/* to do:	Determine cause of reset */
+
+
+    /*
+    *       configure system clock MC68360 p. 6-40
+    *       (value +1)*osc/128 = system clock
+    *                    or
+    *       (value + 1)*osc = system clock
+    *       You do not need to divide the oscillator by 128 unless you want to.
+    */
+set_sim_clock:
+    move.w  #MCU_SIM_PLLCR,         PLLCR
+    move.b  #MCU_SIM_CLKOCR,        CLKOCR
+    move.w  #MCU_SIM_CDVCR,         CDVCR
+
+    // Wait for the PLL to settle
+    move.w      #16384, %d0
+pll_settle_wait:
+    subi.w       #1, %d0
+    bne	pll_settle_wait
+
+    /* Setup the system protection register, and watchdog timer register */
+
+    move.b      #MCU_SIM_SWIV,      SWIV
+    move.w      #MCU_SIM_PICR,      PICR
+    move.w      #MCU_SIM_PITR,      PITR
+    move.w      #MCU_SIM_SYPCR,     SYPCR
+
+/* Clear DPRAM - system + parameter */
+	movea.l	#_dprbase, %a0
+	movea.l	#_dprbase+0x2000, %a1
+
+	/* Copy 0 to %a0 until %a0 == %a1 */
+clear_dpram:
+	movel	#0, %a0@+
+	cmpal	%a0, %a1
+	bhi	clear_dpram
+
+configure_memory_controller:    
+    /*
+    *   Set up Global Memory Register (GMR)
+    */
+    move.l      #MCU_SIM_GMR,   %d0
+    move.l      %d0, GMR
+
+configure_chip_select_0:
+    move.l      #0x00400000,    %d0
+    subq.l      #0x01,          %d0
+    eori.l      #SIM_OR_MASK,   %d0
+    ori.l       #SIM_OR0_MASK,  %d0
+    move.l      %d0,            OR0
+
+    move.l      #__flashstart,  %d0
+    ori.l       #SIM_BR0_MASK,  %d0
+    move.l      %d0,            BR0
+
+    move.l      #0x0,           BR1
+    move.l      #0x0,           BR2
+    move.l      #0x0,           BR3
+    move.l      #0x0,           BR4
+    move.l      #0x0,           BR5
+    move.l      #0x0,           BR6
+    move.l      #0x0,           BR7
+
+    move.w      #MCU_SIM_PEPAR, PEPAR 
+
+/* point to vector table: */
+    move.l  #_romvec,   %a0
+    move.l	#_ramvec,   %a1
+copy_vectors:
+    move.l  %a0@,       %d0
+    move.l  %d0,        %a1@
+    move.l  %a0@,       %a1@
+    addq.l  #0x04,      %a0
+    addq.l  #0x04,      %a1
+    cmp.l   #_start,    %a0
+    blt     copy_vectors
+
+    move.l	#_ramvec, %a1
+    movec	%a1, %vbr
+
+
+	/* Copy data segment from ROM to RAM */
+	moveal	#__data_rom_start, %a0
+	moveal	#__data_start, %a1
+	moveal	#__data_end, %a2
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+LD1:
+    move.l  %a0@,   %d0
+    addq.l  #0x04,  %a0
+    move.l  %d0,    %a1@
+    addq.l  #0x04,  %a1
+    cmp.l   #__data_end,    %a1
+    blt     LD1
+
+	moveal	#__bss_start, %a0
+	moveal	#end, %a1
+
+	/* Copy 0 to %a0 until %a0 == %a1 */
+L1:
+	movel	#0, %a0@+
+	cmpal	%a0, %a1
+	bhi	L1
+
+load_quicc:
+    move.l  #_dprbase,  _quicc_base
+
+store_ram_size:
+    /* Set ram size information */
+    move.l  #_sdata,    _rambase
+    move.l  #end,       _ramstart
+    move.l  #__ramend,  %d0
+    sub.l   #0x1000,    %d0     /* Reserve 4K for stack space.*/
+    move.l  %d0,        _ramend /* Different from __ramend.*/
+
+store_flash_size:
+    /* Set rom size information */
+    move.l  #__flashend,    %d0
+    sub.l   #__flashstart,  %d0
+    move.l  %d0,            rom_length
+    
+	pea	0
+	pea	env
+	pea	%sp@(4)
+	pea	0
+
+	lea	init_thread_union, %a2
+	lea	0x2000(%a2), %sp
+
+lp:
+    jsr	start_kernel
+ /*   jmp lp */
+
+_exit:
+
+	jmp	_exit
+
+
+
+	.data
+    .align 4
+env:
+	.long	0
+_quicc_base:
+	.long	0
+_periph_base:
+	.long	0
+_ramvec:
+    .long   0
+_rambase:
+    .long   0
+_ramstart:
+    .long   0
+_ramend:
+    .long   0
+	.text
+
+    /*
+     * These are the exception vectors at boot up, they are copied into RAM
+     * and then overwritten as needed.
+     */
+ 
+.section ".data.initvect","awx"
+    .long   _boot_stack /* Reset: Initial Stack Pointer                 - 0.  */
+    .long   _start      /* Reset: Initial Program Counter               - 1.  */
+    .long   buserr      /* Bus Error                                    - 2.  */
+    .long   trap        /* Address Error                                - 3.  */
+    .long   trap        /* Illegal Instruction                          - 4.  */
+    .long   trap        /* Divide by zero                               - 5.  */
+    .long   trap        /* CHK, CHK2 Instructions                       - 6.  */
+    .long   trap        /* TRAPcc, TRAPV Instructions                   - 7.  */
+    .long   trap        /* Privilege Violation                          - 8.  */
+    .long   trap        /* Trace                                        - 9.  */
+    .long   trap        /* Line 1010 Emulator                           - 10. */
+    .long   trap        /* Line 1111 Emualtor                           - 11. */
+    .long   trap        /* Harware Breakpoint                           - 12. */
+    .long   trap        /* (Reserved for Coprocessor Protocol Violation)- 13. */
+    .long   trap        /* Format Error                                 - 14. */
+    .long   trap        /* Uninitialized Interrupt                      - 15. */
+    .long   trap        /* (Unassigned, Reserver)                       - 16. */
+    .long   trap        /* (Unassigned, Reserver)                       - 17. */
+    .long   trap        /* (Unassigned, Reserver)                       - 18. */
+    .long   trap        /* (Unassigned, Reserver)                       - 19. */
+    .long   trap        /* (Unassigned, Reserver)                       - 20. */
+    .long   trap        /* (Unassigned, Reserver)                       - 21. */
+    .long   trap        /* (Unassigned, Reserver)                       - 22. */
+    .long   trap        /* (Unassigned, Reserver)                       - 23. */
+    .long   trap        /* Spurious Interrupt                           - 24. */
+    .long   trap        /* Level 1 Interrupt Autovector                 - 25. */
+    .long   trap        /* Level 2 Interrupt Autovector                 - 26. */
+    .long   trap        /* Level 3 Interrupt Autovector                 - 27. */
+    .long   trap        /* Level 4 Interrupt Autovector                 - 28. */
+    .long   trap        /* Level 5 Interrupt Autovector                 - 29. */
+    .long   trap        /* Level 6 Interrupt Autovector                 - 30. */
+    .long   trap        /* Level 7 Interrupt Autovector                 - 31. */
+    .long   system_call /* Trap Instruction Vectors 0                   - 32. */
+    .long   trap        /* Trap Instruction Vectors 1                   - 33. */
+    .long   trap        /* Trap Instruction Vectors 2                   - 34. */
+    .long   trap        /* Trap Instruction Vectors 3                   - 35. */
+    .long   trap        /* Trap Instruction Vectors 4                   - 36. */
+    .long   trap        /* Trap Instruction Vectors 5                   - 37. */
+    .long   trap        /* Trap Instruction Vectors 6                   - 38. */
+    .long   trap        /* Trap Instruction Vectors 7                   - 39. */
+    .long   trap        /* Trap Instruction Vectors 8                   - 40. */
+    .long   trap        /* Trap Instruction Vectors 9                   - 41. */
+    .long   trap        /* Trap Instruction Vectors 10                  - 42. */
+    .long   trap        /* Trap Instruction Vectors 11                  - 43. */
+    .long   trap        /* Trap Instruction Vectors 12                  - 44. */
+    .long   trap        /* Trap Instruction Vectors 13                  - 45. */
+    .long   trap        /* Trap Instruction Vectors 14                  - 46. */
+    .long   trap        /* Trap Instruction Vectors 15                  - 47. */
+    .long   0           /* (Reserved for Coprocessor)                   - 48. */
+    .long   0           /* (Reserved for Coprocessor)                   - 49. */
+    .long   0           /* (Reserved for Coprocessor)                   - 50. */
+    .long   0           /* (Reserved for Coprocessor)                   - 51. */
+    .long   0           /* (Reserved for Coprocessor)                   - 52. */
+    .long   0           /* (Reserved for Coprocessor)                   - 53. */
+    .long   0           /* (Reserved for Coprocessor)                   - 54. */
+    .long   0           /* (Reserved for Coprocessor)                   - 55. */
+    .long   0           /* (Reserved for Coprocessor)                   - 56. */
+    .long   0           /* (Reserved for Coprocessor)                   - 57. */
+    .long   0           /* (Reserved for Coprocessor)                   - 58. */
+    .long   0           /* (Unassigned, Reserved)                       - 59. */
+    .long   0           /* (Unassigned, Reserved)                       - 60. */
+    .long   0           /* (Unassigned, Reserved)                       - 61. */
+    .long   0           /* (Unassigned, Reserved)                       - 62. */
+    .long   0           /* (Unassigned, Reserved)                       - 63. */
+    /*                  The assignment of these vectors to the CPM is         */
+    /*                  dependant on the configuration of the CPM vba         */
+    /*                          fields.                                       */
+    .long   0           /* (User-Defined Vectors 1) CPM Error           - 64. */
+    .long   0           /* (User-Defined Vectors 2) CPM Parallel IO PC11- 65. */
+    .long   0           /* (User-Defined Vectors 3) CPM Parallel IO PC10- 66. */
+    .long   0           /* (User-Defined Vectors 4) CPM SMC2 / PIP      - 67. */
+    .long   0           /* (User-Defined Vectors 5) CPM SMC1            - 68. */
+    .long   0           /* (User-Defined Vectors 6) CPM SPI             - 69. */
+    .long   0           /* (User-Defined Vectors 7) CPM Parallel IO PC9 - 70. */
+    .long   0           /* (User-Defined Vectors 8) CPM Timer 4         - 71. */
+    .long   0           /* (User-Defined Vectors 9) CPM Reserved        - 72. */
+    .long   0           /* (User-Defined Vectors 10) CPM Parallel IO PC8- 73. */
+    .long   0           /* (User-Defined Vectors 11) CPM Parallel IO PC7- 74. */
+    .long   0           /* (User-Defined Vectors 12) CPM Parallel IO PC6- 75. */
+    .long   0           /* (User-Defined Vectors 13) CPM Timer 3        - 76. */
+    .long   0           /* (User-Defined Vectors 14) CPM Reserved       - 77. */
+    .long   0           /* (User-Defined Vectors 15) CPM Parallel IO PC5- 78. */
+    .long   0           /* (User-Defined Vectors 16) CPM Parallel IO PC4- 79. */
+    .long   0           /* (User-Defined Vectors 17) CPM Reserved       - 80. */
+    .long   0           /* (User-Defined Vectors 18) CPM RISC Timer Tbl - 81. */
+    .long   0           /* (User-Defined Vectors 19) CPM Timer 2        - 82. */
+    .long   0           /* (User-Defined Vectors 21) CPM Reserved       - 83. */
+    .long   0           /* (User-Defined Vectors 22) CPM IDMA2          - 84. */
+    .long   0           /* (User-Defined Vectors 23) CPM IDMA1          - 85. */
+    .long   0           /* (User-Defined Vectors 24) CPM SDMA Bus Err   - 86. */
+    .long   0           /* (User-Defined Vectors 25) CPM Parallel IO PC3- 87. */
+    .long   0           /* (User-Defined Vectors 26) CPM Parallel IO PC2- 88. */
+    .long   0           /* (User-Defined Vectors 27) CPM Timer 1        - 89. */
+    .long   0           /* (User-Defined Vectors 28) CPM Parallel IO PC1- 90. */
+    .long   0           /* (User-Defined Vectors 29) CPM SCC 4          - 91. */
+    .long   0           /* (User-Defined Vectors 30) CPM SCC 3          - 92. */
+    .long   0           /* (User-Defined Vectors 31) CPM SCC 2          - 93. */
+    .long   0           /* (User-Defined Vectors 32) CPM SCC 1          - 94. */
+    .long   0           /* (User-Defined Vectors 33) CPM Parallel IO PC0- 95. */
+    /*                  I don't think anything uses the vectors after here.   */
+    .long   0           /* (User-Defined Vectors 34)                    - 96. */
+    .long   0,0,0,0,0               /* (User-Defined Vectors 35  -  39). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 40  -  49). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 50  -  59). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 60  -  69). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 70  -  79). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 80  -  89). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 90  -  99). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 100 - 109). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 110 - 119). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 120 - 129). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 130 - 139). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 140 - 149). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 150 - 159). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 160 - 169). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 170 - 179). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 180 - 189). */
+    .long   0,0,0                   /* (User-Defined Vectors 190 - 192). */
+.text
+ignore: rte
diff -Nru a/arch/m68knommu/platform/68360/uCquicc/ram.ld b/arch/m68knommu/platform/68360/uCquicc/ram.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68360/uCquicc/ram.ld	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,113 @@
+MEMORY
+{
+    romvec   : ORIGIN = 0x00000000,                 LENGTH = 1028
+    flash    : ORIGIN = 1028,                       LENGTH = 0x00080000 - 1028
+    eflash   : ORIGIN = 0x00000000 + 0x00100000,    LENGTH = 1
+    ramvec   : ORIGIN = 0x00200000,                 LENGTH = 1028
+    ram      : ORIGIN = 0x00200000 + 1028,          LENGTH = 0x00080000 - 1028
+    eram     : ORIGIN = 0x00200000 + 0x00080000,    LENGTH = 1
+    dpram    : ORIGIN = 0xffffe000,                 LENGTH = 0x00002000
+}
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS
+{
+    .dpram :
+    {
+        _dprbase = . ;
+    } > dpram
+
+    .romvec :
+    {
+        _romvec = . ;
+        __flashstart = . ;
+        *(.data.initvect)
+        . = ALIGN(4);
+    } > romvec
+
+    .text :
+    {
+        text_start = . ;
+        *(.text)
+        *(.exit.text)
+        *(.text.*)
+        *(.rodata)
+        *(.fixup)
+	*(.kstrtab)
+	__start___ksymtab = . ;
+	*(__ksymtab)
+        __stop___ksymtab = . ;
+	__start___ex_table = . ;
+	*(___ex_table)
+	__stop___ex_table = . ;
+        . = ALIGN(4) ;_etext = . ;
+        __data_rom_start = ALIGN ( 4 ) ;
+    } > flash
+   
+    .eflash :
+    {
+        __flashend = . ;
+    } > eflash
+
+
+    .ramvec :
+    {
+        __ramstart = . ;
+        _ramvec = . ;
+    } > ramvec
+   
+    .data :
+    {
+        _sdata = . ;
+        __data_start = . ;
+       . = ALIGN(0x2000) ;
+       *(.data.init_task)
+       . = ALIGN(0x2000) ;
+        *(.data)
+        *(.data.*)
+        *(.setup.init)
+       *(.exitcall.exit)
+       . = ALIGN(4096) ;
+        __init_begin = .;
+        *(.init.text)
+        *(.init.data)
+        . = ALIGN(16);
+        __setup_start = .;
+        *(.init.setup)
+        __setup_end = .;
+        __initcall_start = .;
+	*(.initcall1.init)
+	*(.initcall2.init)
+	*(.initcall3.init)
+	*(.initcall4.init)
+	*(.initcall5.init)
+	*(.initcall6.init)
+	*(.initcall7.init)
+        __initcall_end = .;
+        . = ALIGN(4) ;
+	__init_end = .;      
+        _edata = . ;
+        edata = .;
+    } > ram
+
+    .bss :
+    {
+        _sbss = ALIGN( 0x10 ) ;
+        __bss_start = ALIGN( 0x10 ) ;
+        __data_end = ALIGN( 0x10 ) ;
+        *(.bss)
+        *(COMMON)
+            _ebss = . ;
+        __bss_end = . ;
+        end = ALIGN( 0x10 ) ;
+        _end = ALIGN( 0x10 ) ;
+    } > ram
+
+    .eram :
+    {
+        _boot_stack = . - 4;
+        __ramend = . ;
+
+    } > eram
+}
diff -Nru a/arch/m68knommu/platform/68360/uCquicc/rom.ld b/arch/m68knommu/platform/68360/uCquicc/rom.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68360/uCquicc/rom.ld	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,113 @@
+MEMORY
+{
+    romvec   : ORIGIN = 0x00000000,                 LENGTH = 1028
+    flash    : ORIGIN = 1028,                       LENGTH = 0x00200000 - 1028
+    eflash   : ORIGIN = 0x00000000 + 0x00200000,    LENGTH = 1
+    ramvec   : ORIGIN = 0x00200000,                 LENGTH = 1028
+    ram      : ORIGIN = 0x00200000 + 1028,          LENGTH = 0x00200000 - 1028
+    eram     : ORIGIN = 0x00200000 + 0x00200000,    LENGTH = 1
+    dpram    : ORIGIN = 0xffffe000,                 LENGTH = 0x00002000
+}
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS
+{
+    .dpram :
+    {
+        _dprbase = . ;
+    } > dpram
+
+    .romvec :
+    {
+        _romvec = . ;
+        __flashstart = . ;
+        *(.data.initvect)
+        . = ALIGN(4);
+    } > romvec
+
+    .text :
+    {
+        text_start = . ;
+        *(.text)
+        *(.exit.text)
+        *(.text.*)
+        *(.rodata)
+        *(.fixup)
+        *(.kstrtab)
+        __start___ksymtab = . ;
+        *(__ksymtab)
+        __stop___ksymtab = . ;
+        __start___ex_table = . ;
+        *(___ex_table)
+        __stop___ex_table = . ;
+        . = ALIGN(4) ;_etext = . ;
+        __data_rom_start = ALIGN ( 4 ) ;
+    } > flash
+   
+    .eflash :
+    {
+        __flashend = . ;
+    } > eflash
+
+
+    .ramvec :
+    {
+        __ramstart = . ;
+        _ramvec = . ;
+    } > ramvec
+   
+    .data :
+    {
+        _sdata = . ;
+        __data_start = . ;
+       . = ALIGN(0x2000) ;
+       *(.data.init_task)
+       . = ALIGN(0x2000) ;
+        *(.data)
+        *(.data.*)
+        *(.setup.init)
+       *(.exitcall.exit)
+       . = ALIGN(4096) ;
+        __init_begin = .;
+        *(.init.text)
+        *(.init.data)
+        . = ALIGN(16);
+        __setup_start = .;
+        *(.init.setup)
+        __setup_end = .;
+        __initcall_start = .;
+	*(.initcall1.init)
+	*(.initcall2.init)
+	*(.initcall3.init)
+	*(.initcall4.init)
+	*(.initcall5.init)
+	*(.initcall6.init)
+	*(.initcall7.init)
+        __initcall_end = .;
+        . = ALIGN(4) ;
+        __init_end = .;      
+        _edata = . ;
+        edata = .;
+    } > ram
+
+    .bss :
+    {
+        _sbss = ALIGN( 0x10 ) ;
+        __bss_start = ALIGN( 0x10 ) ;
+        __data_end = ALIGN( 0x10 ) ;
+        *(.bss)
+        *(COMMON)
+        _ebss = . ;
+        __bss_end = . ;
+        end = ALIGN( 0x10 ) ;
+        _end = ALIGN( 0x10 ) ;
+    } > ram
+
+    .eram :
+    {
+        _boot_stack = . - 4;
+        __ramend = . ;
+
+    } > eram
+}
diff -Nru a/arch/m68knommu/platform/68EZ328/Makefile b/arch/m68knommu/platform/68EZ328/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68EZ328/Makefile	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,14 @@
+#
+# Makefile for arch/m68knommu/platform/68EZ328.
+#
+
+obj-y := config.o
+
+EXTRA_TARGETS := $(BOARD)/bootlogo.rh $(BOARD)/crt0_$(MODEL).o
+
+include $(TOPDIR)/Rules.make
+
+$(obj)/$(BOARD)/bootlogo.rh: $(src)/bootlogo.h
+	perl $(src)/../68328/bootlogo.pl < $(src)/bootlogo.h \
+		> $(obj)/$(BOARD)/bootlogo.rh
+
diff -Nru a/arch/m68knommu/platform/68EZ328/bootlogo.h b/arch/m68knommu/platform/68EZ328/bootlogo.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68EZ328/bootlogo.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,3204 @@
+#define splash_width 640
+#define splash_height 480
+static unsigned char splash_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xf8, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x7f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x03, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xfe, 0xff, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x7c, 0x00, 0xe0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+  0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0xe0, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x3f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3e, 0xf8, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
+  0x00, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0xfe, 0xff, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00,
+  0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x7f, 0xe0,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xe0, 0xff,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xe0, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x7f, 0xe0,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xe0, 0xff,
+  0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x7f, 0xe0,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xe0, 0xff, 0x07, 0xfe, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0xff, 0x01, 0xf8, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff,
+  0x00, 0xf0, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0xe0, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x03,
+  0x3f, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x3f, 0x00, 0xc0, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x0f, 0xfc, 0x00, 0x00, 0x00,
+  0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f,
+  0x00, 0x80, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0xff, 0xff, 0xff, 0x3f, 0xf0, 0x01, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0x80, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0xc0, 0xff,
+  0xc1, 0x03, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0xfc, 0x07, 0x07, 0x00, 0x00,
+  0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f,
+  0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0x07, 0x00, 0x00, 0xe0, 0x07, 0x0e, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0x00,
+  0x3f, 0x1c, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x38, 0x00, 0x00,
+  0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f,
+  0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e,
+  0x00, 0x00, 0x00, 0x00, 0x78, 0x70, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0xe0, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc3, 0x01, 0x00,
+  0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f,
+  0x00, 0x80, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x00, 0xf8, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0x80, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x87, 0x03, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x3f, 0x00, 0xc0, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x07, 0x00,
+  0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f,
+  0x00, 0xe0, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0e, 0x00, 0xf0, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf0, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x30, 0x0c, 0x00, 0xf0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0xff, 0x01, 0xf8, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1c, 0x00,
+  0xf0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x07, 0xfe, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x38, 0x00, 0xf0, 0xff, 0x7f, 0xe0,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x80, 0x38, 0x00, 0xf0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x00,
+  0xe0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00, 0xe0, 0xff, 0x7f, 0xe0,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe2, 0x00, 0xe0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00,
+  0xe0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0xc0, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x01, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01,
+  0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x80, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0x03, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03,
+  0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0x07, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07,
+  0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0xfe, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0x07, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07,
+  0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0xf8, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0x07, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07,
+  0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0xf0, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x07, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+  0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x9f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1c, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
+  0xf8, 0xff, 0x1f, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x80, 0xff, 0xff, 0x00,
+  0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x38, 0x00, 0xfe, 0xff, 0x0f, 0x20, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0xf8, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xc0, 0xff, 0xff,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0xfc, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x03, 0x00, 0xe0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff,
+  0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xfc, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x1f, 0xc0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
+  0xfe, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xf0, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x38, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0xf8, 0xff, 0x01, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xc0, 0xff, 0x01,
+  0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0xfc, 0x01, 0xff, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x41, 0x08, 0x04, 0xb3, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0xe0, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x41, 0x08, 0x04, 0xb3, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x18, 0x8e, 0x31, 0x7b, 0x30,
+  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0x00, 0x18, 0x8e, 0x31, 0x7b, 0x30, 0x30, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0xf8,
+  0x41, 0xc6, 0x84, 0x0c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0xf8, 0x41, 0xc6, 0x84, 0x0c,
+  0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0x0f, 0x00, 0x00, 0x18, 0x0c, 0x08, 0x00, 0x40, 0xc0, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0xe4,
+  0xb1, 0xc1, 0x98, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x09, 0x00, 0x00, 0xe4, 0xb1, 0xc1, 0x98, 0x00,
+  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+  0x08, 0x00, 0x00, 0x1c, 0x02, 0x08, 0x04, 0x4c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0xff, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x1c,
+  0x02, 0x08, 0x04, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x1f, 0xc0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x10, 0x80,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x64, 0x4c, 0x00, 0x00, 0x00,
+  0x36, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x09, 0x00, 0x00, 0x64, 0x4c, 0x00, 0x00, 0x00, 0x36, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0xff, 0x03, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x9c,
+  0x01, 0x08, 0x83, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0xf0, 0xff,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x64, 0x8c, 0x01, 0x18, 0x40,
+  0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x0f, 0x00, 0x00, 0x64, 0x8c, 0x01, 0x18, 0x40, 0x30, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0xff, 0x03, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x9b,
+  0x01, 0xc0, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x40,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x09, 0x00, 0x00, 0x9b, 0x01, 0xc0, 0x00, 0x00,
+  0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+  0x00, 0x00, 0x00, 0x07, 0x32, 0x06, 0x18, 0x43, 0x00, 0x06, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xf0, 0xc1, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x02, 0x02, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x07,
+  0x32, 0x06, 0x18, 0x43, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x10, 0xe0,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x70, 0x08, 0x00, 0x00, 0x7b, 0x00, 0x30, 0x03, 0x0c,
+  0x08, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0x07, 0x03, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x09, 0x00, 0xc0, 0x84, 0x8d, 0x01, 0x80, 0x00, 0xc0, 0x06, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0xfd, 0x03, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0xc0, 0x84,
+  0x8d, 0x01, 0x80, 0x00, 0xc0, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfd, 0x03, 0xf0, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xc0, 0x1b, 0x00, 0x30, 0x00, 0x40,
+  0x08, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xfc, 0x01, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0xc0, 0x1b, 0x00, 0x30, 0x00, 0x40, 0x08, 0x18, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x07, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+  0xf8, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xc0, 0x64,
+  0x42, 0x06, 0x1b, 0x03, 0x00, 0x61, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0xc0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x10, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0xc0, 0x64, 0x42, 0x06, 0x1b, 0x03,
+  0x00, 0x61, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0xff, 0x03, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x0f, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x80, 0x30, 0x08, 0x86, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0x3f, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0x1b,
+  0x00, 0x00, 0x80, 0x30, 0x08, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xc3, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0xe0, 0x84, 0x31, 0x30, 0x04, 0x80,
+  0xc1, 0x18, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1c, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x09, 0x00, 0xc0, 0x63, 0x02, 0x06, 0x00, 0x00, 0x00, 0x60, 0x6c, 0xfc,
+  0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+  0xe0, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x08, 0x00, 0xc0, 0x63,
+  0x02, 0x06, 0x00, 0x00, 0x00, 0x60, 0x6c, 0xfc, 0xff, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0xff, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xe0, 0x1c, 0x40, 0x00, 0x1b, 0x4c,
+  0x06, 0x81, 0x80, 0xfd, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x70, 0x00, 0xf0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0x00, 0xe0, 0x1c, 0x40, 0x00, 0x1b, 0x4c, 0x06, 0x81, 0x80, 0xfd,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0x00, 0x80, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x09, 0x00, 0x20, 0x63,
+  0x0c, 0x08, 0x80, 0x00, 0x30, 0x06, 0x0c, 0xfc, 0xff, 0x7f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x30, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x20, 0x63, 0x0c, 0x08, 0x80, 0x00,
+  0x30, 0x06, 0x0c, 0xfc, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x0f, 0x00, 0xd8, 0x84, 0x01, 0xc0, 0x00, 0x00, 0x06, 0x00, 0x80, 0xf1,
+  0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0xf8, 0x1b,
+  0x40, 0x08, 0x84, 0x0c, 0xc0, 0x18, 0x13, 0xcc, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xe0, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0xf8, 0x1b, 0x40, 0x08, 0x84, 0x0c,
+  0xc0, 0x18, 0x13, 0xcc, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0xf0, 0xe4, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x09, 0x00, 0x38, 0x80, 0x01, 0x00, 0x18, 0x30, 0x06, 0x01, 0x00, 0xc0,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+  0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0x07, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x38, 0x80,
+  0x01, 0x00, 0x18, 0x30, 0x06, 0x01, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x10, 0x84,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xd8, 0x1f, 0x30, 0x36, 0x80, 0x00,
+  0x00, 0x00, 0x03, 0xf2, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x4f, 0x0e, 0x00, 0x10, 0x84, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x08, 0x00, 0xd8, 0x1f, 0x30, 0x36, 0x80, 0x00, 0x00, 0x00, 0x03, 0xf2,
+  0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
+  0x08, 0x00, 0x10, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x09, 0x00, 0x3e, 0x00,
+  0x82, 0x01, 0x03, 0x40, 0x30, 0x98, 0x10, 0xf0, 0xe7, 0xff, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x1f, 0xc0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x08, 0x00, 0x10, 0xe4,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0xe6, 0x1b, 0x00, 0x00, 0x18, 0x0c,
+  0x00, 0x00, 0x00, 0xfc, 0xff, 0xfb, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x41, 0x08, 0x00, 0x30, 0x7c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0xe6, 0x1b, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x00, 0xfc,
+  0xff, 0xfb, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+  0x08, 0x00, 0x20, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x1e, 0x64,
+  0x30, 0xc6, 0x80, 0x80, 0x09, 0x06, 0x63, 0xfe, 0xf9, 0xff, 0xff, 0xff,
+  0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x30, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xf8, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0e, 0x00, 0xc0, 0x3c,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x1e, 0x64, 0x30, 0xc6, 0x80, 0x80,
+  0x09, 0x06, 0x63, 0xfe, 0xf9, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1c, 0x80, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc3, 0x07, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0e, 0x00, 0x39, 0x03, 0x00, 0x00, 0x04, 0x0c, 0xc0, 0x60, 0x80, 0x3f,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+  0x00, 0xfc, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x39, 0x03,
+  0x00, 0x00, 0x04, 0x0c, 0xc0, 0x60, 0x80, 0x3f, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x3e, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x80, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0xe7, 0x04, 0x42, 0xc6, 0x00, 0x00,
+  0x00, 0x00, 0xec, 0xcf, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x0f, 0xc0, 0x1f, 0x80, 0x01, 0x00, 0x98, 0x4c, 0x06, 0x06, 0xf0, 0x01,
+  0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0x01, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x09, 0xc0, 0x1f, 0x80,
+  0x01, 0x00, 0x98, 0x4c, 0x06, 0x06, 0xf0, 0x01, 0x00, 0xe0, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3f, 0x08, 0xc0, 0xe6, 0x04, 0x0c, 0x08, 0x00, 0x00,
+  0xc0, 0x60, 0x7c, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x1f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
+  0x00, 0xc0, 0xe6, 0x04, 0x0c, 0x08, 0x00, 0x00, 0xc0, 0x60, 0x7c, 0x00,
+  0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xc0, 0x19, 0x60,
+  0x40, 0x00, 0x63, 0x30, 0x08, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0xff, 0xf3, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x3f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x09, 0xc0, 0x19, 0x60, 0x40, 0x00, 0x63, 0x30,
+  0x08, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xf3, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x78, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0f, 0xc0, 0x27, 0x03, 0x00, 0x30, 0x00, 0x03, 0x00, 0xe6, 0x1f, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0xcf, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0xc0, 0x27, 0x03,
+  0x00, 0x30, 0x00, 0x03, 0x00, 0xe6, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff,
+  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x0f, 0xc0, 0xde, 0x04, 0x0c, 0x06, 0x03, 0x80,
+  0xc1, 0xf8, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0f, 0x03, 0x00, 0xf8, 0xff, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x0f, 0xc0, 0x19, 0x00, 0x32, 0x00, 0x60, 0x30, 0x08, 0xff, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x9f,
+  0x07, 0x00, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x09, 0xc0, 0x19, 0x00,
+  0x32, 0x00, 0x60, 0x30, 0x08, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x9f, 0x07, 0x00, 0x18, 0x40,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3f, 0x00, 0xc0, 0x27, 0x63, 0x80, 0x31, 0x04, 0x03,
+  0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+  0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1c, 0xfe, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x1f, 0x07, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
+  0x00, 0xc0, 0x27, 0x63, 0x80, 0x31, 0x04, 0x03, 0xf0, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0x7f, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
+  0xe0, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x31,
+  0x04, 0x00, 0x10, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x08, 0x00, 0xd9, 0x04,
+  0x00, 0x08, 0x00, 0x80, 0xf9, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xf0, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f, 0x1e, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0xfe, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x04, 0x00, 0x60, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x09, 0x00, 0xd9, 0x04, 0x00, 0x08, 0x00, 0x80,
+  0xf9, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0x7f, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x78, 0x00, 0xf0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0f, 0xc0, 0x27, 0x00, 0x30, 0xc0, 0x60, 0xb0, 0xff, 0x7f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+  0x60, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0xde, 0x9b,
+  0x8d, 0x01, 0x04, 0xc3, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x80, 0xf1, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x03, 0x00, 0xf0, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0xde, 0x9b, 0x8d, 0x01, 0x04, 0xc3,
+  0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xf1, 0xff,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3e, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xc0, 0x39, 0x04, 0x00, 0xc8, 0x00, 0xfc, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xf8, 0xff, 0x3f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0xc0, 0x39, 0x04,
+  0x00, 0xc8, 0x00, 0xfc, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc6, 0xf8, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1f, 0x00, 0xc0, 0xc7, 0x60, 0x42, 0x00, 0x60, 0xff,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
+  0x00, 0xc0, 0xc7, 0x60, 0x42, 0x00, 0x60, 0xff, 0xff, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0xc0, 0xff, 0x07,
+  0xb0, 0x09, 0xe4, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x30, 0x00, 0xfc, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0e, 0x00, 0xc0, 0xde, 0x78, 0x02, 0x00, 0xfb, 0xff,
+  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0xff, 0x1f, 0xf8, 0xff, 0xff, 0x1f, 0xf0, 0xff, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xc0, 0xde, 0x78, 0x02, 0x00, 0xfb, 0xff, 0xff, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x1f, 0xf8,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x08,
+  0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0x3f, 0x07,
+  0xb0, 0xc9, 0xf8, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xc0, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0x3f, 0x07, 0xb0, 0xc9, 0xf8, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
+  0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x0f, 0x00, 0xe7, 0xfb, 0x43, 0x30, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00,
+  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x07, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0xe7, 0xfb,
+  0x43, 0x30, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x08, 0x70, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0xe0, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0xfe, 0x1c, 0xb2, 0x0f, 0xe0, 0xff,
+  0x07, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xc0, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x00, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0xf8, 0xe7, 0xfd, 0x01, 0xe0, 0xff, 0x07, 0x00, 0xe0, 0xff,
+  0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xe0,
+  0xb1, 0x3f, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0xf8,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0xc0, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xf8, 0xe7,
+  0xfd, 0x01, 0xe0, 0xff, 0x07, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xe0, 0xb1, 0x3f, 0x00, 0x00,
+  0xf8, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x80, 0xff,
+  0x01, 0x00, 0xe0, 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x98, 0x4f, 0x0e, 0x18, 0x00, 0xf8, 0xff, 0xff, 0xff,
+  0x07, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x80, 0xff, 0x01, 0x00, 0xe0, 0x03,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+  0x4f, 0x0e, 0xf8, 0x1f, 0xf6, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x08,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xf8, 0xff,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb1, 0x01, 0xff, 0x1f,
+  0xf6, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x1f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x04, 0x08, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0xb1, 0x01, 0xff, 0x7f, 0xc0, 0xff, 0xff, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0xe0, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
+  0x00, 0xce, 0xff, 0x7f, 0xc0, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0xe3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0xe0, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0xce, 0xff, 0x7f,
+  0x00, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0xc0, 0xff, 0x3f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x20, 0x1b, 0xb2, 0x31, 0xff, 0x7f, 0x00, 0xff, 0xff, 0xff,
+  0x3f, 0x00, 0x00, 0xe0, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x01, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0xc0, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x1c,
+  0x00, 0xc0, 0xff, 0x73, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xf0,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e,
+  0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xc0, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x1c, 0x00, 0xc0, 0x7f, 0x1c,
+  0x30, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x78, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x38, 0x87, 0x31, 0x06, 0x7c, 0x1c, 0x30, 0xff, 0xff, 0xff,
+  0xff, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x87,
+  0x31, 0x06, 0xfc, 0x0f, 0xc8, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x38,
+  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+  0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xc0, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe6, 0x04, 0x00, 0x30, 0xe3, 0x0f,
+  0xc8, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0xe0, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x30, 0xe6, 0x04, 0x00, 0x30, 0x03, 0x00, 0xf0, 0xff, 0xff, 0xff,
+  0xff, 0x03, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0x07, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1b,
+  0x4c, 0x00, 0x04, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0xc0, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x07, 0x04, 0x00, 0x06, 0x18, 0x80,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0f, 0x0e, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x02, 0x07, 0x04, 0x00, 0x06, 0x78, 0xf3, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0xf8, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x08, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3e, 0x04,
+  0x02, 0x30, 0x60, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xf8,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0xc0, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3e, 0x04, 0x02, 0x30, 0xe0, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc6, 0x04, 0x40, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x08, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x04,
+  0x40, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x08,
+  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x39, 0x67, 0x00, 0x06, 0xe0, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x06, 0x04, 0x30, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x04,
+  0x30, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x08,
+  0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x1f, 0x00, 0x7e, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3e, 0x9b, 0x01, 0x30, 0xe0, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x1f, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x30, 0x3e, 0x9b, 0x01, 0x30, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x1c, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x02, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x01, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x1c,
+  0x0c, 0x06, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x38,
+  0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xe0,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0xf0, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x1c, 0x0c, 0x06, 0xfb, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x68, 0x7c, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf8, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x38, 0x18, 0x00, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0xc0, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x18, 0xfe, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0xff, 0x03, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc6, 0x9b,
+  0x81, 0x01, 0x60, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x80,
+  0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xc0, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc6, 0x9b, 0x81, 0x01, 0x00, 0x00,
+  0xf6, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x38, 0x78, 0x0c, 0x30, 0x04, 0x00, 0xf6, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0xe8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+  0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x78,
+  0x0c, 0x30, 0x04, 0x00, 0xc8, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xf8,
+  0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x80, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x64, 0x40, 0x00, 0x1c, 0x00,
+  0xc8, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xf8, 0x58, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x04, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0x64, 0x40, 0x00, 0xfc, 0x03, 0xc0, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0x78, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x08, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+  0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xe0,
+  0x01, 0x36, 0xfc, 0x03, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x38,
+  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x80, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xe0, 0x01, 0x36, 0xfc, 0x1f,
+  0x30, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x8f, 0x01, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc6, 0x87, 0x0f, 0x00, 0xff, 0x1f, 0x30, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0xcf, 0x03, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+  0x40, 0xc0, 0xff, 0x7f, 0xc0, 0xfe, 0xff, 0xff, 0xff, 0x07, 0x00, 0x08,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xcf, 0x03, 0x00, 0xff,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xc0, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x40, 0xc0, 0xff, 0x7f,
+  0x00, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x8f, 0x01, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x0e, 0xc6, 0xff, 0x7f, 0x00, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x0e, 0xc6, 0xff, 0x7f, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0xf0, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x9c, 0x01, 0x30, 0xff, 0x7f,
+  0x00, 0xfe, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x20, 0x9c, 0x01, 0x30, 0xff, 0x63, 0x30, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x08, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x07, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+  0x4c, 0x00, 0xff, 0x63, 0x30, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0xff,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3e, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, 0x31, 0xfc, 0x1f,
+  0x00, 0xff, 0xff, 0xfd, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xb2, 0x31, 0xfc, 0x0f, 0x00, 0xff, 0xff, 0x03,
+  0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0e, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+  0x41, 0x00, 0xe0, 0x0f, 0x00, 0xff, 0xff, 0x03, 0xff, 0x03, 0x00, 0x38,
+  0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x41, 0x00, 0x00, 0x80,
+  0xc9, 0xf9, 0xff, 0x3d, 0xff, 0x03, 0x00, 0x78, 0xc0, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x60, 0x32, 0x08, 0x00, 0x80, 0xc9, 0xf9, 0xff, 0x3d,
+  0xff, 0x03, 0x00, 0xf8, 0xc0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x02, 0x00, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+  0x32, 0x08, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xcf, 0xff, 0x00, 0x00, 0xf8,
+  0x81, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0xff,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xe0, 0x01, 0xf8, 0x00, 0x00,
+  0xf0, 0xff, 0xff, 0xcf, 0xff, 0x00, 0x00, 0x38, 0x03, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x60, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x03, 0x80, 0xff, 0xff, 0xff, 0xff,
+  0x3f, 0x00, 0x00, 0x38, 0x06, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0c, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0xff, 0xff, 0x03, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x38,
+  0x1e, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x18, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0xff,
+  0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x03, 0xfc,
+  0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x38, 0xfc, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x70, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x1f, 0x00, 0x00, 0x38, 0xf8, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+  0x80, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x78,
+  0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xe0, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff,
+  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0xf8, 0xc1, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x60, 0xf8, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
+  0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xc0, 0xff,
+  0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x67,
+  0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf8,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x13, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xc0, 0xff,
+  0xff, 0xff, 0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x67, 0xfe, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0xff, 0xff, 0x98, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
+  0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0x0f, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x98,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0xf8, 0xff,
+  0xff, 0xff, 0x7f, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x3f, 0xe7, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0xff, 0xfc, 0xff, 0xff, 0xff, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0xff, 0x3f, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+  0x00, 0xc0, 0xff, 0x67, 0x8c, 0xf9, 0xfb, 0x73, 0x00, 0x67, 0x10, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xf8,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xc0, 0xff, 0x67,
+  0x8c, 0xf9, 0xfb, 0x73, 0x00, 0x67, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0xe7, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0xc0, 0x27, 0xfc, 0x73, 0xc6, 0x1c, 0x8c,
+  0x37, 0x80, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff,
+  0xff, 0xff, 0x1f, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0x00, 0xc0, 0x27, 0xfc, 0x73, 0xc6, 0x1c, 0x8c, 0x37, 0x80, 0x0c, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xfc,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0xc0, 0xfe, 0x03,
+  0x8c, 0x09, 0xe3, 0x73, 0xc8, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0xc0, 0xfe, 0x03, 0x8c, 0x09, 0xe3, 0x73,
+  0xc8, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x08, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0xc0, 0x27, 0xe7, 0x31, 0x36, 0x04, 0x8c, 0x01, 0x60, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+  0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0xc0, 0xde, 0x18,
+  0x42, 0xc0, 0x98, 0x30, 0x08, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0xc0, 0xde, 0x18, 0x42, 0xc0, 0x98, 0x30,
+  0x08, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0xc0, 0x27, 0x63, 0x00, 0x08, 0x63, 0x03, 0x06, 0x60, 0x10, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x27, 0x63,
+  0x00, 0x08, 0x63, 0x03, 0x06, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0xd9, 0x04, 0xb2, 0x01, 0x00, 0xb0,
+  0x31, 0x19, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf9, 0xff,
+  0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x08, 0xc0, 0xd9, 0x04, 0xb2, 0x01, 0x00, 0xb0, 0x31, 0x19, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0c, 0xc0, 0x1e, 0x63,
+  0x00, 0x30, 0x04, 0x03, 0xc8, 0x60, 0x00, 0x0e, 0x00, 0x00, 0xfc, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x0e, 0xc0, 0xe1, 0x18, 0x80, 0x01, 0x60, 0xb0,
+  0x01, 0xe7, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+  0x0f, 0xc0, 0xe1, 0x18, 0x80, 0x01, 0x60, 0xb0, 0x01, 0xe7, 0xf3, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x04, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x0f, 0xc0, 0x1e, 0x03,
+  0x02, 0x08, 0x04, 0x00, 0xc8, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xd8, 0x0f, 0xc0, 0x1e, 0x03, 0x02, 0x08, 0x04, 0x00,
+  0xc8, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xc0, 0x0f, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x0b, 0x00, 0x21, 0x64, 0x40, 0xc0, 0x00, 0xb3, 0xf1, 0xfe, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xfb, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x21, 0x64,
+  0x40, 0xc0, 0x00, 0xb3, 0xf1, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xfb, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfc, 0xfb, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfd, 0x00, 0xc0, 0xdf, 0x00, 0x00, 0x06, 0x60, 0x00,
+  0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0xf9, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf,
+  0x01, 0xc0, 0xdf, 0x00, 0x00, 0x06, 0x60, 0x00, 0x0e, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xf0, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x0b, 0xc0, 0xc0, 0x84,
+  0x31, 0xc0, 0x00, 0x4c, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x83, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x1e, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0f, 0x0e, 0xc0, 0x3f, 0x18, 0x00, 0x06, 0x84, 0x80,
+  0x09, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xc3, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+  0x0c, 0xc0, 0x3f, 0x18, 0x00, 0x06, 0x84, 0x80, 0x09, 0xff, 0xff, 0x3f,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+  0xc1, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x08, 0xc0, 0xc1, 0x03,
+  0x4c, 0x00, 0x00, 0x30, 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x90, 0x13, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x08, 0xc0, 0xc1, 0x03, 0x4c, 0x00, 0x00, 0x30,
+  0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0xc0, 0x3f, 0x98, 0x01, 0x08, 0x1b, 0x43, 0xc8, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+  0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x98,
+  0x01, 0x08, 0x1b, 0x43, 0xc8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x18, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0e, 0x00, 0xc0, 0xc6, 0x03, 0x40, 0x00, 0x00, 0x80,
+  0x31, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0xef, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
+  0x00, 0x00, 0x3f, 0x18, 0x0c, 0x30, 0x60, 0x0c, 0xce, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0xef, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x3f, 0x18,
+  0x0c, 0x30, 0x60, 0x0c, 0xce, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xc7, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xde, 0x63, 0x40, 0x06, 0x03, 0x30,
+  0x30, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x83, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e,
+  0x00, 0x00, 0xde, 0x63, 0x40, 0x06, 0x03, 0x30, 0x30, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x04,
+  0x02, 0x00, 0x00, 0x83, 0xc9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x38, 0x04, 0x02, 0x00, 0x00, 0x83,
+  0xc9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x03, 0x00, 0xe0, 0x1b, 0x0c, 0x08, 0x18, 0x40, 0x30, 0xfe, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0xc0, 0x84,
+  0x81, 0x01, 0x03, 0x0c, 0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0xc0, 0x84, 0x81, 0x01, 0x03, 0x0c,
+  0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+  0x0e, 0x00, 0x00, 0x1b, 0x0c, 0x30, 0x80, 0x00, 0x30, 0xf8, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+  0x10, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x1b,
+  0x0c, 0x30, 0x80, 0x00, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x67, 0xc0, 0x01, 0x04, 0x40,
+  0x00, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x08, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x08, 0x00, 0x00, 0x67, 0xc0, 0x01, 0x04, 0x40, 0x00, 0xe1, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+  0x30, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x9c,
+  0x01, 0x08, 0x60, 0x0c, 0x06, 0x86, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xbf, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x07, 0x0e, 0x00, 0x00, 0x18, 0x0c, 0xc0, 0x00, 0x00,
+  0xc0, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x9f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0x07, 0x00, 0x00, 0x18, 0x0c, 0xc0, 0x00, 0x00, 0xc0, 0x00, 0xfc, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0xe0,
+  0x01, 0x06, 0x00, 0x30, 0x06, 0x86, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0xe0, 0x01, 0x06, 0x00, 0x30,
+  0x06, 0x86, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x00, 0x00, 0x00, 0x60, 0x30, 0x00, 0x63, 0x03, 0x30, 0x00, 0xe0, 0xff,
+  0xff, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+  0x30, 0x00, 0x63, 0x03, 0x30, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x80, 0x83, 0x09, 0x18, 0x00,
+  0x00, 0x06, 0x83, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x08, 0x00, 0x00, 0x80, 0x83, 0x09, 0x18, 0x00, 0x00, 0x06, 0x83, 0xff,
+  0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0xc0, 0x00, 0x8c, 0xc9, 0x60, 0x00, 0xfe, 0xff, 0xff, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x8e, 0x01, 0x84, 0x40,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x8e, 0x01, 0x84, 0x40, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x60, 0x83, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
+  0x00, 0xc8, 0x60, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x06, 0x00, 0x0c,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0f, 0x00, 0x00, 0x00, 0x80, 0xc1, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x80, 0xc1, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x60, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf8, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xc6,
+  0x03, 0x00, 0x00, 0x00, 0x40, 0x08, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xef, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xd8, 0xef, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x1c, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xf3,
+  0x0f, 0x00, 0x00, 0x00, 0x80, 0x09, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x33, 0x0c, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x88, 0x13, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x13,
+  0x08, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x33, 0x0c, 0x00, 0x00, 0x00,
+  0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x88, 0xf3, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xe3,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xe1, 0x1f, 0x00, 0x00, 0x00,
+  0x00, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xf0, 0xc1, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00,
+  0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xc0, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x60, 0xf0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0e, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1c, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x06, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0e, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0e, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
diff -Nru a/arch/m68knommu/platform/68EZ328/config.c b/arch/m68knommu/platform/68EZ328/config.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68EZ328/config.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,131 @@
+/*
+ *  linux/arch/$(ARCH)/platform/$(PLATFORM)/config.c
+ *
+ *  Copyright (C) 1993 Hamish Macdonald
+ *  Copyright (C) 1999 D. Jeff Dionne
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <stdarg.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+#include <asm/MC68EZ328.h>
+#ifdef CONFIG_UCSIMM
+#include <asm/bootstd.h>
+#endif
+#ifdef CONFIG_PILOT
+#include "PalmV/romfs.h"
+#endif
+
+void BSP_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
+{
+  /* Restart mode, Enable int, 32KHz, Enable timer */
+  TCTL = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_32KHZ | TCTL_TEN;
+  /* Set prescaler (Divide 32KHz by 32)*/
+  TPRER = 31;
+  /* Set compare register  32Khz / 32 / 10 = 100 */
+  TCMP = 10;                                                              
+
+  request_irq(TMR_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
+}
+
+void BSP_tick(void)
+{
+  	/* Reset Timer1 */
+	TSTAT &= 0;
+}
+
+unsigned long BSP_gettimeoffset (void)
+{
+  return 0;
+}
+
+void BSP_gettod (int *yearp, int *monp, int *dayp,
+		   int *hourp, int *minp, int *secp)
+{
+}
+
+int BSP_hwclk(int op, struct hwclk_time *t)
+{
+  if (!op) {
+    /* read */
+  } else {
+    /* write */
+  }
+  return 0;
+}
+
+int BSP_set_clock_mmss (unsigned long nowtime)
+{
+#if 0
+  short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
+
+  tod->second1 = real_seconds / 10;
+  tod->second2 = real_seconds % 10;
+  tod->minute1 = real_minutes / 10;
+  tod->minute2 = real_minutes % 10;
+#endif
+  return 0;
+}
+
+void BSP_reset (void)
+{
+  local_irq_disable();
+  asm volatile ("
+    moveal #0x10c00000, %a0;
+    moveb #0, 0xFFFFF300;
+    moveal 0(%a0), %sp;
+    moveal 4(%a0), %a0;
+    jmp (%a0);
+    ");
+}
+
+unsigned char *cs8900a_hwaddr;
+static int errno;
+
+#ifdef CONFIG_UCSIMM
+_bsc0(char *, getserialnum)
+_bsc1(unsigned char *, gethwaddr, int, a)
+_bsc1(char *, getbenv, char *, a)
+#endif
+
+void config_BSP(char *command, int len)
+{
+  unsigned char *p;
+
+  printk("\n68EZ328 DragonBallEZ support (C) 1999 Rt-Control, Inc\n");
+
+#ifdef CONFIG_UCSIMM
+  printk("uCsimm serial string [%s]\n",getserialnum());
+  p = cs8900a_hwaddr = gethwaddr(0);
+  printk("uCsimm hwaddr %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
+         p[0], p[1], p[2], p[3], p[4], p[5]);
+
+  p = getbenv("APPEND");
+  if (p) strcpy(p,command);
+  else command[0] = 0;
+#endif
+ 
+  mach_sched_init      = BSP_sched_init;
+  mach_tick            = BSP_tick;
+  mach_gettimeoffset   = BSP_gettimeoffset;
+  mach_gettod          = BSP_gettod;
+  mach_hwclk           = NULL;
+  mach_set_clock_mmss  = NULL;
+  mach_reset           = BSP_reset;
+
+  config_M68328_irq();
+}
diff -Nru a/arch/m68knommu/platform/68EZ328/ucsimm/crt0_fixed.S b/arch/m68knommu/platform/68EZ328/ucsimm/crt0_fixed.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68EZ328/ucsimm/crt0_fixed.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,109 @@
+#include <linux/config.h>
+	
+	.global _start
+	.global _stext
+
+	.global _rambase
+	.global _ramvec
+	.global _ramstart
+	.global _ramend
+
+#ifdef CONFIG_INIT_LCD
+	.global splash_bits
+#endif
+
+	.data
+
+/*
+ *      Set up the usable of RAM stuff. Size of RAM is determined then
+ *      an initial stack set up at the end.
+ */
+.align 4
+_ramvec:
+.long   0
+_rambase:
+.long   0
+_ramstart:
+.long   0
+_ramend:
+.long   0
+
+#ifdef CONFIG_INIT_LCD
+splash_bits:
+#include "bootlogo.rh"
+#endif
+	
+	.text
+_start:
+_stext:	movew	#0x2700,%sr
+#ifdef CONFIG_INIT_LCD
+	movel	#splash_bits, 0xfffffA00 /* LSSA */
+	moveb	#0x28,   0xfffffA05	/* LVPW */
+	movew	#0x280,  0xFFFFFa08	/* LXMAX */
+	movew	#0x1df,  0xFFFFFa0a	/* LYMAX */
+	moveb	#0,      0xfffffa29	/* LBAR */
+	moveb	#0,      0xfffffa25	/* LPXCD */
+	moveb	#0x08,   0xFFFFFa20	/* LPICF */
+	moveb	#0x01,   0xFFFFFA21	/* -ve pol */
+	moveb	#0x81,   0xfffffA27	/* LCKCON */
+	movew	#0xff00, 0xfffff412	/* LCD pins */
+#endif
+	moveal  #__ramend-CONFIG_MEMORY_RESERVE*0x100000 - 0x10, %sp
+	movew	#32767, %d0  /* PLL settle wait loop */
+1:	subq	#1, %d0
+	bne	1b
+
+	/* Copy data segment from ROM to RAM */
+	moveal	#__data_rom_start, %a0
+	moveal	#_sdata, %a1
+	moveal	#_edata, %a2
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+1:	movel	%a0@+, %a1@+
+	cmpal	%a1, %a2
+	bhi	1b
+
+	moveal	#_sbss, %a0
+	moveal	#_ebss, %a1
+	/* Copy 0 to %a0 until %a0 == %a1 */
+	
+1:
+	clrl	%a0@+
+	cmpal	%a0, %a1
+	bhi	1b
+
+        movel   #_sdata, %d0    
+        movel   %d0,    _rambase        
+        movel   #_ebss,  %d0
+        movel   %d0,    _ramstart
+	movel	#__ramend-CONFIG_MEMORY_RESERVE*0x100000, %d0
+	movel	%d0,	_ramend
+	movel	#__ramvec,	%d0
+	movel	%d0,	_ramvec
+	
+/*
+ * load the current task pointer and stack
+ */
+	lea	init_thread_union, %a0
+	lea	0x2000(%a0), %sp
+
+1:	jsr	start_kernel
+        bra 1b
+_exit:
+
+	jmp	_exit
+
+
+putc:
+	moveb	%d7,0xfffff907
+1:
+	movew	0xfffff906, %d7
+	andw	#0x2000, %d7
+	beq	1b
+	rts
+
+	.data
+env:
+	.long	0
+	.text
+
diff -Nru a/arch/m68knommu/platform/68EZ328/ucsimm/crt0_himem.S b/arch/m68knommu/platform/68EZ328/ucsimm/crt0_himem.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68EZ328/ucsimm/crt0_himem.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include "crt0_fixed.S"
diff -Nru a/arch/m68knommu/platform/68EZ328/ucsimm/crt0_ram.S b/arch/m68knommu/platform/68EZ328/ucsimm/crt0_ram.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68EZ328/ucsimm/crt0_ram.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,172 @@
+	.global __text_start
+	.global __main
+	.global __bss_start
+	.global __bss_end
+	.global __ram_start
+	.global __ram_end
+	.global __rom_start
+	.global __rom_end
+	.global __data_start
+	.global __data_end
+
+        .global _rambase
+        .global _ramstart
+	
+	.global splash_bits
+	.global _start
+	.global _stext
+
+#define DEBUG
+#define ROM_OFFSET 0x10C00000
+#define STACK_GAURD 0x10
+
+	.text
+	
+_start:
+_stext:
+	movew	#0x2700, %sr            /* Exceptions off! */
+
+	/* Init chip registers.  uCsimm specific */
+	moveb	#0x00,   0xfffffb0b	/* Watchdog off */
+	moveb	#0x10,   0xfffff000	/* SCR */
+
+	movew   #0x2400, 0xfffff200	/* PLLCR */
+	movew   #0x0123, 0xfffff202	/* PLLFSR */
+
+	moveb	#0x00,   0xfffff40b	/* enable chip select */
+	moveb	#0x00,   0xfffff423	/* enable /DWE */
+	moveb	#0x08,   0xfffffd0d	/* disable hardmap */
+	moveb	#0x07,   0xfffffd0e	/* level 7 interrupt clear */
+
+	movew	#0x8600, 0xfffff100	/* FLASH at 0x10c00000 */
+	movew	#0x018b, 0xfffff110	/* 2Meg, enable, 0ws */
+
+	movew	#0x8f00, 0xfffffc00	/* DRAM configuration */
+	movew	#0x9667, 0xfffffc02	/* DRAM control */
+	movew	#0x0000, 0xfffff106	/* DRAM at 0x00000000 */
+	movew	#0x068f, 0xfffff116	/* 8Meg, enable, 0ws */
+
+	moveb	#0x40,   0xfffff300	/* IVR */
+	movel	#0x007FFFFF, %d0	/* IMR */
+	movel	%d0,     0xfffff304
+
+	moveb	0xfffff42b, %d0
+	andb	#0xe0,	 %d0
+	moveb	%d0,	 0xfffff42b
+
+	moveb	#0x08,   0xfffff907	/* Ignore CTS */
+	movew	#0x010b, 0xfffff902	/* BAUD to 9600 */
+	movew	#0xe100, 0xfffff900	/* enable */
+
+	movew	#16384, %d0  /* PLL settle wait loop */
+L0:
+	subw	#1, %d0
+	bne	L0
+#ifdef DEBUG
+	moveq	#70, %d7		/* 'F' */
+	moveb	%d7,0xfffff907          /* No absolute addresses */
+pclp1:
+	movew	0xfffff906, %d7
+	andw	#0x2000, %d7
+	beq	pclp1
+#endif /* DEBUG */
+
+#ifdef CONFIG_RELOCATE
+	/* Copy me to RAM */
+	moveal	#__rom_start, %a0
+	moveal	#__ram_start, %a1
+	moveal	#__data_end, %a2
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+LD1:
+	movel	%a0@+, %d0
+	movel	%d0, %a1@+
+	cmpal	%a1, %a2
+	bhi	LD1
+	
+#ifdef DEBUG
+	moveq	#74, %d7		/* 'J' */
+	moveb	%d7,0xfffff907          /* No absolute addresses */
+pclp2:
+	movew	0xfffff906, %d7
+	andw	#0x2000, %d7
+	beq	pclp2
+#endif /* DEBUG */
+	/* jump into the RAM copy */
+	jmp     ram_jump
+ram_jump:
+
+#endif /* CONFIG_RELOCATE */
+
+#ifdef DEBUG
+	moveq	#82, %d7		/* 'R' */
+	moveb	%d7,0xfffff907          /* No absolute addresses */
+pclp3:
+	movew	0xfffff906, %d7
+	andw	#0x2000, %d7
+	beq	pclp3
+#endif /* DEBUG */
+	moveal	#0x007ffff0, %ssp
+	moveal	#__bss_start, %a0
+	moveal	#__bss_end, %a1
+
+	/* Copy 0 to %a0 until %a0 >= %a1 */
+L1:
+	movel	#0, %a0@+
+	cmpal	%a0, %a1
+	bhi	L1
+
+#ifdef DEBUG
+	moveq	#67, %d7                /* 'C' */
+	jsr	putc
+#endif /* DEBUG */
+
+	pea	0
+	pea	env
+	pea	%sp@(4)
+	pea	0
+
+#ifdef DEBUG
+	moveq	#70, %d7		/* 'F' */
+	jsr	putc
+#endif /* DEBUG */
+
+lp:
+	jsr	start_kernel
+        jmp lp
+_exit:
+
+	jmp	_exit
+
+__main:
+	/* nothing */
+	rts
+
+#ifdef DEBUG
+putc:
+	moveb	%d7,0xfffff907
+pclp:
+	movew	0xfffff906, %d7
+	andw	#0x2000, %d7
+	beq	pclp
+	rts
+#endif /* DEBUG */
+
+	.data
+
+/*
+ *      Set up the usable of RAM stuff. Size of RAM is determined then
+ *      an initial stack set up at the end.
+ */
+.align 4
+_ramvec:
+.long   0
+_rambase:
+.long   0
+_ramstart:
+.long   0
+_ramend:
+.long   0
+
+env:
+	.long	0
diff -Nru a/arch/m68knommu/platform/68EZ328/ucsimm/crt0_rom.S b/arch/m68knommu/platform/68EZ328/ucsimm/crt0_rom.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68EZ328/ucsimm/crt0_rom.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include "crt0_fixed.S"
diff -Nru a/arch/m68knommu/platform/68EZ328/ucsimm/fixed.ld b/arch/m68knommu/platform/68EZ328/ucsimm/fixed.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68EZ328/ucsimm/fixed.ld	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,108 @@
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS
+{
+  .romvec :
+	{
+	_flashstart = . ;
+	_romvec = . ;
+	__rom_start = . ;
+	} > romvec
+
+  .text :
+	{
+	_stext = . ;
+        	*(.text)
+        	*(.exit.text)
+	. = ALIGN(0x4) ;
+		*(.text.*)
+	. = ALIGN(0x4) ;
+		*(.exitcall.exit)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(16);          /* Exception table              */
+	__start___ex_table = .;
+		*(__ex_table)
+	__stop___ex_table = .;
+
+        __start___ksymtab = .;  /* Kernel symbol table          */
+		 *(__ksymtab)
+	__stop___ksymtab = .;
+
+	. = ALIGN(0x4) ;
+	_etext = . ;
+	__data_rom_start = . ;
+        } > flash
+
+  .eflash :
+	{
+	_flashend = . ;
+	} > eflash
+
+  .ramvec :
+	{
+	__ram_start = . ;
+	__ramvec = . ;
+	} > ramvec
+
+  .data :
+	{
+	. = ALIGN(0x4) ;
+	_sdata = . ;
+	__data_start = . ;
+
+	. = ALIGN(0x4) ;
+		*(.rodata)
+	. = ALIGN(0x4) ;
+		*(.data)
+	. = ALIGN(0x4) ;
+		*(.data.*)	
+
+	. = ALIGN(0x4) ;
+	__init_begin = .;
+		*(.init.text)
+		*(.init.data)
+
+	. = ALIGN(0x4) ;
+	__setup_start = .;
+		*(.init.setup)
+	. = ALIGN(0x4) ;
+	__setup_end = .;
+
+	. = ALIGN(0x4) ;
+	__initcall_start = .;
+		*(.initcall1.init)
+		*(.initcall2.init)
+		*(.initcall3.init)
+		*(.initcall4.init)
+		*(.initcall5.init)
+		*(.initcall6.init)
+		*(.initcall7.init)
+	__initcall_end = .;
+	. = ALIGN(0x4) ;
+
+	. = ALIGN(0x2000) ;
+		*(.data.init_task)
+	. = ALIGN(0x2000) ;
+
+	_edata = . ;
+        } > ram
+
+  .bss :
+        {
+	. = ALIGN(0x4) ;
+	_sbss = . ;
+		*(.bss)
+	. = ALIGN(0x4) ;
+		*(COMMON)
+	. = ALIGN(0x4) ;
+	_ebss = . ;
+	_end = . ;
+	} > ram
+
+  .eram :
+	{
+	__ramend = . ;
+	} > eram
+}
diff -Nru a/arch/m68knommu/platform/68EZ328/ucsimm/himem.ld b/arch/m68knommu/platform/68EZ328/ucsimm/himem.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68EZ328/ucsimm/himem.ld	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,11 @@
+MEMORY 
+	{
+        romvec : ORIGIN = 0x00600000, LENGTH = 0x00000400
+        flash  : ORIGIN = 0x00600400, LENGTH = 0x00200000 - 0x00010400
+        eflash : ORIGIN = 0x007f0000, LENGTH = 0
+        ramvec : ORIGIN = 0x00000000, LENGTH = 0x00000400
+        ram    : ORIGIN = 0x00020000, LENGTH = 0x00600000 - 0x00020000
+        eram   : ORIGIN = 0x00600000, LENGTH = 0
+	}
+
+INCLUDE arch/m68knommu/platform/68EZ328/ucsimm/fixed.ld
diff -Nru a/arch/m68knommu/platform/68EZ328/ucsimm/ram.ld b/arch/m68knommu/platform/68EZ328/ucsimm/ram.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68EZ328/ucsimm/ram.ld	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,110 @@
+MEMORY 
+	{
+	romvec : ORIGIN = 0x10c10000, LENGTH = 0x00000400
+	flash  : ORIGIN = 0x10c10400, LENGTH = 0x00200000 - 0x00010400
+	eflash : ORIGIN = 0x10e00000, LENGTH = 0
+	ramvec : ORIGIN = 0x00000000, LENGTH = 0x00000400
+	bvec   : ORIGIN = 0x00020000, LENGTH = 0x00000400
+	ram    : ORIGIN = 0x00020400, LENGTH = 0x00800000 - 0x00020400
+	eram   : ORIGIN = 0x00800000, LENGTH = 0
+	}
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS
+{
+	.fakevec :
+	{
+	} > romvec
+	.rom :
+	{
+	__rom_start = . ;
+	} > flash
+	.eflash :
+	{
+	_flashend = . ;
+	} > eflash
+	.realvec :
+	{
+	_ramvec = . ;
+	} > ramvec
+	.romvec :
+	{
+	_romvec = . ;
+	} > bvec
+        .text :
+	{
+	__ram_start = . ;
+	text_start = . ;
+        	*(.text)
+        	*(.exit.text)
+		*(.text.*)
+		*(.rodata)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(16);          /* Exception table              */
+	__start___ex_table = .;
+		*(__ex_table)
+	__stop___ex_table = .;
+
+        __start___ksymtab = .;  /* Kernel symbol table          */
+		 *(__ksymtab)
+	__stop___ksymtab = .;
+
+	_etext = . ;
+	__data_rom_start = ALIGN ( 4 ) ;
+        } > ram
+        .data :
+	{
+	_sdata = . ;
+	__data_start = . ;
+
+        . = ALIGN(0x2000) ;
+        *(.data.init_task)
+        . = ALIGN(0x2000) ;
+
+        *(.data)
+        *(.data.*)      
+        *(.exitcall.exit)               
+
+        . = ALIGN(4096) ;
+        __init_begin = .;
+        *(.init.text)
+        *(.init.data)
+        . = ALIGN(16);
+        __setup_start = .;
+        *(.init.setup)
+        __setup_end = .;
+        __initcall_start = .;
+	*(.initcall1.init)
+	*(.initcall2.init)
+	*(.initcall3.init)
+	*(.initcall4.init)
+	*(.initcall5.init)
+	*(.initcall6.init)
+	*(.initcall7.init)
+        __initcall_end = .;
+        . = ALIGN(4) ;
+        __init_end = .;
+
+	_edata = . ;
+	edata = ALIGN( 0x10 ) ;
+        } > ram
+        .bss :
+        {
+	_sbss = ALIGN( 0x10 ) ;
+	__bss_start = ALIGN( 0x10 ) ;
+	__data_end = ALIGN( 0x10 ) ;
+	*(.bss)
+	*(COMMON)
+	_ebss = . ;
+	__bss_end = . ;
+	end = ALIGN( 0x10 ) ;
+	_end = ALIGN( 0x10 ) ;
+	} > ram
+	.eram :
+	{
+	__ramend = . ;
+	_ramend = . ;
+	} > eram
+}
diff -Nru a/arch/m68knommu/platform/68EZ328/ucsimm/rom.ld b/arch/m68knommu/platform/68EZ328/ucsimm/rom.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68EZ328/ucsimm/rom.ld	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,11 @@
+MEMORY 
+	{
+        romvec : ORIGIN = 0x10c10000, LENGTH = 0x00000400
+        flash  : ORIGIN = 0x10c10400, LENGTH = 0x001fec00
+        eflash : ORIGIN = 0x10d00000, LENGTH = 0
+        ramvec : ORIGIN = 0x00000000, LENGTH = 1024
+        ram    : ORIGIN = 0x00020000, LENGTH = 0x00800000 - 0x00020000
+        eram   : ORIGIN = 0x00800000, LENGTH = 0
+	}
+
+INCLUDE arch/m68knommu/platform/68EZ328/ucsimm/fixed.ld
diff -Nru a/arch/m68knommu/platform/68VZ328/Makefile b/arch/m68knommu/platform/68VZ328/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68VZ328/Makefile	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,14 @@
+#
+# Makefile for arch/m68knommu/platform/68VZ328.
+#
+
+obj-y := $(BOARD)/config.o
+
+EXTRA_TARGETS := $(BOARD)/bootlogo.rh $(BOARD)/crt0_$(MODEL).o
+
+include $(TOPDIR)/Rules.make
+
+$(obj)/$(BOARD)/bootlogo.rh: $(src)/../68EZ328/bootlogo.h
+	perl $(src)/../68328/bootlogo.pl < $(src)/../68EZ328/bootlogo.h \
+		> $(obj)/$(BOARD)/bootlogo.rh
+
diff -Nru a/arch/m68knommu/platform/68VZ328/de2/config.c b/arch/m68knommu/platform/68VZ328/de2/config.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68VZ328/de2/config.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,151 @@
+/*
+ *  linux/arch/m68knommu/platform/MC68VZ328/de2/config.c
+ *
+ *  Copyright (C) 1993 Hamish Macdonald
+ *  Copyright (C) 1999 D. Jeff Dionne
+ *  Copyright (C) 2001 Georges Menie, Ken Desmet
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <stdarg.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/kd.h>
+#include <linux/netdevice.h>
+
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+#include <asm/MC68VZ328.h>
+
+#define CLOCK_COMPARE (32768/HZ)
+
+static void dragen2_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
+{
+	/* disable timer 1 */
+	TCTL = 0;
+
+	/* set ISR */
+	request_irq(TMR_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
+
+	/* Restart mode, Enable int, 32KHz */
+	TCTL = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_32KHZ;
+	TPRER = 0;
+	TCMP = CLOCK_COMPARE-1; 
+
+	/* Enable timer 1 */
+	TCTL |= TCTL_TEN;
+}
+
+static void dragen2_tick(void)
+{
+  	/* Reset Timer1 */
+	TSTAT &= 0;
+}
+
+static unsigned long dragen2_gettimeoffset(void)
+{
+	unsigned long ticks, offset = 0;
+
+	ticks = TCN;
+
+	if (ticks > (CLOCK_COMPARE>>1)) {
+		/* check for pending interrupt */
+		if (ISR & (1<<TMR_IRQ_NUM))
+			offset = 1000000/HZ;
+	}
+
+	ticks = CLOCK_COMPARE - ticks;
+	ticks = (1000000/HZ * ticks) / CLOCK_COMPARE;
+
+	return ticks + offset;
+}
+
+static void dragen2_gettod(int *year, int *mon, int *day, int *hour, int *min, int *sec)
+{
+	long now = RTCTIME;
+
+	*year = *mon = *day = 1;
+	*hour = (now>>24)%24;
+	*min = (now>>16)%60;
+	*sec = now%60;
+}
+
+static void dragen2_reset(void)
+{
+	local_irq_disable();
+	asm volatile ("
+		movel #-1, 0xFFFFF304;
+		moveb #0, 0xFFFFF300;
+		moveal #0x04000000, %a0;
+		moveal 0(%a0), %sp;
+		moveal 4(%a0), %a0;
+		jmp (%a0);
+	");
+}
+
+int dragen2_cs8900_setup(struct net_device *dev)
+{
+	/* Set the ETH hardware address from its flash monitor location */
+	memcpy(dev->dev_addr, (void *)0x400fffa, 6);
+        dev->irq = INT1_IRQ_NUM;
+	return dev->base_addr = 0x08000041;
+}
+
+static void init_hardware(void)
+{
+	/* CSGB Init */
+	CSGBB = 0x4000;
+	CSB = 0x1a1;
+
+	/* CS8900 init */
+	/* PK3: hardware sleep function pin, active low */
+	PKSEL |= PK(3);	/* select pin as I/O */
+	PKDIR |= PK(3);	/* select pin as output */
+	PKDATA |= PK(3);	/* set pin high */
+
+	/* PF5: hardware reset function pin, active high */
+	PFSEL |= PF(5);	/* select pin as I/O */
+	PFDIR |= PF(5);	/* select pin as output */
+	PFDATA &= ~PF(5);	/* set pin low */
+
+	/* cs8900 hardware reset */
+	PFDATA |= PF(5);
+	{ volatile int i; for (i = 0; i < 32000; ++i); }
+	PFDATA &= ~PF(5);
+
+	/* INT1 enable (cs8900 IRQ) */
+	PDPOL &= ~PD(1);	/* active high signal */
+	PDIQEG &= ~PD(1);
+	PDIRQEN |= PD(1);	/* IRQ enabled */
+
+#ifdef CONFIG_68328_SERIAL_UART2
+	/* Enable RXD TXD port bits to enable UART2 */
+	PJSEL &= ~(PJ(5)|PJ(4));
+#endif
+}
+
+void config_BSP(char *command, int len)
+{
+	printk("68VZ328 DragonBallVZ support (c) 2001 Lineo, Inc.\n");
+        command[0] = '\0'; /* no specific boot option */
+
+	init_hardware();
+
+	mach_sched_init      = dragen2_sched_init;
+	mach_tick            = dragen2_tick;
+	mach_gettimeoffset   = dragen2_gettimeoffset;
+	mach_reset           = dragen2_reset;
+	mach_gettod          = dragen2_gettod;
+
+	config_M68VZ328_irq();
+}
diff -Nru a/arch/m68knommu/platform/68VZ328/de2/crt0_fixed.S b/arch/m68knommu/platform/68VZ328/de2/crt0_fixed.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68VZ328/de2/crt0_fixed.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,159 @@
+#include <linux/config.h>
+	
+	.global _start
+	.global _stext
+
+	.global _rambase
+	.global _ramvec
+	.global _ramstart
+	.global _ramend
+
+#ifdef CONFIG_INIT_LCD
+	.global splash_bits
+#endif
+
+	.data
+
+/*
+ *      Set up the usable of RAM stuff. Size of RAM is determined then
+ *      an initial stack set up at the end.
+ */
+.align 4
+_ramvec:
+.long   0
+_rambase:
+.long   0
+_ramstart:
+.long   0
+_ramend:
+.long   0
+
+#ifdef CONFIG_INIT_LCD
+splash_bits:
+#include "bootlogo.rh"
+#endif
+	
+	.text
+_start:
+_stext:
+	movew	#0x2700,%sr
+	moveal  #__ramend-CONFIG_MEMORY_RESERVE*0x100000 - 0x10, %sp
+	movel	#0xffffffff, 0xfffff304	/* disable all interrupts */
+
+#ifdef CONFIG_RAMKERNEL
+	/* Copy me from ROM to RAM */
+	moveal	#__rom_start, %a0
+	moveal	#__ram_start, %a1
+	moveal	#__data_end, %a2
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+2:	cmpal	%a1, %a2
+	beq	1f
+	movel	%a0@+, %a1@+
+	bra	2b
+1:
+        /* jump into the RAM copy */
+        jmp     ram_jump
+ram_jump:
+#endif
+
+#ifdef CONFIG_INIT_LCD
+	movel	#splash_bits, 0xfffffA00 /* LSSA */
+	moveb	#0x28,   0xfffffA05	/* LVPW */
+	movew	#0x280,  0xFFFFFa08	/* LXMAX */
+	movew	#0x1df,  0xFFFFFa0a	/* LYMAX */
+	moveb	#0,      0xfffffa29	/* LBAR */
+	moveb	#0,      0xfffffa25	/* LPXCD */
+	moveb	#0x08,   0xFFFFFa20	/* LPICF */
+	moveb	#0x01,   0xFFFFFA21	/* -ve pol */
+	moveb	#0x81,   0xfffffA27	/* LCKCON */
+	movew	#0xff00, 0xfffff412	/* LCD pins */
+#endif
+
+	moveq   #13, %d7                /* '\r' */
+	jsr putc
+	moveq   #10, %d7                /* '\n' */
+	jsr putc
+	moveq   #65, %d7                /* 'A' */
+	jsr putc
+
+	movew	#32767, %d0  /* PLL settle wait loop */
+1:	subq	#1, %d0
+	bne	1b
+
+	moveq   #66, %d7                /* 'B' */
+	jsr putc
+
+#ifndef CONFIG_RAMKERNEL
+	/* Copy data segment from ROM to RAM */
+	moveal	#__data_rom_start, %a0
+	moveal	#_sdata, %a1
+	moveal	#_edata, %a2
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+2:	cmpal	%a1, %a2
+	beq	1f
+	movel	%a0@+, %a1@+
+	bra	2b
+1:
+#endif
+	moveq   #67, %d7                /* 'C' */
+	jsr putc
+
+	/* Initialize BSS segment to 0 */
+	moveal	#_sbss, %a0
+	moveal	#_ebss, %a1
+
+	/* Copy 0 to %a0 until %a0 == %a1 */
+2:	cmpal	%a0, %a1
+	beq	1f
+	clrl	%a0@+
+	bra	2b
+1:
+	moveq   #68, %d7                /* 'D' */
+	jsr putc
+
+        movel   #_sdata, %d0    
+        movel   %d0,    _rambase        
+        movel   #_ebss,  %d0
+        movel   %d0,    _ramstart
+	movel	#__ramend-CONFIG_MEMORY_RESERVE*0x100000, %d0
+	movel	%d0,	_ramend
+	movel	#__ramvec,	%d0
+	movel	%d0,	_ramvec
+	
+	moveq   #69, %d7                /* 'E' */
+	jsr putc
+
+/*
+ * load the current task pointer and stack
+ */
+	lea	init_thread_union, %a0
+	lea	0x2000(%a0), %sp
+
+	moveq   #70, %d7                /* 'F' */
+	jsr putc
+	moveq   #13, %d7                /* '\r' */
+	jsr putc
+	moveq   #10, %d7                /* '\n' */
+	jsr putc
+
+1:	jsr	start_kernel
+	bra	1b
+
+_exit:
+	bra	_exit
+
+putc:
+	moveb	%d7,0xfffff907
+1:
+	movew	0xfffff906, %d7
+	andw	#0x2000, %d7
+	beq	1b
+	rts
+
+	.data
+env:
+	.long	0
+	.text
+
diff -Nru a/arch/m68knommu/platform/68VZ328/de2/crt0_himem.S b/arch/m68knommu/platform/68VZ328/de2/crt0_himem.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68VZ328/de2/crt0_himem.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include "crt0_fixed.S"
diff -Nru a/arch/m68knommu/platform/68VZ328/de2/crt0_ram.S b/arch/m68knommu/platform/68VZ328/de2/crt0_ram.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68VZ328/de2/crt0_ram.S	Mon Nov  4 14:31:03 2002
@@ -0,0 +1 @@
+#include "crt0_fixed.S"
diff -Nru a/arch/m68knommu/platform/68VZ328/de2/crt0_rom.S b/arch/m68knommu/platform/68VZ328/de2/crt0_rom.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68VZ328/de2/crt0_rom.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include "crt0_fixed.S"
diff -Nru a/arch/m68knommu/platform/68VZ328/de2/fixed.ld b/arch/m68knommu/platform/68VZ328/de2/fixed.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68VZ328/de2/fixed.ld	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,102 @@
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS
+{
+  .romvec :
+	{
+	_flashstart = . ;
+	_romvec = . ;
+	__rom_start = . ;
+	} > romvec
+
+  .text :
+	{
+	_stext = . ;
+        	*(.text)
+	. = ALIGN(0x4) ;
+		*(.text.*)
+	. = ALIGN(0x4) ;
+		*(.exitcall.exit)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(16);          /* Exception table              */
+	__start___ex_table = .;
+		*(__ex_table)
+	__stop___ex_table = .;
+
+        __start___ksymtab = .;  /* Kernel symbol table          */
+		 *(__ksymtab)
+	__stop___ksymtab = .;
+
+	. = ALIGN(0x4) ;
+	_etext = . ;
+	__data_rom_start = . ;
+        } > flash
+
+  .eflash :
+	{
+	_flashend = . ;
+	} > eflash
+
+  .ramvec :
+	{
+	__ram_start = . ;
+	__ramvec = . ;
+	} > ramvec
+
+  .data :
+	{
+	. = ALIGN(0x4) ;
+	_sdata = . ;
+	__data_start = . ;
+
+	. = ALIGN(0x4) ;
+		*(.rodata)
+	. = ALIGN(0x4) ;
+		*(.data)
+	. = ALIGN(0x4) ;
+		*(.data.*)	
+
+	. = ALIGN(0x4) ;
+	__setup_start = .;
+		*(.init.setup)
+	. = ALIGN(0x4) ;
+	__setup_end = .;
+
+	. = ALIGN(0x4) ;
+	__initcall_start = .;
+	*(.initcall1.init)
+	*(.initcall2.init)
+	*(.initcall3.init)
+	*(.initcall4.init)
+	*(.initcall5.init)
+	*(.initcall6.init)
+	*(.initcall7.init)
+	__initcall_end = .;
+	. = ALIGN(0x4) ;
+
+	. = ALIGN(0x2000) ;
+		*(.data.init_task)
+	. = ALIGN(0x2000) ;
+
+	_edata = . ;
+        } > ram
+
+  .bss :
+        {
+	. = ALIGN(0x4) ;
+	_sbss = . ;
+		*(.bss)
+	. = ALIGN(0x4) ;
+		*(COMMON)
+	. = ALIGN(0x4) ;
+	_ebss = . ;
+	_end = . ;
+	} > ram
+
+  .eram :
+	{
+	__ramend = . ;
+	} > eram
+}
diff -Nru a/arch/m68knommu/platform/68VZ328/de2/himem.ld b/arch/m68knommu/platform/68VZ328/de2/himem.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68VZ328/de2/himem.ld	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,11 @@
+MEMORY 
+	{
+        romvec : ORIGIN = 0x01e00000, LENGTH = 1k
+        flash  : ORIGIN = 0x01e00400, LENGTH = 2M - 1k
+        eflash : ORIGIN = 0x02000000, LENGTH = 0
+        ramvec : ORIGIN = 0x00000000, LENGTH = 1k
+        ram    : ORIGIN = 0x00010000, LENGTH = 30M - 64k
+        eram   : ORIGIN = 0x01e00000, LENGTH = 0
+	}
+
+INCLUDE arch/m68knommu/platform/68VZ328/de2/fixed.ld
diff -Nru a/arch/m68knommu/platform/68VZ328/de2/ram.ld b/arch/m68knommu/platform/68VZ328/de2/ram.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68VZ328/de2/ram.ld	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,109 @@
+MEMORY 
+	{
+	romvec : ORIGIN = 0x04030000, LENGTH = 1k
+	flash  : ORIGIN = 0x04030400, LENGTH = 2M - 197k
+	eflash : ORIGIN = 0x04200000, LENGTH = 0
+	ramvec : ORIGIN = 0x00000000, LENGTH = 1k
+	bvec   : ORIGIN = 0x00010000, LENGTH = 1k
+	ram    : ORIGIN = 0x00010400, LENGTH = 32M - 65k
+	eram   : ORIGIN = 0x02000000, LENGTH = 0
+	}
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS
+{
+	.fakevec :
+	{
+	} > romvec
+	.rom :
+	{
+	__rom_start = . ;
+	} > flash
+	.eflash :
+	{
+	_flashend = . ;
+	} > eflash
+	.realvec :
+	{
+	__ramvec = . ;
+	} > ramvec
+	.romvec :
+	{
+	_romvec = . ;
+	} > bvec
+        .text :
+	{
+	__ram_start = . ;
+	text_start = . ;
+        	*(.text)
+		*(.text.*)
+		*(.rodata)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(16);          /* Exception table              */
+	__start___ex_table = .;
+		*(__ex_table)
+	__stop___ex_table = .;
+
+        __start___ksymtab = .;  /* Kernel symbol table          */
+		 *(__ksymtab)
+	__stop___ksymtab = .;
+
+	_etext = . ;
+	__data_rom_start = ALIGN ( 4 ) ;
+        } > ram
+        .data :
+	{
+	_sdata = . ;
+	__data_start = . ;
+
+        . = ALIGN(0x2000) ;
+        *(.data.init_task)
+        . = ALIGN(0x2000) ;
+
+        *(.data)
+        *(.data.*)      
+        *(.exitcall.exit)               
+
+        . = ALIGN(4096) ;
+        __init_begin = .;
+        *(.init.text)
+        *(.init.data)
+        . = ALIGN(16);
+        __setup_start = .;
+        *(.init.setup)
+        __setup_end = .;
+        __initcall_start = .;
+	*(.initcall1.init)
+	*(.initcall2.init)
+	*(.initcall3.init)
+	*(.initcall4.init)
+	*(.initcall5.init)
+	*(.initcall6.init)
+	*(.initcall7.init)
+        __initcall_end = .;
+        . = ALIGN(4) ;
+        __init_end = .;
+
+	_edata = . ;
+	edata = ALIGN( 0x10 ) ;
+        } > ram
+        .bss :
+        {
+	_sbss = ALIGN( 0x10 ) ;
+	__bss_start = ALIGN( 0x10 ) ;
+	__data_end = ALIGN( 0x10 ) ;
+	*(.bss)
+	*(COMMON)
+	_ebss = . ;
+	__bss_end = . ;
+	end = ALIGN( 0x10 ) ;
+	_end = ALIGN( 0x10 ) ;
+	} > ram
+	.eram :
+	{
+	__ramend = . ;
+	_ramend = . ;
+	} > eram
+}
diff -Nru a/arch/m68knommu/platform/68VZ328/de2/rom.ld b/arch/m68knommu/platform/68VZ328/de2/rom.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68VZ328/de2/rom.ld	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,11 @@
+MEMORY 
+	{
+        romvec : ORIGIN = 0x04030000, LENGTH = 1k
+        flash  : ORIGIN = 0x04030400, LENGTH = 2M - 197k
+        eflash : ORIGIN = 0x04200000, LENGTH = 0
+        ramvec : ORIGIN = 0x00000000, LENGTH = 1k
+        ram    : ORIGIN = 0x00010000, LENGTH = 32M - 64k
+        eram   : ORIGIN = 0x02000000, LENGTH = 0
+	}
+
+INCLUDE arch/m68knommu/platform/68VZ328/de2/fixed.ld
diff -Nru a/arch/m68knommu/platform/68VZ328/ucdimm/crt0_fixed.S b/arch/m68knommu/platform/68VZ328/ucdimm/crt0_fixed.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68VZ328/ucdimm/crt0_fixed.S	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,109 @@
+#include <linux/config.h>
+	
+	.global _start
+	.global _stext
+
+	.global _rambase
+	.global _ramvec
+	.global _ramstart
+	.global _ramend
+
+#ifdef CONFIG_INIT_LCD
+	.global splash_bits
+#endif
+
+	.data
+
+/*
+ *      Set up the usable of RAM stuff. Size of RAM is determined then
+ *      an initial stack set up at the end.
+ */
+.align 4
+_ramvec:
+.long   0
+_rambase:
+.long   0
+_ramstart:
+.long   0
+_ramend:
+.long   0
+
+#ifdef CONFIG_INIT_LCD
+splash_bits:
+#include "bootlogo.rh"
+#endif
+	
+	.text
+_start:
+_stext:	movew	#0x2700,%sr
+#ifdef CONFIG_INIT_LCD
+	movel	#splash_bits, 0xfffffA00 /* LSSA */
+	moveb	#0x28,   0xfffffA05	/* LVPW */
+	movew	#0x280,  0xFFFFFa08	/* LXMAX */
+	movew	#0x1df,  0xFFFFFa0a	/* LYMAX */
+	moveb	#0,      0xfffffa29	/* LBAR */
+	moveb	#0,      0xfffffa25	/* LPXCD */
+	moveb	#0x08,   0xFFFFFa20	/* LPICF */
+	moveb	#0x01,   0xFFFFFA21	/* -ve pol */
+	moveb	#0x81,   0xfffffA27	/* LCKCON */
+	movew	#0xff00, 0xfffff412	/* LCD pins */
+#endif
+	moveal  #__ramend-CONFIG_MEMORY_RESERVE*0x100000 - 0x10, %sp
+	movew	#32767, %d0  /* PLL settle wait loop */
+1:	subq	#1, %d0
+	bne	1b
+
+	/* Copy data segment from ROM to RAM */
+	moveal	#__data_rom_start, %a0
+	moveal	#_sdata, %a1
+	moveal	#_edata, %a2
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+1:	movel	%a0@+, %a1@+
+	cmpal	%a1, %a2
+	bhi	1b
+
+	moveal	#_sbss, %a0
+	moveal	#_ebss, %a1
+	/* Copy 0 to %a0 until %a0 == %a1 */
+	
+1:
+	clrl	%a0@+
+	cmpal	%a0, %a1
+	bhi	1b
+
+        movel   #_sdata, %d0    
+        movel   %d0,    _rambase        
+        movel   #_ebss,  %d0
+        movel   %d0,    _ramstart
+	movel	#__ramend-CONFIG_MEMORY_RESERVE*0x100000, %d0
+	movel	%d0,	_ramend
+	movel	#__ramvec,	%d0
+	movel	%d0,	_ramvec
+	
+/*
+ * load the current task pointer and stack
+ */
+	lea	init_thread_union, %a0
+	lea	0x2000(%a0), %sp
+
+1:	jsr	start_kernel
+        bra 1b
+_exit:
+
+	jmp	_exit
+
+
+putc:
+	moveb	%d7,0xfffff907
+1:
+	movew	0xfffff906, %d7
+	andw	#0x2000, %d7
+	beq	1b
+	rts
+
+	.data
+env:
+	.long	0
+	.text
+
diff -Nru a/arch/m68knommu/platform/68VZ328/ucdimm/crt0_himem.S b/arch/m68knommu/platform/68VZ328/ucdimm/crt0_himem.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68VZ328/ucdimm/crt0_himem.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include "crt0_fixed.S"
diff -Nru a/arch/m68knommu/platform/68VZ328/ucdimm/crt0_ram.S b/arch/m68knommu/platform/68VZ328/ucdimm/crt0_ram.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68VZ328/ucdimm/crt0_ram.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,176 @@
+#include <linux/config.h>
+
+	.global __text_start
+	.global __main
+	.global __bss_start
+	.global __bss_end
+	.global __ram_start
+	.global __ram_end
+	.global __rom_start
+	.global __rom_end
+	.global __data_start
+	.global __data_end
+
+        .global _rambase
+        .global _ramstart
+	
+	.global splash_bits
+	.global _start
+	.global _stext
+
+#define DEBUG
+#define ROM_OFFSET 0x10C00000
+#define STACK_GAURD 0x10
+
+	.text
+	
+_start:
+_stext:
+	movew	#0x2700, %sr            /* Exceptions off! */
+
+#if 0
+	/* Init chip registers.  uCsimm specific */
+	moveb	#0x00,   0xfffffb0b	/* Watchdog off */
+	moveb	#0x10,   0xfffff000	/* SCR */
+
+	movew   #0x2400, 0xfffff200	/* PLLCR */
+	movew   #0x0123, 0xfffff202	/* PLLFSR */
+
+	moveb	#0x00,   0xfffff40b	/* enable chip select */
+	moveb	#0x00,   0xfffff423	/* enable /DWE */
+	moveb	#0x08,   0xfffffd0d	/* disable hardmap */
+	moveb	#0x07,   0xfffffd0e	/* level 7 interrupt clear */
+
+	movew	#0x8600, 0xfffff100	/* FLASH at 0x10c00000 */
+	movew	#0x018b, 0xfffff110	/* 2Meg, enable, 0ws */
+
+	movew	#0x8f00, 0xfffffc00	/* DRAM configuration */
+	movew	#0x9667, 0xfffffc02	/* DRAM control */
+	movew	#0x0000, 0xfffff106	/* DRAM at 0x00000000 */
+	movew	#0x068f, 0xfffff116	/* 8Meg, enable, 0ws */
+
+	moveb	#0x40,   0xfffff300	/* IVR */
+	movel	#0x007FFFFF, %d0	/* IMR */
+	movel	%d0,     0xfffff304
+
+	moveb	0xfffff42b, %d0
+	andb	#0xe0,	 %d0
+	moveb	%d0,	 0xfffff42b
+
+	moveb	#0x08,   0xfffff907	/* Ignore CTS */
+	movew	#0x010b, 0xfffff902	/* BAUD to 9600 */
+	movew	#0xe100, 0xfffff900	/* enable */
+#endif
+
+	movew	#16384, %d0  /* PLL settle wait loop */
+L0:
+	subw	#1, %d0
+	bne	L0
+#ifdef DEBUG
+	moveq	#70, %d7		/* 'F' */
+	moveb	%d7,0xfffff907          /* No absolute addresses */
+pclp1:
+	movew	0xfffff906, %d7
+	andw	#0x2000, %d7
+	beq	pclp1
+#endif /* DEBUG */
+
+#ifdef CONFIG_RELOCATE
+	/* Copy me to RAM */
+	moveal	#__rom_start, %a0
+	moveal	#__ram_start, %a1
+	moveal	#__data_end, %a2
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+LD1:
+	movel	%a0@+, %d0
+	movel	%d0, %a1@+
+	cmpal	%a1, %a2
+	bhi	LD1
+	
+#ifdef DEBUG
+	moveq	#74, %d7		/* 'J' */
+	moveb	%d7,0xfffff907          /* No absolute addresses */
+pclp2:
+	movew	0xfffff906, %d7
+	andw	#0x2000, %d7
+	beq	pclp2
+#endif /* DEBUG */
+	/* jump into the RAM copy */
+	jmp     ram_jump
+ram_jump:
+
+#endif /* CONFIG_RELOCATE */
+
+#ifdef DEBUG
+	moveq	#82, %d7		/* 'R' */
+	moveb	%d7,0xfffff907          /* No absolute addresses */
+pclp3:
+	movew	0xfffff906, %d7
+	andw	#0x2000, %d7
+	beq	pclp3
+#endif /* DEBUG */
+	moveal	#0x007ffff0, %ssp
+	moveal	#__bss_start, %a0
+	moveal	#__bss_end, %a1
+
+	/* Copy 0 to %a0 until %a0 >= %a1 */
+L1:
+	movel	#0, %a0@+
+	cmpal	%a0, %a1
+	bhi	L1
+
+#ifdef DEBUG
+	moveq	#67, %d7                /* 'C' */
+	jsr	putc
+#endif /* DEBUG */
+
+	pea	0
+	pea	env
+	pea	%sp@(4)
+	pea	0
+
+#ifdef DEBUG
+	moveq	#70, %d7		/* 'F' */
+	jsr	putc
+#endif /* DEBUG */
+
+lp:
+	jsr	start_kernel
+        jmp lp
+_exit:
+
+	jmp	_exit
+
+__main:
+	/* nothing */
+	rts
+
+#ifdef DEBUG
+putc:
+	moveb	%d7,0xfffff907
+pclp:
+	movew	0xfffff906, %d7
+	andw	#0x2000, %d7
+	beq	pclp
+	rts
+#endif /* DEBUG */
+
+	.data
+
+/*
+ *      Set up the usable of RAM stuff. Size of RAM is determined then
+ *      an initial stack set up at the end.
+ */
+.align 4
+_ramvec:
+.long   0
+_rambase:
+.long   0
+_ramstart:
+.long   0
+_ramend:
+.long   0
+
+env:
+	.long	0
diff -Nru a/arch/m68knommu/platform/68VZ328/ucdimm/crt0_rom.S b/arch/m68knommu/platform/68VZ328/ucdimm/crt0_rom.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68VZ328/ucdimm/crt0_rom.S	Mon Nov  4 14:31:03 2002
@@ -0,0 +1 @@
+#include "crt0_fixed.S"
diff -Nru a/arch/m68knommu/platform/68VZ328/ucdimm/fixed.ld b/arch/m68knommu/platform/68VZ328/ucdimm/fixed.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68VZ328/ucdimm/fixed.ld	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,102 @@
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS
+{
+  .romvec :
+	{
+	_flashstart = . ;
+	_romvec = . ;
+	__rom_start = . ;
+	} > romvec
+
+  .text :
+	{
+	_stext = . ;
+        	*(.text)
+	. = ALIGN(0x4) ;
+		*(.text.*)
+	. = ALIGN(0x4) ;
+		*(.exitcall.exit)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(16);          /* Exception table              */
+	__start___ex_table = .;
+		*(__ex_table)
+	__stop___ex_table = .;
+
+        __start___ksymtab = .;  /* Kernel symbol table          */
+		 *(__ksymtab)
+	__stop___ksymtab = .;
+
+	. = ALIGN(0x4) ;
+	_etext = . ;
+	__data_rom_start = . ;
+        } > flash
+
+  .eflash :
+	{
+	_flashend = . ;
+	} > eflash
+
+  .ramvec :
+	{
+	__ram_start = . ;
+	__ramvec = . ;
+	} > ramvec
+
+  .data :
+	{
+	. = ALIGN(0x4) ;
+	_sdata = . ;
+	__data_start = . ;
+
+	. = ALIGN(0x4) ;
+		*(.rodata)
+	. = ALIGN(0x4) ;
+		*(.data)
+	. = ALIGN(0x4) ;
+		*(.data.*)	
+
+	. = ALIGN(0x4) ;
+	__setup_start = .;
+		*(.init.setup)
+	. = ALIGN(0x4) ;
+	__setup_end = .;
+
+	. = ALIGN(0x4) ;
+	__initcall_start = .;
+		*(.initcall1.init)
+		*(.initcall2.init)
+		*(.initcall3.init)
+		*(.initcall4.init)
+		*(.initcall5.init)
+		*(.initcall6.init)
+		*(.initcall7.init)
+	__initcall_end = .;
+	. = ALIGN(0x4) ;
+
+	. = ALIGN(0x2000) ;
+		*(.data.init_task)
+	. = ALIGN(0x2000) ;
+
+	_edata = . ;
+        } > ram
+
+  .bss :
+        {
+	. = ALIGN(0x4) ;
+	_sbss = . ;
+		*(.bss)
+	. = ALIGN(0x4) ;
+		*(COMMON)
+	. = ALIGN(0x4) ;
+	_ebss = . ;
+	_end = . ;
+	} > ram
+
+  .eram :
+	{
+	__ramend = . ;
+	} > eram
+}
diff -Nru a/arch/m68knommu/platform/68VZ328/ucdimm/himem.ld b/arch/m68knommu/platform/68VZ328/ucdimm/himem.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68VZ328/ucdimm/himem.ld	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,11 @@
+MEMORY 
+	{
+        romvec : ORIGIN = 0x00600000, LENGTH = 0x00000400
+        flash  : ORIGIN = 0x00600400, LENGTH = 0x00200000 - 0x00010400
+        eflash : ORIGIN = 0x007f0000, LENGTH = 0
+        ramvec : ORIGIN = 0x00000000, LENGTH = 0x00000400
+        ram    : ORIGIN = 0x00020000, LENGTH = 0x00600000 - 0x00020000
+        eram   : ORIGIN = 0x00600000, LENGTH = 0
+	}
+
+INCLUDE arch/m68knommu/platform/68VZ328/ucdimm/fixed.ld
diff -Nru a/arch/m68knommu/platform/68VZ328/ucdimm/ram.ld b/arch/m68knommu/platform/68VZ328/ucdimm/ram.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68VZ328/ucdimm/ram.ld	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,109 @@
+MEMORY 
+	{
+	romvec : ORIGIN = 0x10c10000, LENGTH = 0x00000400
+	flash  : ORIGIN = 0x10c10400, LENGTH = 0x00200000 - 0x00010400
+	eflash : ORIGIN = 0x10e00000, LENGTH = 0
+	ramvec : ORIGIN = 0x00000000, LENGTH = 0x00000400
+	bvec   : ORIGIN = 0x00020000, LENGTH = 0x00000400
+	ram    : ORIGIN = 0x00020400, LENGTH = 0x00800000 - 0x00020400
+	eram   : ORIGIN = 0x00800000, LENGTH = 0
+	}
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS
+{
+	.fakevec :
+	{
+	} > romvec
+	.rom :
+	{
+	__rom_start = . ;
+	} > flash
+	.eflash :
+	{
+	_flashend = . ;
+	} > eflash
+	.realvec :
+	{
+	_ramvec = . ;
+	} > ramvec
+	.romvec :
+	{
+	_romvec = . ;
+	} > bvec
+        .text :
+	{
+	__ram_start = . ;
+	text_start = . ;
+        	*(.text)
+		*(.text.*)
+		*(.rodata)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(16);          /* Exception table              */
+	__start___ex_table = .;
+		*(__ex_table)
+	__stop___ex_table = .;
+
+        __start___ksymtab = .;  /* Kernel symbol table          */
+		 *(__ksymtab)
+	__stop___ksymtab = .;
+
+	_etext = . ;
+	__data_rom_start = ALIGN ( 4 ) ;
+        } > ram
+        .data :
+	{
+	_sdata = . ;
+	__data_start = . ;
+
+        . = ALIGN(0x2000) ;
+        *(.data.init_task)
+        . = ALIGN(0x2000) ;
+
+        *(.data)
+        *(.data.*)      
+        *(.exitcall.exit)               
+
+        . = ALIGN(4096) ;
+        __init_begin = .;
+        *(.init.text)
+        *(.init.data)
+        . = ALIGN(16);
+        __setup_start = .;
+        *(.init.setup)
+        __setup_end = .;
+        __initcall_start = .;
+	*(.initcall1.init)
+	*(.initcall2.init)
+	*(.initcall3.init)
+	*(.initcall4.init)
+	*(.initcall5.init)
+	*(.initcall6.init)
+	*(.initcall7.init)
+        __initcall_end = .;
+        . = ALIGN(4) ;
+        __init_end = .;
+
+	_edata = . ;
+	edata = ALIGN( 0x10 ) ;
+        } > ram
+        .bss :
+        {
+	_sbss = ALIGN( 0x10 ) ;
+	__bss_start = ALIGN( 0x10 ) ;
+	__data_end = ALIGN( 0x10 ) ;
+	*(.bss)
+	*(COMMON)
+	_ebss = . ;
+	__bss_end = . ;
+	end = ALIGN( 0x10 ) ;
+	_end = ALIGN( 0x10 ) ;
+	} > ram
+	.eram :
+	{
+	__ramend = . ;
+	_ramend = . ;
+	} > eram
+}
diff -Nru a/arch/m68knommu/platform/68VZ328/ucdimm/rom.ld b/arch/m68knommu/platform/68VZ328/ucdimm/rom.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/68VZ328/ucdimm/rom.ld	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,11 @@
+MEMORY 
+	{
+        romvec : ORIGIN = 0x10c10000, LENGTH = 0x00000400
+        flash  : ORIGIN = 0x10c10400, LENGTH = 0x001fec00
+        eflash : ORIGIN = 0x10d00000, LENGTH = 0
+        ramvec : ORIGIN = 0x00000000, LENGTH = 1024
+        ram    : ORIGIN = 0x00020000, LENGTH = 0x00800000 - 0x00020000
+        eram   : ORIGIN = 0x00800000, LENGTH = 0
+	}
+
+INCLUDE arch/m68knommu/platform/68VZ328/ucdimm/fixed.ld
diff -Nru a/arch/m68knommu/platform/Makefile b/arch/m68knommu/platform/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/Makefile	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,6 @@
+#
+# Makefile for the arch/m68knommu/platform.
+#
+
+include $(TOPDIR)/Rules.make
+
diff -Nru a/arch/m68knommu/vmlinux.lds.S b/arch/m68knommu/vmlinux.lds.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/vmlinux.lds.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,115 @@
+
+#include <linux/config.h>
+
+#ifdef CONFIG_PILOT3
+#ifdef CONFIG_ROMKERNEL
+#include "platform/68328/pilot/rom.ld"
+#endif
+#ifdef CONFIG_RAMKERNEL
+#include "platform/68328/pilot/ram.ld"
+#endif
+#endif
+
+#ifdef CONFIG_UCSIMM
+#ifdef CONFIG_RAMKERNEL
+#include "platform/68EZ328/ucsimm/ram.ld"
+#endif
+#ifdef CONFIG_ROMKERNEL
+#include "platform/68EZ328/ucsimm/rom.ld"
+#endif
+#ifdef CONFIG_HIMEMKERNEL
+#include "platform/68EZ328/ucsimm/himem.ld"
+#endif
+#endif
+
+#ifdef CONFIG_UCDIMM
+#ifdef CONFIG_RAMKERNEL
+#include "platform/68VZ328/ucdimm/ram.ld"
+#endif
+#ifdef CONFIG_ROMKERNEL
+#include "platform/68VZ328/ucdimm/rom.ld"
+#endif
+#ifdef CONFIG_HIMEMKERNEL
+#include "platform/68VZ328/ucdimm/himem.ld"
+#endif
+#endif
+#ifdef CONFIG_DRAGEN2
+#ifdef CONFIG_RAMKERNEL
+#include "platform/68VZ328/de2/ram.ld"
+#endif
+#ifdef CONFIG_ROMKERNEL
+#include "platform/68VZ328/de2/rom.ld"
+#endif
+#ifdef CONFIG_HIMEMKERNEL
+#include "platform/68VZ328/de2/himem.ld"
+#endif
+#endif
+
+#ifdef CONFIG_UCQUICC
+#ifdef CONFIG_RAMKERNEL
+#include "platform/68360/uCquicc/ram.ld"
+#endif
+#ifdef CONFIG_ROMKERNEL
+#include "platform/68360/uCquicc/rom.ld"
+#endif
+#endif
+
+#ifdef CONFIG_ARN5206
+#include "platform/5206/ARNEWSH/ram.ld"
+#endif
+
+#ifdef CONFIG_M5206eC3
+#include "platform/5206e/MOTOROLA/ram.ld"
+#endif
+#ifdef CONFIG_ELITE
+#include "platform/5206e/eLITE/ram.ld"
+#endif
+
+#ifdef CONFIG_M5249C3
+#include "platform/5249/MOTOROLA/ram.ld"
+#endif
+
+#ifdef CONFIG_M5272C3
+#include "platform/5272/MOTOROLA/ram.ld"
+#endif
+
+#ifdef CONFIG_ARN5307
+#include "platform/5307/ARNEWSH/ram.ld"
+#endif
+#ifdef CONFIG_M5307C3
+#include "platform/5307/MOTOROLA/ram.ld"
+#endif
+#ifdef CONFIG_eLIA
+#include "platform/5307/eLIA/ram.ld"
+#endif
+#ifdef CONFIG_DISKtel
+#include "platform/5307/DISKtel/ram.ld"
+#endif
+#ifdef CONFIG_SECUREEDGEMP3
+#include "platform/5307/MP3/ram.ld"
+#endif
+
+#ifdef CONFIG_M5407
+#include "platform/5407/MOTOROLA/ram.ld"
+#endif
+
+#ifdef CONFIG_CLEOPATRA
+#ifdef CONFIG_M5307
+#include "platform/5307/CLEOPATRA/ram.ld"
+#endif
+#ifdef CONFIG_M5407
+#include "platform/5407/CLEOPATRA/ram.ld"
+#endif
+#endif
+
+#ifdef CONFIG_NETtel
+#ifdef CONFIG_M5206e
+#include "platform/5206e/NETtel/ram.ld"
+#endif
+#ifdef CONFIG_M5272
+#include "platform/5272/NETtel/ram.ld"
+#endif
+#ifdef CONFIG_M5307
+#include "platform/5307/NETtel/ram.ld"
+#endif
+#endif
diff -Nru a/arch/mips/Kconfig b/arch/mips/Kconfig
--- a/arch/mips/Kconfig	Mon Nov  4 14:31:01 2002
+++ b/arch/mips/Kconfig	Mon Nov  4 14:31:01 2002
@@ -6,6 +6,14 @@
 	bool
 	default y
 
+config MMU
+	bool
+	default y
+
+config SWAP
+	bool
+	default y
+
 config SMP
 	bool
 	---help---
diff -Nru a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c
--- a/arch/mips/au1000/common/time.c	Mon Nov  4 14:31:01 2002
+++ b/arch/mips/au1000/common/time.c	Mon Nov  4 14:31:01 2002
@@ -68,7 +68,7 @@
 		goto null;
 
 	do {
-		kstat.irqs[0][irq]++;
+		kstat_cpu(0).irqs[irq]++;
 		do_timer(regs);
 		r4k_cur += r4k_offset;
 		ack_r4ktimer(r4k_cur);
diff -Nru a/arch/mips/baget/irq.c b/arch/mips/baget/irq.c
--- a/arch/mips/baget/irq.c	Mon Nov  4 14:31:02 2002
+++ b/arch/mips/baget/irq.c	Mon Nov  4 14:31:02 2002
@@ -152,7 +152,7 @@
 		if (!action) 
 			continue;
 		seq_printf(p, "%2d: %8d %c %s",
-			i, kstat.irqs[0][i],
+			i, kstat_cpu(0).irqs[i],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
 			action->name);
 		for (action=action->next; action; action = action->next) {
@@ -180,7 +180,7 @@
 
 	cpu = smp_processor_id();
 	irq_enter(cpu, irq);
-	kstat.irqs[cpu][irq]++;
+	kstat_cpu(cpu).irqs[irq]++;
 
 	mask_irq(irq);  
 	action = *(irq + irq_action);
diff -Nru a/arch/mips/dec/irq.c b/arch/mips/dec/irq.c
--- a/arch/mips/dec/irq.c	Mon Nov  4 14:31:02 2002
+++ b/arch/mips/dec/irq.c	Mon Nov  4 14:31:02 2002
@@ -103,7 +103,7 @@
 		if (!action)
 			continue;
 		seq_printf(p, "%2d: %8d %c %s",
-				i, kstat.irqs[0][i],
+				i, kstat_cpu(0).irqs[i],
 				(action->flags & SA_INTERRUPT) ? '+' : ' ',
 				action->name);
 		for (action = action->next; action; action = action->next) {
@@ -130,7 +130,7 @@
 
     cpu = smp_processor_id();
     irq_enter(cpu, irq);
-    kstat.irqs[cpu][irq]++;
+    kstat_cpu(cpu).irqs[irq]++;
 
     mask_irq(irq);
     action = *(irq + irq_action);
diff -Nru a/arch/mips/ite-boards/generic/irq.c b/arch/mips/ite-boards/generic/irq.c
--- a/arch/mips/ite-boards/generic/irq.c	Mon Nov  4 14:31:02 2002
+++ b/arch/mips/ite-boards/generic/irq.c	Mon Nov  4 14:31:02 2002
@@ -256,7 +256,7 @@
 	cpu = smp_processor_id();
 	irq_enter(cpu, irq);
 
-	kstat.irqs[cpu][irq]++;
+	kstat_cpu(cpu).irqs[irq]++;
 #if 0
 	if (irq_desc[irq].handler && irq_desc[irq].handler->ack) {
 	//	printk("invoking ack handler\n");
diff -Nru a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
--- a/arch/mips/kernel/irq.c	Mon Nov  4 14:31:01 2002
+++ b/arch/mips/kernel/irq.c	Mon Nov  4 14:31:01 2002
@@ -244,7 +244,7 @@
 	struct irqaction * action;
 	unsigned int status;
 
-	kstat.irqs[cpu][irq]++;
+	kstat_cpu(cpu).irqs[irq]++;
 	spin_lock(&desc->lock);
 	desc->handler->ack(irq);
 	/*
diff -Nru a/arch/mips/kernel/old-irq.c b/arch/mips/kernel/old-irq.c
--- a/arch/mips/kernel/old-irq.c	Mon Nov  4 14:31:02 2002
+++ b/arch/mips/kernel/old-irq.c	Mon Nov  4 14:31:02 2002
@@ -134,7 +134,7 @@
 		if (!action) 
 			continue;
 		seq_printf(p, "%2d: %8d %c %s",
-			i, kstat.irqs[0][i],
+			i, kstat_cpu(0).irqs[i],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
 			action->name);
 		for (action=action->next; action; action = action->next) {
@@ -176,7 +176,7 @@
 
 	i8259_mask_and_ack_irq(irq);
 
-	kstat.irqs[cpu][irq]++;
+	kstat_cpu(cpu).irqs[irq]++;
 
 	action = *(irq + irq_action);
 	if (!action)
@@ -214,7 +214,7 @@
 
 	cpu = smp_processor_id();
 	irq_enter(cpu, irq);
-	kstat.irqs[cpu][irq]++;
+	kstat_cpu(cpu).irqs[irq]++;
 
 	action = *(irq + irq_action);
 	if (action) {
diff -Nru a/arch/mips/kernel/old-time.c b/arch/mips/kernel/old-time.c
--- a/arch/mips/kernel/old-time.c	Mon Nov  4 14:31:02 2002
+++ b/arch/mips/kernel/old-time.c	Mon Nov  4 14:31:02 2002
@@ -424,7 +424,7 @@
 	 */
 	write_32bit_cp0_register (CP0_COMPARE, 
 				  (unsigned long) (count + r4k_interval));
-        kstat.irqs[0][irq]++;
+        kstat_cpu(0).irqs[irq]++;
 #endif
 
 	timer_interrupt(irq, dev_id, regs);
diff -Nru a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
--- a/arch/mips/kernel/process.c	Mon Nov  4 14:31:01 2002
+++ b/arch/mips/kernel/process.c	Mon Nov  4 14:31:01 2002
@@ -176,7 +176,7 @@
 		:"=r" (retval)
 		:"i" (__NR_clone), "i" (__NR_exit),
 		 "r" (arg), "r" (fn),
-		 "r" (flags | CLONE_VM)
+		 "r" (flags | CLONE_VM | CLONE_UNTRACED)
 		 /*
 		  * The called subroutine might have destroyed any of the
 		  * at, result, argument or temporary registers ...
diff -Nru a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
--- a/arch/mips/kernel/ptrace.c	Mon Nov  4 14:31:03 2002
+++ b/arch/mips/kernel/ptrace.c	Mon Nov  4 14:31:03 2002
@@ -304,16 +304,8 @@
 		res = ptrace_detach(child, data);
 		break;
 
-	case PTRACE_SETOPTIONS:
-		if (data & PTRACE_O_TRACESYSGOOD)
-			child->ptrace |= PT_TRACESYSGOOD;
-		else
-			child->ptrace &= ~PT_TRACESYSGOOD;
-		res = 0;
-		break;
-
 	default:
-		res = -EIO;
+		res = ptrace_request(child, request, addr, data);
 		goto out;
 	}
 out_tsk:
diff -Nru a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
--- a/arch/mips/kernel/time.c	Mon Nov  4 14:31:01 2002
+++ b/arch/mips/kernel/time.c	Mon Nov  4 14:31:01 2002
@@ -369,7 +369,7 @@
 	int cpu = smp_processor_id();
 
 	irq_enter(cpu, irq);
-	kstat.irqs[cpu][irq]++;
+	kstat_cpu(cpu).irqs[irq]++;
 
 	/* we keep interrupt disabled all the time */
 	timer_interrupt(irq, NULL, regs);
diff -Nru a/arch/mips/mips-boards/atlas/atlas_int.c b/arch/mips/mips-boards/atlas/atlas_int.c
--- a/arch/mips/mips-boards/atlas/atlas_int.c	Mon Nov  4 14:31:02 2002
+++ b/arch/mips/mips-boards/atlas/atlas_int.c	Mon Nov  4 14:31:02 2002
@@ -105,7 +105,7 @@
 		if (!action) 
 			continue;
 		seq_printf(p, "%2d: %8d %c %s",
-			num, kstat.irqs[0][num],
+			num, kstat_cpu(0).irqs[num],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
 			action->name);
 		for (action=action->next; action; action = action->next) {
@@ -202,7 +202,7 @@
 	}
 
 	irq_enter(cpu, irq);
-	kstat.irqs[0][irq]++;
+	kstat_cpu(0).irqs[irq]++;
 	action->handler(irq, action->dev_id, regs);
 	irq_exit(cpu, irq);
 
diff -Nru a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c
--- a/arch/mips/mips-boards/generic/time.c	Mon Nov  4 14:31:02 2002
+++ b/arch/mips/mips-boards/generic/time.c	Mon Nov  4 14:31:02 2002
@@ -139,7 +139,7 @@
 		goto null;
 
 	do {
-		kstat.irqs[0][irq]++;
+		kstat_cpu(0).irqs[irq]++;
 		do_timer(regs);
 
 		/* Historical comment/code:
diff -Nru a/arch/mips/philips/nino/irq.c b/arch/mips/philips/nino/irq.c
--- a/arch/mips/philips/nino/irq.c	Mon Nov  4 14:31:00 2002
+++ b/arch/mips/philips/nino/irq.c	Mon Nov  4 14:31:00 2002
@@ -125,7 +125,7 @@
 	if (!action)
 	    continue;
 	seq_printf(p, "%2d: %8d %c %s",
-		       i, kstat.irqs[0][i],
+		       i, kstat_cpu(0).irqs[i],
 		       (action->flags & SA_INTERRUPT) ? '+' : ' ',
 		       action->name);
 	for (action = action->next; action; action = action->next) {
@@ -161,7 +161,7 @@
 
     cpu = smp_processor_id();
     irq_enter(cpu, irq);
-    kstat.irqs[cpu][irq]++;
+    kstat_cpu(0).irqs[irq]++;
 
     if (irq == 20) {
             printk("20 %08lx %08lx\n   %08lx %08lx\n   %08lx\n",
diff -Nru a/arch/mips/sgi/kernel/indy_int.c b/arch/mips/sgi/kernel/indy_int.c
--- a/arch/mips/sgi/kernel/indy_int.c	Mon Nov  4 14:31:00 2002
+++ b/arch/mips/sgi/kernel/indy_int.c	Mon Nov  4 14:31:00 2002
@@ -418,7 +418,7 @@
 	int irq = 6;
 
 	irq_enter(cpu, irq);
-	kstat.irqs[0][irq]++;
+	kstat_cpu(0).irqs[irq]++;
 	printk("Got a bus error IRQ, shouldn't happen yet\n");
 	show_regs(regs);
 	printk("Spinning...\n");
diff -Nru a/arch/mips/sgi/kernel/time.c b/arch/mips/sgi/kernel/time.c
--- a/arch/mips/sgi/kernel/time.c	Mon Nov  4 14:31:01 2002
+++ b/arch/mips/sgi/kernel/time.c	Mon Nov  4 14:31:01 2002
@@ -13,7 +13,7 @@
 	int irq = 4;
 
 	irq_enter(cpu, irq);
-	kstat.irqs[0][irq]++;
+	kstat_cpu(0).irqs[irq]++;
 	printk("indy_8254timer_irq: Whoops, should not have gotten this IRQ\n");
 	prom_getchar();
 	ArcEnterInteractiveMode();
diff -Nru a/arch/mips64/Kconfig b/arch/mips64/Kconfig
--- a/arch/mips64/Kconfig	Mon Nov  4 14:31:01 2002
+++ b/arch/mips64/Kconfig	Mon Nov  4 14:31:01 2002
@@ -5,6 +5,14 @@
 
 mainmenu "Linux Kernel Configuration"
 
+config MMU
+	bool
+	default y
+
+config SWAP
+	bool
+	default y
+
 source "init/Kconfig"
 
 
diff -Nru a/arch/mips64/kernel/ioctl32.c b/arch/mips64/kernel/ioctl32.c
--- a/arch/mips64/kernel/ioctl32.c	Mon Nov  4 14:31:02 2002
+++ b/arch/mips64/kernel/ioctl32.c	Mon Nov  4 14:31:02 2002
@@ -27,6 +27,7 @@
 #include <linux/auto_fs.h>
 #include <linux/ext2_fs.h>
 #include <linux/raid/md_u.h>
+#include <linux/dm-ioctl.h>
 #include <asm/types.h>
 #include <asm/uaccess.h>
 
@@ -790,6 +791,20 @@
 	IOCTL32_DEFAULT(STOP_ARRAY_RO),
 	IOCTL32_DEFAULT(RESTART_ARRAY_RW),
 #endif /* CONFIG_MD */
+
+#if defined(CONFIG_BLK_DEV_DM) || defined(CONFIG_BLK_DEV_DM_MODULE)
+	IOCTL32_DEFAULT(DM_VERSION),
+	IOCTL32_DEFAULT(DM_REMOVE_ALL),
+	IOCTL32_DEFAULT(DM_DEV_CREATE),
+	IOCTL32_DEFAULT(DM_DEV_REMOVE),
+	IOCTL32_DEFAULT(DM_DEV_RELOAD),
+	IOCTL32_DEFAULT(DM_DEV_SUSPEND),
+	IOCTL32_DEFAULT(DM_DEV_RENAME),
+	IOCTL32_DEFAULT(DM_DEV_DEPS),
+	IOCTL32_DEFAULT(DM_DEV_STATUS),
+	IOCTL32_DEFAULT(DM_TARGET_STATUS),
+	IOCTL32_DEFAULT(DM_TARGET_WAIT),
+#endif /* CONFIG_BLK_DEV_DM */
 
 	IOCTL32_DEFAULT(MTIOCTOP),			/* mtio.h ioctls  */
 	IOCTL32_HANDLER(MTIOCGET32, mt_ioctl_trans),
diff -Nru a/arch/mips64/kernel/process.c b/arch/mips64/kernel/process.c
--- a/arch/mips64/kernel/process.c	Mon Nov  4 14:31:01 2002
+++ b/arch/mips64/kernel/process.c	Mon Nov  4 14:31:01 2002
@@ -167,7 +167,7 @@
 		"1:\tmove\t%0, $2"
 		:"=r" (retval)
 		:"i" (__NR_clone), "i" (__NR_exit), "r" (arg), "r" (fn),
-		 "r" (flags | CLONE_VM)
+		 "r" (flags | CLONE_VM | CLONE_UNTRACED)
 
 		 /* The called subroutine might have destroyed any of the
 		  * at, result, argument or temporary registers ...  */
diff -Nru a/arch/mips64/kernel/ptrace.c b/arch/mips64/kernel/ptrace.c
--- a/arch/mips64/kernel/ptrace.c	Mon Nov  4 14:31:01 2002
+++ b/arch/mips64/kernel/ptrace.c	Mon Nov  4 14:31:01 2002
@@ -275,17 +275,8 @@
 		ret = ptrace_detach(child, data);
 		break;
 
-	case PTRACE_SETOPTIONS: {
-		if (data & PTRACE_O_TRACESYSGOOD)
-			child->ptrace |= PT_TRACESYSGOOD;
-		else
-			child->ptrace &= ~PT_TRACESYSGOOD;
-		ret = 0;
-		break;
-	}
-
 	default:
-		ret = -EIO;
+		ret = ptrace_request(child, request, addr, data);
 		break;
 	}
 
@@ -535,17 +526,8 @@
 		ret = ptrace_detach(child, data);
 		break;
 
-	case PTRACE_SETOPTIONS: {
-		if (data & PTRACE_O_TRACESYSGOOD)
-			child->ptrace |= PT_TRACESYSGOOD;
-		else
-			child->ptrace &= ~PT_TRACESYSGOOD;
-		ret = 0;
-		break;
-	}
-
 	default:
-		ret = -EIO;
+		ret = ptrace_request(child, request, addr, data);
 		break;
 	}
 
diff -Nru a/arch/mips64/mips-boards/atlas/atlas_int.c b/arch/mips64/mips-boards/atlas/atlas_int.c
--- a/arch/mips64/mips-boards/atlas/atlas_int.c	Mon Nov  4 14:31:01 2002
+++ b/arch/mips64/mips-boards/atlas/atlas_int.c	Mon Nov  4 14:31:01 2002
@@ -101,7 +101,7 @@
 		if (!action) 
 			continue;
 		seq_printf(p, "%2d: %8d %c %s",
-			num, kstat.irqs[0][num],
+			num, kstat_cpu(0).irqs[num],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
 			action->name);
 		for (action=action->next; action; action = action->next) {
@@ -198,7 +198,7 @@
 	}
 
 	irq_enter(cpu, irq);
-	kstat.irqs[0][irq]++;
+	kstat_cpu(0).irqs[irq]++;
 	action->handler(irq, action->dev_id, regs);
 	irq_exit(cpu, irq);
 
diff -Nru a/arch/mips64/mips-boards/generic/time.c b/arch/mips64/mips-boards/generic/time.c
--- a/arch/mips64/mips-boards/generic/time.c	Mon Nov  4 14:31:01 2002
+++ b/arch/mips64/mips-boards/generic/time.c	Mon Nov  4 14:31:01 2002
@@ -138,7 +138,7 @@
 		goto null;
 
 	do {
-		kstat.irqs[0][irq]++;
+		kstat_cpu(0).irqs[irq]++;
 		do_timer(regs);
 
 		/* Historical comment/code:
diff -Nru a/arch/mips64/mips-boards/malta/malta_int.c b/arch/mips64/mips-boards/malta/malta_int.c
--- a/arch/mips64/mips-boards/malta/malta_int.c	Mon Nov  4 14:31:02 2002
+++ b/arch/mips64/mips-boards/malta/malta_int.c	Mon Nov  4 14:31:02 2002
@@ -131,7 +131,7 @@
 		if (!action) 
 			continue;
 		seq_printf(p, "%2d: %8d %c %s",
-			num, kstat.irqs[0][num],
+			num, kstat_cpu(0).irqs[num],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
 			action->name);
 		for (action=action->next; action; action = action->next) {
@@ -146,7 +146,7 @@
 		if (!action) 
 			continue;
 		seq_printf(p, "%2d: %8d %c %s",
-			num, kstat.irqs[0][num],
+			num, kstat_cpu(0).irqs[num],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
 			action->name);
 		for (action=action->next; action; action = action->next) {
@@ -322,7 +322,7 @@
 		return;
 
 	irq_enter(cpu, irq);
-	kstat.irqs[0][irq + 8]++;
+	kstat_cpu(0).irqs[irq + 8]++;
 	do {
 	        action->handler(irq, action->dev_id, regs);
 		action = action->next;
diff -Nru a/arch/mips64/sgi-ip22/ip22-int.c b/arch/mips64/sgi-ip22/ip22-int.c
--- a/arch/mips64/sgi-ip22/ip22-int.c	Mon Nov  4 14:31:00 2002
+++ b/arch/mips64/sgi-ip22/ip22-int.c	Mon Nov  4 14:31:00 2002
@@ -243,7 +243,7 @@
 		if (!action) 
 			continue;
 		seq_printf(p, "%2d: %8d %c %s",
-			num, kstat.irqs[0][num],
+			num, kstat_cpu(0).irqs[num],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
 			action->name);
 		for (action=action->next; action; action = action->next) {
@@ -258,7 +258,7 @@
 		if (!action) 
 			continue;
 		seq_printf(p, "%2d: %8d %c %s",
-			num, kstat.irqs[0][num],
+			num, kstat_cpu(0).irqs[num],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
 			action->name);
 		for (action=action->next; action; action = action->next) {
@@ -285,7 +285,7 @@
 
 	cpu = smp_processor_id();
 	irq_enter(cpu, irq);
-	kstat.irqs[0][irq]++;
+	kstat_cpu(0).irqs[irq]++;
 
 	panic(KERN_DEBUG "Got irq %d, press a key.", irq);
 
@@ -444,7 +444,7 @@
 	}
 
 	irq_enter(cpu, irq);
-	kstat.irqs[0][irq + 16]++;
+	kstat_cpu(0).irqs[irq + 16]++;
 	action->handler(irq, action->dev_id, regs);
 	irq_exit(cpu, irq);
 }
@@ -468,7 +468,7 @@
 		action = local_irq_action[irq];
 	}
 	irq_enter(cpu, irq);
-	kstat.irqs[0][irq + 24]++;
+	kstat_cpu(0).irqs[irq + 24]++;
 	action->handler(irq, action->dev_id, regs);
 	irq_exit(cpu, irq);
 }
@@ -479,7 +479,7 @@
 	int irq = 6;
 
 	irq_enter(cpu, irq);
-	kstat.irqs[0][irq]++;
+	kstat_cpu(0).irqs[irq]++;
 	printk("Got a bus error IRQ, shouldn't happen yet\n");
 	show_regs(regs);
 	printk("Spinning...\n");
diff -Nru a/arch/mips64/sgi-ip22/ip22-timer.c b/arch/mips64/sgi-ip22/ip22-timer.c
--- a/arch/mips64/sgi-ip22/ip22-timer.c	Mon Nov  4 14:31:02 2002
+++ b/arch/mips64/sgi-ip22/ip22-timer.c	Mon Nov  4 14:31:02 2002
@@ -98,7 +98,7 @@
         else
             r4k_cur += r4k_offset;
 	ack_r4ktimer(r4k_cur);
-	kstat.irqs[0][irq]++;
+	kstat_cpu(0).irqs[irq]++;
 	do_timer(regs);
 
 	/* We update the Dallas time of day approx. every 11 minutes,
@@ -236,7 +236,7 @@
 	int irq = 4;
 
 	irq_enter(cpu, irq);
-	kstat.irqs[0][irq]++;
+	kstat_cpu(0).irqs[irq]++;
 	panic("indy_8254timer_irq: Whoops, should not have gotten this IRQ\n");
 	irq_exit(cpu, irq);
 }
diff -Nru a/arch/mips64/sgi-ip27/ip27-irq.c b/arch/mips64/sgi-ip27/ip27-irq.c
--- a/arch/mips64/sgi-ip27/ip27-irq.c	Mon Nov  4 14:31:02 2002
+++ b/arch/mips64/sgi-ip27/ip27-irq.c	Mon Nov  4 14:31:02 2002
@@ -146,7 +146,7 @@
 		action = irq_action[i];
 		if (!action) 
 			continue;
-		seq_printf(p, "%2d: %8d %c %s", i, kstat.irqs[0][i],
+		seq_printf(p, "%2d: %8d %c %s", i, kstat_cpu(0).irqs[i],
 		               (action->flags & SA_INTERRUPT) ? '+' : ' ',
 		               action->name);
 		for (action=action->next; action; action = action->next) {
@@ -170,7 +170,7 @@
 	int do_random;
 
 	irq_enter(thiscpu, irq);
-	kstat.irqs[thiscpu][irq]++;
+	kstat_cpu(thiscpu).irqs[irq]++;
 
 	action = *(irq + irq_action);
 	if (action) {
diff -Nru a/arch/mips64/sgi-ip27/ip27-timer.c b/arch/mips64/sgi-ip27/ip27-timer.c
--- a/arch/mips64/sgi-ip27/ip27-timer.c	Mon Nov  4 14:31:01 2002
+++ b/arch/mips64/sgi-ip27/ip27-timer.c	Mon Nov  4 14:31:01 2002
@@ -103,7 +103,7 @@
 	if (LOCAL_HUB_L(PI_RT_COUNT) >= ct_cur[cpu])
 		goto again;
 
-	kstat.irqs[cpu][irq]++;		/* kstat only for bootcpu? */
+	kstat_cpu(cpu).irqs[irq]++;		/* kstat only for bootcpu? */
 
 	if (cpu == 0)
 		do_timer(regs);
diff -Nru a/arch/parisc/Kconfig b/arch/parisc/Kconfig
--- a/arch/parisc/Kconfig	Mon Nov  4 14:31:02 2002
+++ b/arch/parisc/Kconfig	Mon Nov  4 14:31:02 2002
@@ -3,15 +3,24 @@
 # see the Configure script.
 #
 
-mainmenu "Linux Kernel Configuration"
+mainmenu "Linux/PA-RISC Kernel Configuration"
 
 config PARISC
 	bool
 	default y
 	help
-	  The PA-RISC microprocessor is a RISC chip designed by
-	  Hewlett-Packard and used in their line of workstations.  The PA-RISC
-	  Linux project has a home page at <www.parisc-linux.org>.
+	  The PA-RISC microprocessor is designed by Hewlett-Packard and used
+	  in many of their workstations & servers (HP9000 700 and 800 series,
+	  and later HP3000 series).  The PA-RISC Linux project home page is
+	  at <http://www.parisc-linux.org/>.
+
+config MMU
+	bool
+	default y
+
+config SWAP
+	bool
+	default y
 
 config UID16
 	bool
@@ -25,16 +34,72 @@
 
 config GENERIC_ISA_DMA
 	bool
-	default y
+
+# unless you want to implement ACPI on PA-RISC ... ;-)
+config PM
+	bool
 
 source "init/Kconfig"
 
 
-menu "General options"
+menu "Processor type and features"
 
-# bool 'Symmetric multi-processing support' CONFIG_SMP
-config SMP
+choice
+	prompt "Processor type"
+	default PA7000
+
+config PA7000
+	bool "PA7000/PA7100"
+	---help---
+	  This is the processor type of your CPU. This information is used for
+	  optimizing purposes.  In order to compile a kernel that can run on
+	  all PA CPUs (albeit not optimally fast), you can specify "PA7000"
+	  here.
+
+	  Specifying "PA8000" here will allow you to select a 64-bit kernel
+	  which is required on some machines.
+
+config PA7100LC
+	bool "PA7100LC/PA7300LC"
+	help
+	  Select this option for a 7100LC or 7300LC processor, as used
+	  in the 712, 715/Mirage, A180, B132, C160L and some other machines.
+
+config PA7200
+	bool "PA7200"
+	help
+	  Select this option for the PCX-T' processor, as used in C110, D100
+	  and similar machines.
+
+config PA8X00
+	bool "PA8000 and up"
+	help
+	  Select this option for PCX-U to PCX-W2 processors.
+
+endchoice
+
+# Define implied options from the CPU selection here
+
+config PA20
 	bool
+	depends on PA8X00
+	default y
+
+config PA11
+	bool
+	depends on PA7000 || PA7100LC || PA7200
+	default y
+
+config PARISC64
+	bool "64-bit kernel"
+	depends on PA8X00
+
+config PDC_NARROW
+	bool "32-bit firmware"
+	depends on PARISC64
+
+config SMP
+	bool "Symmetric multi-processing support"
 	---help---
 	  This enables support for systems with more than one CPU. If you have
 	  a system with only one CPU, like most personal computers, say N. If
@@ -46,97 +111,36 @@
 	  singleprocessor machines. On a singleprocessor machine, the kernel
 	  will run faster if you say N here.
 
-	  Note that if you say Y here and choose architecture "586" or
-	  "Pentium" under "Processor family", the kernel will not work on 486
-	  architectures. Similarly, multiprocessor kernels for the "PPro"
-	  architecture may not work on all Pentium based boards.
-
-	  People using multiprocessor machines who say Y here should also say
-	  Y to "Enhanced Real Time Clock Support", below. The "Advanced Power
-	  Management" code will be disabled if you say Y here.
-
 	  See also the <file:Documentation/smp.tex>,
-	  <file:Documentation/smp.txt>, <file:Documentation/i386/IO-APIC.txt>,
-	  <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at
+	  <file:Documentation/smp.txt>, <file:Documentation/nmi_watchdog.txt>
+	  and the SMP-HOWTO available at
 	  <http://www.linuxdoc.org/docs.html#howto>.
 
 	  If you don't know what to do here, say N.
 
+config PREEMPT
+	bool
+#	bool "Preemptible Kernel"
+	default n
+
 config NR_CPUS
 	int "Maximum number of CPUs (2-32)"
 	depends on SMP
 	default "32"
 
-config KWDB
-	bool "Kernel Debugger support"
-	help
-	  Include in-kernel hooks for kdb, the source level debugger for the
-	  PA-RISC port.
+endmenu
 
-# define_bool CONFIG_KWDB n
-# bool 'GSC/Gecko bus support' CONFIG_GSC y
-config GSC
-	bool
-	default y
 
-config IOMMU_CCIO
-	bool "U2/Uturn I/O MMU"
-	help
-	  Say Y here to enable DMA management routines for the first
-	  generation of PA-RISC cache-coherent machines.  Programs the
-	  U2/Uturn chip in "Virtual Mode" and use the I/O MMU.
+source "drivers/parisc/Kconfig"
 
-config GSC_LASI
-	bool "LASI I/O support"
-	help
-	  Say Y here to directly support the LASI controller chip found on
-	  PA-RISC workstations.  Linux-oriented documentation for this chip
-	  can be found at <http://www.parisc-linux.org/documentation/>.
 
-config PCI
-	bool "PCI support"
-	help
-	  Find out whether you have a PCI motherboard. PCI is the name of a
-	  bus system, i.e. the way the CPU talks to the other stuff inside
-	  your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
-	  VESA. If you have PCI, say Y, otherwise N.
-
-	  The PCI-HOWTO, available from
-	  <http://www.linuxdoc.org/docs.html#howto>, contains valuable
-	  information about which PCI hardware does work under Linux and which
-	  doesn't.
-
-config GSC_DINO
-	bool "GSCtoPCI/DINO PCI support"
-	depends on PCI
-
-config PCI_LBA
-	bool "LBA/Elroy PCI support"
-	depends on PCI
-	help
-	  Say Y here to give the PA-RISC kernel access to PCI configuration
-	  and IO-port space on PA-RISC workstations equipped with a Lower Bus
-	  Adapter (LBA).  This includes A, B, C, J, L, and N-class machines
-	  with 4-digit model numbers, also the A300.
+menu "Executable file formats"
 
-config IOSAPIC
+config KCORE_ELF
 	bool
-	depends on PCI_LBA
+	depends on PROC_FS
 	default y
 
-config IOMMU_SBA
-	bool
-	depends on PCI_LBA
-	default y
-
-#
-# if [ "$CONFIG_PCI_EPIC" = "y" ]; then...
-#
-endmenu
-
-
-menu "General setup"
-
 config BINFMT_SOM
 	tristate "Kernel support for SOM binaries"
 	help
@@ -197,116 +201,25 @@
 	  you have use for it; the module is called binfmt_misc.o. If you
 	  don't know what to answer at this point, say Y.
 
-config BINFMT_JAVA
-	tristate "Kernel support for JAVA binaries (obsolete)"
-	depends on EXPERIMENTAL
-	help
-	  If you say Y here, the kernel will load and execute Java J-code
-	  binaries directly.  Note: this option is obsolete and scheduled for
-	  removal, use CONFIG_BINFMT_MISC instead.
-
 endmenu
 
-##source drivers/parport/Config.in
+# source "drivers/mtd/Kconfig"
 
-menu "Parallel port support"
+source "drivers/parport/Kconfig"
 
-config PARPORT
-	tristate "Parallel port support"
-	---help---
-	  If you want to use devices connected to your machine's parallel port
-	  (the connector at the computer with 25 holes), e.g. printer, ZIP
-	  drive, PLIP link (Parallel Line Internet Protocol is mainly used to
-	  create a mini network by connecting the parallel ports of two local
-	  machines) etc., then you need to say Y here; please read
-	  <file:Documentation/parport.txt> and
-	  <file:drivers/parport/BUGS-parport>.
-
-	  For extensive information about drivers for many devices attaching
-	  to the parallel port see <http://www.torque.net/linux-pp.html> on
-	  the WWW.
-
-	  It is possible to share a single parallel port among several devices
-	  and it is safe to compile all the corresponding drivers into the
-	  kernel.  If you want to compile parallel port support as a module
-	  ( = code which can be inserted in and removed from the running
-	  kernel whenever you want), say M here and read
-	  <file:Documentation/modules.txt>.  The module will be called
-	  parport.o.  If you have more than one parallel port and want to
-	  specify which port and IRQ to be used by this driver at module load
-	  time, take a look at <file:Documentation/parport.txt>.
-
-	  If unsure, say Y.
-
-config PARPORT_PC
-	tristate "PC-style hardware"
-	depends on PCI && PARPORT
-	---help---
-	  You should say Y here if you have a PC-style parallel port. All IBM
-	  PC compatible computers and some Alphas have PC-style parallel
-	  ports.
-
-	  This code is also available as a module.  If you want to compile it
-	  as a module ( = code which can be inserted in and removed from the
-	  running kernel whenever you want), say M here and read
-	  <file:Documentation/modules.txt>.  The module will be called
-	  parport_pc.o.
-
-	  If unsure, say Y.
-
-config PARPORT_PC_FIFO
-	bool "Use FIFO/DMA if available"
-	depends on PARPORT_PC
-	help
-	  Many parallel port chipsets provide hardware that can speed up
-	  printing. Say Y here if you want to take advantage of that.
+# source "drivers/pnp/Kconfig"
 
-	  As well as actually having a FIFO, or DMA capability, the kernel
-	  will need to know which IRQ the parallel port has.  By default,
-	  parallel port interrupts will not be used, and so neither will the
-	  FIFO.  See <file:Documentation/parport.txt> to find out how to
-	  specify which IRQ/DMA to use.
-
-config PARPORT_PC_SUPERIO
-	bool "SuperIO chipset support (EXPERIMENTAL)"
-	depends on PARPORT_PC && EXPERIMENTAL
-	help
-	  Saying Y here enables some probes for Super-IO chipsets in order to
-	  find out things like base addresses, IRQ lines and DMA channels.  It
-	  is safe to say N.
-
-config PARPORT_GSC
-	tristate "LASI/ASP builtin parallel-port"
-	depends on GSC_LASI && PARPORT
-	help
-	  Say Y here to build in low-level parallel-support for PC-style
-	  hardware integrated in the LASI-Controller (on the GSC Bus) for
-	  HP-PARISC workstations.
-
-# If exactly one hardware type is selected then parport will optimise away
-# support for loading any others.  Defeat this if the user is keen.
-config PARPORT_OTHER
-	bool "Support foreign hardware"
-	depends on PARPORT
-	help
-	  Say Y here if you want to be able to load driver modules to support
-	  other non-standard types of parallel ports. This causes a
-	  performance loss, so most people say N.
-
-config PARPORT_1284
-	bool "IEEE 1284 transfer modes"
-	depends on PARPORT
-	help
-	  If you have a printer that supports status readback or device ID, or
-	  want to use a device that uses enhanced parallel port transfer modes
-	  such as EPP and ECP, say Y here to enable advanced IEEE 1284
-	  transfer modes. Also say Y if you want device ID information to
-	  appear in /proc/sys/dev/parport/*/autoprobe*. It is safe to say N.
+source "drivers/block/Kconfig"
 
-endmenu
+menu "ATA/IDE/MFM/RLL support"
+	depends on SUPERIO
 
-source "drivers/block/Kconfig"
+config IDE
+	tristate "ATA/IDE/MFM/RLL support"
 
+source "drivers/ide/Kconfig"
+
+endmenu
 
 menu "SCSI support"
 
@@ -330,304 +243,20 @@
 	  module if your root file system (the one containing the directory /)
 	  is located on a SCSI device.
 
-comment "SCSI support type (disk, tape, CDrom)"
-	depends on SCSI
-
-config BLK_DEV_SD
-	tristate "SCSI disk support"
-	depends on SCSI
-	---help---
-	  If you want to use a SCSI hard disk or the SCSI or parallel port
-	  version of the IOMEGA ZIP drive under Linux, say Y and read the
-	  SCSI-HOWTO, the Disk-HOWTO and the Multi-Disk-HOWTO, available from
-	  <http://www.linuxdoc.org/docs.html#howto>. This is NOT for SCSI
-	  CD-ROMs.
-
-	  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 will be called sd_mod.o.  If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi.txt>.  Do not compile this driver as a
-	  module if your root file system (the one containing the directory /)
-	  is located on a SCSI disk. In this case, do not compile the driver
-	  for your SCSI host adapter (below) as a module either.
+source drivers/scsi/Kconfig
 
-config SD_EXTRA_DEVS
-	int "Maximum number of SCSI disks that can be loaded as modules"
-	depends on BLK_DEV_SD
-	default "40"
-	---help---
-	  This controls the amount of additional space allocated in tables for
-	  drivers that are loaded as modules after the kernel is booted.  In
-	  the event that the SCSI core itself was loaded as a module, this
-	  value is the number of additional disks that can be loaded after the
-	  first host driver is loaded.
-
-	  Admittedly this isn't pretty, but there are tons of race conditions
-	  involved with resizing the internal arrays on the fly.  Someday this
-	  flag will go away, and everything will work automatically.
-
-	  If you don't understand what's going on, go with the default.
-
-config CHR_DEV_ST
-	tristate "SCSI tape support"
-	depends on SCSI
-	---help---
-	  If you want to use a SCSI tape drive under Linux, say Y and read the
-	  SCSI-HOWTO, available from
-	  <http://www.linuxdoc.org/docs.html#howto>, and
-	  <file:drivers/scsi/README.st> in the kernel source.  This is NOT for
-	  SCSI CD-ROMs.
-
-	  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 will be called st.o. If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi.txt>.
-
-config BLK_DEV_SR
-	tristate "SCSI CDROM support"
-	depends on SCSI
-	---help---
-	  If you want to use a SCSI CD-ROM under Linux, say Y and read the
-	  SCSI-HOWTO and the CD-ROM-HOWTO at
-	  <http://www.linuxdoc.org/docs.html#howto>. Also make sure to say Y
-	  or M to "ISO 9660 CD-ROM file system support" later.
-
-	  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 will be called sr_mod.o. If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi.txt>.
-
-config BLK_DEV_SR_VENDOR
-	bool "Enable vendor-specific extensions (for SCSI CDROM)"
-	depends on BLK_DEV_SR
-	help
-	  This enables the usage of vendor specific SCSI commands. This is
-	  required to support multisession CDs with old NEC/TOSHIBA cdrom
-	  drives (and HP Writers). If you have such a drive and get the first
-	  session only, try saying Y here; everybody else says N.
-
-config SR_EXTRA_DEVS
-	int "Maximum number of CDROM devices that can be loaded as modules"
-	depends on BLK_DEV_SR
-	default "2"
-	---help---
-	  This controls the amount of additional space allocated in tables for
-	  drivers that are loaded as modules after the kernel is booted. In
-	  the event that the SCSI core itself was loaded as a module, this
-	  value is the number of additional CD-ROMs that can be loaded after
-	  the first host driver is loaded.
-
-	  Admittedly this isn't pretty, but there are tons of race conditions
-	  involved with resizing the internal arrays on the fly.  Someday this
-	  flag will go away, and everything will work automatically.
-
-	  If you don't understand what's going on, go with the default.
-
-config CHR_DEV_SG
-	tristate "SCSI generic support"
-	depends on SCSI
-	---help---
-	  If you want to use SCSI scanners, synthesizers or CD-writers or just
-	  about anything having "SCSI" in its name other than hard disks,
-	  CD-ROMs or tapes, say Y here. These won't be supported by the kernel
-	  directly, so you need some additional software which knows how to
-	  talk to these devices using the SCSI protocol:
-
-	  For scanners, look at SANE (<http://www.mostang.com/sane/>). For CD
-	  writer software look at Cdrtools
-	  (<http://www.fokus.gmd.de/research/cc/glone/employees/joerg.schilling/private/cdrecord.html>)
-	  and for burning a "disk at once": CDRDAO
-	  (<http://cdrdao.sourceforge.net/>). Cdparanoia is a high
-	  quality digital reader of audio CDs (<http://www.xiph.org/paranoia/>).
-	  For other devices, it's possible that you'll have to write the
-	  driver software yourself. Please read the file
-	  <file:Documentation/scsi-generic.txt> for more information.
-
-	  If you want to compile this as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want),
-	  say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi.txt>. The module will be called sg.o. If unsure,
-	  say N.
-
-comment "Some SCSI devices (e.g. CD jukebox) support multiple LUNs"
-	depends on SCSI
-
-config SCSI_MULTI_LUN
-	bool "Probe all LUNs on each SCSI device"
-	depends on SCSI
-	help
-	  If you have a SCSI device that supports more than one LUN (Logical
-	  Unit Number), e.g. a CD jukebox, and only one LUN is detected, you
-	  can say Y here to force the SCSI driver to probe for multiple LUNs.
-	  A SCSI device with multiple LUNs acts logically like multiple SCSI
-	  devices. The vast majority of SCSI devices have only one LUN, and
-	  so most people can say N here and should in fact do so, because it
-	  is safer.
-
-config SCSI_CONSTANTS
-	bool "Verbose SCSI error reporting (kernel size +=12K)"
-	depends on SCSI
-	help
-	  The error messages regarding your SCSI hardware will be easier to
-	  understand if you say Y here; it will enlarge your kernel by about
-	  12 KB. If in doubt, say Y.
-
-
-menu "SCSI low-level drivers"
-	depends on SCSI!=n
-
-config SCSI_LASI
-	tristate "Lasi SCSI support"
-	depends on GSC_LASI && SCSI
+endmenu
 
-config SCSI_ZALON
-	tristate "Zalon SCSI support"
-	depends on GSC_LASI && SCSI
-	help
-	  The Zalon is an interface chip that sits between the PA-RISC
-	  processor and the NCR 53c720 SCSI controller on K-series PA-RISC
-	  boards (these are used, among other places, on some HP 780
-	  workstations).  Say Y here to make sure it gets initialized
-	  correctly before the Linux kernel tries to talk to the controller.
-
-config SCSI_SYM53C8XX
-	tristate "SYM53C8XX SCSI support"
-	depends on PCI && SCSI
-	---help---
-	  This driver supports all the features of recent 53C8XX chips (used
-	  in PCI SCSI controllers), notably the hardware phase mismatch
-	  feature of the SYM53C896.
-
-	  Older versions of the 53C8XX chips are not supported by this
-	  driver.  If your system uses either a 810 rev. < 16, a 815, or a 825
-	  rev. < 16 PCI SCSI processor, you must use the generic NCR53C8XX
-	  driver ("NCR53C8XX SCSI support" above) or configure both the
-	  NCR53C8XX and this SYM53C8XX drivers either as module or linked to
-	  the kernel image.
-
-	  When both drivers are linked into the kernel, the SYM53C8XX driver
-	  is called first at initialization and you can use the 'excl=ioaddr'
-	  driver boot option to exclude attachment of adapters by the
-	  SYM53C8XX driver.  For example, entering
-	  'sym53c8xx=excl:0xb400,excl=0xc000' at the lilo prompt prevents
-	  adapters at io address 0xb400 and 0xc000 from being attached by the
-	  SYM53C8XX driver, thus allowing the NCR53C8XX driver to attach them.
-	  The 'excl' option is also supported by the NCR53C8XX driver.
-
-	  Please read <file:drivers/scsi/README.ncr53c8xx> for more
-	  information.
-
-config SCSI_NCR53C8XX_DEFAULT_TAGS
-	int "default tagged command queue depth"
-	depends on SCSI_ZALON || SCSI_SYM53C8XX
-	default "8"
-	---help---
-	  "Tagged command queuing" is a feature of SCSI-2 which improves
-	  performance: the host adapter can send several SCSI commands to a
-	  device's queue even if previous commands haven't finished yet.
-	  Because the device is intelligent, it can optimize its operations
-	  (like head positioning) based on its own request queue. Some SCSI
-	  devices don't implement this properly; if you want to disable this
-	  feature, enter 0 or 1 here (it doesn't matter which).
-
-	  The default value is 8 and should be supported by most hard disks.
-	  This value can be overridden from the boot command line using the
-	  'tags' option as follows (example):
-	  'ncr53c8xx=tags:4/t2t3q16/t0u2q10' will set default queue depth to
-	  4, set queue depth to 16 for target 2 and target 3 on controller 0
-	  and set queue depth to 10 for target 0 / lun 2 on controller 1.
-
-	  The normal answer therefore is to go with the default 8 and to use
-	  a boot command line option for devices that need to use a different
-	  command queue depth.
-
-	  There is no safe option other than using good SCSI devices.
-
-config SCSI_NCR53C8XX_MAX_TAGS
-	int "maximum number of queued commands"
-	depends on SCSI_ZALON || SCSI_SYM53C8XX
-	default "32"
-	---help---
-	  This option allows you to specify the maximum number of commands
-	  that can be queued to any device, when tagged command queuing is
-	  possible. The default value is 32. Minimum is 2, maximum is 64.
-	  Modern hard disks are able to support 64 tags and even more, but
-	  do not seem to be faster when more than 32 tags are being used.
-
-	  So, the normal answer here is to go with the default value 32 unless
-	  you are using very large hard disks with large cache (>= 1 MB) that
-	  are able to take advantage of more than 32 tagged commands.
-
-	  There is no safe option and the default answer is recommended.
-
-config SCSI_NCR53C8XX_SYNC
-	int "synchronous transfers frequency in MHz"
-	depends on SCSI_ZALON || SCSI_SYM53C8XX
-	default "20"
-	---help---
-	  The SCSI Parallel Interface-2 Standard defines 5 classes of transfer
-	  rates: FAST-5, FAST-10, FAST-20, FAST-40 and FAST-80.  The numbers
-	  are respectively the maximum data transfer rates in mega-transfers
-	  per second for each class.  For example, a FAST-20 Wide 16 device is
-	  able to transfer data at 20 million 16 bit packets per second for a
-	  total rate of 40 MB/s.
-
-	  You may specify 0 if you want to only use asynchronous data
-	  transfers. This is the safest and slowest option. Otherwise, specify
-	  a value between 5 and 80, depending on the capability of your SCSI
-	  controller.  The higher the number, the faster the data transfer.
-	  Note that 80 should normally be ok since the driver decreases the
-	  value automatically according to the controller's capabilities.
-
-	  Your answer to this question is ignored for controllers with NVRAM,
-	  since the driver will get this information from the user set-up.  It
-	  also can be overridden using a boot setup option, as follows
-	  (example): 'ncr53c8xx=sync:12' will allow the driver to negotiate
-	  for FAST-20 synchronous data transfer (20 mega-transfers per
-	  second).
-
-	  The normal answer therefore is not to go with the default but to
-	  select the maximum value 80 allowing the driver to use the maximum
-	  value supported by each controller. If this causes problems with
-	  your SCSI devices, you should come back and decrease the value.
-
-	  There is no safe option other than using good cabling, right
-	  terminations and SCSI conformant devices.
-
-config SCSI_NCR53C8XX_PROFILE
-	bool "enable profiling"
-	depends on SCSI_ZALON || SCSI_SYM53C8XX
-	help
-	  This option allows you to enable profiling information gathering.
-	  These statistics are not very accurate due to the low frequency
-	  of the kernel clock (100 Hz on i386) and have performance impact
-	  on systems that use very fast devices.
-
-	  The normal answer therefore is N.
-
-config SCSI_NCR53C8XX_IOMAPPED
-	bool "use normal IO"
-	depends on SCSI_ZALON || SCSI_SYM53C8XX
-	help
-	  If you say Y here, the driver will use normal IO, as opposed to
-	  memory mapped IO. Memory mapped IO has less latency than normal IO
-	  and works for most Intel-based hardware. Under Linux/Alpha only
-	  normal IO is currently supported by the driver and so, this option
-	  has no effect on those systems.
+source "drivers/md/Kconfig"
 
-	  The normal answer therefore is N; try Y only if you encounter SCSI
-	  related problems.
+#source drivers/message/fusion/Kconfig
 
-endmenu
+#source drivers/ieee1394/Kconfig
 
-endmenu
+#source drivers/message/i2o/Kconfig
 
 source "net/Kconfig"
 
-
 menu "Network device support"
 	depends on NET
 
@@ -662,23 +291,52 @@
 	  Guide", to be found in <http://www.linuxdoc.org/docs.html#guide>. If
 	  unsure, say Y.
 
-config LASI_82596
-	tristate "Lasi ethernet"
-	depends on NETDEVICES && GSC_LASI
-	help
-	  Say Y here to support the on-board Intel 82596 ethernet controller
-	  built into Hewlett-Packard PA-RISC machines.
-
 source "drivers/net/Kconfig"
 
+source "drivers/atm/Kconfig"
+
 endmenu
 
+#source "net/ax25/Kconfig"
+
+source "net/irda/Kconfig"
+
+#source "drivers/isdn/Kconfig"
+
+#source "drivers/telephony/Kconfig"
+
+# input before char - char/joystick depends on it. As does USB.
+source "drivers/input/Kconfig"
+
 source "drivers/char/Kconfig"
 
+#source "drivers/misc/Kconfig"
+
+source "drivers/media/Kconfig"
+
 source "fs/Kconfig"
 
 
-menu "Sound Drivers"
+menu "Console drivers"
+	depends on VT
+
+config STI_CONSOLE
+	bool "STI console"
+	help
+	  The STI console is the builtin display/keyboard on HP-PARISC
+	  machines.  Say Y here to build support for it into your kernel.
+	  The alternative is to use your primary serial port as a console.
+
+config DUMMY_CONSOLE
+	bool
+	depends on STI_CONSOLE || SERIAL_8250_CONSOLE
+	default y
+
+source "drivers/video/Kconfig"
+
+endmenu
+
+menu "Sound"
 
 config SOUND
 	tristate "Sound card support"
@@ -714,34 +372,29 @@
 
 endmenu
 
+source "drivers/usb/Kconfig"
 
-menu "Console drivers"
-	depends on VT
+source "net/bluetooth/Kconfig"
 
-source "drivers/video/Kconfig"
+menu "Kernel hacking"
 
-#  bool 'IODC console' CONFIG_IODC_CONSOLE
-config STI_CONSOLE
-	bool "STI console"
+config DEBUG_KERNEL
+	bool "Kernel debugging"
 	help
-	  The STI console is the builtin display/keyboard on HP-PARISC
-	  machines.  Say Y here to build support for it into your kernel.
-	  The alternative is to use your primary serial port as a console.
+	  Say Y here if you are developing drivers or trying to debug and
+	  identify kernel problems.
 
-config DUMMY_CONSOLE
-	bool
-	depends on STI_CONSOLE || !IODC_CONSOLE && GSC_PS2
-	default y
-
-endmenu
+config DEBUG_SLAB
+	bool "Debug memory allocations"
+	depends on DEBUG_KERNEL
+	help
+	  Say Y here to have the kernel do limited verification on memory
+	  allocation as well as poisoning memory on free to catch use of freed
+	  memory.
 
-# endmenu
-
-menu "Kernel hacking"
-
-#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
 config MAGIC_SYSRQ
 	bool "Magic SysRq key"
+	depends on DEBUG_KERNEL
 	help
 	  If you say Y here, you will have some control over the system even
 	  if the system crashes for example during kernel debugging (e.g., you
@@ -752,6 +405,14 @@
 	  send a BREAK and then within 5 seconds a command keypress. The
 	  keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
 	  unless you really know what this hack does.
+
+config KALLSYMS
+	bool "Load all symbols for debugging/kksymoops"
+	depends on DEBUG_KERNEL
+	help
+	  Say Y here to let the kernel print out symbolic crash information and
+	  symbolic stack backtraces. This increases the size of the kernel
+	  somewhat, as all symbols have to be loaded into the kernel image.
 
 endmenu
 
diff -Nru a/arch/parisc/Makefile b/arch/parisc/Makefile
--- a/arch/parisc/Makefile	Mon Nov  4 14:31:02 2002
+++ b/arch/parisc/Makefile	Mon Nov  4 14:31:02 2002
@@ -80,7 +80,6 @@
 					   arch/parisc/kernel/init_task.o
 libs-y					+= arch/parisc/lib/ \
 					   `$(CC) -print-libgcc-file-name`
-drivers-$(CONFIG_MATH_EMULATION)	+= arch/parisc/math-emu/
 
 palo: vmlinux
 	@if [ $$(palo -f /dev/null >/dev/null 2>&1 ; echo $$?) != 2 ]; then \
diff -Nru a/arch/parisc/hpux/Makefile b/arch/parisc/hpux/Makefile
--- a/arch/parisc/hpux/Makefile	Mon Nov  4 14:31:02 2002
+++ b/arch/parisc/hpux/Makefile	Mon Nov  4 14:31:02 2002
@@ -1,9 +1,5 @@
 #
-# Makefile for the linux kernel.
+# Makefile for HPUX emulation
 #
 
 obj-y := entry_hpux.o gate.o wrappers.o fs.o ioctl.o sys_hpux.o
-
-EXTRA_AFLAGS := -traditional
-
-include $(TOPDIR)/Rules.make
diff -Nru a/arch/parisc/hpux/entry_hpux.S b/arch/parisc/hpux/entry_hpux.S
--- a/arch/parisc/hpux/entry_hpux.S	Mon Nov  4 14:31:01 2002
+++ b/arch/parisc/hpux/entry_hpux.S	Mon Nov  4 14:31:01 2002
@@ -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 -Nru a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c
--- a/arch/parisc/hpux/fs.c	Mon Nov  4 14:31:01 2002
+++ b/arch/parisc/hpux/fs.c	Mon Nov  4 14:31:01 2002
@@ -34,8 +34,7 @@
 }
 
 struct hpux_dirent {
-	long	d_off_pad; /* we only have a 32-bit off_t */
-	long	d_off;
+	loff_t	d_off;
 	ino_t	d_ino;
 	short	d_reclen;
 	short	d_namlen;
@@ -52,7 +51,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 d_type)
 {
 	struct hpux_dirent * dirent;
 	struct getdents_callback * buf = (struct getdents_callback *) __buf;
@@ -96,7 +96,7 @@
 	buf.count = count;
 	buf.error = 0;
 
-	error = vfs_readdir(file, &buf, filldir);
+	error = vfs_readdir(file, filldir, &buf);
 	if (error < 0)
 		goto out_putf;
 	error = buf.error;
@@ -139,7 +139,7 @@
 	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
 }
 
-long hpux_stat64(const char *path, struct hpux_stat64 *buf)
+long hpux_stat64(char *filename, struct hpux_stat64 *statbuf)
 {
 	struct kstat stat;
 	int error = vfs_stat(filename, &stat);
diff -Nru a/arch/parisc/hpux/gate.S b/arch/parisc/hpux/gate.S
--- a/arch/parisc/hpux/gate.S	Mon Nov  4 14:31:02 2002
+++ b/arch/parisc/hpux/gate.S	Mon Nov  4 14:31:02 2002
@@ -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/offsets.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 -Nru a/arch/parisc/hpux/ioctl.c b/arch/parisc/hpux/ioctl.c
--- a/arch/parisc/hpux/ioctl.c	Mon Nov  4 14:31:01 2002
+++ b/arch/parisc/hpux/ioctl.c	Mon Nov  4 14:31:01 2002
@@ -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 -Nru a/arch/parisc/hpux/sys_hpux.c b/arch/parisc/hpux/sys_hpux.c
--- a/arch/parisc/hpux/sys_hpux.c	Mon Nov  4 14:31:02 2002
+++ b/arch/parisc/hpux/sys_hpux.c	Mon Nov  4 14:31:02 2002
@@ -4,10 +4,15 @@
  * implements HPUX syscalls.
  */
 
+#include <linux/fs.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/utsname.h>
+#include <linux/vmalloc.h>
+
 #include <asm/errno.h>
+#include <asm/pgalloc.h>
 #include <asm/uaccess.h>
 
 unsigned long sys_brk(unsigned long addr);
@@ -41,6 +46,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
@@ -127,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().
@@ -330,4 +406,542 @@
 	error = do_pipe(kstack_fildes);
 	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 -Nru a/arch/parisc/hpux/wrappers.S b/arch/parisc/hpux/wrappers.S
--- a/arch/parisc/hpux/wrappers.S	Mon Nov  4 14:31:02 2002
+++ b/arch/parisc/hpux/wrappers.S	Mon Nov  4 14:31:02 2002
@@ -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
  *
@@ -24,12 +24,11 @@
 #warning Must be changed for PA64
 #endif
 
-#include <asm/offset.h>
+#include <asm/offsets.h>
 
 	.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,12 @@
 
 	/* Set the return value for the child */
 
-child_return:
+hpux_child_return:
+#if CONFIG_SMP || CONFIG_PREEMPT
+	bl	schedule_tail, %r2
+	nop
+#endif
+
 	ldw TASK_PT_GR19-TASK_SZ_ALGN-128(%r30),%r2
 	b fork_return
 	copy %r0,%r28
@@ -242,3 +245,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 -Nru a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile
--- a/arch/parisc/kernel/Makefile	Mon Nov  4 14:31:01 2002
+++ b/arch/parisc/kernel/Makefile	Mon Nov  4 14:31:01 2002
@@ -1,5 +1,5 @@
 #
-# Makefile for the linux kernel.
+# Makefile for arch/parisc/kernel
 #
 
 ifdef CONFIG_PARISC64
@@ -27,5 +27,3 @@
 		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 -Nru a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c
--- a/arch/parisc/kernel/asm-offsets.c	Mon Nov  4 14:31:00 2002
+++ b/arch/parisc/kernel/asm-offsets.c	Mon Nov  4 14:31:00 2002
@@ -35,6 +35,7 @@
 	DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
 	DEFINE(TASK_MM, offsetof(struct task_struct, mm));
 	DEFINE(TASK_PERSONALITY, offsetof(struct task_struct, personality));
+	DEFINE(TASK_PID, offsetof(struct task_struct, pid));
 	BLANK();
 	DEFINE(TASK_REGS, offsetof(struct task_struct, thread.regs));
 	DEFINE(TASK_PT_PSW, offsetof(struct task_struct, thread.regs.gr[ 0]));
diff -Nru a/arch/parisc/kernel/ccio-dma.c b/arch/parisc/kernel/ccio-dma.c
--- a/arch/parisc/kernel/ccio-dma.c	Mon Nov  4 14:31:01 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1209 +0,0 @@
-/*
-** ccio-dma.c:
-**	DMA management routines for first generation cache-coherent machines.
-**	Program U2/Uturn in "Virtual Mode" and use the I/O MMU.
-**
-**	(c) Copyright 2000 Grant Grundler
-**	(c) Copyright 2000 Ryan Bradetich
-**	(c) Copyright 2000 Hewlett-Packard Company
-**
-** 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.
-**
-**
-**  "Real Mode" operation refers to U2/Uturn chip operation.
-**  U2/Uturn were designed to perform coherency checks w/o using
-**  the I/O MMU - basically what x86 does.
-**
-**  Philipp Rumpf has a "Real Mode" driver for PCX-W machines at:
-**      CVSROOT=:pserver:anonymous@198.186.203.37:/cvsroot/linux-parisc
-**      cvs -z3 co linux/arch/parisc/kernel/dma-rm.c
-**
-**  I've rewritten his code to work under TPG's tree. See ccio-rm-dma.c.
-**
-**  Drawbacks of using Real Mode are:
-**	o outbound DMA is slower - U2 won't prefetch data (GSC+ XQL signal).
-**      o Inbound DMA less efficient - U2 can't use DMA_FAST attribute.
-**	o Ability to do scatter/gather in HW is lost.
-**	o Doesn't work under PCX-U/U+ machines since they didn't follow
-**        the coherency design originally worked out. Only PCX-W does.
-*/
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/pci.h>
-
-#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/io.h>
-#include <asm/gsc.h>		/* for gsc_writeN()... */
-
-/* 
-** Choose "ccio" since that's what HP-UX calls it.
-** Make it easier for folks to migrate from one to the other :^)
-*/
-#define MODULE_NAME "ccio"
-
-/*
-#define DEBUG_CCIO_RES
-#define DEBUG_CCIO_RUN
-#define DEBUG_CCIO_INIT
-#define DUMP_RESMAP
-*/
-
-#include <linux/proc_fs.h>
-#include <asm/runway.h>		/* for proc_runway_root */
-
-#ifdef DEBUG_CCIO_INIT
-#define DBG_INIT(x...)  printk(x)
-#else
-#define DBG_INIT(x...)
-#endif
-
-#ifdef DEBUG_CCIO_RUN
-#define DBG_RUN(x...)   printk(x)
-#else
-#define DBG_RUN(x...)
-#endif
-
-#ifdef DEBUG_CCIO_RES
-#define DBG_RES(x...)   printk(x)
-#else
-#define DBG_RES(x...)
-#endif
-
-#define CCIO_INLINE	/* inline */
-#define WRITE_U32(value, addr) gsc_writel(value, (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     */
-#define CMD_TLB_PURGE        33         /* IO_COMMAND to Purge I/O TLB entry */
-
-struct ioa_registers {
-        /* Runway Supervisory Set */
-        volatile int32_t    unused1[12];
-        volatile uint32_t   io_command;             /* Offset 12 */
-        volatile uint32_t   io_status;              /* Offset 13 */
-        volatile uint32_t   io_control;             /* Offset 14 */
-        volatile int32_t    unused2[1];
-
-        /* Runway Auxiliary Register Set */
-        volatile uint32_t   io_err_resp;            /* Offset  0 */
-        volatile uint32_t   io_err_info;            /* Offset  1 */
-        volatile uint32_t   io_err_req;             /* Offset  2 */
-        volatile uint32_t   io_err_resp_hi;         /* Offset  3 */
-        volatile uint32_t   io_tlb_entry_m;         /* Offset  4 */
-        volatile uint32_t   io_tlb_entry_l;         /* Offset  5 */
-        volatile uint32_t   unused3[1];
-        volatile uint32_t   io_pdir_base;           /* Offset  7 */
-        volatile uint32_t   io_io_low_hv;           /* Offset  8 */
-        volatile uint32_t   io_io_high_hv;          /* Offset  9 */
-        volatile uint32_t   unused4[1];
-        volatile uint32_t   io_chain_id_mask;       /* Offset 11 */
-        volatile uint32_t   unused5[2];
-        volatile uint32_t   io_io_low;              /* Offset 14 */
-        volatile uint32_t   io_io_high;             /* Offset 15 */
-};
-
-
-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];
-#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 */
-};
-
-
-/* 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;
-
-/**************************************************************
-*
-*   I/O Pdir Resource Management
-*
-*   Bits set in the resource map are in use.
-*   Each bit can represent a number of pages.
-*   LSbs represent lower addresses (IOVA's).
-*
-*   This was was copied from sba_iommu.c. Don't try to unify
-*   the two resource managers unless a way to have different
-*   allocation policies is also adjusted. We'd like to avoid
-*   I/O TLB thrashing by having resource allocation policy
-*   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 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 */
-
-/*
-** 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;\
-                       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); \
-}
-
-/*
-** Find available bit in this ioa's resource map.
-** Use a "circular" search:
-**   o Most IOVA's are "temporary" - avg search time should be small.
-** o keep a history of what happened for debugging
-** o KISS.
-**
-** Perf optimizations:
-** o search for log2(size) bits at a time.
-** o search for available resource bits using byte/word/whatever.
-** o use different search for "large" (eg > 4 pages) or "very large"
-**   (eg > 16 pages) mappings.
-*/
-static int
-ccio_alloc_range(struct ccio_device *ioa, size_t size)
-{
-	int res_idx;
-	unsigned long mask, flags;
-	unsigned int pages_needed = size >> PAGE_SHIFT;
-
-	ASSERT(pages_needed);
-	ASSERT((pages_needed * IOVP_SIZE) < DMA_CHUNK_SIZE);
-	ASSERT(pages_needed < (BITS_PER_LONG - IOVP_SHIFT));
-
-	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);
-
-	/*
-	** "seek and ye shall find"...praying never hurts either...
-	** ggg sacrafices another 710 to the computer gods.
-	*/
-
-	if(pages_needed <= 8) {
-		CCIO_FIND_FREE_MAPPING(ioa, res_idx, mask, 8);
-	} else if(pages_needed <= 16) {
-		CCIO_FIND_FREE_MAPPING(ioa, res_idx, mask, 16);
-	} else if(pages_needed <= 32) {
-		CCIO_FIND_FREE_MAPPING(ioa, res_idx, mask, 32);
-#ifdef __LP64__
-	} else if(pages_needed <= 64) {
-		CCIO_FIND_FREE_MAPPING(ioa, res_idx, mask, 64)
-#endif
-	} else {
-		panic(__FILE__ ":" __FUNCTION__ "() Too many pages to map.\n");
-	}
-
-#ifdef DUMP_RESMAP
-	dump_resmap();
-#endif
-	panic(__FILE__ ":" __FUNCTION__ "() I/O MMU is out of mapping resources\n");
-	
-resource_found:
-	
-	DBG_RES(__FUNCTION__ " res_idx %d mask 0x%08lx res_hint: %d\n",
-		res_idx, mask, ioa->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 DUMP_RESMAP
-	dump_resmap();
-#endif
-
-	/* 
-	** return the bit address (convert from byte to bit).
-	*/
-	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
-*/
-static void
-ccio_free_range(struct ccio_device *ioa, dma_addr_t iova, size_t size)
-{
-	unsigned long mask, flags;
-	unsigned long iovp = CCIO_IOVP(iova);
-	unsigned int res_idx = PDIR_INDEX(iovp)>>3;
-	unsigned int pages_mapped = (size >> IOVP_SHIFT) + !!(size & ~IOVP_MASK);
-
-	ASSERT(pages_needed);
-	ASSERT((pages_needed * IOVP_SIZE) < DMA_CHUNK_SIZE);
-	ASSERT(pages_needed < (BITS_PER_LONG - IOVP_SHIFT));
-
-	mask = (unsigned long) -1L;
- 	mask >>= BITS_PER_LONG - pages_mapped;
-
-	DBG_RES(__FUNCTION__ " res_idx: %d size: %d pages_mapped %d mask 0x%08lx\n", 
-		res_idx, size, pages_mapped, mask);
-
-	spin_lock_irqsave(&ioa->ccio_lock, flags);
-
-	if(pages_mapped <= 8) {
-		CCIO_FREE_MAPPINGS(ioa, res_idx, mask, 8);
-	} else if(pages_mapped <= 16) {
-		CCIO_FREE_MAPPINGS(ioa, res_idx, mask, 16);
-	} else if(pages_mapped <= 32) {
-		CCIO_FREE_MAPPINGS(ioa, res_idx, mask, 32);
-#ifdef __LP64__
-	} else if(pages_mapped <= 64) {
-		CCIO_FREE_MAPPINGS(ioa, res_idx, mask, 64);
-#endif
-	} else {
-		panic(__FILE__ ":" __FUNCTION__ "() Too many pages to unmap.\n");
-	}
-	
-	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
-**
-*****************************************************************/
-
-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
-**   set for subcacheline DMA transfers since we don't want to damage the
-**   other part of a cacheline.
-** o SAFE_DMA must be set for "memory" allocated via pci_alloc_consistent().
-**   This bit tells U2 to do R/M/W for partial cachelines. "Streaming"
-**   data can avoid this if the mapping covers full cache lines.
-** o STOP_MOST is needed for atomicity across cachelines.
-**   Apperently only "some EISA devices" need this.
-**   Using CONFIG_ISA is hack. Only the IOA with EISA under it needs
-**   to use this hint iff the EISA devices needs this feature.
-**   According to the U2 ERS, STOP_MOST enabled pages hurt performance.
-** o PREFETCH should *not* be set for cases like Multiple PCI devices
-**   behind GSCtoPCI (dino) bus converter. Only one cacheline per GSC
-**   device can be fetched and multiply DMA streams will thrash the
-**   prefetch buffer and burn memory bandwidth. See 6.7.3 "Prefetch Rules
-**   and Invalidation of Prefetch Entries".
-**
-** FIXME: the default hints need to be per GSC device - not global.
-** 
-** HP-UX dorks: linux device driver programming model is totally different
-**    than HP-UX's. HP-UX always sets HINT_PREFETCH since it's drivers
-**    do special things to work on non-coherent platforms...linux has to
-**    be much more careful with this.
-*/
-#define IOPDIR_VALID    0x01UL
-#define HINT_SAFE_DMA   0x02UL	/* used for pci_alloc_consistent() pages */
-#ifdef CONFIG_ISA	/* EISA support really */
-#define HINT_STOP_MOST  0x04UL	/* LSL support */
-#else
-#define HINT_STOP_MOST  0x00UL	/* only needed for "some EISA devices" */
-#endif
-#define HINT_UDPATE_ENB 0x08UL  /* not used/supported by U2 */
-#define HINT_PREFETCH   0x10UL	/* for outbound pages which are not SAFE */
-
-
-/*
-** Use direction (ie PCI_DMA_TODEVICE) to pick hint.
-** ccio_alloc_consistent() depends on this to get SAFE_DMA
-** when it passes in BIDIRECTIONAL flag.
-*/
-static u32 hint_lookup[] = {
-	[PCI_DMA_BIDIRECTIONAL]  HINT_STOP_MOST | HINT_SAFE_DMA | IOPDIR_VALID,
-	[PCI_DMA_TODEVICE]       HINT_STOP_MOST | HINT_PREFETCH | IOPDIR_VALID,
-	[PCI_DMA_FROMDEVICE]     HINT_STOP_MOST | IOPDIR_VALID,
-	[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.
-*/
-
-void CCIO_INLINE
-ccio_io_pdir_entry(u64 *pdir_ptr, space_t sid, void * vba, unsigned long hints)
-{
-	register unsigned long pa = (volatile unsigned long) vba;
-	register unsigned long ci; /* coherent index */
-
-	/* We currently only support kernel addresses */
-	ASSERT(sid == 0);
-	ASSERT(((unsigned long) vba & 0xf0000000UL) == 0xc0000000UL);
-
-	mtsp(sid,1);
-
-	/*
-	** WORD 1 - low order word
-	** "hints" parm includes the VALID bit!
-	** "dep" clobbers the physical address offset bits as well.
-	*/
-	pa = virt_to_phys(vba);
-	asm volatile("depw  %1,31,12,%0" : "+r" (pa) : "r" (hints));
-	((u32 *)pdir_ptr)[1] = (u32) pa;
-
-	/*
-	** WORD 0 - high order word
-	*/
-
-#ifdef __LP64__
-	/*
-	** get bits 12:15 of physical address
-	** shift bits 16:31 of physical address
-	** 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 ("depd  %1,35,4,%0" : "+r" (pa) : "r" (ci));
-#else
-	pa = 0;
-#endif
-	/*
-	** get CPU coherency index bits
-	** Grab virtual index [0:11]
-	** Deposit virt_idx bits into I/O PDIR word
-	*/
-	asm volatile ("lci 0(%%sr1, %1), %0" : "=r" (ci) : "r" (vba));
-	asm volatile ("extru %1,19,12,%0" : "+r" (ci) : "r" (ci));
-	asm volatile ("depw  %1,15,12,%0" : "+r" (pa) : "r" (ci));
-
-	((u32 *)pdir_ptr)[0] = (u32) pa;
-
-
-	/* FIXME: PCX_W platforms don't need FDC/SYNC. (eg C360)
-	**        PCX-U/U+ do. (eg C200/C240)
-	**        PCX-T'? Don't know. (eg C110 or similar K-class)
-	**
-	** See PDC_MODEL/option 0/SW_CAP word for "Non-coherent IO-PDIR bit".
-	** Hopefully we can patch (NOP) these out at boot time somehow.
-	**
-	** "Since PCX-U employs an offset hash that is incompatible with
-	** the real mode coherence index generation of U2, the PDIR entry
-	** must be flushed to memory to retain coherence."
-	*/
-	asm volatile("fdc 0(%0)" : : "r" (pdir_ptr));
-	asm volatile("sync");
-}
-
-
-/*
-** Remove stale entries from the I/O TLB.
-** Need to do this whenever an entry in the PDIR is marked invalid.
-*/
-static CCIO_INLINE void
-ccio_clear_io_tlb( struct ccio_device *d, dma_addr_t iovp, size_t byte_cnt)
-{
-	u32 chain_size = 1 << d->chainid_shift;
-
-	iovp &= ~(IOVP_SIZE-1);	/* 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;
-		byte_cnt -= chain_size;
-        }
-}
-
-
-/***********************************************************
- *
- * 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.
- *
- * 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).
- ***********************************************************/
-static CCIO_INLINE void
-ccio_mark_invalid(struct ccio_device *d, dma_addr_t iova, size_t byte_cnt)
-{
-	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;
-
-	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 */
-
-		/*
-		** FIXME: PCX_W platforms don't need FDC/SYNC. (eg C360)
-		**   PCX-U/U+ do. (eg C200/C240)
-		** See PDC_MODEL/option 0/SW_CAP for "Non-coherent IO-PDIR bit".
-		**
-		** Hopefully someone figures out how to patch (NOP) the
-		** FDC/SYNC out at boot time.
-		*/
-		asm volatile("fdc 0(%0)" : : "r" (pdir_ptr[7]));
-
-		iovp     += IOVP_SIZE;
-		byte_cnt -= IOVP_SIZE;
-	}
-
-	asm volatile("sync");
-	ccio_clear_io_tlb(d, 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)
-{
-	if (dev == NULL) {
-		printk(MODULE_NAME ": EISA/ISA/et al not supported\n");
-		BUG();
-		return(0);
-	}
-
-	dev->dma_mask = mask;   /* save it */
-
-	/* only support 32-bit devices (ie PCI/GSC) */
-	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)
-{
-	struct ccio_device *ioa = ccio_list;  /* FIXME : see Multi-IOC below */
-	dma_addr_t iovp;
-	dma_addr_t offset;
-	u64 *pdir_start;
-	unsigned long hint = hint_lookup[direction];
-	int idx;
-
-	ASSERT(size > 0);
-
-	/* save offset bits */
-	offset = ((dma_addr_t) addr) & ~IOVP_MASK;
-
-	/* round up to nearest IOVP_SIZE */
-	size = (size + offset + IOVP_SIZE - 1) & IOVP_MASK;
-
-	idx = ccio_alloc_range(ioa, size);
-	iovp = (dma_addr_t) MKIOVP(idx);
-
-	DBG_RUN(__FUNCTION__ " 0x%p -> 0x%lx", addr, (long) iovp | offset);
-
-	pdir_start = &(ioa->pdir_base[idx]);
-
-	/* If not cacheline aligned, force SAFE_DMA on the whole mess */
-	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) {
-
-		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])
-			);
-		addr += IOVP_SIZE;
-		size -= IOVP_SIZE;
-		pdir_start++;
-	}
-	/* 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;
-	
-	offset = iova & ~IOVP_MASK;
-
-	/* round up to nearest IOVP_SIZE */
-	size = (size + offset + IOVP_SIZE - 1) & IOVP_MASK;
-
-	/* Mask off offset */
-	iova &= IOVP_MASK;
-
-	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 {
-#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
-}
-
-
-static void * ccio_alloc_consistent (struct pci_dev *hwdev, 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);
-
-#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) {
-		/* 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);
-	}
-	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)
-{
-	unsigned long flags;
-	struct ccio_device *ioa = ccio_list;
-
-	spin_lock_irqsave(&ioa->ccio_lock, flags);
-	ccio_free_size += get_order(size);
-	spin_unlock_irqrestore(&ioa->ccio_lock, flags);
-
-	ccio_unmap_single(hwdev, dma_handle, size, 0);
-	free_pages((unsigned long) vaddr, get_order(size));
-}
-
-
-static int ccio_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
-{
-	int tmp = nents;
-
-	DBG_RUN(KERN_WARNING __FUNCTION__ " START\n");
-
-        /* 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++;
-	}
-
-	DBG_RUN(KERN_WARNING __FUNCTION__ " DONE\n");
-	return tmp;
-}
-
-
-static void ccio_unmap_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++;
-	}
-	return;
-}
-
-
-static struct pci_dma_ops ccio_ops = {
-	ccio_dma_supported,
-	ccio_alloc_consistent,
-	ccio_free_consistent,
-	ccio_map_single,
-	ccio_unmap_single,
-	ccio_map_sg,
-	ccio_unmap_sg,
-	NULL,                   /* dma_sync_single : NOP for U2/Uturn */
-	NULL,                   /* dma_sync_sg     : ditto */
-};
-
-#if 0
-/* GRANT -  is this needed for U2 or not? */
-
-/*
-** Get the size of the I/O TLB for this I/O MMU.
-**
-** If spa_shift is non-zero (ie probably U2),
-** then calculate the I/O TLB size using spa_shift.
-**
-** Otherwise we are supposed to get the IODC entry point ENTRY TLB
-** and execute it. However, both U2 and Uturn firmware supplies spa_shift.
-** I think only Java (K/D/R-class too?) systems don't do this.
-*/
-static int
-ccio_get_iotlb_size(struct hp_device *d)
-{
-	if(d->spa_shift == 0) {
-		panic(__FUNCTION__ ": Can't determine I/O TLB size.\n");
-	}
-	return(1 << d->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.
-*/
-static void
-ccio_alloc_pdir(struct ccio_device *ioa)
-{
-	extern unsigned long mem_max;          /* arch.../setup.c */
-
-	u32 iova_space_size = 0;
-	void * pdir_base;
-	int pdir_size, iov_order;
-
-	/*
-	** 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
-	** own.  Next best thing would be to guess how much DMA
-	** can be outstanding based on PCI Class/sub-class. Both
-	** 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;
-#ifdef __LP64__
-	} else if (mem_max > (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 must be log2() in size.
-	** thus, pdir/res_map will also be log2().
-	*/
-
-	/* 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);
-	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);
-
-	ASSERT(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));
-
-	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");
-	}
-	memset(pdir_base, 0, pdir_size);
-
-	ASSERT((((unsigned long) pdir_base) & PAGE_MASK) == (unsigned long) pdir_base);
-
-	DBG_INIT(" base %p", pdir_base);
-
-	/*
-	** 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;
-
-	/*
-	** 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);
-
-
-	/*
-	** Go to "Virtual Mode"
-	*/
-	WRITE_U32(IOA_NORMAL_MODE, &ioa->ccio_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);
-
-	for (i = 1 << CCIO_CHAINID_SHIFT; i ; i--) {
-		WRITE_U32((CMD_TLB_DIRECT_WRITE | (i << ioa->chainid_shift)),
-					&ioa->ccio_hpa->io_command);
-	}
-
-}
-
-
-static void
-ccio_resmap_init(struct ccio_device *ioa)
-{
-	u32 res_size;
-
-	/*
-	** Ok...we do more than just init resource map
-	*/
-	ioa->ccio_lock = SPIN_LOCK_UNLOCKED;
-
-	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");
-	}
-	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};
-
-/*
-** 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)
-{
-	unsigned long status;
-	unsigned int idx;
-	u8 *res_ptr = ioa->res_map;
-	u32 iovp=0x0;
-	unsigned long mask;
-
-	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;
-	} 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;
-		}
-	}
-
-	printk(MODULE_NAME ": Cujo 2.0 bug needs a work around\n");
-	ccio_cujo_bug = 1;
-
-	/*
-	** 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;
-	}
-}
-/* CUJO20 KLUDGE end */
-
-#ifdef CONFIG_PROC_FS
-static int ccio_proc_info(char *buf, char **start, off_t offset, int len)
-{
-	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 */
-	
-	sprintf(buf, "%sResource bitmap : %d bytes (%d pages)\n", 
-		buf, ioa->res_size, ioa->res_size << 3);   /* 8 bits per byte */
-
-	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));
-
-	sprintf(buf, "%sconsistent       %8ld %8ld\n", buf,
-		ccio_alloc_size, ccio_free_size);
- 
-	strcat(buf, "\nResource bitmap:\n");
-
-	for(; i < (ioa->res_size / sizeof(unsigned long)); ++i, ++res_ptr)
-		len += sprintf(buf, "%s%08lx ", buf, *res_ptr);
-
-	strcat(buf, "\n");
-	return strlen(buf);
-}
-#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 ccio_device *ioa;
-
-	printk("%s found %s at 0x%p\n", dri->name, dri->version, d->hpa);
-
-	if (ccio_list) {
-		printk(MODULE_NAME ": already initialized one device\n");
-		return(0);
-	}
-
-	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));
-
-	/*
-	** 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;
-
-#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
-
-	ccio_alloc_pdir(ioa);
-	ccio_hw_init(ioa);
-	ccio_resmap_init(ioa);
-
-	/* CUJO20 KLUDGE start */
-	ccio_cujo20_hack(ioa);
-	/* CUJO20 KLUDGE end */
-
-	hppa_dma_ops = &ccio_ops;
-
-	create_proc_info_entry(MODULE_NAME, 0, proc_runway_root, ccio_proc_info);
-	return(0);
-}
-
-
-
diff -Nru a/arch/parisc/kernel/ccio-rm-dma.c b/arch/parisc/kernel/ccio-rm-dma.c
--- a/arch/parisc/kernel/ccio-rm-dma.c	Mon Nov  4 14:31:01 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,212 +0,0 @@
-/*
- * ccio-rm-dma.c:
- *	DMA management routines for first generation cache-coherent machines.
- *	"Real Mode" operation refers to U2/Uturn chip operation. The chip
- *      can perform coherency checks w/o using the I/O MMU. That's all we
- *      need until support for more than 4GB phys mem is needed.
- * 
- *	This is the trivial case - basically what x86 does.
- *
- *	Drawbacks of using Real Mode are:
- *	o outbound DMA is slower since one isn't using the prefetching
- *	  U2 can do for outbound DMA.
- *	o Ability to do scatter/gather in HW is also lost.
- *      o only known to work with PCX-W processor. (eg C360)
- *        (PCX-U/U+ are not coherent with U2 in real mode.)
- *
- *
- * 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.
- *
- *
- * Original version/author:
- *      CVSROOT=:pserver:anonymous@198.186.203.37:/cvsroot/linux-parisc
- *      cvs -z3 co linux/arch/parisc/kernel/dma-rm.c
- *
- *	(C) Copyright 2000 Philipp Rumpf <prumpf@tux.org>
- *
- *
- * Adopted for The Puffin Group's parisc-linux port by Grant Grundler.
- *	(C) Copyright 2000 Grant Grundler <grundler@puffin.external.hp.com>
- *	
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/pci.h>
-
-#include <asm/uaccess.h>
-#include <asm/pgalloc.h>
-
-#include <asm/io.h>
-#include <asm/hardware.h>
-#include <asm/page.h>
-
-/* Only chose "ccio" since that's what HP-UX calls it....
-** Make it easier for folks to migrate from one to the other :^)
-*/
-#define MODULE_NAME "ccio"
-
-#define U2_IOA_RUNWAY 0x580
-#define U2_BC_GSC     0x501
-#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))  \
-)
-
-#define IS_UTURN(id) ( \
-    (((id)->hw_type == HPHW_IOA) && ((id)->hversion == UTURN_IOA_RUNWAY)) || \
-    (((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");
-		BUG();
-		return(0);
-	}
-
-	dev->dma_mask = mask;   /* save it */
-
-	/* only support 32-bit devices (ie PCI/GSC) */
-	return((int) (mask >= 0xffffffffUL));
-}
-
-
-static void *ccio_alloc_consistent(struct pci_dev *dev, size_t size,
-				 dma_addr_t *handle)
-{
-	void *ret;
-	
-	ret = (void *)__get_free_pages(GFP_ATOMIC, get_order(size));
-
-	if (ret != NULL) {
-		memset(ret, 0, size);
-		*handle = virt_to_phys(ret);
-	}
-	return ret;
-}
-	
-static void ccio_free_consistent(struct pci_dev *dev, size_t size,
-			       void *vaddr, dma_addr_t handle)
-{
-	free_pages((unsigned long)vaddr, get_order(size));
-}
-
-static dma_addr_t ccio_map_single(struct pci_dev *dev, void *ptr, size_t size,
-			  int direction)
-{
-	return virt_to_phys(ptr);
-}
-
-static void ccio_unmap_single(struct pci_dev *dev, dma_addr_t dma_addr,
-			    size_t size, int direction)
-{
-	/* Nothing to do */
-}
-
-
-static int ccio_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
-{
-	int tmp = nents;
-
-        /* 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++;
-	}
-
-	return tmp;
-}
-
-
-static void ccio_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
-{
-#if 0
-	while (nents) {
-		ccio_unmap_single(dev, sg_dma_address(sglist), sg_dma_len(sglist), direction);
-		nents--;
-		sglist++;
-	}
-	return;
-#else
-	/* Do nothing (copied from current ccio_unmap_single()  :^) */
-#endif
-}
-
-
-static struct pci_dma_ops ccio_ops = {
-	ccio_dma_supported,
-	ccio_alloc_consistent,
-	ccio_free_consistent,
-	ccio_map_single,
-	ccio_unmap_single,
-	ccio_map_sg,
-	ccio_unmap_sg,
-	NULL,                   /* dma_sync_single : NOP for U2 */
-	NULL,                   /* dma_sync_sg     : ditto */
-
-
-};
-
-
-/*
-** Determine if u2 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)
-{
-	printk("%s found %s at 0x%p\n", dri->name, dri->version, d->hpa);
-
-/*
-** FIXME - should check U2 registers to verify it's really running
-** in "Real Mode".
-*/
-
-#if 0
-/* will need this for "Virtual Mode" operation */
-	ccio_hw_init(ccio_dev);
-	ccio_common_init(ccio_dev);
-#endif
-	hppa_dma_ops = &ccio_ops;
-	return 0;
-}
diff -Nru a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
--- a/arch/parisc/kernel/drivers.c	Mon Nov  4 14:31:02 2002
+++ b/arch/parisc/kernel/drivers.c	Mon Nov  4 14:31:02 2002
@@ -23,7 +23,6 @@
 #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;
diff -Nru a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
--- a/arch/parisc/kernel/entry.S	Mon Nov  4 14:31:01 2002
+++ b/arch/parisc/kernel/entry.S	Mon Nov  4 14:31:01 2002
@@ -502,7 +502,6 @@
 	.import		handle_real_interruption,code
 	.import		do_cpu_irq_mask,code
 	.import		parisc_stopkernel,code
-	.import		cpu_irq_region,data
 
 	/*
 	 * r26 = function to be called
@@ -515,6 +514,7 @@
 	 */
 
 #define CLONE_VM 0x100	/* Must agree with <linux/sched.h> */
+#define CLONE_UNTRACED 0x00800000
 
 	.export __kernel_thread, code
 	.import do_fork
@@ -528,23 +528,29 @@
 	ldd	24(%r26), %r2
 	STREG	%r2, PT_GR27(%r1)	/* Store childs %dp */
 	ldd	16(%r26), %r26
+
+	STREG	%r22, PT_GR22(%r1)	/* Store childs %dp */
+	copy	%r0, %r22		/* user_tid */
 #endif
 	STREG	%r26, PT_GR26(%r1)  /* Store function & argument for child */
 	STREG	%r25, PT_GR25(%r1)
-	ldo	CLONE_VM(%r0), %r26   /* Force CLONE_VM since only init_mm */
+	ldil	L%CLONE_UNTRACED, %r26
+	ldo	CLONE_VM(%r26), %r26   /* Force CLONE_VM since only init_mm */
 	or	%r26, %r24, %r26      /* will have kernel mappings.	 */
-	copy	%r0, %r25
+	copy	%r0, %r25		/* stack_start */
+	stw	%r0, -52(%r30)	     	/* user_tid */
 #ifdef __LP64__
 	ldo	-16(%r30),%r29		/* Reference param save area */
 #endif
 	bl	do_fork, %r2
-	copy	%r1, %r24
+	copy	%r1, %r24		/* pt_regs */
 
 	/* Parent Returns here */
 
 	LDREG	-PT_SZ_ALGN-RP_OFFSET(%r30), %r2
-	bv	%r0(%r2)
 	ldo	-PT_SZ_ALGN(%r30), %r30
+	bv	%r0(%r2)
+	ldw	TASK_PID(%r28), %r28
 
 	/*
 	 * Child Returns here
@@ -566,6 +572,7 @@
 	LDREG	TASK_PT_GR25(%r1), %r26
 #ifdef __LP64__
 	LDREG	TASK_PT_GR27(%r1), %r27
+	LDREG	TASK_PT_GR22(%r1), %r22
 #endif
 	LDREG	TASK_PT_GR26(%r1), %r1
 	ble	0(%sr7, %r1)
@@ -785,10 +792,10 @@
 	.import schedule,code
 intr_do_resched:
 	/* Only do reschedule if we are returning to user space */
-	LDREG   PT_IASQ0(%r16), %r20
+	LDREG	PT_IASQ0(%r16), %r20
 	CMPIB= 0,%r20,intr_restore /* backward */
 	nop
-	LDREG   PT_IASQ1(%r16), %r20
+	LDREG	PT_IASQ1(%r16), %r20
 	CMPIB= 0,%r20,intr_restore /* backward */
 	nop
 
@@ -796,28 +803,29 @@
 	ldo	-16(%r30),%r29		/* Reference param save area */
 #endif
 
-	ldil	L%intr_return, %r2
+	ldil	L%intr_check_sig, %r2
 	b	schedule
-	ldo	R%intr_return(%r2), %r2	/* return to intr_return, not here */
+	ldo	R%intr_check_sig(%r2), %r2
 
 
 	.import do_signal,code
 intr_do_signal:
 	/* Only do signals if we are returning to user space */
-	LDREG   PT_IASQ0(%r16), %r20
+	LDREG	PT_IASQ0(%r16), %r20
 	CMPIB= 0,%r20,intr_restore /* backward */
 	nop
-	LDREG   PT_IASQ1(%r16), %r20
+	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
-#warning TAUSQ FIXME, this is wrong
+
+#warning TAUSQ FIXME - review 2.5 signal return path changes
+
 	bl	do_signal,%r2
 	copy	%r0, %r26			/* sigset_t *oldset = NULL */
 
@@ -860,26 +868,19 @@
 	
 	loadgp
 
-	copy	%r29, %r25	/* arg1 is pt_regs */
+	copy	%r29, %r26	/* arg0 is pt_regs */
 	copy	%r29, %r16	/* save pt_regs */
 
+	ldil	L%intr_return, %r2
+
 #ifdef __LP64__
 	ldo	-16(%r30),%r29	/* Reference param save area */
-#else
-	nop
 #endif
-	
-	/*
-	 * 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 */
@@ -953,11 +954,11 @@
 	ldo		-16(%r30),%r29	/* Reference param save area */
 #endif
 
-	ldil		L%intr_return, %r2
+	ldil		L%intr_restore, %r2
 	copy		%r25, %r16	/* save pt_regs */
 
 	b		handle_interruption
-	ldo		R%intr_return(%r2), %r2	/* return to intr_return */
+	ldo		R%intr_restore(%r2), %r2
 
 
 	/*
diff -Nru a/arch/parisc/kernel/hardware.c b/arch/parisc/kernel/hardware.c
--- a/arch/parisc/kernel/hardware.c	Mon Nov  4 14:31:01 2002
+++ b/arch/parisc/kernel/hardware.c	Mon Nov  4 14:31:01 2002
@@ -403,7 +403,7 @@
 	{HPHW_BA, 0x01B, 0x00078, 0x0, "Anole 100 VME BA"}, 
 	{HPHW_BA, 0x024, 0x00078, 0x0, "Fast Pace VME BA"}, 
 	{HPHW_BA, 0x034, 0x00078, 0x0, "Anole T VME BA"}, 
-	{HPHW_BA, 0x04A, 0x00078, 0x0, "Anole L2 132 BME BA"}, 
+	{HPHW_BA, 0x04A, 0x00078, 0x0, "Anole L2 132 VME BA"}, 
 	{HPHW_BA, 0x04C, 0x00078, 0x0, "Anole L2 165 VME BA"}, 
 	{HPHW_BA, 0x011, 0x00081, 0x0, "WB-96 Core BA"}, 
 	{HPHW_BA, 0x012, 0x00081, 0x0, "Orville UX Core BA"}, 
@@ -805,8 +805,8 @@
 	{HPHW_FIO, 0x04E, 0x0007B, 0x0, "Kiji L2 132 Core Audio"}, 
 	{HPHW_FIO, 0x050, 0x0007B, 0x0, "Merlin Jr 132 Core Audio"}, 
 	{HPHW_FIO, 0x051, 0x0007B, 0x0, "Firehawk Audio"}, 
-	{HPHW_FIO, 0x056, 0x0007B, 0x0, "Raven+ w SE FWSCSU Core Audio"}, 
-	{HPHW_FIO, 0x057, 0x0007B, 0x0, "Raven+ w Diff FWSCSU Core Audio"}, 
+	{HPHW_FIO, 0x056, 0x0007B, 0x0, "Raven+ w SE FWSCSI Core Audio"}, 
+	{HPHW_FIO, 0x057, 0x0007B, 0x0, "Raven+ w Diff FWSCSI Core Audio"}, 
 	{HPHW_FIO, 0x058, 0x0007B, 0x0, "FireHawk 200 Audio"}, 
 	{HPHW_FIO, 0x05C, 0x0007B, 0x0, "SummitHawk 230 Core Audio"}, 
 	{HPHW_FIO, 0x800, 0x0007B, 0x0, "Hitachi Tiny 64 Audio"}, 
diff -Nru a/arch/parisc/kernel/iosapic.c b/arch/parisc/kernel/iosapic.c
--- a/arch/parisc/kernel/iosapic.c	Mon Nov  4 14:31:01 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1100 +0,0 @@
-/*
-** I/O Sapic Driver - PCI interrupt line support
-**
-**      (c) Copyright 1999 Grant Grundler
-**      (c) Copyright 1999 Hewlett-Packard Company
-**
-**      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.
-**
-** The I/O sapic driver manages the Interrupt Redirection Table which is
-** the control logic to convert PCI line based interrupts into a Message
-** Signaled Interrupt (aka Transaction Based Interrupt, TBI).
-**
-** Acronyms
-** --------
-** HPA  Hard Physical Address (aka MMIO address)
-** IRQ  Interrupt ReQuest. Implies Line based interrupt.
-** IRT	Interrupt Routing Table (provided by PAT firmware)
-** IRdT Interrupt Redirection Table. IRQ line to TXN ADDR/DATA
-**      table which is implemented in I/O SAPIC.
-** ISR  Interrupt Service Routine. aka Interrupt handler.
-** MSI	Message Signaled Interrupt. PCI 2.2 functionality.
-**      aka Transaction Based Interrupt (or TBI).
-** PA   Precision Architecture. HP's RISC architecture.
-** RISC Reduced Instruction Set Computer.
-**
-**
-** What's a Message Signalled Interrupt?
-** -------------------------------------
-** MSI is a write transaction which targets a processor and is similar
-** to a processor write to memory or MMIO. MSIs can be generated by I/O
-** devices as well as processors and require *architecture* to work.
-**
-** PA only supports MSI. So I/O subsystems must either natively generate
-** MSIs (e.g. GSC or HP-PB) or convert line based interrupts into MSIs
-** (e.g. PCI and EISA).  IA64 supports MSIs via a "local SAPIC" which
-** acts on behalf of a processor.
-**
-** MSI allows any I/O device to interrupt any processor. This makes
-** load balancing of the interrupt processing possible on an SMP platform.
-** Interrupts are also ordered WRT to DMA data.  It's possible on I/O
-** coherent systems to completely eliminate PIO reads from the interrupt
-** path. The device and driver must be designed and implemented to
-** guarantee all DMA has been issued (issues about atomicity here)
-** before the MSI is issued. I/O status can then safely be read from
-** DMA'd data by the ISR.
-**
-**
-** PA Firmware
-** -----------
-** PA-RISC platforms have two fundementally different types of firmware.
-** For PCI devices, "Legacy" PDC initializes the "INTERRUPT_LINE" register
-** and BARs similar to a traditional PC BIOS.
-** The newer "PAT" firmware supports PDC calls which return tables.
-** PAT firmware only initializes PCI Console and Boot interface.
-** With these tables, the OS can progam all other PCI devices.
-**
-** One such PAT PDC call returns the "Interrupt Routing Table" (IRT).
-** The IRT maps each PCI slot's INTA-D "output" line to an I/O SAPIC
-** input line.  If the IRT is not available, this driver assumes
-** INTERRUPT_LINE register has been programmed by firmware. The latter
-** case also means online addition of PCI cards can NOT be supported
-** even if HW support is present.
-**
-** All platforms with PAT firmware to date (Oct 1999) use one Interrupt
-** Routing Table for the entire platform.
-**
-** Where's the iosapic?
-** --------------------
-** I/O sapic is part of the "Core Electronics Complex". And on HP platforms
-** it's integrated as part of the PCI bus adapter, "lba".  So no bus walk
-** will discover I/O Sapic. I/O Sapic driver learns about each device
-** when lba driver advertises the presence of the I/O sapic by calling
-** iosapic_register().
-**
-**
-** IRQ region notes
-** ----------------
-** The data passed to iosapic_interrupt() is per IRQ line.
-** Each IRQ line will get one txn_addr/data pair. Thus each IRQ region,
-** will have several txn_addr/data pairs (up to 7 for current I/O SAPIC
-** implementations).  The IRQ region "sysdata" will NOT be directly passed
-** to the interrupt handler like GSCtoPCI (dino.c).
-**
-** iosapic interrupt handler will NOT call do_irq_mask().
-** It doesn't need to read a bit mask to determine which IRQ line was pulled
-** since it already knows based on vector_info passed to iosapic_interrupt().
-**
-** One IRQ number represents both an IRQ line and a driver ISR.
-** The I/O sapic driver can't manage shared IRQ lines because
-** additional data besides the IRQ number must be passed via
-** irq_region_ops. do_irq() and request_irq() must manage
-** a sharing a bit in the mask.
-**
-** iosapic_interrupt() replaces do_irq_mask() and calls do_irq().
-** Which IRQ line was asserted is already known since each
-** line has unique data associated with it. We could omit
-** iosapic_interrupt() from the calling path if it did NOT need
-** to write EOI. For unshared lines, it really doesn't.
-**
-** Unfortunately, can't optimize out EOI if IRQ line isn't "shared".
-** N-class console "device" and some sort of heartbeat actually share
-** one line though only one driver is registered...<sigh>...this was
-** true for HP-UX at least. May not be true for parisc-linux.
-**
-**
-** Overview of exported iosapic functions
-** --------------------------------------
-** (caveat: code isn't finished yet - this is just the plan)
-**
-** iosapic_init:
-**   o initialize globals (lock, etc)
-**   o try to read IRT. Presence of IRT determines if this is
-**     a PAT platform or not.
-**
-** iosapic_register():
-**   o create iosapic_info instance data structure
-**   o allocate vector_info array for this iosapic
-**   o initialize vector_info - read corresponding IRdT?
-**
-** iosapic_xlate_pin: (only called by fixup_irq for PAT platform)
-**   o intr_pin = read cfg (INTERRUPT_PIN);
-**   o if (device under PCI-PCI bridge)
-**               translate slot/pin
-**
-** iosapic_fixup_irq:
-**   o if PAT platform (IRT present)
-**	   intr_pin = iosapic_xlate_pin(isi,pcidev):
-**         intr_line = find IRT entry(isi, PCI_SLOT(pcidev), intr_pin)
-**         save IRT entry into vector_info later
-**         write cfg INTERRUPT_LINE (with intr_line)?
-**     else
-**         intr_line = pcidev->irq
-**         IRT pointer = NULL
-**     endif
-**   o locate vector_info (needs: isi, intr_line)
-**   o allocate processor "irq" and get txn_addr/data
-**   o request_irq(processor_irq,  iosapic_interrupt, vector_info,...)
-**   o pcidev->irq = isi->isi_region...base + intr_line;
-**
-** iosapic_interrupt:
-**   o call do_irq(vector->isi->irq_region, vector->irq_line, regs)
-**   o assume level triggered and write EOI
-**
-** iosapic_enable_irq:
-**   o clear any pending IRQ on that line
-**   o enable IRdT - call enable_irq(vector[line]->processor_irq)
-**   o write EOI in case line is already asserted.
-**
-** iosapic_disable_irq:
-**   o disable IRdT - call disable_irq(vector[line]->processor_irq)
-**
-** FIXME: mask/unmask
-*/
-
-
-/* FIXME: determine which include files are really needed */
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <linux/pci.h>		/* pci cfg accessor functions  */
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/smp_lock.h>
-#include <linux/interrupt.h>	/* irqaction */
-#include <linux/irq.h>		/* irq_region support */
-
-#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 */
-
-#include <asm/iosapic.h>
-#include "./iosapic_private.h"
-
-#define MODULE_NAME "iosapic"
-
-/* "local" compile flags */
-#undef IOSAPIC_CALLBACK
-#undef PCI_BRIDGE_FUNCS
-#undef DEBUG_IOSAPIC
-#undef DEBUG_IOSAPIC_IRT
-
-
-#ifdef DEBUG_IOSAPIC
-static char assert_buf[128];
-
-static int
-assert_failed (char *a, char *f, int l)
-{
-        sprintf(assert_buf,
-			"ASSERT(%s) failed!\nline %d in %s\n",
-			a,      /* assertion text */
-			l,      /* line number */
-			f);     /* file name */
-        panic(assert_buf);
-	return 0;
-}
-
-#undef ASSERT
-#define ASSERT(EX) { if (!(EX)) assert_failed(# EX, __FILE__, __LINE__); }
-
-#define DBG(x...) printk(x)
-
-#else /* DEBUG_IOSAPIC */
-
-#define DBG(x...)
-#define ASSERT(EX)
-
-#endif /* DEBUG_IOSAPIC */
-
-#ifdef DEBUG_IOSAPIC_IRT
-#define DBG_IRT(x...) printk(x)
-#else
-#define DBG_IRT(x...)
-#endif
-
-
-#define READ_U8(addr)  gsc_readb(addr)
-#define READ_U16(addr) le16_to_cpu(gsc_readw((u16 *) (addr)))
-#define READ_U32(addr) le32_to_cpu(gsc_readl((u32 *) (addr)))
-#define READ_REG16(addr) gsc_readw((u16 *) (addr))
-#define READ_REG32(addr) gsc_readl((u32 *) (addr))
-#define WRITE_U8(value, addr) gsc_writeb(value, addr)
-#define WRITE_U16(value, addr) gsc_writew(cpu_to_le16(value), (u16 *) (addr))
-#define WRITE_U32(value, addr) gsc_writel(cpu_to_le32(value), (u32 *) (addr))
-#define WRITE_REG16(value, addr) gsc_writew(value, (u16 *) (addr))
-#define WRITE_REG32(value, addr) gsc_writel(value, (u32 *) (addr))
-
-
-#define IOSAPIC_REG_SELECT              0
-#define IOSAPIC_REG_WINDOW              0x10
-#define IOSAPIC_REG_EOI                 0x40
-
-#define IOSAPIC_REG_VERSION		0x1
-
-#define IOSAPIC_IRDT_ENTRY(idx)		(0x10+(idx)*2)
-#define IOSAPIC_IRDT_ENTRY_HI(idx)	(0x11+(idx)*2)
-
-/*
-** FIXME: revisit which GFP flags we should really be using.
-**     GFP_KERNEL includes __GFP_WAIT flag and that may not
-**     be acceptable. Since this is boot time, we shouldn't have
-**     to wait ever and this code should (will?) never get called
-**     from the interrrupt context.
-*/
-#define	IOSAPIC_KALLOC(a_type, cnt) \
-			(a_type *) kmalloc(sizeof(a_type)*(cnt), GFP_KERNEL)
-#define IOSAPIC_FREE(addr, f_type, cnt) kfree((void *)addr)
-
-
-#define	IOSAPIC_LOCK(lck)	spin_lock_irqsave(lck, irqflags)
-#define	IOSAPIC_UNLOCK(lck)	spin_unlock_irqrestore(lck, irqflags)
-
-
-#define IOSAPIC_VERSION_MASK            0x000000ff
-#define IOSAPIC_VERSION_SHIFT           0x0
-#define	IOSAPIC_VERSION(ver)				\
-		(int) ((ver & IOSAPIC_VERSION_MASK) >> IOSAPIC_VERSION_SHIFT)
-
-#define IOSAPIC_MAX_ENTRY_MASK          0x00ff0000
-
-#define IOSAPIC_MAX_ENTRY_SHIFT         0x10
-#define	IOSAPIC_IRDT_MAX_ENTRY(ver)			\
-		(int) ((ver&IOSAPIC_MAX_ENTRY_MASK) >> IOSAPIC_MAX_ENTRY_SHIFT)
-
-/* bits in the "low" I/O Sapic IRdT entry */
-#define IOSAPIC_IRDT_ENABLE       0x10000
-#define IOSAPIC_IRDT_PO_LOW       0x02000
-#define IOSAPIC_IRDT_LEVEL_TRIG   0x08000
-#define IOSAPIC_IRDT_MODE_LPRI    0x00100
-
-/* bits in the "high" I/O Sapic IRdT entry */
-#define IOSAPIC_IRDT_ID_EID_SHIFT              0x10
-
-
-
-#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;
-
-
-/*
-** REVISIT: future platforms may have more than one IRT.
-** If so, the following three fields form a structure which
-** then be linked into a list. Names are chosen to make searching
-** for them easy - not necessarily accurate (eg "cell").
-**
-** Alternative: iosapic_info could point to the IRT it's in.
-** iosapic_register() could search a list of IRT's.
-*/
-static struct irt_entry *irt_cell;
-static size_t irt_num_entry;
-
-
-
-/*
-** iosapic_load_irt
-**
-** The "Get PCI INT Routing Table Size" option returns the number of 
-** entries in the PCI interrupt routing table for the cell specified 
-** in the cell_number argument.  The cell number must be for a cell 
-** within the caller's protection domain.
-**
-** The "Get PCI INT Routing Table" option returns, for the cell 
-** specified in the cell_number argument, the PCI interrupt routing 
-** table in the caller allocated memory pointed to by mem_addr.
-** We assume the IRT only contains entries for I/O SAPIC and
-** calculate the size based on the size of I/O sapic entries.
-**
-** The PCI interrupt routing table entry format is derived from the
-** IA64 SAL Specification 2.4.   The PCI interrupt routing table defines
-** the routing of PCI interrupt signals between the PCI device output
-** "pins" and the IO SAPICs' input "lines" (including core I/O PCI
-** devices).  This table does NOT include information for devices/slots
-** behind PCI to PCI bridges. See PCI to PCI Bridge Architecture Spec.
-** for the architected method of routing of IRQ's behind PPB's.
-*/
-
-
-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 */
-	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);
-
-	switch(status) {
-
-	case PDC_RET_OK:	/* PAT box. Proceed to get the IRT */
-
-		/* save the number of entries in the table */
-		num_entries = pdc_io_num.num;
-		ASSERT(0UL != num_entries);
-
-		/*
-		** allocate memory for interrupt routing table
-		** This interface isn't really right. We are assuming
-		** the contents of the table are exclusively
-		** for I/O sapic devices.
-		*/
-		table = IOSAPIC_KALLOC(struct irt_entry, num_entries);
-		if (table == NULL) {
-			printk(KERN_WARNING MODULE_NAME ": read_irt : can not alloc mem for IRT\n");
-			return 0;
-		}
-
-		/* 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 */
-		/*
-		** C3000/J5000 (and similar) platforms with "legacy" PDC
-		** will return exactly one IRT.
-		** So if we have one, don't need to get it again.
-		*/
-		if (NULL != irt_cell)
-			break;
-
-		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);
-
-		if (PDC_RET_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);
-		if (table == NULL) {
-			printk(KERN_WARNING MODULE_NAME ": read_irt : can not alloc mem for IRT\n");
-			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;
-	}
-
-	/* 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",
-		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",
-		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,
-		((u32 *) p)[2],
-		((u32 *) p)[3]
-		);
-	}
-	}
-#endif /* DEBUG_IOSAPIC_IRT */
-
-	return num_entries;
-}
-
-
-
-void __init
-iosapic_init(void)
-{
-	/* init global data */
-	iosapic_lock = SPIN_LOCK_UNLOCKED;
-        iosapic_list = (struct iosapic_info *) NULL;
-	iosapic_count = 0;
-
-	DBG("iosapic_init()\n");
-
-	/*
-	**  get IRT for this cell.
-	*/
-	irt_num_entry =  iosapic_load_irt(0L, &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 */
-}
-
-
-/*
-** Return the IRT entry in case we need to look something else up.
-*/
-static struct irt_entry *
-irt_find_irqline(struct iosapic_info *isi, u8 slot, u8 intr_pin)
-{
-	struct irt_entry *i = irt_cell;
-	int cnt;	/* track how many entries we've looked at */
-	u8 irq_devno = (slot << IRT_DEV_SHIFT) | (intr_pin-1);
-
-	DBG_IRT("irt_find_irqline() SLOT %d pin %d\n", slot, intr_pin);
-
-	for (cnt=0; cnt < irt_num_entry; cnt++, i++) {
-
-		/*
-		** Validate: entry_type, entry_length, interrupt_type
-		**
-		** Difference between validate vs compare is the former
-		** should print debug info and is not expected to "fail"
-		** on current platforms.
-		*/
-		if (i->entry_type != IRT_IOSAPIC_TYPE) {
-			DBG_IRT(KERN_WARNING MODULE_NAME ":find_irqline(0x%p): skipping entry %d type %d\n", i, cnt, i->entry_type);
-			continue;
-		}
-		
-		if (i->entry_length != IRT_IOSAPIC_LENGTH) {
-			DBG_IRT(KERN_WARNING MODULE_NAME ":find_irqline(0x%p): skipping entry %d  length %d\n", i, cnt, i->entry_length);
-			continue;
-		}
-
-		if (i->interrupt_type != IRT_VECTORED_INTR) {
-			DBG_IRT(KERN_WARNING MODULE_NAME ":find_irqline(0x%p): skipping entry  %d interrupt_type %d\n", i, cnt, i->interrupt_type);
-			continue;
-		}
-
-		/*
-		** Compare: dest_iosapic_addr, src_bus_irq_devno
-		*/
-		if (i->dest_iosapic_addr != (u64) ((long) isi->isi_hpa))
-			continue;
-
-		if ((i->src_bus_irq_devno & IRT_IRQ_DEVNO_MASK) != irq_devno)
-			continue;
-
-		/*
-		** Ignore: src_bus_id and rc_seg_id correlate with
-		**         iosapic_info->isi_hpa on HP platforms.
-		**         If needed, pass in "PFA" (aka config space addr)
-		**         instead of slot.
-		*/
-
-		/* Found it! */
-		return i;
-	}
-
-	printk(KERN_WARNING MODULE_NAME ": 0x%p : no IRT entry for slot %d, pin %d\n",
-			isi->isi_hpa, slot, intr_pin);
-	return NULL;
-}
-
-
-/*
-** xlate_pin() supports the skewing of IRQ lines done by subsidiary bridges.
-** Legacy PDC already does this translation for us and stores it in INTR_LINE.
-**
-** PAT PDC needs to basically do what legacy PDC does:
-** o read PIN
-** o adjust PIN in case device is "behind" a PPB
-**     (eg 4-port 100BT and SCSI/LAN "Combo Card")
-** o convert slot/pin to I/O SAPIC input line.
-**
-** HP platforms only support:
-** o one level of skewing for any number of PPBs
-** o only support PCI-PCI Bridges.
-*/
-static struct irt_entry *
-iosapic_xlate_pin(struct iosapic_info *isi, struct pci_dev *pcidev)
-{
-	u8 intr_pin, intr_slot;
-
-	(void) 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);
-
-	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)
-	{
-		/* Convert pcidev INTR_PIN into something we
-		** can lookup in the IRT.
-		*/
-#ifdef PCI_BRIDGE_FUNCS
-		/*
-		** Proposal #1:
-		**
-		** call implementation specific translation function
-		** This is architecturally "cleaner". HP-UX doesn't
-		** support other secondary bus types (eg. E/ISA) directly.
-		** May be needed for other processor (eg IA64) architectures
-		** 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);
-		}
-#else	/* PCI_BRIDGE_FUNCS */
-		struct pci_bus *p = pcidev->bus;
-		/*
-		** Proposal #2:
-		** The "pin" is skewed ((pin + dev - 1) % 4).
-		**
-		** This isn't very clean since I/O SAPIC must assume:
-		**   - all platforms only have PCI busses.
-		**   - only PCI-PCI bridge (eg not PCI-EISA, PCI-PCMCIA)
-		**   - IRQ routing is only skewed once regardless of
-		**     the number of PPB's between iosapic and device.
-		**     (Bit3 expansion chassis follows this rule)
-		**
-		** Advantage is it's really easy to implement.
-		*/
-		intr_pin = ((intr_pin-1)+PCI_SLOT(pcidev->devfn)) % 4;
-		intr_pin++;	/* convert back to INTA-D (1-4) */
-#endif /* PCI_BRIDGE_FUNCS */
-
-		/*
-		** Locate the host slot the PPB nearest the Host bus
-		** adapter.
-		*/
-		while (NULL != p->parent->self)
-			p = p->parent;
-
-		intr_slot = PCI_SLOT(p->self->devfn);
-	} else {
-		intr_slot = PCI_SLOT(pcidev->devfn);
-	}
-	DBG_IRT("iosapic_xlate_pin:  bus %d slot %d pin %d\n",
-				pcidev->bus->secondary, intr_slot, intr_pin);
-
-	return irt_find_irqline(isi, intr_slot, intr_pin);
-}
-
-
-static void
-iosapic_interrupt(int irq, void *dev_id, struct pt_regs * regs)
-{
-	struct vector_info *vi = (struct vector_info *)dev_id;
-	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);
-
-/* FIXME: Need to mask/unmask? processor IRQ is already masked... */
-	do_irq(&vi->vi_ios->isi_region->action[vi->vi_irqline], irq_num, regs);
-
-	/*
-	** PCI only supports level triggered in order to share IRQ lines.
-	** I/O SAPIC must always issue EOI.
-	*/
-	IOSAPIC_EOI(vi->vi_eoi_addr, vi->vi_eoi_data);
-}
-
-
-int
-iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev)
-{
-	struct iosapic_info *isi = (struct iosapic_info *)isi_obj;
-	struct irt_entry *irte = NULL;  /* only used if PAT PDC */
-	struct vector_info *vi;
-	int isi_line;	/* line used by device */
-	int tmp;
-
-	if (NULL == isi) {
-		printk(KERN_WARNING MODULE_NAME ": 0x%p hpa not registered\n", isi->isi_hpa);
-		return(-1);
-	}
-
-	/* lookup IRT entry for isi/slot/pin set */
-	irte = iosapic_xlate_pin(isi, pcidev);
-	if (NULL == irte) {
-		return(-1);
-	}
-	DBG_IRT("iosapic_fixup_irq(): irte %p %x %x %x %x %x %x %x %x\n",
-		irte,
-		irte->entry_type,
-		irte->entry_length,
-		irte->polarity_trigger,
-		irte->src_bus_irq_devno,
-		irte->src_bus_id,
-		irte->src_seg_id,
-		irte->dest_iosapic_intin,
-		(u32) irte->dest_iosapic_addr);
-	isi_line = irte->dest_iosapic_intin;
-
-	/* get vector info for this input line */
-	ASSERT(NULL != isi->isi_vector);
-	vi = &(isi->isi_vector[isi_line]);
-	DBG_IRT("iosapic_fixup_irq:  line %d vi 0x%p\n", isi_line, vi);
-	vi->vi_irte = irte;
-
-	/* Allocate processor IRQ */
-	vi->vi_txn_irq = txn_alloc_irq();
-
-/* XXX/FIXME The txn_alloc_irq() code and related code should be moved
-** to enable_irq(). That way we only allocate processor IRQ bits
-** for devices that actually have drivers claiming them.
-** Right now we assign an IRQ to every PCI device present regardless
-** of whether it's used or not.
-*/
-	if (vi->vi_txn_irq < 0)
-		panic("I/O sapic: couldn't get TXN IRQ\n");
-
-	/* enable_irq() will use txn_* to program IRdT */
-	vi->vi_txn_addr = txn_alloc_addr(vi->vi_txn_irq);
-	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);
-	ASSERT(tmp == 0);
-
-	vi->vi_eoi_addr = ((void *) 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;
-
-	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);
-
-	return(pcidev->irq);
-}
-
-
-static void
-iosapic_rd_irt_entry(struct vector_info *vi , u32 *dp0, u32 *dp1)
-{
-	struct iosapic_info *isp = vi->vi_ios;
-	u8 idx = vi->vi_irqline;
-
-	/* point the window register to the lower word */
-	WRITE_U32(IOSAPIC_IRDT_ENTRY(idx), isp->isi_hpa+IOSAPIC_REG_SELECT);
-	*dp0 = READ_U32(isp->isi_hpa+IOSAPIC_REG_WINDOW);
-
-	/* point the window register to the higher word */
-	WRITE_U32(IOSAPIC_IRDT_ENTRY_HI(idx), isp->isi_hpa+IOSAPIC_REG_SELECT);
-	*dp1 = READ_U32(isp->isi_hpa+IOSAPIC_REG_WINDOW);
-}
-
-
-static void
-iosapic_wr_irt_entry(struct vector_info *vi, u32 dp0, u32 dp1)
-{
-	struct iosapic_info *isp = vi->vi_ios;
-
-	ASSERT(NULL != isp);
-	ASSERT(NULL != 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,
-		dp0, dp1);
-
-	/* point the window register to the lower word */
-	WRITE_U32(IOSAPIC_IRDT_ENTRY(vi->vi_irqline), isp->isi_hpa+IOSAPIC_REG_SELECT);
-	WRITE_U32( dp0, isp->isi_hpa+IOSAPIC_REG_WINDOW);
-
-	/* Read the window register to flush the writes down to HW  */
-	dp0 = READ_U32(isp->isi_hpa+IOSAPIC_REG_WINDOW);
-
-	/* point the window register to the higher word */
-	WRITE_U32(IOSAPIC_IRDT_ENTRY_HI(vi->vi_irqline), isp->isi_hpa+IOSAPIC_REG_SELECT);
-	WRITE_U32( dp1, isp->isi_hpa+IOSAPIC_REG_WINDOW);
-
-	/* Read the window register to flush the writes down to HW  */
-	dp1 = READ_U32(isp->isi_hpa+IOSAPIC_REG_WINDOW);
-}
-
-
-/*
-** set_irt prepares the data (dp0, dp1) according to the vector_info
-** and target cpu (id_eid).  dp0/dp1 are then used to program I/O SAPIC
-** IRdT for the given "vector" (aka IRQ line).
-*/
-static void
-iosapic_set_irt_data( struct vector_info *vi, u32 *dp0, u32 *dp1)
-{
-	u32 mode = 0;
-	struct irt_entry *p = vi->vi_irte;
-	ASSERT(NULL != vi->vi_irte);
-
-	if ((p->polarity_trigger & IRT_PO_MASK) == IRT_ACTIVE_LO)
-		mode |= IOSAPIC_IRDT_PO_LOW;
-
-	if (((p->polarity_trigger >> IRT_EL_SHIFT) & IRT_EL_MASK) == IRT_LEVEL_TRIG)
-		mode |= IOSAPIC_IRDT_LEVEL_TRIG;
-
-	/*
-	** IA64 REVISIT
-	** PA doesn't support EXTINT or LPRIO bits.
-	*/
-
-	ASSERT(vi->vi_txn_data);
-	*dp0 = mode | (u32) vi->vi_txn_data;
-
-	/*
-	** 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) {
-		/*
-		** 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
-	{
-		/* 
-		** eg if base_addr == 0xfffa0000),
-		**    we want to get 0xa0ff0000.
-		**
-		** eid	0x0ff00000 -> 0x00ff0000
-		** id	0x000ff000 -> 0xff000000
-		*/
-		*dp1 = (((u32)vi->vi_txn_addr & 0x0ff00000) >> 4) |
-			(((u32)vi->vi_txn_addr & 0x000ff000) << 12);
-	}
-	DBG_IRT("iosapic_set_irt_data(): 0x%x 0x%x\n", *dp0, *dp1);
-}
-
-
-static void
-iosapic_disable_irq(void *irq_dev, int irq)
-{
-	ulong irqflags;
-	struct vector_info *vi = &(((struct vector_info *) irq_dev)[irq]);
-	u32 d0, d1;
-
-	ASSERT(NULL != vi);
-
-	IOSAPIC_LOCK(&iosapic_lock);
-
-#ifdef REVISIT_DESIGN_ISSUE
-/* 
-** XXX/FIXME
-
-disable_irq()/enable_irq(): drawback of using IRQ as a "handle"
-
-Current disable_irq interface only allows the irq_region support routines
-to manage sharing of "irq" objects.  The problem is the disable_irq()
-interface specifies which IRQ line needs to be disabled but does not
-identify the particular ISR which needs to be disabled.  IO sapic
-(and similar code in Dino) can only support one handler per IRQ
-since they don't further encode the meaning of the IRQ number.
-irq_region support has to hide it's implementation of "shared IRQ"
-behind a function call.
-
-Encoding the IRQ would be possible by I/O SAPIC but makes life really
-complicated for the IRQ handler and not help performance.
-
-Need more info on how Linux supports shared IRQ lines on a PC.
-*/
-#endif /* REVISIT_DESIGN_ISSUE */
-
-	iosapic_rd_irt_entry(vi, &d0, &d1);
-	d0 |= IOSAPIC_IRDT_ENABLE;
-	iosapic_wr_irt_entry(vi, d0, d1);
-
-	IOSAPIC_UNLOCK(&iosapic_lock);
-
-	/* disable ISR for parent */
-	disable_irq(vi->vi_txn_irq);
-}
-
-
-static void
-iosapic_enable_irq(void *dev, int irq)
-{
-	struct vector_info *vi = &(((struct vector_info *) dev)[irq]);
-	u32 d0, d1;
-
-	ASSERT(NULL != vi);
-	ASSERT(NULL != vi->vi_irte);
-
-	/* 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);
-	iosapic_wr_irt_entry(vi, d0, d1);
-
-
-#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");
-}
-
-printk("iosapic_enable_irq(): sel ");
-{
-	struct iosapic_info *isp = vi->vi_ios;
-
-	for (d0=0x10; d0<0x1e; d0++) {
-		/* point the window register to the lower word */
-		WRITE_U32(d0, isp->isi_hpa+IOSAPIC_REG_SELECT);
-
-		/* read the word */
-		d1 = READ_U32(isp->isi_hpa+IOSAPIC_REG_WINDOW);
-		printk(" %x", d1);
-	}
-}
-printk("\n");
-#endif
-
-	/*
-	** KLUGE: IRQ should not be asserted when Drivers enabling their IRQ.
-	**        PCI supports level triggered in order to share IRQ lines.
-	**
-	** Issueing I/O SAPIC an EOI causes an interrupt iff IRQ line is
-	** asserted.
-	*/
-	IOSAPIC_EOI(vi->vi_eoi_addr, vi->vi_eoi_data);
-}
-
-
-static void
-iosapic_mask_irq(void *dev, int irq)
-{
-	BUG();
-}
-
-
-static void
-iosapic_unmask_irq(void *dev, int irq)
-{
-	BUG();
-}
-
-
-static struct irq_region_ops iosapic_irq_ops = {
-	iosapic_disable_irq,
-	iosapic_enable_irq,
-	iosapic_mask_irq,
-	iosapic_unmask_irq
-};
-
-
-/*
-** squirrel away the I/O Sapic Version
-*/
-static unsigned int
-iosapic_rd_version(struct iosapic_info *isi)
-{
-	ASSERT(isi);
-	ASSERT(isi->isi_hpa);
-
-	/* point window to the version register */
-	WRITE_U32(IOSAPIC_REG_VERSION, isi->isi_hpa+IOSAPIC_REG_SELECT);
-
-	/* now read the version register */
-	return (READ_U32(isi->isi_hpa+IOSAPIC_REG_WINDOW));
-}
-
-
-#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.
-**
-**	o allocate iosapic_info and add it to the list
-**	o read iosapic version and squirrel that away
-**	o read size of IRdT.
-**	o allocate and initialize isi_vector[]
-**	o allocate isi_region (registers region handlers)
-*/
-void *
-iosapic_register(void *hpa)
-{
-	struct iosapic_info *isi = NULL;
-	struct irt_entry *irte = irt_cell;
-	struct vector_info *vip;
-	int cnt;	/* track how many entries we've looked at */
-
-	/*
-	** Astro based platforms can't support PCI OLARD if they
-	** implement the legacy PDC (not PAT). Though Legacy PDC
-	** supports an IRT, LBA's with no device under them
-	** are *not* listed in the IRT.
-	** Search the IRT and ignore iosapic's which aren't
-	** in the IRT.
-	*/
-	ASSERT(NULL != irte);	/* always have built-in devices */
-	for (cnt=0; cnt < irt_num_entry; cnt++, irte++) {
-		ASSERT(IRT_IOSAPIC_TYPE == irte->entry_type);
-		/*
-		** We need sign extension of the hpa on 32-bit kernels.
-		** The address in the IRT is *always* 64 bit and really
-		** is an unsigned quantity (like all physical addresses).
-		*/ 
-		if (irte->dest_iosapic_addr == (s64) ((long) hpa))
-			break;
-	}
-
-	if (cnt  >= irt_num_entry)
-		return (NULL);
-
-	if ((isi = IOSAPIC_KALLOC(struct iosapic_info, 1)) == NULL) {
-		BUG();
-		return (NULL);
-	}
-
-	memset(isi, 0, sizeof(struct iosapic_info));
-
-	isi->isi_hpa         = (unsigned char *) hpa;
-	isi->isi_version     = iosapic_rd_version(isi);
-	isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1;
-
-	vip = isi->isi_vector =
-		 IOSAPIC_KALLOC(struct vector_info, isi->isi_num_vectors);
-
-	if (vip == NULL) {
-		IOSAPIC_FREE(isi, struct iosapic_info, 1);
-		return (NULL);
-	}
-
-	memset(vip, 0, sizeof(struct vector_info) * isi->isi_num_vectors);
-
-	/*
-	** Initialize vector array
-	*/
-	for (cnt=0; cnt < isi->isi_num_vectors; cnt++, vip++) {
-		vip->vi_irqline = (unsigned char) cnt;
-		vip->vi_ios = isi;
-	}
-
-	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);
-
-	ASSERT(NULL != isi->isi_region);
-	return ((void *) isi);
-}
-#endif /* !IOSAPIC_CALLBACK */
-
-
-
-#ifdef DEBUG_IOSAPIC
-
-static void
-iosapic_prt_irt(void *irt, long num_entry)
-{
-	unsigned int i, *irp = (unsigned int *) irt;
-
-	ASSERT(NULL != irt);
-
-	printk(KERN_DEBUG MODULE_NAME ": Interrupt Routing Table (%lx entries)\n", num_entry);
-
-	for (i=0; i<num_entry; i++, irp += 4) {
-		printk(KERN_DEBUG "%p : %2d %.8x %.8x %.8x %.8x\n",
-					irp, i, irp[0], irp[1], irp[2], irp[3]);
-	}
-}
-
-
-static void
-iosapic_prt_vi(struct vector_info *vi)
-{
-	ASSERT(NULL != vi);
-
-	printk(KERN_DEBUG MODULE_NAME ": vector_info[%d] is at %p\n", vi->vi_irqline, vi);
-	printk(KERN_DEBUG "\t\tvi_status:	 %.4x\n", vi->vi_status);
-	printk(KERN_DEBUG "\t\tvi_txn_irq:  %d\n",  vi->vi_txn_irq);
-	printk(KERN_DEBUG "\t\tvi_txn_addr: %lx\n", vi->vi_txn_addr);
-	printk(KERN_DEBUG "\t\tvi_txn_data: %lx\n", vi->vi_txn_data);
-	printk(KERN_DEBUG "\t\tvi_eoi_addr: %p\n",  vi->vi_eoi_addr);
-	printk(KERN_DEBUG "\t\tvi_eoi_data: %x\n",  vi->vi_eoi_data);
-}
-
-
-static void
-iosapic_prt_isi(struct iosapic_info *isi)
-{
-	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_version:   %x\n", isi->isi_version);
-	printk(KERN_DEBUG "\t\tisi_vector:    %p\n", isi->isi_vector);
-}
-#endif /* DEBUG_IOSAPIC */
diff -Nru a/arch/parisc/kernel/iosapic_private.h b/arch/parisc/kernel/iosapic_private.h
--- a/arch/parisc/kernel/iosapic_private.h	Mon Nov  4 14:31:01 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,165 +0,0 @@
-/*
-** This file is private to iosapic driver.
-** If stuff needs to be used by another driver, move it to a common file.
-**
-** WARNING: fields most data structures here are ordered to make sure
-**          they pack nicely for 64-bit compilation. (ie sizeof(long) == 8)
-*/
-
-
-/*
-** Interrupt Routing Stuff
-** -----------------------
-** The interrupt routing table consists of entries derived from
-** MP Specification Draft 1.5. There is one interrupt routing 
-** table per cell.  N- and L-class consist of a single cell.
-*/
-struct irt_entry {
-
-	/* Entry Type 139 identifies an I/O SAPIC interrupt entry */
-	u8 entry_type;
-
-	/* Entry Length 16 indicates entry is 16 bytes long */
-	u8 entry_length;
-
-	/* 
-	** Interrupt Type of 0 indicates a vectored interrupt, 
-	** all other values are reserved 
-	*/
-	u8 interrupt_type;
-
-	/* 
-	** PO and EL
-	** Polarity of SAPIC I/O input signals: 
-	**    00 = Reserved 
-	**    01 = Active high 
-	**    10 = Reserved 
-	**    11 = Active low 
-	** Trigger mode of SAPIC I/O input signals: 
-	**    00 = Reserved 
-	**    01 = Edge-triggered 
-	**    10 = Reserved 
-	**    11 = Level-triggered
-	*/
-	u8 polarity_trigger;
-
-	/* 
-	** IRQ and DEVNO
-	** irq identifies PCI interrupt signal where
-	**    0x0 corresponds to INT_A#, 
-	**    0x1 corresponds to INT_B#, 
-	**    0x2 corresponds to INT_C# 
-	**    0x3 corresponds to INT_D# 
-	** PCI device number where interrupt originates 
-	*/
-	u8 src_bus_irq_devno;
-
-	/* Source Bus ID identifies the bus where interrupt signal comes from */
-	u8 src_bus_id;
-
-	/* 
-	** Segment ID is unique across a protection domain and
-	** identifies a segment of PCI buses (reserved in 
-	** MP Specification Draft 1.5) 
-	*/
-	u8 src_seg_id;
-
-	/* 
-	** Destination I/O SAPIC INTIN# identifies the INTIN n pin 
-	** to which the signal is connected 
-	*/
-	u8 dest_iosapic_intin;
-
-	/* 
-	** Destination I/O SAPIC Address identifies the I/O SAPIC 
-	** to which the signal is connected 
-	*/
-	u64 dest_iosapic_addr;
-};
-
-#define IRT_IOSAPIC_TYPE   139
-#define IRT_IOSAPIC_LENGTH 16
-
-#define IRT_VECTORED_INTR  0
-
-#define IRT_PO_MASK        0x3
-#define IRT_ACTIVE_HI      1
-#define IRT_ACTIVE_LO      3
-
-#define IRT_EL_MASK        0x3
-#define IRT_EL_SHIFT       2
-#define IRT_EDGE_TRIG      1
-#define IRT_LEVEL_TRIG     3
-
-#define IRT_IRQ_MASK       0x3
-#define IRT_DEV_MASK       0x1f
-#define IRT_DEV_SHIFT      2
-
-#define IRT_IRQ_DEVNO_MASK	((IRT_DEV_MASK << IRT_DEV_SHIFT) | IRT_IRQ_MASK)
-
-#ifdef SUPPORT_MULTI_CELL
-struct iosapic_irt {
-        struct iosapic_irt *irt_next;  /* next routing table */
-        struct irt_entry *irt_base;             /* intr routing table address */
-        size_t  irte_count;            /* number of entries in the table */
-        size_t  irte_size;             /* size (bytes) of each entry */
-};
-#endif
-
-struct vector_info {
-	struct iosapic_info *vi_ios;    /* I/O SAPIC this vector is on */
-	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 */
-};
-
-
-struct iosapic_info {
-	struct iosapic_info  *isi_next;      /* list of I/O SAPIC          */
-	volatile void        *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 */
-};
-
-
-
-#ifdef __IA64__
-/*
-** PA risc does NOT have any local sapics. IA64 does.
-** PIB (Processor Interrupt Block) is handled by Astro or Dew (Stretch CEC).
-**
-** PA: Get id_eid from IRT and hardcode PIB to 0xfeeNNNN0
-**     Emulate the data on PAT platforms.
-*/
-struct local_sapic_info {
-	struct local_sapic_info *lsi_next;      /* point to next CPU info */
-	int                     *lsi_cpu_id;    /* point to logical CPU id */
-	unsigned long           *lsi_id_eid;    /* point to IA-64 CPU id */
-	int                     *lsi_status;    /* point to CPU status   */
-	void                    *lsi_private;   /* point to special info */
-};
-
-/*
-** "root" data structure which ties everything together.
-** Should always be able to start with sapic_root and locate
-** the desired information.
-*/
-struct sapic_info {
-	struct sapic_info	*si_next;	/* info is per cell */
-	int                     si_cellid;      /* cell id */
-	unsigned int            si_status;       /* status  */
-	char                    *si_pib_base;   /* intr blk base address */
-	local_sapic_info_t      *si_local_info;
-	io_sapic_info_t         *si_io_info;
-	extint_info_t           *si_extint_info;/* External Intr info      */
-};
-#endif
-
diff -Nru a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
--- a/arch/parisc/kernel/irq.c	Mon Nov  4 14:31:01 2002
+++ b/arch/parisc/kernel/irq.c	Mon Nov  4 14:31:01 2002
@@ -57,7 +57,7 @@
 /* Bits in EIEM correlate with cpu_irq_action[].
 ** Numbered *Big Endian*! (ie bit 0 is MSB)
 */
-static unsigned long cpu_eiem = 0;
+static volatile unsigned long cpu_eiem = 0;
 
 static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED;  /* protect IRQ regions */
 
@@ -104,24 +104,35 @@
 	set_eiem(cpu_eiem);
 }
 
-static struct irqaction cpu_irq_actions[IRQ_PER_REGION] = {
+/*
+ * XXX cpu_irq_actions[] will become 2 dimensional for per CPU EIR support.
+ * correspond changes needed in:
+ * 	processor_probe()	initialize additional action arrays
+ * 	request_irq()		handle CPU IRQ region specially
+ * 	do_cpu_irq_mask()	index into the matching irq_action array.
+ */
+struct irqaction cpu_irq_actions[IRQ_PER_REGION] = {
 	[IRQ_OFFSET(TIMER_IRQ)] { handler: timer_interrupt, name: "timer", },
 #ifdef CONFIG_SMP
 	[IRQ_OFFSET(IPI_IRQ)]	{ handler: ipi_interrupt,   name: "IPI", },
 #endif
 };
 
-struct irq_region cpu_irq_region = {
+struct irq_region_ops cpu_irq_ops = {
+	disable_cpu_irq, enable_cpu_irq, unmask_cpu_irq, unmask_cpu_irq
+};
+
+struct irq_region cpu0_irq_region = {
 	ops:	{ disable_cpu_irq, enable_cpu_irq, unmask_cpu_irq, unmask_cpu_irq },
 	data:	{ dev: &cpu_data[0],
-		  name: "PA-CPU-00",
+		  name: "PARISC-CPU",
 		  irqbase: IRQ_FROM_REGION(CPU_IRQ_REGION), },
 	action:	cpu_irq_actions,
 };
 
 struct irq_region *irq_region[NR_IRQ_REGS] = {
 	[ 0 ]              NULL, /* reserved for EISA, else causes data page fault (aka code 15) */
-	[ CPU_IRQ_REGION ] &cpu_irq_region,
+	[ CPU_IRQ_REGION ] &cpu0_irq_region,
 };
 
 
@@ -192,10 +203,10 @@
 	unsigned int regnr = 0;
 
 	seq_puts(p, "     ");
-#if 0 /* def CONFIG_SMP */
-	for (; regnr < smp_num_cpus; regnr++)
+#ifdef CONFIG_SMP
+	for (regnr = 0; regnr < NR_CPUS; regnr++)
 #endif
-		seq_printf(p, "      CPU%d ", regnr);
+		seq_printf(p, "      CPU%02d ", regnr);
 
 #ifdef PARISC_IRQ_CR16_COUNTS
 	seq_printf(p, "[min/avg/max] (CPU cycle counts)");
@@ -216,24 +227,16 @@
 	    for (i = 0; i <= MAX_CPU_IRQ; i++) {
 		struct irqaction *action = &region->action[i];
 		unsigned int irq_no = IRQ_FROM_REGION(regnr) + i;
-#if 0 /* def CONFIG_SMP */
-/* We currently direct all Interrupts at the Monarch.
- * The right way to handle SMP IRQ stats is to have one IRQ region/CPU.
- */
-		unsigned int j;
-#endif
-
+		int j=0;
 		if (!action->handler)
 			continue;
 
 		seq_printf(p, "%3d: ", irq_no);
-#if 1 /* ndef CONFIG_SMP */
-		seq_printf(p, "%10u ", kstat_irqs(irq_no));
-#else
-		for (j = 0; j < smp_num_cpus; j++)
-		    seq_printf(p, "%10u ",
-			    kstat.irqs[cpu_logical_map(j)][irq_no]);
+#ifdef CONFIG_SMP
+		for (; j < NR_CPUS; j++)
 #endif
+		    seq_printf(p, "%10u ", kstat.irqs[j][regnr][irq_no]);
+
 		seq_printf(p, " %14s",
 			    region->data.name ? region->data.name : "N/A");
 #ifndef PARISC_IRQ_CR16_COUNTS
@@ -243,12 +246,12 @@
 			seq_printf(p, ", %s", action->name);
 #else
 		for ( ;action; action = action->next) {
-			unsigned int i, avg, min, max;
+			unsigned int k, avg, min, max;
 
 			min = max = action->cr16_hist[0];
 
-			for (avg = i = 0; i < PARISC_CR16_HIST_SIZE; i++) {
-				int hist = action->cr16_hist[i];
+			for (avg = k = 0; k < PARISC_CR16_HIST_SIZE; k++) {
+				int hist = action->cr16_hist[k];
 
 				if (hist) {
 					avg += hist;
@@ -259,7 +262,7 @@
 				if (hist < min) min = hist;
 			}
 
-			avg /= i;
+			avg /= k;
 			seq_printf(p, " %s[%d/%d/%d]", action->name,
 					min,avg,max);
 		}
@@ -292,7 +295,7 @@
 
 	/* never return irq 0 cause that's the interval timer */
 	for (irq = 1; irq <= MAX_CPU_IRQ; irq++) {
-		if (cpu_irq_region.action[irq].handler == NULL) {
+		if (cpu_irq_actions[irq].handler == NULL) {
 			return (IRQ_FROM_REGION(CPU_IRQ_REGION) + irq);
 		}
 	}
@@ -314,14 +317,18 @@
 unsigned long
 txn_alloc_addr(int virt_irq)
 {
-	struct cpuinfo_parisc *dev = (struct cpuinfo_parisc *) (irq_region[IRQ_REGION(virt_irq)]->data.dev);
+	static int next_cpu = -1;
 
-	if (!dev) {
-		printk(KERN_ERR "txn_alloc_addr(0x%x): CPU IRQ region? dev %p\n",
-			virt_irq,dev);
-		return 0;
-	}
-	return (dev->txn_addr);
+	next_cpu++; /* assign to "next" CPU we want this bugger on */
+
+	/* validate entry */
+	while ((next_cpu < NR_CPUS) && !cpu_data[next_cpu].txn_addr)
+		next_cpu++;
+
+	if (next_cpu >= NR_CPUS) 
+		next_cpu = 0;	/* nothing else, assign monarch */
+
+	return cpu_data[next_cpu].txn_addr;
 }
 
 
@@ -365,7 +372,7 @@
 	int cpu = smp_processor_id();
 
 	irq_enter();
-	++kstat.irqs[IRQ_REGION(irq)][IRQ_OFFSET(irq)];
+	++kstat.irqs[cpu][IRQ_REGION(irq)][IRQ_OFFSET(irq)];
 
 	DBG_IRQ(irq, ("do_irq(%d) %d+%d\n", irq, IRQ_REGION(irq), IRQ_OFFSET(irq)));
 
@@ -407,7 +414,7 @@
 
 
 /* ONLY called from entry.S:intr_extint() */
-void do_cpu_irq_mask(struct irq_region *region, struct pt_regs *regs)
+void do_cpu_irq_mask(struct pt_regs *regs)
 {
 	unsigned long eirr_val;
 	unsigned int i=3;	/* limit time in interrupt context */
@@ -431,7 +438,7 @@
 	 */
 	while ((eirr_val = (mfctl(23) & cpu_eiem)) && --i) {
 		unsigned long bit = (1UL<<MAX_CPU_IRQ);
-		unsigned int irq = 0;
+		unsigned int irq;
 
 		mtctl(eirr_val, 23); /* reset bits we are going to process */
 
@@ -440,17 +447,16 @@
 			printk(KERN_DEBUG "do_cpu_irq_mask  %x\n", eirr_val);
 #endif
 
-		for (; eirr_val && bit; bit>>=1, irq++)
+		/* Work our way from MSb to LSb...same order we alloc EIRs */
+		for (irq = 0; eirr_val && bit; bit>>=1, irq++)
 		{
-			unsigned int irq_num;
-			if (!(bit&eirr_val))
+			if (!(bit & eirr_val & cpu_eiem))
 				continue;
 
 			/* clear bit in mask - can exit loop sooner */
 			eirr_val &= ~bit;
 
-			irq_num = region->data.irqbase + irq;
-			do_irq(&region->action[irq], irq_num, regs);
+			do_irq(&cpu_irq_actions[irq], TIMER_IRQ+irq, regs);
 		}
 	}
 	set_eiem(cpu_eiem);
@@ -673,6 +679,14 @@
 	spin_unlock(&irq_lock);
 	printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
 }
+
+
+#ifdef CONFIG_SMP
+void synchronize_irq(unsigned int irqnum)
+{
+	while (in_irq()) ;
+}
+#endif
 
 
 /*
diff -Nru a/arch/parisc/kernel/lasimap.map b/arch/parisc/kernel/lasimap.map
--- a/arch/parisc/kernel/lasimap.map	Mon Nov  4 14:31:02 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,322 +0,0 @@
-# HP 712 kernel keymap. This uses 7 modifier combinations.
-
-keymaps 0-2,4-5,8,12
-# ie, plain,  Shift,  AltGr,  Control, Control+Shift, Alt and Control+Alt
-
-
-# Change the above line into
-#	keymaps 0-2,4-6,8,12
-# in case you want the entries
-#	altgr   control keycode  83 = Boot            
-#	altgr   control keycode 111 = Boot            
-# below.
-#
-# In fact AltGr is used very little, and one more keymap can
-# be saved by mapping AltGr to Alt (and adapting a few entries):
-# keycode 100 = Alt
-#
-keycode   1 = F9	F19	Console_21
-	control	keycode	1 = F9
-	alt	keycode	1 = Console_9
-	control	alt	keycode	1 = Console_9
-keycode   2 =
-keycode   3 = F5	F15	Console_17
-	control	keycode	3 = F5
-	alt	keycode	3 = Console_5
-	control	alt	keycode	3 = Console_5
-keycode   4 = F3	F13	Console_15
-	control	keycode	4 = F3
-	alt	keycode	4 = Console_3
-	control	alt	keycode	4 = Console_3
-keycode   5 = F1	F11	Console_13
-	control	keycode	5 = F1
-	alt	keycode	5 = Console_1
-	control	alt	keycode	5 = Console_1
-keycode   6 = F2	F12	Console_14
-	control	keycode	6 = F2
-	alt	keycode	6 = Console_2
-	control	alt	keycode	6 = Console_2
-keycode   7 = F12	F12	Console_24
-	control	keycode	7 = F12
-	alt	keycode	7 = Console_12
-	control	alt	keycode	7 = Console_12
-keycode   8 = 
-keycode   9 = F10	F20	Console_22
-	control	keycode	9 = F10
-	alt	keycode	9 = Console_10
-	control	alt	keycode	9 = Console_10
-keycode  10 = F8	F18	Console_20
-	control	keycode	10 = F8
-	alt	keycode	10 = Console_8
-	control	alt	keycode	10 = Console_8
-keycode  11 = F6	F16	Console_18
-	control	keycode	11 = F6
-	alt	keycode	11 = Console_6
-	control	alt	keycode	11 = Console_6
-keycode  12 = F4	F14	Console_16
-	control	keycode	12 = F4
-	alt	keycode	12 = Console_4
-	control	alt	keycode 12 = Console_4
-keycode  13 = Tab	Tab
-	alt	keycode	13 = Meta_Tab
-keycode  14 = grave	asciitilde
-	control	keycode	14 = nul
-	alt	keycode	14 = Meta_grave
-keycode  15 = 
-keycode  16 =
-keycode  17 = Alt
-keycode  18 = Shift
-keycode  19 =
-keycode  20 = Control
-keycode  21 = q
-keycode  22 = one	exclam	exclam
-keycode  23 =
-keycode  24 =
-keycode  25 =
-keycode  26 = z
-keycode  27 = s
-keycode  28 = a
-	altgr	keycode	28 = Hex_A
-keycode  29 = w
-keycode  30 = two	at	at
-keycode  31 =
-keycode  32 =
-keycode  33 = c
-	altgr	keycode	46 = Hex_C
-keycode  34 = x
-keycode  35 = d
-	altgr	keycode 35 = Hex_D
-keycode  36 = e
-	altgr	keycode	36 = Hex_E
-keycode  37 = four	dollar
-keycode  38 = three	numbersign
-keycode  39 =
-keycode  40 =
-keycode  41 =
-keycode  42 = v
-keycode  43 = f
-	 altgr	keycode 43 = Hex_F
-keycode  44 = t
-keycode  45 = r
-keycode  46 = five	percent
-keycode  47 =
-keycode  48 =
-keycode  49 = n
-keycode  50 = b
-	altgr	keycode	50 = Hex_B
-keycode  51 = h
-keycode  52 = g
-keycode  53 = y
-keycode  54 = six	asciicircum
-keycode  55 =
-keycode  56 =
-keycode  57 =
-keycode  58 = m
-keycode  59 = j
-keycode  60 = u
-keycode  61 = seven	ampersand
-keycode  62 = eight	asterisk	asterisk
-keycode  63 =
-keycode  64 =        
-keycode  65 = comma	less
-	alt	keycode	65 = Meta_comma
-keycode  66 = k
-keycode  67 = i
-keycode  68 = o
-keycode  69 = zero	parenright	bracketright
-keycode  70 = nine	parenleft	bracketleft
-keycode  71 = 
-keycode  72 =
-keycode  73 = period	greater
-	control	keycode	73 = Compose
-	alt	keycode	73 = Meta_period
-keycode  74 = slash	question
-	control	keycode 74 = Delete
-	alt	keycode 53 = Meta_slash
-keycode  75 = l
-keycode  76 = semicolon	colon
-	alt	keycode	39 = Meta_semicolon
-keycode  77 = p
-keycode  78 = minus	underscore
-keycode  79 =
-keycode  80 =
-keycode  81 =
-keycode  82 = apostrophe	quotedbl
-	control	keycode	82 = Control_g
-	alt	keycode	40 = Meta_apostrophe
-keycode  83 =
-keycode  84 = bracketleft	braceleft
-	control	keycode	84 = Escape
-	alt	keycode	26 = Meta_bracketleft
-keycode  85 = equal	plus
-keycode  86 = 
-keycode  87 = 
-keycode  88 = Caps_Lock
-keycode  88 =
-keycode  89 =
-keycode  89 =
-keycode  89 =
-keycode  90 = Return
-	 alt  keycode	90 = Meta_Control_m
-keycode  91 = bracketright	braceright	asciitilde
-	control	keycode	91 = Control_bracketright
-	alt	keycode	91 = Meta_bracketright
-keycode  92 =
-keycode  93 = backslash		bar
-	control	keycode	43 = Control_backslash
-	alt	keycode	43 = Meta_backslash
-keycode  94 =
-keycode  95 =
-keycode  96 =
-keycode  97 =
-keycode  98 =
-keycode  99 =
-keycode 100 =
-keycode 101 =
-keycode 102 = BackSpace
-keycode 103 =
-keycode 104 =
-keycode 105 = KP_1
-	alt	keycode	105 = Ascii_1
-	altgr	keycode	105 = Hex_1
-keycode 106 =
-keycode 107 = KP_4
-	alt	keycode	107 = Ascii_4
-	altgr	keycode	107 = Hex_4
-keycode 108 = KP_7
-	alt	keycode	108 = Ascii_7
-	altgr	keycode	108 = Hex_7
-keycode 109 =
-keycode 110 =
-keycode 111 =
-keycode 112 = KP_0
-	alt	keycode	82 = Ascii_0
-	altgr	keycode	82 = Hex_0
-keycode 113 = KP_Period
-keycode 114 = KP_2
-	alt	keycode	114 = Ascii_2
-	altgr	keycode	114 = Hex_2
-keycode 115 = KP_5
-	alt	keycode	115 = Ascii_5
-	altgr	keycode	115 = Hex_5
-keycode 116 = KP_6
-	alt	keycode	116 = Ascii_6
-	altgr	keycode	116 = Hex_6
-keycode 117 = KP_8
-	alt	keycode	117 = Ascii_8
-	altgr	keycode	117 = Hex_8
-keycode 118 = Escape
-keycode 119 =
-keycode 120 = F11
-keycode 121 = KP_Add
-keycode 122 = KP_3
-	alt	keycode	122 = Ascii_3
-	altgr	keycode	122 = Hex_3
-keycode 123 = KP_Subtract
-keycode 124 = KP_Multiply
-keycode 125 = KP_9
-	alt	keycode	125 = Ascii_9
-	altgr	keycode	125 = Hex_9
-keycode 126 =
-# 131!!
-keycode 127 = F7	F17	Console_19
-	control	keycode	127 = F7
-	alt	keycode	127 = Console_7
-	control	alt	keycode	127 = Console_7
-
-string F1 = "\033[[A"
-string F2 = "\033[[B"
-string F3 = "\033[[C"
-string F4 = "\033[[D"
-string F5 = "\033[[E"
-string F6 = "\033[17~"
-string F7 = "\033[18~"
-string F8 = "\033[19~"
-string F9 = "\033[20~"
-string F10 = "\033[21~"
-string F11 = "\033[23~"
-string F12 = "\033[24~"
-string F13 = "\033[25~"
-string F14 = "\033[26~"
-string F15 = "\033[28~"
-string F16 = "\033[29~"
-string F17 = "\033[31~"
-string F18 = "\033[32~"
-string F19 = "\033[33~"
-string F20 = "\033[34~"
-string Find = "\033[1~"
-string Insert = "\033[2~"
-string Remove = "\033[3~"
-string Select = "\033[4~"
-string Prior = "\033[5~"
-string Next = "\033[6~"
-string Macro = "\033[M"
-string Pause = "\033[P"
-compose '`' 'A' to 'À'
-compose '`' 'a' to 'à'
-compose '\'' 'A' to 'Á'
-compose '\'' 'a' to 'á'
-compose '^' 'A' to 'Â'
-compose '^' 'a' to 'â'
-compose '~' 'A' to 'Ã'
-compose '~' 'a' to 'ã'
-compose '"' 'A' to 'Ä'
-compose '"' 'a' to 'ä'
-compose 'O' 'A' to 'Å'
-compose 'o' 'a' to 'å'
-compose '0' 'A' to 'Å'
-compose '0' 'a' to 'å'
-compose 'A' 'A' to 'Å'
-compose 'a' 'a' to 'å'
-compose 'A' 'E' to 'Æ'
-compose 'a' 'e' to 'æ'
-compose ',' 'C' to 'Ç'
-compose ',' 'c' to 'ç'
-compose '`' 'E' to 'È'
-compose '`' 'e' to 'è'
-compose '\'' 'E' to 'É'
-compose '\'' 'e' to 'é'
-compose '^' 'E' to 'Ê'
-compose '^' 'e' to 'ê'
-compose '"' 'E' to 'Ë'
-compose '"' 'e' to 'ë'
-compose '`' 'I' to 'Ì'
-compose '`' 'i' to 'ì'
-compose '\'' 'I' to 'Í'
-compose '\'' 'i' to 'í'
-compose '^' 'I' to 'Î'
-compose '^' 'i' to 'î'
-compose '"' 'I' to 'Ï'
-compose '"' 'i' to 'ï'
-compose '-' 'D' to 'Ð'
-compose '-' 'd' to 'ð'
-compose '~' 'N' to 'Ñ'
-compose '~' 'n' to 'ñ'
-compose '`' 'O' to 'Ò'
-compose '`' 'o' to 'ò'
-compose '\'' 'O' to 'Ó'
-compose '\'' 'o' to 'ó'
-compose '^' 'O' to 'Ô'
-compose '^' 'o' to 'ô'
-compose '~' 'O' to 'Õ'
-compose '~' 'o' to 'õ'
-compose '"' 'O' to 'Ö'
-compose '"' 'o' to 'ö'
-compose '/' 'O' to 'Ø'
-compose '/' 'o' to 'ø'
-compose '`' 'U' to 'Ù'
-compose '`' 'u' to 'ù'
-compose '\'' 'U' to 'Ú'
-compose '\'' 'u' to 'ú'
-compose '^' 'U' to 'Û'
-compose '^' 'u' to 'û'
-compose '"' 'U' to 'Ü'
-compose '"' 'u' to 'ü'
-compose '\'' 'Y' to 'Ý'
-compose '\'' 'y' to 'ý'
-compose 'T' 'H' to 'Þ'
-compose 't' 'h' to 'þ'
-compose 's' 's' to 'ß'
-compose '"' 'y' to 'ÿ'
-compose 's' 'z' to 'ß'
-compose 'i' 'j' to 'ÿ'
diff -Nru a/arch/parisc/kernel/lba_pci.c b/arch/parisc/kernel/lba_pci.c
--- a/arch/parisc/kernel/lba_pci.c	Mon Nov  4 14:31:02 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1346 +0,0 @@
-/*
-**  PCI Lower Bus Adapter (LBA) manager
-**
-**	(c) Copyright 1999,2000 Grant Grundler
-**	(c) Copyright 1999,2000 Hewlett-Packard Company
-**
-**	This program is free software; you can redistribute it and/or modify
-**	it under the terms of the GNU General Public License as published by
-**      the Free Software Foundation; either version 2 of the License, or
-**      (at your option) any later version.
-**
-**
-** This module primarily provides access to PCI bus (config/IOport
-** spaces) on platforms with an SBA/LBA chipset. A/B/C/J/L/N-class
-** with 4 digit model numbers - eg C3000 (and A400...sigh).
-**
-** LBA driver isn't as simple as the Dino driver because:
-**   (a) this chip has substantial bug fixes between revisions
-**       (Only one Dino bug has a software workaround :^(  )
-**   (b) has more options which we don't (yet) support (DMA hints, OLARD)
-**   (c) IRQ support lives in the I/O SAPIC driver (not with PCI driver)
-**   (d) play nicely with both PAT and "Legacy" PA-RISC firmware (PDC).
-**       (dino only deals with "Legacy" PDC)
-**
-** LBA driver passes the I/O SAPIC HPA to the I/O SAPIC driver.
-** (I/O SAPIC is integratd in the LBA chip).
-**
-** FIXME: Add support to SBA and LBA drivers for DMA hint sets
-** FIXME: Add support for PCI card hot-plug (OLARD).
-*/
-
-#include <linux/delay.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <linux/init.h>		/* for __init and __devinit */
-#include <linux/pci.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/smp_lock.h>
-
-#include <asm/byteorder.h>
-#include <asm/irq.h>		/* for struct irq_region support */
-#include <asm/pdc.h>
-#include <asm/pdcpat.h>
-#include <asm/page.h>
-#include <asm/segment.h>
-#include <asm/system.h>
-
-#include <asm/hardware.h>	/* for register_driver() stuff */
-#include <asm/iosapic.h>	/* for iosapic_register() */
-#include <asm/gsc.h>		/* gsc_read/write stuff */
-
-
-#ifndef TRUE
-#define TRUE (1 == 1)
-#define FALSE (1 == 0)
-#endif
-
-#undef DEBUG_LBA	/* general stuff */
-#undef DEBUG_LBA_PORT	/* debug I/O Port access */
-#undef DEBUG_LBA_CFG	/* debug Config Space Access (ie PCI Bus walk) */
-#undef DEBUG_LBA_PAT	/* debug PCI Resource Mgt code - PDC PAT only */
-
-#ifdef DEBUG_LBA
-#define DBG(x...)	printk(x)
-#else
-#define DBG(x...)
-#endif
-
-#ifdef DEBUG_LBA_PORT
-#define DBG_PORT(x...)	printk(x)
-#else
-#define DBG_PORT(x...)
-#endif
-
-#ifdef DEBUG_LBA_CFG
-#define DBG_CFG(x...)	printk(x)
-#else
-#define DBG_CFG(x...)
-#endif
-
-#ifdef DEBUG_LBA_PAT
-#define DBG_PAT(x...)	printk(x)
-#else
-#define DBG_PAT(x...)
-#endif
-
-/*
-** Config accessor functions only pass in the 8-bit bus number and not
-** the 8-bit "PCI Segment" number. Each LBA will be assigned a PCI bus
-** number based on what firmware wrote into the scratch register.
-**
-** The "secondary" bus number is set to this before calling
-** pci_register_ops(). If any PPB's are present, the scan will
-** discover them and update the "secondary" and "subordinate"
-** fields in the pci_bus structure.
-**
-** Changes in the configuration *may* result in a different
-** bus number for each LBA depending on what firmware does.
-*/
-
-#define MODULE_NAME "lba"
-
-static int lba_driver_callback(struct hp_device *, struct pa_iodc_driver *);
-
-
-static struct pa_iodc_driver lba_drivers_for[]= {
-
-   {HPHW_BRIDGE, 0x782, 0x0, 0xa, 0,0,
-		DRIVER_CHECK_HVERSION + 
-		DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
-                MODULE_NAME, "tbd", (void *) lba_driver_callback},
-
-   {0,0,0,0,0,0,
-   0,
-   (char *) NULL, (char *) NULL, (void *) NULL}
-};
-
-
-#define LBA_FUNC_ID	0x0000	/* function id */
-#define LBA_FCLASS	0x0008	/* function class, bist, header, rev... */
-#define LBA_CAPABLE	0x0030	/* capabilities register */
-
-#define LBA_PCI_CFG_ADDR	0x0040	/* poke CFG address here */
-#define LBA_PCI_CFG_DATA	0x0048	/* read or write data here */
-
-#define LBA_PMC_MTLT	0x0050	/* Firmware sets this - read only. */
-#define LBA_FW_SCRATCH	0x0058	/* Firmware writes the PCI bus number here. */
-#define LBA_ERROR_ADDR	0x0070	/* On error, address gets logged here */
-
-#define LBA_ARB_MASK	0x0080	/* bit 0 enable arbitration. PAT/PDC enables */
-#define LBA_ARB_PRI	0x0088	/* firmware sets this. */
-#define LBA_ARB_MODE	0x0090	/* firmware sets this. */
-#define LBA_ARB_MTLT	0x0098	/* firmware sets this. */
-
-#define LBA_MOD_ID	0x0100	/* Module ID. PDC_PAT_CELL reports 4 */
-
-#define LBA_STAT_CTL	0x0108	/* Status & Control */
-#define   HF_ENABLE	0x40	/*    enable HF mode (default is -1 mode) */
-
-#define LBA_LMMIO_BASE	0x0200	/* < 4GB I/O address range */
-#define LBA_LMMIO_MASK	0x0208
-
-#define LBA_GMMIO_BASE	0x0210	/* > 4GB I/O address range */
-#define LBA_GMMIO_MASK	0x0218
-
-#define LBA_WLMMIO_BASE	0x0220	/* All < 4GB ranges under the same *SBA* */
-#define LBA_WLMMIO_MASK	0x0228
-
-#define LBA_WGMMIO_BASE	0x0230	/* All > 4GB ranges under the same *SBA* */
-#define LBA_WGMMIO_MASK	0x0238
-
-#define LBA_IOS_BASE	0x0240	/* I/O port space for this LBA */
-#define LBA_IOS_MASK	0x0248
-
-#define LBA_ELMMIO_BASE	0x0250	/* Extra LMMIO range */
-#define LBA_ELMMIO_MASK	0x0258
-
-#define LBA_EIOS_BASE	0x0260	/* Extra I/O port space */
-#define LBA_EIOS_MASK	0x0268
-
-#define LBA_DMA_CTL	0x0278	/* firmware sets this */
-
-/* RESET: ignore DMA stuff until we can measure performance */
-#define LBA_IBASE	0x0300	/* DMA support */
-#define LBA_IMASK	0x0308
-#define LBA_HINT_CFG	0x0310
-#define LBA_HINT_BASE	0x0380	/* 14 registers at every 8 bytes. */
-
-/* ERROR regs are needed for config cycle kluges */
-#define LBA_ERROR_CONFIG 0x0680
-#define LBA_ERROR_STATUS 0x0688
-
-#define LBA_IOSAPIC_BASE	0x800 /* Offset of IRQ logic */
-
-/* non-postable I/O port space, densely packed */
-#ifdef __LP64__
-#define LBA_ASTRO_PORT_BASE	(0xfffffffffee00000UL)
-#else
-#define LBA_ASTRO_PORT_BASE	(0xfee00000UL)
-#endif
-
-
-/*
-** lba_device: Per instance Elroy data structure
-*/
-struct lba_device {
-	struct pci_hba_data hba;
-
-	spinlock_t	lba_lock;
-	void		*iosapic_obj;
-
-#ifdef __LP64__
-	unsigned long	lmmio_base;  /* PA_VIEW - fixup MEM addresses */
-	unsigned long	gmmio_base;  /* PA_VIEW - Not used (yet) */
-	unsigned long	iop_base;    /* PA_VIEW - for IO port accessor funcs */
-#endif
-
-	int		flags;       /* state/functionality enabled */
-	int		hw_rev;      /* HW revision of chip */
-};
-
-
-static u32 lba_t32;
-
-/*
-** lba "flags"
-*/
-#define LBA_FLAG_NO_DMA_DURING_CFG	0x01
-#define LBA_FLAG_SKIP_PROBE	0x10
-
-/* Tape Release 4 == hw_rev 5 */
-#define LBA_TR4PLUS(d)      ((d)->hw_rev > 0x4)
-#define LBA_DMA_DURING_CFG_DISABLED(d) ((d)->flags & LBA_FLAG_NO_DMA_DURING_CFG)
-#define LBA_SKIP_PROBE(d) ((d)->flags & LBA_FLAG_SKIP_PROBE)
-
-
-/* Looks nice and keeps the compiler happy */
-#define LBA_DEV(d) ((struct lba_device *) (d))
-
-
-/*
-** Only allow 8 subsidiary busses per LBA
-** Problem is the PCI bus numbering is globally shared.
-*/
-#define LBA_MAX_NUM_BUSES 8
-
-/************************************
- * LBA register read and write support
- *
- * BE WARNED: register writes are posted.
- *  (ie follow writes which must reach HW with a read)
- */
-#define READ_U8(addr)  gsc_readb(addr)
-#define READ_U16(addr) gsc_readw((u16 *) (addr))
-#define READ_U32(addr) gsc_readl((u32 *) (addr))
-#define WRITE_U8(value, addr) gsc_writeb(value, addr)
-#define WRITE_U16(value, addr) gsc_writew(value, (u16 *) (addr))
-#define WRITE_U32(value, addr) gsc_writel(value, (u32 *) (addr))
-
-#define READ_REG8(addr)  gsc_readb(addr)
-#define READ_REG16(addr) le16_to_cpu(gsc_readw((u16 *) (addr)))
-#define READ_REG32(addr) le32_to_cpu(gsc_readl((u32 *) (addr)))
-#define WRITE_REG8(value, addr) gsc_writeb(value, addr)
-#define WRITE_REG16(value, addr) gsc_writew(cpu_to_le16(value), (u16 *) (addr))
-#define WRITE_REG32(value, addr) gsc_writel(cpu_to_le32(value), (u32 *) (addr))
-
-
-#define LBA_CFG_TOK(bus,dfn) ((u32) ((bus)<<16 | (dfn)<<8))
-#define LBA_CFG_BUS(tok)  ((u8) ((tok)>>16))
-#define LBA_CFG_DEV(tok)  ((u8) ((tok)>>11) & 0x1f)
-#define LBA_CFG_FUNC(tok) ((u8) ((tok)>>8 ) & 0x7)
-
-
-#ifdef DEBUG_LBA
-/* Extract LBA (Rope) number from HPA */
-#define LBA_NUM(x)    ((((uintptr_t) x) >> 13) & 0xf)
-#endif /* DEBUG_LBA */
-
-#ifdef __LP64__
-/* PDC_PAT */
-static  unsigned long pdc_result[32] __attribute__ ((aligned (8))) = {0,0,0,0};
-#endif
-
-/*
-** One time initialization to let the world know the LBA was found.
-** This is the only routine which is NOT static.
-** Must be called exactly once before pci_init().
-*/
-void __init lba_init(void)
-{
-	register_driver(lba_drivers_for);
-}
-
-
-static void
-lba_dump_res(struct resource *r, int d)
-{
-	int i;
-
-	if (NULL == r)
-		return;
-
-	printk("(%p)", r->parent);
-	for (i = d; i ; --i) printk(" ");
-	printk("%p [%lx,%lx]/%x\n", r, r->start, r->end, (int) r->flags);
-	lba_dump_res(r->child, d+2);
-	lba_dump_res(r->sibling, d);
-}
-
-
-/*
-** LBA rev 2.0, 2.1, 2.2, and 3.0 bus walks require a complex
-** workaround for cfg cycles:
-**	-- preserve  LBA state
-**	-- LBA_FLAG_NO_DMA_DURING_CFG workaround
-**	-- turn on smart mode
-**	-- probe with config writes before doing config reads
-**	-- check ERROR_STATUS
-**	-- clear ERROR_STATUS
-**	-- restore LBA state
-**
-** The workaround is only used for device discovery.
-*/
-
-static int
-lba_device_present( u8 bus, u8 dfn, struct lba_device *d)
-{
-	u8 first_bus = d->hba.hba_bus->secondary;
-	u8 last_sub_bus = d->hba.hba_bus->subordinate;
-#if 0
-/* FIXME - see below in this function */
-        u8 dev = PCI_SLOT(dfn);
-        u8 func = PCI_FUNC(dfn);
-#endif
-
-	ASSERT(bus >= first_bus);
-	ASSERT(bus <= last_sub_bus);
-	ASSERT((bus - first_bus) < LBA_MAX_NUM_BUSES);
-
-	if ((bus < first_bus) ||
-	    (bus > last_sub_bus) ||
-	    ((bus - first_bus) >= LBA_MAX_NUM_BUSES))
-	{
-	    /* devices that fall into any of these cases won't get claimed */
-	    return(FALSE);
-	}
-
-#if 0
-/*
-** FIXME: Need to implement code to fill the devices bitmap based
-** on contents of the local pci_bus tree "data base".
-** pci_register_ops() walks the bus for us and builds the tree.
-** For now, always do the config cycle.
-*/
-	bus -= first_bus;
-
-	return (((d->devices[bus][dev]) >> func) & 0x1);
-#else
-	return TRUE;
-#endif
-}
-
-
-
-#define LBA_CFG_SETUP(d, tok) {				\
-    /* Save contents of error config register.  */			\
-    error_config = READ_REG32(d->hba.base_addr + LBA_ERROR_CONFIG);		\
-\
-    /* Save contents of status control register.  */			\
-    status_control = READ_REG32(d->hba.base_addr + LBA_STAT_CTL);		\
-\
-    /* For LBA rev 2.0, 2.1, 2.2, and 3.0, we must disable DMA		\
-    ** arbitration for full bus walks.					\
-    */									\
-    if (LBA_DMA_DURING_CFG_DISABLED(d)) {				\
-	/* Save contents of arb mask register. */			\
-	arb_mask = READ_REG32(d->hba.base_addr + LBA_ARB_MASK);		\
-\
-	/*								\
-	 * Turn off all device arbitration bits (i.e. everything	\
-	 * except arbitration enable bit).				\
-	 */								\
-	WRITE_REG32(0x1, d->hba.base_addr + LBA_ARB_MASK);			\
-    }									\
-\
-    /*									\
-     * Set the smart mode bit so that master aborts don't cause		\
-     * LBA to go into PCI fatal mode (required).			\
-     */									\
-    WRITE_REG32(error_config | 0x20, d->hba.base_addr + LBA_ERROR_CONFIG);	\
-}
-
-
-#define LBA_CFG_PROBE(d, tok) {				\
-    /*									\
-     * Setup Vendor ID write and read back the address register		\
-     * to make sure that LBA is the bus master.				\
-     */									\
-    WRITE_REG32(tok | PCI_VENDOR_ID, (d)->hba.base_addr + LBA_PCI_CFG_ADDR);\
-    /*									\
-     * Read address register to ensure that LBA is the bus master,	\
-     * which implies that DMA traffic has stopped when DMA arb is off.	\
-     */									\
-    lba_t32 = READ_REG32((d)->hba.base_addr + LBA_PCI_CFG_ADDR);		\
-    /*									\
-     * Generate a cfg write cycle (will have no affect on		\
-     * Vendor ID register since read-only).				\
-     */									\
-    WRITE_REG32(~0, (d)->hba.base_addr + LBA_PCI_CFG_DATA);		\
-    /*									\
-     * Make sure write has completed before proceeding further,		\
-     * i.e. before setting clear enable.				\
-     */									\
-    lba_t32 = READ_REG32((d)->hba.base_addr + LBA_PCI_CFG_ADDR);		\
-}
-
-
-/*
- * HPREVISIT:
- *   -- Can't tell if config cycle got the error.
- *
- *		OV bit is broken until rev 4.0, so can't use OV bit and
- *		LBA_ERROR_LOG_ADDR to tell if error belongs to config cycle.
- *
- *		As of rev 4.0, no longer need the error check.
- *
- *   -- Even if we could tell, we still want to return -1
- *	for **ANY** error (not just master abort).
- *
- *   -- Only clear non-fatal errors (we don't want to bring
- *	LBA out of pci-fatal mode).
- *
- *		Actually, there is still a race in which
- *		we could be clearing a fatal error.  We will
- *		live with this during our real mode bus walk
- *		until rev 4.0 (no driver activity during
- *		real mode bus walk).  The real mode bus walk
- *		has race conditions concerning the use of
- *		smart mode as well.
- */
-
-#define LBA_MASTER_ABORT_ERROR 0xc
-#define LBA_FATAL_ERROR 0x10
-
-#define LBA_CFG_MASTER_ABORT_CHECK(d, base, tok, error) {		\
-    u32 error_status = 0;						\
-    /*									\
-     * Set clear enable (CE) bit. Unset by HW when new			\
-     * errors are logged -- LBA HW ERS section 14.3.3).		\
-     */									\
-    WRITE_REG32(status_control | 0x20, base + LBA_STAT_CTL);	\
-    error_status = READ_REG32(base + LBA_ERROR_STATUS);		\
-    if ((error_status & 0x1f) != 0) {					\
-	/*								\
-	 * Fail the config read request.				\
-	 */								\
-	error = 1;							\
-	if ((error_status & LBA_FATAL_ERROR) == 0) {			\
-	    /*								\
-	     * Clear error status (if fatal bit not set) by setting	\
-	     * clear error log bit (CL).				\
-	     */								\
-	    WRITE_REG32(status_control | 0x10, base + LBA_STAT_CTL);	\
-	}								\
-    }									\
-}
-
-#define LBA_CFG_TR4_ADDR_SETUP(d, addr) \
-    WRITE_REG32(((addr) & ~3), (d)->hba.base_addr + LBA_PCI_CFG_ADDR)
-
-#define LBA_CFG_ADDR_SETUP(d, addr) {				\
-    WRITE_REG32(((addr) & ~3), (d)->hba.base_addr + LBA_PCI_CFG_ADDR);	\
-    /*									\
-     * HPREVISIT:							\
-     *       --	Potentially could skip this once DMA bug fixed.		\
-     *									\
-     * Read address register to ensure that LBA is the bus master,	\
-     * which implies that DMA traffic has stopped when DMA arb is off.	\
-     */									\
-    lba_t32 = READ_REG32((d)->hba.base_addr + LBA_PCI_CFG_ADDR);		\
-}
-
-
-#define LBA_CFG_RESTORE(d, base) {					\
-    /*									\
-     * Restore status control register (turn off clear enable).		\
-     */									\
-    WRITE_REG32(status_control, base + LBA_STAT_CTL);			\
-    /*									\
-     * Restore error config register (turn off smart mode).		\
-     */									\
-    WRITE_REG32(error_config, base + LBA_ERROR_CONFIG);			\
-    if (LBA_DMA_DURING_CFG_DISABLED(d)) {				\
-	/*								\
-	 * Restore arb mask register (reenables DMA arbitration).	\
-	 */								\
-	WRITE_REG32(arb_mask, base + LBA_ARB_MASK);			\
-    }									\
-}
-
-
-
-static unsigned int
-lba_rd_cfg( struct lba_device *d, u32 tok, u8 reg, u32 size)
-{
-	u32 data = ~0;
-	int error = 0;
-	u32 arb_mask = 0;	/* used by LBA_CFG_SETUP/RESTORE */
-	u32 error_config = 0;	/* used by LBA_CFG_SETUP/RESTORE */
-	u32 status_control = 0;	/* used by LBA_CFG_SETUP/RESTORE */
-
-	ASSERT((size == sizeof(u8)) ||
-		(size == sizeof(u16)) ||
-		(size == sizeof(u32)));
-
-	if ((size != sizeof(u8)) &&
-		(size != sizeof(u16)) &&
-		(size != sizeof(u32))) {
-		return(data);
-	}
-
-	LBA_CFG_SETUP(d, tok);
-	LBA_CFG_PROBE(d, tok);
-	LBA_CFG_MASTER_ABORT_CHECK(d, d->hba.base_addr, tok, error);
-	if (!error) {
-		LBA_CFG_ADDR_SETUP(d, tok | reg);
-		switch (size) {
-		case sizeof(u8):
-			data = (u32) READ_REG8(d->hba.base_addr + LBA_PCI_CFG_DATA + (reg & 3));
-			break;
-		case sizeof(u16):
-			data = (u32) READ_REG16(d->hba.base_addr + LBA_PCI_CFG_DATA + (reg & 2));
-			break;
-		case sizeof(u32):
-			data = READ_REG32(d->hba.base_addr + LBA_PCI_CFG_DATA);
-			break;
-		default:
-			break; /* leave data as -1 */
-		}
-	}
-	LBA_CFG_RESTORE(d, d->hba.base_addr);
-	return(data);
-}
-
-
-
-#define LBA_CFG_RD(size, mask) \
-static int lba_cfg_read##size (struct pci_dev *dev, int pos, u##size *data) \
-{ \
-	struct lba_device *d = LBA_DEV(dev->bus->sysdata); \
-	u32 local_bus = (dev->bus->parent == NULL) ? 0 : dev->bus->secondary; \
-	u32 tok = LBA_CFG_TOK(local_bus,dev->devfn); \
- \
-	if ((!LBA_TR4PLUS(d)) && (!LBA_SKIP_PROBE(d))) { \
-		/* original - Generate config cycle on broken elroy \
-		  with risk we will miss PCI bus errors. */ \
-		*data = (u##size) lba_rd_cfg(d, tok, pos, sizeof(u##size)); \
-		DBG_CFG(KERN_DEBUG "%s(%s+%2x) -> 0x%x (a)\n", __FUNCTION__, dev->slot_name, pos, *data); \
-		return(*data == (u##size) -1); \
-	} \
- \
-	if (LBA_SKIP_PROBE(d) && (!lba_device_present(dev->bus->secondary, dev->devfn, d))) \
-	{ \
-		DBG_CFG(KERN_DEBUG "%s(%s+%2x) -> -1 (b)\n", __FUNCTION__, dev->slot_name, pos, *data); \
-		/* either don't want to look or know device isn't present. */ \
-		*data = (u##size) -1; \
-		return(0); \
-	} \
- \
-	/* Basic Algorithm \
-	** Should only get here on fully working LBA rev. \
-	** This is how simple the code should have been. \
-	*/ \
-	LBA_CFG_TR4_ADDR_SETUP(d, tok | pos); \
-	*data = READ_REG##size(d->hba.base_addr + LBA_PCI_CFG_DATA + (pos & mask));\
-	DBG_CFG(KERN_DEBUG "%s(%s+%2x) -> 0x%x (c)\n", __FUNCTION__, dev->slot_name, pos, *data);\
-	return(*data == (u##size) -1); \
-}
-
-LBA_CFG_RD( 8, 3) 
-LBA_CFG_RD(16, 2) 
-LBA_CFG_RD(32, 0) 
-
-
-
-static void
-lba_wr_cfg( struct lba_device *d, u32 tok, u8 reg, u32 data, u32 size)
-{
-	int error = 0;
-	u32 arb_mask = 0;
-	u32 error_config = 0;
-	u32 status_control = 0;
-
-	ASSERT((size == sizeof(u8)) ||
-		(size == sizeof(u16)) ||
-		(size == sizeof(u32)));
-
-	if ((size != sizeof(u8)) &&
-		(size != sizeof(u16)) &&
-		(size != sizeof(u32))) {
-			return;
-	}
-
-	LBA_CFG_SETUP(d, tok);
-	LBA_CFG_ADDR_SETUP(d, tok | reg);
-	switch (size) {
-	case sizeof(u8):
-		WRITE_REG8((u8) data, d->hba.base_addr + LBA_PCI_CFG_DATA + (reg&3));
-		break;
-	case sizeof(u16):
-		WRITE_REG16((u8) data, d->hba.base_addr + LBA_PCI_CFG_DATA +(reg&2));
-		break;
-	case sizeof(u32):
-		WRITE_REG32(data, d->hba.base_addr + LBA_PCI_CFG_DATA);
-		break;
-	default:
-		break;
-	}
-	LBA_CFG_MASTER_ABORT_CHECK(d, d->hba.base_addr, tok, error);
-	LBA_CFG_RESTORE(d, d->hba.base_addr);
-}
-
-
-/*
- * LBA 4.0 config write code implements non-postable semantics
- * by doing a read of CONFIG ADDR after the write.
- */
-
-#define LBA_CFG_WR(size, mask) \
-static int lba_cfg_write##size (struct pci_dev *dev, int pos, u##size data) \
-{ \
-	struct lba_device *d = LBA_DEV(dev->bus->sysdata); \
-	u32 local_bus = (dev->bus->parent == NULL) ? 0 : dev->bus->secondary; \
-	u32 tok = LBA_CFG_TOK(local_bus,dev->devfn); \
- \
- 	ASSERT((tok & 0xff) == 0); \
-	ASSERT(pos < 0x100); \
- \
-	if ((!LBA_TR4PLUS(d)) && (!LBA_SKIP_PROBE(d))) { \
-		/* Original Workaround */ \
-		lba_wr_cfg(d, tok, pos, (u32) data, sizeof(u##size)); \
-		DBG_CFG(KERN_DEBUG "%s(%s+%2x) = 0x%x (a)\n", __FUNCTION__, dev->slot_name, pos, data); \
-		return 0; \
-	} \
- \
-	if (LBA_SKIP_PROBE(d) && (!lba_device_present(dev->bus->secondary, dev->devfn, d))) { \
-		DBG_CFG(KERN_DEBUG "%s(%s+%2x) = 0x%x (b)\n", __FUNCTION__, dev->slot_name, pos, data); \
-		return 1; /* New Workaround */ \
-	} \
- \
-	DBG_CFG(KERN_DEBUG "%s(%s+%2x) = 0x%x (c)\n", __FUNCTION__, dev->slot_name, pos, data); \
-	/* Basic Algorithm */ \
-	LBA_CFG_TR4_ADDR_SETUP(d, tok | pos); \
-	WRITE_REG##size(data, d->hba.base_addr + LBA_PCI_CFG_DATA + (pos & mask)); \
-	lba_t32 = READ_REG32(d->hba.base_addr + LBA_PCI_CFG_ADDR); \
-	return 0; \
-}
-
-
-LBA_CFG_WR( 8, 3) 
-LBA_CFG_WR(16, 2) 
-LBA_CFG_WR(32, 0) 
-
-static struct pci_ops lba_cfg_ops = {
-        lba_cfg_read8, lba_cfg_read16, lba_cfg_read32,
-	lba_cfg_write8, lba_cfg_write16, lba_cfg_write32
-
-};
-
-
-
-static void
-lba_bios_init(void)
-{
-	DBG(KERN_DEBUG MODULE_NAME ": lba_bios_init\n");
-}
-
-
-#ifdef __LP64__
-
-/*
-** Determine if a device is already configured.
-** If so, reserve it resources.
-**
-** Read PCI cfg command register and see if I/O or MMIO is enabled.
-** PAT has to enable the devices it's using.
-**
-** Note: resources are fixed up before we try to claim them.
-*/
-static void
-lba_claim_dev_resources(struct pci_dev *dev)
-{
-	u16 cmd;
-	int i, srch_flags;
-
-	(void) lba_cfg_read16(dev, PCI_COMMAND, &cmd);
-
-	srch_flags  = (cmd & PCI_COMMAND_IO) ? IORESOURCE_IO : 0;
-	if (cmd & PCI_COMMAND_MEMORY)
-		srch_flags |= IORESOURCE_MEM;
-
-	if (!srch_flags)
-		return;
-
-	for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
-		if (dev->resource[i].flags & srch_flags) {
-			pci_claim_resource(dev, i);
-			DBG("   claimed %s %d [%lx,%lx]/%x\n",
-				dev->slot_name, i,
-				dev->resource[i].start,
-				dev->resource[i].end,
-				(int) dev->resource[i].flags
-				);
-		}
-	}
-}
-#endif
-
-
-/*
-** The algorithm is generic code.
-** But it needs to access local data structures to get the IRQ base.
-** Could make this a "pci_fixup_irq(bus, region)" but not sure
-** it's worth it.
-**
-** Called by do_pci_scan_bus() immediately after each PCI bus is walked.
-** Resources aren't allocated until recursive buswalk below HBA is completed.
-*/
-static void
-lba_fixup_bus(struct pci_bus *bus)
-{
-	struct list_head *ln;
-        struct pci_dev *dev;
-	u16 fbb_enable = PCI_STATUS_FAST_BACK;
-	u16 status;
-	struct lba_device *ldev = LBA_DEV(bus->sysdata);
-#ifdef __LP64__
-	int i;
-#endif
-	DBG("lba_fixup_bus(0x%p) bus %d sysdata 0x%p\n",
-				bus, bus->secondary, bus->sysdata);
-
-	/*
-	** Properly Setup MMIO resources for this bus.
-	** pci_alloc_primary_bus() mangles this.
-	*/
-	if (NULL == bus->self) {
-		int err;
-
-		DBG("lba_fixup_bus() %s [%lx/%lx]/%x\n",
-			ldev->hba.io_space.name,
-			ldev->hba.io_space.start,
-			ldev->hba.io_space.end,
-			(int) ldev->hba.io_space.flags);
-		DBG("lba_fixup_bus() %s [%lx/%lx]/%x\n",
-			ldev->hba.mem_space.name,
-			ldev->hba.mem_space.start,
-			ldev->hba.mem_space.end,
-			(int) ldev->hba.mem_space.flags);
-
-		err = request_resource(&ioport_resource, &(ldev->hba.io_space));
-		if (err < 0) {
-			BUG();
-			lba_dump_res(&ioport_resource, 2);
-		}
-		err = request_resource(&iomem_resource, &(ldev->hba.mem_space));
-		if (err < 0) {
-			BUG();
-			lba_dump_res(&iomem_resource, 2);
-		}
-
-		bus->resource[0] = &(ldev->hba.io_space);
-		bus->resource[1] = &(ldev->hba.mem_space);
-	}
-
-	list_for_each(ln, &bus->devices) {
-
-		dev = pci_dev_b(ln);
-
-#ifdef __LP64__
-		/*
-		** 0-5 are the "standard PCI regions"
-		** (see comments near PCI_NUM_RESOURCES in include/linux/pci.h)
-		*/
-		for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
-			struct resource *res = &(dev->resource[i]);
-
-			if (res->flags & IORESOURCE_MEM) {
-				/* "Globalize" PCI address */
-				res->start |= ldev->lmmio_base;
-				res->end   |= ldev->lmmio_base;
-			}
-		}
-#endif
-
-		/*
-		** If one device does not support FBB transfers,
-		** No one on the bus can be allowed to use them.
-		*/
-		(void) lba_cfg_read16(dev, PCI_STATUS, &status);
-		fbb_enable &= status;
-
-#ifdef __LP64__
-		if (pdc_pat) {
-			/* Claim resources for PDC's devices */
-			lba_claim_dev_resources(dev);
-		}
-#endif	/* __LP64__ */
-
-                /*
-		** P2PB's have no IRQs. ignore them.
-		*/
-		if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)
-			continue;
-
-		/* Adjust INTERRUPT_LINE for this dev */
-		iosapic_fixup_irq(LBA_DEV(bus->sysdata)->iosapic_obj, dev);
-	}
-
-#if 0
-/* FIXME/REVISIT - finish figuring out to set FBB on both
-** pbus_set_ranges() clobbers PCI_BRIDGE_CONTROL.
-** Can't fixup here anyway....garr...
-*/
-	if (fbb_enable) {
-		if (bus->self) {
-			u8 control;
-			/* enable on PPB */
-			(void) lba_cfg_read8(bus->self, PCI_BRIDGE_CONTROL, &control);
-			(void) lba_cfg_write8(bus->self, PCI_BRIDGE_CONTROL, control | PCI_STATUS_FAST_BACK);
-
-		} else {
-			/* enable on LBA */
-		}
-		fbb_enable = PCI_COMMAND_FAST_BACK;
-	}
-
-	/* Lastly enable FBB/PERR/SERR on all devices too */
-	list_for_each(ln, &bus->devices) {
-		(void) lba_cfg_read16(dev, PCI_COMMAND, &status);
-		status |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR | fbb_enable;
-		(void) lba_cfg_write16(dev, PCI_COMMAND, status);
-	}
-#endif
-}
-
-
-struct pci_bios_ops lba_bios_ops = {
-	lba_bios_init,
-	lba_fixup_bus  /* void lba_fixup_bus(struct pci_bus *bus) */
-};
-
-
-
-
-/*******************************************************
-**
-** LBA Sprockets "I/O Port" Space Accessor Functions
-**
-** This set of accessor functions is intended for use with
-** "legacy firmware" (ie Sprockets on Allegro/Forte boxes).
-**
-** Many PCI devices don't require use of I/O port space (eg Tulip,
-** NCR720) since they export the same registers to both MMIO and
-** I/O port space. In general I/O port space is slower than
-** MMIO since drivers are designed so PIO writes can be posted.
-**
-********************************************************/
-
-#define LBA_PORT_IN(size, mask) \
-static u##size lba_astro_in##size (struct pci_hba_data *d, u16 addr) \
-{ \
-	u##size t; \
-	ASSERT(bus != NULL); \
-	DBG_PORT(KERN_DEBUG "%s(0x%p, 0x%x) ->", __FUNCTION__, bus, addr); \
-	t = READ_REG##size(LBA_ASTRO_PORT_BASE + addr); \
-	DBG_PORT(" 0x%x\n", t); \
-	return (t); \
-}
-
-LBA_PORT_IN( 8, 3)
-LBA_PORT_IN(16, 2)
-LBA_PORT_IN(32, 0)
-
-
-
-/*
-** BUG X4107:  Ordering broken - DMA RD return can bypass PIO WR
-**
-** Fixed in Elroy 2.2. The READ_U32(..., LBA_FUNC_ID) below is
-** guarantee non-postable completion semantics - not avoid X4107.
-** The READ_U32 only guarantees the write data gets to elroy but
-** out to the PCI bus. We can't read stuff from I/O port space
-** since we don't know what has side-effects. Attempting to read
-** from configuration space would be suicidal given the number of
-** bugs in that elroy functionality.
-**
-**      Description:
-**          DMA read results can improperly pass PIO writes (X4107).  The
-**          result of this bug is that if a processor modifies a location in
-**          memory after having issued PIO writes, the PIO writes are not
-**          guaranteed to be completed before a PCI device is allowed to see
-**          the modified data in a DMA read.
-**
-**          Note that IKE bug X3719 in TR1 IKEs will result in the same
-**          symptom.
-**
-**      Workaround:
-**          The workaround for this bug is to always follow a PIO write with
-**          a PIO read to the same bus before starting DMA on that PCI bus.
-**
-*/
-#define LBA_PORT_OUT(size, mask) \
-static void lba_astro_out##size (struct pci_hba_data *d, u16 addr, u##size val) \
-{ \
-	ASSERT(bus != NULL); \
-	DBG_PORT(KERN_DEBUG "%s(0x%p, 0x%x, 0x%x)\n", __FUNCTION__, d, addr, val); \
-	WRITE_REG##size(val, LBA_ASTRO_PORT_BASE + addr); \
-	if (LBA_DEV(d)->hw_rev < 3) \
-		lba_t32 = READ_U32(d->base_addr + LBA_FUNC_ID); \
-}
-
-LBA_PORT_OUT( 8, 3)
-LBA_PORT_OUT(16, 2)
-LBA_PORT_OUT(32, 0)
-
-
-static struct pci_port_ops lba_astro_port_ops = {
-	lba_astro_in8, lba_astro_in16, lba_astro_in32,
-	lba_astro_out8, lba_astro_out16, lba_astro_out32
-};
-
-
-#ifdef __LP64__
-
-#define PIOP_TO_GMMIO(lba, addr) \
-	((lba)->iop_base + (((addr)&0xFFFC)<<10) + ((addr)&3))
-
-/*******************************************************
-**
-** LBA PAT "I/O Port" Space Accessor Functions
-**
-** This set of accessor functions is intended for use with
-** "PAT PDC" firmware (ie Prelude/Rhapsody/Piranha boxes).
-**
-** This uses the PIOP space located in the first 64MB of GMMIO.
-** Each rope gets a full 64*KB* (ie 4 bytes per page) this way.
-** bits 1:0 stay the same.  bits 15:2 become 25:12.
-** Then add the base and we can generate an I/O Port cycle.
-********************************************************/
-#undef LBA_PORT_IN
-#define LBA_PORT_IN(size, mask) \
-static u##size lba_pat_in##size (struct pci_hba_data *l, u16 addr) \
-{ \
-	u##size t; \
-	ASSERT(bus != NULL); \
-	DBG_PORT(KERN_DEBUG "%s(0x%p, 0x%x) ->", __FUNCTION__, l, addr); \
-	t = READ_REG##size(PIOP_TO_GMMIO(LBA_DEV(l), addr)); \
-	DBG_PORT(" 0x%x\n", t); \
-	return (t); \
-}
-
-LBA_PORT_IN( 8, 3)
-LBA_PORT_IN(16, 2)
-LBA_PORT_IN(32, 0)
-
-
-#undef LBA_PORT_OUT
-#define LBA_PORT_OUT(size, mask) \
-static void lba_pat_out##size (struct pci_hba_data *l, u16 addr, u##size val) \
-{ \
-	void *where = (void *) PIOP_TO_GMMIO(LBA_DEV(l), addr); \
-	ASSERT(bus != NULL); \
-	DBG_PORT(KERN_DEBUG "%s(0x%p, 0x%x, 0x%x)\n", __FUNCTION__, l, addr, val); \
-	WRITE_REG##size(val, where); \
-	/* flush the I/O down to the elroy at least */ \
-	lba_t32 = READ_U32(l->base_addr + LBA_FUNC_ID); \
-}
-
-LBA_PORT_OUT( 8, 3)
-LBA_PORT_OUT(16, 2)
-LBA_PORT_OUT(32, 0)
-
-
-static struct pci_port_ops lba_pat_port_ops = {
-	lba_pat_in8, lba_pat_in16, lba_pat_in32,
-	lba_pat_out8, lba_pat_out16, lba_pat_out32
-};
-
-
-
-/*
-** make range information from PDC available to PCI subsystem.
-** We make the PDC call here in order to get the PCI bus range
-** numbers. The rest will get forwarded in pcibios_fixup_bus().
-** We don't have a struct pci_bus assigned to us yet.
-*/
-static void
-lba_pat_resources( struct hp_device *d, struct lba_device *lba_dev)
-{
-	pdc_pat_cell_mod_maddr_block_t pa_pdc_cell;	/* PA_VIEW */
-#ifdef DONT_NEED_THIS_FOR_ASTRO
-	pdc_pat_cell_mod_maddr_block_t io_pdc_cell;	/* IO_VIEW */
-	long io_count;
-#endif
-	long status;	/* PDC return status */
-	long pa_count;
-	int i;
-
-	/* return cell module (IO view) */
-	status = pdc_pat_cell_module(& pdc_result, d->pcell_loc, d->mod_index,
-				PA_VIEW, & pa_pdc_cell);
-	pa_count = pa_pdc_cell.mod[1];
-
-#ifdef DONT_NEED_THIS_FOR_ASTRO
-	status |= pdc_pat_cell_module(& pdc_result, d->pcell_loc, d->mod_index,
-				IO_VIEW, & io_pdc_cell);
-	io_count = io_pdc_cell.mod[1];
-#endif
-
-	/* We've already done this once for device discovery...*/
-	if (status != PDC_RET_OK) {
-		panic("pdc_pat_cell_module() call failed for LBA!\n");
-	}
-
-	if (PAT_GET_ENTITY(pa_pdc_cell.mod_info) != PAT_ENTITY_LBA) {
-		panic("pdc_pat_cell_module() entity returned != PAT_ENTITY_LBA!\n");
-	}
-
-	/*
-	** Inspect the resources PAT tells us about
-	*/
-	for (i = 0; i < pa_count; i++) {
-		struct {
-			unsigned long type;
-			unsigned long start;
-			unsigned long end;	/* aka finish */
-		} *p;
-		struct resource *r;
-
-		p = (void *) &(pa_pdc_cell.mod[2+i*3]);
-
-		/* Convert the PAT range data to PCI "struct resource" */
-		switch(p->type & 0xff) {
-		case PAT_PBNUM:
-			lba_dev->hba.bus_num.start = p->start;
-			lba_dev->hba.bus_num.end   = p->end;
-			break;
-		case PAT_LMMIO:
-			/* used to fix up pre-initialized MEM BARs */
-			lba_dev->lmmio_base = p->start;
-
-			r = &(lba_dev->hba.mem_space);
-			r->name   = "LBA LMMIO";
-			r->start  = p->start;
-			r->end    = p->end;
-			r->flags  = IORESOURCE_MEM;
-			r->parent = r->sibling = r->child = NULL;
-			break;
-		case PAT_GMMIO:
-			printk(KERN_WARNING MODULE_NAME
-				" range[%d] : ignoring GMMIO (0x%lx)\n",
-				i, p->start);
-			lba_dev->gmmio_base = p->start;
-			break;
-		case PAT_NPIOP:
-			printk(KERN_WARNING MODULE_NAME
-				" range[%d] : ignoring NPIOP (0x%lx)\n",
-				i, p->start);
-			break;
-		case PAT_PIOP:
-			/*
-			** Postable I/O port space is per PCI host adapter.
-			*/
-
-			/* save base of 64MB PIOP region */
-			lba_dev->iop_base = p->start;
-
-			r = &(lba_dev->hba.io_space);
-			r->name   = "LBA I/O Port";
-			r->start = lba_dev->hba.hba_num << 16;
-			r->end   = r->start + 0xffffUL;
-			r->flags  = IORESOURCE_IO;
-			r->parent = r->sibling = r->child = NULL;
-			break;
-		default:
-			printk(KERN_WARNING MODULE_NAME
-				" range[%d] : unknown pat range type (0x%lx)\n",
-				i, p->type & 0xff);
-			break;
-		}
-	}
-}
-#endif	/* __LP64__ */
-
-
-static void
-lba_legacy_resources( struct hp_device *d, struct lba_device *lba_dev)
-{
-	int lba_num;
-	struct resource *r;
-#ifdef __LP64__
-	/*
-	** Used to sign extend instead BAR values are only 32-bit.
-	** 64-bit BARs have the upper 32-bit's zero'd by firmware.
-	** "Sprockets" PDC initializes for 32-bit OS.
-	*/
-	lba_dev->lmmio_base = 0xffffffff00000000UL;
-#endif
-
-	/*
-	** With "legacy" firmware, the lowest byte of FW_SCRATCH
-	** represents bus->secondary and the second byte represents
-	** bus->subsidiary (i.e. highest PPB programmed by firmware).
-	** PCI bus walk *should* end up with the same result.
-	** FIXME: But we don't have sanity checks in PCI or LBA.
-	*/
-	lba_num = READ_REG32(d->hpa + LBA_FW_SCRATCH);
-	r = &(lba_dev->hba.bus_num);
-	r->name = "LBA PCI Busses";
-	r->start = lba_num & 0xff;
-	r->end = (lba_num>>8) & 0xff;
-
-	/* Set up local PCI Bus resources - we don't really need
-	** them for Legacy boxes but it's nice to see in /proc.
-	*/
-	r = &(lba_dev->hba.mem_space);
-	r->name  = "LBA PCI LMMIO";
-	r->flags = IORESOURCE_MEM;
-	r->start = READ_REG32(d->hpa + LBA_LMMIO_BASE);
-	r->end   = r->start + ~ (READ_REG32(d->hpa + LBA_LMMIO_MASK));
-
-	r = &(lba_dev->hba.io_space);
-	r->name  = "LBA PCI I/O Ports";
-	r->flags = IORESOURCE_IO;
-	r->start = READ_REG32(d->hpa + LBA_IOS_BASE);
-	r->end   = r->start + (READ_REG32(d->hpa + LBA_IOS_MASK) ^ 0xffff);
-
-	lba_num = lba_dev->hba.hba_num << 16;
-	r->start |= lba_num;
-	r->end   |= lba_num;
-}
-
-
-/**************************************************************************
-**
-**   LBA initialization code (HW and SW)
-**
-**   o identify LBA chip itself
-**   o initialize LBA chip modes (HardFail)
-**   o FIXME: initialize DMA hints for reasonable defaults
-**   o enable configuration functions
-**   o call pci_register_ops() to discover devs (fixup/fixup_bus get invoked)
-**
-**************************************************************************/
-
-static void
-lba_hw_init(struct lba_device *d)
-{
-	u32 stat;
-
-	/* Set HF mode as the default (vs. -1 mode). */
-        stat = READ_REG32(d->hba.base_addr + LBA_STAT_CTL);
-	WRITE_REG32(stat | HF_ENABLE, d->hba.base_addr + LBA_STAT_CTL);
-
-	/*
-	** FIXME: Hint registers are programmed with default hint
-	** values by firmware. Hints should be sane even if we
-	** can't reprogram them the way drivers want.
-	*/
-}
-
-
-
-static void
-lba_common_init(struct lba_device *lba_dev)
-{
-	pci_bios = &lba_bios_ops;
-	pcibios_register_hba((struct pci_hba_data *)lba_dev);
-	lba_dev->lba_lock = SPIN_LOCK_UNLOCKED;	
-
-	/*
-	** Set flags which depend on hw_rev
-	*/
-	if (!LBA_TR4PLUS(lba_dev)) {
-		lba_dev->flags |= LBA_FLAG_NO_DMA_DURING_CFG;
-	}
-}
-
-
-
-/*
-** Determine if lba 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 __init int
-lba_driver_callback(struct hp_device *d, struct pa_iodc_driver *dri)
-{
-	struct lba_device *lba_dev;
-	struct pci_bus *lba_bus;
-	u32 func_class;
-	void *tmp_obj;
-
-	/* from drivers/pci/setup-bus.c */
-	extern void __init pbus_set_ranges(struct pci_bus *, struct pbus_set_ranges_data *);
-
-	/* Read HW Rev First */
-	func_class = READ_REG32(d->hpa + LBA_FCLASS);
-	func_class &= 0xf;
-
-	switch (func_class) {
-	case 0:	dri->version = "TR1.0"; break;
-	case 1:	dri->version = "TR2.0"; break;
-	case 2:	dri->version = "TR2.1"; break;
-	case 3:	dri->version = "TR2.2"; break;
-	case 4:	dri->version = "TR3.0"; break;
-	case 5:	dri->version = "TR4.0"; break;
-	default: dri->version = "TR4+";
-	}
-
-	printk("%s version %s (0x%x) found at 0x%p\n", dri->name, dri->version, func_class & 0xf, d->hpa);
-
-	/* Just in case we find some prototypes... */
-	if (func_class < 2) {
-		printk(KERN_WARNING "Can't support LBA older than TR2.1 "
-			"- continuing under adversity.\n");
-	}
-
-	/*
-	** Tell I/O SAPIC driver we have a IRQ handler/region.
-	*/
-	tmp_obj = iosapic_register(d->hpa+LBA_IOSAPIC_BASE);
-	if (NULL == tmp_obj) {
-		/* iosapic may have failed. But more likely the
-		** slot isn't occupied and thus has no IRT entries.
-		** iosapic_register looks for this iosapic in the IRT
-		** before bothering to allocating data structures
-		** we don't need.
-		*/
-		DBG(KERN_WARNING MODULE_NAME ": iosapic_register says not used\n");
-		return (1);
-	}
-
-	lba_dev = kmalloc(sizeof(struct lba_device), GFP_KERNEL);
-	if (NULL == lba_dev)
-	{
-		printk("lba_init_chip - couldn't alloc lba_device\n");
-		return(1);
-	}
-
-	memset(lba_dev, 0, sizeof(struct lba_device));
-
-
-	/* ---------- First : initialize data we already have --------- */
-
-	/*
-	** Need hw_rev to adjust configuration space behavior.
-	** LBA_TR4PLUS macro uses hw_rev field.
-	*/
-	lba_dev->hw_rev = func_class;
-
-	lba_dev->hba.base_addr = d->hpa;  /* faster access */
-	lba_dev->iosapic_obj = tmp_obj;  /* save interrupt handle */
-
-	/* ------------ Second : initialize common stuff ---------- */
-	lba_common_init(lba_dev);
-	lba_hw_init(lba_dev);
-
-	/* ---------- Third : setup I/O Port and MMIO resources  --------- */
-#ifdef __LP64__
-
-	if (pdc_pat) {
-		/* PDC PAT firmware uses PIOP region of GMMIO space. */
-		pci_port = &lba_pat_port_ops;
-
-		/* Go ask PDC PAT what resources this LBA has */
-		lba_pat_resources(d, lba_dev);
-
-	} else {
-#endif
-		/* Sprockets PDC uses NPIOP region */
-		pci_port = &lba_astro_port_ops;
-
-		/* Poke the chip a bit for /proc output */
-		lba_legacy_resources(d, lba_dev);
-#ifdef __LP64__
-	}
-#endif
-
-	/* 
-	** Tell PCI support another PCI bus was found.
-	** Walks PCI bus for us too.
-	*/
-	lba_bus = lba_dev->hba.hba_bus =
-		pci_scan_bus( lba_dev->hba.bus_num.start, &lba_cfg_ops, (void *) lba_dev);
-
-#ifdef __LP64__
-	if (pdc_pat) {
-
-		/* determine window sizes needed by PCI-PCI bridges */
-		DBG_PAT("LBA pcibios_size_bridge()\n");
-		pcibios_size_bridge(lba_bus, NULL);
-
-		/* assign resources to un-initialized devices */
-		DBG_PAT("LBA pcibios_assign_unassigned_resources()\n");
-		pcibios_assign_unassigned_resources(lba_bus);
-
-#ifdef DEBUG_LBA_PAT
-		DBG_PAT("\nLBA PIOP resource tree\n");
-		lba_dump_res(&lba_dev->hba.io_space, 2);
-		DBG_PAT("\nLBA LMMIO resource tree\n");
-		lba_dump_res(&lba_dev->hba.mem_space, 2);
-#endif
-
-		/* program *all* PCI-PCI bridge range registers */
-		DBG_PAT("LBA pbus_set_ranges()\n");
-		pbus_set_ranges(lba_bus, NULL);
-	}
-#endif /* __LP64__ */
-
-	/*
-	** Once PCI register ops has walked the bus, access to config
-	** space is restricted. Avoids master aborts on config cycles.
-	** Early LBA revs go fatal on *any* master abort.
-	*/
-	if (!LBA_TR4PLUS(lba_dev)) {
-		lba_dev->flags |= LBA_FLAG_SKIP_PROBE;
-	}
-
-	/* Whew! Finally done! Tell services we got this one covered. */
-	return 0;
-}
-
-
-/*
-** Initialize the IBASE/IMASK registers for LBA (Elroy).
-** Only called from sba_iommu.c initialization sequence.
-*/
-void lba_init_iregs(void *sba_hpa, u32 ibase, u32 imask)
-{
-	extern struct pci_hba_data *hba_list;	/* arch/parisc/kernel/pci.c */
-	struct pci_hba_data *lba;
-
-	imask <<= 2;	/* adjust for hints - 2 more bits */
-
-	ASSERT((ibase & 0x003fffff) == 0);
-	ASSERT((imask & 0x003fffff) == 0);
-	
-	/* FIXME: sba_hpa is intended to search some table to
-	**      determine which LBA's belong to the caller's SBA.
-	** IS_ASTRO: just assume only one SBA for now.
-	*/
-	ASSERT(NULL != hba_list);
-	DBG(KERN_DEBUG "%s() ibase 0x%x imask 0x%x\n", __FUNCTION__, ibase, imask);
-
-	for (lba = hba_list; NULL != lba; lba = lba->next) {
-		DBG(KERN_DEBUG "%s() base_addr %p\n", __FUNCTION__, lba->base_addr);
-		WRITE_REG32( imask, lba->base_addr + LBA_IMASK);
-		WRITE_REG32( ibase, lba->base_addr + LBA_IBASE);
-	}
-	DBG(KERN_DEBUG "%s() done\n", __FUNCTION__);
-}
-
diff -Nru a/arch/parisc/kernel/led.c b/arch/parisc/kernel/led.c
--- a/arch/parisc/kernel/led.c	Mon Nov  4 14:31:01 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,451 +0,0 @@
-/*
- *    Chassis LCD/LED driver for HP-PARISC workstations
- *
- *      (c) Copyright 2000 Red Hat Software
- *      (c) Copyright 2000 Helge Deller <hdeller@redhat.com>
- *
- *      This program is free software; you can redistribute it and/or modify
- *      it under the terms of the GNU General Public License as published by
- *      the Free Software Foundation; either version 2 of the License, or
- *      (at your option) any later version.
- *
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/kernel_stat.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/bitops.h>
-#include <asm/io.h>
-#include <asm/gsc.h>
-#include <asm/processor.h>
-#include <asm/hardware.h>
-#include <asm/param.h>		/* HZ */
-#include <asm/led.h>
-
-
-/* define to disable all LED functions */
-#undef  DISABLE_LEDS
-
-
-#define CPU_HVERSION ((boot_cpu_data.hversion >> 4) & 0x0FFF)
-
-
-struct lcd_block {
-	unsigned char command;	/* stores the command byte      */
-	unsigned char on;	/* value for turning LED on     */
-	unsigned char off;	/* value for turning LED off    */
-};
-
-/* Structure returned by PDC_RETURN_CHASSIS_INFO */
-struct pdc_chassis_lcd_info_ret_block {
-	unsigned long model:16;		/* DISPLAY_MODEL_XXXX (see below)  */
-	unsigned long lcd_width:16;	/* width of the LCD in chars (DISPLAY_MODEL_LCD only) */
-	char *lcd_cmd_reg_addr;		/* ptr to LCD cmd-register & data ptr for LED */
-	char *lcd_data_reg_addr;	/* ptr to LCD data-register (LCD only) */
-	unsigned int min_cmd_delay;	/* delay in uS after cmd-write (LCD only) */
-	unsigned char reset_cmd1;	/* command #1 for writing LCD string (LCD only) */
-	unsigned char reset_cmd2;	/* command #2 for writing LCD string (LCD only) */
-	unsigned char act_enable;	/* 0 = no activity (LCD only) */
-	struct lcd_block heartbeat;
-	struct lcd_block disk_io;
-	struct lcd_block lan_rcv;
-	struct lcd_block lan_tx;
-	char _pad;
-};
-
-/* values for pdc_chassis_lcd_info_ret_block.model: */
-#define DISPLAY_MODEL_LCD  0	/* KittyHawk LED or LCD */
-#define DISPLAY_MODEL_NONE 1	/* no LED or LCD */
-#define DISPLAY_MODEL_LASI 2	/* LASI style 8 bit LED */
-#define DISPLAY_MODEL_OLD_ASP 0x7F /* faked: ASP style 8 x 1 bit LED (only very old ASP versions) */
-
-
-/* LCD_CMD and LCD_DATA for KittyHawk machines */
-#ifdef __LP64__
-#define KITTYHAWK_LCD_CMD 0xfffffffff0190000L
-#else
-#define KITTYHAWK_LCD_CMD 0xf0190000
-#endif
-#define KITTYHAWK_LCD_DATA (KITTYHAWK_LCD_CMD + 1)
-
-
-/* lcd_info is pre-initialized to the values needed to program KittyHawk LCD's */
-static struct pdc_chassis_lcd_info_ret_block
-lcd_info __attribute__((aligned(8))) =
-{
-      model:DISPLAY_MODEL_LCD,
-      lcd_width:16,
-      lcd_cmd_reg_addr:(char *) KITTYHAWK_LCD_CMD,
-      lcd_data_reg_addr:(char *) KITTYHAWK_LCD_DATA,
-      min_cmd_delay:40,
-      reset_cmd1:0x80,
-      reset_cmd2:0xc0,
-};
-
-
-/* direct access to some of the lcd_info variables */
-#define LCD_CMD_REG	lcd_info.lcd_cmd_reg_addr	 
-#define LCD_DATA_REG	lcd_info.lcd_data_reg_addr	 
-#define LED_DATA_REG	lcd_info.lcd_cmd_reg_addr	/* LASI & ASP only */
-
-
-
-
-/*
-   ** 
-   ** led_ASP_driver()
-   ** 
- */
-#define	LED_DATA	0x01	/* data to shift (0:on 1:off) */
-#define	LED_STROBE	0x02	/* strobe to clock data */
-static void led_ASP_driver(unsigned char leds)
-{
-	int i;
-
-	leds = ~leds;
-	for (i = 0; i < 8; i++) {
-		unsigned char value;
-		value = (leds & 0x80) >> 7;
-		gsc_writeb( value,		 LED_DATA_REG );
-		gsc_writeb( value | LED_STROBE,	 LED_DATA_REG );
-		leds <<= 1;
-	}
-}
-
-
-/*
-   ** 
-   ** led_LASI_driver()
-   ** 
- */
-static void led_LASI_driver(unsigned char leds)
-{
-	leds = ~leds;
-	gsc_writeb( leds, LED_DATA_REG );
-}
-
-
-/*
-   ** 
-   ** led_LCD_driver()
-   ** 
-   ** The logic of the LCD driver is, that we write at every interrupt
-   ** only to one of LCD_CMD_REG _or_ LCD_DATA_REG - registers.
-   ** That way we don't need to let this interrupt routine busywait
-   ** the "min_cmd_delay", since idlewaiting in an interrupt-routine is
-   ** allways a BAD IDEA !
-   **
-   ** TODO: check the value of "min_cmd_delay" against the value of HZ.
-   **   
- */
-
-static void led_LCD_driver(unsigned char leds)
-{
-	static int last_index;	/* 0:heartbeat, 1:disk, 2:lan_in, 3:lan_out */
-	static int last_was_cmd;/* 0: CMD was written last, 1: DATA was last */
-	struct lcd_block *block_ptr;
-	int value;
-	
- 	// leds = ~leds;	/* needed ? */ 
-
-	switch (last_index) {
-	    case 0:	block_ptr = &lcd_info.heartbeat;
-			value = leds & LED_HEARTBEAT;
-			break;
-	    case 1:	block_ptr = &lcd_info.disk_io;
-			value = leds & LED_DISK_IO;
-			break;					
-	    case 2:	block_ptr = &lcd_info.lan_rcv;
-			value = leds & LED_LAN_RCV;
-			break;					
-	    case 3:	block_ptr = &lcd_info.lan_tx;
-			value = leds & LED_LAN_TX;
-			break;
-	    default:	/* should never happen: */
-			BUG();
-			return;
-	}
-
-	if (last_was_cmd) {
-	    /* write the value to the LCD data port */
-    	    gsc_writeb( value ? block_ptr->on : block_ptr->off, LCD_DATA_REG );
-	} else {
-	    /* write the command-byte to the LCD command register */
-    	    gsc_writeb( block_ptr->command, LCD_CMD_REG );
-	}    
-	
-	/* now update the vars for the next interrupt iteration */ 
-	if (++last_was_cmd == 2) {
-	    last_was_cmd = 0;
-	    if (++last_index == 4)
-		last_index = 0;
-	}
-}
-
-
-
-static char currentleds;	/* stores current value of the LEDs */
-
-static void (*led_func_ptr) (unsigned char); /* ptr to LCD/LED-specific function */
-
-/*
-   ** led_interrupt_func()
-   ** 
-   ** is called at every timer interrupt from time.c,
-   ** updates the chassis LCD/LED 
- */
-
-#define HEARTBEAT_LEN	(HZ/16)
-
-void led_interrupt_func(void)
-{
-#ifndef DISABLE_LEDS
-	static int count;
-	static int lastleds = -1;
-	static int nr;
-
-	/* exit, if not initialized */
-	if (!led_func_ptr)
-	    return;
-	
-	/* increment the local counter */
-	if (count == (HZ-1))
-	    count = 0;
-	else
-	    count++;
-
-	/* calculate the Heartbeat */
-	if ((count % (HZ/2)) < HEARTBEAT_LEN) 
-	    currentleds |= LED_HEARTBEAT;
-	else
-	    currentleds &= ~LED_HEARTBEAT;
-
-	/* roll LEDs 0..2 */
-	if (count == 0) {
-	    if (nr++ >= 2) 
-		nr = 0;
-	    currentleds &= ~7;
-	    currentleds |= (1 << nr);
-	}
-
-	/* now update the LEDs */
-	if (currentleds != lastleds) {
-	    led_func_ptr(currentleds);
-	    lastleds = currentleds;
-	}
-#endif
-}
-
-
-/*
-   ** register_led_driver()
-   ** 
-   ** All information in lcd_info needs to be set up prior
-   ** calling this function. 
- */
-
-static void __init register_led_driver(void)
-{
-#ifndef DISABLE_LEDS
-	switch (lcd_info.model) {
-	case DISPLAY_MODEL_LCD:
-		printk(KERN_INFO "LCD display at (%p,%p)\n",
-		  LCD_CMD_REG , LCD_DATA_REG);
-		led_func_ptr = led_LCD_driver;
-		break;
-
-	case DISPLAY_MODEL_LASI:
-		printk(KERN_INFO "LED display at %p\n",
-		       LED_DATA_REG);
-		led_func_ptr = led_LASI_driver;
-		break;
-
-	case DISPLAY_MODEL_OLD_ASP:
-		printk(KERN_INFO "LED (ASP-style) display at %p\n",
-		       LED_DATA_REG);
-		led_func_ptr = led_ASP_driver;
-		break;
-
-	default:
-		printk(KERN_ERR "%s: Wrong LCD/LED model %d !\n",
-		       __FUNCTION__, lcd_info.model);
-		return;
-	}
-#endif
-}
-
-/*
- * XXX - could this move to lasi.c ??
- */
-
-/*
-   ** lasi_led_init()
-   ** 
-   ** lasi_led_init() is called from lasi.c with the base hpa  
-   ** of the lasi controller chip. 
-   ** Since Mirage and Electra machines use a different LED
-   ** address register, we need to check for these machines 
-   ** explicitly.
- */
-
-#ifdef CONFIG_GSC_LASI
-void __init lasi_led_init(unsigned long lasi_hpa)
-{
-	if (lcd_info.model != DISPLAY_MODEL_NONE ||
-	    lasi_hpa == 0)
-		return;
-
-	printk("%s: CPU_HVERSION %x\n", __FUNCTION__, CPU_HVERSION);
-
-	/* Mirage and Electra machines need special offsets */
-	switch (CPU_HVERSION) {
-	case 0x60A:		/* Mirage Jr (715/64) */
-	case 0x60B:		/* Mirage 100 */
-	case 0x60C:		/* Mirage 100+ */
-	case 0x60D:		/* Electra 100 */
-	case 0x60E:		/* Electra 120 */
-		LED_DATA_REG = (char *) (lasi_hpa - 0x00020000);
-		break;
-	default:
-		LED_DATA_REG = (char *) (lasi_hpa + 0x0000C000);
-		break;
-	}			/* switch() */
-
-	lcd_info.model = DISPLAY_MODEL_LASI;
-	register_led_driver();
-}
-#endif
-
-
-/*
-   ** asp_led_init()
-   ** 
-   ** asp_led_init() is called from asp.c with the ptr 
-   ** to the LED display.
- */
-
-#ifdef CONFIG_GSC_LASI
-void __init asp_led_init(unsigned long led_ptr)
-{
-	if (lcd_info.model != DISPLAY_MODEL_NONE ||
-	    led_ptr == 0)
-		return;
-
-	lcd_info.model = DISPLAY_MODEL_OLD_ASP;
-	LED_DATA_REG = (char *) led_ptr;
-
-	register_led_driver();
-}
-
-#endif
-
-
-
-/*
-   ** register_led_regions()
-   ** 
-   ** Simple function, which registers the LCD/LED regions for /procfs.
-   ** At bootup - where the initialisation of the LCD/LED normally happens - 
-   ** not all internal structures of request_region() are properly set up,
-   ** so that we delay the registration until busdevice.c is executed.
-   **
- */
-
-void __init register_led_regions(void)
-{
-	switch (lcd_info.model) {
-	case DISPLAY_MODEL_LCD:
-		request_region((unsigned long)LCD_CMD_REG,  1, "lcd_cmd");
-		request_region((unsigned long)LCD_DATA_REG, 1, "lcd_data");
-		break;
-	case DISPLAY_MODEL_LASI:
-	case DISPLAY_MODEL_OLD_ASP:
-		request_region((unsigned long)LED_DATA_REG, 1, "led_data");
-		break;
-	}
-}
-
-
-
-/*
-   ** led_init()
-   ** 
-   ** led_init() is called very early in the bootup-process from setup.c 
-   ** and asks the PDC for an usable chassis LCD or LED.
-   ** If the PDC doesn't return any info, then the LED
-   ** is detected by lasi.c or asp.c and registered with the
-   ** above functions lasi_led_init() or asp_led_init().
-   ** KittyHawk machines have often a buggy PDC, so that
-   ** we explicitly check for those machines here.
- */
-
-int __init led_init(void)
-{
-#ifndef DISABLE_LEDS
-	long pdc_result[32];
-
-	printk("%s: CPU_HVERSION %x\n", __FUNCTION__, CPU_HVERSION);
-
-	/* Work around the buggy PDC of KittyHawk-machines */
-	switch (CPU_HVERSION) {
-	case 0x580:		/* KittyHawk DC2-100 (K100) */
-	case 0x581:		/* KittyHawk DC3-120 (K210) */
-	case 0x582:		/* KittyHawk DC3 100 (K400) */
-	case 0x583:		/* KittyHawk DC3 120 (K410) */
-	case 0x58B:		/* KittyHawk DC2 100 (K200) */
-		printk("%s: KittyHawk-Machine found !!\n", __FUNCTION__);
-		goto found;	/* use the preinitialized values of lcd_info */
-
-	default:
-		break;
-	}
-
-	/* initialize pdc_result, so we can check the return values of pdc_chassis_info() */
-	pdc_result[0] = pdc_result[1] = 0;
-
-	if (pdc_chassis_info(&pdc_result, &lcd_info, sizeof(lcd_info)) == PDC_OK) {
-		printk("%s: chassis info: model %d, ret0=%d, ret1=%d\n",
-		 __FUNCTION__, lcd_info.model, pdc_result[0], pdc_result[1]);
-
-		/* check the results. Some machines have a buggy PDC */
-		if (pdc_result[0] <= 0 || pdc_result[0] != pdc_result[1])
-			goto not_found;
-
-		switch (lcd_info.model) {
-		case DISPLAY_MODEL_LCD:	/* LCD display */
-			if (pdc_result[0] != sizeof(struct pdc_chassis_lcd_info_ret_block)
-			    && pdc_result[0] != sizeof(struct pdc_chassis_lcd_info_ret_block) - 1)
-				 goto not_found;
-			printk("%s: min_cmd_delay = %d uS\n",
-		             __FUNCTION__, lcd_info.min_cmd_delay);
-			break;
-
-		case DISPLAY_MODEL_NONE:	/* no LED or LCD available */
-			goto not_found;
-
-		case DISPLAY_MODEL_LASI:	/* Lasi style 8 bit LED display */
-			if (pdc_result[0] != 8 && pdc_result[0] != 32)
-				goto not_found;
-			break;
-
-		default:
-			printk(KERN_WARNING "Unknown LCD/LED model %d\n",
-			       lcd_info.model);
-			goto not_found;
-		}		/* switch() */
-
-found:
-		/* register the LCD/LED driver */
-		register_led_driver();
-		return 0;
-
-	}			/* if() */
-
-not_found:
-	lcd_info.model = DISPLAY_MODEL_NONE;
-	return 1;
-#endif
-}
diff -Nru a/arch/parisc/kernel/pa7300lc.c b/arch/parisc/kernel/pa7300lc.c
--- a/arch/parisc/kernel/pa7300lc.c	Mon Nov  4 14:31:01 2002
+++ b/arch/parisc/kernel/pa7300lc.c	Mon Nov  4 14:31:01 2002
@@ -7,7 +7,7 @@
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/kernel.h>
-#include <asm/gsc.h>
+#include <asm/io.h>
 #include <asm/ptrace.h>
 #include <asm/machdep.h>
 
diff -Nru a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c
--- a/arch/parisc/kernel/parisc_ksyms.c	Mon Nov  4 14:31:03 2002
+++ b/arch/parisc/kernel/parisc_ksyms.c	Mon Nov  4 14:31:03 2002
@@ -79,13 +79,9 @@
 EXPORT_SYMBOL_NOVERS($global$);
 #endif
 
-#include <asm/gsc.h>
 EXPORT_SYMBOL(register_parisc_driver);
 EXPORT_SYMBOL(unregister_parisc_driver);
 EXPORT_SYMBOL(pdc_iodc_read);
-#ifdef CONFIG_GSC
-EXPORT_SYMBOL(gsc_alloc_irq);
-#endif
 
 #include <asm/io.h>
 EXPORT_SYMBOL(__ioremap);
diff -Nru a/arch/parisc/kernel/pdc.c b/arch/parisc/kernel/pdc.c
--- a/arch/parisc/kernel/pdc.c	Mon Nov  4 14:31:03 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,217 +0,0 @@
-/* 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 ASSERT_ALIGN to ensure the aligment of the arguments is
- *	   correct
- *	 - 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 )
- *	{
- *		ASSERT_ALIGN(cache_info, 8);
- *	
- *		return mem_pdc_call(PDC_CACHE,PDC_CACHE_INFO,__pa(cache_info),0);
- *	}
- *					prumpf	991016	
- */
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-
-#include <asm/page.h>
-#include <asm/pdc.h>
-#include <asm/real.h>
-#include <asm/system.h>
-
-
-#define ASSERT_ALIGN(ptr, align)					\
-	do { if(((unsigned long)(ptr)) & (align-1)) {			\
-		printk("PDC: %s:%d  %s() called with "	\
-			"unaligned argument from %p", __FILE__, __LINE__, \
-			__FUNCTION__, __builtin_return_address(0));	\
-									\
-		return -1;						\
-	} } while(0)
-	
-/* verify address can be accessed without an HPMC */
-int pdc_add_valid(void *address)
-{
-	ASSERT_ALIGN(address, 4);
-
-	return mem_pdc_call(PDC_ADD_VALID, PDC_ADD_VALID_VERIFY, (unsigned long)address);
-}
-
-#if 0
-int pdc_chassis_warn(struct pdc_chassis_warn *address)
-{
-	ASSERT_ALIGN(address, 4);
-
-	return mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_WARN, __pa(address), 0);
-}
-#endif
-
-int pdc_chassis_disp(unsigned long disp)
-{
-	return mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_DISP, disp);
-}
-
-int pdc_chassis_info(void *pdc_result, void *chassis_info, unsigned long len)
-{
-	ASSERT_ALIGN(pdc_result, 4);
-	ASSERT_ALIGN(chassis_info, 4);
-	return mem_pdc_call(PDC_CHASSIS,PDC_RETURN_CHASSIS_INFO, 
-	        __pa(pdc_result), __pa(chassis_info), len);
-}
-
-int pdc_hpa_processor(void *address)
-{
-	/* We're using 0 for the last parameter just to make sure.
-	   It's actually HVERSION dependant.  And remember, life is
-	   hard without a backspace. */
-	ASSERT_ALIGN(address, 4);
-
-	return mem_pdc_call(PDC_HPA, PDC_HPA_PROCESSOR, __pa(address),0);
-}
-
-#if 0
-int pdc_hpa_modules(void *address)
-{
-	return mem_pdc_call(PDC_HPA, PDC_HPA_MODULES, address);
-}
-#endif
-
-int pdc_iodc_read(void *address, void * hpa, unsigned int index,
-	void * iodc_data, unsigned int iodc_data_size)
-{
-	ASSERT_ALIGN(address, 4);
-	ASSERT_ALIGN(iodc_data, 8);
-	return mem_pdc_call(PDC_IODC, PDC_IODC_READ, 
-		__pa(address), hpa, index, __pa(iodc_data), iodc_data_size);
-}
-
-
-int pdc_system_map_find_mods(void *pdc_mod_info, 
-	void *mod_path, int index)
-{
-	return mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_MODULE,
-		__pa(pdc_mod_info), __pa(mod_path), (long)index);
-}
-
-
-int pdc_model_info(struct pdc_model *model) {
-	ASSERT_ALIGN(model, 8);
-	return mem_pdc_call(PDC_MODEL,PDC_MODEL_INFO,__pa(model),0);
-}
-
-/* get system model name from PDC ROM (e.g. 9000/715 or 9000/778/B160L) */ 
-int pdc_model_sysmodel(char * name)
-{
-	struct pdc_model_sysmodel sys_model;
-	int retval;
-	
-	ASSERT_ALIGN(&sys_model, 8);
-	ASSERT_ALIGN(name, 4);
-
-	sys_model.mod_len = 0;
-	retval = mem_pdc_call(PDC_MODEL,PDC_MODEL_SYSMODEL,__pa(&sys_model),
-		    OS_ID_HPUX,__pa(name));
-	
-	if (retval == PDC_RET_OK) 
-	    name[sys_model.mod_len] = '\0'; /* add trailing '\0' */
-	else
-	    name[0] = 0;
-	
-	return retval;
-}
-
-/* id: 0 = cpu revision, 1 = boot-rom-version */
-int pdc_model_versions(struct pdc_model_cpuid *cpu_id, int id) {
-	return mem_pdc_call(PDC_MODEL,PDC_MODEL_VERSIONS,__pa(cpu_id),id);
-}
-
-int pdc_model_cpuid(struct pdc_model_cpuid *cpu_id) {
-	cpu_id->cpuid = 0; /* preset zero (call maybe not implemented!) */
-	return mem_pdc_call(PDC_MODEL,6,__pa(cpu_id),0);  /* 6="return CPU ID" */
-}
-
-int pdc_cache_info(struct pdc_cache_info *cache_info) {
-	ASSERT_ALIGN(cache_info, 8);
-
-	return mem_pdc_call(PDC_CACHE,PDC_CACHE_INFO,__pa(cache_info),0);
-}
-
-#ifndef __LP64__
-int pdc_btlb_info( struct pdc_btlb_info *btlb ) {
-	int status;
-	status = mem_pdc_call(PDC_BLOCK_TLB,PDC_BTLB_INFO,__pa(btlb),0);
-	if (status<0) btlb->max_size = 0;
-	return status;
-}
-
-int pdc_mem_map_hpa(void *r_addr, void *mod_path) {
-	return mem_pdc_call(PDC_MEM_MAP,PDC_MEM_MAP_HPA,
-		__pa(r_addr),__pa(mod_path));
-}
-
-int pdc_lan_station_id(char *lan_addr, void *net_hpa) {
-	struct pdc_lan_station_id id;
-	unsigned char *addr;
-	
-	if (mem_pdc_call(PDC_LAN_STATION_ID, PDC_LAN_STATION_ID_READ,
-			__pa(&id), net_hpa) < 0)
-		addr = 0;	/* FIXME: else read MAC from NVRAM */
-	    else
-		addr = id.addr;
-	if (addr)
-		memmove( lan_addr, addr, PDC_LAN_STATION_ID_SIZE);
-	    else
-		memset( lan_addr, 0, PDC_LAN_STATION_ID_SIZE);
-	return (addr != 0);
-}
-#endif
-
-
-/* Similar to PDC_PAT stuff in pdcpat.c - but added for Forte/Allegro boxes */
-int pdc_pci_irt_size(void *r_addr, void *hpa)
-{
-	return mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL_SIZE,
-		__pa(r_addr), hpa);
-
-}
-
-int pdc_pci_irt(void *r_addr, void *hpa, void *tbl)
-{
-	return mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL,
-		__pa(r_addr), hpa, __pa(tbl));
-}
-
-/* access the TOD clock */
-int pdc_tod_read(struct pdc_tod *tod)
-{
-	ASSERT_ALIGN(tod, 8);
-	return mem_pdc_call(PDC_TOD, PDC_TOD_READ, __pa(tod), 0);
-}
-
-int pdc_tod_set(unsigned long sec, unsigned long usec)
-{
-	return mem_pdc_call(PDC_TOD, PDC_TOD_WRITE, sec, usec);
-}
diff -Nru a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c
--- a/arch/parisc/kernel/perf.c	Mon Nov  4 14:31:01 2002
+++ b/arch/parisc/kernel/perf.c	Mon Nov  4 14:31:01 2002
@@ -49,11 +49,11 @@
 #include <linux/miscdevice.h>
 #include <linux/spinlock.h>
 
-#include <asm/gsc.h>
 #include <asm/uaccess.h>
 #include <asm/perf.h>
 #include <asm/processor.h>
 #include <asm/runway.h>
+#include <asm/io.h>		/* for __raw_read() */
 
 #include "perf_images.h"
 
diff -Nru a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
--- a/arch/parisc/kernel/process.c	Mon Nov  4 14:31:03 2002
+++ b/arch/parisc/kernel/process.c	Mon Nov  4 14:31:03 2002
@@ -35,7 +35,6 @@
 #include <asm/pgalloc.h>
 #include <asm/system.h>
 #include <asm/io.h>
-#include <asm/gsc.h>
 #include <asm/processor.h>
 #include <asm/pdc_chassis.h>
 
diff -Nru a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
--- a/arch/parisc/kernel/processor.c	Mon Nov  4 14:31:02 2002
+++ b/arch/parisc/kernel/processor.c	Mon Nov  4 14:31:02 2002
@@ -167,12 +167,24 @@
 	**	p->state = STATE_RENDEZVOUS;
 	*/
 
-	/*
-	** itimer and ipi IRQ handlers are statically initialized in
-	** arch/parisc/kernel/irq.c. ie Don't need to register them.
-	*/
-	p->region = irq_region[IRQ_FROM_REGION(CPU_IRQ_REGION)];
+#if 0
+	/* CPU 0 IRQ table is statically allocated/initialized */
+	if (cpuid) {
+		struct irqaction actions[];
 
+		/*
+		** itimer and ipi IRQ handlers are statically initialized in
+		** arch/parisc/kernel/irq.c. ie Don't need to register them.
+		*/
+		actions = kmalloc(sizeof(struct irqaction)*MAX_CPU_IRQ, GFP_ATOMIC);
+		if (!actions) {
+			/* not getting it's own table, share with monarch */
+			actions = cpu_irq_actions[0];
+		}
+
+		cpu_irq_actions[cpuid] = actions;
+	}
+#endif
 	return 0;
 }
 
diff -Nru a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
--- a/arch/parisc/kernel/ptrace.c	Mon Nov  4 14:31:00 2002
+++ b/arch/parisc/kernel/ptrace.c	Mon Nov  4 14:31:00 2002
@@ -15,6 +15,7 @@
 #include <linux/ptrace.h>
 #include <linux/user.h>
 #include <linux/personality.h>
+#include <linux/security.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -101,6 +102,11 @@
 		/* are we already being traced? */
 		if (current->ptrace & PT_PTRACED)
 			goto out;
+
+		ret = security_ops->ptrace(current->parent, current);
+		if (ret) 
+			goto out;
+
 		/* set the ptrace bit in the process flags. */
 		current->ptrace |= PT_PTRACED;
 		ret = 0;
@@ -385,7 +391,7 @@
 		goto out_tsk;
 
 	default:
-		ret = -EIO;
+		ret = ptrace_request(child, request, addr, data);
 		goto out_tsk;
 	}
 
@@ -409,7 +415,8 @@
 		return;
 	if (!(current->ptrace & PT_PTRACED))
 		return;
-	current->exit_code = SIGTRAP;
+	current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+					? 0x80 : 0);
 	current->state = TASK_STOPPED;
 	notify_parent(current, SIGCHLD);
 	schedule();
diff -Nru a/arch/parisc/kernel/real1.c b/arch/parisc/kernel/real1.c
--- a/arch/parisc/kernel/real1.c	Mon Nov  4 14:31:01 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,154 +0,0 @@
-/*
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000 Hewlett Packard (Paul Bame bame@puffin.external.hp.com)
- *
- * most of these calls might reasonably be moved to ../kernel -PB
- *
- * The basic principle is to construct a stack frame in C then call
- * some assembly which adopts that stack, does some rfi magic, may
- * switch wide/narrow mode, and calls the routine described by the
- * 'fn' parameter WHICH IS NOT A FUNCTION POINTER!!!!!!!!!!!!!!!!
- */
-#include <linux/spinlock.h>
-#include <asm/system.h>
-#include <stdarg.h>
-#include <asm/pgtable.h>		/* for __pa() */
-#include <asm/pdc.h>
-
-static spinlock_t pdc_lock = SPIN_LOCK_UNLOCKED;
-
-/***************** 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 */
-};
-
-long
-real32_call(unsigned long fn, ...)
-{
-    unsigned long r;
-    va_list args;
-    unsigned long flags;
-    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);
-
-    if (fn == 0) {
-	    /* mem_pdc call */
-	    fn = PAGE0->mem_pdc;
-    }
-
-    spin_lock_irqsave(&pdc_lock, flags);
-    r = real32_call_asm(&real_stack.sp, &real_stack.arg0, fn);
-    spin_unlock_irqrestore(&pdc_lock, flags);
-
-    return r;
-}
-
-#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 */
-};
-
-long
-real64_call(unsigned long fn, ...)
-{
-    unsigned long r;
-    va_list args;
-    unsigned long flags;
-    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);
-
-    if (fn == 0) {
-	    /* mem_pdc call */
-	    fn = PAGE0->mem_pdc_hi;
-	    fn <<= 32;
-	    fn |= PAGE0->mem_pdc;
-    }
-
-    spin_lock_irqsave(&pdc_lock, flags);
-    r = real64_call_asm(&real_stack.sp, &real_stack.arg0, fn);
-    spin_unlock_irqrestore(&pdc_lock, flags);
-
-    return r;
-}
-
-#endif
diff -Nru a/arch/parisc/kernel/sba_iommu.c b/arch/parisc/kernel/sba_iommu.c
--- a/arch/parisc/kernel/sba_iommu.c	Mon Nov  4 14:31:02 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1752 +0,0 @@
-/*
-**  System Bus Adapter (SBA) I/O MMU manager
-**
-**	(c) Copyright 2000 Grant Grundler
-**	(c) Copyright 2000 Hewlett-Packard Company
-**
-**	Portions (c) 1999 Dave S. Miller (from sparc64 I/O MMU code)
-**
-**	This program is free software; you can redistribute it and/or modify
-**	it under the terms of the GNU General Public License as published by
-**      the Free Software Foundation; either version 2 of the License, or
-**      (at your option) any later version.
-**
-**
-** This module initializes the IOC (I/O Controller) found on B1000/C3000/
-** J5000/J7000/N-class/L-class machines and their successors.
-**
-** FIXME: Multi-IOC support missing - depends on hp_device data
-** FIXME: add DMA hint support programming in both sba and lba modules.
-*/
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-
-#include <linux/mm.h>
-#include <linux/string.h>
-#define PCI_DEBUG		/* for ASSERT */
-#include <linux/pci.h>
-#undef PCI_DEBUG
-
-#include <asm/byteorder.h>
-#include <asm/io.h>
-#include <asm/dma.h>		/* for DMA_CHUNK_SIZE */
-
-#include <asm/hardware.h>	/* for register_driver() stuff */
-#include <asm/gsc.h>		/* FIXME: for gsc_read/gsc_write */
-
-#include <linux/proc_fs.h>
-#include <asm/runway.h>		/* for proc_runway_root */
-
-
-#define MODULE_NAME "SBA"
-
-/*
-** The number of debug flags is a clue - this code is fragile.
-** Don't even think about messing with it unless you have
-** plenty of 710's to sacrafice to the computer gods. :^)
-*/
-#undef DEBUG_SBA_INIT
-#undef DEBUG_SBA_RUN
-#undef DEBUG_SBA_RUN_SG
-#undef DEBUG_SBA_RESOURCE
-#undef ASSERT_PDIR_SANITY
-#undef DEBUG_LARGE_SG_ENTRIES
-
-#if 1
-#define SBA_INLINE
-#else
-#define SBA_INLINE	__inline__
-#endif
-
-#ifdef DEBUG_SBA_INIT
-#define DBG_INIT(x...)	printk(x)
-#else
-#define DBG_INIT(x...)
-#endif
-
-#ifdef DEBUG_SBA_RUN
-#define DBG_RUN(x...)	printk(x)
-#else
-#define DBG_RUN(x...)
-#endif
-
-#ifdef DEBUG_SBA_RUN_SG
-#define DBG_RUN_SG(x...)	printk(x)
-#else
-#define DBG_RUN_SG(x...)
-#endif
-
-
-#ifdef DEBUG_SBA_RESOURCE
-#define DBG_RES(x...)	printk(x)
-#else
-#define DBG_RES(x...)
-#endif
-
-/*
-** The number of pdir entries to "free" before issueing
-** a read to PCOM register to flush out PCOM writes.
-** Interacts with allocation granularity (ie 4 or 8 entries
-** allocated and free'd/purged at a time might make this
-** less interesting).
-*/
-#if 0
-#define DELAYED_RESOURCE_CNT	16
-#else
-#undef DELAYED_RESOURCE_CNT
-#endif
-
-#define DEFAULT_DMA_HINT_REG	0
-
-#define ASTRO_RUNWAY_PORT    0x582
-#define ASTRO_ROPES_PORT     0x780
-
-#define IKE_MERCED_PORT      0x803
-#define IKE_ROPES_PORT       0x781
-
-int sba_driver_callback(struct hp_device *, struct pa_iodc_driver *);
-
-static struct pa_iodc_driver sba_drivers_for[] = {
-
-/* FIXME: why is SVERSION checked? */
-
-   {HPHW_IOA, ASTRO_RUNWAY_PORT, 0x0, 0xb, 0, 0x10,
-		DRIVER_CHECK_HVERSION +
-		DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
-                MODULE_NAME, "I/O MMU", (void *) sba_driver_callback},
-
-   {HPHW_BCPORT, ASTRO_ROPES_PORT, 0x0, 0xb, 0, 0x10,
-		DRIVER_CHECK_HVERSION +
-		DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
-                MODULE_NAME, "I/O MMU", (void *) sba_driver_callback},
-
-#if 0
-/* FIXME : N-class! Use a different "callback"? */
-   {HPHW_BCPORT, IKE_MERCED_PORT, 0x0, 0xb, 0, 0x10,
-		DRIVER_CHECK_HVERSION +
-		DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
-                MODULE_NAME, "I/O MMU", (void *) sba_driver_callback},
-
-   {HPHW_BCPORT, IKE_ROPES_PORT, 0x0, 0xb, 0, 0x10,
-		DRIVER_CHECK_HVERSION +
-		DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
-                MODULE_NAME, "I/O MMU", (void *) sba_driver_callback},
-#endif
-
-   {0,0,0,0,0,0,
-   0,
-   (char *) NULL, (char *) NULL, (void *) NULL }
-};
-
-
-#define SBA_FUNC_ID	0x0000	/* function id */
-#define SBA_FCLASS	0x0008	/* function class, bist, header, rev... */
-
-#define IS_ASTRO(id) ( \
-    (((id)->hw_type == HPHW_IOA) && ((id)->hversion == ASTRO_RUNWAY_PORT)) || \
-    (((id)->hw_type == HPHW_BCPORT) && ((id)->hversion == ASTRO_ROPES_PORT))  \
-)
-
-#define CONFIG_FUNC_SIZE 4096   /* SBA configuration function reg set */
-
-#define ASTRO_IOC_OFFSET 0x20000
-/* Ike's IOC's occupy functions 2 and 3 (not 0 and 1) */
-#define IKE_IOC_OFFSET(p) ((p+2)*CONFIG_FUNC_SIZE)
-
-#define IOC_CTRL          0x8	/* IOC_CTRL offset */
-#define IOC_CTRL_TE       (0x1 << 0) /* TOC Enable */
-#define IOC_CTRL_RM       (0x1 << 8) /* Real Mode */
-#define IOC_CTRL_NC       (0x1 << 9) /* Non Coherent Mode */
-
-#define MAX_IOC		2	/* per Ike. Astro only has 1 */
-
-
-/*
-** Offsets into MBIB (Function 0 on Ike and hopefully Astro)
-** Firmware programs this stuff. Don't touch it.
-*/
-#define IOS_DIST_BASE	0x390
-#define IOS_DIST_MASK	0x398
-#define IOS_DIST_ROUTE	0x3A0
-
-#define IOS_DIRECT_BASE	0x3C0
-#define IOS_DIRECT_MASK	0x3C8
-#define IOS_DIRECT_ROUTE 0x3D0
-
-/*
-** Offsets into I/O TLB (Function 2 and 3 on Ike)
-*/
-#define ROPE0_CTL	0x200  /* "regbus pci0" */
-#define ROPE1_CTL	0x208
-#define ROPE2_CTL	0x210
-#define ROPE3_CTL	0x218
-#define ROPE4_CTL	0x220
-#define ROPE5_CTL	0x228
-#define ROPE6_CTL	0x230
-#define ROPE7_CTL	0x238
-
-#define HF_ENABLE	0x40
-
-
-#define IOC_IBASE	0x300	/* IO TLB */
-#define IOC_IMASK	0x308
-#define IOC_PCOM	0x310
-#define IOC_TCNFG	0x318
-#define IOC_PDIR_BASE	0x320
-
-#define IOC_IOVA_SPACE_BASE	0	/* IOVA ranges start at 0 */
-
-/*
-** IOC supports 4/8/16/64KB page sizes (see TCNFG register)
-** It's safer (avoid memory corruption) to keep DMA page mappings
-** equivalently sized to VM PAGE_SIZE.
-**
-** We really can't avoid generating a new mapping for each
-** page since the Virtual Coherence Index has to be generated
-** and updated for each page.
-**
-** IOVP_SIZE could only be greater than PAGE_SIZE if we are
-** confident the drivers really only touch the next physical
-** page iff that driver instance owns it.
-*/
-#define IOVP_SIZE	PAGE_SIZE
-#define IOVP_SHIFT	PAGE_SHIFT
-#define IOVP_MASK	PAGE_MASK
-
-#define SBA_PERF_CFG	0x708	/* Performance Counter stuff */
-#define SBA_PERF_MASK1	0x718
-#define SBA_PERF_MASK2	0x730
-
-
-/*
-** Offsets into PCI Performance Counters (functions 12 and 13)
-** Controlled by PERF registers in function 2 & 3 respectively.
-*/
-#define SBA_PERF_CNT1	0x200
-#define SBA_PERF_CNT2	0x208
-#define SBA_PERF_CNT3	0x210
-
-
-struct ioc {
-	char    *ioc_hpa;	/* I/O MMU base address */
-	char	*res_map;	/* resource map, bit == pdir entry */
-	u64	*pdir_base;	/* physical base address */
-
-	unsigned long	*res_hint;	/* next available IOVP - circular search */
-	unsigned int	res_bitshift;	/* from the LEFT! */
-	unsigned int	res_size;	/* size of resource map in bytes */
-	unsigned int	hint_shift_pdir;
-	spinlock_t	res_lock;
-	unsigned long	hint_mask_pdir;		/* bits used for DMA hints */
-#ifdef DELAYED_RESOURCE_CNT
-	dma_addr_t res_delay[DELAYED_RESOURCE_CNT];
-#endif
-
-#ifdef CONFIG_PROC_FS
-#define SBA_SEARCH_SAMPLE	0x100
-	unsigned long avg_search[SBA_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;
-#endif
-
-	/* STUFF We don't need in performance path */
-	unsigned int	pdir_size;	/* in bytes, determined by IOV Space size */
-	unsigned long	ibase;		/* pdir IOV Space base - shared w/lba_pci */
-	unsigned long	imask;		/* pdir IOV Space mask - shared w/lba_pci */
-};
-
-struct sba_device {
-	struct sba_device	*next;	/* list of LBA's in system */
-	struct hp_device	*iodc;	/* data about dev from firmware */
-	char			*sba_hpa; /* base address */
-	spinlock_t		sba_lock;
-	unsigned int			flags;  /* state/functionality enabled */
-	unsigned int			hw_rev;  /* HW revision of chip */
-
-	unsigned int			num_ioc;  /* number of on-board IOC's */
-	struct ioc		ioc[MAX_IOC];
-};
-
-
-static struct sba_device *sba_list;
-static int sba_count;
-
-/* Ratio of Host MEM to IOV Space size */
-static unsigned long sba_mem_ratio = 4;
-
-/* Looks nice and keeps the compiler happy */
-#define SBA_DEV(d) ((struct sba_device *) (d))
-
-
-#define ROUNDUP(x,y) ((x + ((y)-1)) & ~((y)-1))
-
-
-/************************************
-** SBA register read and write support
-**
-** BE WARNED: register writes are posted.
-**  (ie follow writes which must reach HW with a read)
-*/
-#define READ_U8(addr)  gsc_readb(addr)
-#define READ_U16(addr) gsc_readw((u16 *) (addr))
-#define READ_U32(addr) gsc_readl((u32 *) (addr))
-#define WRITE_U8(value, addr) gsc_writeb(value, addr)
-#define WRITE_U16(value, addr) gsc_writew(value, (u16 *) (addr))
-#define WRITE_U32(value, addr) gsc_writel(value, (u32 *) (addr))
-
-#define READ_REG8(addr)  gsc_readb(addr)
-#define READ_REG16(addr) le16_to_cpu(gsc_readw((u16 *) (addr)))
-#define READ_REG32(addr) le32_to_cpu(gsc_readl((u32 *) (addr)))
-#define READ_REG64(addr) le64_to_cpu(gsc_readq((u64 *) (addr)))
-#define WRITE_REG8(value, addr) gsc_writeb(value, addr)
-#define WRITE_REG16(value, addr) gsc_writew(cpu_to_le16(value), (u16 *) (addr))
-#define WRITE_REG32(value, addr) gsc_writel(cpu_to_le32(value), (u32 *) (addr))
-#define WRITE_REG64(value, addr) gsc_writeq(cpu_to_le64(value), (u64 *) (addr))
-
-#ifdef DEBUG_SBA_INIT
-
-static void
-sba_dump_ranges(char *hpa)
-{
-	printk("SBA at 0x%p\n", hpa);
-	printk("IOS_DIST_BASE   : %08x %08x\n",
-			READ_REG32(hpa+IOS_DIST_BASE+4),
-			READ_REG32(hpa+IOS_DIST_BASE));
-	printk("IOS_DIST_MASK   : %08x %08x\n",
-			READ_REG32(hpa+IOS_DIST_MASK+4),
-			READ_REG32(hpa+IOS_DIST_MASK));
-	printk("IOS_DIST_ROUTE  : %08x %08x\n",
-			READ_REG32(hpa+IOS_DIST_ROUTE+4),
-			READ_REG32(hpa+IOS_DIST_ROUTE));
-	printk("\n");
-	printk("IOS_DIRECT_BASE : %08x %08x\n",
-			READ_REG32(hpa+IOS_DIRECT_BASE+4),
-			READ_REG32(hpa+IOS_DIRECT_BASE));
-	printk("IOS_DIRECT_MASK : %08x %08x\n",
-			READ_REG32(hpa+IOS_DIRECT_MASK+4),
-			READ_REG32(hpa+IOS_DIRECT_MASK));
-	printk("IOS_DIRECT_ROUTE: %08x %08x\n",
-			READ_REG32(hpa+IOS_DIRECT_ROUTE+4),
-			READ_REG32(hpa+IOS_DIRECT_ROUTE));
-}
-
-static void
-sba_dump_tlb(char *hpa)
-{
-	printk("IO TLB at 0x%p\n", hpa);
-	printk("IOC_IBASE   : %08x %08x\n",
-			READ_REG32(hpa+IOC_IBASE+4),
-			READ_REG32(hpa+IOC_IBASE));
-	printk("IOC_IMASK   : %08x %08x\n",
-			READ_REG32(hpa+IOC_IMASK+4),
-			READ_REG32(hpa+IOC_IMASK));
-	printk("IOC_TCNFG   : %08x %08x\n",
-			READ_REG32(hpa+IOC_TCNFG+4),
-			READ_REG32(hpa+IOC_TCNFG));
-	printk("IOC_PDIR_BASE: %08x %08x\n",
-			READ_REG32(hpa+IOC_PDIR_BASE+4),
-			READ_REG32(hpa+IOC_PDIR_BASE));
-	printk("\n");
-}
-#endif
-
-
-#ifdef ASSERT_PDIR_SANITY
-
-static void
-sba_dump_pdir_entry(struct ioc *ioc, char *msg, uint pide)
-{
-	/* start printing from lowest pde in rval */
-	u64 *ptr = &(ioc->pdir_base[pide & (~0U * BITS_PER_LONG)]);
-	unsigned long *rptr = (unsigned long *) &(ioc->res_map[(pide >>3) & ~(sizeof(unsigned long) - 1)]);
-	uint rcnt;
-
-	printk("SBA: %s rp %p bit %d rval 0x%lx\n",
-		 msg,
-		 rptr, pide & (BITS_PER_LONG - 1), *rptr);
-
-	rcnt = 0;
-	while (rcnt < BITS_PER_LONG) {
-		printk("%s %2d %p %016Lx\n",
-			(rcnt == (pide & (BITS_PER_LONG - 1)))
-				? "    -->" : "       ",
-			rcnt, ptr, *ptr );
-		rcnt++;
-		ptr++;
-	}
-	printk(msg);
-}
-
-
-/* Verify the resource map and pdir state is consistent */
-static int
-sba_check_pdir(struct ioc *ioc, char *msg)
-{
-	u32 *rptr_end = (u32 *) &(ioc->res_map[ioc->res_size]);
-	u32 *rptr = (u32 *) ioc->res_map;	/* resource map ptr */
-	u64 *pptr = ioc->pdir_base;	/* pdir ptr */
-	uint pide = 0;
-
-	while (rptr < rptr_end) {
-		u32 rval = *rptr;
-		int rcnt = 32;	/* number of bits we might check */
-
-		while (rcnt) {
-			/* Get last byte and highest bit from that */
-			u32 pde = ((u32) (((char *)pptr)[7])) << 24;
-			if ((rval ^ pde) & 0x80000000)
-			{
-				/*
-				** BUMMER!  -- res_map != pdir --
-				** Dump rval and matching pdir entries
-				*/
-				sba_dump_pdir_entry(ioc, msg, pide);
-				return(1);
-			}
-			rcnt--;
-			rval <<= 1;	/* try the next bit */
-			pptr++;
-			pide++;
-		}
-		rptr++;	/* look at next word of res_map */
-	}
-	/* It'd be nice if we always got here :^) */
-	return 0;
-}
-
-
-static void
-sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents)
-{
-	while (nents-- > 0) {
-		printk(" %d : %08lx/%05x %p/%05x\n",
-				nents,
-				(unsigned long) sg_dma_address(startsg),
-				sg_dma_len(startsg),
-				startsg->address, startsg->length);
-		startsg++;
-	}
-}
-
-#endif /* ASSERT_PDIR_SANITY */
-
-
-
-/*
-** One time initialization to let the world know the LBA was found.
-** This is the only routine which is NOT static.
-** Must be called exactly once before pci_init().
-*/
-void __init
-sba_init(void)
-{
-	sba_list = (struct sba_device *) NULL;
-	sba_count = 0;
-
-#ifdef DEBUG_SBA_INIT
-	sba_dump_ranges((char *) 0xFED00000L);
-#endif
-
-	register_driver(sba_drivers_for);
-}
-
-
-
-/**************************************************************
-*
-*   I/O Pdir Resource Management
-*
-*   Bits set in the resource map are in use.
-*   Each bit can represent a number of pages.
-*   LSbs represent lower addresses (IOVA's).
-*
-***************************************************************/
-#define PAGES_PER_RANGE 1	/* could increase this to 4 or 8 if needed */
-
-/* Convert from IOVP to IOVA and vice versa. */
-#define SBA_IOVA(ioc,iovp,offset,hint_reg) ((iovp) | (offset) | ((hint_reg)<<(ioc->hint_shift_pdir)))
-#define SBA_IOVP(ioc,iova) ((iova) & ioc->hint_mask_pdir)
-
-/* FIXME : review these macros to verify correctness and usage */
-#define PDIR_INDEX(iovp)   ((iovp)>>IOVP_SHIFT)
-#define MKIOVP(dma_hint,pide)  (dma_addr_t)((long)(dma_hint) | ((long)(pide) << IOVP_SHIFT))
-#define MKIOVA(iovp,offset) (dma_addr_t)((long)iovp | (long)offset)
-
-#define RESMAP_MASK(n)    (~0UL << (BITS_PER_LONG - (n)))
-#define RESMAP_IDX_MASK   (sizeof(unsigned long) - 1)
-
-
-/*
-** Perf optimizations:
-** o search for log2(size) bits at a time.
-**
-** Search should use register width as "stride" to search the res_map. 
-*/
-
-static SBA_INLINE unsigned long
-sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted)
-{
-	unsigned long *res_ptr = ioc->res_hint;
-	unsigned long *res_end = (unsigned long *) &(ioc->res_map[ioc->res_size]);
-	unsigned long pide = ~0UL;
-
-	ASSERT(((unsigned long) ioc->res_hint & (sizeof(unsigned long) - 1UL)) == 0);
-	ASSERT(res_ptr < res_end);
-	if (bits_wanted > (BITS_PER_LONG/2)) {
-		/* Search word at a time - no mask needed */
-		for(; res_ptr < res_end; ++res_ptr) {
-			if (*res_ptr == 0) {
-				*res_ptr = RESMAP_MASK(bits_wanted);
-				pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map);
-				pide <<= 3;	/* convert to bit address */
-				ASSERT(0 != pide);
-				break;
-			}
-		}
-		/* point to the next word on next pass */
-		res_ptr++;
-		ioc->res_bitshift = 0;
-	} else {
-		/*
-		** Search the resource bit map on well-aligned values.
-		** "o" is the alignment.
-		** We need the alignment to invalidate I/O TLB using
-		** SBA HW features in the unmap path.
-		*/
-		unsigned long o = 1 << get_order(bits_wanted << PAGE_SHIFT);
-		uint bitshiftcnt = ROUNDUP(ioc->res_bitshift, o);
-		unsigned long mask;
-
-		if (bitshiftcnt >= BITS_PER_LONG) {
-			bitshiftcnt = 0;
-			res_ptr++;
-		}
-		mask = RESMAP_MASK(bits_wanted) >> bitshiftcnt;
-
-		DBG_RES("sba_search_bitmap() o %ld %p", o, res_ptr);
-		while(res_ptr < res_end)
-		{ 
-			DBG_RES("    %p %lx %lx\n", res_ptr, mask, *res_ptr);
-			ASSERT(0 != mask);
-			if(0 == ((*res_ptr) & mask)) {
-				*res_ptr |= mask;     /* mark resources busy! */
-				pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map);
-				pide <<= 3;	/* convert to bit address */
-				pide += bitshiftcnt;
-				ASSERT(0 != pide);
-				break;
-			}
-			mask >>= o;
-			bitshiftcnt += o;
-			if (0 == mask) {
-				mask = RESMAP_MASK(bits_wanted);
-				bitshiftcnt=0;
-				res_ptr++;
-			}
-		}
-		/* look in the same word on the next pass */
-		ioc->res_bitshift = bitshiftcnt + bits_wanted;
-	}
-
-	/* wrapped ? */
-	ioc->res_hint = (res_end == res_ptr) ? (unsigned long *) ioc->res_map : res_ptr;
-	return (pide);
-}
-
-
-static int
-sba_alloc_range(struct ioc *ioc, size_t size)
-{
-	unsigned int pages_needed = size >> IOVP_SHIFT;
-#ifdef CONFIG_PROC_FS
-	unsigned long cr_start = mfctl(16);
-#endif
-	unsigned long pide;
-
-	ASSERT(pages_needed);
-	ASSERT((pages_needed * IOVP_SIZE) < DMA_CHUNK_SIZE);
-	ASSERT(pages_needed < BITS_PER_LONG);
-	ASSERT(0 == (size & ~IOVP_MASK));
-
-	/*
-	** "seek and ye shall find"...praying never hurts either...
-	** ggg sacrifices another 710 to the computer gods.
-	*/
-
-	pide = sba_search_bitmap(ioc, pages_needed);
-	if (pide >= (ioc->res_size << 3)) {
-		pide = sba_search_bitmap(ioc, pages_needed);
-		if (pide >= (ioc->res_size << 3))
-			panic(__FILE__ ": I/O MMU @ %p is out of mapping resources\n", ioc->ioc_hpa);
-	}
-
-#ifdef ASSERT_PDIR_SANITY
-	/* verify the first enable bit is clear */
-	if(0x00 != ((u8 *) ioc->pdir_base)[pide*sizeof(u64) + 7]) {
-		sba_dump_pdir_entry(ioc, "sba_search_bitmap() botched it?", pide);
-	}
-#endif
-
-	DBG_RES("sba_alloc_range(%x) %d -> %lx hint %x/%x\n",
-		size, pages_needed, pide,
-		(uint) ((unsigned long) ioc->res_hint - (unsigned long) ioc->res_map),
-		ioc->res_bitshift );
-
-#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 &= SBA_SEARCH_SAMPLE - 1;
-
-	ioc->used_pages += pages_needed;
-#endif
-
-	return (pide);
-}
-
-
-/*
-** clear bits in the ioc's resource map
-*/
-static SBA_INLINE void
-sba_free_range(struct ioc *ioc, dma_addr_t iova, size_t size)
-{
-	unsigned long iovp = SBA_IOVP(ioc, iova);
-	unsigned int pide = PDIR_INDEX(iovp);
-	unsigned int ridx = pide >> 3;	/* convert bit to byte address */
-	unsigned long *res_ptr = (unsigned long *) &((ioc)->res_map[ridx & ~RESMAP_IDX_MASK]);
-
-	int bits_not_wanted = size >> IOVP_SHIFT;
-
-	/* 3-bits "bit" address plus 2 (or 3) bits for "byte" == bit in word */
-	unsigned long m = RESMAP_MASK(bits_not_wanted) >> (pide & (BITS_PER_LONG - 1));
-
-	DBG_RES("sba_free_range( ,%x,%x) %x/%lx %x %p %lx\n",
-		(uint) iova, size,
-		bits_not_wanted, m, pide, res_ptr, *res_ptr);
-
-#ifdef CONFIG_PROC_FS
-	ioc->used_pages -= bits_not_wanted;
-#endif
-
-	ASSERT(m != 0);
-	ASSERT(bits_not_wanted);
-	ASSERT((bits_not_wanted * IOVP_SIZE) < DMA_CHUNK_SIZE);
-	ASSERT(bits_not_wanted < BITS_PER_LONG);
-	ASSERT((*res_ptr & m) == m); /* verify same bits are set */
-	*res_ptr &= ~m;
-}
-
-
-/**************************************************************
-*
-*   "Dynamic DMA Mapping" support (aka "Coherent I/O")
-*
-***************************************************************/
-
-#define SBA_DMA_HINT(ioc, val) ((val) << (ioc)->hint_shift_pdir)
-
-
-typedef unsigned long space_t;
-#define KERNEL_SPACE 0
-
-/*
-* SBA Mapping Routine
-*
-* Given a virtual address (vba, arg2) and space id, (sid, arg1)
-* sba_io_pdir_entry() loads 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):
-*
-*  0                    19                                 51   55       63
-* +-+---------------------+----------------------------------+----+--------+
-* |V|        U            |            PPN[43:12]            | U  |   VI   |
-* +-+---------------------+----------------------------------+----+--------+
-*
-*  V  == Valid Bit
-*  U  == Unused
-* PPN == Physical Page Number
-* VI  == Virtual Index (aka Coherent Index)
-*
-* The physical address fields are filled with the results of the LPA
-* instruction.  The virtual index field is filled with the results of
-* 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.
-*
-* We need to pre-swap the bytes since PCX-W is Big Endian.
-*/
-
-void SBA_INLINE
-sba_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba)
-{
-	u64 pa; /* physical address */
-	register unsigned ci; /* coherent index */
-
-	/* We currently only support kernel addresses */
-	ASSERT(sid == 0);
-	ASSERT(((unsigned long) vba & 0xc0000000UL) == 0xc0000000UL);
-
-	pa = virt_to_phys(vba);
-	pa &= ~4095ULL;			/* clear out offset bits */
-
-	mtsp(sid,1);
-	asm("lci 0(%%sr1, %1), %0" : "=r" (ci) : "r" (vba));
-	pa |= (ci >> 12) & 0xff;  /* move CI (8 bits) into lowest byte */
-
-	pa |= 0x8000000000000000ULL;	/* set "valid" bit */
-	*pdir_ptr = cpu_to_le64(pa);	/* swap and store into I/O Pdir */
-}
-
-
-/***********************************************************
- * The Ike PCOM (Purge Command Register) is to purge
- * stale entries in the IO TLB when unmapping entries.
- *
- * The PCOM register supports purging of multiple pages, with a minium
- * of 1 page and a maximum of 2GB. Hardware requires the address be
- * aligned to the size of the range being purged. The size of the range
- * must be a power of 2.
- ***********************************************************/
-static SBA_INLINE void
-sba_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt)
-{
-	u32 iovp = (u32) SBA_IOVP(ioc,iova);
-
-	/* Even though this is a big-endian machine, the entries
-	** in the iopdir are swapped. That's why we clear the byte
-	** at +7 instead of at +0.
-	*/
-	int off = PDIR_INDEX(iovp)*sizeof(u64)+7;
-
-	/* Must be non-zero and rounded up */
-	ASSERT(byte_cnt > 0);
-	ASSERT(0 == (byte_cnt & ~IOVP_MASK));
-
-#ifdef ASSERT_PDIR_SANITY
-	/* Assert first pdir entry is set */
-	if (0x80 != (((u8 *) ioc->pdir_base)[off])) {
-		sba_dump_pdir_entry(ioc,"sba_mark_invalid()", PDIR_INDEX(iovp));
-	}
-#endif
-
-	if (byte_cnt <= IOVP_SIZE)
-	{
-		ASSERT( off < ioc->pdir_size);
-
-		iovp |= IOVP_SHIFT;     /* set "size" field for PCOM */
-
-		/*
-		** clear I/O PDIR entry "valid" bit
-		** Do NOT clear the rest - save it for debugging.
-		** We should only clear bits that have previously
-		** been enabled.
-		*/
-		((u8 *)(ioc->pdir_base))[off] = 0;
-	} else {
-		u32 t = get_order(byte_cnt) + PAGE_SHIFT;
-
-		iovp |= t;
-		ASSERT(t <= 31);   /* 2GB! Max value of "size" field */
-
-		do {
-			/* verify this pdir entry is enabled */
-			ASSERT(0x80 == (((u8 *) ioc->pdir_base)[off] & 0x80));
-			/* clear I/O Pdir entry "valid" bit first */
-			((u8 *)(ioc->pdir_base))[off] = 0;
-			off += sizeof(u64);
-			byte_cnt -= IOVP_SIZE;
-		} while (byte_cnt > 0);
-	}
-
-	WRITE_REG32(iovp, ioc->ioc_hpa+IOC_PCOM);
-}
-
-static int
-sba_dma_supported( struct pci_dev *dev, u64 mask)
-{
-	if (dev == NULL) {
-		printk(MODULE_NAME ": EISA/ISA/et al not supported\n");
-		BUG();
-		return(0);
-	}
-
-	dev->dma_mask = mask;	/* save it */
-
-	/* only support PCI devices */
-	return((int) (mask >= 0xffffffff));
-}
-
-
-/*
-** map_single returns a fully formed IOVA
-*/
-static dma_addr_t
-sba_map_single(struct pci_dev *dev, void *addr, size_t size, int direction)
-{
-	struct ioc *ioc = &sba_list->ioc[0];  /* FIXME : see Multi-IOC below */
-	unsigned long flags; 
-	dma_addr_t iovp;
-	dma_addr_t offset;
-	u64 *pdir_start;
-	int pide;
-
-	ASSERT(size > 0);
-
-	/* save offset bits */
-	offset = ((dma_addr_t) addr) & ~IOVP_MASK;
-
-	/* round up to nearest IOVP_SIZE */
-	size = (size + offset + ~IOVP_MASK) & IOVP_MASK;
-
-	spin_lock_irqsave(&ioc->res_lock, flags);
-#ifdef ASSERT_PDIR_SANITY
-	sba_check_pdir(ioc,"Check before sba_map_single()");
-#endif
-
-#ifdef CONFIG_PROC_FS
-	ioc->msingle_calls++;
-	ioc->msingle_pages += size >> IOVP_SHIFT;
-#endif
-	pide = sba_alloc_range(ioc, size);
-	iovp = (dma_addr_t) pide << IOVP_SHIFT;
-
-	DBG_RUN("sba_map_single() 0x%p -> 0x%lx", addr, (long) iovp | offset);
-
-	pdir_start = &(ioc->pdir_base[pide]);
-
-	while (size > 0) {
-		ASSERT(((u8 *)pdir_start)[7] == 0); /* verify availability */
-		sba_io_pdir_entry(pdir_start, KERNEL_SPACE, (unsigned long) addr);
-
-		DBG_RUN(" pdir 0x%p %02x%02x%02x%02x%02x%02x%02x%02x\n",
-			pdir_start,
-			(u8) (((u8 *) pdir_start)[7]),
-			(u8) (((u8 *) pdir_start)[6]),
-			(u8) (((u8 *) pdir_start)[5]),
-			(u8) (((u8 *) pdir_start)[4]),
-			(u8) (((u8 *) pdir_start)[3]),
-			(u8) (((u8 *) pdir_start)[2]),
-			(u8) (((u8 *) pdir_start)[1]),
-			(u8) (((u8 *) pdir_start)[0])
-			);
-
-		addr += IOVP_SIZE;
-		size -= IOVP_SIZE;
-		pdir_start++;
-	}
-	/* form complete address */
-#ifdef ASSERT_PDIR_SANITY
-	sba_check_pdir(ioc,"Check after sba_map_single()");
-#endif
-	spin_unlock_irqrestore(&ioc->res_lock, flags);
-	return SBA_IOVA(ioc, iovp, offset, DEFAULT_DMA_HINT_REG);
-}
-
-
-static void
-sba_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)
-** o use (struct pci_hba) and put fields in there for DMA.
-**   (ioc and per device dma_hint.)
-**
-** Last one seems the clearest and most promising.
-** sba_dma_supported() fill in those fields when the driver queries
-** the system for support.
-*/
-	struct ioc *ioc = (struct ioc *) ((struct pci_hba *) (dev->sysdata))->dma_data;
-#else
-	struct ioc *ioc = &sba_list->ioc[0];
-#endif
-	
-	unsigned long flags; 
-	dma_addr_t offset;
-	offset = iova & ~IOVP_MASK;
-
-	DBG_RUN("%s() iovp 0x%lx/%x\n", __FUNCTION__, (long) iova, size);
-
-	iova ^= offset;        /* clear offset bits */
-	size += offset;
-	size = ROUNDUP(size, IOVP_SIZE);
-
-	ASSERT(0 != iova);
-
-	spin_lock_irqsave(&ioc->res_lock, flags);
-#ifdef CONFIG_PROC_FS
-	ioc->usingle_calls++;
-	ioc->usingle_pages += size >> IOVP_SHIFT;
-#endif
-#ifdef DELAYED_RESOURCE_CNT
-	if (ioc->saved_cnt < DELAYED_RESOURCE_CNT) {
-		ioc->saved_iova[ioc->saved_cnt] = iova;
-		ioc->saved_size[ioc->saved_cnt] = size;
-		ioc_saved_cnt++;
-	} else {
-		do {
-#endif
-			sba_mark_invalid(ioc, iova, size);
-			sba_free_range(ioc, iova, size);
-
-#ifdef DELAYED_RESOURCE_CNT
-			ioc->saved_cnt--;
-			iova = ioc->saved_iova[ioc->saved_cnt];
-			size = ioc->saved_size[ioc->saved_cnt];
-		} while (ioc->saved_cnt)
-
-		/* flush purges */
-		(void) (volatile) READ_REG32(ioc->ioc_hpa+IOC_PCOM);
-	}
-#else
-	/* flush purges */
-	READ_REG32(ioc->ioc_hpa+IOC_PCOM);
-#endif
-	spin_unlock_irqrestore(&ioc->res_lock, flags);
-}
-
-
-static void *
-sba_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle)
-{
-	void *ret;
-
-	if (!hwdev) {
-		/* only support PCI */
-		*dma_handle = 0;
-		return 0;
-	}
-
-        ret = (void *) __get_free_pages(GFP_ATOMIC, get_order(size));
-
-	if (ret) {
-		memset(ret, 0, size);
-		*dma_handle = sba_map_single(hwdev, ret, size, 0);
-	}
-
-	return ret;
-}
-
-
-static void
-sba_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
-{
-	sba_unmap_single(hwdev, dma_handle, size, 0);
-	free_pages((unsigned long) vaddr, get_order(size));
-}
-
-/*
-** Two address ranges are "virtually contiguous" iff:
-** 1) end of prev == start of next, or...	 append case
-** 3) end of next == start of prev		 prepend case
-**
-** and they are DMA contiguous *iff*:
-** 2) end of prev and start of next are both on a page boundry
-**
-** (shift left is a quick trick to mask off upper bits)
-*/
-#define DMA_CONTIG(__X, __Y) \
-	(((((unsigned long) __X) | ((unsigned long) __Y)) << (BITS_PER_LONG - PAGE_SHIFT)) == 0UL)
-
-/*
-** Assumption is two transactions are mutually exclusive.
-** ie both go to different parts of memory.
-** If both are true, then both transaction are on the same page.
-*/
-#define DMA_SAME_PAGE(s1,e1,s2,e2) \
-	( ((((s1) ^ (s2)) >> PAGE_SHIFT) == 0) \
-		&& ((((e1) ^ (e2)) >> PAGE_SHIFT) == 0) )
-
-/*
-** 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
-
-#ifdef DEBUG_LARGE_SG_ENTRIES
-int dump_run_sg = 0;
-#endif
-
-static SBA_INLINE int
-sba_fill_pdir(
-	struct ioc *ioc,
-	struct scatterlist *startsg,
-	int nents)
-{
-	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;
-
-#ifdef DEBUG_LARGE_SG_ENTRIES
-		if (dump_run_sg)
-			printk(" %d : %08lx/%05x %p/%05x\n",
-				nents,
-				(unsigned long) sg_dma_address(startsg), cnt,
-				startsg->address, startsg->length
-		);
-#else
-		DBG_RUN_SG(" %d : %08lx/%05x %p/%05x\n",
-				nents,
-				(unsigned long) sg_dma_address(startsg), cnt,
-				startsg->address, startsg->length
-		);
-#endif
-		/*
-		** 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;
-			pide >>= IOVP_SHIFT;
-			pdirp = &(ioc->pdir_base[pide]);
-			sg_dma_address(startsg) = 0;
-			++dma_sg;
-			sg_dma_address(dma_sg) = (pide << IOVP_SHIFT) + dma_offset;
-			n_mappings++;
-		}
-
-		/*
-		** Look for a VCONTIG chunk
-		*/
-		if (cnt) {
-			unsigned long vaddr = (unsigned long) startsg->address;
-			ASSERT(pdirp);
-
-			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 {
-				sba_io_pdir_entry(pdirp, KERNEL_SPACE, vaddr);
-				vaddr += IOVP_SIZE;
-				cnt -= IOVP_SIZE;
-				pdirp++;
-			} while (cnt > 0);
-		}
-		startsg++;
-	}
-#ifdef DEBUG_LARGE_SG_ENTRIES
-	dump_run_sg = 0;
-#endif
-	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 SBA_INLINE int
-sba_coalesce_chunks( struct ioc *ioc,
-	struct scatterlist *startsg,
-	int nents)
-{
-	int n_mappings = 0;
-
-	while (nents > 0) {
-		struct scatterlist *dma_sg;  /* next DMA stream head */
-		unsigned long dma_offset, dma_len;   /* start/len of DMA stream */
-		struct scatterlist *chunksg; /* virtually contig chunk head */
-		unsigned long chunk_addr, chunk_len; /* start/len of VCONTIG chunk */
-
-		/*
-		** Prepare for first/next DMA stream
-		*/
-		dma_sg = chunksg = startsg;
-		dma_len = chunk_len  = startsg->length;
-		chunk_addr = (unsigned long) startsg->address;
-		dma_offset = 0UL;
-
-		/*
-		** This loop terminates one iteration "early" since
-		** it's always looking one "ahead".
-		*/
-		while (--nents > 0) {
-			/* ptr to coalesce prev and next */
-			struct scatterlist *prev_sg = startsg;
-			unsigned long prev_end = (unsigned long) prev_sg->address + prev_sg->length;
-			unsigned long current_end;
-
-			/* PARANOID: clear entries */
-			sg_dma_address(startsg) = 0;
-			sg_dma_len(startsg) = 0;
-
-			/* Now start looking ahead */
-			startsg++;
-			current_end  = (unsigned long) startsg->address + startsg->length;
-
-			/*
-			** First look for virtually contiguous blocks.
-			** PARISC needs this since it's cache is virtually
-			** indexed and we need the associated virtual
-			** address for each I/O address we map.
-			**
-			** 1) can we *prepend* the next transaction?
-			*/
-			if (current_end == (unsigned long) prev_sg->address)
-			{
-				/* prepend : get new offset */
-				chunksg = startsg;
-				chunk_addr = (unsigned long) prev_sg->address;
-				chunk_len += startsg->length;
-				dma_len   += startsg->length;
-				continue;
-			}
-
-			/*
-			** 2) or append the next transaction?
-			*/
-			if  (prev_end == (unsigned long) startsg->address)
-			{
-				chunk_len += startsg->length;
-				dma_len   += startsg->length;
-				continue;
-			}
-
-#ifdef DEBUG_LARGE_SG_ENTRIES
-			dump_run_sg = (chunk_len > IOVP_SIZE);
-#endif
-			/*
-			** Not virtually contigous.
-			** Terminate prev chunk.
-			** Start a new chunk.
-			**
-			** Once we start a new VCONTIG chunk, the 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(prev_sg) = chunk_len;
-
-			chunk_len = startsg->length;
-			dma_offset |= (chunk_addr & ~IOVP_MASK);
-			ASSERT((0 == (chunk_addr & ~IOVP_MASK)) ||
-				(dma_offset == (chunk_addr & ~IOVP_MASK)));
-
-#if 0
-			/*
-			** 4) do the chunks end/start on page boundaries?
-			**  Easier than 3 since no offsets are involved.
-			*/
-			if (DMA_CONTIG(prev_end, startsg->address))
-			{
-				/*
-				** Yes.
-				** Reset chunk ptr.
-				*/
-				chunksg = startsg;
-				chunk_addr = (unsigned long) startsg->address;
-
-				continue;
-			} else
-#endif
-			{
-				break;
-			}
-		}
-
-		/*
-		** End of DMA Stream
-		** Terminate chunk.
-		** Allocate space for DMA stream.
-		*/
-		sg_dma_len(startsg) = chunk_len;
-		dma_len = (dma_len + dma_offset + ~IOVP_MASK) & IOVP_MASK;
-		sg_dma_address(dma_sg) =
-			PIDE_FLAG 
-			| (sba_alloc_range(ioc, dma_len) << IOVP_SHIFT)
-			| dma_offset;
-		n_mappings++;
-	}
-
-	return n_mappings;
-}
-
-
-/*
-** And this algorithm still generally only ends up coalescing entries
-** that happens to be on the same page due to how sglists are assembled.
-*/
-static int
-sba_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
-{
-	struct ioc *ioc = &sba_list->ioc[0];  /* FIXME : see Multi-IOC below */
-	int coalesced, filled = 0;
-	unsigned long flags;
-
-	DBG_RUN_SG("%s() START %d entries\n", __FUNCTION__, nents);
-
-	/* Fast path single entry scatterlists. */
-	if (nents == 1) {
-		sg_dma_address(sglist)= sba_map_single(dev, sglist->address,
-						sglist->length, direction);
-		sg_dma_len(sglist)= sglist->length;
-		return 1;
-	}
-
-	spin_lock_irqsave(&ioc->res_lock, flags);
-
-#ifdef ASSERT_PDIR_SANITY
-	if (sba_check_pdir(ioc,"Check before sba_map_sg()"))
-	{
-		sba_dump_sg(ioc, sglist, nents);
-		panic("Check before sba_map_sg()");
-	}
-#endif
-
-#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 = sba_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 = sba_fill_pdir(ioc, sglist, nents);
-
-#ifdef ASSERT_PDIR_SANITY
-	if (sba_check_pdir(ioc,"Check after sba_map_sg()"))
-	{
-		sba_dump_sg(ioc, sglist, nents);
-		panic("Check after sba_map_sg()\n");
-	}
-#endif
-
-	spin_unlock_irqrestore(&ioc->res_lock, flags);
-
-	ASSERT(coalesced == filled);
-	DBG_RUN_SG("%s() DONE %d mappings\n", __FUNCTION__, filled);
-
-	return filled;
-}
-
-
-static void 
-sba_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
-{
-	struct ioc *ioc = &sba_list->ioc[0];  /* FIXME : see Multi-IOC below */
-#ifdef ASSERT_PDIR_SANITY
-	unsigned long flags;
-#endif
-
-	DBG_RUN_SG("%s() START %d entries,  %p,%x\n",
-		__FUNCTION__, nents, sglist->address, sglist->length);
-
-#ifdef CONFIG_PROC_FS
-	ioc->usg_calls++;
-#endif
-
-#ifdef ASSERT_PDIR_SANITY
-	spin_lock_irqsave(&ioc->res_lock, flags);
-	sba_check_pdir(ioc,"Check before sba_unmap_sg()");
-	spin_unlock_irqrestore(&ioc->res_lock, flags);
-#endif
-
-	while (sg_dma_len(sglist) && nents--) {
-
-#ifdef CONFIG_PROC_FS
-	ioc->usg_pages += sg_dma_len(sglist) >> PAGE_SHIFT;
-#endif
-		sba_unmap_single(dev, sg_dma_address(sglist), sg_dma_len(sglist), direction);
-		++sglist;
-	}
-
-	DBG_RUN_SG("%s() DONE (nents %d)\n", __FUNCTION__,  nents);
-
-#ifdef ASSERT_PDIR_SANITY
-	spin_lock_irqsave(&ioc->res_lock, flags);
-	sba_check_pdir(ioc,"Check after sba_unmap_sg()");
-	spin_unlock_irqrestore(&ioc->res_lock, flags);
-#endif
-
-}
-
-static struct pci_dma_ops sba_ops = {
-	sba_dma_supported,
-	sba_alloc_consistent,	/* allocate cacheable host mem */
-	sba_free_consistent,	/* release cacheable host mem */
-	sba_map_single,
-	sba_unmap_single,
-	sba_map_sg,
-	sba_unmap_sg,
-	NULL,			/* dma_sync_single */
-	NULL			/* dma_sync_sg */
-};
-
-
-/**************************************************************************
-**
-**   SBA PAT PDC support
-**
-**   o call pdc_pat_cell_module()
-**   o store ranges in PCI "resource" structures
-**
-**************************************************************************/
-
-static void
-sba_get_pat_resources(struct sba_device *sba_dev)
-{
-#if 0
-/*
-** TODO/REVISIT/FIXME: support for directed ranges requires calls to
-**      PAT PDC to program the SBA/LBA directed range registers...this
-**      burden may fall on the LBA code since it directly supports the
-**      PCI subsystem. It's not clear yet. - ggg
-*/
-PAT_MOD(mod)->mod_info.mod_pages   = PAT_GET_MOD_PAGES(temp);
-	FIXME : ???
-PAT_MOD(mod)->mod_info.dvi         = PAT_GET_DVI(temp);
-	Tells where the dvi bits are located in the address.
-PAT_MOD(mod)->mod_info.ioc         = PAT_GET_IOC(temp);
-	FIXME : ???
-#endif
-}
-
-
-/**************************************************************
-*
-*   Initialization and claim
-*
-***************************************************************/
-
-
-static void
-sba_ioc_init(struct ioc *ioc)
-{
-	extern unsigned long mem_max;          /* arch.../setup.c */
-	extern void lba_init_iregs(void *, u32, u32);   /* arch.../lba_pci.c */
-
-	u32 iova_space_size, iova_space_mask;
-	void * pdir_base;
-	int pdir_size, iov_order;
-
-	/*
-	** 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
-	** own.  Next best thing would be to guess how much DMA
-	** can be outstanding based on PCI Class/sub-class. Both
-	** methods still require some "extra" to support PCI
-	** Hot-Plug/Removal of PCI cards. (aka PCI OLARD).
-	**
-	** While we have 32-bits "IOVA" space, top two 2 bits are used
-	** for DMA hints - ergo only 30 bits max.
-	*/
-	/* limit IOVA space size to 1MB-1GB */
-	if (mem_max < (sba_mem_ratio*1024*1024)) {
-		iova_space_size = 1024*1024;
-#ifdef __LP64__
-	} else if (mem_max > (sba_mem_ratio*512*1024*1024)) {
-		iova_space_size = 512*1024*1024;
-#endif
-	} else {
-		iova_space_size = (u32) (mem_max/sba_mem_ratio);
-	}
-
-	/*
-	** iova space must be log2() in size.
-	** thus, pdir/res_map will also be log2().
-	*/
-	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);
-
-	ioc->pdir_size = pdir_size = (iova_space_size/IOVP_SIZE) * sizeof(u64);
-
-	ASSERT(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));
-
-	DBG_INIT("%s() hpa 0x%p mem %dMBIOV %dMB (%d bits) PDIR size 0x%0x",
-		__FUNCTION__, ioc->ioc_hpa, (int) (mem_max>>20),
-		iova_space_size>>20, iov_order + PAGE_SHIFT, pdir_size);
-
-	/* FIXME : DMA HINTs not used */
-	ioc->hint_shift_pdir = iov_order + PAGE_SHIFT;
-	ioc->hint_mask_pdir = ~(0x3 << (iov_order + PAGE_SHIFT));
-
-	ioc->pdir_base =
-	pdir_base = (void *) __get_free_pages(GFP_KERNEL, get_order(pdir_size));
-	if (NULL == pdir_base)
-	{
-		panic(__FILE__ ":%s() could not allocate I/O Page Table\n", __FUNCTION__);
-	}
-	memset(pdir_base, 0, pdir_size);
-
-	DBG_INIT("sba_ioc_init() pdir %p size %x hint_shift_pdir %x hint_mask_pdir %lx\n",
-		pdir_base, pdir_size,
-		ioc->hint_shift_pdir, ioc->hint_mask_pdir);
-
-	ASSERT((((unsigned long) pdir_base) & PAGE_MASK) == (unsigned long) pdir_base);
-	WRITE_REG64(virt_to_phys(pdir_base), (u64 *)(ioc->ioc_hpa+IOC_PDIR_BASE));
-
-	DBG_INIT(" base %p\n", pdir_base);
-
-	/* build IMASK for IOC and Elroy */
-	iova_space_mask =  0xffffffff;
-	iova_space_mask <<= (iov_order + PAGE_SHIFT);
-
-	/*
-	** On C3000 w/512MB mem, HP-UX 10.20 reports:
-	**     ibase=0, imask=0xFE000000, size=0x2000000.
-	*/
-	ioc->ibase = IOC_IOVA_SPACE_BASE | 1;	/* bit 0 == enable bit */
-	ioc->imask = iova_space_mask;	/* save it */
-
-	DBG_INIT("%s() IOV base 0x%lx mask 0x%0lx\n", __FUNCTION__,
-		ioc->ibase, ioc->imask);
-
-	/*
-	** FIXME: Hint registers are programmed with default hint
-	** values during boot, so hints should be sane even if we
-	** can't reprogram them the way drivers want.
-	*/
-
-	/*
-	** setup Elroy IBASE/IMASK registers as well.
-	*/
-	lba_init_iregs(ioc->ioc_hpa, ioc->ibase, ioc->imask);
-
-	/*
-	** Program the IOC's ibase and enable IOVA translation
-	*/
-	WRITE_REG32(ioc->ibase, ioc->ioc_hpa+IOC_IBASE);
-	WRITE_REG32(ioc->imask, ioc->ioc_hpa+IOC_IMASK);
-
-	/* Set I/O PDIR Page size to 4K */
-	WRITE_REG32(0, ioc->ioc_hpa+IOC_TCNFG);
-
-	/*
-	** Clear I/O TLB of any possible entries.
-	** (Yes. This is a it paranoid...but so what)
-	*/
-	WRITE_REG32(0 | 31, ioc->ioc_hpa+IOC_PCOM);
-
-	DBG_INIT("%s() DONE\n", __FUNCTION__);
-}
-
-
-
-/**************************************************************************
-**
-**   SBA initialization code (HW and SW)
-**
-**   o identify SBA chip itself
-**   o initialize SBA chip modes (HardFail)
-**   o initialize SBA chip modes (HardFail)
-**   o FIXME: initialize DMA hints for reasonable defaults
-**
-**************************************************************************/
-
-static void
-sba_hw_init(struct sba_device *sba_dev)
-{ 
-	int i;
-	int num_ioc;
-	u32 ioc_ctl;
-
-	ioc_ctl = READ_REG32(sba_dev->sba_hpa+IOC_CTRL);
-	DBG_INIT("%s() hpa 0x%p ioc_ctl 0x%x ->", __FUNCTION__, sba_dev->sba_hpa, ioc_ctl );
-	ioc_ctl &= ~(IOC_CTRL_RM | IOC_CTRL_NC);
-	ASSERT(ioc_ctl & IOC_CTRL_TE);	/* astro: firmware enables this */
-
-	WRITE_REG32(ioc_ctl, sba_dev->sba_hpa+IOC_CTRL);
-
-#ifdef SBA_DEBUG_INIT
-	ioc_ctl = READ_REG32(sba_dev->sba_hpa+IOC_CTRL);
-	DBG_INIT(" 0x%x\n", ioc_ctl );
-#endif
-
-	if (IS_ASTRO(sba_dev->iodc)) {
-		/* PAT_PDC (L-class) also reports the same goofy base */
-		sba_dev->ioc[0].ioc_hpa = (char *) ASTRO_IOC_OFFSET;
-		num_ioc = 1;
-	} else {
-		sba_dev->ioc[0].ioc_hpa = sba_dev->ioc[1].ioc_hpa = 0;
-		num_ioc = 2;
-	}
-
-	sba_dev->num_ioc = num_ioc;
-	for( i = 0; i < num_ioc; i++)
-	{
-		(unsigned long) sba_dev->ioc[i].ioc_hpa += (unsigned long) sba_dev->sba_hpa + IKE_IOC_OFFSET(i);
-
-		/*
-		** Make sure the box crashes if we get any errors on a rope.
-		*/
-		WRITE_REG32(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE0_CTL);
-		WRITE_REG32(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE1_CTL);
-		WRITE_REG32(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE2_CTL);
-		WRITE_REG32(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE3_CTL);
-		WRITE_REG32(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE4_CTL);
-		WRITE_REG32(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE5_CTL);
-		WRITE_REG32(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE6_CTL);
-		WRITE_REG32(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE7_CTL);
-
-		/* flush out the writes */
-		READ_REG32(sba_dev->ioc[i].ioc_hpa + ROPE7_CTL);
-
-		sba_ioc_init(&(sba_dev->ioc[i]));
-	}
-}
-
-static void
-sba_common_init(struct sba_device *sba_dev)
-{
-	int i;
-
-	/* add this one to the head of the list (order doesn't matter)
-	** This will be useful for debugging - especially if we get coredumps
-	*/
-	sba_dev->next = sba_list;
-	sba_list = sba_dev;
-	sba_count++;
-
-	for(i=0; i< sba_dev->num_ioc; i++) {
-		int res_size;
-#ifdef CONFIG_DMB_TRAP
-		extern void iterate_pages(unsigned long , unsigned long ,
-					  void (*)(pte_t * , unsigned long),
-					  unsigned long );
-		void set_data_memory_break(pte_t * , unsigned long);
-#endif
-		/* resource map size dictated by pdir_size */
-		res_size = sba_dev->ioc[i].pdir_size/sizeof(u64); /* entries */
-		res_size >>= 3;  /* convert bit count to byte count */
-		DBG_INIT("%s() res_size 0x%x\n", __FUNCTION__, res_size);
-
-		sba_dev->ioc[i].res_size = res_size;
-		sba_dev->ioc[i].res_map = (char *) __get_free_pages(GFP_KERNEL, get_order(res_size));
-
-#ifdef CONFIG_DMB_TRAP
-		iterate_pages( sba_dev->ioc[i].res_map, res_size,
-				set_data_memory_break, 0);
-#endif
-
-		if (NULL == sba_dev->ioc[i].res_map)
-		{
-			panic(__FILE__ ":%s() could not allocate resource map\n", __FUNCTION__ );
-		}
-
-		memset(sba_dev->ioc[i].res_map, 0, res_size);
-		/* next available IOVP - circular search */
-		sba_dev->ioc[i].res_hint = (unsigned long *)
-				&(sba_dev->ioc[i].res_map[L1_CACHE_BYTES]);
-
-#ifdef ASSERT_PDIR_SANITY
-		/* Mark first bit busy - ie no IOVA 0 */
-		sba_dev->ioc[i].res_map[0] = 0x80;
-		sba_dev->ioc[i].pdir_base[0] = 0xeeffc0addbba0080ULL;
-#endif
-
-#ifdef CONFIG_DMB_TRAP
-		iterate_pages( sba_dev->ioc[i].res_map, res_size,
-				set_data_memory_break, 0);
-		iterate_pages( sba_dev->ioc[i].pdir_base, sba_dev->ioc[i].pdir_size,
-				set_data_memory_break, 0);
-#endif
-
-		DBG_INIT("sba_common_init() %d res_map %x %p\n",
-					i, res_size, sba_dev->ioc[i].res_map);
-	}
-
-	sba_dev->sba_lock = SPIN_LOCK_UNLOCKED;
-}
-
-#ifdef CONFIG_PROC_FS
-static int sba_proc_info(char *buf, char **start, off_t offset, int len)
-{
-	struct sba_device *sba_dev = sba_list;
-/* FIXME: Multi-IOC support broken! */
-	struct ioc *ioc = &sba_dev->ioc[0];
-	int total_pages = (int) (ioc->res_size << 3); /* 8 bits per byte */
-	unsigned long i = 0, avg = 0, min, max;
-
-	sprintf(buf, "%s rev %d.%d\n",
-		parisc_getHWdescription(sba_dev->iodc->hw_type,
-			sba_dev->iodc->hversion, sba_dev->iodc->sversion),
-		(sba_dev->hw_rev & 0x7) + 1,
-		(sba_dev->hw_rev & 0x18) >> 3
-		);
-	sprintf(buf, "%sIO PDIR size    : %d bytes (%d entries)\n",
-		buf,
-		((ioc->res_size << 3) * sizeof(u64)), /* 8 bits per byte */
-		total_pages);                  /* 8 bits per byte */
-
-	sprintf(buf, "%sIO PDIR entries : %ld free  %ld used (%d%%)\n", buf,
-		total_pages - ioc->used_pages, ioc->used_pages,
-		(int) (ioc->used_pages * 100 / total_pages));
-	
-	sprintf(buf, "%sResource bitmap : %d bytes (%d pages)\n", 
-		buf, ioc->res_size, ioc->res_size << 3);   /* 8 bits per byte */
-
-	min = max = ioc->avg_search[0];
-	for (i = 0; i < SBA_SEARCH_SAMPLE; i++) {
-		avg += ioc->avg_search[i];
-		if (ioc->avg_search[i] > max) max = ioc->avg_search[i];
-		if (ioc->avg_search[i] < min) min = ioc->avg_search[i];
-	}
-	avg /= SBA_SEARCH_SAMPLE;
-	sprintf(buf, "%s  Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n",
-		buf, min, avg, max);
-
-	sprintf(buf, "%spci_map_single(): %8ld calls  %8ld pages (avg %d/1000)\n",
-		buf, ioc->msingle_calls, ioc->msingle_pages,
-		(int) ((ioc->msingle_pages * 1000)/ioc->msingle_calls));
-
-	/* KLUGE - unmap_sg calls unmap_single for each mapped page */
-	min = ioc->usingle_calls - ioc->usg_calls;
-	max = ioc->usingle_pages - ioc->usg_pages;
-	sprintf(buf, "%spci_unmap_single: %8ld calls  %8ld pages (avg %d/1000)\n",
-		buf, min, max,
-		(int) ((max * 1000)/min));
-
-	sprintf(buf, "%spci_map_sg()    : %8ld calls  %8ld pages (avg %d/1000)\n",
-		buf, ioc->msg_calls, ioc->msg_pages,
-		(int) ((ioc->msg_pages * 1000)/ioc->msg_calls));
-
-	sprintf(buf, "%spci_unmap_sg()  : %8ld calls  %8ld pages (avg %d/1000)\n",
-		buf, ioc->usg_calls, ioc->usg_pages,
-		(int) ((ioc->usg_pages * 1000)/ioc->usg_calls));
-
-	return strlen(buf);
-}
-
-static int
-sba_resource_map(char *buf, char **start, off_t offset, int len)
-{
-	struct sba_device *sba_dev = sba_list;
-	struct ioc *ioc = &sba_dev->ioc[0];
-	unsigned long *res_ptr = (unsigned long *)ioc->res_map;
-	int i;
-
-	for(i = 0; i < (ioc->res_size / sizeof(unsigned long)); ++i, ++res_ptr) {
-		if ((i & 7) == 0)
-		    strcat(buf,"\n   ");
-		sprintf(buf, "%s %08lx", buf, *res_ptr);
-	}
-	strcat(buf, "\n");
-
-	return strlen(buf);
-}
-#endif
-
-/*
-** Determine if lba 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.
-*/
-int
-sba_driver_callback(struct hp_device *d, struct pa_iodc_driver *dri)
-{
-	struct sba_device *sba_dev;
-	u32 func_class;
-	int i;
-
-	if (IS_ASTRO(d)) {
-		static char astro_rev[]="Astro ?.?";
-
-		/* Read HW Rev First */
-		func_class = READ_REG32(d->hpa);
-
-		astro_rev[6] = '1' + (char) (func_class & 0x7);
-		astro_rev[8] = '0' + (char) ((func_class & 0x18) >> 3);
-		dri->version = astro_rev;
-	} else {
-		static char ike_rev[]="Ike rev ?";
-
-		/* Read HW Rev First */
-		func_class = READ_REG32(d->hpa + SBA_FCLASS);
-
-		ike_rev[8] = '0' + (char) (func_class & 0xff);
-		dri->version = ike_rev;
-	}
-
-	printk("%s found %s at 0x%p\n", dri->name, dri->version, d->hpa);
-
-	sba_dev = kmalloc(sizeof(struct sba_device), GFP_KERNEL);
-	if (NULL == sba_dev)
-	{
-		printk(MODULE_NAME " - couldn't alloc sba_device\n");
-		return(1);
-	}
-	memset(sba_dev, 0, sizeof(struct sba_device));
-	for(i=0; i<MAX_IOC; i++)
-		spin_lock_init(&(sba_dev->ioc[i].res_lock));
-
-
-	sba_dev->hw_rev = func_class;
-	sba_dev->iodc = d;
-	sba_dev->sba_hpa = d->hpa;  /* faster access */
-
-	sba_get_pat_resources(sba_dev);
-	sba_hw_init(sba_dev);
-	sba_common_init(sba_dev);
-
-	hppa_dma_ops = &sba_ops;
-
-#ifdef CONFIG_PROC_FS
-	if (IS_ASTRO(d)) {
-		create_proc_info_entry("Astro", 0, proc_runway_root, sba_proc_info);
-	} else {
-		create_proc_info_entry("Ike", 0, proc_runway_root, sba_proc_info);
-	}
-	create_proc_info_entry("bitmap", 0, proc_runway_root, sba_resource_map);
-#endif
-	return 0;
-}
diff -Nru a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c
--- a/arch/parisc/kernel/setup.c	Mon Nov  4 14:31:02 2002
+++ b/arch/parisc/kernel/setup.c	Mon Nov  4 14:31:02 2002
@@ -143,10 +143,8 @@
 	dma_ops_init();
 #endif
 
-#ifdef CONFIG_VT
-# if defined(CONFIG_STI_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
+#ifdef CONFIG_DUMMY_CONSOLE
         conswitchp = &dummy_con;        /* we use take_over_console() later ! */
-# endif
 #endif
 
 }
diff -Nru a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
--- a/arch/parisc/kernel/sys_parisc.c	Mon Nov  4 14:31:02 2002
+++ b/arch/parisc/kernel/sys_parisc.c	Mon Nov  4 14:31:02 2002
@@ -147,6 +147,40 @@
 }
 
 
+/* Fucking broken ABI */
+
+extern asmlinkage long sys_truncate64(const char *, loff_t);
+extern asmlinkage long sys_ftruncate64(unsigned int, loff_t);
+extern asmlinkage ssize_t sys_pread64(unsigned int fd, char *buf,
+					size_t count, loff_t pos);
+extern asmlinkage ssize_t sys_pwrite64(unsigned int fd, const char *buf,
+					size_t count, loff_t pos);
+
+asmlinkage long parisc_truncate64(const char * path,
+					unsigned int high, unsigned int low)
+{
+	return sys_truncate(path, (loff_t)high << 32 | low);
+}
+
+asmlinkage long parisc_ftruncate64(unsigned int fd,
+					unsigned int high, unsigned int low)
+{
+	return sys_ftruncate(fd, (loff_t)high << 32 | low);
+}
+
+asmlinkage ssize_t parisc_pread64(unsigned int fd, char *buf, size_t count,
+					unsigned int high, unsigned int low)
+{
+	return sys_pread64(fd, buf, count, (loff_t)high << 32 | low);
+}
+
+asmlinkage ssize_t parisc_pwrite64(unsigned int fd, const char *buf,
+			size_t count, unsigned int high, unsigned int low)
+{
+	return sys_pwrite64(fd, buf, count, (loff_t)high << 32 | low);
+}
+
+
 /*
  * FIXME, please remove this crap as soon as possible
  *
diff -Nru a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c
--- a/arch/parisc/kernel/sys_parisc32.c	Mon Nov  4 14:31:01 2002
+++ b/arch/parisc/kernel/sys_parisc32.c	Mon Nov  4 14:31:01 2002
@@ -2743,19 +2743,7 @@
 
 /* LFS */
 
-extern asmlinkage long sys_truncate(const char *, loff_t);
-extern asmlinkage long sys_ftruncate(unsigned int, loff_t);
 extern asmlinkage long sys_fcntl(unsigned int, unsigned int, unsigned long);
-
-asmlinkage long sys32_truncate64(const char * path, unsigned int high, unsigned int low)
-{
-	return sys_truncate(path, (loff_t)high << 32 | low);
-}
-
-asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned int high, unsigned int low)
-{
-	return sys_ftruncate(fd, (loff_t)high << 32 | low);
-}
 
 asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
diff -Nru a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
--- a/arch/parisc/kernel/syscall.S	Mon Nov  4 14:31:03 2002
+++ b/arch/parisc/kernel/syscall.S	Mon Nov  4 14:31:03 2002
@@ -331,10 +331,12 @@
 #define ENTRY_SAME(_name_) .dword sys_##_name_
 #define ENTRY_DIFF(_name_) .dword sys32_##_name_
 #define ENTRY_UHOH(_name_) .dword sys32_##unimplemented
+#define ENTRY_OURS(_name_) .dword parisc_##_name_
 #else
 #define ENTRY_SAME(_name_) .word sys_##_name_
 #define ENTRY_DIFF(_name_) .word sys_##_name_
 #define ENTRY_UHOH(_name_) .word sys_##_name_
+#define ENTRY_OURS(_name_) .word parisc_##_name_
 #endif
 
 	.align 8
@@ -398,7 +400,7 @@
 	/* struct sockaddr... */
 	ENTRY_SAME(getsockname)
 	/* it seems possible brk() could return a >4G pointer... */
-	ENTRY_SAME(brk)		/* 45 */
+	ENTRY_SAME(brk)			/* 45 */
 	ENTRY_SAME(setgid)
 	ENTRY_SAME(getgid)
 	ENTRY_SAME(signal)
@@ -476,8 +478,8 @@
 	ENTRY_DIFF(getitimer)	/* 105 */
 	ENTRY_SAME(capget)
 	ENTRY_SAME(capset)
-	ENTRY_SAME(pread64)
-	ENTRY_SAME(pwrite64)
+	ENTRY_OURS(pread64)
+	ENTRY_OURS(pwrite64)
 	ENTRY_SAME(getcwd)		/* 110 */
 	ENTRY_SAME(vhangup)
 	ENTRY_SAME(fstat64)
@@ -592,18 +594,18 @@
 	ENTRY_SAME(shmat_wrapper)
 	ENTRY_SAME(shmdt)
 	ENTRY_SAME(shmget)
-	ENTRY_SAME(shmctl_broken)		/* 195 */
+	ENTRY_SAME(shmctl_broken)	/* 195 */
 	ENTRY_SAME(ni_syscall)		/* streams1 */
 	ENTRY_SAME(ni_syscall)		/* streams2 */
 	ENTRY_SAME(lstat64)
-	ENTRY_DIFF(truncate64)
-	ENTRY_DIFF(ftruncate64)	/* 200 */
+	ENTRY_OURS(truncate64)
+	ENTRY_OURS(ftruncate64)		/* 200 */
 	ENTRY_SAME(getdents64)
 	ENTRY_DIFF(fcntl64)
 #ifdef CONFIG_XFS_FS
 	ENTRY_SAME(attrctl)
 	ENTRY_SAME(acl_get)
-	ENTRY_SAME(acl_set)            /* 205 */
+	ENTRY_SAME(acl_set)		/* 205 */
 #else
 	ENTRY_SAME(ni_syscall)
 	ENTRY_SAME(ni_syscall)
diff -Nru a/arch/parisc/lib/Makefile b/arch/parisc/lib/Makefile
--- a/arch/parisc/lib/Makefile	Mon Nov  4 14:31:02 2002
+++ b/arch/parisc/lib/Makefile	Mon Nov  4 14:31:02 2002
@@ -1,9 +1,5 @@
 #
-# Makefile for parisc-specific library files..
+# Makefile for parisc-specific library files
 #
 
-
-L_TARGET = lib.a
 obj-y	:= lusercopy.o bitops.o checksum.o io.o memset.o
-
-include $(TOPDIR)/Rules.make
diff -Nru a/arch/parisc/math-emu/Makefile b/arch/parisc/math-emu/Makefile
--- a/arch/parisc/math-emu/Makefile	Mon Nov  4 14:31:01 2002
+++ b/arch/parisc/math-emu/Makefile	Mon Nov  4 14:31:01 2002
@@ -1,11 +1,6 @@
 #
 # Makefile for the linux/parisc floating point code
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definition is now in the main makefile...
 
 obj-y	 := frnd.o driver.o decode_exc.o fpudispatch.o denormal.o \
 		dfmpy.o sfmpy.o sfsqrt.o dfsqrt.o dfadd.o fmpyfadd.o \
@@ -16,6 +11,4 @@
 # Math emulation code beyond the FRND is required for 712/80i and
 # other very old or stripped-down PA-RISC CPUs -- not currently supported
 
-obj-$CONFIG_MATH_EMULATION	+= unimplemented-math-emulation.o
-
-include $(TOPDIR)/Rules.make
+obj-$(CONFIG_MATH_EMULATION)	+= unimplemented-math-emulation.o
diff -Nru a/arch/parisc/mm/Makefile b/arch/parisc/mm/Makefile
--- a/arch/parisc/mm/Makefile	Mon Nov  4 14:31:02 2002
+++ b/arch/parisc/mm/Makefile	Mon Nov  4 14:31:02 2002
@@ -1,7 +1,5 @@
 #
-# Makefile for the linux parisc-specific parts of the memory manager.
+# Makefile for arch/parisc/mm
 #
 
 obj-y	 := init.o fault.o extable.o ioremap.o
-
-include $(TOPDIR)/Rules.make
diff -Nru a/arch/ppc/Kconfig b/arch/ppc/Kconfig
--- a/arch/ppc/Kconfig	Mon Nov  4 14:31:02 2002
+++ b/arch/ppc/Kconfig	Mon Nov  4 14:31:03 2002
@@ -1,6 +1,15 @@
 # For a description of the syntax of this configuration file,
 # see Documentation/kbuild/config-language.txt.
 #
+
+config MMU
+	bool
+	default y
+
+config SWAP
+	bool
+	default y
+
 config UID16
 	bool
 
diff -Nru a/arch/ppc/amiga/amiints.c b/arch/ppc/amiga/amiints.c
--- a/arch/ppc/amiga/amiints.c	Mon Nov  4 14:31:00 2002
+++ b/arch/ppc/amiga/amiints.c	Mon Nov  4 14:31:00 2002
@@ -189,7 +189,7 @@
 	irq_desc_t *desc = irq_desc + irq;
 	struct irqaction *action = desc->action;
 
-	kstat.irqs[0][irq]++;
+	kstat_cpu(0).irqs[irq]++;
 	action->handler(irq, action->dev_id, fp);
 }
 
@@ -198,7 +198,7 @@
 	irq_desc_t *desc = irq_desc + irq;
 	struct irqaction *action;
 
-	kstat.irqs[0][irq]++;
+	kstat_cpu(0).irqs[irq]++;
 
 	custom.intreq = ami_intena_vals[irq];
 
diff -Nru a/arch/ppc/amiga/cia.c b/arch/ppc/amiga/cia.c
--- a/arch/ppc/amiga/cia.c	Mon Nov  4 14:31:01 2002
+++ b/arch/ppc/amiga/cia.c	Mon Nov  4 14:31:01 2002
@@ -148,7 +148,7 @@
 	custom.intreq = base->int_mask;
 	for (i = 0; i < CIA_IRQS; i++, irq++) {
 		if (ints & 1) {
-			kstat.irqs[0][irq]++;
+			kstat_cpu(0).irqs[irq]++;
 			action = desc->action;
 			action->handler(irq, action->dev_id, fp);
 		}
diff -Nru a/arch/ppc/amiga/ints.c b/arch/ppc/amiga/ints.c
--- a/arch/ppc/amiga/ints.c	Mon Nov  4 14:31:00 2002
+++ b/arch/ppc/amiga/ints.c	Mon Nov  4 14:31:00 2002
@@ -130,7 +130,7 @@
 {
 	if (vec >= VEC_INT1 && vec <= VEC_INT7 && !MACH_IS_BVME6000) {
 		vec -= VEC_SPUR;
-		kstat.irqs[0][vec]++;
+		kstat_cpu(0).irqs[vec]++;
 		irq_list[vec].handler(vec, irq_list[vec].dev_id, fp);
 	} else {
 		if (mach_process_int)
@@ -149,7 +149,7 @@
 	if (mach_default_handler) {
 		for (i = 0; i < SYS_IRQS; i++) {
 			seq_printf(p, "auto %2d: %10u ", i,
-			               i ? kstat.irqs[0][i] : num_spurious);
+			               i ? kstat_cpu(0).irqs[i] : num_spurious);
 			seq_puts(p, "  ");
 			seq_printf(p, "%s\n", irq_list[i].devname);
 		}
diff -Nru a/arch/ppc/configs/apus_defconfig b/arch/ppc/configs/apus_defconfig
--- a/arch/ppc/configs/apus_defconfig	Mon Nov  4 14:31:02 2002
+++ b/arch/ppc/configs/apus_defconfig	Mon Nov  4 14:31:02 2002
@@ -73,7 +73,6 @@
 CONFIG_FB_CONSOLE=y
 CONFIG_AMIGA=y
 CONFIG_ZORRO=y
-CONFIG_AMIGAMOUSE=y
 CONFIG_ABSTRACT_CONSOLE=y
 CONFIG_FB=y
 CONFIG_MOUSE=y
diff -Nru a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c
--- a/arch/ppc/kernel/irq.c	Mon Nov  4 14:31:02 2002
+++ b/arch/ppc/kernel/irq.c	Mon Nov  4 14:31:02 2002
@@ -362,7 +362,7 @@
 		for (j = 0; j < NR_CPUS; j++)
 			if (cpu_online(j))
 				seq_printf(p, "%10u ",
-					   kstat.irqs[j][i]);
+					   kstat_cpu(j).irqs[i]);
 #else		
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #endif /* CONFIG_SMP */
@@ -423,7 +423,7 @@
 	int cpu = smp_processor_id();
 	irq_desc_t *desc = irq_desc + irq;
 
-	kstat.irqs[cpu][irq]++;
+	kstat_cpu(cpu).irqs[irq]++;
 	spin_lock(&desc->lock);
 	ack_irq(irq);	
 	/*
diff -Nru a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
--- a/arch/ppc/kernel/misc.S	Mon Nov  4 14:31:02 2002
+++ b/arch/ppc/kernel/misc.S	Mon Nov  4 14:31:02 2002
@@ -1005,6 +1005,7 @@
 	mr	r30,r3		/* function */
 	mr	r31,r4		/* argument */
 	ori	r3,r5,CLONE_VM	/* flags */
+	oris	r3,r3,CLONE_UNTRACED>>16
 	li	r0,__NR_clone
 	sc
 	cmpi	0,r3,0		/* parent or child? */
diff -Nru a/arch/ppc/kernel/ptrace.c b/arch/ppc/kernel/ptrace.c
--- a/arch/ppc/kernel/ptrace.c	Mon Nov  4 14:31:01 2002
+++ b/arch/ppc/kernel/ptrace.c	Mon Nov  4 14:31:01 2002
@@ -339,7 +339,7 @@
 #endif
 
 	default:
-		ret = -EIO;
+		ret = ptrace_request(child, request, addr, data);
 		break;
 	}
 out_tsk:
@@ -354,7 +354,8 @@
         if (!test_thread_flag(TIF_SYSCALL_TRACE)
 	    || !(current->ptrace & PT_PTRACED))
 		return;
-	current->exit_code = SIGTRAP;
+	current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+					? 0x80 : 0);
 	current->state = TASK_STOPPED;
 	notify_parent(current, SIGCHLD);
 	schedule();
diff -Nru a/arch/ppc/platforms/mcpn765_setup.c b/arch/ppc/platforms/mcpn765_setup.c
--- a/arch/ppc/platforms/mcpn765_setup.c	Mon Nov  4 14:31:02 2002
+++ b/arch/ppc/platforms/mcpn765_setup.c	Mon Nov  4 14:31:02 2002
@@ -154,9 +154,9 @@
 	 * PPCBug doesn't set the enable bits for the IDE device.
 	 * Turn them on now.
 	 */
-	pcibios_read_config_byte(dev->bus->number, dev->devfn, 0x40, &c);
+	pci_read_config_byte(dev, 0x40, &c);
 	c |= 0x03;
-	pcibios_write_config_byte(dev->bus->number, dev->devfn, 0x40, c);
+	pci_write_config_byte(dev, 0x40, c);
 
 	return;
 }
diff -Nru a/arch/ppc/platforms/prep_pci.c b/arch/ppc/platforms/prep_pci.c
--- a/arch/ppc/platforms/prep_pci.c	Mon Nov  4 14:31:02 2002
+++ b/arch/ppc/platforms/prep_pci.c	Mon Nov  4 14:31:02 2002
@@ -1089,8 +1089,7 @@
 	devnum = PCI_SLOT(tdev->devfn);
 
 	/* Read the interrupt pin of the device and adjust for indexing */
-	pcibios_read_config_byte(dev->bus->number, dev->devfn,
-			PCI_INTERRUPT_PIN, &intpin);
+	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &intpin);
 
 	/* If device doesn't request an interrupt, return */
 	if ( (intpin < 1) || (intpin > 4) )
@@ -1162,7 +1161,7 @@
 		pci_for_each_dev(dev) {
 			if (dev->bus->number == 0) {
                        		dev->irq = openpic_to_irq(Motherboard_map[PCI_SLOT(dev->devfn)]);
-				pcibios_write_config_byte(dev->bus->number, dev->devfn, PCI_INTERRUPT_LINE, dev->irq);
+				pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
 			} else {
 				if (Motherboard_non0 != NULL)
 					Motherboard_non0(dev);
diff -Nru a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
--- a/arch/ppc64/Kconfig	Mon Nov  4 14:31:02 2002
+++ b/arch/ppc64/Kconfig	Mon Nov  4 14:31:02 2002
@@ -2,6 +2,15 @@
 # For a description of the syntax of this configuration file,
 # see Documentation/kbuild/config-language.txt.
 #
+
+config MMU
+	bool
+	default y
+
+config SWAP
+	bool
+	default y
+
 config UID16
 	bool
 
diff -Nru a/arch/ppc64/kernel/asm-offsets.c b/arch/ppc64/kernel/asm-offsets.c
--- a/arch/ppc64/kernel/asm-offsets.c	Mon Nov  4 14:31:02 2002
+++ b/arch/ppc64/kernel/asm-offsets.c	Mon Nov  4 14:31:02 2002
@@ -157,6 +157,7 @@
 	DEFINE(_SRR1, STACK_FRAME_OVERHEAD+sizeof(struct pt_regs)+8);
 
 	DEFINE(CLONE_VM, CLONE_VM);
+	DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
 
 	return 0;
 }
diff -Nru a/arch/ppc64/kernel/ioctl32.c b/arch/ppc64/kernel/ioctl32.c
--- a/arch/ppc64/kernel/ioctl32.c	Mon Nov  4 14:31:03 2002
+++ b/arch/ppc64/kernel/ioctl32.c	Mon Nov  4 14:31:03 2002
@@ -66,6 +66,7 @@
 #if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
 #include <linux/lvm.h>
 #endif /* LVM */
+#include <linux/dm-ioctl.h>
 
 #include <scsi/scsi.h>
 /* Ugly hack. */
@@ -4402,6 +4403,18 @@
 COMPATIBLE_IOCTL(NBD_PRINT_DEBUG),
 COMPATIBLE_IOCTL(NBD_SET_SIZE_BLOCKS),
 COMPATIBLE_IOCTL(NBD_DISCONNECT),
+/* device-mapper */
+COMPATIBLE_IOCTL(DM_VERSION),
+COMPATIBLE_IOCTL(DM_REMOVE_ALL),
+COMPATIBLE_IOCTL(DM_DEV_CREATE),
+COMPATIBLE_IOCTL(DM_DEV_REMOVE),
+COMPATIBLE_IOCTL(DM_DEV_RELOAD),
+COMPATIBLE_IOCTL(DM_DEV_SUSPEND),
+COMPATIBLE_IOCTL(DM_DEV_RENAME),
+COMPATIBLE_IOCTL(DM_DEV_DEPS),
+COMPATIBLE_IOCTL(DM_DEV_STATUS),
+COMPATIBLE_IOCTL(DM_TARGET_STATUS),
+COMPATIBLE_IOCTL(DM_TARGET_WAIT),
 /* And these ioctls need translation */
 HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob),
 HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob),
diff -Nru a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c
--- a/arch/ppc64/kernel/irq.c	Mon Nov  4 14:31:01 2002
+++ b/arch/ppc64/kernel/irq.c	Mon Nov  4 14:31:01 2002
@@ -357,7 +357,7 @@
 #ifdef CONFIG_SMP
 		for (j = 0; j < NR_CPUS; j++) {
 			if (cpu_online(j))
-				seq_printf(p, "%10u ", kstat.irqs[j][i]);
+				seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
 		}
 #else		
 		seq_printf(p, "%10u ", kstat_irqs(i));
@@ -484,7 +484,7 @@
 	if (naca->interrupt_controller == IC_OPEN_PIC)
 		balance_irq(irq);
 
-	kstat.irqs[cpu][irq]++;
+	kstat_cpu(cpu).irqs[irq]++;
 	spin_lock(&desc->lock);
 	ack_irq(irq);	
 	/*
diff -Nru a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
--- a/arch/ppc64/kernel/misc.S	Mon Nov  4 14:31:01 2002
+++ b/arch/ppc64/kernel/misc.S	Mon Nov  4 14:31:01 2002
@@ -486,6 +486,7 @@
 	/* XXX fix this when we optimise syscall entry to not save volatiles */
 	mr	r6,r3		/* function */
 	ori	r3,r5,CLONE_VM	/* flags */
+	oris	r3,r3,(CLONE_UNTRACED>>16)
 	li	r0,__NR_clone
 	sc
 	cmpi	0,r3,0		/* parent or child? */
diff -Nru a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c
--- a/arch/ppc64/kernel/ptrace.c	Mon Nov  4 14:31:01 2002
+++ b/arch/ppc64/kernel/ptrace.c	Mon Nov  4 14:31:01 2002
@@ -276,7 +276,7 @@
 	}
 
 	default:
-		ret = -EIO;
+		ret = ptrace_request(child, request, addr, data);
 		break;
 	}
 out_tsk:
@@ -292,7 +292,8 @@
 		return;
 	if (!(current->ptrace & PT_PTRACED))
 		return;
-	current->exit_code = SIGTRAP;
+	current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+					? 0x80 : 0);
 	current->state = TASK_STOPPED;
 	notify_parent(current, SIGCHLD);
 	schedule();
diff -Nru a/arch/ppc64/kernel/ptrace32.c b/arch/ppc64/kernel/ptrace32.c
--- a/arch/ppc64/kernel/ptrace32.c	Mon Nov  4 14:31:02 2002
+++ b/arch/ppc64/kernel/ptrace32.c	Mon Nov  4 14:31:02 2002
@@ -413,7 +413,7 @@
 
 
 	default:
-		ret = -EIO;
+		ret = ptrace_request(child, request, addr, data);
 		break;
 	}
 out_tsk:
diff -Nru a/arch/s390/Kconfig b/arch/s390/Kconfig
--- a/arch/s390/Kconfig	Mon Nov  4 14:31:01 2002
+++ b/arch/s390/Kconfig	Mon Nov  4 14:31:01 2002
@@ -2,6 +2,15 @@
 # For a description of the syntax of this configuration file,
 # see Documentation/kbuild/config-language.txt.
 #
+
+config MMU
+	bool
+	default y
+
+config SWAP
+	bool
+	default y
+
 config ISA
 	bool
 	help
diff -Nru a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
--- a/arch/s390/kernel/process.c	Mon Nov  4 14:31:02 2002
+++ b/arch/s390/kernel/process.c	Mon Nov  4 14:31:02 2002
@@ -146,7 +146,7 @@
 	regs.orig_gpr2 = -1;
 
 	/* Ok, create the new process.. */
-	p = do_fork(flags | CLONE_VM, 0, &regs, 0, NULL);
+	p = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL);
 	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
diff -Nru a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
--- a/arch/s390/kernel/ptrace.c	Mon Nov  4 14:31:02 2002
+++ b/arch/s390/kernel/ptrace.c	Mon Nov  4 14:31:02 2002
@@ -307,15 +307,8 @@
 			copied += sizeof(unsigned long);
 		}
 		return 0;
-
-	case PTRACE_SETOPTIONS:
-		if (data & PTRACE_O_TRACESYSGOOD)
-			child->ptrace |= PT_TRACESYSGOOD;
-		else
-			child->ptrace &= ~PT_TRACESYSGOOD;
-		return 0;
 	}
-	return -EIO;
+	return ptrace_request(child, request, addr, data);
 }
 
 asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
diff -Nru a/arch/s390x/Kconfig b/arch/s390x/Kconfig
--- a/arch/s390x/Kconfig	Mon Nov  4 14:31:02 2002
+++ b/arch/s390x/Kconfig	Mon Nov  4 14:31:02 2002
@@ -2,6 +2,15 @@
 # For a description of the syntax of this configuration file,
 # see Documentation/kbuild/config-language.txt.
 #
+
+config MMU
+	bool
+	default y
+
+config SWAP
+	bool
+	default y
+
 config ISA
 	bool
 	help
diff -Nru a/arch/s390x/kernel/ioctl32.c b/arch/s390x/kernel/ioctl32.c
--- a/arch/s390x/kernel/ioctl32.c	Mon Nov  4 14:31:02 2002
+++ b/arch/s390x/kernel/ioctl32.c	Mon Nov  4 14:31:02 2002
@@ -27,6 +27,7 @@
 #include <linux/if_bonding.h>
 #include <linux/blkpg.h>
 #include <linux/blk.h>
+#include <linux/dm-ioctl.h>
 #include <linux/loop.h>
 #include <linux/elevator.h>
 #include <asm/types.h>
@@ -896,6 +897,18 @@
 	IOCTL32_DEFAULT(VT_UNLOCKSWITCH),
 
 	IOCTL32_DEFAULT(SIOCGSTAMP),
+
+	IOCTL32_DEFAULT(DM_VERSION),
+	IOCTL32_DEFAULT(DM_REMOVE_ALL),
+	IOCTL32_DEFAULT(DM_DEV_CREATE),
+	IOCTL32_DEFAULT(DM_DEV_REMOVE),
+	IOCTL32_DEFAULT(DM_DEV_RELOAD),
+	IOCTL32_DEFAULT(DM_DEV_SUSPEND),
+	IOCTL32_DEFAULT(DM_DEV_RENAME),
+	IOCTL32_DEFAULT(DM_DEV_DEPS),
+	IOCTL32_DEFAULT(DM_DEV_STATUS),
+	IOCTL32_DEFAULT(DM_TARGET_STATUS),
+	IOCTL32_DEFAULT(DM_TARGET_WAIT),
 
 	IOCTL32_DEFAULT(LOOP_SET_FD),
 	IOCTL32_DEFAULT(LOOP_CLR_FD),
diff -Nru a/arch/s390x/kernel/process.c b/arch/s390x/kernel/process.c
--- a/arch/s390x/kernel/process.c	Mon Nov  4 14:31:02 2002
+++ b/arch/s390x/kernel/process.c	Mon Nov  4 14:31:02 2002
@@ -143,7 +143,7 @@
 	regs.orig_gpr2 = -1;
 
 	/* Ok, create the new process.. */
-	p = do_fork(flags | CLONE_VM, 0, &regs, 0, NULL);
+	p = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL);
 	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
diff -Nru a/arch/s390x/kernel/ptrace.c b/arch/s390x/kernel/ptrace.c
--- a/arch/s390x/kernel/ptrace.c	Mon Nov  4 14:31:00 2002
+++ b/arch/s390x/kernel/ptrace.c	Mon Nov  4 14:31:00 2002
@@ -261,7 +261,7 @@
 		}
 		return 0;
 	}
-	return -EIO;
+	return ptrace_request(child, request, addr, data);
 }
 
 #ifdef CONFIG_S390_SUPPORT
@@ -469,7 +469,7 @@
 		}
 		return 0;
 	}
-	return -EIO;
+	return ptrace_request(child, request, addr, data);
 }
 #endif
 
@@ -538,12 +538,6 @@
 		/* detach a process that was attached. */
 		return ptrace_detach(child, data);
 
-	case PTRACE_SETOPTIONS:
-		if (data & PTRACE_O_TRACESYSGOOD)
-			child->ptrace |= PT_TRACESYSGOOD;
-		else
-			child->ptrace &= ~PT_TRACESYSGOOD;
-		return 0;
 	/* Do requests that differ for 31/64 bit */
 	default:
 #ifdef CONFIG_S390_SUPPORT
@@ -551,8 +545,8 @@
 			return do_ptrace_emu31(child, request, addr, data);
 #endif
 		return do_ptrace_normal(child, request, addr, data);
-		
 	}
+	/* Not reached.  */
 	return -EIO;
 }
 
diff -Nru a/arch/sh/Kconfig b/arch/sh/Kconfig
--- a/arch/sh/Kconfig	Mon Nov  4 14:31:03 2002
+++ b/arch/sh/Kconfig	Mon Nov  4 14:31:03 2002
@@ -14,6 +14,14 @@
 	  gaming console.  The SuperH port has a home page at
 	  <http://www.sh-linux.org/>.
 
+config MMU
+	bool
+	default y
+
+config SWAP
+	bool
+	default y
+
 config UID16
 	bool
 	default y
diff -Nru a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
--- a/arch/sh/kernel/irq.c	Mon Nov  4 14:31:01 2002
+++ b/arch/sh/kernel/irq.c	Mon Nov  4 14:31:01 2002
@@ -239,7 +239,7 @@
 		     :"=z" (irq));
 	irq = irq_demux(irq);
 
-	kstat.irqs[cpu][irq]++;
+	kstat_cpu(cpu).irqs[irq]++;
 	desc = irq_desc + irq;
 	spin_lock(&desc->lock);
 	desc->handler->ack(irq);
diff -Nru a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
--- a/arch/sh/kernel/process.c	Mon Nov  4 14:31:02 2002
+++ b/arch/sh/kernel/process.c	Mon Nov  4 14:31:02 2002
@@ -120,7 +120,7 @@
 {	/* Don't use this in BL=1(cli).  Or else, CPU resets! */
 	register unsigned long __sc0 __asm__ ("r0");
 	register unsigned long __sc3 __asm__ ("r3") = __NR_clone;
-	register unsigned long __sc4 __asm__ ("r4") = (long) flags | CLONE_VM;
+	register unsigned long __sc4 __asm__ ("r4") = (long) flags | CLONE_VM | CLONE_UNTRACED;
 	register unsigned long __sc5 __asm__ ("r5") = 0;
 	register unsigned long __sc8 __asm__ ("r8") = (long) arg;
 	register unsigned long __sc9 __asm__ ("r9") = (long) fn;
diff -Nru a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
--- a/arch/sh/kernel/ptrace.c	Mon Nov  4 14:31:00 2002
+++ b/arch/sh/kernel/ptrace.c	Mon Nov  4 14:31:00 2002
@@ -356,17 +356,8 @@
 		ret = ptrace_detach(child, data);
 		break;
 
-	case PTRACE_SETOPTIONS: {
-		if (data & PTRACE_O_TRACESYSGOOD)
-			child->ptrace |= PT_TRACESYSGOOD;
-		else
-			child->ptrace &= ~PT_TRACESYSGOOD;
-		ret = 0;
-		break;
-	}
-
 	default:
-		ret = -EIO;
+		ret = ptrace_request(child, request, addr, data);
 		break;
 	}
 out_tsk:
diff -Nru a/arch/sparc/Kconfig b/arch/sparc/Kconfig
--- a/arch/sparc/Kconfig	Mon Nov  4 14:31:00 2002
+++ b/arch/sparc/Kconfig	Mon Nov  4 14:31:00 2002
@@ -5,6 +5,14 @@
 
 mainmenu "Linux/SPARC Kernel Configuration"
 
+config MMU
+	bool
+	default y
+
+config SWAP
+	bool
+	default y
+
 config UID16
 	bool
 	default y
diff -Nru a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c
--- a/arch/sparc/kernel/irq.c	Mon Nov  4 14:31:00 2002
+++ b/arch/sparc/kernel/irq.c	Mon Nov  4 14:31:00 2002
@@ -124,7 +124,7 @@
 		for (j = 0; j < NR_CPUS; j++) {
 			if (cpu_online(j))
 				seq_printf(p, "%10u ",
-				    kstat.irqs[cpu_logical_map(j)][i]);
+				    kstat_cpu(cpu_logical_map(j)).irqs[i]);
 		}
 #endif
 		seq_printf(p, " %c %s",
@@ -424,7 +424,7 @@
 		smp4m_irq_rotate(cpu);
 #endif
 	action = *(irq + irq_action);
-	kstat.irqs[cpu][irq]++;
+	kstat_cpu(cpu).irqs[irq]++;
 	do {
 		if (!action || !action->handler)
 			unexpected_irq(irq, 0, regs);
@@ -444,7 +444,7 @@
 
 	disable_pil_irq(irq);
 	irq_enter();
-	kstat.irqs[cpu][irq]++;
+	kstat_cpu(cpu).irqs[irq]++;
 	floppy_interrupt(irq, dev_id, regs);
 	irq_exit();
 	enable_pil_irq(irq);
diff -Nru a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
--- a/arch/sparc/kernel/process.c	Mon Nov  4 14:31:01 2002
+++ b/arch/sparc/kernel/process.c	Mon Nov  4 14:31:01 2002
@@ -726,7 +726,7 @@
 			   /* Notreached by child. */
 			   "1: mov %%o0, %0\n\t" :
 			   "=r" (retval) :
-			   "i" (__NR_clone), "r" (flags | CLONE_VM),
+			   "i" (__NR_clone), "r" (flags | CLONE_VM | CLONE_UNTRACED),
 			   "i" (__NR_exit),  "r" (fn), "r" (arg) :
 			   "g1", "g2", "g3", "o0", "o1", "memory", "cc");
 	return retval;
diff -Nru a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c
--- a/arch/sparc/kernel/ptrace.c	Mon Nov  4 14:31:03 2002
+++ b/arch/sparc/kernel/ptrace.c	Mon Nov  4 14:31:03 2002
@@ -584,10 +584,15 @@
 
 	/* PTRACE_DUMPCORE unsupported... */
 
-	default:
-		pt_error_return(regs, EIO);
+	default: {
+		int err = ptrace_request(child, request, addr, data);
+		if (err)
+			pt_error_return(regs, -err);
+		else
+			pt_succ_return(regs, 0);
 		goto out_tsk;
 	}
+	}
 out_tsk:
 	if (child)
 		put_task_struct(child);
@@ -604,7 +609,8 @@
 		return;
 	if (!(current->ptrace & PT_PTRACED))
 		return;
-	current->exit_code = SIGTRAP;
+	current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+					? 0x80 : 0);
 	current->state = TASK_STOPPED;
 	current->thread.flags ^= MAGIC_CONSTANT;
 	notify_parent(current, SIGCHLD);
diff -Nru a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c
--- a/arch/sparc/kernel/sun4d_irq.c	Mon Nov  4 14:31:00 2002
+++ b/arch/sparc/kernel/sun4d_irq.c	Mon Nov  4 14:31:00 2002
@@ -102,7 +102,7 @@
 		for (x = 0; x < NR_CPUS; x++) {
 			if (cpu_online)
 				seq_printf(p, "%10u ",
-				       kstat.irqs[cpu_logical_map(x)][i]);
+				       kstat_cpu(cpu_logical_map(x)).irqs[i]);
 		}
 #endif
 		seq_printf(p, "%c %s",
@@ -199,7 +199,7 @@
 	cc_set_iclr(1 << irq);
 	
 	irq_enter();
-	kstat.irqs[cpu][irq]++;
+	kstat_cpu(cpu).irqs[irq]++;
 	if (!sbusl) {
 		action = *(irq + irq_action);
 		if (!action)
diff -Nru a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
--- a/arch/sparc64/Kconfig	Mon Nov  4 14:31:01 2002
+++ b/arch/sparc64/Kconfig	Mon Nov  4 14:31:01 2002
@@ -5,6 +5,14 @@
 
 mainmenu "Linux/UltraSPARC Kernel Configuration"
 
+config MMU
+	bool
+	default y
+
+config SWAP
+	bool
+	default y
+
 source "init/Kconfig"
 
 
diff -Nru a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
--- a/arch/sparc64/kernel/irq.c	Mon Nov  4 14:31:02 2002
+++ b/arch/sparc64/kernel/irq.c	Mon Nov  4 14:31:02 2002
@@ -135,7 +135,7 @@
 			if (!cpu_online(j))
 				continue;
 			seq_printf(p, "%10u ",
-				   kstat.irqs[j][i]);
+				   kstat_cpu(j).irqs[i]);
 		}
 #endif
 		seq_printf(p, " %s:%lx", action->name,
@@ -738,7 +738,7 @@
 #endif
 
 	irq_enter();
-	kstat.irqs[cpu][irq]++;
+	kstat_cpu(cpu).irqs[irq]++;
 
 	if (irq == 9)
 		kbd_pt_regs = regs;
@@ -813,7 +813,7 @@
 	int cpu = smp_processor_id();
 
 	irq_enter();
-	kstat.irqs[cpu][irq]++;
+	kstat_cpu(cpu).irqs[irq]++;
 
 	*(irq_work(cpu, irq)) = 0;
 	bucket = get_ino_in_irqaction(action) + ivector_table;
diff -Nru a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
--- a/arch/sparc64/kernel/process.c	Mon Nov  4 14:31:01 2002
+++ b/arch/sparc64/kernel/process.c	Mon Nov  4 14:31:01 2002
@@ -694,7 +694,7 @@
 			   /* Notreached by child. */
 			   "1:" :
 			   "=r" (retval) :
-			   "i" (__NR_clone), "r" (flags | CLONE_VM),
+			   "i" (__NR_clone), "r" (flags | CLONE_VM | CLONE_UNTRACED),
 			   "i" (__NR_exit),  "r" (fn), "r" (arg) :
 			   "g1", "g2", "g3", "o0", "o1", "memory", "cc");
 	return retval;
diff -Nru a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c
--- a/arch/sparc64/kernel/ptrace.c	Mon Nov  4 14:31:02 2002
+++ b/arch/sparc64/kernel/ptrace.c	Mon Nov  4 14:31:02 2002
@@ -571,10 +571,15 @@
 
 	/* PTRACE_DUMPCORE unsupported... */
 
-	default:
-		pt_error_return(regs, EIO);
+	default: {
+		int err = ptrace_request(child, request, addr, data);
+		if (err)
+			pt_error_return(regs, -err);
+		else
+			pt_succ_return(regs, 0);
 		goto out_tsk;
 	}
+	}
 flush_and_out:
 	{
 		unsigned long va;
@@ -612,7 +617,8 @@
 		return;
 	if (!(current->ptrace & PT_PTRACED))
 		return;
-	current->exit_code = SIGTRAP;
+	current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+					? 0x80 : 0);
 	current->state = TASK_STOPPED;
 	notify_parent(current, SIGCHLD);
 	schedule();
diff -Nru a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
--- a/arch/sparc64/kernel/smp.c	Mon Nov  4 14:31:00 2002
+++ b/arch/sparc64/kernel/smp.c	Mon Nov  4 14:31:00 2002
@@ -967,7 +967,7 @@
 			if (cpu == boot_cpu_id) {
 				irq_enter();
 
-				kstat.irqs[cpu][0]++;
+				kstat_cpu(cpu).irqs[0]++;
 				timer_tick_interrupt(regs);
 
 				irq_exit();
diff -Nru a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
--- a/arch/sparc64/kernel/sys_sparc.c	Mon Nov  4 14:31:02 2002
+++ b/arch/sparc64/kernel/sys_sparc.c	Mon Nov  4 14:31:02 2002
@@ -13,6 +13,7 @@
 #include <linux/fs.h>
 #include <linux/file.h>
 #include <linux/mm.h>
+#include <linux/hugetlb.h>
 #include <linux/sem.h>
 #include <linux/msg.h>
 #include <linux/shm.h>
diff -Nru a/arch/sparc64/mm/hugetlbpage.c b/arch/sparc64/mm/hugetlbpage.c
--- a/arch/sparc64/mm/hugetlbpage.c	Mon Nov  4 14:31:02 2002
+++ b/arch/sparc64/mm/hugetlbpage.c	Mon Nov  4 14:31:02 2002
@@ -8,6 +8,7 @@
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
+#include <linux/hugetlb.h>
 #include <linux/pagemap.h>
 #include <linux/smp_lock.h>
 #include <linux/slab.h>
diff -Nru a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
--- a/arch/sparc64/mm/init.c	Mon Nov  4 14:31:01 2002
+++ b/arch/sparc64/mm/init.c	Mon Nov  4 14:31:01 2002
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <linux/mm.h>
+#include <linux/hugetlb.h>
 #include <linux/slab.h>
 #include <linux/blk.h>
 #include <linux/swap.h>
diff -Nru a/arch/um/Kconfig b/arch/um/Kconfig
--- a/arch/um/Kconfig	Mon Nov  4 14:31:01 2002
+++ b/arch/um/Kconfig	Mon Nov  4 14:31:01 2002
@@ -2,6 +2,14 @@
 	bool
 	default y
 
+# XXX: does UM have a mmu/swap?
+config MMU
+	bool
+	default y
+
+config SWAP
+	bool
+	default y
 
 mainmenu "Linux/Usermode Kernel Configuration"
 
diff -Nru a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
--- a/arch/um/kernel/irq.c	Mon Nov  4 14:31:02 2002
+++ b/arch/um/kernel/irq.c	Mon Nov  4 14:31:02 2002
@@ -108,7 +108,7 @@
 #else
 		for (j = 0; j < num_online_cpus(); j++)
 			p += sprintf(p, "%10u ",
-				kstat.irqs[cpu_logical_map(j)][i]);
+				kstat_cpu(cpu_logical_map(j)).irqs[i]);
 #endif
 		p += sprintf(p, " %14s", irq_desc[i].handler->typename);
 		p += sprintf(p, "  %s", action->name);
@@ -283,7 +283,7 @@
 	unsigned int status;
 
 	irq_enter();
-	kstat.irqs[cpu][irq]++;
+	kstat_cpu(cpu).irqs[irq]++;
 	spin_lock(&desc->lock);
 	desc->handler->ack(irq);
 	/*
diff -Nru a/arch/v850/Kconfig b/arch/v850/Kconfig
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/Kconfig	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,488 @@
+#############################################################################
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/config-language.txt.
+#
+#############################################################################
+
+mainmenu "uClinux/v850 (w/o MMU) Kernel Configuration"
+
+config MMU
+       	bool
+	default n
+config SWAP
+	bool
+	default n
+config UID16
+	bool
+	default n
+config RWSEM_GENERIC_SPINLOCK
+	bool
+	default y
+config RWSEM_XCHGADD_ALGORITHM
+	bool
+	default n
+
+# Turn off some random 386 crap that can affect device config
+config ISA
+	bool
+	default n
+config ISAPNP
+	bool
+	default n
+config EISA
+	bool
+	default n
+config MCA
+	bool
+	default n
+
+
+#############################################################################
+#### v850-specific config
+
+# Define the architecture
+config V850
+	bool
+	default y
+
+menu "Processor type and features"
+
+   choice
+	  prompt "Platform"
+	  default GDB
+      config RTE_CB_MA1
+      	     bool "RTE-V850E/MA1-CB"
+      config RTE_CB_NB85E
+      	     bool "RTE-V850E/NB85E-CB"
+      config V850E_SIM
+      	     bool "GDB"
+      config V850E2_SIM85E2C
+      	     bool "sim85e2c"
+      config V850E2_FPGA85E2C
+      	     bool "NA85E2C-FPGA"
+      config V850E2_ANNA
+      	     bool "Anna"
+   endchoice
+
+
+   #### V850E processor-specific config
+
+   # All CPUs currently supported use the v850e architecture
+   config V850E
+   	  bool
+	  default y
+
+   # The RTE-V850E/MA1-CB is the only type of V850E/MA1 platform we
+   # currently support
+   config V850E_MA1
+   	  bool
+	  depends RTE_CB_MA1
+	  default y
+   # Similarly for the RTE-V850E/MA1-CB - V850E/TEG
+   config V850E_TEG
+   	  bool
+	  depends RTE_CB_NB85E
+	  default y
+
+   # NB85E processor core
+   config V850E_NB85E
+   	  bool
+	  depends V850E_MA1 || V850E_TEG
+	  default y
+
+   config V850E_MA1_HIGHRES_TIMER
+   	  bool "High resolution timer support"
+  	  depends V850E_MA1
+
+
+   #### V850E2 processor-specific config
+
+   # V850E2 processors
+   config V850E2
+   	  bool
+	  depends V850E2_SIM85E2C || V850E2_FPGA85E2C || V850E2_ANNA
+	  default y
+
+   # Processors based on the NA85E2A core
+   config V850E2_NA85E2A
+   	  bool
+	  depends V850E2_ANNA
+	  default y
+
+   # Processors based on the NA85E2C core
+   config V850E2_NA85E2C
+   	  bool
+	  depends V850E2_SIM85E2C || V850E2_FPGA85E2C
+	  default y
+
+
+   #### RTE-CB platform-specific config
+
+   # Boards in the RTE-x-CB series
+   config RTE_CB
+   	  bool
+	  depends RTE_CB_MA1 || RTE_CB_NB85E
+	  default y
+
+   # Currently, we only support RTE-CB boards using the Multi debugger
+   config RTE_CB_MULTI
+   	  bool
+	  depends RTE_CB
+	  default y
+
+   config RTE_CB_MA1_KSRAM
+   	  bool "Kernel in SRAM (limits size of kernel)"
+	  depends RTE_CB_MA1 && RTE_CB_MULTI
+	  default n
+
+   config RTE_MB_A_PCI
+   	  bool "Mother-A PCI support"
+	  depends RTE_CB
+	  default y
+
+   # The GBUS is used to talk to the RTE-MOTHER-A board
+   config RTE_GBUS_INT
+   	  bool
+	  depends RTE_MB_A_PCI
+	  default y
+
+   # The only PCI bus we support is on the RTE-MOTHER-A board
+   config PCI
+   	  bool
+	  default y if RTE_MB_A_PCI
+
+
+   #### Misc config
+
+   config ROM_KERNEL
+   	  bool "Kernel in ROM"
+	  depends V850E2_ANNA || (RTE_CB && !RTE_CB_MULTI)
+
+   # Some platforms pre-zero memory, in which case the kernel doesn't need to
+   config ZERO_BSS
+   	  bool
+	  depends !V850E2_SIM85E2C
+	  default y
+
+   # The crappy-ass zone allocator requires that the start of allocatable
+   # memory be aligned to the largest possible allocation.
+   config FORCE_MAX_ZONEORDER
+   	  int
+	  default 8 if V850E2_SIM85E2C || V850E2_FPGA85E2C
+
+   config TIME_BOOTUP
+   	  bool "Time bootup"
+	  depends V850E_MA1_HIGHRES_TIMER
+
+   config RESET_GUARD
+   	  bool "Reset Guard"
+
+   config LARGE_ALLOCS
+	  bool "Allow allocating large blocks (> 1MB) of memory"
+	  help
+	     Allow the slab memory allocator to keep chains for very large
+	     memory sizes - upto 32MB. You may need this if your system has
+	     a lot of RAM, and you need to able to allocate very large
+	     contiguous chunks. If unsure, say N.
+
+endmenu
+
+
+#############################################################################
+
+source init/Kconfig
+
+#############################################################################
+
+menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)"
+
+#    config PCI
+# 	   bool "PCI support"
+# 	   help
+# 	     Support for PCI bus.
+
+source "drivers/pci/Kconfig"
+
+config HOTPLUG
+	bool "Support for hot-pluggable device"
+	  ---help---
+	  Say Y here if you want to plug devices into your computer while
+	  the system is running, and be able to use them quickly.  In many
+	  cases, the devices can likewise be unplugged at any time too.
+
+	  One well known example of this is PCMCIA- or PC-cards, credit-card
+	  size devices such as network cards, modems or hard drives which are
+	  plugged into slots found on all modern laptop computers.  Another
+	  example, used on modern desktops as well as laptops, is USB.
+
+	  Enable HOTPLUG and KMOD, and build a modular kernel.  Get agent
+	  software (at <http://linux-hotplug.sourceforge.net/>) and install it.
+	  Then your kernel will automatically call out to a user mode "policy
+	  agent" (/sbin/hotplug) to load modules and set up software needed
+	  to use devices as you hotplug them.
+
+source "drivers/pcmcia/Kconfig"
+
+source "drivers/hotplug/Kconfig"
+
+endmenu
+
+menu "Executable file formats"
+
+config KCORE_AOUT
+	bool
+	default y
+
+config KCORE_ELF
+	default y
+
+config BINFMT_FLAT
+	tristate "Kernel support for flat binaries"
+	help
+	  Support uClinux FLAT format binaries.
+
+config BINFMT_ZFLAT
+	bool "  Enable ZFLAT support"
+	depends on BINFMT_FLAT
+	help
+	  Support FLAT format compressed binaries
+
+endmenu
+
+#############################################################################
+
+source drivers/mtd/Kconfig
+
+source drivers/parport/Kconfig
+
+#source drivers/pnp/Kconfig
+
+source drivers/block/Kconfig
+
+#############################################################################
+
+menu "Disk device support"
+
+config IDE
+       tristate "ATA/ATAPI/MFM/RLL device support"
+       ---help---
+	 If you say Y here, your kernel will be able to manage low cost mass
+	 storage units such as ATA/(E)IDE and ATAPI units. The most common
+	 cases are IDE hard drives and ATAPI CD-ROM drives.
+
+	 It only makes sense to choose this option if your board actually
+	 has an IDE interface. If unsure, say N.
+
+source "drivers/ide/Kconfig"
+
+config SCSI
+	tristate "SCSI device support"
+	help
+	  If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or
+	  any other SCSI device under Linux, say Y and make sure that you know
+	  the name of your SCSI host adapter (the card inside your computer
+	  that "speaks" the SCSI protocol, also called SCSI controller),
+	  because you will be asked for it.
+
+source "drivers/scsi/Kconfig"
+
+endmenu
+
+#############################################################################
+
+
+source "drivers/md/Kconfig"
+
+source "drivers/message/fusion/Kconfig"
+
+source "drivers/ieee1394/Kconfig"
+
+source "drivers/message/i2o/Kconfig"
+
+source "net/Kconfig"
+
+
+menu "Network device support"
+	depends on NET
+
+config NETDEVICES
+	bool "Network device support"
+	---help---
+	  You can say N here if you don't intend to connect your Linux box to
+	  any other computer at all or if all your connections will be over a
+	  telephone line with a modem either via UUCP (UUCP is a protocol to
+	  forward mail and news between unix hosts over telephone lines; read
+	  the UUCP-HOWTO, available from
+	  <http://www.linuxdoc.org/docs.html#howto>) or dialing up a shell
+	  account or a BBS, even using term (term is a program which gives you
+	  almost full Internet connectivity if you have a regular dial up
+	  shell account on some Internet connected Unix computer. Read
+	  <http://www.bart.nl/~patrickr/term-howto/Term-HOWTO.html>).
+
+	  You'll have to say Y if your computer contains a network card that
+	  you want to use under Linux (make sure you know its name because you
+	  will be asked for it and read the Ethernet-HOWTO (especially if you
+	  plan to use more than one network card under Linux)) or if you want
+	  to use SLIP (Serial Line Internet Protocol is the protocol used to
+	  send Internet traffic over telephone lines or null modem cables) or
+	  CSLIP (compressed SLIP) or PPP (Point to Point Protocol, a better
+	  and newer replacement for SLIP) or PLIP (Parallel Line Internet
+	  Protocol is mainly used to create a mini network by connecting the
+	  parallel ports of two local machines) or AX.25/KISS (protocol for
+	  sending Internet traffic over amateur radio links).
+
+	  Make sure to read the NET-3-HOWTO. Eventually, you will have to read
+	  Olaf Kirch's excellent and free book "Network Administrator's
+	  Guide", to be found in <http://www.linuxdoc.org/docs.html#guide>. If
+	  unsure, say Y.
+
+source "drivers/net/Kconfig"
+
+source "drivers/atm/Kconfig"
+
+endmenu
+
+source "net/ax25/Kconfig"
+
+source "net/irda/Kconfig"
+
+source "drivers/isdn/Kconfig"
+
+#source "drivers/telephony/Kconfig"
+
+#
+# input before char - char/joystick depends on it. As does USB.
+#
+source "drivers/input/Kconfig"
+
+source "drivers/char/Kconfig"
+
+#source drivers/misc/Config.in
+source "drivers/media/Kconfig"
+
+source "fs/Kconfig"
+
+
+menu "Console drivers"
+	depends on VT
+
+config VGA_CONSOLE
+	bool "VGA text console"
+	help
+	  Saying Y here will allow you to use Linux in text mode through a
+	  display that complies with the generic VGA standard. Virtually
+	  everyone wants that.
+
+	  The program SVGATextMode can be used to utilize SVGA video cards to
+	  their full potential in text mode. Download it from
+	  <ftp://ibiblio.org/pub/Linux/utils/console/>.
+
+	  If unsure, say N.
+
+config VIDEO_SELECT
+	bool "Video mode selection support"
+	---help---
+	  This enables support for text mode selection on kernel startup. If
+	  you want to take advantage of some high-resolution text mode your
+	  card's BIOS offers, but the traditional Linux utilities like
+	  SVGATextMode don't, you can say Y here and set the mode using the
+	  "vga=" option from your boot loader (lilo or loadlin) or set
+	  "vga=ask" which brings up a video mode menu on kernel startup. (Try
+	  "man bootparam" or see the documentation of your boot loader about
+	  how to pass options to the kernel.)
+
+	  Read the file <file:Documentation/svga.txt> for more information
+	  about the Video mode selection support. If unsure, say N.
+
+source "drivers/video/Kconfig"
+
+endmenu
+
+
+menu "Sound"
+
+config SOUND
+	tristate "Sound card support"
+	---help---
+	  If you have a sound card in your computer, i.e. if it can say more
+	  than an occasional beep, say Y.  Be sure to have all the information
+	  about your sound card and its configuration down (I/O port,
+	  interrupt and DMA channel), because you will be asked for it.
+
+	  You want to read the Sound-HOWTO, available from
+	  <http://www.linuxdoc.org/docs.html#howto>. General information about
+	  the modular sound system is contained in the files
+	  <file:Documentation/sound/Introduction>.  The file
+	  <file:Documentation/sound/README.OSS> contains some slightly
+	  outdated but still useful information as well.
+
+	  If you have a PnP sound card and you want to configure it at boot
+	  time using the ISA PnP tools (read
+	  <http://www.roestock.demon.co.uk/isapnptools/>), then you need to
+	  compile the sound card support as a module ( = code which can be
+	  inserted in and removed from the running kernel whenever you want)
+	  and load that module after the PnP configuration is finished.  To do
+	  this, say M here and read <file:Documentation/modules.txt> as well
+	  as <file:Documentation/sound/README.modules>; the module will be
+	  called soundcore.o.
+
+	  I'm told that even without a sound card, you can make your computer
+	  say more than an occasional beep, by programming the PC speaker.
+	  Kernel patches and supporting utilities to do that are in the pcsp
+	  package, available at <ftp://ftp.infradead.org/pub/pcsp/>.
+
+source "sound/Kconfig"
+
+endmenu
+
+source "drivers/usb/Kconfig"
+
+source "net/bluetooth/Kconfig"
+
+
+menu "Kernel hacking"
+
+config FULLDEBUG
+	bool "Full Symbolic/Source Debugging support"
+	help
+	  Enable debuging symbols on kernel build.
+
+config MAGIC_SYSRQ
+	bool "Magic SysRq key"
+	help
+	  Enables console device to interprent special characters as
+	  commands to dump state information.
+
+config HIGHPROFILE
+	bool "Use fast second timer for profiling"
+	help
+	  Use a fast secondary clock to produce profiling information.
+
+config DUMPTOFLASH
+	bool "Panic/Dump to FLASH"
+	depends on COLDFIRE
+	help
+	  Dump any panic of trap output into a flash memory segment
+	  for later analysis.
+
+config NO_KERNEL_MSG
+	bool "Suppress Kernel BUG Messages"
+	help
+	  Do not output any debug BUG messages within the kernel.
+
+config BDM_DISABLE
+	bool "Disable BDM signals"
+	depends on (EXPERIMENTAL && COLDFIRE)
+	help
+	  Disable the CPU's BDM signals.
+
+endmenu
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
+
+#############################################################################
diff -Nru a/arch/v850/Makefile b/arch/v850/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/Makefile	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,65 @@
+#
+# arch/v850/Makefile
+#
+#  Copyright (C) 2001,02  NEC Corporation
+#  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies. Remember to do have actions
+# for "archclean" and "archdep" for cleaning up and making dependencies for
+# this architecture
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+
+arch_dir = arch/v850
+
+CFLAGS += -mv850e
+# r16 is a fixed pointer to the current task
+CFLAGS += -ffixed-r16 -mno-prolog-function
+CFLAGS += -fno-builtin
+CFLAGS += -D__linux__ -DUTS_SYSNAME=\"uClinux\"
+
+
+HEAD := $(arch_dir)/kernel/head.o $(arch_dir)/kernel/init_task.o
+core-y += $(arch_dir)/kernel/
+libs-y += $(arch_dir)/lib/
+
+
+include $(TOPDIR)/Rules.make
+
+
+# Deal with the initial contents of the root device
+ifdef ROOT_FS_IMAGE
+core-y += root_fs_image.o
+
+# Because the kernel build-system erases all explicit .o build rules, we
+# have to use an intermediate target to fool it into building for us.
+# This results in it being built anew each time, but that's alright.
+root_fs_image.o: root_fs_image_force
+
+# Note that we use the build-system's objcopy, as the v850 tools are fairly
+# old, and don't have the --rename-section option.
+root_fs_image_force: $(ROOT_FS_IMAGE)
+	objcopy -I binary -O elf32-little -B i386 --rename-section .data=.root,alloc,load,readonly,data,contents $< root_fs_image.o
+endif
+
+
+prepare: include/asm-$(ARCH)/asm-consts.h
+
+# Generate constants from C code for use by asm files
+arch/$(ARCH)/kernel/asm-consts.s: include/asm include/linux/version.h \
+				   include/config/MARKER
+include/asm-$(ARCH)/asm-consts.h.tmp: arch/$(ARCH)/kernel/asm-consts.s
+	@$(generate-asm-offsets.h) < $< > $@
+include/asm-$(ARCH)/asm-consts.h: include/asm-$(ARCH)/asm-consts.h.tmp
+	@echo -n '  Generating $@'
+	@$(update-if-changed)
+
+
+CLEAN_FILES += include/asm-$(ARCH)/asm-consts.h.tmp \
+	       include/asm-$(ARCH)/asm-consts.h \
+	       arch/$(ARCH)/kernel/asm-consts.s \
+	       root_fs_image.o
diff -Nru a/arch/v850/README b/arch/v850/README
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/README	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,23 @@
+This port to the NEC V850E processor supports the following platforms:
+
+   + The gdb v850e simulator (CONFIG_V850E_SIM); see the subdirectory `sim'
+     for some more support files for this.
+
+   + The Midas labs RTE-V850E/MA1-CB evaluation board (CONFIG_RTE_CB_MA1),
+     with untested support for the RTE-V850E/NB85E-CB board
+     (CONFIG_RTE_CB_NB85E).  This support has only been tested when running
+     with the Multi-debugger monitor ROM (for the Green Hills Multi debugger).
+     The optional NEC Solution Gear RTE-MOTHER-A motherboard is also
+     supported, which allows PCI boards to be used (CONFIG_RTE_MB_A_PCI).
+
+   + The sim85e2c simulator, which is a verilog simulation of the V850E2
+     NA85E2C cpu core (CONFIG_V850E2_SIM85E2C).
+
+   + A FPGA implementation of the V850E2 NA85E2C cpu core
+     (CONFIG_V850E2_FPGA85E2C).
+
+   + The `Anna' (board/chip) implementation of the V850E2 processor.
+
+Porting to anything with a V850E/MA1 or MA2 processor should be simple.
+See the file <asm-v850/machdep.h> and the files it includes for an example of
+how to add platform/chip-specific support.
diff -Nru a/arch/v850/anna-rom.ld b/arch/v850/anna-rom.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/anna-rom.ld	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,127 @@
+/* Linker script for the Midas labs Anna V850E2 evaluation board
+   (CONFIG_V850E2_ANNA), with kernel in ROM (CONFIG_ROM_KERNEL).  */
+
+/* Note, all symbols are prefixed with an extra `_' for compatibility with
+   the existing linux sources.  */
+
+_jiffies = _jiffies_64 ;
+
+MEMORY {
+       /* 8MB of flash ROM.  */
+       ROM   : ORIGIN = 0,          LENGTH = 0x00800000
+
+       /* 1MB of static RAM.  This memory is mirrored 64 times.  */
+       SRAM  : ORIGIN = 0x04000000, LENGTH = 0x00100000
+       /* 64MB of DRAM.  */
+       SDRAM : ORIGIN = 0x08000000, LENGTH = 0x04000000
+}
+
+SECTIONS {
+	.intv : {
+		__intv_start = . ;
+			*(.intv.reset)	/* Reset vector */
+			*(.intv.common)	/* Vectors common to all v850e proc. */
+			*(.intv.mach)	/* Machine-specific int. vectors.  */
+		__intv_end = . ;
+	} > ROM
+
+	.text ALIGN (0x10) : {
+		__stext = . ;
+        	*(.text)
+			*(.exit.text)	/* 2.5 convention */
+			*(.text.exit)	/* 2.4 convention */
+			*(.text.lock)
+			*(.exitcall.exit)
+		__real_etext = . ;	/* There may be data after here.  */
+			*(.rodata)
+
+		. = ALIGN (0x4) ;
+			*(.kstrtab)
+
+		. = ALIGN (4) ;
+		    	*(.call_table_data)
+			*(.call_table_text)
+
+		. = ALIGN (16) ;	/* Exception table.  */
+		___start___ex_table = . ;
+			*(__ex_table)
+		___stop___ex_table = . ;
+
+		___start___ksymtab = . ;/* Kernel symbol table.  */
+			*(__ksymtab)
+		___stop___ksymtab = . ;
+		. = ALIGN (4) ;
+		__etext = . ;
+	} > ROM
+
+	.init_text ALIGN (4096) : {
+			*(.init.text)	/* 2.5 convention */
+			*(.text.init)	/* 2.4 convention */
+		. = ALIGN (16) ;
+		___setup_start = . ;
+			*(.init.setup)	/* 2.5 convention */
+			*(.setup.init)	/* 2.4 convention */
+		___setup_end = . ;
+		___initcall_start = . ;
+			*(.initcall.init)
+			*(.initcall1.init)
+			*(.initcall2.init)
+			*(.initcall3.init)
+			*(.initcall4.init)
+			*(.initcall5.init)
+			*(.initcall6.init)
+			*(.initcall7.init)
+		. = ALIGN (4) ;
+		___initcall_end = . ;
+	} > ROM
+
+	/* Device contents for the root filesystem.  */
+	.root ALIGN (4096) : {
+		__root_fs_image_start = . ;
+		*(.root)
+		__root_fs_image_end = . ;
+	} > ROM
+
+	__rom_copy_src_start = . ;
+
+	.data : {
+		__kram_start = . ;
+		__rom_copy_dst_start = . ;
+
+		__sdata = . ;
+		___data_start = . ;
+        	*(.data)
+			*(.exit.data)	/* 2.5 convention */
+			*(.data.exit)	/* 2.4 convention */
+		. = ALIGN (16) ;
+		*(.data.cacheline_aligned)
+		. = ALIGN (0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN (0x2000) ;
+		__edata = . ;
+	} > SRAM  AT> ROM
+
+	.init_data ALIGN (4096) : {
+		__init_start = . ;
+			*(.init.data)	/* 2.5 convention */
+			*(.data.init)	/* 2.4 convention */
+		__init_end = . ;
+		__rom_copy_dst_end = . ;
+	} > SRAM  AT> ROM
+
+	.bss ALIGN (4096) : {
+		__sbss = . ;
+			*(.bss)
+			*(COMMON)
+		. = ALIGN (4) ;
+		__init_stack_end = . ;
+		__ebss = . ;
+
+		__kram_end = . ;
+	} > SRAM
+
+	.bootmap ALIGN (4096) : {
+		__bootmap = . ;
+		. = . + 4096 ;		/* enough for 128MB.   */
+	} > SRAM
+}
diff -Nru a/arch/v850/anna.ld b/arch/v850/anna.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/anna.ld	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,122 @@
+/* Linker script for the Midas labs Anna V850E2 evaluation board
+   (CONFIG_V850E2_ANNA).  */
+
+/* Note, all symbols are prefixed with an extra `_' for compatibility with
+   the existing linux sources.  */
+
+_jiffies = _jiffies_64 ;
+
+MEMORY {
+       /* 256KB of internal memory (followed by one mirror).  */
+       iMEM0 : ORIGIN = 0,	    LENGTH = 0x00040000
+       /* 256KB of internal memory (followed by one mirror).  */
+       iMEM1 : ORIGIN = 0x00040000, LENGTH = 0x00040000
+
+       /* 1MB of static RAM.  This memory is mirrored 64 times.  */
+       SRAM  : ORIGIN = 0x04000000, LENGTH = 0x00100000
+       /* 64MB of DRAM.  */
+       SDRAM : ORIGIN = 0x08000000, LENGTH = 0x04000000
+}
+
+SECTIONS {
+	.intv : {
+		__intv_start = . ;
+			*(.intv.reset)	/* Reset vector */
+			*(.intv.common)	/* Vectors common to all v850e proc. */
+			*(.intv.mach)	/* Machine-specific int. vectors.  */
+		__intv_end = . ;
+	} > iMEM0
+
+	.text : {
+		 __kram_start = . ;
+
+		__stext = . ;
+        	*(.text)
+			*(.exit.text)	/* 2.5 convention */
+			*(.text.exit)	/* 2.4 convention */
+			*(.text.lock)
+			*(.exitcall.exit)
+		__real_etext = . ;	/* There may be data after here.  */
+			*(.rodata)
+
+		. = ALIGN (0x4) ;
+			*(.kstrtab)
+
+		. = ALIGN (4) ;
+		    	*(.call_table_data)
+			*(.call_table_text)
+
+		. = ALIGN (16) ;	/* Exception table.  */
+		___start___ex_table = . ;
+			*(__ex_table)
+		___stop___ex_table = . ;
+
+		___start___ksymtab = . ;/* Kernel symbol table.  */
+			*(__ksymtab)
+		___stop___ksymtab = . ;
+		. = ALIGN (4) ;
+		__etext = . ;
+	} > SRAM
+
+	.data ALIGN (0x4) : {
+		__sdata = . ;
+		___data_start = . ;
+        	*(.data)
+			*(.exit.data)	/* 2.5 convention */
+			*(.data.exit)	/* 2.4 convention */
+		. = ALIGN (16) ;
+		*(.data.cacheline_aligned)
+		. = ALIGN (0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN (0x2000) ;
+		__edata = . ;
+	} > SRAM
+
+	.bss ALIGN (0x4) : {
+		__sbss = . ;
+			*(.bss)
+			*(COMMON)
+		. = ALIGN (4) ;
+		__init_stack_end = . ;
+		__ebss = . ;
+	} > SRAM
+
+	.init ALIGN (4096) : {
+		__init_start = . ;
+			*(.init.text)	/* 2.5 convention */
+			*(.init.data)
+			*(.text.init)	/* 2.4 convention */
+			*(.data.init)
+		. = ALIGN (16) ;
+		___setup_start = . ;
+			*(.init.setup)	/* 2.5 convention */
+			*(.setup.init)	/* 2.4 convention */
+		___setup_end = . ;
+		___initcall_start = . ;
+			*(.initcall.init)
+			*(.initcall1.init)
+			*(.initcall2.init)
+			*(.initcall3.init)
+			*(.initcall4.init)
+			*(.initcall5.init)
+			*(.initcall6.init)
+			*(.initcall7.init)
+		. = ALIGN (4) ;
+		___initcall_end = . ;
+		__init_end = . ;
+
+		__kram_end = . ;
+	} > SRAM
+
+	.bootmap ALIGN (4096) : {
+		__bootmap = . ;
+		. = . + 4096 ;		/* enough for 128MB.   */
+	} > SRAM
+
+	/* Device contents for the root filesystem.  */
+	.root : {
+		__root_fs_image_start = . ;
+		*(.root)
+		__root_fs_image_end = . ;
+	} > SDRAM
+}
diff -Nru a/arch/v850/fpga85e2c.ld b/arch/v850/fpga85e2c.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/fpga85e2c.ld	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,144 @@
+/* Linker script for the FPGA implementation of the V850E2 NA85E2C cpu core
+   (CONFIG_V850E2_FPGA85E2C).  */
+
+/* Note, all symbols are prefixed with an extra `_' for compatibility with
+   the existing linux sources.  */
+
+_jiffies = _jiffies_64 ;
+
+MEMORY {
+       /* Reset vector.  */
+       RESET	 : ORIGIN = 0, LENGTH = 0x10
+       /* Interrupt vectors.  */
+       INTV      : ORIGIN = 0x10, LENGTH = 0x470
+       /* The `window' in RAM were we're allowed to load stuff.  */
+       RAM_LOW   : ORIGIN = 0x480, LENGTH = 0x0005FB80
+       /* Some more ram above the window were we can put bss &c.  */
+       RAM_HIGH  : ORIGIN = 0x00060000, LENGTH = 0x000A0000
+       /* This is the area visible from the outside world (we can use
+	  this only for uninitialized data).  */
+       VISIBLE   : ORIGIN = 0x00200000, LENGTH = 0x00060000
+}
+
+SECTIONS {
+	.reset : {
+	        __kram_start = . ;
+		__intv_start = . ;
+	        	*(.intv.reset)	/* Reset vector */
+	} > RESET
+
+	.r0_ram : {
+		__r0_ram = . ;
+		. = . + 32 ;
+	} > RAM_LOW
+
+	.text : {
+		__stext = . ;
+        	*(.text)
+			*(.exit.text)	/* 2.5 convention */
+			*(.text.exit)	/* 2.4 convention */
+			*(.text.lock)
+			*(.exitcall.exit)
+		__real_etext = . ;	/* There may be data after here.  */
+			*(.rodata)
+		. = ALIGN (0x4) ;
+			*(.kstrtab)
+
+		. = ALIGN (4) ;
+		    	*(.call_table_data)
+			*(.call_table_text)
+
+		. = ALIGN (16) ;	/* Exception table.  */
+		___start___ex_table = . ;
+			*(__ex_table)
+		___stop___ex_table = . ;
+
+		___start___ksymtab = . ;/* Kernel symbol table.  */
+			*(__ksymtab)
+		___stop___ksymtab = . ;
+		. = ALIGN (4) ;
+		__etext = . ;
+	} > RAM_LOW
+
+	.data : {
+		__sdata = . ;
+        	*(.data)
+			*(.exit.data)	/* 2.5 convention */
+			*(.data.exit)	/* 2.4 convention */
+		. = ALIGN (16) ;
+		*(.data.cacheline_aligned)
+		. = ALIGN (0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN (0x2000) ;
+		__edata = . ;
+	} > RAM_LOW
+
+	/* Device contents for the root filesystem.  */
+	.root : {
+		. =  ALIGN (4096) ;
+		__root_fs_image_start = . ;
+		*(.root)
+		__root_fs_image_end = . ;
+	} > RAM_LOW
+
+	.init ALIGN (4096) : {
+		__init_start = . ;
+			*(.init.text)	/* 2.5 convention */
+			*(.init.data)
+			*(.text.init)	/* 2.4 convention */
+			*(.data.init)
+		. = ALIGN (16) ;
+		___setup_start = . ;
+			*(.init.setup)	/* 2.5 convention */
+			*(.setup.init)	/* 2.4 convention */
+		___setup_end = . ;
+		___initcall_start = . ;
+			*(.initcall.init)
+			*(.initcall1.init)
+			*(.initcall2.init)
+			*(.initcall3.init)
+			*(.initcall4.init)
+			*(.initcall5.init)
+			*(.initcall6.init)
+			*(.initcall7.init)
+		. = ALIGN (4) ;
+		___initcall_end = . ;
+	} > RAM_LOW
+
+        /* Where the interrupt vectors are initially loaded.  */
+	__intv_load_start = . ;
+
+	.intv : {
+			*(.intv.common)	/* Vectors common to all v850e proc. */
+			*(.intv.mach)	/* Machine-specific int. vectors.  */
+		__intv_end = . ;
+	} > INTV  AT> RAM_LOW
+
+	.bss : {
+		/* This is here so that when we free init memory the
+		   load-time copy of the interrupt vectors and any empty
+		   space at the end of the `RAM_LOW' area is freed too.  */
+		. = ALIGN (4096);
+		__init_end = . ;
+
+		__sbss = . ;
+			*(.bss)
+			*(COMMON)
+		. = ALIGN (4) ;
+		__init_stack_end = . ;
+		__ebss = . ;
+
+	        __kram_end = . ;
+	} > RAM_HIGH
+
+	.bootmap ALIGN (4096) : {
+		__bootmap = . ;
+		. = . + 4096 ;		/* enough for 128MB.   */
+	} > RAM_HIGH
+
+	.visible : {
+		_memcons_output = . ;
+		. = . + 0x8000 ;
+		_memcons_output_end = . ;
+	} > VISIBLE
+}
diff -Nru a/arch/v850/kernel/Makefile b/arch/v850/kernel/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/Makefile	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,38 @@
+#
+# arch/v850/kernel/Makefile
+#
+#  Copyright (C) 2001,02  NEC Corporation
+#  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+#
+# 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.
+#
+
+EXTRA_TARGETS := head.o init_task.o
+
+obj-y += intv.o entry.o process.o syscalls.o time.o semaphore.o setup.o \
+	 signal.o irq.o mach.o ptrace.o bug.o
+export-objs += v850_ksyms.o rte_mb_a_pci.o
+
+obj-$(CONFIG_MODULES)		+= v850_ksyms.o
+# chip-specific code
+obj-$(CONFIG_V850E_MA1)		+= ma.o	nb85e_utils.o nb85e_timer_d.o
+obj-$(CONFIG_V850E_NB85E)	+= nb85e_intc.o
+obj-$(CONFIG_V850E2_ANNA)	+= anna.o nb85e_intc.o nb85e_utils.o nb85e_timer_d.o
+# platform-specific code
+obj-$(CONFIG_V850E_SIM)		+= sim.o simcons.o
+obj-$(CONFIG_V850E2_SIM85E2C)	+= sim85e2c.o nb85e_intc.o memcons.o
+obj-$(CONFIG_V850E2_FPGA85E2C)	+= fpga85e2c.o nb85e_intc.o memcons.o
+obj-$(CONFIG_RTE_CB)		+= rte_cb.o rte_cb_leds.o
+obj-$(CONFIG_RTE_CB_MA1)	+= rte_ma1_cb.o
+obj-$(CONFIG_RTE_CB_NB85E)	+= rte_nb85e_cb.o
+obj-$(CONFIG_RTE_CB_MULTI)	+= rte_cb_multi.o
+obj-$(CONFIG_RTE_MB_A_PCI)	+= rte_mb_a_pci.o
+obj-$(CONFIG_RTE_GBUS_INT)	+= gbus_int.o
+# feature-specific code
+obj-$(CONFIG_V850E_MA1_HIGHRES_TIMER)	+= highres_timer.o
+obj-$(CONFIG_PROC_FS)		+= procfs.o
+
+
+include $(TOPDIR)/Rules.make
diff -Nru a/arch/v850/kernel/anna.c b/arch/v850/kernel/anna.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/anna.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,202 @@
+/*
+ * arch/v850/kernel/anna.c -- Anna V850E2 evaluation chip/board
+ *
+ *  Copyright (C) 2002  NEC Corporation
+ *  Copyright (C) 2002  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/major.h>
+#include <linux/irq.h>
+
+#include <asm/machdep.h>
+#include <asm/atomic.h>
+#include <asm/page.h>
+#include <asm/nb85e_timer_d.h>
+#include <asm/nb85e_uart.h>
+
+#include "mach.h"
+
+
+/* SRAM and SDRAM are vaguely contiguous (with a hole in between; see
+   mach_reserve_bootmem for details), so just use both as one big area.  */
+#define RAM_START 	SRAM_ADDR
+#define RAM_END		(SDRAM_ADDR + SDRAM_SIZE)
+
+
+static void anna_led_tick (void);
+
+
+void __init mach_early_init (void)
+{
+	ANNA_ILBEN  = 0;
+	ANNA_CSC(0) = 0x402F;
+	ANNA_CSC(1) = 0x4000;
+	ANNA_BPC    = 0;
+	ANNA_BSC    = 0xAAAA;
+	ANNA_BEC    = 0;
+	ANNA_BHC    = 0x00FF;	/* icache all memory, dcache none */
+	ANNA_BCT(0) = 0xB088;
+	ANNA_BCT(1) = 0x0008;
+	ANNA_DWC(0) = 0x0027;
+	ANNA_DWC(1) = 0;
+	ANNA_BCC    = 0x0006;
+	ANNA_ASC    = 0;
+	ANNA_LBS    = 0x0089;
+	ANNA_SCR3   = 0x21A9;
+	ANNA_RFS3   = 0x8121;
+
+	nb85e_intc_disable_irqs ();
+}
+
+void __init mach_setup (char **cmdline)
+{
+	printk (KERN_INFO
+		"CPU: %s\n"
+		"Platform: %s\n",
+		CPU_MODEL_LONG,
+		PLATFORM_LONG);
+
+#ifdef CONFIG_V850E_NB85E_UART_CONSOLE
+	nb85e_uart_cons_init (1);
+#endif
+
+	ANNA_PORT_PM (0) = 0;	/* Make all LED pins output pins.  */
+	mach_tick = anna_led_tick;
+}
+
+void __init mach_get_physical_ram (unsigned long *ram_start,
+				   unsigned long *ram_len)
+{
+	*ram_start = RAM_START;
+	*ram_len = RAM_END - RAM_START;
+}
+
+void __init mach_reserve_bootmem ()
+{
+	/* The space between SRAM and SDRAM is filled with duplicate
+	   images of SRAM.  Prevent the kernel from using them.  */
+	reserve_bootmem (SRAM_ADDR + SRAM_SIZE,
+			 SDRAM_ADDR - (SRAM_ADDR + SRAM_SIZE));
+}
+
+void mach_gettimeofday (struct timespec *tv)
+{
+	tv->tv_sec = 0;
+	tv->tv_nsec = 0;
+}
+
+void __init mach_sched_init (struct irqaction *timer_action)
+{
+	/* Start hardware timer.  */
+	nb85e_timer_d_configure (0, HZ);
+	/* Install timer interrupt handler.  */
+	setup_irq (IRQ_INTCMD(0), timer_action);
+}
+
+static struct nb85e_intc_irq_init irq_inits[] = {
+	{ "IRQ", 0, 		NUM_MACH_IRQS,	1, 7 },
+	{ "PIN", IRQ_INTP(0),   IRQ_INTP_NUM,   1, 4 },
+	{ "CCC", IRQ_INTCCC(0),	IRQ_INTCCC_NUM, 1, 5 },
+	{ "CMD", IRQ_INTCMD(0), IRQ_INTCMD_NUM,	1, 5 },
+	{ "DMA", IRQ_INTDMA(0), IRQ_INTDMA_NUM,	1, 2 },
+	{ "DMXER", IRQ_INTDMXER,1,		1, 2 },
+	{ "SRE", IRQ_INTSRE(0), IRQ_INTSRE_NUM,	3, 3 },
+	{ "SR",	 IRQ_INTSR(0),	IRQ_INTSR_NUM, 	3, 4 },
+	{ "ST",  IRQ_INTST(0), 	IRQ_INTST_NUM, 	3, 5 },
+	{ 0 }
+};
+#define NUM_IRQ_INITS ((sizeof irq_inits / sizeof irq_inits[0]) - 1)
+
+static struct hw_interrupt_type hw_itypes[NUM_IRQ_INITS];
+
+void __init mach_init_irqs (void)
+{
+	nb85e_intc_init_irq_types (irq_inits, hw_itypes);
+}
+
+void machine_restart (char *__unused)
+{
+#ifdef CONFIG_RESET_GUARD
+	disable_reset_guard ();
+#endif
+	asm ("jmp r0"); /* Jump to the reset vector.  */
+}
+
+void machine_halt (void)
+{
+#ifdef CONFIG_RESET_GUARD
+	disable_reset_guard ();
+#endif
+	local_irq_disable ();	/* Ignore all interrupts.  */
+	ANNA_PORT_IO(0) = 0xAA;	/* Note that we halted.  */
+	for (;;)
+		asm ("halt; nop; nop; nop; nop; nop");
+}
+
+void machine_power_off (void)
+{
+	machine_halt ();
+}
+
+/* Called before configuring an on-chip UART.  */
+void anna_uart_pre_configure (unsigned chan, unsigned cflags, unsigned baud)
+{
+	/* The Anna connects some general-purpose I/O pins on the CPU to
+	   the RTS/CTS lines of UART 1's serial connection.  I/O pins P07
+	   and P37 are RTS and CTS respectively.  */
+	if (chan == 1) {
+		ANNA_PORT_PM(0) &= ~0x80; /* P07 in output mode */
+		ANNA_PORT_PM(3) |=  0x80; /* P37 in input mode */
+	}
+}
+
+/* Minimum and maximum bounds for the moving upper LED boundary in the
+   clock tick display.  We can't use the last bit because it's used for
+   UART0's CTS output.  */
+#define MIN_MAX_POS 0
+#define MAX_MAX_POS 6
+
+/* There are MAX_MAX_POS^2 - MIN_MAX_POS^2 cycles in the animation, so if
+   we pick 6 and 0 as above, we get 49 cycles, which is when divided into
+   the standard 100 value for HZ, gives us an almost 1s total time.  */
+#define TICKS_PER_FRAME \
+	(HZ / (MAX_MAX_POS * MAX_MAX_POS - MIN_MAX_POS * MIN_MAX_POS))
+
+static void anna_led_tick ()
+{
+	static unsigned counter = 0;
+	
+	if (++counter == TICKS_PER_FRAME) {
+		static int pos = 0, max_pos = MAX_MAX_POS, dir = 1;
+
+		if (dir > 0 && pos == max_pos) {
+			dir = -1;
+			if (max_pos == MIN_MAX_POS)
+				max_pos = MAX_MAX_POS;
+			else
+				max_pos--;
+		} else {
+			if (dir < 0 && pos == 0)
+				dir = 1;
+
+			if (pos + dir <= max_pos) {
+				/* Each bit of port 0 has a LED. */
+				clear_bit (pos, &ANNA_PORT_IO(0));
+				pos += dir;
+				set_bit (pos, &ANNA_PORT_IO(0));
+			}
+		}
+
+		counter = 0;
+	}
+}
diff -Nru a/arch/v850/kernel/asm-consts.c b/arch/v850/kernel/asm-consts.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/asm-consts.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,60 @@
+/*
+ * This program is used to generate definitions needed by
+ * assembly language modules.
+ *
+ * We use the technique used in the OSF Mach kernel code:
+ * generate asm statements containing #defines,
+ * compile this file to assembler, and then extract the
+ * #defines from the assembly-language output.
+ */
+
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <asm/irq.h>
+#include <asm/hardirq.h>
+#include <asm/errno.h>
+
+#define DEFINE(sym, val) \
+	asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+#define BLANK() asm volatile("\n->" : : )
+
+int main (void)
+{
+	/* offsets into the task struct */
+	DEFINE (TASK_STATE, offsetof (struct task_struct, state));
+	DEFINE (TASK_FLAGS, offsetof (struct task_struct, flags));
+	DEFINE (TASK_PTRACE, offsetof (struct task_struct, ptrace));
+	DEFINE (TASK_BLOCKED, offsetof (struct task_struct, blocked));
+	DEFINE (TASK_THREAD, offsetof (struct task_struct, thread));
+	DEFINE (TASK_THREAD_INFO, offsetof (struct task_struct, thread_info));
+	DEFINE (TASK_MM, offsetof (struct task_struct, mm));
+	DEFINE (TASK_ACTIVE_MM, offsetof (struct task_struct, active_mm));
+	DEFINE (TASK_PID, offsetof (struct task_struct, pid));
+
+	/* offsets into the kernel_stat struct */
+	DEFINE (STAT_IRQ, offsetof (struct kernel_stat, irqs));
+
+
+	/* signal defines */
+	DEFINE (SIGSEGV, SIGSEGV);
+	DEFINE (SEGV_MAPERR, SEGV_MAPERR);
+	DEFINE (SIGTRAP, SIGTRAP);
+	DEFINE (SIGCHLD, SIGCHLD);
+	DEFINE (SIGILL, SIGILL);
+	DEFINE (TRAP_TRACE, TRAP_TRACE);
+
+	/* ptrace flag bits */
+	DEFINE (PT_PTRACED, PT_PTRACED);
+	DEFINE (PT_DTRACE, PT_DTRACE);
+
+	/* error values */
+	DEFINE (ENOSYS, ENOSYS);
+
+	/* clone flag bits */
+	DEFINE (CLONE_VFORK, CLONE_VFORK);
+	DEFINE (CLONE_VM, CLONE_VM);
+
+	return 0;
+}
diff -Nru a/arch/v850/kernel/bug.c b/arch/v850/kernel/bug.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/bug.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,62 @@
+/*
+ * arch/v850/kernel/bug.c -- Bug reporting functions
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+#include <linux/sched.h>
+
+#include <asm/errno.h>
+#include <asm/ptrace.h>
+#include <asm/current.h>
+
+/* We should use __builtin_return_address, but it doesn't work in gcc-2.90
+   (which is currently our standard compiler on the v850).  */
+#define ret_addr() ({ register u32 lp asm ("lp"); lp; })
+#define stack_addr() ({ register u32 sp asm ("sp"); sp; })
+
+void __bug ()
+{
+	printk (KERN_CRIT "kernel BUG at PC 0x%x (SP ~0x%x)!\n",
+		ret_addr() - 4, /* - 4 for `jarl' */
+		stack_addr());
+	machine_halt ();
+}
+
+int bad_trap (int trap_num, struct pt_regs *regs)
+{
+	printk (KERN_CRIT
+		"unimplemented trap %d called at 0x%08lx, pid %d!\n",
+		trap_num, regs->pc, current->pid);
+	return -ENOSYS;
+}
+
+int debug_trap (struct pt_regs *regs)
+{
+	printk (KERN_CRIT "debug trap at 0x%08lx!\n", regs->pc);
+	return -ENOSYS;
+}
+
+#ifdef CONFIG_RESET_GUARD
+void unexpected_reset (unsigned long ret_addr, unsigned long kmode,
+		       struct task_struct *task, unsigned long sp)
+{
+	printk (KERN_CRIT
+		"unexpected reset in %s mode, pid %d"
+		" (ret_addr = 0x%lx, sp = 0x%lx)\n",
+		kmode ? "kernel" : "user",
+		task ? task->pid : -1,
+		ret_addr, sp);
+
+	machine_halt ();
+}
+#endif /* CONFIG_RESET_GUARD */
diff -Nru a/arch/v850/kernel/entry.S b/arch/v850/kernel/entry.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/entry.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,1005 @@
+/*
+ * arch/v850/kernel/entry.S -- Low-level system-call handling, trap handlers,
+ *	and context-switching
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/sys.h>
+
+#include <asm/entry.h>
+#include <asm/current.h>
+#include <asm/thread_info.h>
+#include <asm/clinkage.h>
+#include <asm/processor.h>
+#include <asm/irq.h>
+#include <asm/errno.h>
+
+#include <asm/asm-consts.h>
+
+
+/* Make a slightly more convenient alias for C_SYMBOL_NAME.  */
+#define CSYM	C_SYMBOL_NAME
+
+
+/* The offset of the struct pt_regs in a `state save frame' on the stack.  */
+#define PTO	STATE_SAVE_PT_OFFSET
+
+
+/* Save argument registers to the struct pt_regs pointed to by EP.  */
+#define SAVE_ARG_REGS							      \
+	sst.w	r6, PTO+PT_GPR(6)[ep];					      \
+	sst.w	r7, PTO+PT_GPR(7)[ep];					      \
+	sst.w	r8, PTO+PT_GPR(8)[ep];					      \
+	sst.w	r9, PTO+PT_GPR(9)[ep];
+/* Restore argument registers from the struct pt_regs pointed to by EP.  */
+#define RESTORE_ARG_REGS						      \
+	sld.w	PTO+PT_GPR(6)[ep], r6;					      \
+	sld.w	PTO+PT_GPR(7)[ep], r7;					      \
+	sld.w	PTO+PT_GPR(8)[ep], r8;					      \
+	sld.w	PTO+PT_GPR(9)[ep], r9;
+
+/* Save value return registers to the struct pt_regs pointed to by EP.  */
+#define SAVE_RVAL_REGS							      \
+	sst.w	r10, PTO+PT_GPR(10)[ep];				      \
+	sst.w	r11, PTO+PT_GPR(11)[ep];
+/* Restore value return registers from the struct pt_regs pointed to by EP.  */
+#define RESTORE_RVAL_REGS						      \
+	sld.w	PTO+PT_GPR(10)[ep], r10;				      \
+	sld.w	PTO+PT_GPR(11)[ep], r11;
+
+
+#define SAVE_CALL_CLOBBERED_REGS_BEFORE_ARGS				      \
+	sst.w	r1, PTO+PT_GPR(1)[ep];					      \
+	sst.w	r5, PTO+PT_GPR(5)[ep];
+#define SAVE_CALL_CLOBBERED_REGS_AFTER_RVAL				      \
+	sst.w	r12, PTO+PT_GPR(12)[ep];				      \
+	sst.w	r13, PTO+PT_GPR(13)[ep];				      \
+	sst.w	r14, PTO+PT_GPR(14)[ep];				      \
+	sst.w	r15, PTO+PT_GPR(15)[ep];				      \
+	sst.w	r16, PTO+PT_GPR(16)[ep];				      \
+	sst.w	r17, PTO+PT_GPR(17)[ep];				      \
+	sst.w	r18, PTO+PT_GPR(18)[ep];				      \
+	sst.w	r19, PTO+PT_GPR(19)[ep];
+#define RESTORE_CALL_CLOBBERED_REGS_BEFORE_ARGS				      \
+	sld.w	PTO+PT_GPR(1)[ep], r1;					      \
+	sld.w	PTO+PT_GPR(5)[ep], r5;
+#define RESTORE_CALL_CLOBBERED_REGS_AFTER_RVAL				      \
+	sld.w	PTO+PT_GPR(12)[ep], r12;				      \
+	sld.w	PTO+PT_GPR(13)[ep], r13;				      \
+	sld.w	PTO+PT_GPR(14)[ep], r14;				      \
+	sld.w	PTO+PT_GPR(15)[ep], r15;				      \
+	sld.w	PTO+PT_GPR(16)[ep], r16;				      \
+	sld.w	PTO+PT_GPR(17)[ep], r17;				      \
+	sld.w	PTO+PT_GPR(18)[ep], r18;				      \
+	sld.w	PTO+PT_GPR(19)[ep], r19;
+
+/* Save `call clobbered' registers to the struct pt_regs pointed to by EP.  */
+#define SAVE_CALL_CLOBBERED_REGS					      \
+	SAVE_CALL_CLOBBERED_REGS_BEFORE_ARGS;				      \
+	SAVE_ARG_REGS;							      \
+	SAVE_RVAL_REGS;							      \
+	SAVE_CALL_CLOBBERED_REGS_AFTER_RVAL;
+/* Restore `call clobbered' registers from the struct pt_regs pointed to
+   by EP.  */
+#define RESTORE_CALL_CLOBBERED_REGS					      \
+	RESTORE_CALL_CLOBBERED_REGS_BEFORE_ARGS;			      \
+	RESTORE_ARG_REGS;						      \
+	RESTORE_RVAL_REGS;						      \
+	RESTORE_CALL_CLOBBERED_REGS_AFTER_RVAL;
+
+/* Save `call clobbered' registers except for the return-value registers
+   to the struct pt_regs pointed to by EP.  */
+#define SAVE_CALL_CLOBBERED_REGS_NO_RVAL				      \
+	SAVE_CALL_CLOBBERED_REGS_BEFORE_ARGS;				      \
+	SAVE_ARG_REGS;							      \
+	SAVE_CALL_CLOBBERED_REGS_AFTER_RVAL;
+/* Restore `call clobbered' registers except for the return-value registers
+   from the struct pt_regs pointed to by EP.  */
+#define RESTORE_CALL_CLOBBERED_REGS_NO_RVAL				      \
+	RESTORE_CALL_CLOBBERED_REGS_BEFORE_ARGS;			      \
+	RESTORE_ARG_REGS;						      \
+	RESTORE_CALL_CLOBBERED_REGS_AFTER_RVAL;
+
+/* Zero `call clobbered' registers except for the return-value registers.  */
+#define ZERO_CALL_CLOBBERED_REGS_NO_RVAL				      \
+	mov	r0, r1;   mov	r0, r5;					      \
+	mov	r0, r12;  mov	r0, r13;  mov	r0, r14;  mov	r0, r15;      \
+	mov	r0, r16;  mov	r0, r17;  mov	r0, r18;  mov	r0, r19;
+
+/* Save `call saved' registers to the struct pt_regs pointed to by EP.  */
+#define SAVE_CALL_SAVED_REGS						      \
+	sst.w	r2, PTO+PT_GPR(2)[ep];					      \
+	sst.w	r20, PTO+PT_GPR(20)[ep];				      \
+	sst.w	r21, PTO+PT_GPR(21)[ep];				      \
+	sst.w	r22, PTO+PT_GPR(22)[ep];				      \
+	sst.w	r23, PTO+PT_GPR(23)[ep];				      \
+	sst.w	r24, PTO+PT_GPR(24)[ep];				      \
+	sst.w	r25, PTO+PT_GPR(25)[ep];				      \
+	sst.w	r26, PTO+PT_GPR(26)[ep];				      \
+	sst.w	r27, PTO+PT_GPR(27)[ep];				      \
+	sst.w	r28, PTO+PT_GPR(28)[ep];				      \
+	sst.w	r29, PTO+PT_GPR(29)[ep];
+/* Restore `call saved' registers from the struct pt_regs pointed to by EP.  */
+#define RESTORE_CALL_SAVED_REGS						      \
+	sld.w	PTO+PT_GPR(2)[ep], r2;					      \
+	sld.w	PTO+PT_GPR(20)[ep], r20;				      \
+	sld.w	PTO+PT_GPR(21)[ep], r21;				      \
+	sld.w	PTO+PT_GPR(22)[ep], r22;				      \
+	sld.w	PTO+PT_GPR(23)[ep], r23;				      \
+	sld.w	PTO+PT_GPR(24)[ep], r24;				      \
+	sld.w	PTO+PT_GPR(25)[ep], r25;				      \
+	sld.w	PTO+PT_GPR(26)[ep], r26;				      \
+	sld.w	PTO+PT_GPR(27)[ep], r27;				      \
+	sld.w	PTO+PT_GPR(28)[ep], r28;				      \
+	sld.w	PTO+PT_GPR(29)[ep], r29;
+
+
+/* Save system registers to the struct pt_regs pointed to by REG.  
+   r19 is clobbered.  */
+#define SAVE_SYS_REGS							      \
+	stsr	SR_EIPC, r19;	/* user's PC, before interrupt */	      \
+	sst.w	r19, PTO+PT_PC[ep];					      \
+	stsr	SR_EIPSW, r19;	/* & PSW (XXX save this?) */		      \
+	sst.w	r19, PTO+PT_PSW[ep];					      \
+	stsr	SR_CTPC, r19;	/* (XXX maybe not used in kernel?) */	      \
+	sst.w	r19, PTO+PT_CTPC[ep];					      \
+	stsr	SR_CTPSW, r19;	/* " */					      \
+	sst.w	r19, PTO+PT_CTPSW[ep];					      \
+	stsr	SR_CTBP, r19;	/* " */					      \
+	sst.w	r19, PTO+PT_CTBP[ep];
+/* Restore system registers from the struct pt_regs pointed to by EP.  
+   LP is clobbered (it is used as a scratch register because the POP_STATE
+   macro restores it, and this macro is usually used inside POP_STATE).  */
+#define RESTORE_SYS_REGS						      \
+	sld.w	PTO+PT_PC[ep], lp;					      \
+	ldsr	lp, SR_EIPC;	/* user's PC, before interrupt */	      \
+	sld.w	PTO+PT_PSW[ep], lp;					      \
+	ldsr	lp, SR_EIPSW;	/* & PSW (XXX save this?) */		      \
+	sld.w	PTO+PT_CTPC[ep], lp;					      \
+	ldsr	lp, SR_CTPC;	/* (XXX maybe not used in kernel?) */	      \
+	sld.w	PTO+PT_CTPSW[ep], lp;					      \
+	ldsr	lp, SR_CTPSW;	/* " */					      \
+	sld.w	PTO+PT_CTBP[ep], lp;					      \
+	ldsr	lp, SR_CTBP;	/* " */
+
+
+/* Save system registers to the struct pt_regs pointed to by REG.  This is a
+   NMI-specific version, because NMIs save the PC/PSW in a different place
+   than other interrupt requests.  r19 is clobbered.  */
+#define SAVE_SYS_REGS_FOR_NMI						      \
+	stsr	SR_FEPC, r19;	/* user's PC, before NMI */		      \
+	sst.w	r19, PTO+PT_PC[ep];					      \
+	stsr	SR_FEPSW, r19;	/* & PSW (XXX save this?) */		      \
+	sst.w	r19, PTO+PT_PSW[ep];					      \
+	stsr	SR_CTPC, r19;	/* (XXX maybe not used in kernel?) */	      \
+	sst.w	r19, PTO+PT_CTPC[ep];					      \
+	stsr	SR_CTPSW, r19;	/* " */					      \
+	sst.w	r19, PTO+PT_CTPSW[ep];					      \
+	stsr	SR_CTBP, r19;	/* " */					      \
+	sst.w	r19, PTO+PT_CTBP[ep];
+/* Restore system registers from the struct pt_regs pointed to by EP.  This is
+   a NMI-specific version, because NMIs save the PC/PSW in a different place
+   than other interrupt requests.  LP is clobbered (it is used as a scratch
+   register because the POP_STATE macro restores it, and this macro is usually
+   used inside POP_STATE).  */
+#define RESTORE_SYS_REGS_FOR_NMI					      \
+	ldsr	lp, SR_FEPC;	/* user's PC, before NMI */		      \
+	sld.w	PTO+PT_PC[ep], lp;					      \
+	ldsr	lp, SR_FEPSW;	/* & PSW (XXX save this?) */		      \
+	sld.w	PTO+PT_PSW[ep], lp;					      \
+	ldsr	lp, SR_CTPC;	/* (XXX maybe not used in kernel?) */	      \
+	sld.w	PTO+PT_CTPC[ep], lp;					      \
+	ldsr	lp, SR_CTPSW;	/* " */					      \
+	sld.w	PTO+PT_CTPSW[ep], lp;					      \
+	ldsr	lp, SR_CTBP;	/* " */					      \
+	sld.w	PTO+PT_CTBP[ep], lp;
+
+
+/* Push register state, except for the stack pointer, on the stack in the form
+   of a struct pt_regs, in preparation for a system call.  This macro makes
+   sure that `special' registers, system registers; TYPE identifies the set of
+   extra registers to be saved as well.  EP is clobbered.  */
+#define PUSH_STATE(type)						      \
+	addi	-STATE_SAVE_SIZE, sp, sp; /* Make room on the stack.  */      \
+	st.w	ep, PTO+PT_GPR(GPR_EP)[sp];				      \
+	mov	sp, ep;							      \
+	sst.w	gp, PTO+PT_GPR(GPR_GP)[ep];				      \
+	sst.w	lp, PTO+PT_GPR(GPR_LP)[ep];				      \
+	type ## _STATE_SAVER;
+/* Pop a register state, except for the stack pointer, from the struct pt_regs
+   on the stack.  */
+#define POP_STATE(type)							      \
+	mov	sp, ep;							      \
+	type ## _STATE_RESTORER;					      \
+	sld.w	PTO+PT_GPR(GPR_GP)[ep], gp;				      \
+	sld.w	PTO+PT_GPR(GPR_LP)[ep], lp;				      \
+	sld.w	PTO+PT_GPR(GPR_EP)[ep], ep;				      \
+	addi	STATE_SAVE_SIZE, sp, sp; /* Clean up our stack space.  */
+
+
+/* Switch to the kernel stack if necessary, and push register state on
+   the stack in the form of a struct pt_regs.  Also load the current
+   task pointer if switching from user mode.  The stack-pointer (r3)
+   should have already been saved to the memory location SP_SAVE_LOC
+   (the reason for this is that the interrupt vectors may be beyond a
+   22-bit signed offset jump from the actual interrupt handler, and this
+   allows them to save the stack-pointer and use that register to do an
+   indirect jump).  This macro makes sure that `special' registers,
+   system registers, and the stack pointer are saved; TYPE identifies
+   the set of extra registers to be saved as well.  SYSCALL_NUM is the
+   register in which the system-call number this state is for is stored
+   (r0 if this isn't a system call).  Interrupts should already be
+   disabled when calling this.  */
+#define SAVE_STATE(type, syscall_num, sp_save_loc)			      \
+        tst1	0, KM;			/* See if already in kernel mode.  */ \
+	bz	1f;							      \
+        /* Kernel-mode state save.  */					      \
+	ld.w	sp_save_loc, sp;	/* Reload kernel stack-pointer.  */   \
+	st.w	sp, (PT_GPR(GPR_SP)-PT_SIZE)[sp]; /* Save original SP. */     \
+        PUSH_STATE(type);						      \
+	mov	1, r19;			/* Was in kernel-mode.  */	      \
+        sst.w	r19, PTO+PT_KERNEL_MODE[ep]; /* [ep is set by PUSH_STATE] */  \
+        br	2f;							      \
+1:      /* User-mode state save.  */					      \
+        ld.w    KSP, sp;		/* Switch to kernel stack.  */	      \
+        PUSH_STATE(type);						      \
+        sst.w	r0, PTO+PT_KERNEL_MODE[ep]; /* Was in user-mode.  */	      \
+        ld.w    sp_save_loc, r19;				              \
+	sst.w	r19, PTO+PT_GPR(GPR_SP)[ep]; /* Store user SP.  */	      \
+	mov	1, r19;							      \
+	st.b	r19, KM;		/* Now we're in kernel-mode.  */      \
+	GET_CURRENT_TASK(CURRENT_TASK);	/* Fetch the current task pointer. */ \
+2:      /* Save away the syscall number.  */				      \
+        sst.w	syscall_num, PTO+PT_SYSCALL[ep]
+
+
+/* Save register state not normally saved by PUSH_STATE for TYPE.  */
+#define SAVE_EXTRA_STATE(type)						      \
+        mov	sp, ep;							      \
+	type ## _EXTRA_STATE_SAVER;
+/* Restore register state not normally restored by POP_STATE for TYPE.  */
+#define RESTORE_EXTRA_STATE(type)					      \
+        mov	sp, ep;							      \
+	type ## _EXTRA_STATE_RESTORER;
+
+/* Save any call-clobbered registers not normally saved by PUSH_STATE
+   for TYPE.  */
+#define SAVE_EXTRA_STATE_FOR_FUNCALL(type)				      \
+        mov	sp, ep;							      \
+	type ## _FUNCALL_EXTRA_STATE_SAVER;
+/* Restore any call-clobbered registers not normally restored by POP_STATE for
+   TYPE.  */
+#define RESTORE_EXTRA_STATE_FOR_FUNCALL(type)				      \
+        mov	sp, ep;							      \
+	type ## _FUNCALL_EXTRA_STATE_RESTORER;
+
+
+/* These are extra_state_saver/restorer values for a user trap.  Note that we
+   save the argument registers so that restarted syscalls will function
+   properly (otherwise it wouldn't be necessary), and we must _not_ restore
+   the return-value registers (so that traps can return a value!), but there
+   are various options for what happens to other call-clobbered registers,
+   selected by preprocessor conditionals.  */
+
+#if TRAPS_PRESERVE_CALL_CLOBBERED_REGS
+   
+/* Traps save/restore all call-clobbered registers (except for rval regs).  */
+#define TRAP_STATE_SAVER						      \
+     SAVE_CALL_CLOBBERED_REGS_NO_RVAL;					      \
+     SAVE_SYS_REGS
+#define TRAP_STATE_RESTORER						      \
+     RESTORE_CALL_CLOBBERED_REGS_NO_RVAL;				      \
+     RESTORE_SYS_REGS
+
+#else /* !TRAPS_PRESERVE_CALL_CLOBBERED_REGS */
+
+/* Traps don't save call-clobbered registers (but do still save arg regs).  */
+#define TRAP_STATE_SAVER						      \
+     SAVE_ARG_REGS;							      \
+     SAVE_SYS_REGS
+
+#if TRAPS_ZERO_CALL_CLOBBERED_REGS
+   
+/* Traps zero call-clobbered registers (except for arg/rval regs) before
+   returning from a system call, to avoid any internal values from leaking out
+   of the kernel.  */
+#define TRAP_STATE_RESTORER						      \
+     ZERO_CALL_CLOBBERED_REGS_NO_ARGS_NO_RVAL;				      \
+     RESTORE_ARG_REGS;							      \
+     RESTORE_SYS_REGS
+
+#else /* !TRAPS_ZERO_CALL_CLOBBERED_REGS */
+   
+/* When traps return, they just leave call-clobbered registers (except for arg
+   regs) with whatever value they have from the kernel.  */
+#define TRAP_STATE_RESTORER						      \
+     RESTORE_ARG_REGS;							      \
+     RESTORE_SYS_REGS
+
+#endif /* TRAPS_ZERO_CALL_CLOBBERED_REGS */
+#endif /* TRAPS_PRESERVE_CALL_CLOBBERED_REGS */
+
+/* Save registers not normally saved by traps.  */
+#define TRAP_EXTRA_STATE_SAVER						      \
+   SAVE_RVAL_REGS;							      \
+   SAVE_CALL_SAVED_REGS
+#define TRAP_EXTRA_STATE_RESTORER					      \
+   RESTORE_RVAL_REGS;							      \
+   RESTORE_CALL_SAVED_REGS
+#define TRAP_FUNCALL_EXTRA_STATE_SAVER					      \
+   SAVE_RVAL_REGS
+#define TRAP_FUNCALL_EXTRA_STATE_RESTORER				      \
+   RESTORE_RVAL_REGS
+
+
+/* Register saving/restoring for maskable interrupts.  */
+#define IRQ_STATE_SAVER							      \
+   SAVE_CALL_CLOBBERED_REGS;						      \
+   SAVE_SYS_REGS
+#define IRQ_STATE_RESTORER						      \
+   RESTORE_CALL_CLOBBERED_REGS;						      \
+   RESTORE_SYS_REGS
+#define IRQ_EXTRA_STATE_SAVER						      \
+   SAVE_CALL_SAVED_REGS
+#define IRQ_EXTRA_STATE_RESTORER					      \
+   RESTORE_CALL_SAVED_REGS
+#define IRQ_FUNCALL_EXTRA_STATE_SAVER       /* nothing */
+#define IRQ_FUNCALL_EXTRA_STATE_RESTORER    /* nothing */
+
+/* Register saving/restoring for non-maskable interrupts.  */
+#define NMI_STATE_SAVER							      \
+   SAVE_CALL_CLOBBERED_REGS;						      \
+   SAVE_SYS_REGS_FOR_NMI
+#define NMI_STATE_RESTORER						      \
+   RESTORE_CALL_CLOBBERED_REGS;						      \
+   RESTORE_SYS_REGS_FOR_NMI
+#define NMI_EXTRA_STATE_SAVER						      \
+   SAVE_CALL_SAVED_REGS
+#define NMI_EXTRA_STATE_RESTORER					      \
+   RESTORE_CALL_SAVED_REGS
+#define NMI_FUNCALL_EXTRA_STATE_SAVER       /* nothing */
+#define NMI_FUNCALL_EXTRA_STATE_RESTORER    /* nothing */
+   
+/* Register saving/restoring for a context switch.  We don't need to save too
+   many registers, because context-switching looks like a function call (via
+   the function `switch_thread'), so callers will save any call-clobbered
+   registers themselves.  The stack pointer and return value are handled by
+   switch_thread itself.  */
+#define SWITCH_STATE_SAVER						      \
+   SAVE_CALL_SAVED_REGS
+#define SWITCH_STATE_RESTORER						      \
+   RESTORE_CALL_SAVED_REGS
+
+
+/* Restore register state from the struct pt_regs on the stack, switch back
+   to the user stack if necessary, and return from the trap/interrupt.
+   EXTRA_STATE_RESTORER is a sequence of assembly language statements to
+   restore anything not restored by this macro.  Only registers not saved by
+   the C compiler are restored (that is, R3(sp), R4(gp), R31(lp), and
+   anything restored by EXTRA_STATE_RESTORER).  */
+#define RETURN(type)							      \
+        ld.b	PTO+PT_KERNEL_MODE[sp], r19;				      \
+	di;				/* Disable interrupts */	      \
+	cmp	r19, r0;		/* See if returning to kernel mode, */\
+	bne	2f;			/* ... if so, skip resched &c.  */    \
+									      \
+	/* We're returning to user mode, so check for various conditions that \
+	   trigger rescheduling. */					      \
+	GET_CURRENT_THREAD(r18);					      \
+	ld.w	TI_FLAGS[r18], r19;					      \
+	andi	_TIF_NEED_RESCHED, r19, r0;				      \
+	bnz	3f;			/* Call the scheduler.  */	      \
+	andi	_TIF_SIGPENDING, r19, r0;				      \
+	bnz	4f;			/* Signals to handle, handle them */  \
+									      \
+/* Finally, return to user state.  */					      \
+1:	st.b	r0, KM;			/* Now officially in user state. */   \
+	POP_STATE(type);						      \
+	st.w	sp, KSP;		/* Save the kernel stack pointer. */  \
+	ld.w    PT_GPR(GPR_SP)-PT_SIZE[sp], sp;				      \
+					/* Restore user stack pointer. */     \
+	reti;								      \
+									      \
+/* Return to kernel state.  */						      \
+2:	POP_STATE(type);						      \
+	reti;								      \
+									      \
+/* Call the scheduler before returning from a syscall/trap. */		      \
+3:	SAVE_EXTRA_STATE_FOR_FUNCALL(type); /* Prepare for funcall. */	      \
+	jarl	CSYM(schedule), lp;	/* Call scheduler */		      \
+	di;				/* The scheduler enables interrupts */\
+	RESTORE_EXTRA_STATE_FOR_FUNCALL(type);				      \
+	br	1b;							      \
+									      \
+/* Handle a signal return.  */						      \
+4:      /* Not all registers are saved by the normal trap/interrupt entry     \
+	   points (for instance, call-saved registers (because the normal     \
+	   C-compiler calling sequence in the kernel makes sure they're	      \
+	   preserved), and call-clobbered registers in the case of	      \
+	   traps), but signal handlers may want to examine or change the      \
+	   complete register state.  Here we save anything not saved by	      \
+	   the normal entry sequence, so that it may be safely restored	      \
+	   (in a possibly modified form) after do_signal returns.  */	      \
+        SAVE_EXTRA_STATE(type)		/* Save state not saved by entry. */  \
+	movea	PTO, sp, r6;		/* Arg 1: struct pt_regs *regs */     \
+	mov	r0, r7;			/* Arg 2: sigset_t *oldset */	      \
+	jarl	CSYM(do_signal), lp;	/* Handle any signals */	      \
+	di;				/* sig handling enables interrupts */ \
+        RESTORE_EXTRA_STATE(type);	/* Restore extra regs.  */	      \
+	br	1b;
+
+
+/* Jump to the appropriate function for the system call number in r12
+   (r12 is not preserved), or return an error if r12 is not valid.  The
+   LP register should point to the location where the called function
+   should return.  [note that MAKE_SYS_CALL uses label 1]  */
+#define MAKE_SYS_CALL							      \
+	/* See if the system call number is valid.  */			      \
+	addi	-NR_syscalls, r12, r0;					      \
+	bnh	1f;							      \
+	/* Figure out which function to use for this system call.  */	      \
+	shl	2, r12;							      \
+	mov	hilo(CSYM(sys_call_table)), r19;			      \
+	add	r19, r12;						      \
+	ld.w	0[r12], r12;						      \
+	/* Make the system call.  */					      \
+	jmp	[r12];							      \
+	/* The syscall number is invalid, return an error.  */		      \
+1:	addi	-ENOSYS, r0, r10;					      \
+	jmp	[lp];
+
+
+	.text
+
+/*
+ * User trap.
+ *
+ * Trap 0 system calls are also handled here.
+ *
+ * The stack-pointer (r3) should have already been saved to the memory
+ * location ENTRY_SP (the reason for this is that the interrupt vectors may be
+ * beyond a 22-bit signed offset jump from the actual interrupt handler, and
+ * this allows them to save the stack-pointer and use that register to do an
+ * indirect jump).
+ *	
+ * Syscall protocol:
+ *   Syscall number in r12, args in r6-r9
+ *   Return value in r10
+ */
+G_ENTRY(trap):
+	SAVE_STATE (TRAP, r12, ENTRY_SP) // Save registers. 
+	stsr	SR_ECR, r19		// Find out which trap it was.
+	ei				// Enable interrupts.
+	mov	hilo(ret_from_trap), lp	// where the trap should return
+
+	// The following two shifts (1) clear out extraneous NMI data in the
+	// upper 16-bits, (2) convert the 0x40 - 0x5f range of trap ECR
+	// numbers into the (0-31) << 2 range we want, (3) set the flags.
+	shl	27, r19			// chop off all high bits
+	shr	25, r19			// scale back down and then << 2
+	bnz	2f			// See if not trap 0. 
+
+	// Trap 0 is a `short' system call, skip general trap table. 
+	MAKE_SYS_CALL			// Jump to the syscall function. 
+
+2:	// For other traps, use a table lookup. 
+	mov	hilo(CSYM(trap_table)), r18
+	add	r19, r18
+	ld.w	0[r18], r18
+	jmp	[r18]			// Jump to the trap handler.
+END(trap)
+
+/* This is just like ret_from_trap, but first restores extra registers
+   saved by some wrappers.  */
+L_ENTRY(restore_extra_regs_and_ret_from_trap):
+	RESTORE_EXTRA_STATE(TRAP)
+	// fall through
+END(restore_extra_regs_and_ret_from_trap)
+
+/* Entry point used to return from a syscall/trap.  */
+L_ENTRY(ret_from_trap):
+	RETURN(TRAP)
+END(ret_from_trap)
+
+/* This the initial entry point for a new child thread, with an appropriate
+   stack in place that makes it look the the child is in the middle of an
+   syscall.  This function is actually `returned to' from switch_thread
+   (copy_thread makes ret_from_fork the return address in each new thread's
+   saved context).  */
+C_ENTRY(ret_from_fork):
+#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
+	mov	r10, r6			// switch_thread returns the prev task.
+	jarl	CSYM(schedule_tail), lp	// ...which is schedule_tail's arg
+#endif
+	mov	r0, r10			// Child's fork call should return 0.
+	br	ret_from_trap		// Do normal trap return.
+C_END(ret_from_fork)
+
+
+/*
+ * Trap 1: `long' system calls
+ * `Long' syscall protocol:
+ *   Syscall number in r12, args in r6-r9, r13-r14
+ *   Return value in r10
+ */
+L_ENTRY(syscall_long):
+	// Push extra arguments on the stack.  Note that by default, the trap
+	// handler reserves enough stack space for 6 arguments, so we don't
+	// have to make any additional room.
+	st.w	r13, 16[sp]		// arg 5
+	st.w	r14, 20[sp]		// arg 6
+
+#if !TRAPS_PRESERVE_CALL_CLOBBERED_REGS
+	// Make sure r13 and r14 are preserved, in case we have to restart a
+	// system call because of a signal (ep has already been set by caller).
+	st.w	r13, PTO+PT_GPR(13)[sp]
+	st.w	r14, PTO+PT_GPR(13)[sp]
+	mov	hilo(ret_from_long_syscall), lp
+#endif /* !TRAPS_PRESERVE_CALL_CLOBBERED_REGS */
+
+	MAKE_SYS_CALL			// Jump to the syscall function.
+END(syscall_long)	
+
+#if !TRAPS_PRESERVE_CALL_CLOBBERED_REGS
+/* Entry point used to return from a long syscall.  Only needed to restore
+   r13/r14 if the general trap mechanism doesnt' do so.  */
+L_ENTRY(ret_from_long_syscall):
+	ld.w	PTO+PT_GPR(13)[sp], r13 // Restore the extra registers
+	ld.w	PTO+PT_GPR(13)[sp], r14
+	br	ret_from_trap		// The rest is the same as other traps
+END(ret_from_long_syscall)
+#endif /* !TRAPS_PRESERVE_CALL_CLOBBERED_REGS */
+
+
+/* These syscalls need access to the struct pt_regs on the stack, so we
+   implement them in assembly (they're basically all wrappers anyway).  */
+
+L_ENTRY(sys_fork_wrapper):
+#ifdef CONFIG_MMU
+	// Save state not saved by entry.  This is actually slight overkill;
+	// it's actually only necessary to save any state restored by
+	// switch_thread that's not saved by the trap entry.
+	SAVE_EXTRA_STATE(TRAP)		// Save state not saved by entry.
+	addi	SIGCHLD, r0, r6		// Arg 0: flags
+	ld.w	PTO+PT_GPR(GPR_SP)[sp], r7 // Arg 1: child SP (use parent's)
+	movea	PTO, sp, r8		// Arg 2: parent context
+	jr	CSYM(fork_common)	// Do real work (tail-call).
+#else
+	// fork almost works, enough to trick you into looking elsewhere :-(
+	addi	-EINVAL, r0, r10
+	jmp	[lp]
+#endif
+END(sys_fork_wrapper)
+
+L_ENTRY(sys_vfork_wrapper):
+	// Save state not saved by entry.  This is actually slight overkill;
+	// it's actually only necessary to save any state restored by
+	// switch_thread that's not saved by the trap entry.
+	SAVE_EXTRA_STATE(TRAP)		// Save state not saved by entry.
+	addi	CLONE_VFORK | CLONE_VM | SIGCHLD, r0, r6 // Arg 0: flags
+	ld.w	PTO+PT_GPR(GPR_SP)[sp], r7 // Arg 1: child SP (use parent's)
+	movea	PTO, sp, r8		// Arg 2: parent context
+	jr	CSYM(fork_common)	// Do real work (tail-call).
+END(sys_vfork_wrapper)
+
+L_ENTRY(sys_clone_wrapper):
+	// Save state not saved by entry.  This is actually slight overkill;
+	// it's actually only necessary to save any state restored by
+	// switch_thread that's not saved by the trap entry.
+	SAVE_EXTRA_STATE(TRAP)		// Save state not saved by entry.
+	ld.w	PTO+PT_GPR(GPR_SP)[sp], r19 // parent's stack pointer
+        cmp	r7, r0			// See if child SP arg (arg 1) is 0.
+	cmov	z, r19, r7, r7		// ... and use the parent's if so. 
+	movea	PTO, sp, r8		// Arg 2: parent context
+	jr	CSYM(fork_common)	// Do real work (tail-call).
+END(sys_clone_wrapper)
+
+L_ENTRY(sys_execve_wrapper):
+	movea	PTO, sp, r9		// add user context as 4th arg
+	jr	CSYM(sys_execve)	// Do real work (tail-call).
+END(sys_execve_wrapper)
+
+L_ENTRY(sys_sigsuspend_wrapper):
+        SAVE_EXTRA_STATE(TRAP)		// Save state not saved by entry.
+	movea	PTO, sp, r7		// add user context as 2nd arg
+	jarl	CSYM(sys_sigsuspend), lp// Do real work.
+	br	restore_extra_regs_and_ret_from_trap
+END(sys_sigsuspend_wrapper)
+L_ENTRY(sys_rt_sigsuspend_wrapper):
+        SAVE_EXTRA_STATE(TRAP)		// Save state not saved by entry.
+	movea	PTO, sp, r8		// add user context as 3rd arg
+	jarl	CSYM(sys_rt_sigsuspend), lp	// Do real work.
+	br	restore_extra_regs_and_ret_from_trap
+END(sys_rt_sigsuspend_wrapper)
+
+L_ENTRY(sys_sigreturn_wrapper):
+        SAVE_EXTRA_STATE(TRAP)		// Save state not saved by entry.
+	movea	PTO, sp, r6		// add user context as 1st arg
+	jarl	CSYM(sys_sigreturn), lp	// Do real work.
+	br	restore_extra_regs_and_ret_from_trap
+END(sys_sigreturn_wrapper)
+L_ENTRY(sys_rt_sigreturn_wrapper):
+        SAVE_EXTRA_STATE(TRAP)		// Save state not saved by entry.
+	movea	PTO, sp, r6		// add user context as 1st arg
+	jarl	CSYM(sys_rt_sigreturn), lp	// Do real work.
+	br	restore_extra_regs_and_ret_from_trap
+END(sys_rt_sigreturn_wrapper)
+
+
+/*
+ * Hardware maskable interrupts.
+ *
+ * The stack-pointer (r3) should have already been saved to the memory
+ * location ENTRY_SP (the reason for this is that the interrupt vectors may be
+ * beyond a 22-bit signed offset jump from the actual interrupt handler, and
+ * this allows them to save the stack-pointer and use that register to do an
+ * indirect jump).
+ */
+G_ENTRY(irq):
+	SAVE_STATE (IRQ, r0, ENTRY_SP)	// Save registers. 
+
+	stsr	SR_ECR, r6		// Find out which interrupt it was.
+	movea	PTO, sp, r7		// User regs are arg2
+
+	// All v850 implementations I know about encode their interrupts as
+	// multiples of 0x10, starting at 0x80 (after NMIs and software
+	// interrupts).  Convert this number into a simple IRQ index for the
+	// rest of the kernel.  We also clear the upper 16 bits, which hold
+	// NMI info, and don't appear to be cleared when a NMI returns.
+	shl	16, r6			// clear upper 16 bits
+	shr	20, r6			// shift back, and remove lower nibble
+	add	-8, r6			// remove bias for irqs
+	// Call the high-level interrupt handling code.
+	jarl	CSYM(handle_irq), lp
+	// fall through
+
+/* Entry point used to return from an interrupt (also used by exception
+   handlers, below).  */
+ret_from_irq:
+	RETURN(IRQ)
+END(irq)
+
+
+/*
+ * Hardware non-maskable interrupts.
+ *
+ * The stack-pointer (r3) should have already been saved to the memory
+ * location ENTRY_SP (the reason for this is that the interrupt vectors may be
+ * beyond a 22-bit signed offset jump from the actual interrupt handler, and
+ * this allows them to save the stack-pointer and use that register to do an
+ * indirect jump).
+ */
+G_ENTRY(nmi):
+	SAVE_STATE (NMI, r0, NMI_ENTRY_SP); /* Save registers.  */
+
+	stsr	SR_ECR, r6;		/* Find out which nmi it was.  */
+	shr	20, r6;			/* Extract NMI code in bits 20-24. */
+	movea	PTO, sp, r7;		/* User regs are arg2.  */
+
+	/* Non-maskable interrupts always lie right after maskable interrupts.
+	   Call the generic IRQ handler, with two arguments, the IRQ number,
+	   and a pointer to the user registers, to handle the specifics.
+	   (we subtract one because the first NMI has code 1).  */
+	addi	FIRST_NMI - 1, r6, r6;
+	jarl	CSYM(handle_irq), lp
+
+	RETURN(NMI)
+END(nmi0)
+
+
+/*
+ * Illegal instruction trap.
+ *
+ * The stack-pointer (r3) should have already been saved to the memory
+ * location ENTRY_SP (the reason for this is that the interrupt vectors may be
+ * beyond a 22-bit signed offset jump from the actual interrupt handler, and
+ * this allows them to save the stack-pointer and use that register to do an
+ * indirect jump).
+ */
+G_ENTRY(illegal_instruction):
+	SAVE_STATE (IRQ, r0, ENTRY_SP)	// Save registers. 
+	ei
+	addi	SIGILL, r0, r6		// Arg 0: signal number
+	mov	CURRENT_TASK, r7	// Arg 1: task
+	mov	hilo(ret_from_irq), lp	// where the handler should return
+	jr	CSYM(force_sig)
+END(illegal_instruction)
+
+
+/*
+ * `Debug' trap
+ *
+ * The stack-pointer (r3) should have already been saved to the memory
+ * location ENTRY_SP (the reason for this is that the interrupt vectors may be
+ * beyond a 22-bit signed offset jump from the actual interrupt handler, and
+ * this allows them to save the stack-pointer and use that register to do an
+ * indirect jump).
+ */
+G_ENTRY(dbtrap):
+	SAVE_STATE (IRQ, r0, ENTRY_SP)	// Save registers. 
+	ei
+	movea	PTO, sp, r6		// Arg 0: user regs
+	mov	hilo(ret_from_irq), lp	// where the handler should return
+	jr	CSYM(debug_trap)
+END(dbtrap)
+
+
+/*
+ * Trap with no handler
+ */
+L_ENTRY(bad_trap_wrapper):
+	mov	r19, r6			// Arg 0: trap number
+	movea	PTO, sp, r7		// Arg 1: user regs
+	jr	CSYM(bad_trap)		// tail call handler
+END(bad_trap_wrapper)
+
+
+/*
+ * This is where we switch between two threads.  The arguments are:
+ *   r6 -- pointer to the struct thread for the `current' process
+ *   r7 -- pointer to the struct thread for the `new' process.  
+ * when this function returns, it will return to the new thread.
+ */
+C_ENTRY(switch_thread):
+	// Return the previous task (r10 is not clobbered by restore below)
+	mov	CURRENT_TASK, r10
+	// First, push the current processor state on the stack
+	PUSH_STATE(SWITCH)
+	// Now save the location of the kernel stack pointer for this thread;
+	// since we've pushed all other state on the stack, this is enough to
+	// restore it all later.
+	st.w	sp, THREAD_KSP[r6]
+	// Now restore the stack pointer from the new process
+	ld.w	THREAD_KSP[r7], sp
+	// ... and restore all state from that
+	POP_STATE(SWITCH)
+	// Update the current task pointer
+	GET_CURRENT_TASK(CURRENT_TASK)
+	// Now return into the new thread
+	jmp	[lp]
+C_END(switch_thread)
+
+
+	.data
+
+	.align 4
+	.globl CSYM(trap_table)
+CSYM(trap_table):
+	.long bad_trap_wrapper		// trap 0, doesn't use trap table. 
+	.long syscall_long		// trap 1, `long' syscall. 
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+
+
+	.section .rodata
+	
+	.align 4
+	.globl CSYM(sys_call_table)
+CSYM(sys_call_table):
+	.long CSYM(sys_ni_syscall)	// 0  -  old "setup()" system call
+	.long CSYM(sys_exit)
+	.long sys_fork_wrapper
+	.long CSYM(sys_read)
+	.long CSYM(sys_write)
+	.long CSYM(sys_open)		// 5
+	.long CSYM(sys_close)
+	.long CSYM(sys_waitpid)
+	.long CSYM(sys_creat)
+	.long CSYM(sys_link)
+	.long CSYM(sys_unlink)		// 10
+	.long sys_execve_wrapper
+	.long CSYM(sys_chdir)
+	.long CSYM(sys_time)
+	.long CSYM(sys_mknod)
+	.long CSYM(sys_chmod)		// 15
+	.long CSYM(sys_chown)
+	.long CSYM(sys_ni_syscall)	// was: break
+	.long CSYM(sys_ni_syscall)	// was: oldstat (aka stat)
+	.long CSYM(sys_lseek)
+	.long CSYM(sys_getpid)		// 20
+	.long CSYM(sys_mount)
+	.long CSYM(sys_oldumount)
+	.long CSYM(sys_setuid)
+	.long CSYM(sys_getuid)
+	.long CSYM(sys_stime)		// 25
+	.long CSYM(sys_ptrace)
+	.long CSYM(sys_alarm)
+	.long CSYM(sys_ni_syscall)	// was: oldfstat (aka fstat)
+	.long CSYM(sys_pause)
+	.long CSYM(sys_utime)		// 30
+	.long CSYM(sys_ni_syscall)	// was: stty
+	.long CSYM(sys_ni_syscall)	// was: gtty
+	.long CSYM(sys_access)
+	.long CSYM(sys_nice)
+	.long CSYM(sys_ni_syscall)	// 35, was: ftime
+	.long CSYM(sys_sync)
+	.long CSYM(sys_kill)
+	.long CSYM(sys_rename)
+	.long CSYM(sys_mkdir)
+	.long CSYM(sys_rmdir)		// 40
+	.long CSYM(sys_dup)
+	.long CSYM(sys_pipe)
+	.long CSYM(sys_times)
+	.long CSYM(sys_ni_syscall)	// was: prof
+	.long CSYM(sys_brk)		// 45
+	.long CSYM(sys_setgid)
+	.long CSYM(sys_getgid)
+	.long CSYM(sys_signal)
+	.long CSYM(sys_geteuid)
+	.long CSYM(sys_getegid)		// 50
+	.long CSYM(sys_acct)
+	.long CSYM(sys_umount)		// recycled never used phys()
+	.long CSYM(sys_ni_syscall)	// was: lock
+	.long CSYM(sys_ioctl)
+	.long CSYM(sys_fcntl)		// 55
+	.long CSYM(sys_ni_syscall)	// was: mpx
+	.long CSYM(sys_setpgid)
+	.long CSYM(sys_ni_syscall) 	// was: ulimit
+	.long CSYM(sys_ni_syscall)
+	.long CSYM(sys_umask)		// 60
+	.long CSYM(sys_chroot)
+	.long CSYM(sys_ustat)
+	.long CSYM(sys_dup2)
+	.long CSYM(sys_getppid)
+	.long CSYM(sys_getpgrp)		// 65
+	.long CSYM(sys_setsid)
+	.long CSYM(sys_sigaction)
+	.long CSYM(sys_sgetmask)
+	.long CSYM(sys_ssetmask)
+	.long CSYM(sys_setreuid)	// 70
+	.long CSYM(sys_setregid)
+	.long sys_sigsuspend_wrapper
+	.long CSYM(sys_sigpending)
+	.long CSYM(sys_sethostname)
+	.long CSYM(sys_setrlimit)	// 75
+	.long CSYM(sys_getrlimit)
+	.long CSYM(sys_getrusage)
+	.long CSYM(sys_gettimeofday)
+	.long CSYM(sys_settimeofday)
+	.long CSYM(sys_getgroups)	// 80
+	.long CSYM(sys_setgroups)
+	.long CSYM(sys_select)
+	.long CSYM(sys_symlink)
+	.long CSYM(sys_ni_syscall)	// was: oldlstat (aka lstat)
+	.long CSYM(sys_readlink)	// 85
+	.long CSYM(sys_uselib)
+	.long CSYM(sys_swapon)
+	.long CSYM(sys_reboot)
+	.long CSYM(old_readdir)
+	.long CSYM(sys_mmap)		// 90
+	.long CSYM(sys_munmap)
+	.long CSYM(sys_truncate)
+	.long CSYM(sys_ftruncate)
+	.long CSYM(sys_fchmod)
+	.long CSYM(sys_fchown)		// 95
+	.long CSYM(sys_getpriority)
+	.long CSYM(sys_setpriority)
+	.long CSYM(sys_ni_syscall) 	// was: profil
+	.long CSYM(sys_statfs)
+	.long CSYM(sys_fstatfs)		// 100
+	.long CSYM(sys_ni_syscall)	// i386: ioperm
+	.long CSYM(sys_socketcall)
+	.long CSYM(sys_syslog)
+	.long CSYM(sys_setitimer)
+	.long CSYM(sys_getitimer)	// 105
+	.long CSYM(sys_newstat)
+	.long CSYM(sys_newlstat)
+	.long CSYM(sys_newfstat)
+	.long CSYM(sys_ni_syscall)	// was: olduname (aka uname)
+	.long CSYM(sys_ni_syscall)	// 110, i386: iopl
+	.long CSYM(sys_vhangup)
+	.long CSYM(sys_ni_syscall)	// was: idle
+	.long CSYM(sys_ni_syscall)	// i386: vm86old
+	.long CSYM(sys_wait4)
+	.long CSYM(sys_swapoff)		// 115
+	.long CSYM(sys_sysinfo)
+	.long CSYM(sys_ipc)
+	.long CSYM(sys_fsync)
+	.long sys_sigreturn_wrapper
+	.long sys_clone_wrapper		// 120
+	.long CSYM(sys_setdomainname)
+	.long CSYM(sys_newuname)
+	.long CSYM(sys_ni_syscall)	// i386: modify_ldt, m68k: cacheflush 
+	.long CSYM(sys_adjtimex)
+	.long CSYM(sys_ni_syscall)	// 125 - sys_mprotect
+	.long CSYM(sys_sigprocmask)
+	.long CSYM(sys_create_module)
+	.long CSYM(sys_init_module)
+	.long CSYM(sys_delete_module)
+	.long CSYM(sys_get_kernel_syms) // 130
+	.long CSYM(sys_quotactl)
+	.long CSYM(sys_getpgid)
+	.long CSYM(sys_fchdir)
+	.long CSYM(sys_bdflush)
+	.long CSYM(sys_sysfs)		// 135
+	.long CSYM(sys_personality)
+	.long CSYM(sys_ni_syscall)	// for afs_syscall
+	.long CSYM(sys_setfsuid)
+	.long CSYM(sys_setfsgid)
+	.long CSYM(sys_llseek)		// 140
+	.long CSYM(sys_getdents)
+	.long CSYM(sys_select)		// for backward compat; remove someday
+	.long CSYM(sys_flock)
+	.long CSYM(sys_ni_syscall)	// sys_msync
+	.long CSYM(sys_readv)		// 145
+	.long CSYM(sys_writev)
+	.long CSYM(sys_getsid)
+	.long CSYM(sys_fdatasync)
+	.long CSYM(sys_sysctl)
+	.long CSYM(sys_ni_syscall)	// 150 - sys_mlock
+	.long CSYM(sys_ni_syscall)	// sys_munlock
+	.long CSYM(sys_ni_syscall)	// sys_mlockall
+	.long CSYM(sys_ni_syscall)	// sys_munlockall
+	.long CSYM(sys_sched_setparam)
+	.long CSYM(sys_sched_getparam)	// 155
+	.long CSYM(sys_sched_setscheduler)
+	.long CSYM(sys_sched_getscheduler)
+	.long CSYM(sys_sched_yield)
+	.long CSYM(sys_sched_get_priority_max)
+	.long CSYM(sys_sched_get_priority_min)  // 160
+	.long CSYM(sys_sched_rr_get_interval)
+	.long CSYM(sys_nanosleep)
+	.long CSYM(sys_ni_syscall)	// sys_mremap
+	.long CSYM(sys_setresuid)
+	.long CSYM(sys_getresuid)	// 165
+	.long CSYM(sys_ni_syscall)	// for vm86
+	.long CSYM(sys_query_module)
+	.long CSYM(sys_poll)
+	.long CSYM(sys_nfsservctl)
+	.long CSYM(sys_setresgid)	// 170
+	.long CSYM(sys_getresgid)
+	.long CSYM(sys_prctl)
+	.long sys_rt_sigreturn_wrapper
+	.long CSYM(sys_rt_sigaction)
+	.long CSYM(sys_rt_sigprocmask)	// 175
+	.long CSYM(sys_rt_sigpending)
+	.long CSYM(sys_rt_sigtimedwait)
+	.long CSYM(sys_rt_sigqueueinfo)
+	.long sys_rt_sigsuspend_wrapper
+	.long CSYM(sys_pread64)		// 180
+	.long CSYM(sys_pwrite64)
+	.long CSYM(sys_lchown)
+	.long CSYM(sys_getcwd)
+	.long CSYM(sys_capget)
+	.long CSYM(sys_capset)		// 185
+	.long CSYM(sys_sigaltstack)
+	.long CSYM(sys_sendfile)
+	.long CSYM(sys_ni_syscall)	// streams1
+	.long CSYM(sys_ni_syscall)	// streams2
+	.long sys_vfork_wrapper		// 190
+	.long CSYM(sys_ni_syscall)
+	.long CSYM(sys_mmap2)
+	.long CSYM(sys_truncate64)
+	.long CSYM(sys_ftruncate64)
+	.long CSYM(sys_stat64)		// 195
+	.long CSYM(sys_lstat64)
+	.long CSYM(sys_fstat64)
+	.long CSYM(sys_fcntl64)
+	.long CSYM(sys_getdents64)
+	.long CSYM(sys_pivot_root)	// 200
+	.long CSYM(sys_gettid)
+	.long CSYM(sys_tkill)
+	.long CSYM(sys_ni_syscall)	// sys_mincore
+	.long CSYM(sys_ni_syscall)	// sys_madvise
+
+	.space (NR_syscalls-205)*4
diff -Nru a/arch/v850/kernel/fpga85e2c.c b/arch/v850/kernel/fpga85e2c.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/fpga85e2c.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,167 @@
+/*
+ * arch/v850/kernel/fpga85e2c.h -- Machine-dependent defs for
+ *	FPGA implementation of V850E2/NA85E2C
+ *
+ *  Copyright (C) 2002  NEC Corporation
+ *  Copyright (C) 2002  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+
+#include <asm/atomic.h>
+#include <asm/page.h>
+#include <asm/machdep.h>
+#include <asm/bitops.h>
+
+#include "mach.h"
+
+extern void memcons_setup (void);
+
+
+#define REG_DUMP_ADDR		0x220000
+
+
+extern struct irqaction reg_snap_action; /* fwd decl */
+
+
+void __init mach_early_init (void)
+{
+	int i;
+	const u32 *src;
+	register u32 *dst asm ("ep");
+	extern int panic_timeout;
+	extern u32 _intv_end, _intv_load_start;
+
+	/* Set bus sizes: CS0 32-bit, CS1 16-bit, CS7 8-bit,
+	   everything else 32-bit.  */
+	BSC = 0x2AA6;
+	for (i = 2; i <= 6; i++)
+		CSDEV(i) = 0;	/* 32 bit */
+
+	/* Ensure that the simulator halts on a panic, instead of going
+	   into an infinite loop inside the panic function.  */
+	panic_timeout = -1;
+
+	/* Move the interrupt vectors into their real location.  Note that
+	   any relocations there are relative to the real location, so we
+	   don't have to fix anything up.  We use a loop instead of calling
+	   memcpy to keep this a leaf function (to avoid a function
+	   prologue being generated).  */
+	dst = 0x10;		/* &_intv_start + 0x10.  */
+	src = &_intv_load_start;
+	do {
+		u32 t0 = src[0], t1 = src[1], t2 = src[2], t3 = src[3];
+		u32 t4 = src[4], t5 = src[5], t6 = src[6], t7 = src[7];
+		dst[0] = t0; dst[1] = t1; dst[2] = t2; dst[3] = t3;
+		dst[4] = t4; dst[5] = t5; dst[6] = t6; dst[7] = t7;
+		dst += 8;
+		src += 8;
+	} while (dst < &_intv_end);
+}
+
+void __init mach_setup (char **cmdline)
+{
+	printk (KERN_INFO "CPU: NEC V850E2 (NA85E2C FPGA implementation)\n");
+
+	memcons_setup ();
+
+	/* Setup up NMI0 to copy the registers to a known memory location.
+	   The FGPA board has a button that produces NMI0 when pressed, so
+	   this allows us to push the button, and then look at memory to see
+	   what's in the registers (there's no other way to easily do so).
+	   We have to use `setup_irq' instead of `request_irq' because it's
+	   still too early to do memory allocation.  */
+	setup_irq (IRQ_NMI (0), &reg_snap_action);
+}
+
+void mach_get_physical_ram (unsigned long *ram_start, unsigned long *ram_len)
+{
+	*ram_start = ERAM_ADDR;
+	*ram_len = ERAM_SIZE;
+}
+
+void __init mach_sched_init (struct irqaction *timer_action)
+{
+	/* Setup up the timer interrupt.  The FPGA peripheral control
+	   registers _only_ work with single-bit writes (set1/clr1)!  */
+	__clear_bit (RPU_GTMC_CE_BIT, &RPU_GTMC);
+	__clear_bit (RPU_GTMC_CLK_BIT, &RPU_GTMC);
+	__set_bit (RPU_GTMC_CE_BIT, &RPU_GTMC);
+
+	/* We use the first RPU interrupt, which occurs every 8.192ms.  */
+	setup_irq (IRQ_RPU (0), timer_action);
+}
+
+
+void mach_gettimeofday (struct timespec *tv)
+{
+	tv->tv_sec = 0;
+	tv->tv_nsec = 0;
+}
+
+void machine_halt (void) __attribute__ ((noreturn));
+void machine_halt (void)
+{
+	for (;;) {
+		DWC(0) = 0x7777;
+		DWC(1) = 0x7777;
+		ASC = 0xffff;
+		FLGREG(0) = 1;	/* Halt immediately.  */
+		asm ("di; halt; nop; nop; nop; nop; nop");
+	}
+}
+
+void machine_restart (char *__unused)
+{
+	machine_halt ();
+}
+
+void machine_power_off (void)
+{
+	machine_halt ();
+}
+
+
+/* Interrupts */
+
+struct nb85e_intc_irq_init irq_inits[] = {
+	{ "IRQ", 0, 		NUM_MACH_IRQS,	1, 7 },
+	{ "RPU", IRQ_RPU(0),	IRQ_RPU_NUM,	1, 6 },
+	{ 0 }
+};
+#define NUM_IRQ_INITS ((sizeof irq_inits / sizeof irq_inits[0]) - 1)
+
+struct hw_interrupt_type hw_itypes[NUM_IRQ_INITS];
+
+/* Initialize interrupts.  */
+void __init mach_init_irqs (void)
+{
+	nb85e_intc_init_irq_types (irq_inits, hw_itypes);
+}
+
+
+/* An interrupt handler that copies the registers to a known memory location,
+   for debugging purposes.  */
+
+static void make_reg_snap (int irq, void *dummy, struct pt_regs *regs)
+{
+	(*(unsigned *)REG_DUMP_ADDR)++;
+	(*(struct pt_regs *)(REG_DUMP_ADDR + sizeof (unsigned))) = *regs;
+}
+
+static int reg_snap_dev_id;
+static struct irqaction reg_snap_action = {
+	make_reg_snap, 0, 0, "reg_snap", &reg_snap_dev_id, 0
+};
diff -Nru a/arch/v850/kernel/gbus_int.c b/arch/v850/kernel/gbus_int.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/gbus_int.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,267 @@
+/*
+ * arch/v850/kernel/gbus_int.c -- Midas labs GBUS interrupt support
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/sched.h>	/* For some unfathomable reason,
+				   request_irq/free_irq are declared here.  */
+
+#include <asm/machdep.h>
+#include <asm/irq.h>
+
+
+/* The number of shared GINT interrupts. */
+#define NUM_GINTS   	4
+
+/* For each GINT interrupt, how many GBUS interrupts are using it.  */
+static unsigned gint_num_active_irqs[NUM_GINTS] = { 0 };
+
+/* A table of GINTn interrupts we actually use.  */
+struct used_gint {
+	unsigned gint;
+	unsigned priority;
+} used_gint[] = {
+	{ 1, GBUS_INT_PRIORITY_HIGH },
+	{ 3, GBUS_INT_PRIORITY_LOW }
+};
+#define NUM_USED_GINTS	(sizeof used_gint / sizeof used_gint[0])
+
+/* A table of which GINT is used by each GBUS interrupts (they are
+   assigned based on priority).  */
+static unsigned char gbus_int_gint[IRQ_GBUS_INT_NUM];
+
+
+/* Interrupt enabling/disabling.  */
+
+/* Enable interrupt handling for interrupt IRQ.  */
+void gbus_int_enable_irq (unsigned irq)
+{
+	unsigned gint = gbus_int_gint[irq - GBUS_INT_BASE_IRQ];
+	GBUS_INT_ENABLE (GBUS_INT_IRQ_WORD(irq), gint)
+		|= GBUS_INT_IRQ_MASK (irq);
+}
+
+/* Disable interrupt handling for interrupt IRQ.  Note that any
+   interrupts received while disabled will be delivered once the
+   interrupt is enabled again, unless they are explicitly cleared using
+   `gbus_int_clear_pending_irq'.  */
+void gbus_int_disable_irq (unsigned irq)
+{
+	unsigned gint = gbus_int_gint[irq - GBUS_INT_BASE_IRQ];
+	GBUS_INT_ENABLE (GBUS_INT_IRQ_WORD(irq), gint)
+		&= ~GBUS_INT_IRQ_MASK (irq);
+}
+
+/* Return true if interrupt handling for interrupt IRQ is enabled.  */
+int gbus_int_irq_enabled (unsigned irq)
+{
+	unsigned gint = gbus_int_gint[irq - GBUS_INT_BASE_IRQ];
+	return (GBUS_INT_ENABLE (GBUS_INT_IRQ_WORD(irq), gint)
+		& GBUS_INT_IRQ_MASK(irq));
+}
+
+/* Disable all GBUS irqs.  */
+int gbus_int_disable_irqs ()
+{
+	unsigned w, n;
+	for (w = 0; w < GBUS_INT_NUM_WORDS; w++)
+		for (n = 0; n < IRQ_GINT_NUM; n++)
+			GBUS_INT_ENABLE (w, n) = 0;
+}
+
+/* Clear any pending interrupts for IRQ.  */
+void gbus_int_clear_pending_irq (unsigned irq)
+{
+	GBUS_INT_CLEAR (GBUS_INT_IRQ_WORD(irq)) = GBUS_INT_IRQ_MASK (irq);
+}
+
+/* Return true if interrupt IRQ is pending (but disabled).  */
+int gbus_int_irq_pending (unsigned irq)
+{
+	return (GBUS_INT_STATUS (GBUS_INT_IRQ_WORD(irq))
+		& GBUS_INT_IRQ_MASK(irq));
+}
+
+
+/* Delegating interrupts.  */
+
+/* Handle a shared GINT interrupt by passing to the appropriate GBUS
+   interrupt handler.  */
+static void gbus_int_handle_irq (int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned w;
+	unsigned gint = irq - IRQ_GINT (0);
+
+	for (w = 0; w < GBUS_INT_NUM_WORDS; w++) {
+		unsigned status = GBUS_INT_STATUS (w);
+		unsigned enable = GBUS_INT_ENABLE (w, gint);
+
+		/* Only pay attention to enabled interrupts.  */
+		status &= enable;
+		if (status) {
+			unsigned base_irq
+				= IRQ_GBUS_INT (w * GBUS_INT_BITS_PER_WORD);
+			irq = base_irq;
+			do {
+				/* There's an active interrupt in word
+				   W, find out which one, and call its
+				   handler.  */
+
+				while (! (status & 0x1)) {
+					irq++;
+					status >>= 1;
+				}
+				status &= ~0x1;
+
+				/* Recursively call handle_irq to handle it. */
+				handle_irq (irq, regs);
+			} while (status);
+		}
+	}
+
+	/* Toggle the `all enable' bit back and forth, which should cause
+	   another edge transition if there are any other interrupts
+	   still pending, and so result in another CPU interrupt.  */
+	GBUS_INT_ENABLE (0, gint) &= ~0x1;
+	GBUS_INT_ENABLE (0, gint) |=  0x1;
+}
+
+
+/* Initialize GBUS interrupt sources.  */
+
+static void irq_nop (unsigned irq) { }
+
+static unsigned gbus_int_startup_irq (unsigned irq)
+{
+	unsigned gint = gbus_int_gint[irq - GBUS_INT_BASE_IRQ];
+
+	if (gint_num_active_irqs[gint] == 0) {
+		/* First enable the CPU interrupt.  */
+		int rval =
+			request_irq (IRQ_GINT(gint), gbus_int_handle_irq,
+				     SA_INTERRUPT,
+				     "gbus_int_handler",
+				     &gint_num_active_irqs[gint]);
+		if (rval != 0)
+			return rval;
+	}
+
+	gint_num_active_irqs[gint]++;
+
+	gbus_int_clear_pending_irq (irq);
+	gbus_int_enable_irq (irq);
+
+	return 0;
+}
+
+static void gbus_int_shutdown_irq (unsigned irq)
+{
+	unsigned gint = gbus_int_gint[irq - GBUS_INT_BASE_IRQ];
+
+	gbus_int_disable_irq (irq);
+
+	if (--gint_num_active_irqs[gint] == 0)
+		/* Disable the CPU interrupt.  */
+		free_irq (IRQ_GINT(gint), &gint_num_active_irqs[gint]);
+}
+
+/* Initialize HW_IRQ_TYPES for INTC-controlled irqs described in array
+   INITS (which is terminated by an entry with the name field == 0).  */
+void __init gbus_int_init_irq_types (struct gbus_int_irq_init *inits,
+				     struct hw_interrupt_type *hw_irq_types)
+{
+	struct gbus_int_irq_init *init;
+	for (init = inits; init->name; init++) {
+		int i;
+		struct hw_interrupt_type *hwit = hw_irq_types++;
+
+		hwit->typename = init->name;
+
+		hwit->startup  = gbus_int_startup_irq;
+		hwit->shutdown = gbus_int_shutdown_irq;
+		hwit->enable   = gbus_int_enable_irq;
+		hwit->disable  = gbus_int_disable_irq;
+		hwit->ack      = irq_nop;
+		hwit->end      = irq_nop;
+		
+		/* Initialize kernel IRQ infrastructure for this interrupt.  */
+		init_irq_handlers(init->base, init->num, init->interval, hwit);
+
+		/* Set the interrupt priorities.  */
+		for (i = 0; i < init->num; i++) {
+			int j;
+			for (j = 0; j < NUM_USED_GINTS; j++)
+				if (used_gint[j].priority > init->priority)
+					break;
+			/* Wherever we stopped looking is one past the
+			   GINT we want. */
+			gbus_int_gint[init->base + i * init->interval
+				      - GBUS_INT_BASE_IRQ]
+				= used_gint[j > 0 ? j - 1 : 0].gint;
+		}
+	}
+}
+
+
+/* Initialize IRQS.  */
+
+/* Chip interrupts (GINTn) shared among GBUS interrupts.  */
+static struct hw_interrupt_type gint_hw_itypes[NUM_USED_GINTS];
+
+
+/* GBUS interrupts themselves.  */
+
+__init struct gbus_int_irq_init gbus_irq_inits[] = {
+	/* First set defaults.  */
+	{ "GBUS_INT", IRQ_GBUS_INT(0), IRQ_GBUS_INT_NUM, 1, 6},
+	{ 0 }
+};
+#define NUM_GBUS_IRQ_INITS  \
+   ((sizeof gbus_irq_inits / sizeof gbus_irq_inits[0]) - 1)
+
+static struct hw_interrupt_type gbus_hw_itypes[NUM_GBUS_IRQ_INITS];
+
+
+/* Initialize GBUS interrupts.  */
+void __init gbus_int_init_irqs (void)
+{
+	int i;
+
+	/* First initialize the shared gint interrupts.  */
+	for (i = 0; i < NUM_USED_GINTS; i++) {
+		unsigned gint = used_gint[i].gint;
+		struct nb85e_intc_irq_init gint_irq_init[2];
+
+		/* We initialize one GINT interrupt at a time.  */
+		gint_irq_init[0].name = "GINT";
+		gint_irq_init[0].base = IRQ_GINT (gint);
+		gint_irq_init[0].num = 1;
+		gint_irq_init[0].interval = 1;
+		gint_irq_init[0].priority = used_gint[i].priority;
+
+		gint_irq_init[1].name = 0; /* Terminate the vector.  */
+
+		nb85e_intc_init_irq_types (gint_irq_init, gint_hw_itypes);
+	}
+
+	/* Then the GBUS interrupts.  */
+	gbus_int_disable_irqs ();
+	gbus_int_init_irq_types (gbus_irq_inits, gbus_hw_itypes);
+	/* Turn on the `all enable' bits, which are ANDed with
+	   individual interrupt enable bits; we only want to bother with
+	   the latter.  They are the first bit in the first word of each
+	   interrupt-enable area.  */
+	for (i = 0; i < NUM_USED_GINTS; i++)
+		GBUS_INT_ENABLE (0, used_gint[i].gint) = 0x1;
+}
diff -Nru a/arch/v850/kernel/head.S b/arch/v850/kernel/head.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/head.S	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,121 @@
+/*
+ * arch/v850/kernel/head.S -- Lowest-level startup code
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <asm/clinkage.h>
+#include <asm/current.h>
+#include <asm/entry.h>
+#include <asm/thread_info.h>
+#include <asm/irq.h>
+
+
+/* Make a slightly more convenient alias for C_SYMBOL_NAME.  */
+#define CSYM	C_SYMBOL_NAME
+
+
+	.text
+
+	// Define `mach_early_init' as a weak symbol
+	.global	CSYM(mach_early_init)
+	.weak	CSYM(mach_early_init)
+
+C_ENTRY(start):
+	// Make sure interrupts are turned off, just in case
+	di
+
+#ifdef CONFIG_RESET_GUARD
+	// See if we got here via an unexpected reset
+	ld.w	RESET_GUARD, r19	// Check current value of reset guard
+	mov	RESET_GUARD_ACTIVE, r20
+	cmp	r19, r20
+	bne	1f			// Guard was not active
+
+	// If we get here, the reset guard was active.	Load up some
+	// interesting values as arguments, and jump to the handler.
+	st.w	r0, RESET_GUARD		// Allow further resets to succeed
+	mov	lp, r6			// Arg 0: return address
+	ld.b	KM, r7			// Arg 1: kernel mode
+	mov	sp, r9			// Arg 3: stack pointer
+	ld.w	KSP, r19		// maybe switch to kernel stack
+	cmp	r7, r0			// see if already in kernel mode
+	cmov	z, r19, sp, sp		//  and switch to kernel stack if not
+	GET_CURRENT_TASK(r8)		// Arg 2: task pointer
+	jr	CSYM(unexpected_reset)
+
+1:	st.w	r20, RESET_GUARD	// Turn on reset guard
+#endif /* CONFIG_RESET_GUARD */
+  
+	// Setup a temporary stack for doing pre-initialization function calls.
+	// 
+	// We can't use the initial kernel stack, because (1) it may be
+	// located in memory we're not allowed to touch, and (2) since
+	// it's in the data segment, calling memcpy to initialize that
+	// area from ROM will overwrite memcpy's return address.
+	mov	hilo(CSYM(_init_stack_end) - 4), sp
+
+	// See if there's a platform-specific early-initialization routine
+	// defined; it's a weak symbol, so it will have an address of zero if
+	// there's not.
+	mov	hilo(CSYM(mach_early_init)), r6
+	cmp	r6, r0
+	bz	3f
+
+	// There is one, so call it.  If this function is written in C, it
+	// should be very careful -- the stack pointer is valid, but very
+	// little else is (e.g., bss is not zeroed yet, and initialized data
+	// hasn't been).
+	jarl	2f, lp			// first figure out return address
+2:	add	3f - ., lp
+	jmp	[r6]			// do call
+3:
+
+#ifdef CONFIG_ROM_KERNEL
+	// Copy the data area from ROM to RAM
+	mov	hilo(CSYM(_rom_copy_dst_start)), r6
+	mov	hilo(CSYM(_rom_copy_src_start)), r7
+	mov	hilo(CSYM(_rom_copy_dst_end)), r8
+	sub	r6, r8
+	jarl	CSYM(memcpy), lp
+#endif
+
+	// Load the initial thread's stack, and current task pointer (in r16)
+	mov	hilo(CSYM(init_thread_union)), r19
+	movea	THREAD_SIZE, r19, sp
+	ld.w	TI_TASK[r19], CURRENT_TASK
+
+#ifdef CONFIG_TIME_BOOTUP
+	/* This stuff must come after mach_early_init, because interrupts may
+	   not work until after its been called.  */
+	jarl	CSYM(highres_timer_reset), lp
+	jarl	CSYM(highres_timer_start), lp
+#endif
+
+	// Kernel stack pointer save location
+	st.w	sp, KSP
+
+	// Assert that we're in `kernel mode'
+	mov	1, r19
+	st.w	r19, KM
+
+#ifdef CONFIG_ZERO_BSS
+	// Zero bss area, since we can't rely upon any loader to do so
+	mov	hilo(CSYM(_sbss)), r6
+	mov	r0, r7
+	mov	hilo(CSYM(_ebss)), r8
+	sub	r6, r8
+	jarl	CSYM(memset), lp
+#endif
+
+	// Start Linux kernel.
+	mov	hilo(CSYM(machine_halt)), lp
+	jr	CSYM(start_kernel)
+END(start)
diff -Nru a/arch/v850/kernel/highres_timer.c b/arch/v850/kernel/highres_timer.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/highres_timer.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,132 @@
+/*
+ * arch/v850/kernel/highres_timer.c -- High resolution timing routines
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <asm/system.h>
+#include <asm/nb85e_timer_d.h>
+#include <asm/highres_timer.h>
+
+#define HIGHRES_TIMER_USEC_SHIFT   12
+
+/* Pre-calculated constant used for converting ticks to real time
+   units.  We initialize it to prevent it being put into BSS.  */
+static u32 highres_timer_usec_prescale = 1;
+
+void highres_timer_slow_tick_irq (void) __attribute__ ((noreturn));
+void highres_timer_slow_tick_irq (void)
+{
+	/* This is an interrupt handler, so it must be very careful to
+	   not to trash any registers.  At this point, the stack-pointer
+	   (r3) has been saved in the chip ram location ENTRY_SP by the
+	   interrupt vector, so we can use it as a scratch register; we
+	   must also restore it before returning.  */
+	asm ("ld.w	%0[r0], sp;"
+	     "add	1, sp;"
+	     "st.w	sp, %0[r0];"
+	     "ld.w	%1[r0], sp;" /* restore pre-irq stack-pointer */
+	     "reti"
+	     ::
+	      "i" (HIGHRES_TIMER_SLOW_TICKS_ADDR),
+	      "i" (ENTRY_SP_ADDR)
+	     : "memory");
+}
+
+void highres_timer_reset (void)
+{
+	NB85E_TIMER_D_TMD (HIGHRES_TIMER_TIMER_D_UNIT) = 0;
+	HIGHRES_TIMER_SLOW_TICKS = 0;
+}
+
+void highres_timer_start (void)
+{
+	u32 fast_tick_rate;
+
+	/* Start hardware timer.  */
+	nb85e_timer_d_configure (HIGHRES_TIMER_TIMER_D_UNIT,
+				 HIGHRES_TIMER_SLOW_TICK_RATE);
+
+	fast_tick_rate =
+		(NB85E_TIMER_D_BASE_FREQ
+		 >> NB85E_TIMER_D_DIVLOG2 (HIGHRES_TIMER_TIMER_D_UNIT));
+
+	/* The obvious way of calculating microseconds from fast ticks
+	   is to do:
+
+	     usec = fast_ticks * 10^6 / fast_tick_rate
+
+	   However, divisions are much slower than multiplications, and
+	   the above calculation can overflow, so we do this instead:
+
+	     usec = fast_ticks * (10^6 * 2^12 / fast_tick_rate) / 2^12
+
+           since we can pre-calculate (10^6 * (2^12 / fast_tick_rate))
+	   and use a shift for dividing by 2^12, this avoids division,
+	   and is almost as accurate (it differs by about 2 microseconds
+	   at the extreme value of the fast-tick counter's ranger).  */
+	highres_timer_usec_prescale = ((1000000 << HIGHRES_TIMER_USEC_SHIFT)
+				       / fast_tick_rate);
+
+	/* Enable the interrupt (which is hardwired to this use), and
+	   give it the highest priority.  */
+	NB85E_INTC_IC (IRQ_INTCMD (HIGHRES_TIMER_TIMER_D_UNIT)) = 0;
+}
+
+void highres_timer_stop (void)
+{
+	/* Stop the timer.  */
+	NB85E_TIMER_D_TMCD (HIGHRES_TIMER_TIMER_D_UNIT) =
+		NB85E_TIMER_D_TMCD_CAE;
+	/* Disable its interrupt, just in case.  */
+	nb85e_intc_disable_irq (IRQ_INTCMD (HIGHRES_TIMER_TIMER_D_UNIT));
+}
+
+inline void highres_timer_read_ticks (u32 *slow_ticks, u32 *fast_ticks)
+{
+	int flags;
+	u32 fast_ticks_1, fast_ticks_2, _slow_ticks;
+
+	local_irq_save (flags);
+	fast_ticks_1 = NB85E_TIMER_D_TMD (HIGHRES_TIMER_TIMER_D_UNIT);
+	_slow_ticks = HIGHRES_TIMER_SLOW_TICKS;
+	fast_ticks_2 = NB85E_TIMER_D_TMD (HIGHRES_TIMER_TIMER_D_UNIT);
+	local_irq_restore (flags);
+
+	if (fast_ticks_2 < fast_ticks_1)
+		_slow_ticks++;
+
+	*slow_ticks = _slow_ticks;
+	*fast_ticks = fast_ticks_2;
+}
+
+inline void highres_timer_ticks_to_timeval (u32 slow_ticks, u32 fast_ticks,
+					    struct timeval *tv)
+{
+	unsigned long sec, sec_rem, usec;
+
+	usec = ((fast_ticks * highres_timer_usec_prescale)
+		>> HIGHRES_TIMER_USEC_SHIFT);
+
+	sec = slow_ticks / HIGHRES_TIMER_SLOW_TICK_RATE;
+	sec_rem = slow_ticks % HIGHRES_TIMER_SLOW_TICK_RATE;
+
+	usec += sec_rem * (1000000 / HIGHRES_TIMER_SLOW_TICK_RATE);
+
+	tv->tv_sec = sec;
+	tv->tv_usec = usec;
+}
+
+void highres_timer_read (struct timeval *tv)
+{
+	u32 fast_ticks, slow_ticks;
+	highres_timer_read_ticks (&slow_ticks, &fast_ticks);
+	highres_timer_ticks_to_timeval (slow_ticks, fast_ticks, tv);
+}
diff -Nru a/arch/v850/kernel/init_task.c b/arch/v850/kernel/init_task.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/init_task.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,42 @@
+/*
+ * arch/v850/kernel/init_task.c -- Initial task/thread structures
+ *
+ *  Copyright (C) 2002  NEC Corporation
+ *  Copyright (C) 2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ */
+
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/init_task.h>
+#include <linux/fs.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+
+static struct fs_struct init_fs = INIT_FS;
+static struct files_struct init_files = INIT_FILES;
+static struct signal_struct init_signals = INIT_SIGNALS (init_signals);
+struct mm_struct init_mm = INIT_MM (init_mm);
+
+/*
+ * Initial task structure.
+ *
+ * All other task structs will be allocated on slabs in fork.c
+ */
+struct task_struct init_task = INIT_TASK (init_task);
+
+/*
+ * Initial thread structure.
+ *
+ * We need to make sure that this is 8192-byte aligned due to the
+ * way process stacks are handled. This is done by having a special
+ * "init_task" linker map entry.
+ */
+union thread_union init_thread_union 
+	__attribute__((__section__(".data.init_task"))) =
+		{ INIT_THREAD_INFO(init_task) };
diff -Nru a/arch/v850/kernel/intv.S b/arch/v850/kernel/intv.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/intv.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,90 @@
+/*
+ * arch/v850/kernel/intv.S -- Interrupt vectors
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <asm/clinkage.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+#include <asm/entry.h>
+
+#ifdef CONFIG_V850E_MA1_HIGHRES_TIMER
+#include <asm/highres_timer.h>
+#endif
+
+/* Jump to an interrupt/trap handler.  These handlers (defined in entry.S)
+   expect the stack-pointer to be saved in ENTRY_SP, so we use sp to do an
+   indirect jump (which avoids problems when the handler is more than a signed
+   22-bit offset away).  */
+#define JUMP_TO_HANDLER(name, sp_save_loc)				      \
+	st.w	sp, sp_save_loc;					      \
+	mov	hilo(name), sp;						      \
+	jmp	[sp]
+
+
+	/* Reset vector.  */
+	.section	.intv.reset, "ax"
+	.org	0x0
+	mov	hilo(C_SYMBOL_NAME(start)), r1;
+	jmp	[r1]
+
+
+	/* Generic interrupt vectors.  */
+	.section	.intv.common, "ax"
+	.balign	0x10
+	JUMP_TO_HANDLER (nmi, NMI_ENTRY_SP)	// NMI0
+	.balign	0x10
+	JUMP_TO_HANDLER (nmi, NMI_ENTRY_SP)	// NMI1
+	.balign	0x10
+	JUMP_TO_HANDLER (nmi, NMI_ENTRY_SP)	// NMI2
+	
+	.balign	0x10
+	JUMP_TO_HANDLER (trap, ENTRY_SP)	// TRAP0n
+	.balign	0x10
+	JUMP_TO_HANDLER (trap, ENTRY_SP)	// TRAP1n
+
+	.balign	0x10
+	JUMP_TO_HANDLER (illegal_instruction, ENTRY_SP) // illegal insn trap
+
+	.balign	0x10
+	JUMP_TO_HANDLER (dbtrap, ENTRY_SP)	// DBTRAP insn
+
+
+	/* Hardware interrupt vectors.  */
+	.section	.intv.mach, "ax"
+	.org	0x0
+
+#if defined (CONFIG_V850E_MA1_HIGHRES_TIMER) && defined (IRQ_INTCMD)
+
+	/* Interrupts before the highres timer interrupt.  */
+	.rept	IRQ_INTCMD (HIGHRES_TIMER_TIMER_D_UNIT)
+	.balign	0x10
+	JUMP_TO_HANDLER (irq, ENTRY_SP)
+	.endr
+
+	/* The highres timer interrupt.  */
+	.balign	0x10
+	JUMP_TO_HANDLER (C_SYMBOL_NAME (highres_timer_slow_tick_irq), ENTRY_SP)
+
+	/* Interrupts after the highres timer interrupt.  */
+	.rept	NUM_CPU_IRQS - IRQ_INTCMD (HIGHRES_TIMER_TIMER_D_UNIT) - 1
+	.balign	0x10
+	JUMP_TO_HANDLER (irq, ENTRY_SP)
+	.endr
+
+#else /* No highres timer */
+
+	.rept	NUM_CPU_IRQS
+	.balign	0x10
+	JUMP_TO_HANDLER (irq, ENTRY_SP)
+	.endr
+
+#endif /* Highres timer */
diff -Nru a/arch/v850/kernel/irq.c b/arch/v850/kernel/irq.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/irq.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,716 @@
+/*
+ * arch/v850/kernel/irq.c -- High-level interrupt handling
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 1994-2000  Ralf Baechle
+ *  Copyright (C) 1992  Linus Torvalds
+ *
+ * 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.
+ *
+ * This file was was derived from the mips version, arch/mips/kernel/irq.c
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/random.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+
+#include <asm/system.h>
+
+/*
+ * Controller mappings for all interrupt sources:
+ */
+irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
+	{ [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
+
+/*
+ * Special irq handlers.
+ */
+
+void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
+
+/*
+ * Generic no controller code
+ */
+
+static void enable_none(unsigned int irq) { }
+static unsigned int startup_none(unsigned int irq) { return 0; }
+static void disable_none(unsigned int irq) { }
+static void ack_none(unsigned int irq)
+{
+	/*
+	 * '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
+	 * a generic callback i think.
+	 */
+	printk("received IRQ %d with unknown interrupt type\n", irq);
+}
+
+/* startup is the same as "enable", shutdown is same as "disable" */
+#define shutdown_none	disable_none
+#define end_none	enable_none
+
+struct hw_interrupt_type no_irq_type = {
+	"none",
+	startup_none,
+	shutdown_none,
+	enable_none,
+	disable_none,
+	ack_none,
+	end_none
+};
+
+volatile unsigned long irq_err_count, spurious_count;
+
+/*
+ * Generic, controller-independent functions:
+ */
+
+int show_interrupts(struct seq_file *p, void *v)
+{
+	int i;
+	struct irqaction * action;
+
+	seq_puts(p, "           ");
+	for (i=0; i < 1 /*smp_num_cpus*/; i++)
+		seq_printf(p, "CPU%d       ", i);
+	seq_putc(p, '\n');
+
+	for (i = 0 ; i < NR_IRQS ; i++) {
+		int j, count, num;
+		const char *type_name = irq_desc[i].handler->typename;
+
+		action = irq_desc[i].action;
+		if (!action) 
+			continue;
+
+		count = 0;
+		num = -1;
+		for (j = 0; j < NR_IRQS; j++)
+			if (irq_desc[j].handler->typename == type_name) {
+				if (i == j)
+					num = count;
+				count++;
+			}
+
+		seq_printf(p, "%3d: ",i);
+		seq_printf(p, "%10u ", kstat_irqs(i));
+		if (count > 1) {
+			int prec = (num >= 100 ? 3 : num >= 10 ? 2 : 1);
+			seq_printf(p, " %*s%d", 14 - prec, type_name, num);
+		} else
+			seq_printf(p, " %14s", type_name);
+		seq_printf(p, "  %s", action->name);
+
+		for (action=action->next; action; action = action->next)
+			seq_printf(p, ", %s", action->name);
+		seq_putc(p, '\n');
+	}
+	seq_printf(p, "ERR: %10lu\n", irq_err_count);
+	return 0;
+}
+
+/*
+ * This should really return information about whether
+ * we should do bottom half handling etc. Right now we
+ * end up _always_ checking the bottom half, which is a
+ * waste of time and is not what some drivers would
+ * prefer.
+ */
+int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action)
+{
+	int status = 1; /* Force the "do bottom halves" bit */
+
+	if (!(action->flags & SA_INTERRUPT))
+		local_irq_enable();
+
+	do {
+		status |= action->flags;
+		action->handler(irq, action->dev_id, regs);
+		action = action->next;
+	} while (action);
+	if (status & SA_SAMPLE_RANDOM)
+		add_interrupt_randomness(irq);
+	local_irq_disable();
+
+	return status;
+}
+
+/*
+ * Generic enable/disable code: this just calls
+ * down into the PIC-specific version for the actual
+ * hardware disable after having gotten the irq
+ * controller lock. 
+ */
+ 
+/**
+ *	disable_irq_nosync - disable an irq without waiting
+ *	@irq: Interrupt to disable
+ *
+ *	Disable the selected interrupt line. Disables of an interrupt
+ *	stack. Unlike disable_irq(), this function does not ensure existing
+ *	instances of the IRQ handler have completed before returning.
+ *
+ *	This function may be called from IRQ context.
+ */
+ 
+void inline disable_irq_nosync(unsigned int irq)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	if (!desc->depth++) {
+		desc->status |= IRQ_DISABLED;
+		desc->handler->disable(irq);
+	}
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+/**
+ *	disable_irq - disable an irq and wait for completion
+ *	@irq: Interrupt to disable
+ *
+ *	Disable the selected interrupt line. Disables of an interrupt
+ *	stack. That is for two disables you need two enables. This
+ *	function waits for any pending IRQ handlers for this interrupt
+ *	to complete before returning. If you use this function while
+ *	holding a resource the IRQ handler may need you will deadlock.
+ *
+ *	This function may be called - with care - from IRQ context.
+ */
+ 
+void disable_irq(unsigned int irq)
+{
+	disable_irq_nosync(irq);
+	synchronize_irq(irq);
+}
+
+/**
+ *	enable_irq - enable interrupt handling on an irq
+ *	@irq: Interrupt to enable
+ *
+ *	Re-enables the processing of interrupts on this IRQ line
+ *	providing no disable_irq calls are now in effect.
+ *
+ *	This function may be called from IRQ context.
+ */
+ 
+void enable_irq(unsigned int irq)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	switch (desc->depth) {
+	case 1: {
+		unsigned int status = desc->status & ~IRQ_DISABLED;
+		desc->status = status;
+		if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
+			desc->status = status | IRQ_REPLAY;
+			hw_resend_irq(desc->handler,irq);
+		}
+		desc->handler->enable(irq);
+		/* fall-through */
+	}
+	default:
+		desc->depth--;
+		break;
+	case 0:
+		printk("enable_irq(%u) unbalanced from %p\n", irq,
+		       __builtin_return_address(0));
+	}
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+/* Handle interrupt IRQ.  REGS are the registers at the time of ther
+   interrupt.  */
+unsigned int handle_irq (int irq, struct pt_regs *regs)
+{
+	/* 
+	 * We ack quickly, we don't want the irq controller
+	 * thinking we're snobs just because some other CPU has
+	 * disabled global interrupts (we have already done the
+	 * INT_ACK cycles, it's too late to try to pretend to the
+	 * controller that we aren't taking the interrupt).
+	 *
+	 * 0 return value means that this irq is already being
+	 * handled by some other CPU. (or is disabled)
+	 */
+	int cpu = smp_processor_id();
+	irq_desc_t *desc = irq_desc + irq;
+	struct irqaction * action;
+	unsigned int status;
+
+	irq_enter();
+	kstat.irqs[cpu][irq]++;
+	spin_lock(&desc->lock);
+	desc->handler->ack(irq);
+	/*
+	   REPLAY is when Linux resends an IRQ that was dropped earlier
+	   WAITING is used by probe to mark irqs that are being tested
+	   */
+	status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
+	status |= IRQ_PENDING; /* we _want_ to handle it */
+
+	/*
+	 * If the IRQ is disabled for whatever reason, we cannot
+	 * use the action we have.
+	 */
+	action = NULL;
+	if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) {
+		action = desc->action;
+		status &= ~IRQ_PENDING; /* we commit to handling */
+		status |= IRQ_INPROGRESS; /* we are handling it */
+	}
+	desc->status = status;
+
+	/*
+	 * If there is no IRQ handler or it was disabled, exit early.
+	   Since we set PENDING, if another processor is handling
+	   a different instance of this same irq, the other processor
+	   will take care of it.
+	 */
+	if (unlikely(!action))
+		goto out;
+
+	/*
+	 * Edge triggered interrupts need to remember
+	 * pending events.
+	 * This applies to any hw interrupts that allow a second
+	 * instance of the same irq to arrive while we are in handle_irq
+	 * or in the handler. But the code here only handles the _second_
+	 * instance of the irq, not the third or fourth. So it is mostly
+	 * useful for irq hardware that does not mask cleanly in an
+	 * SMP environment.
+	 */
+	for (;;) {
+		spin_unlock(&desc->lock);
+		handle_IRQ_event(irq, regs, action);
+		spin_lock(&desc->lock);
+		
+		if (likely(!(desc->status & IRQ_PENDING)))
+			break;
+		desc->status &= ~IRQ_PENDING;
+	}
+	desc->status &= ~IRQ_INPROGRESS;
+
+out:
+	/*
+	 * The ->end() handler has to deal with interrupts which got
+	 * disabled while the handler was running.
+	 */
+	desc->handler->end(irq);
+	spin_unlock(&desc->lock);
+
+	irq_exit();
+
+	return 1;
+}
+
+/**
+ *	request_irq - allocate an interrupt line
+ *	@irq: Interrupt line to allocate
+ *	@handler: Function to be called when the IRQ occurs
+ *	@irqflags: Interrupt type flags
+ *	@devname: An ascii name for the claiming device
+ *	@dev_id: A cookie passed back to the handler function
+ *
+ *	This call allocates interrupt resources and enables the
+ *	interrupt line and IRQ handling. From the point this
+ *	call is made your handler function may be invoked. Since
+ *	your handler function must clear any interrupt the board 
+ *	raises, you must take care both to initialise your hardware
+ *	and to set up the interrupt handler in the right order.
+ *
+ *	Dev_id must be globally unique. Normally the address of the
+ *	device data structure is used as the cookie. Since the handler
+ *	receives this value it makes sense to use it.
+ *
+ *	If your interrupt is shared you must pass a non NULL dev_id
+ *	as this is required when freeing the interrupt.
+ *
+ *	Flags:
+ *
+ *	SA_SHIRQ		Interrupt is shared
+ *
+ *	SA_INTERRUPT		Disable local interrupts while processing
+ *
+ *	SA_SAMPLE_RANDOM	The interrupt can be used for entropy
+ *
+ */
+ 
+int request_irq(unsigned int irq, 
+		void (*handler)(int, void *, struct pt_regs *),
+		unsigned long irqflags, 
+		const char * devname,
+		void *dev_id)
+{
+	int retval;
+	struct irqaction * action;
+
+#if 1
+	/*
+	 * Sanity-check: shared interrupts should REALLY pass in
+	 * a real dev-ID, otherwise we'll have trouble later trying
+	 * to figure out which interrupt is which (messes up the
+	 * interrupt freeing logic etc).
+	 */
+	if (irqflags & SA_SHIRQ) {
+		if (!dev_id)
+			printk("Bad boy: %s (at 0x%x) called us without a dev_id!\n", devname, (&irq)[-1]);
+	}
+#endif
+
+	if (irq >= NR_IRQS)
+		return -EINVAL;
+	if (!handler)
+		return -EINVAL;
+
+	action = (struct irqaction *)
+			kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+	if (!action)
+		return -ENOMEM;
+
+	action->handler = handler;
+	action->flags = irqflags;
+	action->mask = 0;
+	action->name = devname;
+	action->next = NULL;
+	action->dev_id = dev_id;
+
+	retval = setup_irq(irq, action);
+	if (retval)
+		kfree(action);
+	return retval;
+}
+
+/**
+ *	free_irq - free an interrupt
+ *	@irq: Interrupt line to free
+ *	@dev_id: Device identity to free
+ *
+ *	Remove an interrupt handler. The handler is removed and if the
+ *	interrupt line is no longer in use by any driver it is disabled.
+ *	On a shared IRQ the caller must ensure the interrupt is disabled
+ *	on the card it drives before calling this function. The function
+ *	does not return until any executing interrupts for this IRQ
+ *	have completed.
+ *
+ *	This function may be called from interrupt context. 
+ *
+ *	Bugs: Attempting to free an irq in a handler for the same irq hangs
+ *	      the machine.
+ */
+ 
+void free_irq(unsigned int irq, void *dev_id)
+{
+	irq_desc_t *desc;
+	struct irqaction **p;
+	unsigned long flags;
+
+	if (irq >= NR_IRQS)
+		return;
+
+	desc = irq_desc + irq;
+	spin_lock_irqsave(&desc->lock,flags);
+	p = &desc->action;
+	for (;;) {
+		struct irqaction * action = *p;
+		if (action) {
+			struct irqaction **pp = p;
+			p = &action->next;
+			if (action->dev_id != dev_id)
+				continue;
+
+			/* Found it - now remove it from the list of entries */
+			*pp = action->next;
+			if (!desc->action) {
+				desc->status |= IRQ_DISABLED;
+				desc->handler->shutdown(irq);
+			}
+			spin_unlock_irqrestore(&desc->lock,flags);
+
+			synchronize_irq(irq);
+			kfree(action);
+			return;
+		}
+		printk("Trying to free free IRQ%d\n",irq);
+		spin_unlock_irqrestore(&desc->lock,flags);
+		return;
+	}
+}
+
+/*
+ * IRQ autodetection code..
+ *
+ * This depends on the fact that any interrupt that
+ * comes in on to an unassigned handler will get stuck
+ * with "IRQ_WAITING" cleared and the interrupt
+ * disabled.
+ */
+
+static DECLARE_MUTEX(probe_sem);
+
+/**
+ *	probe_irq_on	- begin an interrupt autodetect
+ *
+ *	Commence probing for an interrupt. The interrupts are scanned
+ *	and a mask of potential interrupt lines is returned.
+ *
+ */
+ 
+unsigned long probe_irq_on(void)
+{
+	unsigned int i;
+	irq_desc_t *desc;
+	unsigned long val;
+	unsigned long delay;
+
+	down(&probe_sem);
+	/* 
+	 * something may have generated an irq long ago and we want to
+	 * flush such a longstanding irq before considering it as spurious. 
+	 */
+	for (i = NR_IRQS-1; i > 0; i--)  {
+		desc = irq_desc + i;
+
+		spin_lock_irq(&desc->lock);
+		if (!irq_desc[i].action) 
+			irq_desc[i].handler->startup(i);
+		spin_unlock_irq(&desc->lock);
+	}
+
+	/* Wait for longstanding interrupts to trigger. */
+	for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
+		/* about 20ms delay */ barrier();
+
+	/*
+	 * enable any unassigned irqs
+	 * (we must startup again here because if a longstanding irq
+	 * happened in the previous stage, it may have masked itself)
+	 */
+	for (i = NR_IRQS-1; i > 0; i--) {
+		desc = irq_desc + i;
+
+		spin_lock_irq(&desc->lock);
+		if (!desc->action) {
+			desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
+			if (desc->handler->startup(i))
+				desc->status |= IRQ_PENDING;
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+
+	/*
+	 * Wait for spurious interrupts to trigger
+	 */
+	for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
+		/* about 100ms delay */ barrier();
+
+	/*
+	 * Now filter out any obviously spurious interrupts
+	 */
+	val = 0;
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc_t *desc = irq_desc + i;
+		unsigned int status;
+
+		spin_lock_irq(&desc->lock);
+		status = desc->status;
+
+		if (status & IRQ_AUTODETECT) {
+			/* It triggered already - consider it spurious. */
+			if (!(status & IRQ_WAITING)) {
+				desc->status = status & ~IRQ_AUTODETECT;
+				desc->handler->shutdown(i);
+			} else
+				if (i < 32)
+					val |= 1 << i;
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+
+	return val;
+}
+
+/*
+ * Return a mask of triggered interrupts (this
+ * can handle only legacy ISA interrupts).
+ */
+ 
+/**
+ *	probe_irq_mask - scan a bitmap of interrupt lines
+ *	@val:	mask of interrupts to consider
+ *
+ *	Scan the ISA bus interrupt lines and return a bitmap of
+ *	active interrupts. The interrupt probe logic state is then
+ *	returned to its previous value.
+ *
+ *	Note: we need to scan all the irq's even though we will
+ *	only return ISA irq numbers - just so that we reset them
+ *	all to a known state.
+ */
+unsigned int probe_irq_mask(unsigned long val)
+{
+	int i;
+	unsigned int mask;
+
+	mask = 0;
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc_t *desc = irq_desc + i;
+		unsigned int status;
+
+		spin_lock_irq(&desc->lock);
+		status = desc->status;
+
+		if (status & IRQ_AUTODETECT) {
+			if (i < 16 && !(status & IRQ_WAITING))
+				mask |= 1 << i;
+
+			desc->status = status & ~IRQ_AUTODETECT;
+			desc->handler->shutdown(i);
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+	up(&probe_sem);
+
+	return mask & val;
+}
+
+/*
+ * Return the one interrupt that triggered (this can
+ * handle any interrupt source).
+ */
+
+/**
+ *	probe_irq_off	- end an interrupt autodetect
+ *	@val: mask of potential interrupts (unused)
+ *
+ *	Scans the unused interrupt lines and returns the line which
+ *	appears to have triggered the interrupt. If no interrupt was
+ *	found then zero is returned. If more than one interrupt is
+ *	found then minus the first candidate is returned to indicate
+ *	their is doubt.
+ *
+ *	The interrupt probe logic state is returned to its previous
+ *	value.
+ *
+ *	BUGS: When used in a module (which arguably shouldnt happen)
+ *	nothing prevents two IRQ probe callers from overlapping. The
+ *	results of this are non-optimal.
+ */
+ 
+int probe_irq_off(unsigned long val)
+{
+	int i, irq_found, nr_irqs;
+
+	nr_irqs = 0;
+	irq_found = 0;
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc_t *desc = irq_desc + i;
+		unsigned int status;
+
+		spin_lock_irq(&desc->lock);
+		status = desc->status;
+
+		if (status & IRQ_AUTODETECT) {
+			if (!(status & IRQ_WAITING)) {
+				if (!nr_irqs)
+					irq_found = i;
+				nr_irqs++;
+			}
+			desc->status = status & ~IRQ_AUTODETECT;
+			desc->handler->shutdown(i);
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+	up(&probe_sem);
+
+	if (nr_irqs > 1)
+		irq_found = -irq_found;
+	return irq_found;
+}
+
+/* this was setup_x86_irq but it seems pretty generic */
+int setup_irq(unsigned int irq, struct irqaction * new)
+{
+	int shared = 0;
+	unsigned long flags;
+	struct irqaction *old, **p;
+	irq_desc_t *desc = irq_desc + irq;
+
+	/*
+	 * Some drivers like serial.c use request_irq() heavily,
+	 * so we have to be careful not to interfere with a
+	 * running system.
+	 */
+	if (new->flags & SA_SAMPLE_RANDOM) {
+		/*
+		 * This function might sleep, we want to call it first,
+		 * outside of the atomic block.
+		 * Yes, this might clear the entropy pool if the wrong
+		 * driver is attempted to be loaded, without actually
+		 * installing a new handler, but is this really a problem,
+		 * only the sysadmin is able to do this.
+		 */
+		rand_initialize_irq(irq);
+	}
+
+	/*
+	 * The following block of code has to be executed atomically
+	 */
+	spin_lock_irqsave(&desc->lock,flags);
+	p = &desc->action;
+	if ((old = *p) != NULL) {
+		/* Can't share interrupts unless both agree to */
+		if (!(old->flags & new->flags & SA_SHIRQ)) {
+			spin_unlock_irqrestore(&desc->lock,flags);
+			return -EBUSY;
+		}
+
+		/* add new interrupt at end of irq queue */
+		do {
+			p = &old->next;
+			old = *p;
+		} while (old);
+		shared = 1;
+	}
+
+	*p = new;
+
+	if (!shared) {
+		desc->depth = 0;
+		desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS);
+		desc->handler->startup(irq);
+	}
+	spin_unlock_irqrestore(&desc->lock,flags);
+
+	/* register_irq_proc(irq); */
+	return 0;
+}
+
+/* Initialize irq handling for IRQs.
+   BASE_IRQ, BASE_IRQ+INTERVAL, ..., BASE_IRQ+NUM*INTERVAL
+   to IRQ_TYPE.  An IRQ_TYPE of 0 means to use a generic interrupt type.  */
+void __init
+init_irq_handlers (int base_irq, int num, int interval,
+		   struct hw_interrupt_type *irq_type)
+{
+	while (num-- > 0) {
+		irq_desc[base_irq].status  = IRQ_DISABLED;
+		irq_desc[base_irq].action  = NULL;
+		irq_desc[base_irq].depth   = 1;
+		irq_desc[base_irq].handler = irq_type;
+		base_irq += interval;
+	}
+}
diff -Nru a/arch/v850/kernel/ma.c b/arch/v850/kernel/ma.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/ma.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,70 @@
+/*
+ * arch/v850/kernel/ma.c -- V850E/MA series of cpu chips
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+
+#include <asm/atomic.h>
+#include <asm/page.h>
+#include <asm/machdep.h>
+#include <asm/nb85e_timer_d.h>
+
+#include "mach.h"
+
+void __init mach_sched_init (struct irqaction *timer_action)
+{
+	/* Start hardware timer.  */
+	nb85e_timer_d_configure (0, HZ);
+	/* Install timer interrupt handler.  */
+	setup_irq (IRQ_INTCMD(0), timer_action);
+}
+
+static struct nb85e_intc_irq_init irq_inits[] = {
+	{ "IRQ", 0, 		NUM_MACH_IRQS,	1, 7 },
+	{ "CMD", IRQ_INTCMD(0), IRQ_INTCMD_NUM,	1, 5 },
+	{ "DMA", IRQ_INTDMA(0), IRQ_INTDMA_NUM,	1, 2 },
+	{ "CSI", IRQ_INTCSI(0), IRQ_INTCSI_NUM,	4, 4 },
+	{ "SER", IRQ_INTSER(0), IRQ_INTSER_NUM,	4, 3 },
+	{ "SR",	 IRQ_INTSR(0),	IRQ_INTSR_NUM, 	4, 4 },
+	{ "ST",  IRQ_INTST(0), 	IRQ_INTST_NUM, 	4, 5 },
+	{ 0 }
+};
+#define NUM_IRQ_INITS ((sizeof irq_inits / sizeof irq_inits[0]) - 1)
+
+static struct hw_interrupt_type hw_itypes[NUM_IRQ_INITS];
+
+/* Initialize MA chip interrupts.  */
+void __init ma_init_irqs (void)
+{
+	nb85e_intc_init_irq_types (irq_inits, hw_itypes);
+}
+
+/* Called before configuring an on-chip UART.  */
+void ma_uart_pre_configure (unsigned chan, unsigned cflags, unsigned baud)
+{
+	/* We only know about the first two UART channels (though
+	   specific chips may have more).  */
+	if (chan < 2) {
+		unsigned bits = 0x3 << (chan * 3);
+		/* Specify that the relevent pins on the chip should do
+		   serial I/O, not direct I/O.  */
+		MA_PORT4_PMC |= bits;
+		/* Specify that we're using the UART, not the CSI device.  */
+		MA_PORT4_PFC |= bits;
+	}
+}
diff -Nru a/arch/v850/kernel/mach.c b/arch/v850/kernel/mach.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/mach.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,17 @@
+/*
+ * arch/v850/kernel/mach.c -- Defaults for some things defined by "mach.h"
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include "mach.h"
+
+/* Called with each timer tick, if non-zero.  */
+void (*mach_tick)(void) = 0;
diff -Nru a/arch/v850/kernel/mach.h b/arch/v850/kernel/mach.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/mach.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,56 @@
+/*
+ * arch/v850/kernel/mach.h -- Machine-dependent functions used by v850 port
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_MACH_H__
+#define __V850_MACH_H__
+
+#include <linux/kernel.h>
+#include <linux/time.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/seq_file.h>
+
+#include <asm/ptrace.h>
+#include <asm/entry.h>
+#include <asm/clinkage.h>
+
+void mach_setup (char **cmdline);
+void mach_gettimeofday (struct timespec *tv);
+void mach_sched_init (struct irqaction *timer_action);
+void mach_get_physical_ram (unsigned long *ram_start, unsigned long *ram_len);
+void mach_init_irqs (void);
+
+/* If defined, is called very early in the kernel initialization.  The
+   stack pointer is valid, but very little has been initialized (e.g.,
+   bss is not zeroed yet) when this is called, so care must taken.  */
+void mach_early_init (void);
+
+/* If defined, called after the bootmem allocator has been initialized,
+   to allow the platform-dependent code to reserve any areas of RAM that
+   the kernel shouldn't touch.  */
+void mach_reserve_bootmem (void) __attribute__ ((__weak__));
+
+/* Called with each timer tick, if non-zero.  */
+extern void (*mach_tick) (void);
+
+/* The following establishes aliases for various mach_ functions to the
+   name by which the rest of the kernal calls them.  These statements
+   should only have an effect in the file that defines the actual functions. */
+#define MACH_ALIAS(to, from)						      \
+   asm (".global " macrology_stringify (C_SYMBOL_NAME (to)) ";"		      \
+	macrology_stringify (C_SYMBOL_NAME (to))			      \
+	" = " macrology_stringify (C_SYMBOL_NAME (from)))
+/* e.g.: MACH_ALIAS (kernel_name,	arch_spec_name);  */
+
+#endif /* __V850_MACH_H__ */
diff -Nru a/arch/v850/kernel/memcons.c b/arch/v850/kernel/memcons.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/memcons.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,134 @@
+/*
+ * arch/v850/kernel/memcons.c -- Console I/O to a memory buffer
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/init.h>
+
+/* If this device is enabled, the linker map should define start and
+   end points for its buffer. */
+extern char memcons_output[], memcons_output_end;
+
+/* Current offset into the buffer.  */
+static unsigned long memcons_offs = 0;
+
+/* Spinlock protecting memcons_offs.  */
+static spinlock_t memcons_lock = SPIN_LOCK_UNLOCKED;
+
+
+static size_t write (const char *buf, size_t len)
+{
+	int flags;
+	char *point;
+
+	spin_lock_irqsave (memcons_lock, flags);
+
+	point = memcons_output + memcons_offs;
+	if (point + len >= &memcons_output_end) {
+		len = &memcons_output_end - point;
+		memcons_offs = 0;
+	} else
+		memcons_offs += len;
+
+	spin_unlock_irqrestore (memcons_lock, flags);
+
+	memcpy (point, buf, len);
+
+	return len;
+}
+
+
+/*  Low-level console. */
+
+static void memcons_write (struct console *co, const char *buf, unsigned len)
+{
+	while (len > 0)
+		len -= write (buf, len);
+}
+
+static kdev_t memcons_device (struct console *co)
+{
+        return MKDEV (TTY_MAJOR, 64 + co->index);
+}
+
+static struct console memcons =
+{
+    name:	"memcons",
+    write:	memcons_write,
+    device:	memcons_device,
+    flags:	CON_PRINTBUFFER,
+    index:	-1,
+};
+
+void memcons_setup (void)
+{
+	register_console (&memcons);
+	printk (KERN_INFO "Console: static memory buffer (memcons)\n");
+}
+
+/* Higher level TTY interface.  */
+
+static struct tty_struct *tty_table[1] = { 0 };
+static struct termios *tty_termios[1] = { 0 };
+static struct termios *tty_termios_locked[1] = { 0 };
+static struct tty_driver tty_driver = { 0 };
+static int tty_ref_count = 0;
+
+int memcons_tty_open (struct tty_struct *tty, struct file *filp)
+{
+	return 0;
+}
+
+int memcons_tty_write (struct tty_struct *tty, int from_user,
+		       const unsigned char *buf, int len)
+{
+	return write (buf, len);
+}
+
+int memcons_tty_write_room (struct tty_struct *tty)
+{
+	return &memcons_output_end - (memcons_output + memcons_offs);
+}
+
+int memcons_tty_chars_in_buffer (struct tty_struct *tty)
+{
+	/* We have no buffer.  */
+	return 0;
+}
+
+int __init memcons_tty_init (void)
+{
+	tty_driver.name = "memcons";
+	tty_driver.major = TTY_MAJOR;
+	tty_driver.minor_start = 64;
+	tty_driver.num = 1;
+	tty_driver.type = TTY_DRIVER_TYPE_SYSCONS;
+
+	tty_driver.refcount = &tty_ref_count;
+
+	tty_driver.table = tty_table;
+	tty_driver.termios = tty_termios;
+	tty_driver.termios_locked = tty_termios_locked;
+
+	tty_driver.init_termios = tty_std_termios;
+
+	tty_driver.open = memcons_tty_open;
+	tty_driver.write = memcons_tty_write;
+	tty_driver.write_room = memcons_tty_write_room;
+	tty_driver.chars_in_buffer = memcons_tty_chars_in_buffer;
+
+	tty_register_driver (&tty_driver);
+}
+__initcall (memcons_tty_init);
diff -Nru a/arch/v850/kernel/nb85e_intc.c b/arch/v850/kernel/nb85e_intc.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/nb85e_intc.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,68 @@
+/*
+ * arch/v850/kernel/nb85e_intc.c -- NB85E cpu core interrupt controller (INTC)
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/nb85e_intc.h>
+
+static void irq_nop (unsigned irq) { }
+
+static unsigned nb85e_intc_irq_startup (unsigned irq)
+{
+	nb85e_intc_clear_pending_irq (irq);
+	nb85e_intc_enable_irq (irq);
+	return 0;
+}
+
+/* Initialize HW_IRQ_TYPES for INTC-controlled irqs described in array
+   INITS (which is terminated by an entry with the name field == 0).  */
+void __init nb85e_intc_init_irq_types (struct nb85e_intc_irq_init *inits,
+				       struct hw_interrupt_type *hw_irq_types)
+{
+	struct nb85e_intc_irq_init *init;
+	for (init = inits; init->name; init++) {
+		int i;
+		struct hw_interrupt_type *hwit = hw_irq_types++;
+
+		hwit->typename = init->name;
+
+		hwit->startup  = nb85e_intc_irq_startup;
+		hwit->shutdown = nb85e_intc_disable_irq;
+		hwit->enable   = nb85e_intc_enable_irq;
+		hwit->disable  = nb85e_intc_disable_irq;
+		hwit->ack      = irq_nop;
+		hwit->end      = irq_nop;
+		
+		/* Initialize kernel IRQ infrastructure for this interrupt.  */
+		init_irq_handlers(init->base, init->num, init->interval, hwit);
+
+		/* Set the interrupt priorities.  */
+		for (i = 0; i < init->num; i++) {
+			unsigned irq = init->base + i * init->interval;
+
+			/* If the interrupt is currently enabled (all
+			   interrupts are initially disabled), then
+			   assume whoever enabled it has set things up
+			   properly, and avoid messing with it.  */
+			if (! nb85e_intc_irq_enabled (irq))
+				/* This write also (1) disables the
+				   interrupt, and (2) clears any pending
+				   interrupts.  */
+				NB85E_INTC_IC (irq)
+					= (NB85E_INTC_IC_PR (init->priority)
+					   | NB85E_INTC_IC_MK);
+		}
+	}
+}
diff -Nru a/arch/v850/kernel/nb85e_timer_d.c b/arch/v850/kernel/nb85e_timer_d.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/nb85e_timer_d.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,54 @@
+/*
+ * include/asm-v850/nb85e_timer_d.c -- `Timer D' component often used
+ *	with the NB85E cpu core
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/kernel.h>
+
+#include <asm/nb85e_utils.h>
+#include <asm/nb85e_timer_d.h>
+
+/* Start interval timer TIMER (0-3).  The timer will issue the
+   corresponding INTCMD interrupt RATE times per second.
+   This function does not enable the interrupt.  */
+void nb85e_timer_d_configure (unsigned timer, unsigned rate)
+{
+	unsigned divlog2, count;
+
+	/* Calculate params for timer.  */
+	if (! calc_counter_params (
+		    NB85E_TIMER_D_BASE_FREQ, rate,
+		    NB85E_TIMER_D_TMCD_CS_MIN, NB85E_TIMER_D_TMCD_CS_MAX, 16,
+		    &divlog2, &count))
+		printk (KERN_WARNING
+			"Cannot find interval timer %d setting suitable"
+			" for rate of %dHz.\n"
+			"Using rate of %dHz instead.\n",
+			timer, rate,
+			(NB85E_TIMER_D_BASE_FREQ >> divlog2) >> 16);
+
+	/* Do the actual hardware timer initialization:  */
+
+	/* Enable timer.  */
+	NB85E_TIMER_D_TMCD(timer) = NB85E_TIMER_D_TMCD_CAE;
+	/* Set clock divider.  */
+	NB85E_TIMER_D_TMCD(timer)
+		= NB85E_TIMER_D_TMCD_CAE
+		| NB85E_TIMER_D_TMCD_CS(divlog2);
+	/* Set timer compare register.  */
+	NB85E_TIMER_D_CMD(timer) = count;
+	/* Start counting.  */
+	NB85E_TIMER_D_TMCD(timer)
+		= NB85E_TIMER_D_TMCD_CAE
+		| NB85E_TIMER_D_TMCD_CS(divlog2)
+		| NB85E_TIMER_D_TMCD_CE;
+}
diff -Nru a/arch/v850/kernel/nb85e_utils.c b/arch/v850/kernel/nb85e_utils.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/nb85e_utils.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,65 @@
+/*
+ * include/asm-v850/nb85e_utils.h -- Utility functions associated with
+ *	the NB85E cpu core
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+/* Note: these functions are often associated with the N85E cpu core,
+   but not always, which is why they're not in `nb85e.c'.  */
+
+#include <asm/nb85e_utils.h>
+
+/* Calculate counter clock-divider and count values to attain the
+   desired frequency RATE from the base frequency BASE_FREQ.  The
+   counter is expected to have a clock-divider, which can divide the
+   system cpu clock by a power of two value from MIN_DIVLOG2 to
+   MAX_DIV_LOG2, and a word-size of COUNTER_SIZE bits (the counter
+   counts up and resets whenever it's equal to the compare register,
+   generating an interrupt or whatever when it does so).  The returned
+   values are: *DIVLOG2 -- log2 of the desired clock divider and *COUNT
+   -- the counter compare value to use.  Returns true if it was possible
+   to find a reasonable value, otherwise false (and the other return
+   values will be set to be as good as possible).  */
+int calc_counter_params (unsigned long base_freq,
+			 unsigned long rate,
+			 unsigned min_divlog2, unsigned max_divlog2,
+			 unsigned counter_size,
+			 unsigned *divlog2, unsigned *count)
+{
+	unsigned _divlog2;
+	int ok = 0;
+
+	/* Find the lowest clock divider setting that can represent RATE.  */
+	for (_divlog2 = min_divlog2; _divlog2 <= max_divlog2; _divlog2++) {
+		/* Minimum interrupt rate possible using this divider.  */
+		int min_int_rate
+			= (base_freq >> _divlog2) >> counter_size;
+
+		if (min_int_rate <= rate) {
+			/* This setting is the highest resolution
+			   setting that's slow enough enough to attain
+			   RATE interrupts per second, so use it.  */
+			ok = 1;
+			break;
+		}
+	}
+
+	if (_divlog2 > max_divlog2)
+		/* Can't find correct setting.  */
+		_divlog2 = max_divlog2;
+
+	if (divlog2)
+		*divlog2 = _divlog2;
+	if (count)
+		*count = ((base_freq >> _divlog2) + rate/2) / rate;
+
+	return ok;
+}
diff -Nru a/arch/v850/kernel/process.c b/arch/v850/kernel/process.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/process.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,282 @@
+/*
+ * arch/v850/kernel/process.c -- Arch-dependent process handling
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/reboot.h>
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/setup.h>
+#include <asm/pgtable.h>
+
+extern void ret_from_fork (void);
+
+
+/* The idle loop.  */
+void default_idle (void)
+{
+	while (1) {
+		while (! need_resched ())
+			asm ("halt; nop; nop; nop; nop; nop" ::: "cc");
+		schedule ();
+	}
+}
+
+void (*idle)(void) = default_idle;
+
+/*
+ * The idle thread. There's no useful work to be
+ * done, so just try to conserve power and have a
+ * low exit latency (ie sit in a loop waiting for
+ * somebody to say that they'd like to reschedule)
+ */
+void cpu_idle (void)
+{
+	/* endless idle loop with no priority at all */
+	(*idle) ();
+}
+
+struct spec_reg_name {
+	const char *name;
+	int gpr;
+};
+
+struct spec_reg_name spec_reg_names[] = {
+	{ "sp", GPR_SP },
+	{ "gp", GPR_GP },
+	{ "tp", GPR_TP },
+	{ "ep", GPR_EP },
+	{ "lp", GPR_LP },
+	{ 0, 0 }
+};
+
+void show_regs (struct pt_regs *regs)
+{
+	int gpr_base, gpr_offs;
+
+	printk ("     pc 0x%08lx    psw 0x%08lx                       kernel_mode %d\n",
+		regs->pc, regs->psw, regs->kernel_mode);
+	printk ("   ctpc 0x%08lx  ctpsw 0x%08lx   ctbp 0x%08lx\n",
+		regs->ctpc, regs->ctpsw, regs->ctbp);
+
+	for (gpr_base = 0; gpr_base < NUM_GPRS; gpr_base += 4) {
+		for (gpr_offs = 0; gpr_offs < 4; gpr_offs++) {
+			int gpr = gpr_base + gpr_offs;
+			long val = regs->gpr[gpr];
+			struct spec_reg_name *srn;
+
+			for (srn = spec_reg_names; srn->name; srn++)
+				if (srn->gpr == gpr)
+					break;
+
+			if (srn->name)
+				printk ("%7s 0x%08lx", srn->name, val);
+			else
+				printk ("    r%02d 0x%08lx", gpr, val);
+		}
+
+		printk ("\n");
+	}
+}
+
+/*
+ * This is the mechanism for creating a new kernel thread.
+ *
+ * NOTE! Only a kernel-only process (ie the swapper or direct descendants who
+ * haven't done an "execve()") should use this: it will work within a system
+ * call from a "real" process, but the process memory space will not be free'd
+ * until both the parent and the child have exited.
+ */
+int kernel_thread (int (*fn)(void *), void *arg, unsigned long flags)
+{
+	register mm_segment_t fs = get_fs ();
+	register unsigned long syscall asm (SYSCALL_NUM);
+	register unsigned long arg0 asm (SYSCALL_ARG0);
+	register unsigned long ret asm (SYSCALL_RET);
+
+	set_fs (KERNEL_DS);
+
+	/* Clone this thread.  */
+	arg0 = flags | CLONE_VM;
+	syscall = __NR_clone;
+	asm volatile ("trap " SYSCALL_SHORT_TRAP
+		      : "=r" (ret), "=r" (syscall)
+		      : "1" (syscall), "r" (arg0)
+		      : SYSCALL_SHORT_CLOBBERS);
+
+	if (ret == 0) {
+		/* In child thread, call FN and exit.  */
+		arg0 = (*fn) (arg);
+		syscall = __NR_exit;
+		asm volatile ("trap " SYSCALL_SHORT_TRAP
+			      : "=r" (ret), "=r" (syscall)
+			      : "1" (syscall), "r" (arg0)
+			      : SYSCALL_SHORT_CLOBBERS);
+	}
+
+	/* In parent.  */
+	set_fs (fs);
+
+	return ret;
+}
+
+void flush_thread (void)
+{
+	set_fs (USER_DS);
+}
+
+int copy_thread (int nr, unsigned long clone_flags,
+		 unsigned long stack_start, unsigned long stack_size,
+		 struct task_struct *p, struct pt_regs *regs)
+{
+	/* Start pushing stuff from the top of the child's kernel stack.  */
+	unsigned long ksp = (unsigned long)p->thread_info + THREAD_SIZE;
+	/* We push two `state save' stack fames (see entry.S) on the new
+	   kernel stack:
+	     1) The innermost one is what switch_thread would have
+	        pushed, and is used when we context switch to the child
+		thread for the first time.  It's set up to return to
+		ret_from_fork in entry.S.
+	     2) The outermost one (nearest the top) is what a syscall
+	        trap would have pushed, and is set up to return to the
+		same location as the parent thread, but with a return
+		value of 0. */
+	struct pt_regs *child_switch_regs, *child_trap_regs;
+
+	/* Trap frame.  */
+	ksp -= STATE_SAVE_SIZE;
+	child_trap_regs = (struct pt_regs *)(ksp + STATE_SAVE_PT_OFFSET);
+	/* Switch frame.  */
+	ksp -= STATE_SAVE_SIZE;
+	child_switch_regs = (struct pt_regs *)(ksp + STATE_SAVE_PT_OFFSET);
+
+	/* First copy parent's register state to child.  */
+	*child_switch_regs = *regs;
+	*child_trap_regs = *regs;
+
+	/* switch_thread returns to the restored value of the lp
+	   register (r31), so we make that the place where we want to
+	   jump when the child thread begins running.  */
+	child_switch_regs->gpr[GPR_LP] = (v850_reg_t)ret_from_fork;
+
+	/* Thread state for the child (everything else is on the stack).  */
+	p->thread.ksp = ksp;
+
+	return 0;
+}
+
+/*
+ * fill in the user structure for a core dump..
+ */
+void dump_thread (struct pt_regs *regs, struct user *dump)
+{
+#if 0  /* Later.  XXX */
+	dump->magic = CMAGIC;
+	dump->start_code = 0;
+	dump->start_stack = regs->gpr[GPR_SP];
+	dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
+	dump->u_dsize = ((unsigned long) (current->mm->brk +
+					  (PAGE_SIZE-1))) >> PAGE_SHIFT;
+	dump->u_dsize -= dump->u_tsize;
+	dump->u_ssize = 0;
+
+	if (dump->start_stack < TASK_SIZE)
+		dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
+
+	dump->u_ar0 = (struct user_regs_struct *)((int)&dump->regs - (int)dump);
+	dump->regs = *regs;
+	dump->u_fpvalid = 0;
+#endif
+}
+
+/*
+ * sys_execve() executes a new program.
+ */
+int sys_execve (char *name, char **argv, char **envp, struct pt_regs *regs)
+{
+	char *filename = getname (name);
+	int error = PTR_ERR (filename);
+
+	if (! IS_ERR (filename)) {
+		error = do_execve (filename, argv, envp, regs);
+		putname (filename);
+	}
+
+	return error;
+}
+
+/* This is the common part of the various fork-like system calls (which
+   are in entry.S).  */
+int fork_common (int flags, unsigned long new_sp, struct pt_regs *regs)
+{
+	struct task_struct *p = do_fork (flags, new_sp, regs, 0, 0);
+	return IS_ERR (p) ? PTR_ERR (p) : p->pid;
+}
+
+
+/*
+ * These bracket the sleeping functions..
+ */
+extern void scheduling_functions_start_here (void);
+extern void scheduling_functions_end_here (void);
+#define first_sched	((unsigned long) scheduling_functions_start_here)
+#define last_sched	((unsigned long) scheduling_functions_end_here)
+
+unsigned long get_wchan (struct task_struct *p)
+{
+#if 0  /* Barf.  Figure out the stack-layout later.  XXX  */
+	unsigned long fp, pc;
+	int count = 0;
+
+	if (!p || p == current || p->state == TASK_RUNNING)
+		return 0;
+
+	pc = thread_saved_pc (&p->thread);
+
+	/* This quite disgusting function walks up the stack, following
+	   saved return address, until it something that's out of bounds
+	   (as defined by `first_sched' and `last_sched').  It then
+	   returns the last PC that was in-bounds.  */
+	do {
+		if (fp < stack_page + sizeof (struct task_struct) ||
+		    fp >= 8184+stack_page)
+			return 0;
+		pc = ((unsigned long *)fp)[1];
+		/* FIXME: This depends on the order of these functions. */
+		if (pc < first_sched || pc >= last_sched)
+			return pc;
+		fp = *(unsigned long *) fp;
+	} while (count++ < 16);
+#endif
+
+	return 0;
+}
+
+void show_trace_task (struct task_struct *t)
+{
+        /* blarg XXX */
+	printk ("show_trace_task: KSP = 0x%lx, USP = 0x%lx, UPC = 0x%lx\n",
+		t->thread.ksp, KSTK_ESP (t), KSTK_EIP (t));
+}
diff -Nru a/arch/v850/kernel/procfs.c b/arch/v850/kernel/procfs.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/procfs.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,67 @@
+/*
+ * arch/v850/kernel/procfs.c -- Introspection functions for /proc filesystem
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include "mach.h"
+
+static int cpuinfo_print (struct seq_file *m, void *v)
+{
+	extern unsigned long loops_per_jiffy;
+	
+	seq_printf (m, "CPU-Family:	v850\nCPU-Arch:	%s\n", CPU_ARCH);
+
+#ifdef CPU_MODEL_LONG
+	seq_printf (m, "CPU-Model:	%s (%s)\n", CPU_MODEL, CPU_MODEL_LONG);
+#else
+	seq_printf (m, "CPU-Model:	%s\n", CPU_MODEL);
+#endif
+ 
+#ifdef CPU_CLOCK_FREQ
+	seq_printf (m, "CPU-Clock:	%ld (%ld MHz)\n",
+		    (long)CPU_CLOCK_FREQ,
+		    (long)CPU_CLOCK_FREQ / 1000000);
+#endif
+
+	seq_printf (m, "BogoMips:	%lu.%02lu\n",
+		    loops_per_jiffy/(500000/HZ),
+		    (loops_per_jiffy/(5000/HZ)) % 100);
+
+#ifdef PLATFORM_LONG
+	seq_printf (m, "Platform:	%s (%s)\n", PLATFORM, PLATFORM_LONG);
+#elif defined (PLATFORM)
+	seq_printf (m, "Platform:	%s\n", PLATFORM);
+#endif
+
+	return 0;
+}
+
+static void *cpuinfo_start (struct seq_file *m, loff_t *pos)
+{
+	return *pos < NR_CPUS ? ((void *) 0x12345678) : NULL;
+}
+
+static void *cpuinfo_next (struct seq_file *m, void *v, loff_t *pos)
+{
+	++*pos;
+	return cpuinfo_start (m, pos);
+}
+
+static void cpuinfo_stop (struct seq_file *m, void *v)
+{
+}
+
+struct seq_operations cpuinfo_op = {
+	start:	cpuinfo_start,
+	next:	cpuinfo_next,
+	stop:	cpuinfo_stop,
+	show:	cpuinfo_print
+};
diff -Nru a/arch/v850/kernel/ptrace.c b/arch/v850/kernel/ptrace.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/ptrace.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,202 @@
+/*
+ * arch/v850/kernel/ptrace.c -- `ptrace' system call
+ *
+ *  Copyright (C) 2002  NEC Corporation
+ *  Copyright (C) 2002  Miles Bader <miles@gnu.org>
+ *
+ * Derived from arch/mips/kernel/ptrace.c:
+ *
+ *  Copyright (C) 1992 Ross Biro
+ *  Copyright (C) Linus Torvalds
+ *  Copyright (C) 1994, 95, 96, 97, 98, 2000 Ralf Baechle
+ *  Copyright (C) 1996 David S. Miller
+ *  Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ *  Copyright (C) 1999 MIPS Technologies, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/ptrace.h>
+
+#include <asm/errno.h>
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+
+int sys_ptrace(long request, long pid, long addr, long data)
+{
+	struct task_struct *child;
+	int rval;
+
+	lock_kernel();
+
+#if 0
+	printk("ptrace(r=%d,pid=%d,addr=%08lx,data=%08lx)\n",
+	       (int) request, (int) pid, (unsigned long) addr,
+	       (unsigned long) data);
+#endif
+
+	if (request == PTRACE_TRACEME) {
+		/* are we already being traced? */
+		if (current->ptrace & PT_PTRACED) {
+			rval = -EPERM;
+			goto out;
+		}
+		/* set the ptrace bit in the process flags. */
+		current->ptrace |= PT_PTRACED;
+		rval = 0;
+		goto out;
+	}
+	rval = -ESRCH;
+	read_lock(&tasklist_lock);
+	child = find_task_by_pid(pid);
+	if (child)
+		get_task_struct(child);
+	read_unlock(&tasklist_lock);
+	if (!child)
+		goto out;
+
+	rval = -EPERM;
+	if (pid == 1)		/* you may not mess with init */
+		goto out;
+
+	if (request == PTRACE_ATTACH) {
+		rval = ptrace_attach(child);
+		goto out_tsk;
+	}
+	rval = -ESRCH;
+	if (!(child->ptrace & PT_PTRACED))
+		goto out_tsk;
+	if (child->state != TASK_STOPPED) {
+		if (request != PTRACE_KILL)
+			goto out_tsk;
+	}
+	if (child->parent != current)
+		goto out_tsk;
+
+	switch (request) {
+	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
+	case PTRACE_PEEKDATA:{
+		unsigned long tmp;
+		int copied;
+
+		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+		rval = -EIO;
+		if (copied != sizeof(tmp))
+			break;
+		rval = put_user(tmp,(unsigned long *) data);
+
+		goto out;
+		}
+
+	/* Read the word at location addr in the USER area.  */
+	case PTRACE_PEEKUSR: 
+		if (addr >= 0 && addr < PT_SIZE && (addr & 0x3) == 0) {
+			struct pt_regs *regs = task_regs (child);
+			unsigned long val =
+				*(unsigned long *)((char *)regs + addr);
+			rval = put_user (val, (unsigned long *)data);
+		} else {
+			rval = 0;
+			rval = -EIO;			
+		}
+		goto out;
+
+	case PTRACE_POKETEXT: /* write the word at location addr. */
+	case PTRACE_POKEDATA:
+		rval = 0;
+		if (access_process_vm(child, addr, &data, sizeof(data), 1)
+		    == sizeof(data))
+			break;
+		rval = -EIO;
+		goto out;
+
+	case PTRACE_POKEUSR:
+		if (addr >= 0 && addr < PT_SIZE && (addr & 0x3) == 0) {
+			struct pt_regs *regs = task_regs (child);
+			unsigned long *loc =
+				(unsigned long *)((char *)regs + addr);
+			*loc = data;
+		} else {
+			rval = 0;
+			rval = -EIO;			
+		}
+		goto out;
+
+	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+	case PTRACE_CONT: /* rvaltart after signal. */
+		rval = -EIO;
+		if ((unsigned long) data > _NSIG)
+			break;
+		if (request == PTRACE_SYSCALL)
+			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+		else
+			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+		child->exit_code = data;
+		wake_up_process(child);
+		rval = 0;
+		break;
+
+	/*
+	 * make the child exit.  Best I can do is send it a sigkill. 
+	 * perhaps it should be put in the status that it wants to 
+	 * exit.
+	 */
+	case PTRACE_KILL:
+		rval = 0;
+		if (child->state == TASK_ZOMBIE)	/* already dead */
+			break;
+		child->exit_code = SIGKILL;
+		wake_up_process(child);
+		break;
+
+	case PTRACE_DETACH: /* detach a process that was attached. */
+		rval = ptrace_detach(child, data);
+		break;
+
+	default:
+		rval = -EIO;
+		goto out;
+	}
+
+out_tsk:
+	put_task_struct(child);
+out:
+	unlock_kernel();
+	return rval;
+}
+
+asmlinkage void syscall_trace(void)
+{
+	if (!test_thread_flag(TIF_SYSCALL_TRACE))
+		return;
+	if (!(current->ptrace & PT_PTRACED))
+		return;
+	/* The 0x80 provides a way for the tracing parent to distinguish
+	   between a syscall stop and SIGTRAP delivery */
+	current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+	                                ? 0x80 : 0);
+	current->state = TASK_STOPPED;
+	notify_parent(current, SIGCHLD);
+	schedule();
+	/*
+	 * this isn't the same as continuing with a signal, but it will do
+	 * for normal use.  strace only continues with a signal if the
+	 * stopping signal is not SIGTRAP.  -brl
+	 */
+	if (current->exit_code) {
+		send_sig(current->exit_code, current, 1);
+		current->exit_code = 0;
+	}
+}
+
+void ptrace_disable (struct task_struct *child)
+{
+	/* nothing to do */
+}
diff -Nru a/arch/v850/kernel/rte_cb.c b/arch/v850/kernel/rte_cb.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/rte_cb.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,234 @@
+/*
+ * include/asm-v850/rte_cb.c -- Midas lab RTE-CB series of evaluation boards
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/fs.h>
+
+#include <asm/machdep.h>
+#include <asm/nb85e_uart.h>
+
+#include "mach.h"
+
+static void led_tick (void);
+
+/* LED access routines.  */
+extern unsigned read_leds (int pos, char *buf, int len);
+extern unsigned write_leds (int pos, const char *buf, int len);
+
+#ifdef CONFIG_RTE_CB_MULTI
+extern void multi_init (void);
+#endif
+
+
+#ifdef CONFIG_ROM_KERNEL
+/* Initialization for kernel in ROM.  */
+static inline rom_kernel_init (void)
+{
+	/* If the kernel is in ROM, we have to copy any initialized data
+	   from ROM into RAM.  */
+	extern unsigned long _data_load_start, _sdata, _edata;
+	register unsigned long *src = &_data_load_start;
+	register unsigned long *dst = &_sdata, *end = &_edata;
+
+	while (dst != end)
+		*dst++ = *src++;
+}
+#endif /* CONFIG_ROM_KERNEL */
+
+void __init mach_early_init (void)
+{
+	nb85e_intc_disable_irqs ();
+
+#if defined (CONFIG_ROM_KERNEL)
+	rom_kernel_init ();
+#elif defined (CONFIG_RTE_CB_MULTI)
+	multi_init ();
+#endif
+}
+
+void __init mach_setup (char **cmdline)
+{
+	printk (KERN_INFO
+		"CPU: %s\n"
+		"Platform: %s%s\n",
+		CPU_MODEL_LONG,
+		PLATFORM_LONG,
+#ifdef CONFIG_ROM_KERNEL
+		""
+#elif defined (CONFIG_RTE_CB_MULTI)
+		" (with Multi ROM monitor)"
+#else
+		" (with ROM monitor)"
+#endif		
+		);
+
+	/* Probe for Mother-A, and print a message if we find it.  */
+	*(volatile long *)MB_A_SRAM_ADDR = 0xDEADBEEF;
+	if (*(volatile long *)MB_A_SRAM_ADDR == 0xDEADBEEF) {
+		*(volatile long *)MB_A_SRAM_ADDR = 0x12345678;
+		if (*(volatile long *)MB_A_SRAM_ADDR == 0x12345678)
+			printk (KERN_INFO
+				"          NEC SolutionGear/Midas lab"
+				" RTE-MOTHER-A motherboard\n");
+	}
+
+#if defined (CONFIG_V850E_NB85E_UART_CONSOLE) && !defined (CONFIG_TIME_BOOTUP)
+	nb85e_uart_cons_init (0);
+#endif
+
+	mach_tick = led_tick;
+}
+
+#ifdef CONFIG_TIME_BOOTUP
+void initial_boot_done (void)
+{
+#ifdef CONFIG_V850E_NB85E_UART_CONSOLE
+	nb85e_uart_cons_init (0);
+#endif
+}
+#endif
+
+void machine_restart (char *__unused)
+{
+#ifdef CONFIG_RESET_GUARD
+	disable_reset_guard ();
+#endif
+	asm ("jmp r0"); /* Jump to the reset vector.  */
+}
+
+/* This says `HALt.' in LEDese.  */
+static unsigned char halt_leds_msg[] = { 0x76, 0x77, 0x38, 0xF8 };
+
+void machine_halt (void)
+{
+#ifdef CONFIG_RESET_GUARD
+	disable_reset_guard ();
+#endif
+
+	/* Ignore all interrupts.  */
+	local_irq_disable ();
+
+	/* Write a little message.  */
+	write_leds (0, halt_leds_msg, sizeof halt_leds_msg);
+
+	/* Really halt.  */
+	for (;;)
+		asm ("halt; nop; nop; nop; nop; nop");
+}
+
+void machine_power_off (void)
+{
+	machine_halt ();
+}
+
+
+/* Animated LED display for timer tick.  */
+
+#define TICK_UPD_FREQ	6
+static int tick_frames[][10] = {
+	{ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, -1 },
+	{ 0x63, 0x5c, -1 },
+	{ 0x5c, 0x00, -1 },
+	{ 0x63, 0x00, -1 },
+	{ -1 }
+};
+
+static void led_tick ()
+{
+	static unsigned counter = 0;
+	
+	if (++counter == (HZ / TICK_UPD_FREQ)) {
+		/* Which frame we're currently displaying for each digit.  */
+		static unsigned frame_nums[LED_NUM_DIGITS] = { 0 };
+		/* Display image.  */
+		static unsigned char image[LED_NUM_DIGITS] = { 0 };
+		unsigned char prev_image[LED_NUM_DIGITS];
+		int write_to_leds = 1; /* true if we should actually display */
+		int digit;
+
+		/* We check to see if the physical LEDs contains what we last
+		   wrote to them; if not, we suppress display (this is so that
+		   users can write to the LEDs, and not have their output
+		   overwritten).  As a special case, we start writing again if
+		   all the LEDs are blank, or our display image is all zeros
+		   (indicating that this is the initial update, when the actual
+		   LEDs might contain random data).  */
+		read_leds (0, prev_image, LED_NUM_DIGITS);
+		for (digit = 0; digit < LED_NUM_DIGITS; digit++)
+			if (image[digit] != prev_image[digit]
+			    && image[digit] && prev_image[digit])
+			{
+				write_to_leds = 0;
+				break;
+			}
+
+		/* Update display image.  */
+		for (digit = 0;
+		     digit < LED_NUM_DIGITS && tick_frames[digit][0] >= 0;
+		     digit++)
+		{
+			int frame = tick_frames[digit][frame_nums[digit]];
+			if (frame < 0) {
+				image[digit] = tick_frames[digit][0];
+				frame_nums[digit] = 1;
+			} else {
+				image[digit] = frame;
+				frame_nums[digit]++;
+				break;
+			}
+		}
+
+		if (write_to_leds)
+			/* Write the display image to the physical LEDs.  */
+			write_leds (0, image, LED_NUM_DIGITS);
+
+		counter = 0;
+	}
+}
+
+
+/* Mother-A interrupts.  */
+
+#ifdef CONFIG_RTE_GBUS_INT
+
+#define L GBUS_INT_PRIORITY_LOW
+#define M GBUS_INT_PRIORITY_MEDIUM
+#define H GBUS_INT_PRIORITY_HIGH
+
+static struct gbus_int_irq_init gbus_irq_inits[] = {
+#ifdef CONFIG_RTE_MB_A_PCI
+	{ "MB_A_LAN",	IRQ_MB_A_LAN,		1,		     1, L },
+	{ "MB_A_PCI1",	IRQ_MB_A_PCI1(0),	IRQ_MB_A_PCI1_NUM,   1, L },
+	{ "MB_A_PCI2",	IRQ_MB_A_PCI2(0),	IRQ_MB_A_PCI2_NUM,   1, L },
+	{ "MB_A_EXT",	IRQ_MB_A_EXT(0),	IRQ_MB_A_EXT_NUM,    1, L },
+	{ "MB_A_USB_OC",IRQ_MB_A_USB_OC(0),	IRQ_MB_A_USB_OC_NUM, 1, L },
+	{ "MB_A_PCMCIA_OC",IRQ_MB_A_PCMCIA_OC,	1,		     1, L },
+#endif
+	{ 0 }
+};
+#define NUM_GBUS_IRQ_INITS  \
+   ((sizeof gbus_irq_inits / sizeof gbus_irq_inits[0]) - 1)
+
+static struct hw_interrupt_type gbus_hw_itypes[NUM_GBUS_IRQ_INITS];
+
+#endif /* CONFIG_RTE_GBUS_INT */
+
+void __init rte_cb_init_irqs (void)
+{
+#ifdef CONFIG_RTE_GBUS_INT
+	gbus_int_init_irqs ();
+	gbus_int_init_irq_types (gbus_irq_inits, gbus_hw_itypes);
+#endif /* CONFIG_RTE_GBUS_INT */
+}
diff -Nru a/arch/v850/kernel/rte_cb_leds.c b/arch/v850/kernel/rte_cb_leds.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/rte_cb_leds.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,135 @@
+/*
+ * include/asm-v850/rte_cb_leds.c -- Midas lab RTE-CB board LED device support
+ *
+ *  Copyright (C) 2002  NEC Corporation
+ *  Copyright (C) 2002  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/miscdevice.h>
+
+#include <asm/uaccess.h>
+
+#define LEDS_MINOR	169	/* Minor device number, using misc major.  */
+
+/* The actual LED hardware is write-only, so we hold the contents here too.  */
+static unsigned char leds_image[LED_NUM_DIGITS] = { 0 };
+
+/* Spinlock protecting the above leds.  */
+static spinlock_t leds_lock = SPIN_LOCK_UNLOCKED;
+
+/* Common body of LED read/write functions, checks POS and LEN for
+   correctness, declares a variable using IMG_DECL, initialized pointing at
+   the POS position in the LED image buffer, and and iterates COPY_EXPR
+   until BUF is equal to the last buffer position; finally, sets LEN to be
+   the amount actually copied.  IMG should be a variable declaration
+   (without an initializer or a terminating semicolon); POS, BUF, and LEN
+   should all be simple variables.  */
+#define DO_LED_COPY(img_decl, pos, buf, len, copy_expr)			\
+do {									\
+	if (pos > LED_NUM_DIGITS)					\
+		len = 0;						\
+	else {								\
+		if (pos + len > LED_NUM_DIGITS)				\
+			len = LED_NUM_DIGITS - pos;			\
+									\
+		if (len > 0) {						\
+			int _flags;					\
+			const char *_end = buf + len;			\
+			img_decl = &leds_image[pos];			\
+									\
+			spin_lock_irqsave (leds_lock, _flags);		\
+			do						\
+				(copy_expr);				\
+			while (buf != _end);				\
+			spin_unlock_irqrestore (leds_lock, _flags);	\
+		}							\
+	}								\
+} while (0)
+
+/* Read LEN bytes from LEDs at position POS, into BUF.
+   Returns actual amount read.  */
+unsigned read_leds (unsigned pos, char *buf, unsigned len)
+{
+	DO_LED_COPY (const char *img, pos, buf, len, *buf++ = *img++);
+	return len;
+}
+
+/* Write LEN bytes to LEDs at position POS, from BUF.
+   Returns actual amount written.  */
+unsigned write_leds (unsigned pos, const char *buf, unsigned len)
+{
+	/* We write the actual LED values backwards, because
+	   increasing memory addresses reflect LEDs right-to-left. */
+	volatile char *led = &LED (LED_NUM_DIGITS - pos - 1);
+	/* We invert the value written to the hardware, because 1 = off,
+	   and 0 = on.  */
+	DO_LED_COPY (char *img, pos, buf, len,
+		     *led-- = 0xFF ^ (*img++ = *buf++));
+	return len;
+}
+
+
+/* Device functions.  */
+
+static ssize_t leds_dev_read (struct file *file, char *buf, size_t len,
+			      loff_t *pos)
+{
+	char temp_buf[LED_NUM_DIGITS];
+	len = read_leds (*pos, temp_buf, len);
+	if (copy_to_user (buf, temp_buf, len))
+		return -EFAULT;
+	*pos += len;
+	return len;
+}
+
+static ssize_t leds_dev_write (struct file *file, const char *buf, size_t len,
+			       loff_t *pos)
+{
+	char temp_buf[LED_NUM_DIGITS];
+	if (copy_from_user (temp_buf, buf, min_t(size_t, len, LED_NUM_DIGITS)))
+		return -EFAULT;
+	len = write_leds (*pos, temp_buf, len);
+	*pos += len;
+	return len;
+}
+
+static loff_t leds_dev_lseek (struct file *file, loff_t offs, int whence)
+{
+	if (whence == 1)
+		offs += file->f_pos; /* relative */
+	else if (whence == 2)
+		offs += LED_NUM_DIGITS; /* end-relative */
+
+	if (offs >= 0 && offs <= LED_NUM_DIGITS)
+		file->f_pos = offs;
+	else
+		return -EINVAL;
+}
+
+static struct file_operations leds_fops = {
+	read:		leds_dev_read,
+	write:		leds_dev_write,
+	llseek:		leds_dev_lseek
+};
+
+static struct miscdevice leds_miscdev = {
+	name:		"leds",
+	minor:		LEDS_MINOR,
+	fops:		&leds_fops
+};
+
+int __init leds_dev_init (void)
+{
+	return misc_register (&leds_miscdev);
+}
+
+__initcall (leds_dev_init);
diff -Nru a/arch/v850/kernel/rte_cb_multi.c b/arch/v850/kernel/rte_cb_multi.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/rte_cb_multi.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,85 @@
+/*
+ * include/asm-v850/rte_multi.c -- Support for Multi debugger monitor ROM
+ * 	on Midas lab RTE-CB series of evaluation boards
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/init.h>
+
+#include <asm/machdep.h>
+
+/* A table of which interrupt vectors to install, since blindly
+   installing all of them makes the debugger stop working.  This is a
+   list of offsets in the interrupt vector area; each entry means to
+   copy that particular 16-byte vector.  An entry less than zero ends
+   the table.  */
+static long multi_intv_install_table[] = {
+	0x40, 0x50,		/* trap vectors */
+	/* Note -- illegal insn trap is used by the debugger.  */
+	0xD0, 0xE0, 0xF0,	/* GINT1 - GINT3 */
+	0x240, 0x250, 0x260, 0x270, /* timer D interrupts */
+	0x2D0, 0x2E0, 0x2F0,	/* UART channel 0 */
+	0x310, 0x320, 0x330,	/* UART channel 1 */
+	0x350, 0x360, 0x370,	/* UART channel 2 */
+	-1
+};
+
+/* Early initialization for kernel using Multi debugger ROM monitor.  */
+void __init multi_init (void)
+{
+	/* We're using the Multi debugger monitor, so we have to install
+	   the interrupt vectors.  The monitor doesn't allow them to be
+	   initially downloaded into their final destination because
+	   it's in the monitor's scratch-RAM area.  Unfortunately, Multi
+	   also doesn't deal correctly with ELF sections where the LMA
+	   and VMA differ -- it just ignores the LMA -- so we can't use
+	   that feature to work around the problem.  What we do instead
+	   is just put the interrupt vectors into a normal section, and
+	   do the necessary copying and relocation here.  Since the
+	   interrupt vector basically only contains `jr' instructions
+	   and no-ops, it's not that hard.  */
+	extern unsigned long _intv_load_start, _intv_start;
+	register unsigned long *src = &_intv_load_start;
+	register unsigned long *dst = (unsigned long *)INTV_BASE;
+	register unsigned long jr_fixup = (char *)&_intv_start - (char *)dst;
+	register long *ii;
+
+	/* Copy interupt vectors as instructed by multi_intv_install_table. */
+	for (ii = multi_intv_install_table; *ii >= 0; ii++) {
+		/* Copy 16-byte interrupt vector at offset *ii.  */
+		int boffs;
+		for (boffs = 0; boffs < 0x10; boffs += sizeof *src) {
+			/* Copy a single word, fixing up the jump offs
+			   if it's a `jr' instruction.  */
+			int woffs = (*ii + boffs) / sizeof *src;
+			unsigned long word = src[woffs];
+
+			if ((word & 0xFC0) == 0x780) {
+				/* A `jr' insn, fix up its offset (and yes, the
+				   wierd half-word swapping is intentional). */
+				unsigned short hi = word & 0xFFFF;
+				unsigned short lo = word >> 16;
+				unsigned long udisp22
+					= lo + ((hi & 0x3F) << 16);
+				long disp22 = (long)(udisp22 << 10) >> 10;
+
+				disp22 += jr_fixup;
+
+				hi = ((disp22 >> 16) & 0x3F) | 0x780;
+				lo = disp22 & 0xFFFF;
+
+				word = hi + (lo << 16);
+			}
+
+			dst[woffs] = word;
+		}
+	}
+}
diff -Nru a/arch/v850/kernel/rte_ma1_cb.c b/arch/v850/kernel/rte_ma1_cb.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/rte_ma1_cb.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,101 @@
+/*
+ * arch/v850/kernel/rte_ma1_cb.c -- Midas labs RTE-V850E/MA1-CB board
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+
+#include <asm/atomic.h>
+#include <asm/page.h>
+#include <asm/ma1.h>
+#include <asm/rte_ma1_cb.h>
+#include <asm/nb85e_timer_c.h>
+
+#include "mach.h"
+
+
+/* SRAM and SDRAM are almost contiguous (with a small hole in between;
+   see mach_reserve_bootmem for details), so just use both as one big area.  */
+#define RAM_START 	SRAM_ADDR
+#define RAM_END		(SDRAM_ADDR + SDRAM_SIZE)
+
+
+void __init mach_get_physical_ram (unsigned long *ram_start,
+				   unsigned long *ram_len)
+{
+	*ram_start = RAM_START;
+	*ram_len = RAM_END - RAM_START;
+}
+
+void __init mach_reserve_bootmem ()
+{
+#ifdef CONFIG_RTE_CB_MULTI
+	/* Prevent the kernel from touching the monitor's scratch RAM.  */
+	reserve_bootmem (MON_SCRATCH_ADDR, MON_SCRATCH_SIZE);
+#endif
+
+	/* The space between SRAM and SDRAM is filled with duplicate
+	   images of SRAM.  Prevent the kernel from using them.  */
+	reserve_bootmem (SRAM_ADDR + SRAM_SIZE,
+			 SDRAM_ADDR - (SRAM_ADDR + SRAM_SIZE));
+}
+
+void mach_gettimeofday (struct timespec *tv)
+{
+	tv->tv_sec = 0;
+	tv->tv_nsec = 0;
+}
+
+/* Called before configuring an on-chip UART.  */
+void rte_ma1_cb_uart_pre_configure (unsigned chan,
+				    unsigned cflags, unsigned baud)
+{
+	/* The RTE-MA1-CB connects some general-purpose I/O pins on the
+	   CPU to the RTS/CTS lines of UART 0's serial connection.
+	   I/O pins P42 and P43 are RTS and CTS respectively.  */
+	if (chan == 0) {
+		/* Put P42 & P43 in I/O port mode.  */
+		MA_PORT4_PMC &= ~0xC;
+		/* Make P42 and output, and P43 an input.  */
+		MA_PORT4_PM = (MA_PORT4_PM & ~0xC) | 0x8;
+	}
+
+	/* Do pre-configuration for the actual UART.  */
+	ma_uart_pre_configure (chan, cflags, baud);
+}
+
+void __init mach_init_irqs (void)
+{
+	unsigned tc;
+
+	/* Initialize interrupts.  */
+	ma_init_irqs ();
+	rte_cb_init_irqs ();
+
+	/* Use falling-edge-sensitivity for interrupts .  */
+	NB85E_TIMER_C_SESC (0) &= ~0xC;
+	NB85E_TIMER_C_SESC (1) &= ~0xF;
+
+	/* INTP000-INTP011 are shared with `Timer C', so we have to set
+	   up Timer C to pass them through as raw interrupts.  */
+	for (tc = 0; tc < 2; tc++)
+		/* Turn on the timer.  */
+		NB85E_TIMER_C_TMCC0 (tc) |= NB85E_TIMER_C_TMCC0_CAE;
+
+	/* Make sure the relevent port0/port1 pins are assigned
+	   interrupt duty.  We used INTP001-INTP011 (don't screw with
+	   INTP000 because the monitor uses it).  */
+	MA_PORT0_PMC |= 0x4;	/* P02 (INTP001) in IRQ mode.  */
+	MA_PORT1_PMC |= 0x6;	/* P11 (INTP010) & P12 (INTP011) in IRQ mode.*/
+}
diff -Nru a/arch/v850/kernel/rte_mb_a_pci.c b/arch/v850/kernel/rte_mb_a_pci.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/rte_mb_a_pci.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,781 @@
+/*
+ * arch/v850/kernel/mb_a_pci.c -- PCI support for Midas lab RTE-MOTHER-A board
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/pci.h>
+
+#include <asm/machdep.h>
+
+/* __nomods_init is like __devinit, but is a no-op when modules are enabled.
+   This is used by some routines that can be called either during boot
+   or by a module.  */
+#ifdef CONFIG_MODULES
+#define __nomods_init /*nothing*/
+#else
+#define __nomods_init __devinit
+#endif
+
+/* PCI devices on the Mother-A board can only do DMA to/from the MB SRAM
+   (the RTE-V850E/MA1-CB cpu board doesn't support PCI access to
+   CPU-board memory), and since linux DMA buffers are allocated in
+   normal kernel memory, we basically have to copy DMA blocks around
+   (this is like a `bounce buffer').  When a DMA block is `mapped', we
+   allocate an identically sized block in MB SRAM, and if we're doing
+   output to the device, copy the CPU-memory block to the MB-SRAM block.
+   When an active block is `unmapped', we will copy the block back to
+   CPU memory if necessary, and then deallocate the MB SRAM block.
+   Ack.  */
+
+/* Where the motherboard SRAM is in the PCI-bus address space (the
+   first 512K of it is also mapped at PCI address 0).  */
+#define PCI_MB_SRAM_ADDR 0x800000
+
+/* Convert CPU-view MB SRAM address to/from PCI-view addresses of the
+   same memory.  */
+#define MB_SRAM_TO_PCI(mb_sram_addr) \
+   ((dma_addr_t)mb_sram_addr - MB_A_SRAM_ADDR + PCI_MB_SRAM_ADDR)
+#define PCI_TO_MB_SRAM(pci_addr)     \
+   (void *)(pci_addr - PCI_MB_SRAM_ADDR + MB_A_SRAM_ADDR)
+
+static void pcibios_assign_resources (void);
+
+struct mb_pci_dev_irq {
+	unsigned dev;		/* PCI device number */
+	unsigned irq_base;	/* First IRQ  */
+	unsigned query_pin;	/* True if we should read the device's
+				   Interrupt Pin info, and allocate
+				   interrupt IRQ_BASE + PIN.  */
+};
+
+/* PCI interrupts are mapped statically to GBUS interrupts.  */
+static struct mb_pci_dev_irq mb_pci_dev_irqs[] = {
+	/* Motherboard SB82558 ethernet controller */
+	{ 10,	IRQ_MB_A_LAN,		0 },
+	/* PCI slot 1 */
+	{ 8, 	IRQ_MB_A_PCI1(0),	1 },
+	/* PCI slot 2 */
+	{ 9, 	IRQ_MB_A_PCI2(0),	1 }
+};
+#define NUM_MB_PCI_DEV_IRQS \
+  (sizeof mb_pci_dev_irqs / sizeof mb_pci_dev_irqs[0])
+
+
+/* PCI configuration primitives.  */
+
+#define CONFIG_DMCFGA(bus, devfn, offs)					\
+   (0x80000000								\
+    | ((offs) & ~0x3)							\
+    | ((devfn) << 8)							\
+    | ((bus)->number << 16))
+
+static int
+mb_pci_read (struct pci_bus *bus, unsigned devfn, int offs, int size, u32 *rval)
+{
+	u32 addr;
+	int flags;
+
+	local_irq_save (flags);
+
+	MB_A_PCI_PCICR = 0x7;
+	MB_A_PCI_DMCFGA = CONFIG_DMCFGA (bus, devfn, offs);
+
+	addr = MB_A_PCI_IO_ADDR + (offs & 0x3);
+
+	switch (size) {
+	case 1:	*rval = *(volatile  u8 *)addr; break;
+	case 2:	*rval = *(volatile u16 *)addr; break;
+	case 4:	*rval = *(volatile u32 *)addr; break;
+	}
+
+        if (MB_A_PCI_PCISR & 0x2000) {
+		MB_A_PCI_PCISR = 0x2000;
+		*rval = ~0;
+        }
+
+	MB_A_PCI_DMCFGA = 0;
+
+	local_irq_restore (flags);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+mb_pci_write (struct pci_bus *bus, unsigned devfn, int offs, int size, u32 val)
+{
+	u32 addr;
+	int flags;
+
+	local_irq_save (flags);
+
+	MB_A_PCI_PCICR = 0x7;
+	MB_A_PCI_DMCFGA = CONFIG_DMCFGA (bus, devfn, offs);
+
+	addr = MB_A_PCI_IO_ADDR + (offs & 0x3);
+
+	switch (size) {
+	case 1: *(volatile  u8 *)addr = val; break;
+	case 2: *(volatile u16 *)addr = val; break;
+	case 4: *(volatile u32 *)addr = val; break;
+	}
+
+        if (MB_A_PCI_PCISR & 0x2000)
+		MB_A_PCI_PCISR = 0x2000;
+
+	MB_A_PCI_DMCFGA = 0;
+
+	local_irq_restore (flags);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops mb_pci_config_ops = {
+	.read	= mb_pci_read,
+	.write	= mb_pci_write,
+};
+
+
+/* PCI Initialization.  */
+
+static struct pci_bus *mb_pci_bus = 0;
+
+/* Do initial PCI setup.  */
+static int __devinit pcibios_init (void)
+{
+	u32 id = MB_A_PCI_PCIHIDR;
+	u16 vendor = id & 0xFFFF;
+	u16 device = (id >> 16) & 0xFFFF;
+
+	if (vendor == PCI_VENDOR_ID_PLX && device == PCI_DEVICE_ID_PLX_9080) {
+		printk (KERN_INFO
+			"PCI: PLX Technology PCI9080 HOST/PCI bridge\n");
+
+		MB_A_PCI_PCICR = 0x147;
+		MB_A_PCI_DMLBAM = 0x0;
+
+		MB_A_PCI_PCIBAR0 = 0x007FFF00;
+		MB_A_PCI_PCIBAR1 = 0x0000FF00;
+		MB_A_PCI_PCIBAR2 = 0x00800000;
+
+		MB_A_PCI_PCILTR = 0x20;
+
+		MB_A_PCI_PCIPBAM |= 0x3;
+
+		MB_A_PCI_PCISR =  ~0; /* Clear errors.  */
+
+		/* Reprogram the motherboard's IO/config address space,
+		   as we don't support the GCS7 address space that the
+		   default uses.  Note that we have to give the address
+		   from the motherboard's point of view, which is
+		   different than the CPU's.  */
+		MB_A_PCI_DMLBAI = MB_A_PCI_IO_ADDR - GCS5_ADDR;
+		MB_A_PCI_DMRR = ~(MB_A_PCI_MEM_SIZE - 1);
+
+		mb_pci_bus = pci_scan_bus (0, &mb_pci_config_ops, 0);
+
+		pcibios_assign_resources ();
+	} else
+		printk (KERN_ERR "PCI: HOST/PCI bridge not found\n");
+
+	return 0;
+}
+
+subsys_initcall (pcibios_init);
+
+char __devinit *pcibios_setup (char *option)
+{
+	/* Don't handle any options. */
+	return option;
+}
+
+
+int __nomods_init pcibios_enable_device (struct pci_dev *dev, int mask)
+{
+	u16 cmd, old_cmd;
+	int idx;
+	struct resource *r;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	old_cmd = cmd;
+	for (idx = 0; idx < 6; idx++) {
+		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);
+			return -EINVAL;
+		}
+		if (r->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		if (r->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+	if (cmd != old_cmd) {
+		printk("PCI: Enabling device %s (%04x -> %04x)\n",
+		       dev->slot_name, old_cmd, cmd);
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+	return 0;
+}
+
+
+/* Resource allocation.  */
+static void __devinit pcibios_assign_resources (void)
+{
+	struct pci_dev *dev;
+	struct resource *r;
+
+	pci_for_each_dev (dev) {
+		int di_num;
+		unsigned class = dev->class >> 8;
+
+		if (class && class != PCI_CLASS_BRIDGE_HOST) {
+			unsigned r_num;
+			for(r_num = 0; r_num < 6; r_num++) {
+				r = &dev->resource[r_num];
+				if (!r->start && r->end)
+					pci_assign_resource (dev, r_num);
+			}
+		}
+
+		/* Assign interrupts.  */
+		for (di_num = 0; di_num < NUM_MB_PCI_DEV_IRQS; di_num++) {
+			struct mb_pci_dev_irq *di = &mb_pci_dev_irqs[di_num];
+
+			if (di->dev == PCI_SLOT (dev->devfn)) {
+				unsigned irq = di->irq_base;
+
+				if (di->query_pin) {
+					/* Find out which interrupt pin
+					   this device uses (each PCI
+					   slot has 4).  */
+					u8 irq_pin;
+
+					pci_read_config_byte (dev,
+							     PCI_INTERRUPT_PIN,
+							      &irq_pin);
+
+					if (irq_pin == 0)
+						/* Doesn't use interrupts.  */ 
+						continue;
+					else
+						irq += irq_pin - 1;
+				}
+
+				pcibios_update_irq (dev, irq);
+			}
+		}
+	}
+}
+
+void __devinit pcibios_update_irq (struct pci_dev *dev, int irq)
+{
+	dev->irq = irq;
+	pci_write_config_byte (dev, PCI_INTERRUPT_LINE, irq);
+}
+
+void __nomods_init
+pcibios_update_resource (struct pci_dev *dev, struct resource *root,
+			 struct resource *r, int resource)
+{
+	u32 new, check;
+	int reg;
+
+	if (r->flags & IORESOURCE_IO)
+		new = (((r->start - MB_A_PCI_IO_ADDR)
+			& PCI_BASE_ADDRESS_IO_MASK)
+		       | PCI_BASE_ADDRESS_SPACE_IO);
+	else if (r->flags & IORESOURCE_MEM)
+		new = (((r->start - MB_A_PCI_MEM_ADDR)
+			& PCI_BASE_ADDRESS_MEM_MASK)
+		       | PCI_BASE_ADDRESS_MEM_TYPE_32
+		       | ((r->flags & IORESOURCE_PREFETCH)
+			  ? PCI_BASE_ADDRESS_MEM_PREFETCH
+			  : 0)
+		       | PCI_BASE_ADDRESS_SPACE_MEMORY);
+	else
+		panic ("pcibios_update_resource: unknown resource type");
+
+	if (resource < 6)
+		reg = PCI_BASE_ADDRESS_0 + 4*resource;
+	else if (resource == PCI_ROM_RESOURCE) {
+		r->flags |= PCI_ROM_ADDRESS_ENABLE;
+		new |= PCI_ROM_ADDRESS_ENABLE;
+		reg = dev->rom_base_reg;
+	} else
+		return;
+	
+	pci_write_config_dword(dev, reg, new);
+	pci_read_config_dword(dev, reg, &check);
+	if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
+		printk (KERN_ERR "PCI: Error while updating region "
+			"%s/%d (%08x != %08x)\n", dev->slot_name, resource,
+			new, check);
+	}
+}
+
+
+/* Stubs for things we don't use.  */
+
+struct pci_fixup pcibios_fixups[] = { { 0 } };
+
+/* Called after each bus is probed, but before its children are examined. */
+void pcibios_fixup_bus(struct pci_bus *b)
+{
+}
+
+void
+pcibios_align_resource (void *data, struct resource *res,
+			unsigned long size, unsigned long align)
+{
+}
+
+void pcibios_set_master (struct pci_dev *dev)
+{
+}
+
+
+/* Mother-A SRAM memory allocation.  This is a simple first-fit allocator.  */
+
+/* A memory free-list node.  */
+struct mb_sram_free_area {
+	void *mem;
+	unsigned long size;
+	struct mb_sram_free_area *next;
+};
+
+/* The tail of the free-list, which starts out containing all the SRAM.  */
+static struct mb_sram_free_area mb_sram_free_tail = {
+	(void *)MB_A_SRAM_ADDR, MB_A_SRAM_SIZE, 0
+};
+
+/* The free-list.  */
+static struct mb_sram_free_area *mb_sram_free_areas = &mb_sram_free_tail;
+
+/* The free-list of free free-list nodes. (:-)  */
+static struct mb_sram_free_area *mb_sram_free_free_areas = 0;
+
+/* Spinlock protecting the above globals.  */
+static spinlock_t mb_sram_lock = SPIN_LOCK_UNLOCKED;
+
+/* Allocate a memory block at least SIZE bytes long in the Mother-A SRAM
+   space.  */
+static void *alloc_mb_sram (size_t size)
+{
+	struct mb_sram_free_area *prev, *fa;
+	int flags;
+	void *mem = 0;
+
+	spin_lock_irqsave (mb_sram_lock, flags);
+
+	/* Look for a free area that can contain SIZE bytes.  */
+	for (prev = 0, fa = mb_sram_free_areas; fa; prev = fa, fa = fa->next)
+		if (fa->size >= size) {
+			/* Found one!  */
+			mem = fa->mem;
+
+			if (fa->size == size) {
+				/* In fact, it fits exactly, so remove
+				   this node from the free-list.  */
+				if (prev)
+					prev->next = fa->next;
+				else
+					mb_sram_free_areas = fa->next;
+				/* Put it on the free-list-entry-free-list. */
+				fa->next = mb_sram_free_free_areas;
+				mb_sram_free_free_areas = fa;
+			} else {
+				/* FA is bigger than SIZE, so just
+				   reduce its size to account for this
+				   allocation.  */
+				fa->mem += size;
+				fa->size -= size;
+			}
+
+			break;
+		}
+
+	spin_unlock_irqrestore (mb_sram_lock, flags);
+
+	return mem;
+}
+
+/* Return the memory area MEM of size SIZE to the MB SRAM free pool.  */
+static void free_mb_sram (void *mem, size_t size)
+{
+	struct mb_sram_free_area *prev, *fa, *new_fa;
+	int flags;
+	void *end = mem + size;
+
+	spin_lock_irqsave (mb_sram_lock, flags);
+
+ retry:
+	/* Find an adjacent free-list entry.  */
+	for (prev = 0, fa = mb_sram_free_areas; fa; prev = fa, fa = fa->next)
+		if (fa->mem == end) {
+			/* FA is just after MEM, grow down to encompass it. */
+			fa->mem = mem;
+			fa->size += size;
+			goto done;
+		} else if (fa->mem + fa->size == mem) {
+			struct mb_sram_free_area *next_fa = fa->next;
+
+			/* FA is just before MEM, expand to encompass it. */
+			fa->size += size;
+
+			/* See if FA can now be merged with its successor. */
+			if (next_fa && fa->mem + fa->size == next_fa->mem) {
+				/* Yup; merge NEXT_FA's info into FA.  */
+				fa->size += next_fa->size;
+				fa->next = next_fa->next;
+				/* Free NEXT_FA.  */
+				next_fa->next = mb_sram_free_free_areas;
+				mb_sram_free_free_areas = next_fa;
+			}
+			goto done;
+		} else if (fa->mem > mem)
+			/* We've reached the right spot in the free-list
+			   without finding an adjacent free-area, so add
+			   a new free area to hold mem. */
+			break;
+
+	/* Make a new free-list entry.  */
+
+	/* First, get a free-list entry.  */
+	if (! mb_sram_free_free_areas) {
+		/* There are none, so make some.  */
+		void *block;
+		size_t block_size = sizeof (struct mb_sram_free_area) * 8;
+
+		/* Don't hold the lock while calling kmalloc (I'm not
+		   sure whether it would be a problem, since we use
+		   GFP_ATOMIC, but it makes me nervous).  */
+		spin_unlock_irqrestore (mb_sram_lock, flags);
+
+		block = kmalloc (block_size, GFP_ATOMIC);
+		if (! block)
+			panic ("free_mb_sram: can't allocate free-list entry");
+
+		/* Now get the lock back.  */
+		spin_lock_irqsave (mb_sram_lock, flags);
+
+		/* Add the new free free-list entries.  */
+		while (block_size > 0) {
+			struct mb_sram_free_area *nfa = block;
+			nfa->next = mb_sram_free_free_areas;
+			mb_sram_free_free_areas = nfa;
+			block += sizeof *nfa;
+			block_size -= sizeof *nfa;
+		}
+
+		/* Since we dropped the lock to call kmalloc, the
+		   free-list could have changed, so retry from the
+		   beginning.  */
+		goto retry;
+	}
+
+	/* Remove NEW_FA from the free-list of free-list entries.  */
+	new_fa = mb_sram_free_free_areas;
+	mb_sram_free_free_areas = new_fa->next;
+
+	/* NEW_FA initially holds only MEM.  */
+	new_fa->mem = mem;
+	new_fa->size = size;
+
+	/* Insert NEW_FA in the free-list between PREV and FA. */
+	new_fa->next = fa;
+	if (prev)
+		prev->next = new_fa;
+	else
+		mb_sram_free_areas = new_fa;
+
+ done:
+	spin_unlock_irqrestore (mb_sram_lock, flags);
+}
+
+
+/* Maintainence of CPU -> Mother-A DMA mappings.  */
+
+struct dma_mapping {
+	void *cpu_addr;
+	void *mb_sram_addr;
+	size_t size;
+	struct dma_mapping *next;
+};
+
+/* A list of mappings from CPU addresses to MB SRAM addresses for active
+   DMA blocks (that have been `granted' to the PCI device).  */
+static struct dma_mapping *active_dma_mappings = 0;
+
+/* A list of free mapping objects.  */
+static struct dma_mapping *free_dma_mappings = 0;
+
+/* Spinlock protecting the above globals.  */
+static spinlock_t dma_mappings_lock = SPIN_LOCK_UNLOCKED;
+
+static struct dma_mapping *new_dma_mapping (size_t size)
+{
+	int flags;
+	struct dma_mapping *mapping;
+	void *mb_sram_block = alloc_mb_sram (size);
+
+	if (! mb_sram_block)
+		return 0;
+
+	spin_lock_irqsave (dma_mappings_lock, flags);
+
+	if (! free_dma_mappings) {
+		/* We're out of mapping structures, make more.  */
+		void *mblock;
+		size_t mblock_size = sizeof (struct dma_mapping) * 8;
+
+		/* Don't hold the lock while calling kmalloc (I'm not
+		   sure whether it would be a problem, since we use
+		   GFP_ATOMIC, but it makes me nervous).  */
+		spin_unlock_irqrestore (dma_mappings_lock, flags);
+
+		mblock = kmalloc (mblock_size, GFP_ATOMIC);
+		if (! mblock) {
+			free_mb_sram (mb_sram_block, size);
+			return 0;
+		}
+
+		/* Get the lock back.  */
+		spin_lock_irqsave (dma_mappings_lock, flags);
+
+		/* Add the new mapping structures to the free-list.  */
+		while (mblock_size > 0) {
+			struct dma_mapping *fm = mblock;
+			fm->next = free_dma_mappings;
+			free_dma_mappings = fm;
+			mblock += sizeof *fm;
+			mblock_size -= sizeof *fm;
+		}
+	}
+
+	/* Get a mapping struct from the freelist.  */
+	mapping = free_dma_mappings;
+	free_dma_mappings = mapping->next;
+
+	/* Initialize the mapping.  Other fields should be filled in by
+	   caller.  */
+	mapping->mb_sram_addr = mb_sram_block;
+	mapping->size = size;
+
+	/* Add it to the list of active mappings.  */
+	mapping->next = active_dma_mappings;
+	active_dma_mappings = mapping;
+
+	spin_unlock_irqrestore (dma_mappings_lock, flags);
+
+	return mapping;
+}
+
+static struct dma_mapping *find_dma_mapping (void *mb_sram_addr)
+{
+	int flags;
+	struct dma_mapping *mapping;
+
+	spin_lock_irqsave (dma_mappings_lock, flags);
+
+	for (mapping = active_dma_mappings; mapping; mapping = mapping->next)
+		if (mapping->mb_sram_addr == mb_sram_addr) {
+			spin_unlock_irqrestore (dma_mappings_lock, flags);
+			return mapping;
+		}
+
+	panic ("find_dma_mapping: unmapped PCI DMA addr 0x%x",
+	       MB_SRAM_TO_PCI (mb_sram_addr));
+}
+
+static struct dma_mapping *deactivate_dma_mapping (void *mb_sram_addr)
+{
+	int flags;
+	struct dma_mapping *mapping, *prev;
+
+	spin_lock_irqsave (dma_mappings_lock, flags);
+
+	for (prev = 0, mapping = active_dma_mappings;
+	     mapping;
+	     prev = mapping, mapping = mapping->next)
+	{
+		if (mapping->mb_sram_addr == mb_sram_addr) {
+			/* This is the MAPPING; deactivate it.  */
+			if (prev)
+				prev->next = mapping->next;
+			else
+				active_dma_mappings = mapping->next;
+
+			spin_unlock_irqrestore (dma_mappings_lock, flags);
+
+			return mapping;
+		}
+	}
+
+	panic ("deactivate_dma_mapping: unmapped PCI DMA addr 0x%x",
+	       MB_SRAM_TO_PCI (mb_sram_addr));
+}
+
+/* Return MAPPING to the freelist.  */
+static inline void
+free_dma_mapping (struct dma_mapping *mapping)
+{
+	int flags;
+
+	free_mb_sram (mapping->mb_sram_addr, mapping->size);
+
+	spin_lock_irqsave (dma_mappings_lock, flags);
+
+	mapping->next = free_dma_mappings;
+	free_dma_mappings = mapping;
+
+	spin_unlock_irqrestore (dma_mappings_lock, flags);
+}
+
+
+/* Single PCI DMA mappings.  */
+
+/* `Grant' to PDEV the memory block at CPU_ADDR, for doing DMA.  The
+   32-bit PCI bus mastering address to use is returned.  the device owns
+   this memory until either pci_unmap_single or pci_dma_sync_single is
+   performed.  */
+dma_addr_t
+pci_map_single (struct pci_dev *pdev, void *cpu_addr, size_t size, int dir)
+{
+	struct dma_mapping *mapping = new_dma_mapping (size);
+
+	if (! mapping)
+		return 0;
+
+	mapping->cpu_addr = cpu_addr;
+
+	if (dir == PCI_DMA_BIDIRECTIONAL || dir == PCI_DMA_TODEVICE)
+		memcpy (mapping->mb_sram_addr, cpu_addr, size);
+
+	return MB_SRAM_TO_PCI (mapping->mb_sram_addr);
+}
+
+/* Return to the CPU the PCI DMA memory block previously `granted' to
+   PDEV, at DMA_ADDR.  */
+void pci_unmap_single (struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
+		       int dir)
+{
+	void *mb_sram_addr = PCI_TO_MB_SRAM (dma_addr);
+	struct dma_mapping *mapping = deactivate_dma_mapping (mb_sram_addr);
+
+	if (size != mapping->size)
+		panic ("pci_unmap_single: size (%d) doesn't match"
+		       " size of mapping at PCI DMA addr 0x%x (%d)\n",
+		       size, dma_addr, mapping->size);
+
+	/* Copy back the DMA'd contents if necessary.  */
+	if (dir == PCI_DMA_BIDIRECTIONAL || dir == PCI_DMA_FROMDEVICE)
+		memcpy (mapping->cpu_addr, mb_sram_addr, size);
+
+	/* Return mapping to the freelist.  */
+	free_dma_mapping (mapping);
+}
+
+/* Make physical memory consistant for a single streaming mode DMA
+   translation after a transfer.
+
+   If you perform a pci_map_single() but wish to interrogate the
+   buffer using the cpu, yet do not wish to teardown the PCI dma
+   mapping, you must call this function before doing so.  At the next
+   point you give the PCI dma address back to the card, the device
+   again owns the buffer.  */
+void
+pci_dma_sync_single (struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
+		     int dir)
+{
+	void *mb_sram_addr = PCI_TO_MB_SRAM (dma_addr);
+	struct dma_mapping *mapping = find_dma_mapping (mb_sram_addr);
+
+	/* Synchronize the DMA buffer with the CPU buffer if necessary.  */
+	if (dir == PCI_DMA_FROMDEVICE)
+		memcpy (mapping->cpu_addr, mb_sram_addr, size);
+	else if (dir == PCI_DMA_TODEVICE)
+		memcpy (mb_sram_addr, mapping->cpu_addr, size);
+	else
+		panic("pci_dma_sync_single: unsupported sync dir: %d", dir);
+}
+
+
+/* Scatter-gather PCI DMA mappings.  */
+
+/* Do multiple DMA mappings at once.  */
+int
+pci_map_sg (struct pci_dev *pdev, struct scatterlist *sg, int sg_len, int dir)
+{
+	BUG ();
+	return 0;
+}
+
+/* Unmap multiple DMA mappings at once.  */
+void
+pci_unmap_sg (struct pci_dev *pdev, struct scatterlist *sg, int sg_len,int dir)
+{
+	BUG ();
+}
+
+/* Make physical memory consistant for a set of streaming mode DMA
+   translations after a transfer.  The same as pci_dma_sync_single but
+   for a scatter-gather list, same rules and usage.  */
+
+void
+pci_dma_sync_sg (struct pci_dev *dev, struct scatterlist *sg, int sg_len,
+		 int dir)
+{
+	BUG ();
+}
+
+
+/* PCI mem mapping.  */
+
+/* Allocate and map kernel buffer using consistent mode DMA for PCI
+   device.  Returns non-NULL cpu-view pointer to the buffer if
+   successful and sets *DMA_ADDR to the pci side dma address as well,
+   else DMA_ADDR is undefined.  */
+void *
+pci_alloc_consistent (struct pci_dev *pdev, size_t size, dma_addr_t *dma_addr)
+{
+	void *mb_sram_mem = alloc_mb_sram (size);
+	if (mb_sram_mem)
+		*dma_addr = MB_SRAM_TO_PCI (mb_sram_mem);
+	return mb_sram_mem;
+}
+
+/* Free and unmap a consistent DMA buffer.  CPU_ADDR and DMA_ADDR must
+   be values that were returned from pci_alloc_consistent.  SIZE must be
+   the same as what as passed into pci_alloc_consistent.  References to
+   the memory and mappings assosciated with CPU_ADDR or DMA_ADDR past
+   this call are illegal.  */
+void
+pci_free_consistent (struct pci_dev *pdev, size_t size, void *cpu_addr,
+		     dma_addr_t dma_addr)
+{
+	void *mb_sram_mem = PCI_TO_MB_SRAM (dma_addr);
+	free_mb_sram (mb_sram_mem, size);
+}
+
+
+/* symbol exports (for modules) */
+
+EXPORT_SYMBOL (pci_map_single);
+EXPORT_SYMBOL (pci_unmap_single);
+EXPORT_SYMBOL (pci_alloc_consistent);
+EXPORT_SYMBOL (pci_free_consistent);
+EXPORT_SYMBOL (pci_dma_sync_single);
diff -Nru a/arch/v850/kernel/rte_nb85e_cb.c b/arch/v850/kernel/rte_nb85e_cb.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/rte_nb85e_cb.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,54 @@
+/*
+ * arch/v850/kernel/rte_nb85e_cb.c -- Midas labs RTE-V850E/NB85E-CB board
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+
+#include <asm/atomic.h>
+#include <asm/page.h>
+#include <asm/nb85e.h>
+#include <asm/rte_nb85e_cb.h>
+
+#include "mach.h"
+
+void __init mach_get_physical_ram (unsigned long *ram_start,
+				   unsigned long *ram_len)
+{
+	/* We just use SDRAM here; the kernel itself is in SRAM.  */
+	*ram_start = SDRAM_ADDR;
+	*ram_len = SDRAM_SIZE;
+}
+
+void __init mach_reserve_bootmem ()
+{
+	extern char _root_fs_image_start, _root_fs_image_end;
+	u32 root_fs_image_start = (u32)&_root_fs_image_start;
+	u32 root_fs_image_end = (u32)&_root_fs_image_end;
+
+	/* Reserve the memory used by the root filesystem image if it's
+	   in RAM.  */
+	if (root_fs_image_start >= RAM_START && root_fs_image_start < RAM_END)
+		reserve_bootmem (root_fs_image_start,
+				 root_fs_image_end - root_fs_image_start);
+}
+
+void mach_gettimeofday (struct timespec *tv)
+{
+	tv->tv_sec = 0;
+	tv->tv_nsec = 0;
+}
diff -Nru a/arch/v850/kernel/semaphore.c b/arch/v850/kernel/semaphore.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/semaphore.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,164 @@
+/*
+ * arch/v850/kernel/semaphore.c -- Semaphore support
+ *
+ *  Copyright (C) 1998-2000  IBM Corporation
+ *  Copyright (C) 1999  Linus Torvalds
+ *
+ * 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.
+ *
+ * This file is a copy of the s390 version, arch/s390/kernel/semaphore.c
+ *    Author(s): Martin Schwidefsky
+ * which was derived from the i386 version, linux/arch/i386/kernel/semaphore.c
+ */
+
+#include <linux/sched.h>
+
+#include <asm/semaphore.h>
+
+/*
+ * Semaphores are implemented using a two-way counter:
+ * The "count" variable is decremented for each process
+ * that tries to acquire the semaphore, while the "sleeping"
+ * variable is a count of such acquires.
+ *
+ * Notably, the inline "up()" and "down()" functions can
+ * efficiently test if they need to do any extra work (up
+ * needs to do something only if count was negative before
+ * the increment operation.
+ *
+ * "sleeping" and the contention routine ordering is
+ * protected by the semaphore spinlock.
+ *
+ * Note that these functions are only called when there is
+ * contention on the lock, and as such all this is the
+ * "non-critical" part of the whole semaphore business. The
+ * critical part is the inline stuff in <asm/semaphore.h>
+ * where we want to avoid any extra jumps and calls.
+ */
+
+/*
+ * Logic:
+ *  - only on a boundary condition do we need to care. When we go
+ *    from a negative count to a non-negative, we wake people up.
+ *  - when we go from a non-negative count to a negative do we
+ *    (a) synchronize with the "sleeper" count and (b) make sure
+ *    that we're on the wakeup list before we synchronize so that
+ *    we cannot lose wakeup events.
+ */
+
+void __up(struct semaphore *sem)
+{
+	wake_up(&sem->wait);
+}
+
+static spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED;
+
+void __down(struct semaphore * sem)
+{
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+	tsk->state = TASK_UNINTERRUPTIBLE;
+	add_wait_queue_exclusive(&sem->wait, &wait);
+
+	spin_lock_irq(&semaphore_lock);
+	sem->sleepers++;
+	for (;;) {
+		int sleepers = sem->sleepers;
+
+		/*
+		 * Add "everybody else" into it. They aren't
+		 * playing, because we own the spinlock.
+		 */
+		if (!atomic_add_negative(sleepers - 1, &sem->count)) {
+			sem->sleepers = 0;
+			break;
+		}
+		sem->sleepers = 1;	/* us - see -1 above */
+		spin_unlock_irq(&semaphore_lock);
+
+		schedule();
+		tsk->state = TASK_UNINTERRUPTIBLE;
+		spin_lock_irq(&semaphore_lock);
+	}
+	spin_unlock_irq(&semaphore_lock);
+	remove_wait_queue(&sem->wait, &wait);
+	tsk->state = TASK_RUNNING;
+	wake_up(&sem->wait);
+}
+
+int __down_interruptible(struct semaphore * sem)
+{
+	int retval = 0;
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+	tsk->state = TASK_INTERRUPTIBLE;
+	add_wait_queue_exclusive(&sem->wait, &wait);
+
+	spin_lock_irq(&semaphore_lock);
+	sem->sleepers ++;
+	for (;;) {
+		int sleepers = sem->sleepers;
+
+		/*
+		 * With signals pending, this turns into
+		 * the trylock failure case - we won't be
+		 * sleeping, and we* can't get the lock as
+		 * it has contention. Just correct the count
+		 * and exit.
+		 */
+		if (signal_pending(current)) {
+			retval = -EINTR;
+			sem->sleepers = 0;
+			atomic_add(sleepers, &sem->count);
+			break;
+		}
+
+		/*
+		 * Add "everybody else" into it. They aren't
+		 * playing, because we own the spinlock. The
+		 * "-1" is because we're still hoping to get
+		 * the lock.
+		 */
+		if (!atomic_add_negative(sleepers - 1, &sem->count)) {
+			sem->sleepers = 0;
+			break;
+		}
+		sem->sleepers = 1;	/* us - see -1 above */
+		spin_unlock_irq(&semaphore_lock);
+
+		schedule();
+		tsk->state = TASK_INTERRUPTIBLE;
+		spin_lock_irq(&semaphore_lock);
+	}
+	spin_unlock_irq(&semaphore_lock);
+	tsk->state = TASK_RUNNING;
+	remove_wait_queue(&sem->wait, &wait);
+	wake_up(&sem->wait);
+	return retval;
+}
+
+/*
+ * Trylock failed - make sure we correct for
+ * having decremented the count.
+ */
+int __down_trylock(struct semaphore * sem)
+{
+        unsigned long flags;
+	int sleepers;
+
+	spin_lock_irqsave(&semaphore_lock, flags);
+	sleepers = sem->sleepers + 1;
+	sem->sleepers = 0;
+
+	/*
+	 * Add "everybody else" and us into it. They aren't
+	 * playing, because we own the spinlock.
+	 */
+	if (!atomic_add_negative(sleepers, &sem->count))
+		wake_up(&sem->wait);
+
+	spin_unlock_irqrestore(&semaphore_lock, flags);
+	return 1;
+}
diff -Nru a/arch/v850/kernel/setup.c b/arch/v850/kernel/setup.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/setup.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,273 @@
+/*
+ * arch/v850/kernel/setup.c -- Arch-dependent initialization functions
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+#include <linux/reboot.h>
+#include <linux/personality.h>
+#include <linux/major.h>
+#include <linux/root_dev.h>
+#include <linux/mtd/mtd.h>
+
+#include <asm/irq.h>
+
+#include "mach.h"
+
+/* These symbols are all defined in the linker map to delineate various
+   statically allocated regions of memory.  */
+
+extern char _intv_start, _intv_end;
+/* `kram' is only used if the kernel uses part of normal user RAM.  */
+extern char _kram_start __attribute__ ((__weak__));
+extern char _kram_end __attribute__ ((__weak__));
+extern char _init_start, _init_end;
+extern char _bootmap;
+extern char _stext, _etext, _sdata, _edata, _sbss, _ebss;
+/* Many platforms use an embedded root image.  */
+extern char _root_fs_image_start __attribute__ ((__weak__));
+extern char _root_fs_image_end __attribute__ ((__weak__));
+
+
+char command_line[512];
+char saved_command_line[512];
+
+/* Memory not used by the kernel.  */
+static unsigned long total_ram_pages;
+
+/* System RAM.  */
+static unsigned long ram_start = 0, ram_len = 0;
+
+
+#define ADDR_TO_PAGE_UP(x)   ((((unsigned long)x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define ADDR_TO_PAGE(x)	     (((unsigned long)x) >> PAGE_SHIFT)
+#define PAGE_TO_ADDR(x)	     (((unsigned long)x) << PAGE_SHIFT)
+
+static void init_mem_alloc (unsigned long ram_start, unsigned long ram_len);
+
+void set_mem_root (void *addr, size_t len, char *cmd_line);
+
+
+void __init setup_arch (char **cmdline)
+{
+	/* Keep a copy of command line */
+	*cmdline = command_line;
+	memcpy (saved_command_line, command_line, sizeof saved_command_line);
+	saved_command_line[sizeof saved_command_line - 1] = '\0';
+
+	console_verbose ();
+
+	init_mm.start_code = (unsigned long) &_stext;
+	init_mm.end_code = (unsigned long) &_etext;
+	init_mm.end_data = (unsigned long) &_edata;
+	init_mm.brk = (unsigned long) &_kram_end;
+
+	/* Find out what mem this machine has.  */
+	mach_get_physical_ram (&ram_start, &ram_len);
+	/* ... and tell the kernel about it.  */
+	init_mem_alloc (ram_start, ram_len);
+
+	/* do machine-specific setups.  */
+	mach_setup (cmdline);
+
+#ifdef CONFIG_MTD
+	if (!ROOT_DEV && &_root_fs_image_end > &_root_fs_image_start)
+		set_mem_root (&_root_fs_image_start,
+			      &_root_fs_image_end - &_root_fs_image_start,
+			      *cmdline);
+#endif
+}
+
+void __init trap_init (void)
+{
+}
+
+#ifdef CONFIG_MTD
+/* Set the root filesystem to be the given memory region.
+   Some parameter may be appended to CMD_LINE.  */
+void set_mem_root (void *addr, size_t len, char *cmd_line)
+{
+	/* The only way to pass info to the MTD slram driver is via
+	   the command line.  */
+	if (*cmd_line) {
+		cmd_line += strlen (cmd_line);
+		*cmd_line++ = ' ';
+	}
+	sprintf (cmd_line, "slram=root,0x%x,+0x%x", (u32)addr, (u32)len);
+
+	ROOT_DEV = MKDEV (MTD_BLOCK_MAJOR, 0);
+}
+#endif
+
+
+static void irq_nop (unsigned irq) { }
+static unsigned irq_zero (unsigned irq) { return 0; }
+
+static void nmi_end (unsigned irq)
+{
+	if (irq != IRQ_NMI (0)) {
+		printk (KERN_CRIT "NMI %d is unrecoverable; restarting...",
+			irq - IRQ_NMI (0));
+		machine_restart (0);
+	}
+}
+
+static struct hw_interrupt_type nmi_irq_type = {
+	"NMI",
+	irq_zero,		/* startup */
+	irq_nop,		/* shutdown */
+	irq_nop,		/* enable */
+	irq_nop,		/* disable */
+	irq_nop,		/* ack */
+	nmi_end,		/* end */
+};
+
+void __init init_IRQ (void)
+{
+	init_irq_handlers (0, NUM_MACH_IRQS, 1, 0);
+	init_irq_handlers (IRQ_NMI (0), NUM_NMIS, 1, &nmi_irq_type);
+	mach_init_irqs ();
+}
+
+
+void __init mem_init (void)
+{
+	max_mapnr = MAP_NR (ram_start + ram_len);
+
+	num_physpages = ADDR_TO_PAGE (ram_len);
+
+	total_ram_pages = free_all_bootmem ();
+
+	printk (KERN_INFO
+		"Memory: %luK/%luK available"
+		" (%luK kernel code, %luK data)\n",
+		PAGE_TO_ADDR (nr_free_pages()) / 1024,
+		ram_len / 1024,
+		((unsigned long)&_etext - (unsigned long)&_stext) / 1024,
+		((unsigned long)&_ebss - (unsigned long)&_sdata) / 1024);
+}
+
+void free_initmem (void)
+{
+	unsigned long ram_end = ram_start + ram_len;
+	unsigned long start = PAGE_ALIGN ((unsigned long)(&_init_start));
+
+	if (start >= ram_start && start < ram_end) {
+		unsigned long addr;
+		unsigned long end = PAGE_ALIGN ((unsigned long)(&_init_end));
+
+		if (end > ram_end)
+			end = ram_end;
+
+		printk("Freeing unused kernel memory: %ldK freed\n",
+		       (end - start) / 1024);
+
+		for (addr = start; addr < end; addr += PAGE_SIZE) {
+			struct page *page = virt_to_page (addr);
+			ClearPageReserved (page);
+			set_page_count (page, 1);
+			__free_page (page);
+			total_ram_pages++;
+		}
+	}
+}
+
+
+/* Initialize the `bootmem allocator'.  RAM_START and RAM_LEN identify
+   what RAM may be used.  */
+static void __init
+init_bootmem_alloc (unsigned long ram_start, unsigned long ram_len)
+{
+	/* The part of the kernel that's in the same managed RAM space
+	   used for general allocation.  */
+	unsigned long kram_start = (unsigned long)&_kram_start;
+	unsigned long kram_end = (unsigned long)&_kram_end;
+	/* End of the managed RAM space.  */
+	unsigned long ram_end = ram_start + ram_len;
+	/* Address range of the interrupt vector table.  */
+	unsigned long intv_start = (unsigned long)&_intv_start;
+	unsigned long intv_end = (unsigned long)&_intv_end;
+	/* True if the interrupt vectors are in the managed RAM area.  */
+	int intv_in_ram = (intv_end > ram_start && intv_start < ram_end);
+	/* True if the interrupt vectors are inside the kernel's RAM.  */
+	int intv_in_kram = (intv_end > kram_start && intv_start < kram_end);
+	/* A pointer to an optional function that reserves platform-specific
+	   memory regions.  We declare the pointer `volatile' to avoid gcc
+	   turning the call into a static call (the problem is that since
+	   it's a weak symbol, a static call may end up trying to reference
+	   the location 0x0, which is not always reachable).  */
+	void (*volatile mrb) (void) = mach_reserve_bootmem;
+	/* The bootmem allocator's allocation bitmap.  */
+	unsigned long bootmap = (unsigned long)&_bootmap;
+	unsigned long bootmap_len;
+
+	/* Round bootmap location up to next page.  */
+	bootmap = PAGE_TO_ADDR (ADDR_TO_PAGE_UP (bootmap));
+
+	/* Initialize bootmem allocator.  */
+	bootmap_len = init_bootmem_node (NODE_DATA (0),
+					 ADDR_TO_PAGE (bootmap),
+					 ADDR_TO_PAGE (PAGE_OFFSET),
+					 ADDR_TO_PAGE (ram_end));
+
+	/* Now make the RAM actually allocatable (it starts out `reserved'). */
+	free_bootmem (ram_start, ram_len);
+
+	if (kram_end > kram_start)
+		/* Reserve the RAM part of the kernel's address space, so it
+		   doesn't get allocated.  */
+		reserve_bootmem (kram_start, kram_end - kram_start);
+	
+	if (intv_in_ram && !intv_in_kram)
+		/* Reserve the interrupt vector space.  */
+		reserve_bootmem (intv_start, intv_end - intv_start);
+
+	if (bootmap >= ram_start && bootmap < ram_end)
+		/* Reserve the bootmap space.  */
+		reserve_bootmem (bootmap, bootmap_len);
+
+	/* Reserve the memory used by the root filesystem image if it's
+	   in RAM.  */
+	if (&_root_fs_image_end > &_root_fs_image_start
+	    && (unsigned long)&_root_fs_image_start >= ram_start
+	    && (unsigned long)&_root_fs_image_start < ram_end)
+		reserve_bootmem ((unsigned long)&_root_fs_image_start,
+				 &_root_fs_image_end - &_root_fs_image_start);
+
+	/* Let the platform-dependent code reserve some too.  */
+	if (mrb)
+		(*mrb) ();
+}
+
+/* Tell the kernel about what RAM it may use for memory allocation.  */
+static void __init
+init_mem_alloc (unsigned long ram_start, unsigned long ram_len)
+{
+	unsigned i;
+	unsigned long zones_size[MAX_NR_ZONES];
+
+	init_bootmem_alloc (ram_start, ram_len);
+
+	for (i = 0; i < MAX_NR_ZONES; i++)
+		zones_size[i] = 0;
+
+	/* We stuff all the memory into one area, which includes the
+	   initial gap from PAGE_OFFSET to ram_start.  */
+	zones_size[ZONE_DMA]
+		= ADDR_TO_PAGE (ram_len + (ram_start - PAGE_OFFSET));
+
+	free_area_init_node (0, NODE_DATA(0), 0, zones_size,
+			     ADDR_TO_PAGE (PAGE_OFFSET), 0);
+	mem_map = NODE_DATA(0)->node_mem_map;
+}
diff -Nru a/arch/v850/kernel/signal.c b/arch/v850/kernel/signal.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/signal.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,523 @@
+/*
+ * arch/v850/kernel/signal.c -- Signal handling
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 1999,2000,2002  Niibe Yutaka & Kaz Kojima
+ *  Copyright (C) 1991,1992  Linus Torvalds
+ *
+ * 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.
+ *
+ * 1997-11-28  Modified for POSIX.1b signals by Richard Henderson
+ *
+ * This file was derived from the sh version, arch/sh/kernel/signal.c
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/personality.h>
+#include <linux/tty.h>
+
+#include <asm/ucontext.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/thread_info.h>
+#include <asm/cacheflush.h>
+
+#define DEBUG_SIG 0
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+asmlinkage int
+sys_sigsuspend(old_sigset_t mask, struct pt_regs *regs)
+{
+	sigset_t saveset;
+
+	mask &= _BLOCKABLE;
+	spin_lock_irq(&current->sig->siglock);
+	saveset = current->blocked;
+	siginitset(&current->blocked, mask);
+	recalc_sigpending();
+	spin_unlock_irq(&current->sig->siglock);
+
+	regs->gpr[GPR_RVAL] = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(regs, &saveset))
+			return -EINTR;
+	}
+}
+
+asmlinkage int
+sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize,
+		  struct pt_regs *regs)
+{
+	sigset_t saveset, newset;
+
+	/* XXX: Don't preclude handling different sized sigset_t's.  */
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	if (copy_from_user(&newset, unewset, sizeof(newset)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+	spin_lock_irq(&current->sig->siglock);
+	saveset = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sig->siglock);
+
+	regs->gpr[GPR_RVAL] = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(regs, &saveset))
+			return -EINTR;
+	}
+}
+
+asmlinkage int 
+sys_sigaction(int sig, const struct old_sigaction *act,
+	      struct old_sigaction *oact)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+
+	if (act) {
+		old_sigset_t mask;
+		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+			return -EFAULT;
+		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		__get_user(mask, &act->sa_mask);
+		siginitset(&new_ka.sa.sa_mask, mask);
+	}
+
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+	if (!ret && oact) {
+		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+			return -EFAULT;
+		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+	}
+
+	return ret;
+}
+
+asmlinkage int
+sys_sigaltstack(const stack_t *uss, stack_t *uoss,
+		struct pt_regs *regs)
+{
+	return do_sigaltstack(uss, uoss, regs->gpr[GPR_SP]);
+}
+
+
+/*
+ * Do a signal return; undo the signal stack.
+ */
+
+struct sigframe
+{
+	struct sigcontext sc;
+	unsigned long extramask[_NSIG_WORDS-1];
+	unsigned long tramp[2];	/* signal trampoline */
+};
+
+struct rt_sigframe
+{
+	struct siginfo *pinfo;
+	void *puc;
+	struct siginfo info;
+	struct ucontext uc;
+	unsigned long tramp[2];	/* signal trampoline */
+};
+
+static int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, int *rval_p)
+{
+	unsigned int err = 0;
+
+#define COPY(x)		err |= __get_user(regs->x, &sc->regs.x)
+	COPY(gpr[0]);	COPY(gpr[1]);	COPY(gpr[2]);	COPY(gpr[3]);
+	COPY(gpr[4]);	COPY(gpr[5]);	COPY(gpr[6]);	COPY(gpr[7]);
+	COPY(gpr[8]);	COPY(gpr[9]);	COPY(gpr[10]);	COPY(gpr[11]);
+	COPY(gpr[12]);	COPY(gpr[13]);	COPY(gpr[14]);	COPY(gpr[15]);
+	COPY(gpr[16]);	COPY(gpr[17]);	COPY(gpr[18]);	COPY(gpr[19]);
+	COPY(gpr[20]);	COPY(gpr[21]);	COPY(gpr[22]);	COPY(gpr[23]);
+	COPY(gpr[24]);	COPY(gpr[25]);	COPY(gpr[26]);	COPY(gpr[27]);
+	COPY(gpr[28]);	COPY(gpr[29]);	COPY(gpr[30]);	COPY(gpr[31]);
+	COPY(pc);	COPY(psw);
+	COPY(ctpc);	COPY(ctpsw);	COPY(ctbp);
+#undef COPY
+
+	return err;
+}
+
+asmlinkage int sys_sigreturn(struct pt_regs *regs)
+{
+	struct sigframe *frame = (struct sigframe *)regs->gpr[GPR_SP];
+	sigset_t set;
+	int rval;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+
+	if (__get_user(set.sig[0], &frame->sc.oldmask)
+	    || (_NSIG_WORDS > 1
+		&& __copy_from_user(&set.sig[1], &frame->extramask,
+				    sizeof(frame->extramask))))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sig->siglock);
+	current->blocked = set;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sig->siglock);
+
+	if (restore_sigcontext(regs, &frame->sc, &rval))
+		goto badframe;
+	return rval;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
+{
+	struct rt_sigframe *frame = (struct rt_sigframe *)regs->gpr[GPR_SP];
+	sigset_t set;
+	stack_t st;
+	int rval;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+
+	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sig->siglock);
+	current->blocked = set;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sig->siglock);
+
+	if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &rval))
+		goto badframe;
+
+	if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
+		goto badframe;
+	/* It is more difficult to avoid calling this function than to
+	   call it and ignore errors.  */
+	do_sigaltstack(&st, NULL, regs->gpr[GPR_SP]);
+
+	return rval;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}	
+
+/*
+ * Set up a signal frame.
+ */
+
+static int
+setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
+		 unsigned long mask)
+{
+	int err = 0;
+
+#define COPY(x)		err |= __put_user(regs->x, &sc->regs.x)
+	COPY(gpr[0]);	COPY(gpr[1]);	COPY(gpr[2]);	COPY(gpr[3]);
+	COPY(gpr[4]);	COPY(gpr[5]);	COPY(gpr[6]);	COPY(gpr[7]);
+	COPY(gpr[8]);	COPY(gpr[9]);	COPY(gpr[10]);	COPY(gpr[11]);
+	COPY(gpr[12]);	COPY(gpr[13]);	COPY(gpr[14]);	COPY(gpr[15]);
+	COPY(gpr[16]);	COPY(gpr[17]);	COPY(gpr[18]);	COPY(gpr[19]);
+	COPY(gpr[20]);	COPY(gpr[21]);	COPY(gpr[22]);	COPY(gpr[23]);
+	COPY(gpr[24]);	COPY(gpr[25]);	COPY(gpr[26]);	COPY(gpr[27]);
+	COPY(gpr[28]);	COPY(gpr[29]);	COPY(gpr[30]);	COPY(gpr[31]);
+	COPY(pc);	COPY(psw);
+	COPY(ctpc);	COPY(ctpsw);	COPY(ctbp);
+#undef COPY
+
+	err |= __put_user(mask, &sc->oldmask);
+
+	return err;
+}
+
+/*
+ * Determine which stack to use..
+ */
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+	/* Default to using normal stack */
+	unsigned long sp = regs->gpr[GPR_SP];
+
+	if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp))
+		sp = current->sas_ss_sp + current->sas_ss_size;
+
+	return (void *)((sp - frame_size) & -8UL);
+}
+
+static void setup_frame(int sig, struct k_sigaction *ka,
+			sigset_t *set, struct pt_regs *regs)
+{
+	struct sigframe *frame;
+	int err = 0;
+	int signal;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto give_sigsegv;
+
+	signal = current_thread_info()->exec_domain
+		&& current_thread_info()->exec_domain->signal_invmap
+		&& sig < 32
+		? current_thread_info()->exec_domain->signal_invmap[sig]
+		: sig;
+
+	err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
+
+	if (_NSIG_WORDS > 1) {
+		err |= __copy_to_user(frame->extramask, &set->sig[1],
+				      sizeof(frame->extramask));
+	}
+
+	/* Set up to return from userspace.  If provided, use a stub
+	   already in userspace.  */
+	if (ka->sa.sa_flags & SA_RESTORER) {
+		regs->gpr[GPR_LP] = (unsigned long) ka->sa.sa_restorer;
+	} else {
+		/* Note, these encodings are _little endian_!  */
+
+		/* addi  __NR_sigreturn, r0, r12  */
+		err |= __put_user(0x6600 | (__NR_sigreturn << 16),
+				  frame->tramp + 0);
+		/* trap 0 */
+		err |= __put_user(0x010007e0,
+				  frame->tramp + 1);
+
+		regs->gpr[GPR_LP] = (unsigned long)frame->tramp;
+
+		flush_cache_sigtramp (regs->gpr[GPR_LP]);
+	}
+
+	if (err)
+		goto give_sigsegv;
+
+	/* Set up registers for signal handler */
+	regs->gpr[GPR_SP] = (unsigned long) frame;
+	regs->gpr[GPR_ARG0] = signal; /* Arg for signal handler */
+	regs->pc = (unsigned long) ka->sa.sa_handler;
+
+	set_fs(USER_DS);
+
+#if DEBUG_SIG
+	printk("SIG deliver (%s:%d): sp=%p pc=%08lx ra=%08lx\n",
+		current->comm, current->pid, frame, regs->pc, );
+#endif
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+			   sigset_t *set, struct pt_regs *regs)
+{
+	struct rt_sigframe *frame;
+	int err = 0;
+	int signal;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto give_sigsegv;
+
+	signal = current_thread_info()->exec_domain
+		&& current_thread_info()->exec_domain->signal_invmap
+		&& sig < 32
+		? current_thread_info()->exec_domain->signal_invmap[sig]
+		: sig;
+
+	err |= __put_user(&frame->info, &frame->pinfo);
+	err |= __put_user(&frame->uc, &frame->puc);
+	err |= copy_siginfo_to_user(&frame->info, info);
+
+	/* Create the ucontext.  */
+	err |= __put_user(0, &frame->uc.uc_flags);
+	err |= __put_user(0, &frame->uc.uc_link);
+	err |= __put_user((void *)current->sas_ss_sp,
+			  &frame->uc.uc_stack.ss_sp);
+	err |= __put_user(sas_ss_flags(regs->gpr[GPR_SP]),
+			  &frame->uc.uc_stack.ss_flags);
+	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+	err |= setup_sigcontext(&frame->uc.uc_mcontext,
+			        regs, set->sig[0]);
+	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+
+	/* Set up to return from userspace.  If provided, use a stub
+	   already in userspace.  */
+	if (ka->sa.sa_flags & SA_RESTORER) {
+		regs->gpr[GPR_LP] = (unsigned long) ka->sa.sa_restorer;
+	} else {
+		/* Note, these encodings are _little endian_!  */
+
+		/* addi  __NR_sigreturn, r0, r12  */
+		err |= __put_user(0x6600 | (__NR_sigreturn << 16),
+				  frame->tramp + 0);
+		/* trap 0 */
+		err |= __put_user(0x010007e0,
+				  frame->tramp + 1);
+
+		regs->gpr[GPR_LP] = (unsigned long)frame->tramp;
+
+		flush_cache_sigtramp (regs->gpr[GPR_LP]);
+	}
+
+	if (err)
+		goto give_sigsegv;
+
+	/* Set up registers for signal handler */
+	regs->gpr[GPR_SP] = (unsigned long) frame;
+	regs->gpr[GPR_ARG0] = signal; /* Arg for signal handler */
+	regs->pc = (unsigned long) ka->sa.sa_handler;
+
+	set_fs(USER_DS);
+
+#if DEBUG_SIG
+	printk("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
+		current->comm, current->pid, frame, regs->pc, regs->pr);
+#endif
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+/*
+ * OK, we're invoking a handler
+ */	
+
+static void
+handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
+	struct pt_regs * regs)
+{
+	struct k_sigaction *ka = &current->sig->action[sig-1];
+
+	/* Are we from a system call? */
+	if (PT_REGS_SYSCALL (regs)) {
+		/* If so, check system call restarting.. */
+		switch (regs->gpr[GPR_RVAL]) {
+			case -ERESTARTNOHAND:
+				regs->gpr[GPR_RVAL] = -EINTR;
+				break;
+
+			case -ERESTARTSYS:
+				if (!(ka->sa.sa_flags & SA_RESTART)) {
+					regs->gpr[GPR_RVAL] = -EINTR;
+					break;
+				}
+			/* fallthrough */
+			case -ERESTARTNOINTR:
+				regs->gpr[12] = PT_REGS_SYSCALL (regs);
+				regs->pc -= 4; /* Size of `trap 0' insn.  */
+		}
+
+		PT_REGS_SET_SYSCALL (regs, 0);
+	}
+
+	/* Set up the stack frame */
+	if (ka->sa.sa_flags & SA_SIGINFO)
+		setup_rt_frame(sig, ka, info, oldset, regs);
+	else
+		setup_frame(sig, ka, oldset, regs);
+
+	if (ka->sa.sa_flags & SA_ONESHOT)
+		ka->sa.sa_handler = SIG_DFL;
+
+	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+		spin_lock_irq(&current->sig->siglock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		sigaddset(&current->blocked,sig);
+		recalc_sigpending();
+		spin_unlock_irq(&current->sig->siglock);
+	}
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ *
+ * Note that we go through the signals twice: once to check the signals that
+ * the kernel can handle, and then we build all the user-level signal handling
+ * stack-frames in one go after that.
+ */
+int do_signal(struct pt_regs *regs, sigset_t *oldset)
+{
+	siginfo_t info;
+	int signr;
+
+	/*
+	 * We want the common case to go fast, which
+	 * is why we may in certain cases get here from
+	 * kernel mode. Just return without doing anything
+	 * if so.
+	 */
+	if (!user_mode(regs))
+		return 1;
+
+	if (!oldset)
+		oldset = &current->blocked;
+
+	signr = get_signal_to_deliver(&info, regs);
+	if (signr > 0) {
+		/* Whee!  Actually deliver the signal.  */
+		handle_signal(signr, &info, oldset, regs);
+		return 1;
+	}
+
+	/* Did we come from a system call? */
+	if (PT_REGS_SYSCALL (regs)) {
+		/* Restart the system call - no handlers present */
+		if (regs->gpr[GPR_RVAL] == -ERESTARTNOHAND ||
+		    regs->gpr[GPR_RVAL] == -ERESTARTSYS ||
+		    regs->gpr[GPR_RVAL] == -ERESTARTNOINTR) {
+			regs->gpr[12] = PT_REGS_SYSCALL (regs);
+			regs->pc -= 4; /* Size of `trap 0' insn.  */
+		}
+	}
+	return 0;
+}
diff -Nru a/arch/v850/kernel/sim.c b/arch/v850/kernel/sim.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/sim.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,174 @@
+/*
+ * arch/v850/kernel/sim.c -- Machine-specific stuff for GDB v850e simulator
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+
+#include <asm/atomic.h>
+#include <asm/page.h>
+#include <asm/machdep.h>
+#include <asm/simsyscall.h>
+
+#include "mach.h"
+
+/* The name of a file containing the root filesystem.  */
+#define ROOT_FS "rootfs.image"
+
+extern void simcons_setup (void);
+extern void simcons_poll_ttys (void);
+extern void set_mem_root (void *addr, size_t len, char *cmd_line);
+
+static int read_file (const char *name,
+		      unsigned long *addr, unsigned long *len,
+		      const char **err);
+
+void __init mach_setup (char **cmdline)
+{
+	const char *err;
+	unsigned long root_dev_addr, root_dev_len;
+
+	printk (KERN_INFO "CPU: NEC V850E (GDB simulator)\n");
+
+	simcons_setup ();
+
+	printk (KERN_INFO "Reading root filesystem: %s", ROOT_FS);
+
+	if (read_file (ROOT_FS, &root_dev_addr, &root_dev_len, &err)) {
+		printk (" (size %luK)\n", root_dev_len / 1024);
+		set_mem_root ((void *)root_dev_addr, (size_t)root_dev_len,
+			      *cmdline);
+	} else
+		printk ("...%s failed!\n", err);
+}
+
+void mach_get_physical_ram (unsigned long *ram_start, unsigned long *ram_len)
+{
+	*ram_start = RAM_ADDR;
+	*ram_len = RAM_SIZE;
+}
+
+void __init mach_sched_init (struct irqaction *timer_action)
+{
+	/* ...do magic timer initialization?...  */
+	mach_tick = simcons_poll_ttys;
+	setup_irq (0, timer_action);
+}
+
+
+static void irq_nop (unsigned irq) { }
+static unsigned irq_zero (unsigned irq) { return 0; }
+
+static struct hw_interrupt_type sim_irq_type = {
+	"IRQ",
+	irq_zero,		/* startup */
+	irq_nop,		/* shutdown */
+	irq_nop,		/* enable */
+	irq_nop,		/* disable */
+	irq_nop,		/* ack */
+	irq_nop,		/* end */
+};
+
+void __init mach_init_irqs (void)
+{
+	init_irq_handlers (0, NUM_MACH_IRQS, 1, &sim_irq_type);
+}
+
+
+void mach_gettimeofday (struct timespec *tv)
+{
+	long timeval[2], timezone[2];
+	int rval = V850_SIM_SYSCALL (gettimeofday, timeval, timezone);
+	if (rval == 0) {
+		tv->tv_sec = timeval[0];
+		tv->tv_nsec = timeval[1] * 1000;
+	}
+}
+
+void machine_restart (char *__unused)
+{
+	V850_SIM_SYSCALL (write, 1, "RESTART\n", 8);
+	V850_SIM_SYSCALL (exit, 0);
+}
+
+void machine_halt (void)
+{
+	V850_SIM_SYSCALL (write, 1, "HALT\n", 5);
+	V850_SIM_SYSCALL (exit, 0);
+}
+
+void machine_power_off (void)
+{
+	V850_SIM_SYSCALL (write, 1, "POWER OFF\n", 10);
+	V850_SIM_SYSCALL (exit, 0);
+}
+
+
+/* Load data from a file called NAME into ram.  The address and length
+   of the data image are returned in ADDR and LEN.  */
+static int __init
+read_file (const char *name,
+	   unsigned long *addr, unsigned long *len,
+	   const char **err)
+{
+	int rval, fd;
+	unsigned long cur, left;
+	/* Note this is not a normal stat buffer, it's an ad-hoc
+	   structure defined by the simulator.  */
+	unsigned long stat_buf[10];
+
+	/* Stat the file to find out the length.  */
+	rval = V850_SIM_SYSCALL (stat, name, stat_buf);
+	if (rval < 0) {
+		if (err) *err = "stat";
+		return 0;
+	}
+	*len = stat_buf[4];
+
+	/* Open the file; `0' is O_RDONLY.  */
+	fd = V850_SIM_SYSCALL (open, name, 0);
+	if (fd < 0) {
+		if (err) *err = "open";
+		return 0;
+	}
+
+	*addr = (unsigned long)alloc_bootmem(*len);
+	if (! *addr) {
+		V850_SIM_SYSCALL (close, fd);
+		if (err) *err = "alloc_bootmem";
+		return 0;
+	}
+
+	cur = *addr;
+	left = *len;
+	while (left > 0) {
+		int chunk = V850_SIM_SYSCALL (read, fd, cur, left);
+		if (chunk <= 0)
+			break;
+		cur += chunk;
+		left -= chunk;
+	}
+	V850_SIM_SYSCALL (close, fd);
+	if (left > 0) {
+		/* Some read failed.  */
+		free_bootmem (*addr, *len);
+		if (err) *err = "read";
+		return 0;
+	}
+
+	return 1;
+}
diff -Nru a/arch/v850/kernel/sim85e2c.c b/arch/v850/kernel/sim85e2c.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/sim85e2c.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,147 @@
+/*
+ * arch/v850/kernel/sim85e2c.c -- Machine-specific stuff for
+ *	V850E2 RTL simulator
+ *
+ *  Copyright (C) 2002  NEC Corporation
+ *  Copyright (C) 2002  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+
+#include <asm/atomic.h>
+#include <asm/page.h>
+#include <asm/machdep.h>
+
+#include "mach.h"
+
+extern void memcons_setup (void);
+
+
+void __init mach_early_init (void)
+{
+	extern int panic_timeout;
+
+	/* Don't stop the simulator at `halt' instructions.  */
+	NOTHAL = 1;
+
+	/* The sim85e2c simulator tracks `undefined' values, so to make
+	   debugging easier, we begin by zeroing out all otherwise
+	   undefined registers.  This is not strictly necessary.
+
+	   The registers we zero are:
+	       Every GPR except:
+	           stack-pointer (r3)
+		   task-pointer (r16)
+		   our return addr (r31)
+	       Every system register (SPR) that we know about except for
+	       the PSW (SPR 5), which we zero except for the
+	       disable-interrupts bit.
+	*/
+
+	/* GPRs */
+	asm volatile ("             mov r0, r1 ; mov r0, r2              ");
+	asm volatile ("mov r0, r4 ; mov r0, r5 ; mov r0, r6 ; mov r0, r7 ");
+	asm volatile ("mov r0, r8 ; mov r0, r9 ; mov r0, r10; mov r0, r11");
+	asm volatile ("mov r0, r12; mov r0, r13; mov r0, r14; mov r0, r15");
+	asm volatile ("             mov r0, r17; mov r0, r18; mov r0, r19");
+	asm volatile ("mov r0, r20; mov r0, r21; mov r0, r22; mov r0, r23");
+	asm volatile ("mov r0, r24; mov r0, r25; mov r0, r26; mov r0, r27");
+	asm volatile ("mov r0, r28; mov r0, r29; mov r0, r30");
+
+	/* SPRs */
+	asm volatile ("ldsr r0, 0;  ldsr r0, 1;  ldsr r0, 2;  ldsr r0, 3");
+	asm volatile ("ldsr r0, 4");
+	asm volatile ("addi 0x20, r0, r1; ldsr r1, 5"); /* PSW */
+	asm volatile ("ldsr r0, 16; ldsr r0, 17; ldsr r0, 18; ldsr r0, 19");
+	asm volatile ("ldsr r0, 20");
+
+	/* Turn on the caches.  */
+	NA85E2C_CACHE_BTSC
+		|= (NA85E2C_CACHE_BTSC_ICM | NA85E2C_CACHE_BTSC_DCM0);
+	NA85E2C_BUSM_BHC = 0xFFFF;
+
+	/* Ensure that the simulator halts on a panic, instead of going
+	   into an infinite loop inside the panic function.  */
+	panic_timeout = -1;
+}
+
+void __init mach_setup (char **cmdline)
+{
+	printk (KERN_INFO "CPU: NEC V850E2 (sim85e2c simulator)\n");
+
+	memcons_setup ();
+}
+
+void mach_get_physical_ram (unsigned long *ram_start, unsigned long *ram_len)
+{
+	/* There are 3 possible areas we can use:
+	     IRAM (1MB) is fast for instruction fetches, but slow for data
+	     DRAM (1020KB) is fast for data, but slow for instructions
+	     ERAM is cached, so should be fast for both insns and data,
+	          _but_ currently only supports write-through caching, so
+		  writes are slow.
+	   Since there's really no area that's good for general kernel
+	   use, we use DRAM -- it won't be good for user programs
+	   (which will be loaded into kernel allocated memory), but
+	   currently we're more concerned with testing the kernel.  */
+	*ram_start = DRAM_ADDR;
+	*ram_len = R0_RAM_ADDR - DRAM_ADDR;
+}
+
+void __init mach_sched_init (struct irqaction *timer_action)
+{
+	/* The simulator actually cycles through all interrupts
+	   periodically.  We just pay attention to IRQ0, which gives us
+	   1/64 the rate of the periodic interrupts.  */
+	setup_irq (0, timer_action);
+}
+
+void mach_gettimeofday (struct timespec *tv)
+{
+	tv->tv_sec = 0;
+	tv->tv_nsec = 0;
+}
+
+/* Interrupts */
+
+struct nb85e_intc_irq_init irq_inits[] = {
+	{ "IRQ", 0, NUM_MACH_IRQS, 1, 7 },
+	{ 0 }
+};
+struct hw_interrupt_type hw_itypes[1];
+
+/* Initialize interrupts.  */
+void __init mach_init_irqs (void)
+{
+	nb85e_intc_init_irq_types (irq_inits, hw_itypes);
+}
+
+
+void machine_halt (void) __attribute__ ((noreturn));
+void machine_halt (void)
+{
+	SIMFIN = 0;		/* Halt immediately.  */
+	for (;;) {}
+}
+
+void machine_restart (char *__unused)
+{
+	machine_halt ();
+}
+
+void machine_power_off (void)
+{
+	machine_halt ();
+}
diff -Nru a/arch/v850/kernel/simcons.c b/arch/v850/kernel/simcons.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/simcons.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,158 @@
+/*
+ * arch/v850/kernel/simcons.c -- Console I/O for GDB v850e simulator
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/tty_driver.h>
+#include <linux/init.h>
+
+#include <asm/poll.h>
+#include <asm/simsyscall.h>
+
+
+/*  Low-level console. */
+
+static void simcons_write (struct console *co, const char *buf, unsigned len)
+{
+	V850_SIM_SYSCALL (write, 1, buf, len);
+}
+
+static int simcons_read (struct console *co, const char *buf, unsigned len)
+{
+	return V850_SIM_SYSCALL (read, 0, buf, len);
+}
+
+static kdev_t simcons_device (struct console *c)
+{
+        return mk_kdev (TTY_MAJOR, 64 + c->index);
+}
+
+static struct console simcons =
+{
+    .name	= "simcons",
+    .write	= simcons_write,
+    .read	= simcons_read,
+    .device	= simcons_device,
+    .flags	= CON_PRINTBUFFER,
+    .index	= -1,
+};
+
+/* Higher level TTY interface.  */
+
+static struct tty_struct *tty_table[1] = { 0 };
+static struct termios *tty_termios[1] = { 0 };
+static struct termios *tty_termios_locked[1] = { 0 };
+static struct tty_driver tty_driver = { 0 };
+static int tty_refcount = 0;
+
+int simcons_tty_open (struct tty_struct *tty, struct file *filp)
+{
+	return 0;
+}
+
+int simcons_tty_write (struct tty_struct *tty, int from_user,
+		       const unsigned char *buf, int count)
+{
+	return V850_SIM_SYSCALL (write, 1, buf, count);
+}
+
+int simcons_tty_write_room (struct tty_struct *tty)
+{
+	/* Completely arbitrary.  */
+	return 0x100000;
+}
+
+int simcons_tty_chars_in_buffer (struct tty_struct *tty)
+{
+	/* We have no buffer.  */
+	return 0;
+}
+
+int __init simcons_tty_init (void)
+{
+	tty_driver.name = "simcons";
+	tty_driver.major = TTY_MAJOR;
+	tty_driver.minor_start = 64;
+	tty_driver.num = 1;
+	tty_driver.type = TTY_DRIVER_TYPE_SYSCONS;
+
+	tty_driver.refcount = &tty_refcount;
+
+	tty_driver.table = tty_table;
+	tty_driver.termios = tty_termios;
+	tty_driver.termios_locked = tty_termios_locked;
+
+	tty_driver.init_termios = tty_std_termios;
+
+	tty_driver.open = simcons_tty_open;
+	tty_driver.write = simcons_tty_write;
+	tty_driver.write_room = simcons_tty_write_room;
+	tty_driver.chars_in_buffer = simcons_tty_chars_in_buffer;
+
+	tty_register_driver (&tty_driver);
+}
+__initcall (simcons_tty_init);
+
+/* Poll for input on the console, and if there's any, deliver it to the
+   tty driver.  */
+void simcons_poll_tty (struct tty_struct *tty)
+{
+	int flip = 0, send_break = 0;
+	struct pollfd pfd;
+	pfd.fd = 0;
+	pfd.events = POLLIN;
+
+	if (V850_SIM_SYSCALL (poll, &pfd, 1, 0) > 0) {
+		if (pfd.revents & POLLIN) {
+			int left = TTY_FLIPBUF_SIZE - tty->flip.count;
+
+			if (left > 0) {
+				unsigned char *buf = tty->flip.char_buf_ptr;
+				int rd = V850_SIM_SYSCALL (read, 0, buf, left);
+
+				if (rd > 0) {
+					tty->flip.count += rd;
+					tty->flip.char_buf_ptr += rd;
+					memset (tty->flip.flag_buf_ptr, 0, rd);
+					tty->flip.flag_buf_ptr += rd;
+					flip = 1;
+				} else
+					send_break = 1;
+			}
+		} else if (pfd.revents & POLLERR)
+			send_break = 1;
+	}
+
+	if (send_break) {
+		tty_insert_flip_char (tty, 0, TTY_BREAK);		
+		flip = 1;
+	}
+
+	if (flip)
+		tty_schedule_flip (tty);
+}
+
+void simcons_poll_ttys (void)
+{
+	if (tty_table[0])
+		simcons_poll_tty (tty_table[0]);
+}
+
+void simcons_setup (void)
+{
+	V850_SIM_SYSCALL (make_raw, 0);
+	register_console (&simcons);
+	printk (KERN_INFO "Console: GDB/v850e simulator stdio\n");
+}
diff -Nru a/arch/v850/kernel/syscalls.c b/arch/v850/kernel/syscalls.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/syscalls.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,197 @@
+/*
+ * arch/v850/kernel/syscalls.c -- Various system-call definitions not
+ * 	defined in machine-independent code
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * This file was derived the ppc version, arch/ppc/kernel/syscalls.c
+ * ... which was derived from "arch/i386/kernel/sys_i386.c" by Gary Thomas;
+ *     modified by Cort Dougan (cort@cs.nmt.edu)
+ *     and Paul Mackerras (paulus@cs.anu.edu.au).
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/mman.h>
+#include <linux/sys.h>
+#include <linux/ipc.h>
+#include <linux/utsname.h>
+#include <linux/file.h>
+
+#include <asm/uaccess.h>
+#include <asm/ipc.h>
+#include <asm/semaphore.h>
+
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly.
+ */
+int
+sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth)
+{
+	int version, ret;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	ret = -EINVAL;
+	switch (call) {
+	case SEMOP:
+		ret = sys_semop (first, (struct sembuf *)ptr, second);
+		break;
+	case SEMGET:
+		ret = sys_semget (first, second, third);
+		break;
+	case SEMCTL:
+	{
+		union semun fourth;
+
+		if (!ptr)
+			break;
+		if ((ret = verify_area (VERIFY_READ, ptr, sizeof(long)))
+		    || (ret = get_user(fourth.__pad, (void **)ptr)))
+			break;
+		ret = sys_semctl (first, second, third, fourth);
+		break;
+	}
+	case MSGSND:
+		ret = sys_msgsnd (first, (struct msgbuf *) ptr, second, third);
+		break;
+	case MSGRCV:
+		switch (version) {
+		case 0: {
+			struct ipc_kludge tmp;
+
+			if (!ptr)
+				break;
+			if ((ret = verify_area (VERIFY_READ, ptr, sizeof(tmp)))
+			    || (ret = copy_from_user(&tmp,
+						(struct ipc_kludge *) ptr,
+						sizeof (tmp))))
+				break;
+			ret = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp,
+					  third);
+			break;
+			}
+		default:
+			ret = sys_msgrcv (first, (struct msgbuf *) ptr,
+					  second, fifth, third);
+			break;
+		}
+		break;
+	case MSGGET:
+		ret = sys_msgget ((key_t) first, second);
+		break;
+	case MSGCTL:
+		ret = sys_msgctl (first, second, (struct msqid_ds *) ptr);
+		break;
+	case SHMAT:
+		switch (version) {
+		default: {
+			ulong raddr;
+
+			if ((ret = verify_area(VERIFY_WRITE, (ulong*) third,
+					       sizeof(ulong))))
+				break;
+			ret = sys_shmat (first, (char *) ptr, second, &raddr);
+			if (ret)
+				break;
+			ret = put_user (raddr, (ulong *) third);
+			break;
+			}
+		case 1:	/* iBCS2 emulator entry point */
+			if (!segment_eq(get_fs(), get_ds()))
+				break;
+			ret = sys_shmat (first, (char *) ptr, second,
+					 (ulong *) third);
+			break;
+		}
+		break;
+	case SHMDT: 
+		ret = sys_shmdt ((char *)ptr);
+		break;
+	case SHMGET:
+		ret = sys_shmget (first, second, third);
+		break;
+	case SHMCTL:
+		ret = sys_shmctl (first, second, (struct shmid_ds *) ptr);
+		break;
+	}
+
+	return ret;
+}
+
+/*
+ * sys_pipe() is the normal C calling standard for creating
+ * a pipe. It's not the way unix traditionally does this, though.
+ */
+int sys_pipe (int *fildes)
+{
+	int fd[2];
+	int error;
+
+	error = do_pipe (fd);
+	if (!error) {
+		if (copy_to_user (fildes, fd, 2*sizeof (int)))
+			error = -EFAULT;
+	}
+	return error;
+}
+
+static inline unsigned long
+do_mmap2 (unsigned long addr, size_t len,
+	 unsigned long prot, unsigned long flags,
+	 unsigned long fd, unsigned long pgoff)
+{
+	struct file * file = NULL;
+	int ret = -EBADF;
+
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+	if (! (flags & MAP_ANONYMOUS)) {
+		if (!(file = fget (fd)))
+			goto out;
+	}
+	
+	down_write (&current->mm->mmap_sem);
+	ret = do_mmap_pgoff (file, addr, len, prot, flags, pgoff);
+	up_write (&current->mm->mmap_sem);
+	if (file)
+		fput (file);
+out:
+	return ret;
+}
+
+unsigned long sys_mmap2 (unsigned long addr, size_t len,
+			unsigned long prot, unsigned long flags,
+			unsigned long fd, unsigned long pgoff)
+{
+	return do_mmap2 (addr, len, prot, flags, fd, pgoff);
+}
+
+unsigned long sys_mmap (unsigned long addr, size_t len,
+		       unsigned long prot, unsigned long flags,
+		       unsigned long fd, off_t offset)
+{
+	int err = -EINVAL;
+
+	if (offset & ~PAGE_MASK)
+		goto out;
+
+	err = do_mmap2 (addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+out:
+	return err;
+}
diff -Nru a/arch/v850/kernel/time.c b/arch/v850/kernel/time.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/time.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,193 @@
+/*
+ * linux/arch/v850/kernel/time.c -- Arch-dependent timer functions
+ *
+ *  Copyright (C) 1991, 1992, 1995, 2001, 2002  Linus Torvalds
+ *
+ * This file contains the v850-specific time handling details.
+ * Most of the stuff is located in the machine specific files.
+ *
+ * 1997-09-10	Updated NTP code according to technical memorandum Jan '96
+ *		"A Kernel Model for Precision Timekeeping" by Dave Mills
+ */
+
+#include <linux/config.h> /* CONFIG_HEARTBEAT */
+#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/interrupt.h>
+#include <linux/timex.h>
+#include <linux/profile.h>
+
+#include <asm/io.h>
+
+#include "mach.h"
+
+u64 jiffies_64;
+
+#define TICK_SIZE	(tick_nsec / 1000)
+
+static inline void do_profile (unsigned long pc)
+{
+	if (prof_buffer && current->pid) {
+		extern int _stext;
+		pc -= (unsigned long) &_stext;
+		pc >>= prof_shift;
+		if (pc < prof_len)
+			++prof_buffer[pc];
+		else
+		/*
+		 * Don't ignore out-of-bounds PC values silently,
+		 * put them into the last histogram slot, so if
+		 * present, they will show up as a sharp peak.
+		 */
+			++prof_buffer[prof_len-1];
+	}
+}
+
+/*
+ * timer_interrupt() needs to keep up the real-time clock,
+ * as well as call the "do_timer()" routine every clocktick
+ */
+static void timer_interrupt (int irq, void *dummy, struct pt_regs *regs)
+{
+#if 0
+	/* last time the cmos clock got updated */
+	static long last_rtc_update=0;
+#endif
+
+	/* may need to kick the hardware timer */
+	if (mach_tick)
+	  mach_tick ();
+
+	do_timer (regs);
+
+	if (! user_mode (regs))
+		do_profile (regs->pc);
+
+#if 0
+	/*
+	 * If we have an externally synchronized Linux clock, then update
+	 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+	 * called as close as possible to 500 ms before the new second starts.
+	 */
+	if ((time_status & STA_UNSYNC) == 0 &&
+	    xtime.tv_sec > last_rtc_update + 660 &&
+	    (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
+	    (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
+	  if (set_rtc_mmss (xtime.tv_sec) == 0)
+	    last_rtc_update = xtime.tv_sec;
+	  else
+	    last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+	}
+#ifdef CONFIG_HEARTBEAT
+	/* use power LED as a heartbeat instead -- much more useful
+	   for debugging -- based on the version for PReP by Cort */
+	/* acts like an actual heart beat -- ie thump-thump-pause... */
+	if (mach_heartbeat) {
+	    static unsigned cnt = 0, period = 0, dist = 0;
+
+	    if (cnt == 0 || cnt == dist)
+		mach_heartbeat ( 1 );
+	    else if (cnt == 7 || cnt == dist+7)
+		mach_heartbeat ( 0 );
+
+	    if (++cnt > period) {
+		cnt = 0;
+		/* The hyperbolic function below modifies the heartbeat period
+		 * length in dependency of the current (5min) load. It goes
+		 * through the points f(0)=126, f(1)=86, f(5)=51,
+		 * f(inf)->30. */
+		period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
+		dist = period / 4;
+	    }
+	}
+#endif /* CONFIG_HEARTBEAT */
+#endif /* 0 */
+}
+
+extern rwlock_t xtime_lock;
+
+/*
+ * This version of gettimeofday has near microsecond resolution.
+ */
+void do_gettimeofday (struct timeval *tv)
+{
+#if 0 /* DAVIDM later if possible */
+	extern volatile unsigned long lost_ticks;
+	unsigned long lost;
+#endif
+	unsigned long flags;
+	unsigned long usec, sec;
+
+	read_lock_irqsave (&xtime_lock, flags);
+#if 0
+	usec = mach_gettimeoffset ? mach_gettimeoffset () : 0;
+#else
+	usec = 0;
+#endif
+#if 0 /* DAVIDM later if possible */
+	lost = lost_ticks;
+	if (lost)
+		usec += lost * (1000000/HZ);
+#endif
+	sec = xtime.tv_sec;
+	usec += xtime.tv_nsec / 1000;
+	read_unlock_irqrestore (&xtime_lock, flags);
+
+	while (usec >= 1000000) {
+		usec -= 1000000;
+		sec++;
+	}
+
+	tv->tv_sec = sec;
+	tv->tv_usec = usec;
+}
+
+void do_settimeofday (struct timeval *tv)
+{
+	write_lock_irq (&xtime_lock);
+
+	/* This is revolting. We need to set the xtime.tv_nsec
+	 * correctly. However, the value in this location is
+	 * is value at the last tick.
+	 * Discover what correction gettimeofday
+	 * would have done, and then undo it!
+	 */
+#if 0
+	tv->tv_usec -= mach_gettimeoffset ();
+#endif
+
+	while (tv->tv_usec < 0) {
+		tv->tv_usec += 1000000;
+		tv->tv_sec--;
+	}
+
+	xtime.tv_sec = tv->tv_sec;
+	xtime.tv_nsec = tv->tv_usec * 1000;
+
+	time_adjust = 0;		/* stop active adjtime () */
+	time_status |= STA_UNSYNC;
+	time_maxerror = NTP_PHASE_LIMIT;
+	time_esterror = NTP_PHASE_LIMIT;
+
+	write_unlock_irq (&xtime_lock);
+}
+
+static int timer_dev_id;
+static struct irqaction timer_irqaction = {
+	timer_interrupt,
+	SA_INTERRUPT,
+	0,
+	"timer",
+	&timer_dev_id,
+	NULL
+};
+
+void time_init (void)
+{
+	mach_gettimeofday (&xtime);
+	mach_sched_init (&timer_irqaction);
+}
diff -Nru a/arch/v850/kernel/v850_ksyms.c b/arch/v850/kernel/v850_ksyms.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/kernel/v850_ksyms.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,79 @@
+#include <linux/module.h>
+#include <linux/linkage.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/user.h>
+#include <linux/elfcore.h>
+#include <linux/in6.h>
+#include <linux/interrupt.h>
+#include <linux/config.h>
+
+#include <asm/setup.h>
+#include <asm/pgalloc.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/semaphore.h>
+#include <asm/checksum.h>
+#include <asm/hardirq.h>
+#include <asm/softirq.h>
+#include <asm/current.h>
+
+
+extern void *trap_table;
+EXPORT_SYMBOL (trap_table);
+
+/* platform dependent support */
+extern void dump_thread (struct pt_regs *, struct user *);
+EXPORT_SYMBOL (dump_thread);
+EXPORT_SYMBOL (kernel_thread);
+EXPORT_SYMBOL (__bug);
+
+/* Networking helper routines. */
+EXPORT_SYMBOL (csum_partial_copy);
+EXPORT_SYMBOL (csum_partial_copy_from_user);
+EXPORT_SYMBOL (ip_compute_csum);
+EXPORT_SYMBOL (ip_fast_csum);
+
+/* string / mem functions */
+EXPORT_SYMBOL_NOVERS (strcpy);
+EXPORT_SYMBOL_NOVERS (strncpy);
+EXPORT_SYMBOL_NOVERS (strcat);
+EXPORT_SYMBOL_NOVERS (strncat);
+EXPORT_SYMBOL_NOVERS (strcmp);
+EXPORT_SYMBOL_NOVERS (strncmp);
+EXPORT_SYMBOL_NOVERS (strchr);
+EXPORT_SYMBOL_NOVERS (strlen);
+EXPORT_SYMBOL_NOVERS (strnlen);
+EXPORT_SYMBOL_NOVERS (strpbrk);
+EXPORT_SYMBOL_NOVERS (strtok);
+EXPORT_SYMBOL_NOVERS (strrchr);
+EXPORT_SYMBOL_NOVERS (strstr);
+EXPORT_SYMBOL_NOVERS (memset);
+EXPORT_SYMBOL_NOVERS (memcpy);
+EXPORT_SYMBOL_NOVERS (memmove);
+EXPORT_SYMBOL_NOVERS (memcmp);
+EXPORT_SYMBOL_NOVERS (memscan);
+
+/* semaphores */
+EXPORT_SYMBOL_NOVERS (__down);
+EXPORT_SYMBOL_NOVERS (__down_interruptible);
+EXPORT_SYMBOL_NOVERS (__down_trylock);
+EXPORT_SYMBOL_NOVERS (__up);
+
+/*
+ * libgcc functions - functions that are used internally by the
+ * compiler...  (prototypes are not correct though, but that
+ * doesn't really matter since they're not versioned).
+ */
+extern void __ashldi3 (void);
+extern void __ashrdi3 (void);
+extern void __lshrdi3 (void);
+extern void __muldi3 (void);
+extern void __negdi2 (void);
+
+EXPORT_SYMBOL_NOVERS (__ashldi3);
+EXPORT_SYMBOL_NOVERS (__ashrdi3);
+EXPORT_SYMBOL_NOVERS (__lshrdi3);
+EXPORT_SYMBOL_NOVERS (__muldi3);
+EXPORT_SYMBOL_NOVERS (__negdi2);
diff -Nru a/arch/v850/lib/Makefile b/arch/v850/lib/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/lib/Makefile	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,9 @@
+#
+# arch/v850/lib/Makefile
+#
+
+L_TARGET = lib.a
+obj-y  = ashrdi3.o ashldi3.o lshrdi3.o muldi3.o negdi2.o \
+	 checksum.o memcpy.o memset.o
+
+include $(TOPDIR)/Rules.make
diff -Nru a/arch/v850/lib/ashldi3.c b/arch/v850/lib/ashldi3.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/lib/ashldi3.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,62 @@
+/* ashldi3.c extracted from gcc-2.95.2/libgcc2.c which is: */
+/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#define BITS_PER_UNIT 8
+
+typedef 	 int SItype	__attribute__ ((mode (SI)));
+typedef unsigned int USItype	__attribute__ ((mode (SI)));
+typedef		 int DItype	__attribute__ ((mode (DI)));
+typedef int word_type __attribute__ ((mode (__word__)));
+
+struct DIstruct {SItype high, low;};
+
+typedef union
+{
+  struct DIstruct s;
+  DItype ll;
+} DIunion;
+
+DItype
+__ashldi3 (DItype u, word_type b)
+{
+  DIunion w;
+  word_type bm;
+  DIunion uu;
+
+  if (b == 0)
+    return u;
+
+  uu.ll = u;
+
+  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+  if (bm <= 0)
+    {
+      w.s.low = 0;
+      w.s.high = (USItype)uu.s.low << -bm;
+    }
+  else
+    {
+      USItype carries = (USItype)uu.s.low >> bm;
+      w.s.low = (USItype)uu.s.low << b;
+      w.s.high = ((USItype)uu.s.high << b) | carries;
+    }
+
+  return w.ll;
+}
diff -Nru a/arch/v850/lib/ashrdi3.c b/arch/v850/lib/ashrdi3.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/lib/ashrdi3.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,63 @@
+/* ashrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#define BITS_PER_UNIT 8
+
+typedef 	 int SItype	__attribute__ ((mode (SI)));
+typedef unsigned int USItype	__attribute__ ((mode (SI)));
+typedef		 int DItype	__attribute__ ((mode (DI)));
+typedef int word_type __attribute__ ((mode (__word__)));
+
+struct DIstruct {SItype high, low;};
+
+typedef union
+{
+  struct DIstruct s;
+  DItype ll;
+} DIunion;
+
+DItype
+__ashrdi3 (DItype u, word_type b)
+{
+  DIunion w;
+  word_type bm;
+  DIunion uu;
+
+  if (b == 0)
+    return u;
+
+  uu.ll = u;
+
+  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+  if (bm <= 0)
+    {
+      /* w.s.high = 1..1 or 0..0 */
+      w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
+      w.s.low = uu.s.high >> -bm;
+    }
+  else
+    {
+      USItype carries = (USItype)uu.s.high << bm;
+      w.s.high = uu.s.high >> b;
+      w.s.low = ((USItype)uu.s.low >> b) | carries;
+    }
+
+  return w.ll;
+}
diff -Nru a/arch/v850/lib/checksum.c b/arch/v850/lib/checksum.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/lib/checksum.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,151 @@
+/*
+ * INET		An implementation of the TCP/IP protocol suite for the LINUX
+ *		operating system.  INET is implemented using the  BSD Socket
+ *		interface as the means of communication with the user level.
+ *
+ *		MIPS specific IP/TCP/UDP checksumming routines
+ *
+ * Authors:	Ralf Baechle, <ralf@waldorf-gmbh.de>
+ *		Lots of code moved from tcp.c and ip.c; see those files
+ *		for more names.
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ *
+ * $Id: checksum.c,v 1.1 2002/09/28 14:58:40 gerg Exp $
+ */
+#include <net/checksum.h>
+#include <linux/types.h>
+#include <asm/byteorder.h>
+#include <asm/string.h>
+#include <asm/uaccess.h>
+
+static inline unsigned short from32to16 (unsigned long sum)
+{
+	unsigned int result;
+	/*
+			        %0		%1
+	      hsw %1, %0	H     L		L     H
+	      add %1, %0	H     L		H+L+C H+L
+	*/
+	asm ("hsw %1, %0; add %1, %0" : "=&r" (result) : "r" (sum));
+	return result >> 16;
+}
+
+static inline unsigned int do_csum(const unsigned char * buff, int len)
+{
+	int odd, count;
+	unsigned int result = 0;
+
+	if (len <= 0)
+		goto out;
+	odd = 1 & (unsigned long) buff;
+	if (odd) {
+		result = be16_to_cpu(*buff);
+		len--;
+		buff++;
+	}
+	count = len >> 1;		/* nr of 16-bit words.. */
+	if (count) {
+		if (2 & (unsigned long) buff) {
+			result += *(unsigned short *) buff;
+			count--;
+			len -= 2;
+			buff += 2;
+		}
+		count >>= 1;		/* nr of 32-bit words.. */
+		if (count) {
+			unsigned int carry = 0;
+			do {
+				unsigned int w = *(unsigned int *) buff;
+				count--;
+				buff += 4;
+				result += carry;
+				result += w;
+				carry = (w > result);
+			} while (count);
+			result += carry;
+			result = (result & 0xffff) + (result >> 16);
+		}
+		if (len & 2) {
+			result += *(unsigned short *) buff;
+			buff += 2;
+		}
+	}
+	if (len & 1)
+		result += le16_to_cpu(*buff);
+	result = from32to16(result);
+	if (odd)
+		result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+out:
+	return result;
+}
+
+/*
+ *	This is a version of ip_compute_csum() optimized for IP headers,
+ *	which always checksum on 4 octet boundaries.
+ */
+unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl)
+{
+	return ~do_csum(iph,ihl*4);
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+unsigned short ip_compute_csum(const unsigned char * buff, int len)
+{
+	return ~do_csum(buff,len);
+}
+
+/*
+ * computes a partial checksum, e.g. for TCP/UDP fragments
+ */
+unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum)
+{
+	unsigned int result = do_csum(buff, len);
+
+	/* add in old sum, and carry.. */
+	result += sum;
+	if(sum > result)
+		result += 1;
+	return result;
+}
+
+/*
+ * copy while checksumming, otherwise like csum_partial
+ */
+unsigned int csum_partial_copy(const char *src, char *dst, 
+                               int len, unsigned int sum)
+{
+	/*
+	 * It's 2:30 am and I don't feel like doing it real ...
+	 * This is lots slower than the real thing (tm)
+	 */
+	sum = csum_partial(src, len, sum);
+	memcpy(dst, src, len);
+
+	return sum;
+}
+
+/*
+ * Copy from userspace and compute checksum.  If we catch an exception
+ * then zero the rest of the buffer.
+ */
+unsigned int csum_partial_copy_from_user (const char *src, char *dst,
+                                          int len, unsigned int sum,
+                                          int *err_ptr)
+{
+	int missing;
+
+	missing = copy_from_user(dst, src, len);
+	if (missing) {
+		memset(dst + len - missing, 0, missing);
+		*err_ptr = -EFAULT;
+	}
+		
+	return csum_partial(dst, len, sum);
+}
diff -Nru a/arch/v850/lib/lshrdi3.c b/arch/v850/lib/lshrdi3.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/lib/lshrdi3.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,62 @@
+/* lshrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#define BITS_PER_UNIT 8
+
+typedef 	 int SItype	__attribute__ ((mode (SI)));
+typedef unsigned int USItype	__attribute__ ((mode (SI)));
+typedef		 int DItype	__attribute__ ((mode (DI)));
+typedef int word_type __attribute__ ((mode (__word__)));
+
+struct DIstruct {SItype high, low;};
+
+typedef union
+{
+  struct DIstruct s;
+  DItype ll;
+} DIunion;
+
+DItype
+__lshrdi3 (DItype u, word_type b)
+{
+  DIunion w;
+  word_type bm;
+  DIunion uu;
+
+  if (b == 0)
+    return u;
+
+  uu.ll = u;
+
+  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+  if (bm <= 0)
+    {
+      w.s.high = 0;
+      w.s.low = (USItype)uu.s.high >> -bm;
+    }
+  else
+    {
+      USItype carries = (USItype)uu.s.high << bm;
+      w.s.high = (USItype)uu.s.high >> b;
+      w.s.low = ((USItype)uu.s.low >> b) | carries;
+    }
+
+  return w.ll;
+}
diff -Nru a/arch/v850/lib/memcpy.c b/arch/v850/lib/memcpy.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/lib/memcpy.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,97 @@
+/*
+ * arch/v850/lib/memcpy.c -- Memory copying
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/types.h>
+#include <asm/string.h>
+
+#define CHUNK_SIZE		32 /* bytes */
+#define CHUNK_ALIGNED(addr)	(((unsigned long)addr & 0x3) == 0)
+
+/* Note that this macro uses 8 call-clobbered registers (not including
+   R1), which are few enough so that the following functions don't need
+   to spill anything to memory.  It also uses R1, which is nominally
+   reserved for the assembler, but here it should be OK.  */
+#define COPY_CHUNK(src, dst)			\
+   asm ("mov %0, ep;"				\
+	"sld.w 0[ep], r1; sld.w 4[ep], r12;"	\
+	"sld.w 8[ep], r13; sld.w 12[ep], r14;"	\
+	"sld.w 16[ep], r15; sld.w 20[ep], r17;"	\
+	"sld.w 24[ep], r18; sld.w 28[ep], r19;"	\
+	"mov %1, ep;"				\
+	"sst.w r1, 0[ep]; sst.w r12, 4[ep];"	\
+	"sst.w r13, 8[ep]; sst.w r14, 12[ep];"	\
+	"sst.w r15, 16[ep]; sst.w r17, 20[ep];"	\
+	"sst.w r18, 24[ep]; sst.w r19, 28[ep]"	\
+	:: "r" (src), "r" (dst)			\
+	: "r1", "r12", "r13", "r14", "r15",	\
+	  "r17", "r18", "r19", "ep", "memory");
+
+void *memcpy (void *dst, const void *src, __kernel_size_t size)
+{
+	char *_dst = dst;
+	const char *_src = src;
+
+	if (size >= CHUNK_SIZE && CHUNK_ALIGNED(_src) && CHUNK_ALIGNED(_dst)) {
+		/* Copy large blocks efficiently.  */
+		unsigned count;
+		for (count = size / CHUNK_SIZE; count; count--) {
+			COPY_CHUNK (_src, _dst);
+			_src += CHUNK_SIZE;
+			_dst += CHUNK_SIZE;
+		}
+		size %= CHUNK_SIZE;
+	}
+
+	if (size > 0)
+		do
+			*_dst++ = *_src++;
+		while (--size);
+
+	return dst;
+}
+
+void bcopy (const char *src, char *dst, int size)
+{
+	memcpy (dst, src, size);
+}
+
+void *memmove (void *dst, const void *src, __kernel_size_t size)
+{
+	if ((unsigned long)dst < (unsigned long)src
+	    || (unsigned long)src + size < (unsigned long)dst)
+		return memcpy (dst, src, size);
+	else {
+		char *_dst = dst + size;
+		const char *_src = src + size;
+
+		if (size >= CHUNK_SIZE
+		    && CHUNK_ALIGNED (_src) && CHUNK_ALIGNED (_dst))
+		{
+			/* Copy large blocks efficiently.  */
+			unsigned count;
+			for (count = size / CHUNK_SIZE; count; count--) {
+				_src -= CHUNK_SIZE;
+				_dst -= CHUNK_SIZE;
+				COPY_CHUNK (_src, _dst);
+			}
+			size %= CHUNK_SIZE;
+		}
+
+		if (size > 0)
+			do
+				*--_dst = *--_src;
+			while (--size);
+
+		return _dst;
+	}
+}
diff -Nru a/arch/v850/lib/memset.c b/arch/v850/lib/memset.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/lib/memset.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,61 @@
+/*
+ * arch/v850/lib/memset.c -- Memory initialization
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/types.h>
+
+void *memset (void *dst, int val, __kernel_size_t count)
+{
+	if (count) {
+		register unsigned loop;
+		register void *ptr asm ("ep") = dst;
+
+		/* replicate VAL into a long.  */
+		val &= 0xff;
+		val |= val << 8;
+		val |= val << 16;
+
+		/* copy initial unaligned bytes.  */
+		if ((long)ptr & 1) {
+			*((char *)ptr)++ = val;
+			count--;
+		}
+		if (count > 2 && ((long)ptr & 2)) {
+			*((short *)ptr)++ = val;
+			count -= 2;
+		}
+
+		/* 32-byte copying loop.  */
+		for (loop = count / 32; loop; loop--) {
+			asm ("sst.w %0, 0[ep]; sst.w %0, 4[ep];"
+			     "sst.w %0, 8[ep]; sst.w %0, 12[ep];"
+			     "sst.w %0, 16[ep]; sst.w %0, 20[ep];"
+			     "sst.w %0, 24[ep]; sst.w %0, 28[ep]"
+			     :: "r" (val) : "memory");
+			ptr += 32;
+		}
+		count %= 32;
+
+		/* long copying loop.  */
+		for (loop = count / 4; loop; loop--)
+			*((long *)ptr)++ = val;
+		count %= 4;
+
+		/* finish up with any trailing bytes.  */
+		if (count & 2)
+			*((short *)ptr)++ = val;
+		if (count & 1)
+			*(char *)ptr = val;
+	}
+
+	return dst;
+}
diff -Nru a/arch/v850/lib/muldi3.c b/arch/v850/lib/muldi3.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/lib/muldi3.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,61 @@
+/* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and 
+			   gcc-2.7.2.3/longlong.h which is: */
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 2001 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#define umul_ppmm(w1, w0, u, v) \
+  __asm__ ("mulu %3, %0, %1"						\
+           : "=r" ((USItype)(w0)),					\
+             "=r" ((USItype)(w1))					\
+           : "%0" ((USItype)(u)),					\
+             "r" ((USItype)(v)))
+
+#define __umulsidi3(u, v) \
+  ({DIunion __w;							\
+    umul_ppmm (__w.s.high, __w.s.low, u, v);				\
+    __w.ll; })
+
+typedef 	 int SItype	__attribute__ ((mode (SI)));
+typedef unsigned int USItype	__attribute__ ((mode (SI)));
+typedef		 int DItype	__attribute__ ((mode (DI)));
+typedef int word_type __attribute__ ((mode (__word__)));
+
+struct DIstruct {SItype high, low;};
+
+typedef union
+{
+  struct DIstruct s;
+  DItype ll;
+} DIunion;
+
+DItype
+__muldi3 (DItype u, DItype v)
+{
+  DIunion w;
+  DIunion uu, vv;
+
+  uu.ll = u,
+  vv.ll = v;
+
+  w.ll = __umulsidi3 (uu.s.low, vv.s.low);
+  w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
+	       + (USItype) uu.s.high * (USItype) vv.s.low);
+
+  return w.ll;
+}
diff -Nru a/arch/v850/lib/negdi2.c b/arch/v850/lib/negdi2.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/lib/negdi2.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,25 @@
+/*
+ * arch/v850/lib/negdi2.c -- 64-bit negation
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+typedef		 int DItype	__attribute__ ((mode (DI)));
+
+DItype __negdi2 (DItype x)
+{
+	__asm__ __volatile__
+		("not	r6, r10;"
+		 "add	1, r10;"
+		 "setf	c, r6;"
+		 "not	r7, r11;"
+		 "add	r6, r11"
+		 ::: "r6", "r7", "r10", "r11");
+}
diff -Nru a/arch/v850/rte_ma1_cb-ksram.ld b/arch/v850/rte_ma1_cb-ksram.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/rte_ma1_cb-ksram.ld	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,152 @@
+/* Linker script for the Midas labs RTE-V850E/MA1-CB evaluation board
+   (CONFIG_RTE_CB_MA1), with kernel in SRAM, under Multi debugger.  */
+
+/* Note, all symbols are prefixed with an extra `_' for compatibility with
+   the existing linux sources.  */
+
+_jiffies = _jiffies_64 ;
+
+MEMORY {
+       /* 1MB of SRAM; we can't use the last 32KB, because it's used by
+          the monitor scratch-RAM.  This memory is mirrored 4 times.  */
+       SRAM  : ORIGIN = 0x00400000, LENGTH = 0x000F8000
+       /* Monitor scratch RAM; only the interrupt vectors should go here.  */
+       MRAM  : ORIGIN = 0x004F8000, LENGTH = 0x00008000
+       /* 32MB of SDRAM.  */
+       SDRAM : ORIGIN = 0x00800000, LENGTH = 0x02000000
+}
+
+SECTIONS {
+	.text : {
+	        __kram_start = . ;
+
+		__stext = . ;
+        	*(.text)
+			*(.exit.text)	/* 2.5 convention */
+			*(.text.exit)	/* 2.4 convention */
+			*(.text.lock)
+			*(.exitcall.exit)
+		__real_etext = . ;	/* There may be data after here.  */
+			*(.rodata)
+
+		. = ALIGN (0x4) ;
+			*(.kstrtab)
+
+		. = ALIGN (4) ;
+		*(.call_table_data)
+		*(.call_table_text)
+
+		. = ALIGN (16) ;	/* Exception table.  */
+		___start___ex_table = . ;
+			*(__ex_table)
+		___stop___ex_table = . ;
+
+		___start___ksymtab = . ;/* Kernel symbol table.  */
+			*(__ksymtab)
+		___stop___ksymtab = . ;
+		. = ALIGN (4) ;
+		__etext = . ;
+	} > SRAM
+
+	.data ALIGN (0x4) : {
+		__sdata = . ;
+		___data_start = . ;
+        	*(.data)
+			*(.exit.data)	/* 2.5 convention */
+			*(.data.exit)	/* 2.4 convention */
+		. = ALIGN (16) ;
+		*(.data.cacheline_aligned)
+		. = ALIGN (0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN (0x2000) ;
+		__edata = . ;
+	} > SRAM
+
+	.bss ALIGN (0x4) : {
+		__sbss = . ;
+			*(.bss)
+			*(COMMON)
+		. = ALIGN (4) ;
+		__init_stack_end = . ;
+		__ebss = . ;
+	} > SRAM
+
+	.init ALIGN (4096) : {
+		__init_start = . ;
+			*(.init.text)	/* 2.5 convention */
+			*(.init.data)
+			*(.text.init)	/* 2.4 convention */
+			*(.data.init)
+		. = ALIGN (16) ;
+		___setup_start = . ;
+			*(.init.setup)	/* 2.5 convention */
+			*(.setup.init)	/* 2.4 convention */
+		___setup_end = . ;
+		___initcall_start = . ;
+			*(.initcall.init)
+			*(.initcall1.init)
+			*(.initcall2.init)
+			*(.initcall3.init)
+			*(.initcall4.init)
+			*(.initcall5.init)
+			*(.initcall6.init)
+			*(.initcall7.init)
+		. = ALIGN (4) ;
+		___initcall_end = . ;
+	} > SRAM
+
+	/* This provides address at which the interrupt vectors are
+	   initially loaded by the loader.  */
+	__intv_load_start = ALIGN (0x10) ;
+
+	/* Interrupt vector space.  Because we're using the monitor
+	   ROM, Instead of the native interrupt vector, we must use the
+	   `alternate interrupt vector' area.  Note that this is in
+	   `SRAM' space, which is not currently used by the kernel (the
+	   kernel uses `SDRAM' space).  */
+
+	/* We can't load the interrupt vectors directly into their
+	   target location, because the monitor ROM for the GHS Multi
+	   debugger barfs if we try.  Unfortunately, Multi also doesn't
+	   deal correctly with ELF sections where the LMA and VMA differ
+	   (it just ignores the LMA), so we can't use that feature to
+	   work around the problem!  What we do instead is just put the
+	   interrupt vectors into a normal section, and have the
+	   `mach_early_init' function for Midas boards do the necessary
+	   copying and relocation at runtime (this section basically
+	   only contains `jr' instructions, so it's not that hard).
+
+	   This the section structure I initially tried to use (which more
+	   accurately expresses the intent):
+
+		.intv 0x007F8000 : AT (ADDR (.init) + SIZEOF (.init)) {
+		    ...
+		} > MRAM
+	*/
+
+	.intv ALIGN (0x10) : {
+		__intv_start = . ;
+	        	*(.intv.reset)	/* Reset vector */
+			*(.intv.common) /* Vectors common to all v850e proc. */
+			*(.intv.mach)   /* Machine-specific int. vectors.  */
+		__intv_end = . ;
+
+		/* This is here so that when we free init memory, the initial
+		   load-area of the interrupt vectors is freed too.  */
+		__init_end = __intv_end;
+
+		__kram_end = __init_end ;
+	} > SRAM
+
+	.bootmap ALIGN (4096) : {
+		__bootmap = . ;
+		. = . + 4096 ;		/* enough for 128MB.   */
+	} > SRAM
+
+	/* Device contents for the root filesystem.  */
+	.root : {
+		__root_fs_image_start = . ;
+		*(.root)
+		__root_fs_image_end = . ;
+	} > SDRAM
+}
diff -Nru a/arch/v850/rte_ma1_cb-rom.ld b/arch/v850/rte_ma1_cb-rom.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/rte_ma1_cb-rom.ld	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,115 @@
+/* Linker script for the Midas labs RTE-V850E/MA1-CB evaluation board
+   (CONFIG_RTE_CB_MA1), with kernel in ROM.  */
+
+/* Note, all symbols are prefixed with an extra `_' for compatibility with
+   the existing linux sources.  */
+
+_jiffies = _jiffies_64 ;
+
+MEMORY {
+       ROM   : ORIGIN = 0x00000000, LENGTH = 0x00100000
+       /* 1MB of SRAM.  This memory is mirrored 4 times.  */
+       SRAM  : ORIGIN = 0x00400000, LENGTH = 0x00100000
+       /* 32MB of SDRAM.  */
+       SDRAM : ORIGIN = 0x00800000, LENGTH = 0x02000000
+}
+
+SECTIONS {
+	/* Interrupt vector space.  */
+	.intv {
+		__intv_start = . ;
+	        	*(.intv.reset)	/* Reset vector */
+			*(.intv.common) /* Vectors common to all v850e proc. */
+			*(.intv.mach)   /* Machine-specific int. vectors.  */
+		__intv_end = . ;
+	} > ROM
+
+	.text : {
+		__stext = . ;
+        	*(.text)
+			*(.exit.text)	/* 2.5 convention */
+			*(.text.exit)	/* 2.4 convention */
+			*(.text.lock)
+			*(.exitcall.exit)
+		__real_etext = . ;	/* There may be data after here.  */
+			*(.rodata)
+		. = ALIGN (0x4) ;
+			*(.kstrtab)
+		. = ALIGN (16) ;	/* Exception table.  */
+		___start___ex_table = . ;
+			*(__ex_table)
+		___stop___ex_table = . ;
+
+		___start___ksymtab = . ;/* Kernel symbol table.  */
+			*(__ksymtab)
+		___stop___ksymtab = . ;
+		. = ALIGN (4) ;
+		__etext = . ;
+	} > ROM
+
+	__data_load_start = . ;
+
+	.data : {
+	        __kram_start = . ;
+
+		__sdata = . ;
+		___data_start = . ;
+        	*(.data)
+			*(.exit.data)	/* 2.5 convention */
+			*(.data.exit)	/* 2.4 convention */
+		. = ALIGN (16) ;
+		*(.data.cacheline_aligned)
+		. = ALIGN (0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN (0x2000) ;
+		__edata = . ;
+	} > SRAM  AT> ROM
+
+	.bss ALIGN (0x4) : {
+		__sbss = . ;
+			*(.bss)
+			*(COMMON)
+		. = ALIGN (4) ;
+		__init_stack_end = . ;
+		__ebss = . ;
+	} > SRAM
+
+	.init ALIGN (4096) : {
+		__init_start = . ;
+			*(.init.text)	/* 2.5 convention */
+			*(.init.data)
+			*(.text.init)	/* 2.4 convention */
+			*(.data.init)
+		. = ALIGN (16) ;
+		___setup_start = . ;
+			*(.init.setup)	/* 2.5 convention */
+			*(.setup.init)	/* 2.4 convention */
+		___setup_end = . ;
+		___initcall_start = . ;
+			*(.initcall.init)
+			*(.initcall1.init)
+			*(.initcall2.init)
+			*(.initcall3.init)
+			*(.initcall4.init)
+			*(.initcall5.init)
+			*(.initcall6.init)
+			*(.initcall7.init)
+		. = ALIGN (4) ;
+		___initcall_end = . ;
+		__init_end = . ;
+
+		__kram_end = . ;
+	} > SRAM
+
+	.bootmap ALIGN (4096) : {
+		__bootmap = . ;
+		. = . + 4096 ;		/* enough for 128MB.   */
+	} > SRAM
+
+	/* device contents for the root filesystem.  */
+	.root ALIGN (4096) {
+		__root_fs_image_start = . ;
+		*(.root)
+		__root_fs_image_end = . ;
+	} > SDRAM
+}
diff -Nru a/arch/v850/rte_ma1_cb.ld b/arch/v850/rte_ma1_cb.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/rte_ma1_cb.ld	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,152 @@
+/* Linker script for the Midas labs RTE-V850E/MA1-CB evaluation board
+   (CONFIG_RTE_CB_MA1), with kernel in SDRAM, under Multi debugger.  */
+
+/* Note, all symbols are prefixed with an extra `_' for compatibility with
+   the existing linux sources.  */
+
+_jiffies = _jiffies_64 ;
+
+MEMORY {
+       /* 1MB of SRAM; we can't use the last 32KB, because it's used by
+          the monitor scratch-RAM.  This memory is mirrored 4 times.  */
+       SRAM  : ORIGIN = 0x00400000, LENGTH = 0x000F8000
+       /* Monitor scratch RAM; only the interrupt vectors should go here.  */
+       MRAM  : ORIGIN = 0x004F8000, LENGTH = 0x00008000
+       /* 32MB of SDRAM.  */
+       SDRAM : ORIGIN = 0x00800000, LENGTH = 0x02000000
+}
+
+SECTIONS {
+	.bootmap : {
+		__bootmap = . ;
+		. = . + 4096 ;		/* enough for 128MB.   */
+	} > SRAM
+
+	.text : {
+		 __kram_start = . ;
+
+		__stext = . ;
+        	*(.text)
+			*(.exit.text)	/* 2.5 convention */
+			*(.text.exit)	/* 2.4 convention */
+			*(.text.lock)
+			*(.exitcall.exit)
+		__real_etext = . ;	/* There may be data after here.  */
+			*(.rodata)
+
+		. = ALIGN (0x4) ;
+			*(.kstrtab)
+
+		. = ALIGN (4) ;
+		    	*(.call_table_data)
+			*(.call_table_text)
+
+		. = ALIGN (16) ;	/* Exception table.  */
+		___start___ex_table = . ;
+			*(__ex_table)
+		___stop___ex_table = . ;
+
+		___start___ksymtab = . ;/* Kernel symbol table.  */
+			*(__ksymtab)
+		___stop___ksymtab = . ;
+		. = ALIGN (4) ;
+		__etext = . ;
+	} > SDRAM
+
+	.data ALIGN (0x4) : {
+		__sdata = . ;
+		___data_start = . ;
+        	*(.data)
+			*(.exit.data)	/* 2.5 convention */
+			*(.data.exit)	/* 2.4 convention */
+		. = ALIGN (16) ;
+		*(.data.cacheline_aligned)
+		. = ALIGN (0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN (0x2000) ;
+		__edata = . ;
+	} > SDRAM
+
+	.bss ALIGN (0x4) : {
+		__sbss = . ;
+			*(.bss)
+			*(COMMON)
+		. = ALIGN (4) ;
+		__init_stack_end = . ;
+		__ebss = . ;
+	} > SDRAM
+
+	.init ALIGN (4096) : {
+		__init_start = . ;
+			*(.init.text)	/* 2.5 convention */
+			*(.init.data)
+			*(.text.init)	/* 2.4 convention */
+			*(.data.init)
+		. = ALIGN (16) ;
+		___setup_start = . ;
+			*(.init.setup)	/* 2.5 convention */
+			*(.setup.init)	/* 2.4 convention */
+		___setup_end = . ;
+		___initcall_start = . ;
+			*(.initcall.init)
+			*(.initcall1.init)
+			*(.initcall2.init)
+			*(.initcall3.init)
+			*(.initcall4.init)
+			*(.initcall5.init)
+			*(.initcall6.init)
+			*(.initcall7.init)
+		. = ALIGN (4) ;
+		___initcall_end = . ;
+	} > SDRAM
+
+	/* This provides address at which the interrupt vectors are
+	   initially loaded by the loader.  */
+	__intv_load_start = ALIGN (0x10) ;
+
+	/* Interrupt vector space.  Because we're using the monitor
+	   ROM, Instead of the native interrupt vector, we must use the
+	   `alternate interrupt vector' area.  Note that this is in
+	   `SRAM' space, which is not currently used by the kernel (the
+	   kernel uses `SDRAM' space).  */
+
+	/* We can't load the interrupt vectors directly into their
+	   target location, because the monitor ROM for the GHS Multi
+	   debugger barfs if we try.  Unfortunately, Multi also doesn't
+	   deal correctly with ELF sections where the LMA and VMA differ
+	   (it just ignores the LMA), so we can't use that feature to
+	   work around the problem!  What we do instead is just put the
+	   interrupt vectors into a normal section, and have the
+	   `mach_early_init' function for Midas boards do the necessary
+	   copying and relocation at runtime (this section basically
+	   only contains `jr' instructions, so it's not that hard).
+
+	   This the section structure I initially tried to use (which more
+	   accurately expresses the intent):
+
+		.intv 0x007F8000 : AT (ADDR (.init) + SIZEOF (.init)) {
+		    ...
+		} > MRAM
+	*/
+
+	.intv ALIGN (0x10) : {
+		__intv_start = . ;
+	        	*(.intv.reset)	/* Reset vector */
+			*(.intv.common) /* Vectors common to all v850e proc. */
+			*(.intv.mach)   /* Machine-specific int. vectors.  */
+		__intv_end = . ;
+
+		/* This is here so that when we free init memory, the initial
+		   load-area of the interrupt vectors is freed too.  */
+		__init_end = __intv_end;
+
+		__kram_end = . ;
+	} > SDRAM
+
+	/* Device contents for the root filesystem.  */
+	.root ALIGN (4096) : {
+		__root_fs_image_start = . ;
+		*(.root)
+		__root_fs_image_end = . ;
+	} > SDRAM
+}
diff -Nru a/arch/v850/sim.ld b/arch/v850/sim.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/sim.ld	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,108 @@
+/* Linker script for the gdb v850e simulator (CONFIG_V850E_SIM).  */
+
+/* Note, all symbols are prefixed with an extra `_' for compatibility with
+   the existing linux sources.  */
+
+_jiffies = _jiffies_64 ;
+
+MEMORY {
+       /* Interrupt vectors.  */
+       INTV  : ORIGIN = 0x0, LENGTH = 0xe0
+       /* 16MB of RAM.
+          This must match RAM_ADDR and RAM_SIZE in include/asm-v580/sim.h  */
+       RAM   : ORIGIN = 0x8F000000, LENGTH = 0x01000000
+}
+
+SECTIONS {
+	.intv : {
+		__intv_start = . ;
+			*(.intv.reset)	/* Reset vector */
+			*(.intv.common)	/* Vectors common to all v850e proc. */
+			*(.intv.mach)	/* Machine-specific int. vectors.  */
+		__intv_end = . ;
+	} > INTV
+
+	.text : {
+		__kram_start = . ;
+
+		__stext = . ;
+        	*(.text)
+			*(.exit.text)	/* 2.5 convention */
+			*(.text.exit)	/* 2.4 convention */
+			*(.text.lock)
+			*(.exitcall.exit)
+		__real_etext = . ;	/* There may be data after here.  */
+			*(.rodata)
+		. = ALIGN (0x4) ;
+			*(.kstrtab)
+
+		. = ALIGN (4) ;
+		    	*(.call_table_data)
+			*(.call_table_text)
+
+		. = ALIGN (16) ;	/* Exception table.  */
+		___start___ex_table = . ;
+			*(__ex_table)
+		___stop___ex_table = . ;
+
+		___start___ksymtab = . ;/* Kernel symbol table.  */
+			*(__ksymtab)
+		___stop___ksymtab = . ;
+		. = ALIGN (4) ;
+		__etext = . ;
+	} > RAM
+
+	.data ALIGN (0x4) : {
+		__sdata = . ;
+        	*(.data)
+			*(.exit.data)	/* 2.5 convention */
+			*(.data.exit)	/* 2.4 convention */
+		. = ALIGN (16) ;
+		*(.data.cacheline_aligned)
+		. = ALIGN (0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN (0x2000) ;
+		__edata = . ;
+	} > RAM
+
+	.bss ALIGN (0x4) : {
+		__sbss = . ;
+			*(.bss)
+			*(COMMON)
+		. = ALIGN (4) ;
+		__init_stack_end = . ;
+		__ebss = . ;
+	} > RAM
+
+	.init ALIGN (4096) : {
+		__init_start = . ;
+			*(.init.text)	/* 2.5 convention */
+			*(.init.data)
+			*(.text.init)	/* 2.4 convention */
+			*(.data.init)
+		. = ALIGN (16) ;
+		___setup_start = . ;
+			*(.init.setup)	/* 2.5 convention */
+			*(.setup.init)	/* 2.4 convention */
+		___setup_end = . ;
+		___initcall_start = . ;
+			*(.initcall.init)
+			*(.initcall1.init)
+			*(.initcall2.init)
+			*(.initcall3.init)
+			*(.initcall4.init)
+			*(.initcall5.init)
+			*(.initcall6.init)
+			*(.initcall7.init)
+		. = ALIGN (4) ;
+		___initcall_end = . ;
+		__init_end = . ;
+
+		__kram_end = . ;
+	} > RAM
+
+	.bootmap ALIGN (4096) : {
+		__bootmap = . ;
+		. = . + 4096 ;		/* enough for 128MB.   */
+	} > RAM
+}
diff -Nru a/arch/v850/sim85e2c.ld b/arch/v850/sim85e2c.ld
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/sim85e2c.ld	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,135 @@
+/* Linker script for the sim85e2c simulator, which is a verilog simulation of
+   the V850E2 NA85E2C cpu core (CONFIG_V850E2_SIM85E2C).  */
+
+/* Note, all symbols are prefixed with an extra `_' for compatibility with
+   the existing linux sources.  */
+
+_jiffies = _jiffies_64 ;
+
+MEMORY {
+       /* 1MB of `instruction RAM', starting at 0.
+          Instruction fetches are much faster from IRAM than from DRAM.
+	  This should match IRAM_ADDR in "include/asm-v580/sim85e2c.h".    */
+       IRAM	: ORIGIN = 0x00000000, LENGTH = 0x00100000
+
+       /* 1MB of `data RAM', below and contiguous with the I/O space.
+          Data fetches are much faster from DRAM than from IRAM.
+	  This should match DRAM_ADDR in "include/asm-v580/sim85e2c.h".  */
+       DRAM	: ORIGIN = 0xfff00000, LENGTH = 0x000ff000
+       /* We have to load DRAM at a mirror-address of 0x1ff00000,
+          because the simulator's preprocessing script isn't smart
+          enough to deal with the above LMA.  */
+       DRAM_LOAD : ORIGIN = 0x1ff00000, LENGTH = 0x000ff000
+
+       /* `external ram' (CS1 area), comes after IRAM.
+          This should match ERAM_ADDR in "include/asm-v580/sim85e2c.h".  */
+       ERAM	: ORIGIN = 0x00100000, LENGTH = 0x07f00000
+}
+
+SECTIONS {
+	.intv : {
+		__intv_start = . ;
+		*(.intv)		/* Interrupt vectors.  */
+	        	*(.intv.reset)	/* Reset vector */
+			*(.intv.common) /* Vectors common to all v850e proc. */
+			*(.intv.mach)   /* Machine-specific int. vectors.  */
+		__intv_end = . ;
+	} > IRAM
+
+	.text : {
+		__stext = . ;
+        	*(.text)
+			*(.exit.text)	/* 2.5 convention */
+			*(.text.exit)	/* 2.4 convention */
+			*(.text.lock)
+			*(.exitcall.exit)
+		__real_etext = . ;	/* There may be data after here.  */
+			*(.rodata)
+		. = ALIGN (0x4) ;
+			*(.kstrtab)
+
+		. = ALIGN (4) ;
+		    	*(.call_table_data)
+			*(.call_table_text)
+
+		. = ALIGN (16) ;	/* Exception table.  */
+		___start___ex_table = . ;
+			*(__ex_table)
+		___stop___ex_table = . ;
+
+		___start___ksymtab = . ;/* Kernel symbol table.  */
+			*(__ksymtab)
+		___stop___ksymtab = . ;
+		. = ALIGN (4) ;
+		__etext = . ;
+	} > IRAM
+
+	.init ALIGN (4096) : {
+		__init_start = . ;
+			*(.init.text)	/* 2.5 convention */
+			*(.init.data)
+			*(.text.init)	/* 2.4 convention */
+			*(.data.init)
+		. = ALIGN (16) ;
+		___setup_start = . ;
+			*(.init.setup)	/* 2.5 convention */
+			*(.setup.init)	/* 2.4 convention */
+		___setup_end = . ;
+		___initcall_start = . ;
+			*(.initcall.init)
+			*(.initcall1.init)
+			*(.initcall2.init)
+			*(.initcall3.init)
+			*(.initcall4.init)
+			*(.initcall5.init)
+			*(.initcall6.init)
+			*(.initcall7.init)
+		. = ALIGN (4) ;
+		___initcall_end = . ;
+		__init_end = . ;
+	} > IRAM
+
+	.data : {
+	        __kram_start = . ;
+
+		__sdata = . ;
+        	*(.data)
+			*(.exit.data)	/* 2.5 convention */
+			*(.data.exit)	/* 2.4 convention */
+		. = ALIGN (16) ;
+		*(.data.cacheline_aligned)
+		. = ALIGN (0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN (0x2000) ;
+		__edata = . ;
+	} > DRAM  AT> DRAM_LOAD
+
+	.bss ALIGN (0x4) : {
+		__sbss = . ;
+			*(.bss)
+			*(COMMON)
+		. = ALIGN (4) ;
+		__init_stack_end = . ;
+		__ebss = . ;
+	} > DRAM  AT> DRAM_LOAD
+
+	/* Device contents for the root filesystem.  */
+	.root ALIGN (4096) : {
+		__root_fs_image_start = . ;
+		*(.root)
+		__root_fs_image_end = . ;
+	} > DRAM  AT> DRAM_LOAD
+
+	.memcons : {
+		_memcons_output = . ;
+		. = . + 0x8000 ;
+		_memcons_output_end = . ;
+
+	        __kram_end = . ;
+	} > DRAM  AT> DRAM_LOAD
+
+	.bootmap ALIGN (4096) : {
+		__bootmap = . ;
+		. = . + 4096 ;		/* enough for 128MB.   */
+	} > DRAM  AT> DRAM_LOAD
+}
diff -Nru a/arch/v850/vmlinux.lds.S b/arch/v850/vmlinux.lds.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/v850/vmlinux.lds.S	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,31 @@
+#include <linux/config.h>
+
+#ifdef CONFIG_V850E_SIM
+# include "sim.ld"
+#endif
+
+#ifdef CONFIG_V850E2_SIM85E2C
+# include "sim85e2c.ld"
+#endif
+
+#ifdef CONFIG_V850E2_FPGA85E2C
+# include "fpga85e2c.ld"
+#endif
+
+#ifdef CONFIG_V850E2_ANNA
+# ifdef CONFIG_ROM_KERNEL
+#  include "anna-rom.ld"
+# else
+#  include "anna.ld"
+# endif
+#endif
+
+#ifdef CONFIG_RTE_CB_MA1
+# ifdef CONFIG_ROM_KERNEL
+#  include "rte_ma1_cb-rom.ld"
+# elif CONFIG_RTE_CB_MA1_KSRAM
+#  include "rte_ma1_cb-ksram.ld"
+# else /* !CONFIG_ROM_KERNEL && !CONFIG_RTE_CB_MA1_KSRAM */
+#  include "rte_ma1_cb.ld"
+# endif /* CONFIG_ROM_KERNEL */
+#endif /* CONFIG_RTE_CB_MA1 */
diff -Nru a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
--- a/arch/x86_64/Kconfig	Mon Nov  4 14:31:02 2002
+++ b/arch/x86_64/Kconfig	Mon Nov  4 14:31:02 2002
@@ -25,6 +25,14 @@
 	  486, 586, Pentiums, and various instruction-set-compatible chips by
 	  AMD, Cyrix, and others.
 
+config MMU
+	bool
+	default y
+
+config SWAP
+	bool
+	default y
+
 config ISA
 	bool
 	help
diff -Nru a/arch/x86_64/ia32/ptrace32.c b/arch/x86_64/ia32/ptrace32.c
--- a/arch/x86_64/ia32/ptrace32.c	Mon Nov  4 14:31:01 2002
+++ b/arch/x86_64/ia32/ptrace32.c	Mon Nov  4 14:31:01 2002
@@ -185,17 +185,6 @@
 	__u32 val;
 
 	switch (request) { 
-	case PTRACE_TRACEME:
-	case PTRACE_ATTACH:
-	case PTRACE_SYSCALL:
-	case PTRACE_CONT:
-	case PTRACE_KILL:
-	case PTRACE_SINGLESTEP:
-	case PTRACE_DETACH:
-	case PTRACE_SETOPTIONS:
-		ret = sys_ptrace(request, pid, addr, data); 
-		return ret;
-
 	case PTRACE_PEEKTEXT:
 	case PTRACE_PEEKDATA:
 	case PTRACE_POKEDATA:
@@ -211,7 +200,8 @@
 		break;
 		
 	default:
-		return -EIO;
+		ret = sys_ptrace(request, pid, addr, data); 
+		return ret;
 	} 
 
 	child = find_target(request, pid, &ret);
diff -Nru a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c
--- a/arch/x86_64/kernel/irq.c	Mon Nov  4 14:31:01 2002
+++ b/arch/x86_64/kernel/irq.c	Mon Nov  4 14:31:01 2002
@@ -151,7 +151,7 @@
 #else
 		for_each_cpu(j) 
 			seq_printf(p, "%10u ",
-				kstat.irqs[j][i]);
+				kstat_cpu(j).irqs[i]);
 #endif
 		seq_printf(p, " %14s", irq_desc[i].handler->typename);
 		seq_printf(p, "  %s", action->name);
@@ -328,7 +328,7 @@
 	if (irq > 256) BUG();
 
 	irq_enter(); 
-	kstat.irqs[cpu][irq]++;
+	kstat_cpu(cpu).irqs[irq]++;
 	spin_lock(&desc->lock);
 	desc->handler->ack(irq);
 	/*
diff -Nru a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
--- a/arch/x86_64/kernel/process.c	Mon Nov  4 14:31:00 2002
+++ b/arch/x86_64/kernel/process.c	Mon Nov  4 14:31:00 2002
@@ -59,7 +59,7 @@
 asmlinkage extern void ret_from_fork(void);
 int sys_arch_prctl(int code, unsigned long addr);
 
-unsigned long kernel_thread_flags = CLONE_VM;
+unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED;
 
 int hlt_counter;
 
diff -Nru a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c
--- a/arch/x86_64/kernel/ptrace.c	Mon Nov  4 14:31:01 2002
+++ b/arch/x86_64/kernel/ptrace.c	Mon Nov  4 14:31:01 2002
@@ -405,17 +405,8 @@
 		break;
 	}
 
-	case PTRACE_SETOPTIONS: {
-		if (data & PTRACE_O_TRACESYSGOOD)
-			child->ptrace |= PT_TRACESYSGOOD;
-		else
-			child->ptrace &= ~PT_TRACESYSGOOD;
-		ret = 0;
-		break;
-	}
-
 	default:
-		ret = -EIO;
+		ret = ptrace_request(child, request, addr, data);
 		break;
 	}
 out_tsk:
diff -Nru a/drivers/Makefile b/drivers/Makefile
--- a/drivers/Makefile	Mon Nov  4 14:31:02 2002
+++ b/drivers/Makefile	Mon Nov  4 14:31:02 2002
@@ -6,6 +6,7 @@
 #
 
 obj-$(CONFIG_PCI)		+= pci/
+obj-$(CONFIG_PARISC)		+= parisc/
 obj-$(CONFIG_ACPI)		+= acpi/
 obj-y				+= serial/
 obj-$(CONFIG_PARPORT)		+= parport/
diff -Nru a/drivers/acorn/block/fd1772.c b/drivers/acorn/block/fd1772.c
--- a/drivers/acorn/block/fd1772.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/acorn/block/fd1772.c	Mon Nov  4 14:31:01 2002
@@ -1206,7 +1206,7 @@
 
 static void redo_fd_request(void)
 {
-	int device, drive, type;
+	int drive, type;
 	struct archy_floppy_struct *floppy;
 
 	DPRINT(("redo_fd_request: CURRENT=%p dev=%s CURRENT->sector=%ld\n",
@@ -1218,10 +1218,9 @@
 	if (blk_queue_empty(QUEUE))
 		goto the_end;
 
-	device = minor(CURRENT->rq_dev);
-	drive = device & 3;
-	type = device >> 2;
-	floppy = &unit[drive];
+	floppy = CURRENT->rq_disk->private_data;
+	drive = floppy - unit;
+	type = fd_device[drive];
 
 	if (!floppy->connected) {
 		/* drive not connected */
@@ -1463,13 +1462,11 @@
 static int floppy_open(struct inode *inode, struct file *filp)
 {
 	int drive = minor(inode->i_rdev) & 3;
-	int old_dev;
+	int type =  minor(inode->i_rdev) >> 2;
+	int old_dev = fd_device[drive];
 
-	old_dev = fd_device[drive];
-
-	if (fd_ref[drive])
-		if (old_dev != inode->i_rdev)
-			return -EBUSY;
+	if (fd_ref[drive] && old_dev != type)
+		return -EBUSY;
 
 	if (fd_ref[drive] == -1 || (fd_ref[drive] && filp->f_flags & O_EXCL))
 		return -EBUSY;
@@ -1479,10 +1476,10 @@
 	else
 		fd_ref[drive]++;
 
-	fd_device[drive] = inode->i_rdev;
+	fd_device[drive] = type;
 
-	if (old_dev && old_dev != inode->i_rdev)
-		invalidate_buffers(old_dev);
+	if (old_dev && old_dev != type)
+		invalidate_buffers(mk_kdev(MAJOR_NR, drive + (old_dev<<2)));
 
 	if (filp->f_flags & O_NDELAY)
 		return 0;
diff -Nru a/drivers/acpi/Makefile b/drivers/acpi/Makefile
--- a/drivers/acpi/Makefile	Mon Nov  4 14:31:02 2002
+++ b/drivers/acpi/Makefile	Mon Nov  4 14:31:02 2002
@@ -32,7 +32,7 @@
 #
 # ACPI Bus and Device Drivers
 #
-obj-$(CONFIG_ACPI_BUS)		+= bus.o driverfs.o
+obj-$(CONFIG_ACPI_BUS)		+= bus.o
 obj-$(CONFIG_ACPI_AC) 		+= ac.o
 obj-$(CONFIG_ACPI_BATTERY)	+= battery.o
 obj-$(CONFIG_ACPI_BUTTON)	+= button.o
diff -Nru a/drivers/acpi/acpi_bus.h b/drivers/acpi/acpi_bus.h
--- a/drivers/acpi/acpi_bus.h	Mon Nov  4 14:31:01 2002
+++ b/drivers/acpi/acpi_bus.h	Mon Nov  4 14:31:01 2002
@@ -27,7 +27,7 @@
 #define __ACPI_BUS_H__
 
 #include <linux/version.h>
-#include <linux/driverfs_fs.h>
+#include <linux/kobject.h>
 
 #include "include/acpi.h"
 
@@ -255,7 +255,7 @@
 	struct acpi_device_ops	ops;
 	struct acpi_driver	*driver;
 	void			*driver_data;
-	struct driver_dir_entry	driverfs_dir;
+	struct kobject		kobj;
 };
 
 #define acpi_driver_data(d)	((d)->driver_data)
@@ -274,6 +274,7 @@
 	u32			data;
 };
 
+extern struct subsystem acpi_subsys;
 
 /*
  * External Functions
diff -Nru a/drivers/acpi/bus.c b/drivers/acpi/bus.c
--- a/drivers/acpi/bus.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/acpi/bus.c	Mon Nov  4 14:31:02 2002
@@ -675,6 +675,9 @@
 	return_VALUE(-ENODEV);
 }
 
+struct subsystem acpi_subsys = {
+	.kobj	= { .name = "acpi" },
+};
 
 static int __init acpi_init (void)
 {
@@ -692,6 +695,8 @@
 		printk(KERN_INFO PREFIX "Disabled via command line (acpi=off)\n");
 		return -ENODEV;
 	}
+
+	firmware_register(&acpi_subsys);
 
 	result = acpi_bus_init();
 
diff -Nru a/drivers/acpi/driverfs.c b/drivers/acpi/driverfs.c
--- a/drivers/acpi/driverfs.c	Mon Nov  4 14:31:01 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,46 +0,0 @@
-/*
- * driverfs.c - ACPI bindings for driverfs.
- *
- * Copyright (c) 2002 Patrick Mochel
- * Copyright (c) 2002 The Open Source Development Lab
- *
- */
-
-#include <linux/stat.h>
-#include <linux/init.h>
-#include <linux/driverfs_fs.h>
-
-#include "acpi_bus.h"
-
-static struct driver_dir_entry acpi_dir = {
-	.name		= "acpi",
-	.mode	= (S_IRWXU | S_IRUGO | S_IXUGO),
-};
- 
-/* driverfs ops for ACPI attribute files go here, when/if
- * there are ACPI attribute files. 
- * For now, we just have directory creation and removal.
- */
-
-void acpi_remove_dir(struct acpi_device * dev)
-{
-	if (dev)
-		driverfs_remove_dir(&dev->driverfs_dir);
-}
-
-int acpi_create_dir(struct acpi_device * dev)
-{
-	struct driver_dir_entry * parent;
-
-	parent = dev->parent ? &dev->parent->driverfs_dir : &acpi_dir;
-	dev->driverfs_dir.name = dev->pnp.bus_id;
-	dev->driverfs_dir.mode  = (S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO);
-	return driverfs_create_dir(&dev->driverfs_dir,parent);
-}
-
-static int __init acpi_driverfs_init(void)
-{
-	return driverfs_create_dir(&acpi_dir,NULL);
-}
-
-subsys_initcall(acpi_driverfs_init);
diff -Nru a/drivers/acpi/events/evxfregn.c b/drivers/acpi/events/evxfregn.c
--- a/drivers/acpi/events/evxfregn.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/acpi/events/evxfregn.c	Mon Nov  4 14:31:01 2002
@@ -2,7 +2,7 @@
  *
  * Module Name: evxfregn - External Interfaces, ACPI Operation Regions and
  *                         Address Spaces.
- *              $Revision: 51 $
+ *              $Revision: 52 $
  *
  *****************************************************************************/
 
@@ -210,8 +210,8 @@
 	}
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
-		"Installing address handler for region %s(%X) on Device %p(%p)\n",
-		acpi_ut_get_region_name (space_id), space_id, node, obj_desc));
+		"Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
+		acpi_ut_get_region_name (space_id), space_id, node->name.ascii, node, obj_desc));
 
 	/*
 	 * Now we can install the handler
diff -Nru a/drivers/acpi/include/acconfig.h b/drivers/acpi/include/acconfig.h
--- a/drivers/acpi/include/acconfig.h	Mon Nov  4 14:31:02 2002
+++ b/drivers/acpi/include/acconfig.h	Mon Nov  4 14:31:02 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acconfig.h - Global configuration constants
- *       $Revision: 114 $
+ *       $Revision: 115 $
  *
  *****************************************************************************/
 
@@ -54,7 +54,7 @@
 
 /* Version string */
 
-#define ACPI_CA_VERSION                 0x20021022
+#define ACPI_CA_VERSION                 0x20021101
 
 /* Version of ACPI supported */
 
diff -Nru a/drivers/acpi/include/acparser.h b/drivers/acpi/include/acparser.h
--- a/drivers/acpi/include/acparser.h	Mon Nov  4 14:31:02 2002
+++ b/drivers/acpi/include/acparser.h	Mon Nov  4 14:31:02 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: acparser.h - AML Parser subcomponent prototypes and defines
- *       $Revision: 62 $
+ *       $Revision: 63 $
  *
  *****************************************************************************/
 
@@ -89,9 +89,9 @@
 
 acpi_status
 acpi_ps_get_next_namepath (
+	acpi_walk_state         *walk_state,
 	acpi_parse_state        *parser_state,
 	acpi_parse_object       *arg,
-	u32                     *arg_count,
 	u8                      method_call);
 
 acpi_parse_object *
@@ -100,9 +100,9 @@
 
 acpi_status
 acpi_ps_get_next_arg (
+	acpi_walk_state         *walk_state,
 	acpi_parse_state        *parser_state,
 	u32                     arg_type,
-	u32                     *arg_count,
 	acpi_parse_object       **return_arg);
 
 
diff -Nru a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c
--- a/drivers/acpi/namespace/nsalloc.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/acpi/namespace/nsalloc.c	Mon Nov  4 14:31:02 2002
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: nsalloc - Namespace allocation and deletion utilities
- *              $Revision: 75 $
+ *              $Revision: 77 $
  *
  ******************************************************************************/
 
@@ -125,6 +125,7 @@
 }
 
 
+#ifdef ACPI_ALPHABETIC_NAMESPACE
 /*******************************************************************************
  *
  * FUNCTION:    Acpi_ns_compare_names
@@ -170,8 +171,9 @@
 		}
 	}
 
-	return (*(s32 *) reversed_name1 - *(s32 *) reversed_name2);
+	return (*(int *) reversed_name1 - *(int *) reversed_name2);
 }
+#endif
 
 
 /*******************************************************************************
@@ -204,7 +206,10 @@
 {
 	u16                     owner_id = TABLE_ID_DSDT;
 	acpi_namespace_node     *child_node;
+#ifdef ACPI_ALPHABETIC_NAMESPACE
+
 	acpi_namespace_node     *previous_child_node;
+#endif
 
 
 	ACPI_FUNCTION_TRACE ("Ns_install_node");
@@ -228,6 +233,7 @@
 		node->peer = parent_node;
 	}
 	else {
+#ifdef ACPI_ALPHABETIC_NAMESPACE
 		/*
 		 * Walk the list whilst searching for the the correct
 		 * alphabetic placement.
@@ -276,6 +282,19 @@
 				parent_node->child = node;
 			}
 		}
+#else
+		while (!(child_node->flags & ANOBJ_END_OF_PEER_LIST)) {
+			child_node = child_node->peer;
+		}
+
+		child_node->peer = node;
+
+		/* Clear end-of-list flag */
+
+		child_node->flags &= ~ANOBJ_END_OF_PEER_LIST;
+		node->flags     |= ANOBJ_END_OF_PEER_LIST;
+		node->peer = parent_node;
+#endif
 	}
 
 	/* Init the new entry */
diff -Nru a/drivers/acpi/osl.c b/drivers/acpi/osl.c
--- a/drivers/acpi/osl.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/acpi/osl.c	Mon Nov  4 14:31:02 2002
@@ -30,6 +30,7 @@
 #include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/pci.h>
+#include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/kmod.h>
 #include <linux/delay.h>
@@ -717,6 +718,9 @@
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Waiting for semaphore[%p|%d|%d]\n", handle, units, timeout));
 
+	if (in_atomic())
+		timeout = 0;
+
 	switch (timeout)
 	{
 		/*
@@ -838,7 +842,7 @@
 u32
 acpi_os_get_thread_id (void)
 {
-	if (!in_interrupt())
+	if (!in_atomic())
 		return current->pid;
 
 	return 0;
diff -Nru a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c
--- a/drivers/acpi/parser/psargs.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/acpi/parser/psargs.c	Mon Nov  4 14:31:01 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: psargs - Parse AML opcode arguments
- *              $Revision: 64 $
+ *              $Revision: 65 $
  *
  *****************************************************************************/
 
@@ -95,6 +95,7 @@
 		break;
 
 	default:
+
 		/* Can't get here, only 2 bits / 4 cases */
 		break;
 	}
@@ -127,6 +128,8 @@
 	ACPI_FUNCTION_TRACE ("Ps_get_next_package_end");
 
 
+	/* Function below changes Parser_state->Aml */
+
 	length = (NATIVE_UINT) acpi_ps_get_next_package_length (parser_state);
 
 	return_PTR (start + length); /* end of package */
@@ -184,21 +187,21 @@
 
 		/* Two name segments */
 
-		end += 9;
+		end += 1 + (2 * ACPI_NAME_SIZE);
 		break;
 
 	case AML_MULTI_NAME_PREFIX_OP:
 
 		/* Multiple name segments, 4 chars each */
 
-		end += 2 + ((ACPI_SIZE) ACPI_GET8 (end + 1) * 4);
+		end += 2 + ((ACPI_SIZE) ACPI_GET8 (end + 1) * ACPI_NAME_SIZE);
 		break;
 
 	default:
 
 		/* Single name segment */
 
-		end += 4;
+		end += ACPI_NAME_SIZE;
 		break;
 	}
 
@@ -215,8 +218,8 @@
  *              Arg                 - Where the namepath will be stored
  *              Arg_count           - If the namepath points to a control method
  *                                    the method's argument is returned here.
- *              Method_call         - Whether the namepath can be the start
- *                                    of a method call
+ *              Method_call         - Whether the namepath can possibly be the
+ *                                    start of a method call
  *
  * RETURN:      Status
  *
@@ -230,9 +233,9 @@
 
 acpi_status
 acpi_ps_get_next_namepath (
+	acpi_walk_state         *walk_state,
 	acpi_parse_state        *parser_state,
 	acpi_parse_object       *arg,
-	u32                     *arg_count,
 	u8                      method_call)
 {
 	NATIVE_CHAR             *path;
@@ -267,12 +270,15 @@
 		 * object  (MUST BE mode EXECUTE to perform upsearch)
 		 */
 		status = acpi_ns_lookup (&scope_info, path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
-				 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL,
-				 &node);
+				 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &node);
 		if (ACPI_SUCCESS (status) && method_call) {
 			if (node->type == ACPI_TYPE_METHOD) {
+				/*
+				 * This name is actually a control method invocation
+				 */
 				method_desc = acpi_ns_get_attached_object (node);
-				ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Control Method - %p Desc %p Path=%p\n",
+				ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+					"Control Method - %p Desc %p Path=%p\n",
 					node, method_desc, path));
 
 				name_op = acpi_ps_alloc_op (AML_INT_NAMEPATH_OP);
@@ -283,7 +289,6 @@
 				/* Change arg into a METHOD CALL and attach name to it */
 
 				acpi_ps_init_op (arg, AML_INT_METHODCALL_OP);
-
 				name_op->common.value.name = path;
 
 				/* Point METHODCALL/NAME to the METHOD Node */
@@ -292,15 +297,19 @@
 				acpi_ps_append_arg (arg, name_op);
 
 				if (!method_desc) {
-					ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Control Method - %p has no attached object\n",
+					ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+						"Control Method - %p has no attached object\n",
 						node));
 					return_ACPI_STATUS (AE_AML_INTERNAL);
 				}
 
-				ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Control Method - %p Args %X\n",
+				ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+					"Control Method - %p Args %X\n",
 					node, method_desc->method.param_count));
 
-				*arg_count = method_desc->method.param_count;
+				/* Get the number of arguments to expect */
+
+				walk_state->arg_count = method_desc->method.param_count;
 				return_ACPI_STATUS (AE_OK);
 			}
 
@@ -310,6 +319,29 @@
 			 * (See code below)
 			 */
 		}
+
+		if (ACPI_FAILURE (status)) {
+			/*
+			 * 1) Any error other than NOT_FOUND is always severe
+			 * 2) NOT_FOUND is only important if we are executing a method.
+			 * 3) If executing a Cond_ref_of opcode, NOT_FOUND is ok.
+			 */
+			if ((((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) &&
+				(status == AE_NOT_FOUND)                                                &&
+				(walk_state->op->common.aml_opcode != AML_COND_REF_OF_OP)) ||
+
+				(status != AE_NOT_FOUND)) {
+				ACPI_REPORT_NSERROR (path, status);
+			}
+			else {
+				/*
+				 * We got a NOT_FOUND during table load or we encountered
+				 * a Cond_ref_of(x) where the target does not exist.
+				 * -- either case is ok
+				 */
+				status = AE_OK;
+			}
+		}
 	}
 
 	/*
@@ -410,6 +442,7 @@
 
 
 	default:
+
 		ACPI_REPORT_ERROR (("Invalid Arg_type %X\n", arg_type));
 		break;
 	}
@@ -435,7 +468,7 @@
 	acpi_parse_state        *parser_state)
 {
 	u32                     aml_offset = ACPI_PTR_DIFF (parser_state->aml,
-			  parser_state->aml_start);
+			 parser_state->aml_start);
 	acpi_parse_object       *field;
 	u16                     opcode;
 	u32                     name;
@@ -484,7 +517,7 @@
 
 		ACPI_MOVE_UNALIGNED32_TO_32 (&name, parser_state->aml);
 		acpi_ps_set_name (field, name);
-		parser_state->aml += 4;
+		parser_state->aml += ACPI_NAME_SIZE;
 
 		/* Get the length which is encoded as a package length */
 
@@ -513,6 +546,7 @@
 		break;
 
 	default:
+
 		/* Opcode was set in previous switch */
 		break;
 	}
@@ -539,9 +573,9 @@
 
 acpi_status
 acpi_ps_get_next_arg (
+	acpi_walk_state         *walk_state,
 	acpi_parse_state        *parser_state,
 	u32                     arg_type,
-	u32                     *arg_count,
 	acpi_parse_object       **return_arg)
 {
 	acpi_parse_object       *arg = NULL;
@@ -620,7 +654,8 @@
 
 			/* Fill in bytelist data */
 
-			arg->common.value.size = ACPI_PTR_DIFF (parser_state->pkg_end, parser_state->aml);
+			arg->common.value.size = ACPI_PTR_DIFF (parser_state->pkg_end,
+					  parser_state->aml);
 			arg->named.data = parser_state->aml;
 
 			/* Skip to End of byte data */
@@ -645,12 +680,12 @@
 				return_ACPI_STATUS (AE_NO_MEMORY);
 			}
 
-			status = acpi_ps_get_next_namepath (parser_state, arg, arg_count, 0);
+			status = acpi_ps_get_next_namepath (walk_state, parser_state, arg, 0);
 		}
 		else {
 			/* single complex argument, nothing returned */
 
-			*arg_count = 1;
+			walk_state->arg_count = 1;
 		}
 		break;
 
@@ -660,7 +695,7 @@
 
 		/* single complex argument, nothing returned */
 
-		*arg_count = 1;
+		walk_state->arg_count = 1;
 		break;
 
 
@@ -671,7 +706,7 @@
 		if (parser_state->aml < parser_state->pkg_end) {
 			/* non-empty list of variable arguments, nothing returned */
 
-			*arg_count = ACPI_VAR_ARGS;
+			walk_state->arg_count = ACPI_VAR_ARGS;
 		}
 		break;
 
diff -Nru a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c
--- a/drivers/acpi/parser/psparse.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/acpi/parser/psparse.c	Mon Nov  4 14:31:01 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: psparse - Parser top level AML parse routines
- *              $Revision: 133 $
+ *              $Revision: 134 $
  *
  *****************************************************************************/
 
@@ -460,7 +460,8 @@
 				status = acpi_ps_next_parse_state (walk_state, op, status);
 			}
 
-			acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count);
+			acpi_ps_pop_scope (parser_state, &op,
+				&walk_state->arg_types, &walk_state->arg_count);
 			ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", op));
 		}
 		else if (walk_state->prev_op) {
@@ -480,7 +481,8 @@
 		if (!op) {
 			/* Get the next opcode from the AML stream */
 
-			walk_state->aml_offset = ACPI_PTR_DIFF (parser_state->aml, parser_state->aml_start);
+			walk_state->aml_offset = ACPI_PTR_DIFF (parser_state->aml,
+					   parser_state->aml_start);
 			walk_state->opcode   = acpi_ps_peek_opcode (parser_state);
 
 			/*
@@ -537,9 +539,8 @@
 				 */
 				while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) &&
 					  (GET_CURRENT_ARG_TYPE (walk_state->arg_types) != ARGP_NAME)) {
-					status = acpi_ps_get_next_arg (parser_state,
-							 GET_CURRENT_ARG_TYPE (walk_state->arg_types),
-							 &walk_state->arg_count, &arg);
+					status = acpi_ps_get_next_arg (walk_state, parser_state,
+							 GET_CURRENT_ARG_TYPE (walk_state->arg_types), &arg);
 					if (ACPI_FAILURE (status)) {
 						goto close_this_op;
 					}
@@ -593,7 +594,7 @@
 					 * Defer final parsing of an Operation_region body,
 					 * because we don't have enough info in the first pass
 					 * to parse it correctly (i.e., there may be method
-					 * calls within the Term_arg elements of the body.
+					 * calls within the Term_arg elements of the body.)
 					 *
 					 * However, we must continue parsing because
 					 * the opregion is not a standalone package --
@@ -673,20 +674,14 @@
 				/* Fill in constant or string argument directly */
 
 				acpi_ps_get_next_simple_arg (parser_state,
-						 GET_CURRENT_ARG_TYPE (walk_state->arg_types), op);
+					GET_CURRENT_ARG_TYPE (walk_state->arg_types), op);
 				break;
 
 			case AML_INT_NAMEPATH_OP:   /* AML_NAMESTRING_ARG */
 
-				status = acpi_ps_get_next_namepath (parser_state, op, &walk_state->arg_count, 1);
+				status = acpi_ps_get_next_namepath (walk_state, parser_state, op, 1);
 				if (ACPI_FAILURE (status)) {
-					/* NOT_FOUND is an error only if we are actually executing a method */
-
-					if ((((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) &&
-							(status == AE_NOT_FOUND)) ||
-						(status != AE_NOT_FOUND)) {
-						goto close_this_op;
-					}
+					goto close_this_op;
 				}
 
 				walk_state->arg_types = 0;
@@ -697,21 +692,14 @@
 
 				/* Op is not a constant or string, append each argument */
 
-				while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) && !walk_state->arg_count) {
+				while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) &&
+						!walk_state->arg_count) {
 					walk_state->aml_offset = ACPI_PTR_DIFF (parser_state->aml,
 							   parser_state->aml_start);
-					status = acpi_ps_get_next_arg (parser_state,
-							 GET_CURRENT_ARG_TYPE (walk_state->arg_types),
-							 &walk_state->arg_count, &arg);
+					status = acpi_ps_get_next_arg (walk_state, parser_state,
+							 GET_CURRENT_ARG_TYPE (walk_state->arg_types), &arg);
 					if (ACPI_FAILURE (status)) {
-						/* NOT_FOUND is an error only if we are actually executing a method */
-
-						if ((((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) &&
-								(status == AE_NOT_FOUND)                                            &&
-								(op->common.aml_opcode != AML_COND_REF_OF_OP)) ||
-							(status != AE_NOT_FOUND)) {
-							goto close_this_op;
-						}
+						goto close_this_op;
 					}
 
 					if (arg) {
@@ -784,7 +772,8 @@
 		if (walk_state->arg_count) {
 			/* There are arguments (complex ones), push Op and prepare for argument */
 
-			status = acpi_ps_push_scope (parser_state, op, walk_state->arg_types, walk_state->arg_count);
+			status = acpi_ps_push_scope (parser_state, op,
+					 walk_state->arg_types, walk_state->arg_count);
 			if (ACPI_FAILURE (status)) {
 				return_ACPI_STATUS (status);
 			}
@@ -866,7 +855,8 @@
 
 		case AE_CTRL_END:
 
-			acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count);
+			acpi_ps_pop_scope (parser_state, &op,
+				&walk_state->arg_types, &walk_state->arg_count);
 
 			if (op) {
 				walk_state->op    = op;
@@ -889,7 +879,8 @@
 			/* Pop off scopes until we find the While */
 
 			while (!op || (op->common.aml_opcode != AML_WHILE_OP)) {
-				acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count);
+				acpi_ps_pop_scope (parser_state, &op,
+					&walk_state->arg_types, &walk_state->arg_count);
 			}
 
 			/* Close this iteration of the While loop */
@@ -917,7 +908,8 @@
 				if (op) {
 					acpi_ps_complete_this_op (walk_state, op);
 				}
-				acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count);
+				acpi_ps_pop_scope (parser_state, &op,
+					&walk_state->arg_types, &walk_state->arg_count);
 
 			} while (op);
 
@@ -930,7 +922,8 @@
 				if (op) {
 					acpi_ps_complete_this_op (walk_state, op);
 				}
-				acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count);
+				acpi_ps_pop_scope (parser_state, &op,
+					&walk_state->arg_types, &walk_state->arg_count);
 
 			} while (op);
 
@@ -940,7 +933,8 @@
 			 */
 #if 0
 			if (op == NULL) {
-				acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count);
+				acpi_ps_pop_scope (parser_state, &op,
+					&walk_state->arg_types, &walk_state->arg_count);
 			}
 #endif
 			walk_state->prev_op = op;
@@ -951,7 +945,8 @@
 		/* This scope complete? */
 
 		if (acpi_ps_has_completed_scope (parser_state)) {
-			acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count);
+			acpi_ps_pop_scope (parser_state, &op,
+				&walk_state->arg_types, &walk_state->arg_count);
 			ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", op));
 		}
 		else {
@@ -991,7 +986,8 @@
 							acpi_ps_complete_this_op (walk_state, op);
 						}
 
-						acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count);
+						acpi_ps_pop_scope (parser_state, &op,
+							&walk_state->arg_types, &walk_state->arg_count);
 
 					} while (op);
 
@@ -1007,7 +1003,8 @@
 			acpi_ps_complete_this_op (walk_state, op);
 		}
 
-		acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count);
+		acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types,
+			&walk_state->arg_count);
 
 	} while (op);
 
@@ -1117,7 +1114,8 @@
 		if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) {
 			terminate_status = acpi_ds_terminate_control_method (walk_state);
 			if (ACPI_FAILURE (terminate_status)) {
-				ACPI_REPORT_ERROR (("Could not terminate control method properly\n"));
+				ACPI_REPORT_ERROR ((
+					"Could not terminate control method properly\n"));
 
 				/* Ignore error and continue */
 			}
@@ -1142,7 +1140,8 @@
 				 * If the method return value is not used by the parent,
 				 * The object is deleted
 				 */
-				status = acpi_ds_restart_control_method (walk_state, previous_walk_state->return_desc);
+				status = acpi_ds_restart_control_method (walk_state,
+						 previous_walk_state->return_desc);
 				if (ACPI_SUCCESS (status)) {
 					walk_state->walk_type |= ACPI_WALK_METHOD_RESTART;
 				}
@@ -1152,7 +1151,8 @@
 
 				acpi_ut_remove_reference (previous_walk_state->return_desc);
 
-				ACPI_REPORT_ERROR (("Method execution failed, %s\n", acpi_format_exception (status)));
+				ACPI_REPORT_ERROR (("Method execution failed, %s\n",
+					acpi_format_exception (status)));
 				ACPI_DUMP_PATHNAME (walk_state->method_node, "Method pathname: ",
 					ACPI_LV_ERROR, _COMPONENT);
 			}
diff -Nru a/drivers/acpi/processor.c b/drivers/acpi/processor.c
--- a/drivers/acpi/processor.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/acpi/processor.c	Mon Nov  4 14:31:02 2002
@@ -1761,6 +1761,9 @@
 
 	ACPI_FUNCTION_TRACE("acpi_cpufreq_init");
 
+	if (!pr->flags.performance)
+		return_VALUE(0);
+
 	if (cpufreq_usage_count) {
 		if (pr->flags.performance == 1)
 			cpufreq_usage_count++;
diff -Nru a/drivers/acpi/scan.c b/drivers/acpi/scan.c
--- a/drivers/acpi/scan.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/acpi/scan.c	Mon Nov  4 14:31:01 2002
@@ -25,20 +25,52 @@
 static LIST_HEAD(acpi_device_list);
 static spinlock_t acpi_device_lock = SPIN_LOCK_UNLOCKED;
 
-static int
-acpi_device_register (
-	struct acpi_device	*device,
-	struct acpi_device	*parent)
+static void acpi_device_release(struct kobject * kobj)
 {
-	return acpi_create_dir(device);
+	struct acpi_device * dev = container_of(kobj,struct acpi_device,kobj);
+	kfree(dev);
 }
 
+static struct subsystem acpi_namespace_subsys = {
+	.kobj		= { .name = "namespace" },
+	.parent		= &acpi_subsys,
+	.release	= acpi_device_release,
+};
+
+
+static void acpi_device_register(struct acpi_device * device, struct acpi_device * parent)
+{
+	/*
+	 * Linkage
+	 * -------
+	 * Link this device to its parent and siblings.
+	 */
+	INIT_LIST_HEAD(&device->children);
+	INIT_LIST_HEAD(&device->node);
+	INIT_LIST_HEAD(&device->g_list);
+
+	spin_lock(&acpi_device_lock);
+	if (device->parent) {
+		list_add_tail(&device->node, &device->parent->children);
+		list_add_tail(&device->g_list,&device->parent->g_list);
+	} else
+		list_add_tail(&device->g_list,&acpi_device_list);
+	spin_unlock(&acpi_device_lock);
+
+	kobject_init(&device->kobj);
+	strncpy(device->kobj.name,device->pnp.bus_id,KOBJ_NAME_LEN);
+	if (parent)
+		device->kobj.parent = &parent->kobj;
+	device->kobj.subsys = &acpi_namespace_subsys;
+	kobject_register(&device->kobj);
+}
 
 static int
 acpi_device_unregister (
-	struct acpi_device	*device)
+	struct acpi_device	*device, 
+	int			type)
 {
-	acpi_remove_dir(device);
+	kobject_unregister(&device->kobj);
 	return 0;
 }
 
@@ -443,16 +475,6 @@
 	return_VALUE(0);
 }
 
-static int
-acpi_bus_remove (
-	struct acpi_device	*device, 
-	int			type)
-{
-	acpi_device_unregister(device);
-	kfree(device);
-	return 0;
-}
-
 static void acpi_device_get_busid(struct acpi_device * device, acpi_handle handle, int type)
 {
 	char			bus_id[5] = {'?',0};
@@ -584,28 +606,31 @@
 
 void acpi_device_get_debug_info(struct acpi_device * device, acpi_handle handle, int type)
 {
-#ifdef CONFIG_ACPI_DEBUG
+#ifdef CONFIG_ACPI_DEBUG_OUTPUT
 	char		*type_string = NULL;
 	char		name[80] = {'?','\0'};
 	acpi_buffer	buffer = {sizeof(name), name};
 
-	acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
-
 	switch (type) {
 	case ACPI_BUS_TYPE_DEVICE:
 		type_string = "Device";
+		acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
 		break;
 	case ACPI_BUS_TYPE_POWER:
 		type_string = "Power Resource";
+		acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
 		break;
 	case ACPI_BUS_TYPE_PROCESSOR:
 		type_string = "Processor";
+		acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
 		break;
 	case ACPI_BUS_TYPE_SYSTEM:
 		type_string = "System";
+		acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
 		break;
 	case ACPI_BUS_TYPE_THERMAL:
 		type_string = "Thermal Zone";
+		acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
 		break;
 	case ACPI_BUS_TYPE_POWER_BUTTON:
 		type_string = "Power Button";
@@ -618,29 +643,7 @@
 	}
 
 	pr_debug("Found %s %s [%p]\n", type_string, name, handle);
-#endif /*CONFIG_ACPI_DEBUG*/
-}
-
-static void acpi_device_attach(struct acpi_device * device, struct acpi_device * parent)
-{
-	/*
-	 * Linkage
-	 * -------
-	 * Link this device to its parent and siblings.
-	 */
-	INIT_LIST_HEAD(&device->children);
-	INIT_LIST_HEAD(&device->node);
-	INIT_LIST_HEAD(&device->g_list);
-
-	spin_lock(&acpi_device_lock);
-	if (device->parent) {
-		list_add_tail(&device->node, &device->parent->children);
-		list_add_tail(&device->g_list,&device->parent->g_list);
-	} else
-		list_add_tail(&device->g_list,&acpi_device_list);
-	spin_unlock(&acpi_device_lock);
-
-	acpi_device_register(device, parent);
+#endif /*CONFIG_ACPI_DEBUG_OUTPUT*/
 }
 
 static int 
@@ -741,7 +744,7 @@
 
 	acpi_device_get_debug_info(device,handle,type);
 
-	acpi_device_attach(device,parent);
+	acpi_device_register(device,parent);
 
 	/*
 	 * Bind _ADR-Based Devices
@@ -760,7 +763,7 @@
 	 * ----------------------
 	 * If there's a hardware id (_HID) or compatible ids (_CID) we check
 	 * to see if there's a driver installed for this kind of device.  Note
-	 * that drivers can install before or after a device in enumerated.
+	 * that drivers can install before or after a device is enumerated.
 	 *
 	 * TBD: Assumes LDM provides driver hot-plug capability.
 	 */
@@ -822,14 +825,10 @@
 		/*
 		 * If this is a scope object then parse it (depth-first).
 		 */
-		if (type == ACPI_TYPE_ANY) {
-			/* Hack to get around scope identity problem */
-			status = acpi_get_next_object(ACPI_TYPE_ANY, chandle, 0, NULL);
-			if (ACPI_SUCCESS(status)) {
-				level++;
-				phandle = chandle;
-				chandle = 0;
-			}
+		if (type == ACPI_TYPE_LOCAL_SCOPE) {
+			level++;
+			phandle = chandle;
+			chandle = 0;
 			continue;
 		}
 
@@ -900,11 +899,11 @@
 	 */
 	if (acpi_fadt.pwr_button == 0)
 		result = acpi_bus_add(&device, acpi_root, 
-			ACPI_ROOT_OBJECT, ACPI_BUS_TYPE_POWER_BUTTON);
+			NULL, ACPI_BUS_TYPE_POWER_BUTTON);
 
 	if (acpi_fadt.sleep_button == 0)
 		result = acpi_bus_add(&device, acpi_root, 
-			ACPI_ROOT_OBJECT, ACPI_BUS_TYPE_SLEEP_BUTTON);
+			NULL, ACPI_BUS_TYPE_SLEEP_BUTTON);
 
 	return_VALUE(result);
 }
@@ -919,6 +918,8 @@
 	if (acpi_disabled)
 		return_VALUE(0);
 
+	subsystem_register(&acpi_namespace_subsys);
+
 	/*
 	 * Create the root device in the bus's device tree
 	 */
@@ -935,7 +936,7 @@
 		result = acpi_bus_scan(acpi_root);
 
 	if (result)
-		acpi_bus_remove(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
+		acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
 
  Done:
 	return_VALUE(result);
diff -Nru a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c
--- a/drivers/acpi/tables/tbutils.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/acpi/tables/tbutils.c	Mon Nov  4 14:31:01 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: tbutils - Table manipulation utilities
- *              $Revision: 56 $
+ *              $Revision: 57 $
  *
  *****************************************************************************/
 
@@ -175,8 +175,8 @@
 	/* Return the appropriate exception */
 
 	if (checksum) {
-		ACPI_REPORT_WARNING (("Invalid checksum (%X) in table %4.4s\n",
-			(u32) checksum, table_header->signature));
+		ACPI_REPORT_WARNING (("Invalid checksum in table [%4.4s] (%02X, sum %02X is not zero)\n",
+			table_header->signature, (u32) table_header->checksum, (u32) checksum));
 
 		status = AE_BAD_CHECKSUM;
 	}
diff -Nru a/drivers/atm/zatm.c b/drivers/atm/zatm.c
--- a/drivers/atm/zatm.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/atm/zatm.c	Mon Nov  4 14:31:01 2002
@@ -1260,13 +1260,13 @@
 		/* don't handle RD */
 		if (reason & uPD98401_INT_SPE)
 			printk(KERN_ALERT DEV_LABEL "(itf %d): system parity "
-			    "error at 0x%08lx\n",dev->number,zin(ADDR));
+			    "error at 0x%08x\n",dev->number,zin(ADDR));
 		if (reason & uPD98401_INT_CPE)
 			printk(KERN_ALERT DEV_LABEL "(itf %d): control memory "
-			    "parity error at 0x%08lx\n",dev->number,zin(ADDR));
+			    "parity error at 0x%08x\n",dev->number,zin(ADDR));
 		if (reason & uPD98401_INT_SBE) {
 			printk(KERN_ALERT DEV_LABEL "(itf %d): system bus "
-			    "error at 0x%08lx\n",dev->number,zin(ADDR));
+			    "error at 0x%08x\n",dev->number,zin(ADDR));
 			event_dump();
 		}
 		/* don't handle IND */
@@ -1448,7 +1448,7 @@
 	}
 	while (t0 > t1 || t1 > t2); /* loop if wrapping ... */
 	zatm_dev->khz = t2-2*t1+t0;
-	printk(KERN_NOTICE DEV_LABEL "(itf %d): uPD98401 %ld.%ld at %d.%03d "
+	printk(KERN_NOTICE DEV_LABEL "(itf %d): uPD98401 %d.%d at %d.%03d "
 	    "MHz\n",dev->number,
 	    (zin(VER) & uPD98401_MAJOR) >> uPD98401_MAJOR_SHIFT,
             zin(VER) & uPD98401_MINOR,zatm_dev->khz/1000,zatm_dev->khz % 1000);
diff -Nru a/drivers/base/Makefile b/drivers/base/Makefile
--- a/drivers/base/Makefile	Mon Nov  4 14:31:02 2002
+++ b/drivers/base/Makefile	Mon Nov  4 14:31:02 2002
@@ -2,13 +2,15 @@
 
 obj-y		:= core.o sys.o interface.o power.o bus.o \
 			driver.o class.o intf.o platform.o \
-			cpu.o
+			cpu.o firmware.o
+
+obj-$(CONFIG_NUMA)	+= node.o  memblk.o
 
 obj-y		+= fs/
 
 obj-$(CONFIG_HOTPLUG)	+= hotplug.o
 
 export-objs	:= core.o power.o sys.o bus.o driver.o \
-			class.o intf.o platform.o cpu.o 
+			class.o intf.o platform.o firmware.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/drivers/base/base.h b/drivers/base/base.h
--- a/drivers/base/base.h	Mon Nov  4 14:31:01 2002
+++ b/drivers/base/base.h	Mon Nov  4 14:31:01 2002
@@ -10,43 +10,14 @@
 extern spinlock_t device_lock;
 extern struct semaphore device_sem;
 
-extern struct device * get_device_locked(struct device *);
-
 extern int bus_add_device(struct device * dev);
 extern void bus_remove_device(struct device * dev);
 
-extern int device_make_dir(struct device * dev);
-extern void device_remove_dir(struct device * dev);
-
-extern int bus_make_dir(struct bus_type * bus);
-extern void bus_remove_dir(struct bus_type * bus);
-
 extern int bus_add_driver(struct device_driver *);
 extern void bus_remove_driver(struct device_driver *);
 
-extern int driver_make_dir(struct device_driver * drv);
-extern void driver_remove_dir(struct device_driver * drv);
-
-extern int device_bus_link(struct device * dev);
-extern void device_remove_symlink(struct driver_dir_entry * dir, const char * name);
-
-extern int devclass_make_dir(struct device_class *);
-extern void devclass_remove_dir(struct device_class *);
-
-extern int devclass_drv_link(struct device_driver *);
-extern void devclass_drv_unlink(struct device_driver *);
-
-extern int devclass_dev_link(struct device_class *, struct device *);
-extern void devclass_dev_unlink(struct device_class *, struct device *);
-
 extern int devclass_add_device(struct device *);
 extern void devclass_remove_device(struct device *);
-
-extern int intf_make_dir(struct device_interface *);
-extern void intf_remove_dir(struct device_interface *);
-
-extern int intf_dev_link(struct intf_data *);
-extern void intf_dev_unlink(struct intf_data *);
 
 extern int interface_add(struct device_class *, struct device *);
 extern void interface_remove(struct device_class *, struct device *);
diff -Nru a/drivers/base/bus.c b/drivers/base/bus.c
--- a/drivers/base/bus.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/base/bus.c	Mon Nov  4 14:31:01 2002
@@ -12,6 +12,7 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/errno.h>
+#include <linux/init.h>
 #include "base.h"
 
 static LIST_HEAD(bus_driver_list);
@@ -19,6 +20,109 @@
 #define to_dev(node) container_of(node,struct device,bus_list)
 #define to_drv(node) container_of(node,struct device_driver,bus_list)
 
+#define to_bus_attr(_attr) container_of(_attr,struct bus_attribute,attr)
+#define to_bus(obj) container_of(obj,struct bus_type,subsys.kobj)
+
+/*
+ * sysfs bindings for drivers
+ */
+
+#define to_drv_attr(_attr) container_of(_attr,struct driver_attribute,attr)
+#define to_driver(obj) container_of(obj, struct device_driver, kobj)
+
+
+static ssize_t
+drv_attr_show(struct kobject * kobj, struct attribute * attr,
+	      char * buf, size_t count, loff_t off)
+{
+	struct driver_attribute * drv_attr = to_drv_attr(attr);
+	struct device_driver * drv = to_driver(kobj);
+	ssize_t ret = 0;
+
+	if (drv_attr->show)
+		ret = drv_attr->show(drv,buf,count,off);
+	return ret;
+}
+
+static ssize_t
+drv_attr_store(struct kobject * kobj, struct attribute * attr,
+	       const char * buf, size_t count, loff_t off)
+{
+	struct driver_attribute * drv_attr = to_drv_attr(attr);
+	struct device_driver * drv = to_driver(kobj);
+	ssize_t ret = 0;
+
+	if (drv_attr->store)
+		ret = drv_attr->store(drv,buf,count,off);
+	return ret;
+}
+
+static struct sysfs_ops driver_sysfs_ops = {
+	.show	= drv_attr_show,
+	.store	= drv_attr_store,
+};
+
+
+/*
+ * sysfs bindings for drivers
+ */
+
+
+static ssize_t
+bus_attr_show(struct kobject * kobj, struct attribute * attr,
+	      char * buf, size_t count, loff_t off)
+{
+	struct bus_attribute * bus_attr = to_bus_attr(attr);
+	struct bus_type * bus = to_bus(kobj);
+	ssize_t ret = 0;
+
+	if (bus_attr->show)
+		ret = bus_attr->show(bus,buf,count,off);
+	return ret;
+}
+
+static ssize_t
+bus_attr_store(struct kobject * kobj, struct attribute * attr,
+	       const char * buf, size_t count, loff_t off)
+{
+	struct bus_attribute * bus_attr = to_bus_attr(attr);
+	struct bus_type * bus = to_bus(kobj);
+	ssize_t ret = 0;
+
+	if (bus_attr->store)
+		ret = bus_attr->store(bus,buf,count,off);
+	return ret;
+}
+
+static struct sysfs_ops bus_sysfs_ops = {
+	.show	= bus_attr_show,
+	.store	= bus_attr_store,
+};
+
+int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
+{
+	int error;
+	if (get_bus(bus)) {
+		error = sysfs_create_file(&bus->subsys.kobj,&attr->attr);
+		put_bus(bus);
+	} else
+		error = -EINVAL;
+	return error;
+}
+
+void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr)
+{
+	if (get_bus(bus)) {
+		sysfs_remove_file(&bus->subsys.kobj,&attr->attr);
+		put_bus(bus);
+	}
+}
+
+struct subsystem bus_subsys = {
+	.kobj	= { .name = "bus" },
+	.sysfs_ops	= &bus_sysfs_ops,
+};
+
 /**
  * bus_for_each_dev - walk list of devices and do something to each
  * @bus:	bus in question
@@ -92,6 +196,7 @@
 	pr_debug("bound device '%s' to driver '%s'\n",
 		 dev->bus_id,dev->driver->name);
 	list_add_tail(&dev->driver_list,&dev->driver->devices);
+	sysfs_create_link(&dev->driver->kobj,&dev->kobj,dev->kobj.name);
 }
 
 static int bus_match(struct device * dev, struct device_driver * drv)
@@ -162,6 +267,7 @@
 static void detach(struct device * dev, struct device_driver * drv)
 {
 	if (drv) {
+		sysfs_remove_link(&drv->kobj,dev->kobj.name);
 		list_del_init(&dev->driver_list);
 		devclass_remove_device(dev);
 		if (drv->remove)
@@ -206,7 +312,7 @@
 		list_add_tail(&dev->bus_list,&dev->bus->devices);
 		device_attach(dev);
 		up_write(&dev->bus->rwsem);
-		device_bus_link(dev);
+		sysfs_create_link(&bus->devsubsys.kobj,&dev->kobj,dev->bus_id);
 	}
 	return 0;
 }
@@ -221,9 +327,9 @@
 void bus_remove_device(struct device * dev)
 {
 	if (dev->bus) {
+		sysfs_remove_link(&dev->bus->devsubsys.kobj,dev->bus_id);
 		down_write(&dev->bus->rwsem);
 		pr_debug("bus %s: remove device %s\n",dev->bus->name,dev->bus_id);
-		device_remove_symlink(&dev->bus->device_dir,dev->bus_id);
 		device_detach(dev);
 		list_del_init(&dev->bus_list);
 		up_write(&dev->bus->rwsem);
@@ -240,7 +346,6 @@
 		list_add_tail(&drv->bus_list,&bus->drivers);
 		driver_attach(drv);
 		up_write(&bus->rwsem);
-		driver_make_dir(drv);
 	}
 	return 0;
 }
@@ -275,7 +380,6 @@
 	list_del_init(&bus->node);
 	spin_unlock(&device_lock);
 	WARN_ON(bus->present);
-	bus_remove_dir(bus);
 }
 
 int bus_register(struct bus_type * bus)
@@ -286,16 +390,25 @@
 	atomic_set(&bus->refcount,2);
 	bus->present = 1;
 
+	strncpy(bus->subsys.kobj.name,bus->name,KOBJ_NAME_LEN);
+	bus->subsys.parent = &bus_subsys;
+	subsystem_register(&bus->subsys);
+
+	snprintf(bus->devsubsys.kobj.name,KOBJ_NAME_LEN,"devices");
+	bus->devsubsys.parent = &bus->subsys;
+	subsystem_register(&bus->devsubsys);
+
+	snprintf(bus->drvsubsys.kobj.name,KOBJ_NAME_LEN,"drivers");
+	bus->drvsubsys.parent = &bus->subsys;
+	bus->drvsubsys.sysfs_ops = &driver_sysfs_ops;
+	subsystem_register(&bus->drvsubsys);
+
 	spin_lock(&device_lock);
 	list_add_tail(&bus->node,&bus_driver_list);
 	spin_unlock(&device_lock);
 
 	pr_debug("bus type '%s' registered\n",bus->name);
-
-	/* give it some driverfs entities */
-	bus_make_dir(bus);
 	put_bus(bus);
-
 	return 0;
 }
 
@@ -306,9 +419,19 @@
 	spin_unlock(&device_lock);
 
 	pr_debug("bus %s: unregistering\n",bus->name);
+	subsystem_unregister(&bus->drvsubsys);
+	subsystem_unregister(&bus->devsubsys);
+	subsystem_unregister(&bus->subsys);
 	put_bus(bus);
 }
 
+static int __init bus_subsys_init(void)
+{
+	return subsystem_register(&bus_subsys);
+}
+
+core_initcall(bus_subsys_init);
+
 EXPORT_SYMBOL(bus_for_each_dev);
 EXPORT_SYMBOL(bus_for_each_drv);
 EXPORT_SYMBOL(bus_add_device);
@@ -317,3 +440,6 @@
 EXPORT_SYMBOL(bus_unregister);
 EXPORT_SYMBOL(get_bus);
 EXPORT_SYMBOL(put_bus);
+
+EXPORT_SYMBOL(bus_create_file);
+EXPORT_SYMBOL(bus_remove_file);
diff -Nru a/drivers/base/class.c b/drivers/base/class.c
--- a/drivers/base/class.c	Mon Nov  4 14:31:03 2002
+++ b/drivers/base/class.c	Mon Nov  4 14:31:03 2002
@@ -4,10 +4,98 @@
 
 #include <linux/device.h>
 #include <linux/module.h>
+#include <linux/init.h>
 #include "base.h"
 
 static LIST_HEAD(class_list);
 
+#define to_class_attr(_attr) container_of(_attr,struct devclass_attribute,attr)
+#define to_class(obj) container_of(obj,struct device_class,subsys.kobj)
+
+static ssize_t
+devclass_attr_show(struct kobject * kobj, struct attribute * attr,
+	      char * buf, size_t count, loff_t off)
+{
+	struct devclass_attribute * class_attr = to_class_attr(attr);
+	struct device_class * dc = to_class(kobj);
+	ssize_t ret = 0;
+
+	if (class_attr->show)
+		ret = class_attr->show(dc,buf,count,off);
+	return ret;
+}
+
+static ssize_t
+devclass_attr_store(struct kobject * kobj, struct attribute * attr,
+	       const char * buf, size_t count, loff_t off)
+{
+	struct devclass_attribute * class_attr = to_class_attr(attr);
+	struct device_class * dc = to_class(kobj);
+	ssize_t ret = 0;
+
+	if (class_attr->store)
+		ret = class_attr->store(dc,buf,count,off);
+	return ret;
+}
+
+static struct sysfs_ops class_sysfs_ops = {
+	show:	devclass_attr_show,
+	store:	devclass_attr_store,
+};
+
+static struct subsystem class_subsys = {
+	.kobj	= { .name = "class", },
+	.sysfs_ops	= &class_sysfs_ops,
+};
+
+
+static int devclass_dev_link(struct device_class * cls, struct device * dev)
+{
+	char	linkname[16];
+	snprintf(linkname,16,"%u",dev->class_num);
+	return sysfs_create_link(&cls->devsubsys.kobj,&dev->kobj,linkname);
+}
+
+static void devclass_dev_unlink(struct device_class * cls, struct device * dev)
+{
+	char	linkname[16];
+	snprintf(linkname,16,"%u",dev->class_num);
+	sysfs_remove_link(&cls->devsubsys.kobj,linkname);
+}
+
+static int devclass_drv_link(struct device_driver * drv)
+{
+	char	name[KOBJ_NAME_LEN * 3];
+	snprintf(name,KOBJ_NAME_LEN * 3,"%s:%s",drv->bus->name,drv->name);
+	return sysfs_create_link(&drv->devclass->drvsubsys.kobj,&drv->kobj,name);
+}
+
+static void devclass_drv_unlink(struct device_driver * drv)
+{
+	char	name[KOBJ_NAME_LEN * 3];
+	snprintf(name,KOBJ_NAME_LEN * 3,"%s:%s",drv->bus->name,drv->name);
+	return sysfs_remove_link(&drv->devclass->drvsubsys.kobj,name);
+}
+
+
+int devclass_create_file(struct device_class * cls, struct devclass_attribute * attr)
+{
+	int error;
+	if (cls) {
+		error = sysfs_create_file(&cls->subsys.kobj,&attr->attr);
+	} else
+		error = -EINVAL;
+	return error;
+}
+
+void devclass_remove_file(struct device_class * cls, struct devclass_attribute * attr)
+{
+	if (cls)
+		sysfs_remove_file(&cls->subsys.kobj,&attr->attr);
+}
+
+
+
 int devclass_add_driver(struct device_driver * drv)
 {
 	struct device_class * cls = get_devclass(drv->devclass);
@@ -136,7 +224,6 @@
 	if (atomic_dec_and_lock(&cls->refcount,&device_lock)) {
 		list_del_init(&cls->node);
 		spin_unlock(&device_lock);
-		devclass_remove_dir(cls);
 	}
 }
 
@@ -150,10 +237,21 @@
 	cls->present = 1;
 	pr_debug("device class '%s': registering\n",cls->name);
 
+	strncpy(cls->subsys.kobj.name,cls->name,KOBJ_NAME_LEN);
+	cls->subsys.parent = &class_subsys;
+	subsystem_register(&cls->subsys);
+
+	snprintf(cls->devsubsys.kobj.name,KOBJ_NAME_LEN,"devices");
+	cls->devsubsys.parent = &cls->subsys;
+	subsystem_register(&cls->devsubsys);
+
+	snprintf(cls->drvsubsys.kobj.name,KOBJ_NAME_LEN,"drivers");
+	cls->drvsubsys.parent = &cls->subsys;
+	subsystem_register(&cls->drvsubsys);
+
 	spin_lock(&device_lock);
 	list_add_tail(&cls->node,&class_list);
 	spin_unlock(&device_lock);
-	devclass_make_dir(cls);
 	put_devclass(cls);
 	return 0;
 }
@@ -164,8 +262,18 @@
 	cls->present = 0;
 	spin_unlock(&device_lock);
 	pr_debug("device class '%s': unregistering\n",cls->name);
+	subsystem_unregister(&cls->drvsubsys);
+	subsystem_unregister(&cls->devsubsys);
+	subsystem_unregister(&cls->subsys);
 	put_devclass(cls);
 }
+
+static int __init class_subsys_init(void)
+{
+	return subsystem_register(&class_subsys);
+}
+
+core_initcall(class_subsys_init);
 
 EXPORT_SYMBOL(devclass_register);
 EXPORT_SYMBOL(devclass_unregister);
diff -Nru a/drivers/base/core.c b/drivers/base/core.c
--- a/drivers/base/core.c	Mon Nov  4 14:31:00 2002
+++ b/drivers/base/core.c	Mon Nov  4 14:31:00 2002
@@ -23,7 +23,74 @@
 
 spinlock_t device_lock = SPIN_LOCK_UNLOCKED;
 
-#define to_dev(node) container_of(node,struct device,driver_list)
+#define to_dev(obj) container_of(obj,struct device,kobj)
+
+
+/*
+ * sysfs bindings for devices.
+ */
+
+#define to_dev_attr(_attr) container_of(_attr,struct device_attribute,attr)
+
+extern struct attribute * dev_default_attrs[];
+
+static ssize_t
+dev_attr_show(struct kobject * kobj, struct attribute * attr,
+	      char * buf, size_t count, loff_t off)
+{
+	struct device_attribute * dev_attr = to_dev_attr(attr);
+	struct device * dev = to_dev(kobj);
+	ssize_t ret = 0;
+
+	if (dev_attr->show)
+		ret = dev_attr->show(dev,buf,count,off);
+	return ret;
+}
+
+static ssize_t
+dev_attr_store(struct kobject * kobj, struct attribute * attr,
+	       const char * buf, size_t count, loff_t off)
+{
+	struct device_attribute * dev_attr = to_dev_attr(attr);
+	struct device * dev = to_dev(kobj);
+	ssize_t ret = 0;
+
+	if (dev_attr->store)
+		ret = dev_attr->store(dev,buf,count,off);
+	return ret;
+}
+
+static struct sysfs_ops dev_sysfs_ops = {
+	.show	= dev_attr_show,
+	.store	= dev_attr_store,
+};
+
+struct subsystem device_subsys = {
+	.kobj		= {
+		.name	= "devices",
+	},
+	.sysfs_ops	= &dev_sysfs_ops,
+	.default_attrs	= dev_default_attrs,
+};
+
+
+int device_create_file(struct device * dev, struct device_attribute * attr)
+{
+	int error = 0;
+	if (get_device(dev)) {
+		error = sysfs_create_file(&dev->kobj,&attr->attr);
+		put_device(dev);
+	}
+	return error;
+}
+
+void device_remove_file(struct device * dev, struct device_attribute * attr)
+{
+	if (get_device(dev)) {
+		sysfs_remove_file(&dev->kobj,&attr->attr);
+		put_device(dev);
+	}
+}
 
 int device_add(struct device *dev)
 {
@@ -44,7 +111,11 @@
 	pr_debug("DEV: registering device: ID = '%s', name = %s\n",
 		 dev->bus_id, dev->name);
 
-	if ((error = device_make_dir(dev)))
+	strncpy(dev->kobj.name,dev->bus_id,KOBJ_NAME_LEN);
+	if (dev->parent)
+		dev->kobj.parent = &dev->parent->kobj;
+	dev->kobj.subsys = &device_subsys;
+	if ((error = kobject_register(&dev->kobj)))
 		goto register_done;
 
 	bus_add_device(dev);
@@ -69,6 +140,7 @@
 
 void device_initialize(struct device *dev)
 {
+	kobject_init(&dev->kobj);
 	INIT_LIST_HEAD(&dev->node);
 	INIT_LIST_HEAD(&dev->children);
 	INIT_LIST_HEAD(&dev->g_list);
@@ -157,9 +229,6 @@
 
 	bus_remove_device(dev);
 
-	/* remove the driverfs directory */
-	device_remove_dir(dev);
-
 	if (dev->release)
 		dev->release(dev);
 
@@ -184,10 +253,21 @@
 
 	pr_debug("DEV: Unregistering device. ID = '%s', name = '%s'\n",
 		 dev->bus_id,dev->name);
+	kobject_unregister(&dev->kobj);
 	put_device(dev);
 }
 
+static int __init device_subsys_init(void)
+{
+	return subsystem_register(&device_subsys);
+}
+
+core_initcall(device_subsys_init);
+
 EXPORT_SYMBOL(device_register);
 EXPORT_SYMBOL(device_unregister);
 EXPORT_SYMBOL(get_device);
 EXPORT_SYMBOL(put_device);
+
+EXPORT_SYMBOL(device_create_file);
+EXPORT_SYMBOL(device_remove_file);
diff -Nru a/drivers/base/cpu.c b/drivers/base/cpu.c
--- a/drivers/base/cpu.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/base/cpu.c	Mon Nov  4 14:31:01 2002
@@ -1,5 +1,5 @@
 /*
- * cpu.c - basic cpu class support
+ * drivers/base/cpu.c - basic CPU class support
  */
 
 #include <linux/device.h>
@@ -7,22 +7,48 @@
 #include <linux/init.h>
 #include <linux/cpu.h>
 
+#include <asm/topology.h>
+
+
 static int cpu_add_device(struct device * dev)
 {
 	return 0;
 }
-
 struct device_class cpu_devclass = {
 	.name		= "cpu",
 	.add_device	= cpu_add_device,
 };
 
 
-static int __init cpu_devclass_init(void)
+struct device_driver cpu_driver = {
+	.name		= "cpu",
+	.bus		= &system_bus_type,
+	.devclass	= &cpu_devclass,
+};
+
+
+/*
+ * register_cpu - Setup a driverfs device for a CPU.
+ * @num - CPU number to use when creating the device.
+ *
+ * Initialize and register the CPU device.
+ */
+int __init register_cpu(struct cpu *cpu, int num, struct node *root)
 {
-	return devclass_register(&cpu_devclass);
+	cpu->node_id = __cpu_to_node(num);
+	cpu->sysdev.name = "cpu";
+	cpu->sysdev.id = num;
+	if (root)
+		cpu->sysdev.root = &root->sysroot;
+	snprintf(cpu->sysdev.dev.name, DEVICE_NAME_SIZE, "CPU %u", num);
+	cpu->sysdev.dev.driver = &cpu_driver;
+	return sys_device_register(&cpu->sysdev);
 }
 
-postcore_initcall(cpu_devclass_init);
 
-EXPORT_SYMBOL(cpu_devclass);
+static int __init register_cpu_type(void)
+{
+	driver_register(&cpu_driver);
+	return devclass_register(&cpu_devclass);
+}
+postcore_initcall(register_cpu_type);
diff -Nru a/drivers/base/driver.c b/drivers/base/driver.c
--- a/drivers/base/driver.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/base/driver.c	Mon Nov  4 14:31:02 2002
@@ -12,6 +12,29 @@
 
 #define to_dev(node) container_of(node,struct device,driver_list)
 
+/*
+ * helpers for creating driver attributes in sysfs
+ */
+
+int driver_create_file(struct device_driver * drv, struct driver_attribute * attr)
+{
+	int error;
+	if (get_driver(drv)) {
+		error = sysfs_create_file(&drv->kobj,&attr->attr);
+		put_driver(drv);
+	} else
+		error = -EINVAL;
+	return error;
+}
+
+void driver_remove_file(struct device_driver * drv, struct driver_attribute * attr)
+{
+	if (get_driver(drv)) {
+		sysfs_remove_file(&drv->kobj,&attr->attr);
+		put_driver(drv);
+	}
+}
+
 int driver_for_each_dev(struct device_driver * drv, void * data, 
 			int (*callback)(struct device *, void * ))
 {
@@ -65,7 +88,6 @@
 		return;
 	spin_unlock(&device_lock);
 	BUG_ON(drv->present);
-	bus_remove_driver(drv);
 	if (drv->release)
 		drv->release(drv);
 	put_bus(bus);
@@ -84,6 +106,11 @@
 
 	pr_debug("driver %s:%s: registering\n",drv->bus->name,drv->name);
 
+	kobject_init(&drv->kobj);
+	strncpy(drv->kobj.name,drv->name,KOBJ_NAME_LEN);
+	drv->kobj.subsys = &drv->bus->drvsubsys;
+	kobject_register(&drv->kobj);
+
 	get_bus(drv->bus);
 	atomic_set(&drv->refcount,2);
 	rwlock_init(&drv->lock);
@@ -108,3 +135,6 @@
 EXPORT_SYMBOL(driver_unregister);
 EXPORT_SYMBOL(get_driver);
 EXPORT_SYMBOL(put_driver);
+
+EXPORT_SYMBOL(driver_create_file);
+EXPORT_SYMBOL(driver_remove_file);
diff -Nru a/drivers/base/firmware.c b/drivers/base/firmware.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/base/firmware.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,32 @@
+/*
+ * firmware.c - firmware subsystem hoohaw.
+ */
+
+#include <linux/kobject.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+static struct subsystem firmware_subsys = {
+	.kobj	= { .name = "firmware" },
+};
+
+int firmware_register(struct subsystem * s)
+{
+	s->parent = &firmware_subsys;
+	return subsystem_register(s);
+}
+
+void firmware_unregister(struct subsystem * s)
+{
+	subsystem_unregister(s);
+}
+
+static int __init firmware_init(void)
+{
+	return subsystem_register(&firmware_subsys);
+}
+
+core_initcall(firmware_init);
+
+EXPORT_SYMBOL(firmware_register);
+EXPORT_SYMBOL(firmware_unregister);
diff -Nru a/drivers/base/fs/Makefile b/drivers/base/fs/Makefile
--- a/drivers/base/fs/Makefile	Mon Nov  4 14:31:02 2002
+++ b/drivers/base/fs/Makefile	Mon Nov  4 14:31:02 2002
@@ -1,5 +1,5 @@
-obj-y		:= device.o bus.o driver.o class.o intf.o
+obj-y		:= device.o
 
-export-objs	:= device.o bus.o driver.o class.o
+export-objs	:= device.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/drivers/base/fs/bus.c b/drivers/base/fs/bus.c
--- a/drivers/base/fs/bus.c	Mon Nov  4 14:31:02 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,123 +0,0 @@
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/init.h>
-#include <linux/stat.h>
-#include "fs.h"
-
-static struct driver_dir_entry bus_dir;
-
-#define to_bus_attr(_attr) container_of(_attr,struct bus_attribute,attr)
-
-#define to_bus(dir) container_of(dir,struct bus_type,dir)
-
-
-/* driverfs ops for device attribute files */
-
-static int
-bus_attr_open(struct driver_dir_entry * dir)
-{
-	struct bus_type * bus = to_bus(dir);
-	get_bus(bus);
-	return 0;
-}
-
-static int
-bus_attr_close(struct driver_dir_entry * dir)
-{
-	struct bus_type * bus = to_bus(dir);
-	put_bus(bus);
-	return 0;
-}
-
-static ssize_t
-bus_attr_show(struct driver_dir_entry * dir, struct attribute * attr,
-	      char * buf, size_t count, loff_t off)
-{
-	struct bus_attribute * bus_attr = to_bus_attr(attr);
-	struct bus_type * bus = to_bus(dir);
-	ssize_t ret = 0;
-
-	if (bus_attr->show)
-		ret = bus_attr->show(bus,buf,count,off);
-	return ret;
-}
-
-static ssize_t
-bus_attr_store(struct driver_dir_entry * dir, struct attribute * attr,
-	       const char * buf, size_t count, loff_t off)
-{
-	struct bus_attribute * bus_attr = to_bus_attr(attr);
-	struct bus_type * bus = to_bus(dir);
-	ssize_t ret = 0;
-
-	if (bus_attr->store)
-		ret = bus_attr->store(bus,buf,count,off);
-	return ret;
-}
-
-static struct driverfs_ops bus_attr_ops = {
-	.open	= bus_attr_open,
-	.close	= bus_attr_close,
-	.show	= bus_attr_show,
-	.store	= bus_attr_store,
-};
-
-int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
-{
-	int error;
-	if (get_bus(bus)) {
-		error = driverfs_create_file(&attr->attr,&bus->dir);
-		put_bus(bus);
-	} else
-		error = -EINVAL;
-	return error;
-}
-
-void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr)
-{
-	if (get_bus(bus)) {
-		driverfs_remove_file(&bus->dir,attr->attr.name);
-		put_bus(bus);
-	}
-}
-
-int bus_make_dir(struct bus_type * bus)
-{
-	int error;
-	bus->dir.name = bus->name;
-	bus->dir.ops = &bus_attr_ops;
-
-	error = device_create_dir(&bus->dir,&bus_dir);
-	if (!error) {
-		bus->device_dir.name = "devices";
-		device_create_dir(&bus->device_dir,&bus->dir);
-
-		bus->driver_dir.name = "drivers";
-		device_create_dir(&bus->driver_dir,&bus->dir);
-	}
-	return error;
-}
-
-void bus_remove_dir(struct bus_type * bus)
-{
-	/* remove driverfs entries */
-	driverfs_remove_dir(&bus->driver_dir);
-	driverfs_remove_dir(&bus->device_dir);
-	driverfs_remove_dir(&bus->dir);
-}
-
-static struct driver_dir_entry bus_dir = {
-	.name	= "bus",
-	.mode	= (S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO),
-};
-
-static int __init bus_init(void)
-{
-	/* make 'bus' driverfs directory */
-	return driverfs_create_dir(&bus_dir,NULL);
-}
-
-core_initcall(bus_init);
-
-EXPORT_SYMBOL(bus_create_file);
-EXPORT_SYMBOL(bus_remove_file);
diff -Nru a/drivers/base/fs/class.c b/drivers/base/fs/class.c
--- a/drivers/base/fs/class.c	Mon Nov  4 14:31:02 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,215 +0,0 @@
-/*
- * class.c - driverfs bindings for device classes.
- */
-
-#include <linux/device.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include "fs.h"
-
-static struct driver_dir_entry class_dir;
-
-
-#define to_class_attr(_attr) container_of(_attr,struct devclass_attribute,attr)
-
-#define to_class(d) container_of(d,struct device_class,dir)
-
-
-static ssize_t
-devclass_attr_show(struct driver_dir_entry * dir, struct attribute * attr,
-	      char * buf, size_t count, loff_t off)
-{
-	struct devclass_attribute * class_attr = to_class_attr(attr);
-	struct device_class * dc = to_class(dir);
-	ssize_t ret = 0;
-
-	if (class_attr->show)
-		ret = class_attr->show(dc,buf,count,off);
-	return ret;
-}
-
-static ssize_t
-devclass_attr_store(struct driver_dir_entry * dir, struct attribute * attr,
-	       const char * buf, size_t count, loff_t off)
-{
-	struct devclass_attribute * class_attr = to_class_attr(attr);
-	struct device_class * dc = to_class(dir);
-	ssize_t ret = 0;
-
-	if (class_attr->store)
-		ret = class_attr->store(dc,buf,count,off);
-	return ret;
-}
-
-static struct driverfs_ops devclass_attr_ops = {
-	show:	devclass_attr_show,
-	store:	devclass_attr_store,
-};
-
-int devclass_create_file(struct device_class * dc, struct devclass_attribute * attr)
-{
-	int error;
-	if (dc) {
-		error = driverfs_create_file(&attr->attr,&dc->dir);
-	} else
-		error = -EINVAL;
-	return error;
-}
-
-void devclass_remove_file(struct device_class * dc, struct devclass_attribute * attr)
-{
-	if (dc)
-		driverfs_remove_file(&dc->dir,attr->attr.name);
-}
-
-/**
- *	devclass_dev_link - create symlink to device's directory
- *	@cls - device class we're a part of 
- *	@dev - device we're linking to 
- *
- *	Create a symlink in the class's devices/ directory to @dev's 
- *	directory in the physical hierarchy. The name is the device's 
- *	class-enumerated value (struct device::class_num). We're 
- *	creating:
- *		class/<class name>/devices/<link name> ->
- *		root/<path to device>/<device's dir>
- *	So, the link looks like:
- *		../../../root/<path to device>/
- */
-int devclass_dev_link(struct device_class * cls, struct device * dev)
-{
-	char	linkname[16];
-	char	* path;
-	int	length;
-	int	error;
-
-	length = get_devpath_length(dev);
-	length += strlen("../../../root");
-
-	if (length > PATH_MAX)
-		return -ENAMETOOLONG;
-
-	if (!(path = kmalloc(length,GFP_KERNEL)))
-		return -ENOMEM;
-	memset(path,0,length);
-	strcpy(path,"../../../root");
-	fill_devpath(dev,path,length);
-	
-	snprintf(linkname,16,"%u",dev->class_num);
-	error = driverfs_create_symlink(&cls->device_dir,linkname,path);
-	kfree(path);
-	return error;
-}
-
-void devclass_dev_unlink(struct device_class * cls, struct device * dev)
-{
-	char	linkname[16];
-
-	snprintf(linkname,16,"%u",dev->class_num);
-	driverfs_remove_file(&cls->device_dir,linkname);
-}
-
-/**
- *	devclass_drv_link - create symlink to driver's directory
- *	@drv:	driver we're linking up
- *
- *	Create a symlink in the class's drivers/ directory to @drv's
- *	directory (in the bus's directory). It's name is <bus>:<driver>
- *	to prevent naming conflicts.
- *
- *	We're creating 
- *		class/<class name>/drivers/<link name> -> 
- *		bus/<bus name>/drivers/<driver name>/
- *	So, the link looks like: 
- *		../../../bus/<bus name>/drivers/<driver name>
- */
-int devclass_drv_link(struct device_driver * drv)
-{
-	char	* name;
-	char	* path;
-	int	namelen;
-	int	pathlen;
-	int	error = 0;
-
-	namelen = strlen(drv->name) + strlen(drv->bus->name) + 2;
-	name = kmalloc(namelen,GFP_KERNEL);
-	if (!name)
-		return -ENOMEM;
-	snprintf(name,namelen,"%s:%s",drv->bus->name,drv->name);
-
-	pathlen = strlen("../../../bus/") + 
-		strlen(drv->bus->name) + 
-		strlen("/drivers/") + 
-		strlen(drv->name) + 1;
-	if (!(path = kmalloc(pathlen,GFP_KERNEL))) {
-		error = -ENOMEM;
-		goto Done;
-	}
-	snprintf(path,pathlen,"%s%s%s%s",
-		 "../../../bus/",
-		 drv->bus->name,
-		 "/drivers/",
-		 drv->name);
-
-	error = driverfs_create_symlink(&drv->devclass->driver_dir,name,path);
- Done:
-	kfree(name);
-	kfree(path);
-	return error;
-}
-
-void devclass_drv_unlink(struct device_driver * drv)
-{
-	char	* name;
-	int	length;
-
-	length = strlen(drv->name) + strlen(drv->bus->name) + 2;
-	if ((name = kmalloc(length,GFP_KERNEL))) {
-		driverfs_remove_file(&drv->devclass->driver_dir,name);
-		kfree(name);
-	}
-}
-
-void devclass_remove_dir(struct device_class * dc)
-{
-	driverfs_remove_dir(&dc->device_dir);
-	driverfs_remove_dir(&dc->driver_dir);
-	driverfs_remove_dir(&dc->dir);
-}
-
-int devclass_make_dir(struct device_class * dc)
-{
-	int error;
-
-	dc->dir.name = dc->name;
-	dc->dir.ops = &devclass_attr_ops;
-	error = device_create_dir(&dc->dir,&class_dir);
-	if (!error) {
-		dc->driver_dir.name = "drivers";
-		error = device_create_dir(&dc->driver_dir,&dc->dir);
-		if (!error) {
-			dc->device_dir.name = "devices";
-			error = device_create_dir(&dc->device_dir,&dc->dir);
-		}
-		if (error)
-			driverfs_remove_dir(&dc->dir);
-	}
-	return error;
-}
-
-static struct driver_dir_entry class_dir = {
-	name:	"class",
-	mode:	(S_IRWXU | S_IRUGO | S_IXUGO),
-};
-
-static int __init devclass_driverfs_init(void)
-{
-	return driverfs_create_dir(&class_dir,NULL);
-}
-
-core_initcall(devclass_driverfs_init);
-
-EXPORT_SYMBOL(devclass_create_file);
-EXPORT_SYMBOL(devclass_remove_file);
diff -Nru a/drivers/base/fs/device.c b/drivers/base/fs/device.c
--- a/drivers/base/fs/device.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/base/fs/device.c	Mon Nov  4 14:31:02 2002
@@ -16,112 +16,6 @@
 #include <linux/stat.h>
 #include <linux/limits.h>
 
-static struct driver_dir_entry device_root_dir = {
-	.name	= "root",
-	.mode	= (S_IRWXU | S_IRUGO | S_IXUGO),
-};
-
-extern struct device_attribute * device_default_files[];
-
-#define to_dev_attr(_attr) container_of(_attr,struct device_attribute,attr)
-
-#define to_device(d) container_of(d, struct device, dir)
-
-
-/* driverfs ops for device attribute files */
-
-static int
-dev_attr_open(struct driver_dir_entry * dir)
-{
-	struct device * dev = to_device(dir);
-	get_device(dev);
-	return 0;
-}
-
-static int
-dev_attr_close(struct driver_dir_entry * dir)
-{
-	struct device * dev = to_device(dir);
-	put_device(dev);
-	return 0;
-}
-
-static ssize_t
-dev_attr_show(struct driver_dir_entry * dir, struct attribute * attr,
-	      char * buf, size_t count, loff_t off)
-{
-	struct device_attribute * dev_attr = to_dev_attr(attr);
-	struct device * dev = to_device(dir);
-	ssize_t ret = 0;
-
-	if (dev_attr->show)
-		ret = dev_attr->show(dev,buf,count,off);
-	return ret;
-}
-
-static ssize_t
-dev_attr_store(struct driver_dir_entry * dir, struct attribute * attr,
-	       const char * buf, size_t count, loff_t off)
-{
-	struct device_attribute * dev_attr = to_dev_attr(attr);
-	struct device * dev = to_device(dir);
-	ssize_t ret = 0;
-
-	if (dev_attr->store)
-		ret = dev_attr->store(dev,buf,count,off);
-	return ret;
-}
-
-static struct driverfs_ops dev_attr_ops = {
-	.open	= dev_attr_open,
-	.close	= dev_attr_close,
-	.show	= dev_attr_show,
-	.store	= dev_attr_store,
-};
-
-/**
- * device_create_file - create a driverfs file for a device
- * @dev:	device requesting file
- * @entry:	entry describing file
- *
- * Allocate space for file entry, copy descriptor, and create.
- */
-int device_create_file(struct device * dev, struct device_attribute * entry)
-{
-	int error = -EINVAL;
-
-	if (get_device(dev)) {
-		error = driverfs_create_file(&entry->attr,&dev->dir);
-		put_device(dev);
-	}
-	return error;
-}
-
-/**
- * device_remove_file - remove a device's file by name
- * @dev:	device requesting removal
- * @name:	name of the file
- *
- */
-void device_remove_file(struct device * dev, struct device_attribute * attr)
-{
-	if (dev) {
-		get_device(dev);
-		driverfs_remove_file(&dev->dir,attr->attr.name);
-		put_device(dev);
-	}
-}
-
-/**
- * device_remove_dir - remove a device's directory
- * @dev:	device in question
- */
-void device_remove_dir(struct device * dev)
-{
-	if (dev)
-		driverfs_remove_dir(&dev->dir);
-}
-
 int get_devpath_length(struct device * dev)
 {
 	int length = 1;
@@ -153,92 +47,3 @@
 	pr_debug("%s: path = '%s'\n",__FUNCTION__,path);
 }
 
-int device_bus_link(struct device * dev)
-{
-	char * path;
-	int length;
-	int error = 0;
-
-	if (!dev->bus)
-		return 0;
-
-	length = get_devpath_length(dev);
-
-	/* now add the path from the bus directory
-	 * It should be '../../..' (one to get to the bus's directory,
-	 * one to get to the 'bus' directory, and one to get to the root 
-	 * of the fs.)
-	 */
-	length += strlen("../../../root");
-
-	if (length > PATH_MAX)
-		return -ENAMETOOLONG;
-
-	if (!(path = kmalloc(length,GFP_KERNEL)))
-		return -ENOMEM;
-	memset(path,0,length);
-
-	/* our relative position */
-	strcpy(path,"../../../root");
-
-	fill_devpath(dev,path,length);
-	error = driverfs_create_symlink(&dev->bus->device_dir,dev->bus_id,path);
-	kfree(path);
-	return error;
-}
-
-void device_remove_symlink(struct driver_dir_entry * dir, const char * name)
-{
-	driverfs_remove_file(dir,name);
-}
-
-int device_create_dir(struct driver_dir_entry * dir, struct driver_dir_entry * parent)
-{
-	dir->mode  = (S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO);
-	return driverfs_create_dir(dir,parent);
-}
-
-/**
- * device_make_dir - create a driverfs directory
- * @name:	name of directory
- * @parent:	dentry for the parent directory
- *
- * Do the initial creation of the device's driverfs directory
- * and populate it with the one default file.
- *
- * This is just a helper for device_register(), as we
- * don't export this function. (Yes, that means we don't allow
- * devices to create subdirectories).
- */
-int device_make_dir(struct device * dev)
-{
-	struct driver_dir_entry * parent;
-	struct device_attribute * entry;
-	int error;
-	int i;
-
-	parent = dev->parent ? &dev->parent->dir : &device_root_dir;
-	dev->dir.name = dev->bus_id;
-	dev->dir.ops = &dev_attr_ops;
-
-	if ((error = device_create_dir(&dev->dir,parent)))
-		return error;
-
-	for (i = 0; (entry = *(device_default_files + i)); i++) {
-		if ((error = device_create_file(dev,entry))) {
-			device_remove_dir(dev);
-			break;
-		}
-	}
-	return error;
-}
-
-static int device_driverfs_init(void)
-{
-	return driverfs_create_dir(&device_root_dir,NULL);
-}
-
-core_initcall(device_driverfs_init);
-
-EXPORT_SYMBOL(device_create_file);
-EXPORT_SYMBOL(device_remove_file);
diff -Nru a/drivers/base/fs/driver.c b/drivers/base/fs/driver.c
--- a/drivers/base/fs/driver.c	Mon Nov  4 14:31:00 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,100 +0,0 @@
-#include <linux/device.h>
-#include <linux/module.h>
-#include <linux/stat.h>
-#include <linux/err.h>
-#include "fs.h"
-
-#define to_drv_attr(_attr) container_of(_attr,struct driver_attribute,attr)
-
-#define to_drv(d) container_of(d, struct device_driver, dir)
-
-
-/* driverfs ops for device attribute files */
-
-static int
-drv_attr_open(struct driver_dir_entry * dir)
-{
-	struct device_driver * drv = to_drv(dir);
-	get_driver(drv);
-	return 0;
-}
-
-static int
-drv_attr_close(struct driver_dir_entry * dir)
-{
-	struct device_driver * drv = to_drv(dir);
-	put_driver(drv);
-	return 0;
-}
-
-static ssize_t
-drv_attr_show(struct driver_dir_entry * dir, struct attribute * attr,
-	      char * buf, size_t count, loff_t off)
-{
-	struct driver_attribute * drv_attr = to_drv_attr(attr);
-	struct device_driver * drv = to_drv(dir);
-	ssize_t ret = 0;
-
-	if (drv_attr->show)
-		ret = drv_attr->show(drv,buf,count,off);
-	return ret;
-}
-
-static ssize_t
-drv_attr_store(struct driver_dir_entry * dir, struct attribute * attr,
-	       const char * buf, size_t count, loff_t off)
-{
-	struct driver_attribute * drv_attr = to_drv_attr(attr);
-	struct device_driver * drv = to_drv(dir);
-	ssize_t ret = 0;
-
-	if (drv_attr->store)
-		ret = drv_attr->store(drv,buf,count,off);
-	return ret;
-}
-
-static struct driverfs_ops drv_attr_ops = {
-	.open	= drv_attr_open,
-	.close	= drv_attr_close,
-	.show	= drv_attr_show,
-	.store	= drv_attr_store,
-};
-
-int driver_create_file(struct device_driver * drv, struct driver_attribute * attr)
-{
-	int error;
-	if (get_driver(drv)) {
-		error = driverfs_create_file(&attr->attr,&drv->dir);
-		put_driver(drv);
-	} else
-		error = -EINVAL;
-	return error;
-}
-
-void driver_remove_file(struct device_driver * drv, struct driver_attribute * attr)
-{
-	if (get_driver(drv)) {
-		driverfs_remove_file(&drv->dir,attr->attr.name);
-		put_driver(drv);
-	}
-}
-
-/**
- * driver_make_dir - create a driverfs directory for a driver
- * @drv:	driver in question
- */
-int driver_make_dir(struct device_driver * drv)
-{
-	drv->dir.name = drv->name;
-	drv->dir.ops = &drv_attr_ops;
-
-	return device_create_dir(&drv->dir,&drv->bus->driver_dir);
-}
-
-void driver_remove_dir(struct device_driver * drv)
-{
-	driverfs_remove_dir(&drv->dir);
-}
-
-EXPORT_SYMBOL(driver_create_file);
-EXPORT_SYMBOL(driver_remove_file);
diff -Nru a/drivers/base/fs/fs.h b/drivers/base/fs/fs.h
--- a/drivers/base/fs/fs.h	Mon Nov  4 14:31:01 2002
+++ b/drivers/base/fs/fs.h	Mon Nov  4 14:31:01 2002
@@ -1,6 +1,4 @@
 
-extern int device_create_dir(struct driver_dir_entry * dir, struct driver_dir_entry * parent);
-
 int get_devpath_length(struct device * dev);
 
 void fill_devpath(struct device * dev, char * path, int length);
diff -Nru a/drivers/base/fs/intf.c b/drivers/base/fs/intf.c
--- a/drivers/base/fs/intf.c	Mon Nov  4 14:31:01 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,54 +0,0 @@
-/*
- * intf.c - driverfs glue for device interfaces
- */
-
-#include <linux/device.h>
-#include <linux/slab.h>
-#include "fs.h"
-
-/**
- * intf_dev_link - symlink from interface's directory to device's directory
- *
- */
-int intf_dev_link(struct intf_data * data)
-{
-	char	linkname[16];
-	char	* path;
-	int	length;
-	int	error;
-
-	length = get_devpath_length(data->dev);
-	length += strlen("../../../root");
-
-	if (length > PATH_MAX)
-		return -ENAMETOOLONG;
-
-	if (!(path = kmalloc(length,GFP_KERNEL)))
-		return -ENOMEM;
-	memset(path,0,length);
-	strcpy(path,"../../../root");
-	fill_devpath(data->dev,path,length);
-
-	snprintf(linkname,16,"%u",data->intf_num);
-	error = driverfs_create_symlink(&data->intf->dir,linkname,path);
-	kfree(path);
-	return error;
-}
-
-void intf_dev_unlink(struct intf_data * data)
-{
-	char	linkname[16];
-	snprintf(linkname,16,"%u",data->intf_num);
-	driverfs_remove_file(&data->intf->dir,linkname);
-}
-
-void intf_remove_dir(struct device_interface * intf)
-{
-	driverfs_remove_dir(&intf->dir);
-}
-
-int intf_make_dir(struct device_interface * intf)
-{
-	intf->dir.name = intf->name;
-	return device_create_dir(&intf->dir,&intf->devclass->dir);
-}
diff -Nru a/drivers/base/interface.c b/drivers/base/interface.c
--- a/drivers/base/interface.c	Mon Nov  4 14:31:00 2002
+++ b/drivers/base/interface.c	Mon Nov  4 14:31:00 2002
@@ -88,8 +88,8 @@
 static DEVICE_ATTR(power,S_IWUSR | S_IRUGO,
 		   device_read_power,device_write_power);
 
-struct device_attribute * device_default_files[] = {
-	&dev_attr_name,
-	&dev_attr_power,
+struct attribute * dev_default_attrs[] = {
+	&dev_attr_name.attr,
+	&dev_attr_power.attr,
 	NULL,
 };
diff -Nru a/drivers/base/intf.c b/drivers/base/intf.c
--- a/drivers/base/intf.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/base/intf.c	Mon Nov  4 14:31:02 2002
@@ -11,6 +11,26 @@
 
 #define to_intf(node) container_of(node,struct device_interface,node)
 
+/**
+ * intf_dev_link - symlink from interface's directory to device's directory
+ *
+ */
+static int intf_dev_link(struct intf_data * data)
+{
+	char	linkname[16];
+
+	snprintf(linkname,16,"%u",data->intf_num);
+	return sysfs_create_link(&data->intf->kobj,&data->dev->kobj,linkname);
+}
+
+static void intf_dev_unlink(struct intf_data * data)
+{
+	char	linkname[16];
+	snprintf(linkname,16,"%u",data->intf_num);
+	sysfs_remove_link(&data->intf->kobj,linkname);
+}
+
+
 int interface_register(struct device_interface * intf)
 {
 	struct device_class * cls = intf->devclass;
@@ -18,7 +38,11 @@
 	if (cls) {
 		pr_debug("register interface '%s' with class '%s\n",
 			 intf->name,cls->name);
-		intf_make_dir(intf);
+		kobject_init(&intf->kobj);
+		strncpy(intf->kobj.name,intf->name,KOBJ_NAME_LEN);
+		intf->kobj.subsys = &cls->subsys;
+		kobject_register(&intf->kobj);
+
 		spin_lock(&device_lock);
 		list_add_tail(&intf->node,&cls->intf_list);
 		spin_unlock(&device_lock);
@@ -31,11 +55,10 @@
 {
 	pr_debug("unregistering interface '%s' from class '%s'\n",
 		 intf->name,intf->devclass->name);
+	kobject_unregister(&intf->kobj);
 	spin_lock(&device_lock);
 	list_del_init(&intf->node);
 	spin_unlock(&device_lock);
-
-	intf_remove_dir(intf);
 }
 
 int interface_add(struct device_class * cls, struct device * dev)
diff -Nru a/drivers/base/memblk.c b/drivers/base/memblk.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/base/memblk.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,55 @@
+/*
+ * drivers/base/memblk.c - basic Memory Block class support
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/memblk.h>
+#include <linux/node.h>
+
+#include <asm/topology.h>
+
+
+static int memblk_add_device(struct device * dev)
+{
+	return 0;
+}
+struct device_class memblk_devclass = {
+	.name		= "memblk",
+	.add_device	= memblk_add_device,
+};
+
+
+struct device_driver memblk_driver = {
+	.name		= "memblk",
+	.bus		= &system_bus_type,
+	.devclass	= &memblk_devclass,
+};
+
+
+/*
+ * register_memblk - Setup a driverfs device for a MemBlk
+ * @num - MemBlk number to use when creating the device.
+ *
+ * Initialize and register the MemBlk device.
+ */
+int __init register_memblk(struct memblk *memblk, int num, struct node *root)
+{
+	memblk->node_id = __memblk_to_node(num);
+	memblk->sysdev.name = "memblk";
+	memblk->sysdev.id = num;
+	if (root)
+		memblk->sysdev.root = &root->sysroot;
+	snprintf(memblk->sysdev.dev.name, DEVICE_NAME_SIZE, "Memory Block %u", num);
+	memblk->sysdev.dev.driver = &memblk_driver;
+	return sys_device_register(&memblk->sysdev);
+}
+
+
+static int __init register_memblk_type(void)
+{
+	driver_register(&memblk_driver);
+	return devclass_register(&memblk_devclass);
+}
+postcore_initcall(register_memblk_type);
diff -Nru a/drivers/base/node.c b/drivers/base/node.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/base/node.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,99 @@
+/*
+ * drivers/base/node.c - basic Node class support
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/node.h>
+
+#include <asm/topology.h>
+
+
+static int node_add_device(struct device * dev)
+{
+	return 0;
+}
+struct device_class node_devclass = {
+	.name		= "node",
+	.add_device	= node_add_device,
+};
+
+
+struct device_driver node_driver = {
+	.name		= "node",
+	.bus		= &system_bus_type,
+	.devclass	= &node_devclass,
+};
+
+
+static ssize_t node_read_cpumap(struct device * dev, char * buf, size_t count, loff_t off)
+{
+	struct node *node_dev = to_node(to_root(dev));
+        return off ? 0 : sprintf(buf,"%lx\n",node_dev->cpumap);
+}
+static DEVICE_ATTR(cpumap,S_IRUGO,node_read_cpumap,NULL);
+
+#define K(x) ((x) << (PAGE_SHIFT - 10))
+static ssize_t node_read_meminfo(struct device * dev, char * buf, size_t count, loff_t off)
+{
+	struct sys_root *node = to_root(dev);
+	int nid = node->id;
+	struct sysinfo i;
+	si_meminfo_node(&i, nid);
+	return off ? 0 : sprintf(buf, "\n"
+			"Node %d MemTotal:     %8lu kB\n"
+			"Node %d MemFree:      %8lu kB\n"
+			"Node %d MemUsed:      %8lu kB\n"
+			"Node %d HighTotal:    %8lu kB\n"
+			"Node %d HighFree:     %8lu kB\n"
+			"Node %d LowTotal:     %8lu kB\n"
+			"Node %d LowFree:      %8lu kB\n",
+			nid, K(i.totalram),
+			nid, K(i.freeram),
+			nid, K(i.totalram-i.freeram),
+			nid, K(i.totalhigh),
+			nid, K(i.freehigh),
+			nid, K(i.totalram-i.totalhigh),
+			nid, K(i.freeram-i.freehigh));
+
+	return 0;
+}
+#undef K 
+static DEVICE_ATTR(meminfo,S_IRUGO,node_read_meminfo,NULL);
+
+
+/*
+ * register_node - Setup a driverfs device for a node.
+ * @num - Node number to use when creating the device.
+ *
+ * Initialize and register the node device.
+ */
+int __init register_node(struct node *node, int num, struct node *parent)
+{
+	int error;
+
+	node->cpumap = __node_to_cpu_mask(num);
+	node->sysroot.id = num;
+	if (parent)
+		node->sysroot.dev.parent = &parent->sysroot.sysdev;
+	snprintf(node->sysroot.dev.name, DEVICE_NAME_SIZE, "Node %u", num);
+	snprintf(node->sysroot.dev.bus_id, BUS_ID_SIZE, "node%u", num);
+	node->sysroot.dev.driver = &node_driver;
+	node->sysroot.dev.bus = &system_bus_type;
+	error = sys_register_root(&node->sysroot);
+	if (!error){
+		device_create_file(&node->sysroot.dev, &dev_attr_cpumap);
+		device_create_file(&node->sysroot.dev, &dev_attr_meminfo);
+	}
+	return error;
+}
+
+
+static int __init register_node_type(void)
+{
+	driver_register(&node_driver);
+	return devclass_register(&node_devclass);
+}
+postcore_initcall(register_node_type);
diff -Nru a/drivers/base/sys.c b/drivers/base/sys.c
--- a/drivers/base/sys.c	Mon Nov  4 14:31:00 2002
+++ b/drivers/base/sys.c	Mon Nov  4 14:31:00 2002
@@ -55,6 +55,9 @@
 	if (!root)
 		return -EINVAL;
 
+	if (!root->dev.parent)
+		root->dev.parent = &system_bus;
+
 	pr_debug("Registering system board %d\n",root->id);
 
 	error = device_register(&root->dev);
diff -Nru a/drivers/block/DAC960.c b/drivers/block/DAC960.c
--- a/drivers/block/DAC960.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/block/DAC960.c	Mon Nov  4 14:31:02 2002
@@ -2019,14 +2019,9 @@
 
 static int DAC960_revalidate(struct gendisk *disk)
 {
-	DAC960_Controller_T *p = disk->private_data;
-	int unit;
-	for (unit = 0; unit < DAC960_MaxLogicalDrives; unit++) {
-		if (p->disks[unit] == disk) {
-			set_capacity(disk, disk_size(p, unit));
-			return 0;
-		}
-	}
+	DAC960_Controller_T *p = disk->queue->queuedata;
+	int unit = (int)disk->private_data;
+	set_capacity(disk, disk_size(p, unit));
 	return 0;
 }
 
@@ -2205,7 +2200,7 @@
 		Controller->disks[i] = alloc_disk(1<<DAC960_MaxPartitionsBits);
 		if (!Controller->disks[i])
 			goto Enomem;
-		Controller->disks[i]->private_data = Controller;
+		Controller->disks[i]->private_data = (void*)i;
 		Controller->disks[i]->queue = &Controller->RequestQueue;
       }
       Controller->ControllerNumber = DAC960_ControllerCount;
@@ -2855,7 +2850,7 @@
     Command->CommandType = DAC960_ReadCommand;
   else Command->CommandType = DAC960_WriteCommand;
   Command->Completion = Request->waiting;
-  Command->LogicalDriveNumber = DAC960_LogicalDriveNumber(Request->rq_dev);
+  Command->LogicalDriveNumber = (int)Request->rq_disk->private_data;
   Command->BlockNumber = Request->sector;
   Command->BlockCount = Request->nr_sectors;
   Command->SegmentCount = Request->nr_phys_segments;
diff -Nru a/drivers/block/amiflop.c b/drivers/block/amiflop.c
--- a/drivers/block/amiflop.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/block/amiflop.c	Mon Nov  4 14:31:01 2002
@@ -208,7 +208,7 @@
 
 /* Prevent "aliased" accesses. */
 static int fd_ref[4] = { 0,0,0,0 };
-static kdev_t fd_device[4] = { NODEV, NODEV, NODEV, NODEV };
+static int fd_device[4] = { 0, 0, 0, 0 };
 
 /*
  * Here come the actual hardware access and helper functions.
@@ -1369,7 +1369,7 @@
 static void redo_fd_request(void)
 {
 	unsigned int cnt, block, track, sector;
-	int device, drive;
+	int drive;
 	struct amiga_floppy_struct *floppy;
 	char *data;
 	unsigned long flags;
@@ -1380,19 +1380,8 @@
 		return;
 	}
 
-	device = minor(CURRENT->rq_dev);
-	if (device < 8) {
-		/* manual selection */
-		drive = device & 3;
-	} else {
-		/* Auto-detection */
-#ifdef DEBUG
-		printk("redo_fd_request: can't handle auto detect\n");
-		printk("redo_fd_request: default to normal\n");
-#endif
-		drive = device & 3;
-	}
 	floppy = CURRENT->rq_disk->private_data;
+	drive = floppy - unit;
 
 	/* Here someone could investigate to be more efficient */
 	for (cnt = 0; cnt < CURRENT->current_nr_sectors; cnt++) { 
@@ -1594,17 +1583,16 @@
  */
 static int floppy_open(struct inode *inode, struct file *filp)
 {
-	int drive;
-	kdev_t old_dev;
+	int drive = minor(inode->i_rdev) & 3;
+	int system =  (minor(inode->i_rdev) & 4) >> 2;
+	int old_dev;
 	int system;
 	unsigned long flags;
 
-	drive = minor(inode->i_rdev) & 3;
 	old_dev = fd_device[drive];
 
-	if (fd_ref[drive])
-		if (!kdev_same(old_dev, inode->i_rdev))
-			return -EBUSY;
+	if (fd_ref[drive] && old_dev != system)
+		return -EBUSY;
 
 	if (filp && filp->f_mode & 3) {
 		check_disk_change(inode->i_bdev);
@@ -1625,17 +1613,16 @@
 	save_flags(flags);
 	cli();
 	fd_ref[drive]++;
-	fd_device[drive] = inode->i_rdev;
+	fd_device[drive] = system;
 #ifdef MODULE
 	if (unit[drive].motor == 0)
 		MOD_INC_USE_COUNT;
 #endif
 	restore_flags(flags);
 
-	if (!kdev_same(old_dev, NODEV) && !kdev_same(old_dev, inode->i_rdev))
-		invalidate_buffers(old_dev);
+	if (old_dev != system)
+		invalidate_buffers(mk_kdev(MAJOR_NR, drive + (system << 2));
 
-	system=(minor(inode->i_rdev) & 4)>>2;
 	unit[drive].dtype=&data_types[system];
 	unit[drive].blocks=unit[drive].type->heads*unit[drive].type->tracks*
 		data_types[system].sects*unit[drive].type->sect_mult;
diff -Nru a/drivers/block/ataflop.c b/drivers/block/ataflop.c
--- a/drivers/block/ataflop.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/block/ataflop.c	Mon Nov  4 14:31:01 2002
@@ -1438,8 +1438,9 @@
 
 static void redo_fd_request(void)
 {
-	int device, drive, type;
-  
+	int drive, type;
+	struct atari_floppy_struct *floppy;
+
 	DPRINT(("redo_fd_request: CURRENT=%p dev=%s CURRENT->sector=%ld\n",
 		CURRENT, !blk_queue_empty(QUEUE) ? CURRENT->rq_disk->disk_name : "",
 		!blk_queue_empty(QUEUE) ? CURRENT->sector : 0 ));
@@ -1451,9 +1452,9 @@
 	if (blk_queue_empty(QUEUE))
 		goto the_end;
 
-	device = minor(CURRENT->rq_dev);
-	drive = device & 3;
-	type = device >> 2;
+	floppy = CURRENT->rq_disk->private_data;
+	drive = floppy - unit;
+	type = fd_device[drive];
 	
 	if (!UD.connected) {
 		/* drive not connected */
@@ -1857,7 +1858,7 @@
 	int old_dev = fd_device[drive];
 
 	DPRINT(("fd_open: type=%d\n",type));
-	if (fd_ref[drive] && old_dev != minor(inode->i_rdev))
+	if (fd_ref[drive] && old_dev != type)
 		return -EBUSY;
 
 	if (fd_ref[drive] == -1 || (fd_ref[drive] && filp->f_flags & O_EXCL))
@@ -1868,10 +1869,10 @@
 	else
 		fd_ref[drive]++;
 
-	fd_device[drive] = minor(inode->i_rdev);
+	fd_device[drive] = type;
 
-	if (old_dev && old_dev != minor(inode->i_rdev))
-		invalidate_buffers(mk_kdev(FLOPPY_MAJOR, old_dev));
+	if (old_dev && old_dev != type)
+		invalidate_buffers(mk_kdev(FLOPPY_MAJOR, drive + (type<<2)));
 
 	if (filp->f_flags & O_NDELAY)
 		return 0;
diff -Nru a/drivers/block/elevator.c b/drivers/block/elevator.c
--- a/drivers/block/elevator.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/block/elevator.c	Mon Nov  4 14:31:02 2002
@@ -69,7 +69,7 @@
 	 * if the device is different (not a normal case) just check if
 	 * bio is after rq
 	 */
-	if (!kdev_same(next_rq->rq_dev, rq->rq_dev))
+	if (next_rq->rq_disk != rq->rq_disk)
 		return bio->bi_sector > rq->sector;
 
 	/*
@@ -112,7 +112,7 @@
 	/*
 	 * same device and no special stuff set, merge is ok
 	 */
-	if (kdev_same(rq->rq_dev, to_kdev_t(bio->bi_bdev->bd_dev)) &&
+	if (rq->rq_disk == bio->bi_bdev->bd_disk &&
 	    !rq->waiting && !rq->special)
 		return 1;
 
diff -Nru a/drivers/block/floppy.c b/drivers/block/floppy.c
--- a/drivers/block/floppy.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/block/floppy.c	Mon Nov  4 14:31:01 2002
@@ -2158,12 +2158,13 @@
 		DRS->track = NEED_2_RECAL;
 }
 
-static void set_floppy(kdev_t device)
+static void set_floppy(int drive)
 {
-	if (TYPE(device))
-		_floppy = TYPE(device) + floppy_type;
+	int type = ITYPE(UDRS->fd_device);
+	if (type)
+		_floppy = floppy_type + type;
 	else
-		_floppy = current_type[ DRIVE(device) ];
+		_floppy = current_type[ drive ];
 }
 
 /*
@@ -2269,7 +2270,7 @@
 	int drive=DRIVE(device);
 
 	LOCK_FDC(drive,1);
-	set_floppy(device);
+	set_floppy(drive);
 	if (!_floppy ||
 	    _floppy->track > DP->tracks ||
 	    tmp_format_req->track >= _floppy->track ||
@@ -2631,7 +2632,7 @@
 		return 0;
 	}
 
-	set_fdc(DRIVE(current_req->rq_dev));
+	set_fdc((int)current_req->rq_disk->private_data);
 
 	raw_cmd = &default_raw_cmd;
 	raw_cmd->flags = FD_RAW_SPIN | FD_RAW_NEED_DISK | FD_RAW_NEED_DISK |
@@ -2902,7 +2903,7 @@
 static void redo_fd_request(void)
 {
 #define REPEAT {request_done(0); continue; }
-	kdev_t device;
+	int drive;
 	int tmp;
 
 	lastredo = jiffies;
@@ -2919,11 +2920,11 @@
 			}
 			current_req = req;
 		}
-		device = current_req->rq_dev;
-		set_fdc(DRIVE(device));
+		drive = (int)current_req->rq_disk->private_data;
+		set_fdc(drive);
 		reschedule_timeout(current_reqD, "redo fd request", 0);
 
-		set_floppy(device);
+		set_floppy(drive);
 		raw_cmd = & default_raw_cmd;
 		raw_cmd->flags = 0;
 		if (start_motor(redo_fd_request)) return;
@@ -3594,7 +3595,7 @@
 			if (type)
 				return -EINVAL;
 			LOCK_FDC(drive,1);
-			set_floppy(device);
+			set_floppy(drive);
 			CALL(i = raw_cmd_ioctl(cmd,(void *) param));
 			process_fd_request();
 			return i;
diff -Nru a/drivers/block/genhd.c b/drivers/block/genhd.c
--- a/drivers/block/genhd.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/block/genhd.c	Mon Nov  4 14:31:01 2002
@@ -252,14 +252,6 @@
 
 extern int blk_dev_init(void);
 
-struct device_class disk_devclass = {
-	.name		= "disk",
-};
-
-static struct bus_type disk_bus = {
-	name:		"block",
-};
- 
 static struct gendisk *base_probe(dev_t dev, int *part, void *data)
 {
 	char name[20];
@@ -268,6 +260,8 @@
 	return NULL;
 }
 
+struct subsystem block_subsys;
+
 int __init device_init(void)
 {
 	struct blk_probe *base = kmalloc(sizeof(struct blk_probe), GFP_KERNEL);
@@ -280,23 +274,116 @@
 	for (i = 1; i < MAX_BLKDEV; i++)
 		probes[i] = base;
 	blk_dev_init();
-	devclass_register(&disk_devclass);
-	bus_register(&disk_bus);
+	subsystem_register(&block_subsys);
 	return 0;
 }
 
-__initcall(device_init);
+subsys_initcall(device_init);
+
+
+
+/*
+ * kobject & sysfs bindings for block devices
+ */
+
+#define to_disk(obj) container_of(obj,struct gendisk,kobj)
+
+struct disk_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct gendisk *, char *, size_t, loff_t);
+};
+
+static ssize_t disk_attr_show(struct kobject * kobj, struct attribute * attr,
+			      char * page, size_t count, loff_t off)
+{
+	struct gendisk * disk = to_disk(kobj);
+	struct disk_attribute * disk_attr = container_of(attr,struct disk_attribute,attr);
+	ssize_t ret = 0;
+	if (disk_attr->show)
+		ret = disk_attr->show(disk,page,count,off);
+	return ret;
+}
+
+static struct sysfs_ops disk_sysfs_ops = {
+	.show	= &disk_attr_show,
+};
+
+static ssize_t disk_dev_read(struct gendisk * disk,
+			     char *page, size_t count, loff_t off)
+{
+	dev_t base = MKDEV(disk->major, disk->first_minor); 
+	return off ? 0 : sprintf(page, "%04x\n",base);
+}
+static ssize_t disk_range_read(struct gendisk * disk,
+			       char *page, size_t count, loff_t off)
+{
+	return off ? 0 : sprintf(page, "%d\n",disk->minors);
+}
+static ssize_t disk_size_read(struct gendisk * disk,
+			      char *page, size_t count, loff_t off)
+{
+	return off ? 0 : sprintf(page, "%llu\n",(unsigned long long)get_capacity(disk));
+}
+static inline unsigned MSEC(unsigned x)
+{
+	return x * 1000 / HZ;
+}
+static ssize_t disk_stat_read(struct gendisk * disk,
+			      char *page, size_t count, loff_t off)
+{
+	disk_round_stats(disk);
+	return off ? 0 : sprintf(page,
+		"%8u %8u %8llu %8u "
+		"%8u %8u %8llu %8u "
+		"%8u %8u %8u"
+		"\n",
+		disk->reads, disk->read_merges, (u64)disk->read_sectors,
+		MSEC(disk->read_ticks),
+		disk->writes, disk->write_merges, (u64)disk->write_sectors,
+		MSEC(disk->write_ticks),
+		disk->in_flight, MSEC(disk->io_ticks),
+		MSEC(disk->time_in_queue));
+}
+static struct disk_attribute disk_attr_dev = {
+	.attr = {.name = "dev", .mode = S_IRUGO },
+	.show	= disk_dev_read
+};
+static struct disk_attribute disk_attr_range = {
+	.attr = {.name = "range", .mode = S_IRUGO },
+	.show	= disk_range_read
+};
+static struct disk_attribute disk_attr_size = {
+	.attr = {.name = "size", .mode = S_IRUGO },
+	.show	= disk_size_read
+};
+static struct disk_attribute disk_attr_stat = {
+	.attr = {.name = "stat", .mode = S_IRUGO },
+	.show	= disk_stat_read
+};
 
-EXPORT_SYMBOL(disk_devclass);
+static struct attribute * default_attrs[] = {
+	&disk_attr_dev.attr,
+	&disk_attr_range.attr,
+	&disk_attr_size.attr,
+	&disk_attr_stat.attr,
+	NULL,
+};
 
-static void disk_release(struct device *dev)
+static void disk_release(struct kobject * kobj)
 {
-	struct gendisk *disk = dev->driver_data;
+	struct gendisk *disk = to_disk(kobj);
 	kfree(disk->random);
 	kfree(disk->part);
 	kfree(disk);
 }
 
+struct subsystem block_subsys = {
+	.kobj	= { .name = "block" },
+	.release	= disk_release,
+	.sysfs_ops	= &disk_sysfs_ops,
+	.default_attrs	= default_attrs,
+};
+
 struct gendisk *alloc_disk(int minors)
 {
 	struct gendisk *disk = kmalloc(sizeof(struct gendisk), GFP_KERNEL);
@@ -314,11 +401,9 @@
 		disk->minors = minors;
 		while (minors >>= 1)
 			disk->minor_shift++;
+		kobject_init(&disk->kobj);
+		disk->kobj.subsys = &block_subsys;
 		INIT_LIST_HEAD(&disk->full_list);
-		disk->disk_dev.bus = &disk_bus;
-		disk->disk_dev.release = disk_release;
-		disk->disk_dev.driver_data = disk;
-		device_initialize(&disk->disk_dev);
 	}
 	rand_initialize_disk(disk);
 	return disk;
@@ -332,14 +417,13 @@
 	owner = disk->fops->owner;
 	if (owner && !try_inc_mod_count(owner))
 		return NULL;
-	atomic_inc(&disk->disk_dev.refcount);
-	return disk;
+	return to_disk(kobject_get(&disk->kobj));
 }
 
 void put_disk(struct gendisk *disk)
 {
 	if (disk)
-		put_device(&disk->disk_dev);
+		kobject_put(&disk->kobj);
 }
 
 EXPORT_SYMBOL(alloc_disk);
diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
--- a/drivers/block/ll_rw_blk.c	Mon Nov  4 14:31:00 2002
+++ b/drivers/block/ll_rw_blk.c	Mon Nov  4 14:31:00 2002
@@ -27,6 +27,10 @@
 #include <linux/completion.h>
 #include <linux/slab.h>
 
+/*
+ * Disk stats 
+ */
+struct disk_stat dkstat;
 
 /*
  * For the allocated request tables
@@ -580,8 +584,8 @@
 
 	if (unlikely((rq->flags & REQ_QUEUED))) {
 		printk(KERN_ERR 
-		       "request %p for device [02%x:02%x] already tagged %d",
-		       rq, major(rq->rq_dev), minor(rq->rq_dev), rq->tag);
+		       "request %p for device [%s] already tagged %d",
+		       rq, rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->tag);
 		BUG();
 	}
 
@@ -661,7 +665,8 @@
 {
 	int bit;
 
-	printk("%s: dev %02x:%02x: flags = ", msg, major(rq->rq_dev), minor(rq->rq_dev));
+	printk("%s: dev %s: flags = ", msg,
+		rq->rq_disk ? rq->rq_disk->disk_name : "?");
 	bit = 0;
 	do {
 		if (rq->flags & (1 << bit))
@@ -1406,9 +1411,8 @@
 
 void drive_stat_acct(struct request *rq, int nr_sectors, int new_io)
 {
-	unsigned int major = major(rq->rq_dev);
 	int rw = rq_data_dir(rq);
-	unsigned int index;
+	unsigned int major, index;
 
 	if (!rq->rq_disk)
 		return;
@@ -1427,18 +1431,19 @@
 		rq->rq_disk->in_flight++;
 	}
 
+	major = rq->rq_disk->major;
 	index = rq->rq_disk->first_minor >> rq->rq_disk->minor_shift;
 
 	if ((index >= DK_MAX_DISK) || (major >= DK_MAX_MAJOR))
 		return;
 
-	kstat.dk_drive[major][index] += new_io;
+	dkstat.drive[major][index] += new_io;
 	if (rw == READ) {
-		kstat.dk_drive_rio[major][index] += new_io;
-		kstat.dk_drive_rblk[major][index] += nr_sectors;
+		dkstat.drive_rio[major][index] += new_io;
+		dkstat.drive_rblk[major][index] += nr_sectors;
 	} else if (rw == WRITE) {
-		kstat.dk_drive_wio[major][index] += new_io;
-		kstat.dk_drive_wblk[major][index] += nr_sectors;
+		dkstat.drive_wio[major][index] += new_io;
+		dkstat.drive_wblk[major][index] += nr_sectors;
 	} else
 		printk(KERN_ERR "drive_stat_acct: cmd not R/W?\n");
 }
@@ -1582,7 +1587,7 @@
 		return;
 
 	if (rq_data_dir(req) != rq_data_dir(next)
-	    || !kdev_same(req->rq_dev, next->rq_dev)
+	    || req->rq_disk != next->rq_disk
 	    || next->waiting || next->special)
 		return;
 
@@ -1794,7 +1799,6 @@
 	req->buffer = bio_data(bio);	/* see ->buffer comment above */
 	req->waiting = NULL;
 	req->bio = req->biotail = bio;
-	req->rq_dev = to_kdev_t(bio->bi_bdev->bd_dev);
 	req->rq_disk = bio->bi_bdev->bd_disk;
 	req->start_time = jiffies;
 	add_request(q, req, insert_here);
@@ -2014,7 +2018,7 @@
 		error = -EIO;
 		if (!(req->flags & REQ_QUIET))
 			printk("end_request: I/O error, dev %s, sector %llu\n",
-				kdevname(req->rq_dev),
+				req->rq_disk ? req->rq_disk->disk_name : "?",
 				(unsigned long long)req->sector);
 	}
 
diff -Nru a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c
--- a/drivers/block/ps2esdi.c	Mon Nov  4 14:31:00 2002
+++ b/drivers/block/ps2esdi.c	Mon Nov  4 14:31:00 2002
@@ -74,7 +74,7 @@
 
 static void do_ps2esdi_request(request_queue_t * q);
 
-static void ps2esdi_readwrite(int cmd, u_char drive, u_int block, u_int count);
+static void ps2esdi_readwrite(int cmd, struct request *req);
 
 static void ps2esdi_fill_cmd_block(u_short * cmd_blk, u_short cmd,
 u_short cyl, u_short head, u_short sector, u_short length, u_char drive);
@@ -567,7 +567,7 @@
 	struct ps2esdi_i_struct *p = req->rq_disk->private_data;
 	unsigned block = req->sector;
 	unsigned count = req->current_nr_sectors;
-	int drive = DEVICE_NR(req->rq_dev);
+	int drive = p - ps2esdi_info;
 	u_short track, head, cylinder, sector;
 	u_short cmd_blk[TYPE_1_CMD_BLK_LENGTH];
 
diff -Nru a/drivers/block/rd.c b/drivers/block/rd.c
--- a/drivers/block/rd.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/block/rd.c	Mon Nov  4 14:31:02 2002
@@ -204,7 +204,7 @@
 		kunmap(vec->bv_page);
 
 		if (rw == READ) {
-			flush_dcache_page(sbh->b_page);
+			flush_dcache_page(vec->bv_page);
 		} else {
 			SetPageDirty(page);
 		}
@@ -300,6 +300,8 @@
 {
 	extern void free_initrd_mem(unsigned long, unsigned long);
 
+	blkdev_put(inode->i_bdev, BDEV_FILE);
+
 	spin_lock(&initrd_users_lock);
 	if (!--initrd_users) {
 		spin_unlock(&initrd_users_lock);
@@ -309,8 +311,6 @@
 	} else {
 		spin_unlock(&initrd_users_lock);
 	}
-		
-	blkdev_put(inode->i_bdev, BDEV_FILE);
 	return 0;
 }
 
@@ -348,6 +348,7 @@
 	 */
 	if (rd_bdev[unit] == NULL) {
 		struct block_device *bdev = inode->i_bdev;
+		atomic_inc(&bdev->bd_count);
 		rd_bdev[unit] = bdev;
 		bdev->bd_openers++;
 		bdev->bd_block_size = rd_blocksize;
diff -Nru a/drivers/block/scsi_ioctl.c b/drivers/block/scsi_ioctl.c
--- a/drivers/block/scsi_ioctl.c	Mon Nov  4 14:31:03 2002
+++ b/drivers/block/scsi_ioctl.c	Mon Nov  4 14:31:03 2002
@@ -51,7 +51,6 @@
 	DECLARE_COMPLETION(wait);
 	int err = 0;
 
-	rq->rq_dev = to_kdev_t(bdev->bd_dev);
 	rq->rq_disk = bdev->bd_disk;
 
 	/*
@@ -227,6 +226,7 @@
 	/*
 	 * fill in request structure
 	 */
+	rq->cmd_len = hdr.cmd_len;
 	copy_from_user(rq->cmd, hdr.cmdp, hdr.cmd_len);
 	if (sizeof(rq->cmd) != hdr.cmd_len)
 		memset(rq->cmd + hdr.cmd_len, 0, sizeof(rq->cmd) - hdr.cmd_len);
@@ -349,6 +349,7 @@
 	 * get command and data to send to device, if any
 	 */
 	err = -EFAULT;
+	rq->cmd_len = cmdlen;
 	if (copy_from_user(rq->cmd, sic->data, cmdlen))
 		goto error;
 
@@ -463,6 +464,7 @@
 			memset(rq->cmd, 0, sizeof(rq->cmd));
 			rq->cmd[0] = GPCMD_START_STOP_UNIT;
 			rq->cmd[4] = 0x02 + (close != 0);
+			rq->cmd_len = 6;
 			err = blk_do_rq(q, bdev, rq);
 			blk_put_request(rq);
 			break;
diff -Nru a/drivers/block/z2ram.c b/drivers/block/z2ram.c
--- a/drivers/block/z2ram.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/block/z2ram.c	Mon Nov  4 14:31:02 2002
@@ -295,7 +295,7 @@
 
 	current_device = device;
 	z2ram_size <<= Z2RAM_CHUNKSHIFT;
-	set_capacity(z2ram_gendisk, z2ram_size >> 9;   
+	set_capacity(z2ram_gendisk, z2ram_size >> 9);
     }
 
     return 0;
diff -Nru a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
--- a/drivers/bluetooth/hci_bcsp.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/bluetooth/hci_bcsp.c	Mon Nov  4 14:31:02 2002
@@ -701,7 +701,13 @@
 
 int bcsp_init(void)
 {
-	return hci_uart_register_proto(&bcsp);
+	int err = hci_uart_register_proto(&bcsp);
+	if (!err)
+		BT_INFO("HCI BCSP protocol initialized");
+	else
+		BT_ERR("HCI BCSP protocol registration failed");
+
+	return err;
 }
 
 int bcsp_deinit(void)
diff -Nru a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c
--- a/drivers/bluetooth/hci_h4.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/bluetooth/hci_h4.c	Mon Nov  4 14:31:01 2002
@@ -269,7 +269,13 @@
 	      
 int h4_init(void)
 {
-	return hci_uart_register_proto(&h4p);
+	int err = hci_uart_register_proto(&h4p);
+	if (!err)
+		BT_INFO("HCI H4 protocol initialized");
+	else
+		BT_ERR("HCI H4 protocol registration failed");
+	
+	return err;
 }
 
 int h4_deinit(void)
diff -Nru a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
--- a/drivers/bluetooth/hci_ldisc.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/bluetooth/hci_ldisc.c	Mon Nov  4 14:31:02 2002
@@ -344,7 +344,8 @@
 	if (tty != hu->tty)
 		return;
 
-	hci_uart_tx_wakeup(hu);
+	if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
+		hci_uart_tx_wakeup(hu);
 }
 
 /* hci_uart_tty_room()
@@ -521,9 +522,7 @@
 	static struct tty_ldisc hci_uart_ldisc;
 	int err;
 
-	BT_INFO("Bluetooth HCI UART driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-		VERSION);
-	BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
+	BT_INFO("HCI UART driver ver %s", VERSION);
 
 	/* Register the tty discipline */
 
@@ -541,7 +540,7 @@
 	hci_uart_ldisc.write_wakeup= hci_uart_tty_wakeup;
 
 	if ((err = tty_register_ldisc(N_HCI, &hci_uart_ldisc))) {
-		BT_ERR("Can't register HCI line discipline (%d)", err);
+		BT_ERR("HCI line discipline registration failed. (%d)", err);
 		return err;
 	}
 
diff -Nru a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h
--- a/drivers/bluetooth/hci_uart.h	Mon Nov  4 14:31:00 2002
+++ b/drivers/bluetooth/hci_uart.h	Mon Nov  4 14:31:00 2002
@@ -68,7 +68,7 @@
 };
 
 /* HCI_UART flag bits */
-#define HCI_UART_PROTO_SET		0x00
+#define HCI_UART_PROTO_SET		0
 
 /* TX states  */
 #define HCI_UART_SENDING		1
diff -Nru a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
--- a/drivers/bluetooth/hci_usb.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/bluetooth/hci_usb.c	Mon Nov  4 14:31:02 2002
@@ -805,9 +805,7 @@
 {
 	int err;
 
-	BT_INFO("Bluetooth HCI USB driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",  
-		VERSION);
-	BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
+	BT_INFO("HCI USB driver ver %s", VERSION);
 
 	if ((err = usb_register(&hci_usb_driver)) < 0)
 		BT_ERR("Failed to register HCI USB driver");
diff -Nru a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
--- a/drivers/bluetooth/hci_vhci.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/bluetooth/hci_vhci.c	Mon Nov  4 14:31:02 2002
@@ -331,9 +331,7 @@
 
 int __init hci_vhci_init(void)
 {
-	BT_INFO("Bluetooth VHCI driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",  
-		VERSION);
-	BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
+	BT_INFO("VHCI driver ver %s", VERSION);
 
 	if (misc_register(&hci_vhci_miscdev)) {
 		BT_ERR("Can't register misc device %d\n", VHCI_MINOR);
diff -Nru a/drivers/char/Makefile b/drivers/char/Makefile
--- a/drivers/char/Makefile	Mon Nov  4 14:31:02 2002
+++ b/drivers/char/Makefile	Mon Nov  4 14:31:02 2002
@@ -7,14 +7,14 @@
 #
 FONTMAPFILE = cp437.uni
 
-obj-y	 += mem.o tty_io.o n_tty.o tty_ioctl.o pty.o misc.o random.o eventpoll.o
+obj-y	 += mem.o tty_io.o n_tty.o tty_ioctl.o pty.o misc.o random.o
 
 # All of the (potential) objects that export symbols.
 # This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
 
 export-objs     :=	busmouse.o vt.o generic_serial.o ip2main.o \
 			ite_gpio.o keyboard.o misc.o nvram.o random.o rtc.o \
-			selection.o sonypi.o sysrq.o tty_io.o tty_ioctl.o eventpoll.o
+			selection.o sonypi.o sysrq.o tty_io.o tty_ioctl.o
 
 obj-$(CONFIG_VT) += vt_ioctl.o vc_screen.o consolemap.o consolemap_deftbl.o selection.o keyboard.o
 obj-$(CONFIG_HW_CONSOLE) += vt.o defkeymap.o
@@ -57,7 +57,6 @@
 obj-$(CONFIG_R3964) += n_r3964.o
 obj-$(CONFIG_APPLICOM) += applicom.o
 obj-$(CONFIG_SONYPI) += sonypi.o
-obj-$(CONFIG_ATARIMOUSE) += atarimouse.o
 obj-$(CONFIG_RTC) += rtc.o
 obj-$(CONFIG_GEN_RTC) += genrtc.o
 obj-$(CONFIG_EFI_RTC) += efirtc.o
diff -Nru a/drivers/char/amiserial.c b/drivers/char/amiserial.c
--- a/drivers/char/amiserial.c	Mon Nov  4 14:31:03 2002
+++ b/drivers/char/amiserial.c	Mon Nov  4 14:31:03 2002
@@ -2054,8 +2054,8 @@
 	return ret;
 }
 
-int rs_read_proc(char *page, char **start, off_t off, int count,
-		 int *eof, void *data)
+static int rs_read_proc(char *page, char **start, off_t off, int count,
+			int *eof, void *data)
 {
 	int len = 0, l;
 	off_t	begin = 0;
diff -Nru a/drivers/char/eventpoll.c b/drivers/char/eventpoll.c
--- a/drivers/char/eventpoll.c	Mon Nov  4 14:31:01 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1438 +0,0 @@
-/*
- *  drivers/char/eventpoll.c ( Efficent event polling implementation )
- *  Copyright (C) 2001,...,2002  Davide Libenzi
- *
- *  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.
- *
- *  Davide Libenzi <davidel@xmailserver.org>
- *
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/fs.h>
-#include <linux/file.h>
-#include <linux/signal.h>
-#include <linux/errno.h>
-#include <linux/mm.h>
-#include <linux/vmalloc.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/miscdevice.h>
-#include <linux/random.h>
-#include <linux/smp_lock.h>
-#include <linux/wrapper.h>
-#include <linux/string.h>
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <linux/wait.h>
-#include <linux/fcblist.h>
-#include <linux/rwsem.h>
-#include <asm/bitops.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/mman.h>
-#include <asm/atomic.h>
-#include <linux/eventpoll.h>
-
-
-
-#define EVENTPOLLFS_MAGIC 0x03111965 /* My birthday should work for this :) */
-
-#define DEBUG_EPOLL 0
-
-#if DEBUG_EPOLL > 0
-#define DPRINTK(x) printk x
-#define DNPRINTK(n, x) do { if ((n) <= DEBUG_EPOLL) printk x; } while (0)
-#else /* #if DEBUG_EPOLL > 0 */
-#define DPRINTK(x) (void) 0
-#define DNPRINTK(n, x) (void) 0
-#endif /* #if DEBUG_EPOLL > 0 */
-
-#define DEBUG_DPI 0
-
-#if DEBUG_DPI != 0
-#define DPI_SLAB_DEBUG (SLAB_DEBUG_FREE | SLAB_RED_ZONE /* | SLAB_POISON */)
-#else /* #if DEBUG_DPI != 0 */
-#define DPI_SLAB_DEBUG 0
-#endif /* #if DEBUG_DPI != 0 */
-
-#define INITIAL_HASH_BITS 7
-#define MAX_HASH_BITS 18
-#define RESIZE_LENGTH 2
-
-#define DPI_MEM_ALLOC()	(struct epitem *) kmem_cache_alloc(dpi_cache, SLAB_KERNEL)
-#define DPI_MEM_FREE(p) kmem_cache_free(dpi_cache, p)
-#define IS_FILE_EPOLL(f) ((f)->f_op == &eventpoll_fops)
-
-
-/*
- * Type used for versioning events snapshots inside the double buffer.
- */
-typedef unsigned long long event_version_t;
-
-/*
- * This structure is stored inside the "private_data" member of the file
- * structure and rapresent the main data sructure for the eventpoll
- * interface.
- */
-struct eventpoll {
-	/*
-	 * Protect the evenpoll interface from sys_epoll_ctl(2), ioctl(EP_POLL)
-	 * and ->write() concurrency. It basically serialize the add/remove/edit
-	 * of items in the interest set.
-	 */
-	struct rw_semaphore acsem;
-
-	/*
-	 * Protect the this structure access. When the "acsem" is acquired
-	 * togheter with this one, "acsem" should be acquired first. Or,
-	 * "lock" nests inside "acsem".
-	 */
-	rwlock_t lock;
-
-	/* Wait queue used by sys_epoll_wait() and ioctl(EP_POLL) */
-	wait_queue_head_t wq;
-
-	/* Wait queue used by file->poll() */
-	wait_queue_head_t poll_wait;
-
-	/* This is the hash used to store the "struct epitem" elements */
-	struct list_head *hash;
-
-	unsigned int hbits;
-	unsigned int hmask;
-	atomic_t hents;
-	atomic_t resize;
-
-	/* Number of pages currently allocated in each side of the double buffer */
-	int numpages;
-
-	/*
-	 * Current page set pointer, switched from "pages0" and "pages1" each time
-	 * ep_poll() returns events to the caller.
-	 */
-	char **pages;
-
-	/* Each one of these contains the pages allocated for each side of
-	 * the double buffer.
-	 */
-	char *pages0[MAX_EVENTPOLL_PAGES];
-	char *pages1[MAX_EVENTPOLL_PAGES];
-
-	/*
-	 * Variable containing the vma base address where the double buffer
-	 * pages are mapped onto.
-	 */
-	unsigned long vmabase;
-
-	/*
-	 * Certain functions cannot be called if the double buffer pages are
-	 * not allocated and if the memory mapping is not in place. This tells
-	 * us that everything is setup to fully use the interface.
-	 */
-	atomic_t mmapped;
-
-	/* Number of events currently available inside the current snapshot */
-	int eventcnt;
-
-	/*
-	 * Variable storing the current "version" of the snapshot. It is used
-	 * to validate the validity of the current slot pointed by the "index"
-	 * member of a "struct epitem".
-	 */
-	event_version_t ver;
-};
-
-/*
- * Each file descriptor added to the eventpoll interface will
- * have an entry of this type linked to the hash.
- */
-struct epitem {
-	/* List header used to link this structure to the eventpoll hash */
-	struct list_head llink;
-
-	/* The "container" of this item */
-	struct eventpoll *ep;
-
-	/* The file this item refers to */
-	struct file *file;
-
-	/* The structure that describe the interested events and the source fd */
-	struct pollfd pfd;
-
-	/*
-	 * The index inside the current double buffer that stores the active
-	 * event slot for this item ( file ).
-	 */
-	int index;
-
-	/*
-	 * The version that is used to validate if the current slot is still
-	 * valid or if it refers to an old snapshot. It is matches togheter
-	 * with the one inside the eventpoll structure.
-	 */
-	event_version_t ver;
-};
-
-
-
-
-static int ep_getfd(int *efd, struct inode **einode, struct file **efile);
-static int ep_alloc_pages(char **pages, int numpages);
-static int ep_free_pages(char **pages, int numpages);
-static int ep_init(struct eventpoll *ep);
-static void ep_free(struct eventpoll *ep);
-static struct epitem *ep_find_nl(struct eventpoll *ep, int fd);
-static struct epitem *ep_find(struct eventpoll *ep, int fd);
-static int ep_hashresize(struct eventpoll *ep, unsigned long *kflags);
-static int ep_insert(struct eventpoll *ep, struct pollfd *pfd);
-static int ep_remove(struct eventpoll *ep, struct epitem *dpi);
-static void notify_proc(struct file *file, void *data, unsigned long *local,
-			long *event);
-static int open_eventpoll(struct inode *inode, struct file *file);
-static int close_eventpoll(struct inode *inode, struct file *file);
-static unsigned int poll_eventpoll(struct file *file, poll_table *wait);
-static int write_eventpoll(struct file *file, const char *buffer, size_t count,
-			   loff_t *ppos);
-static int ep_poll(struct eventpoll *ep, struct evpoll *dvp);
-static int ep_do_alloc_pages(struct eventpoll *ep, int numpages);
-static int ioctl_eventpoll(struct inode *inode, struct file *file,
-			   unsigned int cmd, unsigned long arg);
-static void eventpoll_mm_open(struct vm_area_struct * vma);
-static void eventpoll_mm_close(struct vm_area_struct * vma);
-static int mmap_eventpoll(struct file *file, struct vm_area_struct *vma);
-static int eventpollfs_delete_dentry(struct dentry *dentry);
-static struct inode *get_eventpoll_inode(void);
-static struct super_block *eventpollfs_get_sb(struct file_system_type *fs_type,
-					      int flags, char *dev_name, void *data);
-
-
-
-/* Slab cache used to allocate "struct epitem" */
-static kmem_cache_t *dpi_cache;
-
-/* Virtual fs used to allocate inodes for eventpoll files */
-static struct vfsmount *eventpoll_mnt;
-
-/* File callbacks that implement the eventpoll file behaviour */
-static struct file_operations eventpoll_fops = {
-	.write		= write_eventpoll,
-	.ioctl		= ioctl_eventpoll,
-	.mmap		= mmap_eventpoll,
-	.open		= open_eventpoll,
-	.release	= close_eventpoll,
-	.poll		= poll_eventpoll
-};
-
-/* Memory mapping callbacks for the eventpoll file */
-static struct vm_operations_struct eventpoll_mmap_ops = {
-	.open		= eventpoll_mm_open,
-	.close		= eventpoll_mm_close,
-};
-
-/*
- * The "struct miscdevice" is used to register the eventpoll device
- * to make it suitable to be openend from a /dev file.
- */
-static struct miscdevice eventpoll_miscdev = {
-	EVENTPOLL_MINOR, "eventpoll", &eventpoll_fops
-};
-
-/*
- * This is used to register the virtual file system from where
- * eventpoll inodes are allocated.
- */
-static struct file_system_type eventpoll_fs_type = {
-	.name		= "eventpollfs",
-	.get_sb		= eventpollfs_get_sb,
-	.kill_sb	= kill_anon_super,
-};
-
-/* Very basic directory entry operations for the eventpoll virtual file system */
-static struct dentry_operations eventpollfs_dentry_operations = {
-	.d_delete	= eventpollfs_delete_dentry,
-};
-
-
-
-/*
- * It opens an eventpoll file descriptor by allocating space for "maxfds"
- * file descriptors. It is the kernel part of the userspace epoll_create(2).
- */
-asmlinkage int sys_epoll_create(int maxfds)
-{
-	int error = -EINVAL, fd;
-	unsigned long addr;
-	struct inode *inode;
-	struct file *file;
-	struct eventpoll *ep;
-
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d)\n",
-		     current, maxfds));
-
-	/*
-	 * It is not possible to store more than MAX_FDS_IN_EVENTPOLL file
-	 * descriptors inside the eventpoll interface.
-	 */
-	if (maxfds > MAX_FDS_IN_EVENTPOLL)
-		goto eexit_1;
-
-	/*
-	 * Creates all the items needed to setup an eventpoll file. That is,
-	 * a file structure, and inode and a free file descriptor.
-	 */
-	error = ep_getfd(&fd, &inode, &file);
-	if (error)
-		goto eexit_1;
-
-	/*
-	 * Calls the code to initialize the eventpoll file. This code is
-	 * the same as the "open" file operation callback because inside
-	 * ep_getfd() we did what the kernel usually does before invoking
-	 * corresponding file "open" callback.
-	 */
-	error = open_eventpoll(inode, file);
-	if (error)
-		goto eexit_2;
-
-	/* The "private_data" member is setup by open_eventpoll() */
-	ep = file->private_data;
-
-	/* Alloc pages for the event double buffer */
-	error = ep_do_alloc_pages(ep, EP_FDS_PAGES(maxfds + 1));
-	if (error)
-		goto eexit_2;
-
-	/*
-	 * Create a user space mapping of the event double buffer to
-	 * avoid kernel to user space memory copy when returning events
-	 * to the caller.
-	 */
-	down_write(&current->mm->mmap_sem);
-	addr = do_mmap_pgoff(file, 0, EP_MAP_SIZE(maxfds + 1), PROT_READ,
-			     MAP_PRIVATE, 0);
-	up_write(&current->mm->mmap_sem);
-	error = PTR_ERR((void *) addr);
-	if (IS_ERR((void *) addr))
-		goto eexit_2;
-
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n",
-		     current, maxfds, fd));
-
-	return fd;
-
-eexit_2:
-	sys_close(fd);
-eexit_1:
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n",
-		     current, maxfds, error));
-	return error;
-}
-
-
-/*
- * The following function implement the controller interface for the eventpoll
- * file that enable the insertion/removal/change of file descriptors inside
- * the interest set. It rapresents the kernel part of the user spcae epoll_ctl(2).
- */
-asmlinkage int sys_epoll_ctl(int epfd, int op, int fd, unsigned int events)
-{
-	int error = -EBADF;
-	struct file *file;
-	struct eventpoll *ep;
-	struct epitem *dpi;
-	struct pollfd pfd;
-
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %u)\n",
-		     current, epfd, op, fd, events));
-
-	file = fget(epfd);
-	if (!file)
-		goto eexit_1;
-
-	/*
-	 * We have to check that the file structure underneath the file descriptor
-	 * the user passed to us _is_ an eventpoll file.
-	 */
-	error = -EINVAL;
-	if (!IS_FILE_EPOLL(file))
-		goto eexit_2;
-
-	/*
-	 * At this point it is safe to assume that the "private_data" contains
-	 * our own data structure.
-	 */
-	ep = file->private_data;
-
-	down_write(&ep->acsem);
-
-	pfd.fd = fd;
-	pfd.events = events | POLLERR | POLLHUP;
-	pfd.revents = 0;
-
-	dpi = ep_find(ep, fd);
-
-	error = -EINVAL;
-	switch (op) {
-	case EP_CTL_ADD:
-		if (!dpi)
-			error = ep_insert(ep, &pfd);
-		else
-			error = -EEXIST;
-		break;
-	case EP_CTL_DEL:
-		if (dpi)
-			error = ep_remove(ep, dpi);
-		else
-			error = -ENOENT;
-		break;
-	case EP_CTL_MOD:
-		if (dpi) {
-			dpi->pfd.events = events;
-			error = 0;
-		} else
-			error = -ENOENT;
-		break;
-	}
-
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %u) = %d\n",
-		     current, epfd, op, fd, events, error));
-
-	up_write(&ep->acsem);
-
-eexit_2:
-	fput(file);
-eexit_1:
-	return error;
-}
-
-
-/*
- * Implement the event wait interface for the eventpoll file. It is the kernel
- * part of the user space epoll_wait(2).
- */
-asmlinkage int sys_epoll_wait(int epfd, struct pollfd const **events, int timeout)
-{
-	int error = -EBADF;
-	void *eaddr;
-	struct file *file;
-	struct eventpoll *ep;
-	struct evpoll dvp;
-
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_wait(%d, %p, %d)\n",
-		     current, epfd, events, timeout));
-
-	file = fget(epfd);
-	if (!file)
-		goto eexit_1;
-
-	/*
-	 * We have to check that the file structure underneath the file descriptor
-	 * the user passed to us _is_ an eventpoll file.
-	 */
-	error = -EINVAL;
-	if (!IS_FILE_EPOLL(file))
-		goto eexit_2;
-
-	/*
-	 * At this point it is safe to assume that the "private_data" contains
-	 * our own data structure.
-	 */
-	ep = file->private_data;
-
-	/*
-	 * It is possible that the user created an eventpoll file by open()ing
-	 * the corresponding /dev/ file and he did not perform the correct
-	 * initialization required by the old /dev/epoll interface. This test
-	 * protect us from this scenario.
-	 */
-	error = -EINVAL;
-	if (!atomic_read(&ep->mmapped))
-		goto eexit_2;
-
-	dvp.ep_timeout = timeout;
-	error = ep_poll(ep, &dvp);
-	if (error > 0) {
-		eaddr = (void *) (ep->vmabase + dvp.ep_resoff);
-		if (copy_to_user(events, &eaddr, sizeof(struct pollfd *)))
-			error = -EFAULT;
-	}
-
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_wait(%d, %p, %d) = %d\n",
-		     current, epfd, events, timeout, error));
-
-eexit_2:
-	fput(file);
-eexit_1:
-	return error;
-}
-
-
-/*
- * Creates the file descriptor to be used by the epoll interface.
- */
-static int ep_getfd(int *efd, struct inode **einode, struct file **efile)
-{
-	struct qstr this;
-	char name[32];
-	struct dentry *dentry;
-	struct inode *inode;
-	struct file *file;
-	int error, fd;
-
-	/* Get an ready to use file */
-	error = -ENFILE;
-	file = get_empty_filp();
-	if (!file)
-		goto eexit_1;
-
-	/* Allocates an inode from the eventpoll file system */
-	inode = get_eventpoll_inode();
-	error = PTR_ERR(inode);
-	if (IS_ERR(inode))
-		goto eexit_2;
-
-	/* Allocates a free descriptor to plug the file onto */
-	error = get_unused_fd();
-	if (error < 0)
-		goto eexit_3;
-	fd = error;
-
-	/*
-	 * Link the inode to a directory entry by creating a unique name
-	 * using the inode number.
-	 */
-	error = -ENOMEM;
-	sprintf(name, "[%lu]", inode->i_ino);
-	this.name = name;
-	this.len = strlen(name);
-	this.hash = inode->i_ino;
-	dentry = d_alloc(eventpoll_mnt->mnt_sb->s_root, &this);
-	if (!dentry)
-		goto eexit_4;
-	dentry->d_op = &eventpollfs_dentry_operations;
-	d_add(dentry, inode);
-	file->f_vfsmnt = mntget(eventpoll_mnt);
-	file->f_dentry = dget(dentry);
-
-	/*
-	 * Initialize the file as read/write because it could be used
-	 * with write() to add/remove/change interest sets.
-	 */
-	file->f_pos = 0;
-	file->f_flags = O_RDWR;
-	file->f_op = &eventpoll_fops;
-	file->f_mode = FMODE_READ | FMODE_WRITE;
-	file->f_version = 0;
-	file->private_data = NULL;
-
-	/* Install the new setup file into the allocated fd. */
-	fd_install(fd, file);
-
-	*efd = fd;
-	*einode = inode;
-	*efile = file;
-	return 0;
-
-eexit_4:
-	put_unused_fd(fd);
-eexit_3:
-	iput(inode);
-eexit_2:
-	put_filp(file);
-eexit_1:
-	return error;
-}
-
-
-static int ep_alloc_pages(char **pages, int numpages)
-{
-	int ii;
-
-	for (ii = 0; ii < numpages; ii++) {
-		pages[ii] = (char *) __get_free_pages(GFP_KERNEL, 0);
-		if (!pages[ii]) {
-			for (--ii; ii >= 0; ii--) {
-				ClearPageReserved(virt_to_page(pages[ii]));
-				free_pages((unsigned long) pages[ii], 0);
-			}
-			return -ENOMEM;
-		}
-		SetPageReserved(virt_to_page(pages[ii]));
-	}
-	return 0;
-}
-
-
-static int ep_free_pages(char **pages, int numpages)
-{
-	int ii;
-
-	for (ii = 0; ii < numpages; ii++) {
-		ClearPageReserved(virt_to_page(pages[ii]));
-		free_pages((unsigned long) pages[ii], 0);
-	}
-	return 0;
-}
-
-
-static int ep_init(struct eventpoll *ep)
-{
-	int ii, hentries;
-
-	init_rwsem(&ep->acsem);
-	rwlock_init(&ep->lock);
-	init_waitqueue_head(&ep->wq);
-	init_waitqueue_head(&ep->poll_wait);
-	ep->hbits = INITIAL_HASH_BITS;
-	ep->hmask = (1 << ep->hbits) - 1;
-	atomic_set(&ep->hents, 0);
-	atomic_set(&ep->resize, 0);
-	atomic_set(&ep->mmapped, 0);
-	ep->numpages = 0;
-	ep->vmabase = 0;
-	ep->pages = ep->pages0;
-	ep->eventcnt = 0;
-	ep->ver = 1;
-
-	hentries = ep->hmask + 1;
-	if (!(ep->hash = (struct list_head *) vmalloc(hentries * sizeof(struct list_head))))
-		return -ENOMEM;
-
-	for (ii = 0; ii < hentries; ii++)
-		INIT_LIST_HEAD(&ep->hash[ii]);
-
-	return 0;
-}
-
-
-static void ep_free(struct eventpoll *ep)
-{
-	int ii;
-	struct list_head *lsthead;
-
-	/*
-	 * Walks through the whole hash by unregistering file callbacks and
-	 * freeing each "struct epitem".
-	 */
-	for (ii = 0; ii <= ep->hmask; ii++) {
-		lsthead = &ep->hash[ii];
-		while (!list_empty(lsthead)) {
-			struct epitem *dpi = list_entry(lsthead->next, struct epitem, llink);
-
-			file_notify_delcb(dpi->file, notify_proc);
-			list_del(lsthead->next);
-			DPI_MEM_FREE(dpi);
-		}
-	}
-	/*
-	 * At this point we can free the hash and the pages used for the event
-	 * double buffer. The ep_free() function is called from the "close"
-	 * file operations callback, and this garanties us that the pages are
-	 * already unmapped.
-	 */
-	vfree(ep->hash);
-	if (ep->numpages > 0) {
-		ep_free_pages(ep->pages0, ep->numpages);
-		ep_free_pages(ep->pages1, ep->numpages);
-	}
-}
-
-
-/*
- * No lock version of ep_find(), used when the code had to acquire the lock
- * before calling the function.
- */
-static struct epitem *ep_find_nl(struct eventpoll *ep, int fd)
-{
-	struct epitem *dpi = NULL;
-	struct list_head *lsthead, *lnk;
-
-	lsthead = &ep->hash[fd & ep->hmask];
-	list_for_each(lnk, lsthead) {
-		dpi = list_entry(lnk, struct epitem, llink);
-
-		if (dpi->pfd.fd == fd) break;
-		dpi = NULL;
-	}
-
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_find(%d) -> %p\n",
-		     current, fd, dpi));
-
-	return dpi;
-}
-
-
-static struct epitem *ep_find(struct eventpoll *ep, int fd)
-{
-	struct epitem *dpi;
-	unsigned long flags;
-
-	read_lock_irqsave(&ep->lock, flags);
-
-	dpi = ep_find_nl(ep, fd);
-
-	read_unlock_irqrestore(&ep->lock, flags);
-
-	return dpi;
-}
-
-
-static int ep_hashresize(struct eventpoll *ep, unsigned long *kflags)
-{
-	struct list_head *hash, *oldhash;
-	unsigned int hbits = ep->hbits + 1;
-	unsigned int hmask = (1 << hbits) - 1;
-	int ii, res, hentries = hmask + 1;
-	unsigned long flags = *kflags;
-
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_hashresize(%p) bits=%u\n",
-		     current, ep, hbits));
-
-	write_unlock_irqrestore(&ep->lock, flags);
-
-	res = -ENOMEM;
-	if (!(hash = (struct list_head *) vmalloc(hentries * sizeof(struct list_head)))) {
-		write_lock_irqsave(&ep->lock, flags);
-		goto eexit_1;
-	}
-
-	for (ii = 0; ii < hentries; ii++)
-		INIT_LIST_HEAD(&hash[ii]);
-
-	write_lock_irqsave(&ep->lock, flags);
-
-	oldhash = ep->hash;
-	for (ii = 0; ii <= ep->hmask; ii++) {
-		struct list_head *oldhead = &oldhash[ii], *lnk;
-
-		while (!list_empty(oldhead)) {
-			struct epitem *dpi = list_entry(lnk = oldhead->next, struct epitem, llink);
-
-			list_del(lnk);
-			list_add(lnk, &hash[dpi->pfd.fd & hmask]);
-		}
-	}
-
-	ep->hash = hash;
-	ep->hbits = hbits;
-	ep->hmask = hmask;
-
-	write_unlock_irqrestore(&ep->lock, flags);
-	vfree(oldhash);
-	write_lock_irqsave(&ep->lock, flags);
-
-	res = 0;
-eexit_1:
-	*kflags = flags;
-	atomic_dec(&ep->resize);
-	return res;
-}
-
-
-static int ep_insert(struct eventpoll *ep, struct pollfd *pfd)
-{
-	int error;
-	struct epitem *dpi;
-	struct file *file;
-	unsigned long flags;
-
-	if (atomic_read(&ep->hents) >= (ep->numpages * POLLFD_X_PAGE))
-		return -E2BIG;
-
-	file = fget(pfd->fd);
-	if (!file)
-		return -EBADF;
-
-	error = -ENOMEM;
-	if (!(dpi = DPI_MEM_ALLOC()))
-		goto eexit_1;
-
-	INIT_LIST_HEAD(&dpi->llink);
-	dpi->ep = ep;
-	dpi->file = file;
-	dpi->pfd = *pfd;
-	dpi->index = -1;
-	dpi->ver = ep->ver - 1;
-
-	write_lock_irqsave(&ep->lock, flags);
-
-	list_add(&dpi->llink, &ep->hash[pfd->fd & ep->hmask]);
-	atomic_inc(&ep->hents);
-
-	if (!atomic_read(&ep->resize) &&
-	    (atomic_read(&ep->hents) >> ep->hbits) > RESIZE_LENGTH &&
-	    ep->hbits < MAX_HASH_BITS) {
-		atomic_inc(&ep->resize);
-		ep_hashresize(ep, &flags);
-	}
-
-	write_unlock_irqrestore(&ep->lock, flags);
-
-	file_notify_addcb(file, notify_proc, dpi);
-
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_insert(%p, %d)\n",
-		     current, ep, pfd->fd));
-
-	error = 0;
-eexit_1:
-	fput(file);
-
-	return error;
-}
-
-
-/*
- * Removes a "struct epitem" from the eventpoll hash and deallocates
- * all the associated resources.
- */
-static int ep_remove(struct eventpoll *ep, struct epitem *dpi)
-{
-	unsigned long flags;
-	struct pollfd *pfd, *lpfd;
-	struct epitem *ldpi;
-
-	/* First, removes the callback from the file callback list */
-	file_notify_delcb(dpi->file, notify_proc);
-
-	write_lock_irqsave(&ep->lock, flags);
-
-	list_del(&dpi->llink);
-	atomic_dec(&ep->hents);
-
-	/*
-	 * This is to remove stale events. We don't want that the removed file
-	 * has a pending event that might be associated with a file inserted
-	 * at a later time inside the eventpoll interface. this code checks
-	 * if the currently removed file has a valid pending event and, if it does,
-	 * manages things to remove it and decrement the currently available
-	 * event count.
-	 */
-	if (dpi->index >= 0 && dpi->ver == ep->ver && dpi->index < ep->eventcnt) {
-		pfd = (struct pollfd *) (ep->pages[EVENT_PAGE_INDEX(dpi->index)] +
-					 EVENT_PAGE_OFFSET(dpi->index));
-		if (pfd->fd == dpi->pfd.fd && dpi->index < --ep->eventcnt) {
-			lpfd = (struct pollfd *) (ep->pages[EVENT_PAGE_INDEX(ep->eventcnt)] +
-						  EVENT_PAGE_OFFSET(ep->eventcnt));
-			*pfd = *lpfd;
-
-			if ((ldpi = ep_find_nl(ep, pfd->fd))) ldpi->index = dpi->index;
-		}
-	}
-
-	write_unlock_irqrestore(&ep->lock, flags);
-
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_remove(%p, %d)\n",
-		     current, ep, dpi->pfd.fd));
-
-	/* At this point it is safe to free the eventpoll item */
-	DPI_MEM_FREE(dpi);
-
-	return 0;
-}
-
-
-/*
- * This is the event notify callback that is called from fs/fcblist.c because
- * of the registration ( file_notify_addcb() ) done in ep_insert().
- */
-static void notify_proc(struct file *file, void *data, unsigned long *local,
-			long *event)
-{
-	struct epitem *dpi = data;
-	struct eventpoll *ep = dpi->ep;
-	struct pollfd *pfd;
-
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: notify(%p, %p, %ld, %ld) ep=%p\n",
-		     current, file, data, event[0], event[1], ep));
-
-	/*
-	 * We don't need to disable IRQs here because the callback dispatch
-	 * routine inside fs/fcblist.c already call us with disabled IRQ.
-	 */
-	write_lock(&ep->lock);
-
-	/* We're not expecting any of those events. Jump out soon ... */
-	if (!(dpi->pfd.events & event[1]))
-		goto out;
-
-	/*
-	 * This logic determins if an active even slot is available for the
-	 * currently signaled file, or if we have to make space for a new one
-	 * and increment the number of ready file descriptors ( ep->eventcnt ).
-	 */
-	if (dpi->index < 0 || dpi->ver != ep->ver) {
-		if (ep->eventcnt >= (ep->numpages * POLLFD_X_PAGE))
-			goto out;
-		dpi->index = ep->eventcnt++;
-		dpi->ver = ep->ver;
-		pfd = (struct pollfd *) (ep->pages[EVENT_PAGE_INDEX(dpi->index)] +
-					 EVENT_PAGE_OFFSET(dpi->index));
-		*pfd = dpi->pfd;
-	} else {
-		pfd = (struct pollfd *) (ep->pages[EVENT_PAGE_INDEX(dpi->index)] +
-					 EVENT_PAGE_OFFSET(dpi->index));
-		if (pfd->fd != dpi->pfd.fd) {
-			if (ep->eventcnt >= (ep->numpages * POLLFD_X_PAGE))
-				goto out;
-			dpi->index = ep->eventcnt++;
-			pfd = (struct pollfd *) (ep->pages[EVENT_PAGE_INDEX(dpi->index)] +
-						 EVENT_PAGE_OFFSET(dpi->index));
-			*pfd = dpi->pfd;
-		}
-	}
-
-	/*
-	 * Merge event bits into the corresponding event slot inside the
-	 * double buffer.
-	 */
-	pfd->revents |= (pfd->events & event[1]);
-
-	/*
-	 * Wake up ( if active ) both the eventpoll wait list and the ->poll()
-	 * wait list.
-	 */
-	if (waitqueue_active(&ep->wq))
-		wake_up(&ep->wq);
-	if (waitqueue_active(&ep->poll_wait))
-		wake_up(&ep->poll_wait);
-out:
-	write_unlock(&ep->lock);
-}
-
-
-static int open_eventpoll(struct inode *inode, struct file *file)
-{
-	int res;
-	struct eventpoll *ep;
-
-	if (!(ep = kmalloc(sizeof(struct eventpoll), GFP_KERNEL)))
-		return -ENOMEM;
-
-	memset(ep, 0, sizeof(*ep));
-	if ((res = ep_init(ep))) {
-		kfree(ep);
-		return res;
-	}
-
-	file->private_data = ep;
-
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: open() ep=%p\n", current, ep));
-	return 0;
-}
-
-
-static int close_eventpoll(struct inode *inode, struct file *file)
-{
-	struct eventpoll *ep = file->private_data;
-
-	if (ep) {
-		ep_free(ep);
-		kfree(ep);
-	}
-
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: close() ep=%p\n", current, ep));
-	return 0;
-}
-
-
-static unsigned int poll_eventpoll(struct file *file, poll_table *wait)
-{
-	struct eventpoll *ep = file->private_data;
-
-	poll_wait(file, &ep->poll_wait, wait);
-	if (ep->eventcnt)
-		return POLLIN | POLLRDNORM;
-
-	return 0;
-}
-
-
-static int write_eventpoll(struct file *file, const char *buffer, size_t count,
-			   loff_t *ppos)
-{
-	int rcount;
-	struct eventpoll *ep = file->private_data;
-	struct epitem *dpi;
-	struct pollfd pfd;
-
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: write(%p, %d)\n", current, ep, count));
-
-	/* The size of the write must be a multiple of sizeof(struct pollfd) */
-	rcount = -EINVAL;
-	if (count % sizeof(struct pollfd))
-		goto eexit_1;
-
-	/*
-	 * And we have also to verify that that area is correctly accessible
-	 * for the user.
-	 */
-	if ((rcount = verify_area(VERIFY_READ, buffer, count)))
-		goto eexit_1;
-
-	down_write(&ep->acsem);
-
-	rcount = 0;
-
-	while (count > 0) {
-		if (__copy_from_user(&pfd, buffer, sizeof(pfd))) {
-			rcount = -EFAULT;
-			goto eexit_2;
-		}
-
-		dpi = ep_find(ep, pfd.fd);
-
-		if (pfd.fd >= current->files->max_fds || !current->files->fd[pfd.fd])
-			pfd.events = POLLREMOVE;
-		if (pfd.events & POLLREMOVE) {
-			if (dpi) {
-				ep_remove(ep, dpi);
-				rcount += sizeof(pfd);
-			}
-		}
-		else if (dpi) {
-			dpi->pfd.events = pfd.events;
-			rcount += sizeof(pfd);
-		} else {
-			pfd.revents = 0;
-			if (!ep_insert(ep, &pfd))
-				rcount += sizeof(pfd);
-		}
-
-		buffer += sizeof(pfd);
-		count -= sizeof(pfd);
-	}
-
-eexit_2:
-	up_write(&ep->acsem);
-eexit_1:
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: write(%p, %d) = %d\n",
-		     current, ep, count, rcount));
-
-	return rcount;
-}
-
-
-static int ep_poll(struct eventpoll *ep, struct evpoll *dvp)
-{
-	int res = 0;
-	long timeout;
-	unsigned long flags;
-	wait_queue_t wait;
-
-	/*
-	 * We don't want ep_poll() to be called if the correct sequence
-	 * of operations are performed to initialize it. This won't happen
-	 * for the system call interface but it could happen using the
-	 * old /dev/epoll interface, that is maintained for compatibility.
-	 */
-	if (!atomic_read(&ep->mmapped))
-		return -EINVAL;
-
-	write_lock_irqsave(&ep->lock, flags);
-
-	res = 0;
-	if (!ep->eventcnt) {
-		/*
-		 * We don't have any available event to return to the caller.
-		 * We need to sleep here, and we will be wake up by
-		 * notify_proc() when events will become available.
-		 */
-		init_waitqueue_entry(&wait, current);
-		add_wait_queue(&ep->wq, &wait);
-
-		/*
-		 * Calculate the timeout by checking for the "infinite" value ( -1 )
-		 * and the overflow condition ( > MAX_SCHEDULE_TIMEOUT / HZ ). The
-		 * passed timeout is in milliseconds, that why (t * HZ) / 1000.
-		 */
-		timeout = dvp->ep_timeout == -1 || dvp->ep_timeout > MAX_SCHEDULE_TIMEOUT / HZ ?
-			MAX_SCHEDULE_TIMEOUT: (dvp->ep_timeout * HZ) / 1000;
-
-		for (;;) {
-			/*
-			 * We don't want to sleep if the notify_proc() sends us
-			 * a wakeup in between. That's why we set the task state
-			 * to TASK_INTERRUPTIBLE before doing the checks.
-			 */
-			set_current_state(TASK_INTERRUPTIBLE);
-			if (ep->eventcnt || !timeout)
-				break;
-			if (signal_pending(current)) {
-				res = -EINTR;
-				break;
-			}
-
-			write_unlock_irqrestore(&ep->lock, flags);
-			timeout = schedule_timeout(timeout);
-			write_lock_irqsave(&ep->lock, flags);
-		}
-		remove_wait_queue(&ep->wq, &wait);
-
-		set_current_state(TASK_RUNNING);
-	}
-
-	/*
-	 * If we've been wake up because of events became available, we need to:
-	 *
-	 * 1) null the number of available ready file descriptors
-	 * 2) increment the version of the current ( next ) snapshot
-	 * 3) swap the double buffer to return the current one to the caller
-	 * 4) set the current ( for the user, previous for the interface ) offset
-	 */
-	if (!res && ep->eventcnt) {
-		res = ep->eventcnt;
-		ep->eventcnt = 0;
-		++ep->ver;
-		if (ep->pages == ep->pages0) {
-			ep->pages = ep->pages1;
-			dvp->ep_resoff = 0;
-		} else {
-			ep->pages = ep->pages0;
-			dvp->ep_resoff = ep->numpages * PAGE_SIZE;
-		}
-	}
-
-	write_unlock_irqrestore(&ep->lock, flags);
-
-	return res;
-}
-
-
-static int ep_do_alloc_pages(struct eventpoll *ep, int numpages)
-{
-	int res, pgalloc, pgcpy;
-	unsigned long flags;
-	char **pages, **pages0, **pages1;
-
-	if (atomic_read(&ep->mmapped))
-		return -EBUSY;
-	if (numpages > MAX_EVENTPOLL_PAGES)
-		return -EINVAL;
-
-	pgalloc = numpages - ep->numpages;
-	if ((pages = (char **) vmalloc(2 * (pgalloc + 1) * sizeof(char *))) == NULL)
-		return -ENOMEM;
-	pages0 = &pages[0];
-	pages1 = &pages[pgalloc + 1];
-
-	if ((res = ep_alloc_pages(pages0, pgalloc)))
-		goto eexit_1;
-
-	if ((res = ep_alloc_pages(pages1, pgalloc))) {
-		ep_free_pages(pages0, pgalloc);
-		goto eexit_1;
-	}
-
-	write_lock_irqsave(&ep->lock, flags);
-	pgcpy = (ep->numpages + pgalloc) > numpages ? numpages - ep->numpages: pgalloc;
-	if (pgcpy > 0) {
-		memcpy(&ep->pages0[ep->numpages], pages0, pgcpy * sizeof(char *));
-		memcpy(&ep->pages1[ep->numpages], pages1, pgcpy * sizeof(char *));
-		ep->numpages += pgcpy;
-	}
-	write_unlock_irqrestore(&ep->lock, flags);
-
-	if (pgcpy < pgalloc) {
-		if (pgcpy < 0)
-			pgcpy = 0;
-		ep_free_pages(&pages0[pgcpy], pgalloc - pgcpy);
-		ep_free_pages(&pages1[pgcpy], pgalloc - pgcpy);
-	}
-
-eexit_1:
-	vfree(pages);
-	return res;
-}
-
-
-static int ioctl_eventpoll(struct inode *inode, struct file *file,
-			   unsigned int cmd, unsigned long arg)
-{
-	int res;
-	struct eventpoll *ep = file->private_data;
-	struct epitem *dpi;
-	unsigned long flags;
-	struct pollfd pfd;
-	struct evpoll dvp;
-
-	switch (cmd) {
-	case EP_ALLOC:
-		res = ep_do_alloc_pages(ep, EP_FDS_PAGES(arg));
-
-		DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ioctl(%p, EP_ALLOC, %lu) == %d\n",
-			     current, ep, arg, res));
-		return res;
-
-	case EP_FREE:
-		if (atomic_read(&ep->mmapped))
-			return -EBUSY;
-
-		res = -EINVAL;
-		write_lock_irqsave(&ep->lock, flags);
-		if (ep->numpages > 0) {
-			ep_free_pages(ep->pages0, ep->numpages);
-			ep_free_pages(ep->pages1, ep->numpages);
-			ep->numpages = 0;
-			ep->pages = ep->pages0;
-			res = 0;
-		}
-		write_unlock_irqrestore(&ep->lock, flags);
-
-		DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ioctl(%p, EP_FREE) == %d\n",
-			     current, ep, res));
-		return res;
-
-	case EP_POLL:
-		if (copy_from_user(&dvp, (void *) arg, sizeof(struct evpoll)))
-			return -EFAULT;
-
-		DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ioctl(%p, EP_POLL, %d)\n",
-			     current, ep, dvp.ep_timeout));
-
-		res = ep_poll(ep, &dvp);
-
-		DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ioctl(%p, EP_POLL, %d) == %d\n",
-			     current, ep, dvp.ep_timeout, res));
-
-		if (res > 0 && copy_to_user((void *) arg, &dvp, sizeof(struct evpoll)))
-			res = -EFAULT;
-
-		return res;
-
-	case EP_ISPOLLED:
-		if (copy_from_user(&pfd, (void *) arg, sizeof(struct pollfd)))
-			return 0;
-
-		read_lock_irqsave(&ep->lock, flags);
-
-		res = 0;
-		if (!(dpi = ep_find_nl(ep, pfd.fd)))
-			goto is_not_polled;
-
-		pfd = dpi->pfd;
-		res = 1;
-
-	is_not_polled:
-		read_unlock_irqrestore(&ep->lock, flags);
-
-		if (res)
-			copy_to_user((void *) arg, &pfd, sizeof(struct pollfd));
-
-		DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ioctl(%p, EP_ISPOLLED, %d) == %d\n",
-			     current, ep, pfd.fd, res));
-		return res;
-	}
-
-	return -EINVAL;
-}
-
-
-static void eventpoll_mm_open(struct vm_area_struct * vma)
-{
-	struct file *file = vma->vm_file;
-	struct eventpoll *ep = file->private_data;
-
-	if (ep) atomic_inc(&ep->mmapped);
-
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: mm_open(%p)\n", current, ep));
-}
-
-
-static void eventpoll_mm_close(struct vm_area_struct * vma)
-{
-	struct file *file = vma->vm_file;
-	struct eventpoll *ep = file->private_data;
-
-	if (ep && atomic_dec_and_test(&ep->mmapped))
-		ep->vmabase = 0;
-
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: mm_close(%p)\n", current, ep));
-}
-
-
-static int mmap_eventpoll(struct file *file, struct vm_area_struct *vma)
-{
-	struct eventpoll *ep = file->private_data;
-	unsigned long start;
-	int ii, res, numpages;
-	size_t mapsize;
-
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: mmap(%p, %lx, %lx)\n",
-		     current, ep, vma->vm_start, vma->vm_pgoff << PAGE_SHIFT));
-
-	/*
-	 * We need the eventpoll file to be RW but we don't want it to be
-	 * mapped RW. This test perform the test and reject RW mmaping.
-	 */
-	if (vma->vm_flags & VM_WRITE)
-		return -EACCES;
-
-	if ((vma->vm_pgoff << PAGE_SHIFT) != 0)
-		return -EINVAL;
-
-	/*
-	 * We need to verify that the mapped area covers all the allocated
-	 * double buffer.
-	 */
-	mapsize = PAGE_ALIGN(vma->vm_end - vma->vm_start);
-	numpages = mapsize >> PAGE_SHIFT;
-
-	res = -EINVAL;
-	if (numpages != (2 * ep->numpages))
-		goto eexit_1;
-
-	/*
-	 * Map the double buffer starting from "vma->vm_start" up to
-	 * "vma->vm_start + ep->numpages * PAGE_SIZE".
-	 */
-	start = vma->vm_start;
-	for (ii = 0; ii < ep->numpages; ii++) {
-		if ((res = remap_page_range(vma, start, __pa(ep->pages0[ii]),
-					    PAGE_SIZE, vma->vm_page_prot)))
-			goto eexit_1;
-		start += PAGE_SIZE;
-	}
-	for (ii = 0; ii < ep->numpages; ii++) {
-		if ((res = remap_page_range(vma, start, __pa(ep->pages1[ii]),
-					    PAGE_SIZE, vma->vm_page_prot)))
-			goto eexit_1;
-		start += PAGE_SIZE;
-	}
-	vma->vm_ops = &eventpoll_mmap_ops;
-
-	/* Saves the base mapping address for later use in sys_epoll_wait(2) */
-	ep->vmabase = vma->vm_start;
-
-	/*
-	 * Ok, mapping has been done. We can open the door to functions that
-	 * requires the mapping to be in place.
-	 */
-	atomic_set(&ep->mmapped, 1);
-
-	res = 0;
-eexit_1:
-
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: mmap(%p, %lx, %lx) == %d\n",
-		     current, ep, vma->vm_start, vma->vm_pgoff << PAGE_SHIFT, res));
-	return res;
-}
-
-
-static int eventpollfs_delete_dentry(struct dentry *dentry)
-{
-
-	return 1;
-}
-
-
-static struct inode *get_eventpoll_inode(void)
-{
-	int error = -ENOMEM;
-	struct inode *inode = new_inode(eventpoll_mnt->mnt_sb);
-
-	if (!inode)
-		goto eexit_1;
-
-	inode->i_fop = &eventpoll_fops;
-
-	/*
-	 * Mark the inode dirty from the very beginning,
-	 * that way it will never be moved to the dirty
-	 * list because "mark_inode_dirty()" will think
-	 * that it already _is_ on the dirty list.
-	 */
-	inode->i_state = I_DIRTY;
-	inode->i_mode = S_IRUSR | S_IWUSR;
-	inode->i_uid = current->fsuid;
-	inode->i_gid = current->fsgid;
-	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-	inode->i_blksize = PAGE_SIZE;
-	return inode;
-
-eexit_1:
-	return ERR_PTR(error);
-}
-
-
-static struct super_block *eventpollfs_get_sb(struct file_system_type *fs_type,
-					      int flags, char *dev_name, void *data)
-{
-
-	return get_sb_pseudo(fs_type, "eventpoll:", NULL, EVENTPOLLFS_MAGIC);
-}
-
-
-static int __init eventpoll_init(void)
-{
-	int error;
-
-	/* Allocates slab cache used to allocate "struct epitem" items */
-	error = -ENOMEM;
-	dpi_cache = kmem_cache_create("eventpoll",
-				      sizeof(struct epitem),
-				      __alignof__(struct epitem),
-				      DPI_SLAB_DEBUG, NULL, NULL);
-	if (!dpi_cache)
-		goto eexit_1;
-
-	/*
-	 * Register the virtual file system that will be the source of inodes
-	 * for the eventpoll files
-	 */
-	error = register_filesystem(&eventpoll_fs_type);
-	if (error)
-		goto eexit_2;
-
-	/* Mount the above commented virtual file system */
-	eventpoll_mnt = kern_mount(&eventpoll_fs_type);
-	error = PTR_ERR(eventpoll_mnt);
-	if (IS_ERR(eventpoll_mnt))
-		goto eexit_3;
-
-	/*
-	 * This is to maintain compatibility with the old /dev/epoll interface.
-	 * We need to register a misc device so that the caller can open(2) it
-	 * through a file inside /dev.
-	 */
-	error = misc_register(&eventpoll_miscdev);
-	if (error)
-		goto eexit_4;
-
-	printk(KERN_INFO "[%p] eventpoll: driver installed.\n", current);
-
-	return error;
-
-eexit_4:
-	mntput(eventpoll_mnt);
-eexit_3:
-	unregister_filesystem(&eventpoll_fs_type);
-eexit_2:
-	kmem_cache_destroy(dpi_cache);
-eexit_1:
-
-	return error;
-}
-
-
-static void __exit eventpoll_exit(void)
-{
-	/* Undo all operations done inside eventpoll_init() */
-	unregister_filesystem(&eventpoll_fs_type);
-	mntput(eventpoll_mnt);
-	misc_deregister(&eventpoll_miscdev);
-	kmem_cache_destroy(dpi_cache);
-}
-
-module_init(eventpoll_init);
-module_exit(eventpoll_exit);
-
-MODULE_LICENSE("GPL");
-
diff -Nru a/drivers/char/nvram.c b/drivers/char/nvram.c
--- a/drivers/char/nvram.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/char/nvram.c	Mon Nov  4 14:31:01 2002
@@ -98,6 +98,8 @@
 #define RTC_PORT(x)		(TT_RTC_BAS + 2*(x))
 #define CHECK_DRIVER_INIT()	(MACH_IS_ATARI && ATARIHW_PRESENT(TT_CLK))
 
+#define NVRAM_BYTES		50
+
 /* On Ataris, the checksum is over all bytes except the checksum bytes
  * themselves; these are at the very end */
 #define ATARI_CKS_RANGE_START	0
diff -Nru a/drivers/char/raw.c b/drivers/char/raw.c
--- a/drivers/char/raw.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/char/raw.c	Mon Nov  4 14:31:02 2002
@@ -56,9 +56,15 @@
 	bdev = raw_devices[minor].binding;
 	err = -ENODEV;
 	if (bdev) {
+		err = bd_claim(bdev, raw_open);
+		if (err)
+			goto out;
 		atomic_inc(&bdev->bd_count);
 		err = blkdev_get(bdev, filp->f_mode, 0, BDEV_RAW);
-		if (!err) {
+		if (err) {
+			bd_release(bdev);
+			goto out;
+		} else {
 			err = set_blocksize(bdev, bdev_hardsect_size(bdev));
 			if (err == 0) {
 				raw_devices[minor].inuse++;
@@ -69,6 +75,7 @@
 		}
 	}
 	filp->private_data = bdev;
+out:
 	up(&raw_mutex);
 	return err;
 }
@@ -82,6 +89,7 @@
 	bdev = raw_devices[minor].binding;
 	raw_devices[minor].inuse--;
 	up(&raw_mutex);
+	bd_release(bdev);
 	blkdev_put(bdev, BDEV_RAW);
 	return 0;
 }
diff -Nru a/drivers/char/sysrq.c b/drivers/char/sysrq.c
--- a/drivers/char/sysrq.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/char/sysrq.c	Mon Nov  4 14:31:02 2002
@@ -35,6 +35,10 @@
 
 #include <asm/ptrace.h>
 
+#ifdef CONFIG_VOYAGER
+#include <asm/voyager.h>
+#endif
+
 extern void reset_vc(unsigned int);
 extern struct list_head super_blocks;
 
@@ -319,6 +323,14 @@
 	action_msg:	"Terminate All Tasks",
 };
 
+#ifdef CONFIG_VOYAGER
+static struct sysrq_key_op sysrq_voyager_dump_op = {
+	handler:	voyager_dump,
+	help_msg:	"voyager",
+	action_msg:	"Dump Voyager Status\n",
+};
+#endif
+
 static void sysrq_handle_kill(int key, struct pt_regs *pt_regs,
 			      struct tty_struct *tty) 
 {
@@ -352,7 +364,11 @@
 		 it is handled specially on the sparc
 		 and will never arrive */
 /* b */	&sysrq_reboot_op,
+#ifdef CONFIG_VOYAGER
+/* c */ &sysrq_voyager_dump_op,
+#else
 /* c */	NULL,
+#endif
 /* d */	NULL,
 /* e */	&sysrq_term_op,
 /* f */	NULL,
diff -Nru a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
--- a/drivers/ide/ide-cd.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/ide/ide-cd.c	Mon Nov  4 14:31:01 2002
@@ -878,10 +878,12 @@
  * changed 5 parameters to 3 for dvd-ram
  * struct packet_command *pc; now packet_command_t *pc;
  */
+#define ATAPI_MIN_CDB_BYTES 12
 static ide_startstop_t cdrom_transfer_packet_command (ide_drive_t *drive,
 					  struct request *rq,
 					  ide_handler_t *handler)
 {
+	int cmd_len;
 	struct cdrom_info *info = drive->driver_data;
 	ide_startstop_t startstop;
 
@@ -905,8 +907,13 @@
 	/* Arm the interrupt handler. */
 	ide_set_handler(drive, handler, rq->timeout, cdrom_timer_expiry);
 
+	/* ATAPI commands get padded out to 12 bytes minimum */
+	cmd_len = rq->cmd_len;
+	if (cmd_len < ATAPI_MIN_CDB_BYTES)
+		cmd_len = ATAPI_MIN_CDB_BYTES;
+
 	/* Send the command to the device. */
-	HWIF(drive)->atapi_output_bytes(drive, rq->cmd, sizeof(rq->cmd));
+	HWIF(drive)->atapi_output_bytes(drive, rq->cmd, cmd_len);
 
 	/* Start the DMA if need be */
 	if (info->dma)
@@ -3004,6 +3011,7 @@
 	 */
 	rq->cmd[7] = (blocks >> 8) & 0xff;
 	rq->cmd[8] = blocks & 0xff;
+	rq->cmd_len = 10;
 	return BLKPREP_OK;
 }
 
@@ -3026,6 +3034,7 @@
 		c[2] = 0;
 		c[1] &= 0xe0;
 		c[0] += (READ_10 - READ_6);
+		rq->cmd_len = 10;
 		return BLKPREP_OK;
 	}
 
diff -Nru a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h
--- a/drivers/ide/ide-cd.h	Mon Nov  4 14:31:03 2002
+++ b/drivers/ide/ide-cd.h	Mon Nov  4 14:31:03 2002
@@ -104,9 +104,6 @@
 
 #define CDROM_STATE_FLAGS(drive) (&(((struct cdrom_info *)(drive->driver_data))->state_flags))
 
-struct packet_command {
-};
-
 /* Structure of a MSF cdrom address. */
 struct atapi_msf {
 	byte reserved;
@@ -472,7 +469,6 @@
 	struct request_sense sense_data;
 
 	struct request request_sense_request;
-	struct packet_command request_sense_pc;
 	int dma;
 	int cmd;
 	unsigned long last_block;
diff -Nru a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
--- a/drivers/ide/ide-floppy.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/ide/ide-floppy.c	Mon Nov  4 14:31:01 2002
@@ -1263,8 +1263,8 @@
 	unsigned long block = (unsigned long)block_s;
 
 #if IDEFLOPPY_DEBUG_LOG
-	printk(KERN_INFO "rq_status: %d, rq_dev: %u, flags: %lx, errors: %d\n",
-			rq->rq_status, (unsigned int) rq->rq_dev,
+	printk(KERN_INFO "rq_status: %d, dev: %s, flags: %lx, errors: %d\n",
+			rq->rq_status, rq->rq_disk->disk_name,
 			rq->flags, rq->errors);
 	printk(KERN_INFO "sector: %ld, nr_sectors: %ld, "
 			"current_nr_sectors: %ld\n", (long)rq->sector,
diff -Nru a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
--- a/drivers/ide/ide-lib.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/ide/ide-lib.c	Mon Nov  4 14:31:02 2002
@@ -171,7 +171,7 @@
 		BUG();
 	return min(speed, speed_max[mode]);
 #else /* !CONFIG_BLK_DEV_IDEDMA */
-	return min(speed, XFER_PIO_4);
+	return min(speed, (u8)XFER_PIO_4);
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 }
 
diff -Nru a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
--- a/drivers/ide/ide-tape.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/ide/ide-tape.c	Mon Nov  4 14:31:01 2002
@@ -2591,8 +2591,8 @@
 #if 0
 	if (tape->debug_level >= 5)
 		printk(KERN_INFO "ide-tape: rq_status: %d, "
-			"rq_dev: %u, cmd: %ld, errors: %d\n", rq->rq_status,
-			(unsigned int) rq->rq_dev, rq->flags, rq->errors);
+			"dev: %s, cmd: %ld, errors: %d\n", rq->rq_status,
+			 rq->rq_disk->disk_name, rq->flags, rq->errors);
 #endif
 	if (tape->debug_level >= 2)
 		printk(KERN_INFO "ide-tape: sector: %ld, "
diff -Nru a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
--- a/drivers/ide/ide-taskfile.c	Mon Nov  4 14:31:00 2002
+++ b/drivers/ide/ide-taskfile.c	Mon Nov  4 14:31:00 2002
@@ -1356,7 +1356,6 @@
 	rq->special = args;
 	rq->errors = 0;
 	rq->rq_status = RQ_ACTIVE;
-	rq->rq_dev = mk_kdev(disk->major, disk->first_minor);
 	rq->rq_disk = drive->disk;
 	rq->waiting = &wait;
 
diff -Nru a/drivers/ide/ide.c b/drivers/ide/ide.c
--- a/drivers/ide/ide.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/ide/ide.c	Mon Nov  4 14:31:01 2002
@@ -181,13 +181,13 @@
 
 static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */
 
-#if defined(__mc68000__) || defined(CONFIG_APUS)
+#ifdef IDE_ARCH_LOCK
 /*
  * ide_lock is used by the Atari code to obtain access to the IDE interrupt,
  * which is shared between several drivers.
  */
 static int	ide_intr_lock;
-#endif /* __mc68000__ || CONFIG_APUS */
+#endif /* IDE_ARCH_LOCK */
 
 #ifdef CONFIG_IDEDMA_AUTO
 int noautodma = 0;
@@ -1092,7 +1092,7 @@
 				 */
 
 				/* for atari only */
-				ide_release_lock(&ide_lock);
+				ide_release_lock(&ide_intr_lock);
 				hwgroup->busy = 0;
 			}
 
@@ -1530,7 +1530,6 @@
 	rq->errors = 0;
 	rq->rq_status = RQ_ACTIVE;
 
-	rq->rq_dev = mk_kdev(drive->disk->major, drive->disk->first_minor);
 	rq->rq_disk = drive->disk;
 
 	/*
diff -Nru a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c
--- a/drivers/input/keyboard/amikbd.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/input/keyboard/amikbd.c	Mon Nov  4 14:31:02 2002
@@ -112,7 +112,7 @@
 	if (!request_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100, "amikeyb"))
 		return -EBUSY;
 
-	init_input_dev(&amibkd_dev);
+	init_input_dev(&amikbd_dev);
 
 	amikbd_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
 	amikbd_dev.keycode = amikbd_keycode;
diff -Nru a/drivers/macintosh/mac_keyb.c b/drivers/macintosh/mac_keyb.c
--- a/drivers/macintosh/mac_keyb.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/macintosh/mac_keyb.c	Mon Nov  4 14:31:01 2002
@@ -247,14 +247,6 @@
 static void init_microspeed(int id);
 static void init_ms_a3(int id);
 
-#ifdef CONFIG_ADBMOUSE
-/* XXX: Hook for mouse driver */
-void (*adb_mouse_interrupt_hook)(unsigned char *, int);
-int adb_emulate_buttons = 0;
-int adb_button2_keycode = 0x7d;	/* right control key */
-int adb_button3_keycode = 0x7c; /* right option key */
-#endif
-
 extern struct kbd_struct kbd_table[];
 
 extern void handle_scancode(unsigned char, int);
@@ -342,38 +334,6 @@
 	if (!repeat)
 		del_timer(&repeat_timer);
 
-#ifdef CONFIG_ADBMOUSE
-	/*
-	 * XXX: Add mouse button 2+3 fake codes here if mouse open.
-	 *	Keep track of 'button' states here as we only send
-	 *	single up/down events!
-	 *	Really messy; might need to check if keyboard is in
-	 *	VC_RAW mode.
-	 *	Might also want to know how many buttons need to be emulated.
-	 *	-> hide this as function in arch/m68k/mac ?
-	 */
-	if (adb_emulate_buttons
-	    && (keycode == adb_button2_keycode
-		|| keycode == adb_button3_keycode)
-	    && (adb_mouse_interrupt_hook || console_loglevel == 10)) {
-		int button;
-		/* faked ADB packet */
-		static unsigned char data[4] = { 0, 0x80, 0x80, 0x80 };
-
-		button = keycode == adb_button2_keycode? 2: 3;
-		if (data[button] != up_flag) {
-			/* send a fake mouse packet */
-			data[button] = up_flag;
-			if (console_loglevel >= 8)
-				printk("fake mouse event: %x %x %x\n",
-				       data[1], data[2], data[3]);
-			if (adb_mouse_interrupt_hook)
-				adb_mouse_interrupt_hook(data, 4);
-		}
-		return;
-	}
-#endif /* CONFIG_ADBMOUSE */
-
 	if (kbd->kbdmode != VC_RAW) {
 		if (!up_flag && !dont_repeat[keycode]) {
 			last_keycode = keycode;
@@ -428,163 +388,6 @@
 	}
 }
 
-#ifdef CONFIG_ADBMOUSE
-static void
-mouse_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll)
-{
-  /* [ACA:23-Mar-97] Three button mouse support.  This is designed to
-     function with MkLinux DR-2.1 style X servers.  It only works with
-     three-button mice that conform to Apple's multi-button mouse
-     protocol. */
-
-  /*
-    The X server for MkLinux DR2.1 uses the following unused keycodes to
-    read the mouse:
-
-    0x7e  This indicates that the next two keycodes should be interpreted
-          as mouse information.  The first following byte's high bit
-          represents the state of the left button.  The lower seven bits
-          represent the x-axis acceleration.  The lower seven bits of the
-          second byte represent y-axis acceleration.
-
-    0x3f  The x server interprets this keycode as a middle button
-          release.
-
-    0xbf  The x server interprets this keycode as a middle button
-          depress.
-
-    0x40  The x server interprets this keycode as a right button
-          release.
-
-    0xc0  The x server interprets this keycode as a right button
-          depress.
-
-    NOTES: There should be a better way of handling mice in the X server.
-    The MOUSE_ESCAPE code (0x7e) should be followed by three bytes instead
-    of two.  The three mouse buttons should then, in the X server, be read
-    as the high-bits of all three bytes.  The x and y motions can still be
-    in the first two bytes.  Maybe I'll do this...
-  */
-
-  /*
-    Handler 1 -- 100cpi original Apple mouse protocol.
-    Handler 2 -- 200cpi original Apple mouse protocol.
-
-    For Apple's standard one-button mouse protocol the data array will
-    contain the following values:
-
-                BITS    COMMENTS
-    data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd.
-    data[1] = bxxx xxxx First button and x-axis motion.
-    data[2] = byyy yyyy Second button and y-axis motion.
-
-    Handler 4 -- Apple Extended mouse protocol.
-
-    For Apple's 3-button mouse protocol the data array will contain the
-    following values:
-
-		BITS    COMMENTS
-    data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd.
-    data[1] = bxxx xxxx Left button and x-axis motion.
-    data[2] = byyy yyyy Second button and y-axis motion.
-    data[3] = byyy bxxx Third button and fourth button.  Y is additional
-	      high bits of y-axis motion.  XY is additional
-	      high bits of x-axis motion.
-
-    MacAlly 2-button mouse protocol.
-
-    For MacAlly 2-button mouse protocol the data array will contain the
-    following values:
-
-		BITS    COMMENTS
-    data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd.
-    data[1] = bxxx xxxx Left button and x-axis motion.
-    data[2] = byyy yyyy Right button and y-axis motion.
-    data[3] = ???? ???? unknown
-    data[4] = ???? ???? unknown
-
-  */
-	struct kbd_struct *kbd;
-
-	/* If it's a trackpad, we alias the second button to the first.
-	   NOTE: Apple sends an ADB flush command to the trackpad when
-	         the first (the real) button is released. We could do
-		 this here using async flush requests.
-	*/
-	switch (adb_mouse_kinds[(data[0]>>4) & 0xf])
-	{
-	    case ADBMOUSE_TRACKPAD:
-		data[1] = (data[1] & 0x7f) | ((data[1] & data[2]) & 0x80);
-		data[2] = data[2] | 0x80;
-		break;
-	    case ADBMOUSE_MICROSPEED:
-		data[1] = (data[1] & 0x7f) | ((data[3] & 0x01) << 7);
-		data[2] = (data[2] & 0x7f) | ((data[3] & 0x02) << 6);
-		data[3] = (data[3] & 0x77) | ((data[3] & 0x04) << 5)
-			| (data[3] & 0x08);
-		break;
-	    case ADBMOUSE_TRACKBALLPRO:
-		data[1] = (data[1] & 0x7f) | (((data[3] & 0x04) << 5)
-			& ((data[3] & 0x08) << 4));
-		data[2] = (data[2] & 0x7f) | ((data[3] & 0x01) << 7);
-		data[3] = (data[3] & 0x77) | ((data[3] & 0x02) << 6);
-		break;
-	    case ADBMOUSE_MS_A3:
-		data[1] = (data[1] & 0x7f) | ((data[3] & 0x01) << 7);
-		data[2] = (data[2] & 0x7f) | ((data[3] & 0x02) << 6);
-		data[3] = ((data[3] & 0x04) << 5);
-		break;
-            case ADBMOUSE_MACALLY2:
-		data[3] = (data[2] & 0x80) ? 0x80 : 0x00;
-		data[2] |= 0x80;  /* Right button is mapped as button 3 */
-		nb=4;
-                break;
-	}
-
-	if (adb_mouse_interrupt_hook)
-		adb_mouse_interrupt_hook(data, nb);
-
-	kbd = kbd_table + fg_console;
-
-	/* Only send mouse codes when keyboard is in raw mode. */
-	if (kbd->kbdmode == VC_RAW) {
-		static unsigned char uch_ButtonStateSecond = 0x80;
-		unsigned char uchButtonSecond;
-
-		/* Send first button, second button and movement. */
-		mac_put_queue(0x7e);
-		mac_put_queue(data[1]);
-		mac_put_queue(data[2]);
-
-		/* [ACA: Are there any two-button ADB mice that use handler 1 or 2?] */
-
-		/* Store the button state. */
-		uchButtonSecond = (data[2] & 0x80);
-
-		/* Send second button. */
-		if (uchButtonSecond != uch_ButtonStateSecond) {
-			mac_put_queue(0x3f | uchButtonSecond);
-			uch_ButtonStateSecond = uchButtonSecond;
-		}
-
-		/* Macintosh 3-button mouse (handler 4). */
-		if (nb >= 4) {
-			static unsigned char uch_ButtonStateThird = 0x80;
-			unsigned char uchButtonThird;
-
-			/* Store the button state for speed. */
-			uchButtonThird = (data[3] & 0x80);
-
-			/* Send third button. */
-			if (uchButtonThird != uch_ButtonStateThird) {
-				mac_put_queue(0x40 | uchButtonThird);
-				uch_ButtonStateThird = uchButtonThird;
-			}
-		}
-	}
-}
-#endif /* CONFIG_ADBMOUSE */
-
 static void
 buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll)
 {
@@ -708,11 +511,6 @@
 	memcpy(key_maps[8], macalt_map, sizeof(plain_map));
 	memcpy(key_maps[12], macctrl_alt_map, sizeof(plain_map));
 
-#ifdef CONFIG_ADBMOUSE
-	/* initialize mouse interrupt hook */
-	adb_mouse_interrupt_hook = NULL;
-#endif
-
 	led_request.complete = 1;
 
 	mackeyb_probe();
@@ -751,10 +549,6 @@
 {
 	struct adb_request req;
 	int i;
-
-#ifdef CONFIG_ADBMOUSE
-	adb_register(ADB_MOUSE, 0, &mouse_ids, mouse_input);
-#endif /* CONFIG_ADBMOUSE */
 
 	adb_register(ADB_KEYBOARD, 0, &keyboard_ids, keyboard_input);
 	adb_register(0x07, 0x1F, &buttons_ids, buttons_input);
diff -Nru a/drivers/media/Kconfig b/drivers/media/Kconfig
--- a/drivers/media/Kconfig	Mon Nov  4 14:31:01 2002
+++ b/drivers/media/Kconfig	Mon Nov  4 14:31:01 2002
@@ -12,9 +12,14 @@
 	  this are available from
 	  <ftp://ftp.uk.linux.org/pub/linux/video4linux/>.
 
-	  If you are interested in writing a driver for such an audio/video
-	  device or user software interacting with such a driver, please read
-	  the file <file:Documentation/video4linux/API.html>.
+	  This kernel includes support for the new Video for Linux Two API,
+	  (V4L2) as well as the original system. Drivers and applications
+	  need to be rewritten to use V4L2, but drivers for popular cards
+	  and applications for most video capture functions already exist.
+
+	  Documentation for the original API is included in the file
+	  Documentation/video4linux/API.html.  Documentation for V4L2 is
+	  available on the web at http://bytesex.org/v4l/
 
 	  This driver is also available as a module called videodev.o ( = code
 	  which can be inserted in and removed from the running kernel
diff -Nru a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
--- a/drivers/media/video/Kconfig	Mon Nov  4 14:31:02 2002
+++ b/drivers/media/video/Kconfig	Mon Nov  4 14:31:02 2002
@@ -212,5 +212,17 @@
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
 
+config VIDEO_SAA7134
+	tristate "Philips SAA7134 support"
+	depends on VIDEO_DEV && PCI && I2C
+	---help---
+	  This is a video4linux driver for Philips SAA7130/7134 based
+	  TV cards.
+
+	  This driver is available as a module called saa7134.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>.
+
 endmenu
 
diff -Nru a/drivers/media/video/Makefile b/drivers/media/video/Makefile
--- a/drivers/media/video/Makefile	Mon Nov  4 14:31:01 2002
+++ b/drivers/media/video/Makefile	Mon Nov  4 14:31:01 2002
@@ -5,13 +5,14 @@
 # All of the (potential) objects that export symbols.
 # This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
 
-export-objs     :=	videodev.o bttv-if.o cpia.o video-buf.o
+export-objs     :=	videodev.o v4l2-common.o \
+			bttv-if.o cpia.o video-buf.o
 
 bttv-objs	:=	bttv-driver.o bttv-cards.o bttv-if.o \
 			bttv-risc.o bttv-vbi.o
 zoran-objs      :=	zr36120.o zr36120_i2c.o zr36120_mem.o
 
-obj-$(CONFIG_VIDEO_DEV) += videodev.o
+obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o
 
 obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \
 	tda7432.o tda9875.o tuner.o video-buf.o
@@ -34,6 +35,7 @@
 obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o
 obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o
 obj-$(CONFIG_VIDEO_MEYE) += meye.o
+obj-$(CONFIG_VIDEO_SAA7134) += saa7134/ tuner.o tda9887.o
 obj-$(CONFIG_TUNER_3036) += tuner-3036.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/drivers/media/video/bt848.h b/drivers/media/video/bt848.h
--- a/drivers/media/video/bt848.h	Mon Nov  4 14:31:01 2002
+++ b/drivers/media/video/bt848.h	Mon Nov  4 14:31:01 2002
@@ -347,6 +347,8 @@
 #define BT848_PLL_X            (1<<7)
 #define BT848_PLL_C            (1<<6)
 
+#define BT848_DVSIF            0x0FC
+
 /* Bt878 register */
 
 #define BT878_DEVCTRL 0x40
diff -Nru a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
--- a/drivers/media/video/bttv-cards.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/media/video/bttv-cards.c	Mon Nov  4 14:31:01 2002
@@ -37,15 +37,16 @@
 
 #include "bttvp.h"
 #include "tuner.h"
+#if 0
+# include "bt832.h"
+#endif
 
 /* fwd decl */
 static void boot_msp34xx(struct bttv *btv, int pin);
 static void hauppauge_eeprom(struct bttv *btv);
 static void avermedia_eeprom(struct bttv *btv);
+static void osprey_eeprom(struct bttv *btv);
 static void init_PXC200(struct bttv *btv);
-#if 0
-static void init_tea5757(struct bttv *btv);
-#endif
 
 static void winview_audio(struct bttv *btv, struct video_audio *v, int set);
 static void lt9415_audio(struct bttv *btv, struct video_audio *v, int set);
@@ -58,6 +59,12 @@
 static void fv2000s_audio(struct bttv *btv, struct video_audio *v, int set);
 static void windvr_audio(struct bttv *btv, struct video_audio *v, int set);
 static void rv605_muxsel(struct bttv *btv, unsigned int input);
+static void eagle_muxsel(struct bttv *btv, unsigned int input);
+
+static int terratec_active_radio_upgrade(struct bttv *btv);
+static int tea5757_read(struct bttv *btv);
+static int tea5757_write(struct bttv *btv, int value);
+
 
 /* config variables */
 static int triton1=0;
@@ -83,11 +90,11 @@
 MODULE_PARM_DESC(vsfx,"set VSFX pci config bit "
 		 "[yet another chipset flaw workaround]");
 MODULE_PARM(no_overlay,"i");
-MODULE_PARM(card,"1-" __MODULE_STRING(BTTV_MAX) "i");
+MODULE_PARM(card,"1-" __stringify(BTTV_MAX) "i");
 MODULE_PARM_DESC(card,"specify TV/grabber card model, see CARDLIST file for a list");
-MODULE_PARM(pll,"1-" __MODULE_STRING(BTTV_MAX) "i");
+MODULE_PARM(pll,"1-" __stringify(BTTV_MAX) "i");
 MODULE_PARM_DESC(pll,"specify installed crystal (0=none, 28=28 MHz, 35=35 MHz)");
-MODULE_PARM(tuner,"1-" __MODULE_STRING(BTTV_MAX) "i");
+MODULE_PARM(tuner,"1-" __stringify(BTTV_MAX) "i");
 MODULE_PARM_DESC(tuner,"specify installed tuner type");
 MODULE_PARM(autoload,"i");
 MODULE_PARM_DESC(autoload,"automatically load i2c modules like tuner.o, default is 1 (yes)");
@@ -127,24 +134,29 @@
 } cards[] __devinitdata = {
 	{ 0x13eb0070, BTTV_HAUPPAUGE878,  "Hauppauge WinTV" },
 	{ 0x39000070, BTTV_HAUPPAUGE878,  "Hauppauge WinTV-D" },
-	{ 0x45000070, BTTV_HAUPPAUGE878,  "Hauppauge WinTV/PVR" },
-	{ 0xff000070, BTTV_HAUPPAUGE878,  "Osprey-100" },
-	{ 0xff010070, BTTV_HAUPPAUGE878,  "Osprey-200" },
+	{ 0x45000070, BTTV_HAUPPAUGEPVR,  "Hauppauge WinTV/PVR" },
+	{ 0xff000070, BTTV_OSPREY1x0,     "Osprey-100" },
+	{ 0xff010070, BTTV_OSPREY2x0_SVID,"Osprey-200" },
+	{ 0xff020070, BTTV_OSPREY500,     "Osprey-500" },
+	{ 0xff030070, BTTV_OSPREY2000,    "Osprey-2000" },
+	{ 0xff040070, BTTV_OSPREY540,     "Osprey-540" },
 
 	{ 0x00011002, BTTV_ATI_TVWONDER,  "ATI TV Wonder" },
 	{ 0x00031002, BTTV_ATI_TVWONDERVE,"ATI TV Wonder/VE" },
 
 	{ 0x6606107d, BTTV_WINFAST2000,   "Leadtek WinFast TV 2000" },
 	{ 0x6607107d, BTTV_WINFAST2000,   "Leadtek WinFast VC 100" },
-	{ 0x263610b4, BTTV_STB2,          "STB TV PCI FM, P/N 6000704" },
+	{ 0x263610b4, BTTV_STB2,          "STB TV PCI FM, Gateway P/N 6000704" },
  	{ 0x402010fc, BTTV_GVBCTV3PCI,    "I-O Data Co. GV-BCTV3/PCI" },
 	{ 0x405010fc, BTTV_GVBCTV4PCI,    "I-O Data Co. GV-BCTV4/PCI" },
+	{ 0x407010fc, BTTV_GVBCTV5PCI,    "I-O Data Co. GV-BCTV5/PCI" },
 
 	{ 0x1200bd11, BTTV_PINNACLE,      "Pinnacle PCTV" },
 	{ 0x001211bd, BTTV_PINNACLE,      "Pinnacle PCTV" },
 	{ 0x001c11bd, BTTV_PINNACLE,      "Pinnacle PCTV Sat" },
 
 	{ 0x3000121a, BTTV_VOODOOTV_FM,   "3Dfx VoodooTV FM/ VoodooTV 200" },
+	{ 0x3060121a, BTTV_STB2,	  "3Dfx VoodooTV 100/ STB OEM" },
 	
 	{ 0x3000144f, BTTV_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" },
 	{ 0x3002144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH05x" },
@@ -170,6 +182,7 @@
 	{ 0x1135153b, BTTV_TERRATVALUER,  "Terratec TValue Radio" },
 	{ 0x5018153b, BTTV_TERRATVALUE,   "Terratec TValue" },
 
+	{ 0x400015b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
 	{ 0x400a15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
 	{ 0x400d15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
 	{ 0x401015b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
@@ -225,7 +238,7 @@
 	needs_tvaudio:	1,
 	tuner_type:	-1,
 },{
-	name:		"STB",
+	name:		"STB, Gateway P/N 6000699 (bt848)",
 	video_inputs:	3,
 	audio_inputs:	1,
 	tuner:		0,
@@ -235,7 +248,9 @@
 	audiomux:	{ 4, 0, 2, 3, 1},
 	no_msp34xx:	1,
 	needs_tvaudio:	1,
-	tuner_type:	-1,
+	tuner_type:     TUNER_PHILIPS_NTSC,
+	pll:            PLL_28,
+	has_radio:      1,
 },{
 
 /* ---- card 0x04 ---------------------------------- */
@@ -357,7 +372,7 @@
 	audiomux:	{ 13, 14, 11, 7, 0, 0},
 	needs_tvaudio:	1,
 	pll:		PLL_28,
-	tuner_type:	-1,
+	tuner_type:	TUNER_PHILIPS_PAL,
 },{
 	name:		"Aimslab Video Highway Xtreme (VHX)",
 	video_inputs:	3,
@@ -490,16 +505,17 @@
 	pll:		PLL_28,
 	tuner_type:	-1,
 },{
-	name:		"Terratec Terra TV+ Version 1.0 (Bt848)/Vobis TV-Boostar",
+	name:           "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar",
 	video_inputs:	3,
 	audio_inputs:	1,
 	tuner:		0,
 	svhs:		2,
-	gpiomask:	16777215,
+	gpiomask:       0x1f0fff,
 	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 131072, 1, 1638400, 3,4},
-	needs_tvaudio:	1,
-	tuner_type:	-1,
+	audiomux:       { 0x20000, 0x30000, 0x10000, 0, 0x40000},
+	needs_tvaudio:	0,
+	tuner_type:	TUNER_PHILIPS_PAL,
+	audio_hook:     terratv_audio,
 },{
 	name:		"Hauppauge WinCam newer (bt878)",
 	video_inputs:	4,
@@ -525,17 +541,48 @@
 },{
 
 /* ---- card 0x1c ---------------------------------- */
-	name:		"Terratec TerraTV+",
+	name:           "Terratec TerraTV+ Version 1.1 (bt878)",
 	video_inputs:	3,
 	audio_inputs:	1,
 	tuner:		0,
 	svhs:		2,
-	gpiomask:	0x70000,
+	gpiomask:	0x1f0fff,
 	muxsel:		{ 2, 3, 1, 1},
 	audiomux:	{ 0x20000, 0x30000, 0x10000, 0x00000, 0x40000},
-	needs_tvaudio:	1,
+	needs_tvaudio:	0,
 	tuner_type:	TUNER_PHILIPS_PAL,
 	audio_hook:	terratv_audio,
+	/* GPIO wiring:
+               External 20 pin connector (for Active Radio Upgrade board)
+               gpio00: i2c-sda
+               gpio01: i2c-scl
+               gpio02: om5610-data
+               gpio03: om5610-clk
+               gpio04: om5610-wre
+               gpio05: om5610-stereo
+               gpio06: rds6588-davn
+               gpio07: Pin 7 n.c.
+               gpio08: nIOW
+               gpio09+10: nIOR, nSEL ?? (bt878)
+                gpio09: nIOR (bt848)
+                gpio10: nSEL (bt848)
+              Sound Routing:
+               gpio16: u2-A0 (1st 4052bt)
+               gpio17: u2-A1
+               gpio18: u2-nEN
+               gpio19: u4-A0 (2nd 4052)
+               gpio20: u4-A1
+                       u4-nEN - GND
+	    Btspy:
+	  	00000 : Cdrom (internal audio input)
+		10000 : ext. Video audio input
+		20000 : TV Mono
+		a0000 : TV Mono/2
+	       1a0000 : TV Stereo	
+		30000 : Radio
+		40000 : Mute
+       */
+
 },{
 	/* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */
 	name:		"Imagenation PXC200",
@@ -583,7 +630,7 @@
 	needs_tvaudio:	0,
 	tuner_type:	4,
 },{
-	name:		"Terratec TerraTValue",
+	name:           "Terratec TerraTValue Version Bt878",
 	video_inputs:	3,
 	audio_inputs:	1,
 	tuner:		0,
@@ -595,17 +642,29 @@
 	pll:		PLL_28,
 	tuner_type:	TUNER_PHILIPS_PAL,
 },{
-	name:		"Leadtek WinFast 2000",
-	video_inputs:	3,
+	name:		"Leadtek WinFast 2000/ WinFast 2000 XP",
+	video_inputs:	4,
 	audio_inputs:	1,
 	tuner:		0,
 	svhs:		2,
 	gpiomask:	0xc33000,
-	muxsel:		{ 2, 3, 1, 1,0},
-	audiomux:	{ 0x422000,0x001000,0x621100,0x620000,0x800000,0x620000},
+	muxsel:		{ 2, 3, 1, 1, 0}, // TV, CVid, SVid, CVid over SVid connector
+	audiomux:	{ 0x422000,0x1000,0x0000,0x620000,0x800000},
+	/* Audio Routing for "WinFast 2000 XP" (no tv stereo !)
+		gpio23 -- hef4052:nEnable (0x800000)
+		gpio12 -- hef4052:A1
+	        gpio13 -- hef4052:A0
+	    0x0000: external audio
+	    0x1000: FM
+	    0x2000: TV
+	    0x3000: n.c.
+          Note: There exists another variant "Winfast 2000" with tv stereo !?
+	  Note: eeprom only contains FF and pci subsystem id 107d:6606
+	 */
 	needs_tvaudio:	0,
 	pll:		PLL_28,
-	tuner_type:	-1,
+	has_radio:	1,
+	tuner_type:	5, // default for now, gpio reads BFFF06 for Pal bg+dk
 	audio_hook:	winfast2000_audio,
 },{
 	name:		"Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II",
@@ -671,7 +730,7 @@
 },{
 
 /* ---- card 0x28 ---------------------------------- */
-	name:		"STB2",
+	name:		"STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100",
 	video_inputs:	3,
 	audio_inputs:	1,
 	tuner:		0,
@@ -681,7 +740,9 @@
 	audiomux:	{ 4, 0, 2, 3, 1},
 	no_msp34xx:	1,
 	needs_tvaudio:	1,
-	tuner_type:	-1,
+	tuner_type:     TUNER_PHILIPS_NTSC,
+	pll:            PLL_28,
+	has_radio:      1,
 },{
 	name:		"AVerMedia TVPhone 98",
 	video_inputs:	3,
@@ -810,6 +871,15 @@
 	no_msp34xx:	1,
 	pll:		PLL_28,
 	tuner_type:	TUNER_PHILIPS_PAL_I,
+	/* GPIO wiring: (different from Rev.4C !)
+		GPIO17: U4.A0 (first hef4052bt)
+		GPIO19: U4.A1
+		GPIO20: U5.A1 (second hef4052bt)
+		GPIO21: U4.nEN
+		GPIO22: BT832 Reset Line
+		GPIO23: A5,A0, U5,nEN
+	   Note: At i2c=0x8a is a Bt832 chip, which changes to 0x88 after being reset via GPIO22
+	 */
 },{
 	name:           "Eagle Wireless Capricorn2 (bt878A)",
 	video_inputs:   4,
@@ -1105,10 +1175,17 @@
         svhs:           2,
         gpiomask:       15,
         muxsel:         { 2, 3, 1, 1},
-        audiomux:       { 0, 0, 11, 7, 13, 0},
+        audiomux:       { 0, 0, 11, 7, 13, 0}, // TV and Radio with same GPIO !
         needs_tvaudio:  1,
         pll:            PLL_28,
         tuner_type:     25,
+	/* GPIO wiring:
+		GPIO0: U4.A0 (hef4052bt)
+		GPIO1: U4.A1
+		GPIO2: U4.A1 (second hef4052bt)
+		GPIO3: U4.nEN, U5.A0, A5.nEN
+		GPIO8-15: vrd866b ?
+	 */
 },{
 	name:		"Lifeview FlyVideo 98EZ (capture only) LR51",
 	video_inputs:	4,
@@ -1123,20 +1200,27 @@
 /* ---- card 0x48 ---------------------------------- */
 	/* Dariusz Kowalewski <darekk@automex.pl> */
 	name:		"Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)",
-	video_inputs:	3,
+	video_inputs:	4,
 	audio_inputs:	1,
 	tuner:		0,
 	svhs:		2,
 	gpiomask:	0x3f,
-	muxsel:		{ 2, 3, 0, 1 },
+	muxsel:		{ 2, 3, 1, 1 },
 	audiomux:	{ 0x01, 0x00, 0x03, 0x03, 0x09, 0x02 },
 	needs_tvaudio:  1,
 	no_msp34xx:	1,
 	no_tda9875:	1,
 	pll:		PLL_28,
-	tuner_type:	-1,
-	audio_hook:	pvbt878p9b_audio,
-	has_radio:	1,
+	tuner_type:	5,
+	audio_hook:	pvbt878p9b_audio, // Note: not all cards have stereo
+	has_radio:	1,  // Note: not all cards have radio
+	/* GPIO wiring:
+		GPIO0: A0 hef4052
+		GPIO1: A1 hef4052
+		GPIO3: nEN hef4052
+		GPIO8-15: vrd866b
+		GPIO20,22,23: R30,R29,R28
+	 */
 },{
 	/* Clay Kunz <ckunz@mail.arc.nasa.gov> */
 	/* you must jumper JP5 for the card to work */
@@ -1242,6 +1326,193 @@
         muxsel:         { 2, 3, 1, 0},
         pll:            PLL_28,
         tuner_type:     -1,
+},{
+
+        /* ---- card 0x50 ---------------------------------- */
+	name:           "Hauppauge WinTV PVR",
+        video_inputs:   4,
+        audio_inputs:   1,
+        tuner:          0,
+        svhs:           2,
+        muxsel:         { 2, 0, 1, 1},
+        needs_tvaudio:  1,
+        pll:            PLL_28,
+        tuner_type:     -1,
+
+	gpiomask:       7,
+	audiomux:       {7},
+},{
+	name:           "GV-BCTV5/PCI",
+	video_inputs:   3,
+	audio_inputs:   1,
+	tuner:          0,
+	svhs:           2,
+	gpiomask:       0x010f00,
+	muxsel:         {2, 3, 1, 0},
+	audiomux:       {0x10000, 0, 0x10000, 0, 0, 0},
+	no_msp34xx:     1,
+	pll:            PLL_28,
+	tuner_type:     TUNER_PHILIPS_NTSC_M,
+	audio_hook:     gvbctv3pci_audio,
+},{
+	name:           "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */
+	video_inputs:   4,                  /* id-inputs-clock */
+	audio_inputs:   0,
+	tuner:          -1,
+	svhs:           3,
+	muxsel:         { 3, 2, 0, 1 },
+	pll:            PLL_28,
+	tuner_type:     -1,
+        no_msp34xx:     1,
+        no_tda9875:     1,
+        no_tda7432:     1,
+},{
+	name:           "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */
+	video_inputs:   3,
+	audio_inputs:   0,
+	tuner:          -1,
+	svhs:           2,
+	muxsel:         { 2, 3, 1 },
+	pll:            PLL_28,
+	tuner_type:     -1,
+        no_msp34xx:     1,
+        no_tda9875:     1,
+        no_tda7432:     1,
+},{
+
+	/* ---- card 0x54 ---------------------------------- */
+	name:           "Osprey 101 (848)", /* 0x05-40C0-C1 */
+	video_inputs:   2,
+	audio_inputs:   0,
+	tuner:          -1,
+	svhs:           1,
+	muxsel:         { 3, 1 },
+	pll:            PLL_28,
+	tuner_type:     -1,
+        no_msp34xx:     1,
+        no_tda9875:     1,
+        no_tda7432:     1,
+},{
+	name:           "Osprey 101/151",       /* 0x1(4|5)-0004-C4 */
+	video_inputs:   1,
+	audio_inputs:   0,
+	tuner:          -1,
+	svhs:           -1,
+	muxsel:         { 0 },
+	pll:            PLL_28,
+	tuner_type:     -1,
+        no_msp34xx:     1,
+        no_tda9875:     1,
+        no_tda7432:     1,
+},{
+	name:           "Osprey 101/151 w/ svid",  /* 0x(16|17|20)-00C4-C1 */
+	video_inputs:   2,
+	audio_inputs:   0,
+	tuner:          -1,
+	svhs:           1,
+	muxsel:         { 0, 1 },
+	pll:            PLL_28,
+	tuner_type:     -1,
+        no_msp34xx:     1,
+        no_tda9875:     1,
+        no_tda7432:     1,
+},{
+	name:           "Osprey 200/201/250/251",  /* 0x1(8|9|E|F)-0004-C4 */
+	video_inputs:   1,
+	audio_inputs:   1,
+	tuner:          -1,
+	svhs:           -1,
+	muxsel:         { 0 },
+	pll:            PLL_28,
+	tuner_type:     -1,
+        no_msp34xx:     1,
+        no_tda9875:     1,
+        no_tda7432:     1,
+},{
+	
+	/* ---- card 0x58 ---------------------------------- */
+	name:           "Osprey 200/250",   /* 0x1(A|B)-00C4-C1 */
+	video_inputs:   2,
+	audio_inputs:   1,
+	tuner:          -1,
+	svhs:           1,
+	muxsel:         { 0, 1 },
+	pll:            PLL_28,
+	tuner_type:     -1,
+        no_msp34xx:     1,
+        no_tda9875:     1,
+        no_tda7432:     1,
+},{
+	name:           "Osprey 210/220",   /* 0x1(A|B)-04C0-C1 */
+	video_inputs:   2,
+	audio_inputs:   1,
+	tuner:          -1,
+	svhs:           1,
+	muxsel:         { 2, 3 },
+	pll:            PLL_28,
+	tuner_type:     -1,
+        no_msp34xx:     1,
+        no_tda9875:     1,
+        no_tda7432:     1,
+},{
+	name:           "Osprey 500",   /* 500 */
+	video_inputs:   2,
+	audio_inputs:   1,
+	tuner:          -1,
+	svhs:           1,
+	muxsel:         { 2, 3 },
+	pll:            PLL_28,
+	tuner_type:     -1,
+        no_msp34xx:     1,
+        no_tda9875:     1,
+        no_tda7432:     1,
+},{
+       name:           "Osprey 540",   /* 540 */
+       video_inputs:   4,
+       audio_inputs:   1,
+       tuner:          -1,
+#if 0 /* TODO ... */
+       svhs:           OSPREY540_SVID_ANALOG,
+       muxsel:         {       [OSPREY540_COMP_ANALOG] = 2,
+                               [OSPREY540_SVID_ANALOG] = 3, },
+#endif
+       pll:            PLL_28,
+       tuner_type:     -1,
+       no_msp34xx:     1,
+       no_tda9875:     1,
+       no_tda7432:     1,
+#if 0 /* TODO ... */
+       muxsel_hook:    osprey_540_muxsel,
+       picture_hook:   osprey_540_set_picture,
+#endif
+},{
+
+	/* ---- card 0x5C ---------------------------------- */
+	name:           "Osprey 2000",  /* 2000 */
+	video_inputs:   2,
+	audio_inputs:   1,
+	tuner:          -1,
+	svhs:           1,
+	muxsel:         { 2, 3 },
+	pll:            PLL_28,
+	tuner_type:     -1,
+        no_msp34xx:     1,
+        no_tda9875:     1,
+        no_tda7432:     1,      /* must avoid, conflicts with the bt860 */
+},{
+	/* M G Berberich <berberic@forwiss.uni-passau.de> */
+	name:           "IDS Eagle",
+	video_inputs:   4,
+	audio_inputs:   0,
+	tuner:          -1,
+	tuner_type:     -1,
+	svhs:           -1,
+	gpiomask:       0,
+	muxsel:         { 0, 1, 2, 3 },
+	muxsel_hook:    eagle_muxsel,
+	no_msp34xx:     1,
+	no_tda9875:     1,
+	pll:            PLL_28,
 }};
 
 const int bttv_num_tvcards = (sizeof(bttv_tvcards)/sizeof(struct tvcard));
@@ -1355,11 +1626,13 @@
 	switch(ttype) {
 	case 0x0: tuner=4; // None
 		break;
-	case 0x4: tuner=5; // Philips PAL
+        case 0x2: tuner=39;// LG NTSC (newer TAPC series) TAPC-H701P
+		break;
+	case 0x4: tuner=5; // Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216
 		break;
-	case 0x6: tuner=37; // LG PAL (newer TAPC series)
+	case 0x6: tuner=37; // LG PAL (newer TAPC series) TAPC-G702P
 		break;
-	case 0xC: tuner=3; // Philips SECAM(+PAL)
+	case 0xC: tuner=3; // Philips SECAM(+PAL) FQ1216ME or FI1216MF
 		break;
 	default:
 		printk(KERN_INFO "bttv%d: FlyVideo_gpio: unknown tuner type.\n", btv->nr);
@@ -1394,48 +1667,148 @@
 int miro_tunermap[] = { 0,6,2,3,   4,5,6,0,  3,0,4,5,  5,2,16,1,
 			14,2,17,1, 4,1,4,3,  1,2,16,1, 4,4,4,4 };
 int miro_fmtuner[]  = { 0,0,0,0,   0,0,0,0,  0,0,0,0,  0,0,0,1,
-			1,1,1,1,   1,1,1,0,  0,0,0,0,  0,0,0,0 };
+			1,1,1,1,   1,1,1,0,  0,0,0,0,  0,1,0,0 };
 
 static void miro_pinnacle_gpio(struct bttv *btv)
 {
-	int id,msp;
-	
-	id  = ((btread(BT848_GPIO_DATA)>>10) & 31) -1;
-	msp = bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx");
-	btv->tuner_type = miro_tunermap[id];
-	if (0 == (btread(BT848_GPIO_DATA) & 0x20)) {
-		btv->has_radio = 1;
-		if (!miro_fmtuner[id]) {
-			btv->has_matchbox = 1;
-			btv->mbox_we    = (1<<6);
-			btv->mbox_most  = (1<<7);
-			btv->mbox_clk   = (1<<8);
-			btv->mbox_data  = (1<<9);
-			btv->mbox_mask  = (1<<6)|(1<<7)|(1<<8)|(1<<9);
+	int id,msp,gpio;
+	char *info;
+
+	btwrite(0,BT848_GPIO_OUT_EN);
+        gpio = btread(BT848_GPIO_DATA);
+	id   = ((gpio>>10) & 63) -1;
+	msp  = bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx");
+	if (id < 32) {
+		btv->tuner_type = miro_tunermap[id];
+		if (0 == (gpio & 0x20)) {
+			btv->has_radio = 1;
+			if (!miro_fmtuner[id]) {
+				btv->has_matchbox = 1;
+				btv->mbox_we    = (1<<6);
+				btv->mbox_most  = (1<<7);
+				btv->mbox_clk   = (1<<8);
+				btv->mbox_data  = (1<<9);
+				btv->mbox_mask  = (1<<6)|(1<<7)|(1<<8)|(1<<9);
+			}
+		} else {
+			btv->has_radio = 0;
+		}
+		if (-1 != msp) {
+			if (btv->type == BTTV_MIRO)
+				btv->type = BTTV_MIROPRO;
+			if (btv->type == BTTV_PINNACLE)
+				btv->type = BTTV_PINNACLEPRO;
 		}
+		printk(KERN_INFO "bttv%d: miro: id=%d tuner=%d radio=%s stereo=%s\n",
+		       btv->nr, id+1, btv->tuner_type,
+		       !btv->has_radio ? "no" :
+		       (btv->has_matchbox ? "matchbox" : "fmtuner"),
+		       (-1 == msp) ? "no" : "yes");
 	} else {
+		/* new cards with microtune tuner */
+		id = 63 - id;
 		btv->has_radio = 0;
+		switch (id) {
+		case 1:
+			info = "PAL / mono";
+			break;
+		case 2:
+			info = "PAL+SECAM / stereo";
+			btv->has_radio = 1;
+			break;
+		case 3:
+			info = "NTSC / stereo";
+			btv->has_radio = 1;
+			break;
+		case 4:
+			info = "PAL+SECAM / mono";
+			break;
+		case 5:
+			info = "NTSC / mono";
+			break;
+		case 6:
+			info = "NTSC / stereo";
+			break;
+		default:
+			info = "oops: unknown card";
+			break;
+		}
+		printk(KERN_INFO
+		       "bttv%d: pinnacle/mt: id=%d info=\"%s\" radio=%s\n",
+		       btv->nr, id, info, btv->has_radio ? "yes" : "no");
+		btv->tuner_type = 33;
+		if (autoload)
+			request_module("tda9887");
+		bttv_call_i2c_clients(btv,AUDC_CONFIG_PINNACLE,&id);
 	}
-	if (-1 != msp) {
-		if (btv->type == BTTV_MIRO)
-			btv->type = BTTV_MIROPRO;
-		if (btv->type == BTTV_PINNACLE)
-			btv->type = BTTV_PINNACLEPRO;
-	}
-	printk(KERN_INFO "bttv%d: miro: id=%d tuner=%d radio=%s stereo=%s\n",
-	       btv->nr, id+1, btv->tuner_type,
-	       !btv->has_radio ? "no" :
-	       (btv->has_matchbox ? "matchbox" : "fmtuner"),
-	       (-1 == msp) ? "no" : "yes");
 }
 
+/* GPIO21   L: Buffer aktiv, H: Buffer inaktiv */
+#define LM1882_SYNC_DRIVE     0x200000L
+
+static void init_ids_eagle(struct bttv *btv)
+{
+	btwrite(0xFFFF37, BT848_GPIO_OUT_EN);
+	btwrite(0x000000, BT848_GPIO_REG_INP);
+	
+	btwrite(0x200020, BT848_GPIO_DATA);
+	
+	/* flash strobe inverter ?! */
+	btwrite(0x200024, BT848_GPIO_DATA);
+	
+	/* switch sync drive off */
+	btor(LM1882_SYNC_DRIVE, BT848_GPIO_DATA);
+	
+	/* set BT848 muxel to 2 */
+	btaor((2)<<5, ~(2<<5), BT848_IFORM);
+}
+
+/* Muxsel helper for the IDS Eagle.
+ * the eagles does not use the standard muxsel-bits but
+ * has its own multiplexer */
+static void eagle_muxsel(struct bttv *btv, unsigned int input)
+{
+	btaor((2)<<5, ~(3<<5), BT848_IFORM);
+	btaor((bttv_tvcards[btv->type].muxsel[input&7]&3),
+	      ~3, BT848_GPIO_DATA);
+
+#if 0
+       /* svhs */
+       /* wake chroma ADC */
+       btand(~BT848_ADC_C_SLEEP, BT848_ADC);
+       /* set to YC video */
+       btor(BT848_CONTROL_COMP, BT848_E_CONTROL);
+       btor(BT848_CONTROL_COMP, BT848_O_CONTROL);
+#else
+       /* composite */
+       /* set chroma ADC to sleep */
+       btor(BT848_ADC_C_SLEEP, BT848_ADC);
+       /* set to composite video */
+       btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
+       btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
+#endif
+
+       /* switch sync drive off */
+       btor(LM1882_SYNC_DRIVE, BT848_GPIO_DATA);
+}
+
+/* ----------------------------------------------------------------------- */
+
 /* initialization part one -- before registering i2c bus */
 void __devinit bttv_init_card1(struct bttv *btv)
 {
-        if (btv->type == BTTV_HAUPPAUGE || btv->type == BTTV_HAUPPAUGE878)
+	switch (btv->type) {
+	case BTTV_HAUPPAUGE:
+	case BTTV_HAUPPAUGE878:
                 boot_msp34xx(btv,5);
-        if (btv->type == BTTV_VOODOOTV_FM)
+		break;
+	case BTTV_VOODOOTV_FM:
                 boot_msp34xx(btv,20);
+		break;
+	case BTTV_HAUPPAUGEPVR:
+		pvr_boot(btv);
+		break;
+	}
 }
 
 /* initialization part two -- after registering i2c bus */
@@ -1443,40 +1816,43 @@
 {
         btv->tuner_type = -1;
 
-        /* miro/pinnacle */
-        if (btv->type == BTTV_MIRO      ||
-            btv->type == BTTV_MIROPRO   ||
-            btv->type == BTTV_PINNACLE  ||
-            btv->type == BTTV_PINNACLEPRO) 
+	switch (btv->type) {
+	case BTTV_MIRO:
+	case BTTV_MIROPRO:
+	case BTTV_PINNACLE:
+	case BTTV_PINNACLEPRO: 
+		/* miro/pinnacle */
 		miro_pinnacle_gpio(btv);
-
-	if (btv->type == BTTV_FLYVIDEO_98    ||
-	    btv->type == BTTV_LIFE_FLYKIT    ||
-	    btv->type == BTTV_FLYVIDEO       ||
-	    btv->type == BTTV_TYPHOON_TVIEW  ||
-	    btv->type == BTTV_CHRONOS_VS2    ||
-	    btv->type == BTTV_FLYVIDEO_98FM  ||
-	    btv->type == BTTV_FLYVIDEO2000   ||
-	    btv->type == BTTV_FLYVIDEO98EZ   ||
-	    btv->type == BTTV_CONFERENCETV   ||
-	    btv->type == BTTV_LIFETEC_9415)
+		break;
+	case BTTV_FLYVIDEO_98:
+	case BTTV_MAXI:
+	case BTTV_LIFE_FLYKIT:
+	case BTTV_FLYVIDEO:
+	case BTTV_TYPHOON_TVIEW:
+	case BTTV_CHRONOS_VS2:
+	case BTTV_FLYVIDEO_98FM:
+	case BTTV_FLYVIDEO2000:
+	case BTTV_FLYVIDEO98EZ:
+	case BTTV_CONFERENCETV:
+	case BTTV_LIFETEC_9415:
 		flyvideo_gpio(btv);
-
-        if (btv->type == BTTV_HAUPPAUGE || btv->type == BTTV_HAUPPAUGE878) {
+		break;
+	case BTTV_HAUPPAUGE:
+	case BTTV_HAUPPAUGE878:
+	case BTTV_HAUPPAUGEPVR:
 		/* pick up some config infos from the eeprom */
 		bttv_readee(btv,eeprom_data,0xa0);
                 hauppauge_eeprom(btv);
-        }
-
-	if (btv->type == BTTV_AVERMEDIA98 || btv->type == BTTV_AVPHONE98) {
+		break;
+	case BTTV_AVERMEDIA98:
+	case BTTV_AVPHONE98:
 		bttv_readee(btv,eeprom_data,0xa0);
 		avermedia_eeprom(btv);
-	}
-
- 	if (btv->type == BTTV_PXC200)
+		break;
+	case BTTV_PXC200:
 		init_PXC200(btv);
-
-	if (btv->type == BTTV_VHX) {
+		break;
+	case BTTV_VHX:
 		btv->has_radio    = 1;
 		btv->has_matchbox = 1;
 		btv->mbox_we      = 0x20;
@@ -1484,13 +1860,42 @@
 		btv->mbox_clk     = 0x08;
 		btv->mbox_data    = 0x10;
 		btv->mbox_mask    = 0x38;
-	}
-
-	if (btv->type == BTTV_MAGICTVIEW061) {
-		if(btv->cardid == 0x4002144f) {
+		break;
+	case BTTV_VOBIS_BOOSTAR:
+	case BTTV_TERRATV:
+		terratec_active_radio_upgrade(btv);
+		break;
+	case BTTV_MAGICTVIEW061:
+		if (btv->cardid == 0x3002144f) {
 			btv->has_radio=1;
 			printk("bttv%d: radio detected by subsystem id (CPH05x)\n",btv->nr);
 		}
+		break;
+       case BTTV_STB2:
+                if (btv->cardid == 0x3060121a) {
+			/* Fix up entry for 3DFX VoodooTV 100,
+			   which is an OEM STB card variant. */
+			btv->has_radio=0;
+			btv->tuner_type=TUNER_TEMIC_NTSC;
+		}
+		break;
+	case BTTV_OSPREY1x0:
+	case BTTV_OSPREY1x0_848:
+	case BTTV_OSPREY101_848:
+	case BTTV_OSPREY1x1:
+	case BTTV_OSPREY1x1_SVID:
+	case BTTV_OSPREY2xx:
+	case BTTV_OSPREY2x0_SVID:
+	case BTTV_OSPREY2x0:
+	case BTTV_OSPREY500:
+	case BTTV_OSPREY540:
+	case BTTV_OSPREY2000:
+		bttv_readee(btv,eeprom_data,0xa0);
+                osprey_eeprom(btv);
+		break;
+	case BTTV_IDS_EAGLE:
+		init_ids_eagle(btv);
+		break;
 	}
 
 	/* pll configuration */
@@ -1542,6 +1947,34 @@
 	if (bttv_tvcards[btv->type].audio_hook)
 		btv->audio_hook=bttv_tvcards[btv->type].audio_hook;
 
+#if 0
+	/* detect Bt832 chip for quartzsight digital camera */
+	if((bttv_I2CRead(btv, I2C_BT832_ALT1, "Bt832") >=0) ||
+	   (bttv_I2CRead(btv, I2C_BT832_ALT2, "Bt832") >=0)) {
+		int outbits,databits;
+		request_module("bt832");
+
+		bttv_call_i2c_clients(btv, BT832_HEXDUMP, NULL);
+
+		printk("Reset Bt832 (0x400000 for Pixelview 4E)\n");
+		btwrite(0, BT848_GPIO_DATA);
+		outbits = btread(BT848_GPIO_OUT_EN);
+		databits= btread(BT848_GPIO_DATA);
+		btwrite(0x400000, BT848_GPIO_OUT_EN);
+		udelay(5);
+		btwrite(0x400000, BT848_GPIO_DATA);
+        	udelay(5);
+		btwrite(0, BT848_GPIO_DATA);
+		udelay(5);
+		btwrite(outbits, BT848_GPIO_OUT_EN);
+		btwrite(databits, BT848_GPIO_DATA);
+
+		// bt832 on pixelview changes from i2c 0x8a to 0x88 after
+		// being reset as above. So we must follow by this:
+		bttv_call_i2c_clients(btv, BT832_REATTACH, NULL);
+	}
+#endif
+
 	/* try to detect audio/fader chips */
 	if (!bttv_tvcards[btv->type].no_msp34xx &&
 	    bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx") >=0) {
@@ -1555,7 +1988,8 @@
 			request_module("tda9875");
 	}
 
-	if (bttv_I2CRead(btv, I2C_TDA7432, "TDA7432") >=0) {
+	if (!bttv_tvcards[btv->type].no_tda7432 && 
+	    bttv_I2CRead(btv, I2C_TDA7432, "TDA7432") >=0) {
 		if (autoload)
 			request_module("tda7432");
 	}
@@ -1663,6 +2097,220 @@
 		       btv->tuner_type, radio ? "yes" : "no");
 }
 
+static int terratec_active_radio_upgrade(struct bttv *btv)
+{
+	int freq;
+
+	btv->has_radio    = 1;
+	btv->has_matchbox = 1;
+	btv->mbox_we      = 0x10;
+	btv->mbox_most    = 0x20;
+	btv->mbox_clk     = 0x08;
+	btv->mbox_data    = 0x04;
+	btv->mbox_mask    = 0x3c;
+
+	btv->mbox_iow     = 1 <<  8;
+	btv->mbox_ior     = 1 <<  9;
+	btv->mbox_csel    = 1 << 10;
+
+	freq=88000/62.5;
+	tea5757_write(btv, 5 * freq + 0x358); // write 0x1ed8
+	if (0x1ed8 == tea5757_read(btv)) {
+		printk("bttv%d: Terratec Active Radio Upgrade found.\n",
+		       btv->nr);
+		btv->has_radio    = 1;
+		btv->has_matchbox = 1;
+	} else {
+		btv->has_radio    = 0;
+		btv->has_matchbox = 0;
+	}
+	return 0;
+}	
+
+
+/* ----------------------------------------------------------------------- */
+
+/*
+ * minimal bootstrap for the WinTV/PVR -- upload altera firmware.
+ *
+ * The hcwamc.rbf firmware file is on the Hauppauge driver CD.  Have
+ * a look at Pvr/pvr45xxx.EXE (self-extracting zip archive, can be
+ * unpacked with unzip).
+ */
+static char *firm_altera = "/usr/lib/video4linux/hcwamc.rbf";
+MODULE_PARM(firm_altera,"s");
+MODULE_PARM_DESC(firm_altera,"WinTV/PVR firmware "
+		 "(driver CD => unzip pvr45xxx.exe => hcwamc.rbf)");
+
+/* drivers/sound/sound_firmware.c => soundcore.o */
+extern int mod_firmware_load(const char *fn, char **fp);
+
+#define PVR_GPIO_DELAY		10
+
+#define BTTV_ALT_DATA		0x000001
+#define BTTV_ALT_DCLK		0x100000
+#define BTTV_ALT_NCONFIG	0x800000
+
+static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen)
+{
+	u32 n;
+  	u8 bits;
+	int i;
+ 
+	btwrite(BTTV_ALT_DATA|BTTV_ALT_DCLK|BTTV_ALT_NCONFIG,
+		BT848_GPIO_OUT_EN);
+	btwrite(0,BT848_GPIO_DATA);
+	udelay(PVR_GPIO_DELAY);
+	
+	btwrite(BTTV_ALT_NCONFIG,BT848_GPIO_DATA);
+	udelay(PVR_GPIO_DELAY);
+
+	for (n = 0; n < microlen; n++) {
+		bits = micro[n];
+		for ( i = 0 ; i < 8 ; i++ ) {
+			btand(~BTTV_ALT_DCLK,BT848_GPIO_DATA);
+			if (bits & 0x01) 
+				btor(BTTV_ALT_DATA,BT848_GPIO_DATA);
+			else 
+				btand(~BTTV_ALT_DATA,BT848_GPIO_DATA);
+			btor(BTTV_ALT_DCLK,BT848_GPIO_DATA);
+			bits >>= 1;
+		}
+	}
+	btand(~BTTV_ALT_DCLK,BT848_GPIO_DATA);
+	udelay(PVR_GPIO_DELAY);
+	
+	/* begin Altera init loop (Not necessary,but doesn't hurt) */
+	for (i = 0 ; i < 30 ; i++) {
+		btand(~BTTV_ALT_DCLK,BT848_GPIO_DATA);
+		btor(BTTV_ALT_DCLK,BT848_GPIO_DATA);
+	}
+	btand(~BTTV_ALT_DCLK,BT848_GPIO_DATA);
+	return 0;
+}
+
+int __devinit pvr_boot(struct bttv *btv)
+{
+	u32 microlen;
+	u8 *micro;
+	int result;
+
+	microlen = mod_firmware_load(firm_altera, (char**) &micro);
+	if (!microlen)
+		return -1;
+	
+	printk(KERN_INFO "bttv%d: uploading altera firmware [%s] ...\n",
+	       btv->nr, firm_altera);
+	result = pvr_altera_load(btv, micro, microlen);
+	printk(KERN_INFO "bttv%d: ... upload %s\n",
+	       btv->nr, (result < 0) ? "failed" : "ok");
+	vfree(micro);
+	return result;
+}
+
+/* ----------------------------------------------------------------------- */
+/* some osprey specific stuff                                              */
+
+static void __devinit osprey_eeprom(struct bttv *btv)
+{
+       int i = 0;
+       unsigned char *ee = eeprom_data;
+       unsigned long serial = 0;
+    
+       if (btv->type == 0) {
+               /* this might be an antique... check for MMAC label in eeprom */
+               if ((ee[0]=='M') && (ee[1]=='M') && (ee[2]=='A') && (ee[3]=='C')) {
+                       unsigned char checksum = 0;
+                       for (i =0; i<21; i++)
+			       checksum += ee[i];
+                       if (checksum != ee[21])
+			       return;
+		       btv->type = BTTV_OSPREY1x0_848;
+		       for (i = 12; i < 21; i++)
+			       serial *= 10, serial += ee[i] - '0';
+               }
+       } else {
+	       unsigned short type;
+               int offset = 4*16;
+        
+               for(; offset < 8*16; offset += 16) {
+                       unsigned short checksum = 0;
+                       /* verify the checksum */
+                       for(i = 0; i<14; i++) checksum += ee[i+offset];
+                               checksum = ~checksum;  /* no idea why */
+                               if ((((checksum>>8)&0x0FF) == ee[offset+14]) &&
+                                   ((checksum & 0x0FF) == ee[offset+15])) {
+                               break;
+                       }
+               }
+        
+               if (offset >= 8*16)
+		       return;
+
+	       /* found a valid descriptor */
+	       type = (ee[offset+4]<<8) | (ee[offset+5]);
+	       
+	       switch(type) {
+
+	       /* 848 based */
+	       case 0x0004:
+		       btv->type = BTTV_OSPREY1x0_848;
+		       break;
+	       case 0x0005:
+		       btv->type = BTTV_OSPREY101_848;
+		       break;
+		       
+               /* 878 based */
+	       case 0x0012:
+	       case 0x0013:
+		       btv->type = BTTV_OSPREY1x0;
+		       break;
+	       case 0x0014:
+	       case 0x0015:
+		       btv->type = BTTV_OSPREY1x1;
+		       break;
+	       case 0x0016:
+	       case 0x0017:
+	       case 0x0020:
+		       btv->type = BTTV_OSPREY1x1_SVID;
+		       break;
+	       case 0x0018:
+	       case 0x0019:
+	       case 0x001E:
+	       case 0x001F:
+		       btv->type = BTTV_OSPREY2xx;
+		       break;
+	       case 0x001A:
+	       case 0x001B:
+		       btv->type = BTTV_OSPREY2x0_SVID;
+		       break;
+	       case 0x0040:
+		       btv->type = BTTV_OSPREY500;
+		       break;
+	       case 0x0050:
+	       case 0x0056:
+		       btv->type = BTTV_OSPREY540;
+		       /* bttv_osprey_540_init(btv); */
+		       break;
+	       case 0x0060:
+	       case 0x0070:
+		       btv->type = BTTV_OSPREY2x0;
+		       //enable output on select control lines
+		       btwrite(0x000303, BT848_GPIO_OUT_EN);
+		       break;
+	       default:
+		       /* unknown...leave generic, but get serial # */
+		       break;
+	       }
+	       serial =  (ee[offset+6] << 24)
+		       | (ee[offset+7] << 16)
+		       | (ee[offset+8] <<  8)
+		       | (ee[offset+9]);
+       }
+       
+       printk(KERN_INFO "bttv%d: osprey eeprom: card=%d name=%s serial=%ld\n",
+	      btv->nr, btv->type, bttv_tvcards[btv->type].name,serial);
+}	
 
 /* ----------------------------------------------------------------------- */
 /* AVermedia specific stuff, from  bktr_card.c                             */
@@ -1822,17 +2470,55 @@
  * Brutally hacked by Dan Sheridan <dan.sheridan@contact.org.uk> djs52 8/3/00
  */
 
-#if 0
-/* bus bits on the GPIO port */
-#define TEA_WE			6
-#define TEA_DATA		9
-#define TEA_CLK			8
-#define TEA_MOST		7
-#endif
+void bus_low(struct bttv *btv, int bit)
+{
+	if (btv->mbox_ior) {
+		btor(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
+		     BT848_GPIO_DATA);
+		udelay(5);
+	}
+
+	btand(~(bit), BT848_GPIO_DATA);
+	udelay(5);
+
+	if (btv->mbox_ior) {
+		btand(~(btv->mbox_iow | btv->mbox_csel),
+		      BT848_GPIO_DATA);
+		udelay(5);
+	}
+}
+
+void bus_high(struct bttv *btv, int bit)
+{
+	if (btv->mbox_ior) {
+		btor(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
+		     BT848_GPIO_DATA);
+		udelay(5);
+	}
+
+	btor((bit), BT848_GPIO_DATA);
+	udelay(5);
 
-#define BUS_LOW(bit) 	btand(~(bit), BT848_GPIO_DATA)
-#define BUS_HIGH(bit)	btor((bit), BT848_GPIO_DATA)
-#define BUS_IN(bit)	(btread(BT848_GPIO_DATA) & (bit))
+	if (btv->mbox_ior) {
+		btand(~(btv->mbox_iow | btv->mbox_csel),
+		      BT848_GPIO_DATA);
+		udelay(5);
+	}
+}
+
+int bus_in(struct bttv *btv, int bit)
+{
+	if (btv->mbox_ior) {
+		btor(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
+		     BT848_GPIO_DATA);
+		udelay(5);
+
+		btand(~(btv->mbox_ior | btv->mbox_csel),
+		      BT848_GPIO_DATA);
+		udelay(5);
+	}
+	return btread(BT848_GPIO_DATA) & (bit);
+}
 
 /* TEA5757 register bits */
 #define TEA_FREQ		0:14
@@ -1871,34 +2557,41 @@
 	/* better safe than sorry */
 	btaor((btv->mbox_clk | btv->mbox_we),
 	      ~btv->mbox_mask, BT848_GPIO_OUT_EN);
+
+	if (btv->mbox_ior) {
+		btor(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
+		     BT848_GPIO_DATA);
+		udelay(5);
+	}
+
 	if (bttv_gpio)
 		bttv_gpio_tracking(btv,"tea5757 read");
 	
-	BUS_LOW(btv->mbox_we);
-	BUS_LOW(btv->mbox_clk);
+	bus_low(btv,btv->mbox_we);
+	bus_low(btv,btv->mbox_clk);
 	
 	udelay(10);
-	for(timeout = jiffies + 10 * HZ;
-	    BUS_IN(btv->mbox_data) && time_before(jiffies, timeout);
-	    schedule());	/* 10 s */
-	if (BUS_IN(btv->mbox_data)) {
+	timeout= jiffies + HZ;
+
+	// wait for DATA line to go low; error if it doesn't
+	while (bus_in(btv,btv->mbox_data) && time_before(jiffies, timeout))
+		schedule();
+	if (bus_in(btv,btv->mbox_data)) {
 		printk(KERN_WARNING "bttv%d: tea5757: read timeout\n",btv->nr);
 		return -1;
 	}
-	for(timeout = jiffies + HZ/5;
-	    BUS_IN(btv->mbox_data) == 1 && time_before(jiffies, timeout);
-	    schedule());	/* 0.2 s */
+
 	dprintk("bttv%d: tea5757:",btv->nr);
 	for(i = 0; i < 24; i++)
 	{
 		udelay(5);
-		BUS_HIGH(btv->mbox_clk);
+		bus_high(btv,btv->mbox_clk);
 		udelay(5);
-		dprintk("%c",(BUS_IN(btv->mbox_most) == 0)?'T':'-');
-		BUS_LOW(btv->mbox_clk);
+		dprintk("%c",(bus_in(btv,btv->mbox_most) == 0)?'T':'-');
+		bus_low(btv,btv->mbox_clk);
 		value <<= 1;
-		value |= (BUS_IN(btv->mbox_data) == 0)?0:1;  /* MSB first */
-		dprintk("%c", (BUS_IN(btv->mbox_most) == 0)?'S':'M');
+		value |= (bus_in(btv,btv->mbox_data) == 0)?0:1;  /* MSB first */
+		dprintk("%c", (bus_in(btv,btv->mbox_most) == 0)?'S':'M');
 	}
 	dprintk("\nbttv%d: tea5757: read 0x%X\n", btv->nr, value);
 	return value;
@@ -1911,32 +2604,42 @@
 	
 	btaor(btv->mbox_clk | btv->mbox_we | btv->mbox_data,
 	      ~btv->mbox_mask, BT848_GPIO_OUT_EN);
+
+	if (btv->mbox_ior) {
+		btor(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
+		     BT848_GPIO_DATA);
+		udelay(5);
+	}
 	if (bttv_gpio)
 		bttv_gpio_tracking(btv,"tea5757 write");
+
 	dprintk("bttv%d: tea5757: write 0x%X\n", btv->nr, value);
-	BUS_LOW(btv->mbox_clk);
-	BUS_HIGH(btv->mbox_we);
+	bus_low(btv,btv->mbox_clk);
+	bus_high(btv,btv->mbox_we);
 	for(i = 0; i < 25; i++)
 	{
 		if (reg & 0x1000000)
-			BUS_HIGH(btv->mbox_data);
+			bus_high(btv,btv->mbox_data);
 		else
-			BUS_LOW(btv->mbox_data);
+			bus_low(btv,btv->mbox_data);
 		reg <<= 1;
-		BUS_HIGH(btv->mbox_clk);
+		bus_high(btv,btv->mbox_clk);
 		udelay(10);
-		BUS_LOW(btv->mbox_clk);
+		bus_low(btv,btv->mbox_clk);
 		udelay(10);
 	}
-	BUS_LOW(btv->mbox_we);  /* unmute !!! */
+	bus_low(btv,btv->mbox_we);  /* unmute !!! */
 	return 0;
 }
 
 void tea5757_set_freq(struct bttv *btv, unsigned short freq)
 {
+	int value;
+	
+	dprintk("tea5757_set_freq %d\n",freq);
 	tea5757_write(btv, 5 * freq + 0x358); /* add 10.7MHz (see docs) */
-	if (bttv_debug)
-		tea5757_read(btv);
+	value = tea5757_read(btv);
+	dprintk("bttv%d: tea5757 readback =0x%x\n",btv->nr,value);
 }
 
 
@@ -2076,7 +2779,7 @@
         }
 }
 
-
+// TDA9821 on TerraTV+ Bt848, Bt878
 static void
 terratv_audio(struct bttv *btv, struct video_audio *v, int set)
 {
@@ -2127,6 +2830,9 @@
  * Dariusz Kowalewski <darekk@automex.pl>
  * sound control for Prolink PV-BT878P+9B (PixelView PlayTV Pro FM+NICAM
  * revision 9B has on-board TDA9874A sound decoder).
+ *
+ * Note: There are card variants without tda9874a. Forcing the "stereo sound route"
+ *       will mute this cards.
  */
 static void
 pvbt878p9b_audio(struct bttv *btv, struct video_audio *v, int set)
diff -Nru a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
--- a/drivers/media/video/bttv-driver.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/media/video/bttv-driver.c	Mon Nov  4 14:31:02 2002
@@ -23,6 +23,7 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+#include <linux/init.h>
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/delay.h>
@@ -31,7 +32,6 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
-#include <linux/init.h>
 #include <linux/kdev_t.h>
 
 #include <asm/io.h>
@@ -74,14 +74,11 @@
 
 /* API features (turn on/off stuff for testing) */
 static unsigned int sloppy     = 0;
-static unsigned int mmap       = 1;
-#ifdef HAVE_V4L2
 static unsigned int v4l2       = 1;
-#endif
 
 
 /* insmod args */
-MODULE_PARM(radio,"1-" __MODULE_STRING(BTTV_MAX) "i");
+MODULE_PARM(radio,"1-" __stringify(BTTV_MAX) "i");
 MODULE_PARM_DESC(radio,"The TV card supports radio, default is 0 (no)");
 MODULE_PARM(bigendian,"i");
 MODULE_PARM_DESC(bigendian,"byte order of the framebuffer, default is native endian");
@@ -115,10 +112,7 @@
 MODULE_PARM_DESC(adc_crush,"enables the luminance ADC crush, default is 1 (yes)");
 
 MODULE_PARM(sloppy,"i");
-MODULE_PARM(mmap,"i");
-#ifdef HAVE_V4L2
 MODULE_PARM(v4l2,"i");
-#endif
 
 MODULE_DESCRIPTION("bttv - v4l/v4l2 driver module for bt848/878 based cards");
 MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr");
@@ -130,74 +124,148 @@
 __setup("bttv.radio=", p_radio);
 #endif
 
-#ifndef HAVE_V4L2
-/* some dummy defines to avoid cluttering up the source code with
-   a huge number of ifdef's for V4L2 */
-# define V4L2_STD_PAL          -1
-# define V4L2_STD_NTSC         -1
-# define V4L2_STD_SECAM        -1
-# define V4L2_STD_PAL_60       -1
-# define V4L2_STD_PAL_M        -1
-# define V4L2_STD_PAL_N        -1
-# define V4L2_STD_NTSC_N       -1
-# define V4L2_PIX_FMT_GREY     -1
-# define V4L2_PIX_FMT_HI240    -1
-# define V4L2_PIX_FMT_RGB555   -1
-# define V4L2_PIX_FMT_RGB555X  -1
-# define V4L2_PIX_FMT_RGB565   -1
-# define V4L2_PIX_FMT_RGB565X  -1
-# define V4L2_PIX_FMT_BGR24    -1
-# define V4L2_PIX_FMT_BGR32    -1
-# define V4L2_PIX_FMT_RGB32    -1
-# define V4L2_PIX_FMT_YUYV     -1
-# define V4L2_PIX_FMT_UYVY     -1
-# define V4L2_PIX_FMT_YUV422P  -1
-# define V4L2_PIX_FMT_YUV420   -1
-# define V4L2_PIX_FMT_YVU420   -1
-# define V4L2_PIX_FMT_YUV411P  -1
-# define V4L2_PIX_FMT_YUV410   -1
-# define V4L2_PIX_FMT_YVU410   -1
-# define V4L2_BUF_TYPE_CAPTURE -1
-# define V4L2_BUF_TYPE_VBI     -1
-# define BTTV_APIS "[v4l]"
-#else
-# define BTTV_APIS "[v4l/v4l2]"
-#endif
-
 /* ----------------------------------------------------------------------- */
 /* static data                                                             */
 
+/* special timing tables from conexant... */
+static u8 SRAM_Table[][60] =
+{
+	/* PAL digital input over GPIO[7:0] */
+	{
+		0x36,0x11,0x01,0x00,0x90,0x02,0x05,0x10,0x04,0x16,
+		0x12,0x05,0x11,0x00,0x04,0x12,0xC0,0x00,0x31,0x00,
+		0x06,0x51,0x08,0x03,0x89,0x08,0x07,0xC0,0x44,0x00,
+		0x81,0x01,0x01,0xA9,0x0D,0x02,0x02,0x50,0x03,0x37,
+		0x37,0x00,0xAF,0x21,0x00
+	},
+	/* NTSC digital input over GPIO[7:0] */
+	{
+		0x0C,0xC0,0x00,0x00,0x90,0x02,0x03,0x10,0x03,0x06,
+		0x10,0x04,0x12,0x12,0x05,0x02,0x13,0x04,0x19,0x00,
+		0x04,0x39,0x00,0x06,0x59,0x08,0x03,0x83,0x08,0x07,
+		0x03,0x50,0x00,0xC0,0x40,0x00,0x86,0x01,0x01,0xA6,
+		0x0D,0x02,0x03,0x11,0x01,0x05,0x37,0x00,0xAC,0x21,
+		0x00,
+	},
+};
+
 const struct bttv_tvnorm bttv_tvnorms[] = {
 	/* PAL-BDGHI */
-        { V4L2_STD_PAL, 35468950,
-          922, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
-          1135, 186, 922, 0x20, 255},
-	/* NTSC */
-	{ V4L2_STD_NTSC, 28636363,
-          754, 480,  910, 0x70, 0x5d, (BT848_IFORM_NTSC|BT848_IFORM_XT0),
-          910, 135, 754, 0x1a, 144},
-	/* SECAM */
-        { V4L2_STD_SECAM, 35468950,
-          922, 576, 1135, 0x7f, 0xa0, (BT848_IFORM_SECAM|BT848_IFORM_XT1),
-          1135, 186, 922, 0x20, 255},
-
-	/* these ones are bttv specific (for v4l1) */
-        /* PAL-NC */
-        { V4L2_STD_PAL_60, 28636363,
-          640, 576,  910, 0x7f, 0x72, (BT848_IFORM_PAL_NC|BT848_IFORM_XT0),
-          780, 130, 734, 0x1a, 144},
-	/* PAL-M */
-	{ V4L2_STD_PAL_M, 28636363, 
-          640, 480, 910, 0x70, 0x5d, (BT848_IFORM_PAL_M|BT848_IFORM_XT0),
-	  780, 135, 754, 0x1a, 144},
-	/* PAL-N */
-	{ V4L2_STD_PAL_N, 35468950, 
-          768, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_N|BT848_IFORM_XT0),
-	  944, 186, 922, 0x20, 144},
-	/* NTSC-Japan */
-	{ V4L2_STD_NTSC_N, 28636363,
-          640, 480,  910, 0x70, 0x5d, (BT848_IFORM_NTSC_J|BT848_IFORM_XT0),
-	  780, 135, 754, 0x16, 144},
+        /* max. active video is actually 922, but 924 is divisible by 4 and 3! */
+ 	/* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */
+	{
+		.v4l2_id        = V4L2_STD_PAL,
+		.name           = "PAL",
+		.Fsc            = 35468950,
+		.swidth         = 924,
+		.sheight        = 576,
+		.totalwidth     = 1135,
+		.adelay         = 0x7f,
+		.bdelay         = 0x72, 
+		.iform          = (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
+		.scaledtwidth   = 1135,
+		.hdelayx1       = 186,
+		.hactivex1      = 924,
+		.vdelay         = 0x20,
+		.vbipack        = 255,
+		.sram           = 0,
+	},{
+		.v4l2_id        = V4L2_STD_NTSC,
+		.name           = "NTSC",
+		.Fsc            = 28636363,
+		.swidth         = 768,
+		.sheight        = 480,
+		.totalwidth     = 910,
+		.adelay         = 0x68,
+		.bdelay         = 0x5d,
+		.iform          = (BT848_IFORM_NTSC|BT848_IFORM_XT0),
+		.scaledtwidth   = 910,
+		.hdelayx1       = 128,
+		.hactivex1      = 910,
+		.vdelay         = 0x1a,
+		.vbipack        = 144,
+		.sram           = 1,
+	},{
+		.v4l2_id        = V4L2_STD_SECAM,
+		.name           = "SECAM",
+		.Fsc            = 35468950,
+		.swidth         = 924,
+		.sheight        = 576,
+		.totalwidth     = 1135,
+		.adelay         = 0x7f,
+		.bdelay         = 0xb0,
+		.iform          = (BT848_IFORM_SECAM|BT848_IFORM_XT1),
+		.scaledtwidth   = 1135,
+		.hdelayx1       = 186,
+		.hactivex1      = 922,
+		.vdelay         = 0x20,
+		.vbipack        = 255,
+		.sram           = 0, /* like PAL, correct? */
+	},{
+		.v4l2_id        = V4L2_STD_PAL_Nc,
+		.name           = "PAL-Nc",
+		.Fsc            = 28636363,
+		.swidth         = 640,
+		.sheight        = 576,
+		.totalwidth     = 910,
+		.adelay         = 0x68,
+		.bdelay         = 0x5d,
+		.iform          = (BT848_IFORM_PAL_NC|BT848_IFORM_XT0),
+		.scaledtwidth   = 780,
+		.hdelayx1       = 130,
+		.hactivex1      = 734,
+		.vdelay         = 0x1a,
+		.vbipack        = 144,
+		.sram           = -1,
+	},{
+		.v4l2_id        = V4L2_STD_PAL_M,
+		.name           = "PAL-M",
+		.Fsc            = 28636363,
+		.swidth         = 640,
+		.sheight        = 480,
+		.totalwidth     = 910,
+		.adelay         = 0x68,
+		.bdelay         = 0x5d,
+		.iform          = (BT848_IFORM_PAL_M|BT848_IFORM_XT0),
+		.scaledtwidth   = 780,
+		.hdelayx1       = 135,
+		.hactivex1      = 754,
+		.vdelay         = 0x1a,
+		.vbipack        = 144,
+		.sram           = -1,
+	},{
+		.v4l2_id        = V4L2_STD_PAL_N,
+		.name           = "PAL-N",
+		.Fsc             35468950,
+		.swidth         = 768,
+		.sheight        = 576,
+		.totalwidth     = 1135,
+		.adelay         = 0x7f,
+		.bdelay         = 0x72,
+		.iform          = (BT848_IFORM_PAL_N|BT848_IFORM_XT1),
+		.scaledtwidth   = 944,
+		.hdelayx1       = 186,
+		.hactivex1      = 922,
+		.vdelay         = 0x20,
+		.vbipack        = 144,
+		.sram           = -1,
+	},{
+		.v4l2_id        = V4L2_STD_NTSC_M_JP,
+		.name           = "NTSC-JP",
+		.Fsc            = 28636363,
+		.swidth         = 640,
+		.sheight        = 480,
+		.totalwidth     = 910,
+		.adelay         = 0x68,
+		.bdelay         = 0x5d,
+		.iform          = (BT848_IFORM_NTSC_J|BT848_IFORM_XT0),
+		.scaledtwidth   = 780,
+		.hdelayx1       = 135,
+		.hactivex1      = 754,
+		.vdelay         = 0x16,
+		.vbipack        = 144,
+		.sram           = -1,
+	}
 };
 const int BTTV_TVNORMS = (sizeof(bttv_tvnorms)/sizeof(struct bttv_tvnorm));
 
@@ -360,7 +428,6 @@
 
 /* ----------------------------------------------------------------------- */
 
-#ifdef HAVE_V4L2
 #define V4L2_CID_PRIVATE_CHROMA_AGC  (V4L2_CID_PRIVATE_BASE + 0)
 #define V4L2_CID_PRIVATE_COMBFILTER  (V4L2_CID_PRIVATE_BASE + 1)
 #define V4L2_CID_PRIVATE_AUTOMUTE    (V4L2_CID_PRIVATE_BASE + 2)
@@ -382,8 +449,6 @@
 		step:          256,
 		default_value: 32768,
 		type:          V4L2_CTRL_TYPE_INTEGER,
-		category:      V4L2_CTRL_CAT_VIDEO,
-		group:         "Video",
 	},{
 		id:            V4L2_CID_CONTRAST,
 		name:          "Contrast",
@@ -392,8 +457,6 @@
 		step:          128,
 		default_value: 32768,
 		type:          V4L2_CTRL_TYPE_INTEGER,
-		category:      V4L2_CTRL_CAT_VIDEO,
-		group:         "Video",
 	},{
 		id:            V4L2_CID_SATURATION,
 		name:          "Saturation",
@@ -402,8 +465,6 @@
 		step:          128,
 		default_value: 32768,
 		type:          V4L2_CTRL_TYPE_INTEGER,
-		category:      V4L2_CTRL_CAT_VIDEO,
-		group:         "Video",
 	},{
 		id:            V4L2_CID_HUE,
 		name:          "Hue",
@@ -412,8 +473,6 @@
 		step:          256,
 		default_value: 32768,
 		type:          V4L2_CTRL_TYPE_INTEGER,
-		category:      V4L2_CTRL_CAT_VIDEO,
-		group:         "Video",
 	},
 	/* --- audio --- */
 	{
@@ -422,8 +481,6 @@
 		minimum:       0,
 		maximum:       1,
 		type:          V4L2_CTRL_TYPE_BOOLEAN,
-		category:      V4L2_CTRL_CAT_AUDIO,
-		group:         "Audio",
 	},{
 		id:            V4L2_CID_AUDIO_VOLUME,
 		name:          "Volume",
@@ -432,8 +489,6 @@
 		step:          65535/100,
 		default_value: 65535,
 		type:          V4L2_CTRL_TYPE_INTEGER,
-		category:      V4L2_CTRL_CAT_AUDIO,
-		group:         "Audio",
 	},{
 		id:            V4L2_CID_AUDIO_BALANCE,
 		name:          "Balance",
@@ -442,8 +497,6 @@
 		step:          65535/100,
 		default_value: 32768,
 		type:          V4L2_CTRL_TYPE_INTEGER,
-		category:      V4L2_CTRL_CAT_AUDIO,
-		group:         "Audio",
 	},{
 		id:            V4L2_CID_AUDIO_BASS,
 		name:          "Bass",
@@ -452,8 +505,6 @@
 		step:          65535/100,
 		default_value: 32768,
 		type:          V4L2_CTRL_TYPE_INTEGER,
-		category:      V4L2_CTRL_CAT_AUDIO,
-		group:         "Audio",
 	},{
 		id:            V4L2_CID_AUDIO_TREBLE,
 		name:          "Treble",
@@ -462,8 +513,6 @@
 		step:          65535/100,
 		default_value: 32768,
 		type:          V4L2_CTRL_TYPE_INTEGER,
-		category:      V4L2_CTRL_CAT_AUDIO,
-		group:         "Audio",
 	},
 	/* --- private --- */
 	{
@@ -472,39 +521,33 @@
 		minimum:       0,
 		maximum:       1,
 		type:          V4L2_CTRL_TYPE_BOOLEAN,
-		group:         "Private",
 	},{
 		id:            V4L2_CID_PRIVATE_COMBFILTER,
 		name:          "combfilter",
 		minimum:       0,
 		maximum:       1,
 		type:          V4L2_CTRL_TYPE_BOOLEAN,
-		group:         "Private",
 	},{
 		id:            V4L2_CID_PRIVATE_AUTOMUTE,
 		name:          "automute",
 		minimum:       0,
 		maximum:       1,
 		type:          V4L2_CTRL_TYPE_BOOLEAN,
-		group:         "Private",
 	},{
 		id:            V4L2_CID_PRIVATE_LUMAFILTER,
 		name:          "luma decimation filter",
 		minimum:       0,
 		maximum:       1,
 		type:          V4L2_CTRL_TYPE_BOOLEAN,
-		group:         "Private",
 	},{
 		id:            V4L2_CID_PRIVATE_AGC_CRUSH,
 		name:          "agc crush",
 		minimum:       0,
 		maximum:       1,
 		type:          V4L2_CTRL_TYPE_BOOLEAN,
-		group:         "Private",
 	}
 };
 const int BTTV_CTLS = (sizeof(bttv_ctls)/sizeof(struct v4l2_queryctrl));
-#endif /* HAVE_V4L2 */
 
 /* ----------------------------------------------------------------------- */
 /* resource management                                                     */
@@ -558,57 +601,6 @@
 }
 
 /* ----------------------------------------------------------------------- */
-/*
- * sanity check for video framebuffer address ranges (overlay).
- * let's see if that address range actually belongs to some
- * pci display adapter.
- *
- * FIXME: stuff isn't portable.  It's also a v4l API bug, pass a
- * physical address in VIDIOCSFBUF isn't portable too ...
- */
-
-static int
-find_videomem(unsigned long from, unsigned long to)
-{
-#if PCI_DMA_BUS_IS_PHYS
-	struct pci_dev *dev = NULL;
-	int i,match,found;
-
-	found = 0;
-	dprintk(KERN_DEBUG "bttv: checking video framebuffer address"
-		" (%lx-%lx)\n",from,to);
-        pci_for_each_dev(dev) {
-		if (dev->class != PCI_CLASS_NOT_DEFINED_VGA &&
-		    dev->class >> 16 != PCI_BASE_CLASS_DISPLAY)
-			continue;
-		dprintk(KERN_DEBUG
-			"  pci display adapter %04x:%04x at %02x:%02x.%x\n",
-			dev->vendor,dev->device,dev->bus->number,
-			PCI_SLOT(dev->devfn),PCI_FUNC(dev->devfn));
-		for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
-			if (!(dev->resource[i].flags & IORESOURCE_MEM))
-				continue;
-			if (dev->resource[i].flags & IORESOURCE_READONLY)
-				continue;
-			match = (from >= dev->resource[i].start) &&
-				(to-1 <= dev->resource[i].end);
-			if (match)
-				found = 1;
-			dprintk(KERN_DEBUG "    memory at %08lx-%08lx%s\n",
-				dev->resource[i].start,
-				dev->resource[i].end,
-				match ? "  (check passed)" : "");
-		}
-	}
-	return found;
-#else
-	/* Hmm, the physical address passed to us is probably bogous */
-	dprintk(KERN_DEBUG "bttv: no overlay for this arch, sorry\n");
-	return 0;
-#endif
-}
-
-/* ----------------------------------------------------------------------- */
 /* If Bt848a or Bt849, use PLL for PAL/SECAM and crystal for NTSC          */
 
 /* Frequency = (F_input / PLL_X) * PLL_I.PLL_F/PLL_C 
@@ -688,6 +680,34 @@
         return -1;
 }
 
+/* used to switch between the bt848's analog/digital video capture modes */
+void bt848A_set_timing(struct bttv *btv)
+{
+       u8 dvsif_val = 0;
+       int table_idx = bttv_tvnorms[btv->tvnorm].sram;
+       int i;
+
+       /* timing change...reset timing generator address */
+       btwrite(0x00, BT848_TGCTRL);
+       btwrite(0x02, BT848_TGCTRL);
+       btwrite(0x00, BT848_TGCTRL);
+       
+       if (btv->digital_video  &&  -1 != table_idx) {
+               dprintk("bttv%d: load digital timing table (table_idx=%d)\n",
+		       btv->nr,table_idx);
+	       dvsif_val = 0x41;
+               for(i = 0; i < 51; i++)
+                       btwrite(SRAM_Table[table_idx][i],BT848_TGLB);
+
+	       btwrite(0x75,BT848_PLL_F_LO);
+               btwrite(0x50,BT848_PLL_F_HI);
+               btwrite(0x8B,BT848_PLL_XCI);
+               btwrite(0x11,BT848_TGCTRL);
+	       btv->pll.pll_current = 0;
+       }
+       btwrite(dvsif_val,BT848_DVSIF);
+}
+
 /* ----------------------------------------------------------------------- */
 
 static void bt848_bright(struct bttv *btv, int bright)
@@ -813,9 +833,11 @@
 	i2c_mux = mux = (btv->audio & AUDIO_MUTE) ? AUDIO_OFF : btv->audio;
 	if (btv->opt_automute && !signal && !btv->radio_user)
 		mux = AUDIO_OFF;
+#if 0
 	printk("bttv%d: amux: mode=%d audio=%d signal=%s mux=%d/%d irq=%s\n",
 	       btv->nr, mode, btv->audio, signal ? "yes" : "no",
 	       mux, i2c_mux, in_interrupt() ? "yes" : "no");
+#endif
 
 	val = bttv_tvcards[btv->type].audiomux[mux];
 	btaor(val,~bttv_tvcards[btv->type].gpiomask, BT848_GPIO_DATA);
@@ -856,9 +878,24 @@
 	      BT848_IFORM);
 	btwrite(tvnorm->vbipack, BT848_VBI_PACK_SIZE);
 	btwrite(1, BT848_VBI_PACK_DEL);
-	
-	btv->pll.pll_ofreq = tvnorm->Fsc;
-	set_pll(btv);
+
+	if (btv->digital_video) {
+		bt848A_set_timing(btv);
+	} else {
+		btv->pll.pll_ofreq = tvnorm->Fsc;
+		set_pll(btv);
+	}
+
+	switch (btv->type) {
+	case BTTV_VOODOOTV_FM:
+		bttv_tda9880_setnorm(btv,norm);
+		break;
+#if 0
+	case BTTV_OSPREY540:
+		osprey_540_set_norm(btv,norm);
+		break;
+#endif
+	}
 	return 0;
 }
 
@@ -924,7 +961,6 @@
 	set_input(btv,btv->input);
 }
 
-#ifdef HAVE_V4L2
 static int get_control(struct bttv *btv, struct v4l2_control *c)
 {
 	struct video_audio va;
@@ -935,7 +971,7 @@
 			break;
 	if (i == BTTV_CTLS)
 		return -EINVAL;
-	if (bttv_ctls[i].category == V4L2_CTRL_CAT_AUDIO) {
+	if (i >= 4 && i <= 8) {
 		memset(&va,0,sizeof(va));
 		bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
 		if (btv->audio_hook)
@@ -1002,7 +1038,7 @@
 			break;
 	if (i == BTTV_CTLS)
 		return -EINVAL;
-	if (bttv_ctls[i].category == V4L2_CTRL_CAT_AUDIO) {
+	if (i >= 4 && i <= 8) {
 		memset(&va,0,sizeof(va));
 		bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
 		if (btv->audio_hook)
@@ -1074,14 +1110,13 @@
 	default:
 		return -EINVAL;
 	}
-	if (bttv_ctls[i].category == V4L2_CTRL_CAT_AUDIO) {
+	if (i >= 4 && i <= 8) {
 		bttv_call_i2c_clients(btv, VIDIOCSAUDIO, &va);
 		if (btv->audio_hook)
 			btv->audio_hook(btv,&va,1);
 	}
 	return 0;
 }
-#endif /* HAVE_V4L2 */
 
 /* ----------------------------------------------------------------------- */
 
@@ -1098,9 +1133,9 @@
 {
 	int need_count = 0;
 
-	if (locked_btres(btv,RESOURCE_STREAMING))
+	if (locked_btres(btv,RESOURCE_VIDEO))
 		need_count++;
-	if (btv->vbi.users)
+	if (locked_btres(btv,RESOURCE_VBI))
 		need_count++;
 
 	if (need_count) {
@@ -1127,7 +1162,6 @@
 	return NULL;
 }
 
-#ifdef HAVE_V4L2
 static const struct bttv_format*
 format_by_fourcc(int fourcc)
 {
@@ -1141,7 +1175,6 @@
 	}
 	return NULL;
 }
-#endif
 
 /* ----------------------------------------------------------------------- */
 /* misc helpers                                                            */
@@ -1173,7 +1206,8 @@
 
 static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf,
  			       const struct bttv_format *fmt,
-			       int width, int height, int field)
+			       int width, int height,
+			       enum v4l2_field field)
 {
 	int redo_dma_risc = 0;
 	int rc;
@@ -1196,8 +1230,6 @@
 		buf->vb.size = (width * height * fmt->depth) >> 3;
 		if (0 != buf->vb.baddr  &&  buf->vb.bsize < buf->vb.size)
 			return -EINVAL;
-		field = bttv_buffer_field(btv, field, VBUF_FIELD_EVEN,
-					  btv->tvnorm, height);
 	}
 	
 	/* alloc + fill struct bttv_buffer (if changed) */
@@ -1252,13 +1284,14 @@
 }
 
 static int
-buffer_prepare(struct file *file, struct videobuf_buffer *vb, int field)
+buffer_prepare(struct file *file, struct videobuf_buffer *vb)
 {
 	struct bttv_buffer *buf = (struct bttv_buffer*)vb;
 	struct bttv_fh *fh = file->private_data;
 
 	return bttv_prepare_buffer(fh->btv,buf,fh->buf.fmt,
-				   fh->buf.vb.width,fh->buf.vb.height,field);
+				   fh->buf.vb.width,fh->buf.vb.height,
+				   fh->buf.vb.field);
 }
 
 static void
@@ -1280,7 +1313,7 @@
 	bttv_dma_free(fh->btv,buf);
 }
 
-static struct videobuf_queue_ops bttv_qops = {
+static struct videobuf_queue_ops bttv_video_qops = {
 	buf_setup:    buffer_setup,
 	buf_prepare:  buffer_prepare,
 	buf_queue:    buffer_queue,
@@ -1295,20 +1328,6 @@
 	"SMICROCODE", "GVBIFMT", "SVBIFMT" };
 #define V4L1_IOCTLS (sizeof(v4l1_ioctls)/sizeof(char*))
 
-static const char *v4l2_ioctls[] = {
-	"QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT",
-	"G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF",
-	"G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON",
-	"STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD",
-	"ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER",
-	"G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL",
-	"QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43",
-	"44", "45",  "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT",
-	"S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR",
-	"S_MODULATOR"
-};
-#define V4L2_IOCTLS (sizeof(v4l2_ioctls)/sizeof(char*))
-
 int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
 {
 	switch (cmd) {
@@ -1317,18 +1336,12 @@
 
 	/* ***  v4l1  *** ************************************************ */
 	case VIDIOCGFREQ:
-#ifdef HAVE_V4L2
-	case VIDIOC_G_FREQ:
-#endif
 	{
 		unsigned long *freq = arg;
 		*freq = btv->freq;
 		return 0;
 	}
 	case VIDIOCSFREQ:
-#ifdef HAVE_V4L2
-	case VIDIOC_S_FREQ:
-#endif
 	{
 		unsigned long *freq = arg;
 		down(&btv->lock);
@@ -1456,32 +1469,30 @@
 		return 0;
 	}
 
-#ifdef HAVE_V4L2
 	/* ***  v4l2  *** ************************************************ */
 	case VIDIOC_ENUMSTD:
 	{
-		struct v4l2_enumstd *e = arg;
-
+		struct v4l2_standard *e = arg;
+		
 		if (e->index < 0 || e->index >= BTTV_TVNORMS)
 			return -EINVAL;
-		v4l2_video_std_construct(&e->std, bttv_tvnorms[e->index].v4l2_id, 0);
-		e->inputs  = 0x0f;
-		e->outputs = 0x00;
+		v4l2_video_std_construct(e, bttv_tvnorms[e->index].v4l2_id,
+					 bttv_tvnorms[e->index].name);
 		return 0;
 	}
 	case VIDIOC_G_STD:
 	{
-		struct v4l2_standard *s = arg;
-		v4l2_video_std_construct(s,bttv_tvnorms[btv->tvnorm].v4l2_id,0);
+		v4l2_std_id *id = arg;
+		*id = bttv_tvnorms[btv->tvnorm].v4l2_id;
 		return 0;
 	}
 	case VIDIOC_S_STD:
 	{
-		struct v4l2_standard *s = arg;
-		int i, id = v4l2_video_std_confirm(s);
+		v4l2_std_id *id = arg;
+		int i;
 
-		for(i = 0; i < BTTV_TVNORMS; i++)
-			if (id == bttv_tvnorms[i].v4l2_id)
+		for (i = 0; i < BTTV_TVNORMS; i++)
+			if (*id & bttv_tvnorms[i].v4l2_id)
 				break;
 		if (i == BTTV_TVNORMS)
 			return -EINVAL;
@@ -1492,6 +1503,16 @@
 		up(&btv->lock);
 		return 0;
 	}
+	case VIDIOC_QUERYSTD:
+	{
+		v4l2_std_id *id = arg;
+		
+		if (btread(BT848_DSTATUS) & BT848_DSTATUS_NUML)
+			*id = V4L2_STD_625_50;
+		else
+			*id = V4L2_STD_525_60;
+		return 0;
+	}
 
 	case VIDIOC_ENUMINPUT:
 	{
@@ -1500,12 +1521,10 @@
 		if (i->index >= bttv_tvcards[btv->type].video_inputs)
 			return -EINVAL;
 		i->type = V4L2_INPUT_TYPE_CAMERA;
-		i->capability = 0;
-		i->assoc_audio = 0;
 		if (i->index == bttv_tvcards[btv->type].tuner) {
 			sprintf(i->name, "Television");
-			i->type = V4L2_INPUT_TYPE_TUNER;
-			i->capability = V4L2_INPUT_CAP_AUDIO;
+			i->type  = V4L2_INPUT_TYPE_TUNER;
+			i->tuner = 0;
 		} else if (i->index==bttv_tvcards[btv->type].svhs) {
 			sprintf(i->name, "S-Video");
 		} else {
@@ -1532,14 +1551,17 @@
 		return 0;
 	}
 	
-	case VIDIOC_G_TUNER: {
+	case VIDIOC_G_TUNER:
+	{
 		struct v4l2_tuner *t = arg;
 
+		if (-1 == bttv_tvcards[btv->type].tuner)
+			return -EINVAL;
+		if (0 != t->index)
+			return -EINVAL;
 		down(&btv->lock);
 		memset(t,0,sizeof(*t));
-		t->input = bttv_tvcards[btv->type].tuner;
 		strcpy(t->name, "Television");
-		v4l2_video_std_construct(&t->std, bttv_tvnorms[btv->tvnorm].v4l2_id, 0);
 		t->capability = V4L2_TUNER_CAP_NORM;
 		t->rangehigh = 0xffffffffUL;
 		t->rxsubchans = V4L2_TUNER_SUB_MONO;
@@ -1563,10 +1585,13 @@
 		up(&btv->lock);
 		return 0;
 	}
-	case VIDIOC_S_TUNER: {
+	case VIDIOC_S_TUNER:
+	{
 		struct v4l2_tuner *t = arg;
-		
-		if(t->input!=bttv_tvcards[btv->type].tuner)
+
+		if (-1 == bttv_tvcards[btv->type].tuner)
+			return -EINVAL;
+		if (0 != t->index)
 			return -EINVAL;
 		down(&btv->lock);
 		{
@@ -1587,7 +1612,32 @@
 		up(&btv->lock);
 		return 0;
 	}
-#endif /* HAVE_V4L2 */
+
+	case VIDIOC_G_FREQUENCY:
+	{
+		struct v4l2_frequency *f = arg;
+
+		memset(f,0,sizeof(*f));
+		f->type = V4L2_TUNER_ANALOG_TV;
+		f->frequency = btv->freq;
+		return 0;
+	}
+	case VIDIOC_S_FREQUENCY:
+	{
+		struct v4l2_frequency *f = arg;
+
+		if (unlikely(f->tuner != 0))
+			return -EINVAL;
+		if (unlikely(f->type != V4L2_TUNER_ANALOG_TV))
+			return -EINVAL;
+		down(&btv->lock);
+		btv->freq = f->frequency;
+		bttv_call_i2c_clients(btv,VIDIOCSFREQ,&btv->freq);
+		if (btv->has_matchbox && btv->radio_user)
+			tea5757_set_freq(btv,btv->freq);
+		up(&btv->lock);
+		return 0;
+	}
 
 	default:
 		return -ENOIOCTLCMD;
@@ -1596,55 +1646,88 @@
 	return 0;
 }
 
-static int setup_window(struct bttv_fh *fh, struct bttv *btv,
-			int x, int y, int width, int height,
-			struct video_clip *user_clips, int nclips)
+static int verify_window(const struct bttv_tvnorm *tvn,
+			 struct v4l2_window *win, int fixup)
 {
-	struct video_clip *clips = NULL;
-	int n,size,retval = 0;
+	enum v4l2_field field;
+	int maxw, maxh;
 	
-	if (width  < 48 ||
-	    height < 32 ||
-	    width  > bttv_tvnorms[btv->tvnorm].swidth ||
-	    height > bttv_tvnorms[btv->tvnorm].sheight ||
-	    NULL == fh->ovfmt)
+	if (win->w.width  < 48 || win->w.height < 32)
 		return -EINVAL;
-	if (nclips > 2048)
+	if (win->clipcount > 2048)
+		return -EINVAL;
+
+	field = win->field;
+	maxw  = tvn->swidth;
+	maxh  = tvn->sheight;
+
+	if (V4L2_FIELD_ANY == field) {
+		field = (win->w.height > maxh/2)
+			? V4L2_FIELD_INTERLACED
+			: V4L2_FIELD_TOP;
+	}
+	switch (field) {
+	case V4L2_FIELD_TOP:
+	case V4L2_FIELD_BOTTOM:
+		maxh = maxh / 2;
+		break;
+	case V4L2_FIELD_INTERLACED:
+		break;
+	default:
 		return -EINVAL;
+	}
+
+	if (!fixup && (win->w.width > maxw || win->w.height > maxh))
+		return -EINVAL;
+
+	if (win->w.width > maxw)
+		win->w.width = maxw;
+	if (win->w.height > maxh)
+		win->w.height = maxh;
+	win->field = field;
+	return 0;
+}
+
+static int setup_window(struct bttv_fh *fh, struct bttv *btv,
+			struct v4l2_window *win, int fixup)
+{
+	struct v4l2_clip *clips = NULL;
+	int n,size,retval = 0;
+
+	retval = verify_window(&bttv_tvnorms[btv->tvnorm],win,fixup);
+	if (0 != retval)
+		return retval;
 
 	/* copy clips  --  luckily v4l1 + v4l2 are binary
 	   compatible here ...*/
-	n = nclips;
+	n = win->clipcount;
 	size = sizeof(struct video_clip)*(n+4);
 	clips = kmalloc(size,GFP_KERNEL);
 	if (NULL == clips)
 		return -ENOMEM;
 	if (n > 0) {
-		if (copy_from_user(clips,user_clips,
-				   sizeof(struct video_clip)*nclips)) {
+		if (copy_from_user(clips,win->clips,
+				   sizeof(struct v4l2_clip)*win->clipcount)) {
 			kfree(clips);
 			return -EFAULT;
 		}
 	}
 	/* clip against screen */
 	if (NULL != btv->fbuf.base)
-		n = bttv_screen_clips(&btv->fbuf, x, y,
-				      width, height,
-				      clips, n);
-	bttv_sort_clips(clips,nclips);
+		n = bttv_screen_clips(btv->fbuf.width, btv->fbuf.width,
+				      &win->w, clips, n);
+	bttv_sort_clips(clips,n);
 	
-	down(&fh->q.lock);
+	down(&fh->cap.lock);
 	if (fh->ov.clips)
 		kfree(fh->ov.clips);
 	fh->ov.clips   = clips;
-	fh->ov.nclips  = nclips;
+	fh->ov.nclips  = n;
 	
-	fh->ov.x       = x;
-	fh->ov.y       = y;
-	fh->ov.width   = width;
-	fh->ov.height  = height;
-	btv->init.ov.width   = width;
-	btv->init.ov.height  = height;
+	fh->ov.w       = win->w;
+	fh->ov.field   = win->field;
+	btv->init.ov.w.width   = win->w.width;
+	btv->init.ov.w.height  = win->w.height;
 	
 	/* update overlay if needed */
 	retval = 0;
@@ -1655,10 +1738,205 @@
 		bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
 		retval = bttv_switch_overlay(btv,fh,new);
 	}
-	up(&fh->q.lock);
+	up(&fh->cap.lock);
 	return retval;
 }
 
+/* ----------------------------------------------------------------------- */
+
+static struct videobuf_queue* bttv_queue(struct bttv_fh *fh)
+{
+	struct videobuf_queue* q = NULL;
+	
+	switch (fh->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		q = &fh->cap;
+		break;
+	case V4L2_BUF_TYPE_VBI_CAPTURE:
+		q = &fh->vbi;
+		break;
+	default:
+		BUG();
+	}
+	return q;
+}
+
+static int bttv_resource(struct bttv_fh *fh)
+{
+	int res = 0;
+	
+	switch (fh->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		res = RESOURCE_VIDEO;
+		break;
+	case V4L2_BUF_TYPE_VBI_CAPTURE:
+		res = RESOURCE_VBI;
+		break;
+	default:
+		BUG();
+	}
+	return res;
+}
+
+static int bttv_switch_type(struct bttv_fh *fh, enum v4l2_buf_type type)
+{
+	struct videobuf_queue *q = bttv_queue(fh);
+	int res = bttv_resource(fh);
+
+	if (check_btres(fh,res))
+		return -EBUSY;
+	if (videobuf_queue_is_busy(q))
+		return -EBUSY;
+	fh->type = type;
+	return 0;
+}
+
+static int bttv_g_fmt(struct bttv_fh *fh, struct v4l2_format *f)
+{
+	switch (f->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		memset(&f->fmt.pix,0,sizeof(struct v4l2_pix_format));
+		f->fmt.pix.width        = fh->buf.vb.width;
+		f->fmt.pix.height       = fh->buf.vb.height;
+		f->fmt.pix.pixelformat  = fh->buf.fmt->fourcc;
+		f->fmt.pix.sizeimage    =
+			(fh->buf.vb.width*fh->buf.vb.height*fh->buf.fmt->depth)/8;
+		return 0;
+	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+		memset(&f->fmt.win,0,sizeof(struct v4l2_window));
+		f->fmt.win.w   = fh->ov.w;
+		return 0;
+	case V4L2_BUF_TYPE_VBI_CAPTURE:
+		bttv_vbi_fmt(fh,f);
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int bttv_try_fmt(struct bttv_fh *fh, struct bttv *btv,
+			struct v4l2_format *f)
+{
+	switch (f->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+	{
+		const struct bttv_format *fmt;
+		enum v4l2_field field;
+		int maxw,maxh;
+
+		fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+		if (NULL == fmt)
+			return -EINVAL;
+		if (0 != f->fmt.pix.bytesperline)
+			/* FIXME -- not implemented yet */
+			return -EINVAL;
+
+		/* fixup format */
+		maxw  = bttv_tvnorms[btv->tvnorm].swidth;
+		maxh  = bttv_tvnorms[btv->tvnorm].sheight;
+		field = f->fmt.pix.field;
+		if (V4L2_FIELD_ANY == field)
+			field = (f->fmt.pix.height > maxh/2)
+				? V4L2_FIELD_INTERLACED
+				: V4L2_FIELD_BOTTOM;
+		if (V4L2_FIELD_SEQ_BT == field)
+			field = V4L2_FIELD_SEQ_TB;
+		switch (field) {
+		case V4L2_FIELD_TOP:
+		case V4L2_FIELD_BOTTOM:
+			maxh = maxh/2;
+			break;
+		case V4L2_FIELD_INTERLACED:
+			break;
+		case V4L2_FIELD_SEQ_TB:
+			if (fmt->flags & FORMAT_FLAGS_PLANAR)
+				return -EINVAL;
+		default:
+			return -EINVAL;
+		}
+
+		/* update data for the application */
+		f->fmt.pix.field = field;
+		if (f->fmt.pix.width  < 48)
+			f->fmt.pix.width  = 48;
+		if (f->fmt.pix.height < 32)
+			f->fmt.pix.height = 32;
+		if (f->fmt.pix.width  > maxw)
+			f->fmt.pix.width = maxw;
+		if (f->fmt.pix.height > maxh)
+			f->fmt.pix.height = maxh;
+		f->fmt.pix.sizeimage =
+			(fh->buf.vb.width * fh->buf.vb.height * fmt->depth)/8;
+		
+		return 0;
+	}
+	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+		return verify_window(&bttv_tvnorms[btv->tvnorm],
+				     &f->fmt.win, 1);
+#if 0
+	case V4L2_BUF_TYPE_VBI_CAPTURE:
+		retval = bttv_switch_type(fh,f->type);
+		if (0 != retval)
+			return retval;
+		if (fh->vbi.reading || fh->vbi.streaming)
+			return -EBUSY;
+		bttv_vbi_setlines(fh,btv,f->fmt.vbi.count[0]);
+		bttv_vbi_fmt(fh,f);
+		return 0;
+#endif
+	default:
+		return -EINVAL;
+	}
+}
+
+static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv,
+		      struct v4l2_format *f)
+{
+	int retval;
+	
+	switch (f->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+	{
+		const struct bttv_format *fmt;
+
+		retval = bttv_switch_type(fh,f->type);
+		if (0 != retval)
+			return retval;
+		retval = bttv_try_fmt(fh,btv,f);
+		if (0 != retval)
+			return retval;
+		fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+		
+		/* update our state informations */
+		down(&fh->cap.lock);
+		fh->buf.fmt             = fmt;
+		fh->buf.vb.field        = f->fmt.pix.field;
+		fh->buf.vb.width        = f->fmt.pix.width;
+		fh->buf.vb.height       = f->fmt.pix.height;
+		btv->init.buf.fmt       = fmt;
+		btv->init.buf.vb.field  = f->fmt.pix.field;
+		btv->init.buf.vb.width  = f->fmt.pix.width;
+		btv->init.buf.vb.height = f->fmt.pix.height;
+		up(&fh->cap.lock);
+		
+		return 0;
+	}
+	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+		return setup_window(fh, btv, &f->fmt.win, 1);
+	case V4L2_BUF_TYPE_VBI_CAPTURE:
+		retval = bttv_switch_type(fh,f->type);
+		if (0 != retval)
+			return retval;
+		if (fh->vbi.reading || fh->vbi.streaming)
+			return -EBUSY;
+		bttv_vbi_setlines(fh,btv,f->fmt.vbi.count[0]);
+		bttv_vbi_fmt(fh,f);
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
 static int bttv_do_ioctl(struct inode *inode, struct file *file,
 			 unsigned int cmd, void *arg)
 {
@@ -1676,8 +1954,7 @@
 			break;
 		case 'V':
 			printk("bttv%d: ioctl 0x%x (v4l2, VIDIOC_%s)\n",
-			       btv->nr, cmd,  (_IOC_NR(cmd) < V4L2_IOCTLS) ?
-			       v4l2_ioctls[_IOC_NR(cmd)] : "???");
+			       btv->nr, cmd,  v4l2_ioctl_names[_IOC_NR(cmd)]);
 			break;
 		default:
 			printk("bttv%d: ioctl 0x%x (???)\n",
@@ -1696,17 +1973,23 @@
 
 		memset(cap,0,sizeof(*cap));
                 strcpy(cap->name,btv->video_dev.name);
-                cap->type = VID_TYPE_CAPTURE|
-			VID_TYPE_TUNER|
-			VID_TYPE_OVERLAY|
-			VID_TYPE_CLIPPING|
-                        VID_TYPE_SCALES;
-                cap->channels  = bttv_tvcards[btv->type].video_inputs;
-                cap->audios    = bttv_tvcards[btv->type].audio_inputs;
-                cap->maxwidth  = bttv_tvnorms[btv->tvnorm].swidth;
-                cap->maxheight = bttv_tvnorms[btv->tvnorm].sheight;
-                cap->minwidth  = 48;
-                cap->minheight = 32;
+		if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
+			/* vbi */
+			cap->type = VID_TYPE_TUNER|VID_TYPE_TELETEXT;
+		} else {
+			/* others */
+			cap->type = VID_TYPE_CAPTURE|
+				VID_TYPE_TUNER|
+				VID_TYPE_OVERLAY|
+				VID_TYPE_CLIPPING|
+				VID_TYPE_SCALES;
+			cap->channels  = bttv_tvcards[btv->type].video_inputs;
+			cap->audios    = bttv_tvcards[btv->type].audio_inputs;
+			cap->maxwidth  = bttv_tvnorms[btv->tvnorm].swidth;
+			cap->maxheight = bttv_tvnorms[btv->tvnorm].sheight;
+			cap->minwidth  = 48;
+			cap->minheight = 32;
+		}
                 return 0;
 	}
 
@@ -1733,7 +2016,7 @@
 		fmt = format_by_palette(pic->palette);
 		if (NULL == fmt)
 			return -EINVAL;
-		down(&fh->q.lock);
+		down(&fh->cap.lock);
 		retval = -EINVAL;
 		if (fmt->depth != pic->depth && !sloppy)
 			goto fh_unlock_and_return;
@@ -1754,7 +2037,7 @@
 		bt848_contrast(btv,pic->contrast);
 		bt848_hue(btv,pic->hue);
 		bt848_sat(btv,pic->colour);
-		up(&fh->q.lock);
+		up(&fh->cap.lock);
                 return 0;
 	}
 
@@ -1763,26 +2046,31 @@
 		struct video_window *win = arg;
 
 		memset(win,0,sizeof(*win));
-		win->x      = fh->ov.x;
-		win->y      = fh->ov.y;
-		win->width  = fh->ov.width;
-		win->height = fh->ov.height;
+		win->x      = fh->ov.w.left;
+		win->y      = fh->ov.w.top;
+		win->width  = fh->ov.w.width;
+		win->height = fh->ov.w.height;
 		return 0;
 	}
 	case VIDIOCSWIN:
 	{
 		struct video_window *win = arg;
+		struct v4l2_window w2;
 
-		retval = setup_window(fh,btv,win->x,win->y,
-				      win->width,win->height,
-				      win->clips,
-				      win->clipcount);
+		w2.field     = V4L2_FIELD_ANY;
+		w2.w.left    = win->x;
+		w2.w.top     = win->y;
+		w2.w.width   = win->width;
+		w2.w.height  = win->height;
+		w2.clipcount = win->clipcount;
+		w2.clips     = (struct v4l2_clip*)win->clips;
+		retval = setup_window(fh, btv, &w2, 0);
 		if (0 == retval) {
 			/* on v4l1 this ioctl affects the read() size too */
-			fh->buf.vb.width  = fh->ov.width;
-			fh->buf.vb.height = fh->ov.height;
-			btv->init.buf.vb.width  = fh->ov.width;
-			btv->init.buf.vb.height = fh->ov.height;
+			fh->buf.vb.width  = fh->ov.w.width;
+			fh->buf.vb.height = fh->ov.w.height;
+			btv->init.buf.vb.width  = fh->ov.w.width;
+			btv->init.buf.vb.height = fh->ov.w.height;
 		}
 		return retval;
 	}
@@ -1804,9 +2092,7 @@
                         return -EPERM;
 		end = (unsigned long)fbuf->base +
 			fbuf->height * fbuf->bytesperline;
-		if (0 == find_videomem((unsigned long)fbuf->base,end))
-			return -EINVAL;
-		down(&fh->q.lock);
+		down(&fh->cap.lock);
 		retval = -EINVAL;
 		if (sloppy) {
 			/* also set the default palette -- for backward
@@ -1846,14 +2132,12 @@
 				goto fh_unlock_and_return;
 		}
 		btv->fbuf = *fbuf;
-		up(&fh->q.lock);
+		up(&fh->cap.lock);
 		return 0;
 	}
 
 	case VIDIOCCAPTURE:
-#ifdef HAVE_V4L2
-	case VIDIOC_PREVIEW:
-#endif
+	case VIDIOC_OVERLAY:
 	{
 		struct bttv_buffer *new;
 		int *on = arg;
@@ -1862,10 +2146,10 @@
 			/* verify args */
 			if (NULL == btv->fbuf.base)
 				return -EINVAL;
-			if (fh->ov.width <48 ||
-			    fh->ov.height<32 ||
-			    fh->ov.width >bttv_tvnorms[btv->tvnorm].swidth  ||
-			    fh->ov.height>bttv_tvnorms[btv->tvnorm].sheight ||
+			if (fh->ov.w.width <48 ||
+			    fh->ov.w.height<32 ||
+			    fh->ov.w.width >bttv_tvnorms[btv->tvnorm].swidth ||
+			    fh->ov.w.height>bttv_tvnorms[btv->tvnorm].sheight||
 			    NULL == fh->ovfmt)
 				return -EINVAL;
 		}
@@ -1873,7 +2157,7 @@
 		if (!check_alloc_btres(btv,fh,RESOURCE_OVERLAY))
 			return -EBUSY;
 		
-		down(&fh->q.lock);
+		down(&fh->cap.lock);
 		if (*on) {
 			fh->ov.tvnorm = btv->tvnorm;
 			new = videobuf_alloc(sizeof(*new));
@@ -1884,7 +2168,7 @@
 
 		/* switch over */
 	        retval = bttv_switch_overlay(btv,fh,new);
-		up(&fh->q.lock);
+		up(&fh->cap.lock);
 		return retval;
 	}
 
@@ -1893,10 +2177,8 @@
 		struct video_mbuf *mbuf = arg;
 		int i;
 
-		if (!mmap)
-			return -EINVAL;
-		down(&fh->q.lock);
-		retval = videobuf_mmap_setup(file,&fh->q,gbuffers,gbufsize);
+		down(&fh->cap.lock);
+		retval = videobuf_mmap_setup(file,&fh->cap,gbuffers,gbufsize);
 		if (retval < 0)
 			goto fh_unlock_and_return;
 		memset(mbuf,0,sizeof(*mbuf));
@@ -1904,20 +2186,21 @@
 		mbuf->size   = gbuffers * gbufsize;
 		for (i = 0; i < gbuffers; i++)
 			mbuf->offsets[i] = i * gbufsize;
-		up(&fh->q.lock);
+		up(&fh->cap.lock);
 		return 0;
 	}
 	case VIDIOCMCAPTURE:
 	{
 		struct video_mmap *vm = arg;
 		struct bttv_buffer *buf;
+		enum v4l2_field field;
 
 		if (vm->frame >= VIDEO_MAX_FRAME)
 			return -EINVAL;
 
-		down(&fh->q.lock);
+		down(&fh->cap.lock);
 		retval = -EINVAL;
-		buf = (struct bttv_buffer *)fh->q.bufs[vm->frame];
+		buf = (struct bttv_buffer *)fh->cap.bufs[vm->frame];
 		if (NULL == buf)
 			goto fh_unlock_and_return;
 		if (0 == buf->vb.baddr)
@@ -1926,15 +2209,18 @@
 		    buf->vb.state == STATE_ACTIVE)
 			goto fh_unlock_and_return;
 		
+		field = (vm->height > bttv_tvnorms[btv->tvnorm].sheight/2)
+			? V4L2_FIELD_INTERLACED
+			: V4L2_FIELD_BOTTOM;
 		retval = bttv_prepare_buffer(btv,buf,
 					     format_by_palette(vm->format),
-					     vm->width,vm->height,0);
+					     vm->width,vm->height,field);
 		if (0 != retval)
 			goto fh_unlock_and_return;
 		spin_lock_irqsave(&btv->s_lock,flags);
 		buffer_queue(file,&buf->vb);
 		spin_unlock_irqrestore(&btv->s_lock,flags);
-		up(&fh->q.lock);
+		up(&fh->cap.lock);
 		return 0;
 	}
 	case VIDIOCSYNC:
@@ -1945,9 +2231,9 @@
 		if (*frame >= VIDEO_MAX_FRAME)
 			return -EINVAL;
 
-		down(&fh->q.lock);
+		down(&fh->cap.lock);
 		retval = -EINVAL;
-		buf = (struct bttv_buffer *)fh->q.bufs[*frame];
+		buf = (struct bttv_buffer *)fh->cap.bufs[*frame];
 		if (NULL == buf)
 			goto fh_unlock_and_return;
 		retval = videobuf_waiton(&buf->vb,0,1);
@@ -1965,7 +2251,7 @@
 			retval = -EINVAL;
 			break;
 		}
-		up(&fh->q.lock);
+		up(&fh->cap.lock);
 		return retval;
 	}
 
@@ -1980,8 +2266,11 @@
 	case VIDIOCSAUDIO:
 		return bttv_common_ioctls(btv,cmd,arg);
 
+	/* vbi/teletext ioctls */
+	case BTTV_VBISIZE:
+		bttv_switch_type(fh,V4L2_BUF_TYPE_VBI_CAPTURE);
+		return fh->lines * 2 * 2048;
 
-#ifdef HAVE_V4L2
 	/* ***  v4l2  *** ************************************************ */
 	case VIDIOC_QUERYCAP:
 	{
@@ -1989,25 +2278,21 @@
 
 		if (0 == v4l2)
 			return -EINVAL;
-                strcpy(cap->name,btv->video_dev.name);
-		cap->type = V4L2_TYPE_CAPTURE;
-		cap->flags = V4L2_FLAG_TUNER | V4L2_FLAG_PREVIEW
-			| V4L2_FLAG_READ | V4L2_FLAG_SELECT;
-		if (mmap)
-			cap->flags |= V4L2_FLAG_STREAMING;
-		cap->inputs = bttv_tvcards[btv->type].video_inputs;
-		cap->outputs = 0;
-		cap->audios = bttv_tvcards[btv->type].audio_inputs;
-		cap->maxwidth = bttv_tvnorms[btv->tvnorm].swidth;
-		cap->maxheight = bttv_tvnorms[btv->tvnorm].sheight;
-		cap->minwidth = 48;
-		cap->minheight = 32;
-		cap->maxframerate = 30;
+                strcpy(cap->driver,"bttv");
+                strncpy(cap->card,btv->video_dev.name,sizeof(cap->card));
+		sprintf(cap->bus_info,"PCI:%s",btv->dev->slot_name);
+		cap->version = BTTV_VERSION_CODE;
+		cap->capabilities =
+			V4L2_CAP_VIDEO_CAPTURE |
+			V4L2_CAP_VIDEO_OVERLAY |
+			V4L2_CAP_VBI_CAPTURE |
+			V4L2_CAP_TUNER |
+			V4L2_CAP_READWRITE | 
+			V4L2_CAP_STREAMING;
 		return 0;
 	}
 
-	case VIDIOC_ENUM_PIXFMT:
-	case VIDIOC_ENUM_FBUFFMT:
+	case VIDIOC_ENUM_FMT:
 	{
 		struct v4l2_fmtdesc *f = arg;
 		int i, index;
@@ -2021,81 +2306,38 @@
 		}
 		if (BTTV_FORMATS == i)
 			return -EINVAL;
-		if (cmd == VIDIOC_ENUM_FBUFFMT &&
-		    0 == (bttv_formats[i].flags & FORMAT_FLAGS_PACKED))
+
+		switch (f->type) {
+		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+			break;
+		case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+			if (!(bttv_formats[i].flags & FORMAT_FLAGS_PACKED))
+				return -EINVAL;
+			break;
+		default:
 			return -EINVAL;
+		}
 		memset(f,0,sizeof(*f));
 		f->index = index;
 		strncpy(f->description,bttv_formats[i].name,31);
 		f->pixelformat = bttv_formats[i].fourcc;
-		f->depth = bttv_formats[i].depth;
 		return 0;
 	}
 
+	case VIDIOC_TRY_FMT:
+	{
+		struct v4l2_format *f = arg;
+		return bttv_try_fmt(fh,btv,f);
+	}
 	case VIDIOC_G_FMT:
 	{
 		struct v4l2_format *f = arg;
-
-		memset(f,0,sizeof(*f));
-		f->type = V4L2_BUF_TYPE_CAPTURE;
-		f->fmt.pix.width        = fh->buf.vb.width;
-		f->fmt.pix.height       = fh->buf.vb.height;
-		f->fmt.pix.depth        = fh->buf.fmt->depth;
-		f->fmt.pix.pixelformat  = fh->buf.fmt->fourcc;
-		f->fmt.pix.sizeimage    =
-			(fh->buf.vb.width*fh->buf.vb.height*fh->buf.fmt->depth)/8;
-		return 0;
+		return bttv_g_fmt(fh,f);
 	}
 	case VIDIOC_S_FMT:
 	{
 		struct v4l2_format *f = arg;
-		const struct bttv_format *fmt;
-
-		if ((f->type & V4L2_BUF_TYPE_field) != V4L2_BUF_TYPE_CAPTURE)
-			return -EINVAL;
-		fmt = format_by_fourcc(f->fmt.pix.pixelformat);
-		if (NULL == fmt)
-			return -EINVAL;
-		if (f->fmt.pix.width  < 48 ||
-		    f->fmt.pix.height < 32)
-			return -EINVAL;
-		if (f->fmt.pix.flags & V4L2_FMT_FLAG_BYTESPERLINE)
-			/* FIXME -- not implemented yet */
-			return -EINVAL;
-
-		down(&fh->q.lock);
-		/* fixup format */
-		if (f->fmt.pix.width  > bttv_tvnorms[btv->tvnorm].swidth)
-			f->fmt.pix.width = bttv_tvnorms[btv->tvnorm].swidth;
-		if (f->fmt.pix.height > bttv_tvnorms[btv->tvnorm].sheight)
-			f->fmt.pix.height = bttv_tvnorms[btv->tvnorm].sheight;
-		if (!(f->fmt.pix.flags & V4L2_FMT_FLAG_INTERLACED) &&
-		    f->fmt.pix.height>bttv_tvnorms[btv->tvnorm].sheight/2)
-			f->fmt.pix.height=bttv_tvnorms[btv->tvnorm].sheight/2;
-
-		if (f->fmt.pix.height > bttv_tvnorms[btv->tvnorm].sheight/2) {
-			/* must interlace -- no field splitting available */
-			f->fmt.pix.flags &= ~(V4L2_FMT_FLAG_TOPFIELD|
-					      V4L2_FMT_FLAG_BOTFIELD);
-		} else {
-			/* one field is enouth -- no interlace needed */
-			f->fmt.pix.flags &= ~V4L2_FMT_FLAG_INTERLACED;
-		}
-		
-		/* update our state informations */
-		fh->buf.fmt             = fmt;
-		fh->buf.vb.width        = f->fmt.pix.width;
-		fh->buf.vb.height       = f->fmt.pix.height;
-		btv->init.buf.fmt       = fmt;
-		btv->init.buf.vb.width  = f->fmt.pix.width;
-		btv->init.buf.vb.height = f->fmt.pix.height;
-
-		/* update data for the application */
-		f->fmt.pix.depth = fmt->depth;
-		f->fmt.pix.sizeimage =
-			(fh->buf.vb.width * fh->buf.vb.height * fmt->depth)/8;
-		up(&fh->q.lock);
-		return 0;
+		return bttv_s_fmt(fh,btv,f);
 	}
 
 	case VIDIOC_G_FBUF:
@@ -2103,16 +2345,13 @@
 		struct v4l2_framebuffer *fb = arg;
 
 		memset(fb,0,sizeof(*fb));
-		fb->base[0]    = btv->fbuf.base;
+		fb->base       = btv->fbuf.base;
 		fb->fmt.width  = btv->fbuf.width;
 		fb->fmt.height = btv->fbuf.height;
 		fb->fmt.bytesperline = btv->fbuf.bytesperline;
-		fb->fmt.flags  = V4L2_FMT_FLAG_BYTESPERLINE;
-		fb->capability = V4L2_FBUF_CAP_CLIPPING;
-		if (fh->ovfmt) {
-			fb->fmt.depth  = fh->ovfmt->depth;
+		fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
+		if (fh->ovfmt)
 			fb->fmt.pixelformat  = fh->ovfmt->fourcc;
-		}
 		return 0;
 	}
 	case VIDIOC_S_FBUF:
@@ -2126,18 +2365,16 @@
 			return -EPERM;
 
 		/* check args */
-		end = (unsigned long)fb->base[0] +
+		end = (unsigned long)fb->base +
 			fb->fmt.height * fb->fmt.bytesperline;
-		if (0 == find_videomem((unsigned long)fb->base[0],end))
-			return -EINVAL;
-
+		
 		fmt = format_by_fourcc(fb->fmt.pixelformat);
 		if (NULL == fmt)
 			return -EINVAL;
 		if (0 == (fmt->flags & FORMAT_FLAGS_PACKED))
 			return -EINVAL;
 
-		down(&fh->q.lock);
+		down(&fh->cap.lock);
 		retval = -EINVAL;
 		if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) {
 			if (fb->fmt.width > bttv_tvnorms[btv->tvnorm].swidth)
@@ -2147,11 +2384,11 @@
 		}
 
 		/* ok, accept it */
-		btv->fbuf.base   = fb->base[0];
+		btv->fbuf.base   = fb->base;
 		btv->fbuf.width  = fb->fmt.width;
 		btv->fbuf.height = fb->fmt.height;
 		btv->fbuf.depth  = fmt->depth;
-		if (fb->fmt.flags & V4L2_FMT_FLAG_BYTESPERLINE)
+		if (0 != fb->fmt.bytesperline)
 			btv->fbuf.bytesperline = fb->fmt.bytesperline;
 		else
 			btv->fbuf.bytesperline = btv->fbuf.width*fmt->depth/8;
@@ -2160,12 +2397,12 @@
 		fh->ovfmt = fmt;
 		btv->init.ovfmt = fmt;
 		if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) {
-			fh->ov.x      = 0;
-			fh->ov.y      = 0;
-			fh->ov.width  = fb->fmt.width;
-			fh->ov.height = fb->fmt.height;
-			btv->init.ov.width  = fb->fmt.width;
-			btv->init.ov.height = fb->fmt.height;
+			fh->ov.w.left   = 0;
+			fh->ov.w.top    = 0;
+			fh->ov.w.width  = fb->fmt.width;
+			fh->ov.w.height = fb->fmt.height;
+			btv->init.ov.w.width  = fb->fmt.width;
+			btv->init.ov.w.height = fb->fmt.height;
 			if (fh->ov.clips)
 				kfree(fh->ov.clips);
 			fh->ov.clips = NULL;
@@ -2179,64 +2416,48 @@
 				retval = bttv_switch_overlay(btv,fh,new);
 			}
 		}
-		up(&fh->q.lock);
+		up(&fh->cap.lock);
 		return retval;
 	}
-	case VIDIOC_G_WIN:
-	{
-		struct v4l2_window *win = arg;
-
-		memset(win,0,sizeof(*win));
-		win->x      = fh->ov.x;
-		win->y      = fh->ov.y;
-		win->width  = fh->ov.width;
-		win->height = fh->ov.height;
-		return 0;
-	}
-	case VIDIOC_S_WIN:
-	{
-		struct v4l2_window *win = arg;
-
-		return setup_window(fh,btv,win->x,win->y,
-				    win->width,win->height,
-				    (struct video_clip*)win->clips,
-				    win->clipcount);
-	}
 
 	case VIDIOC_REQBUFS:
-		if (!mmap)
-			return -EINVAL;
-		return videobuf_reqbufs(file,&fh->q,arg);
+		return videobuf_reqbufs(file,bttv_queue(fh),arg);
 
 	case VIDIOC_QUERYBUF:
-		return videobuf_querybuf(&fh->q,arg);
+		return videobuf_querybuf(bttv_queue(fh),arg);
 
 	case VIDIOC_QBUF:
-		return videobuf_qbuf(file,&fh->q,arg);
+		return videobuf_qbuf(file,bttv_queue(fh),arg);
 
 	case VIDIOC_DQBUF:
-		return videobuf_dqbuf(file,&fh->q,arg);
+		return videobuf_dqbuf(file,bttv_queue(fh),arg);
 
 	case VIDIOC_STREAMON:
-		if (!check_alloc_btres(btv,fh,RESOURCE_STREAMING))
+	{
+		int res = bttv_resource(fh);
+
+		if (!check_alloc_btres(btv,fh,res))
 			return -EBUSY;
 		bttv_field_count(btv);
-		return videobuf_streamon(file,&fh->q);
-
+		return videobuf_streamon(file,bttv_queue(fh));
+	}
 	case VIDIOC_STREAMOFF:
-		retval = videobuf_streamoff(file,&fh->q);
+	{
+		int res = bttv_resource(fh);
+
+		retval = videobuf_streamoff(file,bttv_queue(fh));
 		if (retval < 0)
 			return retval;
-		free_btres(btv,fh,RESOURCE_STREAMING);
+		free_btres(btv,fh,res);
 		bttv_field_count(btv);
 		return 0;
+	}
 
 	case VIDIOC_QUERYCTRL:
 	{
 		struct v4l2_queryctrl *c = arg;
 		int i;
 
-		v4l2_fill_ctrl_category(c);
 		if ((c->id <  V4L2_CID_BASE ||
 		     c->id >= V4L2_CID_LASTP1) &&
 		    (c->id <  V4L2_CID_PRIVATE_BASE ||
@@ -2250,7 +2471,7 @@
 			return 0;
 		}
 		*c = bttv_ctls[i];
-		if (bttv_ctls[i].category == V4L2_CTRL_CAT_AUDIO) {
+		if (i >= 4 && i <= 8) {
 			struct video_audio va;
 			memset(&va,0,sizeof(va));
 			bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
@@ -2285,11 +2506,12 @@
 	{
 		struct v4l2_streamparm *parm = arg;
 		struct v4l2_standard s;
-		if (parm->type != V4L2_BUF_TYPE_CAPTURE)
+		if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 			return -EINVAL;
 		memset(parm,0,sizeof(*parm));
-		v4l2_video_std_construct(&s, bttv_tvnorms[btv->tvnorm].v4l2_id, 0);
-		parm->parm.capture.timeperframe = v4l2_video_std_tpf(&s);
+		v4l2_video_std_construct(&s, bttv_tvnorms[btv->tvnorm].v4l2_id,
+					 bttv_tvnorms[btv->tvnorm].name);
+		parm->parm.capture.timeperframe = s.frameperiod;
 		return 0;
 	}
 	
@@ -2301,10 +2523,9 @@
 	case VIDIOC_S_INPUT:
 	case VIDIOC_G_TUNER:
 	case VIDIOC_S_TUNER:
-	case VIDIOC_G_FREQ:
-	case VIDIOC_S_FREQ:
+	case VIDIOC_G_FREQUENCY:
+	case VIDIOC_S_FREQUENCY:
 		return bttv_common_ioctls(btv,cmd,arg);
-#endif /* HAVE_V4L2 */
 
 	default:
 		return -ENOIOCTLCMD;
@@ -2312,7 +2533,7 @@
 	return 0;
 
  fh_unlock_and_return:
-	up(&fh->q.lock);
+	up(&fh->cap.lock);
 	return retval;
 }
 
@@ -2322,55 +2543,30 @@
 	return video_usercopy(inode, file, cmd, arg, bttv_do_ioctl);
 }
 
-#if 0
-/*
- * blocking read for a complete video frame
- * => no kernel bounce buffer needed.
- */
-static ssize_t
-bttv_read_zerocopy(struct bttv_fh *fh, struct bttv *btv,
-		   char *data,size_t count, loff_t *ppos)
-{
-        int rc;
-
-        /* setup stuff */
-	dprintk("bttv%d: read zerocopy\n",btv->nr);
-        fh->q.read_buf->baddr = (unsigned long)data;
-        fh->q.read_buf->bsize = count;
-        rc = bttv_prepare_buffer(btv,fh->q.read_buf,fh->buf.fmt,
-				 fh->buf.vb.width,fh->buf.vb.height,0);
-        if (0 != rc)
-		goto done;
-	
-        /* start capture & wait */
-        bttv_queue_buffer(btv,fh->q.read_buf);
-        rc = videobuf_waiton(fh->q.read_buf,0,1);
-        if (0 == rc) {
-		videobuf_dma_pci_sync(btv->dev,&fh->q.read_buf->dma);
-                rc = fh->q.read_buf->size;
-	}
-
- done:
-	/* cleanup */
-	bttv_dma_free(btv,fh->q.read_buf);
-	fh->q.read_buf->baddr = 0;
-	fh->q.read_buf->size = 0;
-	return rc;
-}
-#endif
-
-
 static ssize_t bttv_read(struct file *file, char *data,
 			 size_t count, loff_t *ppos)
 {
 	struct bttv_fh *fh = file->private_data;
+	int retval = 0;
 
 	if (fh->btv->errors)
 		bttv_reinit_bt848(fh->btv);
-	if (locked_btres(fh->btv,RESOURCE_STREAMING))
-		return -EBUSY;
+	dprintk("read count=%d type=%s\n",
+		(int)count,v4l2_type_names[fh->type]);
 
-	return videobuf_read_one(file, &fh->q, data, count, ppos);
+	switch (fh->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		if (locked_btres(fh->btv,RESOURCE_VIDEO))
+			return -EBUSY;
+		retval = videobuf_read_one(file, &fh->cap, data, count, ppos);
+		break;
+	case V4L2_BUF_TYPE_VBI_CAPTURE:
+		retval = videobuf_read_stream(file, &fh->vbi, data, count, ppos, 1);
+		break;
+	default:
+		BUG();
+	}
+	return retval;
 }
 
 static unsigned int bttv_poll(struct file *file, poll_table *wait)
@@ -2378,34 +2574,37 @@
 	struct bttv_fh *fh = file->private_data;
 	struct bttv_buffer *buf;
 
-	if (check_btres(fh,RESOURCE_STREAMING)) {
+	if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)
+		return videobuf_poll_stream(file, &fh->vbi, wait);
+
+	if (check_btres(fh,RESOURCE_VIDEO)) {
 		/* streaming capture */
-		if (list_empty(&fh->q.stream))
+		if (list_empty(&fh->cap.stream))
 			return POLLERR;
-		buf = list_entry(fh->q.stream.next,struct bttv_buffer,vb.stream);
+		buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream);
 	} else {
 		/* read() capture */
-		down(&fh->q.lock);
-		if (NULL == fh->q.read_buf) {
+		down(&fh->cap.lock);
+		if (NULL == fh->cap.read_buf) {
 			/* need to capture a new frame */
-			if (locked_btres(fh->btv,RESOURCE_STREAMING)) {
-				up(&fh->q.lock);
+			if (locked_btres(fh->btv,RESOURCE_VIDEO)) {
+				up(&fh->cap.lock);
 				return POLLERR;
 			}
-			fh->q.read_buf = videobuf_alloc(fh->q.msize);
-			if (NULL == fh->q.read_buf) {
-				up(&fh->q.lock);
+			fh->cap.read_buf = videobuf_alloc(fh->cap.msize);
+			if (NULL == fh->cap.read_buf) {
+				up(&fh->cap.lock);
 				return POLLERR;
 			}
-			if (0 != fh->q.ops->buf_prepare(file,fh->q.read_buf,0)) {
-				up(&fh->q.lock);
+			if (0 != fh->cap.ops->buf_prepare(file,fh->cap.read_buf)) {
+				up(&fh->cap.lock);
 				return POLLERR;
 			}
-			fh->q.ops->buf_queue(file,fh->q.read_buf);
-			fh->q.read_off = 0;
+			fh->cap.ops->buf_queue(file,fh->cap.read_buf);
+			fh->cap.read_off = 0;
 		}
-		up(&fh->q.lock);
-		buf = (struct bttv_buffer*)fh->q.read_buf;
+		up(&fh->cap.lock);
+		buf = (struct bttv_buffer*)fh->cap.read_buf;
 	}
 	
 	poll_wait(file, &buf->vb.done, wait);
@@ -2420,6 +2619,7 @@
 	unsigned int minor = minor(inode->i_rdev);
 	struct bttv *btv = NULL;
 	struct bttv_fh *fh;
+	enum v4l2_buf_type type = 0;
 	int i;
 
 	dprintk(KERN_DEBUG "bttv: open minor=%d\n",minor);
@@ -2427,13 +2627,20 @@
 	for (i = 0; i < bttv_num; i++) {
 		if (bttvs[i].video_dev.minor == minor) {
 			btv = &bttvs[i];
+			type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+			break;
+		}
+		if (bttvs[i].vbi_dev.minor == minor) {
+			btv = &bttvs[i];
+			type = V4L2_BUF_TYPE_VBI_CAPTURE;
 			break;
 		}
 	}
 	if (NULL == btv)
 		return -ENODEV;
 
-	dprintk(KERN_DEBUG "bttv%d: open called (video)\n",btv->nr);
+	dprintk(KERN_DEBUG "bttv%d: open called (type=%s)\n",
+		btv->nr,v4l2_type_names[type]);
 
 	/* allocate per filehandle data */
 	fh = kmalloc(sizeof(*fh),GFP_KERNEL);
@@ -2441,8 +2648,15 @@
 		return -ENOMEM;
 	file->private_data = fh;
 	*fh = btv->init;
-	videobuf_queue_init(&fh->q, &bttv_qops, btv->dev, &btv->s_lock,
-			    V4L2_BUF_TYPE_CAPTURE,sizeof(struct bttv_buffer));
+	fh->type = type;
+	videobuf_queue_init(&fh->cap, &bttv_video_qops,
+			    btv->dev, &btv->s_lock,
+			    V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			    sizeof(struct bttv_buffer));
+	videobuf_queue_init(&fh->vbi, &bttv_vbi_qops,
+			    btv->dev, &btv->s_lock,
+			    V4L2_BUF_TYPE_VBI_CAPTURE,
+			    sizeof(struct bttv_buffer));
 	
 	i2c_vidiocschan(btv);
         return 0;
@@ -2456,16 +2670,24 @@
 	/* turn off overlay, stop outstanding captures */
 	if (check_btres(fh, RESOURCE_OVERLAY))
 		bttv_switch_overlay(btv,fh,NULL);
-	if (check_btres(fh, RESOURCE_STREAMING)) {
-		videobuf_streamoff(file,&fh->q);
-		free_btres(btv,fh,RESOURCE_STREAMING);
+	
+	/* stop video capture */
+	if (check_btres(fh, RESOURCE_VIDEO)) {
+		videobuf_streamoff(file,&fh->cap);
+		free_btres(btv,fh,RESOURCE_VIDEO);
 		bttv_field_count(btv);
 	}
-	if (fh->q.read_buf) {
-		buffer_release(file,fh->q.read_buf);
-		kfree(fh->q.read_buf);
+	if (fh->cap.read_buf) {
+		buffer_release(file,fh->cap.read_buf);
+		kfree(fh->cap.read_buf);
 	}
 
+	/* stop vbi capture */
+	if (fh->vbi.streaming)
+		videobuf_streamoff(file,&fh->vbi);
+	if (fh->vbi.reading)
+		videobuf_read_stop(file,&fh->vbi);
+
 	file->private_data = NULL;
 	kfree(fh);
 	return 0;
@@ -2476,11 +2698,10 @@
 {
 	struct bttv_fh *fh = file->private_data;
 
-	if (!mmap)
-		return -EINVAL;
-	dprintk("mmap 0x%lx+%ld\n",vma->vm_start,
-		vma->vm_end - vma->vm_start);
-	return videobuf_mmap_mapper(vma,&fh->q);
+	dprintk("bttv%d: mmap type=%s 0x%lx+%ld\n",
+		fh->btv->nr, v4l2_type_names[fh->type],
+		vma->vm_start, vma->vm_end - vma->vm_start);
+	return videobuf_mmap_mapper(vma,bttv_queue(fh));
 }
 
 static struct file_operations bttv_fops =
@@ -2495,7 +2716,7 @@
 	poll:     bttv_poll,
 };
 
-static struct video_device bttv_template =
+static struct video_device bttv_video_template =
 {
 	name:     "UNSET",
 	type:     VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|
@@ -2505,6 +2726,15 @@
 	minor:    -1,
 };
 
+struct video_device bttv_vbi_template =
+{
+	name:     "bt848/878 vbi",
+	type:     VID_TYPE_TUNER|VID_TYPE_TELETEXT,
+	hardware: VID_HARDWARE_BT848,
+	fops:     &bttv_fops,
+	minor:    -1,
+};
+
 /* ----------------------------------------------------------------------- */
 /* radio interface                                                         */
 
@@ -2653,20 +2883,20 @@
 	printk("  main: %08Lx\n",
 	       (u64)btv->main.dma);
 	printk("  vbi : o=%08Lx e=%08Lx\n",
-	       btv->vcurr ? (u64)btv->vcurr->odd.dma : 0,
-	       btv->vcurr ? (u64)btv->vcurr->even.dma : 0);
+	       btv->vcurr ? (u64)btv->vcurr->top.dma : 0,
+	       btv->vcurr ? (u64)btv->vcurr->bottom.dma : 0);
 	printk("  cap : o=%08Lx e=%08Lx\n",
-	       btv->odd ? (u64)btv->odd->odd.dma : 0,
-	       btv->even ? (u64)btv->even->even.dma : 0);
+	       btv->top    ? (u64)btv->top->top.dma : 0,
+	       btv->bottom ? (u64)btv->bottom->bottom.dma : 0);
 	printk("  scr : o=%08Lx e=%08Lx\n",
-	       btv->screen ? (u64)btv->screen->odd.dma  : 0,
-	       btv->screen ? (u64)btv->screen->even.dma : 0);
+	       btv->screen ? (u64)btv->screen->top.dma  : 0,
+	       btv->screen ? (u64)btv->screen->bottom.dma : 0);
 }
 
 static void bttv_irq_timeout(unsigned long data)
 {
 	struct bttv *btv = (struct bttv *)data;
-	struct bttv_buffer *o_even,*o_odd,*o_vcurr;
+	struct bttv_buffer *o_bottom,*o_top,*o_vcurr;
 	struct bttv_buffer *capture;
 
 	if (bttv_verbose) {
@@ -2677,12 +2907,12 @@
 	}
 
 	spin_lock(&btv->s_lock);
-	o_odd   = btv->odd;
-	o_even  = btv->even;
-	o_vcurr = btv->vcurr;
-	btv->odd   = NULL;
-	btv->even  = NULL;
-	btv->vcurr = NULL;
+	o_top    = btv->top;
+	o_bottom = btv->bottom;
+	o_vcurr  = btv->vcurr;
+	btv->top    = NULL;
+	btv->bottom = NULL;
+	btv->vcurr  = NULL;
 	
 	/* deactivate stuff */
 	bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
@@ -2692,19 +2922,19 @@
 	bttv_set_dma(btv, 0, 0);
 
 	/* wake up + free */
-	if (o_odd == o_even) {
-		if (NULL != o_odd) {
-			o_odd->vb.state = STATE_ERROR;
-			wake_up(&o_odd->vb.done);
+	if (o_top == o_bottom) {
+		if (NULL != o_top) {
+			o_top->vb.state = STATE_ERROR;
+			wake_up(&o_top->vb.done);
 		}
 	} else {
-		if (NULL != o_odd) {
-			o_odd->vb.state = STATE_ERROR;
-			wake_up(&o_odd->vb.done);
-		}
-		if (NULL != o_even) {
-			o_even->vb.state = STATE_ERROR;
-			wake_up(&o_even->vb.done);
+		if (NULL != o_top) {
+			o_top->vb.state = STATE_ERROR;
+			wake_up(&o_top->vb.done);
+		}
+		if (NULL != o_bottom) {
+			o_bottom->vb.state = STATE_ERROR;
+			wake_up(&o_bottom->vb.done);
 		}
 	}
 	if (NULL != o_vcurr) {
@@ -2733,20 +2963,18 @@
 static void
 bttv_irq_switch_fields(struct bttv *btv)
 {
-	struct bttv_buffer *o_even,*o_odd,*o_vcurr;
+	struct bttv_buffer *o_bottom,*o_top,*o_vcurr;
 	struct bttv_buffer *capture;
 	int irqflags = 0;
-#ifdef HAVE_V4L2
-	stamp_t ts;
-#endif
+	struct timeval ts;
 
 	spin_lock(&btv->s_lock);
-	o_odd   = btv->odd;
-	o_even  = btv->even;
-	o_vcurr = btv->vcurr;
-	btv->odd   = NULL;
-	btv->even  = NULL;
-	btv->vcurr = NULL;
+	o_top    = btv->top;
+	o_bottom = btv->bottom;
+	o_vcurr  = btv->vcurr;
+	btv->top    = NULL;
+	btv->bottom = NULL;
+	btv->vcurr  = NULL;
 
 	/* vbi request ? */
 	if (!list_empty(&btv->vcapture)) {
@@ -2760,24 +2988,24 @@
 		irqflags = 1;
 		capture = list_entry(btv->capture.next, struct bttv_buffer, vb.queue);
 		list_del(&capture->vb.queue);
-		if (capture->vb.field & VBUF_FIELD_ODD)
-			btv->odd = capture;
-		if (capture->vb.field & VBUF_FIELD_EVEN)
-			btv->even = capture;
+		if (V4L2_FIELD_HAS_TOP(capture->vb.field))
+			btv->top = capture;
+		if (V4L2_FIELD_HAS_BOTTOM(capture->vb.field))
+			btv->bottom = capture;
 
 		/* capture request for other field ? */
-		if (!(capture->vb.field & VBUF_FIELD_INTER) &&
+		if (!V4L2_FIELD_HAS_BOTH(capture->vb.field) &&
 		    !list_empty(&btv->capture)) {
 			capture = list_entry(btv->capture.next, struct bttv_buffer, vb.queue);
-			if (!(capture->vb.field & VBUF_FIELD_INTER)) {
-				if (NULL == btv->odd &&
-				    capture->vb.field & VBUF_FIELD_ODD) {
-					btv->odd = capture;
+			if (!V4L2_FIELD_HAS_BOTH(capture->vb.field)) {
+				if (NULL == btv->top &&
+				     V4L2_FIELD_TOP == capture->vb.field) {
+					btv->top = capture;
 					list_del(&capture->vb.queue);
 				}
-				if (NULL == btv->even &&
-				    capture->vb.field & VBUF_FIELD_EVEN) {
-					btv->even = capture;
+				if (NULL == btv->bottom &&
+				    V4L2_FIELD_BOTTOM == capture->vb.field) {
+					btv->bottom = capture;
 					list_del(&capture->vb.queue);
 				}
 			}
@@ -2786,34 +3014,34 @@
 
 	/* screen overlay ? */
 	if (NULL != btv->screen) {
-		if (btv->screen->vb.field & VBUF_FIELD_INTER) {
-			if (NULL == btv->odd && NULL == btv->even) {
-				btv->odd  = btv->screen;
-				btv->even = btv->screen;
+		if (V4L2_FIELD_HAS_BOTH(btv->screen->vb.field)) {
+			if (NULL == btv->top && NULL == btv->bottom) {
+				btv->top  = btv->screen;
+				btv->bottom = btv->screen;
 			}
 		} else {
-			if ((btv->screen->vb.field & VBUF_FIELD_ODD) &&
-			    NULL == btv->odd) {
-				btv->odd = btv->screen;
+			if (V4L2_FIELD_TOP == btv->screen->vb.field &&
+			    NULL == btv->top) {
+				btv->top = btv->screen;
 			}
-			if ((btv->screen->vb.field & VBUF_FIELD_EVEN) &&
-			    NULL == btv->even) {
-				btv->even = btv->screen;
+			if (V4L2_FIELD_BOTTOM == btv->screen->vb.field &&
+			    NULL == btv->bottom) {
+				btv->bottom = btv->screen;
 			}
 		}
 	}
 
 	if (irq_debug)
 		printk(KERN_DEBUG
-		       "bttv: irq odd=%p even=%p screen=%p vbi=%p\n",
-		       btv->odd,btv->even,btv->screen,btv->vcurr);
+		       "bttv: irq top=%p bottom=%p screen=%p vbi=%p\n",
+		       btv->top,btv->bottom,btv->screen,btv->vcurr);
 	
 	/* activate new fields */
-	bttv_buffer_activate(btv,btv->odd,btv->even);
+	bttv_buffer_activate(btv,btv->top,btv->bottom);
 	if (btv->vcurr) {
 		btv->vcurr->vb.state = STATE_ACTIVE;
-		bttv_risc_hook(btv, RISC_SLOT_O_VBI, &btv->vcurr->odd, 0);
-		bttv_risc_hook(btv, RISC_SLOT_E_VBI, &btv->vcurr->even, 0);
+		bttv_risc_hook(btv, RISC_SLOT_O_VBI, &btv->vcurr->top, 0);
+		bttv_risc_hook(btv, RISC_SLOT_E_VBI, &btv->vcurr->bottom, 0);
 	} else {
 		bttv_risc_hook(btv, RISC_SLOT_O_VBI, NULL, 0);
 		bttv_risc_hook(btv, RISC_SLOT_E_VBI, NULL, 0);
@@ -2821,40 +3049,30 @@
 	bttv_set_dma(btv, 0, irqflags);
 	
 	/* wake up + free */
-#ifdef HAVE_V4L2
-	v4l2_masterclock_gettime(&ts);
-#endif
-	if (o_odd == o_even) {
-		if (NULL != o_odd && btv->odd != o_odd) {
-#ifdef HAVE_V4L2
-			o_odd->vb.ts = ts;
-#endif
-			o_odd->vb.field_count = btv->field_count;
-			o_odd->vb.state = STATE_DONE;
-			wake_up(&o_odd->vb.done);
+	do_gettimeofday(&ts);
+	if (o_top == o_bottom) {
+		if (NULL != o_top && btv->top != o_top) {
+			o_top->vb.ts = ts;
+			o_top->vb.field_count = btv->field_count;
+			o_top->vb.state = STATE_DONE;
+			wake_up(&o_top->vb.done);
 		}
 	} else {
-		if (NULL != o_odd && btv->odd != o_odd) {
-#ifdef HAVE_V4L2
-			o_odd->vb.ts = ts;
-#endif
-			o_odd->vb.field_count = btv->field_count;
-			o_odd->vb.state = STATE_DONE;
-			wake_up(&o_odd->vb.done);
-		}
-		if (NULL != o_even && btv->even != o_even) {
-#ifdef HAVE_V4L2
-			o_even->vb.ts = ts;
-#endif
-			o_even->vb.field_count = btv->field_count;
-			o_even->vb.state = STATE_DONE;
-			wake_up(&o_even->vb.done);
+		if (NULL != o_top && btv->top != o_top) {
+			o_top->vb.ts = ts;
+			o_top->vb.field_count = btv->field_count;
+			o_top->vb.state = STATE_DONE;
+			wake_up(&o_top->vb.done);
+		}
+		if (NULL != o_bottom && btv->bottom != o_bottom) {
+			o_bottom->vb.ts = ts;
+			o_bottom->vb.field_count = btv->field_count;
+			o_bottom->vb.state = STATE_DONE;
+			wake_up(&o_bottom->vb.done);
 		}
 	}
 	if (NULL != o_vcurr) {
-#ifdef HAVE_V4L2
 		o_vcurr->vb.ts = ts;
-#endif
 		o_vcurr->vb.field_count = btv->field_count;
 		o_vcurr->vb.state = STATE_DONE;
 		wake_up(&o_vcurr->vb.done);
@@ -2896,7 +3114,7 @@
 				printk("   PRES => %s", (dstat & BT848_DSTATUS_PRES)
 				       ? "yes" : "no");
 			if (stat & BT848_INT_FMTCHG)
-				printk("   NUML => %s", (dstat & BT848_DSTATUS_PRES)
+				printk("   NUML => %s", (dstat & BT848_DSTATUS_NUML)
 				       ? "625" : "525");
 			printk("\n");
 		}
@@ -3006,8 +3224,6 @@
         init_waitqueue_head(&btv->gpioq);
         INIT_LIST_HEAD(&btv->capture);
         INIT_LIST_HEAD(&btv->vcapture);
-	videobuf_queue_init(&btv->vbi.q, &vbi_qops, btv->dev, &btv->s_lock,
-			    V4L2_BUF_TYPE_VBI,sizeof(struct bttv_buffer));
 
 	btv->timeout.function = bttv_irq_timeout;
 	btv->timeout.data     = (unsigned long)btv;
@@ -3015,9 +3231,9 @@
         btv->i2c_rc = -1;
         btv->tuner_type = -1;
 
-	memcpy(&btv->video_dev, &bttv_template,     sizeof(bttv_template));
-	memcpy(&btv->radio_dev, &radio_template,    sizeof(radio_template));
-	memcpy(&btv->vbi_dev,   &bttv_vbi_template, sizeof(bttv_vbi_template));
+	memcpy(&btv->video_dev, &bttv_video_template, sizeof(bttv_video_template));
+	memcpy(&btv->radio_dev, &radio_template,      sizeof(radio_template));
+	memcpy(&btv->vbi_dev,   &bttv_vbi_template,   sizeof(bttv_vbi_template));
         btv->video_dev.minor = -1;
 	btv->video_dev.priv = btv;
         btv->radio_dev.minor = -1;
@@ -3060,9 +3276,8 @@
 	}
         pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision);
         pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
-        printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %02x:%02x.%x, ",
-               bttv_num,btv->id, btv->revision, dev->bus->number,
-	       PCI_SLOT(dev->devfn),PCI_FUNC(dev->devfn));
+        printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ",
+               bttv_num,btv->id, btv->revision, dev->slot_name);
         printk("irq: %d, latency: %d, mmio: 0x%lx\n",
 	       btv->dev->irq, lat, pci_resource_start(dev,0));
 	
@@ -3100,11 +3315,13 @@
 	
 	/* fill struct bttv with some useful defaults */
 	btv->init.btv = btv;
-	btv->init.ov.width      = 320;
-	btv->init.ov.height     = 240;
+	btv->init.ov.w.width    = 320;
+	btv->init.ov.w.height   = 240;
 	btv->init.buf.fmt       = format_by_palette(VIDEO_PALETTE_RGB24);
 	btv->init.buf.vb.width  = 320;
 	btv->init.buf.vb.height = 240;
+	btv->init.buf.vb.field  = V4L2_FIELD_BOTTOM;
+	btv->init.lines         = 16;
 	btv->input = 0;
 
 	/* initialize hardware */
@@ -3173,7 +3390,7 @@
         /* shutdown everything (DMA+IRQs) */
 	btand(~15, BT848_GPIO_DMA_CTL);
 	btwrite(0, BT848_INT_MASK);
-	btwrite(~0x0UL,BT848_INT_STAT);
+	btwrite(~0x0, BT848_INT_STAT);
 	btwrite(0x0, BT848_GPIO_OUT_EN);
 	if (bttv_gpio)
 		bttv_gpio_tracking(btv,"cleanup");
@@ -3231,8 +3448,7 @@
 {
 	bttv_num = 0;
 
-	printk(KERN_INFO "bttv: driver version %d.%d.%d loaded "
-	       BTTV_APIS "\n",
+	printk(KERN_INFO "bttv: driver version %d.%d.%d loaded\n",
 	       (BTTV_VERSION_CODE >> 16) & 0xff,
 	       (BTTV_VERSION_CODE >> 8) & 0xff,
 	       BTTV_VERSION_CODE & 0xff);
diff -Nru a/drivers/media/video/bttv-if.c b/drivers/media/video/bttv-if.c
--- a/drivers/media/video/bttv-if.c	Mon Nov  4 14:31:00 2002
+++ b/drivers/media/video/bttv-if.c	Mon Nov  4 14:31:00 2002
@@ -41,11 +41,13 @@
 static struct i2c_client bttv_i2c_client_template;
 
 EXPORT_SYMBOL(bttv_get_cardinfo);
+EXPORT_SYMBOL(bttv_get_pcidev);
 EXPORT_SYMBOL(bttv_get_id);
 EXPORT_SYMBOL(bttv_gpio_enable);
 EXPORT_SYMBOL(bttv_read_gpio);
 EXPORT_SYMBOL(bttv_write_gpio);
 EXPORT_SYMBOL(bttv_get_gpio_queue);
+EXPORT_SYMBOL(bttv_i2c_call);
 
 /* ----------------------------------------------------------------------- */
 /* Exported functions - for other modules which want to access the         */
@@ -62,6 +64,13 @@
 	return 0;
 }
 
+struct pci_dev* bttv_get_pcidev(unsigned int card)
+{
+	if (card >= bttv_num)
+		return NULL;
+	return bttvs[card].dev;
+}
+
 int bttv_get_id(unsigned int card)
 {
 	printk("bttv_get_id is obsolete, use bttv_get_cardinfo instead\n");
@@ -243,6 +252,13 @@
 		btv->i2c_clients[i]->driver->command(
 			btv->i2c_clients[i],cmd,arg);
 	}
+}
+
+void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg)
+{
+	if (card >= bttv_num)
+		return;
+	bttv_call_i2c_clients(&bttvs[card], cmd, arg);
 }
 
 static struct i2c_algo_bit_data bttv_i2c_algo_template = {
diff -Nru a/drivers/media/video/bttv-risc.c b/drivers/media/video/bttv-risc.c
--- a/drivers/media/video/bttv-risc.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/media/video/bttv-risc.c	Mon Nov  4 14:31:01 2002
@@ -5,7 +5,7 @@
 	- memory management
 	- generation
 
-    (c) 2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
+    (c) 2000 Gerd Knorr <kraxel@bytesex.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -43,8 +43,8 @@
 			struct bttv_riscmem *risc,
 			unsigned int size)
 {
-	unsigned long  *cpu;
-	dma_addr_t     dma;
+	u32 *cpu;
+	dma_addr_t dma;
 	
 	cpu = pci_alloc_consistent(pci, size, &dma);
 	if (NULL == cpu)
@@ -82,7 +82,7 @@
 {
 	int instructions,rc,line,todo;
 	struct scatterlist *sg;
-	unsigned long *rp;
+	u32 *rp;
 
 	/* estimate risc mem: worst case is one write per page border +
 	   one write per scan line + sync + jump (all 2 dwords) */
@@ -146,7 +146,7 @@
 		 int cpadding)
 {
 	int instructions,rc,line,todo,ylen,chroma;
-	unsigned long *rp,ri;
+	u32 *rp,ri;
 	struct scatterlist *ysg;
 	struct scatterlist *usg;
 	struct scatterlist *vsg;
@@ -241,54 +241,53 @@
 };
 
 int
-bttv_screen_clips(struct video_buffer *fbuf,
-		  int x, int y, int width, int height,
-		  struct video_clip *clips, int n)
+bttv_screen_clips(int swidth, int sheight, struct v4l2_rect *win,
+		  struct v4l2_clip *clips, int n)
 {
-	if (x < 0) {
+	if (win->left < 0) {
 		/* left */
-		clips[n].x = 0;
-		clips[n].y = 0;
-		clips[n].width  = -x;
-		clips[n].height = height;
+		clips[n].c.left = 0;
+		clips[n].c.top = 0;
+		clips[n].c.width  = -win->left;
+		clips[n].c.height = win->height;
 		n++;
 	}
-	if (x+width > fbuf->width) {
+	if (win->left + win->width > swidth) {
 		/* right */
-		clips[n].x = fbuf->width - x;
-		clips[n].y = 0;
-		clips[n].width  = width - clips[n].x;
-		clips[n].height = height;
+		clips[n].c.left   = swidth - win->left;
+		clips[n].c.top    = 0;
+		clips[n].c.width  = win->width - clips[n].c.left;
+		clips[n].c.height = win->height;
 		n++;
 	}
-	if (y < 0) {
+	if (win->top < 0) {
 		/* top */
-		clips[n].x = 0;
-		clips[n].y = 0;
-		clips[n].width  = width;
-		clips[n].height = -y;
+		clips[n].c.left = 0;
+		clips[n].c.top = 0;
+		clips[n].c.width  = win->width;
+		clips[n].c.height = -win->top;
 		n++;
 	}
-	if (y+height > fbuf->height) {
+	if (win->top + win->height > sheight) {
 		/* bottom */
-		clips[n].x = 0;
-		clips[n].y = fbuf->height - y;
-		clips[n].width  = width;
-		clips[n].height = height - clips[n].y;
+		clips[n].c.left = 0;
+		clips[n].c.top = sheight - win->top;
+		clips[n].c.width  = win->width;
+		clips[n].c.height = win->height - clips[n].c.top;
 		n++;
 	}
 	return n;
 }
 
 void
-bttv_sort_clips(struct video_clip *clips, int nclips)
+bttv_sort_clips(struct v4l2_clip *clips, int nclips)
 {
-	struct video_clip swap;
+	struct v4l2_clip swap;
 	int i,j,n;
 
 	for (i = nclips-2; i >= 0; i--) {
 		for (n = 0, j = 0; j <= i; j++) {
-			if (clips[j].x > clips[j+1].x) {
+			if (clips[j].c.left > clips[j+1].c.left) {
 				swap = clips[j];
 				clips[j] = clips[j+1];
 				clips[j+1] = swap;
@@ -303,7 +302,7 @@
 static void
 calc_skips(int line, int width, int *maxy,
 	   struct SKIPLIST *skips, int *nskips,
-	   const struct video_clip *clips, int nclips)
+	   const struct v4l2_clip *clips, int nclips)
 {
 	int clip,skip,maxline,end;
 
@@ -312,35 +311,35 @@
 	for (clip = 0; clip < nclips; clip++) {
 
 		/* sanity checks */
-		if (clips[clip].x + clips[clip].width <= 0)
+		if (clips[clip].c.left + clips[clip].c.width <= 0)
 			continue;
-		if (clips[clip].x > width)
+		if (clips[clip].c.left > width)
 			break;
 		
 		/* vertical range */
-		if (line > clips[clip].y+clips[clip].height-1)
+		if (line > clips[clip].c.top+clips[clip].c.height-1)
 			continue;
-		if (line < clips[clip].y) {
-			if (maxline > clips[clip].y-1)
-				maxline = clips[clip].y-1;
+		if (line < clips[clip].c.top) {
+			if (maxline > clips[clip].c.top-1)
+				maxline = clips[clip].c.top-1;
 			continue;
 		}
-		if (maxline > clips[clip].y+clips[clip].height-1)
-			maxline = clips[clip].y+clips[clip].height-1;
+		if (maxline > clips[clip].c.top+clips[clip].c.height-1)
+			maxline = clips[clip].c.top+clips[clip].c.height-1;
 
 		/* horizontal range */
-		if (0 == skip || clips[clip].x > skips[skip-1].end) {
+		if (0 == skip || clips[clip].c.left > skips[skip-1].end) {
 			/* new one */
-			skips[skip].start = clips[clip].x;
+			skips[skip].start = clips[clip].c.left;
 			if (skips[skip].start < 0)
 				skips[skip].start = 0;
-			skips[skip].end = clips[clip].x + clips[clip].width;
+			skips[skip].end = clips[clip].c.left + clips[clip].c.width;
 			if (skips[skip].end > width)
 				skips[skip].end = width;
 			skip++;
 		} else {
 			/* overlaps -- expand last one */
-			end = clips[clip].x + clips[clip].width;
+			end = clips[clip].c.left + clips[clip].c.width;
 			if (skips[skip-1].end < end)
 				skips[skip-1].end = end;
 			if (skips[skip-1].end > width)
@@ -362,12 +361,12 @@
 int
 bttv_risc_overlay(struct bttv *btv, struct bttv_riscmem *risc,
 		  const struct bttv_format *fmt, struct bttv_overlay *ov,
-		  int fields)
+		  int skip_even, int skip_odd)
 {
 	int instructions,rc,line,maxy,start,end,skip,nskips;
 	struct SKIPLIST *skips;
-	unsigned long *rp,ri,ra;
-	unsigned long addr;
+	u32 *rp,ri,ra;
+	u32 addr;
 
 	/* skip list for window clipping */
 	if (NULL == (skips = kmalloc(sizeof(*skips) * ov->nclips,GFP_KERNEL)))
@@ -376,7 +375,7 @@
 	/* estimate risc mem: worst case is (clip+1) * lines instructions
 	   + sync + jump (all 2 dwords) */
 	instructions  = (ov->nclips + 1) *
-		((fields & VBUF_FIELD_INTER) ? ov->height>>1 :  ov->height);
+		((skip_even || skip_odd) ? ov->w.height>>1 :  ov->w.height);
 	instructions += 2;
 	if ((rc = bttv_riscmem_alloc(btv->dev,risc,instructions*8)) < 0)
 		return rc;
@@ -387,29 +386,27 @@
 	*(rp++) = cpu_to_le32(0);
 
 	addr  = (unsigned long)btv->fbuf.base;
-	addr += btv->fbuf.bytesperline * ov->y;
-	addr += ((btv->fbuf.depth+7) >> 3) * ov->x;
+	addr += btv->fbuf.bytesperline * ov->w.top;
+	addr += ((btv->fbuf.depth+7) >> 3) * ov->w.left;
 
 	/* scan lines */
-	for (maxy = -1, line = 0; line < ov->height;
+	for (maxy = -1, line = 0; line < ov->w.height;
 	     line++, addr += btv->fbuf.bytesperline) {
-		if (fields & VBUF_FIELD_INTER) {
-			if ((line%2) != 0 && (fields & VBUF_FIELD_ODD))
-				continue;
-			if ((line%2) != 1 && (fields & VBUF_FIELD_EVEN))
-				continue;
-		}
+		if ((line%2) == 0  &&  skip_even)
+			continue;
+		if ((line%2) == 1  &&  skip_odd)
+			continue;
 
 		/* calculate clipping */
 		if (line > maxy)
-			calc_skips(line, ov->width, &maxy,
+			calc_skips(line, ov->w.width, &maxy,
 				   skips, &nskips, ov->clips, ov->nclips);
 
 		/* write out risc code */
-		for (start = 0, skip = 0; start < ov->width; start = end) {
+		for (start = 0, skip = 0; start < ov->w.width; start = end) {
 			if (skip >= nskips) {
 				ri  = BT848_RISC_WRITE;
-				end = ov->width;
+				end = ov->w.width;
 			} else if (start < skips[skip].start) {
 				ri  = BT848_RISC_WRITE;
 				end = skips[skip].start;
@@ -425,7 +422,7 @@
 				
 			if (0 == start)
 				ri |= BT848_RISC_SOL;
-			if (ov->width == end)
+			if (ov->w.width == end)
 				ri |= BT848_RISC_EOL;
 			ri |= (fmt->depth>>3) * (end-start);
 
@@ -448,19 +445,30 @@
 bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo,
 	      int width, int height, int interleaved, int norm)
 {
-	const struct bttv_tvnorm *tvnorm;
+	const struct bttv_tvnorm *tvnorm = &bttv_tvnorms[norm];
         u32 xsf, sr;
 	int vdelay;
 
-	tvnorm = &bttv_tvnorms[norm];
+	int swidth       = tvnorm->swidth;
+	int totalwidth   = tvnorm->totalwidth;
+	int scaledtwidth = tvnorm->scaledtwidth;
+
+	if (btv->digital_video) {
+		swidth       = 720;
+		totalwidth   = 858;
+		scaledtwidth = 858;
+	}
+
 	vdelay = tvnorm->vdelay;
+#if 0 /* FIXME */
 	if (vdelay < btv->vbi.lines*2)
 		vdelay = btv->vbi.lines*2;
+#endif
 
-        xsf = (width*tvnorm->scaledtwidth)/tvnorm->swidth;
-        geo->hscale =  ((tvnorm->totalwidth*4096UL)/xsf-4096);
+        xsf = (width*scaledtwidth)/swidth;
+        geo->hscale =  ((totalwidth*4096UL)/xsf-4096);
         geo->hdelay =  tvnorm->hdelayx1;
-        geo->hdelay =  (geo->hdelay*width)/tvnorm->swidth;
+        geo->hdelay =  (geo->hdelay*width)/swidth;
         geo->hdelay &= 0x3fe;
         sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
         geo->vscale =  (0x10000UL-sr) & 0x1fff;
@@ -512,8 +520,8 @@
 	int capctl;
 
 	btv->cap_ctl = 0;
-	if (NULL != btv->odd)      btv->cap_ctl |= 0x02;
-	if (NULL != btv->even)     btv->cap_ctl |= 0x01;
+	if (NULL != btv->top)      btv->cap_ctl |= 0x02;
+	if (NULL != btv->bottom)   btv->cap_ctl |= 0x01;
 	if (NULL != btv->vcurr)    btv->cap_ctl |= 0x0c;
 
 	capctl  = 0;
@@ -522,12 +530,12 @@
 	capctl |= override;
 
 	d2printk(KERN_DEBUG
-		 "bttv%d: capctl=%x irq=%d odd=%08Lx/%08Lx even=%08Lx/%08Lx\n",
+		 "bttv%d: capctl=%x irq=%d top=%08Lx/%08Lx even=%08Lx/%08Lx\n",
 		 btv->nr,capctl,irqflags,
-		 btv->vcurr ? (u64)btv->vcurr->odd.dma  : 0,
-		 btv->odd   ? (u64)btv->odd->odd.dma    : 0,
-		 btv->vcurr ? (u64)btv->vcurr->even.dma : 0,
-		 btv->even  ? (u64)btv->even->even.dma  : 0);
+		 btv->vcurr   ? (u64)btv->vcurr->top.dma      : 0,
+		 btv->top     ? (u64)btv->top->top.dma        : 0,
+		 btv->vcurr   ? (u64)btv->vcurr->bottom.dma   : 0,
+		 btv->bottom  ? (u64)btv->bottom->bottom.dma  : 0);
 	
 	cmd = BT848_RISC_JUMP;
 	if (irqflags) {
@@ -570,7 +578,7 @@
 	btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP);
 	btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2));
 
-	/* odd field */
+	/* top field */
 	btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP);
 	btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2));
 	btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
@@ -580,13 +588,13 @@
 				       BT848_FIFO_STATUS_VRO);
         btv->main.cpu[9] = cpu_to_le32(0);
 
-	/* even field */
+	/* bottom field */
         btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
 	btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
         btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
 	btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
 
-	/* jump back to odd field */
+	/* jump back to top field */
 	btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
         btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
 
@@ -625,43 +633,43 @@
 	videobuf_waiton(&buf->vb,0,0);
 	videobuf_dma_pci_unmap(btv->dev, &buf->vb.dma);
 	videobuf_dma_free(&buf->vb.dma);
-	bttv_riscmem_free(btv->dev,&buf->even);
-	bttv_riscmem_free(btv->dev,&buf->odd);
+	bttv_riscmem_free(btv->dev,&buf->bottom);
+	bttv_riscmem_free(btv->dev,&buf->top);
 	buf->vb.state = STATE_NEEDS_INIT;
 }
 
 int
 bttv_buffer_activate(struct bttv *btv,
-		     struct bttv_buffer *odd,
-		     struct bttv_buffer *even)
+		     struct bttv_buffer *top,
+		     struct bttv_buffer *bottom)
 {
-	if (NULL != odd  &&  NULL != even) {
-		odd->vb.state  = STATE_ACTIVE;
-		even->vb.state = STATE_ACTIVE;
-		bttv_apply_geo(btv, &odd->geo, 1);
-		bttv_apply_geo(btv, &even->geo,0);
-		bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &odd->odd,   0);
-		bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &even->even, 0);
-		btaor((odd->btformat & 0xf0) | (even->btformat & 0x0f),
+	if (NULL != top  &&  NULL != bottom) {
+		top->vb.state  = STATE_ACTIVE;
+		bottom->vb.state = STATE_ACTIVE;
+		bttv_apply_geo(btv, &top->geo, 1);
+		bttv_apply_geo(btv, &bottom->geo,0);
+		bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &top->top,       0);
+		bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &bottom->bottom, 0);
+		btaor((top->btformat & 0xf0) | (bottom->btformat & 0x0f),
 		      ~0xff, BT848_COLOR_FMT);
-		btaor((odd->btswap & 0x0a) | (even->btswap & 0x05),
+		btaor((top->btswap & 0x0a) | (bottom->btswap & 0x05),
 		      ~0x0f, BT848_COLOR_CTL);
-	} else if (NULL != odd) {
-		odd->vb.state  = STATE_ACTIVE;
-		bttv_apply_geo(btv, &odd->geo,1);
-		bttv_apply_geo(btv, &odd->geo,0);
-		bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &odd->odd, 0);
+	} else if (NULL != top) {
+		top->vb.state  = STATE_ACTIVE;
+		bttv_apply_geo(btv, &top->geo,1);
+		bttv_apply_geo(btv, &top->geo,0);
+		bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &top->top, 0);
 		bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL,      0);
-		btaor(odd->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
-		btaor(odd->btswap & 0x0f,   ~0x0f, BT848_COLOR_CTL);
-	} else if (NULL != even) {
-		even->vb.state = STATE_ACTIVE;
-		bttv_apply_geo(btv, &even->geo,1);
-		bttv_apply_geo(btv, &even->geo,0);
-		bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL,        0);
-		bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &even->even, 0);
-		btaor(even->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
-		btaor(even->btswap & 0x0f,   ~0x0f, BT848_COLOR_CTL);
+		btaor(top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
+		btaor(top->btswap & 0x0f,   ~0x0f, BT848_COLOR_CTL);
+	} else if (NULL != bottom) {
+		bottom->vb.state = STATE_ACTIVE;
+		bttv_apply_geo(btv, &bottom->geo,1);
+		bttv_apply_geo(btv, &bottom->geo,0);
+		bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL,            0);
+		bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &bottom->bottom, 0);
+		btaor(bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
+		btaor(bottom->btswap & 0x0f,   ~0x0f, BT848_COLOR_CTL);
 	} else {
 		bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
 		bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
@@ -671,72 +679,53 @@
 
 /* ---------------------------------------------------------- */
 
-int
-bttv_buffer_field(struct bttv *btv, int field, int def_field,
-		  int norm, int height)
-{
-	const struct bttv_tvnorm *tvnorm = bttv_tvnorms + norm;
-
-	/* check interleave, even+odd fields */
-	if (height > (tvnorm->sheight >> 1)) {
-		field = VBUF_FIELD_ODD | VBUF_FIELD_EVEN | VBUF_FIELD_INTER;
-	} else {
-		if (field & def_field) {
-			field = def_field;
-		} else {
-			field = (def_field & VBUF_FIELD_EVEN)
-				? VBUF_FIELD_ODD : VBUF_FIELD_EVEN;
-		}
-	}
-	return field;
-}
-
 /* calculate geometry, build risc code */
 int
 bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
 {
 	const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
 
-	buf->vb.field = bttv_buffer_field(btv,buf->vb.field, VBUF_FIELD_EVEN,
-					  buf->tvnorm,buf->vb.height);
 	dprintk(KERN_DEBUG
-		"bttv%d: buffer flags:%s%s%s format: %s size: %dx%d\n",
-		btv->nr,
-		(buf->vb.field & VBUF_FIELD_INTER) ? " interleave" : "",
-		(buf->vb.field & VBUF_FIELD_ODD)   ? " odd"        : "",
-		(buf->vb.field & VBUF_FIELD_EVEN)  ? " even"       : "",
-		buf->fmt->name,buf->vb.width,buf->vb.height);
+		"bttv%d: buffer field: %s  format: %s  size: %dx%d\n",
+		btv->nr, v4l2_field_names[buf->vb.field],
+		buf->fmt->name, buf->vb.width, buf->vb.height);
 
 	/* packed pixel modes */
 	if (buf->fmt->flags & FORMAT_FLAGS_PACKED) {
-		int bpl, padding, lines;
-		bpl = (buf->fmt->depth >> 3) * buf->vb.width;
+		int bpl = (buf->fmt->depth >> 3) * buf->vb.width;
+		int bpf = bpl * (buf->vb.height >> 1);
 
-		/* calculate geometry */
-		if (buf->vb.field & VBUF_FIELD_INTER) {
-			bttv_calc_geo(btv,&buf->geo,buf->vb.width,
-				      buf->vb.height,1,buf->tvnorm);
-			lines   = buf->vb.height >> 1;
-			padding = bpl;
-		} else {
-			bttv_calc_geo(btv,&buf->geo,buf->vb.width,
-				      buf->vb.height,0,buf->tvnorm);
-			lines   = buf->vb.height;
-			padding = 0;
-		}
+		bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
+			      V4L2_FIELD_HAS_BOTH(buf->vb.field),buf->tvnorm);
 		
-		/* build risc code */
-		if (buf->vb.field & VBUF_FIELD_ODD)
-			bttv_risc_packed(btv,&buf->odd,buf->vb.dma.sglist,
-					 0,bpl,padding,lines);
-		if (buf->vb.field & VBUF_FIELD_EVEN)
-			bttv_risc_packed(btv,&buf->even,buf->vb.dma.sglist,
-					 padding,bpl,padding,lines);
+		switch (buf->vb.field) {
+		case V4L2_FIELD_TOP:
+			bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
+					 0,bpl,0,buf->vb.height);
+			break;
+		case V4L2_FIELD_BOTTOM:
+			bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
+					 0,bpl,0,buf->vb.height);
+			break;
+		case V4L2_FIELD_INTERLACED:
+			bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
+					 0,bpl,bpl,buf->vb.height >> 1);
+			bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
+					 bpl,bpl,bpl,buf->vb.height >> 1);
+			break;
+		case V4L2_FIELD_SEQ_TB:
+			bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
+					 0,bpl,0,buf->vb.height >> 1);
+			bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
+					 bpf,bpl,0,buf->vb.height >> 1);
+			break;
+		default:
+			BUG();
+		}
 	}
 
 	/* planar modes */
 	if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) {
-		struct bttv_riscmem *risc;
 		int uoffset, voffset;
 		int ypadding, cpadding, lines;
 
@@ -755,54 +744,59 @@
 			voffset += uoffset;
 		}
 
-		if (buf->vb.field & VBUF_FIELD_INTER) {
+		switch (buf->vb.field) {
+		case V4L2_FIELD_TOP:
+			bttv_calc_geo(btv,&buf->geo,buf->vb.width,
+				      buf->vb.height,0,buf->tvnorm);
+			bttv_risc_planar(btv, &buf->top, buf->vb.dma.sglist,
+					 0,buf->vb.width,0,buf->vb.height,
+					 uoffset,voffset,buf->fmt->hshift,
+					 buf->fmt->vshift,0);
+			break;
+		case V4L2_FIELD_BOTTOM:
+			bttv_calc_geo(btv,&buf->geo,buf->vb.width,
+				      buf->vb.height,0,buf->tvnorm);
+			bttv_risc_planar(btv, &buf->bottom, buf->vb.dma.sglist,
+					 0,buf->vb.width,0,buf->vb.height,
+					 uoffset,voffset,buf->fmt->hshift,
+					 buf->fmt->vshift,0);
+			break;
+		case V4L2_FIELD_INTERLACED:
 			bttv_calc_geo(btv,&buf->geo,buf->vb.width,
 				      buf->vb.height,1,buf->tvnorm);
 			lines     = buf->vb.height >> 1;
 			ypadding  = buf->vb.width;
-			if (!buf->fmt->vshift) {
-				/* chroma planes are interleaved too */
-				cpadding = buf->vb.width >> buf->fmt->hshift;
-			} else {
-				cpadding = 0;
-			}
-			bttv_risc_planar(btv,&buf->odd,
+			cpadding = buf->vb.width >> buf->fmt->hshift;
+			bttv_risc_planar(btv,&buf->top,
 					 buf->vb.dma.sglist,
 					 0,buf->vb.width,ypadding,lines,
-					 uoffset,voffset,buf->fmt->hshift,
+					 uoffset,voffset,
+					 buf->fmt->hshift,
 					 buf->fmt->vshift >> 1,
 					 cpadding);
-			bttv_risc_planar(btv,&buf->even,
+			bttv_risc_planar(btv,&buf->bottom,
 					 buf->vb.dma.sglist,
 					 ypadding,buf->vb.width,ypadding,lines,
 					 uoffset+cpadding,
 					 voffset+cpadding,
 					 buf->fmt->hshift,
-					 cpadding ? (buf->fmt->vshift>>1) : -1,
+					 buf->fmt->vshift >> 1,
 					 cpadding);
-		} else {
-			if (buf->vb.field & VBUF_FIELD_ODD)
-				risc = &buf->odd;
-			else
-				risc = &buf->even;
-			bttv_calc_geo(btv,&buf->geo,buf->vb.width,
-				      buf->vb.height,0,buf->tvnorm);
-			bttv_risc_planar(btv, risc, buf->vb.dma.sglist,
-					 0,buf->vb.width,0,buf->vb.height,
-					 uoffset,voffset,buf->fmt->hshift,
-					 buf->fmt->vshift,0);
+			break;
+		default:
+			BUG();
 		}
 	}
 
 	/* raw data */
 	if (buf->fmt->flags & FORMAT_FLAGS_RAW) {
 		/* build risc code */
-		buf->vb.field = VBUF_FIELD_INTER | VBUF_FIELD_ODD | VBUF_FIELD_EVEN;
+		buf->vb.field = V4L2_FIELD_SEQ_TB;
 		bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight,
 			      1,buf->tvnorm);
-		bttv_risc_packed(btv, &buf->odd,  buf->vb.dma.sglist,
+		bttv_risc_packed(btv, &buf->top,  buf->vb.dma.sglist,
 				 0, RAW_BPL, 0, RAW_LINES);
-		bttv_risc_packed(btv, &buf->even, buf->vb.dma.sglist,
+		bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist,
 				 buf->vb.size/2 , RAW_BPL, 0, RAW_LINES);
 	}
 
@@ -821,35 +815,41 @@
 		  const struct bttv_format *fmt,
 		  struct bttv_buffer *buf)
 {
-	int interleave;
-
-	/* check interleave, even+odd fields */
-	buf->vb.field = bttv_buffer_field(btv, 0, VBUF_FIELD_ODD,
-					  ov->tvnorm,ov->height);
+	/* check interleave, bottom+top fields */
 	dprintk(KERN_DEBUG
-		"bttv%d: overlay flags:%s%s%s format: %s size: %dx%d\n",
-		btv->nr,
-		(buf->vb.field & VBUF_FIELD_INTER) ? " interleave" : "",
-		(buf->vb.field & VBUF_FIELD_ODD)   ? " odd" : "",
-		(buf->vb.field & VBUF_FIELD_EVEN)  ? " even" : "",
-		fmt->name,ov->width,ov->height);
+		"bttv%d: overlay fields: %s format: %s  size: %dx%d\n",
+		btv->nr, v4l2_field_names[buf->vb.field],
+		fmt->name,ov->w.width,ov->w.height);
 
 	/* calculate geometry */
-	interleave = buf->vb.field & VBUF_FIELD_INTER;
-	bttv_calc_geo(btv,&buf->geo,ov->width,ov->height,
-		      interleave, ov->tvnorm);
+	bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
+		      V4L2_FIELD_HAS_BOTH(ov->field), ov->tvnorm);
 
 	/* build risc code */
-	if (buf->vb.field & VBUF_FIELD_ODD)
-		bttv_risc_overlay(btv, &buf->odd, fmt, ov,
-				  interleave | VBUF_FIELD_ODD);
-	if (buf->vb.field & VBUF_FIELD_EVEN)
-		bttv_risc_overlay(btv, &buf->even,fmt, ov,
-				  interleave | VBUF_FIELD_EVEN);
+	switch (ov->field) {
+	case V4L2_FIELD_TOP:
+		bttv_risc_overlay(btv, &buf->top,   fmt, ov, 0, 0);
+		break;
+	case V4L2_FIELD_BOTTOM:
+		bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
+		break;
+	case V4L2_FIELD_INTERLACED:
+#if 0
+		bttv_risc_overlay(btv, &buf->top,    fmt, ov, 1, 0);
+		bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 1);
+#else
+		bttv_risc_overlay(btv, &buf->top,    fmt, ov, 0, 1);
+		bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
+#endif
+		break;
+	default:
+		BUG();
+	}
 
 	/* copy format info */
 	buf->btformat = fmt->btformat;
 	buf->btswap   = fmt->btswap;
+	buf->vb.field = ov->field;
 	return 0;
 }
 
diff -Nru a/drivers/media/video/bttv-vbi.c b/drivers/media/video/bttv-vbi.c
--- a/drivers/media/video/bttv-vbi.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/media/video/bttv-vbi.c	Mon Nov  4 14:31:02 2002
@@ -47,58 +47,51 @@
 #define dprintk(fmt, arg...)	if (vbi_debug) \
 	printk(KERN_DEBUG "bttv%d/vbi: " fmt, btv->nr, ## arg)
 
-#ifndef HAVE_V4L2
-/* some dummy defines to avoid cluttering up the source code with
-   a huge number of ifdef's for V4L2 */
-# define V4L2_BUF_TYPE_CAPTURE -1
-# define V4L2_BUF_TYPE_VBI     -1
-#endif
-
 /* ----------------------------------------------------------------------- */
 /* vbi risc code + mm                                                      */
 
 static int
-vbi_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
+vbi_buffer_risc(struct bttv *btv, struct bttv_buffer *buf, int lines)
 {
 	int bpl = 2048;
 
-	bttv_risc_packed(btv, &buf->odd, buf->vb.dma.sglist,
-			 0, bpl-4, 4, btv->vbi.lines);
-	bttv_risc_packed(btv, &buf->even, buf->vb.dma.sglist,
-			 btv->vbi.lines * bpl, bpl-4, 4, btv->vbi.lines);
+	bttv_risc_packed(btv, &buf->top, buf->vb.dma.sglist,
+			 0, bpl-4, 4, lines);
+	bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist,
+			 lines * bpl, bpl-4, 4, lines);
 	return 0;
 }
 
 static int vbi_buffer_setup(struct file *file, int *count, int *size)
 {
-	struct bttv *btv = file->private_data;
+	struct bttv_fh *fh = file->private_data;
 
 	if (0 == *count)
 		*count = vbibufs;
-	*size = btv->vbi.lines * 2 * 2048;
+	*size = fh->lines * 2 * 2048;
 	return 0;
 }
 
-static int vbi_buffer_prepare(struct file *file, struct videobuf_buffer *vb,
-			      int fields)
+static int vbi_buffer_prepare(struct file *file, struct videobuf_buffer *vb)
 {
-	struct bttv *btv = file->private_data;
+	struct bttv_fh *fh = file->private_data;
+	struct bttv *btv = fh->btv;
 	struct bttv_buffer *buf = (struct bttv_buffer*)vb;
 	int rc;
 	
-	buf->vb.size = btv->vbi.lines * 2 * 2048;
+	buf->vb.size = fh->lines * 2 * 2048;
 	if (0 != buf->vb.baddr  &&  buf->vb.bsize < buf->vb.size)
 		return -EINVAL;
 
 	if (STATE_NEEDS_INIT == buf->vb.state) {
 		if (0 != (rc = videobuf_iolock(btv->dev,&buf->vb)))
 			goto fail;
-		if (0 != (rc = vbi_buffer_risc(btv,buf)))
+		if (0 != (rc = vbi_buffer_risc(btv,buf,fh->lines)))
 			goto fail;
 	}
 	buf->vb.state = STATE_PREPARED;
-	dprintk("buf prepare %p: odd=%p even=%p\n",
-		vb,&buf->odd,&buf->even);
+	dprintk("buf prepare %p: top=%p bottom=%p\n",
+		vb,&buf->top,&buf->bottom);
 	return 0;
 
  fail:
@@ -109,7 +102,8 @@
 static void
 vbi_buffer_queue(struct file *file, struct videobuf_buffer *vb)
 {
-	struct bttv *btv = file->private_data;
+	struct bttv_fh *fh = file->private_data;
+	struct bttv *btv = fh->btv;
 	struct bttv_buffer *buf = (struct bttv_buffer*)vb;
 	
 	dprintk("queue %p\n",vb);
@@ -120,14 +114,15 @@
 
 static void vbi_buffer_release(struct file *file, struct videobuf_buffer *vb)
 {
-	struct bttv *btv = file->private_data;
+	struct bttv_fh *fh = file->private_data;
+	struct bttv *btv = fh->btv;
 	struct bttv_buffer *buf = (struct bttv_buffer*)vb;
 	
 	dprintk("free %p\n",vb);
-	bttv_dma_free(btv,buf);
+	bttv_dma_free(fh->btv,buf);
 }
 
-struct videobuf_queue_ops vbi_qops = {
+struct videobuf_queue_ops bttv_vbi_qops = {
 	buf_setup:    vbi_buffer_setup,
 	buf_prepare:  vbi_buffer_prepare,
 	buf_queue:    vbi_buffer_queue,
@@ -136,7 +131,7 @@
 
 /* ----------------------------------------------------------------------- */
 
-static void vbi_setlines(struct bttv *btv, int lines)
+void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines)
 {
 	int vdelay;
 
@@ -144,7 +139,7 @@
 		lines = 1;
 	if (lines > VBI_MAXLINES)
 		lines = VBI_MAXLINES;
-	btv->vbi.lines = lines;
+	fh->lines = lines;
 
 	vdelay = btread(BT848_E_VDELAY_LO);
 	if (vdelay < lines*2) {
@@ -154,19 +149,18 @@
 	}
 }
 
-#ifdef HAVE_V4L2
-static void vbi_fmt(struct bttv *btv, struct v4l2_format *f)
+void bttv_vbi_fmt(struct bttv_fh *fh, struct v4l2_format *f)
 {
 	memset(f,0,sizeof(*f));
-	f->type = V4L2_BUF_TYPE_VBI;
+	f->type = V4L2_BUF_TYPE_VBI_CAPTURE;
 	f->fmt.vbi.sampling_rate    = 35468950;
 	f->fmt.vbi.samples_per_line = 2048;
-	f->fmt.vbi.sample_format    = V4L2_VBI_SF_UBYTE;
+	f->fmt.vbi.sample_format    = V4L2_PIX_FMT_GREY;
 	f->fmt.vbi.offset           = 244;
-	f->fmt.vbi.count[0]         = btv->vbi.lines;
-	f->fmt.vbi.count[1]         = btv->vbi.lines;
+	f->fmt.vbi.count[0]         = fh->lines;
+	f->fmt.vbi.count[1]         = fh->lines;
 	f->fmt.vbi.flags            = 0;
-	switch (btv->tvnorm) {
+	switch (fh->btv->tvnorm) {
 	case 1: /* NTSC */
 		f->fmt.vbi.start[0] = 10;
 		f->fmt.vbi.start[1] = 273;
@@ -178,212 +172,8 @@
 		f->fmt.vbi.start[1] = 319;
 	}
 }
-#endif
 
 /* ----------------------------------------------------------------------- */
-/* vbi interface                                                           */
-
-static int vbi_open(struct inode *inode, struct file *file)
-{
-	unsigned int minor = minor(inode->i_rdev);
-	struct bttv *btv = NULL;
-	int i;
-
-	for (i = 0; i < bttv_num; i++) {
-		if (bttvs[i].vbi_dev.minor == minor) {
-			btv = &bttvs[i];
-			break;
-		}
-	}
-	if (NULL == btv)
-		return -ENODEV;
-
-	down(&btv->vbi.q.lock);
-	if (btv->vbi.users) {
-		up(&btv->vbi.q.lock);
-		return -EBUSY;
-	}
-	dprintk("open minor=%d\n",minor);
-	file->private_data = btv;
-	btv->vbi.users++;
-	vbi_setlines(btv,VBI_DEFLINES);
-	bttv_field_count(btv);
-	
-	up(&btv->vbi.q.lock);
-	
-	return 0;
-}
-
-static int vbi_release(struct inode *inode, struct file *file)
-{
-	struct bttv    *btv = file->private_data;
-
-	if (btv->vbi.q.streaming)
-		videobuf_streamoff(file,&btv->vbi.q);
-	down(&btv->vbi.q.lock);
-	if (btv->vbi.q.reading)
-		videobuf_read_stop(file,&btv->vbi.q);
-	btv->vbi.users--;
-	bttv_field_count(btv);
-	vbi_setlines(btv,0);
-	up(&btv->vbi.q.lock);
-	return 0;
-}
-
-static int vbi_do_ioctl(struct inode *inode, struct file *file,
-			unsigned int cmd, void *arg)
-{
-	struct bttv *btv = file->private_data;
-	
-	if (btv->errors)
-		bttv_reinit_bt848(btv);
-	switch (cmd) {
-	case VIDIOCGCAP:
-	{
-                struct video_capability *cap = arg;
-
-		memset(cap,0,sizeof(*cap));
-                strcpy(cap->name,btv->vbi_dev.name);
-                cap->type = VID_TYPE_TUNER|VID_TYPE_TELETEXT;
-                return 0;
-	}
-
-	/* vbi/teletext ioctls */
-	case BTTV_VBISIZE:
-		return btv->vbi.lines * 2 * 2048;
-
-	case BTTV_VERSION:
-        case VIDIOCGFREQ:
-        case VIDIOCSFREQ:
-        case VIDIOCGTUNER:
-        case VIDIOCSTUNER:
-        case VIDIOCGCHAN:
-        case VIDIOCSCHAN:
-		return bttv_common_ioctls(btv,cmd,arg);
-
-#ifdef HAVE_V4L2
-	case VIDIOC_QUERYCAP:
-	{
-		struct v4l2_capability *cap = arg;
-
-		memset(cap,0,sizeof(*cap));
-                strcpy(cap->name, btv->name);
-		cap->type = V4L2_TYPE_VBI;
-		cap->flags = V4L2_FLAG_TUNER | V4L2_FLAG_READ |
-			V4L2_FLAG_STREAMING | V4L2_FLAG_SELECT;
-		return 0;
-	}
-	case VIDIOC_G_FMT:
-	{
-		struct v4l2_format *f = arg;
-
-		vbi_fmt(btv,f);
-		return 0;
-	}
-	case VIDIOC_S_FMT:
-	{
-		struct v4l2_format *f = arg;
-
-		if (btv->vbi.q.reading || btv->vbi.q.streaming)
-			return -EBUSY;
-		vbi_setlines(btv,f->fmt.vbi.count[0]);
-		vbi_fmt(btv,f);
-		return 0;
-	}
-
-	case VIDIOC_REQBUFS:
-		return videobuf_reqbufs(file,&btv->vbi.q,arg);
-
-	case VIDIOC_QUERYBUF:
-		return videobuf_querybuf(&btv->vbi.q, arg);
-
-	case VIDIOC_QBUF:
-		return videobuf_qbuf(file, &btv->vbi.q, arg);
-
-	case VIDIOC_DQBUF:
-		return videobuf_dqbuf(file, &btv->vbi.q, arg);
-
-	case VIDIOC_STREAMON:
-		return videobuf_streamon(file, &btv->vbi.q);
-
-	case VIDIOC_STREAMOFF:
-		return videobuf_streamoff(file, &btv->vbi.q);
-
-	case VIDIOC_ENUMSTD:
-	case VIDIOC_G_STD:
-	case VIDIOC_S_STD:
-	case VIDIOC_ENUMINPUT:
-	case VIDIOC_G_INPUT:
-	case VIDIOC_S_INPUT:
-	case VIDIOC_G_TUNER:
-	case VIDIOC_S_TUNER:
-	case VIDIOC_G_FREQ:
-	case VIDIOC_S_FREQ:
-		return bttv_common_ioctls(btv,cmd,arg);
-#endif /* HAVE_V4L2 */
-
-	default:
-		return -ENOIOCTLCMD;
-	}
-	return 0;
-}
-
-static int vbi_ioctl(struct inode *inode, struct file *file,
-		     unsigned int cmd, unsigned long arg)
-{
-	return video_usercopy(inode, file, cmd, arg, vbi_do_ioctl);
-}
-
-static ssize_t vbi_read(struct file *file, char *data,
-			size_t count, loff_t *ppos)
-{
-	struct bttv *btv = file->private_data;
-
-	if (btv->errors)
-		bttv_reinit_bt848(btv);
-	dprintk("read %d\n",count);
-	return videobuf_read_stream(file, &btv->vbi.q, data, count, ppos, 1);
-}
-
-static unsigned int vbi_poll(struct file *file, poll_table *wait)
-{
-	struct bttv *btv = file->private_data;
-
-	dprintk("poll%s\n","");
-	return videobuf_poll_stream(file, &btv->vbi.q, wait);
-}
-
-static int
-vbi_mmap(struct file *file, struct vm_area_struct * vma)
-{
-	struct bttv *btv = file->private_data;
-	
-	dprintk("mmap 0x%lx+%ld\n",vma->vm_start,
-		vma->vm_end - vma->vm_start);
-	return videobuf_mmap_mapper(vma, &btv->vbi.q);
-}
-
-static struct file_operations vbi_fops =
-{
-	owner:	  THIS_MODULE,
-	open:	  vbi_open,
-	release:  vbi_release,
-	ioctl:	  vbi_ioctl,
-	llseek:	  no_llseek,
-	read:	  vbi_read,
-	poll:	  vbi_poll,
-	mmap:	  vbi_mmap,
-};
-
-struct video_device bttv_vbi_template =
-{
-	name:     "bt848/878 vbi",
-	type:     VID_TYPE_TUNER|VID_TYPE_TELETEXT,
-	hardware: VID_HARDWARE_BT848,
-	fops:     &vbi_fops,
-	minor:    -1,
-};
-
 /*
  * Local variables:
  * c-basic-offset: 8
diff -Nru a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h
--- a/drivers/media/video/bttv.h	Mon Nov  4 14:31:00 2002
+++ b/drivers/media/video/bttv.h	Mon Nov  4 14:31:00 2002
@@ -90,10 +90,26 @@
 #define BTTV_SENSORAY311    0x49
 #define BTTV_RV605          0x4a
 #define BTTV_WINDVR         0x4c
+#define BTTV_HAUPPAUGEPVR   0x50
+#define BTTV_GVBCTV5PCI     0x51
+#define BTTV_OSPREY1x0      0x52
+#define BTTV_OSPREY1x0_848  0x53
+#define BTTV_OSPREY101_848  0x54
+#define BTTV_OSPREY1x1      0x55
+#define BTTV_OSPREY1x1_SVID 0x56
+#define BTTV_OSPREY2xx      0x57
+#define BTTV_OSPREY2x0_SVID 0x58
+#define BTTV_OSPREY2x0      0x59
+#define BTTV_OSPREY500      0x5a
+#define BTTV_OSPREY540      0x5b
+#define BTTV_OSPREY2000     0x5c
+#define BTTV_IDS_EAGLE      0x5d
 
 /* i2c address list */
 #define I2C_TSA5522        0xc2
 #define I2C_TDA7432        0x8a
+#define I2C_BT832_ALT1	   0x88
+#define I2C_BT832_ALT2	   0x8a // alternate setting
 #define I2C_TDA8425        0x82
 #define I2C_TDA9840        0x84
 #define I2C_TDA9850        0xb6 /* also used by 9855,9873 */
@@ -105,6 +121,7 @@
 #define I2C_MSP3400        0x80
 #define I2C_TEA6300        0x80
 #define I2C_DPL3518	   0x84
+#define I2C_TDA9887	   0x86
 
 /* more card-specific defines */
 #define PT2254_L_CHANNEL 0x10
@@ -132,6 +149,7 @@
 	/* i2c audio flags */
 	int no_msp34xx:1;
 	int no_tda9875:1;
+	int no_tda7432:1;
 	int needs_tvaudio:1;
 
 	/* other settings */
@@ -174,6 +192,7 @@
    returns negative value if error occurred 
 */
 extern int bttv_get_cardinfo(unsigned int card, int *type, int *cardid);
+extern struct pci_dev* bttv_get_pcidev(unsigned int card);
 
 /* obsolete, use bttv_get_cardinfo instead */
 extern int bttv_get_id(unsigned int card);
@@ -207,6 +226,11 @@
    process data ASAP
 */
 extern wait_queue_head_t* bttv_get_gpio_queue(unsigned int card);
+
+/* call i2c clients
+*/
+extern void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg);
+
 
 /* i2c */
 #define I2C_CLIENTS_MAX 16
diff -Nru a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h
--- a/drivers/media/video/bttvp.h	Mon Nov  4 14:31:01 2002
+++ b/drivers/media/video/bttvp.h	Mon Nov  4 14:31:01 2002
@@ -24,7 +24,7 @@
 #ifndef _BTTVP_H_
 #define _BTTVP_H_
 
-#define BTTV_VERSION_CODE KERNEL_VERSION(0,8,42)
+#define BTTV_VERSION_CODE KERNEL_VERSION(0,9,1)
 
 #include <linux/types.h>
 #include <linux/wait.h>
@@ -54,7 +54,8 @@
 #define RISC_SLOT_LOOP        14
 
 #define RESOURCE_OVERLAY       1
-#define RESOURCE_STREAMING     2
+#define RESOURCE_VIDEO         2
+#define RESOURCE_VBI           3
 
 #define RAW_LINES            640
 #define RAW_BPL             1024
@@ -63,15 +64,17 @@
 
 struct bttv_tvnorm 
 {
-	int v4l2_id;
-        u32 Fsc;
-        u16 swidth, sheight; /* scaled standard width, height */
-	u16 totalwidth;
-	u8 adelay, bdelay, iform;
-	u32 scaledtwidth;
-	u16 hdelayx1, hactivex1;
-	u16 vdelay;
-        u8 vbipack;
+	int   v4l2_id;
+	char  *name;
+        u32   Fsc;
+        u16   swidth, sheight; /* scaled standard width, height */
+	u16   totalwidth;
+	u8    adelay, bdelay, iform;
+	u32   scaledtwidth;
+	u16   hdelayx1, hactivex1;
+	u16   vdelay;
+        u8    vbipack;
+	int   sram;
 };
 extern const struct bttv_tvnorm bttv_tvnorms[];
 extern const int BTTV_TVNORMS;
@@ -99,8 +102,8 @@
 
 struct bttv_riscmem {
 	unsigned int   size;
-	unsigned long  *cpu;
-	unsigned long  *jmp;
+	u32            *cpu;
+	u32            *jmp;
 	dma_addr_t     dma;
 };
 
@@ -114,32 +117,34 @@
 	int                        btformat;
 	int                        btswap;
 	struct bttv_geometry       geo;
-	struct bttv_riscmem        even;
-	struct bttv_riscmem        odd;
+	struct bttv_riscmem        top;
+	struct bttv_riscmem        bottom;
 };
 
 struct bttv_overlay {
 	int tvnorm;
-	int x,y,width,height;
-	struct video_clip      *clips;
+	struct v4l2_rect       w;
+	enum v4l2_field        field;
+	struct v4l2_clip       *clips;
 	int                    nclips;
 };
 
-struct bttv_vbi {
-	int                      users;
-	int                      lines;
-	struct videobuf_queue    q;
-};
-
 struct bttv_fh {
 	struct bttv              *btv;
-	struct videobuf_queue    q;
 	int resources;
-	
+	enum v4l2_buf_type       type;
+
+	/* video capture */
+	struct videobuf_queue    cap;
+	struct bttv_buffer       buf;
+
 	/* current settings */
 	const struct bttv_format *ovfmt;
 	struct bttv_overlay      ov;
-	struct bttv_buffer       buf;
+
+	/* video overlay */
+	struct videobuf_queue    vbi;
+	int                      lines;
 };
 
 /* ---------------------------------------------------------- */
@@ -163,18 +168,18 @@
 		     int cpadding);
 
 /* risc code generator + helpers - screen overlay */
-int bttv_screen_clips(struct video_buffer *fbuf,
-		      int x, int y, int width, int height,
-		      struct video_clip *clips, int n);
-void bttv_sort_clips(struct video_clip *clips, int nclips);
+int bttv_screen_clips(int swidth, int sheight, struct v4l2_rect *win,
+		      struct v4l2_clip *clips, int n);
+void bttv_sort_clips(struct v4l2_clip *clips, int nclips);
 int bttv_risc_overlay(struct bttv *btv, struct bttv_riscmem *risc,
 		      const struct bttv_format *fmt,
-		      struct bttv_overlay *ov, int flags);
+		      struct bttv_overlay *ov,
+		      int skip_top, int skip_bottom);
 
 /* calculate / apply geometry settings */
 void bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo,
 		   int width, int height, int interleaved, int norm);
-void bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd);
+void bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int top);
 
 /* control dma register + risc main loop */
 void bttv_set_dma(struct bttv *btv, int override, int irqflags);
@@ -183,11 +188,9 @@
 		   int irqflags);
 
 /* capture buffer handling */
-int bttv_buffer_field(struct bttv *btv, int field, int def_field,
-		      int tvnorm, int height);
 int bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf);
-int bttv_buffer_activate(struct bttv *btv, struct bttv_buffer *odd,
-			 struct bttv_buffer *even);
+int bttv_buffer_activate(struct bttv *btv, struct bttv_buffer *top,
+			 struct bttv_buffer *bottom);
 void bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf);
 
 /* overlay handling */
@@ -199,8 +202,10 @@
 /* ---------------------------------------------------------- */
 /* bttv-vbi.c                                                 */
 
-extern struct video_device bttv_vbi_template;
-extern struct videobuf_queue_ops vbi_qops;
+void bttv_vbi_fmt(struct bttv_fh *fh, struct v4l2_format *f);
+void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines);
+
+extern struct videobuf_queue_ops bttv_vbi_qops;
 
 
 /* ---------------------------------------------------------- */
@@ -212,6 +217,7 @@
 extern unsigned int bttv_gpio;
 extern void bttv_gpio_tracking(struct bttv *btv, char *comment);
 extern int init_bttv_i2c(struct bttv *btv);
+extern int pvr_boot(struct bttv *btv);
 
 extern int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg);
 extern void bttv_reinit_bt848(struct bttv *btv);
@@ -285,6 +291,7 @@
 	int tvnorm,hue,contrast,bright,saturation;
 	struct video_buffer fbuf;
 	int field_count;
+	int digital_video;
 
 	/* various options */
 	int opt_combfilter;
@@ -293,27 +300,32 @@
 	int opt_chroma_agc;
 	int opt_adc_crush;
 
-	/* vbi data/state */
-	struct bttv_vbi vbi;
-
 	/* radio data/state */
 	int has_radio;
+	int radio_user;
+
+	/* miro/pinnacle + Aimslab VHX
+	   philips matchbox (tea5757 radio tuner) support */
 	int has_matchbox;
-        int mbox_we;
+	int mbox_we;
 	int mbox_data;
 	int mbox_clk;
 	int mbox_most;
 	int mbox_mask;
-	int radio_user;
-	
+
+	/* ISA stuff (Terratec Active Radio Upgrade) */
+	int mbox_ior;
+	int mbox_iow;
+	int mbox_csel;
+
 	/* risc memory management data
 	   - must aquire s_lock before changing these
 	   - only the irq handler is supported to touch odd + even */
 	struct bttv_riscmem    main;
-	struct bttv_buffer     *odd;       /* current active odd field   */
-	struct bttv_buffer     *even;      /* current active even field  */
-	struct bttv_buffer     *screen;    /* overlay                    */
-	struct list_head       capture;    /* capture buffer queue       */
+	struct bttv_buffer     *top;       /* current active top field    */
+	struct bttv_buffer     *bottom;    /* current active bottom field */
+	struct bttv_buffer     *screen;    /* overlay                     */
+	struct list_head       capture;    /* capture buffer queue        */
 	struct bttv_buffer     *vcurr;
 	struct list_head       vcapture;
 
diff -Nru a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/media/video/saa7134/Makefile	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,11 @@
+
+saa7134-objs :=	saa7134-cards.o saa7134-core.o saa7134-i2c.o	\
+		saa7134-oss.o saa7134-ts.o saa7134-tvaudio.o	\
+		saa7134-vbi.o saa7134-video.o
+
+obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o
+
+EXTRA_CFLAGS = -I$(src)/..
+
+include $(TOPDIR)/Rules.make
+
diff -Nru a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/media/video/saa7134/saa7134-cards.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,361 @@
+/*
+ * device driver for philips saa7134 based TV cards
+ * card-specific stuff.
+ *
+ * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include "saa7134-reg.h"
+#include "saa7134.h"
+#include "tuner.h"
+
+/* commly used strings */
+static char name_mute[]    = "mute";
+static char name_radio[]   = "Radio";
+static char name_tv[]      = "Television";
+static char name_comp1[]   = "Composite1";
+static char name_comp2[]   = "Composite2";
+static char name_svideo[]  = "S-Video";
+
+/* ------------------------------------------------------------------ */
+/* board config info                                                  */
+
+struct saa7134_board saa7134_boards[] = {
+	[SAA7134_BOARD_UNKNOWN] = {
+		name:		"UNKNOWN/GENERIC",
+		audio_clock:	0x00187de7,
+		tuner_type:	TUNER_ABSENT,
+		inputs: {{
+			name: "default",
+			vmux: 0,
+			amux: LINE1,
+		}},
+	},
+	[SAA7134_BOARD_PROTEUS_PRO] = {
+		/* /me */
+		name:		"Proteus Pro [philips reference design]",
+		audio_clock:	0x00187de7,
+		tuner_type:	TUNER_PHILIPS_PAL,
+		inputs: {{
+			name: name_comp1,
+			vmux: 0,
+			amux: LINE1,
+		},{
+			name: name_tv,
+			vmux: 1,
+			amux: TV,
+			tv:   1,
+		}},
+	},
+	[SAA7134_BOARD_FLYVIDEO3000] = {
+		/* "Marco d'Itri" <md@Linux.IT> */
+		name:		"LifeView FlyVIDEO3000",
+		audio_clock:	0x00200000,
+		tuner_type:	TUNER_PHILIPS_PAL,
+		inputs: {{
+			name: name_tv,
+			vmux: 1,
+			amux: TV,
+			tv:   1,
+		},{
+			name: name_comp1,
+			vmux: 0,
+			amux: LINE1,
+		},{
+			name: name_comp2,
+			vmux: 3,
+			amux: LINE1,
+		},{
+			name: name_svideo,
+			vmux: 8,
+			amux: LINE1,
+		}},
+		radio: {
+			name: name_radio,
+			amux: LINE2,
+		},
+	},
+	[SAA7134_BOARD_FLYVIDEO2000] = {
+		/* "TC Wan" <tcwan@cs.usm.my> */
+		name:           "LifeView FlyVIDEO2000",
+		audio_clock:    0x00200000,
+		tuner_type:     TUNER_LG_PAL_NEW_TAPC,
+		gpiomask:       0x6000,
+		inputs: {{
+			name: name_tv,
+			vmux: 1,
+			amux: LINE2,
+			gpio: 0x0000,
+			tv:   1,
+		},{
+			name: name_comp1,
+			vmux: 0,
+			amux: LINE2,
+			gpio: 0x4000,
+		},{
+			name: name_comp2,
+			vmux: 3,
+			amux: LINE2,
+			gpio: 0x4000,
+		},{
+			name: name_svideo,
+			vmux: 8,
+			amux: LINE2,
+			gpio: 0x4000,
+		}},
+                radio: {
+                        name: name_radio,
+                        amux: LINE2,
+                },
+		mute: {
+			name: name_mute,
+			amux: LINE1,
+		},
+	},
+	[SAA7134_BOARD_EMPRESS] = {
+		/* "Gert Vervoort" <gert.vervoort@philips.com> */
+		name:		"EMPRESS",
+		audio_clock:	0x00187de7,
+		tuner_type:	TUNER_PHILIPS_PAL,
+		inputs: {{
+			name: name_comp1,
+			vmux: 0,
+			amux: LINE1,
+		},{
+			name: name_svideo,
+			vmux: 8,
+			amux: LINE1,
+		},{
+			name: name_tv,
+			vmux: 1,
+			amux: LINE2,
+			tv:   1,
+		}},
+		radio: {
+			name: name_radio,
+			amux: LINE2,
+		},
+		i2s_rate:  48000,
+		has_ts:    1,
+		video_out: CCIR656,
+	},
+	[SAA7134_BOARD_MONSTERTV] = {
+               /* "K.Ohta" <alpha292@bremen.or.jp> */
+               name:           "SKNet Monster TV",
+               audio_clock:    0x00187de7,
+               tuner_type:     TUNER_PHILIPS_NTSC_M,
+               inputs: {{
+                       name: name_tv,
+                       vmux: 1,
+                       amux: TV,
+                       tv:   1,
+               },{
+                       name: name_comp1,
+                       vmux: 0,
+                       amux: LINE1,
+               },{
+                       name: name_svideo,
+                       vmux: 8,
+                       amux: LINE1,
+               }},
+               radio: {
+                       name: name_radio,
+                       amux: LINE2,
+               },
+	},
+	[SAA7134_BOARD_MD9717] = {
+		name:		"Tevion MD 9717",
+		audio_clock:	0x00200000,
+		tuner_type:	TUNER_PHILIPS_PAL,
+		inputs: {{
+			name: name_tv,
+			vmux: 1,
+			amux: TV,
+			tv:   1,
+		},{
+			/* workaround for problems with normal TV sound */
+			name: "TV (mono only)",
+			vmux: 1,
+			amux: LINE2,
+			tv:   1,
+		},{
+			name: name_comp1,
+			vmux: 2,
+			amux: LINE1,
+		},{
+			name: name_comp2,
+			vmux: 3,
+			amux: LINE1,
+		},{
+			name: name_svideo,
+			vmux: 8,
+			amux: LINE1,
+		}},
+		radio: {
+			name: name_radio,
+			amux: LINE2,
+		},
+	},
+	[SAA7134_BOARD_TVSTATION_RDS] = {
+		name:		"KNC One TV-Station RDS",
+		audio_clock:	0x00200000,
+		tuner_type:	TUNER_PHILIPS_FM1216ME_MK3,
+		need_tda9887:   1,
+		inputs: {{
+			name: name_tv,
+			vmux: 1,
+			amux: TV,
+			tv:   1,
+		},{
+			name: name_comp1,
+			vmux: 2,
+			amux: LINE1,
+		},{
+			name: name_comp2,
+			vmux: 3,
+			amux: LINE1,
+		}},
+		radio: {
+			name: name_radio,
+			amux: LINE2,
+		},
+	},
+	[SAA7134_BOARD_CINERGY400] = {
+                name:           "Terratec Cinergy 400 TV",
+                audio_clock:    0x00200000,
+                tuner_type:     TUNER_PHILIPS_PAL,
+                inputs: {{
+                        name: name_tv,
+                        vmux: 1,
+                        amux: TV,
+                        tv:   1,
+                },{
+                        name: name_comp1,
+                        vmux: 4,
+                        amux: LINE1,
+                },{
+                        name: name_svideo,
+                        vmux: 8,
+                        amux: LINE1,
+                },{
+                        name: name_comp2, // CVideo over SVideo Connector
+                        vmux: 0,
+                        amux: LINE1,
+                }}
+        },
+	[SAA7134_BOARD_MD5044] = {
+		name:           "Medion 5044",
+		audio_clock:    0x00200000,
+		tuner_type:     TUNER_PHILIPS_FM1216ME_MK3,
+		need_tda9887:   1,
+		inputs: {{
+			name: name_tv,
+			vmux: 1,
+			amux: TV,
+			tv:   1,
+		},{
+			name: name_comp1,
+			vmux: 0,
+			amux: LINE2,
+		},{
+			name: name_comp2,
+			vmux: 3,
+			amux: LINE2,
+		},{
+			name: name_svideo,
+			vmux: 8,
+			amux: LINE2,
+		}},
+		radio: {
+			name: name_radio,
+			amux: LINE2,
+		},
+	},
+};
+const int saa7134_bcount = (sizeof(saa7134_boards)/sizeof(struct saa7134_board));
+
+/* ------------------------------------------------------------------ */
+/* PCI ids + subsystem IDs                                            */
+
+struct pci_device_id __devinitdata saa7134_pci_tbl[] = {
+	{
+		vendor:       PCI_VENDOR_ID_PHILIPS,
+		device:       PCI_DEVICE_ID_PHILIPS_SAA7134,
+		subvendor:    PCI_VENDOR_ID_PHILIPS,
+		subdevice:    0x2001,
+		driver_data:  SAA7134_BOARD_PROTEUS_PRO,
+        },{
+		vendor:       PCI_VENDOR_ID_PHILIPS,
+		device:       PCI_DEVICE_ID_PHILIPS_SAA7134,
+		subvendor:    PCI_VENDOR_ID_PHILIPS,
+		subdevice:    0x6752,
+		driver_data:  SAA7134_BOARD_EMPRESS,
+	},{
+		vendor:       PCI_VENDOR_ID_PHILIPS,
+		device:       PCI_DEVICE_ID_PHILIPS_SAA7134,
+                subvendor:    0x1131,
+                subdevice:    0x4e85,
+		driver_data:  SAA7134_BOARD_MONSTERTV,
+        },{
+                vendor:       PCI_VENDOR_ID_PHILIPS,
+                device:       PCI_DEVICE_ID_PHILIPS_SAA7134,
+                subvendor:    0x153B,
+                subdevice:    0x1142,
+                driver_data:  SAA7134_BOARD_CINERGY400,
+        },{
+
+		/* --- boards without eeprom + subsystem ID --- */
+                vendor:       PCI_VENDOR_ID_PHILIPS,
+                device:       PCI_DEVICE_ID_PHILIPS_SAA7134,
+                subvendor:    PCI_VENDOR_ID_PHILIPS,
+		subdevice:    0,
+		driver_data:  SAA7134_BOARD_NOAUTO,
+        },{
+                vendor:       PCI_VENDOR_ID_PHILIPS,
+                device:       PCI_DEVICE_ID_PHILIPS_SAA7130,
+                subvendor:    PCI_VENDOR_ID_PHILIPS,
+		subdevice:    0,
+		driver_data:  SAA7134_BOARD_NOAUTO,
+	},{
+		
+		/* --- default catch --- */
+		vendor:       PCI_VENDOR_ID_PHILIPS,
+		device:       PCI_DEVICE_ID_PHILIPS_SAA7130,
+                subvendor:    PCI_ANY_ID,
+                subdevice:    PCI_ANY_ID,
+		driver_data:  SAA7134_BOARD_UNKNOWN,
+        },{
+		vendor:       PCI_VENDOR_ID_PHILIPS,
+		device:       PCI_DEVICE_ID_PHILIPS_SAA7134,
+                subvendor:    PCI_ANY_ID,
+                subdevice:    PCI_ANY_ID,
+		driver_data:  SAA7134_BOARD_UNKNOWN,
+	},{
+		/* --- end of list --- */
+	}
+};
+MODULE_DEVICE_TABLE(pci, saa7134_pci_tbl);
+
+/* ----------------------------------------------------------- */
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff -Nru a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/media/video/saa7134/saa7134-core.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,928 @@
+/*
+ * device driver for philips saa7134 based TV cards
+ * driver core
+ *
+ * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/kmod.h>
+#include <linux/sound.h>
+#include <linux/interrupt.h>
+
+#include "saa7134-reg.h"
+#include "saa7134.h"
+#include "tuner.h"
+
+MODULE_DESCRIPTION("v4l2 driver module for saa7130/34 based TV cards");
+MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
+MODULE_LICENSE("GPL");
+
+#define SAA7134_MAXBOARDS 4
+
+/* ------------------------------------------------------------------ */
+
+static unsigned int irq_debug = 0;
+MODULE_PARM(irq_debug,"i");
+MODULE_PARM_DESC(irq_debug,"enable debug messages [IRQ handler]");
+
+static unsigned int core_debug = 0;
+MODULE_PARM(core_debug,"i");
+MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
+
+static unsigned int gpio_tracking = 0;
+MODULE_PARM(gpio_tracking,"i");
+MODULE_PARM_DESC(gpio_tracking,"enable debug messages [gpio]");
+
+static unsigned int video_nr = -1;
+MODULE_PARM(video_nr,"i");
+MODULE_PARM_DESC(video_nr,"video device number");
+
+static unsigned int ts_nr = -1;
+MODULE_PARM(ts_nr,"i");
+MODULE_PARM_DESC(ts_nr,"ts device number");
+
+static unsigned int vbi_nr = -1;
+MODULE_PARM(vbi_nr,"i");
+MODULE_PARM_DESC(vbi_nr,"vbi device number");
+
+static unsigned int radio_nr = -1;
+MODULE_PARM(radio_nr,"i");
+MODULE_PARM_DESC(radio_nr,"radio device number");
+
+static unsigned int dsp_nr = -1;
+MODULE_PARM(dsp_nr,"i");
+MODULE_PARM_DESC(dsp_nr,"oss dsp device number");
+
+static unsigned int mixer_nr = -1;
+MODULE_PARM(mixer_nr,"i");
+MODULE_PARM_DESC(mixer_nr,"oss mixer device number");
+
+static int tuner[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = -1};
+MODULE_PARM(tuner,"1-" __stringify(SAA7134_MAXBOARDS) "i");
+MODULE_PARM_DESC(tuner,"tuner type");
+
+static int card[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = -1};
+MODULE_PARM(card,"1-" __stringify(SAA7134_MAXBOARDS) "i");
+MODULE_PARM_DESC(card,"card type");
+
+static int latency = -1;
+MODULE_PARM(latency,"i");
+MODULE_PARM_DESC(latency,"pci latency timer");
+
+struct list_head  saa7134_devlist;
+int               saa7134_devcount;
+
+#define dprintk(fmt, arg...)	if (core_debug) \
+	printk(KERN_DEBUG "%s/core: " fmt, dev->name, ## arg)
+
+/* ------------------------------------------------------------------ */
+/* debug help functions                                               */
+
+static const char *v4l1_ioctls[] = {
+	"0", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",
+	"CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
+	"SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
+	"GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
+	"SMICROCODE", "GVBIFMT", "SVBIFMT" };
+#define V4L1_IOCTLS (sizeof(v4l1_ioctls)/sizeof(char*))
+
+static const char *v4l2_ioctls[] = {
+	"QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT",
+	"G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF",
+	"G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON",
+	"STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD",
+	"ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER",
+	"G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL",
+	"QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43",
+	"44", "45",  "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT",
+	"S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR",
+	"S_MODULATOR"
+};
+#define V4L2_IOCTLS (sizeof(v4l2_ioctls)/sizeof(char*))
+
+static const char *osspcm_ioctls[] = {
+	"RESET", "SYNC", "SPEED", "STEREO", "GETBLKSIZE", "SETFMT",
+	"CHANNELS", "?", "POST", "SUBDIVIDE", "SETFRAGMENT", "GETFMTS",
+	"GETOSPACE", "GETISPACE", "NONBLOCK", "GETCAPS", "GET/SETTRIGGER",
+	"GETIPTR", "GETOPTR", "MAPINBUF", "MAPOUTBUF", "SETSYNCRO",
+	"SETDUPLEX", "GETODELAY"
+};
+#define OSSPCM_IOCTLS (sizeof(v4l2_ioctls)/sizeof(char*))
+
+void saa7134_print_ioctl(char *name, unsigned int cmd)
+{
+	char *dir;
+
+	switch (_IOC_DIR(cmd)) {
+	case _IOC_NONE:              dir = "--"; break;
+	case _IOC_READ:              dir = "r-"; break;
+	case _IOC_WRITE:             dir = "-w"; break;
+	case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
+	default:                     dir = "??"; break;
+	}
+	switch (_IOC_TYPE(cmd)) {
+	case 'v':
+		printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n",
+		       name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
+		       v4l1_ioctls[_IOC_NR(cmd)] : "???");
+		break;
+	case 'V':
+		printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n",
+		       name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ?
+		       v4l2_ioctls[_IOC_NR(cmd)] : "???");
+		break;
+	case 'P':
+		printk(KERN_DEBUG "%s: ioctl 0x%08x (oss dsp, %s, SNDCTL_DSP_%s)\n",
+		       name, cmd, dir, (_IOC_NR(cmd) < OSSPCM_IOCTLS) ?
+		       osspcm_ioctls[_IOC_NR(cmd)] : "???");
+		break;
+	case 'M':
+		printk(KERN_DEBUG "%s: ioctl 0x%08x (oss mixer, %s, #%d)\n",
+		       name, cmd, dir, _IOC_NR(cmd));
+		break;
+	default:
+		printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n",
+		       name, cmd, dir, _IOC_NR(cmd));
+	}
+}
+
+void saa7134_track_gpio(struct saa7134_dev *dev, char *msg)
+{
+	unsigned long mode,status;
+
+	if (!gpio_tracking)
+		return;
+	/* rising SAA7134_GPIO_GPRESCAN reads the status */
+	saa_andorb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN,0);
+	saa_andorb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN,SAA7134_GPIO_GPRESCAN);
+	mode   = saa_readl(SAA7134_GPIO_GPMODE0   >> 2) & 0xfffffff;
+	status = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & 0xfffffff;
+	printk(KERN_DEBUG
+	       "%s: gpio: mode=0x%07lx in=0x%07lx out=0x%07lx [%s]\n",
+	       dev->name, mode, (~mode) & status, mode & status, msg);
+}
+
+/* ------------------------------------------------------------------ */
+
+#if 0
+static char *dec1_bits[8] = {
+	"DCSTD0", "DCSCT1", "WIPA", "GLIMB",
+	"GLIMT", "SLTCA", "HLCK"
+};
+static char *dec2_bits[8] = {
+	"RDCAP", "COPRO", "COLSTR", "TYPE3",
+	NULL, "FIDT", "HLVLN", "INTL"
+};
+static char *scale1_bits[8] = {
+	"VID_A", "VBI_A", NULL, NULL, "VID_B", "VBI_B"
+};
+static char *scale2_bits[8] = {
+	"TRERR", "CFERR", "LDERR", "WASRST",
+	"FIDSCI", "FIDSCO", "D6^D5", "TASK"
+};
+
+static void dump_statusreg(struct saa7134_dev *dev, int reg,
+			   char *regname, char **bits)
+{
+	int value,i;
+
+	value = saa_readb(reg);
+	printk(KERN_DEBUG "%s: %s:", dev->name, regname);
+	for (i = 7; i >= 0; i--) {
+		if (NULL == bits[i])
+			continue;
+		printk(" %s=%d", bits[i], (value & (1 << i)) ? 1 : 0);
+	}
+	printk("\n");
+}
+
+static void dump_statusregs(struct saa7134_dev *dev)
+{
+	dump_statusreg(dev,SAA7134_STATUS_VIDEO1,"dec1",dec1_bits);
+	dump_statusreg(dev,SAA7134_STATUS_VIDEO2,"dec2",dec2_bits);
+	dump_statusreg(dev,SAA7134_SCALER_STATUS0,"scale0",scale1_bits);
+	dump_statusreg(dev,SAA7134_SCALER_STATUS1,"scale1",scale2_bits);
+}
+#endif
+
+/* ------------------------------------------------------------------ */
+
+/* nr of (saa7134-)pages for the given buffer size */
+int saa7134_buffer_pages(int size)
+{
+	size  = PAGE_ALIGN(size);
+	size += PAGE_SIZE; /* for non-page-aligned buffers */
+	size /= 4096;
+	return size;
+}
+
+/* calc max # of buffers from size (must not exceed the 4MB virtual
+ * address space per DMA channel) */
+int saa7134_buffer_count(int size, int count)
+{
+	int maxcount;
+	
+	maxcount = 1024 / saa7134_buffer_pages(size);
+	if (count > maxcount)
+		count = maxcount;
+	return count;
+}
+
+int saa7134_buffer_startpage(struct saa7134_buf *buf)
+{
+	return saa7134_buffer_pages(buf->vb.bsize) * buf->vb.i;
+}
+
+unsigned long saa7134_buffer_base(struct saa7134_buf *buf)
+{
+	unsigned long base;
+
+	base  = saa7134_buffer_startpage(buf) * 4096;
+	base += buf->vb.dma.sglist[0].offset;
+	return base;
+}
+
+/* ------------------------------------------------------------------ */
+
+int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt)
+{
+        u32          *cpu;
+        dma_addr_t   dma_addr;
+	
+	cpu = pci_alloc_consistent(pci, SAA7134_PGTABLE_SIZE, &dma_addr);
+	if (NULL == cpu)
+		return -ENOMEM;
+	pt->size = SAA7134_PGTABLE_SIZE;
+	pt->cpu  = cpu;
+	pt->dma  = dma_addr;
+	return 0;
+}
+
+int saa7134_pgtable_build(struct pci_dev *pci, struct saa7134_pgtable *pt,
+			  struct scatterlist *list, int length,
+			  int startpage)
+{
+	u32   *ptr;
+	int   i,p;
+
+	BUG_ON(NULL == pt || NULL == pt->cpu);
+
+	ptr = pt->cpu + startpage;
+	for (i = 0; i < length; i++, list++)
+		for (p = 0; p * 4096 < list->length; p++, ptr++)
+			*ptr = sg_dma_address(list) - list->offset;
+	return 0;
+}
+
+void saa7134_pgtable_free(struct pci_dev *pci, struct saa7134_pgtable *pt)
+{
+	if (NULL == pt->cpu)
+		return;
+	pci_free_consistent(pci, pt->size, pt->cpu, pt->dma);
+	pt->cpu = NULL;
+}
+
+/* ------------------------------------------------------------------ */
+
+void saa7134_dma_free(struct saa7134_dev *dev,struct saa7134_buf *buf)
+{
+	if (in_interrupt())
+		BUG();
+
+	videobuf_waiton(&buf->vb,0,0);
+	videobuf_dma_pci_unmap(dev->pci, &buf->vb.dma);
+	videobuf_dma_free(&buf->vb.dma);
+	buf->vb.state = STATE_NEEDS_INIT;
+}
+
+/* ------------------------------------------------------------------ */
+
+int saa7134_buffer_queue(struct saa7134_dev *dev,
+			 struct saa7134_dmaqueue *q,
+			 struct saa7134_buf *buf)
+{
+#if DEBUG_SPINLOCKS
+	BUG_ON(!spin_is_locked(&dev->slock));
+#endif
+	
+	dprintk("buffer_queue %p\n",buf);
+	if (NULL == q->curr) {
+		q->curr = buf;
+		buf->activate(dev,buf,NULL);
+	} else {
+		list_add_tail(&buf->vb.queue,&q->queue);
+		buf->vb.state = STATE_QUEUED;
+	}
+	return 0;
+}
+
+void saa7134_buffer_finish(struct saa7134_dev *dev,
+			   struct saa7134_dmaqueue *q,
+			   int state)
+{
+#if DEBUG_SPINLOCKS
+	BUG_ON(!spin_is_locked(&dev->slock));
+#endif
+	dprintk("buffer_finish %p\n",q->curr);
+	
+	/* finish current buffer */
+	q->curr->vb.state = state;
+	do_gettimeofday(&q->curr->vb.ts);
+	wake_up(&q->curr->vb.done);
+	q->curr = NULL;
+}
+
+void saa7134_buffer_next(struct saa7134_dev *dev,
+			 struct saa7134_dmaqueue *q)
+{
+	struct saa7134_buf *buf,*next = NULL;
+
+#if DEBUG_SPINLOCKS
+	BUG_ON(!spin_is_locked(&dev->slock));
+#endif
+	BUG_ON(NULL != q->curr);
+
+	if (!list_empty(&q->queue)) {
+		/* activate next one from queue */
+		buf = list_entry(q->queue.next,struct saa7134_buf,vb.queue);
+		dprintk("buffer_next %p [prev=%p/next=%p]\n",
+			buf,q->queue.prev,q->queue.next);
+		list_del(&buf->vb.queue);
+		if (!list_empty(&q->queue))
+			next = list_entry(q->queue.next,struct saa7134_buf,
+					  vb.queue);
+		q->curr = buf;
+		buf->activate(dev,buf,next);
+		dprintk("buffer_next #2 prev=%p/next=%p\n",
+			q->queue.prev,q->queue.next);
+	} else {
+		/* nothing to do -- just stop DMA */
+		dprintk("buffer_next %p\n",NULL);
+		saa7134_set_dmabits(dev);
+		del_timer(&q->timeout);
+	}
+}
+
+void saa7134_buffer_timeout(unsigned long data)
+{
+	struct saa7134_dmaqueue *q = (struct saa7134_dmaqueue*)data;
+	struct saa7134_dev *dev = q->dev;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->slock,flags);
+	if (q->curr) {
+		dprintk("timeout on %p\n",q->curr);
+		saa7134_buffer_finish(dev,q,STATE_ERROR);
+	}
+	saa7134_buffer_next(dev,q);
+	spin_unlock_irqrestore(&dev->slock,flags);
+}
+
+/* ------------------------------------------------------------------ */
+
+int saa7134_set_dmabits(struct saa7134_dev *dev)
+{
+	unsigned long task=0, ctrl=0, irq=0, split = 0;
+	enum v4l2_field cap = V4L2_FIELD_ANY;
+	enum v4l2_field ov  = V4L2_FIELD_ANY;
+
+#if DEBUG_SPINLOCKS
+	BUG_ON(!spin_is_locked(&dev->slock));
+#endif
+
+	/* video capture -- dma 0 + video task A */
+	if (dev->video_q.curr) {
+		task |= 0x01;
+		ctrl |= SAA7134_MAIN_CTRL_TE0;
+		irq  |= SAA7134_IRQ1_INTE_RA0_1 |
+			SAA7134_IRQ1_INTE_RA0_0;
+	        cap = dev->video_q.curr->vb.field;
+	}
+
+	/* video capture -- dma 1+2 (planar modes) */
+	if (dev->video_q.curr &&
+	    dev->video_q.curr->fmt->planar) {
+		ctrl |= SAA7134_MAIN_CTRL_TE4 |
+			SAA7134_MAIN_CTRL_TE5;
+	}
+
+	/* screen overlay -- dma 0 + video task B */
+	if (dev->ovenable) {
+		task |= 0x10;
+		ctrl |= SAA7134_MAIN_CTRL_TE1;
+		ov = dev->ovfield;
+	}
+
+	/* vbi capture -- dma 0 + vbi task A+B */
+	if (dev->vbi_q.curr) {
+		task |= 0x22;
+		ctrl |= SAA7134_MAIN_CTRL_TE2 |
+			SAA7134_MAIN_CTRL_TE3;
+		irq  |= SAA7134_IRQ1_INTE_RA0_7 |
+			SAA7134_IRQ1_INTE_RA0_6 |
+			SAA7134_IRQ1_INTE_RA0_5 |
+			SAA7134_IRQ1_INTE_RA0_4;
+	}
+
+	/* audio capture -- dma 3 */
+	if (dev->oss.recording) {
+		ctrl |= SAA7134_MAIN_CTRL_TE6;
+		irq  |= SAA7134_IRQ1_INTE_RA3_1 |
+			SAA7134_IRQ1_INTE_RA3_0;
+	}
+
+	/* TS capture -- dma 5 */
+	if (dev->ts_q.curr) {
+		ctrl |= SAA7134_MAIN_CTRL_TE5;
+		irq  |= SAA7134_IRQ1_INTE_RA2_3 |
+			SAA7134_IRQ1_INTE_RA2_2 |
+			SAA7134_IRQ1_INTE_RA2_1 |
+			SAA7134_IRQ1_INTE_RA2_0;
+	}
+	
+	/* set task conditions + field handling */
+	if (V4L2_FIELD_HAS_BOTH(cap) || V4L2_FIELD_HAS_BOTH(ov) || cap == ov) {
+		/* default config -- use full frames:
+		   odd A, even A, odd B, even B, repeat */
+		saa_writeb(SAA7134_TASK_CONDITIONS(TASK_A), 0x0d);
+		saa_writeb(SAA7134_TASK_CONDITIONS(TASK_B), 0x0d);
+		saa_writeb(SAA7134_FIELD_HANDLING(TASK_A),  0x02);
+		saa_writeb(SAA7134_FIELD_HANDLING(TASK_B),  0x02);
+	} else {
+		/* split fields between tasks */
+		if (V4L2_FIELD_TOP == cap) {
+			/* odd A, even B, repeat */
+			saa_writeb(SAA7134_TASK_CONDITIONS(TASK_A), 0x0d);
+			saa_writeb(SAA7134_TASK_CONDITIONS(TASK_B), 0x0e);
+		} else {
+			/* odd B, even A, repeat */
+			saa_writeb(SAA7134_TASK_CONDITIONS(TASK_A), 0x0e);
+			saa_writeb(SAA7134_TASK_CONDITIONS(TASK_B), 0x0d);
+		}
+		saa_writeb(SAA7134_FIELD_HANDLING(TASK_A),  0x01);
+		saa_writeb(SAA7134_FIELD_HANDLING(TASK_B),  0x01);
+		split = 1;
+	}
+	
+	/* irqs */
+	saa_writeb(SAA7134_REGION_ENABLE, task);
+	saa_writel(SAA7134_IRQ1,          irq);
+	saa_andorl(SAA7134_MAIN_CTRL,
+		   SAA7134_MAIN_CTRL_TE0 |
+		   SAA7134_MAIN_CTRL_TE1 |
+		   SAA7134_MAIN_CTRL_TE2 |
+		   SAA7134_MAIN_CTRL_TE3 |
+		   SAA7134_MAIN_CTRL_TE4 |
+		   SAA7134_MAIN_CTRL_TE5 |
+		   SAA7134_MAIN_CTRL_TE6,
+		   ctrl);
+	dprintk("dmabits: task=0x%02lx ctrl=0x%02lx irq=0x%lx split=%s\n",
+		task, ctrl, irq, split ? "no" : "yes");
+
+	return 0;
+}
+
+/* ------------------------------------------------------------------ */
+/* IRQ handler + helpers                                              */
+
+static char *irqbits[] = {
+	"DONE_RA0", "DONE_RA1", "DONE_RA2", "DONE_RA3",
+	"AR", "PE", "PWR_ON", "RDCAP", "INTL", "FIDT", "MMC",
+	"TRIG_ERR", "CONF_ERR", "LOAD_ERR"
+};
+#define IRQBITS (sizeof(irqbits)/sizeof(char*))
+
+static void print_irqstatus(struct saa7134_dev *dev, int loop,
+			    unsigned long report, unsigned long status)
+{
+	int i;
+	
+	printk(KERN_DEBUG "%s/irq[%d,%ld]: r=0x%lx s=0x%02lx",
+	       dev->name,loop,jiffies,report,status);
+	for (i = 0; i < IRQBITS; i++) {
+		if (!(report & (1 << i)))
+			continue;
+		printk(" %s",irqbits[i]);
+	}
+	if (report & SAA7134_IRQ_REPORT_DONE_RA0) {
+		printk(" | RA0=%s,%s,%s,%ld",
+		       (status & 0x40) ? "vbi"  : "video",
+		       (status & 0x20) ? "b"    : "a",
+		       (status & 0x10) ? "odd"  : "even",
+		       (status & 0x0f));
+	}
+	printk("\n");
+}
+
+static void saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct saa7134_dev *dev = (struct saa7134_dev*) dev_id;
+	unsigned long report,status;
+	int loop;
+
+	for (loop = 0; loop < 10; loop++) {
+		report = saa_readl(SAA7134_IRQ_REPORT);
+		status = saa_readl(SAA7134_IRQ_STATUS);
+		saa_writel(SAA7134_IRQ_REPORT,report);
+		if (0 == report) {
+			if (irq_debug > 1)
+				printk(KERN_DEBUG "%s/irq: no (more) work\n",
+				       dev->name);
+			return;
+		}
+		if (irq_debug)
+			print_irqstatus(dev,loop,report,status);
+
+#if 0
+		if (report & SAA7134_IRQ_REPORT_CONF_ERR)
+			dump_statusregs(dev);
+#endif
+
+		if (report & SAA7134_IRQ_REPORT_INTL)
+			saa7134_irq_video_intl(dev);
+
+		if ((report & SAA7134_IRQ_REPORT_DONE_RA0) &&
+		    (status & 0x60) == 0)
+			saa7134_irq_video_done(dev,status);
+
+		if ((report & SAA7134_IRQ_REPORT_DONE_RA0) &&
+		    (status & 0x40) == 0x40)
+			saa7134_irq_vbi_done(dev,status);
+
+		if ((report & SAA7134_IRQ_REPORT_DONE_RA2) &&
+		    card_has_ts(dev))
+			saa7134_irq_ts_done(dev,status);
+
+		if ((report & SAA7134_IRQ_REPORT_DONE_RA3))
+			saa7134_irq_oss_done(dev,status);
+
+	};
+	if (10 == loop) {
+		print_irqstatus(dev,loop,report,status);
+		printk(KERN_WARNING "%s/irq: looping -- clearing enable bits\n",dev->name);
+		/* disable all irqs */
+		saa_writel(SAA7134_IRQ1,0);
+		saa_writel(SAA7134_IRQ2,0);
+	}
+}
+
+/* ------------------------------------------------------------------ */
+
+static int saa7134_hwinit(struct saa7134_dev *dev)
+{
+        init_MUTEX(&dev->lock);
+	dev->slock = SPIN_LOCK_UNLOCKED;
+
+	saa7134_track_gpio(dev,"pre-init");
+	saa7134_tvaudio_init(dev);
+	saa7134_video_init(dev);
+	saa7134_vbi_init(dev);
+	if (card_has_ts(dev))
+		saa7134_ts_init(dev);
+	if (card_has_audio(dev))
+		saa7134_oss_init(dev);
+	
+	/* RAM FIFO config */
+	saa_writel(SAA7134_FIFO_SIZE, 0x08070503);
+	saa_writel(SAA7134_THRESHOULD,0x02020202);
+	
+	/* enable audio + video processing */
+	saa_writel(SAA7134_MAIN_CTRL,
+		   SAA7134_MAIN_CTRL_VPLLE |
+		   SAA7134_MAIN_CTRL_APLLE |
+		   SAA7134_MAIN_CTRL_EXOSC |
+		   SAA7134_MAIN_CTRL_EVFE1 |
+		   SAA7134_MAIN_CTRL_EVFE2 |
+		   SAA7134_MAIN_CTRL_ESFE  |
+		   SAA7134_MAIN_CTRL_EBADC |
+		   SAA7134_MAIN_CTRL_EBDAC);
+
+	/* IRQ's */
+	saa_writel(SAA7134_IRQ1, 0);
+	saa_writel(SAA7134_IRQ2,
+		   SAA7134_IRQ2_INTE_SC2  |
+		   SAA7134_IRQ2_INTE_SC1  |
+		   SAA7134_IRQ2_INTE_SC0  |
+		   /* SAA7134_IRQ2_INTE_DEC5 |  FIXME: TRIG_ERR ??? */
+		   SAA7134_IRQ2_INTE_DEC3 |
+		   SAA7134_IRQ2_INTE_DEC2 |
+		   /* SAA7134_IRQ2_INTE_DEC1 | */
+		   SAA7134_IRQ2_INTE_DEC0 |
+		   SAA7134_IRQ2_INTE_PE |
+		   SAA7134_IRQ2_INTE_AR);
+
+	/* enable peripheral devices */
+	saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
+
+	return 0;
+}
+
+static void __devinit must_configure_manually(void)
+{
+	int i,p;
+
+	printk(KERN_WARNING
+	       "saa7134: <rant>\n"
+	       "saa7134:  Congratulations!  Your TV card vendor saved a few\n"
+	       "saa7134:  cents for a eeprom, thus your pci board has no\n"
+	       "saa7134:  subsystem ID and I can't identify it automatically\n"
+	       "saa7134: </rant>\n"
+	       "saa7134: I feel better now.  Ok, here are the good news:\n"
+	       "saa7134: You can use the card=<nr> insmod option to specify\n"
+	       "saa7134: which board do you have.  The list:\n");
+	for (i = 0; i < saa7134_bcount; i++) {
+		printk(KERN_WARNING "saa7134:   card=%d -> %-40.40s",
+		       i,saa7134_boards[i].name);
+		for (p = 0; saa7134_pci_tbl[p].driver_data; p++) {
+			if (saa7134_pci_tbl[p].driver_data != i)
+				continue;
+			printk(" %04x:%04x",
+			       saa7134_pci_tbl[p].subvendor,
+			       saa7134_pci_tbl[p].subdevice);
+		}
+		printk("\n");
+	}
+}
+
+static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
+				     const struct pci_device_id *pci_id)
+{
+	struct saa7134_dev *dev;
+	int err;
+
+	dev = kmalloc(sizeof(*dev),GFP_KERNEL);
+	if (NULL == dev)
+		return -ENOMEM;
+	memset(dev,0,sizeof(*dev));
+
+	/* pci stuff */
+	dev->pci = pci_dev;
+	if (pci_enable_device(pci_dev)) {
+		err = -EIO;
+		goto fail1;
+	}
+	sprintf(dev->name,"saa%x[%d]",pci_dev->device,saa7134_devcount);
+	if (-1 != latency) {
+		printk(KERN_INFO "%s: setting pci latency timer to %d\n",
+		       dev->name,latency);
+		pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, latency);
+	}
+	pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
+        pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER,  &dev->pci_lat);
+        printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, "
+	       "latency: %d, mmio: 0x%lx\n", dev->name,
+	       pci_dev->slot_name, dev->pci_rev, pci_dev->irq,
+	       dev->pci_lat,pci_resource_start(pci_dev,0));
+	pci_set_master(pci_dev);
+	if (!pci_dma_supported(pci_dev,0xffffffff)) {
+		printk("%s: Oops: no 32bit PCI DMA ???\n",dev->name);
+		err = -EIO;
+		goto fail1;
+	}
+
+	/* board config */
+	dev->board = pci_id->driver_data;
+	if (card[saa7134_devcount] >= 0 &&
+	    card[saa7134_devcount] < saa7134_bcount)
+		dev->board = card[saa7134_devcount];
+	if (SAA7134_BOARD_NOAUTO == dev->board) {
+		must_configure_manually();
+		dev->board = SAA7134_BOARD_UNKNOWN;
+	}
+	dev->tuner_type = saa7134_boards[dev->board].tuner_type;
+	if (-1 != tuner[saa7134_devcount])
+		dev->tuner_type = tuner[saa7134_devcount];
+        printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
+	       dev->name,pci_dev->subsystem_vendor,
+	       pci_dev->subsystem_device,saa7134_boards[dev->board].name,
+	       dev->board, card[saa7134_devcount] == dev->board ?
+	       "insmod option" : "autodetected");
+
+	/* get mmio */
+	if (!request_mem_region(pci_resource_start(pci_dev,0),
+				pci_resource_len(pci_dev,0),
+				dev->name)) {
+		err = -EBUSY;
+		printk(KERN_ERR "%s: can't get MMIO memory @ 0x%lx\n",
+		       dev->name,pci_resource_start(pci_dev,0));
+		goto fail1;
+	}
+	dev->lmmio = ioremap(pci_resource_start(pci_dev,0), 0x1000);
+	dev->bmmio = (__u8*)dev->lmmio;
+
+	/* get irq */
+	err = request_irq(pci_dev->irq, saa7134_irq,
+			  SA_SHIRQ | SA_INTERRUPT, dev->name, dev);
+	if (err < 0) {
+		printk(KERN_ERR "%s: can't get IRQ %d\n",
+		       dev->name,pci_dev->irq);
+		goto fail2;
+	}
+
+	/* initialize hardware */
+	saa7134_hwinit(dev);
+
+	/* register i2c bus + load i2c helpers */
+	saa7134_i2c_register(dev);
+	if (TUNER_ABSENT != card(dev).tuner_type)
+		request_module("tuner");
+	if (saa7134_boards[dev->board].need_tda9887)
+		request_module("tda9887");
+
+	/* register v4l devices */
+	dev->video_dev = saa7134_video_template;
+	dev->video_dev.priv = dev;
+	err = video_register_device(&dev->video_dev,VFL_TYPE_GRABBER,video_nr);
+	if (err < 0) {
+		printk(KERN_INFO "%s: can't register video device\n",
+		       dev->name);
+		goto fail3;
+	}
+	printk(KERN_INFO "%s: registered device video%d [v4l2]\n",
+	       dev->name,dev->video_dev.minor & 0x1f);
+
+	dev->ts_dev = saa7134_ts_template;
+	dev->ts_dev.priv = dev;
+	if (card_has_ts(dev)) {
+		err = video_register_device(&dev->ts_dev,VFL_TYPE_GRABBER,ts_nr);
+		if (err < 0) {
+			printk(KERN_INFO "%s: can't register video device\n",
+			       dev->name);
+			goto fail4;
+		}
+		printk(KERN_INFO "%s: registered device video%d [ts]\n",
+		       dev->name,dev->ts_dev.minor & 0x1f);
+	}
+	
+	dev->vbi_dev = saa7134_vbi_template;
+	dev->vbi_dev.priv = dev;
+	err = video_register_device(&dev->vbi_dev,VFL_TYPE_VBI,vbi_nr);
+	if (err < 0)
+		goto fail5;
+	printk(KERN_INFO "%s: registered device vbi%d\n",
+	       dev->name,dev->vbi_dev.minor & 0x1f);
+
+	dev->radio_dev = saa7134_radio_template;
+	dev->radio_dev.priv = dev;
+	if (card_has_radio(dev)) {
+		err = video_register_device(&dev->radio_dev,VFL_TYPE_RADIO,radio_nr);
+		if (err < 0)
+			goto fail6;
+		printk(KERN_INFO "%s: registered device radio%d\n",
+		       dev->name,dev->radio_dev.minor & 0x1f);
+	}
+
+	/* register oss devices */
+	if (card_has_audio(dev)) {
+		dev->oss.minor_dsp = register_sound_dsp(&saa7134_dsp_fops,dsp_nr);
+		if (dev->oss.minor_dsp < 0)
+			goto fail7;
+		printk(KERN_INFO "%s: registered device dsp%d\n",
+		       dev->name,dev->oss.minor_dsp >> 4);
+		
+		dev->oss.minor_mixer =
+			register_sound_mixer(&saa7134_mixer_fops,mixer_nr);
+		if (dev->oss.minor_mixer < 0)
+			goto fail8;
+		printk(KERN_INFO "%s: registered device mixer%d\n",
+		       dev->name,dev->oss.minor_mixer >> 4);
+	}
+
+	/* everything worked */
+	list_add_tail(&dev->devlist,&saa7134_devlist);
+	pci_set_drvdata(pci_dev,dev);
+	saa7134_devcount++;
+	return 0;
+
+ fail8:
+	if (card_has_audio(dev))
+		unregister_sound_dsp(dev->oss.minor_dsp);
+ fail7:
+	if (card_has_radio(dev))
+		video_unregister_device(&dev->radio_dev);
+ fail6:
+	video_unregister_device(&dev->vbi_dev);
+ fail5:
+ 	if (card_has_ts(dev))
+  		video_unregister_device(&dev->ts_dev);
+ fail4:
+	video_unregister_device(&dev->video_dev);
+ fail3:
+	if (card_has_audio(dev))
+		saa7134_oss_fini(dev);
+	if (card_has_ts(dev))
+		saa7134_ts_fini(dev);
+	saa7134_vbi_fini(dev);
+	saa7134_video_fini(dev);
+	saa7134_tvaudio_fini(dev);
+	saa7134_i2c_unregister(dev);
+	free_irq(pci_dev->irq, dev);
+ fail2:
+	release_mem_region(pci_resource_start(pci_dev,0),
+			   pci_resource_len(pci_dev,0));
+ fail1:
+	kfree(dev);
+	return err;
+}
+
+static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
+{
+        struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
+
+	/* disable peripheral devices */
+	saa_writeb(SAA7134_SPECIAL_MODE,0);
+
+	/* shutdown hardware */
+	saa_writel(SAA7134_IRQ1,0);
+	saa_writel(SAA7134_IRQ2,0);
+	saa_writel(SAA7134_MAIN_CTRL,0);
+
+	/* shutdown subsystems */
+	if (card_has_audio(dev))
+		saa7134_oss_fini(dev);
+	if (card_has_ts(dev))
+		saa7134_ts_fini(dev);
+	saa7134_vbi_fini(dev);
+	saa7134_video_fini(dev);
+	saa7134_tvaudio_fini(dev);
+	saa7134_i2c_unregister(dev);
+
+	/* release ressources */
+	free_irq(pci_dev->irq, dev);
+	release_mem_region(pci_resource_start(pci_dev,0),
+			   pci_resource_len(pci_dev,0));
+
+	/* unregister */
+	saa7134_i2c_unregister(dev);
+	if (card_has_audio(dev)) {
+		unregister_sound_mixer(dev->oss.minor_mixer);
+		unregister_sound_dsp(dev->oss.minor_dsp);
+	}
+	if (card_has_radio(dev))
+		video_unregister_device(&dev->radio_dev);
+	video_unregister_device(&dev->vbi_dev);
+	if (card_has_ts(dev))
+		video_unregister_device(&dev->ts_dev);
+	video_unregister_device(&dev->video_dev);
+	pci_set_drvdata(pci_dev, NULL);
+#if 0
+	/* causes some trouble when reinserting the driver ... */
+	pci_disable_device(pci_dev);
+#endif
+
+	/* free memory */
+	list_del(&dev->devlist);
+	saa7134_devcount--;
+	kfree(dev);
+}
+
+static struct pci_driver saa7134_pci_driver = {
+        name:     "saa7134",
+        id_table: saa7134_pci_tbl,
+        probe:    saa7134_initdev,
+        remove:   saa7134_finidev,
+};
+
+static int saa7134_init(void)
+{
+	INIT_LIST_HEAD(&saa7134_devlist);
+	printk(KERN_INFO "saa7130/34: v4l2 driver version %d.%d.%d loaded\n",
+	       (SAA7134_VERSION_CODE >> 16) & 0xff,
+	       (SAA7134_VERSION_CODE >>  8) & 0xff,
+	       SAA7134_VERSION_CODE & 0xff);
+	return pci_module_init(&saa7134_pci_driver);
+}
+
+static void saa7134_fini(void)
+{
+	pci_unregister_driver(&saa7134_pci_driver);
+}
+
+module_init(saa7134_init);
+module_exit(saa7134_fini);
+
+/* ----------------------------------------------------------- */
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff -Nru a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/media/video/saa7134/saa7134-i2c.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,451 @@
+/*
+ * device driver for philips saa7134 based TV cards
+ * i2c interface support
+ *
+ * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define __NO_VERSION__ 1
+
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+
+#include "saa7134-reg.h"
+#include "saa7134.h"
+#include "tuner.h"
+#include "id.h"
+
+/* ----------------------------------------------------------- */
+
+static unsigned int i2c_debug = 0;
+MODULE_PARM(i2c_debug,"i");
+MODULE_PARM_DESC(i2c_debug,"enable debug messages [i2c]");
+
+static unsigned int i2c_scan = 0;
+MODULE_PARM(i2c_scan,"i");
+MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
+
+#define d1printk if (1 == i2c_debug) printk
+#define d2printk if (2 == i2c_debug) printk
+
+#define I2C_WAIT_DELAY  32
+#define I2C_WAIT_RETRY  16
+
+/* ----------------------------------------------------------- */
+
+static char *str_i2c_status[] = {
+	"IDLE", "DONE_STOP", "BUSY", "TO_SCL", "TO_ARB", "DONE_WRITE",
+	"DONE_READ", "DONE_WRITE_TO", "DONE_READ_TO", "NO_DEVICE",
+	"NO_ACKN", "BUS_ERR", "ARB_LOST", "SEQ_ERR", "ST_ERR", "SW_ERR"
+};
+
+enum i2c_status {
+	IDLE          = 0,  // no I2C command pending
+	DONE_STOP     = 1,  // I2C command done and STOP executed
+	BUSY          = 2,  // executing I2C command
+	TO_SCL        = 3,  // executing I2C command, time out on clock stretching
+	TO_ARB        = 4,  // time out on arbitration trial, still trying
+	DONE_WRITE    = 5,  // I2C command done and awaiting next write command
+	DONE_READ     = 6,  // I2C command done and awaiting next read command
+	DONE_WRITE_TO = 7,  // see 5, and time out on status echo
+	DONE_READ_TO  = 8,  // see 6, and time out on status echo
+	NO_DEVICE     = 9,  // no acknowledge on device slave address
+	NO_ACKN       = 10, // no acknowledge after data byte transfer
+	BUS_ERR       = 11, // bus error
+	ARB_LOST      = 12, // arbitration lost during transfer
+	SEQ_ERR       = 13, // erroneous programming sequence
+	ST_ERR        = 14, // wrong status echoing
+	SW_ERR        = 15  // software error
+};
+
+static char *str_i2c_attr[] = {
+	"NOP", "STOP", "CONTINUE", "START"
+};
+
+enum i2c_attr {
+	NOP           = 0,  // no operation on I2C bus
+	STOP          = 1,  // stop condition, no associated byte transfer
+	CONTINUE      = 2,  // continue with byte transfer
+	START         = 3   // start condition with byte transfer
+};
+
+static inline enum i2c_status i2c_get_status(struct saa7134_dev *dev)
+{
+	enum i2c_status status;
+	
+	status = saa_readb(SAA7134_I2C_ATTR_STATUS) & 0x0f;
+	d2printk(KERN_DEBUG "%s: i2c stat <= %s\n",dev->name,
+		 str_i2c_status[status]);
+	return status;
+}
+
+static inline void i2c_set_status(struct saa7134_dev *dev,
+				  enum i2c_status status)
+{
+	d2printk(KERN_DEBUG "%s: i2c stat => %s\n",dev->name,
+		 str_i2c_status[status]);
+	saa_andorb(SAA7134_I2C_ATTR_STATUS,0x0f,status);
+}
+
+static inline void i2c_set_attr(struct saa7134_dev *dev, enum i2c_attr attr)
+{
+	d2printk(KERN_DEBUG "%s: i2c attr => %s\n",dev->name,
+		 str_i2c_attr[attr]);
+	saa_andorb(SAA7134_I2C_ATTR_STATUS,0xc0,attr << 6);
+}
+
+static inline int i2c_is_error(enum i2c_status status)
+{
+	switch (status) {
+	case NO_DEVICE:
+	case NO_ACKN:
+	case BUS_ERR:
+	case ARB_LOST:
+	case SEQ_ERR:
+	case ST_ERR:
+		return TRUE;
+	default:
+		return FALSE;
+	}
+}
+
+static inline int i2c_is_idle(enum i2c_status status)
+{
+	switch (status) {
+	case IDLE:
+	case DONE_STOP:
+		return TRUE;
+	default:
+		return FALSE;
+	}
+}
+
+static inline int i2c_is_busy(enum i2c_status status)
+{
+	switch (status) {
+	case BUSY:
+		return TRUE;
+	default:
+		return FALSE;
+	}
+}
+
+static int i2c_is_busy_wait(struct saa7134_dev *dev)
+{
+	enum i2c_status status;
+	int count;
+
+	for (count = 0; count < I2C_WAIT_RETRY; count++) {
+		status = i2c_get_status(dev);
+		if (!i2c_is_busy(status))
+			break;
+		if (need_resched())
+                        schedule();
+		else
+			udelay(I2C_WAIT_DELAY);
+	}
+	if (I2C_WAIT_RETRY == count)
+		return FALSE;
+	return TRUE;
+}
+
+static int i2c_reset(struct saa7134_dev *dev)
+{
+	enum i2c_status status;
+	int count;
+
+	d2printk(KERN_DEBUG "%s: i2c reset\n",dev->name);
+	status = i2c_get_status(dev);
+	if (!i2c_is_error(status))
+		return TRUE;
+	i2c_set_status(dev,status);
+
+	for (count = 0; count < I2C_WAIT_RETRY; count++) {
+		status = i2c_get_status(dev);
+		if (!i2c_is_error(status))
+			break;
+		udelay(I2C_WAIT_DELAY);
+	}
+	if (I2C_WAIT_RETRY == count)
+		return FALSE;
+
+	if (!i2c_is_idle(status))
+		return FALSE;
+	
+	i2c_set_attr(dev,NOP);
+	return TRUE;
+}
+
+static inline int i2c_send_byte(struct saa7134_dev *dev,
+				enum i2c_attr attr,
+				unsigned char data)
+{
+	enum i2c_status status;
+	__u32 dword;
+
+#if 0
+	i2c_set_attr(dev,attr);
+	saa_writeb(SAA7134_I2C_DATA, data);
+#else
+	/* have to write both attr + data in one 32bit word */
+	dword  = saa_readl(SAA7134_I2C_ATTR_STATUS >> 2);
+	dword &= 0x0f;
+	dword |= (attr << 6);
+	dword |= ((__u32)data << 8);
+	dword |= 0x00 << 16;
+	dword |= 0xf0 << 24;
+	saa_writel(SAA7134_I2C_ATTR_STATUS >> 2, dword);
+#endif
+	d2printk(KERN_DEBUG "%s: i2c data => 0x%x\n",dev->name,data);
+	
+	if (!i2c_is_busy_wait(dev))
+		return -EIO;
+	status = i2c_get_status(dev);
+	if (i2c_is_error(status))
+		return -EIO;
+	return 0;
+}
+
+static inline int i2c_recv_byte(struct saa7134_dev *dev)
+{
+	enum i2c_status status;
+	unsigned char data;
+	
+	i2c_set_attr(dev,CONTINUE);
+	if (!i2c_is_busy_wait(dev))
+		return -EIO;
+	status = i2c_get_status(dev);
+	if (i2c_is_error(status))
+		return -EIO;
+	data = saa_readb(SAA7134_I2C_DATA);
+	d2printk(KERN_DEBUG "%s: i2c data <= 0x%x\n",dev->name,data);
+	return data;
+}
+
+static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
+			    struct i2c_msg msgs[], int num)
+{
+	struct saa7134_dev *dev = i2c_adap->algo_data;
+	enum i2c_status status;
+	unsigned char data;
+	int addr,rc,i,byte;
+
+  	status = i2c_get_status(dev);
+	if (!i2c_is_idle(status))
+		if (!i2c_reset(dev))
+			return -EIO;
+
+	d1printk(KERN_DEBUG "%s: i2c xfer:",dev->name);
+	for (i = 0; i < num; i++) {
+		if (!(msgs[i].flags & I2C_M_NOSTART) || 0 == i) {
+			/* send address */
+			addr  = msgs[i].addr << 1;
+			if (msgs[i].flags & I2C_M_RD)
+				addr |= 1;
+			d1printk(" < %02x", addr);
+			rc = i2c_send_byte(dev,START,addr);
+			if (rc < 0)
+				 goto err;
+		}
+		if (msgs[i].flags & I2C_M_RD) {
+			/* read bytes */
+			for (byte = 0; byte < msgs[i].len; byte++) {
+				d1printk(" =");
+				rc = i2c_recv_byte(dev);
+				if (rc < 0)
+					goto err;
+				d1printk("%02x", rc);
+				msgs[i].buf[byte] = rc;
+			}
+		} else {
+			/* write bytes */
+			for (byte = 0; byte < msgs[i].len; byte++) {
+				data = msgs[i].buf[byte];
+				d1printk(" %02x", data);
+				rc = i2c_send_byte(dev,CONTINUE,data);
+				if (rc < 0)
+					goto err;
+			}
+		}
+	}
+	d1printk(" >");
+	i2c_set_attr(dev,STOP);
+	rc = -EIO;
+	if (!i2c_is_busy_wait(dev))
+		goto err;
+  	status = i2c_get_status(dev);
+	if (i2c_is_error(status))
+		goto err;
+
+	d1printk("\n");
+	return num;
+ err:
+	if (1 == i2c_debug) {
+		status = i2c_get_status(dev);
+		printk(" ERROR: %s\n",str_i2c_status[status]);
+	}
+	return rc;
+}
+
+/* ----------------------------------------------------------- */
+
+static int algo_control(struct i2c_adapter *adapter, 
+			unsigned int cmd, unsigned long arg)
+{
+	return 0;
+}
+
+static u32 functionality(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_SMBUS_EMUL;
+}
+
+static void inc_use(struct i2c_adapter *adap)
+{
+	MOD_INC_USE_COUNT;
+}
+
+static void dec_use(struct i2c_adapter *adap)
+{
+	MOD_DEC_USE_COUNT;
+}
+
+static int attach_inform(struct i2c_client *client)
+{
+        struct saa7134_dev *dev = client->adapter->algo_data;
+	int tuner = card(dev).tuner_type;
+
+	saa7134_i2c_call_clients(dev,TUNER_SET_TYPE,&tuner);
+        return 0;
+}
+
+static struct i2c_algorithm saa7134_algo = {
+	name:          "saa7134",
+	id:            I2C_ALGO_SAA7134,
+	master_xfer:   saa7134_i2c_xfer,
+	algo_control:  algo_control,
+	functionality: functionality,
+};
+
+static struct i2c_adapter saa7134_adap_template = {
+	name:	       "saa7134",
+	id:            I2C_ALGO_SAA7134,
+	algo:          &saa7134_algo,
+	inc_use:       inc_use,
+	dec_use:       dec_use,
+	client_register: attach_inform,
+};
+
+static struct i2c_client saa7134_client_template = {
+        name: "saa7134 internal",
+        id:   -1,
+};
+
+/* ----------------------------------------------------------- */
+
+static int
+saa7134_i2c_eeprom(struct saa7134_dev *dev, unsigned char *eedata, int len)
+{
+	unsigned char buf;
+	int i,err;
+
+	dev->i2c_client.addr = 0xa0 >> 1;
+	buf = 0;
+	if (1 != (err = i2c_master_send(&dev->i2c_client,&buf,1))) {
+		printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n",
+		       dev->name,err);
+		return -1;
+	}
+	if (len != (err = i2c_master_recv(&dev->i2c_client,eedata,len))) {
+		printk(KERN_WARNING "%s: i2c eeprom read error (err=%d)\n",
+		       dev->name,err);
+		return -1;
+	}
+	for (i = 0; i < len; i++) {
+		if (0 == (i % 16))
+			printk(KERN_INFO "%s: i2c eeprom %02x:",dev->name,i);
+		printk(" %02x",eedata[i]);
+		if (15 == (i % 16))
+			printk("\n");
+	}
+	return 0;
+}
+
+static int
+saa7134_i2c_scan(struct saa7134_dev *dev)
+{
+	unsigned char buf;
+	int i,rc;
+
+	for (i = 0; i < 256; i+= 2) {
+		dev->i2c_client.addr = i >> 1;
+		rc = i2c_master_recv(&dev->i2c_client,&buf,0);
+		if (rc < 0)
+			continue;
+		printk("%s: i2c scan: found device @ %x%s\n",
+		       dev->name, i, (i == 0xa0) ? " [eeprom]" : "");
+	}
+	return 0;
+}
+
+void saa7134_i2c_call_clients(struct saa7134_dev *dev,
+			      unsigned int cmd, void *arg)
+{
+	int i;
+
+	for (i = 0; i < I2C_CLIENT_MAX; i++) {
+		if (NULL == dev->i2c_adap.clients[i])
+			continue;
+		if (NULL == dev->i2c_adap.clients[i]->driver->command)
+			continue;
+		dev->i2c_adap.clients[i]->driver->command
+			(dev->i2c_adap.clients[i],cmd,arg);
+	}
+}
+
+int saa7134_i2c_register(struct saa7134_dev *dev)
+{
+	dev->i2c_adap = saa7134_adap_template;
+	strcpy(dev->i2c_adap.name,dev->name);
+	dev->i2c_adap.algo_data = dev;
+	i2c_add_adapter(&dev->i2c_adap);
+	
+	dev->i2c_client = saa7134_client_template;
+	dev->i2c_client.adapter = &dev->i2c_adap;
+	
+	saa7134_i2c_eeprom(dev,dev->eedata,sizeof(dev->eedata));
+	if (i2c_scan)
+		saa7134_i2c_scan(dev);
+	return 0;
+}
+
+int saa7134_i2c_unregister(struct saa7134_dev *dev)
+{
+	i2c_del_adapter(&dev->i2c_adap);
+	return 0;
+}
+
+/* ----------------------------------------------------------- */
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff -Nru a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/media/video/saa7134/saa7134-oss.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,762 @@
+/*
+ * device driver for philips saa7134 based TV cards
+ * oss dsp interface
+ *
+ * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define __NO_VERSION__ 1
+
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/soundcard.h>
+
+#include "saa7134-reg.h"
+#include "saa7134.h"
+
+/* ------------------------------------------------------------------ */
+
+static unsigned int oss_debug  = 0;
+MODULE_PARM(oss_debug,"i");
+MODULE_PARM_DESC(oss_debug,"enable debug messages [oss]");
+
+static unsigned int oss_rate  = 0;
+MODULE_PARM(oss_rate,"i");
+MODULE_PARM_DESC(oss_rate,"sample rate (valid are: 32000,48000)");
+
+#define dprintk(fmt, arg...)	if (oss_debug) \
+	printk(KERN_DEBUG "%s/oss: " fmt, dev->name, ## arg)
+
+/* ------------------------------------------------------------------ */
+
+static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
+{
+	blksize &= ~0xff;
+	if (blksize < 0x100)
+		blksize = 0x100;
+	if (blksize > 0x10000)
+		blksize = 0x100;
+
+	if (blocks < 2)
+		blocks = 2;
+        while ((blksize * blocks) & ~PAGE_MASK)
+		blocks++;
+	if ((blksize * blocks) > 1024*1024)
+		blocks = 1024*1024 / blksize;
+
+	dev->oss.blocks  = blocks;
+	dev->oss.blksize = blksize;
+	dev->oss.bufsize = blksize * blocks;
+
+	dprintk("buffer config: %d blocks / %d bytes, %d kB total\n",
+		blocks,blksize,blksize * blocks / 1024);
+	return 0;
+}
+
+static int dsp_buffer_init(struct saa7134_dev *dev)
+{
+	int err;
+
+	if (!dev->oss.bufsize)
+		BUG();
+	err = videobuf_dma_init_kernel(&dev->oss.dma, PCI_DMA_FROMDEVICE,
+				       dev->oss.bufsize >> PAGE_SHIFT);
+	if (0 != err)
+		return err;
+	return 0;
+}
+
+static int dsp_buffer_free(struct saa7134_dev *dev)
+{
+	if (!dev->oss.blksize)
+		BUG();
+	videobuf_dma_free(&dev->oss.dma);
+	dev->oss.blocks  = 0;
+	dev->oss.blksize = 0;
+	dev->oss.bufsize = 0;
+	return 0;
+}
+
+static int dsp_rec_start(struct saa7134_dev *dev)
+{
+	int err, fmt, bswap, wswap;
+	unsigned long control,flags;
+
+	/* prepare buffer */
+	if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->oss.dma)))
+		return err;
+	if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->oss.pt,
+					      dev->oss.dma.sglist,
+					      dev->oss.dma.sglen,
+					      0)))
+		goto fail1;
+
+	/* sample format */
+	switch (dev->oss.afmt) {
+	case AFMT_U8:     fmt = 0x00;         break;
+	case AFMT_S8:     fmt = 0x00 | 0x04;  break;
+	case AFMT_U16_LE:
+	case AFMT_U16_BE: fmt = 0x01;         break;
+	case AFMT_S16_LE:
+	case AFMT_S16_BE: fmt = 0x01 | 0x04;  break;
+/* 4front API specs mention these ones,
+   the (2.4.15) kernel header hasn't them ... */
+#ifdef AFMT_S32_LE
+	case AFMT_S32_LE:
+	case AFMT_S32_BE: fmt = 0x02 | 0x04;  break;
+#endif
+	default:
+		err = -EINVAL;
+		goto fail2;
+	}
+
+	switch (dev->oss.afmt) {
+	case AFMT_U16_BE:
+	case AFMT_S16_BE: bswap = 1; wswap = 0; break;
+#ifdef AFMT_S32_LE
+	case AFMT_S32_BE: bswap = 1; wswap = 1; break;
+#endif
+	default:          bswap = 0; wswap = 0; break;
+	}
+
+	if (1 == dev->oss.channels)
+		fmt |= (1 << 3);
+	if (2 == dev->oss.channels)
+		fmt |= (3 << 3);
+	fmt |= (TV == dev->oss.input) ? 0xc0 : 0x80;
+	
+	saa_writeb(SAA7134_NUM_SAMPLES0, (dev->oss.blksize & 0x0000ff));
+	saa_writeb(SAA7134_NUM_SAMPLES1, (dev->oss.blksize & 0x00ff00) >>  8);
+	saa_writeb(SAA7134_NUM_SAMPLES2, (dev->oss.blksize & 0xff0000) >> 16);
+	saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);
+	dprintk("rec_start: afmt=%d ch=%d  =>  fmt=0x%x swap=%c%c\n",
+		dev->oss.afmt, dev->oss.channels, fmt,
+		bswap ? 'b' : '-', wswap ? 'w' : '-');
+
+	/* dma: setup channel 6 (= AUDIO) */
+	control = SAA7134_RS_CONTROL_BURST_16 |
+		SAA7134_RS_CONTROL_ME |
+		(dev->oss.pt.dma >> 12);
+	if (bswap)
+		control |= SAA7134_RS_CONTROL_BSWAP;
+	if (wswap)
+		control |= SAA7134_RS_CONTROL_WSWAP;
+	saa_writel(SAA7134_RS_BA1(6),0);
+	saa_writel(SAA7134_RS_BA2(6),dev->oss.blksize);
+	saa_writel(SAA7134_RS_PITCH(6),0);
+	saa_writel(SAA7134_RS_CONTROL(6),control);
+	
+	/* start dma */
+	spin_lock_irqsave(&dev->slock,flags);
+	dev->oss.recording = 1;
+	dev->oss.dma_blk   = 0;
+	saa7134_set_dmabits(dev);
+	spin_unlock_irqrestore(&dev->slock,flags);
+	return 0;
+
+ fail2:
+	saa7134_pgtable_free(dev->pci,&dev->oss.pt);
+ fail1:
+	videobuf_dma_pci_unmap(dev->pci,&dev->oss.dma);
+	return err;
+}
+
+static int dsp_rec_stop(struct saa7134_dev *dev)
+{
+	unsigned long flags;
+
+	dprintk("rec_stop dma_blk=%d\n",dev->oss.dma_blk);
+
+	/* stop dma */
+	spin_lock_irqsave(&dev->slock,flags);
+	dev->oss.dma_blk   = -1;
+	dev->oss.recording = 0;
+	saa7134_set_dmabits(dev);
+	spin_unlock_irqrestore(&dev->slock,flags);
+
+	/* unlock buffer */
+	saa7134_pgtable_free(dev->pci,&dev->oss.pt);
+	videobuf_dma_pci_unmap(dev->pci,&dev->oss.dma);
+	return 0;
+}
+
+/* ------------------------------------------------------------------ */
+
+static int dsp_open(struct inode *inode, struct file *file)
+{
+	unsigned int minor = minor(inode->i_rdev);
+	struct saa7134_dev *h,*dev = NULL;
+	struct list_head *list;
+	int err;
+
+	list_for_each(list,&saa7134_devlist) {
+		h = list_entry(list, struct saa7134_dev, devlist);
+		if (h->oss.minor_dsp == minor)
+			dev = h;
+	}
+	if (NULL == dev)
+		return -ENODEV;
+
+	down(&dev->oss.lock);
+	err = -EBUSY;
+	if (dev->oss.users_dsp)
+		goto fail1;
+	dev->oss.users_dsp++;
+	file->private_data = dev;
+
+	dev->oss.afmt        = AFMT_U8;
+	dev->oss.channels    = 1;
+	dev->oss.read_count  = 0;
+	dev->oss.read_offset = 0;
+	dsp_buffer_conf(dev,PAGE_SIZE,64);
+	err = dsp_buffer_init(dev);
+	if (0 != err)
+		goto fail2;
+
+	up(&dev->oss.lock);
+	return 0;
+
+ fail2:
+	dev->oss.users_dsp--;
+ fail1:
+	up(&dev->oss.lock);
+	return err;
+}
+
+static int dsp_release(struct inode *inode, struct file *file)
+{
+	struct saa7134_dev *dev = file->private_data;
+
+	down(&dev->oss.lock);
+	if (dev->oss.recording)
+		dsp_rec_stop(dev);
+	dsp_buffer_free(dev);
+	dev->oss.users_dsp--;
+	file->private_data = NULL;
+	up(&dev->oss.lock);
+	return 0;
+}
+
+static ssize_t dsp_read(struct file *file, char *buffer,
+			size_t count, loff_t *ppos)
+{
+	struct saa7134_dev *dev = file->private_data;
+	DECLARE_WAITQUEUE(wait, current);
+	int bytes,err,ret = 0;
+
+	add_wait_queue(&dev->oss.wq, &wait);
+	down(&dev->oss.lock);
+	while (count > 0) {
+		/* wait for data if needed */
+		if (0 == dev->oss.read_count) {
+			if (!dev->oss.recording) {
+				err = dsp_rec_start(dev);
+				if (err < 0) {
+					if (0 == ret)
+						ret = err;
+					break;
+				}
+			}
+			if (file->f_flags & O_NONBLOCK) {
+				if (0 == ret)
+					ret = -EAGAIN;
+				break;
+			}
+			up(&dev->oss.lock);
+			current->state = TASK_INTERRUPTIBLE;
+			schedule();
+			down(&dev->oss.lock);
+			if (signal_pending(current)) {
+				if (0 == ret)
+					ret = -EINTR;
+				break;
+			}
+		}
+
+		/* copy data to userspace */
+		bytes = count;
+		if (bytes > dev->oss.read_count)
+			bytes = dev->oss.read_count;
+		if (bytes > dev->oss.bufsize - dev->oss.read_offset)
+			bytes = dev->oss.bufsize - dev->oss.read_offset;
+		if (copy_to_user(buffer + ret,
+				 dev->oss.dma.vmalloc + dev->oss.read_offset,
+				 bytes)) {
+			if (0 == ret)
+				ret = -EFAULT;
+			break;
+		}
+
+		ret   += bytes;
+		count -= bytes;
+		dev->oss.read_count  -= bytes;
+		dev->oss.read_offset += bytes;
+		if (dev->oss.read_offset == dev->oss.bufsize)
+			dev->oss.read_offset = 0;
+	}
+	up(&dev->oss.lock);
+	remove_wait_queue(&dev->oss.wq, &wait);
+	current->state = TASK_RUNNING;
+	return ret;
+}
+
+static ssize_t dsp_write(struct file *file, const char *buffer,
+			 size_t count, loff_t *ppos)
+{
+	return -EINVAL;
+}
+
+static int dsp_ioctl(struct inode *inode, struct file *file,
+		     unsigned int cmd, unsigned long arg)
+{
+	struct saa7134_dev *dev = file->private_data;
+	int val = 0;
+	
+	if (oss_debug > 1)
+		saa7134_print_ioctl(dev->name,cmd);
+        switch (cmd) {
+        case OSS_GETVERSION:
+                return put_user(SOUND_VERSION, (int *)arg);
+        case SNDCTL_DSP_GETCAPS:
+		return 0;
+
+        case SNDCTL_DSP_SPEED:
+		if (get_user(val, (int*)arg))
+			return -EFAULT;
+		/* fall through */
+        case SOUND_PCM_READ_RATE:
+		return put_user(dev->oss.rate, (int*)arg);
+
+        case SNDCTL_DSP_STEREO:
+		if (get_user(val, (int*)arg))
+			return -EFAULT;
+		down(&dev->oss.lock);
+		dev->oss.channels = val ? 2 : 1;
+		if (dev->oss.recording) {
+			dsp_rec_stop(dev);
+			dsp_rec_start(dev);
+		}
+		up(&dev->oss.lock);
+		return put_user(dev->oss.channels-1, (int *)arg);
+
+        case SNDCTL_DSP_CHANNELS:
+		if (get_user(val, (int*)arg))
+			return -EFAULT;
+		if (val != 1 && val != 2)
+			return -EINVAL;
+		down(&dev->oss.lock);
+		dev->oss.channels = val;
+		if (dev->oss.recording) {
+			dsp_rec_stop(dev);
+			dsp_rec_start(dev);
+		}
+		up(&dev->oss.lock);
+		/* fall through */
+        case SOUND_PCM_READ_CHANNELS:
+		return put_user(dev->oss.channels, (int *)arg);
+		
+        case SNDCTL_DSP_GETFMTS: /* Returns a mask */
+		return put_user(AFMT_U8     | AFMT_S8     |
+				AFMT_U16_LE | AFMT_U16_BE |
+				AFMT_S16_LE | AFMT_S16_BE, (int*)arg);
+
+        case SNDCTL_DSP_SETFMT: /* Selects ONE fmt */
+		if (get_user(val, (int*)arg))
+			return -EFAULT;
+		switch (val) {
+		case AFMT_QUERY:
+			/* nothing to do */
+			break;
+		case AFMT_U8:
+		case AFMT_S8:
+		case AFMT_U16_LE:
+		case AFMT_U16_BE:
+		case AFMT_S16_LE:
+		case AFMT_S16_BE:
+#ifdef AFMT_S32_LE
+		case AFMT_S32_LE:
+		case AFMT_S32_BE:
+#endif
+			down(&dev->oss.lock);
+			dev->oss.afmt = val;
+			if (dev->oss.recording) {
+				dsp_rec_stop(dev);
+				dsp_rec_start(dev);
+			}
+			up(&dev->oss.lock);
+			return put_user(dev->oss.afmt,(int*)arg);
+		default:
+			return -EINVAL;
+		}
+
+        case SOUND_PCM_READ_BITS:
+		switch (dev->oss.afmt) {
+		case AFMT_U8:
+		case AFMT_S8:
+			return put_user(8, (int*)arg);
+		case AFMT_U16_LE:
+		case AFMT_U16_BE:
+		case AFMT_S16_LE:
+		case AFMT_S16_BE:
+			return put_user(16, (int*)arg);
+#ifdef AFMT_S32_LE
+		case AFMT_S32_LE:
+		case AFMT_S32_BE:
+			return put_user(20, (int*)arg);
+#endif
+		default:
+			return -EINVAL;
+		}
+
+        case SNDCTL_DSP_NONBLOCK:
+                file->f_flags |= O_NONBLOCK;
+                return 0;
+
+        case SNDCTL_DSP_RESET:
+		down(&dev->oss.lock);
+		if (dev->oss.recording)
+			dsp_rec_stop(dev);
+		up(&dev->oss.lock);
+		return 0;
+        case SNDCTL_DSP_GETBLKSIZE:
+		return put_user(dev->oss.blksize,(int*)arg);
+
+        case SNDCTL_DSP_SETFRAGMENT:
+		if (get_user(val, (int*)arg))
+			return -EFAULT;
+		if (dev->oss.recording)
+			return -EBUSY;
+		dsp_buffer_free(dev);
+		dsp_buffer_conf(dev,1 << (val & 0xffff), (arg >> 16) & 0xffff);
+		dsp_buffer_init(dev);
+		return 0;
+
+        case SNDCTL_DSP_SYNC:
+		/* NOP */
+		return 0;
+
+	case SNDCTL_DSP_GETISPACE:
+	{
+		audio_buf_info info;
+		info.fragsize   = dev->oss.blksize;
+		info.fragstotal = dev->oss.blocks;
+		info.bytes      = dev->oss.read_count;
+		info.fragments  = info.bytes / info.fragsize;
+		if (copy_to_user((void *)arg, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
+	}
+	default:
+		return -EINVAL;
+	}
+}
+
+static unsigned int dsp_poll(struct file *file, struct poll_table_struct *wait)
+{
+	struct saa7134_dev *dev = file->private_data;
+	unsigned int mask = 0;
+
+	poll_wait(file, &dev->oss.wq, wait);
+
+	if (0 == dev->oss.read_count) {
+		down(&dev->oss.lock);
+		if (!dev->oss.recording)
+			dsp_rec_start(dev);
+		up(&dev->oss.lock);
+	} else
+		mask |= (POLLIN | POLLRDNORM);
+	return mask;
+}
+
+struct file_operations saa7134_dsp_fops = {
+	owner:   THIS_MODULE,
+	open:    dsp_open,
+	release: dsp_release,
+	read:    dsp_read,
+	write:   dsp_write,
+	ioctl:   dsp_ioctl,
+	poll:    dsp_poll,
+	llseek:  no_llseek,
+};
+
+/* ------------------------------------------------------------------ */
+
+static int
+mixer_recsrc(struct saa7134_dev *dev, enum saa7134_audio_in src)
+{
+	static const char *iname[] = { "Oops", "TV", "LINE1", "LINE2" };
+	int analog_io,rate;
+	
+	dev->oss.count++;
+	dev->oss.input = src;
+	dprintk("mixer input = %s\n",iname[dev->oss.input]);
+	switch (dev->oss.input) {
+	case TV:
+		saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0);
+		saa_andorb(SAA7134_SIF_SAMPLE_FREQ,   0x03, 0x00);
+		break;
+	case LINE1:
+	case LINE2:
+		analog_io = (LINE1 == dev->oss.input) ? 0x00 : 0x08;
+		rate = (32000 == dev->oss.rate) ? 0x01 : 0x03;
+		saa_andorb(SAA7134_ANALOG_IO_SELECT,  0x08, analog_io);
+		saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80);
+		saa_andorb(SAA7134_SIF_SAMPLE_FREQ,   0x03, rate);
+		break;
+	}
+	return 0;
+}
+
+static int
+mixer_level(struct saa7134_dev *dev, enum saa7134_audio_in src, int level)
+{
+	switch (src) {
+	case TV:
+		/* nothing */
+		break;
+	case LINE1:
+		saa_andorb(SAA7134_ANALOG_IO_SELECT,  0x10,
+			   (100 == level) ? 0x00 : 0x10);
+		break;
+	case LINE2:
+		saa_andorb(SAA7134_ANALOG_IO_SELECT,  0x20,
+			   (100 == level) ? 0x00 : 0x20);
+		break;
+	}
+	return 0;
+}
+
+static int mixer_open(struct inode *inode, struct file *file)
+{
+	unsigned int minor = minor(inode->i_rdev);
+	struct saa7134_dev *h,*dev = NULL;
+	struct list_head *list;
+
+	list_for_each(list,&saa7134_devlist) {
+		h = list_entry(list, struct saa7134_dev, devlist);
+		if (h->oss.minor_mixer == minor)
+			dev = h;
+	}
+	if (NULL == dev)
+		return -ENODEV;
+
+	file->private_data = dev;
+	return 0;
+}
+
+static int mixer_release(struct inode *inode, struct file *file)
+{
+	file->private_data = NULL;
+	return 0;
+}
+
+static int mixer_ioctl(struct inode *inode, struct file *file,
+		     unsigned int cmd, unsigned long arg)
+{
+	struct saa7134_dev *dev = file->private_data;
+	enum saa7134_audio_in input;
+	int val,ret;
+	
+	if (oss_debug > 1)
+		saa7134_print_ioctl(dev->name,cmd);
+        switch (cmd) {
+        case OSS_GETVERSION:
+                return put_user(SOUND_VERSION, (int *)arg);
+	case SOUND_MIXER_INFO:
+	{
+		mixer_info info;
+		memset(&info,0,sizeof(info));
+                strncpy(info.id,   "TV audio", sizeof(info.id)-1);
+                strncpy(info.name, dev->name,  sizeof(info.name)-1);
+                info.modify_counter = dev->oss.count;
+                if (copy_to_user((void *)arg, &info, sizeof(info)))
+                        return -EFAULT;
+		return 0;
+	}
+	case SOUND_OLD_MIXER_INFO:
+	{
+		_old_mixer_info info;
+		memset(&info,0,sizeof(info));
+                strncpy(info.id,   "TV audio", sizeof(info.id)-1);
+                strncpy(info.name, dev->name,  sizeof(info.name)-1);
+                if (copy_to_user((void *)arg, &info, sizeof(info)))
+                        return -EFAULT;
+		return 0;
+	}
+	case MIXER_READ(SOUND_MIXER_CAPS):
+		return put_user(SOUND_CAP_EXCL_INPUT,(int*)arg);
+	case MIXER_READ(SOUND_MIXER_STEREODEVS):
+		return put_user(0,(int*)arg);
+	case MIXER_READ(SOUND_MIXER_RECMASK):
+	case MIXER_READ(SOUND_MIXER_DEVMASK):
+		val = SOUND_MASK_LINE1 | SOUND_MASK_LINE2;
+		if (32000 == dev->oss.rate)
+			val |= SOUND_MASK_VIDEO;
+		return put_user(val,(int*)arg);
+
+	case MIXER_WRITE(SOUND_MIXER_RECSRC):
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+		input = dev->oss.input;
+		if (32000 == dev->oss.rate  &&
+		    val & SOUND_MASK_VIDEO  &&  dev->oss.input != TV)
+			input = TV;
+		if (val & SOUND_MASK_LINE1  &&  dev->oss.input != LINE1)
+			input = LINE1;
+		if (val & SOUND_MASK_LINE2  &&  dev->oss.input != LINE2)
+			input = LINE2;
+		if (input != dev->oss.input)
+			mixer_recsrc(dev,input);
+		/* fall throuth */
+	case MIXER_READ(SOUND_MIXER_RECSRC):
+		switch (dev->oss.input) {
+		case TV:    ret = SOUND_MASK_VIDEO; break;
+		case LINE1: ret = SOUND_MASK_LINE1; break;
+		case LINE2: ret = SOUND_MASK_LINE2; break;
+		default:    ret = 0;
+		}
+		return put_user(ret,(int*)arg);
+
+	case MIXER_WRITE(SOUND_MIXER_VIDEO):
+	case MIXER_READ(SOUND_MIXER_VIDEO):
+		if (32000 != dev->oss.rate)
+			return -EINVAL;
+		return put_user(100 | 100 << 8,(int*)arg);
+
+	case MIXER_WRITE(SOUND_MIXER_LINE1):
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+		val &= 0xff;
+		val = (val <= 50) ? 50 : 100;
+		dev->oss.line1 = val;
+		mixer_level(dev,LINE1,dev->oss.line1);
+		/* fall throuth */
+	case MIXER_READ(SOUND_MIXER_LINE1):
+		return put_user(dev->oss.line1 | dev->oss.line1 << 8,
+				(int*)arg);
+
+	case MIXER_WRITE(SOUND_MIXER_LINE2):
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+		val &= 0xff;
+		val = (val <= 50) ? 50 : 100;
+		dev->oss.line2 = val;
+		mixer_level(dev,LINE2,dev->oss.line2);
+		/* fall throuth */
+	case MIXER_READ(SOUND_MIXER_LINE2):
+		return put_user(dev->oss.line2 | dev->oss.line2 << 8,
+				(int*)arg);
+
+	default:
+		return -EINVAL;
+	}
+}
+
+struct file_operations saa7134_mixer_fops = {
+	owner:   THIS_MODULE,
+	open:    mixer_open,
+	release: mixer_release,
+	ioctl:   mixer_ioctl,
+	llseek:  no_llseek,
+};
+
+/* ------------------------------------------------------------------ */
+
+int saa7134_oss_init(struct saa7134_dev *dev)
+{
+        init_MUTEX(&dev->oss.lock);
+	init_waitqueue_head(&dev->oss.wq);
+	dev->oss.line1 = 50;
+	dev->oss.line2 = 50;
+	mixer_level(dev,LINE1,dev->oss.line1);
+	mixer_level(dev,LINE2,dev->oss.line2);
+	
+	dev->oss.rate = 32000;
+	if (oss_rate)
+		dev->oss.rate = oss_rate;
+	if (saa7134_boards[dev->board].i2s_rate)
+		dev->oss.rate = saa7134_boards[dev->board].i2s_rate;
+	dev->oss.rate = (dev->oss.rate > 40000) ? 48000 : 32000;
+
+	mixer_recsrc(dev, (dev->oss.rate == 32000) ? TV : LINE2);
+	return 0;
+}
+
+int saa7134_oss_fini(struct saa7134_dev *dev)
+{
+	/* nothing */
+	return 0;
+}
+
+void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
+{
+	int next_blk, reg = 0;
+
+	spin_lock(&dev->slock);
+	if (-1 == dev->oss.dma_blk) {
+		dprintk("irq: recording stopped%s\n","");
+		goto done;
+	}
+	if (0 != (status & 0x0f000000))
+		dprintk("irq: lost %ld\n", (status >> 24) & 0x0f);
+	if (0 == (status & 0x10000000)) {
+		/* odd */
+		if (0 == (dev->oss.dma_blk & 0x01))
+			reg = SAA7134_RS_BA1(6);
+	} else {
+		/* even */
+		if (0 == (dev->oss.dma_blk & 0x00))
+			reg = SAA7134_RS_BA2(6);
+	}
+	if (0 == reg) {
+		dprintk("irq: field oops [%s]\n",
+			(status & 0x10000000) ? "even" : "odd");
+		goto done;
+	}
+	if (dev->oss.read_count >= dev->oss.blksize * (dev->oss.blocks-2)) {
+		dprintk("irq: overrun [full=%d/%d]\n",dev->oss.read_count,
+			dev->oss.bufsize);
+		dsp_rec_stop(dev);
+		goto done;
+	}
+
+	/* next block addr */
+	next_blk = (dev->oss.dma_blk + 2) % dev->oss.blocks;
+	saa_writel(reg,next_blk * dev->oss.blksize);
+	if (oss_debug > 2)
+		dprintk("irq: ok, %s, next_blk=%d, addr=%x\n",
+			(status & 0x10000000) ? "even" : "odd ", next_blk,
+			next_blk * dev->oss.blksize);
+
+	/* update status & wake waiting readers */
+	dev->oss.dma_blk = (dev->oss.dma_blk + 1) % dev->oss.blocks;
+	dev->oss.read_count += dev->oss.blksize;
+	wake_up(&dev->oss.wq);
+	
+ done:
+	spin_unlock(&dev->slock);
+}
+
+/* ----------------------------------------------------------- */
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff -Nru a/drivers/media/video/saa7134/saa7134-reg.h b/drivers/media/video/saa7134/saa7134-reg.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/media/video/saa7134/saa7134-reg.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,338 @@
+/*
+ * philips saa7134 registers
+ */
+
+/* ------------------------------------------------------------------ */
+/*
+ * PCI ID's
+ */
+#ifndef PCI_DEVICE_ID_PHILIPS_SAA7130
+# define PCI_DEVICE_ID_PHILIPS_SAA7130 0x7130
+#endif
+#ifndef PCI_DEVICE_ID_PHILIPS_SAA7134
+# define PCI_DEVICE_ID_PHILIPS_SAA7134 0x7134
+#endif
+
+/* ------------------------------------------------------------------ */
+/*
+ *  registers -- 32 bit
+ */
+
+/* DMA channels, n = 0 ... 6 */
+#define SAA7134_RS_BA1(n)			((0x200 >> 2) + 4*n)
+#define SAA7134_RS_BA2(n)	       		((0x204 >> 2) + 4*n)
+#define SAA7134_RS_PITCH(n)			((0x208 >> 2) + 4*n)
+#define SAA7134_RS_CONTROL(n)			((0x20c >> 2) + 4*n)
+#define   SAA7134_RS_CONTROL_WSWAP		(0x01 << 25)
+#define   SAA7134_RS_CONTROL_BSWAP		(0x01 << 24)
+#define   SAA7134_RS_CONTROL_BURST_2		(0x01 << 21)
+#define   SAA7134_RS_CONTROL_BURST_4		(0x02 << 21)
+#define   SAA7134_RS_CONTROL_BURST_8		(0x03 << 21)
+#define   SAA7134_RS_CONTROL_BURST_16		(0x04 << 21)
+#define   SAA7134_RS_CONTROL_BURST_32		(0x05 << 21)
+#define   SAA7134_RS_CONTROL_BURST_64		(0x06 << 21)
+#define   SAA7134_RS_CONTROL_BURST_MAX		(0x07 << 21)
+#define   SAA7134_RS_CONTROL_ME			(0x01 << 20)
+#define SAA7134_FIFO_SIZE                       (0x2a0 >> 2)
+#define SAA7134_THRESHOULD                      (0x2a4 >> 2)
+
+/* main control */
+#define SAA7134_MAIN_CTRL                       (0x2a8 >> 2)
+#define   SAA7134_MAIN_CTRL_VPLLE	       	(1 << 15)
+#define   SAA7134_MAIN_CTRL_APLLE	       	(1 << 14)
+#define   SAA7134_MAIN_CTRL_EXOSC	       	(1 << 13)
+#define   SAA7134_MAIN_CTRL_EVFE1	       	(1 << 12)
+#define   SAA7134_MAIN_CTRL_EVFE2	       	(1 << 11)
+#define   SAA7134_MAIN_CTRL_ESFE	       	(1 << 10)
+#define   SAA7134_MAIN_CTRL_EBADC	       	(1 << 9)
+#define   SAA7134_MAIN_CTRL_EBDAC	       	(1 << 8)
+#define   SAA7134_MAIN_CTRL_TE6			(1 << 6)
+#define   SAA7134_MAIN_CTRL_TE5			(1 << 5)
+#define   SAA7134_MAIN_CTRL_TE4			(1 << 4)
+#define   SAA7134_MAIN_CTRL_TE3			(1 << 3)
+#define   SAA7134_MAIN_CTRL_TE2			(1 << 2)
+#define   SAA7134_MAIN_CTRL_TE1			(1 << 1)
+#define   SAA7134_MAIN_CTRL_TE0			(1 << 0)
+
+/* DMA status */
+#define SAA7134_DMA_STATUS                      (0x2ac >> 2)
+
+/* audio / video status */
+#define SAA7134_AV_STATUS			(0x2c0 >> 2)
+#define   SAA7134_AV_STATUS_STEREO		(1 << 17)
+#define   SAA7134_AV_STATUS_DUAL                (1 << 16)
+#define   SAA7134_AV_STATUS_PILOT               (1 << 15)
+#define   SAA7134_AV_STATUS_SMB                 (1 << 14)
+#define   SAA7134_AV_STATUS_DMB                 (1 << 13)
+#define   SAA7134_AV_STATUS_VDSP                (1 << 12)
+#define   SAA7134_AV_STATUS_IIC_STATUS          (3 << 10)
+#define   SAA7134_AV_STATUS_MVM                 (7 << 7)
+#define   SAA7134_AV_STATUS_FIDT                (1 << 6)
+#define   SAA7134_AV_STATUS_INTL                (1 << 5)
+#define   SAA7134_AV_STATUS_RDCAP               (1 << 4)
+#define   SAA7134_AV_STATUS_PWR_ON              (1 << 3)
+#define   SAA7134_AV_STATUS_LOAD_ERR            (1 << 2)
+#define   SAA7134_AV_STATUS_TRIG_ERR            (1 << 1)
+#define   SAA7134_AV_STATUS_CONF_ERR            (1 << 0)
+
+/* interrupt */
+#define SAA7134_IRQ1                            (0x2c4 >> 2)
+#define   SAA7134_IRQ1_INTE_RA3_1               (1 << 25)
+#define   SAA7134_IRQ1_INTE_RA3_0               (1 << 24)
+#define   SAA7134_IRQ1_INTE_RA2_3               (1 << 19)
+#define   SAA7134_IRQ1_INTE_RA2_2               (1 << 18)
+#define   SAA7134_IRQ1_INTE_RA2_1               (1 << 17)
+#define   SAA7134_IRQ1_INTE_RA2_0               (1 << 16)
+#define   SAA7134_IRQ1_INTE_RA1_3               (1 << 11)
+#define   SAA7134_IRQ1_INTE_RA1_2               (1 << 10)
+#define   SAA7134_IRQ1_INTE_RA1_1               (1 <<  9)
+#define   SAA7134_IRQ1_INTE_RA1_0               (1 <<  8)
+#define   SAA7134_IRQ1_INTE_RA0_7               (1 <<  7)
+#define   SAA7134_IRQ1_INTE_RA0_6               (1 <<  6)
+#define   SAA7134_IRQ1_INTE_RA0_5               (1 <<  5)
+#define   SAA7134_IRQ1_INTE_RA0_4               (1 <<  4)
+#define   SAA7134_IRQ1_INTE_RA0_3               (1 <<  3)
+#define   SAA7134_IRQ1_INTE_RA0_2               (1 <<  2)
+#define   SAA7134_IRQ1_INTE_RA0_1               (1 <<  1)
+#define   SAA7134_IRQ1_INTE_RA0_0               (1 <<  0)
+#define SAA7134_IRQ2                            (0x2c8 >> 2)
+#define   SAA7134_IRQ2_INTE_SC2                 (1 << 10)
+#define   SAA7134_IRQ2_INTE_SC1                 (1 <<  9)
+#define   SAA7134_IRQ2_INTE_SC0                 (1 <<  8)
+#define   SAA7134_IRQ2_INTE_DEC5                (1 <<  7)
+#define   SAA7134_IRQ2_INTE_DEC4                (1 <<  6)
+#define   SAA7134_IRQ2_INTE_DEC3                (1 <<  5)
+#define   SAA7134_IRQ2_INTE_DEC2                (1 <<  4)
+#define   SAA7134_IRQ2_INTE_DEC1                (1 <<  3)
+#define   SAA7134_IRQ2_INTE_DEC0                (1 <<  2)
+#define   SAA7134_IRQ2_INTE_PE                  (1 <<  1)
+#define   SAA7134_IRQ2_INTE_AR                  (1 <<  0)
+#define SAA7134_IRQ_REPORT                      (0x2cc >> 2)
+#define   SAA7134_IRQ_REPORT_LOAD_ERR           (1 << 13)
+#define   SAA7134_IRQ_REPORT_CONF_ERR           (1 << 12)
+#define   SAA7134_IRQ_REPORT_TRIG_ERR           (1 << 11)
+#define   SAA7134_IRQ_REPORT_MMC                (1 << 10)
+#define   SAA7134_IRQ_REPORT_FIDT               (1 <<  9)
+#define   SAA7134_IRQ_REPORT_INTL               (1 <<  8)
+#define   SAA7134_IRQ_REPORT_RDCAP              (1 <<  7)
+#define   SAA7134_IRQ_REPORT_PWR_ON             (1 <<  6)
+#define   SAA7134_IRQ_REPORT_PE                 (1 <<  5)
+#define   SAA7134_IRQ_REPORT_AR                 (1 <<  4)
+#define   SAA7134_IRQ_REPORT_DONE_RA3           (1 <<  3)
+#define   SAA7134_IRQ_REPORT_DONE_RA2           (1 <<  2)
+#define   SAA7134_IRQ_REPORT_DONE_RA1           (1 <<  1)
+#define   SAA7134_IRQ_REPORT_DONE_RA0           (1 <<  0)
+#define SAA7134_IRQ_STATUS                      (0x2d0 >> 2)
+
+
+/* ------------------------------------------------------------------ */
+/*
+ *  registers -- 8 bit
+ */
+
+/* video decoder */
+#define SAA7134_INCR_DELAY                      0x101
+#define SAA7134_ANALOG_IN_CTRL1                 0x102
+#define SAA7134_ANALOG_IN_CTRL2                 0x103
+#define SAA7134_ANALOG_IN_CTRL3                 0x104
+#define SAA7134_ANALOG_IN_CTRL4                 0x105
+#define SAA7134_HSYNC_START                     0x106
+#define SAA7134_HSYNC_STOP                      0x107
+#define SAA7134_SYNC_CTRL                       0x108
+#define SAA7134_LUMA_CTRL                       0x109
+#define SAA7134_DEC_LUMA_BRIGHT                 0x10a
+#define SAA7134_DEC_LUMA_CONTRAST               0x10b
+#define SAA7134_DEC_CHROMA_SATURATION           0x10c
+#define SAA7134_DEC_CHROMA_HUE                  0x10d
+#define SAA7134_CHROMA_CTRL1                    0x10e
+#define SAA7134_CHROMA_GAIN                     0x10f
+#define SAA7134_CHROMA_CTRL2                    0x110
+#define SAA7134_MODE_DELAY_CTRL                 0x111
+
+#define SAA7134_ANALOG_ADC                      0x114
+#define SAA7134_VGATE_START                     0x115
+#define SAA7134_VGATE_STOP                      0x116
+#define SAA7134_MISC_VGATE_MSB                  0x117
+#define SAA7134_RAW_DATA_GAIN                   0x118
+#define SAA7134_RAW_DATA_OFFSET                 0x119
+#define SAA7134_STATUS_VIDEO1                   0x11e
+#define SAA7134_STATUS_VIDEO2                   0x11f
+
+/* video scaler */
+#define SAA7134_SOURCE_TIMING1                  0x000
+#define SAA7134_SOURCE_TIMING2                  0x001
+#define SAA7134_REGION_ENABLE                   0x004
+#define SAA7134_SCALER_STATUS0                  0x006
+#define SAA7134_SCALER_STATUS1                  0x007
+#define SAA7134_START_GREEN                     0x00c
+#define SAA7134_START_BLUE                      0x00d
+#define SAA7134_START_RED                       0x00e
+#define SAA7134_GREEN_PATH(x)                   (0x010 +x)
+#define SAA7134_BLUE_PATH(x)                    (0x020 +x)
+#define SAA7134_RED_PATH(x)                     (0x030 +x)
+
+#define TASK_A                                  0x040
+#define TASK_B                                  0x080
+#define SAA7134_TASK_CONDITIONS(t)              (0x000 +t)
+#define SAA7134_FIELD_HANDLING(t)               (0x001 +t)
+#define SAA7134_DATA_PATH(t)                    (0x002 +t)
+#define SAA7134_VBI_H_START1(t)                 (0x004 +t)
+#define SAA7134_VBI_H_START2(t)                 (0x005 +t)
+#define SAA7134_VBI_H_STOP1(t)                  (0x006 +t)
+#define SAA7134_VBI_H_STOP2(t)                  (0x007 +t)
+#define SAA7134_VBI_V_START1(t)                 (0x008 +t)
+#define SAA7134_VBI_V_START2(t)                 (0x009 +t)
+#define SAA7134_VBI_V_STOP1(t)                  (0x00a +t)
+#define SAA7134_VBI_V_STOP2(t)                  (0x00b +t)
+#define SAA7134_VBI_H_LEN1(t)                   (0x00c +t)
+#define SAA7134_VBI_H_LEN2(t)                   (0x00d +t)
+#define SAA7134_VBI_V_LEN1(t)                   (0x00e +t)
+#define SAA7134_VBI_V_LEN2(t)                   (0x00f +t)
+
+#define SAA7134_VIDEO_H_START1(t)               (0x014 +t)
+#define SAA7134_VIDEO_H_START2(t)               (0x015 +t)
+#define SAA7134_VIDEO_H_STOP1(t)                (0x016 +t)
+#define SAA7134_VIDEO_H_STOP2(t)                (0x017 +t)
+#define SAA7134_VIDEO_V_START1(t)               (0x018 +t)
+#define SAA7134_VIDEO_V_START2(t)               (0x019 +t)
+#define SAA7134_VIDEO_V_STOP1(t)                (0x01a +t)
+#define SAA7134_VIDEO_V_STOP2(t)                (0x01b +t)
+#define SAA7134_VIDEO_PIXELS1(t)                (0x01c +t)
+#define SAA7134_VIDEO_PIXELS2(t)                (0x01d +t)
+#define SAA7134_VIDEO_LINES1(t)                 (0x01e +t)
+#define SAA7134_VIDEO_LINES2(t)                 (0x01f +t)
+
+#define SAA7134_H_PRESCALE(t)                   (0x020 +t)
+#define SAA7134_ACC_LENGTH(t)                   (0x021 +t)
+#define SAA7134_LEVEL_CTRL(t)                   (0x022 +t)
+#define SAA7134_FIR_PREFILTER_CTRL(t)           (0x023 +t)
+#define SAA7134_LUMA_BRIGHT(t)                  (0x024 +t)
+#define SAA7134_LUMA_CONTRAST(t)                (0x025 +t)
+#define SAA7134_CHROMA_SATURATION(t)            (0x026 +t)
+#define SAA7134_VBI_H_SCALE_INC1(t)             (0x028 +t)
+#define SAA7134_VBI_H_SCALE_INC2(t)             (0x029 +t)
+#define SAA7134_VBI_PHASE_OFFSET_LUMA(t)        (0x02a +t)
+#define SAA7134_VBI_PHASE_OFFSET_CHROMA(t)      (0x02b +t)
+#define SAA7134_H_SCALE_INC1(t)                 (0x02c +t)
+#define SAA7134_H_SCALE_INC2(t)                 (0x02d +t)
+#define SAA7134_H_PHASE_OFF_LUMA(t)             (0x02e +t)
+#define SAA7134_H_PHASE_OFF_CHROMA(t)           (0x02f +t)
+#define SAA7134_V_SCALE_RATIO1(t)               (0x030 +t)
+#define SAA7134_V_SCALE_RATIO2(t)               (0x031 +t)
+#define SAA7134_V_FILTER(t)                     (0x032 +t)
+#define SAA7134_V_PHASE_OFFSET0(t)              (0x034 +t)
+#define SAA7134_V_PHASE_OFFSET1(t)              (0x035 +t)
+#define SAA7134_V_PHASE_OFFSET2(t)              (0x036 +t)
+#define SAA7134_V_PHASE_OFFSET3(t)              (0x037 +t)
+
+/* clipping & dma */
+#define SAA7134_OFMT_VIDEO_A                    0x300
+#define SAA7134_OFMT_DATA_A                     0x301
+#define SAA7134_OFMT_VIDEO_B                    0x302
+#define SAA7134_OFMT_DATA_B                     0x303
+#define SAA7134_ALPHA_NOCLIP                    0x304
+#define SAA7134_ALPHA_CLIP                      0x305
+#define SAA7134_UV_PIXEL                        0x308
+#define SAA7134_CLIP_RED                        0x309
+#define SAA7134_CLIP_GREEN                      0x30a
+#define SAA7134_CLIP_BLUE                       0x30b
+
+/* i2c bus */
+#define SAA7134_I2C_ATTR_STATUS                 0x180
+#define SAA7134_I2C_DATA                        0x181
+#define SAA7134_I2C_CLOCK_SELECT                0x182
+#define SAA7134_I2C_TIMER                       0x183
+
+/* audio */
+#define SAA7134_NICAM_ADD_DATA1                 0x140
+#define SAA7134_NICAM_ADD_DATA2                 0x141
+#define SAA7134_NICAM_STATUS                    0x142
+#define SAA7134_AUDIO_STATUS                    0x143
+#define SAA7134_NICAM_ERROR_COUNT               0x144
+#define SAA7134_IDENT_SIF                       0x145
+#define SAA7134_LEVEL_READOUT1                  0x146
+#define SAA7134_LEVEL_READOUT2                  0x147
+#define SAA7134_NICAM_ERROR_LOW                 0x148
+#define SAA7134_NICAM_ERROR_HIGH                0x149
+#define SAA7134_DCXO_IDENT_CTRL                 0x14a
+#define SAA7134_DEMODULATOR                     0x14b
+#define SAA7134_AGC_GAIN_SELECT                 0x14c
+#define SAA7134_CARRIER1_FREQ0                  0x150
+#define SAA7134_CARRIER1_FREQ1                  0x151
+#define SAA7134_CARRIER1_FREQ2                  0x152
+#define SAA7134_CARRIER2_FREQ0                  0x154
+#define SAA7134_CARRIER2_FREQ1                  0x155
+#define SAA7134_CARRIER2_FREQ2                  0x156
+#define SAA7134_NUM_SAMPLES0                    0x158
+#define SAA7134_NUM_SAMPLES1                    0x159
+#define SAA7134_NUM_SAMPLES2                    0x15a
+#define SAA7134_AUDIO_FORMAT_CTRL               0x15b
+#define SAA7134_MONITOR_SELECT                  0x160
+#define SAA7134_FM_DEEMPHASIS                   0x161
+#define SAA7134_FM_DEMATRIX                     0x162
+#define SAA7134_CHANNEL1_LEVEL                  0x163
+#define SAA7134_CHANNEL2_LEVEL                  0x164
+#define SAA7134_NICAM_CONFIG                    0x165
+#define SAA7134_NICAM_LEVEL_ADJUST              0x166
+#define SAA7134_STEREO_DAC_OUTPUT_SELECT        0x167
+#define SAA7134_I2S_OUTPUT_FORMAT               0x168
+#define SAA7134_I2S_OUTPUT_SELECT               0x169
+#define SAA7134_I2S_OUTPUT_LEVEL                0x16a
+#define SAA7134_DSP_OUTPUT_SELECT               0x16b
+#define SAA7134_AUDIO_MUTE_CTRL                 0x16c
+#define SAA7134_SIF_SAMPLE_FREQ                 0x16d
+#define SAA7134_ANALOG_IO_SELECT                0x16e
+#define SAA7134_AUDIO_CLOCK0                    0x170
+#define SAA7134_AUDIO_CLOCK1                    0x171
+#define SAA7134_AUDIO_CLOCK2                    0x172
+#define SAA7134_AUDIO_PLL_CTRL                  0x173
+#define SAA7134_AUDIO_CLOCKS_PER_FIELD0         0x174
+#define SAA7134_AUDIO_CLOCKS_PER_FIELD1         0x175
+#define SAA7134_AUDIO_CLOCKS_PER_FIELD2         0x176
+
+/* video port output */
+#define SAA7134_VIDEO_PORT_CTRL0                0x190
+#define SAA7134_VIDEO_PORT_CTRL1                0x191
+#define SAA7134_VIDEO_PORT_CTRL2                0x192
+#define SAA7134_VIDEO_PORT_CTRL3                0x193
+#define SAA7134_VIDEO_PORT_CTRL4                0x194
+#define SAA7134_VIDEO_PORT_CTRL5                0x195
+#define SAA7134_VIDEO_PORT_CTRL6                0x196
+#define SAA7134_VIDEO_PORT_CTRL7                0x197
+#define SAA7134_VIDEO_PORT_CTRL8                0x198
+
+/* transport stream interface */
+#define SAA7134_TS_PARALLEL                     0x1a0
+#define SAA7134_TS_PARALLEL_SERIAL              0x1a1
+#define SAA7134_TS_SERIAL0                      0x1a2
+#define SAA7134_TS_SERIAL1                      0x1a3
+#define SAA7134_TS_DMA0                         0x1a4
+#define SAA7134_TS_DMA1                         0x1a5
+#define SAA7134_TS_DMA2                         0x1a6
+
+/* GPIO Controls */
+#define SAA7134_GPIO_GPRESCAN                   0x80
+#define SAA7134_GPIO_27_25                      0x0E
+
+#define SAA7134_GPIO_GPMODE0                    0x1B0
+#define SAA7134_GPIO_GPMODE1                    0x1B1
+#define SAA7134_GPIO_GPMODE2                    0x1B2
+#define SAA7134_GPIO_GPMODE3                    0x1B3
+#define SAA7134_GPIO_GPSTATUS0                  0x1B4
+#define SAA7134_GPIO_GPSTATUS1                  0x1B5
+#define SAA7134_GPIO_GPSTATUS2                  0x1B6
+#define SAA7134_GPIO_GPSTATUS3                  0x1B7
+
+/* I2S output */
+#define SAA7134_I2S_AUDIO_OUTPUT                0x1c0
+
+/* test modes */
+#define SAA7134_SPECIAL_MODE                    0x1d0
+
+/* ------------------------------------------------------------------ */
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
+
diff -Nru a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/media/video/saa7134/saa7134-ts.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,453 @@
+/*
+ * device driver for philips saa7134 based TV cards
+ * video4linux video interface
+ *
+ * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define __NO_VERSION__ 1
+
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#include "saa7134-reg.h"
+#include "saa7134.h"
+
+/* ------------------------------------------------------------------ */
+
+static unsigned int ts_debug  = 0;
+MODULE_PARM(ts_debug,"i");
+MODULE_PARM_DESC(ts_debug,"enable debug messages [ts]");
+
+static unsigned int tsbufs = 4;
+MODULE_PARM(tsbufs,"i");
+MODULE_PARM_DESC(tsbufs,"number of ts buffers, range 2-32");
+
+#define TS_PACKET_SIZE 188 /* TS packets 188 bytes */
+#define TS_NR_PACKETS 312
+
+#define dprintk(fmt, arg...)	if (ts_debug) \
+	printk(KERN_DEBUG "%s/ts: " fmt, dev->name, ## arg)
+
+/* ------------------------------------------------------------------ */
+
+static int buffer_activate(struct saa7134_dev *dev,
+			   struct saa7134_buf *buf,
+			   struct saa7134_buf *next)
+{
+	unsigned long control,status;
+
+	dprintk("buffer_activate [%p]\n",buf);
+	buf->vb.state = STATE_ACTIVE;
+	
+	/* dma: setup channel 5 (= TS) */
+	control = SAA7134_RS_CONTROL_BURST_16 |
+		SAA7134_RS_CONTROL_ME |
+		(buf->pt->dma >> 12);
+
+	status = saa_readl(SAA7134_IRQ_STATUS);
+	if (0 == (status & 0x100000)) {
+		saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(buf));
+		saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(next));
+	} else {
+		saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next));
+		saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf));
+	}
+	saa_writel(SAA7134_RS_PITCH(5),TS_PACKET_SIZE);
+	saa_writel(SAA7134_RS_CONTROL(5),control);
+
+	/* start DMA */
+	saa7134_set_dmabits(dev);
+	
+	mod_timer(&dev->ts_q.timeout, jiffies+BUFFER_TIMEOUT);
+	return 0;
+}
+
+static int buffer_prepare(struct file *file, struct videobuf_buffer *vb)
+{
+	struct saa7134_dev *dev = file->private_data;
+	struct saa7134_buf *buf = (struct saa7134_buf *)vb;
+	int lines, llength, size, err;
+	
+	llength = TS_PACKET_SIZE;
+	lines = TS_NR_PACKETS;
+	
+	size = lines * llength;
+	if (0 != buf->vb.baddr  &&  buf->vb.bsize < size)
+		return -EINVAL;
+
+	if (buf->vb.size != size) {
+		saa7134_dma_free(dev,buf);
+	}
+
+	if (STATE_NEEDS_INIT == buf->vb.state) {
+		buf->vb.width  = llength;
+		buf->vb.height = lines;
+		buf->vb.size   = size;
+		buf->pt        = &dev->ts.pt_ts;
+
+		err = videobuf_iolock(dev->pci,&buf->vb);
+		if (err)
+			goto oops;
+		err = saa7134_pgtable_build(dev->pci,buf->pt,
+					    buf->vb.dma.sglist,
+					    buf->vb.dma.sglen,
+					    saa7134_buffer_startpage(buf));
+		if (err)
+			goto oops;
+	}
+	buf->vb.state = STATE_PREPARED;
+	buf->top_seen = 0;
+	buf->activate = buffer_activate;
+	buf->vb.field = V4L2_FIELD_SEQ_TB;
+	return 0;
+
+ oops:
+	saa7134_dma_free(dev,buf);
+	return err;
+}
+
+static int
+buffer_setup(struct file *file, int *count, int *size)
+{
+	*size = TS_PACKET_SIZE * TS_NR_PACKETS;
+	if (0 == *count)
+		*count = tsbufs;
+	*count = saa7134_buffer_count(*size,*count);
+	return 0;
+}
+
+static void buffer_queue(struct file *file, struct videobuf_buffer *vb)
+{
+	struct saa7134_dev *dev = file->private_data;
+	struct saa7134_buf *buf = (struct saa7134_buf *)vb;
+	
+	saa7134_buffer_queue(dev,&dev->ts_q,buf);
+}
+
+static void buffer_release(struct file *file, struct videobuf_buffer *vb)
+{
+	struct saa7134_dev *dev = file->private_data;
+	struct saa7134_buf *buf = (struct saa7134_buf *)vb;
+	
+	saa7134_dma_free(dev,buf);
+}
+
+static struct videobuf_queue_ops ts_qops = {
+	buf_setup:    buffer_setup,
+	buf_prepare:  buffer_prepare,
+	buf_queue:    buffer_queue,
+	buf_release:  buffer_release,
+};
+
+/* ------------------------------------------------------------------ */
+
+static int ts_open(struct inode *inode, struct file *file)
+{
+	unsigned int minor = minor(inode->i_rdev);
+	struct saa7134_dev *h,*dev = NULL;
+	struct list_head *list;
+	int err;
+	
+	list_for_each(list,&saa7134_devlist) {
+		h = list_entry(list, struct saa7134_dev, devlist);
+		if (h->ts_dev.minor == minor)
+			dev = h;
+	}
+	if (NULL == dev)
+		return -ENODEV;
+
+	dprintk("open minor=%d\n",minor);
+	down(&dev->ts.ts.lock);
+	err = -EBUSY;
+	if (dev->ts.users)
+		goto done;
+
+	dev->ts.users++;
+	file->private_data = dev;
+	err = 0;
+ done:
+	up(&dev->ts.ts.lock);
+	return err;
+}
+
+static int ts_release(struct inode *inode, struct file *file)
+{
+	struct saa7134_dev *dev = file->private_data;
+
+	if (dev->ts.ts.streaming)
+		videobuf_streamoff(file,&dev->ts.ts);
+	down(&dev->ts.ts.lock);
+	if (dev->ts.ts.reading)
+		videobuf_read_stop(file,&dev->ts.ts);
+	dev->ts.users--;
+	up(&dev->ts.ts.lock);
+	return 0;
+}
+
+static ssize_t
+ts_read(struct file *file, char *data, size_t count, loff_t *ppos)
+{
+	struct saa7134_dev *dev = file->private_data;
+
+	return videobuf_read_stream(file, &dev->ts.ts, data, count, ppos, 0);
+}
+
+static unsigned int
+ts_poll(struct file *file, struct poll_table_struct *wait)
+{
+	struct saa7134_dev *dev = file->private_data;
+
+	return videobuf_poll_stream(file, &dev->ts.ts, wait);
+}
+
+
+static int
+ts_mmap(struct file *file, struct vm_area_struct * vma)
+{
+	struct saa7134_dev *dev = file->private_data;
+
+	return videobuf_mmap_mapper(vma, &dev->ts.ts);
+}
+
+/*
+ * This function is _not_ called directly, but from
+ * video_generic_ioctl (and maybe others).  userspace
+ * copying is done already, arg is a kernel pointer.
+ */
+static int ts_do_ioctl(struct inode *inode, struct file *file,
+		       unsigned int cmd, void *arg)
+{
+	struct saa7134_dev *dev = file->private_data;
+
+	if (ts_debug > 1)
+		saa7134_print_ioctl(dev->name,cmd);
+	switch (cmd) {
+	case VIDIOC_QUERYCAP:
+	{
+		struct v4l2_capability *cap = arg;
+
+		memset(cap,0,sizeof(*cap));
+                strcpy(cap->driver, "saa7134");
+		strncpy(cap->card, saa7134_boards[dev->board].name,
+			sizeof(cap->card));
+		sprintf(cap->bus_info,"PCI:%s",dev->pci->slot_name);
+		cap->version = SAA7134_VERSION_CODE;
+		cap->capabilities =
+			V4L2_CAP_VIDEO_CAPTURE |
+			V4L2_CAP_READWRITE |
+			V4L2_CAP_STREAMING;
+		return 0;
+	}
+
+	/* --- input switching --------------------------------------- */
+	case VIDIOC_ENUMINPUT:
+	{
+		struct v4l2_input *i = arg;
+		
+		if (i->index != 0)
+			return -EINVAL;
+		i->type = V4L2_INPUT_TYPE_CAMERA;
+		strcpy(i->name,"CCIR656");
+		return 0;
+	}
+	case VIDIOC_G_INPUT:
+	{
+		int *i = arg;
+		*i = 0;
+		return 0;
+	}
+	case VIDIOC_S_INPUT:
+	{
+		int *i = arg;
+		
+		if (*i != 0)
+			return -EINVAL;
+		return 0;
+	}
+	/* --- capture ioctls ---------------------------------------- */
+	
+	case VIDIOC_ENUM_FMT:
+	{
+		struct v4l2_fmtdesc *f = arg;
+		int index;
+
+		index = f->index;
+		if (index != 0)
+			return -EINVAL;
+		
+		memset(f,0,sizeof(*f));
+		f->index = index;
+		strncpy(f->description, "MPEG TS", 31);
+		f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		f->pixelformat = V4L2_PIX_FMT_MPEG;
+		return 0;
+	}
+
+	case VIDIOC_G_FMT:
+	{
+		struct v4l2_format *f = arg;
+
+		memset(f,0,sizeof(*f));
+		f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		
+		/* FIXME: translate subsampling type EMPRESS into
+		 *        width/height: */
+		f->fmt.pix.width        = 720; /* D1 */
+		f->fmt.pix.height       = 576;
+		f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
+		f->fmt.pix.sizeimage    = TS_PACKET_SIZE*TS_NR_PACKETS;
+		return 0;
+	}
+	
+	case VIDIOC_S_FMT:
+	{
+		struct v4l2_format *f = arg;
+
+		if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		    return -EINVAL;
+
+		/* 
+		  FIXME: translate and round width/height into EMPRESS
+		  subsample type:
+		 
+		          type  |   PAL   |  NTSC 
+			---------------------------
+			  SIF   | 352x288 | 352x240
+			 1/2 D1 | 352x576 | 352x480
+			 2/3 D1 | 480x576 | 480x480
+			  D1    | 720x576 | 720x480
+		*/
+
+		f->fmt.pix.width        = 720; /* D1 */
+		f->fmt.pix.height       = 576;
+		f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
+		f->fmt.pix.sizeimage    = TS_PACKET_SIZE*TS_NR_PACKETS;
+	}
+
+	case VIDIOC_REQBUFS:
+		return videobuf_reqbufs(file,&dev->ts.ts,arg);
+
+	case VIDIOC_QUERYBUF:
+		return videobuf_querybuf(&dev->ts.ts,arg);
+
+	case VIDIOC_QBUF:
+		return videobuf_qbuf(file,&dev->ts.ts,arg);
+
+	case VIDIOC_DQBUF:
+		return videobuf_dqbuf(file,&dev->ts.ts,arg);
+
+	case VIDIOC_STREAMON:
+		return videobuf_streamon(file,&dev->ts.ts);
+
+	case VIDIOC_STREAMOFF:
+		return videobuf_streamoff(file,&dev->ts.ts);
+
+	default:
+		return -ENOIOCTLCMD;
+	}
+	return 0;
+}
+
+static int ts_ioctl(struct inode *inode, struct file *file,
+		     unsigned int cmd, unsigned long arg)
+{
+	return video_usercopy(inode, file, cmd, arg, ts_do_ioctl);
+}
+
+
+static struct file_operations ts_fops =
+{
+	owner:	  THIS_MODULE,
+	open:	  ts_open,
+	release:  ts_release,
+	read:	  ts_read,
+	poll:	  ts_poll,
+	mmap:	  ts_mmap,
+	ioctl:	  ts_ioctl,
+	llseek:   no_llseek,
+};
+
+
+/* ----------------------------------------------------------- */
+/* exported stuff                                              */
+
+struct video_device saa7134_ts_template =
+{
+	name:          "saa7134-ts",
+	type:          0 /* FIXME */,
+	type2:         0 /* FIXME */,
+	hardware:      0,
+	fops:          &ts_fops,
+	minor:	       -1,
+};
+
+int saa7134_ts_init(struct saa7134_dev *dev)
+{
+	/* sanitycheck insmod options */
+	if (tsbufs < 2)
+		tsbufs = 2;
+	if (tsbufs > VIDEO_MAX_FRAME)
+		tsbufs = VIDEO_MAX_FRAME;
+
+	INIT_LIST_HEAD(&dev->ts_q.queue);
+	dev->ts_q.timeout.function = saa7134_buffer_timeout;
+	dev->ts_q.timeout.data     = (unsigned long)(&dev->ts_q);
+	dev->ts_q.dev              = dev;
+	videobuf_queue_init(&dev->ts.ts, &ts_qops, dev->pci, &dev->slock,
+			    V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			    sizeof(struct saa7134_buf));
+	saa7134_pgtable_alloc(dev->pci,&dev->ts.pt_ts);
+
+	/* init TS hw */
+	saa_writeb(SAA7134_TS_SERIAL1, 0x00);  /* deactivate TS softreset */
+	saa_writeb(SAA7134_TS_PARALLEL, 0xec); /* TSSOP high active, TSVAL high active, TSLOCK ignored */
+	saa_writeb(SAA7134_TS_PARALLEL_SERIAL, (TS_PACKET_SIZE-1));
+	saa_writeb(SAA7134_TS_DMA0, ((TS_NR_PACKETS-1)&0xff));
+	saa_writeb(SAA7134_TS_DMA1, (((TS_NR_PACKETS-1)>>8)&0xff));
+	saa_writeb(SAA7134_TS_DMA2, ((((TS_NR_PACKETS-1)>>16)&0x3f) | 0x00)); /* TSNOPIT=0, TSCOLAP=0 */	 
+ 
+	return 0;
+}
+
+int saa7134_ts_fini(struct saa7134_dev *dev)
+{
+	/* nothing */
+	saa7134_pgtable_free(dev->pci,&dev->ts.pt_ts);
+	return 0;
+}
+
+
+void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status)
+{
+	spin_lock(&dev->slock);
+	if (dev->ts_q.curr) {
+		saa7134_buffer_finish(dev,&dev->ts_q,STATE_DONE);
+	}
+	saa7134_buffer_next(dev,&dev->ts_q);
+	spin_unlock(&dev->slock);
+}
+
+/* ----------------------------------------------------------- */
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff -Nru a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,552 @@
+/*
+ * device driver for philips saa7134 based TV cards
+ * tv audio decoder (fm stereo, nicam, ...)
+ *
+ * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define __NO_VERSION__ 1
+
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <asm/div64.h>
+
+#include "saa7134-reg.h"
+#include "saa7134.h"
+
+/* ------------------------------------------------------------------ */
+
+static unsigned int audio_debug = 0;
+MODULE_PARM(audio_debug,"i");
+MODULE_PARM_DESC(audio_debug,"enable debug messages [tv audio]");
+
+#define dprintk(fmt, arg...)	if (audio_debug) \
+	printk(KERN_DEBUG "%s/audio: " fmt, dev->name, ## arg)
+
+#define print_regb(reg) printk("%s:   reg 0x%03x [%-16s]: 0x%02x\n", \
+		dev->name,(SAA7134_##reg),(#reg),saa_readb((SAA7134_##reg)))
+
+/* ------------------------------------------------------------------ */
+
+static struct saa7134_tvaudio tvaudio[] = {
+	{
+		name:          "PAL-B/G FM-stereo",
+		std:           V4L2_STD_PAL,
+		mode:          TVAUDIO_FM_BG_STEREO,
+		carr1:         5500,
+		carr2:         5742,
+	},{
+		name:          "PAL-D/K1 FM-stereo",
+		std:           V4L2_STD_PAL,
+		carr1:         6500,
+		carr2:         6258,
+		mode:          TVAUDIO_FM_BG_STEREO,
+	},{
+		name:          "PAL-D/K2 FM-stereo",
+		std:           V4L2_STD_PAL,
+		carr1:         6500,
+		carr2:         6742,
+		mode:          TVAUDIO_FM_BG_STEREO,
+	},{
+		name:          "PAL-D/K3 FM-stereo",
+		std:           V4L2_STD_PAL,
+		carr1:         6500,
+		carr2:         5742,
+		mode:          TVAUDIO_FM_BG_STEREO,
+	},{
+		name:          "PAL-B/G NICAM",
+		std:           V4L2_STD_PAL,
+		carr1:         5500,
+		carr2:         5850,
+		mode:          TVAUDIO_NICAM_FM,
+	},{
+		name:          "PAL-I NICAM",
+		std:           V4L2_STD_PAL,
+		carr1:         6000,
+		carr2:         6552,
+		mode:          TVAUDIO_NICAM_FM,
+	},{
+		name:          "PAL-D/K NICAM",
+		std:           V4L2_STD_PAL,
+		carr1:         6500,
+		carr2:         5850,
+		mode:          TVAUDIO_NICAM_FM,
+	},{
+		name:          "SECAM-L NICAM",
+		std:           V4L2_STD_SECAM,
+		carr1:         6500,
+		carr2:         5850,
+		mode:          TVAUDIO_NICAM_AM,
+	},{
+		name:          "NTSC-M",
+		std:           V4L2_STD_NTSC,
+		carr1:         4500,
+		carr2:         -1,
+		mode:          TVAUDIO_FM_MONO,
+	},{
+		name:          "NTSC-A2 FM-stereo",
+		std:           V4L2_STD_NTSC,
+		carr1:         4500,
+		carr2:         4724,
+		mode:          TVAUDIO_FM_K_STEREO,
+	}
+};
+#define TVAUDIO (sizeof(tvaudio)/sizeof(struct saa7134_tvaudio))
+
+/* ------------------------------------------------------------------ */
+
+static void tvaudio_init(struct saa7134_dev *dev)
+{
+	int clock = saa7134_boards[dev->board].audio_clock;
+
+	/* init all audio registers */
+	saa_writeb(SAA7134_AUDIO_PLL_CTRL,   0x00);
+		
+	saa_writeb(SAA7134_AUDIO_CLOCK0,      clock        & 0xff);
+	saa_writeb(SAA7134_AUDIO_CLOCK1,     (clock >>  8) & 0xff);
+	saa_writeb(SAA7134_AUDIO_CLOCK2,     (clock >> 16) & 0xff);
+	saa_writeb(SAA7134_AUDIO_PLL_CTRL,   0x01);
+
+	saa_writeb(SAA7134_NICAM_ERROR_LOW,  0x14);
+	saa_writeb(SAA7134_NICAM_ERROR_HIGH, 0x50);
+	saa_writeb(SAA7134_MONITOR_SELECT,   0xa0);
+	saa_writeb(SAA7134_FM_DEMATRIX,      0x80);
+}
+
+static __u32 tvaudio_carr2reg(__u32 carrier)
+{
+	__u64 a = carrier;
+
+	a <<= 24;
+	do_div(a,12288);
+	return a;
+}
+
+static void tvaudio_setcarrier(struct saa7134_dev *dev,
+			       int primary, int secondary)
+{
+	if (-1 == secondary)
+		secondary = primary;
+	saa_writel(SAA7134_CARRIER1_FREQ0 >> 2, tvaudio_carr2reg(primary));
+	saa_writel(SAA7134_CARRIER2_FREQ0 >> 2, tvaudio_carr2reg(secondary));
+}
+
+static void saa7134_tvaudio_do_mute_input(struct saa7134_dev *dev)
+{
+	int mute;
+	struct saa7134_input *in;
+	int reg = 0;
+	int mask;
+
+	/* look what is to do ... */
+	in   = dev->input;
+	mute = (dev->ctl_mute || dev->automute);
+	if (!card_has_audio(dev) && card(dev).mute.name) {
+		/* 7130 - we'll mute using some unconnected audio input */
+		if (mute)
+			in = &card(dev).mute;
+	}
+	if (dev->hw_mute  == mute &&
+	    dev->hw_input == in)
+		return;
+
+#if 1
+	dprintk("ctl_mute=%d automute=%d input=%s  =>  mute=%d input=%s\n",
+		dev->ctl_mute,dev->automute,dev->input->name,mute,in->name);
+#endif
+	dev->hw_mute  = mute;
+	dev->hw_input = in;
+
+	if (card_has_audio(dev))
+		/* 7134 mute */
+		saa_writeb(SAA7134_AUDIO_MUTE_CTRL, mute ? 0xff : 0xbb);
+
+	/* switch internal audio mux */
+	switch (in->amux) {
+	case TV:    reg = 0x02; break;
+	case LINE1: reg = 0x00; break;
+	case LINE2: reg = 0x01; break;
+	}
+	saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x07, reg);
+
+	/* switch gpio-connected external audio mux */
+	if (0 == card(dev).gpiomask)
+		return;
+	mask = card(dev).gpiomask;
+	saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   mask, mask);
+	saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio);
+	saa7134_track_gpio(dev,in->name);
+}
+
+void saa7134_tvaudio_setmute(struct saa7134_dev *dev)
+{
+	saa7134_tvaudio_do_mute_input(dev);
+}
+
+void saa7134_tvaudio_setinput(struct saa7134_dev *dev,
+			      struct saa7134_input *in)
+{
+	dev->input = in;
+	saa7134_tvaudio_do_mute_input(dev);
+}
+
+void saa7134_tvaudio_setvolume(struct saa7134_dev *dev, int level)
+{
+	saa_writeb(SAA7134_CHANNEL1_LEVEL,     level & 0x1f);
+	saa_writeb(SAA7134_CHANNEL2_LEVEL,     level & 0x1f);
+	saa_writeb(SAA7134_NICAM_LEVEL_ADJUST, level & 0x1f);
+}
+
+static void tvaudio_setmode(struct saa7134_dev *dev,
+			    struct saa7134_tvaudio *audio,
+			    char *note)
+{
+	if (note)
+		dprintk("tvaudio_setmode: %s %s [%d.%03d/%d.%03d MHz]\n",
+			note,audio->name,
+			audio->carr1 / 1000, audio->carr1 % 1000,
+			audio->carr2 / 1000, audio->carr2 % 1000);
+
+	if (dev->tvnorm->id == V4L2_STD_NTSC) {
+		saa_writeb(SAA7134_AUDIO_CLOCKS_PER_FIELD0, 0xde);
+		saa_writeb(SAA7134_AUDIO_CLOCKS_PER_FIELD1, 0x15);
+		saa_writeb(SAA7134_AUDIO_CLOCKS_PER_FIELD2, 0x02);
+	} else {
+		saa_writeb(SAA7134_AUDIO_CLOCKS_PER_FIELD0, 0x00);
+		saa_writeb(SAA7134_AUDIO_CLOCKS_PER_FIELD1, 0x80);
+		saa_writeb(SAA7134_AUDIO_CLOCKS_PER_FIELD2, 0x02);
+	}
+	tvaudio_setcarrier(dev,audio->carr1,audio->carr2);
+	
+	switch (audio->mode) {
+	case TVAUDIO_FM_MONO:
+	case TVAUDIO_FM_BG_STEREO:
+		saa_writeb(SAA7134_DEMODULATOR,               0x00);
+		saa_writeb(SAA7134_DCXO_IDENT_CTRL,           0x00);
+		saa_writeb(SAA7134_FM_DEEMPHASIS,             0x22);
+		saa_writeb(SAA7134_FM_DEMATRIX,               0x80);
+		saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT,  0xa0);
+		break;
+	case TVAUDIO_FM_K_STEREO:
+		saa_writeb(SAA7134_DEMODULATOR,               0x00);
+		saa_writeb(SAA7134_DCXO_IDENT_CTRL,           0x01);
+		saa_writeb(SAA7134_FM_DEEMPHASIS,             0x22);
+		saa_writeb(SAA7134_FM_DEMATRIX,               0x80);
+		saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT,  0xa0);
+		break;
+	case TVAUDIO_NICAM_FM:
+		saa_writeb(SAA7134_DEMODULATOR,               0x10);
+		saa_writeb(SAA7134_DCXO_IDENT_CTRL,           0x00);
+		saa_writeb(SAA7134_FM_DEEMPHASIS,             0x44);
+		saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT,  0xa1);
+		break;
+	case TVAUDIO_NICAM_AM:
+		saa_writeb(SAA7134_DEMODULATOR,               0x12);
+		saa_writeb(SAA7134_DCXO_IDENT_CTRL,           0x00);
+		saa_writeb(SAA7134_FM_DEEMPHASIS,             0x44);
+		saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT,  0xa1);
+		break;
+	case TVAUDIO_FM_SAT_STEREO:
+		/* not implemented (yet) */
+		break;
+	}
+	saa_writel(0x174 >> 2, 0x0001e000); /* FIXME */
+}
+
+int saa7134_tvaudio_getstereo(struct saa7134_dev *dev,
+			      struct saa7134_tvaudio *audio)
+{
+	__u32 idp,nicam;
+	int retval = -1;
+	
+	switch (audio->mode) {
+	case TVAUDIO_FM_MONO:
+		return V4L2_TUNER_SUB_MONO;
+	case TVAUDIO_FM_K_STEREO:
+	case TVAUDIO_FM_BG_STEREO:
+		idp = (saa_readb(SAA7134_IDENT_SIF) & 0xe0) >> 5;
+		if (0x03 == (idp & 0x03))
+			retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
+		else if (0x05 == (idp & 0x05))
+			retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+		else if (0x01 == (idp & 0x01))
+			retval = V4L2_TUNER_SUB_MONO;
+		break;
+	case TVAUDIO_FM_SAT_STEREO:
+		/* not implemented (yet) */
+		break;
+	case TVAUDIO_NICAM_FM:
+	case TVAUDIO_NICAM_AM:
+		nicam = saa_readb(SAA7134_NICAM_STATUS);
+		switch (nicam & 0x0b) {
+		case 0x08:
+			retval = V4L2_TUNER_SUB_MONO;
+			break;
+		case 0x09:
+			retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
+			break;
+		case 0x0a:
+			retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+			break;
+		}
+		break;
+	}
+	if (retval != -1)
+		dprintk("found audio subchannels:%s%s%s%s\n",
+			(retval & V4L2_TUNER_SUB_MONO)   ? " mono"   : "",
+			(retval & V4L2_TUNER_SUB_STEREO) ? " stereo" : "",
+			(retval & V4L2_TUNER_SUB_LANG1)  ? " lang1"  : "",
+			(retval & V4L2_TUNER_SUB_LANG2)  ? " lang2"  : "");
+	return retval;
+}
+
+static int tvaudio_sleep(struct saa7134_dev *dev, int timeout)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	
+	add_wait_queue(&dev->thread.wq, &wait);
+	current->state = TASK_INTERRUPTIBLE;
+	schedule_timeout(timeout);
+	remove_wait_queue(&dev->thread.wq, &wait);
+	return dev->thread.scan1 != dev->thread.scan2;
+}
+
+static int tvaudio_checkcarrier(struct saa7134_dev *dev, int carrier)
+{
+	__s32 left,right,value;
+	
+	tvaudio_setcarrier(dev,carrier-100,carrier-100);
+	if (tvaudio_sleep(dev,HZ/10))
+		return -1;
+	left = saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
+	if (tvaudio_sleep(dev,HZ/10))
+		return -1;
+	left = saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
+
+	tvaudio_setcarrier(dev,carrier+100,carrier+100);
+	if (tvaudio_sleep(dev,HZ/10))
+		return -1;
+        right = saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
+	if (tvaudio_sleep(dev,HZ/10))
+		return -1;
+	right = saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
+
+	left >>= 16;
+        right >>= 16;
+	value = left > right ? left - right : right - left;
+	dprintk("scanning %d.%03d MHz =>  dc is %5d [%d/%d]\n",
+		carrier/1000,carrier%1000,value,left,right);
+	return value;
+}
+
+static void sifdebug_dump_regs(struct saa7134_dev *dev)
+{
+	print_regb(AUDIO_STATUS);
+	print_regb(IDENT_SIF);
+	print_regb(LEVEL_READOUT1);
+	print_regb(LEVEL_READOUT2);
+	print_regb(DCXO_IDENT_CTRL);
+	print_regb(DEMODULATOR);
+	print_regb(AGC_GAIN_SELECT);
+	print_regb(MONITOR_SELECT);
+	print_regb(FM_DEEMPHASIS);
+	print_regb(FM_DEMATRIX);
+	print_regb(SIF_SAMPLE_FREQ);
+	print_regb(ANALOG_IO_SELECT);
+}
+
+static int tvaudio_thread(void *data)
+{
+#define MAX_SCAN 4
+	static const int carr_pal[MAX_SCAN]     = { 5500, 6000, 6500 };
+	static const int carr_ntsc[MAX_SCAN]    = { 4500 };
+	static const int carr_secam[MAX_SCAN]   = { 6500 };
+	static const int carr_default[MAX_SCAN] = { 4500, 5500, 6000, 6500 };
+	struct saa7134_dev *dev = data;
+	const int *carr_scan;
+	int carr_vals[4];
+	int i,max,carrier,audio;
+
+	lock_kernel();
+	daemonize();
+	sigfillset(&current->blocked);
+	sprintf(current->comm, "%s", dev->name);
+	dev->thread.task = current;
+	unlock_kernel();
+	if (dev->thread.notify != NULL)
+		up(dev->thread.notify);
+
+	for (;;) {
+		if (dev->thread.exit || signal_pending(current))
+			goto done;
+		interruptible_sleep_on(&dev->thread.wq);
+		if (dev->thread.exit || signal_pending(current))
+			goto done;
+
+	restart:
+		dev->thread.scan1 = dev->thread.scan2;
+		dprintk("tvaudio thread scan start [%d]\n",dev->thread.scan1);
+		dev->tvaudio  = NULL;
+		tvaudio_init(dev);
+		dev->automute = 1;
+		saa7134_tvaudio_setmute(dev);
+
+		/* give the tuner some time */
+		if (tvaudio_sleep(dev,HZ/2))
+			goto restart;
+
+		/* find the main carrier */
+		carr_scan = carr_default;
+		if (dev->tvnorm->id & V4L2_STD_PAL)
+			carr_scan = carr_pal;
+		if (dev->tvnorm->id & V4L2_STD_NTSC)
+			carr_scan = carr_ntsc;
+		if (dev->tvnorm->id & V4L2_STD_SECAM)
+			carr_scan = carr_secam;
+		saa_writeb(SAA7134_MONITOR_SELECT,0x00);
+		tvaudio_setmode(dev,&tvaudio[0],NULL);
+		for (i = 0; i < MAX_SCAN; i++) {
+			if (!carr_scan[i])
+				continue;
+			carr_vals[i] = tvaudio_checkcarrier(dev,carr_scan[i]);
+			if (dev->thread.scan1 != dev->thread.scan2)
+				goto restart;
+		}
+		for (carrier = 0, max = 0, i = 0; i < MAX_SCAN; i++) {
+			if (!carr_scan[i])
+				continue;
+			if (max < carr_vals[i]) {
+				max = carr_vals[i];
+				carrier = carr_scan[i];
+			}
+		}
+		if (0 == carrier) {
+			/* Oops: autoscan didn't work for some reason :-/ */
+			printk("%s/audio: oops: audio carrier scan failed\n",
+			       dev->name);
+			sifdebug_dump_regs(dev);
+		} else {
+			dprintk("found %s main sound carrier @ %d.%03d MHz\n",
+				dev->tvnorm->name,
+				carrier/1000,carrier%1000);
+		}
+		tvaudio_setcarrier(dev,carrier,carrier);
+		dev->automute = 0;
+		saa7134_tvaudio_setmute(dev);
+
+		/* find the exact tv audio norm */
+		for (audio = -1, i = 0; i < TVAUDIO; i++) {
+			if (dev->tvnorm->id != -1 &&
+			    dev->tvnorm->id != tvaudio[i].std)
+				continue;
+			if (tvaudio[i].carr1 != carrier)
+				continue;
+
+			if (-1 == audio)
+				audio = i;
+			tvaudio_setmode(dev,&tvaudio[i],"trying");
+			if (tvaudio_sleep(dev,HZ))
+				goto restart;
+			if (-1 != saa7134_tvaudio_getstereo(dev,&tvaudio[i])) {
+				audio = i;
+				break;
+			}
+		}
+		if (-1 == audio)
+			continue;
+		tvaudio_setmode(dev,&tvaudio[audio],"using");
+		dev->tvaudio = &tvaudio[audio];
+
+#if 1
+		if (tvaudio_sleep(dev,3*HZ))
+			goto restart;
+		saa7134_tvaudio_getstereo(dev,&tvaudio[i]);
+#endif
+	}
+
+ done:
+	dev->thread.task = NULL;
+	if(dev->thread.notify != NULL)
+		up(dev->thread.notify);
+	return 0;
+}
+
+/* ------------------------------------------------------------------ */
+
+int saa7134_tvaudio_init(struct saa7134_dev *dev)
+{
+	DECLARE_MUTEX_LOCKED(sem);
+
+	/* enable I2S audio output */
+	if (saa7134_boards[dev->board].i2s_rate) {
+		int rate = (32000 == saa7134_boards[dev->board].i2s_rate) ? 0x01 : 0x03;
+		
+		/* set rate */ 
+		saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate);
+
+		/* enable I2S output */
+		saa_writeb(SAA7134_DSP_OUTPUT_SELECT,  0x80);
+		saa_writeb(SAA7134_I2S_OUTPUT_SELECT,  0x80);
+		saa_writeb(SAA7134_I2S_OUTPUT_FORMAT,  0x01);
+		saa_writeb(SAA7134_I2S_OUTPUT_LEVEL,   0x00);	
+		saa_writeb(SAA7134_I2S_AUDIO_OUTPUT,   0x01);
+	}
+
+	/* start tvaudio thread */
+	init_waitqueue_head(&dev->thread.wq);
+	dev->thread.notify = &sem;
+	kernel_thread(tvaudio_thread,dev,0);
+	down(&sem);
+	dev->thread.notify = NULL;
+	wake_up_interruptible(&dev->thread.wq);
+
+	return 0;
+}
+
+int saa7134_tvaudio_fini(struct saa7134_dev *dev)
+{
+	DECLARE_MUTEX_LOCKED(sem);
+
+	/* shutdown tvaudio thread */
+	if (dev->thread.task) {
+		dev->thread.notify = &sem;
+		dev->thread.exit = 1;
+		wake_up_interruptible(&dev->thread.wq);
+		down(&sem);
+		dev->thread.notify = NULL;
+	}
+	saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x07, 0x00); /* LINE1 */
+	return 0;
+}
+
+int saa7134_tvaudio_do_scan(struct saa7134_dev *dev)
+{
+	dev->thread.scan2++;
+	wake_up_interruptible(&dev->thread.wq);
+	return 0;
+}
+
+/* ----------------------------------------------------------- */
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff -Nru a/drivers/media/video/saa7134/saa7134-vbi.c b/drivers/media/video/saa7134/saa7134-vbi.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/media/video/saa7134/saa7134-vbi.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,265 @@
+/*
+ * device driver for philips saa7134 based TV cards
+ * video4linux video interface
+ *
+ * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define __NO_VERSION__ 1
+
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#include "saa7134-reg.h"
+#include "saa7134.h"
+
+/* ------------------------------------------------------------------ */
+
+static unsigned int vbi_debug  = 0;
+MODULE_PARM(vbi_debug,"i");
+MODULE_PARM_DESC(vbi_debug,"enable debug messages [vbi]");
+
+static unsigned int vbibufs = 4;
+MODULE_PARM(vbibufs,"i");
+MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32");
+
+#define dprintk(fmt, arg...)	if (vbi_debug) \
+	printk(KERN_DEBUG "%s/vbi: " fmt, dev->name, ## arg)
+
+/* ------------------------------------------------------------------ */
+
+#define VBI_LINE_COUNT     16
+#define VBI_LINE_LENGTH  2048
+#define VBI_SCALE       0x200
+
+static void task_init(struct saa7134_dev *dev, struct saa7134_buf *buf,
+		      int task)
+{
+	struct saa7134_tvnorm *norm = dev->tvnorm;
+	
+	/* setup video scaler */
+	saa_writeb(SAA7134_VBI_H_START1(task), norm->h_start     &  0xff);
+	saa_writeb(SAA7134_VBI_H_START2(task), norm->h_start     >> 8);
+	saa_writeb(SAA7134_VBI_H_STOP1(task),  norm->h_stop      &  0xff);
+	saa_writeb(SAA7134_VBI_H_STOP2(task),  norm->h_stop      >> 8);
+	saa_writeb(SAA7134_VBI_V_START1(task), norm->vbi_v_start &  0xff);
+	saa_writeb(SAA7134_VBI_V_START2(task), norm->vbi_v_start >> 8);
+	saa_writeb(SAA7134_VBI_V_STOP1(task),  norm->vbi_v_stop  &  0xff);
+	saa_writeb(SAA7134_VBI_V_STOP2(task),  norm->vbi_v_stop  >> 8);
+
+	saa_writeb(SAA7134_VBI_H_SCALE_INC1(task),        VBI_SCALE & 0xff);
+	saa_writeb(SAA7134_VBI_H_SCALE_INC2(task),        VBI_SCALE >> 8);
+	saa_writeb(SAA7134_VBI_PHASE_OFFSET_LUMA(task),   0x00);
+	saa_writeb(SAA7134_VBI_PHASE_OFFSET_CHROMA(task), 0x00);
+
+	saa_writeb(SAA7134_VBI_H_LEN1(task), buf->vb.width   & 0xff);
+	saa_writeb(SAA7134_VBI_H_LEN2(task), buf->vb.width   >> 8);
+	saa_writeb(SAA7134_VBI_V_LEN1(task), buf->vb.height  & 0xff);
+	saa_writeb(SAA7134_VBI_V_LEN2(task), buf->vb.height  >> 8);
+
+	saa_andorb(SAA7134_DATA_PATH(task), 0xc0, 0x00);
+}
+
+/* ------------------------------------------------------------------ */
+
+static int buffer_activate(struct saa7134_dev *dev,
+			   struct saa7134_buf *buf,
+			   struct saa7134_buf *next)
+{
+	unsigned long control,base;
+
+	dprintk("buffer_activate [%p]\n",buf);
+	buf->vb.state = STATE_ACTIVE;
+
+	task_init(dev,buf,TASK_A);
+	task_init(dev,buf,TASK_B);
+	saa_writeb(SAA7134_OFMT_DATA_A, 0x06);
+	saa_writeb(SAA7134_OFMT_DATA_B, 0x06);
+
+	/* DMA: setup channel 2+3 (= VBI Task A+B) */
+	base    = saa7134_buffer_base(buf);
+	control = SAA7134_RS_CONTROL_BURST_16 |
+		SAA7134_RS_CONTROL_ME |
+		(buf->pt->dma >> 12);
+	saa_writel(SAA7134_RS_BA1(2),base);
+	saa_writel(SAA7134_RS_BA2(2),base + buf->vb.size/2);
+	saa_writel(SAA7134_RS_PITCH(2),buf->vb.width);
+	saa_writel(SAA7134_RS_CONTROL(2),control);
+	saa_writel(SAA7134_RS_BA1(3),base);
+	saa_writel(SAA7134_RS_BA2(3),base + buf->vb.size/2);
+	saa_writel(SAA7134_RS_PITCH(3),buf->vb.width);
+	saa_writel(SAA7134_RS_CONTROL(3),control);
+
+	/* start DMA */
+	saa7134_set_dmabits(dev);
+	mod_timer(&dev->vbi_q.timeout, jiffies+BUFFER_TIMEOUT);
+
+	return 0;
+}
+
+static int buffer_prepare(struct file *file, struct videobuf_buffer *vb)
+{
+	struct saa7134_fh *fh   = file->private_data;
+	struct saa7134_dev *dev = fh->dev;
+	struct saa7134_buf *buf = (struct saa7134_buf *)vb;
+	struct saa7134_tvnorm *norm = dev->tvnorm;
+	int lines, llength, size, err;
+
+	lines   = norm->vbi_v_stop - norm->vbi_v_start +1;
+	if (lines > VBI_LINE_COUNT)
+		lines = VBI_LINE_COUNT;
+#if 1
+	llength = VBI_LINE_LENGTH;
+#else
+	llength = (norm->h_stop - norm->h_start +1) * 2;
+	if (llength > VBI_LINE_LENGTH)
+		llength = VBI_LINE_LENGTH;
+#endif
+	size = lines * llength * 2;
+	if (0 != buf->vb.baddr  &&  buf->vb.bsize < size)
+		return -EINVAL;
+
+	if (buf->vb.size != size)
+		saa7134_dma_free(dev,buf);
+
+	if (STATE_NEEDS_INIT == buf->vb.state) {
+		buf->vb.width  = llength;
+		buf->vb.height = lines;
+		buf->vb.size   = size;
+		buf->pt        = &fh->pt_vbi;
+
+		err = videobuf_iolock(dev->pci,&buf->vb);
+		if (err)
+			goto oops;
+		err = saa7134_pgtable_build(dev->pci,buf->pt,
+					    buf->vb.dma.sglist,
+					    buf->vb.dma.sglen,
+					    saa7134_buffer_startpage(buf));
+		if (err)
+			goto oops;
+	}
+	buf->vb.state = STATE_PREPARED;
+	buf->top_seen = 0;
+	buf->activate = buffer_activate;
+	buf->vb.field = V4L2_FIELD_SEQ_TB;
+	return 0;
+
+ oops:
+	saa7134_dma_free(dev,buf);
+	return err;
+}
+
+static int
+buffer_setup(struct file *file, int *count, int *size)
+{
+	struct saa7134_fh *fh   = file->private_data;
+	struct saa7134_dev *dev = fh->dev;
+	int llength,lines;
+	
+	lines   = dev->tvnorm->vbi_v_stop - dev->tvnorm->vbi_v_start +1;
+#if 1
+	llength = VBI_LINE_LENGTH;
+#else
+	llength = (norm->h_stop - norm->h_start +1) * 2;
+	if (llength > VBI_LINE_LENGTH)
+		llength = VBI_LINE_LENGTH;
+#endif
+	*size = lines * llength * 2;
+	if (0 == *count)
+		*count = vbibufs;
+	*count = saa7134_buffer_count(*size,*count);
+	return 0;
+}
+
+static void buffer_queue(struct file *file, struct videobuf_buffer *vb)
+{
+	struct saa7134_fh *fh = file->private_data;
+	struct saa7134_dev *dev = fh->dev;
+	struct saa7134_buf *buf = (struct saa7134_buf *)vb;
+	
+	saa7134_buffer_queue(dev,&dev->vbi_q,buf);
+}
+
+static void buffer_release(struct file *file, struct videobuf_buffer *vb)
+{
+	struct saa7134_fh *fh   = file->private_data;
+	struct saa7134_dev *dev = fh->dev;
+	struct saa7134_buf *buf = (struct saa7134_buf *)vb;
+	
+	saa7134_dma_free(dev,buf);
+}
+
+struct videobuf_queue_ops saa7134_vbi_qops = {
+	buf_setup:    buffer_setup,
+	buf_prepare:  buffer_prepare,
+	buf_queue:    buffer_queue,
+	buf_release:  buffer_release,
+};
+
+/* ------------------------------------------------------------------ */
+
+int saa7134_vbi_init(struct saa7134_dev *dev)
+{
+	INIT_LIST_HEAD(&dev->vbi_q.queue);
+	dev->vbi_q.timeout.function = saa7134_buffer_timeout;
+	dev->vbi_q.timeout.data     = (unsigned long)(&dev->vbi_q);
+	dev->vbi_q.dev              = dev;
+
+	if (vbibufs < 2)
+		vbibufs = 2;
+	if (vbibufs > VIDEO_MAX_FRAME)
+		vbibufs = VIDEO_MAX_FRAME;
+	return 0;
+}
+
+int saa7134_vbi_fini(struct saa7134_dev *dev)
+{
+	/* nothing */
+	return 0;
+}
+
+void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status)
+{
+	spin_lock(&dev->slock);
+	if (dev->vbi_q.curr) {
+		dev->vbi_fieldcount++;
+		/* make sure we have seen both fields */
+		if ((status & 0x10) == 0x10) {
+			dev->vbi_q.curr->top_seen = 1;
+			goto done;
+		}
+		if (!dev->vbi_q.curr->top_seen)
+			goto done;
+
+		dev->vbi_q.curr->vb.field_count = dev->vbi_fieldcount;
+		saa7134_buffer_finish(dev,&dev->vbi_q,STATE_DONE);
+	}
+	saa7134_buffer_next(dev,&dev->vbi_q);
+
+ done:
+	spin_unlock(&dev->slock);
+}
+
+/* ----------------------------------------------------------- */
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff -Nru a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/media/video/saa7134/saa7134-video.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,2035 @@
+/*
+ * device driver for philips saa7134 based TV cards
+ * video4linux video interface
+ *
+ * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define __NO_VERSION__ 1
+
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#include "saa7134-reg.h"
+#include "saa7134.h"
+#include "tuner.h"
+#include "audiochip.h"
+
+/* ------------------------------------------------------------------ */
+
+static unsigned int video_debug  = 0;
+static unsigned int gbuffers     = 8;
+static unsigned int gbufsize     = 768*576*4;
+static unsigned int gbufsize_max = 768*576*4;
+MODULE_PARM(video_debug,"i");
+MODULE_PARM_DESC(video_debug,"enable debug messages [video]");
+MODULE_PARM(gbuffers,"i");
+MODULE_PARM_DESC(gbuffers,"number of capture buffers, range 2-32");
+
+#define dprintk(fmt, arg...)	if (video_debug) \
+	printk(KERN_DEBUG "%s/video: " fmt, dev->name, ## arg)
+
+/* ------------------------------------------------------------------ */
+/* data structs for video                                             */
+
+static int video_out[][9] = {
+	[CCIR656] = { 0x00, 0xb1, 0x00, 0xa1, 0x00, 0x04, 0x06, 0x00, 0x00 },
+};
+		
+static struct saa7134_format formats[] = {
+	{
+		name:     "8 bpp gray",
+		fourcc:   V4L2_PIX_FMT_GREY,
+		depth:    8,
+		pm:       0x06,
+	},{
+		name:     "15 bpp RGB, le",
+		fourcc:   V4L2_PIX_FMT_RGB555,
+		depth:    16,
+		pm:       0x13 | 0x80,
+	},{
+		name:     "15 bpp RGB, be",
+		fourcc:   V4L2_PIX_FMT_RGB555X,
+		depth:    16,
+		pm:       0x13 | 0x80,
+		bswap:    1,
+	},{
+		name:     "16 bpp RGB, le",
+		fourcc:   V4L2_PIX_FMT_RGB565,
+		depth:    16,
+		pm:       0x10 | 0x80,
+	},{
+		name:     "16 bpp RGB, be",
+		fourcc:   V4L2_PIX_FMT_RGB565X,
+		depth:    16,
+		pm:       0x10 | 0x80,
+		bswap:    1,
+	},{
+		name:     "24 bpp RGB, le",
+		fourcc:   V4L2_PIX_FMT_BGR24,
+		depth:    24,
+		pm:       0x11,
+	},{
+		name:     "32 bpp RGB, le",
+		fourcc:   V4L2_PIX_FMT_BGR32,
+		depth:    32,
+		pm:       0x12,
+	},{
+		name:     "32 bpp RGB, be",
+		fourcc:   V4L2_PIX_FMT_RGB32,
+		depth:    32,
+		pm:       0x12,
+		bswap:    1,
+		wswap:    1,
+	},{
+		name:     "4:2:2 packed, YUYV",
+		fourcc:   V4L2_PIX_FMT_YUYV,
+		depth:    16,
+		pm:       0x00,
+		bswap:    1,
+		yuv:      1,
+	},{
+		name:     "4:2:2 packed, UYVY",
+		fourcc:   V4L2_PIX_FMT_UYVY,
+		depth:    16,
+		pm:       0x00,
+		yuv:      1,
+	},{
+		name:     "4:2:2 planar, Y-Cb-Cr",
+		fourcc:   V4L2_PIX_FMT_YUV422P,
+		depth:    16,
+		pm:       0x09,
+		yuv:      1,
+		planar:   1,
+		hshift:   1,
+		vshift:   0,
+	},{
+		name:     "4:2:0 planar, Y-Cb-Cr",
+		fourcc:   V4L2_PIX_FMT_YUV420,
+		depth:    12,
+		pm:       0x0a,
+		yuv:      1,
+		planar:   1,
+		hshift:   1,
+		vshift:   1,
+	}
+};
+#define FORMATS (sizeof(formats)/sizeof(struct saa7134_format))
+
+
+static struct saa7134_tvnorm tvnorms[] = {
+	{
+		name:          "PAL-BGHI",
+		id:            V4L2_STD_PAL,
+		width:         720,
+		height:        576,
+
+		sync_control:  0x18,
+		luma_control:  0x40,
+		chroma_ctrl1:  0x81,
+		chroma_gain:   0x2a,
+		chroma_ctrl2:  0x06,
+
+		h_start:       0,
+		h_stop:        719,
+		video_v_start: 24,
+		video_v_stop:  311,
+		vbi_v_start:   7-3,  /* FIXME */
+		vbi_v_stop:    22-3,
+	},{
+		name:          "NTSC-M",
+		id:            V4L2_STD_NTSC,
+		width:         720,
+		height:        480,
+
+		sync_control:  0x59,
+		luma_control:  0x40,
+		chroma_ctrl1:  0x89,
+		chroma_gain:   0x2a,
+		chroma_ctrl2:  0x0e,
+
+		h_start:       0,
+		h_stop:        719,
+		video_v_start: 22,
+		video_v_stop:  22+240,
+		vbi_v_start:   10, /* FIXME */
+		vbi_v_stop:    21, /* FIXME */
+	},{
+		name:          "SECAM",
+		id:            V4L2_STD_SECAM,
+		width:         720,
+		height:        576,
+
+		sync_control:  0x58,
+		luma_control:  0x1b,
+		chroma_ctrl1:  0xd1,
+		chroma_gain:   0x80,
+		chroma_ctrl2:  0x00,
+
+		h_start:       0,
+		h_stop:        719,
+		video_v_start: 24,
+		video_v_stop:  311,
+		vbi_v_start:   7,
+		vbi_v_stop:    22,
+	},{
+		name:          "AUTO",
+		id:            -1,
+		width:         768,
+		height:        576,
+
+		sync_control:  0x98,
+		luma_control:  0x40,
+		chroma_ctrl1:  0x8b,
+		chroma_gain:   0x00,
+		chroma_ctrl2:  0x00,
+
+		h_start:       0,
+		h_stop:        719,
+		video_v_start: 24,
+		video_v_stop:  311,
+		vbi_v_start:   7,
+		vbi_v_stop:    22,
+	}
+};
+#define TVNORMS (sizeof(tvnorms)/sizeof(struct saa7134_tvnorm))
+
+
+#define V4L2_CID_PRIVATE_INVERT      (V4L2_CID_PRIVATE_BASE + 0)
+#define V4L2_CID_PRIVATE_Y_ODD       (V4L2_CID_PRIVATE_BASE + 1)
+#define V4L2_CID_PRIVATE_Y_EVEN      (V4L2_CID_PRIVATE_BASE + 2)
+#define V4L2_CID_PRIVATE_LASTP1      (V4L2_CID_PRIVATE_BASE + 3)
+
+static const struct v4l2_queryctrl no_ctrl = {
+	name:  "42",
+	flags: V4L2_CTRL_FLAG_DISABLED,
+};
+static const struct v4l2_queryctrl video_ctrls[] = {
+	/* --- video --- */
+	{
+		id:            V4L2_CID_BRIGHTNESS,
+		name:          "Brightness",
+		minimum:       0,
+		maximum:       255,
+		step:          1,
+		default_value: 128,
+		type:          V4L2_CTRL_TYPE_INTEGER,
+	},{
+		id:            V4L2_CID_CONTRAST,
+		name:          "Contrast",
+		minimum:       0,
+		maximum:       127,
+		step:          1,
+		default_value: 68,
+		type:          V4L2_CTRL_TYPE_INTEGER,
+	},{
+		id:            V4L2_CID_SATURATION,
+		name:          "Saturation",
+		minimum:       0,
+		maximum:       127,
+		step:          1,
+		default_value: 64,
+		type:          V4L2_CTRL_TYPE_INTEGER,
+	},{
+		id:            V4L2_CID_HUE,
+		name:          "Hue",
+		minimum:       -128,
+		maximum:       127,
+		step:          1,
+		default_value: 0,
+		type:          V4L2_CTRL_TYPE_INTEGER,
+	},{
+		id:            V4L2_CID_VFLIP,
+		name:          "vertical flip",
+		minimum:       0,
+		maximum:       1,
+		type:          V4L2_CTRL_TYPE_BOOLEAN,
+	},
+	/* --- audio --- */
+	{
+		id:            V4L2_CID_AUDIO_MUTE,
+		name:          "Mute",
+		minimum:       0,
+		maximum:       1,
+		type:          V4L2_CTRL_TYPE_BOOLEAN,
+	},{
+		id:            V4L2_CID_AUDIO_VOLUME,
+		name:          "Volume",
+		minimum:       -15,
+		maximum:       15,
+		step:          1,
+		default_value: 0,
+		type:          V4L2_CTRL_TYPE_INTEGER,
+	},
+	/* --- private --- */
+	{
+		id:            V4L2_CID_PRIVATE_INVERT,
+		name:          "Invert",
+		minimum:       0,
+		maximum:       1,
+		type:          V4L2_CTRL_TYPE_BOOLEAN,
+	},{
+		id:            V4L2_CID_PRIVATE_Y_ODD,
+		name:          "y offset odd field",
+		minimum:       0,
+		maximum:       128,
+		default_value: 0,
+		type:          V4L2_CTRL_TYPE_INTEGER,
+	},{
+		id:            V4L2_CID_PRIVATE_Y_EVEN,
+		name:          "y offset even field",
+		minimum:       0,
+		maximum:       128,
+		default_value: 0,
+		type:          V4L2_CTRL_TYPE_INTEGER,
+	}
+};
+const int CTRLS = (sizeof(video_ctrls)/sizeof(struct v4l2_queryctrl));
+
+static const struct v4l2_queryctrl* ctrl_by_id(int id)
+{
+	int i;
+	
+	for (i = 0; i < CTRLS; i++)
+		if (video_ctrls[i].id == id)
+			return video_ctrls+i;
+	return NULL;
+}
+
+static struct saa7134_format* format_by_fourcc(int  fourcc)
+{
+	int i;
+
+	for (i = 0; i < FORMATS; i++)
+		if (formats[i].fourcc == fourcc)
+			return formats+i;
+	return NULL;
+}
+
+/* ----------------------------------------------------------------------- */
+/* resource management                                                     */
+
+static int res_get(struct saa7134_dev *dev, struct saa7134_fh *fh, int bit)
+{
+	if (fh->resources & bit)
+		/* have it already allocated */
+		return 1;
+
+	/* is it free? */
+	down(&dev->lock);
+	if (dev->resources & bit) {
+		/* no, someone else uses it */
+		up(&dev->lock);
+		return 0;
+	}
+	/* it's free, grab it */
+	fh->resources  |= bit;
+	dev->resources |= bit;
+	dprintk("res: get %d\n",bit);
+	up(&dev->lock);
+	return 1;
+}
+
+static
+int res_check(struct saa7134_fh *fh, int bit)
+{
+	return (fh->resources & bit);
+}
+
+static
+int res_locked(struct saa7134_dev *dev, int bit)
+{
+	return (dev->resources & bit);
+}
+
+static
+void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, int bits)
+{
+	if ((fh->resources & bits) != bits)
+		BUG();
+
+	down(&dev->lock);
+	fh->resources  &= ~bits;
+	dev->resources &= ~bits;
+	dprintk("res: put %d\n",bits);
+	up(&dev->lock);
+}
+
+/* ------------------------------------------------------------------ */
+
+static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
+{
+	struct video_channel c;
+	int luma_control,mux;
+
+	dprintk("set tv norm = %s\n",norm->name);
+	dev->tvnorm = norm;
+
+	mux = card_in(dev,dev->ctl_input).vmux;
+	luma_control = norm->luma_control;
+	if (mux > 5)
+		luma_control |= 0x80; /* svideo */
+
+	/* setup video decoder */
+	saa_writeb(SAA7134_INCR_DELAY,            0x08);
+	saa_writeb(SAA7134_ANALOG_IN_CTRL1,       0xc0 | mux);
+	saa_writeb(SAA7134_ANALOG_IN_CTRL2,       0x00);
+
+	saa_writeb(SAA7134_ANALOG_IN_CTRL3,       0x90);
+	saa_writeb(SAA7134_ANALOG_IN_CTRL4,       0x90);
+	saa_writeb(SAA7134_HSYNC_START,           0xeb);
+	saa_writeb(SAA7134_HSYNC_STOP,            0xe0);
+
+	saa_writeb(SAA7134_SYNC_CTRL,             norm->sync_control);
+	saa_writeb(SAA7134_LUMA_CTRL,             luma_control);
+	saa_writeb(SAA7134_DEC_LUMA_BRIGHT,       dev->ctl_bright);
+	saa_writeb(SAA7134_DEC_LUMA_CONTRAST,     dev->ctl_contrast);
+ 
+	saa_writeb(SAA7134_DEC_CHROMA_SATURATION, dev->ctl_saturation);
+	saa_writeb(SAA7134_DEC_CHROMA_HUE,        dev->ctl_hue);
+	saa_writeb(SAA7134_CHROMA_CTRL1,          norm->chroma_ctrl1);
+	saa_writeb(SAA7134_CHROMA_GAIN,           norm->chroma_gain);
+
+	saa_writeb(SAA7134_CHROMA_CTRL2,          norm->chroma_ctrl2);
+	saa_writeb(SAA7134_MODE_DELAY_CTRL,       0x00);
+
+	saa_writeb(SAA7134_ANALOG_ADC,            0x01);
+	saa_writeb(SAA7134_VGATE_START,           0x11);
+	saa_writeb(SAA7134_VGATE_STOP,            0xfe);
+	saa_writeb(SAA7134_MISC_VGATE_MSB,        0x18); /* FIXME */
+	saa_writeb(SAA7134_RAW_DATA_GAIN,         0x40);
+	saa_writeb(SAA7134_RAW_DATA_OFFSET,       0x80);
+
+	/* pass down info to the i2c chips (v4l1) */
+	memset(&c,0,sizeof(c));
+	c.channel = dev->ctl_input;
+	c.norm = VIDEO_MODE_PAL;
+	if (norm->id & V4L2_STD_NTSC)
+		c.norm = VIDEO_MODE_NTSC;
+	if (norm->id & V4L2_STD_SECAM)
+		c.norm = VIDEO_MODE_SECAM;
+	saa7134_i2c_call_clients(dev,VIDIOCSCHAN,&c);
+}
+
+static void video_mux(struct saa7134_dev *dev, int input)
+{
+	dprintk("video input = %d [%s]\n",input,card_in(dev,input).name);
+	dev->ctl_input = input;
+	set_tvnorm(dev,dev->tvnorm);
+	saa7134_tvaudio_setinput(dev,&card_in(dev,input));
+}
+
+static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale)
+{
+	static const struct {
+		int xpsc;
+		int xacl;
+		int xc2_1;
+		int xdcg;
+		int vpfy;
+	} vals[] = {
+		/* XPSC XACL XC2_1 XDCG VPFY */
+		{    1,   0,    0,    0,   0 },
+		{    2,   2,    1,    2,   2 },
+		{    3,   4,    1,    3,   2 },
+		{    4,   8,    1,    4,   2 },
+		{    5,   8,    1,    4,   2 },
+		{    6,   8,    1,    4,   3 },
+		{    7,   8,    1,    4,   3 },
+		{    8,  15,    0,    4,   3 },
+		{    9,  15,    0,    4,   3 },
+		{   10,  16,    1,    5,   3 },
+	};
+	static const int count = sizeof(vals)/sizeof(vals[0]);
+	int i;
+
+	for (i = 0; i < count; i++)
+		if (vals[i].xpsc == prescale)
+			break;
+	if (i == count)
+		return;
+
+	saa_writeb(SAA7134_H_PRESCALE(task), vals[i].xpsc);
+	saa_writeb(SAA7134_ACC_LENGTH(task), vals[i].xacl);
+	saa_writeb(SAA7134_LEVEL_CTRL(task),
+		   (vals[i].xc2_1 << 3) | (vals[i].xdcg));
+	saa_andorb(SAA7134_FIR_PREFILTER_CTRL(task), 0x0f,
+		   (vals[i].vpfy << 2) | vals[i].vpfy);
+}
+
+static void set_v_scale(struct saa7134_dev *dev, int task, int yscale)
+{
+	int val,mirror;
+	
+	saa_writeb(SAA7134_V_SCALE_RATIO1(task), yscale &  0xff);
+	saa_writeb(SAA7134_V_SCALE_RATIO2(task), yscale >> 8);
+
+	mirror = (dev->ctl_mirror) ? 0x02 : 0x00;
+	if (yscale < 2048) {
+		/* LPI */
+		dprintk("yscale LPI yscale=%d\n",yscale);
+		saa_writeb(SAA7134_V_FILTER(task), 0x00 | mirror);
+		saa_writeb(SAA7134_LUMA_CONTRAST(task), 0x40);
+		saa_writeb(SAA7134_CHROMA_SATURATION(task), 0x40);
+	} else {
+		/* ACM */
+		val = 0x40 * 1024 / yscale;
+		dprintk("yscale ACM yscale=%d val=0x%x\n",yscale,val);
+		saa_writeb(SAA7134_V_FILTER(task), 0x01 | mirror);
+		saa_writeb(SAA7134_LUMA_CONTRAST(task), val);
+		saa_writeb(SAA7134_CHROMA_SATURATION(task), val);
+	}
+	saa_writeb(SAA7134_LUMA_BRIGHT(task),       0x80);
+}
+
+static void set_size(struct saa7134_dev *dev, int task,
+		     int width, int height, int interlace)
+{
+	struct saa7134_tvnorm *norm = dev->tvnorm;
+	int prescale,xscale,yscale,y_even,y_odd;
+	int div = interlace ? 2 : 1;
+
+	/* setup video scaler */
+	saa_writeb(SAA7134_VIDEO_H_START1(task), norm->h_start       &  0xff);
+	saa_writeb(SAA7134_VIDEO_H_START2(task), norm->h_start       >> 8);
+	saa_writeb(SAA7134_VIDEO_H_STOP1(task),  norm->h_stop        &  0xff);
+	saa_writeb(SAA7134_VIDEO_H_STOP2(task),  norm->h_stop        >> 8);
+	saa_writeb(SAA7134_VIDEO_V_START1(task), norm->video_v_start &  0xff);
+	saa_writeb(SAA7134_VIDEO_V_START2(task), norm->video_v_start >> 8);
+	saa_writeb(SAA7134_VIDEO_V_STOP1(task),  norm->video_v_stop  &  0xff);
+	saa_writeb(SAA7134_VIDEO_V_STOP2(task),  norm->video_v_stop  >> 8);
+
+	prescale = norm->width / width;
+	if (0 == prescale)
+		prescale = 1;
+	xscale = 1024 * norm->width / prescale / width;
+	yscale = 512 * div * norm->height / height;
+       	dprintk("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale);
+	set_h_prescale(dev,task,prescale);
+	saa_writeb(SAA7134_H_SCALE_INC1(task),      xscale &  0xff);
+	saa_writeb(SAA7134_H_SCALE_INC2(task),      xscale >> 8);
+	set_v_scale(dev,task,yscale);
+	
+	saa_writeb(SAA7134_VIDEO_PIXELS1(task),     width  & 0xff);
+	saa_writeb(SAA7134_VIDEO_PIXELS2(task),     width  >> 8);
+	saa_writeb(SAA7134_VIDEO_LINES1(task),      height/div & 0xff);
+	saa_writeb(SAA7134_VIDEO_LINES2(task),      height/div >> 8);
+
+	/* deinterlace y offsets */
+	if (interlace) {
+		y_odd  = dev->ctl_y_odd;
+		y_even = dev->ctl_y_even + yscale / 32;
+		saa_writeb(SAA7134_V_PHASE_OFFSET0(task), y_odd);
+		saa_writeb(SAA7134_V_PHASE_OFFSET1(task), y_even);
+		saa_writeb(SAA7134_V_PHASE_OFFSET2(task), y_odd);
+		saa_writeb(SAA7134_V_PHASE_OFFSET3(task), y_even);
+	} else {
+		y_odd  = dev->ctl_y_odd;
+		y_even = dev->ctl_y_even + yscale / 64;
+		saa_writeb(SAA7134_V_PHASE_OFFSET0(task), y_odd);
+		saa_writeb(SAA7134_V_PHASE_OFFSET1(task), y_even);
+		saa_writeb(SAA7134_V_PHASE_OFFSET2(task), y_odd);
+		saa_writeb(SAA7134_V_PHASE_OFFSET3(task), y_even);
+	}
+}
+
+/* ------------------------------------------------------------------ */
+
+struct cliplist {
+	__u16 position;
+	__u8  enable;
+	__u8  disable;
+};
+
+static void sort_cliplist(struct cliplist *cl, int entries)
+{
+	struct cliplist swap;
+	int i,j,n;
+	
+	for (i = entries-2; i >= 0; i--) {
+		for (n = 0, j = 0; j <= i; j++) {
+			if (cl[j].position > cl[j+1].position) {
+				swap = cl[j];
+				cl[j] = cl[j+1];
+				cl[j+1] = swap;
+				n++;
+			}
+		}
+		if (0 == n)
+			break;
+	}
+}
+
+static void set_cliplist(struct saa7134_dev *dev, int reg,
+			struct cliplist *cl, int entries, char *name)
+{
+	__u8 winbits = 0;
+	int i;
+
+	for (i = 0; i < entries; i++) {
+		winbits |= cl[i].enable;
+		winbits &= ~cl[i].disable;
+		if (i < 15 && cl[i].position == cl[i+1].position)
+			continue;
+		saa_writeb(reg + 0, winbits);
+		saa_writeb(reg + 2, cl[i].position & 0xff);
+		saa_writeb(reg + 3, cl[i].position >> 8);
+		dprintk("clip: %s winbits=%02x pos=%d\n",
+			name,winbits,cl[i].position);
+		reg += 8;
+	}
+	for (; reg < 0x400; reg += 8) {
+		saa_writeb(reg+ 0, 0);
+		saa_writeb(reg + 1, 0);
+		saa_writeb(reg + 2, 0);
+		saa_writeb(reg + 3, 0);
+	}
+}
+
+static int clip_range(int val)
+{
+	if (val < 0)
+		val = 0;
+	return val;
+}
+
+static int setup_clipping(struct saa7134_dev *dev, struct v4l2_clip *clips,
+			  int nclips, int interlace)
+{
+	struct cliplist col[16], row[16];
+	int cols, rows, i;
+	int div = interlace ? 2 : 1;
+
+	memset(col,0,sizeof(col)); cols = 0;
+	memset(row,0,sizeof(row)); rows = 0;
+	for (i = 0; i < nclips && i < 8; i++) {
+		col[cols].position = clip_range(clips[i].c.left);
+		col[cols].enable   = (1 << i);
+		cols++;
+		col[cols].position = clip_range(clips[i].c.left+clips[i].c.width);
+		col[cols].disable  = (1 << i);
+		cols++;
+		row[rows].position = clip_range(clips[i].c.top / div);
+		row[rows].enable   = (1 << i);
+		rows++;
+		row[rows].position = clip_range((clips[i].c.top + clips[i].c.height)
+						/ div);
+		row[rows].disable  = (1 << i);
+		rows++;
+	}
+	sort_cliplist(col,cols);
+	sort_cliplist(row,rows);
+	set_cliplist(dev,0x380,col,cols,"cols");
+	set_cliplist(dev,0x384,row,rows,"rows");
+	return 0;
+}
+
+static int verify_preview(struct saa7134_dev *dev, struct v4l2_window *win)
+{
+	enum v4l2_field field;
+	int maxw, maxh;
+
+	if (NULL == dev->ovbuf.base)
+		return -EINVAL;
+	if (NULL == dev->ovfmt)
+		return -EINVAL;
+	if (win->w.width < 48 || win->w.height <  32)
+		return -EINVAL;
+	if (win->clipcount > 2048)
+		return -EINVAL;
+
+	field = win->field;
+	maxw  = dev->tvnorm->width;
+	maxh  = dev->tvnorm->height;
+
+	if (V4L2_FIELD_ANY == field) {
+                field = (win->w.height > maxh/2)
+                        ? V4L2_FIELD_INTERLACED
+                        : V4L2_FIELD_TOP;
+        }
+        switch (field) {
+        case V4L2_FIELD_TOP:
+        case V4L2_FIELD_BOTTOM:
+                maxh = maxh / 2;
+                break;
+        case V4L2_FIELD_INTERLACED:
+                break;
+        default:
+                return -EINVAL;
+        }
+
+	win->field = field;
+	if (win->w.width > maxw)
+		win->w.width = maxw;
+	if (win->w.height > maxh)
+		win->w.height = maxh;
+	return 0;
+}
+
+static int start_preview(struct saa7134_dev *dev, struct saa7134_fh *fh)
+{
+	unsigned long base,control,bpl;
+	int err;
+
+	err = verify_preview(dev,&fh->win);
+	if (0 != err)
+		return err;
+	
+	dprintk("start_preview %dx%d+%d+%d %s field=%s\n",
+		fh->win.w.width,fh->win.w.height,
+		fh->win.w.left,fh->win.w.top,
+		dev->ovfmt->name,v4l2_field_names[dev->ovfield]);
+
+	/* setup window + clipping */
+	set_size(dev,TASK_B,fh->win.w.width,fh->win.w.height,
+		 V4L2_FIELD_HAS_BOTH(dev->ovfield));
+	setup_clipping(dev,fh->clips,fh->nclips,
+		       V4L2_FIELD_HAS_BOTH(dev->ovfield));
+	if (dev->ovfmt->yuv)
+		saa_andorb(SAA7134_DATA_PATH(TASK_B), 0x3f, 0x03);
+	else
+		saa_andorb(SAA7134_DATA_PATH(TASK_B), 0x3f, 0x01);
+	saa_writeb(SAA7134_OFMT_VIDEO_B, dev->ovfmt->pm | 0x20);
+
+	/* dma: setup channel 1 (= Video Task B) */
+	base  = (unsigned long)dev->ovbuf.base;
+	base += dev->ovbuf.fmt.bytesperline * fh->win.w.top;
+	base += dev->ovfmt->depth/8         * fh->win.w.left;
+	bpl   = dev->ovbuf.fmt.bytesperline;
+	control = SAA7134_RS_CONTROL_BURST_16;
+	if (dev->ovfmt->bswap)
+		control |= SAA7134_RS_CONTROL_BSWAP;
+	if (dev->ovfmt->wswap)
+		control |= SAA7134_RS_CONTROL_WSWAP;
+	if (V4L2_FIELD_HAS_BOTH(dev->ovfield)) {
+		saa_writel(SAA7134_RS_BA1(1),base);
+		saa_writel(SAA7134_RS_BA2(1),base+bpl);
+		saa_writel(SAA7134_RS_PITCH(1),bpl*2);
+		saa_writel(SAA7134_RS_CONTROL(1),control);
+	} else {
+		saa_writel(SAA7134_RS_BA1(1),base);
+		saa_writel(SAA7134_RS_BA2(1),base);
+		saa_writel(SAA7134_RS_PITCH(1),bpl);
+		saa_writel(SAA7134_RS_CONTROL(1),control);
+	}
+
+	/* start dma */
+	dev->ovenable = 1;
+	saa7134_set_dmabits(dev);
+
+	return 0;
+}
+
+static int stop_preview(struct saa7134_dev *dev, struct saa7134_fh *fh)
+{
+	dev->ovenable = 0;
+	saa7134_set_dmabits(dev);
+	return 0;
+}
+
+/* ------------------------------------------------------------------ */
+
+static int buffer_activate(struct saa7134_dev *dev,
+			   struct saa7134_buf *buf,
+			   struct saa7134_buf *next)
+{
+	unsigned long base,control,bpl;
+	unsigned long bpl_uv,lines_uv,base2,base3; /* planar */
+
+	dprintk("buffer_activate buf=%p\n",buf);
+	buf->vb.state = STATE_ACTIVE;
+	
+	set_size(dev,TASK_A,buf->vb.width,buf->vb.height,
+		 V4L2_FIELD_HAS_BOTH(buf->vb.field));
+	if (buf->fmt->yuv)
+		saa_andorb(SAA7134_DATA_PATH(TASK_A), 0x3f, 0x03);
+	else
+		saa_andorb(SAA7134_DATA_PATH(TASK_A), 0x3f, 0x01);
+	saa_writeb(SAA7134_OFMT_VIDEO_A, buf->fmt->pm);
+
+	/* DMA: setup channel 0 (= Video Task A0) */
+	base  = saa7134_buffer_base(buf);
+	if (buf->fmt->planar)
+		bpl = buf->vb.width;
+	else
+		bpl = (buf->vb.width * buf->fmt->depth) / 8;
+	control = SAA7134_RS_CONTROL_BURST_16 |
+		SAA7134_RS_CONTROL_ME |
+		(buf->pt->dma >> 12);
+	if (buf->fmt->bswap)
+		control |= SAA7134_RS_CONTROL_BSWAP;
+	if (buf->fmt->wswap)
+		control |= SAA7134_RS_CONTROL_WSWAP;
+	if (V4L2_FIELD_HAS_BOTH(buf->vb.field)) {
+		/* interlaced */
+		saa_writel(SAA7134_RS_BA1(0),base);
+		saa_writel(SAA7134_RS_BA2(0),base+bpl);
+		saa_writel(SAA7134_RS_PITCH(0),bpl*2);
+	} else {
+		/* non-interlaced */
+		saa_writel(SAA7134_RS_BA1(0),base);
+		saa_writel(SAA7134_RS_BA2(0),base);
+		saa_writel(SAA7134_RS_PITCH(0),bpl);
+	}
+	saa_writel(SAA7134_RS_CONTROL(0),control);
+
+	if (buf->fmt->planar) {
+		/* DMA: setup channel 4+5 (= planar task A) */
+		bpl_uv   = bpl >> buf->fmt->hshift;
+		lines_uv = buf->vb.height >> buf->fmt->vshift;
+		base2    = base + bpl * buf->vb.height;
+		base3    = base2 + bpl_uv * lines_uv;
+		dprintk("uv: bpl=%ld lines=%ld base2/3=%ld/%ld\n",
+			bpl_uv,lines_uv,base2,base3);
+		if (V4L2_FIELD_HAS_BOTH(buf->vb.field)) {
+			/* interlaced */
+			saa_writel(SAA7134_RS_BA1(4),base2);
+			saa_writel(SAA7134_RS_BA2(4),base2+bpl_uv);
+			saa_writel(SAA7134_RS_PITCH(4),bpl_uv*2);
+			saa_writel(SAA7134_RS_BA1(5),base3);
+			saa_writel(SAA7134_RS_BA2(5),base3+bpl_uv);
+			saa_writel(SAA7134_RS_PITCH(5),bpl_uv*2);
+		} else {
+			/* non-interlaced */
+			saa_writel(SAA7134_RS_BA1(4),base2);
+			saa_writel(SAA7134_RS_BA2(4),base2);
+			saa_writel(SAA7134_RS_PITCH(4),bpl_uv);
+			saa_writel(SAA7134_RS_BA1(5),base3);
+			saa_writel(SAA7134_RS_BA2(5),base3);
+			saa_writel(SAA7134_RS_PITCH(5),bpl_uv);
+		}
+		saa_writel(SAA7134_RS_CONTROL(4),control);
+		saa_writel(SAA7134_RS_CONTROL(5),control);
+	}
+
+	/* start DMA */
+	saa7134_set_dmabits(dev);
+	mod_timer(&dev->video_q.timeout, jiffies+BUFFER_TIMEOUT);
+	return 0;
+}
+
+static int buffer_prepare(struct file *file, struct videobuf_buffer *vb)
+{
+	struct saa7134_fh *fh = file->private_data;
+	struct saa7134_dev *dev = fh->dev;
+	struct saa7134_buf *buf = (struct saa7134_buf *)vb;
+	int size,err;
+	
+	/* sanity checks */
+	if (NULL == fh->fmt)
+		return -EINVAL;
+	if (fh->width  < 48 ||
+	    fh->height < 32 ||
+	    fh->width  > dev->tvnorm->width ||
+	    fh->height > dev->tvnorm->height)
+		return -EINVAL;
+	size = (fh->width * fh->height * fh->fmt->depth) >> 3;
+	if (0 != buf->vb.baddr  &&  buf->vb.bsize < size)
+		return -EINVAL;
+
+	dprintk("buffer_prepare [size=%dx%d,bytes=%d,fields=%s,%s]\n",
+		fh->width,fh->height,size,v4l2_field_names[fh->field],
+		fh->fmt->name);
+	if (buf->vb.width  != fh->width  ||
+	    buf->vb.height != fh->height ||
+	    buf->vb.size   != size       ||
+	    buf->vb.field  != fh->field  ||
+	    buf->fmt       != fh->fmt) {
+		saa7134_dma_free(dev,buf);
+	}
+
+	if (STATE_NEEDS_INIT == buf->vb.state) {
+		buf->vb.width  = fh->width;
+		buf->vb.height = fh->height;
+		buf->vb.size   = size;
+		buf->fmt       = fh->fmt;
+		buf->vb.field  = fh->field;
+		buf->pt        = &fh->pt_cap;
+
+		err = videobuf_iolock(dev->pci,&buf->vb);
+		if (err)
+			goto oops;
+		err = saa7134_pgtable_build(dev->pci,buf->pt,
+					    buf->vb.dma.sglist,
+					    buf->vb.dma.sglen,
+					    saa7134_buffer_startpage(buf));
+		if (err)
+			goto oops;
+	}
+	buf->vb.state = STATE_PREPARED;
+	buf->top_seen = 0;
+	buf->activate = buffer_activate;
+	return 0;
+
+ oops:
+	saa7134_dma_free(dev,buf);
+	return err;
+}
+
+static int
+buffer_setup(struct file *file, int *count, int *size)
+{
+	struct saa7134_fh *fh = file->private_data;
+
+	*size = fh->fmt->depth * fh->width * fh->height >> 3;
+	if (0 == *count)
+		*count = gbuffers;
+	*count = saa7134_buffer_count(*size,*count);
+	return 0;
+}
+
+static void buffer_queue(struct file *file, struct videobuf_buffer *vb)
+{
+	struct saa7134_fh *fh = file->private_data;
+	struct saa7134_buf *buf = (struct saa7134_buf *)vb;
+	
+	saa7134_buffer_queue(fh->dev,&fh->dev->video_q,buf);
+}
+
+static void buffer_release(struct file *file, struct videobuf_buffer *vb)
+{
+	struct saa7134_fh *fh = file->private_data;
+	struct saa7134_buf *buf = (struct saa7134_buf *)vb;
+	
+	saa7134_dma_free(fh->dev,buf);
+}
+
+static struct videobuf_queue_ops video_qops = {
+	buf_setup:    buffer_setup,
+	buf_prepare:  buffer_prepare,
+	buf_queue:    buffer_queue,
+	buf_release:  buffer_release,
+};
+
+/* ------------------------------------------------------------------ */
+
+static int get_control(struct saa7134_dev *dev, struct v4l2_control *c)
+{
+	const struct v4l2_queryctrl* ctrl;
+
+	ctrl = ctrl_by_id(c->id);
+	if (NULL == ctrl)
+		return -EINVAL;
+	switch (c->id) {
+	case V4L2_CID_BRIGHTNESS:
+		c->value = dev->ctl_bright;
+		break;
+	case V4L2_CID_HUE:
+		c->value = dev->ctl_hue;
+		break;
+	case V4L2_CID_CONTRAST:
+		c->value = dev->ctl_contrast;
+		break;
+	case V4L2_CID_SATURATION:
+		c->value = dev->ctl_saturation;
+		break;
+	case V4L2_CID_AUDIO_MUTE:
+		c->value = dev->ctl_mute;
+		break;
+	case V4L2_CID_AUDIO_VOLUME:
+		c->value = dev->ctl_volume;
+		break;
+	case V4L2_CID_PRIVATE_INVERT:
+		c->value = dev->ctl_invert;
+		break;
+	case V4L2_CID_VFLIP:
+		c->value = dev->ctl_mirror;
+		break;
+	case V4L2_CID_PRIVATE_Y_EVEN:
+		c->value = dev->ctl_y_even;
+		break;
+	case V4L2_CID_PRIVATE_Y_ODD:
+		c->value = dev->ctl_y_odd;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int set_control(struct saa7134_dev *dev, struct saa7134_fh *fh,
+		       struct v4l2_control *c)
+{
+	const struct v4l2_queryctrl* ctrl;
+	unsigned long flags;
+	int restart_overlay = 0;
+
+	ctrl = ctrl_by_id(c->id);
+	if (NULL == ctrl)
+		return -EINVAL;
+	dprintk("set_control name=%s val=%d\n",ctrl->name,c->value);
+	switch (ctrl->type) {
+	case V4L2_CTRL_TYPE_BOOLEAN:
+	case V4L2_CTRL_TYPE_MENU:
+	case V4L2_CTRL_TYPE_INTEGER:
+		if (c->value < ctrl->minimum)
+			c->value = ctrl->minimum;
+		if (c->value > ctrl->maximum)
+			c->value = ctrl->maximum;
+		break;
+	default:
+		/* nothing */;
+	};
+	switch (c->id) {
+	case V4L2_CID_BRIGHTNESS:
+		dev->ctl_bright = c->value;
+		saa_writeb(SAA7134_DEC_LUMA_BRIGHT, dev->ctl_bright);
+		break;
+	case V4L2_CID_HUE:
+		dev->ctl_hue = c->value;
+		saa_writeb(SAA7134_DEC_CHROMA_HUE, dev->ctl_hue);
+		break;
+	case V4L2_CID_CONTRAST:
+		dev->ctl_contrast = c->value;
+		saa_writeb(SAA7134_DEC_LUMA_CONTRAST,
+			   dev->ctl_invert ? -dev->ctl_contrast : dev->ctl_contrast);
+		break;
+	case V4L2_CID_SATURATION:
+		dev->ctl_saturation = c->value;
+		saa_writeb(SAA7134_DEC_CHROMA_SATURATION,
+			   dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);
+		break;
+	case V4L2_CID_AUDIO_MUTE:
+		dev->ctl_mute = c->value;
+		saa7134_tvaudio_setmute(dev);
+		break;
+	case V4L2_CID_AUDIO_VOLUME:
+		dev->ctl_volume = c->value;
+		saa7134_tvaudio_setvolume(dev,dev->ctl_volume);
+		break;
+	case V4L2_CID_PRIVATE_INVERT:
+		dev->ctl_invert = c->value;
+		saa_writeb(SAA7134_DEC_LUMA_CONTRAST,
+			   dev->ctl_invert ? -dev->ctl_contrast : dev->ctl_contrast);
+		saa_writeb(SAA7134_DEC_CHROMA_SATURATION,
+			   dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);
+		break;
+	case V4L2_CID_VFLIP:
+		dev->ctl_mirror = c->value;
+		restart_overlay = 1;
+		break;
+	case V4L2_CID_PRIVATE_Y_EVEN:
+		dev->ctl_y_even = c->value;
+		restart_overlay = 1;
+		break;
+	case V4L2_CID_PRIVATE_Y_ODD:
+		dev->ctl_y_odd = c->value;
+		restart_overlay = 1;
+		break;
+	default:
+		return -EINVAL;
+	}
+	if (restart_overlay && res_check(fh, RESOURCE_OVERLAY)) {
+		spin_lock_irqsave(&dev->slock,flags);
+		stop_preview(dev,fh);
+		start_preview(dev,fh);
+		spin_unlock_irqrestore(&dev->slock,flags);
+	}
+	return 0;
+}
+
+/* ------------------------------------------------------------------ */
+
+static struct videobuf_queue* saa7134_queue(struct saa7134_fh *fh)
+{
+	struct videobuf_queue* q = NULL;
+	
+	switch (fh->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		q = &fh->cap;
+		break;
+	case V4L2_BUF_TYPE_VBI_CAPTURE:
+		q = &fh->vbi;
+		break;
+	default:
+		BUG();
+	}
+	return q;
+}
+
+static int saa7134_resource(struct saa7134_fh *fh)
+{
+	int res = 0;
+	
+	switch (fh->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		res = RESOURCE_VIDEO;
+		break;
+	case V4L2_BUF_TYPE_VBI_CAPTURE:
+		res = RESOURCE_VBI;
+		break;
+	default:
+		BUG();
+	}
+	return res;
+}
+
+static int video_open(struct inode *inode, struct file *file)
+{
+	unsigned int minor = minor(inode->i_rdev);
+	struct saa7134_dev *h,*dev = NULL;
+	struct saa7134_fh *fh;
+	struct list_head *list;
+	enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	int radio = 0;
+	
+	list_for_each(list,&saa7134_devlist) {
+		h = list_entry(list, struct saa7134_dev, devlist);
+		if (h->video_dev.minor == minor)
+			dev = h;
+		if (h->radio_dev.minor == minor) {
+			radio = 1;
+			dev = h;
+		}
+		if (h->vbi_dev.minor == minor) {
+			type = V4L2_BUF_TYPE_VBI_CAPTURE;
+			dev = h;
+		}
+	}
+	if (NULL == dev)
+		return -ENODEV;
+
+	dprintk("open minor=%d radio=%d type=%s\n",minor,radio,
+		v4l2_type_names[type]);
+
+	/* allocate + initialize per filehandle data */
+	fh = kmalloc(sizeof(*fh),GFP_KERNEL);
+	if (NULL == fh)
+		return -ENOMEM;
+	memset(fh,0,sizeof(*fh));
+	file->private_data = fh;
+	fh->dev      = dev;
+	fh->radio    = radio;
+	fh->type     = type;
+	fh->fmt      = format_by_fourcc(V4L2_PIX_FMT_BGR24);
+	fh->width    = 320;
+	fh->height   = 240;
+
+	videobuf_queue_init(&fh->cap, &video_qops,
+			    dev->pci, &dev->slock,
+			    V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			    sizeof(struct saa7134_buf));
+	init_MUTEX(&fh->cap.lock);
+	saa7134_pgtable_alloc(dev->pci,&fh->pt_cap);
+
+	videobuf_queue_init(&fh->vbi, &saa7134_vbi_qops,
+			    dev->pci, &dev->slock,
+			    V4L2_BUF_TYPE_VBI_CAPTURE,
+			    sizeof(struct saa7134_buf));
+        init_MUTEX(&fh->vbi.lock);
+	saa7134_pgtable_alloc(dev->pci,&fh->pt_vbi);
+
+	if (fh->radio) {
+		/* switch to radio mode */
+		saa7134_tvaudio_setinput(dev,&card(dev).radio);
+		saa7134_i2c_call_clients(dev,AUDC_SET_RADIO,NULL);
+	} else {
+		/* switch to video/vbi mode */
+		set_tvnorm(dev,dev->tvnorm);
+		video_mux(dev,dev->ctl_input);
+	}
+        return 0;
+}
+
+static ssize_t
+video_read(struct file *file, char *data, size_t count, loff_t *ppos)
+{
+	struct saa7134_fh *fh = file->private_data;
+
+	switch (fh->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		return videobuf_read_one(file, saa7134_queue(fh),
+					 data, count, ppos);
+	case V4L2_BUF_TYPE_VBI_CAPTURE:
+		return videobuf_read_stream(file, saa7134_queue(fh),
+					    data, count, ppos, 1);
+		break;
+	default:
+		BUG();
+		return 0;
+	}
+}
+
+static unsigned int
+video_poll(struct file *file, struct poll_table_struct *wait)
+{
+	struct saa7134_fh *fh = file->private_data;
+	struct videobuf_buffer *buf = NULL;
+
+	if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)
+		return videobuf_poll_stream(file, &fh->vbi, wait);
+
+	if (res_check(fh,RESOURCE_VIDEO)) {
+		if (!list_empty(&fh->cap.stream))
+			buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream);
+	} else {
+		down(&fh->cap.lock);
+		if (-1 == fh->cap.read_off) {
+                        /* need to capture a new frame */
+			if (res_locked(fh->dev,RESOURCE_VIDEO)) {
+                                up(&fh->cap.lock);
+                                return POLLERR;
+                        }
+                        if (0 != fh->cap.ops->buf_prepare(file,fh->cap.read_buf)) {
+                                up(&fh->cap.lock);
+                                return POLLERR;
+                        }
+                        fh->cap.ops->buf_queue(file,fh->cap.read_buf);
+                        fh->cap.read_off = 0;
+		}
+		up(&fh->cap.lock);
+		buf = fh->cap.read_buf;
+	}
+
+	if (!buf)
+		return POLLERR;
+
+	poll_wait(file, &buf->done, wait);
+	if (buf->state == STATE_DONE ||
+	    buf->state == STATE_ERROR)
+		return POLLIN|POLLRDNORM;
+	return 0;
+}
+
+static int video_release(struct inode *inode, struct file *file)
+{
+	struct saa7134_fh  *fh  = file->private_data;
+	struct saa7134_dev *dev = fh->dev;
+	unsigned long flags;
+
+	if (res_check(fh, RESOURCE_OVERLAY)) {
+		spin_lock_irqsave(&dev->slock,flags);
+		stop_preview(dev,fh);
+		spin_unlock_irqrestore(&dev->slock,flags);
+		res_free(dev,fh,RESOURCE_OVERLAY);
+	}
+	if (res_check(fh, RESOURCE_VIDEO)) {
+		videobuf_queue_cancel(file,&fh->cap);
+		res_free(dev,fh,RESOURCE_VIDEO);
+	}
+	if (fh->cap.read_buf) {
+		buffer_release(file,fh->cap.read_buf);
+		kfree(fh->cap.read_buf);
+	}
+	if (fh->vbi.streaming)
+		videobuf_streamoff(file,&fh->vbi);
+	if (fh->vbi.reading)
+		videobuf_read_stop(file,&fh->vbi);
+
+	saa7134_pgtable_free(dev->pci,&fh->pt_cap);
+	saa7134_pgtable_free(dev->pci,&fh->pt_vbi);
+	
+	file->private_data = NULL;
+	kfree(fh);
+	return 0;
+}
+
+static int
+video_mmap(struct file *file, struct vm_area_struct * vma)
+{
+	struct saa7134_fh *fh = file->private_data;
+	
+	return videobuf_mmap_mapper(vma,saa7134_queue(fh));
+}
+
+/* ------------------------------------------------------------------ */
+
+int saa7134_g_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
+		  struct v4l2_format *f)
+{
+	switch (f->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
+		f->fmt.pix.width        = fh->width;
+		f->fmt.pix.height       = fh->height;
+		f->fmt.pix.pixelformat  = fh->fmt->fourcc;
+		f->fmt.pix.sizeimage    =
+			(fh->width*fh->height*fh->fmt->depth)/8;
+		return 0;
+	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+		f->fmt.win = fh->win;
+		return 0;
+	case V4L2_BUF_TYPE_VBI_CAPTURE:
+	{
+		struct saa7134_tvnorm *norm = fh->dev->tvnorm;
+			
+		f->fmt.vbi.sampling_rate = 6750000 * 4;
+		f->fmt.vbi.samples_per_line = 2048 /* VBI_LINE_LENGTH */;
+		f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
+		f->fmt.vbi.offset = 64 * 4;
+		f->fmt.vbi.start[0] = norm->vbi_v_start;
+		f->fmt.vbi.count[0] = norm->vbi_v_stop - norm->vbi_v_start +1;
+		f->fmt.vbi.start[1] = norm->video_v_stop + norm->vbi_v_start + 1;
+		f->fmt.vbi.count[1] = f->fmt.vbi.count[0];
+		f->fmt.vbi.flags = 0; /* VBI_UNSYNC VBI_INTERLACED */;
+		return 0;
+	}
+	default:
+		return -EINVAL;
+	}
+}
+
+int saa7134_try_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
+		    struct v4l2_format *f)
+{
+	int err;
+	
+	switch (f->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+	{
+		struct saa7134_format *fmt;
+		enum v4l2_field field;
+		int maxw, maxh;
+
+		fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+		if (NULL == fmt)
+			return -EINVAL;
+
+		field = f->fmt.pix.field;
+		maxw  = dev->tvnorm->width;
+		maxh  = dev->tvnorm->height;
+		
+		if (V4L2_FIELD_ANY == field) {
+			field = (f->fmt.pix.height > maxh/2)
+				? V4L2_FIELD_INTERLACED
+				: V4L2_FIELD_BOTTOM;
+		}
+		switch (field) {
+		case V4L2_FIELD_TOP:
+		case V4L2_FIELD_BOTTOM:
+			maxh = maxh / 2;
+			break;
+		case V4L2_FIELD_INTERLACED:
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		f->fmt.pix.field = field;
+		if (f->fmt.pix.width > maxw)
+			f->fmt.pix.width = maxw;
+		if (f->fmt.pix.height > maxh)
+			f->fmt.pix.height = maxh;
+		f->fmt.pix.sizeimage =
+			(fh->width * fh->height * fmt->depth)/8;
+		
+		return 0;
+	}
+	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+		err = verify_preview(dev,&f->fmt.win);
+		if (0 != err)
+			return err;
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
+		  struct v4l2_format *f)
+{
+	unsigned long flags;
+	int err;
+	
+	switch (f->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		err = saa7134_try_fmt(dev,fh,f);
+		if (0 != err)
+			return err;
+			
+		fh->fmt    = format_by_fourcc(f->fmt.pix.pixelformat);
+		fh->width  = f->fmt.pix.width;
+		fh->height = f->fmt.pix.height;
+		fh->field  = f->fmt.pix.field;
+		return 0;
+	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+		err = verify_preview(dev,&f->fmt.win);
+		if (0 != err)
+			return err;
+
+		down(&dev->lock);
+		fh->win    = f->fmt.win;
+		fh->nclips = f->fmt.win.clipcount;
+		if (fh->nclips > 8)
+			fh->nclips = 8;
+		if (copy_from_user(fh->clips,f->fmt.win.clips,
+				   sizeof(struct v4l2_clip)*fh->nclips)) {
+			up(&dev->lock);
+			return -EFAULT;
+		}
+
+		if (res_check(fh, RESOURCE_OVERLAY)) {
+			spin_lock_irqsave(&dev->slock,flags);
+			stop_preview(dev,fh);
+			start_preview(dev,fh);
+			spin_unlock_irqrestore(&dev->slock,flags);
+		}
+		up(&dev->lock);
+		return 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+}
+
+/*
+ * This function is _not_ called directly, but from
+ * video_generic_ioctl (and maybe others).  userspace
+ * copying is done already, arg is a kernel pointer.
+ */
+static int video_do_ioctl(struct inode *inode, struct file *file,
+			  unsigned int cmd, void *arg)
+{
+	struct saa7134_fh *fh = file->private_data;
+	struct saa7134_dev *dev = fh->dev;
+	unsigned long flags;
+	int err;
+
+	if (video_debug > 1)
+		saa7134_print_ioctl(dev->name,cmd);
+	switch (cmd) {
+	case VIDIOC_QUERYCAP:
+	{
+		struct v4l2_capability *cap = arg;
+		
+		memset(cap,0,sizeof(*cap));
+                strcpy(cap->driver, "saa7134");
+		strncpy(cap->card, saa7134_boards[dev->board].name,
+			sizeof(cap->card));
+		sprintf(cap->bus_info,"PCI:%s",dev->pci->slot_name);
+		cap->version = SAA7134_VERSION_CODE;
+		cap->capabilities =
+			V4L2_CAP_VIDEO_CAPTURE |
+			V4L2_CAP_VIDEO_OVERLAY |
+			V4L2_CAP_VBI_CAPTURE |
+			V4L2_CAP_TUNER |
+			V4L2_CAP_READWRITE | 
+			V4L2_CAP_STREAMING;
+		return 0;
+	}
+
+	/* --- tv standards ------------------------------------------ */
+	case VIDIOC_ENUMSTD:
+	{
+		struct v4l2_standard *e = arg;
+
+		if (e->index < 0 || e->index >= TVNORMS)
+			return -EINVAL;
+		err = v4l2_video_std_construct(e, tvnorms[e->index].id,
+					       tvnorms[e->index].name);
+		if (err < 0)
+			return err;
+		return 0;
+	}
+	case VIDIOC_G_STD:
+	{
+		v4l2_std_id *id = arg;
+
+		*id = dev->tvnorm->id;
+		return 0;
+	}
+	case VIDIOC_S_STD:
+	{
+		v4l2_std_id *id = arg;
+		int i;
+
+		for(i = 0; i < TVNORMS; i++)
+			if (*id & tvnorms[i].id)
+				break;
+		if (i == TVNORMS)
+			return -EINVAL;
+
+		down(&dev->lock);
+		if (res_check(fh, RESOURCE_OVERLAY)) {
+			spin_lock_irqsave(&dev->slock,flags);
+			stop_preview(dev,fh);
+			set_tvnorm(dev,&tvnorms[i]);
+			start_preview(dev,fh);
+			spin_unlock_irqrestore(&dev->slock,flags);
+		} else 
+			set_tvnorm(dev,&tvnorms[i]);
+		up(&dev->lock);
+		return 0;
+	}
+
+	/* --- input switching --------------------------------------- */
+	case VIDIOC_ENUMINPUT:
+	{
+		struct v4l2_input *i = arg;
+		
+		if (i->index >= SAA7134_INPUT_MAX)
+			return -EINVAL;
+		if (NULL == card_in(dev,i->index).name)
+			return -EINVAL;
+		i->type = V4L2_INPUT_TYPE_CAMERA;
+		strcpy(i->name,card_in(dev,i->index).name);
+		if (card_in(dev,i->index).tv)
+			i->type = V4L2_INPUT_TYPE_TUNER;
+		return 0;
+	}
+	case VIDIOC_G_INPUT:
+	{
+		int *i = arg;
+		*i = dev->ctl_input;
+		return 0;
+	}
+	case VIDIOC_S_INPUT:
+	{
+		int *i = arg;
+		
+		if (*i < 0  ||  *i >= SAA7134_INPUT_MAX)
+			return -EINVAL;
+		if (NULL == card_in(dev,*i).name)
+			return -EINVAL;
+		down(&dev->lock);
+		video_mux(dev,*i);
+		up(&dev->lock);
+		return 0;
+	}
+
+	/* --- tuner ioctls ------------------------------------------ */
+	case VIDIOC_G_TUNER:
+	{
+		struct v4l2_tuner *t = arg;
+		int n;
+
+		memset(t,0,sizeof(*t));
+		for (n = 0; n < SAA7134_INPUT_MAX; n++)
+			if (card_in(dev,n).tv)
+				break;
+		if (NULL != card_in(dev,n).name) {
+			strcpy(t->name, "Television");
+			t->capability = V4L2_TUNER_CAP_NORM |
+				V4L2_TUNER_CAP_STEREO |
+				V4L2_TUNER_CAP_LANG1 |
+				V4L2_TUNER_CAP_LANG2;
+			t->rangehigh = 0xffffffffUL;
+			if (dev->tvaudio) {
+				t->rxsubchans = saa7134_tvaudio_getstereo
+					(dev,dev->tvaudio);
+			} else {
+				t->rxsubchans = V4L2_TUNER_SUB_MONO;
+			}
+#if 1
+			/* fill audmode -- FIXME: allow manual switching */
+			t->audmode = V4L2_TUNER_MODE_MONO;
+			if (t->rxsubchans & V4L2_TUNER_SUB_STEREO)
+				t->audmode = V4L2_TUNER_MODE_STEREO;
+			else if (t->rxsubchans & V4L2_TUNER_SUB_LANG1)
+				t->audmode = V4L2_TUNER_MODE_LANG1;
+			else if (t->rxsubchans & V4L2_TUNER_SUB_LANG2)
+				t->audmode = V4L2_TUNER_MODE_LANG2;
+#endif
+		}
+		if (0 != (saa_readb(SAA7134_STATUS_VIDEO1) & 0x03))
+			t->signal = 0xffff;
+		return 0;
+	}
+	case VIDIOC_S_TUNER:
+	{
+#if 0
+		struct v4l2_tuner *t = arg;
+#endif
+		return 0;
+	}
+	case VIDIOC_G_FREQUENCY:
+	{
+		struct v4l2_frequency *f = arg;
+
+		memset(f,0,sizeof(*f));
+		f->type = V4L2_TUNER_ANALOG_TV;
+		f->frequency = dev->ctl_freq;
+		return 0;
+	}
+	case VIDIOC_S_FREQUENCY:
+	{
+		struct v4l2_frequency *f = arg;
+
+		if (0 != f->tuner)
+			return -EINVAL;
+		if (V4L2_TUNER_ANALOG_TV != f->type)
+			return -EINVAL;
+		down(&dev->lock);
+		dev->ctl_freq = f->frequency;
+		saa7134_i2c_call_clients(dev,VIDIOCSFREQ,&dev->ctl_freq);
+		up(&dev->lock);
+		return 0;
+	}
+		
+	/* --- control ioctls ---------------------------------------- */
+	case VIDIOC_QUERYCTRL:
+	{
+		const struct v4l2_queryctrl *ctrl;
+		struct v4l2_queryctrl *c = arg;
+
+		if ((c->id <  V4L2_CID_BASE ||
+		     c->id >= V4L2_CID_LASTP1) &&
+		    (c->id <  V4L2_CID_PRIVATE_BASE ||
+		     c->id >= V4L2_CID_PRIVATE_LASTP1))
+			return -EINVAL;
+		ctrl = ctrl_by_id(c->id);
+		*c = (NULL != ctrl) ? *ctrl : no_ctrl;
+		return 0;
+	}
+	case VIDIOC_G_CTRL:
+		return get_control(dev,arg);
+	case VIDIOC_S_CTRL:
+	{
+		down(&dev->lock);
+		err = set_control(dev,fh,arg);
+		up(&dev->lock);
+		return err;
+	}
+	case VIDIOC_G_AUDIO:
+	{
+		struct v4l2_audio *a = arg;
+
+		memset(a,0,sizeof(*a));
+		strcpy(a->name,"audio");
+		return 0;
+	}
+	case VIDIOC_S_AUDIO:
+		return 0;
+        case VIDIOC_G_PARM:
+        {
+                struct v4l2_captureparm *parm = arg;
+                memset(parm,0,sizeof(*parm));
+                return 0;
+        }
+
+	/* --- preview ioctls ---------------------------------------- */
+	case VIDIOC_ENUM_FMT:
+	{
+		struct v4l2_fmtdesc *f = arg;
+		int index;
+
+		switch (f->type) {
+		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+			index = f->index;
+			if (index < 0 || index >= FORMATS)
+				return -EINVAL;
+			if (f->type == V4L2_BUF_TYPE_VIDEO_OVERLAY &&
+			    formats[index].planar)
+				return -EINVAL;
+			memset(f,0,sizeof(*f));
+			f->index = index;
+			strncpy(f->description,formats[index].name,31);
+			f->pixelformat = formats[index].fourcc;
+			break;
+		default:
+			return -EINVAL;	
+		}
+		return 0;
+	}
+	case VIDIOC_G_FBUF:
+	{
+		struct v4l2_framebuffer *fb = arg;
+
+		*fb = dev->ovbuf;
+		fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
+		return 0;
+	}
+	case VIDIOC_S_FBUF:
+	{
+		struct v4l2_framebuffer *fb = arg;
+		struct saa7134_format *fmt;
+		
+		if(!capable(CAP_SYS_ADMIN) &&
+		   !capable(CAP_SYS_RAWIO))
+			return -EPERM;
+
+		/* check args */
+		fmt = format_by_fourcc(fb->fmt.pixelformat);
+		if (NULL == fmt)
+			return -EINVAL;
+
+		/* ok, accept it */
+		dev->ovbuf = *fb;
+		dev->ovfmt = fmt;
+		if (0 == dev->ovbuf.fmt.bytesperline)
+			dev->ovbuf.fmt.bytesperline =
+				dev->ovbuf.fmt.width*fmt->depth/8;
+		return 0;
+	}
+	case VIDIOC_OVERLAY:
+	{
+		int *on = arg;
+
+		if (*on) {
+			if (!res_get(dev,fh,RESOURCE_OVERLAY))
+				return -EBUSY;
+			spin_lock_irqsave(&dev->slock,flags);
+			start_preview(dev,fh);
+			spin_unlock_irqrestore(&dev->slock,flags);
+		}
+		if (!*on) {
+			if (!res_check(fh, RESOURCE_OVERLAY))
+				return -EINVAL;
+			spin_lock_irqsave(&dev->slock,flags);
+			stop_preview(dev,fh);
+			spin_unlock_irqrestore(&dev->slock,flags);
+			res_free(dev,fh,RESOURCE_OVERLAY);
+		}
+		return 0;
+	}
+
+	/* --- capture ioctls ---------------------------------------- */
+	case VIDIOC_G_FMT:
+	{
+		struct v4l2_format *f = arg;
+		return saa7134_g_fmt(dev,fh,f);
+	}
+	case VIDIOC_S_FMT:
+	{
+		struct v4l2_format *f = arg;
+		return saa7134_s_fmt(dev,fh,f);
+	}
+	case VIDIOC_TRY_FMT:
+	{
+		struct v4l2_format *f = arg;
+		return saa7134_try_fmt(dev,fh,f);
+	}
+	
+	case VIDIOCGMBUF:
+	{
+		struct video_mbuf *mbuf = arg;
+		struct videobuf_queue *q;
+		int i;
+
+		q = saa7134_queue(fh);
+		down(&q->lock);
+		err = videobuf_mmap_setup(file,q,gbuffers,gbufsize);
+		if (err < 0) {
+			up(&q->lock);
+			return err;
+		}
+		memset(mbuf,0,sizeof(*mbuf));
+		mbuf->frames = gbuffers;
+		mbuf->size   = gbuffers * gbufsize;
+		for (i = 0; i < gbuffers; i++)
+			mbuf->offsets[i] = i * gbufsize;
+		up(&q->lock);
+		return 0;
+	}
+	case VIDIOC_REQBUFS:
+		return videobuf_reqbufs(file,saa7134_queue(fh),arg);
+
+	case VIDIOC_QUERYBUF:
+		return videobuf_querybuf(saa7134_queue(fh),arg);
+
+	case VIDIOC_QBUF:
+		return videobuf_qbuf(file,saa7134_queue(fh),arg);
+
+	case VIDIOC_DQBUF:
+		return videobuf_dqbuf(file,saa7134_queue(fh),arg);
+
+	case VIDIOC_STREAMON:
+	{
+		int res = saa7134_resource(fh);
+
+                if (!res_get(dev,fh,res))
+			return -EBUSY;
+		return videobuf_streamon(file,saa7134_queue(fh));
+	}
+	case VIDIOC_STREAMOFF:
+	{
+		int res = saa7134_resource(fh);
+		err = videobuf_streamoff(file,saa7134_queue(fh));
+		res_free(dev,fh,res);
+		return 0;
+	}
+
+	default:
+		return v4l_compat_translate_ioctl(inode,file,cmd,arg,
+						  video_do_ioctl);
+	}
+	return 0;
+}
+
+static int video_ioctl(struct inode *inode, struct file *file,
+		       unsigned int cmd, unsigned long arg)
+{
+	return video_usercopy(inode, file, cmd, arg, video_do_ioctl);
+}
+
+static int radio_do_ioctl(struct inode *inode, struct file *file,
+			  unsigned int cmd, void *arg)
+{
+	struct saa7134_fh *fh = file->private_data;
+	struct saa7134_dev *dev = fh->dev;
+	
+	if (video_debug > 1)
+		saa7134_print_ioctl(dev->name,cmd);
+	switch (cmd) {
+	case VIDIOC_QUERYCAP:
+	{
+		struct v4l2_capability *cap = arg;
+
+		memset(cap,0,sizeof(*cap));
+                strcpy(cap->driver, "saa7134");
+		strncpy(cap->card, saa7134_boards[dev->board].name,
+			sizeof(cap->card));
+		sprintf(cap->bus_info,"PCI:%s",dev->pci->slot_name);
+		cap->version = SAA7134_VERSION_CODE;
+		cap->capabilities = V4L2_CAP_TUNER;
+		return 0;
+	}
+	case VIDIOC_G_TUNER:
+	{
+		struct v4l2_tuner *t = arg;
+		struct video_tuner vt;
+
+		memset(t,0,sizeof(*t));
+		strcpy(t->name, "Radio");
+                t->rangelow  = (int)(65*16);
+                t->rangehigh = (int)(108*16);
+		
+		memset(&vt,0,sizeof(vt));
+		saa7134_i2c_call_clients(dev,VIDIOCGTUNER,&vt);
+		t->signal = vt.signal;
+		return 0;
+	}
+	case VIDIOC_ENUMINPUT:
+	{
+		struct v4l2_input *i = arg;
+		
+		if (i->index != 0)
+			return -EINVAL;
+		strcpy(i->name,"Radio");
+		i->type = V4L2_INPUT_TYPE_TUNER;
+		return 0;
+	}
+	case VIDIOC_G_INPUT:
+	{
+		int *i = arg;
+		*i = 0;
+		return 0;
+	}
+	case VIDIOC_G_AUDIO:
+	{
+		struct v4l2_audio *a = arg;
+
+		memset(a,0,sizeof(*a));
+		strcpy(a->name,"Radio");
+		return 0;
+	}
+	case VIDIOC_S_AUDIO:
+	case VIDIOC_S_TUNER:
+	case VIDIOC_S_INPUT:
+		return 0;
+
+	case VIDIOC_QUERYCTRL:
+	{
+		const struct v4l2_queryctrl *ctrl;
+		struct v4l2_queryctrl *c = arg;
+
+		if (c->id <  V4L2_CID_BASE ||
+		    c->id >= V4L2_CID_LASTP1)
+			return -EINVAL;
+		if (c->id == V4L2_CID_AUDIO_MUTE) {
+			ctrl = ctrl_by_id(c->id);
+			*c = *ctrl;
+		} else
+			*c = no_ctrl;
+		return 0;
+	}
+
+	case VIDIOC_G_CTRL:
+	case VIDIOC_S_CTRL:
+	case VIDIOC_G_FREQUENCY:
+	case VIDIOC_S_FREQUENCY:
+		return video_do_ioctl(inode,file,cmd,arg);
+		
+	default:
+		return v4l_compat_translate_ioctl(inode,file,cmd,arg,
+						  radio_do_ioctl);
+	}
+	return 0;
+}
+
+static int radio_ioctl(struct inode *inode, struct file *file,
+		       unsigned int cmd, unsigned long arg)
+{
+	return video_usercopy(inode, file, cmd, arg, radio_do_ioctl);
+}
+
+static struct file_operations video_fops =
+{
+	owner:	  THIS_MODULE,
+	open:	  video_open,
+	release:  video_release,
+	read:	  video_read,
+	poll:     video_poll,
+	mmap:	  video_mmap,
+	ioctl:	  video_ioctl,
+	llseek:   no_llseek,
+};
+
+static struct file_operations radio_fops =
+{
+	owner:	  THIS_MODULE,
+	open:	  video_open,
+	release:  video_release,
+	ioctl:	  radio_ioctl,
+	llseek:   no_llseek,
+};
+
+/* ----------------------------------------------------------- */
+/* exported stuff                                              */
+
+struct video_device saa7134_video_template =
+{
+	name:          "saa7134-video",
+	type:          VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|
+	               VID_TYPE_CLIPPING|VID_TYPE_SCALES,
+	hardware:      0,
+	fops:          &video_fops,
+	minor:         -1,
+};
+
+struct video_device saa7134_vbi_template =
+{
+	name:          "saa7134-vbi",
+	type:          VID_TYPE_TUNER|VID_TYPE_TELETEXT,
+	hardware:      0,
+	fops:          &video_fops,
+	minor:         -1,
+};
+
+struct video_device saa7134_radio_template =
+{
+	name:          "saa7134-radio",
+	type:          VID_TYPE_TUNER,
+	hardware:      0,
+	fops:          &radio_fops,
+	minor:         -1,
+};
+
+int saa7134_video_init(struct saa7134_dev *dev)
+{
+	/* sanitycheck insmod options */
+	if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME)
+		gbuffers = 2;
+	if (gbufsize < 0 || gbufsize > gbufsize_max)
+		gbufsize = gbufsize_max;
+	gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK;
+
+	/* put some sensible defaults into the data structures ... */
+	dev->ctl_bright     = ctrl_by_id(V4L2_CID_BRIGHTNESS)->default_value;
+	dev->ctl_contrast   = ctrl_by_id(V4L2_CID_CONTRAST)->default_value;
+	dev->ctl_hue        = ctrl_by_id(V4L2_CID_HUE)->default_value;
+	dev->ctl_saturation = ctrl_by_id(V4L2_CID_SATURATION)->default_value;
+	dev->ctl_volume     = ctrl_by_id(V4L2_CID_AUDIO_VOLUME)->default_value;
+
+	dev->ctl_invert     = 0;
+	dev->ctl_mute       = 1;
+	dev->automute       = 0;
+
+        INIT_LIST_HEAD(&dev->video_q.queue);
+	dev->video_q.timeout.function = saa7134_buffer_timeout;
+	dev->video_q.timeout.data     = (unsigned long)(&dev->video_q);
+	dev->video_q.dev              = dev;
+
+	/* init video hw */
+	set_tvnorm(dev,&tvnorms[0]);
+	video_mux(dev,0);
+	saa7134_tvaudio_setmute(dev);
+	saa7134_tvaudio_setvolume(dev,dev->ctl_volume);
+
+	if (saa7134_boards[dev->board].video_out) {
+		/* enable video output */
+		int vo = saa7134_boards[dev->board].video_out;
+		saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]);
+		saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_out[vo][1]);
+		saa_writeb(SAA7134_VIDEO_PORT_CTRL2, video_out[vo][2]);
+		saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]);
+		saa_writeb(SAA7134_VIDEO_PORT_CTRL4, video_out[vo][4]);
+		saa_writeb(SAA7134_VIDEO_PORT_CTRL5, video_out[vo][5]);
+		saa_writeb(SAA7134_VIDEO_PORT_CTRL6, video_out[vo][6]);
+		saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]);
+		saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]);
+	}
+ 
+	return 0;
+}
+
+int saa7134_video_fini(struct saa7134_dev *dev)
+{
+	/* nothing */
+	return 0;
+}
+
+void saa7134_irq_video_intl(struct saa7134_dev *dev)
+{
+	static const char *st[] = {
+		"no signal", "found NTSC", "found PAL", "found SECAM" };
+	int norm;
+
+	norm = saa_readb(SAA7134_STATUS_VIDEO1) & 0x03;
+	printk("%s/video: DCSDT: %s\n",dev->name,st[norm]);
+	
+	if (0 != norm) {
+		/* wake up tvaudio audio carrier scan thread */
+		saa7134_tvaudio_do_scan(dev);
+	} else {
+		/* no video signal -> mute audio */
+		dev->automute = 1;
+		saa7134_tvaudio_setmute(dev);
+	}
+}
+
+void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status)
+{
+	enum v4l2_field field;
+	
+	spin_lock(&dev->slock);
+	if (dev->video_q.curr) {
+		field = dev->video_q.curr->vb.field;
+		
+		if (V4L2_FIELD_HAS_BOTH(field)) {
+			/* make sure we have seen both fields */
+			if ((status & 0x10) == 0x10) {
+				dev->video_q.curr->top_seen = 1;
+				goto done;
+			}
+			if (!dev->video_q.curr->top_seen)
+				goto done;
+		} else if (field == V4L2_FIELD_TOP) {
+			if ((status & 0x10) != 0x10)
+				goto done;
+		} else if (field == V4L2_FIELD_BOTTOM) {
+			if ((status & 0x10) != 0x00)
+				goto done;
+		}
+		saa7134_buffer_finish(dev,&dev->video_q,STATE_DONE);
+	}
+	saa7134_buffer_next(dev,&dev->video_q);
+
+ done:
+	spin_unlock(&dev->slock);
+}
+
+/* ----------------------------------------------------------- */
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff -Nru a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/media/video/saa7134/saa7134.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,473 @@
+/*
+ * v4l2 device driver for philips saa7134 based TV cards
+ *
+ * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/pci.h>
+#include <linux/i2c.h>
+#include <linux/videodev.h>
+#include <linux/kdev_t.h>
+#include "video-buf.h"
+
+#define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,1)
+
+#ifndef TRUE
+# define TRUE (1==1)
+#endif
+#ifndef FALSE
+# define FALSE (1==0)
+#endif
+
+/* 2.4 / 2.5 driver compatibility stuff */
+
+/* ----------------------------------------------------------- */
+/* enums                                                       */
+
+enum saa7134_tvaudio_mode {
+	TVAUDIO_FM_MONO       = 1,
+	TVAUDIO_FM_BG_STEREO  = 2,
+	TVAUDIO_FM_SAT_STEREO = 3,
+	TVAUDIO_FM_K_STEREO   = 4,
+	TVAUDIO_NICAM_AM      = 5,
+	TVAUDIO_NICAM_FM      = 6,
+};
+
+enum saa7134_audio_in {
+	TV    = 1,
+	LINE1 = 2,
+	LINE2 = 3,
+};
+
+enum saa7134_video_out {
+	CCIR656 = 1,
+};
+
+/* ----------------------------------------------------------- */
+/* static data                                                 */
+
+struct saa7134_tvnorm {
+	char          *name;
+	v4l2_std_id   id;
+	int           width;
+	int           height;
+
+	/* video decoder */
+	int           sync_control;
+	int           luma_control;
+	int           chroma_ctrl1;
+	int           chroma_gain;
+	int           chroma_ctrl2;
+
+	/* video scaler */
+	int           h_start;
+	int           h_stop;
+	int           video_v_start;
+	int           video_v_stop;
+	int           vbi_v_start;
+	int           vbi_v_stop;
+};
+
+struct saa7134_tvaudio {
+	char  *name;
+	int   std;
+	enum  saa7134_tvaudio_mode mode;
+	int   carr1;
+	int   carr2;
+};
+
+struct saa7134_format {
+	char  *name;
+	int   fourcc;
+	int   depth;
+	int   pm;
+	int   vshift;   /* vertical downsampling (for planar yuv) */
+	int   hshift;   /* horizontal downsampling (for planar yuv) */
+	int   bswap:1;
+	int   wswap:1;
+	int   yuv:1;
+	int   planar:1;
+};
+
+/* ----------------------------------------------------------- */
+/* card configuration                                          */
+
+#define SAA7134_BOARD_NOAUTO           -1
+#define SAA7134_BOARD_UNKNOWN           0
+#define SAA7134_BOARD_PROTEUS_PRO       1
+#define SAA7134_BOARD_FLYVIDEO3000      2
+#define SAA7134_BOARD_FLYVIDEO2000      3
+#define SAA7134_BOARD_EMPRESS           4
+#define SAA7134_BOARD_MONSTERTV         5
+#define SAA7134_BOARD_MD9717            6
+#define SAA7134_BOARD_TVSTATION_RDS     7
+#define SAA7134_BOARD_CINERGY400	8
+#define SAA7134_BOARD_MD5044		9
+
+#define SAA7134_INPUT_MAX 8
+
+struct saa7134_input {
+	char                    *name;
+	int                     vmux;
+	enum saa7134_audio_in   amux;
+	int                     gpio;
+	int                     tv:1;
+};
+
+struct saa7134_board {
+	char                    *name;
+	int                     audio_clock;
+
+	/* input switching */
+	int                     gpiomask;
+	struct saa7134_input    inputs[SAA7134_INPUT_MAX];
+	struct saa7134_input    radio;
+	struct saa7134_input    mute;
+	
+	/* peripheral I/O */
+	int                     i2s_rate;
+	int                     has_ts;
+	enum saa7134_video_out  video_out;
+
+	/* i2c chip info */
+	int                     tuner_type;
+	int                     need_tda9887:1;
+};
+
+#define card_has_audio(dev)   (dev->pci->device == PCI_DEVICE_ID_PHILIPS_SAA7134)
+#define card_has_radio(dev)   (NULL != saa7134_boards[dev->board].radio.name)
+#define card_has_ts(dev)      (saa7134_boards[dev->board].has_ts)
+#define card(dev)             (saa7134_boards[dev->board])
+#define card_in(dev,n)        (saa7134_boards[dev->board].inputs[n])
+
+/* ----------------------------------------------------------- */
+/* device / file handle status                                 */
+
+#define RESOURCE_OVERLAY       1
+#define RESOURCE_VIDEO         2
+#define RESOURCE_VBI           3
+
+#define INTERLACE_AUTO         0
+#define INTERLACE_ON           1
+#define INTERLACE_OFF          2
+
+#define BUFFER_TIMEOUT     (HZ/2)  /* 0.5 seconds */
+
+struct saa7134_dev;
+struct saa7134_dma;
+
+/* saa7134 page table */
+struct saa7134_pgtable {
+	unsigned int               size;
+	u32                        *cpu;
+	dma_addr_t                 dma;
+};
+
+/* tvaudio thread status */
+struct saa7134_thread {
+	struct task_struct         *task;
+	wait_queue_head_t          wq;
+	struct semaphore           *notify;
+	int                        exit;
+	int                        scan1;
+	int                        scan2;
+};
+
+/* buffer for one video/vbi/ts frame */
+struct saa7134_buf {
+	/* common v4l buffer stuff -- must be first */
+	struct videobuf_buffer vb;
+
+	/* saa7134 specific */
+	struct saa7134_format   *fmt;
+	int                     top_seen;
+	int (*activate)(struct saa7134_dev *dev,
+			struct saa7134_buf *buf,
+			struct saa7134_buf *next);
+
+	/* page tables */
+	struct saa7134_pgtable  *pt;
+};
+
+struct saa7134_dmaqueue {
+	struct saa7134_dev         *dev;
+	struct saa7134_buf         *curr;
+	struct list_head           queue;
+	struct timer_list          timeout;
+};
+
+/* video filehandle status */
+struct saa7134_fh {
+	struct saa7134_dev         *dev;
+	int                        radio;
+	enum v4l2_buf_type         type;
+
+	struct v4l2_window         win;
+	struct v4l2_clip           clips[8];
+	int                        nclips;
+	int                        resources;
+
+	/* video capture */
+	struct saa7134_format      *fmt;
+	int                        width,height;
+	enum v4l2_field            field;
+	struct videobuf_queue      cap;
+	struct saa7134_pgtable     pt_cap;
+
+	/* vbi capture */
+	struct videobuf_queue      vbi;
+	struct saa7134_pgtable     pt_vbi;
+};
+
+/* TS status */
+struct saa7134_ts {
+	int                        users;
+
+	/* TS capture */
+	struct videobuf_queue      ts;
+	struct saa7134_pgtable     pt_ts;
+};
+
+/* oss dsp status */
+struct saa7134_oss {
+        struct semaphore           lock;
+	int                        minor_mixer;
+	int                        minor_dsp;
+	int                        users_dsp;
+
+	/* mixer */
+	enum saa7134_audio_in      input;
+	int                        count;
+	int                        line1;
+	int                        line2;
+
+	/* dsp */
+	int                        afmt;
+	int                        rate;
+	int                        channels;
+	int                        recording;
+	int                        blocks;
+	int                        blksize;
+	int                        bufsize;
+	struct saa7134_pgtable     pt;
+	struct videobuf_dmabuf     dma;
+	wait_queue_head_t          wq;
+	int                        dma_blk;
+	int                        read_offset;
+	int                        read_count;
+};
+
+/* global device status */
+struct saa7134_dev {
+	struct list_head           devlist;
+        struct semaphore           lock;
+       	spinlock_t                 slock;
+
+	/* various device info */
+	int                        resources;
+	struct video_device        video_dev;
+	struct video_device        ts_dev;
+	struct video_device        radio_dev;
+	struct video_device        vbi_dev;
+	struct saa7134_oss         oss;
+	struct saa7134_ts          ts;
+
+	/* pci i/o */
+	char                       name[32];
+	struct pci_dev             *pci;
+	unsigned char              pci_rev,pci_lat;
+	__u32                      *lmmio;
+	__u8                       *bmmio;
+
+	/* config info */
+	int                        board;
+	int                        tuner_type;
+
+	/* i2c i/o */
+	struct i2c_adapter         i2c_adap;
+	struct i2c_client          i2c_client;
+	unsigned char              eedata[64];
+
+	/* video overlay */
+	struct v4l2_framebuffer    ovbuf;
+	struct saa7134_format      *ovfmt;
+	int                        ovenable;
+	enum v4l2_field            ovfield;
+
+	/* video+ts+vbi capture */
+	struct saa7134_dmaqueue    video_q;
+	struct saa7134_dmaqueue    ts_q;
+	struct saa7134_dmaqueue    vbi_q;
+	int                        vbi_fieldcount;
+
+	/* various v4l controls */
+	struct saa7134_tvnorm      *tvnorm;              /* video */
+	struct saa7134_tvaudio     *tvaudio;
+	int                        ctl_input;
+	int                        ctl_bright;
+	int                        ctl_contrast;
+	int                        ctl_hue;
+	int                        ctl_saturation;
+	int                        ctl_freq;
+	int                        ctl_mute;             /* audio */
+	int                        ctl_volume;
+	int                        ctl_invert;           /* private */
+	int                        ctl_mirror;
+	int                        ctl_y_odd;
+	int                        ctl_y_even;
+
+	/* other global state info */
+	int                        automute;
+	struct saa7134_thread      thread;
+	struct saa7134_input       *input;
+	struct saa7134_input       *hw_input;
+	int                        hw_mute;
+};
+
+/* ----------------------------------------------------------- */
+
+#define saa_readl(reg)             readl(dev->lmmio + (reg))
+#define saa_writel(reg,value)      writel((value), dev->lmmio + (reg));
+#define saa_andorl(reg,mask,value) \
+  writel((readl(dev->lmmio+(reg)) & ~(mask)) |\
+  ((value) & (mask)), dev->lmmio+(reg))
+#define saa_setl(reg,bit)          saa_andorl((reg),(bit),(bit))
+#define saa_clearl(reg,bit)        saa_andorl((reg),(bit),0)
+
+#define saa_readb(reg)             readb(dev->bmmio + (reg))
+#define saa_writeb(reg,value)      writeb((value), dev->bmmio + (reg));
+#define saa_andorb(reg,mask,value) \
+  writeb((readb(dev->bmmio+(reg)) & ~(mask)) |\
+  ((value) & (mask)), dev->bmmio+(reg))
+#define saa_setb(reg,bit)          saa_andorb((reg),(bit),(bit))
+#define saa_clearb(reg,bit)        saa_andorb((reg),(bit),0)
+
+
+/* ----------------------------------------------------------- */
+/* saa7134-core.c                                              */
+
+extern struct list_head  saa7134_devlist;
+extern int               saa7134_devcount;
+
+void saa7134_print_ioctl(char *name, unsigned int cmd);
+void saa7134_track_gpio(struct saa7134_dev *dev, char *msg);
+
+#define SAA7134_PGTABLE_SIZE 4096
+
+int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt);
+int  saa7134_pgtable_build(struct pci_dev *pci, struct saa7134_pgtable *pt,
+			   struct scatterlist *list, int length,
+			   int startpage);
+void saa7134_pgtable_free(struct pci_dev *pci, struct saa7134_pgtable *pt);
+
+int saa7134_buffer_count(int size, int count);
+int saa7134_buffer_startpage(struct saa7134_buf *buf);
+unsigned long saa7134_buffer_base(struct saa7134_buf *buf);
+
+int saa7134_buffer_queue(struct saa7134_dev *dev, struct saa7134_dmaqueue *q,
+			 struct saa7134_buf *buf);
+void saa7134_buffer_finish(struct saa7134_dev *dev, struct saa7134_dmaqueue *q,
+			   int state);
+void saa7134_buffer_next(struct saa7134_dev *dev, struct saa7134_dmaqueue *q);
+void saa7134_buffer_timeout(unsigned long data);
+void saa7134_dma_free(struct saa7134_dev *dev,struct saa7134_buf *buf);
+
+int saa7134_set_dmabits(struct saa7134_dev *dev);
+
+/* ----------------------------------------------------------- */
+/* saa7134-cards.c                                             */
+
+extern struct saa7134_board saa7134_boards[];
+extern const int saa7134_bcount;
+extern struct pci_device_id __devinitdata saa7134_pci_tbl[];
+
+
+/* ----------------------------------------------------------- */
+/* saa7134-i2c.c                                               */
+
+int saa7134_i2c_register(struct saa7134_dev *dev);
+int saa7134_i2c_unregister(struct saa7134_dev *dev);
+void saa7134_i2c_call_clients(struct saa7134_dev *dev,
+			      unsigned int cmd, void *arg);
+
+
+/* ----------------------------------------------------------- */
+/* saa7134-video.c                                             */
+
+extern struct video_device saa7134_video_template;
+extern struct video_device saa7134_radio_template;
+
+int saa7134_common_ioctl(struct saa7134_dev *dev,
+			 unsigned int cmd, void *arg);
+
+int saa7134_video_init(struct saa7134_dev *dev);
+int saa7134_video_fini(struct saa7134_dev *dev);
+void saa7134_irq_video_intl(struct saa7134_dev *dev);
+void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status);
+
+
+/* ----------------------------------------------------------- */
+/* saa7134-ts.c                                                */
+
+extern struct video_device saa7134_ts_template;
+int saa7134_ts_init(struct saa7134_dev *dev);
+int saa7134_ts_fini(struct saa7134_dev *dev);
+void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status);
+
+
+/* ----------------------------------------------------------- */
+/* saa7134-vbi.c                                               */
+
+extern struct videobuf_queue_ops saa7134_vbi_qops;
+extern struct video_device saa7134_vbi_template;
+
+int saa7134_vbi_init(struct saa7134_dev *dev);
+int saa7134_vbi_fini(struct saa7134_dev *dev);
+void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status);
+
+
+/* ----------------------------------------------------------- */
+/* saa7134-tvaudio.c                                           */
+
+void saa7134_tvaudio_setmute(struct saa7134_dev *dev);
+void saa7134_tvaudio_setinput(struct saa7134_dev *dev,
+			      struct saa7134_input *in);
+void saa7134_tvaudio_setvolume(struct saa7134_dev *dev, int level);
+int saa7134_tvaudio_getstereo(struct saa7134_dev *dev,
+			      struct saa7134_tvaudio *audio);
+
+int saa7134_tvaudio_init(struct saa7134_dev *dev);
+int saa7134_tvaudio_fini(struct saa7134_dev *dev);
+int saa7134_tvaudio_do_scan(struct saa7134_dev *dev);
+
+
+/* ----------------------------------------------------------- */
+/* saa7134-oss.c                                               */
+
+extern struct file_operations saa7134_dsp_fops;
+extern struct file_operations saa7134_mixer_fops;
+
+int saa7134_oss_init(struct saa7134_dev *dev);
+int saa7134_oss_fini(struct saa7134_dev *dev);
+void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status);
+
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff -Nru a/drivers/media/video/tuner.c b/drivers/media/video/tuner.c
--- a/drivers/media/video/tuner.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/media/video/tuner.c	Mon Nov  4 14:31:02 2002
@@ -101,10 +101,16 @@
 
 /* system switching for Philips FI1216MF MK2
    from datasheet "1996 Jul 09",
+    standard         BG     L      L'
+    picture carrier  38.90  38.90  33.95
+    colour	     34.47  34.37  38.38
+    sound 1          33.40  32.40  40.45
+    sound 2          33.16  -      -
+    NICAM            33.05  33.05  39.80
  */
 #define PHILIPS_MF_SET_BG	0x01 /* Bit 2 must be zero, Bit 3 is system output */
-#define PHILIPS_MF_SET_PAL_L	0x03
-#define PHILIPS_MF_SET_PAL_L2	0x02
+#define PHILIPS_MF_SET_PAL_L	0x03 // France
+#define PHILIPS_MF_SET_PAL_L2	0x02 // L'
 
 
 /* ---------------------------------------------------------------------- */
@@ -121,7 +127,9 @@
 	unsigned char VHF_H;
 	unsigned char UHF;
 	unsigned char config; 
-	unsigned short IFPCoff; /* 622.4=16*38.90 MHz PAL, 732=16*45.75 NTSC */
+	unsigned short IFPCoff; /* 622.4=16*38.90 MHz PAL, 
+				   732  =16*45.75 NTSCi, 
+				   940  =58.75 NTSC-Japan */
 };
 
 /*
@@ -132,16 +140,16 @@
 static struct tunertype tuners[] = {
         { "Temic PAL (4002 FH5)", TEMIC, PAL,
 	  16*140.25,16*463.25,0x02,0x04,0x01,0x8e,623},
-	{ "Philips PAL_I", Philips, PAL_I,
+	{ "Philips PAL_I (FI1246 and compatibles)", Philips, PAL_I,
 	  16*140.25,16*463.25,0xa0,0x90,0x30,0x8e,623},
-	{ "Philips NTSC", Philips, NTSC,
+	{ "Philips NTSC (FI1236 and compatibles)", Philips, NTSC,
 	  16*157.25,16*451.25,0xA0,0x90,0x30,0x8e,732},
-	{ "Philips SECAM", Philips, SECAM,
+	{ "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)", Philips, SECAM,
 	  16*168.25,16*447.25,0xA7,0x97,0x37,0x8e,623},
 
 	{ "NoTuner", NoTuner, NOTUNER,
 	  0,0,0x00,0x00,0x00,0x00,0x00},
-	{ "Philips PAL", Philips, PAL,
+	{ "Philips PAL_BG (FI1216 and compatibles)", Philips, PAL,
 	  16*168.25,16*447.25,0xA0,0x90,0x30,0x8e,623},
 	{ "Temic NTSC (4032 FY5)", TEMIC, NTSC,
 	  16*157.25,16*463.25,0x02,0x04,0x01,0x8e,732},
@@ -181,7 +189,7 @@
           16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
         { "Temic PAL/SECAM multi (4046 FM5)", TEMIC, PAL,
           16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
-        { "Philips PAL_DK", Philips, PAL,
+        { "Philips PAL_DK (FI1256 and compatibles)", Philips, PAL,
 	  16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
 
 	{ "Philips PAL/SECAM multi (FQ1216ME)", Philips, PAL,
@@ -200,7 +208,7 @@
 	{ "Temic PAL* auto + FM (4009 FN5)", TEMIC, PAL,
 	  16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
 	{ "SHARP NTSC_JP (2U5JF5540)", SHARP, NTSC, /* 940=16*58.75 NTSC@Japan */
-	  16*137.25,16*317.25,0x01,0x02,0x08,0x8e,940},
+	  16*137.25,16*317.25,0x01,0x02,0x08,0x8e,732 }, // Corrected to NTSC=732 (was:940)
 
 	{ "Samsung PAL TCPM9091PD27", Samsung, PAL,  /* from sourceforge v3tv */
           16*169,16*464,0xA0,0x90,0x30,0x8e,623},
@@ -215,8 +223,10 @@
           16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
         { "LG PAL (newer TAPC series)", LGINNOTEK, PAL,
           16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,623},
-	{ "Philips PAL/SECAM multi (FM1216ME)", Philips, PAL,
+	{ "Philips PAL/SECAM multi (FM1216ME MK3)", Philips, PAL,
 	  16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 },
+	{ "LG NTSC (newer TAPC series)", LGINNOTEK, NTSC,
+          16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,732},
 };
 #define TUNERS (sizeof(tuners)/sizeof(struct tunertype))
 
@@ -295,6 +305,13 @@
                 }
                 printk("\n ");
         }
+	// Look for MT2032 id:
+	// part= 0x04(MT2032), 0x06(MT2030), 0x07(MT2040)
+        if((buf[0x11] != 0x4d) || (buf[0x12] != 0x54) || (buf[0x13] != 0x04)) {
+                printk("not a MT2032.\n");
+                return 0;
+        }
+
 
         // Initialize Registers per spec.
         buf[1]=2; // Index to register 2
@@ -621,7 +638,7 @@
 
 	/* tv norm specific stuff for multi-norm tuners */
 	switch (t->type) {
-	case TUNER_PHILIPS_SECAM:
+	case TUNER_PHILIPS_SECAM: // FI1216MF
 		/* 0x01 -> ??? no change ??? */
 		/* 0x02 -> PAL BDGHI / SECAM L */
 		/* 0x04 -> ??? PAL others / SECAM others ??? */
@@ -751,7 +768,7 @@
         buffer[1] = div      & 0xff;
 	buffer[2] = tun->config;
 	switch (t->type) {
-	case TUNER_PHILIPS_FM1216ME:
+	case TUNER_PHILIPS_FM1216ME_MK3:
 		buffer[3] = 0x19;
 		break;
 	default:
@@ -857,12 +874,14 @@
 
 	/* --- configuration --- */
 	case TUNER_SET_TYPE:
-		if (t->type != -1)
+		if (t->type != -1) {
+			printk("tuner: type already set\n");
 			return 0;
+		}
 		if (*iarg < 0 || *iarg >= TUNERS)
 			return 0;
 		t->type = *iarg;
-		dprintk("tuner: type set to %d (%s)\n",
+		printk("tuner: type set to %d (%s)\n",
                         t->type,tuners[t->type].name);
 		strncpy(client->name, tuners[t->type].name, sizeof(client->name));
 		if (t->type == TUNER_MT2032)
@@ -965,7 +984,7 @@
 };
 static struct i2c_client client_template =
 {
-        name:   "(unset)",
+        name:   "(tuner unset)",
 	flags:  I2C_CLIENT_ALLOW_USE,
         driver: &driver,
 };
diff -Nru a/drivers/media/video/tuner.h b/drivers/media/video/tuner.h
--- a/drivers/media/video/tuner.h	Mon Nov  4 14:31:02 2002
+++ b/drivers/media/video/tuner.h	Mon Nov  4 14:31:02 2002
@@ -62,7 +62,9 @@
 #define TUNER_TEMIC_4012FY5	35	/* 4012 FY5 (3X 0971, 1099)*/
 #define TUNER_TEMIC_4136FY5	36	/* 4136 FY5 (3X 7708, 7746)*/
 #define TUNER_LG_PAL_NEW_TAPC   37
-#define TUNER_PHILIPS_FM1216ME  38
+#define TUNER_PHILIPS_FM1216ME_MK3  38
+#define TUNER_LG_NTSC_NEW_TAPC   39
+
 
 
 
@@ -84,7 +86,9 @@
 
 #define TUNER_SET_TYPE               _IOW('t',1,int)    /* set tuner type */
 #define TUNER_SET_TVFREQ             _IOW('t',2,int)    /* set tv freq */
-#define TUNER_SET_RADIOFREQ          _IOW('t',3,int)    /* set radio freq */
-#define TUNER_SET_MODE               _IOW('t',4,int)    /* set tuner mode */
+#if 0 /* obsolete */
+# define TUNER_SET_RADIOFREQ         _IOW('t',3,int)    /* set radio freq */
+# define TUNER_SET_MODE              _IOW('t',4,int)    /* set tuner mode */
+#endif
 
 #endif
diff -Nru a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/media/video/v4l2-common.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,211 @@
+/*
+ *	Video for Linux Two
+ *
+ *	A generic video device interface for the LINUX operating system
+ *	using a set of device structures/vectors for low level operations.
+ *
+ *	This file replaces the videodev.c file that comes with the
+ *	regular kernel distribution.
+ *
+ *	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.
+ *
+ * Author:	Bill Dirks <bdirks@pacbell.net>
+ *		based on code by Alan Cox, <alan@cymru.net>
+ *
+ */
+
+/*
+ * Video capture interface for Linux
+ *
+ *	A generic video device interface for the LINUX operating system
+ *	using a set of device structures/vectors for low level operations.
+ *
+ *		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.
+ *
+ * Author:	Alan Cox, <alan@redhat.com>
+ *
+ * Fixes:
+ */
+
+/*
+ * Video4linux 1/2 integration by Justin Schoeman
+ * <justin@suntiger.ee.up.ac.za>
+ * 2.4 PROCFS support ported from 2.4 kernels by 
+ *  Iñaki García Etxebarria <garetxe@euskalnet.net>
+ * Makefile fix by "W. Michael Petullo" <mike@flyn.org>
+ * 2.4 devfs support ported from 2.4 kernels by
+ *  Dan Merillat <dan@merillat.org>
+ * Added Gerd Knorrs v4l1 enhancements (Justin Schoeman)
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/io.h>
+#include <asm/div64.h>
+
+#ifdef CONFIG_KMOD
+#include <linux/kmod.h>
+#endif
+
+#if defined(CONFIG_UST) || defined(CONFIG_UST_MODULE)
+#include <linux/ust.h>
+#endif
+
+#include <linux/videodev.h>
+
+MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Gerd Knorr");
+MODULE_DESCRIPTION("misc helper functions for v4l2 device drivers");
+MODULE_LICENSE("GPL");
+
+/*
+ *
+ *	V 4 L 2   D R I V E R   H E L P E R   A P I
+ *
+ */
+
+/*
+ *  Video Standard Operations (contributed by Michael Schimek)
+ */
+
+/* This is the recommended method to deal with the framerate fields. More 
+   sophisticated drivers will access the fields directly. */
+unsigned int
+v4l2_video_std_fps(struct v4l2_standard *vs)
+{ 
+	if (vs->frameperiod.numerator > 0)
+		return (((vs->frameperiod.denominator << 8) / 
+			 vs->frameperiod.numerator) + 
+			(1 << 7)) / (1 << 8);
+	return 0;
+}
+
+/* Fill in the fields of a v4l2_standard structure according to the
+   'id' and 'transmission' parameters.  Returns negative on error.  */
+int v4l2_video_std_construct(struct v4l2_standard *vs,
+			     int id, char *name)
+{
+	memset(vs, 0, sizeof(struct v4l2_standard));
+
+	vs->id = id;
+	if (id & (V4L2_STD_NTSC | V4L2_STD_PAL_M)) {
+		vs->frameperiod.numerator = 1001;
+		vs->frameperiod.denominator = 30000;
+		vs->framelines = 525;
+	} else {
+		vs->frameperiod.numerator = 1;
+		vs->frameperiod.denominator = 25;
+		vs->framelines = 625;
+	}
+	strncpy(vs->name,name,sizeof(vs->name));
+	return 0;
+}
+
+
+/* ----------------------------------------------------------------- */
+
+char *v4l2_field_names[] = {
+	[V4L2_FIELD_ANY]        = "any",
+	[V4L2_FIELD_NONE]       = "none",
+	[V4L2_FIELD_TOP]        = "top",
+	[V4L2_FIELD_BOTTOM]     = "bottom",
+	[V4L2_FIELD_INTERLACED] = "interlaced",
+	[V4L2_FIELD_SEQ_TB]     = "seq-tb",
+	[V4L2_FIELD_SEQ_BT]     = "seq-bt",
+	[V4L2_FIELD_ALTERNATE]  = "alternate",
+};
+
+char *v4l2_type_names[] = {
+	[V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap",
+	[V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over",
+	[V4L2_BUF_TYPE_VIDEO_OUTPUT]  = "video-out",
+	[V4L2_BUF_TYPE_VBI_CAPTURE]   = "vbi-cap",
+	[V4L2_BUF_TYPE_VBI_OUTPUT]    = "vbi-out",
+};
+
+char *v4l2_ioctl_names[256] = {
+#if __GNUC__ >= 3
+	[0 ... 255]                      = "UNKNOWN",
+#endif
+	[_IOC_NR(VIDIOC_QUERYCAP)]       = "VIDIOC_QUERYCAP",
+	[_IOC_NR(VIDIOC_RESERVED)]       = "VIDIOC_RESERVED",
+	[_IOC_NR(VIDIOC_ENUM_FMT)]       = "VIDIOC_ENUM_FMT",
+	[_IOC_NR(VIDIOC_G_FMT)]          = "VIDIOC_G_FMT",
+	[_IOC_NR(VIDIOC_S_FMT)]          = "VIDIOC_S_FMT",
+#if 0
+	[_IOC_NR(VIDIOC_G_COMP)]         = "VIDIOC_G_COMP",
+	[_IOC_NR(VIDIOC_S_COMP)]         = "VIDIOC_S_COMP",
+#endif
+	[_IOC_NR(VIDIOC_REQBUFS)]        = "VIDIOC_REQBUFS",
+	[_IOC_NR(VIDIOC_QUERYBUF)]       = "VIDIOC_QUERYBUF",
+	[_IOC_NR(VIDIOC_G_FBUF)]         = "VIDIOC_G_FBUF",
+	[_IOC_NR(VIDIOC_S_FBUF)]         = "VIDIOC_S_FBUF",
+	[_IOC_NR(VIDIOC_OVERLAY)]        = "VIDIOC_OVERLAY",
+	[_IOC_NR(VIDIOC_QBUF)]           = "VIDIOC_QBUF",
+	[_IOC_NR(VIDIOC_DQBUF)]          = "VIDIOC_DQBUF",
+	[_IOC_NR(VIDIOC_STREAMON)]       = "VIDIOC_STREAMON",
+	[_IOC_NR(VIDIOC_STREAMOFF)]      = "VIDIOC_STREAMOFF",
+	[_IOC_NR(VIDIOC_G_PARM)]         = "VIDIOC_G_PARM",
+	[_IOC_NR(VIDIOC_S_PARM)]         = "VIDIOC_S_PARM",
+	[_IOC_NR(VIDIOC_G_STD)]          = "VIDIOC_G_STD",
+	[_IOC_NR(VIDIOC_S_STD)]          = "VIDIOC_S_STD",
+	[_IOC_NR(VIDIOC_ENUMSTD)]        = "VIDIOC_ENUMSTD",
+	[_IOC_NR(VIDIOC_ENUMINPUT)]      = "VIDIOC_ENUMINPUT",
+	[_IOC_NR(VIDIOC_G_CTRL)]         = "VIDIOC_G_CTRL",
+	[_IOC_NR(VIDIOC_S_CTRL)]         = "VIDIOC_S_CTRL",
+	[_IOC_NR(VIDIOC_G_TUNER)]        = "VIDIOC_G_TUNER",
+	[_IOC_NR(VIDIOC_S_TUNER)]        = "VIDIOC_S_TUNER",
+	[_IOC_NR(VIDIOC_G_AUDIO)]        = "VIDIOC_G_AUDIO",
+	[_IOC_NR(VIDIOC_S_AUDIO)]        = "VIDIOC_S_AUDIO",
+	[_IOC_NR(VIDIOC_QUERYCTRL)]      = "VIDIOC_QUERYCTRL",
+	[_IOC_NR(VIDIOC_QUERYMENU)]      = "VIDIOC_QUERYMENU",
+	[_IOC_NR(VIDIOC_G_INPUT)]        = "VIDIOC_G_INPUT",
+	[_IOC_NR(VIDIOC_S_INPUT)]        = "VIDIOC_S_INPUT",
+	[_IOC_NR(VIDIOC_G_OUTPUT)]       = "VIDIOC_G_OUTPUT",
+	[_IOC_NR(VIDIOC_S_OUTPUT)]       = "VIDIOC_S_OUTPUT",
+	[_IOC_NR(VIDIOC_ENUMOUTPUT)]     = "VIDIOC_ENUMOUTPUT",
+	[_IOC_NR(VIDIOC_G_AUDOUT)]       = "VIDIOC_G_AUDOUT",
+	[_IOC_NR(VIDIOC_S_AUDOUT)]       = "VIDIOC_S_AUDOUT",
+	[_IOC_NR(VIDIOC_G_MODULATOR)]    = "VIDIOC_G_MODULATOR",
+	[_IOC_NR(VIDIOC_S_MODULATOR)]    = "VIDIOC_S_MODULATOR",
+	[_IOC_NR(VIDIOC_G_FREQUENCY)]    = "VIDIOC_G_FREQUENCY",
+	[_IOC_NR(VIDIOC_S_FREQUENCY)]    = "VIDIOC_S_FREQUENCY",
+	[_IOC_NR(VIDIOC_CROPCAP)]        = "VIDIOC_CROPCAP",
+	[_IOC_NR(VIDIOC_G_CROP)]         = "VIDIOC_G_CROP",
+	[_IOC_NR(VIDIOC_S_CROP)]         = "VIDIOC_S_CROP",
+	[_IOC_NR(VIDIOC_G_JPEGCOMP)]     = "VIDIOC_G_JPEGCOMP",
+	[_IOC_NR(VIDIOC_S_JPEGCOMP)]     = "VIDIOC_S_JPEGCOMP",
+	[_IOC_NR(VIDIOC_QUERYSTD)]       = "VIDIOC_QUERYSTD",
+	[_IOC_NR(VIDIOC_TRY_FMT)]        = "VIDIOC_TRY_FMT",
+};
+
+/* ----------------------------------------------------------------- */
+
+EXPORT_SYMBOL(v4l2_video_std_fps);
+EXPORT_SYMBOL(v4l2_video_std_construct);
+
+EXPORT_SYMBOL(v4l2_field_names);
+EXPORT_SYMBOL(v4l2_type_names);
+EXPORT_SYMBOL(v4l2_ioctl_names);
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff -Nru a/drivers/media/video/video-buf.c b/drivers/media/video/video-buf.c
--- a/drivers/media/video/video-buf.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/media/video/video-buf.c	Mon Nov  4 14:31:01 2002
@@ -26,6 +26,11 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 
+#ifndef TryLockPage
+# include "linux/page-flags.h"
+# define TryLockPage TestSetPageLocked
+#endif
+
 #include "video-buf.h"
 
 static int debug = 0;
@@ -65,12 +70,12 @@
 	return NULL;
 }
 
-struct scatterlist *
+struct scatterlist*
 videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
 {
 	struct scatterlist *sglist;
 	int i = 0;
-	
+
 	if (NULL == pages[0])
 		return NULL;
 	sglist = kmalloc(sizeof(*sglist) * nr_pages, GFP_KERNEL);
@@ -80,21 +85,27 @@
 
 	if (PageHighMem(pages[0]))
 		/* DMA to highmem pages might not work */
-		goto err;
+		goto highmem;
 	sglist[0].page   = pages[0];
 	sglist[0].offset = offset;
 	sglist[0].length = PAGE_SIZE - offset;
 	for (i = 1; i < nr_pages; i++) {
 		if (NULL == pages[i])
-			goto err;
+			goto nopage;
 		if (PageHighMem(pages[i]))
-			goto err;
+			goto highmem;
 		sglist[i].page   = pages[i];
 		sglist[i].length = PAGE_SIZE;
 	}
 	return sglist;
 
- err:
+ nopage:
+	dprintk(2,"sgl: oops - no page\n");
+	kfree(sglist);
+	return NULL;
+
+ highmem:
+	dprintk(2,"sgl: oops - highmem page\n");
 	kfree(sglist);
 	return NULL;
 }
@@ -103,14 +114,18 @@
 {
 	int i;
 
+	dprintk(2,"lock start ...\n");
 	for (i = 0; i < nr_pages; i++)
-		if (TestSetPageLocked(pages[i]))
+		if (TryLockPage(pages[i]))
 			goto err;
+	dprintk(2,"lock ok\n");
 	return 0;
 
  err:
+	dprintk(2,"lock failed, unlock ...\n");
 	while (i > 0)
 		unlock_page(pages[--i]);
+	dprintk(2,"lock quit\n");
 	return -EINVAL;
 }
 
@@ -118,8 +133,10 @@
 {
 	int i;
 
+	dprintk(2,"unlock start ...\n");
 	for (i = 0; i < nr_pages; i++)
 		unlock_page(pages[i]);
+	dprintk(2,"unlock ok\n");
 	return 0;
 }
 
@@ -128,6 +145,7 @@
 int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction,
 			   unsigned long data, unsigned long size)
 {
+	unsigned long first,last;
 	int err, rw = 0;
 
 	dma->direction = direction;
@@ -137,25 +155,35 @@
 	default:                 BUG();
 	}
 
-	dma->offset   = data & PAGE_MASK;
-	dma->nr_pages = ((((data+size) & ~PAGE_MASK) -
-			  (data & ~PAGE_MASK)) >> PAGE_SHIFT) +1;
-	dma->pages    = kmalloc(dma->nr_pages * sizeof(struct page*),
-				GFP_KERNEL);
+	first = (data          & PAGE_MASK) >> PAGE_SHIFT;
+	last  = ((data+size-1) & PAGE_MASK) >> PAGE_SHIFT;
+	dma->offset   = data & ~PAGE_MASK;
+	dma->nr_pages = last-first+1;
+	dma->pages = kmalloc(dma->nr_pages * sizeof(struct page*),
+			     GFP_KERNEL);
 	if (NULL == dma->pages)
 		return -ENOMEM;
+	dprintk(1,"init user [0x%lx+0x%lx => %d pages]\n",
+		data,size,dma->nr_pages);
+
 	down_read(&current->mm->mmap_sem);
         err = get_user_pages(current,current->mm,
-			     data, dma->nr_pages,
-			     rw == READ, 0, /* don't force */
+			     data & PAGE_MASK, dma->nr_pages,
+			     rw == READ, 1, /* force */
 			     dma->pages, NULL);
 	up_read(&current->mm->mmap_sem);
-	return err;
+	if (err != dma->nr_pages) {
+		dma->nr_pages = (err >= 0) ? err : 0;
+		dprintk(1,"get_user_pages: err=%d [%d]\n",err,dma->nr_pages);
+		return err < 0 ? err : -EINVAL;
+	}
+	return 0;
 }
 
 int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction,
 			     int nr_pages)
 {
+	dprintk(1,"init kernel [%d pages]\n",nr_pages);
 	dma->direction = direction;
 	dma->vmalloc = vmalloc_32(nr_pages << PAGE_SHIFT);
 	if (NULL == dma->vmalloc) {
@@ -176,13 +204,14 @@
 	
 	if (dma->pages) {
 		if (0 != (err = videobuf_lock(dma->pages, dma->nr_pages))) {
-			dprintk(1,"videobuf_lock_pages: %d\n",err);
+			dprintk(1,"videobuf_lock: %d\n",err);
 			return err;
 		}
 		dma->sglist = videobuf_pages_to_sg(dma->pages, dma->nr_pages,
 						   dma->offset);
+		if (NULL == dma->sglist)
+			videobuf_unlock(dma->pages, dma->nr_pages);
 	}
-
 	if (dma->vmalloc) {
 		dma->sglist = videobuf_vmalloc_to_sg
 			(dma->vmalloc,dma->nr_pages);
@@ -215,7 +244,7 @@
 	dma->sglist = NULL;
 	dma->sglen = 0;
 	if (dma->pages)
-		videobuf_lock(dma->pages, dma->nr_pages);
+		videobuf_unlock(dma->pages, dma->nr_pages);
 	return 0;
 }
 
@@ -231,7 +260,6 @@
 		kfree(dma->pages);
 		dma->pages = NULL;
 	}
-
 	if (dma->vmalloc) {
 		vfree(dma->vmalloc);
 		dma->vmalloc = NULL;
@@ -286,16 +314,12 @@
 	if (0 == vb->baddr) {
 		/* no userspace addr -- kernel bounce buffer */
 		pages = PAGE_ALIGN(vb->size) >> PAGE_SHIFT;
-		dprintk(1,"kernel buf size=%ld (%d pages)\n",
-			vb->size,pages);
 		err = videobuf_dma_init_kernel(&vb->dma,PCI_DMA_FROMDEVICE,
 					       pages);
 		if (0 != err)
 			return err;
 	} else {
 		/* dma directly to userspace */
-		dprintk(1,"user buf addr=%08lx size=%ld\n",
-			vb->baddr,vb->bsize);
 		err = videobuf_dma_init_user(&vb->dma,PCI_DMA_FROMDEVICE,
 					     vb->baddr,vb->bsize);
 		if (0 != err)
@@ -314,7 +338,7 @@
 		    struct videobuf_queue_ops *ops,
 		    struct pci_dev *pci,
 		    spinlock_t *irqlock,
-		    int type,
+		    enum v4l2_buf_type type,
 		    int msize)
 {
 	memset(q,0,sizeof(*q));
@@ -329,6 +353,30 @@
 	INIT_LIST_HEAD(&q->stream);
 }
 
+int 
+videobuf_queue_is_busy(struct videobuf_queue *q)
+{
+	int i;
+	
+	if (q->reading)
+		return 1;
+	if (q->streaming)
+		return 1;
+	if (q->read_buf)
+		return 1;
+	for (i = 0; i < VIDEO_MAX_FRAME; i++) {
+		if (NULL == q->bufs[i])
+			continue;
+		if (q->bufs[i]->map)
+			return 1;
+		if (q->bufs[i]->state == STATE_QUEUED)
+			return 1;
+		if (q->bufs[i]->state == STATE_ACTIVE)
+			return 1;
+	}
+	return 0;
+}
+
 void
 videobuf_queue_cancel(struct file *file, struct videobuf_queue *q)
 {
@@ -358,15 +406,15 @@
 
 /* --------------------------------------------------------------------- */
 
-#ifdef HAVE_V4L2
 void
-videobuf_status(struct v4l2_buffer *b, struct videobuf_buffer *vb, int type)
+videobuf_status(struct v4l2_buffer *b, struct videobuf_buffer *vb,
+		enum v4l2_buf_type type)
 {
-	b->index  = vb->i;
-	b->type   = type;
-	b->offset = vb->boff;
-	b->length = vb->bsize;
-	b->flags  = 0;
+	b->index    = vb->i;
+	b->type     = type;
+	b->m.offset = vb->boff;
+	b->length   = vb->bsize;
+	b->flags    = 0;
 	if (vb->map)
 		b->flags |= V4L2_BUF_FLAG_MAPPED;
 	switch (vb->state) {
@@ -384,12 +432,7 @@
 		/* nothing */
 		break;
 	}
-	if (!(vb->field & VBUF_FIELD_INTER)) {
-		if (vb->field & VBUF_FIELD_ODD)
-			b->flags |= V4L2_BUF_FLAG_TOPFIELD;
-		if (vb->field & VBUF_FIELD_EVEN)
-			b->flags |= V4L2_BUF_FLAG_BOTFIELD;
-	}
+	b->field     = vb->field;
 	b->timestamp = vb->ts;
 	b->bytesused = vb->size;
 	b->sequence  = vb->field_count >> 1;
@@ -401,7 +444,7 @@
 {
 	int size,count,retval;
 
-	if ((req->type & V4L2_BUF_TYPE_field) != q->type)
+	if (req->type != q->type)
 		return -EINVAL;
 	if (req->count < 1)
 		return -EINVAL;
@@ -428,11 +471,11 @@
 int
 videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b)
 {
-	if ((b->type & V4L2_BUF_TYPE_field) != q->type)
+	if (unlikely(b->type != q->type))
 		return -EINVAL;
-	if (b->index < 0 || b->index >= VIDEO_MAX_FRAME)
+	if (unlikely(b->index < 0 || b->index >= VIDEO_MAX_FRAME))
 		return -EINVAL;
-	if (NULL == q->bufs[b->index])
+	if (unlikely(NULL == q->bufs[b->index]))
 		return -EINVAL;
 	videobuf_status(b,q->bufs[b->index],q->type);
 	return 0;
@@ -444,7 +487,6 @@
 {
 	struct videobuf_buffer *buf;
 	unsigned long flags;
-	int field = 0;
 	int retval;
 
 	down(&q->lock);
@@ -452,7 +494,7 @@
 	if (q->reading)
 		goto done;
 	retval = -EINVAL;
-	if ((b->type & V4L2_BUF_TYPE_field) != q->type)
+	if (b->type != q->type)
 		goto done;
 	if (b->index < 0 || b->index >= VIDEO_MAX_FRAME)
 		goto done;
@@ -465,11 +507,7 @@
 	    buf->state == STATE_ACTIVE)
 		goto done;
 
-	if (b->flags & V4L2_BUF_FLAG_TOPFIELD)
-		field |= VBUF_FIELD_ODD;
-	if (b->flags & V4L2_BUF_FLAG_BOTFIELD)
-		field |= VBUF_FIELD_EVEN;
-	retval = q->ops->buf_prepare(file,buf,field);
+	retval = q->ops->buf_prepare(file,buf);
 	if (0 != retval)
 		goto done;
 	
@@ -498,7 +536,7 @@
 	if (q->reading)
 		goto done;
 	retval = -EINVAL;
-	if ((b->type & V4L2_BUF_TYPE_field) != q->type)
+	if (b->type != q->type)
 		goto done;
 	if (list_empty(&q->stream))
 		goto done;
@@ -526,7 +564,6 @@
 	up(&q->lock);
 	return retval;
 }
-#endif /* HAVE_V4L2 */
 
 int videobuf_streamon(struct file *file, struct videobuf_queue *q)
 {
@@ -586,7 +623,7 @@
 
 	q->read_buf->baddr = (unsigned long)data;
         q->read_buf->bsize = count;
-	retval = q->ops->buf_prepare(file,q->read_buf,0);
+	retval = q->ops->buf_prepare(file,q->read_buf);
 	if (0 != retval)
 		goto done;
 	
@@ -631,7 +668,7 @@
 		q->read_buf = videobuf_alloc(q->msize);
 		if (NULL == q->read_buf)
 			goto done;
-		retval = q->ops->buf_prepare(file,q->read_buf,0);
+		retval = q->ops->buf_prepare(file,q->read_buf);
 		if (0 != retval)
 			goto done;
 		q->ops->buf_queue(file,q->read_buf);
@@ -683,7 +720,7 @@
 	if (err)
 		return err;
 	for (i = 0; i < count; i++) {
-		err = q->ops->buf_prepare(file,q->bufs[i],0);
+		err = q->ops->buf_prepare(file,q->bufs[i]);
 		if (err)
 			return err;
 		list_add_tail(&q->bufs[i]->stream, &q->stream);
@@ -1008,6 +1045,8 @@
 /* --------------------------------------------------------------------- */
 
 EXPORT_SYMBOL_GPL(videobuf_vmalloc_to_sg);
+EXPORT_SYMBOL_GPL(videobuf_lock);
+EXPORT_SYMBOL_GPL(videobuf_unlock);
 
 EXPORT_SYMBOL_GPL(videobuf_dma_init_user);
 EXPORT_SYMBOL_GPL(videobuf_dma_init_kernel);
@@ -1022,14 +1061,13 @@
 
 EXPORT_SYMBOL_GPL(videobuf_queue_init);
 EXPORT_SYMBOL_GPL(videobuf_queue_cancel);
+EXPORT_SYMBOL_GPL(videobuf_queue_is_busy);
 
-#ifdef HAVE_V4L2
 EXPORT_SYMBOL_GPL(videobuf_status);
 EXPORT_SYMBOL_GPL(videobuf_reqbufs);
 EXPORT_SYMBOL_GPL(videobuf_querybuf);
 EXPORT_SYMBOL_GPL(videobuf_qbuf);
 EXPORT_SYMBOL_GPL(videobuf_dqbuf);
-#endif
 EXPORT_SYMBOL_GPL(videobuf_streamon);
 EXPORT_SYMBOL_GPL(videobuf_streamoff);
 
diff -Nru a/drivers/media/video/video-buf.h b/drivers/media/video/video-buf.h
--- a/drivers/media/video/video-buf.h	Mon Nov  4 14:31:02 2002
+++ b/drivers/media/video/video-buf.h	Mon Nov  4 14:31:02 2002
@@ -28,12 +28,14 @@
 struct scatterlist* videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages);
 
 /*
- * Return a scatterlist for a an array of userpages (NULL on errors).  Memory
- * for the scatterlist is allocated using kmalloc.  The caller must
- * free the memory.
+ * Return a scatterlist for a an array of userpages (NULL on errors).
+ * Memory for the scatterlist is allocated using kmalloc.  The caller
+ * must free the memory.
  */
-struct scatterlist *videobuf_pages_to_sg(struct page **pages, int nr_pages,
+struct scatterlist* videobuf_pages_to_sg(struct page **pages, int nr_pages,
 					 int offset);
+int videobuf_lock(struct page **pages, int nr_pages);
+int videobuf_unlock(struct page **pages, int nr_pages);
 
 /* --------------------------------------------------------------------- */
 
@@ -58,8 +60,8 @@
 
 struct videobuf_dmabuf {
 	/* for userland buffer */
-	struct page         **pages;
 	int                 offset;
+	struct page         **pages;
 
 	/* for kernel buffers */
 	void                *vmalloc;
@@ -115,10 +117,6 @@
 	struct videobuf_queue *q;
 };
 
-#define VBUF_FIELD_EVEN  1
-#define VBUF_FIELD_ODD   2
-#define VBUF_FIELD_INTER 4
-
 enum videobuf_state {
 	STATE_NEEDS_INIT = 0,
 	STATE_PREPARED   = 1,
@@ -136,30 +134,27 @@
 	int                     width;
 	int                     height;
 	long                    size;
-	int                     field;
+	enum v4l2_field         field;
 	enum videobuf_state     state;
 	struct videobuf_dmabuf  dma;
 	struct list_head        stream;  /* QBUF/DQBUF list */
 
 	/* for mmap'ed buffers */
-	unsigned long  boff;             /* buffer offset (mmap) */
-	unsigned long  bsize;            /* buffer size */
-	unsigned long  baddr;            /* buffer addr (userland ptr!) */
+	off_t                   boff;    /* buffer offset (mmap) */
+	size_t                  bsize;   /* buffer size */
+	unsigned long           baddr;   /* buffer addr (userland ptr!) */
 	struct videobuf_mapping *map;
 
 	/* touched by irq handler */
 	struct list_head        queue;
 	wait_queue_head_t       done;
 	int                     field_count;
-#ifdef HAVE_V4L2
-	stamp_t                 ts;
-#endif
+	struct timeval          ts;
 };
 
 struct videobuf_queue_ops {
 	int (*buf_setup)(struct file *file, int *count, int *size);
-	int (*buf_prepare)(struct file *file,struct videobuf_buffer *vb,
-			   int field);
+	int (*buf_prepare)(struct file *file,struct videobuf_buffer *vb);
 	void (*buf_queue)(struct file *file,struct videobuf_buffer *vb);
 	void (*buf_release)(struct file *file,struct videobuf_buffer *vb);
 };
@@ -169,7 +164,7 @@
 	spinlock_t                 *irqlock;
 	struct pci_dev             *pci;
 
-	int                        type;
+	enum v4l2_buf_type         type;
 	int                        msize;
 	struct videobuf_buffer     *bufs[VIDEO_MAX_FRAME];
 	struct videobuf_queue_ops  *ops;
@@ -191,12 +186,12 @@
 void videobuf_queue_init(struct videobuf_queue *q,
 			 struct videobuf_queue_ops *ops,
 			 struct pci_dev *pci, spinlock_t *irqlock,
-			 int type, int msize);
+			 enum v4l2_buf_type type, int msize);
+int  videobuf_queue_is_busy(struct videobuf_queue *q);
 void videobuf_queue_cancel(struct file *file, struct videobuf_queue *q);
 
-#ifdef HAVE_V4L2
 void videobuf_status(struct v4l2_buffer *b, struct videobuf_buffer *vb,
-		     int type);
+		     enum v4l2_buf_type type);
 int videobuf_reqbufs(struct file *file, struct videobuf_queue *q,
 		     struct v4l2_requestbuffers *req);
 int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b);
@@ -204,7 +199,6 @@
 		  struct v4l2_buffer *b);
 int videobuf_dqbuf(struct file *file, struct videobuf_queue *q,
 		   struct v4l2_buffer *b);
-#endif
 int videobuf_streamon(struct file *file, struct videobuf_queue *q);
 int videobuf_streamoff(struct file *file, struct videobuf_queue *q);
 
diff -Nru a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
--- a/drivers/mtd/maps/Kconfig	Mon Nov  4 14:31:02 2002
+++ b/drivers/mtd/maps/Kconfig	Mon Nov  4 14:31:02 2002
@@ -346,5 +346,11 @@
 	  cards are usually around 4-16MiB in size. This does not include
 	  Compact Flash cards which are treated as IDE devices.
 
+config MTD_UCLINUX
+	tristate "Generic uClinux RAM/ROM filesystem support"
+	depends on MTD_PARTITIONS
+	help
+	  Map driver to support image based filesystems for uClinux.
+
 endmenu
 
diff -Nru a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
--- a/drivers/mtd/maps/Makefile	Mon Nov  4 14:31:00 2002
+++ b/drivers/mtd/maps/Makefile	Mon Nov  4 14:31:00 2002
@@ -30,6 +30,7 @@
 obj-$(CONFIG_MTD_SCx200_DOCFLASH)+= scx200_docflash.o
 obj-$(CONFIG_MTD_DBOX2)		+= dbox2-flash.o
 obj-$(CONFIG_MTD_OCELOT)	+= ocelot.o
+obj-$(CONFIG_MTD_UCLINUX)	+= uclinux.o
 obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
 obj-$(CONFIG_MTD_PCI)		+= pci.o
 obj-$(CONFIG_MTD_AUTCPU12)	+= autcpu12-nvram.o
diff -Nru a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/mtd/maps/uclinux.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,171 @@
+/****************************************************************************/
+
+/*
+ *	uclinux.c -- generic memory mapped MTD driver for uclinux
+ *
+ *	(C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/major.h>
+#include <linux/root_dev.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <asm/io.h>
+
+/****************************************************************************/
+
+__u8 uclinux_read8(struct map_info *map, unsigned long ofs)
+{
+	return(*((__u8 *) (map->map_priv_1 + ofs)));
+}
+
+__u16 uclinux_read16(struct map_info *map, unsigned long ofs)
+{
+	return(*((__u16 *) (map->map_priv_1 + ofs)));
+}
+
+__u32 uclinux_read32(struct map_info *map, unsigned long ofs)
+{
+	return(*((__u32 *) (map->map_priv_1 + ofs)));
+}
+
+void uclinux_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy(to, (void *)(map->map_priv_1 + from), len);
+}
+
+void uclinux_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	*((__u8 *) (map->map_priv_1 + adr)) = d;
+}
+
+void uclinux_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	*((__u16 *) (map->map_priv_1 + adr)) = d;
+}
+
+void uclinux_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	*((__u32 *) (map->map_priv_1 + adr)) = d;
+}
+
+void uclinux_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy((void *) (map->map_priv_1 + to), from, len);
+}
+
+/****************************************************************************/
+
+struct map_info uclinux_ram_map = {
+	name:		"RAM",
+	read8:		uclinux_read8,
+	read16:		uclinux_read16,
+	read32:		uclinux_read32,
+	copy_from:	uclinux_copy_from,
+	write8:		uclinux_write8,
+	write16:	uclinux_write16,
+	write32:	uclinux_write32,
+	copy_to:	uclinux_copy_to,
+};
+
+struct mtd_info *uclinux_ram_mtdinfo;
+
+/****************************************************************************/
+
+struct mtd_partition uclinux_romfs[] = {
+	{ name: "ROMfs", offset: 0 }
+};
+
+#define	NUM_PARTITIONS	(sizeof(uclinux_romfs) / sizeof(uclinux_romfs[0]))
+
+/****************************************************************************/
+
+int uclinux_point(struct mtd_info *mtd, loff_t from, size_t len,
+	size_t *retlen, u_char **mtdbuf)
+{
+	struct map_info *map = (struct map_info *) mtd->priv;
+	*mtdbuf = (u_char *) (map->map_priv_1 + ((int) from));
+	*retlen = len;
+	return(0);
+}
+
+/****************************************************************************/
+
+int __init uclinux_mtd_init(void)
+{
+	struct mtd_info *mtd;
+	struct map_info *mapp;
+	extern char _ebss;
+
+	mapp = &uclinux_ram_map;
+	mapp->map_priv_2 = (unsigned long) &_ebss;
+	mapp->size = PAGE_ALIGN(*((unsigned long *)((&_ebss) + 8)));
+	mapp->buswidth = 4;
+
+	printk("uclinux[mtd]: RAM probe address=0x%x size=0x%x\n",
+	       	(int) mapp->map_priv_2, (int) mapp->size);
+
+	mapp->map_priv_1 = (unsigned long)
+		ioremap_nocache(mapp->map_priv_2, mapp->size);
+
+	if (mapp->map_priv_1 == 0) {
+		printk("uclinux[mtd]: ioremap_nocache() failed\n");
+		return(-EIO);
+	}
+
+	mtd = do_map_probe("map_ram", mapp);
+	if (!mtd) {
+		printk("uclinux[mtd]: failed to find a mapping?\n");
+		iounmap((void *) mapp->map_priv_1);
+		return(-ENXIO);
+	}
+		
+	mtd->module = THIS_MODULE;
+	mtd->point = uclinux_point;
+	mtd->priv = mapp;
+
+	uclinux_ram_mtdinfo = mtd;
+	add_mtd_partitions(mtd, uclinux_romfs, NUM_PARTITIONS);
+
+	printk("uclinux[mtd]: set %s to be root filesystem\n",
+		uclinux_romfs[0].name);
+	ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, 0);
+	put_mtd_device(mtd);
+
+	return(0);
+}
+
+/****************************************************************************/
+
+void __exit uclinux_mtd_cleanup(void)
+{
+	if (uclinux_ram_mtdinfo) {
+		del_mtd_partitions(uclinux_ram_mtdinfo);
+		map_destroy(uclinux_ram_mtdinfo);
+		uclinux_ram_mtdinfo = NULL;
+	}
+	if (uclinux_ram_map.map_priv_1) {
+		iounmap((void *) uclinux_ram_map.map_priv_1);
+		uclinux_ram_map.map_priv_1 = 0;
+	}
+}
+
+/****************************************************************************/
+
+module_init(uclinux_mtd_init);
+module_exit(uclinux_mtd_cleanup);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com>");
+MODULE_DESCRIPTION("Generic RAM based MTD for uClinux");
+
+/****************************************************************************/
diff -Nru a/drivers/net/3c509.c b/drivers/net/3c509.c
--- a/drivers/net/3c509.c	Mon Nov  4 14:31:00 2002
+++ b/drivers/net/3c509.c	Mon Nov  4 14:31:00 2002
@@ -51,11 +51,13 @@
 			- Full duplex support
 		v1.19  16Oct2002 Zwane Mwaikambo <zwane@linuxpower.ca>
 			- Additional ethtool features
+		v1.19a 28Oct2002 Davud Ruggiero <jdr@farfalle.com>
+			- Increase *read_eeprom udelay to workaround oops with 2 cards.
 */
 
 #define DRV_NAME	"3c509"
-#define DRV_VERSION	"1.19"
-#define DRV_RELDATE	"16Oct2002"
+#define DRV_VERSION	"1.19a"
+#define DRV_RELDATE	"28Oct2002"
 
 /* A few values that may be tweaked. */
 
@@ -570,8 +572,9 @@
 static ushort read_eeprom(int ioaddr, int index)
 {
 	outw(EEPROM_READ + index, ioaddr + 10);
-	/* Pause for at least 162 us. for the read to take place. */
-	udelay (500);
+	/* Pause for at least 162 us. for the read to take place. 
+	   Some chips seem to require much longer */
+	mdelay(2);
 	return inw(ioaddr + 12);
 }
 
@@ -585,7 +588,8 @@
 	outb(EEPROM_READ + index, id_port);
 
 	/* Pause for at least 162 us. for the read to take place. */
-	udelay (500);
+	/* Some chips seem to require much longer */
+	mdelay(4);
 	
 	for (bit = 15; bit >= 0; bit--)
 		word = (word << 1) + (inb(id_port) & 0x01);
diff -Nru a/drivers/net/68360enet.c b/drivers/net/68360enet.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/net/68360enet.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,953 @@
+/*
+ * Ethernet driver for Motorola MPC8xx.
+ * Copyright (c) 2000 Michael Leslie <mleslie@lineo.com>
+ * Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
+ *
+ * I copied the basic skeleton from the lance driver, because I did not
+ * know how to write the Linux driver, but I did know how the LANCE worked.
+ *
+ * This version of the driver is somewhat selectable for the different
+ * processor/board combinations.  It works for the boards I know about
+ * now, and should be easily modified to include others.  Some of the
+ * configuration information is contained in "commproc.h" and the
+ * remainder is here.
+ *
+ * Buffer descriptors are kept in the CPM dual port RAM, and the frame
+ * buffers are in the host memory.
+ *
+ * Right now, I am very watseful with the buffers.  I allocate memory
+ * pages and then divide them into 2K frame buffers.  This way I know I
+ * have buffers large enough to hold one frame within one buffer descriptor.
+ * Once I get this working, I will use 64 or 128 byte CPM buffers, which
+ * will be much more memory efficient and will easily handle lots of
+ * small packets.
+ *
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h> 
+#include <asm/irq.h>
+#include <asm/m68360.h>
+/* #include <asm/8xx_immap.h> */
+/* #include <asm/pgtable.h> */
+/* #include <asm/mpc8xx.h> */
+#include <asm/bitops.h>
+/* #include <asm/uaccess.h> */
+#include <asm/commproc.h>
+
+
+/*
+ *				Theory of Operation
+ *
+ * The MPC8xx CPM performs the Ethernet processing on SCC1.  It can use
+ * an aribtrary number of buffers on byte boundaries, but must have at
+ * least two receive buffers to prevent constant overrun conditions.
+ *
+ * The buffer descriptors are allocated from the CPM dual port memory
+ * with the data buffers allocated from host memory, just like all other
+ * serial communication protocols.  The host memory buffers are allocated
+ * from the free page pool, and then divided into smaller receive and
+ * transmit buffers.  The size of the buffers should be a power of two,
+ * since that nicely divides the page.  This creates a ring buffer
+ * structure similar to the LANCE and other controllers.
+ *
+ * Like the LANCE driver:
+ * The driver runs as two independent, single-threaded flows of control.  One
+ * is the send-packet routine, which enforces single-threaded use by the
+ * cep->tx_busy flag.  The other thread is the interrupt handler, which is
+ * single threaded by the hardware and other software.
+ *
+ * The send packet thread has partial control over the Tx ring and the
+ * 'cep->tx_busy' flag.  It sets the tx_busy flag whenever it's queuing a Tx
+ * packet. If the next queue slot is empty, it clears the tx_busy flag when
+ * finished otherwise it sets the 'lp->tx_full' flag.
+ *
+ * The MBX has a control register external to the MPC8xx that has some
+ * control of the Ethernet interface.  Information is in the manual for
+ * your board.
+ *
+ * The RPX boards have an external control/status register.  Consult the
+ * programming documents for details unique to your board.
+ *
+ * For the TQM8xx(L) modules, there is no control register interface.
+ * All functions are directly controlled using I/O pins.  See commproc.h.
+ */
+
+
+/* The transmitter timeout
+ */
+#define TX_TIMEOUT	(2*HZ)
+
+/* The number of Tx and Rx buffers.  These are allocated statically here.
+ * We don't need to allocate pages for the transmitter.  We just use
+ * the skbuffer directly.
+ */
+#ifdef CONFIG_ENET_BIG_BUFFERS
+#define RX_RING_SIZE		64
+#define TX_RING_SIZE		64	/* Must be power of two */
+#define TX_RING_MOD_MASK	63	/*   for this to work */
+#else
+#define RX_RING_SIZE		8
+#define TX_RING_SIZE		8	/* Must be power of two */
+#define TX_RING_MOD_MASK	7	/*   for this to work */
+#endif
+
+#define CPM_ENET_RX_FRSIZE  2048 /* overkill left over from ppc page-based allocation */
+static char rx_buf_pool[RX_RING_SIZE * CPM_ENET_RX_FRSIZE];
+
+
+/* The CPM stores dest/src/type, data, and checksum for receive packets.
+ */
+#define PKT_MAXBUF_SIZE		1518
+#define PKT_MINBUF_SIZE		64
+#define PKT_MAXBLR_SIZE		1520
+
+/* The CPM buffer descriptors track the ring buffers.  The rx_bd_base and
+ * tx_bd_base always point to the base of the buffer descriptors.  The
+ * cur_rx and cur_tx point to the currently available buffer.
+ * The dirty_tx tracks the current buffer that is being sent by the
+ * controller.  The cur_tx and dirty_tx are equal under both completely
+ * empty and completely full conditions.  The empty/ready indicator in
+ * the buffer descriptor determines the actual condition.
+ */
+struct scc_enet_private {
+	/* The saved address of a sent-in-place packet/buffer, for skfree(). */
+	struct	sk_buff* tx_skbuff[TX_RING_SIZE];
+	ushort	skb_cur;
+	ushort	skb_dirty;
+
+	/* CPM dual port RAM relative addresses.
+	*/
+	QUICC_BD	*rx_bd_base;		/* Address of Rx and Tx buffers. */
+	QUICC_BD	*tx_bd_base;
+	QUICC_BD	*cur_rx, *cur_tx;		/* The next free ring entry */
+	QUICC_BD	*dirty_tx;	/* The ring entries to be free()ed. */
+	volatile struct scc_regs	*sccp;
+	/* struct	net_device_stats stats; */
+	struct	net_device_stats stats;
+	uint	tx_full;
+	/* spinlock_t lock; */
+	volatile unsigned int lock;
+};
+
+
+
+static int scc_enet_open(struct net_device *dev);
+static int scc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static int scc_enet_rx(struct net_device *dev);
+/* static void scc_enet_interrupt(void *dev_id); */
+static void scc_enet_interrupt(int vec, void *dev_id, struct pt_regs *fp);
+static int scc_enet_close(struct net_device *dev);
+/* static struct net_device_stats *scc_enet_get_stats(struct net_device *dev); */
+static struct net_device_stats *scc_enet_get_stats(struct net_device *dev);
+static void set_multicast_list(struct net_device *dev);
+
+/* Get this from various configuration locations (depends on board).
+*/
+/*static	ushort	my_enet_addr[] = { 0x0800, 0x3e26, 0x1559 };*/
+
+/* Typically, 860(T) boards use SCC1 for Ethernet, and other 8xx boards
+ * use SCC2.  This is easily extended if necessary.
+ */
+
+#define CONFIG_SCC1_ENET /* by default */
+
+#ifdef CONFIG_SCC1_ENET
+#define CPM_CR_ENET CPM_CR_CH_SCC1
+#define PROFF_ENET	PROFF_SCC1
+#define SCC_ENET	0
+#define CPMVEC_ENET	CPMVEC_SCC1
+#endif
+
+#ifdef CONFIG_SCC2_ENET
+#define CPM_CR_ENET	CPM_CR_CH_SCC2
+#define PROFF_ENET	PROFF_SCC2
+#define SCC_ENET	1		/* Index, not number! */
+#define CPMVEC_ENET	CPMVEC_SCC2
+#endif
+
+static int
+scc_enet_open(struct net_device *dev)
+{
+
+	/* I should reset the ring buffers here, but I don't yet know
+	 * a simple way to do that.
+	 * mleslie: That's no biggie. Worth doing, too.
+	 */
+
+	/* netif_start_queue(dev); */
+	return 0;					/* Always succeed */
+}
+
+
+static int
+scc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct scc_enet_private *cep = (struct scc_enet_private *)dev->priv;
+	volatile QUICC_BD	*bdp;
+
+	/* Fill in a Tx ring entry */
+	bdp = cep->cur_tx;
+
+#ifndef final_version
+	if (bdp->status & BD_ENET_TX_READY) {
+		/* Ooops.  All transmit buffers are full.  Bail out.
+		 * This should not happen, since cep->tx_busy should be set.
+		 */
+		printk("%s: tx queue full!.\n", dev->name);
+		return 1;
+	}
+#endif
+
+	/* Clear all of the status flags.
+	 */
+	bdp->status &= ~BD_ENET_TX_STATS;
+
+	/* If the frame is short, tell CPM to pad it.
+	*/
+	if (skb->len <= ETH_ZLEN)
+		bdp->status |= BD_ENET_TX_PAD;
+	else
+		bdp->status &= ~BD_ENET_TX_PAD;
+
+	/* Set buffer length and buffer pointer.
+	*/
+	bdp->length = skb->len;
+	/* bdp->buf = __pa(skb->data); */
+	bdp->buf = skb->data;
+
+	/* Save skb pointer.
+	*/
+	cep->tx_skbuff[cep->skb_cur] = skb;
+
+	/* cep->stats.tx_bytes += skb->len; */ /* TODO: It would really be nice... */
+
+	cep->skb_cur = (cep->skb_cur+1) & TX_RING_MOD_MASK;
+	
+
+	/* Push the data cache so the CPM does not get stale memory
+	 * data.
+	 */
+/* 	flush_dcache_range((unsigned long)(skb->data), */
+/* 					(unsigned long)(skb->data + skb->len)); */
+
+	/* spin_lock_irq(&cep->lock); */ /* TODO: SPINLOCK */
+	local_irq_disable();
+	if (cep->lock > 0) {
+		printk ("scc_enet_start_xmit() lock == %d\n", cep->lock);
+	} else {
+		cep->lock++;
+	}
+
+	/* Send it on its way.  Tell CPM its ready, interrupt when done,
+	 * its the last BD of the frame, and to put the CRC on the end.
+	 */
+	bdp->status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR | BD_ENET_TX_LAST | BD_ENET_TX_TC);
+
+	dev->trans_start = jiffies;
+
+	/* If this was the last BD in the ring, start at the beginning again.
+	*/
+	if (bdp->status & BD_ENET_TX_WRAP)
+		bdp = cep->tx_bd_base;
+	else
+		bdp++;
+
+	if (bdp->status & BD_ENET_TX_READY) {
+		/* netif_stop_queue(dev); */
+		cep->tx_full = 1;
+	}
+
+	cep->cur_tx = (QUICC_BD *)bdp;
+
+	/* spin_unlock_irq(&cep->lock); */ /* TODO: SPINLOCK */
+	cep->lock--;
+	sti();
+
+	return 0;
+}
+
+#if 0
+static void
+scc_enet_timeout(struct net_device *dev)
+{
+	struct scc_enet_private *cep = (struct scc_enet_private *)dev->priv;
+
+	printk("%s: transmit timed out.\n", dev->name);
+	cep->stats.tx_errors++;
+#ifndef final_version
+	{
+		int	i;
+		QUICC_BD	*bdp;
+		printk(" Ring data dump: cur_tx %p%s cur_rx %p.\n",
+		       cep->cur_tx, cep->tx_full ? " (full)" : "",
+		       cep->cur_rx);
+		bdp = cep->tx_bd_base;
+		for (i = 0 ; i < TX_RING_SIZE; i++, bdp++)
+			printk("%04x %04x %08x\n",
+			       bdp->status,
+			       bdp->length,
+			       (int)(bdp->buf));
+		bdp = cep->rx_bd_base;
+		for (i = 0 ; i < RX_RING_SIZE; i++, bdp++)
+			printk("%04x %04x %08x\n",
+			       bdp->status,
+			       bdp->length,
+			       (int)(bdp->buf));
+	}
+#endif
+/* 	if (!cep->tx_full) */
+/* 		netif_wake_queue(dev); */
+}
+#endif
+
+/* The interrupt handler.
+ * This is called from the CPM handler, not the MPC core interrupt.
+ */
+/* static void scc_enet_interrupt(void *dev_id) */
+static void scc_enet_interrupt(int vec, void *dev_id, struct pt_regs *fp)
+{
+	struct	net_device *dev = (struct net_device *)dev_id;
+	volatile struct	scc_enet_private *cep;
+	volatile QUICC_BD	*bdp;
+	ushort	int_events;
+	int	must_restart;
+
+	cep = (struct scc_enet_private *)dev->priv;
+
+	/* Get the interrupt events that caused us to be here.
+	*/
+	int_events = cep->sccp->scc_scce;
+	cep->sccp->scc_scce = int_events;
+	must_restart = 0;
+
+	/* Handle receive event in its own function.
+	*/
+	if (int_events & SCCE_ENET_RXF)
+		scc_enet_rx(dev_id);
+
+	/* Check for a transmit error.  The manual is a little unclear
+	 * about this, so the debug code until I get it figured out.  It
+	 * appears that if TXE is set, then TXB is not set.  However,
+	 * if carrier sense is lost during frame transmission, the TXE
+	 * bit is set, "and continues the buffer transmission normally."
+	 * I don't know if "normally" implies TXB is set when the buffer
+	 * descriptor is closed.....trial and error :-).
+	 */
+
+	/* Transmit OK, or non-fatal error.  Update the buffer descriptors.
+	*/
+	if (int_events & (SCCE_ENET_TXE | SCCE_ENET_TXB)) {
+	    /* spin_lock(&cep->lock); */ /* TODO: SPINLOCK */
+		/* local_irq_disable(); */
+		if (cep->lock > 0) {
+			printk ("scc_enet_interrupt() lock == %d\n", cep->lock);
+		} else {
+			cep->lock++;
+		}
+
+	    bdp = cep->dirty_tx;
+	    while ((bdp->status&BD_ENET_TX_READY)==0) {
+		if ((bdp==cep->cur_tx) && (cep->tx_full == 0))
+		    break;
+
+		if (bdp->status & BD_ENET_TX_HB)	/* No heartbeat */
+			cep->stats.tx_heartbeat_errors++;
+		if (bdp->status & BD_ENET_TX_LC)	/* Late collision */
+			cep->stats.tx_window_errors++;
+		if (bdp->status & BD_ENET_TX_RL)	/* Retrans limit */
+			cep->stats.tx_aborted_errors++;
+		if (bdp->status & BD_ENET_TX_UN)	/* Underrun */
+			cep->stats.tx_fifo_errors++;
+		if (bdp->status & BD_ENET_TX_CSL)	/* Carrier lost */
+			cep->stats.tx_carrier_errors++;
+
+
+		/* No heartbeat or Lost carrier are not really bad errors.
+		 * The others require a restart transmit command.
+		 */
+		if (bdp->status &
+		    (BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN)) {
+			must_restart = 1;
+			cep->stats.tx_errors++;
+		}
+
+		cep->stats.tx_packets++;
+
+		/* Deferred means some collisions occurred during transmit,
+		 * but we eventually sent the packet OK.
+		 */
+		if (bdp->status & BD_ENET_TX_DEF)
+			cep->stats.collisions++;
+
+		/* Free the sk buffer associated with this last transmit.
+		*/
+		/* dev_kfree_skb_irq(cep->tx_skbuff[cep->skb_dirty]); */
+		dev_kfree_skb (cep->tx_skbuff[cep->skb_dirty]);
+		cep->skb_dirty = (cep->skb_dirty + 1) & TX_RING_MOD_MASK;
+
+		/* Update pointer to next buffer descriptor to be transmitted.
+		*/
+		if (bdp->status & BD_ENET_TX_WRAP)
+			bdp = cep->tx_bd_base;
+		else
+			bdp++;
+
+		/* I don't know if we can be held off from processing these
+		 * interrupts for more than one frame time.  I really hope
+		 * not.  In such a case, we would now want to check the
+		 * currently available BD (cur_tx) and determine if any
+		 * buffers between the dirty_tx and cur_tx have also been
+		 * sent.  We would want to process anything in between that
+		 * does not have BD_ENET_TX_READY set.
+		 */
+
+		/* Since we have freed up a buffer, the ring is no longer
+		 * full.
+		 */
+		if (cep->tx_full) {
+			cep->tx_full = 0;
+/* 			if (netif_queue_stopped(dev)) */
+/* 				netif_wake_queue(dev); */
+		}
+
+		cep->dirty_tx = (QUICC_BD *)bdp;
+	    }
+
+	    if (must_restart) {
+			volatile QUICC *cp;
+
+		/* Some transmit errors cause the transmitter to shut
+		 * down.  We now issue a restart transmit.  Since the
+		 * errors close the BD and update the pointers, the restart
+		 * _should_ pick up without having to reset any of our
+		 * pointers either.
+		 */
+		cp = pquicc;
+		cp->cp_cr =
+		    mk_cr_cmd(CPM_CR_ENET, CPM_CR_RESTART_TX) | CPM_CR_FLG;
+		while (cp->cp_cr & CPM_CR_FLG);
+	    }
+	    /* spin_unlock(&cep->lock); */ /* TODO: SPINLOCK */
+		/* sti(); */
+		cep->lock--;
+	}
+
+	/* Check for receive busy, i.e. packets coming but no place to
+	 * put them.  This "can't happen" because the receive interrupt
+	 * is tossing previous frames.
+	 */
+	if (int_events & SCCE_ENET_BSY) {
+		cep->stats.rx_dropped++;
+		printk("CPM ENET: BSY can't happen.\n");
+	}
+
+	return;
+}
+
+/* During a receive, the cur_rx points to the current incoming buffer.
+ * When we update through the ring, if the next incoming buffer has
+ * not been given to the system, we just set the empty indicator,
+ * effectively tossing the packet.
+ */
+static int
+scc_enet_rx(struct net_device *dev)
+{
+	struct	scc_enet_private *cep;
+	volatile QUICC_BD	*bdp;
+	struct	sk_buff *skb;
+	ushort	pkt_len;
+
+	cep = (struct scc_enet_private *)dev->priv;
+
+	/* First, grab all of the stats for the incoming packet.
+	 * These get messed up if we get called due to a busy condition.
+	 */
+	bdp = cep->cur_rx;
+
+	for (;;) {
+		if (bdp->status & BD_ENET_RX_EMPTY)
+			break;
+		
+#ifndef final_version
+		/* Since we have allocated space to hold a complete frame, both
+		 * the first and last indicators should be set.
+		 */
+		if ((bdp->status & (BD_ENET_RX_FIRST | BD_ENET_RX_LAST)) !=
+			(BD_ENET_RX_FIRST | BD_ENET_RX_LAST))
+			printk("CPM ENET: rcv is not first+last\n");
+#endif
+
+		/* Frame too long or too short.
+		 */
+		if (bdp->status & (BD_ENET_RX_LG | BD_ENET_RX_SH))
+			cep->stats.rx_length_errors++;
+		if (bdp->status & BD_ENET_RX_NO)	/* Frame alignment */
+			cep->stats.rx_frame_errors++;
+		if (bdp->status & BD_ENET_RX_CR)	/* CRC Error */
+			cep->stats.rx_crc_errors++;
+		if (bdp->status & BD_ENET_RX_OV)	/* FIFO overrun */
+			cep->stats.rx_crc_errors++;
+
+		/* Report late collisions as a frame error.
+		 * On this error, the BD is closed, but we don't know what we
+		 * have in the buffer.  So, just drop this frame on the floor.
+		 */
+		if (bdp->status & BD_ENET_RX_CL) {
+			cep->stats.rx_frame_errors++;
+		}
+		else {
+			
+			/* Process the incoming frame.
+			 */
+			cep->stats.rx_packets++;
+			pkt_len = bdp->length;
+			/* cep->stats.rx_bytes += pkt_len; */  /* TODO: It would really be nice... */
+
+			/* This does 16 byte alignment, much more than we need.
+			 * The packet length includes FCS, but we don't want to
+			 * include that when passing upstream as it messes up
+			 * bridging applications.
+			 */
+			skb = dev_alloc_skb(pkt_len-4);
+
+			if (skb == NULL) {
+				printk("%s: Memory squeeze, dropping packet.\n", dev->name);
+				cep->stats.rx_dropped++;
+			}
+			else {
+				skb->dev = dev;
+				skb_put(skb,pkt_len-4);	/* Make room */
+				eth_copy_and_sum(skb, (unsigned char *)bdp->buf, pkt_len-4, 0);
+				skb->protocol=eth_type_trans(skb,dev);
+				netif_rx(skb);
+			}
+		}
+
+		/* Clear the status flags for this buffer.
+		 */
+		bdp->status &= ~BD_ENET_RX_STATS;
+
+		/* Mark the buffer empty.
+		 */
+		bdp->status |= BD_ENET_RX_EMPTY;
+
+		/* Update BD pointer to next entry.
+		 */
+		if (bdp->status & BD_ENET_RX_WRAP)
+			bdp = cep->rx_bd_base;
+		else
+			bdp++;
+
+	}
+	cep->cur_rx = (QUICC_BD *)bdp;
+
+	return 0;
+}
+
+static int
+scc_enet_close(struct net_device *dev)
+{
+	/* Don't know what to do yet.
+	*/
+	/* netif_stop_queue(dev); */
+
+	return 0;
+}
+
+/* static struct net_device_stats *scc_enet_get_stats(struct net_device *dev) */
+static struct net_device_stats *scc_enet_get_stats(struct net_device *dev)
+{
+	struct scc_enet_private *cep = (struct scc_enet_private *)dev->priv;
+
+	return &cep->stats;
+}
+
+/* Set or clear the multicast filter for this adaptor.
+ * Skeleton taken from sunlance driver.
+ * The CPM Ethernet implementation allows Multicast as well as individual
+ * MAC address filtering.  Some of the drivers check to make sure it is
+ * a group multicast address, and discard those that are not.  I guess I
+ * will do the same for now, but just remove the test if you want
+ * individual filtering as well (do the upper net layers want or support
+ * this kind of feature?).
+ */
+
+static void set_multicast_list(struct net_device *dev)
+{
+	struct	scc_enet_private *cep;
+	struct	dev_mc_list *dmi;
+	u_char	*mcptr, *tdptr;
+	volatile scc_enet_t *ep;
+	int	i, j;
+	volatile QUICC *cp = pquicc;
+
+	cep = (struct scc_enet_private *)dev->priv;
+
+	/* Get pointer to SCC area in parameter RAM.
+	*/
+	ep = (scc_enet_t *)dev->base_addr;
+
+	if (dev->flags&IFF_PROMISC) {
+	  
+		/* Log any net taps. */
+		printk("%s: Promiscuous mode enabled.\n", dev->name);
+		cep->sccp->scc_psmr |= ETHER_PRO; 
+	} else {
+
+		cep->sccp->scc_psmr &= ~ETHER_PRO;
+
+		if (dev->flags & IFF_ALLMULTI) {
+			/* Catch all multicast addresses, so set the
+			 * filter to all 1's.
+			 */
+			ep->sen_gaddr1 = 0xffff;
+			ep->sen_gaddr2 = 0xffff;
+			ep->sen_gaddr3 = 0xffff;
+			ep->sen_gaddr4 = 0xffff;
+		}
+		else {
+			/* Clear filter and add the addresses in the list.
+			*/
+			ep->sen_gaddr1 = 0;
+			ep->sen_gaddr2 = 0;
+			ep->sen_gaddr3 = 0;
+			ep->sen_gaddr4 = 0;
+
+			dmi = dev->mc_list;
+
+			for (i=0; i<dev->mc_count; i++) {
+				
+				/* Only support group multicast for now.
+				*/
+				if (!(dmi->dmi_addr[0] & 1))
+					continue;
+
+				/* The address in dmi_addr is LSB first,
+				 * and taddr is MSB first.  We have to
+				 * copy bytes MSB first from dmi_addr.
+				 */
+				mcptr = (u_char *)dmi->dmi_addr + 5;
+				tdptr = (u_char *)&ep->sen_taddrh;
+				for (j=0; j<6; j++)
+					*tdptr++ = *mcptr--;
+
+				/* Ask CPM to run CRC and set bit in
+				 * filter mask.
+				 */
+				cp->cp_cr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_SET_GADDR) | CPM_CR_FLG;
+				/* this delay is necessary here -- Cort */
+				udelay(10);
+				while (cp->cp_cr & CPM_CR_FLG);
+			}
+		}
+	}
+}
+
+
+/* Initialize the CPM Ethernet on SCC.
+ */
+int scc_enet_init(void)
+{
+	struct net_device *dev;
+	struct scc_enet_private *cep;
+	int i, j;
+	unsigned char	*eap;
+	/* unsigned long	mem_addr; */
+	/* pte_t		*pte; */
+	/* bd_t		*bd; */ /* `board tag' used by ppc - TODO: integrate uC bootloader vars */
+	volatile	QUICC_BD	*bdp;
+	volatile	QUICC	*cp;
+	volatile struct scc_regs	*sccp;
+	volatile struct	ethernet_pram	*ep;
+	/* volatile	immap_t		*immap; */
+
+	cp = pquicc;	/* Get pointer to Communication Processor */
+
+	/* immap = (immap_t *)IMAP_ADDR; */	/* and to internal registers */
+
+	/* bd = (bd_t *)__res; */
+
+	/* Allocate some private information.
+	*/
+	cep = (struct scc_enet_private *)kmalloc(sizeof(*cep), GFP_KERNEL);
+	memset(cep, 0, sizeof(*cep));
+	/* __clear_user(cep,sizeof(*cep)); */
+	/* spin_lock_init(&cep->lock); */ /* TODO: SPINLOCK */
+
+	/* Create an Ethernet device instance.
+	 */
+	dev = init_etherdev(0, 0);
+
+	/* Get pointer to SCC area in parameter RAM.
+	*/
+	/* ep = (ethernet_pram *)(&cp->cp_dparam[PROFF_ENET]); */
+	ep = &pquicc->pram[SCC_ENET].enet_scc;
+
+	/* And another to the SCC register area.
+	*/
+	sccp = &pquicc->scc_regs[SCC_ENET];
+	cep->sccp = sccp;		/* Keep the pointer handy */
+
+	/* Disable receive and transmit in case EPPC-Bug started it.
+	*/
+	sccp->scc_gsmr.w.low &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+	/* Set up 360 pins for SCC interface to ethernet transceiver.
+	 * Pin mappings (PA_xx and PC_xx) are defined in commproc.h
+	 */
+
+	/* Configure port A pins for Txd and Rxd.
+	 */
+	pquicc->pio_papar |= (PA_ENET_RXD | PA_ENET_TXD);
+	pquicc->pio_padir &= ~(PA_ENET_RXD | PA_ENET_TXD);
+	pquicc->pio_paodr &= ~PA_ENET_TXD;
+
+	/* Configure port C pins to enable CLSN and RENA.
+	 */
+	pquicc->pio_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA);
+	pquicc->pio_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA);
+	pquicc->pio_pcso |= (PC_ENET_CLSN | PC_ENET_RENA);
+
+	/* Configure port A for TCLK and RCLK.
+	*/
+	pquicc->pio_papar |= (PA_ENET_TCLK | PA_ENET_RCLK);
+	pquicc->pio_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK);
+
+	/* Configure Serial Interface clock routing.
+	 * First, clear all SCC bits to zero, then set the ones we want.
+	 */
+	pquicc->si_sicr &= ~SICR_ENET_MASK;
+	pquicc->si_sicr |= SICR_ENET_CLKRT;
+
+
+	/* Allocate space for the buffer descriptors in the DP ram.
+	 * These are relative offsets in the DP ram address space.
+	 * Initialize base addresses for the buffer descriptors.
+	 */
+	i = m360_cpm_dpalloc(sizeof(QUICC_BD) * RX_RING_SIZE);
+	ep->rbase = i;
+	cep->rx_bd_base = (QUICC_BD *)((uint)pquicc + i);
+
+	i = m360_cpm_dpalloc(sizeof(QUICC_BD) * TX_RING_SIZE);
+	ep->tbase = i;
+	cep->tx_bd_base = (QUICC_BD *)((uint)pquicc + i);
+
+	cep->dirty_tx = cep->cur_tx = cep->tx_bd_base;
+	cep->cur_rx = cep->rx_bd_base;
+
+	/* Issue init Rx BD command for SCC.
+	 * Manual says to perform an Init Rx parameters here.  We have
+	 * to perform both Rx and Tx because the SCC may have been
+	 * already running. [In uCquicc's case, I don't think that is so - mles]
+	 * In addition, we have to do it later because we don't yet have
+	 * all of the BD control/status set properly.
+	cp->cp_cpcr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_INIT_RX) | CPM_CR_FLG;
+	while (cp->cp_cpcr & CPM_CR_FLG);
+	 */
+
+	/* Initialize function code registers for big-endian.
+	*/
+	ep->rfcr = (SCC_EB | SCC_FC_DMA);
+	ep->tfcr = (SCC_EB | SCC_FC_DMA);
+
+	/* Set maximum bytes per receive buffer.
+	 * This appears to be an Ethernet frame size, not the buffer
+	 * fragment size.  It must be a multiple of four.
+	 */
+	ep->mrblr  = PKT_MAXBLR_SIZE;
+
+	/* Set CRC preset and mask.
+	 */
+	ep->c_pres = 0xffffffff;
+	ep->c_mask = 0xdebb20e3; /* see 360UM p. 7-247 */
+
+	ep->crcec  = 0;	/* CRC Error counter */
+	ep->alec   = 0;	/* alignment error counter */
+	ep->disfc  = 0;	/* discard frame counter */
+
+	ep->pads   = 0x8888;	/* Tx short frame pad character */
+	ep->ret_lim = 0x000f;	/* Retry limit threshold */
+
+	ep->mflr   = PKT_MAXBUF_SIZE;	/* maximum frame length register */
+	ep->minflr = PKT_MINBUF_SIZE;	/* minimum frame length register */
+
+	ep->maxd1 = PKT_MAXBLR_SIZE;	/* maximum DMA1 length */
+	ep->maxd2 = PKT_MAXBLR_SIZE;	/* maximum DMA2 length */
+
+	/* Clear hash tables, group and individual.
+	 */
+	ep->gaddr1 = ep->gaddr2 = ep->gaddr3 = ep->gaddr4 = 0;
+	ep->iaddr1 = ep->iaddr2 = ep->iaddr3 = ep->iaddr4 = 0;
+
+	/* Set Ethernet station address.
+	 *
+	 * The uCbootloader provides a hook to the kernel to retrieve
+	 * stuff like the MAC address. This is retrieved in config_BSP()
+	 */
+#if defined (CONFIG_UCQUICC)
+	{
+ 		extern unsigned char *scc1_hwaddr;
+
+		eap = (char *)ep->paddr.b;
+		for (i=5; i>=0; i--)
+			*eap++ = dev->dev_addr[i] = scc1_hwaddr[i];
+	}
+#endif
+
+
+/* #ifndef CONFIG_MBX */
+/* 	eap = (unsigned char *)&(ep->paddrh); */
+
+/* 	for (i=5; i>=0; i--) */
+/* 		*eap++ = dev->dev_addr[i] = bd->bi_enetaddr[i]; */
+/* #else */
+/* 	for (i=5; i>=0; i--) */
+/* 		dev->dev_addr[i] = *eap++; */
+/* #endif */
+
+	ep->p_per   = 0;	/* 'cause the book says so */
+	ep->taddr_l = 0;	/* temp address (LSB) */
+	ep->taddr_m = 0;
+	ep->taddr_h = 0;	/* temp address (MSB) */
+
+	/* Now allocate the host memory pages and initialize the
+	 * buffer descriptors.
+	 */
+	/* initialize rx buffer descriptors */
+	bdp = cep->tx_bd_base;
+	for (j=0; j<(TX_RING_SIZE-1); j++) {
+		bdp->buf = 0;
+		bdp->status = 0;
+		bdp++;
+	}
+	bdp->buf = 0;
+	bdp->status = BD_SC_WRAP;
+
+
+	/* initialize rx buffer descriptors */
+	bdp = cep->rx_bd_base;
+	for (j=0; j<(RX_RING_SIZE-1); j++) {
+		bdp->buf = &rx_buf_pool[j * CPM_ENET_RX_FRSIZE];
+		bdp->status = BD_SC_EMPTY | BD_SC_INTRPT;
+		bdp++;
+	}
+	bdp->buf = &rx_buf_pool[j * CPM_ENET_RX_FRSIZE];
+	bdp->status = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT;
+
+
+
+	/* Let's re-initialize the channel now.  We have to do it later
+	 * than the manual describes because we have just now finished
+	 * the BD initialization.
+	 */
+	cp->cp_cr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+	while (cp->cp_cr & CPM_CR_FLG);
+
+	cep->skb_cur = cep->skb_dirty = 0;
+
+	sccp->scc_scce = 0xffff;	/* Clear any pending events */
+
+	/* Enable interrupts for transmit error, complete frame
+	 * received, and any transmit buffer we have also set the
+	 * interrupt flag.
+	 */
+	sccp->scc_sccm = (SCCE_ENET_TXE | SCCE_ENET_RXF | SCCE_ENET_TXB);
+
+	/* Install our interrupt handler.
+	 */
+	/* cpm_install_handler(CPMVEC_ENET, scc_enet_interrupt, dev); */
+	request_irq(CPMVEC_ENET, scc_enet_interrupt,
+		IRQ_FLG_LOCK, dev->name, (void *)dev);
+
+	/* Set GSMR_H to enable all normal operating modes.
+	 * Set GSMR_L to enable Ethernet to MC68160.
+	 */
+	sccp->scc_gsmr.w.high = 0;
+	sccp->scc_gsmr.w.low  = (SCC_GSMRL_TCI | SCC_GSMRL_TPL_48 |
+							 SCC_GSMRL_TPP_10 | SCC_GSMRL_MODE_ENET);
+
+	/* Set sync/delimiters.
+	 */
+	sccp->scc_dsr = 0xd555;
+
+	/* Set processing mode.  Use Ethernet CRC, catch broadcast, and
+	 * start frame search 22 bit times after RENA.
+	 */
+	sccp->scc_psmr = (SCC_PMSR_ENCRC       /* Ethernet CRC mode */
+			  /* | SCC_PSMR_HBC */ /* Enable heartbeat */
+			  /* | SCC_PMSR_PRO */ /* Promiscuous mode */
+			  /* | SCC_PMSR_FDE */ /* Full duplex enable */
+			  | ETHER_NIB_22);
+	/* sccp->scc_psmr = (SCC_PMSR_PRO | ETHER_CRC_32 | ETHER_NIB_22); */
+
+
+	/* It is now OK to enable the Ethernet transmitter.
+	 * Unfortunately, there are board implementation differences here.
+	 */
+#if defined(CONFIG_UCQUICC)
+/* 	 immap->im_ioport.iop_pcpar |= PC_ENET_TENA; */
+/* 	 immap->im_ioport.iop_pcdir &= ~PC_ENET_TENA; */
+	 cp->pio_pcpar |=  PC_ENET_TENA; /* t_en */
+	 cp->pio_pcdir &= ~PC_ENET_TENA;
+
+	 cp->pip_pbpar &= ~(0x00000200); /* power up ethernet transceiver */
+	 cp->pip_pbdir |=  (0x00000200);
+	 cp->pip_pbdat |=  (0x00000200);
+#endif
+
+
+	dev->base_addr = (unsigned long)ep;
+	dev->priv = cep;
+#if 0
+	dev->name = "CPM_ENET";
+#endif
+
+	/* The CPM Ethernet specific entries in the device structure. */
+	dev->open = scc_enet_open;
+	dev->hard_start_xmit = scc_enet_start_xmit;
+	/* dev->tx_timeout = scc_enet_timeout; */
+	/* dev->watchdog_timeo = TX_TIMEOUT; */
+	dev->stop = scc_enet_close;
+	dev->get_stats = scc_enet_get_stats;
+	dev->set_multicast_list = set_multicast_list;
+
+	/* And last, enable the transmit and receive processing.
+	*/
+	sccp->scc_gsmr.w.low |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+	printk("%s: CPM ENET Version 0.3, ", dev->name);
+	for (i=0; i<5; i++)
+		printk("%02x:", dev->dev_addr[i]);
+	printk("%02x\n", dev->dev_addr[5]);
+
+	return 0;
+}
+
+
+
+int m68360_enet_probe(struct device *dev)
+{
+	return(scc_enet_init ());
+}
+
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 4
+ * End:
+ */
diff -Nru a/drivers/net/Kconfig b/drivers/net/Kconfig
--- a/drivers/net/Kconfig	Mon Nov  4 14:31:02 2002
+++ b/drivers/net/Kconfig	Mon Nov  4 14:31:02 2002
@@ -1541,6 +1541,20 @@
 	  MIPS-32-based Baget embedded system.  This chipset is better known
 	  via the NE2100 cards.
 
+config 68360_ENET
+	bool "Motorola 68360 ethernet controller"
+	depends on M68360
+	help
+	  Say Y here if you want to use the built-in ethernet controller of
+	  the Motorola 68360 processor.
+
+config FEC
+	bool "FEC ethernet controller (of ColdFire 5272)"
+	depends on M5272
+	help
+	  Say Y here if you want to use the built-in 10/100 Fast ethernet
+	  controller on the Motorola ColdFire 5272 processor.
+
 endmenu
 
 #
diff -Nru a/drivers/net/Makefile b/drivers/net/Makefile
--- a/drivers/net/Makefile	Mon Nov  4 14:31:01 2002
+++ b/drivers/net/Makefile	Mon Nov  4 14:31:01 2002
@@ -76,13 +76,15 @@
 obj-$(CONFIG_SEEQ8005) += seeq8005.o
 obj-$(CONFIG_ETHERTAP) += ethertap.o
 obj-$(CONFIG_NET_SB1000) += sb1000.o
-obj-$(CONFIG_MAC8390) += daynaport.o 8390.o
+obj-$(CONFIG_MAC8390) += mac8390.o 8390.o
 obj-$(CONFIG_APNE) += apne.o 8390.o
 obj-$(CONFIG_PCMCIA_PCNET) += 8390.o
 obj-$(CONFIG_SHAPER) += shaper.o
 obj-$(CONFIG_SK_G16) += sk_g16.o
 obj-$(CONFIG_HP100) += hp100.o
 obj-$(CONFIG_SMC9194) += smc9194.o
+obj-$(CONFIG_FEC) += fec.o
+obj-$(CONFIG_68360_ENET) += 68360enet.o
 obj-$(CONFIG_ARM_AM79C961A) += am79c961a.o
 obj-$(CONFIG_ARM_ETHERH) += 8390.o
 obj-$(CONFIG_WD80x3) += wd.o 8390.o
diff -Nru a/drivers/net/daynaport.c b/drivers/net/daynaport.c
--- a/drivers/net/daynaport.c	Mon Nov  4 14:31:02 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,922 +0,0 @@
-/* daynaport.c: A Macintosh 8390 based ethernet driver for linux. */
-/*
-	Derived from code:
-	
-	Written 1993-94 by Donald Becker.
-
-	Copyright 1993 United States Government as represented by the
-	Director, National Security Agency.
-
-	This software may be used and distributed according to the terms
-	of the GNU General Public License, incorporated herein by reference.
-
-	    TODO:
-
-	    The block output routines may be wrong for non Dayna
-	    cards
-
-		Fix this driver so that it will attempt to use the info
-		(i.e. iobase, iosize) given to it by the new and improved
-		NuBus code.
-
-		Despite its misleading filename, this driver is not Dayna-specific
-		anymore. */
-/* Cabletron E6100 card support added by Tony Mantler (eek@escape.ca) April 1999 */
-
-static const char *version =
-	"daynaport.c: v0.02 1999-05-17 Alan Cox (Alan.Cox@linux.org) and others\n";
-static int version_printed;
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/nubus.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/hwtest.h>
-#include <asm/macints.h>
-#include <linux/delay.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include "8390.h"
-
-static int ns8390_probe1(struct net_device *dev, int word16, char *name, int id,
-				  int prom, struct nubus_dev *ndev);
-
-static int ns8390_open(struct net_device *dev);
-static void ns8390_no_reset(struct net_device *dev);
-static int ns8390_close_card(struct net_device *dev);
-
-/* Interlan */
-static void interlan_reset(struct net_device *dev);
-
-/* Dayna */
-static void dayna_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
-						int ring_page);
-static void dayna_block_input(struct net_device *dev, int count,
-						  struct sk_buff *skb, int ring_offset);
-static void dayna_block_output(struct net_device *dev, int count,
-						   const unsigned char *buf, const int start_page);
-
-/* Sane (32-bit chunk memory read/write) */
-static void sane_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
-						int ring_page);
-static void sane_block_input(struct net_device *dev, int count,
-						  struct sk_buff *skb, int ring_offset);
-static void sane_block_output(struct net_device *dev, int count,
-						   const unsigned char *buf, const int start_page);
-
-/* Slow Sane (16-bit chunk memory read/write) */
-static void slow_sane_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
-						int ring_page);
-static void slow_sane_block_input(struct net_device *dev, int count,
-						  struct sk_buff *skb, int ring_offset);
-static void slow_sane_block_output(struct net_device *dev, int count,
-						   const unsigned char *buf, const int start_page);
-
-
-#define WD_START_PG	0x00	/* First page of TX buffer */
-#define WD03_STOP_PG	0x20	/* Last page +1 of RX ring */
-#define WD13_STOP_PG	0x40	/* Last page +1 of RX ring */
-
-#define CABLETRON_RX_START_PG          0x00    /* First page of RX buffer */
-#define CABLETRON_RX_STOP_PG           0x30    /* Last page +1 of RX ring */
-#define CABLETRON_TX_START_PG          CABLETRON_RX_STOP_PG  /* First page of TX buffer */
-
-
-#define DAYNA_MAC_BASE		0xf0007
-#define DAYNA_8390_BASE		0x80000 /* 3 */
-#define DAYNA_8390_MEM		0x00000
-#define DAYNA_MEMSIZE		0x04000	/* First word of each long ! */
-
-#define APPLE_8390_BASE		0xE0000
-#define APPLE_8390_MEM		0xD0000
-#define APPLE_MEMSIZE		8192    /* FIXME: need to dynamically check */
-
-#define KINETICS_MAC_BASE	0xf0004 /* first byte of each long */
-#define KINETICS_8390_BASE	0x80000
-#define KINETICS_8390_MEM	0x00000 /* first word of each long */
-#define KINETICS_MEMSIZE	8192    /* FIXME: need to dynamically check */
-/*#define KINETICS_MEMSIZE	(0x10000/2) * CSA: on the board I have, at least */
-
-#define CABLETRON_8390_BASE		0x90000	
-#define CABLETRON_8390_MEM		0x00000
-
-static int test_8390(volatile char *ptr, int scale)
-{
-	int regd;
-	int v;
-	
-	if(hwreg_present(&ptr[0x00])==0)
-		return -EIO;
-	if(hwreg_present(&ptr[0x0D<<scale])==0)
-		return -EIO;
-	if(hwreg_present(&ptr[0x0D<<scale])==0)
-		return -EIO;
-	ptr[0x00]=E8390_NODMA+E8390_PAGE1+E8390_STOP;
-	regd=ptr[0x0D<<scale];
-	ptr[0x0D<<scale]=0xFF;
-	ptr[0x00]=E8390_NODMA+E8390_PAGE0;
-	v=ptr[0x0D<<scale];
-	if(ptr[0x0D<<scale]!=0)
-	{
-		ptr[0x0D<<scale]=regd;
-		return -ENODEV;
-	}
-/*	printk("NS8390 found at %p scaled %d\n", ptr,scale);*/
-	return 0;
-}
-/*
- *    Identify the species of NS8390 card/driver we need
- */
-
-enum mac8390_type {
-	NS8390_DAYNA,
-	NS8390_INTERLAN,
-	NS8390_KINETICS,
-	NS8390_APPLE,
-	NS8390_FARALLON,
-	NS8390_ASANTE,
-	NS8390_CABLETRON
-};
-
-static int __init ns8390_ident(struct nubus_dev* ndev)
-{
-	/* This really needs to be tested and tested hard.  */
-		
-	/* Summary of what we know so far --
-	 * SW: 0x0104 -- asante,    16 bit, back4_offsets
-	 * SW: 0x010b -- daynaport, 16 bit, fwrd4_offsets
-	 * SW: 0x010c -- farallon,  16 bit, back4_offsets, no long word access
-	 * SW: 0x011a -- focus,     [no details yet]
-	 * SW: ?????? -- interlan,  16 bit, back4_offsets, funny reset
-	 * SW: ?????? -- kinetics,   8 bit, back4_offsets
-	 * -- so i've this hypothesis going that says DrSW&1 says whether the
-	 *    map is forward or backwards -- and maybe DrSW&256 says what the
-	 *    register spacing is -- for all cards that report a DrSW in some
-	 *    range.
-	 *    This would allow the "apple compatible" driver to drive many
-	 *    seemingly different types of cards.  More DrSW info is needed
-	 *    to investigate this properly. [CSA, 21-May-1999]
-	 */
-	/* Dayna ex Kinetics board */
-	if(ndev->dr_sw == NUBUS_DRSW_DAYNA)
-		return NS8390_DAYNA;
-	if(ndev->dr_sw == NUBUS_DRSW_ASANTE)
-		return NS8390_ASANTE;
-	if(ndev->dr_sw == NUBUS_DRSW_FARALLON) /* farallon or sonic systems */
-		return NS8390_FARALLON;
-	if(ndev->dr_sw == NUBUS_DRSW_KINETICS)
-		return NS8390_KINETICS;
-	/* My ATI Engineering card with this combination crashes the */
-	/* driver trying to xmit packets. Best not touch it for now. */
-	/*     - 1999-05-20 (funaho@jurai.org)                       */
-	if(ndev->dr_sw == NUBUS_DRSW_FOCUS)
-		return -1;
-
-	/* Check the HW on this one, because it shares the same DrSW as
-	   the on-board SONIC chips */
-	if(ndev->dr_hw == NUBUS_DRHW_CABLETRON)
-		return NS8390_CABLETRON;
-	/* does anyone have one of these? */
-	if(ndev->dr_hw == NUBUS_DRHW_INTERLAN)
-		return NS8390_INTERLAN;
-
-	/* FIXME: what do genuine Apple boards look like? */
-	return -1;
-}
-
-/*
- *	Memory probe for 8390 cards
- */
- 
-static int __init apple_8390_mem_probe(volatile unsigned short *p)
-{
-	int i, j;
-	/*
-	 *	Algorithm.
-	 *	1.	Check each block size of memory doesn't fault
-	 *	2.	Write a value to it
-	 *	3.	Check all previous blocks are unaffected
-	 */
-	
-	for(i=0;i<2;i++)
-	{
-		volatile unsigned short *m=p+4096*i;
-		/* Unwriteable - we have a fully decoded card and the
-		   RAM end located */
-		   
-		if(hwreg_present(m)==0)
-			return 8192*i;
-			
-		*m=0xA5A0|i;
-		
-		for(j=0;j<i;j++)
-		{
-			/* Partial decode and wrap ? */
-			if(p[4096*j]!=(0xA5A0|j))
-			{
-				/* This is the first misdecode, so it had
-				   one less page than we tried */
-				return 8192*i;
-			}
- 			j++;
- 		}
- 		/* Ok it still decodes.. move on 8K */
- 	}
- 	/* 
- 	 *	We don't look past 16K. That should cover most cards
- 	 *	and above 16K there isnt really any gain.
- 	 */
- 	return 16384;
- }
- 		
-/*
- *    Probe for 8390 cards.  
- *    The ns8390_probe1() routine initializes the card and fills the
- *    station address field.
- *
- *    The NuBus interface has changed!  We now scan for these somewhat
- *    like how the PCI and Zorro drivers do.  It's not clear whether
- *    this is actually better, but it makes things more consistent.
- *
- *    dev->mem_start points
- *    at the memory ring, dev->mem_end gives the end of it.
- */
-
-int __init mac8390_probe(struct net_device *dev)
-{
-	static int slots;
-	volatile unsigned short *i;
-	volatile unsigned char *p;
-	int plen;
-	int id;
-	static struct nubus_dev* ndev;
-
-	/* Find the first card that hasn't already been seen */
-	while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK,
-								   NUBUS_TYPE_ETHERNET, ndev)) != NULL) {
-		/* Have we seen it already? */
-		if (slots & (1<<ndev->board->slot))
-			continue;
-		slots |= 1<<ndev->board->slot;
-
-		/* Is it one of ours? */
-		if ((id = ns8390_ident(ndev)) != -1)
-			break;
-	}
-
-	/* Hm.  No more cards, then */
-	if (ndev == NULL)
-		return -ENODEV;
-
-	dev = init_etherdev(dev, 0);
-	if (!dev)
-		return -ENOMEM;
-	SET_MODULE_OWNER(dev);
-
-	if (!version_printed) {
-		printk(KERN_INFO "%s", version);
-		version_printed = 1;
-	}
-
-	/*
-	 *	Dayna specific init
-	 */
-	if(id==NS8390_DAYNA)
-	{
-		dev->base_addr = (int)(ndev->board->slot_addr+DAYNA_8390_BASE);
-		dev->mem_start = (int)(ndev->board->slot_addr+DAYNA_8390_MEM);
-		dev->mem_end = dev->mem_start+DAYNA_MEMSIZE; /* 8K it seems */
-	
-		printk(KERN_INFO "%s: daynaport. testing board: ", dev->name);
-			
-		printk("memory - ");	
-			
-		i = (void *)dev->mem_start;
-		memset((void *)i,0xAA, DAYNA_MEMSIZE);
-		while(i<(volatile unsigned short *)dev->mem_end)
-		{
-			if(*i!=0xAAAA)
-				goto membad;
-			*i=0x5678; /* make sure we catch byte smearing */
-			if(*i!=0x5678)
-				goto membad;
-			i+=2;	/* Skip a word */
-		}
-			
-		printk("controller - ");
-			
-		p=(void *)dev->base_addr;
-		plen=0;
-			
-		while(plen<0x3FF00)
-		{
-			if(test_8390(p,0)==0)
-				break;
-			if(test_8390(p,1)==0)
-				break;
-			if(test_8390(p,2)==0)
-				break;
-			if(test_8390(p,3)==0)
-				break;
-			plen++;
-			p++;
-		}
-		if(plen==0x3FF00)
-			goto membad;
-		printk("OK\n");
-		dev->irq = SLOT2IRQ(ndev->board->slot);
-		if(ns8390_probe1(dev, 0, "dayna", id, -1, ndev)==0)
-			return 0;
-	}
-	/* Cabletron */
-	if (id==NS8390_CABLETRON) {
-		int memsize = 16<<10; /* fix this */
-		  
-		dev->base_addr=(int)(ndev->board->slot_addr+CABLETRON_8390_BASE);
-		dev->mem_start=(int)(ndev->board->slot_addr+CABLETRON_8390_MEM);
-		dev->mem_end=dev->mem_start+memsize;
-		dev->irq = SLOT2IRQ(ndev->board->slot);
-		  
-		/* The base address is unreadable if 0x00 has been written to the command register */
-		/* Reset the chip by writing E8390_NODMA+E8390_PAGE0+E8390_STOP just to be sure */
-		i = (void *)dev->base_addr;
-		*i = 0x21;
-		  
-		printk(KERN_INFO "%s: cabletron: testing board: ", dev->name);
-		printk("%dK memory - ", memsize>>10);		
-		i=(void *)dev->mem_start;
-		while(i<(volatile unsigned short *)(dev->mem_start+memsize))
-		{
-			*i=0xAAAA;
-			if(*i!=0xAAAA)
-				goto membad;
-			*i=0x5555;
-			if(*i!=0x5555)
-				goto membad;
-			i+=2;	/* Skip a word */
-		}
-		printk("OK\n");
-		  
-		if(ns8390_probe1(dev, 1, "cabletron", id, -1, ndev)==0)
-			return 0;
-	}
-	/* Apple, Farallon, Asante */
-	if(id==NS8390_APPLE || id==NS8390_FARALLON || id==NS8390_ASANTE)
-	{
-		int memsize;
-			
-		dev->base_addr=(int)(ndev->board->slot_addr+APPLE_8390_BASE);
-		dev->mem_start=(int)(ndev->board->slot_addr+APPLE_8390_MEM);
-			
-		memsize = apple_8390_mem_probe((void *)dev->mem_start);
-			
-		dev->mem_end=dev->mem_start+memsize;
-		dev->irq = SLOT2IRQ(ndev->board->slot);
-			
-		switch(id)
-		{
-		case NS8390_FARALLON:
-			printk(KERN_INFO "%s: farallon: testing board: ", dev->name);
-			break;
-		case NS8390_ASANTE:
-			printk(KERN_INFO "%s: asante: testing board: ", dev->name);
-			break;
-		case NS8390_APPLE:
-		default:
-			printk(KERN_INFO "%s: apple/clone: testing board: ", dev->name);
-			break;
-		}
-			
-		printk("%dK memory - ", memsize>>10);		
-			
-		i=(void *)dev->mem_start;
-		memset((void *)i,0xAA, memsize);
-		while(i<(volatile unsigned short *)dev->mem_end)
-		{
-			if(*i!=0xAAAA)
-				goto membad;
-			*i=0x5555;
-			if(*i!=0x5555)
-				goto membad;
-			i+=2;	/* Skip a word */
-		}
-		printk("OK\n");
-			
-		switch (id)
-		{
-		case NS8390_FARALLON:
-			if(ns8390_probe1(dev, 1, "farallon", id, -1, ndev)==0)
-				return 0;
-			break;
-		case NS8390_ASANTE:
-			if(ns8390_probe1(dev, 1, "asante", id, -1, ndev)==0)
-				return 0;
-			break;
-		case NS8390_APPLE:
-		default:
-			if(ns8390_probe1(dev, 1, "apple/clone", id, -1, ndev)==0)
-				return 0;
-			break;
-		}
-	}
-	/* Interlan */
-	if(id==NS8390_INTERLAN)
-	{
-		/* As apple and asante */
-		dev->base_addr=(int)(ndev->board->slot_addr+APPLE_8390_BASE);
-		dev->mem_start=(int)(ndev->board->slot_addr+APPLE_8390_MEM);
-		dev->mem_end=dev->mem_start+APPLE_MEMSIZE; /* 8K it seems */
-		dev->irq = SLOT2IRQ(ndev->board->slot);
-		if(ns8390_probe1(dev, 1, "interlan", id, -1, ndev)==0)
-			return 0;
-	}
-	/* Kinetics (Shiva Etherport) */
-	if(id==NS8390_KINETICS)
-	{
-		dev->base_addr=(int)(ndev->board->slot_addr+KINETICS_8390_BASE);
-		dev->mem_start=(int)(ndev->board->slot_addr+KINETICS_8390_MEM);
-		dev->mem_end=dev->mem_start+KINETICS_MEMSIZE; /* 8K it seems */
-		dev->irq = SLOT2IRQ(ndev->board->slot);
-		if(ns8390_probe1(dev, 0, "kinetics", id, -1, ndev)==0)
-			return 0;
-	}
-
-	/* We should hopefully not get here */
-	printk(KERN_ERR "Probe unsuccessful.\n");
-	return -ENODEV;
-
- membad:
-	printk(KERN_ERR "failed at %p in %p - %p.\n", i,
-		   (void *)dev->mem_start, (void *)dev->mem_end);
-	return -ENODEV;
-}
-
-static int __init mac8390_ethernet_addr(struct nubus_dev* ndev, unsigned char addr[6])
-{
-	struct nubus_dir dir;
-	struct nubus_dirent ent;
-
-	/* Get the functional resource for this device */
-	if (nubus_get_func_dir(ndev, &dir) == -1)
-		return -1;
-	if (nubus_find_rsrc(&dir, NUBUS_RESID_MAC_ADDRESS, &ent) == -1)
-		return -1;
-	
-	nubus_get_rsrc_mem(addr, &ent, 6);
-	return 0;
-}
-
-static int __init ns8390_probe1(struct net_device *dev, int word16, char *model_name,
-			 	int type, int promoff, struct nubus_dev *ndev)
-{
-	static u32 fwrd4_offsets[16]={
-		0,      4,      8,      12,
-		16,     20,     24,     28,
-		32,     36,     40,     44,
-		48,     52,     56,     60
-	};
-	static u32 back4_offsets[16]={
-		60,     56,     52,     48,
-		44,     40,     36,     32,
-		28,     24,     20,     16,
-		12,     8,      4,      0
-	};
-	static u32 fwrd2_offsets[16]={
-		0,      2,      4,      6,
-		8,     10,     12,     14,
-		16,    18,     20,     22,
-		24,    26,     28,     30
-	};
-
-	unsigned char *prom = (unsigned char*) ndev->board->slot_addr + promoff;
-
-	/* Allocate dev->priv and fill in 8390 specific dev fields. */
-	if (ethdev_init(dev)) 
-	{	
-		printk ("%s: unable to get memory for dev->priv.\n", dev->name);
-		return -ENOMEM;
-	}
-
-	/* OK, we are certain this is going to work.  Setup the device. */
-
-	ei_status.name = model_name;
-	ei_status.word16 = word16;
-
-       if (type==NS8390_CABLETRON) {
-               /* Cabletron card puts the RX buffer before the TX buffer */
-               ei_status.tx_start_page = CABLETRON_TX_START_PG;
-               ei_status.rx_start_page = CABLETRON_RX_START_PG;
-               ei_status.stop_page = CABLETRON_RX_STOP_PG;
-               ei_status.rmem_start = dev->mem_start;
-               ei_status.rmem_end = dev->mem_start + CABLETRON_RX_STOP_PG*256;
-       } else {
-               ei_status.tx_start_page = WD_START_PG;
-               ei_status.rx_start_page = WD_START_PG + TX_PAGES;
-               ei_status.stop_page = (dev->mem_end - dev->mem_start)/256;
-               ei_status.rmem_start = dev->mem_start + TX_PAGES*256;
-               ei_status.rmem_end = dev->mem_end;
-       }
-	
-	if(promoff==-1)		/* Use nubus resources ? */
-	{
-		if(mac8390_ethernet_addr(ndev, dev->dev_addr))
-		{
-		  printk("mac_ns8390: MAC address not in resources!\n");
-		  return -ENODEV;
-		}
-	}
-	else			/* Pull it off the card */
-	{
-		int i=0;
-		int x=1;
-		/* These should go in the end I hope */
-		if(type==NS8390_DAYNA)
-			x=2;
-		if(type==NS8390_INTERLAN || type==NS8390_KINETICS)
-			x=4;
-		while(i<6)
-		{
-			dev->dev_addr[i]=*prom;
-			prom+=x;
-			if(i)
-				printk(":");
-			printk("%02X",dev->dev_addr[i++]);
-		}
-	}
-
-	printk(KERN_INFO "%s: %s in slot %X (type %s)\n",
-		   dev->name, ndev->board->name, ndev->board->slot, model_name);
-	printk(KERN_INFO "MAC ");
-	{
-		int i;
-		for (i = 0; i < 6; i++) {
-			printk("%2.2x", dev->dev_addr[i]);
-			if (i < 5)
-				printk(":");
-		}
-	}
-	printk(" IRQ %d, shared memory at %#lx-%#lx.\n",
-		   dev->irq, dev->mem_start, dev->mem_end-1);
-
-	switch(type)
-	{
-		case NS8390_DAYNA:      /* Dayna card */
-		case NS8390_KINETICS:   /* Kinetics --  8 bit config, but 16 bit mem */
-			/* 16 bit, 4 word offsets */
-			ei_status.reset_8390 = &ns8390_no_reset;
-			ei_status.block_input = &dayna_block_input;
-			ei_status.block_output = &dayna_block_output;
-			ei_status.get_8390_hdr = &dayna_get_8390_hdr;
-			ei_status.reg_offset = fwrd4_offsets;
-			break;
-		case NS8390_CABLETRON: /* Cabletron */
-			/*		16 bit card, register map is short forward */
-			ei_status.reset_8390 = &ns8390_no_reset;
-			/* Ctron card won't accept 32bit values read or written to it */
-			ei_status.block_input = &slow_sane_block_input;
-			ei_status.block_output = &slow_sane_block_output;
-			ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
-			ei_status.reg_offset = fwrd2_offsets;
-			break;
-		case NS8390_FARALLON:
-		case NS8390_APPLE:	/* Apple/Asante/Farallon */
-			/*      16 bit card, register map is reversed */
-			ei_status.reset_8390 = &ns8390_no_reset;
-			ei_status.block_input = &slow_sane_block_input;
-			ei_status.block_output = &slow_sane_block_output;
-			ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
-			ei_status.reg_offset = back4_offsets;
-			break;
-		case NS8390_ASANTE:
-			/*      16 bit card, register map is reversed */
-			ei_status.reset_8390 = &ns8390_no_reset;
-			ei_status.block_input = &sane_block_input;
-			ei_status.block_output = &sane_block_output;
-			ei_status.get_8390_hdr = &sane_get_8390_hdr;
-			ei_status.reg_offset = back4_offsets;
-			break;
-		case NS8390_INTERLAN:   /* Interlan */
-			/*      16 bit card, map is forward */
-			ei_status.reset_8390 = &interlan_reset;
-			ei_status.block_input = &sane_block_input;
-			ei_status.block_output = &sane_block_output;
-			ei_status.get_8390_hdr = &sane_get_8390_hdr;
-			ei_status.reg_offset = back4_offsets;
-			break;
-#if 0 /* i think this suffered code rot.  my kinetics card has much
-	   * different settings.  -- CSA [22-May-1999] */
-		case NS8390_KINETICS:   /* Kinetics */
-			/*      8bit card, map is forward */
-			ei_status.reset_8390 = &ns8390_no_reset;
-			ei_status.block_input = &sane_block_input;
-			ei_status.block_output = &sane_block_output;
-			ei_status.get_8390_hdr = &sane_get_8390_hdr;
-			ei_status.reg_offset = back4_offsets;
-			break;
-#endif
-		default:
-			panic("Detected a card I can't drive - whoops\n");
-	}
-	dev->open = &ns8390_open;
-	dev->stop = &ns8390_close_card;
-
-	NS8390_init(dev, 0);
-
-	return 0;
-}
-
-static int ns8390_open(struct net_device *dev)
-{
-	int ret;
-
-	ei_open(dev);
-
-	/* At least on my card (a Focus Enhancements PDS card) I start */
-	/* getting interrupts right away, so the driver needs to be    */
-	/* completely initialized before enabling the interrupt.        */
-	/*                             - funaho@jurai.org (1999-05-17) */
-
-	/* Non-slow interrupt, works around issues with the SONIC driver */
-	ret = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev); 
-	if (ret) {
-		printk ("%s: unable to get IRQ %d.\n", dev->name, dev->irq);
-		return ret;
-	}
-	return 0;
-}
-
-static void ns8390_no_reset(struct net_device *dev)
-{
-	if (ei_debug > 1) 
-		printk("Need to reset the NS8390 t=%lu...", jiffies);
-	ei_status.txing = 0;
-	if (ei_debug > 1) printk("reset not supported\n");
-}
-
-static int ns8390_close_card(struct net_device *dev)
-{
-	if (ei_debug > 1)
-		printk("%s: Shutting down ethercard.\n", dev->name);
-	free_irq(dev->irq, dev);
-	ei_close(dev);
-	return 0;
-}
-
-/*
- *    Interlan Specific Code Starts Here
- */
-
-static void interlan_reset(struct net_device *dev)
-{
-	unsigned char *target=nubus_slot_addr(IRQ2SLOT(dev->irq));
-	if (ei_debug > 1) 
-		printk("Need to reset the NS8390 t=%lu...", jiffies);
-	ei_status.txing = 0;
-	/* This write resets the card */
-	target[0xC0000]=0;
-	if (ei_debug > 1) printk("reset complete\n");
-	return;
-}
-
-/*
- *    Daynaport code (some is used by other drivers)
- */
-
-
-/* Grab the 8390 specific header. Similar to the block_input routine, but
-   we don't need to be concerned with ring wrap as the header will be at
-   the start of a page, so we optimize accordingly. */
-
-
-/* Block input and output are easy on shared memory ethercards, and trivial
-   on the Daynaport card where there is no choice of how to do it.
-   The only complications are that the ring buffer wraps.
-*/
-
-static void dayna_memcpy_fromcard(struct net_device *dev, void *to, int from, int count)
-{
-	volatile unsigned short *ptr;
-	unsigned short *target=to;
-	from<<=1;	/* word, skip overhead */
-	ptr=(unsigned short *)(dev->mem_start+from);
-	/*
-	 * Leading byte?
-	 */
-	if (from&2) {
-		*((char *)target)++ = *(((char *)ptr++)-1);
-		count--;
-	}
-	while(count>=2)
-	{
-		*target++=*ptr++;	/* Copy and */
-		ptr++;			/* skip cruft */
-		count-=2;
-	}
-	/*
-	 *	Trailing byte ?
-	 */
-	if(count)
-	{
-		/* Big endian */
-		unsigned short v=*ptr;
-		*((char *)target)=v>>8;
-	}
-}
-
-static void dayna_memcpy_tocard(struct net_device *dev, int to, const void *from, int count)
-{
-	volatile unsigned short *ptr;
-	const unsigned short *src=from;
-	to<<=1;	/* word, skip overhead */
-	ptr=(unsigned short *)(dev->mem_start+to);
-	/*
-	 * Leading byte?
-	 */
-	if (to&2) { /* avoid a byte write (stomps on other data) */
-		ptr[-1] = (ptr[-1]&0xFF00)|*((unsigned char *)src)++;
-		ptr++;
-		count--;
-	}
-	while(count>=2)
-	{
-		*ptr++=*src++;		/* Copy and */
-		ptr++;			/* skip cruft */
-		count-=2;
-	}
-	/*
-	 *	Trailing byte ?
-	 */
-	if(count)
-	{
-		/* Big endian */
-		unsigned short v=*src;
-		/* card doesn't like byte writes */
-		*ptr=(*ptr&0x00FF)|(v&0xFF00);
-	}
-}
-
-static void dayna_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
-{
-	unsigned long hdr_start = (ring_page - WD_START_PG)<<8;
-	dayna_memcpy_fromcard(dev, (void *)hdr, hdr_start, 4);
-	/* Register endianism - fix here rather than 8390.c */
-	hdr->count=(hdr->count&0xFF)<<8|(hdr->count>>8);
-}
-
-static void dayna_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
-{
-	unsigned long xfer_base = ring_offset - (WD_START_PG<<8);
-	unsigned long xfer_start = xfer_base+dev->mem_start;
-
-	/*
-	 *	Note the offset maths is done in card memory space which
-	 *	is word per long onto our space.
-	 */
-	 
-	if (xfer_start + count > ei_status.rmem_end) 
-	{
-		/* We must wrap the input move. */
-		int semi_count = ei_status.rmem_end - xfer_start;
-		dayna_memcpy_fromcard(dev, skb->data, xfer_base, semi_count);
-		count -= semi_count;
-		dayna_memcpy_fromcard(dev, skb->data + semi_count, 
-			ei_status.rmem_start - dev->mem_start, count);
-	}
-	else
-	{
-		dayna_memcpy_fromcard(dev, skb->data, xfer_base, count);
-	}
-}
-
-static void dayna_block_output(struct net_device *dev, int count, const unsigned char *buf,
-				int start_page)
-{
-	long shmem = (start_page - WD_START_PG)<<8;
-	
-	dayna_memcpy_tocard(dev, shmem, buf, count);
-}
-
-/*
- *	Cards with full width memory
- */
-
-
-static void sane_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
-{
-	unsigned long hdr_start = (ring_page - WD_START_PG)<<8;
-	memcpy((void *)hdr, (char *)dev->mem_start+hdr_start, 4);
-	/* Register endianism - fix here rather than 8390.c */
-	hdr->count=(hdr->count&0xFF)<<8|(hdr->count>>8);
-}
-
-static void sane_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
-{
-	unsigned long xfer_base = ring_offset - (WD_START_PG<<8);
-	unsigned long xfer_start = xfer_base+dev->mem_start;
-
-	if (xfer_start + count > ei_status.rmem_end) 
-	{
-		/* We must wrap the input move. */
-		int semi_count = ei_status.rmem_end - xfer_start;
-		memcpy(skb->data, (char *)dev->mem_start+xfer_base, semi_count);
-		count -= semi_count;
-		memcpy(skb->data + semi_count, 
-			(char *)ei_status.rmem_start, count);
-	}
-	else
-	{
-		memcpy(skb->data, (char *)dev->mem_start+xfer_base, count);
-	}
-}
-
-
-static void sane_block_output(struct net_device *dev, int count, const unsigned char *buf,
-				int start_page)
-{
-	long shmem = (start_page - WD_START_PG)<<8;
-	
-	memcpy((char *)dev->mem_start+shmem, buf, count);
-}
-
-static void word_memcpy_tocard(void *tp, const void *fp, int count)
-{
-	volatile unsigned short *to = tp;
-	const unsigned short *from = fp;
-	
-	count++;
-	count/=2;
-	
-	while(count--)
-		*to++=*from++;
-}
-
-static void word_memcpy_fromcard(void *tp, const void *fp, int count)
-{
-	unsigned short *to = tp;
-	const volatile unsigned short *from = fp;
-	
-	count++;
-	count/=2;
-	
-	while(count--)
-		*to++=*from++;
-}
-
-static void slow_sane_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
-{
-	unsigned long hdr_start = (ring_page - WD_START_PG)<<8;
-	word_memcpy_fromcard((void *)hdr, (char *)dev->mem_start+hdr_start, 4);
-	/* Register endianism - fix here rather than 8390.c */
-	hdr->count=(hdr->count&0xFF)<<8|(hdr->count>>8);
-}
-
-static void slow_sane_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
-{
-	unsigned long xfer_base = ring_offset - (WD_START_PG<<8);
-	unsigned long xfer_start = xfer_base+dev->mem_start;
-
-	if (xfer_start + count > ei_status.rmem_end) 
-	{
-		/* We must wrap the input move. */
-		int semi_count = ei_status.rmem_end - xfer_start;
-		word_memcpy_fromcard(skb->data, (char *)dev->mem_start+xfer_base, semi_count);
-		count -= semi_count;
-		word_memcpy_fromcard(skb->data + semi_count, 
-			(char *)ei_status.rmem_start, count);
-	}
-	else
-	{
-		word_memcpy_fromcard(skb->data, (char *)dev->mem_start+xfer_base, count);
-	}
-}
-
-static void slow_sane_block_output(struct net_device *dev, int count, const unsigned char *buf,
-				int start_page)
-{
-	long shmem = (start_page - WD_START_PG)<<8;
-	
-	word_memcpy_tocard((char *)dev->mem_start+shmem, buf, count);
-#if 0
-	long shmem = (start_page - WD_START_PG)<<8;
-	volatile unsigned short *to=(unsigned short *)(dev->mem_start+shmem);
-	volatile int p;
-	unsigned short *bp=(unsigned short *)buf;
-	
-	count=(count+1)/2;
-	
-	while(count--)
-	{
-		*to++=*bp++;
-		for(p=0;p<10;p++)
-			p++;
-	}
-#endif	
-}
-
-MODULE_LICENSE("GPL");
diff -Nru a/drivers/net/dl2k.c b/drivers/net/dl2k.c
--- a/drivers/net/dl2k.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/net/dl2k.c	Mon Nov  4 14:31:01 2002
@@ -535,7 +535,7 @@
 {
 	long ioaddr = dev->base_addr;
 
-	printk (KERN_INFO "%s: Tx timed out (%4.4lx), is buffer full?\n",
+	printk (KERN_INFO "%s: Tx timed out (%4.4x), is buffer full?\n",
 		dev->name, readl (ioaddr + TxStatus));
 	rio_free_tx(dev, 0);
 	dev->if_port = 0;
diff -Nru a/drivers/net/fealnx.c b/drivers/net/fealnx.c
--- a/drivers/net/fealnx.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/net/fealnx.c	Mon Nov  4 14:31:02 2002
@@ -1155,8 +1155,8 @@
 	unsigned int old_linkok = np->linkok;
 
 	if (debug)
-		printk(KERN_DEBUG "%s: Media selection timer tick, status %8.8x "
-		       "config %8.8x.\n", dev->name, readl(ioaddr + ISR),
+		printk(KERN_DEBUG "%s: Media selection timer tick, status %8.8lx "
+		       "config %8.8lx.\n", dev->name, readl(ioaddr + ISR),
 		       readl(ioaddr + TCRRCR));
 
 	if (np->flags == HAS_MII_XCVR) {
@@ -1184,7 +1184,7 @@
 	long ioaddr = dev->base_addr;
 	int i;
 
-	printk(KERN_WARNING "%s: Transmit timed out, status %8.8x,"
+	printk(KERN_WARNING "%s: Transmit timed out, status %8.8lx,"
 	       " resetting...\n", dev->name, readl(ioaddr + ISR));
 
 	{
@@ -1555,7 +1555,7 @@
 	np->stats.rx_crc_errors += (readl(ioaddr + TALLY) & 0x7fff0000) >> 16;
 
 	if (debug)
-		printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
+		printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4lx.\n",
 		       dev->name, readl(ioaddr + ISR));
 
 	writel(np->imrvalue, ioaddr + IMR);
diff -Nru a/drivers/net/fec.c b/drivers/net/fec.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/net/fec.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,1926 @@
+/*
+ * Fast Ethernet Controller (FEC) driver for Motorola MPC8xx.
+ * Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
+ *
+ * This version of the driver is specific to the FADS implementation,
+ * since the board contains control registers external to the processor
+ * for the control of the LevelOne LXT970 transceiver.  The MPC860T manual
+ * describes connections using the internal parallel port I/O, which
+ * is basically all of Port D.
+ *
+ * Right now, I am very watseful with the buffers.  I allocate memory
+ * pages and then divide them into 2K frame buffers.  This way I know I
+ * have buffers large enough to hold one frame within one buffer descriptor.
+ * Once I get this working, I will use 64 or 128 byte CPM buffers, which
+ * will be much more memory efficient and will easily handle lots of
+ * small packets.
+ *
+ * Much better multiple PHY support by Magnus Damm.
+ * Copyright (c) 2000 Ericsson Radio Systems AB.
+ *
+ * Support for FEC controller of ColdFire/5272.
+ * Copyrught (c) 2001-2002 Greg Ungerer (gerg@snapgear.com)
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+
+#ifdef CONFIG_M5272
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include "fec.h"
+#else
+#include <asm/8xx_immap.h>
+#include <asm/mpc8xx.h>
+#include "commproc.h"
+#endif
+
+static int opened = 0;
+static int found = 0;
+
+/*
+ * Define the fixed address of the FEC hardware.
+ */
+#ifdef CONFIG_M5272
+static volatile fec_t   *fec_hwp = (volatile fec_t *) (MCF_MBAR + 0x840);
+static ushort		my_enet_addr[] = { 0x00d0, 0xcf00, 0x0072 };
+#else
+static volatile fec_t	*fec_hwp = &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec)
+static ushort		my_enet_addr[3];
+#endif /* CONFIG_M5272 */
+
+/*
+ * Some hardware gets it MAC address out of local flash memory.
+ * if this is non-zero then assume it is the address to get MAC from.
+ */
+#if defined(CONFIG_NETtel)
+#define	FEC_FLASHMAC	0xf0006006
+#elif defined(CONFIG_GILBARCONAP)
+#define	FEC_FLASHMAC	0xf0006000
+#elif defined (CONFIG_MTD_KeyTechnology)
+#define	FEC_FLASHMAC	0xffe04000
+#else
+#define	FEC_FLASHMAC	0
+#endif
+
+unsigned char *fec_flashmac = (unsigned char *) FEC_FLASHMAC;
+
+/* Forward declarations of some structures to support different PHYs
+*/
+
+typedef struct {
+	uint mii_data;
+	void (*funct)(uint mii_reg, struct net_device *dev);
+} phy_cmd_t;
+
+typedef struct {
+	uint id;
+	char *name;
+
+	const phy_cmd_t *config;
+	const phy_cmd_t *startup;
+	const phy_cmd_t *ack_int;
+	const phy_cmd_t *shutdown;
+} phy_info_t;
+
+/* The number of Tx and Rx buffers.  These are allocated from the page
+ * pool.  The code may assume these are power of two, so it it best
+ * to keep them that size.
+ * We don't need to allocate pages for the transmitter.  We just use
+ * the skbuffer directly.
+ */
+#if 1
+#define FEC_ENET_RX_PAGES	4
+#define FEC_ENET_RX_FRSIZE	2048
+#define FEC_ENET_RX_FRPPG	(PAGE_SIZE / FEC_ENET_RX_FRSIZE)
+#define RX_RING_SIZE		(FEC_ENET_RX_FRPPG * FEC_ENET_RX_PAGES)
+#define TX_RING_SIZE		8	/* Must be power of two */
+#define TX_RING_MOD_MASK	7	/*   for this to work */
+#else
+#define FEC_ENET_RX_PAGES	16
+#define FEC_ENET_RX_FRSIZE	2048
+#define FEC_ENET_RX_FRPPG	(PAGE_SIZE / FEC_ENET_RX_FRSIZE)
+#define RX_RING_SIZE		(FEC_ENET_RX_FRPPG * FEC_ENET_RX_PAGES)
+#define TX_RING_SIZE		16	/* Must be power of two */
+#define TX_RING_MOD_MASK	15	/*   for this to work */
+#endif
+
+/* Interrupt events/masks.
+*/
+#define FEC_ENET_HBERR	((uint)0x80000000)	/* Heartbeat error */
+#define FEC_ENET_BABR	((uint)0x40000000)	/* Babbling receiver */
+#define FEC_ENET_BABT	((uint)0x20000000)	/* Babbling transmitter */
+#define FEC_ENET_GRA	((uint)0x10000000)	/* Graceful stop complete */
+#define FEC_ENET_TXF	((uint)0x08000000)	/* Full frame transmitted */
+#define FEC_ENET_TXB	((uint)0x04000000)	/* A buffer was transmitted */
+#define FEC_ENET_RXF	((uint)0x02000000)	/* Full frame received */
+#define FEC_ENET_RXB	((uint)0x01000000)	/* A buffer was received */
+#define FEC_ENET_MII	((uint)0x00800000)	/* MII interrupt */
+#define FEC_ENET_EBERR	((uint)0x00400000)	/* SDMA bus error */
+
+/* The FEC stores dest/src/type, data, and checksum for receive packets.
+ */
+#define PKT_MAXBUF_SIZE		1518
+#define PKT_MINBUF_SIZE		64
+#define PKT_MAXBLR_SIZE		1520
+
+/* The FEC buffer descriptors track the ring buffers.  The rx_bd_base and
+ * tx_bd_base always point to the base of the buffer descriptors.  The
+ * cur_rx and cur_tx point to the currently available buffer.
+ * The dirty_tx tracks the current buffer that is being sent by the
+ * controller.  The cur_tx and dirty_tx are equal under both completely
+ * empty and completely full conditions.  The empty/ready indicator in
+ * the buffer descriptor determines the actual condition.
+ */
+struct fec_enet_private {
+	/* The saved address of a sent-in-place packet/buffer, for skfree(). */
+	struct	sk_buff* tx_skbuff[TX_RING_SIZE];
+	ushort	skb_cur;
+	ushort	skb_dirty;
+
+	/* CPM dual port RAM relative addresses.
+	*/
+	cbd_t	*rx_bd_base;		/* Address of Rx and Tx buffers. */
+	cbd_t	*tx_bd_base;
+	cbd_t	*cur_rx, *cur_tx;		/* The next free ring entry */
+	cbd_t	*dirty_tx;	/* The ring entries to be free()ed. */
+	struct	net_device_stats stats;
+	uint	tx_full;
+	spinlock_t lock;
+
+	uint	phy_id;
+	uint	phy_id_done;
+	uint	phy_status;
+	uint	phy_speed;
+	phy_info_t	*phy;
+	struct work_struct phy_task;
+
+	uint	sequence_done;
+
+	uint	phy_addr;
+
+	int	link;
+	int	old_link;
+	int	full_duplex;
+};
+
+static int fec_enet_open(struct net_device *dev);
+static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static void fec_enet_mii(struct net_device *dev);
+static void fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs);
+static void fec_enet_tx(struct net_device *dev);
+static void fec_enet_rx(struct net_device *dev);
+static int fec_enet_close(struct net_device *dev);
+static struct net_device_stats *fec_enet_get_stats(struct net_device *dev);
+static void set_multicast_list(struct net_device *dev);
+static void fec_restart(struct net_device *dev, int duplex);
+static void fec_stop(struct net_device *dev);
+
+
+/* MII processing.  We keep this as simple as possible.  Requests are
+ * placed on the list (if there is room).  When the request is finished
+ * by the MII, an optional function may be called.
+ */
+typedef struct mii_list {
+	uint	mii_regval;
+	void	(*mii_func)(uint val, struct net_device *dev);
+	struct	mii_list *mii_next;
+} mii_list_t;
+
+#define		NMII	20
+mii_list_t	mii_cmds[NMII];
+mii_list_t	*mii_free;
+mii_list_t	*mii_head;
+mii_list_t	*mii_tail;
+
+static int	mii_queue(struct net_device *dev, int request, 
+				void (*func)(uint, struct net_device *));
+
+/* Make MII read/write commands for the FEC.
+*/
+#define mk_mii_read(REG)	(0x60020000 | ((REG & 0x1f) << 18))
+#define mk_mii_write(REG, VAL)	(0x50020000 | ((REG & 0x1f) << 18) | \
+						(VAL & 0xffff))
+#define mk_mii_end	0
+
+/* Transmitter timeout.
+*/
+#define TX_TIMEOUT (2*HZ)
+
+/* Register definitions for the PHY.
+*/
+
+#define MII_REG_CR          0  /* Control Register                         */
+#define MII_REG_SR          1  /* Status Register                          */
+#define MII_REG_PHYIR1      2  /* PHY Identification Register 1            */
+#define MII_REG_PHYIR2      3  /* PHY Identification Register 2            */
+#define MII_REG_ANAR        4  /* A-N Advertisement Register               */ 
+#define MII_REG_ANLPAR      5  /* A-N Link Partner Ability Register        */
+#define MII_REG_ANER        6  /* A-N Expansion Register                   */
+#define MII_REG_ANNPTR      7  /* A-N Next Page Transmit Register          */
+#define MII_REG_ANLPRNPR    8  /* A-N Link Partner Received Next Page Reg. */
+
+/* values for phy_status */
+
+#define PHY_CONF_ANE	0x0001  /* 1 auto-negotiation enabled */
+#define PHY_CONF_LOOP	0x0002  /* 1 loopback mode enabled */
+#define PHY_CONF_SPMASK	0x00f0  /* mask for speed */
+#define PHY_CONF_10HDX	0x0010  /* 10 Mbit half duplex supported */
+#define PHY_CONF_10FDX	0x0020  /* 10 Mbit full duplex supported */ 
+#define PHY_CONF_100HDX	0x0040  /* 100 Mbit half duplex supported */
+#define PHY_CONF_100FDX	0x0080  /* 100 Mbit full duplex supported */ 
+
+#define PHY_STAT_LINK	0x0100  /* 1 up - 0 down */
+#define PHY_STAT_FAULT	0x0200  /* 1 remote fault */
+#define PHY_STAT_ANC	0x0400  /* 1 auto-negotiation complete	*/
+#define PHY_STAT_SPMASK	0xf000  /* mask for speed */
+#define PHY_STAT_10HDX	0x1000  /* 10 Mbit half duplex selected	*/
+#define PHY_STAT_10FDX	0x2000  /* 10 Mbit full duplex selected	*/ 
+#define PHY_STAT_100HDX	0x4000  /* 100 Mbit half duplex selected */
+#define PHY_STAT_100FDX	0x8000  /* 100 Mbit full duplex selected */ 
+
+
+static int
+fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct fec_enet_private *fep;
+	volatile fec_t	*fecp;
+	volatile cbd_t	*bdp;
+
+	fep = dev->priv;
+	fecp = (volatile fec_t*)dev->base_addr;
+
+	if (!fep->link) {
+		/* Link is down or autonegotiation is in progress. */
+		return 1;
+	}
+
+	/* Fill in a Tx ring entry */
+	bdp = fep->cur_tx;
+
+#ifndef final_version
+	if (bdp->cbd_sc & BD_ENET_TX_READY) {
+		/* Ooops.  All transmit buffers are full.  Bail out.
+		 * This should not happen, since dev->tbusy should be set.
+		 */
+		printk("%s: tx queue full!.\n", dev->name);
+		return 1;
+	}
+#endif
+
+	/* Clear all of the status flags.
+	 */
+	bdp->cbd_sc &= ~BD_ENET_TX_STATS;
+
+	/* Set buffer length and buffer pointer.
+	*/
+	bdp->cbd_bufaddr = __pa(skb->data);
+	bdp->cbd_datlen = skb->len;
+
+	/* Save skb pointer.
+	*/
+	fep->tx_skbuff[fep->skb_cur] = skb;
+
+	fep->stats.tx_bytes += skb->len;
+	fep->skb_cur = (fep->skb_cur+1) & TX_RING_MOD_MASK;
+	
+	/* Push the data cache so the CPM does not get stale memory
+	 * data.
+	 */
+	flush_dcache_range((unsigned long)skb->data,
+			   (unsigned long)skb->data + skb->len);
+
+	spin_lock_irq(&fep->lock);
+
+	/* Send it on its way.  Tell FEC its ready, interrupt when done,
+	 * its the last BD of the frame, and to put the CRC on the end.
+	 */
+
+	bdp->cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_INTR
+			| BD_ENET_TX_LAST | BD_ENET_TX_TC);
+
+	dev->trans_start = jiffies;
+
+	/* Trigger transmission start */
+	fecp->fec_x_des_active = 0x01000000;
+
+	/* If this was the last BD in the ring, start at the beginning again.
+	*/
+	if (bdp->cbd_sc & BD_ENET_TX_WRAP) {
+		bdp = fep->tx_bd_base;
+	} else {
+		bdp++;
+	}
+
+	if (bdp == fep->dirty_tx) {
+		fep->tx_full = 1;
+		netif_stop_queue(dev);
+	}
+
+	fep->cur_tx = (cbd_t *)bdp;
+
+	spin_unlock_irq(&fep->lock);
+
+	return 0;
+}
+
+static void
+fec_timeout(struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+
+	printk("%s: transmit timed out.\n", dev->name);
+	fep->stats.tx_errors++;
+#ifndef final_version
+	{
+	int	i;
+	cbd_t	*bdp;
+
+	printk("Ring data dump: cur_tx %lx%s, dirty_tx %lx cur_rx: %lx\n",
+	       (unsigned long)fep->cur_tx, fep->tx_full ? " (full)" : "",
+	       (unsigned long)fep->dirty_tx,
+	       (unsigned long)fep->cur_rx);
+
+	bdp = fep->tx_bd_base;
+	printk(" tx: %u buffers\n",  TX_RING_SIZE);
+	for (i = 0 ; i < TX_RING_SIZE; i++) {
+		printk("  %08x: %04x %04x %08x\n", 
+		       (uint) bdp,
+		       bdp->cbd_sc,
+		       bdp->cbd_datlen,
+		       (int) bdp->cbd_bufaddr);
+		bdp++;
+	}
+
+	bdp = fep->rx_bd_base;
+	printk(" rx: %lu buffers\n",  (unsigned long) RX_RING_SIZE);
+	for (i = 0 ; i < RX_RING_SIZE; i++) {
+		printk("  %08x: %04x %04x %08x\n",
+		       (uint) bdp,
+		       bdp->cbd_sc,
+		       bdp->cbd_datlen,
+		       (int) bdp->cbd_bufaddr);
+		bdp++;
+	}
+	}
+#endif
+	fec_restart(dev, 0);
+	netif_wake_queue(dev);
+}
+
+/* The interrupt handler.
+ * This is called from the MPC core interrupt.
+ */
+static	void
+fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+{
+	struct	net_device *dev = dev_id;
+	volatile fec_t	*fecp;
+	uint	int_events;
+
+	fecp = (volatile fec_t*)dev->base_addr;
+
+	/* Get the interrupt events that caused us to be here.
+	*/
+	while ((int_events = fecp->fec_ievent) != 0) {
+		fecp->fec_ievent = int_events;
+		if ((int_events & (FEC_ENET_HBERR | FEC_ENET_BABR |
+				   FEC_ENET_BABT | FEC_ENET_EBERR)) != 0) {
+			printk("FEC ERROR %x\n", int_events);
+		}
+
+		/* Handle receive event in its own function.
+		 */
+		if (int_events & FEC_ENET_RXF)
+			fec_enet_rx(dev);
+
+		/* Transmit OK, or non-fatal error. Update the buffer
+		   descriptors. FEC handles all errors, we just discover
+		   them as part of the transmit process.
+		*/
+		if (int_events & FEC_ENET_TXF)
+			fec_enet_tx(dev);
+
+		if (int_events & FEC_ENET_MII)
+			fec_enet_mii(dev);
+	
+	}
+}
+
+
+static void
+fec_enet_tx(struct net_device *dev)
+{
+	struct	fec_enet_private *fep;
+	volatile cbd_t	*bdp;
+	struct	sk_buff	*skb;
+
+	fep = dev->priv;
+	spin_lock(&fep->lock);
+	bdp = fep->dirty_tx;
+
+	while ((bdp->cbd_sc&BD_ENET_TX_READY) == 0) {
+		if (bdp == fep->cur_tx && fep->tx_full == 0) break;
+
+		skb = fep->tx_skbuff[fep->skb_dirty];
+		/* Check for errors. */
+		if (bdp->cbd_sc & (BD_ENET_TX_HB | BD_ENET_TX_LC |
+				   BD_ENET_TX_RL | BD_ENET_TX_UN |
+				   BD_ENET_TX_CSL)) {
+			fep->stats.tx_errors++;
+			if (bdp->cbd_sc & BD_ENET_TX_HB)  /* No heartbeat */
+				fep->stats.tx_heartbeat_errors++;
+			if (bdp->cbd_sc & BD_ENET_TX_LC)  /* Late collision */
+				fep->stats.tx_window_errors++;
+			if (bdp->cbd_sc & BD_ENET_TX_RL)  /* Retrans limit */
+				fep->stats.tx_aborted_errors++;
+			if (bdp->cbd_sc & BD_ENET_TX_UN)  /* Underrun */
+				fep->stats.tx_fifo_errors++;
+			if (bdp->cbd_sc & BD_ENET_TX_CSL) /* Carrier lost */
+				fep->stats.tx_carrier_errors++;
+		} else {
+			fep->stats.tx_packets++;
+		}
+
+#ifndef final_version
+		if (bdp->cbd_sc & BD_ENET_TX_READY)
+			printk("HEY! Enet xmit interrupt and TX_READY.\n");
+#endif
+		/* Deferred means some collisions occurred during transmit,
+		 * but we eventually sent the packet OK.
+		 */
+		if (bdp->cbd_sc & BD_ENET_TX_DEF)
+			fep->stats.collisions++;
+	    
+		/* Free the sk buffer associated with this last transmit.
+		 */
+		dev_kfree_skb_any(skb);
+		fep->tx_skbuff[fep->skb_dirty] = NULL;
+		fep->skb_dirty = (fep->skb_dirty + 1) & TX_RING_MOD_MASK;
+	    
+		/* Update pointer to next buffer descriptor to be transmitted.
+		 */
+		if (bdp->cbd_sc & BD_ENET_TX_WRAP)
+			bdp = fep->tx_bd_base;
+		else
+			bdp++;
+	    
+		/* Since we have freed up a buffer, the ring is no longer
+		 * full.
+		 */
+		if (fep->tx_full) {
+			fep->tx_full = 0;
+			if (netif_queue_stopped(dev))
+				netif_wake_queue(dev);
+		}
+	}
+	fep->dirty_tx = (cbd_t *)bdp;
+	spin_unlock(&fep->lock);
+}
+
+
+/* During a receive, the cur_rx points to the current incoming buffer.
+ * When we update through the ring, if the next incoming buffer has
+ * not been given to the system, we just set the empty indicator,
+ * effectively tossing the packet.
+ */
+static void
+fec_enet_rx(struct net_device *dev)
+{
+	struct	fec_enet_private *fep;
+	volatile fec_t	*fecp;
+	volatile cbd_t *bdp;
+	struct	sk_buff	*skb;
+	ushort	pkt_len;
+	__u8 *data;
+
+	fep = dev->priv;
+	fecp = (volatile fec_t*)dev->base_addr;
+
+	/* First, grab all of the stats for the incoming packet.
+	 * These get messed up if we get called due to a busy condition.
+	 */
+	bdp = fep->cur_rx;
+
+while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) {
+
+#ifndef final_version
+	/* Since we have allocated space to hold a complete frame,
+	 * the last indicator should be set.
+	 */
+	if ((bdp->cbd_sc & BD_ENET_RX_LAST) == 0)
+		printk("FEC ENET: rcv is not +last\n");
+#endif
+
+	if (!opened)
+		goto rx_processing_done;
+
+	/* Check for errors. */
+	if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO |
+			   BD_ENET_RX_CR | BD_ENET_RX_OV)) {
+		fep->stats.rx_errors++;       
+		if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH)) {
+		/* Frame too long or too short. */
+			fep->stats.rx_length_errors++;
+		}
+		if (bdp->cbd_sc & BD_ENET_RX_NO)	/* Frame alignment */
+			fep->stats.rx_frame_errors++;
+		if (bdp->cbd_sc & BD_ENET_RX_CR)	/* CRC Error */
+			fep->stats.rx_crc_errors++;
+		if (bdp->cbd_sc & BD_ENET_RX_OV)	/* FIFO overrun */
+			fep->stats.rx_crc_errors++;
+	}
+
+	/* Report late collisions as a frame error.
+	 * On this error, the BD is closed, but we don't know what we
+	 * have in the buffer.  So, just drop this frame on the floor.
+	 */
+	if (bdp->cbd_sc & BD_ENET_RX_CL) {
+		fep->stats.rx_errors++;
+		fep->stats.rx_frame_errors++;
+		goto rx_processing_done;
+	}
+
+	/* Process the incoming frame.
+	 */
+	fep->stats.rx_packets++;
+	pkt_len = bdp->cbd_datlen;
+	fep->stats.rx_bytes += pkt_len;
+	data = (__u8*)__va(bdp->cbd_bufaddr);
+
+	/* This does 16 byte alignment, exactly what we need.
+	 * The packet length includes FCS, but we don't want to
+	 * include that when passing upstream as it messes up
+	 * bridging applications.
+	 */
+	skb = dev_alloc_skb(pkt_len-4);
+
+	if (skb == NULL) {
+		printk("%s: Memory squeeze, dropping packet.\n", dev->name);
+		fep->stats.rx_dropped++;
+	} else {
+		skb->dev = dev;
+		skb_put(skb,pkt_len-4);	/* Make room */
+		eth_copy_and_sum(skb,
+				 (unsigned char *)__va(bdp->cbd_bufaddr),
+				 pkt_len-4, 0);
+		skb->protocol=eth_type_trans(skb,dev);
+		netif_rx(skb);
+	}
+  rx_processing_done:
+
+	/* Clear the status flags for this buffer.
+	*/
+	bdp->cbd_sc &= ~BD_ENET_RX_STATS;
+
+	/* Mark the buffer empty.
+	*/
+	bdp->cbd_sc |= BD_ENET_RX_EMPTY;
+
+	/* Update BD pointer to next entry.
+	*/
+	if (bdp->cbd_sc & BD_ENET_RX_WRAP)
+		bdp = fep->rx_bd_base;
+	else
+		bdp++;
+	
+#if 1
+	/* Doing this here will keep the FEC running while we process
+	 * incoming frames.  On a heavily loaded network, we should be
+	 * able to keep up at the expense of system resources.
+	 */
+	fecp->fec_r_des_active = 0x01000000;
+#endif
+   } /* while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) */
+	fep->cur_rx = (cbd_t *)bdp;
+
+#if 0
+	/* Doing this here will allow us to process all frames in the
+	 * ring before the FEC is allowed to put more there.  On a heavily
+	 * loaded network, some frames may be lost.  Unfortunately, this
+	 * increases the interrupt overhead since we can potentially work
+	 * our way back to the interrupt return only to come right back
+	 * here.
+	 */
+	fecp->fec_r_des_active = 0x01000000;
+#endif
+}
+
+
+static void
+fec_enet_mii(struct net_device *dev)
+{
+	struct	fec_enet_private *fep;
+	volatile fec_t	*ep;
+	mii_list_t	*mip;
+	uint		mii_reg;
+
+	fep = (struct fec_enet_private *)dev->priv;
+	ep = fec_hwp;
+	mii_reg = ep->fec_mii_data;
+	
+	if ((mip = mii_head) == NULL) {
+		printk("MII and no head!\n");
+		return;
+	}
+
+	if (mip->mii_func != NULL)
+		(*(mip->mii_func))(mii_reg, dev);
+
+	mii_head = mip->mii_next;
+	mip->mii_next = mii_free;
+	mii_free = mip;
+
+	if ((mip = mii_head) != NULL)
+		ep->fec_mii_data = mip->mii_regval;
+}
+
+static int
+mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_device *))
+{
+	struct fec_enet_private *fep;
+	unsigned long	flags;
+	mii_list_t	*mip;
+	int		retval;
+
+	/* Add PHY address to register command.
+	*/
+	fep = dev->priv;
+	regval |= fep->phy_addr << 23;
+
+	retval = 0;
+
+	save_flags(flags);
+	cli();
+
+	if ((mip = mii_free) != NULL) {
+		mii_free = mip->mii_next;
+		mip->mii_regval = regval;
+		mip->mii_func = func;
+		mip->mii_next = NULL;
+		if (mii_head) {
+			mii_tail->mii_next = mip;
+			mii_tail = mip;
+		}
+		else {
+			mii_head = mii_tail = mip;
+			fec_hwp->fec_mii_data = regval;
+		}
+	}
+	else {
+		retval = 1;
+	}
+
+	restore_flags(flags);
+
+	return(retval);
+}
+
+static void mii_do_cmd(struct net_device *dev, const phy_cmd_t *c)
+{
+	int k;
+
+	if(!c)
+		return;
+
+	for(k = 0; (c+k)->mii_data != mk_mii_end; k++) {
+		mii_queue(dev, (c+k)->mii_data, (c+k)->funct);
+	}
+}
+
+static void mii_parse_sr(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile uint *s = &(fep->phy_status);
+
+	*s &= ~(PHY_STAT_LINK | PHY_STAT_FAULT | PHY_STAT_ANC);
+
+	if (mii_reg & 0x0004)
+		*s |= PHY_STAT_LINK;
+	if (mii_reg & 0x0010)
+		*s |= PHY_STAT_FAULT;
+	if (mii_reg & 0x0020)
+		*s |= PHY_STAT_ANC;
+}
+
+static void mii_parse_cr(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile uint *s = &(fep->phy_status);
+
+	*s &= ~(PHY_CONF_ANE | PHY_CONF_LOOP);
+
+	if (mii_reg & 0x1000)
+		*s |= PHY_CONF_ANE;
+	if (mii_reg & 0x4000)
+		*s |= PHY_CONF_LOOP;
+}
+
+static void mii_parse_anar(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile uint *s = &(fep->phy_status);
+
+	*s &= ~(PHY_CONF_SPMASK);
+
+	if (mii_reg & 0x0020)
+		*s |= PHY_CONF_10HDX;
+	if (mii_reg & 0x0040)
+		*s |= PHY_CONF_10FDX;
+	if (mii_reg & 0x0080)
+		*s |= PHY_CONF_100HDX;
+	if (mii_reg & 0x00100)
+		*s |= PHY_CONF_100FDX;
+}
+
+/* ------------------------------------------------------------------------- */
+/* The Level one LXT970 is used by many boards				     */
+
+#define MII_LXT970_MIRROR    16  /* Mirror register           */
+#define MII_LXT970_IER       17  /* Interrupt Enable Register */
+#define MII_LXT970_ISR       18  /* Interrupt Status Register */
+#define MII_LXT970_CONFIG    19  /* Configuration Register    */
+#define MII_LXT970_CSR       20  /* Chip Status Register      */
+
+static void mii_parse_lxt970_csr(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile uint *s = &(fep->phy_status);
+
+	*s &= ~(PHY_STAT_SPMASK);
+
+	if (mii_reg & 0x0800) {
+		if (mii_reg & 0x1000)
+			*s |= PHY_STAT_100FDX;
+		else
+			*s |= PHY_STAT_100HDX;
+	} else {
+		if (mii_reg & 0x1000)
+			*s |= PHY_STAT_10FDX;
+		else
+			*s |= PHY_STAT_10HDX;
+	}
+}
+
+static phy_info_t phy_info_lxt970 = {
+	0x07810000, 
+	"LXT970",
+
+	(const phy_cmd_t []) {  /* config */
+		{ mk_mii_read(MII_REG_CR), mii_parse_cr },
+		{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* startup - enable interrupts */
+		{ mk_mii_write(MII_LXT970_IER, 0x0002), NULL },
+		{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) { /* ack_int */
+		/* read SR and ISR to acknowledge */
+		{ mk_mii_read(MII_REG_SR), mii_parse_sr },
+		{ mk_mii_read(MII_LXT970_ISR), NULL },
+
+		/* find out the current status */
+		{ mk_mii_read(MII_LXT970_CSR), mii_parse_lxt970_csr },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* shutdown - disable interrupts */
+		{ mk_mii_write(MII_LXT970_IER, 0x0000), NULL },
+		{ mk_mii_end, }
+	},
+};
+	
+/* ------------------------------------------------------------------------- */
+/* The Level one LXT971 is used on some of my custom boards                  */
+
+/* register definitions for the 971 */
+
+#define MII_LXT971_PCR       16  /* Port Control Register     */
+#define MII_LXT971_SR2       17  /* Status Register 2         */
+#define MII_LXT971_IER       18  /* Interrupt Enable Register */
+#define MII_LXT971_ISR       19  /* Interrupt Status Register */
+#define MII_LXT971_LCR       20  /* LED Control Register      */
+#define MII_LXT971_TCR       30  /* Transmit Control Register */
+
+/* 
+ * I had some nice ideas of running the MDIO faster...
+ * The 971 should support 8MHz and I tried it, but things acted really
+ * wierd, so 2.5 MHz ought to be enough for anyone...
+ */
+
+static void mii_parse_lxt971_sr2(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile uint *s = &(fep->phy_status);
+
+	*s &= ~(PHY_STAT_SPMASK | PHY_STAT_LINK | PHY_STAT_ANC);
+
+	if (mii_reg & 0x0400) {
+		fep->link = 1;
+		*s |= PHY_STAT_LINK;
+	} else {
+		fep->link = 0;
+	}
+	if (mii_reg & 0x0080)
+		*s |= PHY_STAT_ANC;
+	if (mii_reg & 0x4000) {
+		if (mii_reg & 0x0200)
+			*s |= PHY_STAT_100FDX;
+		else
+			*s |= PHY_STAT_100HDX;
+	} else {
+		if (mii_reg & 0x0200)
+			*s |= PHY_STAT_10FDX;
+		else
+			*s |= PHY_STAT_10HDX;
+	}
+	if (mii_reg & 0x0008)
+		*s |= PHY_STAT_FAULT;
+}
+
+static phy_info_t phy_info_lxt971 = {
+	0x0001378e, 
+	"LXT971",
+	
+	(const phy_cmd_t []) {  /* config */  
+		/* limit to 10MBit because my protorype board 
+		 * doesn't work with 100. */
+		{ mk_mii_read(MII_REG_CR), mii_parse_cr },
+		{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
+		{ mk_mii_read(MII_LXT971_SR2), mii_parse_lxt971_sr2 },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* startup - enable interrupts */
+		{ mk_mii_write(MII_LXT971_IER, 0x00f2), NULL },
+		{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
+		{ mk_mii_write(MII_LXT971_LCR, 0xd422), NULL }, /* LED config */
+		/* Somehow does the 971 tell me that the link is down
+		 * the first read after power-up.
+		 * read here to get a valid value in ack_int */
+		{ mk_mii_read(MII_REG_SR), mii_parse_sr }, 
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) { /* ack_int */
+		/* find out the current status */
+		{ mk_mii_read(MII_REG_SR), mii_parse_sr },
+		{ mk_mii_read(MII_LXT971_SR2), mii_parse_lxt971_sr2 },
+		/* we only need to read ISR to acknowledge */
+		{ mk_mii_read(MII_LXT971_ISR), NULL },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* shutdown - disable interrupts */
+		{ mk_mii_write(MII_LXT971_IER, 0x0000), NULL },
+		{ mk_mii_end, }
+	},
+};
+
+/* ------------------------------------------------------------------------- */
+/* The Quality Semiconductor QS6612 is used on the RPX CLLF                  */
+
+/* register definitions */
+
+#define MII_QS6612_MCR       17  /* Mode Control Register      */
+#define MII_QS6612_FTR       27  /* Factory Test Register      */
+#define MII_QS6612_MCO       28  /* Misc. Control Register     */
+#define MII_QS6612_ISR       29  /* Interrupt Source Register  */
+#define MII_QS6612_IMR       30  /* Interrupt Mask Register    */
+#define MII_QS6612_PCR       31  /* 100BaseTx PHY Control Reg. */
+
+static void mii_parse_qs6612_pcr(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile uint *s = &(fep->phy_status);
+
+	*s &= ~(PHY_STAT_SPMASK);
+
+	switch((mii_reg >> 2) & 7) {
+	case 1: *s |= PHY_STAT_10HDX; break;
+	case 2: *s |= PHY_STAT_100HDX; break;
+	case 5: *s |= PHY_STAT_10FDX; break;
+	case 6: *s |= PHY_STAT_100FDX; break;
+	}
+}
+
+static phy_info_t phy_info_qs6612 = {
+	0x00181440, 
+	"QS6612",
+	
+	(const phy_cmd_t []) {  /* config */  
+		/* The PHY powers up isolated on the RPX, 
+		 * so send a command to allow operation.
+		 */
+		{ mk_mii_write(MII_QS6612_PCR, 0x0dc0), NULL },
+
+		/* parse cr and anar to get some info */
+		{ mk_mii_read(MII_REG_CR), mii_parse_cr },
+		{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* startup - enable interrupts */
+		{ mk_mii_write(MII_QS6612_IMR, 0x003a), NULL },
+		{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) { /* ack_int */
+		/* we need to read ISR, SR and ANER to acknowledge */
+		{ mk_mii_read(MII_QS6612_ISR), NULL },
+		{ mk_mii_read(MII_REG_SR), mii_parse_sr },
+		{ mk_mii_read(MII_REG_ANER), NULL },
+
+		/* read pcr to get info */
+		{ mk_mii_read(MII_QS6612_PCR), mii_parse_qs6612_pcr },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* shutdown - disable interrupts */
+		{ mk_mii_write(MII_QS6612_IMR, 0x0000), NULL },
+		{ mk_mii_end, }
+	},
+};
+
+/* ------------------------------------------------------------------------- */
+/* AMD AM79C874 phy                                                          */
+
+/* register definitions for the 874 */
+
+#define MII_AM79C874_MFR       16  /* Miscellaneous Feature Register */
+#define MII_AM79C874_ICSR      17  /* Interrupt/Status Register      */
+#define MII_AM79C874_DR        18  /* Diagnostic Register            */
+#define MII_AM79C874_PMLR      19  /* Power and Loopback Register    */
+#define MII_AM79C874_MCR       21  /* ModeControl Register           */
+#define MII_AM79C874_DC        23  /* Disconnect Counter             */
+#define MII_AM79C874_REC       24  /* Recieve Error Counter          */
+
+static void mii_parse_am79c874_dr(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile uint *s = &(fep->phy_status);
+
+	*s &= ~(PHY_STAT_SPMASK | PHY_STAT_ANC);
+
+	if (mii_reg & 0x0080)
+		*s |= PHY_STAT_ANC;
+	if (mii_reg & 0x0400)
+		*s |= ((mii_reg & 0x0800) ? PHY_STAT_100FDX : PHY_STAT_100HDX);
+	else
+		*s |= ((mii_reg & 0x0800) ? PHY_STAT_10FDX : PHY_STAT_10HDX);
+}
+
+static phy_info_t phy_info_am79c874 = {
+	0x00022561, 
+	"AM79C874",
+	
+	(const phy_cmd_t []) {  /* config */  
+		/* limit to 10MBit because my protorype board 
+		 * doesn't work with 100. */
+		{ mk_mii_read(MII_REG_CR), mii_parse_cr },
+		{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
+		{ mk_mii_read(MII_AM79C874_DR), mii_parse_am79c874_dr },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* startup - enable interrupts */
+		{ mk_mii_write(MII_AM79C874_ICSR, 0xff00), NULL },
+		{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
+		{ mk_mii_read(MII_REG_SR), mii_parse_sr }, 
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) { /* ack_int */
+		/* find out the current status */
+		{ mk_mii_read(MII_REG_SR), mii_parse_sr },
+		{ mk_mii_read(MII_AM79C874_DR), mii_parse_am79c874_dr },
+		/* we only need to read ISR to acknowledge */
+		{ mk_mii_read(MII_AM79C874_ICSR), NULL },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* shutdown - disable interrupts */
+		{ mk_mii_write(MII_AM79C874_ICSR, 0x0000), NULL },
+		{ mk_mii_end, }
+	},
+};
+
+/* ------------------------------------------------------------------------- */
+
+static phy_info_t *phy_info[] = {
+	&phy_info_lxt970,
+	&phy_info_lxt971,
+	&phy_info_qs6612,
+	&phy_info_am79c874,
+	NULL
+};
+
+/* ------------------------------------------------------------------------- */
+
+static void
+#ifdef CONFIG_RPXCLASSIC
+mii_link_interrupt(void *dev_id);
+#else
+mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs);
+#endif
+
+#ifdef CONFIG_M5272
+
+/*
+ *	Code specific to Coldfire 5272 setup.
+ */
+static void __inline__ fec_request_intrs(struct net_device *dev, volatile fec_t *fecp)
+{
+	volatile unsigned long *icrp;
+
+	/* Setup interrupt handlers. */
+	if (request_irq(86, fec_enet_interrupt, 0, "fec(RX)", dev) != 0)
+		printk("FEC: Could not allocate FEC(RC) IRQ(86)!\n");
+	if (request_irq(87, fec_enet_interrupt, 0, "fec(TX)", dev) != 0)
+		printk("FEC: Could not allocate FEC(RC) IRQ(87)!\n");
+	if (request_irq(88, fec_enet_interrupt, 0, "fec(OTHER)", dev) != 0)
+		printk("FEC: Could not allocate FEC(OTHER) IRQ(88)!\n");
+	if (request_irq(66, mii_link_interrupt, 0, "fec(MII)", dev) != 0)
+		printk("FEC: Could not allocate MII IRQ(66)!\n");
+
+	/* Unmask interrupt at ColdFire 5272 SIM */
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR3);
+	*icrp = 0x00000ddd;
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+	*icrp = (*icrp & 0x70777777) | 0x0d000000;
+}
+
+static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
+{
+	volatile fec_t *fecp;
+	fecp = fec_hwp;
+
+	fecp->fec_r_cntrl = 0x04;
+	fecp->fec_x_cntrl = 0x00;
+
+	/* Set MII speed to 2.5 MHz
+	*/
+	fecp->fec_mii_speed = fep->phy_speed = 0x0e;
+
+	fec_restart(dev, 0);
+}
+
+static void __inline__ fec_get_mac(struct net_device *dev, struct fec_enet_private *fep)
+{
+	volatile fec_t *fecp;
+	unsigned char *eap, *iap, tmpaddr[6];
+	int i;
+
+	fecp = fec_hwp;
+	eap = (unsigned char *) my_enet_addr;
+
+	if (fec_flashmac) {
+		/*
+		 * Get MAC address from FLASH.
+		 * If it is all 1's or 0's, use the default.
+		 */
+		iap = fec_flashmac;
+		if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
+		    (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
+			iap = eap;
+		if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) &&
+		    (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff))
+			iap = eap;
+	} else {
+		*((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low;
+		*((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16);
+		iap = &tmpaddr[0];
+	}
+
+	for (i=0; i<6; i++)
+		dev->dev_addr[i] = *eap++ = *iap++;
+}
+
+static void __inline__ fec_enable_phy_intr(void)
+{
+}
+
+static void __inline__ fec_disable_phy_intr(void)
+{
+	volatile unsigned long *icrp;
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+	*icrp = (*icrp & 0x70777777) | 0x08000000;
+}
+
+static void __inline__ fec_phy_ack_intr(void)
+{
+	volatile unsigned long *icrp;
+	/* Acknowledge the interrupt */
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+	*icrp = (*icrp & 0x77777777) | 0x08000000;
+}
+
+static void __inline__ fec_localhw_setup(void)
+{
+}
+
+/*
+ *	Do not need to make region uncached on 5272.
+ */
+static void __inline__ fec_uncache(unsigned long addr)
+{
+}
+
+/* ------------------------------------------------------------------------- */
+
+#else
+
+/*
+ *	Code sepcific to the MPC860T setup.
+ */
+static void __inline__ fec_request_intrs(struct net_device *dev, volatile fec_t *fecp)
+{
+	volatile immap_t *immap;
+
+	immap = (immap_t *)IMAP_ADDR;	/* pointer to internal registers */
+
+	if (request_8xxirq(FEC_INTERRUPT, fec_enet_interrupt, 0, "fec", dev) != 0)
+		panic("Could not allocate FEC IRQ!");
+
+#ifdef CONFIG_RPXCLASSIC
+	/* Make Port C, bit 15 an input that causes interrupts.
+	*/
+	immap->im_ioport.iop_pcpar &= ~0x0001;
+	immap->im_ioport.iop_pcdir &= ~0x0001;
+	immap->im_ioport.iop_pcso &= ~0x0001;
+	immap->im_ioport.iop_pcint |= 0x0001;
+	cpm_install_handler(CPMVEC_PIO_PC15, mii_link_interrupt, dev);
+
+	/* Make LEDS reflect Link status.
+	*/
+	*((uint *) RPX_CSR_ADDR) &= ~BCSR2_FETHLEDMODE;
+#endif
+#ifdef CONFIG_FADS
+	if (request_8xxirq(SIU_IRQ2, mii_link_interrupt, 0, "mii", dev) != 0)
+		panic("Could not allocate MII IRQ!");
+#endif
+}
+
+static void __inline__ fec_get_mac(struct net_device *dev, struct fec_enet_private *fep)
+{
+	unsigned char *eap, *iap, tmpaddr[6];
+	bd_t *bd;
+	int i;
+
+	eap = (unsigned char *)my_enet_addr;
+	iap = bd->bi_enetaddr;
+	bd = (bd_t *)__res;
+
+#ifdef CONFIG_RPXCLASSIC
+	/* The Embedded Planet boards have only one MAC address in
+	 * the EEPROM, but can have two Ethernet ports.  For the
+	 * FEC port, we create another address by setting one of
+	 * the address bits above something that would have (up to
+	 * now) been allocated.
+	 */
+	for (i=0; i<6; i++)
+		tmpaddr[i] = *iap++;
+	tmpaddr[3] |= 0x80;
+	iap = tmpaddr;
+#endif
+
+	for (i=0; i<6; i++)
+		dev->dev_addr[i] = *eap++ = *iap++;
+}
+
+static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
+{
+	extern uint _get_IMMR(void);
+	volatile immap_t *immap;
+	volatile fec_t *fecp;
+
+	fecp = fec_hwp;
+	immap = (immap_t *)IMAP_ADDR;	/* pointer to internal registers */
+
+	/* Configure all of port D for MII.
+	*/
+	immap->im_ioport.iop_pdpar = 0x1fff;
+
+	/* Bits moved from Rev. D onward.
+	*/
+	if ((_get_IMMR() & 0xffff) < 0x0501)
+		immap->im_ioport.iop_pddir = 0x1c58;	/* Pre rev. D */
+	else
+		immap->im_ioport.iop_pddir = 0x1fff;	/* Rev. D and later */
+	
+	/* Set MII speed to 2.5 MHz
+	*/
+	fecp->fec_mii_speed = fep->phy_speed = 
+		((bd->bi_busfreq * 1000000) / 2500000) & 0x7e;
+}
+
+static void __inline__ fec_enable_phy_intr(void)
+{
+	volatile fec_t *fecp;
+	fecp = fec_hwp;
+
+	/* Enable MII command finished interrupt 
+	*/
+	fecp->fec_ivec = (FEC_INTERRUPT/2) << 29;
+}
+
+static void __inline__ fec_disable_phy_intr(void)
+{
+}
+
+static void __inline__ fec_phy_ack_intr(void)
+{
+}
+
+static void __inline__ fec_localhw_setup(void)
+{
+	volatile fec_t *fecp;
+	fecp = fec_hwp;
+
+	fecp->fec_r_hash = PKT_MAXBUF_SIZE;
+	/* Enable big endian and don't care about SDMA FC.
+	*/
+	fecp->fec_fun_code = 0x78000000;
+}
+
+static void __inline__ fec_uncache(unsigned long addr)
+{
+	pte_t *pte;
+	pte = va_to_pte(mem_addr);
+	pte_val(*pte) |= _PAGE_NO_CACHE;
+	flush_tlb_page(init_mm.mmap, mem_addr);
+}
+
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+static void mii_display_status(struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile uint *s = &(fep->phy_status);
+
+	if (!fep->link && !fep->old_link) {
+		/* Link is still down - don't print anything */
+		return;
+	}
+
+	printk("%s: status: ", dev->name);
+
+	if (!fep->link) {
+		printk("link down");
+	} else {
+		printk("link up");
+
+		switch(*s & PHY_STAT_SPMASK) {
+		case PHY_STAT_100FDX: printk(", 100MBit Full Duplex"); break;
+		case PHY_STAT_100HDX: printk(", 100MBit Half Duplex"); break;
+		case PHY_STAT_10FDX: printk(", 10MBit Full Duplex"); break;
+		case PHY_STAT_10HDX: printk(", 10MBit Half Duplex"); break;
+		default:
+			printk(", Unknown speed/duplex");
+		}
+
+		if (*s & PHY_STAT_ANC)
+			printk(", auto-negotiation complete");
+	}
+
+	if (*s & PHY_STAT_FAULT)
+		printk(", remote fault");
+
+	printk(".\n");
+}
+
+static void mii_display_config(struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile uint *s = &(fep->phy_status);
+
+	printk("%s: config: auto-negotiation ", dev->name);
+
+	if (*s & PHY_CONF_ANE)
+		printk("on");
+	else
+		printk("off");
+
+	if (*s & PHY_CONF_100FDX)
+		printk(", 100FDX");
+	if (*s & PHY_CONF_100HDX)
+		printk(", 100HDX");
+	if (*s & PHY_CONF_10FDX)
+		printk(", 10FDX");
+	if (*s & PHY_CONF_10HDX)
+		printk(", 10HDX");
+	if (!(*s & PHY_CONF_SPMASK))
+		printk(", No speed/duplex selected?");
+
+	if (*s & PHY_CONF_LOOP)
+		printk(", loopback enabled");
+	
+	printk(".\n");
+
+	fep->sequence_done = 1;
+}
+
+static void mii_relink(struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	int duplex;
+
+	fep->link = (fep->phy_status & PHY_STAT_LINK) ? 1 : 0;
+	mii_display_status(dev);
+	fep->old_link = fep->link;
+
+	if (fep->link) {
+		duplex = 0;
+		if (fep->phy_status 
+		    & (PHY_STAT_100FDX | PHY_STAT_10FDX))
+			duplex = 1;
+		fec_restart(dev, duplex);
+	}
+	else
+		fec_stop(dev);
+
+#if 0
+	enable_irq(fep->mii_irq);
+#endif
+
+}
+
+static void mii_queue_relink(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+
+	INIT_WORK(&fep->phy_task, (void*)mii_relink, dev);
+	schedule_work(&fep->phy_task);
+}
+
+static void mii_queue_config(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+
+	INIT_WORK(&fep->phy_task, (void*)mii_display_config, dev);
+	schedule_work(&fep->phy_task);
+}
+
+
+
+phy_cmd_t phy_cmd_relink[] = { { mk_mii_read(MII_REG_CR), mii_queue_relink },
+			       { mk_mii_end, } };
+phy_cmd_t phy_cmd_config[] = { { mk_mii_read(MII_REG_CR), mii_queue_config },
+			       { mk_mii_end, } };
+
+
+
+/* Read remainder of PHY ID.
+*/
+static void
+mii_discover_phy3(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep;
+	int	i;
+
+	fep = dev->priv;
+	fep->phy_id |= (mii_reg & 0xffff);
+	printk("fec: PHY @ 0x%x, ID 0x%08x", fep->phy_addr, fep->phy_id);
+
+	for(i = 0; phy_info[i]; i++) {
+		if(phy_info[i]->id == (fep->phy_id >> 4))
+			break;
+	}
+
+	if (phy_info[i])
+		printk(" -- %s\n", phy_info[i]->name);
+	else
+		printk(" -- unknown PHY!\n");
+      
+	fep->phy = phy_info[i];
+	fep->phy_id_done = 1;
+}
+
+/* Scan all of the MII PHY addresses looking for someone to respond
+ * with a valid ID.  This usually happens quickly.
+ */
+static void
+mii_discover_phy(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep;
+	volatile fec_t *fecp;
+	uint phytype;
+
+	fep = dev->priv;
+	fecp = fec_hwp;
+
+	if (fep->phy_addr < 32) {
+		if ((phytype = (mii_reg & 0xffff)) != 0xffff && phytype != 0) {
+			
+			/* Got first part of ID, now get remainder.
+			*/
+			fep->phy_id = phytype << 16;
+			mii_queue(dev, mk_mii_read(MII_REG_PHYIR2),
+							mii_discover_phy3);
+		}
+		else {
+			fep->phy_addr++;
+			mii_queue(dev, mk_mii_read(MII_REG_PHYIR1),
+							mii_discover_phy);
+		}
+	} else {
+		printk("FEC: No PHY device found.\n");
+		/* Disable external MII interface */
+		fecp->fec_mii_speed = fep->phy_speed = 0;
+		fec_disable_phy_intr();
+	}
+}
+
+/* This interrupt occurs when the PHY detects a link change.
+*/
+static void
+#ifdef CONFIG_RPXCLASSIC
+mii_link_interrupt(void *dev_id)
+#else
+mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+#endif
+{
+	struct	net_device *dev = dev_id;
+	struct fec_enet_private *fep = dev->priv;
+
+	fec_phy_ack_intr();
+
+#if 0
+	disable_irq(fep->mii_irq);  /* disable now, enable later */
+#endif
+
+	mii_do_cmd(dev, fep->phy->ack_int);
+	mii_do_cmd(dev, phy_cmd_relink);  /* restart and display status */
+
+}
+
+static int
+fec_enet_open(struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+
+	/* I should reset the ring buffers here, but I don't yet know
+	 * a simple way to do that.
+	 */
+
+	fep->sequence_done = 0;
+	fep->link = 0;
+
+	if (fep->phy) {
+		mii_do_cmd(dev, fep->phy->ack_int);
+		mii_do_cmd(dev, fep->phy->config);
+		mii_do_cmd(dev, phy_cmd_config);  /* display configuration */
+
+		while(!fep->sequence_done)
+			schedule();
+
+		mii_do_cmd(dev, fep->phy->startup);
+	} else {
+		fep->link = 1; /* lets just try it and see */
+		/* no phy,  go full duplex,  it's most likely a hub chip */
+		fec_restart(dev, 1);
+	}
+
+	netif_start_queue(dev);
+	opened = 1;
+	return 0;		/* Success */
+}
+
+static int
+fec_enet_close(struct net_device *dev)
+{
+	/* Don't know what to do yet.
+	*/
+	opened = 0;
+	netif_stop_queue(dev);
+	fec_stop(dev);
+
+	return 0;
+}
+
+static struct net_device_stats *fec_enet_get_stats(struct net_device *dev)
+{
+	struct fec_enet_private *fep = (struct fec_enet_private *)dev->priv;
+
+	return &fep->stats;
+}
+
+/* Set or clear the multicast filter for this adaptor.
+ * Skeleton taken from sunlance driver.
+ * The CPM Ethernet implementation allows Multicast as well as individual
+ * MAC address filtering.  Some of the drivers check to make sure it is
+ * a group multicast address, and discard those that are not.  I guess I
+ * will do the same for now, but just remove the test if you want
+ * individual filtering as well (do the upper net layers want or support
+ * this kind of feature?).
+ */
+
+#define HASH_BITS	6		/* #bits in hash */
+#define CRC32_POLY	0xEDB88320
+
+static void set_multicast_list(struct net_device *dev)
+{
+	struct fec_enet_private *fep;
+	volatile fec_t *ep;
+	struct dev_mc_list *dmi;
+	unsigned int i, j, bit, data, crc;
+	unsigned char hash;
+
+	fep = (struct fec_enet_private *)dev->priv;
+	ep = fec_hwp;
+
+	if (dev->flags&IFF_PROMISC) {
+		/* Log any net taps. */
+		printk("%s: Promiscuous mode enabled.\n", dev->name);
+		ep->fec_r_cntrl |= 0x0008;
+	} else {
+
+		ep->fec_r_cntrl &= ~0x0008;
+
+		if (dev->flags & IFF_ALLMULTI) {
+			/* Catch all multicast addresses, so set the
+			 * filter to all 1's.
+			 */
+			ep->fec_hash_table_high = 0xffffffff;
+			ep->fec_hash_table_low = 0xffffffff;
+		} else {
+			/* Clear filter and add the addresses in hash register.
+			*/
+			ep->fec_hash_table_high = 0;
+			ep->fec_hash_table_low = 0;
+            
+			dmi = dev->mc_list;
+
+			for (j = 0; j < dev->mc_count; j++, dmi = dmi->next)
+			{
+				/* Only support group multicast for now.
+				*/
+				if (!(dmi->dmi_addr[0] & 1))
+					continue;
+			
+				/* calculate crc32 value of mac address
+				*/
+				crc = 0xffffffff;
+
+				for (i = 0; i < dmi->dmi_addrlen; i++)
+				{
+					data = dmi->dmi_addr[i];
+					for (bit = 0; bit < 8; bit++, data >>= 1)
+					{
+						crc = (crc >> 1) ^
+						(((crc ^ data) & 1) ? CRC32_POLY : 0);
+					}
+				}
+
+				/* only upper 6 bits (HASH_BITS) are used
+				   which point to specific bit in he hash registers
+				*/
+				hash = (crc >> (32 - HASH_BITS)) & 0x3f;
+			
+				if (hash > 31)
+					ep->fec_hash_table_high |= 1 << (hash - 32);
+				else
+					ep->fec_hash_table_low |= 1 << hash;
+			}
+		}
+	}
+}
+
+/* Initialize the FEC Ethernet on 860T (or ColdFire 5272).
+ */
+int __init fec_enet_init(struct net_device *dev)
+{
+	struct fec_enet_private *fep;
+	unsigned long	mem_addr;
+	volatile cbd_t	*bdp;
+	cbd_t		*cbd_base;
+	volatile fec_t	*fecp;
+	int 		i, j;
+
+	/* Only allow us to be probed once. */
+	if (found)
+		return(-ENXIO);
+
+	/* Allocate some private information.
+	*/
+	fep = (struct fec_enet_private *)kmalloc(sizeof(*fep), GFP_KERNEL);
+	memset(fep, 0, sizeof(*fep));
+
+	/* Create an Ethernet device instance.
+	*/
+	fecp = fec_hwp;
+
+	/* Whack a reset.  We should wait for this.
+	*/
+	fecp->fec_ecntrl = 1;
+	udelay(10);
+
+	/* Clear and enable interrupts */
+	fecp->fec_ievent = 0xffc0;
+	fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB |
+		FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII);
+	fecp->fec_hash_table_high = 0;
+	fecp->fec_hash_table_low = 0;
+	fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
+        fecp->fec_ecntrl = 2;
+        fecp->fec_r_des_active = 0x01000000;
+
+	/* Set the Ethernet address.  If using multiple Enets on the 8xx,
+	 * this needs some work to get unique addresses.
+	 */
+	fec_get_mac(dev, fep);
+
+	/* Allocate memory for buffer descriptors.
+	*/
+	if (((RX_RING_SIZE + TX_RING_SIZE) * sizeof(cbd_t)) > PAGE_SIZE) {
+		printk("FEC init error.  Need more space.\n");
+		printk("FEC initialization failed.\n");
+		return 1;
+	}
+	mem_addr = __get_free_page(GFP_KERNEL);
+	cbd_base = (cbd_t *)mem_addr;
+
+	fec_uncache(mem_addr);
+
+	/* Set receive and transmit descriptor base.
+	*/
+	fep->rx_bd_base = cbd_base;
+	fep->tx_bd_base = cbd_base + RX_RING_SIZE;
+
+	fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
+	fep->cur_rx = fep->rx_bd_base;
+
+	fep->skb_cur = fep->skb_dirty = 0;
+
+	/* Initialize the receive buffer descriptors.
+	*/
+	bdp = fep->rx_bd_base;
+	for (i=0; i<FEC_ENET_RX_PAGES; i++) {
+
+		/* Allocate a page.
+		*/
+		mem_addr = __get_free_page(GFP_KERNEL);
+
+		fec_uncache(mem_addr);
+
+		/* Initialize the BD for every fragment in the page.
+		*/
+		for (j=0; j<FEC_ENET_RX_FRPPG; j++) {
+			bdp->cbd_sc = BD_ENET_RX_EMPTY;
+			bdp->cbd_bufaddr = __pa(mem_addr);
+			mem_addr += FEC_ENET_RX_FRSIZE;
+			bdp++;
+		}
+	}
+
+	/* Set the last buffer to wrap.
+	*/
+	bdp--;
+	bdp->cbd_sc |= BD_SC_WRAP;
+
+	/* ...and the same for transmmit.
+	*/
+	bdp = fep->tx_bd_base;
+	for (i=0; i<TX_RING_SIZE; i++) {
+
+		/* Initialize the BD for every fragment in the page.
+		*/
+		bdp->cbd_sc = 0;
+		bdp->cbd_bufaddr = 0;
+		bdp++;
+	}
+
+	/* Set the last buffer to wrap.
+	*/
+	bdp--;
+	bdp->cbd_sc |= BD_SC_WRAP;
+
+	/* Set receive and transmit descriptor base.
+	*/
+	fecp->fec_r_des_start = __pa((uint)(fep->rx_bd_base));
+	fecp->fec_x_des_start = __pa((uint)(fep->tx_bd_base));
+
+	/* Install our interrupt handlers. This varies depending on
+	 * the architecture.
+	*/
+	fec_request_intrs(dev, fecp);
+
+	dev->base_addr = (unsigned long)fecp;
+	dev->priv = fep;
+
+	ether_setup(dev);
+
+	/* The FEC Ethernet specific entries in the device structure. */
+	dev->open = fec_enet_open;
+	dev->hard_start_xmit = fec_enet_start_xmit;
+	dev->tx_timeout = fec_timeout;
+	dev->watchdog_timeo = TX_TIMEOUT;
+	dev->stop = fec_enet_close;
+	dev->get_stats = fec_enet_get_stats;
+	dev->set_multicast_list = set_multicast_list;
+
+	for (i=0; i<NMII-1; i++)
+		mii_cmds[i].mii_next = &mii_cmds[i+1];
+	mii_free = mii_cmds;
+
+	/* setup MII interface */
+	fec_set_mii(dev, fep);
+
+	printk("%s: FEC ENET Version 0.2, ", dev->name);
+	for (i=0; i<5; i++)
+		printk("%02x:", dev->dev_addr[i]);
+	printk("%02x\n", dev->dev_addr[5]);
+
+	/* Queue up command to detect the PHY and initialize the
+	 * remainder of the interface.
+	 */
+	fep->phy_id_done = 0;
+	fep->phy_addr = 0;
+	mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), mii_discover_phy);
+
+	found++;
+	return 0;
+}
+
+/* This function is called to start or restart the FEC during a link
+ * change.  This only happens when switching between half and full
+ * duplex.
+ */
+static void
+fec_restart(struct net_device *dev, int duplex)
+{
+	struct fec_enet_private *fep;
+	int i;
+	unsigned char	*eap;
+	volatile	cbd_t	*bdp;
+	volatile	fec_t	*fecp;
+
+	fecp = fec_hwp;
+
+	fep = dev->priv;
+
+	/* Whack a reset.  We should wait for this.
+	*/
+	fecp->fec_ecntrl = 1;
+	udelay(10);
+
+	/* Enable interrupts we wish to service.
+	*/
+	fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB |
+				FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII);
+
+	/* Clear any outstanding interrupt.
+	*/
+	fecp->fec_ievent = 0xffc0;
+	fec_enable_phy_intr();
+
+	/* Set station address.
+	*/
+	fecp->fec_addr_low = (my_enet_addr[0] << 16) | my_enet_addr[1];
+	fecp->fec_addr_high = (my_enet_addr[2] << 16);
+
+	eap = (unsigned char *)&my_enet_addr[0];
+	for (i=0; i<6; i++)
+		dev->dev_addr[i] = *eap++;
+
+	/* Reset all multicast.
+	*/
+	fecp->fec_hash_table_high = 0;
+	fecp->fec_hash_table_low = 0;
+
+	/* Set maximum receive buffer size.
+	*/
+	fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
+
+	fec_localhw_setup();
+
+	/* Set receive and transmit descriptor base.
+	*/
+	fecp->fec_r_des_start = __pa((uint)(fep->rx_bd_base));
+	fecp->fec_x_des_start = __pa((uint)(fep->tx_bd_base));
+
+	fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
+	fep->cur_rx = fep->rx_bd_base;
+
+	/* Reset SKB transmit buffers.
+	*/
+	fep->skb_cur = fep->skb_dirty = 0;
+	for (i=0; i<=TX_RING_MOD_MASK; i++) {
+		if (fep->tx_skbuff[i] != NULL) {
+			dev_kfree_skb_any(fep->tx_skbuff[i]);
+			fep->tx_skbuff[i] = NULL;
+		}
+	}
+
+	/* Initialize the receive buffer descriptors.
+	*/
+	bdp = fep->rx_bd_base;
+	for (i=0; i<RX_RING_SIZE; i++) {
+
+		/* Initialize the BD for every fragment in the page.
+		*/
+		bdp->cbd_sc = BD_ENET_RX_EMPTY;
+		bdp++;
+	}
+
+	/* Set the last buffer to wrap.
+	*/
+	bdp--;
+	bdp->cbd_sc |= BD_SC_WRAP;
+
+	/* ...and the same for transmmit.
+	*/
+	bdp = fep->tx_bd_base;
+	for (i=0; i<TX_RING_SIZE; i++) {
+
+		/* Initialize the BD for every fragment in the page.
+		*/
+		bdp->cbd_sc = 0;
+		bdp->cbd_bufaddr = 0;
+		bdp++;
+	}
+
+	/* Set the last buffer to wrap.
+	*/
+	bdp--;
+	bdp->cbd_sc |= BD_SC_WRAP;
+
+	/* Enable MII mode.
+	*/
+	if (duplex) {
+		fecp->fec_r_cntrl = 0x04;	/* MII enable */
+		fecp->fec_x_cntrl = 0x04;	/* FD enable */
+	}
+	else {
+		fecp->fec_r_cntrl = 0x06;	/* MII enable|No Rcv on Xmit */
+		fecp->fec_x_cntrl = 0x00;
+	}
+	fep->full_duplex = duplex;
+
+	/* Set MII speed.
+	*/
+	fecp->fec_mii_speed = fep->phy_speed;
+
+	/* And last, enable the transmit and receive processing.
+	*/
+	fecp->fec_ecntrl = 2;
+	fecp->fec_r_des_active = 0x01000000;
+}
+
+static void
+fec_stop(struct net_device *dev)
+{
+	volatile fec_t *fecp;
+	struct fec_enet_private *fep;
+
+	fecp = fec_hwp;
+	fep = dev->priv;
+
+	fecp->fec_x_cntrl = 0x01;	/* Graceful transmit stop */
+
+	while(!(fecp->fec_ievent & 0x10000000));
+
+	/* Whack a reset.  We should wait for this.
+	*/
+	fecp->fec_ecntrl = 1;
+	udelay(10);
+
+	/* Clear outstanding MII command interrupts.
+	*/
+	fecp->fec_ievent = FEC_ENET_MII;
+	fec_enable_phy_intr();
+
+	fecp->fec_imask = FEC_ENET_MII;
+	fecp->fec_mii_speed = fep->phy_speed;
+}
+
+static struct net_device fec_dev = {
+	.init = fec_enet_init,
+};
+
+static int __init fec_enet_module_init(void)
+{
+	if (register_netdev(&fec_dev) != 0)
+		return -EIO;
+	return(0);
+}
+
+module_init(fec_enet_module_init);
+
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/net/fec.h b/drivers/net/fec.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/net/fec.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,115 @@
+/****************************************************************************/
+
+/*
+ *	fec.h  --  Fast Ethernet Controller for Motorola ColdFire 5272.
+ *
+ *	(C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com)
+ *	(C) Copyright 2000-2001, Lineo (www.lineo.com)
+ */
+
+/****************************************************************************/
+#ifndef FEC_H
+#define	FEC_H
+/****************************************************************************/
+
+/*
+ *	Define device register set address map.
+ */
+typedef struct fec {
+	unsigned long	fec_ecntrl;		/* Ethernet control reg */
+	unsigned long	fec_ievent;		/* Interrupt even reg */
+	unsigned long	fec_imask;		/* Interrupt mask reg */
+	unsigned long	fec_ivec;		/* Interrupt vec status reg */
+	unsigned long	fec_r_des_active;	/* Receive descriptor reg */
+	unsigned long	fec_x_des_active;	/* Transmit descriptor reg */
+	unsigned long	fec_reserved1[10];
+	unsigned long	fec_mii_data;		/* MII manage frame reg */
+	unsigned long	fec_mii_speed;		/* MII speed control reg */
+	unsigned long	fec_reserved2[17];
+	unsigned long	fec_r_bound;		/* FIFO receive bound reg */
+	unsigned long	fec_r_fstart;		/* FIFO receive start reg */
+	unsigned long	fec_reserved3[4];
+	unsigned long	fec_x_wmrk;		/* FIFO transmit water mark */
+	unsigned long	fec_reserved4;
+	unsigned long	fec_x_fstart;		/* FIFO transmit start reg */
+	unsigned long	fec_reserved5[21];
+	unsigned long	fec_r_cntrl;		/* Receive control reg */
+	unsigned long	fec_max_frm_len;	/* Maximum frame length reg */
+	unsigned long	fec_reserved6[14];
+	unsigned long	fec_x_cntrl;		/* Transmit Control reg */
+	unsigned long	fec_reserved7[158];
+	unsigned long	fec_addr_low;		/* Low 32bits MAC address */
+	unsigned long	fec_addr_high;		/* High 16bits MAC address */
+	unsigned long	fec_hash_table_high;	/* High 32bits hash table */
+	unsigned long	fec_hash_table_low;	/* Low 32bits hash table */
+	unsigned long	fec_r_des_start;	/* Receive descriptor ring */
+	unsigned long	fec_x_des_start;	/* Transmit descriptor ring */
+	unsigned long	fec_r_buff_size;	/* Maximum receive buff size */
+	unsigned long	reserved8[9];
+	unsigned long	fec_fifo_ram[112];	/* FIFO RAM buffer */
+} fec_t;
+
+
+/*
+ *	Define the buffer descriptor structure.
+ */
+typedef struct bufdesc {
+	unsigned short	cbd_sc;			/* Control and status info */
+	unsigned short	cbd_datlen;		/* Data length */
+	unsigned long	cbd_bufaddr;		/* Buffer address */
+} cbd_t;
+
+
+/*
+ *	The following definitions courtesy of commproc.h, which where
+ *	Copyright (c) 1997 Dan Malek (dmalek@jlc.net).
+ */
+#define BD_SC_EMPTY     ((ushort)0x8000)        /* Recieve is empty */
+#define BD_SC_READY     ((ushort)0x8000)        /* Transmit is ready */
+#define BD_SC_WRAP      ((ushort)0x2000)        /* Last buffer descriptor */
+#define BD_SC_INTRPT    ((ushort)0x1000)        /* Interrupt on change */
+#define BD_SC_CM        ((ushort)0x0200)        /* Continous mode */
+#define BD_SC_ID        ((ushort)0x0100)        /* Rec'd too many idles */
+#define BD_SC_P         ((ushort)0x0100)        /* xmt preamble */
+#define BD_SC_BR        ((ushort)0x0020)        /* Break received */
+#define BD_SC_FR        ((ushort)0x0010)        /* Framing error */
+#define BD_SC_PR        ((ushort)0x0008)        /* Parity error */
+#define BD_SC_OV        ((ushort)0x0002)        /* Overrun */
+#define BD_SC_CD        ((ushort)0x0001)        /* ?? */
+
+/* Buffer descriptor control/status used by Ethernet receive.
+*/
+#define BD_ENET_RX_EMPTY        ((ushort)0x8000)
+#define BD_ENET_RX_WRAP         ((ushort)0x2000)
+#define BD_ENET_RX_INTR         ((ushort)0x1000)
+#define BD_ENET_RX_LAST         ((ushort)0x0800)
+#define BD_ENET_RX_FIRST        ((ushort)0x0400)
+#define BD_ENET_RX_MISS         ((ushort)0x0100)
+#define BD_ENET_RX_LG           ((ushort)0x0020)
+#define BD_ENET_RX_NO           ((ushort)0x0010)
+#define BD_ENET_RX_SH           ((ushort)0x0008)
+#define BD_ENET_RX_CR           ((ushort)0x0004)
+#define BD_ENET_RX_OV           ((ushort)0x0002)
+#define BD_ENET_RX_CL           ((ushort)0x0001)
+#define BD_ENET_RX_STATS        ((ushort)0x013f)        /* All status bits */
+
+/* Buffer descriptor control/status used by Ethernet transmit.
+*/
+#define BD_ENET_TX_READY        ((ushort)0x8000)
+#define BD_ENET_TX_PAD          ((ushort)0x4000)
+#define BD_ENET_TX_WRAP         ((ushort)0x2000)
+#define BD_ENET_TX_INTR         ((ushort)0x1000)
+#define BD_ENET_TX_LAST         ((ushort)0x0800)
+#define BD_ENET_TX_TC           ((ushort)0x0400)
+#define BD_ENET_TX_DEF          ((ushort)0x0200)
+#define BD_ENET_TX_HB           ((ushort)0x0100)
+#define BD_ENET_TX_LC           ((ushort)0x0080)
+#define BD_ENET_TX_RL           ((ushort)0x0040)
+#define BD_ENET_TX_RCMASK       ((ushort)0x003c)
+#define BD_ENET_TX_UN           ((ushort)0x0002)
+#define BD_ENET_TX_CSL          ((ushort)0x0001)
+#define BD_ENET_TX_STATS        ((ushort)0x03ff)        /* All status bits */
+
+
+/****************************************************************************/
+#endif /* FEC_H */
diff -Nru a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c
--- a/drivers/net/ibmlana.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/net/ibmlana.c	Mon Nov  4 14:31:01 2002
@@ -260,7 +260,7 @@
 		else
 			tda.link = addr + sizeof(tda_t);
 		tda.link |= 1;
-		isa_memcpy_to_io(dev->mem_start + addr, &tda, sizeof(tda_t));
+		isa_memcpy_toio(dev->mem_start + addr, &tda, sizeof(tda_t));
 		addr += sizeof(tda_t);
 		baddr += PKTSIZE;
 	}
@@ -280,7 +280,7 @@
 		rra.starthi = 0;
 		rra.cntlo = PKTSIZE >> 1;
 		rra.cnthi = 0;
-		isa_memcpy_to_io(dev->mem_start + raddr, &rra, sizeof(rra_t));
+		isa_memcpy_toio(dev->mem_start + raddr, &rra, sizeof(rra_t));
 
 		rda.status = 0;
 		rda.length = 0;
@@ -292,7 +292,7 @@
 		else
 			rda.link = 1;
 		rda.inuse = 1;
-		isa_memcpy_to_io(dev->mem_start + addr, &rda, sizeof(rda_t));
+		isa_memcpy_toio(dev->mem_start + addr, &rda, sizeof(rda_t));
 
 		baddr += PKTSIZE;
 		raddr += sizeof(rra_t);
@@ -429,8 +429,8 @@
 
 	/* feed CDA into SONIC, initialize RCR value (always get broadcasts) */
 
-	isa_memcpy_to_io(dev->mem_start, cams, sizeof(camentry_t) * camcnt);
-	isa_memcpy_to_io(dev->mem_start + (sizeof(camentry_t) * camcnt), &cammask, sizeof(cammask));
+	isa_memcpy_toio(dev->mem_start, cams, sizeof(camentry_t) * camcnt);
+	isa_memcpy_toio(dev->mem_start + (sizeof(camentry_t) * camcnt), &cammask, sizeof(cammask));
 
 #ifdef DEBUG
 	printk("CAM setup:\n");
@@ -627,14 +627,14 @@
 
 		rda.link = 1;
 		rda.inuse = 1;
-		isa_memcpy_to_io(dev->mem_start + rdaaddr, &rda,
+		isa_memcpy_toio(dev->mem_start + rdaaddr, &rda,
 			     sizeof(rda_t));
 
 		/* set up link and EOL = 0 in currently last descriptor. Only write
 		   the link field since the SONIC may currently already access the
 		   other fields. */
 
-		isa_memcpy_to_io(dev->mem_start + lrdaaddr + 20, &rdaaddr, 4);
+		isa_memcpy_toio(dev->mem_start + lrdaaddr + 20, &rdaaddr, 4);
 
 		/* advance indices */
 
@@ -833,7 +833,7 @@
 	if (tmplen < 60)
 		tmplen = 60;
 	baddr = priv->txbufstart + (priv->nexttxdescr * PKTSIZE);
-	isa_memcpy_to_io(dev->mem_start + baddr, skb->data, skb->len);
+	isa_memcpy_toio(dev->mem_start + baddr, skb->data, skb->len);
 
 	/* copy filler into RAM - in case we're filling up... 
 	   we're filling a bit more than necessary, but that doesn't harm
@@ -845,7 +845,7 @@
 		unsigned int destoffs = skb->len, l = strlen(fill);
 
 		while (destoffs < tmplen) {
-			isa_memcpy_to_io(dev->mem_start + baddr + destoffs, fill, l);
+			isa_memcpy_toio(dev->mem_start + baddr + destoffs, fill, l);
 			destoffs += l;
 		}
 	}
@@ -854,7 +854,7 @@
 	addr = priv->tdastart + (priv->nexttxdescr * sizeof(tda_t));
 	isa_memcpy_fromio(&tda, dev->mem_start + addr, sizeof(tda_t));
 	tda.length = tda.fraglength = tmplen;
-	isa_memcpy_to_io(dev->mem_start + addr, &tda, sizeof(tda_t));
+	isa_memcpy_toio(dev->mem_start + addr, &tda, sizeof(tda_t));
 
 	/* if there were no active descriptors, trigger the SONIC */
 	spin_lock_irqsave(&priv->lock, flags);
diff -Nru a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
--- a/drivers/net/irda/sa1100_ir.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/net/irda/sa1100_ir.c	Mon Nov  4 14:31:01 2002
@@ -42,6 +42,8 @@
 #include <asm/mach-types.h>
 
 #include <asm/arch/assabet.h>
+#include <asm/arch/h3600.h>
+#include <asm/arch/yopy.h>
 
 #ifndef GPIO_IRDA_FIR
 #define GPIO_IRDA_FIR		(0)
diff -Nru a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c
--- a/drivers/net/lasi_82596.c	Mon Nov  4 14:31:00 2002
+++ b/drivers/net/lasi_82596.c	Mon Nov  4 14:31:00 2002
@@ -93,7 +93,6 @@
 #include <asm/irq.h>
 
 #include <asm/pdc.h>
-#include <asm/gsc.h>
 #include <asm/cache.h>
 
 static char version[] __devinitdata =
diff -Nru a/drivers/net/mac8390.c b/drivers/net/mac8390.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/net/mac8390.c	Mon Nov  4 14:31:02 2002
@@ -0,0 +1,752 @@
+/* mac8390.c: New driver for 8390-based Nubus (or Nubus-alike)
+   Ethernet cards on Linux */
+/* Based on the former daynaport.c driver, by Alan Cox.  Some code
+   taken from or inspired by skeleton.c by Donald Becker, acenic.c by
+   Jes Sorensen, and ne2k-pci.c by Donald Becker and Paul Gortmaker.
+
+   This software may be used and distributed according to the terms of
+   the GNU Public License, incorporated herein by reference.  */
+
+/* 2000-02-28: support added for Dayna and Kinetics cards by 
+   A.G.deWijn@phys.uu.nl */
+/* 2000-04-04: support added for Dayna2 by bart@etpmod.phys.tue.nl */
+/* 2001-04-18: support for DaynaPort E/LC-M by rayk@knightsmanor.org */
+/* 2001-05-15: support for Cabletron ported from old daynaport driver
+ * and fixed access to Sonic Sys card which masquerades as a Farallon 
+ * by rayk@knightsmanor.org */
+
+#include <linux/version.h>
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/nubus.h>
+#include <linux/in.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/hwtest.h>
+#include <asm/macints.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include "8390.h"
+
+#if (LINUX_VERSION_CODE < 0x02030e)
+#define net_device device
+#endif
+
+#define WD_START_PG			0x00	/* First page of TX buffer */
+#define CABLETRON_RX_START_PG		0x00    /* First page of RX buffer */
+#define CABLETRON_RX_STOP_PG		0x30    /* Last page +1 of RX ring */
+#define CABLETRON_TX_START_PG		CABLETRON_RX_STOP_PG  /* First page of TX buffer */
+
+/* Unfortunately it seems we have to hardcode these for the moment */
+/* Shouldn't the card know about this? Does anyone know where to read it off the card? Do we trust the data provided by the card? */
+
+#define DAYNA_8390_BASE		0x80000
+#define DAYNA_8390_MEM		0x00000
+
+#define KINETICS_8390_BASE	0x80000
+#define KINETICS_8390_MEM	0x00000
+
+#define CABLETRON_8390_BASE	0x90000	
+#define CABLETRON_8390_MEM	0x00000
+
+enum mac8390_type {
+	MAC8390_NONE = -1,
+	MAC8390_APPLE,
+	MAC8390_ASANTE,
+	MAC8390_FARALLON,  /* Apple, Asante, and Farallon are all compatible */
+	MAC8390_CABLETRON,
+	MAC8390_DAYNA,
+	MAC8390_INTERLAN,
+	MAC8390_KINETICS,
+	MAC8390_FOCUS,
+	MAC8390_SONICSYS,
+	MAC8390_DAYNA2,
+	MAC8390_DAYNA3,
+};
+
+static const char * cardname[] = {
+	"apple",
+	"asante",
+	"farallon",
+	"cabletron",
+	"dayna",
+	"interlan",
+	"kinetics",
+	"focus",
+	"sonic systems",
+	"dayna2",
+	"dayna_lc",
+};
+
+static int word16[] = {
+	1, /* apple */
+	1, /* asante */
+	1, /* farallon */
+	1, /* cabletron */
+	0, /* dayna */
+	1, /* interlan */
+	0, /* kinetics */
+	1, /* focus (??) */
+	1, /* sonic systems  */
+	1, /* dayna2 */
+	1, /* dayna-lc */
+};
+
+/* on which cards do we use NuBus resources? */
+static int useresources[] = {
+	1, /* apple */
+	1, /* asante */
+	1, /* farallon */
+	0, /* cabletron */
+	0, /* dayna */
+	0, /* interlan */
+	0, /* kinetics */
+	0, /* focus (??) */
+	1, /* sonic systems */
+	1, /* dayna2 */
+	1, /* dayna-lc */
+};
+
+static const char __initdata * version =
+	"mac8390.c: v0.4 2001-05-15 David Huggins-Daines <dhd@debian.org> and others\n";
+		
+extern int mac8390_probe(struct net_device * dev);
+extern enum mac8390_type mac8390_ident(struct nubus_dev * dev);
+extern int mac8390_memsize(unsigned long membase);
+extern int mac8390_memtest(struct net_device * dev);
+extern int mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev,
+			   enum mac8390_type type);
+
+static int mac8390_open(struct net_device * dev);
+static int mac8390_close(struct net_device * dev);
+static void mac8390_no_reset(struct net_device *dev);
+
+/* Sane (32-bit chunk memory read/write) - Apple/Asante/Farallon do this*/
+static void sane_get_8390_hdr(struct net_device *dev,
+			      struct e8390_pkt_hdr *hdr, int ring_page);
+static void sane_block_input(struct net_device * dev, int count,
+			     struct sk_buff * skb, int ring_offset);
+static void sane_block_output(struct net_device * dev, int count,
+			      const unsigned char * buf, const int start_page);
+
+/* dayna_memcpy to and from card */
+static void dayna_memcpy_fromcard(struct net_device *dev, void *to,
+				int from, int count);
+static void dayna_memcpy_tocard(struct net_device *dev, int to,
+			      const void *from, int count);
+
+/* Dayna - Dayna/Kinetics use this */
+static void dayna_get_8390_hdr(struct net_device *dev,
+			       struct e8390_pkt_hdr *hdr, int ring_page);
+static void dayna_block_input(struct net_device *dev, int count,
+			      struct sk_buff *skb, int ring_offset);
+static void dayna_block_output(struct net_device *dev, int count,
+			       const unsigned char *buf, int start_page);
+
+#define memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
+#define memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
+
+/* Slow Sane (16-bit chunk memory read/write) Cabletron uses this */
+static void slow_sane_get_8390_hdr(struct net_device *dev,
+				   struct e8390_pkt_hdr *hdr, int ring_page);
+static void slow_sane_block_input(struct net_device *dev, int count,
+				  struct sk_buff *skb, int ring_offset);
+static void slow_sane_block_output(struct net_device *dev, int count,
+				   const unsigned char *buf, int start_page);
+static void word_memcpy_tocard(void *tp, const void *fp, int count);
+static void word_memcpy_fromcard(void *tp, const void *fp, int count);
+
+enum mac8390_type __init mac8390_ident(struct nubus_dev * dev)
+{
+	if (dev->dr_sw == NUBUS_DRSW_ASANTE)
+		return MAC8390_ASANTE;
+	if (dev->dr_sw == NUBUS_DRSW_FARALLON) 
+		return MAC8390_FARALLON;
+	if (dev->dr_sw == NUBUS_DRSW_KINETICS)
+		return MAC8390_KINETICS;
+	if (dev->dr_sw == NUBUS_DRSW_DAYNA)
+		return MAC8390_DAYNA;
+	if (dev->dr_sw == NUBUS_DRSW_DAYNA2)
+		return MAC8390_DAYNA2;
+	if (dev->dr_sw == NUBUS_DRSW_DAYNA_LC)
+		return MAC8390_DAYNA3;
+	if (dev->dr_hw == NUBUS_DRHW_CABLETRON)
+		return MAC8390_CABLETRON;
+	return MAC8390_NONE;
+}
+
+int __init mac8390_memsize(unsigned long membase)
+{
+	unsigned long flags;
+	int i, j;
+	
+	save_flags(flags); cli();
+	/* Check up to 32K in 4K increments */
+	for (i = 0; i < 8; i++) {
+		volatile unsigned short *m = (unsigned short *) (membase + (i * 0x1000));
+
+		/* Unwriteable - we have a fully decoded card and the
+		   RAM end located */
+		if (hwreg_present(m) == 0)
+			break;
+		
+		/* write a distinctive byte */
+		*m = 0xA5A0 | i;
+		/* check that we read back what we wrote */
+		if (*m != (0xA5A0 | i))
+			break;
+
+		/* check for partial decode and wrap */
+		for (j = 0; j < i; j++) {
+			volatile unsigned short *p = (unsigned short *) (membase + (j * 0x1000));
+			if (*p != (0xA5A0 | j))
+				break;
+ 		}
+ 	}
+	restore_flags(flags);
+	/* in any case, we stopped once we tried one block too many,
+           or once we reached 32K */
+ 	return i * 0x1000;
+}
+
+static int probed __initdata = 0;
+
+int __init mac8390_probe(struct net_device * dev)
+{
+	volatile unsigned short *i;
+	int boards_found = 0;
+	int version_disp = 0;
+	struct nubus_dev * ndev = NULL;
+	
+	struct nubus_dir dir;
+	struct nubus_dirent ent;
+	int offset;
+
+	enum mac8390_type cardtype;
+
+	if (probed)
+		return -ENODEV;
+	probed++;
+
+	/* probably should check for Nubus instead */
+
+	if (!MACH_IS_MAC)
+		return -ENODEV;
+
+	while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK, NUBUS_TYPE_ETHERNET, ndev))) {
+		
+		dev = NULL;
+		
+		if ((cardtype = mac8390_ident(ndev)) == MAC8390_NONE)
+			continue;
+
+		dev = init_etherdev(dev, 0);
+		if (dev == NULL) {
+			printk(KERN_ERR "Unable to allocate etherdev"
+					"structure!\n");
+			return -ENOMEM;
+		}
+
+		if (version_disp == 0) {
+			version_disp = 1;
+			printk(version);
+		}
+
+		dev->irq = SLOT2IRQ(ndev->board->slot);
+		/* This is getting to be a habit */
+		dev->base_addr = ndev->board->slot_addr | ((ndev->board->slot&0xf) << 20);
+
+		/* Get some Nubus info - we will trust the card's idea
+		   of where its memory and registers are. */
+
+		if (nubus_get_func_dir(ndev, &dir) == -1) {
+			printk(KERN_ERR "%s: Unable to get Nubus functional"
+					" directory for slot %X!\n",
+			       dev->name, ndev->board->slot);
+			continue;
+		}
+		
+		/* Get the MAC address */
+		if ((nubus_find_rsrc(&dir, NUBUS_RESID_MAC_ADDRESS, &ent)) == -1) {
+			printk(KERN_INFO "%s: Couldn't get MAC address!\n",
+					dev->name);
+			continue;
+		} else {
+			nubus_get_rsrc_mem(dev->dev_addr, &ent, 6);
+			/* Some Sonic Sys cards masquerade as Farallon */
+			if (cardtype == MAC8390_FARALLON && 
+					dev->dev_addr[0] == 0x0 &&
+					dev->dev_addr[1] == 0x40 &&
+					dev->dev_addr[2] == 0x10) {
+				/* This is really Sonic Sys card */
+				cardtype = MAC8390_SONICSYS;
+			}
+		}
+		
+		if (useresources[cardtype] == 1) {
+			nubus_rewinddir(&dir);
+			if (nubus_find_rsrc(&dir, NUBUS_RESID_MINOR_BASEOS, &ent) == -1) {
+				printk(KERN_ERR "%s: Memory offset resource"
+						" for slot %X not found!\n",
+				       dev->name, ndev->board->slot);
+				continue;
+			}
+			nubus_get_rsrc_mem(&offset, &ent, 4);
+			dev->mem_start = dev->base_addr + offset;
+			/* yes, this is how the Apple driver does it */
+			dev->base_addr = dev->mem_start + 0x10000;
+			nubus_rewinddir(&dir);
+			if (nubus_find_rsrc(&dir, NUBUS_RESID_MINOR_LENGTH, &ent) == -1) {
+				printk(KERN_INFO "%s: Memory length resource"
+						 " for slot %X not found"
+						 ", probing\n",
+				       dev->name, ndev->board->slot);
+				offset = mac8390_memsize(dev->mem_start);
+				} else {
+					nubus_get_rsrc_mem(&offset, &ent, 4);
+				}
+			dev->mem_end = dev->mem_start + offset;
+		} else {
+			switch (cardtype) {
+				case MAC8390_KINETICS:
+				case MAC8390_DAYNA: /* it's the same */
+					dev->base_addr = 
+						(int)(ndev->board->slot_addr +
+						DAYNA_8390_BASE);
+					dev->mem_start = 
+						(int)(ndev->board->slot_addr +
+						DAYNA_8390_MEM);
+					dev->mem_end =
+						dev->mem_start +
+						mac8390_memsize(dev->mem_start);
+					break;
+				case MAC8390_CABLETRON:
+					dev->base_addr =
+						(int)(ndev->board->slot_addr +
+						CABLETRON_8390_BASE);
+					dev->mem_start =
+						(int)(ndev->board->slot_addr +
+						CABLETRON_8390_MEM);
+					/* The base address is unreadable if 0x00
+					 * has been written to the command register
+					 * Reset the chip by writing E8390_NODMA +
+					 *   E8390_PAGE0 + E8390_STOP just to be
+					 *   sure
+					 */
+					i = (void *)dev->base_addr;
+					*i = 0x21;
+					dev->mem_end = 
+						dev->mem_start +
+						mac8390_memsize(dev->mem_start);
+					break;
+					
+				default:
+					printk(KERN_ERR "Card type %s is"
+							" unsupported, sorry\n",
+					       cardname[cardtype]);
+					return -ENODEV;
+			}
+		}
+
+		/* Do the nasty 8390 stuff */
+		if (mac8390_initdev(dev, ndev, cardtype))
+			continue;
+		boards_found++;
+	}
+
+	/* We're outta here */
+	if (boards_found > 0)
+		return 0;
+	else
+		return -ENODEV;
+}
+
+#ifdef MODULE
+#if LINUX_VERSION_CODE > 0x20118
+MODULE_AUTHOR("David Huggins-Daines <dhd@debian.org> and others");
+MODULE_DESCRIPTION("Macintosh NS8390-based Nubus Ethernet driver");
+MODUEL_LICENSE("GPL");
+#endif
+
+int init_module(void)
+{
+	if (mac8390_probe(NULL)) {
+		printk(KERN_NOTICE "mac8390.c: No useable cards found, driver NOT installed.\n");
+		return -ENODEV;
+	}
+	lock_8390_module();
+	return 0;
+}
+
+void cleanup_module(void)
+{
+	/* FIXME: should probably keep track of net_device structs
+           somewhere and unregister them here? */
+	unlock_8390_module();
+}
+
+#endif /* MODULE */
+
+int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev,
+			    enum mac8390_type type)
+{
+	static u32 fwrd4_offsets[16]={
+		0,      4,      8,      12,
+		16,     20,     24,     28,
+		32,     36,     40,     44,
+		48,     52,     56,     60
+	};
+	static u32 back4_offsets[16]={
+		60,     56,     52,     48,
+		44,     40,     36,     32,
+		28,     24,     20,     16,
+		12,     8,      4,      0
+	};
+	static u32 fwrd2_offsets[16]={
+		0,      2,      4,      6,
+		8,     10,     12,     14,
+		16,    18,     20,     22,
+		24,    26,     28,     30
+	};
+
+	int access_bitmode;
+	
+	/* 8390 specific init for dev - allocates dev->priv */
+	if (ethdev_init(dev)) {
+		printk(KERN_ERR "%s: Unable to allocate memory for dev->priv!\n", dev->name);
+		return -ENOMEM;
+	}
+
+	/* Now fill in our stuff */
+	dev->open = &mac8390_open;
+	dev->stop = &mac8390_close;
+
+	/* GAR, ei_status is actually a macro even though it looks global */
+	ei_status.name = cardname[type];
+	ei_status.word16 = word16[type];
+
+	/* Cabletron's TX/RX buffers are backwards */
+	if (type == MAC8390_CABLETRON) {
+               ei_status.tx_start_page = CABLETRON_TX_START_PG;
+               ei_status.rx_start_page = CABLETRON_RX_START_PG;
+               ei_status.stop_page = CABLETRON_RX_STOP_PG;
+               dev->rmem_start = dev->mem_start;
+               dev->rmem_end = dev->mem_start + CABLETRON_RX_STOP_PG*256;
+	} else {
+               ei_status.tx_start_page = WD_START_PG;
+               ei_status.rx_start_page = WD_START_PG + TX_PAGES;
+               ei_status.stop_page = (dev->mem_end - dev->mem_start)/256;
+               dev->rmem_start = dev->mem_start + TX_PAGES*256;
+               dev->rmem_end = dev->mem_end;
+	}
+	
+	/* Fill in model-specific information and functions */
+	switch(type) {
+	case MAC8390_SONICSYS:
+		/* 16 bit card, register map is reversed */
+		ei_status.reset_8390 = &mac8390_no_reset;
+		ei_status.block_input = &slow_sane_block_input;
+		ei_status.block_output = &slow_sane_block_output;
+		ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
+		ei_status.reg_offset = back4_offsets;
+		access_bitmode = 0;
+		break;
+	case MAC8390_FARALLON:
+	case MAC8390_APPLE:
+	case MAC8390_ASANTE:
+	case MAC8390_DAYNA2:
+	case MAC8390_DAYNA3:
+		/* 32 bit card, register map is reversed */
+		/* sane */
+		ei_status.reset_8390 = &mac8390_no_reset;
+		ei_status.block_input = &sane_block_input;
+		ei_status.block_output = &sane_block_output;
+		ei_status.get_8390_hdr = &sane_get_8390_hdr;
+		ei_status.reg_offset = back4_offsets;
+		access_bitmode = 1;
+		break;
+	case MAC8390_CABLETRON:
+		/* 16 bit card, register map is short forward */
+		ei_status.reset_8390 = &mac8390_no_reset;
+		ei_status.block_input = &slow_sane_block_input;
+		ei_status.block_output = &slow_sane_block_output;
+		ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
+		ei_status.reg_offset = fwrd2_offsets;
+		access_bitmode = 0;
+		break;
+	case MAC8390_DAYNA:
+	case MAC8390_KINETICS:
+		/* 16 bit memory */
+		/* dayna and similar */
+		ei_status.reset_8390 = &mac8390_no_reset;
+		ei_status.block_input = &dayna_block_input;
+		ei_status.block_output = &dayna_block_output;
+		ei_status.get_8390_hdr = &dayna_get_8390_hdr;
+		ei_status.reg_offset = fwrd4_offsets;
+		access_bitmode = 0;
+		break;
+	default:
+		printk(KERN_ERR "Card type %s is unsupported, sorry\n", cardname[type]);
+		return -ENODEV;
+	}
+		
+	NS8390_init(dev, 0);
+
+	/* Good, done, now spit out some messages */
+	printk(KERN_INFO "%s: %s in slot %X (type %s)\n",
+		   dev->name, ndev->board->name, ndev->board->slot, cardname[type]);
+	printk(KERN_INFO "MAC ");
+	{
+		int i;
+		for (i = 0; i < 6; i++) {
+			printk("%2.2x", dev->dev_addr[i]);
+			if (i < 5)
+				printk(":");
+		}
+	}
+	printk(" IRQ %d, shared memory at %#lx-%#lx,  %d-bit access.\n",
+		   dev->irq, dev->mem_start, dev->mem_end-1, 
+		   access_bitmode?32:16);
+	return 0;
+}
+
+static int mac8390_open(struct net_device *dev)
+{
+	ei_open(dev);
+	if (request_irq(dev->irq, ei_interrupt, 0, "8390 Ethernet", dev)) {
+		printk ("%s: unable to get IRQ %d.\n", dev->name, dev->irq);
+		return -EAGAIN;
+	}	
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+static int mac8390_close(struct net_device *dev)
+{
+	free_irq(dev->irq, dev);
+	ei_close(dev);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static void mac8390_no_reset(struct net_device *dev)
+{
+	ei_status.txing = 0;
+	if (ei_debug > 1)
+		printk("reset not supported\n");
+	return;
+}
+
+/* dayna_memcpy_fromio/dayna_memcpy_toio */
+/* directly from daynaport.c by Alan Cox */
+static void dayna_memcpy_fromcard(struct net_device *dev, void *to, int from, int count)
+{
+	volatile unsigned short *ptr;
+	unsigned short *target=to;
+	from<<=1;	/* word, skip overhead */
+	ptr=(unsigned short *)(dev->mem_start+from);
+	/* Leading byte? */
+	if (from&2) {
+		*((char *)target)++ = *(((char *)ptr++)-1);
+		count--;
+	}
+	while(count>=2)
+	{
+		*target++=*ptr++;	/* Copy and */
+		ptr++;			/* skip cruft */
+		count-=2;
+	}
+	/* Trailing byte? */
+	if(count)
+	{
+		/* Big endian */
+		unsigned short v=*ptr;
+		*((char *)target)=v>>8;
+	}
+}
+
+static void dayna_memcpy_tocard(struct net_device *dev, int to, const void *from, int count)
+{
+	volatile unsigned short *ptr;
+	const unsigned short *src=from;
+	to<<=1;	/* word, skip overhead */
+	ptr=(unsigned short *)(dev->mem_start+to);
+	/* Leading byte? */
+	if (to&2) { /* avoid a byte write (stomps on other data) */
+		ptr[-1] = (ptr[-1]&0xFF00)|*((unsigned char *)src)++;
+		ptr++;
+		count--;
+	}
+	while(count>=2)
+	{
+		*ptr++=*src++;		/* Copy and */
+		ptr++;			/* skip cruft */
+		count-=2;
+	}
+	/* Trailing byte? */
+	if(count)
+	{
+		/* Big endian */
+		unsigned short v=*src;
+		/* card doesn't like byte writes */
+		*ptr=(*ptr&0x00FF)|(v&0xFF00);
+	}
+}
+
+/* sane block input/output */
+static void sane_get_8390_hdr(struct net_device *dev,
+			      struct e8390_pkt_hdr *hdr, int ring_page)
+{
+	unsigned long hdr_start = (ring_page - WD_START_PG)<<8;
+	memcpy_fromio((void *)hdr, (char *)dev->mem_start + hdr_start, 4);
+	/* Fix endianness */
+	hdr->count = swab16(hdr->count);
+}
+
+static void sane_block_input(struct net_device *dev, int count,
+			     struct sk_buff *skb, int ring_offset)
+{
+	unsigned long xfer_base = ring_offset - (WD_START_PG<<8);
+	unsigned long xfer_start = xfer_base + dev->mem_start;
+
+	if (xfer_start + count > dev->rmem_end) {
+		/* We must wrap the input move. */
+		int semi_count = dev->rmem_end - xfer_start;
+		memcpy_fromio(skb->data, (char *)dev->mem_start + xfer_base, semi_count);
+		count -= semi_count;
+		memcpy_toio(skb->data + semi_count, (char *)dev->rmem_start, count);
+	} else {
+		memcpy_fromio(skb->data, (char *)dev->mem_start + xfer_base, count);
+	}
+}
+
+static void sane_block_output(struct net_device *dev, int count,
+			      const unsigned char *buf, int start_page)
+{
+	long shmem = (start_page - WD_START_PG)<<8;
+	
+	memcpy_toio((char *)dev->mem_start + shmem, buf, count);
+}
+
+/* dayna block input/output */
+static void dayna_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
+{
+	unsigned long hdr_start = (ring_page - WD_START_PG)<<8;
+
+	dayna_memcpy_fromcard(dev, (void *)hdr, hdr_start, 4);
+	/* Fix endianness */
+	hdr->count=(hdr->count&0xFF)<<8|(hdr->count>>8);
+}
+
+static void dayna_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
+{
+	unsigned long xfer_base = ring_offset - (WD_START_PG<<8);
+	unsigned long xfer_start = xfer_base+dev->mem_start;
+
+	/* Note the offset math is done in card memory space which is word
+	   per long onto our space. */
+	 
+	if (xfer_start + count > dev->rmem_end) 
+	{
+		/* We must wrap the input move. */
+		int semi_count = dev->rmem_end - xfer_start;
+		dayna_memcpy_fromcard(dev, skb->data, xfer_base, semi_count);
+		count -= semi_count;
+		dayna_memcpy_fromcard(dev, skb->data + semi_count, 
+			dev->rmem_start - dev->mem_start, count);
+	}
+	else
+	{
+		dayna_memcpy_fromcard(dev, skb->data, xfer_base, count);
+	}
+}
+
+static void dayna_block_output(struct net_device *dev, int count, const unsigned char *buf,
+				int start_page)
+{
+	long shmem = (start_page - WD_START_PG)<<8;
+	
+	dayna_memcpy_tocard(dev, shmem, buf, count);
+}
+
+/* Cabletron block I/O */
+static void slow_sane_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, 
+	int ring_page)
+{
+	unsigned long hdr_start = (ring_page - WD_START_PG)<<8;
+	word_memcpy_fromcard((void *)hdr, (char *)dev->mem_start+hdr_start, 4);
+	/* Register endianism - fix here rather than 8390.c */
+	hdr->count = (hdr->count&0xFF)<<8|(hdr->count>>8);
+}
+
+static void slow_sane_block_input(struct net_device *dev, int count, struct sk_buff *skb,
+	int ring_offset)
+{
+	unsigned long xfer_base = ring_offset - (WD_START_PG<<8);
+	unsigned long xfer_start = xfer_base+dev->mem_start;
+
+	if (xfer_start + count > dev->rmem_end)
+	{
+		/* We must wrap the input move. */
+		int semi_count = dev->rmem_end - xfer_start;
+		word_memcpy_fromcard(skb->data, (char *)dev->mem_start +
+			xfer_base, semi_count);
+		count -= semi_count;
+		word_memcpy_fromcard(skb->data + semi_count,
+			(char *)dev->rmem_start, count);
+	}
+	else
+	{
+		word_memcpy_fromcard(skb->data, (char *)dev->mem_start +
+			xfer_base, count);
+	}
+}
+
+static void slow_sane_block_output(struct net_device *dev, int count, const unsigned char *buf,
+	int start_page)
+{
+	long shmem = (start_page - WD_START_PG)<<8;
+
+	word_memcpy_tocard((char *)dev->mem_start + shmem, buf, count);
+}
+
+static void word_memcpy_tocard(void *tp, const void *fp, int count)
+{
+	volatile unsigned short *to = tp;
+	const unsigned short *from = fp;
+
+	count++;
+	count/=2;
+
+	while(count--)
+		*to++=*from++;
+}
+
+static void word_memcpy_fromcard(void *tp, const void *fp, int count)
+{
+	unsigned short *to = tp;
+	const volatile unsigned short *from = fp;
+
+	count++;
+	count/=2;
+
+	while(count--)
+		*to++=*from++;
+}
+
+	
diff -Nru a/drivers/net/sun3_82586.c b/drivers/net/sun3_82586.c
--- a/drivers/net/sun3_82586.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/net/sun3_82586.c	Mon Nov  4 14:31:02 2002
@@ -279,14 +279,14 @@
 
 int __init sun3_82586_probe(struct net_device *dev)
 {
-	unsigned long ioaddr, iopte;
+	unsigned long ioaddr;
 	static int found = 0;
 	
-	/* check that this machine has an onboard lance */
+	/* check that this machine has an onboard 82586 */
 	switch(idprom->id_machtype) {
 	case SM_SUN3|SM_3_160:
 	case SM_SUN3|SM_3_260:
-		/* these machines have lance */
+		/* these machines have 82586 */
 		break;
 
 	default:
@@ -296,22 +296,8 @@
 	if(found)
 		return -ENODEV;
 	
-	for(ioaddr = 0xfe00000; ioaddr < (0xfe00000 +
-	    SUN3_PMEG_SIZE); ioaddr += SUN3_PTE_SIZE) {
-
-		iopte = sun3_get_pte(ioaddr);
-		if(!(iopte & SUN3_PAGE_TYPE_IO)) /* this an io page? */
-			continue;
-
-		if(((iopte & SUN3_PAGE_PGNUM_MASK) << PAGE_SHIFT) ==
-		   IE_OBIO) {
-			found = 1;
-			break;
-		}
-	}
-	
-	if(!found)
-		return 0;
+	ioaddr = (unsigned long)ioremap(IE_OBIO, PAGE_SIZE);
+	found = 1;
 	
 	SET_MODULE_OWNER(dev);
 
diff -Nru a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c
--- a/drivers/net/sun3lance.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/net/sun3lance.c	Mon Nov  4 14:31:02 2002
@@ -279,33 +279,16 @@
 
 static int __init lance_probe( struct net_device *dev)
 {	
-	unsigned long ioaddr, iopte;
+	unsigned long ioaddr;
 	
 	struct lance_private	*lp;
 	int 			i;
 	static int 		did_version;
-	int found = 0;
 	volatile unsigned short *ioaddr_probe;
 	unsigned short tmp1, tmp2;
 
 #ifdef CONFIG_SUN3
-	/* LANCE_OBIO can be found within the IO pmeg with some effort */
-	for(ioaddr = 0xfe00000; ioaddr < (0xfe00000 +
-	    SUN3_PMEG_SIZE); ioaddr += SUN3_PTE_SIZE) {
-
-		iopte = sun3_get_pte(ioaddr);
-		if(!(iopte & SUN3_PAGE_TYPE_IO)) /* this an io page? */
-			continue;
-
-		if(((iopte & SUN3_PAGE_PGNUM_MASK) << PAGE_SHIFT) ==
-		   LANCE_OBIO) {
-			found = 1;
-			break;
-		}
-	}
-	
-	if(!found)
-		return 0;
+	ioaddr = (unsigned long)ioremap(LANCE_OBIO, PAGE_SIZE);
 #else
 	ioaddr = SUN3X_LANCE;
 #endif
diff -Nru a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
--- a/drivers/net/tulip/de2104x.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/net/tulip/de2104x.c	Mon Nov  4 14:31:02 2002
@@ -2216,7 +2216,7 @@
 	.name		= DRV_NAME,
 	.id_table	= de_pci_tbl,
 	.probe		= de_init_one,
-	.remove		= de_remove_one,
+	.remove		= __devexit_p(de_remove_one),
 #ifdef CONFIG_PM
 	.suspend	= de_suspend,
 	.resume		= de_resume,
diff -Nru a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
--- a/drivers/net/tulip/de4x5.c	Mon Nov  4 14:31:00 2002
+++ b/drivers/net/tulip/de4x5.c	Mon Nov  4 14:31:00 2002
@@ -874,6 +874,7 @@
     struct de4x5_srom srom;
     int autosense;
     int useSROM;
+    struct pci_dev *pdev;
 } bus;
 
 /*
@@ -1151,8 +1152,7 @@
     if (lp->bus == EISA) {
 	outb(WAKEUP, PCI_CFPM);
     } else {
-	pcibios_write_config_byte(lp->bus_num, lp->device << 3, 
-				  PCI_CFDA_PSM, WAKEUP);
+	pci_write_config_byte(lp->pdev, PCI_CFDA_PSM, WAKEUP);
     }
     mdelay(10);
 
@@ -2222,11 +2222,12 @@
 	}
 
 	/* Get the chip configuration revision register */
-	pcibios_read_config_dword(pb, pdev->devfn, PCI_REVISION_ID, &cfrv);
+	pci_read_config_dword(pdev, PCI_REVISION_ID, &cfrv);
 
 	/* Set the device number information */
 	lp->device = dev_num;
 	lp->bus_num = pb;
+	lp->pdev = pdev;
 	    
 	/* Set the chipset information */
 	if (is_DC2114x) {
@@ -2242,27 +2243,27 @@
 	if ((irq == 0) || (irq == 0xff) || ((int)irq == -1)) continue;
 	    
 	/* Check if I/O accesses and Bus Mastering are enabled */
-	pcibios_read_config_word(pb, pdev->devfn, PCI_COMMAND, &status);
+	pci_read_config_word(pdev, PCI_COMMAND, &status);
 #ifdef __powerpc__
 	if (!(status & PCI_COMMAND_IO)) {
 	    status |= PCI_COMMAND_IO;
-	    pcibios_write_config_word(pb, pdev->devfn, PCI_COMMAND, status);
-	    pcibios_read_config_word(pb, pdev->devfn, PCI_COMMAND, &status);
+	    pci_write_config_word(pdev, PCI_COMMAND, status);
+	    pci_read_config_word(pdev, PCI_COMMAND, &status);
 	}
 #endif /* __powerpc__ */
 	if (!(status & PCI_COMMAND_IO)) continue;
 
 	if (!(status & PCI_COMMAND_MASTER)) {
 	    status |= PCI_COMMAND_MASTER;
-	    pcibios_write_config_word(pb, pdev->devfn, PCI_COMMAND, status);
-	    pcibios_read_config_word(pb, pdev->devfn, PCI_COMMAND, &status);
+	    pci_write_config_word(pdev, PCI_COMMAND, status);
+	    pci_read_config_word(pdev, PCI_COMMAND, &status);
 	}
 	if (!(status & PCI_COMMAND_MASTER)) continue;
 
 	/* Check the latency timer for values >= 0x60 */
-	pcibios_read_config_byte(pb, pdev->devfn, PCI_LATENCY_TIMER, &timer);
+	pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &timer);
 	if (timer < 0x60) {
-	    pcibios_write_config_byte(pb, pdev->devfn, PCI_LATENCY_TIMER, 0x60);
+	    pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x60);
 	}
 
 	DevicePresent(DE4X5_APROM);
@@ -2314,7 +2315,7 @@
 
 	/* Get the chip configuration revision register */
 	pb = this_dev->bus->number;
-	pcibios_read_config_dword(pb, this_dev->devfn, PCI_REVISION_ID, &cfrv);
+	pci_read_config_dword(this_dev, PCI_REVISION_ID, &cfrv);
 
 	/* Set the device number information */
 	lp->device = PCI_SLOT(this_dev->devfn);
@@ -2334,7 +2335,7 @@
 	if ((irq == 0) || (irq == 0xff) || ((int)irq == -1)) continue;
 	    
 	/* Check if I/O accesses are enabled */
-	pcibios_read_config_word(pb, this_dev->devfn, PCI_COMMAND, &status);
+	pci_read_config_word(this_dev, PCI_COMMAND, &status);
 	if (!(status & PCI_COMMAND_IO)) continue;
 
 	/* Search for a valid SROM attached to this DECchip */
@@ -5325,20 +5326,17 @@
     } else {
 	switch(state) {
 	  case WAKEUP:
-	    pcibios_write_config_byte(lp->bus_num, lp->device << 3, 
-				      PCI_CFDA_PSM, WAKEUP);
+	    pci_write_config_byte(lp->pdev, PCI_CFDA_PSM, WAKEUP);
 	    mdelay(10);
 	    break;
 
 	  case SNOOZE:
-	    pcibios_write_config_byte(lp->bus_num, lp->device << 3, 
-				      PCI_CFDA_PSM, SNOOZE);
+	    pci_write_config_byte(lp->pdev, PCI_CFDA_PSM, SNOOZE);
 	    break;
 
 	  case SLEEP:
 	    outl(0, DE4X5_SICR);
-	    pcibios_write_config_byte(lp->bus_num, lp->device << 3, 
-				      PCI_CFDA_PSM, SLEEP);
+	    pci_write_config_byte(lp->pdev, PCI_CFDA_PSM, SLEEP);
 	    break;
 	}
     }
diff -Nru a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
--- a/drivers/net/tulip/winbond-840.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/net/tulip/winbond-840.c	Mon Nov  4 14:31:01 2002
@@ -1428,8 +1428,9 @@
 		memset(mc_filter, 0, sizeof(mc_filter));
 		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
 			 i++, mclist = mclist->next) {
-			set_bit((ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26) ^ 0x3F,
-					mc_filter);
+			int filterbit = (ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26) ^ 0x3F;
+			filterbit &= 0x3f;
+			mc_filter[filterbit >> 5] |= cpu_to_le32(1 << (filterbit & 31));
 		}
 		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
 	}
diff -Nru a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
--- a/drivers/net/wireless/airo.c	Mon Nov  4 14:31:00 2002
+++ b/drivers/net/wireless/airo.c	Mon Nov  4 14:31:00 2002
@@ -97,12 +97,12 @@
    infront of the label, that statistic will not be included in the list
    of statistics in the /proc filesystem */
 
-#define IGNLABEL 0&(int)
+#define IGNLABEL(comment) 0
 static char *statsLabels[] = {
 	"RxOverrun",
-	IGNLABEL "RxPlcpCrcErr",
-	IGNLABEL "RxPlcpFormatErr",
-	IGNLABEL "RxPlcpLengthErr",
+	IGNLABEL("RxPlcpCrcErr"),
+	IGNLABEL("RxPlcpFormatErr"),
+	IGNLABEL("RxPlcpLengthErr"),
 	"RxMacCrcErr",
 	"RxMacCrcOk",
 	"RxWepErr",
@@ -146,15 +146,15 @@
 	"HostRxBc",
 	"HostRxUc",
 	"HostRxDiscard",
-	IGNLABEL "HmacTxMc",
-	IGNLABEL "HmacTxBc",
-	IGNLABEL "HmacTxUc",
-	IGNLABEL "HmacTxFail",
-	IGNLABEL "HmacRxMc",
-	IGNLABEL "HmacRxBc",
-	IGNLABEL "HmacRxUc",
-	IGNLABEL "HmacRxDiscard",
-	IGNLABEL "HmacRxAccepted",
+	IGNLABEL("HmacTxMc"),
+	IGNLABEL("HmacTxBc"),
+	IGNLABEL("HmacTxUc"),
+	IGNLABEL("HmacTxFail"),
+	IGNLABEL("HmacRxMc"),
+	IGNLABEL("HmacRxBc"),
+	IGNLABEL("HmacRxUc"),
+	IGNLABEL("HmacRxDiscard"),
+	IGNLABEL("HmacRxAccepted"),
 	"SsidMismatch",
 	"ApMismatch",
 	"RatesMismatch",
@@ -162,26 +162,26 @@
 	"AuthTimeout",
 	"AssocReject",
 	"AssocTimeout",
-	IGNLABEL "ReasonOutsideTable",
-	IGNLABEL "ReasonStatus1",
-	IGNLABEL "ReasonStatus2",
-	IGNLABEL "ReasonStatus3",
-	IGNLABEL "ReasonStatus4",
-	IGNLABEL "ReasonStatus5",
-	IGNLABEL "ReasonStatus6",
-	IGNLABEL "ReasonStatus7",
-	IGNLABEL "ReasonStatus8",
-	IGNLABEL "ReasonStatus9",
-	IGNLABEL "ReasonStatus10",
-	IGNLABEL "ReasonStatus11",
-	IGNLABEL "ReasonStatus12",
-	IGNLABEL "ReasonStatus13",
-	IGNLABEL "ReasonStatus14",
-	IGNLABEL "ReasonStatus15",
-	IGNLABEL "ReasonStatus16",
-	IGNLABEL "ReasonStatus17",
-	IGNLABEL "ReasonStatus18",
-	IGNLABEL "ReasonStatus19",
+	IGNLABEL("ReasonOutsideTable"),
+	IGNLABEL("ReasonStatus1"),
+	IGNLABEL("ReasonStatus2"),
+	IGNLABEL("ReasonStatus3"),
+	IGNLABEL("ReasonStatus4"),
+	IGNLABEL("ReasonStatus5"),
+	IGNLABEL("ReasonStatus6"),
+	IGNLABEL("ReasonStatus7"),
+	IGNLABEL("ReasonStatus8"),
+	IGNLABEL("ReasonStatus9"),
+	IGNLABEL("ReasonStatus10"),
+	IGNLABEL("ReasonStatus11"),
+	IGNLABEL("ReasonStatus12"),
+	IGNLABEL("ReasonStatus13"),
+	IGNLABEL("ReasonStatus14"),
+	IGNLABEL("ReasonStatus15"),
+	IGNLABEL("ReasonStatus16"),
+	IGNLABEL("ReasonStatus17"),
+	IGNLABEL("ReasonStatus18"),
+	IGNLABEL("ReasonStatus19"),
 	"RxMan",
 	"TxMan",
 	"RxRefresh",
diff -Nru a/drivers/nubus/nubus.c b/drivers/nubus/nubus.c
--- a/drivers/nubus/nubus.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/nubus/nubus.c	Mon Nov  4 14:31:01 2002
@@ -8,7 +8,6 @@
  */
 
 #include <linux/config.h>
-#include <linux/ptrace.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
diff -Nru a/drivers/nubus/proc.c b/drivers/nubus/proc.c
--- a/drivers/nubus/proc.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/nubus/proc.c	Mon Nov  4 14:31:02 2002
@@ -17,7 +17,6 @@
    icons) these files will provide "cooked" data.  Otherwise they will
    simply provide raw access (read-only of course) to the ROM.  */
 
-#include <linux/ptrace.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/nubus.h>
diff -Nru a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
--- a/drivers/oprofile/buffer_sync.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/oprofile/buffer_sync.c	Mon Nov  4 14:31:01 2002
@@ -118,13 +118,13 @@
  * because we cannot reach this code without at least one
  * dcookie user still being registered (namely, the reader
  * of the event buffer). */
-static inline u32 fast_get_dcookie(struct dentry * dentry,
+static inline unsigned long fast_get_dcookie(struct dentry * dentry,
 	struct vfsmount * vfsmnt)
 {
-	u32 cookie;
+	unsigned long cookie;
  
 	if (dentry->d_cookie)
-		return (u32)dentry;
+		return (unsigned long)dentry;
 	get_dcookie(dentry, vfsmnt, &cookie);
 	return cookie;
 }
@@ -135,9 +135,9 @@
  * not strictly necessary but allows oprofile to associate
  * shared-library samples with particular applications
  */
-static u32 get_exec_dcookie(struct mm_struct * mm)
+static unsigned long get_exec_dcookie(struct mm_struct * mm)
 {
-	u32 cookie = 0;
+	unsigned long cookie = 0;
 	struct vm_area_struct * vma;
  
 	if (!mm)
@@ -163,9 +163,9 @@
  * sure to do this lookup before a mm->mmap modification happens so
  * we don't lose track.
  */
-static u32 lookup_dcookie(struct mm_struct * mm, unsigned long addr, off_t * offset)
+static unsigned long lookup_dcookie(struct mm_struct * mm, unsigned long addr, off_t * offset)
 {
-	u32 cookie = 0;
+	unsigned long cookie = 0;
 	struct vm_area_struct * vma;
 
 	for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) {
@@ -188,7 +188,7 @@
 }
 
 
-static u32 last_cookie = ~0UL;
+static unsigned long last_cookie = ~0UL;
  
 static void add_cpu_switch(int i)
 {
@@ -199,7 +199,7 @@
 }
 
  
-static void add_ctx_switch(pid_t pid, u32 cookie)
+static void add_ctx_switch(pid_t pid, unsigned long cookie)
 {
 	add_event_entry(ESCAPE_CODE);
 	add_event_entry(CTX_SWITCH_CODE); 
@@ -208,7 +208,7 @@
 }
 
  
-static void add_cookie_switch(u32 cookie)
+static void add_cookie_switch(unsigned long cookie)
 {
 	add_event_entry(ESCAPE_CODE);
 	add_event_entry(COOKIE_SWITCH_CODE);
@@ -225,7 +225,7 @@
 
 static void add_us_sample(struct mm_struct * mm, struct op_sample * s)
 {
-	u32 cookie;
+	unsigned long cookie;
 	off_t offset;
  
  	cookie = lookup_dcookie(mm, s->eip, &offset);
@@ -317,7 +317,7 @@
 {
 	struct mm_struct * mm = 0;
 	struct task_struct * new;
-	u32 cookie;
+	unsigned long cookie;
 	int i;
  
 	for (i=0; i < cpu_buf->pos; ++i) {
diff -Nru a/drivers/parisc/Kconfig b/drivers/parisc/Kconfig
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/parisc/Kconfig	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,103 @@
+menu "Bus options (PCI, PCMCIA, EISA, GSC, ISA)"
+
+config GSC
+	bool "VSC/GSC/HSC bus support"
+	default y
+	help
+	  The VSC, GSC and HSC busses were used from the earliest 700-series
+	  workstations up to and including the C360/J2240 workstations.  They
+	  were also used in servers from the E-class to the K-class.  They
+	  are not found in B1000, C3000, J5000, A500, L1000, N4000 and upwards.
+	  If in doubt, say "Y".
+
+config IOMMU_CCIO
+	bool "U2/Uturn I/O MMU"
+	depends on GSC
+	help
+	  Say Y here to enable DMA management routines for the first
+	  generation of PA-RISC cache-coherent machines.  Programs the
+	  U2/Uturn chip in "Virtual Mode" and use the I/O MMU.
+
+config GSC_LASI
+	bool "Lasi I/O support"
+	depends on GSC
+	help
+	  Say Y here to directly support the Lasi controller chip found on
+	  PA-RISC workstations.  Linux-oriented documentation for this chip
+	  can be found at <http://www.parisc-linux.org/documentation/>.
+
+config GSC_WAX
+	bool "Wax I/O support"
+	depends on GSC
+	help
+	  Say Y here to support the Wax GSC to EISA Bridge found in some older
+	  systems, including B/C/D/R class.  Some machines use Wax for other
+	  purposes, such as providing one of the serial ports or being an
+	  interface chip for an X.25 GSC card.
+
+config EISA
+	bool "EISA support"
+	depends on GSC
+	help
+	  Say Y here if you have an EISA bus in your machine.  This code
+	  supports both the Mongoose & Wax EISA adapters.  It is sadly
+	  incomplete and lacks support for card-to-host DMA.
+
+config ISA
+	bool
+	depends on EISA
+
+config PCI
+	bool "PCI support"
+	help
+	  All recent HP machines have PCI slots, and you should say Y here
+	  if you have a recent machine.  If you are convinced you do not have
+	  PCI slots in your machine (eg a 712), then you may say "N" here.
+	  Beware that some GSC cards have a Dino onboard and PCI inside them,
+	  so it may be safest to say "Y" anyway.
+
+config GSC_DINO
+	bool "GSCtoPCI/Dino PCI support"
+	depends on PCI && GSC
+	help
+	  Say Y here to support the Dino & Cujo GSC to PCI bridges found in
+	  machines from the B132 to the C360, the J2240 and the A180.  Some
+	  GSC/HSC cards (eg gigabit & dual 100 Mbit Ethernet) have a Dino on
+	  the card, and you also need to say Y here if you have such a card.
+	  If in doubt, say Y.
+
+config PCI_LBA
+	bool "LBA/Elroy PCI support"
+	depends on PCI
+	help
+	  Say Y here to support the Elroy PCI Lower Bus Adapter.  This is
+	  present on B, C, J, L and N-class machines with 4-digit model
+	  numbers and the A400/A500.
+
+config IOSAPIC
+	bool
+	depends on PCI_LBA
+	default y
+
+config IOMMU_SBA
+	bool
+	depends on PCI_LBA
+	default y
+
+#config PCI_EPIC
+#	bool "EPIC/SAGA PCI support"
+#	depends on PCI
+
+config SUPERIO
+	bool
+	depends on PCI
+	help
+	  Say Y here to support the SuperIO chip found in Bxxxx, C3xxx and
+	  J5xxx+ machines.
+
+source "drivers/pci/Kconfig"
+
+config CHASSIS_LCD_LED
+	bool "Chassis LCD and LED support"
+
+endmenu
diff -Nru a/drivers/parisc/Makefile b/drivers/parisc/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/parisc/Makefile	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,25 @@
+#
+# Makefile for most of the non-PCI devices in PA-RISC machines
+#
+
+export-objs	:= gsc.o superio.o
+
+obj-y := gsc.o power.o
+obj-m :=
+obj-n :=
+obj-  :=
+
+obj-$(CONFIG_GSC_DINO) += dino.o
+obj-$(CONFIG_GSC_LASI) += lasi.o asp.o
+obj-$(CONFIG_GSC_WAX) += wax.o
+obj-$(CONFIG_EISA) += eisa.o eisa_enumerator.o eisa_eeprom.o
+obj-$(CONFIG_SUPERIO) += superio.o
+obj-$(CONFIG_PCI_LBA) += lba_pci.o
+# I/O SAPIC is also on IA64 platforms.
+# The two could be merged into a common source some day.
+obj-$(CONFIG_IOSAPIC) += iosapic.o
+obj-$(CONFIG_IOMMU_SBA) += sba_iommu.o
+# 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
+obj-$(CONFIG_CHASSIS_LCD_LED) += led.o
diff -Nru a/drivers/parisc/README.dino b/drivers/parisc/README.dino
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/parisc/README.dino	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,28 @@
+/*
+** HP VISUALIZE Workstation PCI Bus Defect
+**
+** "HP has discovered a potential system defect that can affect
+** the behavior of five models of HP VISUALIZE workstations when
+** equipped with third-party or customer-installed PCI I/O expansion
+** cards. The defect is limited to the HP C180, C160, C160L, B160L,
+** and B132L VISUALIZE workstations, and will only be encountered
+** when data is transmitted through PCI I/O expansion cards on the
+** PCI bus. HP-supplied graphics cards that utilize the PCI bus are
+** not affected."
+**
+** REVISIT: "go/pci_defect" link below is stale.
+**	HP Internal can use <http://hpfcdma.fc.hp.com:80/Dino/>
+**
+**	Product		First Good Serial Number
+**  C200/C240 (US)	US67350000
+**B132L+/B180 (US)	US67390000
+**   C200 (Europe)	3713G01000
+**  B180L (Europe)	3720G01000
+**
+** Note that many boards were fixed/replaced under a free replacement
+** program. Assume a machine is only "suspect" until proven otherwise.
+**
+** "The pci_check program will also be available as application
+**  patch PHSS_12295"
+*/
+
diff -Nru a/drivers/parisc/asp.c b/drivers/parisc/asp.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/parisc/asp.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,131 @@
+/*
+ *	ASP Device Driver
+ *
+ *	(c) Copyright 2000 The Puffin Group Inc.
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2 of the License, or
+ *      (at your option) any later version.
+ *
+ *	by Helge Deller <deller@gmx.de>
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/led.h>
+
+#include "gsc.h"
+
+#define ASP_GSC_IRQ	3		/* hardcoded interrupt for GSC */
+
+#define ASP_VER_OFFSET 	0x20		/* offset of ASP version */
+
+#define ASP_LED_ADDR	0xf0800020
+
+#define VIPER_INT_WORD  0xFFFBF088      /* addr of viper interrupt word */
+
+static int asp_choose_irq(struct parisc_device *dev)
+{
+	int irq = -1;
+
+	switch (dev->id.sversion) {
+	case 0x71:	irq = 22; break; /* SCSI */
+	case 0x72:	irq = 23; break; /* LAN */
+	case 0x73:	irq = 30; break; /* HIL */
+	case 0x74:	irq = 24; break; /* Centronics */
+	case 0x75:	irq = (dev->hw_path == 4) ? 26 : 25; break; /* RS232 */
+	case 0x76:	irq = 21; break; /* EISA BA */
+	case 0x77:	irq = 20; break; /* Graphics1 */
+	case 0x7a:	irq = 18; break; /* Audio (Bushmaster) */
+	case 0x7b:	irq = 18; break; /* Audio (Scorpio) */
+	case 0x7c:	irq = 28; break; /* FW SCSI */
+	case 0x7d:	irq = 27; break; /* FDDI */
+	case 0x7f:	irq = 18; break; /* Audio (Outfield) */
+	}
+	return irq;
+}
+
+/* There are two register ranges we're interested in.  Interrupt /
+ * Status / LED are at 0xf080xxxx and Asp special registers are at
+ * 0xf082fxxx.  PDC only tells us that Asp is at 0xf082f000, so for
+ * the purposes of interrupt handling, we have to tell other bits of
+ * the kernel to look at the other registers.
+ */
+#define ASP_INTERRUPT_ADDR 0xf0800000
+
+int __init
+asp_init_chip(struct parisc_device *dev)
+{
+	struct busdevice *asp;
+	struct gsc_irq gsc_irq;
+	int irq, ret;
+
+	asp = kmalloc(sizeof(struct busdevice), GFP_KERNEL);
+	if(!asp)
+		return -ENOMEM;
+
+	asp->version = gsc_readb(dev->hpa + ASP_VER_OFFSET) & 0xf;
+	asp->name = (asp->version == 1) ? "Asp" : "Cutoff";
+	asp->hpa = ASP_INTERRUPT_ADDR;
+
+	printk(KERN_INFO "%s version %d at 0x%lx found.\n", 
+		asp->name, asp->version, dev->hpa);
+
+	/* the IRQ ASP should use */
+	ret = -EBUSY;
+	irq = gsc_claim_irq(&gsc_irq, ASP_GSC_IRQ);
+	if (irq < 0) {
+		printk(KERN_ERR "%s(): cannot get GSC irq\n", __FUNCTION__);
+		goto out;
+	}
+
+	ret = request_irq(gsc_irq.irq, busdev_barked, 0, "asp", asp);
+	if (ret < 0)
+		goto out;
+
+	/* Save this for debugging later */
+	asp->parent_irq = gsc_irq.irq;
+	asp->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data;
+
+	/* Program VIPER to interrupt on the ASP irq */
+	gsc_writel((1 << (31 - ASP_GSC_IRQ)),VIPER_INT_WORD);
+
+	/* Done init'ing, register this driver */
+	ret = gsc_common_irqsetup(dev, asp);
+	if (ret)
+		goto out;
+
+	fixup_child_irqs(dev, asp->busdev_region->data.irqbase, asp_choose_irq);
+	/* Mongoose is a sibling of Asp, not a child... */
+	fixup_child_irqs(dev->parent, asp->busdev_region->data.irqbase,
+			asp_choose_irq);
+
+	/* initialize the chassis LEDs */ 
+#ifdef CONFIG_CHASSIS_LCD_LED	
+	register_led_driver(DISPLAY_MODEL_OLD_ASP, LED_CMD_REG_NONE, 
+		    (char *)ASP_LED_ADDR);
+#endif
+
+	return 0;
+
+out:
+	kfree(asp);
+	return ret;
+}
+
+static struct parisc_device_id asp_tbl[] = {
+	{ HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00070 },
+	{ 0, }
+};
+
+struct parisc_driver asp_driver = {
+	name:		"Asp",
+	id_table:	asp_tbl,
+	probe:		asp_init_chip,
+};
diff -Nru a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/parisc/ccio-dma.c	Mon Nov  4 14:31:01 2002
@@ -0,0 +1,1613 @@
+/*
+** ccio-dma.c:
+**	DMA management routines for first generation cache-coherent machines.
+**	Program U2/Uturn in "Virtual Mode" and use the I/O MMU.
+**
+**	(c) Copyright 2000 Grant Grundler
+**	(c) Copyright 2000 Ryan Bradetich
+**	(c) Copyright 2000 Hewlett-Packard Company
+**
+** 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.
+**
+**
+**  "Real Mode" operation refers to U2/Uturn chip operation.
+**  U2/Uturn were designed to perform coherency checks w/o using
+**  the I/O MMU - basically what x86 does.
+**
+**  Philipp Rumpf has a "Real Mode" driver for PCX-W machines at:
+**      CVSROOT=:pserver:anonymous@198.186.203.37:/cvsroot/linux-parisc
+**      cvs -z3 co linux/arch/parisc/kernel/dma-rm.c
+**
+**  I've rewritten his code to work under TPG's tree. See ccio-rm-dma.c.
+**
+**  Drawbacks of using Real Mode are:
+**	o outbound DMA is slower - U2 won't prefetch data (GSC+ XQL signal).
+**      o Inbound DMA less efficient - U2 can't use DMA_FAST attribute.
+**	o Ability to do scatter/gather in HW is lost.
+**	o Doesn't work under PCX-U/U+ machines since they didn't follow
+**        the coherency design originally worked out. Only PCX-W does.
+*/
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#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/hardware.h>       /* for register_module() */
+
+/* 
+** Choose "ccio" since that's what HP-UX calls it.
+** Make it easier for folks to migrate from one to the other :^)
+*/
+#define MODULE_NAME "ccio"
+
+#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 */
+
+#ifdef DEBUG_CCIO_INIT
+#define DBG_INIT(x...)  printk(x)
+#else
+#define DBG_INIT(x...)
+#endif
+
+#ifdef DEBUG_CCIO_RUN
+#define DBG_RUN(x...)   printk(x)
+#else
+#define DBG_RUN(x...)
+#endif
+
+#ifdef DEBUG_CCIO_RES
+#define DBG_RES(x...)   printk(x)
+#else
+#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 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
+
+#define IOA_NORMAL_MODE      0x00020080 /* IO_CONTROL to turn on CCIO        */
+#define CMD_TLB_DIRECT_WRITE 35         /* IO_COMMAND for I/O TLB Writes     */
+#define CMD_TLB_PURGE        33         /* IO_COMMAND to Purge I/O TLB entry */
+
+struct ioa_registers {
+        /* Runway Supervisory Set */
+        volatile int32_t    unused1[12];
+        volatile uint32_t   io_command;             /* Offset 12 */
+        volatile uint32_t   io_status;              /* Offset 13 */
+        volatile uint32_t   io_control;             /* Offset 14 */
+        volatile int32_t    unused2[1];
+
+        /* Runway Auxiliary Register Set */
+        volatile uint32_t   io_err_resp;            /* Offset  0 */
+        volatile uint32_t   io_err_info;            /* Offset  1 */
+        volatile uint32_t   io_err_req;             /* Offset  2 */
+        volatile uint32_t   io_err_resp_hi;         /* Offset  3 */
+        volatile uint32_t   io_tlb_entry_m;         /* Offset  4 */
+        volatile uint32_t   io_tlb_entry_l;         /* Offset  5 */
+        volatile uint32_t   unused3[1];
+        volatile uint32_t   io_pdir_base;           /* Offset  7 */
+        volatile uint32_t   io_io_low_hv;           /* Offset  8 */
+        volatile uint32_t   io_io_high_hv;          /* Offset  9 */
+        volatile uint32_t   unused4[1];
+        volatile uint32_t   io_chain_id_mask;       /* Offset 11 */
+        volatile uint32_t   unused5[2];
+        volatile uint32_t   io_io_low;              /* Offset 14 */
+        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;
+
+	unsigned short cujo20_bug;
+#endif
+
+	/* STUFF We don't need in performance path */
+	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 ioc *ioc_list;
+static int ioc_count;
+
+/**************************************************************
+*
+*   I/O Pdir Resource Management
+*
+*   Bits set in the resource map are in use.
+*   Each bit can represent a number of pages.
+*   LSbs represent lower addresses (IOVA's).
+*
+*   This was was copied from sba_iommu.c. Don't try to unify
+*   the two resource managers unless a way to have different
+*   allocation policies is also adjusted. We'd like to avoid
+*   I/O TLB thrashing by having resource allocation policy
+*   match the I/O TLB replacement policy.
+*
+***************************************************************/
+#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_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)
+#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.
+*/
+#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, 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.
+** Use a "circular" search:
+**   o Most IOVA's are "temporary" - avg search time should be small.
+** o keep a history of what happened for debugging
+** o KISS.
+**
+** Perf optimizations:
+** o search for log2(size) bits at a time.
+** o search for available resource bits using byte/word/whatever.
+** 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 ioc *ioc, unsigned long pages_needed)
+{
+	int res_idx;
+	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);
+
+	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 sacrifices another 710 to the computer gods.
+	*/
+
+	if(pages_needed <= 8) {
+		CCIO_FIND_FREE_MAPPING(ioc, res_idx, mask, 8);
+	} else if(pages_needed <= 16) {
+		CCIO_FIND_FREE_MAPPING(ioc, res_idx, mask, 16);
+	} else if(pages_needed <= 32) {
+		CCIO_FIND_FREE_MAPPING(ioc, res_idx, mask, 32);
+#ifdef __LP64__
+	} else if(pages_needed <= 64) {
+		CCIO_FIND_FREE_MAPPING(ioc, res_idx, mask, 64);
+#endif
+	} else {
+		panic(__FILE__ ": %s() Too many pages to map. pages_needed: %ld\n", 
+		      __FUNCTION__, pages_needed);
+	}
+
+	panic(__FILE__ ": %s() I/O MMU is out of mapping resources.\n", 
+	      __FUNCTION__);
+	
+resource_found:
+	
+	DBG_RES("%s() res_idx %d mask 0x%08lx res_hint: %d\n",
+		__FUNCTION__, res_idx, mask, ioc->res_hint);
+
+#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;
+
+	ioc->used_pages += pages_needed;
+#endif
+
+	/* 
+	** return the bit address.
+	*/
+	return res_idx << 3;
+}
+
+#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 ioc *ioc, dma_addr_t iova, unsigned long pages_mapped)
+{
+	unsigned long mask;
+	unsigned long iovp = CCIO_IOVP(iova);
+	unsigned int res_idx = PDIR_INDEX(iovp) >> 3;
+
+	ASSERT(pages_mapped);
+	ASSERT((pages_mapped * IOVP_SIZE) <= DMA_CHUNK_SIZE);
+	ASSERT(pages_mapped <= BITS_PER_LONG);
+
+	mask = ~(~0UL >> pages_mapped);
+
+	DBG_RES("%s():  res_idx: %d pages_mapped %d mask 0x%08lx\n", 
+		__FUNCTION__, res_idx, pages_mapped, mask);
+
+#ifdef CONFIG_PROC_FS
+	ioc->used_pages -= pages_mapped;
+#endif
+
+	if(pages_mapped <= 8) {
+		CCIO_FREE_MAPPINGS(ioc, res_idx, mask, 8);
+	} else if(pages_mapped <= 16) {
+		CCIO_FREE_MAPPINGS(ioc, res_idx, mask, 16);
+	} else if(pages_mapped <= 32) {
+		CCIO_FREE_MAPPINGS(ioc, res_idx, mask, 32);
+#ifdef __LP64__
+	} else if(pages_mapped <= 64) {
+		CCIO_FREE_MAPPINGS(ioc, res_idx, mask, 64);
+#endif
+	} else {
+		panic(__FILE__ ":%s() Too many pages to unmap.\n", 
+		      __FUNCTION__);
+	}
+}
+
+/****************************************************************
+**
+**          CCIO dma_ops support routines
+**
+*****************************************************************/
+
+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
+**   set for subcacheline DMA transfers since we don't want to damage the
+**   other part of a cacheline.
+** o SAFE_DMA must be set for "memory" allocated via pci_alloc_consistent().
+**   This bit tells U2 to do R/M/W for partial cachelines. "Streaming"
+**   data can avoid this if the mapping covers full cache lines.
+** o STOP_MOST is needed for atomicity across cachelines.
+**   Apperently only "some EISA devices" need this.
+**   Using CONFIG_ISA is hack. Only the IOA with EISA under it needs
+**   to use this hint iff the EISA devices needs this feature.
+**   According to the U2 ERS, STOP_MOST enabled pages hurt performance.
+** o PREFETCH should *not* be set for cases like Multiple PCI devices
+**   behind GSCtoPCI (dino) bus converter. Only one cacheline per GSC
+**   device can be fetched and multiply DMA streams will thrash the
+**   prefetch buffer and burn memory bandwidth. See 6.7.3 "Prefetch Rules
+**   and Invalidation of Prefetch Entries".
+**
+** FIXME: the default hints need to be per GSC device - not global.
+** 
+** HP-UX dorks: linux device driver programming model is totally different
+**    than HP-UX's. HP-UX always sets HINT_PREFETCH since it's drivers
+**    do special things to work on non-coherent platforms...linux has to
+**    be much more careful with this.
+*/
+#define IOPDIR_VALID    0x01UL
+#define HINT_SAFE_DMA   0x02UL	/* used for pci_alloc_consistent() pages */
+#ifdef CONFIG_ISA	/* EISA support really */
+#define HINT_STOP_MOST  0x04UL	/* LSL support */
+#else
+#define HINT_STOP_MOST  0x00UL	/* only needed for "some EISA devices" */
+#endif
+#define HINT_UDPATE_ENB 0x08UL  /* not used/supported by U2 */
+#define HINT_PREFETCH   0x10UL	/* for outbound pages which are not SAFE */
+
+
+/*
+** Use direction (ie PCI_DMA_TODEVICE) to pick hint.
+** ccio_alloc_consistent() depends on this to get SAFE_DMA
+** when it passes in BIDIRECTIONAL flag.
+*/
+static u32 hint_lookup[] = {
+	[PCI_DMA_BIDIRECTIONAL]  HINT_STOP_MOST | HINT_SAFE_DMA | IOPDIR_VALID,
+	[PCI_DMA_TODEVICE]       HINT_STOP_MOST | HINT_PREFETCH | IOPDIR_VALID,
+	[PCI_DMA_FROMDEVICE]     HINT_STOP_MOST | IOPDIR_VALID,
+	[PCI_DMA_NONE]           0,            /* not valid */
+};
+
+/**
+ * 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)
+{
+	register unsigned long pa = (volatile unsigned long) vba;
+	register unsigned long ci; /* coherent index */
+
+	/* We currently only support kernel addresses */
+	ASSERT(sid == KERNEL_SPACE);
+
+	mtsp(sid,1);
+
+	/*
+	** WORD 1 - low order word
+	** "hints" parm includes the VALID bit!
+	** "dep" clobbers the physical address offset bits as well.
+	*/
+	pa = virt_to_phys(vba);
+	asm volatile("depw  %1,31,12,%0" : "+r" (pa) : "r" (hints));
+	((u32 *)pdir_ptr)[1] = (u32) pa;
+
+	/*
+	** WORD 0 - high order word
+	*/
+
+#ifdef __LP64__
+	/*
+	** get bits 12:15 of physical address
+	** shift bits 16:31 of physical address
+	** and deposit them
+	*/
+	asm volatile ("extrd,u %1,15,4,%0" : "=r" (ci) : "r" (pa));
+	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;
+#endif
+	/*
+	** get CPU coherency index bits
+	** Grab virtual index [0:11]
+	** Deposit virt_idx bits into I/O PDIR word
+	*/
+	asm volatile ("lci 0(%%sr1, %1), %0" : "=r" (ci) : "r" (vba));
+	asm volatile ("extru %1,19,12,%0" : "+r" (ci) : "r" (ci));
+	asm volatile ("depw  %1,15,12,%0" : "+r" (pa) : "r" (ci));
+
+	((u32 *)pdir_ptr)[0] = (u32) pa;
+
+
+	/* FIXME: PCX_W platforms don't need FDC/SYNC. (eg C360)
+	**        PCX-U/U+ do. (eg C200/C240)
+	**        PCX-T'? Don't know. (eg C110 or similar K-class)
+	**
+	** See PDC_MODEL/option 0/SW_CAP word for "Non-coherent IO-PDIR bit".
+	** Hopefully we can patch (NOP) these out at boot time somehow.
+	**
+	** "Since PCX-U employs an offset hash that is incompatible with
+	** the real mode coherence index generation of U2, the PDIR entry
+	** must be flushed to memory to retain coherence."
+	*/
+	asm volatile("fdc 0(%0)" : : "r" (pdir_ptr));
+	asm volatile("sync");
+}
+
+/**
+ * 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 ioc *ioc, dma_addr_t iovp, size_t byte_cnt)
+{
+	u32 chain_size = 1 << ioc->chainid_shift;
+
+	iovp &= IOVP_MASK;	/* clear offset bits, just want pagenum */
+	byte_cnt += 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.
+ *
+ * FIXME: at some threshhold it might be "cheaper" to just blow
+ *        away the entire I/O TLB instead of individual entries.
+ *
+ * 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 ioc *ioc, dma_addr_t iova, size_t byte_cnt)
+{
+	u32 iovp = (u32)CCIO_IOVP(iova);
+	size_t saved_byte_cnt;
+
+	/* round up to nearest page size */
+	saved_byte_cnt = byte_cnt = ROUNDUP(byte_cnt, IOVP_SIZE);
+
+	while(byte_cnt > 0) {
+		/* invalidate one page at a time */
+		unsigned int idx = PDIR_INDEX(iovp);
+		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)
+		** See PDC_MODEL/option 0/SW_CAP for "Non-coherent IO-PDIR bit".
+		**
+		** Hopefully someone figures out how to patch (NOP) the
+		** FDC/SYNC out at boot time.
+		*/
+		asm volatile("fdc 0(%0)" : : "r" (pdir_ptr[7]));
+
+		iovp     += IOVP_SIZE;
+		byte_cnt -= IOVP_SIZE;
+	}
+
+	asm volatile("sync");
+	ccio_clear_io_tlb(ioc, CCIO_IOVP(iova), saved_byte_cnt);
+}
+
+/****************************************************************
+**
+**          CCIO dma_ops
+**
+*****************************************************************/
+
+/**
+ * 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(KERN_ERR MODULE_NAME ": EISA/ISA/et al not supported\n");
+		BUG();
+		return 0;
+	}
+
+	dev->dma_mask = mask;   /* save it */
+
+	/* only support 32-bit devices (ie PCI/GSC) */
+	return (int)(mask == 0xffffffffUL);
+}
+
+/**
+ * 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)
+{
+	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];
+
+	ASSERT(dev);
+	ASSERT(dev->sysdata);
+	ASSERT(HBA_DATA(dev->sysdata)->iommu);
+	ioc = GET_IOC(dev);
+
+	ASSERT(size > 0);
+
+	/* save offset bits */
+	offset = ((unsigned long) addr) & ~IOVP_MASK;
+
+	/* round up to nearest IOVP_SIZE */
+	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(ioc, (size >> IOVP_SHIFT));
+	iovp = (dma_addr_t)MKIOVP(idx);
+
+	pdir_start = &(ioc->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))
+		hint |= HINT_SAFE_DMA;
+
+	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]));
+		++pdir_start;
+		addr += IOVP_SIZE;
+		size -= IOVP_SIZE;
+	}
+
+	spin_unlock_irqrestore(&ioc->res_lock, flags);
+
+	/* form complete address */
+	return CCIO_IOVA(iovp, 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;
+	
+	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);
+
+	spin_lock_irqsave(&ioc->res_lock, flags);
+
+#ifdef CONFIG_PROC_FS
+	ioc->usingle_calls++;
+	ioc->usingle_pages += size >> IOVP_SHIFT;
+#endif
+
+	ccio_mark_invalid(ioc, iova, size);
+	ccio_free_range(ioc, iova, (size >> IOVP_SHIFT));
+	spin_unlock_irqrestore(&ioc->res_lock, flags);
+}
+
+/**
+ * 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;
+#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) {
+		/* only support PCI */
+		*dma_handle = 0;
+		return 0;
+	}
+#endif
+        ret = (void *) __get_free_pages(GFP_ATOMIC, get_order(size));
+
+	if (ret) {
+		memset(ret, 0, size);
+		*dma_handle = ccio_map_single(dev, ret, size, PCI_DMA_BIDIRECTIONAL);
+	}
+
+	return ret;
+}
+
+/**
+ * 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)
+{
+	ccio_unmap_single(dev, dma_handle, size, 0);
+	free_pages((unsigned long)cpu_addr, get_order(size));
+}
+
+/*
+** 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_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 %08lx/%05x\n", nents,
+			   (unsigned long)sg_dma_address(startsg), cnt,
+			   sg_virt_addr(startsg), 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 = sg_virt_addr(startsg);
+			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 CCIO_INLINE int
+ccio_coalesce_chunks(struct ioc *ioc, struct scatterlist *startsg, int 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 += sg_virt_addr(startsg);
+		dma_offset = sg_virt_addr(startsg) & ~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;
+
+			startsg++;
+			startsg_end = sg_virt_addr(startsg) + 
+				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 == sg_virt_addr(startsg)) {
+				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;
+		}
+
+		/*
+		** 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++;
+	}
+
+	return n_mappings;
+}
+
+/**
+ * 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)
+{
+	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,
+				(void *)sg_virt_addr(sglist), sglist->length,
+				direction);
+		sg_dma_len(sglist) = sglist->length;
+		return 1;
+	}
+	
+	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 page/offset contain 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,  %08lx,%x\n",
+		__FUNCTION__, nents, sg_virt_addr(sglist), 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,
+	ccio_alloc_consistent,
+	ccio_free_consistent,
+	ccio_map_single,
+	ccio_unmap_single,
+	ccio_map_sg,
+	ccio_unmap_sg,
+	NULL,                   /* dma_sync_single : NOP for U2/Uturn */
+	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? */
+
+/*
+** Get the size of the I/O TLB for this I/O MMU.
+**
+** If spa_shift is non-zero (ie probably U2),
+** then calculate the I/O TLB size using spa_shift.
+**
+** Otherwise we are supposed to get the IODC entry point ENTRY TLB
+** and execute it. However, both U2 and Uturn firmware supplies spa_shift.
+** I think only Java (K/D/R-class too?) systems don't do this.
+*/
+static int
+ccio_get_iotlb_size(struct parisc_device *dev)
+{
+	if (dev->spa_shift == 0) {
+		panic("%s() : Can't determine I/O TLB size.\n", __FUNCTION__);
+	}
+	return (1 << dev->spa_shift);
+}
+#else
+
+/* Uturn supports 256 TLB entries */
+#define CCIO_CHAINID_SHIFT	8
+#define CCIO_CHAINID_MASK	0xff
+#endif /* 0 */
+
+/**
+ * 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_ioc_init(struct ioc *ioc)
+{
+	int i, iov_order;
+	u32 iova_space_size;
+	unsigned long physmem;
+
+	/*
+	** Determine IOVA Space size from memory size.
+	**
+	** Ideally, PCI drivers would register the maximum number
+	** of DMA they can have outstanding for each device they
+	** own.  Next best thing would be to guess how much DMA
+	** can be outstanding based on PCI Class/sub-class. Both
+	** methods still require some "extra" to support PCI
+	** Hot-Plug/Removal of PCI cards. (aka PCI OLARD).
+	*/
+
+	/* limit IOVA space size to 1MB-1GB */
+
+	physmem = num_physpages << PAGE_SHIFT;
+	if(physmem < (ccio_mem_ratio * 1024 * 1024)) {
+		iova_space_size = 1024 * 1024;
+#ifdef __LP64__
+	} else if(physmem > (ccio_mem_ratio * 512 * 1024 * 1024)) {
+		iova_space_size = 512 * 1024 * 1024;
+#endif
+	} else {
+		iova_space_size = (u32)(physmem / ccio_mem_ratio);
+	}
+
+	/*
+	** iova space must be log2() in size.
+	** thus, pdir/res_map will also be log2().
+	*/
+
+	/* 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) >> (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);
+
+	ioc->pdir_size = (iova_space_size / IOVP_SIZE) * sizeof(u64);
+
+	ASSERT(ioc->pdir_size < 4 * 1024 * 1024);   /* max pdir size < 4MB */
+
+	/* Verify it's a power of two */
+	ASSERT((1 << get_order(ioc->pdir_size)) == (ioc->pdir_size >> PAGE_SHIFT));
+
+	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(ioc->pdir_base, 0, ioc->pdir_size);
+
+	ASSERT((((unsigned long)ioc->pdir_base) & PAGE_MASK) == (unsigned long)ioc->pdir_base);
+	DBG_INIT(" base %p", ioc->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.
+	*/
+	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 << 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, &ioc->ioc_hpa->io_control);
+
+	/*
+	** Initialize all I/O TLB entries to 0 (Valid bit off).
+	*/
+	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 << ioc->chainid_shift)),
+			  &ioc->ioc_hpa->io_command);
+	}
+}
+
+static void
+ccio_init_resource(struct resource *res, char *name, unsigned long ioaddr)
+{
+	int result;
+
+	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 (%08lx,%08lx)\n", 
+		       __FILE__, res->start, res->end);
+	}
+}
+
+static void __init ccio_init_resources(struct ioc *ioc)
+{
+	struct resource *res = ioc->mmio_region;
+	char *name = kmalloc(14, GFP_KERNEL);
+
+	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)
+{
+#ifdef NASTY_HACK_FOR_K_CLASS
+	__raw_writel(0xfffff600, (unsigned long)&(ioc->ioc_hpa->io_io_high));
+	ioc->mmio_region[0].end = 0xf5ffffff;
+#endif
+}
+
+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 {
+		return NULL;
+	}
+}
+
+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, unsigned long),
+		void *alignf_data)
+{
+	struct ioc *ioc = ccio_get_iommu(dev);
+	struct resource *parent = ccio_get_resource(ioc, dev);
+	if (!parent)
+		return -EBUSY;
+
+	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);
+}
+
+int ccio_request_resource(const struct parisc_device *dev,
+		struct resource *res)
+{
+	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;
+	
+	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));
+
+	ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn";
+
+	printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name, dev->hpa);
+
+	for (i = 0; i < ioc_count; i++) {
+		ioc_p = &(*ioc_p)->next;
+	}
+	*ioc_p = ioc;
+
+	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;
+}
+
+struct pci_dev * ccio_get_fake(const struct parisc_device *dev)
+{
+	struct ioc *ioc;
+
+	dev = find_pa_parent_type(dev, HPHW_IOA);
+	if(!dev)
+		return NULL;
+
+	ioc = ccio_find_ioc(dev->hw_path);
+	if(!ioc)
+		return NULL;
+
+	if(ioc->fake_pci_dev)
+		return ioc->fake_pci_dev;
+
+	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));
+
+	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;
+	}
+
+	HBA_DATA(ioc->fake_pci_dev->sysdata)->iommu = ioc;
+	return ioc->fake_pci_dev;
+}
+
+/* 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, }
+};
+
+static struct parisc_driver ccio_driver = {
+	name:		"U2/Uturn",
+	id_table:	ccio_tbl,
+	probe:		ccio_probe,
+};
+
+/**
+ * ccio_init - ccio initalization procedure.
+ *
+ * Register this driver.
+ */
+void __init ccio_init(void)
+{
+	register_parisc_driver(&ccio_driver);
+}
+
diff -Nru a/drivers/parisc/ccio-rm-dma.c b/drivers/parisc/ccio-rm-dma.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/parisc/ccio-rm-dma.c	Mon Nov  4 14:31:01 2002
@@ -0,0 +1,202 @@
+/*
+ * ccio-rm-dma.c:
+ *	DMA management routines for first generation cache-coherent machines.
+ *	"Real Mode" operation refers to U2/Uturn chip operation. The chip
+ *      can perform coherency checks w/o using the I/O MMU. That's all we
+ *      need until support for more than 4GB phys mem is needed.
+ * 
+ *	This is the trivial case - basically what x86 does.
+ *
+ *	Drawbacks of using Real Mode are:
+ *	o outbound DMA is slower since one isn't using the prefetching
+ *	  U2 can do for outbound DMA.
+ *	o Ability to do scatter/gather in HW is also lost.
+ *      o only known to work with PCX-W processor. (eg C360)
+ *        (PCX-U/U+ are not coherent with U2 in real mode.)
+ *
+ *
+ * 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.
+ *
+ *
+ * Original version/author:
+ *      CVSROOT=:pserver:anonymous@198.186.203.37:/cvsroot/linux-parisc
+ *      cvs -z3 co linux/arch/parisc/kernel/dma-rm.c
+ *
+ *	(C) Copyright 2000 Philipp Rumpf <prumpf@tux.org>
+ *
+ *
+ * Adopted for The Puffin Group's parisc-linux port by Grant Grundler.
+ *	(C) Copyright 2000 Grant Grundler <grundler@puffin.external.hp.com>
+ *	
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/page.h>
+
+/* Only chose "ccio" since that's what HP-UX calls it....
+** Make it easier for folks to migrate from one to the other :^)
+*/
+#define MODULE_NAME "ccio"
+
+#define U2_IOA_RUNWAY 0x580
+#define U2_BC_GSC     0x501
+#define UTURN_IOA_RUNWAY 0x581
+#define UTURN_BC_GSC     0x502
+
+#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))  \
+)
+
+static int ccio_dma_supported( struct pci_dev *dev, u64 mask)
+{
+	if (dev == NULL) {
+		printk(KERN_ERR MODULE_NAME ": EISA/ISA/et al not supported\n");
+		BUG();
+		return(0);
+	}
+
+	dev->dma_mask = mask;   /* save it */
+
+	/* only support 32-bit devices (ie PCI/GSC) */
+	return((int) (mask >= 0xffffffffUL));
+}
+
+
+static void *ccio_alloc_consistent(struct pci_dev *dev, size_t size,
+				 dma_addr_t *handle)
+{
+	void *ret;
+	
+	ret = (void *)__get_free_pages(GFP_ATOMIC, get_order(size));
+
+	if (ret != NULL) {
+		memset(ret, 0, size);
+		*handle = virt_to_phys(ret);
+	}
+	return ret;
+}
+	
+static void ccio_free_consistent(struct pci_dev *dev, size_t size,
+			       void *vaddr, dma_addr_t handle)
+{
+	free_pages((unsigned long)vaddr, get_order(size));
+}
+
+static dma_addr_t ccio_map_single(struct pci_dev *dev, void *ptr, size_t size,
+			  int direction)
+{
+	return virt_to_phys(ptr);
+}
+
+static void ccio_unmap_single(struct pci_dev *dev, dma_addr_t dma_addr,
+			    size_t size, int direction)
+{
+	/* Nothing to do */
+}
+
+
+static int ccio_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
+{
+	int tmp = nents;
+
+        /* 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++;
+	}
+
+	return tmp;
+}
+
+
+static void ccio_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
+{
+#if 0
+	while (nents) {
+		ccio_unmap_single(dev, sg_dma_address(sglist), sg_dma_len(sglist), direction);
+		nents--;
+		sglist++;
+	}
+	return;
+#else
+	/* Do nothing (copied from current ccio_unmap_single()  :^) */
+#endif
+}
+
+
+static struct pci_dma_ops ccio_ops = {
+	ccio_dma_supported,
+	ccio_alloc_consistent,
+	ccio_free_consistent,
+	ccio_map_single,
+	ccio_unmap_single,
+	ccio_map_sg,
+	ccio_unmap_sg,
+	NULL,                   /* dma_sync_single : NOP for U2 */
+	NULL,                   /* dma_sync_sg     : ditto */
+};
+
+
+/*
+** Determine if u2 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)
+{
+	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
+** in "Real Mode".
+*/
+
+#if 0
+/* will need this for "Virtual Mode" operation */
+	ccio_hw_init(ccio_dev);
+	ccio_common_init(ccio_dev);
+#endif
+	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 -Nru a/drivers/parisc/dino.c b/drivers/parisc/dino.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/parisc/dino.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,935 @@
+/*
+**	DINO manager
+**
+**	(c) Copyright 1999 Red Hat Software
+**	(c) Copyright 1999 SuSE GmbH
+**	(c) Copyright 1999,2000 Hewlett-Packard Company
+**	(c) Copyright 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
+**      the Free Software Foundation; either version 2 of the License, or
+**      (at your option) any later version.
+**
+**	This module provides access to Dino PCI bus (config/IOport spaces)
+**	and helps manage Dino IRQ lines.
+**
+**	Dino interrupt handling is a bit complicated.
+**	Dino always writes to the broadcast EIR via irr0 for now.
+**	(BIG WARNING: using broadcast EIR is a really bad thing for SMP!)
+**	Only one processor interrupt is used for the 11 IRQ line 
+**	inputs to dino.
+**
+**	The different between Built-in Dino and Card-Mode
+**	dino is in chip initialization and pci device initialization.
+**
+**	Linux drivers can only use Card-Mode Dino if pci devices I/O port
+**	BARs are configured and used by the driver. Programming MMIO address 
+**	requires substantial knowledge of available Host I/O address ranges
+**	is currently not supported.  Port/Config accessor functions are the
+**	same. "BIOS" differences are handled within the existing routines.
+*/
+
+/*	Changes :
+**	2001-06-14 : Clement Moyroud (moyroudc@esiee.fr)
+**		- added support for the integrated RS232. 	
+*/
+
+/*
+** TODO: create a virtual address for each Dino HPA.
+**       GSC code might be able to do this since IODC data tells us
+**       how many pages are used. PCI subsystem could (must?) do this
+**       for PCI drivers devices which implement/use MMIO registers.
+*/
+
+#include <linux/config.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>	/* for struct irqaction */
+#include <linux/spinlock.h>	/* for spinlock_t and prototypes */
+
+#include <asm/pdc.h>
+#include <asm/page.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+
+#include "gsc.h"
+
+#undef DINO_DEBUG
+
+#ifdef DINO_DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+/*
+** Config accessor functions only pass in the 8-bit bus number
+** and not the 8-bit "PCI Segment" number. Each Dino will be
+** assigned a PCI bus number based on "when" it's discovered.
+**
+** The "secondary" bus number is set to this before calling
+** pci_scan_bus(). If any PPB's are present, the scan will
+** discover them and update the "secondary" and "subordinate"
+** fields in Dino's pci_bus structure.
+**
+** Changes in the configuration *will* result in a different
+** bus number for each dino.
+*/
+
+#define is_card_dino(id) ((id)->hw_type == HPHW_A_DMA)
+
+#define DINO_IAR0		0x004
+#define DINO_IODC_ADDR		0x008
+#define DINO_IODC_DATA_0	0x008
+#define DINO_IODC_DATA_1	0x008
+#define DINO_IRR0		0x00C
+#define DINO_IAR1		0x010
+#define DINO_IRR1		0x014
+#define DINO_IMR		0x018
+#define DINO_IPR		0x01C
+#define DINO_TOC_ADDR		0x020
+#define DINO_ICR		0x024
+#define DINO_ILR		0x028
+#define DINO_IO_COMMAND		0x030
+#define DINO_IO_STATUS		0x034
+#define DINO_IO_CONTROL		0x038
+#define DINO_IO_GSC_ERR_RESP	0x040
+#define DINO_IO_ERR_INFO	0x044
+#define DINO_IO_PCI_ERR_RESP	0x048
+#define DINO_IO_FBB_EN		0x05c
+#define DINO_IO_ADDR_EN		0x060
+#define DINO_PCI_ADDR		0x064
+#define DINO_CONFIG_DATA	0x068
+#define DINO_IO_DATA		0x06c
+#define DINO_MEM_DATA		0x070	/* Dino 3.x only */
+#define DINO_GSC2X_CONFIG	0x7b4
+#define DINO_GMASK		0x800
+#define DINO_PAMR		0x804
+#define DINO_PAPR		0x808
+#define DINO_DAMODE		0x80c
+#define DINO_PCICMD		0x810
+#define DINO_PCISTS		0x814
+#define DINO_MLTIM		0x81c
+#define DINO_BRDG_FEAT		0x820
+#define DINO_PCIROR		0x824
+#define DINO_PCIWOR		0x828
+#define DINO_TLTIM		0x830
+
+#define DINO_IRQS 11		/* bits 0-10 are architected */
+#define DINO_IRR_MASK	0x5ff	/* only 10 bits are implemented */
+
+#define DINO_MASK_IRQ(x)	(1<<(x))
+
+#define PCIINTA   0x001
+#define PCIINTB   0x002
+#define PCIINTC   0x004
+#define PCIINTD   0x008
+#define PCIINTE   0x010
+#define PCIINTF   0x020
+#define GSCEXTINT 0x040
+/* #define xxx       0x080 - bit 7 is "default" */
+/* #define xxx    0x100 - bit 8 not used */
+/* #define xxx    0x200 - bit 9 not used */
+#define RS232INT  0x400
+
+struct dino_device
+{
+	struct pci_hba_data	hba;	/* 'C' inheritance - must be first */
+	spinlock_t		dinosaur_pen;
+	unsigned long		txn_addr; /* EIR addr to generate interrupt */ 
+	u32			txn_data; /* EIR data assign to each dino */ 
+	int			irq;      /* Virtual IRQ dino uses */
+	struct irq_region	*dino_region;  /* region for this Dino */
+
+	u32 			imr; /* IRQ's which are enabled */ 
+#ifdef DINO_DEBUG
+	unsigned int		dino_irr0; /* save most recent IRQ line stat */ 
+#endif
+};
+
+/* Looks nice and keeps the compiler happy */
+#define DINO_DEV(d) ((struct dino_device *) d)
+
+
+/*
+ * Dino Configuration Space Accessor Functions
+ */
+
+#define DINO_CFG_TOK(bus,dfn,pos) ((u32) ((bus)<<16 | (dfn)<<8 | (pos)))
+
+static int dino_cfg_read(struct pci_bus *bus, unsigned int devfn, int where,
+		int size, u32 *val)
+{
+	struct dino_device *d = DINO_DEV(bus->sysdata);
+	u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
+	u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3);
+	unsigned long base_addr = d->hba.base_addr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&d->dinosaur_pen, flags);
+
+	/* tell HW which CFG address */
+	gsc_writel(v, base_addr + DINO_PCI_ADDR);
+
+	/* generate cfg read cycle */
+	if (size == 1) {
+		*val = gsc_readb(base_addr + DINO_CONFIG_DATA + (where & 3));
+	} else if (size == 2) {
+		*val = le16_to_cpu(gsc_readw(base_addr +
+					DINO_CONFIG_DATA + (where & 2)));
+	} else if (size == 4) {
+		*val = le32_to_cpu(gsc_readl(base_addr + DINO_CONFIG_DATA));
+	}
+
+	spin_unlock_irqrestore(&d->dinosaur_pen, flags);
+	return 0;
+}
+
+/*
+ * Dino address stepping "feature":
+ * When address stepping, Dino attempts to drive the bus one cycle too soon
+ * even though the type of cycle (config vs. MMIO) might be different. 
+ * The read of Ven/Prod ID is harmless and avoids Dino's address stepping.
+ */
+static int dino_cfg_write(struct pci_bus *bus, unsigned int devfn, int where,
+	int size, u32 val)
+{
+	struct dino_device *d = DINO_DEV(bus->sysdata);
+	u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
+	u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3);
+	unsigned long base_addr = d->hba.base_addr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&d->dinosaur_pen, flags);
+
+	/* avoid address stepping feature */
+	gsc_writel(v & 0xffffff00, base_addr + DINO_PCI_ADDR);
+	gsc_readl(base_addr + DINO_CONFIG_DATA);
+
+	/* tell HW which CFG address */
+	gsc_writel(v, base_addr + DINO_PCI_ADDR);
+	/* generate cfg read cycle */
+	if (size == 1) {
+		gsc_writeb(val, base_addr + DINO_CONFIG_DATA + (where & 3));
+	} else if (size == 2) {
+		gsc_writew(cpu_to_le16(val),
+				base_addr + DINO_CONFIG_DATA + (where & 2));
+	} else if (size == 4) {
+		gsc_writel(cpu_to_le32(val), base_addr + DINO_CONFIG_DATA);
+	}
+
+	spin_unlock_irqrestore(&d->dinosaur_pen, flags);
+	return 0;
+}
+
+static struct pci_ops dino_cfg_ops = {
+	.read =		dino_cfg_read,
+	.write =	dino_cfg_write,
+};
+
+
+/*
+ * Dino "I/O Port" Space Accessor Functions
+ *
+ * Many PCI devices don't require use of I/O port space (eg Tulip,
+ * NCR720) since they export the same registers to both MMIO and
+ * I/O port space.  Performance is going to stink if drivers use
+ * I/O port instead of MMIO.
+ */
+
+#define cpu_to_le8(x) (x)
+#define le8_to_cpu(x) (x)
+
+#define DINO_PORT_IN(type, size, mask) \
+static u##size dino_in##size (struct pci_hba_data *d, u16 addr) \
+{ \
+	u##size v; \
+	unsigned long flags; \
+	spin_lock_irqsave(&(DINO_DEV(d)->dinosaur_pen), flags); \
+	/* tell HW which IO Port address */ \
+	gsc_writel((u32) addr & ~3, d->base_addr + DINO_PCI_ADDR); \
+	/* generate I/O PORT read cycle */ \
+	v = gsc_read##type(d->base_addr+DINO_IO_DATA+(addr&mask)); \
+	spin_unlock_irqrestore(&(DINO_DEV(d)->dinosaur_pen), flags); \
+	return le##size##_to_cpu(v); \
+}
+
+DINO_PORT_IN(b,  8, 3)
+DINO_PORT_IN(w, 16, 2)
+DINO_PORT_IN(l, 32, 0)
+
+#define DINO_PORT_OUT(type, size, mask) \
+static void dino_out##size (struct pci_hba_data *d, u16 addr, u##size val) \
+{ \
+	unsigned long flags; \
+	spin_lock_irqsave(&(DINO_DEV(d)->dinosaur_pen), flags); \
+	/* tell HW which CFG address */ \
+	gsc_writel((u32) addr, d->base_addr + DINO_PCI_ADDR); \
+	/* generate cfg write cycle */ \
+	gsc_write##type(cpu_to_le##size(val), d->base_addr+DINO_IO_DATA+(addr&mask)); \
+	spin_unlock_irqrestore(&(DINO_DEV(d)->dinosaur_pen), flags); \
+}
+
+DINO_PORT_OUT(b,  8, 3)
+DINO_PORT_OUT(w, 16, 2)
+DINO_PORT_OUT(l, 32, 0)
+
+struct pci_port_ops dino_port_ops = {
+	inb:	dino_in8,
+	inw:	dino_in16,
+	inl:	dino_in32,
+	outb:	dino_out8,
+	outw:	dino_out16,
+	outl:	dino_out32
+};
+
+static void
+dino_mask_irq(void *irq_dev, int irq)
+{
+	struct dino_device *dino_dev = DINO_DEV(irq_dev);
+
+	DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, irq_dev, irq);
+
+	if (NULL == irq_dev || irq > DINO_IRQS || irq < 0) {
+		printk(KERN_WARNING "%s(0x%lx, %d) - not a dino irq?\n",
+			__FUNCTION__, (long) irq_dev, irq);
+		BUG();
+	} else {
+		/*
+		** Clear the matching bit in the IMR register
+		*/
+		dino_dev->imr &= ~(DINO_MASK_IRQ(irq));
+		gsc_writel(dino_dev->imr, dino_dev->hba.base_addr+DINO_IMR);
+	}
+}
+
+
+static void
+dino_unmask_irq(void *irq_dev, int irq)
+{
+	struct dino_device *dino_dev = DINO_DEV(irq_dev);
+	u32 tmp;
+
+	DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, irq_dev, irq);
+
+	if (NULL == irq_dev || irq > DINO_IRQS) {
+		printk(KERN_WARNING "%s(): %d not a dino irq?\n",
+				__FUNCTION__, irq);
+		BUG();
+		return;
+	}
+
+	/* set the matching bit in the IMR register */
+	dino_dev->imr |= DINO_MASK_IRQ(irq);          /* used in dino_isr() */
+	gsc_writel( dino_dev->imr, dino_dev->hba.base_addr+DINO_IMR);
+
+	/* Emulate "Level Triggered" Interrupt
+	** Basically, a driver is blowing it if the IRQ line is asserted
+	** while the IRQ is disabled.  But tulip.c seems to do that....
+	** Give 'em a kluge award and a nice round of applause!
+	**
+	** The gsc_write will generate an interrupt which invokes dino_isr().
+	** dino_isr() will read IPR and find nothing. But then catch this
+	** when it also checks ILR.
+	*/
+	tmp = gsc_readl(dino_dev->hba.base_addr+DINO_ILR);
+	if (tmp & DINO_MASK_IRQ(irq)) {
+		DBG(KERN_WARNING "%s(): IRQ asserted! (ILR 0x%x)\n",
+				__FUNCTION__, tmp);
+		gsc_writel(dino_dev->txn_data, dino_dev->txn_addr);
+	}
+}
+
+
+
+static void
+dino_enable_irq(void *irq_dev, int irq)
+{
+	struct dino_device *dino_dev = DINO_DEV(irq_dev);
+
+	/*
+	** clear pending IRQ bits
+	**
+	** This does NOT change ILR state!
+	** See comments in dino_unmask_irq() for ILR usage.
+	*/
+	gsc_readl(dino_dev->hba.base_addr+DINO_IPR);
+
+	dino_unmask_irq(irq_dev, irq);
+}
+
+
+static struct irq_region_ops dino_irq_ops = {
+	disable_irq:	dino_mask_irq,	/* ??? */
+	enable_irq:	dino_enable_irq, 
+	mask_irq:	dino_mask_irq,
+	unmask_irq:	dino_unmask_irq
+};
+
+
+/*
+ * Handle a Processor interrupt generated by Dino.
+ *
+ * ilr_loop counter is a kluge to prevent a "stuck" IRQ line from
+ * wedging the CPU. Could be removed or made optional at some point.
+ */
+static void
+dino_isr(int irq, void *intr_dev, struct pt_regs *regs)
+{
+	struct dino_device *dino_dev = DINO_DEV(intr_dev);
+	u32 mask;
+	int ilr_loop = 100;
+	extern void do_irq(struct irqaction *a, int i, struct pt_regs *p);
+
+
+	/* read and acknowledge pending interrupts */
+#ifdef DINO_DEBUG
+	dino_dev->dino_irr0 =
+#endif
+	mask = gsc_readl(dino_dev->hba.base_addr+DINO_IRR0) & DINO_IRR_MASK;
+
+ilr_again:
+	while (mask)
+	{
+		int irq;
+
+		/*
+		 * Perform a binary search on set bits.
+		 * `Less than Fatal' and PS2 interupts aren't supported.
+		 */
+		if (mask & 0xf) {
+			if (mask & 0x3) {
+				irq = (mask & 0x1) ? 0 : 1; /* PCI INT A, B */
+			} else {
+				irq = (mask & 0x4) ? 2 : 3; /* PCI INT C, D */
+			}
+		} else {
+			if (mask & 0x30) {
+				irq = (mask & 0x10) ? 4 : 5; /* PCI INT E, F */
+			} else {
+				irq = (mask & 0x40) ? 6 : 10; /* GSC, RS232 */
+			}
+		}
+
+		mask &= ~(1<<irq);
+
+		DBG(KERN_WARNING "%s(%x, %p) mask %0x\n",
+			__FUNCTION__, irq, intr_dev, mask);
+		do_irq(&dino_dev->dino_region->action[irq],
+			dino_dev->dino_region->data.irqbase + irq,
+			regs);
+
+	}
+
+	/* Support for level triggered IRQ lines.
+	** 
+	** Dropping this support would make this routine *much* faster.
+	** But since PCI requires level triggered IRQ line to share lines...
+	** device drivers may assume lines are level triggered (and not
+	** edge triggered like EISA/ISA can be).
+	*/
+	mask = gsc_readl(dino_dev->hba.base_addr+DINO_ILR) & dino_dev->imr;
+	if (mask) {
+		if (--ilr_loop > 0)
+			goto ilr_again;
+		printk("Dino %lx: stuck interrupt %d\n", dino_dev->hba.base_addr, mask);
+	}
+}
+
+static int dino_choose_irq(struct parisc_device *dev)
+{
+	int irq = -1;
+
+	switch (dev->id.sversion) {
+		case 0x00084:	irq =  8; break; /* PS/2 */
+		case 0x0008c:	irq = 10; break; /* RS232 */
+		case 0x00096:	irq =  8; break; /* PS/2 */
+	}
+
+	return irq;
+}
+
+static void __init
+dino_bios_init(void)
+{
+	DBG("dino_bios_init\n");
+}
+
+/*
+ * dino_card_setup - Set up the memory space for a Dino in card mode.
+ * @bus: the bus under this dino
+ *
+ * Claim an 8MB chunk of unused IO space and call the generic PCI routines
+ * to set up the addresses of the devices on this bus.
+ */
+#define _8MB 0x00800000UL
+static void __init
+dino_card_setup(struct pci_bus *bus, unsigned long base_addr)
+{
+	int i;
+	struct dino_device *dino_dev = DINO_DEV(bus->sysdata);
+	struct resource *res;
+
+	res = &dino_dev->hba.lmmio_space;
+	res->flags = IORESOURCE_MEM;
+
+	if (ccio_allocate_resource(dino_dev->hba.dev, res, _8MB,
+				(unsigned long) 0xfffffffff0000000UL | _8MB,
+				0xffffffffffffffffUL &~ _8MB, _8MB,
+				NULL, NULL) < 0) {
+		printk(KERN_WARNING "Dino: Failed to allocate memory region\n");
+		return;
+	}
+	bus->resource[1] = res;
+	bus->resource[0] = &(dino_dev->hba.io_space);
+
+	/* Now tell dino what range it has */
+	for (i = 1; i < 31; i++) {
+		if (res->start == (0xfffffffff0000000UL | i * _8MB))
+			break;
+	}
+	gsc_writel(1 << i, base_addr + DINO_IO_ADDR_EN);
+
+	pcibios_assign_unassigned_resources(bus);
+}
+
+static void __init
+dino_card_fixup(struct pci_dev *dev)
+{
+	u32 irq_pin;
+
+	/*
+	** REVISIT: card-mode PCI-PCI expansion chassis do exist.
+	**         Not sure they were ever productized.
+	**         Die here since we'll die later in dino_inb() anyway.
+	*/
+	if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
+		panic("Card-Mode Dino: PCI-PCI Bridge not supported\n");
+	}
+
+	/*
+	** Set Latency Timer to 0xff (not a shared bus)
+	** Set CACHELINE_SIZE.
+	*/
+	dino_cfg_write(dev->bus, dev->devfn, PCI_CACHE_LINE_SIZE, 16, 0xff00 | L1_CACHE_BYTES/4); 
+
+	/*
+	** Program INT_LINE for card-mode devices.
+	** The cards are hardwired according to this algorithm.
+	** And it doesn't matter if PPB's are present or not since
+	** the IRQ lines bypass the PPB.
+	**
+	** "-1" converts INTA-D (1-4) to PCIINTA-D (0-3) range.
+	** The additional "-1" adjusts for skewing the IRQ<->slot.
+	*/
+	dino_cfg_read(dev->bus, dev->devfn, PCI_INTERRUPT_PIN, 8, &irq_pin); 
+	dev->irq = (irq_pin + PCI_SLOT(dev->devfn) - 1) % 4 ;
+
+	/* Shouldn't really need to do this but it's in case someone tries
+	** to bypass PCI services and look at the card themselves.
+	*/
+	dino_cfg_write(dev->bus, dev->devfn, PCI_INTERRUPT_LINE, 8, dev->irq); 
+}
+
+
+static void __init
+dino_fixup_bus(struct pci_bus *bus)
+{
+	struct list_head *ln;
+        struct pci_dev *dev;
+        struct dino_device *dino_dev = DINO_DEV(bus->sysdata);
+	int port_base = HBA_PORT_BASE(dino_dev->hba.hba_num);
+
+	DBG(KERN_WARNING "%s(0x%p) bus %d sysdata 0x%p\n",
+			__FUNCTION__, bus, bus->secondary, bus->sysdata);
+
+	/* Firmware doesn't set up card-mode dino, so we have to */
+	if (is_card_dino(&dino_dev->hba.dev->id))
+		dino_card_setup(bus, dino_dev->hba.base_addr);
+
+	/* If this is a PCI-PCI Bridge, read the window registers etc */
+	if (bus->self)
+		pci_read_bridge_bases(bus);
+
+	list_for_each(ln, &bus->devices) {
+		int i;
+
+		dev = pci_dev_b(ln);
+		if (is_card_dino(&dino_dev->hba.dev->id))
+			dino_card_fixup(dev);
+
+		/*
+		** P2PB's only have 2 BARs, no IRQs.
+		** I'd like to just ignore them for now.
+		*/
+		if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)
+			continue;
+
+		/* Adjust the I/O Port space addresses */
+		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+			struct resource *res = &dev->resource[i];
+			if (res->flags & IORESOURCE_IO) {
+				res->start |= port_base;
+				res->end |= port_base;
+			}
+#ifdef __LP64__
+			/* Sign Extend MMIO addresses */
+			else if (res->flags & IORESOURCE_MEM) {
+				res->start |= 0xffffffff00000000UL;
+				res->end   |= 0xffffffff00000000UL;
+			}
+#endif
+		}
+
+		/* Adjust INT_LINE for that busses region */
+		dev->irq = dino_dev->dino_region->data.irqbase + dev->irq;
+	}
+}
+
+
+struct pci_bios_ops dino_bios_ops = {
+	.init		= dino_bios_init,
+	.fixup_bus	= dino_fixup_bus
+};
+
+
+/*
+ *	Initialise a DINO controller chip
+ */
+static void __init
+dino_card_init(struct dino_device *dino_dev)
+{
+	u32 brdg_feat = 0x00784e05;
+
+	gsc_writel(0x00000000, dino_dev->hba.base_addr+DINO_GMASK);
+	gsc_writel(0x00000001, dino_dev->hba.base_addr+DINO_IO_FBB_EN);
+	gsc_writel(0x00000000, dino_dev->hba.base_addr+DINO_ICR);
+
+#if 1
+/* REVISIT - should be a runtime check (eg if (CPU_IS_PCX_L) ...) */
+	/*
+	** PCX-L processors don't support XQL like Dino wants it.
+	** PCX-L2 ignore XQL signal and it doesn't matter.
+	*/
+	brdg_feat &= ~0x4;	/* UXQL */
+#endif
+	gsc_writel( brdg_feat, dino_dev->hba.base_addr+DINO_BRDG_FEAT);
+
+	/*
+	** Don't enable address decoding until we know which I/O range
+	** currently is available from the host. Only affects MMIO
+	** and not I/O port space.
+	*/
+	gsc_writel(0x00000000, dino_dev->hba.base_addr+DINO_IO_ADDR_EN);
+
+	gsc_writel(0x00000000, dino_dev->hba.base_addr+DINO_DAMODE);
+	gsc_writel(0x00222222, dino_dev->hba.base_addr+DINO_PCIROR);
+	gsc_writel(0x00222222, dino_dev->hba.base_addr+DINO_PCIWOR);
+
+	gsc_writel(0x00000040, dino_dev->hba.base_addr+DINO_MLTIM);
+	gsc_writel(0x00000080, dino_dev->hba.base_addr+DINO_IO_CONTROL);
+	gsc_writel(0x0000008c, dino_dev->hba.base_addr+DINO_TLTIM);
+
+	/* Disable PAMR before writing PAPR */
+	gsc_writel(0x0000007e, dino_dev->hba.base_addr+DINO_PAMR);
+	gsc_writel(0x0000007f, dino_dev->hba.base_addr+DINO_PAPR);
+	gsc_writel(0x00000000, dino_dev->hba.base_addr+DINO_PAMR);
+
+	/*
+	** Dino ERS encourages enabling FBB (0x6f).
+	** We can't until we know *all* devices below us can support it.
+	** (Something in device configuration header tells us).
+	*/
+	gsc_writel(0x0000004f, dino_dev->hba.base_addr+DINO_PCICMD);
+
+	/* Somewhere, the PCI spec says give devices 1 second
+	** to recover from the #RESET being de-asserted.
+	** Experience shows most devices only need 10ms.
+	** This short-cut speeds up booting significantly.
+	*/
+	mdelay(pci_post_reset_delay);
+}
+
+static int __init
+dino_bridge_init(struct dino_device *dino_dev, const char *name)
+{
+	unsigned long io_addr, bpos;
+	int result;
+	struct resource *res;
+	/*
+	 * Decoding IO_ADDR_EN only works for Built-in Dino
+	 * since PDC has already initialized this.
+	 */
+
+	io_addr = gsc_readl(dino_dev->hba.base_addr + DINO_IO_ADDR_EN);
+	if (io_addr == 0) {
+		printk(KERN_WARNING "%s: No PCI devices enabled.\n", name);
+		return -ENODEV;
+	}
+
+	for (bpos = 0; (io_addr & (1 << bpos)) == 0; bpos++)
+		;
+
+	res = &dino_dev->hba.lmmio_space;
+	res->flags = IORESOURCE_MEM;
+
+	res->start = (unsigned long)(signed int)(0xf0000000 | (bpos << 23));
+	res->end = res->start + 8 * 1024 * 1024 - 1;
+
+	result = ccio_request_resource(dino_dev->hba.dev, res);
+	if (result < 0) {
+		printk(KERN_ERR "%s: failed to claim PCI Bus address space!\n", name);
+		return result;
+	}
+
+	return 0;
+}
+
+static int __init dino_common_init(struct parisc_device *dev,
+		struct dino_device *dino_dev, const char *name)
+{
+	int status;
+	u32 eim;
+	struct gsc_irq gsc_irq;
+	struct resource *res;
+
+	pcibios_register_hba(&dino_dev->hba);
+
+	pci_bios = &dino_bios_ops;   /* used by pci_scan_bus() */
+	pci_port = &dino_port_ops;
+
+	/*
+	** Note: SMP systems can make use of IRR1/IAR1 registers
+	**   But it won't buy much performance except in very
+	**   specific applications/configurations. Note Dino
+	**   still only has 11 IRQ input lines - just map some of them
+	**   to a different processor.
+	*/
+	dino_dev->irq = gsc_alloc_irq(&gsc_irq);
+	dino_dev->txn_addr = gsc_irq.txn_addr;
+	dino_dev->txn_data = gsc_irq.txn_data;
+	eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data;
+
+	/* 
+	** Dino needs a PA "IRQ" to get a processor's attention.
+	** arch/parisc/kernel/irq.c returns an EIRR bit.
+	*/
+	if (dino_dev->irq < 0) {
+		printk(KERN_WARNING "%s: gsc_alloc_irq() failed\n", name);
+		return 1;
+	}
+
+	status = request_irq(dino_dev->irq, dino_isr, 0, name, dino_dev);
+	if (status) {
+		printk(KERN_WARNING "%s: request_irq() failed with %d\n", 
+			name, status);
+		return 1;
+	}
+
+	/*
+	** Tell generic interrupt support we have 11 bits which need
+	** be checked in the interrupt handler.
+	*/
+	dino_dev->dino_region = alloc_irq_region(DINO_IRQS, &dino_irq_ops,
+						name, dino_dev);
+
+	if (NULL == dino_dev->dino_region) {
+		printk(KERN_WARNING "%s: alloc_irq_region() failed\n", name);
+		return 1;
+	}
+
+	/* Support the serial port which is sometimes attached on built-in
+	 * Dino / Cujo chips.
+	 */
+
+	fixup_child_irqs(dev, dino_dev->dino_region->data.irqbase,
+			dino_choose_irq);
+
+	/*
+	** This enables DINO to generate interrupts when it sees
+	** any of it's inputs *change*. Just asserting an IRQ
+	** before it's enabled (ie unmasked) isn't good enough.
+	*/
+	gsc_writel(eim, dino_dev->hba.base_addr+DINO_IAR0);
+
+	/*
+	** Some platforms don't clear Dino's IRR0 register at boot time.
+	** Reading will clear it now.
+	*/
+	gsc_readl(dino_dev->hba.base_addr+DINO_IRR0);
+
+	/* allocate I/O Port resource region */
+	res = &dino_dev->hba.io_space;
+	if (dev->id.hversion == 0x680 || is_card_dino(&dev->id)) {
+		res->name = "Dino I/O Port";
+	        dino_dev->hba.lmmio_space.name = "Dino LMMIO";
+	} else {
+		res->name = "Cujo I/O Port";
+	        dino_dev->hba.lmmio_space.name = "Cujo LMMIO";
+	}
+	res->start = HBA_PORT_BASE(dino_dev->hba.hba_num);
+	res->end = res->start + (HBA_PORT_SPACE_SIZE - 1);
+	res->flags = IORESOURCE_IO; /* do not mark it busy ! */
+	if (request_resource(&ioport_resource, res) < 0) {
+		printk(KERN_ERR "%s: request I/O Port region failed 0x%lx/%lx (hpa 0x%lx)\n",
+				name, res->start, res->end, dino_dev->hba.base_addr);
+		return 1;
+	}
+
+	return 0;
+}
+
+#define CUJO_RAVEN_ADDR		0xfffffffff1000000UL
+#define CUJO_FIREHAWK_ADDR	0xfffffffff1604000UL
+#define CUJO_RAVEN_BADPAGE	0x01003000UL
+#define CUJO_FIREHAWK_BADPAGE	0x01607000UL
+
+static const char *dino_vers[] = {
+	"2.0",
+	"2.1",
+	"3.0",
+	"3.1"
+};
+
+static const char *cujo_vers[] = {
+	"1.0",
+	"2.0"
+};
+
+void ccio_cujo20_fixup(struct parisc_device *dev, u32 iovp);
+
+/*
+** Determine if dino should claim this chip (return 0) or not (return 1).
+** If so, initialize the chip appropriately (card-mode vs bridge mode).
+** Much of the initialization is common though.
+*/
+static int __init
+dino_driver_callback(struct parisc_device *dev)
+{
+	struct dino_device *dino_dev;	// Dino specific control struct
+	const char *version = "unknown";
+	const char *name = "Dino";
+	int is_cujo = 0;
+
+	if (is_card_dino(&dev->id)) {
+		version = "3.x (card mode)";
+	} else {
+		if(dev->id.hversion == 0x680) {
+			if (dev->id.hversion_rev < 4) {
+				version = dino_vers[dev->id.hversion_rev];
+			}
+		} else {
+			name = "Cujo";
+			is_cujo = 1;
+			if (dev->id.hversion_rev < 2) {
+				version = cujo_vers[dev->id.hversion_rev];
+			}
+		}
+	}
+
+	printk("%s version %s found at 0x%lx\n", name, version, dev->hpa);
+
+	if (!request_mem_region(dev->hpa, PAGE_SIZE, name)) {
+		printk(KERN_ERR "DINO: Hey! Someone took my MMIO space (0x%ld)!\n",
+			dev->hpa);
+		return 1;
+	}
+
+	/* Check for bugs */
+	if (is_cujo && dev->id.hversion_rev == 1) {
+#ifdef CONFIG_IOMMU_CCIO
+		printk(KERN_WARNING "Enabling Cujo 2.0 bug workaround\n");
+		if (dev->hpa == (unsigned long)CUJO_RAVEN_ADDR) {
+			ccio_cujo20_fixup(dev->parent, CUJO_RAVEN_BADPAGE);
+		} else if (dev->hpa == (unsigned long)CUJO_FIREHAWK_ADDR) {
+			ccio_cujo20_fixup(dev->parent, CUJO_FIREHAWK_BADPAGE);
+		} else {
+			printk("Don't recognise Cujo at address 0x%lx, not enabling workaround\n", dev->hpa);
+		}
+#endif
+	} else if (!is_cujo && !is_card_dino(&dev->id) &&
+			dev->id.hversion_rev < 3) {
+		printk(KERN_WARNING
+"The GSCtoPCI (Dino hrev %d) bus converter found may exhibit\n"
+"data corruption.  See Service Note Numbers: A4190A-01, A4191A-01.\n"
+"Systems shipped after Aug 20, 1997 will not exhibit this problem.\n"
+"Models affected: C180, C160, C160L, B160L, and B132L workstations.\n\n",
+			dev->id.hversion_rev);
+/* REVISIT: why are C200/C240 listed in the README table but not
+**   "Models affected"? Could be an omission in the original literature.
+*/
+	}
+
+	dino_dev = kmalloc(sizeof(struct dino_device), GFP_KERNEL);
+	if (!dino_dev) {
+		printk("dino_init_chip - couldn't alloc dino_device\n");
+		return 1;
+	}
+
+	memset(dino_dev, 0, sizeof(struct dino_device));
+
+	dino_dev->hba.dev = dev;
+	dino_dev->hba.base_addr = dev->hpa;  /* faster access */
+	dino_dev->hba.lmmio_space_offset = 0;	/* CPU addrs == bus addrs */
+	dino_dev->dinosaur_pen = SPIN_LOCK_UNLOCKED;
+	dino_dev->hba.iommu = ccio_get_iommu(dev);
+
+	if (is_card_dino(&dev->id)) {
+		dino_card_init(dino_dev);
+	} else {
+		dino_bridge_init(dino_dev, name);
+	}
+
+	if (dino_common_init(dev, dino_dev, name))
+		return 1;
+
+	/*
+	** It's not used to avoid chicken/egg problems
+	** with configuration accessor functions.
+	*/
+	dino_dev->hba.hba_bus = pci_scan_bus(dino_dev->hba.hba_num,
+			&dino_cfg_ops, dino_dev);
+
+	return 0;
+}
+
+/*
+ * Normally, we would just test sversion.  But the Elroy PCI adapter has
+ * the same sversion as Dino, so we have to check hversion as well.
+ * Unfortunately, the J2240 PDC reports the wrong hversion for the first
+ * Dino, so we have to test for Dino, Cujo and Dino-in-a-J2240.
+ */
+static struct parisc_device_id dino_tbl[] = {
+	{ HPHW_A_DMA, HVERSION_REV_ANY_ID, 0x004, 0x0009D }, /* Card-mode Dino. */
+	{ HPHW_A_DMA, HVERSION_REV_ANY_ID, 0x444, 0x08080 }, /* Same card in a 715.  Bug? */
+	{ HPHW_BRIDGE, HVERSION_REV_ANY_ID, 0x680, 0xa }, /* Bridge-mode Dino */
+	{ HPHW_BRIDGE, HVERSION_REV_ANY_ID, 0x682, 0xa }, /* Bridge-mode Cujo */
+	{ HPHW_BRIDGE, HVERSION_REV_ANY_ID, 0x05d, 0xa }, /* Dino in a J2240 */
+	{ 0, }
+};
+
+static struct parisc_driver dino_driver = {
+	.name		= "Dino",
+	.id_table	= dino_tbl,
+	.probe		= dino_driver_callback,
+};
+
+/*
+ * One time initialization to let the world know Dino is here.
+ * This is the only routine which is NOT static.
+ * Must be called exactly once before pci_init().
+ */
+int __init dino_init(void)
+{
+	register_parisc_driver(&dino_driver);
+	return 0;
+}
+
diff -Nru a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/parisc/eisa.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,454 @@
+/*
+ * eisa.c - provide support for EISA adapters in PA-RISC machines
+ *
+ * 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) 2001 Matthew Wilcox for Hewlett Packard
+ * Copyright (c) 2001 Daniel Engstrom <5116@telia.com>
+ *
+ * There are two distinct EISA adapters.  Mongoose is found in machines
+ * before the 712; then the Wax ASIC is used.  To complicate matters, the
+ * Wax ASIC also includes a PS/2 and RS-232 controller, but those are
+ * dealt with elsewhere; this file is concerned only with the EISA portions
+ * of Wax.
+ * 
+ * 
+ * HINT:
+ * -----
+ * To allow an ISA card to work properly in the EISA slot you need to
+ * set an edge trigger level. This may be done on the palo command line 
+ * by adding the kernel parameter "eisa_irq_edge=n,n2,[...]]", with 
+ * n and n2 as the irq levels you want to use.
+ * 
+ * Example: "eisa_irq_edge=10,11" allows ISA cards to operate at 
+ * irq levels 10 and 11.
+ */
+
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/processor.h>
+#include <asm/delay.h>
+#include <asm/eisa_bus.h>
+
+#if 0
+#define EISA_DBG(msg, arg... ) printk(KERN_DEBUG "eisa: " msg , ## arg )
+#else
+#define EISA_DBG(msg, arg... )  
+#endif
+
+#define SNAKES_EEPROM_BASE_ADDR 0xF0810400
+#define MIRAGE_EEPROM_BASE_ADDR 0xF00C0400
+
+static spinlock_t eisa_irq_lock = SPIN_LOCK_UNLOCKED;
+
+/* We can only have one EISA adapter in the system because neither
+ * implementation can be flexed.
+ */
+static struct eisa_ba {
+	struct pci_hba_data	hba;
+	unsigned long eeprom_addr;
+} eisa_dev;
+
+/* Port ops */
+
+static inline unsigned long eisa_permute(unsigned short port)
+{
+	if (port & 0x300) {
+		return 0xfc000000 | ((port & 0xfc00) >> 6)
+			| ((port & 0x3f8) << 9) | (port & 7);
+	} else {
+		return 0xfc000000 | port;
+	}
+}
+
+unsigned char eisa_in8(unsigned short port)
+{
+	if (EISA_bus)
+		return gsc_readb(eisa_permute(port));
+	return 0xff;
+}
+
+unsigned short eisa_in16(unsigned short port)
+{
+	if (EISA_bus)
+		return le16_to_cpu(gsc_readw(eisa_permute(port)));
+	return 0xffff;
+}
+
+unsigned int eisa_in32(unsigned short port)
+{
+	if (EISA_bus)
+		return le32_to_cpu(gsc_readl(eisa_permute(port)));
+	return 0xffffffff;
+}
+
+void eisa_out8(unsigned char data, unsigned short port)
+{
+	if (EISA_bus)
+		gsc_writeb(data, eisa_permute(port));
+}
+
+void eisa_out16(unsigned short data, unsigned short port)
+{
+	if (EISA_bus)	
+		gsc_writew(cpu_to_le16(data), eisa_permute(port));
+}
+
+void eisa_out32(unsigned int data, unsigned short port)
+{
+	if (EISA_bus)
+		gsc_writel(cpu_to_le32(data), eisa_permute(port));
+}
+
+/* Interrupt handling */
+
+/* cached interrupt mask registers */
+static int master_mask;
+static int slave_mask;
+
+/* the trig level can be set with the
+ * eisa_irq_edge=n,n,n commandline parameter 
+ * We should really read this from the EEPROM 
+ * in the furure. 
+ */
+/* irq 13,8,2,1,0 must be edge */
+static unsigned int eisa_irq_level; /* default to edge triggered */
+
+
+/* called by free irq */
+static void eisa_disable_irq(void *irq_dev, int irq)
+{
+	unsigned long flags;
+
+	EISA_DBG("disable irq %d\n", irq);
+	/* just mask for now */
+	spin_lock_irqsave(&eisa_irq_lock, flags);
+        if (irq & 8) {
+		slave_mask |= (1 << (irq&7));
+		eisa_out8(slave_mask, 0xa1);
+	} else {
+		master_mask |= (1 << (irq&7));
+		eisa_out8(master_mask, 0x21);
+	}
+	spin_unlock_irqrestore(&eisa_irq_lock, flags);
+	EISA_DBG("pic0 mask %02x\n", eisa_in8(0x21));
+	EISA_DBG("pic1 mask %02x\n", eisa_in8(0xa1));
+}
+
+/* called by request irq */
+static void eisa_enable_irq(void *irq_dev, int irq)
+{
+	unsigned long flags;
+	EISA_DBG("enable irq %d\n", irq);
+		
+	spin_lock_irqsave(&eisa_irq_lock, flags);
+        if (irq & 8) {
+		slave_mask &= ~(1 << (irq&7));
+		eisa_out8(slave_mask, 0xa1);
+	} else {
+		master_mask &= ~(1 << (irq&7));
+		eisa_out8(master_mask, 0x21);
+	}
+	spin_unlock_irqrestore(&eisa_irq_lock, flags);
+	EISA_DBG("pic0 mask %02x\n", eisa_in8(0x21));
+	EISA_DBG("pic1 mask %02x\n", eisa_in8(0xa1));
+}
+
+static void eisa_mask_irq(void *irq_dev, int irq)
+{
+	unsigned long flags;
+	EISA_DBG("mask irq %d\n", irq);
+	
+        /* mask irq */
+	spin_lock_irqsave(&eisa_irq_lock, flags);
+	if (irq & 8) {
+		slave_mask |= (1 << (irq&7));
+		eisa_out8(slave_mask, 0xa1);
+	} else {
+		master_mask |= (1 << (irq&7));
+		eisa_out8(master_mask, 0x21);
+	}
+	spin_unlock_irqrestore(&eisa_irq_lock, flags);
+}
+
+static void eisa_unmask_irq(void *irq_dev, int irq)
+{
+	unsigned long flags;
+	EISA_DBG("unmask irq %d\n", irq);
+        
+	/* unmask */
+	spin_lock_irqsave(&eisa_irq_lock, flags);
+	if (irq & 8) {
+		slave_mask &= ~(1 << (irq&7));
+		eisa_out8(slave_mask, 0xa1);
+	} else {
+		master_mask &= ~(1 << (irq&7));
+		eisa_out8(master_mask, 0x21);
+	}
+	spin_unlock_irqrestore(&eisa_irq_lock, flags);
+}
+
+static struct irqaction action[IRQ_PER_REGION];
+
+/* EISA needs to be fixed at IRQ region #0 (EISA_IRQ_REGION) */
+static struct irq_region eisa_irq_region = {
+	ops:	{ eisa_disable_irq, eisa_enable_irq, eisa_mask_irq, eisa_unmask_irq },
+	data:	{ name: "EISA", irqbase: 0 },
+	action:	action,
+};
+
+static void eisa_irq(int _, void *intr_dev, struct pt_regs *regs)
+{
+	extern void do_irq(struct irqaction *a, int i, struct pt_regs *p);
+	int irq = gsc_readb(0xfc01f000); /* EISA supports 16 irqs */
+	unsigned long flags;
+        
+	spin_lock_irqsave(&eisa_irq_lock, flags);
+	/* read IRR command */
+	eisa_out8(0x0a, 0x20);
+	eisa_out8(0x0a, 0xa0);
+
+	EISA_DBG("irq IAR %02x 8259-1 irr %02x 8259-2 irr %02x\n",
+		   irq, eisa_in8(0x20), eisa_in8(0xa0));
+   
+	/* read ISR command */
+	eisa_out8(0x0a, 0x20);
+	eisa_out8(0x0a, 0xa0);
+	EISA_DBG("irq 8259-1 isr %02x imr %02x 8259-2 isr %02x imr %02x\n",
+		 eisa_in8(0x20), eisa_in8(0x21), eisa_in8(0xa0), eisa_in8(0xa1));
+	
+	irq &= 0xf;
+	
+	/* mask irq and write eoi */
+	if (irq & 8) {
+		slave_mask |= (1 << (irq&7));
+		eisa_out8(slave_mask, 0xa1);
+		eisa_out8(0x60 | (irq&7),0xa0);/* 'Specific EOI' to slave */
+		eisa_out8(0x62,0x20);	/* 'Specific EOI' to master-IRQ2 */
+		
+	} else {
+		master_mask |= (1 << (irq&7));
+		eisa_out8(master_mask, 0x21);
+		eisa_out8(0x60|irq,0x20);	/* 'Specific EOI' to master */
+	}
+	spin_unlock_irqrestore(&eisa_irq_lock, flags);
+
+   
+	do_irq(&eisa_irq_region.action[irq], EISA_IRQ_REGION + irq, regs);
+   
+	spin_lock_irqsave(&eisa_irq_lock, flags);
+	/* unmask */
+        if (irq & 8) {
+		slave_mask &= ~(1 << (irq&7));
+		eisa_out8(slave_mask, 0xa1);
+	} else {
+		master_mask &= ~(1 << (irq&7));
+		eisa_out8(master_mask, 0x21);
+	}
+	spin_unlock_irqrestore(&eisa_irq_lock, flags);
+}
+
+static void dummy_irq2_handler(int _, void *dev, struct pt_regs *regs)
+{
+	printk(KERN_ALERT "eisa: uhh, irq2?\n");
+}
+
+static void init_eisa_pic(void)
+{
+	unsigned long flags;
+	
+	spin_lock_irqsave(&eisa_irq_lock, flags);
+
+	eisa_out8(0xff, 0x21); /* mask during init */
+	eisa_out8(0xff, 0xa1); /* mask during init */
+	
+	/* master pic */
+	eisa_out8(0x11,0x20); /* ICW1 */   
+	eisa_out8(0x00,0x21); /* ICW2 */   
+	eisa_out8(0x04,0x21); /* ICW3 */   
+	eisa_out8(0x01,0x21); /* ICW4 */   
+	eisa_out8(0x40,0x20); /* OCW2 */   
+	
+	/* slave pic */
+	eisa_out8(0x11,0xa0); /* ICW1 */   
+	eisa_out8(0x08,0xa1); /* ICW2 */   
+        eisa_out8(0x02,0xa1); /* ICW3 */   
+	eisa_out8(0x01,0xa1); /* ICW4 */   
+	eisa_out8(0x40,0xa0); /* OCW2 */   
+        
+	udelay(100);
+	
+	slave_mask = 0xff; 
+	master_mask = 0xfb; 
+	eisa_out8(slave_mask, 0xa1); /* OCW1 */
+	eisa_out8(master_mask, 0x21); /* OCW1 */
+	
+	/* setup trig level */
+	EISA_DBG("EISA edge/level %04x\n", eisa_irq_level);
+	
+	eisa_out8(eisa_irq_level&0xff, 0x4d0); /* Set all irq's to edge  */
+	eisa_out8((eisa_irq_level >> 8) & 0xff, 0x4d1); 
+	
+	EISA_DBG("pic0 mask %02x\n", eisa_in8(0x21));
+	EISA_DBG("pic1 mask %02x\n", eisa_in8(0xa1));
+	EISA_DBG("pic0 edge/level %02x\n", eisa_in8(0x4d0));
+	EISA_DBG("pic1 edge/level %02x\n", eisa_in8(0x4d1));
+	
+	spin_unlock_irqrestore(&eisa_irq_lock, flags);
+}
+
+/* Device initialisation */
+
+#define is_mongoose(dev) (dev->id.sversion == 0x00076)
+
+static int __devinit eisa_probe(struct parisc_device *dev)
+{
+	int result;
+
+	char *name = is_mongoose(dev) ? "Mongoose" : "Wax";
+
+	printk(KERN_INFO "%s EISA Adapter found at 0x%08lx\n", 
+		name, dev->hpa);
+
+	eisa_dev.hba.dev = dev;
+	eisa_dev.hba.iommu = ccio_get_iommu(dev);
+
+	eisa_dev.hba.lmmio_space.name = "EISA";
+	eisa_dev.hba.lmmio_space.start = (unsigned long) 0xfffffffffc000000;
+	eisa_dev.hba.lmmio_space.end = (unsigned long) 0xffffffffffbfffff;
+	eisa_dev.hba.lmmio_space.flags = IORESOURCE_MEM;
+	result = ccio_request_resource(dev, &eisa_dev.hba.lmmio_space);
+	if (result < 0) {
+		printk(KERN_ERR "EISA: failed to claim EISA Bus address space!\n");
+		return result;
+	}
+	eisa_dev.hba.io_space.name = "EISA";
+	eisa_dev.hba.io_space.start = 0;
+	eisa_dev.hba.io_space.end = 0xffff;
+	eisa_dev.hba.lmmio_space.flags = IORESOURCE_IO;
+	result = request_resource(&ioport_resource, &eisa_dev.hba.io_space);
+	if (result < 0) {
+		printk(KERN_ERR "EISA: failed to claim EISA Bus port space!\n");
+		return result;
+	}
+	pcibios_register_hba(&eisa_dev.hba);
+
+	result = request_irq(dev->irq, eisa_irq, SA_SHIRQ, "EISA", NULL);
+	if (result) {
+		printk(KERN_ERR "EISA: request_irq failed!\n");
+		return result;
+	}
+	
+	/* Reserve IRQ2 */
+	action[2].handler = dummy_irq2_handler;
+	action[2].name = "cascade";
+	
+	eisa_irq_region.data.dev = dev;
+	irq_region[0] = &eisa_irq_region;
+	
+	EISA_bus = 1;
+	if (dev->num_addrs) {
+		/* newer firmware hand out the eeprom address */
+		eisa_dev.eeprom_addr = dev->addr[0];
+	} else {
+		/* old firmware, need to figure out the box */
+		if (is_mongoose(dev)) {
+			eisa_dev.eeprom_addr = SNAKES_EEPROM_BASE_ADDR;
+		} else {
+			eisa_dev.eeprom_addr = MIRAGE_EEPROM_BASE_ADDR;
+		}
+	}
+	eisa_eeprom_init(eisa_dev.eeprom_addr);
+	eisa_enumerator(eisa_dev.eeprom_addr, &eisa_dev.hba.io_space, &eisa_dev.hba.lmmio_space);
+	init_eisa_pic();
+	
+	return 0;
+}
+
+static struct parisc_device_id __devinitdata eisa_tbl[] = {
+	{ HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00076 }, /* Mongoose */
+	{ HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00090 }, /* Wax EISA */
+	{ 0, }
+};
+
+MODULE_DEVICE_TABLE(parisc, eisa_tbl);
+
+static struct parisc_driver eisa_driver = {
+	name:		"EISA Bus Adapter",
+	id_table:	eisa_tbl,
+	probe:		eisa_probe,
+};
+
+void __init eisa_init(void)
+{
+	register_parisc_driver(&eisa_driver);
+}
+
+
+static unsigned int eisa_irq_configured;
+void eisa_make_irq_level(int num)
+{
+	if (eisa_irq_configured& (1<<num)) {
+		printk(KERN_WARNING
+		       "IRQ %d polarity configured twice (last to level)\n", 
+		       num);
+	}
+	eisa_irq_level |= (1<<num); /* set the corresponding bit */
+	eisa_irq_configured |= (1<<num); /* set the corresponding bit */
+}
+
+void eisa_make_irq_edge(int num)
+{
+	if (eisa_irq_configured& (1<<num)) {
+		printk(KERN_WARNING 
+		       "IRQ %d polarity configured twice (last to edge)\n",
+		       num);
+	}
+	eisa_irq_level &= ~(1<<num); /* clear the corresponding bit */
+	eisa_irq_configured |= (1<<num); /* set the corresponding bit */
+}
+
+static int __init eisa_irq_setup(char *str)
+{
+	char *cur = str;
+	int val;
+
+	EISA_DBG("IRQ setup\n");
+	while (cur != NULL) {
+		char *pe;
+		
+		val = (int) simple_strtoul(cur, &pe, 0);
+		if (val > 15 || val < 0) {
+			printk(KERN_ERR "eisa: EISA irq value are 0-15\n");
+			continue;
+		}
+		if (val == 2) { 
+			val = 9;
+		}
+		eisa_make_irq_edge(val); /* clear the corresponding bit */
+		EISA_DBG("setting IRQ %d to edge-triggered mode\n", val);
+		
+		if ((cur = strchr(cur, ','))) {
+			cur++;
+		} else {
+			break;
+		}
+	}
+	return 1;
+}
+
+__setup("eisa_irq_edge=", eisa_irq_setup);
+
diff -Nru a/drivers/parisc/eisa_eeprom.c b/drivers/parisc/eisa_eeprom.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/parisc/eisa_eeprom.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,107 @@
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/eisa_eeprom.h>
+
+#define 	EISA_EEPROM_MINOR 241
+
+static unsigned long eeprom_addr;
+
+static long long eisa_eeprom_llseek(struct file *file, loff_t offset, int origin )
+{
+	switch (origin) {
+	  case 0:
+		/* nothing to do */
+		break;
+	  case 1:
+		offset += file->f_pos;
+		break;
+	  case 2:
+		offset += HPEE_MAX_LENGTH;
+		break;
+	}
+	return (offset >= 0 && offset < HPEE_MAX_LENGTH) ? (file->f_pos = offset) : -EINVAL;
+}
+
+static ssize_t eisa_eeprom_read(struct file * file,
+			      char *buf, size_t count, loff_t *ppos )
+{
+	unsigned char *tmp;
+	ssize_t ret;
+	int i;
+	
+	if (*ppos >= HPEE_MAX_LENGTH)
+		return 0;
+	
+	count = *ppos + count < HPEE_MAX_LENGTH ? count : HPEE_MAX_LENGTH - *ppos;
+	tmp = kmalloc(count, GFP_KERNEL);
+	if (tmp) {
+		for (i = 0; i < count; i++)
+			tmp[i] = gsc_readb(eeprom_addr+(*ppos)++);
+
+		if (copy_to_user (buf, tmp, count))
+			ret = -EFAULT;
+		else
+			ret = count;
+		kfree (tmp);
+	} else
+		ret = -ENOMEM;
+	
+	return ret;
+}
+
+static int eisa_eeprom_ioctl(struct inode *inode, struct file *file, 
+			   unsigned int cmd,
+			   unsigned long arg)
+{
+	return -ENOTTY;
+}
+
+static int eisa_eeprom_open(struct inode *inode, struct file *file)
+{
+	if (file->f_mode & 2 || eeprom_addr == 0)
+		return -EINVAL;
+   
+	return 0;
+}
+
+static int eisa_eeprom_release(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+/*
+ *	The various file operations we support.
+ */
+static struct file_operations eisa_eeprom_fops = {
+	owner:		THIS_MODULE,
+	llseek:		eisa_eeprom_llseek,
+	read:		eisa_eeprom_read,
+	ioctl:		eisa_eeprom_ioctl,
+	open:		eisa_eeprom_open,
+	release:	eisa_eeprom_release,
+};
+
+static struct miscdevice eisa_eeprom_dev=
+{
+	EISA_EEPROM_MINOR,
+	"eisa eeprom",
+	&eisa_eeprom_fops
+};
+
+int __init eisa_eeprom_init(unsigned long addr)
+{
+	if (addr) {
+		eeprom_addr = addr;
+		misc_register(&eisa_eeprom_dev);
+		printk(KERN_INFO "EISA EEPROM at 0x%lx\n", eeprom_addr);
+	}
+	return 0;
+}
+
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/parisc/eisa_enumerator.c b/drivers/parisc/eisa_enumerator.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/parisc/eisa_enumerator.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,518 @@
+/*
+ * eisa_enumerator.c - provide support for EISA adapters in PA-RISC machines
+ *
+ * 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) 2002 Daniel Engstrom <5116@telia.com>
+ *
+ */
+
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/byteorder.h>
+
+#include <asm/eisa_bus.h>
+#include <asm/eisa_eeprom.h>
+
+
+/*
+ * Todo:
+ * 
+ * PORT init with MASK attr and other size than byte
+ * MEMORY with other decode than 20 bit
+ * CRC stuff
+ * FREEFORM stuff
+ */
+
+#define EPI 0xc80
+#define NUM_SLOT 16
+#define SLOT2PORT(x) (x<<12)
+
+
+/* macros to handle unaligned accesses and 
+ * byte swapping. The data in the EEPROM is
+ * little-endian on the big-endian PAROSC */
+#define get_8(x) (*(u_int8_t*)(x))
+
+static inline u_int16_t get_16(const unsigned char *x)
+{ 
+	return (x[1] << 8) | x[0];
+}
+
+static inline u_int32_t get_32(const unsigned char *x)
+{
+	return (x[3] << 24) | (x[2] << 16) | (x[1] << 8) | x[0];
+}
+
+static inline u_int32_t get_24(const unsigned char *x)
+{
+	return (x[2] << 24) | (x[1] << 16) | (x[0] << 8);
+}
+
+static void print_eisa_id(char *s, u_int32_t id)
+{
+	char vendor[4];
+	int rev;
+	int device;
+	
+	rev = id & 0xff;
+	id >>= 8;
+	device = id & 0xff;
+	id >>= 8;
+	vendor[3] = '\0';
+	vendor[2] = '@' + (id & 0x1f);
+	id >>= 5;	
+	vendor[1] = '@' + (id & 0x1f);
+	id >>= 5;	
+	vendor[0] = '@' + (id & 0x1f);
+	id >>= 5;	
+	
+	sprintf(s, "%s%02X%02X", vendor, device, rev);
+}
+       
+static int configure_memory(const unsigned char *buf, 
+		       struct resource *mem_parent,
+		       char *name)
+{
+	int len;
+	u_int8_t c;
+	int i;
+	struct resource *res;
+	
+	len=0;
+	
+	for (i=0;i<HPEE_MEMORY_MAX_ENT;i++) {
+		c = get_8(buf+len);
+		
+		if (NULL != (res = kmalloc(sizeof(struct resource), GFP_KERNEL))) {
+			int result;
+			
+			res->name = name;
+			res->start = mem_parent->start + get_24(buf+len+2);
+			res->end = res->start + get_16(buf+len+5)*1024;
+			res->flags = IORESOURCE_MEM;
+			printk("memory %lx-%lx ", res->start, res->end);
+			result = request_resource(mem_parent, res);
+			if (result < 0) {
+				printk("\n" KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
+				return result;
+			}
+		}
+		 	
+		len+=7;      
+	
+		if (!(c & HPEE_MEMORY_MORE)) {
+			break;
+		}
+	}
+	
+	return len;
+}
+
+
+static int configure_irq(const unsigned char *buf)
+{
+	int len;
+	u_int8_t c;
+	int i;
+	
+	len=0;
+	
+	for (i=0;i<HPEE_IRQ_MAX_ENT;i++) {
+		c = get_8(buf+len);
+		
+		printk("IRQ %d ", c & HPEE_IRQ_CHANNEL_MASK);
+		if (c & HPEE_IRQ_TRIG_LEVEL) {
+			eisa_make_irq_level(c & HPEE_IRQ_CHANNEL_MASK);
+		} else {
+			eisa_make_irq_edge(c & HPEE_IRQ_CHANNEL_MASK);
+		}
+		
+		len+=2; 
+		/* hpux seems to allow for
+		 * two bytes of irq data but only defines one of
+		 * them, I think */
+		if  (!(c & HPEE_IRQ_MORE)) {
+			break;
+		}
+	}
+	
+	return len;
+}
+
+
+static int configure_dma(const unsigned char *buf)
+{
+	int len;
+	u_int8_t c;
+	int i;
+	
+	len=0;
+	
+	for (i=0;i<HPEE_DMA_MAX_ENT;i++) {
+		c = get_8(buf+len);
+		printk("DMA %d ", c&HPEE_DMA_CHANNEL_MASK);
+		/* fixme: maybe initialize the dma channel withthe timing ? */
+		len+=2;      
+		if (!(c & HPEE_DMA_MORE)) {
+			break;
+		}
+	}
+	
+	return len;
+}
+
+static int configure_port(const unsigned char *buf, struct resource *io_parent,
+		     char *board)
+{
+	int len;
+	u_int8_t c;
+	int i;
+	struct resource *res;
+	int result;
+	
+	len=0;
+	
+	for (i=0;i<HPEE_PORT_MAX_ENT;i++) {
+		c = get_8(buf+len);
+		
+		if (NULL != (res = kmalloc(sizeof(struct resource), GFP_KERNEL))) {
+			res->name = board;
+			res->start = get_16(buf+len+1);
+			res->end = get_16(buf+len+1)+(c&HPEE_PORT_SIZE_MASK)+1;
+			res->flags = IORESOURCE_IO;
+			printk("ioports %lx-%lx ", res->start, res->end);
+			result = request_resource(io_parent, res);
+			if (result < 0) {
+				printk("\n" KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
+				return result;
+			}
+		}
+
+		len+=3;      
+		if (!(c & HPEE_PORT_MORE)) {
+			break;
+		}
+	}
+	
+	return len;
+}
+
+
+/* byte 1 and 2 is the port number to write
+ * and at byte 3 the value to write starts.
+ * I assume that there are and- and or- masks
+ * here when HPEE_PORT_INIT_MASK is set but I have 
+ * not yet encountered this. */
+static int configure_port_init(const unsigned char *buf)
+{
+	int len=0;
+	u_int8_t c;
+	
+	while (len<HPEE_PORT_INIT_MAX_LEN) {
+		int s=0;
+		c = get_8(buf+len);
+		
+		switch (c & HPEE_PORT_INIT_WIDTH_MASK)  {
+		 case HPEE_PORT_INIT_WIDTH_BYTE:
+			s=1;
+			if (c & HPEE_PORT_INIT_MASK) {
+				printk("\n" KERN_WARNING "port_init: unverified mask attribute\n");
+				outb((inb(get_16(buf+len+1) & 
+					  get_8(buf+len+3)) | 
+				      get_8(buf+len+4)), get_16(buf+len+1));
+				      
+			} else {
+				outb(get_8(buf+len+3), get_16(buf+len+1));
+				      
+			}
+			break;
+		 case HPEE_PORT_INIT_WIDTH_WORD:
+			s=2;
+			if (c & HPEE_PORT_INIT_MASK) {
+ 				printk(KERN_WARNING "port_init: unverified mask attribute\n");
+				       outw((inw(get_16(buf+len+1)) &
+					     get_16(buf+len+3)) |
+					    get_16(buf+len+5), 
+					    get_16(buf+len+1));
+			} else {
+				outw(cpu_to_le16(get_16(buf+len+3)), get_16(buf+len+1));
+			}
+			break;
+		 case HPEE_PORT_INIT_WIDTH_DWORD:
+			s=4;
+			if (c & HPEE_PORT_INIT_MASK) {
+ 				printk("\n" KERN_WARNING "port_init: unverified mask attribute\n");
+				outl((inl(get_16(buf+len+1) &
+					  get_32(buf+len+3)) |
+				      get_32(buf+len+7)), get_16(buf+len+1));
+			} else {
+				outl(cpu_to_le32(get_32(buf+len+3)), get_16(buf+len+1));
+			}
+
+			break;
+		 default:
+			printk("\n" KERN_ERR "Invalid port init word %02x\n", c);
+			return 0;
+		}
+		
+		if (c & HPEE_PORT_INIT_MASK) {   
+			s*=2;
+		}
+		
+		len+=s+3;
+		if (!(c & HPEE_PORT_INIT_MORE)) {
+			break;
+		}
+	}
+	
+	return len;
+}
+
+static int configure_choise(const unsigned char *buf, u_int8_t *info)
+{
+	int len;
+	
+	/* theis record contain the value of the functions
+	 * configuration choises and an info byte which 
+	 * describes which other records to expect in this 
+	 * function */
+	len = get_8(buf);
+	*info=get_8(buf+len+1);
+	 
+	return len+2;
+}
+
+static int configure_type_string(const unsigned char *buf) 
+{
+	int len;
+	
+	/* just skip past the type field */
+	len = get_8(buf);
+	if (len > 80) {
+		printk("\n" KERN_ERR "eisa_enumerator: type info field too long (%d, max is 80)\n", len);
+	}
+	
+	return 1+len;
+}
+
+static int configure_function(const unsigned char *buf, int *more) 
+{
+	/* the init field seems to be a two-byte field
+	 * which is non-zero if there are an other function following
+	 * I think it is the length of the function def 
+	 */
+	*more = get_16(buf);
+	
+	return 2;
+}
+
+static int parse_slot_config(int slot,
+			     const unsigned char *buf,
+			     struct eeprom_eisa_slot_info *es, 
+			     struct resource *io_parent,
+			     struct resource *mem_parent)
+{
+	int res=0;
+	int function_len;
+	unsigned int pos=0;
+	unsigned int maxlen;
+	int num_func=0;
+	u_int8_t flags;
+	int p0;
+	
+	char *board;
+	int id_string_used=0;
+	
+	if (NULL == (board = kmalloc(8, GFP_KERNEL))) {
+		return -1;
+	}
+	print_eisa_id(board, es->eisa_slot_id);
+	printk(KERN_INFO "EISA slot %d: %s %s ", 
+	       slot, board, es->flags&HPEE_FLAG_BOARD_IS_ISA ? "ISA" : "EISA");
+	
+	maxlen = es->config_data_length < HPEE_MAX_LENGTH ?
+			 es->config_data_length : HPEE_MAX_LENGTH;
+	while ((pos < maxlen) && (num_func <= es->num_functions)) {
+		pos+=configure_function(buf+pos, &function_len); 
+		
+		if (!function_len) {
+			break;
+		}
+		num_func++;
+		p0 = pos;
+		pos += configure_choise(buf+pos, &flags);
+
+		if (flags & HPEE_FUNCTION_INFO_F_DISABLED) {
+			/* function disabled, skip silently */
+			pos = p0 + function_len;
+			continue;
+		}
+		if (flags & HPEE_FUNCTION_INFO_CFG_FREE_FORM) {
+			/* I have no idea how to handle this */
+			printk("function %d have free-form confgiuration, skipping ",
+				num_func);
+			pos = p0 + function_len;
+			continue;
+		}
+
+		/* the ordering of the sections need
+		 * more investigation.
+		 * Currently I think that memory comaed before IRQ
+		 * I assume the order is LSB to MSB in the 
+		 * info flags 
+		 * eg type, memory, irq, dma, port, HPEE_PORT_init 
+		 */
+
+		if (flags & HPEE_FUNCTION_INFO_HAVE_TYPE) {
+			pos += configure_type_string(buf+pos);
+		}
+		
+		if (flags & HPEE_FUNCTION_INFO_HAVE_MEMORY) {
+			id_string_used=1;
+			pos += configure_memory(buf+pos, mem_parent, board);
+		} 
+		
+		if (flags & HPEE_FUNCTION_INFO_HAVE_IRQ) {
+			pos += configure_irq(buf+pos);
+		} 
+		
+		if (flags & HPEE_FUNCTION_INFO_HAVE_DMA) {
+			pos += configure_dma(buf+pos);
+		} 
+		
+		if (flags & HPEE_FUNCTION_INFO_HAVE_PORT) {
+			id_string_used=1;
+			pos += configure_port(buf+pos, io_parent, board);
+		} 
+		
+		if (flags &  HPEE_FUNCTION_INFO_HAVE_PORT_INIT) {
+			pos += configure_port_init(buf+pos);
+		}
+		
+		if (p0 + function_len < pos) {
+			printk("\n" KERN_ERR "eisa_enumerator: function %d length mis-match "
+			       "got %d, expected %d\n",
+			       num_func, pos-p0, function_len);
+			res=-1;
+			break;
+		}
+		pos = p0 + function_len;
+	}
+	printk("\n");
+	if (!id_string_used) {
+		kfree(board);
+	}
+	
+	if (pos != es->config_data_length) {
+		printk(KERN_ERR "eisa_enumerator: config data length mis-match got %d, expected %d\n",
+			pos, es->config_data_length);
+		res=-1;
+	}
+	
+	if (num_func != es->num_functions) {
+		printk(KERN_ERR "eisa_enumerator: number of functions mis-match got %d, expected %d\n",
+			num_func, es->num_functions);
+		res=-2;
+	}
+	
+	return res;
+	
+}
+
+static int init_slot(int slot, struct eeprom_eisa_slot_info *es)
+{
+	unsigned int id;
+	
+	char id_string[8];
+	
+	if (!(es->slot_info&HPEE_SLOT_INFO_NO_READID)) {
+		/* try to read the id of the board in the slot */
+		id = le32_to_cpu(inl(SLOT2PORT(slot)+EPI));
+		
+		if (0xffffffff == id) {
+			/* this board is not here or it does not 
+			 * support readid 
+			 */
+			printk(KERN_ERR "EISA slot %d a configured board was not detected (", 
+			       slot);
+			
+			print_eisa_id(id_string, es->eisa_slot_id);
+			printk(" expected %s)\n", id_string);
+		
+			return -1;	
+
+		}
+		if (es->eisa_slot_id != id) {
+			print_eisa_id(id_string, id);
+			printk(KERN_ERR "EISA slot %d id mis-match: got %s", 
+			       slot, id_string);
+			
+			print_eisa_id(id_string, es->eisa_slot_id);
+			printk(" expected %s \n", id_string);
+		
+			return -1;	
+			
+		}
+	}
+	
+	/* now: we need to enable the board if 
+	 * it supports enabling and run through
+	 * the port init sction if present
+	 * and finally record any interrupt polarity
+	 */
+	if (es->slot_features & HPEE_SLOT_FEATURES_ENABLE) {
+		/* enable board */
+		outb(0x01| inb(SLOT2PORT(slot)+EPI+4),
+		     SLOT2PORT(slot)+EPI+4);
+	}
+	
+	return 0;
+}
+
+
+int eisa_enumerator(unsigned long eeprom_addr,
+		    struct resource *io_parent, struct resource *mem_parent) 
+{
+	int i;
+	struct eeprom_header *eh;
+	static char eeprom_buf[HPEE_MAX_LENGTH];
+	
+	for (i=0; i < HPEE_MAX_LENGTH; i++) {
+		eeprom_buf[i] = gsc_readb(eeprom_addr+i);
+	}
+	
+	printk(KERN_INFO "Enumerating EISA bus\n");
+		    	
+	eh = (struct eeprom_header*)(eeprom_buf);
+	for (i=0;i<eh->num_slots;i++) {
+		struct eeprom_eisa_slot_info *es;
+		
+		es = (struct eeprom_eisa_slot_info*)
+			(&eeprom_buf[HPEE_SLOT_INFO(i)]);
+	        
+		if (-1==init_slot(i+1, es)) {
+			return -1;
+			
+		}
+		
+		if (es->config_data_offset < HPEE_MAX_LENGTH) {
+			if (parse_slot_config(i+1, &eeprom_buf[es->config_data_offset],
+					      es, io_parent, mem_parent)) {
+				return -1;
+			}
+		} else {
+			printk (KERN_WARNING "EISA EEPROM offset 0x%x out of range\n",es->config_data_offset);
+			return -1;
+		}
+	}
+	return 0;
+}
+
diff -Nru a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/parisc/gsc.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,205 @@
+/*
+ * Interrupt management for most GSC and related devices.
+ *
+ * (c) Copyright 1999 Alex deVries for The Puffin Group
+ * (c) Copyright 1999 Grant Grundler for Hewlett-Packard
+ * (c) Copyright 1999 Matthew Wilcox
+ * (c) Copyright 2000 Helge Deller
+ * (c) Copyright 2001 Matthew Wilcox for Hewlett-Packard
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2 of the License, or
+ *      (at your option) any later version.
+ */
+
+#include <linux/bitops.h>
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include "gsc.h"
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DEBPRINTK printk
+#else
+#define DEBPRINTK(x,...)
+#endif
+
+int gsc_alloc_irq(struct gsc_irq *i)
+{
+	int irq = txn_alloc_irq();
+	if (irq < 0) {
+		printk("cannot get irq\n");
+		return irq;
+	}
+
+	i->txn_addr = txn_alloc_addr(irq);
+	i->txn_data = txn_alloc_data(irq, GSC_EIM_WIDTH);
+	i->irq = irq;
+
+	return irq;
+}
+
+int gsc_claim_irq(struct gsc_irq *i, int irq)
+{
+	int c = irq;
+
+	irq += IRQ_FROM_REGION(CPU_IRQ_REGION); /* virtualize the IRQ first */
+
+	irq = txn_claim_irq(irq);
+	if (irq < 0) {
+		printk("cannot claim irq %d\n", c);
+		return irq;
+	}
+
+	i->txn_addr = txn_alloc_addr(irq);
+	i->txn_data = txn_alloc_data(irq, GSC_EIM_WIDTH);
+	i->irq = irq;
+
+	return irq;
+}
+
+EXPORT_SYMBOL(gsc_alloc_irq);
+EXPORT_SYMBOL(gsc_claim_irq);
+
+/* IRQ bits must be numbered from Most Significant Bit */
+#define GSC_FIX_IRQ(x)	(31-(x))
+#define GSC_MASK_IRQ(x)	(1<<(GSC_FIX_IRQ(x)))
+
+/* Common interrupt demultiplexer used by Asp, Lasi & Wax.  */
+void busdev_barked(int busdev_irq, void *dev, struct pt_regs *regs)
+{
+	unsigned long irq;
+	struct busdevice *busdev = (struct busdevice *) dev;
+
+	/* 
+	    Don't need to protect OFFSET_IRR with spinlock since this is
+	    the only place it's touched.
+	    Protect busdev_region by disabling this region's interrupts,
+	    modifying the region, and then re-enabling the region.
+	*/
+
+	irq = gsc_readl(busdev->hpa+OFFSET_IRR);
+	if (irq == 0) {
+		printk(KERN_ERR "%s: barking without apparent reason.\n", busdev->name);
+	} else {
+		DEBPRINTK ("%s (0x%x) barked, mask=0x%x, irq=%d\n", 
+		    busdev->name, busdev->busdev_region->data.irqbase, 
+		    irq, GSC_FIX_IRQ(ffs(irq))+1 );
+
+		do_irq_mask(irq, busdev->busdev_region, regs);
+	}
+}
+
+static void
+busdev_disable_irq(void *irq_dev, int irq)
+{
+	/* Disable the IRQ line by clearing the bit in the IMR */
+	u32 imr = gsc_readl(BUSDEV_DEV(irq_dev)->hpa+OFFSET_IMR);
+	imr &= ~(GSC_MASK_IRQ(irq));
+
+	DEBPRINTK( KERN_WARNING "%s(%p, %d) %s: IMR 0x%x\n", 
+		    __FUNCTION__, irq_dev, irq, BUSDEV_DEV(irq_dev)->name, imr);
+
+	gsc_writel(imr, BUSDEV_DEV(irq_dev)->hpa+OFFSET_IMR);
+}
+
+
+static void
+busdev_enable_irq(void *irq_dev, int irq)
+{
+	/* Enable the IRQ line by setting the bit in the IMR */
+	unsigned long addr = BUSDEV_DEV(irq_dev)->hpa + OFFSET_IMR;
+	u32 imr = gsc_readl(addr);
+	imr |= GSC_MASK_IRQ(irq);
+
+	DEBPRINTK (KERN_WARNING "%s(%p, %d) %s: IMR 0x%x\n", 
+		    __FUNCTION__, irq_dev, irq, BUSDEV_DEV(irq_dev)->name, imr);
+
+	gsc_writel(imr, addr);
+//	gsc_writel(~0L, addr);
+
+/* FIXME: read IPR to make sure the IRQ isn't already pending.
+**   If so, we need to read IRR and manually call do_irq_mask().
+**   This code should be shared with busdev_unmask_irq().
+*/
+}
+
+static void
+busdev_mask_irq(void *irq_dev, int irq)
+{
+/* FIXME: Clear the IMR bit in busdev for that IRQ */
+}
+
+static void
+busdev_unmask_irq(void *irq_dev, int irq)
+{
+/* FIXME: Read IPR. Set the IMR bit in busdev for that IRQ.
+   call do_irq_mask() if IPR is non-zero
+*/
+}
+
+struct irq_region_ops busdev_irq_ops = {
+	disable_irq:	busdev_disable_irq,
+	enable_irq:	busdev_enable_irq,
+	mask_irq:	busdev_mask_irq,
+	unmask_irq:	busdev_unmask_irq
+};
+
+
+int gsc_common_irqsetup(struct parisc_device *parent, struct busdevice *busdev)
+{
+	struct resource *res;
+
+	busdev->gsc = parent;
+
+	/* the IRQs we simulate */
+	busdev->busdev_region = alloc_irq_region(32, &busdev_irq_ops,
+						 busdev->name, busdev);
+	if (!busdev->busdev_region)
+		return -ENOMEM;
+
+	/* allocate resource region */
+	res = request_mem_region(busdev->hpa, 0x100000, busdev->name);
+	if (res) {
+		res->flags = IORESOURCE_MEM; 	/* do not mark it busy ! */
+	}
+
+#if 0
+	printk(KERN_WARNING "%s IRQ %d EIM 0x%x", busdev->name,
+			busdev->parent_irq, busdev->eim);
+	if (gsc_readl(busdev->hpa + OFFSET_IMR))
+		printk("  IMR is non-zero! (0x%x)",
+				gsc_readl(busdev->hpa + OFFSET_IMR));
+	printk("\n");
+#endif
+
+	return 0;
+}
+
+extern struct parisc_driver lasi_driver;
+extern struct parisc_driver asp_driver;
+extern struct parisc_driver wax_driver;
+
+void __init gsc_init(void)
+{
+#ifdef CONFIG_GSC_LASI
+	register_parisc_driver(&lasi_driver);
+	register_parisc_driver(&asp_driver);
+#endif
+#ifdef CONFIG_GSC_WAX
+	register_parisc_driver(&wax_driver);
+#endif
+}
diff -Nru a/drivers/parisc/gsc.h b/drivers/parisc/gsc.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/parisc/gsc.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,45 @@
+/*
+ * drivers/parisc/gsc.h
+ * Declarations for functions in gsc.c
+ * Copyright (c) 2000-2002 Helge Deller, Matthew Wilcox
+ *
+ * Distributed under the terms of the GPL, version 2
+ */
+
+#include <linux/interrupt.h>
+#include <asm/hardware.h>
+
+#define OFFSET_IRR 0x0000   /* Interrupt request register */
+#define OFFSET_IMR 0x0004   /* Interrupt mask register */
+#define OFFSET_IPR 0x0008   /* Interrupt pending register */
+#define OFFSET_ICR 0x000C   /* Interrupt control register */
+#define OFFSET_IAR 0x0010   /* Interrupt address register */
+
+/* PA I/O Architected devices support at least 5 bits in the EIM register. */
+#define GSC_EIM_WIDTH 5
+
+struct gsc_irq {
+	unsigned long txn_addr;	/* IRQ "target" */
+	int txn_data;		/* HW "IRQ" */
+	int irq;		/* virtual IRQ */
+};
+
+struct busdevice {
+	struct parisc_device *gsc;
+	unsigned long hpa;
+	char *name;
+	int version;
+	int type;
+	int parent_irq;
+	int eim;
+	struct irq_region *busdev_region;
+};
+
+/* short cut to keep the compiler happy */
+#define BUSDEV_DEV(x)	((struct busdevice *) (x))
+
+int gsc_common_irqsetup(struct parisc_device *parent, struct busdevice *busdev);
+extern int gsc_alloc_irq(struct gsc_irq *dev);	/* dev needs an irq */
+extern int gsc_claim_irq(struct gsc_irq *dev, int irq);	/* dev needs this irq */
+
+void busdev_barked(int busdev_irq, void *dev, struct pt_regs *regs);
diff -Nru a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/parisc/iosapic.c	Mon Nov  4 14:31:01 2002
@@ -0,0 +1,1092 @@
+/*
+** I/O Sapic Driver - PCI interrupt line support
+**
+**      (c) Copyright 1999 Grant Grundler
+**      (c) Copyright 1999 Hewlett-Packard Company
+**
+**      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.
+**
+** The I/O sapic driver manages the Interrupt Redirection Table which is
+** the control logic to convert PCI line based interrupts into a Message
+** Signaled Interrupt (aka Transaction Based Interrupt, TBI).
+**
+** Acronyms
+** --------
+** HPA  Hard Physical Address (aka MMIO address)
+** IRQ  Interrupt ReQuest. Implies Line based interrupt.
+** IRT	Interrupt Routing Table (provided by PAT firmware)
+** IRdT Interrupt Redirection Table. IRQ line to TXN ADDR/DATA
+**      table which is implemented in I/O SAPIC.
+** ISR  Interrupt Service Routine. aka Interrupt handler.
+** MSI	Message Signaled Interrupt. PCI 2.2 functionality.
+**      aka Transaction Based Interrupt (or TBI).
+** PA   Precision Architecture. HP's RISC architecture.
+** RISC Reduced Instruction Set Computer.
+**
+**
+** What's a Message Signalled Interrupt?
+** -------------------------------------
+** MSI is a write transaction which targets a processor and is similar
+** to a processor write to memory or MMIO. MSIs can be generated by I/O
+** devices as well as processors and require *architecture* to work.
+**
+** PA only supports MSI. So I/O subsystems must either natively generate
+** MSIs (e.g. GSC or HP-PB) or convert line based interrupts into MSIs
+** (e.g. PCI and EISA).  IA64 supports MSIs via a "local SAPIC" which
+** acts on behalf of a processor.
+**
+** MSI allows any I/O device to interrupt any processor. This makes
+** load balancing of the interrupt processing possible on an SMP platform.
+** Interrupts are also ordered WRT to DMA data.  It's possible on I/O
+** coherent systems to completely eliminate PIO reads from the interrupt
+** path. The device and driver must be designed and implemented to
+** guarantee all DMA has been issued (issues about atomicity here)
+** before the MSI is issued. I/O status can then safely be read from
+** DMA'd data by the ISR.
+**
+**
+** PA Firmware
+** -----------
+** PA-RISC platforms have two fundementally different types of firmware.
+** For PCI devices, "Legacy" PDC initializes the "INTERRUPT_LINE" register
+** and BARs similar to a traditional PC BIOS.
+** The newer "PAT" firmware supports PDC calls which return tables.
+** PAT firmware only initializes PCI Console and Boot interface.
+** With these tables, the OS can progam all other PCI devices.
+**
+** One such PAT PDC call returns the "Interrupt Routing Table" (IRT).
+** The IRT maps each PCI slot's INTA-D "output" line to an I/O SAPIC
+** input line.  If the IRT is not available, this driver assumes
+** INTERRUPT_LINE register has been programmed by firmware. The latter
+** case also means online addition of PCI cards can NOT be supported
+** even if HW support is present.
+**
+** All platforms with PAT firmware to date (Oct 1999) use one Interrupt
+** Routing Table for the entire platform.
+**
+** Where's the iosapic?
+** --------------------
+** I/O sapic is part of the "Core Electronics Complex". And on HP platforms
+** it's integrated as part of the PCI bus adapter, "lba".  So no bus walk
+** will discover I/O Sapic. I/O Sapic driver learns about each device
+** when lba driver advertises the presence of the I/O sapic by calling
+** iosapic_register().
+**
+**
+** IRQ region notes
+** ----------------
+** The data passed to iosapic_interrupt() is per IRQ line.
+** Each IRQ line will get one txn_addr/data pair. Thus each IRQ region,
+** will have several txn_addr/data pairs (up to 7 for current I/O SAPIC
+** implementations).  The IRQ region "sysdata" will NOT be directly passed
+** to the interrupt handler like GSCtoPCI (dino.c).
+**
+** iosapic interrupt handler will NOT call do_irq_mask().
+** It doesn't need to read a bit mask to determine which IRQ line was pulled
+** since it already knows based on vector_info passed to iosapic_interrupt().
+**
+** One IRQ number represents both an IRQ line and a driver ISR.
+** The I/O sapic driver can't manage shared IRQ lines because
+** additional data besides the IRQ number must be passed via
+** irq_region_ops. do_irq() and request_irq() must manage
+** a sharing a bit in the mask.
+**
+** iosapic_interrupt() replaces do_irq_mask() and calls do_irq().
+** Which IRQ line was asserted is already known since each
+** line has unique data associated with it. We could omit
+** iosapic_interrupt() from the calling path if it did NOT need
+** to write EOI. For unshared lines, it really doesn't.
+**
+** Unfortunately, can't optimize out EOI if IRQ line isn't "shared".
+** N-class console "device" and some sort of heartbeat actually share
+** one line though only one driver is registered...<sigh>...this was
+** true for HP-UX at least. May not be true for parisc-linux.
+**
+**
+** Overview of exported iosapic functions
+** --------------------------------------
+** (caveat: code isn't finished yet - this is just the plan)
+**
+** iosapic_init:
+**   o initialize globals (lock, etc)
+**   o try to read IRT. Presence of IRT determines if this is
+**     a PAT platform or not.
+**
+** iosapic_register():
+**   o create iosapic_info instance data structure
+**   o allocate vector_info array for this iosapic
+**   o initialize vector_info - read corresponding IRdT?
+**
+** iosapic_xlate_pin: (only called by fixup_irq for PAT platform)
+**   o intr_pin = read cfg (INTERRUPT_PIN);
+**   o if (device under PCI-PCI bridge)
+**               translate slot/pin
+**
+** iosapic_fixup_irq:
+**   o if PAT platform (IRT present)
+**	   intr_pin = iosapic_xlate_pin(isi,pcidev):
+**         intr_line = find IRT entry(isi, PCI_SLOT(pcidev), intr_pin)
+**         save IRT entry into vector_info later
+**         write cfg INTERRUPT_LINE (with intr_line)?
+**     else
+**         intr_line = pcidev->irq
+**         IRT pointer = NULL
+**     endif
+**   o locate vector_info (needs: isi, intr_line)
+**   o allocate processor "irq" and get txn_addr/data
+**   o request_irq(processor_irq,  iosapic_interrupt, vector_info,...)
+**   o pcidev->irq = isi->isi_region...base + intr_line;
+**
+** iosapic_interrupt:
+**   o call do_irq(vector->isi->irq_region, vector->irq_line, regs)
+**   o assume level triggered and write EOI
+**
+** iosapic_enable_irq:
+**   o clear any pending IRQ on that line
+**   o enable IRdT - call enable_irq(vector[line]->processor_irq)
+**   o write EOI in case line is already asserted.
+**
+** iosapic_disable_irq:
+**   o disable IRdT - call disable_irq(vector[line]->processor_irq)
+**
+** FIXME: mask/unmask
+*/
+
+
+/* FIXME: determine which include files are really needed */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/pci.h>		/* pci cfg accessor functions  */
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>	/* irqaction */
+#include <linux/irq.h>		/* irq_region support */
+
+#include <asm/byteorder.h>	/* get in-line asm for swab */
+#include <asm/pdc.h>
+#include <asm/page.h>
+#include <asm/segment.h>
+#include <asm/system.h>
+#include <asm/io.h>		/* gsc_read/write functions */
+#ifdef CONFIG_SUPERIO
+#include <asm/superio.h>
+#endif
+
+#include <asm/iosapic.h>
+#include "./iosapic_private.h"
+
+#define MODULE_NAME "iosapic"
+
+/* "local" compile flags */
+#undef PCI_BRIDGE_FUNCS
+#undef DEBUG_IOSAPIC
+#undef DEBUG_IOSAPIC_IRT
+
+
+#ifdef DEBUG_IOSAPIC
+static char assert_buf[128];
+
+static int
+assert_failed (char *a, char *f, int l)
+{
+        sprintf(assert_buf,
+			"ASSERT(%s) failed!\nline %d in %s\n",
+			a,      /* assertion text */
+			l,      /* line number */
+			f);     /* file name */
+        panic(assert_buf);
+	return 0;
+}
+
+#undef ASSERT
+#define ASSERT(EX) { if (!(EX)) assert_failed(# EX, __FILE__, __LINE__); }
+
+#define DBG(x...) printk(x)
+
+#else /* DEBUG_IOSAPIC */
+
+#define DBG(x...)
+#undef	ASSERT
+#define ASSERT(EX)
+
+#endif /* DEBUG_IOSAPIC */
+
+#ifdef DEBUG_IOSAPIC_IRT
+#define DBG_IRT(x...) printk(x)
+#else
+#define DBG_IRT(x...)
+#endif
+
+
+#define READ_U8(addr)  gsc_readb(addr)
+#define READ_U16(addr) le16_to_cpu(gsc_readw((u16 *) (addr)))
+#define READ_U32(addr) le32_to_cpu(gsc_readl((u32 *) (addr)))
+#define READ_REG16(addr) gsc_readw((u16 *) (addr))
+#define READ_REG32(addr) gsc_readl((u32 *) (addr))
+#define WRITE_U8(value, addr) gsc_writeb(value, addr)
+#define WRITE_U16(value, addr) gsc_writew(cpu_to_le16(value), (u16 *) (addr))
+#define WRITE_U32(value, addr) gsc_writel(cpu_to_le32(value), (u32 *) (addr))
+#define WRITE_REG16(value, addr) gsc_writew(value, (u16 *) (addr))
+#define WRITE_REG32(value, addr) gsc_writel(value, (u32 *) (addr))
+
+
+#define IOSAPIC_REG_SELECT              0
+#define IOSAPIC_REG_WINDOW              0x10
+#define IOSAPIC_REG_EOI                 0x40
+
+#define IOSAPIC_REG_VERSION		0x1
+
+#define IOSAPIC_IRDT_ENTRY(idx)		(0x10+(idx)*2)
+#define IOSAPIC_IRDT_ENTRY_HI(idx)	(0x11+(idx)*2)
+
+/*
+** FIXME: revisit which GFP flags we should really be using.
+**     GFP_KERNEL includes __GFP_WAIT flag and that may not
+**     be acceptable. Since this is boot time, we shouldn't have
+**     to wait ever and this code should (will?) never get called
+**     from the interrrupt context.
+*/
+#define	IOSAPIC_KALLOC(a_type, cnt) \
+			(a_type *) kmalloc(sizeof(a_type)*(cnt), GFP_KERNEL)
+#define IOSAPIC_FREE(addr, f_type, cnt) kfree((void *)addr)
+
+
+#define	IOSAPIC_LOCK(lck)	spin_lock_irqsave(lck, irqflags)
+#define	IOSAPIC_UNLOCK(lck)	spin_unlock_irqrestore(lck, irqflags)
+
+
+#define IOSAPIC_VERSION_MASK            0x000000ff
+#define IOSAPIC_VERSION_SHIFT           0x0
+#define	IOSAPIC_VERSION(ver)				\
+		(int) ((ver & IOSAPIC_VERSION_MASK) >> IOSAPIC_VERSION_SHIFT)
+
+#define IOSAPIC_MAX_ENTRY_MASK          0x00ff0000
+
+#define IOSAPIC_MAX_ENTRY_SHIFT         0x10
+#define	IOSAPIC_IRDT_MAX_ENTRY(ver)			\
+		(int) ((ver&IOSAPIC_MAX_ENTRY_MASK) >> IOSAPIC_MAX_ENTRY_SHIFT)
+
+/* bits in the "low" I/O Sapic IRdT entry */
+#define IOSAPIC_IRDT_ENABLE       0x10000
+#define IOSAPIC_IRDT_PO_LOW       0x02000
+#define IOSAPIC_IRDT_LEVEL_TRIG   0x08000
+#define IOSAPIC_IRDT_MODE_LPRI    0x00100
+
+/* bits in the "high" I/O Sapic IRdT entry */
+#define IOSAPIC_IRDT_ID_EID_SHIFT              0x10
+
+
+
+#define	IOSAPIC_EOI(eoi_addr, eoi_data) gsc_writel(eoi_data, eoi_addr)
+
+static struct iosapic_info *iosapic_list;
+static spinlock_t iosapic_lock;
+static int iosapic_count;
+
+
+/*
+** REVISIT: future platforms may have more than one IRT.
+** If so, the following three fields form a structure which
+** then be linked into a list. Names are chosen to make searching
+** for them easy - not necessarily accurate (eg "cell").
+**
+** Alternative: iosapic_info could point to the IRT it's in.
+** iosapic_register() could search a list of IRT's.
+*/
+static struct irt_entry *irt_cell;
+static size_t irt_num_entry;
+
+
+
+/*
+** iosapic_load_irt
+**
+** The "Get PCI INT Routing Table Size" option returns the number of 
+** entries in the PCI interrupt routing table for the cell specified 
+** in the cell_number argument.  The cell number must be for a cell 
+** within the caller's protection domain.
+**
+** The "Get PCI INT Routing Table" option returns, for the cell 
+** specified in the cell_number argument, the PCI interrupt routing 
+** table in the caller allocated memory pointed to by mem_addr.
+** We assume the IRT only contains entries for I/O SAPIC and
+** calculate the size based on the size of I/O sapic entries.
+**
+** The PCI interrupt routing table entry format is derived from the
+** IA64 SAL Specification 2.4.   The PCI interrupt routing table defines
+** the routing of PCI interrupt signals between the PCI device output
+** "pins" and the IO SAPICs' input "lines" (including core I/O PCI
+** devices).  This table does NOT include information for devices/slots
+** behind PCI to PCI bridges. See PCI to PCI Bridge Architecture Spec.
+** for the architected method of routing of IRQ's behind PPB's.
+*/
+
+
+static int __init /* return number of entries as success/fail flag */
+iosapic_load_irt(unsigned long cell_num, struct irt_entry **irt)
+{
+	long status;              /* PDC return value status */
+	struct irt_entry *table;  /* start of interrupt routing tbl */
+	unsigned long num_entries = 0UL;
+
+	ASSERT(NULL != irt);
+
+	if (is_pdc_pat()) {
+
+		/* 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);
+
+		ASSERT(status == PDC_OK);
+
+		/* save the number of entries in the table */
+		ASSERT(0UL != num_entries);
+
+		/*
+		** allocate memory for interrupt routing table
+		** This interface isn't really right. We are assuming
+		** the contents of the table are exclusively
+		** for I/O sapic devices.
+		*/
+		table = IOSAPIC_KALLOC(struct irt_entry, num_entries);
+		if (table == NULL) {
+			printk(KERN_WARNING MODULE_NAME ": read_irt : can not alloc mem for IRT\n");
+			return 0;
+		}
+
+		/* get PCI INT routing table */
+		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 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)
+			return 0;
+
+		/* 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_OK != status) {
+			/* Not a "legacy" system with I/O SAPIC either */
+			return 0;
+		}
+
+		ASSERT(0UL != num_entries);
+
+		table = IOSAPIC_KALLOC(struct irt_entry, num_entries);
+		if (table == NULL) {
+			printk(KERN_WARNING MODULE_NAME ": read_irt : can not alloc mem for IRT\n");
+			return 0;
+		}
+
+		/* 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(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(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,
+		((u32 *) p)[2],
+		((u32 *) p)[3]
+		);
+	}
+}
+#endif /* DEBUG_IOSAPIC_IRT */
+
+	return num_entries;
+}
+
+
+
+void __init
+iosapic_init(void)
+{
+	unsigned long cell = 0;
+
+	/* init global data */
+	iosapic_lock = SPIN_LOCK_UNLOCKED;
+        iosapic_list = (struct iosapic_info *) NULL;
+	iosapic_count = 0;
+
+	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(cell, &irt_cell);
+	if (0 == irt_num_entry)
+		irt_cell = NULL;	/* old PDC w/o iosapic */
+}
+
+
+/*
+** Return the IRT entry in case we need to look something else up.
+*/
+static struct irt_entry *
+irt_find_irqline(struct iosapic_info *isi, u8 slot, u8 intr_pin)
+{
+	struct irt_entry *i = irt_cell;
+	int cnt;	/* track how many entries we've looked at */
+	u8 irq_devno = (slot << IRT_DEV_SHIFT) | (intr_pin-1);
+
+	DBG_IRT("irt_find_irqline() SLOT %d pin %d\n", slot, intr_pin);
+
+	for (cnt=0; cnt < irt_num_entry; cnt++, i++) {
+
+		/*
+		** Validate: entry_type, entry_length, interrupt_type
+		**
+		** Difference between validate vs compare is the former
+		** should print debug info and is not expected to "fail"
+		** on current platforms.
+		*/
+		if (i->entry_type != IRT_IOSAPIC_TYPE) {
+			DBG_IRT(KERN_WARNING MODULE_NAME ":find_irqline(0x%p): skipping entry %d type %d\n", i, cnt, i->entry_type);
+			continue;
+		}
+		
+		if (i->entry_length != IRT_IOSAPIC_LENGTH) {
+			DBG_IRT(KERN_WARNING MODULE_NAME ":find_irqline(0x%p): skipping entry %d  length %d\n", i, cnt, i->entry_length);
+			continue;
+		}
+
+		if (i->interrupt_type != IRT_VECTORED_INTR) {
+			DBG_IRT(KERN_WARNING MODULE_NAME ":find_irqline(0x%p): skipping entry  %d interrupt_type %d\n", i, cnt, i->interrupt_type);
+			continue;
+		}
+
+		/*
+		** Compare: dest_iosapic_addr, src_bus_irq_devno
+		*/
+		if (i->dest_iosapic_addr != (u64) ((long) isi->isi_hpa))
+			continue;
+
+		if ((i->src_bus_irq_devno & IRT_IRQ_DEVNO_MASK) != irq_devno)
+			continue;
+
+		/*
+		** Ignore: src_bus_id and rc_seg_id correlate with
+		**         iosapic_info->isi_hpa on HP platforms.
+		**         If needed, pass in "PFA" (aka config space addr)
+		**         instead of slot.
+		*/
+
+		/* Found it! */
+		return i;
+	}
+
+	printk(KERN_WARNING MODULE_NAME ": 0x%lx : no IRT entry for slot %d, pin %d\n",
+			isi->isi_hpa, slot, intr_pin);
+	return NULL;
+}
+
+
+/*
+** xlate_pin() supports the skewing of IRQ lines done by subsidiary bridges.
+** Legacy PDC already does this translation for us and stores it in INTR_LINE.
+**
+** PAT PDC needs to basically do what legacy PDC does:
+** o read PIN
+** o adjust PIN in case device is "behind" a PPB
+**     (eg 4-port 100BT and SCSI/LAN "Combo Card")
+** o convert slot/pin to I/O SAPIC input line.
+**
+** HP platforms only support:
+** o one level of skewing for any number of PPBs
+** o only support PCI-PCI Bridges.
+*/
+static struct irt_entry *
+iosapic_xlate_pin(struct iosapic_info *isi, struct pci_dev *pcidev)
+{
+	u8 intr_pin, intr_slot;
+
+	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);
+
+	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) {
+		/* Convert pcidev INTR_PIN into something we
+		** can lookup in the IRT.
+		*/
+#ifdef PCI_BRIDGE_FUNCS
+		/*
+		** Proposal #1:
+		**
+		** call implementation specific translation function
+		** This is architecturally "cleaner". HP-UX doesn't
+		** support other secondary bus types (eg. E/ISA) directly.
+		** May be needed for other processor (eg IA64) architectures
+		** 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);
+		}
+#else	/* PCI_BRIDGE_FUNCS */
+		struct pci_bus *p = pcidev->bus;
+		/*
+		** Proposal #2:
+		** The "pin" is skewed ((pin + dev - 1) % 4).
+		**
+		** This isn't very clean since I/O SAPIC must assume:
+		**   - all platforms only have PCI busses.
+		**   - only PCI-PCI bridge (eg not PCI-EISA, PCI-PCMCIA)
+		**   - IRQ routing is only skewed once regardless of
+		**     the number of PPB's between iosapic and device.
+		**     (Bit3 expansion chassis follows this rule)
+		**
+		** Advantage is it's really easy to implement.
+		*/
+		intr_pin = ((intr_pin-1)+PCI_SLOT(pcidev->devfn)) % 4;
+		intr_pin++;	/* convert back to INTA-D (1-4) */
+#endif /* PCI_BRIDGE_FUNCS */
+
+		/*
+		** Locate the host slot the PPB nearest the Host bus
+		** adapter.
+		*/
+		while (NULL != p->parent->self)
+			p = p->parent;
+
+		intr_slot = PCI_SLOT(p->self->devfn);
+	} else {
+		intr_slot = PCI_SLOT(pcidev->devfn);
+	}
+	DBG_IRT("iosapic_xlate_pin:  bus %d slot %d pin %d\n",
+				pcidev->bus->secondary, intr_slot, intr_pin);
+
+	return irt_find_irqline(isi, intr_slot, intr_pin);
+}
+
+
+static void
+iosapic_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct vector_info *vi = (struct vector_info *)dev_id;
+	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);
+
+/* FIXME: Need to mask/unmask? processor IRQ is already masked... */
+	do_irq(&vi->vi_ios->isi_region->action[vi->vi_irqline], irq_num, regs);
+
+	/*
+	** PCI only supports level triggered in order to share IRQ lines.
+	** I/O SAPIC must always issue EOI.
+	*/
+	IOSAPIC_EOI(vi->vi_eoi_addr, vi->vi_eoi_data);
+}
+
+
+int
+iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev)
+{
+	struct iosapic_info *isi = (struct iosapic_info *)isi_obj;
+	struct irt_entry *irte = NULL;  /* only used if PAT PDC */
+	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 ": 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) {
+		return(-1);
+	}
+	DBG_IRT("iosapic_fixup_irq(): irte %p %x %x %x %x %x %x %x %x\n",
+		irte,
+		irte->entry_type,
+		irte->entry_length,
+		irte->polarity_trigger,
+		irte->src_bus_irq_devno,
+		irte->src_bus_id,
+		irte->src_seg_id,
+		irte->dest_iosapic_intin,
+		(u32) irte->dest_iosapic_addr);
+	isi_line = irte->dest_iosapic_intin;
+
+	/* get vector info for this input line */
+	ASSERT(NULL != isi->isi_vector);
+	vi = &(isi->isi_vector[isi_line]);
+	DBG_IRT("iosapic_fixup_irq:  line %d vi 0x%p\n", isi_line, vi);
+	vi->vi_irte = irte;
+
+	/* Allocate processor IRQ */
+	vi->vi_txn_irq = txn_alloc_irq();
+
+/* XXX/FIXME The txn_alloc_irq() code and related code should be moved
+** to enable_irq(). That way we only allocate processor IRQ bits
+** for devices that actually have drivers claiming them.
+** Right now we assign an IRQ to every PCI device present regardless
+** of whether it's used or not.
+*/
+	if (vi->vi_txn_irq < 0)
+		panic("I/O sapic: couldn't get TXN IRQ\n");
+
+	/* enable_irq() will use txn_* to program IRdT */
+	vi->vi_txn_addr = txn_alloc_addr(vi->vi_txn_irq);
+	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,
+						vi->vi_name, vi);
+	ASSERT(tmp == 0);
+
+	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.  */
+
+	return_irq = isi->isi_region->data.irqbase + isi_line;
+
+#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 return_irq;
+}
+
+
+static void
+iosapic_rd_irt_entry(struct vector_info *vi , u32 *dp0, u32 *dp1)
+{
+	struct iosapic_info *isp = vi->vi_ios;
+	u8 idx = vi->vi_irqline;
+
+	/* point the window register to the lower word */
+	WRITE_U32(IOSAPIC_IRDT_ENTRY(idx), isp->isi_hpa+IOSAPIC_REG_SELECT);
+	*dp0 = READ_U32(isp->isi_hpa+IOSAPIC_REG_WINDOW);
+
+	/* point the window register to the higher word */
+	WRITE_U32(IOSAPIC_IRDT_ENTRY_HI(idx), isp->isi_hpa+IOSAPIC_REG_SELECT);
+	*dp1 = READ_U32(isp->isi_hpa+IOSAPIC_REG_WINDOW);
+}
+
+
+static void
+iosapic_wr_irt_entry(struct vector_info *vi, u32 dp0, u32 dp1)
+{
+	struct iosapic_info *isp = vi->vi_ios;
+
+	ASSERT(NULL != isp);
+	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,
+		dp0, dp1);
+
+	/* point the window register to the lower word */
+	WRITE_U32(IOSAPIC_IRDT_ENTRY(vi->vi_irqline), isp->isi_hpa+IOSAPIC_REG_SELECT);
+	WRITE_U32( dp0, isp->isi_hpa+IOSAPIC_REG_WINDOW);
+
+	/* Read the window register to flush the writes down to HW  */
+	dp0 = READ_U32(isp->isi_hpa+IOSAPIC_REG_WINDOW);
+
+	/* point the window register to the higher word */
+	WRITE_U32(IOSAPIC_IRDT_ENTRY_HI(vi->vi_irqline), isp->isi_hpa+IOSAPIC_REG_SELECT);
+	WRITE_U32( dp1, isp->isi_hpa+IOSAPIC_REG_WINDOW);
+
+	/* Read the window register to flush the writes down to HW  */
+	dp1 = READ_U32(isp->isi_hpa+IOSAPIC_REG_WINDOW);
+}
+
+
+/*
+** set_irt prepares the data (dp0, dp1) according to the vector_info
+** and target cpu (id_eid).  dp0/dp1 are then used to program I/O SAPIC
+** IRdT for the given "vector" (aka IRQ line).
+*/
+static void
+iosapic_set_irt_data( struct vector_info *vi, u32 *dp0, u32 *dp1)
+{
+	u32 mode = 0;
+	struct irt_entry *p = vi->vi_irte;
+	ASSERT(NULL != vi->vi_irte);
+
+	if ((p->polarity_trigger & IRT_PO_MASK) == IRT_ACTIVE_LO)
+		mode |= IOSAPIC_IRDT_PO_LOW;
+
+	if (((p->polarity_trigger >> IRT_EL_SHIFT) & IRT_EL_MASK) == IRT_LEVEL_TRIG)
+		mode |= IOSAPIC_IRDT_LEVEL_TRIG;
+
+	/*
+	** IA64 REVISIT
+	** PA doesn't support EXTINT or LPRIO bits.
+	*/
+
+	ASSERT(vi->vi_txn_data);
+	*dp0 = mode | (u32) vi->vi_txn_data;
+
+	/*
+	** Extracting id_eid isn't a real clean way of getting it.
+	** But the encoding is the same for both PA and IA64 platforms.
+	*/
+	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 {
+		/* 
+		** eg if base_addr == 0xfffa0000),
+		**    we want to get 0xa0ff0000.
+		**
+		** eid	0x0ff00000 -> 0x00ff0000
+		** id	0x000ff000 -> 0xff000000
+		*/
+		*dp1 = (((u32)vi->vi_txn_addr & 0x0ff00000) >> 4) |
+			(((u32)vi->vi_txn_addr & 0x000ff000) << 12);
+	}
+	DBG_IRT("iosapic_set_irt_data(): 0x%x 0x%x\n", *dp0, *dp1);
+}
+
+
+static void
+iosapic_disable_irq(void *irq_dev, int irq)
+{
+	ulong irqflags;
+	struct vector_info *vi = &(((struct vector_info *) irq_dev)[irq]);
+	u32 d0, d1;
+
+	ASSERT(NULL != vi);
+
+	IOSAPIC_LOCK(&iosapic_lock);
+
+#ifdef REVISIT_DESIGN_ISSUE
+/* 
+** XXX/FIXME
+
+disable_irq()/enable_irq(): drawback of using IRQ as a "handle"
+
+Current disable_irq interface only allows the irq_region support routines
+to manage sharing of "irq" objects.  The problem is the disable_irq()
+interface specifies which IRQ line needs to be disabled but does not
+identify the particular ISR which needs to be disabled.  IO sapic
+(and similar code in Dino) can only support one handler per IRQ
+since they don't further encode the meaning of the IRQ number.
+irq_region support has to hide it's implementation of "shared IRQ"
+behind a function call.
+
+Encoding the IRQ would be possible by I/O SAPIC but makes life really
+complicated for the IRQ handler and not help performance.
+
+Need more info on how Linux supports shared IRQ lines on a PC.
+*/
+#endif /* REVISIT_DESIGN_ISSUE */
+
+	iosapic_rd_irt_entry(vi, &d0, &d1);
+	d0 |= IOSAPIC_IRDT_ENABLE;
+	iosapic_wr_irt_entry(vi, d0, d1);
+
+	IOSAPIC_UNLOCK(&iosapic_lock);
+
+	/* disable ISR for parent */
+	disable_irq(vi->vi_txn_irq);
+}
+
+
+static void
+iosapic_enable_irq(void *dev, int irq)
+{
+	struct vector_info *vi = &(((struct vector_info *) dev)[irq]);
+	u32 d0, d1;
+
+	ASSERT(NULL != vi);
+	ASSERT(NULL != vi->vi_irte);
+
+	/* data is initialized by fixup_irq */
+	ASSERT(0 < vi->vi_txn_irq);
+	ASSERT(0UL != vi->vi_txn_data);
+
+	iosapic_set_irt_data(vi, &d0, &d1);
+	iosapic_wr_irt_entry(vi, d0, d1);
+
+
+#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");
+}
+
+printk("iosapic_enable_irq(): sel ");
+{
+	struct iosapic_info *isp = vi->vi_ios;
+
+	for (d0=0x10; d0<0x1e; d0++) {
+		/* point the window register to the lower word */
+		WRITE_U32(d0, isp->isi_hpa+IOSAPIC_REG_SELECT);
+
+		/* read the word */
+		d1 = READ_U32(isp->isi_hpa+IOSAPIC_REG_WINDOW);
+		printk(" %x", d1);
+	}
+}
+printk("\n");
+#endif
+
+	/*
+	** KLUGE: IRQ should not be asserted when Drivers enabling their IRQ.
+	**        PCI supports level triggered in order to share IRQ lines.
+	**
+	** Issueing I/O SAPIC an EOI causes an interrupt iff IRQ line is
+	** asserted.
+	*/
+	IOSAPIC_EOI(vi->vi_eoi_addr, vi->vi_eoi_data);
+}
+
+
+static void
+iosapic_mask_irq(void *dev, int irq)
+{
+	BUG();
+}
+
+
+static void
+iosapic_unmask_irq(void *dev, int irq)
+{
+	BUG();
+}
+
+
+static struct irq_region_ops iosapic_irq_ops = {
+	disable_irq:	iosapic_disable_irq,
+	enable_irq:	iosapic_enable_irq,
+	mask_irq:	iosapic_mask_irq,
+	unmask_irq:	iosapic_unmask_irq
+};
+
+
+/*
+** squirrel away the I/O Sapic Version
+*/
+static unsigned int
+iosapic_rd_version(struct iosapic_info *isi)
+{
+	ASSERT(isi);
+	ASSERT(isi->isi_hpa);
+
+	/* point window to the version register */
+	WRITE_U32(IOSAPIC_REG_VERSION, isi->isi_hpa+IOSAPIC_REG_SELECT);
+
+	/* now read the version register */
+	return (READ_U32(isi->isi_hpa+IOSAPIC_REG_WINDOW));
+}
+
+
+/*
+** iosapic_register() is called by "drivers" with an integrated I/O SAPIC.
+** 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
+**	o read size of IRdT.
+**	o allocate and initialize isi_vector[]
+**	o allocate isi_region (registers region handlers)
+*/
+void *
+iosapic_register(unsigned long hpa)
+{
+	struct iosapic_info *isi = NULL;
+	struct irt_entry *irte = irt_cell;
+	struct vector_info *vip;
+	int cnt;	/* track how many entries we've looked at */
+
+	/*
+	** Astro based platforms can't support PCI OLARD if they
+	** implement the legacy PDC (not PAT). Though Legacy PDC
+	** supports an IRT, LBA's with no device under them
+	** are *not* listed in the IRT.
+	** Search the IRT and ignore iosapic's which aren't
+	** in the IRT.
+	*/
+	ASSERT(NULL != irte);	/* always have built-in devices */
+	for (cnt=0; cnt < irt_num_entry; cnt++, irte++) {
+		ASSERT(IRT_IOSAPIC_TYPE == irte->entry_type);
+		/*
+		** We need sign extension of the hpa on 32-bit kernels.
+		** The address in the IRT is *always* 64 bit and really
+		** is an unsigned quantity (like all physical addresses).
+		*/ 
+		if (irte->dest_iosapic_addr == (s64) ((long) hpa))
+			break;
+	}
+
+	if (cnt  >= irt_num_entry)
+		return (NULL);
+
+	if ((isi = IOSAPIC_KALLOC(struct iosapic_info, 1)) == NULL) {
+		BUG();
+		return (NULL);
+	}
+
+	memset(isi, 0, sizeof(struct iosapic_info));
+
+	isi->isi_hpa         = hpa;
+	isi->isi_version     = iosapic_rd_version(isi);
+	isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1;
+
+	vip = isi->isi_vector =
+		 IOSAPIC_KALLOC(struct vector_info, isi->isi_num_vectors);
+
+	if (vip == NULL) {
+		IOSAPIC_FREE(isi, struct iosapic_info, 1);
+		return (NULL);
+	}
+
+	memset(vip, 0, sizeof(struct vector_info) * isi->isi_num_vectors);
+	sprintf(isi->isi_name, "IO-SAPIC%02d", iosapic_count++);
+
+	/*
+	** Initialize vector array
+	*/
+	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, isi->isi_name,
+				(void *) isi->isi_vector);
+
+	ASSERT(NULL != isi->isi_region);
+	return ((void *) isi);
+}
+
+
+#ifdef DEBUG_IOSAPIC
+
+static void
+iosapic_prt_irt(void *irt, long num_entry)
+{
+	unsigned int i, *irp = (unsigned int *) irt;
+
+	ASSERT(NULL != irt);
+
+	printk(KERN_DEBUG MODULE_NAME ": Interrupt Routing Table (%lx entries)\n", num_entry);
+
+	for (i=0; i<num_entry; i++, irp += 4) {
+		printk(KERN_DEBUG "%p : %2d %.8x %.8x %.8x %.8x\n",
+					irp, i, irp[0], irp[1], irp[2], irp[3]);
+	}
+}
+
+
+static void
+iosapic_prt_vi(struct vector_info *vi)
+{
+	ASSERT(NULL != vi);
+
+	printk(KERN_DEBUG MODULE_NAME ": vector_info[%d] is at %p\n", vi->vi_irqline, vi);
+	printk(KERN_DEBUG "\t\tvi_status:	 %.4x\n", vi->vi_status);
+	printk(KERN_DEBUG "\t\tvi_txn_irq:  %d\n",  vi->vi_txn_irq);
+	printk(KERN_DEBUG "\t\tvi_txn_addr: %lx\n", vi->vi_txn_addr);
+	printk(KERN_DEBUG "\t\tvi_txn_data: %lx\n", vi->vi_txn_data);
+	printk(KERN_DEBUG "\t\tvi_eoi_addr: %p\n",  vi->vi_eoi_addr);
+	printk(KERN_DEBUG "\t\tvi_eoi_data: %x\n",  vi->vi_eoi_data);
+}
+
+
+static void
+iosapic_prt_isi(struct iosapic_info *isi)
+{
+	ASSERT(NULL != isi);
+	printk(KERN_DEBUG MODULE_NAME ": io_sapic_info at %p\n", isi);
+	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);
+}
+#endif /* DEBUG_IOSAPIC */
diff -Nru a/drivers/parisc/iosapic_private.h b/drivers/parisc/iosapic_private.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/parisc/iosapic_private.h	Mon Nov  4 14:31:01 2002
@@ -0,0 +1,168 @@
+/*
+** This file is private to iosapic driver.
+** If stuff needs to be used by another driver, move it to a common file.
+**
+** WARNING: fields most data structures here are ordered to make sure
+**          they pack nicely for 64-bit compilation. (ie sizeof(long) == 8)
+*/
+
+
+/*
+** Interrupt Routing Stuff
+** -----------------------
+** The interrupt routing table consists of entries derived from
+** MP Specification Draft 1.5. There is one interrupt routing 
+** table per cell.  N- and L-class consist of a single cell.
+*/
+struct irt_entry {
+
+	/* Entry Type 139 identifies an I/O SAPIC interrupt entry */
+	u8 entry_type;
+
+	/* Entry Length 16 indicates entry is 16 bytes long */
+	u8 entry_length;
+
+	/* 
+	** Interrupt Type of 0 indicates a vectored interrupt, 
+	** all other values are reserved 
+	*/
+	u8 interrupt_type;
+
+	/* 
+	** PO and EL
+	** Polarity of SAPIC I/O input signals: 
+	**    00 = Reserved 
+	**    01 = Active high 
+	**    10 = Reserved 
+	**    11 = Active low 
+	** Trigger mode of SAPIC I/O input signals: 
+	**    00 = Reserved 
+	**    01 = Edge-triggered 
+	**    10 = Reserved 
+	**    11 = Level-triggered
+	*/
+	u8 polarity_trigger;
+
+	/* 
+	** IRQ and DEVNO
+	** irq identifies PCI interrupt signal where
+	**    0x0 corresponds to INT_A#, 
+	**    0x1 corresponds to INT_B#, 
+	**    0x2 corresponds to INT_C# 
+	**    0x3 corresponds to INT_D# 
+	** PCI device number where interrupt originates 
+	*/
+	u8 src_bus_irq_devno;
+
+	/* Source Bus ID identifies the bus where interrupt signal comes from */
+	u8 src_bus_id;
+
+	/* 
+	** Segment ID is unique across a protection domain and
+	** identifies a segment of PCI buses (reserved in 
+	** MP Specification Draft 1.5) 
+	*/
+	u8 src_seg_id;
+
+	/* 
+	** Destination I/O SAPIC INTIN# identifies the INTIN n pin 
+	** to which the signal is connected 
+	*/
+	u8 dest_iosapic_intin;
+
+	/* 
+	** Destination I/O SAPIC Address identifies the I/O SAPIC 
+	** to which the signal is connected 
+	*/
+	u64 dest_iosapic_addr;
+};
+
+#define IRT_IOSAPIC_TYPE   139
+#define IRT_IOSAPIC_LENGTH 16
+
+#define IRT_VECTORED_INTR  0
+
+#define IRT_PO_MASK        0x3
+#define IRT_ACTIVE_HI      1
+#define IRT_ACTIVE_LO      3
+
+#define IRT_EL_MASK        0x3
+#define IRT_EL_SHIFT       2
+#define IRT_EDGE_TRIG      1
+#define IRT_LEVEL_TRIG     3
+
+#define IRT_IRQ_MASK       0x3
+#define IRT_DEV_MASK       0x1f
+#define IRT_DEV_SHIFT      2
+
+#define IRT_IRQ_DEVNO_MASK	((IRT_DEV_MASK << IRT_DEV_SHIFT) | IRT_IRQ_MASK)
+
+#ifdef SUPPORT_MULTI_CELL
+struct iosapic_irt {
+        struct iosapic_irt *irt_next;  /* next routing table */
+        struct irt_entry *irt_base;             /* intr routing table address */
+        size_t  irte_count;            /* number of entries in the table */
+        size_t  irte_size;             /* size (bytes) of each entry */
+};
+#endif
+
+struct vector_info {
+	struct iosapic_info *vi_ios;    /* I/O SAPIC this vector is on */
+	struct irt_entry *vi_irte;      /* IRT entry */
+	u32	*vi_eoi_addr;	/* precalculate EOI reg address */
+	u32	vi_eoi_data;	/* IA64: ?       PA: swapped txn_data */
+	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          */
+	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 */
+};
+
+
+
+#ifdef __IA64__
+/*
+** PA risc does NOT have any local sapics. IA64 does.
+** PIB (Processor Interrupt Block) is handled by Astro or Dew (Stretch CEC).
+**
+** PA: Get id_eid from IRT and hardcode PIB to 0xfeeNNNN0
+**     Emulate the data on PAT platforms.
+*/
+struct local_sapic_info {
+	struct local_sapic_info *lsi_next;      /* point to next CPU info */
+	int                     *lsi_cpu_id;    /* point to logical CPU id */
+	unsigned long           *lsi_id_eid;    /* point to IA-64 CPU id */
+	int                     *lsi_status;    /* point to CPU status   */
+	void                    *lsi_private;   /* point to special info */
+};
+
+/*
+** "root" data structure which ties everything together.
+** Should always be able to start with sapic_root and locate
+** the desired information.
+*/
+struct sapic_info {
+	struct sapic_info	*si_next;	/* info is per cell */
+	int                     si_cellid;      /* cell id */
+	unsigned int            si_status;       /* status  */
+	char                    *si_pib_base;   /* intr blk base address */
+	local_sapic_info_t      *si_local_info;
+	io_sapic_info_t         *si_io_info;
+	extint_info_t           *si_extint_info;/* External Intr info      */
+};
+#endif
+
diff -Nru a/drivers/parisc/lasi.c b/drivers/parisc/lasi.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/parisc/lasi.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,245 @@
+/*
+ *	LASI Device Driver
+ *
+ *	(c) Copyright 1999 Red Hat Software
+ *	Portions (c) Copyright 1999 The Puffin Group Inc.
+ *	Portions (c) Copyright 1999 Hewlett-Packard
+ *
+ *	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.
+ *
+ *	by Alan Cox <alan@redhat.com> and 
+ * 	   Alex deVries <adevries@thepuffingroup.com> 
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/pm.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/led.h>
+
+#include "gsc.h"
+
+
+#define LASI_VER	0xC008	/* LASI Version */
+
+#define LASI_IO_CONF	0x7FFFE	/* LASI primary configuration register */
+#define LASI_IO_CONF2	0x7FFFF	/* LASI secondary configuration register */
+
+static int lasi_choose_irq(struct parisc_device *dev)
+{
+	int irq;
+
+	/*
+	** "irq" bits below are numbered relative to most significant bit.
+	*/
+	switch (dev->id.sversion) {
+		case 0x74:	irq = 24; break; /* Centronics */
+		case 0x7B:	irq = 18; break; /* Audio */
+		case 0x81:	irq = 17; break; /* Lasi itself */
+		case 0x82:	irq = 22; break; /* SCSI */
+		case 0x83:	irq = 11; break; /* Floppy */
+		case 0x84:	irq =  5; break; /* PS/2 Keyboard */
+		case 0x87:	irq = 13; break; /* ISDN */
+		case 0x8A:	irq = 23; break; /* LAN */
+		case 0x8C:	irq = 26; break; /* RS232 */
+		case 0x8D:	irq = (dev->hw_path == 13) ? 15 : 14;
+						break; /* Telephone */
+		default: 	irq = -1; break; /* unknown */
+	}
+
+	return irq;
+}
+
+static void __init
+lasi_init_irq(struct busdevice *this_lasi)
+{
+	unsigned long lasi_base = this_lasi->hpa;
+
+	/* Stop LASI barking for a bit */
+	gsc_writel(0x00000000, lasi_base+OFFSET_IMR);
+
+	/* clear pending interrupts */
+	gsc_readl(lasi_base+OFFSET_IRR);
+
+	/* We're not really convinced we want to reset the onboard
+         * devices. Firmware does it for us...
+	 */
+
+	/* Resets */
+	/* gsc_writel(0xFFFFFFFF, lasi_base+0x2000);*/	/* Parallel */
+	gsc_writel(0xFFFFFFFF, lasi_base+0x4004);	/* Audio */
+	/* gsc_writel(0xFFFFFFFF, lasi_base+0x5000);*/	/* Serial */ 
+	/* gsc_writel(0xFFFFFFFF, lasi_base+0x6000);*/	/* SCSI */
+	gsc_writel(0xFFFFFFFF, lasi_base+0x7000);	/* LAN */
+	gsc_writel(0xFFFFFFFF, lasi_base+0x8000);	/* Keyboard */
+	gsc_writel(0xFFFFFFFF, lasi_base+0xA000);	/* FDC */
+	
+	/* Ok we hit it on the head with a hammer, our Dog is now
+	** comatose and muzzled.  Devices will now unmask LASI
+	** interrupts as they are registered as irq's in the LASI range.
+	*/
+	/* XXX: I thought it was `awks that got `it on the `ead with an
+	 * `ammer.  -- willy
+	 */
+}
+
+
+/*
+   ** lasi_led_init()
+   ** 
+   ** lasi_led_init() initializes the LED controller on the LASI.
+   **
+   ** Since Mirage and Electra machines use a different LED
+   ** address register, we need to check for these machines 
+   ** explicitly.
+ */
+
+#ifndef CONFIG_CHASSIS_LCD_LED
+
+#define lasi_led_init(x)	/* nothing */
+
+#else
+
+void __init lasi_led_init(unsigned long lasi_hpa)
+{
+	unsigned long datareg;
+
+	switch (CPU_HVERSION) {
+	/* Gecko machines have only one single LED, which can be permanently 
+	   turned on by writing a zero into the power control register. */ 
+	case 0x600:		/* Gecko (712/60) */
+	case 0x601:		/* Gecko (712/80) */
+	case 0x602:		/* Gecko (712/100) */
+	case 0x603:		/* Anole 64 (743/64) */
+	case 0x604:		/* Anole 100 (743/100) */
+	case 0x605:		/* Gecko (712/120) */
+		datareg = lasi_hpa + 0x0000C000;
+		gsc_writeb(0, datareg);
+		return; /* no need to register the LED interrupt-function */  
+
+	/* Mirage and Electra machines need special offsets */
+	case 0x60A:		/* Mirage Jr (715/64) */
+	case 0x60B:		/* Mirage 100 */
+	case 0x60C:		/* Mirage 100+ */
+	case 0x60D:		/* Electra 100 */
+	case 0x60E:		/* Electra 120 */
+		datareg = lasi_hpa - 0x00020000;
+		break;
+
+	default:
+		datareg = lasi_hpa + 0x0000C000;
+		break;
+	} /* switch() */
+
+	register_led_driver(DISPLAY_MODEL_LASI, LED_CMD_REG_NONE, (char *)datareg);
+}
+#endif
+
+/*
+ * lasi_power_off
+ *
+ * Function for lasi to turn off the power.  This is accomplished by setting a
+ * 1 to PWR_ON_L in the Power Control Register
+ * 
+ */
+
+static unsigned long lasi_power_off_hpa;
+
+static void lasi_power_off(void)
+{
+	unsigned long datareg;
+
+	/* calculate addr of the Power Control Register */
+	datareg = lasi_power_off_hpa + 0x0000C000;
+
+	/* Power down the machine */
+	gsc_writel(0x02, datareg);
+}
+
+int __init
+lasi_init_chip(struct parisc_device *dev)
+{
+	struct busdevice *lasi;
+	struct gsc_irq gsc_irq;
+	int irq, ret;
+
+	lasi = kmalloc(sizeof(struct busdevice), GFP_KERNEL);
+	if (!lasi)
+		return -ENOMEM;
+
+	lasi->name = "Lasi";
+	lasi->hpa = dev->hpa;
+
+	/* Check the 4-bit (yes, only 4) version register */
+	lasi->version = gsc_readl(lasi->hpa + LASI_VER) & 0xf;
+	printk(KERN_INFO "%s version %d at 0x%lx found.\n",
+		lasi->name, lasi->version, lasi->hpa);
+
+	/* initialize the chassis LEDs really early */ 
+	lasi_led_init(lasi->hpa);
+
+	/* Stop LASI barking for a bit */
+	lasi_init_irq(lasi);
+
+	/* the IRQ lasi should use */
+	irq = gsc_alloc_irq(&gsc_irq);
+	if (irq < 0) {
+		printk(KERN_ERR "%s(): cannot get GSC irq\n",
+				__FUNCTION__);
+		kfree(lasi);
+		return -EBUSY;
+	}
+
+	ret = request_irq(gsc_irq.irq, busdev_barked, 0, "lasi", lasi);
+	if (ret < 0) {
+		kfree(lasi);
+		return ret;
+	}
+
+	/* Save this for debugging later */
+	lasi->parent_irq = gsc_irq.irq;
+	lasi->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data;
+
+	/* enable IRQ's for devices below LASI */
+	gsc_writel(lasi->eim, lasi->hpa + OFFSET_IAR);
+
+	/* Done init'ing, register this driver */
+	ret = gsc_common_irqsetup(dev, lasi);
+	if (ret) {
+		kfree(lasi);
+		return ret;
+	}    
+
+	fixup_child_irqs(dev, lasi->busdev_region->data.irqbase,
+			lasi_choose_irq);
+
+	/* initialize the power off function */
+	/* FIXME: Record the LASI HPA for the power off function.  This should
+	 * ensure that only the first LASI (the one controlling the power off)
+	 * should set the HPA here */
+	lasi_power_off_hpa = lasi->hpa;
+	pm_power_off = lasi_power_off;
+	
+	return ret;
+}
+
+static struct parisc_device_id lasi_tbl[] = {
+	{ HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00081 },
+	{ 0, }
+};
+
+struct parisc_driver lasi_driver = {
+	name:		"Lasi",
+	id_table:	lasi_tbl,
+	probe:		lasi_init_chip,
+};
diff -Nru a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/parisc/lba_pci.c	Mon Nov  4 14:31:02 2002
@@ -0,0 +1,1498 @@
+/*
+**  PCI Lower Bus Adapter (LBA) manager
+**
+**	(c) Copyright 1999,2000 Grant Grundler
+**	(c) Copyright 1999,2000 Hewlett-Packard Company
+**
+**	This program is free software; you can redistribute it and/or modify
+**	it under the terms of the GNU General Public License as published by
+**      the Free Software Foundation; either version 2 of the License, or
+**      (at your option) any later version.
+**
+**
+** This module primarily provides access to PCI bus (config/IOport
+** spaces) on platforms with an SBA/LBA chipset. A/B/C/J/L/N-class
+** with 4 digit model numbers - eg C3000 (and A400...sigh).
+**
+** LBA driver isn't as simple as the Dino driver because:
+**   (a) this chip has substantial bug fixes between revisions
+**       (Only one Dino bug has a software workaround :^(  )
+**   (b) has more options which we don't (yet) support (DMA hints, OLARD)
+**   (c) IRQ support lives in the I/O SAPIC driver (not with PCI driver)
+**   (d) play nicely with both PAT and "Legacy" PA-RISC firmware (PDC).
+**       (dino only deals with "Legacy" PDC)
+**
+** LBA driver passes the I/O SAPIC HPA to the I/O SAPIC driver.
+** (I/O SAPIC is integratd in the LBA chip).
+**
+** FIXME: Add support to SBA and LBA drivers for DMA hint sets
+** FIXME: Add support for PCI card hot-plug (OLARD).
+*/
+
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>		/* for __init and __devinit */
+/* #define PCI_DEBUG	enable ASSERT */
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+
+#include <asm/byteorder.h>
+#include <asm/irq.h>		/* for struct irq_region support */
+#include <asm/pdc.h>
+#include <asm/page.h>
+#include <asm/segment.h>
+#include <asm/system.h>
+
+#include <asm/hardware.h>	/* for register_parisc_driver() stuff */
+#include <asm/iosapic.h>	/* for iosapic_register() */
+#include <asm/io.h>		/* read/write stuff */
+
+#ifndef TRUE
+#define TRUE (1 == 1)
+#define FALSE (1 == 0)
+#endif
+
+#undef DEBUG_LBA	/* general stuff */
+#undef DEBUG_LBA_PORT	/* debug I/O Port access */
+#undef DEBUG_LBA_CFG	/* debug Config Space Access (ie PCI Bus walk) */
+#undef DEBUG_LBA_PAT	/* debug PCI Resource Mgt code - PDC PAT only */
+
+#undef FBB_SUPPORT	/* Fast Back-Back xfers - NOT READY YET */
+
+
+#ifdef DEBUG_LBA
+#define DBG(x...)	printk(x)
+#else
+#define DBG(x...)
+#endif
+
+#ifdef DEBUG_LBA_PORT
+#define DBG_PORT(x...)	printk(x)
+#else
+#define DBG_PORT(x...)
+#endif
+
+#ifdef DEBUG_LBA_CFG
+#define DBG_CFG(x...)	printk(x)
+#else
+#define DBG_CFG(x...)
+#endif
+
+#ifdef DEBUG_LBA_PAT
+#define DBG_PAT(x...)	printk(x)
+#else
+#define DBG_PAT(x...)
+#endif
+
+/*
+** Config accessor functions only pass in the 8-bit bus number and not
+** the 8-bit "PCI Segment" number. Each LBA will be assigned a PCI bus
+** number based on what firmware wrote into the scratch register.
+**
+** The "secondary" bus number is set to this before calling
+** pci_register_ops(). If any PPB's are present, the scan will
+** discover them and update the "secondary" and "subordinate"
+** fields in the pci_bus structure.
+**
+** Changes in the configuration *may* result in a different
+** bus number for each LBA depending on what firmware does.
+*/
+
+#define MODULE_NAME "lba"
+
+#define LBA_FUNC_ID	0x0000	/* function id */
+#define LBA_FCLASS	0x0008	/* function class, bist, header, rev... */
+#define LBA_CAPABLE	0x0030	/* capabilities register */
+
+#define LBA_PCI_CFG_ADDR	0x0040	/* poke CFG address here */
+#define LBA_PCI_CFG_DATA	0x0048	/* read or write data here */
+
+#define LBA_PMC_MTLT	0x0050	/* Firmware sets this - read only. */
+#define LBA_FW_SCRATCH	0x0058	/* Firmware writes the PCI bus number here. */
+#define LBA_ERROR_ADDR	0x0070	/* On error, address gets logged here */
+
+#define LBA_ARB_MASK	0x0080	/* bit 0 enable arbitration. PAT/PDC enables */
+#define LBA_ARB_PRI	0x0088	/* firmware sets this. */
+#define LBA_ARB_MODE	0x0090	/* firmware sets this. */
+#define LBA_ARB_MTLT	0x0098	/* firmware sets this. */
+
+#define LBA_MOD_ID	0x0100	/* Module ID. PDC_PAT_CELL reports 4 */
+
+#define LBA_STAT_CTL	0x0108	/* Status & Control */
+#define   LBA_BUS_RESET		0x01	/*  Deassert PCI Bus Reset Signal */
+#define   CLEAR_ERRLOG		0x10	/*  "Clear Error Log" cmd */
+#define   CLEAR_ERRLOG_ENABLE	0x20	/*  "Clear Error Log" Enable */
+#define   HF_ENABLE	0x40	/*    enable HF mode (default is -1 mode) */
+
+#define LBA_LMMIO_BASE	0x0200	/* < 4GB I/O address range */
+#define LBA_LMMIO_MASK	0x0208
+
+#define LBA_GMMIO_BASE	0x0210	/* > 4GB I/O address range */
+#define LBA_GMMIO_MASK	0x0218
+
+#define LBA_WLMMIO_BASE	0x0220	/* All < 4GB ranges under the same *SBA* */
+#define LBA_WLMMIO_MASK	0x0228
+
+#define LBA_WGMMIO_BASE	0x0230	/* All > 4GB ranges under the same *SBA* */
+#define LBA_WGMMIO_MASK	0x0238
+
+#define LBA_IOS_BASE	0x0240	/* I/O port space for this LBA */
+#define LBA_IOS_MASK	0x0248
+
+#define LBA_ELMMIO_BASE	0x0250	/* Extra LMMIO range */
+#define LBA_ELMMIO_MASK	0x0258
+
+#define LBA_EIOS_BASE	0x0260	/* Extra I/O port space */
+#define LBA_EIOS_MASK	0x0268
+
+#define LBA_DMA_CTL	0x0278	/* firmware sets this */
+
+#define LBA_IBASE	0x0300	/* SBA DMA support */
+#define LBA_IMASK	0x0308
+
+/* FIXME: ignore DMA Hint stuff until we can measure performance */
+#define LBA_HINT_CFG	0x0310
+#define LBA_HINT_BASE	0x0380	/* 14 registers at every 8 bytes. */
+
+/* ERROR regs are needed for config cycle kluges */
+#define LBA_ERROR_CONFIG 0x0680
+#define     LBA_SMART_MODE 0x20
+#define LBA_ERROR_STATUS 0x0688
+#define LBA_ROPE_CTL     0x06A0
+
+#define LBA_IOSAPIC_BASE	0x800 /* Offset of IRQ logic */
+
+/* non-postable I/O port space, densely packed */
+#ifdef __LP64__
+#define LBA_ASTRO_PORT_BASE	(0xfffffffffee00000UL)
+#else
+#define LBA_ASTRO_PORT_BASE	(0xfee00000UL)
+#endif
+
+
+/*
+** lba_device: Per instance Elroy data structure
+*/
+struct lba_device {
+	struct pci_hba_data hba;
+
+	spinlock_t	lba_lock;
+	void		*iosapic_obj;
+
+#ifdef __LP64__
+	unsigned long	lmmio_base;  /* PA_VIEW - fixup MEM addresses */
+	unsigned long	gmmio_base;  /* PA_VIEW - Not used (yet) */
+	unsigned long	iop_base;    /* PA_VIEW - for IO port accessor funcs */
+#endif
+
+	int		flags;       /* state/functionality enabled */
+	int		hw_rev;      /* HW revision of chip */
+};
+
+
+static u32 lba_t32;
+
+/*
+** lba "flags"
+*/
+#define LBA_FLAG_NO_DMA_DURING_CFG	0x01
+#define LBA_FLAG_SKIP_PROBE	0x10
+
+/* Tape Release 4 == hw_rev 5 */
+#define LBA_TR4PLUS(d)      ((d)->hw_rev > 0x4)
+#define LBA_DMA_DURING_CFG_DISABLED(d) ((d)->flags & LBA_FLAG_NO_DMA_DURING_CFG)
+#define LBA_SKIP_PROBE(d) ((d)->flags & LBA_FLAG_SKIP_PROBE)
+
+
+/* Looks nice and keeps the compiler happy */
+#define LBA_DEV(d) ((struct lba_device *) (d))
+
+
+/*
+** Only allow 8 subsidiary busses per LBA
+** Problem is the PCI bus numbering is globally shared.
+*/
+#define LBA_MAX_NUM_BUSES 8
+
+/************************************
+ * LBA register read and write support
+ *
+ * BE WARNED: register writes are posted.
+ *  (ie follow writes which must reach HW with a read)
+ */
+#define READ_U8(addr)  __raw_readb(addr)
+#define READ_U16(addr) __raw_readw(addr)
+#define READ_U32(addr) __raw_readl(addr)
+#define WRITE_U8(value, addr)  __raw_writeb(value, addr)
+#define WRITE_U16(value, addr) __raw_writew(value, addr)
+#define WRITE_U32(value, addr) __raw_writel(value, addr)
+
+#define READ_REG8(addr)  readb(addr)
+#define READ_REG16(addr) readw(addr)
+#define READ_REG32(addr) readl(addr)
+#define READ_REG64(addr) readq(addr)
+#define WRITE_REG8(value, addr)  writeb(value, addr)
+#define WRITE_REG16(value, addr) writew(value, addr)
+#define WRITE_REG32(value, addr) writel(value, addr)
+
+
+#define LBA_CFG_TOK(bus,dfn) ((u32) ((bus)<<16 | (dfn)<<8))
+#define LBA_CFG_BUS(tok)  ((u8) ((tok)>>16))
+#define LBA_CFG_DEV(tok)  ((u8) ((tok)>>11) & 0x1f)
+#define LBA_CFG_FUNC(tok) ((u8) ((tok)>>8 ) & 0x7)
+
+
+/*
+** Extract LBA (Rope) number from HPA
+** REVISIT: 16 ropes for Stretch/Ike?
+*/
+#define ROPES_PER_SBA	8
+#define LBA_NUM(x)    ((((unsigned long) x) >> 13) & (ROPES_PER_SBA-1))
+
+
+static void
+lba_dump_res(struct resource *r, int d)
+{
+	int i;
+
+	if (NULL == r)
+		return;
+
+	printk(KERN_DEBUG "(%p)", r->parent);
+	for (i = d; i ; --i) printk(" ");
+	printk(KERN_DEBUG "%p [%lx,%lx]/%x\n", r, r->start, r->end, (int) r->flags);
+	lba_dump_res(r->child, d+2);
+	lba_dump_res(r->sibling, d);
+}
+
+
+/*
+** LBA rev 2.0, 2.1, 2.2, and 3.0 bus walks require a complex
+** workaround for cfg cycles:
+**	-- preserve  LBA state
+**	-- LBA_FLAG_NO_DMA_DURING_CFG workaround
+**	-- turn on smart mode
+**	-- probe with config writes before doing config reads
+**	-- check ERROR_STATUS
+**	-- clear ERROR_STATUS
+**	-- restore LBA state
+**
+** The workaround is only used for device discovery.
+*/
+
+static int
+lba_device_present( u8 bus, u8 dfn, struct lba_device *d)
+{
+	u8 first_bus = d->hba.hba_bus->secondary;
+	u8 last_sub_bus = d->hba.hba_bus->subordinate;
+#if 0
+/* FIXME - see below in this function */
+        u8 dev = PCI_SLOT(dfn);
+        u8 func = PCI_FUNC(dfn);
+#endif
+
+	ASSERT(bus >= first_bus);
+	ASSERT(bus <= last_sub_bus);
+	ASSERT((bus - first_bus) < LBA_MAX_NUM_BUSES);
+
+	if ((bus < first_bus) ||
+	    (bus > last_sub_bus) ||
+	    ((bus - first_bus) >= LBA_MAX_NUM_BUSES))
+	{
+	    /* devices that fall into any of these cases won't get claimed */
+	    return(FALSE);
+	}
+
+#if 0
+/*
+** FIXME: Need to implement code to fill the devices bitmap based
+** on contents of the local pci_bus tree "data base".
+** pci_register_ops() walks the bus for us and builds the tree.
+** For now, always do the config cycle.
+*/
+	bus -= first_bus;
+
+	return (((d->devices[bus][dev]) >> func) & 0x1);
+#else
+	return TRUE;
+#endif
+}
+
+
+
+#define LBA_CFG_SETUP(d, tok) {				\
+    /* Save contents of error config register.  */			\
+    error_config = READ_REG32(d->hba.base_addr + LBA_ERROR_CONFIG);		\
+\
+    /* Save contents of status control register.  */			\
+    status_control = READ_REG32(d->hba.base_addr + LBA_STAT_CTL);		\
+\
+    /* For LBA rev 2.0, 2.1, 2.2, and 3.0, we must disable DMA		\
+    ** arbitration for full bus walks.					\
+    */									\
+    if (LBA_DMA_DURING_CFG_DISABLED(d)) {				\
+	/* Save contents of arb mask register. */			\
+	arb_mask = READ_REG32(d->hba.base_addr + LBA_ARB_MASK);		\
+\
+	/*								\
+	 * Turn off all device arbitration bits (i.e. everything	\
+	 * except arbitration enable bit).				\
+	 */								\
+	WRITE_REG32(0x1, d->hba.base_addr + LBA_ARB_MASK);			\
+    }									\
+\
+    /*									\
+     * Set the smart mode bit so that master aborts don't cause		\
+     * LBA to go into PCI fatal mode (required).			\
+     */									\
+    WRITE_REG32(error_config | LBA_SMART_MODE, d->hba.base_addr + LBA_ERROR_CONFIG);	\
+}
+
+
+#define LBA_CFG_PROBE(d, tok) {				\
+    /*									\
+     * Setup Vendor ID write and read back the address register		\
+     * to make sure that LBA is the bus master.				\
+     */									\
+    WRITE_REG32(tok | PCI_VENDOR_ID, (d)->hba.base_addr + LBA_PCI_CFG_ADDR);\
+    /*									\
+     * Read address register to ensure that LBA is the bus master,	\
+     * which implies that DMA traffic has stopped when DMA arb is off.	\
+     */									\
+    lba_t32 = READ_REG32((d)->hba.base_addr + LBA_PCI_CFG_ADDR);		\
+    /*									\
+     * Generate a cfg write cycle (will have no affect on		\
+     * Vendor ID register since read-only).				\
+     */									\
+    WRITE_REG32(~0, (d)->hba.base_addr + LBA_PCI_CFG_DATA);		\
+    /*									\
+     * Make sure write has completed before proceeding further,		\
+     * i.e. before setting clear enable.				\
+     */									\
+    lba_t32 = READ_REG32((d)->hba.base_addr + LBA_PCI_CFG_ADDR);		\
+}
+
+
+/*
+ * HPREVISIT:
+ *   -- Can't tell if config cycle got the error.
+ *
+ *		OV bit is broken until rev 4.0, so can't use OV bit and
+ *		LBA_ERROR_LOG_ADDR to tell if error belongs to config cycle.
+ *
+ *		As of rev 4.0, no longer need the error check.
+ *
+ *   -- Even if we could tell, we still want to return -1
+ *	for **ANY** error (not just master abort).
+ *
+ *   -- Only clear non-fatal errors (we don't want to bring
+ *	LBA out of pci-fatal mode).
+ *
+ *		Actually, there is still a race in which
+ *		we could be clearing a fatal error.  We will
+ *		live with this during our initial bus walk
+ *		until rev 4.0 (no driver activity during
+ *		initial bus walk).  The initial bus walk
+ *		has race conditions concerning the use of
+ *		smart mode as well.
+ */
+
+#define LBA_MASTER_ABORT_ERROR 0xc
+#define LBA_FATAL_ERROR 0x10
+
+#define LBA_CFG_MASTER_ABORT_CHECK(d, base, tok, error) {		\
+    u32 error_status = 0;						\
+    /*									\
+     * Set clear enable (CE) bit. Unset by HW when new			\
+     * errors are logged -- LBA HW ERS section 14.3.3).		\
+     */									\
+    WRITE_REG32(status_control | CLEAR_ERRLOG_ENABLE, base + LBA_STAT_CTL); \
+    error_status = READ_REG32(base + LBA_ERROR_STATUS);		\
+    if ((error_status & 0x1f) != 0) {					\
+	/*								\
+	 * Fail the config read request.				\
+	 */								\
+	error = 1;							\
+	if ((error_status & LBA_FATAL_ERROR) == 0) {			\
+	    /*								\
+	     * Clear error status (if fatal bit not set) by setting	\
+	     * clear error log bit (CL).				\
+	     */								\
+	    WRITE_REG32(status_control | CLEAR_ERRLOG, base + LBA_STAT_CTL); \
+	}								\
+    }									\
+}
+
+#define LBA_CFG_TR4_ADDR_SETUP(d, addr) \
+    WRITE_REG32(((addr) & ~3), (d)->hba.base_addr + LBA_PCI_CFG_ADDR)
+
+#define LBA_CFG_ADDR_SETUP(d, addr) {				\
+    WRITE_REG32(((addr) & ~3), (d)->hba.base_addr + LBA_PCI_CFG_ADDR);	\
+    /*									\
+     * HPREVISIT:							\
+     *       --	Potentially could skip this once DMA bug fixed.		\
+     *									\
+     * Read address register to ensure that LBA is the bus master,	\
+     * which implies that DMA traffic has stopped when DMA arb is off.	\
+     */									\
+    lba_t32 = READ_REG32((d)->hba.base_addr + LBA_PCI_CFG_ADDR);		\
+}
+
+
+#define LBA_CFG_RESTORE(d, base) {					\
+    /*									\
+     * Restore status control register (turn off clear enable).		\
+     */									\
+    WRITE_REG32(status_control, base + LBA_STAT_CTL);			\
+    /*									\
+     * Restore error config register (turn off smart mode).		\
+     */									\
+    WRITE_REG32(error_config, base + LBA_ERROR_CONFIG);			\
+    if (LBA_DMA_DURING_CFG_DISABLED(d)) {				\
+	/*								\
+	 * Restore arb mask register (reenables DMA arbitration).	\
+	 */								\
+	WRITE_REG32(arb_mask, base + LBA_ARB_MASK);			\
+    }									\
+}
+
+
+
+static unsigned int
+lba_rd_cfg(struct lba_device *d, u32 tok, u8 reg, u32 size)
+{
+	u32 data = ~0;
+	int error = 0;
+	u32 arb_mask = 0;	/* used by LBA_CFG_SETUP/RESTORE */
+	u32 error_config = 0;	/* used by LBA_CFG_SETUP/RESTORE */
+	u32 status_control = 0;	/* used by LBA_CFG_SETUP/RESTORE */
+
+	ASSERT((size == sizeof(u8)) ||
+		(size == sizeof(u16)) ||
+		(size == sizeof(u32)));
+
+	if ((size != sizeof(u8)) &&
+		(size != sizeof(u16)) &&
+		(size != sizeof(u32))) {
+		return(data);
+	}
+
+	LBA_CFG_SETUP(d, tok);
+	LBA_CFG_PROBE(d, tok);
+	LBA_CFG_MASTER_ABORT_CHECK(d, d->hba.base_addr, tok, error);
+	if (!error) {
+		LBA_CFG_ADDR_SETUP(d, tok | reg);
+		switch (size) {
+		case sizeof(u8):
+			data = (u32) READ_REG8(d->hba.base_addr + LBA_PCI_CFG_DATA + (reg & 3));
+			break;
+		case sizeof(u16):
+			data = (u32) READ_REG16(d->hba.base_addr + LBA_PCI_CFG_DATA + (reg & 2));
+			break;
+		case sizeof(u32):
+			data = READ_REG32(d->hba.base_addr + LBA_PCI_CFG_DATA);
+			break;
+		default:
+			break; /* leave data as -1 */
+		}
+	}
+	LBA_CFG_RESTORE(d, d->hba.base_addr);
+	return(data);
+}
+
+
+static int lba_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 *data)
+{
+	struct lba_device *d = LBA_DEV(bus->sysdata);
+	u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
+	u32 tok = LBA_CFG_TOK(local_bus, devfn);
+
+/* FIXME: B2K/C3600 workaround is always use old method... */
+	/* if (!LBA_TR4PLUS(d) && !LBA_SKIP_PROBE(d)) */ {
+		/* original - Generate config cycle on broken elroy
+		  with risk we will miss PCI bus errors. */
+		*data = lba_rd_cfg(d, tok, pos, size);
+		DBG_CFG("%s(%x+%2x) -> 0x%x (a)\n", __FUNCTION__, tok, pos, *data);
+		return(*data == ~0UL);
+	}
+
+	if (LBA_SKIP_PROBE(d) && (!lba_device_present(bus->secondary, devfn, d)))
+	{
+		DBG_CFG("%s(%x+%2x) -> -1 (b)\n", __FUNCTION__, tok, pos);
+		/* either don't want to look or know device isn't present. */
+		*data = ~0U;
+		return(0);
+	}
+
+	/* Basic Algorithm
+	** Should only get here on fully working LBA rev.
+	** This is how simple the code should have been.
+	*/
+	LBA_CFG_TR4_ADDR_SETUP(d, tok | pos);
+	switch(size) {
+	case 1: *(u8 *)  data = READ_REG8(d->hba.base_addr + LBA_PCI_CFG_DATA);
+	   break;
+	case 2: *(u16 *) data = READ_REG16(d->hba.base_addr + LBA_PCI_CFG_DATA);
+	   break;
+	case 4: *(u32 *) data = READ_REG32(d->hba.base_addr + LBA_PCI_CFG_DATA);
+	   break;
+	}
+	DBG_CFG("%s(%x+%2x) -> 0x%x (c)\n", __FUNCTION__, tok, pos, *data);
+	return(*data == ~0U);
+}
+
+
+static void
+lba_wr_cfg( struct lba_device *d, u32 tok, u8 reg, u32 data, u32 size)
+{
+	int error = 0;
+	u32 arb_mask = 0;
+	u32 error_config = 0;
+	u32 status_control = 0;
+
+	ASSERT((size == sizeof(u8)) ||
+		(size == sizeof(u16)) ||
+		(size == sizeof(u32)));
+
+	if ((size != sizeof(u8)) &&
+		(size != sizeof(u16)) &&
+		(size != sizeof(u32))) {
+			return;
+	}
+
+	LBA_CFG_SETUP(d, tok);
+	LBA_CFG_ADDR_SETUP(d, tok | reg);
+	switch (size) {
+	case sizeof(u8):
+		WRITE_REG8((u8) data, d->hba.base_addr + LBA_PCI_CFG_DATA + (reg&3));
+		break;
+	case sizeof(u16):
+		WRITE_REG16((u8) data, d->hba.base_addr + LBA_PCI_CFG_DATA +(reg&2));
+		break;
+	case sizeof(u32):
+		WRITE_REG32(data, d->hba.base_addr + LBA_PCI_CFG_DATA);
+		break;
+	default:
+		break;
+	}
+	LBA_CFG_MASTER_ABORT_CHECK(d, d->hba.base_addr, tok, error);
+	LBA_CFG_RESTORE(d, d->hba.base_addr);
+}
+
+
+/*
+ * LBA 4.0 config write code implements non-postable semantics
+ * by doing a read of CONFIG ADDR after the write.
+ */
+
+static int lba_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 data)
+{
+	struct lba_device *d = LBA_DEV(bus->sysdata);
+	u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
+	u32 tok = LBA_CFG_TOK(local_bus,devfn);
+
+ 	ASSERT((tok & 0xff) == 0);
+	ASSERT(pos < 0x100);
+
+	if (!LBA_TR4PLUS(d) && !LBA_SKIP_PROBE(d)) {
+		/* Original Workaround */
+		lba_wr_cfg(d, tok, pos, (u32) data, size);
+		DBG_CFG("%s(%x+%2x) = 0x%x (a)\n", __FUNCTION__, tok, pos,data);
+		return 0;
+	}
+
+	if (LBA_SKIP_PROBE(d) && (!lba_device_present(bus->secondary, devfn, d))) {
+		DBG_CFG("%s(%x+%2x) = 0x%x (b)\n", __FUNCTION__, tok, pos,data);
+		return 1; /* New Workaround */
+	}
+
+	DBG_CFG("%s(%x+%2x) = 0x%x (c)\n", __FUNCTION__, tok, pos, data);
+	/* Basic Algorithm */
+	LBA_CFG_TR4_ADDR_SETUP(d, tok | pos);
+	switch(size) {
+	case 1: WRITE_REG8 (data, d->hba.base_addr + LBA_PCI_CFG_DATA);
+		   break;
+	case 2: WRITE_REG16(data, d->hba.base_addr + LBA_PCI_CFG_DATA);
+		   break;
+	case 4: WRITE_REG32(data, d->hba.base_addr + LBA_PCI_CFG_DATA);
+		   break;
+	}
+	lba_t32 = READ_REG32(d->hba.base_addr + LBA_PCI_CFG_ADDR);
+	return 0;
+}
+
+
+static struct pci_ops lba_cfg_ops = {
+	read:	lba_cfg_read,
+	write:	lba_cfg_write,
+};
+
+
+static void
+lba_bios_init(void)
+{
+	DBG(MODULE_NAME ": lba_bios_init\n");
+}
+
+
+#ifdef __LP64__
+
+/*
+** Determine if a device is already configured.
+** If so, reserve it resources.
+**
+** Read PCI cfg command register and see if I/O or MMIO is enabled.
+** PAT has to enable the devices it's using.
+**
+** Note: resources are fixed up before we try to claim them.
+*/
+static void
+lba_claim_dev_resources(struct pci_dev *dev)
+{
+	u16 cmd;
+	int i, srch_flags;
+
+	(void) pci_read_config_word(dev, PCI_COMMAND, &cmd);
+
+	srch_flags  = (cmd & PCI_COMMAND_IO) ? IORESOURCE_IO : 0;
+	if (cmd & PCI_COMMAND_MEMORY)
+		srch_flags |= IORESOURCE_MEM;
+
+	if (!srch_flags)
+		return;
+
+	for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
+		if (dev->resource[i].flags & srch_flags) {
+			pci_claim_resource(dev, i);
+			DBG("   claimed %s %d [%lx,%lx]/%x\n",
+				dev->slot_name, i,
+				dev->resource[i].start,
+				dev->resource[i].end,
+				(int) dev->resource[i].flags
+				);
+		}
+	}
+}
+#endif
+
+
+/*
+** The algorithm is generic code.
+** But it needs to access local data structures to get the IRQ base.
+** Could make this a "pci_fixup_irq(bus, region)" but not sure
+** it's worth it.
+**
+** Called by do_pci_scan_bus() immediately after each PCI bus is walked.
+** Resources aren't allocated until recursive buswalk below HBA is completed.
+*/
+static void
+lba_fixup_bus(struct pci_bus *bus)
+{
+	struct list_head *ln;
+#ifdef FBB_SUPPORT
+	u16 fbb_enable = PCI_STATUS_FAST_BACK;
+	u16 status;
+#endif
+	struct lba_device *ldev = LBA_DEV(bus->sysdata);
+	int lba_portbase = HBA_PORT_BASE(ldev->hba.hba_num);
+
+	DBG("lba_fixup_bus(0x%p) bus %d sysdata 0x%p\n",
+		bus, bus->secondary, bus->sysdata);
+
+	/*
+	** Properly Setup MMIO resources for this bus.
+	** pci_alloc_primary_bus() mangles this.
+	*/
+	if (NULL == bus->self) {
+		int err;
+
+		DBG("lba_fixup_bus() %s [%lx/%lx]/%x\n",
+			ldev->hba.io_space.name,
+			ldev->hba.io_space.start, ldev->hba.io_space.end,
+			(int) ldev->hba.io_space.flags);
+		DBG("lba_fixup_bus() %s [%lx/%lx]/%x\n",
+			ldev->hba.lmmio_space.name,
+			ldev->hba.lmmio_space.start, ldev->hba.lmmio_space.end,
+			(int) ldev->hba.lmmio_space.flags);
+
+		err = request_resource(&ioport_resource, &(ldev->hba.io_space));
+		if (err < 0) {
+			BUG();
+			lba_dump_res(&ioport_resource, 2);
+		}
+		err = request_resource(&iomem_resource, &(ldev->hba.lmmio_space));
+		if (err < 0) {
+			BUG();
+			lba_dump_res(&iomem_resource, 2);
+		}
+
+		bus->resource[0] = &(ldev->hba.io_space);
+		bus->resource[1] = &(ldev->hba.lmmio_space);
+	} else {
+		/* KLUGE ALERT!
+		** PCI-PCI Bridge resource munging.
+		** This hack should go away in the near future.
+		** It's based on the Alpha port.
+		*/
+		int i;
+		u16 cmd;
+
+		for (i = 0; i < 4; i++) {
+			bus->resource[i] =
+				&bus->self->resource[PCI_BRIDGE_RESOURCES+i];
+			bus->resource[i]->name = bus->name;
+		}
+#if 0
+		bus->resource[0]->flags |= pci_bridge_check_io(bus->self);
+#else
+		bus->resource[0]->flags |= IORESOURCE_IO;
+#endif
+		bus->resource[1]->flags |= IORESOURCE_MEM;
+		bus->resource[2]->flags = 0;	/* Don't support prefetchable */
+		bus->resource[3]->flags = 0;	/* not used */
+
+		/* 
+		** If the PPB is enabled (ie already configured) then
+		** just read those values.
+		*/
+		(void) pci_read_config_word(bus->self, PCI_COMMAND, &cmd);
+		if (cmd & (PCI_COMMAND_MEMORY | PCI_COMMAND_IO)) {
+			pci_read_bridge_bases(bus);
+		} else {
+			/* Not configured.
+			** For now, propogate HBA limits to the bus;
+			**	PCI will adjust them later.
+			*/
+			bus->resource[0]->end = ldev->hba.io_space.end;
+			bus->resource[1]->end = ldev->hba.lmmio_space.end;
+		}
+
+		/* Turn off downstream PF memory address range by default */
+		bus->resource[2]->start = 1024*1024;
+		bus->resource[2]->end = bus->resource[2]->start - 1;
+	}
+
+
+	list_for_each(ln, &bus->devices) {
+		int i;
+		struct pci_dev *dev = pci_dev_b(ln);
+
+		DBG("lba_fixup_bus() %s\n", dev->name);
+
+		/* Virtualize Device/Bridge Resources. */
+		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+			struct resource *res = &dev->resource[i];
+
+			/* If resource not allocated - skip it */
+			if (!res->start)
+				continue;
+
+			if (res->flags & IORESOURCE_IO) {
+				DBG("lba_fixup_bus() I/O Ports [%lx/%lx] -> ",
+					res->start, res->end);
+				res->start |= lba_portbase;
+				res->end   |= lba_portbase;
+				DBG("[%lx/%lx]\n", res->start, res->end);
+			} else if (res->flags & IORESOURCE_MEM) {
+				/*
+				** Convert PCI (IO_VIEW) addresses to
+				** processor (PA_VIEW) addresses
+				 */
+				DBG("lba_fixup_bus() MMIO [%lx/%lx] -> ",
+					res->start, res->end);
+				res->start = PCI_HOST_ADDR(HBA_DATA(ldev), res->start);
+				res->end   = PCI_HOST_ADDR(HBA_DATA(ldev), res->end);
+				DBG("[%lx/%lx]\n", res->start, res->end);
+			}
+		}
+
+#ifdef FBB_SUPPORT
+		/*
+		** If one device does not support FBB transfers,
+		** No one on the bus can be allowed to use them.
+		*/
+		(void) pci_read_config_word(dev, PCI_STATUS, &status);
+		fbb_enable &= status;
+#endif
+
+#ifdef __LP64__
+		if (is_pdc_pat()) {
+			/* Claim resources for PDC's devices */
+			lba_claim_dev_resources(dev);
+		}
+#endif
+
+                /*
+		** P2PB's have no IRQs. ignore them.
+		*/
+		if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)
+			continue;
+
+		/* Adjust INTERRUPT_LINE for this dev */
+		iosapic_fixup_irq(ldev->iosapic_obj, dev);
+	}
+
+#ifdef FBB_SUPPORT
+/* FIXME/REVISIT - finish figuring out to set FBB on both
+** pci_setup_bridge() clobbers PCI_BRIDGE_CONTROL.
+** Can't fixup here anyway....garr...
+*/
+	if (fbb_enable) {
+		if (bus->self) {
+			u8 control;
+			/* enable on PPB */
+			(void) pci_read_config_byte(bus->self, PCI_BRIDGE_CONTROL, &control);
+			(void) pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, control | PCI_STATUS_FAST_BACK);
+
+		} else {
+			/* enable on LBA */
+		}
+		fbb_enable = PCI_COMMAND_FAST_BACK;
+	}
+
+	/* Lastly enable FBB/PERR/SERR on all devices too */
+	list_for_each(ln, &bus->devices) {
+		(void) pci_read_config_word(dev, PCI_COMMAND, &status);
+		status |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR | fbb_enable;
+		(void) pci_write_config_word(dev, PCI_COMMAND, status);
+	}
+#endif
+}
+
+
+struct pci_bios_ops lba_bios_ops = {
+	init:		lba_bios_init,
+	fixup_bus:	lba_fixup_bus,
+};
+
+
+
+
+/*******************************************************
+**
+** LBA Sprockets "I/O Port" Space Accessor Functions
+**
+** This set of accessor functions is intended for use with
+** "legacy firmware" (ie Sprockets on Allegro/Forte boxes).
+**
+** Many PCI devices don't require use of I/O port space (eg Tulip,
+** NCR720) since they export the same registers to both MMIO and
+** I/O port space. In general I/O port space is slower than
+** MMIO since drivers are designed so PIO writes can be posted.
+**
+********************************************************/
+
+#define LBA_PORT_IN(size, mask) \
+static u##size lba_astro_in##size (struct pci_hba_data *d, u16 addr) \
+{ \
+	u##size t; \
+	t = READ_REG##size(LBA_ASTRO_PORT_BASE + addr); \
+	DBG_PORT(" 0x%x\n", t); \
+	return (t); \
+}
+
+LBA_PORT_IN( 8, 3)
+LBA_PORT_IN(16, 2)
+LBA_PORT_IN(32, 0)
+
+
+
+/*
+** BUG X4107:  Ordering broken - DMA RD return can bypass PIO WR
+**
+** Fixed in Elroy 2.2. The READ_U32(..., LBA_FUNC_ID) below is
+** guarantee non-postable completion semantics - not avoid X4107.
+** The READ_U32 only guarantees the write data gets to elroy but
+** out to the PCI bus. We can't read stuff from I/O port space
+** since we don't know what has side-effects. Attempting to read
+** from configuration space would be suicidal given the number of
+** bugs in that elroy functionality.
+**
+**      Description:
+**          DMA read results can improperly pass PIO writes (X4107).  The
+**          result of this bug is that if a processor modifies a location in
+**          memory after having issued PIO writes, the PIO writes are not
+**          guaranteed to be completed before a PCI device is allowed to see
+**          the modified data in a DMA read.
+**
+**          Note that IKE bug X3719 in TR1 IKEs will result in the same
+**          symptom.
+**
+**      Workaround:
+**          The workaround for this bug is to always follow a PIO write with
+**          a PIO read to the same bus before starting DMA on that PCI bus.
+**
+*/
+#define LBA_PORT_OUT(size, mask) \
+static void lba_astro_out##size (struct pci_hba_data *d, u16 addr, u##size val) \
+{ \
+	ASSERT(d != NULL); \
+	DBG_PORT("%s(0x%p, 0x%x, 0x%x)\n", __FUNCTION__, d, addr, val); \
+	WRITE_REG##size(val, LBA_ASTRO_PORT_BASE + addr); \
+	if (LBA_DEV(d)->hw_rev < 3) \
+		lba_t32 = READ_U32(d->base_addr + LBA_FUNC_ID); \
+}
+
+LBA_PORT_OUT( 8, 3)
+LBA_PORT_OUT(16, 2)
+LBA_PORT_OUT(32, 0)
+
+
+static struct pci_port_ops lba_astro_port_ops = {
+	inb:	lba_astro_in8,
+	inw:	lba_astro_in16,
+	inl:	lba_astro_in32,
+	outb:	lba_astro_out8,
+	outw:	lba_astro_out16,
+	outl:	lba_astro_out32
+};
+
+
+#ifdef __LP64__
+#define PIOP_TO_GMMIO(lba, addr) \
+	((lba)->iop_base + (((addr)&0xFFFC)<<10) + ((addr)&3))
+
+/*******************************************************
+**
+** LBA PAT "I/O Port" Space Accessor Functions
+**
+** This set of accessor functions is intended for use with
+** "PAT PDC" firmware (ie Prelude/Rhapsody/Piranha boxes).
+**
+** This uses the PIOP space located in the first 64MB of GMMIO.
+** Each rope gets a full 64*KB* (ie 4 bytes per page) this way.
+** bits 1:0 stay the same.  bits 15:2 become 25:12.
+** Then add the base and we can generate an I/O Port cycle.
+********************************************************/
+#undef LBA_PORT_IN
+#define LBA_PORT_IN(size, mask) \
+static u##size lba_pat_in##size (struct pci_hba_data *l, u16 addr) \
+{ \
+	u##size t; \
+	ASSERT(bus != NULL); \
+	DBG_PORT("%s(0x%p, 0x%x) ->", __FUNCTION__, l, addr); \
+	t = READ_REG##size(PIOP_TO_GMMIO(LBA_DEV(l), addr)); \
+	DBG_PORT(" 0x%x\n", t); \
+	return (t); \
+}
+
+LBA_PORT_IN( 8, 3)
+LBA_PORT_IN(16, 2)
+LBA_PORT_IN(32, 0)
+
+
+#undef LBA_PORT_OUT
+#define LBA_PORT_OUT(size, mask) \
+static void lba_pat_out##size (struct pci_hba_data *l, u16 addr, u##size val) \
+{ \
+	void *where = (void *) PIOP_TO_GMMIO(LBA_DEV(l), addr); \
+	ASSERT(bus != NULL); \
+	DBG_PORT("%s(0x%p, 0x%x, 0x%x)\n", __FUNCTION__, l, addr, val); \
+	WRITE_REG##size(val, where); \
+	/* flush the I/O down to the elroy at least */ \
+	lba_t32 = READ_U32(l->base_addr + LBA_FUNC_ID); \
+}
+
+LBA_PORT_OUT( 8, 3)
+LBA_PORT_OUT(16, 2)
+LBA_PORT_OUT(32, 0)
+
+
+static struct pci_port_ops lba_pat_port_ops = {
+	inb:	lba_pat_in8,
+	inw:	lba_pat_in16,
+	inl:	lba_pat_in32,
+	outb:	lba_pat_out8,
+	outw:	lba_pat_out16,
+	outl:	lba_pat_out32
+};
+
+
+
+/*
+** make range information from PDC available to PCI subsystem.
+** We make the PDC call here in order to get the PCI bus range
+** numbers. The rest will get forwarded in pcibios_fixup_bus().
+** We don't have a struct pci_bus assigned to us yet.
+*/
+static void
+lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
+{
+	unsigned long bytecnt;
+	pdc_pat_cell_mod_maddr_block_t pa_pdc_cell;	/* PA_VIEW */
+	pdc_pat_cell_mod_maddr_block_t io_pdc_cell;	/* IO_VIEW */
+	long io_count;
+	long status;	/* PDC return status */
+	long pa_count;
+	int i;
+
+	/* return cell module (IO view) */
+	status = pdc_pat_cell_module(&bytecnt, pa_dev->pcell_loc, pa_dev->mod_index,
+				PA_VIEW, & pa_pdc_cell);
+	pa_count = pa_pdc_cell.mod[1];
+
+	status |= pdc_pat_cell_module(&bytecnt, pa_dev->pcell_loc, pa_dev->mod_index,
+				IO_VIEW, &io_pdc_cell);
+	io_count = io_pdc_cell.mod[1];
+
+	/* We've already done this once for device discovery...*/
+	if (status != PDC_OK) {
+		panic("pdc_pat_cell_module() call failed for LBA!\n");
+	}
+
+	if (PAT_GET_ENTITY(pa_pdc_cell.mod_info) != PAT_ENTITY_LBA) {
+		panic("pdc_pat_cell_module() entity returned != PAT_ENTITY_LBA!\n");
+	}
+
+	/*
+	** Inspect the resources PAT tells us about
+	*/
+	for (i = 0; i < pa_count; i++) {
+		struct {
+			unsigned long type;
+			unsigned long start;
+			unsigned long end;	/* aka finish */
+		} *p, *io;
+		struct resource *r;
+
+		p = (void *) &(pa_pdc_cell.mod[2+i*3]);
+		io = (void *) &(io_pdc_cell.mod[2+i*3]);
+
+		/* Convert the PAT range data to PCI "struct resource" */
+		switch(p->type & 0xff) {
+		case PAT_PBNUM:
+			lba_dev->hba.bus_num.start = p->start;
+			lba_dev->hba.bus_num.end   = p->end;
+			break;
+		case PAT_LMMIO:
+			/* used to fix up pre-initialized MEM BARs */
+			lba_dev->hba.lmmio_space_offset = p->start - io->start;
+
+			r = &(lba_dev->hba.lmmio_space);
+			r->name   = "LBA LMMIO";
+			r->start  = p->start;
+			r->end    = p->end;
+			r->flags  = IORESOURCE_MEM;
+			r->parent = r->sibling = r->child = NULL;
+			break;
+		case PAT_GMMIO:
+			printk(KERN_WARNING MODULE_NAME
+				" range[%d] : ignoring GMMIO (0x%lx)\n",
+				i, p->start);
+			lba_dev->gmmio_base = p->start;
+			break;
+		case PAT_NPIOP:
+			printk(KERN_WARNING MODULE_NAME
+				" range[%d] : ignoring NPIOP (0x%lx)\n",
+				i, p->start);
+			break;
+		case PAT_PIOP:
+			/*
+			** Postable I/O port space is per PCI host adapter.
+			*/
+
+			/* save base of 64MB PIOP region */
+			lba_dev->iop_base = p->start;
+
+			r = &(lba_dev->hba.io_space);
+			r->name   = "LBA I/O Port";
+			r->start  = HBA_PORT_BASE(lba_dev->hba.hba_num);
+			r->end    = r->start + HBA_PORT_SPACE_SIZE - 1;
+			r->flags  = IORESOURCE_IO;
+			r->parent = r->sibling = r->child = NULL;
+			break;
+		default:
+			printk(KERN_WARNING MODULE_NAME
+				" range[%d] : unknown pat range type (0x%lx)\n",
+				i, p->type & 0xff);
+			break;
+		}
+	}
+}
+#endif	/* __LP64__ */
+
+
+static void
+lba_legacy_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
+{
+	struct resource *r;
+	unsigned long rsize;
+	int lba_num;
+
+#ifdef __LP64__
+	/*
+	** Sign extend all BAR values on "legacy" platforms.
+	** "Sprockets" PDC (Forte/Allegro) initializes everything
+	** for "legacy" 32-bit OS (HPUX 10.20).
+	** Upper 32-bits of 64-bit BAR will be zero too.
+	*/
+	lba_dev->hba.lmmio_space_offset = 0xffffffff00000000UL;
+#else
+	lba_dev->hba.lmmio_space_offset = 0UL;
+#endif
+
+	/*
+	** With "legacy" firmware, the lowest byte of FW_SCRATCH
+	** represents bus->secondary and the second byte represents
+	** bus->subsidiary (i.e. highest PPB programmed by firmware).
+	** PCI bus walk *should* end up with the same result.
+	** FIXME: But we don't have sanity checks in PCI or LBA.
+	*/
+	lba_num = READ_REG32(pa_dev->hpa + LBA_FW_SCRATCH);
+	r = &(lba_dev->hba.bus_num);
+	r->name = "LBA PCI Busses";
+	r->start = lba_num & 0xff;
+	r->end = (lba_num>>8) & 0xff;
+
+	/* Set up local PCI Bus resources - we don't really need
+	** them for Legacy boxes but it's nice to see in /proc.
+	*/
+	r = &(lba_dev->hba.lmmio_space);
+	r->name  = "LBA PCI LMMIO";
+	r->flags = IORESOURCE_MEM;
+	/* Ignore "Range Enable" bit in the BASE register */
+	r->start = PCI_HOST_ADDR(HBA_DATA(lba_dev),
+		((long) READ_REG32(pa_dev->hpa + LBA_LMMIO_BASE)) & ~1UL);
+	rsize =  ~READ_REG32(pa_dev->hpa + LBA_LMMIO_MASK) + 1;
+
+	/*
+	** Each rope only gets part of the distributed range.
+	** Adjust "window" for this rope
+	*/
+	rsize /= ROPES_PER_SBA;
+	r->start += rsize * LBA_NUM(pa_dev->hpa);
+	r->end = r->start + rsize - 1 ;
+
+	/*
+	** XXX FIXME - ignore LBA_ELMMIO_BASE for now
+	** "Directed" ranges are used when the "distributed range" isn't
+	** sufficient for all devices below a given LBA.  Typically devices
+	** like graphics cards or X25 may need a directed range when the
+	** bus has multiple slots (ie multiple devices) or the device
+	** needs more than the typical 4 or 8MB a distributed range offers.
+	**
+	** The main reason for ignoring it now frigging complications.
+	** Directed ranges may overlap (and have precedence) over
+	** distributed ranges. Ie a distributed range assigned to a unused
+	** rope may be used by a directed range on a different rope.
+	** Support for graphics devices may require fixing this
+	** since they may be assigned a directed range which overlaps
+	** an existing (but unused portion of) distributed range.
+	*/
+	r = &(lba_dev->hba.elmmio_space);
+	r->name  = "extra LBA PCI LMMIO";
+	r->flags = IORESOURCE_MEM;
+	r->start = READ_REG32(pa_dev->hpa + LBA_ELMMIO_BASE);
+	r->end   = 0;
+
+	/* check Range Enable bit */
+	if (r->start & 1) {
+		/* First baby step to getting Direct Ranges listed in /proc.
+		** AFAIK, only Sprockets PDC will setup a directed Range.
+		*/
+
+		r->start &= ~1;
+		r->end    = r->start;
+		r->end   += ~READ_REG32(pa_dev->hpa + LBA_ELMMIO_MASK);
+		printk(KERN_DEBUG "WARNING: Ignoring enabled ELMMIO BASE 0x%0lx  SIZE 0x%lx\n",
+			r->start,
+			r->end + 1);
+
+	}
+
+	r = &(lba_dev->hba.io_space);
+	r->name  = "LBA PCI I/O Ports";
+	r->flags = IORESOURCE_IO;
+	r->start = READ_REG32(pa_dev->hpa + LBA_IOS_BASE) & ~1L;
+	r->end   = r->start + (READ_REG32(pa_dev->hpa + LBA_IOS_MASK) ^ (HBA_PORT_SPACE_SIZE - 1));
+
+	/* Virtualize the I/O Port space ranges */
+	lba_num = HBA_PORT_BASE(lba_dev->hba.hba_num);
+	r->start |= lba_num;
+	r->end   |= lba_num;
+}
+
+
+/**************************************************************************
+**
+**   LBA initialization code (HW and SW)
+**
+**   o identify LBA chip itself
+**   o initialize LBA chip modes (HardFail)
+**   o FIXME: initialize DMA hints for reasonable defaults
+**   o enable configuration functions
+**   o call pci_register_ops() to discover devs (fixup/fixup_bus get invoked)
+**
+**************************************************************************/
+
+static int __init
+lba_hw_init(struct lba_device *d)
+{
+	u32 stat;
+	u32 bus_reset;	/* PDC_PAT_BUG */
+
+#if 0
+	printk(KERN_DEBUG "LBA %lx  STAT_CTL %Lx  ERROR_CFG %Lx  STATUS %Lx DMA_CTL %Lx\n",
+		d->hba.base_addr,
+		READ_REG64(d->hba.base_addr + LBA_STAT_CTL),
+		READ_REG64(d->hba.base_addr + LBA_ERROR_CONFIG),
+		READ_REG64(d->hba.base_addr + LBA_ERROR_STATUS),
+		READ_REG64(d->hba.base_addr + LBA_DMA_CTL) );
+	printk(KERN_DEBUG "	ARB mask %Lx  pri %Lx  mode %Lx  mtlt %Lx\n",
+		READ_REG64(d->hba.base_addr + LBA_ARB_MASK),
+		READ_REG64(d->hba.base_addr + LBA_ARB_PRI),
+		READ_REG64(d->hba.base_addr + LBA_ARB_MODE),
+		READ_REG64(d->hba.base_addr + LBA_ARB_MTLT) );
+	printk(KERN_DEBUG "	HINT cfg 0x%Lx\n",
+		READ_REG64(d->hba.base_addr + LBA_HINT_CFG));
+	printk(KERN_DEBUG "	HINT reg ");
+	{ int i;
+	for (i=LBA_HINT_BASE; i< (14*8 + LBA_HINT_BASE); i+=8)
+		printk(" %Lx", READ_REG64(d->hba.base_addr + i));
+	}
+	printk("\n");
+#endif	/* DEBUG_LBA_PAT */
+
+#ifdef __LP64__
+#warning FIXME add support for PDC_PAT_IO "Get slot status" - OLAR support
+#endif
+
+	/* PDC_PAT_BUG: exhibited in rev 40.48  on L2000 */
+	bus_reset = READ_REG32(d->hba.base_addr + LBA_STAT_CTL + 4) & 1;
+	if (bus_reset) {
+		printk(KERN_DEBUG "NOTICE: PCI bus reset still asserted! (clearing)\n");
+	}
+
+	stat = READ_REG32(d->hba.base_addr + LBA_ERROR_CONFIG);
+	if (stat & LBA_SMART_MODE) {
+		printk(KERN_DEBUG "NOTICE: LBA in SMART mode! (cleared)\n");
+		stat &= ~LBA_SMART_MODE;
+		WRITE_REG32(stat, d->hba.base_addr + LBA_ERROR_CONFIG);
+	}
+
+	/* Set HF mode as the default (vs. -1 mode). */
+        stat = READ_REG32(d->hba.base_addr + LBA_STAT_CTL);
+	WRITE_REG32(stat | HF_ENABLE, d->hba.base_addr + LBA_STAT_CTL);
+
+	/*
+	** Writing a zero to STAT_CTL.rf (bit 0) will clear reset signal
+	** if it's not already set. If we just cleared the PCI Bus Reset
+	** signal, wait a bit for the PCI devices to recover and setup.
+	*/
+	if (bus_reset)
+		mdelay(pci_post_reset_delay);
+
+	if (0 == READ_REG32(d->hba.base_addr + LBA_ARB_MASK)) {
+		/*
+		** PDC_PAT_BUG: PDC rev 40.48 on L2000.
+		** B2000/C3600/J6000 also have this problem?
+		** 
+		** Elroys with hot pluggable slots don't get configured
+		** correctly if the slot is empty.  ARB_MASK is set to 0
+		** and we can't master transactions on the bus if it's
+		** not at least one. 0x3 enables elroy and first slot.
+		*/
+		printk(KERN_DEBUG "NOTICE: Enabling PCI Arbitration\n");
+		WRITE_REG32(0x3, d->hba.base_addr + LBA_ARB_MASK);
+	}
+
+	/*
+	** FIXME: Hint registers are programmed with default hint
+	** values by firmware. Hints should be sane even if we
+	** can't reprogram them the way drivers want.
+	*/
+	return 0;
+}
+
+
+
+static void __init
+lba_common_init(struct lba_device *lba_dev)
+{
+	pci_bios = &lba_bios_ops;
+	pcibios_register_hba(HBA_DATA(lba_dev));
+	lba_dev->lba_lock = SPIN_LOCK_UNLOCKED;	
+
+	/*
+	** Set flags which depend on hw_rev
+	*/
+	if (!LBA_TR4PLUS(lba_dev)) {
+		lba_dev->flags |= LBA_FLAG_NO_DMA_DURING_CFG;
+	}
+}
+
+
+
+/*
+** Determine if lba 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 __init
+lba_driver_callback(struct parisc_device *dev)
+{
+	struct lba_device *lba_dev;
+	struct pci_bus *lba_bus;
+	u32 func_class;
+	void *tmp_obj;
+	char *version;
+
+	/* Read HW Rev First */
+	func_class = READ_REG32(dev->hpa + LBA_FCLASS);
+	func_class &= 0xf;
+
+	switch (func_class) {
+	case 0:	version = "TR1.0"; break;
+	case 1:	version = "TR2.0"; break;
+	case 2:	version = "TR2.1"; break;
+	case 3:	version = "TR2.2"; break;
+	case 4:	version = "TR3.0"; break;
+	case 5:	version = "TR4.0"; break;
+	default: version = "TR4+";
+	}
+
+	printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n",
+		MODULE_NAME, version, func_class & 0xf, dev->hpa);
+
+	/* Just in case we find some prototypes... */
+	if (func_class < 2) {
+		printk(KERN_WARNING "Can't support LBA older than TR2.1 "
+			"- continuing under adversity.\n");
+	}
+
+	/*
+	** Tell I/O SAPIC driver we have a IRQ handler/region.
+	*/
+	tmp_obj = iosapic_register(dev->hpa + LBA_IOSAPIC_BASE);
+
+	/* NOTE: PCI devices (e.g. 103c:1005 graphics card) which don't
+	**	have an IRT entry will get NULL back from iosapic code.
+	*/
+	
+	lba_dev = kmalloc(sizeof(struct lba_device), GFP_KERNEL);
+	if (NULL == lba_dev)
+	{
+		printk(KERN_ERR "lba_init_chip - couldn't alloc lba_device\n");
+		return(1);
+	}
+
+	memset(lba_dev, 0, sizeof(struct lba_device));
+
+
+	/* ---------- First : initialize data we already have --------- */
+
+	/*
+	** Need hw_rev to adjust configuration space behavior.
+	** LBA_TR4PLUS macro uses hw_rev field.
+	*/
+	lba_dev->hw_rev = func_class;
+
+	lba_dev->hba.base_addr = dev->hpa;  /* faster access */
+	lba_dev->hba.dev = dev;
+	lba_dev->iosapic_obj = tmp_obj;  /* save interrupt handle */
+	lba_dev->hba.iommu = sba_get_iommu(dev);  /* get iommu data */
+
+	/* ------------ Second : initialize common stuff ---------- */
+	lba_common_init(lba_dev);
+
+	if (lba_hw_init(lba_dev))
+		return(1);
+
+	/* ---------- Third : setup I/O Port and MMIO resources  --------- */
+
+#ifdef __LP64__
+	if (is_pdc_pat()) {
+		/* PDC PAT firmware uses PIOP region of GMMIO space. */
+		pci_port = &lba_pat_port_ops;
+
+		/* Go ask PDC PAT what resources this LBA has */
+		lba_pat_resources(dev, lba_dev);
+	} else
+#endif
+	{
+		/* Sprockets PDC uses NPIOP region */
+		pci_port = &lba_astro_port_ops;
+
+		/* Poke the chip a bit for /proc output */
+		lba_legacy_resources(dev, lba_dev);
+	}
+
+	/* 
+	** Tell PCI support another PCI bus was found.
+	** Walks PCI bus for us too.
+	*/
+	lba_bus = lba_dev->hba.hba_bus =
+		pci_scan_bus(lba_dev->hba.bus_num.start, &lba_cfg_ops, (void *) lba_dev);
+
+#ifdef __LP64__
+	if (is_pdc_pat()) {
+		/* assign resources to un-initialized devices */
+		DBG_PAT("LBA pcibios_assign_unassigned_resources()\n");
+		pcibios_assign_unassigned_resources(lba_bus);
+
+#ifdef DEBUG_LBA_PAT
+		DBG_PAT("\nLBA PIOP resource tree\n");
+		lba_dump_res(&lba_dev->hba.io_space, 2);
+		DBG_PAT("\nLBA LMMIO resource tree\n");
+		lba_dump_res(&lba_dev->hba.lmmio_space, 2);
+#endif
+	}
+#endif
+
+	/*
+	** Once PCI register ops has walked the bus, access to config
+	** space is restricted. Avoids master aborts on config cycles.
+	** Early LBA revs go fatal on *any* master abort.
+	*/
+	if (!LBA_TR4PLUS(lba_dev)) {
+		lba_dev->flags |= LBA_FLAG_SKIP_PROBE;
+	}
+
+	/* Whew! Finally done! Tell services we got this one covered. */
+	return 0;
+}
+
+static struct parisc_device_id lba_tbl[] = {
+	{ HPHW_BRIDGE, HVERSION_REV_ANY_ID, 0x782, 0xa },
+	{ 0, }
+};
+
+static struct parisc_driver lba_driver = {
+	name:		MODULE_NAME,
+	id_table:	lba_tbl,
+	probe:		lba_driver_callback
+};
+
+/*
+** One time initialization to let the world know the LBA was found.
+** Must be called exactly once before pci_init().
+*/
+void __init lba_init(void)
+{
+	register_parisc_driver(&lba_driver);
+}
+
+/*
+** Initialize the IBASE/IMASK registers for LBA (Elroy).
+** Only called from sba_iommu.c in order to route ranges (MMIO vs DMA).
+** sba_iommu is responsible for locking (none needed at init time).
+*/
+void
+lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask)
+{
+	unsigned long base_addr = lba->hpa;
+
+	imask <<= 2;	/* adjust for hints - 2 more bits */
+
+	ASSERT((ibase & 0x003fffff) == 0);
+	ASSERT((imask & 0x003fffff) == 0);
+	
+	DBG("%s() ibase 0x%x imask 0x%x\n", __FUNCTION__, ibase, imask);
+	WRITE_REG32( imask, base_addr + LBA_IMASK);
+	WRITE_REG32( ibase, base_addr + LBA_IBASE);
+}
+
diff -Nru a/drivers/parisc/led.c b/drivers/parisc/led.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/parisc/led.c	Mon Nov  4 14:31:01 2002
@@ -0,0 +1,775 @@
+/*
+ *    Chassis LCD/LED driver for HP-PARISC workstations
+ *
+ *      (c) Copyright 2000 Red Hat Software
+ *      (c) Copyright 2000 Helge Deller <hdeller@redhat.com>
+ *      (c) Copyright 2001-2002 Helge Deller <deller@gmx.de>
+ *      (c) Copyright 2001 Randolph Chung <tausq@debian.org>
+ *
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2 of the License, or
+ *      (at your option) any later version.
+ *
+ * TODO:
+ *	- speed-up calculations with inlined assembler
+ *	- interface to write to second row of LCD from /proc
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/stddef.h>	/* for offsetof() */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/ioport.h>
+#include <linux/bitops.h>
+#include <linux/version.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/reboot.h>
+#include <linux/proc_fs.h>
+#include <linux/ctype.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/hardware.h>
+#include <asm/param.h>		/* HZ */
+#include <asm/led.h>
+#include <asm/pdc.h>
+#include <asm/uaccess.h>
+
+/* The control of the LEDs and LCDs on PARISC-machines have to be done 
+   completely in software. The necessary calculations are done in a tasklet
+   which is scheduled at every timer interrupt and since the calculations 
+   may consume relatively much CPU-time some of the calculations can be 
+   turned off with the following variables (controlled via procfs) */
+
+static int led_type = -1;
+static int led_heartbeat = 1;
+static int led_diskio = 1;
+static int led_lanrxtx = 1;
+static char lcd_text[32];
+
+#if 0
+#define DPRINTK(x)	printk x
+#else
+#define DPRINTK(x)
+#endif
+
+
+#define CALC_ADD(val, comp, add) \
+ (val<=(comp/8) ? add/16 : val<=(comp/4) ? add/8 : val<=(comp/2) ? add/4 : add)
+
+
+struct lcd_block {
+	unsigned char command;	/* stores the command byte      */
+	unsigned char on;	/* value for turning LED on     */
+	unsigned char off;	/* value for turning LED off    */
+};
+
+/* Structure returned by PDC_RETURN_CHASSIS_INFO */
+/* NOTE: we use unsigned long:16 two times, since the following member 
+   lcd_cmd_reg_addr needs to be 64bit aligned on 64bit PA2.0-machines */
+struct pdc_chassis_lcd_info_ret_block {
+	unsigned long model:16;		/* DISPLAY_MODEL_XXXX */
+	unsigned long lcd_width:16;	/* width of the LCD in chars (DISPLAY_MODEL_LCD only) */
+	char *lcd_cmd_reg_addr;		/* ptr to LCD cmd-register & data ptr for LED */
+	char *lcd_data_reg_addr;	/* ptr to LCD data-register (LCD only) */
+	unsigned int min_cmd_delay;	/* delay in uS after cmd-write (LCD only) */
+	unsigned char reset_cmd1;	/* command #1 for writing LCD string (LCD only) */
+	unsigned char reset_cmd2;	/* command #2 for writing LCD string (LCD only) */
+	unsigned char act_enable;	/* 0 = no activity (LCD only) */
+	struct lcd_block heartbeat;
+	struct lcd_block disk_io;
+	struct lcd_block lan_rcv;
+	struct lcd_block lan_tx;
+	char _pad;
+};
+
+
+/* LCD_CMD and LCD_DATA for KittyHawk machines */
+#define KITTYHAWK_LCD_CMD  (0xfffffffff0190000UL) /* 64bit-ready */
+#define KITTYHAWK_LCD_DATA (KITTYHAWK_LCD_CMD+1)
+
+/* lcd_info is pre-initialized to the values needed to program KittyHawk LCD's 
+ * HP seems to have used Sharp/Hitachi HD44780 LCDs most of the time. */
+static struct pdc_chassis_lcd_info_ret_block
+lcd_info __attribute__((aligned(8))) =
+{
+      model:		DISPLAY_MODEL_LCD,
+      lcd_width:	16,
+      lcd_cmd_reg_addr:	(char *) KITTYHAWK_LCD_CMD,
+      lcd_data_reg_addr:(char *) KITTYHAWK_LCD_DATA,
+      min_cmd_delay:	40,
+      reset_cmd1:	0x80,
+      reset_cmd2:	0xc0,
+};
+
+
+/* direct access to some of the lcd_info variables */
+#define LCD_CMD_REG	lcd_info.lcd_cmd_reg_addr	 
+#define LCD_DATA_REG	lcd_info.lcd_data_reg_addr	 
+#define LED_DATA_REG	lcd_info.lcd_cmd_reg_addr	/* LASI & ASP only */
+
+
+/* ptr to LCD/LED-specific function */
+static void (*led_func_ptr) (unsigned char);
+
+#define LED_HASLCD 1
+#define LED_NOLCD  0
+#ifdef CONFIG_PROC_FS
+static int led_proc_read(char *page, char **start, off_t off, int count, 
+	int *eof, void *data)
+{
+	char *out = page;
+	int len;
+
+	switch ((long)data)
+	{
+	case LED_NOLCD:
+		out += sprintf(out, "Heartbeat: %d\n", led_heartbeat);
+		out += sprintf(out, "Disk IO: %d\n", led_diskio);
+		out += sprintf(out, "LAN Rx/Tx: %d\n", led_lanrxtx);
+		break;
+	case LED_HASLCD:
+		out += sprintf(out, "%s\n", lcd_text);
+		break;
+	default:
+		*eof = 1;
+		return 0;
+	}
+
+	len = out - page - off;
+	if (len < count) {
+		*eof = 1;
+		if (len <= 0) return 0;
+	} else {
+		len = count;
+	}
+	*start = page + off;
+	return len;
+}
+
+static int led_proc_write(struct file *file, const char *buf, 
+	unsigned long count, void *data)
+{
+	char *cur, lbuf[count];
+	int d;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	memset(lbuf, 0, count);
+
+	copy_from_user(lbuf, buf, count);
+	cur = lbuf;
+
+	/* skip initial spaces */
+	while (*cur && isspace(*cur))
+	{
+		cur++;
+	}
+
+	switch ((long)data)
+	{
+	case LED_NOLCD:
+		d = *cur++ - '0';
+		if (d != 0 && d != 1) goto parse_error;
+		led_heartbeat = d;
+
+		if (*cur++ != ' ') goto parse_error;
+
+		d = *cur++ - '0';
+		if (d != 0 && d != 1) goto parse_error;
+		led_diskio = d;
+
+		if (*cur++ != ' ') goto parse_error;
+
+		d = *cur++ - '0';
+		if (d != 0 && d != 1) goto parse_error;
+		led_lanrxtx = d;
+
+		break;
+	case LED_HASLCD:
+		if (*cur == 0) 
+		{
+			/* reset to default */
+			lcd_print("Linux " UTS_RELEASE);
+		}
+		else
+		{
+			/* chop off trailing \n.. if the user gives multiple
+			 * \n then it's all their fault.. */
+			if (*cur && cur[strlen(cur)-1] == '\n')
+				cur[strlen(cur)-1] = 0;
+			lcd_print(cur);
+		}
+		break;
+	default:
+		return 0;
+	}
+	
+	return count;
+
+parse_error:
+	if ((long)data == LED_NOLCD)
+		printk(KERN_CRIT "Parse error: expect \"n n n\" (n == 0 or 1) for heartbeat,\ndisk io and lan tx/rx indicators\n");
+	return -EINVAL;
+}
+
+static int __init led_create_procfs(void)
+{
+	struct proc_dir_entry *proc_pdc_root = NULL;
+	struct proc_dir_entry *ent;
+
+	if (led_type == -1) return -1;
+
+	proc_pdc_root = proc_mkdir("pdc", 0);
+	if (!proc_pdc_root) return -1;
+	proc_pdc_root->owner = THIS_MODULE;
+	ent = create_proc_entry("led", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root);
+	if (!ent) return -1;
+	ent->nlink = 1;
+	ent->data = (void *)LED_NOLCD; /* LED */
+	ent->read_proc = led_proc_read;
+	ent->write_proc = led_proc_write;
+	ent->owner = THIS_MODULE;
+
+	if (led_type == LED_HASLCD)
+	{
+		ent = create_proc_entry("lcd", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root);
+		if (!ent) return -1;
+		ent->nlink = 1;
+		ent->data = (void *)LED_HASLCD; /* LCD */
+		ent->read_proc = led_proc_read;
+		ent->write_proc = led_proc_write;
+		ent->owner = THIS_MODULE;
+	}
+
+	return 0;
+}
+#endif
+
+/*
+   ** 
+   ** led_ASP_driver()
+   ** 
+ */
+#define	LED_DATA	0x01	/* data to shift (0:on 1:off) */
+#define	LED_STROBE	0x02	/* strobe to clock data */
+static void led_ASP_driver(unsigned char leds)
+{
+	int i;
+
+	leds = ~leds;
+	for (i = 0; i < 8; i++) {
+		unsigned char value;
+		value = (leds & 0x80) >> 7;
+		gsc_writeb( value,		 LED_DATA_REG );
+		gsc_writeb( value | LED_STROBE,	 LED_DATA_REG );
+		leds <<= 1;
+	}
+}
+
+
+/*
+   ** 
+   ** led_LASI_driver()
+   ** 
+ */
+static void led_LASI_driver(unsigned char leds)
+{
+	leds = ~leds;
+	gsc_writeb( leds, LED_DATA_REG );
+}
+
+
+/*
+   ** 
+   ** led_LCD_driver()
+   ** 
+   ** The logic of the LCD driver is, that we write at every scheduled call
+   ** only to one of LCD_CMD_REG _or_ LCD_DATA_REG - registers.
+   ** That way we don't need to let this tasklet busywait for min_cmd_delay
+   ** milliseconds.
+   **
+   ** TODO: check the value of "min_cmd_delay" against the value of HZ.
+   **   
+ */
+static void led_LCD_driver(unsigned char leds)
+{
+	static int last_index;	/* 0:heartbeat, 1:disk, 2:lan_in, 3:lan_out */
+	static int last_was_cmd;/* 0: CMD was written last, 1: DATA was last */
+	struct lcd_block *block_ptr;
+	int value;
+
+	switch (last_index) {
+	    case 0:	block_ptr = &lcd_info.heartbeat;
+			value = leds & LED_HEARTBEAT;
+			break;
+	    case 1:	block_ptr = &lcd_info.disk_io;
+			value = leds & LED_DISK_IO;
+			break;					
+	    case 2:	block_ptr = &lcd_info.lan_rcv;
+			value = leds & LED_LAN_RCV;
+			break;					
+	    case 3:	block_ptr = &lcd_info.lan_tx;
+			value = leds & LED_LAN_TX;
+			break;
+	    default:	/* should never happen: */
+			return;
+	}
+
+	if (last_was_cmd) {
+	    /* write the value to the LCD data port */
+    	    gsc_writeb( value ? block_ptr->on : block_ptr->off, LCD_DATA_REG );
+	} else {
+	    /* write the command-byte to the LCD command register */
+    	    gsc_writeb( block_ptr->command, LCD_CMD_REG );
+	}    
+	
+	/* now update the vars for the next interrupt iteration */ 
+	if (++last_was_cmd == 2) { /* switch between cmd & data */
+	    last_was_cmd = 0;
+	    if (++last_index == 4) 
+		last_index = 0;	 /* switch back to heartbeat index */
+	}
+}
+
+
+/*
+   ** 
+   ** led_get_net_stats()
+   ** 
+   ** calculate the TX- & RX-troughput on the network interfaces in
+   ** the system for usage in the LED code
+   **
+   ** (analog to dev_get_info() from net/core/dev.c)
+   **   
+ */
+static unsigned long led_net_rx_counter, led_net_tx_counter;
+
+static void led_get_net_stats(int addvalue)
+{ 
+#ifdef CONFIG_NET
+	static unsigned long rx_total_last, tx_total_last;
+	unsigned long rx_total, tx_total;
+	struct net_device *dev;
+	struct net_device_stats *stats;
+
+	rx_total = tx_total = 0;
+	
+	/* we are running as a tasklet, so locking dev_base 
+	 * for reading should be OK */
+	read_lock(&dev_base_lock);
+	for (dev = dev_base; dev != NULL; dev = dev->next) {
+	    if (dev->get_stats) { 
+	        stats = dev->get_stats(dev);
+		rx_total += stats->rx_packets;
+		tx_total += stats->tx_packets;
+	    }
+	}
+	read_unlock(&dev_base_lock);
+
+	rx_total -= rx_total_last;
+	tx_total -= tx_total_last;
+	
+	if (rx_total)
+	    led_net_rx_counter += CALC_ADD(rx_total, tx_total, addvalue);
+
+	if (tx_total)
+	    led_net_tx_counter += CALC_ADD(tx_total, rx_total, addvalue);
+        
+	rx_total_last += rx_total;
+        tx_total_last += tx_total;
+#endif
+}
+
+
+/*
+   ** 
+   ** led_get_diskio_stats()
+   ** 
+   ** calculate the disk-io througput in the system
+   ** (analog to linux/fs/proc/proc_misc.c)
+   **   
+ */
+static unsigned long led_diskio_counter;
+
+static void led_get_diskio_stats(int addvalue)
+{	
+	static unsigned int diskio_total_last, diskio_max;
+	int major, disk, total;
+	
+	total = 0;
+	for (major = 0; major < DK_MAX_MAJOR; major++) {
+	    for (disk = 0; disk < DK_MAX_DISK; disk++)
+		total += kstat.dk_drive[major][disk];
+	}
+	total -= diskio_total_last;
+	
+	if (total) {
+	    if (total >= diskio_max) {
+		led_diskio_counter += addvalue;
+	        diskio_max = total; /* new maximum value found */ 
+	    } else
+		led_diskio_counter += CALC_ADD(total, diskio_max, addvalue);
+	}
+	
+	diskio_total_last += total; 
+}
+
+
+
+/*
+   ** led_tasklet_func()
+   ** 
+   ** is scheduled at every timer interrupt from time.c and
+   ** updates the chassis LCD/LED 
+
+    TODO:
+    - display load average (older machines like 715/64 have 4 "free" LED's for that)
+    - optimizations
+ */
+
+static unsigned char currentleds;	/* stores current value of the LEDs */
+
+#define HEARTBEAT_LEN (HZ*6/100)
+#define HEARTBEAT_2ND_RANGE_START (HZ*22/100)
+#define HEARTBEAT_2ND_RANGE_END   (HEARTBEAT_2ND_RANGE_START + HEARTBEAT_LEN)
+
+static void led_tasklet_func(unsigned long unused)
+{
+	static unsigned int count, count_HZ;
+	static unsigned char lastleds;
+
+	/* exit if not initialized */
+	if (!led_func_ptr)
+	    return;
+
+	/* increment the local counters */
+	++count;
+	if (++count_HZ == HZ)
+	    count_HZ = 0;
+
+	if (led_heartbeat)
+	{
+		/* flash heartbeat-LED like a real heart (2 x short then a long delay) */
+		if (count_HZ<HEARTBEAT_LEN || 
+		    (count_HZ>=HEARTBEAT_2ND_RANGE_START && count_HZ<HEARTBEAT_2ND_RANGE_END)) 
+		    currentleds |= LED_HEARTBEAT;
+		else
+		    currentleds &= ~LED_HEARTBEAT;
+	}
+
+	/* gather network and diskio statistics and flash LEDs respectively */
+
+	if (led_lanrxtx)
+	{
+		if ((count & 31) == 0)
+			led_get_net_stats(30);
+
+		if (led_net_rx_counter) {
+			led_net_rx_counter--;
+			currentleds |= LED_LAN_RCV;
+		}
+		else    
+			currentleds &= ~LED_LAN_RCV;
+
+		if (led_net_tx_counter) {
+			led_net_tx_counter--;
+			currentleds |= LED_LAN_TX;
+		}
+		else    
+			currentleds &= ~LED_LAN_TX;
+	}
+
+	if (led_diskio)
+	{
+		/* avoid to calculate diskio-stats at same irq as netio-stats ! */
+		if ((count & 31) == 15) 
+			led_get_diskio_stats(30);
+
+		if (led_diskio_counter) {
+			led_diskio_counter--;
+			currentleds |= LED_DISK_IO;
+		}
+		else    
+			currentleds &= ~LED_DISK_IO;
+	}
+
+	/* update the LCD/LEDs */
+	if (currentleds != lastleds) {
+	    led_func_ptr(currentleds);
+	    lastleds = currentleds;
+	}
+}
+
+/* main led tasklet struct (scheduled from time.c) */
+DECLARE_TASKLET_DISABLED(led_tasklet, led_tasklet_func, 0);
+
+
+/*
+   ** led_halt()
+   ** 
+   ** called by the reboot notifier chain at shutdown and stops all
+   ** LED/LCD activities.
+   ** 
+ */
+
+static int led_halt(struct notifier_block *, unsigned long, void *);
+
+static struct notifier_block led_notifier = {
+	notifier_call: led_halt,
+};
+
+static int led_halt(struct notifier_block *nb, unsigned long event, void *buf) 
+{
+	char *txt;
+	
+	switch (event) {
+	case SYS_RESTART:	txt = "SYSTEM RESTART";
+				break;
+	case SYS_HALT:		txt = "SYSTEM HALT";
+				break;
+	case SYS_POWER_OFF:	txt = "SYSTEM POWER OFF";
+				break;
+	default:		return NOTIFY_DONE;
+	}
+	
+	/* completely stop the LED/LCD tasklet */
+	tasklet_disable(&led_tasklet);
+
+	if (lcd_info.model == DISPLAY_MODEL_LCD)
+		lcd_print(txt);
+	else
+		if (led_func_ptr)
+			led_func_ptr(0xff); /* turn all LEDs ON */
+	
+	unregister_reboot_notifier(&led_notifier);
+	return NOTIFY_OK;
+}
+
+/*
+   ** register_led_driver()
+   ** 
+   ** registers an external LED or LCD for usage by this driver.
+   ** currently only LCD-, LASI- and ASP-style LCD/LED's are supported.
+   ** 
+ */
+
+int __init register_led_driver(int model, char *cmd_reg, char *data_reg)
+{
+	static int initialized;
+	
+	if (initialized || !data_reg)
+	    return 1;
+	
+	lcd_info.model = model;		/* store the values */
+	LCD_CMD_REG = (cmd_reg == LED_CMD_REG_NONE) ? NULL : cmd_reg;
+
+	switch (lcd_info.model) {
+	case DISPLAY_MODEL_LCD:
+		LCD_DATA_REG = data_reg;
+		printk(KERN_INFO "LCD display at %p,%p registered\n", 
+			LCD_CMD_REG , LCD_DATA_REG);
+		led_func_ptr = led_LCD_driver;
+		lcd_print( "Linux " UTS_RELEASE );
+		led_type = LED_HASLCD;
+		break;
+
+	case DISPLAY_MODEL_LASI:
+		LED_DATA_REG = data_reg;
+		led_func_ptr = led_LASI_driver;
+		printk(KERN_INFO "LED display at %p registered\n", LED_DATA_REG);
+		led_type = LED_NOLCD;
+		break;
+
+	case DISPLAY_MODEL_OLD_ASP:
+		LED_DATA_REG = data_reg;
+		led_func_ptr = led_ASP_driver;
+		printk(KERN_INFO "LED (ASP-style) display at %p registered\n", 
+		    LED_DATA_REG);
+		led_type = LED_NOLCD;
+		break;
+
+	default:
+		printk(KERN_ERR "%s: Wrong LCD/LED model %d !\n",
+		       __FUNCTION__, lcd_info.model);
+		return 1;
+	}
+	
+	/* mark the LCD/LED driver now as initialized and 
+	 * register to the reboot notifier chain */
+	initialized++;
+	register_reboot_notifier(&led_notifier);
+
+	/* start the led tasklet for the first time */
+	tasklet_enable(&led_tasklet);
+	
+	return 0;
+}
+
+/*
+   ** register_led_regions()
+   ** 
+   ** register_led_regions() registers the LCD/LED regions for /procfs.
+   ** At bootup - where the initialisation of the LCD/LED normally happens - 
+   ** not all internal structures of request_region() are properly set up,
+   ** so that we delay the led-registration until after busdevices_init() 
+   ** has been executed.
+   **
+ */
+
+void __init register_led_regions(void)
+{
+	switch (lcd_info.model) {
+	case DISPLAY_MODEL_LCD:
+		request_mem_region((unsigned long)LCD_CMD_REG,  1, "lcd_cmd");
+		request_mem_region((unsigned long)LCD_DATA_REG, 1, "lcd_data");
+		break;
+	case DISPLAY_MODEL_LASI:
+	case DISPLAY_MODEL_OLD_ASP:
+		request_mem_region((unsigned long)LED_DATA_REG, 1, "led_data");
+		break;
+	}
+}
+
+
+/*
+   ** 
+   ** lcd_print()
+   ** 
+   ** Displays the given string on the LCD-Display of newer machines.
+   ** lcd_print() disables the timer-based led tasklet during its 
+   ** execution and enables it afterwards again.
+   **
+ */
+int lcd_print( char *str )
+{
+	int i;
+
+	if (!led_func_ptr || lcd_info.model != DISPLAY_MODEL_LCD)
+	    return 0;
+	
+	/* temporarily disable the led tasklet */
+	tasklet_disable(&led_tasklet);
+
+	/* copy display string to buffer for procfs */
+	strncpy(lcd_text, str, sizeof(lcd_text)-1);
+	
+	/* Set LCD Cursor to 1st character */
+	gsc_writeb(lcd_info.reset_cmd1, LCD_CMD_REG);
+	udelay(lcd_info.min_cmd_delay);
+
+	/* Print the string */
+	for (i=0; i < lcd_info.lcd_width; i++) {
+	    if (str && *str)
+		gsc_writeb(*str++, LCD_DATA_REG);
+	    else
+		gsc_writeb(' ', LCD_DATA_REG);
+	    udelay(lcd_info.min_cmd_delay);
+	}
+	
+	/* re-enable the led tasklet */
+	tasklet_enable(&led_tasklet);
+
+	return lcd_info.lcd_width;
+}
+
+/*
+   ** led_init()
+   ** 
+   ** led_init() is called very early in the bootup-process from setup.c 
+   ** and asks the PDC for an usable chassis LCD or LED.
+   ** If the PDC doesn't return any info, then the LED
+   ** is detected by lasi.c or asp.c and registered with the
+   ** above functions lasi_led_init() or asp_led_init().
+   ** KittyHawk machines have often a buggy PDC, so that
+   ** we explicitly check for those machines here.
+ */
+
+int __init led_init(void)
+{
+	struct pdc_chassis_info chassis_info;
+	int ret;
+
+	/* Work around the buggy PDC of KittyHawk-machines */
+	switch (CPU_HVERSION) {
+	case 0x580:		/* KittyHawk DC2-100 (K100) */
+	case 0x581:		/* KittyHawk DC3-120 (K210) */
+	case 0x582:		/* KittyHawk DC3 100 (K400) */
+	case 0x583:		/* KittyHawk DC3 120 (K410) */
+	case 0x58B:		/* KittyHawk DC2 100 (K200) */
+		printk(KERN_INFO "%s: KittyHawk-Machine (hversion 0x%x) found, "
+				"LED detection skipped.\n", __FILE__, CPU_HVERSION);
+		goto found;	/* use the preinitialized values of lcd_info */
+	}
+
+	/* initialize the struct, so that we can check for valid return values */
+	lcd_info.model = DISPLAY_MODEL_NONE;
+	chassis_info.actcnt = chassis_info.maxcnt = 0;
+
+	if ((ret = pdc_chassis_info(&chassis_info, &lcd_info, sizeof(lcd_info))) == PDC_OK) {
+		DPRINTK((KERN_INFO "%s: chassis info: model=%d (%s), "
+			 "lcd_width=%d, cmd_delay=%u,\n"
+			 "%s: sizecnt=%d, actcnt=%ld, maxcnt=%ld\n",
+		         __FILE__, lcd_info.model,
+			 (lcd_info.model==DISPLAY_MODEL_LCD) ? "LCD" :
+			  (lcd_info.model==DISPLAY_MODEL_LASI) ? "LED" : "unknown",
+			 lcd_info.lcd_width, lcd_info.min_cmd_delay,
+			 __FILE__, sizeof(lcd_info), 
+			 chassis_info.actcnt, chassis_info.maxcnt));
+		DPRINTK((KERN_INFO "%s: cmd=%p, data=%p, reset1=%x, reset2=%x, act_enable=%d\n",
+			__FILE__, lcd_info.lcd_cmd_reg_addr, 
+			lcd_info.lcd_data_reg_addr, lcd_info.reset_cmd1,  
+			lcd_info.reset_cmd2, lcd_info.act_enable ));
+	
+		/* check the results. Some machines have a buggy PDC */
+		if (chassis_info.actcnt <= 0 || chassis_info.actcnt != chassis_info.maxcnt)
+			goto not_found;
+
+		switch (lcd_info.model) {
+		case DISPLAY_MODEL_LCD:		/* LCD display */
+			if (chassis_info.actcnt < 
+				offsetof(struct pdc_chassis_lcd_info_ret_block, _pad)-1)
+				goto not_found;
+			if (!lcd_info.act_enable) {
+				DPRINTK((KERN_INFO "PDC prohibited usage of the LCD.\n"));
+				goto not_found;
+			}
+			break;
+
+		case DISPLAY_MODEL_NONE:	/* no LED or LCD available */
+			printk(KERN_INFO "PDC reported no LCD or LED.\n");
+			goto not_found;
+
+		case DISPLAY_MODEL_LASI:	/* Lasi style 8 bit LED display */
+			if (chassis_info.actcnt != 8 && chassis_info.actcnt != 32)
+				goto not_found;
+			break;
+
+		default:
+			printk(KERN_WARNING "PDC reported unknown LCD/LED model %d\n",
+			       lcd_info.model);
+			goto not_found;
+		} /* switch() */
+
+found:
+		/* register the LCD/LED driver */
+		register_led_driver(lcd_info.model, LCD_CMD_REG, LCD_DATA_REG);
+		return 0;
+
+	} else { /* if() */
+		DPRINTK((KERN_INFO "pdc_chassis_info call failed with retval = %d\n", ret));
+	}
+
+not_found:
+	lcd_info.model = DISPLAY_MODEL_NONE;
+	return 1;
+}
+
+#ifdef CONFIG_PROC_FS
+module_init(led_create_procfs)
+#endif
diff -Nru a/drivers/parisc/power.c b/drivers/parisc/power.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/parisc/power.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,375 @@
+/*
+ * linux/arch/parisc/kernel/power.c
+ * HP PARISC soft power switch support driver
+ *
+ * Copyright (c) 2001-2002 Helge Deller <deller@gmx.de>
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL").
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *
+ *
+ * 
+ *  HINT:
+ *  Support of the soft power switch button may be enabled or disabled at
+ *  runtime through the "/proc/sys/kernel/power" procfs entry.
+ */ 
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/proc_fs.h>
+#include <linux/ctype.h>
+#include <linux/workqueue.h>
+
+#include <asm/pdc.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/led.h>
+#include <asm/uaccess.h>
+
+
+#ifdef DEBUG
+# define DPRINTK(x) printk x
+#else
+# define DPRINTK(x) do { } while (0)
+#endif
+
+
+/* filename in /proc which can be used to enable/disable the power switch */
+#define SYSCTL_FILENAME		"sys/kernel/power"
+
+
+#define DIAG_CODE(code)		(0x14000000 + ((code)<<5))
+
+/* this will go to processor.h or any other place... */
+/* taken from PCXL ERS page 82 */
+#define MFCPU_X(rDiagReg, t_ch, t_th, code) \
+	(DIAG_CODE(code) + ((rDiagReg)<<21) + ((t_ch)<<16) + ((t_th)<<0) )
+	
+#define MTCPU(dr, gr)		MFCPU_X(dr, gr,  0, 0x12)       /* move value of gr to dr[dr] */
+#define MFCPU_C(dr, gr)		MFCPU_X(dr, gr,  0, 0x30)	/* for dr0 and dr8 only ! */
+#define MFCPU_T(dr, gr)		MFCPU_X(dr,  0, gr, 0xa0)	/* all dr except dr0 and dr8 */
+	
+#define __getDIAG(dr) ( { 			\
+        register unsigned long __res asm("r28");\
+	 __asm__ __volatile__ (			\
+		".word %1\n nop\n" : "=&r" (__res) : "i" (MFCPU_T(dr,28)) \
+	);					\
+	__res;					\
+} )
+
+
+static void deferred_poweroff(void *dummy)
+{
+	extern int cad_pid;	/* from kernel/sys.c */
+	if (kill_proc(cad_pid, SIGINT, 1)) {
+		/* just in case killing init process failed */
+		machine_power_off();
+	}
+}
+
+/*
+ * This function gets called from interrupt context.
+ * As it's called within an interrupt, it wouldn't sync if we don't
+ * use schedule_work().
+ */
+
+static DECLARE_WORK(poweroff_work, deferred_poweroff, NULL);
+
+static void poweroff(void)
+{
+	static int powering_off;
+
+	if (powering_off)
+		return;
+
+	powering_off++;
+	schedule_work(&poweroff_work);
+}
+
+
+/* local time-counter for shutdown */
+static int shutdown_timer;
+
+/* check, give feedback and start shutdown after one second */
+static void process_shutdown(void)
+{
+	if (shutdown_timer == 0)
+		DPRINTK((KERN_INFO "Shutdown requested...\n"));
+
+	shutdown_timer++;
+	
+	/* wait until the button was pressed for 1 second */
+	if (shutdown_timer == HZ) {
+		static char msg[] = "Shutting down...";
+		DPRINTK((KERN_INFO "%s\n", msg));
+#ifdef CONFIG_CHASSIS_LCD_LED
+		lcd_print(msg);
+#endif
+		poweroff();
+	}
+}
+
+
+/* main power switch tasklet struct (scheduled from time.c) */
+DECLARE_TASKLET_DISABLED(power_tasklet, NULL, 0);
+
+/* soft power switch enabled/disabled */
+#ifdef CONFIG_PROC_FS
+static int pwrsw_enabled = 1;
+#else
+#define pwrsw_enabled (1)
+#endif
+
+/*
+ * On gecko style machines (e.g. 712/xx and 715/xx) 
+ * the power switch status is stored in Bit 0 ("the highest bit")
+ * of CPU diagnose register 25.
+ * 
+ */
+static void gecko_tasklet_func(unsigned long unused)
+{
+	if (!pwrsw_enabled)
+		return;
+
+	if (__getDIAG(25) & 0x80000000) {
+		/* power switch button not pressed or released again */
+		/* Warning: Some machines do never reset this DIAG flag! */
+		shutdown_timer = 0;
+	} else {
+		process_shutdown();
+	}
+}
+
+
+
+/*
+ * Check the power switch status which is read from the
+ * real I/O location at soft_power_reg.
+ * Bit 31 ("the lowest bit) is the status of the power switch.
+ */
+
+static void polling_tasklet_func(unsigned long soft_power_reg)
+{
+        unsigned long current_status;
+	
+	if (!pwrsw_enabled)
+		return;
+
+	current_status = gsc_readl(soft_power_reg);
+	if (current_status & 0x1) {
+		/* power switch button not pressed */
+		shutdown_timer = 0;
+	} else {
+		process_shutdown();
+	}
+}
+
+
+/*
+ * powerfail interruption handler (irq IRQ_FROM_REGION(CPU_IRQ_REGION)+2) 
+ */
+#if 0
+static void powerfail_interrupt(int code, void *x, struct pt_regs *regs)
+{
+	printk(KERN_CRIT "POWERFAIL INTERRUPTION !\n");
+	poweroff();
+}
+#endif
+
+
+
+
+/* 
+ * /proc filesystem support 
+ */
+
+#ifdef CONFIG_SYSCTL
+static int power_proc_read(char *page, char **start, off_t off, int count, 
+	int *eof, void *data)
+{
+	char *out = page;
+	int len;
+
+	out += sprintf(out, "Software power switch support: ");
+	out += sprintf(out, pwrsw_enabled ? "enabled (1)" : "disabled (0)" );
+	out += sprintf(out, "\n");
+
+	len = out - page - off;
+	if (len < count) {
+		*eof = 1;
+		if (len <= 0) return 0;
+	} else {
+		len = count;
+	}
+	*start = page + off;
+	return len;
+}
+
+static int power_proc_write(struct file *file, const char *buf, 
+	unsigned long count, void *data)
+{
+	char *cur, lbuf[count];
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	memset(lbuf, 0, count);
+
+	copy_from_user(lbuf, buf, count);
+	cur = lbuf;
+
+	/* skip initial spaces */
+	while (*cur && isspace(*cur))
+		cur++;
+
+	switch (*cur) {
+	case '0':	pwrsw_enabled = 0;
+			break;
+	case '1':	pwrsw_enabled = 1;
+			break;
+	default:	printk(KERN_CRIT "/proc/" SYSCTL_FILENAME 
+					": Parse error: only '0' or '1' allowed!\n");
+			return -EINVAL;
+	} /* switch() */
+
+	return count;
+}
+
+static struct proc_dir_entry *ent;
+
+static void __init power_create_procfs(void)
+{
+	if (!power_tasklet.func)
+		return;
+	
+	ent = create_proc_entry(SYSCTL_FILENAME, S_IFREG|S_IRUGO|S_IWUSR, 0);
+	if (!ent) return;
+	
+	ent->nlink = 1;
+	ent->read_proc = power_proc_read;
+	ent->write_proc = power_proc_write;
+	ent->owner = THIS_MODULE;
+}
+
+static void __exit power_remove_procfs(void)
+{
+	remove_proc_entry(SYSCTL_FILENAME, NULL);
+}
+
+#else
+#define power_create_procfs()	do { } while (0)
+#define power_remove_procfs()	do { } while (0)
+#endif	/* CONFIG_SYSCTL */
+
+
+
+/* parisc_panic_event() is called by the panic handler.
+ * As soon as a panic occurs, our tasklets above will not be
+ * executed any longer. This function then re-enables the 
+ * soft-power switch and allows the user to switch off the system
+ */
+static int parisc_panic_event(struct notifier_block *this,
+		unsigned long event, void *ptr)
+{
+	/* re-enable the soft-power switch */
+	pdc_soft_power_button(0);
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block parisc_panic_block = {
+	notifier_call: parisc_panic_event,
+	priority: INT_MAX,
+};
+
+
+static int __init power_init(void)
+{
+	unsigned long ret;
+	unsigned long soft_power_reg = 0;
+
+#if 0
+	request_irq( IRQ_FROM_REGION(CPU_IRQ_REGION)+2, &powerfail_interrupt,
+		0, "powerfail", NULL);
+#endif
+
+	/* enable the soft power switch if possible */
+	ret = pdc_soft_power_info(&soft_power_reg);
+	if (ret == PDC_OK)
+		ret = pdc_soft_power_button(1);
+	if (ret != PDC_OK)
+		soft_power_reg = -1UL;
+	
+	switch (soft_power_reg) {
+	case 0:		printk(KERN_INFO "Gecko-style soft power switch enabled.\n");
+			power_tasklet.func = gecko_tasklet_func;
+			break;
+			
+	case -1UL:	printk(KERN_INFO "Soft power switch support not available.\n");
+			return -ENODEV;
+	
+	default:	printk(KERN_INFO "Soft power switch enabled, polling @ 0x%08lx.\n",
+				soft_power_reg);
+			power_tasklet.data = soft_power_reg;
+			power_tasklet.func = polling_tasklet_func;
+	}
+
+	/* Register a call for panic conditions. */
+	notifier_chain_register(&panic_notifier_list, &parisc_panic_block);
+
+	power_create_procfs();
+	tasklet_enable(&power_tasklet);
+
+	return 0;
+}
+
+static void __exit power_exit(void)
+{
+	if (!power_tasklet.func)
+		return;
+
+	tasklet_disable(&power_tasklet);
+	notifier_chain_unregister(&panic_notifier_list, &parisc_panic_block);
+	power_remove_procfs();
+	power_tasklet.func = NULL;
+	pdc_soft_power_button(0);
+}
+
+module_init(power_init);
+module_exit(power_exit);
+
+
+MODULE_AUTHOR("Helge Deller");
+MODULE_DESCRIPTION("Soft power switch driver");
+MODULE_LICENSE("Dual BSD/GPL");
+
+
+EXPORT_NO_SYMBOLS;
+
diff -Nru a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/parisc/sba_iommu.c	Mon Nov  4 14:31:02 2002
@@ -0,0 +1,2052 @@
+/*
+**  System Bus Adapter (SBA) I/O MMU manager
+**
+**	(c) Copyright 2000 Grant Grundler
+**	(c) Copyright 2000 Hewlett-Packard Company
+**
+**	Portions (c) 1999 Dave S. Miller (from sparc64 I/O MMU code)
+**
+**	This program is free software; you can redistribute it and/or modify
+**	it under the terms of the GNU General Public License as published by
+**      the Free Software Foundation; either version 2 of the License, or
+**      (at your option) any later version.
+**
+**
+** This module initializes the IOC (I/O Controller) found on B1000/C3000/
+** J5000/J7000/N-class/L-class machines and their successors.
+**
+** FIXME: add DMA hint support programming in both sba and lba modules.
+*/
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+
+#include <linux/mm.h>
+#include <linux/string.h>
+#undef PCI_DEBUG		/* for ASSERT */
+#include <linux/pci.h>
+#undef PCI_DEBUG
+
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/dma.h>		/* for DMA_CHUNK_SIZE */
+
+#include <asm/hardware.h>	/* for register_parisc_driver() stuff */
+
+#include <linux/proc_fs.h>
+#include <asm/runway.h>		/* for proc_runway_root */
+#include <asm/pdc.h>		/* for PDC_MODEL_* */
+
+#define MODULE_NAME "SBA"
+
+/*
+** The number of debug flags is a clue - this code is fragile.
+** Don't even think about messing with it unless you have
+** plenty of 710's to sacrifice to the computer gods. :^)
+*/
+#undef DEBUG_SBA_INIT
+#undef DEBUG_SBA_RUN
+#undef DEBUG_SBA_RUN_SG
+#undef DEBUG_SBA_RESOURCE
+#undef ASSERT_PDIR_SANITY
+#undef DEBUG_LARGE_SG_ENTRIES
+#undef DEBUG_DMB_TRAP
+
+#define SBA_INLINE	__inline__
+
+#ifdef DEBUG_SBA_INIT
+#define DBG_INIT(x...)	printk(x)
+#else
+#define DBG_INIT(x...)
+#endif
+
+#ifdef DEBUG_SBA_RUN
+#define DBG_RUN(x...)	printk(x)
+#else
+#define DBG_RUN(x...)
+#endif
+
+#ifdef DEBUG_SBA_RUN_SG
+#define DBG_RUN_SG(x...)	printk(x)
+#else
+#define DBG_RUN_SG(x...)
+#endif
+
+
+#ifdef DEBUG_SBA_RESOURCE
+#define DBG_RES(x...)	printk(x)
+#else
+#define DBG_RES(x...)
+#endif
+
+/*
+** The number of pdir entries to "free" before issueing
+** a read to PCOM register to flush out PCOM writes.
+** Interacts with allocation granularity (ie 4 or 8 entries
+** allocated and free'd/purged at a time might make this
+** less interesting).
+*/
+#define DELAYED_RESOURCE_CNT	16
+
+#define DEFAULT_DMA_HINT_REG	0
+
+#define ASTRO_RUNWAY_PORT	0x582
+#define ASTRO_ROPES_PORT	0x780
+
+#define IKE_MERCED_PORT		0x803
+#define IKE_ROPES_PORT		0x781
+
+#define REO_MERCED_PORT		0x804
+#define REO_ROPES_PORT		0x782
+
+#define REOG_MERCED_PORT	0x805
+#define REOG_ROPES_PORT		0x783
+
+#define SBA_FUNC_ID	0x0000	/* function id */
+#define SBA_FCLASS	0x0008	/* function class, bist, header, rev... */
+
+#define IS_ASTRO(id) \
+(((id)->hversion == ASTRO_RUNWAY_PORT) || ((id)->hversion == ASTRO_ROPES_PORT))
+
+#define IS_IKE(id) \
+(((id)->hversion == IKE_MERCED_PORT) || ((id)->hversion == IKE_ROPES_PORT))
+
+#define SBA_FUNC_SIZE 4096   /* SBA configuration function reg set */
+
+#define ASTRO_IOC_OFFSET 0x20000
+/* Ike's IOC's occupy functions 2 and 3 (not 0 and 1) */
+#define IKE_IOC_OFFSET(p) ((p+2)*SBA_FUNC_SIZE)
+
+#define IOC_CTRL          0x8	/* IOC_CTRL offset */
+#define IOC_CTRL_TC       (1 << 0) /* TOC Enable */
+#define IOC_CTRL_CE       (1 << 1) /* Coalesce Enable */
+#define IOC_CTRL_DE       (1 << 2) /* Dillon Enable */
+#define IOC_CTRL_RM       (1 << 8) /* Real Mode */
+#define IOC_CTRL_NC       (1 << 9) /* Non Coherent Mode */
+
+#define MAX_IOC		2	/* per Ike. Astro only has 1 */
+
+
+/*
+** Offsets into MBIB (Function 0 on Ike and hopefully Astro)
+** Firmware programs this stuff. Don't touch it.
+*/
+#define IOS_DIST_BASE	0x390
+#define IOS_DIST_MASK	0x398
+#define IOS_DIST_ROUTE	0x3A0
+
+#define IOS_DIRECT_BASE	0x3C0
+#define IOS_DIRECT_MASK	0x3C8
+#define IOS_DIRECT_ROUTE 0x3D0
+
+/*
+** Offsets into I/O TLB (Function 2 and 3 on Ike)
+*/
+#define ROPE0_CTL	0x200  /* "regbus pci0" */
+#define ROPE1_CTL	0x208
+#define ROPE2_CTL	0x210
+#define ROPE3_CTL	0x218
+#define ROPE4_CTL	0x220
+#define ROPE5_CTL	0x228
+#define ROPE6_CTL	0x230
+#define ROPE7_CTL	0x238
+
+#define HF_ENABLE	0x40
+
+
+#define IOC_IBASE	0x300	/* IO TLB */
+#define IOC_IMASK	0x308
+#define IOC_PCOM	0x310
+#define IOC_TCNFG	0x318
+#define IOC_PDIR_BASE	0x320
+
+#define IOC_IOVA_SPACE_BASE	0	/* IOVA ranges start at 0 */
+
+/*
+** IOC supports 4/8/16/64KB page sizes (see TCNFG register)
+** It's safer (avoid memory corruption) to keep DMA page mappings
+** equivalently sized to VM PAGE_SIZE.
+**
+** We really can't avoid generating a new mapping for each
+** page since the Virtual Coherence Index has to be generated
+** and updated for each page.
+**
+** IOVP_SIZE could only be greater than PAGE_SIZE if we are
+** confident the drivers really only touch the next physical
+** page iff that driver instance owns it.
+*/
+#define IOVP_SIZE	PAGE_SIZE
+#define IOVP_SHIFT	PAGE_SHIFT
+#define IOVP_MASK	PAGE_MASK
+
+#define SBA_PERF_CFG	0x708	/* Performance Counter stuff */
+#define SBA_PERF_MASK1	0x718
+#define SBA_PERF_MASK2	0x730
+
+
+/*
+** Offsets into PCI Performance Counters (functions 12 and 13)
+** Controlled by PERF registers in function 2 & 3 respectively.
+*/
+#define SBA_PERF_CNT1	0x200
+#define SBA_PERF_CNT2	0x208
+#define SBA_PERF_CNT3	0x210
+
+
+struct ioc {
+	unsigned long	ioc_hpa;	/* I/O MMU base address */
+	char	*res_map;	/* resource map, bit == pdir entry */
+	u64	*pdir_base;	/* physical base address */
+
+	unsigned long	*res_hint;	/* next avail IOVP - circular search */
+	spinlock_t	res_lock;
+	unsigned long	hint_mask_pdir;	/* bits used for DMA hints */
+	unsigned int	res_bitshift;	/* from the LEFT! */
+	unsigned int	res_size;	/* size of resource map in bytes */
+	unsigned int	hint_shift_pdir;
+#if DELAYED_RESOURCE_CNT > 0
+	int saved_cnt;
+	struct sba_dma_pair {
+		dma_addr_t	iova;
+		size_t		size;
+	} saved[DELAYED_RESOURCE_CNT];
+#endif
+
+#ifdef CONFIG_PROC_FS
+#define SBA_SEARCH_SAMPLE	0x100
+	unsigned long avg_search[SBA_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;
+#endif
+
+	/* STUFF We don't need in performance path */
+	unsigned int	pdir_size;	/* in bytes, determined by IOV Space size */
+	unsigned long	ibase;		/* pdir IOV Space base - shared w/lba_pci */
+	unsigned long	imask;		/* pdir IOV Space mask - shared w/lba_pci */
+};
+
+struct sba_device {
+	struct sba_device	*next;	/* list of SBA's in system */
+	struct parisc_device	*dev;	/* dev found in bus walk */
+	struct parisc_device_id	*iodc;	/* data about dev from firmware */
+	const char 		*name;
+	unsigned long		sba_hpa; /* base address */
+	spinlock_t		sba_lock;
+	unsigned int		flags;  /* state/functionality enabled */
+	unsigned int		hw_rev;  /* HW revision of chip */
+
+	unsigned int		num_ioc;  /* number of on-board IOC's */
+	struct ioc		ioc[MAX_IOC];
+};
+
+
+static struct sba_device *sba_list;
+
+static unsigned long ioc_needs_fdc = 0;
+
+/* Ratio of Host MEM to IOV Space size */
+static unsigned long sba_mem_ratio = 8;
+
+/* global count of IOMMUs in the system */
+static unsigned int global_ioc_cnt = 0;
+
+/* PA8700 (Piranha 2.2) bug workaround */
+static unsigned long piranha_bad_128k = 0;
+
+/* Looks nice and keeps the compiler happy */
+#define SBA_DEV(d) ((struct sba_device *) (d))
+
+
+#define ROUNDUP(x,y) ((x + ((y)-1)) & ~((y)-1))
+
+
+/************************************
+** SBA register read and write support
+**
+** BE WARNED: register writes are posted.
+**  (ie follow writes which must reach HW with a read)
+**
+** Superdome (in particular, REO) allows only 64-bit CSR accesses.
+*/
+#define READ_REG32(addr)	 le32_to_cpu(__raw_readl(addr))
+#define READ_REG64(addr)	 le64_to_cpu(__raw_readq(addr))
+#define WRITE_REG32(val, addr) __raw_writel(cpu_to_le32(val), addr)
+#define WRITE_REG64(val, addr) __raw_writeq(cpu_to_le64(val), addr)
+
+#ifdef __LP64__
+#define READ_REG(addr)		READ_REG64(addr)
+#define WRITE_REG(value, addr)	WRITE_REG64(value, addr)
+#else
+#define READ_REG(addr)		READ_REG32(addr)
+#define WRITE_REG(value, addr)	WRITE_REG32(value, addr)
+#endif
+
+#ifdef DEBUG_SBA_INIT
+
+/* NOTE: When __LP64__ isn't defined, READ_REG64() is two 32-bit reads */
+
+/**
+ * sba_dump_ranges - debugging only - print ranges assigned to this IOA
+ * @hpa: base address of the sba
+ *
+ * Print the MMIO and IO Port address ranges forwarded by an Astro/Ike/RIO
+ * IO Adapter (aka Bus Converter).
+ */
+static void
+sba_dump_ranges(unsigned long hpa)
+{
+	DBG_INIT("SBA at 0x%lx\n", hpa);
+	DBG_INIT("IOS_DIST_BASE   : %Lx\n", READ_REG64(hpa+IOS_DIST_BASE));
+	DBG_INIT("IOS_DIST_MASK   : %Lx\n", READ_REG64(hpa+IOS_DIST_MASK));
+	DBG_INIT("IOS_DIST_ROUTE  : %Lx\n", READ_REG64(hpa+IOS_DIST_ROUTE));
+	DBG_INIT("\n");
+	DBG_INIT("IOS_DIRECT_BASE : %Lx\n", READ_REG64(hpa+IOS_DIRECT_BASE));
+	DBG_INIT("IOS_DIRECT_MASK : %Lx\n", READ_REG64(hpa+IOS_DIRECT_MASK));
+	DBG_INIT("IOS_DIRECT_ROUTE: %Lx\n", READ_REG64(hpa+IOS_DIRECT_ROUTE));
+}
+
+/**
+ * sba_dump_tlb - debugging only - print IOMMU operating parameters
+ * @hpa: base address of the IOMMU
+ *
+ * Print the size/location of the IO MMU PDIR.
+ */
+static void
+sba_dump_tlb(unsigned long hpa)
+{
+	DBG_INIT("IO TLB at 0x%lx\n", hpa);
+	DBG_INIT("IOC_IBASE    : %Lx\n", READ_REG64(hpa+IOC_IBASE));
+	DBG_INIT("IOC_IMASK    : %Lx\n", READ_REG64(hpa+IOC_IMASK));
+	DBG_INIT("IOC_TCNFG    : %Lx\n", READ_REG64(hpa+IOC_TCNFG));
+	DBG_INIT("IOC_PDIR_BASE: %Lx\n", READ_REG64(hpa+IOC_PDIR_BASE));
+	DBG_INIT("\n");
+}
+#endif
+
+
+#ifdef ASSERT_PDIR_SANITY
+
+/**
+ * sba_dump_pdir_entry - debugging only - print one IOMMU PDIR entry
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @msg: text to print ont the output line.
+ * @pide: pdir index.
+ *
+ * Print one entry of the IO MMU PDIR in human readable form.
+ */
+static void
+sba_dump_pdir_entry(struct ioc *ioc, char *msg, uint pide)
+{
+	/* start printing from lowest pde in rval */
+	u64 *ptr = &(ioc->pdir_base[pide & (~0U * BITS_PER_LONG)]);
+	unsigned long *rptr = (unsigned long *) &(ioc->res_map[(pide >>3) & ~(sizeof(unsigned long) - 1)]);
+	uint rcnt;
+
+	printk(KERN_DEBUG "SBA: %s rp %p bit %d rval 0x%lx\n",
+		 msg,
+		 rptr, pide & (BITS_PER_LONG - 1), *rptr);
+
+	rcnt = 0;
+	while (rcnt < BITS_PER_LONG) {
+		printk(KERN_DEBUG "%s %2d %p %016Lx\n",
+			(rcnt == (pide & (BITS_PER_LONG - 1)))
+				? "    -->" : "       ",
+			rcnt, ptr, *ptr );
+		rcnt++;
+		ptr++;
+	}
+	printk(KERN_DEBUG "%s", msg);
+}
+
+
+/**
+ * sba_check_pdir - debugging only - consistency checker
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @msg: text to print ont the output line.
+ *
+ * Verify the resource map and pdir state is consistent
+ */
+static int
+sba_check_pdir(struct ioc *ioc, char *msg)
+{
+	u32 *rptr_end = (u32 *) &(ioc->res_map[ioc->res_size]);
+	u32 *rptr = (u32 *) ioc->res_map;	/* resource map ptr */
+	u64 *pptr = ioc->pdir_base;	/* pdir ptr */
+	uint pide = 0;
+
+	while (rptr < rptr_end) {
+		u32 rval = *rptr;
+		int rcnt = 32;	/* number of bits we might check */
+
+		while (rcnt) {
+			/* Get last byte and highest bit from that */
+			u32 pde = ((u32) (((char *)pptr)[7])) << 24;
+			if ((rval ^ pde) & 0x80000000)
+			{
+				/*
+				** BUMMER!  -- res_map != pdir --
+				** Dump rval and matching pdir entries
+				*/
+				sba_dump_pdir_entry(ioc, msg, pide);
+				return(1);
+			}
+			rcnt--;
+			rval <<= 1;	/* try the next bit */
+			pptr++;
+			pide++;
+		}
+		rptr++;	/* look at next word of res_map */
+	}
+	/* It'd be nice if we always got here :^) */
+	return 0;
+}
+
+
+/**
+ * sba_dump_sg - debugging only - print Scatter-Gather list
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @startsg: head of the SG list
+ * @nents: number of entries in SG list
+ *
+ * print the SG list so we can verify it's correct by hand.
+ */
+static void
+sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents)
+{
+	while (nents-- > 0) {
+		printk(KERN_DEBUG " %d : %08lx/%05x %p/%05x\n",
+				nents,
+				(unsigned long) sg_dma_address(startsg),
+				sg_dma_len(startsg),
+				sg_virt_addr(startsg), startsg->length);
+		startsg++;
+	}
+}
+
+#endif /* ASSERT_PDIR_SANITY */
+
+
+
+
+/**************************************************************
+*
+*   I/O Pdir Resource Management
+*
+*   Bits set in the resource map are in use.
+*   Each bit can represent a number of pages.
+*   LSbs represent lower addresses (IOVA's).
+*
+***************************************************************/
+#define PAGES_PER_RANGE 1	/* could increase this to 4 or 8 if needed */
+
+/* Convert from IOVP to IOVA and vice versa. */
+#define SBA_IOVA(ioc,iovp,offset,hint_reg) ((iovp) | (offset) | ((hint_reg)<<(ioc->hint_shift_pdir)))
+#define SBA_IOVP(ioc,iova) ((iova) & ioc->hint_mask_pdir)
+
+/* FIXME : review these macros to verify correctness and usage */
+#define PDIR_INDEX(iovp)   ((iovp)>>IOVP_SHIFT)
+#define MKIOVP(dma_hint,pide)  (dma_addr_t)((long)(dma_hint) | ((long)(pide) << IOVP_SHIFT))
+#define MKIOVA(iovp,offset) (dma_addr_t)((long)iovp | (long)offset)
+
+#define RESMAP_MASK(n)    (~0UL << (BITS_PER_LONG - (n)))
+#define RESMAP_IDX_MASK   (sizeof(unsigned long) - 1)
+
+
+/**
+ * sba_search_bitmap - find free space in IO PDIR resource bitmap
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @bits_wanted: number of entries we need.
+ *
+ * Find consecutive free bits in resource bitmap.
+ * Each bit represents one entry in the IO Pdir.
+ * Cool perf optimization: search for log2(size) bits at a time.
+ */
+static SBA_INLINE unsigned long
+sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted)
+{
+	unsigned long *res_ptr = ioc->res_hint;
+	unsigned long *res_end = (unsigned long *) &(ioc->res_map[ioc->res_size]);
+	unsigned long pide = ~0UL;
+
+	ASSERT(((unsigned long) ioc->res_hint & (sizeof(unsigned long) - 1UL)) == 0);
+	ASSERT(res_ptr < res_end);
+	if (bits_wanted > (BITS_PER_LONG/2)) {
+		/* Search word at a time - no mask needed */
+		for(; res_ptr < res_end; ++res_ptr) {
+			if (*res_ptr == 0) {
+				*res_ptr = RESMAP_MASK(bits_wanted);
+				pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map);
+				pide <<= 3;	/* convert to bit address */
+				break;
+			}
+		}
+		/* point to the next word on next pass */
+		res_ptr++;
+		ioc->res_bitshift = 0;
+	} else {
+		/*
+		** Search the resource bit map on well-aligned values.
+		** "o" is the alignment.
+		** We need the alignment to invalidate I/O TLB using
+		** SBA HW features in the unmap path.
+		*/
+		unsigned long o = 1 << get_order(bits_wanted << PAGE_SHIFT);
+		uint bitshiftcnt = ROUNDUP(ioc->res_bitshift, o);
+		unsigned long mask;
+
+		if (bitshiftcnt >= BITS_PER_LONG) {
+			bitshiftcnt = 0;
+			res_ptr++;
+		}
+		mask = RESMAP_MASK(bits_wanted) >> bitshiftcnt;
+
+		DBG_RES("%s() o %ld %p", __FUNCTION__, o, res_ptr);
+		while(res_ptr < res_end)
+		{ 
+			DBG_RES("    %p %lx %lx\n", res_ptr, mask, *res_ptr);
+			ASSERT(0 != mask);
+			if(0 == ((*res_ptr) & mask)) {
+				*res_ptr |= mask;     /* mark resources busy! */
+				pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map);
+				pide <<= 3;	/* convert to bit address */
+				pide += bitshiftcnt;
+				break;
+			}
+			mask >>= o;
+			bitshiftcnt += o;
+			if (0 == mask) {
+				mask = RESMAP_MASK(bits_wanted);
+				bitshiftcnt=0;
+				res_ptr++;
+			}
+		}
+		/* look in the same word on the next pass */
+		ioc->res_bitshift = bitshiftcnt + bits_wanted;
+	}
+
+	/* wrapped ? */
+	if (res_end <= res_ptr) {
+		ioc->res_hint = (unsigned long *) ioc->res_map;
+		ioc->res_bitshift = 0;
+	} else {
+		ioc->res_hint = res_ptr;
+	}
+	return (pide);
+}
+
+
+/**
+ * sba_alloc_range - find free bits and mark them in IO PDIR resource bitmap
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @size: number of bytes to create a mapping for
+ *
+ * Given a size, find consecutive unmarked and then mark those bits in the
+ * resource bit map.
+ */
+static int
+sba_alloc_range(struct ioc *ioc, size_t size)
+{
+	unsigned int pages_needed = size >> IOVP_SHIFT;
+#ifdef CONFIG_PROC_FS
+	unsigned long cr_start = mfctl(16);
+#endif
+	unsigned long pide;
+
+	ASSERT(pages_needed);
+	ASSERT((pages_needed * IOVP_SIZE) <= DMA_CHUNK_SIZE);
+	ASSERT(pages_needed <= BITS_PER_LONG);
+	ASSERT(0 == (size & ~IOVP_MASK));
+
+	/*
+	** "seek and ye shall find"...praying never hurts either...
+	** ggg sacrifices another 710 to the computer gods.
+	*/
+
+	pide = sba_search_bitmap(ioc, pages_needed);
+	if (pide >= (ioc->res_size << 3)) {
+		pide = sba_search_bitmap(ioc, pages_needed);
+		if (pide >= (ioc->res_size << 3))
+			panic(__FILE__ ": I/O MMU @ %lx is out of mapping resources\n", ioc->ioc_hpa);
+	}
+
+#ifdef ASSERT_PDIR_SANITY
+	/* verify the first enable bit is clear */
+	if(0x00 != ((u8 *) ioc->pdir_base)[pide*sizeof(u64) + 7]) {
+		sba_dump_pdir_entry(ioc, "sba_search_bitmap() botched it?", pide);
+	}
+#endif
+
+	DBG_RES("%s(%x) %d -> %lx hint %x/%x\n",
+		__FUNCTION__, size, pages_needed, pide,
+		(uint) ((unsigned long) ioc->res_hint - (unsigned long) ioc->res_map),
+		ioc->res_bitshift );
+
+#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 &= SBA_SEARCH_SAMPLE - 1;
+
+	ioc->used_pages += pages_needed;
+#endif
+
+	return (pide);
+}
+
+
+/**
+ * sba_free_range - unmark bits in IO PDIR resource bitmap
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @iova: IO virtual address which was previously allocated.
+ * @size: number of bytes to create a mapping for
+ *
+ * clear bits in the ioc's resource map
+ */
+static SBA_INLINE void
+sba_free_range(struct ioc *ioc, dma_addr_t iova, size_t size)
+{
+	unsigned long iovp = SBA_IOVP(ioc, iova);
+	unsigned int pide = PDIR_INDEX(iovp);
+	unsigned int ridx = pide >> 3;	/* convert bit to byte address */
+	unsigned long *res_ptr = (unsigned long *) &((ioc)->res_map[ridx & ~RESMAP_IDX_MASK]);
+
+	int bits_not_wanted = size >> IOVP_SHIFT;
+
+	/* 3-bits "bit" address plus 2 (or 3) bits for "byte" == bit in word */
+	unsigned long m = RESMAP_MASK(bits_not_wanted) >> (pide & (BITS_PER_LONG - 1));
+
+	DBG_RES("%s( ,%x,%x) %x/%lx %x %p %lx\n",
+		__FUNCTION__, (uint) iova, size,
+		bits_not_wanted, m, pide, res_ptr, *res_ptr);
+
+#ifdef CONFIG_PROC_FS
+	ioc->used_pages -= bits_not_wanted;
+#endif
+
+	ASSERT(m != 0);
+	ASSERT(bits_not_wanted);
+	ASSERT((bits_not_wanted * IOVP_SIZE) <= DMA_CHUNK_SIZE);
+	ASSERT(bits_not_wanted <= BITS_PER_LONG);
+	ASSERT((*res_ptr & m) == m); /* verify same bits are set */
+	*res_ptr &= ~m;
+}
+
+
+/**************************************************************
+*
+*   "Dynamic DMA Mapping" support (aka "Coherent I/O")
+*
+***************************************************************/
+
+#define SBA_DMA_HINT(ioc, val) ((val) << (ioc)->hint_shift_pdir)
+
+
+typedef unsigned long space_t;
+#define KERNEL_SPACE 0
+
+/**
+ * sba_io_pdir_entry - fill in one IO PDIR entry
+ * @pdir_ptr:  pointer to IO PDIR entry
+ * @sid: process Space ID
+ * @vba: Virtual CPU address of buffer to map
+ *
+ * SBA Mapping Routine
+ *
+ * Given a virtual address (vba, arg2) and space id, (sid, arg1)
+ * sba_io_pdir_entry() loads 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):
+ *
+ *  0                    19                                 51   55       63
+ * +-+---------------------+----------------------------------+----+--------+
+ * |V|        U            |            PPN[43:12]            | U  |   VI   |
+ * +-+---------------------+----------------------------------+----+--------+
+ *
+ *  V  == Valid Bit
+ *  U  == Unused
+ * PPN == Physical Page Number
+ * VI  == Virtual Index (aka Coherent Index)
+ *
+ * The physical address fields are filled with the results of the LPA
+ * instruction.  The virtual index field is filled with the results of
+ * 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.
+ *
+ * We need to pre-swap the bytes since PCX-W is Big Endian.
+ */
+
+
+void SBA_INLINE
+sba_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba)
+{
+	u64 pa; /* physical address */
+	register unsigned ci; /* coherent index */
+
+	/* We currently only support kernel addresses.
+	 * fdc instr below will need to reload sr1 with KERNEL_SPACE
+	 * once we try to support direct DMA to user space.
+	 */
+	ASSERT(sid == KERNEL_SPACE);
+
+	pa = virt_to_phys(vba);
+	pa &= ~4095ULL;			/* clear out offset bits */
+
+	mtsp(sid,1);
+	asm("lci 0(%%sr1, %1), %0" : "=r" (ci) : "r" (vba));
+	pa |= (ci >> 12) & 0xff;  /* move CI (8 bits) into lowest byte */
+
+	pa |= 0x8000000000000000ULL;	/* set "valid" bit */
+	*pdir_ptr = cpu_to_le64(pa);	/* swap and store into I/O Pdir */
+
+	/*
+	 * If the PDC_MODEL capabilities has Non-coherent IO-PDIR bit set
+	 * (bit #61, big endian), we have to flush and sync every time
+	 * IO-PDIR is changed in Ike/Astro.
+	 */
+	if (ioc_needs_fdc) {
+		asm volatile("fdc 0(%%sr1,%0)\n\tsync" : : "r" (pdir_ptr));
+	}
+}
+
+
+/**
+ * sba_mark_invalid - invalidate one or more IO PDIR entries
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @iova:  IO Virtual Address mapped earlier
+ * @byte_cnt:  number of bytes this mapping covers.
+ *
+ * Marking the IO PDIR entry(ies) as Invalid and invalidate
+ * corresponding IO TLB entry. The Ike PCOM (Purge Command Register)
+ * is to purge stale entries in the IO TLB when unmapping entries.
+ *
+ * The PCOM register supports purging of multiple pages, with a minium
+ * of 1 page and a maximum of 2GB. Hardware requires the address be
+ * aligned to the size of the range being purged. The size of the range
+ * must be a power of 2. The "Cool perf optimization" in the
+ * allocation routine helps keep that true.
+ */
+static SBA_INLINE void
+sba_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt)
+{
+	u32 iovp = (u32) SBA_IOVP(ioc,iova);
+
+	/* Even though this is a big-endian machine, the entries
+	** in the iopdir are little endian. That's why we clear the byte
+	** at +7 instead of at +0.
+	*/
+	int off = PDIR_INDEX(iovp)*sizeof(u64)+7;
+
+	/* Must be non-zero and rounded up */
+	ASSERT(byte_cnt > 0);
+	ASSERT(0 == (byte_cnt & ~IOVP_MASK));
+
+#ifdef ASSERT_PDIR_SANITY
+	/* Assert first pdir entry is set */
+	if (0x80 != (((u8 *) ioc->pdir_base)[off])) {
+		sba_dump_pdir_entry(ioc,"sba_mark_invalid()", PDIR_INDEX(iovp));
+	}
+#endif
+
+	if (byte_cnt <= IOVP_SIZE)
+	{
+		ASSERT( off < ioc->pdir_size);
+
+		iovp |= IOVP_SHIFT;     /* set "size" field for PCOM */
+
+		/*
+		** clear I/O PDIR entry "valid" bit
+		** Do NOT clear the rest - save it for debugging.
+		** We should only clear bits that have previously
+		** been enabled.
+		*/
+		((u8 *)(ioc->pdir_base))[off] = 0;
+	} else {
+		u32 t = get_order(byte_cnt) + PAGE_SHIFT;
+
+		iovp |= t;
+		ASSERT(t <= 31);   /* 2GB! Max value of "size" field */
+
+		do {
+			/* verify this pdir entry is enabled */
+			ASSERT(0x80 == (((u8 *) ioc->pdir_base)[off] & 0x80));
+			/* clear I/O Pdir entry "valid" bit first */
+			((u8 *)(ioc->pdir_base))[off] = 0;
+			off += sizeof(u64);
+			byte_cnt -= IOVP_SIZE;
+		} while (byte_cnt > 0);
+	}
+
+	WRITE_REG(iovp, ioc->ioc_hpa+IOC_PCOM);
+}
+
+/**
+ * sba_dma_supported - PCI driver can query DMA support
+ * @dev: instance of PCI owned by the driver that's asking
+ * @mask:  number of address bits this PCI device can handle
+ *
+ * See Documentation/DMA-mapping.txt
+ */
+static int
+sba_dma_supported( struct pci_dev *dev, u64 mask)
+{
+	if (dev == NULL) {
+		printk(KERN_ERR MODULE_NAME ": EISA/ISA/et al not supported\n");
+		BUG();
+		return(0);
+	}
+
+	dev->dma_mask = mask;	/* save it */
+
+	/* only support 32-bit PCI devices - no DAC support (yet) */
+	return((int) (mask == 0xffffffff));
+}
+
+
+/**
+ * sba_map_single - map one buffer and return IOVA for DMA
+ * @dev: instance of PCI owned by the driver that's asking.
+ * @addr:  driver buffer to map.
+ * @size:  number of bytes to map in driver buffer.
+ * @direction:  R/W or both.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
+static dma_addr_t
+sba_map_single(struct pci_dev *dev, void *addr, size_t size, int direction)
+{
+	struct ioc *ioc;
+	unsigned long flags; 
+	dma_addr_t iovp;
+	dma_addr_t offset;
+	u64 *pdir_start;
+	int pide;
+
+	ASSERT(size > 0);
+	ASSERT(size <= DMA_CHUNK_SIZE);
+
+	ASSERT(dev->sysdata);
+	ioc = GET_IOC(dev);
+	ASSERT(ioc);
+
+	/* save offset bits */
+	offset = ((dma_addr_t) (long) addr) & ~IOVP_MASK;
+
+	/* round up to nearest IOVP_SIZE */
+	size = (size + offset + ~IOVP_MASK) & IOVP_MASK;
+
+	spin_lock_irqsave(&ioc->res_lock, flags);
+#ifdef ASSERT_PDIR_SANITY
+	sba_check_pdir(ioc,"Check before sba_map_single()");
+#endif
+
+#ifdef CONFIG_PROC_FS
+	ioc->msingle_calls++;
+	ioc->msingle_pages += size >> IOVP_SHIFT;
+#endif
+	pide = sba_alloc_range(ioc, size);
+	iovp = (dma_addr_t) pide << IOVP_SHIFT;
+
+	DBG_RUN("%s() 0x%p -> 0x%lx",
+		__FUNCTION__, addr, (long) iovp | offset);
+
+	pdir_start = &(ioc->pdir_base[pide]);
+
+	while (size > 0) {
+		ASSERT(((u8 *)pdir_start)[7] == 0); /* verify availability */
+		sba_io_pdir_entry(pdir_start, KERNEL_SPACE, (unsigned long) addr);
+
+		DBG_RUN(" pdir 0x%p %02x%02x%02x%02x%02x%02x%02x%02x\n",
+			pdir_start,
+			(u8) (((u8 *) pdir_start)[7]),
+			(u8) (((u8 *) pdir_start)[6]),
+			(u8) (((u8 *) pdir_start)[5]),
+			(u8) (((u8 *) pdir_start)[4]),
+			(u8) (((u8 *) pdir_start)[3]),
+			(u8) (((u8 *) pdir_start)[2]),
+			(u8) (((u8 *) pdir_start)[1]),
+			(u8) (((u8 *) pdir_start)[0])
+			);
+
+		addr += IOVP_SIZE;
+		size -= IOVP_SIZE;
+		pdir_start++;
+	}
+	/* form complete address */
+#ifdef ASSERT_PDIR_SANITY
+	sba_check_pdir(ioc,"Check after sba_map_single()");
+#endif
+	spin_unlock_irqrestore(&ioc->res_lock, flags);
+	return SBA_IOVA(ioc, iovp, offset, DEFAULT_DMA_HINT_REG);
+}
+
+
+/**
+ * sba_unmap_single - unmap one IOVA and free resources
+ * @dev: instance of PCI owned by the driver that's asking.
+ * @iova:  IOVA of driver buffer previously mapped.
+ * @size:  number of bytes mapped in driver buffer.
+ * @direction:  R/W or both.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
+static void
+sba_unmap_single(struct pci_dev *dev, dma_addr_t iova, size_t size, int direction)
+{
+	struct ioc *ioc;
+#if DELAYED_RESOURCE_CNT > 0
+	struct sba_dma_pair *d;
+#endif
+	unsigned long flags; 
+	dma_addr_t offset;
+
+	ASSERT(dev->sysdata);
+	ioc = GET_IOC(dev);
+	ASSERT(ioc);
+
+	offset = iova & ~IOVP_MASK;
+
+	DBG_RUN("%s() iovp 0x%lx/%x\n",
+		__FUNCTION__, (long) iova, size);
+
+	iova ^= offset;        /* clear offset bits */
+	size += offset;
+	size = ROUNDUP(size, IOVP_SIZE);
+
+	spin_lock_irqsave(&ioc->res_lock, flags);
+
+#ifdef CONFIG_PROC_FS
+	ioc->usingle_calls++;
+	ioc->usingle_pages += size >> IOVP_SHIFT;
+#endif
+
+#if DELAYED_RESOURCE_CNT > 0
+	d = &(ioc->saved[ioc->saved_cnt]);
+	d->iova = iova;
+	d->size = size;
+	if (++(ioc->saved_cnt) >= DELAYED_RESOURCE_CNT) {
+		int cnt = ioc->saved_cnt;
+		while (cnt--) {
+			sba_mark_invalid(ioc, d->iova, d->size);
+			sba_free_range(ioc, d->iova, d->size);
+			d--;
+		}
+		ioc->saved_cnt = 0;
+		READ_REG(ioc->ioc_hpa+IOC_PCOM);	/* flush purges */
+	}
+#else /* DELAYED_RESOURCE_CNT == 0 */
+	sba_mark_invalid(ioc, iova, size);
+	sba_free_range(ioc, iova, size);
+	READ_REG(ioc->ioc_hpa+IOC_PCOM);	/* flush purges */
+#endif /* DELAYED_RESOURCE_CNT == 0 */
+	spin_unlock_irqrestore(&ioc->res_lock, flags);
+
+	/* XXX REVISIT for 2.5 Linux - need syncdma for zero-copy support.
+	** For Astro based systems this isn't a big deal WRT performance.
+	** As long as 2.4 kernels copyin/copyout data from/to userspace,
+	** we don't need the syncdma. The issue here is I/O MMU cachelines
+	** are *not* coherent in all cases.  May be hwrev dependent.
+	** Need to investigate more.
+	asm volatile("syncdma");	
+	*/
+}
+
+
+/**
+ * sba_alloc_consistent - allocate/map shared mem for DMA
+ * @hwdev: instance of PCI owned by the driver that's asking.
+ * @size:  number of bytes mapped in driver buffer.
+ * @dma_handle:  IOVA of new buffer.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
+static void *
+sba_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle)
+{
+	void *ret;
+
+	if (!hwdev) {
+		/* only support PCI */
+		*dma_handle = 0;
+		return 0;
+	}
+
+        ret = (void *) __get_free_pages(GFP_ATOMIC, get_order(size));
+
+	if (ret) {
+		memset(ret, 0, size);
+		*dma_handle = sba_map_single(hwdev, ret, size, 0);
+	}
+
+	return ret;
+}
+
+
+/**
+ * sba_free_consistent - free/unmap shared mem for DMA
+ * @hwdev: instance of PCI owned by the driver that's asking.
+ * @size:  number of bytes mapped in driver buffer.
+ * @vaddr:  virtual address IOVA of "consistent" buffer.
+ * @dma_handler:  IO virtual address of "consistent" buffer.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
+static void
+sba_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
+{
+	sba_unmap_single(hwdev, dma_handle, size, 0);
+	free_pages((unsigned long) vaddr, get_order(size));
+}
+
+
+/*
+** 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
+
+#ifdef DEBUG_LARGE_SG_ENTRIES
+int dump_run_sg = 0;
+#endif
+
+
+/**
+ * sba_fill_pdir - write allocated SG entries into IO PDIR
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @startsg:  list of IOVA/size pairs
+ * @nents: number of entries in startsg list
+ *
+ * Take preprocessed SG list and write corresponding entries
+ * in the IO PDIR.
+ */
+
+static SBA_INLINE int
+sba_fill_pdir(
+	struct ioc *ioc,
+	struct scatterlist *startsg,
+	int nents)
+{
+	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;
+
+#ifdef DEBUG_LARGE_SG_ENTRIES
+		if (dump_run_sg)
+			printk(KERN_DEBUG " %2d : %08lx/%05x %p/%05x\n",
+				nents,
+				(unsigned long) sg_dma_address(startsg), cnt,
+				sg_virt_address(startsg), startsg->length
+		);
+#else
+		DBG_RUN_SG(" %d : %08lx/%05x %p/%05x\n",
+				nents,
+				(unsigned long) sg_dma_address(startsg), cnt,
+				sg_virt_addr(startsg), startsg->length
+		);
+#endif
+		/*
+		** 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) sg_virt_addr(startsg);
+			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 {
+				sba_io_pdir_entry(pdirp, KERNEL_SPACE, vaddr);
+				vaddr += IOVP_SIZE;
+				cnt -= IOVP_SIZE;
+				pdirp++;
+			} while (cnt > 0);
+		}
+		startsg++;
+	}
+#ifdef DEBUG_LARGE_SG_ENTRIES
+	dump_run_sg = 0;
+#endif
+	return(n_mappings);
+}
+
+
+/*
+** Two address ranges are DMA contiguous *iff* "end of prev" and
+** "start of next" are both on a page boundry.
+**
+** (shift left is a quick trick to mask off upper bits)
+*/
+#define DMA_CONTIG(__X, __Y) \
+	(((((unsigned long) __X) | ((unsigned long) __Y)) << (BITS_PER_LONG - PAGE_SHIFT)) == 0UL)
+
+
+/**
+ * sba_coalesce_chunks - preprocess the SG list
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @startsg:  list of IOVA/size pairs
+ * @nents: number of entries in startsg list
+ *
+ * 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 SBA_INLINE int
+sba_coalesce_chunks( struct ioc *ioc,
+	struct scatterlist *startsg,
+	int 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) {
+		unsigned long vaddr = (unsigned long) sg_virt_addr(startsg); 
+
+		/*
+		** Prepare for first/next DMA stream
+		*/
+		dma_sg = vcontig_sg = startsg;
+		dma_len = vcontig_len = vcontig_end = startsg->length;
+		vcontig_end +=  vaddr;
+		dma_offset = vaddr & ~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 vaddr;	/* tmp */
+
+			startsg++;
+
+			/* PARANOID: clear entries */
+			sg_dma_address(startsg) = 0;
+			sg_dma_len(startsg) = 0;
+
+			/* catch brokenness in SCSI layer */
+			ASSERT(startsg->length <= DMA_CHUNK_SIZE);
+
+			/*
+			** First make sure current dma stream won't
+			** exceed DMA_CHUNK_SIZE if we coalesce the
+			** next entry.
+			*/
+			if (((dma_len + dma_offset + startsg->length + ~IOVP_MASK) & IOVP_MASK) > DMA_CHUNK_SIZE)
+				break;
+
+			/*
+			** Then look for virtually contiguous blocks.
+			** PARISC needs to associate a virtual address
+			** with each IO address mapped. The CPU cache is
+			** virtually tagged and the IOMMU uses part
+			** of the virtual address to participate in
+			** CPU cache coherency.
+			**
+			** append the next transaction?
+			*/
+			vaddr = (unsigned long) sg_virt_addr(startsg);
+			if  (vcontig_end == vaddr)
+			{
+				vcontig_len += startsg->length;
+				vcontig_end += startsg->length;
+				dma_len     += startsg->length;
+				continue;
+			}
+
+#ifdef DEBUG_LARGE_SG_ENTRIES
+			dump_run_sg = (vcontig_len > IOVP_SIZE);
+#endif
+
+			/*
+			** 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;
+
+			/*
+			** 3) do the entries end/start on page boundaries?
+			**    Don't update vcontig_end until we've checked.
+			*/
+			if (DMA_CONTIG(vcontig_end, vaddr))
+			{
+				vcontig_end = vcontig_len + vaddr;
+				dma_len += vcontig_len;
+				continue;
+			} else {
+				break;
+			}
+		}
+
+		/*
+		** End of DMA Stream
+		** Terminate last VCONTIG block.
+		** Allocate space for DMA stream.
+		*/
+		sg_dma_len(vcontig_sg) = vcontig_len;
+		dma_len = (dma_len + dma_offset + ~IOVP_MASK) & IOVP_MASK;
+		ASSERT(dma_len <= DMA_CHUNK_SIZE);
+		sg_dma_address(dma_sg) =
+			PIDE_FLAG 
+			| (sba_alloc_range(ioc, dma_len) << IOVP_SHIFT)
+			| dma_offset;
+		n_mappings++;
+	}
+
+	return n_mappings;
+}
+
+
+/**
+ * sba_map_sg - map Scatter/Gather list
+ * @dev: instance of PCI owned by the driver that's asking.
+ * @sglist:  array of buffer/length pairs
+ * @nents:  number of entries in list
+ * @direction:  R/W or both.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
+static int
+sba_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
+{
+	struct ioc *ioc;
+	int coalesced, filled = 0;
+	unsigned long flags;
+
+	DBG_RUN_SG("%s() START %d entries\n", __FUNCTION__, nents);
+
+	ASSERT(dev->sysdata);
+	ioc = GET_IOC(dev);
+	ASSERT(ioc);
+
+	/* Fast path single entry scatterlists. */
+	if (nents == 1) {
+		sg_dma_address(sglist) = sba_map_single(dev,
+						(void *)sg_virt_addr(sglist),
+						sglist->length, direction);
+		sg_dma_len(sglist)     = sglist->length;
+		return 1;
+	}
+
+	spin_lock_irqsave(&ioc->res_lock, flags);
+
+#ifdef ASSERT_PDIR_SANITY
+	if (sba_check_pdir(ioc,"Check before sba_map_sg()"))
+	{
+		sba_dump_sg(ioc, sglist, nents);
+		panic("Check before sba_map_sg()");
+	}
+#endif
+
+#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 = sba_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 = sba_fill_pdir(ioc, sglist, nents);
+
+#ifdef ASSERT_PDIR_SANITY
+	if (sba_check_pdir(ioc,"Check after sba_map_sg()"))
+	{
+		sba_dump_sg(ioc, sglist, nents);
+		panic("Check after sba_map_sg()\n");
+	}
+#endif
+
+	spin_unlock_irqrestore(&ioc->res_lock, flags);
+
+	ASSERT(coalesced == filled);
+	DBG_RUN_SG("%s() DONE %d mappings\n", __FUNCTION__, filled);
+
+	return filled;
+}
+
+
+/**
+ * sba_unmap_sg - unmap Scatter/Gather list
+ * @dev: instance of PCI owned by the driver that's asking.
+ * @sglist:  array of buffer/length pairs
+ * @nents:  number of entries in list
+ * @direction:  R/W or both.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
+static void 
+sba_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
+{
+	struct ioc *ioc;
+#ifdef ASSERT_PDIR_SANITY
+	unsigned long flags;
+#endif
+
+	DBG_RUN_SG("%s() START %d entries,  %p,%x\n",
+		__FUNCTION__, nents, sg_virt_addr(sglist), sglist->length);
+
+	ASSERT(dev->sysdata);
+	ioc = GET_IOC(dev);
+	ASSERT(ioc);
+
+#ifdef CONFIG_PROC_FS
+	ioc->usg_calls++;
+#endif
+
+#ifdef ASSERT_PDIR_SANITY
+	spin_lock_irqsave(&ioc->res_lock, flags);
+	sba_check_pdir(ioc,"Check before sba_unmap_sg()");
+	spin_unlock_irqrestore(&ioc->res_lock, flags);
+#endif
+
+	while (sg_dma_len(sglist) && nents--) {
+
+		sba_unmap_single(dev, sg_dma_address(sglist), sg_dma_len(sglist), direction);
+#ifdef CONFIG_PROC_FS
+		ioc->usg_pages += ((sg_dma_address(sglist) & ~IOVP_MASK) + sg_dma_len(sglist) + IOVP_SIZE - 1) >> PAGE_SHIFT;
+		ioc->usingle_calls--;	/* kluge since call is unmap_sg() */
+#endif
+		++sglist;
+	}
+
+	DBG_RUN_SG("%s() DONE (nents %d)\n", __FUNCTION__,  nents);
+
+#ifdef ASSERT_PDIR_SANITY
+	spin_lock_irqsave(&ioc->res_lock, flags);
+	sba_check_pdir(ioc,"Check after sba_unmap_sg()");
+	spin_unlock_irqrestore(&ioc->res_lock, flags);
+#endif
+
+}
+
+static struct pci_dma_ops sba_ops = {
+	sba_dma_supported,
+	sba_alloc_consistent,	/* allocate cacheable host mem */
+	sba_free_consistent,	/* release cacheable host mem */
+	sba_map_single,
+	sba_unmap_single,
+	sba_map_sg,
+	sba_unmap_sg,
+	NULL,			/* dma_sync_single */
+	NULL			/* dma_sync_sg */
+};
+
+
+/**************************************************************************
+**
+**   SBA PAT PDC support
+**
+**   o call pdc_pat_cell_module()
+**   o store ranges in PCI "resource" structures
+**
+**************************************************************************/
+
+static void
+sba_get_pat_resources(struct sba_device *sba_dev)
+{
+#if 0
+/*
+** TODO/REVISIT/FIXME: support for directed ranges requires calls to
+**      PAT PDC to program the SBA/LBA directed range registers...this
+**      burden may fall on the LBA code since it directly supports the
+**      PCI subsystem. It's not clear yet. - ggg
+*/
+PAT_MOD(mod)->mod_info.mod_pages   = PAT_GET_MOD_PAGES(temp);
+	FIXME : ???
+PAT_MOD(mod)->mod_info.dvi         = PAT_GET_DVI(temp);
+	Tells where the dvi bits are located in the address.
+PAT_MOD(mod)->mod_info.ioc         = PAT_GET_IOC(temp);
+	FIXME : ???
+#endif
+}
+
+
+/**************************************************************
+*
+*   Initialization and claim
+*
+***************************************************************/
+#define PIRANHA_ADDR_MASK	0x00160000UL /* bit 17,18,20 */
+#define PIRANHA_ADDR_VAL	0x00060000UL /* bit 17,18 on */
+static void *
+sba_alloc_pdir(unsigned int pdir_size)
+{
+        unsigned long pdir_base;
+	unsigned long pdir_order = get_order(pdir_size);
+
+	pdir_base = __get_free_pages(GFP_KERNEL, pdir_order);
+	if (NULL == (void *) pdir_base)
+		panic("sba_ioc_init() could not allocate I/O Page Table\n");
+
+	/* If this is not PA8700 (PCX-W2)
+	**	OR newer than ver 2.2
+	**	OR in a system that doesn't need VINDEX bits from SBA,
+	**
+	** then we aren't exposed to the HW bug.
+	*/
+	if ( ((boot_cpu_data.pdc.cpuid >> 5) & 0x7f) != 0x13
+			|| (boot_cpu_data.pdc.versions > 0x202)
+			|| (boot_cpu_data.pdc.capabilities & 0x08L) )
+		return (void *) pdir_base;
+
+	/*
+	 * PA8700 (PCX-W2, aka piranha) silent data corruption fix
+	 *
+	 * An interaction between PA8700 CPU (Ver 2.2 or older) and
+	 * Ike/Astro can cause silent data corruption. This is only
+	 * a problem if the I/O PDIR is located in memory such that
+	 * (little-endian)  bits 17 and 18 are on and bit 20 is off.
+	 *
+	 * Since the max IO Pdir size is 2MB, by cleverly allocating the
+	 * right physical address, we can either avoid (IOPDIR <= 1MB)
+	 * or minimize (2MB IO Pdir) the problem if we restrict the
+	 * IO Pdir to a maximum size of 2MB-128K (1902K).
+	 *
+	 * Because we always allocate 2^N sized IO pdirs, either of the
+	 * "bad" regions will be the last 128K if at all. That's easy
+	 * to test for.
+	 * 
+	 */
+	if (pdir_order <= (19-12)) {
+		if (((virt_to_phys(pdir_base)+pdir_size-1) & PIRANHA_ADDR_MASK) == PIRANHA_ADDR_VAL) {
+			/* allocate a new one on 512k alignment */
+			unsigned long new_pdir = __get_free_pages(GFP_KERNEL, (19-12));
+			/* release original */
+			free_pages(pdir_base, pdir_order);
+
+			pdir_base = new_pdir;
+
+			/* release excess */
+			while (pdir_order < (19-12)) {
+				new_pdir += pdir_size;
+				free_pages(new_pdir, pdir_order);
+				pdir_order +=1;
+				pdir_size <<=1;
+			}
+		}
+	} else {
+		/*
+		** 1MB or 2MB Pdir
+		** Needs to be aligned on an "odd" 1MB boundary.
+		*/
+		unsigned long new_pdir = __get_free_pages(GFP_KERNEL, pdir_order+1); /* 2 or 4MB */
+
+		/* release original */
+		free_pages( pdir_base, pdir_order);
+
+		/* release first 1MB */
+		free_pages(new_pdir, 20-12);
+
+		pdir_base = new_pdir + 1024*1024;
+
+		if (pdir_order > (20-12)) {
+			/*
+			** 2MB Pdir.
+			**
+			** Flag tells init_bitmap() to mark bad 128k as used
+			** and to reduce the size by 128k.
+			*/
+			piranha_bad_128k = 1;
+
+			new_pdir += 3*1024*1024;
+			/* release last 1MB */
+			free_pages(new_pdir, 20-12);
+
+			/* release unusable 128KB */
+			free_pages(new_pdir - 128*1024 , 17-12);
+
+			pdir_size -= 128*1024;
+		}
+	}
+
+	memset((void *) pdir_base, 0, pdir_size);
+	return (void *) pdir_base;
+}
+
+
+static void
+sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
+{
+	/* lba_set_iregs() is in arch/parisc/kernel/lba_pci.c */
+	extern void lba_set_iregs(struct parisc_device *, u32, u32);
+
+	u32 iova_space_size, iova_space_mask;
+	int pdir_size, iov_order;
+	unsigned long physmem;
+	struct parisc_device *lba;
+
+	/*
+	** Determine IOVA Space size from memory size.
+	**
+	** Ideally, PCI drivers would register the maximum number
+	** of DMA they can have outstanding for each device they
+	** own.  Next best thing would be to guess how much DMA
+	** can be outstanding based on PCI Class/sub-class. Both
+	** methods still require some "extra" to support PCI
+	** Hot-Plug/Removal of PCI cards. (aka PCI OLARD).
+	**
+	** While we have 32-bits "IOVA" space, top two 2 bits are used
+	** for DMA hints - ergo only 30 bits max.
+	*/
+
+	physmem = num_physpages << PAGE_SHIFT;
+	iova_space_size = (u32) (physmem/(sba_mem_ratio*global_ioc_cnt));
+
+	/* limit IOVA space size to 1MB-1GB */
+	if (iova_space_size < 1024*1024) {
+		iova_space_size = 1024*1024;
+	}
+#ifdef __LP64__
+	else if (iova_space_size > 512*1024*1024) {
+		iova_space_size = 512*1024*1024;
+	}
+#endif
+
+	/*
+	** iova space must be log2() in size.
+	** thus, pdir/res_map will also be log2().
+	** PIRANHA BUG: Exception is when IO Pdir is 2MB (gets reduced)
+	*/
+	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);
+
+	ioc->pdir_size = pdir_size = (iova_space_size/IOVP_SIZE) * sizeof(u64);
+
+	ASSERT(pdir_size < 4*1024*1024);   /* max pdir size == 2MB */
+
+	/* Verify it's a power of two */
+	ASSERT((1 << get_order(pdir_size)) == (pdir_size >> PAGE_SHIFT));
+
+	DBG_INIT("%s() hpa 0x%lx mem %dMB IOV %dMB (%d bits) PDIR size 0x%0x\n",
+		__FUNCTION__, ioc->ioc_hpa, (int) (physmem>>20),
+		iova_space_size>>20, iov_order + PAGE_SHIFT, pdir_size);
+
+	/* FIXME : DMA HINTs not used */
+	ioc->hint_shift_pdir = iov_order + PAGE_SHIFT;
+	ioc->hint_mask_pdir = ~(0x3 << (iov_order + PAGE_SHIFT));
+
+	ioc->pdir_base = sba_alloc_pdir(pdir_size);
+
+	DBG_INIT("%s() pdir %p size %x hint_shift_pdir %x hint_mask_pdir %lx\n",
+		__FUNCTION__, ioc->pdir_base, pdir_size,
+		ioc->hint_shift_pdir, ioc->hint_mask_pdir);
+
+	ASSERT((((unsigned long) ioc->pdir_base) & PAGE_MASK) == (unsigned long) ioc->pdir_base);
+	WRITE_REG64(virt_to_phys(ioc->pdir_base), ioc->ioc_hpa + IOC_PDIR_BASE);
+
+	/* build IMASK for IOC and Elroy */
+	iova_space_mask =  0xffffffff;
+	iova_space_mask <<= (iov_order + PAGE_SHIFT);
+
+	/*
+	** On C3000 w/512MB mem, HP-UX 10.20 reports:
+	**     ibase=0, imask=0xFE000000, size=0x2000000.
+	*/
+	ioc->ibase = IOC_IOVA_SPACE_BASE | 1;	/* bit 0 == enable bit */
+	ioc->imask = iova_space_mask;	/* save it */
+
+	DBG_INIT("%s() IOV base 0x%lx mask 0x%0lx\n",
+		__FUNCTION__, ioc->ibase, ioc->imask);
+
+	/*
+	** FIXME: Hint registers are programmed with default hint
+	** values during boot, so hints should be sane even if we
+	** can't reprogram them the way drivers want.
+	*/
+
+	/*
+	** setup Elroy IBASE/IMASK registers as well.
+	*/
+	for (lba = sba->child; lba; lba = lba->sibling) {
+		int rope_num = (lba->hpa >> 13) & 0xf;
+		if (rope_num >> 3 == ioc_num)
+			lba_set_iregs(lba, ioc->ibase, ioc->imask);
+	}
+
+	/*
+	** Program the IOC's ibase and enable IOVA translation
+	*/
+	WRITE_REG(ioc->ibase, ioc->ioc_hpa+IOC_IBASE);
+	WRITE_REG(ioc->imask, ioc->ioc_hpa+IOC_IMASK);
+
+	/* Set I/O PDIR Page size to 4K */
+	WRITE_REG(0, ioc->ioc_hpa+IOC_TCNFG);
+
+	/*
+	** Clear I/O TLB of any possible entries.
+	** (Yes. This is a bit paranoid...but so what)
+	*/
+	WRITE_REG(0 | 31, ioc->ioc_hpa+IOC_PCOM);
+
+	DBG_INIT("%s() DONE\n", __FUNCTION__);
+}
+
+
+
+/**************************************************************************
+**
+**   SBA initialization code (HW and SW)
+**
+**   o identify SBA chip itself
+**   o initialize SBA chip modes (HardFail)
+**   o initialize SBA chip modes (HardFail)
+**   o FIXME: initialize DMA hints for reasonable defaults
+**
+**************************************************************************/
+
+static void
+sba_hw_init(struct sba_device *sba_dev)
+{ 
+	int i;
+	int num_ioc;
+	u64 ioc_ctl;
+
+	ioc_ctl = READ_REG(sba_dev->sba_hpa+IOC_CTRL);
+	DBG_INIT("%s() hpa 0x%lx ioc_ctl 0x%Lx ->",
+		__FUNCTION__, sba_dev->sba_hpa, ioc_ctl);
+	ioc_ctl &= ~(IOC_CTRL_RM | IOC_CTRL_NC | IOC_CTRL_CE);
+	ioc_ctl |= IOC_CTRL_TC;	/* Astro: firmware enables this */
+
+	WRITE_REG(ioc_ctl, sba_dev->sba_hpa+IOC_CTRL);
+
+#ifdef DEBUG_SBA_INIT
+	ioc_ctl = READ_REG64(sba_dev->sba_hpa+IOC_CTRL);
+	DBG_INIT(" 0x%Lx\n", ioc_ctl);
+#endif
+
+	if (IS_ASTRO(sba_dev->iodc)) {
+		/* PAT_PDC (L-class) also reports the same goofy base */
+		sba_dev->ioc[0].ioc_hpa = ASTRO_IOC_OFFSET;
+		num_ioc = 1;
+	} else {
+		sba_dev->ioc[0].ioc_hpa = sba_dev->ioc[1].ioc_hpa = 0;
+		num_ioc = 2;
+	}
+
+	sba_dev->num_ioc = num_ioc;
+	for (i = 0; i < num_ioc; i++) {
+		sba_dev->ioc[i].ioc_hpa += sba_dev->sba_hpa + IKE_IOC_OFFSET(i);
+
+		/*
+		** Make sure the box crashes if we get any errors on a rope.
+		*/
+		WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE0_CTL);
+		WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE1_CTL);
+		WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE2_CTL);
+		WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE3_CTL);
+		WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE4_CTL);
+		WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE5_CTL);
+		WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE6_CTL);
+		WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE7_CTL);
+
+		/* flush out the writes */
+		READ_REG(sba_dev->ioc[i].ioc_hpa + ROPE7_CTL);
+
+		sba_ioc_init(sba_dev->dev, &(sba_dev->ioc[i]), i);
+	}
+}
+
+static void
+sba_common_init(struct sba_device *sba_dev)
+{
+	int i;
+
+	/* add this one to the head of the list (order doesn't matter)
+	** This will be useful for debugging - especially if we get coredumps
+	*/
+	sba_dev->next = sba_list;
+	sba_list = sba_dev;
+
+	for(i=0; i< sba_dev->num_ioc; i++) {
+		int res_size;
+#ifdef DEBUG_DMB_TRAP
+		extern void iterate_pages(unsigned long , unsigned long ,
+					  void (*)(pte_t * , unsigned long),
+					  unsigned long );
+		void set_data_memory_break(pte_t * , unsigned long);
+#endif
+		/* resource map size dictated by pdir_size */
+		res_size = sba_dev->ioc[i].pdir_size/sizeof(u64); /* entries */
+
+		/* Second part of PIRANHA BUG */
+		if (piranha_bad_128k) {
+			res_size -= (128*1024)/sizeof(u64);
+		}
+
+		res_size >>= 3;  /* convert bit count to byte count */
+		DBG_INIT("%s() res_size 0x%x\n",
+			__FUNCTION__, res_size);
+
+		sba_dev->ioc[i].res_size = res_size;
+		sba_dev->ioc[i].res_map = (char *) __get_free_pages(GFP_KERNEL, get_order(res_size));
+
+#ifdef DEBUG_DMB_TRAP
+		iterate_pages( sba_dev->ioc[i].res_map, res_size,
+				set_data_memory_break, 0);
+#endif
+
+		if (NULL == sba_dev->ioc[i].res_map)
+		{
+			panic(__FILE__ ":%s() could not allocate resource map\n", __FUNCTION__ );
+		}
+
+		memset(sba_dev->ioc[i].res_map, 0, res_size);
+		/* next available IOVP - circular search */
+		sba_dev->ioc[i].res_hint = (unsigned long *)
+				&(sba_dev->ioc[i].res_map[L1_CACHE_BYTES]);
+
+#ifdef ASSERT_PDIR_SANITY
+		/* Mark first bit busy - ie no IOVA 0 */
+		sba_dev->ioc[i].res_map[0] = 0x80;
+		sba_dev->ioc[i].pdir_base[0] = 0xeeffc0addbba0080ULL;
+#endif
+
+		/* Third (and last) part of PIRANHA BUG */
+		if (piranha_bad_128k) {
+			/* region from +1408K to +1536 is un-usable. */
+
+			int idx_start = (1408*1024/sizeof(u64)) >> 3;
+			int idx_end   = (1536*1024/sizeof(u64)) >> 3;
+			long *p_start = (long *) &(sba_dev->ioc[i].res_map[idx_start]);
+			long *p_end   = (long *) &(sba_dev->ioc[i].res_map[idx_end]);
+
+			/* mark that part of the io pdir busy */
+			while (p_start < p_end)
+				*p_start++ = -1;
+				
+		}
+
+#ifdef DEBUG_DMB_TRAP
+		iterate_pages( sba_dev->ioc[i].res_map, res_size,
+				set_data_memory_break, 0);
+		iterate_pages( sba_dev->ioc[i].pdir_base, sba_dev->ioc[i].pdir_size,
+				set_data_memory_break, 0);
+#endif
+
+		DBG_INIT("%s() %d res_map %x %p\n",
+			__FUNCTION__, i, res_size, sba_dev->ioc[i].res_map);
+	}
+
+	sba_dev->sba_lock = SPIN_LOCK_UNLOCKED;
+	ioc_needs_fdc = boot_cpu_data.pdc.capabilities & PDC_MODEL_IOPDIR_FDC;
+
+#ifdef DEBUG_SBA_INIT
+	/*
+	 * If the PDC_MODEL capabilities has Non-coherent IO-PDIR bit set
+	 * (bit #61, big endian), we have to flush and sync every time
+	 * IO-PDIR is changed in Ike/Astro.
+	 */
+	if (boot_cpu_data.pdc.capabilities & PDC_MODEL_IOPDIR_FDC) {
+		printk(KERN_INFO MODULE_NAME " FDC/SYNC required.\n");
+	} else {
+		printk(KERN_INFO MODULE_NAME " IOC has cache coherent PDIR.\n");
+	}
+#endif
+}
+
+#ifdef CONFIG_PROC_FS
+static int sba_proc_info(char *buf, char **start, off_t offset, int len)
+{
+	struct sba_device *sba_dev = sba_list;
+	struct ioc *ioc = &sba_dev->ioc[0];	/* FIXME: Multi-IOC support! */
+	int total_pages = (int) (ioc->res_size << 3); /* 8 bits per byte */
+	unsigned long i = 0, avg = 0, min, max;
+
+	sprintf(buf, "%s rev %d.%d\n",
+		sba_dev->name,
+		(sba_dev->hw_rev & 0x7) + 1,
+		(sba_dev->hw_rev & 0x18) >> 3
+		);
+	sprintf(buf, "%sIO PDIR size    : %d bytes (%d entries)\n",
+		buf,
+		(int) ((ioc->res_size << 3) * sizeof(u64)), /* 8 bits/byte */
+		total_pages);
+
+	sprintf(buf, "%sIO PDIR entries : %ld free  %ld used (%d%%)\n", buf,
+		total_pages - ioc->used_pages, ioc->used_pages,
+		(int) (ioc->used_pages * 100 / total_pages));
+	
+	sprintf(buf, "%sResource bitmap : %d bytes (%d pages)\n", 
+		buf, ioc->res_size, ioc->res_size << 3);   /* 8 bits per byte */
+
+	min = max = ioc->avg_search[0];
+	for (i = 0; i < SBA_SEARCH_SAMPLE; i++) {
+		avg += ioc->avg_search[i];
+		if (ioc->avg_search[i] > max) max = ioc->avg_search[i];
+		if (ioc->avg_search[i] < min) min = ioc->avg_search[i];
+	}
+	avg /= SBA_SEARCH_SAMPLE;
+	sprintf(buf, "%s  Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n",
+		buf, min, avg, max);
+
+	sprintf(buf, "%spci_map_single(): %12ld calls  %12ld pages (avg %d/1000)\n",
+		buf, ioc->msingle_calls, ioc->msingle_pages,
+		(int) ((ioc->msingle_pages * 1000)/ioc->msingle_calls));
+
+	/* KLUGE - unmap_sg calls unmap_single for each mapped page */
+	min = ioc->usingle_calls;
+	max = ioc->usingle_pages - ioc->usg_pages;
+	sprintf(buf, "%spci_unmap_single: %12ld calls  %12ld pages (avg %d/1000)\n",
+		buf, min, max,
+		(int) ((max * 1000)/min));
+
+	sprintf(buf, "%spci_map_sg()    : %12ld calls  %12ld pages (avg %d/1000)\n",
+		buf, ioc->msg_calls, ioc->msg_pages,
+		(int) ((ioc->msg_pages * 1000)/ioc->msg_calls));
+
+	sprintf(buf, "%spci_unmap_sg()  : %12ld calls  %12ld pages (avg %d/1000)\n",
+		buf, ioc->usg_calls, ioc->usg_pages,
+		(int) ((ioc->usg_pages * 1000)/ioc->usg_calls));
+
+	return strlen(buf);
+}
+
+#if 0
+/* XXX too much output - exceeds 4k limit and needs to be re-written */
+static int
+sba_resource_map(char *buf, char **start, off_t offset, int len)
+{
+	struct sba_device *sba_dev = sba_list;
+	struct ioc *ioc = &sba_dev->ioc[0];	/* FIXME: Mutli-IOC suppoer! */
+	unsigned int *res_ptr = (unsigned int *)ioc->res_map;
+	int i;
+
+	buf[0] = '\0';
+	for(i = 0; i < (ioc->res_size / sizeof(unsigned int)); ++i, ++res_ptr) {
+		if ((i & 7) == 0)
+		    strcat(buf,"\n   ");
+		sprintf(buf, "%s %08x", buf, *res_ptr);
+	}
+	strcat(buf, "\n");
+
+	return strlen(buf);
+}
+#endif /* 0 */
+#endif /* CONFIG_PROC_FS */
+
+static struct parisc_device_id sba_tbl[] = {
+	{ HPHW_IOA, HVERSION_REV_ANY_ID, ASTRO_RUNWAY_PORT, 0xb },
+	{ HPHW_BCPORT, HVERSION_REV_ANY_ID, IKE_MERCED_PORT, 0xc },
+	{ HPHW_BCPORT, HVERSION_REV_ANY_ID, REO_MERCED_PORT, 0xc },
+	{ HPHW_BCPORT, HVERSION_REV_ANY_ID, REOG_MERCED_PORT, 0xc },
+/* These two entries commented out because we don't find them in a
+ * buswalk yet.  If/when we do, they would cause us to think we had
+ * many more SBAs then we really do.
+ *	{ HPHW_BCPORT, HVERSION_REV_ANY_ID, ASTRO_ROPES_PORT, 0xc },
+ *	{ HPHW_BCPORT, HVERSION_REV_ANY_ID, IKE_ROPES_PORT, 0xc },
+ */
+	{ 0, }
+};
+
+int sba_driver_callback(struct parisc_device *);
+
+static struct parisc_driver sba_driver = {
+	name:		MODULE_NAME,
+	id_table:	sba_tbl,
+	probe:		sba_driver_callback,
+};
+
+/*
+** Determine if lba 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.
+*/
+int
+sba_driver_callback(struct parisc_device *dev)
+{
+	struct sba_device *sba_dev;
+	u32 func_class;
+	int i;
+	char *version;
+
+#ifdef DEBUG_SBA_INIT
+	sba_dump_ranges(dev->hpa);
+#endif
+
+	/* Read HW Rev First */
+	func_class = READ_REG(dev->hpa + SBA_FCLASS);
+
+	if (IS_ASTRO(&dev->id)) {
+		unsigned long fclass;
+		static char astro_rev[]="Astro ?.?";
+
+		/* Astro is broken...Read HW Rev First */
+		fclass = READ_REG(dev->hpa);
+
+		astro_rev[6] = '1' + (char) (fclass & 0x7);
+		astro_rev[8] = '0' + (char) ((fclass & 0x18) >> 3);
+		version = astro_rev;
+
+	} else if (IS_IKE(&dev->id)) {
+		static char ike_rev[]="Ike rev ?";
+
+		ike_rev[8] = '0' + (char) (func_class & 0xff);
+		version = ike_rev;
+	} else {
+		static char reo_rev[]="REO rev ?";
+
+		reo_rev[8] = '0' + (char) (func_class & 0xff);
+		version = reo_rev;
+	}
+
+	if (!global_ioc_cnt) {
+		global_ioc_cnt = count_parisc_driver(&sba_driver);
+
+		/* Only Astro has one IOC per SBA */
+		if (!IS_ASTRO(&dev->id))
+			global_ioc_cnt *= 2;
+	}
+
+	printk(KERN_INFO "%s found %s at 0x%lx\n",
+		MODULE_NAME, version, dev->hpa);
+
+#ifdef DEBUG_SBA_INIT
+	sba_dump_tlb(dev->hpa);
+#endif
+
+	sba_dev = kmalloc(sizeof(struct sba_device), GFP_KERNEL);
+	if (NULL == sba_dev) {
+		printk(KERN_ERR MODULE_NAME " - couldn't alloc sba_device\n");
+		return(1);
+	}
+
+	dev->sysdata = (void *) sba_dev;
+	memset(sba_dev, 0, sizeof(struct sba_device));
+
+	for(i=0; i<MAX_IOC; i++)
+		spin_lock_init(&(sba_dev->ioc[i].res_lock));
+
+	sba_dev->dev = dev;
+	sba_dev->hw_rev = func_class;
+	sba_dev->iodc = &dev->id;
+	sba_dev->name = dev->name;
+	sba_dev->sba_hpa = dev->hpa;  /* faster access */
+
+	sba_get_pat_resources(sba_dev);
+	sba_hw_init(sba_dev);
+	sba_common_init(sba_dev);
+
+	hppa_dma_ops = &sba_ops;
+
+#ifdef CONFIG_PROC_FS
+	if (IS_ASTRO(&dev->id)) {
+		create_proc_info_entry("Astro", 0, proc_runway_root, sba_proc_info);
+	} else if (IS_IKE(&dev->id)) {
+		create_proc_info_entry("Ike", 0, proc_runway_root, sba_proc_info);
+	} else {
+		create_proc_info_entry("Reo", 0, proc_runway_root, sba_proc_info);
+	}
+#if 0
+	create_proc_info_entry("bitmap", 0, proc_runway_root, sba_resource_map);
+#endif
+#endif
+	return 0;
+}
+
+/*
+** One time initialization to let the world know the SBA was found.
+** This is the only routine which is NOT static.
+** Must be called exactly once before pci_init().
+*/
+void __init sba_init(void)
+{
+	register_parisc_driver(&sba_driver);
+}
+
+
+/**
+ * sba_get_iommu - Assign the iommu pointer for the pci bus controller.
+ * @dev: The parisc device.
+ *
+ * This function searches through the registerd IOMMU's and returns the
+ * appropriate IOMMU data for the given parisc PCI controller.
+ */
+void * sba_get_iommu(struct parisc_device *pci_hba)
+{
+	struct sba_device *sba = (struct sba_device *) pci_hba->parent->sysdata;
+	char t = pci_hba->parent->id.hw_type;
+	int iocnum = (pci_hba->hw_path >> 3);	/* rope # */
+
+	if ((t!=HPHW_IOA) && (t!=HPHW_BCPORT))
+		BUG();
+
+	return &(sba->ioc[iocnum]);
+}
diff -Nru a/drivers/parisc/superio.c b/drivers/parisc/superio.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/parisc/superio.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,542 @@
+/*      National Semiconductor NS87560UBD Super I/O controller used in
+ *      HP [BCJ]x000 workstations.
+ *
+ *      This chip is a horrid piece of engineering, and National
+ *      denies any knowledge of its existence. Thus no datasheet is
+ *      available off www.national.com. 
+ *
+ *	(C) Copyright 2000 Linuxcare, Inc.
+ * 	(C) Copyright 2000 Linuxcare Canada, Inc.
+ *	(C) Copyright 2000 Martin K. Petersen <mkp@linuxcare.com>
+ * 	(C) Copyright 2000 Alex deVries <alex@linuxcare.com>
+ *      (C) Copyright 2001 John Marvin <jsm@fc.hp.com>
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License as
+ *	published by the Free Software Foundation; either version 2 of
+ *	the License, or (at your option) any later version.  
+ *
+ *	The initial version of this is by Martin Peterson.  Alex deVries
+ *	has spent a bit of time trying to coax it into working.
+ *
+ *      Major changes to get basic interrupt infrastructure working to
+ *      hopefully be able to support all SuperIO devices. Currently
+ *      works with serial. -- John Marvin <jsm@fc.hp.com>
+ */
+
+
+/* NOTES:
+ * 
+ * Function 0 is an IDE controller. It is identical to a PC87415 IDE
+ * controller (and identifies itself as such).
+ *
+ * Function 1 is a "Legacy I/O" controller. Under this function is a
+ * whole mess of legacy I/O peripherals. Of course, HP hasn't enabled
+ * all the functionality in hardware, but the following is available:
+ *
+ *      Two 16550A compatible serial controllers
+ *      An IEEE 1284 compatible parallel port
+ *      A floppy disk controller
+ *
+ * Function 2 is a USB controller.
+ *
+ * We must be incredibly careful during initialization.  Since all
+ * interrupts are routed through function 1 (which is not allowed by
+ * the PCI spec), we need to program the PICs on the legacy I/O port
+ * *before* we attempt to set up IDE and USB.  @#$!&
+ *
+ * According to HP, devices are only enabled by firmware if they have
+ * a physical device connected.
+ *
+ * Configuration register bits:
+ *     0x5A: FDC, SP1, IDE1, SP2, IDE2, PAR, Reserved, P92
+ *     0x5B: RTC, 8259, 8254, DMA1, DMA2, KBC, P61, APM
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/serial.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/parport.h>
+#include <linux/parport_pc.h>
+#include <linux/serial_reg.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/superio.h>
+
+static struct superio_device sio_dev = {
+	iosapic_irq: -1
+};
+
+
+#undef DEBUG_INIT
+
+void
+superio_inform_irq(int irq)
+{
+    if (sio_dev.iosapic_irq != -1) {
+	printk(KERN_ERR "SuperIO: superio_inform_irq called twice! (more than one SuperIO?)\n");
+	BUG();
+	return;
+    }
+
+    sio_dev.iosapic_irq = irq;
+}
+
+static void
+superio_interrupt(int irq, void *devp, struct pt_regs *regs)
+{
+	struct superio_device *sio = (struct superio_device *)devp;
+	u8 results;
+	u8 local_irq;
+
+	/* Poll the 8259 to see if there's an interrupt. */
+	outb (OCW3_POLL,IC_PIC1+0);
+
+	results = inb(IC_PIC1+0);
+
+	if ((results & 0x80) == 0) {
+#ifndef CONFIG_SMP
+		/* HACK: need to investigate why this happens if SMP enabled */
+		BUG(); /* This shouldn't happen */
+#endif
+		return;
+	}
+
+	/* Check to see which device is interrupting */
+
+	local_irq = results & 0x0f;
+
+	if (local_irq == 2 || local_irq > 7) {
+		printk(KERN_ERR "SuperIO: slave interrupted!\n");
+		BUG();
+		return;
+	}
+
+	if (local_irq == 7) {
+
+		/* Could be spurious. Check in service bits */
+
+		outb(OCW3_ISR,IC_PIC1+0);
+		results = inb(IC_PIC1+0);
+		if ((results & 0x80) == 0) { /* if ISR7 not set: spurious */
+			printk(KERN_WARNING "SuperIO: spurious interrupt!\n");
+			return;
+		}
+	}
+
+	/* Call the appropriate device's interrupt */
+
+	do_irq(&sio->irq_region->action[local_irq],
+		sio->irq_region->data.irqbase + local_irq,
+		regs);
+
+	/* set EOI */
+
+	outb((OCW2_SEOI|local_irq),IC_PIC1 + 0);
+	return;
+}
+
+/* Initialize Super I/O device */
+
+static void __devinit
+superio_init(struct superio_device *sio)
+{
+	struct pci_dev *pdev = sio->lio_pdev;
+	u16 word;
+	u8  i;
+
+	if (!pdev || sio->iosapic_irq == -1) {
+		printk(KERN_ERR "All SuperIO functions not found!\n");
+		BUG();
+		return;
+	}
+
+	printk (KERN_INFO "SuperIO: Found NS87560 Legacy I/O device at %s (IRQ %i) \n",
+		pdev->slot_name,sio->iosapic_irq);
+
+	/* Find our I/O devices */
+	pci_read_config_word (pdev, SIO_SP1BAR, &sio->sp1_base);
+	sio->sp1_base &= ~1;
+	printk (KERN_INFO "SuperIO: Serial port 1 at 0x%x\n", sio->sp1_base);
+
+	pci_read_config_word (pdev, SIO_SP2BAR, &sio->sp2_base);
+	sio->sp2_base &= ~1;
+	printk (KERN_INFO "SuperIO: Serial port 2 at 0x%x\n", sio->sp2_base);
+
+	pci_read_config_word (pdev, SIO_PPBAR, &sio->pp_base);
+	sio->pp_base &= ~1;
+	printk (KERN_INFO "SuperIO: Parallel port at 0x%x\n", sio->pp_base);
+
+	pci_read_config_word (pdev, SIO_FDCBAR, &sio->fdc_base);
+	sio->fdc_base &= ~1;
+	printk (KERN_INFO "SuperIO: Floppy controller at 0x%x\n", sio->fdc_base);
+	pci_read_config_word (pdev, SIO_ACPIBAR, &sio->acpi_base);
+	sio->acpi_base &= ~1;
+	printk (KERN_INFO "SuperIO: ACPI at 0x%x\n", sio->acpi_base);
+
+	request_region (IC_PIC1, 0x1f, "pic1");
+	request_region (IC_PIC2, 0x1f, "pic2");
+	request_region (sio->acpi_base, 0x1f, "acpi");
+
+	/* Enable the legacy I/O function */
+        pci_read_config_word (pdev, PCI_COMMAND, &word);
+	word |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_IO;
+	pci_write_config_word (pdev, PCI_COMMAND, word);
+	pci_set_master (pdev);
+
+	/* Next project is programming the onboard interrupt
+	 * controllers.  PDC hasn't done this for us, since it's using
+	 * polled I/O.
+	 */
+
+	/* Set PIC interrupts to edge triggered */
+	pci_write_config_byte (pdev, TRIGGER_1, 0x0);
+	pci_write_config_byte (pdev, TRIGGER_2, 0x0);
+
+	/* Disable all interrupt routing */
+	for (i = IR_LOW ; i < IR_HIGH ; i++)
+		pci_write_config_byte (pdev, i, 0x0);
+
+	/* PIC1 Initialization Command Word register programming */
+	outb (0x11,IC_PIC1+0);	/* ICW1: ICW4 write req | ICW1 */
+	outb (0x00,IC_PIC1+1);	/* ICW2: N/A */
+	outb (0x04,IC_PIC1+1);	/* ICW3: Cascade */
+	outb (0x01,IC_PIC1+1);	/* ICW4: x86 mode */
+
+	/* PIC1 Program Operational Control Words */
+	outb (0xff,IC_PIC1+1);	/* OCW1: Mask all interrupts */
+	outb (0xc2,IC_PIC1+0);  /* OCW2: priority (3-7,0-2) */
+
+	/* PIC2 Initialization Command Word register programming */
+	outb (0x11,IC_PIC2+0);	/* ICW1: ICW4 write req | ICW1 */
+	outb (0x00,IC_PIC2+1);	/* ICW2: N/A */
+	outb (0x02,IC_PIC2+1);	/* ICW3: Slave ID code */
+	outb (0x01,IC_PIC2+1);	/* ICW4: x86 mode */
+		
+	/* Program Operational Control Words */
+	outb (0xff,IC_PIC1+1);	/* OCW1: Mask all interrupts */
+	outb (0x68,IC_PIC1+0);	/* OCW3: OCW3 select | ESMM | SMM */
+
+	/* Write master mask reg */
+
+	outb (0xff,IC_PIC1+1);
+
+	/* Set up interrupt routing */
+
+	pci_write_config_byte (pdev, IR_USB, 0x10); /* USB on IRQ1 */
+	pci_write_config_byte (pdev, IR_SER, 0x43); /* SP1 on IRQ3, SP2 on IRQ4 */
+	pci_write_config_byte (pdev, IR_PFD, 0x65); /* PAR on IRQ5, FDC on IRQ6 */
+	pci_write_config_byte (pdev, IR_IDE, 0x07); /* IDE1 on IRQ7 */
+	
+	/* Set USB and IDE to level triggered interrupts, rest to edge */
+	pci_write_config_byte (pdev, TRIGGER_1, 0x82); /* IRQ 1 and 7 */
+
+	/* Setup USB power regulation */
+	outb(1, sio->acpi_base + USB_REG_CR);
+	if (inb(sio->acpi_base + USB_REG_CR) & 1)
+		printk(KERN_INFO "SuperIO: USB regulator enabled\n");
+	else
+		printk(KERN_ERR "USB regulator not initialized!\n");
+
+	pci_enable_device(pdev);
+
+	if (request_irq(sio->iosapic_irq,superio_interrupt,SA_INTERRUPT,
+			"SuperIO",(void *)sio)) {
+
+		printk(KERN_ERR "SuperIO: could not get irq\n");
+		BUG();
+		return;
+	}
+
+	sio->iosapic_irq_enabled = 1;
+	
+}
+
+static void
+superio_disable_irq(void *dev, int local_irq)
+{
+	u8 r8;
+
+	if ((local_irq < 1) || (local_irq == 2) || (local_irq > 7)) {
+	    printk(KERN_ERR "SuperIO: Illegal irq number.\n");
+	    BUG();
+	    return;
+	}
+
+	/* Mask interrupt */
+
+	r8 = inb(IC_PIC1+1);
+	r8 |= (1 << local_irq);
+	outb (r8,IC_PIC1+1);
+}
+
+static void
+superio_enable_irq(void *dev, int local_irq)
+{
+	struct superio_device *sio = (struct superio_device *)dev;
+	u8 r8;
+
+	if ((local_irq < 1) || (local_irq == 2) || (local_irq > 7)) {
+	    printk(KERN_ERR "SuperIO: Illegal irq number.\n");
+	    BUG();
+	    return;
+	}
+
+	/*
+	 * It's possible that we haven't initialized the legacy IO
+	 * function yet. If not, do it now.
+	 */
+
+	if (!sio->iosapic_irq_enabled)
+		superio_init(sio);
+
+	/* Unmask interrupt */
+
+	r8 = inb(IC_PIC1+1);
+	r8 &= ~(1 << local_irq);
+	outb (r8,IC_PIC1+1);
+}
+
+static void
+superio_mask_irq(void *dev, int local_irq)
+{
+	BUG();
+}
+
+static void
+superio_unmask_irq(void *dev, int local_irq)
+{
+	BUG();
+}
+
+static struct irq_region_ops superio_irq_ops = {
+	disable_irq:	superio_disable_irq,
+	enable_irq:	superio_enable_irq,
+	mask_irq:	superio_mask_irq,
+	unmask_irq:	superio_unmask_irq
+};
+
+#ifdef DEBUG_INIT
+static unsigned short expected_device[3] = {
+	PCI_DEVICE_ID_NS_87415,
+	PCI_DEVICE_ID_NS_87560_LIO,
+	PCI_DEVICE_ID_NS_87560_USB
+};
+#endif
+
+int superio_fixup_irq(struct pci_dev *pcidev)
+{
+	int local_irq;
+
+#ifdef DEBUG_INIT
+	int fn;
+	fn = PCI_FUNC(pcidev->devfn);
+
+	/* Verify the function number matches the expected device id. */
+	if (expected_device[fn] != pcidev->device) {
+		BUG();
+		return -1;
+	}
+	printk("superio_fixup_irq(%s) ven 0x%x dev 0x%x from %p\n",
+		pcidev->slot_name,
+		pcidev->vendor, pcidev->device,
+		__builtin_return_address(0));
+#endif
+
+	if (!sio_dev.irq_region) {
+		/* Allocate an irq region for SuperIO devices */
+		sio_dev.irq_region = alloc_irq_region(SUPERIO_NIRQS,
+						&superio_irq_ops,
+						"SuperIO", (void *) &sio_dev);
+		if (!sio_dev.irq_region) {
+			printk(KERN_WARNING "SuperIO: alloc_irq_region failed\n");
+			return -1;
+		}
+	}
+
+	/*
+	 * We don't allocate a SuperIO irq for the legacy IO function,
+	 * since it is a "bridge". Instead, we will allocate irq's for
+	 * each legacy device as they are initialized.
+	 */
+
+	switch(pcidev->device) {
+	case PCI_DEVICE_ID_NS_87415:		/* Function 0 */
+		local_irq = IDE_IRQ;
+		break;
+	case PCI_DEVICE_ID_NS_87560_LIO:	/* Function 1 */
+		sio_dev.lio_pdev = pcidev; /* save for later initialization */
+		return -1;
+	case PCI_DEVICE_ID_NS_87560_USB:	/* Function 2 */
+		local_irq = USB_IRQ;
+		break;
+	default:
+		local_irq = -1;
+		BUG();
+		break;
+	}
+
+	return(sio_dev.irq_region->data.irqbase + local_irq);
+}
+
+void __devinit
+superio_serial_init(void)
+{
+#ifdef CONFIG_SERIAL
+	struct serial_struct *serial;
+	int retval;
+	
+	if (!sio_dev.irq_region)
+		return; /* superio not present */
+
+	if (!sio_dev.iosapic_irq_enabled)
+		superio_init(&sio_dev);
+
+	serial = kmalloc(2 * sizeof (struct serial_struct), GFP_KERNEL);
+
+	if (!serial) {
+		printk(KERN_WARNING "SuperIO: Could not get memory for serial struct.\n");
+		return;
+	}
+
+	memset(serial, 0, 2 * sizeof (struct serial_struct));
+
+	serial->type = PORT_16550A;
+	serial->line = 0;
+	serial->port = sio_dev.sp1_base;
+	serial->port_high = 0;
+	serial->irq = sio_dev.irq_region->data.irqbase + SP1_IRQ;
+	serial->io_type = SERIAL_IO_PORT;
+	serial->flags = 0;
+	serial->xmit_fifo_size = 16;
+	serial->custom_divisor = 0;
+	serial->baud_base = 115200;
+
+	retval = register_serial(serial);
+	if (retval < 0) {
+		printk(KERN_WARNING "SuperIO: Register Serial #0 failed.\n");
+		kfree (serial);
+		return;
+	}
+
+	serial++;
+
+	serial->type = PORT_16550A;
+	serial->line = 1;
+	serial->port = sio_dev.sp2_base;
+	serial->port_high = 0;
+	serial->irq = sio_dev.irq_region->data.irqbase + SP2_IRQ;
+	serial->io_type = SERIAL_IO_PORT;
+	serial->flags = 0;
+	serial->xmit_fifo_size = 16;
+	serial->custom_divisor = 0;
+	serial->baud_base = 115200;
+
+	retval = register_serial(serial);
+	if (retval < 0)
+		printk(KERN_WARNING "SuperIO: Register Serial #1 failed.\n");
+#endif /* CONFIG_SERIAL */
+}
+
+EXPORT_SYMBOL(superio_serial_init);
+
+
+#ifdef CONFIG_PARPORT_PC
+void __devinit
+superio_parport_init(void)
+{
+	if (!sio_dev.irq_region)
+		return; /* superio not present */
+
+	if (!sio_dev.iosapic_irq_enabled)
+		superio_init(&sio_dev);
+
+	if (!parport_pc_probe_port(sio_dev.pp_base, 
+		0 /*base_hi*/,
+		sio_dev.irq_region->data.irqbase + PAR_IRQ, 
+		PARPORT_DMA_NONE /* dma */,
+		NULL /*struct pci_dev* */))
+
+		printk(KERN_WARNING "SuperIO: Probing parallel port failed.\n");
+}
+
+EXPORT_SYMBOL(superio_parport_init);
+#endif	/* CONFIG_PARPORT_PC */
+
+
+int
+superio_get_ide_irq(void)
+{
+	if (sio_dev.irq_region)
+		return sio_dev.irq_region->data.irqbase + IDE_IRQ;
+	else
+		return 0;
+}
+
+EXPORT_SYMBOL(superio_get_ide_irq);
+
+static int __devinit superio_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+#ifdef DEBUG_INIT
+	printk("superio_probe(%s) ven 0x%x dev 0x%x sv 0x%x sd 0x%x class 0x%x\n",
+		dev->slot_name,
+		dev->vendor, dev->device,
+		dev->subsystem_vendor, dev->subsystem_device,
+		dev->class);
+/*
+** superio_probe(00:0e.0) ven 0x100b dev 0x2 sv 0x0 sd 0x0 class 0x1018a
+** superio_probe(00:0e.1) ven 0x100b dev 0xe sv 0x0 sd 0x0 class 0x68000
+** superio_probe(00:0e.2) ven 0x100b dev 0x12 sv 0x0 sd 0x0 class 0xc0310
+*/
+#endif
+
+	/* superio_fixup_irq(dev); */
+
+	if (dev->device == PCI_DEVICE_ID_NS_87560_LIO) {
+#ifdef CONFIG_PARPORT_PC
+		superio_parport_init();
+#endif
+#ifdef CONFIG_SERIAL
+		superio_serial_init();
+#endif
+		/* REVISIT : superio_fdc_init() ? */
+		return 0;
+	} else {
+		/* don't claim this device; let whatever either driver
+		 * do it 
+		 */ 
+		return -1;
+	}
+}
+
+static struct pci_device_id superio_tbl[] __devinitdata = {
+	{ PCI_VENDOR_ID_NS, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	{ 0, }
+};
+
+static struct pci_driver superio_driver = {
+	name:		"SuperIO",
+	id_table:	superio_tbl,
+	probe:		superio_probe,
+};
+
+static int __init superio_modinit(void)
+{
+	return pci_module_init(&superio_driver);
+}
+
+static void __exit superio_exit(void)
+{
+	pci_unregister_driver(&superio_driver);
+}
+
+module_init(superio_modinit);
+module_exit(superio_exit);
diff -Nru a/drivers/parisc/wax.c b/drivers/parisc/wax.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/parisc/wax.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,141 @@
+/*
+ *	WAX Device Driver
+ *
+ *	(c) Copyright 2000 The Puffin Group Inc.
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2 of the License, or
+ *      (at your option) any later version.
+ *
+ *	by Helge Deller <deller@gmx.de>
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+
+#include "gsc.h"
+
+#define WAX_GSC_IRQ	7	/* Hardcoded Interrupt for GSC */
+#define WAX_GSC_NMI_IRQ	29
+
+static int wax_choose_irq(struct parisc_device *dev)
+{
+	int irq = -1;
+
+	switch (dev->id.sversion) {
+		case 0x73:	irq = 30; break; /* HIL */
+		case 0x8c:	irq = 25; break; /* RS232 */
+		case 0x90:	irq = 21; break; /* WAX EISA BA */
+	}
+
+	return irq;
+}
+
+static void __init
+wax_init_irq(struct busdevice *wax)
+{
+	unsigned long base = wax->hpa;
+
+	/* Stop WAX barking for a bit */
+	gsc_writel(0x00000000, base+OFFSET_IMR);
+
+	/* clear pending interrupts */
+	(volatile u32) gsc_readl(base+OFFSET_IRR);
+
+	/* We're not really convinced we want to reset the onboard
+         * devices. Firmware does it for us...
+	 */
+
+	/* Resets */
+//	gsc_writel(0xFFFFFFFF, base+0x1000); /* HIL */
+//	gsc_writel(0xFFFFFFFF, base+0x2000); /* RS232-B on Wax */
+	
+	/* Ok we hit it on the head with a hammer, our Dog is now
+	** comatose and muzzled.  Devices will now unmask WAX
+	** interrupts as they are registered as irq's in the WAX range.
+	*/
+}
+
+int __init
+wax_init_chip(struct parisc_device *dev)
+{
+	struct busdevice *wax;
+	struct gsc_irq gsc_irq;
+	int irq, ret;
+
+	wax = kmalloc(sizeof(struct busdevice), GFP_KERNEL);
+	if (!wax)
+		return -ENOMEM;
+
+	wax->name = "Wax";
+	wax->hpa = dev->hpa;
+
+	wax->version = 0;   /* gsc_readb(wax->hpa+WAX_VER); */
+	printk(KERN_INFO "%s at 0x%lx found.\n", wax->name, wax->hpa);
+
+	/* Stop wax hissing for a bit */
+	wax_init_irq(wax);
+
+	/* the IRQ wax should use */
+	irq = gsc_claim_irq(&gsc_irq, WAX_GSC_IRQ);
+	if (irq < 0) {
+		printk(KERN_ERR "%s(): cannot get GSC irq\n",
+				__FUNCTION__);
+		kfree(wax);
+		return -EBUSY;
+	}
+
+	ret = request_irq(gsc_irq.irq, busdev_barked, 0, "wax", wax);
+	if (ret < 0) {
+		kfree(wax);
+		return ret;
+	}
+
+	/* Save this for debugging later */
+	wax->parent_irq = gsc_irq.irq;
+	wax->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data;
+
+	/* enable IRQ's for devices below WAX */
+	gsc_writel(wax->eim, wax->hpa + OFFSET_IAR);
+
+	/* Done init'ing, register this driver */
+	ret = gsc_common_irqsetup(dev, wax);
+	if (ret) {
+		kfree(wax);
+		return ret;
+	}
+
+	fixup_child_irqs(dev, wax->busdev_region->data.irqbase,
+			wax_choose_irq);
+	/* On 715-class machines, Wax EISA is a sibling of Wax, not a child. */
+	if (dev->parent->id.hw_type != HPHW_IOA) {
+		fixup_child_irqs(dev->parent, wax->busdev_region->data.irqbase,
+				wax_choose_irq);
+	}
+
+	return ret;
+}
+
+static struct parisc_device_id wax_tbl[] = {
+  	{ HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008e },
+	{ 0, }
+};
+
+MODULE_DEVICE_TABLE(parisc, wax_tbl);
+
+struct parisc_driver wax_driver = {
+	name:		"Wax",
+	id_table:	wax_tbl,
+	probe:		wax_init_chip,
+};
diff -Nru a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c
--- a/drivers/parport/parport_gsc.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/parport/parport_gsc.c	Mon Nov  4 14:31:02 2002
@@ -7,7 +7,7 @@
  *      the Free Software Foundation; either version 2 of the License, or
  *      (at your option) any later version.
  *
- *	by Helge Deller <deller@gmx.de>
+ *	(C) 1999-2001 by Helge Deller <deller@gmx.de>
  *
  * 
  * based on parport_pc.c by 
@@ -36,9 +36,9 @@
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/uaccess.h>
+#include <asm/superio.h>
 
 #include <linux/parport.h>
-#include <asm/gsc.h>
 #include <asm/pdc.h>
 #include <asm/hardware.h>
 #include <asm/parport_gsc.h>
@@ -47,6 +47,7 @@
 MODULE_AUTHOR("Helge Deller <deller@gmx.de>");
 MODULE_DESCRIPTION("HP-PARISC PC-style parallel port driver");
 MODULE_SUPPORTED_DEVICE("integrated PC-style parallel port");
+MODULE_LICENSE("GPL");
 
 
 /*
@@ -347,13 +348,6 @@
 	struct parport tmp;
 	struct parport *p = &tmp;
 
-#if 1
-#warning Take this out when region handling works again, <deller@gmx,de>
-#else
-	if (check_region(base, 3)) 
-	    return NULL;
-#endif
-	    
 	priv = kmalloc (sizeof (struct parport_gsc_private), GFP_KERNEL);
 	if (!priv) {
 		printk (KERN_DEBUG "parport (0x%lx): no memory!\n", base);
@@ -430,12 +424,6 @@
 	printk("]\n");
 	parport_proc_register(p);
 
-	request_region (p->base, 3, p->name);
-	if (p->size > 3)
-		request_region (p->base + 3, p->size - 3, p->name);
-	if (p->modes & PARPORT_MODE_ECP)
-		request_region (p->base_hi, 3, p->name);
-
 	if (p->irq != PARPORT_IRQ_NONE) {
 		if (request_irq (p->irq, parport_gsc_interrupt,
 				 0, p->name, p)) {
@@ -465,62 +453,56 @@
 
 static int __initdata parport_count;
 
-static int __init parport_init_chip(struct hp_device *d, struct pa_iodc_driver *dri)
+static int __devinit parport_init_chip(struct parisc_device *dev)
 {
 	unsigned long port;
-	int irq;
-
-	irq = busdevice_alloc_irq(d); 
 
-	if (!irq) {
-	    printk(KERN_DEBUG "IRQ not found for parallel device at 0x%p\n", d->hpa);
-	    return -ENODEV;
+	if (!dev->irq) {
+		printk("IRQ not found for parallel device at 0x%lx\n", dev->hpa);
+		return -ENODEV;
 	}
 
-	port = ((unsigned long) d->hpa) + PARPORT_GSC_OFFSET;
+	port = dev->hpa + PARPORT_GSC_OFFSET;
 	
-	/* 
-	    some older machines with ASP-chip don't support the enhanced parport modes 
-	*/
-	if (!pdc_add_valid( (void *)(port+4))) {
-	    /* Initialize bidirectional-mode (0x10) & data-tranfer-mode #1 (0x20) */
-	    printk(KERN_DEBUG "%s: initialize bidirectional-mode.\n", __FUNCTION__);
-	    parport_writeb ( (0x10 + 0x20), port + 4);
+	/* some older machines with ASP-chip don't support
+	 * the enhanced parport modes.
+	 */
+	if (boot_cpu_data.cpu_type > pcxt && !pdc_add_valid(port+4)) {
+
+		/* Initialize bidirectional-mode (0x10) & data-tranfer-mode #1 (0x20) */
+		printk("%s: initialize bidirectional-mode.\n", __FUNCTION__);
+		parport_writeb ( (0x10 + 0x20), port + 4);
+
 	} else {
-	    printk(KERN_DEBUG "%s: enhanced parport-modes not supported.\n", __FUNCTION__);
+		printk("%s: enhanced parport-modes not supported.\n", __FUNCTION__);
 	}
 	
-	if (parport_gsc_probe_port(port, 0, 
-		    irq, /* PARPORT_IRQ_NONE */
-		    PARPORT_DMA_NONE, NULL))
-	    parport_count++;
+	if (parport_gsc_probe_port(port, 0, dev->irq,
+			/* PARPORT_IRQ_NONE */ PARPORT_DMA_NONE, NULL))
+		parport_count++;
 
 	return 0;
 }
 
-static struct pa_iodc_driver parport_drivers_for[] __initdata = {
-  {HPHW_FIO, 0x0, 0x0, 0x74, 0x0, 0,			/* 715/64 */
-	DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
-	"parallel device", "HP 7xx - Series", (void *) parport_init_chip},
-  { 0 }
+static struct parisc_device_id parport_tbl[] = {
+	{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x74 },
+	{ 0, }
 };
 
-int __init parport_gsc_init(void)
-{
-	parport_count = 0;
-	
-	register_driver(parport_drivers_for);
-
-	return 0;
-}
+MODULE_DEVICE_TABLE(parisc, parport_tbl);
 
+static struct parisc_driver parport_driver = {
+	name:		"Parallel",
+	id_table:	parport_tbl,
+	probe:		parport_init_chip,
+};
 
-static int __init parport_gsc_init_module(void)
-{	
-	return !parport_gsc_init();
+int __devinit parport_gsc_init(void)
+{
+	return register_parisc_driver(&parport_driver);
 }
 
-static void __exit parport_gsc_exit_module(void)
+static void __devexit parport_gsc_exit(void)
 {
 	struct parport *p = parport_enumerate(), *tmp;
 	while (p) {
@@ -532,11 +514,6 @@
 				free_dma(p->dma);
 			if (p->irq != PARPORT_IRQ_NONE)
 				free_irq(p->irq, p);
-			release_region(p->base, 3);
-			if (p->size > 3)
-				release_region(p->base + 3, p->size - 3);
-			if (p->modes & PARPORT_MODE_ECP)
-				release_region(p->base_hi, 3);
 			parport_proc_unregister(p);
 			if (priv->dma_buf)
 				pci_free_consistent(priv->dev, PAGE_SIZE,
@@ -548,7 +525,8 @@
 		}
 		p = tmp;
 	}
+	unregister_parisc_driver(&parport_driver);
 }
 
-module_init(parport_gsc_init_module);
-module_exit(parport_gsc_exit_module);
+module_init(parport_gsc_init);
+module_exit(parport_gsc_exit);
diff -Nru a/drivers/pci/pci.c b/drivers/pci/pci.c
--- a/drivers/pci/pci.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/pci/pci.c	Mon Nov  4 14:31:01 2002
@@ -642,6 +642,11 @@
 
 __setup("pci=", pci_setup);
 
+#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
+struct pci_dev *isa_bridge;
+EXPORT_SYMBOL(isa_bridge);
+#endif
+
 EXPORT_SYMBOL(pci_enable_device);
 EXPORT_SYMBOL(pci_disable_device);
 EXPORT_SYMBOL(pci_find_capability);
diff -Nru a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
--- a/drivers/pnp/isapnp/core.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/pnp/isapnp/core.c	Mon Nov  4 14:31:02 2002
@@ -43,6 +43,7 @@
 #include <linux/init.h>
 #include <linux/isapnp.h>
 #include <linux/pnp.h>
+#include <asm/io.h>
 
 LIST_HEAD(isapnp_cards);
 LIST_HEAD(isapnp_devices);
diff -Nru a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
--- a/drivers/s390/net/lcs.c	Mon Nov  4 14:31:00 2002
+++ b/drivers/s390/net/lcs.c	Mon Nov  4 14:31:00 2002
@@ -126,7 +126,6 @@
 #include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/init.h>
-#include <linux/tqueue.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/irq.h>
diff -Nru a/drivers/sbus/char/aurora.c b/drivers/sbus/char/aurora.c
--- a/drivers/sbus/char/aurora.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/sbus/char/aurora.c	Mon Nov  4 14:31:01 2002
@@ -59,7 +59,6 @@
 #include <linux/mm.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/tqueue.h>
 #include <linux/delay.h>
 
 #include <asm/io.h>
diff -Nru a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
--- a/drivers/scsi/3w-xxxx.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/scsi/3w-xxxx.c	Mon Nov  4 14:31:02 2002
@@ -153,6 +153,17 @@
                  Cleanup some AEN severity levels.
    1.02.00.027 - Add drive not supported AEN code for SATA controllers.
                  Remove spurious unknown ioctl error message.
+   1.02.00.028 - Fix bug where multiple controllers with no units were the
+                 same card number.
+                 Fix bug where cards were being shut down more than once.
+   1.02.00.029 - Add missing pci_free_consistent() in tw_allocate_memory().
+                 Replace pci_map_single() with pci_map_page() for highmem.
+                 Check for tw_setfeature() failure.
+   1.02.00.030 - Make driver 64-bit clean.
+   1.02.00.031 - Cleanup polling timeouts/routines in several places.
+                 Add support for mode sense opcode.
+                 Add support for cache mode page.
+                 Add support for synchronize cache opcode.
 */
 
 #include <linux/module.h>
@@ -205,7 +216,7 @@
 };
 
 /* Globals */
-char *tw_driver_version="1.02.00.027";
+char *tw_driver_version="1.02.00.031";
 TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
 int tw_device_extension_count = 0;
 
@@ -281,11 +292,10 @@
 {
 	TW_Command *command_packet;
 	TW_Param *param;
-	int tries = 0;
 	int request_id = 0;
-	u32 command_que_value = 0, command_que_addr;
-	u32 status_reg_value = 0, status_reg_addr;
-	u32 param_value;
+	u32 command_que_addr;
+	unsigned long command_que_value;
+	unsigned long param_value;
 	TW_Response_Queue response_queue;
 	u32 response_que_addr;
 	unsigned short aen;
@@ -293,13 +303,11 @@
 	int finished = 0;
 	int first_reset = 0;
 	int queue = 0;
-	int imax, i;
 	int found = 0, table_max = 0;
 
 	dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue()\n");
 
 	command_que_addr = tw_dev->registers.command_que_addr;
-	status_reg_addr = tw_dev->registers.status_reg_addr;
 	response_que_addr = tw_dev->registers.response_que_addr;
 
 	if (tw_poll_status(tw_dev, TW_STATUS_ATTENTION_INTERRUPT | TW_STATUS_MICROCONTROLLER_READY, 30)) {
@@ -351,114 +359,96 @@
 	command_packet->byte8.param.sgl[0].address = param_value;
 	command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
 
-	imax = TW_POLL_MAX_RETRIES;
-
 	/* Now drain the controller's aen queue */
 	do {
 		/* Post command packet */
 		outl(command_que_value, command_que_addr);
 
 		/* Now poll for completion */
-		for (i=0;i<imax;i++) {
-			mdelay(5);
-			status_reg_value = inl(status_reg_addr);
-			if (tw_check_bits(status_reg_value)) {
-				dprintk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unexpected bits.\n");
-				tw_decode_bits(tw_dev, status_reg_value, 0);
+		if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
+			response_queue.value = inl(response_que_addr);
+			request_id = (unsigned char)response_queue.u.response_id;
+
+			if (request_id != 0) {
+				/* Unexpected request id */
+				printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unexpected request id.\n");
 				return 1;
 			}
-			if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
-				response_queue.value = inl(response_que_addr);
-				request_id = (unsigned char)response_queue.u.response_id;
-    
-				if (request_id != 0) {
-					/* Unexpected request id */
-					printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unexpected request id.\n");
+			
+			if (command_packet->status != 0) {
+				if (command_packet->flags != TW_AEN_TABLE_UNDEFINED) {
+					/* Bad response */
+					tw_decode_sense(tw_dev, request_id, 0);
 					return 1;
+				} else {
+					/* We know this is a 3w-1x00, and doesn't support aen's */
+					return 0;
 				}
-	
-				if (command_packet->status != 0) {
-					if (command_packet->flags != TW_AEN_TABLE_UNDEFINED) {
-						/* Bad response */
-						tw_decode_sense(tw_dev, request_id, 0);
+			}
+
+			/* Now check the aen */
+			aen = *(unsigned short *)(param->data);
+			aen_code = (aen & 0x0ff);
+			queue = 0;
+			switch (aen_code) {
+				case TW_AEN_QUEUE_EMPTY:
+					dprintk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
+					if (first_reset != 1) {
 						return 1;
 					} else {
-						/* We know this is a 3w-1x00, and doesn't support aen's */
-						return 0;
+						finished = 1;
 					}
-				}
-
-				/* Now check the aen */
-				aen = *(unsigned short *)(param->data);
-				aen_code = (aen & 0x0ff);
-				queue = 0;
-				switch (aen_code) {
-					case TW_AEN_QUEUE_EMPTY:
-						dprintk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
-						if (first_reset != 1) {
-							continue;
-						} else {
-							finished = 1;
-						}
-						break;
-					case TW_AEN_SOFT_RESET:
-						if (first_reset == 0) {
-							first_reset = 1;
-						} else {
-							printk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
-							tw_dev->aen_count++;
-							queue = 1;
-						}
-						break;
-					default:
-						if (aen == 0x0ff) {
-							printk(KERN_WARNING "3w-xxxx: AEN: INFO: AEN queue overflow.\n");
-						} else {
-							table_max = sizeof(tw_aen_string)/sizeof(char *);
-							if ((aen & 0x0ff) < table_max) {
-								if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
-									printk(KERN_WARNING "3w-xxxx: AEN: %s%d.\n", tw_aen_string[aen & 0xff], aen >> 8);
-								} else {
-									printk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
-								}
-							} else
-								printk(KERN_WARNING "3w-xxxx: Received AEN %d.\n", aen);
-						}
+					break;
+				case TW_AEN_SOFT_RESET:
+					if (first_reset == 0) {
+						first_reset = 1;
+					} else {
+						printk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
 						tw_dev->aen_count++;
 						queue = 1;
-				}
-
-				/* Now put the aen on the aen_queue */
-				if (queue == 1) {
-					tw_dev->aen_queue[tw_dev->aen_tail] = aen;
-					if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
-						tw_dev->aen_tail = TW_Q_START;
+					}
+					break;
+				default:
+					if (aen == 0x0ff) {
+						printk(KERN_WARNING "3w-xxxx: AEN: INFO: AEN queue overflow.\n");
 					} else {
-						tw_dev->aen_tail = tw_dev->aen_tail + 1;
+						table_max = sizeof(tw_aen_string)/sizeof(char *);
+						if ((aen & 0x0ff) < table_max) {
+							if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
+								printk(KERN_WARNING "3w-xxxx: AEN: %s%d.\n", tw_aen_string[aen & 0xff], aen >> 8);
+							} else {
+								printk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
+							}
+						} else
+							printk(KERN_WARNING "3w-xxxx: Received AEN %d.\n", aen);
 					}
-					if (tw_dev->aen_head == tw_dev->aen_tail) {
-						if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
-							tw_dev->aen_head = TW_Q_START;
-						} else {
-							tw_dev->aen_head = tw_dev->aen_head + 1;
-						}
+					tw_dev->aen_count++;
+					queue = 1;
+			}
+
+			/* Now put the aen on the aen_queue */
+			if (queue == 1) {
+				tw_dev->aen_queue[tw_dev->aen_tail] = aen;
+				if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
+					tw_dev->aen_tail = TW_Q_START;
+				} else {
+					tw_dev->aen_tail = tw_dev->aen_tail + 1;
+				}
+				if (tw_dev->aen_head == tw_dev->aen_tail) {
+					if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
+						tw_dev->aen_head = TW_Q_START;
+					} else {
+						tw_dev->aen_head = tw_dev->aen_head + 1;
 					}
 				}
-				found = 1;
-				break;
 			}
+			found = 1;
 		}
 		if (found == 0) {
 			printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Response never received.\n");
 			return 1;
 		}
-		tries++;
-	} while ((tries < TW_MAX_AEN_TRIES) && (finished == 0));
-
-	if (tries >=TW_MAX_AEN_TRIES) {
-		printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Aen queue error.\n");
-		return 1;
-	}
+	} while (finished == 0);
 
 	return 0;
 } /* End tw_aen_drain_queue() */
@@ -468,9 +458,10 @@
 {
 	TW_Command *command_packet;
 	TW_Param *param;
-	u32 command_que_value = 0, command_que_addr;
+	u32 command_que_addr;
+	unsigned long command_que_value;
 	u32 status_reg_value = 0, status_reg_addr;
-	u32 param_value = 0;
+	unsigned long param_value = 0;
 
 	dprintk(KERN_NOTICE "3w-xxxx: tw_aen_read_queue()\n");
 	command_que_addr = tw_dev->registers.command_que_addr;
@@ -539,7 +530,7 @@
 {
 	int i;
 	dma_addr_t dma_handle;
-	u32 *cpu_addr = NULL;
+	unsigned long *cpu_addr = NULL;
 
 	dprintk(KERN_NOTICE "3w-xxxx: tw_allocate_memory()\n");
 
@@ -550,8 +541,9 @@
 			return 1;
 		}
 
-		if ((u32)cpu_addr % (tw_dev->tw_pci_dev->device == TW_DEVICE_ID ? TW_ALIGNMENT_6000 : TW_ALIGNMENT_7000)) {
+		if ((unsigned long)cpu_addr % (tw_dev->tw_pci_dev->device == TW_DEVICE_ID ? TW_ALIGNMENT_6000 : TW_ALIGNMENT_7000)) {
 			printk(KERN_WARNING "3w-xxxx: Couldn't allocate correctly aligned memory.\n");
+			pci_free_consistent(tw_dev->tw_pci_dev, size, cpu_addr, dma_handle);
 			return 1;
 		}
 
@@ -816,13 +808,14 @@
 	struct pci_dev *tw_pci_dev = NULL;
 	u32 status_reg_value;
 	unsigned char c = 1;
-	int i;
+	int i, j = -1;
 	u16 device[TW_NUMDEVICES] = { TW_DEVICE_ID, TW_DEVICE_ID2 };
 
 	dprintk(KERN_NOTICE "3w-xxxx: tw_findcards()\n");
 
 	for (i=0;i<TW_NUMDEVICES;i++) {
 		while ((tw_pci_dev = pci_find_device(TW_VENDOR_ID, device[i], tw_pci_dev))) {
+			j++;
 			if (pci_enable_device(tw_pci_dev))
 				continue;
 
@@ -835,7 +828,7 @@
 			/* Prepare temporary device extension */
 			tw_dev=(TW_Device_Extension *)kmalloc(sizeof(TW_Device_Extension), GFP_ATOMIC);
 			if (tw_dev == NULL) {
-				printk(KERN_WARNING "3w-xxxx: tw_findcards(): kmalloc() failed for card %d.\n", numcards);
+				printk(KERN_WARNING "3w-xxxx: tw_findcards(): kmalloc() failed for card %d.\n", j);
 				continue;
 			}
 			memset(tw_dev, 0, sizeof(TW_Device_Extension));
@@ -845,7 +838,7 @@
 
 			error = tw_initialize_device_extension(tw_dev);
 			if (error) {
-				printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't initialize device extension for card %d.\n", numcards);
+				printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't initialize device extension for card %d.\n", j);
 				tw_free_device_extension(tw_dev);
 				kfree(tw_dev);
 				continue;
@@ -865,7 +858,7 @@
 			
 			/* Poll status register for 60 secs for 'Controller Ready' flag */
 			if (tw_poll_status(tw_dev, TW_STATUS_MICROCONTROLLER_READY, 60)) {
-				printk(KERN_WARNING "3w-xxxx: tw_findcards(): Microcontroller not ready for card %d.\n", numcards);
+				printk(KERN_WARNING "3w-xxxx: tw_findcards(): Microcontroller not ready for card %d.\n", j);
 				tw_free_device_extension(tw_dev);
 				kfree(tw_dev);
 				continue;
@@ -880,14 +873,14 @@
 			  
 				error = tw_aen_drain_queue(tw_dev);
 				if (error) {
-					printk(KERN_WARNING "3w-xxxx: AEN drain failed for card %d.\n", numcards);
+					printk(KERN_WARNING "3w-xxxx: AEN drain failed for card %d.\n", j);
 					tries++;
 					continue;
 				}
 
 				/* Check for controller errors */
 				if (tw_check_errors(tw_dev)) {
-					printk(KERN_WARNING "3w-xxxx: Controller errors found, retrying for card %d.\n", numcards);
+					printk(KERN_WARNING "3w-xxxx: Controller errors found, retrying for card %d.\n", j);
 					tries++;
 					continue;
 				}
@@ -897,7 +890,7 @@
 			}
 
 			if (tries >= TW_MAX_RESET_TRIES) {
-				printk(KERN_WARNING "3w-xxxx: Controller errors, card not responding, check all cabling for card %d.\n", numcards);
+				printk(KERN_WARNING "3w-xxxx: Controller errors, card not responding, check all cabling for card %d.\n", j);
 				tw_free_device_extension(tw_dev);
 				kfree(tw_dev);
 				continue;
@@ -908,7 +901,7 @@
 				printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't get io range 0x%lx-0x%lx for card %d.\n", 
 				       (tw_dev->tw_pci_dev->resource[0].start), 
 				       (tw_dev->tw_pci_dev->resource[0].start) + 
-				       TW_IO_ADDRESS_RANGE, numcards);
+				       TW_IO_ADDRESS_RANGE, j);
 				tw_free_device_extension(tw_dev);
 				kfree(tw_dev);
 				continue;
@@ -918,7 +911,7 @@
 			request_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE, TW_DEVICE_NAME);
 			error = tw_initialize_units(tw_dev);
 			if (error) {
-				printk(KERN_WARNING "3w-xxxx: No valid units for for card %d.\n", numcards);
+				printk(KERN_WARNING "3w-xxxx: No valid units for for card %d.\n", j);
 				release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
 				tw_free_device_extension(tw_dev);
 				kfree(tw_dev);
@@ -927,13 +920,16 @@
 
 			error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
 			if (error) {
-				printk(KERN_WARNING "3w-xxxx: Connection initialization failed for card %d.\n", numcards);
+				printk(KERN_WARNING "3w-xxxx: Connection initialization failed for card %d.\n", j);
 				release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
 				tw_free_device_extension(tw_dev);
 				kfree(tw_dev);
 				continue;
 			}
 
+			/* Set card status as online */
+			tw_dev->online = 1;
+
 			/* Calculate max cmds per lun, and setup queues */
 			if (tw_dev->num_units > 0) {
 				/* Use SHT cmd_per_lun here */
@@ -945,7 +941,7 @@
 			/* Register the card with the kernel SCSI layer */
 			host = scsi_register(tw_host, sizeof(TW_Device_Extension));
 			if (host == NULL) {
-				printk(KERN_WARNING "3w-xxxx: tw_findcards(): scsi_register() failed for card %d.\n", numcards);
+				printk(KERN_WARNING "3w-xxxx: tw_findcards(): scsi_register() failed for card %d.\n", j);
 				release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
 				tw_free_device_extension(tw_dev);
 				kfree(tw_dev);
@@ -982,7 +978,7 @@
 				tw_device_extension_count = numcards;
 				tw_dev2->host = host;
 			} else { 
-				printk(KERN_WARNING "3w-xxxx: tw_findcards(): Bad scsi host data for card %d.\n", numcards);
+				printk(KERN_WARNING "3w-xxxx: tw_findcards(): Bad scsi host data for card %d.\n", j);
 				scsi_unregister(host);
 				release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
 				tw_free_device_extension(tw_dev);
@@ -991,12 +987,21 @@
 			}
 
 			/* Tell the firmware we support shutdown notification*/
-			tw_setfeature(tw_dev2, 2, 1, &c);
+			error = tw_setfeature(tw_dev2, 2, 1, &c);
+			if (error) {
+				printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Error setting features for card %d.\n", j);
+				scsi_unregister(host);
+				release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
+				tw_free_device_extension(tw_dev);
+				kfree(tw_dev);
+				numcards--;
+				continue;
+			}
 
 			/* Now setup the interrupt handler */
 			error = tw_setup_irq(tw_dev2);
 			if (error) {
-				printk(KERN_WARNING "3w-xxxx: tw_findcards(): Error requesting irq for card %d.\n", numcards-1);
+				printk(KERN_WARNING "3w-xxxx: tw_findcards(): Error requesting irq for card %d.\n", j);
 				scsi_unregister(host);
 				release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
 
@@ -1045,8 +1050,11 @@
 	int i;
 
 	for (i=0;i<tw_device_extension_count;i++) {
-		printk(KERN_NOTICE "3w-xxxx: Shutting down card %d.\n", i);
-		tw_shutdown_device(tw_device_extension_list[i]);
+		if (tw_device_extension_list[i]->online == 1) {
+			printk(KERN_NOTICE "3w-xxxx: Shutting down card %d.\n", i);
+			tw_shutdown_device(tw_device_extension_list[i]);
+			tw_device_extension_list[i]->online = 0;
+		}
 	}
 	unregister_reboot_notifier(&tw_notifier);
 
@@ -1056,18 +1064,15 @@
 /* This function will send an initconnection command to controller */
 int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits) 
 {
-	u32 command_que_addr, command_que_value;
-	u32 status_reg_addr, status_reg_value;
+	unsigned long command_que_value;
+	u32 command_que_addr;
 	u32 response_que_addr;
 	TW_Command  *command_packet;
 	TW_Response_Queue response_queue;
 	int request_id = 0;
-	int i = 0;
-	int imax = 0;
 
 	dprintk(KERN_NOTICE "3w-xxxx: tw_initconnection()\n");
 	command_que_addr = tw_dev->registers.command_que_addr;
-	status_reg_addr = tw_dev->registers.status_reg_addr;
 	response_que_addr = tw_dev->registers.response_que_addr;
 
 	/* Initialize InitConnection command packet */
@@ -1099,29 +1104,18 @@
 	outl(command_que_value, command_que_addr);
     
 	/* Poll for completion */
-	imax = TW_POLL_MAX_RETRIES;
-	for (i=0;i<imax;i++) {
-		mdelay(5);
-		status_reg_value = inl(status_reg_addr);
-		if (tw_check_bits(status_reg_value)) {
-			dprintk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected bits.\n");
-			tw_decode_bits(tw_dev, status_reg_value, 0);
+	if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
+		response_queue.value = inl(response_que_addr);
+		request_id = (unsigned char)response_queue.u.response_id;
+		if (request_id != 0) {
+			/* unexpected request id */
+			printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected request id.\n");
 			return 1;
 		}
-		if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
-			response_queue.value = inl(response_que_addr);
-			request_id = (unsigned char)response_queue.u.response_id;
-			if (request_id != 0) {
-				/* unexpected request id */
-				printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected request id.\n");
-				return 1;
-			}
-			if (command_packet->status != 0) {
-				/* bad response */
-				tw_decode_sense(tw_dev, request_id, 0);
-				return 1;
-			}
-			break;	/* Response was okay, so we exit */
+		if (command_packet->status != 0) {
+			/* bad response */
+			tw_decode_sense(tw_dev, request_id, 0);
+			return 1;
 		}
 	}
 	return 0;
@@ -1168,16 +1162,15 @@
 	TW_Command *command_packet;
 	TW_Param *param;
 	int i, imax, num_units = 0;
-	u32 status_reg_addr, status_reg_value;
-	u32 command_que_addr, command_que_value;
+	unsigned long command_que_value;
+	u32 command_que_addr;
 	u32 response_que_addr;
 	TW_Response_Queue response_queue;
-	u32 param_value;
+	unsigned long param_value;
 	unsigned char *is_unit_present;
 
 	dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units()\n");
 
-	status_reg_addr = tw_dev->registers.status_reg_addr;
 	command_que_addr = tw_dev->registers.command_que_addr;
 	response_que_addr = tw_dev->registers.response_que_addr;
   
@@ -1226,31 +1219,20 @@
 	outl(command_que_value, command_que_addr);
 
 	/* Poll for completion */
-	imax = TW_POLL_MAX_RETRIES;
-	for(i=0; i<imax; i++) {
-		mdelay(5);
-		status_reg_value = inl(status_reg_addr);
-		if (tw_check_bits(status_reg_value)) {
-			dprintk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected bits.\n");
-			tw_decode_bits(tw_dev, status_reg_value, 0);
+	if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
+		response_queue.value = inl(response_que_addr);
+		request_id = (unsigned char)response_queue.u.response_id;
+		if (request_id != 0) {
+			/* unexpected request id */
+			printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected request id.\n");
 			return 1;
 		}
-		if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
-			response_queue.value = inl(response_que_addr);
-			request_id = (unsigned char)response_queue.u.response_id;
-			if (request_id != 0) {
-				/* unexpected request id */
-				printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected request id.\n");
-				return 1;
-			}
-			if (command_packet->status != 0) {
-				/* bad response */
-				tw_decode_sense(tw_dev, request_id, 0);
-				return 1;
-			}
-			found = 1;
-			break;
+		if (command_packet->status != 0) {
+			/* bad response */
+			tw_decode_sense(tw_dev, request_id, 0);
+			return 1;
 		}
+		found = 1;
 	}
 	if (found == 0) {
 		/* response never received */
@@ -1432,6 +1414,13 @@
 						dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_CAPACITY\n");
 						error = tw_scsiop_read_capacity_complete(tw_dev, request_id);
 						break;
+					case MODE_SENSE:
+						dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught MODE_SENSE\n");
+						error = tw_scsiop_mode_sense_complete(tw_dev, request_id);
+						break;
+					case SYNCHRONIZE_CACHE:
+						dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught SYNCHRONIZE_CACHE\n");
+						break;
 					case TW_IOCTL:
 						dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught TW_IOCTL\n");
 						error = tw_ioctl_complete(tw_dev, request_id);
@@ -1490,11 +1479,11 @@
 	int bufflen, error = 0;
 	TW_Param *param;
 	TW_Command *command_packet, *command_save;
-	u32 param_value;
+	unsigned long param_value;
 	TW_Ioctl *ioctl = NULL;
 	TW_Passthru *passthru = NULL;
 	int tw_aen_code, i, use_sg;
-	char *data_ptr;
+	unsigned long *data_ptr;
 	int total_bytes = 0, posted = 0;
 	dma_addr_t dma_handle;
 	struct timeval before, timeout;
@@ -1601,7 +1590,7 @@
 			passthru = (TW_Passthru *)tw_dev->command_packet_virtual_address[request_id];
 			passthru->sg_list[0].length = passthru->sector_count*512;
 			if (passthru->sg_list[0].length > TW_MAX_PASSTHRU_BYTES) {
-				printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Passthru size (%ld) too big.\n", passthru->sg_list[0].length);
+				printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Passthru size (%d) too big.\n", passthru->sg_list[0].length);
 				return 1;
 			}
 			passthru->sg_list[0].address = tw_dev->alignment_physical_address[request_id];
@@ -1639,15 +1628,15 @@
 					tw_dev->ioctl_data[request_id] = pci_alloc_consistent(tw_dev->tw_pci_dev, total_bytes, &dma_handle);
 
 					if (!tw_dev->ioctl_data[request_id]) {
-						printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): kmalloc failed for request_id %d.\n", tw_dev->host->host_no, request_id);
+						printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): pci_alloc_consistent() failed for request_id %d.\n", tw_dev->host->host_no, request_id);
 						return 1;
 					}
 
 					/* Copy param sglist into the kernel */
 					data_ptr = tw_dev->ioctl_data[request_id];
 					for (i=0;i<use_sg;i++) {
-						if ((u32 *)command_packet->byte8.param.sgl[i].address != NULL) {
-							error = copy_from_user(data_ptr, (u32 *)command_packet->byte8.param.sgl[i].address, command_packet->byte8.param.sgl[i].length);
+						if (command_packet->byte8.param.sgl[i].address != 0) {
+							error = copy_from_user(data_ptr, (void *)(unsigned long)command_packet->byte8.param.sgl[i].address, command_packet->byte8.param.sgl[i].length);
 							if (error) {
 								dprintk(KERN_WARNING "3w-xxxx: scsi%d: Error copying param sglist from userspace.\n", tw_dev->host->host_no);
 								goto tw_ioctl_bail;
@@ -1677,8 +1666,8 @@
 						/* Copy io sglist into the kernel */
 						data_ptr = tw_dev->ioctl_data[request_id];
 						for (i=0;i<use_sg;i++) {
-							if ((u32 *)command_packet->byte8.io.sgl[i].address != NULL) {
-								error = copy_from_user(data_ptr, (u32 *)command_packet->byte8.io.sgl[i].address, command_packet->byte8.io.sgl[i].length);
+							if (command_packet->byte8.io.sgl[i].address != 0) {
+								error = copy_from_user(data_ptr, (void *)(unsigned long)command_packet->byte8.io.sgl[i].address, command_packet->byte8.io.sgl[i].length);
 								if (error) {
 									dprintk(KERN_WARNING "3w-xxxx: scsi%d: Error copying io sglist from userspace.\n", tw_dev->host->host_no);
 									goto tw_ioctl_bail;
@@ -1732,10 +1721,10 @@
 				/* Now copy up the param or io sglist to userspace */
 				if (command_packet->byte0.sgl_offset == 2) {
 					use_sg = command_save->size - 3;
-					data_ptr = phys_to_virt(command_packet->byte8.param.sgl[0].address);
+					data_ptr = tw_dev->ioctl_data[request_id];
 					for (i=0;i<use_sg;i++) {
-						if ((u32 *)command_save->byte8.param.sgl[i].address != NULL) {
-							error = copy_to_user((u32 *)command_save->byte8.param.sgl[i].address, data_ptr, command_save->byte8.param.sgl[i].length);
+						if (command_save->byte8.param.sgl[i].address != 0) {
+							error = copy_to_user((void *)(unsigned long)command_save->byte8.param.sgl[i].address, data_ptr, command_save->byte8.param.sgl[i].length);
 							if (error) {
 								dprintk(KERN_WARNING "3w-xxxx: scsi%d: Error copying param sglist to userspace.\n", tw_dev->host->host_no);
 								goto tw_ioctl_bail;
@@ -1752,10 +1741,10 @@
 				if (command_packet->byte0.sgl_offset == 3) {
 					use_sg = command_save->size - 4;
 					if (command_packet->byte0.opcode == TW_OP_READ) {
-						data_ptr = phys_to_virt(command_packet->byte8.io.sgl[0].address);
+						data_ptr = tw_dev->ioctl_data[request_id];
 						for(i=0;i<use_sg;i++) {
-							if ((u32 *)command_save->byte8.io.sgl[i].address != NULL) {
-								error = copy_to_user((u32 *)command_save->byte8.io.sgl[i].address, data_ptr, command_save->byte8.io.sgl[i].length);
+							if (command_save->byte8.io.sgl[i].address != 0) {
+								error = copy_to_user((void *)(unsigned long)command_save->byte8.io.sgl[i].address, data_ptr, command_save->byte8.io.sgl[i].length);
 								if (error) {
 									dprintk(KERN_WARNING "3w-xxxx: scsi%d: Error copying io sglist to userspace.\n", tw_dev->host->host_no);
 									goto tw_ioctl_bail;
@@ -1885,6 +1874,12 @@
 		return 0;
 
 	use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir);
+	
+	if (use_sg == 0) {
+		printk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data(): pci_map_sg() failed.\n");
+		return 0;
+	}
+
 	cmd->SCp.phase = 2;
 	cmd->SCp.have_data_in = use_sg;
 	
@@ -1901,8 +1896,14 @@
 	if (cmd->request_bufflen == 0)
 		return 0;
 
-	mapping = pci_map_single(pdev, cmd->request_buffer, cmd->request_bufflen, dma_dir);
-	cmd->SCp.phase = 2;
+	mapping = pci_map_page(pdev, virt_to_page(cmd->request_buffer), ((unsigned long)cmd->request_buffer & ~PAGE_MASK), cmd->request_bufflen, dma_dir);
+
+	if (mapping == 0) {
+		printk(KERN_WARNING "3w-xxxx: tw_map_scsi_single_data(): pci_map_page() failed.\n");
+		return 0;
+	}
+
+	cmd->SCp.phase = 1;
 	cmd->SCp.have_data_in = mapping;
 
 	return mapping;
@@ -1951,11 +1952,45 @@
 	return 0;
 } /* End tw_poll_status() */
 
+/* This function will poll the status register for disappearance of a flag */
+int tw_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds)
+{
+	u32 status_reg_addr, status_reg_value;
+	struct timeval before, timeout;
+
+	status_reg_addr = tw_dev->registers.status_reg_addr;
+	do_gettimeofday(&before);
+	status_reg_value = inl(status_reg_addr);
+
+	if (tw_check_bits(status_reg_value)) {
+		dprintk(KERN_WARNING "3w-xxxx: tw_poll_status_gone(): Unexpected bits.\n");
+		tw_decode_bits(tw_dev, status_reg_value, 0);
+	}
+
+	while ((status_reg_value & flag) != 0) {
+		status_reg_value = inl(status_reg_addr);
+
+		if (tw_check_bits(status_reg_value)) {
+			dprintk(KERN_WARNING "3w-xxxx: tw_poll_status_gone(): Unexpected bits.\n");
+			tw_decode_bits(tw_dev, status_reg_value, 0);
+		}
+
+		do_gettimeofday(&timeout);
+		if (before.tv_sec + seconds < timeout.tv_sec) {
+			dprintk(KERN_WARNING "3w-xxxx: tw_poll_status_gone(): Flag 0x%x never disappeared.\n", flag);
+			return 1;
+		}
+		mdelay(5);
+	}
+	return 0;
+} /* End tw_poll_status_gone() */
+
 /* This function will attempt to post a command packet to the board */
 int tw_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
 {
 	u32 status_reg_addr, status_reg_value;
-	u32 command_que_addr, command_que_value;
+	unsigned long command_que_value;
+	u32 command_que_addr;
 
 	dprintk(KERN_NOTICE "3w-xxxx: tw_post_command_packet()\n");
 	command_que_addr = tw_dev->registers.command_que_addr;
@@ -2164,14 +2199,14 @@
 	for (i=0;i<TW_Q_LENGTH;i++) {
 		if (tw_dev->srb[i] == SCpnt) {
 			if (tw_dev->state[i] == TW_S_STARTED) {
-				printk(KERN_WARNING "3w-xxxx: scsi%d: Unit #%d: Command (0x%x) timed out.\n", tw_dev->host->host_no, tw_dev->srb[i]==0 ? 0 : tw_dev->srb[i]->target, (u32)SCpnt);
+				printk(KERN_WARNING "3w-xxxx: scsi%d: Unit #%d: Command (%p) timed out.\n", tw_dev->host->host_no, tw_dev->srb[i]==0 ? 0 : tw_dev->srb[i]->target, SCpnt);
 				tw_dev->state[i] = TW_S_COMPLETED;
 				tw_state_request_finish(tw_dev, i);
 				spin_unlock(&tw_dev->tw_lock);
 				return (SUCCESS);
 			}
 			if (tw_dev->state[i] == TW_S_PENDING) {
-				printk(KERN_WARNING "3w-xxxx: scsi%d: Unit #%d: Command (0x%x) timed out.\n", tw_dev->host->host_no, tw_dev->srb[i]==0 ? 0 : tw_dev->srb[i]->target, (u32)SCpnt);
+				printk(KERN_WARNING "3w-xxxx: scsi%d: Unit #%d: Command (%p) timed out.\n", tw_dev->host->host_no, tw_dev->srb[i]==0 ? 0 : tw_dev->srb[i]->target, SCpnt);
 				if (tw_dev->pending_head == TW_Q_LENGTH-1) {
 					tw_dev->pending_head = TW_Q_START;
 				} else {
@@ -2185,7 +2220,7 @@
 			}
 			if (tw_dev->state[i] == TW_S_POSTED) {
 				/* If the command has already been posted, we have to reset the card */
-				printk(KERN_WARNING "3w-xxxx: scsi%d: Unit #%d: Command (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, tw_dev->srb[i]==0 ? 0 : tw_dev->srb[i]->target, (u32)SCpnt);
+				printk(KERN_WARNING "3w-xxxx: scsi%d: Unit #%d: Command (%p) timed out, resetting card.\n", tw_dev->host->host_no, tw_dev->srb[i]==0 ? 0 : tw_dev->srb[i]->target, SCpnt);
 				/* We have to let AEN requests through before the reset */
 				spin_unlock(&tw_dev->tw_lock);
 				spin_unlock_irq(tw_dev->host->host_lock);
@@ -2278,9 +2313,9 @@
 					printk(KERN_INFO "3w-xxxx: Request_id: %d\n", j);
 					printk(KERN_INFO "Opcode: 0x%x\n", command->byte0.opcode);
 					printk(KERN_INFO "Block_count: 0x%x\n", command->byte6.block_count);
-					printk(KERN_INFO "LBA: 0x%x\n", (u32)command->byte8.io.lba);
-					printk(KERN_INFO "Physical command packet addr: 0x%x\n", tw_dev->command_packet_physical_address[j]);
-					printk(KERN_INFO "Scsi_Cmnd: 0x%x\n", (u32)tw_dev->srb[j]);
+					printk(KERN_INFO "LBA: 0x%x\n", command->byte8.io.lba);
+					printk(KERN_INFO "Physical command packet addr: 0x%lx\n", tw_dev->command_packet_physical_address[j]);
+					printk(KERN_INFO "Scsi_Cmnd: %p\n", tw_dev->srb[j]);
 				}
 			}
 			printk(KERN_INFO "3w-xxxx: Free_head: %3d\n", tw_dev->free_head);
@@ -2373,6 +2408,14 @@
 		        dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught REQUEST_SENSE.\n");
 		        error = tw_scsiop_request_sense(tw_dev, request_id);
 		        break;
+		case MODE_SENSE:
+			dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught MODE_SENSE.\n");
+			error = tw_scsiop_mode_sense(tw_dev, request_id);
+			break;
+		case SYNCHRONIZE_CACHE:
+			dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught SYNCHRONIZE_CACHE.\n");
+			error = tw_scsiop_synchronize_cache(tw_dev, request_id);
+			break;
 		case TW_IOCTL:
 			dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught TW_SCSI_IOCTL.\n");
 			error = tw_ioctl(tw_dev, request_id);
@@ -2428,8 +2471,9 @@
 {
 	TW_Param *param;
 	TW_Command *command_packet;
-	u32 command_que_value, command_que_addr;
-	u32 param_value;
+	unsigned long command_que_value;
+	u32 command_que_addr;
+	unsigned long param_value;
 
 	dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry()\n");
 
@@ -2527,13 +2571,115 @@
 	return 0;
 } /* End tw_scsiop_inquiry_complete() */
 
+/* This function handles scsi mode_sense commands */
+int tw_scsiop_mode_sense(TW_Device_Extension *tw_dev, int request_id)
+{
+	TW_Param *param;
+	TW_Command *command_packet;
+	unsigned long command_que_value;
+	unsigned long param_value;
+
+	dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense()\n");
+
+	/* Only page control = 0, page code = 0x8 (cache page) supported */
+	if (tw_dev->srb[request_id]->cmnd[2] != 0x8) {
+		tw_dev->state[request_id] = TW_S_COMPLETED;
+		tw_state_request_finish(tw_dev, request_id);
+		tw_dev->srb[request_id]->result = (DID_OK << 16);
+		tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
+		return 0;
+	}
+
+	/* Now read firmware cache setting for this unit */
+	command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
+	if (command_packet == NULL) {
+		printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad command packet virtual address.\n");
+		return 1;
+	}
+
+	/* Setup the command packet */
+	memset(command_packet, 0, sizeof(TW_Sector));
+	command_packet->byte0.opcode = TW_OP_GET_PARAM;
+	command_packet->byte0.sgl_offset = 2;
+	command_packet->size = 4;
+	command_packet->request_id = request_id;
+	command_packet->byte3.unit = 0;
+	command_packet->byte3.host_id = 0;
+	command_packet->status = 0;
+	command_packet->flags = 0;
+	command_packet->byte6.parameter_count = 1;
+
+	/* Setup the param */
+	if (tw_dev->alignment_virtual_address[request_id] == NULL) {
+		printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad alignment virtual address.\n");
+		return 1;
+	}
+
+	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
+	memset(param, 0, sizeof(TW_Sector));
+	param->table_id = TW_UNIT_INFORMATION_TABLE_BASE + tw_dev->srb[request_id]->target;
+	param->parameter_id = 7; /* unit flags */
+	param->parameter_size_bytes = 1;
+	param_value = tw_dev->alignment_physical_address[request_id];
+	if (param_value == 0) {
+		printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad alignment physical address.\n");
+		return 1;
+	}
+
+	command_packet->byte8.param.sgl[0].address = param_value;
+	command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
+	command_que_value = tw_dev->command_packet_physical_address[request_id];
+	if (command_que_value == 0) {
+		printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad command packet physical address.\n");
+		return 1;
+	}
+
+	/* Now try to post the command packet */
+	tw_post_command_packet(tw_dev, request_id);
+	
+	return 0;
+} /* End tw_scsiop_mode_sense() */
+
+/* This function is called by the isr to complete a mode sense command */
+int tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int request_id)
+{
+	TW_Param *param;
+	unsigned char *flags;
+	unsigned char *request_buffer;
+
+	dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense_complete()\n");
+
+	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
+	if (param == NULL) {
+		printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense_complete(): Bad alignment virtual address.\n");
+		return 1;
+	}
+	flags = (char *)&(param->data[0]);
+	request_buffer = tw_dev->srb[request_id]->buffer;
+	memset(request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
+
+	request_buffer[0] = 0xf;        /* mode data length */
+	request_buffer[1] = 0;          /* default medium type */
+	request_buffer[2] = 0x10;       /* dpo/fua support on */
+	request_buffer[3] = 0;          /* no block descriptors */
+	request_buffer[4] = 0x8;        /* caching page */
+	request_buffer[5] = 0xa;        /* page length */
+	if (*flags & 0x1)
+		request_buffer[6] = 0x4;        /* WCE on */
+	else
+		request_buffer[6] = 0x0;        /* WCE off */
+
+	return 0;
+} /* End tw_scsiop_mode_sense_complete() */
+
 /* This function handles scsi read_capacity commands */
 int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id) 
 {
 	TW_Param *param;
 	TW_Command *command_packet;
-	u32 command_que_addr, command_que_value;
-	u32 param_value;
+	unsigned long command_que_value;
+	u32 command_que_addr;
+	unsigned long param_value;
 
 	dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity()\n");
 
@@ -2637,7 +2783,8 @@
 int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id) 
 {
 	TW_Command *command_packet;
-	u32 command_que_addr, command_que_value = 0;
+	unsigned long command_que_value;
+	u32 command_que_addr = 0x0;
 	u32 lba = 0x0, num_sectors = 0x0, buffaddr = 0x0;
 	int i, use_sg;
 	Scsi_Cmnd *srb;
@@ -2700,6 +2847,9 @@
 	if (tw_dev->srb[request_id]->use_sg == 0) {    
 		dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): SG = 0\n");
 		buffaddr = tw_map_scsi_single_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
+		if (buffaddr == 0)
+			return 1;
+
 		command_packet->byte8.io.sgl[0].address = buffaddr;
 		command_packet->byte8.io.sgl[0].length = tw_dev->srb[request_id]->request_bufflen;
 		command_packet->size+=2;
@@ -2707,7 +2857,10 @@
 
 	/* Do this if we have multiple sg list entries */
 	if (tw_dev->srb[request_id]->use_sg > 0) {
-		use_sg = tw_map_scsi_sg_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);;
+		use_sg = tw_map_scsi_sg_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
+		if (use_sg == 0)
+			return 1;
+
 		for (i=0;i<use_sg; i++) {
 			command_packet->byte8.io.sgl[i].address = sg_dma_address(&sglist[i]);
 			command_packet->byte8.io.sgl[i].length = sg_dma_len(&sglist[i]);
@@ -2749,6 +2902,44 @@
 	return 0;
 } /* End tw_scsiop_request_sense() */
 
+/* This function will handle synchronize cache scsi command */
+int tw_scsiop_synchronize_cache(TW_Device_Extension *tw_dev, int request_id)
+{
+	TW_Command *command_packet;
+	unsigned long command_que_value;
+
+	dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_synchronize_cache()\n");
+
+	/* Send firmware flush command for this unit */
+	command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
+	if (command_packet == NULL) {
+		printk(KERN_WARNING "3w-xxxx: tw_scsiop_synchronize_cache(): Bad command packet virtual address.\n");
+		return 1;
+	}
+
+	/* Setup the command packet */
+	memset(command_packet, 0, sizeof(TW_Sector));
+	command_packet->byte0.opcode = TW_OP_FLUSH_CACHE;
+	command_packet->byte0.sgl_offset = 0;
+	command_packet->size = 2;
+	command_packet->request_id = request_id;
+	command_packet->byte3.unit = tw_dev->srb[request_id]->target;
+	command_packet->byte3.host_id = 0;
+	command_packet->status = 0;
+	command_packet->flags = 0;
+	command_packet->byte6.parameter_count = 1;
+	command_que_value = tw_dev->command_packet_physical_address[request_id];
+	if (command_que_value == 0) {
+		printk(KERN_WARNING "3w-xxxx: tw_scsiop_synchronize_cache(): Bad command packet physical address.\n");
+		return 1;
+	}
+
+	/* Now try to post the command packet */
+	tw_post_command_packet(tw_dev, request_id);
+
+	return 0;
+} /* End tw_scsiop_synchronize_cache() */
+
 /* This function will handle test unit ready scsi command */
 int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id)
 {
@@ -2771,11 +2962,10 @@
 	TW_Command  *command_packet;
 	TW_Response_Queue response_queue;
 	int request_id = 0;
-	u32 command_que_value, command_que_addr;
-	u32 status_reg_addr, status_reg_value;
+	unsigned long command_que_value;
+	u32 command_que_addr;
 	u32 response_que_addr;
-	u32 param_value;
-	int imax, i;
+	unsigned long param_value;
 
   	/* Initialize SetParam command packet */
 	if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
@@ -2814,40 +3004,28 @@
 	return 1;
 	}
 	command_que_addr = tw_dev->registers.command_que_addr;
-	status_reg_addr = tw_dev->registers.status_reg_addr;
 	response_que_addr = tw_dev->registers.response_que_addr;
 
 	/* Send command packet to the board */
 	outl(command_que_value, command_que_addr);
 
 	/* Poll for completion */
-	imax = TW_POLL_MAX_RETRIES;
-	for (i=0;i<imax;i++) {
-		mdelay(5);
-		status_reg_value = inl(status_reg_addr);
-		if (tw_check_bits(status_reg_value)) {
-			dprintk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected bits.\n");
-			tw_decode_bits(tw_dev, status_reg_value, 1);
+	if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
+		response_queue.value = inl(response_que_addr);
+		request_id = (unsigned char)response_queue.u.response_id;
+		if (request_id != 0) {
+			/* unexpected request id */
+			printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected request id.\n");
 			return 1;
 		}
-		if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
-			response_queue.value = inl(response_que_addr);
-			request_id = (unsigned char)response_queue.u.response_id;
-			if (request_id != 0) {
-				/* unexpected request id */
-				printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected request id.\n");
-				return 1;
-			}
-			if (command_packet->status != 0) {
-				/* bad response */
-				tw_decode_sense(tw_dev, request_id, 0);
-				return 1;
-			}
-			break; /* Response was okay, so we exit */
+		if (command_packet->status != 0) {
+			/* bad response */
+			tw_decode_sense(tw_dev, request_id, 0);
+			return 1;
 		}
 	}
 
-  return 0;
+	return 0;
 } /* End tw_setfeature() */
 
 /* This function will setup the interrupt handler */
@@ -2957,10 +3135,13 @@
 
 	dprintk(KERN_WARNING "3w-xxxx: tw_unmap_scsi_data()\n");
 
-	if (cmd->use_sg) {
-		pci_unmap_sg(pdev, cmd->request_buffer, cmd->use_sg, dma_dir);
-	} else {
-		pci_unmap_single(pdev, cmd->SCp.have_data_in, cmd->request_bufflen, dma_dir);
+	switch(cmd->SCp.phase) {
+		case 1:
+			pci_unmap_page(pdev, cmd->SCp.have_data_in, cmd->request_bufflen, dma_dir);
+			break;
+		case 2:
+			pci_unmap_sg(pdev, cmd->request_buffer, cmd->use_sg, dma_dir);
+			break;
 	}
 } /* End tw_unmap_scsi_data() */
 
diff -Nru a/drivers/scsi/3w-xxxx.h b/drivers/scsi/3w-xxxx.h
--- a/drivers/scsi/3w-xxxx.h	Mon Nov  4 14:31:01 2002
+++ b/drivers/scsi/3w-xxxx.h	Mon Nov  4 14:31:01 2002
@@ -164,7 +164,7 @@
 #define TW_RESPONSE_ID_MASK		       0x00000FF0
 
 /* PCI related defines */
-#define TW_IO_ADDRESS_RANGE		       0xD
+#define TW_IO_ADDRESS_RANGE		       0x10
 #define TW_DEVICE_NAME			       "3ware Storage Controller"
 #define TW_VENDOR_ID (0x13C1)	/* 3ware */
 #define TW_DEVICE_ID (0x1000)	/* Storage Controller */
@@ -183,6 +183,7 @@
 #define TW_OP_SET_PARAM	      0x13
 #define TW_OP_SECTOR_INFO     0x1a
 #define TW_OP_AEN_LISTEN      0x1c
+#define TW_OP_FLUSH_CACHE     0x0e
 #define TW_CMD_PACKET         0x1d
 #define TW_ATA_PASSTHRU       0x1e
 #define TW_CMD_PACKET_WITH_DATA 0x1f
@@ -221,7 +222,6 @@
 #define TW_MAX_CMDS_PER_LUN		      255
 #define TW_BLOCK_SIZE			      0x200 /* 512-byte blocks */
 #define TW_IOCTL                              0x80
-#define TW_MAX_AEN_TRIES                      100
 #define TW_UNIT_ONLINE                        1
 #define TW_IN_INTR                            1
 #define TW_IN_IOCTL                           2
@@ -248,8 +248,8 @@
 
 /* Scatter Gather List Entry */
 typedef struct TAG_TW_SG_Entry {
-	unsigned long address;
-	unsigned long length;
+	u32 address;
+	u32 length;
 } TW_SG_Entry;
 
 typedef unsigned char TW_Sector[512];
@@ -277,17 +277,17 @@
 	} byte6;
 	union {
 		struct {
-			unsigned long lba;
+			u32 lba;
 			TW_SG_Entry sgl[TW_MAX_SGL_LENGTH];
-			unsigned long padding;	/* pad to 512 bytes */
+			u32 padding;	/* pad to 512 bytes */
 		} io;
 		struct {
 			TW_SG_Entry sgl[TW_MAX_SGL_LENGTH];
-			unsigned long padding[2];
+			u32 padding[2];
 		} param;
 		struct {
-			unsigned long response_queue_pointer;
-			unsigned long padding[125];
+			u32 response_queue_pointer;
+			u32 padding[125];
 		} init_connection;
 		struct {
 			char version[504];
@@ -376,12 +376,12 @@
 
 typedef struct TAG_TW_Device_Extension {
 	TW_Registers		registers;
-	u32			*alignment_virtual_address[TW_Q_LENGTH];
-	u32			alignment_physical_address[TW_Q_LENGTH];
+	unsigned long		*alignment_virtual_address[TW_Q_LENGTH];
+	unsigned long		alignment_physical_address[TW_Q_LENGTH];
 	int			is_unit_present[TW_MAX_UNITS];
 	int			num_units;
-	u32			*command_packet_virtual_address[TW_Q_LENGTH];
-	u32			command_packet_physical_address[TW_Q_LENGTH];
+	unsigned long		*command_packet_virtual_address[TW_Q_LENGTH];
+	unsigned long		command_packet_physical_address[TW_Q_LENGTH];
 	struct pci_dev		*tw_pci_dev;
 	Scsi_Cmnd		*srb[TW_Q_LENGTH];
 	unsigned char		free_queue[TW_Q_LENGTH];
@@ -411,8 +411,9 @@
 	unsigned char		aen_head;
 	unsigned char		aen_tail;
 	volatile long		flags; /* long req'd for set_bit --RR */
-	char			*ioctl_data[TW_Q_LENGTH];
+	unsigned long		*ioctl_data[TW_Q_LENGTH];
 	int			reset_print;
+	char                    online;
 } TW_Device_Extension;
 
 /* Function prototypes */
@@ -440,10 +441,11 @@
 int tw_ioctl_complete(TW_Device_Extension *tw_dev, int request_id);
 void tw_mask_command_interrupt(TW_Device_Extension *tw_dev);
 int tw_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds);
+int tw_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds);
 int tw_post_command_packet(TW_Device_Extension *tw_dev, int request_id);
 int tw_reset_device_extension(TW_Device_Extension *tw_dev);
 int tw_reset_sequence(TW_Device_Extension *tw_dev);
-int tw_scsi_biosparam(struct scsi_device *sdev, struct block_device *bev,
+int tw_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev,
 		sector_t capacity, int geom[]);
 int tw_scsi_detect(Scsi_Host_Template *tw_host);
 int tw_scsi_eh_abort(Scsi_Cmnd *SCpnt);
@@ -453,10 +455,13 @@
 int tw_scsi_release(struct Scsi_Host *tw_host);
 int tw_scsiop_inquiry(TW_Device_Extension *tw_dev, int request_id);
 int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id);
+int tw_scsiop_mode_sense(TW_Device_Extension *tw_dev, int request_id);
+int tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int request_id);
 int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id);
 int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int request_id);
 int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id);
 int tw_scsiop_request_sense(TW_Device_Extension *tw_dev, int request_id);
+int tw_scsiop_synchronize_cache(TW_Device_Extension *tw_dev, int request_id);
 int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id);
 int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size, 
 		  unsigned char *val);
@@ -485,6 +490,7 @@
 	present : 0,					\
 	unchecked_isa_dma : 0,				\
 	use_clustering : ENABLE_CLUSTERING,		\
-	emulated : 1					\
+	emulated : 1,					\
+	highmem_io : 1					\
 }
 #endif /* _3W_XXXX_H */
diff -Nru a/drivers/scsi/Makefile b/drivers/scsi/Makefile
--- a/drivers/scsi/Makefile	Mon Nov  4 14:31:02 2002
+++ b/drivers/scsi/Makefile	Mon Nov  4 14:31:02 2002
@@ -42,7 +42,7 @@
 obj-$(CONFIG_ATARI_SCSI)	+= atari_scsi.o
 obj-$(CONFIG_MAC_SCSI)		+= mac_scsi.o
 obj-$(CONFIG_SCSI_MAC_ESP)	+= mac_esp.o	NCR53C9x.o
-obj-$(CONFIG_SUN3_SCSI)		+= sun3_scsi.o
+obj-$(CONFIG_SUN3_SCSI)		+= sun3_scsi.o  sun3_scsi_vme.o
 obj-$(CONFIG_MVME16x_SCSI)	+= mvme16x.o	53c7xx.o
 obj-$(CONFIG_BVME6000_SCSI)	+= bvme6000.o	53c7xx.o
 obj-$(CONFIG_SCSI_SIM710)	+= sim710.o
diff -Nru a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
--- a/drivers/scsi/aacraid/aachba.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/scsi/aacraid/aachba.c	Mon Nov  4 14:31:01 2002
@@ -220,7 +220,6 @@
  
 static struct fsa_scsi_hba *fsa_dev[MAXIMUM_NUM_ADAPTERS];	/*  SCSI Device Instance Pointers */
 static struct sense_data sense_data[MAXIMUM_NUM_CONTAINERS];
-static void get_sd_devname(int disknum, char *buffer);
 static unsigned long aac_build_sg(Scsi_Cmnd* scsicmd, struct sgmap* sgmap);
 static unsigned long aac_build_sg64(Scsi_Cmnd* scsicmd, struct sgmap64* psg);
 static int aac_send_srb_fib(Scsi_Cmnd* scsicmd);
@@ -1061,8 +1060,10 @@
 			 */
 			 
 			spin_unlock_irq(scsicmd->host->host_lock);
-			fsa_dev_ptr->devno[cid] = 
-				DEVICE_NR(scsicmd->request->rq_dev);
+			if  (scsicmd->request->rq_disk)
+				memcpy(fsa_dev_ptr->devname[cid],
+					scsicmd->request->rq_disk->disk_name,
+					8);
 			ret = aac_read(scsicmd, cid);
 			spin_lock_irq(scsicmd->host->host_lock);
 			return ret;
@@ -1112,40 +1113,18 @@
 	qd.locked = fsa_dev_ptr->locked[qd.cnum];
 	qd.deleted = fsa_dev_ptr->deleted[qd.cnum];
 
-	if (fsa_dev_ptr->devno[qd.cnum] == -1)
+	if (fsa_dev_ptr->devno[qd.cnum][0] == '\0')
 		qd.unmapped = 1;
 	else
 		qd.unmapped = 0;
 
-	get_sd_devname(fsa_dev_ptr->devno[qd.cnum], qd.name);
+	strncpy(dq.name, fsa_dev_ptr->devname[qd.cnum], 8);
 
 	if (copy_to_user(arg, &qd, sizeof (struct aac_query_disk)))
 		return -EFAULT;
 	return 0;
 }
 
-static void get_sd_devname(int disknum, char *buffer)
-{
-	if (disknum < 0) {
-		sprintf(buffer, "%s", "");
-		return;
-	}
-
-	if (disknum < 26)
-		sprintf(buffer, "sd%c", 'a' + disknum);
-	else {
-		unsigned int min1;
-		unsigned int min2;
-		/*
-		 * For larger numbers of disks, we need to go to a new
-		 * naming scheme.
-		 */
-		min1 = disknum / 26;
-		min2 = disknum % 26;
-		sprintf(buffer, "sd%c%c", 'a' + min1 - 1, 'a' + min2);
-	}
-}
-
 static int force_delete_disk(struct aac_dev *dev, void *arg)
 {
 	struct aac_delete_disk dd;
@@ -1191,7 +1170,7 @@
 		 *	Mark the container as no longer being valid.
 		 */
 		fsa_dev_ptr->valid[dd.cnum] = 0;
-		fsa_dev_ptr->devno[dd.cnum] = -1;
+		fsa_dev_ptr->devno[dd.cnum][0] = '\0';
 		return 0;
 	}
 }
diff -Nru a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
--- a/drivers/scsi/aacraid/aacraid.h	Mon Nov  4 14:31:01 2002
+++ b/drivers/scsi/aacraid/aacraid.h	Mon Nov  4 14:31:01 2002
@@ -639,7 +639,7 @@
 	u8		ro[MAXIMUM_NUM_CONTAINERS];
 	u8		locked[MAXIMUM_NUM_CONTAINERS];
 	u8		deleted[MAXIMUM_NUM_CONTAINERS];
-	u32		devno[MAXIMUM_NUM_CONTAINERS];
+	char		devname[MAXIMUM_NUM_CONTAINERS][8];
 };
 
 struct fib {
diff -Nru a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
--- a/drivers/scsi/aacraid/linit.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/scsi/aacraid/linit.c	Mon Nov  4 14:31:01 2002
@@ -237,7 +237,7 @@
 			/* Initialize the ordinal number of the device to -1 */
 			fsa_dev_ptr = &(aac->fsa_dev);
 			for( container = 0; container < MAXIMUM_NUM_CONTAINERS; container++ )
-				fsa_dev_ptr->devno[container] = -1;
+				fsa_dev_ptr->devname[container][0] = '\0';
 
 			dprintk((KERN_DEBUG "Initializing Hardware...\n"));
 			if((*aac_drivers[index].init)(aac , host_ptr->unique_id) != 0)
diff -Nru a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
--- a/drivers/scsi/aha1542.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/scsi/aha1542.c	Mon Nov  4 14:31:02 2002
@@ -1635,14 +1635,18 @@
 		if (HOSTDATA(SCpnt->host)->SCint[i]) {
 			if (HOSTDATA(SCpnt->host)->SCint[i] == SCpnt) {
 				printk(KERN_ERR "Timed out command pending for %s\n",
-				       kdevname(SCpnt->request->rq_dev));
+				       SCpnt->request->rq_disk ?
+				       SCpnt->request->rq_disk->disk_name : "?"
+				       );
 				if (HOSTDATA(SCpnt->host)->mb[i].status) {
 					printk(KERN_ERR "OGMB still full - restarting\n");
 					aha1542_out(SCpnt->host->io_port, &ahacmd, 1);
 				};
 			} else
 				printk(KERN_ERR "Other pending command %s\n",
-				       kdevname(SCpnt->request->rq_dev));
+				       SCpnt->request->rq_disk ?
+				       SCpnt->request->rq_disk->disk_name : "?"
+				       );
 		}
 #endif
 
diff -Nru a/drivers/scsi/aic7xxx/Makefile b/drivers/scsi/aic7xxx/Makefile
--- a/drivers/scsi/aic7xxx/Makefile	Mon Nov  4 14:31:03 2002
+++ b/drivers/scsi/aic7xxx/Makefile	Mon Nov  4 14:31:03 2002
@@ -1,6 +1,8 @@
 #
 # Makefile for the Linux aic7xxx SCSI driver.
 #
+# Let kbuild descend into aicasm when cleaning
+subdir-				+= aicasm
 
 obj-$(CONFIG_SCSI_AIC7XXX)	+= aic7xxx.o
 
@@ -23,11 +25,6 @@
 # Files generated that shall be removed upon make clean
 clean-files := aic7xxx_seq.h aic7xxx_reg.h
 
-# Command to be executed upon make clean
-clean-rule := $(MAKE) -C $(src)/aicasm clean
-
-include $(TOPDIR)/Rules.make
-
 # Dependencies for generated files need to be listed explicitly
 
 $(obj)/aic7xxx_core.o: $(obj)/aic7xxx_seq.h
@@ -41,7 +38,7 @@
 	$(obj)/aicasm/aicasm -I$(obj) -r $(obj)/aic7xxx_reg.h \
 				 -o $(obj)/aic7xxx_seq.h $(src)/aic7xxx.seq
 
-$(obj)/aic7xxx_reg.h: $(obj)/aix7xxx_seq.h
+$(obj)/aic7xxx_reg.h: $(obj)/aic7xxx_seq.h
 
 $(obj)/aicasm/aicasm: $(src)/aicasm/*.[chyl]
 	$(MAKE) -C $(src)/aicasm
diff -Nru a/drivers/scsi/aic7xxx/aicasm/Makefile b/drivers/scsi/aic7xxx/aicasm/Makefile
--- a/drivers/scsi/aic7xxx/aicasm/Makefile	Mon Nov  4 14:31:02 2002
+++ b/drivers/scsi/aic7xxx/aicasm/Makefile	Mon Nov  4 14:31:02 2002
@@ -7,7 +7,9 @@
 GENHDRS= y.tab.h aicdb.h
 
 SRCS=	${GENSRCS} ${CSRCS}
-CLEANFILES= ${GENSRCS} ${GENHDRS} y.output
+
+# Cleaned up by make clean
+clean-files := $(GENSRCS) $(GENHDRS) y.output $(PROG)
 # Override default kernel CFLAGS.  This is a userland app.
 AICASM_CFLAGS:= -I/usr/include -I. -ldb
 YFLAGS= -d
@@ -41,9 +43,6 @@
 	 else							\
 		echo "*** Install db development libraries";	\
 	 fi
-
-clean:
-	@rm -f $(CLEANFILES) $(PROG)
 
 y.tab.h aicasm_gram.c: aicasm_gram.y
 	$(YACC) $(YFLAGS) aicasm_gram.y
diff -Nru a/drivers/scsi/constants.c b/drivers/scsi/constants.c
--- a/drivers/scsi/constants.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/scsi/constants.c	Mon Nov  4 14:31:02 2002
@@ -905,12 +905,13 @@
 static void
 print_sense_internal(const char * devclass, 
 		     const unsigned char * sense_buffer,
-		     kdev_t dev)
+		     struct request *req)
 {
 	int s, sense_class, valid, code, info;
 	const char * error = NULL;
 	unsigned char asc, ascq;
 	const char *sense_txt;
+	char *name = req->rq_disk ? req->rq_disk->disk_name : "?";
     
 	sense_class = (sense_buffer[0] >> 4) & 0x07;
 	code = sense_buffer[0] & 0xf;
@@ -954,10 +955,10 @@
 		sense_txt = scsi_sense_key_string(sense_buffer[2]);
 		if (sense_txt)
 			printk("%s%s: sense key %s\n",
-			       devclass, kdevname(dev), sense_txt);
+			       devclass, name, sense_txt);
 		else
 			printk("%s%s: sense = %2x %2x\n",
-			       devclass, kdevname(dev),
+			       devclass, name,
 			       sense_buffer[0], sense_buffer[2]);
 
 		asc = ascq = 0;
@@ -981,10 +982,10 @@
 		sense_txt = scsi_sense_key_string(sense_buffer[0]);
 		if (sense_txt)
 			printk("%s%s: old sense key %s\n",
-			       devclass, kdevname(dev), sense_txt);
+			       devclass, name, sense_txt);
 		else
 			printk("%s%s: sense = %2x %2x\n",
-			       devclass, kdevname(dev),
+			       devclass, name,
 			       sense_buffer[0], sense_buffer[2]);
 
 		printk("Non-extended sense class %d code 0x%0x\n",
@@ -1006,13 +1007,13 @@
 void print_sense(const char * devclass, Scsi_Cmnd * SCpnt)
 {
 	print_sense_internal(devclass, SCpnt->sense_buffer,
-			     SCpnt->request->rq_dev);
+			     SCpnt->request);
 }
 
 void print_req_sense(const char * devclass, Scsi_Request * SRpnt)
 {
 	print_sense_internal(devclass, SRpnt->sr_sense_buffer,
-			     SRpnt->sr_request->rq_dev);
+			     SRpnt->sr_request);
 }
 
 #if (CONSTANTS & CONST_MSG) 
diff -Nru a/drivers/scsi/eata.c b/drivers/scsi/eata.c
--- a/drivers/scsi/eata.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/scsi/eata.c	Mon Nov  4 14:31:02 2002
@@ -1,6 +1,17 @@
 /*
  *      eata.c - Low-level driver for EATA/DMA SCSI host adapters.
  *
+ *      28 Oct 2002 Rev. 8.00 for linux 2.5.44-ac4
+ *        + Use new tcq and adjust_queue_depth api.
+ *        + New command line option (tm:[0-2]) to choose the type of tags:
+ *          0 -> disable tagging ; 1 -> simple tags  ; 2 -> ordered tags.
+ *          Default is tm:0 (tagged commands disabled).
+ *          For compatibility the "tc:" option is an alias of the "tm:"
+ *          option; tc:n is equivalent to tm:0 and tc:y is equivalent to
+ *          tm:1.
+ *        + The tagged_comm module parameter has been removed, use tag_mode
+ *          instead, equivalent to the "tm:" boot option.
+ *
  *      10 Oct 2002 Rev. 7.70 for linux 2.5.42
  *        + Foreport from revision 6.70.
  *
@@ -362,24 +373,21 @@
  *  rs:n  use BIOS order while detecting PCI boards;
  *  lc:y  enables linked commands;
  *  lc:n  disables linked commands;
- *  tc:y  enables tagged commands;
- *  tc:n  disables tagged commands;
- *  tm:0  use head/simple/ordered queue tag sequences;
- *  tm:1  use only simple queue tags;
- *  tm:2  use only head of queue tags;
- *  tm:3  use only ordered queue tags;
+ *  tm:0  disables tagged commands (same as tc:n);
+ *  tm:1  use simple queue tags (same as tc:y);
+ *  tm:2  use ordered queue tags (same as tc:2);
  *  mq:xx set the max queue depth to the value xx (2 <= xx <= 32).
  *
- *  The default value is: "eata=lc:n,tc:n,mq:16,tm:0,et:n,rs:n".
+ *  The default value is: "eata=lc:n,mq:16,tm:0,et:n,rs:n".
  *  An example using the list of detection probes could be:
- *  "eata=0x7410,0x230,lc:y,tc:n,mq:4,et:n".
+ *  "eata=0x7410,0x230,lc:y,tm:2,mq:4,et:n".
  *
  *  When loading as a module, parameters can be specified as well.
  *  The above example would be (use 1 in place of y and 0 in place of n):
  *
- *  modprobe eata io_port=0x7410,0x230 linked_comm=1 tagged_comm=0 \
- *                max_queue_depth=4 tag_mode=0 \
- *                ext_tran=0 rev_scan=1
+ *  modprobe eata io_port=0x7410,0x230 linked_comm=1 \
+ *                max_queue_depth=4 ext_tran=0 tag_mode=2 \
+ *                rev_scan=1
  *
  *  ----------------------------------------------------------------------------
  *  In this implementation, linked commands are designed to work with any DISK
@@ -447,15 +455,11 @@
 MODULE_PARM(boot_options, "s");
 MODULE_PARM(io_port, "1-" __MODULE_STRING(MAX_INT_PARAM) "i");
 MODULE_PARM(linked_comm, "i");
-MODULE_PARM(tagged_comm, "i");
 MODULE_PARM(link_statistics, "i");
 MODULE_PARM(max_queue_depth, "i");
 MODULE_PARM(tag_mode, "i");
 MODULE_PARM(ext_tran, "i");
 MODULE_PARM(rev_scan, "i");
-MODULE_PARM(isa_probe, "i");
-MODULE_PARM(eisa_probe, "i");
-MODULE_PARM(pci_probe, "i");
 MODULE_AUTHOR("Dario Ballabio");
 
 #endif
@@ -472,6 +476,7 @@
 #include <linux/blk.h>
 #include "scsi.h"
 #include "hosts.h"
+#include "sd.h"
 #include <asm/dma.h>
 #include <asm/irq.h>
 #include "eata.h"
@@ -481,6 +486,7 @@
 #include <linux/init.h>
 #include <linux/ctype.h>
 #include <linux/spinlock.h>
+#include <scsi/scsicam.h>
 
 #if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD)
 #error "Adjust your <asm/byteorder.h> defines"
@@ -528,10 +534,9 @@
 #define ABORTING 6
 #define NO_DMA  0xff
 #define MAXLOOP  10000
-#define TAG_MIXED    0
+#define TAG_DISABLED 0
 #define TAG_SIMPLE   1
-#define TAG_HEAD     2
-#define TAG_ORDERED  3
+#define TAG_ORDERED  2
 
 #define REG_CMD         7
 #define REG_STATUS      7
@@ -543,7 +548,7 @@
 #define REG_LM          3
 #define REG_MID         4
 #define REG_MSB         5
-#define REGION_SIZE     9UL
+#define REGION_SIZE     9
 #define MAX_ISA_ADDR    0x03ff
 #define MIN_EISA_ADDR   0x1c88
 #define MAX_EISA_ADDR   0xfc88
@@ -567,7 +572,7 @@
 #define TLDEV(type) ((type) == TYPE_DISK || (type) == TYPE_ROM)
 
 /* "EATA", in Big Endian format */
-#define EATA_SIG_BE 0x45415441
+#define EATA_SIGNATURE 0x41544145
 
 /* Number of valid bytes in the board config structure for EATA 2.0x */
 #define EATA_2_0A_SIZE 28
@@ -578,12 +583,6 @@
 struct eata_info {
    u_int32_t data_len;  /* Number of valid bytes after this field */
    u_int32_t sign;      /* ASCII "EATA" signature */
-
-#if defined(__BIG_ENDIAN_BITFIELD)
-   unchar version:4, :4;
-   unchar  haaval:1, ata:1, drqvld:1, dmasup:1, morsup:1, trnxfr:1, tarsup:1,
-           ocsena:1;
-#else
    unchar        :4,    /* unused low nibble */
           version:4;    /* EATA version, should be 0x1 */
    unchar  ocsena:1,    /* Overlap Command Support Enabled */
@@ -594,8 +593,6 @@
            drqvld:1,    /* DRQ Index (DRQX) is valid */
               ata:1,    /* This is an ATA device */
            haaval:1;    /* Host Adapter Address Valid */
-#endif
-
    ushort cp_pad_len;   /* Number of pad bytes after cp_len */
    unchar host_addr[4]; /* Host Adapter SCSI ID for channels 3, 2, 1, 0 */
    u_int32_t cp_len;    /* Number of valid bytes in cp */
@@ -603,15 +600,6 @@
    ushort queue_size;   /* Max number of cp that can be queued */
    ushort unused;
    ushort scatt_size;   /* Max number of entries in scatter/gather table */
-
-#if defined(__BIG_ENDIAN_BITFIELD)
-   unchar    drqx:2, second:1, irq_tr:1, irq:4;
-   unchar  sync;
-   unchar         :4, res1:1, large_sg:1, forcaddr:1, isaena:1;
-   unchar max_chan:3, max_id:5;
-   unchar   max_lun;
-   unchar     eisa:1, pci:1, idquest:1, m1:1, :4;
-#else
    unchar     irq:4,    /* Interrupt Request assigned to this controller */
            irq_tr:1,    /* 0 for edge triggered, 1 for level triggered */
            second:1,    /* 1 if this is a secondary (not primary) controller */
@@ -634,8 +622,6 @@
           idquest:1,    /* RAIDNUM returned is questionable */
               pci:1,    /* This board is PCI */
              eisa:1;    /* This board is EISA */
-#endif
-
    unchar   raidnum;    /* Uniquely identifies this HBA in a system */
    unchar   notused;
 
@@ -645,30 +631,18 @@
 /* Board config structure */
 struct eata_config {
    ushort len;          /* Number of bytes following this field */
-
-#if defined(__BIG_ENDIAN_BITFIELD)
-   unchar     :4, tarena:1, mdpena:1, ocena:1, edis:1;
-#else
    unchar edis:1,       /* Disable EATA interface after config command */
          ocena:1,       /* Overlapped Commands Enabled */
         mdpena:1,       /* Transfer all Modified Data Pointer Messages */
         tarena:1,       /* Target Mode Enabled for this controller */
               :4;
-#endif
-
    unchar cpad[511];
    };
 
 /* Returned status packet structure */
 struct mssp {
-
-#if defined(__BIG_ENDIAN_BITFIELD)
-   unchar            eoc:1, adapter_status:7;
-#else
    unchar adapter_status:7,    /* State related to current command */
                      eoc:1;    /* End Of Command (1 = command completed) */
-#endif
-
    unchar target_status;       /* SCSI status received after data transfer */
    unchar unused[2];
    u_int32_t inv_res_len;      /* Number of bytes not transferred */
@@ -683,16 +657,6 @@
 
 /* MailBox SCSI Command Packet */
 struct mscp {
-
-#if defined(__BIG_ENDIAN_BITFIELD)
-   unchar     din:1, dout:1, interp:1, :1, sg:1, reqsen:1, init:1, sreset:1;
-   unchar sense_len;
-   unchar unused[3];
-   unchar        :7, fwnest:1;
-   unchar        :5, hbaci:1, iat:1, phsunit:1;
-   unchar channel:3, target:5;
-   unchar     one:1, dispri:1, luntar:1, lun:5;
-#else
    unchar  sreset:1,     /* SCSI Bus Reset Signal should be asserted */
              init:1,     /* Re-initialize controller and self test */
            reqsen:1,     /* Transfer Request Sense Data to addr using DMA */
@@ -715,8 +679,6 @@
            luntar:1,     /* This cp is for Target (not LUN) */
            dispri:1,     /* Disconnect Privilege granted */
               one:1;     /* 1 */
-#endif
-
    unchar mess[3];       /* Massage to/from Target */
    unchar cdb[12];       /* Command Descriptor Block */
    u_int32_t data_len;   /* If sg=0 Data Length, if sg=1 sglist length */
@@ -793,28 +755,22 @@
 #define BN(board) (HD(board)->board_name)
 
 /* Device is Big Endian */
-#define H2DEV(x)   cpu_to_be32(x)
-#define DEV2H(x)   be32_to_cpu(x)
-#define H2DEV16(x) cpu_to_be16(x)
-#define DEV2H16(x) be16_to_cpu(x)
-
-/* But transfer orientation from the 16 bit data register is Little Endian */
-#define REG2H(x)   le16_to_cpu(x)
+#define H2DEV(x) cpu_to_be32(x)
+#define DEV2H(x) be32_to_cpu(x)
 
 static void do_interrupt_handler(int, void *, struct pt_regs *);
 static void flush_dev(Scsi_Device *, unsigned long, unsigned int, unsigned int);
 static int do_trace = FALSE;
 static int setup_done = FALSE;
 static int link_statistics;
-static int tag_mode = TAG_MIXED;
 static int ext_tran = FALSE;
 static int rev_scan = TRUE;
 static char *boot_options;
 
 #if defined(CONFIG_SCSI_EATA_TAGGED_QUEUE)
-static int tagged_comm = TRUE;
+static int tag_mode = TAG_SIMPLE;
 #else
-static int tagged_comm = FALSE;
+static int tag_mode = TAG_DISABLED;
 #endif
 
 #if defined(CONFIG_SCSI_EATA_LINKED_COMMANDS)
@@ -846,38 +802,57 @@
 #else
 static int pci_probe = FALSE;
 #endif
- 
+
 static int eata2x_slave_attach(Scsi_Device *dev) {
    int j, tqd, utqd;
-   char *link_suffix = "";
+   char *tag_suffix, *link_suffix;
    struct Scsi_Host *host = dev->host;
 
    j = ((struct hostdata *) host->hostdata)->board_number;
 
    utqd = MAX_CMD_PER_LUN;
-   tqd = (host->can_queue - utqd);
+   tqd = max_queue_depth;
 
-   if (TLDEV(dev->type) && (dev->tagged_supported || linked_comm)) {
-      if(!dev->tagged_supported)
-         scsi_adjust_queue_depth(dev, 0, tqd);
-      else
+   if (TLDEV(dev->type) && dev->tagged_supported)
+
+      if (tag_mode == TAG_SIMPLE) {
          scsi_adjust_queue_depth(dev, MSG_SIMPLE_TAG, tqd);
-   } else {
+         tag_suffix = ", simple tags";
+         }
+      else if (tag_mode == TAG_ORDERED) {
+         scsi_adjust_queue_depth(dev, MSG_ORDERED_TAG, tqd);
+         tag_suffix = ", ordered tags";
+         }
+      else {
+         scsi_adjust_queue_depth(dev, 0, tqd);
+         tag_suffix = ", no tags";
+         }
+
+   else if (TLDEV(dev->type) && linked_comm) {
+      scsi_adjust_queue_depth(dev, 0, tqd);
+      tag_suffix = ", untagged";
+      }
+
+   else {
       scsi_adjust_queue_depth(dev, 0, utqd);
-   }
+      tag_suffix = "";
+      }
 
-   if (!dev->simple_tags && dev->new_queue_depth > 2)
+   if (TLDEV(dev->type) && linked_comm && dev->new_queue_depth > 2)
       link_suffix = ", sorted";
-   else if (dev->simple_tags)
+   else if (TLDEV(dev->type))
       link_suffix = ", unsorted";
+   else
+      link_suffix = "";
 
-   printk("%s: scsi%d, channel %d, id %d, lun %d, cmds/lun %d%s.\n",
+   printk("%s: scsi%d, channel %d, id %d, lun %d, cmds/lun %d%s%s.\n",
           BN(j), host->host_no, dev->channel, dev->id, dev->lun,
-          dev->new_queue_depth, link_suffix);
-   return 0;
+          dev->new_queue_depth, link_suffix, tag_suffix);
+
+   return FALSE;
 }
 
-static inline int wait_on_busy(unsigned long iobase, unsigned int loop) {
+static int wait_on_busy(unsigned long iobase, unsigned int loop) {
 
    while (inb(iobase + REG_AUX_STATUS) & ABSY_ASSERTED) {
       udelay(1L);
@@ -887,7 +862,7 @@
    return FALSE;
 }
 
-static inline int do_dma(unsigned long iobase, unsigned long addr, unchar cmd) {
+static int do_dma(unsigned long iobase, unsigned long addr, unchar cmd) {
    unsigned char *byaddr;
    unsigned long devaddr;
 
@@ -906,7 +881,7 @@
    return FALSE;
 }
 
-static inline int read_pio(unsigned long iobase, ushort *start, ushort *end) {
+static int read_pio(unsigned long iobase, ushort *start, ushort *end) {
    unsigned int loop = MAXLOOP;
    ushort *p;
 
@@ -918,13 +893,13 @@
          }
 
       loop = MAXLOOP;
-      *p = REG2H(inw(iobase));
+      *p = inw(iobase);
       }
 
    return FALSE;
 }
 
-static inline struct pci_dev *get_pci_dev(unsigned long port_base) {
+static struct pci_dev *get_pci_dev(unsigned long port_base) {
 
 #if defined(CONFIG_PCI)
 
@@ -972,12 +947,12 @@
 #endif /* end CONFIG_PCI */
 }
 
-static inline int port_detect \
+static int port_detect \
       (unsigned long port_base, unsigned int j, Scsi_Host_Template *tpnt) {
    unsigned char irq, dma_channel, subversion, i, is_pci = FALSE;
    unsigned char protocol_rev;
    struct eata_info info;
-   char *bus_type, dma_name[16], tag_type;
+   char *bus_type, dma_name[16];
    struct pci_dev *pdev;
 
    /* Allowed DMA channels for ISA (0 indicates reserved) */
@@ -995,48 +970,31 @@
       }
 
    if (do_dma(port_base, 0, READ_CONFIG_PIO)) {
-#if defined(DEBUG_DETECT)
-      printk("%s: detect, do_dma failed at 0x%03lx.\n", name, port_base);
-#endif
       release_region(port_base, REGION_SIZE);
       return FALSE;
       }
 
    /* Read the info structure */
    if (read_pio(port_base, (ushort *)&info, (ushort *)&info.ipad[0])) {
-#if defined(DEBUG_DETECT)
-      printk("%s: detect, read_pio failed at 0x%03lx.\n", name, port_base);
-#endif
       release_region(port_base, REGION_SIZE);
       return FALSE;
       }
 
-   info.data_len = DEV2H(info.data_len);
-   info.sign = DEV2H(info.sign);
-   info.cp_pad_len = DEV2H16(info.cp_pad_len);
-   info.cp_len = DEV2H(info.cp_len);
-   info.sp_len = DEV2H(info.sp_len);
-   info.scatt_size = DEV2H16(info.scatt_size);
-   info.queue_size = DEV2H16(info.queue_size);
-
    /* Check the controller "EATA" signature */
-   if (info.sign != EATA_SIG_BE) {
-#if defined(DEBUG_DETECT)
-      printk("%s: signature 0x%04x discarded.\n", name, info.sign);
-#endif
+   if (info.sign != EATA_SIGNATURE) {
       release_region(port_base, REGION_SIZE);
       return FALSE;
       }
 
-   if (info.data_len < EATA_2_0A_SIZE) {
+   if (DEV2H(info.data_len) < EATA_2_0A_SIZE) {
       printk("%s: config structure size (%d bytes) too short, detaching.\n",
-             name, info.data_len);
+             name, DEV2H(info.data_len));
       release_region(port_base, REGION_SIZE);
       return FALSE;
       }
-   else if (info.data_len == EATA_2_0A_SIZE)
+   else if (DEV2H(info.data_len) == EATA_2_0A_SIZE)
       protocol_rev = 'A';
-   else if (info.data_len == EATA_2_0B_SIZE)
+   else if (DEV2H(info.data_len) == EATA_2_0B_SIZE)
       protocol_rev = 'B';
    else
       protocol_rev = 'C';
@@ -1148,7 +1106,7 @@
 
    /* Set board configuration */
    memset((char *)cf, 0, sizeof(struct eata_config));
-   cf->len = (ushort) H2DEV16((ushort)510);
+   cf->len = (ushort) cpu_to_be16((ushort)510);
    cf->ocena = TRUE;
 
    if (do_dma(port_base, cf_dma_addr, SET_CONFIG_DMA)) {
@@ -1179,9 +1137,9 @@
    sh[j]->n_io_port = REGION_SIZE;
    sh[j]->dma_channel = dma_channel;
    sh[j]->irq = irq;
-   sh[j]->sg_tablesize = (ushort) info.scatt_size;
+   sh[j]->sg_tablesize = (ushort) be16_to_cpu(info.scatt_size);
    sh[j]->this_id = (ushort) info.host_addr[3];
-   sh[j]->can_queue = (ushort) info.queue_size;
+   sh[j]->can_queue = (ushort) be16_to_cpu(info.queue_size);
    sh[j]->cmd_per_lun = MAX_CMD_PER_LUN;
    memset(HD(j), 0, sizeof(struct hostdata));
    HD(j)->subversion = subversion;
@@ -1268,18 +1226,13 @@
 
    if (max_queue_depth < MAX_CMD_PER_LUN) max_queue_depth = MAX_CMD_PER_LUN;
 
-   if (tagged_comm) {
-      if      (tag_mode == TAG_SIMPLE)  tag_type = '1';
-      else if (tag_mode == TAG_HEAD)    tag_type = '2';
-      else if (tag_mode == TAG_ORDERED) tag_type = '3';
-      else                              tag_type = 'y';
-      }
-   else                                 tag_type = 'n';
+   if (tag_mode != TAG_DISABLED && tag_mode != TAG_SIMPLE)
+      tag_mode = TAG_ORDERED;
 
    if (j == 0) {
       printk("EATA/DMA 2.0x: Copyright (C) 1994-2002 Dario Ballabio.\n");
-      printk("%s config options -> tc:%c, lc:%c, mq:%d, rs:%c, et:%c, "\
-             "ip:%c, ep:%c, pp:%c.\n", driver_name, tag_type,
+      printk("%s config options -> tm:%d, lc:%c, mq:%d, rs:%c, et:%c, "\
+             "ip:%c, ep:%c, pp:%c.\n", driver_name, tag_mode,
              YESNO(linked_comm), max_queue_depth, YESNO(rev_scan),
              YESNO(ext_tran), YESNO(isa_probe), YESNO(eisa_probe),
              YESNO(pci_probe));
@@ -1301,8 +1254,8 @@
    printk("%s: Vers. 0x%x, ocs %u, tar %u, trnxfr %u, more %u, SYNC 0x%x, "\
           "sec. %u, infol %d, cpl %d spl %d.\n", name, info.version,
           info.ocsena, info.tarsup, info.trnxfr, info.morsup, info.sync,
-          info.second, info.data_len, info.cp_len,
-          info.sp_len);
+          info.second, DEV2H(info.data_len), DEV2H(info.cp_len),
+          DEV2H(info.sp_len));
 
    if (protocol_rev == 'B' || protocol_rev == 'C')
       printk("%s: isaena %u, forcaddr %u, max_id %u, max_chan %u, "\
@@ -1346,15 +1299,12 @@
       else val = (int) simple_strtoul(pc, NULL, 0);
 
       if (!strncmp(cur, "lc:", 3)) linked_comm = val;
-      else if (!strncmp(cur, "tc:", 3)) tagged_comm = val;
       else if (!strncmp(cur, "tm:", 3)) tag_mode = val;
+      else if (!strncmp(cur, "tc:", 3)) tag_mode = val;
       else if (!strncmp(cur, "mq:", 3))  max_queue_depth = val;
       else if (!strncmp(cur, "ls:", 3))  link_statistics = val;
       else if (!strncmp(cur, "et:", 3))  ext_tran = val;
       else if (!strncmp(cur, "rs:", 3))  rev_scan = val;
-      else if (!strncmp(cur, "ip:", 3))  isa_probe = val;
-      else if (!strncmp(cur, "ep:", 3))  eisa_probe = val;
-      else if (!strncmp(cur, "pp:", 3))  pci_probe = val;
 
       if ((cur = strchr(cur, ','))) ++cur;
       }
@@ -1419,7 +1369,7 @@
    return;
 }
 
-int eata2x_detect(Scsi_Host_Template *tpnt) {
+static int eata2x_detect(Scsi_Host_Template *tpnt) {
    unsigned int j = 0, k;
    unsigned long spin_flags;
 
@@ -1439,19 +1389,7 @@
 
    for (k = 0; k < MAX_BOARDS + 1; k++) sh[k] = NULL;
 
-   for (k = MAX_INT_PARAM; io_port[k]; k++)
-      if (io_port[k] == SKIP) continue;
-      else if (io_port[k] <= MAX_ISA_ADDR) {
-         if (!isa_probe) io_port[k] = SKIP;
-         }
-      else if (io_port[k] >= MIN_EISA_ADDR && io_port[k] <= MAX_EISA_ADDR) {
-         if (!eisa_probe) io_port[k] = SKIP;
-         }
-
-   if (pci_probe) {
-      if (!setup_done) add_pci_ports();
-      else          enable_pci_ports();
-      }
+   if (!setup_done) add_pci_ports();
 
    for (k = 0; io_port[k]; k++) {
 
@@ -1465,7 +1403,7 @@
    return j;
 }
 
-static inline void map_dma(unsigned int i, unsigned int j) {
+static void map_dma(unsigned int i, unsigned int j) {
    unsigned int k, count, pci_dir;
    struct scatterlist *sgpnt;
    struct mscp *cpp;
@@ -1552,7 +1490,7 @@
                        DEV2H(cpp->data_len), pci_dir);
 }
 
-static inline void scsi_to_dev_dir(unsigned int i, unsigned int j) {
+static void scsi_to_dev_dir(unsigned int i, unsigned int j) {
    unsigned int k;
 
    static const unsigned char data_out_cmds[] = {
@@ -1606,7 +1544,7 @@
 
 }
 
-static inline int do_qcomm(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
+static int eata2x_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
    unsigned int i, j, k;
    struct mscp *cpp;
 
@@ -1670,25 +1608,8 @@
    /* Map DMA buffers and SG list */
    map_dma(i, j);
 
-   if (SCpnt->device->simple_tags) {
-
-      if (HD(j)->target_redo[SCpnt->target][SCpnt->channel] ||
-            HD(j)->target_to[SCpnt->target][SCpnt->channel])
-         cpp->mess[0] = ORDERED_QUEUE_TAG;
-      else if (tag_mode == TAG_SIMPLE)  cpp->mess[0] = SIMPLE_QUEUE_TAG;
-      else if (tag_mode == TAG_HEAD)    cpp->mess[0] = HEAD_OF_QUEUE_TAG;
-      else if (tag_mode == TAG_ORDERED) cpp->mess[0] = ORDERED_QUEUE_TAG;
-      else if (SCpnt->device->current_tag == 0)
-         cpp->mess[0] = ORDERED_QUEUE_TAG;
-      else if (SCpnt->device->current_tag == 1)
-         cpp->mess[0] = HEAD_OF_QUEUE_TAG;
-      else
-         cpp->mess[0] = SIMPLE_QUEUE_TAG;
-
-      cpp->mess[1] = SCpnt->device->current_tag++;
-      }
-
-   if (SCpnt->device->new_queue_depth > 2 && !SCpnt->device->simple_tags) {
+   if (linked_comm && SCpnt->device->new_queue_depth > 2
+                                     && TLDEV(SCpnt->device->type)) {
       HD(j)->cp_stat[i] = READY;
       flush_dev(SCpnt->device, SCpnt->request->sector, j, FALSE);
       return 0;
@@ -1707,14 +1628,7 @@
    return 0;
 }
 
-int eata2x_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
-   int rtn;
-
-   rtn = do_qcomm(SCpnt, done);
-   return rtn;
-}
-
-static inline int do_abort(Scsi_Cmnd *SCarg) {
+static int eata2x_eh_abort(Scsi_Cmnd *SCarg) {
    unsigned int i, j;
 
    j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
@@ -1788,12 +1702,7 @@
    panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i);
 }
 
-int eata2x_abort(Scsi_Cmnd *SCarg) {
-
-   return do_abort(SCarg);
-}
-
-static inline int do_reset(Scsi_Cmnd *SCarg) {
+static int eata2x_eh_host_reset(Scsi_Cmnd *SCarg) {
    unsigned int i, j, time, k, c, limit = 0;
    int arg_done = FALSE;
    Scsi_Cmnd *SCpnt;
@@ -1925,23 +1834,18 @@
    return SUCCESS;
 }
 
-int eata2x_reset(Scsi_Cmnd *SCarg) {
-
-   return do_reset(SCarg);
-}
-
-int eata2x_biosparam(struct scsi_device *sdev, struct block_device *bdev,
+int eata2x_bios_param(struct scsi_device *sdev, struct block_device *bdev, 
 		sector_t capacity, int *dkinfo) {
    int size = capacity;
 
-   if (ext_tran || (scsicam_bios_param(bdev, capacity, dkinfo) < 0)) {
+   if (ext_tran || (scsicam_bios_param(disk, bdev, dkinfo) < 0)) {
       dkinfo[0] = 255;
       dkinfo[1] = 63;
       dkinfo[2] = size / (dkinfo[0] * dkinfo[1]);
       }
 
 #if defined (DEBUG_GEOMETRY)
-   printk ("%s: biosparam, head=%d, sec=%d, cyl=%d.\n", driver_name,
+   printk ("%s: bios_param, head=%d, sec=%d, cyl=%d.\n", driver_name,
            dkinfo[0], dkinfo[1], dkinfo[2]);
 #endif
 
@@ -1973,7 +1877,7 @@
    return;
    }
 
-static inline int reorder(unsigned int j, unsigned long cursec,
+static int reorder(unsigned int j, unsigned long cursec,
                  unsigned int ihdlr, unsigned int il[], unsigned int n_ready) {
    Scsi_Cmnd *SCpnt;
    struct mscp *cpp;
@@ -2108,7 +2012,7 @@
 
 }
 
-static inline void ihdlr(int irq, unsigned int j) {
+static void ihdlr(int irq, unsigned int j) {
    Scsi_Cmnd *SCpnt;
    unsigned int i, k, c, status, tstatus, reg;
    struct mssp *spp;
@@ -2351,7 +2255,7 @@
    spin_unlock_irqrestore(sh[j]->host_lock, spin_flags);
 }
 
-int eata2x_release(struct Scsi_Host *shpnt) {
+static int eata2x_release(struct Scsi_Host *shpnt) {
    unsigned int i, j;
 
    for (j = 0; sh[j] != NULL && sh[j] != shpnt; j++);
diff -Nru a/drivers/scsi/eata.h b/drivers/scsi/eata.h
--- a/drivers/scsi/eata.h	Mon Nov  4 14:31:01 2002
+++ b/drivers/scsi/eata.h	Mon Nov  4 14:31:01 2002
@@ -1,34 +1,32 @@
 /*
  *        eata.h - used by the low-level driver for EATA/DMA SCSI host adapters.
  */
-#ifndef _EATA_H
-#define _EATA_H
 
-#include <scsi/scsicam.h>
-
-int eata2x_detect(Scsi_Host_Template *);
-int eata2x_release(struct Scsi_Host *);
-int eata2x_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int eata2x_abort(Scsi_Cmnd *);
-int eata2x_reset(Scsi_Cmnd *);
-int eata2x_biosparam(struct scsi_device *, struct block_device *,
+static int eata2x_detect(Scsi_Host_Template *);
+static int eata2x_release(struct Scsi_Host *);
+static int eata2x_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int eata2x_eh_abort(Scsi_Cmnd *);
+static int eata2x_eh_host_reset(Scsi_Cmnd *);
+static int eata2x_biosparam(struct scsi_device *, struct block_device *,
 		sector_t, int *);
 static int eata2x_slave_attach(Scsi_Device *);
 
-#define EATA_VERSION "7.70.00"
+#define EATA_VERSION "8.00.00"
 
 #define EATA {                                                               \
                 name:              "EATA/DMA 2.0x rev. " EATA_VERSION " ",   \
                 detect:                  eata2x_detect,                      \
                 release:                 eata2x_release,                     \
                 queuecommand:            eata2x_queuecommand,                \
-                eh_abort_handler:        eata2x_abort,                       \
-                eh_host_reset_handler:   eata2x_reset,                       \
-                bios_param:              eata2x_biosparam,                   \
+                abort:                   NULL,                               \
+                reset:                   NULL,                               \
+                eh_abort_handler:        eata2x_eh_abort,                    \
+                eh_device_reset_handler: NULL,                               \
+                eh_bus_reset_handler:    NULL,                               \
+                eh_host_reset_handler:   eata2x_eh_host_reset,               \
+                bios_param:              eata2x_bios_param,                  \
 		slave_attach:		 eata2x_slave_attach,		     \
                 this_id:                 7,                                  \
                 unchecked_isa_dma:       1,                                  \
-                use_clustering:          ENABLE_CLUSTERING,                  \
+                use_clustering:          ENABLE_CLUSTERING                   \
              }
-
-#endif
diff -Nru a/drivers/scsi/hosts.h b/drivers/scsi/hosts.h
--- a/drivers/scsi/hosts.h	Mon Nov  4 14:31:01 2002
+++ b/drivers/scsi/hosts.h	Mon Nov  4 14:31:01 2002
@@ -191,6 +191,13 @@
      int (*eh_host_reset_handler)(Scsi_Cmnd *);
 
     /*
+     * Old EH handlers, no longer used. Make them warn the user of old
+     * drivers by using a wrogn type
+     */
+    int (*abort)(int);
+    int (*reset)(int,int);
+
+    /*
      * Once the device has responded to an INQUIRY and we know the device
      * is online, call into the low level driver with the Scsi_Device *
      * (so that the low level driver may save it off in a safe location
@@ -560,9 +567,6 @@
     const char * tag;
     struct module * module;	  /* Used for loadable modules */
     unsigned char scsi_type;
-    unsigned int major;
-    unsigned int min_major;      /* Minimum major in range. */ 
-    unsigned int max_major;      /* Maximum major in range. */
     unsigned int nr_dev;	  /* Number currently attached */
     unsigned int dev_noticed;	  /* Number of devices detected. */
     unsigned int dev_max;	  /* Current size of arrays */
diff -Nru a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
--- a/drivers/scsi/ide-scsi.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/scsi/ide-scsi.c	Mon Nov  4 14:31:02 2002
@@ -489,7 +489,7 @@
 static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *rq, sector_t block)
 {
 #if IDESCSI_DEBUG_LOG
-	printk (KERN_INFO "rq_status: %d, rq_dev: %u, cmd: %d, errors: %d\n",rq->rq_status,(unsigned int) rq->rq_dev,rq->cmd,rq->errors);
+	printk (KERN_INFO "rq_status: %d, dev: %s, cmd: %d, errors: %d\n",rq->rq_status, rq->rq_disk->disk_name,rq->cmd,rq->errors);
 	printk (KERN_INFO "sector: %ld, nr_sectors: %ld, current_nr_sectors: %ld\n",rq->sector,rq->nr_sectors,rq->current_nr_sectors);
 #endif /* IDESCSI_DEBUG_LOG */
 
@@ -760,9 +760,13 @@
 static inline int should_transform(ide_drive_t *drive, Scsi_Cmnd *cmd)
 {
 	idescsi_scsi_t *scsi = drive->driver_data;
+	struct gendisk *disk = cmd->request->rq_disk;
 
-	if (major(cmd->request->rq_dev) == SCSI_GENERIC_MAJOR)
-		return test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);
+	if (disk) {
+		struct Scsi_Device_Template **p = disk->private_data;
+		if (strcmp((*p)->tag, "sg") == 0)
+			return test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);
+	}
 	return test_bit(IDESCSI_TRANSFORM, &scsi->transform);
 }
 
diff -Nru a/drivers/scsi/inia100.h b/drivers/scsi/inia100.h
--- a/drivers/scsi/inia100.h	Mon Nov  4 14:31:00 2002
+++ b/drivers/scsi/inia100.h	Mon Nov  4 14:31:00 2002
@@ -92,6 +92,8 @@
 	detect:		inia100_detect, \
 	release:	inia100_release, \
 	queuecommand:	inia100_queue, \
+	abort:		inia100_abort, \
+	reset:		inia100_reset, \
 	can_queue:	1, \
 	this_id:	1, \
 	sg_tablesize:	SG_ALL, \
diff -Nru a/drivers/scsi/ncr53c8xx.h b/drivers/scsi/ncr53c8xx.h
--- a/drivers/scsi/ncr53c8xx.h	Mon Nov  4 14:31:01 2002
+++ b/drivers/scsi/ncr53c8xx.h	Mon Nov  4 14:31:01 2002
@@ -76,6 +76,8 @@
 			info:           ncr53c8xx_info, 	\
 			queuecommand:   ncr53c8xx_queue_command,\
 			slave_attach:   ncr53c8xx_slave_attach, \
+			abort:          ncr53c8xx_abort,	\
+			reset:          ncr53c8xx_reset,	\
 			can_queue:      SCSI_NCR_CAN_QUEUE,	\
 			this_id:        7,			\
 			sg_tablesize:   SCSI_NCR_SG_TABLESIZE,	\
diff -Nru a/drivers/scsi/osst.c b/drivers/scsi/osst.c
--- a/drivers/scsi/osst.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/scsi/osst.c	Mon Nov  4 14:31:01 2002
@@ -162,7 +162,6 @@
        name:		"OnStream tape",
        tag:		"osst",
        scsi_type:	TYPE_TAPE,
-       major:		OSST_MAJOR,
        detect:		osst_detect,
        init:		osst_init,
        attach:		osst_attach,
@@ -179,13 +178,18 @@
 
 static int osst_write_error_recovery(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int pending);
 
+static inline char *tape_name(OS_Scsi_Tape *tape)
+{
+	return tape->disk->disk_name;
+}
+
 
 /* Routines that handle the interaction with mid-layer SCSI routines */
 
 /* Convert the result to success code */
 static int osst_chk_result(OS_Scsi_Tape * STp, Scsi_Request * SRpnt)
 {
-	int dev = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 	int result = SRpnt->sr_result;
 	unsigned char * sense = SRpnt->sr_sense_buffer, scode;
 #if DEBUG
@@ -205,8 +209,8 @@
 
 #if DEBUG
 	if (debugging) {
-		printk(OSST_DEB_MSG "osst%d:D: Error: %x, cmd: %x %x %x %x %x %x Len: %d\n",
-		   dev, result,
+		printk(OSST_DEB_MSG "%s:D: Error: %x, cmd: %x %x %x %x %x %x Len: %d\n",
+		   name, result,
 		   SRpnt->sr_cmnd[0], SRpnt->sr_cmnd[1], SRpnt->sr_cmnd[2],
 		   SRpnt->sr_cmnd[3], SRpnt->sr_cmnd[4], SRpnt->sr_cmnd[5],
 		   SRpnt->sr_bufflen);
@@ -225,22 +229,22 @@
 		 SRpnt->sr_cmnd[0] != MODE_SENSE &&
 		 SRpnt->sr_cmnd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */
 		if (driver_byte(result) & DRIVER_SENSE) {
-			printk(KERN_WARNING "osst%d:W: Command with sense data: ", dev);
+			printk(KERN_WARNING "%s:W: Command with sense data: ", name);
 			print_req_sense("osst:", SRpnt);
 		}
 		else {
 			static	int	notyetprinted = 1;
 
 			printk(KERN_WARNING
-			     "osst%d:W: Warning %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n",
-			     dev, result, suggestion(result), driver_byte(result) & DRIVER_MASK,
+			     "%s:W: Warning %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n",
+			     name, result, suggestion(result), driver_byte(result) & DRIVER_MASK,
 			     host_byte(result));
 			if (notyetprinted) {
 				notyetprinted = 0;
 				printk(KERN_INFO
-					"osst%d:I: This warning may be caused by your scsi controller,\n", dev);
+					"%s:I: This warning may be caused by your scsi controller,\n", name);
 				printk(KERN_INFO
-					"osst%d:I: it has been reported with some Buslogic cards.\n", dev);
+					"%s:I: it has been reported with some Buslogic cards.\n", name);
 			}
 		}
 	}
@@ -256,8 +260,8 @@
 				stp = "write";
 			else
 				stp = "ioctl";
-			printk(OSST_DEB_MSG "osst%d:D: Recovered %s error (%d).\n", dev, stp,
-					     os_scsi_tapes[dev]->recover_count);
+			printk(OSST_DEB_MSG "%s:D: Recovered %s error (%d).\n", name, stp,
+					     STp->recover_count);
 		}
 #endif
 		if ((sense[2] & 0xe0) == 0)
@@ -270,33 +274,27 @@
 /* Wakeup from interrupt */
 static void osst_sleep_done (Scsi_Cmnd * SCpnt)
 {
-	unsigned int dev = TAPE_NR(SCpnt->request->rq_dev);
-	OS_Scsi_Tape * STp;
+	OS_Scsi_Tape * STp = container_of(SCpnt->request->rq_disk->private_data,
+					OS_Scsi_Tape, driver);
 
-	if (os_scsi_tapes && (STp = os_scsi_tapes[dev])) {
-		if ((STp->buffer)->writing &&
-		    (SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
-		    (SCpnt->sense_buffer[2] & 0x40)) {
-			/* EOM at write-behind, has all been written? */
-			if ((SCpnt->sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW)
-				(STp->buffer)->midlevel_result = SCpnt->result; /* Error */
-			else
-				(STp->buffer)->midlevel_result = INT_MAX;       /* OK */
-		}
+	if ((STp->buffer)->writing &&
+	    (SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
+	    (SCpnt->sense_buffer[2] & 0x40)) {
+		/* EOM at write-behind, has all been written? */
+		if ((SCpnt->sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW)
+			(STp->buffer)->midlevel_result = SCpnt->result; /* Error */
 		else
-			(STp->buffer)->midlevel_result = SCpnt->result;
-		SCpnt->request->rq_status = RQ_SCSI_DONE;
-		(STp->buffer)->last_SRpnt = SCpnt->sc_request;
-
-#if DEBUG
-		STp->write_pending = 0;
-#endif
-		complete(SCpnt->request->waiting);
+			(STp->buffer)->midlevel_result = INT_MAX;       /* OK */
 	}
+	else
+		(STp->buffer)->midlevel_result = SCpnt->result;
+	SCpnt->request->rq_status = RQ_SCSI_DONE;
+	(STp->buffer)->last_SRpnt = SCpnt->sc_request;
+
 #if DEBUG
-	else if (debugging)
-		printk(OSST_DEB_MSG "osst?:D: Illegal interrupt device %x\n", dev);
+	STp->write_pending = 0;
 #endif
+	complete(SCpnt->request->waiting);
 }
 
 
@@ -313,7 +311,7 @@
 #endif
 	if (SRpnt == NULL) {
 		if ((SRpnt = scsi_allocate_request(STp->device)) == NULL) {
-			printk(KERN_ERR "osst%d:E: Can't get SCSI request->\n", TAPE_NR(STp->devt));
+			printk(KERN_ERR "%s:E: Can't get SCSI request->\n", tape_name(STp));
 			if (signal_pending(current))
 				(STp->buffer)->syscall_result = (-EINTR);
 			else
@@ -336,7 +334,7 @@
 	SRpnt->sr_cmd_len = 0;
 	SRpnt->sr_request->waiting = &(STp->wait);
 	SRpnt->sr_request->rq_status = RQ_SCSI_BUSY;
-	SRpnt->sr_request->rq_dev = STp->devt;
+	SRpnt->sr_request->rq_disk = STp->disk;
 
 	scsi_do_req(SRpnt, (void *)cmd, bp, bytes, osst_sleep_done, timeout, retries);
 
@@ -352,7 +350,7 @@
 		      (STp->first_frame_position == 240 
 			         /* or STp->read_error_frame to fail again on the block calculated above */ &&
 				 ++repeat < 3))) {
-			printk(OSST_DEB_MSG "osst%d:D: Injecting read error\n", TAPE_NR(STp->devt));
+			printk(OSST_DEB_MSG "%s:D: Injecting read error\n", tape_name(STp));
 			STp->buffer->last_result_fatal = 1;
 		}
 #endif
@@ -466,10 +464,10 @@
  */
 static int osst_verify_frame(OS_Scsi_Tape * STp, int frame_seq_number, int quiet)
 {
+	char *name = tape_name(STp);
 	os_aux_t       * aux  = STp->buffer->aux;
 	os_partition_t * par  = &(aux->partition);
 	ST_partstat    * STps = &(STp->ps[STp->partition]);
-	int		 dev  = TAPE_NR(STp->devt);
 	int		 blk_cnt, blk_sz, i;
 
 	if (STp->raw) {
@@ -484,42 +482,42 @@
 	}
 	if (STp->buffer->syscall_result) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Skipping frame, read error\n", dev);
+		printk(OSST_DEB_MSG "%s:D: Skipping frame, read error\n", name);
 #endif
 		return 0;
 	}
 	if (ntohl(aux->format_id) != 0) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Skipping frame, format_id %u\n", dev, ntohl(aux->format_id));
+		printk(OSST_DEB_MSG "%s:D: Skipping frame, format_id %u\n", name, ntohl(aux->format_id));
 #endif
 		goto err_out;
 	}
 	if (memcmp(aux->application_sig, STp->application_sig, 4) != 0 &&
 	    (memcmp(aux->application_sig, "LIN3", 4) != 0 || STp->linux_media_version != 4)) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Skipping frame, incorrect application signature\n", dev);
+		printk(OSST_DEB_MSG "%s:D: Skipping frame, incorrect application signature\n", name);
 #endif
 		goto err_out;
 	}
 	if (par->partition_num != OS_DATA_PARTITION) {
 		if (!STp->linux_media || STp->linux_media_version != 2) {
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d:D: Skipping frame, partition num %d\n",
-					    dev, par->partition_num);
+			printk(OSST_DEB_MSG "%s:D: Skipping frame, partition num %d\n",
+					    name, par->partition_num);
 #endif
 			goto err_out;
 		}
 	}
 	if (par->par_desc_ver != OS_PARTITION_VERSION) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Skipping frame, partition version %d\n", dev, par->par_desc_ver);
+		printk(OSST_DEB_MSG "%s:D: Skipping frame, partition version %d\n", name, par->par_desc_ver);
 #endif
 		goto err_out;
 	}
 	if (ntohs(par->wrt_pass_cntr) != STp->wrt_pass_cntr) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Skipping frame, wrt_pass_cntr %d (expected %d)\n", 
-				    dev, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr);
+		printk(OSST_DEB_MSG "%s:D: Skipping frame, wrt_pass_cntr %d (expected %d)\n", 
+				    name, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr);
 #endif
 		goto err_out;
 	}
@@ -528,13 +526,13 @@
 	    aux->frame_type != OS_FRAME_TYPE_MARKER) {
 		if (!quiet)
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d:D: Skipping frame, frame type %x\n", dev, aux->frame_type);
+			printk(OSST_DEB_MSG "%s:D: Skipping frame, frame type %x\n", name, aux->frame_type);
 #endif
 		goto err_out;
 	}
 	if (aux->frame_type == OS_FRAME_TYPE_EOD &&
 	    STp->first_frame_position < STp->eod_frame_ppos) {
-		printk(KERN_INFO "osst%d:I: Skipping premature EOD frame %d\n", dev,
+		printk(KERN_INFO "%s:I: Skipping premature EOD frame %d\n", name,
 				 STp->first_frame_position);
 		goto err_out;
 	}
@@ -543,8 +541,8 @@
         if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) {
 		if (!quiet)
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d:D: Skipping frame, sequence number %u (expected %d)\n", 
-					    dev, ntohl(aux->frame_seq_num), frame_seq_number);
+			printk(OSST_DEB_MSG "%s:D: Skipping frame, sequence number %u (expected %d)\n", 
+					    name, ntohl(aux->frame_seq_num), frame_seq_number);
 #endif
 		goto err_out;
 	}
@@ -555,7 +553,7 @@
 		if (STp->header_cache != NULL && i < OS_FM_TAB_MAX && (i > STp->filemark_cnt ||
 		    STp->first_frame_position - 1 != ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i]))) {
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d:D: %s filemark %d at frame pos %d\n", dev,
+			printk(OSST_DEB_MSG "%s:D: %s filemark %d at frame pos %d\n", name,
 				  STp->header_cache->dat_fm_tab.fm_tab_ent[i] == 0?"Learned":"Corrected",
 				  i, STp->first_frame_position - 1);
 #endif
@@ -576,8 +574,8 @@
 		/* See what block size was used to write file */
 		if (STp->block_size != blk_sz && blk_sz > 0) {
 			printk(KERN_INFO
-	    	"osst%d:I: File was written with block size %d%c, currently %d%c, adjusted to match.\n",
-       				dev, blk_sz<1024?blk_sz:blk_sz/1024,blk_sz<1024?'b':'k',
+	    	"%s:I: File was written with block size %d%c, currently %d%c, adjusted to match.\n",
+       				name, blk_sz<1024?blk_sz:blk_sz/1024,blk_sz<1024?'b':'k',
 				STp->block_size<1024?STp->block_size:STp->block_size/1024,
 				STp->block_size<1024?'b':'k');
 			STp->block_size            = blk_sz;
@@ -605,9 +603,9 @@
 	long		startwait = jiffies;
 #if DEBUG
 	int		dbg = debugging;
-	int		dev  = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 
-	printk(OSST_DEB_MSG "osst%d:D: Reached onstream wait ready\n", dev);
+	printk(OSST_DEB_MSG "%s:D: Reached onstream wait ready\n", name);
 #endif
 
 	memset(cmd, 0, MAX_COMMAND_SIZE);
@@ -624,8 +622,8 @@
 		  SRpnt->sr_sense_buffer[13] == 0                                        )  )) {
 #if DEBUG
 	    if (debugging) {
-		printk(OSST_DEB_MSG "osst%d:D: Sleeping in onstream wait ready\n", dev);
-		printk(OSST_DEB_MSG "osst%d:D: Turning off debugging for a while\n", dev);
+		printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait ready\n", name);
+		printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
 		debugging = 0;
 	    }
 #endif
@@ -644,15 +642,15 @@
 	if ( STp->buffer->syscall_result &&
 	     osst_write_error_recovery(STp, aSRpnt, 0) ) {
 #if DEBUG
-	    printk(OSST_DEB_MSG "osst%d:D: Abnormal exit from onstream wait ready\n", dev);
-	    printk(OSST_DEB_MSG "osst%d:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", dev,
+	    printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait ready\n", name);
+	    printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
 			STp->buffer->syscall_result, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2],
 			SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
 #endif
 	    return (-EIO);
 	}
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d:D: Normal exit from onstream wait ready\n", dev);
+	printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait ready\n", name);
 #endif
 	return 0;
 }
@@ -667,9 +665,9 @@
 	long		startwait = jiffies;
 #if DEBUG
 	int		dbg = debugging;
-	int		dev  = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 
-	printk(OSST_DEB_MSG "osst%d:D: Reached onstream wait for medium\n", dev);
+	printk(OSST_DEB_MSG "%s:D: Reached onstream wait for medium\n", name);
 #endif
 
 	memset(cmd, 0, MAX_COMMAND_SIZE);
@@ -684,8 +682,8 @@
 	        SRpnt->sr_sense_buffer[13] == 0                                             ) {
 #if DEBUG
 	    if (debugging) {
-		printk(OSST_DEB_MSG "osst%d:D: Sleeping in onstream wait medium\n", dev);
-		printk(OSST_DEB_MSG "osst%d:D: Turning off debugging for a while\n", dev);
+		printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait medium\n", name);
+		printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
 		debugging = 0;
 	    }
 #endif
@@ -704,15 +702,15 @@
 	if ( STp->buffer->syscall_result     && SRpnt->sr_sense_buffer[2]  != 2 &&
 	     SRpnt->sr_sense_buffer[12] != 4 && SRpnt->sr_sense_buffer[13] == 1) {
 #if DEBUG
-	    printk(OSST_DEB_MSG "osst%d:D: Abnormal exit from onstream wait medium\n", dev);
-	    printk(OSST_DEB_MSG "osst%d:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", dev,
+	    printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait medium\n", name);
+	    printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
 			STp->buffer->syscall_result, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2],
 			SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
 #endif
 	    return 0;
 	}
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d:D: Normal exit from onstream wait medium\n", dev);
+	printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait medium\n", name);
 #endif
 	return 1;
 }
@@ -738,9 +736,9 @@
 
 	int             result = 0;
 #if DEBUG
-	int		dev  = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 
-	printk(OSST_DEB_MSG "osst%d:D: Reached onstream flush drive buffer (write filemark)\n", dev);
+	printk(OSST_DEB_MSG "%s:D: Reached onstream flush drive buffer (write filemark)\n", name);
 #endif
 
 	memset(cmd, 0, MAX_COMMAND_SIZE);
@@ -763,12 +761,12 @@
 static int osst_wait_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int curr, int minlast, int to)
 {
 	long	startwait     = jiffies;
-	int	dev	      = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 #if DEBUG
 	char	notyetprinted = 1;
 #endif
 	if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING)
-		printk(KERN_ERR "osst%i:A: Waiting for frame without having initialized read!\n", dev);
+		printk(KERN_ERR "%s:A: Waiting for frame without having initialized read!\n", name);
 
 	while (time_before (jiffies, startwait + to*HZ))
 	{ 
@@ -787,8 +785,8 @@
 #if DEBUG			
 			if (debugging || jiffies - startwait >= 2*HZ/OSST_POLL_PER_SEC)
 				printk (OSST_DEB_MSG
-					"osst%d:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n",
-					dev, curr, curr+minlast, STp->first_frame_position,
+					"%s:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n",
+					name, curr, curr+minlast, STp->first_frame_position,
 					STp->last_frame_position, STp->cur_frames,
 					result, (jiffies-startwait)/HZ, 
 					(((jiffies-startwait)%HZ)*10)/HZ);
@@ -798,8 +796,8 @@
 #if DEBUG
 		if (jiffies - startwait >= 2*HZ/OSST_POLL_PER_SEC && notyetprinted)
 		{
-			printk (OSST_DEB_MSG "osst%d:D: Wait for frame %i (>%i): %i-%i %i (%i)\n",
-				dev, curr, curr+minlast, STp->first_frame_position,
+			printk (OSST_DEB_MSG "%s:D: Wait for frame %i (>%i): %i-%i %i (%i)\n",
+				name, curr, curr+minlast, STp->first_frame_position,
 				STp->last_frame_position, STp->cur_frames, result);
 			notyetprinted--;
 		}
@@ -808,8 +806,8 @@
 		schedule_timeout (HZ / OSST_POLL_PER_SEC);
 	}
 #if DEBUG
-	printk (OSST_DEB_MSG "osst%d:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n",
-		dev, curr, curr+minlast, STp->first_frame_position,
+	printk (OSST_DEB_MSG "%s:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n",
+		name, curr, curr+minlast, STp->first_frame_position,
 		STp->last_frame_position, STp->cur_frames,
 		(jiffies-startwait)/HZ, (((jiffies-startwait)%HZ)*10)/HZ);
 #endif	
@@ -826,7 +824,7 @@
 	int		retval = 0;
 #if DEBUG
 	os_aux_t      * aux    = STp->buffer->aux;
-	int		dev    = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 #endif
 
 	/* TODO: Error handling */
@@ -843,7 +841,7 @@
 
 #if DEBUG
 	if (debugging)
-	    printk(OSST_DEB_MSG "osst%d:D: Reading frame from OnStream tape\n", dev);
+	    printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name);
 #endif
 	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ,
 				      STp->timeout, MAX_RETRIES, TRUE);
@@ -856,13 +854,13 @@
 	    if (STp->read_error_frame == 0) {
 		STp->read_error_frame = STp->first_frame_position;
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Recording read error at %d\n", dev, STp->read_error_frame);
+		printk(OSST_DEB_MSG "%s:D: Recording read error at %d\n", name, STp->read_error_frame);
 #endif
 	    }
 #if DEBUG
 	    if (debugging)
-		printk(OSST_DEB_MSG "osst%d:D: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
-		   dev,
+		printk(OSST_DEB_MSG "%s:D: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
+		   name,
 		   SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[1],
 		   SRpnt->sr_sense_buffer[2], SRpnt->sr_sense_buffer[3],
 		   SRpnt->sr_sense_buffer[4], SRpnt->sr_sense_buffer[5],
@@ -874,7 +872,7 @@
 #if DEBUG
 	if (debugging) {
 	   printk(OSST_DEB_MSG 
-		"osst%d:D: AUX: %c%c%c%c UpdFrCt#%d Wpass#%d %s FrSeq#%d LogBlk#%d Qty=%d Sz=%d\n", dev,
+		"%s:D: AUX: %c%c%c%c UpdFrCt#%d Wpass#%d %s FrSeq#%d LogBlk#%d Qty=%d Sz=%d\n", name,
 			aux->application_sig[0], aux->application_sig[1],
 			aux->application_sig[2], aux->application_sig[3], 
 			ntohl(aux->update_frame_cntr), ntohs(aux->partition.wrt_pass_cntr),
@@ -883,9 +881,9 @@
 			ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
 			ntohs(aux->dat.dat_list[0].blk_cnt), ntohl(aux->dat.dat_list[0].blk_sz) );
 	   if (aux->frame_type==2)
-		printk(OSST_DEB_MSG "osst%d:D: mark_cnt=%d, last_mark_ppos=%d, last_mark_lbn=%d\n", dev,
+		printk(OSST_DEB_MSG "%s:D: mark_cnt=%d, last_mark_ppos=%d, last_mark_lbn=%d\n", name,
 			ntohl(aux->filemark_cnt), ntohl(aux->last_mark_ppos), ntohl(aux->last_mark_lbn));
-	   printk(OSST_DEB_MSG "osst%d:D: Exit read frame from OnStream tape with code %d\n", dev, retval);
+	   printk(OSST_DEB_MSG "%s:D: Exit read frame from OnStream tape with code %d\n", name, retval);
 	}
 #endif
 	return (retval);
@@ -898,7 +896,7 @@
 	unsigned char	cmd[MAX_COMMAND_SIZE];
 	int		retval = 0;
 #if DEBUG
-	int		dev    = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 #endif
 
 	if (STps->rw != ST_READING) {         /* Initialize read operation */
@@ -918,7 +916,7 @@
 		cmd[1] = 1;
 
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Start Read Ahead on OnStream tape\n", dev);
+		printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name);
 #endif
 		SRpnt   = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_RETRIES, TRUE);
 		*aSRpnt = SRpnt;
@@ -931,7 +929,7 @@
 static int osst_get_logical_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int frame_seq_number, int quiet)
 {
 	ST_partstat * STps  = &(STp->ps[STp->partition]);
-	int           dev   = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 	int           cnt   = 0,
 		      bad   = 0,
 		      past  = 0,
@@ -943,13 +941,13 @@
 	 */
 	while (1) {
 		if (cnt++ > 400) {
-                        printk(KERN_ERR "osst%d:E: Couldn't find logical frame %d, aborting\n",
-					    dev, frame_seq_number);
+                        printk(KERN_ERR "%s:E: Couldn't find logical frame %d, aborting\n",
+					    name, frame_seq_number);
 			if (STp->read_error_frame) {
 				osst_set_frame_position(STp, aSRpnt, STp->read_error_frame, 0);
 #if DEBUG
-                        	printk(OSST_DEB_MSG "osst%d:D: Repositioning tape to bad frame %d\n",
-						    dev, STp->read_error_frame);
+                        	printk(OSST_DEB_MSG "%s:D: Repositioning tape to bad frame %d\n",
+						    name, STp->read_error_frame);
 #endif
 				STp->read_error_frame = 0;
 			}
@@ -957,8 +955,8 @@
 		}
 #if DEBUG
 		if (debugging)
-			printk(OSST_DEB_MSG "osst%d:D: Looking for frame %d, attempt %d\n",
-					  dev, frame_seq_number, cnt);
+			printk(OSST_DEB_MSG "%s:D: Looking for frame %d, attempt %d\n",
+					  name, frame_seq_number, cnt);
 #endif
 		if ( osst_initiate_read(STp, aSRpnt)
                 || ( (!STp->frame_in_buffer) && osst_read_frame(STp, aSRpnt, 30) ) ) {
@@ -975,8 +973,8 @@
 				cnt += 20;
 			}
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d:D: Bad frame detected, positioning tape to block %d\n",
-					 dev, position);
+			printk(OSST_DEB_MSG "%s:D: Bad frame detected, positioning tape to block %d\n",
+					 name, position);
 #endif
 			osst_set_frame_position(STp, aSRpnt, position, 0);
 			continue;
@@ -987,8 +985,8 @@
 			x = ntohl(STp->buffer->aux->frame_seq_num);
 			if (STp->fast_open) {
 				printk(KERN_WARNING
-				       "osst%d:W: Found logical frame %d instead of %d after fast open\n",
-				       dev, x, frame_seq_number);
+				       "%s:W: Found logical frame %d instead of %d after fast open\n",
+				       name, x, frame_seq_number);
 				STp->header_ok = 0;
 				STp->read_error_frame = 0;
 				return (-EIO);
@@ -1007,8 +1005,8 @@
 				}
 #if DEBUG
                                 printk(OSST_DEB_MSG
-				       "osst%d:D: Found logical frame %d while looking for %d: back up %d\n",
-						dev, x, frame_seq_number,
+				       "%s:D: Found logical frame %d while looking for %d: back up %d\n",
+						name, x, frame_seq_number,
 					       	STp->first_frame_position - position);
 #endif
                         	osst_set_frame_position(STp, aSRpnt, position, 0);
@@ -1019,7 +1017,7 @@
 		}
 		if (osst_get_frame_position(STp, aSRpnt) == 0xbaf) {
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d:D: Skipping config partition\n", dev);
+			printk(OSST_DEB_MSG "%s:D: Skipping config partition\n", name);
 #endif
 			osst_set_frame_position(STp, aSRpnt, 0xbb8, 0);
 			cnt--;
@@ -1029,16 +1027,16 @@
 	if (cnt > 1) {
 		STp->recover_count++;
 		STp->recover_erreg++;
-		printk(KERN_WARNING "osst%d:I: Don't worry, Read error at position %d recovered\n", 
-					dev, STp->read_error_frame);
+		printk(KERN_WARNING "%s:I: Don't worry, Read error at position %d recovered\n", 
+					name, STp->read_error_frame);
  	}
 	STp->read_count++;
 
 #if DEBUG
 	if (debugging || STps->eof)
 		printk(OSST_DEB_MSG
-			"osst%d:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n",
-			dev, frame_seq_number, STp->frame_seq_number, STps->eof);
+			"%s:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n",
+			name, frame_seq_number, STp->frame_seq_number, STps->eof);
 #endif
 	STp->fast_open = FALSE;
 	STp->read_error_frame = 0;
@@ -1048,14 +1046,14 @@
 static int osst_seek_logical_blk(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int logical_blk_num)
 {
         ST_partstat * STps = &(STp->ps[STp->partition]);
-	int	dev        = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 	int	retries    = 0;
 	int	frame_seq_estimate, ppos_estimate, move;
 	
 	if (logical_blk_num < 0) logical_blk_num = 0;
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d:D: Seeking logical block %d (now at %d, size %d%c)\n",
-				dev, logical_blk_num, STp->logical_blk_num, 
+	printk(OSST_DEB_MSG "%s:D: Seeking logical block %d (now at %d, size %d%c)\n",
+				name, logical_blk_num, STp->logical_blk_num, 
 				STp->block_size<1024?STp->block_size:STp->block_size/1024,
 				STp->block_size<1024?'b':'k');
 #endif
@@ -1093,8 +1091,8 @@
 		 }
 #if DEBUG
 		 printk(OSST_DEB_MSG
-			"osst%d:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n",
-				dev, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate, 
+			"%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n",
+				name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate, 
 				STp->logical_blk_num, logical_blk_num, move);
 #endif
 		 frame_seq_estimate += move;
@@ -1106,8 +1104,8 @@
 		 STp->logical_blk_num       =  logical_blk_num;
 #if DEBUG
 		 printk(OSST_DEB_MSG 
-			"osst%d:D: Seek success at ppos %d fsq %d in_buf %d, bytes %d, ptr %d*%d\n",
-				dev, ppos_estimate, STp->frame_seq_number, STp->frame_in_buffer, 
+			"%s:D: Seek success at ppos %d fsq %d in_buf %d, bytes %d, ptr %d*%d\n",
+				name, ppos_estimate, STp->frame_seq_number, STp->frame_in_buffer, 
 				STp->buffer->buffer_bytes, STp->buffer->read_pointer / STp->block_size, 
 				STp->block_size);
 #endif
@@ -1129,8 +1127,8 @@
 	      goto error;
 	   /* we are not yet at the estimated frame, adjust our estimate of its physical position */
 #if DEBUG
-	   printk(OSST_DEB_MSG "osst%d:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d)\n", 
-			   dev, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate, 
+	   printk(OSST_DEB_MSG "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d)\n", 
+			   name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate, 
 			   STp->logical_blk_num, logical_blk_num);
 #endif
 	   if (frame_seq_estimate != STp->frame_seq_number)
@@ -1139,8 +1137,8 @@
 	      break;
 	}
 error:
-	printk(KERN_ERR "osst%d:E: Couldn't seek to logical block %d (at %d), %d retries\n", 
-			    dev, logical_blk_num, STp->logical_blk_num, retries);
+	printk(KERN_ERR "%s:E: Couldn't seek to logical block %d (at %d), %d retries\n", 
+			    name, logical_blk_num, STp->logical_blk_num, retries);
 	return (-EIO);
 }
 
@@ -1157,11 +1155,11 @@
 {
 	int	sector;
 #if DEBUG
-	int	dev = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 	
 	printk(OSST_DEB_MSG 
-		"osst%d:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %d\n",
-		dev, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
+		"%s:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %d\n",
+		name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
 		STp->ps[STp->partition].drv_file, STp->ps[STp->partition].drv_block, 
 		STp->ps[STp->partition].rw == ST_WRITING?'w':'r',
 		STp->ps[STp->partition].rw == ST_WRITING?STp->buffer->buffer_bytes:
@@ -1190,10 +1188,10 @@
 			offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT, 
 			r;
 #if DEBUG
-	int		dev    = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 
-	printk(OSST_DEB_MSG "osst%d:D: Seeking sector %d in frame %d at offset %d\n",
-				dev, sector, frame, offset);
+	printk(OSST_DEB_MSG "%s:D: Seeking sector %d in frame %d at offset %d\n",
+				name, sector, frame, offset);
 #endif
 	if (frame < 0 || frame >= STp->capacity) return (-ENXIO);
 
@@ -1232,8 +1230,8 @@
 	STps->eof       = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
 #if DEBUG
 	printk(OSST_DEB_MSG 
-		"osst%d:D: Now positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, rptr %d, eof %d\n",
-		dev, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
+		"%s:D: Now positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, rptr %d, eof %d\n",
+		name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
 		STps->drv_file, STps->drv_block, STp->buffer->read_pointer, STps->eof);
 #endif
 	return 0;
@@ -1259,7 +1257,7 @@
 						- (nframes + pending - 1);
 	int             logical_blk_num  = ntohl(STp->buffer->aux->logical_blk_num) 
 						- (nframes + pending - 1) * blks_per_frame;
-	int		dev              = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 	long		startwait        = jiffies;
 #if DEBUG
 	int		dbg              = debugging;
@@ -1268,14 +1266,14 @@
 	if ((buffer = (unsigned char *)vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL)
 		return (-EIO);
 
-	printk(KERN_INFO "osst%d:I: Reading back %d frames from drive buffer%s\n",
-			 dev, nframes, pending?" and one that was pending":"");
+	printk(KERN_INFO "%s:I: Reading back %d frames from drive buffer%s\n",
+			 name, nframes, pending?" and one that was pending":"");
 
 	osst_copy_from_buffer(STp->buffer, (p = &buffer[nframes * OS_DATA_SIZE]));
 #if DEBUG
 	if (pending && debugging)
-		printk(OSST_DEB_MSG "osst%d:D: Pending frame %d (lblk %d), data %02x %02x %02x %02x\n",
-				dev, frame_seq_number + nframes,
+		printk(OSST_DEB_MSG "%s:D: Pending frame %d (lblk %d), data %02x %02x %02x %02x\n",
+				name, frame_seq_number + nframes,
 			       	logical_blk_num + nframes * blks_per_frame,
 			       	p[0], p[1], p[2], p[3]);
 #endif
@@ -1291,7 +1289,7 @@
 					    STp->timeout, MAX_RETRIES, TRUE);
 	
 		if ((STp->buffer)->syscall_result || !SRpnt) {
-			printk(KERN_ERR "osst%d:E: Failed to read frame back from OnStream buffer\n", dev);
+			printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name);
 			vfree((void *)buffer);
 			*aSRpnt = SRpnt;
 			return (-EIO);
@@ -1299,15 +1297,15 @@
 		osst_copy_from_buffer(STp->buffer, p);
 #if DEBUG
 		if (debugging)
-			printk(OSST_DEB_MSG "osst%d:D: Read back logical frame %d, data %02x %02x %02x %02x\n",
-					  dev, frame_seq_number + i, p[0], p[1], p[2], p[3]);
+			printk(OSST_DEB_MSG "%s:D: Read back logical frame %d, data %02x %02x %02x %02x\n",
+					  name, frame_seq_number + i, p[0], p[1], p[2], p[3]);
 #endif
 	}
 	*aSRpnt = SRpnt;
 	osst_get_frame_position(STp, aSRpnt);
 
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d:D: Frames left in buffer: %d\n", dev, STp->cur_frames);
+	printk(OSST_DEB_MSG "%s:D: Frames left in buffer: %d\n", name, STp->cur_frames);
 #endif
 	/* Write synchronously so we can be sure we're OK again and don't have to recover recursively */
 	/* In the header we don't actually re-write the frames that fail, just the ones after them */
@@ -1324,8 +1322,8 @@
 			else
 				new_frame += skip;
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d:D: Position to frame %d, write fseq %d\n",
-						dev, new_frame+i, frame_seq_number+i);
+			printk(OSST_DEB_MSG "%s:D: Position to frame %d, write fseq %d\n",
+						name, new_frame+i, frame_seq_number+i);
 #endif
 			osst_set_frame_position(STp, aSRpnt, new_frame + i, 0);
 			osst_wait_ready(STp, aSRpnt, 60);
@@ -1333,7 +1331,7 @@
 			SRpnt = * aSRpnt;
 
 			if (new_frame > frame + 1000) {
-				printk(KERN_ERR "osst%d:E: Failed to find writable tape media\n", dev);
+				printk(KERN_ERR "%s:E: Failed to find writable tape media\n", name);
 				vfree((void *)buffer);
 				return (-EIO);
 			}
@@ -1355,8 +1353,8 @@
 #if DEBUG
 		if (debugging)
 			printk(OSST_DEB_MSG
-				"osst%d:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02x\n",
-				dev, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame,
+				"%s:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02x\n",
+				name, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame,
 				p[0], p[1], p[2], p[3]);
 #endif
 		SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_WRITE,
@@ -1370,7 +1368,7 @@
 			/* if we just sent the last frame, wait till all successfully written */
 			if ( i == nframes + pending ) {
 #if DEBUG
-				printk(OSST_DEB_MSG "osst%d:D: Check re-write successful\n", dev);
+				printk(OSST_DEB_MSG "%s:D: Check re-write successful\n", name);
 #endif
 				memset(cmd, 0, MAX_COMMAND_SIZE);
 				cmd[0] = WRITE_FILEMARKS;
@@ -1379,8 +1377,8 @@
 							    STp->timeout, MAX_WRITE_RETRIES, TRUE);
 #if DEBUG
 				if (debugging) {
-					printk(OSST_DEB_MSG "osst%d:D: Sleeping in re-write wait ready\n", dev);
-					printk(OSST_DEB_MSG "osst%d:D: Turning off debugging for a while\n", dev);
+					printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
+					printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
 					debugging = 0;
 				}
 #endif
@@ -1405,7 +1403,7 @@
 				}
 #if DEBUG
 				debugging = dbg;
-				printk(OSST_DEB_MSG "osst%d:D: Wait re-write finished\n", dev);
+				printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
 #endif
 			}
 		}
@@ -1414,7 +1412,7 @@
 			if ((SRpnt->sr_sense_buffer[ 2] & 0x0f) == 13 &&
 			     SRpnt->sr_sense_buffer[12]         ==  0 &&
 			     SRpnt->sr_sense_buffer[13]         ==  2) {
-				printk(KERN_ERR "osst%d:E: Volume overflow in write error recovery\n", dev);
+				printk(KERN_ERR "%s:E: Volume overflow in write error recovery\n", name);
 				vfree((void *)buffer);
 				return (-EIO);			/* hit end of tape = fail */
 			}
@@ -1424,12 +1422,12 @@
 			      SRpnt->sr_sense_buffer[6]        ) - new_frame;
 			p = &buffer[i * OS_DATA_SIZE];
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d:D: Additional write error at %d\n", dev, new_frame+i);
+			printk(OSST_DEB_MSG "%s:D: Additional write error at %d\n", name, new_frame+i);
 #endif
 			osst_get_frame_position(STp, aSRpnt);
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d:D: reported frame positions: host = %d, tape = %d\n",
-					  dev, STp->first_frame_position, STp->last_frame_position);
+			printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n",
+					  name, STp->first_frame_position, STp->last_frame_position);
 #endif
 		}
 	}    
@@ -1444,7 +1442,7 @@
 {
 	unsigned char	cmd[MAX_COMMAND_SIZE];
 	Scsi_Request  * SRpnt;
-	int		dev       = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 	int		expected  = 0;
 	int		attempts  = 1000 / skip;
 	int		flag      = 1;
@@ -1462,8 +1460,8 @@
 				frame = 3000-skip;
 			expected = frame+skip+STp->cur_frames+pending;
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d:D: Position to fppos %d, re-write from fseq %d\n",
-					  dev, frame+skip, STp->frame_seq_number-STp->cur_frames-pending);
+			printk(OSST_DEB_MSG "%s:D: Position to fppos %d, re-write from fseq %d\n",
+					  name, frame+skip, STp->frame_seq_number-STp->cur_frames-pending);
 #endif
 			osst_set_frame_position(STp, aSRpnt, frame + skip, 1);
 			flag = 0;
@@ -1471,8 +1469,8 @@
 		}
 		if (osst_get_frame_position(STp, aSRpnt) < 0) {		/* additional write error */
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d:D: Addl error, host %d, tape %d, buffer %d\n",
-					  dev, STp->first_frame_position,
+			printk(OSST_DEB_MSG "%s:D: Addl error, host %d, tape %d, buffer %d\n",
+					  name, STp->first_frame_position,
 					  STp->last_frame_position, STp->cur_frames);
 #endif
 			frame = STp->last_frame_position;
@@ -1486,8 +1484,8 @@
 			cmd[1] = 1;
 			cmd[4] = 1;
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d:D: About to write pending fseq %d at fppos %d\n",
-					  dev, STp->frame_seq_number-1, STp->first_frame_position);
+			printk(OSST_DEB_MSG "%s:D: About to write pending fseq %d at fppos %d\n",
+					  name, STp->frame_seq_number-1, STp->first_frame_position);
 #endif
 			SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_WRITE,
 						      STp->timeout, MAX_WRITE_RETRIES, TRUE);
@@ -1498,8 +1496,8 @@
 				     SRpnt->sr_sense_buffer[12]         ==  0 &&
 				     SRpnt->sr_sense_buffer[13]         ==  2) {
 					printk(KERN_ERR
-					       "osst%d:E: Volume overflow in write error recovery\n",
-					       dev);
+					       "%s:E: Volume overflow in write error recovery\n",
+					       name);
 					break;				/* hit end of tape = fail */
 				}
 				flag = 1;
@@ -1512,25 +1510,25 @@
 		if (STp->cur_frames == 0) {
 #if DEBUG
 			debugging = dbg;
-			printk(OSST_DEB_MSG "osst%d:D: Wait re-write finished\n", dev);
+			printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
 #endif
 			if (STp->first_frame_position != expected) {
-				printk(KERN_ERR "osst%d:A: Actual position %d - expected %d\n", 
-						dev, STp->first_frame_position, expected);
+				printk(KERN_ERR "%s:A: Actual position %d - expected %d\n", 
+						name, STp->first_frame_position, expected);
 				return (-EIO);
 			}
 			return 0;
 		}
 #if DEBUG
 		if (debugging) {
-			printk(OSST_DEB_MSG "osst%d:D: Sleeping in re-write wait ready\n", dev);
-			printk(OSST_DEB_MSG "osst%d:D: Turning off debugging for a while\n", dev);
+			printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
+			printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
 			debugging = 0;
 		}
 #endif
 		schedule_timeout(HZ / 10);
 	}
-	printk(KERN_ERR "osst%d:E: Failed to find valid tape media\n", dev);
+	printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name);
 #if DEBUG
 	debugging = dbg;
 #endif
@@ -1545,7 +1543,7 @@
 {
 	Scsi_Request * SRpnt  = * aSRpnt;
 	ST_partstat  * STps   = & STp->ps[STp->partition];
-	int            dev    = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 	int            retval = 0;
 	int            rw_state;
 	unsigned int  frame, skip;
@@ -1556,7 +1554,7 @@
 	  || SRpnt->sr_sense_buffer[12]         != 12
 	  || SRpnt->sr_sense_buffer[13]         != 0) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Write error recovery cannot handle %02x:%02x:%02x\n", dev,
+		printk(OSST_DEB_MSG "%s:D: Write error recovery cannot handle %02x:%02x:%02x\n", name,
 			SRpnt->sr_sense_buffer[2], SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
 #endif
 		return (-EIO);
@@ -1568,47 +1566,47 @@
 	skip  =  SRpnt->sr_sense_buffer[9];
  
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d:D: Detected physical bad frame at %u, advised to skip %d\n", dev, frame, skip);
+	printk(OSST_DEB_MSG "%s:D: Detected physical bad frame at %u, advised to skip %d\n", name, frame, skip);
 #endif
 	osst_get_frame_position(STp, aSRpnt);
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d:D: reported frame positions: host = %d, tape = %d\n",
-			dev, STp->first_frame_position, STp->last_frame_position);
+	printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n",
+			name, STp->first_frame_position, STp->last_frame_position);
 #endif
 	switch (STp->write_type) {
 	   case OS_WRITE_DATA:
 	   case OS_WRITE_EOD:
 	   case OS_WRITE_NEW_MARK:
 		printk(KERN_WARNING 
-			"osst%d:I: Relocating %d buffered logical frames from position %u to %u\n",
-			dev, STp->cur_frames, frame, (frame + skip > 3000 && frame < 3000)?3000:frame + skip);
+			"%s:I: Relocating %d buffered logical frames from position %u to %u\n",
+			name, STp->cur_frames, frame, (frame + skip > 3000 && frame < 3000)?3000:frame + skip);
 		if (STp->os_fw_rev >= 10600)
 			retval = osst_reposition_and_retry(STp, aSRpnt, frame, skip, pending);
 		else
 			retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, skip, pending);
-		printk(KERN_WARNING "osst%d:%s: %sWrite error%srecovered\n", dev,
+		printk(KERN_WARNING "%s:%s: %sWrite error%srecovered\n", name,
 			       	retval?"E"    :"I",
 			       	retval?""     :"Don't worry, ",
 			       	retval?" not ":" ");
 		break;
 	   case OS_WRITE_LAST_MARK:
-		printk(KERN_ERR "osst%d:E: Bad frame in update last marker, fatal\n", dev);
+		printk(KERN_ERR "%s:E: Bad frame in update last marker, fatal\n", name);
 		osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
 		retval = -EIO;
 		break;
 	   case OS_WRITE_HEADER:
-		printk(KERN_WARNING "osst%d:I: Bad frame in header partition, skipped\n", dev);
+		printk(KERN_WARNING "%s:I: Bad frame in header partition, skipped\n", name);
 		retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, 1, pending);
 		break;
 	   default:
-		printk(KERN_INFO "osst%d:I: Bad frame in filler, ignored\n", dev);
+		printk(KERN_INFO "%s:I: Bad frame in filler, ignored\n", name);
 		osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
 	}
 	osst_get_frame_position(STp, aSRpnt);
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d:D: Positioning complete, cur_frames %d, pos %d, tape pos %d\n", 
-			dev, STp->cur_frames, STp->first_frame_position, STp->last_frame_position);
-	printk(OSST_DEB_MSG "osst%d:D: next logical frame to write: %d\n", dev, STp->logical_blk_num);
+	printk(OSST_DEB_MSG "%s:D: Positioning complete, cur_frames %d, pos %d, tape pos %d\n", 
+			name, STp->cur_frames, STp->first_frame_position, STp->last_frame_position);
+	printk(OSST_DEB_MSG "%s:D: next logical frame to write: %d\n", name, STp->logical_blk_num);
 #endif
 	if (retval == 0) {
 		STp->recover_count++;
@@ -1621,16 +1619,16 @@
 static int osst_space_over_filemarks_backward(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
 								 int mt_op, int mt_count)
 {
-	int     dev = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 	int     cnt;
 	int     last_mark_ppos = -1;
 
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d:D: Reached space_over_filemarks_backwards %d %d\n", dev, mt_op, mt_count);
+	printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_backwards %d %d\n", name, mt_op, mt_count);
 #endif
 	if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in space_filemarks_bwd\n", dev);
+		printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_bwd\n", name);
 #endif
 		return -EIO;
 	}
@@ -1649,11 +1647,11 @@
 			last_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt - mt_count]);
 #if DEBUG
 		if (STp->header_cache == NULL || (cnt - mt_count) < 0 || (cnt - mt_count) >= OS_FM_TAB_MAX)
-			printk(OSST_DEB_MSG "osst%d:D: Filemark lookup fail due to %s\n", dev,
+			printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
 			       STp->header_cache == NULL?"lack of header cache":"count out of range");
 		else
-			printk(OSST_DEB_MSG "osst%d:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
-				dev, cnt,
+			printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
+				name, cnt,
 				((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
 				 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] ==
 					 STp->buffer->aux->last_mark_ppos))?"match":"error",
@@ -1664,13 +1662,13 @@
 			if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
 #if DEBUG
 				printk(OSST_DEB_MSG 
-					"osst%d:D: Couldn't get logical blk num in space_filemarks\n", dev);
+					"%s:D: Couldn't get logical blk num in space_filemarks\n", name);
 #endif
 				return (-EIO);
 			}
 			if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
-				printk(KERN_WARNING "osst%d:W: Expected to find marker at ppos %d, not found\n",
-						 dev, last_mark_ppos);
+				printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
+						 name, last_mark_ppos);
 				return (-EIO);
 			}
 			if (mt_op == MTBSFM) {
@@ -1681,7 +1679,7 @@
 			return 0;
 		}
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Reverting to scan filemark backwards\n", dev);
+		printk(OSST_DEB_MSG "%s:D: Reverting to scan filemark backwards\n", name);
 #endif
 	}
 	cnt = 0;
@@ -1690,19 +1688,19 @@
 		if (last_mark_ppos == -1)
 			return (-EIO);
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Positioning to last mark at %d\n", dev, last_mark_ppos);
+		printk(OSST_DEB_MSG "%s:D: Positioning to last mark at %d\n", name, last_mark_ppos);
 #endif
 		osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
 		cnt++;
 		if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in space_filemarks\n", dev);
+			printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
 #endif
 			return (-EIO);
 		}
 		if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
-			printk(KERN_WARNING "osst%d:W: Expected to find marker at ppos %d, not found\n",
-					 dev, last_mark_ppos);
+			printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
+					 name, last_mark_ppos);
 			return (-EIO);
 		}
 	}
@@ -1724,20 +1722,20 @@
 {
 	int	cnt = 0;
 #if DEBUG
-	int	dev = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 
-	printk(OSST_DEB_MSG "osst%d:D: Reached space_over_filemarks_forward_slow %d %d\n", dev, mt_op, mt_count);
+	printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_slow %d %d\n", name, mt_op, mt_count);
 #endif
 	if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in space_filemarks_fwd\n", dev);
+		printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
 #endif
 		return (-EIO);
 	}
 	while (1) {
 		if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in space_filemarks\n", dev);
+			printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
 #endif
 			return (-EIO);
 		}
@@ -1745,12 +1743,12 @@
 			cnt++;
 		if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d:D: space_fwd: EOD reached\n", dev);
+			printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
 #endif
 			if (STp->first_frame_position > STp->eod_frame_ppos+1) {
 #if DEBUG
-				printk(OSST_DEB_MSG "osst%d:D: EOD position corrected (%d=>%d)\n",
-					       	dev, STp->eod_frame_ppos, STp->first_frame_position-1);
+				printk(OSST_DEB_MSG "%s:D: EOD position corrected (%d=>%d)\n",
+					       	name, STp->eod_frame_ppos, STp->first_frame_position-1);
 #endif
 				STp->eod_frame_ppos = STp->first_frame_position-1;
 			}
@@ -1774,16 +1772,16 @@
 static int osst_space_over_filemarks_forward_fast(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
 								     int mt_op, int mt_count)
 {
-	int	dev = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 	int	cnt = 0,
 		next_mark_ppos = -1;
 
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d:D: Reached space_over_filemarks_forward_fast %d %d\n", dev, mt_op, mt_count);
+	printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_fast %d %d\n", name, mt_op, mt_count);
 #endif
 	if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in space_filemarks_fwd\n", dev);
+		printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
 #endif
 		return (-EIO);
 	}
@@ -1803,11 +1801,11 @@
 			next_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt + mt_count]);
 #if DEBUG
 		if (STp->header_cache == NULL || (cnt + mt_count) >= OS_FM_TAB_MAX)
-			printk(OSST_DEB_MSG "osst%d:D: Filemark lookup fail due to %s\n", dev,
+			printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
 			       STp->header_cache == NULL?"lack of header cache":"count out of range");
 		else
-			printk(OSST_DEB_MSG "osst%d:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
-			       dev, cnt,
+			printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
+			       name, cnt,
 			       ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
 				(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] ==
 					 STp->buffer->aux->last_mark_ppos))?"match":"error",
@@ -1815,26 +1813,26 @@
 #endif
 		if (next_mark_ppos <= 10 || next_mark_ppos > STp->eod_frame_ppos) {
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d:D: Reverting to slow filemark space\n", dev);
+			printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
 #endif
 			return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
 		} else {
 			osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
 			if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
 #if DEBUG
-				printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in space_filemarks\n",
-						 dev);
+				printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
+						 name);
 #endif
 				return (-EIO);
 			}
 			if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
-				printk(KERN_WARNING "osst%d:W: Expected to find marker at ppos %d, not found\n",
-						 dev, next_mark_ppos);
+				printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
+						 name, next_mark_ppos);
 				return (-EIO);
 			}
 			if (ntohl(STp->buffer->aux->filemark_cnt) != cnt + mt_count) {
-				printk(KERN_WARNING "osst%d:W: Expected to find marker %d at ppos %d, not %d\n",
-						 dev, cnt+mt_count, next_mark_ppos,
+				printk(KERN_WARNING "%s:W: Expected to find marker %d at ppos %d, not %d\n",
+						 name, cnt+mt_count, next_mark_ppos,
 						 ntohl(STp->buffer->aux->filemark_cnt));
        				return (-EIO);
 			}
@@ -1848,14 +1846,14 @@
 				break;
 			if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
 #if DEBUG
-				printk(OSST_DEB_MSG "osst%d:D: space_fwd: EOD reached\n", dev);
+				printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
 #endif
 				return (-EIO);
 			}
 			if (ntohl(STp->buffer->aux->filemark_cnt) == 0) {
 				if (STp->first_mark_ppos == -1) {
 #if DEBUG
-					printk(OSST_DEB_MSG "osst%d:D: Reverting to slow filemark space\n", dev);
+					printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
 #endif
 					return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
 				}
@@ -1863,14 +1861,14 @@
 				if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
 #if DEBUG
 					printk(OSST_DEB_MSG
-					       "osst%d:D: Couldn't get logical blk num in space_filemarks_fwd_fast\n",
-					       dev);
+					       "%s:D: Couldn't get logical blk num in space_filemarks_fwd_fast\n",
+					       name);
 #endif
 					return (-EIO);
 				}
 				if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
-					printk(KERN_WARNING "osst%d:W: Expected to find filemark at %d\n",
-							 dev, STp->first_mark_ppos);
+					printk(KERN_WARNING "%s:W: Expected to find filemark at %d\n",
+							 name, STp->first_mark_ppos);
 					return (-EIO);
 				}
 			} else {
@@ -1884,25 +1882,25 @@
 			next_mark_ppos = ntohl(STp->buffer->aux->next_mark_ppos);
 			if (!next_mark_ppos || next_mark_ppos > STp->eod_frame_ppos) {
 #if DEBUG
-				printk(OSST_DEB_MSG "osst%d:D: Reverting to slow filemark space\n", dev);
+				printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
 #endif
 				return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count - cnt);
 			}
 #if DEBUG
-			else printk(OSST_DEB_MSG "osst%d:D: Positioning to next mark at %d\n", dev, next_mark_ppos);
+			else printk(OSST_DEB_MSG "%s:D: Positioning to next mark at %d\n", name, next_mark_ppos);
 #endif
 			osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
 			cnt++;
 			if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
 #if DEBUG
-				printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in space_filemarks\n",
-						 dev);
+				printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
+						 name);
 #endif
 				return (-EIO);
 			}
 			if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
-				printk(KERN_WARNING "osst%d:W: Expected to find marker at ppos %d, not found\n",
-						 dev, next_mark_ppos);
+				printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
+						 name, next_mark_ppos);
 				return (-EIO);
 			}
 		}
@@ -1924,7 +1922,7 @@
 {
 	unsigned char	cmd[MAX_COMMAND_SIZE];
 	Scsi_Request     * SRpnt  = * aSRpnt;
-	int		dev  = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 
 	memset(cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = MODE_SELECT;
@@ -1941,13 +1939,13 @@
 	(STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = retries;
 
 	if (debugging)
-	    printk(OSST_DEB_MSG "osst%d:D: Setting number of retries on OnStream tape to %d\n", dev, retries);
+	    printk(OSST_DEB_MSG "%s:D: Setting number of retries on OnStream tape to %d\n", name, retries);
 
 	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE, STp->timeout, 0, TRUE);
 	*aSRpnt = SRpnt;
 
 	if ((STp->buffer)->syscall_result)
-	    printk (KERN_ERR "osst%d:D: Couldn't set retries to %d\n", dev, retries);
+	    printk (KERN_ERR "%s:D: Couldn't set retries to %d\n", name, retries);
 }
 #endif
 
@@ -1958,15 +1956,15 @@
 	int	this_mark_ppos = STp->first_frame_position;
 	int	this_mark_lbn  = STp->logical_blk_num;
 #if DEBUG
-	int	dev = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 #endif
 
 	if (STp->raw) return 0;
 
 	STp->write_type = OS_WRITE_NEW_MARK;
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d:D: Writing Filemark %i at fppos %d (fseq %d, lblk %d)\n", 
-	       dev, STp->filemark_cnt, this_mark_ppos, STp->frame_seq_number, this_mark_lbn);
+	printk(OSST_DEB_MSG "%s:D: Writing Filemark %i at fppos %d (fseq %d, lblk %d)\n", 
+	       name, STp->filemark_cnt, this_mark_ppos, STp->frame_seq_number, this_mark_lbn);
 #endif
 	STp->dirty = 1;
 	result  = osst_flush_write_buffer(STp, aSRpnt);
@@ -1984,7 +1982,7 @@
 {
 	int	result;
 #if DEBUG
-	int	dev = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 #endif
 
 	if (STp->raw) return 0;
@@ -1992,7 +1990,7 @@
 	STp->write_type = OS_WRITE_EOD;
 	STp->eod_frame_ppos = STp->first_frame_position;
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d:D: Writing EOD at fppos %d (fseq %d, lblk %d)\n", dev,
+	printk(OSST_DEB_MSG "%s:D: Writing EOD at fppos %d (fseq %d, lblk %d)\n", name,
 			STp->eod_frame_ppos, STp->frame_seq_number, STp->logical_blk_num);
 #endif
 	STp->dirty = 1;
@@ -2005,10 +2003,10 @@
 
 static int osst_write_filler(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int where, int count)
 {
-	int	dev = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d:D: Reached onstream write filler group %d\n", dev, where);
+	printk(OSST_DEB_MSG "%s:D: Reached onstream write filler group %d\n", name, where);
 #endif
 	osst_wait_ready(STp, aSRpnt, 60 * 5);
 	osst_set_frame_position(STp, aSRpnt, where, 0);
@@ -2018,23 +2016,23 @@
 		STp->buffer->buffer_bytes = 6;
 		STp->dirty = 1;
 		if (osst_flush_write_buffer(STp, aSRpnt)) {
-			printk(KERN_INFO "osst%i:I: Couldn't write filler frame\n", dev);
+			printk(KERN_INFO "%s:I: Couldn't write filler frame\n", name);
 			return (-EIO);
 		}
 	}
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d:D: Exiting onstream write filler group\n", dev);
+	printk(OSST_DEB_MSG "%s:D: Exiting onstream write filler group\n", name);
 #endif
 	return osst_flush_drive_buffer(STp, aSRpnt);
 }
 
 static int __osst_write_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int where, int count)
 {
-	int	dev   = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 	int     result;
 
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d:D: Reached onstream write header group %d\n", dev, where);
+	printk(OSST_DEB_MSG "%s:D: Reached onstream write header group %d\n", name, where);
 #endif
 	osst_wait_ready(STp, aSRpnt, 60 * 5);
 	osst_set_frame_position(STp, aSRpnt, where, 0);
@@ -2044,13 +2042,13 @@
 		STp->buffer->buffer_bytes = sizeof(os_header_t);
 		STp->dirty = 1;
 		if (osst_flush_write_buffer(STp, aSRpnt)) {
-			printk(KERN_INFO "osst%i:I: Couldn't write header frame\n", dev);
+			printk(KERN_INFO "%s:I: Couldn't write header frame\n", name);
 			return (-EIO);
 		}
 	}
 	result = osst_flush_drive_buffer(STp, aSRpnt);
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d:D: Write onstream header group %s\n", dev, result?"failed":"done");
+	printk(OSST_DEB_MSG "%s:D: Write onstream header group %s\n", name, result?"failed":"done");
 #endif
 	return result;
 }
@@ -2059,21 +2057,21 @@
 {
 	os_header_t * header;
 	int	      result;
-	int	      dev   = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d:D: Writing tape header\n", dev);
+	printk(OSST_DEB_MSG "%s:D: Writing tape header\n", name);
 #endif
 	if (STp->raw) return 0;
 
 	if (STp->header_cache == NULL) {
 		if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
-			printk(KERN_ERR "osst%i:E: Failed to allocate header cache\n", dev);
+			printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
 			return (-ENOMEM);
 		}
 		memset(STp->header_cache, 0, sizeof(os_header_t));
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Allocated and cleared memory for header cache\n", dev);
+		printk(OSST_DEB_MSG "%s:D: Allocated and cleared memory for header cache\n", name);
 #endif
 	}
 	if (STp->header_ok) STp->update_frame_cntr++;
@@ -2114,12 +2112,12 @@
 
 	if (locate_eod) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Locating back to eod frame addr %d\n", dev, STp->eod_frame_ppos);
+		printk(OSST_DEB_MSG "%s:D: Locating back to eod frame addr %d\n", name, STp->eod_frame_ppos);
 #endif
 		osst_set_frame_position(STp, aSRpnt, STp->eod_frame_ppos, 0);
 	}
 	if (result)
-		printk(KERN_ERR "osst%i:E: Write header failed\n", dev);
+		printk(KERN_ERR "%s:E: Write header failed\n", name);
 	else {
 		memcpy(STp->application_sig, "LIN4", 4);
 		STp->linux_media         = 1;
@@ -2144,7 +2142,7 @@
 
 static int __osst_analyze_headers(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int ppos)
 {
-	int           dev = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 	os_header_t * header;
 	os_aux_t    * aux;
 	char          id_string[8];
@@ -2156,15 +2154,15 @@
 
 	if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) {
 		if (osst_set_frame_position(STp, aSRpnt, ppos, 0))
-			printk(KERN_WARNING "osst%i:W: Couldn't position tape\n", dev);
+			printk(KERN_WARNING "%s:W: Couldn't position tape\n", name);
 		if (osst_initiate_read (STp, aSRpnt)) {
-			printk(KERN_WARNING "osst%i:W: Couldn't initiate read\n", dev);
+			printk(KERN_WARNING "%s:W: Couldn't initiate read\n", name);
 			return 0;
 		}
 	}
 	if (osst_read_frame(STp, aSRpnt, 180)) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Couldn't read header frame\n", dev);
+		printk(OSST_DEB_MSG "%s:D: Couldn't read header frame\n", name);
 #endif
 		return 0;
 	}
@@ -2172,7 +2170,7 @@
 	aux = STp->buffer->aux;
 	if (aux->frame_type != OS_FRAME_TYPE_HEADER) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Skipping non-header frame (%d)\n", dev, ppos);
+		printk(OSST_DEB_MSG "%s:D: Skipping non-header frame (%d)\n", name, ppos);
 #endif
 		return 0;
 	}
@@ -2182,7 +2180,7 @@
 	    ntohl(aux->partition.first_frame_ppos) != 0                   ||
 	    ntohl(aux->partition.last_frame_ppos)  != 0xbb7               ) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Invalid header frame (%d,%d,%d,%d,%d)\n", dev,
+		printk(OSST_DEB_MSG "%s:D: Invalid header frame (%d,%d,%d,%d,%d)\n", name,
 				ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
 			       	aux->partition.partition_num, ntohl(aux->partition.first_frame_ppos),
 			       	ntohl(aux->partition.last_frame_ppos));
@@ -2194,22 +2192,22 @@
 		strncpy(id_string, header->ident_str, 7);
 		id_string[7] = 0;
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Invalid header identification string %s\n", dev, id_string);
+		printk(OSST_DEB_MSG "%s:D: Invalid header identification string %s\n", name, id_string);
 #endif
 		return 0;
 	}
 	update_frame_cntr = ntohl(aux->update_frame_cntr);
 	if (update_frame_cntr < STp->update_frame_cntr) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Skipping frame %d with update_frame_counter %d<%d\n",
-				   dev, ppos, update_frame_cntr, STp->update_frame_cntr);
+		printk(OSST_DEB_MSG "%s:D: Skipping frame %d with update_frame_counter %d<%d\n",
+				   name, ppos, update_frame_cntr, STp->update_frame_cntr);
 #endif
 		return 0;
 	}
 	if (header->major_rev != 1 || header->minor_rev != 4 ) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: %s revision %d.%d detected (1.4 supported)\n", 
-				 dev, (header->major_rev != 1 || header->minor_rev < 2 || 
+		printk(OSST_DEB_MSG "%s:D: %s revision %d.%d detected (1.4 supported)\n", 
+				 name, (header->major_rev != 1 || header->minor_rev < 2 || 
 				       header->minor_rev  > 4 )? "Invalid" : "Warning:",
 				 header->major_rev, header->minor_rev);
 #endif
@@ -2218,8 +2216,8 @@
 	}
 #if DEBUG
 	if (header->pt_par_num != 1)
-		printk(KERN_INFO "osst%i:W: %d partitions defined, only one supported\n", 
-				 dev, header->pt_par_num);
+		printk(KERN_INFO "%s:W: %d partitions defined, only one supported\n", 
+				 name, header->pt_par_num);
 #endif
 	memcpy(id_string, aux->application_sig, 4);
 	id_string[4] = 0;
@@ -2227,23 +2225,23 @@
 		STp->linux_media = 1;
 		linux_media_version = id_string[3] - '0';
 		if (linux_media_version != 4)
-			printk(KERN_INFO "osst%i:I: Linux media version %d detected (current 4)\n",
-					 dev, linux_media_version);
+			printk(KERN_INFO "%s:I: Linux media version %d detected (current 4)\n",
+					 name, linux_media_version);
 	} else {
-		printk(KERN_WARNING "osst%i:W: Non Linux media detected (%s)\n", dev, id_string);
+		printk(KERN_WARNING "%s:W: Non Linux media detected (%s)\n", name, id_string);
 		return 0;
 	}
 	if (linux_media_version < STp->linux_media_version) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Skipping frame %d with linux_media_version %d\n",
-				  dev, ppos, linux_media_version);
+		printk(OSST_DEB_MSG "%s:D: Skipping frame %d with linux_media_version %d\n",
+				  name, ppos, linux_media_version);
 #endif
 		return 0;
 	}
 	if (linux_media_version > STp->linux_media_version) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Frame %d sets linux_media_version to %d\n",
-				   dev, ppos, linux_media_version);
+		printk(OSST_DEB_MSG "%s:D: Frame %d sets linux_media_version to %d\n",
+				   name, ppos, linux_media_version);
 #endif
 		memcpy(STp->application_sig, id_string, 5);
 		STp->linux_media_version = linux_media_version;
@@ -2251,16 +2249,16 @@
 	}
 	if (update_frame_cntr > STp->update_frame_cntr) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Frame %d sets update_frame_counter to %d\n",
-				   dev, ppos, update_frame_cntr);
+		printk(OSST_DEB_MSG "%s:D: Frame %d sets update_frame_counter to %d\n",
+				   name, ppos, update_frame_cntr);
 #endif
 		if (STp->header_cache == NULL) {
 			if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
-				printk(KERN_ERR "osst%i:E: Failed to allocate header cache\n", dev);
+				printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
 				return 0;
 			}
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d:D: Allocated memory for header cache\n", dev);
+			printk(OSST_DEB_MSG "%s:D: Allocated memory for header cache\n", name);
 #endif
 		}
 		osst_copy_from_buffer(STp->buffer, (unsigned char *)STp->header_cache);
@@ -2276,18 +2274,18 @@
 		STp->last_mark_lbn     = ntohl(aux->last_mark_lbn);
 		STp->update_frame_cntr = update_frame_cntr;
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d:D: Detected write pass %d, update frame counter %d, filemark counter %d\n",
-			  dev, STp->wrt_pass_cntr, STp->update_frame_cntr, STp->filemark_cnt);
-	printk(OSST_DEB_MSG "osst%d:D: first data frame on tape = %d, last = %d, eod frame = %d\n", dev,
+	printk(OSST_DEB_MSG "%s:D: Detected write pass %d, update frame counter %d, filemark counter %d\n",
+			  name, STp->wrt_pass_cntr, STp->update_frame_cntr, STp->filemark_cnt);
+	printk(OSST_DEB_MSG "%s:D: first data frame on tape = %d, last = %d, eod frame = %d\n", name,
 			  STp->first_data_ppos,
 			  ntohl(header->partition[0].last_frame_ppos),
 			  ntohl(header->partition[0].eod_frame_ppos));
-	printk(OSST_DEB_MSG "osst%d:D: first mark on tape = %d, last = %d, eod frame = %d\n", 
-			  dev, STp->first_mark_ppos, STp->last_mark_ppos, STp->eod_frame_ppos);
+	printk(OSST_DEB_MSG "%s:D: first mark on tape = %d, last = %d, eod frame = %d\n", 
+			  name, STp->first_mark_ppos, STp->last_mark_ppos, STp->eod_frame_ppos);
 #endif
 		if (header->minor_rev < 4 && STp->linux_media_version == 4) {
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%i:D: Moving filemark list to ADR 1.4 location\n", dev);
+			printk(OSST_DEB_MSG "%s:D: Moving filemark list to ADR 1.4 location\n", name);
 #endif
 			memcpy((void *)header->dat_fm_tab.fm_tab_ent, 
 			       (void *)header->old_filemark_list, sizeof(header->dat_fm_tab.fm_tab_ent));
@@ -2312,7 +2310,7 @@
 		     header->dat_fm_tab.fm_tab_ent_sz                != 4                          ||
 		     header->dat_fm_tab.fm_tab_ent_cnt               !=
 			     htons(STp->filemark_cnt<OS_FM_TAB_MAX?STp->filemark_cnt:OS_FM_TAB_MAX)))
-			printk(KERN_WARNING "osst%i:W: Failed consistency check ADR 1.4 format\n", dev);
+			printk(KERN_WARNING "%s:W: Failed consistency check ADR 1.4 format\n", name);
 
 	}
 
@@ -2324,7 +2322,7 @@
 	int position, ppos;
 	int	first, last;
 	int	valid = 0;
-	int	dev = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 
 	position = osst_get_frame_position(STp, aSRpnt);
 
@@ -2338,7 +2336,7 @@
 	STp->eod_frame_ppos = STp->first_data_ppos = -1;
 	STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d:D: Reading header\n", dev);
+	printk(OSST_DEB_MSG "%s:D: Reading header\n", name);
 #endif
 
 	/* optimization for speed - if we are positioned at ppos 10, read second group first  */	
@@ -2359,7 +2357,7 @@
 			valid = 1;
 
 	if (!valid) {
-		printk(KERN_ERR "osst%i:E: Failed to find valid ADRL header, new media?\n", dev);
+		printk(KERN_ERR "%s:E: Failed to find valid ADRL header, new media?\n", name);
 		STp->eod_frame_ppos = STp->first_data_ppos = 0;
 		osst_set_frame_position(STp, aSRpnt, 10, 0);
 		return 0;
@@ -2384,14 +2382,14 @@
 	int	prev_mark_ppos  = -1;
 	int	actual_mark_ppos, i, n;
 #if DEBUG
-	int	dev = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 
-	printk(OSST_DEB_MSG "osst%d:D: Verify that the tape is really the one we think before writing\n", dev);
+	printk(OSST_DEB_MSG "%s:D: Verify that the tape is really the one we think before writing\n", name);
 #endif
 	osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
 	if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in verify_position\n", dev);
+		printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in verify_position\n", name);
 #endif
 		return (-EIO);
 	}
@@ -2407,7 +2405,7 @@
 	    frame_seq_numbr != STp->frame_seq_number + (halfway_frame?0:1) ||
 	    prev_mark_ppos  != actual_mark_ppos                            ) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Block mismatch: fppos %d-%d, fseq %d-%d, mark %d-%d\n", dev,
+		printk(OSST_DEB_MSG "%s:D: Block mismatch: fppos %d-%d, fseq %d-%d, mark %d-%d\n", name,
 				  STp->first_frame_position, frame_position, 
 				  STp->frame_seq_number + (halfway_frame?0:1),
 				  frame_seq_numbr, actual_mark_ppos, prev_mark_ppos);
@@ -2453,7 +2451,7 @@
 static int osst_configure_onstream(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt)
 {
 	unsigned char                  cmd[MAX_COMMAND_SIZE];
-	int                            dev   = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 	Scsi_Request                    * SRpnt = * aSRpnt;
 	osst_mode_parameter_header_t * header;
 	osst_block_size_page_t       * bs;
@@ -2463,14 +2461,14 @@
 
 	if (STp->ready != ST_READY) {
 #if DEBUG
-	    printk(OSST_DEB_MSG "osst%d:D: Not Ready\n", dev);
+	    printk(OSST_DEB_MSG "%s:D: Not Ready\n", name);
 #endif
 	    return (-EIO);
 	}
 	
 	if (STp->os_fw_rev < 10600) {
-	    printk(KERN_INFO "osst%i:I: Old OnStream firmware revision detected (%s),\n", dev, STp->device->rev);
-	    printk(KERN_INFO "osst%d:I: an upgrade to version 1.06 or above is recommended\n", dev);
+	    printk(KERN_INFO "%s:I: Old OnStream firmware revision detected (%s),\n", name, STp->device->rev);
+	    printk(KERN_INFO "%s:I: an upgrade to version 1.06 or above is recommended\n", name);
 	}
 
 	/*
@@ -2492,7 +2490,7 @@
 	}
 	*aSRpnt = SRpnt;
 	if ((STp->buffer)->syscall_result != 0) {
-	    printk (KERN_ERR "osst%i:E: Can't get tape block size mode page\n", dev);
+	    printk (KERN_ERR "%s:E: Can't get tape block size mode page\n", name);
 	    return (-EIO);
 	}
 
@@ -2500,10 +2498,10 @@
 	bs = (osst_block_size_page_t *) ((STp->buffer)->b_data + sizeof(osst_mode_parameter_header_t) + header->bdl);
 
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d:D: 32KB play back: %s\n",   dev, bs->play32     ? "Yes" : "No");
-	printk(OSST_DEB_MSG "osst%d:D: 32.5KB play back: %s\n", dev, bs->play32_5   ? "Yes" : "No");
-	printk(OSST_DEB_MSG "osst%d:D: 32KB record: %s\n",      dev, bs->record32   ? "Yes" : "No");
-	printk(OSST_DEB_MSG "osst%d:D: 32.5KB record: %s\n",    dev, bs->record32_5 ? "Yes" : "No");
+	printk(OSST_DEB_MSG "%s:D: 32KB play back: %s\n",   name, bs->play32     ? "Yes" : "No");
+	printk(OSST_DEB_MSG "%s:D: 32.5KB play back: %s\n", name, bs->play32_5   ? "Yes" : "No");
+	printk(OSST_DEB_MSG "%s:D: 32KB record: %s\n",      name, bs->record32   ? "Yes" : "No");
+	printk(OSST_DEB_MSG "%s:D: 32.5KB record: %s\n",    name, bs->record32_5 ? "Yes" : "No");
 #endif
 
 	/*
@@ -2523,12 +2521,12 @@
 	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE, STp->timeout, 0, TRUE);
 	*aSRpnt = SRpnt;
 	if ((STp->buffer)->syscall_result != 0) {
-	    printk (KERN_ERR "osst%i:E: Couldn't set tape block size mode page\n", dev);
+	    printk (KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name);
 	    return (-EIO);
 	}
 
 #if DEBUG
-	printk(KERN_INFO "osst%d:D: Drive Block Size changed to 32.5K\n", dev);
+	printk(KERN_INFO "%s:D: Drive Block Size changed to 32.5K\n", name);
 	 /*
 	 * In debug mode, we want to see as many errors as possible
 	 * to test the error recovery mechanism.
@@ -2564,7 +2562,7 @@
 	*aSRpnt = SRpnt;
 
 	if ((STp->buffer)->syscall_result != 0) {
-	    printk (KERN_ERR "osst%i:E: Couldn't set vendor name to %s\n", dev, 
+	    printk (KERN_ERR "%s:E: Couldn't set vendor name to %s\n", name, 
 			(char *) ((STp->buffer)->b_data + MODE_HEADER_LENGTH + 2));
 	    return (-EIO);
 	}
@@ -2579,7 +2577,7 @@
 	*aSRpnt = SRpnt;
 
 	if ((STp->buffer)->syscall_result != 0) {
-	    printk (KERN_ERR "osst%i:E: Can't get capabilities page\n", dev);
+	    printk (KERN_ERR "%s:E: Can't get capabilities page\n", name);
 	    return (-EIO);
 	}
 
@@ -2599,7 +2597,7 @@
 	*aSRpnt = SRpnt;
 
 	if ((STp->buffer)->syscall_result != 0) {
-	    printk (KERN_ERR "osst%i:E: Can't get tape parameter page\n", dev);
+	    printk (KERN_ERR "%s:E: Can't get tape parameter page\n", name);
 	    return (-EIO);
 	}
 
@@ -2610,8 +2608,8 @@
 	STp->density  = prm->density;
 	STp->capacity = ntohs(prm->segtrk) * ntohs(prm->trks);
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d:D: Density %d, tape length: %dMB, drive buffer size: %dKB\n",
-			  dev, STp->density, STp->capacity / 32, drive_buffer_size);
+	printk(OSST_DEB_MSG "%s:D: Density %d, tape length: %dMB, drive buffer size: %dKB\n",
+			  name, STp->density, STp->capacity / 32, drive_buffer_size);
 #endif
 
 	return 0;
@@ -2624,12 +2622,12 @@
 static int cross_eof(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int forward)
 {
 	int	result;
-	int	dev   = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 
 #if DEBUG
 	if (debugging)
-		printk(OSST_DEB_MSG "osst%d:D: Stepping over filemark %s.\n",
-	   			  dev, forward ? "forward" : "backward");
+		printk(OSST_DEB_MSG "%s:D: Stepping over filemark %s.\n",
+	   			  name, forward ? "forward" : "backward");
 #endif
 
 	if (forward) {
@@ -2641,8 +2639,8 @@
 	   result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - 1);
 
 	if (result < 0)
-	   printk(KERN_WARNING "osst%d:W: Stepping over filemark %s failed.\n",
-				dev, forward ? "forward" : "backward");
+	   printk(KERN_WARNING "%s:W: Stepping over filemark %s failed.\n",
+				name, forward ? "forward" : "backward");
 
 	return result;
 }
@@ -2661,7 +2659,7 @@
 	char		mybuf[24];
 	char	      * olddata = STp->buffer->b_data;
 	int		oldsize = STp->buffer->buffer_size;
-	int		dev     = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 
 	if (STp->ready != ST_READY) return (-EIO);
 
@@ -2681,7 +2679,7 @@
 		result = ((SRpnt->sr_sense_buffer[2] & 0x0f) == 3) ? -EIO : -EINVAL;
 
 	if (result == -EINVAL)
-		printk(KERN_ERR "osst%d:E: Can't read tape position.\n", dev);
+		printk(KERN_ERR "%s:E: Can't read tape position.\n", name);
 	else {
 
 		if (result == -EIO) {	/* re-read position */
@@ -2706,7 +2704,7 @@
 		STp->cur_frames           =  (STp->buffer)->b_data[15];
 #if DEBUG
 		if (debugging) {
-			printk(OSST_DEB_MSG "osst%d:D: Drive Positions: host %d, tape %d%s, buffer %d\n", dev,
+			printk(OSST_DEB_MSG "%s:D: Drive Positions: host %d, tape %d%s, buffer %d\n", name,
 					    STp->first_frame_position, STp->last_frame_position,
 					    ((STp->buffer)->b_data[0]&0x80)?" (BOP)":
 					    ((STp->buffer)->b_data[0]&0x40)?" (EOP)":"",
@@ -2715,7 +2713,7 @@
 #endif
 		if (STp->cur_frames == 0 && STp->first_frame_position != STp->last_frame_position) {
 #if DEBUG
-			printk(KERN_WARNING "osst%d:D: Correcting read position %d, %d, %d\n", dev,
+			printk(KERN_WARNING "%s:D: Correcting read position %d, %d, %d\n", name,
 					STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
 #endif
 			STp->first_frame_position = STp->last_frame_position;
@@ -2735,14 +2733,14 @@
 	ST_partstat   * STps;
 	int		result = 0;
 	int		pp  = (ppos == 3000 && !skip)? 0 : ppos;
-	int		dev = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 
 	if (STp->ready != ST_READY) return (-EIO);
 
 	STps = &(STp->ps[STp->partition]);
 
 	if (ppos < 0 || ppos > STp->capacity) {
-		printk(KERN_WARNING "osst%d:W: Reposition request %d out of range\n", dev, ppos);
+		printk(KERN_WARNING "%s:W: Reposition request %d out of range\n", name, ppos);
 		pp = ppos = ppos < 0 ? 0 : (STp->capacity - 1);
 		result = (-EINVAL);
 	}
@@ -2750,7 +2748,7 @@
 	do {
 #if DEBUG
 		if (debugging)
-			printk(OSST_DEB_MSG "osst%d:D: Setting ppos to %d.\n", dev, pp);
+			printk(OSST_DEB_MSG "%s:D: Setting ppos to %d.\n", name, pp);
 #endif
 		memset (scmd, 0, MAX_COMMAND_SIZE);
 		scmd[0] = SEEK_10;
@@ -2770,8 +2768,8 @@
 
 		if ((STp->buffer)->syscall_result != 0) {
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d:D: SEEK command from %d to %d failed.\n",
-					dev, STp->first_frame_position, pp);
+			printk(OSST_DEB_MSG "%s:D: SEEK command from %d to %d failed.\n",
+					name, STp->first_frame_position, pp);
 #endif
 			result = (-EIO);
 		}
@@ -2798,26 +2796,26 @@
 	unsigned char cmd[MAX_COMMAND_SIZE];
 	Scsi_Request * SRpnt = *aSRpnt;
 	ST_partstat * STps;
-	int dev = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 
 	if ((STp->buffer)->writing) {
 		if (SRpnt == (STp->buffer)->last_SRpnt)
 #if DEBUG
 			{ printk(OSST_DEB_MSG
-	 "osst%d:D: aSRpnt points to Scsi_Request that write_behind_check will release -- cleared\n", dev);
+	 "%s:D: aSRpnt points to Scsi_Request that write_behind_check will release -- cleared\n", name);
 #endif
 			*aSRpnt = SRpnt = NULL;
 #if DEBUG
 			} else if (SRpnt)
 				printk(OSST_DEB_MSG
-	 "osst%d:D: aSRpnt does not point to Scsi_Request that write_behind_check will release -- strange\n", dev);
+	 "%s:D: aSRpnt does not point to Scsi_Request that write_behind_check will release -- strange\n", name);
 #endif	
 		osst_write_behind_check(STp);
 		if ((STp->buffer)->syscall_result) {
 #if DEBUG
 			if (debugging)
-				printk(OSST_DEB_MSG "osst%d:D: Async write error (flush) %x.\n",
-				       dev, (STp->buffer)->midlevel_result);
+				printk(OSST_DEB_MSG "%s:D: Async write error (flush) %x.\n",
+				       name, (STp->buffer)->midlevel_result);
 #endif
 			if ((STp->buffer)->midlevel_result == INT_MAX)
 				return (-ENOSPC);
@@ -2851,8 +2849,8 @@
 		   case OS_WRITE_DATA:
 #if DEBUG
    			if (debugging)
-				printk(OSST_DEB_MSG "osst%d:D: Writing %d blocks to frame %d, lblks %d-%d\n",
-					dev, blks, STp->frame_seq_number, 
+				printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n",
+					name, blks, STp->frame_seq_number, 
 					STp->logical_blk_num - blks, STp->logical_blk_num - 1);
 #endif
 			osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
@@ -2874,8 +2872,8 @@
 		}
 #if DEBUG
 		if (debugging)
-			printk(OSST_DEB_MSG "osst%d:D: Flushing %d bytes, Transfering %d bytes in %d lblocks.\n",
-			  			 dev, offset, transfer, blks);
+			printk(OSST_DEB_MSG "%s:D: Flushing %d bytes, Transfering %d bytes in %d lblocks.\n",
+			  			 name, offset, transfer, blks);
 #endif
 
 		SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, SCSI_DATA_WRITE,
@@ -2887,8 +2885,8 @@
 		if ((STp->buffer)->syscall_result != 0) {
 #if DEBUG
 			printk(OSST_DEB_MSG
-				"osst%d:D: write sense [0]=0x%02x [2]=%02x [12]=%02x [13]=%02x\n",
-				dev, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2],
+				"%s:D: write sense [0]=0x%02x [2]=%02x [12]=%02x [13]=%02x\n",
+				name, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2],
 				SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
 #endif
 			if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
@@ -2900,7 +2898,7 @@
 			}
 			else {
 				if (osst_write_error_recovery(STp, aSRpnt, 1)) {
-					printk(KERN_ERR "osst%d:E: Error on flush write.\n", dev);
+					printk(KERN_ERR "%s:E: Error on flush write.\n", name);
 					result = (-EIO);
 				}
 			}
@@ -2913,7 +2911,7 @@
 		}
 	}
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d:D: Exit flush write buffer with code %d\n", dev, result);
+	printk(OSST_DEB_MSG "%s:D: Exit flush write buffer with code %d\n", name, result);
 #endif
 	return result;
 }
@@ -2926,7 +2924,7 @@
 	ST_partstat   * STps;
 	int backspace = 0, result = 0;
 #if DEBUG
-	int dev = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 #endif
 
 	/*
@@ -2947,7 +2945,7 @@
 		return 0;
 
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d:D: Reached flush (read) buffer\n", dev);
+	printk(OSST_DEB_MSG "%s:D: Reached flush (read) buffer\n", name);
 #endif
 
 	if (!STp->can_bsr) {
@@ -2988,12 +2986,12 @@
 	Scsi_Request     * SRpnt;
 	int		blks;
 #if DEBUG
-	int		dev = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 #endif
 
 	if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) { /* _must_ preserve buffer! */
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Reaching config partition.\n", dev);
+		printk(OSST_DEB_MSG "%s:D: Reaching config partition.\n", name);
 #endif
 		if (osst_flush_drive_buffer(STp, aSRpnt) < 0) {
 			return (-EIO);
@@ -3001,7 +2999,7 @@
 		/* error recovery may have bumped us past the header partition */
 		if (osst_get_frame_position(STp, aSRpnt) < 0xbb8) {
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d:D: Skipping over config partition.\n", dev);
+			printk(OSST_DEB_MSG "%s:D: Skipping over config partition.\n", name);
 #endif
 		osst_position_tape_and_confirm(STp, aSRpnt, 0xbb8);
 		}
@@ -3023,7 +3021,7 @@
 	blks     = STp->buffer->buffer_bytes / STp->block_size;
 #if DEBUG
 	if (debugging)
-		printk(OSST_DEB_MSG "osst%d:D: Writing %d blocks to frame %d, lblks %d-%d\n", dev, blks, 
+		printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n", name, blks, 
 			STp->frame_seq_number, STp->logical_blk_num - blks, STp->logical_blk_num - 1);
 #endif
 	osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
@@ -3043,7 +3041,7 @@
 		if (STp->buffer->syscall_result != 0) {
 #if DEBUG
 			if (debugging)
-				printk(OSST_DEB_MSG "osst%d:D: Error on write:\n", dev);
+				printk(OSST_DEB_MSG "%s:D: Error on write:\n", name);
 #endif
 			if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
 			    (SRpnt->sr_sense_buffer[2] & 0x40)) {
@@ -3070,19 +3068,17 @@
 /* Write command */
 static ssize_t osst_write(struct file * filp, const char * buf, size_t count, loff_t *ppos)
 {
-	struct inode *inode = filp->f_dentry->d_inode;
 	ssize_t total, retval = 0;
 	ssize_t i, do_count, blks, transfer;
 	int write_threshold;
 	int doing_write = 0;
 	const char *b_point;
 	Scsi_Request * SRpnt = NULL;
-	OS_Scsi_Tape * STp;
 	ST_mode * STm;
 	ST_partstat * STps;
-	int dev = TAPE_NR(inode->i_rdev);
+	OS_Scsi_Tape * STp = filp->private_data;
+	char *name = tape_name(STp);
 
-	STp = os_scsi_tapes[dev];
 
 	if (down_interruptible(&STp->lock))
 		return (-ERESTARTSYS);
@@ -3130,7 +3126,7 @@
 
 #if DEBUG
 	if (!STp->in_use) {
-		printk(OSST_DEB_MSG "osst%d:D: Incorrect device.\n", dev);
+		printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
 		retval = (-EIO);
 		goto out;
 	}
@@ -3143,16 +3139,16 @@
 
 	/* Write must be integral number of blocks */
 	if (STp->block_size != 0 && (count % STp->block_size) != 0) {
-		printk(KERN_ERR "osst%d:E: Write (%ld bytes) not multiple of tape block size (%d%c).\n",
-				       dev, (unsigned long)count, STp->block_size<1024?
+		printk(KERN_ERR "%s:E: Write (%ld bytes) not multiple of tape block size (%d%c).\n",
+				       name, (unsigned long)count, STp->block_size<1024?
 				       STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
 		retval = (-EINVAL);
 		goto out;
 	}
 
 	if (STp->first_frame_position >= STp->capacity - OSST_EOM_RESERVE) {
-		printk(KERN_ERR "osst%d:E: Write truncated at EOM early warning (frame %d).\n",
-				       dev, STp->first_frame_position);
+		printk(KERN_ERR "%s:E: Write truncated at EOM early warning (frame %d).\n",
+				       name, STp->first_frame_position);
 		retval = (-ENOSPC);
 		goto out;
 	}
@@ -3177,8 +3173,8 @@
 		    (STps->drv_file == 0 && STps->drv_block == 0)) {
 			STp->wrt_pass_cntr++;
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d:D: Allocating next write pass counter: %d\n",
-						  dev, STp->wrt_pass_cntr);
+			printk(OSST_DEB_MSG "%s:D: Allocating next write pass counter: %d\n",
+						  name, STp->wrt_pass_cntr);
 #endif
 			osst_reset_header(STp, &SRpnt);
 			STps->drv_file = STps->drv_block = 0;
@@ -3195,7 +3191,7 @@
 					/* We have no idea where the tape is positioned - give up */
 #if DEBUG
 					printk(OSST_DEB_MSG
-						"osst%d:D: Cannot write at indeterminate position.\n", dev);
+						"%s:D: Cannot write at indeterminate position.\n", name);
 #endif
 					retval = (-EIO);
 					goto out;
@@ -3206,15 +3202,15 @@
 				STp->last_mark_ppos =
 				       	ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt-1]);
 				printk(KERN_WARNING
-					"osst%d:W: Overwriting file %d with old write pass counter %d\n",
-						dev, STps->drv_file, STp->wrt_pass_cntr);
+					"%s:W: Overwriting file %d with old write pass counter %d\n",
+						name, STps->drv_file, STp->wrt_pass_cntr);
 				printk(KERN_WARNING
-					"osst%d:W: may lead to stale data being accepted on reading back!\n",
-						dev);
+					"%s:W: may lead to stale data being accepted on reading back!\n",
+						name);
 #if DEBUG
 				printk(OSST_DEB_MSG
-				  "osst%d:D: resetting filemark count to %d and last mark ppos,lbn to %d,%d\n",
-					dev, STp->filemark_cnt, STp->last_mark_ppos, STp->last_mark_lbn);
+				  "%s:D: resetting filemark count to %d and last mark ppos,lbn to %d,%d\n",
+					name, STp->filemark_cnt, STp->last_mark_ppos, STp->last_mark_lbn);
 #endif
 			}
 		}
@@ -3222,19 +3218,19 @@
 	}
 	if (!STp->header_ok) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Write cannot proceed without valid headers\n", dev);
+		printk(OSST_DEB_MSG "%s:D: Write cannot proceed without valid headers\n", name);
 #endif
 		retval = (-EIO);
 		goto out;
 	}
 
 	if ((STp->buffer)->writing) {
-if (SRpnt) printk(KERN_ERR "osst%d:A: Not supposed to have SRpnt at line %d\n", dev, __LINE__);
+if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name, __LINE__);
 		osst_write_behind_check(STp);
 		if ((STp->buffer)->syscall_result) {
 #if DEBUG
 		if (debugging)
-			printk(OSST_DEB_MSG "osst%d:D: Async write error (write) %x.\n", dev,
+			printk(OSST_DEB_MSG "%s:D: Async write error (write) %x.\n", name,
 						 (STp->buffer)->midlevel_result);
 #endif
 		if ((STp->buffer)->midlevel_result == INT_MAX)
@@ -3271,8 +3267,8 @@
 	total = count;
 #if DEBUG
 	if (debugging)
-		printk(OSST_DEB_MSG "osst%d:D: Writing %d bytes to file %d block %d lblk %d fseq %d fppos %d\n",
-				dev, count, STps->drv_file, STps->drv_block,
+		printk(OSST_DEB_MSG "%s:D: Writing %d bytes to file %d block %d lblk %d fseq %d fppos %d\n",
+				name, count, STps->drv_file, STps->drv_block,
 				STp->logical_blk_num, STp->frame_seq_number, STp->first_frame_position);
 #endif
 	b_point = buf;
@@ -3307,8 +3303,8 @@
 				retval = (-ENOSPC);		/* EOM within current request */
 #if DEBUG
 				if (debugging)
-				      printk(OSST_DEB_MSG "osst%d:D: EOM with %d bytes unwritten.\n",
-							     dev, transfer);
+				      printk(OSST_DEB_MSG "%s:D: EOM with %d bytes unwritten.\n",
+							     name, transfer);
 #endif
 			}
 			else {
@@ -3317,7 +3313,7 @@
 				retval = (-EIO);		/* EOM for old data */
 #if DEBUG
 				if (debugging)
-				      printk(OSST_DEB_MSG "osst%d:D: EOM with lost data.\n", dev);
+				      printk(OSST_DEB_MSG "%s:D: EOM with lost data.\n", name);
 #endif
 			}
 		}
@@ -3399,17 +3395,15 @@
 /* Read command */
 static ssize_t osst_read(struct file * filp, char * buf, size_t count, loff_t *ppos)
 {
-	struct inode * inode = filp->f_dentry->d_inode;
 	ssize_t total, retval = 0;
 	ssize_t i, transfer;
 	int special;
-	OS_Scsi_Tape * STp;
 	ST_mode * STm;
 	ST_partstat * STps;
 	Scsi_Request *SRpnt = NULL;
-	int dev = TAPE_NR(inode->i_rdev);
+	OS_Scsi_Tape * STp = filp->private_data;
+	char *name = tape_name(STp);
 
-	STp = os_scsi_tapes[dev];
 
 	if (down_interruptible(&STp->lock))
 		return (-ERESTARTSYS);
@@ -3445,7 +3439,7 @@
 	}
 #if DEBUG
 	if (!STp->in_use) {
-		printk(OSST_DEB_MSG "osst%d:D: Incorrect device.\n", dev);
+		printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
 		retval = (-EIO);
 		goto out;
 	}
@@ -3471,13 +3465,13 @@
 
 	if ((count % STp->block_size) != 0) {
 		printk(KERN_WARNING
-		    "osst%d:W: Read (%Zd bytes) not multiple of tape block size (%d%c).\n", dev, count,
+		    "%s:W: Read (%Zd bytes) not multiple of tape block size (%d%c).\n", name, count,
 		    STp->block_size<1024?STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
 	}
 
 #if DEBUG
 	if (debugging && STps->eof != ST_NOEOF)
-		printk(OSST_DEB_MSG "osst%d:D: EOF/EOM flag up (%d). Bytes %d\n", dev,
+		printk(OSST_DEB_MSG "%s:D: EOF/EOM flag up (%d). Bytes %d\n", name,
 				     STps->eof, (STp->buffer)->buffer_bytes);
 #endif
 	if ((STp->buffer)->buffer_bytes == 0 &&
@@ -3520,7 +3514,7 @@
 		if ((STp->buffer)->buffer_bytes > 0) {
 #if DEBUG
 			if (debugging && STps->eof != ST_NOEOF)
-			    printk(OSST_DEB_MSG "osst%d:D: EOF up (%d). Left %d, needed %d.\n", dev,
+			    printk(OSST_DEB_MSG "%s:D: EOF up (%d). Left %d, needed %d.\n", name,
 						 STps->eof, (STp->buffer)->buffer_bytes, count - total);
 #endif
 			transfer = (((STp->buffer)->buffer_bytes < count - total ?
@@ -3541,8 +3535,8 @@
 		if ((STp->buffer)->buffer_bytes == 0) {
 #if DEBUG
 			if (debugging)
-				printk(OSST_DEB_MSG "osst%d:D: Finished with frame %d\n",
-					       	dev, STp->frame_seq_number);
+				printk(OSST_DEB_MSG "%s:D: Finished with frame %d\n",
+					       	name, STp->frame_seq_number);
 #endif
 			STp->frame_in_buffer = 0;
 			STp->frame_seq_number++;              /* frame to look for next time */
@@ -3581,25 +3575,25 @@
 
 
 /* Set the driver options */
-static void osst_log_options(OS_Scsi_Tape *STp, ST_mode *STm, int dev)
+static void osst_log_options(OS_Scsi_Tape *STp, ST_mode *STm, char *name)
 {
   printk(KERN_INFO
-"osst%d:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
-	 dev, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
+"%s:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
+	 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
 	 STm->do_read_ahead);
   printk(KERN_INFO
-"osst%d:I:    can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
-	 dev, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
+"%s:I:    can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
+	 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
   printk(KERN_INFO
-"osst%d:I:    defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
-	 dev, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
+"%s:I:    defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
+	 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
 	 STp->scsi2_logical);
   printk(KERN_INFO
-"osst%d:I:    sysv: %d\n", dev, STm->sysv);
+"%s:I:    sysv: %d\n", name, STm->sysv);
 #if DEBUG
   printk(KERN_INFO
-	 "osst%d:D:    debugging: %d\n",
-	 dev, debugging);
+	 "%s:D:    debugging: %d\n",
+	 name, debugging);
 #endif
 }
 
@@ -3609,7 +3603,7 @@
 	int value;
 	long code;
 	ST_mode *STm;
-	int dev = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 
 	STm = &(STp->modes[STp->current_mode]);
 	if (!STm->defined) {
@@ -3617,8 +3611,8 @@
 		modes_defined = TRUE;
 #if DEBUG
 		if (debugging)
-			printk(OSST_DEB_MSG "osst%d:D: Initialized mode %d definition from mode 0\n",
-					     dev, STp->current_mode);
+			printk(OSST_DEB_MSG "%s:D: Initialized mode %d definition from mode 0\n",
+					     name, STp->current_mode);
 #endif
 	}
 
@@ -3640,7 +3634,7 @@
 #if DEBUG
 		debugging = (options & MT_ST_DEBUGGING) != 0;
 #endif
-		osst_log_options(STp, STm, dev);
+		osst_log_options(STp, STm, name);
 	}
 	else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
 		value = (code == MT_ST_SETBOOLEANS);
@@ -3673,46 +3667,46 @@
 		if ((options & MT_ST_DEBUGGING) != 0)
 			debugging = value;
 #endif
-		osst_log_options(STp, STm, dev);
+		osst_log_options(STp, STm, name);
 	}
 	else if (code == MT_ST_WRITE_THRESHOLD) {
 		value = (options & ~MT_ST_OPTIONS) * ST_KILOBYTE;
 		if (value < 1 || value > osst_buffer_size) {
-			printk(KERN_WARNING "osst%d:W: Write threshold %d too small or too large.\n",
-					     dev, value);
+			printk(KERN_WARNING "%s:W: Write threshold %d too small or too large.\n",
+					     name, value);
 			return (-EIO);
 		}
 		STp->write_threshold = value;
-		printk(KERN_INFO "osst%d:I: Write threshold set to %d bytes.\n",
-				  dev, value);
+		printk(KERN_INFO "%s:I: Write threshold set to %d bytes.\n",
+				  name, value);
 	}
 	else if (code == MT_ST_DEF_BLKSIZE) {
 		value = (options & ~MT_ST_OPTIONS);
 		if (value == ~MT_ST_OPTIONS) {
 			STm->default_blksize = (-1);
-			printk(KERN_INFO "osst%d:I: Default block size disabled.\n", dev);
+			printk(KERN_INFO "%s:I: Default block size disabled.\n", name);
 		}
 		else {
 			if (value < 512 || value > OS_DATA_SIZE || OS_DATA_SIZE % value) {
-				printk(KERN_WARNING "osst%d:W: Default block size cannot be set to %d.\n",
-							 dev, value);
+				printk(KERN_WARNING "%s:W: Default block size cannot be set to %d.\n",
+							 name, value);
 				return (-EINVAL);
 			}
 			STm->default_blksize = value;
-			printk(KERN_INFO "osst%d:I: Default block size set to %d bytes.\n",
-					  dev, STm->default_blksize);
+			printk(KERN_INFO "%s:I: Default block size set to %d bytes.\n",
+					  name, STm->default_blksize);
 		}
 	}
 	else if (code == MT_ST_TIMEOUTS) {
 		value = (options & ~MT_ST_OPTIONS);
 		if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
 			STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
-			printk(KERN_INFO "osst%d:I: Long timeout set to %d seconds.\n", dev,
+			printk(KERN_INFO "%s:I: Long timeout set to %d seconds.\n", name,
 					     (value & ~MT_ST_SET_LONG_TIMEOUT));
 		}
 		else {
 			STp->timeout = value * HZ;
-			printk(KERN_INFO "osst%d:I: Normal timeout set to %d seconds.\n", dev, value);
+			printk(KERN_INFO "%s:I: Normal timeout set to %d seconds.\n", name, value);
 		}
 	}
 	else if (code == MT_ST_DEF_OPTIONS) {
@@ -3721,34 +3715,34 @@
 		if (code == MT_ST_DEF_DENSITY) {
 			if (value == MT_ST_CLEAR_DEFAULT) {
 				STm->default_density = (-1);
-				printk(KERN_INFO "osst%d:I: Density default disabled.\n", dev);
+				printk(KERN_INFO "%s:I: Density default disabled.\n", name);
 			}
 			else {
 				STm->default_density = value & 0xff;
-				printk(KERN_INFO "osst%d:I: Density default set to %x\n",
-						  dev, STm->default_density);
+				printk(KERN_INFO "%s:I: Density default set to %x\n",
+						  name, STm->default_density);
 			}
 		}
 		else if (code == MT_ST_DEF_DRVBUFFER) {
 			if (value == MT_ST_CLEAR_DEFAULT) {
 				STp->default_drvbuffer = 0xff;
-				printk(KERN_INFO "osst%d:I: Drive buffer default disabled.\n", dev);
+				printk(KERN_INFO "%s:I: Drive buffer default disabled.\n", name);
 			}
 			else {
 				STp->default_drvbuffer = value & 7;
-				printk(KERN_INFO "osst%d:I: Drive buffer default set to %x\n",
-						  dev, STp->default_drvbuffer);
+				printk(KERN_INFO "%s:I: Drive buffer default set to %x\n",
+						  name, STp->default_drvbuffer);
 			}
 		}
 		else if (code == MT_ST_DEF_COMPRESSION) {
 			if (value == MT_ST_CLEAR_DEFAULT) {
 				STm->default_compression = ST_DONT_TOUCH;
-				printk(KERN_INFO "osst%d:I: Compression default disabled.\n", dev);
+				printk(KERN_INFO "%s:I: Compression default disabled.\n", name);
 			}
 			else {
 				STm->default_compression = (value & 1 ? ST_YES : ST_NO);
-				printk(KERN_INFO "osst%d:I: Compression default set to %x\n",
-						  dev, (value & 1));
+				printk(KERN_INFO "%s:I: Compression default set to %x\n",
+						  name, (value & 1));
 			}
 		}
 	}
@@ -3771,7 +3765,7 @@
 	ST_partstat * STps;
 	int fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num;
 	int datalen = 0, direction = SCSI_DATA_NONE;
-	int dev = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 
 	if (STp->ready != ST_READY && cmd_in != MTLOAD) {
 		if (STp->ready == ST_NO_TAPE)
@@ -3820,8 +3814,8 @@
 	 case MTBSR:
 #if DEBUG
 		if (debugging)
-		   printk(OSST_DEB_MSG "osst%d:D: Skipping %lu blocks %s from logical block %d\n",
-				dev, arg, cmd_in==MTFSR?"forward":"backward", logical_blk_num);
+		   printk(OSST_DEB_MSG "%s:D: Skipping %lu blocks %s from logical block %d\n",
+				name, arg, cmd_in==MTFSR?"forward":"backward", logical_blk_num);
 #endif
 		if (cmd_in == MTFSR) {
 		   logical_blk_num += arg;
@@ -3845,7 +3839,7 @@
 		cmd[4] = arg;
 #if DEBUG
 		if (debugging)
-			printk(OSST_DEB_MSG "osst%d:D: Spacing tape forward %d setmarks.\n", dev,
+			printk(OSST_DEB_MSG "%s:D: Spacing tape forward %d setmarks.\n", name,
 		cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
 #endif
 		if (arg != 0) {
@@ -3865,8 +3859,8 @@
 			if (cmd[2] & 0x80)
 			   ltmp = 0xff000000;
 			ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
-			printk(OSST_DEB_MSG "osst%d:D: Spacing tape backward %ld setmarks.\n",
-						dev, (-ltmp));
+			printk(OSST_DEB_MSG "%s:D: Spacing tape backward %ld setmarks.\n",
+						name, (-ltmp));
 		 }
 #endif
 		 if (arg != 0) {
@@ -3881,7 +3875,7 @@
 			ioctl_result = 0;
 #if DEBUG
 		 if (debugging) 
-			   printk(OSST_DEB_MSG "osst%d:D: Writing %ld filemark(s).\n", dev, arg);
+			   printk(OSST_DEB_MSG "%s:D: Writing %ld filemark(s).\n", name, arg);
 #endif
 		 for (i=0; i<arg; i++)
 			ioctl_result |= osst_write_filemark(STp, &SRpnt);
@@ -3903,7 +3897,7 @@
 		 timeout = STp->timeout;
 #if DEBUG
 		 if (debugging) 
-			   printk(OSST_DEB_MSG "osst%d:D: Writing %d setmark(s).\n", dev,
+			   printk(OSST_DEB_MSG "%s:D: Writing %d setmark(s).\n", name,
 				  cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
 #endif
 		 if (fileno >= 0)
@@ -3932,16 +3926,16 @@
 		 if (debugging) {
 			 switch (cmd_in) {
 				 case MTUNLOAD:
-					 printk(OSST_DEB_MSG "osst%d:D: Unloading tape.\n", dev);
+					 printk(OSST_DEB_MSG "%s:D: Unloading tape.\n", name);
 					 break;
 				 case MTLOAD:
-					 printk(OSST_DEB_MSG "osst%d:D: Loading tape.\n", dev);
+					 printk(OSST_DEB_MSG "%s:D: Loading tape.\n", name);
 					 break;
 				 case MTRETEN:
-					 printk(OSST_DEB_MSG "osst%d:D: Retensioning tape.\n", dev);
+					 printk(OSST_DEB_MSG "%s:D: Retensioning tape.\n", name);
 					 break;
 				 case MTOFFL:
-					 printk(OSST_DEB_MSG "osst%d:D: Ejecting tape.\n", dev);
+					 printk(OSST_DEB_MSG "%s:D: Ejecting tape.\n", name);
 					 break;
 			 }
 		 }
@@ -3951,14 +3945,14 @@
 	 case MTNOP:
 #if DEBUG
 		 if (debugging)
-			 printk(OSST_DEB_MSG "osst%d:D: No-op on tape.\n", dev);
+			 printk(OSST_DEB_MSG "%s:D: No-op on tape.\n", name);
 #endif
 		 return 0;  /* Should do something ? */
 		 break;
 	 case MTEOM:
 #if DEBUG
 		if (debugging)
-		   printk(OSST_DEB_MSG "osst%d:D: Spacing to end of recorded medium.\n", dev);
+		   printk(OSST_DEB_MSG "%s:D: Spacing to end of recorded medium.\n", name);
 #endif
 		osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0);
 	if (osst_get_logical_frame(STp, &SRpnt, -1, 0) < 0) {
@@ -3967,7 +3961,7 @@
 		}
 		if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_EOD) {
 #if DEBUG
-		   printk(OSST_DEB_MSG "osst%d:D: No EOD frame found where expected.\n", dev);
+		   printk(OSST_DEB_MSG "%s:D: No EOD frame found where expected.\n", name);
 #endif
 		   ioctl_result = -EIO;
 		   goto os_bypass;
@@ -3993,7 +3987,7 @@
 		cmd[1] = 1;
 #if DEBUG
 		if (debugging)
-		   printk(OSST_DEB_MSG "osst%d:D: Rewinding tape, Immed=%d.\n", dev, cmd[1]);
+		   printk(OSST_DEB_MSG "%s:D: Rewinding tape, Immed=%d.\n", name, cmd[1]);
 #endif
 		fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
 		break;
@@ -4004,7 +3998,7 @@
 		cmd[4] = SCSI_REMOVAL_PREVENT;
 #if DEBUG
 		if (debugging)
-		    printk(OSST_DEB_MSG "osst%d:D: Locking drive door.\n", dev);
+		    printk(OSST_DEB_MSG "%s:D: Locking drive door.\n", name);
 #endif
 		break;
 
@@ -4014,7 +4008,7 @@
 		cmd[4] = SCSI_REMOVAL_ALLOW;
 #if DEBUG
 		if (debugging)
-		   printk(OSST_DEB_MSG "osst%d:D: Unlocking drive door.\n", dev);
+		   printk(OSST_DEB_MSG "%s:D: Unlocking drive door.\n", name);
 #endif
 	break;
 
@@ -4030,7 +4024,7 @@
 		   ((arg & MT_ST_BLKSIZE_MASK) < STp->min_block ||
 		    (arg & MT_ST_BLKSIZE_MASK) > STp->max_block ||
 		    (arg & MT_ST_BLKSIZE_MASK) > osst_buffer_size)) {
-			 printk(KERN_WARNING "osst%d:W: Illegal block size.\n", dev);
+			 printk(KERN_WARNING "%s:W: Illegal block size.\n", name);
 			 return (-EINVAL);
 		 }
 		 return 0;  /* FIXME silently ignore if block size didn't change */
@@ -4045,7 +4039,7 @@
 
 	if (!SRpnt) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Couldn't exec scsi cmd for IOCTL\n", dev);
+		printk(OSST_DEB_MSG "%s:D: Couldn't exec scsi cmd for IOCTL\n", name);
 #endif
 		return ioctl_result;
 	}
@@ -4058,7 +4052,7 @@
 os_bypass:
 #if DEBUG
 	if (debugging)
-		printk(OSST_DEB_MSG "osst%d:D: IOCTL (%d) Result=%d\n", dev, cmd_in, ioctl_result);
+		printk(OSST_DEB_MSG "%s:D: IOCTL (%d) Result=%d\n", name, cmd_in, ioctl_result);
 #endif
 
 	if (!ioctl_result) {				/* success */
@@ -4158,18 +4152,22 @@
 	ST_mode * STm;
 	ST_partstat * STps;
 	int dev = TAPE_NR(inode->i_rdev);
+	char *name;
 	int mode = TAPE_MODE(inode->i_rdev);
 
 	if (dev >= osst_template.dev_max || (STp = os_scsi_tapes[dev]) == NULL || !STp->device)
 		return (-ENXIO);
 
+	filp->private_data = STp;
+	name = tape_name(STp);
+
 	if( !scsi_block_when_processing_errors(STp->device) ) {
 		return -ENXIO;
 	}
 
 	if (STp->in_use) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Device already in use.\n", dev);
+		printk(OSST_DEB_MSG "%s:D: Device already in use.\n", name);
 #endif
 		return (-EBUSY);
 	}
@@ -4185,8 +4183,8 @@
 	if (mode != STp->current_mode) {
 #if DEBUG
 		if (debugging)
-			printk(OSST_DEB_MSG "osst%d:D: Mode change from %d to %d.\n",
-					       dev, STp->current_mode, mode);
+			printk(OSST_DEB_MSG "%s:D: Mode change from %d to %d.\n",
+					       name, STp->current_mode, mode);
 #endif
 		new_session = TRUE;
 		STp->current_mode = mode;
@@ -4209,7 +4207,7 @@
 	if (i >= osst_nbr_buffers) {
 		STp->buffer = new_tape_buffer(FALSE, need_dma_buffer);
 		if (STp->buffer == NULL) {
-			printk(KERN_WARNING "osst%d:W: Can't allocate tape buffer.\n", dev);
+			printk(KERN_WARNING "%s:W: Can't allocate tape buffer.\n", name);
 			retval = (-EBUSY);
 			goto err_out;
 		}
@@ -4252,7 +4250,7 @@
 	    (SRpnt->sr_sense_buffer[2] & 0x0f) == NOT_READY &&
 	     SRpnt->sr_sense_buffer[12]        == 4         ) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Unit not ready, cause %x\n", dev, SRpnt->sr_sense_buffer[13]);
+		printk(OSST_DEB_MSG "%s:D: Unit not ready, cause %x\n", name, SRpnt->sr_sense_buffer[13]);
 #endif
 		if (SRpnt->sr_sense_buffer[13] == 2) {	/* initialize command required (LOAD) */
 			memset (cmd, 0, MAX_COMMAND_SIZE);
@@ -4267,7 +4265,7 @@
 	if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
 	    (SRpnt->sr_sense_buffer[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Unit wants attention\n", dev);
+		printk(OSST_DEB_MSG "%s:D: Unit wants attention\n", name);
 #endif
 		STp->header_ok = 0;
 
@@ -4320,7 +4318,7 @@
 		    STp->buffer->b_data[MODE_HEADER_LENGTH + 4] != 'N' ||
 		    STp->buffer->b_data[MODE_HEADER_LENGTH + 5] != '4'  ) {
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d:D: Signature was changed to %c%c%c%c\n", dev,
+			printk(OSST_DEB_MSG "%s:D: Signature was changed to %c%c%c%c\n", name,
 			  STp->buffer->b_data[MODE_HEADER_LENGTH + 2],
 			  STp->buffer->b_data[MODE_HEADER_LENGTH + 3],
 			  STp->buffer->b_data[MODE_HEADER_LENGTH + 4],
@@ -4332,7 +4330,7 @@
 		if (STp->header_ok && i == osst_get_frame_position(STp, &SRpnt)) {
 			if (STp->door_locked == ST_UNLOCKED) {
 				if (osst_int_ioctl(STp, &SRpnt, MTLOCK, 0))
-					printk(KERN_INFO "osst%d:I: Can't lock drive door\n", dev);
+					printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
 				else
 					STp->door_locked = ST_LOCKED_AUTO;
 			}
@@ -4348,8 +4346,8 @@
 		}
 #if DEBUG
 		if (i != STp->first_frame_position)
-			printk(OSST_DEB_MSG "osst%d:D: Tape position changed from %d to %d\n",
-						dev, i, STp->first_frame_position);
+			printk(OSST_DEB_MSG "%s:D: Tape position changed from %d to %d\n",
+						name, i, STp->first_frame_position);
 #endif
 		STp->header_ok = 0;
 	}
@@ -4373,7 +4371,7 @@
 		(STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 3;
 
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: Applying soft reset\n", dev);
+		printk(OSST_DEB_MSG "%s:D: Applying soft reset\n", name);
 #endif
 		SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE, STp->timeout, 0, TRUE);
 
@@ -4410,7 +4408,7 @@
 	}
 
 	if (osst_wait_ready(STp, &SRpnt, 15 * 60))		/* FIXME - not allowed with NOBLOCK */
-		 printk(KERN_INFO "osst%i:I: Device did not become Ready in open\n",dev);
+		 printk(KERN_INFO "%s:I: Device did not become Ready in open\n",name);
 
 	if ((STp->buffer)->syscall_result != 0) {
 		if ((STp->device)->scsi_level >= SCSI_2 &&
@@ -4437,7 +4435,7 @@
 
 	if (OS_FRAME_SIZE > (STp->buffer)->buffer_size &&
 	    !enlarge_buffer(STp->buffer, OS_FRAME_SIZE, STp->restr_dma)) {
-		printk(KERN_NOTICE "osst%d:A: Framesize %d too large for buffer.\n", dev,
+		printk(KERN_NOTICE "%s:A: Framesize %d too large for buffer.\n", name,
 				     OS_FRAME_SIZE);
 		retval = (-EIO);
 		goto err_out;
@@ -4449,9 +4447,9 @@
 		     b_size += STp->buffer->sg[i++].length);
 		STp->buffer->aux = (os_aux_t *) (page_address(STp->buffer->sg[i].page) + OS_DATA_SIZE - b_size);
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d:D: b_data points to %p in segment 0 at %p\n", dev,
+		printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name,
 			STp->buffer->b_data, page_address(STp->buffer->sg[0].page));
-		printk(OSST_DEB_MSG "osst%d:D: AUX points to %p in segment %d at %p\n", dev,
+		printk(OSST_DEB_MSG "%s:D: AUX points to %p in segment %d at %p\n", name,
 			 STp->buffer->aux, i, page_address(STp->buffer->sg[i].page));
 #endif
 	} else
@@ -4466,8 +4464,8 @@
 
 #if DEBUG
 	if (debugging)
-		printk(OSST_DEB_MSG "osst%d:D: Block size: %d, frame size: %d, buffer size: %d (%d blocks).\n",
-		     dev, STp->block_size, OS_FRAME_SIZE, (STp->buffer)->buffer_size,
+		printk(OSST_DEB_MSG "%s:D: Block size: %d, frame size: %d, buffer size: %d (%d blocks).\n",
+		     name, STp->block_size, OS_FRAME_SIZE, (STp->buffer)->buffer_size,
 		     (STp->buffer)->buffer_blocks);
 #endif
 
@@ -4475,7 +4473,7 @@
 		STp->write_prot = 1;
 #if DEBUG
 		if (debugging)
-			printk(OSST_DEB_MSG "osst%d:D: Write protected\n", dev);
+			printk(OSST_DEB_MSG "%s:D: Write protected\n", name);
 #endif
 		if ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR) {
 			retval = (-EROFS);
@@ -4486,7 +4484,7 @@
 	if (new_session) {  /* Change the drive parameters for the new mode */
 #if DEBUG
 		if (debugging)
-	printk(OSST_DEB_MSG "osst%d:D: New Session\n", dev);
+	printk(OSST_DEB_MSG "%s:D: New Session\n", name);
 #endif
 		STp->density_changed = STp->blksize_changed = FALSE;
 		STp->compression_changed = FALSE;
@@ -4497,7 +4495,7 @@
 	 */
 	if (STp->door_locked == ST_UNLOCKED) {
 		 if (osst_int_ioctl(STp, &SRpnt, MTLOCK, 0))
-			printk(KERN_INFO "osst%d:I: Can't lock drive door\n", dev);
+			printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
 		 else
 			STp->door_locked = ST_LOCKED_AUTO;
 	}
@@ -4533,22 +4531,14 @@
 static int os_scsi_tape_flush(struct file * filp)
 {
 	int result = 0, result2;
-	OS_Scsi_Tape * STp;
-	ST_mode * STm;
-	ST_partstat * STps;
+	OS_Scsi_Tape * STp = filp->private_data;
+	ST_mode * STm = &(STp->modes[STp->current_mode]);
+	ST_partstat * STps = &(STp->ps[STp->partition]);
 	Scsi_Request *SRpnt = NULL;
-
-	struct inode *inode = filp->f_dentry->d_inode;
-	kdev_t devt = inode->i_rdev;
-	int dev;
+	char *name = tape_name(STp);
 
 	if (file_count(filp) > 1)
-	return 0;
-
-	dev = TAPE_NR(devt);
-	STp = os_scsi_tapes[dev];
-	STm = &(STp->modes[STp->current_mode]);
-	STps = &(STp->ps[STp->partition]);
+		return 0;
 
 	if ( STps->rw == ST_WRITING && !(STp->device)->was_reset) {
 		result = osst_flush_write_buffer(STp, &SRpnt);
@@ -4559,10 +4549,10 @@
 
 #if DEBUG
 		if (debugging) {
-			printk(OSST_DEB_MSG "osst%d:D: File length %ld bytes.\n",
-					       dev, (long)(filp->f_pos));
-			printk(OSST_DEB_MSG "osst%d:D: Async write waits %d, finished %d.\n",
-					       dev, STp->nbr_waits, STp->nbr_finished);
+			printk(OSST_DEB_MSG "%s:D: File length %ld bytes.\n",
+					       name, (long)(filp->f_pos));
+			printk(OSST_DEB_MSG "%s:D: Async write waits %d, finished %d.\n",
+					       name, STp->nbr_waits, STp->nbr_finished);
 		}
 #endif
 		if (STp->write_type != OS_WRITE_NEW_MARK) {
@@ -4583,8 +4573,8 @@
 
 #if DEBUG
 		if (debugging)
-			printk(OSST_DEB_MSG "osst%d:D: Buffer flushed, %d EOF(s) written\n",
-					       dev, 1+STp->two_fm);
+			printk(OSST_DEB_MSG "%s:D: Buffer flushed, %d EOF(s) written\n",
+					       name, 1+STp->two_fm);
 #endif
 	}
 	else if (!STp->rew_at_close) {
@@ -4624,7 +4614,7 @@
 	if (SRpnt) scsi_release_request(SRpnt);
 
 	if (STp->recover_count) {
-		printk(KERN_INFO "osst%d:I: %d recovered errors in", dev, STp->recover_count);
+		printk(KERN_INFO "%s:I: %d recovered errors in", name, STp->recover_count);
 		if (STp->write_count)
 			printk(" %d frames written", STp->write_count);
 		if (STp->read_count)
@@ -4643,15 +4633,9 @@
 static int os_scsi_tape_close(struct inode * inode, struct file * filp)
 {
 	int result = 0;
-	OS_Scsi_Tape * STp;
+	OS_Scsi_Tape * STp = filp->private_data;
 	Scsi_Request * SRpnt = NULL;
 
-	kdev_t devt = inode->i_rdev;
-	int dev;
-
-	dev = TAPE_NR(devt);
-	STp = os_scsi_tapes[dev];
-
 	if (STp->door_locked == ST_LOCKED_AUTO)
 		osst_int_ioctl(STp, &SRpnt, MTUNLOCK, 0);
 	if (SRpnt) scsi_release_request(SRpnt);
@@ -4680,20 +4664,18 @@
 {
 	int i, cmd_nr, cmd_type, retval = 0;
 	unsigned int blk;
-	OS_Scsi_Tape *STp;
 	ST_mode *STm;
 	ST_partstat *STps;
 	Scsi_Request *SRpnt = NULL;
-	int dev = TAPE_NR(inode->i_rdev);
-
-	STp = os_scsi_tapes[dev];
+	OS_Scsi_Tape *STp = file->private_data;
+	char *name = tape_name(STp);
 
 	if (down_interruptible(&STp->lock))
 		return -ERESTARTSYS;
 
 #if DEBUG
 	if (debugging && !STp->in_use) {
-		printk(OSST_DEB_MSG "osst%d:D: Incorrect device.\n", dev);
+		printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
 		retval = (-EIO);
 		goto out;
 	}
@@ -4715,7 +4697,7 @@
 	cmd_type = _IOC_TYPE(cmd_in);
 	cmd_nr   = _IOC_NR(cmd_in);
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d:D: Ioctl %d,%d in %s mode\n", dev,
+	printk(OSST_DEB_MSG "%s:D: Ioctl %d,%d in %s mode\n", name,
 			    cmd_type, cmd_nr, STp->raw?"raw":"normal");
 #endif
 	if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
@@ -4733,7 +4715,7 @@
 		}
 
 		if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
-			printk(KERN_WARNING "osst%d:W: MTSETDRVBUFFER only allowed for root.\n", dev);
+			printk(KERN_WARNING "%s:W: MTSETDRVBUFFER only allowed for root.\n", name);
 			retval = (-EPERM);
 			goto out;
 		}
@@ -4793,8 +4775,8 @@
 			if (STp->door_locked != ST_UNLOCKED &&
 			    STp->door_locked != ST_LOCK_FAILS) {
 				if (osst_int_ioctl(STp, &SRpnt, MTLOCK, 0)) {
-					printk(KERN_NOTICE "osst%d:I: Could not relock door after bus reset.\n",
-								  dev);
+					printk(KERN_NOTICE "%s:I: Could not relock door after bus reset.\n",
+								  name);
 					STp->door_locked = ST_UNLOCKED;
 				}
 			}
@@ -5421,6 +5403,7 @@
 	ST_mode * STm;
 	ST_partstat * STps;
 	int i, dev;
+	struct gendisk *disk;
 #ifdef CONFIG_DEVFS_FS
 	int mode;
 #endif
@@ -5428,8 +5411,13 @@
 	if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
 		 return 1;
 
+	disk = alloc_disk(1);
+	if (!disk)
+		return 1;
+
 	if (osst_template.nr_dev >= osst_template.dev_max) {
 		 SDp->attached--;
+		 put_disk(disk);
 		 return 1;
 	}
 	
@@ -5442,6 +5430,7 @@
 	if (tpnt == NULL) {
 		 SDp->attached--;
 		 printk(KERN_WARNING "osst :W: Can't allocate device descriptor.\n");
+		 put_disk(disk);
 		 return 1;
 	}
 	memset(tpnt, 0, sizeof(OS_Scsi_Tape));
@@ -5493,7 +5482,10 @@
 #endif
 
 	tpnt->device = SDp;
-	tpnt->devt = mk_kdev(MAJOR_NR, i);
+	disk->private_data = &tpnt->driver;
+	sprintf(disk->disk_name, "osst%d", i);
+	tpnt->driver = &osst_template;
+	tpnt->disk = disk;
 	tpnt->dirty = 0;
 	tpnt->in_use = 0;
 	tpnt->drv_buffer = 1;  /* Try buffering if no mode sense */
@@ -5558,8 +5550,8 @@
 	osst_template.nr_dev++;
 
 	printk(KERN_INFO
-		"osst :I: Attached OnStream %.5s tape at scsi%d, channel %d, id %d, lun %d as osst%d\n",
-		SDp->model, SDp->host->host_no, SDp->channel, SDp->id, SDp->lun, dev);
+		"osst :I: Attached OnStream %.5s tape at scsi%d, channel %d, id %d, lun %d as %s\n",
+		SDp->model, SDp->host->host_no, SDp->channel, SDp->id, SDp->lun, tape_name(tpnt));
 
 	return 0;
 };
@@ -5578,52 +5570,53 @@
 /* Driver initialization (not __initfunc because may be called later) */
 static int osst_init()
 {
-  int i;
+	int i;
+
+	if (osst_template.dev_noticed == 0)
+		return 0;
 
-  if (osst_template.dev_noticed == 0) return 0;
+	if (!osst_registered) {
+		if (register_chrdev(MAJOR_NR,"osst",&osst_fops)) {
+			printk(KERN_ERR "osst :W: Unable to get major %d for OnStream tapes\n",MAJOR_NR);
+			return 1;
+		}
+		osst_registered++;
+	}
 
-  if(!osst_registered) {
-	if (register_chrdev(MAJOR_NR,"osst",&osst_fops)) {
-		printk(KERN_ERR "osst :W: Unable to get major %d for OnStream tapes\n",MAJOR_NR);
+	if (os_scsi_tapes)
+		return 0;
+	osst_template.dev_max = OSST_MAX_TAPES;
+	if (osst_template.dev_max > 128 / ST_NBR_MODES)
+		printk(KERN_INFO "osst :I: Only %d tapes accessible.\n", 128 / ST_NBR_MODES);
+	os_scsi_tapes = kmalloc(osst_template.dev_max * sizeof(OS_Scsi_Tape *),
+								GFP_ATOMIC);
+	if (!os_scsi_tapes) {
+		printk(KERN_ERR "osst :W: Unable to allocate array for OnStream SCSI tapes.\n");
+		unregister_chrdev(MAJOR_NR, "osst");
 		return 1;
 	}
-	osst_registered++;
-  }
-  
-  if (os_scsi_tapes) return 0;
-  osst_template.dev_max = OSST_MAX_TAPES;
-  if (osst_template.dev_max > 128 / ST_NBR_MODES)
-	printk(KERN_INFO "osst :I: Only %d tapes accessible.\n", 128 / ST_NBR_MODES);
-  os_scsi_tapes =
-	(OS_Scsi_Tape **)kmalloc(osst_template.dev_max * sizeof(OS_Scsi_Tape *),
-				   GFP_ATOMIC);
-  if (os_scsi_tapes == NULL) {
-	printk(KERN_ERR "osst :W: Unable to allocate array for OnStream SCSI tapes.\n");
-	unregister_chrdev(MAJOR_NR, "osst");
-	return 1;
-  }
 
-  for (i=0; i < osst_template.dev_max; ++i) os_scsi_tapes[i] = NULL;
+	for (i=0; i < osst_template.dev_max; ++i)
+		os_scsi_tapes[i] = NULL;
 
-  /* Allocate the buffer pointers */
-  osst_buffers =
-	(OSST_buffer **)kmalloc(osst_template.dev_max * sizeof(OSST_buffer *),
-				    GFP_ATOMIC);
-  if (osst_buffers == NULL) {
-	printk(KERN_ERR "osst :W: Unable to allocate tape buffer pointers.\n");
-	unregister_chrdev(MAJOR_NR, "osst");
-	kfree(os_scsi_tapes);
-	return 1;
-  }
-  osst_nbr_buffers = 0;
+	/* Allocate the buffer pointers */
+	osst_buffers = kmalloc(osst_template.dev_max * sizeof(OSST_buffer *),
+								GFP_ATOMIC);
+	if (!osst_buffers) {
+		printk(KERN_ERR "osst :W: Unable to allocate tape buffer pointers.\n");
+		unregister_chrdev(MAJOR_NR, "osst");
+		kfree(os_scsi_tapes);
+		return 1;
+	}
+	osst_nbr_buffers = 0;
 
-  printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
+	printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
 
 #if DEBUG
-  printk(OSST_DEB_MSG "osst :D: Buffer size %d bytes, write threshold %d bytes.\n",
-	 osst_buffer_size, osst_write_threshold);
+	printk(OSST_DEB_MSG "osst :D: Buffer size %d bytes, write threshold %d bytes.\n",
+			osst_buffer_size, osst_write_threshold);
 #endif
-  return 0;
+	return 0;
 }
 
 
@@ -5641,12 +5634,13 @@
 		tpnt->device = NULL;
 #ifdef CONFIG_DEVFS_FS
 		for (mode = 0; mode < ST_NBR_MODES; ++mode) {
-	  devfs_unregister (tpnt->de_r[mode]);
-	  tpnt->de_r[mode] = NULL;
-	  devfs_unregister (tpnt->de_n[mode]);
-	  tpnt->de_n[mode] = NULL;
+			devfs_unregister (tpnt->de_r[mode]);
+			tpnt->de_r[mode] = NULL;
+			devfs_unregister (tpnt->de_n[mode]);
+			tpnt->de_n[mode] = NULL;
 		}
 #endif
+		put_disk(tpnt->disk);
 		kfree(tpnt);
 		os_scsi_tapes[i] = NULL;
 		SDp->attached--;
@@ -5666,34 +5660,37 @@
 
 static void __exit exit_osst (void)
 {
-  int i;
-  OS_Scsi_Tape * STp;
+	int i;
+	OS_Scsi_Tape * STp;
 
-  scsi_unregister_device(&osst_template);
-  unregister_chrdev(MAJOR_NR, "osst");
-  osst_registered--;
-  if(os_scsi_tapes != NULL) {
-	for (i=0; i < osst_template.dev_max; ++i) {
-		if ((STp = os_scsi_tapes[i])) {
-	if (STp->header_cache != NULL) vfree(STp->header_cache);
-	kfree(STp);
+	scsi_unregister_device(&osst_template);
+	unregister_chrdev(MAJOR_NR, "osst");
+	osst_registered--;
+	if (os_scsi_tapes) {
+		for (i=0; i < osst_template.dev_max; ++i) {
+			STp = os_scsi_tapes[i];
+			if (!STp)
+				continue;
+			if (STp->header_cache)
+				vfree(STp->header_cache);
+			put_disk(STp->disk);
+			kfree(STp);
+		}
+		kfree(os_scsi_tapes);
+
+		if (osst_buffers) {
+			for (i=0; i < osst_nbr_buffers; i++) {
+				if (osst_buffers[i]) {
+					osst_buffers[i]->orig_sg_segs = 0;
+					normalize_buffer(osst_buffers[i]);
+					kfree(osst_buffers[i]);
+				}
+			}
+			kfree(osst_buffers);
 		}
 	}
-	kfree(os_scsi_tapes);
-
-	if (osst_buffers != NULL) {
-		for (i=0; i < osst_nbr_buffers; i++)
-	if (osst_buffers[i] != NULL) {
-	  osst_buffers[i]->orig_sg_segs = 0;
-	  normalize_buffer(osst_buffers[i]);
-	  kfree(osst_buffers[i]);
-	}
-
-		kfree(osst_buffers);
-	}
-  }
-  osst_template.dev_max = 0;
-  printk(KERN_INFO "osst :I: Unloaded.\n");
+	osst_template.dev_max = 0;
+	printk(KERN_INFO "osst :I: Unloaded.\n");
 }
 
 module_init(init_osst);
diff -Nru a/drivers/scsi/osst.h b/drivers/scsi/osst.h
--- a/drivers/scsi/osst.h	Mon Nov  4 14:31:02 2002
+++ b/drivers/scsi/osst.h	Mon Nov  4 14:31:02 2002
@@ -532,7 +532,7 @@
 
 /* The tape drive descriptor */
 typedef struct {
-  kdev_t devt;
+  struct Scsi_Device_Template *driver;
   unsigned capacity;
   Scsi_Device* device;
   struct semaphore lock;       /* for serialization */
@@ -628,6 +628,7 @@
   unsigned char last_cmnd[6];
   unsigned char last_sense[16];
 #endif
+  struct gendisk *disk;
 } OS_Scsi_Tape;
 
 /* Values of write_type */
diff -Nru a/drivers/scsi/qla1280.h b/drivers/scsi/qla1280.h
--- a/drivers/scsi/qla1280.h	Mon Nov  4 14:31:03 2002
+++ b/drivers/scsi/qla1280.h	Mon Nov  4 14:31:03 2002
@@ -1331,6 +1331,9 @@
 	release: qla1280_release,				\
 	info: qla1280_info,					\
 	queuecommand: qla1280_queuecommand,			\
+/*	use_new_eh_code: 0, */					\
+	abort: qla1280_abort,					\
+	reset: qla1280_reset,					\
 	slave_attach: qla1280_slave_attach,			\
 	bios_param: qla1280_biosparam,				\
 	can_queue: 255,		/* max simultaneous cmds      */\
diff -Nru a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
--- a/drivers/scsi/scsi.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/scsi/scsi.c	Mon Nov  4 14:31:02 2002
@@ -2171,7 +2171,8 @@
                                        SCpnt->target,
                                        SCpnt->lun,
 
-                                       kdevname(SCpnt->request->rq_dev),
+                                       SCpnt->request->rq_disk ?
+                                       SCpnt->request->rq_disk->disk_name : "?",
                                        (unsigned long long)SCpnt->request->sector,
 				       SCpnt->request->nr_sectors,
 				       (long)SCpnt->request->current_nr_sectors,
diff -Nru a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h
--- a/drivers/scsi/scsi.h	Mon Nov  4 14:31:01 2002
+++ b/drivers/scsi/scsi.h	Mon Nov  4 14:31:01 2002
@@ -164,8 +164,6 @@
 #define SCSI_OWNER_BH_HANDLER     0x104
 #define SCSI_OWNER_NOBODY         0x105
 
-#define COMMAND_SIZE(opcode) scsi_command_size[((opcode) >> 5) & 7]
-
 #define IDENTIFY_BASE       0x80
 #define IDENTIFY(can_disconnect, lun)   (IDENTIFY_BASE |\
 		     ((can_disconnect) ?  0x40 : 0) |\
@@ -415,7 +413,6 @@
 extern unsigned int scsi_need_isa_buffer;	/* True if some devices need indirection
 						   * buffers */
 extern volatile int in_scan_scsis;
-extern const unsigned char scsi_command_size[8];
 
 extern struct bus_type scsi_driverfs_bus_type;
 
diff -Nru a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
--- a/drivers/scsi/scsi_lib.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/scsi/scsi_lib.c	Mon Nov  4 14:31:02 2002
@@ -635,7 +635,7 @@
 			break;
 		case NOT_READY:
 			printk(KERN_INFO "Device %s not ready.\n",
-			       kdevname(req->rq_dev));
+			       req->rq_disk ? req->rq_disk->disk_name : "");
 			SCpnt = scsi_end_request(SCpnt, 0, this_count);
 			return;
 			break;
@@ -703,36 +703,8 @@
  */
 struct Scsi_Device_Template *scsi_get_request_dev(struct request *req)
 {
-	struct Scsi_Device_Template *spnt;
-	kdev_t dev = req->rq_dev;
-	int major = major(dev);
-
-	for (spnt = scsi_devicelist; spnt; spnt = spnt->next) {
-		/*
-		 * Search for a block device driver that supports this
-		 * major.
-		 */
-		if (spnt->blk && spnt->major == major) {
-			return spnt;
-		}
-		/*
-		 * I am still not entirely satisfied with this solution,
-		 * but it is good enough for now.  Disks have a number of
-		 * major numbers associated with them, the primary
-		 * 8, which we test above, and a secondary range of 7
-		 * different consecutive major numbers.   If this ever
-		 * becomes insufficient, then we could add another function
-		 * to the structure, and generalize this completely.
-		 */
-		if( spnt->min_major != 0 
-		    && spnt->max_major != 0
-		    && major >= spnt->min_major
-		    && major <= spnt->max_major )
-		{
-			return spnt;
-		}
-	}
-	return NULL;
+	struct gendisk *p = req->rq_disk;
+	return p ? *(struct Scsi_Device_Template **)p->private_data : NULL;
 }
 
 /*
diff -Nru a/drivers/scsi/sd.c b/drivers/scsi/sd.c
--- a/drivers/scsi/sd.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/scsi/sd.c	Mon Nov  4 14:31:02 2002
@@ -73,6 +73,7 @@
 
 struct scsi_disk {
 	struct list_head list;		/* list of all scsi_disks */
+	struct Scsi_Device_Template *driver;	/* always &sd_template */
 	struct scsi_device *device;
 	struct gendisk	*disk;
 	sector_t	capacity;	/* size in 512-byte sectors */
@@ -105,9 +106,6 @@
 	.name		= "disk",
 	.tag		= "sd",
 	.scsi_type	= TYPE_DISK,
-	.major		= SCSI_DISK0_MAJOR,
-	.min_major	= SCSI_DISK1_MAJOR,
-	.max_major	= SCSI_DISK7_MAJOR,
 	.blk		= 1,
 	.detect		= sd_detect,
 	.attach		= sd_attach,
@@ -144,6 +142,11 @@
 	list_del(&sdkp->list);
 	spin_unlock(&sd_devlist_lock);
 }
+ 
+static inline struct scsi_disk *scsi_disk(struct gendisk *disk)
+{
+	return container_of(disk->private_data, struct scsi_disk, driver);
+}
 
 /**
  *	sd_ioctl - process an ioctl
@@ -164,7 +167,7 @@
 {
 	struct block_device *bdev = inode->i_bdev;
 	struct gendisk *disk = bdev->bd_disk;
-	struct scsi_disk *sdkp = disk->private_data;
+	struct scsi_disk *sdkp = scsi_disk(disk);
 	struct scsi_device *sdp = sdkp->device;
 	sector_t capacity = sdkp->capacity;
 	struct Scsi_Host *host;
@@ -431,7 +434,7 @@
 static int sd_open(struct inode *inode, struct file *filp)
 {
 	struct gendisk *disk = inode->i_bdev->bd_disk;
-	struct scsi_disk *sdkp = disk->private_data;
+	struct scsi_disk *sdkp = scsi_disk(disk);
 	struct scsi_device * sdp = sdkp->device;
 	int retval = -ENXIO;
 
@@ -516,7 +519,7 @@
 static int sd_release(struct inode *inode, struct file *filp)
 {
 	struct gendisk *disk = inode->i_bdev->bd_disk;
-	struct scsi_disk *sdkp = disk->private_data;
+	struct scsi_disk *sdkp = scsi_disk(disk);
 	struct scsi_device *sdp = sdkp->device;
 
 	SCSI_LOG_HLQUEUE(3, printk("sd_release: disk=%s\n", disk->disk_name));
@@ -670,7 +673,7 @@
  **/
 static int check_scsidisk_media_change(struct gendisk *disk)
 {
-	struct scsi_disk *sdkp = disk->private_data;
+	struct scsi_disk *sdkp = scsi_disk(disk);
 	struct scsi_device *sdp = sdkp->device;
 	int retval;
 	int flag = 0;	/* <<<< what is this for?? */
@@ -697,15 +700,17 @@
 				 * check_disk_change */
 	}
 
-	/* Using Start/Stop enables differentiation between drive with
+	/* Using TEST_UNIT_READY enables differentiation between drive with
 	 * no cartridge loaded - NOT READY, drive with changed cartridge -
 	 * UNIT ATTENTION, or with same cartridge - GOOD STATUS.
-	 * This also handles drives that auto spin down. eg iomega jaz 1GB
-	 * as this will spin up the drive.
+	 *
+	 * Drives that auto spin down. eg iomega jaz 1G, will be started
+	 * by sd_spinup_disk() from sd_init_onedisk(), which happens whenever
+	 * sd_revalidate() is called.
 	 */
 	retval = -ENODEV;
 	if (scsi_block_when_processing_errors(sdp))
-		retval = scsi_ioctl(sdp, SCSI_IOCTL_START_UNIT, NULL);
+		retval = scsi_ioctl(sdp, SCSI_IOCTL_TEST_UNIT_READY, NULL);
 
 	if (retval) {		/* Unable to test, unit probably not ready.
 				 * This usually means there is no disc in the
@@ -791,10 +796,9 @@
 		if (sd_media_not_present(sdkp, SRpnt))
 			return;
 
-		/* Look for non-removable devices that return NOT_READY.
+		/* Look for devices that return NOT_READY.
 		 * Issue command to spin up drive for these cases. */
-		if (the_result && !sdp->removable &&
-		    SRpnt->sr_sense_buffer[2] == NOT_READY) {
+		if (the_result && SRpnt->sr_sense_buffer[2] == NOT_READY) {
 			unsigned long time1;
 			if (!spintime) {
 				printk(KERN_NOTICE "%s: Spinning up disk...",
@@ -1227,6 +1231,7 @@
 	dsk_nr = sd_template.nr_dev++;
 
 	sdkp->device = sdp;
+	sdkp->driver = &sd_template;
 	sdkp->disk = gd;
 
 	sd_init_onedisk(sdkp, gd);
@@ -1243,7 +1248,7 @@
 	gd->flags = GENHD_FL_DRIVERFS | GENHD_FL_DEVFS;
 	if (sdp->removable)
 		gd->flags |= GENHD_FL_REMOVABLE;
-	gd->private_data = sdkp;
+	gd->private_data = &sdkp->driver;
 	gd->queue = &sdkp->device->request_queue;
 
 	sd_devlist_insert(sdkp);
@@ -1266,7 +1271,7 @@
 
 static int sd_revalidate(struct gendisk *disk)
 {
-	struct scsi_disk *sdkp = disk->private_data;
+	struct scsi_disk *sdkp = scsi_disk(disk);
 
 	if (!sdkp->device)
 		return -ENODEV;
diff -Nru a/drivers/scsi/sg.c b/drivers/scsi/sg.c
--- a/drivers/scsi/sg.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/scsi/sg.c	Mon Nov  4 14:31:01 2002
@@ -125,7 +125,6 @@
 	.name = "generic",
 	.tag = "sg",
 	.scsi_type = 0xff,
-	.major = SCSI_GENERIC_MAJOR,
 	.detect = sg_detect,
 	.init = sg_init,
 	.attach = sg_attach,
@@ -180,16 +179,17 @@
 } Sg_fd;
 
 typedef struct sg_device { /* holds the state of each scsi generic device */
+	struct Scsi_Device_Template *driver;
 	Scsi_Device *device;
 	wait_queue_head_t o_excl_wait;	/* queue open() when O_EXCL in use */
 	int sg_tablesize;	/* adapter's max scatter-gather table size */
 	Sg_fd *headfp;		/* first open fd belonging to this device */
 	devfs_handle_t de;
-	kdev_t i_rdev;		/* holds device major+minor number */
 	volatile char detached;	/* 0->attached, 1->detached pending removal */
 	volatile char exclude;	/* opened for exclusive access */
 	char sgdebug;		/* 0->off, 1->sense, 9->dump dev, 10-> all devs */
 	struct device sg_driverfs_dev;
+	struct gendisk *disk;
 } Sg_device;
 
 static int sg_fasync(int fd, struct file *filp, int mode);
@@ -330,7 +330,7 @@
 
 	if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
 		return -ENXIO;
-	SCSI_LOG_TIMEOUT(3, printk("sg_release: dev=%d\n", minor(sdp->i_rdev)));
+	SCSI_LOG_TIMEOUT(3, printk("sg_release: %s\n", sdp->disk->disk_name));
 	sg_fasync(-1, filp, 0);	/* remove filp from async notification list */
 	if (0 == sg_remove_sfp(sdp, sfp)) {	/* Returns 1 when sdp gone */
 		if (!sdp->detached) {
@@ -359,8 +359,8 @@
 
 	if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
 		return -ENXIO;
-	SCSI_LOG_TIMEOUT(3, printk("sg_read: dev=%d, count=%d\n",
-				   minor(sdp->i_rdev), (int) count));
+	SCSI_LOG_TIMEOUT(3, printk("sg_read: %s, count=%d\n",
+				   sdp->disk->disk_name, (int) count));
 	if (ppos != &filp->f_pos) ;	/* FIXME: Hmm.  Seek to the right place, or fail?  */
 	if ((k = verify_area(VERIFY_WRITE, buf, count)))
 		return k;
@@ -514,8 +514,8 @@
 
 	if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
 		return -ENXIO;
-	SCSI_LOG_TIMEOUT(3, printk("sg_write: dev=%d, count=%d\n",
-				   minor(sdp->i_rdev), (int) count));
+	SCSI_LOG_TIMEOUT(3, printk("sg_write: %s, count=%d\n",
+				   sdp->disk->disk_name, (int) count));
 	if (sdp->detached)
 		return -ENODEV;
 	if (!((filp->f_flags & O_NONBLOCK) ||
@@ -702,7 +702,7 @@
 
 	srp->my_cmdp = SRpnt;
 	q = &SRpnt->sr_device->request_queue;
-	SRpnt->sr_request->rq_dev = sdp->i_rdev;
+	SRpnt->sr_request->rq_disk = sdp->disk;
 	SRpnt->sr_sense_buffer[0] = 0;
 	SRpnt->sr_cmd_len = hp->cmd_len;
 	SRpnt->sr_use_sg = srp->data.k_use_sg;
@@ -753,8 +753,8 @@
 
 	if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
 		return -ENXIO;
-	SCSI_LOG_TIMEOUT(3, printk("sg_ioctl: dev=%d, cmd=0x%x\n",
-				   minor(sdp->i_rdev), (int) cmd_in));
+	SCSI_LOG_TIMEOUT(3, printk("sg_ioctl: %s, cmd=0x%x\n",
+				   sdp->disk->disk_name, (int) cmd_in));
 	read_only = (O_RDWR != (filp->f_flags & O_ACCMODE));
 
 	switch (cmd_in) {
@@ -1056,8 +1056,8 @@
 			res |= POLLOUT | POLLWRNORM;
 	} else if (count < SG_MAX_QUEUE)
 		res |= POLLOUT | POLLWRNORM;
-	SCSI_LOG_TIMEOUT(3, printk("sg_poll: dev=%d, res=0x%x\n",
-				   minor(sdp->i_rdev), (int) res));
+	SCSI_LOG_TIMEOUT(3, printk("sg_poll: %s, res=0x%x\n",
+				   sdp->disk->disk_name, (int) res));
 	return res;
 }
 
@@ -1070,8 +1070,8 @@
 
 	if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
 		return -ENXIO;
-	SCSI_LOG_TIMEOUT(3, printk("sg_fasync: dev=%d, mode=%d\n",
-				   minor(sdp->i_rdev), mode));
+	SCSI_LOG_TIMEOUT(3, printk("sg_fasync: %s, mode=%d\n",
+				   sdp->disk->disk_name, mode));
 
 	retval = fasync_helper(fd, filp, mode, &sfp->async_qp);
 	return (retval < 0) ? retval : 0;
@@ -1257,13 +1257,13 @@
 	SRpnt->sr_bufflen = 0;
 	SRpnt->sr_buffer = NULL;
 	SRpnt->sr_underflow = 0;
-	SRpnt->sr_request->rq_dev = mk_kdev(0, 0);	/* "sg" _disowns_ request blk */
+	SRpnt->sr_request->rq_disk = NULL; /* "sg" _disowns_ request blk */
 
 	srp->my_cmdp = NULL;
 	srp->done = 1;
 
-	SCSI_LOG_TIMEOUT(4, printk("sg_cmd_done: dev=%d, pack_id=%d, res=0x%x\n",
-		minor(sdp->i_rdev), srp->header.pack_id, (int) SRpnt->sr_result));
+	SCSI_LOG_TIMEOUT(4, printk("sg_cmd_done: %s, pack_id=%d, res=0x%x\n",
+		sdp->disk->disk_name, srp->header.pack_id, (int) SRpnt->sr_result));
 	srp->header.resid = SCpnt->resid;
 	/* N.B. unit of duration changes here from jiffies to millisecs */
 	srp->header.duration =
@@ -1420,7 +1420,8 @@
 		    size_t count, loff_t off)
 {
 	Sg_device *sdp = list_entry(driverfs_dev, Sg_device, sg_driverfs_dev);
-	return off ? 0 : sprintf(page, "%x\n", sdp->i_rdev.value);
+	return off ? 0 : sprintf(page, "%x\n", MKDEV(sdp->disk->major,
+						     sdp->disk->first_minor));
 }
 static DEVICE_ATTR(kdev,S_IRUGO,sg_device_kdev_read,NULL);
 
@@ -1436,10 +1437,13 @@
 static int
 sg_attach(Scsi_Device * scsidp)
 {
+	struct gendisk *disk = alloc_disk(1);
 	Sg_device *sdp = NULL;
 	unsigned long iflags;
 	int k;
 
+	if (!disk)
+		return 1;
 	write_lock_irqsave(&sg_dev_arr_lock, iflags);
 	if (sg_template.nr_dev >= sg_template.dev_max) {	/* try to resize */
 		Sg_device **tmp_da;
@@ -1452,6 +1456,7 @@
 			scsidp->attached--;
 			printk(KERN_ERR
 			       "sg_attach: device array cannot be resized\n");
+			put_disk(disk);
 			return 1;
 		}
 		write_lock_irqsave(&sg_dev_arr_lock, iflags);
@@ -1477,6 +1482,7 @@
 		       scsidp->lun, scsidp->type, SG_MAX_DEVS_MASK);
 		if (NULL != sdp)
 			vfree((char *) sdp);
+		put_disk(disk);
 		return 1;
 	}
 	if (k < sg_template.dev_max) {
@@ -1493,11 +1499,18 @@
 		scsidp->attached--;
 		write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
 		printk(KERN_ERR "sg_attach: Sg_device cannot be allocated\n");
+		put_disk(disk);
 		return 1;
 	}
 
 	SCSI_LOG_TIMEOUT(3, printk("sg_attach: dev=%d \n", k));
 	memset(sdp, 0, sizeof(*sdp));
+	sdp->driver = &sg_template;
+	disk->private_data = &sdp->driver;
+	sprintf(disk->disk_name, "sg%d", k);
+	disk->major = SCSI_GENERIC_MAJOR;
+	disk->first_minor = k;
+	sdp->disk = disk;
 	sdp->device = scsidp;
 	init_waitqueue_head(&sdp->o_excl_wait);
 	sdp->headfp = NULL;
@@ -1505,7 +1518,6 @@
 	sdp->sgdebug = 0;
 	sdp->detached = 0;
 	sdp->sg_tablesize = scsidp->host ? scsidp->host->sg_tablesize : 0;
-	sdp->i_rdev = mk_kdev(SCSI_GENERIC_MAJOR, k);
 
 	memset(&sdp->sg_driverfs_dev, 0, sizeof (struct device));
 	sprintf(sdp->sg_driverfs_dev.bus_id, "%s:gen",
@@ -1608,6 +1620,8 @@
 		device_remove_file(&sdp->sg_driverfs_dev, &dev_attr_type);
 		device_remove_file(&sdp->sg_driverfs_dev, &dev_attr_kdev);
 		device_unregister(&sdp->sg_driverfs_dev);
+		put_disk(sdp->disk);
+		sdp->disk = NULL;
 		if (NULL == sdp->headfp)
 			vfree((char *) sdp);
 	}
@@ -2972,18 +2986,16 @@
 	PRINT_PROC(" def_reserved_size=%d\n", sg_big_buff);
 	for (j = 0; j < max_dev; ++j) {
 		if ((sdp = sg_get_dev(j))) {
-			struct scsi_device *scsidp;
-			int dev;
+			struct scsi_device *scsidp = sdp->device;
 
-			scsidp = sdp->device;
 			if (NULL == scsidp) {
 				PRINT_PROC("device %d detached ??\n", j);
 				continue;
 			}
-			dev = minor(sdp->i_rdev);
 
 			if (sg_get_nth_sfp(sdp, 0)) {
-				PRINT_PROC(" >>> device=sg%d ", dev);
+				PRINT_PROC(" >>> device=%s ",
+					sdp->disk->disk_name);
 				if (sdp->detached)
 					PRINT_PROC("detached pending close ");
 				else
diff -Nru a/drivers/scsi/sr.c b/drivers/scsi/sr.c
--- a/drivers/scsi/sr.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/scsi/sr.c	Mon Nov  4 14:31:01 2002
@@ -77,7 +77,6 @@
 	.name		= "cdrom",
 	.tag		= "sr",
 	.scsi_type	= TYPE_ROM,
-	.major		= SCSI_CDROM_MAJOR,
 	.blk		= 1,
 	.detect		= sr_detect,
 	.init		= sr_init,
@@ -177,6 +176,11 @@
 	}
 	return retval;
 }
+ 
+static inline struct scsi_cd *scsi_cd(struct gendisk *disk)
+{
+	return container_of(disk->private_data, struct scsi_cd, driver);
+}
 
 /*
  * rw_intr is the interrupt routine for the device driver.
@@ -190,7 +194,7 @@
 	int this_count = SCpnt->bufflen >> 9;
 	int good_sectors = (result == 0 ? this_count : 0);
 	int block_sectors = 0;
-	struct scsi_cd *cd = SCpnt->request->rq_disk->private_data;
+	struct scsi_cd *cd = scsi_cd(SCpnt->request->rq_disk);
 
 #ifdef DEBUG
 	printk("sr.c done: %x %p\n", result, SCpnt->request->bh->b_data);
@@ -243,7 +247,7 @@
 static int sr_init_command(struct scsi_cmnd * SCpnt)
 {
 	int block=0, this_count, s_size, timeout = SR_TIMEOUT;
-	struct scsi_cd *cd = SCpnt->request->rq_disk->private_data;
+	struct scsi_cd *cd = scsi_cd(SCpnt->request->rq_disk);
 
 	SCSI_LOG_HLQUEUE(1, printk("Doing sr request, dev = %s, block = %d\n",
 				cd->disk->disk_name, block));
@@ -395,26 +399,26 @@
 
 static int sr_block_open(struct inode *inode, struct file *file)
 {
-	struct scsi_cd *cd = inode->i_bdev->bd_disk->private_data;
+	struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk);
 	return cdrom_open(&cd->cdi, inode, file);
 }
 
 static int sr_block_release(struct inode *inode, struct file *file)
 {
-	struct scsi_cd *cd = inode->i_bdev->bd_disk->private_data;
+	struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk);
 	return cdrom_release(&cd->cdi, file);
 }
 
 static int sr_block_ioctl(struct inode *inode, struct file *file, unsigned cmd,
 			  unsigned long arg)
 {
-	struct scsi_cd *cd = inode->i_bdev->bd_disk->private_data;
+	struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk);
 	return cdrom_ioctl(&cd->cdi, inode, cmd, arg);
 }
 
 static int sr_block_media_changed(struct gendisk *disk)
 {
-	struct scsi_cd *cd = disk->private_data;
+	struct scsi_cd *cd = scsi_cd(disk);
 	return cdrom_media_changed(&cd->cdi);
 }
 
@@ -766,6 +770,7 @@
 	strcpy(disk->disk_name, cd->cdi.name);
 	disk->fops = &sr_bdops;
 	disk->flags = GENHD_FL_CD;
+	cd->driver = &sr_template;
 	cd->disk = disk;
 	cd->capacity = 0x1fffff;
 	cd->device->sector_size = 2048;/* A guess, just in case */
@@ -798,7 +803,7 @@
 	disk->driverfs_dev = &cd->device->sdev_driverfs_dev;
 	register_cdrom(&cd->cdi);
 	set_capacity(disk, cd->capacity);
-	disk->private_data = cd;
+	disk->private_data = &cd->driver;
 	disk->queue = &cd->device->request_queue;
 	add_disk(disk);
 
diff -Nru a/drivers/scsi/sr.h b/drivers/scsi/sr.h
--- a/drivers/scsi/sr.h	Mon Nov  4 14:31:01 2002
+++ b/drivers/scsi/sr.h	Mon Nov  4 14:31:01 2002
@@ -25,6 +25,7 @@
 #define IOCTL_TIMEOUT 30*HZ
 
 typedef struct scsi_cd {
+	struct Scsi_Device_Template *driver;
 	unsigned capacity;	/* size in blocks                       */
 	Scsi_Device *device;
 	unsigned int vendor;	/* vendor code, see sr_vendor.c         */
diff -Nru a/drivers/scsi/st.c b/drivers/scsi/st.c
--- a/drivers/scsi/st.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/scsi/st.c	Mon Nov  4 14:31:02 2002
@@ -175,7 +175,6 @@
 	.name =		"tape", 
 	.tag =		"st", 
 	.scsi_type =	TYPE_TAPE,
-	.major =	SCSI_TAPE_MAJOR, 
 	.detect =	st_detect, 
 	.attach =	st_attach, 
 	.detach =	st_detach
@@ -230,13 +229,18 @@
 }
 
 
+static inline char *tape_name(Scsi_Tape *tape)
+{
+	return tape->disk->disk_name;
+}
+
 /* Convert the result to success code */
 static int st_chk_result(Scsi_Tape *STp, Scsi_Request * SRpnt)
 {
-	int dev;
 	int result = SRpnt->sr_result;
 	unsigned char *sense = SRpnt->sr_sense_buffer, scode;
 	DEB(const char *stp;)
+	char *name = tape_name(STp);
 
 	if (!result) {
 		sense[0] = 0;	/* We don't have sense data if this byte is zero */
@@ -250,11 +254,10 @@
 		scode = 0;
 	}
 
-	dev = TAPE_NR(SRpnt->sr_request->rq_dev);
         DEB(
         if (debugging) {
-                printk(ST_DEB_MSG "st%d: Error: %x, cmd: %x %x %x %x %x %x Len: %d\n",
-		       dev, result,
+                printk(ST_DEB_MSG "%s: Error: %x, cmd: %x %x %x %x %x %x Len: %d\n",
+		       name, result,
 		       SRpnt->sr_cmnd[0], SRpnt->sr_cmnd[1], SRpnt->sr_cmnd[2],
 		       SRpnt->sr_cmnd[3], SRpnt->sr_cmnd[4], SRpnt->sr_cmnd[5],
 		       SRpnt->sr_bufflen);
@@ -271,12 +274,12 @@
 		     SRpnt->sr_cmnd[0] != MODE_SENSE &&
 		     SRpnt->sr_cmnd[0] != TEST_UNIT_READY)) {	/* Abnormal conditions for tape */
 		if (driver_byte(result) & DRIVER_SENSE) {
-			printk(KERN_WARNING "st%d: Error with sense data: ", dev);
+			printk(KERN_WARNING "%s: Error with sense data: ", name);
 			print_req_sense("st", SRpnt);
 		} else
 			printk(KERN_WARNING
-			       "st%d: Error %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n",
-			       dev, result, suggestion(result),
+			       "%s: Error %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n",
+			       name, result, suggestion(result),
                                driver_byte(result) & DRIVER_MASK, host_byte(result));
 	}
 
@@ -311,7 +314,7 @@
 				stp = "write";
 			else
 				stp = "ioctl";
-			printk(ST_DEB_MSG "st%d: Recovered %s error (%d).\n", dev, stp,
+			printk(ST_DEB_MSG "%s: Recovered %s error (%d).\n", name, stp,
 			       STp->recover_count);
 		} ) /* end DEB */
 
@@ -325,14 +328,10 @@
 /* Wakeup from interrupt */
 static void st_sleep_done(Scsi_Cmnd * SCpnt)
 {
-	unsigned int st_nbr;
 	int remainder;
-	Scsi_Tape *STp;
+	Scsi_Tape *STp = container_of(SCpnt->request->rq_disk->private_data,
+				    Scsi_Tape, driver);
 
-	st_nbr = TAPE_NR(SCpnt->request->rq_dev);
-	read_lock(&st_dev_arr_lock);
-	STp = scsi_tapes[st_nbr];
-	read_unlock(&st_dev_arr_lock);
 	if ((STp->buffer)->writing &&
 	    (SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
 	    (SCpnt->sense_buffer[2] & 0x40)) {
@@ -358,7 +357,6 @@
 	complete(SCpnt->request->waiting);
 }
 
-
 /* Do the scsi command. Waits until command performed if do_wait is true.
    Otherwise write_behind_check() is used to check that the command
    has finished. */
@@ -371,8 +369,8 @@
 	if (SRpnt == NULL) {
 		SRpnt = scsi_allocate_request(STp->device);
 		if (SRpnt == NULL) {
-			DEBC( printk(KERN_ERR "st%d: Can't get SCSI request.\n",
-				     TAPE_NR(STp->devt)); );
+			DEBC( printk(KERN_ERR "%s: Can't get SCSI request.\n",
+				     tape_name(STp)); );
 			if (signal_pending(current))
 				(STp->buffer)->syscall_result = (-EINTR);
 			else
@@ -394,7 +392,7 @@
 	SRpnt->sr_cmd_len = 0;
 	SRpnt->sr_request->waiting = &(STp->wait);
 	SRpnt->sr_request->rq_status = RQ_SCSI_BUSY;
-	SRpnt->sr_request->rq_dev = STp->devt;
+	SRpnt->sr_request->rq_disk = STp->disk;
 
 	scsi_do_req(SRpnt, (void *) cmd, bp, bytes,
 		    st_sleep_done, timeout, retries);
@@ -459,8 +457,8 @@
 		cmd[2] = cmd[3] = cmd[4] = 0xff;	/* -1 filemarks */
 	cmd[5] = 0;
 
-        DEBC(printk(ST_DEB_MSG "st%d: Stepping over filemark %s.\n",
-		   TAPE_NR(STp->devt), forward ? "forward" : "backward"));
+        DEBC(printk(ST_DEB_MSG "%s: Stepping over filemark %s.\n",
+		   tape_name(STp), forward ? "forward" : "backward"));
 
 	SRpnt = st_do_scsi(NULL, STp, cmd, 0, SCSI_DATA_NONE,
 			   STp->timeout, MAX_RETRIES, TRUE);
@@ -471,8 +469,8 @@
 	SRpnt = NULL;
 
 	if ((STp->buffer)->midlevel_result != 0)
-		printk(KERN_ERR "st%d: Stepping over filemark %s failed.\n",
-		   TAPE_NR(STp->devt), forward ? "forward" : "backward");
+		printk(KERN_ERR "%s: Stepping over filemark %s failed.\n",
+		   tape_name(STp), forward ? "forward" : "backward");
 
 	return (STp->buffer)->syscall_result;
 }
@@ -491,8 +489,8 @@
 		write_behind_check(STp);
 		if ((STp->buffer)->syscall_result) {
                         DEBC(printk(ST_DEB_MSG
-                                       "st%d: Async write error (flush) %x.\n",
-				       TAPE_NR(STp->devt), (STp->buffer)->midlevel_result))
+                                       "%s: Async write error (flush) %x.\n",
+				       tape_name(STp), (STp->buffer)->midlevel_result))
 			if ((STp->buffer)->midlevel_result == INT_MAX)
 				return (-ENOSPC);
 			return (-EIO);
@@ -507,8 +505,8 @@
 		offset = (STp->buffer)->buffer_bytes;
 		transfer = ((offset + STp->block_size - 1) /
 			    STp->block_size) * STp->block_size;
-                DEBC(printk(ST_DEB_MSG "st%d: Flushing %d bytes.\n",
-                               TAPE_NR(STp->devt), transfer));
+                DEBC(printk(ST_DEB_MSG "%s: Flushing %d bytes.\n",
+                               tape_name(STp), transfer));
 
 		memset((STp->buffer)->b_data + offset, 0, transfer - offset);
 
@@ -534,8 +532,8 @@
 				(STp->buffer)->buffer_bytes = 0;
 				result = (-ENOSPC);
 			} else {
-				printk(KERN_ERR "st%d: Error on flush.\n",
-                                       TAPE_NR(STp->devt));
+				printk(KERN_ERR "%s: Error on flush.\n",
+                                       tape_name(STp));
 				result = (-EIO);
 			}
 			STps->drv_block = (-1);
@@ -613,7 +611,7 @@
 {
 	int set_it = FALSE;
 	unsigned long arg;
-	int dev = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 
 	if (!STp->density_changed &&
 	    STm->default_density >= 0 &&
@@ -633,8 +631,8 @@
 	if (set_it &&
 	    st_int_ioctl(STp, SET_DENS_AND_BLK, arg)) {
 		printk(KERN_WARNING
-		       "st%d: Can't set default block size to %d bytes and density %x.\n",
-		       dev, STm->default_blksize, STm->default_density);
+		       "%s: Can't set default block size to %d bytes and density %x.\n",
+		       name, STm->default_blksize, STm->default_density);
 		if (modes_defined)
 			return (-EINVAL);
 	}
@@ -646,11 +644,11 @@
 static int do_door_lock(Scsi_Tape * STp, int do_lock)
 {
 	int retval, cmd;
-	DEB(int dev = TAPE_NR(STp->devt);)
+	DEB(char *name = tape_name(STp);)
 
 
 	cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
-	DEBC(printk(ST_DEB_MSG "st%d: %socking drive door.\n", dev,
+	DEBC(printk(ST_DEB_MSG "%s: %socking drive door.\n", name,
 		    do_lock ? "L" : "Unl"));
 	retval = scsi_ioctl(STp->device, cmd, NULL);
 	if (!retval) {
@@ -779,15 +777,15 @@
 	Scsi_Request *SRpnt = NULL;
 	ST_mode *STm;
 	ST_partstat *STps;
-	int dev = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 	struct inode *inode = filp->f_dentry->d_inode;
 	int mode = TAPE_MODE(inode->i_rdev);
 
 	STp->ready = ST_READY;
 
 	if (mode != STp->current_mode) {
-                DEBC(printk(ST_DEB_MSG "st%d: Mode change from %d to %d.\n",
-			       dev, STp->current_mode, mode));
+                DEBC(printk(ST_DEB_MSG "%s: Mode change from %d to %d.\n",
+			       name, STp->current_mode, mode));
 		new_session = TRUE;
 		STp->current_mode = mode;
 	}
@@ -858,12 +856,12 @@
 			    (STp->buffer)->b_data[5];
 			if ( DEB( debugging || ) !STp->inited)
 				printk(KERN_WARNING
-                                       "st%d: Block limits %d - %d bytes.\n", dev,
+                                       "%s: Block limits %d - %d bytes.\n", name,
                                        STp->min_block, STp->max_block);
 		} else {
 			STp->min_block = STp->max_block = (-1);
-                        DEBC(printk(ST_DEB_MSG "st%d: Can't read block limits.\n",
-                                       dev));
+                        DEBC(printk(ST_DEB_MSG "%s: Can't read block limits.\n",
+                                       name));
 		}
 	}
 
@@ -879,14 +877,14 @@
 	}
 
 	if ((STp->buffer)->syscall_result != 0) {
-                DEBC(printk(ST_DEB_MSG "st%d: No Mode Sense.\n", dev));
+                DEBC(printk(ST_DEB_MSG "%s: No Mode Sense.\n", name));
 		STp->block_size = ST_DEFAULT_BLOCK;	/* Educated guess (?) */
 		(STp->buffer)->syscall_result = 0;	/* Prevent error propagation */
 		STp->drv_write_prot = 0;
 	} else {
                 DEBC(printk(ST_DEB_MSG
-                            "st%d: Mode sense. Length %d, medium %x, WBS %x, BLL %d\n",
-                            dev,
+                            "%s: Mode sense. Length %d, medium %x, WBS %x, BLL %d\n",
+                            name,
                             (STp->buffer)->b_data[0], (STp->buffer)->b_data[1],
                             (STp->buffer)->b_data[2], (STp->buffer)->b_data[3]));
 
@@ -896,8 +894,8 @@
 			STp->block_size = (STp->buffer)->b_data[9] * 65536 +
 			    (STp->buffer)->b_data[10] * 256 + (STp->buffer)->b_data[11];
                         DEBC(printk(ST_DEB_MSG
-                                    "st%d: Density %x, tape length: %x, drv buffer: %d\n",
-                                    dev, STp->density, (STp->buffer)->b_data[5] * 65536 +
+                                    "%s: Density %x, tape length: %x, drv buffer: %d\n",
+                                    name, STp->density, (STp->buffer)->b_data[5] * 65536 +
                                     (STp->buffer)->b_data[6] * 256 + (STp->buffer)->b_data[7],
                                     STp->drv_buffer));
 		}
@@ -915,14 +913,14 @@
 	(STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
 
         DEBC(printk(ST_DEB_MSG
-                       "st%d: Block size: %d, buffer size: %d (%d blocks).\n", dev,
+                       "%s: Block size: %d, buffer size: %d (%d blocks).\n", name,
 		       STp->block_size, (STp->buffer)->buffer_size,
 		       (STp->buffer)->buffer_blocks));
 
 	if (STp->drv_write_prot) {
 		STp->write_prot = 1;
 
-                DEBC(printk(ST_DEB_MSG "st%d: Write protected\n", dev));
+                DEBC(printk(ST_DEB_MSG "%s: Write protected\n", name));
 
 		if ((st_flags & O_ACCMODE) == O_WRONLY ||
 		    (st_flags & O_ACCMODE) == O_RDWR) {
@@ -936,7 +934,7 @@
 		   after the driver has been initialized with tape in the drive and the
 		   partition support has been enabled. */
                 DEBC(printk(ST_DEB_MSG
-                            "st%d: Updating partition number in status.\n", dev));
+                            "%s: Updating partition number in status.\n", name));
 		if ((STp->partition = find_partition(STp)) < 0) {
 			retval = STp->partition;
 			goto err_out;
@@ -955,8 +953,8 @@
 		if (STp->default_drvbuffer != 0xff) {
 			if (st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer))
 				printk(KERN_WARNING
-                                       "st%d: Can't set default drive buffering to %d.\n",
-				       dev, STp->default_drvbuffer);
+                                       "%s: Can't set default drive buffering to %d.\n",
+				       name, STp->default_drvbuffer);
 		}
 	}
 
@@ -975,6 +973,7 @@
 	Scsi_Tape *STp;
 	ST_partstat *STps;
 	int dev = TAPE_NR(inode->i_rdev);
+	char *name;
 
 	write_lock(&st_dev_arr_lock);
 	if (dev >= st_template.dev_max || scsi_tapes == NULL ||
@@ -982,10 +981,12 @@
 		write_unlock(&st_dev_arr_lock);
 		return (-ENXIO);
 	}
+	filp->private_data = STp;
+	name = tape_name(STp);
 
 	if (STp->in_use) {
 		write_unlock(&st_dev_arr_lock);
-		DEB( printk(ST_DEB_MSG "st%d: Device already in use.\n", dev); )
+		DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); )
 		return (-EBUSY);
 	}
 	STp->in_use = 1;
@@ -1003,7 +1004,7 @@
 
 	/* See that we have at least a one page buffer available */
 	if (!enlarge_buffer(STp->buffer, PAGE_SIZE, STp->restr_dma)) {
-		printk(KERN_WARNING "st%d: Can't allocate tape buffer.\n", dev);
+		printk(KERN_WARNING "%s: Can't allocate tape buffer.\n", name);
 		retval = (-EOVERFLOW);
 		goto err_out;
 	}
@@ -1049,24 +1050,14 @@
 	int result = 0, result2;
 	unsigned char cmd[MAX_COMMAND_SIZE];
 	Scsi_Request *SRpnt;
-	Scsi_Tape *STp;
-	ST_mode *STm;
-	ST_partstat *STps;
-
-	struct inode *inode = filp->f_dentry->d_inode;
-	kdev_t devt = inode->i_rdev;
-	int dev;
+	Scsi_Tape *STp = filp->private_data;
+	ST_mode *STm = &(STp->modes[STp->current_mode]);
+	ST_partstat *STps = &(STp->ps[STp->partition]);
+	char *name = tape_name(STp);
 
 	if (file_count(filp) > 1)
 		return 0;
 
-	dev = TAPE_NR(devt);
-	read_lock(&st_dev_arr_lock);
-	STp = scsi_tapes[dev];
-	read_unlock(&st_dev_arr_lock);
-	STm = &(STp->modes[STp->current_mode]);
-	STps = &(STp->ps[STp->partition]);
-
 	if (STps->rw == ST_WRITING && !STp->pos_unknown) {
 		result = flush_write_buffer(STp);
 		if (result != 0 && result != (-ENOSPC))
@@ -1076,22 +1067,22 @@
 	if (STp->can_partitions &&
 	    (result2 = switch_partition(STp)) < 0) {
                 DEBC(printk(ST_DEB_MSG
-                               "st%d: switch_partition at close failed.\n", dev));
+                               "%s: switch_partition at close failed.\n", name));
 		if (result == 0)
 			result = result2;
 		goto out;
 	}
 
 	DEBC( if (STp->nbr_requests)
-		printk(KERN_WARNING "st%d: Number of r/w requests %d, dio used in %d, pages %d (%d).\n",
-		       dev, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages, STp->nbr_combinable));
+		printk(KERN_WARNING "%s: Number of r/w requests %d, dio used in %d, pages %d (%d).\n",
+		       name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages, STp->nbr_combinable));
 
 	if (STps->rw == ST_WRITING && !STp->pos_unknown) {
 
-                DEBC(printk(ST_DEB_MSG "st%d: File length %ld bytes.\n",
-                            dev, (long) (filp->f_pos));
-                     printk(ST_DEB_MSG "st%d: Async write waits %d, finished %d.\n",
-                            dev, STp->nbr_waits, STp->nbr_finished);
+                DEBC(printk(ST_DEB_MSG "%s: File length %ld bytes.\n",
+                            name, (long) (filp->f_pos));
+                     printk(ST_DEB_MSG "%s: Async write waits %d, finished %d.\n",
+                            name, STp->nbr_waits, STp->nbr_finished);
 		)
 
 		memset(cmd, 0, MAX_COMMAND_SIZE);
@@ -1115,7 +1106,7 @@
 			/* Filter out successful write at EOM */
 			scsi_release_request(SRpnt);
 			SRpnt = NULL;
-			printk(KERN_ERR "st%d: Error on write filemark.\n", dev);
+			printk(KERN_ERR "%s: Error on write filemark.\n", name);
 			if (result == 0)
 				result = (-EIO);
 		} else {
@@ -1129,8 +1120,8 @@
 			STps->eof = ST_FM;
 		}
 
-                DEBC(printk(ST_DEB_MSG "st%d: Buffer flushed, %d EOF(s) written\n",
-                            dev, cmd[4]));
+                DEBC(printk(ST_DEB_MSG "%s: Buffer flushed, %d EOF(s) written\n",
+                            name, cmd[4]));
 	} else if (!STp->rew_at_close) {
 		STps = &(STp->ps[STp->partition]);
 		if (!STm->sysv || STps->rw != ST_READING) {
@@ -1171,15 +1162,7 @@
 static int st_release(struct inode *inode, struct file *filp)
 {
 	int result = 0;
-	Scsi_Tape *STp;
-
-	kdev_t devt = inode->i_rdev;
-	int dev;
-
-	dev = TAPE_NR(devt);
-	read_lock(&st_dev_arr_lock);
-	STp = scsi_tapes[dev];
-	read_unlock(&st_dev_arr_lock);
+	Scsi_Tape *STp = filp->private_data;
 
 	if (STp->door_locked == ST_LOCKED_AUTO)
 		do_door_lock(STp, 0);
@@ -1245,8 +1228,7 @@
 
         DEB(
 	if (!STp->in_use) {
-		int dev = TAPE_NR(filp->f_dentry->d_inode->i_rdev);
-		printk(ST_DEB_MSG "st%d: Incorrect device.\n", dev);
+		printk(ST_DEB_MSG "%s: Incorrect device.\n", tape_name(STp));
 		retval = (-EIO);
 		goto out;
 	} ) /* end DEB */
@@ -1328,7 +1310,6 @@
 static ssize_t
  st_write(struct file *filp, const char *buf, size_t count, loff_t * ppos)
 {
-	struct inode *inode = filp->f_dentry->d_inode;
 	ssize_t total;
 	ssize_t i, do_count, blks, transfer;
 	ssize_t retval;
@@ -1337,15 +1318,11 @@
 	unsigned char cmd[MAX_COMMAND_SIZE];
 	const char *b_point;
 	Scsi_Request *SRpnt = NULL;
-	Scsi_Tape *STp;
+	Scsi_Tape *STp = filp->private_data;
 	ST_mode *STm;
 	ST_partstat *STps;
 	ST_buffer *STbp;
-	int dev = TAPE_NR(inode->i_rdev);
-
-	read_lock(&st_dev_arr_lock);
-	STp = scsi_tapes[dev];
-	read_unlock(&st_dev_arr_lock);
+	char *name = tape_name(STp);
 
 	if (down_interruptible(&STp->lock))
 		return -ERESTARTSYS;
@@ -1356,8 +1333,8 @@
 
 	/* Write must be integral number of blocks */
 	if (STp->block_size != 0 && (count % STp->block_size) != 0) {
-		printk(KERN_WARNING "st%d: Write not multiple of tape block size.\n",
-		       dev);
+		printk(KERN_WARNING "%s: Write not multiple of tape block size.\n",
+		       name);
 		retval = (-EINVAL);
 		goto out;
 	}
@@ -1383,8 +1360,8 @@
 		if (STm->default_compression != ST_DONT_TOUCH &&
 		    !(STp->compression_changed)) {
 			if (st_compression(STp, (STm->default_compression == ST_YES))) {
-				printk(KERN_WARNING "st%d: Can't set default compression.\n",
-				       dev);
+				printk(KERN_WARNING "%s: Can't set default compression.\n",
+				       name);
 				if (modes_defined) {
 					retval = (-EINVAL);
 					goto out;
@@ -1397,8 +1374,8 @@
 	if (STbp->writing) {
 		write_behind_check(STp);
 		if (STbp->syscall_result) {
-                        DEBC(printk(ST_DEB_MSG "st%d: Async write error (write) %x.\n",
-                                    dev, STbp->midlevel_result));
+                        DEBC(printk(ST_DEB_MSG "%s: Async write error (write) %x.\n",
+                                    name, STbp->midlevel_result));
 			if (STbp->midlevel_result == INT_MAX)
 				STps->eof = ST_EOM_OK;
 			else
@@ -1508,7 +1485,7 @@
 		}
 
 		if (STbp->syscall_result != 0) {
-                        DEBC(printk(ST_DEB_MSG "st%d: Error on write:\n", dev));
+                        DEBC(printk(ST_DEB_MSG "%s: Error on write:\n", name));
 			if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
 			    (SRpnt->sr_sense_buffer[2] & 0x40)) {
 				if ((SRpnt->sr_sense_buffer[0] & 0x80) != 0)
@@ -1540,8 +1517,8 @@
 					   undone > 0 || count == 0)
 						retval = (-ENOSPC); /* EOM within current request */
                                         DEBC(printk(ST_DEB_MSG
-                                                       "st%d: EOM with %d bytes unwritten.\n",
-						       dev, transfer));
+                                                       "%s: EOM with %d bytes unwritten.\n",
+						       name, transfer));
 				} else {
 					/* Previously buffered data not written */
 					count -= do_count;
@@ -1550,8 +1527,8 @@
 					STps->drv_block = (-1); /* Too cautious? */
 					retval = (-EIO);	/* EOM for old data */
 					DEBC(printk(ST_DEB_MSG
-                                                       "st%d: EOM with lost data.\n",
-                                                       dev));
+                                                       "%s: EOM with lost data.\n",
+                                                       name));
 				}
 			} else {
 				filp->f_pos -= do_count;
@@ -1608,8 +1585,8 @@
 	ST_mode *STm;
 	ST_partstat *STps;
 	ST_buffer *STbp;
-	int dev = TAPE_NR(STp->devt);
 	int retval = 0;
+	char *name = tape_name(STp);
 
 	if (count == 0)
 		return 0;
@@ -1655,8 +1632,8 @@
 	/* Something to check */
 	if (STbp->syscall_result) {
 		retval = 1;
-		DEBC(printk(ST_DEB_MSG "st%d: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
-                            dev,
+		DEBC(printk(ST_DEB_MSG "%s: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
+                            name,
                             SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[1],
                             SRpnt->sr_sense_buffer[2], SRpnt->sr_sense_buffer[3],
                             SRpnt->sr_sense_buffer[4], SRpnt->sr_sense_buffer[5],
@@ -1691,7 +1668,7 @@
 						scsi_release_request(SRpnt);
 						SRpnt = *aSRpnt = NULL;
 						if (transfer == blks) {	/* We did not get anything, error */
-							printk(KERN_NOTICE "st%d: Incorrect block size.\n", dev);
+							printk(KERN_NOTICE "%s: Incorrect block size.\n", name);
 							if (STps->drv_block >= 0)
 								STps->drv_block += blks - transfer + 1;
 							st_int_ioctl(STp, MTBSR, 1);
@@ -1701,8 +1678,8 @@
 						STbp->buffer_bytes = (blks - transfer) *
 						    STp->block_size;
                                                 DEBC(printk(ST_DEB_MSG
-                                                            "st%d: ILI but enough data received %ld %d.\n",
-                                                            dev, count, STbp->buffer_bytes));
+                                                            "%s: ILI but enough data received %ld %d.\n",
+                                                            name, count, STbp->buffer_bytes));
 						if (STps->drv_block >= 0)
 							STps->drv_block += 1;
 						if (st_int_ioctl(STp, MTBSR, 1))
@@ -1719,8 +1696,8 @@
 						STbp->buffer_bytes =
 						    bytes - transfer * STp->block_size;
                                         DEBC(printk(ST_DEB_MSG
-                                                    "st%d: EOF detected (%d bytes read).\n",
-                                                    dev, STbp->buffer_bytes));
+                                                    "%s: EOF detected (%d bytes read).\n",
+                                                    name, STbp->buffer_bytes));
 				} else if (SRpnt->sr_sense_buffer[2] & 0x40) {
 					if (STps->eof == ST_FM)
 						STps->eof = ST_EOD_1;
@@ -1732,20 +1709,20 @@
 						STbp->buffer_bytes =
 						    bytes - transfer * STp->block_size;
 
-                                        DEBC(printk(ST_DEB_MSG "st%d: EOM detected (%d bytes read).\n",
-                                                    dev, STbp->buffer_bytes));
+                                        DEBC(printk(ST_DEB_MSG "%s: EOM detected (%d bytes read).\n",
+                                                    name, STbp->buffer_bytes));
 				}
 			}
 			/* end of EOF, EOM, ILI test */ 
 			else {	/* nonzero sense key */
                                 DEBC(printk(ST_DEB_MSG
-                                            "st%d: Tape error while reading.\n", dev));
+                                            "%s: Tape error while reading.\n", name));
 				STps->drv_block = (-1);
 				if (STps->eof == ST_FM &&
 				    (SRpnt->sr_sense_buffer[2] & 0x0f) == BLANK_CHECK) {
                                         DEBC(printk(ST_DEB_MSG
-                                                    "st%d: Zero returned for first BLANK CHECK after EOF.\n",
-                                                    dev));
+                                                    "%s: Zero returned for first BLANK CHECK after EOF.\n",
+                                                    name));
 					STps->eof = ST_EOD_2;	/* First BLANK_CHECK after FM */
 				} else	/* Some other extended sense code */
 					retval = (-EIO);
@@ -1775,22 +1752,16 @@
 static ssize_t
  st_read(struct file *filp, char *buf, size_t count, loff_t * ppos)
 {
-	struct inode *inode = filp->f_dentry->d_inode;
 	ssize_t total;
 	ssize_t retval = 0;
 	ssize_t i, transfer;
 	int special;
 	Scsi_Request *SRpnt = NULL;
-	Scsi_Tape *STp;
+	Scsi_Tape *STp = filp->private_data;
 	ST_mode *STm;
 	ST_partstat *STps;
-	ST_buffer *STbp;
-	int dev = TAPE_NR(inode->i_rdev);
-
-	read_lock(&st_dev_arr_lock);
-	STp = scsi_tapes[dev];
-	read_unlock(&st_dev_arr_lock);
-	STbp = STp->buffer;
+	ST_buffer *STbp = STp->buffer;
+	DEB( char *name = tape_name(STp); )
 
 	if (down_interruptible(&STp->lock))
 		return -ERESTARTSYS;
@@ -1815,7 +1786,7 @@
 	}
         DEB(
 	if (debugging && STps->eof != ST_NOEOF)
-		printk(ST_DEB_MSG "st%d: EOF/EOM flag up (%d). Bytes %d\n", dev,
+		printk(ST_DEB_MSG "%s: EOF/EOM flag up (%d). Bytes %d\n", name,
 		       STps->eof, STbp->buffer_bytes);
         ) /* end DEB */
 
@@ -1866,7 +1837,7 @@
                         DEB(
 			if (debugging && STps->eof != ST_NOEOF)
 				printk(ST_DEB_MSG
-                                       "st%d: EOF up (%d). Left %d, needed %d.\n", dev,
+                                       "%s: EOF up (%d). Left %d, needed %d.\n", name,
 				       STps->eof, STbp->buffer_bytes,
                                        count - total);
                         ) /* end DEB */
@@ -1926,24 +1897,24 @@
 
 
 /* Set the driver options */
-static void st_log_options(Scsi_Tape * STp, ST_mode * STm, int dev)
+static void st_log_options(Scsi_Tape * STp, ST_mode * STm, char *name)
 {
 	printk(KERN_INFO
-	       "st%d: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
-	       dev, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
+	       "%s: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
+	       name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
 	       STm->do_read_ahead);
 	printk(KERN_INFO
-	       "st%d:    can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
-	       dev, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
+	       "%s:    can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
+	       name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
 	printk(KERN_INFO
-	       "st%d:    defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
-	       dev, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
+	       "%s:    defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
+	       name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
 	       STp->scsi2_logical);
 	printk(KERN_INFO
-	       "st%d:    sysv: %d nowait: %d\n", dev, STm->sysv, STp->immediate);
+	       "%s:    sysv: %d nowait: %d\n", name, STm->sysv, STp->immediate);
         DEB(printk(KERN_INFO
-                   "st%d:    debugging: %d\n",
-                   dev, debugging);)
+                   "%s:    debugging: %d\n",
+                   name, debugging);)
 }
 
 
@@ -1952,15 +1923,15 @@
 	int value;
 	long code;
 	ST_mode *STm;
-	int dev = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 
 	STm = &(STp->modes[STp->current_mode]);
 	if (!STm->defined) {
 		memcpy(STm, &(STp->modes[0]), sizeof(ST_mode));
 		modes_defined = TRUE;
                 DEBC(printk(ST_DEB_MSG
-                            "st%d: Initialized mode %d definition from mode 0\n",
-                            dev, STp->current_mode));
+                            "%s: Initialized mode %d definition from mode 0\n",
+                            name, STp->current_mode));
 	}
 
 	code = options & MT_ST_OPTIONS;
@@ -1980,7 +1951,7 @@
 		STp->immediate = (options & MT_ST_NOWAIT) != 0;
 		STm->sysv = (options & MT_ST_SYSV) != 0;
 		DEB( debugging = (options & MT_ST_DEBUGGING) != 0; )
-		st_log_options(STp, STm, dev);
+		st_log_options(STp, STm, name);
 	} else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
 		value = (code == MT_ST_SETBOOLEANS);
 		if ((options & MT_ST_BUFFER_WRITES) != 0)
@@ -2013,27 +1984,27 @@
                 DEB(
 		if ((options & MT_ST_DEBUGGING) != 0)
 			debugging = value; )
-		st_log_options(STp, STm, dev);
+		st_log_options(STp, STm, name);
 	} else if (code == MT_ST_WRITE_THRESHOLD) {
 		value = (options & ~MT_ST_OPTIONS) * ST_KILOBYTE;
 		if (value < 1 || value > st_fixed_buffer_size) {
 			printk(KERN_WARNING
-                               "st%d: Write threshold %d too small or too large.\n",
-			       dev, value);
+                               "%s: Write threshold %d too small or too large.\n",
+			       name, value);
 			return (-EIO);
 		}
 		STp->write_threshold = value;
-		printk(KERN_INFO "st%d: Write threshold set to %d bytes.\n",
-		       dev, value);
+		printk(KERN_INFO "%s: Write threshold set to %d bytes.\n",
+		       name, value);
 	} else if (code == MT_ST_DEF_BLKSIZE) {
 		value = (options & ~MT_ST_OPTIONS);
 		if (value == ~MT_ST_OPTIONS) {
 			STm->default_blksize = (-1);
-			printk(KERN_INFO "st%d: Default block size disabled.\n", dev);
+			printk(KERN_INFO "%s: Default block size disabled.\n", name);
 		} else {
 			STm->default_blksize = value;
-			printk(KERN_INFO "st%d: Default block size set to %d bytes.\n",
-			       dev, STm->default_blksize);
+			printk(KERN_INFO "%s: Default block size set to %d bytes.\n",
+			       name, STm->default_blksize);
 			if (STp->ready == ST_READY) {
 				STp->blksize_changed = FALSE;
 				set_mode_densblk(STp, STm);
@@ -2043,12 +2014,12 @@
 		value = (options & ~MT_ST_OPTIONS);
 		if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
 			STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
-			printk(KERN_INFO "st%d: Long timeout set to %d seconds.\n", dev,
+			printk(KERN_INFO "%s: Long timeout set to %d seconds.\n", name,
 			       (value & ~MT_ST_SET_LONG_TIMEOUT));
 		} else {
 			STp->timeout = value * HZ;
-			printk(KERN_INFO "st%d: Normal timeout set to %d seconds.\n",
-                               dev, value);
+			printk(KERN_INFO "%s: Normal timeout set to %d seconds.\n",
+                               name, value);
 		}
 	} else if (code == MT_ST_SET_CLN) {
 		value = (options & ~MT_ST_OPTIONS) & 0xff;
@@ -2059,20 +2030,20 @@
 		STp->cln_sense_mask = (options >> 8) & 0xff;
 		STp->cln_sense_value = (options >> 16) & 0xff;
 		printk(KERN_INFO
-		       "st%d: Cleaning request mode %d, mask %02x, value %02x\n",
-		       dev, value, STp->cln_sense_mask, STp->cln_sense_value);
+		       "%s: Cleaning request mode %d, mask %02x, value %02x\n",
+		       name, value, STp->cln_sense_mask, STp->cln_sense_value);
 	} else if (code == MT_ST_DEF_OPTIONS) {
 		code = (options & ~MT_ST_CLEAR_DEFAULT);
 		value = (options & MT_ST_CLEAR_DEFAULT);
 		if (code == MT_ST_DEF_DENSITY) {
 			if (value == MT_ST_CLEAR_DEFAULT) {
 				STm->default_density = (-1);
-				printk(KERN_INFO "st%d: Density default disabled.\n",
-                                       dev);
+				printk(KERN_INFO "%s: Density default disabled.\n",
+                                       name);
 			} else {
 				STm->default_density = value & 0xff;
-				printk(KERN_INFO "st%d: Density default set to %x\n",
-				       dev, STm->default_density);
+				printk(KERN_INFO "%s: Density default set to %x\n",
+				       name, STm->default_density);
 				if (STp->ready == ST_READY) {
 					STp->density_changed = FALSE;
 					set_mode_densblk(STp, STm);
@@ -2082,12 +2053,12 @@
 			if (value == MT_ST_CLEAR_DEFAULT) {
 				STp->default_drvbuffer = 0xff;
 				printk(KERN_INFO
-                                       "st%d: Drive buffer default disabled.\n", dev);
+                                       "%s: Drive buffer default disabled.\n", name);
 			} else {
 				STp->default_drvbuffer = value & 7;
 				printk(KERN_INFO
-                                       "st%d: Drive buffer default set to %x\n",
-				       dev, STp->default_drvbuffer);
+                                       "%s: Drive buffer default set to %x\n",
+				       name, STp->default_drvbuffer);
 				if (STp->ready == ST_READY)
 					st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer);
 			}
@@ -2095,17 +2066,17 @@
 			if (value == MT_ST_CLEAR_DEFAULT) {
 				STm->default_compression = ST_DONT_TOUCH;
 				printk(KERN_INFO
-                                       "st%d: Compression default disabled.\n", dev);
+                                       "%s: Compression default disabled.\n", name);
 			} else {
 				if ((value & 0xff00) != 0) {
 					STp->c_algo = (value & 0xff00) >> 8;
-					printk(KERN_INFO "st%d: Compression algorithm set to 0x%x.\n",
-					       dev, STp->c_algo);
+					printk(KERN_INFO "%s: Compression algorithm set to 0x%x.\n",
+					       name, STp->c_algo);
 				}
 				if ((value & 0xff) != 0xff) {
 					STm->default_compression = (value & 1 ? ST_YES : ST_NO);
-					printk(KERN_INFO "st%d: Compression default set to %x\n",
-					       dev, (value & 1));
+					printk(KERN_INFO "%s: Compression default set to %x\n",
+					       name, (value & 1));
 					if (STp->ready == ST_READY) {
 						STp->compression_changed = FALSE;
 						st_compression(STp, (STm->default_compression == ST_YES));
@@ -2217,7 +2188,7 @@
 	int retval;
 	int mpoffs;  /* Offset to mode page start */
 	unsigned char *b_data = (STp->buffer)->b_data;
-	DEB( int dev = TAPE_NR(STp->devt); )
+	DEB( char *name = tape_name(STp); )
 
 	if (STp->ready != ST_READY)
 		return (-EIO);
@@ -2225,18 +2196,18 @@
 	/* Read the current page contents */
 	retval = read_mode_page(STp, COMPRESSION_PAGE, FALSE);
 	if (retval) {
-                DEBC(printk(ST_DEB_MSG "st%d: Compression mode page not supported.\n",
-                            dev));
+                DEBC(printk(ST_DEB_MSG "%s: Compression mode page not supported.\n",
+                            name));
 		return (-EIO);
 	}
 
 	mpoffs = MODE_HEADER_LENGTH + b_data[MH_OFF_BDESCS_LENGTH];
-        DEBC(printk(ST_DEB_MSG "st%d: Compression state is %d.\n", dev,
+        DEBC(printk(ST_DEB_MSG "%s: Compression state is %d.\n", name,
                     (b_data[mpoffs + CP_OFF_DCE_DCC] & DCE_MASK ? 1 : 0)));
 
 	/* Check if compression can be changed */
 	if ((b_data[mpoffs + CP_OFF_DCE_DCC] & DCC_MASK) == 0) {
-                DEBC(printk(ST_DEB_MSG "st%d: Compression not supported.\n", dev));
+                DEBC(printk(ST_DEB_MSG "%s: Compression not supported.\n", name));
 		return (-EIO);
 	}
 
@@ -2254,11 +2225,11 @@
 
 	retval = write_mode_page(STp, COMPRESSION_PAGE);
 	if (retval) {
-                DEBC(printk(ST_DEB_MSG "st%d: Compression change failed.\n", dev));
+                DEBC(printk(ST_DEB_MSG "%s: Compression change failed.\n", name));
 		return (-EIO);
 	}
-        DEBC(printk(ST_DEB_MSG "st%d: Compression state changed to %d.\n",
-		       dev, state));
+        DEBC(printk(ST_DEB_MSG "%s: Compression state changed to %d.\n",
+		       name, state));
 
 	STp->compression_changed = TRUE;
 	return 0;
@@ -2269,7 +2240,7 @@
 static int do_load_unload(Scsi_Tape *STp, struct file *filp, int load_code)
 {
 	int retval = (-EIO), timeout;
-	DEB(int dev = TAPE_NR(STp->devt);)
+	DEB( char *name = tape_name(STp); )
 	unsigned char cmd[MAX_COMMAND_SIZE];
 	ST_partstat *STps;
 	Scsi_Request *SRpnt;
@@ -2290,8 +2261,8 @@
 	 */
 	if (load_code >= 1 + MT_ST_HPLOADER_OFFSET
 	    && load_code <= 6 + MT_ST_HPLOADER_OFFSET) {
-		DEBC(printk(ST_DEB_MSG "st%d: Enhanced %sload slot %2d.\n",
-			    dev, (cmd[4]) ? "" : "un",
+		DEBC(printk(ST_DEB_MSG "%s: Enhanced %sload slot %2d.\n",
+			    name, (cmd[4]) ? "" : "un",
 			    load_code - MT_ST_HPLOADER_OFFSET));
 		cmd[3] = load_code - MT_ST_HPLOADER_OFFSET; /* MediaID field of C1553A */
 	}
@@ -2304,9 +2275,9 @@
 
 	DEBC(
 		if (!load_code)
-		printk(ST_DEB_MSG "st%d: Unloading tape.\n", dev);
+		printk(ST_DEB_MSG "%s: Unloading tape.\n", name);
 		else
-		printk(ST_DEB_MSG "st%d: Loading tape.\n", dev);
+		printk(ST_DEB_MSG "%s: Loading tape.\n", name);
 		);
 
 	SRpnt = st_do_scsi(NULL, STp, cmd, 0, SCSI_DATA_NONE,
@@ -2351,7 +2322,7 @@
 	ST_partstat *STps;
 	int fileno, blkno, at_sm, undone;
 	int datalen = 0, direction = SCSI_DATA_NONE;
-	int dev = TAPE_NR(STp->devt);
+	char *name = tape_name(STp);
 
 	if (STp->ready != ST_READY) {
 		if (STp->ready == ST_NO_TAPE)
@@ -2375,8 +2346,8 @@
 		cmd[2] = (arg >> 16);
 		cmd[3] = (arg >> 8);
 		cmd[4] = arg;
-                DEBC(printk(ST_DEB_MSG "st%d: Spacing tape forward over %d filemarks.\n",
-			    dev, cmd[2] * 65536 + cmd[3] * 256 + cmd[4]));
+                DEBC(printk(ST_DEB_MSG "%s: Spacing tape forward over %d filemarks.\n",
+			    name, cmd[2] * 65536 + cmd[3] * 256 + cmd[4]));
 		if (fileno >= 0)
 			fileno += arg;
 		blkno = 0;
@@ -2396,8 +2367,8 @@
                      	ltmp = 0xff000000;
                      ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
                      printk(ST_DEB_MSG
-                            "st%d: Spacing tape backward over %ld filemarks.\n",
-                            dev, (-ltmp));
+                            "%s: Spacing tape backward over %ld filemarks.\n",
+                            name, (-ltmp));
 		)
 		if (fileno >= 0)
 			fileno -= arg;
@@ -2410,7 +2381,7 @@
 		cmd[2] = (arg >> 16);
 		cmd[3] = (arg >> 8);
 		cmd[4] = arg;
-                DEBC(printk(ST_DEB_MSG "st%d: Spacing tape forward %d blocks.\n", dev,
+                DEBC(printk(ST_DEB_MSG "%s: Spacing tape forward %d blocks.\n", name,
 			       cmd[2] * 65536 + cmd[3] * 256 + cmd[4]));
 		if (blkno >= 0)
 			blkno += arg;
@@ -2428,7 +2399,7 @@
                           ltmp = 0xff000000;
                      ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
                      printk(ST_DEB_MSG
-                            "st%d: Spacing tape backward %ld blocks.\n", dev, (-ltmp));
+                            "%s: Spacing tape backward %ld blocks.\n", name, (-ltmp));
 		)
 		if (blkno >= 0)
 			blkno -= arg;
@@ -2440,7 +2411,7 @@
 		cmd[2] = (arg >> 16);
 		cmd[3] = (arg >> 8);
 		cmd[4] = arg;
-                DEBC(printk(ST_DEB_MSG "st%d: Spacing tape forward %d setmarks.\n", dev,
+                DEBC(printk(ST_DEB_MSG "%s: Spacing tape forward %d setmarks.\n", name,
                             cmd[2] * 65536 + cmd[3] * 256 + cmd[4]));
 		if (arg != 0) {
 			blkno = fileno = (-1);
@@ -2458,8 +2429,8 @@
                      if (cmd[2] & 0x80)
 				ltmp = 0xff000000;
                      ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
-                     printk(ST_DEB_MSG "st%d: Spacing tape backward %ld setmarks.\n",
-                            dev, (-ltmp));
+                     printk(ST_DEB_MSG "%s: Spacing tape backward %ld setmarks.\n",
+                            name, (-ltmp));
 		)
 		if (arg != 0) {
 			blkno = fileno = (-1);
@@ -2479,10 +2450,10 @@
 		timeout = STp->timeout;
                 DEBC(
                      if (cmd_in == MTWEOF)
-                               printk(ST_DEB_MSG "st%d: Writing %d filemarks.\n", dev,
+                               printk(ST_DEB_MSG "%s: Writing %d filemarks.\n", name,
 				 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
                      else
-				printk(ST_DEB_MSG "st%d: Writing %d setmarks.\n", dev,
+				printk(ST_DEB_MSG "%s: Writing %d setmarks.\n", name,
 				 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
 		)
 		if (fileno >= 0)
@@ -2496,11 +2467,11 @@
 			cmd[1] = 1;	/* Don't wait for completion */
 			timeout = STp->timeout;
 		}
-                DEBC(printk(ST_DEB_MSG "st%d: Rewinding tape.\n", dev));
+                DEBC(printk(ST_DEB_MSG "%s: Rewinding tape.\n", name));
 		fileno = blkno = at_sm = 0;
 		break;
 	case MTNOP:
-                DEBC(printk(ST_DEB_MSG "st%d: No op on tape.\n", dev));
+                DEBC(printk(ST_DEB_MSG "%s: No op on tape.\n", name));
 		return 0;	/* Should do something ? */
 		break;
 	case MTRETEN:
@@ -2510,7 +2481,7 @@
 			timeout = STp->timeout;
 		}
 		cmd[4] = 3;
-                DEBC(printk(ST_DEB_MSG "st%d: Retensioning tape.\n", dev));
+                DEBC(printk(ST_DEB_MSG "%s: Retensioning tape.\n", name));
 		fileno = blkno = at_sm = 0;
 		break;
 	case MTEOM:
@@ -2528,8 +2499,8 @@
 			fileno = (-1);
 		cmd[0] = SPACE;
 		cmd[1] = 3;
-                DEBC(printk(ST_DEB_MSG "st%d: Spacing to end of recorded medium.\n",
-                            dev));
+                DEBC(printk(ST_DEB_MSG "%s: Spacing to end of recorded medium.\n",
+                            name));
 		blkno = 0;
 		at_sm = 0;
 		break;
@@ -2545,7 +2516,7 @@
 		else
 			timeout = STp->long_timeout * 8;
 
-                DEBC(printk(ST_DEB_MSG "st%d: Erasing tape.\n", dev));
+                DEBC(printk(ST_DEB_MSG "%s: Erasing tape.\n", name));
 		fileno = blkno = at_sm = 0;
 		break;
 	case MTSETBLK:		/* Set block length */
@@ -2560,7 +2531,7 @@
 		    STp->max_block > 0 &&
 		    ((arg & MT_ST_BLKSIZE_MASK) < STp->min_block ||
 		     (arg & MT_ST_BLKSIZE_MASK) > STp->max_block)) {
-			printk(KERN_WARNING "st%d: Illegal block size.\n", dev);
+			printk(KERN_WARNING "%s: Illegal block size.\n", name);
 			return (-EINVAL);
 		}
 		cmd[0] = MODE_SELECT;
@@ -2596,17 +2567,17 @@
                 DEBC(
 			if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK)
 				printk(ST_DEB_MSG
-                                       "st%d: Setting block size to %d bytes.\n", dev,
+                                       "%s: Setting block size to %d bytes.\n", name,
 				       (STp->buffer)->b_data[9] * 65536 +
 				       (STp->buffer)->b_data[10] * 256 +
 				       (STp->buffer)->b_data[11]);
 			if (cmd_in == MTSETDENSITY || cmd_in == SET_DENS_AND_BLK)
 				printk(ST_DEB_MSG
-                                       "st%d: Setting density code to %x.\n", dev,
+                                       "%s: Setting density code to %x.\n", name,
 				       (STp->buffer)->b_data[4]);
 			if (cmd_in == MTSETDRVBUFFER)
 				printk(ST_DEB_MSG
-                                       "st%d: Setting drive buffer code to %d.\n", dev,
+                                       "%s: Setting drive buffer code to %d.\n", name,
 				    ((STp->buffer)->b_data[2] >> 4) & 7);
 		)
 		break;
@@ -2759,7 +2730,7 @@
 	int result;
 	unsigned char scmd[MAX_COMMAND_SIZE];
 	Scsi_Request *SRpnt;
-	DEB( int dev = TAPE_NR(STp->devt); )
+	DEB( char *name = tape_name(STp); )
 
 	if (STp->ready != ST_READY)
 		return (-EIO);
@@ -2782,7 +2753,7 @@
 	    (STp->device->scsi_level >= SCSI_2 &&
 	     ((STp->buffer)->b_data[0] & 4) != 0)) {
 		*block = *partition = 0;
-                DEBC(printk(ST_DEB_MSG "st%d: Can't read tape position.\n", dev));
+                DEBC(printk(ST_DEB_MSG "%s: Can't read tape position.\n", name));
 		result = (-EIO);
 	} else {
 		result = 0;
@@ -2801,7 +2772,7 @@
 			    (STp->buffer)->b_data[1] == 0)	/* BOP of partition 0 */
 				STp->ps[0].drv_block = STp->ps[0].drv_file = 0;
 		}
-                DEBC(printk(ST_DEB_MSG "st%d: Got tape pos. blk %d part %d.\n", dev,
+                DEBC(printk(ST_DEB_MSG "%s: Got tape pos. blk %d part %d.\n", name,
                             *block, *partition));
 	}
 	scsi_release_request(SRpnt);
@@ -2822,15 +2793,15 @@
 	int timeout;
 	unsigned char scmd[MAX_COMMAND_SIZE];
 	Scsi_Request *SRpnt;
-	DEB( int dev = TAPE_NR(STp->devt); )
+	DEB( char *name = tape_name(STp); )
 
 	if (STp->ready != ST_READY)
 		return (-EIO);
 	timeout = STp->long_timeout;
 	STps = &(STp->ps[STp->partition]);
 
-        DEBC(printk(ST_DEB_MSG "st%d: Setting block to %d and partition to %d.\n",
-                    dev, block, partition));
+        DEBC(printk(ST_DEB_MSG "%s: Setting block to %d and partition to %d.\n",
+                    name, block, partition));
 	DEB(if (partition < 0)
 		return (-EIO); )
 
@@ -2845,8 +2816,8 @@
 			STps->last_block_valid = TRUE;
 			STps->last_block_visited = blk;
                         DEBC(printk(ST_DEB_MSG
-                                    "st%d: Visited block %d for partition %d saved.\n",
-                                    dev, blk, STp->partition));
+                                    "%s: Visited block %d for partition %d saved.\n",
+                                    name, blk, STp->partition));
 		}
 	}
 
@@ -2869,8 +2840,8 @@
 			scmd[1] |= 2;
 			scmd[8] = partition;
                         DEBC(printk(ST_DEB_MSG
-                                    "st%d: Trying to change partition from %d to %d\n",
-                                    dev, STp->partition, partition));
+                                    "%s: Trying to change partition from %d to %d\n",
+                                    name, STp->partition, partition));
 		}
 	}
 	if (STp->immediate) {
@@ -2961,7 +2932,7 @@
 static int nbr_partitions(Scsi_Tape *STp)
 {
 	int result;
-	DEB( int dev = TAPE_NR(STp->devt) );
+	DEB( char *name = tape_name(STp); )
 
 	if (STp->ready != ST_READY)
 		return (-EIO);
@@ -2969,13 +2940,13 @@
 	result = read_mode_page(STp, PART_PAGE, TRUE);
 
 	if (result) {
-                DEBC(printk(ST_DEB_MSG "st%d: Can't read medium partition page.\n",
-                            dev));
+                DEBC(printk(ST_DEB_MSG "%s: Can't read medium partition page.\n",
+                            name));
 		result = (-EIO);
 	} else {
 		result = (STp->buffer)->b_data[MODE_HEADER_LENGTH +
 					      PP_OFF_NBR_ADD_PARTS] + 1;
-                DEBC(printk(ST_DEB_MSG "st%d: Number of partitions %d.\n", dev, result));
+                DEBC(printk(ST_DEB_MSG "%s: Number of partitions %d.\n", name, result));
 	}
 
 	return result;
@@ -3003,20 +2974,21 @@
  */
 static int partition_tape(Scsi_Tape *STp, int size)
 {
-	int dev = TAPE_NR(STp->devt), result;
+	char *name = tape_name(STp);
+	int result;
 	int pgo, psd_cnt, psdo;
 	unsigned char *bp;
 
 	result = read_mode_page(STp, PART_PAGE, FALSE);
 	if (result) {
-		DEBC(printk(ST_DEB_MSG "st%d: Can't read partition mode page.\n", dev));
+		DEBC(printk(ST_DEB_MSG "%s: Can't read partition mode page.\n", name));
 		return result;
 	}
 	/* The mode page is in the buffer. Let's modify it and write it. */
 	bp = (STp->buffer)->b_data;
 	pgo = MODE_HEADER_LENGTH + bp[MH_OFF_BDESCS_LENGTH];
-	DEBC(printk(ST_DEB_MSG "st%d: Partition page length is %d bytes.\n",
-		    dev, bp[pgo + MP_OFF_PAGE_LENGTH] + 2));
+	DEBC(printk(ST_DEB_MSG "%s: Partition page length is %d bytes.\n",
+		    name, bp[pgo + MP_OFF_PAGE_LENGTH] + 2));
 
 	psd_cnt = (bp[pgo + MP_OFF_PAGE_LENGTH] + 2 - PART_PAGE_FIXED_LENGTH) / 2;
 	psdo = pgo + PART_PAGE_FIXED_LENGTH;
@@ -3026,7 +2998,7 @@
 	}
 	memset(bp + psdo, 0, bp[pgo + PP_OFF_NBR_ADD_PARTS] * 2);
 
-	DEBC(printk("st%d: psd_cnt %d, max.parts %d, nbr_parts %d\n", dev,
+	DEBC(printk("%s: psd_cnt %d, max.parts %d, nbr_parts %d\n", name,
 		    psd_cnt, bp[pgo + PP_OFF_MAX_ADD_PARTS],
 		    bp[pgo + PP_OFF_NBR_ADD_PARTS]));
 
@@ -3034,8 +3006,8 @@
 		bp[pgo + PP_OFF_NBR_ADD_PARTS] = 0;
 		if (psd_cnt <= bp[pgo + PP_OFF_MAX_ADD_PARTS])
 		    bp[pgo + MP_OFF_PAGE_LENGTH] = 6;
-                DEBC(printk(ST_DEB_MSG "st%d: Formatting tape with one partition.\n",
-                            dev));
+                DEBC(printk(ST_DEB_MSG "%s: Formatting tape with one partition.\n",
+                            name));
 	} else {
 		bp[psdo] = (size >> 8) & 0xff;
 		bp[psdo + 1] = size & 0xff;
@@ -3043,8 +3015,8 @@
 		if (bp[pgo + MP_OFF_PAGE_LENGTH] < 8)
 		    bp[pgo + MP_OFF_PAGE_LENGTH] = 8;
                 DEBC(printk(ST_DEB_MSG
-                            "st%d: Formatting tape with two partitions (1 = %d MB).\n",
-                            dev, size));
+                            "%s: Formatting tape with two partitions (1 = %d MB).\n",
+                            name, size));
 	}
 	bp[pgo + PP_OFF_PART_UNITS] = 0;
 	bp[pgo + PP_OFF_RESERVED] = 0;
@@ -3052,7 +3024,7 @@
 
 	result = write_mode_page(STp, PART_PAGE);
 	if (result) {
-		printk(KERN_INFO "st%d: Partitioning of tape failed.\n", dev);
+		printk(KERN_INFO "%s: Partitioning of tape failed.\n", name);
 		result = (-EIO);
 	}
 
@@ -3068,21 +3040,17 @@
 	int i, cmd_nr, cmd_type, bt;
 	int retval = 0;
 	unsigned int blk;
-	Scsi_Tape *STp;
+	Scsi_Tape *STp = file->private_data;
 	ST_mode *STm;
 	ST_partstat *STps;
-	int dev = TAPE_NR(inode->i_rdev);
-
-	read_lock(&st_dev_arr_lock);
-	STp = scsi_tapes[dev];
-	read_unlock(&st_dev_arr_lock);
+	char *name = tape_name(STp);
 
 	if (down_interruptible(&STp->lock))
 		return -ERESTARTSYS;
 
         DEB(
 	if (debugging && !STp->in_use) {
-		printk(ST_DEB_MSG "st%d: Incorrect device.\n", dev);
+		printk(ST_DEB_MSG "%s: Incorrect device.\n", name);
 		retval = (-EIO);
 		goto out;
 	} ) /* end DEB */
@@ -3119,7 +3087,7 @@
 
 		if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
 			printk(KERN_WARNING
-                               "st%d: MTSETDRVBUFFER only allowed for root.\n", dev);
+                               "%s: MTSETDRVBUFFER only allowed for root.\n", name);
 			retval = (-EPERM);
 			goto out;
 		}
@@ -3677,6 +3645,7 @@
 
 static int st_attach(Scsi_Device * SDp)
 {
+	struct gendisk *disk;
 	Scsi_Tape *tpnt;
 	ST_mode *STm;
 	ST_partstat *STps;
@@ -3704,6 +3673,12 @@
 		return 1;
 	}
 
+	disk = alloc_disk(1);
+	if (!disk) {
+		printk(KERN_ERR "st: out of memory. Device not attached.\n");
+		return 1;
+	}
+
 	write_lock(&st_dev_arr_lock);
 	if (st_template.nr_dev >= st_template.dev_max) {
 		Scsi_Tape **tmp_da;
@@ -3718,6 +3693,7 @@
 			write_unlock(&st_dev_arr_lock);
 			printk(KERN_ERR "st: Too many tape devices (max. %d).\n",
 			       ST_MAX_TAPES);
+			put_disk(disk);
 			return 1;
 		}
 
@@ -3731,6 +3707,7 @@
 			SDp->attached--;
 			write_unlock(&st_dev_arr_lock);
 			printk(KERN_ERR "st: Can't extend device array.\n");
+			put_disk(disk);
 			return 1;
 		}
 
@@ -3756,9 +3733,14 @@
 		SDp->attached--;
 		write_unlock(&st_dev_arr_lock);
 		printk(KERN_ERR "st: Can't allocate device descriptor.\n");
+		put_disk(disk);
 		return 1;
 	}
 	memset(tpnt, 0, sizeof(Scsi_Tape));
+	tpnt->disk = disk;
+	sprintf(disk->disk_name, "st%d", i);
+	disk->private_data = &tpnt->driver;
+	tpnt->driver = &st_template;
 	scsi_tapes[i] = tpnt;
 	dev_num = i;
 
@@ -3770,8 +3752,7 @@
 
 	tpnt->buffer = buffer;
 
-        tpnt->inited = 0;
-	tpnt->devt = mk_kdev(SCSI_TAPE_MAJOR, i);
+	tpnt->inited = 0;
 	tpnt->dirty = 0;
 	tpnt->in_use = 0;
 	tpnt->drv_buffer = 1;	/* Try buffering if no mode sense */
@@ -3890,10 +3871,10 @@
 	devfs_register_tape (tpnt->de_r[0]);
 
 	printk(KERN_WARNING
-	"Attached scsi tape st%d at scsi%d, channel %d, id %d, lun %d\n",
-	       dev_num, SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);
-	printk(KERN_WARNING "st%d: try direct i/o: %s, max page reachable by HBA %lu\n",
-	       dev_num, tpnt->try_dio ? "yes" : "no", tpnt->max_pfn);
+	"Attached scsi tape %s at scsi%d, channel %d, id %d, lun %d\n",
+	       tape_name(tpnt), SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);
+	printk(KERN_WARNING "%s: try direct i/o: %s, max page reachable by HBA %lu\n",
+	       tape_name(tpnt), tpnt->try_dio ? "yes" : "no", tpnt->max_pfn);
 
 	return 0;
 };
@@ -3945,6 +3926,7 @@
 				normalize_buffer(tpnt->buffer);
 				kfree(tpnt->buffer);
 			}
+			put_disk(tpnt->disk);
 			kfree(tpnt);
 			return;
 		}
@@ -3981,8 +3963,10 @@
 	unregister_chrdev(SCSI_TAPE_MAJOR, "st");
 	if (scsi_tapes != NULL) {
 		for (i=0; i < st_template.dev_max; ++i)
-			if (scsi_tapes[i])
+			if (scsi_tapes[i]) {
+				put_disk(scsi_tapes[i]->disk);
 				kfree(scsi_tapes[i]);
+			}
 		kfree(scsi_tapes);
 	}
 	st_template.dev_max = 0;
diff -Nru a/drivers/scsi/st.h b/drivers/scsi/st.h
--- a/drivers/scsi/st.h	Mon Nov  4 14:31:02 2002
+++ b/drivers/scsi/st.h	Mon Nov  4 14:31:02 2002
@@ -71,7 +71,7 @@
 
 /* The tape drive descriptor */
 typedef struct {
-	kdev_t devt;
+	struct Scsi_Device_Template *driver;
 	Scsi_Device *device;
 	struct semaphore lock;	/* For serialization */
 	struct completion wait;	/* For SCSI commands */
@@ -147,6 +147,7 @@
 	unsigned char last_cmnd[6];
 	unsigned char last_sense[16];
 #endif
+	struct gendisk *disk;
 } Scsi_Tape;
 
 /* Bit masks for use_pf */
diff -Nru a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c
--- a/drivers/scsi/sun3_NCR5380.c	Mon Nov  4 14:31:00 2002
+++ b/drivers/scsi/sun3_NCR5380.c	Mon Nov  4 14:31:00 2002
@@ -270,6 +270,9 @@
 #define	HOSTNO		instance->host_no
 #define	H_NO(cmd)	(cmd)->host->host_no
 
+#define SGADDR(buffer) (void *)(((unsigned long)page_address((buffer)->page)) + \
+			(buffer)->offset)
+
 #ifdef SUPPORT_TAGS
 
 /*
@@ -476,10 +479,10 @@
 
     for (endaddr = virt_to_phys(cmd->SCp.ptr + cmd->SCp.this_residual - 1) + 1;
 	 cmd->SCp.buffers_residual &&
-	 virt_to_phys(cmd->SCp.buffer[1].address) == endaddr; ) {
+	 virt_to_phys(SGADDR(&(cmd->SCp.buffer[1]))) == endaddr; ) {
 	
 	MER_PRINTK("VTOP(%p) == %08lx -> merging\n",
-		   cmd->SCp.buffer[1].address, endaddr);
+		   SGADDR(&(cmd->SCp.buffer[1])), endaddr);
 #if (NDEBUG & NDEBUG_MERGING)
 	++cnt;
 #endif
@@ -514,12 +517,13 @@
     if (cmd->use_sg) {
 	cmd->SCp.buffer = (struct scatterlist *) cmd->buffer;
 	cmd->SCp.buffers_residual = cmd->use_sg - 1;
-	cmd->SCp.ptr = (char *) cmd->SCp.buffer->address;
+	cmd->SCp.ptr = (char *) SGADDR(cmd->SCp.buffer);
 	cmd->SCp.this_residual = cmd->SCp.buffer->length;
+
 	/* ++roman: Try to merge some scatter-buffers if they are at
 	 * contiguous physical addresses.
 	 */
-	merge_contiguous_buffers( cmd );
+//	merge_contiguous_buffers( cmd );
     } else {
 	cmd->SCp.buffer = NULL;
 	cmd->SCp.buffers_residual = 0;
@@ -613,11 +617,11 @@
 
     status = NCR5380_read(STATUS_REG);
     if (!(status & SR_REQ)) 
-	printk(KERN_DEBUG "scsi%d: REQ not asserted, phase unknown.\n", HOSTNO);
+	printk("scsi%d: REQ not asserted, phase unknown.\n", HOSTNO);
     else {
 	for (i = 0; (phases[i].value != PHASE_UNKNOWN) && 
 	    (phases[i].value != (status & PHASE_MASK)); ++i); 
-	printk(KERN_DEBUG "scsi%d: phase %s\n", HOSTNO, phases[i].name);
+	printk("scsi%d: phase %s\n", HOSTNO, phases[i].name);
     }
 }
 
@@ -751,11 +755,8 @@
 static
 char *lprint_Scsi_Cmnd (Scsi_Cmnd *cmd, char *pos, char *buffer, int length);
 
-#ifndef NCR5380_proc_info
-static
-#endif
-int NCR5380_proc_info (char *buffer, char **start, off_t offset,
-		       int length, int hostno, int inout)
+static int NCR5380_proc_info (char *buffer, char **start, off_t offset,
+			      int length, int hostno, int inout)
 {
     char *pos = buffer;
     struct Scsi_Host *instance;
@@ -910,10 +911,7 @@
  */
 
 /* Only make static if a wrapper function is used */
-#ifndef NCR5380_queue_command
-static
-#endif
-int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
+static int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
 {
     SETUP_HOSTDATA(cmd->host);
     Scsi_Cmnd *tmp;
@@ -1211,7 +1209,7 @@
 	       HOSTNO, NCR5380_read(BUS_AND_STATUS_REG),
 	       NCR5380_read(STATUS_REG));
 
-    if((sun3scsi_dma_finish(hostdata->connected->request->cmd))) {
+    if((sun3scsi_dma_finish(rq_data_dir(hostdata->connected->request)))) {
 	    printk("scsi%d: overrun in UDC counter -- not prepared to deal with this!\n", HOSTNO);
 	    printk("please e-mail sammy@sammy.net with a description of how this\n");
 	    printk("error was produced.\n");
@@ -1315,11 +1313,14 @@
 	    {
 /* MS: Ignore unknown phase mismatch interrupts (caused by EOP interrupt) */
 		if (basr & BASR_PHASE_MATCH)
-		    printk(KERN_NOTICE "scsi%d: unknown interrupt, "
+		   INT_PRINTK("scsi%d: unknown interrupt, "
 			   "BASR 0x%x, MR 0x%x, SR 0x%x\n",
 			   HOSTNO, basr, NCR5380_read(MODE_REG),
 			   NCR5380_read(STATUS_REG));
 		(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+#ifdef SUN3_SCSI_VME
+		dregs->csr |= CSR_DMA_ENABLE;
+#endif
 	    }
 	} /* if !(SELECTION || PARITY) */
     } /* BASR & IRQ */
@@ -1329,6 +1330,9 @@
 	       "BASR 0x%X, MR 0x%X, SR 0x%x\n", HOSTNO, basr,
 	       NCR5380_read(MODE_REG), NCR5380_read(STATUS_REG));
 	(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+#ifdef SUN3_SCSI_VME
+		dregs->csr |= CSR_DMA_ENABLE;
+#endif
     }
     
     if (!done) {
@@ -1691,7 +1695,9 @@
 #ifndef SUPPORT_TAGS
     hostdata->busy[cmd->target] |= (1 << cmd->lun);
 #endif    
-
+#ifdef SUN3_SCSI_VME
+    dregs->csr |= CSR_INTR;
+#endif
     initialize_SCp(cmd);
 
 
@@ -1918,19 +1924,18 @@
 	 printk("scsi%d: transfer_dma without setup!\n", HOSTNO);
 	 BUG();
     }
-
     hostdata->dma_len = c;
 
     DMA_PRINTK("scsi%d: initializing DMA for %s, %d bytes %s %p\n",
 	       HOSTNO, (p & SR_IO) ? "reading" : "writing",
-	       c, (p & SR_IO) ? "to" : "from", d);
+	       c, (p & SR_IO) ? "to" : "from", *data);
 
     /* netbsd turns off ints here, why not be safe and do it too */
     save_flags(flags);
     cli();
     
     /* send start chain */
-    sun3_udc_write(UDC_CHN_START, UDC_CSR);
+    sun3scsi_dma_start(c, *data);
     
     if (p & SR_IO) {
 	    NCR5380_write(TARGET_COMMAND_REG, 1);
@@ -1946,6 +1951,10 @@
 	    NCR5380_write(START_DMA_SEND_REG, 0);
     }
 
+#ifdef SUN3_SCSI_VME
+    dregs->csr |= CSR_DMA_ENABLE;
+#endif
+
     restore_flags(flags);
 
     sun3_dma_active = 1;
@@ -1984,6 +1993,10 @@
     unsigned char phase, tmp, extended_msg[10], old_phase=0xff;
     Scsi_Cmnd *cmd = (Scsi_Cmnd *) hostdata->connected;
 
+#ifdef SUN3_SCSI_VME
+    dregs->csr |= CSR_INTR;
+#endif
+
     while (1) {
 	tmp = NCR5380_read(STATUS_REG);
 	/* We only have a valid SCSI phase when REQ is asserted */
@@ -2000,7 +2013,7 @@
 
 		if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) {
 			count = cmd->SCp.buffer->length;
-			d = cmd->SCp.buffer->address;
+			d = SGADDR(cmd->SCp.buffer);
 		} else {
 			count = cmd->SCp.this_residual;
 			d = cmd->SCp.ptr;
@@ -2010,13 +2023,16 @@
 		if((count > SUN3_DMA_MINSIZE) && (sun3_dma_setup_done
 						  != cmd))
 		{
-			if((cmd->request->cmd == 0) || (cmd->request->cmd == 1)) {
+			if(cmd->request->flags & REQ_CMD) {
 				sun3scsi_dma_setup(d, count,
-						   cmd->request->cmd);
+						   rq_data_dir(cmd->request));
 				sun3_dma_setup_done = cmd;
 			}
 		}
 #endif
+#ifdef SUN3_SCSI_VME
+		dregs->csr |= CSR_INTR;
+#endif
 	    }
 
 	    
@@ -2052,7 +2068,7 @@
 		    ++cmd->SCp.buffer;
 		    --cmd->SCp.buffers_residual;
 		    cmd->SCp.this_residual = cmd->SCp.buffer->length;
-		    cmd->SCp.ptr = cmd->SCp.buffer->address;
+		    cmd->SCp.ptr = SGADDR(cmd->SCp.buffer);
 
 		    /* ++roman: Try to merge some scatter-buffers if
 		     * they are at contiguous physical addresses.
@@ -2132,7 +2148,7 @@
 		NCR5380_write(SELECT_ENABLE_REG, 0); 	/* disable reselects */
 		NCR5380_transfer_pio(instance, &phase, &len, &data);
 		cmd->SCp.Message = tmp;
-
+		
 		switch (tmp) {
 		/*
 		 * Linking lets us reduce the time required to get the 
@@ -2338,6 +2354,9 @@
 		    /* Wait for bus free to avoid nasty timeouts */
 		    while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
 		    	barrier();
+#ifdef SUN3_SCSI_VME
+		    dregs->csr |= CSR_DMA_ENABLE;
+#endif
 		    return;
 		/* 
 		 * The SCSI data pointer is *IMPLICITLY* saved on a disconnect
@@ -2607,24 +2626,22 @@
     /* engage dma setup for the command we just saw */
     {
 	    void *d;
-		    unsigned long count;
+	    unsigned long count;
 
-		if (!tmp->SCp.this_residual && tmp->SCp.buffers_residual) {
-			count = tmp->SCp.buffer->length;
-			d = tmp->SCp.buffer->address;
-		} else {
-			count = tmp->SCp.this_residual;
-			d = tmp->SCp.ptr;
-		}
-#ifdef REAL_DMA		
-		/* setup this command for dma if not already */
-		if((count > SUN3_DMA_MINSIZE) && (sun3_dma_setup_done
-						  != tmp))
-		{
-			sun3scsi_dma_setup(d, count,
-					   tmp->request->cmd);
-			sun3_dma_setup_done = tmp;
-		}
+	    if (!tmp->SCp.this_residual && tmp->SCp.buffers_residual) {
+		    count = tmp->SCp.buffer->length;
+		    d = SGADDR(tmp->SCp.buffer);
+	    } else {
+		    count = tmp->SCp.this_residual;
+		    d = tmp->SCp.ptr;
+	    }
+#ifdef REAL_DMA
+	    /* setup this command for dma if not already */
+	    if((count > SUN3_DMA_MINSIZE) && (sun3_dma_setup_done != tmp))
+	    {
+		    sun3scsi_dma_setup(d, count, rq_data_dir(tmp->request));
+		    sun3_dma_setup_done = tmp;
+	    }
 #endif
     }
 #endif
@@ -2675,10 +2692,7 @@
  * 	 called where the loop started in NCR5380_main().
  */
 
-#ifndef NCR5380_abort
-static
-#endif
-int NCR5380_abort (Scsi_Cmnd *cmd)
+static int NCR5380_abort (Scsi_Cmnd *cmd)
 {
     struct Scsi_Host *instance = cmd->host;
     SETUP_HOSTDATA(instance);
@@ -2872,7 +2886,7 @@
  *
  */ 
 
-int NCR5380_reset( Scsi_Cmnd *cmd, unsigned int reset_flags)
+static int NCR5380_reset( Scsi_Cmnd *cmd, unsigned int reset_flags)
 {
     SETUP_HOSTDATA(cmd->host);
     int           i;
diff -Nru a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c
--- a/drivers/scsi/sun3_scsi.c	Mon Nov  4 14:31:00 2002
+++ b/drivers/scsi/sun3_scsi.c	Mon Nov  4 14:31:00 2002
@@ -1,7 +1,7 @@
 /*
  * Sun3 SCSI stuff by Erik Verbruggen (erik@bigmama.xtdnet.nl)
  *
- * Sun3 DMA routines added by Sam Creasey (sammy@oh.verio.com)
+ * Sun3 DMA routines added by Sam Creasey (sammy@sammy.net)
  *
  * Adapted from mac_scsinew.c:
  */
@@ -79,8 +79,10 @@
 #include "sun3_scsi.h"
 #include "NCR5380.h"
 
+/* #define OLDDMA */
+
 #define USE_WRAPPER
-#define RESET_BOOT
+/*#define RESET_BOOT */
 #define DRIVER_SETUP
 
 #define NDEBUG 0
@@ -93,7 +95,7 @@
 #undef DRIVER_SETUP
 #endif
 
-#undef SUPPORT_TAGS
+/* #define SUPPORT_TAGS */
 
 #define	ENABLE_IRQ()	enable_irq( IRQ_SUN3_SCSI ); 
 
@@ -103,12 +105,17 @@
 static inline void sun3scsi_write(int reg, int value);
 
 static int setup_can_queue = -1;
+MODULE_PARM(setup_can_queue, "i");
 static int setup_cmd_per_lun = -1;
+MODULE_PARM(setup_cmd_per_lun, "i");
 static int setup_sg_tablesize = -1;
+MODULE_PARM(setup_sg_tablesize, "i");
 #ifdef SUPPORT_TAGS
 static int setup_use_tagged_queuing = -1;
+MODULE_PARM(setup_use_tagged_queuing, "i");
 #endif
 static int setup_hostid = -1;
+MODULE_PARM(setup_hostid, "i");
 
 static Scsi_Cmnd *sun3_dma_setup_done = NULL;
 
@@ -125,7 +132,9 @@
 
 static volatile unsigned char *sun3_scsi_regp;
 static volatile struct sun3_dma_regs *dregs;
+#ifdef OLDDMA
 static unsigned char *dmabuf = NULL; /* dma memory buffer */
+#endif
 static struct sun3_udc_regs *udc_regs = NULL;
 static unsigned char *sun3_dma_orig_addr = NULL;
 static unsigned long sun3_dma_orig_count = 0;
@@ -187,8 +196,7 @@
  
 int sun3scsi_detect(Scsi_Host_Template * tpnt)
 {
-	unsigned long ioaddr, iopte;
-	int count = 0;
+	unsigned long ioaddr;
 	static int called = 0;
 	struct Scsi_Host *instance;
 
@@ -222,28 +230,9 @@
 		tpnt->this_id = 7;
 	}
 
-	/* Taken from Sammy's lance driver: */
-        /* IOBASE_SUN3_SCSI can be found within the IO pmeg with some effort */
-        for(ioaddr = 0xfe00000; ioaddr < (0xfe00000 + SUN3_PMEG_SIZE);
-            ioaddr += SUN3_PTE_SIZE) {
-
-                iopte = sun3_get_pte(ioaddr);
-                if(!(iopte & SUN3_PAGE_TYPE_IO)) /* this an io page? */
-                        continue;
-
-                if(((iopte & SUN3_PAGE_PGNUM_MASK) << PAGE_SHIFT) ==
-                   IOBASE_SUN3_SCSI) {
-                        count = 1;
-                        break;
-                }
-        }
-
-	if(!count) {
-		printk("No Sun3 NCR5380 found!\n");
-		return 0;
-	}
-
+	ioaddr = (unsigned long)ioremap(IOBASE_SUN3_SCSI, PAGE_SIZE);
 	sun3_scsi_regp = (unsigned char *)ioaddr;
+
 	dregs = (struct sun3_dma_regs *)(((unsigned char *)ioaddr) + 8);
 
 	if((udc_regs = dvma_malloc(sizeof(struct sun3_udc_regs)))
@@ -259,7 +248,7 @@
 #endif
 #ifdef SUPPORT_TAGS
 	if (setup_use_tagged_queuing < 0)
-		setup_use_tagged_queuing = DEFAULT_USE_TAGGED_QUEUING;
+		setup_use_tagged_queuing = USE_TAGGED_QUEUING;
 #endif
 
 	instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
@@ -309,16 +298,25 @@
 	dregs->fifo_count = 0;
 
 	called = 1;
+
+#ifdef RESET_BOOT
+	sun3_scsi_reset_boot(instance);
+#endif
+
 	return 1;
 }
 
+#ifdef MODULE
 int sun3scsi_release (struct Scsi_Host *shpnt)
 {
 	if (shpnt->irq != IRQ_NONE)
 		free_irq (shpnt->irq, NULL);
 
+	iounmap(sun3_scsi_regp);
+
 	return 0;
 }
+#endif
 
 #ifdef RESET_BOOT
 /*
@@ -340,7 +338,7 @@
 	printk( "Sun3 SCSI: resetting the SCSI bus..." );
 
 	/* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */
-       	sun3_disable_irq( IRQ_SUN3_SCSI );
+//       	sun3_disable_irq( IRQ_SUN3_SCSI );
 
 	/* get in phase */
 	NCR5380_write( TARGET_COMMAND_REG,
@@ -360,7 +358,7 @@
 		barrier();
 
 	/* switch on SCSI IRQ again */
-       	sun3_enable_irq( IRQ_SUN3_SCSI );
+//       	sun3_enable_irq( IRQ_SUN3_SCSI );
 
 	printk( " done\n" );
 }
@@ -426,8 +424,12 @@
 #else
 	void *addr;
 
+	if(sun3_dma_orig_addr != NULL)
+		dvma_unmap(sun3_dma_orig_addr);
+
 //	addr = sun3_dvma_page((unsigned long)data, (unsigned long)dmabuf);
 	addr = (void *)dvma_map((unsigned long) data, count);
+		
 	sun3_dma_orig_addr = addr;
 	sun3_dma_orig_count = count;
 #endif
@@ -453,7 +455,6 @@
 	dregs->csr &= ~CSR_FIFO;
 	dregs->csr |= CSR_FIFO;
 	
-
 	if(dregs->fifo_count != count) { 
 		printk("scsi%d: fifo_mismatch %04x not %04x\n",
 		       default_instance->host_no, dregs->fifo_count,
@@ -518,12 +519,20 @@
 static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, Scsi_Cmnd *cmd,
 				    int write_flag)
 {
-	if((cmd->request->cmd == 0) || (cmd->request->cmd == 1))
+	if(cmd->request->flags & REQ_CMD)
  		return wanted;
 	else
 		return 0;
 }
 
+static inline int sun3scsi_dma_start(unsigned long count, unsigned char *data)
+{
+
+    sun3_udc_write(UDC_CHN_START, UDC_CSR);
+    
+    return 0;
+}
+
 /* clean up after our dma is done */
 static int sun3scsi_dma_finish(int write_flag)
 {
@@ -532,7 +541,7 @@
 	int ret = 0;
 	
 	sun3_dma_active = 0;
-
+#if 1
 	// check to empty the fifo on a read
 	if(!write_flag) {
 		int tmo = 200000; /* 2 sec */
@@ -541,13 +550,15 @@
 			if(dregs->csr & CSR_FIFO_EMPTY)
 				break;
 
-			if(--tmo <= 0) 
+			if(--tmo <= 0) {
+				printk("sun3scsi: fifo failed to empty!\n");
 				return 1;
-
+			}
 			udelay(10);
 		}
 	}
 		
+#endif
 
 	count = sun3scsi_dma_count(default_instance);
 #ifdef OLDDMA
@@ -587,6 +598,7 @@
 	}
 
 	dvma_unmap(sun3_dma_orig_addr);
+	sun3_dma_orig_addr = NULL;
 #endif
 	sun3_udc_write(UDC_RESET, UDC_CSR);
 	dregs->fifo_count = 0;
diff -Nru a/drivers/scsi/sun3_scsi.h b/drivers/scsi/sun3_scsi.h
--- a/drivers/scsi/sun3_scsi.h	Mon Nov  4 14:31:00 2002
+++ b/drivers/scsi/sun3_scsi.h	Mon Nov  4 14:31:00 2002
@@ -1,7 +1,7 @@
 /*
  * Sun3 SCSI stuff by Erik Verbruggen (erik@bigmama.xtdnet.nl)
  *
- * Sun3 DMA additions by Sam Creasey (sammy@oh.verio.com)
+ * Sun3 DMA additions by Sam Creasey (sammy@sammy.net)
  *
  * Adapted from mac_scsinew.h:
  */
@@ -36,6 +36,11 @@
 #ifndef SUN3_NCR5380_H
 #define SUN3_NCR5380_H
 
+#ifndef NULL
+#define NULL 0
+#endif
+
+
 #define SUN3SCSI_PUBLIC_RELEASE 1
 
 /*
@@ -45,17 +50,19 @@
 #define IRQ_SUN3_SCSI 2
 #define IOBASE_SUN3_SCSI 0x00140000
 
-int sun3scsi_abort (Scsi_Cmnd *);
-int sun3scsi_detect (Scsi_Host_Template *);
-int sun3scsi_release (struct Scsi_Host *);
-const char *sun3scsi_info (struct Scsi_Host *);
-int sun3scsi_reset(Scsi_Cmnd *, unsigned int);
-int sun3scsi_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int sun3scsi_proc_info (char *buffer, char **start, off_t offset,
-			int length, int hostno, int inout);
+#define IOBASE_SUN3_VMESCSI 0xff200000
 
-#ifndef NULL
-#define NULL 0
+static int sun3scsi_abort (Scsi_Cmnd *);
+static int sun3scsi_detect (Scsi_Host_Template *);
+static const char *sun3scsi_info (struct Scsi_Host *);
+static int sun3scsi_reset(Scsi_Cmnd *, unsigned int);
+static int sun3scsi_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int sun3scsi_proc_info (char *buffer, char **start, off_t offset,
+			int length, int hostno, int inout);
+#ifdef MODULE
+static int sun3scsi_release (struct Scsi_Host *);
+#else
+#define sun3scsi_release NULL
 #endif
 
 #ifndef CMD_PER_LUN
@@ -70,26 +77,36 @@
 #define SG_TABLESIZE SG_NONE
 #endif
 
+#ifndef MAX_TAGS
+#define MAX_TAGS 32
+#endif
+
 #ifndef USE_TAGGED_QUEUING
-#define	USE_TAGGED_QUEUING 0
+#define	USE_TAGGED_QUEUING 1
 #endif
 
 #include <scsi/scsicam.h>
 
+#ifdef SUN3_SCSI_VME
+#define SUN3_SCSI_NAME "Sun3 NCR5380 VME SCSI"
+#else
+#define SUN3_SCSI_NAME "Sun3 NCR5380 SCSI"
+#endif
+
 #define SUN3_NCR5380 {							\
-name:			"Sun3 NCR5380 SCSI",				\
-detect:			sun3scsi_detect,				\
-release:		sun3scsi_release,	/* Release */		\
-info:			sun3scsi_info,					\
-queuecommand:		sun3scsi_queue_command,				\
-abort:			sun3scsi_abort,			 		\
-reset:			sun3scsi_reset,					\
-can_queue:		CAN_QUEUE,		/* can queue */		\
-this_id:		7,			/* id */		\
-sg_tablesize:		SG_ALL,			/* sg_tablesize */	\
-cmd_per_lun:		CMD_PER_LUN,		/* cmd per lun */	\
-unchecked_isa_dma:	0,			/* unchecked_isa_dma */	\
-use_clustering:		DISABLE_CLUSTERING				\
+.name =			SUN3_SCSI_NAME,					\
+.detect =		sun3scsi_detect,				\
+.release =		sun3scsi_release,	/* Release */		\
+.info =			sun3scsi_info,					\
+.queuecommand =		sun3scsi_queue_command,				\
+.abort =		sun3scsi_abort,					\
+.reset =		sun3scsi_reset,					\
+.can_queue =		CAN_QUEUE,		/* can queue */		\
+.this_id =		7,			/* id */		\
+.sg_tablesize =		SG_TABLESIZE,		/* sg_tablesize */	\
+.cmd_per_lun =		CMD_PER_LUN,		/* cmd per lun */	\
+.unchecked_isa_dma =	0,			/* unchecked_isa_dma */	\
+.use_clustering =	DISABLE_CLUSTERING				\
 	}
 
 #ifndef HOSTS_C
@@ -124,13 +141,20 @@
 /* additional registers - mainly DMA control regs */
 /* these start at regbase + 8 -- directly after the NCR regs */
 struct sun3_dma_regs {
-	unsigned short vmeregs[4];  /* unimpl vme stuff */
-	unsigned short udc_data; /* udc dma data reg */
-	unsigned short udc_addr; /* uda dma addr reg */
+	unsigned short dma_addr_hi; /* vme only */
+	unsigned short dma_addr_lo; /* vme only */
+	unsigned short dma_count_hi; /* vme only */
+	unsigned short dma_count_lo; /* vme only */
+	unsigned short udc_data; /* udc dma data reg (obio only) */
+	unsigned short udc_addr; /* uda dma addr reg (obio only) */
 	unsigned short fifo_data; /* fifo data reg, holds extra byte on
 				     odd dma reads */
 	unsigned short fifo_count; 
 	unsigned short csr; /* control/status reg */
+	unsigned short bpack_hi; /* vme only */
+	unsigned short bpack_lo; /* vme only */
+	unsigned short ivect; /* vme only */
+	unsigned short fifo_count_hi; /* vme only */
 };
 
 /* ucd chip specific regs - live in dvma space */
@@ -179,11 +203,21 @@
 #define CSR_SDB_INT 0x200 /* sbc interrupt pending */
 #define CSR_DMA_INT 0x100 /* dma interrupt pending */
 
+#define CSR_LEFT 0xc0
+#define CSR_LEFT_3 0xc0
+#define CSR_LEFT_2 0x80
+#define CSR_LEFT_1 0x40
+#define CSR_PACK_ENABLE 0x20
+
+#define CSR_DMA_ENABLE 0x10
+
 #define CSR_SEND 0x8 /* 1 = send  0 = recv */
 #define CSR_FIFO 0x2 /* reset fifo */
 #define CSR_INTR 0x4 /* interrupt enable */
 #define CSR_SCSI 0x1 
 
+#define VME_DATA24 0x3d00
+
 // debugging printk's, taken from atari_scsi.h 
 /* Debugging printk definitions:
  *
@@ -364,8 +398,6 @@
 
 #define NCR_PRINT_STATUS(mask) \
 	((NDEBUG & (mask)) ? NCR5380_print_status(instance) : (void)0)
-
-#define NDEBUG_ANY	0xffffffff
 
 
 
diff -Nru a/drivers/scsi/sun3_scsi_vme.c b/drivers/scsi/sun3_scsi_vme.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/scsi/sun3_scsi_vme.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,567 @@
+/*
+ * Sun3 SCSI stuff by Erik Verbruggen (erik@bigmama.xtdnet.nl)
+ *
+ * Sun3 DMA routines added by Sam Creasey (sammy@sammy.net)
+ *
+ * VME support added by Sam Creasey
+ *
+ * Adapted from sun3_scsi.c -- see there for other headers
+ *
+ * TODO: modify this driver to support multiple Sun3 SCSI VME boards
+ *
+ */
+
+#define AUTOSENSE
+
+#include <linux/types.h>
+#include <linux/stddef.h>
+#include <linux/ctype.h>
+#include <linux/delay.h>
+
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/blk.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+
+#include <asm/sun3ints.h>
+#include <asm/dvma.h>
+#include <asm/idprom.h>
+#include <asm/machines.h>
+
+#define SUN3_SCSI_VME
+
+#undef SUN3_SCSI_DEBUG
+
+/* dma on! */
+#define REAL_DMA
+
+#include "scsi.h"
+#include "hosts.h"
+#include "sun3_scsi.h"
+#include "NCR5380.h"
+
+extern int sun3_map_test(unsigned long, char *);
+
+#define USE_WRAPPER
+/*#define RESET_BOOT */
+#define DRIVER_SETUP
+
+#define NDEBUG 0
+
+/*
+ * BUG can be used to trigger a strange code-size related hang on 2.1 kernels
+ */
+#ifdef BUG
+#undef RESET_BOOT
+#undef DRIVER_SETUP
+#endif
+
+/* #define SUPPORT_TAGS */
+
+//#define	ENABLE_IRQ()	enable_irq( SUN3_VEC_VMESCSI0 ); 
+#define ENABLE_IRQ()
+
+
+static void scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp);
+static inline unsigned char sun3scsi_read(int reg);
+static inline void sun3scsi_write(int reg, int value);
+
+static int setup_can_queue = -1;
+MODULE_PARM(setup_can_queue, "i");
+static int setup_cmd_per_lun = -1;
+MODULE_PARM(setup_cmd_per_lun, "i");
+static int setup_sg_tablesize = -1;
+MODULE_PARM(setup_sg_tablesize, "i");
+#ifdef SUPPORT_TAGS
+static int setup_use_tagged_queuing = -1;
+MODULE_PARM(setup_use_tagged_queuing, "i");
+#endif
+static int setup_hostid = -1;
+MODULE_PARM(setup_hostid, "i");
+
+static Scsi_Cmnd *sun3_dma_setup_done = NULL;
+
+#define	AFTER_RESET_DELAY	(HZ/2)
+
+/* ms to wait after hitting dma regs */
+#define SUN3_DMA_DELAY 10
+
+/* dvma buffer to allocate -- 32k should hopefully be more than sufficient */
+#define SUN3_DVMA_BUFSIZE 0xe000
+
+/* minimum number of bytes to do dma on */
+#define SUN3_DMA_MINSIZE 128
+
+static volatile unsigned char *sun3_scsi_regp;
+static volatile struct sun3_dma_regs *dregs;
+#ifdef OLDDMA
+static unsigned char *dmabuf = NULL; /* dma memory buffer */
+#endif
+static unsigned char *sun3_dma_orig_addr = NULL;
+static unsigned long sun3_dma_orig_count = 0;
+static int sun3_dma_active = 0;
+static unsigned long last_residual = 0;
+
+/*
+ * NCR 5380 register access functions
+ */
+
+static inline unsigned char sun3scsi_read(int reg)
+{
+	return( sun3_scsi_regp[reg] );
+}
+
+static inline void sun3scsi_write(int reg, int value)
+{
+	sun3_scsi_regp[reg] = value;
+}
+
+/*
+ * XXX: status debug
+ */
+static struct Scsi_Host *default_instance;
+
+/*
+ * Function : int sun3scsi_detect(Scsi_Host_Template * tpnt)
+ *
+ * Purpose : initializes mac NCR5380 driver based on the
+ *	command line / compile time port and irq definitions.
+ *
+ * Inputs : tpnt - template for this SCSI adapter.
+ *
+ * Returns : 1 if a host adapter was found, 0 if not.
+ *
+ */
+ 
+static int sun3scsi_detect(Scsi_Host_Template * tpnt)
+{
+	unsigned long ioaddr, irq;
+	static int called = 0;
+	struct Scsi_Host *instance;
+	int i;
+	unsigned long addrs[3] = { IOBASE_SUN3_VMESCSI, 
+				   IOBASE_SUN3_VMESCSI + 0x4000,
+				   0 };
+	unsigned long vecs[3] = { SUN3_VEC_VMESCSI0,
+				  SUN3_VEC_VMESCSI1,
+				  0 };
+	/* check that this machine has an onboard 5380 */
+	switch(idprom->id_machtype) {
+	case SM_SUN3|SM_3_160:
+	case SM_SUN3|SM_3_260:
+		break;
+
+	default:
+		return 0;
+	}
+
+	if(called)
+		return 0;
+
+	tpnt->proc_name = "Sun3 5380 VME SCSI";
+
+	/* setup variables */
+	tpnt->can_queue =
+		(setup_can_queue > 0) ? setup_can_queue : CAN_QUEUE;
+	tpnt->cmd_per_lun =
+		(setup_cmd_per_lun > 0) ? setup_cmd_per_lun : CMD_PER_LUN;
+	tpnt->sg_tablesize = 
+		(setup_sg_tablesize >= 0) ? setup_sg_tablesize : SG_TABLESIZE;
+	
+	if (setup_hostid >= 0)
+		tpnt->this_id = setup_hostid;
+	else {
+		/* use 7 as default */
+		tpnt->this_id = 7;
+	}
+	
+	ioaddr = 0;
+	for(i = 0; addrs[i] != 0; i++) {
+		unsigned char x;
+		
+		ioaddr = (unsigned long)sun3_ioremap(addrs[i], PAGE_SIZE,
+						     SUN3_PAGE_TYPE_VME16);
+		irq = vecs[i];
+		sun3_scsi_regp = (unsigned char *)ioaddr;
+		
+		dregs = (struct sun3_dma_regs *)(((unsigned char *)ioaddr) + 8);
+		
+		if(sun3_map_test((unsigned long)dregs, &x)) {
+			unsigned short oldcsr;
+
+			oldcsr = dregs->csr;
+			dregs->csr = 0;
+			udelay(SUN3_DMA_DELAY);
+			if(dregs->csr == 0x1400)
+				break;
+			
+			dregs->csr = oldcsr;
+		}
+
+		iounmap((void *)ioaddr);
+		ioaddr = 0;
+	}
+
+	if(!ioaddr)
+		return 0;
+	
+#ifdef SUPPORT_TAGS
+	if (setup_use_tagged_queuing < 0)
+		setup_use_tagged_queuing = USE_TAGGED_QUEUING;
+#endif
+
+	instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
+	if(instance == NULL)
+		return 0;
+		
+	default_instance = instance;
+
+        instance->io_port = (unsigned long) ioaddr;
+	instance->irq = irq;
+
+	NCR5380_init(instance, 0);
+
+	instance->n_io_port = 32;
+
+        ((struct NCR5380_hostdata *)instance->hostdata)->ctrl = 0;
+
+	if (request_irq(instance->irq, scsi_sun3_intr,
+			     0, "Sun3SCSI-5380VME", NULL)) {
+#ifndef REAL_DMA
+		printk("scsi%d: IRQ%d not free, interrupts disabled\n",
+		       instance->host_no, instance->irq);
+		instance->irq = IRQ_NONE;
+#else
+		printk("scsi%d: IRQ%d not free, bailing out\n",
+		       instance->host_no, instance->irq);
+		return 0;
+#endif
+	}
+
+	printk("scsi%d: Sun3 5380 VME at port %lX irq", instance->host_no, instance->io_port);
+	if (instance->irq == IRQ_NONE)
+		printk ("s disabled");
+	else
+		printk (" %d", instance->irq);
+	printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
+	       instance->can_queue, instance->cmd_per_lun,
+	       SUN3SCSI_PUBLIC_RELEASE);
+	printk("\nscsi%d:", instance->host_no);
+	NCR5380_print_options(instance);
+	printk("\n");
+
+	dregs->csr = 0;
+	udelay(SUN3_DMA_DELAY);
+	dregs->csr = CSR_SCSI | CSR_FIFO | CSR_INTR;
+	udelay(SUN3_DMA_DELAY);
+	dregs->fifo_count = 0;
+	dregs->fifo_count_hi = 0;
+	dregs->dma_addr_hi = 0;
+	dregs->dma_addr_lo = 0;
+	dregs->dma_count_hi = 0;
+	dregs->dma_count_lo = 0;
+
+	dregs->ivect = VME_DATA24 | (instance->irq & 0xff);
+
+	called = 1;
+
+#ifdef RESET_BOOT
+	sun3_scsi_reset_boot(instance);
+#endif
+
+	return 1;
+}
+
+#ifdef MODULE
+int sun3scsi_release (struct Scsi_Host *shpnt)
+{
+	if (shpnt->irq != IRQ_NONE)
+		free_irq (shpnt->irq, NULL);
+
+	iounmap(sun3_scsi_regp);
+
+	return 0;
+}
+#endif
+
+#ifdef RESET_BOOT
+/*
+ * Our 'bus reset on boot' function
+ */
+
+static void sun3_scsi_reset_boot(struct Scsi_Host *instance)
+{
+	unsigned long end;
+
+	NCR5380_local_declare();
+	NCR5380_setup(instance);
+	
+	/*
+	 * Do a SCSI reset to clean up the bus during initialization. No
+	 * messing with the queues, interrupts, or locks necessary here.
+	 */
+
+	printk( "Sun3 SCSI: resetting the SCSI bus..." );
+
+	/* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */
+//       	sun3_disable_irq( IRQ_SUN3_SCSI );
+
+	/* get in phase */
+	NCR5380_write( TARGET_COMMAND_REG,
+		      PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) ));
+
+	/* assert RST */
+	NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST );
+
+	/* The min. reset hold time is 25us, so 40us should be enough */
+	udelay( 50 );
+
+	/* reset RST and interrupt */
+	NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE );
+	NCR5380_read( RESET_PARITY_INTERRUPT_REG );
+
+	for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); )
+		barrier();
+
+	/* switch on SCSI IRQ again */
+//       	sun3_enable_irq( IRQ_SUN3_SCSI );
+
+	printk( " done\n" );
+}
+#endif
+
+static const char * sun3scsi_info (struct Scsi_Host *spnt) {
+    return "";
+}
+
+// safe bits for the CSR
+#define CSR_GOOD 0x060f
+
+static void scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp)
+{
+	unsigned short csr = dregs->csr;
+
+	dregs->csr &= ~CSR_DMA_ENABLE;
+
+
+#ifdef SUN3_SCSI_DEBUG
+	printk("scsi_intr csr %x\n", csr);
+#endif
+
+	if(csr & ~CSR_GOOD) {
+		if(csr & CSR_DMA_BUSERR) {
+			printk("scsi%d: bus error in dma\n", default_instance->host_no);
+#ifdef SUN3_SCSI_DEBUG
+			printk("scsi: residual %x count %x addr %p dmaaddr %x\n", 
+			       dregs->fifo_count,
+			       dregs->dma_count_lo | (dregs->dma_count_hi << 16),
+			       sun3_dma_orig_addr,
+			       dregs->dma_addr_lo | (dregs->dma_addr_hi << 16));
+#endif
+		}
+
+		if(csr & CSR_DMA_CONFLICT) {
+			printk("scsi%d: dma conflict\n", default_instance->host_no);
+		}
+	}
+
+	if(csr & (CSR_SDB_INT | CSR_DMA_INT))
+		NCR5380_intr(irq, dummy, fp);
+}
+
+/*
+ * Debug stuff - to be called on NMI, or sysrq key. Use at your own risk; 
+ * reentering NCR5380_print_status seems to have ugly side effects
+ */
+
+/* this doesn't seem to get used at all -- sam */
+#if 0
+void sun3_sun3_debug (void)
+{
+	unsigned long flags;
+	NCR5380_local_declare();
+
+	if (default_instance) {
+			save_flags(flags);
+			cli();
+			NCR5380_print_status(default_instance);
+			restore_flags(flags);
+	}
+}
+#endif
+
+
+/* sun3scsi_dma_setup() -- initialize the dma controller for a read/write */
+static unsigned long sun3scsi_dma_setup(void *data, unsigned long count, int write_flag)
+{
+	void *addr;
+
+	if(sun3_dma_orig_addr != NULL)
+		dvma_unmap(sun3_dma_orig_addr);
+
+//	addr = sun3_dvma_page((unsigned long)data, (unsigned long)dmabuf);
+	addr = (void *)dvma_map_vme((unsigned long) data, count);
+		
+	sun3_dma_orig_addr = addr;
+	sun3_dma_orig_count = count;
+	
+#ifdef SUN3_SCSI_DEBUG
+	printk("scsi: dma_setup addr %p count %x\n", addr, count);
+#endif
+
+//	dregs->fifo_count = 0;
+#if 0	
+	/* reset fifo */
+	dregs->csr &= ~CSR_FIFO;
+	dregs->csr |= CSR_FIFO;
+#endif	
+	/* set direction */
+	if(write_flag)
+		dregs->csr |= CSR_SEND;
+	else
+		dregs->csr &= ~CSR_SEND;
+	
+	/* reset fifo */
+//	dregs->csr &= ~CSR_FIFO;
+//	dregs->csr |= CSR_FIFO;
+
+	dregs->csr |= CSR_PACK_ENABLE;
+
+	dregs->dma_addr_hi = ((unsigned long)addr >> 16);
+	dregs->dma_addr_lo = ((unsigned long)addr & 0xffff);
+	
+	dregs->dma_count_hi = 0;
+	dregs->dma_count_lo = 0;
+	dregs->fifo_count_hi = 0;
+	dregs->fifo_count = 0;
+		
+#ifdef SUN3_SCSI_DEBUG
+	printk("scsi: dma_setup done csr %x\n", dregs->csr);
+#endif
+       	return count;
+
+}
+
+static inline unsigned long sun3scsi_dma_residual(struct Scsi_Host *instance)
+{
+	return last_residual;
+}
+
+static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, Scsi_Cmnd *cmd,
+				    int write_flag)
+{
+	if(cmd->request->flags & REQ_CMD)
+ 		return wanted;
+	else
+		return 0;
+}
+
+static int sun3scsi_dma_start(unsigned long count, char *data)
+{
+	
+	unsigned short csr;
+
+	csr = dregs->csr;
+#ifdef SUN3_SCSI_DEBUG
+	printk("scsi: dma_start data %p count %x csr %x fifo %x\n", data, count, csr, dregs->fifo_count);
+#endif
+	
+	dregs->dma_count_hi = (sun3_dma_orig_count >> 16);
+	dregs->dma_count_lo = (sun3_dma_orig_count & 0xffff);
+
+	dregs->fifo_count_hi = (sun3_dma_orig_count >> 16);
+	dregs->fifo_count = (sun3_dma_orig_count & 0xffff);
+
+//	if(!(csr & CSR_DMA_ENABLE))
+//		dregs->csr |= CSR_DMA_ENABLE;
+
+	return 0;
+}
+
+/* clean up after our dma is done */
+static int sun3scsi_dma_finish(int write_flag)
+{
+	unsigned short fifo;
+	int ret = 0;
+	
+	sun3_dma_active = 0;
+
+	dregs->csr &= ~CSR_DMA_ENABLE;
+	
+	fifo = dregs->fifo_count;
+	if(write_flag) {
+		if((fifo > 0) && (fifo < sun3_dma_orig_count))
+			fifo++;
+	}
+
+	last_residual = fifo;
+#ifdef SUN3_SCSI_DEBUG
+	printk("scsi: residual %x total %x\n", fifo, sun3_dma_orig_count);
+#endif
+	/* empty bytes from the fifo which didn't make it */
+	if((!write_flag) && (dregs->csr & CSR_LEFT)) {
+		unsigned char *vaddr;
+
+#ifdef SUN3_SCSI_DEBUG
+		printk("scsi: got left over bytes\n");
+#endif
+
+		vaddr = (unsigned char *)dvma_vmetov(sun3_dma_orig_addr);
+		
+		vaddr += (sun3_dma_orig_count - fifo);
+		vaddr--;
+		
+		switch(dregs->csr & CSR_LEFT) {
+		case CSR_LEFT_3:
+			*vaddr = (dregs->bpack_lo & 0xff00) >> 8;
+			vaddr--;
+			
+		case CSR_LEFT_2:
+			*vaddr = (dregs->bpack_hi & 0x00ff);
+			vaddr--;
+			
+		case CSR_LEFT_1:
+			*vaddr = (dregs->bpack_hi & 0xff00) >> 8;
+			break;
+		}
+		
+		
+	}
+
+	dvma_unmap(sun3_dma_orig_addr);
+	sun3_dma_orig_addr = NULL;
+
+	dregs->dma_addr_hi = 0;
+	dregs->dma_addr_lo = 0;
+	dregs->dma_count_hi = 0;
+	dregs->dma_count_lo = 0;
+
+	dregs->fifo_count = 0;
+	dregs->fifo_count_hi = 0;
+
+	dregs->csr &= ~CSR_SEND;
+	
+//	dregs->csr |= CSR_DMA_ENABLE;
+	
+#if 0
+	/* reset fifo */
+	dregs->csr &= ~CSR_FIFO;
+	dregs->csr |= CSR_FIFO;
+#endif	
+	sun3_dma_setup_done = NULL;
+
+	return ret;
+
+}
+
+#include "sun3_NCR5380.c"
+
+static Scsi_Host_Template driver_template = SUN3_NCR5380;
+
+#include "scsi_module.c"
+
diff -Nru a/drivers/scsi/sun3x_esp.c b/drivers/scsi/sun3x_esp.c
--- a/drivers/scsi/sun3x_esp.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/scsi/sun3x_esp.c	Mon Nov  4 14:31:02 2002
@@ -343,27 +343,28 @@
 static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp)
 {
     int sz = sp->SCp.buffers_residual;
-    struct mmu_sglist *sg = (struct mmu_sglist *) sp->SCp.buffer;
+    struct scatterlist *sg = sp->SCp.buffer;
 
     while (sz >= 0) {
-        sg[sz].dvma_addr = dvma_map((unsigned long)sg[sz].addr, sg[sz].len);
-        sz--;
+	    sg[sz].dvma_address = dvma_map((unsigned long)page_address(sg[sz].page) +
+					   sg[sz].offset, sg[sz].length);
+	    sz--;
     }
     sp->SCp.ptr=(char *)((unsigned long)sp->SCp.buffer->dvma_address);
 }
 
 static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp)
 {
-    dvma_unmap(sp->SCp.have_data_in);
+    dvma_unmap((char *)sp->SCp.have_data_in);
 }
 
 static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp)
 {
     int sz = sp->use_sg - 1;
-    struct mmu_sglist *sg = (struct mmu_sglist *)sp->buffer;
+    struct scatterlist *sg = (struct scatterlist *)sp->buffer;
                         
     while(sz >= 0) {
-        dvma_unmap(sg[sz].dvma_addr);
+        dvma_unmap((char *)sg[sz].dvma_address);
         sz--;
     }
 }
diff -Nru a/drivers/scsi/sym53c8xx.h b/drivers/scsi/sym53c8xx.h
--- a/drivers/scsi/sym53c8xx.h	Mon Nov  4 14:31:01 2002
+++ b/drivers/scsi/sym53c8xx.h	Mon Nov  4 14:31:01 2002
@@ -91,6 +91,8 @@
 			info:           sym53c8xx_info, 	\
 			queuecommand:   sym53c8xx_queue_command,\
 			slave_attach:   sym53c8xx_slave_attach, \
+			abort:          sym53c8xx_abort,	\
+			reset:          sym53c8xx_reset,	\
 			can_queue:      SCSI_NCR_CAN_QUEUE,	\
 			this_id:        7,			\
 			sg_tablesize:   SCSI_NCR_SG_TABLESIZE,	\
diff -Nru a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c
--- a/drivers/scsi/u14-34f.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/scsi/u14-34f.c	Mon Nov  4 14:31:01 2002
@@ -1,6 +1,15 @@
 /*
  *      u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters.
  *
+ *      28 Oct 2002 Rev. 8.00 for linux 2.5.44-ac4
+ *        + Use new tcq and adjust_queue_depth api.
+ *        + New command line option (tm:[0-2]) to choose the type of tags:
+ *          0 -> disable tagging ; 1 -> simple tags  ; 2 -> ordered tags.
+ *          Default is tm:0 (tagged commands disabled).
+ *          For compatibility the "tc:" option is an alias of the "tm:"
+ *          option; tc:n is equivalent to tm:0 and tc:y is equivalent to
+ *          tm:1.
+ *
  *      10 Oct 2002 Rev. 7.70 for linux 2.5.42
  *        + Foreport from revision 6.70.
  *
@@ -304,19 +313,22 @@
  *  et:n  use disk geometry jumpered on the board;
  *  lc:y  enables linked commands;
  *  lc:n  disables linked commands;
+ *  tm:0  disables tagged commands (same as tc:n);
+ *  tm:1  use simple queue tags (same as tc:y);
+ *  tm:2  use ordered queue tags (same as tc:2);
  *  of:y  enables old firmware support;
  *  of:n  disables old firmware support;
  *  mq:xx set the max queue depth to the value xx (2 <= xx <= 8).
  *
- *  The default value is: "u14-34f=lc:n,of:n,mq:8,et:n".
+ *  The default value is: "u14-34f=lc:n,of:n,mq:8,tm:0,et:n".
  *  An example using the list of detection probes could be:
- *  "u14-34f=0x230,0x340,lc:y,of:n,mq:4,et:n".
+ *  "u14-34f=0x230,0x340,lc:y,tm:2,of:n,mq:4,et:n".
  *
  *  When loading as a module, parameters can be specified as well.
  *  The above example would be (use 1 in place of y and 0 in place of n):
  *
  *  modprobe u14-34f io_port=0x230,0x340 linked_comm=1 have_old_firmware=0 \
- *                max_queue_depth=4 ext_tran=0
+ *                max_queue_depth=4 ext_tran=0 tag_mode=2
  *
  *  ----------------------------------------------------------------------------
  *  In this implementation, linked commands are designed to work with any DISK
@@ -374,6 +386,7 @@
 MODULE_PARM(have_old_firmware, "i");
 MODULE_PARM(link_statistics, "i");
 MODULE_PARM(max_queue_depth, "i");
+MODULE_PARM(tag_mode, "i");
 MODULE_PARM(ext_tran, "i");
 MODULE_AUTHOR("Dario Ballabio");
 
@@ -400,6 +413,7 @@
 #include <linux/init.h>
 #include <linux/ctype.h>
 #include <linux/spinlock.h>
+#include <scsi/scsicam.h>
 
 #if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD)
 #error "Adjust your <asm/byteorder.h> defines"
@@ -460,6 +474,9 @@
 #define ABORTING 6
 #define NO_DMA  0xff
 #define MAXLOOP  10000
+#define TAG_DISABLED 0
+#define TAG_SIMPLE   1
+#define TAG_ORDERED  2
 
 #define REG_LCL_MASK      0
 #define REG_LCL_INTR      1
@@ -593,6 +610,12 @@
 static int have_old_firmware = FALSE;
 #endif
 
+#if defined(CONFIG_SCSI_U14_34F_TAGGED_QUEUE)
+static int tag_mode = TAG_SIMPLE;
+#else
+static int tag_mode = TAG_DISABLED;
+#endif
+
 #if defined(CONFIG_SCSI_U14_34F_LINKED_COMMANDS)
 static int linked_comm = TRUE;
 #else
@@ -605,61 +628,56 @@
 static int max_queue_depth = MAX_CMD_PER_LUN;
 #endif
 
-static void select_queue_depths(struct Scsi_Host *host, Scsi_Device *devlist) {
-   Scsi_Device *dev;
-   int j, ntag = 0, nuntag = 0, tqd, utqd;
+static int u14_34f_slave_attach(Scsi_Device *dev) {
+   int j, tqd, utqd;
+   char *tag_suffix, *link_suffix;
+   struct Scsi_Host *host = dev->host;
 
    j = ((struct hostdata *) host->hostdata)->board_number;
 
-   for(dev = devlist; dev; dev = dev->next) {
-
-      if (dev->host != host) continue;
-
-      if (TLDEV(dev->type) && (dev->tagged_supported || linked_comm))
-         ntag++;
-      else
-         nuntag++;
-      }
-
    utqd = MAX_CMD_PER_LUN;
+   tqd = max_queue_depth;
 
-   tqd = (host->can_queue - utqd * nuntag) / (ntag ? ntag : 1);
+   if (TLDEV(dev->type) && dev->tagged_supported)
 
-   if (tqd > max_queue_depth) tqd = max_queue_depth;
-
-   if (tqd < MAX_CMD_PER_LUN) tqd = MAX_CMD_PER_LUN;
-
-   for(dev = devlist; dev; dev = dev->next) {
-      char *tag_suffix = "", *link_suffix = "";
-
-      if (dev->host != host) continue;
-
-      if (TLDEV(dev->type) && (dev->tagged_supported || linked_comm))
-         dev->queue_depth = tqd;
-      else
-         dev->queue_depth = utqd;
-
-      if (TLDEV(dev->type)) {
-         if (linked_comm && dev->queue_depth > 2)
-            link_suffix = ", sorted";
-         else
-            link_suffix = ", unsorted";
+      if (tag_mode == TAG_SIMPLE) {
+         scsi_adjust_queue_depth(dev, MSG_SIMPLE_TAG, tqd);
+         tag_suffix = ", simple tags";
+         }
+      else if (tag_mode == TAG_ORDERED) {
+         scsi_adjust_queue_depth(dev, MSG_ORDERED_TAG, tqd);
+         tag_suffix = ", ordered tags";
+         }
+      else {
+         scsi_adjust_queue_depth(dev, 0, tqd);
+         tag_suffix = ", no tags";
          }
 
-      if (dev->tagged_supported && TLDEV(dev->type) && dev->tagged_queue)
-         tag_suffix = ", soft-tagged";
-      else if (dev->tagged_supported && TLDEV(dev->type))
-         tag_suffix = ", tagged";
-
-      printk("%s: scsi%d, channel %d, id %d, lun %d, cmds/lun %d%s%s.\n",
-             BN(j), host->host_no, dev->channel, dev->id, dev->lun,
-             dev->queue_depth, link_suffix, tag_suffix);
+   else if (TLDEV(dev->type) && linked_comm) {
+      scsi_adjust_queue_depth(dev, 0, tqd);
+      tag_suffix = ", untagged";
       }
 
-   return;
+   else {
+      scsi_adjust_queue_depth(dev, 0, utqd);
+      tag_suffix = "";
+      }
+
+   if (TLDEV(dev->type) && linked_comm && dev->new_queue_depth > 2)
+      link_suffix = ", sorted";
+   else if (TLDEV(dev->type))
+      link_suffix = ", unsorted";
+   else
+      link_suffix = "";
+
+   printk("%s: scsi%d, channel %d, id %d, lun %d, cmds/lun %d%s%s.\n",
+          BN(j), host->host_no, dev->channel, dev->id, dev->lun,
+          dev->new_queue_depth, link_suffix, tag_suffix);
+
+   return FALSE;
 }
 
-static inline int wait_on_busy(unsigned long iobase, unsigned int loop) {
+static int wait_on_busy(unsigned long iobase, unsigned int loop) {
 
    while (inb(iobase + REG_LCL_INTR) & BSY_ASSERTED) {
       udelay(1L);
@@ -721,7 +739,7 @@
    return FALSE;
 }
 
-static inline int port_detect \
+static int port_detect \
       (unsigned long port_base, unsigned int j, Scsi_Host_Template *tpnt) {
    unsigned char irq, dma_channel, subversion, i;
    unsigned char in_byte;
@@ -843,7 +861,6 @@
    sh[j]->this_id = config_2.ha_scsi_id;
    sh[j]->can_queue = MAX_MAILBOXES;
    sh[j]->cmd_per_lun = MAX_CMD_PER_LUN;
-   sh[j]->select_queue_depths = select_queue_depths;
 
 #if defined(DEBUG_DETECT)
    {
@@ -930,11 +947,14 @@
 
    if (max_queue_depth < MAX_CMD_PER_LUN) max_queue_depth = MAX_CMD_PER_LUN;
 
+   if (tag_mode != TAG_DISABLED && tag_mode != TAG_SIMPLE)
+      tag_mode = TAG_ORDERED;
+
    if (j == 0) {
       printk("UltraStor 14F/34F: Copyright (C) 1994-2002 Dario Ballabio.\n");
-      printk("%s config options -> of:%c, lc:%c, mq:%d, et:%c.\n",
-             driver_name, YESNO(have_old_firmware), YESNO(linked_comm),
-             max_queue_depth, YESNO(ext_tran));
+      printk("%s config options -> of:%c, tm:%d, lc:%c, mq:%d, et:%c.\n",
+             driver_name, YESNO(have_old_firmware), tag_mode,
+             YESNO(linked_comm), max_queue_depth, YESNO(ext_tran));
       }
 
    printk("%s: %s 0x%03lx, BIOS 0x%05x, IRQ %u, %s, SG %d, MB %d.\n",
@@ -975,6 +995,8 @@
 
       if (!strncmp(cur, "lc:", 3)) linked_comm = val;
       else if (!strncmp(cur, "of:", 3)) have_old_firmware = val;
+      else if (!strncmp(cur, "tm:", 3)) tag_mode = val;
+      else if (!strncmp(cur, "tc:", 3)) tag_mode = val;
       else if (!strncmp(cur, "mq:", 3))  max_queue_depth = val;
       else if (!strncmp(cur, "ls:", 3))  link_statistics = val;
       else if (!strncmp(cur, "et:", 3))  ext_tran = val;
@@ -1001,7 +1023,7 @@
    return 1;
 }
 
-int u14_34f_detect(Scsi_Host_Template *tpnt) {
+static int u14_34f_detect(Scsi_Host_Template *tpnt) {
    unsigned int j = 0, k;
    unsigned long spin_flags;
 
@@ -1033,7 +1055,7 @@
    return j;
 }
 
-static inline void map_dma(unsigned int i, unsigned int j) {
+static void map_dma(unsigned int i, unsigned int j) {
    unsigned int data_len = 0;
    unsigned int k, count, pci_dir;
    struct scatterlist *sgpnt;
@@ -1123,7 +1145,7 @@
                        DEV2H(cpp->data_len), pci_dir);
 }
 
-static inline void scsi_to_dev_dir(unsigned int i, unsigned int j) {
+static void scsi_to_dev_dir(unsigned int i, unsigned int j) {
    unsigned int k;
 
    static const unsigned char data_out_cmds[] = {
@@ -1176,7 +1198,7 @@
 
 }
 
-static inline int do_qcomm(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
+static int u14_34f_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
    unsigned int i, j, k;
    struct mscp *cpp;
 
@@ -1232,7 +1254,7 @@
    /* Map DMA buffers and SG list */
    map_dma(i, j);
 
-   if (linked_comm && SCpnt->device->queue_depth > 2
+   if (linked_comm && SCpnt->device->new_queue_depth > 2
                                      && TLDEV(SCpnt->device->type)) {
       HD(j)->cp_stat[i] = READY;
       flush_dev(SCpnt->device, SCpnt->request->sector, j, FALSE);
@@ -1257,14 +1279,7 @@
    return 0;
 }
 
-int u14_34f_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
-   int rtn;
-
-   rtn = do_qcomm(SCpnt, done);
-   return rtn;
-}
-
-static inline int do_abort(Scsi_Cmnd *SCarg) {
+static int u14_34f_eh_abort(Scsi_Cmnd *SCarg) {
    unsigned int i, j;
 
    j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
@@ -1338,12 +1353,7 @@
    panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i);
 }
 
-int u14_34f_abort(Scsi_Cmnd *SCarg) {
-
-   return do_abort(SCarg);
-}
-
-static inline int do_reset(Scsi_Cmnd *SCarg) {
+static int u14_34f_eh_host_reset(Scsi_Cmnd *SCarg) {
    unsigned int i, j, time, k, c, limit = 0;
    int arg_done = FALSE;
    Scsi_Cmnd *SCpnt;
@@ -1476,28 +1486,23 @@
    return SUCCESS;
 }
 
-int u14_34f_reset(Scsi_Cmnd *SCarg) {
-
-   return do_reset(SCarg);
-}
-
-int u14_34f_biosparam(struct scsi_device *sdev, struct block_device *bdev,
-		sector_t capacity, int *dkinfo) {
+static int u14_34f_bios_param(Disk *disk, struct block_device *bdev,
+                                                          int *dkinfo) {
    unsigned int j = 0;
-   int size = capacity;
+   int size = disk->capacity;
 
    dkinfo[0] = HD(j)->heads;
    dkinfo[1] = HD(j)->sectors;
    dkinfo[2] = size / (HD(j)->heads * HD(j)->sectors);
 
-   if (ext_tran && (scsicam_bios_param(bdev, capacity, dkinfo) < 0)) {
+   if (ext_tran && (scsicam_bios_param(disk, bdev, dkinfo) < 0)) {
       dkinfo[0] = 255;
       dkinfo[1] = 63;
       dkinfo[2] = size / (dkinfo[0] * dkinfo[1]);
       }
 
 #if defined (DEBUG_GEOMETRY)
-   printk ("%s: biosparam, head=%d, sec=%d, cyl=%d.\n", driver_name,
+   printk ("%s: bios_param, head=%d, sec=%d, cyl=%d.\n", driver_name,
            dkinfo[0], dkinfo[1], dkinfo[2]);
 #endif
 
@@ -1529,7 +1534,7 @@
    return;
    }
 
-static inline int reorder(unsigned int j, unsigned long cursec,
+static int reorder(unsigned int j, unsigned long cursec,
                  unsigned int ihdlr, unsigned int il[], unsigned int n_ready) {
    Scsi_Cmnd *SCpnt;
    struct mscp *cpp;
@@ -1666,7 +1671,7 @@
 
 }
 
-static inline void ihdlr(int irq, unsigned int j) {
+static void ihdlr(int irq, unsigned int j) {
    Scsi_Cmnd *SCpnt;
    unsigned int i, k, c, status, tstatus, reg, ret;
    struct mscp *spp, *cpp;
@@ -1746,7 +1751,7 @@
 
    sync_dma(i, j);
 
-   if (linked_comm && SCpnt->device->queue_depth > 2
+   if (linked_comm && SCpnt->device->new_queue_depth > 2
                                      && TLDEV(SCpnt->device->type))
       flush_dev(SCpnt->device, SCpnt->request->sector, j, TRUE);
 
@@ -1888,7 +1893,7 @@
    spin_unlock_irqrestore(sh[j]->host_lock, spin_flags);
 }
 
-int u14_34f_release(struct Scsi_Host *shpnt) {
+static int u14_34f_release(struct Scsi_Host *shpnt) {
    unsigned int i, j;
 
    for (j = 0; sh[j] != NULL && sh[j] != shpnt; j++);
diff -Nru a/drivers/scsi/u14-34f.h b/drivers/scsi/u14-34f.h
--- a/drivers/scsi/u14-34f.h	Mon Nov  4 14:31:02 2002
+++ b/drivers/scsi/u14-34f.h	Mon Nov  4 14:31:02 2002
@@ -1,20 +1,16 @@
 /*
  *   u14-34f.h - used by the low-level driver for UltraStor 14F/34F
  */
-#ifndef _U14_34F_H
-#define _U14_34F_H
 
-#include <scsi/scsicam.h>
+static int u14_34f_detect(Scsi_Host_Template *);
+static int u14_34f_release(struct Scsi_Host *);
+static int u14_34f_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int u14_34f_eh_abort(Scsi_Cmnd *);
+static int u14_34f_eh_host_reset(Scsi_Cmnd *);
+static int u14_34f_bios_param(Disk *, struct block_device *, int *);
+static int u14_34f_slave_attach(Scsi_Device *);
 
-int u14_34f_detect(Scsi_Host_Template *);
-int u14_34f_release(struct Scsi_Host *);
-int u14_34f_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int u14_34f_abort(Scsi_Cmnd *);
-int u14_34f_reset(Scsi_Cmnd *);
-int u14_34f_biosparam(struct scsi_device *, struct block_device *,
-		sector_t, int *);
-
-#define U14_34F_VERSION "7.70.00"
+#define U14_34F_VERSION "8.00.00"
 
 #define ULTRASTOR_14_34F {                                                   \
                 name:         "UltraStor 14F/34F rev. " U14_34F_VERSION " ", \
@@ -23,14 +19,13 @@
                 queuecommand:            u14_34f_queuecommand,               \
                 abort:                   NULL,                               \
                 reset:                   NULL,                               \
-                eh_abort_handler:        u14_34f_abort,                      \
+                eh_abort_handler:        u14_34f_eh_abort,                   \
                 eh_device_reset_handler: NULL,                               \
                 eh_bus_reset_handler:    NULL,                               \
-                eh_host_reset_handler:   u14_34f_reset,                      \
-                bios_param:              u14_34f_biosparam,                  \
+                eh_host_reset_handler:   u14_34f_eh_host_reset,              \
+                bios_param:              u14_34f_bios_param,                 \
+                slave_attach:            u14_34f_slave_attach,               \
                 this_id:                 7,                                  \
                 unchecked_isa_dma:       1,                                  \
-                use_clustering:          ENABLE_CLUSTERING,                  \
+                use_clustering:          ENABLE_CLUSTERING                   \
                 }
-
-#endif
diff -Nru a/drivers/serial/21285.c b/drivers/serial/21285.c
--- a/drivers/serial/21285.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/serial/21285.c	Mon Nov  4 14:31:02 2002
@@ -171,7 +171,7 @@
 	} while (--count > 0 && !(*CSR_UARTFLG & 0x20));
 
 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-		uart_event(port, EVT_WRITE_WAKEUP);
+		uart_write_wakeup(port);
 
 	if (uart_circ_empty(xmit))
 		serial21285_stop_tx(port, 0);
@@ -485,11 +485,7 @@
 static struct uart_driver serial21285_reg = {
 	.owner			= THIS_MODULE,
 	.driver_name		= "ttyFB",
-#ifdef CONFIG_DEVFS_FS
 	.dev_name		= "ttyFB%d",
-#else
-	.dev_name		= "ttyFB",
-#endif
 	.major			= SERIAL_21285_MAJOR,
 	.minor			= SERIAL_21285_MINOR,
 	.nr			= 1,
diff -Nru a/drivers/serial/8250.c b/drivers/serial/8250.c
--- a/drivers/serial/8250.c	Mon Nov  4 14:31:00 2002
+++ b/drivers/serial/8250.c	Mon Nov  4 14:31:00 2002
@@ -124,6 +124,8 @@
 	unsigned char		ier;
 	unsigned char		rev;
 	unsigned char		lcr;
+	unsigned char		mcr_mask;	/* mask of user bits */
+	unsigned char		mcr_force;	/* mask of forced bits */
 	unsigned int		lsr_break_flag;
 
 	/*
@@ -342,10 +344,9 @@
  * 
  * What evil have men's minds wrought...
  */
-static void
-autoconfig_startech_uarts(struct uart_8250_port *up)
+static void autoconfig_has_efr(struct uart_8250_port *up)
 {
-	unsigned char scratch, scratch2, scratch3, scratch4;
+	unsigned char id1, id2, id3, rev, saved_dll, saved_dlm;
 
 	/*
 	 * First we check to see if it's an Oxford Semiconductor UART.
@@ -354,31 +355,32 @@
 	 * Semiconductor clone chips lock up if you try writing to the
 	 * LSR register (which serial_icr_read does)
 	 */
-	if (up->port.type == PORT_16550A) {
-		/*
-		 * EFR [4] must be set else this test fails
-		 *
-		 * This shouldn't be necessary, but Mike Hudson
-		 * (Exoray@isys.ca) claims that it's needed for 952
-		 * dual UART's (which are not recommended for new designs).
-		 */
-		up->acr = 0;
-		serial_out(up, UART_LCR, 0xBF);
-		serial_out(up, UART_EFR, 0x10);
-		serial_out(up, UART_LCR, 0x00);
-		/* Check for Oxford Semiconductor 16C950 */
-		scratch = serial_icr_read(up, UART_ID1);
-		scratch2 = serial_icr_read(up, UART_ID2);
-		scratch3 = serial_icr_read(up, UART_ID3);
-		
-		if (scratch == 0x16 && scratch2 == 0xC9 &&
-		    (scratch3 == 0x50 || scratch3 == 0x52 ||
-		     scratch3 == 0x54)) {
-			up->port.type = PORT_16C950;
-			up->rev = serial_icr_read(up, UART_REV) |
-						  (scratch3 << 8);
-			return;
-		}
+
+	/*
+	 * Check for Oxford Semiconductor 16C950.
+	 *
+	 * EFR [4] must be set else this test fails.
+	 *
+	 * This shouldn't be necessary, but Mike Hudson (Exoray@isys.ca)
+	 * claims that it's needed for 952 dual UART's (which are not
+	 * recommended for new designs).
+	 */
+	up->acr = 0;
+	serial_out(up, UART_LCR, 0xBF);
+	serial_out(up, UART_EFR, UART_EFR_ECB);
+	serial_out(up, UART_LCR, 0x00);
+	id1 = serial_icr_read(up, UART_ID1);
+	id2 = serial_icr_read(up, UART_ID2);
+	id3 = serial_icr_read(up, UART_ID3);
+	rev = serial_icr_read(up, UART_REV);
+
+	DEBUG_AUTOCONF("950id=%02x:%02x:%02x:%02x ", id1, id2, id3, rev);
+
+	if (id1 == 0x16 && id2 == 0xC9 &&
+	    (id3 == 0x50 || id3 == 0x52 || id3 == 0x54)) {
+		up->port.type = PORT_16C950;
+		up->rev = rev | (id3 << 8);
+		return;
 	}
 	
 	/*
@@ -389,34 +391,28 @@
 	 *  0x12 - XR16C2850.
 	 *  0x14 - XR16C854.
 	 */
-
-	/* Save the DLL and DLM */
-
 	serial_outp(up, UART_LCR, UART_LCR_DLAB);
-	scratch3 = serial_inp(up, UART_DLL);
-	scratch4 = serial_inp(up, UART_DLM);
-
+	saved_dll = serial_inp(up, UART_DLL);
+	saved_dlm = serial_inp(up, UART_DLM);
 	serial_outp(up, UART_DLL, 0);
 	serial_outp(up, UART_DLM, 0);
-	scratch2 = serial_inp(up, UART_DLL);
-	scratch = serial_inp(up, UART_DLM);
-	serial_outp(up, UART_LCR, 0);
-
-	if (scratch == 0x10 || scratch == 0x12 || scratch == 0x14) {
-		if (scratch == 0x10)
-			up->rev = scratch2;
+	id2 = serial_inp(up, UART_DLL);
+	id1 = serial_inp(up, UART_DLM);
+	serial_outp(up, UART_DLL, saved_dll);
+	serial_outp(up, UART_DLM, saved_dlm);
+
+	DEBUG_AUTOCONF("850id=%02x:%02x ", id1, id2);
+
+	if (id1 == 0x10 || id1 == 0x12 || id1 == 0x14) {
+		if (id1 == 0x10)
+			up->rev = id2;
 		up->port.type = PORT_16850;
 		return;
 	}
 
-	/* Restore the DLL and DLM */
-
-	serial_outp(up, UART_LCR, UART_LCR_DLAB);
-	serial_outp(up, UART_DLL, scratch3);
-	serial_outp(up, UART_DLM, scratch4);
-	serial_outp(up, UART_LCR, 0);
-
 	/*
+	 * It wasn't an XR16C850.
+	 *
 	 * We distinguish between the '654 and the '650 by counting
 	 * how many bytes are in the FIFO.  I'm using this for now,
 	 * since that's the technique that was sent to me in the
@@ -430,6 +426,85 @@
 }
 
 /*
+ * We detected a chip without a FIFO.  Only two fall into
+ * this category - the original 8250 and the 16450.  The
+ * 16450 has a scratch register (accessible with LCR=0)
+ */
+static void autoconfig_8250(struct uart_8250_port *up)
+{
+	unsigned char scratch, status1, status2;
+
+	up->port.type = PORT_8250;
+
+	scratch = serial_in(up, UART_SCR);
+	serial_outp(up, UART_SCR, 0xa5);
+	status1 = serial_in(up, UART_SCR);
+	serial_outp(up, UART_SCR, 0x5a);
+	status2 = serial_in(up, UART_SCR);
+	serial_outp(up, UART_SCR, scratch);
+
+	if (status1 == 0xa5 && status2 == 0x5a)
+		up->port.type = PORT_16450;
+}
+
+/*
+ * We know that the chip has FIFOs.  Does it have an EFR?  The
+ * EFR is located in the same register position as the IIR and
+ * we know the top two bits of the IIR are currently set.  The
+ * EFR should contain zero.  Try to read the EFR.
+ */
+static void autoconfig_16550a(struct uart_8250_port *up)
+{
+	unsigned char status1, status2;
+
+	up->port.type = PORT_16550A;
+
+	/*
+	 * Check for presence of the EFR when DLAB is set.
+	 * Only ST16C650V1 UARTs pass this test.
+	 */
+	serial_outp(up, UART_LCR, UART_LCR_DLAB);
+	if (serial_in(up, UART_EFR) == 0) {
+		DEBUG_AUTOCONF("EFRv1 ");
+		up->port.type = PORT_16650;
+		return;
+	}
+
+	/*
+	 * Maybe it requires 0xbf to be written to the LCR.
+	 * (other ST16C650V2 UARTs, TI16C752A, etc)
+	 */
+	serial_outp(up, UART_LCR, 0xBF);
+	if (serial_in(up, UART_EFR) == 0) {
+		DEBUG_AUTOCONF("EFRv2 ");
+		autoconfig_has_efr(up);
+		return;
+	}
+
+	/*
+	 * No EFR.  Try to detect a TI16750, which only sets bit 5 of
+	 * the IIR when 64 byte FIFO mode is enabled when DLAB is set.
+	 * Try setting it with and without DLAB set.  Cheap clones
+	 * set bit 5 without DLAB set.
+	 */
+	serial_outp(up, UART_LCR, 0);
+	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
+	status1 = serial_in(up, UART_IIR) >> 5;
+	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+	serial_outp(up, UART_LCR, UART_LCR_DLAB);
+	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
+	status2 = serial_in(up, UART_IIR) >> 5;
+	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+
+	DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2);
+
+	if (status1 == 6 && status2 == 7) {
+		up->port.type = PORT_16750;
+		return;
+	}
+}
+
+/*
  * This routine is called by rs_init() to initialize a specific serial
  * port.  It determines what type of UART chip this serial port is
  * using: 8250, 16450, 16550, 16550A.  The important question is
@@ -438,16 +513,16 @@
  */
 static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
 {
-	unsigned char status1, status2, scratch, scratch2, scratch3;
+	unsigned char status1, scratch, scratch2, scratch3;
 	unsigned char save_lcr, save_mcr;
 	unsigned long flags;
 
-	DEBUG_AUTOCONF("Testing ttyS%d (0x%04x, 0x%08lx)...\n",
-			up->port.line, up->port.iobase, up->port.membase);
-
 	if (!up->port.iobase && !up->port.membase)
 		return;
 
+	DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04x, 0x%08lx): ",
+			up->port.line, up->port.iobase, up->port.membase);
+
 	/*
 	 * We really do need global IRQs disabled here - we're going to
 	 * be frobbing the chips IRQ enable register to see if it exists.
@@ -455,7 +530,7 @@
 	spin_lock_irqsave(&up->port.lock, flags);
 //	save_flags(flags); cli();
 
-	if (!(up->port.flags & ASYNC_BUGGY_UART)) {
+	if (!(up->port.flags & UPF_BUGGY_UART)) {
 		/*
 		 * Do a simple existence test first; if we fail this,
 		 * there's no point trying anything else.
@@ -465,6 +540,9 @@
 		 * assumption is that 0x80 is a non-existent port;
 		 * which should be safe since include/asm/io.h also
 		 * makes this assumption.
+		 *
+		 * Note: this is safe as long as MCR bit 4 is clear
+		 * and the device is in "PC" mode.
 		 */
 		scratch = serial_inp(up, UART_IER);
 		serial_outp(up, UART_IER, 0);
@@ -482,9 +560,8 @@
 			/*
 			 * We failed; there's nothing here
 			 */
-			DEBUG_AUTOCONF("serial: ttyS%d: simple autoconfig "
-				       "failed (%02x, %02x)\n",
-				       up->port.line, scratch2, scratch3);
+			DEBUG_AUTOCONF("IER test failed (%02x, %02x) ",
+				       scratch2, scratch3);
 			goto out;
 		}
 	}
@@ -501,69 +578,50 @@
 	 * manufacturer would be stupid enough to design a board
 	 * that conflicts with COM 1-4 --- we hope!
 	 */
-	if (!(up->port.flags & ASYNC_SKIP_TEST)) {
+	if (!(up->port.flags & UPF_SKIP_TEST)) {
 		serial_outp(up, UART_MCR, UART_MCR_LOOP | 0x0A);
 		status1 = serial_inp(up, UART_MSR) & 0xF0;
 		serial_outp(up, UART_MCR, save_mcr);
 		if (status1 != 0x90) {
-			DEBUG_AUTOCONF("serial: ttyS%d: no UART loopback "
-				       "failed\n", up->port.line);
+			DEBUG_AUTOCONF("LOOP test failed (%02x) ",
+				       status1);
 			goto out;
 		}
 	}
-	serial_outp(up, UART_LCR, 0xBF); /* set up for StarTech test */
-	serial_outp(up, UART_EFR, 0);	/* EFR is the same as FCR */
+
+	/*
+	 * We're pretty sure there's a port here.  Lets find out what
+	 * type of port it is.  The IIR top two bits allows us to find
+	 * out if its 8250 or 16450, 16550, 16550A or later.  This
+	 * determines what we test for next.
+	 *
+	 * We also initialise the EFR (if any) to zero for later.  The
+	 * EFR occupies the same register location as the FCR and IIR.
+	 */
+	serial_outp(up, UART_LCR, 0xBF);
+	serial_outp(up, UART_EFR, 0);
 	serial_outp(up, UART_LCR, 0);
+
 	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
 	scratch = serial_in(up, UART_IIR) >> 6;
+
+	DEBUG_AUTOCONF("iir=%d ", scratch);
+
 	switch (scratch) {
-		case 0:
-			up->port.type = PORT_16450;
-			break;
-		case 1:
-			up->port.type = PORT_UNKNOWN;
-			break;
-		case 2:
-			up->port.type = PORT_16550;
-			break;
-		case 3:
-			up->port.type = PORT_16550A;
-			break;
-	}
-	if (up->port.type == PORT_16550A) {
-		/* Check for Startech UART's */
-		serial_outp(up, UART_LCR, UART_LCR_DLAB);
-		if (serial_in(up, UART_EFR) == 0) {
-			up->port.type = PORT_16650;
-		} else {
-			serial_outp(up, UART_LCR, 0xBF);
-			if (serial_in(up, UART_EFR) == 0)
-				autoconfig_startech_uarts(up);
-		}
-	}
-	if (up->port.type == PORT_16550A) {
-		/* Check for TI 16750 */
-		serial_outp(up, UART_LCR, save_lcr | UART_LCR_DLAB);
-		serial_outp(up, UART_FCR,
-			    UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
-		scratch = serial_in(up, UART_IIR) >> 5;
-		if (scratch == 7) {
-			/*
-			 * If this is a 16750, and not a cheap UART
-			 * clone, then it should only go into 64 byte
-			 * mode if the UART_FCR7_64BYTE bit was set
-			 * while UART_LCR_DLAB was latched.
-			 */
- 			serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
-			serial_outp(up, UART_LCR, 0);
-			serial_outp(up, UART_FCR,
-				    UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
-			scratch = serial_in(up, UART_IIR) >> 5;
-			if (scratch == 6)
-				up->port.type = PORT_16750;
-		}
-		serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+	case 0:
+		autoconfig_8250(up);
+		break;
+	case 1:
+		up->port.type = PORT_UNKNOWN;
+		break;
+	case 2:
+		up->port.type = PORT_16550;
+		break;
+	case 3:
+		autoconfig_16550a(up);
+		break;
 	}
+
 #if defined(CONFIG_SERIAL_8250_RSA) && defined(MODULE)
 	/*
 	 * Only probe for RSA ports if we got the region.
@@ -586,17 +644,6 @@
 	}
 #endif
 	serial_outp(up, UART_LCR, save_lcr);
-	if (up->port.type == PORT_16450) {
-		scratch = serial_in(up, UART_SCR);
-		serial_outp(up, UART_SCR, 0xa5);
-		status1 = serial_in(up, UART_SCR);
-		serial_outp(up, UART_SCR, 0x5a);
-		status2 = serial_in(up, UART_SCR);
-		serial_outp(up, UART_SCR, scratch);
-
-		if ((status1 != 0xa5) || (status2 != 0x5a))
-			up->port.type = PORT_8250;
-	}
 
 	up->port.fifosize = uart_config[up->port.type].dfl_xmit_fifo_size;
 
@@ -628,6 +675,7 @@
 			       "serial_rsa");
 	}
 #endif
+	DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name);
 }
 
 static void autoconfig_irq(struct uart_8250_port *up)
@@ -638,7 +686,7 @@
 	unsigned long irqs;
 	int irq;
 
-	if (up->port.flags & ASYNC_FOURPORT) {
+	if (up->port.flags & UPF_FOURPORT) {
 		ICP = (up->port.iobase & 0xfe0) | 0x1f;
 		save_ICP = inb_p(ICP);
 		outb_p(0x80, ICP);
@@ -654,7 +702,7 @@
 	irqs = probe_irq_on();
 	serial_outp(up, UART_MCR, 0);
 	udelay (10);
-	if (up->port.flags & ASYNC_FOURPORT)  {
+	if (up->port.flags & UPF_FOURPORT)  {
 		serial_outp(up, UART_MCR,
 			    UART_MCR_DTR | UART_MCR_RTS);
 	} else {
@@ -673,7 +721,7 @@
 	serial_outp(up, UART_MCR, save_mcr);
 	serial_outp(up, UART_IER, save_ier);
 
-	if (up->port.flags & ASYNC_FOURPORT)
+	if (up->port.flags & UPF_FOURPORT)
 		outb_p(save_ICP, ICP);
 
 	up->port.irq = (irq > 0) ? irq : 0;
@@ -839,7 +887,7 @@
 	} while (--count > 0);
 
 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-		uart_event(&up->port, EVT_WRITE_WAKEUP);
+		uart_write_wakeup(&up->port);
 
 	DEBUG_INTR("THRE...");
 
@@ -948,10 +996,26 @@
  * line being stuck active, and, since ISA irqs are edge triggered,
  * no more IRQs will be seen.
  */
+static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up)
+{
+	spin_lock_irq(&i->lock);
+
+	if (!list_empty(i->head)) {
+		if (i->head == &up->list)
+			i->head = i->head->next;
+		list_del(&up->list);
+	} else {
+		BUG_ON(i->head != &up->list);
+		i->head = NULL;
+	}
+
+	spin_unlock_irq(&i->lock);
+}
+
 static int serial_link_irq_chain(struct uart_8250_port *up)
 {
 	struct irq_info *i = irq_lists + up->port.irq;
-	int ret, irq_flags = share_irqs ? SA_SHIRQ : 0;
+	int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? SA_SHIRQ : 0;
 
 	spin_lock_irq(&i->lock);
 
@@ -967,6 +1031,8 @@
 
 		ret = request_irq(up->port.irq, serial8250_interrupt,
 				  irq_flags, "serial", i);
+		if (ret)
+			serial_do_unlink(i, up);
 	}
 
 	return ret;
@@ -981,18 +1047,7 @@
 	if (list_empty(i->head))
 		free_irq(up->port.irq, i);
 
-	spin_lock_irq(&i->lock);
-
-	if (!list_empty(i->head)) {
-		if (i->head == &up->list)
-			i->head = i->head->next;
-		list_del(&up->list);
-	} else {
-		BUG_ON(i->head != &up->list);
-		i->head = NULL;
-	}
-
-	spin_unlock_irq(&i->lock);
+	serial_do_unlink(i, up);
 }
 
 /*
@@ -1058,7 +1113,7 @@
 static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
 {
 	struct uart_8250_port *up = (struct uart_8250_port *)port;
-	unsigned char mcr = ALPHA_KLUDGE_MCR;
+	unsigned char mcr = 0;
 
 	if (mctrl & TIOCM_RTS)
 		mcr |= UART_MCR_RTS;
@@ -1071,6 +1126,8 @@
 	if (mctrl & TIOCM_LOOP)
 		mcr |= UART_MCR_LOOP;
 
+	mcr = (mcr & up->mcr_mask) | up->mcr_force;
+
 	serial_out(up, UART_MCR, mcr);
 }
 
@@ -1139,7 +1196,7 @@
 	 * if it is, then bail out, because there's likely no UART
 	 * here.
 	 */
-	if (!(up->port.flags & ASYNC_BUGGY_UART) &&
+	if (!(up->port.flags & UPF_BUGGY_UART) &&
 	    (serial_inp(up, UART_LSR) == 0xff)) {
 		printk("ttyS%d: LSR safety check engaged!\n", up->port.line);
 		return -ENODEV;
@@ -1169,7 +1226,7 @@
 	serial_outp(up, UART_LCR, UART_LCR_WLEN8);
 
 	spin_lock_irqsave(&up->port.lock, flags);
-	if (up->port.flags & ASYNC_FOURPORT) {
+	if (up->port.flags & UPF_FOURPORT) {
 		if (!is_real_interrupt(up->port.irq))
 			up->port.mctrl |= TIOCM_OUT1;
 	} else
@@ -1190,7 +1247,7 @@
 	up->ier = UART_IER_RLSI | UART_IER_RDI;
 	serial_outp(up, UART_IER, up->ier);
 
-	if (up->port.flags & ASYNC_FOURPORT) {
+	if (up->port.flags & UPF_FOURPORT) {
 		unsigned int icp;
 		/*
 		 * Enable interrupts on the AST Fourport board
@@ -1223,7 +1280,7 @@
 	serial_outp(up, UART_IER, 0);
 
 	spin_lock_irqsave(&up->port.lock, flags);
-	if (up->port.flags & ASYNC_FOURPORT) {
+	if (up->port.flags & UPF_FOURPORT) {
 		/* reset interrupts on the AST Fourport board */
 		inb((up->port.iobase & 0xfe0) | 0x1f);
 		up->port.mctrl |= TIOCM_OUT1;
@@ -1604,7 +1661,7 @@
 	/*
 	 * Don't probe for MCA ports on non-MCA machines.
 	 */
-	if (up->port.flags & ASYNC_BOOT_ONLYMCA && !MCA_bus)
+	if (up->port.flags & UPF_BOOT_ONLYMCA && !MCA_bus)
 		return;
 #endif
 
@@ -1704,6 +1761,8 @@
 		up->port.iotype   = old_serial_port[i].io_type;
 		up->port.regshift = old_serial_port[i].iomem_reg_shift;
 		up->port.ops      = &serial8250_pops;
+		if (share_irqs)
+			up->port.flags |= UPF_SHARE_IRQ;
 	}
 }
 
@@ -1714,11 +1773,20 @@
 	serial8250_isa_init_ports();
 
 	for (i = 0; i < UART_NR; i++) {
-		serial8250_ports[i].port.line = i;
-		serial8250_ports[i].port.ops = &serial8250_pops;
-		init_timer(&serial8250_ports[i].timer);
-		serial8250_ports[i].timer.function = serial8250_timeout;
-		uart_add_one_port(drv, &serial8250_ports[i].port);
+		struct uart_8250_port *up = &serial8250_ports[i];
+
+		up->port.line = i;
+		up->port.ops = &serial8250_pops;
+		init_timer(&up->timer);
+		up->timer.function = serial8250_timeout;
+
+		/*
+		 * ALPHA_KLUDGE_MCR needs to be killed.
+		 */
+		up->mcr_mask = ~ALPHA_KLUDGE_MCR;
+		up->mcr_force = ALPHA_KLUDGE_MCR;
+
+		uart_add_one_port(drv, &up->port);
 	}
 }
 
@@ -1746,7 +1814,7 @@
 	} while ((status & BOTH_EMPTY) != BOTH_EMPTY);
 
 	/* Wait up to 1s for flow control if necessary */
-	if (up->port.flags & ASYNC_CONS_FLOW) {
+	if (up->port.flags & UPF_CONS_FLOW) {
 		tmout = 1000000;
 		while (--tmout &&
 		       ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0))
@@ -1857,7 +1925,7 @@
 #ifdef CONFIG_DEVFS_FS
 	.dev_name		= "tts/%d",
 #else
-	.dev_name		= "ttyS",
+	.dev_name		= "ttyS%d",
 #endif
 	.major			= TTY_MAJOR,
 	.minor			= 64,
@@ -1881,8 +1949,11 @@
 	port.fifosize = req->xmit_fifo_size;
 	port.regshift = req->iomem_reg_shift;
 	port.iotype   = req->io_type;
-	port.flags    = req->flags | ASYNC_BOOT_AUTOCONF;
+	port.flags    = req->flags | UPF_BOOT_AUTOCONF;
 	port.line     = line;
+
+	if (share_irqs)
+		port.flags |= UPF_SHARE_IRQ;
 
 	if (HIGH_BITS_OFFSET)
 		port.iobase |= (long) req->port_high << HIGH_BITS_OFFSET;
diff -Nru a/drivers/serial/8250_cs.c b/drivers/serial/8250_cs.c
--- a/drivers/serial/8250_cs.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/serial/8250_cs.c	Mon Nov  4 14:31:02 2002
@@ -41,6 +41,7 @@
 #include <linux/timer.h>
 #include <linux/tty.h>
 #include <linux/serial.h>
+#include <linux/serial_core.h>
 #include <linux/major.h>
 #include <linux/workqueue.h>
 #include <asm/io.h>
@@ -306,7 +307,7 @@
 	memset(&serial, 0, sizeof (serial));
 	serial.port = port;
 	serial.irq = irq;
-	serial.flags = ASYNC_SKIP_TEST | ASYNC_SHARE_IRQ;
+	serial.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ;
 	line = register_serial(&serial);
 	if (line < 0) {
 		printk(KERN_NOTICE "serial_cs: register_serial() at 0x%04lx,"
diff -Nru a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/serial/8250_gsc.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,133 @@
+/*
+ *	Serial Device Initialisation for Lasi/Asp/Wax/Dino
+ *
+ *	(c) Copyright Matthew Wilcox <willy@debian.org> 2001-2002
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2 of the License, or
+ *      (at your option) any later version.
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/serial.h>
+#include <linux/signal.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/serial.h>
+
+static void setup_parisc_serial(struct serial_struct *serial,
+		unsigned long address, int irq, int line)
+{
+	memset(serial, 0, sizeof(struct serial_struct));
+
+	/* autoconfig() sets state->type.  This sets info->type */
+	serial->type = PORT_16550A;
+
+	serial->line = line;
+	serial->iomem_base = ioremap(address, 0x8);
+
+	serial->irq = irq;
+	serial->io_type = SERIAL_IO_MEM;	/* define access method */
+	serial->flags = 0;
+	serial->xmit_fifo_size = 16;
+	serial->custom_divisor = 0;
+	serial->baud_base = LASI_BASE_BAUD;
+}
+
+static int __init 
+serial_init_chip(struct parisc_device *dev)
+{
+	static int serial_line_nr;
+	unsigned long address;
+	int err;
+
+	struct serial_struct *serial;
+
+	if (!dev->irq) {
+		/* We find some unattached serial ports by walking native
+		 * busses.  These should be silently ignored.  Otherwise,
+		 * what we have here is a missing parent device, so tell
+		 * the user what they're missing.
+		 */
+		if (dev->parent->id.hw_type != HPHW_IOA) {
+			printk(KERN_INFO "Serial: device 0x%lx not configured.\n"
+				"Enable support for Wax, Lasi, Asp or Dino.\n", dev->hpa);
+		}
+		return -ENODEV;
+	}
+
+	serial = kmalloc(sizeof(*serial), GFP_KERNEL);
+	if (!serial)
+		return -ENOMEM;
+
+	address = dev->hpa;
+	if (dev->id.sversion != 0x8d) {
+		address += 0x800;
+	}
+
+	setup_parisc_serial(serial, address, dev->irq, serial_line_nr++);
+	err = register_serial(serial);
+	if (err < 0) {
+		printk(KERN_WARNING "register_serial returned error %d\n", err);
+		kfree(serial);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static struct parisc_device_id serial_tbl[] = {
+	{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00075 },
+	{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008c },
+	{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008d },
+	{ 0 }
+};
+
+/* Hack.  Dino's serial port will get listed first on some machines.
+ * So we register this driver first which knows about Lasi's serial port.
+ * This needs to get fixed properly somehow.
+ */
+static struct parisc_device_id serial1_tbl[] = {
+	{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03B, 0x0008C }, /* C1xx/C1xxL */
+	{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03C, 0x0008C }, /* B132L */
+	{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03D, 0x0008C }, /* B160L */
+	{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03E, 0x0008C }, /* B132L+ */
+	{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03F, 0x0008C }, /* B180L+ */
+	{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x046, 0x0008C }, /* Rocky2 120 */
+	{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x047, 0x0008C }, /* Rocky2 150 */
+	{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x04E, 0x0008C }, /* Kiji L2 132 */
+	{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x056, 0x0008C }, /* Raven+ */
+	{ 0 }
+};
+
+
+MODULE_DEVICE_TABLE(parisc, serial_tbl);
+
+static struct parisc_driver serial1_driver = {
+	name:		"Serial RS232",
+	id_table:	serial1_tbl,
+	probe:		serial_init_chip,
+};
+
+static struct parisc_driver serial_driver = {
+	name:		"Serial RS232",
+	id_table:	serial_tbl,
+	probe:		serial_init_chip,
+};
+
+int __init probe_serial_gsc(void)
+{
+	register_parisc_driver(&serial1_driver);
+	register_parisc_driver(&serial_driver);
+	return 0;
+}
+
+module_init(probe_serial_gsc);
diff -Nru a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
--- a/drivers/serial/8250_pci.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/serial/8250_pci.c	Mon Nov  4 14:31:02 2002
@@ -11,7 +11,7 @@
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License.
  *
- *  $Id: 8250_pci.c,v 1.24 2002/07/29 14:39:56 rmk Exp $
+ *  $Id: 8250_pci.c,v 1.28 2002/11/02 11:14:18 rmk Exp $
  */
 #include <linux/module.h>
 #include <linux/init.h>
@@ -21,7 +21,6 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/serial.h>
-
 #include <linux/serialP.h>
 
 #include <asm/bitops.h>
@@ -55,14 +54,19 @@
 	int line[0];
 };
 
+/*
+ * init_fn returns:
+ *  > 0 - number of ports
+ *  = 0 - use board->num_ports
+ *  < 0 - error
+ */
 struct pci_board {
 	int flags;
 	int num_ports;
 	int base_baud;
 	int uart_offset;
 	int reg_shift;
-	int (*init_fn)(struct pci_dev *dev, struct pci_board *board,
-			int enable);
+	int (*init_fn)(struct pci_dev *dev, int enable);
 	int first_uart_offset;
 };
 
@@ -201,8 +205,7 @@
  * seems to be mainly needed on card using the PLX which also use I/O
  * mapped memory.
  */
-static int __devinit
-pci_plx9050_fn(struct pci_dev *dev, struct pci_board *board, int enable)
+static int __devinit pci_plx9050_fn(struct pci_dev *dev, int enable)
 {
 	u8 *p, irq_config = 0;
 
@@ -264,8 +267,7 @@
 #define PCI_DEVICE_ID_SIIG_1S_10x (PCI_DEVICE_ID_SIIG_1S_10x_550 & 0xfffc)
 #define PCI_DEVICE_ID_SIIG_2S_10x (PCI_DEVICE_ID_SIIG_2S_10x_550 & 0xfff8)
 
-static int __devinit
-pci_siig10x_fn(struct pci_dev *dev, struct pci_board *board, int enable)
+static int __devinit pci_siig10x_fn(struct pci_dev *dev, int enable)
 {
 	u16 data, *p;
 
@@ -296,8 +298,7 @@
 #define PCI_DEVICE_ID_SIIG_2S_20x (PCI_DEVICE_ID_SIIG_2S_20x_550 & 0xfffc)
 #define PCI_DEVICE_ID_SIIG_2S1P_20x (PCI_DEVICE_ID_SIIG_2S1P_20x_550 & 0xfffc)
 
-static int __devinit
-pci_siig20x_fn(struct pci_dev *dev, struct pci_board *board, int enable)
+static int __devinit pci_siig20x_fn(struct pci_dev *dev, int enable)
 {
 	u8 data;
 
@@ -318,8 +319,7 @@
 }
 
 /* Added for EKF Intel i960 serial boards */
-static int __devinit
-pci_inteli960ni_fn(struct pci_dev *dev, struct pci_board *board, int enable)
+static int __devinit pci_inteli960ni_fn(struct pci_dev *dev, int enable)
 {
 	unsigned long oldval;
 
@@ -378,8 +378,7 @@
 	{ 0, 0 }
 };
 
-static int __devinit
-pci_timedia_fn(struct pci_dev *dev, struct pci_board *board, int enable)
+static int __devinit pci_timedia_fn(struct pci_dev *dev, int enable)
 {
 	int	i, j;
 	unsigned short *ids;
@@ -389,12 +388,9 @@
 
 	for (i = 0; timedia_data[i].num; i++) {
 		ids = timedia_data[i].ids;
-		for (j = 0; ids[j]; j++) {
-			if (pci_get_subdevice(dev) == ids[j]) {
-				board->num_ports = timedia_data[i].num;
-				return 0;
-			}
-		}
+		for (j = 0; ids[j]; j++)
+			if (pci_get_subdevice(dev) == ids[j])
+				return timedia_data[i].num;
 	}
 	return 0;
 }
@@ -406,9 +402,10 @@
  * and Keystone have one Diva chip with 3 UARTs.  Some later machines have
  * one Diva chip, but it has been expanded to 5 UARTs.
  */
-static int __devinit
-pci_hp_diva(struct pci_dev *dev, struct pci_board *board, int enable)
+static int __devinit pci_hp_diva(struct pci_dev *dev, int enable)
 {
+	int rc = 0;
+
 	if (!enable)
 		return 0;
 
@@ -417,25 +414,24 @@
 	case PCI_DEVICE_ID_HP_DIVA_HALFDOME:
 	case PCI_DEVICE_ID_HP_DIVA_KEYSTONE:
 	case PCI_DEVICE_ID_HP_DIVA_EVEREST:
-		board->num_ports = 3;
+		rc = 3;
 		break;
 	case PCI_DEVICE_ID_HP_DIVA_TOSCA2:
-		board->num_ports = 2;
+		rc = 2;
 		break;
 	case PCI_DEVICE_ID_HP_DIVA_MAESTRO:
-		board->num_ports = 4;
+		rc = 4;
 		break;
 	case PCI_DEVICE_ID_HP_DIVA_POWERBAR:
-		board->num_ports = 1;
+		rc = 1;
 		break;
 	}
 
-	return 0;
+	return rc;
 }
 
 
-static int __devinit
-pci_xircom_fn(struct pci_dev *dev, struct pci_board *board, int enable)
+static int __devinit pci_xircom_fn(struct pci_dev *dev, int enable)
 {
 	__set_current_state(TASK_UNINTERRUPTIBLE);
 	schedule_timeout(HZ/10);
@@ -579,8 +575,11 @@
 		0x400, 7, pci_plx9050_fn },
 	{ SPCI_FL_BASE2, 4, 921600,			   /* pbn_plx_romulus */
 		0x20, 2, pci_plx9050_fn, 0x03 },
-		/* This board uses the size of PCI Base region 0 to
-		 * signal now many ports are available */
+
+	/*
+	 * This board uses the size of PCI Base region 0 to
+	 * signal now many ports are available
+	 */
 	{ SPCI_FL_BASE0 | SPCI_FL_REGION_SZ_CAP, 32, 115200 }, /* pbn_oxsemi */
 	{ SPCI_FL_BASE_TABLE, 1, 921600,		   /* pbn_timedia */
 		0, 0, pci_timedia_fn },
@@ -645,9 +644,9 @@
 	 * later?) 
 	 */
 	if ((((dev->class >> 8) != PCI_CLASS_COMMUNICATION_SERIAL) &&
-	    ((dev->class >> 8) != PCI_CLASS_COMMUNICATION_MODEM)) ||
+	     ((dev->class >> 8) != PCI_CLASS_COMMUNICATION_MODEM)) ||
 	    (dev->class & 0xff) > 6)
-		return 1;
+		return -ENODEV;
 
 	for (i = 0; i < 6; i++) {
 		if (IS_PCI_REGION_IOPORT(dev, i)) {
@@ -667,20 +666,31 @@
 		board->flags = first_port;
 		return 0;
 	}
-	return 1;
+	return -ENODEV;
+}
+
+static inline int
+serial_pci_matches(struct pci_board *board, int index)
+{
+	return
+	    board->base_baud == pci_boards[index].base_baud &&
+	    board->num_ports == pci_boards[index].num_ports &&
+	    board->uart_offset == pci_boards[index].uart_offset &&
+	    board->reg_shift == pci_boards[index].reg_shift &&
+	    board->first_uart_offset == pci_boards[index].first_uart_offset;
 }
 
 /*
- * return an error code to refuse.
- *
- * serial_struct is 60 bytes.
+ * Probe one serial board.  Unfortunately, there is no rhyme nor reason
+ * to the arrangement of serial ports on a PCI card.
  */
-static int __devinit pci_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
+static int __devinit
+pci_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
 {
 	struct serial_private *priv;
 	struct pci_board *board, tmp;
 	struct serial_struct serial_req;
-	int base_baud, rc, k;
+	int base_baud, rc, nr_ports, i;
 
 	if (ent->driver_data >= ARRAY_SIZE(pci_boards)) {
 		printk(KERN_ERR "pci_init_one: invalid driver_data: %ld\n",
@@ -694,67 +704,98 @@
 	if (rc)
 		return rc;
 
-	if (ent->driver_data == pbn_default &&
-	    serial_pci_guess_board(dev, board)) {
-		pci_disable_device(dev);
-		return -ENODEV;
-	} else if (serial_pci_guess_board(dev, &tmp) == 0) {
-		printk(KERN_INFO "Redundant entry in serial pci_table.  "
-		       "Please send the output of\n"
-		       "lspci -vv, this message (%d,%d,%d,%d)\n"
-		       "and the manufacturer and name of "
-		       "serial board or modem board\n"
-		       "to serial-pci-info@lists.sourceforge.net.\n",
-		       dev->vendor, dev->device,
-		       pci_get_subvendor(dev), pci_get_subdevice(dev));
+	if (ent->driver_data == pbn_default) {
+		/*
+		 * Use a copy of the pci_board entry for this;
+		 * avoid changing entries in the table.
+		 */
+		memcpy(&tmp, board, sizeof(struct pci_board));
+		board = &tmp;
+
+		/*
+		 * We matched one of our class entries.  Try to
+		 * determine the parameters of this board.
+		 */
+		rc = serial_pci_guess_board(dev, board);
+		if (rc)
+			goto disable;
+	} else {
+		/*
+		 * We matched an explicit entry.  If we are able to
+		 * detect this boards settings with our heuristic,
+		 * then we no longer need this entry.
+		 */
+		rc = serial_pci_guess_board(dev, &tmp);
+		if (rc == 0 && serial_pci_matches(board, pbn_default)) {
+			printk(KERN_INFO
+		"Redundant entry in serial pci_table.  Please send the output\n"
+		"of lspci -vv, this message (0x%04x,0x%04x,0x%04x,0x%04x),\n"
+		"the manufacturer and name of serial board or modem board to\n"
+		"rmk@arm.linux.org.uk.\n",
+			       dev->vendor, dev->device,
+			       pci_get_subvendor(dev), pci_get_subdevice(dev));
+		}
 	}
 
-	priv = kmalloc(sizeof(struct serial_private) +
-			      sizeof(unsigned int) * board->num_ports,
-			      GFP_KERNEL);
-	if (!priv) {
-		pci_disable_device(dev);
-		return -ENOMEM;
-	}
+	nr_ports = board->num_ports;
 
 	/*
-	 * Run the initialization function, if any
+	 * Run the initialization function, if any.  The initialization
+	 * function returns:
+	 *  <0  - error
+	 *   0  - use board->num_ports
+	 *  >0  - number of ports
 	 */
 	if (board->init_fn) {
-		rc = board->init_fn(dev, board, 1);
-		if (rc != 0) {
-			pci_disable_device(dev);
-			kfree(priv);
-			return rc;
-		}
+		rc = board->init_fn(dev, 1);
+		if (rc < 0)
+			goto disable;
+
+		if (rc)
+			nr_ports = rc;
+	}
+
+	priv = kmalloc(sizeof(struct serial_private) +
+			      sizeof(unsigned int) * nr_ports,
+			      GFP_KERNEL);
+	if (!priv) {
+		rc = -ENOMEM;
+		goto deinit;
 	}
 
 	base_baud = board->base_baud;
 	if (!base_baud)
 		base_baud = BASE_BAUD;
 	memset(&serial_req, 0, sizeof(serial_req));
-	for (k = 0; k < board->num_ports; k++) {
-		serial_req.irq = get_pci_irq(dev, board, k);
-		if (get_pci_port(dev, board, &serial_req, k))
+	for (i = 0; i < nr_ports; i++) {
+		serial_req.irq = get_pci_irq(dev, board, i);
+		if (get_pci_port(dev, board, &serial_req, i))
 			break;
 #ifdef SERIAL_DEBUG_PCI
-		printk("Setup PCI/PNP port: port %x, irq %d, type %d\n",
+		printk("Setup PCI port: port %x, irq %d, type %d\n",
 		       serial_req.port, serial_req.irq, serial_req.io_type);
 #endif
 		serial_req.flags = ASYNC_SKIP_TEST | ASYNC_AUTOPROBE;
 		serial_req.baud_base = base_baud;
 		
-		priv->line[k] = register_serial(&serial_req);
-		if (priv->line[k] < 0)
+		priv->line[i] = register_serial(&serial_req);
+		if (priv->line[i] < 0)
 			break;
 	}
 
 	priv->board = board;
-	priv->nr = k;
+	priv->nr = i;
 
 	pci_set_drvdata(dev, priv);
 
 	return 0;
+
+ deinit:
+	if (board->init_fn)
+		board->init_fn(dev, 0);
+ disable:
+	pci_disable_device(dev);
+	return rc;
 }
 
 static void __devexit pci_remove_one(struct pci_dev *dev)
@@ -769,7 +810,7 @@
 			unregister_serial(priv->line[i]);
 
 		if (priv->board->init_fn)
-			priv->board->init_fn(dev, priv->board, 0);
+			priv->board->init_fn(dev, 0);
 
 		pci_disable_device(dev);
 
@@ -1160,18 +1201,23 @@
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_dci_pccom8 },
 
+	/*
+	 * These entries match devices with class
+	 * COMMUNICATION_SERIAL, COMMUNICATION_MODEM
+	 * or COMMUNICATION_MULTISERIAL
+	 */
 	{	PCI_ANY_ID, PCI_ANY_ID,
 		PCI_ANY_ID, PCI_ANY_ID,
 		PCI_CLASS_COMMUNICATION_SERIAL << 8,
-		0xffff00, },
+		0xffff00, pbn_default },
 	{	PCI_ANY_ID, PCI_ANY_ID,
 		PCI_ANY_ID, PCI_ANY_ID,
 		PCI_CLASS_COMMUNICATION_MODEM << 8,
-		0xffff00, },
+		0xffff00, pbn_default },
 	{	PCI_ANY_ID, PCI_ANY_ID,
 		PCI_ANY_ID, PCI_ANY_ID,
 		PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
-		0xffff00, },
+		0xffff00, pbn_default },
 	{ 0, }
 };
 
diff -Nru a/drivers/serial/Makefile b/drivers/serial/Makefile
--- a/drivers/serial/Makefile	Mon Nov  4 14:31:01 2002
+++ b/drivers/serial/Makefile	Mon Nov  4 14:31:01 2002
@@ -7,6 +7,7 @@
 export-objs	:= core.o 8250.o suncore.o
 
 serial-8250-y :=
+serial-8250-$(CONFIG_GSC) += 8250_gsc.o
 serial-8250-$(CONFIG_PCI) += 8250_pci.o
 serial-8250-$(CONFIG_PNP) += 8250_pnp.o
 obj-$(CONFIG_SERIAL_CORE) += core.o
diff -Nru a/drivers/serial/amba.c b/drivers/serial/amba.c
--- a/drivers/serial/amba.c	Mon Nov  4 14:31:00 2002
+++ b/drivers/serial/amba.c	Mon Nov  4 14:31:00 2002
@@ -245,7 +245,7 @@
 	} while (--count > 0);
 
 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-		uart_event(port, EVT_WRITE_WAKEUP);
+		uart_write_wakeup(port);
 
 	if (uart_circ_empty(xmit))
 		ambauart_stop_tx(port);
@@ -706,11 +706,7 @@
 static struct uart_driver amba_reg = {
 	.owner			= THIS_MODULE,
 	.driver_name		= "ttyAM",
-#ifdef CONFIG_DEVFS_FS
 	.dev_name		= "ttyAM%d",
-#else
-	.dev_name		= "ttyAM",
-#endif
 	.major			= SERIAL_AMBA_MAJOR,
 	.minor			= SERIAL_AMBA_MINOR,
 	.nr			= UART_NR,
diff -Nru a/drivers/serial/anakin.c b/drivers/serial/anakin.c
--- a/drivers/serial/anakin.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/serial/anakin.c	Mon Nov  4 14:31:01 2002
@@ -161,7 +161,7 @@
 	anakin_transmit_buffer(port);
 
 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-		uart_event(port, EVT_WRITE_WAKEUP);
+		uart_write_wakeup(port);
 }
 
 static void
diff -Nru a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c
--- a/drivers/serial/clps711x.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/serial/clps711x.c	Mon Nov  4 14:31:01 2002
@@ -50,14 +50,12 @@
 #define UART_NR		2
 
 #ifndef CONFIG_SERIAL_CLPS711X_OLD_NAME
-#define SERIAL_CLPS711X_NAME	"ttyCL"
 #define SERIAL_CLPS711X_MAJOR	204
 #define SERIAL_CLPS711X_MINOR	40
 #define SERIAL_CLPS711X_NR	UART_NR
 
 #else
 #warning The old names/device number for this driver if compatabity is needed
-#define SERIAL_CLPS711X_NAME    "ttyAM"
 #define SERIAL_CLPS711X_MAJOR   204
 #define SERIAL_CLPS711X_MINOR   16
 #define SERIAL_CLPS711X_NR      UART_NR
@@ -209,7 +207,7 @@
 	} while (--count > 0);
 
 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-		uart_event(port, EVT_WRITE_WAKEUP);
+		uart_write_wakeup(port);
 
 	if (uart_circ_empty(xmit))
 		clps711xuart_stop_tx(port);
@@ -545,7 +543,7 @@
 }
 
 static struct console clps711x_console = {
-	.name		= SERIAL_CLPS711X_NAME,
+	.name		= "ttyCL",
 	.write		= clps711xuart_console_write,
 	.device		= clps711xuart_console_device,
 	.setup		= clps711xuart_console_setup,
@@ -565,12 +563,7 @@
 
 static struct uart_driver clps711x_reg = {
 	.driver_name		= "ttyCL",
-#ifdef CONFIG_DEVFS_FS
-	.dev_name		= SERIAL_CLPS711X_NAME,
-#else
-	.dev_name		= SERIAL_CLPS711X_NAME,
-#endif
-
+	.dev_name		= "ttyCL%d",
 	.major			= SERIAL_CLPS711X_MAJOR,
 	.minor			= SERIAL_CLPS711X_MINOR,
 	.nr			= UART_NR,
diff -Nru a/drivers/serial/core.c b/drivers/serial/core.c
--- a/drivers/serial/core.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/serial/core.c	Mon Nov  4 14:31:01 2002
@@ -65,11 +65,9 @@
  * This routine is used by the interrupt handler to schedule processing in
  * the software interrupt portion of the driver.
  */
-void uart_event(struct uart_port *port, int event)
+void uart_write_wakeup(struct uart_port *port)
 {
 	struct uart_info *info = port->info;
-
-	set_bit(0, &info->event);
 	tasklet_schedule(&info->tlet);
 }
 
@@ -112,13 +110,12 @@
 	struct tty_struct *tty;
 
 	tty = info->tty;
-	if (!tty || !test_and_clear_bit(EVT_WRITE_WAKEUP, &info->event))
-		return;
-
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
-	wake_up_interruptible(&tty->write_wait);
+	if (tty) {
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+		    tty->ldisc.write_wakeup)
+			tty->ldisc.write_wakeup(tty);
+		wake_up_interruptible(&tty->write_wait);
+	}
 }
 
 static inline void
@@ -1981,7 +1978,8 @@
 static inline void
 uart_report_port(struct uart_driver *drv, struct uart_port *port)
 {
-	printk("%s%d at ", drv->dev_name, port->line);
+	printk(drv->dev_name, port->line);
+	printk(" at ");
 	switch (port->iotype) {
 	case UPIO_PORT:
 		printk("I/O 0x%x", port->iobase);
@@ -2005,7 +2003,6 @@
 	state->port = port;
 
 	spin_lock_init(&port->lock);
-	port->type = PORT_UNKNOWN;
 	port->cons = drv->cons;
 	port->info = state->info;
 
@@ -2022,8 +2019,10 @@
 	flags = UART_CONFIG_TYPE;
 	if (port->flags & UPF_AUTO_IRQ)
 		flags |= UART_CONFIG_IRQ;
-	if (port->flags & UPF_BOOT_AUTOCONF)
+	if (port->flags & UPF_BOOT_AUTOCONF) {
+		port->type = PORT_UNKNOWN;
 		port->ops->config_port(port, flags);
+	}
 
 	/*
 	 * Register the port whether it's detected or not.  This allows
@@ -2439,8 +2438,9 @@
 	struct uart_state *state;
 
 	if (line < 0 || line >= drv->nr) {
-		printk(KERN_ERR "Attempt to unregister %s%d\n",
-			drv->dev_name, line);
+		printk(KERN_ERR "Attempt to unregister ");
+		printk(drv->dev_name, line);
+		printk("\n");
 		return;
 	}
 
@@ -2453,7 +2453,7 @@
 	up(&port_sem);
 }
 
-EXPORT_SYMBOL(uart_event);
+EXPORT_SYMBOL(uart_write_wakeup);
 EXPORT_SYMBOL(uart_register_driver);
 EXPORT_SYMBOL(uart_unregister_driver);
 EXPORT_SYMBOL(uart_register_port);
diff -Nru a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
--- a/drivers/serial/sa1100.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/serial/sa1100.c	Mon Nov  4 14:31:01 2002
@@ -305,7 +305,7 @@
 	}
 
 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-		uart_event(&sport->port, EVT_WRITE_WAKEUP);
+		uart_write_wakeup(&sport->port);
 
 	if (uart_circ_empty(xmit))
 		sa1100_stop_tx(&sport->port, 0);
@@ -661,7 +661,7 @@
 void __init sa1100_register_uart(int idx, int port)
 {
 	if (idx >= NR_PORTS) {
-		printk(KERN_ERR __FUNCTION__ ": bad index number %d\n", idx);
+		printk(KERN_ERR "%s: bad index number %d\n", __FUNCTION__, idx);
 		return;
 	}
 
@@ -688,7 +688,7 @@
 		break;
 
 	default:
-		printk(KERN_ERR __FUNCTION__ ": bad port number %d\n", port);
+		printk(KERN_ERR "%s: bad port number %d\n", __FUNCTION__, port);
 	}
 }
 
@@ -827,11 +827,7 @@
 static struct uart_driver sa1100_reg = {
 	.owner			= THIS_MODULE,
 	.driver_name		= "ttySA",
-#ifdef CONFIG_DEVFS_FS
 	.dev_name		= "ttySA%d",
-#else
-	.dev_name		= "ttySA",
-#endif
 	.major			= SERIAL_SA1100_MAJOR,
 	.minor			= MINOR_START,
 	.nr			= NR_PORTS,
diff -Nru a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
--- a/drivers/serial/sunsab.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/serial/sunsab.c	Mon Nov  4 14:31:01 2002
@@ -266,7 +266,7 @@
 	writeb(SAB82532_CMDR_XF, &up->regs->w.cmdr);
 
 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-		uart_event(&up->port, EVT_WRITE_WAKEUP);
+		uart_write_wakeup(&up->port);
 
 	if (uart_circ_empty(xmit))
 		sunsab_stop_tx(&up->port, 0);
@@ -843,7 +843,7 @@
 #ifdef CONFIG_DEVFS_FS
 	.dev_name		= "tts/%d",
 #else
-	.dev_name		= "ttyS",
+	.dev_name		= "ttyS%d",
 #endif
 	.major			= TTY_MAJOR,
 };
diff -Nru a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
--- a/drivers/serial/sunsu.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/serial/sunsu.c	Mon Nov  4 14:31:01 2002
@@ -431,7 +431,7 @@
 	} while (--count > 0);
 
 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-		uart_event(&up->port, EVT_WRITE_WAKEUP);
+		uart_write_wakeup(&up->port);
 
 	if (uart_circ_empty(xmit))
 		sunsu_stop_tx(&up->port, 0);
@@ -1262,7 +1262,7 @@
 #ifdef CONFIG_DEVFS_FS
 	.dev_name		= "tts/%d",
 #else
-	.dev_name		= "ttyS",
+	.dev_name		= "ttyS%d",
 #endif
 	.major			= TTY_MAJOR,
 };
diff -Nru a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
--- a/drivers/serial/sunzilog.c	Mon Nov  4 14:31:03 2002
+++ b/drivers/serial/sunzilog.c	Mon Nov  4 14:31:03 2002
@@ -523,7 +523,7 @@
 	up->port.icount.tx++;
 
 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-		uart_event(&up->port, EVT_WRITE_WAKEUP);
+		uart_write_wakeup(&up->port);
 
 	if (!uart_circ_empty(xmit))
 		return;
@@ -1003,7 +1003,7 @@
 #ifdef CONFIG_DEVFS_FS
 	.dev_name	=	"ttyS%d",
 #else
-	.dev_name	=	"ttyS",
+	.dev_name	=	"ttyS%d",
 #endif
 	.major		=	TTY_MAJOR,
 };
diff -Nru a/drivers/serial/uart00.c b/drivers/serial/uart00.c
--- a/drivers/serial/uart00.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/serial/uart00.c	Mon Nov  4 14:31:01 2002
@@ -215,7 +215,7 @@
 	} while (--count > 0);
 
 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-		uart_event(port, EVT_WRITE_WAKEUP);
+		uart_write_wakeup(port);
 
 	if (uart_circ_empty(xmit))
 		uart00_stop_tx(port, 0);
diff -Nru a/drivers/video/Kconfig b/drivers/video/Kconfig
--- a/drivers/video/Kconfig	Mon Nov  4 14:31:00 2002
+++ b/drivers/video/Kconfig	Mon Nov  4 14:31:00 2002
@@ -350,9 +350,8 @@
 	  console or the IODC BIOS.
 
 config FB_MAC
-	bool
+	bool "Generic Macintosh display support"
 	depends on FB && MAC
-	default y
 
 #      bool '  Apple DAFB display support' CONFIG_FB_DAFB
 config FB_HP300
diff -Nru a/drivers/video/fbcon.c b/drivers/video/fbcon.c
--- a/drivers/video/fbcon.c	Mon Nov  4 14:31:01 2002
+++ b/drivers/video/fbcon.c	Mon Nov  4 14:31:01 2002
@@ -627,7 +627,7 @@
     }
     
     if (!fontwidthvalid(p,fontwidth(p))) {
-#ifdef CONFIG_FBCON_MAC
+#if defined(CONFIG_FBCON_MAC) && defined(CONFIG_MAC)
 	if (MACH_IS_MAC)
 	    /* ++Geert: hack to make 6x11 fonts work on mac */
 	    p->dispsw = &fbcon_mac;
diff -Nru a/drivers/video/hpfb.c b/drivers/video/hpfb.c
--- a/drivers/video/hpfb.c	Mon Nov  4 14:31:02 2002
+++ b/drivers/video/hpfb.c	Mon Nov  4 14:31:02 2002
@@ -78,29 +78,29 @@
                            unsigned blue, unsigned transp,
                            struct fb_info *info)
 {
-	while (readw(fb_regs + 0x6002) & 0x4) udelay(1);
-	writew(0, fb_regs + 0x60f0);
-	writew(regno, fb_regs + 0x60b8);
-	writew(red, fb_regs + 0x60b2);
-	writew(green, fb_regs + 0x60b4);
-	writew(blue, fb_regs + 0x60b6);
-	writew(0xff, fb_regs + 0x60f0);
+	while (in_be16(fb_regs + 0x6002) & 0x4) udelay(1);
+	out_be16(fb_regs + 0x60f0, 0);
+	out_be16(fb_regs + 0x60b8, regno);
+	out_be16(fb_regs + 0x60b2, red);
+	out_be16(fb_regs + 0x60b4, green);
+	out_be16(fb_regs + 0x60b6, blue);
+	out_be16(fb_regs + 0x60f0, 0xff);
 	udelay(100);
-	writew(0xffff, fb_regs + 0x60ba);
+	out_be16(fb_regs + 0x60ba, 0xffff);
 	return 0;
 }
 
 void hpfb_copyarea(struct fb_info *info, struct fb_copyarea *area) 
 {
-	while (readb(fb_regs + BUSY) & fb_bitmask);
-	writeb(0x3, fb_regs + WMRR);
-	writew(area->sx, fb_regs + SOURCE_X);
-	writew(area->sy, fb_regs + SOURCE_Y);
-	writew(area->dx, fb_regs + DEST_X);
-	writew(area->dy, fb_regs + DEST_Y);
-	writew(area->height, fb_regs + WHEIGHT);
-	writew(area->width, fb_regs + WWIDTH);
-	writeb(fb_bitmask, fb_regs + WMOVE);
+	while (in_8(fb_regs + BUSY) & fb_bitmask);
+	out_8(fb_regs + WMRR, 0x3);
+	out_be16(fb_regs + SOURCE_X, area->sx);
+	out_be16(fb_regs + SOURCE_Y, area->sy);
+	out_be16(fb_regs + DEST_X, area->dx);
+	out_be16(fb_regs + DEST_Y, area->dy);
+	out_be16(fb_regs + WHEIGHT, area->height);
+	out_be16(fb_regs + WWIDTH, area->width);
+	out_8(fb_regs + WMOVE, fb_bitmask);
 }
 
 static struct fb_ops hpfb_ops = {
@@ -121,38 +121,37 @@
 {
 	unsigned long fboff;
 
-	fboff = (readb(base + TOPCAT_FBOMSB) << 8) 
-		| readb(base + TOPCAT_FBOLSB);
+	fboff = (in_8(base + TOPCAT_FBOMSB) << 8) | in_8(base + TOPCAT_FBOLSB);
 
-	hpfb_fix.smem_start = 0xf0000000 | (readb(base + fboff) << 16);
+	hpfb_fix.smem_start = 0xf0000000 | (in_8(base + fboff) << 16);
 	fb_regs = base;
 
 #if 0
 	/* This is the magic incantation NetBSD uses to make Catseye boards work. */
-	writeb(0, base+0x4800);
-	writeb(0, base+0x4510);
-	writeb(0, base+0x4512);
-	writeb(0, base+0x4514);
-	writeb(0, base+0x4516);
-	writeb(0x90, base+0x4206);
+	out_8(base+0x4800, 0);
+	out_8(base+0x4510, 0);
+	out_8(base+0x4512, 0);
+	out_8(base+0x4514, 0);
+	out_8(base+0x4516, 0);
+	out_8(base+0x4206, 0x90);
 #endif
 	/* 
 	 *	Give the hardware a bit of a prod and work out how many bits per
 	 *	pixel are supported.
 	 */
 	
-	writeb(0xff, base + TC_WEN);
-	writeb(0xff, base + TC_FBEN);
-	writeb(0xff, hpfb_fix.smem_start);
-	fb_bitmask = readb(hpfb_fix.smem_start);
+	out_8(base + TC_WEN, 0xff);
+	out_8(base + TC_FBEN, 0xff);
+	out_8(hpfb_fix.smem_start, 0xff);
+	fb_bitmask = in_8(hpfb_fix.smem_start);
 
 	/*
 	 *	Enable reading/writing of all the planes.
 	 */
-	writeb(fb_bitmask, base + TC_WEN);
-	writeb(fb_bitmask, base + TC_REN);
-	writeb(fb_bitmask, base + TC_FBEN);
-	writeb(0x1, base + TC_NBLANK);
+	out_8(base + TC_WEN, fb_bitmask);
+	out_8(base + TC_REN, fb_bitmask);
+	out_8(base + TC_FBEN, fb_bitmask);
+	out_8(base + TC_NBLANK, 0x1);
 
 	/*
 	 *	Let there be consoles..
diff -Nru a/drivers/zorro/proc.c b/drivers/zorro/proc.c
--- a/drivers/zorro/proc.c	Mon Nov  4 14:31:00 2002
+++ b/drivers/zorro/proc.c	Mon Nov  4 14:31:00 2002
@@ -51,7 +51,7 @@
 	struct proc_dir_entry *dp = PDE(ino);
 	struct zorro_dev *dev = dp->data;
 	struct ConfigDev cd;
-	int pos = *ppos;
+	loff_t pos = *ppos;
 
 	if (pos >= sizeof(struct ConfigDev))
 		return 0;
diff -Nru a/drivers/zorro/zorro.ids b/drivers/zorro/zorro.ids
--- a/drivers/zorro/zorro.ids	Mon Nov  4 14:31:02 2002
+++ b/drivers/zorro/zorro.ids	Mon Nov  4 14:31:02 2002
@@ -4,7 +4,7 @@
 #	Maintained by Geert Uytterhoeven <zorro@linux-m68k.org>
 #	If you have any new entries, please send them to the maintainer.
 #
-#	$Id: zorro.ids,v 1.17 2001/10/25 08:21:39 geert Exp $
+#	$Id: zorro.ids,v 1.19 2002/10/14 13:08:58 geert Exp $
 #
 
 # Manufacturers and Products. Please keep sorted.
@@ -364,7 +364,13 @@
 	1300  Warp Engine 40xx [Accelerator, SCSI Host Adapter and RAM Expansion]
 089e  ElBox Computer
 	0600  1200/4 [RAM Expansion]
-	1900  PowerFlyer [IDE Interface]
+	0800  FastATA 1200 [IDE Interface]
+	1200  FastATA 1200 [IDE Interface]
+	1300  FastATA 1200 [IDE Interface]
+	1800  FastATA 1200 [IDE Interface]
+	1900  FastATA 4000 [IDE Interface]
+	1d00  FastATA 4000 [IDE Interface]
+	1e00  FastATA ZIV [IDE Interface]
 0a00  Harms Professional
 	1000  030 Plus [Accelerator]
 	d000  3500 Professional [Accelerator and RAM Expansion]
diff -Nru a/fs/Kconfig b/fs/Kconfig
--- a/fs/Kconfig	Mon Nov  4 14:31:02 2002
+++ b/fs/Kconfig	Mon Nov  4 14:31:02 2002
@@ -289,6 +289,31 @@
 	  of your root partition (the one containing the directory /) cannot
 	  be compiled as a module, and so this may be dangerous.
 
+config EXT3_FS_XATTR
+	bool "Ext3 extended attributes"
+	depends on EXT3_FS
+	default y
+	---help---
+	  Extended attributes are name:value pairs associated with inodes by
+	  the kernel or by users (see the attr(5) manual page, or visit
+	  <http://acl.bestbits.at/> for details).
+
+	  If unsure, say N.
+
+	  You need this for POSIX ACL support on ext3.
+
+config EXT3_FS_POSIX_ACL
+	bool "Ext3 POSIX Access Control Lists"
+	depends on EXT3_FS_XATTR
+	---help---
+	  Posix Access Control Lists (ACLs) support permissions for users and
+	  groups beyond the owner/group/world scheme.
+
+	  To learn more about Access Control Lists, visit the Posix ACLs for
+	  Linux website <http://acl.bestbits.at/>.
+
+	  If you don't know what Access Control Lists are, say N
+
 # CONFIG_JBD could be its own option (even modular), but until there are
 # other users than ext3, we will simply make it be the same as CONFIG_EXT3_FS
 # dep_tristate '  Journal Block Device support (JBD for ext3)' CONFIG_JBD $CONFIG_EXT3_FS
@@ -578,6 +603,10 @@
 	  say M here and read <file:Documentation/modules.txt>.  The module
 	  will be called ramfs.o.
 
+config HUGETLBFS
+	bool "HugeTLB file system support"
+	depends on HUGETLB_PAGE
+
 config ISO9660_FS
 	tristate "ISO 9660 CDROM file system support"
 	---help---
@@ -626,6 +655,18 @@
 
 	  If you do not intend to use the JFS filesystem, say N.
 
+config JFS_POSIX_ACL
+	bool "JFS POSIX Access Control Lists"
+	depends on JFS_FS
+	---help---
+	  Posix Access Control Lists (ACLs) support permissions for users and
+	  groups beyond the owner/group/world scheme.
+
+	  To learn more about Access Control Lists, visit the Posix ACLs for
+	  Linux website <http://acl.bestbits.at/>.
+
+	  If you don't know what Access Control Lists are, say N
+
 config JFS_DEBUG
 	bool "JFS debugging"
 	depends on JFS_FS
@@ -935,6 +976,28 @@
 	  be compiled as a module, and so this could be dangerous.  Most
 	  everyone wants to say Y here.
 
+config EXT2_FS_XATTR
+	bool "Ext2 extended attributes"
+	depends on EXT2_FS
+	---help---
+	  Extended attributes are name:value pairs associated with inodes by
+	  the kernel or by users (see the attr(5) manual page, or visit
+	  <http://acl.bestbits.at/> for details).
+
+	  If unsure, say N.
+
+config EXT2_FS_POSIX_ACL
+	bool "Ext2 POSIX Access Control Lists"
+	depends on EXT2_FS_XATTR
+	---help---
+	  Posix Access Control Lists (ACLs) support permissions for users and
+	  groups beyond the owner/group/world scheme.
+
+	  To learn more about Access Control Lists, visit the Posix ACLs for
+	  Linux website <http://acl.bestbits.at/>.
+
+	  If you don't know what Access Control Lists are, say N
+
 config SYSV_FS
 	tristate "System V/Xenix/V7/Coherent file system support"
 	---help---
@@ -1406,6 +1469,18 @@
 	depends on ZISOFS
 	default ISO9660_FS
 
+# Meta block cache for Extended Attributes (ext2/ext3)
+config FS_MBCACHE
+	tristate
+	depends on EXT2_FS_XATTR || EXT3_FS_XATTR
+	default y if EXT2_FS=y || EXT3_FS=y
+	default m if EXT2_FS=m || EXT3_FS=m
+
+# Posix ACL utility routines (for now, only ext2/ext3/jfs)
+config FS_POSIX_ACL
+	bool
+	depends on EXT2_FS_POSIX_ACL || EXT3_FS_POSIX_ACL || JFS_POSIX_ACL
+	default y
 
 menu "Partition Types"
 
diff -Nru a/fs/Makefile b/fs/Makefile
--- a/fs/Makefile	Mon Nov  4 14:31:02 2002
+++ b/fs/Makefile	Mon Nov  4 14:31:02 2002
@@ -6,14 +6,14 @@
 # 
 
 export-objs :=	open.o dcache.o buffer.o bio.o inode.o dquot.o mpage.o aio.o \
-                fcntl.o read_write.o dcookies.o fcblist.o
+                fcntl.o read_write.o dcookies.o mbcache.o posix_acl.o xattr_acl.o
 
 obj-y :=	open.o read_write.o devices.o file_table.o buffer.o \
 		bio.o super.o block_dev.o char_dev.o stat.o exec.o pipe.o \
 		namei.o fcntl.o ioctl.o readdir.o select.o fifo.o locks.o \
 		dcache.o inode.o attr.o bad_inode.o file.o dnotify.o \
 		filesystems.o namespace.o seq_file.o xattr.o libfs.o \
-		fs-writeback.o mpage.o direct-io.o aio.o fcblist.o
+		fs-writeback.o mpage.o direct-io.o aio.o eventpoll.o
 
 ifneq ($(CONFIG_NFSD),n)
 ifneq ($(CONFIG_NFSD),)
@@ -29,6 +29,11 @@
 obj-y				+= binfmt_script.o
 
 obj-$(CONFIG_BINFMT_ELF)	+= binfmt_elf.o
+obj-$(CONFIG_BINFMT_SOM)	+= binfmt_som.o
+obj-$(CONFIG_BINFMT_FLAT)	+= binfmt_flat.o
+
+obj-$(CONFIG_FS_MBCACHE)	+= mbcache.o
+obj-$(CONFIG_FS_POSIX_ACL)	+= posix_acl.o xattr_acl.o
 
 obj-$(CONFIG_QUOTA)		+= dquot.o
 obj-$(CONFIG_QFMT_V1)		+= quota_v1.o
@@ -37,7 +42,7 @@
 
 obj-$(CONFIG_PROC_FS)		+= proc/
 obj-y				+= partitions/
-obj-y				+= driverfs/ sysfs/
+obj-y				+= sysfs/
 obj-y				+= devpts/
 
 obj-$(CONFIG_PROFILING)		+= dcookies.o
@@ -48,6 +53,7 @@
 obj-$(CONFIG_EXT2_FS)		+= ext2/
 obj-$(CONFIG_CRAMFS)		+= cramfs/
 obj-$(CONFIG_RAMFS)		+= ramfs/
+obj-$(CONFIG_HUGETLBFS)		+= hugetlbfs/
 obj-$(CONFIG_CODA_FS)		+= coda/
 obj-$(CONFIG_INTERMEZZO_FS)	+= intermezzo/
 obj-$(CONFIG_MINIX_FS)		+= minix/
diff -Nru a/fs/afs/Makefile b/fs/afs/Makefile
--- a/fs/afs/Makefile	Mon Nov  4 14:31:02 2002
+++ b/fs/afs/Makefile	Mon Nov  4 14:31:02 2002
@@ -23,14 +23,6 @@
 	vnode.o \
 	volume.o
 
-#	cache.o
-
-obj-m  := kafs.o
-
-# superfluous for 2.5, but needed for 2.4..
-ifeq "$(VERSION).$(PATCHLEVEL)" "2.4"
-kafs.o: $(kafs-objs)
-	$(LD) -r -o kafs.o $(kafs-objs)
-endif
+obj-$(CONFIG_AFS_FS)  := kafs.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/fs/afs/dir.c b/fs/afs/dir.c
--- a/fs/afs/dir.c	Mon Nov  4 14:31:01 2002
+++ b/fs/afs/dir.c	Mon Nov  4 14:31:01 2002
@@ -38,19 +38,17 @@
 
 struct inode_operations afs_dir_inode_operations = {
 	.lookup		= afs_dir_lookup,
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	.getattr	= afs_inode_getattr,
-#else
-	.revalidate	= afs_inode_revalidate,
+#if 0 /* TODO */
+	.create		= afs_dir_create,
+	.link		= afs_dir_link,
+	.unlink		= afs_dir_unlink,
+	.symlink	= afs_dir_symlink,
+	.mkdir		= afs_dir_mkdir,
+	.rmdir		= afs_dir_rmdir,
+	.mknod		= afs_dir_mknod,
+	.rename		= afs_dir_rename,
 #endif
-//	.create		= afs_dir_create,
-//	.link		= afs_dir_link,
-//	.unlink		= afs_dir_unlink,
-//	.symlink	= afs_dir_symlink,
-//	.mkdir		= afs_dir_mkdir,
-//	.rmdir		= afs_dir_rmdir,
-//	.mknod		= afs_dir_mknod,
-//	.rename		= afs_dir_rename,
 };
 
 static struct dentry_operations afs_fs_dentry_operations = {
@@ -72,7 +70,7 @@
 		u8	name[16];
 		u8	overflow[4];	/* if any char of the name (inc NUL) reaches here, consume
 					 * the next dirent too */
-	};
+	} parts;
 	u8	extended_name[32];
 } afs_dirent_t;
 
@@ -250,7 +248,7 @@
 
 		/* skip entries marked unused in the bitmap */
 		if (!(block->pagehdr.bitmap[offset/8] & (1 << (offset % 8)))) {
-			_debug("ENT[%u.%u]: unused\n",blkoff/sizeof(afs_dir_block_t),offset);
+			_debug("ENT[%Zu.%u]: unused\n",blkoff/sizeof(afs_dir_block_t),offset);
 			if (offset>=curr)
 				*fpos = blkoff + next * sizeof(afs_dirent_t);
 			continue;
@@ -258,28 +256,28 @@
 
 		/* got a valid entry */
 		dire = &block->dirents[offset];
-		nlen = strnlen(dire->name,sizeof(*block) - offset*sizeof(afs_dirent_t));
+		nlen = strnlen(dire->parts.name,sizeof(*block) - offset*sizeof(afs_dirent_t));
 
-		_debug("ENT[%u.%u]: %s %u \"%.*s\"\n",
+		_debug("ENT[%Zu.%u]: %s %Zu \"%s\"\n",
 		       blkoff/sizeof(afs_dir_block_t),offset,
-		       offset<curr ? "skip" : "fill",
-		       nlen,nlen,dire->name);
+		       (offset<curr ? "skip" : "fill"),
+		       nlen,dire->u.name);
 
 		/* work out where the next possible entry is */
 		for (tmp=nlen; tmp>15; tmp-=sizeof(afs_dirent_t)) {
 			if (next>=AFS_DIRENT_PER_BLOCK) {
-				_debug("ENT[%u.%u]:"
-				       " %u travelled beyond end dir block (len %u/%u)\n",
+				_debug("ENT[%Zu.%u]:"
+				       " %u travelled beyond end dir block (len %u/%Zu)\n",
 				       blkoff/sizeof(afs_dir_block_t),offset,next,tmp,nlen);
 				return -EIO;
 			}
 			if (!(block->pagehdr.bitmap[next/8] & (1 << (next % 8)))) {
-				_debug("ENT[%u.%u]: %u unmarked extension (len %u/%u)\n",
+				_debug("ENT[%Zu.%u]: %u unmarked extension (len %u/%Zu)\n",
 				       blkoff/sizeof(afs_dir_block_t),offset,next,tmp,nlen);
 				return -EIO;
 			}
 
-			_debug("ENT[%u.%u]: ext %u/%u\n",
+			_debug("ENT[%Zu.%u]: ext %u/%Zu\n",
 			       blkoff/sizeof(afs_dir_block_t),next,tmp,nlen);
 			next++;
 		}
@@ -290,11 +288,11 @@
 
 		/* found the next entry */
 		ret = filldir(cookie,
-			      dire->name,
+			      dire->parts.name,
 			      nlen,
 			      blkoff + offset * sizeof(afs_dirent_t),
-			      ntohl(dire->vnode),
-			      filldir==afs_dir_lookup_filldir ? dire->unique : DT_UNKNOWN);
+			      ntohl(dire->parts.vnode),
+			      filldir==afs_dir_lookup_filldir ? dire->parts.unique : DT_UNKNOWN);
 		if (ret<0) {
 			_leave(" = 0 [full]");
 			return 0;
@@ -397,7 +395,7 @@
 {
 	struct afs_dir_lookup_cookie *cookie = _cookie;
 
-	_enter("{%s,%u},%s,%u,,%lu,%u",cookie->name,cookie->nlen,name,nlen,ino,ntohl(dtype));
+	_enter("{%s,%Zu},%s,%u,,%lu,%u",cookie->name,cookie->nlen,name,nlen,ino,ntohl(dtype));
 
 	if (cookie->nlen != nlen || memcmp(cookie->name,name,nlen)!=0) {
 		_leave(" = 0 [no]");
@@ -471,7 +469,7 @@
 	}
 
 	dentry->d_op = &afs_fs_dentry_operations;
-	dentry->d_fsdata = (void*) (unsigned) vnode->status.version;
+	dentry->d_fsdata = (void*) (unsigned long) vnode->status.version;
 
 	d_add(dentry,inode);
 	_leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%lu }",
@@ -500,15 +498,9 @@
 	_enter("%s,%x",dentry->d_name.name,flags);
 
 	/* lock down the parent dentry so we can peer at it */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	read_lock(&dparent_lock);
 	parent = dget(dentry->d_parent);
 	read_unlock(&dparent_lock);
-#else
-	lock_kernel();
-	parent = dget(dentry->d_parent);
-	unlock_kernel();
-#endif
 
 	dir = parent->d_inode;
 	inode = dentry->d_inode;
@@ -541,10 +533,10 @@
 		goto out_bad;
 	}
 
-	if ((unsigned)dentry->d_fsdata != (unsigned)AFS_FS_I(dir)->status.version) {
-		_debug("%s: parent changed %u -> %u",
+	if ((unsigned long)dentry->d_fsdata != (unsigned long)AFS_FS_I(dir)->status.version) {
+		_debug("%s: parent changed %lu -> %u",
 		       dentry->d_name.name,
-		       (unsigned)dentry->d_fsdata,
+		       (unsigned long)dentry->d_fsdata,
 		       (unsigned)AFS_FS_I(dir)->status.version);
 
 		/* search the directory for this vnode */
@@ -585,7 +577,7 @@
 			goto out_bad;
 		}
 
-		dentry->d_fsdata = (void*) (unsigned) AFS_FS_I(dir)->status.version;
+		dentry->d_fsdata = (void*) (unsigned long) AFS_FS_I(dir)->status.version;
 	}
 
  out_valid:
diff -Nru a/fs/afs/errors.h b/fs/afs/errors.h
--- a/fs/afs/errors.h	Mon Nov  4 14:31:03 2002
+++ b/fs/afs/errors.h	Mon Nov  4 14:31:03 2002
@@ -9,8 +9,8 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-#ifndef _H_DB712916_5113_11D6_9A6D_0002B3163499
-#define _H_DB712916_5113_11D6_9A6D_0002B3163499
+#ifndef _LINUX_AFS_ERRORS_H
+#define _LINUX_AFS_ERRORS_H
 
 #include "types.h"
 
@@ -31,4 +31,4 @@
 
 extern int afs_abort_to_error(int abortcode);
 
-#endif /* _H_DB712916_5113_11D6_9A6D_0002B3163499 */
+#endif /* _LINUX_AFS_ERRORS_H */
diff -Nru a/fs/afs/file.c b/fs/afs/file.c
--- a/fs/afs/file.c	Mon Nov  4 14:31:02 2002
+++ b/fs/afs/file.c	Mon Nov  4 14:31:02 2002
@@ -21,52 +21,33 @@
 #include <rxrpc/call.h>
 #include "internal.h"
 
-//static int afs_file_open(struct inode *inode, struct file *file);
-//static int afs_file_release(struct inode *inode, struct file *file);
+#if 0
+static int afs_file_open(struct inode *inode, struct file *file);
+static int afs_file_release(struct inode *inode, struct file *file);
+#endif
 
 static int afs_file_readpage(struct file *file, struct page *page);
 
-//static ssize_t afs_file_read(struct file *file, char *buf, size_t size, loff_t *off);
-
 static ssize_t afs_file_write(struct file *file, const char *buf, size_t size, loff_t *off);
 
 struct inode_operations afs_file_inode_operations = {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	.getattr	= afs_inode_getattr,
-#else
-	.revalidate	= afs_inode_revalidate,
-#endif
 };
 
 struct file_operations afs_file_file_operations = {
-//	.open		= afs_file_open,
-//	.release	= afs_file_release,
-	.read		= generic_file_read, //afs_file_read,
+	.read		= generic_file_read,
 	.write		= afs_file_write,
 	.mmap		= generic_file_mmap,
-//	.fsync		= afs_file_fsync,
+#if 0
+	.open		= afs_file_open,
+	.release	= afs_file_release,
+	.fsync		= afs_file_fsync,
+#endif
 };
 
 struct address_space_operations afs_fs_aops = {
 	.readpage	= afs_file_readpage,
 };
-
-/*****************************************************************************/
-/*
- * AFS file read
- */
-#if 0
-static ssize_t afs_file_read(struct file *file, char *buf, size_t size, loff_t *off)
-{
-	struct afs_inode_info *ai;
-
-	ai = AFS_FS_I(file->f_dentry->d_inode);
-	if (ai->flags & AFS_INODE_DELETED)
-		return -ESTALE;
-
-	return -EIO;
-} /* end afs_file_read() */
-#endif
 
 /*****************************************************************************/
 /*
diff -Nru a/fs/afs/fsclient.c b/fs/afs/fsclient.c
--- a/fs/afs/fsclient.c	Mon Nov  4 14:31:02 2002
+++ b/fs/afs/fsclient.c	Mon Nov  4 14:31:02 2002
@@ -426,7 +426,7 @@
 	int ret;
 	u32 *bp;
 
-	_enter("%p,{fid={%u,%u,%u},sz=%u,of=%lu}",
+	_enter("%p,{fid={%u,%u,%u},sz=%Zu,of=%lu}",
 	       server,
 	       desc->fid.vid,
 	       desc->fid.vnode,
diff -Nru a/fs/afs/inode.c b/fs/afs/inode.c
--- a/fs/afs/inode.c	Mon Nov  4 14:31:01 2002
+++ b/fs/afs/inode.c	Mon Nov  4 14:31:01 2002
@@ -28,9 +28,6 @@
 struct afs_iget_data {
 	afs_fid_t		fid;
 	afs_volume_t		*volume;	/* volume on which resides */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	afs_vnode_t		*new_vnode;	/* new vnode record */
-#endif
 };
 
 /*****************************************************************************/
@@ -41,7 +38,7 @@
 {
 	struct inode *inode = AFS_VNODE_TO_I(vnode);
 
-	_debug("FS: ft=%d lk=%d sz=%u ver=%Lu mod=%hu",
+	_debug("FS: ft=%d lk=%d sz=%Zu ver=%Lu mod=%hu",
 	       vnode->status.type,
 	       vnode->status.nlink,
 	       vnode->status.size,
@@ -117,7 +114,6 @@
 /*
  * iget5() comparator
  */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 static int afs_iget5_test(struct inode *inode, void *opaque)
 {
 	struct afs_iget_data *data = opaque;
@@ -125,13 +121,11 @@
 	/* only match inodes with the same version number */
 	return inode->i_ino==data->fid.vnode && inode->i_version==data->fid.unique;
 } /* end afs_iget5_test() */
-#endif
 
 /*****************************************************************************/
 /*
  * iget5() inode initialiser
  */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 static int afs_iget5_set(struct inode *inode, void *opaque)
 {
 	struct afs_iget_data *data = opaque;
@@ -144,71 +138,6 @@
 
 	return 0;
 } /* end afs_iget5_set() */
-#endif
-
-/*****************************************************************************/
-/*
- * iget4() comparator
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-static int afs_iget4_test(struct inode *inode, ino_t ino, void *opaque)
-{
-	struct afs_iget_data *data = opaque;
-
-	/* only match inodes with the same version number */
-	return inode->i_ino==data->fid.vnode && inode->i_version==data->fid.unique;
-} /* end afs_iget4_test() */
-#endif
-
-/*****************************************************************************/
-/*
- * read an inode (2.4 only)
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-void afs_read_inode2(struct inode *inode, void *opaque)
-{
-	struct afs_iget_data *data = opaque;
-	afs_vnode_t *vnode;
-	int ret;
-
-	_enter(",{{%u,%u,%u},%p}",data->fid.vid,data->fid.vnode,data->fid.unique,data->volume);
-
-	if (inode->u.generic_ip) BUG();
-
-	/* attach a pre-allocated vnode record */
-	inode->u.generic_ip = vnode = data->new_vnode;
-	data->new_vnode = NULL;
-
-	memset(vnode,0,sizeof(*vnode));
-	vnode->inode = inode;
-	init_waitqueue_head(&vnode->update_waitq);
-	spin_lock_init(&vnode->lock);
-	INIT_LIST_HEAD(&vnode->cb_link);
-	INIT_LIST_HEAD(&vnode->cb_hash_link);
-	afs_timer_init(&vnode->cb_timeout,&afs_vnode_cb_timed_out_ops);
-	vnode->flags |= AFS_VNODE_CHANGED;
-	vnode->volume = data->volume;
-	vnode->fid = data->fid;
-
-	/* ask the server for a status check */
-	ret = afs_vnode_fetch_status(vnode);
-	if (ret<0) {
-		make_bad_inode(inode);
-		_leave(" [bad inode]");
-		return;
-	}
-
-	ret = afs_inode_map_status(vnode);
-	if (ret<0) {
-		make_bad_inode(inode);
-		_leave(" [bad inode]");
-		return;
-	}
-
-	_leave("");
-	return;
-} /* end afs_read_inode2() */
-#endif
 
 /*****************************************************************************/
 /*
@@ -227,7 +156,6 @@
 	as = sb->s_fs_info;
 	data.volume = as->volume;
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	inode = iget5_locked(sb,fid->vnode,afs_iget5_test,afs_iget5_set,&data);
 	if (!inode) {
 		_leave(" = -ENOMEM");
@@ -253,13 +181,6 @@
 	if (ret<0)
 		goto bad_inode;
 
-#if 0
-	/* find a cache entry for it */
-	ret = afs_cache_lookup_vnode(as->volume,vnode);
-	if (ret<0)
-		goto bad_inode;
-#endif
-
 	/* success */
 	unlock_new_inode(inode);
 
@@ -280,42 +201,12 @@
 
 	_leave(" = %d [bad]",ret);
 	return ret;
-
-#else
-
-	/* pre-allocate a vnode record so that afs_read_inode2() doesn't have to return an inode
-	 * without one attached
-	 */
-	data.new_vnode = kmalloc(sizeof(afs_vnode_t),GFP_KERNEL);
-	if (!data.new_vnode) {
-		_leave(" = -ENOMEM");
-		return -ENOMEM;
-	}
-
-	inode = iget4(sb,fid->vnode,afs_iget4_test,&data);
-	if (data.new_vnode) kfree(data.new_vnode); 
-	if (!inode) {
-		_leave(" = -ENOMEM");
-		return -ENOMEM;
-	}
-
-	vnode = AFS_FS_I(inode);
-	*_inode = inode;
-	_leave(" = 0 [CB { v=%u x=%lu t=%u nix=%u }]",
-	       vnode->cb_version,
-	       vnode->cb_timeout.timo_jif,
-	       vnode->cb_type,
-	       vnode->nix
-	       );
-	return 0;
-#endif
 } /* end afs_iget() */
 
 /*****************************************************************************/
 /*
  * read the attributes of an inode
  */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
 {
 	struct inode *inode;
@@ -349,44 +240,6 @@
 
 	return 0;
 } /* end afs_inode_getattr() */
-#endif
-
-/*****************************************************************************/
-/*
- * revalidate the inode
- */
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
-int afs_inode_revalidate(struct dentry *dentry)
-{
-	struct inode *inode;
-	afs_vnode_t *vnode;
-	int ret;
-
-	inode = dentry->d_inode;
-
-	_enter("{ ino=%lu v=%lu }",inode->i_ino,inode->i_version);
-
-	vnode = AFS_FS_I(inode);
-
-	ret = afs_inode_fetch_status(inode);
-	if (ret==-ENOENT) {
-		_leave(" = %d [%d %p]",ret,atomic_read(&dentry->d_count),dentry->d_inode);
-		return ret;
-	}
-	else if (ret<0) {
-		make_bad_inode(inode);
-		_leave(" = %d",ret);
-		return ret;
-	}
-
-	_leave(" = 0 CB { v=%u x=%u t=%u }",
-	       vnode->cb_version,
-	       vnode->cb_expiry,
-	       vnode->cb_type);
-
-	return 0;
-} /* end afs_inode_revalidate() */
-#endif
 
 /*****************************************************************************/
 /*
@@ -409,10 +262,6 @@
 	if (inode->i_ino!=vnode->fid.vnode) BUG();
 
 	afs_vnode_give_up_callback(vnode);
-
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
-	if (inode->u.generic_ip) kfree(inode->u.generic_ip);
-#endif
 
 	_leave("");
 } /* end afs_clear_inode() */
diff -Nru a/fs/afs/internal.h b/fs/afs/internal.h
--- a/fs/afs/internal.h	Mon Nov  4 14:31:01 2002
+++ b/fs/afs/internal.h	Mon Nov  4 14:31:01 2002
@@ -21,34 +21,24 @@
 /*
  * debug tracing
  */
-#define kenter(FMT,...)	printk("==> %s("FMT")\n",__FUNCTION__,##__VA_ARGS__)
-#define kleave(FMT,...)	printk("<== %s()"FMT"\n",__FUNCTION__,##__VA_ARGS__)
-#define kdebug(FMT,...)	printk(FMT"\n",##__VA_ARGS__)
-#define kproto(FMT,...)	printk("### "FMT"\n",##__VA_ARGS__)
-#define knet(FMT,...)	printk(FMT"\n",##__VA_ARGS__)
+#define kenter(FMT, a...)	printk("==> %s("FMT")\n",__FUNCTION__ , ## a)
+#define kleave(FMT, a...)	printk("<== %s()"FMT"\n",__FUNCTION__ , ## a)
+#define kdebug(FMT, a...)	printk(FMT"\n" , ## a)
+#define kproto(FMT, a...)	printk("### "FMT"\n" , ## a)
+#define knet(FMT, a...)		printk(FMT"\n" , ## a)
 
 #if 0
-#define _enter(FMT,...)	kenter(FMT,##__VA_ARGS__)
-#define _leave(FMT,...)	kleave(FMT,##__VA_ARGS__)
-#define _debug(FMT,...)	kdebug(FMT,##__VA_ARGS__)
-#define _proto(FMT,...)	kproto(FMT,##__VA_ARGS__)
-#define _net(FMT,...)	knet(FMT,##__VA_ARGS__)
+#define _enter(FMT, a...)	kenter(FMT , ## a)
+#define _leave(FMT, a...)	kleave(FMT , ## a)
+#define _debug(FMT, a...)	kdebug(FMT , ## a)
+#define _proto(FMT, a...)	kproto(FMT , ## a)
+#define _net(FMT, a...)		knet(FMT , ## a)
 #else
-#define _enter(FMT,...)	do { } while(0)
-#define _leave(FMT,...)	do { } while(0)
-#define _debug(FMT,...)	do { } while(0)
-#define _proto(FMT,...)	do { } while(0)
-#define _net(FMT,...)	do { } while(0)
-#endif
-
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
-#define wait_on_page_locked wait_on_page
-#define PageUptodate Page_Uptodate
-
-static inline struct proc_dir_entry *PDE(const struct inode *inode)
-{
-	return (struct proc_dir_entry *)inode->u.generic_ip;
-}
+#define _enter(FMT, a...)	do { } while(0)
+#define _leave(FMT, a...)	do { } while(0)
+#define _debug(FMT, a...)	do { } while(0)
+#define _proto(FMT, a...)	do { } while(0)
+#define _net(FMT, a...)		do { } while(0)
 #endif
 
 static inline void afs_discard_my_signals(void)
@@ -85,12 +75,7 @@
  * inode.c
  */
 extern int afs_iget(struct super_block *sb, afs_fid_t *fid, struct inode **_inode);
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 extern int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat);
-#else
-extern void afs_read_inode2(struct inode *inode, void *opaque);
-extern int afs_inode_revalidate(struct dentry *dentry);
-#endif
 extern void afs_clear_inode(struct inode *inode);
 
 /*
@@ -113,7 +98,7 @@
 extern spinlock_t afs_cb_hash_lock;
 
 #define afs_cb_hash(SRV,FID) \
-	afs_cb_hash_tbl[((unsigned)(SRV) + (FID)->vid + (FID)->vnode + (FID)->unique) % \
+	afs_cb_hash_tbl[((unsigned long)(SRV) + (FID)->vid + (FID)->vnode + (FID)->unique) % \
 			AFS_CB_HASH_COUNT]
 
 /*
diff -Nru a/fs/afs/kafsasyncd.c b/fs/afs/kafsasyncd.c
--- a/fs/afs/kafsasyncd.c	Mon Nov  4 14:31:01 2002
+++ b/fs/afs/kafsasyncd.c	Mon Nov  4 14:31:01 2002
@@ -103,11 +103,7 @@
 	/* only certain signals are of interest */
 	spin_lock_irq(&current->sig->siglock);
 	siginitsetinv(&current->blocked,0);
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,3)
 	recalc_sigpending();
-#else
-	recalc_sigpending(current);
-#endif
 	spin_unlock_irq(&current->sig->siglock);
 
 	/* loop around looking for things to attend to */
diff -Nru a/fs/afs/kafstimod.c b/fs/afs/kafstimod.c
--- a/fs/afs/kafstimod.c	Mon Nov  4 14:31:02 2002
+++ b/fs/afs/kafstimod.c	Mon Nov  4 14:31:02 2002
@@ -80,11 +80,7 @@
 	/* only certain signals are of interest */
 	spin_lock_irq(&current->sig->siglock);
 	siginitsetinv(&current->blocked,0);
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,3)
 	recalc_sigpending();
-#else
-	recalc_sigpending(current);
-#endif
 	spin_unlock_irq(&current->sig->siglock);
 
 	/* loop around looking for things to attend to */
diff -Nru a/fs/afs/main.c b/fs/afs/main.c
--- a/fs/afs/main.c	Mon Nov  4 14:31:01 2002
+++ b/fs/afs/main.c	Mon Nov  4 14:31:01 2002
@@ -173,8 +173,8 @@
 
 	_debug("Discarding peer %08x (rtt=%lu.%lumS)\n",
 	       ntohl(peer->addr.s_addr),
-	       peer->rtt/1000,
-	       peer->rtt%1000);
+	       (long)(peer->rtt/1000),
+	       (long)(peer->rtt%1000));
 
 	/* uncross-point the structs under a global lock */
 	spin_lock(&afs_server_peer_lock);
diff -Nru a/fs/afs/mntpt.c b/fs/afs/mntpt.c
--- a/fs/afs/mntpt.c	Mon Nov  4 14:31:01 2002
+++ b/fs/afs/mntpt.c	Mon Nov  4 14:31:01 2002
@@ -31,11 +31,7 @@
 struct inode_operations afs_mntpt_inode_operations = {
 	.lookup		= afs_mntpt_lookup,
 	.readlink	= page_readlink,
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	.getattr	= afs_inode_getattr,
-#else
-	.revalidate	= afs_inode_revalidate,
-#endif
 };
 
 /*****************************************************************************/
@@ -70,7 +66,7 @@
 
 	/* examine the symlink's contents */
 	size = vnode->status.size;
-	_debug("symlink to %*.*s",size,size,buf);
+	_debug("symlink to %*.*s",size,(int)size,buf);
 
 	if (size>2 &&
 	    (buf[0]=='%' || buf[0]=='#') &&
diff -Nru a/fs/afs/proc.c b/fs/afs/proc.c
--- a/fs/afs/proc.c	Mon Nov  4 14:31:01 2002
+++ b/fs/afs/proc.c	Mon Nov  4 14:31:01 2002
@@ -412,6 +412,7 @@
 
 	afs_put_cell(cell);
 
+	return ret;
 } /* end afs_proc_cell_volumes_release() */
 
 /*****************************************************************************/
@@ -536,6 +537,7 @@
 
 	afs_put_cell(cell);
 
+	return ret;
 } /* end afs_proc_cell_vlservers_release() */
 
 /*****************************************************************************/
@@ -651,6 +653,7 @@
 
 	afs_put_cell(cell);
 
+	return ret;
 } /* end afs_proc_cell_servers_release() */
 
 /*****************************************************************************/
diff -Nru a/fs/afs/super.c b/fs/afs/super.c
--- a/fs/afs/super.c	Mon Nov  4 14:31:01 2002
+++ b/fs/afs/super.c	Mon Nov  4 14:31:01 2002
@@ -39,12 +39,8 @@
 
 static void afs_i_init_once(void *foo, kmem_cache_t *cachep, unsigned long flags);
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 static struct super_block *afs_get_sb(struct file_system_type *fs_type,
 				      int flags, char *dev_name, void *data);
-#else
-static struct super_block *afs_read_super(struct super_block *sb, void *data, int);
-#endif
 
 static struct inode *afs_alloc_inode(struct super_block *sb);
 
@@ -55,30 +51,20 @@
 static struct file_system_type afs_fs_type = {
 	.owner		= THIS_MODULE,
 	.name		= "afs",
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	.get_sb		= afs_get_sb,
 	.kill_sb	= kill_anon_super,
-#else
-	.read_super	= afs_read_super,
-#endif
 };
 
 static struct super_operations afs_super_ops = {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	.statfs		= simple_statfs,
 	.alloc_inode	= afs_alloc_inode,
 	.drop_inode	= generic_delete_inode,
 	.destroy_inode	= afs_destroy_inode,
-#else
-	.read_inode2	= afs_read_inode2,
-#endif
 	.clear_inode	= afs_clear_inode,
 	.put_super	= afs_put_super,
 };
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 static kmem_cache_t *afs_inode_cachep;
-#endif
 
 /*****************************************************************************/
 /*
@@ -90,23 +76,6 @@
 
 	kenter("");
 
-	/* open the cache */
-#if 0
-	ret = -EINVAL;
-	if (!cachedev) {
-		printk(KERN_NOTICE "kAFS: No cache device specified as module parm\n");
-		printk(KERN_NOTICE "kAFS: Set with \"cachedev=<devname>\" on insmod's cmdline\n");
-		return ret;
-	}
-
-	ret = afs_cache_open(cachedev,&afs_cache);
-	if (ret<0) {
-		printk(KERN_NOTICE "kAFS: Failed to open cache device\n");
-		return ret;
-	}
-#endif
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	/* create ourselves an inode cache */
 	ret = -ENOMEM;
 	afs_inode_cachep = kmem_cache_create("afs_inode_cache",
@@ -117,22 +86,13 @@
 						NULL);
 	if (!afs_inode_cachep) {
 		printk(KERN_NOTICE "kAFS: Failed to allocate inode cache\n");
-#if 0
-		afs_put_cache(afs_cache);
-#endif
 		return ret;
 	}
-#endif
 
 	/* now export our filesystem to lesser mortals */
 	ret = register_filesystem(&afs_fs_type);
 	if (ret<0) {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 		kmem_cache_destroy(afs_inode_cachep);
-#endif
-#if 0
-		afs_put_cache(afs_cache);
-#endif
 		kleave(" = %d",ret);
 		return ret;
 	}
@@ -148,16 +108,10 @@
 void __exit afs_fs_exit(void)
 {
 	/* destroy our private inode cache */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	kmem_cache_destroy(afs_inode_cachep);
-#endif
 
 	unregister_filesystem(&afs_fs_type);
 
-#if 0
-	if (afs_cache)
-		afs_put_cache(afs_cache);
-#endif
 } /* end afs_fs_exit() */
 
 /*****************************************************************************/
@@ -453,7 +407,6 @@
  * get an AFS superblock
  * - TODO: don't use get_sb_nodev(), but rather call sget() directly
  */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 static struct super_block *afs_get_sb(struct file_system_type *fs_type,
 				      int flags,
 				      char *dev_name,
@@ -482,39 +435,6 @@
 	_leave("");
 	return sb;
 } /* end afs_get_sb() */
-#endif
-
-/*****************************************************************************/
-/*
- * read an AFS superblock
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-static struct super_block *afs_read_super(struct super_block *sb, void *options, int silent)
-{
-	void *data[2] = { NULL, options };
-	int ret;
-
-	_enter(",,%s",(char*)options);
-
-	/* start the cache manager */
-	ret = afscm_start();
-	if (ret<0) {
-		_leave(" = NULL (%d)",ret);
-		return NULL;
-	}
-
-	/* allocate a deviceless superblock */
-	ret = afs_fill_super(sb,data,silent);
-	if (ret<0) {
-		afscm_stop();
-		_leave(" = NULL (%d)",ret);
-		return NULL;
-	}
-
-	_leave(" = %p",sb);
-	return sb;
-} /* end afs_read_super() */
-#endif
 
 /*****************************************************************************/
 /*
@@ -540,7 +460,6 @@
 /*
  * initialise an inode cache slab element prior to any use
  */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 static void afs_i_init_once(void *_vnode, kmem_cache_t *cachep, unsigned long flags)
 {
 	afs_vnode_t *vnode = (afs_vnode_t *) _vnode;
@@ -556,13 +475,11 @@
 	}
 
 } /* end afs_i_init_once() */
-#endif
 
 /*****************************************************************************/
 /*
  * allocate an AFS inode struct from our slab cache
  */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 static struct inode *afs_alloc_inode(struct super_block *sb)
 {
 	afs_vnode_t *vnode;
@@ -580,16 +497,13 @@
 
 	return &vnode->vfs_inode;
 } /* end afs_alloc_inode() */
-#endif
 
 /*****************************************************************************/
 /*
  * destroy an AFS inode struct
  */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 static void afs_destroy_inode(struct inode *inode)
 {
 	_enter("{%lu}",inode->i_ino);
 	kmem_cache_free(afs_inode_cachep, AFS_FS_I(inode));
 } /* end afs_destroy_inode() */
-#endif
diff -Nru a/fs/afs/vlclient.c b/fs/afs/vlclient.c
--- a/fs/afs/vlclient.c	Mon Nov  4 14:31:00 2002
+++ b/fs/afs/vlclient.c	Mon Nov  4 14:31:00 2002
@@ -626,7 +626,7 @@
 	case RXRPC_CSTATE_CLNT_GOT_REPLY:
 		if (call->app_read_count==0)
 			break;
-		printk("kAFS: Reply bigger than expected {cst=%u asyn=%d mark=%d rdy=%u pr=%u%s}",
+		printk("kAFS: Reply bigger than expected {cst=%u asyn=%d mark=%Zu rdy=%Zu pr=%u%s}",
 		       call->app_call_state,
 		       call->app_async_read,
 		       call->app_mark,
diff -Nru a/fs/afs/vnode.h b/fs/afs/vnode.h
--- a/fs/afs/vnode.h	Mon Nov  4 14:31:00 2002
+++ b/fs/afs/vnode.h	Mon Nov  4 14:31:00 2002
@@ -27,11 +27,7 @@
  */
 struct afs_vnode
 {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	struct inode		vfs_inode;	/* the VFS's inode record */
-#else
-	struct inode		*inode;		/* the VFS's inode */
-#endif
 
 	afs_volume_t		*volume;	/* volume on which vnode resides */
 	afs_fid_t		fid;		/* the file identifier for this inode */
@@ -59,20 +55,12 @@
 
 static inline afs_vnode_t *AFS_FS_I(struct inode *inode)
 {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-	return list_entry(inode,afs_vnode_t,vfs_inode);
-#else
-	return inode->u.generic_ip;
-#endif
+	return container_of(inode,afs_vnode_t,vfs_inode);
 }
 
 static inline struct inode *AFS_VNODE_TO_I(afs_vnode_t *vnode)
 {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	return &vnode->vfs_inode;
-#else
-	return vnode->inode;
-#endif
 }
 
 extern int afs_vnode_fetch_status(afs_vnode_t *vnode);
diff -Nru a/fs/attr.c b/fs/attr.c
--- a/fs/attr.c	Mon Nov  4 14:31:00 2002
+++ b/fs/attr.c	Mon Nov  4 14:31:00 2002
@@ -95,7 +95,7 @@
 	return error;
 }
 
-static int setattr_mask(unsigned int ia_valid)
+int setattr_mask(unsigned int ia_valid)
 {
 	unsigned long dn_mask = 0;
 
diff -Nru a/fs/binfmt_aout.c b/fs/binfmt_aout.c
--- a/fs/binfmt_aout.c	Mon Nov  4 14:31:01 2002
+++ b/fs/binfmt_aout.c	Mon Nov  4 14:31:01 2002
@@ -307,6 +307,7 @@
 		(current->mm->start_data = N_DATADDR(ex));
 	current->mm->brk = ex.a_bss +
 		(current->mm->start_brk = N_BSSADDR(ex));
+	current->mm->free_area_cache = TASK_UNMAPPED_BASE;
 
 	current->mm->rss = 0;
 	current->mm->mmap = NULL;
@@ -425,8 +426,12 @@
 	regs->gp = ex.a_gpvalue;
 #endif
 	start_thread(regs, ex.a_entry, current->mm->start_stack);
-	if (current->ptrace & PT_PTRACED)
-		send_sig(SIGTRAP, current, 0);
+	if (unlikely(current->ptrace & PT_PTRACED)) {
+		if (current->ptrace & PT_TRACE_EXEC)
+			ptrace_notify ((PTRACE_EVENT_EXEC << 8) | SIGTRAP);
+		else
+			send_sig(SIGTRAP, current, 0);
+	}
 	return 0;
 }
 
diff -Nru a/fs/binfmt_elf.c b/fs/binfmt_elf.c
--- a/fs/binfmt_elf.c	Mon Nov  4 14:31:01 2002
+++ b/fs/binfmt_elf.c	Mon Nov  4 14:31:01 2002
@@ -619,6 +619,7 @@
 	/* Do this so that we can load the interpreter, if need be.  We will
 	   change some of these later */
 	current->mm->rss = 0;
+	current->mm->free_area_cache = TASK_UNMAPPED_BASE;
 	retval = setup_arg_pages(bprm);
 	if (retval < 0) {
 		send_sig(SIGKILL, current, 0);
@@ -792,8 +793,12 @@
 #endif
 
 	start_thread(regs, elf_entry, bprm->p);
-	if (current->ptrace & PT_PTRACED)
-		send_sig(SIGTRAP, current, 0);
+	if (unlikely(current->ptrace & PT_PTRACED)) {
+		if (current->ptrace & PT_TRACE_EXEC)
+			ptrace_notify ((PTRACE_EVENT_EXEC << 8) | SIGTRAP);
+		else
+			send_sig(SIGTRAP, current, 0);
+	}
 	retval = 0;
 out:
 	return retval;
diff -Nru a/fs/binfmt_flat.c b/fs/binfmt_flat.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/binfmt_flat.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,659 @@
+/*
+ *  linux/fs/binfmt_flat.c
+ *
+ *	Copyright (C) 2000, 2001 Lineo, by David McCullough <davidm@uclinux.org>
+ *	Copyright (C) 2002 Greg Ungerer <gerg@snapgear.com>
+ *
+ *  based heavily on:
+ *
+ *  linux/fs/binfmt_aout.c:
+ *      Copyright (C) 1991, 1992, 1996  Linus Torvalds
+ *  linux/fs/binfmt_flat.c for 2.0 kernel
+ *	Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>
+ *	JAN/99 -- coded full program relocation (gerg@snapgear.com)
+ */
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/a.out.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/stat.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+#include <linux/slab.h>
+#include <linux/binfmts.h>
+#include <linux/personality.h>
+#include <linux/init.h>
+#include <linux/flat.h>
+
+#include <asm/byteorder.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
+#include <asm/unaligned.h>
+#include <asm/cacheflush.h>
+
+#undef DEBUG
+#ifdef DEBUG
+#define	DBG_FLT(a...)	printk(##a)
+#else
+#define	DBG_FLT(a...)
+#endif
+
+static int load_flat_binary(struct linux_binprm *, struct pt_regs * regs);
+static int load_flat_library(struct file*);
+extern void dump_thread(struct pt_regs *, struct user *);
+
+static struct linux_binfmt flat_format = {
+	NULL, THIS_MODULE, load_flat_binary, load_flat_library, NULL, PAGE_SIZE
+};
+
+
+/*
+ * create_flat_tables() parses the env- and arg-strings in new user
+ * memory and creates the pointer tables from them, and puts their
+ * addresses on the "stack", returning the new stack pointer value.
+ */
+static unsigned long create_flat_tables(
+	unsigned long pp,
+	struct linux_binprm * bprm)
+{
+	unsigned long *argv,*envp;
+	unsigned long * sp;
+	char * p = (char*)pp;
+	int argc = bprm->argc;
+	int envc = bprm->envc;
+	char dummy;
+
+	sp = (unsigned long *) ((-(unsigned long)sizeof(char *))&(unsigned long) p);
+
+	sp -= envc+1;
+	envp = sp;
+	sp -= argc+1;
+	argv = sp;
+	put_user((unsigned long) envp, --sp);
+	put_user((unsigned long) argv, --sp);
+	put_user(argc,--sp);
+	current->mm->arg_start = (unsigned long) p;
+	while (argc-->0) {
+		put_user((unsigned long) p, argv++);
+		do {
+			get_user(dummy, p); p++;
+		} while (dummy);
+	}
+	put_user((unsigned long) NULL, argv);
+	current->mm->arg_end = current->mm->env_start = (unsigned long) p;
+	while (envc-->0) {
+		put_user((unsigned long)p, envp); envp++;
+		do {
+			get_user(dummy, p); p++;
+		} while (dummy);
+	}
+	put_user((unsigned long) NULL, envp);
+	current->mm->env_end = (unsigned long) p;
+	return (unsigned long)sp;
+}
+
+
+#ifdef CONFIG_BINFMT_ZFLAT
+
+#include <linux/zlib.h>
+
+#define LBUFSIZE	4000
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01 /* bit 0 set: file probably ASCII text */
+#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
+#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
+#define COMMENT      0x10 /* bit 4 set: file comment present */
+#define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
+#define RESERVED     0xC0 /* bit 6,7:   reserved */
+
+static int decompress_exec(
+	struct linux_binprm *bprm,
+	unsigned long offset,
+	char *dst,
+	long len,
+	int fd)
+{
+	unsigned char *buf;
+	z_stream strm;
+	loff_t fpos;
+	int ret;
+
+	DBG_FLT("decompress_exec(offset=%x,buf=%x,len=%x)\n",(int)offset, (int)dst, (int)len);
+
+	memset(&strm, 0, sizeof(strm));
+	strm.workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
+	if (strm.workspace == NULL) {
+		DBG_FLT("binfmt_flat: no memory for decompress workspace\n");
+		return -ENOMEM;
+	}
+	buf = kmalloc(LBUFSIZE, GFP_KERNEL);
+	if (buf == NULL) {
+		DBG_FLT("binfmt_flat: no memory for read buffer\n");
+		return -ENOMEM;
+	}
+
+	/* Read in first chunk of data and parse gzip header. */
+	fpos = offset;
+	ret = bprm->file->f_op->read(bprm->file, buf, LBUFSIZE, &fpos);
+
+	strm.next_in = buf;
+	strm.avail_in = ret;
+	strm.total_in = 0;
+
+	/* Check minimum size -- gzip header */
+	if (ret < 10) {
+		DBG_FLT("binfmt_flat: file too small?\n");
+		return -ENOEXEC;
+	}
+
+	/* Check gzip magic number */
+	if ((buf[0] != 037) || ((buf[1] != 0213) && (buf[1] != 0236))) {
+		DBG_FLT("binfmt_flat: unknown compression magic?\n");
+		return -ENOEXEC;
+	}
+
+	/* Check gzip method */
+	if (buf[2] != 8) {
+		DBG_FLT("binfmt_flat: unknown compression method?\n");
+		return -ENOEXEC;
+	}
+	/* Check gzip flags */
+	if ((buf[3] & ENCRYPTED) || (buf[3] & CONTINUATION) ||
+	    (buf[3] & RESERVED)) {
+		DBG_FLT("binfmt_flat: unknown flags?\n");
+		return -ENOEXEC;
+	}
+
+	ret = 10;
+	if (buf[3] & EXTRA_FIELD)
+		ret += 2 + buf[10] + (buf[11] << 8);
+	if (buf[3] & ORIG_NAME) {
+		for (; (buf[ret] != 0); ret++)
+			;
+	}
+	if (buf[3] & COMMENT) {
+		for (; (buf[ret] != 0); ret++)
+			;
+	}
+
+	strm.next_in += ret;
+	strm.avail_in -= ret;
+
+	strm.next_out = dst;
+	strm.avail_out = len;
+	strm.total_out = 0;
+
+	if (zlib_inflateInit2(&strm, -MAX_WBITS) != Z_OK) {
+		DBG_FLT("binfmt_flat: zlib init failed?\n");
+		return -ENOEXEC;
+	}
+
+	while ((ret = zlib_inflate(&strm, Z_NO_FLUSH)) == Z_OK) {
+		ret = bprm->file->f_op->read(bprm->file, buf, LBUFSIZE, &fpos);
+		if (ret == 0)
+			break;
+		if (ret >= (unsigned long) -4096)
+			break;
+		len -= ret;
+
+		strm.next_in = buf;
+		strm.avail_in = ret;
+		strm.total_in = 0;
+	}
+
+	if (ret < 0) {
+		DBG_FLT("binfmt_flat: decompression failed (%d), %s\n",
+			ret, strm.msg);
+		return -ENOEXEC;
+	}
+
+	zlib_inflateEnd(&strm);
+	kfree(buf);
+	kfree(strm.workspace);
+	return 0;
+}
+
+#endif /* CONFIG_BINFMT_ZFLAT */
+
+
+static unsigned long
+calc_reloc(unsigned long r, unsigned long text_len)
+{
+	unsigned long addr;
+
+	if (r > current->mm->start_brk - current->mm->start_data + text_len) {
+		printk("BINFMT_FLAT: reloc outside program 0x%x (0 - 0x%x), killing!\n",
+				(int) r,(int)(current->mm->start_brk-current->mm->start_code));
+		send_sig(SIGSEGV, current, 0);
+		return(current->mm->start_brk); /* return something safe to write to */
+	}
+
+	if (r < text_len) {
+		/* In text segment */
+		return r + current->mm->start_code;
+	}
+
+	/*
+	 * we allow inclusive ranges here so that programs may do things
+	 * like reference the end of data (_end) without failing these tests
+	 */
+	addr =  r - text_len + current->mm->start_data;
+	if (addr >= current->mm->start_code &&
+			addr <= current->mm->start_code + text_len)
+		return(addr);
+
+	if (addr >= current->mm->start_data &&
+			addr <= current->mm->start_brk)
+		return(addr);
+
+	printk("BINFMT_FLAT: reloc addr outside text/data 0x%x "
+			"code(0x%x - 0x%x) data(0x%x - 0x%x) killing\n", (int) addr,
+			(int) current->mm->start_code,
+			(int) (current->mm->start_code + text_len),
+			(int) current->mm->start_data,
+			(int) current->mm->start_brk);
+	send_sig(SIGSEGV, current, 0);
+
+	return(current->mm->start_brk); /* return something safe to write to */
+}
+
+
+void old_reloc(unsigned long rl)
+{
+#ifdef DEBUG
+	char *segment[] = { "TEXT", "DATA", "BSS", "*UNKNOWN*" };
+#endif
+	flat_v2_reloc_t	r;
+	unsigned long *ptr;
+	
+	r.value = rl;
+#if defined(CONFIG_COLDFIRE)
+	ptr = (unsigned long *) (current->mm->start_code + r.reloc.offset);
+#else
+	ptr = (unsigned long *) (current->mm->start_data + r.reloc.offset);
+#endif
+
+#ifdef DEBUG
+	printk("Relocation of variable at DATASEG+%x "
+		"(address %p, currently %x) into segment %s\n",
+		r.reloc.offset, ptr, (int)*ptr, segment[r.reloc.type]);
+#endif
+	
+	switch (r.reloc.type) {
+	case OLD_FLAT_RELOC_TYPE_TEXT:
+		*ptr += current->mm->start_code;
+		break;
+	case OLD_FLAT_RELOC_TYPE_DATA:
+		*ptr += current->mm->start_data;
+		break;
+	case OLD_FLAT_RELOC_TYPE_BSS:
+		*ptr += current->mm->end_data;
+		break;
+	default:
+		printk("BINFMT_FLAT: Unknown relocation type=%x\n", r.reloc.type);
+		break;
+	}
+
+#ifdef DEBUG
+	printk("Relocation became %x\n", (int)*ptr);
+#endif
+}		
+
+
+/*
+ * These are the functions used to load flat style executables and shared
+ * libraries.  There is no binary dependent code anywhere else.
+ */
+
+static int load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs)
+{
+	struct flat_hdr * hdr;
+	unsigned long textpos = 0, datapos = 0, result;
+	unsigned long text_len, data_len, bss_len, stack_len, flags;
+	unsigned long memp = 0, memkasked = 0; /* for finding the brk area */
+	unsigned long extra, rlim;
+	unsigned long p = bprm->p;
+	unsigned long *reloc = 0, *rp;
+	struct inode *inode;
+	int i, rev, relocs = 0;
+	loff_t fpos;
+
+	DBG_FLT("BINFMT_FLAT: Loading file: %x\n", bprm->file);
+
+	hdr = ((struct flat_hdr *) bprm->buf);		/* exec-header */
+	inode = bprm->file->f_dentry->d_inode;
+
+	text_len  = ntohl(hdr->data_start);
+	data_len  = ntohl(hdr->data_end) - ntohl(hdr->data_start);
+	bss_len   = ntohl(hdr->bss_end) - ntohl(hdr->data_end);
+	stack_len = ntohl(hdr->stack_size);
+	relocs    = ntohl(hdr->reloc_count);
+	flags     = ntohl(hdr->flags);
+	rev       = ntohl(hdr->rev);
+
+	/*
+	 * We have to add the size of our arguments to our stack size
+	 * otherwise it's too easy for users to create stack overflows
+	 * by passing in a huge argument list.  And yes,  we have to be
+	 * pedantic and include space for the argv/envp array as it may have
+	 * a lot of entries.
+	 */
+	#define TOP_OF_ARGS (PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *))
+	stack_len += TOP_OF_ARGS - bprm->p;             /* the strings */
+	stack_len += (bprm->argc + 1) * sizeof(char *); /* the argv array */
+	stack_len += (bprm->envc + 1) * sizeof(char *); /* the envp array */
+
+	if (strncmp(hdr->magic, "bFLT", 4) ||
+			(rev != FLAT_VERSION && rev != OLD_FLAT_VERSION)) {
+		/*
+		 * because a lot of people do not manage to produce good
+		 * flat binaries,  we leave this printk to help them realise
+		 * the problem.  We only print the error if its * not a script file
+		 */
+		if (strncmp(hdr->magic, "#!", 2))
+			printk("BINFMT_FLAT: bad magic/rev (0x%x, need 0x%x)\n",
+					rev, (int) FLAT_VERSION);
+		return -ENOEXEC;
+	}
+
+	/*
+	 * fix up the flags for the older format,  there were all kinds
+	 * of endian hacks,  this only works for the simple cases
+	 */
+	if (rev == OLD_FLAT_VERSION && flags)
+		flags = FLAT_FLAG_RAM;
+
+#ifndef CONFIG_BINFMT_ZFLAT
+	if (flags & (FLAT_FLAG_GZIP|FLAT_FLAG_GZDATA)) {
+		printk("Support for ZFLAT executables is not enabled.\n");
+		return -ENOEXEC;
+	}
+#endif
+
+	/*
+	 * Check initial limits. This avoids letting people circumvent
+	 * size limits imposed on them by creating programs with large
+	 * arrays in the data or bss.
+	 */
+	rlim = current->rlim[RLIMIT_DATA].rlim_cur;
+	if (rlim >= RLIM_INFINITY)
+		rlim = ~0;
+	if (data_len + bss_len > rlim)
+		return -ENOMEM;
+
+	/* Flush all traces of the currently running executable */
+	result = flush_old_exec(bprm);
+	if (result)
+		return result;
+
+	/* OK, This is the point of no return */
+	set_personality(PER_LINUX);
+
+	/*
+	 * there are a couple of cases here,  the seperate code/data
+	 * case,  and then the fully copied to RAM case which lumps
+	 * it all together.
+	 */
+	if ((flags & (FLAT_FLAG_RAM|FLAT_FLAG_GZIP)) == 0) {
+		/*
+		 * this should give us a ROM ptr,  but if it doesn't we don't
+		 * really care
+		 */
+		DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n");
+
+		down_write(&current->mm->mmap_sem);
+		textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, 0, 0);
+		up_write(&current->mm->mmap_sem);
+		if (!textpos  || textpos >= (unsigned long) -4096) {
+			if (!textpos)
+				textpos = (unsigned long) -ENOMEM;
+			printk("Unable to mmap process text, errno %d\n", (int)-textpos);
+		}
+
+		extra = max(bss_len + stack_len, relocs * sizeof(unsigned long)),
+
+		down_write(&current->mm->mmap_sem);
+		datapos = do_mmap(0, 0, data_len + extra,
+				PROT_READ|PROT_WRITE|PROT_EXEC, 0, 0);
+		up_write(&current->mm->mmap_sem);
+
+		if (datapos == 0 || datapos >= (unsigned long)-4096) {
+			if (!datapos)
+				datapos = (unsigned long) -ENOMEM;
+			printk("Unable to allocate RAM for process data, errno %d\n",
+					(int)-datapos);
+			do_munmap(current->mm, textpos, text_len);
+			return datapos;
+		}
+
+		DBG_FLT("BINFMT_FLAT: Allocated data+bss+stack (%d bytes): %x\n",
+				data_len + bss_len + stack_len, datapos);
+
+		fpos = ntohl(hdr->data_start);
+#ifdef CONFIG_BINFMT_ZFLAT
+		if (flags & FLAT_FLAG_GZDATA) {
+			result = decompress_exec(bprm, fpos, (char *) datapos, 
+						 data_len + (relocs * sizeof(unsigned long)), 0);
+		} else
+#endif
+		{
+			result = bprm->file->f_op->read(bprm->file,
+					(char *) datapos, data_len + extra, &fpos);
+		}
+		if (result >= (unsigned long)-4096) {
+			printk("Unable to read data+bss, errno %d\n", (int)-result);
+			do_munmap(current->mm, textpos, text_len);
+			do_munmap(current->mm, datapos, data_len + extra);
+			return result;
+		}
+
+		reloc = (unsigned long *) (datapos+(ntohl(hdr->reloc_start)-text_len));
+		memp = datapos;
+		memkasked = data_len + extra;
+
+	} else {
+
+		/*
+		 * calculate the extra space we need to map in
+		 */
+
+		extra = max(bss_len + stack_len, relocs * sizeof(unsigned long)),
+
+		down_write(&current->mm->mmap_sem);
+		textpos = do_mmap(0, 0, text_len + data_len + extra,
+				PROT_READ | PROT_EXEC | PROT_WRITE, 0, 0);
+		up_write(&current->mm->mmap_sem);
+		if (!textpos  || textpos >= (unsigned long) -4096) {
+			if (!textpos)
+				textpos = (unsigned long) -ENOMEM;
+			printk("Unable to allocate RAM for process text/data, errno %d\n",
+					(int)-textpos);
+		}
+
+		datapos = textpos + ntohl (hdr->data_start);
+		reloc = (unsigned long *) (textpos + ntohl(hdr->reloc_start));
+		memp = textpos;
+		memkasked = text_len + data_len + extra;
+
+#ifdef CONFIG_BINFMT_ZFLAT
+		/*
+		 * load it all in and treat it like a RAM load from now on
+		 */
+		if (flags & FLAT_FLAG_GZIP) {
+			result = decompress_exec(bprm, sizeof (struct flat_hdr),
+					 (((char *) textpos) + sizeof (struct flat_hdr)),
+					 (text_len + data_len + (relocs * sizeof(unsigned long))
+						  - sizeof (struct flat_hdr)),
+					 0);
+		} else if (flags & FLAT_FLAG_GZDATA) {
+			fpos = 0;
+			result = bprm->file->f_op->read(bprm->file,
+					(char *) textpos, text_len, &fpos);
+			if (result < (unsigned long) -4096)
+				result = decompress_exec(bprm, text_len, (char *) datapos,
+						 data_len + (relocs * sizeof(unsigned long)), 0);
+		}
+		else
+#endif
+		{
+			fpos = 0;
+			result = bprm->file->f_op->read(bprm->file,
+					(char *) textpos, text_len + data_len + extra, &fpos);
+		}
+		if (result >= (unsigned long)-4096) {
+			printk("Unable to read code+data+bss, errno %d\n",(int)-result);
+			do_munmap(current->mm, textpos, text_len + data_len + extra);
+			return result;
+		}
+	}
+
+	DBG_FLT("Mapping is %x, Entry point is %x, data_start is %x\n",
+			textpos, ntohl(hdr->entry), ntohl(hdr->data_start));
+
+	current->mm->start_code = textpos + sizeof (struct flat_hdr);
+	current->mm->end_code = textpos + text_len;
+	current->mm->start_data = datapos;
+	current->mm->end_data = datapos + data_len;
+	/*
+	 *	set up the brk stuff (uses any slack left in data/bss/stack allocation
+	 *	We put the brk after the bss (between the bss and stack) like other
+	 *	platforms.
+	 */
+	current->mm->start_brk = datapos + data_len + bss_len;
+	current->mm->brk = (current->mm->start_brk + 3) & ~3;
+	current->mm->context.end_brk = memp + ksize((void *) memp) - stack_len;
+	current->mm->rss = 0;
+
+	DBG_FLT("Load %s: TEXT=%x-%x DATA=%x-%x BSS=%x-%x\n",
+		bprm->filename,
+		(int) current->mm->start_code, (int) current->mm->end_code,
+		(int) current->mm->start_data, (int) current->mm->end_data,
+		(int) current->mm->end_data, (int) current->mm->brk);
+
+	text_len -= sizeof(struct flat_hdr); /* the real code len */
+
+	/*
+	 * We just load the allocations into some temporary memory to
+	 * help simplify all this mumbo jumbo
+	 *
+	 * We've got two different sections of relocation entries.
+	 * The first is the GOT which resides at the begining of the data segment
+	 * and is terminated with a -1.  This one can be relocated in place.
+	 * The second is the extra relocation entries tacked after the image's
+	 * data segment. These require a little more processing as the entry is
+	 * really an offset into the image which contains an offset into the
+	 * image.
+	 */
+	
+	if (flags & FLAT_FLAG_GOTPIC) {
+		for (rp = (unsigned long *)datapos; *rp != 0xffffffff; rp++)
+			*rp = calc_reloc(*rp, text_len);
+	}
+
+	/*
+	 * Now run through the relocation entries.
+	 * We've got to be careful here as C++ produces relocatable zero
+	 * entries in the constructor and destructor tables which are then
+	 * tested for being not zero (which will always occur unless we're
+	 * based from address zero).  This causes an endless loop as __start
+	 * is at zero.  The solution used is to not relocate zero addresses.
+	 * This has the negative side effect of not allowing a global data
+	 * reference to be statically initialised to _stext (I've moved
+	 * __start to address 4 so that is okay).
+	 */
+
+	if (rev > OLD_FLAT_VERSION) {
+		for (i=0; i < relocs; i++) {
+			unsigned long addr;
+
+			/* Get the address of the pointer to be
+			   relocated (of course, the address has to be
+			   relocated first).  */
+			rp = (unsigned long *) calc_reloc(ntohl(reloc[i]), text_len);
+
+			/* Get the pointer's value.  */
+			addr = get_unaligned (rp);
+
+			if (addr != 0) {
+				/*
+				 * Do the relocation.  PIC relocs in the data section are
+				 * already in target order
+				 */
+				addr = calc_reloc(
+						(flags & FLAT_FLAG_GOTPIC) ? addr : ntohl(addr),
+						text_len);
+				/* Write back the relocated pointer.  */
+				put_unaligned (addr, rp);
+			}
+		}
+	} else {
+		for (i=0; i < relocs; i++)
+			old_reloc(ntohl(reloc[i]));
+	}
+
+	/* zero the BSS,  BRK and stack areas */
+	memset((void*)(datapos + data_len), 0, bss_len + 
+			(current->mm->context.end_brk - current->mm->start_brk) +
+			stack_len);
+
+	compute_creds(bprm);
+ 	current->flags &= ~PF_FORKNOEXEC;
+
+	flush_icache_range(current->mm->start_code, current->mm->end_code);
+
+	set_binfmt(&flat_format);
+
+	p = ((current->mm->context.end_brk + stack_len + 3) & ~3) - 4;
+	DBG_FLT("p=%x\n", p);
+
+	/* copy the arg pages onto the stack, this could be more efficient :-) */
+	for (i = TOP_OF_ARGS - 1; i >= bprm->p; i--)
+		* (char *) --p =
+			((char *) page_address(bprm->page[i/PAGE_SIZE]))[i % PAGE_SIZE];
+
+	current->mm->start_stack = (unsigned long) create_flat_tables(p, bprm);
+
+	DBG_FLT("start_thread(regs=0x%x, entry=0x%x, start_stack=0x%x)\n",
+		regs, textpos + ntohl(hdr->entry), current->mm->start_stack);
+	start_thread(regs,
+		     textpos + ntohl(hdr->entry),
+		     current->mm->start_stack);
+
+	if (current->ptrace & PT_PTRACED)
+		send_sig(SIGTRAP, current, 0);
+
+	return 0;
+}
+
+static int load_flat_library(struct file *file)
+{
+	return(-ENOEXEC);
+}
+
+static int __init init_flat_binfmt(void)
+{
+	return register_binfmt(&flat_format);
+}
+
+static void __exit exit_flat_binfmt(void)
+{
+	unregister_binfmt(&flat_format);
+}
+
+EXPORT_NO_SYMBOLS;
+
+module_init(init_flat_binfmt);
+module_exit(exit_flat_binfmt);
diff -Nru a/fs/binfmt_som.c b/fs/binfmt_som.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/binfmt_som.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,329 @@
+/*
+ * linux/fs/binfmt_som.c
+ *
+ * These are the functions used to load SOM format executables as used
+ * by HP-UX.  
+ *
+ * Copyright 1999 Matthew Wilcox <willy@bofh.ai>
+ * based on binfmt_elf which is
+ * Copyright 1993, 1994: Eric Youngdale (ericy@cais.com).
+ */
+
+#include <linux/module.h>
+
+#include <linux/fs.h>
+#include <linux/stat.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/binfmts.h>
+#include <linux/som.h>
+#include <linux/string.h>
+#include <linux/file.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/shm.h>
+#include <linux/personality.h>
+#include <linux/init.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+
+#include <linux/config.h>
+
+#include <linux/elf.h>
+
+static int load_som_binary(struct linux_binprm * bprm, struct pt_regs * regs);
+static int load_som_library(struct file *);
+
+/*
+ * If we don't support core dumping, then supply a NULL so we
+ * don't even try.
+ */
+#if 0
+static int som_core_dump(long signr, struct pt_regs * regs);
+#else
+#define som_core_dump	NULL
+#endif
+
+#define SOM_PAGESTART(_v) ((_v) & ~(unsigned long)(SOM_PAGESIZE-1))
+#define SOM_PAGEOFFSET(_v) ((_v) & (SOM_PAGESIZE-1))
+#define SOM_PAGEALIGN(_v) (((_v) + SOM_PAGESIZE - 1) & ~(SOM_PAGESIZE - 1))
+
+static struct linux_binfmt som_format = {
+	NULL, THIS_MODULE, load_som_binary, load_som_library, som_core_dump, SOM_PAGESIZE
+};
+
+/*
+ * create_som_tables() parses the env- and arg-strings in new user
+ * memory and creates the pointer tables from them, and puts their
+ * addresses on the "stack", returning the new stack pointer value.
+ */
+static void create_som_tables(struct linux_binprm *bprm)
+{
+	char **argv, **envp;
+	int argc = bprm->argc;
+	int envc = bprm->envc;
+	unsigned long p;
+	unsigned long *sp;
+
+	/* Word-align the stack pointer */
+	sp = (unsigned long *)((bprm->p + 3) & ~3);
+
+	envp = (char **) sp;
+	sp += envc + 1;
+	argv = (char **) sp;
+	sp += argc + 1;
+
+	__put_user((unsigned long) envp,++sp);
+	__put_user((unsigned long) argv,++sp);
+
+	__put_user(argc, ++sp);
+
+	bprm->p = (unsigned long) sp;
+
+	p = current->mm->arg_start;
+	while (argc-- > 0) {
+		__put_user((char *)p,argv++);
+		p += strlen_user((char *)p);
+	}
+	__put_user(NULL, argv);
+	current->mm->arg_end = current->mm->env_start = p;
+	while (envc-- > 0) {
+		__put_user((char *)p,envp++);
+		p += strlen_user((char *)p);
+	}
+	__put_user(NULL, envp);
+	current->mm->env_end = p;
+}
+
+static int check_som_header(struct som_hdr *som_ex)
+{
+	int *buf = (int *)som_ex;
+	int i, ck;
+
+	if (som_ex->system_id != SOM_SID_PARISC_1_0 &&
+	    som_ex->system_id != SOM_SID_PARISC_1_1 &&
+	    som_ex->system_id != SOM_SID_PARISC_2_0)
+		return -ENOEXEC;
+
+	if (som_ex->a_magic != SOM_EXEC_NONSHARE &&
+	    som_ex->a_magic != SOM_EXEC_SHARE &&
+	    som_ex->a_magic != SOM_EXEC_DEMAND)
+		return -ENOEXEC;
+
+	if (som_ex->version_id != SOM_ID_OLD &&
+	    som_ex->version_id != SOM_ID_NEW)
+		return -ENOEXEC;
+
+	ck = 0;
+	for (i=0; i<32; i++)
+		ck ^= buf[i];
+	if (ck != 0)
+		return -ENOEXEC;
+
+	return 0;
+}
+
+static int map_som_binary(struct file *file,
+		const struct som_exec_auxhdr *hpuxhdr)
+{
+	unsigned long code_start, code_size, data_start, data_size;
+	unsigned long bss_start, som_brk;
+	int retval;
+	int prot = PROT_READ | PROT_EXEC;
+	int flags = MAP_FIXED|MAP_PRIVATE|MAP_DENYWRITE|MAP_EXECUTABLE;
+
+	mm_segment_t old_fs = get_fs();
+	set_fs(get_ds());
+
+	code_start = SOM_PAGESTART(hpuxhdr->exec_tmem);
+	code_size = SOM_PAGEALIGN(hpuxhdr->exec_tsize);
+	current->mm->start_code = code_start;
+	current->mm->end_code = code_start + code_size;
+	down_write(&current->mm->mmap_sem);
+	retval = do_mmap(file, code_start, code_size, prot,
+			flags, SOM_PAGESTART(hpuxhdr->exec_tfile));
+	up_write(&current->mm->mmap_sem);
+	if (retval < 0 && retval > -1024)
+		goto out;
+
+	data_start = SOM_PAGESTART(hpuxhdr->exec_dmem);
+	data_size = SOM_PAGEALIGN(hpuxhdr->exec_dsize);
+	current->mm->start_data = data_start;
+	current->mm->end_data = bss_start = data_start + data_size;
+	down_write(&current->mm->mmap_sem);
+	retval = do_mmap(file, data_start, data_size,
+			prot | PROT_WRITE, flags,
+			SOM_PAGESTART(hpuxhdr->exec_dfile));
+	up_write(&current->mm->mmap_sem);
+	if (retval < 0 && retval > -1024)
+		goto out;
+
+	som_brk = bss_start + SOM_PAGEALIGN(hpuxhdr->exec_bsize);
+	current->mm->start_brk = current->mm->brk = som_brk;
+	down_write(&current->mm->mmap_sem);
+	retval = do_mmap(NULL, bss_start, som_brk - bss_start,
+			prot | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, 0);
+	up_write(&current->mm->mmap_sem);
+	if (retval > 0 || retval < -1024)
+		retval = 0;
+out:
+	set_fs(old_fs);
+	return retval;
+}
+
+
+/*
+ * These are the functions used to load SOM executables and shared
+ * libraries.  There is no binary dependent code anywhere else.
+ */
+
+static inline int
+do_load_som_binary(struct linux_binprm * bprm, struct pt_regs * regs)
+{
+	int som_exec_fileno;
+	int retval;
+	unsigned int size;
+	unsigned long som_entry;
+	struct som_hdr *som_ex;
+	struct som_exec_auxhdr *hpuxhdr;
+
+	/* Get the exec-header */
+	som_ex = (struct som_hdr *) bprm->buf;
+
+	retval = check_som_header(som_ex);
+	if (retval != 0)
+		goto out;
+
+	/* Now read in the auxiliary header information */
+
+	retval = -ENOMEM;
+	size = som_ex->aux_header_size;
+	if (size > SOM_PAGESIZE)
+		goto out;
+	hpuxhdr = (struct som_exec_auxhdr *) kmalloc(size, GFP_KERNEL);
+	if (!hpuxhdr)
+		goto out;
+
+	retval = kernel_read(bprm->file, som_ex->aux_header_location,
+			(char *) hpuxhdr, size);
+	if (retval < 0)
+		goto out_free;
+
+	retval = get_unused_fd();
+	if (retval < 0)
+		goto out_free;
+	get_file(bprm->file);
+	fd_install(som_exec_fileno = retval, bprm->file);
+
+	/* Flush all traces of the currently running executable */
+	retval = flush_old_exec(bprm);
+	if (retval)
+		goto out_free;
+
+	/* OK, This is the point of no return */
+	current->flags &= ~PF_FORKNOEXEC;
+	current->personality = PER_HPUX;
+
+	/* Set the task size for HP-UX processes such that
+	 * the gateway page is outside the address space.
+	 * This can be fixed later, but for now, this is much
+	 * easier.
+	 */
+
+	current->thread.task_size = 0xc0000000;
+
+	/* Set map base to allow enough room for hp-ux heap growth */
+
+	current->thread.map_base = 0x80000000;
+
+	retval = map_som_binary(bprm->file, hpuxhdr);
+	if (retval < 0)
+		goto out_free;
+
+	som_entry = hpuxhdr->exec_entry;
+	kfree(hpuxhdr);
+
+	set_binfmt(&som_format);
+	compute_creds(bprm);
+	setup_arg_pages(bprm);
+
+	create_som_tables(bprm);
+
+	current->mm->start_stack = bprm->p;
+	current->mm->rss = 0;
+
+#if 0
+	printk("(start_brk) %08lx\n" , (unsigned long) current->mm->start_brk);
+	printk("(end_code) %08lx\n" , (unsigned long) current->mm->end_code);
+	printk("(start_code) %08lx\n" , (unsigned long) current->mm->start_code);
+	printk("(end_data) %08lx\n" , (unsigned long) current->mm->end_data);
+	printk("(start_stack) %08lx\n" , (unsigned long) current->mm->start_stack);
+	printk("(brk) %08lx\n" , (unsigned long) current->mm->brk);
+#endif
+
+	map_hpux_gateway_page(current,current->mm);
+
+	start_thread_som(regs, som_entry, bprm->p);
+	if (current->ptrace & PT_PTRACED)
+		send_sig(SIGTRAP, current, 0);
+	return 0;
+
+	/* error cleanup */
+out_free:
+	kfree(hpuxhdr);
+out:
+	return retval;
+}
+
+static int
+load_som_binary(struct linux_binprm * bprm, struct pt_regs * regs)
+{
+	int retval;
+
+	MOD_INC_USE_COUNT;
+	retval = do_load_som_binary(bprm, regs);
+	MOD_DEC_USE_COUNT;
+	return retval;
+}
+
+static inline int
+do_load_som_library(struct file *f)
+{
+/* No lib support in SOM yet.  gizza chance.. */
+	return -ENOEXEC;
+}
+
+static int load_som_library(struct file *f)
+{
+	int retval;
+
+	MOD_INC_USE_COUNT;
+	retval = do_load_som_library(f);
+	MOD_DEC_USE_COUNT;
+	return retval;
+}
+
+	/* Install the SOM loader.
+	 * N.B. We *rely* on the table being the right size with the
+	 * right number of free slots...
+	 */
+
+static int __init init_som_binfmt(void)
+{
+	return register_binfmt(&som_format);
+}
+
+static void __exit exit_som_binfmt(void)
+{
+	/* Remove the SOM loader. */
+	unregister_binfmt(&som_format);
+}
+
+module_init(init_som_binfmt);
+module_exit(exit_som_binfmt);
+
diff -Nru a/fs/cifs/AUTHORS b/fs/cifs/AUTHORS
--- a/fs/cifs/AUTHORS	Mon Nov  4 14:31:00 2002
+++ b/fs/cifs/AUTHORS	Mon Nov  4 14:31:00 2002
@@ -14,3 +14,9 @@
 the other members of the Storage Network Industry Association CIFS Technical
 Workgroup for their work specifying this highly complex protocol and finally
 thanks to the Samba team for their technical advice and encouragement.
+
+Patch Contributors
+------------------
+Zwane Mwaikambo
+Andi Kleen
+
diff -Nru a/fs/cifs/CHANGES b/fs/cifs/CHANGES
--- a/fs/cifs/CHANGES	Mon Nov  4 14:31:02 2002
+++ b/fs/cifs/CHANGES	Mon Nov  4 14:31:02 2002
@@ -1,3 +1,24 @@
+Version 0.58
+------------
+Changed read and write to go through pagecache. Added additional address space operations.
+Memory mapped operations now working.
+
+Version 0.57
+------------
+Added writepage code for additional memory mapping support.  Fixed leak in xids causing
+the simultaneous operations counter (/proc/fs/cifs/SimultaneousOps) to increase on 
+every stat call.  Additional formatting cleanup. 
+
+Version 0.56
+------------
+Fix bigendian bug in order of time conversion. Merge 2.5 to 2.4 version.  Formatting cleanup.   
+
+Version 0.55
+------------
+Fixes from Zwane Mwaikambo for adding missing return code checking in a few places.
+Also included a modified version of his fix to protect global list manipulation of
+the smb session and tree connection and mid related global variables.
+
 Version 0.54
 ------------
 Fix problem with captive thread hanging around at unmount time.  Adjust to 2.5.42-pre
diff -Nru a/fs/cifs/TODO b/fs/cifs/TODO
--- a/fs/cifs/TODO	Mon Nov  4 14:31:01 2002
+++ b/fs/cifs/TODO	Mon Nov  4 14:31:01 2002
@@ -31,9 +31,6 @@
 
 j) finish off the mount helper, mount.cifs - (started)
 
-k) support for memory mapped files only partially works until support for
-MS_INVALIDATE implemented.  readpage and writepage code not finished (started)
-
 KNOWN BUGS (updated October 8nd, 2002)
 ====================================
 1) symbolic links (Windows reparse points) are recognized but
@@ -42,6 +39,8 @@
 symlink text beginning with slash
 2) delete of file with read-only attribute set will fail (may be ok)
 3) autoreconnection logic is only partially complete.
+4) there may be a problem with truncating a memmapped file to smaller than 4k with
+the size being reported as exactly 4k.
 
 Misc testing to do
 =================
diff -Nru a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
--- a/fs/cifs/cifs_debug.c	Mon Nov  4 14:31:01 2002
+++ b/fs/cifs/cifs_debug.c	Mon Nov  4 14:31:01 2002
@@ -79,18 +79,20 @@
 	buf += length;
 
 	i = 0;
+	read_lock(&GlobalSMBSeslock);
 	list_for_each(tmp, &GlobalSMBSessionList) {
 		i++;
 		ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
 		length =
 		    sprintf(buf,
-			    "\n%d) Name: %s  Domain: %s HowManyMounts: %d LocalUsersToSameServer: %d\n\t ServerOS: %s  ServerNOS: %s  Capabilities: 0x%x ",
-			    i, ses->serverName, ses->serverDomain,
-			    atomic_read(&ses->inUse),
-			    atomic_read(&ses->server->socketUseCount),
-			    ses->serverOS, ses->serverNOS, ses->capabilities);
+			    "\n%d) Name: %s  Domain: %s HowManyMounts: %d ServerOS: %s  ServerNOS: %s  Capabilities: 0x%x\n",
+				i, ses->serverName, ses->serverDomain, atomic_read(&ses->inUse),
+				ses->serverOS, ses->serverNOS, ses->capabilities);
 		buf += length;
+		if(ses->server)
+		buf += sprintf(buf, "\tLocal Users To Same Server: %d ",atomic_read(&ses->server->socketUseCount));
 	}
+	read_unlock(&GlobalSMBSeslock);
 	sprintf(buf, "\n");
 	buf++;
 	printk("\nTotal Buffer so far: %s\n", buf_start);
@@ -99,6 +101,7 @@
 	buf += length;
 
 	i = 0;
+	read_lock(&GlobalSMBSeslock);
 	list_for_each(tmp, &GlobalTreeConnectionList) {
 		i++;
 		tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
@@ -122,6 +125,7 @@
 				    tcon->fsDevInfo.DeviceType);
 		buf += length;
 	}
+	read_unlock(&GlobalSMBSeslock);
 	length = sprintf(buf, "\n");
 	buf += length;
 	*eof = 1;
@@ -156,22 +160,22 @@
 cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
 		  int length, int *eof, void *data)
 {
-   int item_length;
+	int item_length;
 	length =
 	    sprintf(buf,
 		    "Currently Allocated structures\nCIFS Sessions: %d\n",sesInfoAllocCount.counter);
-    buf += length;
-    item_length = 
-        sprintf(buf,"Shares (unique mount targets): %d\n",tconInfoAllocCount.counter);
-    length += item_length;
-    buf += item_length;      
-    item_length = 
-        sprintf(buf,"Allocated SMB Request and Response Buffers: %d\n",bufAllocCount.counter);
-    length += item_length;
-    buf += item_length;      
-    item_length = 
-        sprintf(buf,"Active Operations (MIDs in use): %d\n",midCount.counter);
-    length += item_length;
+	buf += length;
+	item_length = 
+		sprintf(buf,"Shares (unique mount targets): %d\n",tconInfoAllocCount.counter);
+	length += item_length;
+	buf += item_length;      
+	item_length = 
+			sprintf(buf,"Allocated SMB Request and Response Buffers: %d\n",bufAllocCount.counter);
+	length += item_length;
+	buf += item_length;      
+	item_length = 
+		sprintf(buf,"Active Operations (MIDs in use): %d\n",midCount.counter);
+	length += item_length;
 
 	return length;
 }
@@ -262,10 +266,13 @@
 	remove_proc_entry("DebugData", proc_fs_cifs);
 	remove_proc_entry("cifsFYI", proc_fs_cifs);
 	remove_proc_entry("TraceSMB", proc_fs_cifs);
-	remove_proc_entry("MaxSimultaneousOps", proc_fs_cifs);
+	remove_proc_entry("SimultaneousOps", proc_fs_cifs);
 	remove_proc_entry("TotalOps", proc_fs_cifs);
 	remove_proc_entry("MultiuserMount", proc_fs_cifs);
 	remove_proc_entry("oplockEnabled", proc_fs_cifs);
+	remove_proc_entry("NTLMV2Enabled",proc_fs_cifs);
+	remove_proc_entry("ExtendedSecurity",proc_fs_cifs);
+	remove_proc_entry("PacketSigningEnabled",proc_fs_cifs);
 	remove_proc_entry("cifs", proc_root_fs);
 }
 
diff -Nru a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
--- a/fs/cifs/cifsfs.c	Mon Nov  4 14:31:02 2002
+++ b/fs/cifs/cifsfs.c	Mon Nov  4 14:31:02 2002
@@ -64,8 +64,10 @@
 	struct cifs_sb_info *cifs_sb;
 	int rc = 0;
 
-    sb->s_fs_info = kmalloc(sizeof(struct cifs_sb_info),GFP_KERNEL);
+	sb->s_fs_info = kmalloc(sizeof(struct cifs_sb_info),GFP_KERNEL);
 	cifs_sb = CIFS_SB(sb);
+	if(cifs_sb == NULL)
+		return -ENOMEM;
 	cifs_sb->local_nls = load_nls_default();	/* needed for ASCII cp to Unicode converts */
 	rc = cifs_mount(sb, cifs_sb, data, devname);
 
@@ -97,13 +99,12 @@
 	if (inode)
 		iput(inode);
 
-/*	rc = cifs_umount(sb);  BB is CIFS unmount routine needed? */
 	if (rc) {
-		cERROR(1, ("cifs_umount failed with return code %d\n", rc));
+		cERROR(1, ("cifs_mount failed with no root inode"));
 	}
 out_mount_failed:
-    if(cifs_sb)
-        kfree(cifs_sb);
+	if(cifs_sb)
+		kfree(cifs_sb);
 	return -EINVAL;
 }
 
@@ -115,14 +116,16 @@
 
 	cFYI(1, ("In cifs_put_super\n"));
 	cifs_sb = CIFS_SB(sb);
-	rc = cifs_umount(sb, cifs_sb);	
+	if(cifs_sb == NULL) {
+		cFYI(1,("\nEmpty cifs superblock info passed to unmount"));
+		return;
+	}
+	rc = cifs_umount(sb, cifs_sb); 
 	if (rc) {
 		cERROR(1, ("cifs_umount failed with return code %d\n", rc));
 	}
-    if(cifs_sb) {    
-        unload_nls(cifs_sb->local_nls);
-        kfree(cifs_sb);
-    }
+	unload_nls(cifs_sb->local_nls);
+	kfree(cifs_sb);
 	return;
 }
 
@@ -155,7 +158,7 @@
 	   __fsid_t f_fsid;
 	   int f_namelen;  */
 	/* BB get from info put in tcon struct at mount time with call to QFSAttrInfo */
-
+	FreeXid(xid);
 	return 0;		/* always return success? what if volume is no longer available? */
 }
 
@@ -176,7 +179,7 @@
 	atomic_set(&cifs_inode->inUse, 0);
 	cifs_inode->time = 0;
 	cifs_inode->clientCanCache = 0;
-    INIT_LIST_HEAD(&cifs_inode->openFileList);
+	INIT_LIST_HEAD(&cifs_inode->openFileList);
 	return &cifs_inode->vfs_inode;
 }
 
@@ -258,6 +261,7 @@
 struct inode_operations cifs_dir_inode_ops = {
 	.create = cifs_create,
 	.lookup = cifs_lookup,
+	.getattr = cifs_getattr,
 	.unlink = cifs_unlink,
 	.link = cifs_hardlink,
 	.mkdir = cifs_mkdir,
@@ -271,6 +275,7 @@
 struct inode_operations cifs_file_inode_ops = {
 /*	revalidate:cifs_revalidate, */
 	.setattr = cifs_setattr,
+	.getattr = cifs_getattr,
 	.rename = cifs_rename,
 };
 
@@ -278,17 +283,18 @@
 	.readlink = cifs_readlink,
 	.follow_link = cifs_follow_link,
 	/* BB add the following two eventually */
-	/* revalidate:     cifs_revalidate,
-   setattr:        cifs_notify_change, *//* BB do we need notify change */
+	/* revalidate: cifs_revalidate,
+	   setattr:    cifs_notify_change, *//* BB do we need notify change */
 };
 
 struct file_operations cifs_file_ops = {
-	.read = cifs_read,
-	.write = cifs_write,
+	.read = generic_file_read,
+	.write = generic_file_write,
 	.open = cifs_open,
 	.release = cifs_close,
 	.lock = cifs_lock,
 	.fsync = cifs_fsync,
+	.mmap  = cifs_file_mmap,
 };
 
 struct file_operations cifs_dir_ops = {
@@ -387,8 +393,11 @@
 	atomic_set(&tconInfoAllocCount, 0);
 	atomic_set(&bufAllocCount, 0);
 	atomic_set(&midCount, 0);
+	GlobalCurrentXid = 0;
 	GlobalTotalActiveXid = 0;
 	GlobalMaxActiveXid = 0;
+	GlobalSMBSeslock = RW_LOCK_UNLOCKED;
+	GlobalMid_Lock = RW_LOCK_UNLOCKED;
 
 	rc = cifs_init_inodecache();
 	if (!rc) {
@@ -419,7 +428,7 @@
 #if CONFIG_PROC_FS
 	cifs_proc_clean();
 #endif
-    unregister_filesystem(&cifs_fs_type);
+    	unregister_filesystem(&cifs_fs_type);
 	cifs_destroy_inodecache();
 	cifs_destroy_mids();
 	cifs_destroy_request_bufs();
diff -Nru a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
--- a/fs/cifs/cifsfs.h	Mon Nov  4 14:31:01 2002
+++ b/fs/cifs/cifsfs.h	Mon Nov  4 14:31:01 2002
@@ -55,6 +55,7 @@
 extern int cifs_rename(struct inode *, struct dentry *, struct inode *,
 		       struct dentry *);
 extern int cifs_revalidate(struct dentry *);
+extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
 extern int cifs_setattr(struct dentry *, struct iattr *);
 
 extern struct inode_operations cifs_file_inode_ops;
@@ -73,7 +74,7 @@
 			  size_t write_size, loff_t * poffset);
 extern int cifs_lock(struct file *, int, struct file_lock *);
 extern int cifs_fsync(struct file *, struct dentry *, int);
-
+extern int cifs_file_mmap(struct file * , struct vm_area_struct *);
 extern struct file_operations cifs_dir_ops;
 extern int cifs_dir_open(struct inode *inode, struct file *file);
 extern int cifs_readdir(struct file *file, void *direntry, filldir_t filldir);
diff -Nru a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
--- a/fs/cifs/cifsglob.h	Mon Nov  4 14:31:01 2002
+++ b/fs/cifs/cifsglob.h	Mon Nov  4 14:31:01 2002
@@ -165,7 +165,7 @@
  */
 struct cifsTconInfo {
 	struct list_head cifsConnectionList;
-    struct list_head openFileList;
+	struct list_head openFileList;
 	struct semaphore tconSem;
 	struct cifsSesInfo *ses;	/* pointer to session associated with */
 	char treeName[MAX_TREE_SIZE + 1];	/* The ascii or unicode name of this resource depending on the ses->capabilities *//* BB fill in this field */
@@ -201,6 +201,7 @@
 	__u16 netfid;		/* file id from remote */
 	/* BB add lock scope info here if needed */ ;
 	/* lock scope id (0 if none) */
+    struct file * pfile; /* needed for writepage */
 	int endOfSearch:1;	/* we have reached end of search */
 	int closePend:1;	/* file is marked to close */
 };
@@ -212,12 +213,12 @@
 struct cifsInodeInfo {
 	struct list_head lockList;
 	/* BB add in lists for dirty pages - i.e. write caching info for oplock */
-    struct list_head openFileList;
+	struct list_head openFileList;
 	__u32 cifsAttrs;	/* e.g. DOS archive bit, sparse, compressed, system etc. */
 	atomic_t inUse;		/* num concurrent users (local openers cifs) of file */
 	unsigned long time;	/* jiffies of last update/check of inode */
 	int clientCanCache:1;	/* oplocked.  We need to extend cases beyond this i.e. what
-				   if file read-only or if file locked? or if file on r/o vol? */
+			   if file read-only or if file locked? or if file on r/o vol? */
 	struct inode vfs_inode;
 };
 
@@ -244,7 +245,7 @@
 	struct cifsSesInfo *ses;	/* smb was sent to this server */
 	struct task_struct *tsk;	/* task waiting for response */
 	struct smb_hdr *resp_buf;	/* response buffer */
-	int midState;		/* wish this could be an enum but can not pass that to wait_event */
+	int midState;	/* wish this were enum but can not pass to wait_event */
 };
 
 #define   MID_FREE 0
@@ -292,13 +293,10 @@
  */
 GLOBAL_EXTERN struct smbUidInfo *GlobalUidList[UID_HASH];
 
-GLOBAL_EXTERN struct list_head GlobalServerList;	/* BB this one is not implemented yet */
+GLOBAL_EXTERN struct list_head GlobalServerList; /* BB not implemented yet */
 GLOBAL_EXTERN struct list_head GlobalSMBSessionList;
 GLOBAL_EXTERN struct list_head GlobalTreeConnectionList;
-/*
- * Global list of free SMB structures
- */
-GLOBAL_EXTERN void *GlobalFreeSMB;
+GLOBAL_EXTERN rwlock_t GlobalSMBSeslock;  /* protects list inserts on 3 above */
 
 /*
  * Global transaction id (XID) information
@@ -306,7 +304,8 @@
 GLOBAL_EXTERN unsigned int GlobalCurrentXid;	/* protected by GlobalMid_Sem */
 GLOBAL_EXTERN unsigned int GlobalTotalActiveXid;	/* prot by GlobalMid_Sem */
 GLOBAL_EXTERN unsigned int GlobalMaxActiveXid;	/* prot by GlobalMid_Sem */
-
+GLOBAL_EXTERN rwlock_t GlobalMid_Lock;  /* protects above and list operations */
+					/* on midQ entries */
 GLOBAL_EXTERN char Local_System_Name[15];
 
 /*
@@ -321,13 +320,12 @@
 
 /* Misc globals */
 GLOBAL_EXTERN unsigned int multiuser_mount;	/* if enabled allows new sessions
-                                     to be established on existing mount if we
-					                 have the uid/password or Kerberos credential 
-                                     or equivalent for current user */
+				to be established on existing mount if we
+				have the uid/password or Kerberos credential 
+				or equivalent for current user */
 GLOBAL_EXTERN unsigned int oplockEnabled;
 GLOBAL_EXTERN unsigned int extended_security;	/* if on, session setup sent 
-                                     with more secure ntlmssp2 challenge/resp */
+				with more secure ntlmssp2 challenge/resp */
 GLOBAL_EXTERN unsigned int ntlmv2_support;  /* better optional password hash */
 GLOBAL_EXTERN unsigned int sign_CIFS_PDUs;  /* enable smb packet signing */
-
 
diff -Nru a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
--- a/fs/cifs/cifsproto.h	Mon Nov  4 14:31:00 2002
+++ b/fs/cifs/cifsproto.h	Mon Nov  4 14:31:00 2002
@@ -31,7 +31,7 @@
 extern struct smb_hdr *buf_get(void);
 extern void buf_release(void *);
 extern int smb_send(struct socket *, struct smb_hdr *,
-		    unsigned int /* length */ , struct sockaddr *);
+			unsigned int /* length */ , struct sockaddr *);
 extern unsigned int _GetXid(void);
 extern void _FreeXid(unsigned int);
 #define GetXid() (int)_GetXid(); cFYI(1,("\nCIFS VFS: in %s as Xid: %d with uid: %d",__FUNCTION__, xid,current->fsuid));
@@ -41,70 +41,70 @@
 extern void renew_parental_timestamps(struct dentry *direntry);
 extern void *kcalloc(size_t mem, int type);
 extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
-		       struct smb_hdr * /* input */ ,
-		       struct smb_hdr * /* out */ ,
-		       int * /* bytes returned */ , const int long_op);
+			struct smb_hdr * /* input */ ,
+			struct smb_hdr * /* out */ ,
+			int * /* bytes returned */ , const int long_op);
 extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid);
 extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length);
 extern int is_valid_oplock_break(struct smb_hdr *smb);
 extern int smbCalcSize(struct smb_hdr *ptr);
 extern int decode_negTokenInit(unsigned char *security_blob, int length,
-			       enum securityEnum *secType);
+			enum securityEnum *secType);
 extern int map_smb_to_linux_error(struct smb_hdr *smb);
 extern void header_assemble(struct smb_hdr *, char /* command */ ,
-			    const struct cifsTconInfo *, int
-			    /* length of fixed section (word count) in two byte units  */
-    );
+			const struct cifsTconInfo *, int
+			/* length of fixed section (word count) in two byte units  */
+			);
 extern time_t cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ );
 extern u64 cifs_UnixTimeToNT(time_t);
 extern void RevUcode_to_Ucode(char *revUnicode, char *UnicodeName);
 extern void Ucode_to_RevUcode(char *Unicode, char *revUnicodeName);
 extern void RevUcode_to_Ucode_with_Len(char *revUnicode, char *UnicodeName,
-				       int Len);
+			int Len);
 extern void Ucode_to_RevUcode_with_Len(char *Unicode, char *revUnicodeName,
-				       int Len);
+			int Len);
 extern int cifs_get_inode_info(struct inode **pinode,
-			       const unsigned char *search_path,
-			       struct super_block *sb);
+			const unsigned char *search_path,
+			struct super_block *sb);
 extern int cifs_get_inode_info_unix(struct inode **pinode,
-				    const unsigned char *search_path,
-				    struct super_block *sb);
+			const unsigned char *search_path,
+			struct super_block *sb);
 
 extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses,
-			    char cryptokey[CIFS_CRYPTO_KEY_SIZE]);
+			char cryptokey[CIFS_CRYPTO_KEY_SIZE]);
 extern int CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
-			 char *user, char *domain,
-			 char *session_key, char *ntlm_session_key,
-			 const struct nls_table *);
+			char *user, char *domain,
+			char *session_key, char *ntlm_session_key,
+			const struct nls_table *);
 extern int CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
-			       char *user, char *domain,
-			       char *SecurityBlob,
-			       int SecurityBlobLength,
-			       const struct nls_table *);
+			char *user, char *domain,
+			char *SecurityBlob,
+			int SecurityBlobLength,
+			const struct nls_table *);
 extern int CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
-					 struct cifsSesInfo *ses,
-					 char *domain,
-					 char *ntlm_session_key,
-                     int  *ntlmv2_flag,
-					 const struct nls_table *);
+			struct cifsSesInfo *ses,
+			char *domain,
+			char *ntlm_session_key,
+			int  *ntlmv2_flag,
+			const struct nls_table *);
 extern int CIFSNTLMSSPAuthSessSetup(unsigned int xid,
-				    struct cifsSesInfo *ses, char *user,
-				    char *domain, char *ntlm_session_key,
-				    char *lanman_session_key,
-                    int ntlmv2_flag,
-				    const struct nls_table *);
+			struct cifsSesInfo *ses, char *user,
+			char *domain, char *ntlm_session_key,
+			char *lanman_session_key,
+			int ntlmv2_flag,
+			const struct nls_table *);
 
 extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
-		    const char *tree, struct cifsTconInfo *tcon,
-		    const struct nls_table *);
+			const char *tree, struct cifsTconInfo *tcon,
+			const struct nls_table *);
 
 extern int CIFSFindFirst(const int xid, const struct cifsTconInfo *tcon,
-			 const char *searchName,
-			 FILE_DIRECTORY_INFO * findData,
-			 T2_FFIRST_RSP_PARMS * findParms,
-			 const struct nls_table *nls_codepage,
-			 int *pUnicodeFlag,
-			 int *pUnixFlag /* if Unix extensions used */ );
+			const char *searchName,
+			FILE_DIRECTORY_INFO * findData,
+			T2_FFIRST_RSP_PARMS * findParms,
+			const struct nls_table *nls_codepage,
+			int *pUnicodeFlag,
+			int *pUnixFlag /* if Unix extensions used */ );
 extern int CIFSFindNext(const int xid, const struct cifsTconInfo *tcon,
 			FILE_DIRECTORY_INFO * findData,
 			T2_FNEXT_RSP_PARMS * findParms,
@@ -112,48 +112,48 @@
 			int *UnicodeFlag, int *pUnixFlag);
 
 extern int CIFSSMBQPathInfo(const int xid, const struct cifsTconInfo *tcon,
-			    const unsigned char *searchName,
-			    FILE_ALL_INFO * findData,
-			    const struct nls_table *nls_codepage);
+			const unsigned char *searchName,
+			FILE_ALL_INFO * findData,
+			const struct nls_table *nls_codepage);
 
 extern int CIFSSMBUnixQPathInfo(const int xid,
-				const struct cifsTconInfo *tcon,
-				const unsigned char *searchName,
-				FILE_UNIX_BASIC_INFO * pFindData,
-				const struct nls_table *nls_codepage);
+			const struct cifsTconInfo *tcon,
+			const unsigned char *searchName,
+			FILE_UNIX_BASIC_INFO * pFindData,
+			const struct nls_table *nls_codepage);
 
 extern int CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
-			   const unsigned char *searchName,
-			   unsigned char **targetUNCs,
-			   int *number_of_UNC_in_array,
-			   const struct nls_table *nls_codepage);
+			const unsigned char *searchName,
+			unsigned char **targetUNCs,
+			int *number_of_UNC_in_array,
+			const struct nls_table *nls_codepage);
 
 extern int connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
-			       const char *old_path,
-			       const struct nls_table *nls_codepage);
+			const char *old_path,
+			const struct nls_table *nls_codepage);
 
 extern int CIFSSMBQFSInfo(const int xid, const struct cifsTconInfo *tcon,
-			  struct statfs *FSData,
-			  const struct nls_table *nls_codepage);
+			struct statfs *FSData,
+			const struct nls_table *nls_codepage);
 extern int CIFSSMBQFSAttributeInfo(const int xid,
-				   struct cifsTconInfo *tcon,
-				   const struct nls_table *nls_codepage);
+			struct cifsTconInfo *tcon,
+			const struct nls_table *nls_codepage);
 extern int CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon,
-				const struct nls_table *nls_codepage);
+			const struct nls_table *nls_codepage);
 extern int CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon,
-			      const struct nls_table *nls_codepage);
+			const struct nls_table *nls_codepage);
 
 extern int CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon,
-			   char *fileName, FILE_BASIC_INFO * data,
-			   const struct nls_table *nls_codepage);
+			char *fileName, FILE_BASIC_INFO * data,
+			const struct nls_table *nls_codepage);
 extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon,
-			 char *fileName, __u64 size,int setAllocationSizeFlag,
-			 const struct nls_table *nls_codepage);
+			char *fileName, __u64 size,int setAllocationSizeFlag,
+			const struct nls_table *nls_codepage);
 extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon,
 			 __u64 size, __u16 fileHandle,__u32 opener_pid, int AllocSizeFlag);
 extern int CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *pTcon,
-			       char *full_path, __u64 mode, __u64 uid,
-			       __u64 gid, const struct nls_table *nls_codepage);
+			char *full_path, __u64 mode, __u64 uid,
+			__u64 gid, const struct nls_table *nls_codepage);
 
 extern int CIFSSMBMkDir(const int xid, const struct cifsTconInfo *tcon,
 			const char *newName,
@@ -162,49 +162,49 @@
 			const char *name, const struct nls_table *nls_codepage);
 
 extern int CIFSSMBDelFile(const int xid, const struct cifsTconInfo *tcon,
-			  const char *name,
-			  const struct nls_table *nls_codepage);
+			const char *name,
+			const struct nls_table *nls_codepage);
 extern int CIFSSMBRename(const int xid, const struct cifsTconInfo *tcon,
-			 const char *fromName, const char *toName,
-			 const struct nls_table *nls_codepage);
+			const char *fromName, const char *toName,
+			const struct nls_table *nls_codepage);
 extern int CIFSCreateHardLink(const int xid,
-			      const struct cifsTconInfo *tcon,
-			      const char *fromName, const char *toName,
-			      const struct nls_table *nls_codepage);
+			const struct cifsTconInfo *tcon,
+			const char *fromName, const char *toName,
+			const struct nls_table *nls_codepage);
 extern int CIFSUnixCreateHardLink(const int xid,
-				  const struct cifsTconInfo *tcon,
-				  const char *fromName, const char *toName,
-				  const struct nls_table *nls_codepage);
+			const struct cifsTconInfo *tcon,
+			const char *fromName, const char *toName,
+			const struct nls_table *nls_codepage);
 extern int CIFSUnixCreateSymLink(const int xid,
-				 const struct cifsTconInfo *tcon,
-				 const char *fromName, const char *toName,
-				 const struct nls_table *nls_codepage);
+			const struct cifsTconInfo *tcon,
+			const char *fromName, const char *toName,
+			const struct nls_table *nls_codepage);
 extern int CIFSSMBUnixQuerySymLink(const int xid,
-				   const struct cifsTconInfo *tcon,
-				   const unsigned char *searchName,
-				   char *syminfo, const int buflen,
-				   const struct nls_table *nls_codepage);
+			const struct cifsTconInfo *tcon,
+			const unsigned char *searchName,
+			char *syminfo, const int buflen,
+			const struct nls_table *nls_codepage);
 
 extern int CIFSSMBOpen(const int xid, const struct cifsTconInfo *tcon,
-		       const char *fileName, const int disposition,
-		       const int access_flags, const int omode,
-		       __u16 * netfid, int *pOplock,
-		       const struct nls_table *nls_codepage);
+			const char *fileName, const int disposition,
+			const int access_flags, const int omode,
+			__u16 * netfid, int *pOplock,
+			const struct nls_table *nls_codepage);
 extern int CIFSSMBClose(const int xid, const struct cifsTconInfo *tcon,
 			const int smb_file_id);
 
 extern int CIFSSMBRead(const int xid, const struct cifsTconInfo *tcon,
-		       const int netfid, unsigned int count,
-		       const __u64 lseek, unsigned int *nbytes, char *buf);
+			const int netfid, unsigned int count,
+			const __u64 lseek, unsigned int *nbytes, char *buf);
 extern int CIFSSMBWrite(const int xid, const struct cifsTconInfo *tcon,
 			const int netfid, const unsigned int count,
 			const __u64 lseek, unsigned int *nbytes,
 			const char *buf, const int long_op);
 extern int CIFSSMBLock(const int xid, const struct cifsTconInfo *tcon,
-		       const __u16 netfid, const __u64 len,
-		       const __u64 offset, const __u32 numUnlock,
-		       const __u32 numLock, const __u8 lockType,
-		       const int waitFlag);
+			const __u16 netfid, const __u64 len,
+			const __u64 offset, const __u32 numUnlock,
+			const __u32 numLock, const __u8 lockType,
+			const int waitFlag);
 
 extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon);
 extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses);
@@ -220,32 +220,32 @@
 /* BB routines below not implemented yet BB */
 
 extern int CIFSBuildServerList(int xid, char *serverBufferList,
-			       int recordlength, int *entries,
-			       int *totalEntries, int *topoChangedFlag);
+			int recordlength, int *entries,
+			int *totalEntries, int *topoChangedFlag);
 extern int CIFSSMBQueryShares(int xid, struct cifsTconInfo *tcon,
-			      struct shareInfo *shareList, int bufferLen,
-			      int *entries, int *totalEntries);
+			struct shareInfo *shareList, int bufferLen,
+			int *entries, int *totalEntries);
 extern int CIFSSMBQueryAlias(int xid, struct cifsTconInfo *tcon,
-			     struct aliasInfo *aliasList, int bufferLen,
-			     int *entries, int *totalEntries);
+			struct aliasInfo *aliasList, int bufferLen,
+			int *entries, int *totalEntries);
 extern int CIFSSMBAliasInfo(int xid, struct cifsTconInfo *tcon,
-			    char *aliasName, char *serverName,
-			    char *shareName, char *comment);
+			char *aliasName, char *serverName,
+			char *shareName, char *comment);
 extern int CIFSSMBGetShareInfo(int xid, struct cifsTconInfo *tcon,
-			       char *share, char *comment);
+			char *share, char *comment);
 extern int CIFSSMBGetUserPerms(int xid, struct cifsTconInfo *tcon,
-			       char *userName, char *searchName, int *perms);
+			char *userName, char *searchName, int *perms);
 extern int CIFSSMBSync(int xid, struct cifsTconInfo *tcon, int netfid, int pid);
 
 extern int CIFSSMBSeek(int xid,
-		       struct cifsTconInfo *tcon,
-		       int netfid,
-		       int pid,
-		       int whence, unsigned long offset, long long *newoffset);
+			struct cifsTconInfo *tcon,
+			int netfid,
+			int pid,
+			int whence, unsigned long offset, long long *newoffset);
 
 extern int CIFSSMBCopy(int xid,
-		       struct cifsTconInfo *ftcon,
-		       char *fromName,
-		       struct cifsTconInfo *ttcon,
-		       char *toName, int ofun, int flags);
-#endif				/* _CIFSPROTO_H */
+			struct cifsTconInfo *ftcon,
+			char *fromName,
+			struct cifsTconInfo *ttcon,
+			char *toName, int ofun, int flags);
+#endif			/* _CIFSPROTO_H */
diff -Nru a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
--- a/fs/cifs/cifssmb.c	Mon Nov  4 14:31:01 2002
+++ b/fs/cifs/cifssmb.c	Mon Nov  4 14:31:01 2002
@@ -487,7 +487,7 @@
 					 (tcon->ses->maxBuf -
 					  MAX_CIFS_HDR_SIZE) & 0xFFFFFF00));
 	pSMB->MaxCountHigh = 0;
-	pSMB->ByteCount = 0;	/* no need to do le conversion since it is 0 */
+	pSMB->ByteCount = 0;  /* no need to do le conversion since it is 0 */
 
 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -497,15 +497,20 @@
 	} else {
 		pSMBr->DataLength = le16_to_cpu(pSMBr->DataLength);
 		*nbytes = pSMBr->DataLength;
-		/* BB check that DataLength would not go beyond end of SMB BB */
-		if (pSMBr->DataLength > CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE) {
+		/*check that DataLength would not go beyond end of SMB */
+		if ((pSMBr->DataLength > CIFS_MAX_MSGSIZE) 
+				|| (pSMBr->DataLength > count)) {
 			rc = -EIO;
 			*nbytes = 0;
 		} else {
 			pReadData =
 			    (char *) (&pSMBr->hdr.Protocol) +
 			    le16_to_cpu(pSMBr->DataOffset);
-			copy_to_user(buf, pReadData, pSMBr->DataLength);
+/*			if(rc = copy_to_user(buf, pReadData, pSMBr->DataLength)) {
+				cERROR(1,("\nFaulting on read rc = %d",rc));
+				rc = -EFAULT;
+			}*/ /* can not use copy_to_user when using page cache*/
+			memcpy(buf,pReadData,pSMBr->DataLength);
 		}
 	}
 
@@ -544,7 +549,8 @@
 	pSMB->DataLengthHigh = 0;
 	pSMB->DataOffset =
 	    cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);
-	copy_from_user(pSMB->Data, buf, pSMB->DataLengthLow);
+
+	memcpy(pSMB->Data,buf,pSMB->DataLengthLow);
 
 	pSMB->ByteCount += pSMB->DataLengthLow + 1 /* pad */ ;
 	pSMB->DataLengthLow = cpu_to_le16(pSMB->DataLengthLow);
diff -Nru a/fs/cifs/connect.c b/fs/cifs/connect.c
--- a/fs/cifs/connect.c	Mon Nov  4 14:31:02 2002
+++ b/fs/cifs/connect.c	Mon Nov  4 14:31:02 2002
@@ -219,6 +219,7 @@
 				}
 
                 task_to_wake = NULL;
+				read_lock(&GlobalMid_Lock);
 				list_for_each(tmp, &server->pending_mid_q) {
 					mid_entry = list_entry(tmp, struct
 							       mid_q_entry,
@@ -234,7 +235,7 @@
 						    MID_RESPONSE_RECEIVED;
 					}
 				}
-
+				read_unlock(&GlobalMid_Lock);
 				if (task_to_wake) {
 					smb_buffer = NULL;	/* will be freed by users thread after he is done */
 					wake_up_process(task_to_wake);
@@ -256,12 +257,14 @@
 	}
 	/* BB add code to lock SMB sessions while releasing */
 	if(server->ssocket) {
-        sock_release(csocket);
+		sock_release(csocket);
 	    server->ssocket = NULL;
-    }
+	}
 	set_fs(temp_fs);
 	if (smb_buffer) /* buffer usually freed in free_mid - need to free it on error or exit */
 		buf_release(smb_buffer);
+
+	read_lock(&GlobalSMBSeslock);
 	if (list_empty(&server->pending_mid_q)) {
 		/* loop through server session structures attached to this and mark them dead */
 		list_for_each(tmp, &GlobalSMBSessionList) {
@@ -275,10 +278,12 @@
 		}
 		kfree(server);
 	} else	/* BB need to more gracefully handle the rare negative session 
-               response case because response will be still outstanding */
+			   response case because response will be still outstanding */
 		cERROR(1, ("\nThere are still active MIDs in queue and we are exiting but we can not delete mid_q_entries or TCP_Server_Info structure due to pending requests MEMORY LEAK!!\n "));	/* BB wake up waitors, and/or wait and/or free stale mids and try again? BB */
 /* BB Need to fix bug in error path above - perhaps wait until smb requests
    time out and then free the tcp per server struct BB */
+	read_unlock(&GlobalSMBSeslock);
+
 
 	cFYI(1, ("\nAbout to exit from demultiplex thread\n"));
 	return 0;
@@ -421,7 +426,7 @@
 	struct cifsSesInfo *ses;
 
 	*psrvTcp = NULL;
-
+	read_lock(&GlobalSMBSeslock);
 	list_for_each(tmp, &GlobalSMBSessionList) {
 		ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
 		if (ses->server) {
@@ -432,12 +437,15 @@
 				/* BB check if reconnection needed */
 				if (strncmp
 				    (ses->userName, userName,
-				     MAX_USERNAME_SIZE) == 0)
+				     MAX_USERNAME_SIZE) == 0){
+					read_unlock(&GlobalSMBSeslock);
 					return ses;	/* found exact match on both tcp and SMB sessions */
+				}
 			}
 		}
 		/* else tcp and smb sessions need reconnection */
 	}
+	read_unlock(&GlobalSMBSeslock);
 	return NULL;
 }
 
@@ -447,6 +455,7 @@
 	struct list_head *tmp;
 	struct cifsTconInfo *tcon;
 
+	read_lock(&GlobalSMBSeslock);
 	list_for_each(tmp, &GlobalTreeConnectionList) {
 		cFYI(1, ("\nNext tcon - "));
 		tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
@@ -473,13 +482,16 @@
 						if (strncmp
 						    (tcon->ses->userName,
 						     userName,
-						     MAX_USERNAME_SIZE) == 0)
+						     MAX_USERNAME_SIZE) == 0) {
+							read_unlock(&GlobalSMBSeslock);
 							return tcon;/* also matched user (smb session)*/
+						}
 					}
 				}
 			}
 		}
 	}
+	read_unlock(&GlobalSMBSeslock);
 	return NULL;
 }
 
@@ -599,7 +611,7 @@
 {
 	int rc = 0;
 	int xid;
-    int ntlmv2_flag = FALSE;
+	int ntlmv2_flag = FALSE;
 	struct socket *csocket;
 	struct sockaddr_in sin_server;
 /*	struct sockaddr_in6 sin_server6; */
@@ -616,7 +628,11 @@
 	xid = GetXid();
 	cFYI(0, ("\nEntering cifs_mount. Xid: %d with: %s\n", xid, mount_data));
 
-	parse_mount_options(mount_data, devname, &volume_info);
+	if(parse_mount_options(mount_data, devname, &volume_info)) {
+		FreeXid(xid);
+		return -EINVAL;
+	}
+
 
 	if (volume_info.username) {
 		cFYI(1, ("\nUsername: %s ", volume_info.username));
@@ -634,7 +650,7 @@
 		cERROR(1,
 		       ("\nCIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified  "));
 		FreeXid(xid);
-		return -ENODEV;
+		return -EINVAL;
 	}
 	/* BB add support to use the multiuser_mount flag BB */
 	existingCifsSes =
@@ -720,18 +736,18 @@
 				   && (pSesInfo->secType == RawNTLMSSP)) {
 				cFYI(1, ("\nNTLMSSP sesssetup "));
 				rc = CIFSNTLMSSPNegotiateSessSetup(xid,
-								   pSesInfo,
-								   cryptKey,
-								   volume_info.domainname,
-                                   &ntlmv2_flag,
-								   cifs_sb->local_nls);
+								pSesInfo,
+								cryptKey,
+								volume_info.domainname,
+								&ntlmv2_flag,
+								cifs_sb->local_nls);
 				if (!rc) {
-                    if(ntlmv2_flag) {
-                        cFYI(1,("\nAble to use the more secure NTLM version 2 password hash"));
-                        /* SMBNTv2encrypt( ...);  */ /* BB fix this up - 
-                        and note that Samba client equivalent looks wrong */
-                    } else
-					    SMBNTencrypt(password_with_pad,cryptKey,ntlm_session_key);
+					if(ntlmv2_flag) {
+						cFYI(1,("\nAble to use the more secure NTLM version 2 password hash"));
+				/* SMBNTv2encrypt( ...);  */ /* BB fix this up - 
+				   and note that Samba client equivalent looks wrong */
+					} else
+						SMBNTencrypt(password_with_pad,cryptKey,ntlm_session_key);
 
 					/* for better security the weaker lanman hash not sent 
                        in AuthSessSetup so why bother calculating it */
@@ -742,13 +758,13 @@
 						   cryptKey, session_key); */
 
 					rc = CIFSNTLMSSPAuthSessSetup(xid,
-								      pSesInfo,
-								      volume_info.
-								      username,
-								      volume_info.domainname,
-								      ntlm_session_key,
-								      session_key,
-                                      ntlmv2_flag,
+								pSesInfo,
+								volume_info.
+								username,
+								volume_info.domainname,
+								ntlm_session_key,
+								session_key,
+								ntlmv2_flag,
 								      cifs_sb->local_nls);
 				}
 			} else {	/* old style NTLM 0.12 session setup */
@@ -805,6 +821,7 @@
 								 "",
 								 cifs_sb->
 								 local_nls);
+					FreeXid(xid);
 					return -ENODEV;
 				} else {
 					rc = CIFSTCon(xid, pSesInfo,
@@ -893,8 +910,8 @@
 	pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->maxBuf);
 	pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->maxReq);
 
-    if(ses->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
-        smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
+	if(ses->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
+		smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
 
 	pSMB->req_no_secext.Capabilities =
 	    CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS;
@@ -928,8 +945,8 @@
 			*bcc_ptr = 0;
 			bcc_ptr++;
 		}
-        if(user == NULL)
-            bytes_returned = 0; /* skill null user */
+		if(user == NULL)
+			bytes_returned = 0; /* skill null user */
         else
 		    bytes_returned =
 		        cifs_strtoUCS((wchar_t *) bcc_ptr, user, 100, nls_codepage);
@@ -960,10 +977,10 @@
 		bcc_ptr += 2 * bytes_returned;
 		bcc_ptr += 2;
 	} else {
-        if(user != NULL) {                
+		if(user != NULL) {                
 		    strncpy(bcc_ptr, user, 200);
 		    bcc_ptr += strnlen(user, 200);
-        }
+		}
 		*bcc_ptr = 0;
 		bcc_ptr++;
 		if (domain == NULL) {
@@ -1065,7 +1082,6 @@
 						    kcalloc(2, GFP_KERNEL);
 					}
 				} else {	/* ASCII */
-
 					len = strnlen(bcc_ptr, 1024);
 					if (((long) bcc_ptr + len) - (long)
 					    pByteArea(smb_buffer_response)
@@ -1148,8 +1164,8 @@
 	pSMB->req.MaxBufferSize = cpu_to_le16(ses->maxBuf);
 	pSMB->req.MaxMpxCount = cpu_to_le16(ses->maxReq);
 
-    if(ses->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
-        smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
+	if(ses->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
+		smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
 
 	pSMB->req.Capabilities =
 	    CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
@@ -1394,7 +1410,7 @@
 	PCHALLENGE_MESSAGE SecurityBlob2;
 
 	cFYI(1, ("\nIn NTLMSSP sesssetup (negotiate) "));
-    *pNTLMv2_flag = FALSE;
+	*pNTLMv2_flag = FALSE;
 	smb_buffer = buf_get();
 	if (smb_buffer == 0) {
 		return -ENOMEM;
@@ -1413,8 +1429,8 @@
 	pSMB->req.MaxBufferSize = cpu_to_le16(ses->maxBuf);
 	pSMB->req.MaxMpxCount = cpu_to_le16(ses->maxReq);
 
-    if(ses->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
-        smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
+	if(ses->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
+		smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
 
 	pSMB->req.Capabilities =
 	    CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
@@ -1441,8 +1457,8 @@
 	    NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
 	    NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | 0x80000000 |
 	    NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_NEGOTIATE_128;
-    if(ntlmv2_support)
-        SecurityBlob->NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLMV2;
+	if(ntlmv2_support)
+		SecurityBlob->NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLMV2;
 	/* setup pointers to domain name and workstation name */
 	bcc_ptr += SecurityBlobLength;
 
@@ -1558,8 +1574,8 @@
 				memcpy(challenge_from_server,
 				       SecurityBlob2->Challenge,
 				       CIFS_CRYPTO_KEY_SIZE);
-                if(SecurityBlob2->NegotiateFlags & NTLMSSP_NEGOTIATE_NTLMV2)
-                    *pNTLMv2_flag = TRUE;
+				if(SecurityBlob2->NegotiateFlags & NTLMSSP_NEGOTIATE_NTLMV2)
+					*pNTLMv2_flag = TRUE;
 				if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) {
 					if ((long) (bcc_ptr) % 2) {
 						remaining_words =
@@ -1645,7 +1661,6 @@
 						    kcalloc(2, GFP_KERNEL);
 					}
 				} else {	/* ASCII */
-
 					len = strnlen(bcc_ptr, 1024);
 					if (((long) bcc_ptr + len) - (long)
 					    pByteArea(smb_buffer_response)
@@ -1742,8 +1757,8 @@
 
 	pSMB->req.hdr.Uid = ses->Suid;
 
-    if(ses->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
-        smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
+	if(ses->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
+		smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
 
 	pSMB->req.Capabilities =
 	    CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
@@ -1771,8 +1786,8 @@
 	    NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
 	    NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
 	    0x80000000 | NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_NEGOTIATE_128;
-    if(ntlmv2_flag)
-        SecurityBlob->NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLMV2;
+	if(ntlmv2_flag)
+		SecurityBlob->NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLMV2;
 
 /* setup pointers to domain name and workstation name */
 
@@ -2032,7 +2047,6 @@
 						ses->serverNOS = kcalloc(2, GFP_KERNEL);
 					}
 				} else {	/* ASCII */
-
 					len = strnlen(bcc_ptr, 1024);
 					if (((long) bcc_ptr + len) - 
                         (long) pByteArea(smb_buffer_response) 
@@ -2116,8 +2130,8 @@
 	bcc_ptr = &(pSMB->Password[0]);
 	bcc_ptr++;		/* skip password */
 
-    if(ses->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
-        smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
+	if(ses->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
+		smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
 
 	if (ses->capabilities & CAP_STATUS32) {
 		smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
@@ -2202,6 +2216,7 @@
 	struct cifsSesInfo *ses = NULL;
 
 	xid = GetXid();
+
 	if (cifs_sb->tcon) {
 		ses = cifs_sb->tcon->ses; /* save ptr to ses before delete tcon!*/
 		rc = CIFSSMBTDis(xid, cifs_sb->tcon);
@@ -2218,16 +2233,11 @@
 				FreeXid(xid);
 				return 0;
 			}
-    	 /* wake_up_process(ses->server->tsk);*/ /* was worth a try */
 			schedule_timeout(HZ / 4);	/* give captive thread time to exit */
-            if((ses->server) && (ses->server->ssocket)) {            
-                cFYI(1,("\nWaking up socket by sending it signal "));
-                send_sig(SIGINT,ses->server->tsk,1);
-                /* No luck figuring out a better way to_close socket */
-         /*ses->server->ssocket->sk->prot->close(ses->server->ssocket->sk,0);*/
-              /*  ses->server->ssocket = NULL; */  /* serialize better */
-                /* sock_wake_async(ses->server->ssocket,3,POLL_HUP); */
-            }
+			if((ses->server) && (ses->server->ssocket)) {            
+				cFYI(1,("\nWaking up socket by sending it signal "));
+				send_sig(SIGINT,ses->server->tsk,1);
+			}
 		} else
 			cFYI(1, ("\nNo session or bad tcon"));
 	}
diff -Nru a/fs/cifs/file.c b/fs/cifs/file.c
--- a/fs/cifs/file.c	Mon Nov  4 14:31:00 2002
+++ b/fs/cifs/file.c	Mon Nov  4 14:31:00 2002
@@ -35,6 +35,8 @@
 #include "cifs_debug.h"
 #include "cifs_fs_sb.h"
 
+
+
 int
 cifs_open(struct inode *inode, struct file *file)
 {
@@ -42,8 +44,8 @@
 	int xid, oplock;
 	struct cifs_sb_info *cifs_sb;
 	struct cifsTconInfo *pTcon;
-    struct cifsFileInfo *pCifsFile;
-    struct cifsInodeInfo *pCifsInode;
+	struct cifsFileInfo *pCifsFile;
+	struct cifsInodeInfo *pCifsInode;
 	char *full_path = NULL;
 	int desiredAccess = 0x20197;
 	int disposition = FILE_OPEN;
@@ -104,28 +106,27 @@
 		if (file->private_data) {
 			memset(file->private_data, 0,
 			       sizeof (struct cifsFileInfo));
-            pCifsFile = (struct cifsFileInfo *) file->private_data;
+			pCifsFile = (struct cifsFileInfo *) file->private_data;
 			pCifsFile->netfid = netfid;
 			pCifsFile->pid = current->pid;
-            list_add(&pCifsFile->tlist,&pTcon->openFileList);
-            pCifsInode = CIFS_I(file->f_dentry->d_inode);
-            list_add(&pCifsFile->flist,&pCifsInode->openFileList);
-            if(file->f_flags & O_CREAT) {           
-                 /* time to set mode which we can not
-                 set earlier due to problems creating new read-only files */
-                if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)                
-                    CIFSSMBUnixSetPerms(xid, pTcon, full_path, inode->i_mode,
-                                        0xFFFFFFFFFFFFFFFF,  
-                                        0xFFFFFFFFFFFFFFFF,
-                                        cifs_sb->local_nls);
-                else {/* BB to be implemented via Windows secrty descriptors*/
-         /* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/
-                    /* in the meantime we could set the r/o dos attribute 
-                       when perms are e.g.:   
-                            mode & 0222 == 0 */
-                }
-            }
-
+			pCifsFile->pfile = file; /* needed for writepage */
+			list_add(&pCifsFile->tlist,&pTcon->openFileList);
+			pCifsInode = CIFS_I(file->f_dentry->d_inode);
+			list_add(&pCifsFile->flist,&pCifsInode->openFileList);
+			if(file->f_flags & O_CREAT) {           
+				/* time to set mode which we can not set earlier due
+				 to problems creating new read-only files */
+				if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)                
+					CIFSSMBUnixSetPerms(xid, pTcon, full_path, inode->i_mode,
+						0xFFFFFFFFFFFFFFFF,  
+						0xFFFFFFFFFFFFFFFF,
+						cifs_sb->local_nls);
+				else {/* BB implement via Windows security descriptors */
+			/* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/
+			/* in the meantime could set r/o dos attribute when perms are eg:
+					mode & 0222 == 0 */
+				}
+			}
 		}
 	}
 
@@ -151,10 +152,10 @@
 
 	cifs_sb = CIFS_SB(inode->i_sb);
 	pTcon = cifs_sb->tcon;
- 	if (pSMBFile) {
-        list_del(&pSMBFile->flist);
-        list_del(&pSMBFile->tlist);
-        rc = CIFSSMBClose(xid, pTcon, pSMBFile->netfid);
+	if (pSMBFile) {
+		list_del(&pSMBFile->flist);
+		list_del(&pSMBFile->tlist);
+		rc = CIFSSMBClose(xid, pTcon, pSMBFile->netfid);
 		kfree(file->private_data);
 		file->private_data = NULL;
 	} else
@@ -162,7 +163,6 @@
 
 	FreeXid(xid);
 	return rc;
-
 }
 
 int
@@ -344,20 +344,24 @@
 			file->f_dentry->d_inode->i_size = *poffset;
 	}
 	mark_inode_dirty_sync(file->f_dentry->d_inode);
+	FreeXid(xid);
 	return total_written;
 }
 
 static int
-cifs_writepage(struct page *page)
+cifs_partialpagewrite(struct page *page,unsigned from, unsigned to)
 {
 	struct address_space *mapping = page->mapping;
+	loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
+	char * write_data = kmap(page);
 	int rc = -EFAULT;
 	int bytes_written = 0;
 	struct cifs_sb_info *cifs_sb;
 	struct cifsTconInfo *pTcon;
-	int xid;
 	struct inode *inode = page->mapping->host;
-	loff_t *poffset = NULL;
+	struct cifsInodeInfo *cifsInode;
+	struct cifsFileInfo *open_file = NULL;
+	int xid;
 
 	xid = GetXid();
 
@@ -365,51 +369,90 @@
 	pTcon = cifs_sb->tcon;
 
 	/* figure out which file struct to use 
-	   if (file->private_data == NULL) {
+	if (file->private_data == NULL) {
 	   FreeXid(xid);
 	   return -EBADF;
-	   }     
+	}     
 	 */
 	if (!mapping) {
 		FreeXid(xid);
 		return -EFAULT;
+	} else if(!mapping->host) {
+		FreeXid(xid);
+		return -EFAULT;
 	}
 
-	/* BB fix and add missing call to cifs_writepage_sync here */
+	if((to > PAGE_CACHE_SIZE) || (from > to))
+		return -EIO;
 
-	inode->i_ctime = inode->i_mtime = CURRENT_TIME;	/* BB is this right? */
-	if ((bytes_written > 0) && (poffset)) {
-		if (*poffset > inode->i_size)
-			inode->i_size = *poffset;
+        offset += (loff_t)from;
+	write_data += from;
+
+	cifsInode = CIFS_I(mapping->host);
+	if(!list_empty(&(cifsInode->openFileList))) {            
+		open_file = list_entry(cifsInode->openFileList.next,
+					   struct cifsFileInfo, flist);           
+	/* We could check if file is open for writing first */
+		if(open_file->pfile)
+			bytes_written = cifs_write(open_file->pfile, write_data,
+					   to-from, &offset);
+		/* Does mm or vfs already set times? */
+		inode->i_atime = inode->i_mtime = CURRENT_TIME;	
+		if ((bytes_written > 0) && (offset)) {
+			rc = 0;
+			if (offset > inode->i_size)
+				inode->i_size = offset;
+		} else if(bytes_written < 0) {
+			rc = bytes_written;
+		}
+		mark_inode_dirty_sync(inode);
+	} else {
+		cFYI(1,("\nNo open files to get file handle from"));
+		rc = -EIO;
 	}
-	mark_inode_dirty_sync(inode);
 
 	FreeXid(xid);
 	return rc;
 }
 
 static int
-cifs_prepare_write(struct file *file, struct page *page, unsigned offset,
-		   unsigned to)
+cifs_writepage(struct page* page)
 {
-	return 0;	/* eventually add code to flush any incompatible requests */
+	int rc = -EFAULT;
+	int xid;
+
+	xid = GetXid();
+	page_cache_get(page);
+	rc = cifs_partialpagewrite(page,0,PAGE_CACHE_SIZE);
+	/* insert call to SetPageToUpdate like function here? */
+	unlock_page(page);
+	page_cache_release(page);	
+	FreeXid(xid);
+	return rc;
 }
 
 static int
 cifs_commit_write(struct file *file, struct page *page, unsigned offset,
 		  unsigned to)
 {
-	long rc = -EFAULT;
-
-	lock_kernel();
-/*	status = cifs_updatepage(file, page, offset, to-offset); */
+	int xid,rc;
+	xid = GetXid();
 
-/* BB add - do we really need to lock the kernel here for so long ? */
+	if(offset > to)
+		return -EIO;
+	rc = cifs_partialpagewrite(page,offset,to);
 
-	unlock_kernel();
+	FreeXid(xid);
 	return rc;
 }
 
+static int
+cifs_prepare_write(struct file *file, struct page *page, unsigned offset,
+		   unsigned to)
+{
+	return 0;	/* eventually add code to flush any incompatible requests */
+}
+
 int
 cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
 {
@@ -489,13 +532,30 @@
 	return total_read;
 }
 
+int
+cifs_file_mmap(struct file * file, struct vm_area_struct * vma)
+{
+	struct dentry * dentry = file->f_dentry;
+	int	rc, xid;
+
+	xid = GetXid();
+	rc = cifs_revalidate(dentry);
+	if (rc) {
+		cFYI(1,("Validation prior to mmap failed, error=%d\n", rc));
+		FreeXid(xid);
+		return rc;
+	}
+	rc = generic_file_mmap(file, vma);
+	FreeXid(xid);
+	return rc;
+}
+
 static int
-cifs_readpage_sync(struct file *file, struct page *page)
+cifs_readpage(struct file *file, struct page *page)
 {
-	unsigned int count = PAGE_CACHE_SIZE;
+	loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
+	char * read_data;
 	int rc = -EACCES;
-	int bytes_read = 0;
-	int total_read = 0;
 	struct cifs_sb_info *cifs_sb;
 	struct cifsTconInfo *pTcon;
 	int xid;
@@ -508,26 +568,33 @@
 		FreeXid(xid);
 		return -EBADF;
 	}
+	page_cache_get(page);
+	read_data = kmap(page);
+	/* for reads over a certain size we could initiate async read ahead */
 
-	/* BB finish adding missing here */
+	rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, &offset);
 
-	cFYI(1,
-	     ("\nCount is %d total read %d bytes read %d ", count, total_read,
-	      bytes_read));
+	if (rc < 0)
+		goto io_error;
+	else {
+		cFYI(1,("\nBytes read %d ",rc));
+	}
 
-	FreeXid(xid);
-	return rc;
-}
+	file->f_dentry->d_inode->i_atime = CURRENT_TIME;
 
-static int
-cifs_readpage(struct file *file, struct page *page)
-{
-	int rc;
+	if(PAGE_CACHE_SIZE > rc) {
+		memset(read_data+rc, 0, PAGE_CACHE_SIZE - rc);
+	}
+	flush_dcache_page(page);
+	SetPageUptodate(page);
+	rc = 0;
+
+io_error:
+	kunmap(page);
+	unlock_page(page);
 
-	page_cache_get(page);
-	rc = cifs_readpage_sync(file, page);
-	/* for reads over a certain size we could initiate async read ahead */
 	page_cache_release(page);
+	FreeXid(xid);
 	return rc;
 }
 
@@ -546,11 +613,11 @@
 
 	/* Linux can not store file creation time unfortunately so we ignore it */
 	tmp_inode->i_atime =
-	    le64_to_cpu(cifs_NTtimeToUnix(pfindData->LastAccessTime));
+	    cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
 	tmp_inode->i_mtime =
-	    le64_to_cpu(cifs_NTtimeToUnix(pfindData->LastWriteTime));
+	    cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
 	tmp_inode->i_ctime =
-	    le64_to_cpu(cifs_NTtimeToUnix(pfindData->ChangeTime));
+	    cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
 	/* should we treat the dos attribute of read-only as read-only mode bit e.g. 555 */
 	tmp_inode->i_mode = S_IALLUGO & ~(S_ISUID | S_IXGRP);	/* 2767 perms - indicate mandatory locking */
 	cFYI(0,
@@ -605,16 +672,12 @@
 	atomic_inc(&cifsInfo->inUse);
 
 	tmp_inode->i_atime =
-	    le64_to_cpu(cifs_NTtimeToUnix(pfindData->LastAccessTime));
+	    cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
 	tmp_inode->i_mtime =
-	    le64_to_cpu(cifs_NTtimeToUnix(pfindData->LastModificationTime));
+	    cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastModificationTime));
 	tmp_inode->i_ctime =
-	    le64_to_cpu(cifs_NTtimeToUnix(pfindData->LastStatusChange));
+	    cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange));
 
-	/* tmp_inode->i_mtime =
-	   cifs_NTtimeToUnix(pfindData->LastModificationTime);
-	   tmp_inode->i_ctime =
-	   cifs_NTtimeToUnix(pfindData->LastStatusChange); */
 	tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions);
 	pfindData->Type = le32_to_cpu(pfindData->Type);
 	if (pfindData->Type == UNIX_FILE) {
@@ -1013,8 +1076,17 @@
 
 struct address_space_operations cifs_addr_ops = {
 	.readpage = cifs_readpage,
-	.sync_page = cifs_sync_page,
 	.writepage = cifs_writepage,
 	.prepare_write = cifs_prepare_write,
-	.commit_write = cifs_commit_write
+	.commit_write = cifs_commit_write,
+/*	.sync_page = cifs_sync_page, */
+};
+
+/* change over to struct below when sync page tested and complete */
+struct address_space_operations cifs_addr_ops2 = {
+	.readpage = cifs_readpage,
+	.writepage = cifs_writepage,
+	.prepare_write = cifs_prepare_write,
+	.commit_write = cifs_commit_write,
+	.sync_page = cifs_sync_page,
 };
diff -Nru a/fs/cifs/inode.c b/fs/cifs/inode.c
--- a/fs/cifs/inode.c	Mon Nov  4 14:31:00 2002
+++ b/fs/cifs/inode.c	Mon Nov  4 14:31:00 2002
@@ -52,9 +52,9 @@
 	if (rc) {
 		if (rc == -EREMOTE) {
 /* rc = *//* CIFSGetDFSRefer(xid, pTcon->ses, search_path,
-   &referrals,
-   &num_referrals,
-   cifs_sb->local_nls); */
+	&referrals,
+	&num_referrals,
+	cifs_sb->local_nls); */
 			tmp_path =
 			    kmalloc(strnlen
 				    (pTcon->treeName,
@@ -99,12 +99,12 @@
 		atomic_inc(&cifsInfo->inUse);	/* inc on every refresh of inode */
 
 		inode->i_atime =
-		    le64_to_cpu(cifs_NTtimeToUnix(findData.LastAccessTime));
+		    cifs_NTtimeToUnix(le64_to_cpu(findData.LastAccessTime));
 		inode->i_mtime =
-		    le64_to_cpu(cifs_NTtimeToUnix
+		    cifs_NTtimeToUnix(le64_to_cpu
 				(findData.LastModificationTime));
 		inode->i_ctime =
-		    le64_to_cpu(cifs_NTtimeToUnix(findData.LastStatusChange));
+		    cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange));
 		inode->i_mode = le64_to_cpu(findData.Permissions);
 		findData.Type = le32_to_cpu(findData.Type);
 		if (findData.Type == UNIX_FILE) {
@@ -140,6 +140,7 @@
 			cFYI(1, (" File inode "));
 			inode->i_op = &cifs_file_inode_ops;
 			inode->i_fop = &cifs_file_ops;
+			inode->i_data.a_ops = &cifs_addr_ops;
 		} else if (S_ISDIR(inode->i_mode)) {
 			cFYI(1, (" Directory inode"));
 			inode->i_op = &cifs_dir_inode_ops;
@@ -182,9 +183,9 @@
 		if (rc == -EREMOTE) {
 			/* BB add call to new func rc = GetDFSReferral(); */
 /* rc = *//* CIFSGetDFSRefer(xid, pTcon->ses, search_path,
-   &referrals,
-   &num_referrals,
-   cifs_sb->local_nls); */
+	&referrals,
+	&num_referrals,
+	cifs_sb->local_nls); */
 			tmp_path =
 			    kmalloc(strnlen
 				    (pTcon->treeName,
@@ -265,6 +266,7 @@
 			cFYI(1, (" File inode "));
 			inode->i_op = &cifs_file_inode_ops;
 			inode->i_fop = &cifs_file_ops;
+			inode->i_data.a_ops = &cifs_addr_ops;
 		} else if (S_ISDIR(inode->i_mode)) {
 			cFYI(1, (" Directory inode "));
 			inode->i_op = &cifs_dir_inode_ops;
@@ -441,9 +443,11 @@
 	cifs_sb_source = CIFS_SB(source_inode->i_sb);
 	pTcon = cifs_sb_source->tcon;
 
-	if (pTcon != cifs_sb_target->tcon)
+	if (pTcon != cifs_sb_target->tcon) {    
 		return -EXDEV;	/* BB actually could be allowed if same server, but
                      different share. Might eventually add support for this */
+        FreeXid(xid);
+    }
 
 	fromName = build_path_from_dentry(source_direntry);
 	toName = build_path_from_dentry(target_direntry);
@@ -455,6 +459,7 @@
 	if (toName)
 		kfree(toName);
 
+    FreeXid(xid);
 	return rc;
 }
 
@@ -479,7 +484,7 @@
 	      direntry->d_time, jiffies));
 
 	cifsInode = CIFS_I(direntry->d_inode);
-
+/* BB add check - do not need to revalidate oplocked files */
 	if ((time_before(jiffies, cifsInode->time + HZ))
 	    && (direntry->d_inode->i_nlink == 1)) {
 		cFYI(1, (" Do not need to revalidate "));
@@ -505,12 +510,20 @@
 	return rc;
 }
 
+int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+{
+	int err = cifs_revalidate(dentry);
+	if (!err)
+		generic_fillattr(dentry->d_inode, stat);
+	return err;
+}
+
 void
 cifs_truncate_file(struct inode *inode)
 {				/* BB remove - may not need this function after all BB */
 	int xid;
 	int rc = 0;
-    struct cifsFileInfo *open_file = NULL;
+	struct cifsFileInfo *open_file = NULL;
 	struct cifs_sb_info *cifs_sb;
 	struct cifsTconInfo *pTcon;
 	struct cifsInodeInfo *cifsInode;
@@ -534,21 +547,19 @@
 		full_path = build_path_from_dentry(dirent);
 		rc = CIFSSMBSetEOF(xid, pTcon, full_path, inode->i_size,FALSE,
 				   cifs_sb->local_nls);
-        cFYI(1,("\nSetEOF (truncate) rc = %d",rc));
-        if(rc == -ETXTBSY) {        
-            cifsInode = CIFS_I(inode);
-            if(!list_empty(&(cifsInode->openFileList))) {            
-	            open_file = list_entry(cifsInode->openFileList.next,
-                                       struct cifsFileInfo, flist);           
-                /* We could check if file is open for writing first and 
-                   also we could also override the smb pid with the pid 
-                   of the file opener when sending the CIFS request */
-                rc = CIFSSMBSetFileSize(xid, pTcon, inode->i_size,
-                                        open_file->netfid,open_file->pid,FALSE);
-            } else {
-                cFYI(1,("\nNo open files to get file handle from"));
-            }
-        }
+		cFYI(1,("\nSetEOF (truncate) rc = %d",rc));
+		if(rc == -ETXTBSY) {        
+			cifsInode = CIFS_I(inode);
+			if(!list_empty(&(cifsInode->openFileList))) {            
+				open_file = list_entry(cifsInode->openFileList.next,
+					struct cifsFileInfo, flist);           
+            /* We could check if file is open for writing first */
+				 rc = CIFSSMBSetFileSize(xid, pTcon, inode->i_size,
+					open_file->netfid,open_file->pid,FALSE);
+			} else {
+				  cFYI(1,("\nNo open files to get file handle from"));
+			}
+		}
 		if (!rc)
 			CIFSSMBSetEOF(xid,pTcon,full_path,inode->i_size,TRUE,cifs_sb->local_nls);
            /* allocation size setting seems optional so ignore return code */
@@ -567,7 +578,7 @@
 	struct cifsTconInfo *pTcon;
 	char *full_path = NULL;
 	int rc = -EACCES;
-    struct cifsFileInfo *open_file = NULL;
+	struct cifsFileInfo *open_file = NULL;
 	FILE_BASIC_INFO time_buf;
 	int set_time = FALSE;
 	__u64 mode = 0xFFFFFFFFFFFFFFFF;
@@ -593,19 +604,19 @@
 	if (attrs->ia_valid & ATTR_SIZE) {
 		rc = CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size,FALSE,
 				   cifs_sb->local_nls);
-        cFYI(1,("\nSetEOF (setattrs) rc = %d",rc));
+		cFYI(1,("\nSetEOF (setattrs) rc = %d",rc));
 
-        if(rc == -ETXTBSY) {
-            if(!list_empty(&(cifsInode->openFileList))) {            
-                open_file = list_entry(cifsInode->openFileList.next, 
-                               struct cifsFileInfo, flist);           
+		if(rc == -ETXTBSY) {
+			if(!list_empty(&(cifsInode->openFileList))) {            
+				open_file = list_entry(cifsInode->openFileList.next, 
+					   struct cifsFileInfo, flist);           
     /* We could check if file is open for writing first */
-                rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size,
-                                        open_file->netfid,open_file->pid,FALSE);           
-            } else {
-                cFYI(1,("\nNo open files to get file handle from"));
-            }
-        }
+				rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size,
+					   open_file->netfid,open_file->pid,FALSE);           
+			} else {
+				cFYI(1,("\nNo open files to get file handle from"));
+			}
+		}
         /*  Set Allocation Size of file - might not even need to call the
             following but might as well and it does not hurt if it fails */
 		CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size, TRUE, cifs_sb->local_nls);
@@ -684,5 +695,4 @@
 	cFYI(1, ("In cifs_delete_inode, inode = 0x%p\n", inode));
 	/* may have to add back in when safe distributed caching of
              directories via e.g. FindNotify added */
-
 }
diff -Nru a/fs/cifs/md5.h b/fs/cifs/md5.h
--- a/fs/cifs/md5.h	Mon Nov  4 14:31:00 2002
+++ b/fs/cifs/md5.h	Mon Nov  4 14:31:00 2002
@@ -22,17 +22,17 @@
 
 void MD5Init(struct MD5Context *context);
 void MD5Update(struct MD5Context *context, unsigned char const *buf,
-	       unsigned len);
+			unsigned len);
 void MD5Final(unsigned char digest[16], struct MD5Context *context);
 
 /* The following definitions come from lib/hmacmd5.c  */
 
 void hmac_md5_init_rfc2104(unsigned char *key, int key_len,
-			   struct HMACMD5Context *ctx);
+			struct HMACMD5Context *ctx);
 void hmac_md5_init_limK_to_64(const unsigned char *key, int key_len,
-			      struct HMACMD5Context *ctx);
+			struct HMACMD5Context *ctx);
 void hmac_md5_update(const unsigned char *text, int text_len,
-		     struct HMACMD5Context *ctx);
+			struct HMACMD5Context *ctx);
 void hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx);
 void hmac_md5(unsigned char key[16], unsigned char *data, int data_len,
-	      unsigned char *digest);
+			unsigned char *digest);
diff -Nru a/fs/cifs/misc.c b/fs/cifs/misc.c
--- a/fs/cifs/misc.c	Mon Nov  4 14:31:02 2002
+++ b/fs/cifs/misc.c	Mon Nov  4 14:31:02 2002
@@ -28,7 +28,6 @@
 
 extern kmem_cache_t *cifs_req_cachep;
 
-static DECLARE_MUTEX(GlobalMid_Sem);	/* also protects XID globals */
 __u16 GlobalMid;		/* multiplex id - rotating counter */
 
 /* The xid serves as a useful identifier for each incoming vfs request, 
@@ -42,21 +41,21 @@
 {
 	unsigned int xid;
 
-	down(&GlobalMid_Sem);
+	write_lock(&GlobalMid_Lock);
 	GlobalTotalActiveXid++;
 	if (GlobalTotalActiveXid > GlobalMaxActiveXid)
 		GlobalMaxActiveXid = GlobalTotalActiveXid;	/* keep high water mark for number of simultaneous vfs ops in our filesystem */
 	xid = GlobalCurrentXid++;
-	up(&GlobalMid_Sem);
+	write_unlock(&GlobalMid_Lock);
 	return xid;
 }
 
 void
 _FreeXid(unsigned int xid)
 {
-	down(&GlobalMid_Sem);
+	write_lock(&GlobalMid_Lock);
 	GlobalTotalActiveXid--;
-	up(&GlobalMid_Sem);
+	write_unlock(&GlobalMid_Lock);
 }
 
 struct cifsSesInfo *
@@ -69,9 +68,11 @@
 					   GFP_KERNEL);
 	if (ret_buf) {
 		memset(ret_buf, 0, sizeof (struct cifsSesInfo));
+		write_lock(&GlobalSMBSeslock);
 		atomic_inc(&sesInfoAllocCount);
 		list_add(&ret_buf->cifsSessionList, &GlobalSMBSessionList);
 		init_MUTEX(&ret_buf->sesSem);
+		write_unlock(&GlobalSMBSeslock);
 	}
 	return ret_buf;
 }
@@ -84,8 +85,10 @@
 		return;
 	}
 
+	write_lock(&GlobalSMBSeslock);
 	atomic_dec(&sesInfoAllocCount);
 	list_del(&buf_to_free->cifsSessionList);
+	write_unlock(&GlobalSMBSeslock);
 	if (buf_to_free->serverOS)
 		kfree(buf_to_free->serverOS);
 	if (buf_to_free->serverDomain)
@@ -104,11 +107,13 @@
 					    GFP_KERNEL);
 	if (ret_buf) {
 		memset(ret_buf, 0, sizeof (struct cifsTconInfo));
+		write_lock(&GlobalSMBSeslock);
 		atomic_inc(&tconInfoAllocCount);
 		list_add(&ret_buf->cifsConnectionList,
 			 &GlobalTreeConnectionList);
-        INIT_LIST_HEAD(&ret_buf->openFileList);
+		INIT_LIST_HEAD(&ret_buf->openFileList);
 		init_MUTEX(&ret_buf->tconSem);
+		write_unlock(&GlobalSMBSeslock);
 	}
 	return ret_buf;
 }
@@ -120,9 +125,10 @@
 		cFYI(1, ("\nNull buffer passed to tconInfoFree"));
 		return;
 	}
-
+	write_lock(&GlobalSMBSeslock);
 	atomic_dec(&tconInfoAllocCount);
 	list_del(&buf_to_free->cifsConnectionList);
+	write_unlock(&GlobalSMBSeslock);
 	if (buf_to_free->nativeFileSystem)
 		kfree(buf_to_free->nativeFileSystem);
 	kfree(buf_to_free);
@@ -203,9 +209,10 @@
 	buffer->Pid = tmp & 0xFFFF;
 	tmp >>= 16;
 	buffer->PidHigh = tmp & 0xFFFF;
-	down(&GlobalMid_Sem);
+	write_lock(&GlobalMid_Lock);
 	GlobalMid++;
 	buffer->Mid = GlobalMid;
+	write_unlock(&GlobalMid_Lock);
 	if (treeCon) {
 		buffer->Tid = treeCon->tid;
 		if (treeCon->ses) {
@@ -218,13 +225,11 @@
 		}
 		if (treeCon->Flags & SMB_SHARE_IS_IN_DFS)
 			buffer->Flags2 |= SMBFLG2_DFS;
-        if(treeCon->ses->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
-            buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
-
+		if(treeCon->ses->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
+			buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
 	}
 
 /*  endian conversion of flags is now done just before sending */
-	up(&GlobalMid_Sem);
 	buffer->WordCount = (char) word_count;
 	return;
 }
@@ -233,17 +238,18 @@
 checkSMBhdr(struct smb_hdr *smb, __u16 mid)
 {
 	/* Make sure that this really is an SMB, that it is a response, 
-        and that the message ids match */
-	if ((*(unsigned int *) smb->Protocol == cpu_to_le32(0x424d53ff)) && (mid == smb->Mid)) {    
-        if(smb->Flags & SMBFLG_RESPONSE)
-            return 0;                    
-        else {        
-    /* only one valid case where server sends us request */
-            if(smb->Command == SMB_COM_LOCKING_ANDX)
-                return 0;
-            else
-                cERROR(1, ("\n Rcvd Request not response "));         
-        }
+	   and that the message ids match */
+	if ((*(unsigned int *) smb->Protocol == cpu_to_le32(0x424d53ff)) && 
+		(mid == smb->Mid)) {    
+		if(smb->Flags & SMBFLG_RESPONSE)
+			return 0;                    
+		else {        
+		/* only one valid case where server sends us request */
+			if(smb->Command == SMB_COM_LOCKING_ANDX)
+				return 0;
+			else
+				cERROR(1, ("\n Rcvd Request not response "));         
+		}
 	} else { /* bad signature or mid */
 		if (*(unsigned int *) smb->Protocol != cpu_to_le32(0x424d53ff))
 			cERROR(1,
@@ -252,8 +258,8 @@
 		if (mid != smb->Mid)
 			cERROR(1, ("\n Mids do not match \n"));
 	}
-    cERROR(1, ("\nCIFS: bad smb detected. The Mid=%d\n", smb->Mid));
-    return 1;
+	cERROR(1, ("\nCIFS: bad smb detected. The Mid=%d\n", smb->Mid));
+	return 1;
 }
 
 int
@@ -269,7 +275,7 @@
 			cERROR(1, ("\n Length less than 2 + sizeof smb_hdr "));
 			if ((length >= sizeof (struct smb_hdr) - 1)
 			    && (smb->Status.CifsError != 0))
-				return 0;	/* this is ok - some error cases do not return wct and bcc */
+				return 0;	/* some error cases do not return wct and bcc */
 
 		}
 		if (4 + ntohl(smb->smb_buf_length) >
@@ -298,30 +304,42 @@
 int
 is_valid_oplock_break(struct smb_hdr *buf)
 {    
-    struct smb_com_lock_req * pSMB = (struct smb_com_lock_req *)buf;
-
-    /* could add check for smb response flag 0x80 */
-    cFYI(1,("\nChecking for oplock break"));    
-    if(pSMB->hdr.Command != SMB_COM_LOCKING_ANDX)
-        return FALSE;
-    if(pSMB->hdr.Flags & SMBFLG_RESPONSE)
-        return FALSE; /* server sends us "request" here */
-    if(pSMB->hdr.WordCount != 8)
-        return FALSE;
-
-    cFYI(1,(" oplock type 0x%d level 0x%d",pSMB->LockType,pSMB->OplockLevel));
-    if(!(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE))
-        return FALSE;    
-
-    /* BB Add following logic: 
-       1) look up tcon based on tid & uid 
-       2) look up inode from tcon->openFileList->file->f_dentry->d_inode 
-       3) flush dirty pages and cached byte range locks and mark inode   
-       4) depending on break type change to r/o caching or no caching
-       5) send oplock break response to server */
-    cFYI(1,("\nNeed to process oplock break "));
-
-    return TRUE;
+       struct smb_com_lock_req * pSMB = (struct smb_com_lock_req *)buf;
+       struct list_head *tmp;
+       struct cifsTconInfo *tcon;
+
+       /* could add check for smb response flag 0x80 */
+       cFYI(1,("\nChecking for oplock break"));    
+       if(pSMB->hdr.Command != SMB_COM_LOCKING_ANDX)
+               return FALSE;
+       if(pSMB->hdr.Flags & SMBFLG_RESPONSE)
+               return FALSE; /* server sends us "request" here */
+       if(pSMB->hdr.WordCount != 8)
+               return FALSE;
+
+       cFYI(1,(" oplock type 0x%d level 0x%d",pSMB->LockType,pSMB->OplockLevel));
+       if(!(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE))
+               return FALSE;    
+
+       /* look up tcon based on tid & uid */
+       read_lock(&GlobalSMBSeslock);
+       list_for_each(tmp, &GlobalTreeConnectionList) {
+               tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
+               if (tcon->tid == buf->Tid)
+                       if(tcon->ses->Suid == buf->Uid) {
+                       /* BB Add following logic: 
+                         2) look up inode from tcon->openFileList->file->f_dentry->d_inode
+                         3) flush dirty pages and cached byte range locks and mark inode
+                         4) depending on break type change to r/o caching or no caching
+                         5) send oplock break response to server */
+                               read_unlock(&GlobalSMBSeslock);
+                               cFYI(1,("\nFound matching connection, process oplock break"));
+                               return TRUE;
+                       }
+       }
+       read_unlock(&GlobalSMBSeslock);
+       cFYI(1,("\nProcessing oplock break for non-existent connection"));
+       return TRUE;
 }
 
 void
diff -Nru a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
--- a/fs/cifs/netmisc.c	Mon Nov  4 14:31:02 2002
+++ b/fs/cifs/netmisc.c	Mon Nov  4 14:31:02 2002
@@ -745,7 +745,28 @@
 	ERRDOS, ERRnoaccess, 0xc0000290}, {
 ERRDOS, ERRbadfunc, 0xc000029c},};
 
-void
+/*****************************************************************************
+ Print an error message from the status code
+ *****************************************************************************/
+static void
+cifs_print_status(__u32 status_code)
+{
+	int idx = 0;
+
+	printk("\nStatus code returned: 0x%08x", status_code);
+
+	while (nt_errs[idx].nt_errstr != NULL) {
+		if (((nt_errs[idx].nt_errcode) & 0xFFFFFF) ==
+		    (status_code & 0xFFFFFF)) {
+			printk(nt_errs[idx].nt_errstr);
+		}
+		idx++;
+	}
+	return;
+}
+
+
+static void
 ntstatus_to_dos(__u32 ntstatus, __u8 * eclass, __u16 * ecode)
 {
 	int i;
@@ -781,9 +802,9 @@
 
 	if (smb->Flags2 & SMBFLG2_ERR_STATUS) {
 		/* translate the newer STATUS codes to old style errors and then to POSIX errors */
-		cFYI(1,
-		     (" !!Mapping cifs error code %d ", smb->Status.CifsError));
 		smb->Status.CifsError = le32_to_cpu(smb->Status.CifsError);
+		if(cifsFYI)
+			cifs_print_status(smb->Status.CifsError);
 		ntstatus_to_dos(smb->Status.CifsError, &smberrclass,
 				&smberrcode);
 	} else {
diff -Nru a/fs/cifs/nterr.c b/fs/cifs/nterr.c
--- a/fs/cifs/nterr.c	Mon Nov  4 14:31:00 2002
+++ b/fs/cifs/nterr.c	Mon Nov  4 14:31:00 2002
@@ -20,14 +20,9 @@
  */
 
 /* NT error codes - see nterr.h */
-#include "nterr.h"
 #include <linux/types.h>
 #include <linux/fs.h>
-
-struct nt_err_code_struct {
-	char *nt_errstr;
-	__u32 nt_errcode;
-};
+#include "nterr.h"
 
 const struct nt_err_code_struct nt_errs[] = {
 	{"NT_STATUS_OK", NT_STATUS_OK},
@@ -690,23 +685,3 @@
 	{"STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED},
 	{NULL, 0}
 };
-
-/*****************************************************************************
- Print an error message from the status code
- *****************************************************************************/
-/* void
-cifs_print_status(__u32 status_code)
-{
-	int idx = 0;
-
-	printk("\nStatus code returned: 0x%08x", status_code);
-
-	while (nt_errs[idx].nt_errstr != NULL) {
-		if (((nt_errs[idx].nt_errcode) & 0xFFFFFF) ==
-		    (status_code & 0xFFFFFF)) {
-			printk(nt_errs[idx].nt_errstr);
-		}
-		idx++;
-	}
-	return;
-} */
diff -Nru a/fs/cifs/nterr.h b/fs/cifs/nterr.h
--- a/fs/cifs/nterr.h	Mon Nov  4 14:31:00 2002
+++ b/fs/cifs/nterr.h	Mon Nov  4 14:31:00 2002
@@ -22,8 +22,17 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+
+
 #ifndef _NTERR_H
 #define _NTERR_H
+
+struct nt_err_code_struct {
+	char *nt_errstr;
+	__u32 nt_errcode;
+};
+
+extern const struct nt_err_code_struct nt_errs[];
 
 /* Win32 Status codes. */
 
diff -Nru a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c
--- a/fs/cifs/smbencrypt.c	Mon Nov  4 14:31:01 2002
+++ b/fs/cifs/smbencrypt.c	Mon Nov  4 14:31:01 2002
@@ -205,19 +205,26 @@
 /* Does the NTLMv2 owfs of a user's password */
 void
 ntv2_owf_gen(const unsigned char owf[16], const char *user_n,
-	     const char *domain_n, unsigned char kr_buf[16],
-	     const struct nls_table *nls_codepage)
+		const char *domain_n, unsigned char kr_buf[16],
+		const struct nls_table *nls_codepage)
 {
-	wchar_t user_u[1024];
-	wchar_t dom_u[1024];
+	wchar_t * user_u;
+	wchar_t * dom_u;
+	int user_l, domain_l;
 	struct HMACMD5Context ctx;
 
+	/* might as well do one alloc to hold both (user_u and dom_u) */
+	user_u = kmalloc(2048 * sizeof(wchar_t),GFP_KERNEL); 
+	if(user_u == NULL)
+		return;
+	dom_u = user_u + 1024;
+    
 	/* push_ucs2(NULL, user_u, user_n, (user_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER);
 	   push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); */
 
-    /* do not think it is supposed to be uppercased */
-	int user_l = cifs_strtoUCS(user_u, user_n, 511, nls_codepage);
-	int domain_l = cifs_strtoUCS(dom_u, domain_n, 511, nls_codepage);
+	/* do not think it is supposed to be uppercased */
+	user_l = cifs_strtoUCS(user_u, user_n, 511, nls_codepage);
+	domain_l = cifs_strtoUCS(dom_u, domain_n, 511, nls_codepage);
 
 	user_l++;		/* trailing null */
 	domain_l++;
@@ -234,6 +241,7 @@
 	dump_data(100, owf, 16);
 	dump_data(100, kr_buf, 16);
 #endif
+	kfree(user_u);
 }
 
 /* Does the des encryption from the NT or LM MD4 hash. */
diff -Nru a/fs/cifs/transport.c b/fs/cifs/transport.c
--- a/fs/cifs/transport.c	Mon Nov  4 14:31:01 2002
+++ b/fs/cifs/transport.c	Mon Nov  4 14:31:01 2002
@@ -59,9 +59,11 @@
 		temp->tsk = current;
 	}
 	if (ses->status == CifsGood) {
+		write_lock(&GlobalMid_Lock);
 		list_add_tail(&temp->qhead, &ses->server->pending_mid_q);
 		atomic_inc(&midCount);
 		temp->midState = MID_REQUEST_ALLOCATED;
+		write_unlock(&GlobalMid_Lock);
 	} else {		/* BB add reconnect code here BB */
 
 		cERROR(1,
@@ -77,11 +79,13 @@
 DeleteMidQEntry(struct mid_q_entry *midEntry)
 {
 	/* BB add spinlock to protect midq for each session BB */
+	write_lock(&GlobalMid_Lock);
 	midEntry->midState = MID_FREE;
-	buf_release(midEntry->resp_buf);
 	list_del(&midEntry->qhead);
-	kmem_cache_free(cifs_mid_cachep, midEntry);
 	atomic_dec(&midCount);
+	write_unlock(&GlobalMid_Lock);
+	buf_release(midEntry->resp_buf);
+	kmem_cache_free(cifs_mid_cachep, midEntry);
 }
 
 int
@@ -93,8 +97,8 @@
 	struct iovec iov;
 	mm_segment_t temp_fs;
 
-    if(ssocket == NULL)
-        return -ENOTSOCK; /* BB eventually add reconnect code here */
+	if(ssocket == NULL)
+		return -ENOTSOCK; /* BB eventually add reconnect code here */
 /*  ssocket->sk->allocation = GFP_BUFFER; *//* BB is this spurious? */
 	iov.iov_base = smb_buffer;
 	iov.iov_len = smb_buf_length + 4;
@@ -159,8 +163,6 @@
 	rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
 		      (struct sockaddr *) &(ses->server->sockAddr));
 
-	cFYI(1, ("\ncifs smb_send rc %d", rc));	/* BB remove */
-	/* BB add code to wait for response and copy to out_buf */
 	if (long_op > 1)	/* writes past end of file can take a looooooong time */
 		timeout = 300 * HZ;
 	else if (long_op == 1)
@@ -174,10 +176,9 @@
 	/* Replace above line with wait_event to get rid of sleep_on per lk guidelines */
 
 	timeout = wait_event_interruptible_timeout(ses->server->response_q,
-						   midQ->
-						   midState &
-						   MID_RESPONSE_RECEIVED,
-						   15 * HZ);
+				midQ->
+				midState & MID_RESPONSE_RECEIVED,
+				timeout);
 	cFYI(1,
 	     (" with timeout %ld and Out_buf: %p  midQ->resp_buf: %p ", timeout,
 	      out_buf, midQ->resp_buf));
@@ -240,6 +241,8 @@
 			rc = -EIO;
 	}
 
-	DeleteMidQEntry(midQ);	/* BB what if process is killed ? - BB add background daemon to clean up Mid entries from killed processes BB test killing process with active mid */
+	DeleteMidQEntry(midQ);	/* BB what if process is killed?
+			 - BB add background daemon to clean up Mid entries from
+			 killed processes & test killing process with active mid */
 	return rc;
 }
diff -Nru a/fs/dcookies.c b/fs/dcookies.c
--- a/fs/dcookies.c	Mon Nov  4 14:31:00 2002
+++ b/fs/dcookies.c	Mon Nov  4 14:31:00 2002
@@ -8,7 +8,7 @@
  * non-transitory that can be processed at a later date.
  * This is done by locking the dentry/vfsmnt pair in the
  * kernel until released by the tasks needing the persistent
- * objects. The tag is simply an u32 that refers
+ * objects. The tag is simply an unsigned long that refers
  * to the pair and can be looked up from userspace.
  */
 
@@ -46,19 +46,19 @@
 
 
 /* The dentry is locked, its address will do for the cookie */
-static inline u32 dcookie_value(struct dcookie_struct * dcs)
+static inline unsigned long dcookie_value(struct dcookie_struct * dcs)
 {
-	return (u32)dcs->dentry;
+	return (unsigned long)dcs->dentry;
 }
 
 
-static size_t dcookie_hash(u32 dcookie)
+static size_t dcookie_hash(unsigned long dcookie)
 {
-	return (dcookie >> 2) & (hash_size - 1);
+	return (dcookie >> L1_CACHE_SHIFT) & (hash_size - 1);
 }
 
 
-static struct dcookie_struct * find_dcookie(u32 dcookie)
+static struct dcookie_struct * find_dcookie(unsigned long dcookie)
 {
 	struct dcookie_struct * found = 0;
 	struct dcookie_struct * dcs;
@@ -109,7 +109,7 @@
  * value for a dentry/vfsmnt pair.
  */
 int get_dcookie(struct dentry * dentry, struct vfsmount * vfsmnt,
-	u32 * cookie)
+	unsigned long * cookie)
 {
 	int err = 0;
 	struct dcookie_struct * dcs;
@@ -142,11 +142,12 @@
 /* And here is where the userspace process can look up the cookie value
  * to retrieve the path.
  */
-asmlinkage int sys_lookup_dcookie(u32 cookie, char * buf, size_t len)
+asmlinkage int sys_lookup_dcookie(u64 cookie64, char * buf, size_t len)
 {
+	unsigned long cookie = (unsigned long)cookie64;
+	int err = -EINVAL;
 	char * kbuf;
 	char * path;
-	int err = -EINVAL;
 	size_t pathlen;
 	struct dcookie_struct * dcs;
 
@@ -170,19 +171,18 @@
 	kbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
 	if (!kbuf)
 		goto out;
-	memset(kbuf, 0, PAGE_SIZE);
 
 	/* FIXME: (deleted) ? */
 	path = d_path(dcs->dentry, dcs->vfsmnt, kbuf, PAGE_SIZE);
 
-	err = 0;
-
+	err = -ERANGE;
+ 
 	pathlen = kbuf + PAGE_SIZE - path;
-	if (len > pathlen)
-		len = pathlen;
-
-	if (copy_to_user(buf, path, len))
-		err = -EFAULT;
+	if (pathlen <= len) {
+		err = pathlen;
+		if (copy_to_user(buf, path, pathlen))
+			err = -EFAULT;
+	}
 
 	kfree(kbuf);
 out:
diff -Nru a/fs/direct-io.c b/fs/direct-io.c
--- a/fs/direct-io.c	Mon Nov  4 14:31:02 2002
+++ b/fs/direct-io.c	Mon Nov  4 14:31:02 2002
@@ -139,7 +139,7 @@
 		 */
 		if (dio->page_errors == 0)
 			dio->page_errors = ret;
-		dio->pages[0] = ZERO_PAGE(dio->cur_user_address);
+		dio->pages[0] = ZERO_PAGE(dio->curr_user_address);
 		dio->head = 0;
 		dio->tail = 1;
 		ret = 0;
diff -Nru a/fs/driverfs/Makefile b/fs/driverfs/Makefile
--- a/fs/driverfs/Makefile	Mon Nov  4 14:31:03 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,9 +0,0 @@
-#
-# Makefile for the driverfs virtual filesystem.
-#
-
-export-objs := inode.o
-
-obj-y := inode.o
-
-include $(TOPDIR)/Rules.make
diff -Nru a/fs/driverfs/inode.c b/fs/driverfs/inode.c
--- a/fs/driverfs/inode.c	Mon Nov  4 14:31:00 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,708 +0,0 @@
-/*
- * driverfs.c - The device driver file system
- *
- * Copyright (c) 2001 Patrick Mochel <mochel@osdl.org>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * This is a simple, ram-based filesystem, which allows kernel
- * callbacks for read/write of files.
- *
- * Please see Documentation/filesystems/driverfs.txt for more information.
- */
-
-#include <linux/list.h>
-#include <linux/init.h>
-#include <linux/pagemap.h>
-#include <linux/stat.h>
-#include <linux/fs.h>
-#include <linux/dcache.h>
-#include <linux/namei.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/backing-dev.h>
-#include <linux/driverfs_fs.h>
-
-#include <asm/uaccess.h>
-
-#undef DEBUG
-
-#ifdef DEBUG
-# define DBG(x...) printk(x)
-#else
-# define DBG(x...)
-#endif
-
-/* Random magic number */
-#define DRIVERFS_MAGIC 0x42454552
-
-static struct super_operations driverfs_ops;
-static struct file_operations driverfs_file_operations;
-static struct inode_operations driverfs_dir_inode_operations;
-static struct address_space_operations driverfs_aops;
-
-static struct vfsmount *driverfs_mount;
-static spinlock_t mount_lock = SPIN_LOCK_UNLOCKED;
-static int mount_count = 0;
-
-static struct backing_dev_info driverfs_backing_dev_info = {
-	.ra_pages	= 0,	/* No readahead */
-	.memory_backed	= 1,	/* Does not contribute to dirty memory */
-};
-
-static int driverfs_readpage(struct file *file, struct page * page)
-{
-	if (!PageUptodate(page)) {
-		void *kaddr = kmap_atomic(page, KM_USER0);
-
-		memset(kaddr, 0, PAGE_CACHE_SIZE);
-		flush_dcache_page(page);
-		kunmap_atomic(kaddr, KM_USER0);
-		SetPageUptodate(page);
-	}
-	unlock_page(page);
-	return 0;
-}
-
-static int driverfs_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
-{
-	if (!PageUptodate(page)) {
-		void *kaddr = kmap_atomic(page, KM_USER0);
-
-		memset(kaddr, 0, PAGE_CACHE_SIZE);
-		flush_dcache_page(page);
-		kunmap_atomic(kaddr, KM_USER0);
-		SetPageUptodate(page);
-	}
-	return 0;
-}
-
-static int driverfs_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to)
-{
-	struct inode *inode = page->mapping->host;
-	loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
-
-	set_page_dirty(page);
-	if (pos > inode->i_size)
-		inode->i_size = pos;
-	return 0;
-}
-
-
-struct inode *driverfs_get_inode(struct super_block *sb, int mode, int dev)
-{
-	struct inode *inode = new_inode(sb);
-
-	if (inode) {
-		inode->i_mode = mode;
-		inode->i_uid = current->fsuid;
-		inode->i_gid = current->fsgid;
-		inode->i_blksize = PAGE_CACHE_SIZE;
-		inode->i_blocks = 0;
-		inode->i_rdev = NODEV;
-		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-		inode->i_mapping->a_ops = &driverfs_aops;
-		inode->i_mapping->backing_dev_info = &driverfs_backing_dev_info;
-		switch (mode & S_IFMT) {
-		default:
-			init_special_inode(inode, mode, dev);
-			break;
-		case S_IFREG:
-			inode->i_fop = &driverfs_file_operations;
-			break;
-		case S_IFDIR:
-			inode->i_op = &driverfs_dir_inode_operations;
-			inode->i_fop = &simple_dir_operations;
-
-			/* directory inodes start off with i_nlink == 2 (for "." entry) */
-			inode->i_nlink++;
-			break;
-		case S_IFLNK:
-			inode->i_op = &page_symlink_inode_operations;
-			break;
-		}
-	}
-	return inode;
-}
-
-static int driverfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev)
-{
-	struct inode *inode;
-	int error = -ENOSPC;
-
-	if (dentry->d_inode)
-		return -EEXIST;
-
-	/* only allow create if ->d_fsdata is not NULL (so we can assume it 
-	 * comes from the driverfs API below. */
-	inode = driverfs_get_inode(dir->i_sb, mode, dev);
-	if (inode) {
-		d_instantiate(dentry, inode);
-		error = 0;
-	}
-	return error;
-}
-
-static int driverfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
-{
-	int res;
-	mode = (mode & (S_IRWXUGO|S_ISVTX)) | S_IFDIR;
- 	res = driverfs_mknod(dir, dentry, mode, 0);
- 	if (!res)
- 		dir->i_nlink++;
-	return res;
-}
-
-static int driverfs_create(struct inode *dir, struct dentry *dentry, int mode)
-{
-	int res;
-	mode = (mode & S_IALLUGO) | S_IFREG;
- 	res = driverfs_mknod(dir, dentry, mode, 0);
-	return res;
-}
-
-static int driverfs_symlink(struct inode * dir, struct dentry *dentry, const char * symname)
-{
-	struct inode *inode;
-	int error = -ENOSPC;
-
-	if (dentry->d_inode)
-		return -EEXIST;
-
-	inode = driverfs_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0);
-	if (inode) {
-		int l = strlen(symname)+1;
-		error = page_symlink(inode, symname, l);
-		if (!error) {
-			d_instantiate(dentry, inode);
-			dget(dentry);
-		} else
-			iput(inode);
-	}
-	return error;
-}
-
-static inline int driverfs_positive(struct dentry *dentry)
-{
-	return (dentry->d_inode && !d_unhashed(dentry));
-}
-
-static int driverfs_empty(struct dentry *dentry)
-{
-	struct list_head *list;
-
-	spin_lock(&dcache_lock);
-
-	list_for_each(list, &dentry->d_subdirs) {
-		struct dentry *de = list_entry(list, struct dentry, d_child);
-		if (driverfs_positive(de)) {
-			spin_unlock(&dcache_lock);
-			return 0;
-		}
-	}
-
-	spin_unlock(&dcache_lock);
-	return 1;
-}
-
-static int driverfs_unlink(struct inode *dir, struct dentry *dentry)
-{
-	struct inode *inode = dentry->d_inode;
-	down(&inode->i_sem);
-	dentry->d_inode->i_nlink--;
-	up(&inode->i_sem);
-	d_invalidate(dentry);
-	dput(dentry);
-	return 0;
-}
-
-/**
- * driverfs_read_file - "read" data from a file.
- * @file:	file pointer
- * @buf:	buffer to fill
- * @count:	number of bytes to read
- * @ppos:	starting offset in file
- *
- * Userspace wants data from a file. It is up to the creator of the file to
- * provide that data.
- * There is a struct device_attribute embedded in file->private_data. We
- * obtain that and check if the read callback is implemented. If so, we call
- * it, passing the data field of the file entry.
- * Said callback is responsible for filling the buffer and returning the number
- * of bytes it put in it. We update @ppos correctly.
- */
-static ssize_t
-driverfs_read_file(struct file *file, char *buf, size_t count, loff_t *ppos)
-{
-	struct attribute * attr = file->f_dentry->d_fsdata;
-	struct driver_dir_entry * dir;
-	unsigned char *page;
-	ssize_t retval = 0;
-
-	dir = file->f_dentry->d_parent->d_fsdata;
-	if (!dir->ops->show)
-		return 0;
-
-	if (count > PAGE_SIZE)
-		count = PAGE_SIZE;
-
-	page = (unsigned char*)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
-	while (count > 0) {
-		ssize_t len;
-
-		len = dir->ops->show(dir,attr,page,count,*ppos);
-
-		if (len <= 0) {
-			if (len < 0)
-				retval = len;
-			break;
-		} else if (len > count)
-			len = count;
-
-		if (copy_to_user(buf,page,len)) {
-			retval = -EFAULT;
-			break;
-		}
-
-		*ppos += len;
-		count -= len;
-		buf += len;
-		retval += len;
-	}
-	free_page((unsigned long)page);
-	return retval;
-}
-
-/**
- * driverfs_write_file - "write" to a file
- * @file:	file pointer
- * @buf:	data to write
- * @count:	number of bytes
- * @ppos:	starting offset
- *
- * Similarly to driverfs_read_file, we act essentially as a bit pipe.
- * We check for a "write" callback in file->private_data, and pass
- * @buffer, @count, @ppos, and the file entry's data to the callback.
- * The number of bytes written is returned, and we handle updating
- * @ppos properly.
- */
-static ssize_t
-driverfs_write_file(struct file *file, const char *buf, size_t count, loff_t *ppos)
-{
-	struct attribute * attr = file->f_dentry->d_fsdata;
-	struct driver_dir_entry * dir;
-	ssize_t retval = 0;
-	char * page;
-
-	dir = file->f_dentry->d_parent->d_fsdata;
-
-	page = (char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
-	if (count >= PAGE_SIZE)
-		count = PAGE_SIZE - 1;
-	if (copy_from_user(page,buf,count))
-		goto done;
-	*(page + count) = '\0';
-
-	while (count > 0) {
-		ssize_t len;
-
-		len = dir->ops->store(dir,attr,page + retval,count,*ppos);
-
-		if (len <= 0) {
-			if (len < 0)
-				retval = len;
-			break;
-		}
-		retval += len;
-		count -= len;
-		*ppos += len;
-		buf += len;
-	}
- done:
-	free_page((unsigned long)page);
-	return retval;
-}
-
-static loff_t
-driverfs_file_lseek(struct file *file, loff_t offset, int orig)
-{
-	loff_t retval = -EINVAL;
-
-	down(&file->f_dentry->d_inode->i_sem);
-	switch(orig) {
-	case 0:
-		if (offset > 0) {
-			file->f_pos = offset;
-			retval = file->f_pos;
-		}
-		break;
-	case 1:
-		if ((offset + file->f_pos) > 0) {
-			file->f_pos += offset;
-			retval = file->f_pos;
-		}
-		break;
-	default:
-		break;
-	}
-	up(&file->f_dentry->d_inode->i_sem);
-	return retval;
-}
-
-static int driverfs_open_file(struct inode * inode, struct file * filp)
-{
-	struct driver_dir_entry * dir;
-	int error = 0;
-
-	dir = (struct driver_dir_entry *)filp->f_dentry->d_parent->d_fsdata;
-	if (dir) {
-		struct attribute * attr = filp->f_dentry->d_fsdata;
-		if (attr && dir->ops) {
-			if (dir->ops->open)
-				error = dir->ops->open(dir);
-			goto Done;
-		}
-	}
-	error = -EINVAL;
- Done:
-	return error;
-}
-
-static int driverfs_release(struct inode * inode, struct file * filp)
-{
-	struct driver_dir_entry * dir;
-	dir = (struct driver_dir_entry *)filp->f_dentry->d_parent->d_fsdata;
-	if (dir->ops->close)
-		dir->ops->close(dir);
-	return 0;
-}
-
-static struct file_operations driverfs_file_operations = {
-	.read		= driverfs_read_file,
-	.write		= driverfs_write_file,
-	.llseek		= driverfs_file_lseek,
-	.open		= driverfs_open_file,
-	.release	= driverfs_release,
-};
-
-static struct inode_operations driverfs_dir_inode_operations = {
-	.lookup		= simple_lookup,
-};
-
-static struct address_space_operations driverfs_aops = {
-	.readpage	= driverfs_readpage,
-	.writepage	= fail_writepage,
-	.prepare_write	= driverfs_prepare_write,
-	.commit_write	= driverfs_commit_write
-};
-
-static struct super_operations driverfs_ops = {
-	.statfs		= simple_statfs,
-	.drop_inode	= generic_delete_inode,
-};
-
-static int driverfs_fill_super(struct super_block *sb, void *data, int silent)
-{
-	struct inode *inode;
-	struct dentry *root;
-
-	sb->s_blocksize = PAGE_CACHE_SIZE;
-	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
-	sb->s_magic = DRIVERFS_MAGIC;
-	sb->s_op = &driverfs_ops;
-	inode = driverfs_get_inode(sb, S_IFDIR | 0755, 0);
-
-	if (!inode) {
-		DBG("%s: could not get inode!\n",__FUNCTION__);
-		return -ENOMEM;
-	}
-
-	root = d_alloc_root(inode);
-	if (!root) {
-		DBG("%s: could not get root dentry!\n",__FUNCTION__);
-		iput(inode);
-		return -ENOMEM;
-	}
-	sb->s_root = root;
-	return 0;
-}
-
-static struct super_block *driverfs_get_sb(struct file_system_type *fs_type,
-	int flags, char *dev_name, void *data)
-{
-	return get_sb_single(fs_type, flags, data, driverfs_fill_super);
-}
-
-static struct file_system_type driverfs_fs_type = {
-	.owner		= THIS_MODULE,
-	.name		= "driverfs",
-	.get_sb		= driverfs_get_sb,
-	.kill_sb	= kill_litter_super,
-};
-
-static int get_mount(void)
-{
-	struct vfsmount * mnt;
-
-	spin_lock(&mount_lock);
-	if (driverfs_mount) {
-		mntget(driverfs_mount);
-		++mount_count;
-		spin_unlock(&mount_lock);
-		goto go_ahead;
-	}
-
-	spin_unlock(&mount_lock);
-	mnt = kern_mount(&driverfs_fs_type);
-
-	if (IS_ERR(mnt)) {
-		printk(KERN_ERR "driverfs: could not mount!\n");
-		return -ENODEV;
-	}
-
-	spin_lock(&mount_lock);
-	if (!driverfs_mount) {
-		driverfs_mount = mnt;
-		++mount_count;
-		spin_unlock(&mount_lock);
-		goto go_ahead;
-	}
-
-	mntget(driverfs_mount);
-	++mount_count;
-	spin_unlock(&mount_lock);
-
- go_ahead:
-	DBG("driverfs: mount_count = %d\n",mount_count);
-	return 0;
-}
-
-static void put_mount(void)
-{
-	struct vfsmount * mnt;
-
-	spin_lock(&mount_lock);
-	mnt = driverfs_mount;
-	--mount_count;
-	if (!mount_count)
-		driverfs_mount = NULL;
-	spin_unlock(&mount_lock);
-	mntput(mnt);
-	DBG("driverfs: mount_count = %d\n",mount_count);
-}
-
-static int __init driverfs_init(void)
-{
-	return register_filesystem(&driverfs_fs_type);
-}
-
-core_initcall(driverfs_init);
-
-static struct dentry * get_dentry(struct dentry * parent, const char * name)
-{
-	struct qstr qstr;
-
-	qstr.name = name;
-	qstr.len = strlen(name);
-	qstr.hash = full_name_hash(name,qstr.len);
-	return lookup_hash(&qstr,parent);
-}
-
-/**
- * driverfs_create_dir - create a directory in the filesystem
- * @entry:	directory entry
- * @parent:	parent directory entry
- */
-int
-driverfs_create_dir(struct driver_dir_entry * entry,
-		    struct driver_dir_entry * parent)
-{
-	struct dentry * dentry = NULL;
-	struct dentry * parent_dentry;
-	int error = 0;
-
-	if (!entry)
-		return -EINVAL;
-
-	get_mount();
-
-	parent_dentry = parent ? parent->dentry : NULL;
-
-	if (!parent_dentry)
-		if (driverfs_mount && driverfs_mount->mnt_sb)
-			parent_dentry = driverfs_mount->mnt_sb->s_root;
-
-	if (!parent_dentry) {
-		put_mount();
-		return -EFAULT;
-	}
-
-	down(&parent_dentry->d_inode->i_sem);
-	dentry = get_dentry(parent_dentry,entry->name);
-	if (!IS_ERR(dentry)) {
-		dentry->d_fsdata = (void *) entry;
-		entry->dentry = dentry;
-		error = driverfs_mkdir(parent_dentry->d_inode,dentry,entry->mode);
-	} else
-		error = PTR_ERR(dentry);
-	up(&parent_dentry->d_inode->i_sem);
-
-	if (error)
-		put_mount();
-	return error;
-}
-
-/**
- * driverfs_create_file - create a file
- * @entry:	structure describing the file
- * @parent:	directory to create it in
- */
-int
-driverfs_create_file(struct attribute * entry,
-		     struct driver_dir_entry * parent)
-{
-	struct dentry * dentry;
-	int error = 0;
-
-	if (!entry || !parent)
-		return -EINVAL;
-
-	if (!parent->dentry) {
-		put_mount();
-		return -EINVAL;
-	}
-
-	down(&parent->dentry->d_inode->i_sem);
-	dentry = get_dentry(parent->dentry,entry->name);
-	if (!IS_ERR(dentry)) {
-		dentry->d_fsdata = (void *)entry;
-		error = driverfs_create(parent->dentry->d_inode,dentry,entry->mode);
-	} else
-		error = PTR_ERR(dentry);
-	up(&parent->dentry->d_inode->i_sem);
-	return error;
-}
-
-/**
- * driverfs_create_symlink - make a symlink
- * @parent:	directory we're creating in 
- * @entry:	entry describing link
- * @target:	place we're symlinking to
- * 
- */
-int driverfs_create_symlink(struct driver_dir_entry * parent, 
-			    char * name, char * target)
-{
-	struct dentry * dentry;
-	int error = 0;
-
-	if (!parent)
-		return -EINVAL;
-
-	if (!parent->dentry) {
-		put_mount();
-		return -EINVAL;
-	}
-	down(&parent->dentry->d_inode->i_sem);
-	dentry = get_dentry(parent->dentry,name);
-	if (!IS_ERR(dentry))
-		error = driverfs_symlink(parent->dentry->d_inode,dentry,target);
-	else
-		error = PTR_ERR(dentry);
-	up(&parent->dentry->d_inode->i_sem);
-	return error;
-}
-
-/**
- * driverfs_remove_file - exported file removal
- * @dir:	directory the file supposedly resides in
- * @name:	name of the file
- *
- * Try and find the file in the dir's list.
- * If it's there, call __remove_file() (above) for the dentry.
- */
-void driverfs_remove_file(struct driver_dir_entry * dir, const char * name)
-{
-	struct dentry * dentry;
-
-	if (!dir->dentry)
-		return;
-
-	down(&dir->dentry->d_inode->i_sem);
-	dentry = get_dentry(dir->dentry,name);
-	if (!IS_ERR(dentry)) {
-		/* make sure dentry is really there */
-		if (dentry->d_inode && 
-		    (dentry->d_parent->d_inode == dir->dentry->d_inode)) {
-			driverfs_unlink(dir->dentry->d_inode,dentry);
-		}
-	}
-	up(&dir->dentry->d_inode->i_sem);
-}
-
-/**
- * driverfs_remove_dir - exportable directory removal
- * @dir:	directory to remove
- *
- * To make sure we don't orphan anyone, first remove
- * all the children in the list, then do clean up the directory.
- */
-void driverfs_remove_dir(struct driver_dir_entry * dir)
-{
-	struct list_head * node, * next;
-	struct dentry * dentry = dir->dentry;
-	struct dentry * parent;
-
-	if (!dentry)
-		goto done;
-
-	parent = dget(dentry->d_parent);
-	down(&parent->d_inode->i_sem);
-	down(&dentry->d_inode->i_sem);
-
-	list_for_each_safe(node,next,&dentry->d_subdirs) {
-		struct dentry * d = list_entry(node,struct dentry,d_child);
-		/* make sure dentry is still there */
-		if (d->d_inode)
-			driverfs_unlink(dentry->d_inode,d);
-	}
-
-	d_invalidate(dentry);
-	if (driverfs_empty(dentry)) {
-		dentry->d_inode->i_nlink -= 2;
-		dentry->d_inode->i_flags |= S_DEAD;
-		parent->d_inode->i_nlink--;
-	}
-	up(&dentry->d_inode->i_sem);
-	dput(dentry);
-
-	up(&parent->d_inode->i_sem);
-	dput(parent);
- done:
-	put_mount();
-}
-
-EXPORT_SYMBOL(driverfs_create_file);
-EXPORT_SYMBOL(driverfs_create_symlink);
-EXPORT_SYMBOL(driverfs_create_dir);
-EXPORT_SYMBOL(driverfs_remove_file);
-EXPORT_SYMBOL(driverfs_remove_dir);
-MODULE_LICENSE("GPL");
diff -Nru a/fs/eventpoll.c b/fs/eventpoll.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/eventpoll.c	Mon Nov  4 14:31:01 2002
@@ -0,0 +1,1293 @@
+/*
+ *  drivers/char/eventpoll.c ( Efficent event polling implementation )
+ *  Copyright (C) 2001,...,2002	 Davide Libenzi
+ *
+ *  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.
+ *
+ *  Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/smp_lock.h>
+#include <linux/string.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <asm/bitops.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/mman.h>
+#include <asm/atomic.h>
+#include <linux/eventpoll.h>
+
+
+
+#define EVENTPOLLFS_MAGIC 0x03111965 /* My birthday should work for this :) */
+
+#define DEBUG_EPOLL 0
+
+#if DEBUG_EPOLL > 0
+#define DPRINTK(x) printk x
+#define DNPRINTK(n, x) do { if ((n) <= DEBUG_EPOLL) printk x; } while (0)
+#else /* #if DEBUG_EPOLL > 0 */
+#define DPRINTK(x) (void) 0
+#define DNPRINTK(n, x) (void) 0
+#endif /* #if DEBUG_EPOLL > 0 */
+
+#define DEBUG_DPI 0
+
+#if DEBUG_DPI != 0
+#define DPI_SLAB_DEBUG (SLAB_DEBUG_FREE | SLAB_RED_ZONE /* | SLAB_POISON */)
+#else /* #if DEBUG_DPI != 0 */
+#define DPI_SLAB_DEBUG 0
+#endif /* #if DEBUG_DPI != 0 */
+
+
+/* Maximum storage for the eventpoll interest set */
+#define EP_MAX_FDS_SIZE (1024 * 128)
+
+/* We don't want the hash to be smaller than this */
+#define EP_MIN_HASH_SIZE 101
+/*
+ * Event buffer dimension used to cache events before sending them in
+ * userspace with a __copy_to_user(). The event buffer is in stack,
+ * so keep this size fairly small.
+ */
+#define EP_EVENT_BUFF_SIZE 32
+
+/* Maximum number of wait queue we can attach to */
+#define EP_MAX_POLL_QUEUE 2
+
+/* Number of hash entries ( "struct list_head" ) inside a page */
+#define EP_HENTRY_X_PAGE (PAGE_SIZE / sizeof(struct list_head))
+
+/* Maximum size of the hash in pages */
+#define EP_MAX_HPAGES (EP_MAX_FDS_SIZE / EP_HENTRY_X_PAGE + 1)
+
+/* Macro to allocate a "struct epitem" from the slab cache */
+#define DPI_MEM_ALLOC()	(struct epitem *) kmem_cache_alloc(dpi_cache, SLAB_KERNEL)
+
+/* Macro to free a "struct epitem" to the slab cache */
+#define DPI_MEM_FREE(p) kmem_cache_free(dpi_cache, p)
+
+/* Fast test to see if the file is an evenpoll file */
+#define IS_FILE_EPOLL(f) ((f)->f_op == &eventpoll_fops)
+
+/*
+ * Remove the item from the list and perform its initialization.
+ * This is usefull for us because we can test if the item is linked
+ * using "EP_IS_LINKED(p)".
+ */
+#define EP_LIST_DEL(p) do { list_del(p); INIT_LIST_HEAD(p); } while (0)
+
+/* Tells us if the item is currently linked */
+#define EP_IS_LINKED(p) (!list_empty(p))
+
+/* Get the "struct epitem" from a wait queue pointer */
+#define EP_ITEM_FROM_WAIT(p) ((struct epitem *) container_of(p, struct eppoll_entry, wait)->base)
+
+
+
+
+
+/*
+ * This structure is stored inside the "private_data" member of the file
+ * structure and rapresent the main data sructure for the eventpoll
+ * interface.
+ */
+struct eventpoll {
+	/* Used to link to the "struct eventpoll" list ( eplist ) */
+	struct list_head llink;
+
+	/* Protect the this structure access */
+	rwlock_t lock;
+
+	/* Wait queue used by sys_epoll_wait() */
+	wait_queue_head_t wq;
+
+	/* Wait queue used by file->poll() */
+	wait_queue_head_t poll_wait;
+
+	/* List of ready file descriptors */
+	struct list_head rdllist;
+
+	/* Size of the hash */
+	int hsize;
+
+	/* Number of pages currently allocated for the hash */
+	int nhpages;
+
+	/* Pages for the "struct epitem" hash */
+	char *hpages[EP_MAX_HPAGES];
+};
+
+/* Wait structure used by the poll hooks */
+struct eppoll_entry {
+	/* The "base" pointer is set to the container "struct epitem" */
+	void *base;
+
+	/*
+	 * Wait queue item that will be linked to the target file wait
+	 * queue head.
+	 */
+	wait_queue_t wait;
+
+	/* The wait queue head that linked the "wait" wait queue item */
+	wait_queue_head_t *whead;
+};
+
+/*
+ * Each file descriptor added to the eventpoll interface will
+ * have an entry of this type linked to the hash.
+ */
+struct epitem {
+	/* List header used to link this structure to the eventpoll hash */
+	struct list_head llink;
+
+	/* List header used to link this structure to the eventpoll ready list */
+	struct list_head rdllink;
+
+	/* Number of active wait queue attached to poll operations */
+	int nwait;
+
+	/* Wait queue used to attach poll operations */
+	struct eppoll_entry wait[EP_MAX_POLL_QUEUE];
+
+	/* The "container" of this item */
+	struct eventpoll *ep;
+
+	/* The file this item refers to */
+	struct file *file;
+
+	/* The structure that describe the interested events and the source fd */
+	struct pollfd pfd;
+
+	/*
+	 * Used to keep track of the usage count of the structure. This avoids
+	 * that the structure will desappear from underneath our processing.
+	 */
+	atomic_t usecnt;
+};
+
+
+
+
+static int ep_is_prime(int n);
+static int ep_getfd(int *efd, struct inode **einode, struct file **efile);
+static int ep_alloc_pages(char **pages, int numpages);
+static int ep_free_pages(char **pages, int numpages);
+static int ep_file_init(struct file *file, int hsize);
+static int ep_hash_index(struct eventpoll *ep, struct file *file);
+static struct list_head *ep_hash_entry(struct eventpoll *ep, int index);
+static int ep_init(struct eventpoll *ep, int hsize);
+static void ep_free(struct eventpoll *ep);
+static struct epitem *ep_find(struct eventpoll *ep, struct file *file);
+static void ep_use_epitem(struct epitem *dpi);
+static void ep_release_epitem(struct epitem *dpi);
+static void ep_ptable_queue_proc(void *priv, wait_queue_head_t *whead);
+static int ep_insert(struct eventpoll *ep, struct pollfd *pfd, struct file *tfile);
+static unsigned int ep_get_file_events(struct file *file);
+static int ep_modify(struct eventpoll *ep, struct epitem *dpi, unsigned int events);
+static int ep_unlink(struct eventpoll *ep, struct epitem *dpi);
+static int ep_remove(struct eventpoll *ep, struct epitem *dpi);
+static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync);
+static int ep_eventpoll_close(struct inode *inode, struct file *file);
+static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait);
+static int ep_events_transfer(struct eventpoll *ep, struct pollfd *events, int maxevents);
+static int ep_poll(struct eventpoll *ep, struct pollfd *events, int maxevents,
+		   int timeout);
+static int eventpollfs_delete_dentry(struct dentry *dentry);
+static struct inode *ep_eventpoll_inode(void);
+static struct super_block *eventpollfs_get_sb(struct file_system_type *fs_type,
+					      int flags, char *dev_name, void *data);
+
+
+/* Use to link togheter all the "struct eventpoll" */
+static struct list_head eplist;
+
+/* Serialize the access to "eplist" */
+static rwlock_t eplock;
+
+/* Slab cache used to allocate "struct epitem" */
+static kmem_cache_t *dpi_cache;
+
+/* Virtual fs used to allocate inodes for eventpoll files */
+static struct vfsmount *eventpoll_mnt;
+
+/* File callbacks that implement the eventpoll file behaviour */
+static struct file_operations eventpoll_fops = {
+	.release	= ep_eventpoll_close,
+	.poll		= ep_eventpoll_poll
+};
+
+/*
+ * This is used to register the virtual file system from where
+ * eventpoll inodes are allocated.
+ */
+static struct file_system_type eventpoll_fs_type = {
+	.name		= "eventpollfs",
+	.get_sb		= eventpollfs_get_sb,
+	.kill_sb	= kill_anon_super,
+};
+
+/* Very basic directory entry operations for the eventpoll virtual file system */
+static struct dentry_operations eventpollfs_dentry_operations = {
+	.d_delete	= eventpollfs_delete_dentry,
+};
+
+
+
+/* Report if the number is prime. Needed to correctly size the hash  */
+static int ep_is_prime(int n)
+{
+
+	if (n > 3) {
+		if (n & 1) {
+			int i, hn = n / 2;
+
+			for (i = 3; i < hn; i += 2)
+				if (!(n % i))
+					return 0;
+		} else
+			return 0;
+	}
+	return 1;
+}
+
+
+/*
+ * This is called from inside fs/file_table.c:__fput() to unlink files
+ * from the eventpoll interface. We need to have this facility to cleanup
+ * correctly files that are closed without being removed from the eventpoll
+ * interface.
+ */
+void ep_notify_file_close(struct file *file)
+{
+	unsigned long flags;
+	struct list_head *lnk;
+	struct eventpoll *ep;
+	struct epitem *dpi;
+
+	read_lock_irqsave(&eplock, flags);
+	list_for_each(lnk, &eplist) {
+		ep = list_entry(lnk, struct eventpoll, llink);
+
+		while ((dpi = ep_find(ep, file))) {
+			ep_remove(ep, dpi);
+			ep_release_epitem(dpi);
+		}
+	}
+	read_unlock_irqrestore(&eplock, flags);
+}
+
+
+/*
+ * It opens an eventpoll file descriptor by suggesting a storage of "size"
+ * file descriptors. It is the kernel part of the userspace epoll_create(2).
+ */
+asmlinkage int sys_epoll_create(int size)
+{
+	int error, fd;
+	struct inode *inode;
+	struct file *file;
+
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d)\n",
+		     current, size));
+
+	/* Search the nearest prime number higher than "size" */
+	for (; !ep_is_prime(size); size++);
+	if (size < EP_MIN_HASH_SIZE)
+		size = EP_MIN_HASH_SIZE;
+
+	/*
+	 * Creates all the items needed to setup an eventpoll file. That is,
+	 * a file structure, and inode and a free file descriptor.
+	 */
+	error = ep_getfd(&fd, &inode, &file);
+	if (error)
+		goto eexit_1;
+
+	/* Setup the file internal data structure ( "struct eventpoll" ) */
+	error = ep_file_init(file, size);
+	if (error)
+		goto eexit_2;
+
+
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n",
+		     current, size, fd));
+
+	return fd;
+
+eexit_2:
+	sys_close(fd);
+eexit_1:
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n",
+		     current, size, error));
+	return error;
+}
+
+
+/*
+ * The following function implement the controller interface for the eventpoll
+ * file that enable the insertion/removal/change of file descriptors inside
+ * the interest set. It rapresents the kernel part of the user spcae epoll_ctl(2).
+ */
+asmlinkage int sys_epoll_ctl(int epfd, int op, int fd, unsigned int events)
+{
+	int error;
+	struct file *file, *tfile;
+	struct eventpoll *ep;
+	struct epitem *dpi;
+	struct pollfd pfd;
+
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %u)\n",
+		     current, epfd, op, fd, events));
+
+	/* Get the "struct file *" for the eventpoll file */
+	error = -EBADF;
+	file = fget(epfd);
+	if (!file)
+		goto eexit_1;
+
+	/* Get the "struct file *" for the target file */
+	tfile = fget(fd);
+	if (!tfile)
+		goto eexit_2;
+
+	/* The target file descriptor must support poll */
+	error = -EPERM;
+	if (!tfile->f_op || !tfile->f_op->poll)
+		goto eexit_3;
+
+	/*
+	 * We have to check that the file structure underneath the file descriptor
+	 * the user passed to us _is_ an eventpoll file.
+	 */
+	error = -EINVAL;
+	if (!IS_FILE_EPOLL(file))
+		goto eexit_3;
+
+	/*
+	 * At this point it is safe to assume that the "private_data" contains
+	 * our own data structure.
+	 */
+	ep = file->private_data;
+
+	/*
+	 * Try to lookup the file inside our hash table. When an item is found
+	 * ep_find() increases the usage count of the item so that it won't
+	 * desappear underneath us. The only thing that might happen, if someone
+	 * tries very hard, is a double insertion of the same file descriptor.
+	 * This does not rapresent a problem though and we don't really want
+	 * to put an extra syncronization object to deal with this harmless condition.
+	 */
+	dpi = ep_find(ep, tfile);
+
+	error = -EINVAL;
+	switch (op) {
+	case EP_CTL_ADD:
+		if (!dpi) {
+			pfd.fd = fd;
+			pfd.events = events | POLLERR | POLLHUP;
+			pfd.revents = 0;
+
+			error = ep_insert(ep, &pfd, tfile);
+		} else
+			error = -EEXIST;
+		break;
+	case EP_CTL_DEL:
+		if (dpi)
+			error = ep_remove(ep, dpi);
+		else
+			error = -ENOENT;
+		break;
+	case EP_CTL_MOD:
+		if (dpi)
+			error = ep_modify(ep, dpi, events | POLLERR | POLLHUP);
+		else
+			error = -ENOENT;
+		break;
+	}
+
+	/*
+	 * The function ep_find() increments the usage count of the structure
+	 * so, if this is not NULL, we need to release it.
+	 */
+	if (dpi)
+		ep_release_epitem(dpi);
+
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %u) = %d\n",
+		     current, epfd, op, fd, events, error));
+
+eexit_3:
+	fput(tfile);
+eexit_2:
+	fput(file);
+eexit_1:
+	return error;
+}
+
+
+/*
+ * Implement the event wait interface for the eventpoll file. It is the kernel
+ * part of the user space epoll_wait(2).
+ */
+asmlinkage int sys_epoll_wait(int epfd, struct pollfd *events, int maxevents,
+			      int timeout)
+{
+	int error;
+	struct file *file;
+	struct eventpoll *ep;
+
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_wait(%d, %p, %d, %d)\n",
+		     current, epfd, events, maxevents, timeout));
+
+	/* Verify that the area passed by the user is writeable */
+	if ((error = verify_area(VERIFY_WRITE, events, maxevents * sizeof(struct pollfd))))
+		goto eexit_1;
+
+	/* Get the "struct file *" for the eventpoll file */
+	error = -EBADF;
+	file = fget(epfd);
+	if (!file)
+		goto eexit_1;
+
+	/*
+	 * We have to check that the file structure underneath the file descriptor
+	 * the user passed to us _is_ an eventpoll file.
+	 */
+	error = -EINVAL;
+	if (!IS_FILE_EPOLL(file))
+		goto eexit_2;
+
+	/*
+	 * At this point it is safe to assume that the "private_data" contains
+	 * our own data structure.
+	 */
+	ep = file->private_data;
+
+	/* Time to fish for events ... */
+	error = ep_poll(ep, events, maxevents, timeout);
+
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_wait(%d, %p, %d, %d) = %d\n",
+		     current, epfd, events, maxevents, timeout, error));
+
+eexit_2:
+	fput(file);
+eexit_1:
+	return error;
+}
+
+
+/*
+ * Creates the file descriptor to be used by the epoll interface.
+ */
+static int ep_getfd(int *efd, struct inode **einode, struct file **efile)
+{
+	struct qstr this;
+	char name[32];
+	struct dentry *dentry;
+	struct inode *inode;
+	struct file *file;
+	int error, fd;
+
+	/* Get an ready to use file */
+	error = -ENFILE;
+	file = get_empty_filp();
+	if (!file)
+		goto eexit_1;
+
+	/* Allocates an inode from the eventpoll file system */
+	inode = ep_eventpoll_inode();
+	error = PTR_ERR(inode);
+	if (IS_ERR(inode))
+		goto eexit_2;
+
+	/* Allocates a free descriptor to plug the file onto */
+	error = get_unused_fd();
+	if (error < 0)
+		goto eexit_3;
+	fd = error;
+
+	/*
+	 * Link the inode to a directory entry by creating a unique name
+	 * using the inode number.
+	 */
+	error = -ENOMEM;
+	sprintf(name, "[%lu]", inode->i_ino);
+	this.name = name;
+	this.len = strlen(name);
+	this.hash = inode->i_ino;
+	dentry = d_alloc(eventpoll_mnt->mnt_sb->s_root, &this);
+	if (!dentry)
+		goto eexit_4;
+	dentry->d_op = &eventpollfs_dentry_operations;
+	d_add(dentry, inode);
+	file->f_vfsmnt = mntget(eventpoll_mnt);
+	file->f_dentry = dget(dentry);
+
+	/*
+	 * Initialize the file as read/write because it could be used
+	 * with write() to add/remove/change interest sets.
+	 */
+	file->f_pos = 0;
+	file->f_flags = O_RDONLY;
+	file->f_op = &eventpoll_fops;
+	file->f_mode = FMODE_READ;
+	file->f_version = 0;
+	file->private_data = NULL;
+
+	/* Install the new setup file into the allocated fd. */
+	fd_install(fd, file);
+
+	*efd = fd;
+	*einode = inode;
+	*efile = file;
+	return 0;
+
+eexit_4:
+	put_unused_fd(fd);
+eexit_3:
+	iput(inode);
+eexit_2:
+	put_filp(file);
+eexit_1:
+	return error;
+}
+
+
+static int ep_alloc_pages(char **pages, int numpages)
+{
+	int i;
+
+	for (i = 0; i < numpages; i++) {
+		pages[i] = (char *) __get_free_pages(GFP_KERNEL, 0);
+		if (!pages[i]) {
+			for (--i; i >= 0; i--) {
+				ClearPageReserved(virt_to_page(pages[i]));
+				free_pages((unsigned long) pages[i], 0);
+			}
+			return -ENOMEM;
+		}
+		SetPageReserved(virt_to_page(pages[i]));
+	}
+	return 0;
+}
+
+
+static int ep_free_pages(char **pages, int numpages)
+{
+	int i;
+
+	for (i = 0; i < numpages; i++) {
+		ClearPageReserved(virt_to_page(pages[i]));
+		free_pages((unsigned long) pages[i], 0);
+	}
+	return 0;
+}
+
+
+static int ep_file_init(struct file *file, int hsize)
+{
+	int error;
+	unsigned long flags;
+	struct eventpoll *ep;
+
+	if (!(ep = kmalloc(sizeof(struct eventpoll), GFP_KERNEL)))
+		return -ENOMEM;
+
+	memset(ep, 0, sizeof(*ep));
+
+	error = ep_init(ep, hsize);
+	if (error) {
+		kfree(ep);
+		return error;
+	}
+
+	file->private_data = ep;
+
+	/* Add the structure to the linked list that links "struct eventpoll" */
+	write_lock_irqsave(&eplock, flags);
+	list_add(&ep->llink, &eplist);
+	write_unlock_irqrestore(&eplock, flags);
+
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_file_init() ep=%p\n",
+		     current, ep));
+	return 0;
+}
+
+
+/*
+ * Calculate the index of the hash relative to "file".
+ */
+static int ep_hash_index(struct eventpoll *ep, struct file *file)
+{
+
+	return (int) ((((unsigned long) file) / sizeof(struct file)) % ep->hsize);
+}
+
+
+/*
+ * Returns the hash entry ( struct list_head * ) of the passed index.
+ */
+static struct list_head *ep_hash_entry(struct eventpoll *ep, int index)
+{
+
+	return (struct list_head *) (ep->hpages[index / EP_HENTRY_X_PAGE] +
+				     (index % EP_HENTRY_X_PAGE) * sizeof(struct list_head));
+}
+
+
+static int ep_init(struct eventpoll *ep, int hsize)
+{
+	int error, i;
+
+	INIT_LIST_HEAD(&ep->llink);
+	rwlock_init(&ep->lock);
+	init_waitqueue_head(&ep->wq);
+	init_waitqueue_head(&ep->poll_wait);
+	INIT_LIST_HEAD(&ep->rdllist);
+
+	/* Hash allocation and setup */
+	ep->hsize = hsize;
+	ep->nhpages = hsize / EP_HENTRY_X_PAGE + (hsize % EP_HENTRY_X_PAGE ? 1: 0);
+	error = ep_alloc_pages(ep->hpages, ep->nhpages);
+	if (error)
+		goto eexit_1;
+
+	/* Initialize hash buckets */
+	for (i = 0; i < ep->hsize; i++)
+		INIT_LIST_HEAD(ep_hash_entry(ep, i));
+
+	return 0;
+eexit_1:
+	return error;
+}
+
+
+static void ep_free(struct eventpoll *ep)
+{
+	int i;
+	unsigned long flags;
+	struct list_head *lsthead;
+
+	/*
+	 * Walks through the whole hash by unregistering file callbacks and
+	 * freeing each "struct epitem".
+	 */
+	for (i = 0; i < ep->hsize; i++) {
+		lsthead = ep_hash_entry(ep, i);
+
+		/*
+		 * We need to lock this because we could be hit by
+		 * ep_notify_file_close() while we're freeing this.
+		 */
+		write_lock_irqsave(&ep->lock, flags);
+
+		while (!list_empty(lsthead)) {
+			struct epitem *dpi = list_entry(lsthead->next, struct epitem, llink);
+
+			/* The function ep_unlink() must be called with held lock */
+			ep_unlink(ep, dpi);
+
+			/* We release the lock before releasing the "struct epitem" */
+			write_unlock_irqrestore(&ep->lock, flags);
+
+			ep_release_epitem(dpi);
+
+			/* And then we reaquire the lock ... */
+			write_lock_irqsave(&ep->lock, flags);
+		}
+
+		write_unlock_irqrestore(&ep->lock, flags);
+	}
+
+	/* Remove the structure to the linked list that links "struct eventpoll" */
+	write_lock_irqsave(&eplock, flags);
+	EP_LIST_DEL(&ep->llink);
+	write_unlock_irqrestore(&eplock, flags);
+
+	/* Free hash pages */
+	if (ep->nhpages > 0)
+		ep_free_pages(ep->hpages, ep->nhpages);
+}
+
+
+/*
+ * Search the file inside the eventpoll hash. It add usage count to
+ * the returned item, so the caller must call ep_release_epitem()
+ * after finished using the "struct epitem".
+ */
+static struct epitem *ep_find(struct eventpoll *ep, struct file *file)
+{
+	unsigned long flags;
+	struct list_head *lsthead, *lnk;
+	struct epitem *dpi = NULL;
+
+	read_lock_irqsave(&ep->lock, flags);
+
+	lsthead = ep_hash_entry(ep, ep_hash_index(ep, file));
+	list_for_each(lnk, lsthead) {
+		dpi = list_entry(lnk, struct epitem, llink);
+
+		if (dpi->file == file) {
+			ep_use_epitem(dpi);
+			break;
+		}
+		dpi = NULL;
+	}
+
+	read_unlock_irqrestore(&ep->lock, flags);
+
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_find(%p) -> %p\n",
+		     current, file, dpi));
+
+	return dpi;
+}
+
+
+/*
+ * Increment the usage count of the "struct epitem" making it sure
+ * that the user will have a valid pointer to reference.
+ */
+static void ep_use_epitem(struct epitem *dpi)
+{
+
+	atomic_inc(&dpi->usecnt);
+}
+
+
+/*
+ * Decrement ( release ) the usage count by signaling that the user
+ * has finished using the structure. It might lead to freeing the
+ * structure itself if the count goes to zero.
+ */
+static void ep_release_epitem(struct epitem *dpi)
+{
+
+	if (atomic_dec_and_test(&dpi->usecnt))
+		DPI_MEM_FREE(dpi);
+}
+
+
+/*
+ * This is the callback that is used to add our wait queue to the
+ * target file wakeup lists.
+ */
+static void ep_ptable_queue_proc(void *priv, wait_queue_head_t *whead)
+{
+	struct epitem *dpi = priv;
+
+	/* No more than EP_MAX_POLL_QUEUE wait queue are supported */
+	if (dpi->nwait < EP_MAX_POLL_QUEUE) {
+		add_wait_queue(whead, &dpi->wait[dpi->nwait].wait);
+		dpi->wait[dpi->nwait].whead = whead;
+		dpi->nwait++;
+	}
+}
+
+
+static int ep_insert(struct eventpoll *ep, struct pollfd *pfd, struct file *tfile)
+{
+	int error, i, revents;
+	unsigned long flags;
+	struct epitem *dpi;
+	poll_table pt;
+
+	error = -ENOMEM;
+	if (!(dpi = DPI_MEM_ALLOC()))
+		goto eexit_1;
+
+	/* Item initialization follow here ... */
+	INIT_LIST_HEAD(&dpi->llink);
+	INIT_LIST_HEAD(&dpi->rdllink);
+	dpi->ep = ep;
+	dpi->file = tfile;
+	dpi->pfd = *pfd;
+	atomic_set(&dpi->usecnt, 1);
+	dpi->nwait = 0;
+	for (i = 0; i < EP_MAX_POLL_QUEUE; i++) {
+		init_waitqueue_func_entry(&dpi->wait[i].wait, ep_poll_callback);
+		dpi->wait[i].whead = NULL;
+		dpi->wait[i].base = dpi;
+	}
+
+	/* Attach the item to the poll hooks */
+	poll_initwait_ex(&pt, 1, ep_ptable_queue_proc, dpi);
+	revents = tfile->f_op->poll(tfile, &pt);
+	poll_freewait(&pt);
+
+	/* We have to drop the new item inside our item list to keep track of it */
+	write_lock_irqsave(&ep->lock, flags);
+
+	list_add(&dpi->llink, ep_hash_entry(ep, ep_hash_index(ep, tfile)));
+
+	/* If the file is already "ready" we drop it inside the ready list */
+	if ((revents & pfd->events) && !EP_IS_LINKED(&dpi->rdllink))
+		list_add(&dpi->rdllink, &ep->rdllist);
+
+	write_unlock_irqrestore(&ep->lock, flags);
+
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_insert(%p, %d)\n",
+		     current, ep, pfd->fd));
+
+	return 0;
+
+eexit_1:
+	return error;
+}
+
+
+/*
+ * Returns the current events of the given file. It uses the special
+ * poll table initialization to avoid any poll queue insertion.
+ */
+static unsigned int ep_get_file_events(struct file *file)
+{
+	unsigned int revents;
+	poll_table pt;
+
+	/*
+	 * This is a special poll table initialization that will
+	 * make poll_wait() to not perform any wait queue insertion when
+	 * called by file->f_op->poll(). This is a fast way to retrieve
+	 * file events with perform any queue insertion, hence saving CPU cycles.
+	 */
+	poll_initwait_ex(&pt, 0, NULL, NULL);
+
+	revents = file->f_op->poll(file, &pt);
+
+	poll_freewait(&pt);
+	return revents;
+}
+
+
+/*
+ * Modify the interest event mask by dropping an event if the new mask
+ * has a match in the current file status.
+ */
+static int ep_modify(struct eventpoll *ep, struct epitem *dpi, unsigned int events)
+{
+	unsigned int revents;
+	unsigned long flags;
+
+	revents = ep_get_file_events(dpi->file);
+
+	write_lock_irqsave(&ep->lock, flags);
+
+	dpi->pfd.events = events;
+
+	/* If the file is already "ready" we drop it inside the ready list */
+	if ((revents & events) && EP_IS_LINKED(&dpi->llink) && !EP_IS_LINKED(&dpi->rdllink))
+		list_add(&dpi->rdllink, &ep->rdllist);
+
+	write_unlock_irqrestore(&ep->lock, flags);
+
+	return 0;
+}
+
+
+/*
+ * Unlink the "struct epitem" from all places it might have been hooked up.
+ * This function must be called with write IRQ lock on "ep->lock".
+ */
+static int ep_unlink(struct eventpoll *ep, struct epitem *dpi)
+{
+	int i;
+
+	/*
+	 * It can happen that this one is called for an item already unlinked.
+	 * The check protect us from doing a double unlink ( crash ).
+	 */
+	if (!EP_IS_LINKED(&dpi->llink))
+		goto not_linked;
+
+	/*
+	 * At this point is safe to do the job, unlink the item from our list.
+	 * This operation togheter with the above check closes the door to
+	 * double unlinks.
+	 */
+	EP_LIST_DEL(&dpi->llink);
+
+	/* Removes poll wait queue hooks */
+	for (i = 0; i < dpi->nwait; i++)
+		remove_wait_queue(dpi->wait[i].whead, &dpi->wait[i].wait);
+
+	/*
+	 * If the item we are going to remove is inside the ready file descriptors
+	 * we want to remove it from this list to avoid stale events.
+	 */
+	if (EP_IS_LINKED(&dpi->rdllink))
+		EP_LIST_DEL(&dpi->rdllink);
+
+not_linked:
+
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_unlink(%p, %d)\n",
+		     current, ep, dpi->pfd.fd));
+
+	return 0;
+}
+
+
+/*
+ * Removes a "struct epitem" from the eventpoll hash and deallocates
+ * all the associated resources.
+ */
+static int ep_remove(struct eventpoll *ep, struct epitem *dpi)
+{
+	int error;
+	unsigned long flags;
+
+	/* We need to acquire the write IRQ lock before calling ep_unlink() */
+	write_lock_irqsave(&ep->lock, flags);
+
+	/* Really unlink the item from the hash */
+	error = ep_unlink(ep, dpi);
+
+	write_unlock_irqrestore(&ep->lock, flags);
+
+	if (error)
+		goto eexit_1;
+
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_remove(%p, %d)\n",
+		     current, ep, dpi->pfd.fd));
+
+	/* At this point it is safe to free the eventpoll item */
+	ep_release_epitem(dpi);
+
+	error = 0;
+eexit_1:
+	return error;
+}
+
+
+/*
+ * This is the callback that is passed to the wait queue wakeup
+ * machanism. It is called by the stored file descriptors when they
+ * have events to report.
+ */
+static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync)
+{
+	unsigned long flags;
+	struct epitem *dpi = EP_ITEM_FROM_WAIT(wait);
+	struct eventpoll *ep = dpi->ep;
+
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: poll_callback(%p) dpi=%p ep=%p\n",
+		     current, dpi->file, dpi, ep));
+
+	write_lock_irqsave(&ep->lock, flags);
+
+	/* If this file is already in the ready list we exit soon */
+	if (EP_IS_LINKED(&dpi->rdllink))
+		goto is_linked;
+
+	list_add(&dpi->rdllink, &ep->rdllist);
+
+is_linked:
+	/*
+	 * Wake up ( if active ) both the eventpoll wait list and the ->poll()
+	 * wait list.
+	 */
+	if (waitqueue_active(&ep->wq))
+		wake_up(&ep->wq);
+	if (waitqueue_active(&ep->poll_wait))
+		wake_up(&ep->poll_wait);
+
+	write_unlock_irqrestore(&ep->lock, flags);
+	return 1;
+}
+
+
+static int ep_eventpoll_close(struct inode *inode, struct file *file)
+{
+	struct eventpoll *ep = file->private_data;
+
+	if (ep) {
+		ep_free(ep);
+		kfree(ep);
+	}
+
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: close() ep=%p\n", current, ep));
+	return 0;
+}
+
+
+static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait)
+{
+	unsigned int pollflags = 0;
+	unsigned long flags;
+	struct eventpoll *ep = file->private_data;
+
+	/* Insert inside our poll wait queue */
+	poll_wait(file, &ep->poll_wait, wait);
+
+	/* Check our condition */
+	read_lock_irqsave(&ep->lock, flags);
+	if (!list_empty(&ep->rdllist))
+		pollflags = POLLIN | POLLRDNORM;
+	read_unlock_irqrestore(&ep->lock, flags);
+
+	return pollflags;
+}
+
+
+/*
+ * Perform the transfer of events to user space. Optimize the copy by
+ * caching EP_EVENT_BUFF_SIZE events at a time and then copying it to user space.
+ */
+static int ep_events_transfer(struct eventpoll *ep, struct pollfd *events, int maxevents)
+{
+	int eventcnt, ebufcnt, revents;
+	unsigned long flags;
+	struct list_head *lsthead = &ep->rdllist;
+	struct pollfd eventbuf[EP_EVENT_BUFF_SIZE];
+	poll_table pt;
+
+	/*
+	 * This is a special poll table initialization that will
+	 * make poll_wait() to not perform any wait queue insertion when
+	 * called by file->f_op->poll(). This is a fast way to retrieve
+	 * file events with perform any queue insertion, hence saving CPU cycles.
+	 */
+	poll_initwait_ex(&pt, 0, NULL, NULL);
+
+	write_lock_irqsave(&ep->lock, flags);
+
+	for (eventcnt = 0, ebufcnt = 0; eventcnt < maxevents && !list_empty(lsthead);) {
+		struct epitem *dpi = list_entry(lsthead->next, struct epitem, rdllink);
+
+		/* Remove the item from the ready list */
+		EP_LIST_DEL(&dpi->rdllink);
+
+		/* Fetch event bits from the signaled file */
+		revents = dpi->file->f_op->poll(dpi->file, &pt);
+
+		if (revents & dpi->pfd.events) {
+			eventbuf[ebufcnt] = dpi->pfd;
+			eventbuf[ebufcnt].revents = revents & eventbuf[ebufcnt].events;
+			ebufcnt++;
+
+			/* If our buffer page is full we need to flush it to user space */
+			if (ebufcnt == EP_EVENT_BUFF_SIZE) {
+				/*
+				 * We need to drop the irqlock before using the function
+				 * __copy_to_user() because it might fault.
+				 */
+				write_unlock_irqrestore(&ep->lock, flags);
+				if (__copy_to_user(&events[eventcnt], eventbuf,
+						   ebufcnt * sizeof(struct pollfd))) {
+					poll_freewait(&pt);
+					return -EFAULT;
+				}
+				eventcnt += ebufcnt;
+				ebufcnt = 0;
+				write_lock_irqsave(&ep->lock, flags);
+			}
+		}
+	}
+	write_unlock_irqrestore(&ep->lock, flags);
+
+	/* There might be still something inside our event buffer */
+	if (ebufcnt) {
+		if (__copy_to_user(&events[eventcnt], eventbuf,
+				   ebufcnt * sizeof(struct pollfd)))
+			eventcnt = -EFAULT;
+		else
+			eventcnt += ebufcnt;
+	}
+
+	poll_freewait(&pt);
+
+	return eventcnt;
+}
+
+
+static int ep_poll(struct eventpoll *ep, struct pollfd *events, int maxevents,
+		   int timeout)
+{
+	int res = 0, eavail;
+	unsigned long flags;
+	long jtimeout;
+	wait_queue_t wait;
+
+	/*
+	 * Calculate the timeout by checking for the "infinite" value ( -1 )
+	 * and the overflow condition ( > MAX_SCHEDULE_TIMEOUT / HZ ). The
+	 * passed timeout is in milliseconds, that why (t * HZ) / 1000.
+	 */
+	jtimeout = timeout == -1 || timeout > MAX_SCHEDULE_TIMEOUT / HZ ?
+		MAX_SCHEDULE_TIMEOUT: (timeout * HZ) / 1000;
+
+retry:
+	write_lock_irqsave(&ep->lock, flags);
+
+	res = 0;
+	if (list_empty(&ep->rdllist)) {
+		/*
+		 * We don't have any available event to return to the caller.
+		 * We need to sleep here, and we will be wake up by
+		 * ep_poll_callback() when events will become available.
+		 */
+		init_waitqueue_entry(&wait, current);
+		add_wait_queue(&ep->wq, &wait);
+
+		for (;;) {
+			/*
+			 * We don't want to sleep if the ep_poll_callback() sends us
+			 * a wakeup in between. That's why we set the task state
+			 * to TASK_INTERRUPTIBLE before doing the checks.
+			 */
+			set_current_state(TASK_INTERRUPTIBLE);
+			if (!list_empty(&ep->rdllist) || !jtimeout)
+				break;
+			if (signal_pending(current)) {
+				res = -EINTR;
+				break;
+			}
+
+			write_unlock_irqrestore(&ep->lock, flags);
+			jtimeout = schedule_timeout(jtimeout);
+			write_lock_irqsave(&ep->lock, flags);
+		}
+		remove_wait_queue(&ep->wq, &wait);
+
+		set_current_state(TASK_RUNNING);
+	}
+
+	/* Is it worth to try to dig for events ? */
+	eavail = !list_empty(&ep->rdllist);
+
+	write_unlock_irqrestore(&ep->lock, flags);
+
+	/*
+	 * Try to transfer events to user space. In case we get 0 events and
+	 * there's still timeout left over, we go trying again in search of
+	 * more luck.
+	 */
+	if (!res && eavail &&
+	    !(res = ep_events_transfer(ep, events, maxevents)) && jtimeout)
+		goto retry;
+
+	return res;
+}
+
+
+static int eventpollfs_delete_dentry(struct dentry *dentry)
+{
+
+	return 1;
+}
+
+
+static struct inode *ep_eventpoll_inode(void)
+{
+	int error = -ENOMEM;
+	struct inode *inode = new_inode(eventpoll_mnt->mnt_sb);
+
+	if (!inode)
+		goto eexit_1;
+
+	inode->i_fop = &eventpoll_fops;
+
+	/*
+	 * Mark the inode dirty from the very beginning,
+	 * that way it will never be moved to the dirty
+	 * list because mark_inode_dirty() will think
+	 * that it already _is_ on the dirty list.
+	 */
+	inode->i_state = I_DIRTY;
+	inode->i_mode = S_IRUSR | S_IWUSR;
+	inode->i_uid = current->fsuid;
+	inode->i_gid = current->fsgid;
+	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	inode->i_blksize = PAGE_SIZE;
+	return inode;
+
+eexit_1:
+	return ERR_PTR(error);
+}
+
+
+static struct super_block *eventpollfs_get_sb(struct file_system_type *fs_type,
+					      int flags, char *dev_name, void *data)
+{
+
+	return get_sb_pseudo(fs_type, "eventpoll:", NULL, EVENTPOLLFS_MAGIC);
+}
+
+
+static int __init eventpoll_init(void)
+{
+	int error;
+
+	/* Initialize the list that will link "struct eventpoll" */
+	INIT_LIST_HEAD(&eplist);
+
+	/* Initialize the rwlock used to access "eplist" */
+	rwlock_init(&eplock);
+
+	/* Allocates slab cache used to allocate "struct epitem" items */
+	error = -ENOMEM;
+	dpi_cache = kmem_cache_create("eventpoll",
+				      sizeof(struct epitem),
+				      0,
+				      DPI_SLAB_DEBUG, NULL, NULL);
+	if (!dpi_cache)
+		goto eexit_1;
+
+	/*
+	 * Register the virtual file system that will be the source of inodes
+	 * for the eventpoll files
+	 */
+	error = register_filesystem(&eventpoll_fs_type);
+	if (error)
+		goto eexit_2;
+
+	/* Mount the above commented virtual file system */
+	eventpoll_mnt = kern_mount(&eventpoll_fs_type);
+	error = PTR_ERR(eventpoll_mnt);
+	if (IS_ERR(eventpoll_mnt))
+		goto eexit_3;
+
+	printk(KERN_INFO "[%p] eventpoll: driver installed.\n", current);
+
+	return 0;
+
+eexit_3:
+	unregister_filesystem(&eventpoll_fs_type);
+eexit_2:
+	kmem_cache_destroy(dpi_cache);
+eexit_1:
+
+	return error;
+}
+
+
+static void __exit eventpoll_exit(void)
+{
+	/* Undo all operations done inside eventpoll_init() */
+	unregister_filesystem(&eventpoll_fs_type);
+	mntput(eventpoll_mnt);
+	kmem_cache_destroy(dpi_cache);
+}
+
+module_init(eventpoll_init);
+module_exit(eventpoll_exit);
+
+MODULE_LICENSE("GPL");
+
diff -Nru a/fs/exec.c b/fs/exec.c
--- a/fs/exec.c	Mon Nov  4 14:31:01 2002
+++ b/fs/exec.c	Mon Nov  4 14:31:01 2002
@@ -306,7 +306,7 @@
 		pte_unmap(pte);
 		goto out;
 	}
-	lru_cache_add(page);
+	lru_cache_add_active(page);
 	flush_dcache_page(page);
 	flush_page_to_ram(page);
 	set_pte(pte, pte_mkdirty(pte_mkwrite(mk_pte(page, PAGE_COPY))));
diff -Nru a/fs/ext2/Makefile b/fs/ext2/Makefile
--- a/fs/ext2/Makefile	Mon Nov  4 14:31:02 2002
+++ b/fs/ext2/Makefile	Mon Nov  4 14:31:02 2002
@@ -7,4 +7,14 @@
 ext2-objs := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
 	     ioctl.o namei.o super.o symlink.o
 
+export-objs += xattr.o
+
+ifeq ($(CONFIG_EXT2_FS_XATTR),y)
+ext2-objs += xattr.o xattr_user.o
+endif
+
+ifeq ($(CONFIG_EXT2_FS_POSIX_ACL),y)
+ext2-objs += acl.o
+endif
+
 include $(TOPDIR)/Rules.make
diff -Nru a/fs/ext2/acl.c b/fs/ext2/acl.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/ext2/acl.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,573 @@
+/*
+ * linux/fs/ext2/acl.c
+ *
+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include "ext2.h"
+#include "xattr.h"
+#include "acl.h"
+
+/*
+ * Convert from filesystem to in-memory representation.
+ */
+static struct posix_acl *
+ext2_acl_from_disk(const void *value, size_t size)
+{
+	const char *end = (char *)value + size;
+	int n, count;
+	struct posix_acl *acl;
+
+	if (!value)
+		return NULL;
+	if (size < sizeof(ext2_acl_header))
+		 return ERR_PTR(-EINVAL);
+	if (((ext2_acl_header *)value)->a_version !=
+	    cpu_to_le32(EXT2_ACL_VERSION))
+		return ERR_PTR(-EINVAL);
+	value = (char *)value + sizeof(ext2_acl_header);
+	count = ext2_acl_count(size);
+	if (count < 0)
+		return ERR_PTR(-EINVAL);
+	if (count == 0)
+		return NULL;
+	acl = posix_acl_alloc(count, GFP_KERNEL);
+	if (!acl)
+		return ERR_PTR(-ENOMEM);
+	for (n=0; n < count; n++) {
+		ext2_acl_entry *entry =
+			(ext2_acl_entry *)value;
+		if ((char *)value + sizeof(ext2_acl_entry_short) > end)
+			goto fail;
+		acl->a_entries[n].e_tag  = le16_to_cpu(entry->e_tag);
+		acl->a_entries[n].e_perm = le16_to_cpu(entry->e_perm);
+		switch(acl->a_entries[n].e_tag) {
+			case ACL_USER_OBJ:
+			case ACL_GROUP_OBJ:
+			case ACL_MASK:
+			case ACL_OTHER:
+				value = (char *)value +
+					sizeof(ext2_acl_entry_short);
+				acl->a_entries[n].e_id = ACL_UNDEFINED_ID;
+				break;
+
+			case ACL_USER:
+			case ACL_GROUP:
+				value = (char *)value + sizeof(ext2_acl_entry);
+				if ((char *)value > end)
+					goto fail;
+				acl->a_entries[n].e_id =
+					le32_to_cpu(entry->e_id);
+				break;
+
+			default:
+				goto fail;
+		}
+	}
+	if (value != end)
+		goto fail;
+	return acl;
+
+fail:
+	posix_acl_release(acl);
+	return ERR_PTR(-EINVAL);
+}
+
+/*
+ * Convert from in-memory to filesystem representation.
+ */
+static void *
+ext2_acl_to_disk(const struct posix_acl *acl, size_t *size)
+{
+	ext2_acl_header *ext_acl;
+	char *e;
+	int n;
+
+	*size = ext2_acl_size(acl->a_count);
+	ext_acl = (ext2_acl_header *)kmalloc(sizeof(ext2_acl_header) +
+		acl->a_count * sizeof(ext2_acl_entry), GFP_KERNEL);
+	if (!ext_acl)
+		return ERR_PTR(-ENOMEM);
+	ext_acl->a_version = cpu_to_le32(EXT2_ACL_VERSION);
+	e = (char *)ext_acl + sizeof(ext2_acl_header);
+	for (n=0; n < acl->a_count; n++) {
+		ext2_acl_entry *entry = (ext2_acl_entry *)e;
+		entry->e_tag  = cpu_to_le16(acl->a_entries[n].e_tag);
+		entry->e_perm = cpu_to_le16(acl->a_entries[n].e_perm);
+		switch(acl->a_entries[n].e_tag) {
+			case ACL_USER:
+			case ACL_GROUP:
+				entry->e_id =
+					cpu_to_le32(acl->a_entries[n].e_id);
+				e += sizeof(ext2_acl_entry);
+				break;
+
+			case ACL_USER_OBJ:
+			case ACL_GROUP_OBJ:
+			case ACL_MASK:
+			case ACL_OTHER:
+				e += sizeof(ext2_acl_entry_short);
+				break;
+
+			default:
+				goto fail;
+		}
+	}
+	return (char *)ext_acl;
+
+fail:
+	kfree(ext_acl);
+	return ERR_PTR(-EINVAL);
+}
+
+/*
+ * inode->i_sem: down
+ */
+static struct posix_acl *
+ext2_get_acl(struct inode *inode, int type)
+{
+	int name_index;
+	char *value;
+	struct posix_acl *acl, **p_acl;
+	const size_t size = ext2_acl_size(EXT2_ACL_MAX_ENTRIES);
+	int retval;
+
+	if (!test_opt(inode->i_sb, POSIX_ACL))
+		return 0;
+
+	switch(type) {
+		case ACL_TYPE_ACCESS:
+			p_acl = &EXT2_I(inode)->i_acl;
+			name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;
+			break;
+
+		case ACL_TYPE_DEFAULT:
+			p_acl = &EXT2_I(inode)->i_default_acl;
+			name_index = EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT;
+			break;
+
+		default:
+			return ERR_PTR(-EINVAL);
+	}
+	if (*p_acl != EXT2_ACL_NOT_CACHED)
+		return posix_acl_dup(*p_acl);
+	value = kmalloc(size, GFP_KERNEL);
+	if (!value)
+		return ERR_PTR(-ENOMEM);
+
+	retval = ext2_xattr_get(inode, name_index, "", value, size);
+
+	if (retval == -ENODATA || retval == -ENOSYS)
+		*p_acl = acl = NULL;
+	else if (retval < 0)
+		acl = ERR_PTR(retval);
+	else {
+		acl = ext2_acl_from_disk(value, retval);
+		if (!IS_ERR(acl))
+			*p_acl = posix_acl_dup(acl);
+	}
+	kfree(value);
+	return acl;
+}
+
+/*
+ * inode->i_sem: down
+ */
+static int
+ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
+{
+	int name_index;
+	void *value = NULL;
+	struct posix_acl **p_acl;
+	size_t size;
+	int error;
+
+	if (S_ISLNK(inode->i_mode))
+		return -EOPNOTSUPP;
+	if (!test_opt(inode->i_sb, POSIX_ACL))
+		return 0;
+
+	switch(type) {
+		case ACL_TYPE_ACCESS:
+			name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;
+			p_acl = &EXT2_I(inode)->i_acl;
+			if (acl) {
+				mode_t mode = inode->i_mode;
+				error = posix_acl_equiv_mode(acl, &mode);
+				if (error < 0)
+					return error;
+				else {
+					inode->i_mode = mode;
+					mark_inode_dirty(inode);
+					if (error == 0)
+						acl = NULL;
+				}
+			}
+			break;
+
+		case ACL_TYPE_DEFAULT:
+			name_index = EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT;
+			p_acl = &EXT2_I(inode)->i_default_acl;
+			if (!S_ISDIR(inode->i_mode))
+				return acl ? -EACCES : 0;
+			break;
+
+		default:
+			return -EINVAL;
+	}
+ 	if (acl) {
+		if (acl->a_count > EXT2_ACL_MAX_ENTRIES)
+			return -EINVAL;
+		value = ext2_acl_to_disk(acl, &size);
+		if (IS_ERR(value))
+			return (int)PTR_ERR(value);
+	}
+
+	error = ext2_xattr_set(inode, name_index, "", value, size, 0);
+
+	if (value)
+		kfree(value);
+	if (!error) {
+		if (*p_acl && *p_acl != EXT2_ACL_NOT_CACHED)
+			posix_acl_release(*p_acl);
+		*p_acl = posix_acl_dup(acl);
+	}
+	return error;
+}
+
+static int
+__ext2_permission(struct inode *inode, int mask, int lock)
+{
+	int mode = inode->i_mode;
+
+	/* Nobody gets write access to a read-only fs */
+	if ((mask & MAY_WRITE) && IS_RDONLY(inode) &&
+	    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
+		return -EROFS;
+	/* Nobody gets write access to an immutable file */
+	if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode))
+	    return -EACCES;
+	if (current->fsuid == inode->i_uid) {
+		mode >>= 6;
+	} else if (test_opt(inode->i_sb, POSIX_ACL)) {
+		/* ACL can't contain additional permissions if
+		   the ACL_MASK entry is 0 */
+		if (!(mode & S_IRWXG))
+			goto check_groups;
+		if (EXT2_I(inode)->i_acl == EXT2_ACL_NOT_CACHED) {
+			struct posix_acl *acl;
+
+			if (lock) {
+				down(&inode->i_sem);
+				acl = ext2_get_acl(inode, ACL_TYPE_ACCESS);
+				up(&inode->i_sem);
+			} else
+				acl = ext2_get_acl(inode, ACL_TYPE_ACCESS);
+
+			if (IS_ERR(acl))
+				return PTR_ERR(acl);
+			posix_acl_release(acl);
+			if (EXT2_I(inode)->i_acl == EXT2_ACL_NOT_CACHED)
+				return -EIO;
+		}
+		if (EXT2_I(inode)->i_acl) {
+			int error = posix_acl_permission(inode,
+				EXT2_I(inode)->i_acl, mask);
+			if (error == -EACCES)
+				goto check_capabilities;
+			return error;
+		} else
+			goto check_groups;
+	} else {
+check_groups:
+		if (in_group_p(inode->i_gid))
+			mode >>= 3;
+	}
+	if ((mode & mask & S_IRWXO) == mask)
+		return 0;
+
+check_capabilities:
+	/* Allowed to override Discretionary Access Control? */
+	if ((mask & (MAY_READ|MAY_WRITE)) || (inode->i_mode & S_IXUGO))
+		if (capable(CAP_DAC_OVERRIDE))
+			return 0;
+	/* Read and search granted if capable(CAP_DAC_READ_SEARCH) */
+	if (capable(CAP_DAC_READ_SEARCH) && ((mask == MAY_READ) ||
+	    (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE))))
+		return 0;
+	return -EACCES;
+}
+
+/*
+ * Inode operation permission().
+ *
+ * inode->i_sem: up
+ * BKL held [before 2.5.x]
+ */
+int
+ext2_permission(struct inode *inode, int mask)
+{
+	return __ext2_permission(inode, mask, 1);
+}
+
+/*
+ * Used internally if i_sem is already down.
+ */
+int
+ext2_permission_locked(struct inode *inode, int mask)
+{
+	return __ext2_permission(inode, mask, 0);
+}
+
+/*
+ * Initialize the ACLs of a new inode. Called from ext2_new_inode.
+ *
+ * dir->i_sem: down
+ * inode->i_sem: up (access to inode is still exclusive)
+ * BKL held [before 2.5.x] 
+ */
+int
+ext2_init_acl(struct inode *inode, struct inode *dir)
+{
+	struct posix_acl *acl = NULL;
+	int error = 0;
+
+	if (!S_ISLNK(inode->i_mode)) {
+		if (test_opt(dir->i_sb, POSIX_ACL)) {
+			acl = ext2_get_acl(dir, ACL_TYPE_DEFAULT);
+			if (IS_ERR(acl))
+				return PTR_ERR(acl);
+		}
+		if (!acl)
+			inode->i_mode &= ~current->fs->umask;
+	}
+	if (test_opt(inode->i_sb, POSIX_ACL) && acl) {
+               struct posix_acl *clone;
+	       mode_t mode;
+
+		if (S_ISDIR(inode->i_mode)) {
+			error = ext2_set_acl(inode, ACL_TYPE_DEFAULT, acl);
+			if (error)
+				goto cleanup;
+		}
+		clone = posix_acl_clone(acl, GFP_KERNEL);
+		error = -ENOMEM;
+		if (!clone)
+			goto cleanup;
+		mode = inode->i_mode;
+		error = posix_acl_create_masq(clone, &mode);
+		if (error >= 0) {
+			inode->i_mode = mode;
+			if (error > 0) {
+				/* This is an extended ACL */
+				error = ext2_set_acl(inode,
+						     ACL_TYPE_ACCESS, clone);
+			}
+		}
+		posix_acl_release(clone);
+	}
+cleanup:
+       posix_acl_release(acl);
+       return error;
+}
+
+/*
+ * Does chmod for an inode that may have an Access Control List. The
+ * inode->i_mode field must be updated to the desired value by the caller
+ * before calling this function.
+ * Returns 0 on success, or a negative error number.
+ *
+ * We change the ACL rather than storing some ACL entries in the file
+ * mode permission bits (which would be more efficient), because that
+ * would break once additional permissions (like  ACL_APPEND, ACL_DELETE
+ * for directories) are added. There are no more bits available in the
+ * file mode.
+ *
+ * inode->i_sem: down
+ * BKL held [before 2.5.x]
+ */
+int
+ext2_acl_chmod(struct inode *inode)
+{
+	struct posix_acl *acl, *clone;
+        int error;
+
+	if (!test_opt(inode->i_sb, POSIX_ACL))
+		return 0;
+	if (S_ISLNK(inode->i_mode))
+		return -EOPNOTSUPP;
+	acl = ext2_get_acl(inode, ACL_TYPE_ACCESS);
+	if (IS_ERR(acl) || !acl)
+		return PTR_ERR(acl);
+	clone = posix_acl_clone(acl, GFP_KERNEL);
+	posix_acl_release(acl);
+	if (!clone)
+		return -ENOMEM;
+	error = posix_acl_chmod_masq(clone, inode->i_mode);
+	if (!error)
+		error = ext2_set_acl(inode, ACL_TYPE_ACCESS, clone);
+	posix_acl_release(clone);
+	return error;
+}
+
+/*
+ * Extended attribut handlers
+ */
+static size_t
+ext2_xattr_list_acl_access(char *list, struct inode *inode,
+			   const char *name, int name_len)
+{
+	const size_t len = sizeof(XATTR_NAME_ACL_ACCESS)-1;
+
+	if (!test_opt(inode->i_sb, POSIX_ACL))
+		return 0;
+	if (list)
+		memcpy(list, XATTR_NAME_ACL_ACCESS, len);
+	return len;
+}
+
+static size_t
+ext2_xattr_list_acl_default(char *list, struct inode *inode,
+			    const char *name, int name_len)
+{
+	const size_t len = sizeof(XATTR_NAME_ACL_DEFAULT)-1;
+
+	if (!test_opt(inode->i_sb, POSIX_ACL))
+		return 0;
+	if (list)
+		memcpy(list, XATTR_NAME_ACL_DEFAULT, len);
+	return len;
+}
+
+static int
+ext2_xattr_get_acl(struct inode *inode, int type, void *buffer, size_t size)
+{
+	struct posix_acl *acl;
+	int error;
+
+	if (!test_opt(inode->i_sb, POSIX_ACL))
+		return -EOPNOTSUPP;
+
+	acl = ext2_get_acl(inode, type);
+	if (IS_ERR(acl))
+		return PTR_ERR(acl);
+	if (acl == NULL)
+		return -ENODATA;
+	error = posix_acl_to_xattr(acl, buffer, size);
+	posix_acl_release(acl);
+
+	return error;
+}
+
+static int
+ext2_xattr_get_acl_access(struct inode *inode, const char *name,
+			  void *buffer, size_t size)
+{
+	if (strcmp(name, "") != 0)
+		return -EINVAL;
+	return ext2_xattr_get_acl(inode, ACL_TYPE_ACCESS, buffer, size);
+}
+
+static int
+ext2_xattr_get_acl_default(struct inode *inode, const char *name,
+			   void *buffer, size_t size)
+{
+	if (strcmp(name, "") != 0)
+		return -EINVAL;
+	return ext2_xattr_get_acl(inode, ACL_TYPE_DEFAULT, buffer, size);
+}
+
+static int
+ext2_xattr_set_acl(struct inode *inode, int type, const void *value, size_t size)
+{
+	struct posix_acl *acl;
+	int error;
+
+	if (!test_opt(inode->i_sb, POSIX_ACL))
+		return -EOPNOTSUPP;
+	if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+		return -EPERM;
+
+	if (value) {
+		acl = posix_acl_from_xattr(value, size);
+		if (IS_ERR(acl))
+			return PTR_ERR(acl);
+		else if (acl) {
+			error = posix_acl_valid(acl);
+			if (error)
+				goto release_and_out;
+		}
+	} else
+		acl = NULL;
+
+	error = ext2_set_acl(inode, type, acl);
+
+release_and_out:
+	posix_acl_release(acl);
+	return error;
+}
+
+static int
+ext2_xattr_set_acl_access(struct inode *inode, const char *name,
+			  const void *value, size_t size, int flags)
+{
+	if (strcmp(name, "") != 0)
+		return -EINVAL;
+	return ext2_xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size);
+}
+
+static int
+ext2_xattr_set_acl_default(struct inode *inode, const char *name,
+			   const void *value, size_t size, int flags)
+{
+	if (strcmp(name, "") != 0)
+		return -EINVAL;
+	return ext2_xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size);
+}
+
+struct ext2_xattr_handler ext2_xattr_acl_access_handler = {
+	prefix:	XATTR_NAME_ACL_ACCESS,
+	list:	ext2_xattr_list_acl_access,
+	get:	ext2_xattr_get_acl_access,
+	set:	ext2_xattr_set_acl_access,
+};
+
+struct ext2_xattr_handler ext2_xattr_acl_default_handler = {
+	prefix:	XATTR_NAME_ACL_DEFAULT,
+	list:	ext2_xattr_list_acl_default,
+	get:	ext2_xattr_get_acl_default,
+	set:	ext2_xattr_set_acl_default,
+};
+
+void
+exit_ext2_acl(void)
+{
+	ext2_xattr_unregister(EXT2_XATTR_INDEX_POSIX_ACL_ACCESS,
+			      &ext2_xattr_acl_access_handler);
+	ext2_xattr_unregister(EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT,
+			      &ext2_xattr_acl_default_handler);
+}
+
+int __init
+init_ext2_acl(void)
+{
+	int error;
+
+	error = ext2_xattr_register(EXT2_XATTR_INDEX_POSIX_ACL_ACCESS,
+				    &ext2_xattr_acl_access_handler);
+	if (error)
+		goto fail;
+	error = ext2_xattr_register(EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT,
+				    &ext2_xattr_acl_default_handler);
+	if (error)
+		goto fail;
+	return 0;
+
+fail:
+	exit_ext2_acl();
+	return error;
+}
diff -Nru a/fs/ext2/acl.h b/fs/ext2/acl.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/ext2/acl.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,88 @@
+/*
+  File: fs/ext2/acl.h
+
+  (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
+*/
+
+#include <linux/xattr_acl.h>
+
+#define EXT2_ACL_VERSION	0x0001
+#define EXT2_ACL_MAX_ENTRIES	32
+
+typedef struct {
+	__u16		e_tag;
+	__u16		e_perm;
+	__u32		e_id;
+} ext2_acl_entry;
+
+typedef struct {
+	__u16		e_tag;
+	__u16		e_perm;
+} ext2_acl_entry_short;
+
+typedef struct {
+	__u32		a_version;
+} ext2_acl_header;
+
+static inline size_t ext2_acl_size(int count)
+{
+	if (count <= 4) {
+		return sizeof(ext2_acl_header) +
+		       count * sizeof(ext2_acl_entry_short);
+	} else {
+		return sizeof(ext2_acl_header) +
+		       4 * sizeof(ext2_acl_entry_short) +
+		       (count - 4) * sizeof(ext2_acl_entry);
+	}
+}
+
+static inline int ext2_acl_count(size_t size)
+{
+	ssize_t s;
+	size -= sizeof(ext2_acl_header);
+	s = size - 4 * sizeof(ext2_acl_entry_short);
+	if (s < 0) {
+		if (size % sizeof(ext2_acl_entry_short))
+			return -1;
+		return size / sizeof(ext2_acl_entry_short);
+	} else {
+		if (s % sizeof(ext2_acl_entry))
+			return -1;
+		return s / sizeof(ext2_acl_entry) + 4;
+	}
+}
+
+#ifdef CONFIG_EXT2_FS_POSIX_ACL
+
+/* Value for inode->u.ext2_i.i_acl and inode->u.ext2_i.i_default_acl
+   if the ACL has not been cached */
+#define EXT2_ACL_NOT_CACHED ((void *)-1)
+
+/* acl.c */
+extern int ext2_permission (struct inode *, int);
+extern int ext2_permission_locked (struct inode *, int);
+extern int ext2_acl_chmod (struct inode *);
+extern int ext2_init_acl (struct inode *, struct inode *);
+
+extern int init_ext2_acl(void);
+extern void exit_ext2_acl(void);
+
+#else
+#include <linux/sched.h>
+#define ext2_permission NULL
+#define ext2_get_acl	NULL
+#define ext2_set_acl	NULL
+
+static inline int
+ext2_acl_chmod (struct inode *inode)
+{
+	return 0;
+}
+
+static inline int ext2_init_acl (struct inode *inode, struct inode *dir)
+{
+	inode->i_mode &= ~current->fs->umask;
+	return 0;
+}
+#endif
+
diff -Nru a/fs/ext2/ext2.h b/fs/ext2/ext2.h
--- a/fs/ext2/ext2.h	Mon Nov  4 14:31:03 2002
+++ b/fs/ext2/ext2.h	Mon Nov  4 14:31:03 2002
@@ -10,6 +10,7 @@
 	__u32	i_faddr;
 	__u8	i_frag_no;
 	__u8	i_frag_size;
+	__u16	i_state;
 	__u32	i_file_acl;
 	__u32	i_dir_acl;
 	__u32	i_dtime;
@@ -19,11 +20,21 @@
 	__u32	i_prealloc_block;
 	__u32	i_prealloc_count;
 	__u32	i_dir_start_lookup;
+#ifdef CONFIG_EXT2_FS_POSIX_ACL
+	struct posix_acl	*i_acl;
+	struct posix_acl	*i_default_acl;
+#endif
 	rwlock_t i_meta_lock;
 	struct inode	vfs_inode;
 };
 
 /*
+ * Inode dynamic state flags
+ */
+#define EXT2_STATE_NEW			0x00000001 /* inode is newly created */
+
+
+/*
  * Function prototypes
  */
 
@@ -45,6 +56,7 @@
 extern void ext2_free_blocks (struct inode *, unsigned long,
 			      unsigned long);
 extern unsigned long ext2_count_free_blocks (struct super_block *);
+extern unsigned long ext2_count_dirs (struct super_block *);
 extern void ext2_check_blocks_bitmap (struct super_block *);
 extern struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
 						    unsigned int block_group,
@@ -78,6 +90,7 @@
 extern int ext2_sync_inode (struct inode *);
 extern void ext2_discard_prealloc (struct inode *);
 extern void ext2_truncate (struct inode *);
+extern int ext2_setattr (struct dentry *, struct iattr *);
 
 /* ioctl.c */
 extern int ext2_ioctl (struct inode *, struct file *, unsigned int,
@@ -110,6 +123,8 @@
 
 /* namei.c */
 extern struct inode_operations ext2_dir_inode_operations;
+extern struct inode_operations ext2_special_inode_operations;
 
 /* symlink.c */
 extern struct inode_operations ext2_fast_symlink_inode_operations;
+extern struct inode_operations ext2_symlink_inode_operations;
diff -Nru a/fs/ext2/file.c b/fs/ext2/file.c
--- a/fs/ext2/file.c	Mon Nov  4 14:31:01 2002
+++ b/fs/ext2/file.c	Mon Nov  4 14:31:01 2002
@@ -18,8 +18,10 @@
  * 	(jj@sunsite.ms.mff.cuni.cz)
  */
 
-#include "ext2.h"
 #include <linux/time.h>
+#include "ext2.h"
+#include "xattr.h"
+#include "acl.h"
 
 /*
  * Called when an inode is released. Note that this is different
@@ -55,4 +57,10 @@
 
 struct inode_operations ext2_file_inode_operations = {
 	.truncate	= ext2_truncate,
+	.setxattr	= ext2_setxattr,
+	.getxattr	= ext2_getxattr,
+	.listxattr	= ext2_listxattr,
+	.removexattr	= ext2_removexattr,
+	.setattr	= ext2_setattr,
+	.permission	= ext2_permission,
 };
diff -Nru a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
--- a/fs/ext2/ialloc.c	Mon Nov  4 14:31:02 2002
+++ b/fs/ext2/ialloc.c	Mon Nov  4 14:31:02 2002
@@ -13,11 +13,14 @@
  */
 
 #include <linux/config.h>
-#include "ext2.h"
 #include <linux/quotaops.h>
 #include <linux/sched.h>
 #include <linux/backing-dev.h>
 #include <linux/buffer_head.h>
+#include <linux/random.h>
+#include "ext2.h"
+#include "xattr.h"
+#include "acl.h"
 
 /*
  * ialloc.c contains the inodes allocation and deallocation routines
@@ -97,6 +100,7 @@
 	 */
 	if (!is_bad_inode(inode)) {
 		/* Quota is already initialized in iput() */
+		ext2_xattr_delete_inode(inode);
 	    	DQUOT_FREE_INODE(inode);
 		DQUOT_DROP(inode);
 	}
@@ -205,8 +209,7 @@
  * For other inodes, search forward from the parent directory\'s block
  * group to find a free inode.
  */
-
-static int find_group_dir(struct super_block *sb, int parent_group)
+static int find_group_dir(struct super_block *sb, struct inode *parent)
 {
 	struct ext2_super_block * es = EXT2_SB(sb)->s_es;
 	int ngroups = EXT2_SB(sb)->s_groups_count;
@@ -239,8 +242,140 @@
 	return best_group;
 }
 
-static int find_group_other(struct super_block *sb, int parent_group)
+/* 
+ * Orlov's allocator for directories. 
+ * 
+ * We always try to spread first-level directories.
+ *
+ * If there are blockgroups with both free inodes and free blocks counts 
+ * not worse than average we return one with smallest directory count. 
+ * Otherwise we simply return a random group. 
+ * 
+ * For the rest rules look so: 
+ * 
+ * It's OK to put directory into a group unless 
+ * it has too many directories already (max_dirs) or 
+ * it has too few free inodes left (min_inodes) or 
+ * it has too few free blocks left (min_blocks) or 
+ * it's already running too large debt (max_debt). 
+ * Parent's group is prefered, if it doesn't satisfy these 
+ * conditions we search cyclically through the rest. If none 
+ * of the groups look good we just look for a group with more 
+ * free inodes than average (starting at parent's group). 
+ * 
+ * Debt is incremented each time we allocate a directory and decremented 
+ * when we allocate an inode, within 0--255. 
+ */ 
+
+#define INODE_COST 64
+#define BLOCK_COST 256
+
+static int find_group_orlov(struct super_block *sb, struct inode *parent)
+{
+	int parent_group = EXT2_I(parent)->i_block_group;
+	struct ext2_sb_info *sbi = EXT2_SB(sb);
+	struct ext2_super_block *es = sbi->s_es;
+	int ngroups = sbi->s_groups_count;
+	int inodes_per_group = EXT2_INODES_PER_GROUP(sb);
+	int avefreei = le32_to_cpu(es->s_free_inodes_count) / ngroups;
+	int avefreeb = le32_to_cpu(es->s_free_blocks_count) / ngroups;
+	int blocks_per_dir;
+	int ndirs = sbi->s_dir_count;
+	int max_debt, max_dirs, min_blocks, min_inodes;
+	int group = -1, i;
+	struct ext2_group_desc *desc;
+	struct buffer_head *bh;
+
+	if ((parent == sb->s_root->d_inode) ||
+	    (parent->i_flags & EXT2_TOPDIR_FL)) {
+		struct ext2_group_desc *best_desc = NULL;
+		struct buffer_head *best_bh = NULL;
+		int best_ndir = inodes_per_group;
+		int best_group = -1;
+
+		get_random_bytes(&group, sizeof(group));
+		parent_group = (unsigned)group % ngroups;
+		for (i = 0; i < ngroups; i++) {
+			group = (parent_group + i) % ngroups;
+			desc = ext2_get_group_desc (sb, group, &bh);
+			if (!desc || !desc->bg_free_inodes_count)
+				continue;
+			if (le16_to_cpu(desc->bg_used_dirs_count) >= best_ndir)
+				continue;
+			if (le16_to_cpu(desc->bg_free_inodes_count) < avefreei)
+				continue;
+			if (le16_to_cpu(desc->bg_free_blocks_count) < avefreeb)
+				continue;
+			best_group = group;
+			best_ndir = le16_to_cpu(desc->bg_used_dirs_count);
+			best_desc = desc;
+			best_bh = bh;
+		}
+		if (best_group >= 0) {
+			desc = best_desc;
+			bh = best_bh;
+			group = best_group;
+			goto found;
+		}
+		goto fallback;
+	}
+
+	blocks_per_dir = (le32_to_cpu(es->s_blocks_count) -
+			  le32_to_cpu(es->s_free_blocks_count)) / ndirs;
+
+	max_dirs = ndirs / ngroups + inodes_per_group / 16;
+	min_inodes = avefreei - inodes_per_group / 4;
+	min_blocks = avefreeb - EXT2_BLOCKS_PER_GROUP(sb) / 4;
+
+	max_debt = EXT2_BLOCKS_PER_GROUP(sb) / max(blocks_per_dir, BLOCK_COST);
+	if (max_debt * INODE_COST > inodes_per_group)
+		max_debt = inodes_per_group / INODE_COST;
+	if (max_debt > 255)
+		max_debt = 255;
+	if (max_debt == 0)
+		max_debt = 1;
+
+	for (i = 0; i < ngroups; i++) {
+		group = (parent_group + i) % ngroups;
+		desc = ext2_get_group_desc (sb, group, &bh);
+		if (!desc || !desc->bg_free_inodes_count)
+			continue;
+		if (sbi->s_debts[group] >= max_debt)
+			continue;
+		if (le16_to_cpu(desc->bg_used_dirs_count) >= max_dirs)
+			continue;
+		if (le16_to_cpu(desc->bg_free_inodes_count) < min_inodes)
+			continue;
+		if (le16_to_cpu(desc->bg_free_blocks_count) < min_blocks)
+			continue;
+		goto found;
+	}
+
+fallback:
+	for (i = 0; i < ngroups; i++) {
+		group = (parent_group + i) % ngroups;
+		desc = ext2_get_group_desc (sb, group, &bh);
+		if (!desc || !desc->bg_free_inodes_count)
+			continue;
+		if (le16_to_cpu(desc->bg_free_inodes_count) >= avefreei)
+			goto found;
+	}
+
+	return -1;
+
+found:
+	desc->bg_free_inodes_count =
+		cpu_to_le16(le16_to_cpu(desc->bg_free_inodes_count) - 1);
+	desc->bg_used_dirs_count =
+		cpu_to_le16(le16_to_cpu(desc->bg_used_dirs_count) + 1);
+	sbi->s_dir_count++;
+	mark_buffer_dirty(bh);
+	return group;
+}
+
+static int find_group_other(struct super_block *sb, struct inode *parent)
 {
+	int parent_group = EXT2_I(parent)->i_block_group;
 	int ngroups = EXT2_SB(sb)->s_groups_count;
 	struct ext2_group_desc *desc;
 	struct buffer_head *bh;
@@ -300,7 +435,6 @@
 	struct ext2_super_block * es;
 	struct ext2_inode_info *ei;
 	int err;
-	struct inode *ret;
 
 	sb = dir->i_sb;
 	inode = new_inode(sb);
@@ -311,17 +445,19 @@
 	lock_super (sb);
 	es = EXT2_SB(sb)->s_es;
 repeat:
-	if (S_ISDIR(mode))
-		group = find_group_dir(sb, EXT2_I(dir)->i_block_group);
-	else 
-		group = find_group_other(sb, EXT2_I(dir)->i_block_group);
+	if (S_ISDIR(mode)) {
+		if (test_opt (sb, OLDALLOC))
+			group = find_group_dir(sb, dir);
+		else
+			group = find_group_orlov(sb, dir);
+	} else 
+		group = find_group_other(sb, dir);
 
 	err = -ENOSPC;
 	if (group == -1)
 		goto fail;
 
 	err = -EIO;
-	brelse(bitmap_bh);
 	bitmap_bh = read_inode_bitmap(sb, group);
 	if (!bitmap_bh)
 		goto fail2;
@@ -337,6 +473,7 @@
 		ll_rw_block(WRITE, 1, &bitmap_bh);
 		wait_on_buffer(bitmap_bh);
 	}
+	brelse(bitmap_bh);
 
 	ino = group * EXT2_INODES_PER_GROUP(sb) + i + 1;
 	if (ino < EXT2_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) {
@@ -350,6 +487,15 @@
 
 	es->s_free_inodes_count =
 		cpu_to_le32(le32_to_cpu(es->s_free_inodes_count) - 1);
+
+	if (S_ISDIR(mode)) {
+		if (EXT2_SB(sb)->s_debts[group] < 255)
+			EXT2_SB(sb)->s_debts[group]++;
+	} else {
+		if (EXT2_SB(sb)->s_debts[group])
+			EXT2_SB(sb)->s_debts[group]--;
+	}
+
 	mark_buffer_dirty(EXT2_SB(sb)->s_sbh);
 	sb->s_dirt = 1;
 	inode->i_uid = current->fsuid;
@@ -386,27 +532,34 @@
 	ei->i_prealloc_block = 0;
 	ei->i_prealloc_count = 0;
 	ei->i_dir_start_lookup = 0;
+	ei->i_state = EXT2_STATE_NEW;
 	if (ei->i_flags & EXT2_SYNC_FL)
 		inode->i_flags |= S_SYNC;
 	if (ei->i_flags & EXT2_DIRSYNC_FL)
 		inode->i_flags |= S_DIRSYNC;
 	inode->i_generation = EXT2_SB(sb)->s_next_generation++;
 	insert_inode_hash(inode);
-	mark_inode_dirty(inode);
 
 	unlock_super(sb);
-	ret = inode;
 	if(DQUOT_ALLOC_INODE(inode)) {
 		DQUOT_DROP(inode);
-		inode->i_flags |= S_NOQUOTA;
-		inode->i_nlink = 0;
-		iput(inode);
-		ret = ERR_PTR(-EDQUOT);
-	} else {
-		ext2_debug("allocating inode %lu\n", inode->i_ino);
-		ext2_preread_inode(inode);
+		goto fail3;
+	}
+	err = ext2_init_acl(inode, dir);
+	if (err) {
+		DQUOT_FREE_INODE(inode);
+		goto fail3;
 	}
-	goto out;
+	mark_inode_dirty(inode);
+	ext2_debug("allocating inode %lu\n", inode->i_ino);
+	ext2_preread_inode(inode);
+	return inode;
+
+fail3:
+	inode->i_flags |= S_NOQUOTA;
+	inode->i_nlink = 0;
+	iput(inode);
+	return ERR_PTR(err);
 
 fail2:
 	desc = ext2_get_group_desc (sb, group, &bh2);
@@ -420,10 +573,10 @@
 	unlock_super(sb);
 	make_bad_inode(inode);
 	iput(inode);
-	ret = ERR_PTR(err);
-	goto out;
+	return ERR_PTR(err);
 
 bad_count:
+	brelse(bitmap_bh);
 	ext2_error (sb, "ext2_new_inode",
 		    "Free inodes count corrupted in group %d",
 		    group);
@@ -436,9 +589,6 @@
 	desc->bg_free_inodes_count = 0;
 	mark_buffer_dirty(bh2);
 	goto repeat;
-out:
-	brelse(bitmap_bh);
-	return ret;
 }
 
 unsigned long ext2_count_free_inodes (struct super_block * sb)
@@ -477,6 +627,21 @@
 #else
 	return le32_to_cpu(EXT2_SB(sb)->s_es->s_free_inodes_count);
 #endif
+}
+
+/* Called at mount-time, super-block is locked */
+unsigned long ext2_count_dirs (struct super_block * sb)
+{
+	unsigned long count = 0;
+	int i;
+
+	for (i = 0; i < EXT2_SB(sb)->s_groups_count; i++) {
+		struct ext2_group_desc *gdp = ext2_get_group_desc (sb, i, NULL);
+		if (!gdp)
+			continue;
+		count += le16_to_cpu(gdp->bg_used_dirs_count);
+	}
+	return count;
 }
 
 #ifdef CONFIG_EXT2_CHECK
diff -Nru a/fs/ext2/inode.c b/fs/ext2/inode.c
--- a/fs/ext2/inode.c	Mon Nov  4 14:31:00 2002
+++ b/fs/ext2/inode.c	Mon Nov  4 14:31:00 2002
@@ -22,7 +22,6 @@
  *  Assorted race fixes, rewrite of ext2_get_block() by Al Viro, 2000
  */
 
-#include "ext2.h"
 #include <linux/smp_lock.h>
 #include <linux/time.h>
 #include <linux/highuid.h>
@@ -31,6 +30,8 @@
 #include <linux/module.h>
 #include <linux/buffer_head.h>
 #include <linux/mpage.h>
+#include "ext2.h"
+#include "acl.h"
 
 MODULE_AUTHOR("Remy Card and others");
 MODULE_DESCRIPTION("Second Extended Filesystem");
@@ -39,6 +40,18 @@
 static int ext2_update_inode(struct inode * inode, int do_sync);
 
 /*
+ * Test whether an inode is a fast symlink.
+ */
+static inline int ext2_inode_is_fast_symlink(struct inode *inode)
+{
+	int ea_blocks = EXT2_I(inode)->i_file_acl ?
+		(inode->i_sb->s_blocksize >> 9) : 0;
+
+	return (S_ISLNK(inode->i_mode) &&
+		inode->i_blocks - ea_blocks == 0);
+}
+
+/*
  * Called at each iput()
  */
 void ext2_put_inode (struct inode * inode)
@@ -51,9 +64,7 @@
  */
 void ext2_delete_inode (struct inode * inode)
 {
-	if (is_bad_inode(inode) ||
-	    inode->i_ino == EXT2_ACL_IDX_INO ||
-	    inode->i_ino == EXT2_ACL_DATA_INO)
+	if (is_bad_inode(inode))
 		goto no_delete;
 	EXT2_I(inode)->i_dtime	= CURRENT_TIME;
 	mark_inode_dirty(inode);
@@ -843,6 +854,8 @@
 	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
 	    S_ISLNK(inode->i_mode)))
 		return;
+	if (ext2_inode_is_fast_symlink(inode))
+		return;
 	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
 		return;
 
@@ -929,8 +942,7 @@
 	struct ext2_group_desc * gdp;
 
 	*p = NULL;
-	if ((ino != EXT2_ROOT_INO && ino != EXT2_ACL_IDX_INO &&
-	     ino != EXT2_ACL_DATA_INO && ino < EXT2_FIRST_INO(sb)) ||
+	if ((ino != EXT2_ROOT_INO && ino < EXT2_FIRST_INO(sb)) ||
 	    ino > le32_to_cpu(EXT2_SB(sb)->s_es->s_inodes_count))
 		goto Einval;
 
@@ -971,6 +983,10 @@
 	struct ext2_inode * raw_inode = ext2_get_inode(inode->i_sb, ino, &bh);
 	int n;
 
+#ifdef CONFIG_EXT2_FS_POSIX_ACL
+	ei->i_acl = EXT2_ACL_NOT_CACHED;
+	ei->i_default_acl = EXT2_ACL_NOT_CACHED;
+#endif
 	if (IS_ERR(raw_inode))
  		goto bad_inode;
 
@@ -1012,6 +1028,7 @@
 		ei->i_dir_acl = le32_to_cpu(raw_inode->i_dir_acl);
 	ei->i_dtime = 0;
 	inode->i_generation = le32_to_cpu(raw_inode->i_generation);
+	ei->i_state = 0;
 	ei->i_next_alloc_block = 0;
 	ei->i_next_alloc_goal = 0;
 	ei->i_prealloc_count = 0;
@@ -1025,9 +1042,7 @@
 	for (n = 0; n < EXT2_N_BLOCKS; n++)
 		ei->i_data[n] = raw_inode->i_block[n];
 
-	if (ino == EXT2_ACL_IDX_INO || ino == EXT2_ACL_DATA_INO)
-		/* Nothing to do */ ;
-	else if (S_ISREG(inode->i_mode)) {
+	if (S_ISREG(inode->i_mode)) {
 		inode->i_op = &ext2_file_inode_operations;
 		inode->i_fop = &ext2_file_operations;
 		inode->i_mapping->a_ops = &ext2_aops;
@@ -1036,15 +1051,17 @@
 		inode->i_fop = &ext2_dir_operations;
 		inode->i_mapping->a_ops = &ext2_aops;
 	} else if (S_ISLNK(inode->i_mode)) {
-		if (!inode->i_blocks)
+		if (ext2_inode_is_fast_symlink(inode))
 			inode->i_op = &ext2_fast_symlink_inode_operations;
 		else {
-			inode->i_op = &page_symlink_inode_operations;
+			inode->i_op = &ext2_symlink_inode_operations;
 			inode->i_mapping->a_ops = &ext2_aops;
 		}
-	} else 
+	} else {
+		inode->i_op = &ext2_special_inode_operations;
 		init_special_inode(inode, inode->i_mode,
 				   le32_to_cpu(raw_inode->i_block[0]));
+	}
 	brelse (bh);
 	if (ei->i_flags & EXT2_SYNC_FL)
 		inode->i_flags |= S_SYNC;
@@ -1076,12 +1093,11 @@
 	if (IS_ERR(raw_inode))
  		return -EIO;
 
-	if (ino == EXT2_ACL_IDX_INO || ino == EXT2_ACL_DATA_INO) {
-		ext2_error (sb, "ext2_write_inode", "bad inode number: %lu",
-			    (unsigned long) ino);
-		brelse(bh);
-		return -EIO;
-	}
+	/* For fields not not tracking in the in-memory inode,
+	 * initialise them to zero for new inodes. */
+	if (ei->i_state & EXT2_STATE_NEW)
+		memset(raw_inode, 0, EXT2_SB(sb)->s_inode_size);
+
 	raw_inode->i_mode = cpu_to_le16(inode->i_mode);
 	if (!(test_opt(sb, NO_UID32))) {
 		raw_inode->i_uid_low = cpu_to_le16(low_16_bits(uid));
@@ -1152,6 +1168,7 @@
 			err = -EIO;
 		}
 	}
+	ei->i_state &= ~EXT2_STATE_NEW;
 	brelse (bh);
 	return err;
 }
@@ -1165,3 +1182,18 @@
 {
 	return ext2_update_inode (inode, 1);
 }
+
+int ext2_setattr(struct dentry *dentry, struct iattr *iattr)
+{
+	struct inode *inode = dentry->d_inode;
+	int error;
+
+	error = inode_change_ok(inode, iattr);
+	if (error)
+		return error;
+	inode_setattr(inode, iattr);
+	if (iattr->ia_valid & ATTR_MODE)
+		error = ext2_acl_chmod(inode);
+	return error;
+}
+
diff -Nru a/fs/ext2/namei.c b/fs/ext2/namei.c
--- a/fs/ext2/namei.c	Mon Nov  4 14:31:02 2002
+++ b/fs/ext2/namei.c	Mon Nov  4 14:31:02 2002
@@ -29,8 +29,10 @@
  *        David S. Miller (davem@caip.rutgers.edu), 1995
  */
 
-#include "ext2.h"
 #include <linux/pagemap.h>
+#include "ext2.h"
+#include "xattr.h"
+#include "acl.h"
 
 /*
  * Couple of helper functions - make the code slightly cleaner.
@@ -137,7 +139,10 @@
 	struct inode * inode = ext2_new_inode (dir, mode);
 	int err = PTR_ERR(inode);
 	if (!IS_ERR(inode)) {
-		init_special_inode(inode, mode, rdev);
+		init_special_inode(inode, inode->i_mode, rdev);
+#ifdef CONFIG_EXT2_FS_EXT_ATTR
+		inode->i_op = &ext2_special_inode_operations;
+#endif
 		mark_inode_dirty(inode);
 		err = ext2_add_nondir(dentry, inode);
 	}
@@ -162,7 +167,7 @@
 
 	if (l > sizeof (EXT2_I(inode)->i_data)) {
 		/* slow symlink */
-		inode->i_op = &page_symlink_inode_operations;
+		inode->i_op = &ext2_symlink_inode_operations;
 		inode->i_mapping->a_ops = &ext2_aops;
 		err = page_symlink(inode, symname, l);
 		if (err)
@@ -368,4 +373,19 @@
 	.rmdir		= ext2_rmdir,
 	.mknod		= ext2_mknod,
 	.rename		= ext2_rename,
+	.setxattr	= ext2_setxattr,
+	.getxattr	= ext2_getxattr,
+	.listxattr	= ext2_listxattr,
+	.removexattr	= ext2_removexattr,
+	.setattr	= ext2_setattr,
+	.permission	= ext2_permission,
+};
+
+struct inode_operations ext2_special_inode_operations = {
+	.setxattr	= ext2_setxattr,
+	.getxattr	= ext2_getxattr,
+	.listxattr	= ext2_listxattr,
+	.removexattr	= ext2_removexattr,
+	.setattr	= ext2_setattr,
+	.permission	= ext2_permission,
 };
diff -Nru a/fs/ext2/super.c b/fs/ext2/super.c
--- a/fs/ext2/super.c	Mon Nov  4 14:31:02 2002
+++ b/fs/ext2/super.c	Mon Nov  4 14:31:02 2002
@@ -19,7 +19,6 @@
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/string.h>
-#include "ext2.h"
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/blkdev.h>
@@ -27,7 +26,9 @@
 #include <linux/buffer_head.h>
 #include <linux/smp_lock.h>
 #include <asm/uaccess.h>
-
+#include "ext2.h"
+#include "xattr.h"
+#include "acl.h"
 
 static void ext2_sync_super(struct super_block *sb,
 			    struct ext2_super_block *es);
@@ -52,16 +53,12 @@
 	va_start (args, fmt);
 	vsprintf (error_buf, fmt, args);
 	va_end (args);
-	if (test_opt (sb, ERRORS_PANIC) ||
-	    (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_PANIC &&
-	     !test_opt (sb, ERRORS_CONT) && !test_opt (sb, ERRORS_RO)))
+	if (test_opt (sb, ERRORS_PANIC))
 		panic ("EXT2-fs panic (device %s): %s: %s\n",
 		       sb->s_id, function, error_buf);
 	printk (KERN_CRIT "EXT2-fs error (device %s): %s: %s\n",
 		sb->s_id, function, error_buf);
-	if (test_opt (sb, ERRORS_RO) ||
-	    (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_RO &&
-	     !test_opt (sb, ERRORS_CONT) && !test_opt (sb, ERRORS_PANIC))) {
+	if (test_opt (sb, ERRORS_RO)) {
 		printk ("Remounting filesystem read-only\n");
 		sb->s_flags |= MS_RDONLY;
 	}
@@ -131,6 +128,7 @@
 	int i;
 	struct ext2_sb_info *sbi = EXT2_SB(sb);
 
+	ext2_xattr_put_super(sb);
 	if (!(sb->s_flags & MS_RDONLY)) {
 		struct ext2_super_block *es = sbi->s_es;
 
@@ -142,6 +140,7 @@
 		if (sbi->s_group_desc[i])
 			brelse (sbi->s_group_desc[i]);
 	kfree(sbi->s_group_desc);
+	kfree(sbi->s_debts);
 	brelse (sbi->s_sbh);
 	sb->s_fs_info = NULL;
 	kfree(sbi);
@@ -157,6 +156,10 @@
 	ei = (struct ext2_inode_info *)kmem_cache_alloc(ext2_inode_cachep, SLAB_KERNEL);
 	if (!ei)
 		return NULL;
+#ifdef CONFIG_EXT2_FS_POSIX_ACL
+	ei->i_acl = EXT2_ACL_NOT_CACHED;
+	ei->i_default_acl = EXT2_ACL_NOT_CACHED;
+#endif
 	return &ei->vfs_inode;
 }
 
@@ -193,6 +196,26 @@
 		printk(KERN_INFO "ext2_inode_cache: not all structures were freed\n");
 }
 
+#ifdef CONFIG_EXT2_FS_POSIX_ACL
+
+static void ext2_clear_inode(struct inode *inode)
+{
+	struct ext2_inode_info *ei = EXT2_I(inode);
+
+	if (ei->i_acl && ei->i_acl != EXT2_ACL_NOT_CACHED) {
+		posix_acl_release(ei->i_acl);
+		ei->i_acl = EXT2_ACL_NOT_CACHED;
+	}
+	if (ei->i_default_acl && ei->i_default_acl != EXT2_ACL_NOT_CACHED) {
+		posix_acl_release(ei->i_default_acl);
+		ei->i_default_acl = EXT2_ACL_NOT_CACHED;
+	}
+}
+
+#else
+# define ext2_clear_inode NULL
+#endif
+
 static struct super_operations ext2_sops = {
 	.alloc_inode	= ext2_alloc_inode,
 	.destroy_inode	= ext2_destroy_inode,
@@ -204,6 +227,7 @@
 	.write_super	= ext2_write_super,
 	.statfs		= ext2_statfs,
 	.remount_fs	= ext2_remount,
+	.clear_inode	= ext2_clear_inode,
 };
 
 /* Yes, most of these are left as NULL!!
@@ -216,12 +240,61 @@
 	.get_parent = ext2_get_parent,
 };
 
+static unsigned long get_sb_block(void **data)
+{
+	unsigned long 	sb_block;
+	char 		*options = (char *) *data;
+
+	if (!options || strncmp(options, "sb=", 3) != 0)
+		return 1;	/* Default location */
+	options += 3;
+	sb_block = simple_strtoul(options, &options, 0);
+	if (*options && *options != ',') {
+		printk("EXT2-fs: Invalid sb specification: %s\n",
+		       (char *) *data);
+		return 1;
+	}
+	if (*options == ',')
+		options++;
+	*data = (void *) options;
+	return sb_block;
+}
+
+static int want_value(char *value, char *option)
+{
+	if (!value || !*value) {
+		printk(KERN_NOTICE "EXT2-fs: the %s option needs an argument\n",
+		       option);
+		return -1;
+	}
+	return 0;
+}
+
+static int want_null_value(char *value, char *option)
+{
+	if (*value) {
+		printk(KERN_NOTICE "EXT2-fs: Invalid %s argument: %s\n",
+		       option, value);
+		return -1;
+	}
+	return 0;
+}
+
+static int want_numeric(char *value, char *option, unsigned long *number)
+{
+	if (want_value(value, option))
+		return -1;
+	*number = simple_strtoul(value, &value, 0);
+	if (want_null_value(value, option))
+		return -1;
+	return 0;
+}
+
 /*
  * This function has been shamelessly adapted from the msdos fs
  */
-static int parse_options (char * options, unsigned long * sb_block,
-			  unsigned short *resuid, unsigned short * resgid,
-			  unsigned long * mount_options)
+static int parse_options (char * options,
+			  struct ext2_sb_info *sbi)
 {
 	char * this_char;
 	char * value;
@@ -233,23 +306,37 @@
 			continue;
 		if ((value = strchr (this_char, '=')) != NULL)
 			*value++ = 0;
+#ifdef CONFIG_EXT2_FS_XATTR
+		if (!strcmp (this_char, "user_xattr"))
+			set_opt (sbi->s_mount_opt, XATTR_USER);
+		else if (!strcmp (this_char, "nouser_xattr"))
+			clear_opt (sbi->s_mount_opt, XATTR_USER);
+		else
+#endif
+#ifdef CONFIG_EXT2_FS_POSIX_ACL
+		if (!strcmp(this_char, "acl"))
+			set_opt(sbi->s_mount_opt, POSIX_ACL);
+		else if (!strcmp(this_char, "noacl"))
+			clear_opt(sbi->s_mount_opt, POSIX_ACL);
+		else
+#endif
 		if (!strcmp (this_char, "bsddf"))
-			clear_opt (*mount_options, MINIX_DF);
+			clear_opt (sbi->s_mount_opt, MINIX_DF);
 		else if (!strcmp (this_char, "nouid32")) {
-			set_opt (*mount_options, NO_UID32);
+			set_opt (sbi->s_mount_opt, NO_UID32);
 		}
 		else if (!strcmp (this_char, "check")) {
 			if (!value || !*value || !strcmp (value, "none"))
-				clear_opt (*mount_options, CHECK);
+				clear_opt (sbi->s_mount_opt, CHECK);
 			else
 #ifdef CONFIG_EXT2_CHECK
-				set_opt (*mount_options, CHECK);
+				set_opt (sbi->s_mount_opt, CHECK);
 #else
 				printk("EXT2 Check option not supported\n");
 #endif
 		}
 		else if (!strcmp (this_char, "debug"))
-			set_opt (*mount_options, DEBUG);
+			set_opt (sbi->s_mount_opt, DEBUG);
 		else if (!strcmp (this_char, "errors")) {
 			if (!value || !*value) {
 				printk ("EXT2-fs: the errors option requires "
@@ -257,19 +344,19 @@
 				return 0;
 			}
 			if (!strcmp (value, "continue")) {
-				clear_opt (*mount_options, ERRORS_RO);
-				clear_opt (*mount_options, ERRORS_PANIC);
-				set_opt (*mount_options, ERRORS_CONT);
+				clear_opt (sbi->s_mount_opt, ERRORS_RO);
+				clear_opt (sbi->s_mount_opt, ERRORS_PANIC);
+				set_opt (sbi->s_mount_opt, ERRORS_CONT);
 			}
 			else if (!strcmp (value, "remount-ro")) {
-				clear_opt (*mount_options, ERRORS_CONT);
-				clear_opt (*mount_options, ERRORS_PANIC);
-				set_opt (*mount_options, ERRORS_RO);
+				clear_opt (sbi->s_mount_opt, ERRORS_CONT);
+				clear_opt (sbi->s_mount_opt, ERRORS_PANIC);
+				set_opt (sbi->s_mount_opt, ERRORS_RO);
 			}
 			else if (!strcmp (value, "panic")) {
-				clear_opt (*mount_options, ERRORS_CONT);
-				clear_opt (*mount_options, ERRORS_RO);
-				set_opt (*mount_options, ERRORS_PANIC);
+				clear_opt (sbi->s_mount_opt, ERRORS_CONT);
+				clear_opt (sbi->s_mount_opt, ERRORS_RO);
+				set_opt (sbi->s_mount_opt, ERRORS_PANIC);
 			}
 			else {
 				printk ("EXT2-fs: Invalid errors option: %s\n",
@@ -279,53 +366,30 @@
 		}
 		else if (!strcmp (this_char, "grpid") ||
 			 !strcmp (this_char, "bsdgroups"))
-			set_opt (*mount_options, GRPID);
+			set_opt (sbi->s_mount_opt, GRPID);
 		else if (!strcmp (this_char, "minixdf"))
-			set_opt (*mount_options, MINIX_DF);
+			set_opt (sbi->s_mount_opt, MINIX_DF);
 		else if (!strcmp (this_char, "nocheck"))
-			clear_opt (*mount_options, CHECK);
+			clear_opt (sbi->s_mount_opt, CHECK);
 		else if (!strcmp (this_char, "nogrpid") ||
 			 !strcmp (this_char, "sysvgroups"))
-			clear_opt (*mount_options, GRPID);
+			clear_opt (sbi->s_mount_opt, GRPID);
 		else if (!strcmp (this_char, "resgid")) {
-			if (!value || !*value) {
-				printk ("EXT2-fs: the resgid option requires "
-					"an argument\n");
+			unsigned long v;
+			if (want_numeric(value, "resgid", &v))
 				return 0;
-			}
-			*resgid = simple_strtoul (value, &value, 0);
-			if (*value) {
-				printk ("EXT2-fs: Invalid resgid option: %s\n",
-					value);
-				return 0;
-			}
+			sbi->s_resgid = v;
 		}
 		else if (!strcmp (this_char, "resuid")) {
-			if (!value || !*value) {
-				printk ("EXT2-fs: the resuid option requires "
-					"an argument");
-				return 0;
-			}
-			*resuid = simple_strtoul (value, &value, 0);
-			if (*value) {
-				printk ("EXT2-fs: Invalid resuid option: %s\n",
-					value);
+			unsigned long v;
+			if (want_numeric(value, "resuid", &v))
 				return 0;
-			}
-		}
-		else if (!strcmp (this_char, "sb")) {
-			if (!value || !*value) {
-				printk ("EXT2-fs: the sb option requires "
-					"an argument");
-				return 0;
-			}
-			*sb_block = simple_strtoul (value, &value, 0);
-			if (*value) {
-				printk ("EXT2-fs: Invalid sb option: %s\n",
-					value);
-				return 0;
-			}
+			sbi->s_resuid = v;
 		}
+		else if (!strcmp (this_char, "oldalloc"))
+			set_opt (sbi->s_mount_opt, OLDALLOC);
+		else if (!strcmp (this_char, "orlov"))
+			clear_opt (sbi->s_mount_opt, OLDALLOC);
 		/* Silently ignore the quota options */
 		else if (!strcmp (this_char, "grpquota")
 		         || !strcmp (this_char, "noquota")
@@ -458,16 +522,32 @@
 	return res;
 }
 
+static unsigned long descriptor_loc(struct super_block *sb,
+				    unsigned long logic_sb_block,
+				    int nr)
+{
+	struct ext2_sb_info *sbi = EXT2_SB(sb);
+	unsigned long bg, first_data_block, first_meta_bg;
+	
+	first_data_block = le32_to_cpu(sbi->s_es->s_first_data_block);
+	first_meta_bg = le32_to_cpu(sbi->s_es->s_first_meta_bg);
+
+	if (!EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_META_BG) ||
+	    nr < first_meta_bg)
+		return (logic_sb_block + nr + 1);
+	bg = sbi->s_desc_per_block * nr;
+	return (first_data_block + 1 + (bg * sbi->s_blocks_per_group));
+}
+
 static int ext2_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct buffer_head * bh;
 	struct ext2_sb_info * sbi;
 	struct ext2_super_block * es;
-	unsigned long sb_block = 1;
-	unsigned short resuid = EXT2_DEF_RESUID;
-	unsigned short resgid = EXT2_DEF_RESGID;
-	unsigned long logic_sb_block = 1;
+	unsigned long block, sb_block = 1;
+	unsigned long logic_sb_block = get_sb_block(&data);
 	unsigned long offset = 0;
+	unsigned long def_mount_opts;
 	int blocksize = BLOCK_SIZE;
 	int db_count;
 	int i, j;
@@ -485,12 +565,6 @@
 	 * This is important for devices that have a hardware
 	 * sectorsize that is larger than the default.
 	 */
-
-	sbi->s_mount_opt = 0;
-	if (!parse_options ((char *) data, &sb_block, &resuid, &resgid,
-	    &sbi->s_mount_opt))
-		goto failed_sbi;
-
 	blocksize = sb_min_blocksize(sb, BLOCK_SIZE);
 	if (!blocksize) {
 		printk ("EXT2-fs: unable to set blocksize\n");
@@ -498,9 +572,8 @@
 	}
 
 	/*
-	 * If the superblock doesn't start on a sector boundary,
-	 * calculate the offset.  FIXME(eric) this doesn't make sense
-	 * that we would have to do this.
+	 * If the superblock doesn't start on a hardware sector boundary,
+	 * calculate the offset.  
 	 */
 	if (blocksize != BLOCK_SIZE) {
 		logic_sb_block = (sb_block*BLOCK_SIZE) / blocksize;
@@ -524,6 +597,35 @@
 				sb->s_id);
 		goto failed_mount;
 	}
+
+	/* Set defaults before we parse the mount options */
+	def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
+	if (def_mount_opts & EXT2_DEFM_DEBUG)
+		set_opt(sbi->s_mount_opt, DEBUG);
+	if (def_mount_opts & EXT2_DEFM_BSDGROUPS)
+		set_opt(sbi->s_mount_opt, GRPID);
+	if (def_mount_opts & EXT2_DEFM_UID16)
+		set_opt(sbi->s_mount_opt, NO_UID32);
+	if (def_mount_opts & EXT2_DEFM_XATTR_USER)
+		set_opt(sbi->s_mount_opt, XATTR_USER);
+	if (def_mount_opts & EXT2_DEFM_ACL)
+		set_opt(sbi->s_mount_opt, POSIX_ACL);
+	
+	if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_PANIC)
+		set_opt(sbi->s_mount_opt, ERRORS_PANIC);
+	else if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_RO)
+		set_opt(sbi->s_mount_opt, ERRORS_RO);
+
+	sbi->s_resuid = le16_to_cpu(es->s_def_resuid);
+	sbi->s_resgid = le16_to_cpu(es->s_def_resgid);
+	
+	if (!parse_options ((char *) data, sbi))
+		goto failed_mount;
+
+	sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
+		((EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ?
+		 MS_POSIXACL : 0);
+
 	if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV &&
 	    (EXT2_HAS_COMPAT_FEATURE(sb, ~0U) ||
 	     EXT2_HAS_RO_COMPAT_FEATURE(sb, ~0U) ||
@@ -582,7 +684,9 @@
 	} else {
 		sbi->s_inode_size = le16_to_cpu(es->s_inode_size);
 		sbi->s_first_ino = le32_to_cpu(es->s_first_ino);
-		if (sbi->s_inode_size != EXT2_GOOD_OLD_INODE_SIZE) {
+		if ((sbi->s_inode_size < EXT2_GOOD_OLD_INODE_SIZE) ||
+		    (sbi->s_inode_size & (sbi->s_inode_size - 1)) ||
+		    (sbi->s_inode_size > blocksize)) {
 			printk ("EXT2-fs: unsupported inode size: %d\n",
 				sbi->s_inode_size);
 			goto failed_mount;
@@ -605,14 +709,6 @@
 	sbi->s_desc_per_block = sb->s_blocksize /
 					 sizeof (struct ext2_group_desc);
 	sbi->s_sbh = bh;
-	if (resuid != EXT2_DEF_RESUID)
-		sbi->s_resuid = resuid;
-	else
-		sbi->s_resuid = le16_to_cpu(es->s_def_resuid);
-	if (resgid != EXT2_DEF_RESGID)
-		sbi->s_resgid = resgid;
-	else
-		sbi->s_resgid = le16_to_cpu(es->s_def_resgid);
 	sbi->s_mount_state = le16_to_cpu(es->s_state);
 	sbi->s_addr_per_block_bits =
 		log2 (EXT2_ADDR_PER_BLOCK(sb));
@@ -665,14 +761,22 @@
 		printk ("EXT2-fs: not enough memory\n");
 		goto failed_mount;
 	}
+	sbi->s_debts = kmalloc(sbi->s_groups_count * sizeof(*sbi->s_debts),
+			       GFP_KERNEL);
+	if (!sbi->s_debts) {
+		printk ("EXT2-fs: not enough memory\n");
+		goto failed_mount_group_desc;
+	}
+	memset(sbi->s_debts, 0, sbi->s_groups_count * sizeof(*sbi->s_debts));
 	for (i = 0; i < db_count; i++) {
-		sbi->s_group_desc[i] = sb_bread(sb, logic_sb_block + i + 1);
+		block = descriptor_loc(sb, logic_sb_block, i);
+		sbi->s_group_desc[i] = sb_bread(sb, block);
 		if (!sbi->s_group_desc[i]) {
 			for (j = 0; j < i; j++)
 				brelse (sbi->s_group_desc[j]);
 			kfree(sbi->s_group_desc);
 			printk ("EXT2-fs: unable to read group descriptors\n");
-			goto failed_mount;
+			goto failed_mount_group_desc;
 		}
 	}
 	if (!ext2_check_descriptors (sb)) {
@@ -681,6 +785,7 @@
 		goto failed_mount2;
 	}
 	sbi->s_gdb_count = db_count;
+	sbi->s_dir_count = ext2_count_dirs(sb);
 	get_random_bytes(&sbi->s_next_generation, sizeof(u32));
 	/*
 	 * set up enough so that it can read an inode
@@ -706,7 +811,10 @@
 failed_mount2:
 	for (i = 0; i < db_count; i++)
 		brelse(sbi->s_group_desc[i]);
+failed_mount_group_desc:
 	kfree(sbi->s_group_desc);
+	if (sbi->s_debts)
+		kfree(sbi->s_debts);
 failed_mount:
 	brelse(bh);
 failed_sbi:
@@ -767,22 +875,16 @@
 {
 	struct ext2_sb_info * sbi = EXT2_SB(sb);
 	struct ext2_super_block * es;
-	unsigned short resuid = sbi->s_resuid;
-	unsigned short resgid = sbi->s_resgid;
-	unsigned long new_mount_opt;
-	unsigned long tmp;
 
 	/*
 	 * Allow the "check" option to be passed as a remount option.
 	 */
-	new_mount_opt = sbi->s_mount_opt;
-	if (!parse_options (data, &tmp, &resuid, &resgid,
-			    &new_mount_opt))
+	if (!parse_options (data, sbi))
 		return -EINVAL;
 
-	sbi->s_mount_opt = new_mount_opt;
-	sbi->s_resuid = resuid;
-	sbi->s_resgid = resgid;
+	sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
+		((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
+
 	es = sbi->s_es;
 	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
 		return 0;
@@ -883,7 +985,10 @@
 
 static int __init init_ext2_fs(void)
 {
-	int err = init_inodecache();
+	int err = init_ext2_xattr();
+	if (err)
+		return err;
+	err = init_inodecache();
 	if (err)
 		goto out1;
         err = register_filesystem(&ext2_fs_type);
@@ -893,6 +998,7 @@
 out:
 	destroy_inodecache();
 out1:
+	exit_ext2_xattr();
 	return err;
 }
 
@@ -900,6 +1006,7 @@
 {
 	unregister_filesystem(&ext2_fs_type);
 	destroy_inodecache();
+	exit_ext2_xattr();
 }
 
 module_init(init_ext2_fs)
diff -Nru a/fs/ext2/symlink.c b/fs/ext2/symlink.c
--- a/fs/ext2/symlink.c	Mon Nov  4 14:31:01 2002
+++ b/fs/ext2/symlink.c	Mon Nov  4 14:31:01 2002
@@ -18,6 +18,7 @@
  */
 
 #include "ext2.h"
+#include "xattr.h"
 
 static int ext2_readlink(struct dentry *dentry, char *buffer, int buflen)
 {
@@ -31,7 +32,20 @@
 	return vfs_follow_link(nd, (char *)ei->i_data);
 }
 
+struct inode_operations ext2_symlink_inode_operations = {
+	.readlink	= page_readlink,
+	.follow_link	= page_follow_link,
+	.setxattr	= ext2_setxattr,
+	.getxattr	= ext2_getxattr,
+	.listxattr	= ext2_listxattr,
+	.removexattr	= ext2_removexattr,
+};
+ 
 struct inode_operations ext2_fast_symlink_inode_operations = {
 	.readlink	= ext2_readlink,
 	.follow_link	= ext2_follow_link,
+	.setxattr	= ext2_setxattr,
+	.getxattr	= ext2_getxattr,
+	.listxattr	= ext2_listxattr,
+	.removexattr	= ext2_removexattr,
 };
diff -Nru a/fs/ext2/xattr.c b/fs/ext2/xattr.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/ext2/xattr.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,1135 @@
+/*
+ * linux/fs/ext2/xattr.c
+ *
+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
+ *
+ * Fix by Harrison Xing <harrison@mountainviewdata.com>.
+ * Extended attributes for symlinks and special files added per
+ *  suggestion of Luka Renko <luka.renko@hermes.si>.
+ */
+
+/*
+ * Extended attributes are stored on disk blocks allocated outside of
+ * any inode. The i_file_acl field is then made to point to this allocated
+ * block. If all extended attributes of an inode are identical, these
+ * inodes may share the same extended attribute block. Such situations
+ * are automatically detected by keeping a cache of recent attribute block
+ * numbers and hashes over the block's contents in memory.
+ *
+ *
+ * Extended attribute block layout:
+ *
+ *   +------------------+
+ *   | header           |
+ *   ¦ entry 1          | |
+ *   | entry 2          | | growing downwards
+ *   | entry 3          | v
+ *   | four null bytes  |
+ *   | . . .            |
+ *   | value 1          | ^
+ *   | value 3          | | growing upwards
+ *   | value 2          | |
+ *   +------------------+
+ *
+ * The block header is followed by multiple entry descriptors. These entry
+ * descriptors are variable in size, and alligned to EXT2_XATTR_PAD
+ * byte boundaries. The entry descriptors are sorted by attribute name,
+ * so that two extended attribute blocks can be compared efficiently.
+ *
+ * Attribute values are aligned to the end of the block, stored in
+ * no specific order. They are also padded to EXT2_XATTR_PAD byte
+ * boundaries. No additional gaps are left between them.
+ *
+ * Locking strategy
+ * ----------------
+ * The VFS already holds the BKL and the inode->i_sem semaphore when any of
+ * the xattr inode operations are called, so we are guaranteed that only one
+ * processes accesses extended attributes of an inode at any time.
+ *
+ * For writing we also grab the ext2_xattr_sem semaphore. This ensures that
+ * only a single process is modifying an extended attribute block, even
+ * if the block is shared among inodes.
+ */
+
+#include <linux/buffer_head.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/mbcache.h>
+#include <linux/quotaops.h>
+#include <asm/semaphore.h>
+#include "ext2.h"
+#include "xattr.h"
+#include "acl.h"
+
+/* These symbols may be needed by a module. */
+EXPORT_SYMBOL(ext2_xattr_register);
+EXPORT_SYMBOL(ext2_xattr_unregister);
+EXPORT_SYMBOL(ext2_xattr_get);
+EXPORT_SYMBOL(ext2_xattr_list);
+EXPORT_SYMBOL(ext2_xattr_set);
+
+#define HDR(bh) ((struct ext2_xattr_header *)((bh)->b_data))
+#define ENTRY(ptr) ((struct ext2_xattr_entry *)(ptr))
+#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1)
+#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
+
+#ifdef EXT2_XATTR_DEBUG
+# define ea_idebug(inode, f...) do { \
+		printk(KERN_DEBUG "inode %s:%ld: ", \
+			kdevname(inode->i_dev), inode->i_ino); \
+		printk(f); \
+		printk("\n"); \
+	} while (0)
+# define ea_bdebug(bh, f...) do { \
+		printk(KERN_DEBUG "block %s:%ld: ", \
+			kdevname(bh->b_dev), bh->b_blocknr); \
+		printk(f); \
+		printk("\n"); \
+	} while (0)
+#else
+# define ea_idebug(f...)
+# define ea_bdebug(f...)
+#endif
+
+static int ext2_xattr_set2(struct inode *, struct buffer_head *,
+			   struct ext2_xattr_header *);
+
+static int ext2_xattr_cache_insert(struct buffer_head *);
+static struct buffer_head *ext2_xattr_cache_find(struct inode *,
+						 struct ext2_xattr_header *);
+static void ext2_xattr_cache_remove(struct buffer_head *);
+static void ext2_xattr_rehash(struct ext2_xattr_header *,
+			      struct ext2_xattr_entry *);
+
+static struct mb_cache *ext2_xattr_cache;
+
+/*
+ * If a file system does not share extended attributes among inodes,
+ * we should not need the ext2_xattr_sem semaphore. However, the
+ * filesystem may still contain shared blocks, so we always take
+ * the lock.
+ */
+
+static DECLARE_MUTEX(ext2_xattr_sem);
+static struct ext2_xattr_handler *ext2_xattr_handlers[EXT2_XATTR_INDEX_MAX];
+static rwlock_t ext2_handler_lock = RW_LOCK_UNLOCKED;
+
+int
+ext2_xattr_register(int name_index, struct ext2_xattr_handler *handler)
+{
+	int error = -EINVAL;
+
+	if (name_index > 0 && name_index <= EXT2_XATTR_INDEX_MAX) {
+		write_lock(&ext2_handler_lock);
+		if (!ext2_xattr_handlers[name_index-1]) {
+			ext2_xattr_handlers[name_index-1] = handler;
+			error = 0;
+		}
+		write_unlock(&ext2_handler_lock);
+	}
+	return error;
+}
+
+void
+ext2_xattr_unregister(int name_index, struct ext2_xattr_handler *handler)
+{
+	if (name_index > 0 || name_index <= EXT2_XATTR_INDEX_MAX) {
+		write_lock(&ext2_handler_lock);
+		ext2_xattr_handlers[name_index-1] = NULL;
+		write_unlock(&ext2_handler_lock);
+	}
+}
+
+static inline const char *
+strcmp_prefix(const char *a, const char *a_prefix)
+{
+	while (*a_prefix && *a == *a_prefix) {
+		a++;
+		a_prefix++;
+	}
+	return *a_prefix ? NULL : a;
+}
+
+/*
+ * Decode the extended attribute name, and translate it into
+ * the name_index and name suffix.
+ */
+static struct ext2_xattr_handler *
+ext2_xattr_resolve_name(const char **name)
+{
+	struct ext2_xattr_handler *handler = NULL;
+	int i;
+
+	if (!*name)
+		return NULL;
+	read_lock(&ext2_handler_lock);
+	for (i=0; i<EXT2_XATTR_INDEX_MAX; i++) {
+		if (ext2_xattr_handlers[i]) {
+			const char *n = strcmp_prefix(*name,
+				ext2_xattr_handlers[i]->prefix);
+			if (n) {
+				handler = ext2_xattr_handlers[i];
+				*name = n;
+				break;
+			}
+		}
+	}
+	read_unlock(&ext2_handler_lock);
+	return handler;
+}
+
+static inline struct ext2_xattr_handler *
+ext2_xattr_handler(int name_index)
+{
+	struct ext2_xattr_handler *handler = NULL;
+	if (name_index > 0 && name_index <= EXT2_XATTR_INDEX_MAX) {
+		read_lock(&ext2_handler_lock);
+		handler = ext2_xattr_handlers[name_index-1];
+		read_unlock(&ext2_handler_lock);
+	}
+	return handler;
+}
+
+/*
+ * Inode operation getxattr()
+ *
+ * dentry->d_inode->i_sem down
+ * BKL held [before 2.5.x]
+ */
+ssize_t
+ext2_getxattr(struct dentry *dentry, const char *name,
+	      void *buffer, size_t size)
+{
+	struct ext2_xattr_handler *handler;
+	struct inode *inode = dentry->d_inode;
+
+	handler = ext2_xattr_resolve_name(&name);
+	if (!handler)
+		return -EOPNOTSUPP;
+	return handler->get(inode, name, buffer, size);
+}
+
+/*
+ * Inode operation listxattr()
+ *
+ * dentry->d_inode->i_sem down
+ * BKL held [before 2.5.x]
+ */
+ssize_t
+ext2_listxattr(struct dentry *dentry, char *buffer, size_t size)
+{
+	return ext2_xattr_list(dentry->d_inode, buffer, size);
+}
+
+/*
+ * Inode operation setxattr()
+ *
+ * dentry->d_inode->i_sem down
+ * BKL held [before 2.5.x]
+ */
+int
+ext2_setxattr(struct dentry *dentry, const char *name,
+	      void *value, size_t size, int flags)
+{
+	struct ext2_xattr_handler *handler;
+	struct inode *inode = dentry->d_inode;
+
+	if (size == 0)
+		value = "";  /* empty EA, do not remove */
+	handler = ext2_xattr_resolve_name(&name);
+	if (!handler)
+		return -EOPNOTSUPP;
+	return handler->set(inode, name, value, size, flags);
+}
+
+/*
+ * Inode operation removexattr()
+ *
+ * dentry->d_inode->i_sem down
+ * BKL held [before 2.5.x]
+ */
+int
+ext2_removexattr(struct dentry *dentry, const char *name)
+{
+	struct ext2_xattr_handler *handler;
+	struct inode *inode = dentry->d_inode;
+
+	handler = ext2_xattr_resolve_name(&name);
+	if (!handler)
+		return -EOPNOTSUPP;
+	return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
+}
+
+/*
+ * ext2_xattr_get()
+ *
+ * Copy an extended attribute into the buffer
+ * provided, or compute the buffer size required.
+ * Buffer is NULL to compute the size of the buffer required.
+ *
+ * Returns a negative error number on failure, or the number of bytes
+ * used / required on success.
+ */
+int
+ext2_xattr_get(struct inode *inode, int name_index, const char *name,
+	       void *buffer, size_t buffer_size)
+{
+	struct buffer_head *bh = NULL;
+	struct ext2_xattr_entry *entry;
+	unsigned int size;
+	char *end;
+	int name_len, error;
+
+	ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
+		  name_index, name, buffer, (long)buffer_size);
+
+	if (name == NULL)
+		return -EINVAL;
+	if (!EXT2_I(inode)->i_file_acl)
+		return -ENODATA;
+	ea_idebug(inode, "reading block %d", EXT2_I(inode)->i_file_acl);
+	bh = sb_bread(inode->i_sb, EXT2_I(inode)->i_file_acl);
+	if (!bh)
+		return -EIO;
+	ea_bdebug(bh, "b_count=%d, refcount=%d",
+		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
+	end = bh->b_data + bh->b_size;
+	if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
+	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
+bad_block:	ext2_error(inode->i_sb, "ext2_xattr_get",
+			"inode %ld: bad block %d", inode->i_ino,
+			EXT2_I(inode)->i_file_acl);
+		error = -EIO;
+		goto cleanup;
+	}
+	/* find named attribute */
+	name_len = strlen(name);
+
+	error = -ERANGE;
+	if (name_len > 255)
+		goto cleanup;
+	entry = FIRST_ENTRY(bh);
+	while (!IS_LAST_ENTRY(entry)) {
+		struct ext2_xattr_entry *next =
+			EXT2_XATTR_NEXT(entry);
+		if ((char *)next >= end)
+			goto bad_block;
+		if (name_index == entry->e_name_index &&
+		    name_len == entry->e_name_len &&
+		    memcmp(name, entry->e_name, name_len) == 0)
+			goto found;
+		entry = next;
+	}
+	/* Check the remaining name entries */
+	while (!IS_LAST_ENTRY(entry)) {
+		struct ext2_xattr_entry *next =
+			EXT2_XATTR_NEXT(entry);
+		if ((char *)next >= end)
+			goto bad_block;
+		entry = next;
+	}
+	if (ext2_xattr_cache_insert(bh))
+		ea_idebug(inode, "cache insert failed");
+	error = -ENODATA;
+	goto cleanup;
+found:
+	/* check the buffer size */
+	if (entry->e_value_block != 0)
+		goto bad_block;
+	size = le32_to_cpu(entry->e_value_size);
+	if (size > inode->i_sb->s_blocksize ||
+	    le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize)
+		goto bad_block;
+
+	if (ext2_xattr_cache_insert(bh))
+		ea_idebug(inode, "cache insert failed");
+	if (buffer) {
+		error = -ERANGE;
+		if (size > buffer_size)
+			goto cleanup;
+		/* return value of attribute */
+		memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
+			size);
+	}
+	error = size;
+
+cleanup:
+	brelse(bh);
+
+	return error;
+}
+
+/*
+ * ext2_xattr_list()
+ *
+ * Copy a list of attribute names into the buffer
+ * provided, or compute the buffer size required.
+ * Buffer is NULL to compute the size of the buffer required.
+ *
+ * Returns a negative error number on failure, or the number of bytes
+ * used / required on success.
+ */
+int
+ext2_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
+{
+	struct buffer_head *bh = NULL;
+	struct ext2_xattr_entry *entry;
+	unsigned int size = 0;
+	char *buf, *end;
+	int error;
+
+	ea_idebug(inode, "buffer=%p, buffer_size=%ld",
+		  buffer, (long)buffer_size);
+
+	if (!EXT2_I(inode)->i_file_acl)
+		return 0;
+	ea_idebug(inode, "reading block %d", EXT2_I(inode)->i_file_acl);
+	bh = sb_bread(inode->i_sb, EXT2_I(inode)->i_file_acl);
+	if (!bh)
+		return -EIO;
+	ea_bdebug(bh, "b_count=%d, refcount=%d",
+		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
+	end = bh->b_data + bh->b_size;
+	if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
+	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
+bad_block:	ext2_error(inode->i_sb, "ext2_xattr_list",
+			"inode %ld: bad block %d", inode->i_ino,
+			EXT2_I(inode)->i_file_acl);
+		error = -EIO;
+		goto cleanup;
+	}
+	/* compute the size required for the list of attribute names */
+	for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
+	     entry = EXT2_XATTR_NEXT(entry)) {
+		struct ext2_xattr_handler *handler;
+		struct ext2_xattr_entry *next =
+			EXT2_XATTR_NEXT(entry);
+		if ((char *)next >= end)
+			goto bad_block;
+
+		handler = ext2_xattr_handler(entry->e_name_index);
+		if (handler) {
+			size += handler->list(NULL, inode, entry->e_name,
+					      entry->e_name_len) + 1;
+		}
+	}
+
+	if (ext2_xattr_cache_insert(bh))
+		ea_idebug(inode, "cache insert failed");
+	if (!buffer) {
+		error = size;
+		goto cleanup;
+	} else {
+		error = -ERANGE;
+		if (size > buffer_size)
+			goto cleanup;
+	}
+
+	/* list the attribute names */
+	buf = buffer;
+	for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
+	     entry = EXT2_XATTR_NEXT(entry)) {
+		struct ext2_xattr_handler *handler;
+		
+		handler = ext2_xattr_handler(entry->e_name_index);
+		if (handler) {
+			buf += handler->list(buf, inode, entry->e_name,
+					     entry->e_name_len);
+			*buf++ = '\0';
+		}
+	}
+	error = size;
+
+cleanup:
+	brelse(bh);
+
+	return error;
+}
+
+/*
+ * If the EXT2_FEATURE_COMPAT_EXT_ATTR feature of this file system is
+ * not set, set it.
+ */
+static void ext2_xattr_update_super_block(struct super_block *sb)
+{
+	if (EXT2_HAS_COMPAT_FEATURE(sb, EXT2_FEATURE_COMPAT_EXT_ATTR))
+		return;
+
+	lock_super(sb);
+	EXT2_SB(sb)->s_es->s_feature_compat |=
+		cpu_to_le32(EXT2_FEATURE_COMPAT_EXT_ATTR);
+	sb->s_dirt = 1;
+	mark_buffer_dirty(EXT2_SB(sb)->s_sbh);
+	unlock_super(sb);
+}
+
+/*
+ * ext2_xattr_set()
+ *
+ * Create, replace or remove an extended attribute for this inode. Buffer
+ * is NULL to remove an existing extended attribute, and non-NULL to
+ * either replace an existing extended attribute, or create a new extended
+ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
+ * specify that an extended attribute must exist and must not exist
+ * previous to the call, respectively.
+ *
+ * Returns 0, or a negative error number on failure.
+ */
+int
+ext2_xattr_set(struct inode *inode, int name_index, const char *name,
+	       const void *value, size_t value_len, int flags)
+{
+	struct super_block *sb = inode->i_sb;
+	struct buffer_head *bh = NULL;
+	struct ext2_xattr_header *header = NULL;
+	struct ext2_xattr_entry *here, *last;
+	unsigned int name_len;
+	int min_offs = sb->s_blocksize, not_found = 1, free, error;
+	char *end;
+	
+	/*
+	 * header -- Points either into bh, or to a temporarily
+	 *           allocated buffer.
+	 * here -- The named entry found, or the place for inserting, within
+	 *         the block pointed to by header.
+	 * last -- Points right after the last named entry within the block
+	 *         pointed to by header.
+	 * min_offs -- The offset of the first value (values are aligned
+	 *             towards the end of the block).
+	 * end -- Points right after the block pointed to by header.
+	 */
+	
+	ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
+		  name_index, name, value, (long)value_len);
+
+	if (IS_RDONLY(inode))
+		return -EROFS;
+	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+		return -EPERM;
+	if (value == NULL)
+		value_len = 0;
+	if (name == NULL)
+		return -EINVAL;
+	name_len = strlen(name);
+	if (name_len > 255 || value_len > sb->s_blocksize)
+		return -ERANGE;
+	down(&ext2_xattr_sem);
+
+	if (EXT2_I(inode)->i_file_acl) {
+		/* The inode already has an extended attribute block. */
+		bh = sb_bread(sb, EXT2_I(inode)->i_file_acl);
+		error = -EIO;
+		if (!bh)
+			goto cleanup;
+		ea_bdebug(bh, "b_count=%d, refcount=%d",
+			atomic_read(&(bh->b_count)),
+			le32_to_cpu(HDR(bh)->h_refcount));
+		header = HDR(bh);
+		end = bh->b_data + bh->b_size;
+		if (header->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
+		    header->h_blocks != cpu_to_le32(1)) {
+bad_block:		ext2_error(sb, "ext2_xattr_set",
+				"inode %ld: bad block %d", inode->i_ino, 
+				   EXT2_I(inode)->i_file_acl);
+			error = -EIO;
+			goto cleanup;
+		}
+		/* Find the named attribute. */
+		here = FIRST_ENTRY(bh);
+		while (!IS_LAST_ENTRY(here)) {
+			struct ext2_xattr_entry *next = EXT2_XATTR_NEXT(here);
+			if ((char *)next >= end)
+				goto bad_block;
+			if (!here->e_value_block && here->e_value_size) {
+				int offs = le16_to_cpu(here->e_value_offs);
+				if (offs < min_offs)
+					min_offs = offs;
+			}
+			not_found = name_index - here->e_name_index;
+			if (!not_found)
+				not_found = name_len - here->e_name_len;
+			if (!not_found)
+				not_found = memcmp(name, here->e_name,name_len);
+			if (not_found <= 0)
+				break;
+			here = next;
+		}
+		last = here;
+		/* We still need to compute min_offs and last. */
+		while (!IS_LAST_ENTRY(last)) {
+			struct ext2_xattr_entry *next = EXT2_XATTR_NEXT(last);
+			if ((char *)next >= end)
+				goto bad_block;
+			if (!last->e_value_block && last->e_value_size) {
+				int offs = le16_to_cpu(last->e_value_offs);
+				if (offs < min_offs)
+					min_offs = offs;
+			}
+			last = next;
+		}
+
+		/* Check whether we have enough space left. */
+		free = min_offs - ((char*)last - (char*)header) - sizeof(__u32);
+	} else {
+		/* We will use a new extended attribute block. */
+		free = sb->s_blocksize -
+			sizeof(struct ext2_xattr_header) - sizeof(__u32);
+		here = last = NULL;  /* avoid gcc uninitialized warning. */
+	}
+
+	if (not_found) {
+		/* Request to remove a nonexistent attribute? */
+		error = -ENODATA;
+		if (flags & XATTR_REPLACE)
+			goto cleanup;
+		error = 0;
+		if (value == NULL)
+			goto cleanup;
+		else
+			free -= EXT2_XATTR_LEN(name_len);
+	} else {
+		/* Request to create an existing attribute? */
+		error = -EEXIST;
+		if (flags & XATTR_CREATE)
+			goto cleanup;
+		if (!here->e_value_block && here->e_value_size) {
+			unsigned int size = le32_to_cpu(here->e_value_size);
+
+			if (le16_to_cpu(here->e_value_offs) + size > 
+			    sb->s_blocksize || size > sb->s_blocksize)
+				goto bad_block;
+			free += EXT2_XATTR_SIZE(size);
+		}
+	}
+	free -= EXT2_XATTR_SIZE(value_len);
+	error = -ENOSPC;
+	if (free < 0)
+		goto cleanup;
+
+	/* Here we know that we can set the new attribute. */
+
+	if (header) {
+		if (header->h_refcount == cpu_to_le32(1)) {
+			ea_bdebug(bh, "modifying in-place");
+			ext2_xattr_cache_remove(bh);
+		} else {
+			int offset;
+
+			ea_bdebug(bh, "cloning");
+			header = kmalloc(bh->b_size, GFP_KERNEL);
+			error = -ENOMEM;
+			if (header == NULL)
+				goto cleanup;
+			memcpy(header, HDR(bh), bh->b_size);
+			header->h_refcount = cpu_to_le32(1);
+			offset = (char *)header - bh->b_data;
+			here = ENTRY((char *)here + offset);
+			last = ENTRY((char *)last + offset);
+		}
+	} else {
+		/* Allocate a buffer where we construct the new block. */
+		header = kmalloc(sb->s_blocksize, GFP_KERNEL);
+		error = -ENOMEM;
+		if (header == NULL)
+			goto cleanup;
+		memset(header, 0, sb->s_blocksize);
+		end = (char *)header + sb->s_blocksize;
+		header->h_magic = cpu_to_le32(EXT2_XATTR_MAGIC);
+		header->h_blocks = header->h_refcount = cpu_to_le32(1);
+		last = here = ENTRY(header+1);
+	}
+
+	if (not_found) {
+		/* Insert the new name. */
+		int size = EXT2_XATTR_LEN(name_len);
+		int rest = (char *)last - (char *)here;
+		memmove((char *)here + size, here, rest);
+		memset(here, 0, size);
+		here->e_name_index = name_index;
+		here->e_name_len = name_len;
+		memcpy(here->e_name, name, name_len);
+	} else {
+		/* Remove the old value. */
+		if (!here->e_value_block && here->e_value_size) {
+			char *first_val = (char *)header + min_offs;
+			int offs = le16_to_cpu(here->e_value_offs);
+			char *val = (char *)header + offs;
+			size_t size = EXT2_XATTR_SIZE(
+				le32_to_cpu(here->e_value_size));
+			memmove(first_val + size, first_val, val - first_val);
+			memset(first_val, 0, size);
+			here->e_value_offs = 0;
+			min_offs += size;
+
+			/* Adjust all value offsets. */
+			last = ENTRY(header+1);
+			while (!IS_LAST_ENTRY(last)) {
+				int o = le16_to_cpu(last->e_value_offs);
+				if (!last->e_value_block && o < offs)
+					last->e_value_offs =
+						cpu_to_le16(o + size);
+				last = EXT2_XATTR_NEXT(last);
+			}
+		}
+		if (value == NULL) {
+			/* Remove this attribute. */
+			if (EXT2_XATTR_NEXT(ENTRY(header+1)) == last) {
+				/* This block is now empty. */
+				error = ext2_xattr_set2(inode, bh, NULL);
+				goto cleanup;
+			} else {
+				/* Remove the old name. */
+				int size = EXT2_XATTR_LEN(name_len);
+				last = ENTRY((char *)last - size);
+				memmove(here, (char*)here + size,
+					(char*)last - (char*)here);
+				memset(last, 0, size);
+			}
+		}
+	}
+
+	if (value != NULL) {
+		/* Insert the new value. */
+		here->e_value_size = cpu_to_le32(value_len);
+		if (value_len) {
+			size_t size = EXT2_XATTR_SIZE(value_len);
+			char *val = (char *)header + min_offs - size;
+			here->e_value_offs =
+				cpu_to_le16((char *)val - (char *)header);
+			memset(val + size - EXT2_XATTR_PAD, 0,
+			       EXT2_XATTR_PAD); /* Clear the pad bytes. */
+			memcpy(val, value, value_len);
+		}
+	}
+	ext2_xattr_rehash(header, here);
+
+	error = ext2_xattr_set2(inode, bh, header);
+
+cleanup:
+	brelse(bh);
+	if (!(bh && header == HDR(bh)))
+		kfree(header);
+	up(&ext2_xattr_sem);
+
+	return error;
+}
+
+/*
+ * Second half of ext2_xattr_set(): Update the file system.
+ */
+static int
+ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
+		struct ext2_xattr_header *header)
+{
+	struct super_block *sb = inode->i_sb;
+	struct buffer_head *new_bh = NULL;
+	int error;
+
+	if (header) {
+		new_bh = ext2_xattr_cache_find(inode, header);
+		if (new_bh) {
+			/*
+			 * We found an identical block in the cache.
+			 * The old block will be released after updating
+			 * the inode.
+			 */
+			ea_bdebug(old_bh, "reusing block %ld",
+				new_bh->b_blocknr);
+			
+			error = -EDQUOT;
+			if (DQUOT_ALLOC_BLOCK(inode, 1))
+				goto cleanup;
+			
+			HDR(new_bh)->h_refcount = cpu_to_le32(
+				le32_to_cpu(HDR(new_bh)->h_refcount) + 1);
+			ea_bdebug(new_bh, "refcount now=%d",
+				le32_to_cpu(HDR(new_bh)->h_refcount));
+		} else if (old_bh && header == HDR(old_bh)) {
+			/* Keep this block. */
+			new_bh = old_bh;
+			ext2_xattr_cache_insert(new_bh);
+		} else {
+			/* We need to allocate a new block */
+			int goal = le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block) +
+				EXT2_I(inode)->i_block_group * EXT2_BLOCKS_PER_GROUP(sb);
+			int block = ext2_new_block(inode, goal, 0, 0, &error);
+			if (error)
+				goto cleanup;
+			ea_idebug(inode, "creating block %d", block);
+
+			new_bh = sb_getblk(sb, block);
+			if (!new_bh) {
+				ext2_free_blocks(inode, block, 1);
+				error = -EIO;
+				goto cleanup;
+			}
+			lock_buffer(new_bh);
+			memcpy(new_bh->b_data, header, new_bh->b_size);
+			set_buffer_uptodate(new_bh);
+			unlock_buffer(new_bh);
+			ext2_xattr_cache_insert(new_bh);
+			
+			ext2_xattr_update_super_block(sb);
+		}
+		mark_buffer_dirty(new_bh);
+		if (IS_SYNC(inode)) {
+			ll_rw_block(WRITE, 1, &new_bh);
+			wait_on_buffer(new_bh); 
+			error = -EIO;
+			if (buffer_req(new_bh) && !buffer_uptodate(new_bh))
+				goto cleanup;
+		}
+	}
+
+	/* Update the inode. */
+	EXT2_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
+	inode->i_ctime = CURRENT_TIME;
+	if (IS_SYNC(inode)) {
+		error = ext2_sync_inode (inode);
+		if (error)
+			goto cleanup;
+	} else
+		mark_inode_dirty(inode);
+
+	error = 0;
+	if (old_bh && old_bh != new_bh) {
+		/*
+		 * If there was an old block, and we are not still using it,
+		 * we now release the old block.
+		*/
+		unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount);
+
+		if (refcount == 1) {
+			/* Free the old block. */
+			ea_bdebug(old_bh, "freeing");
+			ext2_free_blocks(inode, old_bh->b_blocknr, 1);
+			/* We let our caller release old_bh, so we
+			 * need to duplicate the buffer before. */
+			get_bh(old_bh);
+			bforget(old_bh);
+		} else {
+			/* Decrement the refcount only. */
+			refcount--;
+			HDR(old_bh)->h_refcount = cpu_to_le32(refcount);
+			DQUOT_FREE_BLOCK(inode, 1);
+			mark_buffer_dirty(old_bh);
+			ea_bdebug(old_bh, "refcount now=%d", refcount);
+		}
+	}
+
+cleanup:
+	if (old_bh != new_bh)
+		brelse(new_bh);
+
+	return error;
+}
+
+/*
+ * ext2_xattr_delete_inode()
+ *
+ * Free extended attribute resources associated with this inode. This
+ * is called immediately before an inode is freed.
+ */
+void
+ext2_xattr_delete_inode(struct inode *inode)
+{
+	struct buffer_head *bh;
+
+	if (!EXT2_I(inode)->i_file_acl)
+		return;
+	down(&ext2_xattr_sem);
+
+	bh = sb_bread(inode->i_sb, EXT2_I(inode)->i_file_acl);
+	if (!bh) {
+		ext2_error(inode->i_sb, "ext2_xattr_delete_inode",
+			"inode %ld: block %d read error", inode->i_ino,
+			EXT2_I(inode)->i_file_acl);
+		goto cleanup;
+	}
+	ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count)));
+	if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
+	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
+		ext2_error(inode->i_sb, "ext2_xattr_delete_inode",
+			"inode %ld: bad block %d", inode->i_ino,
+			EXT2_I(inode)->i_file_acl);
+		goto cleanup;
+	}
+	ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1);
+	if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
+		ext2_xattr_cache_remove(bh);
+		ext2_free_blocks(inode, EXT2_I(inode)->i_file_acl, 1);
+		bforget(bh);
+		bh = NULL;
+	} else {
+		HDR(bh)->h_refcount = cpu_to_le32(
+			le32_to_cpu(HDR(bh)->h_refcount) - 1);
+		mark_buffer_dirty(bh);
+		if (IS_SYNC(inode)) {
+			ll_rw_block(WRITE, 1, &bh);
+			wait_on_buffer(bh);
+		}
+		DQUOT_FREE_BLOCK(inode, 1);
+	}
+	EXT2_I(inode)->i_file_acl = 0;
+
+cleanup:
+	brelse(bh);
+	up(&ext2_xattr_sem);
+}
+
+/*
+ * ext2_xattr_put_super()
+ *
+ * This is called when a file system is unmounted.
+ */
+void
+ext2_xattr_put_super(struct super_block *sb)
+{
+	mb_cache_shrink(ext2_xattr_cache, sb->s_bdev);
+}
+
+
+/*
+ * ext2_xattr_cache_insert()
+ *
+ * Create a new entry in the extended attribute cache, and insert
+ * it unless such an entry is already in the cache.
+ *
+ * Returns 0, or a negative error number on failure.
+ */
+static int
+ext2_xattr_cache_insert(struct buffer_head *bh)
+{
+	__u32 hash = le32_to_cpu(HDR(bh)->h_hash);
+	struct mb_cache_entry *ce;
+	int error;
+
+	ce = mb_cache_entry_alloc(ext2_xattr_cache);
+	if (!ce)
+		return -ENOMEM;
+	error = mb_cache_entry_insert(ce, bh->b_bdev, bh->b_blocknr, &hash);
+	if (error) {
+		mb_cache_entry_free(ce);
+		if (error == -EBUSY) {
+			ea_bdebug(bh, "already in cache (%d cache entries)",
+				atomic_read(&ext2_xattr_cache->c_entry_count));
+			error = 0;
+		}
+	} else {
+		ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash,
+			  atomic_read(&ext2_xattr_cache->c_entry_count));
+		mb_cache_entry_release(ce);
+	}
+	return error;
+}
+
+/*
+ * ext2_xattr_cmp()
+ *
+ * Compare two extended attribute blocks for equality.
+ *
+ * Returns 0 if the blocks are equal, 1 if they differ, and
+ * a negative error number on errors.
+ */
+static int
+ext2_xattr_cmp(struct ext2_xattr_header *header1,
+	       struct ext2_xattr_header *header2)
+{
+	struct ext2_xattr_entry *entry1, *entry2;
+
+	entry1 = ENTRY(header1+1);
+	entry2 = ENTRY(header2+1);
+	while (!IS_LAST_ENTRY(entry1)) {
+		if (IS_LAST_ENTRY(entry2))
+			return 1;
+		if (entry1->e_hash != entry2->e_hash ||
+		    entry1->e_name_len != entry2->e_name_len ||
+		    entry1->e_value_size != entry2->e_value_size ||
+		    memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
+			return 1;
+		if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
+			return -EIO;
+		if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
+			   (char *)header2 + le16_to_cpu(entry2->e_value_offs),
+			   le32_to_cpu(entry1->e_value_size)))
+			return 1;
+
+		entry1 = EXT2_XATTR_NEXT(entry1);
+		entry2 = EXT2_XATTR_NEXT(entry2);
+	}
+	if (!IS_LAST_ENTRY(entry2))
+		return 1;
+	return 0;
+}
+
+/*
+ * ext2_xattr_cache_find()
+ *
+ * Find an identical extended attribute block.
+ *
+ * Returns a pointer to the block found, or NULL if such a block was
+ * not found or an error occurred.
+ */
+static struct buffer_head *
+ext2_xattr_cache_find(struct inode *inode, struct ext2_xattr_header *header)
+{
+	__u32 hash = le32_to_cpu(header->h_hash);
+	struct mb_cache_entry *ce;
+
+	if (!header->h_hash)
+		return NULL;  /* never share */
+	ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
+	ce = mb_cache_entry_find_first(ext2_xattr_cache, 0, inode->i_bdev, hash);
+	while (ce) {
+		struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block);
+
+		if (!bh) {
+			ext2_error(inode->i_sb, "ext2_xattr_cache_find",
+				"inode %ld: block %ld read error",
+				inode->i_ino, (unsigned long) ce->e_block);
+		} else if (le32_to_cpu(HDR(bh)->h_refcount) >
+			   EXT2_XATTR_REFCOUNT_MAX) {
+			ea_idebug(inode, "block %ld refcount %d>%d",
+				  (unsigned long) ce->e_block,
+				  le32_to_cpu(HDR(bh)->h_refcount),
+				  EXT2_XATTR_REFCOUNT_MAX);
+		} else if (!ext2_xattr_cmp(header, HDR(bh))) {
+			ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count)));
+			mb_cache_entry_release(ce);
+			return bh;
+		}
+		brelse(bh);
+		ce = mb_cache_entry_find_next(ce, 0, inode->i_bdev, hash);
+	}
+	return NULL;
+}
+
+/*
+ * ext2_xattr_cache_remove()
+ *
+ * Remove the cache entry of a block from the cache. Called when a
+ * block becomes invalid.
+ */
+static void
+ext2_xattr_cache_remove(struct buffer_head *bh)
+{
+	struct mb_cache_entry *ce;
+
+	ce = mb_cache_entry_get(ext2_xattr_cache, bh->b_bdev, bh->b_blocknr);
+	if (ce) {
+		ea_bdebug(bh, "removing (%d cache entries remaining)",
+			  atomic_read(&ext2_xattr_cache->c_entry_count)-1);
+		mb_cache_entry_free(ce);
+	} else 
+		ea_bdebug(bh, "no cache entry");
+}
+
+#define NAME_HASH_SHIFT 5
+#define VALUE_HASH_SHIFT 16
+
+/*
+ * ext2_xattr_hash_entry()
+ *
+ * Compute the hash of an extended attribute.
+ */
+static inline void ext2_xattr_hash_entry(struct ext2_xattr_header *header,
+					 struct ext2_xattr_entry *entry)
+{
+	__u32 hash = 0;
+	char *name = entry->e_name;
+	int n;
+
+	for (n=0; n < entry->e_name_len; n++) {
+		hash = (hash << NAME_HASH_SHIFT) ^
+		       (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
+		       *name++;
+	}
+
+	if (entry->e_value_block == 0 && entry->e_value_size != 0) {
+		__u32 *value = (__u32 *)((char *)header +
+			le16_to_cpu(entry->e_value_offs));
+		for (n = (le32_to_cpu(entry->e_value_size) +
+		     EXT2_XATTR_ROUND) >> EXT2_XATTR_PAD_BITS; n; n--) {
+			hash = (hash << VALUE_HASH_SHIFT) ^
+			       (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
+			       le32_to_cpu(*value++);
+		}
+	}
+	entry->e_hash = cpu_to_le32(hash);
+}
+
+#undef NAME_HASH_SHIFT
+#undef VALUE_HASH_SHIFT
+
+#define BLOCK_HASH_SHIFT 16
+
+/*
+ * ext2_xattr_rehash()
+ *
+ * Re-compute the extended attribute hash value after an entry has changed.
+ */
+static void ext2_xattr_rehash(struct ext2_xattr_header *header,
+			      struct ext2_xattr_entry *entry)
+{
+	struct ext2_xattr_entry *here;
+	__u32 hash = 0;
+	
+	ext2_xattr_hash_entry(header, entry);
+	here = ENTRY(header+1);
+	while (!IS_LAST_ENTRY(here)) {
+		if (!here->e_hash) {
+			/* Block is not shared if an entry's hash value == 0 */
+			hash = 0;
+			break;
+		}
+		hash = (hash << BLOCK_HASH_SHIFT) ^
+		       (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^
+		       le32_to_cpu(here->e_hash);
+		here = EXT2_XATTR_NEXT(here);
+	}
+	header->h_hash = cpu_to_le32(hash);
+}
+
+#undef BLOCK_HASH_SHIFT
+
+int __init
+init_ext2_xattr(void)
+{
+	int	err;
+	
+	err = ext2_xattr_register(EXT2_XATTR_INDEX_USER, &ext2_xattr_user_handler);
+	if (err)
+		return err;
+#ifdef CONFIG_EXT2_FS_POSIX_ACL
+	err = init_ext2_acl();
+	if (err)
+		goto out;
+#endif
+	ext2_xattr_cache = mb_cache_create("ext2_xattr", NULL,
+		sizeof(struct mb_cache_entry) +
+		sizeof(struct mb_cache_entry_index), 1, 6);
+	if (!ext2_xattr_cache) {
+		err = -ENOMEM;
+		goto out1;
+	}
+	return 0;
+out1:
+#ifdef CONFIG_EXT2_FS_POSIX_ACL
+	exit_ext2_acl();
+out:
+#endif
+	ext2_xattr_unregister(EXT2_XATTR_INDEX_USER,
+			      &ext2_xattr_user_handler);
+	return err;
+}
+
+void
+exit_ext2_xattr(void)
+{
+	mb_cache_destroy(ext2_xattr_cache);
+#ifdef CONFIG_EXT2_FS_POSIX_ACL
+	exit_ext2_acl();
+#endif
+	ext2_xattr_unregister(EXT2_XATTR_INDEX_USER, &ext2_xattr_user_handler);
+}
diff -Nru a/fs/ext2/xattr.h b/fs/ext2/xattr.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/ext2/xattr.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,135 @@
+/*
+  File: linux/ext2_xattr.h
+
+  On-disk format of extended attributes for the ext2 filesystem.
+
+  (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
+*/
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/xattr.h>
+
+/* Magic value in attribute blocks */
+#define EXT2_XATTR_MAGIC		0xEA020000
+
+/* Maximum number of references to one attribute block */
+#define EXT2_XATTR_REFCOUNT_MAX		1024
+
+/* Name indexes */
+#define EXT2_XATTR_INDEX_MAX			10
+#define EXT2_XATTR_INDEX_USER			1
+#define EXT2_XATTR_INDEX_POSIX_ACL_ACCESS	2
+#define EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT	3
+
+struct ext2_xattr_header {
+	__u32	h_magic;	/* magic number for identification */
+	__u32	h_refcount;	/* reference count */
+	__u32	h_blocks;	/* number of disk blocks used */
+	__u32	h_hash;		/* hash value of all attributes */
+	__u32	h_reserved[4];	/* zero right now */
+};
+
+struct ext2_xattr_entry {
+	__u8	e_name_len;	/* length of name */
+	__u8	e_name_index;	/* attribute name index */
+	__u16	e_value_offs;	/* offset in disk block of value */
+	__u32	e_value_block;	/* disk block attribute is stored on (n/i) */
+	__u32	e_value_size;	/* size of attribute value */
+	__u32	e_hash;		/* hash value of name and value */
+	char	e_name[0];	/* attribute name */
+};
+
+#define EXT2_XATTR_PAD_BITS		2
+#define EXT2_XATTR_PAD		(1<<EXT2_XATTR_PAD_BITS)
+#define EXT2_XATTR_ROUND		(EXT2_XATTR_PAD-1)
+#define EXT2_XATTR_LEN(name_len) \
+	(((name_len) + EXT2_XATTR_ROUND + \
+	sizeof(struct ext2_xattr_entry)) & ~EXT2_XATTR_ROUND)
+#define EXT2_XATTR_NEXT(entry) \
+	( (struct ext2_xattr_entry *)( \
+	  (char *)(entry) + EXT2_XATTR_LEN((entry)->e_name_len)) )
+#define EXT2_XATTR_SIZE(size) \
+	(((size) + EXT2_XATTR_ROUND) & ~EXT2_XATTR_ROUND)
+
+# ifdef CONFIG_EXT2_FS_XATTR
+
+struct ext2_xattr_handler {
+	char *prefix;
+	size_t (*list)(char *list, struct inode *inode, const char *name,
+		       int name_len);
+	int (*get)(struct inode *inode, const char *name, void *buffer,
+		   size_t size);
+	int (*set)(struct inode *inode, const char *name, const void *buffer,
+		   size_t size, int flags);
+};
+
+extern int ext2_xattr_register(int, struct ext2_xattr_handler *);
+extern void ext2_xattr_unregister(int, struct ext2_xattr_handler *);
+
+extern int ext2_setxattr(struct dentry *, const char *, void *, size_t, int);
+extern ssize_t ext2_getxattr(struct dentry *, const char *, void *, size_t);
+extern ssize_t ext2_listxattr(struct dentry *, char *, size_t);
+extern int ext2_removexattr(struct dentry *, const char *);
+
+extern int ext2_xattr_get(struct inode *, int, const char *, void *, size_t);
+extern int ext2_xattr_list(struct inode *, char *, size_t);
+extern int ext2_xattr_set(struct inode *, int, const char *, const void *, size_t, int);
+
+extern void ext2_xattr_delete_inode(struct inode *);
+extern void ext2_xattr_put_super(struct super_block *);
+
+extern int init_ext2_xattr(void);
+extern void exit_ext2_xattr(void);
+
+# else  /* CONFIG_EXT2_FS_XATTR */
+#  define ext2_setxattr		NULL
+#  define ext2_getxattr		NULL
+#  define ext2_listxattr	NULL
+#  define ext2_removexattr	NULL
+
+static inline int
+ext2_xattr_get(struct inode *inode, int name_index,
+	       const char *name, void *buffer, size_t size)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int
+ext2_xattr_list(struct inode *inode, char *buffer, size_t size)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int
+ext2_xattr_set(struct inode *inode, int name_index, const char *name,
+	       const void *value, size_t size, int flags)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline void
+ext2_xattr_delete_inode(struct inode *inode)
+{
+}
+
+static inline void
+ext2_xattr_put_super(struct super_block *sb)
+{
+}
+
+static inline int
+init_ext2_xattr(void)
+{
+	return 0;
+}
+
+static inline void
+exit_ext2_xattr(void)
+{
+}
+
+# endif  /* CONFIG_EXT2_FS_XATTR */
+
+extern struct ext2_xattr_handler ext2_xattr_user_handler;
+
diff -Nru a/fs/ext2/xattr_user.c b/fs/ext2/xattr_user.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/ext2/xattr_user.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,102 @@
+/*
+ * linux/fs/ext2/xattr_user.c
+ * Handler for extended user attributes.
+ *
+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include "ext2.h"
+#include "xattr.h"
+
+#ifdef CONFIG_EXT2_FS_POSIX_ACL
+# include "acl.h"
+#endif
+
+#define XATTR_USER_PREFIX "user."
+
+static size_t
+ext2_xattr_user_list(char *list, struct inode *inode,
+		     const char *name, int name_len)
+{
+	const int prefix_len = sizeof(XATTR_USER_PREFIX)-1;
+
+	if (!test_opt(inode->i_sb, XATTR_USER))
+		return 0;
+
+	if (list) {
+		memcpy(list, XATTR_USER_PREFIX, prefix_len);
+		memcpy(list+prefix_len, name, name_len);
+	}
+	return prefix_len + name_len;
+}
+
+static int
+ext2_xattr_user_get(struct inode *inode, const char *name,
+		    void *buffer, size_t size)
+{
+	int error;
+
+	if (strcmp(name, "") == 0)
+		return -EINVAL;
+	if (!test_opt(inode->i_sb, XATTR_USER))
+		return -EOPNOTSUPP;
+#ifdef CONFIG_EXT2_FS_POSIX_ACL
+	error = ext2_permission_locked(inode, MAY_READ);
+#else
+	error = permission(inode, MAY_READ);
+#endif
+	if (error)
+		return error;
+
+	return ext2_xattr_get(inode, EXT2_XATTR_INDEX_USER, name,
+			      buffer, size);
+}
+
+static int
+ext2_xattr_user_set(struct inode *inode, const char *name,
+		    const void *value, size_t size, int flags)
+{
+	int error;
+
+	if (strcmp(name, "") == 0)
+		return -EINVAL;
+	if (!test_opt(inode->i_sb, XATTR_USER))
+		return -EOPNOTSUPP;
+	if ( !S_ISREG(inode->i_mode) &&
+	    (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
+		return -EPERM;
+#ifdef CONFIG_EXT2_FS_POSIX_ACL
+	error = ext2_permission_locked(inode, MAY_WRITE);
+#else
+	error = permission(inode, MAY_WRITE);
+#endif
+	if (error)
+		return error;
+  
+	return ext2_xattr_set(inode, EXT2_XATTR_INDEX_USER, name,
+			      value, size, flags);
+}
+
+struct ext2_xattr_handler ext2_xattr_user_handler = {
+	prefix:	XATTR_USER_PREFIX,
+	list:	ext2_xattr_user_list,
+	get:	ext2_xattr_user_get,
+	set:	ext2_xattr_user_set,
+};
+
+int __init
+init_ext2_xattr_user(void)
+{
+	return ext2_xattr_register(EXT2_XATTR_INDEX_USER,
+				   &ext2_xattr_user_handler);
+}
+
+void
+exit_ext2_xattr_user(void)
+{
+	ext2_xattr_unregister(EXT2_XATTR_INDEX_USER,
+			      &ext2_xattr_user_handler);
+}
diff -Nru a/fs/ext3/Makefile b/fs/ext3/Makefile
--- a/fs/ext3/Makefile	Mon Nov  4 14:31:00 2002
+++ b/fs/ext3/Makefile	Mon Nov  4 14:31:00 2002
@@ -7,4 +7,14 @@
 ext3-objs    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
 		ioctl.o namei.o super.o symlink.o hash.o
 
+export-objs += xattr.o
+
+ifeq ($(CONFIG_EXT3_FS_XATTR),y)
+ext3-objs += xattr.o xattr_user.o
+endif
+
+ifeq ($(CONFIG_EXT3_FS_POSIX_ACL),y)
+ext3-objs += acl.o
+endif
+
 include $(TOPDIR)/Rules.make
diff -Nru a/fs/ext3/acl.c b/fs/ext3/acl.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/ext3/acl.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,590 @@
+/*
+ * linux/fs/ext3/acl.c
+ *
+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/ext3_jbd.h>
+#include <linux/ext3_fs.h>
+#include "xattr.h"
+#include "acl.h"
+
+/*
+ * Convert from filesystem to in-memory representation.
+ */
+static struct posix_acl *
+ext3_acl_from_disk(const void *value, size_t size)
+{
+	const char *end = (char *)value + size;
+	int n, count;
+	struct posix_acl *acl;
+
+	if (!value)
+		return NULL;
+	if (size < sizeof(ext3_acl_header))
+		 return ERR_PTR(-EINVAL);
+	if (((ext3_acl_header *)value)->a_version !=
+	    cpu_to_le32(EXT3_ACL_VERSION))
+		return ERR_PTR(-EINVAL);
+	value = (char *)value + sizeof(ext3_acl_header);
+	count = ext3_acl_count(size);
+	if (count < 0)
+		return ERR_PTR(-EINVAL);
+	if (count == 0)
+		return NULL;
+	acl = posix_acl_alloc(count, GFP_KERNEL);
+	if (!acl)
+		return ERR_PTR(-ENOMEM);
+	for (n=0; n < count; n++) {
+		ext3_acl_entry *entry =
+			(ext3_acl_entry *)value;
+		if ((char *)value + sizeof(ext3_acl_entry_short) > end)
+			goto fail;
+		acl->a_entries[n].e_tag  = le16_to_cpu(entry->e_tag);
+		acl->a_entries[n].e_perm = le16_to_cpu(entry->e_perm);
+		switch(acl->a_entries[n].e_tag) {
+			case ACL_USER_OBJ:
+			case ACL_GROUP_OBJ:
+			case ACL_MASK:
+			case ACL_OTHER:
+				value = (char *)value +
+					sizeof(ext3_acl_entry_short);
+				acl->a_entries[n].e_id = ACL_UNDEFINED_ID;
+				break;
+
+			case ACL_USER:
+			case ACL_GROUP:
+				value = (char *)value + sizeof(ext3_acl_entry);
+				if ((char *)value > end)
+					goto fail;
+				acl->a_entries[n].e_id =
+					le32_to_cpu(entry->e_id);
+				break;
+
+			default:
+				goto fail;
+		}
+	}
+	if (value != end)
+		goto fail;
+	return acl;
+
+fail:
+	posix_acl_release(acl);
+	return ERR_PTR(-EINVAL);
+}
+
+/*
+ * Convert from in-memory to filesystem representation.
+ */
+static void *
+ext3_acl_to_disk(const struct posix_acl *acl, size_t *size)
+{
+	ext3_acl_header *ext_acl;
+	char *e;
+	int n;
+
+	*size = ext3_acl_size(acl->a_count);
+	ext_acl = (ext3_acl_header *)kmalloc(sizeof(ext3_acl_header) +
+		acl->a_count * sizeof(ext3_acl_entry), GFP_KERNEL);
+	if (!ext_acl)
+		return ERR_PTR(-ENOMEM);
+	ext_acl->a_version = cpu_to_le32(EXT3_ACL_VERSION);
+	e = (char *)ext_acl + sizeof(ext3_acl_header);
+	for (n=0; n < acl->a_count; n++) {
+		ext3_acl_entry *entry = (ext3_acl_entry *)e;
+		entry->e_tag  = cpu_to_le16(acl->a_entries[n].e_tag);
+		entry->e_perm = cpu_to_le16(acl->a_entries[n].e_perm);
+		switch(acl->a_entries[n].e_tag) {
+			case ACL_USER:
+			case ACL_GROUP:
+				entry->e_id =
+					cpu_to_le32(acl->a_entries[n].e_id);
+				e += sizeof(ext3_acl_entry);
+				break;
+
+			case ACL_USER_OBJ:
+			case ACL_GROUP_OBJ:
+			case ACL_MASK:
+			case ACL_OTHER:
+				e += sizeof(ext3_acl_entry_short);
+				break;
+
+			default:
+				goto fail;
+		}
+	}
+	return (char *)ext_acl;
+
+fail:
+	kfree(ext_acl);
+	return ERR_PTR(-EINVAL);
+}
+
+/*
+ * Inode operation get_posix_acl().
+ *
+ * inode->i_sem: down
+ */
+static struct posix_acl *
+ext3_get_acl(struct inode *inode, int type)
+{
+	int name_index;
+	char *value;
+	struct posix_acl *acl, **p_acl;
+	const size_t size = ext3_acl_size(EXT3_ACL_MAX_ENTRIES);
+	int retval;
+
+	if (!test_opt(inode->i_sb, POSIX_ACL))
+		return 0;
+
+	switch(type) {
+		case ACL_TYPE_ACCESS:
+			p_acl = &EXT3_I(inode)->i_acl;
+			name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS;
+			break;
+
+		case ACL_TYPE_DEFAULT:
+			p_acl = &EXT3_I(inode)->i_default_acl;
+			name_index = EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT;
+			break;
+
+		default:
+			return ERR_PTR(-EINVAL);
+	}
+	if (*p_acl != EXT3_ACL_NOT_CACHED)
+		return posix_acl_dup(*p_acl);
+	value = kmalloc(size, GFP_KERNEL);
+	if (!value)
+		return ERR_PTR(-ENOMEM);
+
+	retval = ext3_xattr_get(inode, name_index, "", value, size);
+
+	if (retval == -ENODATA || retval == -ENOSYS)
+		*p_acl = acl = NULL;
+	else if (retval < 0)
+		acl = ERR_PTR(retval);
+	else {
+		acl = ext3_acl_from_disk(value, retval);
+		if (!IS_ERR(acl))
+			*p_acl = posix_acl_dup(acl);
+	}
+	kfree(value);
+	return acl;
+}
+
+/*
+ * Set the access or default ACL of an inode.
+ *
+ * inode->i_sem: down unless called from ext3_new_inode
+ */
+static int
+ext3_set_acl(handle_t *handle, struct inode *inode, int type,
+	     struct posix_acl *acl)
+{
+	int name_index;
+	void *value = NULL;
+	struct posix_acl **p_acl;
+	size_t size;
+	int error;
+
+	if (S_ISLNK(inode->i_mode))
+		return -EOPNOTSUPP;
+
+	switch(type) {
+		case ACL_TYPE_ACCESS:
+			name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS;
+			p_acl = &EXT3_I(inode)->i_acl;
+			if (acl) {
+				mode_t mode = inode->i_mode;
+				error = posix_acl_equiv_mode(acl, &mode);
+				if (error < 0)
+					return error;
+				else {
+					inode->i_mode = mode;
+					ext3_mark_inode_dirty(handle, inode);
+					if (error == 0)
+						acl = NULL;
+				}
+			}
+			break;
+
+		case ACL_TYPE_DEFAULT:
+			name_index = EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT;
+			p_acl = &EXT3_I(inode)->i_default_acl;
+			if (!S_ISDIR(inode->i_mode))
+				return acl ? -EACCES : 0;
+			break;
+
+		default:
+			return -EINVAL;
+	}
+ 	if (acl) {
+		if (acl->a_count > EXT3_ACL_MAX_ENTRIES)
+			return -EINVAL;
+		value = ext3_acl_to_disk(acl, &size);
+		if (IS_ERR(value))
+			return (int)PTR_ERR(value);
+	}
+
+	error = ext3_xattr_set(handle, inode, name_index, "", value, size, 0);
+
+	if (value)
+		kfree(value);
+	if (!error) {
+		if (*p_acl && *p_acl != EXT3_ACL_NOT_CACHED)
+			posix_acl_release(*p_acl);
+		*p_acl = posix_acl_dup(acl);
+	}
+	return error;
+}
+
+static int
+__ext3_permission(struct inode *inode, int mask, int lock)
+{
+	int mode = inode->i_mode;
+
+	/* Nobody gets write access to a read-only fs */
+	if ((mask & MAY_WRITE) && IS_RDONLY(inode) &&
+	    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
+		return -EROFS;
+	/* Nobody gets write access to an immutable file */
+	if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode))
+	    return -EACCES;
+	if (current->fsuid == inode->i_uid) {
+		mode >>= 6;
+	} else if (test_opt(inode->i_sb, POSIX_ACL)) {
+		/* ACL can't contain additional permissions if
+		   the ACL_MASK entry is 0 */
+		if (!(mode & S_IRWXG))
+			goto check_groups;
+		if (EXT3_I(inode)->i_acl == EXT3_ACL_NOT_CACHED) {
+			struct posix_acl *acl;
+
+			if (lock) {
+				down(&inode->i_sem);
+				acl = ext3_get_acl(inode, ACL_TYPE_ACCESS);
+				up(&inode->i_sem);
+			} else
+				acl = ext3_get_acl(inode, ACL_TYPE_ACCESS);
+
+			if (IS_ERR(acl))
+				return PTR_ERR(acl);
+			posix_acl_release(acl);
+			if (EXT3_I(inode)->i_acl == EXT3_ACL_NOT_CACHED)
+				return -EIO;
+		}
+		if (EXT3_I(inode)->i_acl) {
+			int error = posix_acl_permission(inode,
+				EXT3_I(inode)->i_acl, mask);
+			if (error == -EACCES)
+				goto check_capabilities;
+			return error;
+		} else
+			goto check_groups;
+	} else {
+check_groups:
+		if (in_group_p(inode->i_gid))
+			mode >>= 3;
+	}
+	if ((mode & mask & S_IRWXO) == mask)
+		return 0;
+
+check_capabilities:
+	/* Allowed to override Discretionary Access Control? */
+	if ((mask & (MAY_READ|MAY_WRITE)) || (inode->i_mode & S_IXUGO))
+		if (capable(CAP_DAC_OVERRIDE))
+			return 0;
+	/* Read and search granted if capable(CAP_DAC_READ_SEARCH) */
+	if (capable(CAP_DAC_READ_SEARCH) && ((mask == MAY_READ) ||
+	    (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE))))
+		return 0;
+	return -EACCES;
+}
+
+/*
+ * Inode operation permission().
+ *
+ * inode->i_sem: up
+ */
+int
+ext3_permission(struct inode *inode, int mask)
+{
+	return __ext3_permission(inode, mask, 1);
+}
+
+/*
+ * Used internally if i_sem is already down.
+ */
+int
+ext3_permission_locked(struct inode *inode, int mask)
+{
+	return __ext3_permission(inode, mask, 0);
+}
+
+/*
+ * Initialize the ACLs of a new inode. Called from ext3_new_inode.
+ *
+ * dir->i_sem: down
+ * inode->i_sem: up (access to inode is still exclusive)
+ */
+int
+ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
+{
+	struct posix_acl *acl = NULL;
+	int error = 0;
+
+	if (!S_ISLNK(inode->i_mode)) {
+		if (test_opt(dir->i_sb, POSIX_ACL)) {
+			acl = ext3_get_acl(dir, ACL_TYPE_DEFAULT);
+			if (IS_ERR(acl))
+				return PTR_ERR(acl);
+		}
+		if (!acl)
+			inode->i_mode &= ~current->fs->umask;
+	}
+	if (test_opt(inode->i_sb, POSIX_ACL) && acl) {
+		struct posix_acl *clone;
+		mode_t mode;
+
+		if (S_ISDIR(inode->i_mode)) {
+			error = ext3_set_acl(handle, inode,
+					     ACL_TYPE_DEFAULT, acl);
+			if (error)
+				goto cleanup;
+		}
+		clone = posix_acl_clone(acl, GFP_KERNEL);
+		error = -ENOMEM;
+		if (!clone)
+			goto cleanup;
+		
+		mode = inode->i_mode;
+		error = posix_acl_create_masq(clone, &mode);
+		if (error >= 0) {
+			inode->i_mode = mode;
+			if (error > 0) {
+				/* This is an extended ACL */
+				error = ext3_set_acl(handle, inode,
+						     ACL_TYPE_ACCESS, clone);
+			}
+		}
+		posix_acl_release(clone);
+	}
+cleanup:
+	posix_acl_release(acl);
+	return error;
+}
+
+/*
+ * Does chmod for an inode that may have an Access Control List. The
+ * inode->i_mode field must be updated to the desired value by the caller
+ * before calling this function.
+ * Returns 0 on success, or a negative error number.
+ *
+ * We change the ACL rather than storing some ACL entries in the file
+ * mode permission bits (which would be more efficient), because that
+ * would break once additional permissions (like  ACL_APPEND, ACL_DELETE
+ * for directories) are added. There are no more bits available in the
+ * file mode.
+ *
+ * inode->i_sem: down
+ */
+int
+ext3_acl_chmod(struct inode *inode)
+{
+	struct posix_acl *acl, *clone;
+        int error;
+
+	if (S_ISLNK(inode->i_mode))
+		return -EOPNOTSUPP;
+	if (!test_opt(inode->i_sb, POSIX_ACL))
+		return 0;
+	acl = ext3_get_acl(inode, ACL_TYPE_ACCESS);
+	if (IS_ERR(acl) || !acl)
+		return PTR_ERR(acl);
+	clone = posix_acl_clone(acl, GFP_KERNEL);
+	posix_acl_release(acl);
+	if (!clone)
+		return -ENOMEM;
+	error = posix_acl_chmod_masq(clone, inode->i_mode);
+	if (!error) {
+		handle_t *handle;
+
+		handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
+		if (IS_ERR(handle)) {
+			ext3_std_error(inode->i_sb, error);
+			return PTR_ERR(handle);
+		}
+		error = ext3_set_acl(handle, inode, ACL_TYPE_ACCESS, clone);
+		ext3_journal_stop(handle, inode);
+	}
+	posix_acl_release(clone);
+	return error;
+}
+
+/*
+ * Extended attribute handlers
+ */
+static size_t
+ext3_xattr_list_acl_access(char *list, struct inode *inode,
+			   const char *name, int name_len)
+{
+	const size_t len = sizeof(XATTR_NAME_ACL_ACCESS)-1;
+
+	if (!test_opt(inode->i_sb, POSIX_ACL))
+		return 0;
+	if (list)
+		memcpy(list, XATTR_NAME_ACL_ACCESS, len);
+	return len;
+}
+
+static size_t
+ext3_xattr_list_acl_default(char *list, struct inode *inode,
+			    const char *name, int name_len)
+{
+	const size_t len = sizeof(XATTR_NAME_ACL_DEFAULT)-1;
+
+	if (!test_opt(inode->i_sb, POSIX_ACL))
+		return 0;
+	if (list)
+		memcpy(list, XATTR_NAME_ACL_DEFAULT, len);
+	return len;
+}
+
+static int
+ext3_xattr_get_acl(struct inode *inode, int type, void *buffer, size_t size)
+{
+	struct posix_acl *acl;
+	int error;
+
+	if (!test_opt(inode->i_sb, POSIX_ACL))
+		return -EOPNOTSUPP;
+
+	acl = ext3_get_acl(inode, type);
+	if (IS_ERR(acl))
+		return PTR_ERR(acl);
+	if (acl == NULL)
+		return -ENODATA;
+	error = posix_acl_to_xattr(acl, buffer, size);
+	posix_acl_release(acl);
+
+	return error;
+}
+
+static int
+ext3_xattr_get_acl_access(struct inode *inode, const char *name,
+			  void *buffer, size_t size)
+{
+	if (strcmp(name, "") != 0)
+		return -EINVAL;
+	return ext3_xattr_get_acl(inode, ACL_TYPE_ACCESS, buffer, size);
+}
+
+static int
+ext3_xattr_get_acl_default(struct inode *inode, const char *name,
+			   void *buffer, size_t size)
+{
+	if (strcmp(name, "") != 0)
+		return -EINVAL;
+	return ext3_xattr_get_acl(inode, ACL_TYPE_DEFAULT, buffer, size);
+}
+
+static int
+ext3_xattr_set_acl(struct inode *inode, int type, const void *value, size_t size)
+{
+	handle_t *handle;
+	struct posix_acl *acl;
+	int error;
+
+	if (!test_opt(inode->i_sb, POSIX_ACL))
+		return -EOPNOTSUPP;
+	if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+		return -EPERM;
+
+	if (value) {
+		acl = posix_acl_from_xattr(value, size);
+		if (IS_ERR(acl))
+			return PTR_ERR(acl);
+		else if (acl) {
+			error = posix_acl_valid(acl);
+			if (error)
+				goto release_and_out;
+		}
+	} else
+		acl = NULL;
+
+	handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
+	if (IS_ERR(handle))
+		return PTR_ERR(handle);
+	error = ext3_set_acl(handle, inode, type, acl);
+	ext3_journal_stop(handle, inode);
+
+release_and_out:
+	posix_acl_release(acl);
+	return error;
+}
+
+static int
+ext3_xattr_set_acl_access(struct inode *inode, const char *name,
+			  const void *value, size_t size, int flags)
+{
+	if (strcmp(name, "") != 0)
+		return -EINVAL;
+	return ext3_xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size);
+}
+
+static int
+ext3_xattr_set_acl_default(struct inode *inode, const char *name,
+			   const void *value, size_t size, int flags)
+{
+	if (strcmp(name, "") != 0)
+		return -EINVAL;
+	return ext3_xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size);
+}
+
+struct ext3_xattr_handler ext3_xattr_acl_access_handler = {
+	prefix:	XATTR_NAME_ACL_ACCESS,
+	list:	ext3_xattr_list_acl_access,
+	get:	ext3_xattr_get_acl_access,
+	set:	ext3_xattr_set_acl_access,
+};
+
+struct ext3_xattr_handler ext3_xattr_acl_default_handler = {
+	prefix:	XATTR_NAME_ACL_DEFAULT,
+	list:	ext3_xattr_list_acl_default,
+	get:	ext3_xattr_get_acl_default,
+	set:	ext3_xattr_set_acl_default,
+};
+
+void
+exit_ext3_acl(void)
+{
+	ext3_xattr_unregister(EXT3_XATTR_INDEX_POSIX_ACL_ACCESS,
+			      &ext3_xattr_acl_access_handler);
+	ext3_xattr_unregister(EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT,
+			      &ext3_xattr_acl_default_handler);
+}
+
+int __init
+init_ext3_acl(void)
+{
+	int error;
+
+	error = ext3_xattr_register(EXT3_XATTR_INDEX_POSIX_ACL_ACCESS,
+				    &ext3_xattr_acl_access_handler);
+	if (error)
+		goto fail;
+	error = ext3_xattr_register(EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT,
+				    &ext3_xattr_acl_default_handler);
+	if (error)
+		goto fail;
+	return 0;
+
+fail:
+	exit_ext3_acl();
+	return error;
+}
diff -Nru a/fs/ext3/acl.h b/fs/ext3/acl.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/ext3/acl.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,87 @@
+/*
+  File: fs/ext3/acl.h
+
+  (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
+*/
+
+#include <linux/xattr_acl.h>
+
+#define EXT3_ACL_VERSION	0x0001
+#define EXT3_ACL_MAX_ENTRIES	32
+
+typedef struct {
+	__u16		e_tag;
+	__u16		e_perm;
+	__u32		e_id;
+} ext3_acl_entry;
+
+typedef struct {
+	__u16		e_tag;
+	__u16		e_perm;
+} ext3_acl_entry_short;
+
+typedef struct {
+	__u32		a_version;
+} ext3_acl_header;
+
+static inline size_t ext3_acl_size(int count)
+{
+	if (count <= 4) {
+		return sizeof(ext3_acl_header) +
+		       count * sizeof(ext3_acl_entry_short);
+	} else {
+		return sizeof(ext3_acl_header) +
+		       4 * sizeof(ext3_acl_entry_short) +
+		       (count - 4) * sizeof(ext3_acl_entry);
+	}
+}
+
+static inline int ext3_acl_count(size_t size)
+{
+	ssize_t s;
+	size -= sizeof(ext3_acl_header);
+	s = size - 4 * sizeof(ext3_acl_entry_short);
+	if (s < 0) {
+		if (size % sizeof(ext3_acl_entry_short))
+			return -1;
+		return size / sizeof(ext3_acl_entry_short);
+	} else {
+		if (s % sizeof(ext3_acl_entry))
+			return -1;
+		return s / sizeof(ext3_acl_entry) + 4;
+	}
+}
+
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
+
+/* Value for inode->u.ext3_i.i_acl and inode->u.ext3_i.i_default_acl
+   if the ACL has not been cached */
+#define EXT3_ACL_NOT_CACHED ((void *)-1)
+
+/* acl.c */
+extern int ext3_permission (struct inode *, int);
+extern int ext3_permission_locked (struct inode *, int);
+extern int ext3_acl_chmod (struct inode *);
+extern int ext3_init_acl (handle_t *, struct inode *, struct inode *);
+
+extern int init_ext3_acl(void);
+extern void exit_ext3_acl(void);
+
+#else  /* CONFIG_EXT3_FS_POSIX_ACL */
+#include <linux/sched.h>
+#define ext3_permission NULL
+
+static inline int
+ext3_acl_chmod(struct inode *inode)
+{
+	return 0;
+}
+
+static inline int
+ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
+{
+	inode->i_mode &= ~current->fs->umask;
+	return 0;
+}
+#endif  /* CONFIG_EXT3_FS_POSIX_ACL */
+
diff -Nru a/fs/ext3/file.c b/fs/ext3/file.c
--- a/fs/ext3/file.c	Mon Nov  4 14:31:02 2002
+++ b/fs/ext3/file.c	Mon Nov  4 14:31:02 2002
@@ -23,7 +23,8 @@
 #include <linux/jbd.h>
 #include <linux/ext3_fs.h>
 #include <linux/ext3_jbd.h>
-#include <linux/smp_lock.h>
+#include "xattr.h"
+#include "acl.h"
 
 /*
  * Called when an inode is released. Note that this is different
@@ -98,5 +99,10 @@
 struct inode_operations ext3_file_inode_operations = {
 	.truncate	= ext3_truncate,
 	.setattr	= ext3_setattr,
+	.setxattr	= ext3_setxattr,
+	.getxattr	= ext3_getxattr,
+	.listxattr	= ext3_listxattr,
+	.removexattr	= ext3_removexattr,
+	.permission	= ext3_permission,
 };
 
diff -Nru a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
--- a/fs/ext3/ialloc.c	Mon Nov  4 14:31:02 2002
+++ b/fs/ext3/ialloc.c	Mon Nov  4 14:31:02 2002
@@ -21,10 +21,14 @@
 #include <linux/string.h>
 #include <linux/quotaops.h>
 #include <linux/buffer_head.h>
+#include <linux/random.h>
 
 #include <asm/bitops.h>
 #include <asm/byteorder.h>
 
+#include "xattr.h"
+#include "acl.h"
+
 /*
  * ialloc.c contains the inodes allocation and deallocation routines
  */
@@ -118,6 +122,7 @@
 	 * as writing the quota to disk may need the lock as well.
 	 */
 	DQUOT_INIT(inode);
+	ext3_xattr_delete_inode(handle, inode);
 	DQUOT_FREE_INODE(inode);
 	DQUOT_DROP(inode);
 
@@ -194,6 +199,230 @@
  * the groups with above-average free space, that group with the fewest
  * directories already is chosen.
  *
+ * For other inodes, search forward from the parent directory\'s block
+ * group to find a free inode.
+ */
+static int find_group_dir(struct super_block *sb, struct inode *parent)
+{
+	struct ext3_super_block * es = EXT3_SB(sb)->s_es;
+	int ngroups = EXT3_SB(sb)->s_groups_count;
+	int avefreei = le32_to_cpu(es->s_free_inodes_count) / ngroups;
+	struct ext3_group_desc *desc, *best_desc = NULL;
+	struct buffer_head *bh, *best_bh = NULL;
+	int group, best_group = -1;
+
+	for (group = 0; group < ngroups; group++) {
+		desc = ext3_get_group_desc (sb, group, &bh);
+		if (!desc || !desc->bg_free_inodes_count)
+			continue;
+		if (le16_to_cpu(desc->bg_free_inodes_count) < avefreei)
+			continue;
+		if (!best_desc || 
+		    (le16_to_cpu(desc->bg_free_blocks_count) >
+		     le16_to_cpu(best_desc->bg_free_blocks_count))) {
+			best_group = group;
+			best_desc = desc;
+			best_bh = bh;
+		}
+	}
+	if (!best_desc)
+		return -1;
+	best_desc->bg_free_inodes_count =
+		cpu_to_le16(le16_to_cpu(best_desc->bg_free_inodes_count) - 1);
+	best_desc->bg_used_dirs_count =
+		cpu_to_le16(le16_to_cpu(best_desc->bg_used_dirs_count) + 1);
+	mark_buffer_dirty(best_bh);
+	return best_group;
+}
+
+/* 
+ * Orlov's allocator for directories. 
+ * 
+ * We always try to spread first-level directories.
+ *
+ * If there are blockgroups with both free inodes and free blocks counts 
+ * not worse than average we return one with smallest directory count. 
+ * Otherwise we simply return a random group. 
+ * 
+ * For the rest rules look so: 
+ * 
+ * It's OK to put directory into a group unless 
+ * it has too many directories already (max_dirs) or 
+ * it has too few free inodes left (min_inodes) or 
+ * it has too few free blocks left (min_blocks) or 
+ * it's already running too large debt (max_debt). 
+ * Parent's group is prefered, if it doesn't satisfy these 
+ * conditions we search cyclically through the rest. If none 
+ * of the groups look good we just look for a group with more 
+ * free inodes than average (starting at parent's group). 
+ * 
+ * Debt is incremented each time we allocate a directory and decremented 
+ * when we allocate an inode, within 0--255. 
+ */ 
+
+#define INODE_COST 64
+#define BLOCK_COST 256
+
+static int find_group_orlov(struct super_block *sb, struct inode *parent)
+{
+	int parent_group = EXT3_I(parent)->i_block_group;
+	struct ext3_sb_info *sbi = EXT3_SB(sb);
+	struct ext3_super_block *es = sbi->s_es;
+	int ngroups = sbi->s_groups_count;
+	int inodes_per_group = EXT3_INODES_PER_GROUP(sb);
+	int avefreei = le32_to_cpu(es->s_free_inodes_count) / ngroups;
+	int avefreeb = le32_to_cpu(es->s_free_blocks_count) / ngroups;
+	int blocks_per_dir;
+	int ndirs = sbi->s_dir_count;
+	int max_debt, max_dirs, min_blocks, min_inodes;
+	int group = -1, i;
+	struct ext3_group_desc *desc;
+	struct buffer_head *bh;
+
+	if ((parent == sb->s_root->d_inode) ||
+	    (parent->i_flags & EXT3_TOPDIR_FL)) {
+		struct ext3_group_desc *best_desc = NULL;
+		struct buffer_head *best_bh = NULL;
+		int best_ndir = inodes_per_group;
+		int best_group = -1;
+
+		get_random_bytes(&group, sizeof(group));
+		parent_group = (unsigned)group % ngroups;
+		for (i = 0; i < ngroups; i++) {
+			group = (parent_group + i) % ngroups;
+			desc = ext3_get_group_desc (sb, group, &bh);
+			if (!desc || !desc->bg_free_inodes_count)
+				continue;
+			if (le16_to_cpu(desc->bg_used_dirs_count) >= best_ndir)
+				continue;
+			if (le16_to_cpu(desc->bg_free_inodes_count) < avefreei)
+				continue;
+			if (le16_to_cpu(desc->bg_free_blocks_count) < avefreeb)
+				continue;
+			best_group = group;
+			best_ndir = le16_to_cpu(desc->bg_used_dirs_count);
+			best_desc = desc;
+			best_bh = bh;
+		}
+		if (best_group >= 0) {
+			desc = best_desc;
+			bh = best_bh;
+			group = best_group;
+			goto found;
+		}
+		goto fallback;
+	}
+
+	blocks_per_dir = (le32_to_cpu(es->s_blocks_count) -
+			  le32_to_cpu(es->s_free_blocks_count)) / ndirs;
+
+	max_dirs = ndirs / ngroups + inodes_per_group / 16;
+	min_inodes = avefreei - inodes_per_group / 4;
+	min_blocks = avefreeb - EXT3_BLOCKS_PER_GROUP(sb) / 4;
+
+	max_debt = EXT3_BLOCKS_PER_GROUP(sb) / max(blocks_per_dir, BLOCK_COST);
+	if (max_debt * INODE_COST > inodes_per_group)
+		max_debt = inodes_per_group / INODE_COST;
+	if (max_debt > 255)
+		max_debt = 255;
+	if (max_debt == 0)
+		max_debt = 1;
+
+	for (i = 0; i < ngroups; i++) {
+		group = (parent_group + i) % ngroups;
+		desc = ext3_get_group_desc (sb, group, &bh);
+		if (!desc || !desc->bg_free_inodes_count)
+			continue;
+		if (sbi->s_debts[group] >= max_debt)
+			continue;
+		if (le16_to_cpu(desc->bg_used_dirs_count) >= max_dirs)
+			continue;
+		if (le16_to_cpu(desc->bg_free_inodes_count) < min_inodes)
+			continue;
+		if (le16_to_cpu(desc->bg_free_blocks_count) < min_blocks)
+			continue;
+		goto found;
+	}
+
+fallback:
+	for (i = 0; i < ngroups; i++) {
+		group = (parent_group + i) % ngroups;
+		desc = ext3_get_group_desc (sb, group, &bh);
+		if (!desc || !desc->bg_free_inodes_count)
+			continue;
+		if (le16_to_cpu(desc->bg_free_inodes_count) >= avefreei)
+			goto found;
+	}
+
+	return -1;
+
+found:
+	desc->bg_free_inodes_count =
+		cpu_to_le16(le16_to_cpu(desc->bg_free_inodes_count) - 1);
+	desc->bg_used_dirs_count =
+		cpu_to_le16(le16_to_cpu(desc->bg_used_dirs_count) + 1);
+	sbi->s_dir_count++;
+	mark_buffer_dirty(bh);
+	return group;
+}
+
+static int find_group_other(struct super_block *sb, struct inode *parent)
+{
+	int parent_group = EXT3_I(parent)->i_block_group;
+	int ngroups = EXT3_SB(sb)->s_groups_count;
+	struct ext3_group_desc *desc;
+	struct buffer_head *bh;
+	int group, i;
+
+	/*
+	 * Try to place the inode in its parent directory
+	 */
+	group = parent_group;
+	desc = ext3_get_group_desc (sb, group, &bh);
+	if (desc && le16_to_cpu(desc->bg_free_inodes_count))
+		goto found;
+
+	/*
+	 * Use a quadratic hash to find a group with a
+	 * free inode
+	 */
+	for (i = 1; i < ngroups; i <<= 1) {
+		group += i;
+		if (group >= ngroups)
+			group -= ngroups;
+		desc = ext3_get_group_desc (sb, group, &bh);
+		if (desc && le16_to_cpu(desc->bg_free_inodes_count))
+			goto found;
+	}
+
+	/*
+	 * That failed: try linear search for a free inode
+	 */
+	group = parent_group + 1;
+	for (i = 2; i < ngroups; i++) {
+		if (++group >= ngroups)
+			group = 0;
+		desc = ext3_get_group_desc (sb, group, &bh);
+		if (desc && le16_to_cpu(desc->bg_free_inodes_count))
+			goto found;
+	}
+
+	return -1;
+
+found:
+	desc->bg_free_inodes_count =
+		cpu_to_le16(le16_to_cpu(desc->bg_free_inodes_count) - 1);
+	mark_buffer_dirty(bh);
+	return group;
+}
+
+/*
+ * There are two policies for allocating an inode.  If the new inode is
+ * a directory, then a forward search is made for a block group with both
+ * free space and a low directory-to-inode ratio; if that fails, then of
+ * the groups with above-average free space, that group with the fewest
+ * directories already is chosen.
+ *
  * For other inodes, search forward from the parent directory's block
  * group to find a free inode.
  */
@@ -202,10 +431,10 @@
 	struct super_block *sb;
 	struct buffer_head *bitmap_bh = NULL;
 	struct buffer_head *bh2;
-	int i, j, avefreei;
+	int group;
+	ino_t ino;
 	struct inode * inode;
 	struct ext3_group_desc * gdp;
-	struct ext3_group_desc * tmp;
 	struct ext3_super_block * es;
 	struct ext3_inode_info *ei;
 	int err = 0;
@@ -224,93 +453,35 @@
 	lock_super (sb);
 	es = EXT3_SB(sb)->s_es;
 repeat:
-	gdp = NULL;
-	i = 0;
-
 	if (S_ISDIR(mode)) {
-		avefreei = le32_to_cpu(es->s_free_inodes_count) /
-			EXT3_SB(sb)->s_groups_count;
-		if (!gdp) {
-			for (j = 0; j < EXT3_SB(sb)->s_groups_count; j++) {
-				struct buffer_head *temp_buffer;
-				tmp = ext3_get_group_desc (sb, j, &temp_buffer);
-				if (tmp &&
-				    le16_to_cpu(tmp->bg_free_inodes_count) &&
-				    le16_to_cpu(tmp->bg_free_inodes_count) >=
-							avefreei) {
-					if (!gdp || (le16_to_cpu(tmp->bg_free_blocks_count) >
-						le16_to_cpu(gdp->bg_free_blocks_count))) {
-						i = j;
-						gdp = tmp;
-						bh2 = temp_buffer;
-					}
-				}
-			}
-		}
-	} else {
-		/*
-		 * Try to place the inode in its parent directory
-		 */
-		i = EXT3_I(dir)->i_block_group;
-		tmp = ext3_get_group_desc (sb, i, &bh2);
-		if (tmp && le16_to_cpu(tmp->bg_free_inodes_count))
-			gdp = tmp;
+		if (test_opt (sb, OLDALLOC))
+			group = find_group_dir(sb, dir);
 		else
-		{
-			/*
-			 * Use a quadratic hash to find a group with a
-			 * free inode
-			 */
-			for (j = 1; j < EXT3_SB(sb)->s_groups_count; j <<= 1) {
-				i += j;
-				if (i >= EXT3_SB(sb)->s_groups_count)
-					i -= EXT3_SB(sb)->s_groups_count;
-				tmp = ext3_get_group_desc (sb, i, &bh2);
-				if (tmp &&
-				    le16_to_cpu(tmp->bg_free_inodes_count)) {
-					gdp = tmp;
-					break;
-				}
-			}
-		}
-		if (!gdp) {
-			/*
-			 * That failed: try linear search for a free inode
-			 */
-			i = EXT3_I(dir)->i_block_group + 1;
-			for (j = 2; j < EXT3_SB(sb)->s_groups_count; j++) {
-				if (++i >= EXT3_SB(sb)->s_groups_count)
-					i = 0;
-				tmp = ext3_get_group_desc (sb, i, &bh2);
-				if (tmp &&
-				    le16_to_cpu(tmp->bg_free_inodes_count)) {
-					gdp = tmp;
-					break;
-				}
-			}
-		}
-	}
+			group = find_group_orlov(sb, dir);
+	} else 
+		group = find_group_other(sb, dir);
 
 	err = -ENOSPC;
-	if (!gdp)
+	if (group == -1)
 		goto out;
 
 	err = -EIO;
 	brelse(bitmap_bh);
-	bitmap_bh = read_inode_bitmap(sb, i);
+	bitmap_bh = read_inode_bitmap(sb, group);
 	if (!bitmap_bh)
 		goto fail;
+	gdp = ext3_get_group_desc (sb, group, &bh2);
 
-	if ((j = ext3_find_first_zero_bit((unsigned long *)bitmap_bh->b_data,
+	if ((ino = ext3_find_first_zero_bit((unsigned long *)bitmap_bh->b_data,
 				      EXT3_INODES_PER_GROUP(sb))) <
 	    EXT3_INODES_PER_GROUP(sb)) {
 		BUFFER_TRACE(bitmap_bh, "get_write_access");
 		err = ext3_journal_get_write_access(handle, bitmap_bh);
 		if (err) goto fail;
 		
-		if (ext3_set_bit(j, bitmap_bh->b_data)) {
+		if (ext3_set_bit(ino, bitmap_bh->b_data)) {
 			ext3_error (sb, "ext3_new_inode",
-				      "bit already set for inode %d", j);
+				      "bit already set for inode %lu", ino);
 			goto repeat;
 		}
 		BUFFER_TRACE(bitmap_bh, "call ext3_journal_dirty_metadata");
@@ -320,7 +491,7 @@
 		if (le16_to_cpu(gdp->bg_free_inodes_count) != 0) {
 			ext3_error (sb, "ext3_new_inode",
 				    "Free inodes count corrupted in group %d",
-				    i);
+				    group);
 			/* Is it really ENOSPC? */
 			err = -ENOSPC;
 			if (sb->s_flags & MS_RDONLY)
@@ -336,11 +507,11 @@
 		}
 		goto repeat;
 	}
-	j += i * EXT3_INODES_PER_GROUP(sb) + 1;
-	if (j < EXT3_FIRST_INO(sb) || j > le32_to_cpu(es->s_inodes_count)) {
+	ino += group * EXT3_INODES_PER_GROUP(sb) + 1;
+	if (ino < EXT3_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) {
 		ext3_error (sb, "ext3_new_inode",
 			    "reserved inode or inode > inodes count - "
-			    "block_group = %d,inode=%d", i, j);
+			    "block_group = %d, inode=%lu", group, ino);
 		err = -EIO;
 		goto fail;
 	}
@@ -378,7 +549,7 @@
 		inode->i_gid = current->fsgid;
 	inode->i_mode = mode;
 
-	inode->i_ino = j;
+	inode->i_ino = ino;
 	/* This is the optimal IO size (for stat), not the fs block size */
 	inode->i_blksize = PAGE_SIZE;
 	inode->i_blocks = 0;
@@ -408,7 +579,7 @@
 	ei->i_prealloc_block = 0;
 	ei->i_prealloc_count = 0;
 #endif
-	ei->i_block_group = i;
+	ei->i_block_group = group;
 	
 	if (ei->i_flags & EXT3_SYNC_FL)
 		inode->i_flags |= S_SYNC;
@@ -420,20 +591,27 @@
 	inode->i_generation = EXT3_SB(sb)->s_next_generation++;
 
 	ei->i_state = EXT3_STATE_NEW;
-	err = ext3_mark_inode_dirty(handle, inode);
-	if (err) goto fail;
-	
+
 	unlock_super(sb);
 	ret = inode;
 	if(DQUOT_ALLOC_INODE(inode)) {
 		DQUOT_DROP(inode);
-		inode->i_flags |= S_NOQUOTA;
-		inode->i_nlink = 0;
-		iput(inode);
-		ret = ERR_PTR(-EDQUOT);
-	} else {
-		ext3_debug("allocating inode %lu\n", inode->i_ino);
+		err = -EDQUOT;
+		goto fail2;
+	}
+	err = ext3_init_acl(handle, inode, dir);
+	if (err) {
+		DQUOT_FREE_INODE(inode);
+		goto fail2;
+  	}
+	err = ext3_mark_inode_dirty(handle, inode);
+	if (err) {
+		ext3_std_error(sb, err);
+		DQUOT_FREE_INODE(inode);
+		goto fail2;
 	}
+
+	ext3_debug("allocating inode %lu\n", inode->i_ino);
 	goto really_out;
 fail:
 	ext3_std_error(sb, err);
@@ -444,6 +622,12 @@
 really_out:
 	brelse(bitmap_bh);
 	return ret;
+
+fail2:
+	inode->i_flags |= S_NOQUOTA;
+	inode->i_nlink = 0;
+	iput(inode);
+	return ERR_PTR(err);
 }
 
 /* Verify that we are loading a valid orphan from disk */
@@ -543,6 +727,21 @@
 #else
 	return le32_to_cpu(EXT3_SB(sb)->s_es->s_free_inodes_count);
 #endif
+}
+
+/* Called at mount-time, super-block is locked */
+unsigned long ext3_count_dirs (struct super_block * sb)
+{
+	unsigned long count = 0;
+	int i;
+
+	for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) {
+		struct ext3_group_desc *gdp = ext3_get_group_desc (sb, i, NULL);
+		if (!gdp)
+			continue;
+		count += le16_to_cpu(gdp->bg_used_dirs_count);
+	}
+	return count;
 }
 
 #ifdef CONFIG_EXT3_CHECK
diff -Nru a/fs/ext3/inode.c b/fs/ext3/inode.c
--- a/fs/ext3/inode.c	Mon Nov  4 14:31:02 2002
+++ b/fs/ext3/inode.c	Mon Nov  4 14:31:02 2002
@@ -34,6 +34,8 @@
 #include <linux/string.h>
 #include <linux/buffer_head.h>
 #include <linux/mpage.h>
+#include "xattr.h"
+#include "acl.h"
 
 /*
  * SEARCH_FROM_ZERO forces each block allocation to search from the start
@@ -42,6 +44,18 @@
  */
 #undef SEARCH_FROM_ZERO
 
+/*
+ * Test whether an inode is a fast symlink.
+ */
+static inline int ext3_inode_is_fast_symlink(struct inode *inode)
+{
+	int ea_blocks = EXT3_I(inode)->i_file_acl ?
+		(inode->i_sb->s_blocksize >> 9) : 0;
+
+	return (S_ISLNK(inode->i_mode) &&
+		inode->i_blocks - ea_blocks == 0);
+}
+
 /* The ext3 forget function must perform a revoke if we are freeing data
  * which has been journaled.  Metadata (eg. indirect blocks) must be
  * revoked in all cases. 
@@ -51,7 +65,7 @@
  * still needs to be revoked.
  */
 
-static int ext3_forget(handle_t *handle, int is_metadata,
+int ext3_forget(handle_t *handle, int is_metadata,
 		       struct inode *inode, struct buffer_head *bh,
 		       int blocknr)
 {
@@ -167,9 +181,7 @@
 {
 	handle_t *handle;
 	
-	if (is_bad_inode(inode) ||
-	    inode->i_ino == EXT3_ACL_IDX_INO ||
-	    inode->i_ino == EXT3_ACL_DATA_INO)
+	if (is_bad_inode(inode))
 		goto no_delete;
 
 	lock_kernel();
@@ -1979,6 +1991,8 @@
 	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
 	    S_ISLNK(inode->i_mode)))
 		return;
+	if (ext3_inode_is_fast_symlink(inode))
+		return;
 	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
 		return;
 
@@ -2130,8 +2144,6 @@
 	struct ext3_group_desc * gdp;
 		
 	if ((inode->i_ino != EXT3_ROOT_INO &&
-		inode->i_ino != EXT3_ACL_IDX_INO &&
-		inode->i_ino != EXT3_ACL_DATA_INO &&
 		inode->i_ino != EXT3_JOURNAL_INO &&
 		inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) ||
 		inode->i_ino > le32_to_cpu(
@@ -2189,7 +2201,11 @@
 	struct buffer_head *bh;
 	int block;
 	
-	if(ext3_get_inode_loc(inode, &iloc))
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
+	ei->i_acl = EXT3_ACL_NOT_CACHED;
+	ei->i_default_acl = EXT3_ACL_NOT_CACHED;
+#endif
+	if (ext3_get_inode_loc(inode, &iloc))
 		goto bad_inode;
 	bh = iloc.bh;
 	raw_inode = iloc.raw_inode;
@@ -2263,10 +2279,7 @@
 
 	brelse (iloc.bh);
 
-	if (inode->i_ino == EXT3_ACL_IDX_INO ||
-	    inode->i_ino == EXT3_ACL_DATA_INO)
-		/* Nothing to do */ ;
-	else if (S_ISREG(inode->i_mode)) {
+	if (S_ISREG(inode->i_mode)) {
 		inode->i_op = &ext3_file_inode_operations;
 		inode->i_fop = &ext3_file_operations;
 		if (ext3_should_writeback_data(inode))
@@ -2277,18 +2290,20 @@
 		inode->i_op = &ext3_dir_inode_operations;
 		inode->i_fop = &ext3_dir_operations;
 	} else if (S_ISLNK(inode->i_mode)) {
-		if (!inode->i_blocks)
+		if (ext3_inode_is_fast_symlink(inode))
 			inode->i_op = &ext3_fast_symlink_inode_operations;
 		else {
-			inode->i_op = &page_symlink_inode_operations;
+			inode->i_op = &ext3_symlink_inode_operations;
 			if (ext3_should_writeback_data(inode))
 				inode->i_mapping->a_ops = &ext3_writeback_aops;
 			else
 				inode->i_mapping->a_ops = &ext3_aops;
 		}
-	} else 
+	} else {
+		inode->i_op = &ext3_special_inode_operations;
 		init_special_inode(inode, inode->i_mode,
 				   le32_to_cpu(iloc.raw_inode->i_block[0]));
+	}
 	if (ei->i_flags & EXT3_SYNC_FL)
 		inode->i_flags |= S_SYNC;
 	if (ei->i_flags & EXT3_APPEND_FL)
@@ -2325,6 +2340,11 @@
 		if (err)
 			goto out_brelse;
 	}
+	/* For fields not not tracking in the in-memory inode,
+	 * initialise them to zero for new inodes. */
+	if (ei->i_state & EXT3_STATE_NEW)
+		memset(raw_inode, 0, EXT3_SB(inode->i_sb)->s_inode_size);
+
 	raw_inode->i_mode = cpu_to_le16(inode->i_mode);
 	if(!(test_opt(inode->i_sb, NO_UID32))) {
 		raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid));
@@ -2362,15 +2382,6 @@
 	raw_inode->i_faddr = cpu_to_le32(ei->i_faddr);
 	raw_inode->i_frag = ei->i_frag_no;
 	raw_inode->i_fsize = ei->i_frag_size;
-#else
-	/* If we are not tracking these fields in the in-memory inode,
-	 * then preserve them on disk, but still initialise them to zero
-	 * for new inodes. */
-	if (ei->i_state & EXT3_STATE_NEW) {
-		raw_inode->i_faddr = 0;
-		raw_inode->i_frag = 0;
-		raw_inode->i_fsize = 0;
-	}
 #endif
 	raw_inode->i_file_acl = cpu_to_le32(ei->i_file_acl);
 	if (!S_ISREG(inode->i_mode)) {
@@ -2486,13 +2497,8 @@
  * be freed, so we have a strong guarantee that no future commit will
  * leave these blocks visible to the user.)  
  *
- * This is only needed for regular files.  rmdir() has its own path, and
- * we can never truncate a direcory except on final unlink (at which
- * point i_nlink is zero so recovery is easy.)
- *
- * Called with the BKL.  
+ * Called with inode->sem down.
  */
-
 int ext3_setattr(struct dentry *dentry, struct iattr *attr)
 {
 	struct inode *inode = dentry->d_inode;
@@ -2512,7 +2518,8 @@
 
 	lock_kernel();
 
-	if (attr->ia_valid & ATTR_SIZE && attr->ia_size < inode->i_size) {
+	if (S_ISREG(inode->i_mode) &&
+	    attr->ia_valid & ATTR_SIZE && attr->ia_size < inode->i_size) {
 		handle_t *handle;
 
 		handle = ext3_journal_start(inode, 3);
@@ -2536,6 +2543,9 @@
 	 * orphan list manually. */
 	if (inode->i_nlink)
 		ext3_orphan_del(NULL, inode);
+
+	if (!rc && (ia_valid & ATTR_MODE))
+		rc = ext3_acl_chmod(inode);
 
 err_out:
 	ext3_std_error(inode->i_sb, error);
diff -Nru a/fs/ext3/namei.c b/fs/ext3/namei.c
--- a/fs/ext3/namei.c	Mon Nov  4 14:31:02 2002
+++ b/fs/ext3/namei.c	Mon Nov  4 14:31:02 2002
@@ -36,7 +36,8 @@
 #include <linux/quotaops.h>
 #include <linux/buffer_head.h>
 #include <linux/smp_lock.h>
-
+#include "xattr.h"
+#include "acl.h"
 
 /*
  * define how far ahead to read directories while searching them.
@@ -1623,7 +1624,10 @@
 	inode = ext3_new_inode (handle, dir, mode);
 	err = PTR_ERR(inode);
 	if (!IS_ERR(inode)) {
-		init_special_inode(inode, mode, rdev);
+		init_special_inode(inode, inode->i_mode, rdev);
+#ifdef CONFIG_EXT3_FS_XATTR
+		inode->i_op = &ext3_special_inode_operations;
+#endif
 		err = ext3_add_nondir(handle, dentry, inode);
 		ext3_mark_inode_dirty(handle, inode);
 	}
@@ -1654,7 +1658,7 @@
 	if (IS_DIRSYNC(dir))
 		handle->h_sync = 1;
 
-	inode = ext3_new_inode (handle, dir, S_IFDIR);
+	inode = ext3_new_inode (handle, dir, S_IFDIR | mode);
 	err = PTR_ERR(inode);
 	if (IS_ERR(inode))
 		goto out_stop;
@@ -1662,7 +1666,6 @@
 	inode->i_op = &ext3_dir_inode_operations;
 	inode->i_fop = &ext3_dir_operations;
 	inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
-	inode->i_blocks = 0;	
 	dir_block = ext3_bread (handle, inode, 0, 1, &err);
 	if (!dir_block) {
 		inode->i_nlink--; /* is this nlink == 0? */
@@ -1689,9 +1692,6 @@
 	BUFFER_TRACE(dir_block, "call ext3_journal_dirty_metadata");
 	ext3_journal_dirty_metadata(handle, dir_block);
 	brelse (dir_block);
-	inode->i_mode = S_IFDIR | mode;
-	if (dir->i_mode & S_ISGID)
-		inode->i_mode |= S_ISGID;
 	ext3_mark_inode_dirty(handle, inode);
 	err = ext3_add_entry (handle, dentry, inode);
 	if (err) {
@@ -2068,7 +2068,7 @@
 		goto out_stop;
 
 	if (l > sizeof (EXT3_I(inode)->i_data)) {
-		inode->i_op = &page_symlink_inode_operations;
+		inode->i_op = &ext3_symlink_inode_operations;
 		if (ext3_should_writeback_data(inode))
 			inode->i_mapping->a_ops = &ext3_writeback_aops;
 		else
@@ -2284,4 +2284,21 @@
 	.rmdir		= ext3_rmdir,
 	.mknod		= ext3_mknod,
 	.rename		= ext3_rename,
+	.setattr	= ext3_setattr,
+	.setxattr	= ext3_setxattr,	
+	.getxattr	= ext3_getxattr,	
+	.listxattr	= ext3_listxattr,	
+	.removexattr	= ext3_removexattr,
+	.permission	= ext3_permission,
 };
+
+struct inode_operations ext3_special_inode_operations = {
+	.setattr	= ext3_setattr,
+	.setxattr	= ext3_setxattr,
+	.getxattr	= ext3_getxattr,
+	.listxattr	= ext3_listxattr,
+	.removexattr	= ext3_removexattr,
+	.permission	= ext3_permission,
+};
+
+ 
diff -Nru a/fs/ext3/super.c b/fs/ext3/super.c
--- a/fs/ext3/super.c	Mon Nov  4 14:31:02 2002
+++ b/fs/ext3/super.c	Mon Nov  4 14:31:02 2002
@@ -30,6 +30,8 @@
 #include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
 #include <asm/uaccess.h>
+#include "xattr.h"
+#include "acl.h"
 
 #ifdef CONFIG_JBD_DEBUG
 static int ext3_ro_after; /* Make fs read-only after this many jiffies */
@@ -105,32 +107,6 @@
 
 static char error_buf[1024];
 
-/* Determine the appropriate response to ext3_error on a given filesystem */
-
-static int ext3_error_behaviour(struct super_block *sb)
-{
-	/* First check for mount-time options */
-	if (test_opt (sb, ERRORS_PANIC))
-		return EXT3_ERRORS_PANIC;
-	if (test_opt (sb, ERRORS_RO))
-		return EXT3_ERRORS_RO;
-	if (test_opt (sb, ERRORS_CONT))
-		return EXT3_ERRORS_CONTINUE;
-	
-	/* If no overrides were specified on the mount, then fall back
-	 * to the default behaviour set in the filesystem's superblock
-	 * on disk. */
-	switch (le16_to_cpu(EXT3_SB(sb)->s_es->s_errors)) {
-	case EXT3_ERRORS_PANIC:
-		return EXT3_ERRORS_PANIC;
-	case EXT3_ERRORS_RO:
-		return EXT3_ERRORS_RO;
-	default:
-		break;
-	}
-	return EXT3_ERRORS_CONTINUE;
-}
-
 /* Deal with the reporting of failure conditions on a filesystem such as
  * inconsistencies detected or read IO failures.
  *
@@ -156,20 +132,16 @@
 	if (sb->s_flags & MS_RDONLY)
 		return;
 
-	if (ext3_error_behaviour(sb) != EXT3_ERRORS_CONTINUE) {
-		EXT3_SB(sb)->s_mount_opt |= EXT3_MOUNT_ABORT;
-		journal_abort(EXT3_SB(sb)->s_journal, -EIO);
-	}
-
-	if (ext3_error_behaviour(sb) == EXT3_ERRORS_PANIC) 
+	if (test_opt (sb, ERRORS_PANIC))
 		panic ("EXT3-fs (device %s): panic forced after error\n",
 		       sb->s_id);
-
-	if (ext3_error_behaviour(sb) == EXT3_ERRORS_RO) {
+	if (test_opt (sb, ERRORS_RO)) {
 		printk (KERN_CRIT "Remounting filesystem read-only\n");
 		sb->s_flags |= MS_RDONLY;
+	} else {
+		EXT3_SB(sb)->s_mount_opt |= EXT3_MOUNT_ABORT;
+		journal_abort(EXT3_SB(sb)->s_journal, -EIO);
 	}
-
 	ext3_commit_super(sb, es, 1);
 }
 
@@ -257,7 +229,7 @@
 	vsprintf (error_buf, fmt, args);
 	va_end (args);
 
-	if (ext3_error_behaviour(sb) == EXT3_ERRORS_PANIC)
+	if (test_opt (sb, ERRORS_PANIC))
 		panic ("EXT3-fs panic (device %s): %s: %s\n",
 		       sb->s_id, function, error_buf);
 
@@ -405,6 +377,7 @@
 	struct ext3_super_block *es = sbi->s_es;
 	int i;
 
+	ext3_xattr_put_super(sb);
 	journal_destroy(sbi->s_journal);
 	if (!(sb->s_flags & MS_RDONLY)) {
 		EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
@@ -417,6 +390,7 @@
 	for (i = 0; i < sbi->s_gdb_count; i++)
 		brelse(sbi->s_group_desc[i]);
 	kfree(sbi->s_group_desc);
+	kfree(sbi->s_debts);
 	brelse(sbi->s_sbh);
 
 	/* Debugging code just in case the in-memory inode orphan list
@@ -456,6 +430,10 @@
 	ei = kmem_cache_alloc(ext3_inode_cachep, SLAB_NOFS);
 	if (!ei)
 		return NULL;
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
+	ei->i_acl = EXT3_ACL_NOT_CACHED;
+	ei->i_default_acl = EXT3_ACL_NOT_CACHED;
+#endif
 	return &ei->vfs_inode;
 }
 
@@ -493,6 +471,26 @@
 		printk(KERN_INFO "ext3_inode_cache: not all structures were freed\n");
 }
 
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
+
+static void ext3_clear_inode(struct inode *inode)
+{
+       if (EXT3_I(inode)->i_acl &&
+           EXT3_I(inode)->i_acl != EXT3_ACL_NOT_CACHED) {
+               posix_acl_release(EXT3_I(inode)->i_acl);
+               EXT3_I(inode)->i_acl = EXT3_ACL_NOT_CACHED;
+       }
+       if (EXT3_I(inode)->i_default_acl &&
+           EXT3_I(inode)->i_default_acl != EXT3_ACL_NOT_CACHED) {
+               posix_acl_release(EXT3_I(inode)->i_default_acl);
+               EXT3_I(inode)->i_default_acl = EXT3_ACL_NOT_CACHED;
+       }
+}
+
+#else
+# define ext3_clear_inode NULL
+#endif
+
 static struct super_operations ext3_sops = {
 	.alloc_inode	= ext3_alloc_inode,
 	.destroy_inode	= ext3_destroy_inode,
@@ -507,6 +505,7 @@
 	.unlockfs	= ext3_unlockfs,		/* BKL not held.  We take it */
 	.statfs		= ext3_statfs,		/* BKL not held. */
 	.remount_fs	= ext3_remount,		/* BKL held */
+	.clear_inode	= ext3_clear_inode,	/* BKL not needed. */
 };
 
 struct dentry *ext3_get_parent(struct dentry *child);
@@ -545,17 +544,32 @@
 	return 0;
 }
 
+static unsigned long get_sb_block(void **data)
+{
+	unsigned long 	sb_block;
+	char 		*options = (char *) *data;
+
+	if (!options || strncmp(options, "sb=", 3) != 0)
+		return 1;	/* Default location */
+	options += 3;
+	sb_block = simple_strtoul(options, &options, 0);
+	if (*options && *options != ',') {
+		printk("EXT3-fs: Invalid sb specification: %s\n",
+		       (char *) *data);
+		return 1;
+	}
+	if (*options == ',')
+		options++;
+	*data = (void *) options;
+	return sb_block;
+}
+
 /*
  * This function has been shamelessly adapted from the msdos fs
  */
-static int parse_options (char * options, unsigned long * sb_block,
-			  struct ext3_sb_info *sbi,
-			  unsigned long * inum,
-			  int is_remount)
-{
-	unsigned long *mount_options = &sbi->s_mount_opt;
-	uid_t *resuid = &sbi->s_resuid;
-	gid_t *resgid = &sbi->s_resgid;
+static int parse_options (char * options, struct ext3_sb_info *sbi,
+			  unsigned long * inum, int is_remount)
+{
 	char * this_char;
 	char * value;
 
@@ -566,43 +580,57 @@
 			continue;
 		if ((value = strchr (this_char, '=')) != NULL)
 			*value++ = 0;
+#ifdef CONFIG_EXT3_FS_XATTR
+		if (!strcmp (this_char, "user_xattr"))
+			set_opt (sbi->s_mount_opt, XATTR_USER);
+		else if (!strcmp (this_char, "nouser_xattr"))
+			clear_opt (sbi->s_mount_opt, XATTR_USER);
+		else
+#endif
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
+		if (!strcmp(this_char, "acl"))
+			set_opt (sbi->s_mount_opt, POSIX_ACL);
+		else if (!strcmp(this_char, "noacl"))
+			clear_opt (sbi->s_mount_opt, POSIX_ACL);
+		else
+#endif
 		if (!strcmp (this_char, "bsddf"))
-			clear_opt (*mount_options, MINIX_DF);
+			clear_opt (sbi->s_mount_opt, MINIX_DF);
 		else if (!strcmp (this_char, "nouid32")) {
-			set_opt (*mount_options, NO_UID32);
+			set_opt (sbi->s_mount_opt, NO_UID32);
 		}
 		else if (!strcmp (this_char, "abort"))
-			set_opt (*mount_options, ABORT);
+			set_opt (sbi->s_mount_opt, ABORT);
 		else if (!strcmp (this_char, "check")) {
 			if (!value || !*value || !strcmp (value, "none"))
-				clear_opt (*mount_options, CHECK);
+				clear_opt (sbi->s_mount_opt, CHECK);
 			else
 #ifdef CONFIG_EXT3_CHECK
-				set_opt (*mount_options, CHECK);
+				set_opt (sbi->s_mount_opt, CHECK);
 #else
 				printk(KERN_ERR 
 				       "EXT3 Check option not supported\n");
 #endif
 		}
 		else if (!strcmp (this_char, "debug"))
-			set_opt (*mount_options, DEBUG);
+			set_opt (sbi->s_mount_opt, DEBUG);
 		else if (!strcmp (this_char, "errors")) {
 			if (want_value(value, "errors"))
 				return 0;
 			if (!strcmp (value, "continue")) {
-				clear_opt (*mount_options, ERRORS_RO);
-				clear_opt (*mount_options, ERRORS_PANIC);
-				set_opt (*mount_options, ERRORS_CONT);
+				clear_opt (sbi->s_mount_opt, ERRORS_RO);
+				clear_opt (sbi->s_mount_opt, ERRORS_PANIC);
+				set_opt (sbi->s_mount_opt, ERRORS_CONT);
 			}
 			else if (!strcmp (value, "remount-ro")) {
-				clear_opt (*mount_options, ERRORS_CONT);
-				clear_opt (*mount_options, ERRORS_PANIC);
-				set_opt (*mount_options, ERRORS_RO);
+				clear_opt (sbi->s_mount_opt, ERRORS_CONT);
+				clear_opt (sbi->s_mount_opt, ERRORS_PANIC);
+				set_opt (sbi->s_mount_opt, ERRORS_RO);
 			}
 			else if (!strcmp (value, "panic")) {
-				clear_opt (*mount_options, ERRORS_CONT);
-				clear_opt (*mount_options, ERRORS_RO);
-				set_opt (*mount_options, ERRORS_PANIC);
+				clear_opt (sbi->s_mount_opt, ERRORS_CONT);
+				clear_opt (sbi->s_mount_opt, ERRORS_RO);
+				set_opt (sbi->s_mount_opt, ERRORS_PANIC);
 			}
 			else {
 				printk (KERN_ERR
@@ -613,29 +641,25 @@
 		}
 		else if (!strcmp (this_char, "grpid") ||
 			 !strcmp (this_char, "bsdgroups"))
-			set_opt (*mount_options, GRPID);
+			set_opt (sbi->s_mount_opt, GRPID);
 		else if (!strcmp (this_char, "minixdf"))
-			set_opt (*mount_options, MINIX_DF);
+			set_opt (sbi->s_mount_opt, MINIX_DF);
 		else if (!strcmp (this_char, "nocheck"))
-			clear_opt (*mount_options, CHECK);
+			clear_opt (sbi->s_mount_opt, CHECK);
 		else if (!strcmp (this_char, "nogrpid") ||
 			 !strcmp (this_char, "sysvgroups"))
-			clear_opt (*mount_options, GRPID);
+			clear_opt (sbi->s_mount_opt, GRPID);
 		else if (!strcmp (this_char, "resgid")) {
 			unsigned long v;
 			if (want_numeric(value, "resgid", &v))
 				return 0;
-			*resgid = v;
+			sbi->s_resgid = v;
 		}
 		else if (!strcmp (this_char, "resuid")) {
 			unsigned long v;
 			if (want_numeric(value, "resuid", &v))
 				return 0;
-			*resuid = v;
-		}
-		else if (!strcmp (this_char, "sb")) {
-			if (want_numeric(value, "sb", sb_block))
-				return 0;
+			sbi->s_resuid = v;
 		}
 #ifdef CONFIG_JBD_DEBUG
 		else if (!strcmp (this_char, "ro-after")) {
@@ -666,12 +690,12 @@
 			if (want_value(value, "journal"))
 				return 0;
 			if (!strcmp (value, "update"))
-				set_opt (*mount_options, UPDATE_JOURNAL);
+				set_opt (sbi->s_mount_opt, UPDATE_JOURNAL);
 			else if (want_numeric(value, "journal", inum))
 				return 0;
 		}
 		else if (!strcmp (this_char, "noload"))
-			set_opt (*mount_options, NOLOAD);
+			set_opt (sbi->s_mount_opt, NOLOAD);
 		else if (!strcmp (this_char, "data")) {
 			int data_opt = 0;
 
@@ -690,7 +714,7 @@
 				return 0;
 			}
 			if (is_remount) {
-				if ((*mount_options & EXT3_MOUNT_DATA_FLAGS) !=
+				if ((sbi->s_mount_opt & EXT3_MOUNT_DATA_FLAGS) !=
 							data_opt) {
 					printk(KERN_ERR
 					       "EXT3-fs: cannot change data "
@@ -698,8 +722,8 @@
 					return 0;
 				}
 			} else {
-				*mount_options &= ~EXT3_MOUNT_DATA_FLAGS;
-				*mount_options |= data_opt;
+				sbi->s_mount_opt &= ~EXT3_MOUNT_DATA_FLAGS;
+				sbi->s_mount_opt |= data_opt;
 			}
 		} else if (!strcmp (this_char, "commit")) {
 			unsigned long v;
@@ -948,16 +972,34 @@
 	return res;
 }
 
+static unsigned long descriptor_loc(struct super_block *sb,
+				    unsigned long logic_sb_block,
+				    int nr)
+{
+	struct ext3_sb_info *sbi = EXT3_SB(sb);
+	unsigned long bg, first_data_block, first_meta_bg;
+	
+	first_data_block = le32_to_cpu(sbi->s_es->s_first_data_block);
+	first_meta_bg = le32_to_cpu(sbi->s_es->s_first_meta_bg);
+
+	if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_META_BG) ||
+	    nr < first_meta_bg)
+		return (logic_sb_block + nr + 1);
+	bg = sbi->s_desc_per_block * nr;
+	return (first_data_block + 1 + (bg * sbi->s_blocks_per_group));
+}
+
 
 static int ext3_fill_super (struct super_block *sb, void *data, int silent)
 {
 	struct buffer_head * bh;
 	struct ext3_super_block *es = 0;
 	struct ext3_sb_info *sbi;
-	unsigned long sb_block = 1;
-	unsigned long logic_sb_block = 1;
+	unsigned long sb_block = get_sb_block(&data);
+	unsigned long block, logic_sb_block = 1;
 	unsigned long offset = 0;
 	unsigned long journal_inum = 0;
+	unsigned long def_mount_opts;
 	int blocksize;
 	int hblock;
 	int db_count;
@@ -967,13 +1009,6 @@
 #ifdef CONFIG_JBD_DEBUG
 	ext3_ro_after = 0;
 #endif
-	/*
-	 * See what the current blocksize for the device is, and
-	 * use that as the blocksize.  Otherwise (or if the blocksize
-	 * is smaller than the default) use the default.
-	 * This is important for devices that have a hardware
-	 * sectorsize that is larger than the default.
-	 */
 	sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
 	if (!sbi)
 		return -ENOMEM;
@@ -982,8 +1017,6 @@
 	sbi->s_mount_opt = 0;
 	sbi->s_resuid = EXT3_DEF_RESUID;
 	sbi->s_resgid = EXT3_DEF_RESGID;
-	if (!parse_options ((char *) data, &sb_block, sbi, &journal_inum, 0))
-		goto out_fail;
 
 	blocksize = sb_min_blocksize(sb, EXT3_MIN_BLOCK_SIZE);
 	if (!blocksize) {
@@ -1018,6 +1051,40 @@
 			       sb->s_id);
 		goto failed_mount;
 	}
+	
+	/* Set defaults before we parse the mount options */
+	def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
+	if (def_mount_opts & EXT3_DEFM_DEBUG)
+		set_opt(sbi->s_mount_opt, DEBUG);
+	if (def_mount_opts & EXT3_DEFM_BSDGROUPS)
+		set_opt(sbi->s_mount_opt, GRPID);
+	if (def_mount_opts & EXT3_DEFM_UID16)
+		set_opt(sbi->s_mount_opt, NO_UID32);
+	if (def_mount_opts & EXT3_DEFM_XATTR_USER)
+		set_opt(sbi->s_mount_opt, XATTR_USER);
+	if (def_mount_opts & EXT3_DEFM_ACL)
+		set_opt(sbi->s_mount_opt, POSIX_ACL);
+	if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_DATA)
+		sbi->s_mount_opt |= EXT3_MOUNT_JOURNAL_DATA;
+	else if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_ORDERED)
+		sbi->s_mount_opt |= EXT3_MOUNT_ORDERED_DATA;
+	else if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_WBACK)
+		sbi->s_mount_opt |= EXT3_MOUNT_WRITEBACK_DATA;
+
+	if (le16_to_cpu(sbi->s_es->s_errors) == EXT3_ERRORS_PANIC)
+		set_opt(sbi->s_mount_opt, ERRORS_PANIC);
+	else if (le16_to_cpu(sbi->s_es->s_errors) == EXT3_ERRORS_RO)
+		set_opt(sbi->s_mount_opt, ERRORS_RO);
+	
+	sbi->s_resuid = le16_to_cpu(es->s_def_resuid);
+	sbi->s_resgid = le16_to_cpu(es->s_def_resgid);
+
+	if (!parse_options ((char *) data, sbi, &journal_inum, 0))
+		goto failed_mount;
+
+	sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
+		((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
+
 	if (le32_to_cpu(es->s_rev_level) == EXT3_GOOD_OLD_REV &&
 	    (EXT3_HAS_COMPAT_FEATURE(sb, ~0U) ||
 	     EXT3_HAS_RO_COMPAT_FEATURE(sb, ~0U) ||
@@ -1092,7 +1159,9 @@
 	} else {
 		sbi->s_inode_size = le16_to_cpu(es->s_inode_size);
 		sbi->s_first_ino = le32_to_cpu(es->s_first_ino);
-		if (sbi->s_inode_size != EXT3_GOOD_OLD_INODE_SIZE) {
+		if ((sbi->s_inode_size < EXT3_GOOD_OLD_INODE_SIZE) ||
+		    (sbi->s_inode_size & (sbi->s_inode_size - 1)) ||
+		    (sbi->s_inode_size > blocksize)) {
 			printk (KERN_ERR
 				"EXT3-fs: unsupported inode size: %d\n",
 				sbi->s_inode_size);
@@ -1115,10 +1184,6 @@
 	sbi->s_itb_per_group = sbi->s_inodes_per_group /sbi->s_inodes_per_block;
 	sbi->s_desc_per_block = blocksize / sizeof(struct ext3_group_desc);
 	sbi->s_sbh = bh;
-	if (sbi->s_resuid == EXT3_DEF_RESUID)
-		sbi->s_resuid = le16_to_cpu(es->s_def_resuid);
-	if (sbi->s_resgid == EXT3_DEF_RESGID)
-		sbi->s_resgid = le16_to_cpu(es->s_def_resgid);
 	sbi->s_mount_state = le16_to_cpu(es->s_state);
 	sbi->s_addr_per_block_bits = log2(EXT3_ADDR_PER_BLOCK(sb));
 	sbi->s_desc_per_block_bits = log2(EXT3_DESC_PER_BLOCK(sb));
@@ -1157,8 +1222,16 @@
 		printk (KERN_ERR "EXT3-fs: not enough memory\n");
 		goto failed_mount;
 	}
+	sbi->s_debts = kmalloc(sbi->s_groups_count * sizeof(*sbi->s_debts),
+			GFP_KERNEL);
+	if (!sbi->s_debts) {
+		printk ("EXT3-fs: not enough memory\n");
+		goto failed_mount2;
+	}
+	memset(sbi->s_debts, 0, sbi->s_groups_count * sizeof(*sbi->s_debts));
 	for (i = 0; i < db_count; i++) {
-		sbi->s_group_desc[i] = sb_bread(sb, logic_sb_block + i + 1);
+		block = descriptor_loc(sb, logic_sb_block, i);
+		sbi->s_group_desc[i] = sb_bread(sb, block);
 		if (!sbi->s_group_desc[i]) {
 			printk (KERN_ERR "EXT3-fs: "
 				"can't read group descriptor %d\n", i);
@@ -1171,6 +1244,7 @@
 		goto failed_mount2;
 	}
 	sbi->s_gdb_count = db_count;
+	sbi->s_dir_count = ext3_count_dirs(sb);
 	/*
 	 * set up enough so that it can read an inode
 	 */
@@ -1274,6 +1348,8 @@
 failed_mount3:
 	journal_destroy(sbi->s_journal);
 failed_mount2:
+	if (sbi->s_debts)
+		kfree(sbi->s_debts);
 	for (i = 0; i < db_count; i++)
 		brelse(sbi->s_group_desc[i]);
 	kfree(sbi->s_group_desc);
@@ -1702,12 +1778,15 @@
 	/*
 	 * Allow the "check" option to be passed as a remount option.
 	 */
-	if (!parse_options(data, &tmp, sbi, &tmp, 1))
+	if (!parse_options(data, sbi, &tmp, 1))
 		return -EINVAL;
 
 	if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
 		ext3_abort(sb, __FUNCTION__, "Abort forced by user");
 
+	sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
+		((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
+
 	es = sbi->s_es;
 
 	ext3_init_journal_params(sbi, sbi->s_journal);
@@ -1824,7 +1903,10 @@
 
 static int __init init_ext3_fs(void)
 {
-	int err = init_inodecache();
+	int err = init_ext3_xattr();
+	if (err)
+		return err;
+	err = init_inodecache();
 	if (err)
 		goto out1;
         err = register_filesystem(&ext3_fs_type);
@@ -1834,6 +1916,7 @@
 out:
 	destroy_inodecache();
 out1:
+ 	exit_ext3_xattr();
 	return err;
 }
 
@@ -1841,6 +1924,7 @@
 {
 	unregister_filesystem(&ext3_fs_type);
 	destroy_inodecache();
+	exit_ext3_xattr();
 }
 
 MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
diff -Nru a/fs/ext3/symlink.c b/fs/ext3/symlink.c
--- a/fs/ext3/symlink.c	Mon Nov  4 14:31:02 2002
+++ b/fs/ext3/symlink.c	Mon Nov  4 14:31:02 2002
@@ -20,6 +20,7 @@
 #include <linux/fs.h>
 #include <linux/jbd.h>
 #include <linux/ext3_fs.h>
+#include "xattr.h"
 
 static int ext3_readlink(struct dentry *dentry, char *buffer, int buflen)
 {
@@ -33,7 +34,20 @@
 	return vfs_follow_link(nd, (char*)ei->i_data);
 }
 
+struct inode_operations ext3_symlink_inode_operations = {
+	.readlink	= page_readlink,
+	.follow_link	= page_follow_link,
+	.setxattr	= ext3_setxattr,
+	.getxattr	= ext3_getxattr,
+	.listxattr	= ext3_listxattr,
+	.removexattr	= ext3_removexattr,
+};
+
 struct inode_operations ext3_fast_symlink_inode_operations = {
-	.readlink	= ext3_readlink,		/* BKL not held.  Don't need */
+	.readlink	= ext3_readlink,	/* BKL not held.  Don't need */
 	.follow_link	= ext3_follow_link,	/* BKL not held.  Don't need */
+	.setxattr	= ext3_setxattr,
+	.getxattr	= ext3_getxattr,
+	.listxattr	= ext3_listxattr,
+	.removexattr	= ext3_removexattr,
 };
diff -Nru a/fs/ext3/xattr.c b/fs/ext3/xattr.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/ext3/xattr.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,1142 @@
+/*
+ * linux/fs/ext3/xattr.c
+ *
+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
+ *
+ * Fix by Harrison Xing <harrison@mountainviewdata.com>.
+ * Ext3 code with a lot of help from Eric Jarman <ejarman@acm.org>.
+ * Extended attributes for symlinks and special files added per
+ *  suggestion of Luka Renko <luka.renko@hermes.si>.
+ */
+
+/*
+ * Extended attributes are stored on disk blocks allocated outside of
+ * any inode. The i_file_acl field is then made to point to this allocated
+ * block. If all extended attributes of an inode are identical, these
+ * inodes may share the same extended attribute block. Such situations
+ * are automatically detected by keeping a cache of recent attribute block
+ * numbers and hashes over the block's contents in memory.
+ *
+ *
+ * Extended attribute block layout:
+ *
+ *   +------------------+
+ *   | header           |
+ *   ¦ entry 1          | |
+ *   | entry 2          | | growing downwards
+ *   | entry 3          | v
+ *   | four null bytes  |
+ *   | . . .            |
+ *   | value 1          | ^
+ *   | value 3          | | growing upwards
+ *   | value 2          | |
+ *   +------------------+
+ *
+ * The block header is followed by multiple entry descriptors. These entry
+ * descriptors are variable in size, and alligned to EXT3_XATTR_PAD
+ * byte boundaries. The entry descriptors are sorted by attribute name,
+ * so that two extended attribute blocks can be compared efficiently.
+ *
+ * Attribute values are aligned to the end of the block, stored in
+ * no specific order. They are also padded to EXT3_XATTR_PAD byte
+ * boundaries. No additional gaps are left between them.
+ *
+ * Locking strategy
+ * ----------------
+ * The VFS holdsinode->i_sem semaphore when any of the xattr inode
+ * operations are called, so we are guaranteed that only one
+ * processes accesses extended attributes of an inode at any time.
+ *
+ * For writing we also grab the ext3_xattr_sem semaphore. This ensures that
+ * only a single process is modifying an extended attribute block, even
+ * if the block is shared among inodes.
+ */
+
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/ext3_jbd.h>
+#include <linux/ext3_fs.h>
+#include <linux/mbcache.h>
+#include <linux/quotaops.h>
+#include <asm/semaphore.h>
+#include "xattr.h"
+#include "acl.h"
+
+#define EXT3_EA_USER "user."
+
+#define HDR(bh) ((struct ext3_xattr_header *)((bh)->b_data))
+#define ENTRY(ptr) ((struct ext3_xattr_entry *)(ptr))
+#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1)
+#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
+
+#ifdef EXT3_XATTR_DEBUG
+# define ea_idebug(inode, f...) do { \
+		printk(KERN_DEBUG "inode %s:%ld: ", \
+			kdevname(inode->i_dev), inode->i_ino); \
+		printk(f); \
+		printk("\n"); \
+	} while (0)
+# define ea_bdebug(bh, f...) do { \
+		printk(KERN_DEBUG "block %s:%ld: ", \
+			kdevname(bh->b_dev), bh->b_blocknr); \
+		printk(f); \
+		printk("\n"); \
+	} while (0)
+#else
+# define ea_idebug(f...)
+# define ea_bdebug(f...)
+#endif
+
+static int ext3_xattr_set2(handle_t *, struct inode *, struct buffer_head *,
+			   struct ext3_xattr_header *);
+
+static int ext3_xattr_cache_insert(struct buffer_head *);
+static struct buffer_head *ext3_xattr_cache_find(struct inode *,
+						 struct ext3_xattr_header *);
+static void ext3_xattr_cache_remove(struct buffer_head *);
+static void ext3_xattr_rehash(struct ext3_xattr_header *,
+			      struct ext3_xattr_entry *);
+
+static struct mb_cache *ext3_xattr_cache;
+
+/*
+ * If a file system does not share extended attributes among inodes,
+ * we should not need the ext3_xattr_sem semaphore. However, the
+ * filesystem may still contain shared blocks, so we always take
+ * the lock.
+ */
+
+static DECLARE_MUTEX(ext3_xattr_sem);
+static struct ext3_xattr_handler *ext3_xattr_handlers[EXT3_XATTR_INDEX_MAX];
+static rwlock_t ext3_handler_lock = RW_LOCK_UNLOCKED;
+
+int
+ext3_xattr_register(int name_index, struct ext3_xattr_handler *handler)
+{
+	int error = -EINVAL;
+
+	if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) {
+		write_lock(&ext3_handler_lock);
+		if (!ext3_xattr_handlers[name_index-1]) {
+			ext3_xattr_handlers[name_index-1] = handler;
+			error = 0;
+		}
+		write_unlock(&ext3_handler_lock);
+	}
+	return error;
+}
+
+void
+ext3_xattr_unregister(int name_index, struct ext3_xattr_handler *handler)
+{
+	if (name_index > 0 || name_index <= EXT3_XATTR_INDEX_MAX) {
+		write_lock(&ext3_handler_lock);
+		ext3_xattr_handlers[name_index-1] = NULL;
+		write_unlock(&ext3_handler_lock);
+	}
+}
+
+static inline const char *
+strcmp_prefix(const char *a, const char *a_prefix)
+{
+	while (*a_prefix && *a == *a_prefix) {
+		a++;
+		a_prefix++;
+	}
+	return *a_prefix ? NULL : a;
+}
+
+/*
+ * Decode the extended attribute name, and translate it into
+ * the name_index and name suffix.
+ */
+static inline struct ext3_xattr_handler *
+ext3_xattr_resolve_name(const char **name)
+{
+	struct ext3_xattr_handler *handler = NULL;
+	int i;
+
+	if (!*name)
+		return NULL;
+	read_lock(&ext3_handler_lock);
+	for (i=0; i<EXT3_XATTR_INDEX_MAX; i++) {
+		if (ext3_xattr_handlers[i]) {
+			const char *n = strcmp_prefix(*name,
+				ext3_xattr_handlers[i]->prefix);
+			if (n) {
+				handler = ext3_xattr_handlers[i];
+				*name = n;
+				break;
+			}
+		}
+	}
+	read_unlock(&ext3_handler_lock);
+	return handler;
+}
+
+static inline struct ext3_xattr_handler *
+ext3_xattr_handler(int name_index)
+{
+	struct ext3_xattr_handler *handler = NULL;
+	if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) {
+		read_lock(&ext3_handler_lock);
+		handler = ext3_xattr_handlers[name_index-1];
+		read_unlock(&ext3_handler_lock);
+	}
+	return handler;
+}
+
+/*
+ * Inode operation getxattr()
+ *
+ * dentry->d_inode->i_sem down
+ */
+ssize_t
+ext3_getxattr(struct dentry *dentry, const char *name,
+	      void *buffer, size_t size)
+{
+	struct ext3_xattr_handler *handler;
+	struct inode *inode = dentry->d_inode;
+
+	handler = ext3_xattr_resolve_name(&name);
+	if (!handler)
+		return -EOPNOTSUPP;
+	return handler->get(inode, name, buffer, size);
+}
+
+/*
+ * Inode operation listxattr()
+ *
+ * dentry->d_inode->i_sem down
+ */
+ssize_t
+ext3_listxattr(struct dentry *dentry, char *buffer, size_t size)
+{
+	return ext3_xattr_list(dentry->d_inode, buffer, size);
+}
+
+/*
+ * Inode operation setxattr()
+ *
+ * dentry->d_inode->i_sem down
+ */
+int
+ext3_setxattr(struct dentry *dentry, const char *name,
+	      void *value, size_t size, int flags)
+{
+	struct ext3_xattr_handler *handler;
+	struct inode *inode = dentry->d_inode;
+
+	if (size == 0)
+		value = "";  /* empty EA, do not remove */
+	handler = ext3_xattr_resolve_name(&name);
+	if (!handler)
+		return -EOPNOTSUPP;
+	return handler->set(inode, name, value, size, flags);
+}
+
+/*
+ * Inode operation removexattr()
+ *
+ * dentry->d_inode->i_sem down
+ */
+int
+ext3_removexattr(struct dentry *dentry, const char *name)
+{
+	struct ext3_xattr_handler *handler;
+	struct inode *inode = dentry->d_inode;
+
+	handler = ext3_xattr_resolve_name(&name);
+	if (!handler)
+		return -EOPNOTSUPP;
+	return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
+}
+
+/*
+ * ext3_xattr_get()
+ *
+ * Copy an extended attribute into the buffer
+ * provided, or compute the buffer size required.
+ * Buffer is NULL to compute the size of the buffer required.
+ *
+ * Returns a negative error number on failure, or the number of bytes
+ * used / required on success.
+ */
+int
+ext3_xattr_get(struct inode *inode, int name_index, const char *name,
+	       void *buffer, size_t buffer_size)
+{
+	struct buffer_head *bh = NULL;
+	struct ext3_xattr_entry *entry;
+	unsigned int size;
+	char *end;
+	int name_len, error;
+
+	ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
+		  name_index, name, buffer, (long)buffer_size);
+
+	if (name == NULL)
+		return -EINVAL;
+	if (!EXT3_I(inode)->i_file_acl)
+		return -ENODATA;
+	ea_idebug(inode, "reading block %d", EXT3_I(inode)->i_file_acl);
+	bh = sb_bread(inode->i_sb, EXT3_I(inode)->i_file_acl);
+	if (!bh)
+		return -EIO;
+	ea_bdebug(bh, "b_count=%d, refcount=%d",
+		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
+	end = bh->b_data + bh->b_size;
+	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
+	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
+bad_block:	ext3_error(inode->i_sb, "ext3_xattr_get",
+			"inode %ld: bad block %d", inode->i_ino,
+			EXT3_I(inode)->i_file_acl);
+		error = -EIO;
+		goto cleanup;
+	}
+	/* find named attribute */
+	name_len = strlen(name);
+
+	error = -ERANGE;
+	if (name_len > 255)
+		goto cleanup;
+	entry = FIRST_ENTRY(bh);
+	while (!IS_LAST_ENTRY(entry)) {
+		struct ext3_xattr_entry *next =
+			EXT3_XATTR_NEXT(entry);
+		if ((char *)next >= end)
+			goto bad_block;
+		if (name_index == entry->e_name_index &&
+		    name_len == entry->e_name_len &&
+		    memcmp(name, entry->e_name, name_len) == 0)
+			goto found;
+		entry = next;
+	}
+	/* Check the remaining name entries */
+	while (!IS_LAST_ENTRY(entry)) {
+		struct ext3_xattr_entry *next =
+			EXT3_XATTR_NEXT(entry);
+		if ((char *)next >= end)
+			goto bad_block;
+		entry = next;
+	}
+	if (ext3_xattr_cache_insert(bh))
+		ea_idebug(inode, "cache insert failed");
+	error = -ENODATA;
+	goto cleanup;
+found:
+	/* check the buffer size */
+	if (entry->e_value_block != 0)
+		goto bad_block;
+	size = le32_to_cpu(entry->e_value_size);
+	if (size > inode->i_sb->s_blocksize ||
+	    le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize)
+		goto bad_block;
+
+	if (ext3_xattr_cache_insert(bh))
+		ea_idebug(inode, "cache insert failed");
+	if (buffer) {
+		error = -ERANGE;
+		if (size > buffer_size)
+			goto cleanup;
+		/* return value of attribute */
+		memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
+			size);
+	}
+	error = size;
+
+cleanup:
+	brelse(bh);
+
+	return error;
+}
+
+/*
+ * ext3_xattr_list()
+ *
+ * Copy a list of attribute names into the buffer
+ * provided, or compute the buffer size required.
+ * Buffer is NULL to compute the size of the buffer required.
+ *
+ * Returns a negative error number on failure, or the number of bytes
+ * used / required on success.
+ */
+int
+ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
+{
+	struct buffer_head *bh = NULL;
+	struct ext3_xattr_entry *entry;
+	unsigned int size = 0;
+	char *buf, *end;
+	int error;
+
+	ea_idebug(inode, "buffer=%p, buffer_size=%ld",
+		  buffer, (long)buffer_size);
+
+	if (!EXT3_I(inode)->i_file_acl)
+		return 0;
+	ea_idebug(inode, "reading block %d", EXT3_I(inode)->i_file_acl);
+	bh = sb_bread(inode->i_sb, EXT3_I(inode)->i_file_acl);
+	if (!bh)
+		return -EIO;
+	ea_bdebug(bh, "b_count=%d, refcount=%d",
+		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
+	end = bh->b_data + bh->b_size;
+	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
+	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
+bad_block:	ext3_error(inode->i_sb, "ext3_xattr_list",
+			"inode %ld: bad block %d", inode->i_ino,
+			EXT3_I(inode)->i_file_acl);
+		error = -EIO;
+		goto cleanup;
+	}
+	/* compute the size required for the list of attribute names */
+	for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
+	     entry = EXT3_XATTR_NEXT(entry)) {
+		struct ext3_xattr_handler *handler;
+		struct ext3_xattr_entry *next =
+			EXT3_XATTR_NEXT(entry);
+		if ((char *)next >= end)
+			goto bad_block;
+
+		handler = ext3_xattr_handler(entry->e_name_index);
+		if (handler) {
+			size += handler->list(NULL, inode, entry->e_name,
+					      entry->e_name_len) + 1;
+		}
+	}
+
+	if (ext3_xattr_cache_insert(bh))
+		ea_idebug(inode, "cache insert failed");
+	if (!buffer) {
+		error = size;
+		goto cleanup;
+	} else {
+		error = -ERANGE;
+		if (size > buffer_size)
+			goto cleanup;
+	}
+
+	/* list the attribute names */
+	buf = buffer;
+	for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
+	     entry = EXT3_XATTR_NEXT(entry)) {
+		struct ext3_xattr_handler *handler;
+
+		handler = ext3_xattr_handler(entry->e_name_index);
+		if (handler) {
+			buf += handler->list(buf, inode, entry->e_name,
+					     entry->e_name_len);
+			*buf++ = '\0';
+		}
+	}
+	error = size;
+
+cleanup:
+	brelse(bh);
+
+	return error;
+}
+
+/*
+ * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is
+ * not set, set it.
+ */
+static void ext3_xattr_update_super_block(handle_t *handle,
+					  struct super_block *sb)
+{
+	if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR))
+		return;
+
+	lock_super(sb);
+	ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
+	EXT3_SB(sb)->s_es->s_feature_compat |=
+		cpu_to_le32(EXT3_FEATURE_COMPAT_EXT_ATTR);
+	sb->s_dirt = 1;
+	ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
+	unlock_super(sb);
+}
+
+/*
+ * ext3_xattr_set()
+ *
+ * Create, replace or remove an extended attribute for this inode. Buffer
+ * is NULL to remove an existing extended attribute, and non-NULL to
+ * either replace an existing extended attribute, or create a new extended
+ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
+ * specify that an extended attribute must exist and must not exist
+ * previous to the call, respectively.
+ *
+ * Returns 0, or a negative error number on failure.
+ */
+int
+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
+	       const char *name, const void *value, size_t value_len, int flags)
+{
+	struct super_block *sb = inode->i_sb;
+	struct buffer_head *bh = NULL;
+	struct ext3_xattr_header *header = NULL;
+	struct ext3_xattr_entry *here, *last;
+	unsigned int name_len;
+	int min_offs = sb->s_blocksize, not_found = 1, free, error;
+	char *end;
+	
+	/*
+	 * header -- Points either into bh, or to a temporarily
+	 *           allocated buffer.
+	 * here -- The named entry found, or the place for inserting, within
+	 *         the block pointed to by header.
+	 * last -- Points right after the last named entry within the block
+	 *         pointed to by header.
+	 * min_offs -- The offset of the first value (values are aligned
+	 *             towards the end of the block).
+	 * end -- Points right after the block pointed to by header.
+	 */
+	
+	ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
+		  name_index, name, value, (long)value_len);
+
+	if (IS_RDONLY(inode))
+		return -EROFS;
+	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+		return -EPERM;
+	if (value == NULL)
+		value_len = 0;
+	if (name == NULL)
+		return -EINVAL;
+	name_len = strlen(name);
+	if (name_len > 255 || value_len > sb->s_blocksize)
+		return -ERANGE;
+	down(&ext3_xattr_sem);
+
+	if (EXT3_I(inode)->i_file_acl) {
+		/* The inode already has an extended attribute block. */
+		bh = sb_bread(sb, EXT3_I(inode)->i_file_acl);
+		error = -EIO;
+		if (!bh)
+			goto cleanup;
+		ea_bdebug(bh, "b_count=%d, refcount=%d",
+			atomic_read(&(bh->b_count)),
+			le32_to_cpu(HDR(bh)->h_refcount));
+		header = HDR(bh);
+		end = bh->b_data + bh->b_size;
+		if (header->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
+		    header->h_blocks != cpu_to_le32(1)) {
+bad_block:		ext3_error(sb, "ext3_xattr_set",
+				"inode %ld: bad block %d", inode->i_ino,
+				EXT3_I(inode)->i_file_acl);
+			error = -EIO;
+			goto cleanup;
+		}
+		/* Find the named attribute. */
+		here = FIRST_ENTRY(bh);
+		while (!IS_LAST_ENTRY(here)) {
+			struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(here);
+			if ((char *)next >= end)
+				goto bad_block;
+			if (!here->e_value_block && here->e_value_size) {
+				int offs = le16_to_cpu(here->e_value_offs);
+				if (offs < min_offs)
+					min_offs = offs;
+			}
+			not_found = name_index - here->e_name_index;
+			if (!not_found)
+				not_found = name_len - here->e_name_len;
+			if (!not_found)
+				not_found = memcmp(name, here->e_name,name_len);
+			if (not_found <= 0)
+				break;
+			here = next;
+		}
+		last = here;
+		/* We still need to compute min_offs and last. */
+		while (!IS_LAST_ENTRY(last)) {
+			struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
+			if ((char *)next >= end)
+				goto bad_block;
+			if (!last->e_value_block && last->e_value_size) {
+				int offs = le16_to_cpu(last->e_value_offs);
+				if (offs < min_offs)
+					min_offs = offs;
+			}
+			last = next;
+		}
+
+		/* Check whether we have enough space left. */
+		free = min_offs - ((char*)last - (char*)header) - sizeof(__u32);
+	} else {
+		/* We will use a new extended attribute block. */
+		free = sb->s_blocksize -
+			sizeof(struct ext3_xattr_header) - sizeof(__u32);
+		here = last = NULL;  /* avoid gcc uninitialized warning. */
+	}
+
+	if (not_found) {
+		/* Request to remove a nonexistent attribute? */
+		error = -ENODATA;
+		if (flags & XATTR_REPLACE)
+			goto cleanup;
+		error = 0;
+		if (value == NULL)
+			goto cleanup;
+		else
+			free -= EXT3_XATTR_LEN(name_len);
+	} else {
+		/* Request to create an existing attribute? */
+		error = -EEXIST;
+		if (flags & XATTR_CREATE)
+			goto cleanup;
+		if (!here->e_value_block && here->e_value_size) {
+			unsigned int size = le32_to_cpu(here->e_value_size);
+
+			if (le16_to_cpu(here->e_value_offs) + size > 
+			    sb->s_blocksize || size > sb->s_blocksize)
+				goto bad_block;
+			free += EXT3_XATTR_SIZE(size);
+		}
+	}
+	free -= EXT3_XATTR_SIZE(value_len);
+	error = -ENOSPC;
+	if (free < 0)
+		goto cleanup;
+
+	/* Here we know that we can set the new attribute. */
+
+	if (header) {
+		if (header->h_refcount == cpu_to_le32(1)) {
+			ea_bdebug(bh, "modifying in-place");
+			ext3_xattr_cache_remove(bh);
+			error = ext3_journal_get_write_access(handle, bh);
+			if (error)
+				goto cleanup;
+		} else {
+			int offset;
+
+			ea_bdebug(bh, "cloning");
+			header = kmalloc(bh->b_size, GFP_KERNEL);
+			error = -ENOMEM;
+			if (header == NULL)
+				goto cleanup;
+			memcpy(header, HDR(bh), bh->b_size);
+			header->h_refcount = cpu_to_le32(1);
+			offset = (char *)header - bh->b_data;
+			here = ENTRY((char *)here + offset);
+			last = ENTRY((char *)last + offset);
+		}
+	} else {
+		/* Allocate a buffer where we construct the new block. */
+		header = kmalloc(sb->s_blocksize, GFP_KERNEL);
+		error = -ENOMEM;
+		if (header == NULL)
+			goto cleanup;
+		memset(header, 0, sb->s_blocksize);
+		end = (char *)header + sb->s_blocksize;
+		header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC);
+		header->h_blocks = header->h_refcount = cpu_to_le32(1);
+		last = here = ENTRY(header+1);
+	}
+
+	if (not_found) {
+		/* Insert the new name. */
+		int size = EXT3_XATTR_LEN(name_len);
+		int rest = (char *)last - (char *)here;
+		memmove((char *)here + size, here, rest);
+		memset(here, 0, size);
+		here->e_name_index = name_index;
+		here->e_name_len = name_len;
+		memcpy(here->e_name, name, name_len);
+	} else {
+		/* Remove the old value. */
+		if (!here->e_value_block && here->e_value_size) {
+			char *first_val = (char *)header + min_offs;
+			int offs = le16_to_cpu(here->e_value_offs);
+			char *val = (char *)header + offs;
+			size_t size = EXT3_XATTR_SIZE(
+				le32_to_cpu(here->e_value_size));
+			memmove(first_val + size, first_val, val - first_val);
+			memset(first_val, 0, size);
+			here->e_value_offs = 0;
+			min_offs += size;
+
+			/* Adjust all value offsets. */
+			last = ENTRY(header+1);
+			while (!IS_LAST_ENTRY(last)) {
+				int o = le16_to_cpu(last->e_value_offs);
+				if (!last->e_value_block && o < offs)
+					last->e_value_offs =
+						cpu_to_le16(o + size);
+				last = EXT3_XATTR_NEXT(last);
+			}
+		}
+		if (value == NULL) {
+			/* Remove this attribute. */
+			if (EXT3_XATTR_NEXT(ENTRY(header+1)) == last) {
+				/* This block is now empty. */
+				error = ext3_xattr_set2(handle, inode, bh,NULL);
+				goto cleanup;
+			} else {
+				/* Remove the old name. */
+				int size = EXT3_XATTR_LEN(name_len);
+				last = ENTRY((char *)last - size);
+				memmove(here, (char*)here + size,
+					(char*)last - (char*)here);
+				memset(last, 0, size);
+			}
+		}
+	}
+
+	if (value != NULL) {
+		/* Insert the new value. */
+		here->e_value_size = cpu_to_le32(value_len);
+		if (value_len) {
+			size_t size = EXT3_XATTR_SIZE(value_len);
+			char *val = (char *)header + min_offs - size;
+			here->e_value_offs =
+				cpu_to_le16((char *)val - (char *)header);
+			memset(val + size - EXT3_XATTR_PAD, 0,
+			       EXT3_XATTR_PAD); /* Clear the pad bytes. */
+			memcpy(val, value, value_len);
+		}
+	}
+	ext3_xattr_rehash(header, here);
+
+	error = ext3_xattr_set2(handle, inode, bh, header);
+
+cleanup:
+	brelse(bh);
+	if (!(bh && header == HDR(bh)))
+		kfree(header);
+	up(&ext3_xattr_sem);
+
+	return error;
+}
+
+/*
+ * Second half of ext3_xattr_set(): Update the file system.
+ */
+static int
+ext3_xattr_set2(handle_t *handle, struct inode *inode,
+		struct buffer_head *old_bh, struct ext3_xattr_header *header)
+{
+	struct super_block *sb = inode->i_sb;
+	struct buffer_head *new_bh = NULL;
+	int error;
+
+	if (header) {
+		new_bh = ext3_xattr_cache_find(inode, header);
+		if (new_bh) {
+			/*
+			 * We found an identical block in the cache.
+			 * The old block will be released after updating
+			 * the inode.
+			 */
+			ea_bdebug(old_bh, "reusing block %ld",
+				new_bh->b_blocknr);
+			
+			error = -EDQUOT;
+			if (DQUOT_ALLOC_BLOCK(inode, 1))
+				goto cleanup;
+			
+			error = ext3_journal_get_write_access(handle, new_bh);
+			if (error)
+				goto cleanup;
+			HDR(new_bh)->h_refcount = cpu_to_le32(
+				le32_to_cpu(HDR(new_bh)->h_refcount) + 1);
+			ea_bdebug(new_bh, "refcount now=%d",
+				le32_to_cpu(HDR(new_bh)->h_refcount));
+		} else if (old_bh && header == HDR(old_bh)) {
+			/* Keep this block. */
+			new_bh = old_bh;
+			ext3_xattr_cache_insert(new_bh);
+		} else {
+			/* We need to allocate a new block */
+			int goal = le32_to_cpu(
+					EXT3_SB(sb)->s_es->s_first_data_block) +
+				EXT3_I(inode)->i_block_group *
+				EXT3_BLOCKS_PER_GROUP(sb);
+			int block  = ext3_new_block(handle,
+				inode, goal, 0, 0, &error);
+			if (error)
+				goto cleanup;
+			ea_idebug(inode, "creating block %d", block);
+
+			new_bh = sb_getblk(sb, block);
+			if (!new_bh) {
+getblk_failed:
+				ext3_free_blocks(handle, inode, block, 1);
+				error = -EIO;
+				goto cleanup;
+			}
+			lock_buffer(new_bh);
+			error = ext3_journal_get_create_access(handle, new_bh);
+			if (error) {
+				unlock_buffer(new_bh);
+				goto getblk_failed;
+			}
+			memcpy(new_bh->b_data, header, new_bh->b_size);
+			set_buffer_uptodate(new_bh);
+			unlock_buffer(new_bh);
+			ext3_xattr_cache_insert(new_bh);
+			
+			ext3_xattr_update_super_block(handle, sb);
+		}
+		error = ext3_journal_dirty_metadata(handle, new_bh);
+		if (error)
+			goto cleanup;
+	}
+
+	/* Update the inode. */
+	EXT3_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
+	inode->i_ctime = CURRENT_TIME;
+	ext3_mark_inode_dirty(handle, inode);
+	if (IS_SYNC(inode))
+		handle->h_sync = 1;
+
+	error = 0;
+	if (old_bh && old_bh != new_bh) {
+		/*
+		 * If there was an old block, and we are not still using it,
+		 * we now release the old block.
+		*/
+		unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount);
+
+		error = ext3_journal_get_write_access(handle, old_bh);
+		if (error)
+			goto cleanup;
+		if (refcount == 1) {
+			/* Free the old block. */
+			ea_bdebug(old_bh, "freeing");
+			ext3_free_blocks(handle, inode, old_bh->b_blocknr, 1);
+
+			/* ext3_forget() calls bforget() for us, but we
+			   let our caller release old_bh, so we need to
+			   duplicate the handle before. */
+			get_bh(old_bh);
+			ext3_forget(handle, 1, inode, old_bh,old_bh->b_blocknr);
+		} else {
+			/* Decrement the refcount only. */
+			refcount--;
+			HDR(old_bh)->h_refcount = cpu_to_le32(refcount);
+			DQUOT_FREE_BLOCK(inode, 1);
+			ext3_journal_dirty_metadata(handle, old_bh);
+			ea_bdebug(old_bh, "refcount now=%d", refcount);
+		}
+	}
+
+cleanup:
+	if (old_bh != new_bh)
+		brelse(new_bh);
+
+	return error;
+}
+
+/*
+ * ext3_xattr_delete_inode()
+ *
+ * Free extended attribute resources associated with this inode. This
+ * is called immediately before an inode is freed.
+ */
+void
+ext3_xattr_delete_inode(handle_t *handle, struct inode *inode)
+{
+	struct buffer_head *bh;
+
+	if (!EXT3_I(inode)->i_file_acl)
+		return;
+	down(&ext3_xattr_sem);
+
+	bh = sb_bread(inode->i_sb, EXT3_I(inode)->i_file_acl);
+	if (!bh) {
+		ext3_error(inode->i_sb, "ext3_xattr_delete_inode",
+			"inode %ld: block %d read error", inode->i_ino,
+			EXT3_I(inode)->i_file_acl);
+		goto cleanup;
+	}
+	ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count)));
+	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
+	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
+		ext3_error(inode->i_sb, "ext3_xattr_delete_inode",
+			"inode %ld: bad block %d", inode->i_ino,
+			EXT3_I(inode)->i_file_acl);
+		goto cleanup;
+	}
+	ext3_journal_get_write_access(handle, bh);
+	ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1);
+	if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
+		ext3_xattr_cache_remove(bh);
+		ext3_free_blocks(handle, inode, EXT3_I(inode)->i_file_acl, 1);
+		ext3_forget(handle, 1, inode, bh, EXT3_I(inode)->i_file_acl);
+		bh = NULL;
+	} else {
+		HDR(bh)->h_refcount = cpu_to_le32(
+			le32_to_cpu(HDR(bh)->h_refcount) - 1);
+		ext3_journal_dirty_metadata(handle, bh);
+		if (IS_SYNC(inode))
+			handle->h_sync = 1;
+		DQUOT_FREE_BLOCK(inode, 1);
+	}
+	EXT3_I(inode)->i_file_acl = 0;
+
+cleanup:
+	brelse(bh);
+	up(&ext3_xattr_sem);
+}
+
+/*
+ * ext3_xattr_put_super()
+ *
+ * This is called when a file system is unmounted.
+ */
+void
+ext3_xattr_put_super(struct super_block *sb)
+{
+	mb_cache_shrink(ext3_xattr_cache, sb->s_bdev);
+}
+
+/*
+ * ext3_xattr_cache_insert()
+ *
+ * Create a new entry in the extended attribute cache, and insert
+ * it unless such an entry is already in the cache.
+ *
+ * Returns 0, or a negative error number on failure.
+ */
+static int
+ext3_xattr_cache_insert(struct buffer_head *bh)
+{
+	__u32 hash = le32_to_cpu(HDR(bh)->h_hash);
+	struct mb_cache_entry *ce;
+	int error;
+
+	ce = mb_cache_entry_alloc(ext3_xattr_cache);
+	if (!ce)
+		return -ENOMEM;
+	error = mb_cache_entry_insert(ce, bh->b_bdev, bh->b_blocknr, &hash);
+	if (error) {
+		mb_cache_entry_free(ce);
+		if (error == -EBUSY) {
+			ea_bdebug(bh, "already in cache (%d cache entries)",
+				atomic_read(&ext3_xattr_cache->c_entry_count));
+			error = 0;
+		}
+	} else {
+		ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash,
+			  atomic_read(&ext3_xattr_cache->c_entry_count));
+		mb_cache_entry_release(ce);
+	}
+	return error;
+}
+
+/*
+ * ext3_xattr_cmp()
+ *
+ * Compare two extended attribute blocks for equality.
+ *
+ * Returns 0 if the blocks are equal, 1 if they differ, and
+ * a negative error number on errors.
+ */
+static int
+ext3_xattr_cmp(struct ext3_xattr_header *header1,
+	       struct ext3_xattr_header *header2)
+{
+	struct ext3_xattr_entry *entry1, *entry2;
+
+	entry1 = ENTRY(header1+1);
+	entry2 = ENTRY(header2+1);
+	while (!IS_LAST_ENTRY(entry1)) {
+		if (IS_LAST_ENTRY(entry2))
+			return 1;
+		if (entry1->e_hash != entry2->e_hash ||
+		    entry1->e_name_len != entry2->e_name_len ||
+		    entry1->e_value_size != entry2->e_value_size ||
+		    memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
+			return 1;
+		if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
+			return -EIO;
+		if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
+			   (char *)header2 + le16_to_cpu(entry2->e_value_offs),
+			   le32_to_cpu(entry1->e_value_size)))
+			return 1;
+
+		entry1 = EXT3_XATTR_NEXT(entry1);
+		entry2 = EXT3_XATTR_NEXT(entry2);
+	}
+	if (!IS_LAST_ENTRY(entry2))
+		return 1;
+	return 0;
+}
+
+/*
+ * ext3_xattr_cache_find()
+ *
+ * Find an identical extended attribute block.
+ *
+ * Returns a pointer to the block found, or NULL if such a block was
+ * not found or an error occurred.
+ */
+static struct buffer_head *
+ext3_xattr_cache_find(struct inode *inode, struct ext3_xattr_header *header)
+{
+	__u32 hash = le32_to_cpu(header->h_hash);
+	struct mb_cache_entry *ce;
+
+	if (!header->h_hash)
+		return NULL;  /* never share */
+	ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
+	ce = mb_cache_entry_find_first(ext3_xattr_cache, 0, inode->i_bdev, hash);
+	while (ce) {
+		struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block);
+
+		if (!bh) {
+			ext3_error(inode->i_sb, "ext3_xattr_cache_find",
+				"inode %ld: block %ld read error",
+				inode->i_ino, (unsigned long) ce->e_block);
+		} else if (le32_to_cpu(HDR(bh)->h_refcount) >
+			   EXT3_XATTR_REFCOUNT_MAX) {
+			ea_idebug(inode, "block %ld refcount %d>%d",
+				  (unsigned long) ce->e_block,
+				  le32_to_cpu(HDR(bh)->h_refcount),
+				  EXT3_XATTR_REFCOUNT_MAX);
+		} else if (!ext3_xattr_cmp(header, HDR(bh))) {
+			ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count)));
+			mb_cache_entry_release(ce);
+			return bh;
+		}
+		brelse(bh);
+		ce = mb_cache_entry_find_next(ce, 0, inode->i_bdev, hash);
+	}
+	return NULL;
+}
+
+/*
+ * ext3_xattr_cache_remove()
+ *
+ * Remove the cache entry of a block from the cache. Called when a
+ * block becomes invalid.
+ */
+static void
+ext3_xattr_cache_remove(struct buffer_head *bh)
+{
+	struct mb_cache_entry *ce;
+
+	ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_bdev,
+				bh->b_blocknr);
+	if (ce) {
+		ea_bdebug(bh, "removing (%d cache entries remaining)",
+			  atomic_read(&ext3_xattr_cache->c_entry_count)-1);
+		mb_cache_entry_free(ce);
+	} else 
+		ea_bdebug(bh, "no cache entry");
+}
+
+#define NAME_HASH_SHIFT 5
+#define VALUE_HASH_SHIFT 16
+
+/*
+ * ext3_xattr_hash_entry()
+ *
+ * Compute the hash of an extended attribute.
+ */
+static inline void ext3_xattr_hash_entry(struct ext3_xattr_header *header,
+					 struct ext3_xattr_entry *entry)
+{
+	__u32 hash = 0;
+	char *name = entry->e_name;
+	int n;
+
+	for (n=0; n < entry->e_name_len; n++) {
+		hash = (hash << NAME_HASH_SHIFT) ^
+		       (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
+		       *name++;
+	}
+
+	if (entry->e_value_block == 0 && entry->e_value_size != 0) {
+		__u32 *value = (__u32 *)((char *)header +
+			le16_to_cpu(entry->e_value_offs));
+		for (n = (le32_to_cpu(entry->e_value_size) +
+		     EXT3_XATTR_ROUND) >> EXT3_XATTR_PAD_BITS; n; n--) {
+			hash = (hash << VALUE_HASH_SHIFT) ^
+			       (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
+			       le32_to_cpu(*value++);
+		}
+	}
+	entry->e_hash = cpu_to_le32(hash);
+}
+
+#undef NAME_HASH_SHIFT
+#undef VALUE_HASH_SHIFT
+
+#define BLOCK_HASH_SHIFT 16
+
+/*
+ * ext3_xattr_rehash()
+ *
+ * Re-compute the extended attribute hash value after an entry has changed.
+ */
+static void ext3_xattr_rehash(struct ext3_xattr_header *header,
+			      struct ext3_xattr_entry *entry)
+{
+	struct ext3_xattr_entry *here;
+	__u32 hash = 0;
+	
+	ext3_xattr_hash_entry(header, entry);
+	here = ENTRY(header+1);
+	while (!IS_LAST_ENTRY(here)) {
+		if (!here->e_hash) {
+			/* Block is not shared if an entry's hash value == 0 */
+			hash = 0;
+			break;
+		}
+		hash = (hash << BLOCK_HASH_SHIFT) ^
+		       (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^
+		       le32_to_cpu(here->e_hash);
+		here = EXT3_XATTR_NEXT(here);
+	}
+	header->h_hash = cpu_to_le32(hash);
+}
+
+#undef BLOCK_HASH_SHIFT
+
+int __init
+init_ext3_xattr(void)
+{
+	int	err;
+	
+	err = ext3_xattr_register(EXT3_XATTR_INDEX_USER, &ext3_xattr_user_handler);
+	if (err)
+		return err;
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
+	err = init_ext3_acl();
+	if (err)
+		goto out;
+#endif
+	ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL,
+		sizeof(struct mb_cache_entry) +
+		sizeof(struct mb_cache_entry_index), 1, 6);
+	if (!ext3_xattr_cache) {
+		err = -ENOMEM;
+		goto out1;
+	}
+	return 0;
+out1:
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
+	exit_ext3_acl();
+out:
+#endif
+	ext3_xattr_unregister(EXT3_XATTR_INDEX_USER,
+			      &ext3_xattr_user_handler);
+	return err;
+}
+
+void
+exit_ext3_xattr(void)
+{
+	if (ext3_xattr_cache)
+		mb_cache_destroy(ext3_xattr_cache);
+	ext3_xattr_cache = NULL;
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
+	exit_ext3_acl();
+#endif
+	ext3_xattr_unregister(EXT3_XATTR_INDEX_USER, &ext3_xattr_user_handler);
+}
diff -Nru a/fs/ext3/xattr.h b/fs/ext3/xattr.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/ext3/xattr.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,133 @@
+/*
+  File: fs/ext3/xattr.h
+
+  On-disk format of extended attributes for the ext3 filesystem.
+
+  (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
+*/
+
+#include <linux/config.h>
+#include <linux/xattr.h>
+
+/* Magic value in attribute blocks */
+#define EXT3_XATTR_MAGIC		0xEA020000
+
+/* Maximum number of references to one attribute block */
+#define EXT3_XATTR_REFCOUNT_MAX		1024
+
+/* Name indexes */
+#define EXT3_XATTR_INDEX_MAX			10
+#define EXT3_XATTR_INDEX_USER			1
+#define EXT3_XATTR_INDEX_POSIX_ACL_ACCESS	2
+#define EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT	3
+
+struct ext3_xattr_header {
+	__u32	h_magic;	/* magic number for identification */
+	__u32	h_refcount;	/* reference count */
+	__u32	h_blocks;	/* number of disk blocks used */
+	__u32	h_hash;		/* hash value of all attributes */
+	__u32	h_reserved[4];	/* zero right now */
+};
+
+struct ext3_xattr_entry {
+	__u8	e_name_len;	/* length of name */
+	__u8	e_name_index;	/* attribute name index */
+	__u16	e_value_offs;	/* offset in disk block of value */
+	__u32	e_value_block;	/* disk block attribute is stored on (n/i) */
+	__u32	e_value_size;	/* size of attribute value */
+	__u32	e_hash;		/* hash value of name and value */
+	char	e_name[0];	/* attribute name */
+};
+
+#define EXT3_XATTR_PAD_BITS		2
+#define EXT3_XATTR_PAD		(1<<EXT3_XATTR_PAD_BITS)
+#define EXT3_XATTR_ROUND		(EXT3_XATTR_PAD-1)
+#define EXT3_XATTR_LEN(name_len) \
+	(((name_len) + EXT3_XATTR_ROUND + \
+	sizeof(struct ext3_xattr_entry)) & ~EXT3_XATTR_ROUND)
+#define EXT3_XATTR_NEXT(entry) \
+	( (struct ext3_xattr_entry *)( \
+	  (char *)(entry) + EXT3_XATTR_LEN((entry)->e_name_len)) )
+#define EXT3_XATTR_SIZE(size) \
+	(((size) + EXT3_XATTR_ROUND) & ~EXT3_XATTR_ROUND)
+
+# ifdef CONFIG_EXT3_FS_XATTR
+
+struct ext3_xattr_handler {
+	char *prefix;
+	size_t (*list)(char *list, struct inode *inode, const char *name,
+		       int name_len);
+	int (*get)(struct inode *inode, const char *name, void *buffer,
+		   size_t size);
+	int (*set)(struct inode *inode, const char *name, const void *buffer,
+		   size_t size, int flags);
+};
+
+extern int ext3_xattr_register(int, struct ext3_xattr_handler *);
+extern void ext3_xattr_unregister(int, struct ext3_xattr_handler *);
+
+extern int ext3_setxattr(struct dentry *, const char *, void *, size_t, int);
+extern ssize_t ext3_getxattr(struct dentry *, const char *, void *, size_t);
+extern ssize_t ext3_listxattr(struct dentry *, char *, size_t);
+extern int ext3_removexattr(struct dentry *, const char *);
+
+extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t);
+extern int ext3_xattr_list(struct inode *, char *, size_t);
+extern int ext3_xattr_set(handle_t *handle, struct inode *, int, const char *, const void *, size_t, int);
+
+extern void ext3_xattr_delete_inode(handle_t *, struct inode *);
+extern void ext3_xattr_put_super(struct super_block *);
+
+extern int init_ext3_xattr(void);
+extern void exit_ext3_xattr(void);
+
+# else  /* CONFIG_EXT3_FS_XATTR */
+#  define ext3_setxattr		NULL
+#  define ext3_getxattr		NULL
+#  define ext3_listxattr	NULL
+#  define ext3_removexattr	NULL
+
+static inline int
+ext3_xattr_get(struct inode *inode, int name_index, const char *name,
+	       void *buffer, size_t size, int flags)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int
+ext3_xattr_list(struct inode *inode, void *buffer, size_t size, int flags)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int
+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
+	       const char *name, const void *value, size_t size, int flags)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline void
+ext3_xattr_delete_inode(handle_t *handle, struct inode *inode)
+{
+}
+
+static inline void
+ext3_xattr_put_super(struct super_block *sb)
+{
+}
+
+static inline int
+init_ext3_xattr(void)
+{
+	return 0;
+}
+
+static inline void
+exit_ext3_xattr(void)
+{
+}
+
+# endif  /* CONFIG_EXT3_FS_XATTR */
+
+extern struct ext3_xattr_handler ext3_xattr_user_handler;
diff -Nru a/fs/ext3/xattr_user.c b/fs/ext3/xattr_user.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/ext3/xattr_user.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,99 @@
+/*
+ * linux/fs/ext3/xattr_user.c
+ * Handler for extended user attributes.
+ *
+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
+ */
+
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <linux/smp_lock.h>
+#include <linux/ext3_jbd.h>
+#include <linux/ext3_fs.h>
+#include "xattr.h"
+
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
+# include "acl.h"
+#endif
+
+#define XATTR_USER_PREFIX "user."
+
+static size_t
+ext3_xattr_user_list(char *list, struct inode *inode,
+		     const char *name, int name_len)
+{
+	const int prefix_len = sizeof(XATTR_USER_PREFIX)-1;
+
+	if (!test_opt(inode->i_sb, XATTR_USER))
+		return 0;
+
+	if (list) {
+		memcpy(list, XATTR_USER_PREFIX, prefix_len);
+		memcpy(list+prefix_len, name, name_len);
+	}
+	return prefix_len + name_len;
+}
+
+static int
+ext3_xattr_user_get(struct inode *inode, const char *name,
+		    void *buffer, size_t size)
+{
+	int error;
+
+	if (strcmp(name, "") == 0)
+		return -EINVAL;
+	if (!test_opt(inode->i_sb, XATTR_USER))
+		return -EOPNOTSUPP;
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
+	error = ext3_permission_locked(inode, MAY_READ);
+#else
+	error = permission(inode, MAY_READ);
+#endif
+	if (error)
+		return error;
+
+	return ext3_xattr_get(inode, EXT3_XATTR_INDEX_USER, name,
+			      buffer, size);
+}
+
+static int
+ext3_xattr_user_set(struct inode *inode, const char *name,
+		    const void *value, size_t size, int flags)
+{
+	handle_t *handle;
+	int error;
+
+	if (strcmp(name, "") == 0)
+		return -EINVAL;
+	if (!test_opt(inode->i_sb, XATTR_USER))
+		return -EOPNOTSUPP;
+	if ( !S_ISREG(inode->i_mode) &&
+	    (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
+		return -EPERM;
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
+	error = ext3_permission_locked(inode, MAY_WRITE);
+#else
+	error = permission(inode, MAY_WRITE);
+#endif
+	if (error)
+		return error;
+  
+	lock_kernel();
+	handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
+	if (IS_ERR(handle))
+		return PTR_ERR(handle);
+	error = ext3_xattr_set(handle, inode, EXT3_XATTR_INDEX_USER, name,
+			       value, size, flags);
+	ext3_journal_stop(handle, inode);
+	unlock_kernel();
+
+	return error;
+}
+
+struct ext3_xattr_handler ext3_xattr_user_handler = {
+	prefix:	XATTR_USER_PREFIX,
+	list:	ext3_xattr_user_list,
+	get:	ext3_xattr_user_get,
+	set:	ext3_xattr_user_set,
+};
diff -Nru a/fs/fcblist.c b/fs/fcblist.c
--- a/fs/fcblist.c	Mon Nov  4 14:31:02 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,146 +0,0 @@
-/*
- *  linux/fs/fcblist.c ( File event callbacks handling )
- *  Copyright (C) 2001,...,2002  Davide Libenzi
- *
- *  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.
- *
- *  Davide Libenzi <davidel@xmailserver.org>
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/poll.h>
-#include <asm/bitops.h>
-#include <linux/fcblist.h>
-
-
-long ion_band_table[NSIGPOLL] = {
-	ION_IN,		/* POLL_IN */
-	ION_OUT,	/* POLL_OUT */
-	ION_IN,		/* POLL_MSG */
-	ION_ERR,	/* POLL_ERR */
-	0,		/* POLL_PRI */
-	ION_HUP		/* POLL_HUP */
-};
-
-long poll_band_table[NSIGPOLL] = {
-	POLLIN | POLLRDNORM,			/* POLL_IN */
-	POLLOUT | POLLWRNORM | POLLWRBAND,	/* POLL_OUT */
-	POLLIN | POLLRDNORM | POLLMSG,		/* POLL_MSG */
-	POLLERR,				/* POLL_ERR */
-	POLLPRI | POLLRDBAND,			/* POLL_PRI */
-	POLLHUP | POLLERR			/* POLL_HUP */
-};
-
-
-
-/*
- * Walk through the file callback list by calling each registered callback
- * with the event that happened on the "filep" file. Callbacks are called
- * by holding a read lock on the callback list lock, and also by keeping
- * local IRQs disabled.
- */
-void file_notify_event(struct file *filep, long *event)
-{
-	unsigned long flags;
-	struct list_head *lnk, *lsthead;
-
-	read_lock_irqsave(&filep->f_cblock, flags);
-
-	lsthead = &filep->f_cblist;
-	list_for_each(lnk, lsthead) {
-		struct fcb_struct *fcbp = list_entry(lnk, struct fcb_struct, llink);
-
-		fcbp->cbproc(filep, fcbp->data, fcbp->local, event);
-	}
-
-	read_unlock_irqrestore(&filep->f_cblock, flags);
-}
-
-
-/*
- * Add a new callback to the list of file callbacks.
- */
-int file_notify_addcb(struct file *filep,
-		      void (*cbproc)(struct file *, void *, unsigned long *, long *),
-		      void *data)
-{
-	unsigned long flags;
-	struct fcb_struct *fcbp;
-
-	if (!(fcbp = (struct fcb_struct *) kmalloc(sizeof(struct fcb_struct), GFP_KERNEL)))
-		return -ENOMEM;
-
-	memset(fcbp, 0, sizeof(struct fcb_struct));
-	fcbp->cbproc = cbproc;
-	fcbp->data = data;
-
-	write_lock_irqsave(&filep->f_cblock, flags);
-	list_add_tail(&fcbp->llink, &filep->f_cblist);
-	write_unlock_irqrestore(&filep->f_cblock, flags);
-
-	return 0;
-}
-
-
-/*
- * Removes the callback "cbproc" from the file callback list.
- */
-int file_notify_delcb(struct file *filep,
-		      void (*cbproc)(struct file *, void *, unsigned long *, long *))
-{
-	unsigned long flags;
-	struct list_head *lnk, *lsthead;
-
-	write_lock_irqsave(&filep->f_cblock, flags);
-
-	lsthead = &filep->f_cblist;
-	list_for_each(lnk, lsthead) {
-		struct fcb_struct *fcbp = list_entry(lnk, struct fcb_struct, llink);
-
-		if (fcbp->cbproc == cbproc) {
-			list_del(lnk);
-			write_unlock_irqrestore(&filep->f_cblock, flags);
-			kfree(fcbp);
-			return 0;
-		}
-	}
-
-	write_unlock_irqrestore(&filep->f_cblock, flags);
-
-	return -ENOENT;
-}
-
-
-/*
- * It is called at file cleanup time and removes all the registered callbacks.
- */
-void file_notify_cleanup(struct file *filep)
-{
-	unsigned long flags;
-	struct list_head *lsthead;
-
-	write_lock_irqsave(&filep->f_cblock, flags);
-
-	lsthead = &filep->f_cblist;
-	while (!list_empty(lsthead)) {
-		struct fcb_struct *fcbp = list_entry(lsthead->next, struct fcb_struct, llink);
-
-		list_del(lsthead->next);
-		write_unlock_irqrestore(&filep->f_cblock, flags);
-		kfree(fcbp);
-		write_lock_irqsave(&filep->f_cblock, flags);
-	}
-
-	write_unlock_irqrestore(&filep->f_cblock, flags);
-}
-
diff -Nru a/fs/file_table.c b/fs/file_table.c
--- a/fs/file_table.c	Mon Nov  4 14:31:00 2002
+++ b/fs/file_table.c	Mon Nov  4 14:31:00 2002
@@ -8,12 +8,12 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/file.h>
-#include <linux/fcblist.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/smp_lock.h>
 #include <linux/fs.h>
 #include <linux/security.h>
+#include <linux/eventpoll.h>
 
 /* sysctl tunables... */
 struct files_stat_struct files_stat = {0, 0, NR_FILE};
@@ -59,7 +59,6 @@
 		f->f_gid = current->fsgid;
 		f->f_owner.lock = RW_LOCK_UNLOCKED;
 		list_add(&f->f_list, &anon_list);
-		file_notify_init(f);
 		file_list_unlock();
 		return f;
 	}
@@ -104,7 +103,6 @@
 	filp->f_uid    = current->fsuid;
 	filp->f_gid    = current->fsgid;
 	filp->f_op     = dentry->d_inode->i_fop;
-	file_notify_init(filp);
 	if (filp->f_op->open)
 		return filp->f_op->open(dentry->d_inode, filp);
 	else
@@ -126,7 +124,7 @@
 	struct vfsmount * mnt = file->f_vfsmnt;
 	struct inode * inode = dentry->d_inode;
 
-	file_notify_cleanup(file);
+	ep_notify_file_close(file);
 	locks_remove_flock(file);
 
 	if (file->f_op && file->f_op->release)
diff -Nru a/fs/hugetlbfs/Makefile b/fs/hugetlbfs/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/hugetlbfs/Makefile	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,9 @@
+#
+# Makefile for the linux ramfs routines.
+#
+
+obj-$(CONFIG_HUGETLBFS) += hugetlbfs.o
+
+hugetlbfs-objs := inode.o
+
+include $(TOPDIR)/Rules.make
diff -Nru a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/hugetlbfs/inode.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,594 @@
+/*
+ * hugetlbpage-backed filesystem.  Based on ramfs.
+ *
+ * William Irwin, 2002
+ *
+ * Copyright (C) 2002 Linus Torvalds.
+ */
+
+#include <linux/module.h>
+#include <linux/thread_info.h>
+#include <asm/current.h>
+#include <linux/sched.h>		/* remove ASAP */
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/writeback.h>
+#include <linux/pagemap.h>
+#include <linux/highmem.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/backing-dev.h>
+#include <linux/hugetlb.h>
+#include <linux/pagevec.h>
+#include <linux/quotaops.h>
+#include <linux/dnotify.h>
+
+#include <asm/uaccess.h>
+
+/* some random number */
+#define HUGETLBFS_MAGIC	0x958458f6
+
+static struct super_operations hugetlbfs_ops;
+static struct address_space_operations hugetlbfs_aops;
+struct file_operations hugetlbfs_file_operations;
+static struct inode_operations hugetlbfs_dir_inode_operations;
+
+static struct backing_dev_info hugetlbfs_backing_dev_info = {
+	.ra_pages	= 0,	/* No readahead */
+	.memory_backed	= 1,	/* Does not contribute to dirty memory */
+};
+
+static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct inode *inode =file->f_dentry->d_inode;
+	struct address_space *mapping = inode->i_mapping;
+	int ret;
+
+	if (!capable(CAP_IPC_LOCK))
+		return -EPERM;
+
+	if (vma->vm_start & ~HPAGE_MASK)
+		return -EINVAL;
+
+	if (vma->vm_end & ~HPAGE_MASK)
+		return -EINVAL;
+
+	if (vma->vm_end - vma->vm_start < HPAGE_SIZE)
+		return -EINVAL;
+
+	down(&inode->i_sem);
+
+	UPDATE_ATIME(inode);
+	vma->vm_flags |= VM_HUGETLB | VM_RESERVED;
+	vma->vm_ops = &hugetlb_vm_ops;
+	ret = hugetlb_prefault(mapping, vma);
+
+	up(&inode->i_sem);
+
+	return ret;
+}
+
+/*
+ * Read a page. Again trivial. If it didn't already exist
+ * in the page cache, it is zero-filled.
+ */
+static int hugetlbfs_readpage(struct file *file, struct page * page)
+{
+	return -EINVAL;
+}
+
+static int hugetlbfs_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+{
+	return -EINVAL;
+}
+
+static int hugetlbfs_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+{
+	return -EINVAL;
+}
+
+void huge_pagevec_release(struct pagevec *pvec)
+{
+	int i;
+
+	for (i = 0; i < pagevec_count(pvec); ++i)
+		huge_page_release(pvec->pages[i]);
+
+	pagevec_reinit(pvec);
+}
+
+void truncate_partial_hugepage(struct page *page, unsigned partial)
+{
+	int i;
+	const unsigned piece = partial & (PAGE_SIZE - 1);
+	const unsigned tailstart = PAGE_SIZE - piece;
+	const unsigned whole_pages = partial / PAGE_SIZE;
+	const unsigned last_page_offset = HPAGE_SIZE/PAGE_SIZE - whole_pages;
+
+	for (i = HPAGE_SIZE/PAGE_SIZE - 1; i >= last_page_offset; ++i)
+		memclear_highpage_flush(&page[i], 0, PAGE_SIZE);
+
+	if (!piece)
+		return;
+
+	memclear_highpage_flush(&page[last_page_offset - 1], tailstart, piece);
+}
+
+void truncate_huge_page(struct address_space *mapping, struct page *page)
+{
+	if (page->mapping != mapping)
+		return;
+
+	clear_page_dirty(page);
+	ClearPageUptodate(page);
+	remove_from_page_cache(page);
+	huge_page_release(page);
+}
+
+void truncate_hugepages(struct address_space *mapping, loff_t lstart)
+{
+	const pgoff_t start = (lstart + HPAGE_SIZE - 1) >> HPAGE_SHIFT;
+	const unsigned partial = lstart & (HPAGE_SIZE - 1);
+	struct pagevec pvec;
+	pgoff_t next;
+	int i;
+
+	pagevec_init(&pvec, 0);
+	next = start;
+
+	while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
+		for (i = 0; i < pagevec_count(&pvec); ++i) {
+			struct page *page = pvec.pages[i];
+			pgoff_t page_index = page->index;
+
+			if (page_index > next)
+				next = page_index;
+
+			++next;
+
+			if (TestSetPageLocked(page))
+				continue;
+
+			if (PageWriteback(page)) {
+				unlock_page(page);
+				continue;
+			}
+
+			truncate_huge_page(mapping, page);
+			unlock_page(page);
+		}
+		huge_pagevec_release(&pvec);
+		cond_resched();
+	}
+
+	if (partial) {
+		struct page *page = find_lock_page(mapping, start - 1);
+		if (page) {
+			wait_on_page_writeback(page);
+			truncate_partial_hugepage(page, partial);
+			unlock_page(page);
+			huge_page_release(page);
+		}
+	}
+
+	next = start;
+
+	while (1) {
+		if (!pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
+			if (next == start)
+				break;
+			next = start;
+			continue;
+		}
+
+		for (i = 0; i < pagevec_count(&pvec); ++i) {
+			struct page *page = pvec.pages[i];
+
+			lock_page(page);
+			wait_on_page_writeback(page);
+			if (page->index > next)
+				next = page->index;
+			++next;
+			truncate_huge_page(mapping, page);
+			unlock_page(page);
+		}
+		huge_pagevec_release(&pvec);
+	}
+	BUG_ON(!lstart && mapping->nrpages);
+}
+
+static void hugetlbfs_delete_inode(struct inode *inode)
+{
+	list_del_init(&inode->i_hash);
+	list_del_init(&inode->i_list);
+	inode->i_state |= I_FREEING;
+	inodes_stat.nr_inodes--;
+	spin_unlock(&inode_lock);
+
+	if (inode->i_data.nrpages)
+		truncate_hugepages(&inode->i_data, 0);
+
+	security_ops->inode_delete(inode);
+
+	clear_inode(inode);
+	destroy_inode(inode);
+}
+
+static void hugetlbfs_forget_inode(struct inode *inode)
+{
+	struct super_block *super_block = inode->i_sb;
+
+	if (list_empty(&inode->i_hash))
+		goto out_truncate;
+
+	if (!(inode->i_state & (I_DIRTY|I_LOCK))) {
+		list_del(&inode->i_list);
+		list_add(&inode->i_list, &inode_unused);
+	}
+	inodes_stat.nr_unused++;
+	if (!super_block | (super_block->s_flags & MS_ACTIVE)) {
+		spin_unlock(&inode_lock);
+		return;
+	}
+
+	/* write_inode_now() ? */
+	inodes_stat.nr_unused--;
+	list_del_init(&inode->i_hash);
+out_truncate:
+	list_del_init(&inode->i_list);
+	inode->i_state |= I_FREEING;
+	inodes_stat.nr_inodes--;
+	spin_unlock(&inode_lock);
+	if (inode->i_data.nrpages)
+		truncate_hugepages(&inode->i_data, 0);
+	clear_inode(inode);
+	destroy_inode(inode);
+}
+
+static void hugetlbfs_drop_inode(struct inode *inode)
+{
+	if (!inode->i_nlink)
+		hugetlbfs_delete_inode(inode);
+	else
+		hugetlbfs_forget_inode(inode);
+}
+
+static void hugetlb_vmtruncate_list(struct list_head *list, unsigned long pgoff)
+{
+	unsigned long start, end, length, delta;
+	struct vm_area_struct *vma;
+
+	list_for_each_entry(vma, list, shared) {
+		start = vma->vm_start;
+		end = vma->vm_end;
+		length = end - start;
+
+		if (vma->vm_pgoff >= pgoff) {
+			zap_hugepage_range(vma, start, length);
+			continue;
+		}
+
+		length >>= PAGE_SHIFT;
+		delta = pgoff = vma->vm_pgoff;
+		if (delta >= length)
+			continue;
+
+		start += delta << PAGE_SHIFT;
+		length = (length - delta) << PAGE_SHIFT;
+		zap_hugepage_range(vma, start, length);
+	}
+}
+
+static int hugetlb_vmtruncate(struct inode *inode, loff_t offset)
+{
+	unsigned long pgoff;
+	struct address_space *mapping = inode->i_mapping;
+	unsigned long limit;
+
+	pgoff = (offset + HPAGE_SIZE - 1) >> HPAGE_SHIFT;
+
+	if (inode->i_size < offset)
+		goto do_expand;
+
+	inode->i_size = offset;
+	spin_lock(&mapping->i_shared_lock);
+	if (list_empty(&mapping->i_mmap) && list_empty(&mapping->i_mmap_shared))
+		goto out_unlock;
+	if (!list_empty(&mapping->i_mmap))
+		hugetlb_vmtruncate_list(&mapping->i_mmap, pgoff);
+	if (!list_empty(&mapping->i_mmap_shared))
+		hugetlb_vmtruncate_list(&mapping->i_mmap_shared, pgoff);
+
+out_unlock:
+	spin_unlock(&mapping->i_shared_lock);
+	truncate_hugepages(mapping, offset);
+	return 0;
+
+do_expand:
+	limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
+	if (limit != RLIM_INFINITY && offset > limit)
+		goto out_sig;
+	if (offset > inode->i_sb->s_maxbytes)
+		goto out;
+	inode->i_size = offset;
+	return 0;
+
+out_sig:
+	send_sig(SIGXFSZ, current, 0);
+out:
+	return -EFBIG;
+}
+
+static int hugetlbfs_setattr(struct dentry *dentry, struct iattr *attr)
+{
+	struct inode *inode = dentry->d_inode;
+	int error;
+	unsigned int ia_valid = attr->ia_valid;
+	unsigned long dn_mask;
+
+	BUG_ON(!inode);
+
+	error = inode_change_ok(inode, attr);
+	if (error)
+		goto out;
+
+	error = security_ops->inode_setattr(dentry, attr);
+	if (error)
+		goto out;
+
+	if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
+	    (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid))
+		error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
+	if (error)
+		goto out;
+
+	if (ia_valid & ATTR_SIZE) {
+		error = hugetlb_vmtruncate(inode, attr->ia_size);
+		if (error)
+			goto out;
+		attr->ia_valid &= ~ATTR_SIZE;
+		error = inode_setattr(inode, attr);
+	}
+	if (error)
+		goto out;
+	dn_mask = setattr_mask(ia_valid);
+	if (dn_mask)
+		dnotify_parent(dentry, dn_mask);
+out:
+	return error;
+}
+
+struct inode *hugetlbfs_get_inode(struct super_block *sb, int mode, int dev)
+{
+	struct inode * inode = new_inode(sb);
+
+	if (inode) {
+		inode->i_mode = mode;
+		inode->i_uid = current->fsuid;
+		inode->i_gid = current->fsgid;
+		inode->i_blksize = PAGE_CACHE_SIZE;
+		inode->i_blocks = 0;
+		inode->i_rdev = NODEV;
+		inode->i_mapping->a_ops = &hugetlbfs_aops;
+		inode->i_mapping->backing_dev_info = &hugetlbfs_backing_dev_info;
+		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+		switch (mode & S_IFMT) {
+		default:
+			init_special_inode(inode, mode, dev);
+			break;
+		case S_IFREG:
+			inode->i_fop = &hugetlbfs_file_operations;
+			break;
+		case S_IFDIR:
+			inode->i_op = &hugetlbfs_dir_inode_operations;
+			inode->i_fop = &simple_dir_operations;
+
+			/* directory inodes start off with i_nlink == 2 (for "." entry) */
+			inode->i_nlink++;
+			break;
+		case S_IFLNK:
+			inode->i_op = &page_symlink_inode_operations;
+			break;
+		}
+	}
+	return inode;
+}
+
+/*
+ * File creation. Allocate an inode, and we're done..
+ */
+/* SMP-safe */
+static int hugetlbfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev)
+{
+	struct inode * inode = hugetlbfs_get_inode(dir->i_sb, mode, dev);
+	int error = -ENOSPC;
+
+	if (inode) {
+		d_instantiate(dentry, inode);
+		dget(dentry);		/* Extra count - pin the dentry in core */
+		error = 0;
+	}
+	return error;
+}
+
+static int hugetlbfs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
+{
+	int retval = hugetlbfs_mknod(dir, dentry, mode | S_IFDIR, 0);
+	if (!retval)
+		dir->i_nlink++;
+	return retval;
+}
+
+static int hugetlbfs_create(struct inode *dir, struct dentry *dentry, int mode)
+{
+	return hugetlbfs_mknod(dir, dentry, mode | S_IFREG, 0);
+}
+
+static int hugetlbfs_symlink(struct inode * dir, struct dentry *dentry, const char * symname)
+{
+	struct inode *inode;
+	int error = -ENOSPC;
+
+	inode = hugetlbfs_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0);
+	if (inode) {
+		int l = strlen(symname)+1;
+		error = page_symlink(inode, symname, l);
+		if (!error) {
+			d_instantiate(dentry, inode);
+			dget(dentry);
+		} else
+			iput(inode);
+	}
+	return error;
+}
+
+static struct address_space_operations hugetlbfs_aops = {
+	readpage:	hugetlbfs_readpage,
+	writepage:	fail_writepage,
+	prepare_write:	hugetlbfs_prepare_write,
+	commit_write:	hugetlbfs_commit_write
+};
+
+struct file_operations hugetlbfs_file_operations = {
+	read:		generic_file_read,
+	write:		generic_file_write,
+	mmap:		hugetlbfs_file_mmap,
+	fsync:		simple_sync_file,
+	sendfile:	generic_file_sendfile,
+};
+
+static struct inode_operations hugetlbfs_dir_inode_operations = {
+	create:		hugetlbfs_create,
+	lookup:		simple_lookup,
+	link:		simple_link,
+	unlink:		simple_unlink,
+	symlink:	hugetlbfs_symlink,
+	mkdir:		hugetlbfs_mkdir,
+	rmdir:		simple_rmdir,
+	mknod:		hugetlbfs_mknod,
+	rename:		simple_rename,
+	setattr:	hugetlbfs_setattr,
+};
+
+static struct super_operations hugetlbfs_ops = {
+	statfs:		simple_statfs,
+	drop_inode:	hugetlbfs_drop_inode,
+};
+
+static int hugetlbfs_fill_super(struct super_block * sb, void * data, int silent)
+{
+	struct inode * inode;
+	struct dentry * root;
+
+	sb->s_blocksize = PAGE_CACHE_SIZE;
+	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+	sb->s_magic = HUGETLBFS_MAGIC;
+	sb->s_op = &hugetlbfs_ops;
+	inode = hugetlbfs_get_inode(sb, S_IFDIR | 0755, 0);
+	if (!inode)
+		return -ENOMEM;
+
+	root = d_alloc_root(inode);
+	if (!root) {
+		iput(inode);
+		return -ENOMEM;
+	}
+	sb->s_root = root;
+	return 0;
+}
+
+static struct super_block *hugetlbfs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_nodev(fs_type, flags, data, hugetlbfs_fill_super);
+}
+
+static struct file_system_type hugetlbfs_fs_type = {
+	name:		"hugetlbfs",
+	get_sb:		hugetlbfs_get_sb,
+	kill_sb:	kill_litter_super,
+};
+
+static struct vfsmount *hugetlbfs_vfsmount;
+
+static atomic_t hugetlbfs_counter = ATOMIC_INIT(0);
+
+struct file *hugetlb_zero_setup(size_t size)
+{
+	int error, n;
+	struct file *file;
+	struct inode *inode;
+	struct dentry *dentry, *root;
+	struct qstr quick_string;
+	char buf[16];
+
+	if (!capable(CAP_IPC_LOCK))
+		return ERR_PTR(-EPERM);
+
+	n = atomic_read(&hugetlbfs_counter);
+	atomic_inc(&hugetlbfs_counter);
+
+	root = hugetlbfs_vfsmount->mnt_root;
+	snprintf(buf, 16, "%d", n);
+	quick_string.name = buf;
+	quick_string.len = strlen(quick_string.name);
+	quick_string.hash = 0;
+	dentry = d_alloc(root, &quick_string);
+	if (!dentry)
+		return ERR_PTR(-ENOMEM);
+
+	error = -ENFILE;
+	file = get_empty_filp();
+	if (!file)
+		goto out_dentry;
+
+	error = -ENOSPC;
+	inode = hugetlbfs_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0);
+	if (!inode)
+		goto out_file;
+
+	d_instantiate(dentry, inode);
+	inode->i_size = size;
+	inode->i_nlink = 0;
+	file->f_vfsmnt = mntget(hugetlbfs_vfsmount);
+	file->f_dentry = dentry;
+	file->f_op = &hugetlbfs_file_operations;
+	file->f_mode = FMODE_WRITE | FMODE_READ;
+	return file;
+
+out_file:
+	put_filp(file);
+out_dentry:
+	dput(dentry);
+	return ERR_PTR(error);
+}
+
+static int __init init_hugetlbfs_fs(void)
+{
+	int error;
+	struct vfsmount *vfsmount;
+
+	error = register_filesystem(&hugetlbfs_fs_type);
+	if (error)
+		return error;
+
+	vfsmount = kern_mount(&hugetlbfs_fs_type);
+
+	if (!IS_ERR(vfsmount)) {
+		hugetlbfs_vfsmount = vfsmount;
+		return 0;
+	}
+
+	error = PTR_ERR(vfsmount);
+	return error;
+}
+
+static void __exit exit_hugetlbfs_fs(void)
+{
+	unregister_filesystem(&hugetlbfs_fs_type);
+}
+
+module_init(init_hugetlbfs_fs)
+module_exit(exit_hugetlbfs_fs)
+
+MODULE_LICENSE("GPL");
diff -Nru a/fs/inode.c b/fs/inode.c
--- a/fs/inode.c	Mon Nov  4 14:31:03 2002
+++ b/fs/inode.c	Mon Nov  4 14:31:03 2002
@@ -142,7 +142,7 @@
 	return inode;
 }
 
-static void destroy_inode(struct inode *inode) 
+void destroy_inode(struct inode *inode) 
 {
 	if (inode_has_buffers(inode))
 		BUG();
@@ -363,57 +363,69 @@
 	return res;
 }
 
+static int can_unuse(struct inode *inode)
+{
+	if (inode->i_state)
+		return 0;
+	if (inode_has_buffers(inode))
+		return 0;
+	if (atomic_read(&inode->i_count))
+		return 0;
+	return 1;
+}
 
 /*
- * This is called with the inode lock held. It searches
- * the in-use for freeable inodes, which are moved to a
- * temporary list and then placed on the unused list by
- * dispose_list. 
- *
- * We don't expect to have to call this very often.
+ * Scan `goal' inodes on the unused list for freeable ones. They are moved to
+ * a temporary list and then are freed outside inode_lock by dispose_list().
  *
- * N.B. The spinlock is released during the call to
- *      dispose_list.
+ * Any inodes which are pinned purely because of attached pagecache have their
+ * pagecache removed.  We expect the final iput() on that inode to add it to
+ * the front of the inode_unused list.  So look for it there and if the
+ * inode is still freeable, proceed.  The right inode is found 99.9% of the
+ * time in testing on a 4-way.
  */
-#define CAN_UNUSE(inode) \
-	((((inode)->i_state | (inode)->i_data.nrpages) == 0)  && \
-	 !inode_has_buffers(inode))
-#define INODE(entry)	(list_entry(entry, struct inode, i_list))
-
-static inline void prune_icache(int goal)
-{
-	LIST_HEAD(list);
-	struct list_head *entry, *freeable = &list;
-	int count;
-	struct inode * inode;
+static void prune_icache(int nr_to_scan)
+{
+	LIST_HEAD(freeable);
+	int nr_pruned = 0;
+	int nr_scanned;
 
 	spin_lock(&inode_lock);
+	for (nr_scanned = 0; nr_scanned < nr_to_scan; nr_scanned++) {
+		struct inode *inode;
 
-	count = 0;
-	entry = inode_unused.prev;
-	for(; goal; goal--) {
-		struct list_head *tmp = entry;
-
-		if (entry == &inode_unused)
+		if (list_empty(&inode_unused))
 			break;
-		entry = entry->prev;
-		inode = INODE(tmp);
-		if (inode->i_state & (I_FREEING|I_CLEAR|I_LOCK))
-			continue;
-		if (!CAN_UNUSE(inode))
-			continue;
-		if (atomic_read(&inode->i_count))
+
+		inode = list_entry(inode_unused.prev, struct inode, i_list);
+
+		if (!can_unuse(inode)) {
+			list_move(&inode->i_list, &inode_unused);
 			continue;
-		list_del(tmp);
+		}
+		if (inode->i_data.nrpages) {
+			__iget(inode);
+			spin_unlock(&inode_lock);
+			invalidate_inode_pages(&inode->i_data);
+			iput(inode);
+			spin_lock(&inode_lock);
+
+			if (inode != list_entry(inode_unused.next,
+						struct inode, i_list))
+				continue;	/* wrong inode or list_empty */
+			if (!can_unuse(inode))
+				continue;
+			if (inode->i_data.nrpages)
+				continue;
+		}
 		list_del_init(&inode->i_hash);
-		list_add(tmp, freeable);
+		list_move(&inode->i_list, &freeable);
 		inode->i_state |= I_FREEING;
-		count++;
+		nr_pruned++;
 	}
-	inodes_stat.nr_unused -= count;
+	inodes_stat.nr_unused -= nr_pruned;
 	spin_unlock(&inode_lock);
-
-	dispose_list(freeable);
+	dispose_list(&freeable);
 }
 
 /*
diff -Nru a/fs/jfs/Makefile b/fs/jfs/Makefile
--- a/fs/jfs/Makefile	Mon Nov  4 14:31:02 2002
+++ b/fs/jfs/Makefile	Mon Nov  4 14:31:02 2002
@@ -10,6 +10,10 @@
 	    jfs_extent.o symlink.o jfs_metapage.o \
 	    jfs_logmgr.o jfs_txnmgr.o jfs_uniupr.o resize.o xattr.o
 
+ifeq ($(CONFIG_JFS_POSIX_ACL),y)
+jfs-objs += acl.o
+endif
+
 EXTRA_CFLAGS += -D_JFS_4K
 
 include $(TOPDIR)/Rules.make
diff -Nru a/fs/jfs/file.c b/fs/jfs/file.c
--- a/fs/jfs/file.c	Mon Nov  4 14:31:01 2002
+++ b/fs/jfs/file.c	Mon Nov  4 14:31:01 2002
@@ -22,6 +22,7 @@
 #include "jfs_dmap.h"
 #include "jfs_txnmgr.h"
 #include "jfs_xattr.h"
+#include "jfs_acl.h"
 #include "jfs_debug.h"
 
 
@@ -142,6 +143,10 @@
 	.getxattr	= jfs_getxattr,
 	.listxattr	= jfs_listxattr,
 	.removexattr	= jfs_removexattr,
+#ifdef CONFIG_JFS_POSIX_ACL
+	.setattr	= jfs_setattr,
+	.permission	= jfs_permission,
+#endif
 };
 
 struct file_operations jfs_file_operations = {
diff -Nru a/fs/jfs/jfs_incore.h b/fs/jfs/jfs_incore.h
--- a/fs/jfs/jfs_incore.h	Mon Nov  4 14:31:00 2002
+++ b/fs/jfs/jfs_incore.h	Mon Nov  4 14:31:00 2002
@@ -69,6 +69,10 @@
 	 */
 	struct semaphore commit_sem;
 	lid_t	xtlid;		/* lid of xtree lock on directory */
+#ifdef CONFIG_JFS_POSIX_ACL
+	struct posix_acl *i_acl;
+	struct posix_acl *i_default_acl;
+#endif
 	union {
 		struct {
 			xtpage_t _xtroot;	/* 288: xtree root */
@@ -97,6 +101,7 @@
 #define i_inline u.link._inline
 #define i_inline_ea u.link._inline_ea
 
+#define JFS_ACL_NOT_CACHED ((void *)-1)
 
 #define IREAD_LOCK(ip)		down_read(&JFS_IP(ip)->rdwrlock)
 #define IREAD_UNLOCK(ip)	up_read(&JFS_IP(ip)->rdwrlock)
diff -Nru a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
--- a/fs/jfs/jfs_txnmgr.c	Mon Nov  4 14:31:02 2002
+++ b/fs/jfs/jfs_txnmgr.c	Mon Nov  4 14:31:02 2002
@@ -2209,9 +2209,21 @@
 				tlck->flag &= ~tlckWRITEPAGE;
 
 				/* do not release page to freelist */
+
+				/*
+				 * The "right" thing to do here is to
+				 * synchronously write the metadata.
+				 * With the current implementation this
+				 * is hard since write_metapage requires
+				 * us to kunmap & remap the page.  If we
+				 * have tlocks pointing into the metadata
+				 * pages, we don't want to do this.  I think
+				 * we can get by with synchronously writing
+				 * the pages when they are released.
+				 */
 				assert(atomic_read(&mp->nohomeok));
-				hold_metapage(mp, 0);
-				write_metapage(mp);
+				set_bit(META_dirty, &mp->flag);
+				set_bit(META_sync, &mp->flag);
 			}
 		}
 	}
diff -Nru a/fs/jfs/namei.c b/fs/jfs/namei.c
--- a/fs/jfs/namei.c	Mon Nov  4 14:31:02 2002
+++ b/fs/jfs/namei.c	Mon Nov  4 14:31:02 2002
@@ -25,6 +25,7 @@
 #include "jfs_unicode.h"
 #include "jfs_metapage.h"
 #include "jfs_xattr.h"
+#include "jfs_acl.h"
 #include "jfs_debug.h"
 
 extern struct inode_operations jfs_file_inode_operations;
@@ -35,6 +36,7 @@
 extern int jfs_fsync(struct file *, struct dentry *, int);
 extern void jfs_truncate_nolock(struct inode *, loff_t);
 extern struct inode *jfs_iget(struct super_block *, ino_t);
+extern int jfs_init_acl(struct inode *, struct inode *);
 
 /*
  * forward references
@@ -150,6 +152,11 @@
       out2:
 	free_UCSname(&dname);
 
+#ifdef CONFIG_JFS_POSIX_ACL
+	if (rc == 0)
+		jfs_init_acl(ip, dip);
+#endif
+
       out1:
 
 	jFYI(1, ("jfs_create: rc:%d\n", -rc));
@@ -275,6 +282,11 @@
       out2:
 	free_UCSname(&dname);
 
+#ifdef CONFIG_JFS_POSIX_ACL
+	if (rc == 0)
+		jfs_init_acl(ip, dip);
+#endif
+
       out1:
 
 	jFYI(1, ("jfs_mkdir: rc:%d\n", -rc));
@@ -1016,6 +1028,11 @@
       out2:
 	free_UCSname(&dname);
 
+#ifdef CONFIG_JFS_POSIX_ACL
+	if (rc == 0)
+		jfs_init_acl(ip, dip);
+#endif
+
       out1:
 	jFYI(1, ("jfs_symlink: rc:%d\n", -rc));
 	return -rc;
@@ -1364,6 +1381,11 @@
       out1:
 	free_UCSname(&dname);
 
+#ifdef CONFIG_JFS_POSIX_ACL
+	if (rc == 0)
+		jfs_init_acl(ip, dir);
+#endif
+
       out:
 	jFYI(1, ("jfs_mknod: returning %d\n", rc));
 	return -rc;
@@ -1445,6 +1467,10 @@
 	.getxattr	= jfs_getxattr,
 	.listxattr	= jfs_listxattr,
 	.removexattr	= jfs_removexattr,
+#ifdef CONFIG_JFS_POSIX_ACL
+	.setattr	= jfs_setattr,
+	.permission	= jfs_permission,
+#endif
 };
 
 struct file_operations jfs_dir_operations = {
diff -Nru a/fs/jfs/super.c b/fs/jfs/super.c
--- a/fs/jfs/super.c	Mon Nov  4 14:31:01 2002
+++ b/fs/jfs/super.c	Mon Nov  4 14:31:01 2002
@@ -28,6 +28,7 @@
 #include "jfs_superblock.h"
 #include "jfs_dmap.h"
 #include "jfs_imap.h"
+#include "jfs_acl.h"
 #include "jfs_debug.h"
 
 MODULE_DESCRIPTION("The Journaled Filesystem (JFS)");
@@ -94,7 +95,16 @@
 
 static void jfs_destroy_inode(struct inode *inode)
 {
-	kmem_cache_free(jfs_inode_cachep, JFS_IP(inode));
+	struct jfs_inode_info *ji = JFS_IP(inode);
+
+#ifdef CONFIG_JFS_POSIX_ACL
+	if (ji->i_acl && (ji->i_acl != JFS_ACL_NOT_CACHED))
+		posix_acl_release(ji->i_acl);
+	if (ji->i_default_acl && (ji->i_default_acl != JFS_ACL_NOT_CACHED))
+		posix_acl_release(ji->i_default_acl);
+#endif
+
+	kmem_cache_free(jfs_inode_cachep, ji);
 }
 
 static int jfs_statfs(struct super_block *sb, struct statfs *buf)
@@ -407,6 +417,10 @@
 		init_MUTEX(&jfs_ip->commit_sem);
 		jfs_ip->atlhead = 0;
 		jfs_ip->active_ag = -1;
+#ifdef CONFIG_JFS_POSIX_ACL
+		jfs_ip->i_acl = JFS_ACL_NOT_CACHED;
+		jfs_ip->i_default_acl = JFS_ACL_NOT_CACHED;
+#endif
 		inode_init_once(&jfs_ip->vfs_inode);
 	}
 }
diff -Nru a/fs/jfs/xattr.c b/fs/jfs/xattr.c
--- a/fs/jfs/xattr.c	Mon Nov  4 14:31:01 2002
+++ b/fs/jfs/xattr.c	Mon Nov  4 14:31:01 2002
@@ -26,6 +26,7 @@
 #include "jfs_extent.h"
 #include "jfs_metapage.h"
 #include "jfs_xattr.h"
+#include "jfs_acl.h"
 
 /*
  *	jfs_xattr.c: extended attribute service
@@ -201,7 +202,6 @@
 			ji->mode2 |= INLINEEA;
 	}
 
-	mark_inode_dirty(ip);
 	return 0;
 }
 
@@ -640,6 +640,71 @@
 	return rc;
 }
 
+/*
+ * can_set_system_xattr
+ *
+ * This code is specific to the system.* namespace.  It contains policy
+ * which doesn't belong in the main xattr codepath.
+ */
+static int can_set_system_xattr(struct inode *inode, const char *name,
+				const void *value, size_t value_len)
+{
+#ifdef CONFIG_JFS_POSIX_ACL
+	struct posix_acl *acl;
+	int rc;
+
+	if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+		return -EPERM;
+
+	/*
+	 * XATTR_NAME_ACL_ACCESS is tied to i_mode
+	 */
+	if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0) {
+		acl = posix_acl_from_xattr(value, value_len);
+		if (acl < 0) {
+			printk(KERN_ERR "posix_acl_from_xattr returned %d\n",
+			       rc);
+			return rc;
+		}
+		if (acl > 0) {
+			mode_t mode = inode->i_mode;
+			rc = posix_acl_equiv_mode(acl, &mode);
+			posix_acl_release(acl);
+			if (rc < 0) {
+				printk(KERN_ERR
+				       "posix_acl_equiv_mode returned %d\n",
+				       rc);
+				return rc;
+			}
+			inode->i_mode = mode;
+			mark_inode_dirty(inode);
+			if (rc == 0)
+				value = NULL;
+		}
+		/*
+		 * We're changing the ACL.  Get rid of the cached one
+		 */
+		acl =JFS_IP(inode)->i_acl;
+		if (acl && (acl != JFS_ACL_NOT_CACHED))
+			posix_acl_release(acl);
+		JFS_IP(inode)->i_acl = JFS_ACL_NOT_CACHED;
+	} else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0) {
+		/*
+		 * We're changing the default ACL.  Get rid of the cached one
+		 */
+		acl =JFS_IP(inode)->i_default_acl;
+		if (acl && (acl != JFS_ACL_NOT_CACHED))
+			posix_acl_release(acl);
+		JFS_IP(inode)->i_default_acl = JFS_ACL_NOT_CACHED;
+	} else
+		/* Invalid xattr name */
+		return -EINVAL;
+	return 0;
+#else			/* CONFIG_JFS_POSIX_ACL */
+	return -EOPNOTSUPP;
+#endif			/* CONFIG_JFS_POSIX_ACL */
+}
+
 static int can_set_xattr(struct inode *inode, const char *name,
 			 void *value, size_t value_len)
 {
@@ -649,6 +714,12 @@
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode) || S_ISLNK(inode->i_mode))
 		return -EPERM;
 
+	if(strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) == 0)
+		/*
+		 * "system.*"
+		 */
+		return can_set_system_xattr(inode, name, value, value_len);
+
 	if((strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) != 0) &&
 	   (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) != 0))
 		return -EOPNOTSUPP;
@@ -657,7 +728,11 @@
 	    (!S_ISDIR(inode->i_mode) || inode->i_mode &S_ISVTX))
 		return -EPERM;
 
+#ifdef CONFIG_JFS_POSIX_ACL
+	return jfs_permission_have_sem(inode, MAY_WRITE);
+#else
 	return permission(inode, MAY_WRITE);
+#endif
 }
 
 int __jfs_setxattr(struct inode *inode, const char *name, void *value,
@@ -810,9 +885,16 @@
 	return __jfs_setxattr(dentry->d_inode, name, value, value_len, flags);
 }
 
-static inline int can_get_xattr(struct inode *inode, const char *name)
+static int can_get_xattr(struct inode *inode, const char *name)
 {
+#ifdef CONFIG_JFS_POSIX_ACL
+	if(strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) == 0)
+		return 0;
+	else
+		return jfs_permission_have_sem(inode, MAY_READ);
+#else
 	return permission(inode, MAY_READ);
+#endif
 }
 
 ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
diff -Nru a/fs/mbcache.c b/fs/mbcache.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/mbcache.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,702 @@
+/*
+ * linux/fs/mbcache.c
+ * (C) 2001-2002 Andreas Gruenbacher, <a.gruenbacher@computer.org>
+ */
+
+/*
+ * Filesystem Meta Information Block Cache (mbcache)
+ *
+ * The mbcache caches blocks of block devices that need to be located
+ * by their device/block number, as well as by other criteria (such
+ * as the block's contents).
+ *
+ * There can only be one cache entry in a cache per device and block number.
+ * Additional indexes need not be unique in this sense. The number of
+ * additional indexes (=other criteria) can be hardwired (at compile time)
+ * or specified at cache create time.
+ *
+ * Each cache entry is of fixed size. An entry may be `valid' or `invalid'
+ * in the cache. A valid entry is in the main hash tables of the cache,
+ * and may also be in the lru list. An invalid entry is not in any hashes
+ * or lists.
+ *
+ * A valid cache entry is only in the lru list if no handles refer to it.
+ * Invalid cache entries will be freed when the last handle to the cache
+ * entry is released.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <linux/hash.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/mbcache.h>
+
+
+#ifdef MB_CACHE_DEBUG
+# define mb_debug(f...) do { \
+		printk(KERN_DEBUG f); \
+		printk("\n"); \
+	} while (0)
+#define mb_assert(c) do { if (!(c)) \
+		printk(KERN_ERR "assertion " #c " failed\n"); \
+	} while(0)
+#else
+# define mb_debug(f...) do { } while(0)
+# define mb_assert(c) do { } while(0)
+#endif
+#define mb_error(f...) do { \
+		printk(KERN_ERR f); \
+		printk("\n"); \
+	} while(0)
+		
+MODULE_AUTHOR("Andreas Gruenbacher <a.gruenbacher@computer.org>");
+MODULE_DESCRIPTION("Meta block cache (for extended attributes)");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(mb_cache_create);
+EXPORT_SYMBOL(mb_cache_shrink);
+EXPORT_SYMBOL(mb_cache_destroy);
+EXPORT_SYMBOL(mb_cache_entry_alloc);
+EXPORT_SYMBOL(mb_cache_entry_insert);
+EXPORT_SYMBOL(mb_cache_entry_release);
+EXPORT_SYMBOL(mb_cache_entry_takeout);
+EXPORT_SYMBOL(mb_cache_entry_free);
+EXPORT_SYMBOL(mb_cache_entry_dup);
+EXPORT_SYMBOL(mb_cache_entry_get);
+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
+EXPORT_SYMBOL(mb_cache_entry_find_first);
+EXPORT_SYMBOL(mb_cache_entry_find_next);
+#endif
+
+
+/*
+ * Global data: list of all mbcache's, lru list, and a spinlock for
+ * accessing cache data structures on SMP machines. (The lru list is
+ * global across all mbcaches.)
+ */
+
+static LIST_HEAD(mb_cache_list);
+static LIST_HEAD(mb_cache_lru_list);
+static spinlock_t mb_cache_spinlock = SPIN_LOCK_UNLOCKED;
+static struct shrinker *mb_shrinker;
+
+static inline int
+mb_cache_indexes(struct mb_cache *cache)
+{
+#ifdef MB_CACHE_INDEXES_COUNT
+	return MB_CACHE_INDEXES_COUNT;
+#else
+	return cache->c_indexes_count;
+#endif
+}
+
+/*
+ * What the mbcache registers as to get shrunk dynamically.
+ */
+
+static int mb_cache_shrink_fn(int nr_to_scan, unsigned int gfp_mask);
+
+static inline void
+__mb_cache_entry_takeout_lru(struct mb_cache_entry *ce)
+{
+	if (!list_empty(&ce->e_lru_list))
+		list_del_init(&ce->e_lru_list);
+}
+
+
+static inline void
+__mb_cache_entry_into_lru(struct mb_cache_entry *ce)
+{
+	list_add(&ce->e_lru_list, &mb_cache_lru_list);
+}
+
+
+static inline int
+__mb_cache_entry_in_lru(struct mb_cache_entry *ce)
+{
+	return (!list_empty(&ce->e_lru_list));
+}
+
+
+/*
+ * Insert the cache entry into all hashes.
+ */
+static inline void
+__mb_cache_entry_link(struct mb_cache_entry *ce)
+{
+	struct mb_cache *cache = ce->e_cache;
+	unsigned int bucket;
+	int n;
+	
+	bucket = hash_long((unsigned long)ce->e_bdev +
+			   (ce->e_block & 0xffffff), cache->c_bucket_bits);
+	list_add(&ce->e_block_list, &cache->c_block_hash[bucket]);
+	for (n=0; n<mb_cache_indexes(cache); n++) {
+		bucket = hash_long(ce->e_indexes[n].o_key,
+				   cache->c_bucket_bits);
+		list_add(&ce->e_indexes[n].o_list,
+		         &cache->c_indexes_hash[n][bucket]);
+	}
+}
+
+
+/*
+ * Remove the cache entry from all hashes.
+ */
+static inline void
+__mb_cache_entry_unlink(struct mb_cache_entry *ce)
+{
+	int n;
+
+	list_del_init(&ce->e_block_list);
+	for (n = 0; n < mb_cache_indexes(ce->e_cache); n++)
+		list_del(&ce->e_indexes[n].o_list);
+}
+
+
+static inline int
+__mb_cache_entry_is_linked(struct mb_cache_entry *ce)
+{
+	return (!list_empty(&ce->e_block_list));
+}
+
+
+static inline struct mb_cache_entry *
+__mb_cache_entry_read(struct mb_cache_entry *ce)
+{
+	__mb_cache_entry_takeout_lru(ce);
+	atomic_inc(&ce->e_used);
+	return ce;
+}
+
+
+static inline void
+__mb_cache_entry_forget(struct mb_cache_entry *ce)
+{
+	struct mb_cache *cache = ce->e_cache;
+
+	mb_assert(atomic_read(&ce->e_used) == 0);
+	atomic_dec(&cache->c_entry_count);
+	if (cache->c_op.free)
+		cache->c_op.free(ce);
+	kmem_cache_free(cache->c_entry_cache, ce);
+}
+
+
+static inline void
+__mb_cache_entry_release_unlock(struct mb_cache_entry *ce)
+{
+	if (atomic_dec_and_test(&ce->e_used)) {
+		if (!__mb_cache_entry_is_linked(ce))
+			goto forget;
+		__mb_cache_entry_into_lru(ce);
+	}
+	spin_unlock(&mb_cache_spinlock);
+	return;
+forget:
+	spin_unlock(&mb_cache_spinlock);
+	__mb_cache_entry_forget(ce);
+}
+
+
+/*
+ * mb_cache_shrink_fn()  memory pressure callback
+ *
+ * This function is called by the kernel memory management when memory
+ * gets low.
+ *
+ * @nr_to_scan: Number of objects to scan
+ * @gfp_mask: (ignored)
+ *
+ * Returns the number of objects which are present in the cache.
+ */
+static int
+mb_cache_shrink_fn(int nr_to_scan, unsigned int gfp_mask)
+{
+	LIST_HEAD(free_list);
+	struct list_head *l;
+	int count = 0;
+
+	spin_lock(&mb_cache_spinlock);
+	list_for_each_prev(l, &mb_cache_list) {
+		struct mb_cache *cache =
+			list_entry(l, struct mb_cache, c_cache_list);
+		mb_debug("cache %s (%d)", cache->c_name,
+			  atomic_read(&cache->c_entry_count));
+		count += atomic_read(&cache->c_entry_count);
+	}
+	mb_debug("trying to free %d entries", nr_to_scan);
+	if (nr_to_scan == 0) {
+		spin_unlock(&mb_cache_spinlock);
+		goto out;
+	}
+	while (nr_to_scan && !list_empty(&mb_cache_lru_list)) {
+		struct mb_cache_entry *ce =
+			list_entry(mb_cache_lru_list.prev,
+				   struct mb_cache_entry, e_lru_list);
+		list_move(&ce->e_lru_list, &free_list);
+		if (__mb_cache_entry_is_linked(ce))
+			__mb_cache_entry_unlink(ce);
+		nr_to_scan--;
+	}
+	spin_unlock(&mb_cache_spinlock);
+	l = free_list.prev;
+	while (l != &free_list) {
+		struct mb_cache_entry *ce = list_entry(l,
+			struct mb_cache_entry, e_lru_list);
+		l = l->prev;
+		__mb_cache_entry_forget(ce);
+		count--;
+	}
+out:
+	mb_debug("%d remaining entries ", count);
+	return count;
+}
+
+
+/*
+ * mb_cache_create()  create a new cache
+ *
+ * All entries in one cache are equal size. Cache entries may be from
+ * multiple devices. If this is the first mbcache created, registers
+ * the cache with kernel memory management. Returns NULL if no more
+ * memory was available.
+ *
+ * @name: name of the cache (informal)
+ * @cache_op: contains the callback called when freeing a cache entry
+ * @entry_size: The size of a cache entry, including
+ *              struct mb_cache_entry
+ * @indexes_count: number of additional indexes in the cache. Must equal
+ *                 MB_CACHE_INDEXES_COUNT if the number of indexes is
+ *                 hardwired.
+ * @bucket_bits: log2(number of hash buckets)
+ */
+struct mb_cache *
+mb_cache_create(const char *name, struct mb_cache_op *cache_op,
+		size_t entry_size, int indexes_count, int bucket_bits)
+{
+	int m=0, n, bucket_count = 1 << bucket_bits;
+	struct mb_cache *cache = NULL;
+
+	if(entry_size < sizeof(struct mb_cache_entry) +
+	   indexes_count * sizeof(struct mb_cache_entry_index))
+		return NULL;
+
+	cache = kmalloc(sizeof(struct mb_cache) +
+	                indexes_count * sizeof(struct list_head), GFP_KERNEL);
+	if (!cache)
+		goto fail;
+	cache->c_name = name;
+	if (cache_op)
+		cache->c_op.free = cache_op->free;
+	else
+		cache->c_op.free = NULL;
+	atomic_set(&cache->c_entry_count, 0);
+	cache->c_bucket_bits = bucket_bits;
+#ifdef MB_CACHE_INDEXES_COUNT
+	mb_assert(indexes_count == MB_CACHE_INDEXES_COUNT);
+#else
+	cache->c_indexes_count = indexes_count;
+#endif
+	cache->c_block_hash = kmalloc(bucket_count * sizeof(struct list_head),
+	                              GFP_KERNEL);
+	if (!cache->c_block_hash)
+		goto fail;
+	for (n=0; n<bucket_count; n++)
+		INIT_LIST_HEAD(&cache->c_block_hash[n]);
+	for (m=0; m<indexes_count; m++) {
+		cache->c_indexes_hash[m] = kmalloc(bucket_count *
+		                                 sizeof(struct list_head),
+		                                 GFP_KERNEL);
+		if (!cache->c_indexes_hash[m])
+			goto fail;
+		for (n=0; n<bucket_count; n++)
+			INIT_LIST_HEAD(&cache->c_indexes_hash[m][n]);
+	}
+	cache->c_entry_cache = kmem_cache_create(name, entry_size, 0,
+		0 /*SLAB_POISON | SLAB_RED_ZONE*/, NULL, NULL);
+	if (!cache->c_entry_cache)
+		goto fail;
+
+	spin_lock(&mb_cache_spinlock);
+	if (list_empty(&mb_cache_list)) {
+		if (mb_shrinker) {
+			printk(KERN_ERR "%s: already have a shrinker!\n",
+					__FUNCTION__);
+			remove_shrinker(mb_shrinker);
+		}
+		mb_shrinker = set_shrinker(DEFAULT_SEEKS, mb_cache_shrink_fn);
+	}
+	list_add(&cache->c_cache_list, &mb_cache_list);
+	spin_unlock(&mb_cache_spinlock);
+	return cache;
+
+fail:
+	if (cache) {
+		while (--m >= 0)
+			kfree(cache->c_indexes_hash[m]);
+		if (cache->c_block_hash)
+			kfree(cache->c_block_hash);
+		kfree(cache);
+	}
+	return NULL;
+}
+
+
+/*
+ * mb_cache_shrink()
+ *
+ * Removes all cache entires of a device from the cache. All cache entries
+ * currently in use cannot be freed, and thus remain in the cache. All others
+ * are freed.
+ *
+ * @cache: which cache to shrink
+ * @bdev: which device's cache entries to shrink
+ */
+void
+mb_cache_shrink(struct mb_cache *cache, struct block_device *bdev)
+{
+	LIST_HEAD(free_list);
+	struct list_head *l;
+
+	spin_lock(&mb_cache_spinlock);
+	l = mb_cache_lru_list.prev;
+	while (l != &mb_cache_lru_list) {
+		struct mb_cache_entry *ce =
+			list_entry(l, struct mb_cache_entry, e_lru_list);
+		l = l->prev;
+		if (ce->e_bdev == bdev) {
+			list_move(&ce->e_lru_list, &free_list);
+			if (__mb_cache_entry_is_linked(ce))
+				__mb_cache_entry_unlink(ce);
+		}
+	}
+	spin_unlock(&mb_cache_spinlock);
+	l = free_list.prev;
+	while (l != &free_list) {
+		struct mb_cache_entry *ce =
+			list_entry(l, struct mb_cache_entry, e_lru_list);
+		l = l->prev;
+		__mb_cache_entry_forget(ce);
+	}
+}
+
+
+/*
+ * mb_cache_destroy()
+ *
+ * Shrinks the cache to its minimum possible size (hopefully 0 entries),
+ * and then destroys it. If this was the last mbcache, un-registers the
+ * mbcache from kernel memory management.
+ */
+void
+mb_cache_destroy(struct mb_cache *cache)
+{
+	LIST_HEAD(free_list);
+	struct list_head *l;
+	int n;
+
+	spin_lock(&mb_cache_spinlock);
+	l = mb_cache_lru_list.prev;
+	while (l != &mb_cache_lru_list) {
+		struct mb_cache_entry *ce =
+			list_entry(l, struct mb_cache_entry, e_lru_list);
+		l = l->prev;
+		if (ce->e_cache == cache) {
+			list_move(&ce->e_lru_list, &free_list);
+			if (__mb_cache_entry_is_linked(ce))
+				__mb_cache_entry_unlink(ce);
+		}
+	}
+	list_del(&cache->c_cache_list);
+	if (list_empty(&mb_cache_list) && mb_shrinker) {
+		remove_shrinker(mb_shrinker);
+		mb_shrinker = 0;
+	}
+	spin_unlock(&mb_cache_spinlock);
+
+	l = free_list.prev;
+	while (l != &free_list) {
+		struct mb_cache_entry *ce =
+			list_entry(l, struct mb_cache_entry, e_lru_list);
+		l = l->prev;
+		__mb_cache_entry_forget(ce);
+	}
+
+	if (atomic_read(&cache->c_entry_count) > 0) {
+		mb_error("cache %s: %d orphaned entries",
+			  cache->c_name,
+			  atomic_read(&cache->c_entry_count));
+	}
+
+	kmem_cache_destroy(cache->c_entry_cache);
+
+	for (n=0; n < mb_cache_indexes(cache); n++)
+		kfree(cache->c_indexes_hash[n]);
+	kfree(cache->c_block_hash);
+
+	kfree(cache);
+}
+
+
+/*
+ * mb_cache_entry_alloc()
+ *
+ * Allocates a new cache entry. The new entry will not be valid initially,
+ * and thus cannot be looked up yet. It should be filled with data, and
+ * then inserted into the cache using mb_cache_entry_insert(). Returns NULL
+ * if no more memory was available.
+ */
+struct mb_cache_entry *
+mb_cache_entry_alloc(struct mb_cache *cache)
+{
+	struct mb_cache_entry *ce;
+
+	atomic_inc(&cache->c_entry_count);
+	ce = kmem_cache_alloc(cache->c_entry_cache, GFP_KERNEL);
+	if (ce) {
+		INIT_LIST_HEAD(&ce->e_lru_list);
+		INIT_LIST_HEAD(&ce->e_block_list);
+		ce->e_cache = cache;
+		atomic_set(&ce->e_used, 1);
+	}
+	return ce;
+}
+
+
+/*
+ * mb_cache_entry_insert()
+ *
+ * Inserts an entry that was allocated using mb_cache_entry_alloc() into
+ * the cache. After this, the cache entry can be looked up, but is not yet
+ * in the lru list as the caller still holds a handle to it. Returns 0 on
+ * success, or -EBUSY if a cache entry for that device + inode exists
+ * already (this may happen after a failed lookup, but when another process
+ * has inserted the same cache entry in the meantime).
+ *
+ * @bdev: device the cache entry belongs to
+ * @block: block number
+ * @keys: array of additional keys. There must be indexes_count entries
+ *        in the array (as specified when creating the cache).
+ */
+int
+mb_cache_entry_insert(struct mb_cache_entry *ce, struct block_device *bdev,
+		      sector_t block, unsigned int keys[])
+{
+	struct mb_cache *cache = ce->e_cache;
+	unsigned int bucket;
+	struct list_head *l;
+	int error = -EBUSY, n;
+
+	bucket =  hash_long((unsigned long)bdev + (block & 0xffffffff), 
+			    cache->c_bucket_bits);
+	spin_lock(&mb_cache_spinlock);
+	list_for_each_prev(l, &cache->c_block_hash[bucket]) {
+		struct mb_cache_entry *ce =
+			list_entry(l, struct mb_cache_entry, e_block_list);
+		if (ce->e_bdev == bdev && ce->e_block == block)
+			goto out;
+	}
+	mb_assert(!__mb_cache_entry_is_linked(ce));
+	ce->e_bdev = bdev;
+	ce->e_block = block;
+	for (n=0; n<mb_cache_indexes(cache); n++)
+		ce->e_indexes[n].o_key = keys[n];
+	__mb_cache_entry_link(ce);
+out:
+	spin_unlock(&mb_cache_spinlock);
+	return error;
+}
+
+
+/*
+ * mb_cache_entry_release()
+ *
+ * Release a handle to a cache entry. When the last handle to a cache entry
+ * is released it is either freed (if it is invalid) or otherwise inserted
+ * in to the lru list.
+ */
+void
+mb_cache_entry_release(struct mb_cache_entry *ce)
+{
+	spin_lock(&mb_cache_spinlock);
+	__mb_cache_entry_release_unlock(ce);
+}
+
+
+/*
+ * mb_cache_entry_takeout()
+ *
+ * Take a cache entry out of the cache, making it invalid. The entry can later
+ * be re-inserted using mb_cache_entry_insert(), or released using
+ * mb_cache_entry_release().
+ */
+void
+mb_cache_entry_takeout(struct mb_cache_entry *ce)
+{
+	spin_lock(&mb_cache_spinlock);
+	mb_assert(!__mb_cache_entry_in_lru(ce));
+	if (__mb_cache_entry_is_linked(ce))
+		__mb_cache_entry_unlink(ce);
+	spin_unlock(&mb_cache_spinlock);
+}
+
+
+/*
+ * mb_cache_entry_free()
+ *
+ * This is equivalent to the sequence mb_cache_entry_takeout() --
+ * mb_cache_entry_release().
+ */
+void
+mb_cache_entry_free(struct mb_cache_entry *ce)
+{
+	spin_lock(&mb_cache_spinlock);
+	mb_assert(!__mb_cache_entry_in_lru(ce));
+	if (__mb_cache_entry_is_linked(ce))
+		__mb_cache_entry_unlink(ce);
+	__mb_cache_entry_release_unlock(ce);
+}
+
+
+/*
+ * mb_cache_entry_dup()
+ *
+ * Duplicate a handle to a cache entry (does not duplicate the cache entry
+ * itself). After the call, both the old and the new handle must be released.
+ */
+struct mb_cache_entry *
+mb_cache_entry_dup(struct mb_cache_entry *ce)
+{
+	atomic_inc(&ce->e_used);
+	return ce;
+}
+
+
+/*
+ * mb_cache_entry_get()
+ *
+ * Get a cache entry  by device / block number. (There can only be one entry
+ * in the cache per device and block.) Returns NULL if no such cache entry
+ * exists.
+ */
+struct mb_cache_entry *
+mb_cache_entry_get(struct mb_cache *cache, struct block_device *bdev,
+		   sector_t block)
+{
+	unsigned int bucket;
+	struct list_head *l;
+	struct mb_cache_entry *ce;
+
+	bucket = hash_long((unsigned long)bdev + (block & 0xffffffff),
+			   cache->c_bucket_bits);
+	spin_lock(&mb_cache_spinlock);
+	list_for_each(l, &cache->c_block_hash[bucket]) {
+		ce = list_entry(l, struct mb_cache_entry, e_block_list);
+		if (ce->e_bdev == bdev && ce->e_block == block) {
+			ce = __mb_cache_entry_read(ce);
+			goto cleanup;
+		}
+	}
+	ce = NULL;
+
+cleanup:
+	spin_unlock(&mb_cache_spinlock);
+	return ce;
+}
+
+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
+
+static struct mb_cache_entry *
+__mb_cache_entry_find(struct list_head *l, struct list_head *head,
+		      int index, struct block_device *bdev, unsigned int key)
+{
+	while (l != head) {
+		struct mb_cache_entry *ce =
+			list_entry(l, struct mb_cache_entry,
+			           e_indexes[index].o_list);
+		if (ce->e_bdev == bdev &&
+		    ce->e_indexes[index].o_key == key) {
+			ce = __mb_cache_entry_read(ce);
+			if (ce)
+				return ce;
+		}
+		l = l->next;
+	}
+	return NULL;
+}
+
+
+/*
+ * mb_cache_entry_find_first()
+ *
+ * Find the first cache entry on a given device with a certain key in
+ * an additional index. Additonal matches can be found with
+ * mb_cache_entry_find_next(). Returns NULL if no match was found.
+ *
+ * @cache: the cache to search
+ * @index: the number of the additonal index to search (0<=index<indexes_count)
+ * @bdev: the device the cache entry should belong to
+ * @key: the key in the index
+ */
+struct mb_cache_entry *
+mb_cache_entry_find_first(struct mb_cache *cache, int index,
+			  struct block_device *bdev, unsigned int key)
+{
+	unsigned int bucket = hash_long(key, cache->c_bucket_bits);
+	struct list_head *l;
+	struct mb_cache_entry *ce;
+
+	mb_assert(index < mb_cache_indexes(cache));
+	spin_lock(&mb_cache_spinlock);
+	l = cache->c_indexes_hash[index][bucket].next;
+	ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket],
+	                           index, bdev, key);
+	spin_unlock(&mb_cache_spinlock);
+	return ce;
+}
+
+
+/*
+ * mb_cache_entry_find_next()
+ *
+ * Find the next cache entry on a given device with a certain key in an
+ * additional index. Returns NULL if no match could be found. The previous
+ * entry is atomatically released, so that mb_cache_entry_find_next() can
+ * be called like this:
+ *
+ * entry = mb_cache_entry_find_first();
+ * while (entry) {
+ * 	...
+ *	entry = mb_cache_entry_find_next(entry, ...);
+ * }
+ *
+ * @prev: The previous match
+ * @index: the number of the additonal index to search (0<=index<indexes_count)
+ * @bdev: the device the cache entry should belong to
+ * @key: the key in the index
+ */
+struct mb_cache_entry *
+mb_cache_entry_find_next(struct mb_cache_entry *prev, int index,
+			 struct block_device *bdev, unsigned int key)
+{
+	struct mb_cache *cache = prev->e_cache;
+	unsigned int bucket = hash_long(key, cache->c_bucket_bits);
+	struct list_head *l;
+	struct mb_cache_entry *ce;
+
+	mb_assert(index < mb_cache_indexes(cache));
+	spin_lock(&mb_cache_spinlock);
+	l = prev->e_indexes[index].o_list.next;
+	ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket],
+	                           index, bdev, key);
+	__mb_cache_entry_release_unlock(prev);
+	return ce;
+}
+
+#endif  /* !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) */
diff -Nru a/fs/namei.c b/fs/namei.c
--- a/fs/namei.c	Mon Nov  4 14:31:01 2002
+++ b/fs/namei.c	Mon Nov  4 14:31:01 2002
@@ -1279,8 +1279,9 @@
 
 	/* Negative dentry, just create the file */
 	if (!dentry->d_inode) {
-		error = vfs_create(dir->d_inode, dentry,
-				   mode & ~current->fs->umask);
+		if (!IS_POSIXACL(dir->d_inode))
+			mode &= ~current->fs->umask;
+		error = vfs_create(dir->d_inode, dentry, mode);
 		up(&dir->d_inode->i_sem);
 		dput(nd->dentry);
 		nd->dentry = dentry;
@@ -1442,7 +1443,8 @@
 	dentry = lookup_create(&nd, 0);
 	error = PTR_ERR(dentry);
 
-	mode &= ~current->fs->umask;
+	if (!IS_POSIXACL(nd.dentry->d_inode))
+		mode &= ~current->fs->umask;
 	if (!IS_ERR(dentry)) {
 		switch (mode & S_IFMT) {
 		case 0: case S_IFREG:
@@ -1508,8 +1510,9 @@
 		dentry = lookup_create(&nd, 1);
 		error = PTR_ERR(dentry);
 		if (!IS_ERR(dentry)) {
-			error = vfs_mkdir(nd.dentry->d_inode, dentry,
-					  mode & ~current->fs->umask);
+			if (!IS_POSIXACL(nd.dentry->d_inode))
+				mode &= ~current->fs->umask;
+			error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
 			dput(dentry);
 		}
 		up(&nd.dentry->d_inode->i_sem);
diff -Nru a/fs/partitions/check.c b/fs/partitions/check.c
--- a/fs/partitions/check.c	Mon Nov  4 14:31:02 2002
+++ b/fs/partitions/check.c	Mon Nov  4 14:31:02 2002
@@ -277,231 +277,146 @@
 #endif
 }
 
-static ssize_t part_dev_read(struct device *dev,
-			char *page, size_t count, loff_t off)
+
+/*
+ * sysfs bindings for partitions
+ */
+
+struct part_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct hd_struct *,char *,size_t,loff_t);
+};
+
+static ssize_t part_attr_show(struct kobject * kobj, struct attribute * attr,
+			      char * page, size_t count, loff_t off)
+{
+	struct hd_struct * p = container_of(kobj,struct hd_struct,kobj);
+	struct part_attribute * part_attr = container_of(attr,struct part_attribute,attr);
+	ssize_t ret = 0;
+	if (part_attr->show)
+		part_attr->show(p,page,count,off);
+	return ret;
+}
+
+static struct sysfs_ops part_sysfs_ops = {
+	.show	=	part_attr_show,
+};
+
+static ssize_t part_dev_read(struct hd_struct * p,
+			     char *page, size_t count, loff_t off)
 {
-	struct gendisk *disk = dev->parent->driver_data;
-	struct hd_struct *p = dev->driver_data;
+	struct gendisk *disk = container_of(p->kobj.parent,struct gendisk,kobj);
 	int part = p - disk->part + 1;
 	dev_t base = MKDEV(disk->major, disk->first_minor); 
 	return off ? 0 : sprintf(page, "%04x\n",base + part);
 }
-static ssize_t part_start_read(struct device *dev,
-			char *page, size_t count, loff_t off)
+static ssize_t part_start_read(struct hd_struct * p,
+			       char *page, size_t count, loff_t off)
 {
-	struct hd_struct *p = dev->driver_data;
 	return off ? 0 : sprintf(page, "%llu\n",(unsigned long long)p->start_sect);
 }
-static ssize_t part_size_read(struct device *dev,
-			char *page, size_t count, loff_t off)
+static ssize_t part_size_read(struct hd_struct * p,
+			      char *page, size_t count, loff_t off)
 {
-	struct hd_struct *p = dev->driver_data;
 	return off ? 0 : sprintf(page, "%llu\n",(unsigned long long)p->nr_sects);
 }
-static ssize_t part_stat_read(struct device *dev,
-			char *page, size_t count, loff_t off)
+static ssize_t part_stat_read(struct hd_struct * p,
+			      char *page, size_t count, loff_t off)
 {
-	struct hd_struct *p = dev->driver_data;
 	return off ? 0 : sprintf(page, "%8u %8llu %8u %8llu\n",
 				p->reads, (u64)p->read_sectors,
 				p->writes, (u64)p->write_sectors);
 }
-static struct device_attribute part_attr_dev = {
+static struct part_attribute part_attr_dev = {
 	.attr = {.name = "dev", .mode = S_IRUGO },
 	.show	= part_dev_read
 };
-static struct device_attribute part_attr_start = {
+static struct part_attribute part_attr_start = {
 	.attr = {.name = "start", .mode = S_IRUGO },
 	.show	= part_start_read
 };
-static struct device_attribute part_attr_size = {
+static struct part_attribute part_attr_size = {
 	.attr = {.name = "size", .mode = S_IRUGO },
 	.show	= part_size_read
 };
-static struct device_attribute part_attr_stat = {
+static struct part_attribute part_attr_stat = {
 	.attr = {.name = "stat", .mode = S_IRUGO },
 	.show	= part_stat_read
 };
 
+static struct attribute * default_attrs[] = {
+	&part_attr_dev.attr,
+	&part_attr_start.attr,
+	&part_attr_size.attr,
+	&part_attr_stat.attr,
+	NULL,
+};
+
+extern struct subsystem block_subsys;
+
+static struct subsystem part_subsys = {
+	.parent		= &block_subsys,
+	.default_attrs	= default_attrs,
+	.sysfs_ops	= &part_sysfs_ops,
+};
+
+static int __init part_subsys_init(void)
+{
+	return subsystem_register(&part_subsys);
+}
+
+__initcall(part_subsys_init);
+
 void delete_partition(struct gendisk *disk, int part)
 {
 	struct hd_struct *p = disk->part + part - 1;
-	struct device *dev;
 	if (!p->nr_sects)
 		return;
 	p->start_sect = 0;
 	p->nr_sects = 0;
 	p->reads = p->writes = p->read_sectors = p->write_sectors = 0;
 	devfs_unregister(p->de);
-	dev = p->hd_driverfs_dev;
-	p->hd_driverfs_dev = NULL;
-	if (dev) {
-		device_remove_file(dev, &part_attr_stat);
-		device_remove_file(dev, &part_attr_size);
-		device_remove_file(dev, &part_attr_start);
-		device_remove_file(dev, &part_attr_dev);
-		device_unregister(dev);	
-	}
-}
-
-static void part_release(struct device *dev)
-{
-	kfree(dev);
+	kobject_unregister(&p->kobj);
 }
 
 void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len)
 {
 	struct hd_struct *p = disk->part + part - 1;
-	struct device *parent = &disk->disk_dev;
-	struct device *dev;
 
 	p->start_sect = start;
 	p->nr_sects = len;
 	devfs_register_partition(disk, part);
-	dev = kmalloc(sizeof(struct device), GFP_KERNEL);
-	if (!dev)
-		return;
-	memset(dev, 0, sizeof(struct device));
-	dev->parent = parent;
-	sprintf(dev->bus_id, "p%d", part);
-	dev->release = part_release;
-	dev->driver_data = p;
-	device_register(dev);
-	device_create_file(dev, &part_attr_dev);
-	device_create_file(dev, &part_attr_start);
-	device_create_file(dev, &part_attr_size);
-	device_create_file(dev, &part_attr_stat);
-	p->hd_driverfs_dev = dev;
+	kobject_init(&p->kobj);
+	snprintf(p->kobj.name,KOBJ_NAME_LEN,"%s%d",disk->disk_name,part);
+	p->kobj.parent = &disk->kobj;
+	p->kobj.subsys = &part_subsys;
+	kobject_register(&p->kobj);
 }
 
-static ssize_t disk_dev_read(struct device *dev,
-			char *page, size_t count, loff_t off)
-{
-	struct gendisk *disk = dev->driver_data;
-	dev_t base = MKDEV(disk->major, disk->first_minor); 
-	return off ? 0 : sprintf(page, "%04x\n",base);
-}
-static ssize_t disk_range_read(struct device *dev,
-			char *page, size_t count, loff_t off)
-{
-	struct gendisk *disk = dev->driver_data;
-	return off ? 0 : sprintf(page, "%d\n",disk->minors);
-}
-static ssize_t disk_size_read(struct device *dev,
-			char *page, size_t count, loff_t off)
-{
-	struct gendisk *disk = dev->driver_data;
-	return off ? 0 : sprintf(page, "%llu\n",(unsigned long long)get_capacity(disk));
-}
-static inline unsigned MSEC(unsigned x)
-{
-	return x * 1000 / HZ;
-}
-static ssize_t disk_stat_read(struct device *dev,
-			char *page, size_t count, loff_t off)
-{
-	struct gendisk *disk = dev->driver_data;
-	disk_round_stats(disk);
-	return off ? 0 : sprintf(page,
-		"%8u %8u %8llu %8u "
-		"%8u %8u %8llu %8u "
-		"%8u %8u %8u"
-		"\n",
-		disk->reads, disk->read_merges, (u64)disk->read_sectors,
-		MSEC(disk->read_ticks),
-		disk->writes, disk->write_merges, (u64)disk->write_sectors,
-		MSEC(disk->write_ticks),
-		disk->in_flight, MSEC(disk->io_ticks),
-		MSEC(disk->time_in_queue));
-}
-static struct device_attribute disk_attr_dev = {
-	.attr = {.name = "dev", .mode = S_IRUGO },
-	.show	= disk_dev_read
-};
-static struct device_attribute disk_attr_range = {
-	.attr = {.name = "range", .mode = S_IRUGO },
-	.show	= disk_range_read
-};
-static struct device_attribute disk_attr_size = {
-	.attr = {.name = "size", .mode = S_IRUGO },
-	.show	= disk_size_read
-};
-static struct device_attribute disk_attr_stat = {
-	.attr = {.name = "stat", .mode = S_IRUGO },
-	.show	= disk_stat_read
-};
-
-static void disk_driverfs_symlinks(struct gendisk *disk)
-{
-	struct device *target = disk->driverfs_dev;
-	struct device *dev = &disk->disk_dev;
-	struct device *p;
-	char *path;
-	char *s;
-	int length;
-	int depth;
-
-	if (!target)
-		return;
-
-	get_device(target);
-
-	length = get_devpath_length(target);
-	length += strlen("..");
-
-	if (length > PATH_MAX)
-		return;
-
-	if (!(path = kmalloc(length,GFP_KERNEL)))
-		return;
-	memset(path,0,length);
-
-	/* our relative position */
-	strcpy(path,"..");
-
-	fill_devpath(target, path, length);
-	driverfs_create_symlink(&dev->dir, "device", path);
-	kfree(path);
-
-	for (p = target, depth = 0; p; p = p->parent, depth++)
-		;
-	length = get_devpath_length(dev);
-	length += 3 * depth - 1;
-
-	if (length > PATH_MAX)
-		return;
-
-	if (!(path = kmalloc(length,GFP_KERNEL)))
-		return;
-	memset(path,0,length);
-	for (s = path; depth--; s += 3)
-		strcpy(s, "../");
-
-	fill_devpath(dev, path, length);
-	driverfs_create_symlink(&target->dir, "block", path);
-	kfree(path);
+static void disk_sysfs_symlinks(struct gendisk *disk)
+{
+	struct device *target = get_device(disk->driverfs_dev);
+	if (target) {
+		sysfs_create_link(&disk->kobj,&target->kobj,"device");
+		sysfs_create_link(&target->kobj,&disk->kobj,"block");
+	}
 }
 
 /* Not exported, helper to add_disk(). */
 void register_disk(struct gendisk *disk)
 {
-	struct device *dev = &disk->disk_dev;
 	struct parsed_partitions *state;
 	struct block_device *bdev;
 	char *s;
 	int j;
 
-	strcpy(dev->bus_id, disk->disk_name);
+	strncpy(disk->kobj.name,disk->disk_name,KOBJ_NAME_LEN);
 	/* ewww... some of these buggers have / in name... */
-	s = strchr(dev->bus_id, '/');
+	s = strchr(disk->kobj.name, '/');
 	if (s)
 		*s = '!';
-	device_add(dev);
-	device_create_file(dev, &disk_attr_dev);
-	device_create_file(dev, &disk_attr_range);
-	device_create_file(dev, &disk_attr_size);
-	device_create_file(dev, &disk_attr_stat);
-	disk_driverfs_symlinks(disk);
+	kobject_register(&disk->kobj);
+	disk_sysfs_symlinks(disk);
 
 	if (disk->flags & GENHD_FL_CD)
 		devfs_create_cdrom(disk);
@@ -620,16 +535,13 @@
 	disk->time_in_queue = 0;
 	disk->stamp = disk->stamp_idle = 0;
 	devfs_remove_partitions(disk);
-	device_remove_file(&disk->disk_dev, &disk_attr_dev);
-	device_remove_file(&disk->disk_dev, &disk_attr_range);
-	device_remove_file(&disk->disk_dev, &disk_attr_size);
-	device_remove_file(&disk->disk_dev, &disk_attr_stat);
-	driverfs_remove_file(&disk->disk_dev.dir, "device");
 	if (disk->driverfs_dev) {
-		driverfs_remove_file(&disk->driverfs_dev->dir, "block");
+		sysfs_remove_link(&disk->kobj, "device");
+		sysfs_remove_link(&disk->driverfs_dev->kobj, "block");
 		put_device(disk->driverfs_dev);
 	}
-	device_del(&disk->disk_dev);
+	kobject_get(&disk->kobj);	/* kobject model is fucked in head */
+	kobject_unregister(&disk->kobj);
 }
 
 struct dev_name {
@@ -680,3 +592,4 @@
 
 	return dname->name;
 }
+
diff -Nru a/fs/pipe.c b/fs/pipe.c
--- a/fs/pipe.c	Mon Nov  4 14:31:02 2002
+++ b/fs/pipe.c	Mon Nov  4 14:31:02 2002
@@ -11,7 +11,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/fs.h>
-#include <linux/fcblist.h>
 
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
@@ -34,13 +33,12 @@
 /* Drop the inode semaphore and wait for a pipe event, atomically */
 void pipe_wait(struct inode * inode)
 {
-	DECLARE_WAITQUEUE(wait, current);
-	current->state = TASK_INTERRUPTIBLE;
-	add_wait_queue(PIPE_WAIT(*inode), &wait);
+	DEFINE_WAIT(wait);
+
+	prepare_to_wait(PIPE_WAIT(*inode), &wait, TASK_INTERRUPTIBLE);
 	up(PIPE_SEM(*inode));
 	schedule();
-	remove_wait_queue(PIPE_WAIT(*inode), &wait);
-	current->state = TASK_RUNNING;
+	finish_wait(PIPE_WAIT(*inode), &wait);
 	down(PIPE_SEM(*inode));
 }
 
@@ -48,7 +46,7 @@
 pipe_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
 {
 	struct inode *inode = filp->f_dentry->d_inode;
-	int do_wakeup, pfull;
+	int do_wakeup;
 	ssize_t ret;
 
 	/* pread is not allowed on pipes. */
@@ -64,7 +62,6 @@
 	down(PIPE_SEM(*inode));
 	for (;;) {
 		int size = PIPE_LEN(*inode);
-		pfull = PIPE_FULL(*inode);
 		if (size) {
 			char *pipebuf = PIPE_BASE(*inode) + PIPE_START(*inode);
 			ssize_t chars = PIPE_MAX_RCHUNK(*inode);
@@ -110,18 +107,12 @@
 			if (!ret) ret = -ERESTARTSYS;
 			break;
 		}
-		/* Send notification message */
-		if (pfull && !PIPE_FULL(*inode) && PIPE_WRITEFILE(*inode))
-			file_send_notify(PIPE_WRITEFILE(*inode), ION_OUT, POLLOUT | POLLWRNORM | POLLWRBAND);
 		if (do_wakeup) {
 			wake_up_interruptible_sync(PIPE_WAIT(*inode));
  			kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT);
 		}
 		pipe_wait(inode);
 	}
-	/* Send notification message */
-	if (pfull && !PIPE_FULL(*inode) && PIPE_WRITEFILE(*inode))
-		file_send_notify(PIPE_WRITEFILE(*inode), ION_OUT, POLLOUT | POLLWRNORM | POLLWRBAND);
 	up(PIPE_SEM(*inode));
 	/* Signal writers asynchronously that there is more room.  */
 	if (do_wakeup) {
@@ -139,7 +130,7 @@
 	struct inode *inode = filp->f_dentry->d_inode;
 	ssize_t ret;
 	size_t min;
-	int do_wakeup, pempty;
+	int do_wakeup;
 
 	/* pwrite is not allowed on pipes. */
 	if (unlikely(ppos != &filp->f_pos))
@@ -157,7 +148,6 @@
 	down(PIPE_SEM(*inode));
 	for (;;) {
 		int free;
-		pempty = PIPE_EMPTY(*inode);
 		if (!PIPE_READERS(*inode)) {
 			send_sig(SIGPIPE, current, 0);
 			if (!ret) ret = -EPIPE;
@@ -203,9 +193,6 @@
 			if (!ret) ret = -ERESTARTSYS;
 			break;
 		}
-		/* Send notification message */
-		if (pempty && !PIPE_EMPTY(*inode) && PIPE_READFILE(*inode))
-			file_send_notify(PIPE_READFILE(*inode), ION_IN, POLLIN | POLLRDNORM);
 		if (do_wakeup) {
 			wake_up_interruptible_sync(PIPE_WAIT(*inode));
 			kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN);
@@ -215,9 +202,6 @@
 		pipe_wait(inode);
 		PIPE_WAITING_WRITERS(*inode)--;
 	}
-	/* Send notification message */
-	if (pempty && !PIPE_EMPTY(*inode) && PIPE_READFILE(*inode))
-		file_send_notify(PIPE_READFILE(*inode), ION_IN, POLLIN | POLLRDNORM);
 	up(PIPE_SEM(*inode));
 	if (do_wakeup) {
 		wake_up_interruptible(PIPE_WAIT(*inode));
@@ -281,22 +265,9 @@
 static int
 pipe_release(struct inode *inode, int decr, int decw)
 {
-	struct file *rdfile, *wrfile;
 	down(PIPE_SEM(*inode));
 	PIPE_READERS(*inode) -= decr;
 	PIPE_WRITERS(*inode) -= decw;
-	rdfile = PIPE_READFILE(*inode);
-	wrfile = PIPE_WRITEFILE(*inode);
- 	if (decr && !PIPE_READERS(*inode)) {
-		PIPE_READFILE(*inode) = NULL;
-		if (wrfile)
-			file_send_notify(wrfile, ION_HUP, POLLHUP);
-	}
-	if (decw && !PIPE_WRITERS(*inode)) {
-		PIPE_WRITEFILE(*inode) = NULL;
-		if (rdfile)
-			file_send_notify(rdfile, ION_HUP, POLLHUP);
-	}
 	if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode)) {
 		struct pipe_inode_info *info = inode->i_pipe;
 		inode->i_pipe = NULL;
@@ -516,7 +487,6 @@
 	PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
 	PIPE_WAITING_WRITERS(*inode) = 0;
 	PIPE_RCOUNTER(*inode) = PIPE_WCOUNTER(*inode) = 1;
-	PIPE_READFILE(*inode) = PIPE_WRITEFILE(*inode) = NULL;
 	*PIPE_FASYNC_READERS(*inode) = *PIPE_FASYNC_WRITERS(*inode) = NULL;
 
 	return inode;
@@ -624,9 +594,6 @@
 	f2->f_op = &write_pipe_fops;
 	f2->f_mode = 2;
 	f2->f_version = 0;
-
-	PIPE_READFILE(*inode) = f1;
-	PIPE_WRITEFILE(*inode) = f2;
 
 	fd_install(i, f1);
 	fd_install(j, f2);
diff -Nru a/fs/posix_acl.c b/fs/posix_acl.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/posix_acl.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,423 @@
+/*
+ * linux/fs/posix_acl.c
+ *
+ *  Copyright (C) 2002 by Andreas Gruenbacher <a.gruenbacher@computer.org>
+ *
+ *  Fixes from William Schumacher incorporated on 15 March 2001.
+ *     (Reported by Charles Bertsch, <CBertsch@microtest.com>).
+ */
+
+/*
+ *  This file contains generic functions for manipulating
+ *  POSIX 1003.1e draft standard 17 ACLs.
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <asm/atomic.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/posix_acl.h>
+#include <linux/module.h>
+
+#include <linux/errno.h>
+
+EXPORT_SYMBOL(posix_acl_alloc);
+EXPORT_SYMBOL(posix_acl_clone);
+EXPORT_SYMBOL(posix_acl_valid);
+EXPORT_SYMBOL(posix_acl_equiv_mode);
+EXPORT_SYMBOL(posix_acl_from_mode);
+EXPORT_SYMBOL(posix_acl_create_masq);
+EXPORT_SYMBOL(posix_acl_chmod_masq);
+EXPORT_SYMBOL(posix_acl_masq_nfs_mode);
+EXPORT_SYMBOL(posix_acl_permission);
+
+/*
+ * Allocate a new ACL with the specified number of entries.
+ */
+struct posix_acl *
+posix_acl_alloc(int count, int flags)
+{
+	const size_t size = sizeof(struct posix_acl) +
+	                    count * sizeof(struct posix_acl_entry);
+	struct posix_acl *acl = kmalloc(size, flags);
+	if (acl) {
+		atomic_set(&acl->a_refcount, 1);
+		acl->a_count = count;
+	}
+	return acl;
+}
+
+/*
+ * Clone an ACL.
+ */
+struct posix_acl *
+posix_acl_clone(const struct posix_acl *acl, int flags)
+{
+	struct posix_acl *clone = NULL;
+
+	if (acl) {
+		int size = sizeof(struct posix_acl) + acl->a_count *
+		           sizeof(struct posix_acl_entry);
+		clone = kmalloc(size, flags);
+		if (clone) {
+			memcpy(clone, acl, size);
+			atomic_set(&clone->a_refcount, 1);
+		}
+	}
+	return clone;
+}
+
+/*
+ * Check if an acl is valid. Returns 0 if it is, or -E... otherwise.
+ */
+int
+posix_acl_valid(const struct posix_acl *acl)
+{
+	const struct posix_acl_entry *pa, *pe;
+	int state = ACL_USER_OBJ;
+	unsigned int id = 0;  /* keep gcc happy */
+	int needs_mask = 0;
+
+	FOREACH_ACL_ENTRY(pa, acl, pe) {
+		if (pa->e_perm & ~(ACL_READ|ACL_WRITE|ACL_EXECUTE))
+			return -EINVAL;
+		switch (pa->e_tag) {
+			case ACL_USER_OBJ:
+				if (state == ACL_USER_OBJ) {
+					id = 0;
+					state = ACL_USER;
+					break;
+				}
+				return -EINVAL;
+
+			case ACL_USER:
+				if (state != ACL_USER)
+					return -EINVAL;
+				if (pa->e_id == ACL_UNDEFINED_ID ||
+				    pa->e_id < id)
+					return -EINVAL;
+				id = pa->e_id + 1;
+				needs_mask = 1;
+				break;
+
+			case ACL_GROUP_OBJ:
+				if (state == ACL_USER) {
+					id = 0;
+					state = ACL_GROUP;
+					break;
+				}
+				return -EINVAL;
+
+			case ACL_GROUP:
+				if (state != ACL_GROUP)
+					return -EINVAL;
+				if (pa->e_id == ACL_UNDEFINED_ID ||
+				    pa->e_id < id)
+					return -EINVAL;
+				id = pa->e_id + 1;
+				needs_mask = 1;
+				break;
+
+			case ACL_MASK:
+				if (state != ACL_GROUP)
+					return -EINVAL;
+				state = ACL_OTHER;
+				break;
+
+			case ACL_OTHER:
+				if (state == ACL_OTHER ||
+				    (state == ACL_GROUP && !needs_mask)) {
+					state = 0;
+					break;
+				}
+				return -EINVAL;
+
+			default:
+				return -EINVAL;
+		}
+	}
+	if (state == 0)
+		return 0;
+	return -EINVAL;
+}
+
+/*
+ * Returns 0 if the acl can be exactly represented in the traditional
+ * file mode permission bits, or else 1. Returns -E... on error.
+ */
+int
+posix_acl_equiv_mode(const struct posix_acl *acl, mode_t *mode_p)
+{
+	const struct posix_acl_entry *pa, *pe;
+	mode_t mode = 0;
+	int not_equiv = 0;
+
+	FOREACH_ACL_ENTRY(pa, acl, pe) {
+		switch (pa->e_tag) {
+			case ACL_USER_OBJ:
+				mode |= (pa->e_perm & S_IRWXO) << 6;
+				break;
+			case ACL_GROUP_OBJ:
+				mode |= (pa->e_perm & S_IRWXO) << 3;
+				break;
+			case ACL_OTHER:
+				mode |= pa->e_perm & S_IRWXO;
+				break;
+			case ACL_MASK:
+				mode = (mode & ~S_IRWXG) |
+				       ((pa->e_perm & S_IRWXO) << 3);
+				not_equiv = 1;
+				break;
+			case ACL_USER:
+			case ACL_GROUP:
+				not_equiv = 1;
+				break;
+			default:
+				return -EINVAL;
+		}
+	}
+        if (mode_p)
+                *mode_p = (*mode_p & ~S_IRWXUGO) | mode;
+        return not_equiv;
+}
+
+/*
+ * Create an ACL representing the file mode permission bits of an inode.
+ */
+struct posix_acl *
+posix_acl_from_mode(mode_t mode, int flags)
+{
+	struct posix_acl *acl = posix_acl_alloc(3, flags);
+	if (!acl)
+		return ERR_PTR(-ENOMEM);
+
+	acl->a_entries[0].e_tag  = ACL_USER_OBJ;
+	acl->a_entries[0].e_id   = ACL_UNDEFINED_ID;
+	acl->a_entries[0].e_perm = (mode & S_IRWXU) >> 6;
+
+	acl->a_entries[1].e_tag  = ACL_GROUP_OBJ;
+	acl->a_entries[1].e_id   = ACL_UNDEFINED_ID;
+	acl->a_entries[1].e_perm = (mode & S_IRWXG) >> 3;
+
+	acl->a_entries[2].e_tag  = ACL_OTHER;
+	acl->a_entries[2].e_id   = ACL_UNDEFINED_ID;
+	acl->a_entries[2].e_perm = (mode & S_IRWXO);
+	return acl;
+}
+
+/*
+ * Return 0 if current is granted want access to the inode
+ * by the acl. Returns -E... otherwise.
+ */
+int
+posix_acl_permission(struct inode *inode, const struct posix_acl *acl, int want)
+{
+	const struct posix_acl_entry *pa, *pe, *mask_obj;
+	int found = 0;
+
+	FOREACH_ACL_ENTRY(pa, acl, pe) {
+                switch(pa->e_tag) {
+                        case ACL_USER_OBJ:
+				/* (May have been checked already) */
+                                if (inode->i_uid == current->fsuid)
+                                        goto check_perm;
+                                break;
+                        case ACL_USER:
+                                if (pa->e_id == current->fsuid)
+                                        goto mask;
+				break;
+                        case ACL_GROUP_OBJ:
+                                if (in_group_p(inode->i_gid)) {
+					found = 1;
+					if ((pa->e_perm & want) == want)
+						goto mask;
+                                }
+				break;
+                        case ACL_GROUP:
+                                if (in_group_p(pa->e_id)) {
+					found = 1;
+					if ((pa->e_perm & want) == want)
+						goto mask;
+                                }
+                                break;
+                        case ACL_MASK:
+                                break;
+                        case ACL_OTHER:
+				if (found)
+					return -EACCES;
+				else
+					goto check_perm;
+			default:
+				return -EIO;
+                }
+        }
+	return -EIO;
+
+mask:
+	for (mask_obj = pa+1; mask_obj != pe; mask_obj++) {
+		if (mask_obj->e_tag == ACL_MASK) {
+			if ((pa->e_perm & mask_obj->e_perm & want) == want)
+				return 0;
+			return -EACCES;
+		}
+	}
+
+check_perm:
+	if ((pa->e_perm & want) == want)
+		return 0;
+	return -EACCES;
+}
+
+/*
+ * Modify acl when creating a new inode. The caller must ensure the acl is
+ * only referenced once.
+ *
+ * mode_p initially must contain the mode parameter to the open() / creat()
+ * system calls. All permissions that are not granted by the acl are removed.
+ * The permissions in the acl are changed to reflect the mode_p parameter.
+ */
+int
+posix_acl_create_masq(struct posix_acl *acl, mode_t *mode_p)
+{
+	struct posix_acl_entry *pa, *pe;
+	struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL;
+	mode_t mode = *mode_p;
+	int not_equiv = 0;
+
+	/* assert(atomic_read(acl->a_refcount) == 1); */
+
+	FOREACH_ACL_ENTRY(pa, acl, pe) {
+                switch(pa->e_tag) {
+                        case ACL_USER_OBJ:
+				pa->e_perm &= (mode >> 6) | ~S_IRWXO;
+				mode &= (pa->e_perm << 6) | ~S_IRWXU;
+				break;
+
+			case ACL_USER:
+			case ACL_GROUP:
+				not_equiv = 1;
+				break;
+
+                        case ACL_GROUP_OBJ:
+				group_obj = pa;
+                                break;
+
+                        case ACL_OTHER:
+				pa->e_perm &= mode | ~S_IRWXO;
+				mode &= pa->e_perm | ~S_IRWXO;
+                                break;
+
+                        case ACL_MASK:
+				mask_obj = pa;
+				not_equiv = 1;
+                                break;
+
+			default:
+				return -EIO;
+                }
+        }
+
+	if (mask_obj) {
+		mask_obj->e_perm &= (mode >> 3) | ~S_IRWXO;
+		mode &= (mask_obj->e_perm << 3) | ~S_IRWXG;
+	} else {
+		if (!group_obj)
+			return -EIO;
+		group_obj->e_perm &= (mode >> 3) | ~S_IRWXO;
+		mode &= (group_obj->e_perm << 3) | ~S_IRWXG;
+	}
+
+	*mode_p = (*mode_p & ~S_IRWXUGO) | mode;
+        return not_equiv;
+}
+
+/*
+ * Modify the ACL for the chmod syscall.
+ */
+int
+posix_acl_chmod_masq(struct posix_acl *acl, mode_t mode)
+{
+	struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL;
+	struct posix_acl_entry *pa, *pe;
+
+	/* assert(atomic_read(acl->a_refcount) == 1); */
+
+	FOREACH_ACL_ENTRY(pa, acl, pe) {
+		switch(pa->e_tag) {
+			case ACL_USER_OBJ:
+				pa->e_perm = (mode & S_IRWXU) >> 6;
+				break;
+
+			case ACL_USER:
+			case ACL_GROUP:
+				break;
+
+			case ACL_GROUP_OBJ:
+				group_obj = pa;
+				break;
+
+			case ACL_MASK:
+				mask_obj = pa;
+				break;
+
+			case ACL_OTHER:
+				pa->e_perm = (mode & S_IRWXO);
+				break;
+
+			default:
+				return -EIO;
+		}
+	}
+
+	if (mask_obj) {
+		mask_obj->e_perm = (mode & S_IRWXG) >> 3;
+	} else {
+		if (!group_obj)
+			return -EIO;
+		group_obj->e_perm = (mode & S_IRWXG) >> 3;
+	}
+
+	return 0;
+}
+
+/*
+ * Adjust the mode parameter so that NFSv2 grants nobody permissions
+ * that may not be granted by the ACL. This is necessary because NFSv2
+ * may compute access permissions on the client side, and may serve cached
+ * data whenever it assumes access would be granted.  Since ACLs may also
+ * be used to deny access to specific users, the minimal permissions
+ * for secure operation over NFSv2 are very restrictive. Permissions
+ * granted to users via Access Control Lists will not be effective over
+ * NFSv2.
+ *
+ * Privilege escalation can only happen for read operations, as writes are
+ * always carried out on the NFS server, where the proper access checks are
+ * implemented.
+ */
+int
+posix_acl_masq_nfs_mode(struct posix_acl *acl, mode_t *mode_p)
+{
+	struct posix_acl_entry *pa, *pe; int min_perm = S_IRWXO;
+
+	FOREACH_ACL_ENTRY(pa, acl, pe) {
+                switch(pa->e_tag) {
+			case ACL_USER_OBJ:
+				break;
+
+			case ACL_USER:
+			case ACL_GROUP_OBJ:
+			case ACL_GROUP:
+			case ACL_MASK:
+			case ACL_OTHER:
+				min_perm &= pa->e_perm;
+				break;
+
+			default:
+				return -EIO;
+		}
+	}
+	*mode_p = (*mode_p & ~(S_IRWXG|S_IRWXO)) | (min_perm << 3) | min_perm;
+
+	return 0;
+}
diff -Nru a/fs/proc/array.c b/fs/proc/array.c
--- a/fs/proc/array.c	Mon Nov  4 14:31:02 2002
+++ b/fs/proc/array.c	Mon Nov  4 14:31:02 2002
@@ -64,6 +64,7 @@
 #include <linux/proc_fs.h>
 #include <linux/ioport.h>
 #include <linux/mm.h>
+#include <linux/hugetlb.h>
 #include <linux/pagemap.h>
 #include <linux/swap.h>
 #include <linux/slab.h>
diff -Nru a/fs/proc/base.c b/fs/proc/base.c
--- a/fs/proc/base.c	Mon Nov  4 14:31:02 2002
+++ b/fs/proc/base.c	Mon Nov  4 14:31:02 2002
@@ -28,6 +28,7 @@
 #include <linux/namespace.h>
 #include <linux/mm.h>
 #include <linux/smp_lock.h>
+#include <linux/kallsyms.h>
 
 /*
  * For hysterical raisins we keep the same inumbers as in the old procfs.
@@ -54,6 +55,7 @@
 	PROC_PID_MAPS,
 	PROC_PID_CPU,
 	PROC_PID_MOUNTS,
+	PROC_PID_WCHAN,
 	PROC_PID_FD_DIR = 0x8000,	/* 0x8000-0xffff */
 };
 
@@ -81,6 +83,9 @@
   E(PROC_PID_ROOT,	"root",		S_IFLNK|S_IRWXUGO),
   E(PROC_PID_EXE,	"exe",		S_IFLNK|S_IRWXUGO),
   E(PROC_PID_MOUNTS,	"mounts",	S_IFREG|S_IRUGO),
+#ifdef CONFIG_KALLSYMS
+  E(PROC_PID_WCHAN,	"wchan",	S_IFREG|S_IRUGO),
+#endif
   {0,0,NULL,0}
 };
 #undef E
@@ -245,6 +250,28 @@
 	return res;
 }
 
+#ifdef CONFIG_KALLSYMS
+/*
+ * Provides a wchan file via kallsyms in a proper one-value-per-file format.
+ * Returns the resolved symbol.  If that fails, simply return the address.
+ */
+static int proc_pid_wchan(struct task_struct *task, char *buffer)
+{
+	const char *sym_name, *ignore;
+	unsigned long wchan, dummy;
+
+	wchan = get_wchan(task);
+
+	if (!kallsyms_address_to_symbol(wchan, &ignore, &dummy, &dummy,
+			&ignore, &dummy, &dummy, &sym_name,
+			&dummy, &dummy)) {
+		return sprintf(buffer, "%lu", wchan);
+	}
+
+	return sprintf(buffer, "%s", sym_name);
+}
+#endif
+
 /************************************************************************/
 /*                       Here the fs part begins                        */
 /************************************************************************/
@@ -1016,6 +1043,12 @@
 		case PROC_PID_MOUNTS:
 			inode->i_fop = &proc_mounts_operations;
 			break;
+#ifdef CONFIG_KALLSYMS
+		case PROC_PID_WCHAN:
+			inode->i_fop = &proc_info_file_operations;
+			ei->op.proc_read = proc_pid_wchan;
+			break;
+#endif
 		default:
 			printk("procfs: impossible type (%d)",p->type);
 			iput(inode);
diff -Nru a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
--- a/fs/proc/proc_misc.c	Mon Nov  4 14:31:01 2002
+++ b/fs/proc/proc_misc.c	Mon Nov  4 14:31:01 2002
@@ -62,7 +62,6 @@
 extern int get_exec_domain_list(char *);
 extern int get_dma_list(char *);
 extern int get_locks_status (char *, char **, off_t, int);
-extern int get_swaparea_info (char *);
 #ifdef CONFIG_SGI_DS1286
 extern int get_ds1286_status(char *);
 #endif
@@ -296,18 +295,6 @@
 	.release	= seq_release,
 };
 
-extern struct seq_operations swaps_op;
-static int swaps_open(struct inode *inode, struct file *file)
-{
-	return seq_open(file, &swaps_op);
-}
-static struct file_operations proc_swaps_operations = {
-	.open		= swaps_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= seq_release,
-};
-
 #ifdef CONFIG_MODULES
 extern struct seq_operations modules_op;
 static int modules_open(struct inode *inode, struct file *file)
@@ -360,14 +347,14 @@
 		int j;
 
 		if(!cpu_online(i)) continue;
-		user += kstat.per_cpu_user[i];
-		nice += kstat.per_cpu_nice[i];
-		system += kstat.per_cpu_system[i];
-		idle += kstat.per_cpu_idle[i];
-		iowait += kstat.per_cpu_iowait[i];
+		user += kstat_cpu(i).cpustat.user;
+		nice += kstat_cpu(i).cpustat.nice;
+		system += kstat_cpu(i).cpustat.system;
+		idle += kstat_cpu(i).cpustat.idle;
+		iowait += kstat_cpu(i).cpustat.iowait;
 #if !defined(CONFIG_ARCH_S390)
 		for (j = 0 ; j < NR_IRQS ; j++)
-			sum += kstat.irqs[i][j];
+			sum += kstat_cpu(i).irqs[j];
 #endif
 	}
 
@@ -381,11 +368,11 @@
 		if (!cpu_online(i)) continue;
 		len += sprintf(page + len, "cpu%d %u %u %u %u %u\n",
 			i,
-			jiffies_to_clock_t(kstat.per_cpu_user[i]),
-			jiffies_to_clock_t(kstat.per_cpu_nice[i]),
-			jiffies_to_clock_t(kstat.per_cpu_system[i]),
-			jiffies_to_clock_t(kstat.per_cpu_idle[i]),
-			jiffies_to_clock_t(kstat.per_cpu_iowait[i]));
+			jiffies_to_clock_t(kstat_cpu(i).cpustat.user),
+			jiffies_to_clock_t(kstat_cpu(i).cpustat.nice),
+			jiffies_to_clock_t(kstat_cpu(i).cpustat.system),
+			jiffies_to_clock_t(kstat_cpu(i).cpustat.idle),
+			jiffies_to_clock_t(kstat_cpu(i).cpustat.idle));
 	}
 	len += sprintf(page + len, "intr %u", sum);
 
@@ -398,18 +385,18 @@
 
 	for (major = 0; major < DK_MAX_MAJOR; major++) {
 		for (disk = 0; disk < DK_MAX_DISK; disk++) {
-			int active = kstat.dk_drive[major][disk] +
-				kstat.dk_drive_rblk[major][disk] +
-				kstat.dk_drive_wblk[major][disk];
+			int active = dkstat.drive[major][disk] +
+				dkstat.drive_rblk[major][disk] +
+				dkstat.drive_wblk[major][disk];
 			if (active)
 				len += sprintf(page + len,
 					"(%u,%u):(%u,%u,%u,%u,%u) ",
 					major, disk,
-					kstat.dk_drive[major][disk],
-					kstat.dk_drive_rio[major][disk],
-					kstat.dk_drive_rblk[major][disk],
-					kstat.dk_drive_wio[major][disk],
-					kstat.dk_drive_wblk[major][disk]
+					dkstat.drive[major][disk],
+					dkstat.drive_rio[major][disk],
+					dkstat.drive_rblk[major][disk],
+					dkstat.drive_wio[major][disk],
+					dkstat.drive_wblk[major][disk]
 			);
 		}
 	}
@@ -641,7 +628,6 @@
 		entry->proc_fops = &proc_kmsg_operations;
 	create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
 	create_seq_entry("partitions", 0, &proc_partitions_operations);
-	create_seq_entry("swaps", 0, &proc_swaps_operations);
 #if !defined(CONFIG_ARCH_S390)
 	create_seq_entry("interrupts", 0, &proc_interrupts_operations);
 #endif
diff -Nru a/fs/select.c b/fs/select.c
--- a/fs/select.c	Mon Nov  4 14:31:00 2002
+++ b/fs/select.c	Mon Nov  4 14:31:00 2002
@@ -77,6 +77,14 @@
 {
 	struct poll_table_page *table = p->table;
 
+	if (!p->queue)
+		return;
+
+	if (p->qproc) {
+		p->qproc(p->priv, wait_address);
+		return;
+	}
+
 	if (!table || POLL_TABLE_FULL(table)) {
 		struct poll_table_page *new_table;
 
diff -Nru a/fs/xattr_acl.c b/fs/xattr_acl.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/xattr_acl.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,99 @@
+/*
+ * linux/fs/xattr_acl.c
+ *
+ * Almost all from linux/fs/ext2/acl.c:
+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/posix_acl_xattr.h>
+
+
+/*
+ * Convert from extended attribute to in-memory representation.
+ */
+struct posix_acl *
+posix_acl_from_xattr(const void *value, size_t size)
+{
+	posix_acl_xattr_header *header = (posix_acl_xattr_header *)value;
+	posix_acl_xattr_entry *entry = (posix_acl_xattr_entry *)(header+1), *end;
+	int count;
+	struct posix_acl *acl;
+	struct posix_acl_entry *acl_e;
+
+	if (!value)
+		return NULL;
+	if (size < sizeof(posix_acl_xattr_header))
+		 return ERR_PTR(-EINVAL);
+	if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
+		return ERR_PTR(-EINVAL);
+
+	count = posix_acl_xattr_count(size);
+	if (count < 0)
+		return ERR_PTR(-EINVAL);
+	if (count == 0)
+		return NULL;
+	
+	acl = posix_acl_alloc(count, GFP_KERNEL);
+	if (!acl)
+		return ERR_PTR(-ENOMEM);
+	acl_e = acl->a_entries;
+	
+	for (end = entry + count; entry != end; acl_e++, entry++) {
+		acl_e->e_tag  = le16_to_cpu(entry->e_tag);
+		acl_e->e_perm = le16_to_cpu(entry->e_perm);
+
+		switch(acl_e->e_tag) {
+			case ACL_USER_OBJ:
+			case ACL_GROUP_OBJ:
+			case ACL_MASK:
+			case ACL_OTHER:
+				acl_e->e_id = ACL_UNDEFINED_ID;
+				break;
+
+			case ACL_USER:
+			case ACL_GROUP:
+				acl_e->e_id = le32_to_cpu(entry->e_id);
+				break;
+
+			default:
+				goto fail;
+		}
+	}
+	return acl;
+
+fail:
+	posix_acl_release(acl);
+	return ERR_PTR(-EINVAL);
+}
+EXPORT_SYMBOL (posix_acl_from_xattr);
+
+/*
+ * Convert from in-memory to extended attribute representation.
+ */
+int
+posix_acl_to_xattr(const struct posix_acl *acl, void *buffer, size_t size)
+{
+	posix_acl_xattr_header *ext_acl = (posix_acl_xattr_header *)buffer;
+	posix_acl_xattr_entry *ext_entry = ext_acl->a_entries;
+	int real_size, n;
+
+	real_size = posix_acl_xattr_size(acl->a_count);
+	if (!buffer)
+		return real_size;
+	if (real_size > size)
+		return -ERANGE;
+	
+	ext_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
+
+	for (n=0; n < acl->a_count; n++, ext_entry++) {
+		ext_entry->e_tag  = cpu_to_le16(acl->a_entries[n].e_tag);
+		ext_entry->e_perm = cpu_to_le16(acl->a_entries[n].e_perm);
+		ext_entry->e_id   = cpu_to_le32(acl->a_entries[n].e_id);
+	}
+	return real_size;
+}
+EXPORT_SYMBOL (posix_acl_to_xattr);
diff -Nru a/include/asm-alpha/dma.h b/include/asm-alpha/dma.h
--- a/include/asm-alpha/dma.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-alpha/dma.h	Mon Nov  4 14:31:02 2002
@@ -85,43 +85,46 @@
 /* The maximum address for ISA DMA transfer on Alpha XL, due to an
    hardware SIO limitation, is 64MB.
 */
-#define ALPHA_XL_MAX_DMA_ADDRESS	(IDENT_ADDR+0x04000000UL)
+#define ALPHA_XL_MAX_ISA_DMA_ADDRESS		0x04000000UL
 
-/* The maximum address for ISA DMA transfer on RUFFIAN and NAUTILUS,
+/* The maximum address for ISA DMA transfer on RUFFIAN,
    due to an hardware SIO limitation, is 16MB.
 */
-#define ALPHA_RUFFIAN_MAX_DMA_ADDRESS	(IDENT_ADDR+0x01000000UL)
-#define ALPHA_NAUTILUS_MAX_DMA_ADDRESS	(IDENT_ADDR+0x01000000UL)
+#define ALPHA_RUFFIAN_MAX_ISA_DMA_ADDRESS	0x01000000UL
 
 /* The maximum address for ISA DMA transfer on SABLE, and some ALCORs,
    due to an hardware SIO chip limitation, is 2GB.
 */
-#define ALPHA_SABLE_MAX_DMA_ADDRESS	(IDENT_ADDR+0x80000000UL)
-#define ALPHA_ALCOR_MAX_DMA_ADDRESS	(IDENT_ADDR+0x80000000UL)
+#define ALPHA_SABLE_MAX_ISA_DMA_ADDRESS		0x80000000UL
+#define ALPHA_ALCOR_MAX_ISA_DMA_ADDRESS		0x80000000UL
 
 /*
   Maximum address for all the others is the complete 32-bit bus
   address space.
 */
-#define ALPHA_MAX_DMA_ADDRESS		(IDENT_ADDR+0x100000000UL)
+#define ALPHA_MAX_ISA_DMA_ADDRESS		0x100000000UL
 
 #ifdef CONFIG_ALPHA_GENERIC
-# define MAX_DMA_ADDRESS		(alpha_mv.max_dma_address)
+# define MAX_ISA_DMA_ADDRESS		(alpha_mv.max_isa_dma_address)
 #else
 # if defined(CONFIG_ALPHA_XL)
-#  define MAX_DMA_ADDRESS		ALPHA_XL_MAX_DMA_ADDRESS
+#  define MAX_ISA_DMA_ADDRESS		ALPHA_XL_MAX_ISA_DMA_ADDRESS
 # elif defined(CONFIG_ALPHA_RUFFIAN)
-#  define MAX_DMA_ADDRESS		ALPHA_RUFFIAN_MAX_DMA_ADDRESS
-# elif defined(CONFIG_ALPHA_NAUTILUS)
-#  define MAX_DMA_ADDRESS		ALPHA_NAUTILUS_MAX_DMA_ADDRESS
+#  define MAX_ISA_DMA_ADDRESS		ALPHA_RUFFIAN_MAX_ISA_DMA_ADDRESS
 # elif defined(CONFIG_ALPHA_SABLE)
-#  define MAX_DMA_ADDRESS		ALPHA_SABLE_MAX_DMA_ADDRESS
+#  define MAX_ISA_DMA_ADDRESS		ALPHA_SABLE_MAX_DMA_ISA_ADDRESS
 # elif defined(CONFIG_ALPHA_ALCOR)
-#  define MAX_DMA_ADDRESS		ALPHA_ALCOR_MAX_DMA_ADDRESS
+#  define MAX_ISA_DMA_ADDRESS		ALPHA_ALCOR_MAX_DMA_ISA_ADDRESS
 # else
-#  define MAX_DMA_ADDRESS		ALPHA_MAX_DMA_ADDRESS
+#  define MAX_ISA_DMA_ADDRESS		ALPHA_MAX_ISA_DMA_ADDRESS
 # endif
 #endif
+
+/* If we have the iommu, we don't have any address limitations on DMA.
+   Otherwise (Nautilus, RX164), we have to have 0-16 Mb DMA zone
+   like i386. */
+#define MAX_DMA_ADDRESS		(alpha_mv.mv_pci_tbi ?	\
+				 ~0UL : IDENT_ADDR + 0x01000000)
 
 /* 8237 DMA controllers */
 #define IO_DMA1_BASE	0x00	/* 8 bit slave DMA, channels 0..3 */
diff -Nru a/include/asm-alpha/floppy.h b/include/asm-alpha/floppy.h
--- a/include/asm-alpha/floppy.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-alpha/floppy.h	Mon Nov  4 14:31:02 2002
@@ -51,12 +51,12 @@
 	if (bus_addr 
 	    && (addr != prev_addr || size != prev_size || dir != prev_dir)) {
 		/* different from last time -- unmap prev */
-		pci_unmap_single(NULL, bus_addr, prev_size, prev_dir);
+		pci_unmap_single(isa_bridge, bus_addr, prev_size, prev_dir);
 		bus_addr = 0;
 	}
 
 	if (!bus_addr)	/* need to map it */
-		bus_addr = pci_map_single(NULL, addr, size, dir);
+		bus_addr = pci_map_single(isa_bridge, addr, size, dir);
 
 	/* remember this one as prev */
 	prev_addr = addr;
diff -Nru a/include/asm-alpha/hwrpb.h b/include/asm-alpha/hwrpb.h
--- a/include/asm-alpha/hwrpb.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-alpha/hwrpb.h	Mon Nov  4 14:31:01 2002
@@ -109,6 +109,9 @@
 	unsigned long ipc_buffer[21];
 	unsigned long palcode_avail[16];
 	unsigned long compatibility;
+	unsigned long console_data_log_pa;
+	unsigned long console_data_log_length;
+	unsigned long bcache_info;
 };
 
 struct procdesc_struct {
diff -Nru a/include/asm-alpha/machvec.h b/include/asm-alpha/machvec.h
--- a/include/asm-alpha/machvec.h	Mon Nov  4 14:31:00 2002
+++ b/include/asm-alpha/machvec.h	Mon Nov  4 14:31:00 2002
@@ -34,7 +34,7 @@
 	int nr_irqs;
 	int rtc_port;
 	int max_asn;
-	unsigned long max_dma_address;
+	unsigned long max_isa_dma_address;
 	unsigned long irq_probe_mask;
 	unsigned long iack_sc;
 	unsigned long min_io_address;
diff -Nru a/include/asm-alpha/mman.h b/include/asm-alpha/mman.h
--- a/include/asm-alpha/mman.h	Mon Nov  4 14:31:00 2002
+++ b/include/asm-alpha/mman.h	Mon Nov  4 14:31:00 2002
@@ -19,11 +19,13 @@
 #define _MAP_UNALIGNED	0x0800
 
 /* These are linux-specific */
-#define MAP_GROWSDOWN	0x1000		/* stack-like segment */
-#define MAP_DENYWRITE	0x2000		/* ETXTBSY */
-#define MAP_EXECUTABLE	0x4000		/* mark it as an executable */
-#define MAP_LOCKED	0x8000		/* lock the mapping */
+#define MAP_GROWSDOWN	0x01000		/* stack-like segment */
+#define MAP_DENYWRITE	0x02000		/* ETXTBSY */
+#define MAP_EXECUTABLE	0x04000		/* mark it as an executable */
+#define MAP_LOCKED	0x08000		/* lock the mapping */
 #define MAP_NORESERVE	0x10000		/* don't check for reservations */
+#define MAP_POPULATE	0x20000		/* populate (prefault) pagetables */
+#define MAP_NONBLOCK	0x40000		/* do not block on IO */
 
 #define MS_ASYNC	1		/* sync memory asynchronously */
 #define MS_SYNC		2		/* synchronous memory sync */
diff -Nru a/include/asm-alpha/poll.h b/include/asm-alpha/poll.h
--- a/include/asm-alpha/poll.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-alpha/poll.h	Mon Nov  4 14:31:01 2002
@@ -1,17 +1,18 @@
 #ifndef __ALPHA_POLL_H
 #define __ALPHA_POLL_H
 
-#define POLLIN		1
-#define POLLPRI		2
-#define POLLOUT		4
-#define POLLERR		8
-#define POLLHUP		16
-#define POLLNVAL	32
-#define POLLRDNORM	64
-#define POLLRDBAND	128
-#define POLLWRNORM	256
-#define POLLWRBAND	512
-#define POLLMSG		1024
+#define POLLIN		(1 << 0)
+#define POLLPRI		(1 << 1)
+#define POLLOUT		(1 << 2)
+#define POLLERR		(1 << 3)
+#define POLLHUP		(1 << 4)
+#define POLLNVAL	(1 << 5)
+#define POLLRDNORM	(1 << 6)
+#define POLLRDBAND	(1 << 7)
+#define POLLWRNORM	(1 << 8)
+#define POLLWRBAND	(1 << 9)
+#define POLLMSG		(1 << 10)
+#define POLLREMOVE	(1 << 11)
 
 struct pollfd {
 	int fd;
diff -Nru a/include/asm-alpha/processor.h b/include/asm-alpha/processor.h
--- a/include/asm-alpha/processor.h	Mon Nov  4 14:31:03 2002
+++ b/include/asm-alpha/processor.h	Mon Nov  4 14:31:03 2002
@@ -55,9 +55,6 @@
 /* Create a kernel thread without removing it from tasklists.  */
 extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
 
-#define copy_segments(tsk, mm)		do { } while (0)
-#define release_segments(mm)		do { } while (0)
-
 unsigned long get_wchan(struct task_struct *p);
 
 /* See arch/alpha/kernel/ptrace.c for details.  */
diff -Nru a/include/asm-alpha/siginfo.h b/include/asm-alpha/siginfo.h
--- a/include/asm-alpha/siginfo.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-alpha/siginfo.h	Mon Nov  4 14:31:02 2002
@@ -1,26 +1,11 @@
 #ifndef _ALPHA_SIGINFO_H
 #define _ALPHA_SIGINFO_H
 
-#define SI_PAD_SIZE	((SI_MAX_SIZE/sizeof(int)) - 4)
+#define __ARCH_SI_PREAMBLE_SIZE		(4 * sizeof(int))
+#define __ARCH_SI_TRAPNO
 
-#define SIGEV_PAD_SIZE	((SIGEV_MAX_SIZE/sizeof(int)) - 4)
-
-#define HAVE_ARCH_COPY_SIGINFO
+#define SIGEV_PAD_SIZE			((SIGEV_MAX_SIZE/sizeof(int)) - 4)
 
 #include <asm-generic/siginfo.h>
-
-#ifdef __KERNEL__
-#include <linux/string.h>
-
-extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
-{
-	if (from->si_code < 0)
-		memcpy(to, from, sizeof(siginfo_t));
-	else
-		/* _sigchld is currently the largest know union member */
-		memcpy(to, from, 4*sizeof(int) + sizeof(from->_sifields._sigchld));
-}
-
-#endif /* __KERNEL__ */
 
 #endif
diff -Nru a/include/asm-alpha/system.h b/include/asm-alpha/system.h
--- a/include/asm-alpha/system.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-alpha/system.h	Mon Nov  4 14:31:02 2002
@@ -61,7 +61,8 @@
 	int		retry	:  1;	/* retry flag */
 	unsigned int	proc_offset;	/* processor-specific offset */
 	unsigned int	sys_offset;	/* system-specific offset */
-	unsigned long	code;		/* machine check code */
+	unsigned int	code;		/* machine check code */
+	unsigned int	frame_rev;	/* frame revision */
 };
 
 /* Machine Check Frame for uncorrectable errors (Large format)
@@ -117,11 +118,11 @@
 	unsigned long DC0_SYNDROME;
 	unsigned long C_STAT;
 	unsigned long C_STS;
-	unsigned long RESERVED0;
+	unsigned long MM_STAT;
 	unsigned long EXC_ADDR;
 	unsigned long IER_CM;
 	unsigned long ISUM;
-	unsigned long MM_STAT;
+	unsigned long RESERVED0;
 	unsigned long PAL_BASE;
 	unsigned long I_CTL;
 	unsigned long PCTX;
diff -Nru a/include/asm-alpha/unistd.h b/include/asm-alpha/unistd.h
--- a/include/asm-alpha/unistd.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-alpha/unistd.h	Mon Nov  4 14:31:01 2002
@@ -552,9 +552,9 @@
 }
 
 extern off_t sys_lseek(int, off_t, int);
-static inline off_t lseek(int fd, off_t off, int whense)
+static inline off_t lseek(int fd, off_t off, int whence)
 {
-	return sys_lseek(fd, off, whense);
+	return sys_lseek(fd, off, whence);
 }
 
 extern long sys_exit(int);
@@ -565,14 +565,14 @@
 
 #define exit(x) _exit(x)
 
-extern long sys_write(int, const char *, int);
-static inline long write(int fd, const char * buf, int nr)
+extern long sys_write(int, const char *, size_t);
+static inline long write(int fd, const char * buf, size_t nr)
 {
 	return sys_write(fd, buf, nr);
 }
 
-extern long sys_read(int, char *, int);
-static inline long read(int fd, char * buf, int nr)
+extern long sys_read(int, char *, size_t);
+static inline long read(int fd, char * buf, size_t nr)
 {
 	return sys_read(fd, buf, nr);
 }
diff -Nru a/include/asm-arm/arch-ebsa285/hardware.h b/include/asm-arm/arch-ebsa285/hardware.h
--- a/include/asm-arm/arch-ebsa285/hardware.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-arm/arch-ebsa285/hardware.h	Mon Nov  4 14:31:02 2002
@@ -133,7 +133,7 @@
 
 #define pcibios_assign_all_busses()	1
 
-#define PCIBIOS_MIN_IO		0x6000
-#define PCIBIOS_MIN_MEM 	0x40000000
+#define PCIBIOS_MIN_IO		0x1000
+#define PCIBIOS_MIN_MEM 	0x81000000
 
 #endif
diff -Nru a/include/asm-arm/arch-sa1100/badge4.h b/include/asm-arm/arch-sa1100/badge4.h
--- a/include/asm-arm/arch-sa1100/badge4.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-arm/arch-sa1100/badge4.h	Mon Nov  4 14:31:02 2002
@@ -68,6 +68,7 @@
 #define BADGE4_5V_PCMCIA_SOCK1		(1<<1)
 #define BADGE4_5V_PCMCIA_SOCK(n)	(1<<(n))
 #define BADGE4_5V_USB			(1<<2)
+#define BADGE4_5V_INITIALLY		(1<<3)
 
 #ifndef __ASSEMBLY__
 extern void badge4_set_5V(unsigned subsystem, int on);
diff -Nru a/include/asm-arm/io.h b/include/asm-arm/io.h
--- a/include/asm-arm/io.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-arm/io.h	Mon Nov  4 14:31:01 2002
@@ -22,7 +22,6 @@
 
 #ifdef __KERNEL__
 
-#include <linux/config.h>
 #include <linux/types.h>
 #include <asm/byteorder.h>
 #include <asm/memory.h>
@@ -94,6 +93,8 @@
  * Note that we prevent GCC re-ordering or caching values in expressions
  * by introducing sequence points into the in*() definitions.  Note that
  * __raw_* do not guarantee this behaviour.
+ *
+ * The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space.
  */
 #ifdef __io
 #define outb(v,p)		__raw_writeb(v,__io(p))
diff -Nru a/include/asm-arm/mman.h b/include/asm-arm/mman.h
--- a/include/asm-arm/mman.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-arm/mman.h	Mon Nov  4 14:31:01 2002
@@ -18,6 +18,8 @@
 #define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
 #define MAP_LOCKED	0x2000		/* pages are locked */
 #define MAP_NORESERVE	0x4000		/* don't check for reservations */
+#define MAP_POPULATE	0x8000		/* populate (prefault) page tables */
+#define MAP_NONBLOCK	0x10000		/* do not block on IO */
 
 #define MS_ASYNC	1		/* sync memory asynchronously */
 #define MS_INVALIDATE	2		/* invalidate the caches */
diff -Nru a/include/asm-arm/pci.h b/include/asm-arm/pci.h
--- a/include/asm-arm/pci.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-arm/pci.h	Mon Nov  4 14:31:01 2002
@@ -241,7 +241,7 @@
 
 /* kmem_cache style wrapper around pci_alloc_consistent() */
 struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev,
-		size_t size, size_t align, size_t allocation, int flags);
+		size_t size, size_t align, size_t allocation);
 void pci_pool_destroy (struct pci_pool *pool);
 
 void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle);
diff -Nru a/include/asm-arm/poll.h b/include/asm-arm/poll.h
--- a/include/asm-arm/poll.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-arm/poll.h	Mon Nov  4 14:31:02 2002
@@ -15,6 +15,7 @@
 #define POLLWRNORM	0x0100
 #define POLLWRBAND	0x0200
 #define POLLMSG		0x0400
+#define POLLREMOVE	0x1000
 
 struct pollfd {
 	int fd;
diff -Nru a/include/asm-arm/proc-armv/pgtable.h b/include/asm-arm/proc-armv/pgtable.h
--- a/include/asm-arm/proc-armv/pgtable.h	Mon Nov  4 14:31:00 2002
+++ b/include/asm-arm/proc-armv/pgtable.h	Mon Nov  4 14:31:00 2002
@@ -38,7 +38,7 @@
 #define PMD_TYPE_FAULT		(0 << 0)
 #define PMD_TYPE_TABLE		(1 << 0)
 #define PMD_TYPE_SECT		(2 << 0)
-#define PMD_UPDATABLE		(1 << 4)
+#define PMD_BIT4		(1 << 4)
 #define PMD_DOMAIN(x)		((x) << 5)
 #define PMD_PROTECTION		(1 << 9)	/* v5 */
 /*
@@ -49,6 +49,13 @@
 #define PMD_SECT_AP_WRITE	(1 << 10)
 #define PMD_SECT_AP_READ	(1 << 11)
 #define PMD_SECT_TEX(x)		((x) << 12)	/* v5 */
+
+#define PMD_SECT_UNCACHED	(0)
+#define PMD_SECT_WT		(PMD_SECT_CACHEABLE)
+#define PMD_SECT_WB		(PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE)
+#define PMD_SECT_MINICACHE	(PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE)
+#define PMD_SECT_WBWA		(PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE)
+
 /*
  *   - coarse table (not used)
  */
@@ -184,6 +191,7 @@
  * Mark the prot value as uncacheable and unbufferable.
  */
 #define pgprot_noncached(prot)	__pgprot(pgprot_val(prot) & ~(L_PTE_CACHEABLE | L_PTE_BUFFERABLE))
+#define pgprot_writecombine(prot) __pgprot(pgprot_val(prot) & ~L_PTE_CACHEABLE)
 
 #define pgtable_cache_init() do { } while (0)
 
diff -Nru a/include/asm-arm/processor.h b/include/asm-arm/processor.h
--- a/include/asm-arm/processor.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-arm/processor.h	Mon Nov  4 14:31:01 2002
@@ -62,10 +62,6 @@
 /* Free all resources held by a thread. */
 extern void release_thread(struct task_struct *);
 
-/* Copy and release all segment info associated with a VM */
-#define copy_segments(tsk, mm)		do { } while (0)
-#define release_segments(mm)		do { } while (0)
-
 unsigned long get_wchan(struct task_struct *p);
 
 #define cpu_relax()			barrier()
diff -Nru a/include/asm-arm/ptrace.h b/include/asm-arm/ptrace.h
--- a/include/asm-arm/ptrace.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-arm/ptrace.h	Mon Nov  4 14:31:02 2002
@@ -6,10 +6,7 @@
 #define PTRACE_GETFPREGS	14
 #define PTRACE_SETFPREGS	15
 
-#define PTRACE_SETOPTIONS	21
-
-/* options set using PTRACE_SETOPTIONS */
-#define PTRACE_O_TRACESYSGOOD	0x00000001
+#define PTRACE_OLDSETOPTIONS	21
 
 #include <asm/proc/ptrace.h>
 
diff -Nru a/include/asm-arm/system.h b/include/asm-arm/system.h
--- a/include/asm-arm/system.h	Mon Nov  4 14:31:00 2002
+++ b/include/asm-arm/system.h	Mon Nov  4 14:31:00 2002
@@ -44,6 +44,16 @@
 
 extern asmlinkage void __backtrace(void);
 
+#define CPU_ARCH_UNKNOWN	0
+#define CPU_ARCH_ARMv3		1
+#define CPU_ARCH_ARMv4		2
+#define CPU_ARCH_ARMv4T		3
+#define CPU_ARCH_ARMv5		4
+#define CPU_ARCH_ARMv5T		5
+#define CPU_ARCH_ARMv5TE	6
+
+extern int cpu_architecture(void);
+
 /*
  * Include processor dependent parts
  */
diff -Nru a/include/asm-cris/processor.h b/include/asm-cris/processor.h
--- a/include/asm-cris/processor.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-cris/processor.h	Mon Nov  4 14:31:01 2002
@@ -108,10 +108,6 @@
 
 #define KSTK_ESP(tsk)   ((tsk) == current ? rdusp() : (tsk)->thread.usp)
 
-#define copy_segments(tsk, mm)          do { } while (0)
-#define release_segments(mm)            do { } while (0)
-#define forget_segments()               do { } while (0)
- 
 /*
  * Free current thread data structures etc..
  */
diff -Nru a/include/asm-i386/cpu.h b/include/asm-i386/cpu.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-i386/cpu.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,26 @@
+#ifndef _ASM_I386_CPU_H_
+#define _ASM_I386_CPU_H_
+
+#include <linux/device.h>
+#include <linux/cpu.h>
+
+#include <asm/topology.h>
+#include <asm/node.h>
+
+struct i386_cpu {
+	struct cpu cpu;
+};
+extern struct i386_cpu cpu_devices[NR_CPUS];
+
+
+static inline int arch_register_cpu(int num){
+	struct node *parent = NULL;
+	
+#ifdef CONFIG_NUMA
+	parent = &node_devices[__cpu_to_node(num)].node;
+#endif /* CONFIG_NUMA */
+
+	return register_cpu(&cpu_devices[num].cpu, num, parent);
+}
+
+#endif /* _ASM_I386_CPU_H_ */
diff -Nru a/include/asm-i386/memblk.h b/include/asm-i386/memblk.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-i386/memblk.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,23 @@
+#ifndef _ASM_I386_MEMBLK_H_
+#define _ASM_I386_MEMBLK_H_
+
+#include <linux/device.h>
+#include <linux/mmzone.h>
+#include <linux/memblk.h>
+
+#include <asm/topology.h>
+#include <asm/node.h>
+
+struct i386_memblk {
+	struct memblk memblk;
+};
+extern struct i386_memblk memblk_devices[MAX_NR_MEMBLKS];
+
+static inline int arch_register_memblk(int num){
+	int p_node = __memblk_to_node(num);
+
+	return register_memblk(&memblk_devices[num].memblk, num, 
+				&node_devices[p_node].node);
+}
+
+#endif /* _ASM_I386_MEMBLK_H_ */
diff -Nru a/include/asm-i386/mman.h b/include/asm-i386/mman.h
--- a/include/asm-i386/mman.h	Mon Nov  4 14:31:00 2002
+++ b/include/asm-i386/mman.h	Mon Nov  4 14:31:00 2002
@@ -18,6 +18,8 @@
 #define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
 #define MAP_LOCKED	0x2000		/* pages are locked */
 #define MAP_NORESERVE	0x4000		/* don't check for reservations */
+#define MAP_POPULATE	0x8000		/* populate (prefault) pagetables */
+#define MAP_NONBLOCK	0x10000		/* do not block on IO */
 
 #define MS_ASYNC	1		/* sync memory asynchronously */
 #define MS_INVALIDATE	2		/* invalidate the caches */
diff -Nru a/include/asm-i386/mmu_context.h b/include/asm-i386/mmu_context.h
--- a/include/asm-i386/mmu_context.h	Mon Nov  4 14:31:00 2002
+++ b/include/asm-i386/mmu_context.h	Mon Nov  4 14:31:00 2002
@@ -8,10 +8,10 @@
 #include <asm/tlbflush.h>
 
 /*
- * possibly do the LDT unload here?
+ * Used for LDT copy/destruction.
  */
-#define destroy_context(mm)		do { } while(0)
 int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
+void destroy_context(struct mm_struct *mm);
 
 #ifdef CONFIG_SMP
 
diff -Nru a/include/asm-i386/node.h b/include/asm-i386/node.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-i386/node.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,25 @@
+#ifndef _ASM_I386_NODE_H_
+#define _ASM_I386_NODE_H_
+
+#include <linux/device.h>
+#include <linux/mmzone.h>
+#include <linux/node.h>
+
+#include <asm/topology.h>
+
+struct i386_node {
+	struct node node;
+};
+extern struct i386_node node_devices[MAX_NUMNODES];
+
+static inline int arch_register_node(int num){
+	int p_node = __parent_node(num);
+	struct node *parent = NULL;
+
+	if (p_node != num)
+		parent = &node_devices[p_node].node;
+
+	return register_node(&node_devices[num].node, num, parent);
+}
+
+#endif /* _ASM_I386_NODE_H_ */
diff -Nru a/include/asm-i386/processor.h b/include/asm-i386/processor.h
--- a/include/asm-i386/processor.h	Mon Nov  4 14:31:00 2002
+++ b/include/asm-i386/processor.h	Mon Nov  4 14:31:00 2002
@@ -270,7 +270,7 @@
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
-#define TASK_UNMAPPED_BASE	(TASK_SIZE / 3)
+#define TASK_UNMAPPED_BASE	(PAGE_ALIGN(TASK_SIZE / 3))
 
 /*
  * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
@@ -433,9 +433,6 @@
  * create a kernel thread without removing it from tasklists
  */
 extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
-/* Release all segment info associated with a VM */
-extern void release_segments(struct mm_struct * mm);
 
 extern unsigned long thread_saved_pc(struct task_struct *tsk);
 
diff -Nru a/include/asm-i386/ptrace.h b/include/asm-i386/ptrace.h
--- a/include/asm-i386/ptrace.h	Mon Nov  4 14:31:00 2002
+++ b/include/asm-i386/ptrace.h	Mon Nov  4 14:31:00 2002
@@ -49,10 +49,7 @@
 #define PTRACE_GETFPXREGS         18
 #define PTRACE_SETFPXREGS         19
 
-#define PTRACE_SETOPTIONS         21
-
-/* options set using PTRACE_SETOPTIONS */
-#define PTRACE_O_TRACESYSGOOD     0x00000001
+#define PTRACE_OLDSETOPTIONS         21
 
 #ifdef __KERNEL__
 #define user_mode(regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->xcs))
diff -Nru a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
--- a/include/asm-i386/unistd.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-i386/unistd.h	Mon Nov  4 14:31:02 2002
@@ -261,7 +261,8 @@
 #define __NR_sys_epoll_create	254
 #define __NR_sys_epoll_ctl	255
 #define __NR_sys_epoll_wait	256
-  
+#define __NR_remap_file_pages	257
+
 
 /* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
 
diff -Nru a/include/asm-i386/vic.h b/include/asm-i386/vic.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-i386/vic.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,61 @@
+/* Copyright (C) 1999,2001
+ *
+ * Author: J.E.J.Bottomley@HansenPartnership.com
+ *
+ * Standard include definitions for the NCR Voyager Interrupt Controller */
+
+/* The eight CPI vectors.  To activate a CPI, you write a bit mask
+ * corresponding to the processor set to be interrupted into the
+ * relevant register.  That set of CPUs will then be interrupted with
+ * the CPI */
+static const int VIC_CPI_Registers[] =
+	{0xFC00, 0xFC01, 0xFC08, 0xFC09,
+	 0xFC10, 0xFC11, 0xFC18, 0xFC19 };
+
+#define VIC_PROC_WHO_AM_I		0xfc29
+#	define	QUAD_IDENTIFIER		0xC0
+#	define  EIGHT_SLOT_IDENTIFIER	0xE0
+#define QIC_EXTENDED_PROCESSOR_SELECT	0xFC72
+#define VIC_CPI_BASE_REGISTER		0xFC41
+#define VIC_PROCESSOR_ID		0xFC21
+#	define VIC_CPU_MASQUERADE_ENABLE 0x8
+
+#define VIC_CLAIM_REGISTER_0		0xFC38
+#define VIC_CLAIM_REGISTER_1		0xFC39
+#define VIC_REDIRECT_REGISTER_0		0xFC60
+#define VIC_REDIRECT_REGISTER_1		0xFC61
+#define VIC_PRIORITY_REGISTER		0xFC20
+
+#define VIC_PRIMARY_MC_BASE		0xFC48
+#define VIC_SECONDARY_MC_BASE		0xFC49
+
+#define QIC_PROCESSOR_ID		0xFC71
+#	define	QIC_CPUID_ENABLE	0x08
+
+#define QIC_VIC_CPI_BASE_REGISTER	0xFC79
+#define QIC_CPI_BASE_REGISTER		0xFC7A
+
+#define QIC_MASK_REGISTER0		0xFC80
+/* NOTE: these are masked high, enabled low */
+#	define QIC_PERF_TIMER		0x01
+#	define QIC_LPE			0x02
+#	define QIC_SYS_INT		0x04
+#	define QIC_CMN_INT		0x08
+/* at the moment, just enable CMN_INT, disable SYS_INT */
+#	define QIC_DEFAULT_MASK0	(~(QIC_CMN_INT /* | VIC_SYS_INT */))
+#define QIC_MASK_REGISTER1		0xFC81
+#	define QIC_BOOT_CPI_MASK	0xFE
+/* Enable CPI's 1-6 inclusive */
+#	define QIC_CPI_ENABLE		0x81
+
+#define QIC_INTERRUPT_CLEAR0		0xFC8A
+#define QIC_INTERRUPT_CLEAR1		0xFC8B
+
+/* this is where we place the CPI vectors */
+#define VIC_DEFAULT_CPI_BASE		0xC0
+/* this is where we place the QIC CPI vectors */
+#define QIC_DEFAULT_CPI_BASE		0xD0
+
+#define VIC_BOOT_INTERRUPT_MASK		0xfe
+
+extern void smp_vic_timer_interrupt(struct pt_regs *regs);
diff -Nru a/include/asm-ia64/ide.h b/include/asm-ia64/ide.h
--- a/include/asm-ia64/ide.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-ia64/ide.h	Mon Nov  4 14:31:02 2002
@@ -83,6 +83,7 @@
 	int index;
 
 	for(index = 0; index < MAX_HWIFS; index++) {
+		memset(&hw, 0, sizeof hw);
 		ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL);
 		hw.irq = ide_default_irq(ide_default_io_base(index));
 		ide_register_hw(&hw, NULL);
diff -Nru a/include/asm-ia64/numa.h b/include/asm-ia64/numa.h
--- a/include/asm-ia64/numa.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-ia64/numa.h	Mon Nov  4 14:31:01 2002
@@ -21,7 +21,9 @@
 # define NR_MEMBLKS   (NR_NODES * 8)
 #endif
 
-extern char cpu_to_node_map[NR_CPUS] __cacheline_aligned;
+#include <linux/cache.h>
+extern volatile char cpu_to_node_map[NR_CPUS] __cacheline_aligned;
+extern volatile unsigned long node_to_cpu_mask[NR_NODES] __cacheline_aligned;
 
 /* Stuff below this line could be architecture independent */
 
diff -Nru a/include/asm-ia64/page.h b/include/asm-ia64/page.h
--- a/include/asm-ia64/page.h	Mon Nov  4 14:31:00 2002
+++ b/include/asm-ia64/page.h	Mon Nov  4 14:31:00 2002
@@ -30,6 +30,9 @@
 #define PAGE_MASK		(~(PAGE_SIZE - 1))
 #define PAGE_ALIGN(addr)	(((addr) + PAGE_SIZE - 1) & PAGE_MASK)
 
+#define PERCPU_PAGE_SHIFT	16	/* log2() of max. size of per-CPU area */
+#define PERCPU_PAGE_SIZE	(__IA64_UL_CONST(1) << PERCPU_PAGE_SHIFT)
+
 #ifdef CONFIG_HUGETLB_PAGE
 
 # if defined(CONFIG_HUGETLB_PAGE_SIZE_4GB)
diff -Nru a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h
--- a/include/asm-ia64/pgtable.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-ia64/pgtable.h	Mon Nov  4 14:31:01 2002
@@ -202,7 +202,7 @@
 #define RGN_MAP_LIMIT	((1UL << (4*PAGE_SHIFT - 12)) - PAGE_SIZE)	/* per region addr limit */
 #define RGN_KERNEL	7
 
-#define VMALLOC_START		(0xa000000000000000 + 3*PAGE_SIZE)
+#define VMALLOC_START		(0xa000000000000000 + 3*PERCPU_PAGE_SIZE)
 #define VMALLOC_VMADDR(x)	((unsigned long)(x))
 #define VMALLOC_END		(0xa000000000000000 + (1UL << (4*PAGE_SHIFT - 9)))
 
diff -Nru a/include/asm-ia64/poll.h b/include/asm-ia64/poll.h
--- a/include/asm-ia64/poll.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-ia64/poll.h	Mon Nov  4 14:31:02 2002
@@ -4,8 +4,8 @@
 /*
  * poll(2) bit definitions.  Chosen to be compatible with Linux/x86.
  *
- * Copyright (C) 1998, 1999 Hewlett-Packard Co
- * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998, 1999, 2002 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
 #define POLLIN		0x0001
@@ -20,6 +20,7 @@
 #define POLLWRNORM	0x0100
 #define POLLWRBAND	0x0200
 #define POLLMSG		0x0400
+#define POLLREMOVE	0x1000
 
 struct pollfd {
 	int fd;
diff -Nru a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h
--- a/include/asm-ia64/processor.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-ia64/processor.h	Mon Nov  4 14:31:01 2002
@@ -179,7 +179,6 @@
 #endif
 #ifdef CONFIG_NUMA
 	struct ia64_node_data *node_data;
-	int nodeid;
 #endif
 };
 
@@ -192,10 +191,6 @@
 #define local_cpu_data		(&__get_cpu_var(cpu_info))
 #define cpu_data(cpu)		(&per_cpu(cpu_info, cpu))
 
-#ifdef CONFIG_NUMA
-#define numa_node_id()		(local_cpu_data->nodeid)
-#endif
-
 extern void identify_cpu (struct cpuinfo_ia64 *);
 extern void print_cpu_info (struct cpuinfo_ia64 *);
 
@@ -366,10 +361,6 @@
  * been called already.
  */
 extern int kernel_thread (int (*fn)(void *), void *arg, unsigned long flags);
-
-/* Copy and release all segment info associated with a VM */
-#define copy_segments(tsk, mm)			do { } while (0)
-#define release_segments(mm)			do { } while (0)
 
 /* Get wait channel for task P.  */
 extern unsigned long get_wchan (struct task_struct *p);
diff -Nru a/include/asm-ia64/ptrace.h b/include/asm-ia64/ptrace.h
--- a/include/asm-ia64/ptrace.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-ia64/ptrace.h	Mon Nov  4 14:31:02 2002
@@ -287,9 +287,6 @@
 #define PTRACE_GETREGS		18	/* get all registers (pt_all_user_regs) in one shot */
 #define PTRACE_SETREGS		19	/* set all registers (pt_all_user_regs) in one shot */
 
-#define PTRACE_SETOPTIONS	21
-
-/* options set using PTRACE_SETOPTIONS */
-#define PTRACE_O_TRACESYSGOOD	0x00000001
+#define PTRACE_OLDSETOPTIONS	21
 
 #endif /* _ASM_IA64_PTRACE_H */
diff -Nru a/include/asm-ia64/system.h b/include/asm-ia64/system.h
--- a/include/asm-ia64/system.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-ia64/system.h	Mon Nov  4 14:31:01 2002
@@ -20,8 +20,9 @@
 
 #define KERNEL_START		(PAGE_OFFSET + 68*1024*1024)
 
-#define GATE_ADDR		(0xa000000000000000 + PAGE_SIZE)
-#define PERCPU_ADDR		(0xa000000000000000 + 2*PAGE_SIZE)
+/* 0xa000000000000000 - 0xa000000000000000+PERCPU_MAX_SIZE remain unmapped */
+#define PERCPU_ADDR		(0xa000000000000000 + PERCPU_PAGE_SIZE)
+#define GATE_ADDR		(0xa000000000000000 + 2*PERCPU_PAGE_SIZE)
 
 #ifndef __ASSEMBLY__
 
diff -Nru a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h
--- a/include/asm-ia64/topology.h	Mon Nov  4 14:31:00 2002
+++ b/include/asm-ia64/topology.h	Mon Nov  4 14:31:00 2002
@@ -15,12 +15,22 @@
 
 #include <asm/acpi.h>
 #include <asm/numa.h>
+#include <asm/smp.h>
 
-/* Returns the number of the node containing CPU 'cpu' */
 #ifdef CONFIG_NUMA
-#define __cpu_to_node(cpu) cpu_to_node_map[cpu]
+/*
+ * Returns the number of the node containing CPU 'cpu'
+ */
+#define __cpu_to_node(cpu) (int)(cpu_to_node_map[cpu])
+
+/*
+ * Returns a bitmask of CPUs on Node 'node'.
+ */
+#define __node_to_cpu_mask(node) (node_to_cpu_mask[node])
+
 #else
 #define __cpu_to_node(cpu) (0)
+#define __node_to_cpu_mask(node) (phys_cpu_present_map)
 #endif
 
 /*
@@ -41,34 +51,8 @@
 
 /*
  * Returns the number of the first CPU on Node 'node'.
- * Slow in the current implementation.
- * Who needs this?
- */
-/* #define __node_to_first_cpu(node) pool_cpus[pool_ptr[node]] */
-static inline int __node_to_first_cpu(int node)
-{
-	int i;
-
-	for (i=0; i<NR_CPUS; i++)
-		if (__cpu_to_node(i)==node)
-			return i;
-	BUG(); /* couldn't find a cpu on given node */
-	return -1;
-}
-
-/*
- * Returns a bitmask of CPUs on Node 'node'.
  */
-static inline unsigned long __node_to_cpu_mask(int node)
-{
-	int cpu;
-	unsigned long mask = 0UL;
-
-	for(cpu=0; cpu<NR_CPUS; cpu++)
-		if (__cpu_to_node(cpu) == node)
-			mask |= 1UL << cpu;
-	return mask;
-}
+#define __node_to_first_cpu(node) (__ffs(__node_to_cpu_mask(node)))
 
 /*
  * Returns the number of the first MemBlk on Node 'node'
diff -Nru a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h
--- a/include/asm-ia64/unistd.h	Mon Nov  4 14:31:00 2002
+++ b/include/asm-ia64/unistd.h	Mon Nov  4 14:31:00 2002
@@ -226,12 +226,15 @@
 #define __NR_alloc_hugepages		1234
 #define __NR_free_hugepages		1235
 #define __NR_exit_group			1236
-/* 1237 currently unused */
+#define __NR_lookup_dcookie		1237
 #define __NR_io_setup			1238
 #define __NR_io_destroy			1239
 #define __NR_io_getevents		1240
 #define __NR_io_submit			1241
 #define __NR_io_cancel			1242
+#define __NR_epoll_create		1243
+#define __NR_epoll_ctl			1244
+#define __NR_epoll_wait			1245
 
 #if !defined(__ASSEMBLY__) && !defined(ASSEMBLER)
 
diff -Nru a/include/asm-m68k/checksum.h b/include/asm-m68k/checksum.h
--- a/include/asm-m68k/checksum.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-m68k/checksum.h	Mon Nov  4 14:31:02 2002
@@ -26,8 +26,8 @@
 extern unsigned int csum_partial_copy_from_user(const char *src, char *dst,
 						int len, int sum, int *csum_err);
 
-#define csum_partial_copy_nocheck(src, dst, len, sum)	\
-	csum_partial_copy((src), (dst), (len), (sum))
+extern unsigned int csum_partial_copy_nocheck(const char *src, char *dst,
+					      int len, int sum);
 
 /*
  *	This is a version of ip_compute_csum() optimized for IP headers,
diff -Nru a/include/asm-m68k/dvma.h b/include/asm-m68k/dvma.h
--- a/include/asm-m68k/dvma.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-m68k/dvma.h	Mon Nov  4 14:31:02 2002
@@ -22,7 +22,8 @@
 
 #define dvma_malloc(x) dvma_malloc_align(x, 0)
 #define dvma_map(x, y) dvma_map_align(x, y, 0)
-
+#define dvma_map_vme(x, y) (dvma_map(x, y) & 0xfffff)
+#define dvma_map_align_vme(x, y, z) (dvma_map_align (x, y, z) & 0xfffff)
 extern unsigned long dvma_map_align(unsigned long kaddr, int len, 
 			    int align);
 extern void *dvma_malloc_align(unsigned long len, unsigned long align);
@@ -52,6 +53,8 @@
 /* virt <-> phys conversions */
 #define dvma_vtop(x) ((unsigned long)(x) & 0xffffff)
 #define dvma_ptov(x) ((unsigned long)(x) | 0xf000000)
+#define dvma_vtovme(x) ((unsigned long)(x) & 0x00fffff)
+#define dvma_vmetov(x) ((unsigned long)(x) | 0xff00000)
 #define dvma_vtob(x) dvma_vtop(x)
 #define dvma_btov(x) dvma_ptov(x)
 
diff -Nru a/include/asm-m68k/floppy.h b/include/asm-m68k/floppy.h
--- a/include/asm-m68k/floppy.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-m68k/floppy.h	Mon Nov  4 14:31:02 2002
@@ -9,7 +9,7 @@
  *
  * Copyright (C) 1999, 2000, 2001
  *
- * Sun3x support added 2/4/2000 Sam Creasey (sammy@oh.verio.com)
+ * Sun3x support added 2/4/2000 Sam Creasey (sammy@sammy.net)
  *
  */
 
diff -Nru a/include/asm-m68k/hardirq.h b/include/asm-m68k/hardirq.h
--- a/include/asm-m68k/hardirq.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-m68k/hardirq.h	Mon Nov  4 14:31:01 2002
@@ -7,24 +7,87 @@
 /* entry.S is sensitive to the offsets of these fields */
 typedef struct {
 	unsigned int __softirq_pending;
-	unsigned int __local_irq_count;
-	unsigned int __local_bh_count;
 	unsigned int __syscall_count;
         struct task_struct * __ksoftirqd_task;
 } ____cacheline_aligned irq_cpustat_t;
 
 #include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
 
-#define in_interrupt() (local_irq_count(smp_processor_id()) + local_bh_count(smp_processor_id()) != 0)
+/*
+ * We put the hardirq and softirq counter into the preemption
+ * counter. The bitmask has the following meaning:
+ *
+ * - bits 0-7 are the preemption count (max preemption depth: 256)
+ * - bits 8-15 are the softirq count (max # of softirqs: 256)
+ * - bits 16-23 are the hardirq count (max # of hardirqs: 256)
+ *
+ * - ( bit 26 is the PREEMPT_ACTIVE flag. )
+ *
+ * PREEMPT_MASK: 0x000000ff
+ * HARDIRQ_MASK: 0x0000ff00
+ * SOFTIRQ_MASK: 0x00ff0000
+ */
+
+#define PREEMPT_BITS	8
+#define SOFTIRQ_BITS	8
+#define HARDIRQ_BITS	8
+
+#define PREEMPT_SHIFT	0
+#define SOFTIRQ_SHIFT	(PREEMPT_SHIFT + PREEMPT_BITS)
+#define HARDIRQ_SHIFT	(SOFTIRQ_SHIFT + SOFTIRQ_BITS)
+
+#define __MASK(x)	((1UL << (x))-1)
+
+#define PREEMPT_MASK	(__MASK(PREEMPT_BITS) << PREEMPT_SHIFT)
+#define HARDIRQ_MASK	(__MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT)
+#define SOFTIRQ_MASK	(__MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT)
+
+#define hardirq_count()	(preempt_count() & HARDIRQ_MASK)
+#define softirq_count()	(preempt_count() & SOFTIRQ_MASK)
+#define irq_count()	(preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK))
+
+#define PREEMPT_OFFSET	(1UL << PREEMPT_SHIFT)
+#define SOFTIRQ_OFFSET	(1UL << SOFTIRQ_SHIFT)
+#define HARDIRQ_OFFSET	(1UL << HARDIRQ_SHIFT)
+
+/*
+ * The hardirq mask has to be large enough to have
+ * space for potentially all IRQ sources in the system
+ * nesting on a single CPU:
+ */
+#if (1 << HARDIRQ_BITS) < NR_IRQS
+# error HARDIRQ_BITS is too low!
+#endif
+
+/*
+ * Are we doing bottom half or hardware interrupt processing?
+ * Are we in a softirq context? Interrupt context?
+ */
+#define in_irq()		(hardirq_count())
+#define in_softirq()		(softirq_count())
+#define in_interrupt()		(irq_count())
+
+
+#define hardirq_trylock()	(!in_interrupt())
+#define hardirq_endlock()	do { } while (0)
+
+#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
+
+#if CONFIG_PREEMPT
+# define in_atomic()	(preempt_count() != kernel_locked())
+# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
+#else
+# define in_atomic()	(preempt_count() != 0)
+# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
+#endif
+#define irq_exit()							\
+do {									\
+		preempt_count() -= IRQ_EXIT_OFFSET;			\
+		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
+			do_softirq();					\
+		preempt_enable_no_resched();				\
+} while (0)
 
-#define in_irq() (local_irq_count(smp_processor_id()) != 0)
-
-#define hardirq_trylock(cpu)	(local_irq_count(cpu) == 0)
-#define hardirq_endlock(cpu)	do { } while (0)
-
-#define irq_enter(cpu)		(local_irq_count(cpu)++)
-#define irq_exit(cpu)		(local_irq_count(cpu)--)
-
-#define synchronize_irq()	barrier()
+#define synchronize_irq(irq)	barrier()
 
 #endif
diff -Nru a/include/asm-m68k/io.h b/include/asm-m68k/io.h
--- a/include/asm-m68k/io.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-m68k/io.h	Mon Nov  4 14:31:02 2002
@@ -280,18 +280,6 @@
 #endif /* CONFIG_PCI */
 
 
-/* Values for nocacheflag and cmode */
-#define IOMAP_FULL_CACHING		0
-#define IOMAP_NOCACHE_SER		1
-#define IOMAP_NOCACHE_NONSER		2
-#define IOMAP_WRITETHROUGH		3
-
-extern void iounmap(void *addr);
-
-extern void *__ioremap(unsigned long physaddr, unsigned long size,
-		       int cacheflag);
-extern void __iounmap(void *addr, unsigned long size);
-
 extern inline void *ioremap(unsigned long physaddr, unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
diff -Nru a/include/asm-m68k/kmap_types.h b/include/asm-m68k/kmap_types.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68k/kmap_types.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,21 @@
+#ifndef __ASM_M68K_KMAP_TYPES_H
+#define __ASM_M68K_KMAP_TYPES_H
+
+#include <linux/config.h>
+
+enum km_type {
+	KM_BOUNCE_READ,
+	KM_SKB_SUNRPC_DATA,
+	KM_SKB_DATA_SOFTIRQ,
+	KM_USER0,
+	KM_USER1,
+	KM_BIO_SRC_IRQ,
+	KM_BIO_DST_IRQ,
+	KM_PTE0,
+	KM_PTE1,
+	KM_IRQ0,
+	KM_IRQ1,
+	KM_TYPE_NR
+};
+
+#endif	/* __ASM_M68K_KMAP_TYPES_H */
diff -Nru a/include/asm-m68k/nubus.h b/include/asm-m68k/nubus.h
--- a/include/asm-m68k/nubus.h	Mon Nov  4 14:31:03 2002
+++ b/include/asm-m68k/nubus.h	Mon Nov  4 14:31:03 2002
@@ -1,7 +1,7 @@
 #ifndef _ASM_M68K_NUBUS_H
 #define _ASM_M68K_NUBUS_H
 
-#include <asm/io.h>
+#include <asm/raw_io.h>
 
 #define nubus_readb raw_inb
 #define nubus_readw raw_inw
diff -Nru a/include/asm-m68k/page.h b/include/asm-m68k/page.h
--- a/include/asm-m68k/page.h	Mon Nov  4 14:31:03 2002
+++ b/include/asm-m68k/page.h	Mon Nov  4 14:31:03 2002
@@ -124,6 +124,7 @@
 
 #ifndef CONFIG_SUN3
 
+#define WANT_PAGE_VIRTUAL
 #ifdef CONFIG_SINGLE_MEMORY_CHUNK
 extern unsigned long m68k_memoffset;
 
diff -Nru a/include/asm-m68k/pci.h b/include/asm-m68k/pci.h
--- a/include/asm-m68k/pci.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-m68k/pci.h	Mon Nov  4 14:31:01 2002
@@ -30,7 +30,7 @@
 	struct pci_ops *m68k_pci_ops;
 
 	void (*fixup)(int pci_modify);
-	void (*conf_device)(unsigned char bus, unsigned char device_fn);
+	void (*conf_device)(struct pci_dev *dev);
 };
 
 #define pcibios_assign_all_busses()	0
diff -Nru a/include/asm-m68k/percpu.h b/include/asm-m68k/percpu.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68k/percpu.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,6 @@
+#ifndef __ASM_M68K_PERCPU_H
+#define __ASM_M68K_PERCPU_H
+
+#include <asm-generic/percpu.h>
+
+#endif	/* __ASM_M68K_PERCPU_H */
diff -Nru a/include/asm-m68k/poll.h b/include/asm-m68k/poll.h
--- a/include/asm-m68k/poll.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-m68k/poll.h	Mon Nov  4 14:31:01 2002
@@ -12,6 +12,7 @@
 #define POLLRDBAND	128
 #define POLLWRBAND	256
 #define POLLMSG		0x0400
+#define POLLREMOVE	0x1000
 
 struct pollfd {
 	int fd;
diff -Nru a/include/asm-m68k/processor.h b/include/asm-m68k/processor.h
--- a/include/asm-m68k/processor.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-m68k/processor.h	Mon Nov  4 14:31:02 2002
@@ -114,9 +114,6 @@
 
 extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
-#define copy_segments(tsk, mm)		do { } while (0)
-#define release_segments(mm)		do { } while (0)
-
 /*
  * Free current thread data structures etc..
  */
diff -Nru a/include/asm-m68k/q40_master.h b/include/asm-m68k/q40_master.h
--- a/include/asm-m68k/q40_master.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-m68k/q40_master.h	Mon Nov  4 14:31:02 2002
@@ -10,7 +10,6 @@
 
 
 #define q40_master_addr 0xff000000
-#define q40_rtc_addr    0xff021ffc
 
 #define IIRQ_REG            0x0       /* internal IRQ reg */
 #define EIRQ_REG            0x4       /* external ... */
@@ -43,28 +42,25 @@
 #define master_inb(_reg_)      in_8((unsigned char *)q40_master_addr+_reg_)
 #define master_outb(_b_,_reg_)  out_8((unsigned char *)q40_master_addr+_reg_,_b_)
 
-
-/* define some Q40 specific ints */
-#include "q40ints.h"
-
 /* RTC defines */
 
-#define Q40_RTC_BASE (q40_rtc_addr)
-
-#define RTC_YEAR        (*(unsigned char *)(Q40_RTC_BASE+0))
-#define RTC_MNTH        (*(unsigned char *)(Q40_RTC_BASE-4))
-#define RTC_DATE        (*(unsigned char *)(Q40_RTC_BASE-8))
-#define RTC_DOW         (*(unsigned char *)(Q40_RTC_BASE-12))
-#define RTC_HOUR        (*(unsigned char *)(Q40_RTC_BASE-16))
-#define RTC_MINS        (*(unsigned char *)(Q40_RTC_BASE-20))
-#define RTC_SECS        (*(unsigned char *)(Q40_RTC_BASE-24))
-#define RTC_CTRL        (*(unsigned char *)(Q40_RTC_BASE-28))
+#define Q40_RTC_BASE	    (0xff021ffc)
 
+#define Q40_RTC_YEAR        (*(volatile unsigned char *)(Q40_RTC_BASE+0))
+#define Q40_RTC_MNTH        (*(volatile unsigned char *)(Q40_RTC_BASE-4))
+#define Q40_RTC_DATE        (*(volatile unsigned char *)(Q40_RTC_BASE-8))
+#define Q40_RTC_DOW         (*(volatile unsigned char *)(Q40_RTC_BASE-12))
+#define Q40_RTC_HOUR        (*(volatile unsigned char *)(Q40_RTC_BASE-16))
+#define Q40_RTC_MINS        (*(volatile unsigned char *)(Q40_RTC_BASE-20))
+#define Q40_RTC_SECS        (*(volatile unsigned char *)(Q40_RTC_BASE-24))
+#define Q40_RTC_CTRL        (*(volatile unsigned char *)(Q40_RTC_BASE-28))
 
 /* some control bits */
-#define RTC_READ   64  /* prepare for reading */
-#define RTC_WRITE  128
+#define Q40_RTC_READ   64  /* prepare for reading */
+#define Q40_RTC_WRITE  128
 
+/* define some Q40 specific ints */
+#include "q40ints.h"
 
 /* misc defs */
 #define DAC_LEFT  ((unsigned char *)0xff008000)
diff -Nru a/include/asm-m68k/raw_io.h b/include/asm-m68k/raw_io.h
--- a/include/asm-m68k/raw_io.h	Mon Nov  4 14:31:03 2002
+++ b/include/asm-m68k/raw_io.h	Mon Nov  4 14:31:03 2002
@@ -11,6 +11,19 @@
 #ifdef __KERNEL__
 
 
+/* Values for nocacheflag and cmode */
+#define IOMAP_FULL_CACHING		0
+#define IOMAP_NOCACHE_SER		1
+#define IOMAP_NOCACHE_NONSER		2
+#define IOMAP_WRITETHROUGH		3
+
+extern void iounmap(void *addr);
+
+extern void *__ioremap(unsigned long physaddr, unsigned long size,
+		       int cacheflag);
+extern void __iounmap(void *addr, unsigned long size);
+
+
 /* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
  * two accesses to memory, which may be undesirable for some devices.
  */
diff -Nru a/include/asm-m68k/rtc.h b/include/asm-m68k/rtc.h
--- a/include/asm-m68k/rtc.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-m68k/rtc.h	Mon Nov  4 14:31:01 2002
@@ -33,6 +33,36 @@
 #define RTC_24H 0x02		/* 24 hour mode - else hours bit 7 means pm */
 #define RTC_DST_EN 0x01	        /* auto switch DST - works f. USA only */
 
+static inline void get_rtc_time(struct rtc_time *time)
+{
+	/*
+	 * Only the values that we read from the RTC are set. We leave
+	 * tm_wday, tm_yday and tm_isdst untouched. Even though the
+	 * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
+	 * by the RTC when initially set to a non-zero value.
+	 */
+	mach_hwclk(0, time);
+}
+
+static inline int set_rtc_time(struct rtc_time *time)
+{
+	return mach_hwclk(1, time);
+}
+
+static inline int get_rtc_pll(struct rtc_pll_info *pll)
+{
+	if (mach_get_rtc_pll)
+		return mach_get_rtc_pll(pll);
+	else
+		return -EINVAL;
+}
+static inline int set_rtc_pll(struct rtc_pll_info *pll)
+{
+	if (mach_set_rtc_pll)
+		return mach_set_rtc_pll(pll);
+	else
+		return -EINVAL;
+}
 
 #endif /* __KERNEL__ */
 
diff -Nru a/include/asm-m68k/softirq.h b/include/asm-m68k/softirq.h
--- a/include/asm-m68k/softirq.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-m68k/softirq.h	Mon Nov  4 14:31:01 2002
@@ -6,14 +6,19 @@
  */
 
 #include <asm/atomic.h>
+#include <asm/hardirq.h>
 
-#define cpu_bh_disable(cpu)	do { local_bh_count(cpu)++; barrier(); } while (0)
-#define cpu_bh_enable(cpu)	do { barrier(); local_bh_count(cpu)--; } while (0)
+#define local_bh_disable() \
+		do { preempt_count() += SOFTIRQ_OFFSET; barrier(); } while (0)
+#define __local_bh_enable() \
+		do { barrier(); preempt_count() -= SOFTIRQ_OFFSET; } while (0)
 
-#define local_bh_disable()	cpu_bh_disable(smp_processor_id())
-#define local_bh_enable()	cpu_bh_enable(smp_processor_id())
-#define __local_bh_enable()     local_bh_enable()			  
-
-#define in_softirq() (local_bh_count(smp_processor_id()) != 0)
+#define local_bh_enable()						\
+do {									\
+	__local_bh_enable();						\
+	if (unlikely(!in_interrupt() && softirq_pending(smp_processor_id()))) \
+		do_softirq();						\
+	preempt_check_resched();					\
+} while (0)
 
 #endif
diff -Nru a/include/asm-m68k/sun3_pgalloc.h b/include/asm-m68k/sun3_pgalloc.h
--- a/include/asm-m68k/sun3_pgalloc.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-m68k/sun3_pgalloc.h	Mon Nov  4 14:31:01 2002
@@ -95,14 +95,4 @@
 
 #define pgd_populate(mm, pmd, pte) BUG()
 
-
-/* Reserved PMEGs. */
-extern char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
-extern unsigned long pmeg_vaddr[SUN3_PMEGS_NUM];
-extern unsigned char pmeg_alloc[SUN3_PMEGS_NUM];
-extern unsigned char pmeg_ctx[SUN3_PMEGS_NUM];
-
-
-#define check_pgt_cache()	do { } while (0)
-
 #endif /* SUN3_PGALLOC_H */
diff -Nru a/include/asm-m68k/sun3ints.h b/include/asm-m68k/sun3ints.h
--- a/include/asm-m68k/sun3ints.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-m68k/sun3ints.h	Mon Nov  4 14:31:02 2002
@@ -21,6 +21,8 @@
 #include <asm/intersil.h>
 #include <asm/oplib.h>
 
+#define SUN3_INT_VECS 192
+
 void sun3_enable_irq(unsigned int irq);
 void sun3_disable_irq(unsigned int irq);
 int sun3_request_irq(unsigned int irq,
@@ -36,6 +38,12 @@
 extern int show_sun3_interrupts(struct seq_file *, void *);
 extern void sun3_process_int(int, struct pt_regs *);
 extern volatile unsigned char* sun3_intreg;
+
+/* master list of VME vectors -- don't fuck with this */
+#define SUN3_VEC_FLOPPY 0x40
+#define SUN3_VEC_VMESCSI0 0x40
+#define SUN3_VEC_VMESCSI1 0x41
+#define SUN3_VEC_CG 0xA8
 
 
 #endif /* SUN3INTS_H */
diff -Nru a/include/asm-m68k/sun3mmu.h b/include/asm-m68k/sun3mmu.h
--- a/include/asm-m68k/sun3mmu.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-m68k/sun3mmu.h	Mon Nov  4 14:31:01 2002
@@ -161,6 +161,10 @@
 	return;
 }
 
+extern void *sun3_ioremap(unsigned long phys, unsigned long size,
+			  unsigned long type);
+
+extern int sun3_map_test(unsigned long addr, char *val);
 
 #endif	/* !__ASSEMBLY__ */
 
diff -Nru a/include/asm-m68k/sun3xflop.h b/include/asm-m68k/sun3xflop.h
--- a/include/asm-m68k/sun3xflop.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-m68k/sun3xflop.h	Mon Nov  4 14:31:02 2002
@@ -3,7 +3,7 @@
  * Derived partially from asm-sparc/floppy.h, which is:
  *     Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
  *
- * Sun3x version 2/4/2000 Sam Creasey (sammy@oh.verio.com)
+ * Sun3x version 2/4/2000 Sam Creasey (sammy@sammy.net)
  */
 
 #ifndef __ASM_SUN3X_FLOPPY_H
diff -Nru a/include/asm-m68k/system.h b/include/asm-m68k/system.h
--- a/include/asm-m68k/system.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-m68k/system.h	Mon Nov  4 14:31:02 2002
@@ -7,11 +7,6 @@
 #include <asm/segment.h>
 #include <asm/entry.h>
 
-#define prepare_arch_schedule(prev)		do { } while(0)
-#define finish_arch_schedule(prev)		do { } while(0)
-#define prepare_arch_switch(rq)			do { } while(0)
-#define finish_arch_switch(rq)			spin_unlock_irq(&(rq)->lock)
-
 /*
  * switch_to(n) should switch tasks to task ptr, first checking that
  * ptr isn't the current task, in which case it does nothing.  This
@@ -52,24 +47,25 @@
 #define local_irq_enable() asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory")
 #else
 #include <asm/hardirq.h>
-#define local_irq_enable() ({							      \
-	if (MACH_IS_Q40 || !local_irq_count(smp_processor_id()))              \
-		asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory");  \
+#define local_irq_enable() ({							\
+	if (MACH_IS_Q40 || !hardirq_count())					\
+		asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory");	\
 })
 #endif
 #define local_irq_disable() asm volatile ("oriw  #0x0700,%%sr": : : "memory")
 #define local_save_flags(x) asm volatile ("movew %%sr,%0":"=d" (x) : : "memory")
 #define local_irq_restore(x) asm volatile ("movew %0,%%sr": :"d" (x) : "memory")
 
+static inline int irqs_disabled(void)
+{
+	unsigned long flags;
+	local_save_flags(flags);
+	return flags & ~ALLOWINT;
+}
+
 /* For spinlocks etc */
 #define local_irq_save(x)	({ local_save_flags(x); local_irq_disable(); })
 
-#define cli()			local_irq_disable()
-#define sti()			local_irq_enable()
-#define save_flags(x)		local_save_flags(x)
-#define restore_flags(x)	local_irq_restore(x)
-#define save_and_cli(flags)   do { save_flags(flags); cli(); } while(0)
-
 /*
  * Force strict CPU ordering.
  * Not really required on m68k...
@@ -95,33 +91,29 @@
 #ifndef CONFIG_RMW_INSNS
 static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
 {
-  unsigned long tmp, flags;
+	unsigned long flags, tmp;
+
+	local_irq_save(flags);
 
-  save_flags(flags);
-  cli();
+	switch (size) {
+	case 1:
+		tmp = *(u8 *)ptr;
+		*(u8 *)ptr = x;
+		break;
+	case 2:
+		tmp = *(u16 *)ptr;
+		*(u16 *)ptr = x;
+		break;
+	case 4:
+		tmp = *(u32 *)ptr;
+		*(u32 *)ptr = x;
+		break;
+	default:
+		BUG();
+	}
 
-  switch (size) {
-  case 1:
-    __asm__ __volatile__
-    ("moveb %2,%0\n\t"
-     "moveb %1,%2"
-    : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
-    break;
-  case 2:
-    __asm__ __volatile__
-    ("movew %2,%0\n\t"
-     "movew %1,%2"
-    : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
-    break;
-  case 4:
-    __asm__ __volatile__
-    ("movel %2,%0\n\t"
-     "movel %1,%2"
-    : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
-    break;
-  }
-  restore_flags(flags);
-  return tmp;
+	local_irq_restore(flags);
+	return tmp;
 }
 #else
 static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
diff -Nru a/include/asm-m68k/thread_info.h b/include/asm-m68k/thread_info.h
--- a/include/asm-m68k/thread_info.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-m68k/thread_info.h	Mon Nov  4 14:31:02 2002
@@ -18,8 +18,8 @@
 
 #define INIT_THREAD_INFO(tsk)			\
 {						\
-	task:		&tsk,			\
-	exec_domain:	&default_exec_domain,	\
+	.task		= &tsk,			\
+	.exec_domain	= &default_exec_domain,	\
 }
 
 /* THREAD_SIZE should be 8k, so handle differently for 4k and 8k machines */
@@ -60,6 +60,9 @@
 	case TIF_NEED_RESCHED:				\
 		tsk->thread.work.need_resched = val;	\
 		break;					\
+	case TIF_SYSCALL_TRACE:				\
+		tsk->thread.work.syscall_trace = val;	\
+		break;					\
 	default:					\
 		thread_flag_fixme();			\
 	}						\
@@ -73,6 +76,9 @@
 		break;					\
 	case TIF_NEED_RESCHED:				\
 		___res = tsk->thread.work.need_resched;	\
+		break;					\
+	case TIF_SYSCALL_TRACE:				\
+		___res = tsk->thread.work.syscall_trace;\
 		break;					\
 	default:					\
 		___res = thread_flag_fixme();		\
diff -Nru a/include/asm-m68k/virtconvert.h b/include/asm-m68k/virtconvert.h
--- a/include/asm-m68k/virtconvert.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-m68k/virtconvert.h	Mon Nov  4 14:31:02 2002
@@ -20,7 +20,6 @@
  */
 #ifndef CONFIG_SUN3
 extern unsigned long mm_vtop(unsigned long addr) __attribute__ ((const));
-extern unsigned long mm_vtop_fallback (unsigned long) __attribute__ ((const));
 extern unsigned long mm_ptov(unsigned long addr) __attribute__ ((const));
 #else
 extern inline unsigned long mm_vtop(unsigned long vaddr)
@@ -35,39 +34,22 @@
 #endif 
 
 #ifdef CONFIG_SINGLE_MEMORY_CHUNK
-extern inline unsigned long virt_to_phys(volatile void *vaddr)
+static inline unsigned long virt_to_phys(void *vaddr)
 {
-	unsigned long voff = (unsigned long)vaddr - PAGE_OFFSET;
-
-	if (voff < m68k_memory[0].size)
-		return voff + m68k_memory[0].addr;
-	return mm_vtop_fallback((unsigned long)vaddr);
+	return (unsigned long)vaddr - PAGE_OFFSET + m68k_memory[0].addr;
 }
 
-extern inline void * phys_to_virt(unsigned long paddr)
+static inline void * phys_to_virt(unsigned long paddr)
 {
-	unsigned long poff = paddr - m68k_memory[0].addr;
-
-	if (poff < m68k_memory[0].size)
-		return (void *)(poff + PAGE_OFFSET);
-
-#ifdef CONFIG_AMIGA
-	/*
-	 * if on an amiga and address is in first 16M, move it 
-	 * to the ZTWO_VADDR range
-	 */
-	if (MACH_IS_AMIGA && paddr < 16*1024*1024)
-		return (void *)ZTWO_VADDR(paddr);
-#endif
-	return (void *)paddr;
+	return (void *)(paddr - m68k_memory[0].addr + PAGE_OFFSET);
 }
 #else
-extern inline unsigned long virt_to_phys(volatile void * address)
+static inline unsigned long virt_to_phys(void *address)
 {
 	return mm_vtop((unsigned long)address);
 }
 
-extern inline void * phys_to_virt(unsigned long address)
+static inline void *phys_to_virt(unsigned long address)
 {
 	return (void *) mm_ptov(address);
 }
diff -Nru a/include/asm-m68k/zorro.h b/include/asm-m68k/zorro.h
--- a/include/asm-m68k/zorro.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-m68k/zorro.h	Mon Nov  4 14:31:01 2002
@@ -1,7 +1,7 @@
 #ifndef _ASM_M68K_ZORRO_H
 #define _ASM_M68K_ZORRO_H
 
-#include <asm/io.h>
+#include <asm/raw_io.h>
 
 #define z_readb raw_inb
 #define z_readw raw_inw
diff -Nru a/include/asm-m68knommu/MC68328.h b/include/asm-m68knommu/MC68328.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/MC68328.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,1266 @@
+
+/* include/asm-m68knommu/MC68328.h: '328 control registers
+ *
+ * Copyright (C) 1999  Vladimir Gurevich <vgurevic@cisco.com>
+ *                     Bear & Hare Software, Inc.
+ *
+ * Based on include/asm-m68knommu/MC68332.h
+ * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *
+ */
+
+#ifndef _MC68328_H_
+#define _MC68328_H_
+
+#define BYTE_REF(addr) (*((volatile unsigned char*)addr))
+#define WORD_REF(addr) (*((volatile unsigned short*)addr))
+#define LONG_REF(addr) (*((volatile unsigned long*)addr))
+
+#define PUT_FIELD(field, val) (((val) << field##_SHIFT) & field##_MASK)
+#define GET_FIELD(reg, field) (((reg) & field##_MASK) >> field##_SHIFT)
+
+/********** 
+ *
+ * 0xFFFFF0xx -- System Control
+ *
+ **********/
+ 
+/*
+ * System Control Register (SCR)
+ */
+#define SCR_ADDR	0xfffff000
+#define SCR		BYTE_REF(SCR_ADDR)
+
+#define SCR_WDTH8	0x01	/* 8-Bit Width Select */
+#define SCR_DMAP	0x04	/* Double Map */
+#define SCR_SO		0x08	/* Supervisor Only */
+#define SCR_BETEN	0x10	/* Bus-Error Time-Out Enable */
+#define SCR_PRV		0x20	/* Privilege Violation */
+#define SCR_WPV		0x40	/* Write Protect Violation */
+#define SCR_BETO	0x80	/* Bus-Error TimeOut */
+
+/*
+ * Mask Revision Register
+ */
+#define MRR_ADDR 0xfffff004
+#define MRR      LONG_REF(MRR_ADDR)
+ 
+/********** 
+ *
+ * 0xFFFFF1xx -- Chip-Select logic
+ *
+ **********/
+
+/********** 
+ *
+ * 0xFFFFF2xx -- Phase Locked Loop (PLL) & Power Control
+ *
+ **********/
+
+/*
+ * Group Base Address Registers
+ */
+#define GRPBASEA_ADDR	0xfffff100
+#define GRPBASEB_ADDR	0xfffff102
+#define GRPBASEC_ADDR	0xfffff104
+#define GRPBASED_ADDR	0xfffff106
+
+#define GRPBASEA	WORD_REF(GRPBASEA_ADDR)
+#define GRPBASEB	WORD_REF(GRPBASEB_ADDR)
+#define GRPBASEC	WORD_REF(GRPBASEC_ADDR)
+#define GRPBASED	WORD_REF(GRPBASED_ADDR)
+
+#define GRPBASE_V	  0x0001	/* Valid */
+#define GRPBASE_GBA_MASK  0xfff0	/* Group Base Address (bits 31-20) */
+
+/*
+ * Group Base Address Mask Registers 
+ */
+#define GRPMASKA_ADDR	0xfffff108
+#define GRPMASKB_ADDR	0xfffff10a
+#define GRPMASKC_ADDR	0xfffff10c
+#define GRPMASKD_ADDR	0xfffff10e
+
+#define GRPMASKA	WORD_REF(GRPMASKA_ADDR)
+#define GRPMASKB	WORD_REF(GRPMASKB_ADDR)
+#define GRPMASKC	WORD_REF(GRPMASKC_ADDR)
+#define GRPMASKD	WORD_REF(GRPMASKD_ADDR)
+
+#define GRMMASK_GMA_MASK 0xfffff0	/* Group Base Mask (bits 31-20) */
+
+/*
+ * Chip-Select Option Registers (group A)
+ */
+#define CSA0_ADDR	0xfffff110
+#define CSA1_ADDR	0xfffff114
+#define CSA2_ADDR	0xfffff118
+#define CSA3_ADDR	0xfffff11c
+
+#define CSA0		LONG_REF(CSA0_ADDR)
+#define CSA1		LONG_REF(CSA1_ADDR)
+#define CSA2		LONG_REF(CSA2_ADDR)
+#define CSA3		LONG_REF(CSA3_ADDR)
+
+#define CSA_WAIT_MASK	0x00000007	/* Wait State Selection */
+#define CSA_WAIT_SHIFT	0
+#define CSA_RO		0x00000008	/* Read-Only */
+#define CSA_AM_MASK	0x0000ff00	/* Address Mask (bits 23-16) */
+#define CSA_AM_SHIFT	8
+#define CSA_BUSW	0x00010000	/* Bus Width Select */
+#define CSA_AC_MASK	0xff000000	/* Address Compare (bits 23-16) */
+#define CSA_AC_SHIFT	24
+
+/*
+ * Chip-Select Option Registers (group B)
+ */
+#define CSB0_ADDR	0xfffff120
+#define CSB1_ADDR	0xfffff124
+#define CSB2_ADDR	0xfffff128
+#define CSB3_ADDR	0xfffff12c
+
+#define CSB0		LONG_REF(CSB0_ADDR)
+#define CSB1		LONG_REF(CSB1_ADDR)
+#define CSB2		LONG_REF(CSB2_ADDR)
+#define CSB3		LONG_REF(CSB3_ADDR)
+
+#define CSB_WAIT_MASK	0x00000007	/* Wait State Selection */
+#define CSB_WAIT_SHIFT	0
+#define CSB_RO		0x00000008	/* Read-Only */
+#define CSB_AM_MASK	0x0000ff00	/* Address Mask (bits 23-16) */
+#define CSB_AM_SHIFT	8
+#define CSB_BUSW	0x00010000	/* Bus Width Select */
+#define CSB_AC_MASK	0xff000000	/* Address Compare (bits 23-16) */
+#define CSB_AC_SHIFT	24
+
+/*
+ * Chip-Select Option Registers (group C)
+ */
+#define CSC0_ADDR	0xfffff130
+#define CSC1_ADDR	0xfffff134
+#define CSC2_ADDR	0xfffff138
+#define CSC3_ADDR	0xfffff13c
+
+#define CSC0		LONG_REF(CSC0_ADDR)
+#define CSC1		LONG_REF(CSC1_ADDR)
+#define CSC2		LONG_REF(CSC2_ADDR)
+#define CSC3		LONG_REF(CSC3_ADDR)
+
+#define CSC_WAIT_MASK	0x00000007	/* Wait State Selection */
+#define CSC_WAIT_SHIFT	0
+#define CSC_RO		0x00000008	/* Read-Only */
+#define CSC_AM_MASK	0x0000fff0	/* Address Mask (bits 23-12) */
+#define CSC_AM_SHIFT	4
+#define CSC_BUSW	0x00010000	/* Bus Width Select */
+#define CSC_AC_MASK	0xfff00000	/* Address Compare (bits 23-12) */
+#define CSC_AC_SHIFT	20
+
+/*
+ * Chip-Select Option Registers (group D)
+ */
+#define CSD0_ADDR	0xfffff140
+#define CSD1_ADDR	0xfffff144
+#define CSD2_ADDR	0xfffff148
+#define CSD3_ADDR	0xfffff14c
+
+#define CSD0		LONG_REF(CSD0_ADDR)
+#define CSD1		LONG_REF(CSD1_ADDR)
+#define CSD2		LONG_REF(CSD2_ADDR)
+#define CSD3		LONG_REF(CSD3_ADDR)
+
+#define CSD_WAIT_MASK	0x00000007	/* Wait State Selection */
+#define CSD_WAIT_SHIFT	0
+#define CSD_RO		0x00000008	/* Read-Only */
+#define CSD_AM_MASK	0x0000fff0	/* Address Mask (bits 23-12) */
+#define CSD_AM_SHIFT	4
+#define CSD_BUSW	0x00010000	/* Bus Width Select */
+#define CSD_AC_MASK	0xfff00000	/* Address Compare (bits 23-12) */
+#define CSD_AC_SHIFT	20
+
+/**********
+ *
+ * 0xFFFFF2xx -- Phase Locked Loop (PLL) & Power Control
+ *
+ **********/
+ 
+/*
+ * PLL Control Register 
+ */
+#define PLLCR_ADDR	0xfffff200
+#define PLLCR		WORD_REF(PLLCR_ADDR)
+
+#define PLLCR_DISPLL	       0x0008	/* Disable PLL */
+#define PLLCR_CLKEN	       0x0010	/* Clock (CLKO pin) enable */
+#define PLLCR_SYSCLK_SEL_MASK  0x0700	/* System Clock Selection */
+#define PLLCR_SYSCLK_SEL_SHIFT 8
+#define PLLCR_PIXCLK_SEL_MASK  0x3800	/* LCD Clock Selection */
+#define PLLCR_PIXCLK_SEL_SHIFT 11
+
+/* 'EZ328-compatible definitions */
+#define PLLCR_LCDCLK_SEL_MASK	PLLCR_PIXCLK_SEL_MASK
+#define PLLCR_LCDCLK_SEL_SHIFT	PLLCR_PIXCLK_SEL_SHIFT
+
+/*
+ * PLL Frequency Select Register
+ */
+#define PLLFSR_ADDR	0xfffff202
+#define PLLFSR		WORD_REF(PLLFSR_ADDR)
+
+#define PLLFSR_PC_MASK	0x00ff		/* P Count */
+#define PLLFSR_PC_SHIFT 0
+#define PLLFSR_QC_MASK	0x0f00		/* Q Count */
+#define PLLFSR_QC_SHIFT 8
+#define PLLFSR_PROT	0x4000		/* Protect P & Q */
+#define PLLFSR_CLK32	0x8000		/* Clock 32 (kHz) */
+
+/*
+ * Power Control Register
+ */
+#define PCTRL_ADDR	0xfffff207
+#define PCTRL		BYTE_REF(PCTRL_ADDR)
+
+#define PCTRL_WIDTH_MASK	0x1f	/* CPU Clock bursts width */
+#define PCTRL_WIDTH_SHIFT	0
+#define PCTRL_STOP		0x40	/* Enter power-save mode immediately */ 
+#define PCTRL_PCEN		0x80	/* Power Control Enable */
+
+/**********
+ *
+ * 0xFFFFF3xx -- Interrupt Controller
+ *
+ **********/
+
+/* 
+ * Interrupt Vector Register
+ */
+#define IVR_ADDR	0xfffff300
+#define IVR		BYTE_REF(IVR_ADDR)
+
+#define IVR_VECTOR_MASK 0xF8
+
+/*
+ * Interrupt control Register
+ */
+#define ICR_ADRR	0xfffff302
+#define ICR		WORD_REF(ICR_ADDR)
+
+#define ICR_ET6		0x0100	/* Edge Trigger Select for IRQ6 */
+#define ICR_ET3		0x0200	/* Edge Trigger Select for IRQ3 */
+#define ICR_ET2		0x0400	/* Edge Trigger Select for IRQ2 */
+#define ICR_ET1		0x0800	/* Edge Trigger Select for IRQ1 */
+#define ICR_POL6	0x1000	/* Polarity Control for IRQ6 */
+#define ICR_POL3	0x2000	/* Polarity Control for IRQ3 */
+#define ICR_POL2	0x4000	/* Polarity Control for IRQ2 */
+#define ICR_POL1	0x8000	/* Polarity Control for IRQ1 */
+
+/*
+ * Interrupt Mask Register
+ */
+#define IMR_ADDR	0xfffff304
+#define IMR		LONG_REF(IMR_ADDR)
+ 
+/*
+ * Define the names for bit positions first. This is useful for
+ * request_irq
+ */
+#define SPIM_IRQ_NUM	0	/* SPI Master interrupt */
+#define	TMR2_IRQ_NUM	1	/* Timer 2 interrupt */
+#define UART_IRQ_NUM	2	/* UART interrupt */	
+#define	WDT_IRQ_NUM	3	/* Watchdog Timer interrupt */
+#define RTC_IRQ_NUM	4	/* RTC interrupt */
+#define	KB_IRQ_NUM	6	/* Keyboard Interrupt */
+#define PWM_IRQ_NUM	7	/* Pulse-Width Modulator int. */
+#define	INT0_IRQ_NUM	8	/* External INT0 */
+#define	INT1_IRQ_NUM	9	/* External INT1 */
+#define	INT2_IRQ_NUM	10	/* External INT2 */
+#define	INT3_IRQ_NUM	11	/* External INT3 */
+#define	INT4_IRQ_NUM	12	/* External INT4 */
+#define	INT5_IRQ_NUM	13	/* External INT5 */
+#define	INT6_IRQ_NUM	14	/* External INT6 */
+#define	INT7_IRQ_NUM	15	/* External INT7 */
+#define IRQ1_IRQ_NUM	16	/* IRQ1 */
+#define IRQ2_IRQ_NUM	17	/* IRQ2 */
+#define IRQ3_IRQ_NUM	18	/* IRQ3 */
+#define IRQ6_IRQ_NUM	19	/* IRQ6 */
+#define PEN_IRQ_NUM	20	/* Pen Interrupt */
+#define SPIS_IRQ_NUM	21	/* SPI Slave Interrupt */
+#define TMR1_IRQ_NUM	22	/* Timer 1 interrupt */
+#define IRQ7_IRQ_NUM	23	/* IRQ7 */
+
+/* '328-compatible definitions */
+#define SPI_IRQ_NUM	SPIM_IRQ_NUM
+#define TMR_IRQ_NUM	TMR1_IRQ_NUM
+ 
+/*
+ * Here go the bitmasks themselves
+ */
+#define IMR_MSPIM 	(1 << SPIM _IRQ_NUM)	/* Mask SPI Master interrupt */
+#define	IMR_MTMR2	(1 << TMR2_IRQ_NUM)	/* Mask Timer 2 interrupt */
+#define IMR_MUART	(1 << UART_IRQ_NUM)	/* Mask UART interrupt */	
+#define	IMR_MWDT	(1 << WDT_IRQ_NUM)	/* Mask Watchdog Timer interrupt */
+#define IMR_MRTC	(1 << RTC_IRQ_NUM)	/* Mask RTC interrupt */
+#define	IMR_MKB		(1 << KB_IRQ_NUM)	/* Mask Keyboard Interrupt */
+#define IMR_MPWM	(1 << PWM_IRQ_NUM)	/* Mask Pulse-Width Modulator int. */
+#define	IMR_MINT0	(1 << INT0_IRQ_NUM)	/* Mask External INT0 */
+#define	IMR_MINT1	(1 << INT1_IRQ_NUM)	/* Mask External INT1 */
+#define	IMR_MINT2	(1 << INT2_IRQ_NUM)	/* Mask External INT2 */
+#define	IMR_MINT3	(1 << INT3_IRQ_NUM)	/* Mask External INT3 */
+#define	IMR_MINT4	(1 << INT4_IRQ_NUM)	/* Mask External INT4 */
+#define	IMR_MINT5	(1 << INT5_IRQ_NUM)	/* Mask External INT5 */
+#define	IMR_MINT6	(1 << INT6_IRQ_NUM)	/* Mask External INT6 */
+#define	IMR_MINT7	(1 << INT7_IRQ_NUM)	/* Mask External INT7 */
+#define IMR_MIRQ1	(1 << IRQ1_IRQ_NUM)	/* Mask IRQ1 */
+#define IMR_MIRQ2	(1 << IRQ2_IRQ_NUM)	/* Mask IRQ2 */
+#define IMR_MIRQ3	(1 << IRQ3_IRQ_NUM)	/* Mask IRQ3 */
+#define IMR_MIRQ6	(1 << IRQ6_IRQ_NUM)	/* Mask IRQ6 */
+#define IMR_MPEN	(1 << PEN_IRQ_NUM)	/* Mask Pen Interrupt */
+#define IMR_MSPIS	(1 << SPIS_IRQ_NUM)	/* Mask SPI Slave Interrupt */
+#define IMR_MTMR1	(1 << TMR1_IRQ_NUM)	/* Mask Timer 1 interrupt */
+#define IMR_MIRQ7	(1 << IRQ7_IRQ_NUM)	/* Mask IRQ7 */
+
+/* 'EZ328-compatible definitions */
+#define IMR_MSPI	IMR_MSPIM
+#define IMR_MTMR	IMR_MTMR1
+
+/* 
+ * Interrupt Wake-Up Enable Register
+ */
+#define IWR_ADDR	0xfffff308
+#define IWR		LONG_REF(IWR_ADDR)
+
+#define IWR_SPIM 	(1 << SPIM _IRQ_NUM)	/* SPI Master interrupt */
+#define	IWR_TMR2	(1 << TMR2_IRQ_NUM)	/* Timer 2 interrupt */
+#define IWR_UART	(1 << UART_IRQ_NUM)	/* UART interrupt */	
+#define	IWR_WDT		(1 << WDT_IRQ_NUM)	/* Watchdog Timer interrupt */
+#define IWR_RTC		(1 << RTC_IRQ_NUM)	/* RTC interrupt */
+#define	IWR_KB		(1 << KB_IRQ_NUM)	/* Keyboard Interrupt */
+#define IWR_PWM		(1 << PWM_IRQ_NUM)	/* Pulse-Width Modulator int. */
+#define	IWR_INT0	(1 << INT0_IRQ_NUM)	/* External INT0 */
+#define	IWR_INT1	(1 << INT1_IRQ_NUM)	/* External INT1 */
+#define	IWR_INT2	(1 << INT2_IRQ_NUM)	/* External INT2 */
+#define	IWR_INT3	(1 << INT3_IRQ_NUM)	/* External INT3 */
+#define	IWR_INT4	(1 << INT4_IRQ_NUM)	/* External INT4 */
+#define	IWR_INT5	(1 << INT5_IRQ_NUM)	/* External INT5 */
+#define	IWR_INT6	(1 << INT6_IRQ_NUM)	/* External INT6 */
+#define	IWR_INT7	(1 << INT7_IRQ_NUM)	/* External INT7 */
+#define IWR_IRQ1	(1 << IRQ1_IRQ_NUM)	/* IRQ1 */
+#define IWR_IRQ2	(1 << IRQ2_IRQ_NUM)	/* IRQ2 */
+#define IWR_IRQ3	(1 << IRQ3_IRQ_NUM)	/* IRQ3 */
+#define IWR_IRQ6	(1 << IRQ6_IRQ_NUM)	/* IRQ6 */
+#define IWR_PEN		(1 << PEN_IRQ_NUM)	/* Pen Interrupt */
+#define IWR_SPIS	(1 << SPIS_IRQ_NUM)	/* SPI Slave Interrupt */
+#define IWR_TMR1	(1 << TMR1_IRQ_NUM)	/* Timer 1 interrupt */
+#define IWR_IRQ7	(1 << IRQ7_IRQ_NUM)	/* IRQ7 */
+
+/* 
+ * Interrupt Status Register 
+ */
+#define ISR_ADDR	0xfffff30c
+#define ISR		LONG_REF(ISR_ADDR)
+
+#define ISR_SPIM 	(1 << SPIM _IRQ_NUM)	/* SPI Master interrupt */
+#define	ISR_TMR2	(1 << TMR2_IRQ_NUM)	/* Timer 2 interrupt */
+#define ISR_UART	(1 << UART_IRQ_NUM)	/* UART interrupt */	
+#define	ISR_WDT		(1 << WDT_IRQ_NUM)	/* Watchdog Timer interrupt */
+#define ISR_RTC		(1 << RTC_IRQ_NUM)	/* RTC interrupt */
+#define	ISR_KB		(1 << KB_IRQ_NUM)	/* Keyboard Interrupt */
+#define ISR_PWM		(1 << PWM_IRQ_NUM)	/* Pulse-Width Modulator int. */
+#define	ISR_INT0	(1 << INT0_IRQ_NUM)	/* External INT0 */
+#define	ISR_INT1	(1 << INT1_IRQ_NUM)	/* External INT1 */
+#define	ISR_INT2	(1 << INT2_IRQ_NUM)	/* External INT2 */
+#define	ISR_INT3	(1 << INT3_IRQ_NUM)	/* External INT3 */
+#define	ISR_INT4	(1 << INT4_IRQ_NUM)	/* External INT4 */
+#define	ISR_INT5	(1 << INT5_IRQ_NUM)	/* External INT5 */
+#define	ISR_INT6	(1 << INT6_IRQ_NUM)	/* External INT6 */
+#define	ISR_INT7	(1 << INT7_IRQ_NUM)	/* External INT7 */
+#define ISR_IRQ1	(1 << IRQ1_IRQ_NUM)	/* IRQ1 */
+#define ISR_IRQ2	(1 << IRQ2_IRQ_NUM)	/* IRQ2 */
+#define ISR_IRQ3	(1 << IRQ3_IRQ_NUM)	/* IRQ3 */
+#define ISR_IRQ6	(1 << IRQ6_IRQ_NUM)	/* IRQ6 */
+#define ISR_PEN		(1 << PEN_IRQ_NUM)	/* Pen Interrupt */
+#define ISR_SPIS	(1 << SPIS_IRQ_NUM)	/* SPI Slave Interrupt */
+#define ISR_TMR1	(1 << TMR1_IRQ_NUM)	/* Timer 1 interrupt */
+#define ISR_IRQ7	(1 << IRQ7_IRQ_NUM)	/* IRQ7 */
+
+/* 'EZ328-compatible definitions */
+#define ISR_SPI	ISR_SPIM
+#define ISR_TMR	ISR_TMR1
+
+/* 
+ * Interrupt Pending Register 
+ */
+#define IPR_ADDR	0xfffff310
+#define IPR		LONG_REF(IPR_ADDR)
+
+#define IPR_SPIM 	(1 << SPIM _IRQ_NUM)	/* SPI Master interrupt */
+#define	IPR_TMR2	(1 << TMR2_IRQ_NUM)	/* Timer 2 interrupt */
+#define IPR_UART	(1 << UART_IRQ_NUM)	/* UART interrupt */	
+#define	IPR_WDT		(1 << WDT_IRQ_NUM)	/* Watchdog Timer interrupt */
+#define IPR_RTC		(1 << RTC_IRQ_NUM)	/* RTC interrupt */
+#define	IPR_KB		(1 << KB_IRQ_NUM)	/* Keyboard Interrupt */
+#define IPR_PWM		(1 << PWM_IRQ_NUM)	/* Pulse-Width Modulator int. */
+#define	IPR_INT0	(1 << INT0_IRQ_NUM)	/* External INT0 */
+#define	IPR_INT1	(1 << INT1_IRQ_NUM)	/* External INT1 */
+#define	IPR_INT2	(1 << INT2_IRQ_NUM)	/* External INT2 */
+#define	IPR_INT3	(1 << INT3_IRQ_NUM)	/* External INT3 */
+#define	IPR_INT4	(1 << INT4_IRQ_NUM)	/* External INT4 */
+#define	IPR_INT5	(1 << INT5_IRQ_NUM)	/* External INT5 */
+#define	IPR_INT6	(1 << INT6_IRQ_NUM)	/* External INT6 */
+#define	IPR_INT7	(1 << INT7_IRQ_NUM)	/* External INT7 */
+#define IPR_IRQ1	(1 << IRQ1_IRQ_NUM)	/* IRQ1 */
+#define IPR_IRQ2	(1 << IRQ2_IRQ_NUM)	/* IRQ2 */
+#define IPR_IRQ3	(1 << IRQ3_IRQ_NUM)	/* IRQ3 */
+#define IPR_IRQ6	(1 << IRQ6_IRQ_NUM)	/* IRQ6 */
+#define IPR_PEN		(1 << PEN_IRQ_NUM)	/* Pen Interrupt */
+#define IPR_SPIS	(1 << SPIS_IRQ_NUM)	/* SPI Slave Interrupt */
+#define IPR_TMR1	(1 << TMR1_IRQ_NUM)	/* Timer 1 interrupt */
+#define IPR_IRQ7	(1 << IRQ7_IRQ_NUM)	/* IRQ7 */
+
+/* 'EZ328-compatible definitions */
+#define IPR_SPI	IPR_SPIM
+#define IPR_TMR	IPR_TMR1
+
+/**********
+ *
+ * 0xFFFFF4xx -- Parallel Ports
+ *
+ **********/
+
+/*
+ * Port A
+ */
+#define PADIR_ADDR	0xfffff400		/* Port A direction reg */
+#define PADATA_ADDR	0xfffff401		/* Port A data register */
+#define PASEL_ADDR	0xfffff403		/* Port A Select register */
+
+#define PADIR		BYTE_REF(PADIR_ADDR)
+#define PADATA		BYTE_REF(PADATA_ADDR)
+#define PASEL		BYTE_REF(PASEL_ADDR)
+
+#define PA(x)           (1 << (x))
+#define PA_A(x)		PA((x) - 16)	/* This is specific to PA only! */
+
+#define PA_A16		PA(0)		/* Use A16 as PA(0) */
+#define PA_A17		PA(1)		/* Use A17 as PA(1) */
+#define PA_A18		PA(2)		/* Use A18 as PA(2) */
+#define PA_A19		PA(3)		/* Use A19 as PA(3) */
+#define PA_A20		PA(4)		/* Use A20 as PA(4) */
+#define PA_A21		PA(5)		/* Use A21 as PA(5) */
+#define PA_A22		PA(6)		/* Use A22 as PA(6) */
+#define PA_A23		PA(7)		/* Use A23 as PA(7) */
+
+/* 
+ * Port B
+ */
+#define PBDIR_ADDR	0xfffff408		/* Port B direction reg */
+#define PBDATA_ADDR	0xfffff409		/* Port B data register */
+#define PBSEL_ADDR	0xfffff40b		/* Port B Select Register */
+
+#define PBDIR		BYTE_REF(PBDIR_ADDR)
+#define PBDATA		BYTE_REF(PBDATA_ADDR)
+#define PBSEL		BYTE_REF(PBSEL_ADDR)
+
+#define PB(x)           (1 << (x))
+#define PB_D(x)		PB(x)		/* This is specific to port B only */
+
+#define PB_D0		PB(0)		/* Use D0 as PB(0) */
+#define PB_D1		PB(1)		/* Use D1 as PB(1) */
+#define PB_D2		PB(2)		/* Use D2 as PB(2) */
+#define PB_D3		PB(3)		/* Use D3 as PB(3) */
+#define PB_D4		PB(4)		/* Use D4 as PB(4) */
+#define PB_D5		PB(5)		/* Use D5 as PB(5) */
+#define PB_D6		PB(6)		/* Use D6 as PB(6) */
+#define PB_D7		PB(7)		/* Use D7 as PB(7) */
+
+/* 
+ * Port C
+ */
+#define PCDIR_ADDR	0xfffff410		/* Port C direction reg */
+#define PCDATA_ADDR	0xfffff411		/* Port C data register */
+#define PCSEL_ADDR	0xfffff413		/* Port C Select Register */
+
+#define PCDIR		BYTE_REF(PCDIR_ADDR)
+#define PCDATA		BYTE_REF(PCDATA_ADDR)
+#define PCSEL		BYTE_REF(PCSEL_ADDR)
+
+#define PC(x)           (1 << (x))
+
+#define PC_WE		PC(6)		/* Use WE    as PC(6) */
+#define PC_DTACK	PC(5)		/* Use DTACK as PC(5) */
+#define PC_IRQ7		PC(4)		/* Use IRQ7  as PC(4) */
+#define PC_LDS		PC(2)		/* Use LDS   as PC(2) */
+#define PC_UDS		PC(1)		/* Use UDS   as PC(1) */
+#define PC_MOCLK	PC(0)		/* Use MOCLK as PC(0) */
+
+/* 
+ * Port D
+ */
+#define PDDIR_ADDR	0xfffff418		/* Port D direction reg */
+#define PDDATA_ADDR	0xfffff419		/* Port D data register */
+#define PDPUEN_ADDR	0xfffff41a		/* Port D Pull-Up enable reg */
+#define PDPOL_ADDR	0xfffff41c		/* Port D Polarity Register */
+#define PDIRQEN_ADDR	0xfffff41d		/* Port D IRQ enable register */
+#define	PDIQEG_ADDR	0xfffff41f		/* Port D IRQ Edge Register */
+
+#define PDDIR		BYTE_REF(PDDIR_ADDR)
+#define PDDATA		BYTE_REF(PDDATA_ADDR)
+#define PDPUEN		BYTE_REF(PDPUEN_ADDR)
+#define	PDPOL		BYTE_REF(PDPOL_ADDR)
+#define PDIRQEN		BYTE_REF(PDIRQEN_ADDR)
+#define PDIQEG		BYTE_REF(PDIQEG_ADDR)
+
+#define PD(x)           (1 << (x))
+#define PD_KB(x)	PD(x)		/* This is specific for Port D only */
+
+#define PD_KB0		PD(0)	/* Use KB0 as PD(0) */
+#define PD_KB1		PD(1)	/* Use KB1 as PD(1) */
+#define PD_KB2		PD(2)	/* Use KB2 as PD(2) */
+#define PD_KB3		PD(3)	/* Use KB3 as PD(3) */
+#define PD_KB4		PD(4)	/* Use KB4 as PD(4) */
+#define PD_KB5		PD(5)	/* Use KB5 as PD(5) */
+#define PD_KB6		PD(6)	/* Use KB6 as PD(6) */
+#define PD_KB7		PD(7)	/* Use KB7 as PD(7) */
+
+/* 
+ * Port E
+ */
+#define PEDIR_ADDR	0xfffff420		/* Port E direction reg */
+#define PEDATA_ADDR	0xfffff421		/* Port E data register */
+#define PEPUEN_ADDR	0xfffff422		/* Port E Pull-Up enable reg */
+#define PESEL_ADDR	0xfffff423		/* Port E Select Register */
+
+#define PEDIR		BYTE_REF(PEDIR_ADDR)
+#define PEDATA		BYTE_REF(PEDATA_ADDR)
+#define PEPUEN		BYTE_REF(PEPUEN_ADDR)
+#define PESEL		BYTE_REF(PESEL_ADDR)
+
+#define PE(x)           (1 << (x))
+
+#define PE_CSA1		PE(1)	/* Use CSA1 as PE(1) */
+#define PE_CSA2		PE(2)	/* Use CSA2 as PE(2) */
+#define PE_CSA3		PE(3)	/* Use CSA3 as PE(3) */
+#define PE_CSB0		PE(4)	/* Use CSB0 as PE(4) */
+#define PE_CSB1		PE(5)	/* Use CSB1 as PE(5) */
+#define PE_CSB2		PE(6)	/* Use CSB2 as PE(6) */
+#define PE_CSB3		PE(7)	/* Use CSB3 as PE(7) */
+
+/* 
+ * Port F
+ */
+#define PFDIR_ADDR	0xfffff428		/* Port F direction reg */
+#define PFDATA_ADDR	0xfffff429		/* Port F data register */
+#define PFPUEN_ADDR	0xfffff42a		/* Port F Pull-Up enable reg */
+#define PFSEL_ADDR	0xfffff42b		/* Port F Select Register */
+
+#define PFDIR		BYTE_REF(PFDIR_ADDR)
+#define PFDATA		BYTE_REF(PFDATA_ADDR)
+#define PFPUEN		BYTE_REF(PFPUEN_ADDR)
+#define PFSEL		BYTE_REF(PFSEL_ADDR)
+
+#define PF(x)           (1 << (x))
+#define PF_A(x)		PF((x) - 24)	/* This is Port F specific only */
+
+#define PF_A24		PF(0)	/* Use A24 as PF(0) */
+#define PF_A25		PF(1)	/* Use A25 as PF(1) */
+#define PF_A26		PF(2)	/* Use A26 as PF(2) */
+#define PF_A27		PF(3)	/* Use A27 as PF(3) */
+#define PF_A28		PF(4)	/* Use A28 as PF(4) */
+#define PF_A29		PF(5)	/* Use A29 as PF(5) */
+#define PF_A30		PF(6)	/* Use A30 as PF(6) */
+#define PF_A31		PF(7)	/* Use A31 as PF(7) */
+
+/* 
+ * Port G
+ */
+#define PGDIR_ADDR	0xfffff430		/* Port G direction reg */
+#define PGDATA_ADDR	0xfffff431		/* Port G data register */
+#define PGPUEN_ADDR	0xfffff432		/* Port G Pull-Up enable reg */
+#define PGSEL_ADDR	0xfffff433		/* Port G Select Register */
+
+#define PGDIR		BYTE_REF(PGDIR_ADDR)
+#define PGDATA		BYTE_REF(PGDATA_ADDR)
+#define PGPUEN		BYTE_REF(PGPUEN_ADDR)
+#define PGSEL		BYTE_REF(PGSEL_ADDR)
+
+#define PG(x)           (1 << (x))
+
+#define PG_UART_TXD	PG(0)	/* Use UART_TXD as PG(0) */
+#define PG_UART_RXD	PG(1)	/* Use UART_RXD as PG(1) */
+#define PG_PWMOUT	PG(2)	/* Use PWMOUT   as PG(2) */
+#define PG_TOUT2	PG(3)   /* Use TOUT2    as PG(3) */
+#define PG_TIN2		PG(4)	/* Use TIN2     as PG(4) */
+#define PG_TOUT1	PG(5)   /* Use TOUT1    as PG(5) */
+#define PG_TIN1		PG(6)	/* Use TIN1     as PG(6) */
+#define PG_RTCOUT	PG(7)	/* Use RTCOUT   as PG(7) */
+
+/* 
+ * Port J
+ */
+#define PJDIR_ADDR	0xfffff438		/* Port J direction reg */
+#define PJDATA_ADDR	0xfffff439		/* Port J data register */
+#define PJSEL_ADDR	0xfffff43b		/* Port J Select Register */
+
+#define PJDIR		BYTE_REF(PJDIR_ADDR)
+#define PJDATA		BYTE_REF(PJDATA_ADDR)
+#define PJSEL		BYTE_REF(PJSEL_ADDR)
+
+#define PJ(x)           (1 << (x)) 
+
+#define PJ_CSD3		PJ(7)	/* Use CSD3 as PJ(7) */
+
+/* 
+ * Port K
+ */
+#define PKDIR_ADDR	0xfffff440		/* Port K direction reg */
+#define PKDATA_ADDR	0xfffff441		/* Port K data register */
+#define PKPUEN_ADDR	0xfffff442		/* Port K Pull-Up enable reg */
+#define PKSEL_ADDR	0xfffff443		/* Port K Select Register */
+
+#define PKDIR		BYTE_REF(PKDIR_ADDR)
+#define PKDATA		BYTE_REF(PKDATA_ADDR)
+#define PKPUEN		BYTE_REF(PKPUEN_ADDR)
+#define PKSEL		BYTE_REF(PKSEL_ADDR)
+
+#define PK(x)           (1 << (x))
+
+/* 
+ * Port M
+ */
+#define PMDIR_ADDR	0xfffff438		/* Port M direction reg */
+#define PMDATA_ADDR	0xfffff439		/* Port M data register */
+#define PMPUEN_ADDR	0xfffff43a		/* Port M Pull-Up enable reg */
+#define PMSEL_ADDR	0xfffff43b		/* Port M Select Register */
+
+#define PMDIR		BYTE_REF(PMDIR_ADDR)
+#define PMDATA		BYTE_REF(PMDATA_ADDR)
+#define PMPUEN		BYTE_REF(PMPUEN_ADDR)
+#define PMSEL		BYTE_REF(PMSEL_ADDR)
+
+#define PM(x)           (1 << (x))
+
+/**********
+ *
+ * 0xFFFFF5xx -- Pulse-Width Modulator (PWM)
+ *
+ **********/
+
+/*
+ * PWM Control Register 
+ */
+#define PWMC_ADDR	0xfffff500
+#define PWMC		WORD_REF(PWMC_ADDR)
+
+#define PWMC_CLKSEL_MASK	0x0007	/* Clock Selection */
+#define PWMC_CLKSEL_SHIFT	0
+#define PWMC_PWMEN		0x0010	/* Enable PWM */
+#define PMNC_POL		0x0020	/* PWM Output Bit Polarity */
+#define PWMC_PIN		0x0080	/* Current PWM output pin status */
+#define PWMC_LOAD		0x0100	/* Force a new period */
+#define PWMC_IRQEN		0x4000	/* Interrupt Request Enable */
+#define PWMC_CLKSRC		0x8000	/* Clock Source Select */
+
+/* 'EZ328-compatible definitions */
+#define PWMC_EN	PWMC_PWMEN
+
+/*
+ * PWM Period Register
+ */
+#define PWMP_ADDR	0xfffff502
+#define PWMP		WORD_REF(PWMP_ADDR)
+
+/* 
+ * PWM Width Register 
+ */
+#define PWMW_ADDR	0xfffff504
+#define PWMW		WORD_REF(PWMW_ADDR)
+
+/*
+ * PWM Counter Register
+ */
+#define PWMCNT_ADDR	0xfffff506
+#define PWMCNT		WORD_REF(PWMCNT_ADDR)
+
+/**********
+ *
+ * 0xFFFFF6xx -- General-Purpose Timers
+ *
+ **********/
+
+/* 
+ * Timer Unit 1 and 2 Control Registers
+ */
+#define TCTL1_ADDR	0xfffff600
+#define TCTL1		WORD_REF(TCTL1_ADDR)
+#define TCTL2_ADDR	0xfffff60c
+#define TCTL2		WORD_REF(TCTL2_ADDR)
+
+#define	TCTL_TEN		0x0001	/* Timer Enable  */
+#define TCTL_CLKSOURCE_MASK 	0x000e	/* Clock Source: */
+#define   TCTL_CLKSOURCE_STOP	   0x0000	/* Stop count (disabled)    */
+#define   TCTL_CLKSOURCE_SYSCLK	   0x0002	/* SYSCLK to prescaler      */
+#define   TCTL_CLKSOURCE_SYSCLK_16 0x0004	/* SYSCLK/16 to prescaler   */
+#define   TCTL_CLKSOURCE_TIN	   0x0006	/* TIN to prescaler         */
+#define   TCTL_CLKSOURCE_32KHZ	   0x0008	/* 32kHz clock to prescaler */
+#define TCTL_IRQEN		0x0010	/* IRQ Enable    */
+#define TCTL_OM			0x0020	/* Output Mode   */
+#define TCTL_CAP_MASK		0x00c0	/* Capture Edge: */
+#define	  TCTL_CAP_RE		0x0040		/* Capture on rizing edge   */
+#define   TCTL_CAP_FE		0x0080		/* Capture on falling edge  */
+#define TCTL_FRR		0x0010	/* Free-Run Mode */
+
+/* 'EZ328-compatible definitions */
+#define TCTL_ADDR	TCTL1_ADDR
+#define TCTL		TCTL1
+
+/*
+ * Timer Unit 1 and 2 Prescaler Registers
+ */
+#define TPRER1_ADDR	0xfffff602
+#define TPRER1		WORD_REF(TPRER1_ADDR)
+#define TPRER2_ADDR	0xfffff60e
+#define TPRER2		WORD_REF(TPRER2_ADDR)
+
+/* 'EZ328-compatible definitions */
+#define TPRER_ADDR	TPRER1_ADDR
+#define TPRER		TPRER1
+
+/*
+ * Timer Unit 1 and 2 Compare Registers
+ */
+#define TCMP1_ADDR	0xfffff604
+#define TCMP1		WORD_REF(TCMP1_ADDR)
+#define TCMP2_ADDR	0xfffff610
+#define TCMP2		WORD_REF(TCMP2_ADDR)
+
+/* 'EZ328-compatible definitions */
+#define TCMP_ADDR	TCMP1_ADDR
+#define TCMP		TCMP1
+
+/*
+ * Timer Unit 1 and 2 Capture Registers
+ */
+#define TCR1_ADDR	0xfffff606
+#define TCR1		WORD_REF(TCR1_ADDR)
+#define TCR2_ADDR	0xfffff612
+#define TCR2		WORD_REF(TCR2_ADDR)
+
+/* 'EZ328-compatible definitions */
+#define TCR_ADDR	TCR1_ADDR
+#define TCR		TCR1
+
+/*
+ * Timer Unit 1 and 2 Counter Registers
+ */
+#define TCN1_ADDR	0xfffff608
+#define TCN1		WORD_REF(TCN1_ADDR)
+#define TCN2_ADDR	0xfffff614
+#define TCN2		WORD_REF(TCN2_ADDR)
+
+/* 'EZ328-compatible definitions */
+#define TCN_ADDR	TCN1_ADDR
+#define TCN		TCN
+
+/*
+ * Timer Unit 1 and 2 Status Registers
+ */
+#define TSTAT1_ADDR	0xfffff60a
+#define TSTAT1		WORD_REF(TSTAT1_ADDR)
+#define TSTAT2_ADDR	0xfffff616
+#define TSTAT2		WORD_REF(TSTAT2_ADDR)
+
+#define TSTAT_COMP	0x0001		/* Compare Event occurred */
+#define TSTAT_CAPT	0x0001		/* Capture Event occurred */
+
+/* 'EZ328-compatible definitions */
+#define TSTAT_ADDR	TSTAT1_ADDR
+#define TSTAT		TSTAT1
+
+/*
+ * Watchdog Compare Register 
+ */
+#define WRR_ADDR	0xfffff61a
+#define WRR		WORD_REF(WRR_ADDR)
+
+/*
+ * Watchdog Counter Register 
+ */
+#define WCN_ADDR	0xfffff61c
+#define WCN		WORD_REF(WCN_ADDR)
+
+/*
+ * Watchdog Control and Status Register
+ */
+#define WCSR_ADDR	0xfffff618
+#define WCSR		WORD_REF(WCSR_ADDR)
+
+#define WCSR_WDEN	0x0001	/* Watchdog Enable */
+#define WCSR_FI		0x0002	/* Forced Interrupt (instead of SW reset)*/
+#define WCSR_WRST	0x0004	/* Watchdog Reset */
+
+/**********
+ *
+ * 0xFFFFF7xx -- Serial Periferial Interface Slave (SPIS)
+ *
+ **********/
+
+/*
+ * SPI Slave Register
+ */
+#define SPISR_ADDR	0xfffff700
+#define SPISR		WORD_REF(SPISR_ADDR)
+
+#define SPISR_DATA_ADDR	0xfffff701
+#define SPISR_DATA	BYTE_REF(SPISR_DATA_ADDR)
+
+#define SPISR_DATA_MASK	 0x00ff	/* Shifted data from the external device */
+#define SPISR_DATA_SHIFT 0
+#define SPISR_SPISEN	 0x0100	/* SPIS module enable */
+#define SPISR_POL	 0x0200	/* SPSCLK polarity control */
+#define SPISR_PHA	 0x0400	/* Phase relationship between SPSCLK & SPSRxD */
+#define SPISR_OVWR	 0x0800	/* Data buffer has been overwritten */
+#define SPISR_DATARDY	 0x1000	/* Data ready */
+#define SPISR_ENPOL	 0x2000	/* Enable Polarity */
+#define SPISR_IRQEN	 0x4000	/* SPIS IRQ Enable */
+#define SPISR_SPISIRQ	 0x8000	/* SPIS IRQ posted */
+
+/**********
+ *
+ * 0xFFFFF8xx -- Serial Periferial Interface Master (SPIM)
+ *
+ **********/
+
+/*
+ * SPIM Data Register
+ */
+#define SPIMDATA_ADDR	0xfffff800
+#define SPIMDATA	WORD_REF(SPIMDATA_ADDR)
+
+/*
+ * SPIM Control/Status Register
+ */
+#define SPIMCONT_ADDR	0xfffff802
+#define SPIMCONT	WORD_REF(SPIMCONT_ADDR)
+
+#define SPIMCONT_BIT_COUNT_MASK	 0x000f	/* Transfer Length in Bytes */
+#define SPIMCONT_BIT_COUNT_SHIFT 0
+#define SPIMCONT_POL		 0x0010	/* SPMCLK Signel Polarity */
+#define	SPIMCONT_PHA		 0x0020	/* Clock/Data phase relationship */
+#define SPIMCONT_IRQEN		 0x0040 /* IRQ Enable */
+#define SPIMCONT_SPIMIRQ	 0x0080	/* Interrupt Request */
+#define SPIMCONT_XCH		 0x0100	/* Exchange */
+#define SPIMCONT_RSPIMEN	 0x0200	/* Enable SPIM */
+#define SPIMCONT_DATA_RATE_MASK	 0xe000	/* SPIM Data Rate */
+#define SPIMCONT_DATA_RATE_SHIFT 13
+
+/* 'EZ328-compatible definitions */
+#define SPIMCONT_IRQ	SPIMCONT_SPIMIRQ
+#define SPIMCONT_ENABLE	SPIMCONT_SPIMEN
+/**********
+ *
+ * 0xFFFFF9xx -- UART
+ *
+ **********/
+
+/*
+ * UART Status/Control Register
+ */
+#define USTCNT_ADDR	0xfffff900
+#define USTCNT		WORD_REF(USTCNT_ADDR)
+
+#define USTCNT_TXAVAILEN	0x0001	/* Transmitter Available Int Enable */
+#define USTCNT_TXHALFEN		0x0002	/* Transmitter Half Empty Int Enable */
+#define USTCNT_TXEMPTYEN	0x0004	/* Transmitter Empty Int Enable */
+#define USTCNT_RXREADYEN	0x0008	/* Receiver Ready Interrupt Enable */
+#define USTCNT_RXHALFEN		0x0010	/* Receiver Half-Full Int Enable */
+#define USTCNT_RXFULLEN		0x0020	/* Receiver Full Interrupt Enable */
+#define USTCNT_CTSDELTAEN	0x0040	/* CTS Delta Interrupt Enable */
+#define USTCNT_GPIODELTAEN	0x0080	/* Old Data Interrupt Enable */
+#define USTCNT_8_7		0x0100	/* Eight or seven-bit transmission */
+#define USTCNT_STOP		0x0200	/* Stop bit transmission */
+#define USTCNT_ODD_EVEN		0x0400	/* Odd Parity */
+#define	USTCNT_PARITYEN		0x0800	/* Parity Enable */
+#define USTCNT_CLKMODE		0x1000	/* Clock Mode Select */
+#define	USTCNT_TXEN		0x2000	/* Transmitter Enable */
+#define USTCNT_RXEN		0x4000	/* Receiver Enable */
+#define USTCNT_UARTEN		0x8000	/* UART Enable */
+
+/* 'EZ328-compatible definitions */
+#define USTCNT_TXAE	USTCNT_TXAVAILEN 
+#define USTCNT_TXHE	USTCNT_TXHALFEN
+#define USTCNT_TXEE	USTCNT_TXEMPTYEN
+#define USTCNT_RXRE	USTCNT_RXREADYEN
+#define USTCNT_RXHE	USTCNT_RXHALFEN
+#define USTCNT_RXFE	USTCNT_RXFULLEN
+#define USTCNT_CTSD	USTCNT_CTSDELTAEN
+#define USTCNT_ODD	USTCNT_ODD_EVEN
+#define USTCNT_PEN	USTCNT_PARITYEN
+#define USTCNT_CLKM	USTCNT_CLKMODE
+#define USTCNT_UEN	USTCNT_UARTEN
+
+/*
+ * UART Baud Control Register
+ */
+#define UBAUD_ADDR	0xfffff902
+#define UBAUD		WORD_REF(UBAUD_ADDR)
+
+#define UBAUD_PRESCALER_MASK	0x003f	/* Actual divisor is 65 - PRESCALER */
+#define UBAUD_PRESCALER_SHIFT	0
+#define UBAUD_DIVIDE_MASK	0x0700	/* Baud Rate freq. divizor */
+#define UBAUD_DIVIDE_SHIFT	8
+#define UBAUD_BAUD_SRC		0x0800	/* Baud Rate Source */
+#define UBAUD_GPIOSRC		0x1000	/* GPIO source */
+#define UBAUD_GPIODIR		0x2000	/* GPIO Direction */
+#define UBAUD_GPIO		0x4000	/* Current GPIO pin status */
+#define UBAUD_GPIODELTA		0x8000	/* GPIO pin value changed */
+
+/*
+ * UART Receiver Register 
+ */
+#define URX_ADDR	0xfffff904
+#define URX		WORD_REF(URX_ADDR)
+
+#define URX_RXDATA_ADDR	0xfffff905
+#define URX_RXDATA	BYTE_REF(URX_RXDATA_ADDR)
+
+#define URX_RXDATA_MASK	 0x00ff	/* Received data */
+#define URX_RXDATA_SHIFT 0
+#define URX_PARITY_ERROR 0x0100	/* Parity Error */
+#define URX_BREAK	 0x0200	/* Break Detected */
+#define URX_FRAME_ERROR	 0x0400	/* Framing Error */
+#define URX_OVRUN	 0x0800	/* Serial Overrun */
+#define URX_DATA_READY	 0x2000	/* Data Ready (FIFO not empty) */
+#define URX_FIFO_HALF	 0x4000 /* FIFO is Half-Full */
+#define URX_FIFO_FULL	 0x8000	/* FIFO is Full */
+
+/*
+ * UART Transmitter Register 
+ */
+#define UTX_ADDR	0xfffff906
+#define UTX		WORD_REF(UTX_ADDR)
+
+#define UTX_TXDATA_ADDR	0xfffff907
+#define UTX_TXDATA	BYTE_REF(UTX_TXDATA_ADDR)
+
+#define UTX_TXDATA_MASK	 0x00ff	/* Data to be transmitted */
+#define UTX_TXDATA_SHIFT 0
+#define UTX_CTS_DELTA	 0x0100	/* CTS changed */
+#define UTX_CTS_STATUS	 0x0200	/* CTS State */
+#define	UTX_IGNORE_CTS	 0x0800	/* Ignore CTS */
+#define UTX_SEND_BREAK	 0x1000	/* Send a BREAK */
+#define UTX_TX_AVAIL	 0x2000	/* Transmit FIFO has a slot available */
+#define UTX_FIFO_HALF	 0x4000	/* Transmit FIFO is half empty */
+#define UTX_FIFO_EMPTY	 0x8000	/* Transmit FIFO is empty */
+
+/* 'EZ328-compatible definitions */
+#define UTX_CTS_STAT	UTX_CTS_STATUS
+#define UTX_NOCTS	UTX_IGNORE_CTS
+
+/*
+ * UART Miscellaneous Register 
+ */
+#define UMISC_ADDR	0xfffff908
+#define UMISC		WORD_REF(UMISC_ADDR)
+
+#define UMISC_TX_POL	 0x0004	/* Transmit Polarity */
+#define UMISC_RX_POL	 0x0008	/* Receive Polarity */
+#define UMISC_IRDA_LOOP	 0x0010	/* IrDA Loopback Enable */
+#define UMISC_IRDA_EN	 0x0020	/* Infra-Red Enable */
+#define UMISC_RTS	 0x0040	/* Set RTS status */
+#define UMISC_RTSCONT	 0x0080	/* Choose RTS control */
+#define UMISC_LOOP	 0x1000	/* Serial Loopback Enable */
+#define UMISC_FORCE_PERR 0x2000	/* Force Parity Error */
+#define UMISC_CLKSRC	 0x4000	/* Clock Source */
+
+
+/* generalization of uart control registers to support multiple ports: */
+typedef volatile struct {
+  volatile unsigned short int ustcnt;
+  volatile unsigned short int ubaud;
+  union {
+    volatile unsigned short int w;
+    struct {
+      volatile unsigned char status;
+      volatile unsigned char rxdata;
+    } b;
+  } urx;
+  union {
+    volatile unsigned short int w;
+    struct {
+      volatile unsigned char status;
+      volatile unsigned char txdata;
+    } b;
+  } utx;
+  volatile unsigned short int umisc;
+  volatile unsigned short int pad1;
+  volatile unsigned short int pad2;
+  volatile unsigned short int pad3;
+} m68328_uart __attribute__((packed));
+
+
+/**********
+ *
+ * 0xFFFFFAxx -- LCD Controller
+ *
+ **********/
+
+/*
+ * LCD Screen Starting Address Register 
+ */
+#define LSSA_ADDR	0xfffffa00
+#define LSSA		LONG_REF(LSSA_ADDR)
+
+#define LSSA_SSA_MASK	0xfffffffe	/* Bit 0 is reserved */
+
+/*
+ * LCD Virtual Page Width Register 
+ */
+#define LVPW_ADDR	0xfffffa05
+#define LVPW		BYTE_REF(LVPW_ADDR)
+
+/*
+ * LCD Screen Width Register (not compatible with 'EZ328 !!!)
+ */
+#define LXMAX_ADDR	0xfffffa08
+#define LXMAX		WORD_REF(LXMAX_ADDR)
+
+#define LXMAX_XM_MASK	0x02ff		/* Bits 0-3 are reserved */
+
+/*
+ * LCD Screen Height Register
+ */
+#define LYMAX_ADDR	0xfffffa0a
+#define LYMAX		WORD_REF(LYMAX_ADDR)
+
+#define LYMAX_YM_MASK	0x02ff		/* Bits 10-15 are reserved */
+
+/*
+ * LCD Cursor X Position Register
+ */
+#define LCXP_ADDR	0xfffffa18
+#define LCXP		WORD_REF(LCXP_ADDR)
+
+#define LCXP_CC_MASK	0xc000		/* Cursor Control */
+#define   LCXP_CC_TRAMSPARENT	0x0000
+#define   LCXP_CC_BLACK		0x4000
+#define   LCXP_CC_REVERSED	0x8000
+#define   LCXP_CC_WHITE		0xc000
+#define LCXP_CXP_MASK	0x02ff		/* Cursor X position */
+
+/*
+ * LCD Cursor Y Position Register
+ */
+#define LCYP_ADDR	0xfffffa1a
+#define LCYP		WORD_REF(LCYP_ADDR)
+
+#define LCYP_CYP_MASK	0x01ff		/* Cursor Y Position */
+
+/*
+ * LCD Cursor Width and Heigth Register
+ */
+#define LCWCH_ADDR	0xfffffa1c
+#define LCWCH		WORD_REF(LCWCH_ADDR)
+
+#define LCWCH_CH_MASK	0x001f		/* Cursor Height */
+#define LCWCH_CH_SHIFT	0
+#define LCWCH_CW_MASK	0x1f00		/* Cursor Width */
+#define LCWCH_CW_SHIFT	8
+
+/*
+ * LCD Blink Control Register
+ */
+#define LBLKC_ADDR	0xfffffa1f
+#define LBLKC		BYTE_REF(LBLKC_ADDR)
+
+#define LBLKC_BD_MASK	0x7f	/* Blink Divisor */
+#define LBLKC_BD_SHIFT	0
+#define LBLKC_BKEN	0x80	/* Blink Enabled */
+
+/*
+ * LCD Panel Interface Configuration Register 
+ */
+#define LPICF_ADDR	0xfffffa20
+#define LPICF		BYTE_REF(LPICF_ADDR)
+
+#define LPICF_GS_MASK	 0x01	 /* Gray-Scale Mode */
+#define	  LPICF_GS_BW	   0x00
+#define   LPICF_GS_GRAY_4  0x01
+#define LPICF_PBSIZ_MASK 0x06	/* Panel Bus Width */
+#define   LPICF_PBSIZ_1	   0x00
+#define   LPICF_PBSIZ_2    0x02
+#define   LPICF_PBSIZ_4    0x04
+
+/*
+ * LCD Polarity Configuration Register 
+ */
+#define LPOLCF_ADDR	0xfffffa21
+#define LPOLCF		BYTE_REF(LPOLCF_ADDR)
+
+#define LPOLCF_PIXPOL	0x01	/* Pixel Polarity */
+#define LPOLCF_LPPOL	0x02	/* Line Pulse Polarity */
+#define LPOLCF_FLMPOL	0x04	/* Frame Marker Polarity */
+#define LPOLCF_LCKPOL	0x08	/* LCD Shift Lock Polarity */
+
+/*
+ * LACD (LCD Alternate Crystal Direction) Rate Control Register
+ */
+#define LACDRC_ADDR	0xfffffa23
+#define LACDRC		BYTE_REF(LACDRC_ADDR)
+
+#define LACDRC_ACD_MASK	 0x0f	/* Alternate Crystal Direction Control */
+#define LACDRC_ACD_SHIFT 0
+
+/*
+ * LCD Pixel Clock Divider Register
+ */
+#define LPXCD_ADDR	0xfffffa25
+#define LPXCD		BYTE_REF(LPXCD_ADDR)
+
+#define	LPXCD_PCD_MASK	0x3f 	/* Pixel Clock Divider */
+#define LPXCD_PCD_SHIFT	0
+
+/*
+ * LCD Clocking Control Register
+ */
+#define LCKCON_ADDR	0xfffffa27
+#define LCKCON		BYTE_REF(LCKCON_ADDR)
+
+#define LCKCON_PCDS	 0x01	/* Pixel Clock Divider Source Select */
+#define LCKCON_DWIDTH	 0x02	/* Display Memory Width  */
+#define LCKCON_DWS_MASK	 0x3c	/* Display Wait-State */
+#define LCKCON_DWS_SHIFT 2
+#define LCKCON_DMA16	 0x40	/* DMA burst length */
+#define LCKCON_LCDON	 0x80	/* Enable LCD Controller */
+
+/* 'EZ328-compatible definitions */
+#define LCKCON_DW_MASK	LCKCON_DWS_MASK
+#define LCKCON_DW_SHIFT	LCKCON_DWS_SHIFT
+
+/*
+ * LCD Last Buffer Address Register
+ */
+#define LLBAR_ADDR	0xfffffa29
+#define LLBAR		BYTE_REF(LLBAR_ADDR)
+
+#define LLBAR_LBAR_MASK	 0x7f	/* Number of memory words to fill 1 line */
+#define LLBAR_LBAR_SHIFT 0
+
+/*
+ * LCD Octet Terminal Count Register 
+ */
+#define LOTCR_ADDR	0xfffffa2b
+#define LOTCR		BYTE_REF(LOTCR_ADDR)
+
+/*
+ * LCD Panning Offset Register
+ */
+#define LPOSR_ADDR	0xfffffa2d
+#define LPOSR		BYTE_REF(LPOSR_ADDR)
+
+#define LPOSR_BOS	0x08	/* Byte offset (for B/W mode only */
+#define LPOSR_POS_MASK	0x07	/* Pixel Offset Code */
+#define LPOSR_POS_SHIFT	0
+
+/*
+ * LCD Frame Rate Control Modulation Register
+ */
+#define LFRCM_ADDR	0xfffffa31
+#define LFRCM		BYTE_REF(LFRCM_ADDR)
+
+#define LFRCM_YMOD_MASK	 0x0f	/* Vertical Modulation */
+#define LFRCM_YMOD_SHIFT 0
+#define LFRCM_XMOD_MASK	 0xf0	/* Horizontal Modulation */
+#define LFRCM_XMOD_SHIFT 4
+
+/*
+ * LCD Gray Palette Mapping Register
+ */
+#define LGPMR_ADDR	0xfffffa32
+#define LGPMR		WORD_REF(LGPMR_ADDR)
+
+#define LGPMR_GLEVEL3_MASK	0x000f
+#define LGPMR_GLEVEL3_SHIFT	0 
+#define LGPMR_GLEVEL2_MASK	0x00f0
+#define LGPMR_GLEVEL2_SHIFT	4 
+#define LGPMR_GLEVEL0_MASK	0x0f00
+#define LGPMR_GLEVEL0_SHIFT	8 
+#define LGPMR_GLEVEL1_MASK	0xf000
+#define LGPMR_GLEVEL1_SHIFT	12
+
+/**********
+ *
+ * 0xFFFFFBxx -- Real-Time Clock (RTC)
+ *
+ **********/
+
+/*
+ * RTC Hours Minutes and Seconds Register
+ */
+#define RTCTIME_ADDR	0xfffffb00
+#define RTCTIME		LONG_REF(RTCTIME_ADDR)
+
+#define RTCTIME_SECONDS_MASK	0x0000003f	/* Seconds */
+#define RTCTIME_SECONDS_SHIFT	0
+#define RTCTIME_MINUTES_MASK	0x003f0000	/* Minutes */
+#define RTCTIME_MINUTES_SHIFT	16
+#define RTCTIME_HOURS_MASK	0x1f000000	/* Hours */
+#define RTCTIME_HOURS_SHIFT	24
+
+/*
+ *  RTC Alarm Register 
+ */
+#define RTCALRM_ADDR    0xfffffb04
+#define RTCALRM         LONG_REF(RTCALRM_ADDR)
+
+#define RTCALRM_SECONDS_MASK    0x0000003f      /* Seconds */
+#define RTCALRM_SECONDS_SHIFT   0
+#define RTCALRM_MINUTES_MASK    0x003f0000      /* Minutes */
+#define RTCALRM_MINUTES_SHIFT   16
+#define RTCALRM_HOURS_MASK      0x1f000000      /* Hours */
+#define RTCALRM_HOURS_SHIFT     24
+
+/*
+ * RTC Control Register
+ */
+#define RTCCTL_ADDR	0xfffffb0c
+#define RTCCTL		WORD_REF(RTCCTL_ADDR)
+
+#define RTCCTL_384	0x0020	/* Crystal Selection */
+#define RTCCTL_ENABLE	0x0080	/* RTC Enable */
+
+/* 'EZ328-compatible definitions */
+#define RTCCTL_XTL	RTCCTL_384
+#define RTCCTL_EN	RTCCTL_ENABLE
+
+/*
+ * RTC Interrupt Status Register 
+ */
+#define RTCISR_ADDR	0xfffffb0e
+#define RTCISR		WORD_REF(RTCISR_ADDR)
+
+#define RTCISR_SW	0x0001	/* Stopwatch timed out */
+#define RTCISR_MIN	0x0002	/* 1-minute interrupt has occured */
+#define RTCISR_ALM	0x0004	/* Alarm interrupt has occured */
+#define RTCISR_DAY	0x0008	/* 24-hour rollover interrupt has occured */
+#define RTCISR_1HZ	0x0010	/* 1Hz interrupt has occured */
+
+/*
+ * RTC Interrupt Enable Register
+ */
+#define RTCIENR_ADDR	0xfffffb10
+#define RTCIENR		WORD_REF(RTCIENR_ADDR)
+
+#define RTCIENR_SW	0x0001	/* Stopwatch interrupt enable */
+#define RTCIENR_MIN	0x0002	/* 1-minute interrupt enable */
+#define RTCIENR_ALM	0x0004	/* Alarm interrupt enable */
+#define RTCIENR_DAY	0x0008	/* 24-hour rollover interrupt enable */
+#define RTCIENR_1HZ	0x0010	/* 1Hz interrupt enable */
+
+/* 
+ * Stopwatch Minutes Register
+ */
+#define STPWCH_ADDR	0xfffffb12
+#define STPWCH		WORD_REF(STPWCH)
+
+#define STPWCH_CNT_MASK	 0x00ff	/* Stopwatch countdown value */
+#define SPTWCH_CNT_SHIFT 0
+
+#endif /* _MC68328_H_ */
diff -Nru a/include/asm-m68knommu/MC68332.h b/include/asm-m68knommu/MC68332.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/MC68332.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,152 @@
+
+/* include/asm-m68knommu/MC68332.h: '332 control registers
+ *
+ * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *
+ */
+
+#ifndef _MC68332_H_
+#define _MC68332_H_
+
+#define BYTE_REF(addr) (*((volatile unsigned char*)addr))
+#define WORD_REF(addr) (*((volatile unsigned short*)addr))
+
+#define PORTE_ADDR	0xfffa11
+#define PORTE	BYTE_REF(PORTE_ADDR)
+#define DDRE_ADDR	0xfffa15
+#define DDRE	BYTE_REF(DDRE_ADDR)
+#define PEPAR_ADDR	0xfffa17
+#define PEPAR	BYTE_REF(PEPAR_ADDR)
+
+#define PORTF_ADDR	0xfffa19
+#define PORTF	BYTE_REF(PORTF_ADDR)
+#define DDRF_ADDR	0xfffa1d
+#define DDRF	BYTE_REF(DDRF_ADDR)
+#define PFPAR_ADDR	0xfffa1f
+#define PFPAR	BYTE_REF(PFPAR_ADDR)
+
+#define PORTQS_ADDR	0xfffc15
+#define PORTQS	BYTE_REF(PORTQS_ADDR)
+#define DDRQS_ADDR	0xfffc17
+#define DDRQS	BYTE_REF(DDRQS_ADDR)
+#define PQSPAR_ADDR	0xfffc16
+#define PQSPAR	BYTE_REF(PQSPAR_ADDR)
+
+#define CSPAR0_ADDR 0xFFFA44
+#define CSPAR0 WORD_REF(CSPAR0_ADDR)
+#define CSPAR1_ADDR 0xFFFA46
+#define CSPAR1 WORD_REF(CSPAR1_ADDR)
+#define CSARBT_ADDR 0xFFFA48
+#define CSARBT WORD_REF(CSARBT_ADDR)
+#define CSOPBT_ADDR 0xFFFA4A
+#define CSOPBT WORD_REF(CSOPBT_ADDR)
+#define CSBAR0_ADDR 0xFFFA4C
+#define CSBAR0 WORD_REF(CSBAR0_ADDR)
+#define CSOR0_ADDR 0xFFFA4E
+#define CSOR0 WORD_REF(CSOR0_ADDR)
+#define CSBAR1_ADDR 0xFFFA50
+#define CSBAR1 WORD_REF(CSBAR1_ADDR)
+#define CSOR1_ADDR 0xFFFA52
+#define CSOR1 WORD_REF(CSOR1_ADDR)
+#define CSBAR2_ADDR 0xFFFA54
+#define CSBAR2 WORD_REF(CSBAR2_ADDR)
+#define CSOR2_ADDR 0xFFFA56
+#define CSOR2 WORD_REF(CSOR2_ADDR)
+#define CSBAR3_ADDR 0xFFFA58
+#define CSBAR3 WORD_REF(CSBAR3_ADDR)
+#define CSOR3_ADDR 0xFFFA5A
+#define CSOR3 WORD_REF(CSOR3_ADDR)
+#define CSBAR4_ADDR 0xFFFA5C
+#define CSBAR4 WORD_REF(CSBAR4_ADDR)
+#define CSOR4_ADDR 0xFFFA5E
+#define CSOR4 WORD_REF(CSOR4_ADDR)
+#define CSBAR5_ADDR 0xFFFA60
+#define CSBAR5 WORD_REF(CSBAR5_ADDR)
+#define CSOR5_ADDR 0xFFFA62
+#define CSOR5 WORD_REF(CSOR5_ADDR)
+#define CSBAR6_ADDR 0xFFFA64
+#define CSBAR6 WORD_REF(CSBAR6_ADDR)
+#define CSOR6_ADDR 0xFFFA66
+#define CSOR6 WORD_REF(CSOR6_ADDR)
+#define CSBAR7_ADDR 0xFFFA68
+#define CSBAR7 WORD_REF(CSBAR7_ADDR)
+#define CSOR7_ADDR 0xFFFA6A
+#define CSOR7 WORD_REF(CSOR7_ADDR)
+#define CSBAR8_ADDR 0xFFFA6C
+#define CSBAR8 WORD_REF(CSBAR8_ADDR)
+#define CSOR8_ADDR 0xFFFA6E
+#define CSOR8 WORD_REF(CSOR8_ADDR)
+#define CSBAR9_ADDR 0xFFFA70
+#define CSBAR9 WORD_REF(CSBAR9_ADDR)
+#define CSOR9_ADDR 0xFFFA72
+#define CSOR9 WORD_REF(CSOR9_ADDR)
+#define CSBAR10_ADDR 0xFFFA74
+#define CSBAR10 WORD_REF(CSBAR10_ADDR)
+#define CSOR10_ADDR 0xFFFA76
+#define CSOR10 WORD_REF(CSOR10_ADDR)
+
+#define CSOR_MODE_ASYNC	0x0000
+#define CSOR_MODE_SYNC	0x8000
+#define CSOR_MODE_MASK	0x8000
+#define CSOR_BYTE_DISABLE	0x0000
+#define CSOR_BYTE_UPPER		0x4000
+#define CSOR_BYTE_LOWER		0x2000
+#define CSOR_BYTE_BOTH		0x6000
+#define CSOR_BYTE_MASK		0x6000
+#define CSOR_RW_RSVD		0x0000
+#define CSOR_RW_READ		0x0800
+#define CSOR_RW_WRITE		0x1000
+#define CSOR_RW_BOTH		0x1800
+#define CSOR_RW_MASK		0x1800
+#define CSOR_STROBE_DS		0x0400
+#define CSOR_STROBE_AS		0x0000
+#define CSOR_STROBE_MASK	0x0400
+#define CSOR_DSACK_WAIT(x)	(wait << 6)
+#define CSOR_DSACK_FTERM	(14 << 6)
+#define CSOR_DSACK_EXTERNAL	(15 << 6)
+#define CSOR_DSACK_MASK		0x03c0
+#define CSOR_SPACE_CPU		0x0000
+#define CSOR_SPACE_USER		0x0010
+#define CSOR_SPACE_SU		0x0020
+#define CSOR_SPACE_BOTH		0x0030
+#define CSOR_SPACE_MASK		0x0030
+#define CSOR_IPL_ALL		0x0000
+#define CSOR_IPL_PRIORITY(x)	(x << 1)
+#define CSOR_IPL_MASK		0x000e
+#define CSOR_AVEC_ON		0x0001
+#define CSOR_AVEC_OFF		0x0000
+#define CSOR_AVEC_MASK		0x0001
+
+#define CSBAR_ADDR(x)		((addr >> 11) << 3) 
+#define CSBAR_ADDR_MASK		0xfff8
+#define CSBAR_BLKSIZE_2K	0x0000
+#define CSBAR_BLKSIZE_8K	0x0001
+#define CSBAR_BLKSIZE_16K	0x0002
+#define CSBAR_BLKSIZE_64K	0x0003
+#define CSBAR_BLKSIZE_128K	0x0004
+#define CSBAR_BLKSIZE_256K	0x0005
+#define CSBAR_BLKSIZE_512K	0x0006
+#define CSBAR_BLKSIZE_1M	0x0007
+#define CSBAR_BLKSIZE_MASK	0x0007
+
+#define CSPAR_DISC	0
+#define CSPAR_ALT	1
+#define CSPAR_CS8	2
+#define CSPAR_CS16	3
+#define CSPAR_MASK	3
+
+#define CSPAR0_CSBOOT(x) (x << 0)
+#define CSPAR0_CS0(x)	(x << 2)
+#define CSPAR0_CS1(x)	(x << 4)
+#define CSPAR0_CS2(x)	(x << 6)
+#define CSPAR0_CS3(x)	(x << 8)
+#define CSPAR0_CS4(x)	(x << 10)
+#define CSPAR0_CS5(x)	(x << 12)
+
+#define CSPAR1_CS6(x)	(x << 0)
+#define CSPAR1_CS7(x)	(x << 2)
+#define CSPAR1_CS8(x)	(x << 4)
+#define CSPAR1_CS9(x)	(x << 6)
+#define CSPAR1_CS10(x)	(x << 8)
+
+#endif
diff -Nru a/include/asm-m68knommu/MC68EZ328.h b/include/asm-m68knommu/MC68EZ328.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/MC68EZ328.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,1253 @@
+
+/* include/asm-m68knommu/MC68EZ328.h: 'EZ328 control registers
+ *
+ * Copyright (C) 1999  Vladimir Gurevich <vgurevic@cisco.com>
+ *                     Bear & Hare Software, Inc.
+ *
+ * Based on include/asm-m68knommu/MC68332.h
+ * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *                     The Silver Hammer Group, Ltd.
+ *
+ */
+
+#ifndef _MC68EZ328_H_
+#define _MC68EZ328_H_
+
+#define BYTE_REF(addr) (*((volatile unsigned char*)addr))
+#define WORD_REF(addr) (*((volatile unsigned short*)addr))
+#define LONG_REF(addr) (*((volatile unsigned long*)addr))
+
+#define PUT_FIELD(field, val) (((val) << field##_SHIFT) & field##_MASK)
+#define GET_FIELD(reg, field) (((reg) & field##_MASK) >> field##_SHIFT)
+
+/********** 
+ *
+ * 0xFFFFF0xx -- System Control
+ *
+ **********/
+ 
+/*
+ * System Control Register (SCR)
+ */
+#define SCR_ADDR	0xfffff000
+#define SCR		BYTE_REF(SCR_ADDR)
+
+#define SCR_WDTH8	0x01	/* 8-Bit Width Select */
+#define SCR_DMAP	0x04	/* Double Map */
+#define SCR_SO		0x08	/* Supervisor Only */
+#define SCR_BETEN	0x10	/* Bus-Error Time-Out Enable */
+#define SCR_PRV		0x20	/* Privilege Violation */
+#define SCR_WPV		0x40	/* Write Protect Violation */
+#define SCR_BETO	0x80	/* Bus-Error TimeOut */
+
+/*
+ * Silicon ID Register (Mask Revision Register (MRR) for '328 Compatibility)
+ */
+#define MRR_ADDR 0xfffff004
+#define MRR	 LONG_REF(MRR_ADDR)
+
+/********** 
+ *
+ * 0xFFFFF1xx -- Chip-Select logic
+ *
+ **********/
+ 
+/*
+ * Chip Select Group Base Registers 
+ */
+#define CSGBA_ADDR	0xfffff100
+#define CSGBB_ADDR	0xfffff102
+
+#define CSGBC_ADDR	0xfffff104
+#define CSGBD_ADDR	0xfffff106
+
+#define CSGBA		WORD_REF(CSGBA_ADDR)
+#define CSGBB		WORD_REF(CSGBB_ADDR)
+#define CSGBC		WORD_REF(CSGBC_ADDR)
+#define CSGBD		WORD_REF(CSGBD_ADDR)
+
+/*
+ * Chip Select Registers 
+ */
+#define CSA_ADDR	0xfffff110
+#define CSB_ADDR	0xfffff112
+#define CSC_ADDR	0xfffff114
+#define CSD_ADDR	0xfffff116
+
+#define CSA		WORD_REF(CSA_ADDR)
+#define CSB		WORD_REF(CSB_ADDR)
+#define CSC		WORD_REF(CSC_ADDR)
+#define CSD		WORD_REF(CSD_ADDR)
+
+#define CSA_EN		0x0001		/* Chip-Select Enable */
+#define CSA_SIZ_MASK	0x000e		/* Chip-Select Size */
+#define CSA_SIZ_SHIFT   1
+#define CSA_WS_MASK	0x0070		/* Wait State */
+#define CSA_WS_SHIFT    4
+#define CSA_BSW		0x0080		/* Data Bus Width */
+#define CSA_FLASH	0x0100		/* FLASH Memory Support */
+#define CSA_RO		0x8000		/* Read-Only */
+
+#define CSB_EN		0x0001		/* Chip-Select Enable */
+#define CSB_SIZ_MASK	0x000e		/* Chip-Select Size */
+#define CSB_SIZ_SHIFT   1
+#define CSB_WS_MASK	0x0070		/* Wait State */
+#define CSB_WS_SHIFT    4
+#define CSB_BSW		0x0080		/* Data Bus Width */
+#define CSB_FLASH	0x0100		/* FLASH Memory Support */
+#define CSB_UPSIZ_MASK	0x1800		/* Unprotected memory block size */
+#define CSB_UPSIZ_SHIFT 11
+#define CSB_ROP		0x2000		/* Readonly if protected */
+#define CSB_SOP		0x4000		/* Supervisor only if protected */
+#define CSB_RO		0x8000		/* Read-Only */
+
+#define CSC_EN		0x0001		/* Chip-Select Enable */
+#define CSC_SIZ_MASK	0x000e		/* Chip-Select Size */
+#define CSC_SIZ_SHIFT   1
+#define CSC_WS_MASK	0x0070		/* Wait State */
+#define CSC_WS_SHIFT    4
+#define CSC_BSW		0x0080		/* Data Bus Width */
+#define CSC_FLASH	0x0100		/* FLASH Memory Support */
+#define CSC_UPSIZ_MASK	0x1800		/* Unprotected memory block size */
+#define CSC_UPSIZ_SHIFT 11
+#define CSC_ROP		0x2000		/* Readonly if protected */
+#define CSC_SOP		0x4000		/* Supervisor only if protected */
+#define CSC_RO		0x8000		/* Read-Only */
+
+#define CSD_EN		0x0001		/* Chip-Select Enable */
+#define CSD_SIZ_MASK	0x000e		/* Chip-Select Size */
+#define CSD_SIZ_SHIFT   1
+#define CSD_WS_MASK	0x0070		/* Wait State */
+#define CSD_WS_SHIFT    4
+#define CSD_BSW		0x0080		/* Data Bus Width */
+#define CSD_FLASH	0x0100		/* FLASH Memory Support */
+#define CSD_DRAM	0x0200		/* Dram Selection */
+#define	CSD_COMB	0x0400		/* Combining */
+#define CSD_UPSIZ_MASK	0x1800		/* Unprotected memory block size */
+#define CSD_UPSIZ_SHIFT 11
+#define CSD_ROP		0x2000		/* Readonly if protected */
+#define CSD_SOP		0x4000		/* Supervisor only if protected */
+#define CSD_RO		0x8000		/* Read-Only */
+
+/*
+ * Emulation Chip-Select Register 
+ */
+#define EMUCS_ADDR	0xfffff118
+#define EMUCS		WORD_REF(EMUCS_ADDR)
+
+#define EMUCS_WS_MASK	0x0070
+#define EMUCS_WS_SHIFT	4
+
+/********** 
+ *
+ * 0xFFFFF2xx -- Phase Locked Loop (PLL) & Power Control
+ *
+ **********/
+
+/*
+ * PLL Control Register 
+ */
+#define PLLCR_ADDR	0xfffff200
+#define PLLCR		WORD_REF(PLLCR_ADDR)
+
+#define PLLCR_DISPLL	       0x0008	/* Disable PLL */
+#define PLLCR_CLKEN	       0x0010	/* Clock (CLKO pin) enable */
+#define PLLCR_PRESC	       0x0020	/* VCO prescaler */
+#define PLLCR_SYSCLK_SEL_MASK  0x0700	/* System Clock Selection */
+#define PLLCR_SYSCLK_SEL_SHIFT 8
+#define PLLCR_LCDCLK_SEL_MASK  0x3800	/* LCD Clock Selection */
+#define PLLCR_LCDCLK_SEL_SHIFT 11
+
+/* '328-compatible definitions */
+#define PLLCR_PIXCLK_SEL_MASK	PLLCR_LCDCLK_SEL_MASK
+#define PLLCR_PIXCLK_SEL_SHIFT	PLLCR_LCDCLK_SEL_SHIFT
+
+/*
+ * PLL Frequency Select Register
+ */
+#define PLLFSR_ADDR	0xfffff202
+#define PLLFSR		WORD_REF(PLLFSR_ADDR)
+
+#define PLLFSR_PC_MASK	0x00ff		/* P Count */
+#define PLLFSR_PC_SHIFT 0
+#define PLLFSR_QC_MASK	0x0f00		/* Q Count */
+#define PLLFSR_QC_SHIFT 8
+#define PLLFSR_PROT	0x4000		/* Protect P & Q */
+#define PLLFSR_CLK32	0x8000		/* Clock 32 (kHz) */
+
+/*
+ * Power Control Register
+ */
+#define PCTRL_ADDR	0xfffff207
+#define PCTRL		BYTE_REF(PCTRL_ADDR)
+
+#define PCTRL_WIDTH_MASK	0x1f	/* CPU Clock bursts width */
+#define PCTRL_WIDTH_SHIFT	0
+#define PCTRL_PCEN		0x80	/* Power Control Enable */
+
+/**********
+ *
+ * 0xFFFFF3xx -- Interrupt Controller
+ *
+ **********/
+
+/* 
+ * Interrupt Vector Register
+ */
+#define IVR_ADDR	0xfffff300
+#define IVR		BYTE_REF(IVR_ADDR)
+
+#define IVR_VECTOR_MASK 0xF8
+
+/*
+ * Interrupt control Register
+ */
+#define ICR_ADDR	0xfffff302
+#define ICR		WORD_REF(ICR_ADDR)
+
+#define ICR_POL5	0x0080	/* Polarity Control for IRQ5 */
+#define ICR_ET6		0x0100	/* Edge Trigger Select for IRQ6 */
+#define ICR_ET3		0x0200	/* Edge Trigger Select for IRQ3 */
+#define ICR_ET2		0x0400	/* Edge Trigger Select for IRQ2 */
+#define ICR_ET1		0x0800	/* Edge Trigger Select for IRQ1 */
+#define ICR_POL6	0x1000	/* Polarity Control for IRQ6 */
+#define ICR_POL3	0x2000	/* Polarity Control for IRQ3 */
+#define ICR_POL2	0x4000	/* Polarity Control for IRQ2 */
+#define ICR_POL1	0x8000	/* Polarity Control for IRQ1 */
+
+/*
+ * Interrupt Mask Register
+ */
+#define IMR_ADDR	0xfffff304
+#define IMR		LONG_REF(IMR_ADDR)
+
+/*
+ * Define the names for bit positions first. This is useful for 
+ * request_irq
+ */
+#define SPI_IRQ_NUM	0	/* SPI interrupt */
+#define TMR_IRQ_NUM	1	/* Timer interrupt */
+#define UART_IRQ_NUM	2	/* UART interrupt */	
+#define	WDT_IRQ_NUM	3	/* Watchdog Timer interrupt */
+#define RTC_IRQ_NUM	4	/* RTC interrupt */
+#define	KB_IRQ_NUM	6	/* Keyboard Interrupt */
+#define PWM_IRQ_NUM	7	/* Pulse-Width Modulator int. */
+#define	INT0_IRQ_NUM	8	/* External INT0 */
+#define	INT1_IRQ_NUM	9	/* External INT1 */
+#define	INT2_IRQ_NUM	10	/* External INT2 */
+#define	INT3_IRQ_NUM	11	/* External INT3 */
+#define IRQ1_IRQ_NUM	16	/* IRQ1 */
+#define IRQ2_IRQ_NUM	17	/* IRQ2 */
+#define IRQ3_IRQ_NUM	18	/* IRQ3 */
+#define IRQ6_IRQ_NUM	19	/* IRQ6 */
+#define IRQ5_IRQ_NUM	20	/* IRQ5 */
+#define SAM_IRQ_NUM	22	/* Sampling Timer for RTC */
+#define EMIQ_IRQ_NUM	23	/* Emulator Interrupt */
+
+/* '328-compatible definitions */
+#define SPIM_IRQ_NUM	SPI_IRQ_NUM
+#define TMR1_IRQ_NUM	TMR_IRQ_NUM
+
+/* 
+ * Here go the bitmasks themselves
+ */
+#define IMR_MSPI 	(1 << SPI_IRQ_NUM)	/* Mask SPI interrupt */
+#define	IMR_MTMR	(1 << TMR_IRQ_NUM)	/* Mask Timer interrupt */
+#define IMR_MUART	(1 << UART_IRQ_NUM)	/* Mask UART interrupt */	
+#define	IMR_MWDT	(1 << WDT_IRQ_NUM)	/* Mask Watchdog Timer interrupt */
+#define IMR_MRTC	(1 << RTC_IRQ_NUM)	/* Mask RTC interrupt */
+#define	IMR_MKB		(1 << KB_IRQ_NUM)	/* Mask Keyboard Interrupt */
+#define IMR_MPWM	(1 << PWM_IRQ_NUM)	/* Mask Pulse-Width Modulator int. */
+#define	IMR_MINT0	(1 << INT0_IRQ_NUM)	/* Mask External INT0 */
+#define	IMR_MINT1	(1 << INT1_IRQ_NUM)	/* Mask External INT1 */
+#define	IMR_MINT2	(1 << INT2_IRQ_NUM)	/* Mask External INT2 */
+#define	IMR_MINT3	(1 << INT3_IRQ_NUM)	/* Mask External INT3 */
+#define IMR_MIRQ1	(1 << IRQ1_IRQ_NUM)	/* Mask IRQ1 */
+#define IMR_MIRQ2	(1 << IRQ2_IRQ_NUM)	/* Mask IRQ2 */
+#define IMR_MIRQ3	(1 << IRQ3_IRQ_NUM)	/* Mask IRQ3 */
+#define IMR_MIRQ6	(1 << IRQ6_IRQ_NUM)	/* Mask IRQ6 */
+#define IMR_MIRQ5	(1 << IRQ5_IRQ_NUM)	/* Mask IRQ5 */
+#define IMR_MSAM	(1 << SAM_IRQ_NUM)	/* Mask Sampling Timer for RTC */
+#define IMR_MEMIQ	(1 << EMIQ_IRQ_NUM)	/* Mask Emulator Interrupt */
+
+/* '328-compatible definitions */
+#define IMR_MSPIM	IMR_MSPI
+#define IMR_MTMR1	IMR_MTMR
+
+/* 
+ * Interrupt Status Register 
+ */
+#define ISR_ADDR	0xfffff30c
+#define ISR		LONG_REF(ISR_ADDR)
+
+#define ISR_SPI 	(1 << SPI_IRQ_NUM)	/* SPI interrupt */
+#define	ISR_TMR		(1 << TMR_IRQ_NUM)	/* Timer interrupt */
+#define ISR_UART	(1 << UART_IRQ_NUM)	/* UART interrupt */	
+#define	ISR_WDT		(1 << WDT_IRQ_NUM)	/* Watchdog Timer interrupt */
+#define ISR_RTC		(1 << RTC_IRQ_NUM)	/* RTC interrupt */
+#define	ISR_KB		(1 << KB_IRQ_NUM)	/* Keyboard Interrupt */
+#define ISR_PWM		(1 << PWM_IRQ_NUM)	/* Pulse-Width Modulator interrupt */
+#define	ISR_INT0	(1 << INT0_IRQ_NUM)	/* External INT0 */
+#define	ISR_INT1	(1 << INT1_IRQ_NUM)	/* External INT1 */
+#define	ISR_INT2	(1 << INT2_IRQ_NUM)	/* External INT2 */
+#define	ISR_INT3	(1 << INT3_IRQ_NUM)	/* External INT3 */
+#define ISR_IRQ1	(1 << IRQ1_IRQ_NUM)	/* IRQ1 */
+#define ISR_IRQ2	(1 << IRQ2_IRQ_NUM)	/* IRQ2 */
+#define ISR_IRQ3	(1 << IRQ3_IRQ_NUM)	/* IRQ3 */
+#define ISR_IRQ6	(1 << IRQ6_IRQ_NUM)	/* IRQ6 */
+#define ISR_IRQ5	(1 << IRQ5_IRQ_NUM)	/* IRQ5 */
+#define ISR_SAM		(1 << SAM_IRQ_NUM)	/* Sampling Timer for RTC */
+#define ISR_EMIQ	(1 << EMIQ_IRQ_NUM)	/* Emulator Interrupt */
+
+/* '328-compatible definitions */
+#define ISR_SPIM	ISR_SPI
+#define ISR_TMR1	ISR_TMR
+
+/* 
+ * Interrupt Pending Register 
+ */
+#define IPR_ADDR	0xfffff30c
+#define IPR		LONG_REF(IPR_ADDR)
+
+#define IPR_SPI 	(1 << SPI_IRQ_NUM)	/* SPI interrupt */
+#define	IPR_TMR		(1 << TMR_IRQ_NUM)	/* Timer interrupt */
+#define IPR_UART	(1 << UART_IRQ_NUM)	/* UART interrupt */	
+#define	IPR_WDT		(1 << WDT_IRQ_NUM)	/* Watchdog Timer interrupt */
+#define IPR_RTC		(1 << RTC_IRQ_NUM)	/* RTC interrupt */
+#define	IPR_KB		(1 << KB_IRQ_NUM)	/* Keyboard Interrupt */
+#define IPR_PWM		(1 << PWM_IRQ_NUM)	/* Pulse-Width Modulator interrupt */
+#define	IPR_INT0	(1 << INT0_IRQ_NUM)	/* External INT0 */
+#define	IPR_INT1	(1 << INT1_IRQ_NUM)	/* External INT1 */
+#define	IPR_INT2	(1 << INT2_IRQ_NUM)	/* External INT2 */
+#define	IPR_INT3	(1 << INT3_IRQ_NUM)	/* External INT3 */
+#define IPR_IRQ1	(1 << IRQ1_IRQ_NUM)	/* IRQ1 */
+#define IPR_IRQ2	(1 << IRQ2_IRQ_NUM)	/* IRQ2 */
+#define IPR_IRQ3	(1 << IRQ3_IRQ_NUM)	/* IRQ3 */
+#define IPR_IRQ6	(1 << IRQ6_IRQ_NUM)	/* IRQ6 */
+#define IPR_IRQ5	(1 << IRQ5_IRQ_NUM)	/* IRQ5 */
+#define IPR_SAM		(1 << SAM_IRQ_NUM)	/* Sampling Timer for RTC */
+#define IPR_EMIQ	(1 << EMIQ_IRQ_NUM)	/* Emulator Interrupt */
+
+/* '328-compatible definitions */
+#define IPR_SPIM	IPR_SPI
+#define IPR_TMR1	IPR_TMR
+
+/**********
+ *
+ * 0xFFFFF4xx -- Parallel Ports
+ *
+ **********/
+
+/*
+ * Port A
+ */
+#define PADIR_ADDR	0xfffff400		/* Port A direction reg */
+#define PADATA_ADDR	0xfffff401		/* Port A data register */
+#define PAPUEN_ADDR	0xfffff402		/* Port A Pull-Up enable reg */
+
+#define PADIR		BYTE_REF(PADIR_ADDR)
+#define PADATA		BYTE_REF(PADATA_ADDR)
+#define PAPUEN		BYTE_REF(PAPUEN_ADDR)
+
+#define PA(x)		(1 << (x))
+
+/* 
+ * Port B
+ */
+#define PBDIR_ADDR	0xfffff408		/* Port B direction reg */
+#define PBDATA_ADDR	0xfffff409		/* Port B data register */
+#define PBPUEN_ADDR	0xfffff40a		/* Port B Pull-Up enable reg */
+#define PBSEL_ADDR	0xfffff40b		/* Port B Select Register */
+
+#define PBDIR		BYTE_REF(PBDIR_ADDR)
+#define PBDATA		BYTE_REF(PBDATA_ADDR)
+#define PBPUEN		BYTE_REF(PBPUEN_ADDR)
+#define PBSEL		BYTE_REF(PBSEL_ADDR)
+
+#define PB(x)		(1 << (x))
+
+#define PB_CSB0		0x01	/* Use CSB0      as PB[0] */
+#define PB_CSB1		0x02	/* Use CSB1      as PB[1] */
+#define PB_CSC0_RAS0	0x04    /* Use CSC0/RAS0 as PB[2] */	
+#define PB_CSC1_RAS1	0x08    /* Use CSC1/RAS1 as PB[3] */	
+#define PB_CSD0_CAS0	0x10    /* Use CSD0/CAS0 as PB[4] */	
+#define PB_CSD1_CAS1	0x20    /* Use CSD1/CAS1 as PB[5] */
+#define PB_TIN_TOUT	0x40	/* Use TIN/TOUT  as PB[6] */
+#define PB_PWMO		0x80	/* Use PWMO      as PB[7] */
+
+/* 
+ * Port C
+ */
+#define PCDIR_ADDR	0xfffff410		/* Port C direction reg */
+#define PCDATA_ADDR	0xfffff411		/* Port C data register */
+#define PCPDEN_ADDR	0xfffff412		/* Port C Pull-Down enb. reg */
+#define PCSEL_ADDR	0xfffff413		/* Port C Select Register */
+
+#define PCDIR		BYTE_REF(PCDIR_ADDR)
+#define PCDATA		BYTE_REF(PCDATA_ADDR)
+#define PCPDEN		BYTE_REF(PCPDEN_ADDR)
+#define PCSEL		BYTE_REF(PCSEL_ADDR)
+
+#define PC(x)		(1 << (x))
+
+#define PC_LD0		0x01	/* Use LD0  as PC[0] */
+#define PC_LD1		0x02	/* Use LD1  as PC[1] */
+#define PC_LD2		0x04	/* Use LD2  as PC[2] */
+#define PC_LD3		0x08	/* Use LD3  as PC[3] */
+#define PC_LFLM		0x10	/* Use LFLM as PC[4] */
+#define PC_LLP 		0x20	/* Use LLP  as PC[5] */
+#define PC_LCLK		0x40	/* Use LCLK as PC[6] */
+#define PC_LACD		0x80	/* Use LACD as PC[7] */
+
+/* 
+ * Port D
+ */
+#define PDDIR_ADDR	0xfffff418		/* Port D direction reg */
+#define PDDATA_ADDR	0xfffff419		/* Port D data register */
+#define PDPUEN_ADDR	0xfffff41a		/* Port D Pull-Up enable reg */
+#define PDSEL_ADDR	0xfffff41b		/* Port D Select Register */
+#define PDPOL_ADDR	0xfffff41c		/* Port D Polarity Register */
+#define PDIRQEN_ADDR	0xfffff41d		/* Port D IRQ enable register */
+#define PDKBEN_ADDR	0xfffff41e		/* Port D Keyboard Enable reg */
+#define	PDIQEG_ADDR	0xfffff41f		/* Port D IRQ Edge Register */
+
+#define PDDIR		BYTE_REF(PDDIR_ADDR)
+#define PDDATA		BYTE_REF(PDDATA_ADDR)
+#define PDPUEN		BYTE_REF(PDPUEN_ADDR)
+#define PDSEL		BYTE_REF(PDSEL_ADDR)
+#define	PDPOL		BYTE_REF(PDPOL_ADDR)
+#define PDIRQEN		BYTE_REF(PDIRQEN_ADDR)
+#define PDKBEN		BYTE_REF(PDKBEN_ADDR)
+#define PDIQEG		BYTE_REF(PDIQEG_ADDR)
+
+#define PD(x)		(1 << (x))
+
+#define PD_INT0		0x01	/* Use INT0 as PD[0] */
+#define PD_INT1		0x02	/* Use INT1 as PD[1] */
+#define PD_INT2		0x04	/* Use INT2 as PD[2] */
+#define PD_INT3		0x08	/* Use INT3 as PD[3] */
+#define PD_IRQ1		0x10	/* Use IRQ1 as PD[4] */
+#define PD_IRQ2		0x20	/* Use IRQ2 as PD[5] */
+#define PD_IRQ3		0x40	/* Use IRQ3 as PD[6] */
+#define PD_IRQ6		0x80	/* Use IRQ6 as PD[7] */
+
+/* 
+ * Port E
+ */
+#define PEDIR_ADDR	0xfffff420		/* Port E direction reg */
+#define PEDATA_ADDR	0xfffff421		/* Port E data register */
+#define PEPUEN_ADDR	0xfffff422		/* Port E Pull-Up enable reg */
+#define PESEL_ADDR	0xfffff423		/* Port E Select Register */
+
+#define PEDIR		BYTE_REF(PEDIR_ADDR)
+#define PEDATA		BYTE_REF(PEDATA_ADDR)
+#define PEPUEN		BYTE_REF(PEPUEN_ADDR)
+#define PESEL		BYTE_REF(PESEL_ADDR)
+
+#define PE(x)		(1 << (x))
+
+#define PE_SPMTXD	0x01	/* Use SPMTXD as PE[0] */
+#define PE_SPMRXD	0x02	/* Use SPMRXD as PE[1] */
+#define PE_SPMCLK	0x04	/* Use SPMCLK as PE[2] */
+#define PE_DWE		0x08	/* Use DWE    as PE[3] */
+#define PE_RXD		0x10	/* Use RXD    as PE[4] */
+#define PE_TXD		0x20	/* Use TXD    as PE[5] */
+#define PE_RTS		0x40	/* Use RTS    as PE[6] */
+#define PE_CTS		0x80	/* Use CTS    as PE[7] */
+
+/* 
+ * Port F
+ */
+#define PFDIR_ADDR	0xfffff428		/* Port F direction reg */
+#define PFDATA_ADDR	0xfffff429		/* Port F data register */
+#define PFPUEN_ADDR	0xfffff42a		/* Port F Pull-Up enable reg */
+#define PFSEL_ADDR	0xfffff42b		/* Port F Select Register */
+
+#define PFDIR		BYTE_REF(PFDIR_ADDR)
+#define PFDATA		BYTE_REF(PFDATA_ADDR)
+#define PFPUEN		BYTE_REF(PFPUEN_ADDR)
+#define PFSEL		BYTE_REF(PFSEL_ADDR)
+
+#define PF(x)		(1 << (x))
+
+#define PF_LCONTRAST	0x01	/* Use LCONTRAST as PF[0] */
+#define PF_IRQ5         0x02    /* Use IRQ5      as PF[1] */
+#define PF_CLKO         0x04    /* Use CLKO      as PF[2] */
+#define PF_A20          0x08    /* Use A20       as PF[3] */
+#define PF_A21          0x10    /* Use A21       as PF[4] */
+#define PF_A22          0x20    /* Use A22       as PF[5] */
+#define PF_A23          0x40    /* Use A23       as PF[6] */
+#define PF_CSA1		0x80    /* Use CSA1      as PF[7] */
+
+/* 
+ * Port G
+ */
+#define PGDIR_ADDR	0xfffff430		/* Port G direction reg */
+#define PGDATA_ADDR	0xfffff431		/* Port G data register */
+#define PGPUEN_ADDR	0xfffff432		/* Port G Pull-Up enable reg */
+#define PGSEL_ADDR	0xfffff433		/* Port G Select Register */
+
+#define PGDIR		BYTE_REF(PGDIR_ADDR)
+#define PGDATA		BYTE_REF(PGDATA_ADDR)
+#define PGPUEN		BYTE_REF(PGPUEN_ADDR)
+#define PGSEL		BYTE_REF(PGSEL_ADDR)
+
+#define PG(x)		(1 << (x))
+
+#define PG_BUSW_DTACK	0x01	/* Use BUSW/DTACK as PG[0] */
+#define PG_A0		0x02	/* Use A0         as PG[1] */
+#define PG_EMUIRQ	0x04	/* Use EMUIRQ     as PG[2] */
+#define PG_HIZ_P_D	0x08	/* Use HIZ/P/D    as PG[3] */
+#define PG_EMUCS        0x10	/* Use EMUCS      as PG[4] */
+#define PG_EMUBRK	0x20	/* Use EMUBRK     as PG[5] */
+
+/**********
+ *
+ * 0xFFFFF5xx -- Pulse-Width Modulator (PWM)
+ *
+ **********/
+
+/*
+ * PWM Control Register 
+ */
+#define PWMC_ADDR	0xfffff500
+#define PWMC		WORD_REF(PWMC_ADDR)
+
+#define PWMC_CLKSEL_MASK	0x0003	/* Clock Selection */
+#define PWMC_CLKSEL_SHIFT	0
+#define PWMC_REPEAT_MASK	0x000c	/* Sample Repeats */
+#define PWMC_REPEAT_SHIFT	2
+#define PWMC_EN			0x0010	/* Enable PWM */
+#define PMNC_FIFOAV		0x0020	/* FIFO Available */
+#define PWMC_IRQEN		0x0040	/* Interrupt Request Enable */
+#define PWMC_IRQ		0x0080	/* Interrupt Request (FIFO empty) */
+#define PWMC_PRESCALER_MASK	0x7f00	/* Incoming Clock prescaler */
+#define PWMC_PRESCALER_SHIFT	8
+#define PWMC_CLKSRC		0x8000	/* Clock Source Select */
+
+/* '328-compatible definitions */
+#define PWMC_PWMEN	PWMC_EN
+
+/*
+ * PWM Sample Register 
+ */
+#define PWMS_ADDR	0xfffff502
+#define PWMS		WORD_REF(PWMS_ADDR)
+
+/*
+ * PWM Period Register
+ */
+#define PWMP_ADDR	0xfffff504
+#define PWMP		BYTE_REF(PWMP_ADDR)
+
+/*
+ * PWM Counter Register
+ */
+#define PWMCNT_ADDR	0xfffff505
+#define PWMCNT		BYTE_REF(PWMCNT_ADDR)
+
+/**********
+ *
+ * 0xFFFFF6xx -- General-Purpose Timer
+ *
+ **********/
+
+/* 
+ * Timer Control register
+ */
+#define TCTL_ADDR	0xfffff600
+#define TCTL		WORD_REF(TCTL_ADDR)
+
+#define	TCTL_TEN		0x0001	/* Timer Enable  */
+#define TCTL_CLKSOURCE_MASK 	0x000e	/* Clock Source: */
+#define   TCTL_CLKSOURCE_STOP	   0x0000	/* Stop count (disabled)    */
+#define   TCTL_CLKSOURCE_SYSCLK	   0x0002	/* SYSCLK to prescaler      */
+#define   TCTL_CLKSOURCE_SYSCLK_16 0x0004	/* SYSCLK/16 to prescaler   */
+#define   TCTL_CLKSOURCE_TIN	   0x0006	/* TIN to prescaler         */
+#define   TCTL_CLKSOURCE_32KHZ	   0x0008	/* 32kHz clock to prescaler */
+#define TCTL_IRQEN		0x0010	/* IRQ Enable    */
+#define TCTL_OM			0x0020	/* Output Mode   */
+#define TCTL_CAP_MASK		0x00c0	/* Capture Edge: */
+#define	  TCTL_CAP_RE		0x0040		/* Capture on rizing edge   */
+#define   TCTL_CAP_FE		0x0080		/* Capture on falling edge  */
+#define TCTL_FRR		0x0010	/* Free-Run Mode */
+
+/* '328-compatible definitions */
+#define TCTL1_ADDR	TCTL_ADDR
+#define TCTL1		TCTL
+
+/*
+ * Timer Prescaler Register
+ */
+#define TPRER_ADDR	0xfffff602
+#define TPRER		WORD_REF(TPRER_ADDR)
+
+/* '328-compatible definitions */
+#define TPRER1_ADDR	TPRER_ADDR
+#define TPRER1		TPRER
+
+/*
+ * Timer Compare Register
+ */
+#define TCMP_ADDR	0xfffff604
+#define TCMP		WORD_REF(TCMP_ADDR)
+
+/* '328-compatible definitions */
+#define TCMP1_ADDR	TCMP_ADDR
+#define TCMP1		TCMP
+
+/*
+ * Timer Capture register
+ */
+#define TCR_ADDR	0xfffff606
+#define TCR		WORD_REF(TCR_ADDR)
+
+/* '328-compatible definitions */
+#define TCR1_ADDR	TCR_ADDR
+#define TCR1		TCR
+
+/*
+ * Timer Counter Register
+ */
+#define TCN_ADDR	0xfffff608
+#define TCN		WORD_REF(TCN_ADDR)
+
+/* '328-compatible definitions */
+#define TCN1_ADDR	TCN_ADDR
+#define TCN1		TCN
+
+/*
+ * Timer Status Register
+ */
+#define TSTAT_ADDR	0xfffff60a
+#define TSTAT		WORD_REF(TSTAT_ADDR)
+
+#define TSTAT_COMP	0x0001		/* Compare Event occurred */
+#define TSTAT_CAPT	0x0001		/* Capture Event occurred */
+
+/* '328-compatible definitions */
+#define TSTAT1_ADDR	TSTAT_ADDR
+#define TSTAT1		TSTAT
+
+/**********
+ *
+ * 0xFFFFF8xx -- Serial Periferial Interface Master (SPIM)
+ *
+ **********/
+
+/*
+ * SPIM Data Register
+ */
+#define SPIMDATA_ADDR	0xfffff800
+#define SPIMDATA	WORD_REF(SPIMDATA_ADDR)
+
+/*
+ * SPIM Control/Status Register
+ */
+#define SPIMCONT_ADDR	0xfffff802
+#define SPIMCONT	WORD_REF(SPIMCONT_ADDR)
+
+#define SPIMCONT_BIT_COUNT_MASK	 0x000f	/* Transfer Length in Bytes */
+#define SPIMCONT_BIT_COUNT_SHIFT 0
+#define SPIMCONT_POL		 0x0010	/* SPMCLK Signel Polarity */
+#define	SPIMCONT_PHA		 0x0020	/* Clock/Data phase relationship */
+#define SPIMCONT_IRQEN		 0x0040 /* IRQ Enable */
+#define SPIMCONT_IRQ		 0x0080	/* Interrupt Request */
+#define SPIMCONT_XCH		 0x0100	/* Exchange */
+#define SPIMCONT_ENABLE		 0x0200	/* Enable SPIM */
+#define SPIMCONT_DATA_RATE_MASK	 0xe000	/* SPIM Data Rate */
+#define SPIMCONT_DATA_RATE_SHIFT 13
+
+/* '328-compatible definitions */
+#define SPIMCONT_SPIMIRQ	SPIMCONT_IRQ
+#define SPIMCONT_SPIMEN		SPIMCONT_ENABLE
+
+/**********
+ *
+ * 0xFFFFF9xx -- UART
+ *
+ **********/
+
+/*
+ * UART Status/Control Register
+ */
+#define USTCNT_ADDR	0xfffff900
+#define USTCNT		WORD_REF(USTCNT_ADDR)
+
+#define USTCNT_TXAE	0x0001	/* Transmitter Available Interrupt Enable */
+#define USTCNT_TXHE	0x0002	/* Transmitter Half Empty Enable */
+#define USTCNT_TXEE	0x0004	/* Transmitter Empty Interrupt Enable */
+#define USTCNT_RXRE	0x0008	/* Receiver Ready Interrupt Enable */
+#define USTCNT_RXHE	0x0010	/* Receiver Half-Full Interrupt Enable */
+#define USTCNT_RXFE	0x0020	/* Receiver Full Interrupt Enable */
+#define USTCNT_CTSD	0x0040	/* CTS Delta Interrupt Enable */
+#define USTCNT_ODEN	0x0080	/* Old Data Interrupt Enable */
+#define USTCNT_8_7	0x0100	/* Eight or seven-bit transmission */
+#define USTCNT_STOP	0x0200	/* Stop bit transmission */
+#define USTCNT_ODD	0x0400	/* Odd Parity */
+#define	USTCNT_PEN	0x0800	/* Parity Enable */
+#define USTCNT_CLKM	0x1000	/* Clock Mode Select */
+#define	USTCNT_TXEN	0x2000	/* Transmitter Enable */
+#define USTCNT_RXEN	0x4000	/* Receiver Enable */
+#define USTCNT_UEN	0x8000	/* UART Enable */
+
+/* '328-compatible definitions */
+#define USTCNT_TXAVAILEN	USTCNT_TXAE
+#define USTCNT_TXHALFEN		USTCNT_TXHE
+#define USTCNT_TXEMPTYEN	USTCNT_TXEE
+#define USTCNT_RXREADYEN	USTCNT_RXRE
+#define USTCNT_RXHALFEN		USTCNT_RXHE
+#define USTCNT_RXFULLEN		USTCNT_RXFE
+#define USTCNT_CTSDELTAEN	USTCNT_CTSD
+#define USTCNT_ODD_EVEN		USTCNT_ODD
+#define USTCNT_PARITYEN		USTCNT_PEN
+#define USTCNT_CLKMODE		USTCNT_CLKM
+#define USTCNT_UARTEN		USTCNT_UEN
+
+/*
+ * UART Baud Control Register
+ */
+#define UBAUD_ADDR	0xfffff902
+#define UBAUD		WORD_REF(UBAUD_ADDR)
+
+#define UBAUD_PRESCALER_MASK	0x003f	/* Actual divisor is 65 - PRESCALER */
+#define UBAUD_PRESCALER_SHIFT	0
+#define UBAUD_DIVIDE_MASK	0x0700	/* Baud Rate freq. divizor */
+#define UBAUD_DIVIDE_SHIFT	8
+#define UBAUD_BAUD_SRC		0x0800	/* Baud Rate Source */
+#define UBAUD_UCLKDIR		0x2000	/* UCLK Direction */
+
+/*
+ * UART Receiver Register 
+ */
+#define URX_ADDR	0xfffff904
+#define URX		WORD_REF(URX_ADDR)
+
+#define URX_RXDATA_ADDR	0xfffff905
+#define URX_RXDATA	BYTE_REF(URX_RXDATA_ADDR)
+
+#define URX_RXDATA_MASK	 0x00ff	/* Received data */
+#define URX_RXDATA_SHIFT 0
+#define URX_PARITY_ERROR 0x0100	/* Parity Error */
+#define URX_BREAK	 0x0200	/* Break Detected */
+#define URX_FRAME_ERROR	 0x0400	/* Framing Error */
+#define URX_OVRUN	 0x0800	/* Serial Overrun */
+#define URX_OLD_DATA	 0x1000	/* Old data in FIFO */
+#define URX_DATA_READY	 0x2000	/* Data Ready (FIFO not empty) */
+#define URX_FIFO_HALF	 0x4000 /* FIFO is Half-Full */
+#define URX_FIFO_FULL	 0x8000	/* FIFO is Full */
+
+/*
+ * UART Transmitter Register 
+ */
+#define UTX_ADDR	0xfffff906
+#define UTX		WORD_REF(UTX_ADDR)
+
+#define UTX_TXDATA_ADDR	0xfffff907
+#define UTX_TXDATA	BYTE_REF(UTX_TXDATA_ADDR)
+
+#define UTX_TXDATA_MASK	 0x00ff	/* Data to be transmitted */
+#define UTX_TXDATA_SHIFT 0
+#define UTX_CTS_DELTA	 0x0100	/* CTS changed */
+#define UTX_CTS_STAT	 0x0200	/* CTS State */
+#define	UTX_BUSY	 0x0400	/* FIFO is busy, sending a character */
+#define	UTX_NOCTS	 0x0800	/* Ignore CTS */
+#define UTX_SEND_BREAK	 0x1000	/* Send a BREAK */
+#define UTX_TX_AVAIL	 0x2000	/* Transmit FIFO has a slot available */
+#define UTX_FIFO_HALF	 0x4000	/* Transmit FIFO is half empty */
+#define UTX_FIFO_EMPTY	 0x8000	/* Transmit FIFO is empty */
+
+/* '328-compatible definitions */
+#define UTX_CTS_STATUS	UTX_CTS_STAT
+#define UTX_IGNORE_CTS	UTX_NOCTS
+
+/*
+ * UART Miscellaneous Register 
+ */
+#define UMISC_ADDR	0xfffff908
+#define UMISC		WORD_REF(UMISC_ADDR)
+
+#define UMISC_TX_POL	 0x0004	/* Transmit Polarity */
+#define UMISC_RX_POL	 0x0008	/* Receive Polarity */
+#define UMISC_IRDA_LOOP	 0x0010	/* IrDA Loopback Enable */
+#define UMISC_IRDA_EN	 0x0020	/* Infra-Red Enable */
+#define UMISC_RTS	 0x0040	/* Set RTS status */
+#define UMISC_RTSCONT	 0x0080	/* Choose RTS control */
+#define UMISC_IR_TEST	 0x0400	/* IRDA Test Enable */
+#define UMISC_BAUD_RESET 0x0800	/* Reset Baud Rate Generation Counters */
+#define UMISC_LOOP	 0x1000	/* Serial Loopback Enable */
+#define UMISC_FORCE_PERR 0x2000	/* Force Parity Error */
+#define UMISC_CLKSRC	 0x4000	/* Clock Source */
+#define UMISC_BAUD_TEST	 0x8000	/* Enable Baud Test Mode */
+
+/* 
+ * UART Non-integer Prescaler Register
+ */
+#define NIPR_ADDR	0xfffff90a
+#define NIPR		WORD_REF(NIPR_ADDR)
+
+#define NIPR_STEP_VALUE_MASK	0x00ff	/* NI prescaler step value */
+#define NIPR_STEP_VALUE_SHIFT	0
+#define NIPR_SELECT_MASK	0x0700	/* Tap Selection */
+#define NIPR_SELECT_SHIFT	8
+#define NIPR_PRE_SEL		0x8000	/* Non-integer prescaler select */
+
+
+/* generalization of uart control registers to support multiple ports: */
+typedef volatile struct {
+  volatile unsigned short int ustcnt;
+  volatile unsigned short int ubaud;
+  union {
+    volatile unsigned short int w;
+    struct {
+      volatile unsigned char status;
+      volatile unsigned char rxdata;
+    } b;
+  } urx;
+  union {
+    volatile unsigned short int w;
+    struct {
+      volatile unsigned char status;
+      volatile unsigned char txdata;
+    } b;
+  } utx;
+  volatile unsigned short int umisc;
+  volatile unsigned short int nipr;
+  volatile unsigned short int pad1;
+  volatile unsigned short int pad2;
+} m68328_uart __attribute__((packed));
+
+
+/**********
+ *
+ * 0xFFFFFAxx -- LCD Controller
+ *
+ **********/
+
+/*
+ * LCD Screen Starting Address Register 
+ */
+#define LSSA_ADDR	0xfffffa00
+#define LSSA		LONG_REF(LSSA_ADDR)
+
+#define LSSA_SSA_MASK	0x1ffffffe	/* Bits 0 and 29-31 are reserved */
+
+/*
+ * LCD Virtual Page Width Register 
+ */
+#define LVPW_ADDR	0xfffffa05
+#define LVPW		BYTE_REF(LVPW_ADDR)
+
+/*
+ * LCD Screen Width Register (not compatible with '328 !!!) 
+ */
+#define LXMAX_ADDR	0xfffffa08
+#define LXMAX		WORD_REF(LXMAX_ADDR)
+
+#define LXMAX_XM_MASK	0x02f0		/* Bits 0-3 and 10-15 are reserved */
+
+/*
+ * LCD Screen Height Register
+ */
+#define LYMAX_ADDR	0xfffffa0a
+#define LYMAX		WORD_REF(LYMAX_ADDR)
+
+#define LYMAX_YM_MASK	0x01ff		/* Bits 9-15 are reserved */
+
+/*
+ * LCD Cursor X Position Register
+ */
+#define LCXP_ADDR	0xfffffa18
+#define LCXP		WORD_REF(LCXP_ADDR)
+
+#define LCXP_CC_MASK	0xc000		/* Cursor Control */
+#define   LCXP_CC_TRAMSPARENT	0x0000
+#define   LCXP_CC_BLACK		0x4000
+#define   LCXP_CC_REVERSED	0x8000
+#define   LCXP_CC_WHITE		0xc000
+#define LCXP_CXP_MASK	0x02ff		/* Cursor X position */
+
+/*
+ * LCD Cursor Y Position Register
+ */
+#define LCYP_ADDR	0xfffffa1a
+#define LCYP		WORD_REF(LCYP_ADDR)
+
+#define LCYP_CYP_MASK	0x01ff		/* Cursor Y Position */
+
+/*
+ * LCD Cursor Width and Heigth Register
+ */
+#define LCWCH_ADDR	0xfffffa1c
+#define LCWCH		WORD_REF(LCWCH_ADDR)
+
+#define LCWCH_CH_MASK	0x001f		/* Cursor Height */
+#define LCWCH_CH_SHIFT	0
+#define LCWCH_CW_MASK	0x1f00		/* Cursor Width */
+#define LCWCH_CW_SHIFT	8
+
+/*
+ * LCD Blink Control Register
+ */
+#define LBLKC_ADDR	0xfffffa1f
+#define LBLKC		BYTE_REF(LBLKC_ADDR)
+
+#define LBLKC_BD_MASK	0x7f	/* Blink Divisor */
+#define LBLKC_BD_SHIFT	0
+#define LBLKC_BKEN	0x80	/* Blink Enabled */
+
+/*
+ * LCD Panel Interface Configuration Register 
+ */
+#define LPICF_ADDR	0xfffffa20
+#define LPICF		BYTE_REF(LPICF_ADDR)
+
+#define LPICF_GS_MASK	 0x03	 /* Gray-Scale Mode */
+#define	  LPICF_GS_BW	   0x00
+#define   LPICF_GS_GRAY_4  0x01
+#define   LPICF_GS_GRAY_16 0x02
+#define LPICF_PBSIZ_MASK 0x0c	/* Panel Bus Width */
+#define   LPICF_PBSIZ_1	   0x00
+#define   LPICF_PBSIZ_2    0x04
+#define   LPICF_PBSIZ_4    0x08
+
+/*
+ * LCD Polarity Configuration Register 
+ */
+#define LPOLCF_ADDR	0xfffffa21
+#define LPOLCF		BYTE_REF(LPOLCF_ADDR)
+
+#define LPOLCF_PIXPOL	0x01	/* Pixel Polarity */
+#define LPOLCF_LPPOL	0x02	/* Line Pulse Polarity */
+#define LPOLCF_FLMPOL	0x04	/* Frame Marker Polarity */
+#define LPOLCF_LCKPOL	0x08	/* LCD Shift Lock Polarity */
+
+/*
+ * LACD (LCD Alternate Crystal Direction) Rate Control Register
+ */
+#define LACDRC_ADDR	0xfffffa23
+#define LACDRC		BYTE_REF(LACDRC_ADDR)
+
+#define LACDRC_ACDSLT	 0x80	/* Signal Source Select */
+#define LACDRC_ACD_MASK	 0x0f	/* Alternate Crystal Direction Control */
+#define LACDRC_ACD_SHIFT 0
+
+/*
+ * LCD Pixel Clock Divider Register
+ */
+#define LPXCD_ADDR	0xfffffa25
+#define LPXCD		BYTE_REF(LPXCD_ADDR)
+
+#define	LPXCD_PCD_MASK	0x3f 	/* Pixel Clock Divider */
+#define LPXCD_PCD_SHIFT	0
+
+/*
+ * LCD Clocking Control Register
+ */
+#define LCKCON_ADDR	0xfffffa27
+#define LCKCON		BYTE_REF(LCKCON_ADDR)
+
+#define LCKCON_DWS_MASK	 0x0f	/* Display Wait-State */
+#define LCKCON_DWS_SHIFT 0
+#define LCKCON_DWIDTH	 0x40	/* Display Memory Width  */
+#define LCKCON_LCDON	 0x80	/* Enable LCD Controller */
+
+/* '328-compatible definitions */
+#define LCKCON_DW_MASK  LCKCON_DWS_MASK
+#define LCKCON_DW_SHIFT LCKCON_DWS_SHIFT
+ 
+/*
+ * LCD Refresh Rate Adjustment Register 
+ */
+#define LRRA_ADDR	0xfffffa29
+#define LRRA		BYTE_REF(LRRA_ADDR)
+
+/*
+ * LCD Panning Offset Register
+ */
+#define LPOSR_ADDR	0xfffffa2d
+#define LPOSR		BYTE_REF(LPOSR_ADDR)
+
+#define LPOSR_POS_MASK	0x0f	/* Pixel Offset Code */
+#define LPOSR_POS_SHIFT	0
+
+/*
+ * LCD Frame Rate Control Modulation Register
+ */
+#define LFRCM_ADDR	0xfffffa31
+#define LFRCM		BYTE_REF(LFRCM_ADDR)
+
+#define LFRCM_YMOD_MASK	 0x0f	/* Vertical Modulation */
+#define LFRCM_YMOD_SHIFT 0
+#define LFRCM_XMOD_MASK	 0xf0	/* Horizontal Modulation */
+#define LFRCM_XMOD_SHIFT 4
+
+/*
+ * LCD Gray Palette Mapping Register
+ */
+#define LGPMR_ADDR	0xfffffa33
+#define LGPMR		BYTE_REF(LGPMR_ADDR)
+
+#define LGPMR_G1_MASK	0x0f
+#define LGPMR_G1_SHIFT	0
+#define LGPMR_G2_MASK	0xf0
+#define LGPMR_G2_SHIFT	4
+
+/* 
+ * PWM Contrast Control Register
+ */
+#define PWMR_ADDR	0xfffffa36
+#define PWMR		WORD_REF(PWMR_ADDR)
+
+#define PWMR_PW_MASK	0x00ff	/* Pulse Width */
+#define PWMR_PW_SHIFT	0
+#define PWMR_CCPEN	0x0100	/* Contrast Control Enable */
+#define PWMR_SRC_MASK	0x0600	/* Input Clock Source */
+#define   PWMR_SRC_LINE	  0x0000	/* Line Pulse  */
+#define   PWMR_SRC_PIXEL  0x0200	/* Pixel Clock */
+#define   PWMR_SRC_LCD    0x4000	/* LCD clock   */
+
+/**********
+ *
+ * 0xFFFFFBxx -- Real-Time Clock (RTC)
+ *
+ **********/
+
+/*
+ * RTC Hours Minutes and Seconds Register
+ */
+#define RTCTIME_ADDR	0xfffffb00
+#define RTCTIME		LONG_REF(RTCTIME_ADDR)
+
+#define RTCTIME_SECONDS_MASK	0x0000003f	/* Seconds */
+#define RTCTIME_SECONDS_SHIFT	0
+#define RTCTIME_MINUTES_MASK	0x003f0000	/* Minutes */
+#define RTCTIME_MINUTES_SHIFT	16
+#define RTCTIME_HOURS_MASK	0x1f000000	/* Hours */
+#define RTCTIME_HOURS_SHIFT	24
+
+/*
+ *  RTC Alarm Register 
+ */
+#define RTCALRM_ADDR    0xfffffb04
+#define RTCALRM         LONG_REF(RTCALRM_ADDR)
+
+#define RTCALRM_SECONDS_MASK    0x0000003f      /* Seconds */
+#define RTCALRM_SECONDS_SHIFT   0
+#define RTCALRM_MINUTES_MASK    0x003f0000      /* Minutes */
+#define RTCALRM_MINUTES_SHIFT   16
+#define RTCALRM_HOURS_MASK      0x1f000000      /* Hours */
+#define RTCALRM_HOURS_SHIFT     24
+
+/*
+ * Watchdog Timer Register 
+ */
+#define WATCHDOG_ADDR	0xfffffb0a
+#define WATCHDOG	WORD_REF(WATCHDOG_ADDR)
+
+#define WATCHDOG_EN	0x0001	/* Watchdog Enabled */
+#define WATCHDOG_ISEL	0x0002	/* Select the watchdog interrupt */
+#define WATCHDOG_INTF	0x0080	/* Watchdog interrupt occcured */
+#define WATCHDOG_CNT_MASK  0x0300	/* Watchdog Counter */
+#define WATCHDOG_CNT_SHIFT 8
+
+/*
+ * RTC Control Register
+ */
+#define RTCCTL_ADDR	0xfffffb0c
+#define RTCCTL		WORD_REF(RTCCTL_ADDR)
+
+#define RTCCTL_XTL	0x0020	/* Crystal Selection */
+#define RTCCTL_EN	0x0080	/* RTC Enable */
+
+/* '328-compatible definitions */
+#define RTCCTL_384	RTCCTL_XTL
+#define RTCCTL_ENABLE	RTCCTL_EN
+
+/*
+ * RTC Interrupt Status Register 
+ */
+#define RTCISR_ADDR	0xfffffb0e
+#define RTCISR		WORD_REF(RTCISR_ADDR)
+
+#define RTCISR_SW	0x0001	/* Stopwatch timed out */
+#define RTCISR_MIN	0x0002	/* 1-minute interrupt has occured */
+#define RTCISR_ALM	0x0004	/* Alarm interrupt has occured */
+#define RTCISR_DAY	0x0008	/* 24-hour rollover interrupt has occured */
+#define RTCISR_1HZ	0x0010	/* 1Hz interrupt has occured */
+#define RTCISR_HR	0x0020	/* 1-hour interrupt has occured */
+#define RTCISR_SAM0	0x0100	/*   4Hz /   4.6875Hz interrupt has occured */ 
+#define RTCISR_SAM1	0x0200	/*   8Hz /   9.3750Hz interrupt has occured */ 
+#define RTCISR_SAM2	0x0400	/*  16Hz /  18.7500Hz interrupt has occured */ 
+#define RTCISR_SAM3	0x0800	/*  32Hz /  37.5000Hz interrupt has occured */ 
+#define RTCISR_SAM4	0x1000	/*  64Hz /  75.0000Hz interrupt has occured */ 
+#define RTCISR_SAM5	0x2000	/* 128Hz / 150.0000Hz interrupt has occured */ 
+#define RTCISR_SAM6	0x4000	/* 256Hz / 300.0000Hz interrupt has occured */ 
+#define RTCISR_SAM7	0x8000	/* 512Hz / 600.0000Hz interrupt has occured */ 
+
+/*
+ * RTC Interrupt Enable Register
+ */
+#define RTCIENR_ADDR	0xfffffb10
+#define RTCIENR		WORD_REF(RTCIENR_ADDR)
+
+#define RTCIENR_SW	0x0001	/* Stopwatch interrupt enable */
+#define RTCIENR_MIN	0x0002	/* 1-minute interrupt enable */
+#define RTCIENR_ALM	0x0004	/* Alarm interrupt enable */
+#define RTCIENR_DAY	0x0008	/* 24-hour rollover interrupt enable */
+#define RTCIENR_1HZ	0x0010	/* 1Hz interrupt enable */
+#define RTCIENR_HR	0x0020	/* 1-hour interrupt enable */
+#define RTCIENR_SAM0	0x0100	/*   4Hz /   4.6875Hz interrupt enable */ 
+#define RTCIENR_SAM1	0x0200	/*   8Hz /   9.3750Hz interrupt enable */ 
+#define RTCIENR_SAM2	0x0400	/*  16Hz /  18.7500Hz interrupt enable */ 
+#define RTCIENR_SAM3	0x0800	/*  32Hz /  37.5000Hz interrupt enable */ 
+#define RTCIENR_SAM4	0x1000	/*  64Hz /  75.0000Hz interrupt enable */ 
+#define RTCIENR_SAM5	0x2000	/* 128Hz / 150.0000Hz interrupt enable */ 
+#define RTCIENR_SAM6	0x4000	/* 256Hz / 300.0000Hz interrupt enable */ 
+#define RTCIENR_SAM7	0x8000	/* 512Hz / 600.0000Hz interrupt enable */ 
+
+/* 
+ * Stopwatch Minutes Register
+ */
+#define STPWCH_ADDR	0xfffffb12
+#define STPWCH		WORD_REF(STPWCH)
+
+#define STPWCH_CNT_MASK	 0x003f	/* Stopwatch countdown value */
+#define SPTWCH_CNT_SHIFT 0
+
+/*
+ * RTC Day Count Register 
+ */
+#define DAYR_ADDR	0xfffffb1a
+#define DAYR		WORD_REF(DAYR_ADDR)
+
+#define DAYR_DAYS_MASK	0x1ff	/* Day Setting */
+#define DAYR_DAYS_SHIFT 0
+
+/*
+ * RTC Day Alarm Register 
+ */
+#define DAYALARM_ADDR	0xfffffb1c
+#define DAYALARM	WORD_REF(DAYALARM_ADDR)
+
+#define DAYALARM_DAYSAL_MASK	0x01ff	/* Day Setting of the Alarm */
+#define DAYALARM_DAYSAL_SHIFT 	0
+
+/**********
+ *
+ * 0xFFFFFCxx -- DRAM Controller
+ *
+ **********/
+
+/*
+ * DRAM Memory Configuration Register 
+ */
+#define DRAMMC_ADDR	0xfffffc00
+#define DRAMMC		WORD_REF(DRAMMC_ADDR)
+
+#define DRAMMC_ROW12_MASK	0xc000	/* Row address bit for MD12 */
+#define   DRAMMC_ROW12_PA10	0x0000
+#define   DRAMMC_ROW12_PA21	0x4000	
+#define   DRAMMC_ROW12_PA23	0x8000
+#define	DRAMMC_ROW0_MASK	0x3000	/* Row address bit for MD0 */
+#define	  DRAMMC_ROW0_PA11	0x0000
+#define   DRAMMC_ROW0_PA22	0x1000
+#define   DRAMMC_ROW0_PA23	0x2000
+#define DRAMMC_ROW11		0x0800	/* Row address bit for MD11 PA20/PA22 */
+#define DRAMMC_ROW10		0x0400	/* Row address bit for MD10 PA19/PA21 */
+#define	DRAMMC_ROW9		0x0200	/* Row address bit for MD9  PA9/PA19  */
+#define DRAMMC_ROW8		0x0100	/* Row address bit for MD8  PA10/PA20 */
+#define DRAMMC_COL10		0x0080	/* Col address bit for MD10 PA11/PA0  */
+#define DRAMMC_COL9		0x0040	/* Col address bit for MD9  PA10/PA0  */
+#define DRAMMC_COL8		0x0020	/* Col address bit for MD8  PA9/PA0   */
+#define DRAMMC_REF_MASK		0x001f	/* Reresh Cycle */
+#define DRAMMC_REF_SHIFT	0
+
+/*
+ * DRAM Control Register
+ */
+#define DRAMC_ADDR	0xfffffc02
+#define DRAMC		WORD_REF(DRAMC_ADDR)
+
+#define DRAMC_DWE	   0x0001	/* DRAM Write Enable */
+#define DRAMC_RST	   0x0002	/* Reset Burst Refresh Enable */
+#define DRAMC_LPR	   0x0004	/* Low-Power Refresh Enable */
+#define DRAMC_SLW	   0x0008	/* Slow RAM */
+#define DRAMC_LSP	   0x0010	/* Light Sleep */
+#define DRAMC_MSW	   0x0020	/* Slow Multiplexing */
+#define DRAMC_WS_MASK	   0x00c0	/* Wait-states */
+#define DRAMC_WS_SHIFT	   6
+#define DRAMC_PGSZ_MASK    0x0300	/* Page Size for fast page mode */
+#define DRAMC_PGSZ_SHIFT   8
+#define   DRAMC_PGSZ_256K  0x0000	
+#define   DRAMC_PGSZ_512K  0x0100
+#define   DRAMC_PGSZ_1024K 0x0200
+#define	  DRAMC_PGSZ_2048K 0x0300
+#define DRAMC_EDO	   0x0400	/* EDO DRAM */
+#define DRAMC_CLK	   0x0800	/* Refresh Timer Clock source select */
+#define DRAMC_BC_MASK	   0x3000	/* Page Access Clock Cycle (FP mode) */
+#define DRAMC_BC_SHIFT	   12
+#define DRAMC_RM	   0x4000	/* Refresh Mode */
+#define DRAMC_EN	   0x8000	/* DRAM Controller enable */
+
+
+/**********
+ *
+ * 0xFFFFFDxx -- In-Circuit Emulation (ICE)
+ *
+ **********/
+
+/*
+ * ICE Module Address Compare Register
+ */
+#define ICEMACR_ADDR	0xfffffd00
+#define ICEMACR		LONG_REF(ICEMACR_ADDR)
+
+/*
+ * ICE Module Address Mask Register
+ */
+#define ICEMAMR_ADDR	0xfffffd04
+#define ICEMAMR		LONG_REF(ICEMAMR_ADDR)
+
+/*
+ * ICE Module Control Compare Register
+ */
+#define ICEMCCR_ADDR	0xfffffd08
+#define ICEMCCR		WORD_REF(ICEMCCR_ADDR)
+
+#define ICEMCCR_PD	0x0001	/* Program/Data Cycle Selection */
+#define ICEMCCR_RW	0x0002	/* Read/Write Cycle Selection */
+
+/*
+ * ICE Module Control Mask Register
+ */
+#define ICEMCMR_ADDR	0xfffffd0a
+#define ICEMCMR		WORD_REF(ICEMCMR_ADDR)
+
+#define ICEMCMR_PDM	0x0001	/* Program/Data Cycle Mask */
+#define ICEMCMR_RWM	0x0002	/* Read/Write Cycle Mask */
+
+/*
+ * ICE Module Control Register 
+ */
+#define ICEMCR_ADDR	0xfffffd0c
+#define ICEMCR		WORD_REF(ICEMCR_ADDR)
+
+#define ICEMCR_CEN	0x0001	/* Compare Enable */
+#define ICEMCR_PBEN	0x0002	/* Program Break Enable */
+#define ICEMCR_SB	0x0004	/* Single Breakpoint */
+#define ICEMCR_HMDIS	0x0008	/* HardMap disable */
+#define ICEMCR_BBIEN	0x0010	/* Bus Break Interrupt Enable */
+
+/*
+ * ICE Module Status Register 
+ */
+#define ICEMSR_ADDR	0xfffffd0e
+#define ICEMSR		WORD_REF(ICEMSR_ADDR)
+
+#define ICEMSR_EMUEN	0x0001	/* Emulation Enable */
+#define ICEMSR_BRKIRQ	0x0002	/* A-Line Vector Fetch Detected */
+#define ICEMSR_BBIRQ	0x0004	/* Bus Break Interrupt Detected */
+#define ICEMSR_EMIRQ	0x0008	/* EMUIRQ Falling Edge Detected */
+
+#endif /* _MC68EZ328_H_ */
diff -Nru a/include/asm-m68knommu/MC68VZ328.h b/include/asm-m68knommu/MC68VZ328.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/MC68VZ328.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,1349 @@
+
+/* include/asm-m68knommu/MC68VZ328.h: 'VZ328 control registers
+ *
+ * Copyright (c) 2000-2001	Lineo Inc. <www.lineo.com>
+ * Copyright (c) 2000-2001	Lineo Canada Corp. <www.lineo.ca>
+ * Copyright (C) 1999		Vladimir Gurevich <vgurevic@cisco.com>
+ * 				Bare & Hare Software, Inc.
+ * Based on include/asm-m68knommu/MC68332.h
+ * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *                     The Silver Hammer Group, Ltd.
+ *
+ * M68VZ328 fixes by Evan Stawnyczy <evan@lineo.com>
+ * vz multiport fixes by Michael Leslie <mleslie@lineo.com>
+ */
+
+#ifndef _MC68VZ328_H_
+#define _MC68VZ328_H_
+
+#define BYTE_REF(addr) (*((volatile unsigned char*)addr))
+#define WORD_REF(addr) (*((volatile unsigned short*)addr))
+#define LONG_REF(addr) (*((volatile unsigned long*)addr))
+
+#define PUT_FIELD(field, val) (((val) << field##_SHIFT) & field##_MASK)
+#define GET_FIELD(reg, field) (((reg) & field##_MASK) >> field##_SHIFT)
+
+/********** 
+ *
+ * 0xFFFFF0xx -- System Control
+ *
+ **********/
+ 
+/*
+ * System Control Register (SCR)
+ */
+#define SCR_ADDR	0xfffff000
+#define SCR		BYTE_REF(SCR_ADDR)
+
+#define SCR_WDTH8	0x01	/* 8-Bit Width Select */
+#define SCR_DMAP	0x04	/* Double Map */
+#define SCR_SO		0x08	/* Supervisor Only */
+#define SCR_BETEN	0x10	/* Bus-Error Time-Out Enable */
+#define SCR_PRV		0x20	/* Privilege Violation */
+#define SCR_WPV		0x40	/* Write Protect Violation */
+#define SCR_BETO	0x80	/* Bus-Error TimeOut */
+
+/*
+ * Silicon ID Register (Mask Revision Register (MRR) for '328 Compatibility)
+ */
+#define MRR_ADDR 0xfffff004
+#define MRR	 LONG_REF(MRR_ADDR)
+
+/********** 
+ *
+ * 0xFFFFF1xx -- Chip-Select logic
+ *
+ **********/
+ 
+/*
+ * Chip Select Group Base Registers 
+ */
+#define CSGBA_ADDR	0xfffff100
+#define CSGBB_ADDR	0xfffff102
+
+#define CSGBC_ADDR	0xfffff104
+#define CSGBD_ADDR	0xfffff106
+
+#define CSGBA		WORD_REF(CSGBA_ADDR)
+#define CSGBB		WORD_REF(CSGBB_ADDR)
+#define CSGBC		WORD_REF(CSGBC_ADDR)
+#define CSGBD		WORD_REF(CSGBD_ADDR)
+
+/*
+ * Chip Select Registers 
+ */
+#define CSA_ADDR	0xfffff110
+#define CSB_ADDR	0xfffff112
+#define CSC_ADDR	0xfffff114
+#define CSD_ADDR	0xfffff116
+
+#define CSA		WORD_REF(CSA_ADDR)
+#define CSB		WORD_REF(CSB_ADDR)
+#define CSC		WORD_REF(CSC_ADDR)
+#define CSD		WORD_REF(CSD_ADDR)
+
+#define CSA_EN		0x0001		/* Chip-Select Enable */
+#define CSA_SIZ_MASK	0x000e		/* Chip-Select Size */
+#define CSA_SIZ_SHIFT   1
+#define CSA_WS_MASK	0x0070		/* Wait State */
+#define CSA_WS_SHIFT    4
+#define CSA_BSW		0x0080		/* Data Bus Width */
+#define CSA_FLASH	0x0100		/* FLASH Memory Support */
+#define CSA_RO		0x8000		/* Read-Only */
+
+#define CSB_EN		0x0001		/* Chip-Select Enable */
+#define CSB_SIZ_MASK	0x000e		/* Chip-Select Size */
+#define CSB_SIZ_SHIFT   1
+#define CSB_WS_MASK	0x0070		/* Wait State */
+#define CSB_WS_SHIFT    4
+#define CSB_BSW		0x0080		/* Data Bus Width */
+#define CSB_FLASH	0x0100		/* FLASH Memory Support */
+#define CSB_UPSIZ_MASK	0x1800		/* Unprotected memory block size */
+#define CSB_UPSIZ_SHIFT 11
+#define CSB_ROP		0x2000		/* Readonly if protected */
+#define CSB_SOP		0x4000		/* Supervisor only if protected */
+#define CSB_RO		0x8000		/* Read-Only */
+
+#define CSC_EN		0x0001		/* Chip-Select Enable */
+#define CSC_SIZ_MASK	0x000e		/* Chip-Select Size */
+#define CSC_SIZ_SHIFT   1
+#define CSC_WS_MASK	0x0070		/* Wait State */
+#define CSC_WS_SHIFT    4
+#define CSC_BSW		0x0080		/* Data Bus Width */
+#define CSC_FLASH	0x0100		/* FLASH Memory Support */
+#define CSC_UPSIZ_MASK	0x1800		/* Unprotected memory block size */
+#define CSC_UPSIZ_SHIFT 11
+#define CSC_ROP		0x2000		/* Readonly if protected */
+#define CSC_SOP		0x4000		/* Supervisor only if protected */
+#define CSC_RO		0x8000		/* Read-Only */
+
+#define CSD_EN		0x0001		/* Chip-Select Enable */
+#define CSD_SIZ_MASK	0x000e		/* Chip-Select Size */
+#define CSD_SIZ_SHIFT   1
+#define CSD_WS_MASK	0x0070		/* Wait State */
+#define CSD_WS_SHIFT    4
+#define CSD_BSW		0x0080		/* Data Bus Width */
+#define CSD_FLASH	0x0100		/* FLASH Memory Support */
+#define CSD_DRAM	0x0200		/* Dram Selection */
+#define	CSD_COMB	0x0400		/* Combining */
+#define CSD_UPSIZ_MASK	0x1800		/* Unprotected memory block size */
+#define CSD_UPSIZ_SHIFT 11
+#define CSD_ROP		0x2000		/* Readonly if protected */
+#define CSD_SOP		0x4000		/* Supervisor only if protected */
+#define CSD_RO		0x8000		/* Read-Only */
+
+/*
+ * Emulation Chip-Select Register 
+ */
+#define EMUCS_ADDR	0xfffff118
+#define EMUCS		WORD_REF(EMUCS_ADDR)
+
+#define EMUCS_WS_MASK	0x0070
+#define EMUCS_WS_SHIFT	4
+
+/********** 
+ *
+ * 0xFFFFF2xx -- Phase Locked Loop (PLL) & Power Control
+ *
+ **********/
+
+/*
+ * PLL Control Register 
+ */
+#define PLLCR_ADDR	0xfffff200
+#define PLLCR		WORD_REF(PLLCR_ADDR)
+
+#define PLLCR_DISPLL	       0x0008	/* Disable PLL */
+#define PLLCR_CLKEN	       0x0010	/* Clock (CLKO pin) enable */
+#define PLLCR_PRESC	       0x0020	/* VCO prescaler */
+#define PLLCR_SYSCLK_SEL_MASK  0x0700	/* System Clock Selection */
+#define PLLCR_SYSCLK_SEL_SHIFT 8
+#define PLLCR_LCDCLK_SEL_MASK  0x3800	/* LCD Clock Selection */
+#define PLLCR_LCDCLK_SEL_SHIFT 11
+
+/* '328-compatible definitions */
+#define PLLCR_PIXCLK_SEL_MASK	PLLCR_LCDCLK_SEL_MASK
+#define PLLCR_PIXCLK_SEL_SHIFT	PLLCR_LCDCLK_SEL_SHIFT
+
+/*
+ * PLL Frequency Select Register
+ */
+#define PLLFSR_ADDR	0xfffff202
+#define PLLFSR		WORD_REF(PLLFSR_ADDR)
+
+#define PLLFSR_PC_MASK	0x00ff		/* P Count */
+#define PLLFSR_PC_SHIFT 0
+#define PLLFSR_QC_MASK	0x0f00		/* Q Count */
+#define PLLFSR_QC_SHIFT 8
+#define PLLFSR_PROT	0x4000		/* Protect P & Q */
+#define PLLFSR_CLK32	0x8000		/* Clock 32 (kHz) */
+
+/*
+ * Power Control Register
+ */
+#define PCTRL_ADDR	0xfffff207
+#define PCTRL		BYTE_REF(PCTRL_ADDR)
+
+#define PCTRL_WIDTH_MASK	0x1f	/* CPU Clock bursts width */
+#define PCTRL_WIDTH_SHIFT	0
+#define PCTRL_PCEN		0x80	/* Power Control Enable */
+
+/**********
+ *
+ * 0xFFFFF3xx -- Interrupt Controller
+ *
+ **********/
+
+/* 
+ * Interrupt Vector Register
+ */
+#define IVR_ADDR	0xfffff300
+#define IVR		BYTE_REF(IVR_ADDR)
+
+#define IVR_VECTOR_MASK 0xF8
+
+/*
+ * Interrupt control Register
+ */
+#define ICR_ADDR	0xfffff302
+#define ICR		WORD_REF(ICR_ADDR)
+
+#define ICR_POL5	0x0080	/* Polarity Control for IRQ5 */
+#define ICR_ET6		0x0100	/* Edge Trigger Select for IRQ6 */
+#define ICR_ET3		0x0200	/* Edge Trigger Select for IRQ3 */
+#define ICR_ET2		0x0400	/* Edge Trigger Select for IRQ2 */
+#define ICR_ET1		0x0800	/* Edge Trigger Select for IRQ1 */
+#define ICR_POL6	0x1000	/* Polarity Control for IRQ6 */
+#define ICR_POL3	0x2000	/* Polarity Control for IRQ3 */
+#define ICR_POL2	0x4000	/* Polarity Control for IRQ2 */
+#define ICR_POL1	0x8000	/* Polarity Control for IRQ1 */
+
+/*
+ * Interrupt Mask Register
+ */
+#define IMR_ADDR	0xfffff304
+#define IMR		LONG_REF(IMR_ADDR)
+
+/*
+ * Define the names for bit positions first. This is useful for 
+ * request_irq
+ */
+#define SPI2_IRQ_NUM	0	/* SPI 2 interrupt */
+#define TMR_IRQ_NUM	1	/* Timer 1 interrupt */
+#define UART1_IRQ_NUM	2	/* UART 1 interrupt */	
+#define	WDT_IRQ_NUM	3	/* Watchdog Timer interrupt */
+#define RTC_IRQ_NUM	4	/* RTC interrupt */
+#define TMR2_IRQ_NUM	5	/* Timer 2 interrupt */
+#define	KB_IRQ_NUM	6	/* Keyboard Interrupt */
+#define PWM1_IRQ_NUM	7	/* Pulse-Width Modulator 1 int. */
+#define	INT0_IRQ_NUM	8	/* External INT0 */
+#define	INT1_IRQ_NUM	9	/* External INT1 */
+#define	INT2_IRQ_NUM	10	/* External INT2 */
+#define	INT3_IRQ_NUM	11	/* External INT3 */
+#define UART2_IRQ_NUM	12	/* UART 2 interrupt */	
+#define PWM2_IRQ_NUM	13	/* Pulse-Width Modulator 1 int. */
+#define IRQ1_IRQ_NUM	16	/* IRQ1 */
+#define IRQ2_IRQ_NUM	17	/* IRQ2 */
+#define IRQ3_IRQ_NUM	18	/* IRQ3 */
+#define IRQ6_IRQ_NUM	19	/* IRQ6 */
+#define IRQ5_IRQ_NUM	20	/* IRQ5 */
+#define SPI1_IRQ_NUM	21	/* SPI 1 interrupt */
+#define SAM_IRQ_NUM	22	/* Sampling Timer for RTC */
+#define EMIQ_IRQ_NUM	23	/* Emulator Interrupt */
+
+#define SPI_IRQ_NUM	SPI2_IRQ_NUM
+
+/* '328-compatible definitions */
+#define SPIM_IRQ_NUM	SPI_IRQ_NUM
+#define TMR1_IRQ_NUM	TMR_IRQ_NUM
+#define UART_IRQ_NUM	UART1_IRQ_NUM
+
+/* 
+ * Here go the bitmasks themselves
+ */
+#define IMR_MSPI 	(1 << SPI_IRQ_NUM)	/* Mask SPI interrupt */
+#define	IMR_MTMR	(1 << TMR_IRQ_NUM)	/* Mask Timer interrupt */
+#define IMR_MUART	(1 << UART_IRQ_NUM)	/* Mask UART interrupt */	
+#define	IMR_MWDT	(1 << WDT_IRQ_NUM)	/* Mask Watchdog Timer interrupt */
+#define IMR_MRTC	(1 << RTC_IRQ_NUM)	/* Mask RTC interrupt */
+#define	IMR_MKB		(1 << KB_IRQ_NUM)	/* Mask Keyboard Interrupt */
+#define IMR_MPWM	(1 << PWM_IRQ_NUM)	/* Mask Pulse-Width Modulator int. */
+#define	IMR_MINT0	(1 << INT0_IRQ_NUM)	/* Mask External INT0 */
+#define	IMR_MINT1	(1 << INT1_IRQ_NUM)	/* Mask External INT1 */
+#define	IMR_MINT2	(1 << INT2_IRQ_NUM)	/* Mask External INT2 */
+#define	IMR_MINT3	(1 << INT3_IRQ_NUM)	/* Mask External INT3 */
+#define IMR_MIRQ1	(1 << IRQ1_IRQ_NUM)	/* Mask IRQ1 */
+#define IMR_MIRQ2	(1 << IRQ2_IRQ_NUM)	/* Mask IRQ2 */
+#define IMR_MIRQ3	(1 << IRQ3_IRQ_NUM)	/* Mask IRQ3 */
+#define IMR_MIRQ6	(1 << IRQ6_IRQ_NUM)	/* Mask IRQ6 */
+#define IMR_MIRQ5	(1 << IRQ5_IRQ_NUM)	/* Mask IRQ5 */
+#define IMR_MSAM	(1 << SAM_IRQ_NUM)	/* Mask Sampling Timer for RTC */
+#define IMR_MEMIQ	(1 << EMIQ_IRQ_NUM)	/* Mask Emulator Interrupt */
+
+/* '328-compatible definitions */
+#define IMR_MSPIM	IMR_MSPI
+#define IMR_MTMR1	IMR_MTMR
+
+/* 
+ * Interrupt Status Register 
+ */
+#define ISR_ADDR	0xfffff30c
+#define ISR		LONG_REF(ISR_ADDR)
+
+#define ISR_SPI 	(1 << SPI_IRQ_NUM)	/* SPI interrupt */
+#define	ISR_TMR		(1 << TMR_IRQ_NUM)	/* Timer interrupt */
+#define ISR_UART	(1 << UART_IRQ_NUM)	/* UART interrupt */	
+#define	ISR_WDT		(1 << WDT_IRQ_NUM)	/* Watchdog Timer interrupt */
+#define ISR_RTC		(1 << RTC_IRQ_NUM)	/* RTC interrupt */
+#define	ISR_KB		(1 << KB_IRQ_NUM)	/* Keyboard Interrupt */
+#define ISR_PWM		(1 << PWM_IRQ_NUM)	/* Pulse-Width Modulator interrupt */
+#define	ISR_INT0	(1 << INT0_IRQ_NUM)	/* External INT0 */
+#define	ISR_INT1	(1 << INT1_IRQ_NUM)	/* External INT1 */
+#define	ISR_INT2	(1 << INT2_IRQ_NUM)	/* External INT2 */
+#define	ISR_INT3	(1 << INT3_IRQ_NUM)	/* External INT3 */
+#define ISR_IRQ1	(1 << IRQ1_IRQ_NUM)	/* IRQ1 */
+#define ISR_IRQ2	(1 << IRQ2_IRQ_NUM)	/* IRQ2 */
+#define ISR_IRQ3	(1 << IRQ3_IRQ_NUM)	/* IRQ3 */
+#define ISR_IRQ6	(1 << IRQ6_IRQ_NUM)	/* IRQ6 */
+#define ISR_IRQ5	(1 << IRQ5_IRQ_NUM)	/* IRQ5 */
+#define ISR_SAM		(1 << SAM_IRQ_NUM)	/* Sampling Timer for RTC */
+#define ISR_EMIQ	(1 << EMIQ_IRQ_NUM)	/* Emulator Interrupt */
+
+/* '328-compatible definitions */
+#define ISR_SPIM	ISR_SPI
+#define ISR_TMR1	ISR_TMR
+
+/* 
+ * Interrupt Pending Register 
+ */
+#define IPR_ADDR	0xfffff30c
+#define IPR		LONG_REF(IPR_ADDR)
+
+#define IPR_SPI 	(1 << SPI_IRQ_NUM)	/* SPI interrupt */
+#define	IPR_TMR		(1 << TMR_IRQ_NUM)	/* Timer interrupt */
+#define IPR_UART	(1 << UART_IRQ_NUM)	/* UART interrupt */	
+#define	IPR_WDT		(1 << WDT_IRQ_NUM)	/* Watchdog Timer interrupt */
+#define IPR_RTC		(1 << RTC_IRQ_NUM)	/* RTC interrupt */
+#define	IPR_KB		(1 << KB_IRQ_NUM)	/* Keyboard Interrupt */
+#define IPR_PWM		(1 << PWM_IRQ_NUM)	/* Pulse-Width Modulator interrupt */
+#define	IPR_INT0	(1 << INT0_IRQ_NUM)	/* External INT0 */
+#define	IPR_INT1	(1 << INT1_IRQ_NUM)	/* External INT1 */
+#define	IPR_INT2	(1 << INT2_IRQ_NUM)	/* External INT2 */
+#define	IPR_INT3	(1 << INT3_IRQ_NUM)	/* External INT3 */
+#define IPR_IRQ1	(1 << IRQ1_IRQ_NUM)	/* IRQ1 */
+#define IPR_IRQ2	(1 << IRQ2_IRQ_NUM)	/* IRQ2 */
+#define IPR_IRQ3	(1 << IRQ3_IRQ_NUM)	/* IRQ3 */
+#define IPR_IRQ6	(1 << IRQ6_IRQ_NUM)	/* IRQ6 */
+#define IPR_IRQ5	(1 << IRQ5_IRQ_NUM)	/* IRQ5 */
+#define IPR_SAM		(1 << SAM_IRQ_NUM)	/* Sampling Timer for RTC */
+#define IPR_EMIQ	(1 << EMIQ_IRQ_NUM)	/* Emulator Interrupt */
+
+/* '328-compatible definitions */
+#define IPR_SPIM	IPR_SPI
+#define IPR_TMR1	IPR_TMR
+
+/**********
+ *
+ * 0xFFFFF4xx -- Parallel Ports
+ *
+ **********/
+
+/*
+ * Port A
+ */
+#define PADIR_ADDR	0xfffff400		/* Port A direction reg */
+#define PADATA_ADDR	0xfffff401		/* Port A data register */
+#define PAPUEN_ADDR	0xfffff402		/* Port A Pull-Up enable reg */
+
+#define PADIR		BYTE_REF(PADIR_ADDR)
+#define PADATA		BYTE_REF(PADATA_ADDR)
+#define PAPUEN		BYTE_REF(PAPUEN_ADDR)
+
+#define PA(x)		(1 << (x))
+
+/* 
+ * Port B
+ */
+#define PBDIR_ADDR	0xfffff408		/* Port B direction reg */
+#define PBDATA_ADDR	0xfffff409		/* Port B data register */
+#define PBPUEN_ADDR	0xfffff40a		/* Port B Pull-Up enable reg */
+#define PBSEL_ADDR	0xfffff40b		/* Port B Select Register */
+
+#define PBDIR		BYTE_REF(PBDIR_ADDR)
+#define PBDATA		BYTE_REF(PBDATA_ADDR)
+#define PBPUEN		BYTE_REF(PBPUEN_ADDR)
+#define PBSEL		BYTE_REF(PBSEL_ADDR)
+
+#define PB(x)		(1 << (x))
+
+#define PB_CSB0		0x01	/* Use CSB0      as PB[0] */
+#define PB_CSB1		0x02	/* Use CSB1      as PB[1] */
+#define PB_CSC0_RAS0	0x04    /* Use CSC0/RAS0 as PB[2] */	
+#define PB_CSC1_RAS1	0x08    /* Use CSC1/RAS1 as PB[3] */	
+#define PB_CSD0_CAS0	0x10    /* Use CSD0/CAS0 as PB[4] */	
+#define PB_CSD1_CAS1	0x20    /* Use CSD1/CAS1 as PB[5] */
+#define PB_TIN_TOUT	0x40	/* Use TIN/TOUT  as PB[6] */
+#define PB_PWMO		0x80	/* Use PWMO      as PB[7] */
+
+/* 
+ * Port C
+ */
+#define PCDIR_ADDR	0xfffff410		/* Port C direction reg */
+#define PCDATA_ADDR	0xfffff411		/* Port C data register */
+#define PCPDEN_ADDR	0xfffff412		/* Port C Pull-Down enb. reg */
+#define PCSEL_ADDR	0xfffff413		/* Port C Select Register */
+
+#define PCDIR		BYTE_REF(PCDIR_ADDR)
+#define PCDATA		BYTE_REF(PCDATA_ADDR)
+#define PCPDEN		BYTE_REF(PCPDEN_ADDR)
+#define PCSEL		BYTE_REF(PCSEL_ADDR)
+
+#define PC(x)		(1 << (x))
+
+#define PC_LD0		0x01	/* Use LD0  as PC[0] */
+#define PC_LD1		0x02	/* Use LD1  as PC[1] */
+#define PC_LD2		0x04	/* Use LD2  as PC[2] */
+#define PC_LD3		0x08	/* Use LD3  as PC[3] */
+#define PC_LFLM		0x10	/* Use LFLM as PC[4] */
+#define PC_LLP 		0x20	/* Use LLP  as PC[5] */
+#define PC_LCLK		0x40	/* Use LCLK as PC[6] */
+#define PC_LACD		0x80	/* Use LACD as PC[7] */
+
+/* 
+ * Port D
+ */
+#define PDDIR_ADDR	0xfffff418		/* Port D direction reg */
+#define PDDATA_ADDR	0xfffff419		/* Port D data register */
+#define PDPUEN_ADDR	0xfffff41a		/* Port D Pull-Up enable reg */
+#define PDSEL_ADDR	0xfffff41b		/* Port D Select Register */
+#define PDPOL_ADDR	0xfffff41c		/* Port D Polarity Register */
+#define PDIRQEN_ADDR	0xfffff41d		/* Port D IRQ enable register */
+#define PDKBEN_ADDR	0xfffff41e		/* Port D Keyboard Enable reg */
+#define	PDIQEG_ADDR	0xfffff41f		/* Port D IRQ Edge Register */
+
+#define PDDIR		BYTE_REF(PDDIR_ADDR)
+#define PDDATA		BYTE_REF(PDDATA_ADDR)
+#define PDPUEN		BYTE_REF(PDPUEN_ADDR)
+#define PDSEL		BYTE_REF(PDSEL_ADDR)
+#define	PDPOL		BYTE_REF(PDPOL_ADDR)
+#define PDIRQEN		BYTE_REF(PDIRQEN_ADDR)
+#define PDKBEN		BYTE_REF(PDKBEN_ADDR)
+#define PDIQEG		BYTE_REF(PDIQEG_ADDR)
+
+#define PD(x)		(1 << (x))
+
+#define PD_INT0		0x01	/* Use INT0 as PD[0] */
+#define PD_INT1		0x02	/* Use INT1 as PD[1] */
+#define PD_INT2		0x04	/* Use INT2 as PD[2] */
+#define PD_INT3		0x08	/* Use INT3 as PD[3] */
+#define PD_IRQ1		0x10	/* Use IRQ1 as PD[4] */
+#define PD_IRQ2		0x20	/* Use IRQ2 as PD[5] */
+#define PD_IRQ3		0x40	/* Use IRQ3 as PD[6] */
+#define PD_IRQ6		0x80	/* Use IRQ6 as PD[7] */
+
+/* 
+ * Port E
+ */
+#define PEDIR_ADDR	0xfffff420		/* Port E direction reg */
+#define PEDATA_ADDR	0xfffff421		/* Port E data register */
+#define PEPUEN_ADDR	0xfffff422		/* Port E Pull-Up enable reg */
+#define PESEL_ADDR	0xfffff423		/* Port E Select Register */
+
+#define PEDIR		BYTE_REF(PEDIR_ADDR)
+#define PEDATA		BYTE_REF(PEDATA_ADDR)
+#define PEPUEN		BYTE_REF(PEPUEN_ADDR)
+#define PESEL		BYTE_REF(PESEL_ADDR)
+
+#define PE(x)		(1 << (x))
+
+#define PE_SPMTXD	0x01	/* Use SPMTXD as PE[0] */
+#define PE_SPMRXD	0x02	/* Use SPMRXD as PE[1] */
+#define PE_SPMCLK	0x04	/* Use SPMCLK as PE[2] */
+#define PE_DWE		0x08	/* Use DWE    as PE[3] */
+#define PE_RXD		0x10	/* Use RXD    as PE[4] */
+#define PE_TXD		0x20	/* Use TXD    as PE[5] */
+#define PE_RTS		0x40	/* Use RTS    as PE[6] */
+#define PE_CTS		0x80	/* Use CTS    as PE[7] */
+
+/* 
+ * Port F
+ */
+#define PFDIR_ADDR	0xfffff428		/* Port F direction reg */
+#define PFDATA_ADDR	0xfffff429		/* Port F data register */
+#define PFPUEN_ADDR	0xfffff42a		/* Port F Pull-Up enable reg */
+#define PFSEL_ADDR	0xfffff42b		/* Port F Select Register */
+
+#define PFDIR		BYTE_REF(PFDIR_ADDR)
+#define PFDATA		BYTE_REF(PFDATA_ADDR)
+#define PFPUEN		BYTE_REF(PFPUEN_ADDR)
+#define PFSEL		BYTE_REF(PFSEL_ADDR)
+
+#define PF(x)		(1 << (x))
+
+#define PF_LCONTRAST	0x01	/* Use LCONTRAST as PF[0] */
+#define PF_IRQ5         0x02    /* Use IRQ5      as PF[1] */
+#define PF_CLKO         0x04    /* Use CLKO      as PF[2] */
+#define PF_A20          0x08    /* Use A20       as PF[3] */
+#define PF_A21          0x10    /* Use A21       as PF[4] */
+#define PF_A22          0x20    /* Use A22       as PF[5] */
+#define PF_A23          0x40    /* Use A23       as PF[6] */
+#define PF_CSA1		0x80    /* Use CSA1      as PF[7] */
+
+/* 
+ * Port G
+ */
+#define PGDIR_ADDR	0xfffff430		/* Port G direction reg */
+#define PGDATA_ADDR	0xfffff431		/* Port G data register */
+#define PGPUEN_ADDR	0xfffff432		/* Port G Pull-Up enable reg */
+#define PGSEL_ADDR	0xfffff433		/* Port G Select Register */
+
+#define PGDIR		BYTE_REF(PGDIR_ADDR)
+#define PGDATA		BYTE_REF(PGDATA_ADDR)
+#define PGPUEN		BYTE_REF(PGPUEN_ADDR)
+#define PGSEL		BYTE_REF(PGSEL_ADDR)
+
+#define PG(x)		(1 << (x))
+
+#define PG_BUSW_DTACK	0x01	/* Use BUSW/DTACK as PG[0] */
+#define PG_A0		0x02	/* Use A0         as PG[1] */
+#define PG_EMUIRQ	0x04	/* Use EMUIRQ     as PG[2] */
+#define PG_HIZ_P_D	0x08	/* Use HIZ/P/D    as PG[3] */
+#define PG_EMUCS        0x10	/* Use EMUCS      as PG[4] */
+#define PG_EMUBRK	0x20	/* Use EMUBRK     as PG[5] */
+
+/* 
+ * Port J
+ */
+#define PJDIR_ADDR	0xfffff438		/* Port J direction reg */
+#define PJDATA_ADDR	0xfffff439		/* Port J data register */
+#define PJPUEN_ADDR	0xfffff43A		/* Port J Pull-Up enb. reg */
+#define PJSEL_ADDR	0xfffff43B		/* Port J Select Register */
+
+#define PJDIR		BYTE_REF(PJDIR_ADDR)
+#define PJDATA		BYTE_REF(PJDATA_ADDR)
+#define PJPUEN		BYTE_REF(PJPUEN_ADDR)
+#define PJSEL		BYTE_REF(PJSEL_ADDR)
+
+#define PJ(x)		(1 << (x))
+
+/*
+ * Port K
+ */
+#define PKDIR_ADDR	0xfffff440		/* Port K direction reg */
+#define PKDATA_ADDR	0xfffff441		/* Port K data register */
+#define PKPUEN_ADDR	0xfffff442		/* Port K Pull-Up enb. reg */
+#define PKSEL_ADDR	0xfffff443		/* Port K Select Register */
+
+#define PKDIR		BYTE_REF(PKDIR_ADDR)
+#define PKDATA		BYTE_REF(PKDATA_ADDR)
+#define PKPUEN		BYTE_REF(PKPUEN_ADDR)
+#define PKSEL		BYTE_REF(PKSEL_ADDR)
+
+#define PK(x)		(1 << (x))
+
+#define PK_DATAREADY		0x01	/* Use ~DATA_READY  as PK[0] */
+#define PK_PWM2		0x01	/* Use PWM2  as PK[0] */
+#define PK_R_W		0x02	/* Use R/W  as PK[1] */
+#define PK_LDS		0x04	/* Use /LDS  as PK[2] */
+#define PK_UDS		0x08	/* Use /UDS  as PK[3] */
+#define PK_LD4		0x10	/* Use LD4 as PK[4] */
+#define PK_LD5 		0x20	/* Use LD5  as PK[5] */
+#define PK_LD6		0x40	/* Use LD6 as PK[6] */
+#define PK_LD7		0x80	/* Use LD7 as PK[7] */
+
+#define PJDIR_ADDR	0xfffff438		/* Port J direction reg */
+#define PJDATA_ADDR	0xfffff439		/* Port J data register */
+#define PJPUEN_ADDR	0xfffff43A		/* Port J Pull-Up enable reg */
+#define PJSEL_ADDR	0xfffff43B		/* Port J Select Register */
+
+#define PJDIR		BYTE_REF(PJDIR_ADDR)
+#define PJDATA		BYTE_REF(PJDATA_ADDR)
+#define PJPUEN		BYTE_REF(PJPUEN_ADDR)
+#define PJSEL		BYTE_REF(PJSEL_ADDR)
+
+#define PJ(x)		(1 << (x))
+
+#define PJ_MOSI 	0x01	/* Use MOSI       as PJ[0] */
+#define PJ_MISO		0x02	/* Use MISO       as PJ[1] */
+#define PJ_SPICLK1  	0x04	/* Use SPICLK1    as PJ[2] */
+#define PJ_SS   	0x08	/* Use SS         as PJ[3] */
+#define PJ_RXD2         0x10	/* Use RXD2       as PJ[4] */
+#define PJ_TXD2  	0x20	/* Use TXD2       as PJ[5] */
+#define PJ_RTS2  	0x40	/* Use RTS2       as PJ[5] */
+#define PJ_CTS2  	0x80	/* Use CTS2       as PJ[5] */
+
+/*
+ * Port M
+ */
+#define PMDIR_ADDR	0xfffff448		/* Port M direction reg */
+#define PMDATA_ADDR	0xfffff449		/* Port M data register */
+#define PMPUEN_ADDR	0xfffff44a		/* Port M Pull-Up enable reg */
+#define PMSEL_ADDR	0xfffff44b		/* Port M Select Register */
+
+#define PMDIR		BYTE_REF(PMDIR_ADDR)
+#define PMDATA		BYTE_REF(PMDATA_ADDR)
+#define PMPUEN		BYTE_REF(PMPUEN_ADDR)
+#define PMSEL		BYTE_REF(PMSEL_ADDR)
+
+#define PM(x)		(1 << (x))
+
+#define PM_SDCLK	0x01	/* Use SDCLK      as PM[0] */
+#define PM_SDCE		0x02	/* Use SDCE       as PM[1] */
+#define PM_DQMH 	0x04	/* Use DQMH       as PM[2] */
+#define PM_DQML 	0x08	/* Use DQML       as PM[3] */
+#define PM_SDA10        0x10	/* Use SDA10      as PM[4] */
+#define PM_DMOE 	0x20	/* Use DMOE       as PM[5] */
+
+/**********
+ *
+ * 0xFFFFF5xx -- Pulse-Width Modulator (PWM)
+ *
+ **********/
+
+/*
+ * PWM Control Register
+ */
+#define PWMC_ADDR	0xfffff500
+#define PWMC		WORD_REF(PWMC_ADDR)
+
+#define PWMC_CLKSEL_MASK	0x0003	/* Clock Selection */
+#define PWMC_CLKSEL_SHIFT	0
+#define PWMC_REPEAT_MASK	0x000c	/* Sample Repeats */
+#define PWMC_REPEAT_SHIFT	2
+#define PWMC_EN			0x0010	/* Enable PWM */
+#define PMNC_FIFOAV		0x0020	/* FIFO Available */
+#define PWMC_IRQEN		0x0040	/* Interrupt Request Enable */
+#define PWMC_IRQ		0x0080	/* Interrupt Request (FIFO empty) */
+#define PWMC_PRESCALER_MASK	0x7f00	/* Incoming Clock prescaler */
+#define PWMC_PRESCALER_SHIFT	8
+#define PWMC_CLKSRC		0x8000	/* Clock Source Select */
+
+/* '328-compatible definitions */
+#define PWMC_PWMEN	PWMC_EN
+
+/*
+ * PWM Sample Register 
+ */
+#define PWMS_ADDR	0xfffff502
+#define PWMS		WORD_REF(PWMS_ADDR)
+
+/*
+ * PWM Period Register
+ */
+#define PWMP_ADDR	0xfffff504
+#define PWMP		BYTE_REF(PWMP_ADDR)
+
+/*
+ * PWM Counter Register
+ */
+#define PWMCNT_ADDR	0xfffff505
+#define PWMCNT		BYTE_REF(PWMCNT_ADDR)
+
+/**********
+ *
+ * 0xFFFFF6xx -- General-Purpose Timer
+ *
+ **********/
+
+/* 
+ * Timer Control register
+ */
+#define TCTL_ADDR	0xfffff600
+#define TCTL		WORD_REF(TCTL_ADDR)
+
+#define	TCTL_TEN		0x0001	/* Timer Enable  */
+#define TCTL_CLKSOURCE_MASK 	0x000e	/* Clock Source: */
+#define   TCTL_CLKSOURCE_STOP	   0x0000	/* Stop count (disabled)    */
+#define   TCTL_CLKSOURCE_SYSCLK	   0x0002	/* SYSCLK to prescaler      */
+#define   TCTL_CLKSOURCE_SYSCLK_16 0x0004	/* SYSCLK/16 to prescaler   */
+#define   TCTL_CLKSOURCE_TIN	   0x0006	/* TIN to prescaler         */
+#define   TCTL_CLKSOURCE_32KHZ	   0x0008	/* 32kHz clock to prescaler */
+#define TCTL_IRQEN		0x0010	/* IRQ Enable    */
+#define TCTL_OM			0x0020	/* Output Mode   */
+#define TCTL_CAP_MASK		0x00c0	/* Capture Edge: */
+#define	  TCTL_CAP_RE		0x0040		/* Capture on rizing edge   */
+#define   TCTL_CAP_FE		0x0080		/* Capture on falling edge  */
+#define TCTL_FRR		0x0010	/* Free-Run Mode */
+
+/* '328-compatible definitions */
+#define TCTL1_ADDR	TCTL_ADDR
+#define TCTL1		TCTL
+
+/*
+ * Timer Prescaler Register
+ */
+#define TPRER_ADDR	0xfffff602
+#define TPRER		WORD_REF(TPRER_ADDR)
+
+/* '328-compatible definitions */
+#define TPRER1_ADDR	TPRER_ADDR
+#define TPRER1		TPRER
+
+/*
+ * Timer Compare Register
+ */
+#define TCMP_ADDR	0xfffff604
+#define TCMP		WORD_REF(TCMP_ADDR)
+
+/* '328-compatible definitions */
+#define TCMP1_ADDR	TCMP_ADDR
+#define TCMP1		TCMP
+
+/*
+ * Timer Capture register
+ */
+#define TCR_ADDR	0xfffff606
+#define TCR		WORD_REF(TCR_ADDR)
+
+/* '328-compatible definitions */
+#define TCR1_ADDR	TCR_ADDR
+#define TCR1		TCR
+
+/*
+ * Timer Counter Register
+ */
+#define TCN_ADDR	0xfffff608
+#define TCN		WORD_REF(TCN_ADDR)
+
+/* '328-compatible definitions */
+#define TCN1_ADDR	TCN_ADDR
+#define TCN1		TCN
+
+/*
+ * Timer Status Register
+ */
+#define TSTAT_ADDR	0xfffff60a
+#define TSTAT		WORD_REF(TSTAT_ADDR)
+
+#define TSTAT_COMP	0x0001		/* Compare Event occurred */
+#define TSTAT_CAPT	0x0001		/* Capture Event occurred */
+
+/* '328-compatible definitions */
+#define TSTAT1_ADDR	TSTAT_ADDR
+#define TSTAT1		TSTAT
+
+/**********
+ *
+ * 0xFFFFF8xx -- Serial Periferial Interface Master (SPIM)
+ *
+ **********/
+
+/*
+ * SPIM Data Register
+ */
+#define SPIMDATA_ADDR	0xfffff800
+#define SPIMDATA	WORD_REF(SPIMDATA_ADDR)
+
+/*
+ * SPIM Control/Status Register
+ */
+#define SPIMCONT_ADDR	0xfffff802
+#define SPIMCONT	WORD_REF(SPIMCONT_ADDR)
+
+#define SPIMCONT_BIT_COUNT_MASK	 0x000f	/* Transfer Length in Bytes */
+#define SPIMCONT_BIT_COUNT_SHIFT 0
+#define SPIMCONT_POL		 0x0010	/* SPMCLK Signel Polarity */
+#define	SPIMCONT_PHA		 0x0020	/* Clock/Data phase relationship */
+#define SPIMCONT_IRQEN		 0x0040 /* IRQ Enable */
+#define SPIMCONT_IRQ		 0x0080	/* Interrupt Request */
+#define SPIMCONT_XCH		 0x0100	/* Exchange */
+#define SPIMCONT_ENABLE		 0x0200	/* Enable SPIM */
+#define SPIMCONT_DATA_RATE_MASK	 0xe000	/* SPIM Data Rate */
+#define SPIMCONT_DATA_RATE_SHIFT 13
+
+/* '328-compatible definitions */
+#define SPIMCONT_SPIMIRQ	SPIMCONT_IRQ
+#define SPIMCONT_SPIMEN		SPIMCONT_ENABLE
+
+/**********
+ *
+ * 0xFFFFF9xx -- UART
+ *
+ **********/
+
+/*
+ * UART Status/Control Register
+ */
+
+#define USTCNT_ADDR	0xfffff900
+#define USTCNT		WORD_REF(USTCNT_ADDR)
+
+#define USTCNT_TXAE	0x0001	/* Transmitter Available Interrupt Enable */
+#define USTCNT_TXHE	0x0002	/* Transmitter Half Empty Enable */
+#define USTCNT_TXEE	0x0004	/* Transmitter Empty Interrupt Enable */
+#define USTCNT_RXRE	0x0008	/* Receiver Ready Interrupt Enable */
+#define USTCNT_RXHE	0x0010	/* Receiver Half-Full Interrupt Enable */
+#define USTCNT_RXFE	0x0020	/* Receiver Full Interrupt Enable */
+#define USTCNT_CTSD	0x0040	/* CTS Delta Interrupt Enable */
+#define USTCNT_ODEN	0x0080	/* Old Data Interrupt Enable */
+#define USTCNT_8_7	0x0100	/* Eight or seven-bit transmission */
+#define USTCNT_STOP	0x0200	/* Stop bit transmission */
+#define USTCNT_ODD	0x0400	/* Odd Parity */
+#define	USTCNT_PEN	0x0800	/* Parity Enable */
+#define USTCNT_CLKM	0x1000	/* Clock Mode Select */
+#define	USTCNT_TXEN	0x2000	/* Transmitter Enable */
+#define USTCNT_RXEN	0x4000	/* Receiver Enable */
+#define USTCNT_UEN	0x8000	/* UART Enable */
+
+/* '328-compatible definitions */
+#define USTCNT_TXAVAILEN	USTCNT_TXAE
+#define USTCNT_TXHALFEN		USTCNT_TXHE
+#define USTCNT_TXEMPTYEN	USTCNT_TXEE
+#define USTCNT_RXREADYEN	USTCNT_RXRE
+#define USTCNT_RXHALFEN		USTCNT_RXHE
+#define USTCNT_RXFULLEN		USTCNT_RXFE
+#define USTCNT_CTSDELTAEN	USTCNT_CTSD
+#define USTCNT_ODD_EVEN		USTCNT_ODD
+#define USTCNT_PARITYEN		USTCNT_PEN
+#define USTCNT_CLKMODE		USTCNT_CLKM
+#define USTCNT_UARTEN		USTCNT_UEN
+
+/*
+ * UART Baud Control Register
+ */
+#define UBAUD_ADDR	0xfffff902
+#define UBAUD		WORD_REF(UBAUD_ADDR)
+
+#define UBAUD_PRESCALER_MASK	0x003f	/* Actual divisor is 65 - PRESCALER */
+#define UBAUD_PRESCALER_SHIFT	0
+#define UBAUD_DIVIDE_MASK	0x0700	/* Baud Rate freq. divizor */
+#define UBAUD_DIVIDE_SHIFT	8
+#define UBAUD_BAUD_SRC		0x0800	/* Baud Rate Source */
+#define UBAUD_UCLKDIR		0x2000	/* UCLK Direction */
+
+/*
+ * UART Receiver Register 
+ */
+#define URX_ADDR	0xfffff904
+#define URX		WORD_REF(URX_ADDR)
+
+#define URX_RXDATA_ADDR	0xfffff905
+#define URX_RXDATA	BYTE_REF(URX_RXDATA_ADDR)
+
+#define URX_RXDATA_MASK	 0x00ff	/* Received data */
+#define URX_RXDATA_SHIFT 0
+#define URX_PARITY_ERROR 0x0100	/* Parity Error */
+#define URX_BREAK	 0x0200	/* Break Detected */
+#define URX_FRAME_ERROR	 0x0400	/* Framing Error */
+#define URX_OVRUN	 0x0800	/* Serial Overrun */
+#define URX_OLD_DATA	 0x1000	/* Old data in FIFO */
+#define URX_DATA_READY	 0x2000	/* Data Ready (FIFO not empty) */
+#define URX_FIFO_HALF	 0x4000 /* FIFO is Half-Full */
+#define URX_FIFO_FULL	 0x8000	/* FIFO is Full */
+
+/*
+ * UART Transmitter Register 
+ */
+#define UTX_ADDR	0xfffff906
+#define UTX		WORD_REF(UTX_ADDR)
+
+#define UTX_TXDATA_ADDR	0xfffff907
+#define UTX_TXDATA	BYTE_REF(UTX_TXDATA_ADDR)
+
+#define UTX_TXDATA_MASK	 0x00ff	/* Data to be transmitted */
+#define UTX_TXDATA_SHIFT 0
+#define UTX_CTS_DELTA	 0x0100	/* CTS changed */
+#define UTX_CTS_STAT	 0x0200	/* CTS State */
+#define	UTX_BUSY	 0x0400	/* FIFO is busy, sending a character */
+#define	UTX_NOCTS	 0x0800	/* Ignore CTS */
+#define UTX_SEND_BREAK	 0x1000	/* Send a BREAK */
+#define UTX_TX_AVAIL	 0x2000	/* Transmit FIFO has a slot available */
+#define UTX_FIFO_HALF	 0x4000	/* Transmit FIFO is half empty */
+#define UTX_FIFO_EMPTY	 0x8000	/* Transmit FIFO is empty */
+
+/* '328-compatible definitions */
+#define UTX_CTS_STATUS	UTX_CTS_STAT
+#define UTX_IGNORE_CTS	UTX_NOCTS
+
+/*
+ * UART Miscellaneous Register 
+ */
+#define UMISC_ADDR	0xfffff908
+#define UMISC		WORD_REF(UMISC_ADDR)
+
+#define UMISC_TX_POL	 0x0004	/* Transmit Polarity */
+#define UMISC_RX_POL	 0x0008	/* Receive Polarity */
+#define UMISC_IRDA_LOOP	 0x0010	/* IrDA Loopback Enable */
+#define UMISC_IRDA_EN	 0x0020	/* Infra-Red Enable */
+#define UMISC_RTS	 0x0040	/* Set RTS status */
+#define UMISC_RTSCONT	 0x0080	/* Choose RTS control */
+#define UMISC_IR_TEST	 0x0400	/* IRDA Test Enable */
+#define UMISC_BAUD_RESET 0x0800	/* Reset Baud Rate Generation Counters */
+#define UMISC_LOOP	 0x1000	/* Serial Loopback Enable */
+#define UMISC_FORCE_PERR 0x2000	/* Force Parity Error */
+#define UMISC_CLKSRC	 0x4000	/* Clock Source */
+#define UMISC_BAUD_TEST	 0x8000	/* Enable Baud Test Mode */
+
+/* 
+ * UART Non-integer Prescaler Register
+ */
+#define NIPR_ADDR	0xfffff90a
+#define NIPR		WORD_REF(NIPR_ADDR)
+
+#define NIPR_STEP_VALUE_MASK	0x00ff	/* NI prescaler step value */
+#define NIPR_STEP_VALUE_SHIFT	0
+#define NIPR_SELECT_MASK	0x0700	/* Tap Selection */
+#define NIPR_SELECT_SHIFT	8
+#define NIPR_PRE_SEL		0x8000	/* Non-integer prescaler select */
+
+
+/* generalization of uart control registers to support multiple ports: */
+typedef struct {
+  volatile unsigned short int ustcnt;
+  volatile unsigned short int ubaud;
+  union {
+    volatile unsigned short int w;
+    struct {
+      volatile unsigned char status;
+      volatile unsigned char rxdata;
+    } b;
+  } urx;
+  union {
+    volatile unsigned short int w;
+    struct {
+      volatile unsigned char status;
+      volatile unsigned char txdata;
+    } b;
+  } utx;
+  volatile unsigned short int umisc;
+  volatile unsigned short int nipr;
+  volatile unsigned short int hmark;
+  volatile unsigned short int unused;
+} m68328_uart __attribute__((packed));
+
+
+
+
+/**********
+ *
+ * 0xFFFFFAxx -- LCD Controller
+ *
+ **********/
+
+/*
+ * LCD Screen Starting Address Register 
+ */
+#define LSSA_ADDR	0xfffffa00
+#define LSSA		LONG_REF(LSSA_ADDR)
+
+#define LSSA_SSA_MASK	0x1ffffffe	/* Bits 0 and 29-31 are reserved */
+
+/*
+ * LCD Virtual Page Width Register 
+ */
+#define LVPW_ADDR	0xfffffa05
+#define LVPW		BYTE_REF(LVPW_ADDR)
+
+/*
+ * LCD Screen Width Register (not compatible with '328 !!!) 
+ */
+#define LXMAX_ADDR	0xfffffa08
+#define LXMAX		WORD_REF(LXMAX_ADDR)
+
+#define LXMAX_XM_MASK	0x02f0		/* Bits 0-3 and 10-15 are reserved */
+
+/*
+ * LCD Screen Height Register
+ */
+#define LYMAX_ADDR	0xfffffa0a
+#define LYMAX		WORD_REF(LYMAX_ADDR)
+
+#define LYMAX_YM_MASK	0x01ff		/* Bits 9-15 are reserved */
+
+/*
+ * LCD Cursor X Position Register
+ */
+#define LCXP_ADDR	0xfffffa18
+#define LCXP		WORD_REF(LCXP_ADDR)
+
+#define LCXP_CC_MASK	0xc000		/* Cursor Control */
+#define   LCXP_CC_TRAMSPARENT	0x0000
+#define   LCXP_CC_BLACK		0x4000
+#define   LCXP_CC_REVERSED	0x8000
+#define   LCXP_CC_WHITE		0xc000
+#define LCXP_CXP_MASK	0x02ff		/* Cursor X position */
+
+/*
+ * LCD Cursor Y Position Register
+ */
+#define LCYP_ADDR	0xfffffa1a
+#define LCYP		WORD_REF(LCYP_ADDR)
+
+#define LCYP_CYP_MASK	0x01ff		/* Cursor Y Position */
+
+/*
+ * LCD Cursor Width and Heigth Register
+ */
+#define LCWCH_ADDR	0xfffffa1c
+#define LCWCH		WORD_REF(LCWCH_ADDR)
+
+#define LCWCH_CH_MASK	0x001f		/* Cursor Height */
+#define LCWCH_CH_SHIFT	0
+#define LCWCH_CW_MASK	0x1f00		/* Cursor Width */
+#define LCWCH_CW_SHIFT	8
+
+/*
+ * LCD Blink Control Register
+ */
+#define LBLKC_ADDR	0xfffffa1f
+#define LBLKC		BYTE_REF(LBLKC_ADDR)
+
+#define LBLKC_BD_MASK	0x7f	/* Blink Divisor */
+#define LBLKC_BD_SHIFT	0
+#define LBLKC_BKEN	0x80	/* Blink Enabled */
+
+/*
+ * LCD Panel Interface Configuration Register 
+ */
+#define LPICF_ADDR	0xfffffa20
+#define LPICF		BYTE_REF(LPICF_ADDR)
+
+#define LPICF_GS_MASK	 0x03	 /* Gray-Scale Mode */
+#define	  LPICF_GS_BW	   0x00
+#define   LPICF_GS_GRAY_4  0x01
+#define   LPICF_GS_GRAY_16 0x02
+#define LPICF_PBSIZ_MASK 0x0c	/* Panel Bus Width */
+#define   LPICF_PBSIZ_1	   0x00
+#define   LPICF_PBSIZ_2    0x04
+#define   LPICF_PBSIZ_4    0x08
+
+/*
+ * LCD Polarity Configuration Register 
+ */
+#define LPOLCF_ADDR	0xfffffa21
+#define LPOLCF		BYTE_REF(LPOLCF_ADDR)
+
+#define LPOLCF_PIXPOL	0x01	/* Pixel Polarity */
+#define LPOLCF_LPPOL	0x02	/* Line Pulse Polarity */
+#define LPOLCF_FLMPOL	0x04	/* Frame Marker Polarity */
+#define LPOLCF_LCKPOL	0x08	/* LCD Shift Lock Polarity */
+
+/*
+ * LACD (LCD Alternate Crystal Direction) Rate Control Register
+ */
+#define LACDRC_ADDR	0xfffffa23
+#define LACDRC		BYTE_REF(LACDRC_ADDR)
+
+#define LACDRC_ACDSLT	 0x80	/* Signal Source Select */
+#define LACDRC_ACD_MASK	 0x0f	/* Alternate Crystal Direction Control */
+#define LACDRC_ACD_SHIFT 0
+
+/*
+ * LCD Pixel Clock Divider Register
+ */
+#define LPXCD_ADDR	0xfffffa25
+#define LPXCD		BYTE_REF(LPXCD_ADDR)
+
+#define	LPXCD_PCD_MASK	0x3f 	/* Pixel Clock Divider */
+#define LPXCD_PCD_SHIFT	0
+
+/*
+ * LCD Clocking Control Register
+ */
+#define LCKCON_ADDR	0xfffffa27
+#define LCKCON		BYTE_REF(LCKCON_ADDR)
+
+#define LCKCON_DWS_MASK	 0x0f	/* Display Wait-State */
+#define LCKCON_DWS_SHIFT 0
+#define LCKCON_DWIDTH	 0x40	/* Display Memory Width  */
+#define LCKCON_LCDON	 0x80	/* Enable LCD Controller */
+
+/* '328-compatible definitions */
+#define LCKCON_DW_MASK  LCKCON_DWS_MASK
+#define LCKCON_DW_SHIFT LCKCON_DWS_SHIFT
+ 
+/*
+ * LCD Refresh Rate Adjustment Register 
+ */
+#define LRRA_ADDR	0xfffffa29
+#define LRRA		BYTE_REF(LRRA_ADDR)
+
+/*
+ * LCD Panning Offset Register
+ */
+#define LPOSR_ADDR	0xfffffa2d
+#define LPOSR		BYTE_REF(LPOSR_ADDR)
+
+#define LPOSR_POS_MASK	0x0f	/* Pixel Offset Code */
+#define LPOSR_POS_SHIFT	0
+
+/*
+ * LCD Frame Rate Control Modulation Register
+ */
+#define LFRCM_ADDR	0xfffffa31
+#define LFRCM		BYTE_REF(LFRCM_ADDR)
+
+#define LFRCM_YMOD_MASK	 0x0f	/* Vertical Modulation */
+#define LFRCM_YMOD_SHIFT 0
+#define LFRCM_XMOD_MASK	 0xf0	/* Horizontal Modulation */
+#define LFRCM_XMOD_SHIFT 4
+
+/*
+ * LCD Gray Palette Mapping Register
+ */
+#define LGPMR_ADDR	0xfffffa33
+#define LGPMR		BYTE_REF(LGPMR_ADDR)
+
+#define LGPMR_G1_MASK	0x0f
+#define LGPMR_G1_SHIFT	0
+#define LGPMR_G2_MASK	0xf0
+#define LGPMR_G2_SHIFT	4
+
+/* 
+ * PWM Contrast Control Register
+ */
+#define PWMR_ADDR	0xfffffa36
+#define PWMR		WORD_REF(PWMR_ADDR)
+
+#define PWMR_PW_MASK	0x00ff	/* Pulse Width */
+#define PWMR_PW_SHIFT	0
+#define PWMR_CCPEN	0x0100	/* Contrast Control Enable */
+#define PWMR_SRC_MASK	0x0600	/* Input Clock Source */
+#define   PWMR_SRC_LINE	  0x0000	/* Line Pulse  */
+#define   PWMR_SRC_PIXEL  0x0200	/* Pixel Clock */
+#define   PWMR_SRC_LCD    0x4000	/* LCD clock   */
+
+/**********
+ *
+ * 0xFFFFFBxx -- Real-Time Clock (RTC)
+ *
+ **********/
+
+/*
+ * RTC Hours Minutes and Seconds Register
+ */
+#define RTCTIME_ADDR	0xfffffb00
+#define RTCTIME		LONG_REF(RTCTIME_ADDR)
+
+#define RTCTIME_SECONDS_MASK	0x0000003f	/* Seconds */
+#define RTCTIME_SECONDS_SHIFT	0
+#define RTCTIME_MINUTES_MASK	0x003f0000	/* Minutes */
+#define RTCTIME_MINUTES_SHIFT	16
+#define RTCTIME_HOURS_MASK	0x1f000000	/* Hours */
+#define RTCTIME_HOURS_SHIFT	24
+
+/*
+ *  RTC Alarm Register 
+ */
+#define RTCALRM_ADDR    0xfffffb04
+#define RTCALRM         LONG_REF(RTCALRM_ADDR)
+
+#define RTCALRM_SECONDS_MASK    0x0000003f      /* Seconds */
+#define RTCALRM_SECONDS_SHIFT   0
+#define RTCALRM_MINUTES_MASK    0x003f0000      /* Minutes */
+#define RTCALRM_MINUTES_SHIFT   16
+#define RTCALRM_HOURS_MASK      0x1f000000      /* Hours */
+#define RTCALRM_HOURS_SHIFT     24
+
+/*
+ * Watchdog Timer Register 
+ */
+#define WATCHDOG_ADDR	0xfffffb0a
+#define WATCHDOG	WORD_REF(WATCHDOG_ADDR)
+
+#define WATCHDOG_EN	0x0001	/* Watchdog Enabled */
+#define WATCHDOG_ISEL	0x0002	/* Select the watchdog interrupt */
+#define WATCHDOG_INTF	0x0080	/* Watchdog interrupt occcured */
+#define WATCHDOG_CNT_MASK  0x0300	/* Watchdog Counter */
+#define WATCHDOG_CNT_SHIFT 8
+
+/*
+ * RTC Control Register
+ */
+#define RTCCTL_ADDR	0xfffffb0c
+#define RTCCTL		WORD_REF(RTCCTL_ADDR)
+
+#define RTCCTL_XTL	0x0020	/* Crystal Selection */
+#define RTCCTL_EN	0x0080	/* RTC Enable */
+
+/* '328-compatible definitions */
+#define RTCCTL_384	RTCCTL_XTL
+#define RTCCTL_ENABLE	RTCCTL_EN
+
+/*
+ * RTC Interrupt Status Register 
+ */
+#define RTCISR_ADDR	0xfffffb0e
+#define RTCISR		WORD_REF(RTCISR_ADDR)
+
+#define RTCISR_SW	0x0001	/* Stopwatch timed out */
+#define RTCISR_MIN	0x0002	/* 1-minute interrupt has occured */
+#define RTCISR_ALM	0x0004	/* Alarm interrupt has occured */
+#define RTCISR_DAY	0x0008	/* 24-hour rollover interrupt has occured */
+#define RTCISR_1HZ	0x0010	/* 1Hz interrupt has occured */
+#define RTCISR_HR	0x0020	/* 1-hour interrupt has occured */
+#define RTCISR_SAM0	0x0100	/*   4Hz /   4.6875Hz interrupt has occured */ 
+#define RTCISR_SAM1	0x0200	/*   8Hz /   9.3750Hz interrupt has occured */ 
+#define RTCISR_SAM2	0x0400	/*  16Hz /  18.7500Hz interrupt has occured */ 
+#define RTCISR_SAM3	0x0800	/*  32Hz /  37.5000Hz interrupt has occured */ 
+#define RTCISR_SAM4	0x1000	/*  64Hz /  75.0000Hz interrupt has occured */ 
+#define RTCISR_SAM5	0x2000	/* 128Hz / 150.0000Hz interrupt has occured */ 
+#define RTCISR_SAM6	0x4000	/* 256Hz / 300.0000Hz interrupt has occured */ 
+#define RTCISR_SAM7	0x8000	/* 512Hz / 600.0000Hz interrupt has occured */ 
+
+/*
+ * RTC Interrupt Enable Register
+ */
+#define RTCIENR_ADDR	0xfffffb10
+#define RTCIENR		WORD_REF(RTCIENR_ADDR)
+
+#define RTCIENR_SW	0x0001	/* Stopwatch interrupt enable */
+#define RTCIENR_MIN	0x0002	/* 1-minute interrupt enable */
+#define RTCIENR_ALM	0x0004	/* Alarm interrupt enable */
+#define RTCIENR_DAY	0x0008	/* 24-hour rollover interrupt enable */
+#define RTCIENR_1HZ	0x0010	/* 1Hz interrupt enable */
+#define RTCIENR_HR	0x0020	/* 1-hour interrupt enable */
+#define RTCIENR_SAM0	0x0100	/*   4Hz /   4.6875Hz interrupt enable */ 
+#define RTCIENR_SAM1	0x0200	/*   8Hz /   9.3750Hz interrupt enable */ 
+#define RTCIENR_SAM2	0x0400	/*  16Hz /  18.7500Hz interrupt enable */ 
+#define RTCIENR_SAM3	0x0800	/*  32Hz /  37.5000Hz interrupt enable */ 
+#define RTCIENR_SAM4	0x1000	/*  64Hz /  75.0000Hz interrupt enable */ 
+#define RTCIENR_SAM5	0x2000	/* 128Hz / 150.0000Hz interrupt enable */ 
+#define RTCIENR_SAM6	0x4000	/* 256Hz / 300.0000Hz interrupt enable */ 
+#define RTCIENR_SAM7	0x8000	/* 512Hz / 600.0000Hz interrupt enable */ 
+
+/* 
+ * Stopwatch Minutes Register
+ */
+#define STPWCH_ADDR	0xfffffb12
+#define STPWCH		WORD_REF(STPWCH_ADDR)
+
+#define STPWCH_CNT_MASK	 0x003f	/* Stopwatch countdown value */
+#define SPTWCH_CNT_SHIFT 0
+
+/*
+ * RTC Day Count Register 
+ */
+#define DAYR_ADDR	0xfffffb1a
+#define DAYR		WORD_REF(DAYR_ADDR)
+
+#define DAYR_DAYS_MASK	0x1ff	/* Day Setting */
+#define DAYR_DAYS_SHIFT 0
+
+/*
+ * RTC Day Alarm Register 
+ */
+#define DAYALARM_ADDR	0xfffffb1c
+#define DAYALARM	WORD_REF(DAYALARM_ADDR)
+
+#define DAYALARM_DAYSAL_MASK	0x01ff	/* Day Setting of the Alarm */
+#define DAYALARM_DAYSAL_SHIFT 	0
+
+/**********
+ *
+ * 0xFFFFFCxx -- DRAM Controller
+ *
+ **********/
+
+/*
+ * DRAM Memory Configuration Register 
+ */
+#define DRAMMC_ADDR	0xfffffc00
+#define DRAMMC		WORD_REF(DRAMMC_ADDR)
+
+#define DRAMMC_ROW12_MASK	0xc000	/* Row address bit for MD12 */
+#define   DRAMMC_ROW12_PA10	0x0000
+#define   DRAMMC_ROW12_PA21	0x4000	
+#define   DRAMMC_ROW12_PA23	0x8000
+#define	DRAMMC_ROW0_MASK	0x3000	/* Row address bit for MD0 */
+#define	  DRAMMC_ROW0_PA11	0x0000
+#define   DRAMMC_ROW0_PA22	0x1000
+#define   DRAMMC_ROW0_PA23	0x2000
+#define DRAMMC_ROW11		0x0800	/* Row address bit for MD11 PA20/PA22 */
+#define DRAMMC_ROW10		0x0400	/* Row address bit for MD10 PA19/PA21 */
+#define	DRAMMC_ROW9		0x0200	/* Row address bit for MD9  PA9/PA19  */
+#define DRAMMC_ROW8		0x0100	/* Row address bit for MD8  PA10/PA20 */
+#define DRAMMC_COL10		0x0080	/* Col address bit for MD10 PA11/PA0  */
+#define DRAMMC_COL9		0x0040	/* Col address bit for MD9  PA10/PA0  */
+#define DRAMMC_COL8		0x0020	/* Col address bit for MD8  PA9/PA0   */
+#define DRAMMC_REF_MASK		0x001f	/* Reresh Cycle */
+#define DRAMMC_REF_SHIFT	0
+
+/*
+ * DRAM Control Register
+ */
+#define DRAMC_ADDR	0xfffffc02
+#define DRAMC		WORD_REF(DRAMC_ADDR)
+
+#define DRAMC_DWE	   0x0001	/* DRAM Write Enable */
+#define DRAMC_RST	   0x0002	/* Reset Burst Refresh Enable */
+#define DRAMC_LPR	   0x0004	/* Low-Power Refresh Enable */
+#define DRAMC_SLW	   0x0008	/* Slow RAM */
+#define DRAMC_LSP	   0x0010	/* Light Sleep */
+#define DRAMC_MSW	   0x0020	/* Slow Multiplexing */
+#define DRAMC_WS_MASK	   0x00c0	/* Wait-states */
+#define DRAMC_WS_SHIFT	   6
+#define DRAMC_PGSZ_MASK    0x0300	/* Page Size for fast page mode */
+#define DRAMC_PGSZ_SHIFT   8
+#define   DRAMC_PGSZ_256K  0x0000	
+#define   DRAMC_PGSZ_512K  0x0100
+#define   DRAMC_PGSZ_1024K 0x0200
+#define	  DRAMC_PGSZ_2048K 0x0300
+#define DRAMC_EDO	   0x0400	/* EDO DRAM */
+#define DRAMC_CLK	   0x0800	/* Refresh Timer Clock source select */
+#define DRAMC_BC_MASK	   0x3000	/* Page Access Clock Cycle (FP mode) */
+#define DRAMC_BC_SHIFT	   12
+#define DRAMC_RM	   0x4000	/* Refresh Mode */
+#define DRAMC_EN	   0x8000	/* DRAM Controller enable */
+
+
+/**********
+ *
+ * 0xFFFFFDxx -- In-Circuit Emulation (ICE)
+ *
+ **********/
+
+/*
+ * ICE Module Address Compare Register
+ */
+#define ICEMACR_ADDR	0xfffffd00
+#define ICEMACR		LONG_REF(ICEMACR_ADDR)
+
+/*
+ * ICE Module Address Mask Register
+ */
+#define ICEMAMR_ADDR	0xfffffd04
+#define ICEMAMR		LONG_REF(ICEMAMR_ADDR)
+
+/*
+ * ICE Module Control Compare Register
+ */
+#define ICEMCCR_ADDR	0xfffffd08
+#define ICEMCCR		WORD_REF(ICEMCCR_ADDR)
+
+#define ICEMCCR_PD	0x0001	/* Program/Data Cycle Selection */
+#define ICEMCCR_RW	0x0002	/* Read/Write Cycle Selection */
+
+/*
+ * ICE Module Control Mask Register
+ */
+#define ICEMCMR_ADDR	0xfffffd0a
+#define ICEMCMR		WORD_REF(ICEMCMR_ADDR)
+
+#define ICEMCMR_PDM	0x0001	/* Program/Data Cycle Mask */
+#define ICEMCMR_RWM	0x0002	/* Read/Write Cycle Mask */
+
+/*
+ * ICE Module Control Register 
+ */
+#define ICEMCR_ADDR	0xfffffd0c
+#define ICEMCR		WORD_REF(ICEMCR_ADDR)
+
+#define ICEMCR_CEN	0x0001	/* Compare Enable */
+#define ICEMCR_PBEN	0x0002	/* Program Break Enable */
+#define ICEMCR_SB	0x0004	/* Single Breakpoint */
+#define ICEMCR_HMDIS	0x0008	/* HardMap disable */
+#define ICEMCR_BBIEN	0x0010	/* Bus Break Interrupt Enable */
+
+/*
+ * ICE Module Status Register 
+ */
+#define ICEMSR_ADDR	0xfffffd0e
+#define ICEMSR		WORD_REF(ICEMSR_ADDR)
+
+#define ICEMSR_EMUEN	0x0001	/* Emulation Enable */
+#define ICEMSR_BRKIRQ	0x0002	/* A-Line Vector Fetch Detected */
+#define ICEMSR_BBIRQ	0x0004	/* Bus Break Interrupt Detected */
+#define ICEMSR_EMIRQ	0x0008	/* EMUIRQ Falling Edge Detected */
+
+#endif /* _MC68VZ328_H_ */
diff -Nru a/include/asm-m68knommu/a.out.h b/include/asm-m68knommu/a.out.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/a.out.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1 @@
+#include <asm-m68k/a.out.h>
diff -Nru a/include/asm-m68knommu/anchor.h b/include/asm-m68knommu/anchor.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/anchor.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,112 @@
+/****************************************************************************/
+
+/*
+ *	anchor.h -- Anchor CO-MEM Lite PCI host bridge part.
+ *
+ *	(C) Copyright 2000, Moreton Bay (www.moreton.com.au)
+ */
+
+/****************************************************************************/
+#ifndef	anchor_h
+#define	anchor_h
+/****************************************************************************/
+
+/*
+ *	Define basic addressing info.
+ */
+#if defined(CONFIG_MOTOROLA) && defined(CONFIG_M5407)
+#define	COMEM_BASE	0xFFFF0000	/* Base of CO-MEM address space */
+#define	COMEM_IRQ	25		/* IRQ of anchor part */
+#else
+#define	COMEM_BASE	0x80000000	/* Base of CO-MEM address space */
+#define	COMEM_IRQ	25		/* IRQ of anchor part */
+#endif
+
+/****************************************************************************/
+
+/*
+ *	4-byte registers of CO-MEM, so adjust register addresses for
+ *	easy access. Handy macro for word access too.
+ */
+#define	LREG(a)		((a) >> 2)
+#define	WREG(a)		((a) >> 1)
+
+
+/*
+ *	Define base addresses within CO-MEM Lite register address space.
+ */
+#define	COMEM_I2O	0x0000		/* I2O registers */
+#define	COMEM_OPREGS	0x0400		/* Operation registers */
+#define	COMEM_PCIBUS	0x2000		/* Direct access to PCI bus */
+#define	COMEM_SHMEM	0x4000		/* Shared memory region */
+
+#define	COMEM_SHMEMSIZE	0x4000		/* Size of shared memory */
+
+
+/*
+ *	Define CO-MEM Registers.
+ */
+#define	COMEM_I2OHISR	0x0030		/* I2O host interrupt status */
+#define	COMEM_I2OHIMR	0x0034		/* I2O host interrupt mask */
+#define	COMEM_I2OLISR	0x0038		/* I2O local interrupt status */
+#define	COMEM_I2OLIMR	0x003c		/* I2O local interrupt mask */
+#define	COMEM_IBFPFIFO	0x0040		/* I2O inbound free/post FIFO */
+#define	COMEM_OBPFFIFO	0x0044		/* I2O outbound post/free FIFO */
+#define	COMEM_IBPFFIFO	0x0048		/* I2O inbound post/free FIFO */
+#define	COMEM_OBFPFIFO	0x004c		/* I2O outbound free/post FIFO */
+
+#define	COMEM_DAHBASE	0x0460		/* Direct access base address */
+
+#define	COMEM_NVCMD	0x04a0		/* I2C serial command */
+#define	COMEM_NVREAD	0x04a4		/* I2C serial read */
+#define	COMEM_NVSTAT	0x04a8		/* I2C status */
+
+#define	COMEM_DMALBASE	0x04b0		/* DMA local base address */
+#define	COMEM_DMAHBASE	0x04b4		/* DMA host base address */
+#define	COMEM_DMASIZE	0x04b8		/* DMA size */
+#define	COMEM_DMACTL	0x04bc		/* DMA control */
+
+#define	COMEM_HCTL	0x04e0		/* Host control */
+#define	COMEM_HINT	0x04e4		/* Host interrupt control/status */
+#define	COMEM_HLDATA	0x04e8		/* Host to local data mailbox */
+#define	COMEM_LINT	0x04f4		/* Local interrupt contole status */
+#define	COMEM_LHDATA	0x04f8		/* Local to host data mailbox */
+
+#define	COMEM_LBUSCFG	0x04fc		/* Local bus configuration */
+
+
+/*
+ *	Commands and flags for use with Direct Access Register.
+ */
+#define	COMEM_DA_IACK	0x00000000	/* Interrupt acknowledge (read) */
+#define	COMEM_DA_SPCL	0x00000010	/* Special cycle (write) */
+#define	COMEM_DA_MEMRD	0x00000004	/* Memory read cycle */
+#define	COMEM_DA_MEMWR	0x00000004	/* Memory write cycle */
+#define	COMEM_DA_IORD	0x00000002	/* I/O read cycle */
+#define	COMEM_DA_IOWR	0x00000002	/* I/O write cycle */
+#define	COMEM_DA_CFGRD	0x00000006	/* Configuration read cycle */
+#define	COMEM_DA_CFGWR	0x00000006	/* Configuration write cycle */
+
+#define	COMEM_DA_ADDR(a)	((a) & 0xffffe000)
+
+#define	COMEM_DA_OFFSET(a)	((a) & 0x00001fff)
+
+
+/*
+ *	The PCI bus will be limited in what slots will actually be used.
+ *	Define valid device numbers for different boards.
+ */
+#if defined(CONFIG_MOTOROLA) && defined(CONFIG_M5407)
+#define	COMEM_MINDEV	14		/* Minimum valid DEVICE */
+#define	COMEM_MAXDEV	14		/* Maximum valid DEVICE */
+#define	COMEM_BRIDGEDEV	15		/* Slot bridge is in */
+#else
+#define	COMEM_MINDEV	0		/* Minimum valid DEVICE */
+#define	COMEM_MAXDEV	3		/* Maximum valid DEVICE */
+#endif
+
+#define	COMEM_MAXPCI	(COMEM_MAXDEV+1)	/* Maximum PCI devices */
+
+
+/****************************************************************************/
+#endif	/* anchor_h */
diff -Nru a/include/asm-m68knommu/asm-offsets.h b/include/asm-m68knommu/asm-offsets.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/asm-offsets.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,49 @@
+#ifndef __ASM_OFFSETS_H__
+#define __ASM_OFFSETS_H__
+/*
+ * DO NOT MODIFY.
+ *
+ * This file was generated by arch/m68knommu/Makefile
+ *
+ */
+
+#define TASK_STATE 0 /* offsetof(struct task_struct, state) */
+#define TASK_FLAGS 12 /* offsetof(struct task_struct, flags) */
+#define TASK_PTRACE 16 /* offsetof(struct task_struct, ptrace) */
+#define TASK_BLOCKED 922 /* offsetof(struct task_struct, blocked) */
+#define TASK_THREAD 772 /* offsetof(struct task_struct, thread) */
+#define TASK_THREAD_INFO 4 /* offsetof(struct task_struct, thread_info) */
+#define TASK_MM 92 /* offsetof(struct task_struct, mm) */
+#define TASK_ACTIVE_MM 96 /* offsetof(struct task_struct, active_mm) */
+#define CPUSTAT_SOFTIRQ_PENDING 0 /* offsetof(irq_cpustat_t, __softirq_pending) */
+#define THREAD_KSP 0 /* offsetof(struct thread_struct, ksp) */
+#define THREAD_USP 4 /* offsetof(struct thread_struct, usp) */
+#define THREAD_SR 8 /* offsetof(struct thread_struct, sr) */
+#define THREAD_FS 10 /* offsetof(struct thread_struct, fs) */
+#define THREAD_CRP 12 /* offsetof(struct thread_struct, crp) */
+#define THREAD_ESP0 20 /* offsetof(struct thread_struct, esp0) */
+#define THREAD_FPREG 24 /* offsetof(struct thread_struct, fp) */
+#define THREAD_FPCNTL 120 /* offsetof(struct thread_struct, fpcntl) */
+#define THREAD_FPSTATE 132 /* offsetof(struct thread_struct, fpstate) */
+#define PT_D0 32 /* offsetof(struct pt_regs, d0) */
+#define PT_ORIG_D0 36 /* offsetof(struct pt_regs, orig_d0) */
+#define PT_D1 0 /* offsetof(struct pt_regs, d1) */
+#define PT_D2 4 /* offsetof(struct pt_regs, d2) */
+#define PT_D3 8 /* offsetof(struct pt_regs, d3) */
+#define PT_D4 12 /* offsetof(struct pt_regs, d4) */
+#define PT_D5 16 /* offsetof(struct pt_regs, d5) */
+#define PT_A0 20 /* offsetof(struct pt_regs, a0) */
+#define PT_A1 24 /* offsetof(struct pt_regs, a1) */
+#define PT_A2 28 /* offsetof(struct pt_regs, a2) */
+#define PT_PC 48 /* offsetof(struct pt_regs, pc) */
+#define PT_SR 46 /* offsetof(struct pt_regs, sr) */
+#define PT_VECTOR 52 /* offsetof(struct pt_regs, pc) + 4 */
+#define STAT_IRQ 5140 /* offsetof(struct kernel_stat, irqs) */
+#define SIGSEGV 11 /* SIGSEGV */
+#define SEGV_MAPERR 196609 /* SEGV_MAPERR */
+#define SIGTRAP 5 /* SIGTRAP */
+#define TRAP_TRACE 196610 /* TRAP_TRACE */
+#define PT_PTRACED 1 /* PT_PTRACED */
+#define PT_DTRACE 2 /* PT_DTRACE */
+
+#endif
diff -Nru a/include/asm-m68knommu/atomic.h b/include/asm-m68knommu/atomic.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/atomic.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,118 @@
+#ifndef __ARCH_M68KNOMMU_ATOMIC__
+#define __ARCH_M68KNOMMU_ATOMIC__
+
+#include <asm/system.h>	/* local_irq_XXX() */
+
+/*
+ * Atomic operations that C can't guarantee us.  Useful for
+ * resource counting etc..
+ */
+
+/*
+ * We do not have SMP m68k systems, so we don't have to deal with that.
+ */
+
+typedef struct { int counter; } atomic_t;
+#define ATOMIC_INIT(i)	{ (i) }
+
+#define atomic_read(v)		((v)->counter)
+#define atomic_set(v, i)	(((v)->counter) = i)
+
+#ifdef CONFIG_COLDFIRE
+
+static __inline__ void atomic_add(int i, atomic_t *v)
+{
+	__asm__ __volatile__(
+		"movel %1,%%d0\t\n"
+		"addl %%d0,%0"
+		:
+		: "m" (*v), "id" (i)
+		: "d0");
+}
+
+static __inline__ void atomic_sub(int i, atomic_t *v)
+{
+	__asm__ __volatile__(
+		"movel %1,%%d0\t\n"
+		"subl %%d0,%0"
+		:
+		: "m" (*v), "id" (i)
+		: "d0");
+}
+
+#else
+
+static __inline__ void atomic_add(int i, atomic_t *v)
+{
+	__asm__ __volatile__("addl %1,%0" : "=m" (*v) : "d" (i), "0" (*v));
+}
+
+static __inline__ void atomic_sub(int i, atomic_t *v)
+{
+	__asm__ __volatile__("subl %1,%0" : "=m" (*v) : "d" (i), "0" (*v));
+}
+
+#endif /* COLDFIRE */
+
+static __inline__ void atomic_inc(volatile atomic_t *v)
+{
+	__asm__ __volatile__("addql #1,%0" : "=m" (*v): "0" (*v));
+}
+
+static __inline__ void atomic_dec(volatile atomic_t *v)
+{
+	__asm__ __volatile__("subql #1,%0" : "=m" (*v): "0" (*v));
+}
+
+static __inline__ int atomic_dec_and_test(volatile atomic_t *v)
+{
+	char c;
+	__asm__ __volatile__("subql #1,%1; seq %0" : "=d" (c), "=m" (*v): "1" (*v));
+	return c != 0;
+}
+
+#define atomic_clear_mask(mask, v) \
+	__asm__ __volatile__("andl %1,%0" : "=m" (*v) : "id" (~(mask)),"0"(*v))
+
+#define atomic_set_mask(mask, v) \
+	__asm__ __volatile__("orl %1,%0" : "=m" (*v) : "id" (mask),"0"(*v))
+
+/* Atomic operations are already serializing */
+#define smp_mb__before_atomic_dec()    barrier()
+#define smp_mb__after_atomic_dec() barrier()
+#define smp_mb__before_atomic_inc()    barrier()
+#define smp_mb__after_atomic_inc() barrier()
+
+extern __inline__ int atomic_add_return(int i, atomic_t * v)
+{
+	unsigned long temp, flags;
+
+	local_irq_save(flags);
+	temp = *(long *)v;
+	temp += i;
+	*(long *)v = temp;
+	local_irq_restore(flags);
+
+	return temp;
+}
+
+extern __inline__ int atomic_sub_return(int i, atomic_t * v)
+{
+	unsigned long temp, flags;
+
+	local_irq_save(flags);
+	temp = *(long *)v;
+	temp -= i;
+	*(long *)v = temp;
+	local_irq_restore(flags);
+
+	return temp;
+}
+
+#define atomic_dec_return(v) atomic_sub_return(1,(v))
+#define atomic_inc_return(v) atomic_add_return(1,(v))
+
+#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
+#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
+
+#endif /* __ARCH_M68KNOMMU_ATOMIC __ */
diff -Nru a/include/asm-m68knommu/bitops.h b/include/asm-m68knommu/bitops.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/bitops.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,488 @@
+#ifndef _M68KNOMMU_BITOPS_H
+#define _M68KNOMMU_BITOPS_H
+
+/*
+ * Copyright 1992, Linus Torvalds.
+ */
+
+#include <linux/config.h>
+#include <linux/compiler.h>
+#include <asm/byteorder.h>	/* swab32 */
+#include <asm/system.h>		/* save_flags */
+
+#ifdef __KERNEL__
+/*
+ * Function prototypes to keep gcc -Wall happy
+ */
+
+/*
+ * The __ functions are not atomic
+ */
+
+extern void set_bit(int nr, volatile void * addr);
+extern void __set_bit(int nr, volatile void * addr);
+extern void clear_bit(int nr, volatile void * addr);
+extern void __clear_bit(int nr, volatile void * addr);
+extern void change_bit(int nr, volatile void * addr);
+extern void __change_bit(int nr, volatile void * addr);
+extern int test_and_set_bit(int nr, volatile void * addr);
+extern int __test_and_set_bit(int nr, volatile void * addr);
+extern int test_and_clear_bit(int nr, volatile void * addr);
+extern int __test_and_clear_bit(int nr, volatile void * addr);
+extern int test_and_change_bit(int nr, volatile void * addr);
+extern int __test_and_change_bit(int nr, volatile void * addr);
+extern int __constant_test_bit(int nr, const volatile void * addr);
+extern int __test_bit(int nr, volatile void * addr);
+extern int find_first_zero_bit(void * addr, unsigned size);
+extern int find_next_zero_bit (void * addr, int size, int offset);
+
+
+/*
+ *	Generic ffs().
+ */
+static inline int ffs(int x)
+{
+	int r = 1;
+
+	if (!x)
+		return 0;
+	if (!(x & 0xffff)) {
+		x >>= 16;
+		r += 16;
+	}
+	if (!(x & 0xff)) {
+		x >>= 8;
+		r += 8;
+	}
+	if (!(x & 0xf)) {
+		x >>= 4;
+		r += 4;
+	}
+	if (!(x & 3)) {
+		x >>= 2;
+		r += 2;
+	}
+	if (!(x & 1)) {
+		x >>= 1;
+		r += 1;
+	}
+	return r;
+}
+
+/*
+ *	Generic __ffs().
+ */
+static inline int __ffs(int x)
+{
+	int r = 0;
+
+	if (!x)
+		return 0;
+	if (!(x & 0xffff)) {
+		x >>= 16;
+		r += 16;
+	}
+	if (!(x & 0xff)) {
+		x >>= 8;
+		r += 8;
+	}
+	if (!(x & 0xf)) {
+		x >>= 4;
+		r += 4;
+	}
+	if (!(x & 3)) {
+		x >>= 2;
+		r += 2;
+	}
+	if (!(x & 1)) {
+		x >>= 1;
+		r += 1;
+	}
+	return r;
+}
+
+/*
+ * fls: find last bit set.
+ */
+#define fls(x) generic_fls(x)
+
+
+/*
+ * Every architecture must define this function. It's the fastest
+ * way of searching a 140-bit bitmap where the first 100 bits are
+ * unlikely to be set. It's guaranteed that at least one of the 140
+ * bits is cleared.
+ */
+static inline int sched_find_first_bit(unsigned long *b)
+{
+	if (unlikely(b[0]))
+		return __ffs(b[0]);
+	if (unlikely(b[1]))
+		return __ffs(b[1]) + 32;
+	if (unlikely(b[2]))
+		return __ffs(b[2]) + 64;
+	if (b[3])
+		return __ffs(b[3]) + 96;
+	return __ffs(b[4]) + 128;
+}
+
+/*
+ * ffz = Find First Zero in word. Undefined if no zero exists,
+ * so code should check against ~0UL first..
+ */
+extern __inline__ unsigned long ffz(unsigned long word)
+{
+	unsigned long result = 0;
+
+	while(word & 1) {
+		result++;
+		word >>= 1;
+	}
+	return result;
+}
+
+
+extern __inline__ void set_bit(int nr, volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	local_irq_save(flags);
+	*a |= mask;
+	local_irq_restore(flags);
+}
+
+extern __inline__ void __set_bit(int nr, volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	*a |= mask;
+}
+
+/*
+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+#define smp_mb__before_clear_bit()	barrier()
+#define smp_mb__after_clear_bit()	barrier()
+
+extern __inline__ void clear_bit(int nr, volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	local_irq_save(flags);
+	*a &= ~mask;
+	local_irq_restore(flags);
+}
+
+extern __inline__ void __clear_bit(int nr, volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	*a &= ~mask;
+}
+
+extern __inline__ void change_bit(int nr, volatile void * addr)
+{
+	int mask, flags;
+	unsigned long *ADDR = (unsigned long *) addr;
+
+	ADDR += nr >> 5;
+	mask = 1 << (nr & 31);
+	local_irq_save(flags);
+	*ADDR ^= mask;
+	local_irq_restore(flags);
+}
+
+extern __inline__ void __change_bit(int nr, volatile void * addr)
+{
+	int mask;
+	unsigned long *ADDR = (unsigned long *) addr;
+
+	ADDR += nr >> 5;
+	mask = 1 << (nr & 31);
+	*ADDR ^= mask;
+}
+
+extern __inline__ int test_and_set_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	local_irq_save(flags);
+	retval = (mask & *a) != 0;
+	*a |= mask;
+	local_irq_restore(flags);
+
+	return retval;
+}
+
+extern __inline__ int __test_and_set_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *a) != 0;
+	*a |= mask;
+	return retval;
+}
+
+extern __inline__ int test_and_clear_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	local_irq_save(flags);
+	retval = (mask & *a) != 0;
+	*a &= ~mask;
+	local_irq_restore(flags);
+
+	return retval;
+}
+
+extern __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *a) != 0;
+	*a &= ~mask;
+	return retval;
+}
+
+extern __inline__ int test_and_change_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	local_irq_save(flags);
+	retval = (mask & *a) != 0;
+	*a ^= mask;
+	local_irq_restore(flags);
+
+	return retval;
+}
+
+extern __inline__ int __test_and_change_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *a) != 0;
+	*a ^= mask;
+	return retval;
+}
+
+/*
+ * This routine doesn't need to be atomic.
+ */
+extern __inline__ int __constant_test_bit(int nr, const volatile void * addr)
+{
+	return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
+}
+
+extern __inline__ int __test_bit(int nr, volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	return ((mask & *a) != 0);
+}
+
+#define test_bit(nr,addr) \
+(__builtin_constant_p(nr) ? \
+ __constant_test_bit((nr),(addr)) : \
+ __test_bit((nr),(addr)))
+
+#define find_first_zero_bit(addr, size) \
+        find_next_zero_bit((addr), (size), 0)
+
+extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
+{
+	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if (offset) {
+		tmp = *(p++);
+		tmp |= ~0UL >> (32-offset);
+		if (size < 32)
+			goto found_first;
+		if (~tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while (size & ~31UL) {
+		if (~(tmp = *(p++)))
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if (!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	tmp |= ~0UL >> size;
+found_middle:
+	return result + ffz(tmp);
+}
+
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
+
+#define hweight32(x) generic_hweight32(x)
+#define hweight16(x) generic_hweight16(x)
+#define hweight8(x) generic_hweight8(x)
+
+
+extern __inline__ int ext2_set_bit(int nr, volatile void * addr)
+{
+	int		mask, retval;
+	unsigned long	flags;
+	volatile unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	local_irq_save(flags);
+	retval = (mask & *ADDR) != 0;
+	*ADDR |= mask;
+	local_irq_restore(flags);
+	return retval;
+}
+
+extern __inline__ int ext2_clear_bit(int nr, volatile void * addr)
+{
+	int		mask, retval;
+	unsigned long	flags;
+	volatile unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	local_irq_save(flags);
+	retval = (mask & *ADDR) != 0;
+	*ADDR &= ~mask;
+	local_irq_restore(flags);
+	return retval;
+}
+
+extern __inline__ int ext2_test_bit(int nr, const volatile void * addr)
+{
+	int	mask;
+	const volatile unsigned char	*ADDR = (const unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	return ((mask & *ADDR) != 0);
+}
+
+#define ext2_find_first_zero_bit(addr, size) \
+        ext2_find_next_zero_bit((addr), (size), 0)
+
+extern __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
+{
+	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if(offset) {
+		/* We hold the little endian value in tmp, but then the
+		 * shift is illegal. So we could keep a big endian value
+		 * in tmp, like this:
+		 *
+		 * tmp = __swab32(*(p++));
+		 * tmp |= ~0UL >> (32-offset);
+		 *
+		 * but this would decrease preformance, so we change the
+		 * shift:
+		 */
+		tmp = *(p++);
+		tmp |= __swab32(~0UL >> (32-offset));
+		if(size < 32)
+			goto found_first;
+		if(~tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while(size & ~31UL) {
+		if(~(tmp = *(p++)))
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if(!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	/* tmp is little endian, so we would have to swab the shift,
+	 * see above. But then we have to swab tmp below for ffz, so
+	 * we might as well do this here.
+	 */
+	return result + ffz(__swab32(tmp) | (~0UL << size));
+found_middle:
+	return result + ffz(__swab32(tmp));
+}
+
+/* Bitmap functions for the minix filesystem.  */
+#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
+#define minix_set_bit(nr,addr) set_bit(nr,addr)
+#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
+#define minix_test_bit(nr,addr) test_bit(nr,addr)
+#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
+
+/**
+ * hweightN - returns the hamming weight of a N-bit word
+ * @x: the word to weigh
+ *
+ * The Hamming Weight of a number is the total number of bits set in it.
+ */
+
+#define hweight32(x) generic_hweight32(x)
+#define hweight16(x) generic_hweight16(x)
+#define hweight8(x) generic_hweight8(x)
+
+#endif /* __KERNEL__ */
+
+#endif /* _M68KNOMMU_BITOPS_H */
diff -Nru a/include/asm-m68knommu/bootinfo.h b/include/asm-m68knommu/bootinfo.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/bootinfo.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,2 @@
+
+/* Nothing for m68knommu */
diff -Nru a/include/asm-m68knommu/bootstd.h b/include/asm-m68knommu/bootstd.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/bootstd.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,132 @@
+/* bootstd.h:  Bootloader system call interface
+ *
+ * (c) 1999, Rt-Control, Inc.
+ */
+
+#ifndef __BOOTSTD_H__
+#define __BOOTSTD_H__
+
+#define NR_BSC 21            /* last used bootloader system call */
+
+#define __BN_reset        0  /* reset and start the bootloader */
+#define __BN_test         1  /* tests the system call interface */
+#define __BN_exec         2  /* executes a bootloader image */
+#define __BN_exit         3  /* terminates a bootloader image */
+#define __BN_program      4  /* program FLASH from a chain */
+#define __BN_erase        5  /* erase sector(s) of FLASH */
+#define __BN_open         6
+#define __BN_write        7
+#define __BN_read         8
+#define __BN_close        9
+#define __BN_mmap         10 /* map a file descriptor into memory */
+#define __BN_munmap       11 /* remove a file to memory mapping */
+#define __BN_gethwaddr    12 /* get the hardware address of my interfaces */
+#define __BN_getserialnum 13 /* get the serial number of this board */
+#define __BN_getbenv      14 /* get a bootloader envvar */
+#define __BN_setbenv      15 /* get a bootloader envvar */
+#define __BN_setpmask     16 /* set the protection mask */
+#define __BN_readenv      17 /* read environment variables */
+#define __BN_flash_chattr_range		18
+#define __BN_flash_erase_range		19
+#define __BN_flash_write_range		20
+
+/* Calling conventions compatible to (uC)linux/68k
+ * We use simmilar macros to call into the bootloader as for uClinux
+ */
+
+#define __bsc_return(type, res) \
+do { \
+   if ((unsigned long)(res) >= (unsigned long)(-64)) { \
+      /* let errno be a function, preserve res in %d0 */ \
+      int __err = -(res); \
+      errno = __err; \
+      res = -1; \
+   } \
+   return (type)(res); \
+} while (0)
+
+#define _bsc0(type,name) \
+type name(void) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc1(type,name,atype,a) \
+type name(atype a) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc2(type,name,atype,a,btype,b) \
+type name(atype a, btype b) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc3(type,name,atype,a,btype,b,ctype,c) \
+type name(atype a, btype b, ctype c) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   register long __c __asm__ ("%d3") = (long)c; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b), \
+                           "d" (__c) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc4(type,name,atype,a,btype,b,ctype,c,dtype,d) \
+type name(atype a, btype b, ctype c, dtype d) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   register long __c __asm__ ("%d3") = (long)c; \
+   register long __d __asm__ ("%d4") = (long)d; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b), \
+                           "d" (__c), "d" (__d) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
+type name(atype a, btype b, ctype c, dtype d, etype e) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   register long __c __asm__ ("%d3") = (long)c; \
+   register long __d __asm__ ("%d4") = (long)d; \
+   register long __e __asm__ ("%d5") = (long)e; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b), \
+                           "d" (__c), "d" (__d), "d" (__e) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#endif /* __BOOTSTD_H__ */
diff -Nru a/include/asm-m68knommu/bugs.h b/include/asm-m68knommu/bugs.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/bugs.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,16 @@
+/*
+ *  include/asm-m68k/bugs.h
+ *
+ *  Copyright (C) 1994  Linus Torvalds
+ */
+
+/*
+ * This is included by init/main.c to check for architecture-dependent bugs.
+ *
+ * Needs:
+ *	void check_bugs(void);
+ */
+
+static void check_bugs(void)
+{
+}
diff -Nru a/include/asm-m68knommu/byteorder.h b/include/asm-m68knommu/byteorder.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/byteorder.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,13 @@
+#ifndef _M68KNOMMU_BYTEORDER_H
+#define _M68KNOMMU_BYTEORDER_H
+
+#include <asm/types.h>
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#  define __BYTEORDER_HAS_U64__
+#  define __SWAB_64_THRU_32__
+#endif
+
+#include <linux/byteorder/big_endian.h>
+
+#endif /* _M68KNOMMU_BYTEORDER_H */
diff -Nru a/include/asm-m68knommu/cache.h b/include/asm-m68knommu/cache.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/cache.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,12 @@
+#ifndef __ARCH_M68KNOMMU_CACHE_H
+#define __ARCH_M68KNOMMU_CACHE_H
+
+/* bytes per L1 cache line */
+#define        L1_CACHE_BYTES  16	/* this need to be at least 1 */
+
+/* m68k-elf-gcc  2.95.2 doesn't like these */
+
+#define __cacheline_aligned
+#define ____cacheline_aligned
+
+#endif
diff -Nru a/include/asm-m68knommu/cachectl.h b/include/asm-m68knommu/cachectl.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/cachectl.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/cachectl.h>
diff -Nru a/include/asm-m68knommu/cacheflush.h b/include/asm-m68knommu/cacheflush.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/cacheflush.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,82 @@
+#ifndef _M68KNOMMU_CACHEFLUSH_H
+#define _M68KNOMMU_CACHEFLUSH_H
+
+/*
+ * (C) Copyright 2000-2002, Greg Ungerer <gerg@snapgear.com>
+ */
+
+#include <asm/io.h>
+
+/*
+ * Cache handling functions
+ */
+
+#define flush_cache_all() __flush_cache_all()
+
+extern inline void __flush_cache_all(void)
+{
+#ifdef CONFIG_M5407
+	__asm__ __volatile__ (
+		"nop\n\t"
+		"clrl	%%d0\n\t"
+		"1:\n\t"
+		"movel	%%d0,%%a0\n\t"
+		"2:\n\t"
+		".word	0xf4e8\n\t"
+		"addl	#0x10,%%a0\n\t"
+		"cmpl	#0x00000800,%%a0\n\t"
+		"blt	2b\n\t"
+		"addql	#1,%%d0\n\t"
+		"cmpil	#4,%%d0\n\t"
+		"bne	1b\n\t"
+		"movel  #0x01040100,%%d0\n\t"
+		"movec  %%d0,%%CACR\n\t"
+		"nop\n\t"
+		"movel  #0x86088400,%%d0\n\t"
+		"movec  %%d0,%%CACR\n\t"
+		: : : "d0", "a0" );
+#endif /* CONFIG_M5407 */
+#ifdef CONFIG_M5272
+	__asm__ __volatile__ (
+        	"movel	#0x01000000, %%d0\n\t"
+        	"movec	%%d0, %%CACR\n\t"
+		"nop\n\t"
+        	"movel	#0x80000100, %%d0\n\t"
+        	"movec	%%d0, %%CACR\n\t"
+		"nop\n\t"
+		: : : "d0" );
+#endif /* CONFIG_M5272 */
+#if 0 /* CONFIG_M5249 */
+	__asm__ __volatile__ (
+        	"movel	#0x01000000, %%d0\n\t"
+        	"movec	%%d0, %%CACR\n\t"
+		"nop\n\t"
+        	"movel	#0xa0000200, %%d0\n\t"
+        	"movec	%%d0, %%CACR\n\t"
+		"nop\n\t"
+		: : : "d0" );
+#endif /* CONFIG_M5249 */
+}
+
+/*
+ *	FIXME: we could do better than an entire flush in most cases.
+ *	But this will always work :-)
+ */
+#define	flush_cache_all()		__flush_cache_all()
+#define	flush_cache_mm(mm)		__flush_cache_all()
+#define	flush_cache_range(vma,a,b)	__flush_cache_all()
+#define	flush_cache_page(vma,p)		__flush_cache_all()
+#define	flush_page_to_ram(page)		__flush_cache_all()
+#define	flush_dcache_page(page)		__flush_cache_all()
+#define	flush_icache()			__flush_cache_all()
+#define	flush_icache_page(page)		__flush_cache_all()
+#define	flush_icache_range(start,len)	__flush_cache_all()
+#define	cache_push_v(vaddr,len)		__flush_cache_all()
+#define	cache_push(paddr,len)		__flush_cache_all()
+#define	cache_clear(paddr,len)		__flush_cache_all()
+
+#define	flush_dcache_range(a,b)
+
+#define	flush_icache_user_range(vma,page,addr,len)	__flush_cache_all()
+
+#endif /* _M68KNOMMU_CACHEFLUSH_H */
diff -Nru a/include/asm-m68knommu/checksum.h b/include/asm-m68knommu/checksum.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/checksum.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,131 @@
+#ifndef _M68K_CHECKSUM_H
+#define _M68K_CHECKSUM_H
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum);
+
+
+/*
+ * the same as csum_partial_copy, but copies from user space.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+extern unsigned int csum_partial_copy_from_user(const char *src, char *dst,
+						int len, int sum, int *csum_err);
+
+#define csum_partial_copy_nocheck(src, dst, len, sum)	\
+	csum_partial_copy((src), (dst), (len), (sum))
+
+unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl);
+
+/*
+ *	Fold a partial checksum
+ */
+
+static inline unsigned int csum_fold(unsigned int sum)
+{
+#ifdef CONFIG_COLDFIRE
+	sum = (sum & 0xffff) + (sum >> 16);
+	sum = (sum & 0xffff) + (sum >> 16);
+#else
+	unsigned int tmp = sum;
+	__asm__("swap %1\n\t"
+		"addw %1, %0\n\t"
+		"clrw %1\n\t"
+		"addxw %1, %0"
+		: "=&d" (sum), "=&d" (tmp)
+		: "0" (sum), "1" (sum));
+#endif
+	return ~sum;
+}
+
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+
+static inline unsigned int
+csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len,
+		  unsigned short proto, unsigned int sum)
+{
+	__asm__ ("addl  %1,%0\n\t"
+		 "addxl %4,%0\n\t"
+		 "addxl %5,%0\n\t"
+		 "clrl %1\n\t"
+		 "addxl %1,%0"
+		 : "=&d" (sum), "=&d" (saddr)
+		 : "0" (daddr), "1" (saddr), "d" (len + proto),
+		   "d"(sum));
+	return sum;
+}
+
+static inline unsigned short int
+csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len,
+		  unsigned short proto, unsigned int sum)
+{
+	return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+
+extern unsigned short ip_compute_csum(const unsigned char * buff, int len);
+
+#define _HAVE_ARCH_IPV6_CSUM
+static __inline__ unsigned short int
+csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr,
+		__u32 len, unsigned short proto, unsigned int sum) 
+{
+	register unsigned long tmp;
+	__asm__("addl %2@,%0\n\t"
+		"movel %2@(4),%1\n\t"
+		"addxl %1,%0\n\t"
+		"movel %2@(8),%1\n\t"
+		"addxl %1,%0\n\t"
+		"movel %2@(12),%1\n\t"
+		"addxl %1,%0\n\t"
+		"movel %3@,%1\n\t"
+		"addxl %1,%0\n\t"
+		"movel %3@(4),%1\n\t"
+		"addxl %1,%0\n\t"
+		"movel %3@(8),%1\n\t"
+		"addxl %1,%0\n\t"
+		"movel %3@(12),%1\n\t"
+		"addxl %1,%0\n\t"
+		"addxl %4,%0\n\t"
+		"clrl %1\n\t"
+		"addxl %1,%0"
+		: "=&d" (sum), "=&d" (tmp)
+		: "a" (saddr), "a" (daddr), "d" (len + proto),
+		  "0" (sum));
+
+	return csum_fold(sum);
+}
+
+#endif /* _M68K_CHECKSUM_H */
diff -Nru a/include/asm-m68knommu/coldfire.h b/include/asm-m68knommu/coldfire.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/coldfire.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,72 @@
+/****************************************************************************/
+
+/*
+ *	coldfire.h -- Motorola ColdFire CPU sepecific defines
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com)
+ *	(C) Copyright 2000, Lineo (www.lineo.com)
+ */
+
+/****************************************************************************/
+#ifndef	coldfire_h
+#define	coldfire_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/*
+ *	Define the processor support peripherals base address.
+ *	This is generally setup by the boards start up code.
+ */
+#define	MCF_MBAR	0x10000000
+#define	MCF_MBAR2	0x80000000
+
+/*
+ *	Define master clock frequency.
+ */
+#if defined(CONFIG_CLOCK_11MHz)
+#define	MCF_CLK		11289600
+#elif defined(CONFIG_CLOCK_16MHz)
+#define	MCF_CLK		16000000
+#elif defined(CONFIG_CLOCK_20MHz)
+#define	MCF_CLK		20000000
+#elif defined(CONFIG_CLOCK_24MHz)
+#define	MCF_CLK		24000000
+#elif defined(CONFIG_CLOCK_25MHz)
+#define	MCF_CLK		25000000
+#elif defined(CONFIG_CLOCK_33MHz)
+#define	MCF_CLK		33000000
+#elif defined(CONFIG_CLOCK_40MHz)
+#define	MCF_CLK		40000000
+#elif defined(CONFIG_CLOCK_45MHz)
+#define	MCF_CLK		45000000
+#elif defined(CONFIG_CLOCK_48MHz)
+#define	MCF_CLK		48000000
+#elif defined(CONFIG_CLOCK_50MHz)
+#define	MCF_CLK		50000000
+#elif defined(CONFIG_CLOCK_54MHz)
+#define	MCF_CLK		54000000
+#elif defined(CONFIG_CLOCK_60MHz)
+#define	MCF_CLK		60000000
+#elif defined(CONFIG_CLOCK_66MHz)
+#define	MCF_CLK		66000000
+#elif defined(CONFIG_CLOCK_70MHz)
+#define	MCF_CLK		70000000
+#elif defined(CONFIG_CLOCK_140MHz)
+#define	MCF_CLK		140000000
+#else
+#error "Don't know what your ColdFire CPU clock frequency is??"
+#endif
+
+/*
+ *	One some ColdFire family members the bus clock (used by internal
+ *	peripherals) is not the same as the CPU clock.
+ */
+#ifdef CONFIG_M5249
+#define	MCF_BUSCLK	(MCF_CLK / 2)
+#else
+#define	MCF_BUSCLK	MCF_CLK
+#endif
+
+/****************************************************************************/
+#endif	/* coldfire_h */
diff -Nru a/include/asm-m68knommu/commproc.h b/include/asm-m68knommu/commproc.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/commproc.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,723 @@
+
+/*
+ * 68360 Communication Processor Module.
+ * Copyright (c) 2000 Michael Leslie <mleslie@lineo.com> (mc68360) after:
+ * Copyright (c) 1997 Dan Malek <dmalek@jlc.net> (mpc8xx)
+ *
+ * This file contains structures and information for the communication
+ * processor channels.  Some CPM control and status is available
+ * through the 68360 internal memory map.  See include/asm/360_immap.h for details.
+ * This file is not a complete map of all of the 360 QUICC's capabilities
+ *
+ * On the MBX board, EPPC-Bug loads CPM microcode into the first 512
+ * bytes of the DP RAM and relocates the I2C parameter area to the
+ * IDMA1 space.  The remaining DP RAM is available for buffer descriptors
+ * or other use.
+ */
+#ifndef __CPM_360__
+#define __CPM_360__
+
+#include <linux/config.h>
+
+/* CPM Command register masks: */
+#define CPM_CR_RST	((ushort)0x8000)
+#define CPM_CR_OPCODE	((ushort)0x0f00)
+#define CPM_CR_CHAN	((ushort)0x00f0)
+#define CPM_CR_FLG	((ushort)0x0001)
+
+/* CPM Command set (opcodes): */
+#define CPM_CR_INIT_TRX		((ushort)0x0000)
+#define CPM_CR_INIT_RX		((ushort)0x0001)
+#define CPM_CR_INIT_TX		((ushort)0x0002)
+#define CPM_CR_HUNT_MODE	((ushort)0x0003)
+#define CPM_CR_STOP_TX		((ushort)0x0004)
+#define CPM_CR_GRSTOP_TX	((ushort)0x0005)
+#define CPM_CR_RESTART_TX	((ushort)0x0006)
+#define CPM_CR_CLOSE_RXBD	((ushort)0x0007)
+#define CPM_CR_SET_GADDR	((ushort)0x0008)
+#define CPM_CR_GCI_TIMEOUT	((ushort)0x0009)
+#define CPM_CR_GCI_ABORT	((ushort)0x000a)
+#define CPM_CR_RESET_BCS	((ushort)0x000a)
+
+/* CPM Channel numbers. */
+#define CPM_CR_CH_SCC1	((ushort)0x0000)
+#define CPM_CR_CH_SCC2	((ushort)0x0004)
+#define CPM_CR_CH_SPI	((ushort)0x0005)	/* SPI / Timers */
+#define CPM_CR_CH_TMR	((ushort)0x0005)
+#define CPM_CR_CH_SCC3	((ushort)0x0008)
+#define CPM_CR_CH_SMC1	((ushort)0x0009)	/* SMC1 / IDMA1 */
+#define CPM_CR_CH_IDMA1	((ushort)0x0009)
+#define CPM_CR_CH_SCC4	((ushort)0x000c)
+#define CPM_CR_CH_SMC2	((ushort)0x000d)	/* SMC2 / IDMA2 */
+#define CPM_CR_CH_IDMA2	((ushort)0x000d)
+
+
+#define mk_cr_cmd(CH, CMD)	((CMD << 8) | (CH << 4))
+
+#if 1 /* mleslie: I dinna think we have any such restrictions on
+       * DP RAM aboard the 360 board - see the MC68360UM p.3-3 */
+
+/* The dual ported RAM is multi-functional.  Some areas can be (and are
+ * being) used for microcode.  There is an area that can only be used
+ * as data ram for buffer descriptors, which is all we use right now.
+ * Currently the first 512 and last 256 bytes are used for microcode.
+ */
+/* mleslie: The uCquicc board is using no extra microcode in DPRAM */
+#define CPM_DATAONLY_BASE	((uint)0x0000)
+#define CPM_DATAONLY_SIZE	((uint)0x0800)
+#define CPM_DP_NOSPACE		((uint)0x7fffffff)
+
+#endif
+
+
+/* Export the base address of the communication processor registers
+ * and dual port ram. */
+/* extern	cpm360_t	*cpmp; */		/* Pointer to comm processor */
+extern QUICC *pquicc;
+uint         m360_cpm_dpalloc(uint size);
+/* void         *m360_cpm_hostalloc(uint size); */
+void	      m360_cpm_setbrg(uint brg, uint rate);
+
+#if 0 /* use QUICC_BD declared in include/asm/m68360_quicc.h  */
+/* Buffer descriptors used by many of the CPM protocols. */
+typedef struct cpm_buf_desc {
+	ushort	cbd_sc;		/* Status and Control */
+	ushort	cbd_datlen;	/* Data length in buffer */
+	uint	cbd_bufaddr;	/* Buffer address in host memory */
+} cbd_t;
+#endif
+
+
+/* rx bd status/control bits */
+#define BD_SC_EMPTY	((ushort)0x8000)	/* Recieve is empty */
+#define BD_SC_WRAP	((ushort)0x2000)	/* Last buffer descriptor in table */
+#define BD_SC_INTRPT	((ushort)0x1000)	/* Interrupt on change */
+#define BD_SC_LAST	((ushort)0x0800)	/* Last buffer in frame OR control char */
+
+#define BD_SC_FIRST	((ushort)0x0400)	/* 1st buffer in an HDLC frame */
+#define BD_SC_ADDR	((ushort)0x0400)	/* 1st byte is a multidrop address */
+
+#define BD_SC_CM	((ushort)0x0200)	/* Continous mode */
+#define BD_SC_ID	((ushort)0x0100)	/* Received too many idles */
+
+#define BD_SC_AM	((ushort)0x0080)	/* Multidrop address match */
+#define BD_SC_DE	((ushort)0x0080)	/* DPLL Error (HDLC) */
+
+#define BD_SC_BR	((ushort)0x0020)	/* Break received */
+#define BD_SC_LG	((ushort)0x0020)	/* Frame length violation (HDLC) */
+
+#define BD_SC_FR	((ushort)0x0010)	/* Framing error */
+#define BD_SC_NO	((ushort)0x0010)	/* Nonoctet aligned frame (HDLC) */
+
+#define BD_SC_PR	((ushort)0x0008)	/* Parity error */
+#define BD_SC_AB	((ushort)0x0008)	/* Received abort Sequence (HDLC) */
+
+#define BD_SC_OV	((ushort)0x0002)	/* Overrun */
+#define BD_SC_CD	((ushort)0x0001)	/* Carrier Detect lost */
+
+/* tx bd status/control bits (as differ from rx bd) */
+#define BD_SC_READY	((ushort)0x8000)	/* Transmit is ready */
+#define BD_SC_TC	((ushort)0x0400)	/* Transmit CRC */
+#define BD_SC_P		((ushort)0x0100)	/* xmt preamble */
+#define BD_SC_UN	((ushort)0x0002)	/* Underrun */
+
+
+
+
+/* Parameter RAM offsets. */
+
+
+
+/* In 2.4 ppc, the PROFF_S?C? are used as byte offsets into DPRAM.
+ * In 2.0, we use a more structured C struct map of DPRAM, and so 
+ * instead, we need only a parameter ram `slot'  */
+
+#define PRSLOT_SCC1	0
+#define PRSLOT_SCC2	1
+#define PRSLOT_SCC3	2
+#define PRSLOT_SMC1	2
+#define PRSLOT_SCC4	3
+#define PRSLOT_SMC2	3
+
+
+/* #define PROFF_SCC1	((uint)0x0000) */
+/* #define PROFF_SCC2	((uint)0x0100) */
+/* #define PROFF_SCC3	((uint)0x0200) */
+/* #define PROFF_SMC1	((uint)0x0280) */
+/* #define PROFF_SCC4	((uint)0x0300) */
+/* #define PROFF_SMC2	((uint)0x0380) */
+
+
+/* Define enough so I can at least use the serial port as a UART.
+ * The MBX uses SMC1 as the host serial port.
+ */
+typedef struct smc_uart {
+	ushort	smc_rbase;	/* Rx Buffer descriptor base address */
+	ushort	smc_tbase;	/* Tx Buffer descriptor base address */
+	u_char	smc_rfcr;	/* Rx function code */
+	u_char	smc_tfcr;	/* Tx function code */
+	ushort	smc_mrblr;	/* Max receive buffer length */
+	uint	smc_rstate;	/* Internal */
+	uint	smc_idp;	/* Internal */
+	ushort	smc_rbptr;	/* Internal */
+	ushort	smc_ibc;	/* Internal */
+	uint	smc_rxtmp;	/* Internal */
+	uint	smc_tstate;	/* Internal */
+	uint	smc_tdp;	/* Internal */
+	ushort	smc_tbptr;	/* Internal */
+	ushort	smc_tbc;	/* Internal */
+	uint	smc_txtmp;	/* Internal */
+	ushort	smc_maxidl;	/* Maximum idle characters */
+	ushort	smc_tmpidl;	/* Temporary idle counter */
+	ushort	smc_brklen;	/* Last received break length */
+	ushort	smc_brkec;	/* rcv'd break condition counter */
+	ushort	smc_brkcr;	/* xmt break count register */
+	ushort	smc_rmask;	/* Temporary bit mask */
+} smc_uart_t;
+
+/* Function code bits.
+*/
+#define SMC_EB	((u_char)0x10)	/* Set big endian byte order */
+
+/* SMC uart mode register.
+*/
+#define	SMCMR_REN	((ushort)0x0001)
+#define SMCMR_TEN	((ushort)0x0002)
+#define SMCMR_DM	((ushort)0x000c)
+#define SMCMR_SM_GCI	((ushort)0x0000)
+#define SMCMR_SM_UART	((ushort)0x0020)
+#define SMCMR_SM_TRANS	((ushort)0x0030)
+#define SMCMR_SM_MASK	((ushort)0x0030)
+#define SMCMR_PM_EVEN	((ushort)0x0100)	/* Even parity, else odd */
+#define SMCMR_REVD	SMCMR_PM_EVEN
+#define SMCMR_PEN	((ushort)0x0200)	/* Parity enable */
+#define SMCMR_BS	SMCMR_PEN
+#define SMCMR_SL	((ushort)0x0400)	/* Two stops, else one */
+#define SMCR_CLEN_MASK	((ushort)0x7800)	/* Character length */
+#define smcr_mk_clen(C)	(((C) << 11) & SMCR_CLEN_MASK)
+
+/* SMC2 as Centronics parallel printer.  It is half duplex, in that
+ * it can only receive or transmit.  The parameter ram values for
+ * each direction are either unique or properly overlap, so we can
+ * include them in one structure.
+ */
+typedef struct smc_centronics {
+	ushort	scent_rbase;
+	ushort	scent_tbase;
+	u_char	scent_cfcr;
+	u_char	scent_smask;
+	ushort	scent_mrblr;
+	uint	scent_rstate;
+	uint	scent_r_ptr;
+	ushort	scent_rbptr;
+	ushort	scent_r_cnt;
+	uint	scent_rtemp;
+	uint	scent_tstate;
+	uint	scent_t_ptr;
+	ushort	scent_tbptr;
+	ushort	scent_t_cnt;
+	uint	scent_ttemp;
+	ushort	scent_max_sl;
+	ushort	scent_sl_cnt;
+	ushort	scent_character1;
+	ushort	scent_character2;
+	ushort	scent_character3;
+	ushort	scent_character4;
+	ushort	scent_character5;
+	ushort	scent_character6;
+	ushort	scent_character7;
+	ushort	scent_character8;
+	ushort	scent_rccm;
+	ushort	scent_rccr;
+} smc_cent_t;
+
+/* Centronics Status Mask Register.
+*/
+#define SMC_CENT_F	((u_char)0x08)
+#define SMC_CENT_PE	((u_char)0x04)
+#define SMC_CENT_S	((u_char)0x02)
+
+/* SMC Event and Mask register.
+*/
+#define	SMCM_BRKE	((unsigned char)0x40)	/* When in UART Mode */
+#define	SMCM_BRK	((unsigned char)0x10)	/* When in UART Mode */
+#define	SMCM_TXE	((unsigned char)0x10)	/* When in Transparent Mode */
+#define	SMCM_BSY	((unsigned char)0x04)
+#define	SMCM_TX		((unsigned char)0x02)
+#define	SMCM_RX		((unsigned char)0x01)
+
+/* Baud rate generators.
+*/
+#define CPM_BRG_RST		((uint)0x00020000)
+#define CPM_BRG_EN		((uint)0x00010000)
+#define CPM_BRG_EXTC_INT	((uint)0x00000000)
+#define CPM_BRG_EXTC_CLK2	((uint)0x00004000)
+#define CPM_BRG_EXTC_CLK6	((uint)0x00008000)
+#define CPM_BRG_ATB		((uint)0x00002000)
+#define CPM_BRG_CD_MASK		((uint)0x00001ffe)
+#define CPM_BRG_DIV16		((uint)0x00000001)
+
+/* SCCs.
+*/
+#define SCC_GSMRH_IRP		((uint)0x00040000)
+#define SCC_GSMRH_GDE		((uint)0x00010000)
+#define SCC_GSMRH_TCRC_CCITT	((uint)0x00008000)
+#define SCC_GSMRH_TCRC_BISYNC	((uint)0x00004000)
+#define SCC_GSMRH_TCRC_HDLC	((uint)0x00000000)
+#define SCC_GSMRH_REVD		((uint)0x00002000)
+#define SCC_GSMRH_TRX		((uint)0x00001000)
+#define SCC_GSMRH_TTX		((uint)0x00000800)
+#define SCC_GSMRH_CDP		((uint)0x00000400)
+#define SCC_GSMRH_CTSP		((uint)0x00000200)
+#define SCC_GSMRH_CDS		((uint)0x00000100)
+#define SCC_GSMRH_CTSS		((uint)0x00000080)
+#define SCC_GSMRH_TFL		((uint)0x00000040)
+#define SCC_GSMRH_RFW		((uint)0x00000020)
+#define SCC_GSMRH_TXSY		((uint)0x00000010)
+#define SCC_GSMRH_SYNL16	((uint)0x0000000c)
+#define SCC_GSMRH_SYNL8		((uint)0x00000008)
+#define SCC_GSMRH_SYNL4		((uint)0x00000004)
+#define SCC_GSMRH_RTSM		((uint)0x00000002)
+#define SCC_GSMRH_RSYN		((uint)0x00000001)
+
+#define SCC_GSMRL_SIR		((uint)0x80000000)	/* SCC2 only */
+#define SCC_GSMRL_EDGE_NONE	((uint)0x60000000)
+#define SCC_GSMRL_EDGE_NEG	((uint)0x40000000)
+#define SCC_GSMRL_EDGE_POS	((uint)0x20000000)
+#define SCC_GSMRL_EDGE_BOTH	((uint)0x00000000)
+#define SCC_GSMRL_TCI		((uint)0x10000000)
+#define SCC_GSMRL_TSNC_3	((uint)0x0c000000)
+#define SCC_GSMRL_TSNC_4	((uint)0x08000000)
+#define SCC_GSMRL_TSNC_14	((uint)0x04000000)
+#define SCC_GSMRL_TSNC_INF	((uint)0x00000000)
+#define SCC_GSMRL_RINV		((uint)0x02000000)
+#define SCC_GSMRL_TINV		((uint)0x01000000)
+#define SCC_GSMRL_TPL_128	((uint)0x00c00000)
+#define SCC_GSMRL_TPL_64	((uint)0x00a00000)
+#define SCC_GSMRL_TPL_48	((uint)0x00800000)
+#define SCC_GSMRL_TPL_32	((uint)0x00600000)
+#define SCC_GSMRL_TPL_16	((uint)0x00400000)
+#define SCC_GSMRL_TPL_8		((uint)0x00200000)
+#define SCC_GSMRL_TPL_NONE	((uint)0x00000000)
+#define SCC_GSMRL_TPP_ALL1	((uint)0x00180000)
+#define SCC_GSMRL_TPP_01	((uint)0x00100000)
+#define SCC_GSMRL_TPP_10	((uint)0x00080000)
+#define SCC_GSMRL_TPP_ZEROS	((uint)0x00000000)
+#define SCC_GSMRL_TEND		((uint)0x00040000)
+#define SCC_GSMRL_TDCR_32	((uint)0x00030000)
+#define SCC_GSMRL_TDCR_16	((uint)0x00020000)
+#define SCC_GSMRL_TDCR_8	((uint)0x00010000)
+#define SCC_GSMRL_TDCR_1	((uint)0x00000000)
+#define SCC_GSMRL_RDCR_32	((uint)0x0000c000)
+#define SCC_GSMRL_RDCR_16	((uint)0x00008000)
+#define SCC_GSMRL_RDCR_8	((uint)0x00004000)
+#define SCC_GSMRL_RDCR_1	((uint)0x00000000)
+#define SCC_GSMRL_RENC_DFMAN	((uint)0x00003000)
+#define SCC_GSMRL_RENC_MANCH	((uint)0x00002000)
+#define SCC_GSMRL_RENC_FM0	((uint)0x00001000)
+#define SCC_GSMRL_RENC_NRZI	((uint)0x00000800)
+#define SCC_GSMRL_RENC_NRZ	((uint)0x00000000)
+#define SCC_GSMRL_TENC_DFMAN	((uint)0x00000600)
+#define SCC_GSMRL_TENC_MANCH	((uint)0x00000400)
+#define SCC_GSMRL_TENC_FM0	((uint)0x00000200)
+#define SCC_GSMRL_TENC_NRZI	((uint)0x00000100)
+#define SCC_GSMRL_TENC_NRZ	((uint)0x00000000)
+#define SCC_GSMRL_DIAG_LE	((uint)0x000000c0)	/* Loop and echo */
+#define SCC_GSMRL_DIAG_ECHO	((uint)0x00000080)
+#define SCC_GSMRL_DIAG_LOOP	((uint)0x00000040)
+#define SCC_GSMRL_DIAG_NORM	((uint)0x00000000)
+#define SCC_GSMRL_ENR		((uint)0x00000020)
+#define SCC_GSMRL_ENT		((uint)0x00000010)
+#define SCC_GSMRL_MODE_ENET	((uint)0x0000000c)
+#define SCC_GSMRL_MODE_DDCMP	((uint)0x00000009)
+#define SCC_GSMRL_MODE_BISYNC	((uint)0x00000008)
+#define SCC_GSMRL_MODE_V14	((uint)0x00000007)
+#define SCC_GSMRL_MODE_AHDLC	((uint)0x00000006)
+#define SCC_GSMRL_MODE_PROFIBUS	((uint)0x00000005)
+#define SCC_GSMRL_MODE_UART	((uint)0x00000004)
+#define SCC_GSMRL_MODE_SS7	((uint)0x00000003)
+#define SCC_GSMRL_MODE_ATALK	((uint)0x00000002)
+#define SCC_GSMRL_MODE_HDLC	((uint)0x00000000)
+
+#define SCC_TODR_TOD		((ushort)0x8000)
+
+/* SCC Event and Mask register.
+*/
+#define	SCCM_TXE	((unsigned char)0x10)
+#define	SCCM_BSY	((unsigned char)0x04)
+#define	SCCM_TX		((unsigned char)0x02)
+#define	SCCM_RX		((unsigned char)0x01)
+
+typedef struct scc_param {
+	ushort	scc_rbase;	/* Rx Buffer descriptor base address */
+	ushort	scc_tbase;	/* Tx Buffer descriptor base address */
+	u_char	scc_rfcr;	/* Rx function code */
+	u_char	scc_tfcr;	/* Tx function code */
+	ushort	scc_mrblr;	/* Max receive buffer length */
+	uint	scc_rstate;	/* Internal */
+	uint	scc_idp;	/* Internal */
+	ushort	scc_rbptr;	/* Internal */
+	ushort	scc_ibc;	/* Internal */
+	uint	scc_rxtmp;	/* Internal */
+	uint	scc_tstate;	/* Internal */
+	uint	scc_tdp;	/* Internal */
+	ushort	scc_tbptr;	/* Internal */
+	ushort	scc_tbc;	/* Internal */
+	uint	scc_txtmp;	/* Internal */
+	uint	scc_rcrc;	/* Internal */
+	uint	scc_tcrc;	/* Internal */
+} sccp_t;
+
+
+/* Function code bits.
+ */
+#define SCC_EB	((u_char)0x10)	/* Set big endian byte order */
+#define SCC_FC_DMA ((u_char)0x08) /* Set SDMA */
+
+/* CPM Ethernet through SCC1.
+ */
+typedef struct scc_enet {
+	sccp_t	sen_genscc;
+	uint	sen_cpres;	/* Preset CRC */
+	uint	sen_cmask;	/* Constant mask for CRC */
+	uint	sen_crcec;	/* CRC Error counter */
+	uint	sen_alec;	/* alignment error counter */
+	uint	sen_disfc;	/* discard frame counter */
+	ushort	sen_pads;	/* Tx short frame pad character */
+	ushort	sen_retlim;	/* Retry limit threshold */
+	ushort	sen_retcnt;	/* Retry limit counter */
+	ushort	sen_maxflr;	/* maximum frame length register */
+	ushort	sen_minflr;	/* minimum frame length register */
+	ushort	sen_maxd1;	/* maximum DMA1 length */
+	ushort	sen_maxd2;	/* maximum DMA2 length */
+	ushort	sen_maxd;	/* Rx max DMA */
+	ushort	sen_dmacnt;	/* Rx DMA counter */
+	ushort	sen_maxb;	/* Max BD byte count */
+	ushort	sen_gaddr1;	/* Group address filter */
+	ushort	sen_gaddr2;
+	ushort	sen_gaddr3;
+	ushort	sen_gaddr4;
+	uint	sen_tbuf0data0;	/* Save area 0 - current frame */
+	uint	sen_tbuf0data1;	/* Save area 1 - current frame */
+	uint	sen_tbuf0rba;	/* Internal */
+	uint	sen_tbuf0crc;	/* Internal */
+	ushort	sen_tbuf0bcnt;	/* Internal */
+	ushort	sen_paddrh;	/* physical address (MSB) */
+	ushort	sen_paddrm;
+	ushort	sen_paddrl;	/* physical address (LSB) */
+	ushort	sen_pper;	/* persistence */
+	ushort	sen_rfbdptr;	/* Rx first BD pointer */
+	ushort	sen_tfbdptr;	/* Tx first BD pointer */
+	ushort	sen_tlbdptr;	/* Tx last BD pointer */
+	uint	sen_tbuf1data0;	/* Save area 0 - current frame */
+	uint	sen_tbuf1data1;	/* Save area 1 - current frame */
+	uint	sen_tbuf1rba;	/* Internal */
+	uint	sen_tbuf1crc;	/* Internal */
+	ushort	sen_tbuf1bcnt;	/* Internal */
+	ushort	sen_txlen;	/* Tx Frame length counter */
+	ushort	sen_iaddr1;	/* Individual address filter */
+	ushort	sen_iaddr2;
+	ushort	sen_iaddr3;
+	ushort	sen_iaddr4;
+	ushort	sen_boffcnt;	/* Backoff counter */
+
+	/* NOTE: Some versions of the manual have the following items
+	 * incorrectly documented.  Below is the proper order.
+	 */
+	ushort	sen_taddrh;	/* temp address (MSB) */
+	ushort	sen_taddrm;
+	ushort	sen_taddrl;	/* temp address (LSB) */
+} scc_enet_t;
+
+
+
+#if defined (CONFIG_UCQUICC)
+/* uCquicc has the following signals connected to Ethernet:
+ *  68360    - lxt905
+ * PA0/RXD1  - rxd
+ * PA1/TXD1  - txd
+ * PA8/CLK1  - tclk
+ * PA9/CLK2  - rclk
+ * PC0/!RTS1 - t_en
+ * PC1/!CTS1 - col
+ * PC5/!CD1  - cd
+ */
+#define PA_ENET_RXD	PA_RXD1
+#define PA_ENET_TXD	PA_TXD1
+#define PA_ENET_TCLK	PA_CLK1
+#define PA_ENET_RCLK	PA_CLK2
+#define PC_ENET_TENA	PC_RTS1
+#define PC_ENET_CLSN	PC_CTS1
+#define PC_ENET_RENA	PC_CD1
+
+/* Control bits in the SICR to route TCLK (CLK1) and RCLK (CLK2) to
+ * SCC1.
+ */
+#define SICR_ENET_MASK	((uint)0x000000ff)
+#define SICR_ENET_CLKRT	((uint)0x0000002c)
+
+#endif /* config_ucquicc */
+
+
+#ifdef MBX
+/* Bits in parallel I/O port registers that have to be set/cleared
+ * to configure the pins for SCC1 use.  The TCLK and RCLK seem unique
+ * to the MBX860 board.  Any two of the four available clocks could be
+ * used, and the MPC860 cookbook manual has an example using different
+ * clock pins.
+ */
+#define PA_ENET_RXD	((ushort)0x0001)
+#define PA_ENET_TXD	((ushort)0x0002)
+#define PA_ENET_TCLK	((ushort)0x0200)
+#define PA_ENET_RCLK	((ushort)0x0800)
+#define PC_ENET_TENA	((ushort)0x0001)
+#define PC_ENET_CLSN	((ushort)0x0010)
+#define PC_ENET_RENA	((ushort)0x0020)
+
+/* Control bits in the SICR to route TCLK (CLK2) and RCLK (CLK4) to
+ * SCC1.  Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero.
+ */
+#define SICR_ENET_MASK	((uint)0x000000ff)
+#define SICR_ENET_CLKRT	((uint)0x0000003d)
+#endif
+
+#ifdef CONFIG_RPXLITE
+/* This ENET stuff is for the MPC850 with ethernet on SCC2.  Some of
+ * this may be unique to the RPX-Lite configuration.
+ * Note TENA is on Port B.
+ */
+#define PA_ENET_RXD	((ushort)0x0004)
+#define PA_ENET_TXD	((ushort)0x0008)
+#define PA_ENET_TCLK	((ushort)0x0200)
+#define PA_ENET_RCLK	((ushort)0x0800)
+#define PB_ENET_TENA	((uint)0x00002000)
+#define PC_ENET_CLSN	((ushort)0x0040)
+#define PC_ENET_RENA	((ushort)0x0080)
+
+#define SICR_ENET_MASK	((uint)0x0000ff00)
+#define SICR_ENET_CLKRT	((uint)0x00003d00)
+#endif
+
+#ifdef CONFIG_BSEIP
+/* This ENET stuff is for the MPC823 with ethernet on SCC2.
+ * This is unique to the BSE ip-Engine board.
+ */
+#define PA_ENET_RXD	((ushort)0x0004)
+#define PA_ENET_TXD	((ushort)0x0008)
+#define PA_ENET_TCLK	((ushort)0x0100)
+#define PA_ENET_RCLK	((ushort)0x0200)
+#define PB_ENET_TENA	((uint)0x00002000)
+#define PC_ENET_CLSN	((ushort)0x0040)
+#define PC_ENET_RENA	((ushort)0x0080)
+
+/* BSE uses port B and C bits for PHY control also.
+*/
+#define PB_BSE_POWERUP	((uint)0x00000004)
+#define PB_BSE_FDXDIS	((uint)0x00008000)
+#define PC_BSE_LOOPBACK	((ushort)0x0800)
+
+#define SICR_ENET_MASK	((uint)0x0000ff00)
+#define SICR_ENET_CLKRT	((uint)0x00002c00)
+#endif
+
+#ifdef CONFIG_RPXCLASSIC
+/* Bits in parallel I/O port registers that have to be set/cleared
+ * to configure the pins for SCC1 use.
+ */
+#define PA_ENET_RXD	((ushort)0x0001)
+#define PA_ENET_TXD	((ushort)0x0002)
+#define PA_ENET_TCLK	((ushort)0x0200)
+#define PA_ENET_RCLK	((ushort)0x0800)
+#define PB_ENET_TENA	((uint)0x00001000)
+#define PC_ENET_CLSN	((ushort)0x0010)
+#define PC_ENET_RENA	((ushort)0x0020)
+
+/* Control bits in the SICR to route TCLK (CLK2) and RCLK (CLK4) to
+ * SCC1.  Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero.
+ */
+#define SICR_ENET_MASK	((uint)0x000000ff)
+#define SICR_ENET_CLKRT	((uint)0x0000003d)
+#endif
+
+/* SCC Event register as used by Ethernet.
+*/
+#define SCCE_ENET_GRA	((ushort)0x0080)	/* Graceful stop complete */
+#define SCCE_ENET_TXE	((ushort)0x0010)	/* Transmit Error */
+#define SCCE_ENET_RXF	((ushort)0x0008)	/* Full frame received */
+#define SCCE_ENET_BSY	((ushort)0x0004)	/* All incoming buffers full */
+#define SCCE_ENET_TXB	((ushort)0x0002)	/* A buffer was transmitted */
+#define SCCE_ENET_RXB	((ushort)0x0001)	/* A buffer was received */
+
+/* SCC Mode Register (PMSR) as used by Ethernet.
+*/
+#define SCC_PMSR_HBC	((ushort)0x8000)	/* Enable heartbeat */
+#define SCC_PMSR_FC	((ushort)0x4000)	/* Force collision */
+#define SCC_PMSR_RSH	((ushort)0x2000)	/* Receive short frames */
+#define SCC_PMSR_IAM	((ushort)0x1000)	/* Check individual hash */
+#define SCC_PMSR_ENCRC	((ushort)0x0800)	/* Ethernet CRC mode */
+#define SCC_PMSR_PRO	((ushort)0x0200)	/* Promiscuous mode */
+#define SCC_PMSR_BRO	((ushort)0x0100)	/* Catch broadcast pkts */
+#define SCC_PMSR_SBT	((ushort)0x0080)	/* Special backoff timer */
+#define SCC_PMSR_LPB	((ushort)0x0040)	/* Set Loopback mode */
+#define SCC_PMSR_SIP	((ushort)0x0020)	/* Sample Input Pins */
+#define SCC_PMSR_LCW	((ushort)0x0010)	/* Late collision window */
+#define SCC_PMSR_NIB22	((ushort)0x000a)	/* Start frame search */
+#define SCC_PMSR_FDE	((ushort)0x0001)	/* Full duplex enable */
+
+/* Buffer descriptor control/status used by Ethernet receive.
+*/
+#define BD_ENET_RX_EMPTY	((ushort)0x8000)
+#define BD_ENET_RX_WRAP		((ushort)0x2000)
+#define BD_ENET_RX_INTR		((ushort)0x1000)
+#define BD_ENET_RX_LAST		((ushort)0x0800)
+#define BD_ENET_RX_FIRST	((ushort)0x0400)
+#define BD_ENET_RX_MISS		((ushort)0x0100)
+#define BD_ENET_RX_LG		((ushort)0x0020)
+#define BD_ENET_RX_NO		((ushort)0x0010)
+#define BD_ENET_RX_SH		((ushort)0x0008)
+#define BD_ENET_RX_CR		((ushort)0x0004)
+#define BD_ENET_RX_OV		((ushort)0x0002)
+#define BD_ENET_RX_CL		((ushort)0x0001)
+#define BD_ENET_RX_STATS	((ushort)0x013f)	/* All status bits */
+
+/* Buffer descriptor control/status used by Ethernet transmit.
+*/
+#define BD_ENET_TX_READY	((ushort)0x8000)
+#define BD_ENET_TX_PAD		((ushort)0x4000)
+#define BD_ENET_TX_WRAP		((ushort)0x2000)
+#define BD_ENET_TX_INTR		((ushort)0x1000)
+#define BD_ENET_TX_LAST		((ushort)0x0800)
+#define BD_ENET_TX_TC		((ushort)0x0400)
+#define BD_ENET_TX_DEF		((ushort)0x0200)
+#define BD_ENET_TX_HB		((ushort)0x0100)
+#define BD_ENET_TX_LC		((ushort)0x0080)
+#define BD_ENET_TX_RL		((ushort)0x0040)
+#define BD_ENET_TX_RCMASK	((ushort)0x003c)
+#define BD_ENET_TX_UN		((ushort)0x0002)
+#define BD_ENET_TX_CSL		((ushort)0x0001)
+#define BD_ENET_TX_STATS	((ushort)0x03ff)	/* All status bits */
+
+/* SCC as UART
+*/
+typedef struct scc_uart {
+	sccp_t	scc_genscc;
+	uint	scc_res1;	/* Reserved */
+	uint	scc_res2;	/* Reserved */
+	ushort	scc_maxidl;	/* Maximum idle chars */
+	ushort	scc_idlc;	/* temp idle counter */
+	ushort	scc_brkcr;	/* Break count register */
+	ushort	scc_parec;	/* receive parity error counter */
+	ushort	scc_frmec;	/* receive framing error counter */
+	ushort	scc_nosec;	/* receive noise counter */
+	ushort	scc_brkec;	/* receive break condition counter */
+	ushort	scc_brkln;	/* last received break length */
+	ushort	scc_uaddr1;	/* UART address character 1 */
+	ushort	scc_uaddr2;	/* UART address character 2 */
+	ushort	scc_rtemp;	/* Temp storage */
+	ushort	scc_toseq;	/* Transmit out of sequence char */
+	ushort	scc_char1;	/* control character 1 */
+	ushort	scc_char2;	/* control character 2 */
+	ushort	scc_char3;	/* control character 3 */
+	ushort	scc_char4;	/* control character 4 */
+	ushort	scc_char5;	/* control character 5 */
+	ushort	scc_char6;	/* control character 6 */
+	ushort	scc_char7;	/* control character 7 */
+	ushort	scc_char8;	/* control character 8 */
+	ushort	scc_rccm;	/* receive control character mask */
+	ushort	scc_rccr;	/* receive control character register */
+	ushort	scc_rlbc;	/* receive last break character */
+} scc_uart_t;
+
+/* SCC Event and Mask registers when it is used as a UART.
+*/
+#define UART_SCCM_GLR		((ushort)0x1000)
+#define UART_SCCM_GLT		((ushort)0x0800)
+#define UART_SCCM_AB		((ushort)0x0200)
+#define UART_SCCM_IDL		((ushort)0x0100)
+#define UART_SCCM_GRA		((ushort)0x0080)
+#define UART_SCCM_BRKE		((ushort)0x0040)
+#define UART_SCCM_BRKS		((ushort)0x0020)
+#define UART_SCCM_CCR		((ushort)0x0008)
+#define UART_SCCM_BSY		((ushort)0x0004)
+#define UART_SCCM_TX		((ushort)0x0002)
+#define UART_SCCM_RX		((ushort)0x0001)
+
+/* The SCC PMSR when used as a UART.
+*/
+#define SCU_PMSR_FLC		((ushort)0x8000)
+#define SCU_PMSR_SL		((ushort)0x4000)
+#define SCU_PMSR_CL		((ushort)0x3000)
+#define SCU_PMSR_UM		((ushort)0x0c00)
+#define SCU_PMSR_FRZ		((ushort)0x0200)
+#define SCU_PMSR_RZS		((ushort)0x0100)
+#define SCU_PMSR_SYN		((ushort)0x0080)
+#define SCU_PMSR_DRT		((ushort)0x0040)
+#define SCU_PMSR_PEN		((ushort)0x0010)
+#define SCU_PMSR_RPM		((ushort)0x000c)
+#define SCU_PMSR_REVP		((ushort)0x0008)
+#define SCU_PMSR_TPM		((ushort)0x0003)
+#define SCU_PMSR_TEVP		((ushort)0x0003)
+
+/* CPM Transparent mode SCC.
+ */
+typedef struct scc_trans {
+	sccp_t	st_genscc;
+	uint	st_cpres;	/* Preset CRC */
+	uint	st_cmask;	/* Constant mask for CRC */
+} scc_trans_t;
+
+#define BD_SCC_TX_LAST		((ushort)0x0800)
+
+
+
+/* CPM interrupts.  There are nearly 32 interrupts generated by CPM
+ * channels or devices.  All of these are presented to the PPC core
+ * as a single interrupt.  The CPM interrupt handler dispatches its
+ * own handlers, in a similar fashion to the PPC core handler.  We
+ * use the table as defined in the manuals (i.e. no special high
+ * priority and SCC1 == SCCa, etc...).
+ */
+/* #define CPMVEC_NR		32 */
+/* #define	CPMVEC_PIO_PC15		((ushort)0x1f) */
+/* #define	CPMVEC_SCC1		((ushort)0x1e) */
+/* #define	CPMVEC_SCC2		((ushort)0x1d) */
+/* #define	CPMVEC_SCC3		((ushort)0x1c) */
+/* #define	CPMVEC_SCC4		((ushort)0x1b) */
+/* #define	CPMVEC_PIO_PC14		((ushort)0x1a) */
+/* #define	CPMVEC_TIMER1		((ushort)0x19) */
+/* #define	CPMVEC_PIO_PC13		((ushort)0x18) */
+/* #define	CPMVEC_PIO_PC12		((ushort)0x17) */
+/* #define	CPMVEC_SDMA_CB_ERR	((ushort)0x16) */
+/* #define CPMVEC_IDMA1		((ushort)0x15) */
+/* #define CPMVEC_IDMA2		((ushort)0x14) */
+/* #define CPMVEC_TIMER2		((ushort)0x12) */
+/* #define CPMVEC_RISCTIMER	((ushort)0x11) */
+/* #define CPMVEC_I2C		((ushort)0x10) */
+/* #define	CPMVEC_PIO_PC11		((ushort)0x0f) */
+/* #define	CPMVEC_PIO_PC10		((ushort)0x0e) */
+/* #define CPMVEC_TIMER3		((ushort)0x0c) */
+/* #define	CPMVEC_PIO_PC9		((ushort)0x0b) */
+/* #define	CPMVEC_PIO_PC8		((ushort)0x0a) */
+/* #define	CPMVEC_PIO_PC7		((ushort)0x09) */
+/* #define CPMVEC_TIMER4		((ushort)0x07) */
+/* #define	CPMVEC_PIO_PC6		((ushort)0x06) */
+/* #define	CPMVEC_SPI		((ushort)0x05) */
+/* #define	CPMVEC_SMC1		((ushort)0x04) */
+/* #define	CPMVEC_SMC2		((ushort)0x03) */
+/* #define	CPMVEC_PIO_PC5		((ushort)0x02) */
+/* #define	CPMVEC_PIO_PC4		((ushort)0x01) */
+/* #define	CPMVEC_ERROR		((ushort)0x00) */
+
+extern void cpm_install_handler(int vec, void (*handler)(void *), void *dev_id);
+
+/* CPM interrupt configuration vector.
+*/
+#define	CICR_SCD_SCC4		((uint)0x00c00000)	/* SCC4 @ SCCd */
+#define	CICR_SCC_SCC3		((uint)0x00200000)	/* SCC3 @ SCCc */
+#define	CICR_SCB_SCC2		((uint)0x00040000)	/* SCC2 @ SCCb */
+#define	CICR_SCA_SCC1		((uint)0x00000000)	/* SCC1 @ SCCa */
+#define CICR_IRL_MASK		((uint)0x0000e000)	/* Core interrrupt */
+#define CICR_HP_MASK		((uint)0x00001f00)	/* Hi-pri int. */
+#define CICR_IEN		((uint)0x00000080)	/* Int. enable */
+#define CICR_SPS		((uint)0x00000001)	/* SCC Spread */
+#endif /* __CPM_360__ */
diff -Nru a/include/asm-m68knommu/current.h b/include/asm-m68knommu/current.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/current.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,24 @@
+#ifndef _M68KNOMMU_CURRENT_H
+#define _M68KNOMMU_CURRENT_H
+/*
+ *	current.h
+ *	(C) Copyright 2000, Lineo, David McCullough <davidm@uclinux.org>
+ *	(C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
+ *
+ *	rather than dedicate a register (as the m68k source does), we
+ *	just keep a global,  we should probably just change it all to be
+ *	current and lose _current_task.
+ */
+
+#include <asm/thread_info.h>
+
+struct task_struct;
+
+static inline struct task_struct *get_current(void)
+{
+	return(current_thread_info()->task);
+}
+
+#define	current	get_current()
+
+#endif /* _M68KNOMMU_CURRENT_H */
diff -Nru a/include/asm-m68knommu/dbg.h b/include/asm-m68knommu/dbg.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/dbg.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,6 @@
+#define DEBUG 1
+#ifdef CONFIG_COLDFIRE
+#define	BREAK asm volatile ("halt")
+#else
+#define BREAK *(volatile unsigned char *)0xdeadbee0 = 0
+#endif
diff -Nru a/include/asm-m68knommu/delay.h b/include/asm-m68knommu/delay.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/delay.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,77 @@
+#ifndef _M68KNOMMU_DELAY_H
+#define _M68KNOMMU_DELAY_H
+
+#include <asm/param.h>
+
+/*
+ * Copyright (C) 1994 Hamish Macdonald
+ *
+ * Delay routines, using a pre-computed "loops_per_second" value.
+ */
+
+extern __inline__ void __delay(unsigned long loops)
+{
+#if defined(CONFIG_COLDFIRE)
+	/* The coldfire runs this loop at significantly different speeds
+	 * depending upon long word alignment or not.  We'll pad it to
+	 * long word alignment which is the faster version.
+	 * The 0x4a8e is of course a 'tstl %fp' instruction.  This is better
+	 * than using a NOP (0x4e71) instruction because it executes in one
+	 * cycle not three and doesn't allow for an arbitary delay waiting
+	 * for bus cycles to finish.  Also fp/a6 isn't likely to cause a
+	 * stall waiting for the register to become valid if such is added
+	 * to the coldfire at some stage.
+	 */
+	__asm__ __volatile__ (	".balignw 4, 0x4a8e\n\t"
+				"1: subql #1, %0\n\t"
+				"jcc 1b"
+		: "=d" (loops) : "0" (loops));
+#else
+	__asm__ __volatile__ (	"1: subql #1, %0\n\t"
+				"jcc 1b"
+		: "=d" (loops) : "0" (loops));
+#endif
+}
+
+/*
+ * Use only for very small delays ( < 1 msec).  Should probably use a
+ * lookup table, really, as the multiplications take much too long with
+ * short delays.  This is a "reasonable" implementation, though (and the
+ * first constant multiplications gets optimized away if the delay is
+ * a constant)  
+ */
+
+extern unsigned long loops_per_jiffy;
+
+extern __inline__ void udelay(unsigned long usecs)
+{
+#ifdef CONFIG_M68332
+        usecs *= 0x000010c6;       
+       __asm__ __volatile__ ("mulul %1,%0:%2"
+                    : "=d" (usecs)
+                  : "d" (usecs),
+                   "d" (loops_per_jiffy*HZ));
+	__delay(usecs);
+
+#elif defined(CONFIG_M68328) || defined(CONFIG_M68EZ328) || \
+		defined(CONFIG_COLDFIRE) || defined(CONFIG_M68360) || \
+		defined(CONFIG_M68VZ328)
+	register unsigned long full_loops, part_loops;
+
+	full_loops = ((usecs * HZ) / 1000000) * loops_per_jiffy;
+	usecs %= (1000000 / HZ);
+	part_loops = (usecs * HZ * loops_per_jiffy) / 1000000;
+
+	__delay(full_loops + part_loops);
+#else
+	unsigned long tmp;
+
+	usecs *= 4295;		/* 2**32 / 1000000 */
+	__asm__ ("mulul %2,%0:%1"
+		: "=d" (usecs), "=d" (tmp)
+		: "d" (usecs), "1" (loops_per_jiffy*HZ));
+	__delay(usecs);
+#endif
+}
+
+#endif /* defined(_M68KNOMMU_DELAY_H) */
diff -Nru a/include/asm-m68knommu/div64.h b/include/asm-m68knommu/div64.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/div64.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,13 @@
+#ifndef _M68KNOMMU_DIV64_H
+#define _M68KNOMMU_DIV64_H
+
+/* n = n / base; return rem; */
+
+#define do_div(n,base) ({					\
+	int __res;						\
+	__res = ((unsigned long) n) % (unsigned) base;		\
+	n = ((unsigned long) n) / (unsigned) base;		\
+	__res;							\
+})
+
+#endif /* _M68K_DIV64_H */
diff -Nru a/include/asm-m68knommu/dma.h b/include/asm-m68knommu/dma.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/dma.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,492 @@
+#ifndef _M68K_DMA_H
+#define _M68K_DMA_H 1
+ 
+//#define	DMA_DEBUG	1
+
+#include <linux/config.h>
+
+#ifdef CONFIG_COLDFIRE
+/*
+ * ColdFire DMA Model:
+ *   ColdFire DMA supports two forms of DMA: Single and Dual address. Single
+ * address mode emits a source address, and expects that the device will either
+ * pick up the data (DMA READ) or source data (DMA WRITE). This implies that
+ * the device will place data on the correct byte(s) of the data bus, as the
+ * memory transactions are always 32 bits. This implies that only 32 bit
+ * devices will find single mode transfers useful. Dual address DMA mode
+ * performs two cycles: source read and destination write. ColdFire will
+ * align the data so that the device will always get the correct bytes, thus
+ * is useful for 8 and 16 bit devices. This is the mode that is supported
+ * below.
+ *
+ * AUG/22/2000 : added support for 32-bit Dual-Address-Mode (K) 2000 
+ *               Oliver Kamphenkel (O.Kamphenkel@tu-bs.de)
+ *
+ * AUG/25/2000 : addad support for 8, 16 and 32-bit Single-Address-Mode (K)2000
+ *               Oliver Kamphenkel (O.Kamphenkel@tu-bs.de)
+ *
+ * APR/18/2002 : added proper support for MCF5272 DMA controller.
+ *               Arthur Shipkowski (art@videon-central.com)
+ */
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfdma.h>
+
+/*
+ * Set number of channels of DMA on ColdFire for different implementations.
+ */
+#if defined(CONFIG_M5307) || defined(CONFIG_M5407)
+#define MAX_M68K_DMA_CHANNELS 4
+#elif defined(CONFIG_M5272)
+#define MAX_M68K_DMA_CHANNELS 1
+#else
+#define MAX_M68K_DMA_CHANNELS 2
+#endif
+
+extern unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS];
+extern unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+
+#if !defined(CONFIG_M5272)
+#define DMA_MODE_WRITE_BIT  0x01  /* Memory/IO to IO/Memory select */
+#define DMA_MODE_WORD_BIT   0x02  /* 8 or 16 bit transfers */
+#define DMA_MODE_LONG_BIT   0x04  /* or 32 bit transfers */
+#define DMA_MODE_SINGLE_BIT 0x08  /* single-address-mode */
+
+/* I/O to memory, 8 bits, mode */
+#define DMA_MODE_READ	            0
+/* memory to I/O, 8 bits, mode */
+#define DMA_MODE_WRITE	            1
+/* I/O to memory, 16 bits, mode */
+#define DMA_MODE_READ_WORD          2
+/* memory to I/O, 16 bits, mode */
+#define DMA_MODE_WRITE_WORD         3
+/* I/O to memory, 32 bits, mode */
+#define DMA_MODE_READ_LONG          4
+/* memory to I/O, 32 bits, mode */
+#define DMA_MODE_WRITE_LONG         5
+/* I/O to memory, 8 bits, single-address-mode */     
+#define DMA_MODE_READ_SINGLE        8
+/* memory to I/O, 8 bits, single-address-mode */
+#define DMA_MODE_WRITE_SINGLE       9
+/* I/O to memory, 16 bits, single-address-mode */
+#define DMA_MODE_READ_WORD_SINGLE  10
+/* memory to I/O, 16 bits, single-address-mode */
+#define DMA_MODE_WRITE_WORD_SINGLE 11
+/* I/O to memory, 32 bits, single-address-mode */
+#define DMA_MODE_READ_LONG_SINGLE  12
+/* memory to I/O, 32 bits, single-address-mode */
+#define DMA_MODE_WRITE_LONG_SINGLE 13
+
+#else /* CONFIG_M5272 is defined */
+
+/* Source static-address mode */
+#define DMA_MODE_SRC_SA_BIT 0x01  
+/* Two bits to select between all four modes */
+#define DMA_MODE_SSIZE_MASK 0x06 
+/* Offset to shift bits in */
+#define DMA_MODE_SSIZE_OFF  0x01  
+/* Destination static-address mode */
+#define DMA_MODE_DES_SA_BIT 0x10  
+/* Two bits to select between all four modes */
+#define DMA_MODE_DSIZE_MASK 0x60  
+/* Offset to shift bits in */
+#define DMA_MODE_DSIZE_OFF  0x05
+/* Size modifiers */
+#define DMA_MODE_SIZE_LONG  0x00
+#define DMA_MODE_SIZE_BYTE  0x01
+#define DMA_MODE_SIZE_WORD  0x02
+#define DMA_MODE_SIZE_LINE  0x03
+
+/* 
+ * Aliases to help speed quick ports; these may be suboptimal, however. They
+ * do not include the SINGLE mode modifiers since the MCF5272 does not have a
+ * mode where the device is in control of its addressing.
+ */
+
+/* I/O to memory, 8 bits, mode */
+#define DMA_MODE_READ	              ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
+/* memory to I/O, 8 bits, mode */
+#define DMA_MODE_WRITE	            ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
+/* I/O to memory, 16 bits, mode */
+#define DMA_MODE_READ_WORD	        ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
+/* memory to I/O, 16 bits, mode */
+#define DMA_MODE_WRITE_WORD         ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
+/* I/O to memory, 32 bits, mode */
+#define DMA_MODE_READ_LONG	        ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
+/* memory to I/O, 32 bits, mode */
+#define DMA_MODE_WRITE_LONG         ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
+
+#endif /* !defined(CONFIG_M5272) */
+
+#if !defined(CONFIG_M5272)
+/* enable/disable a specific DMA channel */
+static __inline__ void enable_dma(unsigned int dmanr)
+{
+  volatile unsigned short *dmawp;
+
+#ifdef DMA_DEBUG
+  printk("enable_dma(dmanr=%d)\n", dmanr);
+#endif
+
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+  dmawp[MCFDMA_DCR] |= MCFDMA_DCR_EEXT;
+}
+
+static __inline__ void disable_dma(unsigned int dmanr)
+{
+  volatile unsigned short *dmawp;
+  volatile unsigned char  *dmapb;
+
+#ifdef DMA_DEBUG
+  printk("disable_dma(dmanr=%d)\n", dmanr);
+#endif
+
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+  dmapb = (unsigned char *) dma_base_addr[dmanr];
+
+  /* Turn off external requests, and stop any DMA in progress */
+  dmawp[MCFDMA_DCR] &= ~MCFDMA_DCR_EEXT;
+  dmapb[MCFDMA_DSR] = MCFDMA_DSR_DONE;
+}
+
+/*
+ * Clear the 'DMA Pointer Flip Flop'.
+ * Write 0 for LSB/MSB, 1 for MSB/LSB access.
+ * Use this once to initialize the FF to a known state.
+ * After that, keep track of it. :-)
+ * --- In order to do that, the DMA routines below should ---
+ * --- only be used while interrupts are disabled! ---
+ *
+ * This is a NOP for ColdFire. Provide a stub for compatibility.
+ */
+static __inline__ void clear_dma_ff(unsigned int dmanr)
+{
+}
+
+/* set mode (above) for a specific DMA channel */
+static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
+{
+
+  volatile unsigned char  *dmabp;
+  volatile unsigned short *dmawp;
+
+#ifdef DMA_DEBUG
+  printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode);
+#endif
+
+  dmabp = (unsigned char *) dma_base_addr[dmanr];
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+
+  // Clear config errors
+  dmabp[MCFDMA_DSR] = MCFDMA_DSR_DONE; 
+
+  // Set command register
+  dmawp[MCFDMA_DCR] =
+    MCFDMA_DCR_INT |         // Enable completion irq
+    MCFDMA_DCR_CS |          // Force one xfer per request
+    MCFDMA_DCR_AA |          // Enable auto alignment
+    // single-address-mode
+    ((mode & DMA_MODE_SINGLE_BIT) ? MCFDMA_DCR_SAA : 0) |
+    // sets s_rw (-> r/w) high if Memory to I/0
+    ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_S_RW : 0) |
+    // Memory to I/O or I/O to Memory
+    ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_SINC : MCFDMA_DCR_DINC) |
+    // 32 bit, 16 bit or 8 bit transfers
+    ((mode & DMA_MODE_WORD_BIT)  ? MCFDMA_DCR_SSIZE_WORD : 
+     ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_SSIZE_LONG :
+                                   MCFDMA_DCR_SSIZE_BYTE)) |
+    ((mode & DMA_MODE_WORD_BIT)  ? MCFDMA_DCR_DSIZE_WORD :
+     ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_DSIZE_LONG :
+                                   MCFDMA_DCR_DSIZE_BYTE));
+
+#ifdef DEBUG_DMA
+  printk("%s(%d): dmanr=%d DSR[%x]=%x DCR[%x]=%x\n", __FILE__, __LINE__,
+         dmanr, (int) &dmabp[MCFDMA_DSR], dmabp[MCFDMA_DSR],
+	 (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR]);
+#endif
+}
+
+/* Set transfer address for specific DMA channel */
+static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
+{
+  volatile unsigned short *dmawp;
+  volatile unsigned int   *dmalp;
+
+#ifdef DMA_DEBUG
+  printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a);
+#endif
+
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+
+  // Determine which address registers are used for memory/device accesses
+  if (dmawp[MCFDMA_DCR] & MCFDMA_DCR_SINC) {
+    // Source incrementing, must be memory
+    dmalp[MCFDMA_SAR] = a;
+    // Set dest address, must be device
+    dmalp[MCFDMA_DAR] = dma_device_address[dmanr];
+  } else {
+    // Destination incrementing, must be memory
+    dmalp[MCFDMA_DAR] = a;
+    // Set source address, must be device
+    dmalp[MCFDMA_SAR] = dma_device_address[dmanr];
+  }
+
+#ifdef DEBUG_DMA
+  printk("%s(%d): dmanr=%d DCR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n",
+	__FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR],
+	(int) &dmalp[MCFDMA_SAR], dmalp[MCFDMA_SAR],
+	(int) &dmalp[MCFDMA_DAR], dmalp[MCFDMA_DAR]);
+#endif
+}
+
+/*
+ * Specific for Coldfire - sets device address.
+ * Should be called after the mode set call, and before set DMA address.
+ */
+static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a)
+{
+#ifdef DMA_DEBUG
+  printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a);
+#endif
+
+  dma_device_address[dmanr] = a;
+}
+
+/*
+ * NOTE 2: "count" represents _bytes_.
+ */
+static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
+{
+  volatile unsigned short *dmawp;
+
+#ifdef DMA_DEBUG
+  printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count);
+#endif
+
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+  dmawp[MCFDMA_BCR] = (unsigned short)count;
+}
+
+/*
+ * Get DMA residue count. After a DMA transfer, this
+ * should return zero. Reading this while a DMA transfer is
+ * still in progress will return unpredictable results.
+ * Otherwise, it returns the number of _bytes_ left to transfer.
+ */
+static __inline__ int get_dma_residue(unsigned int dmanr)
+{
+  volatile unsigned short *dmawp;
+  unsigned short count;
+
+#ifdef DMA_DEBUG
+  printk("get_dma_residue(dmanr=%d)\n", dmanr);
+#endif
+
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+  count = dmawp[MCFDMA_BCR];
+  return((int) count);
+}
+#else /* CONFIG_M5272 is defined */
+
+/*
+ * The MCF5272 DMA controller is very different than the controller defined above
+ * in terms of register mapping.  For instance, with the exception of the 16-bit 
+ * interrupt register (IRQ#85, for reference), all of the registers are 32-bit.
+ *
+ * The big difference, however, is the lack of device-requested DMA.  All modes
+ * are dual address transfer, and there is no 'device' setup or direction bit.
+ * You can DMA between a device and memory, between memory and memory, or even between
+ * two devices directly, with any combination of incrementing and non-incrementing
+ * addresses you choose.  This puts a crimp in distinguishing between the 'device 
+ * address' set up by set_dma_device_addr.
+ *
+ * Therefore, there are two options.  One is to use set_dma_addr and set_dma_device_addr,
+ * which will act exactly as above in -- it will look to see if the source is set to
+ * autoincrement, and if so it will make the source use the set_dma_addr value and the
+ * destination the set_dma_device_addr value.  Otherwise the source will be set to the
+ * set_dma_device_addr value and the destination will get the set_dma_addr value.
+ *
+ * The other is to use the provided set_dma_src_addr and set_dma_dest_addr functions
+ * and make it explicit.  Depending on what you're doing, one of these two should work
+ * for you, but don't mix them in the same transfer setup.
+ */
+
+/* enable/disable a specific DMA channel */
+static __inline__ void enable_dma(unsigned int dmanr)
+{
+  volatile unsigned int  *dmalp;
+
+#ifdef DMA_DEBUG
+  printk("enable_dma(dmanr=%d)\n", dmanr);
+#endif
+
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+  dmalp[MCFDMA_DMR] |= MCFDMA_DMR_EN;
+}
+
+static __inline__ void disable_dma(unsigned int dmanr)
+{
+  volatile unsigned int   *dmalp;
+
+#ifdef DMA_DEBUG
+  printk("disable_dma(dmanr=%d)\n", dmanr);
+#endif
+
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+
+  /* Turn off external requests, and stop any DMA in progress */
+  dmalp[MCFDMA_DMR] &= ~MCFDMA_DMR_EN;
+  dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET;
+}
+
+/*
+ * Clear the 'DMA Pointer Flip Flop'.
+ * Write 0 for LSB/MSB, 1 for MSB/LSB access.
+ * Use this once to initialize the FF to a known state.
+ * After that, keep track of it. :-)
+ * --- In order to do that, the DMA routines below should ---
+ * --- only be used while interrupts are disabled! ---
+ *
+ * This is a NOP for ColdFire. Provide a stub for compatibility.
+ */
+static __inline__ void clear_dma_ff(unsigned int dmanr)
+{
+}
+
+/* set mode (above) for a specific DMA channel */
+static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
+{
+
+  volatile unsigned int   *dmalp;
+  volatile unsigned short *dmawp;
+
+#ifdef DMA_DEBUG
+  printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode);
+#endif
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+
+  // Clear config errors
+  dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET; 
+
+  // Set command register
+  dmalp[MCFDMA_DMR] =
+    MCFDMA_DMR_RQM_DUAL |         // Mandatory Request Mode setting
+    MCFDMA_DMR_DSTT_SD  |         // Set up addressing types; set to supervisor-data.
+    MCFDMA_DMR_SRCT_SD  |         // Set up addressing types; set to supervisor-data. 
+    // source static-address-mode
+    ((mode & DMA_MODE_SRC_SA_BIT) ? MCFDMA_DMR_SRCM_SA : MCFDMA_DMR_SRCM_IA) |
+    // dest static-address-mode
+    ((mode & DMA_MODE_DES_SA_BIT) ? MCFDMA_DMR_DSTM_SA : MCFDMA_DMR_DSTM_IA) |
+    // burst, 32 bit, 16 bit or 8 bit transfers are separately configurable on the MCF5272
+    (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_DSTS_OFF) |
+    (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_SRCS_OFF);
+    
+  dmawp[MCFDMA_DIR] |= MCFDMA_DIR_ASCEN;   /* Enable completion interrupts */
+  
+#ifdef DEBUG_DMA
+  printk("%s(%d): dmanr=%d DMR[%x]=%x DIR[%x]=%x\n", __FILE__, __LINE__,
+         dmanr, (int) &dmalp[MCFDMA_DMR], dmabp[MCFDMA_DMR],
+	 (int) &dmawp[MCFDMA_DIR], dmawp[MCFDMA_DIR]);
+#endif
+}
+
+/* Set transfer address for specific DMA channel */
+static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
+{
+  volatile unsigned int   *dmalp;
+
+#ifdef DMA_DEBUG
+  printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a);
+#endif
+
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+
+  // Determine which address registers are used for memory/device accesses
+  if (dmalp[MCFDMA_DMR] & MCFDMA_DMR_SRCM) {
+    // Source incrementing, must be memory
+    dmalp[MCFDMA_DSAR] = a;
+    // Set dest address, must be device
+    dmalp[MCFDMA_DDAR] = dma_device_address[dmanr];
+  } else {
+    // Destination incrementing, must be memory
+    dmalp[MCFDMA_DDAR] = a;
+    // Set source address, must be device
+    dmalp[MCFDMA_DSAR] = dma_device_address[dmanr];
+  }
+
+#ifdef DEBUG_DMA
+  printk("%s(%d): dmanr=%d DMR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n",
+	__FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DMR], dmawp[MCFDMA_DMR],
+	(int) &dmalp[MCFDMA_DSAR], dmalp[MCFDMA_DSAR],
+	(int) &dmalp[MCFDMA_DDAR], dmalp[MCFDMA_DDAR]);
+#endif
+}
+
+/*
+ * Specific for Coldfire - sets device address.
+ * Should be called after the mode set call, and before set DMA address.
+ */
+static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a)
+{
+#ifdef DMA_DEBUG
+  printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a);
+#endif
+
+  dma_device_address[dmanr] = a;
+}
+
+/*
+ * NOTE 2: "count" represents _bytes_.
+ *
+ * NOTE 3: While a 32-bit register, "count" is only a maximum 24-bit value.
+ */
+static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
+{
+  volatile unsigned int *dmalp;
+  
+#ifdef DMA_DEBUG
+  printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count);
+#endif
+
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+  dmalp[MCFDMA_DBCR] = count;
+}
+
+/*
+ * Get DMA residue count. After a DMA transfer, this
+ * should return zero. Reading this while a DMA transfer is
+ * still in progress will return unpredictable results.
+ * Otherwise, it returns the number of _bytes_ left to transfer.
+ */
+static __inline__ int get_dma_residue(unsigned int dmanr)
+{
+  volatile unsigned int *dmalp;
+  unsigned int count;
+
+#ifdef DMA_DEBUG
+  printk("get_dma_residue(dmanr=%d)\n", dmanr);
+#endif
+
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+  count = dmalp[MCFDMA_DBCR];
+  return(count);
+}
+
+#endif /* !defined(CONFIG_M5272) */
+#endif /* CONFIG_COLDFIRE */
+ 
+#define MAX_DMA_CHANNELS 8
+
+/* Don't define MAX_DMA_ADDRESS; it's useless on the m68k/coldfire and any
+   occurrence should be flagged as an error.  */
+/* under 2.4 it is actually needed by the new bootmem allocator */
+#define MAX_DMA_ADDRESS PAGE_OFFSET
+
+/* These are in kernel/dma.c: */
+extern int request_dma(unsigned int dmanr, const char *device_id);	/* reserve a DMA channel */
+extern void free_dma(unsigned int dmanr);	/* release it again */
+ 
+#endif /* _M68K_DMA_H */
diff -Nru a/include/asm-m68knommu/elf.h b/include/asm-m68knommu/elf.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/elf.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,95 @@
+#ifndef __ASMm68k_ELF_H
+#define __ASMm68k_ELF_H
+
+/*
+ * ELF register definitions..
+ */
+
+#include <linux/config.h>
+#include <asm/ptrace.h>
+#include <asm/user.h>
+
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct user_m68kfp_struct elf_fpregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ((x)->e_machine == EM_68K)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS	ELFCLASS32
+#define ELF_DATA	ELFDATA2MSB
+#define ELF_ARCH	EM_68K
+
+/* For SVR4/m68k the function pointer to be registered with `atexit' is
+   passed in %a1.  Although my copy of the ABI has no such statement, it
+   is actually used on ASV.  */
+#define ELF_PLAT_INIT(_r)	_r->a1 = 0
+
+#define USE_ELF_CORE_DUMP
+#ifndef CONFIG_SUN3
+#define ELF_EXEC_PAGESIZE	4096
+#else
+#define ELF_EXEC_PAGESIZE	8192
+#endif
+
+/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
+   use of this is to invoke "./ld.so someprog" to test out a new version of
+   the loader.  We need to make sure that it is out of the way of the program
+   that it will "exec", and that there is sufficient room for the brk.  */
+
+#ifndef CONFIG_SUN3
+#define ELF_ET_DYN_BASE         0xD0000000UL
+#else
+#define ELF_ET_DYN_BASE         0x0D800000UL
+#endif
+
+#define ELF_CORE_COPY_REGS(pr_reg, regs)				\
+	/* Bleech. */							\
+	pr_reg[0] = regs->d1;						\
+	pr_reg[1] = regs->d2;						\
+	pr_reg[2] = regs->d3;						\
+	pr_reg[3] = regs->d4;						\
+	pr_reg[4] = regs->d5;						\
+	pr_reg[7] = regs->a0;						\
+	pr_reg[8] = regs->a1;						\
+	pr_reg[14] = regs->d0;						\
+	pr_reg[15] = rdusp();						\
+	pr_reg[16] = 0 /* regs->orig_d0; */			\
+	pr_reg[17] = regs->sr;						\
+	pr_reg[18] = regs->pc;						\
+	/* pr_reg[19] = (regs->format << 12) | regs->vector; */		\
+	{								\
+	  struct switch_stack *sw = ((struct switch_stack *)regs) - 1;	\
+	  pr_reg[5] = sw->d6;						\
+	  pr_reg[6] = sw->d7;						\
+	  pr_reg[9] = sw->a2;						\
+	  pr_reg[10] = sw->a3;						\
+	  pr_reg[11] = sw->a4;						\
+	  pr_reg[12] = sw->a5;						\
+	  pr_reg[13] = sw->a6;						\
+	}
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this cpu supports.  */
+
+#define ELF_HWCAP	(0)
+
+/* This yields a string that ld.so will use to load implementation
+   specific libraries for optimization.  This is more specific in
+   intent than poking at uname or /proc/cpuinfo.  */
+
+#define ELF_PLATFORM  (NULL)
+
+#ifdef __KERNEL__
+#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#endif
+
+#endif
diff -Nru a/include/asm-m68knommu/elia.h b/include/asm-m68knommu/elia.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/elia.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,42 @@
+/****************************************************************************/
+
+/*
+ *	elia.h -- Lineo (formerly Moreton Bay) eLIA platform support.
+ *
+ *	(C) Copyright 1999-2000, Moreton Bay (www.moreton.com.au)
+ *	(C) Copyright 1999-2000, Lineo (www.lineo.com)
+ */
+
+/****************************************************************************/
+#ifndef	elia_h
+#define	elia_h
+/****************************************************************************/
+
+#include <linux/config.h>
+#include <asm/coldfire.h>
+
+#ifdef CONFIG_eLIA
+
+/*
+ *	The serial port DTR and DCD lines are also on the Parallel I/O
+ *	as well, so define those too.
+ */
+
+#define	eLIA_DCD1		0x0001
+#define	eLIA_DCD0		0x0002
+#define	eLIA_DTR1		0x0004
+#define	eLIA_DTR0		0x0008
+
+#define	eLIA_PCIRESET		0x0020
+
+/*
+ *	Kernel macros to set and unset the LEDs.
+ */
+#ifndef __ASSEMBLY__
+extern unsigned short	ppdata;
+#endif /* __ASSEMBLY__ */
+
+#endif	/* CONFIG_eLIA */
+
+/****************************************************************************/
+#endif	/* elia_h */
diff -Nru a/include/asm-m68knommu/entry.h b/include/asm-m68knommu/entry.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/entry.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,129 @@
+#ifndef __M68K_ENTRY_H
+#define __M68K_ENTRY_H
+
+#include <linux/config.h>
+#ifndef CONFIG_COLDFIRE
+#include <asm/setup.h>
+#include <asm/page.h>
+
+/*
+ * Stack layout in 'ret_from_exception':
+ *
+ *	This allows access to the syscall arguments in registers d1-d5
+ *
+ *	 0(sp) - d1
+ *	 4(sp) - d2
+ *	 8(sp) - d3
+ *	 C(sp) - d4
+ *	10(sp) - d5
+ *	14(sp) - a0
+ *	18(sp) - a1
+ *	1C(sp) - a2
+ *	20(sp) - d0
+ *	24(sp) - orig_d0
+ *	28(sp) - stack adjustment
+ *	2C(sp) - sr
+ *	2E(sp) - pc
+ *	32(sp) - format & vector
+ */
+
+/*
+ * 97/05/14 Andreas: Register %a2 is now set to the current task throughout
+ *		     the whole kernel.
+ */
+
+/* the following macro is used when enabling interrupts */
+#if defined(MACH_ATARI_ONLY) && !defined(CONFIG_HADES)
+	/* block out HSYNC on the atari */
+#define ALLOWINT 0xfbff
+#define	MAX_NOINT_IPL	3
+#else
+	/* portable version */
+#define ALLOWINT 0xf8ff
+#define	MAX_NOINT_IPL	0
+#endif /* machine compilation types */ 
+
+#ifdef __ASSEMBLY__
+
+#define curptr a2
+
+LFLUSH_I_AND_D = 0x00000808
+LSIGTRAP = 5
+
+/* process bits for task_struct.flags */
+PF_TRACESYS_OFF = 3
+PF_TRACESYS_BIT = 5
+PF_PTRACED_OFF = 3
+PF_PTRACED_BIT = 4
+PF_DTRACE_OFF = 1
+PF_DTRACE_BIT = 5
+
+#define SAVE_ALL_INT save_all_int
+#define SAVE_ALL_SYS save_all_sys
+#define RESTORE_ALL restore_all
+/*
+ * This defines the normal kernel pt-regs layout.
+ *
+ * regs a3-a6 and d6-d7 are preserved by C code
+ * the kernel doesn't mess with usp unless it needs to
+ */
+
+/*
+ * a -1 in the orig_d0 field signifies
+ * that the stack frame is NOT for syscall
+ */
+.macro	save_all_int VEC=0
+	oriw	#0x0700,%sr	/* disable interrupts */
+	clrl	%sp@-		/* stk_adj */
+	pea	-1:w		/* orig d0 */
+	movel	%d0,%sp@-	/* d0 */
+	moveml	%d1-%d5/%a0-%a1/%curptr,%sp@-
+.endm
+
+.macro	save_all_sys VEC=0
+	clrl	%sp@-		/* stk_adj */
+	movel	%d0,%sp@-	/* orig d0 */
+	movel	%d0,%sp@-	/* d0 */
+	moveml	%d1-%d5/%a0-%a1/%curptr,%sp@-
+.endm
+
+.macro	restore_all
+	moveml	%sp@+,%a0-%a1/%curptr/%d1-%d5
+	movel	%sp@+,%d0
+	addql	#4,%sp		/* orig d0 */
+	addl	%sp@+,%sp	/* stk adj */
+	rte
+.endm
+
+#define SWITCH_STACK_SIZE (6*4+4)	/* includes return address */
+
+#define SAVE_SWITCH_STACK save_switch_stack
+#define RESTORE_SWITCH_STACK restore_switch_stack
+#define GET_CURRENT(tmp)
+
+.macro	save_switch_stack
+	moveml	%a3-%a6/%d6-%d7,%sp@-
+.endm
+
+.macro	restore_switch_stack
+	moveml	%sp@+,%a3-%a6/%d6-%d7
+.endm
+
+#else /* C source */
+
+#define STR(X) STR1(X)
+#define STR1(X) #X
+
+#define PT_OFF_ORIG_D0	 0x24
+#define PT_OFF_FORMATVEC 0x32
+#define PT_OFF_SR	 0x2C
+#define SAVE_ALL_INT				\
+	"clrl	%%sp@-;"    /* stk_adj */	\
+	"pea	-1:w;"	    /* orig d0 = -1 */	\
+	"movel	%%d0,%%sp@-;" /* d0 */		\
+	"moveml	%%d1-%%d5/%%a0-%%a2,%%sp@-"
+
+#endif
+
+#endif /* CONFIG_COLDFIRE */
+#endif /* __M68K_ENTRY_H */
diff -Nru a/include/asm-m68knommu/errno.h b/include/asm-m68knommu/errno.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/errno.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1 @@
+#include <asm-m68k/errno.h>
diff -Nru a/include/asm-m68knommu/fcntl.h b/include/asm-m68knommu/fcntl.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/fcntl.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1 @@
+#include <asm-m68k/fcntl.h>
diff -Nru a/include/asm-m68knommu/fpu.h b/include/asm-m68knommu/fpu.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/fpu.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,22 @@
+#ifndef __M68KNOMMU_FPU_H
+#define __M68KNOMMU_FPU_H
+
+#include <linux/config.h>
+
+/*
+ * MAX floating point unit state size (FSAVE/FRESTORE)
+ */
+#if defined(CONFIG_M68020) || defined(CONFIG_M68030)
+#define FPSTATESIZE (216/sizeof(unsigned char))
+#elif defined(CONFIG_M68040)
+#define FPSTATESIZE (96/sizeof(unsigned char))
+#elif defined(CONFIG_M68KFPU_EMU)
+#define FPSTATESIZE (28/sizeof(unsigned char))
+#elif defined(CONFIG_M68060)
+#define FPSTATESIZE (12/sizeof(unsigned char))
+#else
+/* Assume no FP unit present then... */
+#define FPSTATESIZE (2) /* dummy size */
+#endif
+
+#endif /* __M68K_FPU_H */
diff -Nru a/include/asm-m68knommu/hardirq.h b/include/asm-m68knommu/hardirq.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/hardirq.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,102 @@
+#ifndef __M68K_HARDIRQ_H
+#define __M68K_HARDIRQ_H
+
+#include <linux/config.h>
+#include <linux/threads.h>
+
+typedef struct {
+	unsigned int __softirq_pending;
+	unsigned int __syscall_count;
+	struct task_struct * __ksoftirqd_task;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
+
+/*
+ * We put the hardirq and softirq counter into the preemption
+ * counter. The bitmask has the following meaning:
+ *
+ * - bits 0-7 are the preemption count (max preemption depth: 256)
+ * - bits 8-15 are the softirq count (max # of softirqs: 256)
+ * - bits 16-23 are the hardirq count (max # of hardirqs: 256)
+ *
+ * - ( bit 26 is the PREEMPT_ACTIVE flag. )
+ *
+ * PREEMPT_MASK: 0x000000ff
+ * HARDIRQ_MASK: 0x0000ff00
+ * SOFTIRQ_MASK: 0x00ff0000
+ */
+
+#define PREEMPT_BITS	8
+#define SOFTIRQ_BITS	8
+#define HARDIRQ_BITS	8
+
+#define PREEMPT_SHIFT	0
+#define SOFTIRQ_SHIFT	(PREEMPT_SHIFT + PREEMPT_BITS)
+#define HARDIRQ_SHIFT	(SOFTIRQ_SHIFT + SOFTIRQ_BITS)
+
+#define __MASK(x)	((1UL << (x))-1)
+
+#define PREEMPT_MASK	(__MASK(PREEMPT_BITS) << PREEMPT_SHIFT)
+#define HARDIRQ_MASK	(__MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT)
+#define SOFTIRQ_MASK	(__MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT)
+
+#define hardirq_count()	(preempt_count() & HARDIRQ_MASK)
+#define softirq_count()	(preempt_count() & SOFTIRQ_MASK)
+#define irq_count()	(preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK))
+
+#define PREEMPT_OFFSET	(1UL << PREEMPT_SHIFT)
+#define SOFTIRQ_OFFSET	(1UL << SOFTIRQ_SHIFT)
+#define HARDIRQ_OFFSET	(1UL << HARDIRQ_SHIFT)
+
+/*
+ * The hardirq mask has to be large enough to have
+ * space for potentially all IRQ sources in the system
+ * nesting on a single CPU:
+ */
+#if (1 << HARDIRQ_BITS) < NR_IRQS
+# error HARDIRQ_BITS is too low!
+#endif
+
+/*
+ * Are we doing bottom half or hardware interrupt processing?
+ * Are we in a softirq context? Interrupt context?
+ */
+#define in_irq()		(hardirq_count())
+#define in_softirq()		(softirq_count())
+#define in_interrupt()		(irq_count())
+
+#define hardirq_trylock()	(!in_interrupt())
+#define hardirq_endlock()	do { } while (0)
+
+#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
+
+#if CONFIG_PREEMPT
+# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
+#else
+# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
+#endif
+
+#if CONFIG_PREEMPT
+# define in_atomic()	(preempt_count() != kernel_locked())
+# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
+#else
+# define in_atomic()	(preempt_count() != 0)
+# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
+#endif
+
+#define irq_exit()							\
+do {									\
+		preempt_count() -= IRQ_EXIT_OFFSET;			\
+		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
+			do_softirq();					\
+		preempt_enable_no_resched();				\
+} while (0)
+
+#ifndef CONFIG_SMP
+# define synchronize_irq(irq)	barrier()
+#else
+# error m68knommu SMP is not available
+#endif /* CONFIG_SMP */
+
+#endif /* __M68K_HARDIRQ_H */
diff -Nru a/include/asm-m68knommu/hdreg.h b/include/asm-m68knommu/hdreg.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/hdreg.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1 @@
+#include <asm-m68k/hdreg.h>
diff -Nru a/include/asm-m68knommu/hwtest.h b/include/asm-m68knommu/hwtest.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/hwtest.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1 @@
+#include <asm-m68k/hwtest.h>
diff -Nru a/include/asm-m68knommu/ide.h b/include/asm-m68knommu/ide.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/ide.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,465 @@
+/****************************************************************************/
+/*
+ *  linux/include/asm-m68knommu/ide.h
+ *
+ *  Copyright (C) 1994-1996  Linus Torvalds & authors
+ *	Copyright (C) 2001       Lineo Inc., davidm@uclinux.org
+ */
+/****************************************************************************/
+#ifndef _M68KNOMMU_IDE_H
+#define _M68KNOMMU_IDE_H
+
+#ifdef __KERNEL__
+/****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/interrupt.h>
+
+#include <asm/setup.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+/****************************************************************************/
+/*
+ *	some coldfire specifics
+ */
+
+#ifdef CONFIG_COLDFIRE
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+
+/*
+ *	Save some space,  only have 1 interface
+ */
+#define MAX_HWIFS		  1	/* we only have one interface for now */
+
+#ifdef CONFIG_SECUREEDGEMP3
+#define	MCFSIM_LOCALCS	  MCFSIM_CSCR4
+#else
+#define	MCFSIM_LOCALCS	  MCFSIM_CSCR6
+#endif
+
+#endif /* CONFIG_COLDFIRE */
+
+/****************************************************************************/
+/*
+ *	Fix up things that may not have been provided
+ */
+
+#ifndef MAX_HWIFS
+#define MAX_HWIFS	4	/* same as the other archs */
+#endif
+
+#undef SUPPORT_SLOW_DATA_PORTS
+#define SUPPORT_SLOW_DATA_PORTS 0
+
+#undef SUPPORT_VLB_SYNC
+#define SUPPORT_VLB_SYNC 0
+
+/* this definition is used only on startup .. */
+#undef HD_DATA
+#define HD_DATA NULL
+
+#define	DBGIDE(fmt,a...)
+// #define	DBGIDE(fmt,a...) printk(fmt, ##a)
+#define IDE_INLINE __inline__
+// #define IDE_INLINE
+
+/****************************************************************************/
+
+typedef union {
+	unsigned all			: 8;	/* all of the bits together */
+	struct {
+		unsigned bit7		: 1;	/* always 1 */
+		unsigned lba		: 1;	/* using LBA instead of CHS */
+		unsigned bit5		: 1;	/* always 1 */
+		unsigned unit		: 1;	/* drive select number, 0 or 1 */
+		unsigned head		: 4;	/* always zeros here */
+	} b;
+} select_t;
+
+/*
+ *	our list of ports/irq's for different boards
+ */
+
+static struct m68k_ide_defaults {
+	ide_ioreg_t	base;
+	int			irq;
+} m68k_ide_defaults[MAX_HWIFS] = {
+#if defined(CONFIG_SECUREEDGEMP3)
+	{ ((ide_ioreg_t)0x30800000), 29 },
+#elif defined(CONFIG_eLIA)
+	{ ((ide_ioreg_t)0x30c00000), 29 },
+#else
+	{ ((ide_ioreg_t)0x0), 0 }
+#endif
+};
+
+/****************************************************************************/
+
+static IDE_INLINE int ide_default_irq(ide_ioreg_t base)
+{
+	int i;
+
+	for (i = 0; i < MAX_HWIFS; i++)
+		if (m68k_ide_defaults[i].base == base)
+			return(m68k_ide_defaults[i].irq);
+	return 0;
+}
+
+static IDE_INLINE ide_ioreg_t ide_default_io_base(int index)
+{
+	if (index >= 0 && index < MAX_HWIFS)
+		return(m68k_ide_defaults[index].base);
+	return 0;
+}
+
+
+/*
+ * Set up a hw structure for a specified data port, control port and IRQ.
+ * This should follow whatever the default interface uses.
+ */
+static IDE_INLINE void ide_init_hwif_ports(
+	hw_regs_t *hw,
+	ide_ioreg_t data_port,
+	ide_ioreg_t ctrl_port,
+	int *irq)
+{
+	ide_ioreg_t reg = data_port;
+	int i;
+
+	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
+		hw->io_ports[i] = reg;
+		reg += 1;
+	}
+	if (ctrl_port) {
+		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
+	} else {
+		hw->io_ports[IDE_CONTROL_OFFSET] = data_port + 0xe;
+	}
+}
+
+
+/*
+ * This registers the standard ports for this architecture with the IDE
+ * driver.
+ */
+static IDE_INLINE void ide_init_default_hwifs(void)
+{
+	hw_regs_t hw;
+	ide_ioreg_t base;
+	int index;
+
+	for (index = 0; index < MAX_HWIFS; index++) {
+		base = ide_default_io_base(index);
+		if (!base)
+			continue;
+		memset(&hw, 0, sizeof(hw));
+		ide_init_hwif_ports(&hw, base, 0, NULL);
+		hw.irq = ide_default_irq(base);
+		ide_register_hw(&hw, NULL);
+	}
+}
+
+
+static IDE_INLINE int
+ide_request_irq(
+	unsigned int irq,
+	void (*handler)(int, void *, struct pt_regs *),
+	unsigned long flags,
+	const char *device,
+	void *dev_id)
+{
+#ifdef CONFIG_COLDFIRE
+	mcf_autovector(irq);
+#endif
+	return(request_irq(irq, handler, flags, device, dev_id));
+}
+
+
+static IDE_INLINE void
+ide_free_irq(unsigned int irq, void *dev_id)
+{
+	free_irq(irq, dev_id);
+}
+
+
+static IDE_INLINE int
+ide_check_region(ide_ioreg_t from, unsigned int extent)
+{
+	return 0;
+}
+
+
+static IDE_INLINE void
+ide_request_region(ide_ioreg_t from, unsigned int extent, const char *name)
+{
+}
+
+
+static IDE_INLINE void
+ide_release_region(ide_ioreg_t from, unsigned int extent)
+{
+}
+
+
+static IDE_INLINE void
+ide_fix_driveid(struct hd_driveid *id)
+{
+#ifdef CONFIG_COLDFIRE
+	int i, n;
+	unsigned short *wp = (unsigned short *) id;
+	int avoid[] = {49, 51, 52, 59, -1 }; /* do not swap these words */
+
+	/* Need to byte swap shorts,  but not char fields */
+	for (i = n = 0; i < sizeof(*id) / sizeof(*wp); i++, wp++) {
+		if (avoid[n] == i) {
+			n++;
+			continue;
+		}
+		*wp = ((*wp & 0xff) << 8) | ((*wp >> 8) & 0xff);
+	}
+	/* have to word swap the one 32 bit field */
+	id->lba_capacity = ((id->lba_capacity & 0xffff) << 16) |
+				((id->lba_capacity >> 16) & 0xffff);
+#endif
+}
+
+
+static IDE_INLINE void
+ide_release_lock (int *ide_lock)
+{
+}
+
+
+static IDE_INLINE void
+ide_get_lock(
+	int *ide_lock,
+	void (*handler)(int, void *, struct pt_regs *),
+	void *data)
+{
+}
+
+
+#define ide_ack_intr(hwif) \
+	((hwif)->hw.ack_intr ? (hwif)->hw.ack_intr(hwif) : 1)
+#define	ide__sti()	__sti()
+
+/****************************************************************************/
+/*
+ *	System specific IO requirements
+ */
+
+#ifdef CONFIG_COLDFIRE
+
+#ifdef CONFIG_SECUREEDGEMP3
+
+/* Replace standard IO functions for funky mapping of MP3 board */
+#undef outb
+#undef outb_p
+#undef inb
+#undef inb_p
+
+#define outb(v, a)          ide_outb(v, (unsigned long) (a))
+#define outb_p(v, a)        ide_outb(v, (unsigned long) (a))
+#define inb(a)              ide_inb((unsigned long) (a))
+#define inb_p(a)            ide_inb((unsigned long) (a))
+
+#define ADDR8_PTR(addr)		(((addr) & 0x1) ? (0x8000 + (addr) - 1) : (addr))
+#define ADDR16_PTR(addr)	(addr)
+#define ADDR32_PTR(addr)	(addr)
+#define SWAP8(w)			((((w) & 0xffff) << 8) | (((w) & 0xffff) >> 8))
+#define SWAP16(w)			(w)
+#define SWAP32(w)			(w)
+
+
+static IDE_INLINE void
+ide_outb(unsigned int val, unsigned int addr)
+{
+	volatile unsigned short	*rp;
+
+	DBGIDE("%s(val=%x,addr=%x)\n", __FUNCTION__, val, addr);
+	rp = (volatile unsigned short *) ADDR8_PTR(addr);
+	*rp = SWAP8(val);
+}
+
+
+static IDE_INLINE int
+ide_inb(unsigned int addr)
+{
+	volatile unsigned short	*rp, val;
+
+	DBGIDE("%s(addr=%x)\n", __FUNCTION__, addr);
+	rp = (volatile unsigned short *) ADDR8_PTR(addr);
+	val = *rp;
+	return(SWAP8(val));
+}
+
+
+static IDE_INLINE void
+ide_outw(unsigned int val, unsigned int addr)
+{
+	volatile unsigned short	*rp;
+
+	DBGIDE("%s(val=%x,addr=%x)\n", __FUNCTION__, val, addr);
+	rp = (volatile unsigned short *) ADDR16_PTR(addr);
+	*rp = SWAP16(val);
+}
+
+static IDE_INLINE void
+ide_outsw(unsigned int addr, const void *vbuf, unsigned long len)
+{
+	volatile unsigned short	*rp, val;
+	unsigned short   	*buf;
+
+	DBGIDE("%s(addr=%x,vbuf=%p,len=%x)\n", __FUNCTION__, addr, vbuf, len);
+	buf = (unsigned short *) vbuf;
+	rp = (volatile unsigned short *) ADDR16_PTR(addr);
+	for (; (len > 0); len--) {
+		val = *buf++;
+		*rp = SWAP16(val);
+	}
+}
+
+static IDE_INLINE int
+ide_inw(unsigned int addr)
+{
+	volatile unsigned short *rp, val;
+
+	DBGIDE("%s(addr=%x)\n", __FUNCTION__, addr);
+	rp = (volatile unsigned short *) ADDR16_PTR(addr);
+	val = *rp;
+	return(SWAP16(val));
+}
+
+static IDE_INLINE void
+ide_insw(unsigned int addr, void *vbuf, unsigned long len)
+{
+	volatile unsigned short *rp;
+	unsigned short          w, *buf;
+
+	DBGIDE("%s(addr=%x,vbuf=%p,len=%x)\n", __FUNCTION__, addr, vbuf, len);
+	buf = (unsigned short *) vbuf;
+	rp = (volatile unsigned short *) ADDR16_PTR(addr);
+	for (; (len > 0); len--) {
+		w = *rp;
+		*buf++ = SWAP16(w);
+	}
+}
+
+static IDE_INLINE void
+ide_insl(unsigned int addr, void *vbuf, unsigned long len)
+{
+	volatile unsigned long *rp;
+	unsigned long          w, *buf;
+
+	DBGIDE("%s(addr=%x,vbuf=%p,len=%x)\n", __FUNCTION__, addr, vbuf, len);
+	buf = (unsigned long *) vbuf;
+	rp = (volatile unsigned long *) ADDR32_PTR(addr);
+	for (; (len > 0); len--) {
+		w = *rp;
+		*buf++ = SWAP32(w);
+	}
+}
+
+static IDE_INLINE void
+ide_outsl(unsigned int addr, const void *vbuf, unsigned long len)
+{
+	volatile unsigned long	*rp, val;
+	unsigned long   	*buf;
+
+	DBGIDE("%s(addr=%x,vbuf=%p,len=%x)\n", __FUNCTION__, addr, vbuf, len);
+	buf = (unsigned long *) vbuf;
+	rp = (volatile unsigned long *) ADDR32_PTR(addr);
+	for (; (len > 0); len--) {
+		val = *buf++;
+		*rp = SWAP32(val);
+	}
+}
+
+#elif CONFIG_eLIA
+
+/* 8/16 bit acesses are controlled by flicking bits in the CS register */
+#define	ACCESS_MODE_16BIT()	\
+	*((volatile unsigned short *) (MCF_MBAR + MCFSIM_LOCALCS)) = 0x0080
+#define	ACCESS_MODE_8BIT()	\
+	*((volatile unsigned short *) (MCF_MBAR + MCFSIM_LOCALCS)) = 0x0040
+
+
+static IDE_INLINE void
+ide_outw(unsigned int val, unsigned int addr)
+{
+	ACCESS_MODE_16BIT();
+	outw(val, addr);
+	ACCESS_MODE_8BIT();
+}
+
+static IDE_INLINE void
+ide_outsw(unsigned int addr, const void *vbuf, unsigned long len)
+{
+	ACCESS_MODE_16BIT();
+	outsw(addr, vbuf, len);
+	ACCESS_MODE_8BIT();
+}
+
+static IDE_INLINE int
+ide_inw(unsigned int addr)
+{
+	int ret;
+
+	ACCESS_MODE_16BIT();
+	ret = inw(addr);
+	ACCESS_MODE_8BIT();
+	return(ret);
+}
+
+static IDE_INLINE void
+ide_insw(unsigned int addr, void *vbuf, unsigned long len)
+{
+	ACCESS_MODE_16BIT();
+	insw(addr, vbuf, len);
+	ACCESS_MODE_8BIT();
+}
+
+static IDE_INLINE void
+ide_insl(unsigned int addr, void *vbuf, unsigned long len)
+{
+	ACCESS_MODE_16BIT();
+	insl(addr, vbuf, len);
+	ACCESS_MODE_8BIT();
+}
+
+static IDE_INLINE void
+ide_outsl(unsigned int addr, const void *vbuf, unsigned long len)
+{
+	ACCESS_MODE_16BIT();
+	outsl(addr, vbuf, len);
+	ACCESS_MODE_8BIT();
+}
+
+#endif /* CONFIG_SECUREEDGEMP3 */
+
+#undef outw
+#undef outw_p
+#undef outsw
+#undef inw
+#undef inw_p
+#undef insw
+#undef insl
+#undef outsl
+
+#define	outw(v, a)	     ide_outw(v, (unsigned long) (a))
+#define	outw_p(v, a)     ide_outw(v, (unsigned long) (a))
+#define outsw(a, b, n)   ide_outsw((unsigned long) (a), b, n)
+#define	inw(a)	         ide_inw((unsigned long) (a))
+#define	inw_p(a)	     ide_inw((unsigned long) (a))
+#define insw(a, b, n)    ide_insw((unsigned long) (a), b, n)
+#define insl(a, b, n)    ide_insl((unsigned long) (a), b, n)
+#define outsl(a, b, n)   ide_outsl((unsigned long) (a), b, n)
+
+#endif CONFIG_COLDFIRE
+
+/****************************************************************************/
+#endif /* __KERNEL__ */
+#endif /* _M68KNOMMU_IDE_H */
+/****************************************************************************/
diff -Nru a/include/asm-m68knommu/init.h b/include/asm-m68knommu/init.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/init.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/init.h>
diff -Nru a/include/asm-m68knommu/io.h b/include/asm-m68knommu/io.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/io.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,179 @@
+#ifndef _M68KNOMMU_IO_H
+#define _M68KNOMMU_IO_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+
+/*
+ * These are for ISA/PCI shared memory _only_ and should never be used
+ * on any other type of memory, including Zorro memory. They are meant to
+ * access the bus in the bus byte order which is little-endian!.
+ *
+ * readX/writeX() are used to access memory mapped devices. On some
+ * architectures the memory mapped IO stuff needs to be accessed
+ * differently. On the m68k architecture, we just read/write the
+ * memory location directly.
+ */
+/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
+ * two accesses to memory, which may be undesireable for some devices.
+ */
+
+/*
+ * swap functions are sometimes needed to interface little-endian hardware
+ */
+static inline unsigned short _swapw(volatile unsigned short v)
+{
+    return ((v << 8) | (v >> 8));
+}
+
+static inline unsigned int _swapl(volatile unsigned long v)
+{
+    return ((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | (v >> 24));
+}
+
+#define readb(addr) \
+    ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; })
+#define readw(addr) \
+    ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; })
+#define readl(addr) \
+    ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
+
+#define writeb(b,addr) (void)((*(volatile unsigned char *) (addr)) = (b))
+#define writew(b,addr) (void)((*(volatile unsigned short *) (addr)) = (b))
+#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b))
+
+static inline void io_outsb(unsigned int addr, void *buf, int len)
+{
+	volatile unsigned char *ap = (volatile unsigned char *) addr;
+	unsigned char *bp = (unsigned char *) buf;
+	while (len--)
+		*ap = *bp++;
+}
+
+static inline void io_outsw(unsigned int addr, void *buf, int len)
+{
+	volatile unsigned short *ap = (volatile unsigned short *) addr;
+	unsigned short *bp = (unsigned short *) buf;
+	while (len--)
+		*ap = _swapw(*bp++);
+}
+
+static inline void io_outsl(unsigned int addr, void *buf, int len)
+{
+	volatile unsigned int *ap = (volatile unsigned int *) addr;
+	unsigned int *bp = (unsigned int *) buf;
+	while (len--)
+		*ap = _swapl(*bp++);
+}
+
+static inline void io_insb(unsigned int addr, void *buf, int len)
+{
+	volatile unsigned char *ap = (volatile unsigned char *) addr;
+	unsigned char *bp = (unsigned char *) buf;
+	while (len--)
+		*bp++ = *ap;
+}
+
+static inline void io_insw(unsigned int addr, void *buf, int len)
+{
+	volatile unsigned short *ap = (volatile unsigned short *) addr;
+	unsigned short *bp = (unsigned short *) buf;
+	while (len--)
+		*bp++ = _swapw(*ap);
+}
+
+static inline void io_insl(unsigned int addr, void *buf, int len)
+{
+	volatile unsigned int *ap = (volatile unsigned int *) addr;
+	unsigned int *bp = (unsigned int *) buf;
+	while (len--)
+		*bp++ = _swapl(*ap);
+}
+
+/*
+ *	make the short names macros so specific devices
+ *	can override them as required
+ */
+
+#define memset_io(a,b,c)	memset((void *)(a),(b),(c))
+#define memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
+#define memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
+
+#define inb(addr)      readb(addr)
+#define inw(addr)    readw(addr)
+#define inl(addr)    readl(addr)
+#define outb(x,addr) ((void) writeb(x,addr))
+#define outw(x,addr) ((void) writew(x,addr))
+#define outl(x,addr) ((void) writel(x,addr))
+
+#define inb_p(addr)    inb(addr)
+#define inw_p(addr)    inw(addr)
+#define inl_p(addr)    inl(addr)
+#define outb_p(x,addr) outb(x,addr)
+#define outw_p(x,addr) outw(x,addr)
+#define outl_p(x,addr) outl(x,addr)
+
+#define outsb(a,b,l) io_outsb(a,b,l)
+#define outsw(a,b,l) io_outsw(a,b,l)
+#define outsl(a,b,l) io_outsl(a,b,l)
+
+#define insb(a,b,l) io_insb(a,b,l)
+#define insw(a,b,l) io_insw(a,b,l)
+#define insl(a,b,l) io_insl(a,b,l)
+
+#define IO_SPACE_LIMIT 0xffff
+
+
+/* Values for nocacheflag and cmode */
+#define IOMAP_FULL_CACHING		0
+#define IOMAP_NOCACHE_SER		1
+#define IOMAP_NOCACHE_NONSER		2
+#define IOMAP_WRITETHROUGH		3
+
+extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
+extern void __iounmap(void *addr, unsigned long size);
+
+extern inline void *ioremap(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+}
+extern inline void *ioremap_nocache(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+}
+extern inline void *ioremap_writethrough(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
+}
+extern inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
+}
+
+extern void iounmap(void *addr);
+
+/* Nothing to do */
+
+#define dma_cache_inv(_start,_size)		do { } while (0)
+#define dma_cache_wback(_start,_size)		do { } while (0)
+#define dma_cache_wback_inv(_start,_size)	do { } while (0)
+
+/* Pages to physical address... */
+#define page_to_phys(page)      ((page - mem_map) << PAGE_SHIFT)
+#define page_to_bus(page)       ((page - mem_map) << PAGE_SHIFT)
+
+/*
+ * Macros used for converting between virtual and physical mappings.
+ */
+#define mm_ptov(vaddr)		((void *) (vaddr))
+#define mm_vtop(vaddr)		((unsigned long) (vaddr))
+#define phys_to_virt(vaddr)	((void *) (vaddr))
+#define virt_to_phys(vaddr)	((unsigned long) (vaddr))
+
+#define virt_to_bus virt_to_phys
+#define bus_to_virt phys_to_virt
+
+#endif /* __KERNEL__ */
+
+#endif /* _M68KNOMMU_IO_H */
diff -Nru a/include/asm-m68knommu/io_hw_swap.h b/include/asm-m68knommu/io_hw_swap.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/io_hw_swap.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,113 @@
+#ifndef _M68K_IO_HW_SWAP_H
+#define _M68K_IO_HW_SWAP_H
+
+/*
+ * swap functions are sometimes needed to interface little-endian hardware
+ */
+static inline unsigned short _swapw(volatile unsigned short v)
+{
+    return ((v << 8) | (v >> 8));
+}
+
+static inline unsigned int _swapl(volatile unsigned long v)
+{
+    return ((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | (v >> 24));
+}
+
+/*
+ * readX/writeX() are used to access memory mapped devices. On some
+ * architectures the memory mapped IO stuff needs to be accessed
+ * differently. On the m68k architecture, we just read/write the
+ * memory location directly.
+ */
+/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
+ * two accesses to memory, which may be undesireable for some devices.
+ */
+#define readb(addr) \
+    ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; })
+#define readw(addr) \
+    ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; })
+#define readl(addr) \
+    ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
+
+#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
+#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b))
+#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
+
+/* There is no difference between I/O and memory on 68k, these are the same */
+#define inb(addr) \
+    ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; })
+#define inw(addr) \
+    ({ unsigned short __v = (*(volatile unsigned short *) (addr)); \
+       _swapw(__v); })
+#define inl(addr) \
+    ({ unsigned int __v = (*(volatile unsigned int *) (addr)); _swapl(__v); })
+
+#define outb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
+#define outw(b,addr) ((*(volatile unsigned short *) (addr)) = (_swapw(b)))
+#define outl(b,addr) ((*(volatile unsigned int *) (addr)) = (_swapl(b)))
+
+/* FIXME: these need to be optimized.  Watch out for byte swapping, they
+ * are used mostly for Intel devices... */
+#define outsw(addr,buf,len) \
+    ({ unsigned short * __p = (unsigned short *)(buf); \
+       unsigned short * __e = (unsigned short *)(__p) + (len); \
+       while (__p < __e) { \
+	  *(volatile unsigned short *)(addr) = *__p++;\
+       } \
+     })
+
+#define insw(addr,buf,len) \
+    ({ unsigned short * __p = (unsigned short *)(buf); \
+       unsigned short * __e = (unsigned short *)(__p) + (len); \
+       while (__p < __e) { \
+          *(__p++) = *(volatile unsigned short *)(addr); \
+       } \
+     })
+
+
+static inline unsigned char get_user_byte_io(const char * addr)
+{
+	register unsigned char _v;
+
+	__asm__ __volatile__ ("moveb %1,%0":"=dm" (_v):"m" (*addr));
+	return _v;
+}
+#define inb_p(addr) get_user_byte_io((char *)(addr))
+
+static inline void put_user_byte_io(char val,char *addr)
+{
+	__asm__ __volatile__ ("moveb %0,%1"
+			      : /* no outputs */
+			      :"idm" (val),"m" (*addr)
+			      : "memory");
+}
+#define outb_p(x,addr) put_user_byte_io((x),(char *)(addr))
+
+/*
+ * Change virtual addresses to physical addresses and vv.
+ * These are trivial on the 1:1 Linux/i386 mapping (but if we ever
+ * make the kernel segment mapped at 0, we need to do translation
+ * on the i386 as well)
+ */
+extern unsigned long mm_vtop(unsigned long addr);
+extern unsigned long mm_ptov(unsigned long addr);
+
+extern inline unsigned long virt_to_phys(volatile void * address)
+{
+	return (unsigned long) mm_vtop((unsigned long)address);
+}
+
+extern inline void * phys_to_virt(unsigned long address)
+{
+	return (void *) mm_ptov(address);
+}
+
+/*
+ * IO bus memory addresses are also 1:1 with the physical address
+ */
+#define virt_to_bus virt_to_phys
+#define bus_to_virt phys_to_virt
+
+
+#endif /* _M68K_IO_HW_SWAP_H */
diff -Nru a/include/asm-m68knommu/ioctl.h b/include/asm-m68knommu/ioctl.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/ioctl.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1 @@
+#include <asm-m68k/ioctl.h>
diff -Nru a/include/asm-m68knommu/ioctls.h b/include/asm-m68knommu/ioctls.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/ioctls.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1 @@
+#include <asm-m68k/ioctls.h>
diff -Nru a/include/asm-m68knommu/ipc.h b/include/asm-m68knommu/ipc.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/ipc.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/ipc.h>
diff -Nru a/include/asm-m68knommu/ipcbuf.h b/include/asm-m68knommu/ipcbuf.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/ipcbuf.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/ipcbuf.h>
diff -Nru a/include/asm-m68knommu/irq.h b/include/asm-m68knommu/irq.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/irq.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,128 @@
+#ifndef _M68K_IRQ_H_
+#define _M68K_IRQ_H_
+
+#include <linux/config.h>
+#include <asm/ptrace.h>
+
+#ifdef CONFIG_COLDFIRE
+/*
+ * On the ColdFire we keep track of all vectors. That way drivers
+ * can register whatever vector number they wish, and we can deal
+ * with it.
+ */
+#define	SYS_IRQS	256
+#define	NR_IRQS		SYS_IRQS
+
+#else
+
+/*
+ * # of m68k interrupts
+ */
+#define SYS_IRQS 8
+#define NR_IRQS (24+SYS_IRQS)
+
+#endif /* CONFIG_COLDFIRE */
+
+/*
+ * Interrupt source definitions
+ * General interrupt sources are the level 1-7.
+ * Adding an interrupt service routine for one of these sources
+ * results in the addition of that routine to a chain of routines.
+ * Each one is called in succession.  Each individual interrupt
+ * service routine should determine if the device associated with
+ * that routine requires service.
+ */
+
+#define IRQ1		(1)	/* level 1 interrupt */
+#define IRQ2		(2)	/* level 2 interrupt */
+#define IRQ3		(3)	/* level 3 interrupt */
+#define IRQ4		(4)	/* level 4 interrupt */
+#define IRQ5		(5)	/* level 5 interrupt */
+#define IRQ6		(6)	/* level 6 interrupt */
+#define IRQ7		(7)	/* level 7 interrupt (non-maskable) */
+
+/*
+ * Machine specific interrupt sources.
+ *
+ * Adding an interrupt service routine for a source with this bit
+ * set indicates a special machine specific interrupt source.
+ * The machine specific files define these sources.
+ *
+ * The IRQ_MACHSPEC bit is now gone - the only thing it did was to
+ * introduce unnecessary overhead.
+ *
+ * All interrupt handling is actually machine specific so it is better
+ * to use function pointers, as used by the Sparc port, and select the
+ * interrupt handling functions when initializing the kernel. This way
+ * we save some unnecessary overhead at run-time. 
+ *                                                      01/11/97 - Jes
+ */
+
+extern void (*mach_enable_irq)(unsigned int);
+extern void (*mach_disable_irq)(unsigned int);
+
+extern int sys_request_irq(unsigned int, 
+	void (*)(int, void *, struct pt_regs *), 
+	unsigned long, const char *, void *);
+extern void sys_free_irq(unsigned int, void *);
+
+/*
+ * various flags for request_irq() - the Amiga now uses the standard
+ * mechanism like all other architectures - SA_INTERRUPT and SA_SHIRQ
+ * are your friends.
+ */
+#define IRQ_FLG_LOCK	(0x0001)	/* handler is not replaceable	*/
+#define IRQ_FLG_REPLACE	(0x0002)	/* replace existing handler	*/
+#define IRQ_FLG_FAST	(0x0004)
+#define IRQ_FLG_SLOW	(0x0008)
+#define IRQ_FLG_STD	(0x8000)	/* internally used		*/
+
+#ifdef CONFIG_M68360
+
+#define CPM_INTERRUPT    IRQ4
+
+/* see MC68360 User's Manual, p. 7-377  */
+#define CPM_VECTOR_BASE  0x04           /* 3 MSbits of CPM vector */
+
+#endif /* CONFIG_M68360 */
+
+/*
+ * This structure is used to chain together the ISRs for a particular
+ * interrupt source (if it supports chaining).
+ */
+typedef struct irq_node {
+	void		(*handler)(int, void *, struct pt_regs *);
+	unsigned long	flags;
+	void		*dev_id;
+	const char	*devname;
+	struct irq_node *next;
+} irq_node_t;
+
+/*
+ * This structure has only 4 elements for speed reasons
+ */
+typedef struct irq_handler {
+	void		(*handler)(int, void *, struct pt_regs *);
+	unsigned long	flags;
+	void		*dev_id;
+	const char	*devname;
+} irq_handler_t;
+
+/* count of spurious interrupts */
+extern volatile unsigned int num_spurious;
+
+/*
+ * This function returns a new irq_node_t
+ */
+extern irq_node_t *new_irq_node(void);
+
+/*
+ * Some drivers want these entry points
+ */
+#define enable_irq(x)	(mach_enable_irq  ? (*mach_enable_irq)(x)  : 0)
+#define disable_irq(x)	(mach_disable_irq ? (*mach_disable_irq)(x) : 0)
+
+#define enable_irq_nosync(x)	enable_irq(x)
+#define disable_irq_nosync(x)	disable_irq(x)
+
+#endif /* _M68K_IRQ_H_ */
diff -Nru a/include/asm-m68knommu/keyboard.h b/include/asm-m68knommu/keyboard.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/keyboard.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1 @@
+#include <asm-m68k/keyboard.h>
diff -Nru a/include/asm-m68knommu/kmap_types.h b/include/asm-m68knommu/kmap_types.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/kmap_types.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,19 @@
+#ifndef _ASM_KMAP_TYPES_H
+#define _ASM_KMAP_TYPES_H
+
+enum km_type {
+	KM_BOUNCE_READ,
+	KM_SKB_SUNRPC_DATA,
+	KM_SKB_DATA_SOFTIRQ,
+	KM_USER0,
+	KM_USER1,
+	KM_BIO_SRC_IRQ,
+	KM_BIO_DST_IRQ,
+	KM_PTE0,
+	KM_PTE1,
+	KM_IRQ0,
+	KM_IRQ1,
+	KM_TYPE_NR
+};
+
+#endif
diff -Nru a/include/asm-m68knommu/linkage.h b/include/asm-m68knommu/linkage.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/linkage.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/linkage.h>
diff -Nru a/include/asm-m68knommu/linux_logo.h b/include/asm-m68knommu/linux_logo.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/linux_logo.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,13 @@
+/*
+ * include/asm-m68knommu/linux_logo.h: This is a linux logo
+ *                                 to be displayed on boot.
+ */
+ 
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/version.h>
+
+#define linux_logo_banner "Linux/m68knommu version " UTS_RELEASE
+
+#include <linux/linux_logo.h>
+
diff -Nru a/include/asm-m68knommu/m5206sim.h b/include/asm-m68knommu/m5206sim.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/m5206sim.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,132 @@
+/****************************************************************************/
+
+/*
+ *	m5206sim.h -- ColdFire 5206 System Integration Module support.
+ *
+ *	(C) Copyright 1999, Greg Ungerer (gerg@snapgear.com)
+ * 	(C) Copyright 2000, Lineo Inc. (www.lineo.com) 
+ */
+
+/****************************************************************************/
+#ifndef	m5206sim_h
+#define	m5206sim_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/*
+ *	Define the 5206 SIM register set addresses.
+ */
+#define	MCFSIM_SIMR		0x03		/* SIM Config reg (r/w) */
+#define	MCFSIM_ICR1		0x14		/* Intr Ctrl reg 1 (r/w) */
+#define	MCFSIM_ICR2		0x15		/* Intr Ctrl reg 2 (r/w) */
+#define	MCFSIM_ICR3		0x16		/* Intr Ctrl reg 3 (r/w) */
+#define	MCFSIM_ICR4		0x17		/* Intr Ctrl reg 4 (r/w) */
+#define	MCFSIM_ICR5		0x18		/* Intr Ctrl reg 5 (r/w) */
+#define	MCFSIM_ICR6		0x19		/* Intr Ctrl reg 6 (r/w) */
+#define	MCFSIM_ICR7		0x1a		/* Intr Ctrl reg 7 (r/w) */
+#define	MCFSIM_ICR8		0x1b		/* Intr Ctrl reg 8 (r/w) */
+#define	MCFSIM_ICR9		0x1c		/* Intr Ctrl reg 9 (r/w) */
+#define	MCFSIM_ICR10		0x1d		/* Intr Ctrl reg 10 (r/w) */
+#define	MCFSIM_ICR11		0x1e		/* Intr Ctrl reg 11 (r/w) */
+#define	MCFSIM_ICR12		0x1f		/* Intr Ctrl reg 12 (r/w) */
+#define	MCFSIM_ICR13		0x20		/* Intr Ctrl reg 13 (r/w) */
+#ifdef CONFIG_M5206e
+#define	MCFSIM_ICR14		0x21		/* Intr Ctrl reg 14 (r/w) */
+#define	MCFSIM_ICR15		0x22		/* Intr Ctrl reg 15 (r/w) */
+#endif
+
+#define MCFSIM_IMR		0x36		/* Interrupt Mask reg (r/w) */
+#define MCFSIM_IPR		0x3a		/* Interrupt Pend reg (r/w) */
+
+#define	MCFSIM_RSR		0x40		/* Reset Status reg (r/w) */
+#define	MCFSIM_SYPCR		0x41		/* System Protection reg (r/w)*/
+
+#define	MCFSIM_SWIVR		0x42		/* SW Watchdog intr reg (r/w) */
+#define	MCFSIM_SWSR		0x43		/* SW Watchdog service (r/w) */
+
+#define	MCFSIM_DCRR		0x46		/* DRAM Refresh reg (r/w) */
+#define	MCFSIM_DCTR		0x4a		/* DRAM Timing reg (r/w) */
+#define	MCFSIM_DCAR0		0x4c		/* DRAM 0 Address reg(r/w) */
+#define	MCFSIM_DCMR0		0x50		/* DRAM 0 Mask reg (r/w) */
+#define	MCFSIM_DCCR0		0x57		/* DRAM 0 Control reg (r/w) */
+#define	MCFSIM_DCAR1		0x58		/* DRAM 1 Address reg (r/w) */
+#define	MCFSIM_DCMR1		0x5c		/* DRAM 1 Mask reg (r/w) */
+#define	MCFSIM_DCCR1		0x63		/* DRAM 1 Control reg (r/w) */
+
+#define	MCFSIM_CSAR0		0x64		/* CS 0 Address 0 reg (r/w) */
+#define	MCFSIM_CSMR0		0x68		/* CS 0 Mask 0 reg (r/w) */
+#define	MCFSIM_CSCR0		0x6e		/* CS 0 Control reg (r/w) */
+#define	MCFSIM_CSAR1		0x70		/* CS 1 Address reg (r/w) */
+#define	MCFSIM_CSMR1		0x74		/* CS 1 Mask reg (r/w) */
+#define	MCFSIM_CSCR1		0x7a		/* CS 1 Control reg (r/w) */
+#define	MCFSIM_CSAR2		0x7c		/* CS 2 Address reg (r/w) */
+#define	MCFSIM_CSMR2		0x80		/* CS 2 Mask reg (r/w) */
+#define	MCFSIM_CSCR2		0x86		/* CS 2 Control reg (r/w) */
+#define	MCFSIM_CSAR3		0x88		/* CS 3 Address reg (r/w) */
+#define	MCFSIM_CSMR3		0x8c		/* CS 3 Mask reg (r/w) */
+#define	MCFSIM_CSCR3		0x92		/* CS 3 Control reg (r/w) */
+#define	MCFSIM_CSAR4		0x94		/* CS 4 Address reg (r/w) */
+#define	MCFSIM_CSMR4		0x98		/* CS 4 Mask reg (r/w) */
+#define	MCFSIM_CSCR4		0x9e		/* CS 4 Control reg (r/w) */
+#define	MCFSIM_CSAR5		0xa0		/* CS 5 Address reg (r/w) */
+#define	MCFSIM_CSMR5		0xa4		/* CS 5 Mask reg (r/w) */
+#define	MCFSIM_CSCR5		0xaa		/* CS 5 Control reg (r/w) */
+#define	MCFSIM_CSAR6		0xac		/* CS 6 Address reg (r/w) */
+#define	MCFSIM_CSMR6		0xb0		/* CS 6 Mask reg (r/w) */
+#define	MCFSIM_CSCR6		0xb6		/* CS 6 Control reg (r/w) */
+#define	MCFSIM_CSAR7		0xb8		/* CS 7 Address reg (r/w) */
+#define	MCFSIM_CSMR7		0xbc		/* CS 7 Mask reg (r/w) */
+#define	MCFSIM_CSCR7		0xc2		/* CS 7 Control reg (r/w) */
+#define	MCFSIM_DMCR		0xc6		/* Default control */
+
+#ifdef CONFIG_M5206e
+#define	MCFSIM_PAR		0xca		/* Pin Assignment reg (r/w) */
+#else
+#define	MCFSIM_PAR		0xcb		/* Pin Assignment reg (r/w) */
+#endif
+
+#define	MCFSIM_PADDR		0x1c5		/* Parallel Direction (r/w) */
+#define	MCFSIM_PADAT		0x1c9		/* Parallel Port Value (r/w) */
+
+/*
+ *	Some symbol defines for the Parallel Port Pin Assignment Register
+ */
+#ifdef CONFIG_M5206e
+#define MCFSIM_PAR_DREQ0        0x100           /* Set to select DREQ0 input */
+                                                /* Clear to select T0 input */
+#define MCFSIM_PAR_DREQ1        0x200           /* Select DREQ1 input */
+                                                /* Clear to select T0 output */
+#endif
+
+/*
+ *	Some symbol defines for the Interrupt Control Register
+ */
+#define	MCFSIM_SWDICR		MCFSIM_ICR8	/* Watchdog timer ICR */
+#define	MCFSIM_TIMER1ICR	MCFSIM_ICR9	/* Timer 1 ICR */
+#define	MCFSIM_TIMER2ICR	MCFSIM_ICR10	/* Timer 2 ICR */
+#define	MCFSIM_UART1ICR		MCFSIM_ICR12	/* UART 1 ICR */
+#define	MCFSIM_UART2ICR		MCFSIM_ICR13	/* UART 2 ICR */
+#ifdef CONFIG_M5206e
+#define	MCFSIM_DMA1ICR		MCFSIM_ICR14	/* DMA 1 ICR */
+#define	MCFSIM_DMA2ICR		MCFSIM_ICR15	/* DMA 2 ICR */
+#endif
+
+#if defined(CONFIG_M5206e)
+#define	MCFSIM_IMR_MASKALL	0xfffe		/* All SIM intr sources */
+#endif
+
+/*
+ *	Macro to get and set IMR register. It is 16 bits on the 5206.
+ */
+#define	mcf_getimr()		\
+	*((volatile unsigned short *) (MCF_MBAR + MCFSIM_IMR))
+
+#define	mcf_setimr(imr)		\
+	*((volatile unsigned short *) (MCF_MBAR + MCFSIM_IMR)) = (imr)
+
+#define	mcf_getipr()		\
+	*((volatile unsigned short *) (MCF_MBAR + MCFSIM_IPR))
+
+/****************************************************************************/
+#endif	/* m5206sim_h */
diff -Nru a/include/asm-m68knommu/m5249sim.h b/include/asm-m68knommu/m5249sim.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/m5249sim.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,119 @@
+/****************************************************************************/
+
+/*
+ *	m5249sim.h -- ColdFire 5249 System Integration Module support.
+ *
+ *	(C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/****************************************************************************/
+#ifndef	m5249sim_h
+#define	m5249sim_h
+/****************************************************************************/
+
+/*
+ *	Define the 5249 SIM register set addresses.
+ */
+#define	MCFSIM_RSR		0x00		/* Reset Status reg (r/w) */
+#define	MCFSIM_SYPCR		0x01		/* System Protection reg (r/w)*/
+#define	MCFSIM_SWIVR		0x02		/* SW Watchdog intr reg (r/w) */
+#define	MCFSIM_SWSR		0x03		/* SW Watchdog service (r/w) */
+#define	MCFSIM_PAR		0x04		/* Pin Assignment reg (r/w) */
+#define	MCFSIM_IRQPAR		0x06		/* Interrupt Assignment reg (r/w) */
+#define	MCFSIM_MPARK		0x0C		/* BUS Master Control Reg*/
+#define	MCFSIM_IPR		0x40		/* Interrupt Pend reg (r/w) */
+#define	MCFSIM_IMR		0x44		/* Interrupt Mask reg (r/w) */
+#define	MCFSIM_AVR		0x4b		/* Autovector Ctrl reg (r/w) */
+#define	MCFSIM_ICR0		0x4c		/* Intr Ctrl reg 0 (r/w) */
+#define	MCFSIM_ICR1		0x4d		/* Intr Ctrl reg 1 (r/w) */
+#define	MCFSIM_ICR2		0x4e		/* Intr Ctrl reg 2 (r/w) */
+#define	MCFSIM_ICR3		0x4f		/* Intr Ctrl reg 3 (r/w) */
+#define	MCFSIM_ICR4		0x50		/* Intr Ctrl reg 4 (r/w) */
+#define	MCFSIM_ICR5		0x51		/* Intr Ctrl reg 5 (r/w) */
+#define	MCFSIM_ICR6		0x52		/* Intr Ctrl reg 6 (r/w) */
+#define	MCFSIM_ICR7		0x53		/* Intr Ctrl reg 7 (r/w) */
+#define	MCFSIM_ICR8		0x54		/* Intr Ctrl reg 8 (r/w) */
+#define	MCFSIM_ICR9		0x55		/* Intr Ctrl reg 9 (r/w) */
+#define	MCFSIM_ICR10		0x56		/* Intr Ctrl reg 10 (r/w) */
+#define	MCFSIM_ICR11		0x57		/* Intr Ctrl reg 11 (r/w) */
+
+#define MCFSIM_CSAR0		0x80		/* CS 0 Address 0 reg (r/w) */
+#define MCFSIM_CSMR0		0x84		/* CS 0 Mask 0 reg (r/w) */
+#define MCFSIM_CSCR0		0x8a		/* CS 0 Control reg (r/w) */
+#define MCFSIM_CSAR1		0x8c		/* CS 1 Address reg (r/w) */
+#define MCFSIM_CSMR1		0x90		/* CS 1 Mask reg (r/w) */
+#define MCFSIM_CSCR1		0x96		/* CS 1 Control reg (r/w) */
+#define MCFSIM_CSAR2		0x98		/* CS 2 Adress reg (r/w) */
+#define MCFSIM_CSMR2		0x9c		/* CS 2 Mask reg (r/w) */
+#define MCFSIM_CSCR2		0xa2		/* CS 2 Control reg (r/w) */
+#define MCFSIM_CSAR3		0xa4		/* CS 3 Adress reg (r/w) */
+#define MCFSIM_CSMR3		0xa8		/* CS 3 Mask reg (r/w) */
+#define MCFSIM_CSCR3		0xae		/* CS 3 Control reg (r/w) */
+
+#define MCFSIM_DCR		0x100		/* DRAM Control reg (r/w) */
+#define MCFSIM_DACR0		0x108		/* DRAM 0 Addr and Ctrl (r/w) */
+#define MCFSIM_DMR0		0x10c		/* DRAM 0 Mask reg (r/w) */
+#define MCFSIM_DACR1		0x110		/* DRAM 1 Addr and Ctrl (r/w) */
+#define MCFSIM_DMR1		0x114		/* DRAM 1 Mask reg (r/w) */
+
+
+/*
+ *	Some symbol defines for the above...
+ */
+#define	MCFSIM_SWDICR		MCFSIM_ICR0	/* Watchdog timer ICR */
+#define	MCFSIM_TIMER1ICR	MCFSIM_ICR1	/* Timer 1 ICR */
+#define	MCFSIM_TIMER2ICR	MCFSIM_ICR2	/* Timer 2 ICR */
+#define	MCFSIM_UART1ICR		MCFSIM_ICR4	/* UART 1 ICR */
+#define	MCFSIM_UART2ICR		MCFSIM_ICR5	/* UART 2 ICR */
+#define	MCFSIM_DMA0ICR		MCFSIM_ICR6	/* DMA 0 ICR */
+#define	MCFSIM_DMA1ICR		MCFSIM_ICR7	/* DMA 1 ICR */
+#define	MCFSIM_DMA2ICR		MCFSIM_ICR8	/* DMA 2 ICR */
+#define	MCFSIM_DMA3ICR		MCFSIM_ICR9	/* DMA 3 ICR */
+
+/*
+ *	General purpose IO registers (in MBAR2).
+ */
+#define	MCFSIM2_GPIOREAD	0x0		/* GPIO read values */
+#define	MCFSIM2_GPIOWRITE	0x4		/* GPIO write values */
+#define	MCFSIM2_GPIOENABLE	0x8		/* GPIO enabled */
+#define	MCFSIM2_GPIOFUNC	0xc		/* GPIO function */
+#define	MCFSIM2_GPIO1READ	0xb0		/* GPIO1 read values */
+#define	MCFSIM2_GPIO1WRITE	0xb4		/* GPIO1 write values */
+#define	MCFSIM2_GPIO1ENABLE	0xb8		/* GPIO1 enabled */
+#define	MCFSIM2_GPIO1FUNC	0xbc		/* GPIO1 function */
+
+#define	MCFSIM2_GPIOINTSTAT	0xc0		/* GPIO interrupt status */
+#define	MCFSIM2_GPIOINTCLEAR	0xc0		/* GPIO interrupt clear */
+#define	MCFSIM2_GPIOINTENABLE	0xc4		/* GPIO interrupt enable */
+
+#define	MCFSIM2_INTLEVEL1	0x140		/* Interrupt level reg 1 */
+#define	MCFSIM2_INTLEVEL2	0x144		/* Interrupt level reg 2 */
+#define	MCFSIM2_INTLEVEL3	0x148		/* Interrupt level reg 3 */
+#define	MCFSIM2_INTLEVEL4	0x14c		/* Interrupt level reg 4 */
+#define	MCFSIM2_INTLEVEL5	0x150		/* Interrupt level reg 5 */
+#define	MCFSIM2_INTLEVEL6	0x154		/* Interrupt level reg 6 */
+#define	MCFSIM2_INTLEVEL7	0x158		/* Interrupt level reg 7 */
+#define	MCFSIM2_INTLEVEL8	0x15c		/* Interrupt level reg 8 */
+
+#define	MCFSIM2_DMAROUTE	0x188		/* DMA routing */
+
+#define	MCFSIM2_IDECONFIG1	0x18c		/* IDEconfig1 */
+#define	MCFSIM2_IDECONFIG2	0x190		/* IDEconfig2 */
+
+
+/*
+ *	Macro to set IMR register. It is 32 bits on the 5249.
+ */
+#define	MCFSIM_IMR_MASKALL	0x7fffe		/* All SIM intr sources */
+
+#define	mcf_getimr()		\
+	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR))
+
+#define	mcf_setimr(imr)		\
+	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr);
+
+#define	mcf_getipr()		\
+	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR))
+
+/****************************************************************************/
+#endif	/* m5249sim_h */
diff -Nru a/include/asm-m68knommu/m5272sim.h b/include/asm-m68knommu/m5272sim.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/m5272sim.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,79 @@
+/****************************************************************************/
+
+/*
+ *	m5272sim.h -- ColdFire 5272 System Integration Module support.
+ *
+ *	(C) Copyright 1999, Greg Ungerer (gerg@snapgear.com)
+ * 	(C) Copyright 2000, Lineo Inc. (www.lineo.com) 
+ */
+
+/****************************************************************************/
+#ifndef	m5272sim_h
+#define	m5272sim_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/*
+ *	Define the 5272 SIM register set addresses.
+ */
+#define	MCFSIM_SCR		0x04		/* SIM Config reg (r/w) */
+#define	MCFSIM_SPR		0x06		/* System Protection reg (r/w)*/
+#define	MCFSIM_PMR		0x08		/* Power Management reg (r/w) */
+#define	MCFSIM_APMR		0x0e		/* Active Low Power reg (r/w) */
+#define	MCFSIM_DIR		0x10		/* Device Identity reg (r/w) */
+
+#define	MCFSIM_ICR1		0x20		/* Intr Ctrl reg 1 (r/w) */
+#define	MCFSIM_ICR2		0x24		/* Intr Ctrl reg 2 (r/w) */
+#define	MCFSIM_ICR3		0x28		/* Intr Ctrl reg 3 (r/w) */
+#define	MCFSIM_ICR4		0x2c		/* Intr Ctrl reg 4 (r/w) */
+
+#define MCFSIM_ISR		0x30		/* Interrupt Source reg (r/w) */
+#define MCFSIM_PITR		0x34		/* Interrupt Transition (r/w) */
+#define	MCFSIM_PIWR		0x38		/* Interrupt Wakeup reg (r/w) */
+#define	MCFSIM_PIVR		0x3f		/* Interrupt Vector reg (r/w( */
+
+#define	MCFSIM_WRRR		0x280		/* Watchdog reference (r/w) */
+#define	MCFSIM_WIRR		0x284		/* Watchdog interrupt (r/w) */
+#define	MCFSIM_WCR		0x288		/* Watchdog counter (r/w) */
+#define	MCFSIM_WER		0x28c		/* Watchdog event (r/w) */
+
+#define	MCFSIM_CSBR0		0x40		/* CS0 Base Address (r/w) */
+#define	MCFSIM_CSOR0		0x44		/* CS0 Option (r/w) */
+#define	MCFSIM_CSBR1		0x48		/* CS1 Base Address (r/w) */
+#define	MCFSIM_CSOR1		0x4c		/* CS1 Option (r/w) */
+#define	MCFSIM_CSBR2		0x50		/* CS2 Base Address (r/w) */
+#define	MCFSIM_CSOR2		0x54		/* CS2 Option (r/w) */
+#define	MCFSIM_CSBR3		0x58		/* CS3 Base Address (r/w) */
+#define	MCFSIM_CSOR3		0x5c		/* CS3 Option (r/w) */
+#define	MCFSIM_CSBR4		0x60		/* CS4 Base Address (r/w) */
+#define	MCFSIM_CSOR4		0x64		/* CS4 Option (r/w) */
+#define	MCFSIM_CSBR5		0x68		/* CS5 Base Address (r/w) */
+#define	MCFSIM_CSOR5		0x6c		/* CS5 Option (r/w) */
+#define	MCFSIM_CSBR6		0x70		/* CS6 Base Address (r/w) */
+#define	MCFSIM_CSOR6		0x74		/* CS6 Option (r/w) */
+#define	MCFSIM_CSBR7		0x78		/* CS7 Base Address (r/w) */
+#define	MCFSIM_CSOR7		0x7c		/* CS7 Option (r/w) */
+
+#define	MCFSIM_SDCR		0x180		/* SDRAM Configuration (r/w) */
+#define	MCFSIM_SDTR		0x184		/* SDRAM Timing (r/w) */
+#define	MCFSIM_DCAR0		0x4c		/* DRAM 0 Address reg(r/w) */
+#define	MCFSIM_DCMR0		0x50		/* DRAM 0 Mask reg (r/w) */
+#define	MCFSIM_DCCR0		0x57		/* DRAM 0 Control reg (r/w) */
+#define	MCFSIM_DCAR1		0x58		/* DRAM 1 Address reg (r/w) */
+#define	MCFSIM_DCMR1		0x5c		/* DRAM 1 Mask reg (r/w) */
+#define	MCFSIM_DCCR1		0x63		/* DRAM 1 Control reg (r/w) */
+
+#define	MCFSIM_PACNT		0x80		/* Port A Control (r/w) */
+#define	MCFSIM_PADDR		0x84		/* Port A Direction (r/w) */
+#define	MCFSIM_PADAT		0x86		/* Port A Data (r/w) */
+#define	MCFSIM_PBCNT		0x88		/* Port B Control (r/w) */
+#define	MCFSIM_PBDDR		0x8c		/* Port B Direction (r/w) */
+#define	MCFSIM_PBDAT		0x8e		/* Port B Data (r/w) */
+#define	MCFSIM_PCDDR		0x94		/* Port C Direction (r/w) */
+#define	MCFSIM_PCDAT		0x96		/* Port C Data (r/w) */
+#define	MCFSIM_PDCNT		0x98		/* Port D Control (r/w) */
+
+
+/****************************************************************************/
+#endif	/* m5272sim_h */
diff -Nru a/include/asm-m68knommu/m5307sim.h b/include/asm-m68knommu/m5307sim.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/m5307sim.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,181 @@
+/****************************************************************************/
+
+/*
+ *	m5307sim.h -- ColdFire 5307 System Integration Module support.
+ *
+ *	(C) Copyright 1999,  Moreton Bay Ventures Pty Ltd.
+ *	(C) Copyright 1999,  Lineo (www.lineo.com)
+ *
+ *      Modified by David W. Miller for the MCF5307 Eval Board.
+ */
+
+/****************************************************************************/
+#ifndef	m5307sim_h
+#define	m5307sim_h
+/****************************************************************************/
+
+/*
+ *	Define the 5307 SIM register set addresses.
+ */
+#define	MCFSIM_RSR		0x00		/* Reset Status reg (r/w) */
+#define	MCFSIM_SYPCR		0x01		/* System Protection reg (r/w)*/
+#define	MCFSIM_SWIVR		0x02		/* SW Watchdog intr reg (r/w) */
+#define	MCFSIM_SWSR		0x03		/* SW Watchdog service (r/w) */
+#define	MCFSIM_PAR		0x04		/* Pin Assignment reg (r/w) */
+#define	MCFSIM_IRQPAR		0x06		/* Interrupt Assignment reg (r/w) */
+#define	MCFSIM_PLLCR		0x08		/* PLL Controll Reg*/
+#define	MCFSIM_MPARK		0x0C		/* BUS Master Control Reg*/
+#define	MCFSIM_IPR		0x40		/* Interrupt Pend reg (r/w) */
+#define	MCFSIM_IMR		0x44		/* Interrupt Mask reg (r/w) */
+#define	MCFSIM_AVR		0x4b		/* Autovector Ctrl reg (r/w) */
+#define	MCFSIM_ICR0		0x4c		/* Intr Ctrl reg 0 (r/w) */
+#define	MCFSIM_ICR1		0x4d		/* Intr Ctrl reg 1 (r/w) */
+#define	MCFSIM_ICR2		0x4e		/* Intr Ctrl reg 2 (r/w) */
+#define	MCFSIM_ICR3		0x4f		/* Intr Ctrl reg 3 (r/w) */
+#define	MCFSIM_ICR4		0x50		/* Intr Ctrl reg 4 (r/w) */
+#define	MCFSIM_ICR5		0x51		/* Intr Ctrl reg 5 (r/w) */
+#define	MCFSIM_ICR6		0x52		/* Intr Ctrl reg 6 (r/w) */
+#define	MCFSIM_ICR7		0x53		/* Intr Ctrl reg 7 (r/w) */
+#define	MCFSIM_ICR8		0x54		/* Intr Ctrl reg 8 (r/w) */
+#define	MCFSIM_ICR9		0x55		/* Intr Ctrl reg 9 (r/w) */
+#define	MCFSIM_ICR10		0x56		/* Intr Ctrl reg 10 (r/w) */
+#define	MCFSIM_ICR11		0x57		/* Intr Ctrl reg 11 (r/w) */
+
+#define MCFSIM_CSAR0		0x80		/* CS 0 Address 0 reg (r/w) */
+#define MCFSIM_CSMR0		0x84		/* CS 0 Mask 0 reg (r/w) */
+#define MCFSIM_CSCR0		0x8a		/* CS 0 Control reg (r/w) */
+#define MCFSIM_CSAR1		0x8c		/* CS 1 Address reg (r/w) */
+#define MCFSIM_CSMR1		0x90		/* CS 1 Mask reg (r/w) */
+#define MCFSIM_CSCR1		0x96		/* CS 1 Control reg (r/w) */
+
+#ifdef CONFIG_OLDMASK
+#define MCFSIM_CSBAR		0x98		/* CS Base Address reg (r/w) */
+#define MCFSIM_CSBAMR		0x9c		/* CS Base Mask reg (r/w) */
+#define MCFSIM_CSMR2		0x9e		/* CS 2 Mask reg (r/w) */
+#define MCFSIM_CSCR2		0xa2		/* CS 2 Control reg (r/w) */
+#define MCFSIM_CSMR3		0xaa		/* CS 3 Mask reg (r/w) */
+#define MCFSIM_CSCR3		0xae		/* CS 3 Control reg (r/w) */
+#define MCFSIM_CSMR4		0xb6		/* CS 4 Mask reg (r/w) */
+#define MCFSIM_CSCR4		0xba		/* CS 4 Control reg (r/w) */
+#define MCFSIM_CSMR5		0xc2		/* CS 5 Mask reg (r/w) */
+#define MCFSIM_CSCR5		0xc6		/* CS 5 Control reg (r/w) */
+#define MCFSIM_CSMR6		0xce		/* CS 6 Mask reg (r/w) */
+#define MCFSIM_CSCR6		0xd2		/* CS 6 Control reg (r/w) */
+#define MCFSIM_CSMR7		0xda		/* CS 7 Mask reg (r/w) */
+#define MCFSIM_CSCR7		0xde		/* CS 7 Control reg (r/w) */
+#else
+#define MCFSIM_CSAR2		0x98		/* CS 2 Adress reg (r/w) */
+#define MCFSIM_CSMR2		0x9c		/* CS 2 Mask reg (r/w) */
+#define MCFSIM_CSCR2		0xa2		/* CS 2 Control reg (r/w) */
+#define MCFSIM_CSAR3		0xa4		/* CS 3 Adress reg (r/w) */
+#define MCFSIM_CSMR3		0xa8		/* CS 3 Mask reg (r/w) */
+#define MCFSIM_CSCR3		0xae		/* CS 3 Control reg (r/w) */
+#define MCFSIM_CSAR4		0xb0		/* CS 4 Adress reg (r/w) */
+#define MCFSIM_CSMR4		0xb4		/* CS 4 Mask reg (r/w) */
+#define MCFSIM_CSCR4		0xba		/* CS 4 Control reg (r/w) */
+#define MCFSIM_CSAR5		0xbc		/* CS 5 Adress reg (r/w) */
+#define MCFSIM_CSMR5		0xc0		/* CS 5 Mask reg (r/w) */
+#define MCFSIM_CSCR5		0xc6		/* CS 5 Control reg (r/w) */
+#define MCFSIM_CSAR6		0xc8		/* CS 6 Adress reg (r/w) */
+#define MCFSIM_CSMR6		0xcc		/* CS 6 Mask reg (r/w) */
+#define MCFSIM_CSCR6		0xd2		/* CS 6 Control reg (r/w) */
+#define MCFSIM_CSAR7		0xd4		/* CS 7 Adress reg (r/w) */
+#define MCFSIM_CSMR7		0xd8		/* CS 7 Mask reg (r/w) */
+#define MCFSIM_CSCR7		0xde		/* CS 7 Control reg (r/w) */
+#endif /* CONFIG_OLDMASK */
+
+#define MCFSIM_DCR		0x100		/* DRAM Control reg (r/w) */
+#define MCFSIM_DACR0		0x108		/* DRAM 0 Addr and Ctrl (r/w) */
+#define MCFSIM_DMR0		0x10c		/* DRAM 0 Mask reg (r/w) */
+#define MCFSIM_DACR1		0x110		/* DRAM 1 Addr and Ctrl (r/w) */
+#define MCFSIM_DMR1		0x114		/* DRAM 1 Mask reg (r/w) */
+
+#define	MCFSIM_PADDR		0x244		/* Parallel Direction (r/w) */
+#define	MCFSIM_PADAT		0x248		/* Parallel Data (r/w) */
+
+
+/* Definition offset address for CS2-7  -- old mask 5307 */
+
+#define	MCF5307_CS2		(0x400000)
+#define	MCF5307_CS3		(0x600000)
+#define	MCF5307_CS4		(0x800000)
+#define	MCF5307_CS5		(0xA00000)
+#define	MCF5307_CS6		(0xC00000)
+#define	MCF5307_CS7		(0xE00000)
+
+
+/*
+ *	Some symbol defines for the above...
+ */
+#define	MCFSIM_SWDICR		MCFSIM_ICR0	/* Watchdog timer ICR */
+#define	MCFSIM_TIMER1ICR	MCFSIM_ICR1	/* Timer 1 ICR */
+#define	MCFSIM_TIMER2ICR	MCFSIM_ICR2	/* Timer 2 ICR */
+#define	MCFSIM_UART1ICR		MCFSIM_ICR4	/* UART 1 ICR */
+#define	MCFSIM_UART2ICR		MCFSIM_ICR5	/* UART 2 ICR */
+#define	MCFSIM_DMA0ICR		MCFSIM_ICR6	/* DMA 0 ICR */
+#define	MCFSIM_DMA1ICR		MCFSIM_ICR7	/* DMA 1 ICR */
+#define	MCFSIM_DMA2ICR		MCFSIM_ICR8	/* DMA 2 ICR */
+#define	MCFSIM_DMA3ICR		MCFSIM_ICR9	/* DMA 3 ICR */
+
+#if defined(CONFIG_M5307)
+#define	MCFSIM_IMR_MASKALL	0x3fffe		/* All SIM intr sources */
+#endif
+
+/*
+ *	Macro to set IMR register. It is 32 bits on the 5307.
+ */
+#define	mcf_getimr()		\
+	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR))
+
+#define	mcf_setimr(imr)		\
+	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr);
+
+#define	mcf_getipr()		\
+	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR))
+
+
+/*
+ *	Some symbol defines for the Parallel Port Pin Assignment Register
+ */
+#define MCFSIM_PAR_DREQ0        0x40            /* Set to select DREQ0 input */
+                                                /* Clear to select par I/O */
+#define MCFSIM_PAR_DREQ1        0x20            /* Select DREQ1 input */
+                                                /* Clear to select par I/O */
+
+/*
+ *       Defines for the IRQPAR Register
+ */
+#define IRQ5_LEVEL4	0x80
+#define IRQ3_LEVEL6	0x40
+#define IRQ1_LEVEL2	0x20
+
+
+/*
+ *	Define the Cache register flags.
+ */
+#define	CACR_EC			(1<<31)
+#define	CACR_ESB		(1<<29)
+#define	CACR_DPI		(1<<28)
+#define	CACR_HLCK		(1<<27)
+#define	CACR_CINVA		(1<<24)
+#define	CACR_DNFB		(1<<10)
+#define	CACR_DCM_WTHRU		(0<<8)
+#define	CACR_DCM_WBACK		(1<<8)
+#define	CACR_DCM_OFF_PRE	(2<<8)
+#define	CACR_DCM_OFF_IMP	(3<<8)
+#define	CACR_DW			(1<<5)
+
+#define	ACR_BASE_POS		24
+#define	ACR_MASK_POS		16
+#define	ACR_ENABLE		(1<<15)
+#define	ACR_USER		(0<<13)
+#define	ACR_SUPER		(1<<13)
+#define	ACR_ANY			(2<<13)
+#define	ACR_CM_WTHRU		(0<<5)
+#define	ACR_CM_WBACK		(1<<5)
+#define	ACR_CM_OFF_PRE		(2<<5)
+#define	ACR_CM_OFF_IMP		(3<<5)
+#define	ACR_WPROTECT		(1<<2)
+
+/****************************************************************************/
+#endif	/* m5307sim_h */
diff -Nru a/include/asm-m68knommu/m5407sim.h b/include/asm-m68knommu/m5407sim.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/m5407sim.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,157 @@
+/****************************************************************************/
+
+/*
+ *	m5407sim.h -- ColdFire 5407 System Integration Module support.
+ *
+ *	(C) Copyright 2000,  Lineo (www.lineo.com)
+ *	(C) Copyright 1999,  Moreton Bay Ventures Pty Ltd.
+ *
+ *      Modified by David W. Miller for the MCF5307 Eval Board.
+ */
+
+/****************************************************************************/
+#ifndef	m5407sim_h
+#define	m5407sim_h
+/****************************************************************************/
+
+/*
+ *	Define the 5407 SIM register set addresses.
+ */
+#define	MCFSIM_RSR		0x00		/* Reset Status reg (r/w) */
+#define	MCFSIM_SYPCR		0x01		/* System Protection reg (r/w)*/
+#define	MCFSIM_SWIVR		0x02		/* SW Watchdog intr reg (r/w) */
+#define	MCFSIM_SWSR		0x03		/* SW Watchdog service (r/w) */
+#define	MCFSIM_PAR		0x04		/* Pin Assignment reg (r/w) */
+#define	MCFSIM_IRQPAR		0x06		/* Interrupt Assignment reg (r/w) */
+#define	MCFSIM_PLLCR		0x08		/* PLL Controll Reg*/
+#define	MCFSIM_MPARK		0x0C		/* BUS Master Control Reg*/
+#define	MCFSIM_IPR		0x40		/* Interrupt Pend reg (r/w) */
+#define	MCFSIM_IMR		0x44		/* Interrupt Mask reg (r/w) */
+#define	MCFSIM_AVR		0x4b		/* Autovector Ctrl reg (r/w) */
+#define	MCFSIM_ICR0		0x4c		/* Intr Ctrl reg 0 (r/w) */
+#define	MCFSIM_ICR1		0x4d		/* Intr Ctrl reg 1 (r/w) */
+#define	MCFSIM_ICR2		0x4e		/* Intr Ctrl reg 2 (r/w) */
+#define	MCFSIM_ICR3		0x4f		/* Intr Ctrl reg 3 (r/w) */
+#define	MCFSIM_ICR4		0x50		/* Intr Ctrl reg 4 (r/w) */
+#define	MCFSIM_ICR5		0x51		/* Intr Ctrl reg 5 (r/w) */
+#define	MCFSIM_ICR6		0x52		/* Intr Ctrl reg 6 (r/w) */
+#define	MCFSIM_ICR7		0x53		/* Intr Ctrl reg 7 (r/w) */
+#define	MCFSIM_ICR8		0x54		/* Intr Ctrl reg 8 (r/w) */
+#define	MCFSIM_ICR9		0x55		/* Intr Ctrl reg 9 (r/w) */
+#define	MCFSIM_ICR10		0x56		/* Intr Ctrl reg 10 (r/w) */
+#define	MCFSIM_ICR11		0x57		/* Intr Ctrl reg 11 (r/w) */
+
+#define MCFSIM_CSAR0		0x80		/* CS 0 Address 0 reg (r/w) */
+#define MCFSIM_CSMR0		0x84		/* CS 0 Mask 0 reg (r/w) */
+#define MCFSIM_CSCR0		0x8a		/* CS 0 Control reg (r/w) */
+#define MCFSIM_CSAR1		0x8c		/* CS 1 Address reg (r/w) */
+#define MCFSIM_CSMR1		0x90		/* CS 1 Mask reg (r/w) */
+#define MCFSIM_CSCR1		0x96		/* CS 1 Control reg (r/w) */
+
+#define MCFSIM_CSAR2		0x98		/* CS 2 Adress reg (r/w) */
+#define MCFSIM_CSMR2		0x9c		/* CS 2 Mask reg (r/w) */
+#define MCFSIM_CSCR2		0xa2		/* CS 2 Control reg (r/w) */
+#define MCFSIM_CSAR3		0xa4		/* CS 3 Adress reg (r/w) */
+#define MCFSIM_CSMR3		0xa8		/* CS 3 Mask reg (r/w) */
+#define MCFSIM_CSCR3		0xae		/* CS 3 Control reg (r/w) */
+#define MCFSIM_CSAR4		0xb0		/* CS 4 Adress reg (r/w) */
+#define MCFSIM_CSMR4		0xb4		/* CS 4 Mask reg (r/w) */
+#define MCFSIM_CSCR4		0xba		/* CS 4 Control reg (r/w) */
+#define MCFSIM_CSAR5		0xbc		/* CS 5 Adress reg (r/w) */
+#define MCFSIM_CSMR5		0xc0		/* CS 5 Mask reg (r/w) */
+#define MCFSIM_CSCR5		0xc6		/* CS 5 Control reg (r/w) */
+#define MCFSIM_CSAR6		0xc8		/* CS 6 Adress reg (r/w) */
+#define MCFSIM_CSMR6		0xcc		/* CS 6 Mask reg (r/w) */
+#define MCFSIM_CSCR6		0xd2		/* CS 6 Control reg (r/w) */
+#define MCFSIM_CSAR7		0xd4		/* CS 7 Adress reg (r/w) */
+#define MCFSIM_CSMR7		0xd8		/* CS 7 Mask reg (r/w) */
+#define MCFSIM_CSCR7		0xde		/* CS 7 Control reg (r/w) */
+
+#define MCFSIM_DCR		0x100		/* DRAM Control reg (r/w) */
+#define MCFSIM_DACR0		0x108		/* DRAM 0 Addr and Ctrl (r/w) */
+#define MCFSIM_DMR0		0x10c		/* DRAM 0 Mask reg (r/w) */
+#define MCFSIM_DACR1		0x110		/* DRAM 1 Addr and Ctrl (r/w) */
+#define MCFSIM_DMR1		0x114		/* DRAM 1 Mask reg (r/w) */
+
+#define	MCFSIM_PADDR		0x244		/* Parallel Direction (r/w) */
+#define	MCFSIM_PADAT		0x248		/* Parallel Data (r/w) */
+
+
+/*
+ *	Some symbol defines for the above...
+ */
+#define	MCFSIM_SWDICR		MCFSIM_ICR0	/* Watchdog timer ICR */
+#define	MCFSIM_TIMER1ICR	MCFSIM_ICR1	/* Timer 1 ICR */
+#define	MCFSIM_TIMER2ICR	MCFSIM_ICR2	/* Timer 2 ICR */
+#define	MCFSIM_UART1ICR		MCFSIM_ICR4	/* UART 1 ICR */
+#define	MCFSIM_UART2ICR		MCFSIM_ICR5	/* UART 2 ICR */
+#define	MCFSIM_DMA0ICR		MCFSIM_ICR6	/* DMA 0 ICR */
+#define	MCFSIM_DMA1ICR		MCFSIM_ICR7	/* DMA 1 ICR */
+#define	MCFSIM_DMA2ICR		MCFSIM_ICR8	/* DMA 2 ICR */
+#define	MCFSIM_DMA3ICR		MCFSIM_ICR9	/* DMA 3 ICR */
+
+/*
+ *	Macro to set IMR register. It is 32 bits on the 5407.
+ */
+#define	mcf_getimr()		\
+	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR))
+
+#define	mcf_setimr(imr)		\
+	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr);
+
+#define	mcf_getipr()		\
+	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR))
+
+
+/*
+ *	Some symbol defines for the Parallel Port Pin Assignment Register
+ */
+#define MCFSIM_PAR_DREQ0        0x40            /* Set to select DREQ0 input */
+                                                /* Clear to select par I/O */
+#define MCFSIM_PAR_DREQ1        0x20            /* Select DREQ1 input */
+                                                /* Clear to select par I/O */
+
+/*
+ *       Defines for the IRQPAR Register
+ */
+#define IRQ5_LEVEL4	0x80
+#define IRQ3_LEVEL6	0x40
+#define IRQ1_LEVEL2	0x20
+
+
+/*
+ *	Define the Cache register flags.
+ */
+#define	CACR_DEC		0x80000000	/* Enable data cache */
+#define	CACR_DWP		0x40000000	/* Data write protection */
+#define	CACR_DESB		0x20000000	/* Enable data store buffer */
+#define	CACR_DDPI		0x10000000	/* Disable CPUSHL */
+#define	CACR_DHCLK		0x08000000	/* Half data cache lock mode */
+#define	CACR_DDCM_WT		0x00000000	/* Write through cache*/
+#define	CACR_DDCM_CP		0x02000000	/* Copyback cache */
+#define	CACR_DDCM_P		0x04000000	/* No cache, precise */
+#define	CACR_DDCM_IMP		0x06000000	/* No cache, imprecise */
+#define	CACR_DCINVA		0x01000000	/* Invalidate data cache */
+#define	CACR_BEC		0x00080000	/* Enable branch cache */
+#define	CACR_BCINVA		0x00040000	/* Invalidate branch cache */
+#define	CACR_IEC		0x00008000	/* Enable instruction cache */
+#define	CACR_DNFB		0x00002000	/* Inhibited fill buffer */
+#define	CACR_IDPI		0x00001000	/* Disable CPUSHL */
+#define	CACR_IHLCK		0x00000800	/* Intruction cache half lock */
+#define	CACR_IDCM		0x00000400	/* Intruction cache inhibit */
+#define	CACR_ICINVA		0x00000100	/* Invalidate instr cache */
+
+#define	ACR_BASE_POS		24		/* Address Base */
+#define	ACR_MASK_POS		16		/* Address Mask */
+#define	ACR_ENABLE		0x00008000	/* Enable address */
+#define	ACR_USER		0x00000000	/* User mode access only */
+#define	ACR_SUPER		0x00002000	/* Supervisor mode only */
+#define	ACR_ANY			0x00004000	/* Match any access mode */
+#define	ACR_CM_WT		0x00000000	/* Write through mode */
+#define	ACR_CM_CP		0x00000020	/* Copyback mode */
+#define	ACR_CM_OFF_PRE		0x00000040	/* No cache, precise */
+#define	ACR_CM_OFF_IMP		0x00000060	/* No cache, imprecise */
+#define	ACR_WPROTECT		0x00000004	/* Write protect */
+
+/****************************************************************************/
+#endif	/* m5407sim_h */
diff -Nru a/include/asm-m68knommu/m68360.h b/include/asm-m68knommu/m68360.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/m68360.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,5 @@
+#include "m68360_regs.h"
+#include "m68360_pram.h"
+#include "m68360_quicc.h"
+#include "m68360_enet.h"
+
diff -Nru a/include/asm-m68knommu/m68360_enet.h b/include/asm-m68knommu/m68360_enet.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/m68360_enet.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,177 @@
+/***********************************
+ * $Id: m68360_enet.h,v 1.1 2002/03/02 15:01:07 gerg Exp $
+ ***********************************
+ *
+ ***************************************
+ * Definitions for the ETHERNET controllers
+ ***************************************
+ */
+
+#ifndef __ETHER_H
+#define __ETHER_H
+
+#include "quicc_simple.h"
+
+/*
+ * transmit BD's
+ */
+#define T_R     0x8000          /* ready bit */
+#define E_T_PAD 0x4000          /* short frame padding */
+#define T_W     0x2000          /* wrap bit */
+#define T_I     0x1000          /* interrupt on completion */
+#define T_L     0x0800          /* last in frame */
+#define T_TC    0x0400          /* transmit CRC (when last) */
+
+#define T_DEF   0x0200          /* defer indication */
+#define T_HB    0x0100          /* heartbeat */
+#define T_LC    0x0080          /* error: late collision */
+#define T_RL    0x0040          /* error: retransmission limit */
+#define T_RC    0x003c          /* retry count */
+#define T_UN    0x0002          /* error: underrun */
+#define T_CSL   0x0001          /* carier sense lost */
+#define T_ERROR (T_HB | T_LC | T_RL | T_UN | T_CSL)
+
+/*
+ * receive BD's
+ */
+#define R_E     0x8000          /* buffer empty */
+#define R_W     0x2000          /* wrap bit */
+#define R_I     0x1000          /* interrupt on reception */
+#define R_L     0x0800          /* last BD in frame */
+#define R_F     0x0400          /* first BD in frame */
+#define R_M     0x0100          /* received because of promisc. mode */
+
+#define R_LG    0x0020          /* frame too long */
+#define R_NO    0x0010          /* non-octet aligned */
+#define R_SH    0x0008          /* short frame */
+#define R_CR    0x0004          /* receive CRC error */
+#define R_OV    0x0002          /* receive overrun */
+#define R_CL    0x0001          /* collision */
+#define ETHER_R_ERROR (R_LG | R_NO | R_SH | R_CR | R_OV | R_CL)
+
+
+/*
+ * ethernet interrupts
+ */
+#define ETHERNET_GRA    0x0080  /* graceful stop complete */
+#define ETHERNET_TXE    0x0010  /* transmit error         */
+#define ETHERNET_RXF    0x0008  /* receive frame          */
+#define ETHERNET_BSY    0x0004  /* busy condition         */
+#define ETHERNET_TXB    0x0002  /* transmit buffer        */
+#define ETHERNET_RXB    0x0001  /* receive buffer         */
+
+/*
+ * ethernet protocol specific mode register (PSMR)
+ */
+#define ETHER_HBC       0x8000    /* heartbeat checking      */
+#define ETHER_FC        0x4000    /* force collision         */
+#define ETHER_RSH       0x2000    /* receive short frames    */
+#define ETHER_IAM       0x1000    /* individual address mode */
+#define ETHER_CRC_32    (0x2<<10) /* Enable CRC              */
+#define ETHER_PRO       0x0200    /* promiscuous             */
+#define ETHER_BRO       0x0100    /* broadcast address       */
+#define ETHER_SBT       0x0080    /* stop backoff timer      */
+#define ETHER_LPB       0x0040    /* Loop Back Mode          */
+#define ETHER_SIP       0x0020    /* sample input pins       */
+#define ETHER_LCW       0x0010    /* late collision window   */
+#define ETHER_NIB_13    (0x0<<1)  /* # of ignored bits 13    */
+#define ETHER_NIB_14    (0x1<<1)  /* # of ignored bits 14    */
+#define ETHER_NIB_15    (0x2<<1)  /* # of ignored bits 15    */
+#define ETHER_NIB_16    (0x3<<1)  /* # of ignored bits 16    */
+#define ETHER_NIB_21    (0x4<<1)  /* # of ignored bits 21    */
+#define ETHER_NIB_22    (0x5<<1)  /* # of ignored bits 22    */
+#define ETHER_NIB_23    (0x6<<1)  /* # of ignored bits 23    */
+#define ETHER_NIB_24    (0x7<<1)  /* # of ignored bits 24    */
+
+/*
+ * ethernet specific parameters
+ */
+#define CRC_WORD 4          /* Length in bytes of CRC */               
+#define C_PRES   0xffffffff /* preform 32 bit CRC */
+#define C_MASK   0xdebb20e3 /* comply with 32 bit CRC */       
+#define CRCEC    0x00000000
+#define ALEC     0x00000000
+#define DISFC    0x00000000
+#define PADS     0x00000000
+#define RET_LIM  0x000f     /* retry 15 times to send a frame before interupt */
+#define ETH_MFLR 0x05ee     /* 1518 max frame size */
+#define MINFLR   0x0040     /* Minimum frame size 64 */
+#define MAXD1    0x05ee     /* Max dma count 1518 */
+#define MAXD2    0x05ee
+#define GADDR1   0x00000000 /* Clear group address */  
+#define GADDR2   0x00000000
+#define GADDR3   0x00000000    
+#define GADDR4   0x00000000    
+#define P_PER    0x00000000 /*not used */              
+#define IADDR1   0x00000000 /* Individual hash table not used */       
+#define IADDR2   0x00000000
+#define IADDR3   0x00000000    
+#define IADDR4   0x00000000            
+#define TADDR_H  0x00000000 /* clear this regs */              
+#define TADDR_M  0x00000000            
+#define TADDR_L  0x00000000            
+
+/*       SCC Parameter Ram */
+#define RFCR    0x18 /* normal operation */
+#define TFCR    0x18 /* normal operation */
+#define E_MRBLR 1518 /* Max ethernet frame length */
+
+/*
+ * ethernet specific structure
+ */
+typedef union {
+        unsigned char b[6];
+        struct {
+            unsigned short high;
+            unsigned short middl;
+            unsigned short low;
+        } w;
+} ETHER_ADDR;
+
+typedef struct {
+    int        max_frame_length;
+    int        promisc_mode;
+    int        reject_broadcast;
+    ETHER_ADDR phys_adr;
+} ETHER_SPECIFIC;
+
+typedef struct {
+    ETHER_ADDR     dst_addr;
+    ETHER_ADDR     src_addr;
+    unsigned short type_or_len;
+    unsigned char  data[1];
+} ETHER_FRAME;
+
+#define MAX_DATALEN 1500
+typedef struct {
+    ETHER_ADDR     dst_addr;
+    ETHER_ADDR     src_addr;
+    unsigned short type_or_len;
+    unsigned char  data[MAX_DATALEN];
+    unsigned char  fcs[CRC_WORD];
+} ETHER_MAX_FRAME;
+
+
+/*
+ * Internal ethernet function prototypes
+ */
+void        ether_interrupt(int scc_num);
+/* mleslie: debug */
+/* static void ethernet_rx_internal(int scc_num); */
+/* static void ethernet_tx_internal(int scc_num); */
+
+/*
+ * User callable routines prototypes (ethernet specific)
+ */
+void ethernet_init(int                       scc_number,
+                   alloc_routine             *alloc_buffer,
+                   free_routine              *free_buffer,
+                   store_rx_buffer_routine   *store_rx_buffer,
+                   handle_tx_error_routine   *handle_tx_error,
+                   handle_rx_error_routine   *handle_rx_error,
+                   handle_lost_error_routine *handle_lost_error,
+                   ETHER_SPECIFIC            *ether_spec);
+int  ethernet_tx(int scc_number, void *buf, int length);
+
+#endif
+
diff -Nru a/include/asm-m68knommu/m68360_pram.h b/include/asm-m68knommu/m68360_pram.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/m68360_pram.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,431 @@
+/***********************************
+ * $Id: m68360_pram.h,v 1.1 2002/03/02 15:01:07 gerg Exp $
+ ***********************************
+ *
+ ***************************************
+ * Definitions of the parameter area RAM.
+ * Note that different structures are overlaid
+ * at the same offsets for the different modes
+ * of operation.
+ ***************************************
+ */
+
+#ifndef __PRAM_H
+#define __PRAM_H
+
+/* Time slot assignment table */
+#define VALID_SLOT	0x8000
+#define WRAP_SLOT	0x4000
+
+/*****************************************************************
+        Global Multichannel parameter RAM
+*****************************************************************/
+struct global_multi_pram {
+    /*
+     * Global Multichannel parameter RAM
+     */
+    unsigned long   mcbase;		/* Multichannel Base pointer */
+    unsigned short  qmcstate;		/* Multichannel Controller state */
+    unsigned short  mrblr;		/* Maximum Receive Buffer Length */
+    unsigned short  tx_s_ptr;		/* TSTATx Pointer */
+    unsigned short  rxptr;		/* Current Time slot entry in TSATRx */
+    unsigned short  grfthr;		/* Global Receive frame threshold */
+    unsigned short  grfcnt;		/* Global Receive Frame Count */
+    unsigned long   intbase;		/* Multichannel Base address */
+    unsigned long   iintptr;		/* Pointer to interrupt queue */
+    unsigned short  rx_s_ptr;		/* TSTARx Pointer */
+
+    unsigned short  txptr;		/* Current Time slot entry in TSATTx */
+    unsigned long   c_mask32;		/* CRC Constant (debb20e3) */
+    unsigned short  tsatrx[32];		/* Time Slot Assignment Table Rx */
+    unsigned short  tsattx[32];		/* Time Slot Assignment Table Tx */
+    unsigned short  c_mask16;		/* CRC Constant (f0b8) */
+};
+
+/*****************************************************************
+        Quicc32 HDLC parameter RAM
+*****************************************************************/
+struct quicc32_pram {
+
+    unsigned short  tbase;		/* Tx Buffer Descriptors Base Address */
+    unsigned short  chamr;		/* Channel Mode Register */
+    unsigned long   tstate;		/* Tx Internal State */
+    unsigned long   txintr;		/* Tx Internal Data Pointer */
+    unsigned short  tbptr;		/* Tx Buffer Descriptor Pointer */
+    unsigned short  txcntr;		/* Tx Internal Byte Count */
+    unsigned long   tupack;		/* (Tx Temp) */
+    unsigned long   zistate;		/* Zero Insertion machine state */
+    unsigned long   tcrc;		/* Temp Transmit CRC */
+    unsigned short  intmask;		/* Channel's interrupt mask flags */
+    unsigned short  bdflags;		
+    unsigned short  rbase;		/* Rx Buffer Descriptors Base Address */
+    unsigned short  mflr;		/* Max Frame Length Register */
+    unsigned long   rstate;		/* Rx Internal State */
+    unsigned long   rxintr;		/* Rx Internal Data Pointer */
+    unsigned short  rbptr;		/* Rx Buffer Descriptor Pointer */
+    unsigned short  rxbyc;		/* Rx Internal Byte Count */
+    unsigned long   rpack;		/* (Rx Temp) */
+    unsigned long   zdstate;		/* Zero Deletion machine state */
+    unsigned long   rcrc;		/* Temp Transmit CRC */
+    unsigned short  maxc;		/* Max_length counter */
+    unsigned short  tmp_mb;		/* Temp */
+};
+
+
+/*****************************************************************
+        HDLC parameter RAM
+*****************************************************************/
+
+struct hdlc_pram {
+    /*
+     * SCC parameter RAM
+     */
+    unsigned short  rbase;          /* RX BD base address */
+    unsigned short  tbase;          /* TX BD base address */
+    unsigned char   rfcr;           /* Rx function code */
+    unsigned char   tfcr;           /* Tx function code */
+    unsigned short  mrblr;          /* Rx buffer length */
+    unsigned long   rstate;         /* Rx internal state */
+    unsigned long   rptr;           /* Rx internal data pointer */
+    unsigned short  rbptr;          /* rb BD Pointer */
+    unsigned short  rcount;         /* Rx internal byte count */
+    unsigned long   rtemp;          /* Rx temp */
+    unsigned long   tstate;         /* Tx internal state */
+    unsigned long   tptr;           /* Tx internal data pointer */
+    unsigned short  tbptr;          /* Tx BD pointer */
+    unsigned short  tcount;         /* Tx byte count */
+    unsigned long   ttemp;          /* Tx temp */
+    unsigned long   rcrc;           /* temp receive CRC */
+    unsigned long   tcrc;           /* temp transmit CRC */
+   
+    /*
+     * HDLC specific parameter RAM
+     */
+    unsigned char   RESERVED1[4];   /* Reserved area */
+    unsigned long   c_mask;         /* CRC constant */
+    unsigned long   c_pres;         /* CRC preset */
+    unsigned short  disfc;          /* discarded frame counter */
+    unsigned short  crcec;          /* CRC error counter */
+    unsigned short  abtsc;          /* abort sequence counter */
+    unsigned short  nmarc;          /* nonmatching address rx cnt */
+    unsigned short  retrc;          /* frame retransmission cnt */
+    unsigned short  mflr;           /* maximum frame length reg */
+    unsigned short  max_cnt;        /* maximum length counter */
+    unsigned short  rfthr;          /* received frames threshold */
+    unsigned short  rfcnt;          /* received frames count */
+    unsigned short  hmask;          /* user defined frm addr mask */
+    unsigned short  haddr1;         /* user defined frm address 1 */
+    unsigned short  haddr2;         /* user defined frm address 2 */
+    unsigned short  haddr3;         /* user defined frm address 3 */
+    unsigned short  haddr4;         /* user defined frm address 4 */
+    unsigned short  tmp;            /* temp */
+    unsigned short  tmp_mb;         /* temp */
+};
+
+
+
+/*****************************************************************
+        UART parameter RAM
+*****************************************************************/
+
+/*
+ * bits in uart control characters table
+ */
+#define CC_INVALID  0x8000          /* control character is valid */
+#define CC_REJ      0x4000          /* don't store char in buffer */
+#define CC_CHAR     0x00ff          /* control character */
+
+/* UART */
+struct uart_pram {
+    /*
+     * SCC parameter RAM
+     */
+    unsigned short  rbase;          /* RX BD base address */
+    unsigned short  tbase;          /* TX BD base address */
+    unsigned char   rfcr;           /* Rx function code */
+    unsigned char   tfcr;           /* Tx function code */
+    unsigned short  mrblr;          /* Rx buffer length */
+    unsigned long   rstate;         /* Rx internal state */
+    unsigned long   rptr;           /* Rx internal data pointer */
+    unsigned short  rbptr;          /* rb BD Pointer */
+    unsigned short  rcount;         /* Rx internal byte count */
+    unsigned long   rx_temp;        /* Rx temp */
+    unsigned long   tstate;         /* Tx internal state */
+    unsigned long   tptr;           /* Tx internal data pointer */
+    unsigned short  tbptr;          /* Tx BD pointer */
+    unsigned short  tcount;         /* Tx byte count */
+    unsigned long   ttemp;          /* Tx temp */
+    unsigned long   rcrc;           /* temp receive CRC */
+    unsigned long   tcrc;           /* temp transmit CRC */
+   
+    /*
+     * UART specific parameter RAM
+     */
+    unsigned char   RESERVED1[8];   /* Reserved area */
+    unsigned short  max_idl;        /* maximum idle characters */
+    unsigned short  idlc;           /* rx idle counter (internal) */
+    unsigned short  brkcr;          /* break count register */
+                   
+    unsigned short  parec;          /* Rx parity error counter */
+    unsigned short  frmer;          /* Rx framing error counter */
+    unsigned short  nosec;          /* Rx noise counter */
+    unsigned short  brkec;          /* Rx break character counter */
+    unsigned short  brkln;          /* Reaceive break length */
+                   
+    unsigned short  uaddr1;         /* address character 1 */
+    unsigned short  uaddr2;         /* address character 2 */
+    unsigned short  rtemp;          /* temp storage */
+    unsigned short  toseq;          /* Tx out of sequence char */
+    unsigned short  cc[8];          /* Rx control characters */
+    unsigned short  rccm;           /* Rx control char mask */
+    unsigned short  rccr;           /* Rx control char register */
+    unsigned short  rlbc;           /* Receive last break char */
+};
+
+
+
+/*****************************************************************
+        BISYNC parameter RAM
+*****************************************************************/
+
+struct bisync_pram {
+    /*
+     * SCC parameter RAM
+     */
+    unsigned short  rbase;          /* RX BD base address */
+    unsigned short  tbase;          /* TX BD base address */
+    unsigned char   rfcr;           /* Rx function code */
+    unsigned char   tfcr;           /* Tx function code */
+    unsigned short  mrblr;          /* Rx buffer length */
+    unsigned long   rstate;         /* Rx internal state */
+    unsigned long   rptr;           /* Rx internal data pointer */
+    unsigned short  rbptr;          /* rb BD Pointer */
+    unsigned short  rcount;         /* Rx internal byte count */
+    unsigned long   rtemp;          /* Rx temp */
+    unsigned long   tstate;         /* Tx internal state */
+    unsigned long   tptr;           /* Tx internal data pointer */
+    unsigned short  tbptr;          /* Tx BD pointer */
+    unsigned short  tcount;         /* Tx byte count */
+    unsigned long   ttemp;          /* Tx temp */
+    unsigned long   rcrc;           /* temp receive CRC */
+    unsigned long   tcrc;           /* temp transmit CRC */
+   
+    /*
+     * BISYNC specific parameter RAM
+     */
+    unsigned char   RESERVED1[4];   /* Reserved area */
+    unsigned long   crcc;           /* CRC Constant Temp Value */
+    unsigned short  prcrc;          /* Preset Receiver CRC-16/LRC */
+    unsigned short  ptcrc;          /* Preset Transmitter CRC-16/LRC */
+    unsigned short  parec;          /* Receive Parity Error Counter */
+    unsigned short  bsync;          /* BISYNC SYNC Character */
+    unsigned short  bdle;           /* BISYNC DLE Character */
+    unsigned short  cc[8];          /* Rx control characters */
+    unsigned short  rccm;           /* Receive Control Character Mask */
+};
+
+/*****************************************************************
+        IOM2 parameter RAM
+        (overlaid on tx bd[5] of SCC channel[2])
+*****************************************************************/
+struct iom2_pram {
+    unsigned short  ci_data;        /* ci data */
+    unsigned short  monitor_data;   /* monitor data */
+    unsigned short  tstate;         /* transmitter state */
+    unsigned short  rstate;         /* receiver state */
+};
+
+/*****************************************************************
+        SPI/SMC parameter RAM
+        (overlaid on tx bd[6,7] of SCC channel[2])
+*****************************************************************/
+
+#define SPI_R       0x8000          /* Ready bit in BD */
+
+struct spi_pram {
+    unsigned short  rbase;          /* Rx BD Base Address */
+    unsigned short  tbase;          /* Tx BD Base Address */
+    unsigned char   rfcr;           /* Rx function code */
+    unsigned char   tfcr;           /* Tx function code */
+    unsigned short  mrblr;          /* Rx buffer length */
+    unsigned long   rstate;         /* Rx internal state */
+    unsigned long   rptr;           /* Rx internal data pointer */
+    unsigned short  rbptr;          /* rb BD Pointer */
+    unsigned short  rcount;         /* Rx internal byte count */
+    unsigned long   rtemp;          /* Rx temp */
+    unsigned long   tstate;         /* Tx internal state */
+    unsigned long   tptr;           /* Tx internal data pointer */
+    unsigned short  tbptr;          /* Tx BD pointer */
+    unsigned short  tcount;         /* Tx byte count */
+    unsigned long   ttemp;          /* Tx temp */
+};
+
+struct smc_uart_pram {
+    unsigned short  rbase;          /* Rx BD Base Address */
+    unsigned short  tbase;          /* Tx BD Base Address */
+    unsigned char   rfcr;           /* Rx function code */
+    unsigned char   tfcr;           /* Tx function code */
+    unsigned short  mrblr;          /* Rx buffer length */
+    unsigned long   rstate;         /* Rx internal state */
+    unsigned long   rptr;           /* Rx internal data pointer */
+    unsigned short  rbptr;          /* rb BD Pointer */
+    unsigned short  rcount;         /* Rx internal byte count */
+    unsigned long   rtemp;          /* Rx temp */
+    unsigned long   tstate;         /* Tx internal state */
+    unsigned long   tptr;           /* Tx internal data pointer */
+    unsigned short  tbptr;          /* Tx BD pointer */
+    unsigned short  tcount;         /* Tx byte count */
+    unsigned long   ttemp;          /* Tx temp */
+    unsigned short  max_idl;        /* Maximum IDLE Characters */
+    unsigned short  idlc;           /* Temporary IDLE Counter */
+    unsigned short  brkln;          /* Last Rx Break Length */
+    unsigned short  brkec;          /* Rx Break Condition Counter */
+    unsigned short  brkcr;          /* Break Count Register (Tx) */
+    unsigned short  r_mask;         /* Temporary bit mask */
+};
+
+struct smc_trnsp_pram {
+    unsigned short  rbase;          /* rx BD Base Address */
+    unsigned short  tbase;          /* Tx BD Base Address */
+    unsigned char   rfcr;           /* Rx function code */
+    unsigned char   tfcr;           /* Tx function code */
+    unsigned short  mrblr;          /* Rx buffer length */
+    unsigned long   rstate;         /* Rx internal state */
+    unsigned long   rptr;           /* Rx internal data pointer */
+    unsigned short  rbptr;          /* rb BD Pointer */
+    unsigned short  rcount;         /* Rx internal byte count */
+    unsigned long   rtemp;          /* Rx temp */
+    unsigned long   tstate;         /* Tx internal state */
+    unsigned long   tptr;           /* Tx internal data pointer */
+    unsigned short  tbptr;          /* Tx BD pointer */
+    unsigned short  tcount;         /* Tx byte count */
+    unsigned long   ttemp;          /* Tx temp */
+    unsigned short  reserved[5];    /* Reserved */
+};
+
+struct idma_pram {
+    unsigned short  ibase;          /* IDMA BD Base Address */
+    unsigned short  ibptr;          /* IDMA buffer descriptor pointer */
+    unsigned long   istate;         /* IDMA internal state */
+    unsigned long   itemp;          /* IDMA temp */
+};
+
+struct ethernet_pram {
+    /*
+     * SCC parameter RAM
+     */
+    unsigned short  rbase;          /* RX BD base address */
+    unsigned short  tbase;          /* TX BD base address */
+    unsigned char   rfcr;           /* Rx function code */
+    unsigned char   tfcr;           /* Tx function code */
+    unsigned short  mrblr;          /* Rx buffer length */
+    unsigned long   rstate;         /* Rx internal state */
+    unsigned long   rptr;           /* Rx internal data pointer */
+    unsigned short  rbptr;          /* rb BD Pointer */
+    unsigned short  rcount;         /* Rx internal byte count */
+    unsigned long   rtemp;          /* Rx temp */
+    unsigned long   tstate;         /* Tx internal state */
+    unsigned long   tptr;           /* Tx internal data pointer */
+    unsigned short  tbptr;          /* Tx BD pointer */
+    unsigned short  tcount;         /* Tx byte count */
+    unsigned long   ttemp;          /* Tx temp */
+    unsigned long   rcrc;           /* temp receive CRC */
+    unsigned long   tcrc;           /* temp transmit CRC */
+   
+    /*
+     * ETHERNET specific parameter RAM
+     */
+    unsigned long   c_pres;         /* preset CRC */
+    unsigned long   c_mask;         /* constant mask for CRC */
+    unsigned long   crcec;          /* CRC error counter */
+    unsigned long   alec;           /* alighnment error counter */
+    unsigned long   disfc;          /* discard frame counter */
+    unsigned short  pads;           /* short frame PAD characters */
+    unsigned short  ret_lim;        /* retry limit threshold */
+    unsigned short  ret_cnt;        /* retry limit counter */
+    unsigned short  mflr;           /* maximum frame length reg */
+    unsigned short  minflr;         /* minimum frame length reg */
+    unsigned short  maxd1;          /* maximum DMA1 length reg */
+    unsigned short  maxd2;          /* maximum DMA2 length reg */
+    unsigned short  maxd;           /* rx max DMA */
+    unsigned short  dma_cnt;        /* rx dma counter */
+    unsigned short  max_b;          /* max bd byte count */
+    unsigned short  gaddr1;         /* group address filter 1 */
+    unsigned short  gaddr2;         /* group address filter 2 */
+    unsigned short  gaddr3;         /* group address filter 3 */
+    unsigned short  gaddr4;         /* group address filter 4 */
+    unsigned long   tbuf0_data0;    /* save area 0 - current frm */
+    unsigned long   tbuf0_data1;    /* save area 1 - current frm */
+    unsigned long   tbuf0_rba0;
+    unsigned long   tbuf0_crc;
+    unsigned short  tbuf0_bcnt;
+    union {
+        unsigned char b[6];
+        struct {
+            unsigned short high;
+            unsigned short middl;
+            unsigned short low;
+        } w;
+    } paddr;
+    unsigned short  p_per;          /* persistence */
+    unsigned short  rfbd_ptr;       /* rx first bd pointer */
+    unsigned short  tfbd_ptr;       /* tx first bd pointer */
+    unsigned short  tlbd_ptr;       /* tx last bd pointer */
+    unsigned long   tbuf1_data0;    /* save area 0 - next frame */
+    unsigned long   tbuf1_data1;    /* save area 1 - next frame */
+    unsigned long   tbuf1_rba0;
+    unsigned long   tbuf1_crc;
+    unsigned short  tbuf1_bcnt;
+    unsigned short  tx_len;         /* tx frame length counter */
+    unsigned short  iaddr1;         /* individual address filter 1*/
+    unsigned short  iaddr2;         /* individual address filter 2*/
+    unsigned short  iaddr3;         /* individual address filter 3*/
+    unsigned short  iaddr4;         /* individual address filter 4*/
+    unsigned short  boff_cnt;       /* back-off counter */
+    unsigned short  taddr_h;        /* temp address (MSB) */
+    unsigned short  taddr_m;        /* temp address */
+    unsigned short  taddr_l;        /* temp address (LSB) */
+};
+
+struct transparent_pram {
+    /*
+     * SCC parameter RAM
+     */
+    unsigned short  rbase;          /* RX BD base address */
+    unsigned short  tbase;          /* TX BD base address */
+    unsigned char   rfcr;           /* Rx function code */
+    unsigned char   tfcr;           /* Tx function code */
+    unsigned short  mrblr;          /* Rx buffer length */
+    unsigned long   rstate;         /* Rx internal state */
+    unsigned long   rptr;           /* Rx internal data pointer */
+    unsigned short  rbptr;          /* rb BD Pointer */
+    unsigned short  rcount;         /* Rx internal byte count */
+    unsigned long   rtemp;          /* Rx temp */
+    unsigned long   tstate;         /* Tx internal state */
+    unsigned long   tptr;           /* Tx internal data pointer */
+    unsigned short  tbptr;          /* Tx BD pointer */
+    unsigned short  tcount;         /* Tx byte count */
+    unsigned long   ttemp;          /* Tx temp */
+    unsigned long   rcrc;           /* temp receive CRC */
+    unsigned long   tcrc;           /* temp transmit CRC */
+   
+    /*
+     * TRANSPARENT specific parameter RAM
+     */
+    unsigned long   crc_p;          /* CRC Preset */
+    unsigned long   crc_c;          /* CRC constant */
+};
+
+struct timer_pram {
+    /*
+     * RISC timers parameter RAM
+     */
+    unsigned short  tm_base;        /* RISC timer table base adr */
+    unsigned short  tm_ptr;         /* RISC timer table pointer */
+    unsigned short  r_tmr;          /* RISC timer mode register */
+    unsigned short  r_tmv;          /* RISC timer valid register */
+    unsigned long   tm_cmd;         /* RISC timer cmd register */
+    unsigned long   tm_cnt;         /* RISC timer internal cnt */
+};
+
+#endif
diff -Nru a/include/asm-m68knommu/m68360_quicc.h b/include/asm-m68knommu/m68360_quicc.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/m68360_quicc.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,362 @@
+/***********************************
+ * $Id: m68360_quicc.h,v 1.1 2002/03/02 15:01:07 gerg Exp $
+ ***********************************
+ *
+ ***************************************
+ * Definitions of QUICC memory structures
+ ***************************************
+ */
+
+#ifndef __M68360_QUICC_H
+#define __M68360_QUICC_H
+
+/*
+ * include registers and
+ * parameter ram definitions files
+ */
+#include <asm/m68360_regs.h>
+#include <asm/m68360_pram.h>
+
+
+
+/* Buffer Descriptors */
+typedef struct quicc_bd {
+    volatile unsigned short     status;
+    volatile unsigned short     length;
+    volatile unsigned char      *buf;     /* WARNING: This is only true if *char is 32 bits */
+} QUICC_BD;
+
+
+#ifdef MOTOROLA_ORIGINAL
+struct user_data {
+    /* BASE + 0x000: user data memory */
+    volatile unsigned char      udata_bd_ucode[0x400]; /*user data bd's Ucode*/
+    volatile unsigned char      udata_bd[0x200];       /*user data Ucode     */
+    volatile unsigned char      ucode_ext[0x100];      /*Ucode Extention ram */
+    volatile unsigned char      RESERVED1[0x500];      /* Reserved area      */
+};
+#else
+struct user_data {
+    /* BASE + 0x000: user data memory */
+    volatile unsigned char      udata_bd_ucode[0x400]; /* user data, bds, Ucode*/
+    volatile unsigned char      udata_bd1[0x200];       /* user, bds */
+    volatile unsigned char      ucode_bd_scratch[0x100]; /* user, bds, ucode scratch */
+    volatile unsigned char      udata_bd2[0x100];       /* user, bds */
+    volatile unsigned char      RESERVED1[0x400];      /* Reserved area      */
+};
+#endif
+
+
+/*
+ * internal ram
+ */
+typedef struct quicc {
+	union {
+		struct quicc32_pram ch_pram_tbl[32];	/* 32*64(bytes) per channel */	
+		struct user_data		u;
+	}ch_or_u;	/* multipul or user space */
+
+    /* BASE + 0xc00: PARAMETER RAM */
+	union {
+		struct scc_pram {
+			union {
+				struct hdlc_pram        h;
+				struct uart_pram        u;
+				struct bisync_pram      b;
+				struct transparent_pram t;
+				unsigned char   RESERVED66[0x70];
+			} pscc;               /* scc parameter area (protocol dependent) */
+			union {
+				struct {
+					unsigned char       RESERVED70[0x10];
+					struct spi_pram     spi;
+					unsigned char       RESERVED72[0x8];
+					struct timer_pram   timer;
+				} timer_spi;
+				struct {
+					struct idma_pram idma;
+					unsigned char       RESERVED67[0x4];
+					union {
+						struct smc_uart_pram u;
+						struct smc_trnsp_pram t;
+					} psmc;
+				} idma_smc;
+			} pothers;
+		} scc;
+		struct ethernet_pram    enet_scc;
+		struct global_multi_pram        m;
+		unsigned char   pr[0x100];
+	} pram[4];
+
+    /* reserved */
+
+    /* BASE + 0x1000: INTERNAL REGISTERS */
+    /* SIM */
+    volatile unsigned long      sim_mcr;        /* module configuration reg */
+    volatile unsigned short     sim_simtr;      /* module test register     */
+    volatile unsigned char      RESERVED2[0x2]; /* Reserved area            */
+    volatile unsigned char      sim_avr;        /* auto vector reg          */
+    volatile unsigned char      sim_rsr;        /* reset status reg         */
+    volatile unsigned char      RESERVED3[0x2]; /* Reserved area            */
+    volatile unsigned char      sim_clkocr;     /* CLCO control register    */
+    volatile unsigned char      RESERVED62[0x3];        /* Reserved area    */
+    volatile unsigned short     sim_pllcr;      /* PLL control register     */
+    volatile unsigned char      RESERVED63[0x2];        /* Reserved area    */
+    volatile unsigned short     sim_cdvcr;      /* Clock devider control register */
+    volatile unsigned short     sim_pepar;      /* Port E pin assignment register */
+    volatile unsigned char      RESERVED64[0xa];        /* Reserved area    */
+    volatile unsigned char      sim_sypcr;      /* system protection control*/
+    volatile unsigned char      sim_swiv;       /* software interrupt vector*/
+    volatile unsigned char      RESERVED6[0x2]; /* Reserved area            */
+    volatile unsigned short     sim_picr;       /* periodic interrupt control reg */
+    volatile unsigned char      RESERVED7[0x2]; /* Reserved area            */
+    volatile unsigned short     sim_pitr;       /* periodic interrupt timing reg */
+    volatile unsigned char      RESERVED8[0x3]; /* Reserved area            */
+    volatile unsigned char      sim_swsr;       /* software service         */
+    volatile unsigned long      sim_bkar;       /* breakpoint address register*/
+    volatile unsigned long      sim_bkcr;       /* breakpoint control register*/
+    volatile unsigned char      RESERVED10[0x8];        /* Reserved area    */
+    /* MEMC */
+    volatile unsigned long      memc_gmr;       /* Global memory register   */
+    volatile unsigned short     memc_mstat;     /* MEMC status register     */
+    volatile unsigned char      RESERVED11[0xa];        /* Reserved area    */
+    volatile unsigned long      memc_br0;       /* base register 0          */
+    volatile unsigned long      memc_or0;       /* option register 0        */
+    volatile unsigned char      RESERVED12[0x8];        /* Reserved area    */
+    volatile unsigned long      memc_br1;       /* base register 1          */
+    volatile unsigned long      memc_or1;       /* option register 1        */
+    volatile unsigned char      RESERVED13[0x8];        /* Reserved area    */
+    volatile unsigned long      memc_br2;       /* base register 2          */
+    volatile unsigned long      memc_or2;       /* option register 2        */
+    volatile unsigned char      RESERVED14[0x8];        /* Reserved area    */
+    volatile unsigned long      memc_br3;       /* base register 3          */
+    volatile unsigned long      memc_or3;       /* option register 3        */
+    volatile unsigned char      RESERVED15[0x8];        /* Reserved area    */
+    volatile unsigned long      memc_br4;       /* base register 3          */
+    volatile unsigned long      memc_or4;       /* option register 3        */
+    volatile unsigned char      RESERVED16[0x8];        /* Reserved area    */
+    volatile unsigned long      memc_br5;       /* base register 3          */
+    volatile unsigned long      memc_or5;       /* option register 3        */
+    volatile unsigned char      RESERVED17[0x8];        /* Reserved area    */
+    volatile unsigned long      memc_br6;       /* base register 3          */
+    volatile unsigned long      memc_or6;       /* option register 3        */
+    volatile unsigned char      RESERVED18[0x8];        /* Reserved area    */
+    volatile unsigned long      memc_br7;       /* base register 3          */
+    volatile unsigned long      memc_or7;       /* option register 3        */
+    volatile unsigned char      RESERVED9[0x28];        /* Reserved area    */
+    /* TEST */
+    volatile unsigned short     test_tstmra;    /* master shift a           */
+    volatile unsigned short     test_tstmrb;    /* master shift b           */
+    volatile unsigned short     test_tstsc;     /* shift count              */
+    volatile unsigned short     test_tstrc;     /* repetition counter       */
+    volatile unsigned short     test_creg;      /* control                  */
+    volatile unsigned short     test_dreg;      /* destributed register     */
+    volatile unsigned char      RESERVED58[0x404];      /* Reserved area    */
+    /* IDMA1 */
+    volatile unsigned short     idma_iccr;      /* channel configuration reg*/
+    volatile unsigned char      RESERVED19[0x2];        /* Reserved area    */
+    volatile unsigned short     idma1_cmr;      /* dma mode reg             */
+    volatile unsigned char      RESERVED68[0x2];        /* Reserved area    */
+    volatile unsigned long      idma1_sapr;     /* dma source addr ptr      */
+    volatile unsigned long      idma1_dapr;     /* dma destination addr ptr */
+    volatile unsigned long      idma1_bcr;      /* dma byte count reg       */
+    volatile unsigned char      idma1_fcr;      /* function code reg        */
+    volatile unsigned char      RESERVED20;     /* Reserved area            */
+    volatile unsigned char      idma1_cmar;     /* channel mask reg         */
+    volatile unsigned char      RESERVED21;     /* Reserved area            */
+    volatile unsigned char      idma1_csr;      /* channel status reg       */
+    volatile unsigned char      RESERVED22[0x3];        /* Reserved area    */
+    /* SDMA */
+    volatile unsigned char      sdma_sdsr;      /* status reg               */
+    volatile unsigned char      RESERVED23;     /* Reserved area            */
+    volatile unsigned short     sdma_sdcr;      /* configuration reg        */
+    volatile unsigned long      sdma_sdar;      /* address reg              */
+    /* IDMA2 */
+    volatile unsigned char      RESERVED69[0x2];        /* Reserved area    */
+    volatile unsigned short     idma2_cmr;      /* dma mode reg             */
+    volatile unsigned long      idma2_sapr;     /* dma source addr ptr      */
+    volatile unsigned long      idma2_dapr;     /* dma destination addr ptr */
+    volatile unsigned long      idma2_bcr;      /* dma byte count reg       */
+    volatile unsigned char      idma2_fcr;      /* function code reg        */
+    volatile unsigned char      RESERVED24;     /* Reserved area            */
+    volatile unsigned char      idma2_cmar;     /* channel mask reg         */
+    volatile unsigned char      RESERVED25;     /* Reserved area            */
+    volatile unsigned char      idma2_csr;      /* channel status reg       */
+    volatile unsigned char      RESERVED26[0x7];        /* Reserved area    */
+    /* Interrupt Controller */
+    volatile unsigned long      intr_cicr;      /* CP interrupt configuration reg*/
+    volatile unsigned long      intr_cipr;      /* CP interrupt pending reg */
+    volatile unsigned long      intr_cimr;      /* CP interrupt mask reg    */
+    volatile unsigned long      intr_cisr;      /* CP interrupt in service reg*/
+    /* Parallel I/O */
+    volatile unsigned short     pio_padir;      /* port A data direction reg */
+    volatile unsigned short     pio_papar;      /* port A pin assignment reg */
+    volatile unsigned short     pio_paodr;      /* port A open drain reg    */
+    volatile unsigned short     pio_padat;      /* port A data register     */
+    volatile unsigned char      RESERVED28[0x8];        /* Reserved area    */
+    volatile unsigned short     pio_pcdir;      /* port C data direction reg*/
+    volatile unsigned short     pio_pcpar;      /* port C pin assignment reg*/
+    volatile unsigned short     pio_pcso;       /* port C special options   */
+    volatile unsigned short     pio_pcdat;      /* port C data register     */
+    volatile unsigned short     pio_pcint;      /* port C interrupt cntrl reg */
+    volatile unsigned char      RESERVED29[0x16];       /* Reserved area    */
+    /* Timer */
+    volatile unsigned short     timer_tgcr;     /* timer global configuration reg */
+    volatile unsigned char      RESERVED30[0xe];        /* Reserved area    */
+    volatile unsigned short     timer_tmr1;     /* timer 1 mode reg         */
+    volatile unsigned short     timer_tmr2;     /* timer 2 mode reg         */
+    volatile unsigned short     timer_trr1;     /* timer 1 referance reg    */
+    volatile unsigned short     timer_trr2;     /* timer 2 referance reg    */
+    volatile unsigned short     timer_tcr1;     /* timer 1 capture reg      */
+    volatile unsigned short     timer_tcr2;     /* timer 2 capture reg      */
+    volatile unsigned short     timer_tcn1;     /* timer 1 counter reg      */
+    volatile unsigned short     timer_tcn2;     /* timer 2 counter reg      */
+    volatile unsigned short     timer_tmr3;     /* timer 3 mode reg         */
+    volatile unsigned short     timer_tmr4;     /* timer 4 mode reg         */
+    volatile unsigned short     timer_trr3;     /* timer 3 referance reg    */
+    volatile unsigned short     timer_trr4;     /* timer 4 referance reg    */
+    volatile unsigned short     timer_tcr3;     /* timer 3 capture reg      */
+    volatile unsigned short     timer_tcr4;     /* timer 4 capture reg      */
+    volatile unsigned short     timer_tcn3;     /* timer 3 counter reg      */
+    volatile unsigned short     timer_tcn4;     /* timer 4 counter reg      */
+    volatile unsigned short     timer_ter1;     /* timer 1 event reg        */
+    volatile unsigned short     timer_ter2;     /* timer 2 event reg        */
+    volatile unsigned short     timer_ter3;     /* timer 3 event reg        */
+    volatile unsigned short     timer_ter4;     /* timer 4 event reg        */
+    volatile unsigned char      RESERVED34[0x8];        /* Reserved area    */
+    /* CP */
+    volatile unsigned short     cp_cr;          /* command register         */
+    volatile unsigned char      RESERVED35[0x2];        /* Reserved area    */
+    volatile unsigned short     cp_rccr;        /* main configuration reg   */
+    volatile unsigned char      RESERVED37;     /* Reserved area            */
+    volatile unsigned char      cp_rmds;        /* development support status reg */
+    volatile unsigned long      cp_rmdr;        /* development support control reg */
+    volatile unsigned short     cp_rctr1;       /* ram break register 1     */
+    volatile unsigned short     cp_rctr2;       /* ram break register 2     */
+    volatile unsigned short     cp_rctr3;       /* ram break register 3     */
+    volatile unsigned short     cp_rctr4;       /* ram break register 4     */
+    volatile unsigned char      RESERVED59[0x2];        /* Reserved area    */
+    volatile unsigned short     cp_rter;        /* RISC timers event reg    */
+    volatile unsigned char      RESERVED38[0x2];        /* Reserved area    */
+    volatile unsigned short     cp_rtmr;        /* RISC timers mask reg     */
+    volatile unsigned char      RESERVED39[0x14];       /* Reserved area    */
+    /* BRG */
+    union {
+        volatile unsigned long l;
+        struct {
+            volatile unsigned short BRGC_RESERV:14;
+            volatile unsigned short rst:1;
+            volatile unsigned short en:1;
+            volatile unsigned short extc:2;
+            volatile unsigned short atb:1;
+            volatile unsigned short cd:12;
+            volatile unsigned short div16:1;
+        } b;
+    } brgc[4];                                  /* BRG1-BRG4 configuration regs*/
+    /* SCC registers */
+    struct scc_regs {
+        union {
+            struct {
+                /* Low word. */
+                volatile unsigned short GSMR_RESERV2:1;
+                volatile unsigned short edge:2;
+                volatile unsigned short tci:1;
+                volatile unsigned short tsnc:2;
+                volatile unsigned short rinv:1;
+                volatile unsigned short tinv:1;
+                volatile unsigned short tpl:3;
+                volatile unsigned short tpp:2;
+                volatile unsigned short tend:1;
+                volatile unsigned short tdcr:2;
+                volatile unsigned short rdcr:2;
+                volatile unsigned short renc:3;
+                volatile unsigned short tenc:3;
+                volatile unsigned short diag:2;
+                volatile unsigned short enr:1;
+                volatile unsigned short ent:1;
+                volatile unsigned short mode:4;
+                /* High word. */
+                volatile unsigned short GSMR_RESERV1:14;
+                volatile unsigned short pri:1;
+                volatile unsigned short gde:1;
+                volatile unsigned short tcrc:2;
+                volatile unsigned short revd:1;
+                volatile unsigned short trx:1;
+                volatile unsigned short ttx:1;
+                volatile unsigned short cdp:1;
+                volatile unsigned short ctsp:1;
+                volatile unsigned short cds:1;
+                volatile unsigned short ctss:1;
+                volatile unsigned short tfl:1;
+                volatile unsigned short rfw:1;
+                volatile unsigned short txsy:1;
+                volatile unsigned short synl:2;
+                volatile unsigned short rtsm:1;
+                volatile unsigned short rsyn:1;
+            } b;
+            struct {
+                volatile unsigned long low;
+                volatile unsigned long high;
+            } w;
+        } scc_gsmr;                         /* SCC general mode reg         */
+        volatile unsigned short scc_psmr;   /* protocol specific mode reg   */
+        volatile unsigned char  RESERVED42[0x2]; /* Reserved area           */
+        volatile unsigned short scc_todr; /* SCC transmit on demand         */
+        volatile unsigned short scc_dsr;        /* SCC data sync reg        */
+        volatile unsigned short scc_scce;       /* SCC event reg            */
+        volatile unsigned char  RESERVED43[0x2];/* Reserved area            */
+        volatile unsigned short scc_sccm;       /* SCC mask reg             */
+        volatile unsigned char  RESERVED44[0x1];/* Reserved area            */
+        volatile unsigned char  scc_sccs;       /* SCC status reg           */
+        volatile unsigned char  RESERVED45[0x8]; /* Reserved area           */
+    } scc_regs[4];
+    /* SMC */
+    struct smc_regs {
+        volatile unsigned char  RESERVED46[0x2]; /* Reserved area           */
+        volatile unsigned short smc_smcmr;       /* SMC mode reg            */
+        volatile unsigned char  RESERVED60[0x2]; /* Reserved area           */
+        volatile unsigned char  smc_smce;        /* SMC event reg           */
+        volatile unsigned char  RESERVED47[0x3]; /* Reserved area           */
+        volatile unsigned char  smc_smcm;        /* SMC mask reg            */
+        volatile unsigned char  RESERVED48[0x5]; /* Reserved area           */
+    } smc_regs[2];
+    /* SPI */
+    volatile unsigned short     spi_spmode;     /* SPI mode reg             */
+    volatile unsigned char      RESERVED51[0x4];        /* Reserved area    */
+    volatile unsigned char      spi_spie;       /* SPI event reg            */
+    volatile unsigned char      RESERVED52[0x3];        /* Reserved area    */
+    volatile unsigned char      spi_spim;       /* SPI mask reg             */
+    volatile unsigned char      RESERVED53[0x2];        /* Reserved area    */
+    volatile unsigned char      spi_spcom;      /* SPI command reg          */
+    volatile unsigned char      RESERVED54[0x4];        /* Reserved area    */
+    /* PIP */
+    volatile unsigned short     pip_pipc;       /* pip configuration reg    */
+    volatile unsigned char      RESERVED65[0x2];        /* Reserved area    */
+    volatile unsigned short     pip_ptpr;       /* pip timing parameters reg */
+    volatile unsigned long      pip_pbdir;      /* port b data direction reg */
+    volatile unsigned long      pip_pbpar;      /* port b pin assignment reg */
+    volatile unsigned long      pip_pbodr;      /* port b open drain reg    */
+    volatile unsigned long      pip_pbdat;      /* port b data reg          */
+    volatile unsigned char      RESERVED71[0x18];       /* Reserved area    */
+    /* Serial Interface */
+    volatile unsigned long      si_simode;      /* SI mode register         */
+    volatile unsigned char      si_sigmr;       /* SI global mode register  */
+    volatile unsigned char      RESERVED55;     /* Reserved area            */
+    volatile unsigned char      si_sistr;       /* SI status register       */
+    volatile unsigned char      si_sicmr;       /* SI command register      */
+    volatile unsigned char      RESERVED56[0x4]; /* Reserved area           */
+    volatile unsigned long      si_sicr;        /* SI clock routing         */
+    volatile unsigned long      si_sirp;        /* SI ram pointers          */
+    volatile unsigned char      RESERVED57[0xc]; /* Reserved area           */
+    volatile unsigned short     si_siram[0x80]; /* SI routing ram          */
+} QUICC;
+
+#endif
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 4
+ * End:
+ */
diff -Nru a/include/asm-m68knommu/m68360_regs.h b/include/asm-m68knommu/m68360_regs.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/m68360_regs.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,408 @@
+/***********************************
+ * $Id: m68360_regs.h,v 1.2 2002/10/26 15:03:55 gerg Exp $
+ ***********************************
+ *
+ ***************************************
+ * Definitions of the QUICC registers
+ ***************************************
+ */
+
+#ifndef __REGISTERS_H
+#define __REGISTERS_H
+
+#define CLEAR_BIT(x, bit)  x =bit 
+
+/*****************************************************************
+        Command Register
+*****************************************************************/
+
+/* bit fields within command register */
+#define SOFTWARE_RESET  0x8000
+#define CMD_OPCODE      0x0f00
+#define CMD_CHANNEL     0x00f0
+#define CMD_FLAG        0x0001
+
+/* general command opcodes */
+#define INIT_RXTX_PARAMS        0x0000
+#define INIT_RX_PARAMS          0x0100
+#define INIT_TX_PARAMS          0x0200
+#define ENTER_HUNT_MODE         0x0300
+#define STOP_TX                 0x0400
+#define GR_STOP_TX              0x0500
+#define RESTART_TX              0x0600
+#define CLOSE_RX_BD             0x0700
+#define SET_ENET_GROUP          0x0800
+#define RESET_ENET_GROUP        0x0900
+
+/* quicc32 CP commands */
+#define STOP_TX_32		0x0e00	/*add chan# bits 2-6 */
+#define ENTER_HUNT_MODE_32	0x1e00
+
+/* quicc32 mask/event SCC register */
+#define GOV	0x01
+#define GUN	0x02
+#define GINT	0x04
+#define IQOV	0x08
+
+
+/* Timer commands */
+#define SET_TIMER               0x0800
+
+/* Multi channel Interrupt structure */
+#define INTR_VALID	0x8000	/* Valid interrupt entry */
+#define INTR_WRAP	0x4000	/* Wrap bit in the interrupt entry table */
+#define INTR_CH_NU	0x07c0	/* Channel Num in interrupt table */
+#define INTR_MASK_BITS	0x383f
+
+/*
+ * General SCC mode register (GSMR)
+ */
+
+#define MODE_HDLC               0x0
+#define MODE_APPLE_TALK         0x2
+#define MODE_SS7                0x3
+#define MODE_UART               0x4
+#define MODE_PROFIBUS           0x5
+#define MODE_ASYNC_HDLC         0x6
+#define MODE_V14                0x7
+#define MODE_BISYNC             0x8
+#define MODE_DDCMP              0x9
+#define MODE_MULTI_CHANNEL      0xa
+#define MODE_ETHERNET           0xc
+
+#define DIAG_NORMAL             0x0
+#define DIAG_LOCAL_LPB          0x1
+#define DIAG_AUTO_ECHO          0x2
+#define DIAG_LBP_ECHO           0x3
+
+/* For RENC and TENC fields in GSMR */
+#define ENC_NRZ                 0x0
+#define ENC_NRZI                0x1
+#define ENC_FM0                 0x2
+#define ENC_MANCH               0x4
+#define ENC_DIFF_MANC           0x6
+
+/* For TDCR and RDCR fields in GSMR */
+#define CLOCK_RATE_1            0x0
+#define CLOCK_RATE_8            0x1
+#define CLOCK_RATE_16           0x2
+#define CLOCK_RATE_32           0x3
+
+#define TPP_00                  0x0
+#define TPP_10                  0x1
+#define TPP_01                  0x2
+#define TPP_11                  0x3
+
+#define TPL_NO                  0x0
+#define TPL_8                   0x1
+#define TPL_16                  0x2
+#define TPL_32                  0x3
+#define TPL_48                  0x4
+#define TPL_64                  0x5
+#define TPL_128                 0x6
+
+#define TSNC_INFINITE           0x0
+#define TSNC_14_65              0x1
+#define TSNC_4_15               0x2
+#define TSNC_3_1                0x3
+
+#define EDGE_BOTH               0x0
+#define EDGE_POS                0x1
+#define EDGE_NEG                0x2
+#define EDGE_NO                 0x3
+
+#define SYNL_NO                 0x0
+#define SYNL_4                  0x1
+#define SYNL_8                  0x2
+#define SYNL_16                 0x3
+
+#define TCRC_CCITT16            0x0
+#define TCRC_CRC16              0x1
+#define TCRC_CCITT32            0x2
+
+
+/*****************************************************************
+        TODR (Transmit on demand) Register
+*****************************************************************/
+#define TODR_TOD        0x8000  /* Transmit on demand */
+
+
+/*****************************************************************
+        CICR register settings
+*****************************************************************/
+
+/* note that relative irq priorities of the SCCs can be reordered
+ * if desired - see p. 7-377 of the MC68360UM */
+#define CICR_SCA_SCC1           ((uint)0x00000000)      /* SCC1 @ SCCa */
+#define CICR_SCB_SCC2           ((uint)0x00040000)      /* SCC2 @ SCCb */
+#define CICR_SCC_SCC3           ((uint)0x00200000)      /* SCC3 @ SCCc */
+#define CICR_SCD_SCC4           ((uint)0x00c00000)      /* SCC4 @ SCCd */
+
+#define CICR_IRL_MASK           ((uint)0x0000e000)      /* Core interrrupt */
+#define CICR_HP_MASK            ((uint)0x00001f00)      /* Hi-pri int. */
+#define CICR_VBA_MASK           ((uint)0x000000e0)      /* Vector Base Address */
+#define CICR_SPS                ((uint)0x00000001)      /* SCC Spread */
+
+
+/*****************************************************************
+       Interrupt bits for CIPR and CIMR (MC68360UM p. 7-379)
+*****************************************************************/
+
+#define INTR_PIO_PC0    0x80000000      /* parallel I/O C bit 0 */
+#define INTR_SCC1       0x40000000      /* SCC port 1 */
+#define INTR_SCC2       0x20000000      /* SCC port 2 */
+#define INTR_SCC3       0x10000000      /* SCC port 3 */
+#define INTR_SCC4       0x08000000      /* SCC port 4 */
+#define INTR_PIO_PC1    0x04000000      /* parallel i/o C bit 1 */
+#define INTR_TIMER1     0x02000000      /* timer 1 */
+#define INTR_PIO_PC2    0x01000000      /* parallel i/o C bit 2 */
+#define INTR_PIO_PC3    0x00800000      /* parallel i/o C bit 3 */
+#define INTR_SDMA_BERR  0x00400000      /* SDMA channel bus error */
+#define INTR_DMA1       0x00200000      /* idma 1 */
+#define INTR_DMA2       0x00100000      /* idma 2 */
+#define INTR_TIMER2     0x00040000      /* timer 2 */
+#define INTR_CP_TIMER   0x00020000      /* CP timer */
+#define INTR_PIP_STATUS 0x00010000      /* PIP status */
+#define INTR_PIO_PC4    0x00008000      /* parallel i/o C bit 4 */
+#define INTR_PIO_PC5    0x00004000      /* parallel i/o C bit 5 */
+#define INTR_TIMER3     0x00001000      /* timer 3 */
+#define INTR_PIO_PC6    0x00000800      /* parallel i/o C bit 6 */
+#define INTR_PIO_PC7    0x00000400      /* parallel i/o C bit 7 */
+#define INTR_PIO_PC8    0x00000200      /* parallel i/o C bit 8 */
+#define INTR_TIMER4     0x00000080      /* timer 4 */
+#define INTR_PIO_PC9    0x00000040      /* parallel i/o C bit 9 */
+#define INTR_SCP        0x00000020      /* SCP */
+#define INTR_SMC1       0x00000010      /* SMC 1 */
+#define INTR_SMC2       0x00000008      /* SMC 2 */
+#define INTR_PIO_PC10   0x00000004      /* parallel i/o C bit 10 */
+#define INTR_PIO_PC11   0x00000002      /* parallel i/o C bit 11 */
+#define INTR_ERR        0x00000001      /* error */
+
+
+/*****************************************************************
+        CPM Interrupt vector encodings (MC68360UM p. 7-376)
+*****************************************************************/
+
+#define CPMVEC_NR		32
+#define CPMVEC_PIO_PC0		0x1f
+#define CPMVEC_SCC1		0x1e
+#define CPMVEC_SCC2		0x1d
+#define CPMVEC_SCC3		0x1c
+#define CPMVEC_SCC4		0x1b
+#define CPMVEC_PIO_PC1		0x1a
+#define CPMVEC_TIMER1		0x19
+#define CPMVEC_PIO_PC2		0x18
+#define CPMVEC_PIO_PC3		0x17
+#define CPMVEC_SDMA_CB_ERR	0x16
+#define CPMVEC_IDMA1		0x15
+#define CPMVEC_IDMA2		0x14
+#define CPMVEC_RESERVED3	0x13
+#define CPMVEC_TIMER2		0x12
+#define CPMVEC_RISCTIMER	0x11
+#define CPMVEC_RESERVED2	0x10
+#define CPMVEC_PIO_PC4		0x0f
+#define CPMVEC_PIO_PC5		0x0e
+#define CPMVEC_TIMER3		0x0c
+#define CPMVEC_PIO_PC6		0x0b
+#define CPMVEC_PIO_PC7		0x0a
+#define CPMVEC_PIO_PC8		0x09
+#define CPMVEC_RESERVED1	0x08
+#define CPMVEC_TIMER4		0x07
+#define CPMVEC_PIO_PC9		0x06
+#define CPMVEC_SPI		0x05
+#define CPMVEC_SMC1		0x04
+#define CPMVEC_SMC2		0x03
+#define CPMVEC_PIO_PC10		0x02
+#define CPMVEC_PIO_PC11		0x01
+#define CPMVEC_ERROR		0x00
+
+/* #define CPMVEC_PIO_PC0		((ushort)0x1f) */
+/* #define CPMVEC_SCC1		((ushort)0x1e) */
+/* #define CPMVEC_SCC2		((ushort)0x1d) */
+/* #define CPMVEC_SCC3		((ushort)0x1c) */
+/* #define CPMVEC_SCC4		((ushort)0x1b) */
+/* #define CPMVEC_PIO_PC1		((ushort)0x1a) */
+/* #define CPMVEC_TIMER1		((ushort)0x19) */
+/* #define CPMVEC_PIO_PC2		((ushort)0x18) */
+/* #define CPMVEC_PIO_PC3		((ushort)0x17) */
+/* #define CPMVEC_SDMA_CB_ERR	((ushort)0x16) */
+/* #define CPMVEC_IDMA1		((ushort)0x15) */
+/* #define CPMVEC_IDMA2		((ushort)0x14) */
+/* #define CPMVEC_RESERVED3	((ushort)0x13) */
+/* #define CPMVEC_TIMER2		((ushort)0x12) */
+/* #define CPMVEC_RISCTIMER	((ushort)0x11) */
+/* #define CPMVEC_RESERVED2	((ushort)0x10) */
+/* #define CPMVEC_PIO_PC4		((ushort)0x0f) */
+/* #define CPMVEC_PIO_PC5		((ushort)0x0e) */
+/* #define CPMVEC_TIMER3		((ushort)0x0c) */
+/* #define CPMVEC_PIO_PC6		((ushort)0x0b) */
+/* #define CPMVEC_PIO_PC7		((ushort)0x0a) */
+/* #define CPMVEC_PIO_PC8		((ushort)0x09) */
+/* #define CPMVEC_RESERVED1	((ushort)0x08) */
+/* #define CPMVEC_TIMER4		((ushort)0x07) */
+/* #define CPMVEC_PIO_PC9		((ushort)0x06) */
+/* #define CPMVEC_SPI		((ushort)0x05) */
+/* #define CPMVEC_SMC1		((ushort)0x04) */
+/* #define CPMVEC_SMC2		((ushort)0x03) */
+/* #define CPMVEC_PIO_PC10		((ushort)0x02) */
+/* #define CPMVEC_PIO_PC11		((ushort)0x01) */
+/* #define CPMVEC_ERROR		((ushort)0x00) */
+
+
+/*****************************************************************
+ *        PIO control registers
+ *****************************************************************/
+
+/* Port A - See 360UM p. 7-358
+ * 
+ *  Note that most of these pins have alternate functions
+ */
+
+
+/* The macros are nice, but there are all sorts of references to 1-indexed
+ * facilities on the 68360... */
+/* #define PA_RXD(n)	((ushort)(0x01<<(2*n))) */
+/* #define PA_TXD(n)	((ushort)(0x02<<(2*n))) */
+
+#define PA_RXD1		((ushort)0x0001)
+#define PA_TXD1		((ushort)0x0002)
+#define PA_RXD2		((ushort)0x0004)
+#define PA_TXD2		((ushort)0x0008)
+#define PA_RXD3		((ushort)0x0010)
+#define PA_TXD3		((ushort)0x0020)
+#define PA_RXD4		((ushort)0x0040)
+#define PA_TXD4		((ushort)0x0080)
+
+#define PA_CLK1		((ushort)0x0100)
+#define PA_CLK2		((ushort)0x0200)
+#define PA_CLK3		((ushort)0x0400)
+#define PA_CLK4		((ushort)0x0800)
+#define PA_CLK5		((ushort)0x1000)
+#define PA_CLK6		((ushort)0x2000)
+#define PA_CLK7		((ushort)0x4000)
+#define PA_CLK8		((ushort)0x8000)
+
+
+/* Port B - See 360UM p. 7-362
+ */
+
+
+/* Port C - See 360UM p. 7-365
+ */
+
+#define PC_RTS1		((ushort)0x0001)
+#define PC_RTS2		((ushort)0x0002)
+#define PC__RTS3	((ushort)0x0004) /* !RTS3 */
+#define PC__RTS4	((ushort)0x0008) /* !RTS4 */
+
+#define PC_CTS1		((ushort)0x0010)
+#define PC_CD1		((ushort)0x0020)
+#define PC_CTS2		((ushort)0x0040)
+#define PC_CD2		((ushort)0x0080)
+#define PC_CTS3		((ushort)0x0100)
+#define PC_CD3		((ushort)0x0200)
+#define PC_CTS4		((ushort)0x0400)
+#define PC_CD4		((ushort)0x0800)
+
+
+
+/*****************************************************************
+        chip select option register
+*****************************************************************/
+#define DTACK           0xe000
+#define ADR_MASK        0x1ffc
+#define RDWR_MASK       0x0002
+#define FC_MASK         0x0001
+
+/*****************************************************************
+        tbase and rbase registers
+*****************************************************************/
+#define TBD_ADDR(quicc,pram) ((struct quicc_bd *) \
+    (quicc->ch_or_u.u.udata_bd_ucode + pram->tbase))
+#define RBD_ADDR(quicc,pram) ((struct quicc_bd *) \
+    (quicc->ch_or_u.u.udata_bd_ucode + pram->rbase))
+#define TBD_CUR_ADDR(quicc,pram) ((struct quicc_bd *) \
+    (quicc->ch_or_u.u.udata_bd_ucode + pram->tbptr))
+#define RBD_CUR_ADDR(quicc,pram) ((struct quicc_bd *) \
+    (quicc->ch_or_u.u.udata_bd_ucode + pram->rbptr))
+#define TBD_SET_CUR_ADDR(bd,quicc,pram) pram->tbptr = \
+    ((unsigned short)((char *)(bd) - (char *)(quicc->ch_or_u.u.udata_bd_ucode)))
+#define RBD_SET_CUR_ADDR(bd,quicc,pram) pram->rbptr = \
+    ((unsigned short)((char *)(bd) - (char *)(quicc->ch_or_u.u.udata_bd_ucode)))
+#define INCREASE_TBD(bd,quicc,pram) {  \
+    if((bd)->status & T_W)             \
+        (bd) = TBD_ADDR(quicc,pram);   \
+    else                               \
+        (bd)++;                        \
+}
+#define DECREASE_TBD(bd,quicc,pram) {  \
+    if ((bd) == TBD_ADDR(quicc, pram)) \
+        while (!((bd)->status & T_W))  \
+            (bd)++;                    \
+    else                               \
+        (bd)--;                        \
+}
+#define INCREASE_RBD(bd,quicc,pram) {  \
+    if((bd)->status & R_W)             \
+        (bd) = RBD_ADDR(quicc,pram);   \
+    else                               \
+        (bd)++;                        \
+}
+#define DECREASE_RBD(bd,quicc,pram) {  \
+    if ((bd) == RBD_ADDR(quicc, pram)) \
+        while (!((bd)->status & T_W))  \
+            (bd)++;                    \
+    else                               \
+        (bd)--;                        \
+}
+
+/*****************************************************************
+        Macros for Multi channel
+*****************************************************************/
+#define QMC_BASE(quicc,page) (struct global_multi_pram *)(&quicc->pram[page])
+#define MCBASE(quicc,page) (unsigned long)(quicc->pram[page].m.mcbase)
+#define CHANNEL_PRAM_BASE(quicc,channel) ((struct quicc32_pram *) \
+		(&(quicc->ch_or_u.ch_pram_tbl[channel])))
+#define TBD_32_ADDR(quicc,page,channel) ((struct quicc_bd *) \
+    (MCBASE(quicc,page) + (CHANNEL_PRAM_BASE(quicc,channel)->tbase)))
+#define RBD_32_ADDR(quicc,page,channel) ((struct quicc_bd *) \
+    (MCBASE(quicc,page) + (CHANNEL_PRAM_BASE(quicc,channel)->rbase)))
+#define TBD_32_CUR_ADDR(quicc,page,channel) ((struct quicc_bd *) \
+    (MCBASE(quicc,page) + (CHANNEL_PRAM_BASE(quicc,channel)->tbptr)))
+#define RBD_32_CUR_ADDR(quicc,page,channel) ((struct quicc_bd *) \
+    (MCBASE(quicc,page) + (CHANNEL_PRAM_BASE(quicc,channel)->rbptr)))
+#define TBD_32_SET_CUR_ADDR(bd,quicc,page,channel) \
+     CHANNEL_PRAM_BASE(quicc,channel)->tbptr = \
+    ((unsigned short)((char *)(bd) - (char *)(MCBASE(quicc,page))))
+#define RBD_32_SET_CUR_ADDR(bd,quicc,page,channel) \
+     CHANNEL_PRAM_BASE(quicc,channel)->rbptr = \
+    ((unsigned short)((char *)(bd) - (char *)(MCBASE(quicc,page))))
+
+#define INCREASE_TBD_32(bd,quicc,page,channel) {  \
+    if((bd)->status & T_W)                        \
+        (bd) = TBD_32_ADDR(quicc,page,channel);   \
+    else                                          \
+        (bd)++;                                   \
+}
+#define DECREASE_TBD_32(bd,quicc,page,channel) {  \
+    if ((bd) == TBD_32_ADDR(quicc, page,channel)) \
+        while (!((bd)->status & T_W))             \
+            (bd)++;                               \
+    else                                          \
+        (bd)--;                                   \
+}
+#define INCREASE_RBD_32(bd,quicc,page,channel) {  \
+    if((bd)->status & R_W)                        \
+        (bd) = RBD_32_ADDR(quicc,page,channel);   \
+    else                                          \
+        (bd)++;                                   \
+}
+#define DECREASE_RBD_32(bd,quicc,page,channel) {  \
+    if ((bd) == RBD_32_ADDR(quicc, page,channel)) \
+        while (!((bd)->status & T_W))             \
+            (bd)++;                               \
+    else                                          \
+        (bd)--;                                   \
+}
+
+#endif
diff -Nru a/include/asm-m68knommu/machdep.h b/include/asm-m68knommu/machdep.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/machdep.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,51 @@
+#ifndef _M68KNOMMU_MACHDEP_H
+#define _M68KNOMMU_MACHDEP_H
+
+struct pt_regs;
+struct kbd_repeat;
+struct mktime;
+struct hwclk_time;
+struct gendisk;
+struct buffer_head;
+
+extern void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *));
+/* machine dependent keyboard functions */
+extern int (*mach_keyb_init) (void);
+extern int (*mach_kbdrate) (struct kbd_repeat *);
+extern void (*mach_kbd_leds) (unsigned int);
+/* machine dependent irq functions */
+extern void (*mach_init_IRQ) (void);
+extern void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *);
+extern int (*mach_request_irq) (unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+                                unsigned long flags, const char *devname, void *dev_id);
+extern void (*mach_free_irq) (unsigned int irq, void *dev_id);
+extern void (*mach_get_model) (char *model);
+extern int (*mach_get_hardware_list) (char *buffer);
+extern int (*mach_get_irq_list) (struct seq_file *p, void *v);
+extern void (*mach_process_int) (int irq, struct pt_regs *fp);
+/* machine dependent timer functions */
+extern unsigned long (*mach_gettimeoffset)(void);
+extern void (*mach_gettod)(int *year, int *mon, int *day, int *hour,
+			   int *min, int *sec);
+extern int (*mach_hwclk)(int, struct hwclk_time*);
+extern int (*mach_set_clock_mmss)(unsigned long);
+extern void (*mach_reset)( void );
+extern void (*mach_halt)( void );
+extern void (*mach_power_off)( void );
+extern unsigned long (*mach_hd_init) (unsigned long, unsigned long);
+extern void (*mach_hd_setup)(char *, int *);
+extern long mach_max_dma_address;
+extern void (*mach_floppy_setup)(char *, int *);
+extern void (*mach_floppy_eject)(void);
+extern void (*mach_heartbeat) (int);
+extern void (*mach_l2_flush) (int);
+extern int mach_sysrq_key;
+extern int mach_sysrq_shift_state;
+extern int mach_sysrq_shift_mask;
+extern char *mach_sysrq_xlate;
+
+extern void config_BSP(char *command, int len);
+extern void (*mach_tick)(void);
+extern void (*mach_trap_init)(void);
+
+#endif /* _M68KNOMMU_MACHDEP_H */
diff -Nru a/include/asm-m68knommu/math-emu.h b/include/asm-m68knommu/math-emu.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/math-emu.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/math-emu.h>
diff -Nru a/include/asm-m68knommu/mc146818rtc.h b/include/asm-m68knommu/mc146818rtc.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/mc146818rtc.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,9 @@
+/*
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef _M68KNOMMU_MC146818RTC_H
+#define _M68KNOMMU_MC146818RTC_H
+
+/* empty include file to satisfy the include in genrtc.c/ide-geometry.c */
+
+#endif /* _M68KNOMMU_MC146818RTC_H */
diff -Nru a/include/asm-m68knommu/mcfdma.h b/include/asm-m68knommu/mcfdma.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/mcfdma.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,139 @@
+/****************************************************************************/
+
+/*
+ *	mcfdma.h -- Coldfire internal DMA support defines.
+ *
+ *	(C) Copyright 1999, Rob Scott (rscott@mtrob.ml.org)
+ */
+
+/****************************************************************************/
+#ifndef	mcfdma_h
+#define	mcfdma_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/*
+ *	Get address specific defines for this Coldfire member.
+ */
+#if defined(CONFIG_M5206) || defined(CONFIG_M5206e)
+#define	MCFDMA_BASE0		0x200		/* Base address of DMA 0 */
+#define	MCFDMA_BASE1		0x240		/* Base address of DMA 1 */
+#elif defined(CONFIG_M5272)
+#define	MCFDMA_BASE0		0x0e0		/* Base address of DMA 0 */
+#elif defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407)
+#define	MCFDMA_BASE0		0x300		/* Base address of DMA 0 */
+#define	MCFDMA_BASE1		0x340		/* Base address of DMA 1 */
+#define	MCFDMA_BASE2		0x380		/* Base address of DMA 2 */
+#define	MCFDMA_BASE3		0x3C0		/* Base address of DMA 3 */
+#endif
+
+
+#if !defined(CONFIG_M5272)
+
+/*
+ *	Define the DMA register set addresses.
+ *      Note: these are longword registers, use unsigned long as data type
+ */
+#define	MCFDMA_SAR		0x00		/* DMA source address (r/w) */
+#define	MCFDMA_DAR		0x01		/* DMA destination adr (r/w) */
+/* these are word registers, use unsigned short data type */
+#define	MCFDMA_DCR		0x04		/* DMA control reg (r/w) */
+#define	MCFDMA_BCR		0x06		/* DMA byte count reg (r/w) */
+/* these are byte registers, use unsiged char data type */
+#define	MCFDMA_DSR		0x10		/* DMA status reg (r/w) */
+#define	MCFDMA_DIVR		0x14		/* DMA interrupt vec (r/w) */
+
+/*
+ *	Bit definitions for the DMA Control Register (DCR).
+ */
+#define	MCFDMA_DCR_INT	        0x8000		/* Enable completion irq */
+#define	MCFDMA_DCR_EEXT	        0x4000		/* Enable external DMA req */
+#define	MCFDMA_DCR_CS 	        0x2000		/* Enable cycle steal */
+#define	MCFDMA_DCR_AA   	0x1000		/* Enable auto alignment */
+#define	MCFDMA_DCR_BWC_MASK  	0x0E00		/* Bandwidth ctl mask */
+#define MCFDMA_DCR_BWC_512      0x0200          /* Bandwidth:   512 Bytes */
+#define MCFDMA_DCR_BWC_1024     0x0400          /* Bandwidth:  1024 Bytes */
+#define MCFDMA_DCR_BWC_2048     0x0600          /* Bandwidth:  2048 Bytes */
+#define MCFDMA_DCR_BWC_4096     0x0800          /* Bandwidth:  4096 Bytes */
+#define MCFDMA_DCR_BWC_8192     0x0a00          /* Bandwidth:  8192 Bytes */
+#define MCFDMA_DCR_BWC_16384    0x0c00          /* Bandwidth: 16384 Bytes */
+#define MCFDMA_DCR_BWC_32768    0x0e00          /* Bandwidth: 32768 Bytes */
+#define	MCFDMA_DCR_SAA         	0x0100		/* Single Address Access */
+#define	MCFDMA_DCR_S_RW        	0x0080		/* SAA read/write value */
+#define	MCFDMA_DCR_SINC        	0x0040		/* Source addr inc enable */
+#define	MCFDMA_DCR_SSIZE_MASK  	0x0030		/* Src xfer size */
+#define	MCFDMA_DCR_SSIZE_LONG  	0x0000		/* Src xfer size, 00 = longw */
+#define	MCFDMA_DCR_SSIZE_BYTE  	0x0010		/* Src xfer size, 01 = byte */
+#define	MCFDMA_DCR_SSIZE_WORD  	0x0020		/* Src xfer size, 10 = word */
+#define	MCFDMA_DCR_SSIZE_LINE  	0x0030		/* Src xfer size, 11 = line */
+#define	MCFDMA_DCR_DINC        	0x0008		/* Dest addr inc enable */
+#define	MCFDMA_DCR_DSIZE_MASK  	0x0006		/* Dest xfer size */
+#define	MCFDMA_DCR_DSIZE_LONG  	0x0000		/* Dest xfer size, 00 = long */
+#define	MCFDMA_DCR_DSIZE_BYTE  	0x0002		/* Dest xfer size, 01 = byte */
+#define	MCFDMA_DCR_DSIZE_WORD  	0x0004		/* Dest xfer size, 10 = word */
+#define	MCFDMA_DCR_DSIZE_LINE  	0x0006		/* Dest xfer size, 11 = line */
+#define	MCFDMA_DCR_START       	0x0001		/* Start transfer */
+
+/*
+ *	Bit definitions for the DMA Status Register (DSR).
+ */
+#define	MCFDMA_DSR_CE	        0x40		/* Config error */
+#define	MCFDMA_DSR_BES	        0x20		/* Bus Error on source */
+#define	MCFDMA_DSR_BED 	        0x10		/* Bus Error on dest */
+#define	MCFDMA_DSR_REQ   	0x04		/* Requests remaining */
+#define	MCFDMA_DSR_BSY  	0x02		/* Busy */
+#define	MCFDMA_DSR_DONE        	0x01		/* DMA transfer complete */
+
+#else /* This is an MCF5272 */
+
+#define MCFDMA_DMR        0x00    /* Mode Register (r/w) */
+#define MCFDMA_DIR        0x03    /* Interrupt trigger register (r/w) */
+#define MCFDMA_DSAR       0x03    /* Source Address register (r/w) */
+#define MCFDMA_DDAR       0x04    /* Destination Address register (r/w) */
+#define MCFDMA_DBCR       0x02    /* Byte Count Register (r/w) */
+
+/* Bit definitions for the DMA Mode Register (DMR) */
+#define MCFDMA_DMR_RESET     0x80000000L /* Reset bit */
+#define MCFDMA_DMR_EN        0x40000000L /* DMA enable */
+#define MCFDMA_DMR_RQM       0x000C0000L /* Request Mode Mask */
+#define MCFDMA_DMR_RQM_DUAL  0x000C0000L /* Dual address mode, the only valid mode */
+#define MCFDMA_DMR_DSTM      0x00002000L /* Destination addressing mask */
+#define MCFDMA_DMR_DSTM_SA   0x00000000L /* Destination uses static addressing */
+#define MCFDMA_DMR_DSTM_IA   0x00002000L /* Destination uses incremental addressing */
+#define MCFDMA_DMR_DSTT_UD   0x00000400L /* Destination is user data */
+#define MCFDMA_DMR_DSTT_UC   0x00000800L /* Destination is user code */
+#define MCFDMA_DMR_DSTT_SD   0x00001400L /* Destination is supervisor data */
+#define MCFDMA_DMR_DSTT_SC   0x00001800L /* Destination is supervisor code */
+#define MCFDMA_DMR_DSTS_OFF  0x8         /* offset to the destination size bits */
+#define MCFDMA_DMR_DSTS_LONG 0x00000000L /* Long destination size */
+#define MCFDMA_DMR_DSTS_BYTE 0x00000100L /* Byte destination size */
+#define MCFDMA_DMR_DSTS_WORD 0x00000200L /* Word destination size */
+#define MCFDMA_DMR_DSTS_LINE 0x00000300L /* Line destination size */
+#define MCFDMA_DMR_SRCM      0x00000020L /* Source addressing mask */
+#define MCFDMA_DMR_SRCM_SA   0x00000000L /* Source uses static addressing */
+#define MCFDMA_DMR_SRCM_IA   0x00000020L /* Source uses incremental addressing */
+#define MCFDMA_DMR_SRCT_UD   0x00000004L /* Source is user data */
+#define MCFDMA_DMR_SRCT_UC   0x00000008L /* Source is user code */
+#define MCFDMA_DMR_SRCT_SD   0x00000014L /* Source is supervisor data */
+#define MCFDMA_DMR_SRCT_SC   0x00000018L /* Source is supervisor code */
+#define MCFDMA_DMR_SRCS_OFF  0x0         /* Offset to the source size bits */
+#define MCFDMA_DMR_SRCS_LONG 0x00000000L /* Long source size */
+#define MCFDMA_DMR_SRCS_BYTE 0x00000001L /* Byte source size */
+#define MCFDMA_DMR_SRCS_WORD 0x00000002L /* Word source size */
+#define MCFDMA_DMR_SRCS_LINE 0x00000003L /* Line source size */
+
+/* Bit definitions for the DMA interrupt register (DIR) */
+#define MCFDMA_DIR_INVEN     0x1000 /* Invalid Combination interrupt enable */
+#define MCFDMA_DIR_ASCEN     0x0800 /* Address Sequence Complete (Completion) interrupt enable */
+#define MCFDMA_DIR_TEEN      0x0200 /* Transfer Error interrupt enable */
+#define MCFDMA_DIR_TCEN      0x0100 /* Transfer Complete (a bus transfer, that is) interrupt enable */
+#define MCFDMA_DIR_INV       0x1000 /* Invalid Combination */
+#define MCFDMA_DIR_ASC       0x0008 /* Address Sequence Complete (DMA Completion) */
+#define MCFDMA_DIR_TE        0x0002 /* Transfer Error */
+#define MCFDMA_DIR_TC        0x0001 /* Transfer Complete */
+
+#endif /* !defined(CONFIG_M5272) */ 
+
+/****************************************************************************/
+#endif	/* mcfdma_h */
diff -Nru a/include/asm-m68knommu/mcfmbus.h b/include/asm-m68knommu/mcfmbus.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/mcfmbus.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,78 @@
+/****************************************************************************/
+
+/*
+ *      mcfmbus.h -- Coldfire MBUS support defines.
+ *
+ *      (C) Copyright 1999, Martin Floeer (mfloeer@axcent.de) 
+ */
+
+/****************************************************************************/
+
+
+#ifndef mcfmbus_h
+#define mcfmbus_h
+#include <linux/config.h>
+
+
+#define MCFMBUS_BASE		0x280
+#define MCFMBUS_IRQ_VECTOR	0x19
+#define MCFMBUS_IRQ		0x1
+#define MCFMBUS_CLK		0x3f
+#define MCFMBUS_IRQ_LEVEL	0x07	/*IRQ Level 1*/
+#define MCFMBUS_ADDRESS		0x01
+
+
+/*
+*	Define the 5307 MBUS register set adresses
+*/
+
+#define MCFMBUS_MADR	0x00
+#define MCFMBUS_MFDR	0x04
+#define MCFMBUS_MBCR	0x08
+#define MCFMBUS_MBSR	0x0C
+#define MCFMBUS_MBDR	0x10
+
+
+#define MCFMBUS_MADR_ADDR(a)	(((a)&0x7F)<<0x01) /*Slave Address*/
+
+#define MCFMBUS_MFDR_MBC(a)	((a)&0x3F)	   /*M-Bus Clock*/
+
+/*
+*	Define bit flags in Controll Register
+*/
+
+#define MCFMBUS_MBCR_MEN           (0x80)  /* M-Bus Enable                 */
+#define MCFMBUS_MBCR_MIEN          (0x40)  /* M-Bus Interrupt Enable       */
+#define MCFMBUS_MBCR_MSTA          (0x20)  /* Master/Slave Mode Select Bit */
+#define MCFMBUS_MBCR_MTX           (0x10)  /* Transmit/Rcv Mode Select Bit */
+#define MCFMBUS_MBCR_TXAK          (0x08)  /* Transmit Acknowledge Enable  */
+#define MCFMBUS_MBCR_RSTA          (0x04)  /* Repeat Start                 */
+
+/*
+*	Define bit flags in Status Register
+*/
+
+#define MCFMBUS_MBSR_MCF           (0x80)  /* Data Transfer Complete       */
+#define MCFMBUS_MBSR_MAAS          (0x40)  /* Addressed as a Slave         */
+#define MCFMBUS_MBSR_MBB           (0x20)  /* Bus Busy                     */
+#define MCFMBUS_MBSR_MAL           (0x10)  /* Arbitration Lost             */
+#define MCFMBUS_MBSR_SRW           (0x04)  /* Slave Transmit               */
+#define MCFMBUS_MBSR_MIF           (0x02)  /* M-Bus Interrupt              */
+#define MCFMBUS_MBSR_RXAK          (0x01)  /* No Acknowledge Received      */
+
+/*
+*	Define bit flags in DATA I/O Register
+*/
+
+#define MCFMBUS_MBDR_READ          (0x01)  /* 1=read 0=write MBUS */
+
+#define MBUSIOCSCLOCK		1
+#define MBUSIOCGCLOCK		2
+#define MBUSIOCSADDR			3
+#define MBUSIOCGADDR			4
+#define MBUSIOCSSLADDR			5
+#define MBUSIOCGSLADDR			6
+#define MBUSIOCSSUBADDR			7
+#define MBUSIOCGSUBADDR			8
+
+#endif
diff -Nru a/include/asm-m68knommu/mcfne.h b/include/asm-m68knommu/mcfne.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/mcfne.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,353 @@
+/****************************************************************************/
+
+/*
+ *	mcfne.h -- NE2000 in ColdFire eval boards.
+ *
+ *	(C) Copyright 1999-2000, Greg Ungerer (gerg@snapgear.com)
+ *	(C) Copyright 2000,      Lineo (www.lineo.com)
+ *	(C) Copyright 2001,      SnapGear (www.snapgear.com)
+ *
+ *      19990409 David W. Miller  Converted from m5206ne.h for 5307 eval board
+ *
+ *      Hacked support for m5206e Cadre III evaluation board
+ *      Fred Stevens (fred.stevens@pemstar.com) 13 April 1999
+ */
+
+/****************************************************************************/
+#ifndef	mcfne_h
+#define	mcfne_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/*
+ *	Support for NE2000 clones devices in ColdFire based boards.
+ *	Not all boards address these parts the same way, some use a
+ *	direct addressing method, others use a side-band address space
+ *	to access odd address registers, some require byte swapping
+ *	others do not.
+ */
+#define	BSWAP(w)	(((w) << 8) | ((w) >> 8))
+#define	RSWAP(w)	(w)
+
+
+/*
+ *	Define the basic hardware resources of NE2000 boards.
+ */
+
+#if defined(CONFIG_M5206) && defined(CONFIG_ARNEWSH)
+#define NE2000_ADDR		0x40000300
+#define NE2000_ODDOFFSET	0x00010000
+#define	NE2000_IRQ_VECTOR	0xf0
+#define	NE2000_IRQ_PRIORITY	2
+#define	NE2000_IRQ_LEVEL	4
+#define	NE2000_BYTE		volatile unsigned short
+#endif
+
+#if defined(CONFIG_M5206e) && defined(CONFIG_MOTOROLA)
+#define	NE2000_ADDR		0x40000300
+#define	NE2000_ODDOFFSET	0x00010000
+#define	NE2000_IRQ_VECTOR	0x1c
+#define	NE2000_IRQ_PRIORITY	2
+#define	NE2000_IRQ_LEVEL	4
+#define	NE2000_BYTE		volatile unsigned short
+#endif
+
+#if defined(CONFIG_M5206e) && defined(CONFIG_NETtel)
+#define NE2000_ADDR		0x30000300
+#define NE2000_IRQ_VECTOR	25
+#define NE2000_IRQ_PRIORITY	1
+#define NE2000_IRQ_LEVEL	3
+#define	NE2000_BYTE		volatile unsigned char
+#endif
+
+#if defined(CONFIG_M5206e) && defined(CONFIG_CFV240)
+#define NE2000_ADDR             0x40010000
+#define NE2000_ADDR1            0x40010001
+#define NE2000_ODDOFFSET        0x00000000
+#define NE2000_IRQ              1
+#define NE2000_IRQ_VECTOR       0x19
+#define NE2000_IRQ_PRIORITY     2
+#define NE2000_IRQ_LEVEL        1
+#define	NE2000_BYTE		volatile unsigned char
+#endif
+
+#if defined(CONFIG_M5307) && defined(CONFIG_MOTOROLA)
+#define NE2000_ADDR		0x40000300
+#define NE2000_ODDOFFSET	0x00010000
+#define NE2000_IRQ_VECTOR	0x1b
+#define	NE2000_BYTE		volatile unsigned short
+#endif
+
+#if defined(CONFIG_M5272) && defined(CONFIG_NETtel)
+#define NE2000_ADDR		0x30600300
+#define NE2000_ODDOFFSET	0x00008000
+#define NE2000_IRQ_VECTOR	67
+#undef	BSWAP
+#define	BSWAP(w)		(w)
+#define	NE2000_BYTE		volatile unsigned short
+#undef	RSWAP
+#define	RSWAP(w)		(((w) << 8) | ((w) >> 8))
+#endif
+
+#if defined(CONFIG_M5307) && defined(CONFIG_NETtel)
+#define NE2000_ADDR0		0x30600300
+#define NE2000_ADDR1		0x30800300
+#define NE2000_ODDOFFSET	0x00008000
+#define NE2000_IRQ_VECTOR0	27
+#define NE2000_IRQ_VECTOR1	29
+#undef	BSWAP
+#define	BSWAP(w)		(w)
+#define	NE2000_BYTE		volatile unsigned short
+#undef	RSWAP
+#define	RSWAP(w)		(((w) << 8) | ((w) >> 8))
+#endif
+
+#if defined(CONFIG_M5307) && defined(CONFIG_SECUREEDGEMP3)
+#define NE2000_ADDR		0x30600300
+#define NE2000_ODDOFFSET	0x00008000
+#define NE2000_IRQ_VECTOR	27
+#undef	BSWAP
+#define	BSWAP(w)		(w)
+#define	NE2000_BYTE		volatile unsigned short
+#undef	RSWAP
+#define	RSWAP(w)		(((w) << 8) | ((w) >> 8))
+#endif
+
+#if defined(CONFIG_M5307) && defined(CONFIG_ARNEWSH)
+#define NE2000_ADDR		0xfe600300
+#define NE2000_ODDOFFSET	0x00010000
+#define NE2000_IRQ_VECTOR	0x1b
+#define NE2000_IRQ_PRIORITY	2
+#define NE2000_IRQ_LEVEL	3
+#define	NE2000_BYTE		volatile unsigned short
+#endif
+
+#if defined(CONFIG_M5407)
+#define NE2000_ADDR		0x40000300
+#define NE2000_ODDOFFSET	0x00010000
+#define NE2000_IRQ_VECTOR	0x1b
+#define	NE2000_BYTE		volatile unsigned short
+#endif
+
+/****************************************************************************/
+
+/*
+ *	Side-band address space for odd address requires re-mapping
+ *	many of the standard ISA access functions.
+ */
+#ifdef NE2000_ODDOFFSET
+
+#undef outb
+#undef outb_p
+#undef inb
+#undef inb_p
+#undef outsb
+#undef outsw
+#undef insb
+#undef insw
+
+#define	outb	ne2000_outb
+#define	inb	ne2000_inb
+#define	outb_p	ne2000_outb
+#define	inb_p	ne2000_inb
+#define	outsb	ne2000_outsb
+#define	outsw	ne2000_outsw
+#define	insb	ne2000_insb
+#define	insw	ne2000_insw
+
+
+#ifndef COLDFIRE_NE2000_FUNCS
+
+void ne2000_outb(unsigned int val, unsigned int addr);
+int  ne2000_inb(unsigned int addr);
+void ne2000_insb(unsigned int addr, void *vbuf, int unsigned long len);
+void ne2000_insw(unsigned int addr, void *vbuf, unsigned long len);
+void ne2000_outsb(unsigned int addr, void *vbuf, unsigned long len);
+void ne2000_outsw(unsigned int addr, void *vbuf, unsigned long len);
+
+#else
+
+/*
+ *	This macro converts a conventional register address into the
+ *	real memory pointer of the mapped NE2000 device.
+ *	On most NE2000 implementations on ColdFire boards the chip is
+ *	mapped in kinda funny, due to its ISA heritage.
+ */
+#ifdef CONFIG_CFV240
+#define NE2000_PTR(addr)	(NE2000_ADDR + ((addr & 0x3f) << 1) + 1)
+#define NE2000_DATA_PTR(addr)	(NE2000_ADDR + ((addr & 0x3f) << 1))
+#else
+#define	NE2000_PTR(addr)	((addr&0x1)?(NE2000_ODDOFFSET+addr-1):(addr))
+#define	NE2000_DATA_PTR(addr)	(addr)
+#endif
+
+
+void ne2000_outb(unsigned int val, unsigned int addr)
+{
+	NE2000_BYTE	*rp;
+
+	rp = (NE2000_BYTE *) NE2000_PTR(addr);
+	*rp = RSWAP(val);
+}
+
+int ne2000_inb(unsigned int addr)
+{
+	NE2000_BYTE	*rp, val;
+
+	rp = (NE2000_BYTE *) NE2000_PTR(addr);
+	val = *rp;
+	return((int) ((NE2000_BYTE) RSWAP(val)));
+}
+
+void ne2000_insb(unsigned int addr, void *vbuf, int unsigned long len)
+{
+	NE2000_BYTE	*rp, val;
+	unsigned char	*buf;
+
+	buf = (unsigned char *) vbuf;
+	rp = (NE2000_BYTE *) NE2000_DATA_PTR(addr);
+	for (; (len > 0); len--) {
+		val = *rp;
+		*buf++ = RSWAP(val);
+	}
+}
+
+void ne2000_insw(unsigned int addr, void *vbuf, unsigned long len)
+{
+	volatile unsigned short	*rp;
+	unsigned short		w, *buf;
+
+	buf = (unsigned short *) vbuf;
+	rp = (volatile unsigned short *) NE2000_DATA_PTR(addr);
+	for (; (len > 0); len--) {
+		w = *rp;
+		*buf++ = BSWAP(w);
+	}
+}
+
+void ne2000_outsb(unsigned int addr, const void *vbuf, unsigned long len)
+{
+	NE2000_BYTE	*rp, val;
+	unsigned char	*buf;
+
+	buf = (unsigned char *) vbuf;
+	rp = (NE2000_BYTE *) NE2000_DATA_PTR(addr);
+	for (; (len > 0); len--) {
+		val = *buf++;
+		*rp = RSWAP(val);
+	}
+}
+
+void ne2000_outsw(unsigned int addr, const void *vbuf, unsigned long len)
+{
+	volatile unsigned short	*rp;
+	unsigned short		w, *buf;
+
+	buf = (unsigned short *) vbuf;
+	rp = (volatile unsigned short *) NE2000_DATA_PTR(addr);
+	for (; (len > 0); len--) {
+		w = *buf++;
+		*rp = BSWAP(w);
+	}
+}
+
+#endif /* COLDFIRE_NE2000_FUNCS */
+#endif /* NE2000_OFFOFFSET */
+
+/****************************************************************************/
+
+#ifdef COLDFIRE_NE2000_FUNCS
+
+/*
+ *	Lastly the interrupt set up code...
+ *	Minor diferences between the different board types.
+ */
+
+#if defined(CONFIG_M5206) && defined(CONFIG_ARNEWSH)
+void ne2000_irqsetup(int irq)
+{
+	volatile unsigned char  *icrp;
+
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_ICR4);
+	*icrp = MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI2;
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT4);
+}
+#endif
+
+#if defined(CONFIG_M5206e) && defined(CONFIG_MOTOROLA)
+void ne2000_irqsetup(int irq)
+{
+	volatile unsigned char  *icrp;
+
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_ICR4);
+	*icrp = MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI2 | MCFSIM_ICR_AUTOVEC;
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT4);
+}
+#endif
+
+#if defined(CONFIG_M5206e) && defined(CONFIG_CFV240)
+void ne2000_irqsetup(int irq)
+{
+	volatile unsigned char  *icrp;
+
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_ICR1);
+	*icrp = MCFSIM_ICR_LEVEL1 | MCFSIM_ICR_PRI2 | MCFSIM_ICR_AUTOVEC;
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT1);
+}
+#endif
+
+#if defined(CONFIG_M5206e) && defined(CONFIG_NETtel)
+void ne2000_irqsetup(int irq)
+{
+	mcf_autovector(irq);
+}
+#endif
+
+#if defined(CONFIG_M5272) && defined(CONFIG_NETtel)
+void ne2000_irqsetup(int irq)
+{
+	volatile unsigned long	*icrp;
+	volatile unsigned long	*pitr;
+
+	/* The NE2000 device uses external IRQ3 */
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+	*icrp = (*icrp & 0x77077777) | 0x00d00000;
+
+	pitr = (volatile unsigned long *) (MCF_MBAR + MCFSIM_PITR);
+	*pitr = *pitr | 0x20000000;
+}
+
+void ne2000_irqack(int irq)
+{
+	volatile unsigned long	*icrp;
+
+	/* The NE2000 device uses external IRQ3 */
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+	*icrp = (*icrp & 0x77777777) | 0x00800000;
+}
+#endif
+
+#if defined(CONFIG_M5307) || defined(CONFIG_M5407)
+#if defined(CONFIG_NETtel) || defined(CONFIG_SECUREEDGEMP3)
+
+void ne2000_irqsetup(int irq)
+{
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT3);
+	mcf_autovector(irq);
+}
+
+#else
+
+void ne2000_irqsetup(int irq)
+{
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT3);
+}
+
+#endif /* ! CONFIG_NETtel || CONFIG_SECUREEDGEMP3 */
+#endif /* CONFIG_M5307 || CONFIG_M5407 */
+
+#endif /* COLDFIRE_NE2000_FUNCS */
+
+/****************************************************************************/
+#endif	/* mcfne_h */
diff -Nru a/include/asm-m68knommu/mcfpci.h b/include/asm-m68knommu/mcfpci.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/mcfpci.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,120 @@
+/****************************************************************************/
+
+/*
+ *	mcfpci.h -- PCI bridge on ColdFire eval boards.
+ *
+ *	(C) Copyright 2000, Greg Ungerer (gerg@snapgear.com)
+ *	(C) Copyright 2000, Lineo Inc. (www.lineo.com)
+ */
+
+/****************************************************************************/
+#ifndef	mcfpci_h
+#define	mcfpci_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+#ifdef CONFIG_PCI
+
+/*
+ *	Address regions in the PCI addres space are not mapped into the
+ *	normal memory space of the ColdFire. They must be accessed via
+ *	handler routines. This is easy for I/O space (inb/outb/etc) but
+ *	needs some code changes to support ordinary memory. Interrupts
+ *	also need to be vectored through the PCI handler first, then it
+ *	will call the actual driver sub-handlers.
+ */
+
+/*
+ *	Un-define all the standard I/O access routines.
+ */
+#undef	inb
+#undef	inw
+#undef	inl
+#undef	inb_p
+#undef	inw_p
+#undef	insb
+#undef	insw
+#undef	insl
+#undef	outb
+#undef	outw
+#undef	outl
+#undef	outb_p
+#undef	outw_p
+#undef	outsb
+#undef	outsw
+#undef	outsl
+
+#undef	request_irq
+#undef	free_irq
+
+#undef	bus_to_virt
+#undef	virt_to_bus
+
+
+/*
+ *	Re-direct all I/O memory accesses functions to PCI specific ones.
+ */
+#define	inb	pci_inb
+#define	inw	pci_inw
+#define	inl	pci_inl
+#define	inb_p	pci_inb
+#define	inw_p	pci_inw
+#define	insb	pci_insb
+#define	insw	pci_insw
+#define	insl	pci_insl
+
+#define	outb	pci_outb
+#define	outw	pci_outw
+#define	outl	pci_outl
+#define	outb_p	pci_outb
+#define	outw_p	pci_outw
+#define	outsb	pci_outsb
+#define	outsw	pci_outsw
+#define	outsl	pci_outsl
+
+#define	request_irq	pci_request_irq
+#define	free_irq	pci_free_irq
+
+#define	virt_to_bus	pci_virt_to_bus
+#define	bus_to_virt	pci_bus_to_virt
+
+#define	CONFIG_COMEMPCI	1
+
+
+/*
+ *	Prototypes of the real PCI functions (defined in bios32.c).
+ */
+unsigned char	pci_inb(unsigned int addr);
+unsigned short	pci_inw(unsigned int addr);
+unsigned int	pci_inl(unsigned int addr);
+void		pci_insb(void *addr, void *buf, int len);
+void		pci_insw(void *addr, void *buf, int len);
+void		pci_insl(void *addr, void *buf, int len);
+
+void		pci_outb(unsigned char val, unsigned int addr);
+void		pci_outw(unsigned short val, unsigned int addr);
+void		pci_outl(unsigned int val, unsigned int addr);
+void		pci_outsb(void *addr, void *buf, int len);
+void		pci_outsw(void *addr, void *buf, int len);
+void		pci_outsl(void *addr, void *buf, int len);
+
+int		pci_request_irq(unsigned int irq,
+			void (*handler)(int, void *, struct pt_regs *),
+			unsigned long flags,
+			const char *device,
+			void *dev_id);
+void		pci_free_irq(unsigned int irq, void *dev_id);
+
+void		*pci_bmalloc(int size);
+void		pci_bmfree(void *bmp, int len);
+void		pci_copytoshmem(unsigned long bmp, void *src, int size);
+void		pci_copyfromshmem(void *dst, unsigned long bmp, int size);
+unsigned long	pci_virt_to_bus(volatile void *address);
+void		*pci_bus_to_virt(unsigned long address);
+void		pci_bmcpyto(void *dst, void *src, int len);
+void		pci_bmcpyfrom(void *dst, void *src, int len);
+
+#endif /* CONFIG_PCI */
+/****************************************************************************/
+#endif	/* mcfpci_h */
diff -Nru a/include/asm-m68knommu/mcfsim.h b/include/asm-m68knommu/mcfsim.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/mcfsim.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,104 @@
+/****************************************************************************/
+
+/*
+ *	mcfsim.h -- ColdFire System Integration Module support.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com)
+ * 	(C) Copyright 2000, Lineo Inc. (www.lineo.com) 
+ */
+
+/****************************************************************************/
+#ifndef	mcfsim_h
+#define	mcfsim_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/*
+ *	Include 5204, 5206, 5249, 5272, 5307 or 5407 specific addresses.
+ */
+#if defined(CONFIG_M5204)
+#include <asm/m5204sim.h>
+#elif defined(CONFIG_M5206) || defined(CONFIG_M5206e)
+#include <asm/m5206sim.h>
+#elif defined(CONFIG_M5249)
+#include <asm/m5249sim.h>
+#elif defined(CONFIG_M5272)
+#include <asm/m5272sim.h>
+#elif defined(CONFIG_M5307)
+#include <asm/m5307sim.h>
+#elif defined(CONFIG_M5407)
+#include <asm/m5407sim.h>
+#endif
+
+
+/*
+ *	Define the base address of the SIM within the MBAR address space.
+ */
+#define	MCFSIM_BASE		0x0		/* Base address of SIM */
+
+
+/*
+ *	Bit definitions for the ICR family of registers.
+ */
+#define	MCFSIM_ICR_AUTOVEC	0x80		/* Auto-vectored intr */
+#define	MCFSIM_ICR_LEVEL0	0x00		/* Level 0 intr */
+#define	MCFSIM_ICR_LEVEL1	0x04		/* Level 1 intr */
+#define	MCFSIM_ICR_LEVEL2	0x08		/* Level 2 intr */
+#define	MCFSIM_ICR_LEVEL3	0x0c		/* Level 3 intr */
+#define	MCFSIM_ICR_LEVEL4	0x10		/* Level 4 intr */
+#define	MCFSIM_ICR_LEVEL5	0x14		/* Level 5 intr */
+#define	MCFSIM_ICR_LEVEL6	0x18		/* Level 6 intr */
+#define	MCFSIM_ICR_LEVEL7	0x1c		/* Level 7 intr */
+
+#define	MCFSIM_ICR_PRI0		0x00		/* Priority 0 intr */
+#define	MCFSIM_ICR_PRI1		0x01		/* Priority 1 intr */
+#define	MCFSIM_ICR_PRI2		0x02		/* Priority 2 intr */
+#define	MCFSIM_ICR_PRI3		0x03		/* Priority 3 intr */
+
+/*
+ *	Bit definitions for the Interrupt Mask register (IMR).
+ */
+#define	MCFSIM_IMR_EINT1	0x0002		/* External intr # 1 */
+#define	MCFSIM_IMR_EINT2	0x0004		/* External intr # 2 */
+#define	MCFSIM_IMR_EINT3	0x0008		/* External intr # 3 */
+#define	MCFSIM_IMR_EINT4	0x0010		/* External intr # 4 */
+#define	MCFSIM_IMR_EINT5	0x0020		/* External intr # 5 */
+#define	MCFSIM_IMR_EINT6	0x0040		/* External intr # 6 */
+#define	MCFSIM_IMR_EINT7	0x0080		/* External intr # 7 */
+
+#define	MCFSIM_IMR_SWD		0x0100		/* Software Watchdog intr */
+#define	MCFSIM_IMR_TIMER1	0x0200		/* TIMER 1 intr */
+#define	MCFSIM_IMR_TIMER2	0x0400		/* TIMER 2 intr */
+#define MCFSIM_IMR_MBUS		0x0800		/* MBUS intr	*/
+#define	MCFSIM_IMR_UART1	0x1000		/* UART 1 intr */
+#define	MCFSIM_IMR_UART2	0x2000		/* UART 2 intr */
+
+#if defined(CONFIG_M5206e)
+#define	MCFSIM_IMR_DMA1		0x4000		/* DMA 1 intr */
+#define	MCFSIM_IMR_DMA2		0x8000		/* DMA 2 intr */
+#elif defined(CONFIG_M5249) || defined(CONFIG_M5307)
+#define	MCFSIM_IMR_DMA0		0x4000		/* DMA 0 intr */
+#define	MCFSIM_IMR_DMA1		0x8000		/* DMA 1 intr */
+#define	MCFSIM_IMR_DMA2		0x10000		/* DMA 2 intr */
+#define	MCFSIM_IMR_DMA3		0x20000		/* DMA 3 intr */
+#endif
+
+/*
+ *	Mask for all of the SIM devices. Some parts have more or less
+ *	SIM devices. This is a catchall for the sandard set.
+ */
+#ifndef MCFSIM_IMR_MASKALL
+#define	MCFSIM_IMR_MASKALL	0x3ffe		/* All intr sources */
+#endif
+
+
+#ifndef __ASSEMBLY__
+/*
+ *	Definition for the interrupt auto-vectoring support.
+ */
+extern void	mcf_autovector(unsigned int vec);
+#endif /* __ASSEMBLY__ */
+
+/****************************************************************************/
+#endif	/* mcfsim_h */
diff -Nru a/include/asm-m68knommu/mcfsmc.h b/include/asm-m68knommu/mcfsmc.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/mcfsmc.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,176 @@
+/****************************************************************************/
+
+/*
+ *	mcfsmc.h -- SMC ethernet support for ColdFire environments.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com)
+ *	(C) Copyright 2000, Lineo Inc. (www.lineo.com) 
+ */
+
+/****************************************************************************/
+#ifndef	mcfsmc_h
+#define	mcfsmc_h
+/****************************************************************************/
+
+/*
+ *	None of the current ColdFire targets that use the SMC91x111
+ *	allow 8 bit accesses. So this code is 16bit access only.
+ */
+
+#include <linux/config.h>
+
+#undef	outb
+#undef	inb
+
+/*
+ *	Re-defines for ColdFire environment... The SMC part is
+ *	mapped into memory space, so remap the PC-style in/out
+ *	routines to handle that.
+ */
+#define	outb	smc_outb
+#define	inb	smc_inb
+#define	outw	smc_outw
+#define	outwd	smc_outwd
+#define	inw	smc_inw
+#define	outl	smc_outl
+#define	inl	smc_inl
+
+#define	outsb	smc_outsb
+#define	outsw	smc_outsw
+#define	outsl	smc_outsl
+#define	insb	smc_insb
+#define	insw	smc_insw
+#define	insl	smc_insl
+
+
+static inline int smc_inb(unsigned int addr)
+{
+	register unsigned short	w;
+	w = *((volatile unsigned short *) (addr & ~0x1));
+	return(((addr & 0x1) ? w : (w >> 8)) & 0xff);
+}
+
+static inline void smc_outw(unsigned int val, unsigned int addr)
+{
+	*((volatile unsigned short *) addr) = (val << 8) | (val >> 8);
+}
+
+static inline int smc_inw(unsigned int addr)
+{
+	register unsigned short	w;
+	w = *((volatile unsigned short *) addr);
+	return(((w << 8) | (w >> 8)) & 0xffff);
+}
+
+static inline void smc_outl(unsigned long val, unsigned int addr)
+{
+	*((volatile unsigned long *) addr) = 
+		((val << 8) & 0xff000000) | ((val >> 8) & 0x00ff0000) |
+		((val << 8) & 0x0000ff00) | ((val >> 8) & 0x000000ff);
+}
+
+static inline void smc_outwd(unsigned int val, unsigned int addr)
+{
+	*((volatile unsigned short *) addr) = val;
+}
+
+
+/*
+ *	The rep* functions are used to feed the data port with
+ *	raw data. So we do not byte swap them when copying.
+ */
+
+static inline void smc_insb(unsigned int addr, void *vbuf, int unsigned long len)
+{
+	volatile unsigned short	*rp;
+	unsigned short		*buf, *ebuf;
+
+	buf = (unsigned short *) vbuf;
+	rp = (volatile unsigned short *) addr;
+
+	/* Copy as words for as long as possible */
+	for (ebuf = buf + (len >> 1); (buf < ebuf); )
+		*buf++ = *rp;
+
+	/* Lastly, handle left over byte */
+	if (len & 0x1)
+		*((unsigned char *) buf) = (*rp >> 8) & 0xff;
+}
+
+static inline void smc_insw(unsigned int addr, void *vbuf, unsigned long len)
+{
+	volatile unsigned short	*rp;
+	unsigned short		*buf, *ebuf;
+
+	buf = (unsigned short *) vbuf;
+	rp = (volatile unsigned short *) addr;
+	for (ebuf = buf + len; (buf < ebuf); )
+		*buf++ = *rp;
+}
+
+static inline void smc_insl(unsigned int addr, void *vbuf, unsigned long len)
+{
+	volatile unsigned long	*rp;
+	unsigned long		*buf, *ebuf;
+
+	buf = (unsigned long *) vbuf;
+	rp = (volatile unsigned long *) addr;
+	for (ebuf = buf + len; (buf < ebuf); )
+		*buf++ = *rp;
+}
+
+static inline void smc_outsw(unsigned int addr, const void *vbuf, unsigned long len)
+{
+	volatile unsigned short	*rp;
+	unsigned short		*buf, *ebuf;
+
+	buf = (unsigned short *) vbuf;
+	rp = (volatile unsigned short *) addr;
+	for (ebuf = buf + len; (buf < ebuf); )
+		*rp = *buf++;
+}
+
+static inline void smc_outsl(unsigned int addr, void *vbuf, unsigned long len)
+{
+	volatile unsigned long	*rp;
+	unsigned long		*buf, *ebuf;
+
+	buf = (unsigned long *) vbuf;
+	rp = (volatile unsigned long *) addr;
+	for (ebuf = buf + len; (buf < ebuf); )
+		*rp = *buf++;
+}
+
+
+#ifdef CONFIG_NETtel
+/*
+ *	Re-map the address space of at least one of the SMC ethernet
+ *	parts. Both parts power up decoding the same address, so we
+ *	need to move one of them first, before doing enything else.
+ *
+ *	We also increase the number of wait states for this part by one.
+ */
+
+void smc_remap(unsigned int ioaddr)
+{
+	static int		once = 0;
+	extern unsigned short	ppdata;
+	if (once++ == 0) {
+		*((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADDR)) = 0x00ec;
+		ppdata |= 0x0080;
+		*((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADAT)) = ppdata;
+		outw(0x0001, ioaddr + BANK_SELECT);
+		outw(0x0001, ioaddr + BANK_SELECT);
+		outw(0x0067, ioaddr + BASE);
+
+		ppdata &= ~0x0080;
+		*((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADAT)) = ppdata;
+	}
+	
+	*((volatile unsigned short *)(MCF_MBAR+MCFSIM_CSCR3)) = 0x1180;
+}
+
+#endif
+
+/****************************************************************************/
+#endif	/* mcfsmc_h */
diff -Nru a/include/asm-m68knommu/mcftimer.h b/include/asm-m68knommu/mcftimer.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/mcftimer.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,73 @@
+/****************************************************************************/
+
+/*
+ *	mcftimer.h -- ColdFire internal TIMER support defines.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com)
+ * 	(C) Copyright 2000, Lineo Inc. (www.lineo.com) 
+ */
+
+/****************************************************************************/
+#ifndef	mcftimer_h
+#define	mcftimer_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/*
+ *	Get address specific defines for this ColdFire member.
+ */
+#if defined(CONFIG_M5204) || defined(CONFIG_M5206) || defined(CONFIG_M5206e)
+#define	MCFTIMER_BASE1		0x100		/* Base address of TIMER1 */
+#define	MCFTIMER_BASE2		0x120		/* Base address of TIMER2 */
+#elif defined(CONFIG_M5272)
+#define MCFTIMER_BASE1		0x200           /* Base address of TIMER1 */
+#define MCFTIMER_BASE2		0x220           /* Base address of TIMER2 */
+#define MCFTIMER_BASE3		0x240           /* Base address of TIMER4 */
+#define MCFTIMER_BASE4		0x260           /* Base address of TIMER3 */
+#elif defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407)
+#define MCFTIMER_BASE1		0x140           /* Base address of TIMER1 */
+#define MCFTIMER_BASE2		0x180           /* Base address of TIMER2 */
+#endif
+
+
+/*
+ *	Define the TIMER register set addresses.
+ */
+#define	MCFTIMER_TMR		0x00		/* Timer Mode reg (r/w) */
+#define	MCFTIMER_TRR		0x02		/* Timer Reference (r/w) */
+#define	MCFTIMER_TCR		0x04		/* Timer Capture reg (r/w) */
+#define	MCFTIMER_TCN		0x06		/* Timer Counter reg (r/w) */
+#define	MCFTIMER_TER		0x11		/* Timer Event reg (r/w) */
+
+
+/*
+ *	Bit definitions for the Timer Mode Register (TMR).
+ *	Register bit flags are common accross ColdFires.
+ */
+#define	MCFTIMER_TMR_PREMASK	0xff00		/* Prescalar mask */
+#define	MCFTIMER_TMR_DISCE	0x0000		/* Disable capture */
+#define	MCFTIMER_TMR_ANYCE	0x00c0		/* Capture any edge */
+#define	MCFTIMER_TMR_FALLCE	0x0080		/* Capture fallingedge */
+#define	MCFTIMER_TMR_RISECE	0x0040		/* Capture rising edge */
+#define	MCFTIMER_TMR_ENOM	0x0020		/* Enable output toggle */
+#define	MCFTIMER_TMR_DISOM	0x0000		/* Do single output pulse  */
+#define	MCFTIMER_TMR_ENORI	0x0010		/* Enable ref interrupt */
+#define	MCFTIMER_TMR_DISORI	0x0000		/* Disable ref interrupt */
+#define	MCFTIMER_TMR_RESTART	0x0008		/* Restart counter */
+#define	MCFTIMER_TMR_FREERUN	0x0000		/* Free running counter */
+#define	MCFTIMER_TMR_CLKTIN	0x0006		/* Input clock is TIN */
+#define	MCFTIMER_TMR_CLK16	0x0004		/* Input clock is /16 */
+#define	MCFTIMER_TMR_CLK1	0x0002		/* Input clock is /1 */
+#define	MCFTIMER_TMR_CLKSTOP	0x0000		/* Stop counter */
+#define	MCFTIMER_TMR_ENABLE	0x0001		/* Enable timer */
+#define	MCFTIMER_TMR_DISABLE	0x0000		/* Disable timer */
+
+/*
+ *	Bit definitions for the Timer Event Registers (TER).
+ */
+#define	MCFTIMER_TER_CAP	0x01		/* Capture event */
+#define	MCFTIMER_TER_REF	0x02		/* Refernece event */
+
+/****************************************************************************/
+#endif	/* mcftimer_h */
diff -Nru a/include/asm-m68knommu/mcfuart.h b/include/asm-m68knommu/mcfuart.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/mcfuart.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,174 @@
+/****************************************************************************/
+
+/*
+ *	mcfuart.h -- ColdFire internal UART support defines.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com)
+ * 	(C) Copyright 2000, Lineo Inc. (www.lineo.com) 
+ */
+
+/****************************************************************************/
+#ifndef	mcfuart_h
+#define	mcfuart_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/*
+ *	Define the base address of the UARTS within the MBAR address
+ *	space.
+ */
+#if defined(CONFIG_M5272)
+#define	MCFUART_BASE1		0x100		/* Base address of UART1 */
+#define	MCFUART_BASE2		0x140		/* Base address of UART2 */
+#elif defined(CONFIG_M5204) || defined(CONFIG_M5206) || defined(CONFIG_M5206e)
+#if defined(CONFIG_NETtel)
+#define	MCFUART_BASE1		0x180		/* Base address of UART1 */
+#define	MCFUART_BASE2		0x140		/* Base address of UART2 */
+#else
+#define	MCFUART_BASE1		0x140		/* Base address of UART1 */
+#define	MCFUART_BASE2		0x180		/* Base address of UART2 */
+#endif
+#elif defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407)
+#if defined(CONFIG_NETtel) || defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3)
+#define MCFUART_BASE1		0x200           /* Base address of UART1 */
+#define MCFUART_BASE2		0x1c0           /* Base address of UART2 */    
+#else
+#define MCFUART_BASE1		0x1c0           /* Base address of UART1 */
+#define MCFUART_BASE2		0x200           /* Base address of UART2 */    
+#endif
+#endif
+
+
+/*
+ *	Define the ColdFire UART register set addresses.
+ */
+#define	MCFUART_UMR		0x00		/* Mode register (r/w) */
+#define	MCFUART_USR		0x04		/* Status register (r) */
+#define	MCFUART_UCSR		0x04		/* Clock Select (w) */
+#define	MCFUART_UCR		0x08		/* Command register (w) */
+#define	MCFUART_URB		0x0c		/* Receiver Buffer (r) */
+#define	MCFUART_UTB		0x0c		/* Transmit Buffer (w) */
+#define	MCFUART_UIPCR		0x10		/* Input Port Change (r) */
+#define	MCFUART_UACR		0x10		/* Auxiliary Control (w) */
+#define	MCFUART_UISR		0x14		/* Interrup Status (r) */
+#define	MCFUART_UIMR		0x14		/* Interrupt Mask (w) */
+#define	MCFUART_UBG1		0x18		/* Baud Rate MSB (r/w) */
+#define	MCFUART_UBG2		0x1c		/* Baud Rate LSB (r/w) */
+#define	MCFUART_UIVR		0x30		/* Interrupt Vector (r/w) */
+#define	MCFUART_UIPR		0x34		/* Input Port (r) */
+#define	MCFUART_UOP1		0x38		/* Output Port Bit Set (w) */
+#define	MCFUART_UOP0		0x3c		/* Output Port Bit Reset (w) */
+
+
+/*
+ *	Define bit flags in Mode Register 1 (MR1).
+ */
+#define	MCFUART_MR1_RXRTS	0x80		/* Auto RTS flow control */
+#define	MCFUART_MR1_RXIRQFULL	0x40		/* RX IRQ type FULL */
+#define	MCFUART_MR1_RXIRQRDY	0x00		/* RX IRQ type RDY */
+#define	MCFUART_MR1_RXERRBLOCK	0x20		/* RX block error mode */
+#define	MCFUART_MR1_RXERRCHAR	0x00		/* RX char error mode */
+
+#define	MCFUART_MR1_PARITYNONE	0x10		/* No parity */
+#define	MCFUART_MR1_PARITYEVEN	0x00		/* Even parity */
+#define	MCFUART_MR1_PARITYODD	0x04		/* Odd parity */
+#define	MCFUART_MR1_PARITYSPACE	0x08		/* Space parity */
+#define	MCFUART_MR1_PARITYMARK	0x06		/* Mark parity */
+
+#define	MCFUART_MR1_CS5		0x00		/* 5 bits per char */
+#define	MCFUART_MR1_CS6		0x01		/* 6 bits per char */
+#define	MCFUART_MR1_CS7		0x02		/* 7 bits per char */
+#define	MCFUART_MR1_CS8		0x03		/* 8 bits per char */
+
+/*
+ *	Define bit flags in Mode Register 2 (MR2).
+ */
+#define	MCFUART_MR2_LOOPBACK	0x80		/* Loopback mode */
+#define	MCFUART_MR2_REMOTELOOP	0xc0		/* Remote loopback mode */
+#define	MCFUART_MR2_AUTOECHO	0x40		/* Automatic echo */
+#define	MCFUART_MR2_TXRTS	0x20		/* Assert RTS on TX */
+#define	MCFUART_MR2_TXCTS	0x10		/* Auto CTS flow control */
+
+#define	MCFUART_MR2_STOP1	0x07		/* 1 stop bit */
+#define	MCFUART_MR2_STOP15	0x08		/* 1.5 stop bits */
+#define	MCFUART_MR2_STOP2	0x0f		/* 2 stop bits */
+
+/*
+ *	Define bit flags in Status Register (USR).
+ */
+#define	MCFUART_USR_RXBREAK	0x80		/* Received BREAK */
+#define	MCFUART_USR_RXFRAMING	0x40		/* Received framing error */
+#define	MCFUART_USR_RXPARITY	0x20		/* Received parity error */
+#define	MCFUART_USR_RXOVERRUN	0x10		/* Received overrun error */
+#define	MCFUART_USR_TXEMPTY	0x08		/* Transmitter empty */
+#define	MCFUART_USR_TXREADY	0x04		/* Transmitter ready */
+#define	MCFUART_USR_RXFULL	0x02		/* Receiver full */
+#define	MCFUART_USR_RXREADY	0x01		/* Receiver ready */
+
+#define	MCFUART_USR_RXERR	(MCFUART_USR_RXBREAK | MCFUART_USR_RXFRAMING | \
+				MCFUART_USR_RXPARITY | MCFUART_USR_RXOVERRUN)
+
+/*
+ *	Define bit flags in Clock Select Register (UCSR).
+ */
+#define	MCFUART_UCSR_RXCLKTIMER	0xd0		/* RX clock is timer */
+#define	MCFUART_UCSR_RXCLKEXT16	0xe0		/* RX clock is external x16 */
+#define	MCFUART_UCSR_RXCLKEXT1	0xf0		/* RX clock is external x1 */
+
+#define	MCFUART_UCSR_TXCLKTIMER	0x0d		/* TX clock is timer */
+#define	MCFUART_UCSR_TXCLKEXT16	0x0e		/* TX clock is external x16 */
+#define	MCFUART_UCSR_TXCLKEXT1	0x0f		/* TX clock is external x1 */
+
+/*
+ *	Define bit flags in Command Register (UCR).
+ */
+#define	MCFUART_UCR_CMDNULL		0x00	/* No command */
+#define	MCFUART_UCR_CMDRESETMRPTR	0x10	/* Reset MR pointer */
+#define	MCFUART_UCR_CMDRESETRX		0x20	/* Reset receiver */
+#define	MCFUART_UCR_CMDRESETTX		0x30	/* Reset transmitter */
+#define	MCFUART_UCR_CMDRESETERR		0x40	/* Reset error status */
+#define	MCFUART_UCR_CMDRESETBREAK	0x50	/* Reset BREAK change */
+#define	MCFUART_UCR_CMDBREAKSTART	0x60	/* Start BREAK */
+#define	MCFUART_UCR_CMDBREAKSTOP	0x70	/* Stop BREAK */
+
+#define	MCFUART_UCR_TXNULL	0x00		/* No TX command */
+#define	MCFUART_UCR_TXENABLE	0x04		/* Enable TX */
+#define	MCFUART_UCR_TXDISABLE	0x08		/* Disable TX */
+#define	MCFUART_UCR_RXNULL	0x00		/* No RX command */
+#define	MCFUART_UCR_RXENABLE	0x01		/* Enable RX */
+#define	MCFUART_UCR_RXDISABLE	0x02		/* Disable RX */
+
+/*
+ *	Define bit flags in Input Port Change Register (UIPCR).
+ */
+#define	MCFUART_UIPCR_CTSCOS	0x10		/* CTS change of state */
+#define	MCFUART_UIPCR_CTS	0x01		/* CTS value */
+
+/*
+ *	Define bit flags in Input Port Register (UIP).
+ */
+#define	MCFUART_UIPR_CTS	0x01		/* CTS value */
+
+/*
+ *	Define bit flags in Output Port Registers (UOP).
+ *	Clear bit by writing to UOP0, set by writing to UOP1.
+ */
+#define	MCFUART_UOP_RTS		0x01		/* RTS set or clear */
+
+/*
+ *	Define bit flags in the Auxiliary Control Register (UACR).
+ */
+#define	MCFUART_UACR_IEC	0x01		/* Input enable control */
+
+/*
+ *	Define bit flags in Interrupt Status Register (UISR).
+ *	These same bits are used for the Interrupt Mask Register (UIMR).
+ */
+#define	MCFUART_UIR_COS		0x80		/* Change of state (CTS) */
+#define	MCFUART_UIR_DELTABREAK	0x04		/* Break start or stop */
+#define	MCFUART_UIR_RXREADY	0x02		/* Receiver ready */
+#define	MCFUART_UIR_TXREADY	0x01		/* Transmitter ready */
+
+/****************************************************************************/
+#endif	/* mcfuart_h */
diff -Nru a/include/asm-m68knommu/mcfwdebug.h b/include/asm-m68knommu/mcfwdebug.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/mcfwdebug.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,119 @@
+/****************************************************************************/
+
+/*
+ *	mcfdebug.h -- ColdFire Debug Module support.
+ *
+ * 	(C) Copyright 2001, Lineo Inc. (www.lineo.com) 
+ */
+
+/****************************************************************************/
+#ifndef mcfdebug_h
+#define mcfdebug_h
+/****************************************************************************/
+#include <linux/config.h>
+
+/* Define the debug module registers */
+#define MCFDEBUG_CSR	0x0			/* Configuration status		*/
+#define MCFDEBUG_BAAR	0x5			/* BDM address attribute	*/
+#define MCFDEBUG_AATR	0x6			/* Address attribute trigger	*/
+#define MCFDEBUG_TDR	0x7			/* Trigger definition		*/
+#define MCFDEBUG_PBR	0x8			/* PC breakpoint		*/
+#define MCFDEBUG_PBMR	0x9			/* PC breakpoint mask		*/
+#define MCFDEBUG_ABHR	0xc			/* High address breakpoint	*/
+#define MCFDEBUG_ABLR	0xd			/* Low address breakpoint	*/
+#define MCFDEBUG_DBR	0xe			/* Data breakpoint		*/
+#define MCFDEBUG_DBMR	0xf			/* Data breakpoint mask		*/
+
+/* Define some handy constants for the trigger definition register */
+#define MCFDEBUG_TDR_TRC_DISP	0x00000000	/* display on DDATA only	*/
+#define MCFDEBUG_TDR_TRC_HALT	0x40000000	/* Processor halt on BP		*/
+#define MCFDEBUG_TDR_TRC_INTR	0x80000000	/* Debug intr on BP		*/
+#define MCFDEBUG_TDR_LXT1	0x00004000	/* TDR level 1			*/
+#define MCFDEBUG_TDR_LXT2	0x00008000	/* TDR level 2			*/
+#define MCFDEBUG_TDR_EBL1	0x00002000	/* Enable breakpoint level 1	*/
+#define MCFDEBUG_TDR_EBL2	0x20000000	/* Enable breakpoint level 2	*/
+#define MCFDEBUG_TDR_EDLW1	0x00001000	/* Enable data BP longword	*/
+#define MCFDEBUG_TDR_EDLW2	0x10000000
+#define MCFDEBUG_TDR_EDWL1	0x00000800	/* Enable data BP lower word	*/
+#define MCFDEBUG_TDR_EDWL2	0x08000000
+#define MCFDEBUG_TDR_EDWU1	0x00000400	/* Enable data BP upper word	*/
+#define MCFDEBUG_TDR_EDWU2	0x04000000
+#define MCFDEBUG_TDR_EDLL1	0x00000200	/* Enable data BP low low byte	*/
+#define MCFDEBUG_TDR_EDLL2	0x02000000
+#define MCFDEBUG_TDR_EDLM1	0x00000100	/* Enable data BP low mid byte	*/
+#define MCFDEBUG_TDR_EDLM2	0x01000000
+#define MCFDEBUG_TDR_EDUM1	0x00000080	/* Enable data BP up mid byte	*/
+#define MCFDEBUG_TDR_EDUM2	0x00800000
+#define MCFDEBUG_TDR_EDUU1	0x00000040	/* Enable data BP up up byte	*/
+#define MCFDEBUG_TDR_EDUU2	0x00400000
+#define MCFDEBUG_TDR_DI1	0x00000020	/* Data BP invert		*/
+#define MCFDEBUG_TDR_DI2	0x00200000
+#define MCFDEBUG_TDR_EAI1	0x00000010	/* Enable address BP inverted	*/
+#define MCFDEBUG_TDR_EAI2	0x00100000
+#define MCFDEBUG_TDR_EAR1	0x00000008	/* Enable address BP range	*/
+#define MCFDEBUG_TDR_EAR2	0x00080000
+#define MCFDEBUG_TDR_EAL1	0x00000004	/* Enable address BP low	*/
+#define MCFDEBUG_TDR_EAL2	0x00040000
+#define MCFDEBUG_TDR_EPC1	0x00000002	/* Enable PC BP			*/
+#define MCFDEBUG_TDR_EPC2	0x00020000
+#define MCFDEBUG_TDR_PCI1	0x00000001	/* PC BP invert			*/
+#define MCFDEBUG_TDR_PCI2	0x00010000
+
+/* Constants for the address attribute trigger register */
+#define MCFDEBUG_AAR_RESET	0x00000005
+/* Fields not yet implemented */
+
+/* And some definitions for the writable sections of the CSR */
+#define MCFDEBUG_CSR_RESET	0x00100000
+#define MCFDEBUG_CSR_PSTCLK	0x00020000	/* PSTCLK disable		*/
+#define MCFDEBUG_CSR_IPW	0x00010000	/* Inhibit processor writes	*/
+#define MCFDEBUG_CSR_MAP	0x00008000	/* Processor refs in emul mode	*/
+#define MCFDEBUG_CSR_TRC	0x00004000	/* Emul mode on trace exception	*/
+#define MCFDEBUG_CSR_EMU	0x00002000	/* Force emulation mode		*/
+#define MCFDEBUG_CSR_DDC_READ	0x00000800	/* Debug data control		*/
+#define MCFDEBUG_CSR_DDC_WRITE	0x00001000
+#define MCFDEBUG_CSR_UHE	0x00000400	/* User mode halt enable	*/
+#define MCFDEBUG_CSR_BTB0	0x00000000	/* Branch target 0 bytes	*/
+#define MCFDEBUG_CSR_BTB2	0x00000100	/* Branch target 2 bytes	*/
+#define MCFDEBUG_CSR_BTB3	0x00000200	/* Branch target 3 bytes	*/
+#define MCFDEBUG_CSR_BTB4	0x00000300	/* Branch target 4 bytes	*/
+#define MCFDEBUG_CSR_NPL	0x00000040	/* Non-pipelined mode		*/
+#define MCFDEBUG_CSR_SSM	0x00000010	/* Single step mode		*/
+
+/* Constants for the BDM address attribute register */
+#define MCFDEBUG_BAAR_RESET	0x00000005
+/* Fields not yet implemented */
+
+
+/* This routine wrappers up the wdebug asm instruction so that the register
+ * and value can be relatively easily specified.  The biggest hassle here is
+ * that the debug module instructions (2 longs) must be long word aligned and
+ * some pointer fiddling is performed to ensure this.
+ */
+extern inline void wdebug(int reg, unsigned long data) {
+	unsigned short dbg_spc[6];
+	unsigned short *dbg;
+
+	// Force alignment to long word boundary
+	dbg = (unsigned short *)((((unsigned long)dbg_spc) + 3) & 0xfffffffc);
+
+	// Build up the debug instruction
+	dbg[0] = 0x2c80 | (reg & 0xf);
+	dbg[1] = (data >> 16) & 0xffff;
+	dbg[2] = data & 0xffff;
+	dbg[3] = 0;
+
+	// Perform the wdebug instruction
+#if 0
+	// This strain is for gas which doesn't have the wdebug instructions defined
+	asm(	"move.l	%0, %%a0\n\t"
+		".word	0xfbd0\n\t"
+		".word	0x0003\n\t"
+	    :: "g" (dbg) : "a0");
+#else
+	// And this is for when it does
+	asm(	"wdebug	(%0)" :: "a" (dbg));
+#endif
+}
+
+#endif
diff -Nru a/include/asm-m68knommu/md.h b/include/asm-m68knommu/md.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/md.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1 @@
+#include <asm-m68k/md.h>
diff -Nru a/include/asm-m68knommu/mman.h b/include/asm-m68knommu/mman.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/mman.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/mman.h>
diff -Nru a/include/asm-m68knommu/mmu.h b/include/asm-m68knommu/mmu.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/mmu.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,22 @@
+#ifndef __M68KNOMMU_MMU_H
+#define __M68KNOMMU_MMU_H
+
+/* Copyright (C) 2002, David McCullough <davidm@snapgear.com> */
+
+struct mm_rblock_struct {
+	int	size;
+	int	refcount;
+	void	*kblock;
+};
+
+struct mm_tblock_struct {
+	struct mm_rblock_struct	*rblock;
+	struct mm_tblock_struct	*next;
+};
+
+typedef struct {
+	struct mm_tblock_struct	tblock;
+	unsigned long		end_brk;
+} mm_context_t;
+
+#endif /* __M68KNOMMU_MMU_H */
diff -Nru a/include/asm-m68knommu/mmu_context.h b/include/asm-m68knommu/mmu_context.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/mmu_context.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,31 @@
+#ifndef __M68KNOMMU_MMU_CONTEXT_H
+#define __M68KNOMMU_MMU_CONTEXT_H
+
+#include <linux/config.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
+{
+}
+
+extern inline int
+init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+	// mm->context = virt_to_phys(mm->pgd);
+	return(0);
+}
+
+#define destroy_context(mm)		do { } while(0)
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk, unsigned cpu)
+{
+}
+
+extern inline void activate_mm(struct mm_struct *prev_mm,
+			       struct mm_struct *next_mm)
+{
+}
+
+#endif
diff -Nru a/include/asm-m68knommu/module.h b/include/asm-m68knommu/module.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/module.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/module.h>
diff -Nru a/include/asm-m68knommu/movs.h b/include/asm-m68knommu/movs.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/movs.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/movs.h>
diff -Nru a/include/asm-m68knommu/msgbuf.h b/include/asm-m68knommu/msgbuf.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/msgbuf.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/msgbuf.h>
diff -Nru a/include/asm-m68knommu/namei.h b/include/asm-m68knommu/namei.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/namei.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/namei.h>
diff -Nru a/include/asm-m68knommu/nap.h b/include/asm-m68knommu/nap.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/nap.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,96 @@
+/****************************************************************************/
+
+/*
+ *	nap.h -- Marconi/NAP support.
+ *
+ * 	(C) Copyright 2001, SnapGear (www.snapgear.com) 
+ */
+
+/****************************************************************************/
+#ifndef	nap_h
+#define	nap_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/****************************************************************************/
+#ifdef CONFIG_MARCONINAP
+/****************************************************************************/
+
+#ifdef CONFIG_COLDFIRE
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#endif
+
+/*
+ *	Command to support selecting RS232 or RS422 mode on the
+ *	second COM port.
+ */
+#define	TIOCSET422	0x4d01		/* Set port mode 232 or 422 */
+#define	TIOCGET422	0x4d02		/* Get current port mode */
+
+/*
+ *	Low level control of the RS232/422 enable.
+ */
+#define	MCFPP_PA11	0x0800
+
+#ifndef __ASSEMBLY__
+/*
+ *	RS232/422 control is via the single PA11 line. Low is the RS422
+ *	enable, high is RS232 mode.
+ */
+static __inline__ unsigned int mcf_getpa(void)
+{
+	volatile unsigned short *pp;
+	pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+	return((unsigned int) *pp);
+}
+
+static __inline__ void mcf_setpa(unsigned int mask, unsigned int bits)
+{
+	volatile unsigned short *pp;
+	unsigned long		flags;
+
+	pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+	save_flags(flags); cli();
+	*pp = (*pp & ~mask) | bits;
+	restore_flags(flags);
+}
+#endif /* __ASSEMBLY__ */
+
+/****************************************************************************/
+
+#if defined(CONFIG_M5272)
+/*
+ *	Marconi/NAP based hardware. DTR/DCD lines are wired to GPB lines.
+ */
+#define	MCFPP_DCD0	0x0080
+#define	MCFPP_DCD1	0x0020
+#define	MCFPP_DTR0	0x0040
+#define	MCFPP_DTR1	0x0010
+
+#ifndef __ASSEMBLY__
+/*
+ *	These functions defined to give quasi generic access to the
+ *	PPIO bits used for DTR/DCD.
+ */
+static __inline__ unsigned int mcf_getppdata(void)
+{
+	volatile unsigned short *pp;
+	pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PBDAT);
+	return((unsigned int) *pp);
+}
+
+static __inline__ void mcf_setppdata(unsigned int mask, unsigned int bits)
+{
+	volatile unsigned short *pp;
+	pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PBDAT);
+	*pp = (*pp & ~mask) | bits;
+}
+#endif /* __ASSEMBLY__ */
+#endif /* CONFIG_M5272 */
+
+/****************************************************************************/
+#endif /* CONFIG_MARCONINAP */
+/****************************************************************************/
+#endif	/* nap_h */
diff -Nru a/include/asm-m68knommu/nettel.h b/include/asm-m68knommu/nettel.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/nettel.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,109 @@
+/****************************************************************************/
+
+/*
+ *	nettel.h -- Lineo (formerly Moreton Bay) NETtel support.
+ *
+ *	(C) Copyright 1999-2000, Moreton Bay (www.moretonbay.com)
+ * 	(C) Copyright 2000-2001, Lineo Inc. (www.lineo.com) 
+ * 	(C) Copyright 2001-2002, SnapGear Inc., (www.snapgear.com) 
+ */
+
+/****************************************************************************/
+#ifndef	nettel_h
+#define	nettel_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/****************************************************************************/
+#ifdef CONFIG_NETtel
+/****************************************************************************/
+
+#ifdef CONFIG_COLDFIRE
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#endif
+
+/*---------------------------------------------------------------------------*/
+#if defined(CONFIG_M5307)
+/*
+ *	NETtel/5307 based hardware first. DTR/DCD lines are wired to
+ *	GPIO lines. Most of the LED's are driver through a latch
+ *	connected to CS2.
+ */
+#define	MCFPP_DCD1	0x0001
+#define	MCFPP_DCD0	0x0002
+#define	MCFPP_DTR1	0x0004
+#define	MCFPP_DTR0	0x0008
+
+#define	NETtel_LEDADDR	0x30400000
+
+#ifndef __ASSEMBLY__
+
+extern volatile unsigned short ppdata;
+
+/*
+ *	These functions defined to give quasi generic access to the
+ *	PPIO bits used for DTR/DCD.
+ */
+static __inline__ unsigned int mcf_getppdata(void)
+{
+	volatile unsigned short *pp;
+	pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+	return((unsigned int) *pp);
+}
+
+static __inline__ void mcf_setppdata(unsigned int mask, unsigned int bits)
+{
+	volatile unsigned short *pp;
+	pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+	ppdata = (ppdata & ~mask) | bits;
+	*pp = ppdata;
+}
+#endif
+
+/*---------------------------------------------------------------------------*/
+#elif defined(CONFIG_M5206e)
+/*
+ *	NETtel/5206e based hardware has leds on latch on CS3.
+ *	No support modem for lines??
+ */
+#define	NETtel_LEDADDR	0x50000000
+
+/*---------------------------------------------------------------------------*/
+#elif defined(CONFIG_M5272)
+/*
+ *	NETtel/5272 based hardware. DTR/DCD lines are wired to GPB lines.
+ */
+#define	MCFPP_DCD0	0x0080
+#define	MCFPP_DCD1	0x0000		/* Port 1 no DCD support */
+#define	MCFPP_DTR0	0x0040
+#define	MCFPP_DTR1	0x0000		/* Port 1 no DTR support */
+
+#ifndef __ASSEMBLY__
+/*
+ *	These functions defined to give quasi generic access to the
+ *	PPIO bits used for DTR/DCD.
+ */
+static __inline__ unsigned int mcf_getppdata(void)
+{
+	volatile unsigned short *pp;
+	pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PBDAT);
+	return((unsigned int) *pp);
+}
+
+static __inline__ void mcf_setppdata(unsigned int mask, unsigned int bits)
+{
+	volatile unsigned short *pp;
+	pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PBDAT);
+	*pp = (*pp & ~mask) | bits;
+}
+#endif
+
+#endif
+/*---------------------------------------------------------------------------*/
+
+/****************************************************************************/
+#endif /* CONFIG_NETtel */
+/****************************************************************************/
+#endif	/* nettel_h */
diff -Nru a/include/asm-m68knommu/openprom.h b/include/asm-m68knommu/openprom.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/openprom.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/openprom.h>
diff -Nru a/include/asm-m68knommu/oplib.h b/include/asm-m68knommu/oplib.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/oplib.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/oplib.h>
diff -Nru a/include/asm-m68knommu/page.h b/include/asm-m68knommu/page.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/page.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,123 @@
+#ifndef _M68KNOMMU_PAGE_H
+#define _M68KNOMMU_PAGE_H
+
+#include <linux/config.h>
+
+/* PAGE_SHIFT determines the page size */
+
+#define PAGE_SHIFT	(12)
+#define PAGE_SIZE	(4096)
+#define PAGE_MASK	(~(PAGE_SIZE-1))
+
+#ifdef __KERNEL__
+
+#include <asm/setup.h>
+
+#if !defined(CONFIG_SMALL_TASKS) && PAGE_SHIFT < 13
+#define KTHREAD_SIZE (8192)
+#else
+#define KTHREAD_SIZE PAGE_SIZE
+#endif
+ 
+#ifndef __ASSEMBLY__
+ 
+#define get_user_page(vaddr)		__get_free_page(GFP_KERNEL)
+#define free_user_page(page, addr)	free_page(addr)
+
+#define clear_page(page)	memset((page), 0, PAGE_SIZE)
+#define copy_page(to,from)	memcpy((to), (from), PAGE_SIZE)
+
+#define clear_user_page(page, vaddr, pg)	clear_page(page)
+#define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long pmd[16]; } pmd_t;
+typedef struct { unsigned long pgd; } pgd_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+#define pte_val(x)	((x).pte)
+#define pmd_val(x)	((&x)->pmd[0])
+#define pgd_val(x)	((x).pgd)
+#define pgprot_val(x)	((x).pgprot)
+
+#define __pte(x)	((pte_t) { (x) } )
+#define __pmd(x)	((pmd_t) { (x) } )
+#define __pgd(x)	((pgd_t) { (x) } )
+#define __pgprot(x)	((pgprot_t) { (x) } )
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE-1)&PAGE_MASK)
+
+/* Pure 2^n version of get_order */
+extern __inline__ int get_order(unsigned long size)
+{
+	int order;
+
+	size = (size-1) >> (PAGE_SHIFT-1);
+	order = -1;
+	do {
+		size >>= 1;
+		order++;
+	} while (size);
+	return order;
+}
+
+extern unsigned long memory_start;
+extern unsigned long memory_end;
+
+#endif /* !__ASSEMBLY__ */
+
+#include <asm/page_offset.h>
+
+#define PAGE_OFFSET		(PAGE_OFFSET_RAW)
+
+#ifndef __ASSEMBLY__
+
+#define __pa(vaddr)		virt_to_phys((void *)vaddr)
+#define __va(paddr)		phys_to_virt((unsigned long)paddr)
+
+#define MAP_NR(addr)		(((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)
+
+#define virt_to_pfn(kaddr)	(__pa(kaddr) >> PAGE_SHIFT)
+#define pfn_to_virt(pfn)	__va((pfn) << PAGE_SHIFT)
+
+#define virt_to_page(addr)	(mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT))
+#define page_to_virt(page)	((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)
+#define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
+
+#define pfn_to_page(pfn)	virt_to_page(pfn_to_virt(pfn))
+#define page_to_pfn(page)	virt_to_pfn(page_to_virt(page))
+
+#define	virt_addr_valid(kaddr)	(((void *)(kaddr) >= (void *)PAGE_OFFSET) && \
+				((void *)(kaddr) < (void *)memory_end))
+
+
+#ifdef CONFIG_NO_KERNEL_MSG
+#define	BUG_PRINT()
+#else
+#define	BUG_PRINT() printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__)
+#endif
+
+
+// #define BUG_PANIC()	asm volatile ("halt") /* drop to debugger */
+// #define BUG_PANIC()	while(1)
+#define BUG_PANIC()	panic("BUG!")
+
+
+#define BUG() do { \
+	BUG_PRINT(); \
+	BUG_PANIC(); \
+} while (0)
+
+#define PAGE_BUG(page) do { \
+	BUG(); \
+} while (0)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* _M68KNOMMU_PAGE_H */
diff -Nru a/include/asm-m68knommu/page_offset.h b/include/asm-m68knommu/page_offset.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/page_offset.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,51 @@
+
+#include <linux/config.h>
+#include <asm/shglcore.h>
+
+/* This handles the memory map.. */
+
+#ifdef CONFIG_COLDFIRE
+#if defined(CONFIG_SMALL)
+#define PAGE_OFFSET_RAW		0x30020000
+#elif defined(CONFIG_CFV240)
+#define PAGE_OFFSET_RAW		0x02000000
+#else
+#define PAGE_OFFSET_RAW		0x00000000
+#endif
+#endif
+
+#ifdef CONFIG_M68360
+#define PAGE_OFFSET_RAW     0x00000000
+#endif
+
+#ifdef CONFIG_PILOT
+#ifdef CONFIG_M68328
+#define PAGE_OFFSET_RAW		0x10000000
+#endif
+#ifdef CONFIG_M68EZ328
+#define PAGE_OFFSET_RAW		0x00000000
+#endif
+#endif
+#ifdef CONFIG_UCSIMM
+#define PAGE_OFFSET_RAW		0x00000000
+#endif
+
+#if defined(CONFIG_UCDIMM) || defined(CONFIG_DRAGEN2)
+#ifdef CONFIG_M68VZ328 
+#define PAGE_OFFSET_RAW		0x00000000
+#endif /* CONFIG_M68VZ328 */
+#endif /* CONFIG_UCDIMM */
+
+#ifdef CONFIG_M68EZ328ADS
+#define PAGE_OFFSET_RAW		0x00000000
+#endif
+#ifdef CONFIG_ALMA_ANS
+#define PAGE_OFFSET_RAW		0x00000000
+#endif
+#ifdef CONFIG_M68EN302
+#define PAGE_OFFSET_RAW		0x00000000
+#endif
+#ifdef CONFIG_SHGLCORE
+#define PAGE_OFFSET_RAW		SHGLCORE_RAM_BANK_0_ADDR 
+#endif
+
diff -Nru a/include/asm-m68knommu/param.h b/include/asm-m68knommu/param.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/param.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,57 @@
+#ifndef _M68KNOMMU_PARAM_H
+#define _M68KNOMMU_PARAM_H
+
+#include <linux/config.h>
+
+#ifndef HZ
+#ifdef CONFIG_COLDFIRE
+#if defined(CONFIG_CLEOPATRA)
+#define HZ 1000
+#else
+#define HZ 100
+#endif
+#endif
+#ifdef CONFIG_M68EN302
+#define HZ 100
+#endif
+#ifdef CONFIG_M68328
+#define HZ 100
+#endif
+#ifdef CONFIG_M68EZ328
+#define HZ 100
+#endif
+#ifdef CONFIG_UCSIMM
+#define HZ 100
+#endif
+
+#ifdef CONFIG_M68VZ328
+#define HZ 100
+#endif
+
+#ifdef CONFIG_SHGLCORE
+#define HZ 50
+#endif
+#ifdef CONFIG_M68360
+#define HZ 100
+#endif
+
+#endif
+
+#ifdef __KERNEL__
+#define	USER_HZ		HZ
+#define	CLOCKS_PER_SEC	(USER_HZ)
+#endif
+
+#define EXEC_PAGESIZE	4096
+
+#ifndef NGROUPS
+#define NGROUPS		32
+#endif
+
+#ifndef NOGROUP
+#define NOGROUP		(-1)
+#endif
+
+#define MAXHOSTNAMELEN	64	/* max length of hostname */
+
+#endif /* _M68KNOMMU_PARAM_H */
diff -Nru a/include/asm-m68knommu/pci.h b/include/asm-m68knommu/pci.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/pci.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/pci.h>
diff -Nru a/include/asm-m68knommu/percpu.h b/include/asm-m68knommu/percpu.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/percpu.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,6 @@
+#ifndef __ARCH_M68KNOMMU_PERCPU__
+#define __ARCH_M68KNOMMU_PERCPU__
+
+#include <asm-generic/percpu.h>
+
+#endif /* __ARCH_M68KNOMMU_PERCPU__ */
diff -Nru a/include/asm-m68knommu/pgalloc.h b/include/asm-m68knommu/pgalloc.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/pgalloc.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,8 @@
+#ifndef _M68KNOMMU_PGALLOC_H
+#define _M68KNOMMU_PGALLOC_H
+
+#include <asm/setup.h>
+
+#define check_pgt_cache()	do { } while (0)
+
+#endif /* _M68KNOMMU_PGALLOC_H */
diff -Nru a/include/asm-m68knommu/pgtable.h b/include/asm-m68knommu/pgtable.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/pgtable.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,59 @@
+#ifndef _M68KNOMMU_PGTABLE_H
+#define _M68KNOMMU_PGTABLE_H
+
+/*
+ * (C) Copyright 2000-2002, Greg Ungerer <gerg@snapgear.com>
+ */
+
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/io.h>
+
+typedef pte_t *pte_addr_t;
+
+/*
+ * Trivial page table functions.
+ */
+#define pgd_present(pgd)	(1)
+#define pgd_none(pgd)		(0)
+#define pgd_bad(pgd)		(0)
+#define pgd_clear(pgdp)
+#define kern_addr_valid(addr)	(1)
+#define	pmd_offset(a, b)	((void *)0)
+
+#define PAGE_NONE	__pgprot(0)
+#define PAGE_SHARED	__pgprot(0)
+#define PAGE_COPY	__pgprot(0)
+#define PAGE_READONLY	__pgprot(0)
+#define PAGE_KERNEL	__pgprot(0)
+
+extern void paging_init(void);
+#define swapper_pg_dir ((pgd_t *) 0)
+
+#define __swp_type(x)		(0)
+#define __swp_offset(x)		(0)
+#define __swp_entry(typ,off)	((swp_entry_t) { ((typ) | ((off) << 7)) })
+#define __pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(x)	((pte_t) { (x).val })
+
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+#define ZERO_PAGE(vaddr)	(virt_to_page(0))
+
+/*
+ * These would be in other places but having them here reduces the diffs.
+ */
+extern unsigned int kobjsize(const void *objp);
+extern int is_in_rom(unsigned long);
+
+/*
+ * No page table caches to initialise.
+ */
+#define pgtable_cache_init()	do { } while (0)
+#define io_remap_page_range	remap_page_range
+
+#endif /* _M68KNOMMU_PGTABLE_H */
diff -Nru a/include/asm-m68knommu/poll.h b/include/asm-m68knommu/poll.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/poll.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/poll.h>
diff -Nru a/include/asm-m68knommu/posix_types.h b/include/asm-m68knommu/posix_types.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/posix_types.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/posix_types.h>
diff -Nru a/include/asm-m68knommu/processor.h b/include/asm-m68knommu/processor.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/processor.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,128 @@
+/*
+ * include/asm-m68k/processor.h
+ *
+ * Copyright (C) 1995 Hamish Macdonald
+ */
+
+#ifndef __ASM_M68K_PROCESSOR_H
+#define __ASM_M68K_PROCESSOR_H
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+
+#include <linux/config.h>
+#include <linux/threads.h>
+#include <asm/types.h>
+#include <asm/segment.h>
+#include <asm/fpu.h>
+#include <asm/ptrace.h>
+#include <asm/current.h>
+
+extern inline unsigned long rdusp(void)
+{
+#ifdef CONFIG_COLDFIRE
+	extern unsigned int sw_usp;
+	return(sw_usp);
+#else
+  	unsigned long usp;
+	__asm__ __volatile__("move %/usp,%0" : "=a" (usp));
+	return usp;
+#endif
+}
+
+extern inline void wrusp(unsigned long usp)
+{
+#ifdef CONFIG_COLDFIRE
+	extern unsigned int sw_usp;
+	sw_usp = usp;
+#else
+	__asm__ __volatile__("move %0,%/usp" : : "a" (usp));
+#endif
+}
+
+/*
+ * User space process size: 3.75GB. This is hardcoded into a few places,
+ * so don't change it unless you know what you are doing.
+ */
+#define TASK_SIZE	(0xF0000000UL)
+
+/*
+ * Bus types
+ */
+#define EISA_bus 0
+#define MCA_bus 0
+
+/* 
+ * if you change this structure, you must change the code and offsets
+ * in m68k/machasm.S
+ */
+   
+struct thread_struct {
+	unsigned long  ksp;		/* kernel stack pointer */
+	unsigned long  usp;		/* user stack pointer */
+	unsigned short sr;		/* saved status register */
+	unsigned short fs;		/* saved fs (sfc, dfc) */
+	unsigned long  crp[2];		/* cpu root pointer */
+	unsigned long  esp0;		/* points to SR of stack frame */
+	unsigned long  fp[8*3];
+	unsigned long  fpcntl[3];	/* fp control regs */
+	unsigned char  fpstate[FPSTATESIZE];  /* floating point state */
+};
+
+#define INIT_THREAD  { \
+	sizeof(init_stack) + (unsigned long) init_stack, 0, \
+	PS_S, __KERNEL_DS, \
+	{0, 0}, 0, {0,}, {0, 0, 0}, {0,}, \
+}
+
+/*
+ * Do necessary setup to start up a newly executed thread.
+ *
+ * pass the data segment into user programs if it exists,
+ * it can't hurt anything as far as I can tell
+ */
+#define start_thread(_regs, _pc, _usp)           \
+do {                                             \
+	set_fs(USER_DS); /* reads from user space */ \
+	(_regs)->pc = (_pc);                         \
+	if (current->mm)                             \
+		(_regs)->d5 = current->mm->start_data;   \
+	(_regs)->sr &= ~0x2000;                      \
+	wrusp(_usp);                                 \
+} while(0)
+
+/* Forward declaration, a strange C thing */
+struct task_struct;
+
+/* Free all resources held by a thread. */
+static inline void release_thread(struct task_struct *dead_task)
+{
+}
+
+extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
+/*
+ * Free current thread data structures etc..
+ */
+static inline void exit_thread(void)
+{
+}
+
+unsigned long thread_saved_pc(struct task_struct *tsk);
+unsigned long get_wchan(struct task_struct *p);
+
+#define	KSTK_EIP(tsk)	\
+    ({			\
+	unsigned long eip = 0;	 \
+	if ((tsk)->thread.esp0 > PAGE_SIZE && \
+	    MAP_NR((tsk)->thread.esp0) < max_mapnr) \
+	      eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \
+	eip; })
+#define	KSTK_ESP(tsk)	((tsk) == current ? rdusp() : (tsk)->thread.usp)
+
+#define cpu_relax()    do { } while (0)
+
+#endif
diff -Nru a/include/asm-m68knommu/ptrace.h b/include/asm-m68knommu/ptrace.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/ptrace.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,90 @@
+#ifndef _M68K_PTRACE_H
+#define _M68K_PTRACE_H
+
+#define PT_D1	   0
+#define PT_D2	   1
+#define PT_D3	   2
+#define PT_D4	   3
+#define PT_D5	   4
+#define PT_D6	   5
+#define PT_D7	   6
+#define PT_A0	   7
+#define PT_A1	   8
+#define PT_A2	   9
+#define PT_A3	   10
+#define PT_A4	   11
+#define PT_A5	   12
+#define PT_A6	   13
+#define PT_D0	   14
+#define PT_USP	   15
+#define PT_ORIG_D0 16
+#define PT_SR	   17
+#define PT_PC	   18
+
+#ifndef __ASSEMBLY__
+
+/* this struct defines the way the registers are stored on the
+   stack during a system call. */
+
+struct pt_regs {
+  long     d1;
+  long     d2;
+  long     d3;
+  long     d4;
+  long     d5;
+  long     a0;
+  long     a1;
+  long     a2;
+  long     d0;
+  long     orig_d0;
+  long     stkadj;
+#ifdef CONFIG_COLDFIRE
+  unsigned format :  4; /* frame format specifier */
+  unsigned vector : 12; /* vector offset */
+  unsigned short sr;
+  unsigned long  pc;
+#else
+  unsigned short sr;
+  unsigned long  pc;
+#ifndef NO_FORMAT_VEC
+  unsigned format :  4; /* frame format specifier */
+  unsigned vector : 12; /* vector offset */
+#endif
+#endif
+};
+
+/*
+ * This is the extended stack used by signal handlers and the context
+ * switcher: it's pushed after the normal "struct pt_regs".
+ */
+struct switch_stack {
+	unsigned long  d6;
+	unsigned long  d7;
+	unsigned long  a3;
+	unsigned long  a4;
+	unsigned long  a5;
+	unsigned long  a6;
+	unsigned long  retpc;
+};
+
+/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
+#define PTRACE_GETREGS            12
+#define PTRACE_SETREGS            13
+#ifdef COFNIG_FPU
+#define PTRACE_GETFPREGS          14
+#define PTRACE_SETFPREGS          15
+#endif
+
+#ifdef __KERNEL__
+
+#ifndef PS_S
+#define PS_S  (0x2000)
+#define PS_M  (0x1000)
+#endif
+
+#define user_mode(regs) (!((regs)->sr & PS_S))
+#define instruction_pointer(regs) ((regs)->pc)
+extern void show_regs(struct pt_regs *);
+#endif /* __KERNEL__ */
+#endif /* __ASSEMBLY__ */
+#endif /* _M68K_PTRACE_H */
diff -Nru a/include/asm-m68knommu/quicc_simple.h b/include/asm-m68knommu/quicc_simple.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/quicc_simple.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,52 @@
+/***********************************
+ * $Id: quicc_simple.h,v 1.1 2002/03/02 15:01:10 gerg Exp $
+ ***********************************
+ *
+ ***************************************
+ * Simple drivers common header
+ ***************************************
+ */
+
+#ifndef __SIMPLE_H
+#define __SIMPLE_H
+
+/* #include "quicc.h" */
+
+#define GLB_SCC_0   0
+#define GLB_SCC_1   1
+#define GLB_SCC_2   2
+#define GLB_SCC_3   3
+
+typedef void (int_routine)(unsigned short interrupt_event);
+typedef int_routine *int_routine_ptr; 
+typedef void *(alloc_routine)(int length);
+typedef void (free_routine)(int scc_num, int channel_num, void *buf);
+typedef void (store_rx_buffer_routine)(int scc_num, int channel_num, void *buff, int length);
+typedef int  (handle_tx_error_routine)(int scc_num, int channel_num, QUICC_BD *tbd);
+typedef void (handle_rx_error_routine)(int scc_num, int channel_num, QUICC_BD *rbd);
+typedef void (handle_lost_error_routine)(int scc_num, int channel_num);
+
+/* user defined functions for global errors */
+typedef void (handle_glob_overrun_routine)(int scc_number);
+typedef void (handle_glob_underrun_routine)(int scc_number);
+typedef void (glob_intr_q_overflow_routine)(int scc_number);
+
+/*
+ * General initialization and command routines
+ */
+void quicc_issue_cmd (unsigned short cmd, int scc_num);
+void quicc_init(void);
+void quicc_scc_init(int scc_number, int number_of_rx_buf, int number_of_tx_buf);
+void quicc_smc_init(int smc_number, int number_of_rx_buf, int number_of_tx_buf);
+void quicc_scc_start(int scc_num);
+void quicc_scc_loopback(int scc_num);
+
+/* Interrupt enable/disable routines for critical pieces of code*/
+unsigned short  IntrDis(void);
+void            IntrEna(unsigned short old_sr);
+
+/* For debugging */
+void print_rbd(int scc_num);
+void print_tbd(int scc_num);
+
+#endif
diff -Nru a/include/asm-m68knommu/resource.h b/include/asm-m68knommu/resource.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/resource.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/resource.h>
diff -Nru a/include/asm-m68knommu/rmap.h b/include/asm-m68knommu/rmap.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/rmap.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,2 @@
+/* Do not need anything here */
+
diff -Nru a/include/asm-m68knommu/scatterlist.h b/include/asm-m68knommu/scatterlist.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/scatterlist.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,13 @@
+#ifndef _M68KNOMMU_SCATTERLIST_H
+#define _M68KNOMMU_SCATTERLIST_H
+
+struct scatterlist {
+	struct page	*page;
+	unsigned int	offset;
+	dma_addr_t	dma_address;
+	unsigned int	length;
+};
+
+#define ISA_DMA_THRESHOLD	(0xffffffff)
+
+#endif /* !(_M68KNOMMU_SCATTERLIST_H) */
diff -Nru a/include/asm-m68knommu/segment.h b/include/asm-m68knommu/segment.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/segment.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,51 @@
+#ifndef _M68K_SEGMENT_H
+#define _M68K_SEGMENT_H
+
+/* define constants */
+/* Address spaces (FC0-FC2) */
+#define USER_DATA     (1)
+#ifndef __USER_DS
+#define __USER_DS     (USER_DATA)
+#endif
+#define USER_PROGRAM  (2)
+#define SUPER_DATA    (5)
+#ifndef __KERNEL_DS
+#define __KERNEL_DS   (SUPER_DATA)
+#endif
+#define SUPER_PROGRAM (6)
+#define CPU_SPACE     (7)
+
+#ifndef __ASSEMBLY__
+
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+#define MAKE_MM_SEG(s)	((mm_segment_t) { (s) })
+#define USER_DS		MAKE_MM_SEG(__USER_DS)
+#define KERNEL_DS	MAKE_MM_SEG(__KERNEL_DS)
+
+/*
+ * Get/set the SFC/DFC registers for MOVES instructions
+ */
+
+static inline mm_segment_t get_fs(void)
+{
+    return USER_DS;
+}
+
+static inline mm_segment_t get_ds(void)
+{
+    /* return the supervisor data space code */
+    return KERNEL_DS;
+}
+
+static inline void set_fs(mm_segment_t val)
+{
+}
+
+#define segment_eq(a,b)	((a).seg == (b).seg)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _M68K_SEGMENT_H */
diff -Nru a/include/asm-m68knommu/semaphore-helper.h b/include/asm-m68knommu/semaphore-helper.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/semaphore-helper.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,83 @@
+#ifndef _M68K_SEMAPHORE_HELPER_H
+#define _M68K_SEMAPHORE_HELPER_H
+
+/*
+ * SMP- and interrupt-safe semaphores helper functions.
+ *
+ * (C) Copyright 1996 Linus Torvalds
+ *
+ * m68k version by Andreas Schwab
+ */
+
+#include <linux/config.h>
+
+/*
+ * These two _must_ execute atomically wrt each other.
+ */
+static inline void wake_one_more(struct semaphore * sem)
+{
+	atomic_inc(&sem->waking);
+}
+
+static inline int waking_non_zero(struct semaphore *sem)
+{
+	int ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	ret = 0;
+	if (atomic_read(&sem->waking) > 0) {
+		atomic_dec(&sem->waking);
+		ret = 1;
+	}
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;
+}
+
+/*
+ * waking_non_zero_interruptible:
+ *	1	got the lock
+ *	0	go to sleep
+ *	-EINTR	interrupted
+ */
+static inline int waking_non_zero_interruptible(struct semaphore *sem,
+						struct task_struct *tsk)
+{
+	int ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	ret = 0;
+	if (atomic_read(&sem->waking) > 0) {
+		atomic_dec(&sem->waking);
+		ret = 1;
+	} else if (signal_pending(tsk)) {
+		atomic_inc(&sem->count);
+		ret = -EINTR;
+	}
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;
+}
+
+/*
+ * waking_non_zero_trylock:
+ *	1	failed to lock
+ *	0	got the lock
+ */
+static inline int waking_non_zero_trylock(struct semaphore *sem)
+{
+	int ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	ret = 1;
+	if (atomic_read(&sem->waking) > 0) {
+		atomic_dec(&sem->waking);
+		ret = 0;
+	} else
+		atomic_inc(&sem->count);
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;
+}
+
+#endif
diff -Nru a/include/asm-m68knommu/semaphore.h b/include/asm-m68knommu/semaphore.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/semaphore.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,178 @@
+#ifndef _M68K_SEMAPHORE_H
+#define _M68K_SEMAPHORE_H
+
+#define RW_LOCK_BIAS		 0x01000000
+
+#ifndef __ASSEMBLY__
+
+#include <linux/linkage.h>
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+#include <linux/rwsem.h>
+
+#include <asm/system.h>
+#include <asm/atomic.h>
+
+/*
+ * Interrupt-safe semaphores..
+ *
+ * (C) Copyright 1996 Linus Torvalds
+ *
+ * m68k version by Andreas Schwab
+ */
+
+
+struct semaphore {
+	atomic_t count;
+	atomic_t waking;
+	wait_queue_head_t wait;
+#if WAITQUEUE_DEBUG
+	long __magic;
+#endif
+};
+
+#if WAITQUEUE_DEBUG
+# define __SEM_DEBUG_INIT(name) \
+		, (long)&(name).__magic
+#else
+# define __SEM_DEBUG_INIT(name)
+#endif
+
+#define __SEMAPHORE_INITIALIZER(name,count) \
+{ ATOMIC_INIT(count), ATOMIC_INIT(0), __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
+	__SEM_DEBUG_INIT(name) }
+
+#define __MUTEX_INITIALIZER(name) \
+	__SEMAPHORE_INITIALIZER(name,1)
+
+#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+
+#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
+#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
+
+extern inline void sema_init (struct semaphore *sem, int val)
+{
+	*sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val);
+}
+
+static inline void init_MUTEX (struct semaphore *sem)
+{
+	sema_init(sem, 1);
+}
+
+static inline void init_MUTEX_LOCKED (struct semaphore *sem)
+{
+	sema_init(sem, 0);
+}
+
+asmlinkage void __down_failed(void /* special register calling convention */);
+asmlinkage int  __down_failed_interruptible(void  /* params in registers */);
+asmlinkage int  __down_failed_trylock(void  /* params in registers */);
+asmlinkage void __up_wakeup(void /* special register calling convention */);
+
+asmlinkage void __down(struct semaphore * sem);
+asmlinkage int  __down_interruptible(struct semaphore * sem);
+asmlinkage int  __down_trylock(struct semaphore * sem);
+asmlinkage void __up(struct semaphore * sem);
+
+extern spinlock_t semaphore_wake_lock;
+
+/*
+ * This is ugly, but we want the default case to fall through.
+ * "down_failed" is a special asm handler that calls the C
+ * routine that actually waits. See arch/m68k/lib/semaphore.S
+ */
+extern inline void down(struct semaphore * sem)
+{
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	__asm__ __volatile__(
+		"| atomic down operation\n\t"
+		"movel	%0, %%a1\n\t"
+		"lea	%%pc@(1f), %%a0\n\t"
+		"subql	#1, %%a1@\n\t"
+		"jmi __down_failed\n"
+		"1:"
+		: /* no outputs */
+		: "g" (sem)
+		: "cc", "%a0", "%a1", "memory");
+}
+
+extern inline int down_interruptible(struct semaphore * sem)
+{
+	int ret;
+
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	__asm__ __volatile__(
+		"| atomic down operation\n\t"
+		"movel	%1, %%a1\n\t"
+		"lea	%%pc@(1f), %%a0\n\t"
+		"subql	#1, %%a1@\n\t"
+		"jmi __down_failed_interruptible\n\t"
+		"clrl	%%d0\n"
+		"1: movel	%%d0, %0\n"
+		: "=d" (ret)
+		: "g" (sem)
+		: "cc", "%d0", "%a0", "%a1", "memory");
+	return(ret);
+}
+
+extern inline int down_trylock(struct semaphore * sem)
+{
+	register struct semaphore *sem1 __asm__ ("%a1") = sem;
+	register int result __asm__ ("%d0");
+
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	__asm__ __volatile__(
+		"| atomic down trylock operation\n\t"
+		"subql #1,%1@\n\t"
+		"jmi 2f\n\t"
+		"clrl %0\n"
+		"1:\n"
+		".section .text.lock,\"ax\"\n"
+		".even\n"
+		"2:\tpea 1b\n\t"
+		"jbra __down_failed_trylock\n"
+		".previous"
+		: "=d" (result)
+		: "a" (sem1)
+		: "%d0", "memory");
+	return result;
+}
+
+/*
+ * Note! This is subtle. We jump to wake people up only if
+ * the semaphore was negative (== somebody was waiting on it).
+ * The default case (no contention) will result in NO
+ * jumps for both down() and up().
+ */
+extern inline void up(struct semaphore * sem)
+{
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	__asm__ __volatile__(
+		"| atomic up operation\n\t"
+		"movel	%0, %%a1\n\t"
+		"lea	%%pc@(1f), %%a0\n\t"
+		"addql	#1, %%a1@\n\t"
+		"jle __up_wakeup\n"
+		"1:"
+		: /* no outputs */
+		: "g" (sem)
+		: "cc", "%a0", "%a1", "memory");
+}
+
+#endif /* __ASSEMBLY__ */
+
+#endif
diff -Nru a/include/asm-m68knommu/sembuf.h b/include/asm-m68knommu/sembuf.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/sembuf.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/sembuf.h>
diff -Nru a/include/asm-m68knommu/semp3.h b/include/asm-m68knommu/semp3.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/semp3.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,60 @@
+/****************************************************************************/
+
+/*
+ *	semp.h -- SecureEdge MP3 hardware platform support.
+ *
+ *	(C) Copyright 2001-2002, Greg Ungerer (gerg@snapgear.com).
+ */
+
+/****************************************************************************/
+#ifndef	semp3_h
+#define	semp3_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/****************************************************************************/
+#ifdef CONFIG_SECUREEDGEMP3
+/****************************************************************************/
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+
+/*
+ *	The ColdFire UARTs do not have any support for DTR/DCD lines.
+ *	We have wired them onto some of the parallel IO lines.
+ */
+#define	MCFPP_DCD1	0x0004
+#define	MCFPP_DCD0	0x0000		/* No DCD line on port 0 */
+#define	MCFPP_DTR1	0x0080
+#define	MCFPP_DTR0	0x0000		/* No DTR line on port 0 */
+
+
+#ifndef __ASSEMBLY__
+
+extern volatile unsigned short ppdata;
+
+/*
+ *	These functions defined to give quasi generic access to the
+ *	PPIO bits used for DTR/DCD.
+ */
+static __inline__ unsigned int mcf_getppdata(void)
+{
+	volatile unsigned short *pp;
+	pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+	return((unsigned int) *pp);
+}
+
+static __inline__ void mcf_setppdata(unsigned int mask, unsigned int bits)
+{
+	volatile unsigned short *pp;
+	pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+	ppdata = (ppdata & ~mask) | bits;
+	*pp = ppdata;
+}
+#endif
+
+/****************************************************************************/
+#endif /* CONFIG_SECUREEDGEMP3 */
+/****************************************************************************/
+#endif	/* semp3_h */
diff -Nru a/include/asm-m68knommu/setup.h b/include/asm-m68knommu/setup.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/setup.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/setup.h>
diff -Nru a/include/asm-m68knommu/shglcore.h b/include/asm-m68knommu/shglcore.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/shglcore.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,65 @@
+
+/* Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ */
+
+#ifndef _M68K_SHGLCORE_H
+#define _M68K_SHGLCORE_H
+
+#include <linux/config.h>
+
+#ifdef CONFIG_SHGLCORE
+
+#include <asm/MC68332.h>
+
+#ifdef CONFIG_SHGLCORE_2MEG
+
+#define SHGLCORE_ROM_BANK_0_ADDR	0x000000
+#define SHGLCORE_ROM_BANK_1_ADDR	0x100000
+#define SHGLCORE_RAM_BANK_0_ADDR	0x200000
+#define SHGLCORE_RAM_BANK_1_ADDR	0x300000
+#define SHGLCORE_FLASH_BANK_0_ADDR	0x400000
+
+#define SHGLCORE_ROM_BANK_0_LENGTH	0x100000
+#define SHGLCORE_ROM_BANK_1_LENGTH	0x100000
+#define SHGLCORE_RAM_BANK_0_LENGTH	0x100000
+#define SHGLCORE_RAM_BANK_1_LENGTH	0x100000
+#define SHGLCORE_FLASH_BANK_0_LENGTH	0x80000
+
+#define SHGLCORE_ACC_ADDR		0x600000
+#define SHGLCORE_LANCE_ADDR		0x700000
+
+#else
+
+#define SHGLCORE_ROM_BANK_0_ADDR	0x000000
+#define SHGLCORE_RAM_BANK_0_ADDR	0x100000
+#define SHGLCORE_FLASH_BANK_0_ADDR	0x300000
+
+#define SHGLCORE_ROM_BANK_0_LENGTH	0x100000
+#define SHGLCORE_RAM_BANK_0_LENGTH	0x100000
+#define SHGLCORE_FLASH_BANK_0_LENGTH	0x80000
+
+#define SHGLCORE_ACC_ADDR		0x400000
+#define SHGLCORE_LANCE_ADDR		0x500000
+
+#endif
+
+#define MAX_DMA_ADDRESS			SHGLCORE_RAM_BANK_0_ADDR + SHGLCORE_RAM_BANK_0_LENGTH
+
+#define SHGLCORE_LATCH_ADDR	(SHGLCORE_ACC_ADDR+0x100)
+#define SHGLCORE_1865_0_ADDR	(SHGLCORE_ACC_ADDR+0x600)
+#define SHGLCORE_1865_1_ADDR	(SHGLCORE_ACC_ADDR+0x700)
+
+#define SHGLCORE_LATCH_BIT(x)	BYTE_REF(SHGLCORE_LATCH_ADDR+x)
+
+#define SHGLCORE_LATCH_STATUS_LED	0
+#define SHGLCORE_LATCH_ERROR_LED	1
+#define SHGLCORE_LATCH_ALARM_LED	2
+
+#define SHGLCORE_LATCH_1865		4
+
+#define SHGLCORE_LATCH_RELAY_1		6
+#define SHGLCORE_LATCH_RELAY_2		7
+
+#endif /* SHGLCORE */
+
+#endif /* _M68K_SHGLCORE_H */
diff -Nru a/include/asm-m68knommu/shglports.h b/include/asm-m68knommu/shglports.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/shglports.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,76 @@
+
+/* Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *         1997, 1998  D. Jeff Dionne <jeff@lineo.ca>,
+ */
+
+#ifndef _M68K_SHGLPORTS_H
+#define _M68K_SHGLPORTS_H
+
+#include <linux/config.h>
+#include <linux/sched.h>
+
+#ifdef CONFIG_SHGLCORE
+
+extern struct semaphore porte_interlock;
+
+struct SHGLCORE_PORT_QS { 
+  unsigned char
+  nullqs:1, /* COM1TX */ 
+  sbin:1,   /* PQS6 (PCS3) */
+  sbclk:1,  /* PQS5 (PCS2) */
+  sbout:1,  /* PQS4 (PCS1) */
+  null4:4;  /* MISO, MOSI, SCLK, /SS=PCS0 */
+};
+
+#define PORT_QS ((volatile struct SHGLCORE_PORT_QS*)PORTQS_ADDR)
+
+struct SHGLCORE_PORT_E {
+  unsigned char
+  dead:1,       /* LED */
+  sbirigb:1,    /* PE6 */
+  ds:1,         /* /DS */
+  nulle1:1,     /* na */ 
+  sbpll:1,      /* PE3 */
+  avec:1,       /* /AVEC */
+  sbsrom:1,     /* PE1 */
+  sbpanel:1;    /* PE0 */
+};
+
+#define PORT_E ((volatile struct SHGLCORE_PORT_E*)PORTE_ADDR)
+
+struct SHGLCORE_PORT_F {
+  unsigned char
+  nullf1:4,
+  nullf2:4;
+};
+
+#define PORT_F ((volatile struct SHGLCORE_PORT_F*)PORTF_ADDR)
+
+extern int comm_status_led, comm_error_led, alarm_led;
+
+static inline void SET_COMM_STATUS_LED(int value) {
+	BYTE_REF(SHGLCORE_ACC_ADDR+0x100+0) = comm_status_led = value;
+}
+static inline int GET_COMM_STATUS_LED(void) {
+	return comm_status_led;
+}
+
+
+static inline void SET_COMM_ERROR_LED(int value) {
+	BYTE_REF(SHGLCORE_ACC_ADDR+0x100+1) = comm_error_led = value;
+}
+static inline int GET_COMM_ERROR_LED(void) {
+	return comm_error_led;
+}
+
+
+static inline void SET_ALARM_LED(int value) {
+	BYTE_REF(SHGLCORE_ACC_ADDR+0x100+2) = alarm_led = value;
+}
+static inline int GET_ALARM_LED(void) {
+	return alarm_led;
+}
+
+#endif
+
+#endif /* _M68K_SHGLPORTS_H */
diff -Nru a/include/asm-m68knommu/shm.h b/include/asm-m68knommu/shm.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/shm.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/shm.h>
diff -Nru a/include/asm-m68knommu/shmbuf.h b/include/asm-m68knommu/shmbuf.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/shmbuf.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/shmbuf.h>
diff -Nru a/include/asm-m68knommu/shmparam.h b/include/asm-m68knommu/shmparam.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/shmparam.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/shmparam.h>
diff -Nru a/include/asm-m68knommu/sigcontext.h b/include/asm-m68knommu/sigcontext.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/sigcontext.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,16 @@
+#ifndef _ASM_M68KNOMMU_SIGCONTEXT_H
+#define _ASM_M68KNOMMU_SIGCONTEXT_H
+
+struct sigcontext {
+	unsigned long  sc_mask; 	/* old sigmask */
+	unsigned long  sc_usp;		/* old user stack pointer */
+	unsigned long  sc_d0;
+	unsigned long  sc_d1;
+	unsigned long  sc_a0;
+	unsigned long  sc_a1;
+	unsigned short sc_sr;
+	unsigned long  sc_pc;
+	unsigned short sc_formatvec;
+};
+
+#endif
diff -Nru a/include/asm-m68knommu/siginfo.h b/include/asm-m68knommu/siginfo.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/siginfo.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1 @@
+#include <asm-m68k/siginfo.h>
diff -Nru a/include/asm-m68knommu/signal.h b/include/asm-m68knommu/signal.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/signal.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,181 @@
+#ifndef _M68KNOMMU_SIGNAL_H
+#define _M68KNOMMU_SIGNAL_H
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+
+#ifdef __KERNEL__
+/* Most things should be clean enough to redefine this at will, if care
+   is taken to make libc match.  */
+
+#define _NSIG		64
+#define _NSIG_BPW	32
+#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t;		/* at least 32 bits */
+
+typedef struct {
+	unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+#define NSIG		32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+#define SIGBUS		 7
+#define SIGFPE		 8
+#define SIGKILL		 9
+#define SIGUSR1		10
+#define SIGSEGV		11
+#define SIGUSR2		12
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGSTKFLT	16
+#define SIGCHLD		17
+#define SIGCONT		18
+#define SIGSTOP		19
+#define SIGTSTP		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGURG		23
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGIO		29
+#define SIGPOLL		SIGIO
+/*
+#define SIGLOST		29
+*/
+#define SIGPWR		30
+#define SIGSYS		31
+#define	SIGUNUSED	31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN	32
+#define SIGRTMAX	(_NSIG-1)
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP	0x00000001
+#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_SIGINFO	0x00000004
+#define SA_ONSTACK	0x08000000
+#define SA_RESTART	0x10000000
+#define SA_NODEFER	0x40000000
+#define SA_RESETHAND	0x80000000
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+#define SA_INTERRUPT	0x20000000 /* dummy -- ignored */
+
+/* 
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	2048
+#define SIGSTKSZ	8192
+
+#ifdef __KERNEL__
+/*
+ * These values of sa_flags are used only by the kernel as part of the
+ * irq handling routines.
+ *
+ * SA_INTERRUPT is also used by the irq handling routines.
+ * SA_SHIRQ is for shared interrupt support on PCI and EISA.
+ */
+#define SA_PROBE		SA_ONESHOT
+#define SA_SAMPLE_RANDOM	SA_RESTART
+#define SA_SHIRQ		0x04000000
+#endif
+
+#define SIG_BLOCK          0	/* for blocking signals */
+#define SIG_UNBLOCK        1	/* for unblocking signals */
+#define SIG_SETMASK        2	/* for setting the signal mask */
+
+/* Type of a signal handler.  */
+typedef void (*__sighandler_t)(int);
+
+#define SIG_DFL	((__sighandler_t)0)	/* default signal handling */
+#define SIG_IGN	((__sighandler_t)1)	/* ignore signal */
+#define SIG_ERR	((__sighandler_t)-1)	/* error return from signal */
+
+#ifdef __KERNEL__
+struct old_sigaction {
+	__sighandler_t sa_handler;
+	old_sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+struct sigaction {
+	__sighandler_t sa_handler;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+	sigset_t sa_mask;		/* mask last for extensibility */
+};
+
+struct k_sigaction {
+	struct sigaction sa;
+};
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+struct sigaction {
+	union {
+	  __sighandler_t _sa_handler;
+	  void (*_sa_sigaction)(int, struct siginfo *, void *);
+	} _u;
+	sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+#define sa_handler	_u._sa_handler
+#define sa_sigaction	_u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+} stack_t;
+
+#ifdef __KERNEL__
+
+#include <asm/sigcontext.h>
+#undef __HAVE_ARCH_SIG_BITOPS
+
+#endif /* __KERNEL__ */
+
+#endif /* _M68KNOMMU_SIGNAL_H */
diff -Nru a/include/asm-m68knommu/smp.h b/include/asm-m68knommu/smp.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/smp.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+/* nothing required here yet */
diff -Nru a/include/asm-m68knommu/socket.h b/include/asm-m68knommu/socket.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/socket.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1 @@
+#include <asm-m68k/socket.h>
diff -Nru a/include/asm-m68knommu/sockios.h b/include/asm-m68knommu/sockios.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/sockios.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/sockios.h>
diff -Nru a/include/asm-m68knommu/softirq.h b/include/asm-m68knommu/softirq.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/softirq.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,20 @@
+#ifndef __ASM_SOFTIRQ_H
+#define __ASM_SOFTIRQ_H
+
+#include <linux/preempt.h>
+#include <asm/hardirq.h>
+
+#define local_bh_disable() \
+		do { preempt_count() += SOFTIRQ_OFFSET; barrier(); } while (0)
+#define __local_bh_enable() \
+		do { barrier(); preempt_count() -= SOFTIRQ_OFFSET; } while (0)
+
+#define local_bh_enable()						\
+do {									\
+	__local_bh_enable();						\
+	if (unlikely(!in_interrupt() && softirq_pending(smp_processor_id()))) \
+		do_softirq();						\
+	preempt_check_resched();					\
+} while (0)
+
+#endif	/* __ASM_SOFTIRQ_H */
diff -Nru a/include/asm-m68knommu/spinlock.h b/include/asm-m68knommu/spinlock.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/spinlock.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/spinlock.h>
diff -Nru a/include/asm-m68knommu/stat.h b/include/asm-m68knommu/stat.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/stat.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/stat.h>
diff -Nru a/include/asm-m68knommu/statfs.h b/include/asm-m68knommu/statfs.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/statfs.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/statfs.h>
diff -Nru a/include/asm-m68knommu/string.h b/include/asm-m68knommu/string.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/string.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,126 @@
+#ifndef _M68KNOMMU_STRING_H_
+#define _M68KNOMMU_STRING_H_
+
+#ifdef __KERNEL__ /* only set these up for kernel code */
+
+#include <asm/setup.h>
+#include <asm/page.h>
+
+#define __HAVE_ARCH_STRCPY
+static inline char * strcpy(char * dest,const char *src)
+{
+  char *xdest = dest;
+
+  __asm__ __volatile__
+       ("1:\tmoveb %1@+,%0@+\n\t"
+        "jne 1b"
+	: "=a" (dest), "=a" (src)
+        : "0" (dest), "1" (src) : "memory");
+  return xdest;
+}
+
+#define __HAVE_ARCH_STRNCPY
+static inline char * strncpy(char *dest, const char *src, size_t n)
+{
+  char *xdest = dest;
+
+  if (n == 0)
+    return xdest;
+
+  __asm__ __volatile__
+       ("1:\tmoveb %1@+,%0@+\n\t"
+	"jeq 2f\n\t"
+        "subql #1,%2\n\t"
+        "jne 1b\n\t"
+        "2:"
+        : "=a" (dest), "=a" (src), "=d" (n)
+        : "0" (dest), "1" (src), "2" (n)
+        : "memory");
+  return xdest;
+}
+
+
+#ifndef CONFIG_COLDFIRE
+
+#define __HAVE_ARCH_STRCMP
+static inline int strcmp(const char * cs,const char * ct)
+{
+  char __res;
+
+  __asm__
+       ("1:\tmoveb %0@+,%2\n\t" /* get *cs */
+        "cmpb %1@+,%2\n\t"      /* compare a byte */
+        "jne  2f\n\t"           /* not equal, break out */
+        "tstb %2\n\t"           /* at end of cs? */
+        "jne  1b\n\t"           /* no, keep going */
+        "jra  3f\n\t"		/* strings are equal */
+        "2:\tsubb %1@-,%2\n\t"  /* *cs - *ct */
+        "3:"
+        : "=a" (cs), "=a" (ct), "=d" (__res)
+        : "0" (cs), "1" (ct));
+
+  return __res;
+}
+
+#define __HAVE_ARCH_STRNCMP
+static inline int strncmp(const char * cs,const char * ct,size_t count)
+{
+  char __res;
+
+  if (!count)
+    return 0;
+  __asm__
+       ("1:\tmovb %0@+,%3\n\t"          /* get *cs */
+        "cmpb   %1@+,%3\n\t"            /* compare a byte */
+        "jne    3f\n\t"                 /* not equal, break out */
+        "tstb   %3\n\t"                 /* at end of cs? */
+        "jeq    4f\n\t"                 /* yes, all done */
+        "subql  #1,%2\n\t"              /* no, adjust count */
+        "jne    1b\n\t"                 /* more to do, keep going */
+        "2:\tmoveq #0,%3\n\t"           /* strings are equal */
+        "jra    4f\n\t"
+        "3:\tsubb %1@-,%3\n\t"          /* *cs - *ct */
+        "4:"
+        : "=a" (cs), "=a" (ct), "=d" (count), "=d" (__res)
+        : "0" (cs), "1" (ct), "2" (count));
+  return __res;
+}
+
+#endif /* CONFIG_COLDFIRE */
+
+#define __HAVE_ARCH_MEMSET
+extern void * memset(void * s, int c, size_t count);
+
+#define __HAVE_ARCH_MEMCPY
+extern void * memcpy(void *d, const void *s, size_t count);
+
+#else /* KERNEL */
+
+/*
+ *	let user libraries deal with these,
+ *	IMHO the kernel has no place defining these functions for user apps
+ */
+
+#define __HAVE_ARCH_STRCPY 1
+#define __HAVE_ARCH_STRNCPY 1
+#define __HAVE_ARCH_STRCAT 1
+#define __HAVE_ARCH_STRNCAT 1
+#define __HAVE_ARCH_STRCMP 1
+#define __HAVE_ARCH_STRNCMP 1
+#define __HAVE_ARCH_STRNICMP 1
+#define __HAVE_ARCH_STRCHR 1
+#define __HAVE_ARCH_STRRCHR 1
+#define __HAVE_ARCH_STRSTR 1
+#define __HAVE_ARCH_STRLEN 1
+#define __HAVE_ARCH_STRNLEN 1
+#define __HAVE_ARCH_MEMSET 1
+#define __HAVE_ARCH_MEMCPY 1
+#define __HAVE_ARCH_MEMMOVE 1
+#define __HAVE_ARCH_MEMSCAN 1
+#define __HAVE_ARCH_MEMCMP 1
+#define __HAVE_ARCH_MEMCHR 1
+#define __HAVE_ARCH_STRTOK 1
+
+#endif /* KERNEL */
+
+#endif /* _M68K_STRING_H_ */
diff -Nru a/include/asm-m68knommu/system.h b/include/asm-m68knommu/system.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/system.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,270 @@
+#ifndef _M68KNOMMU_SYSTEM_H
+#define _M68KNOMMU_SYSTEM_H
+
+#include <linux/config.h> /* get configuration macros */
+#include <linux/linkage.h>
+#include <asm/segment.h>
+#include <asm/entry.h>
+
+/*
+ * switch_to(n) should switch tasks to task ptr, first checking that
+ * ptr isn't the current task, in which case it does nothing.  This
+ * also clears the TS-flag if the task we switched to has used the
+ * math co-processor latest.
+ */
+/*
+ * switch_to() saves the extra registers, that are not saved
+ * automatically by SAVE_SWITCH_STACK in resume(), ie. d0-d5 and
+ * a0-a1. Some of these are used by schedule() and its predecessors
+ * and so we might get see unexpected behaviors when a task returns
+ * with unexpected register values.
+ *
+ * syscall stores these registers itself and none of them are used
+ * by syscall after the function in the syscall has been called.
+ *
+ * Beware that resume now expects *next to be in d1 and the offset of
+ * tss to be in a1. This saves a few instructions as we no longer have
+ * to push them onto the stack and read them back right after.
+ *
+ * 02/17/96 - Jes Sorensen (jds@kom.auc.dk)
+ *
+ * Changed 96/09/19 by Andreas Schwab
+ * pass prev in a0, next in a1, offset of tss in d1, and whether
+ * the mm structures are shared in d2 (to avoid atc flushing).
+ */
+asmlinkage void resume(void);
+#define switch_to(prev,next,last)				\
+{								\
+  void *_last;							\
+  __asm__ __volatile__(						\
+  	"movel	%1, %%a0\n\t"					\
+	"movel	%2, %%a1\n\t"					\
+	"jbsr resume\n\t"					\
+	"movel	%%d1, %0\n\t"					\
+       : "=d" (_last)						\
+       : "d" (prev), "d" (next)					\
+       : "cc", "d0", "d1", "d2", "d3", "d4", "d5", "a0", "a1");	\
+  (last) = _last;						\
+}
+
+#ifdef CONFIG_COLDFIRE
+#define local_irq_enable() __asm__ __volatile__ (		\
+	"move %/sr,%%d0\n\t"					\
+	"andi.l #0xf8ff,%%d0\n\t"				\
+	"move %%d0,%/sr\n"					\
+	: /* no outputs */					\
+	:							\
+        : "cc", "%d0", "memory")
+#define local_irq_disable() __asm__ __volatile__ (		\
+	"move %/sr,%%d0\n\t"					\
+	"ori.l  #0x0700,%%d0\n\t"				\
+	"move %%d0,%/sr\n"					\
+	: /* no inputs */					\
+	:							\
+	: "cc", "%d0", "memory")
+#else
+
+/* portable version */ /* FIXME - see entry.h*/
+#define ALLOWINT 0xf8ff
+
+#define local_irq_enable() asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory")
+#define local_irq_disable() asm volatile ("oriw  #0x0700,%%sr": : : "memory")
+#endif
+
+#define local_save_flags(x) asm volatile ("movew %%sr,%0":"=d" (x) : : "memory")
+#define local_irq_restore(x) asm volatile ("movew %0,%%sr": :"d" (x) : "memory")
+
+/* For spinlocks etc */
+#define local_irq_save(x) do { local_save_flags(x); local_irq_disable(); } while (0)
+
+#define	irqs_disabled()			\
+({					\
+	unsigned long flags;		\
+	local_save_flags(flags);	\
+	((flags & 0x0700) == 0x0700);	\
+})
+
+#define iret() __asm__ __volatile__ ("rte": : :"memory", "sp", "cc")
+
+/*
+ * Force strict CPU ordering.
+ * Not really required on m68k...
+ */
+#define nop()  asm volatile ("nop"::)
+#define mb()   asm volatile (""   : : :"memory")
+#define rmb()  asm volatile (""   : : :"memory")
+#define wmb()  asm volatile (""   : : :"memory")
+#define set_rmb(var, value)    do { xchg(&var, value); } while (0)
+#define set_mb(var, value)     set_rmb(var, value)
+#define set_wmb(var, value)    do { var = value; wmb(); } while (0)
+
+#ifdef CONFIG_SMP
+#define smp_mb()	mb()
+#define smp_rmb()	rmb()
+#define smp_wmb()	wmb()
+#else
+#define smp_mb()	barrier()
+#define smp_rmb()	barrier()
+#define smp_wmb()	barrier()
+#endif
+
+#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+#define tas(ptr) (xchg((ptr),1))
+
+struct __xchg_dummy { unsigned long a[100]; };
+#define __xg(x) ((volatile struct __xchg_dummy *)(x))
+
+#ifndef CONFIG_RMW_INSNS
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+{
+  unsigned long tmp, flags;
+
+  local_irq_save(flags);
+
+  switch (size) {
+  case 1:
+    __asm__ __volatile__
+    ("moveb %2,%0\n\t"
+     "moveb %1,%2"
+    : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
+    break;
+  case 2:
+    __asm__ __volatile__
+    ("movew %2,%0\n\t"
+     "movew %1,%2"
+    : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
+    break;
+  case 4:
+    __asm__ __volatile__
+    ("movel %2,%0\n\t"
+     "movel %1,%2"
+    : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
+    break;
+  }
+  local_irq_restore(flags);
+  return tmp;
+}
+#else
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+{
+	switch (size) {
+	    case 1:
+		__asm__ __volatile__
+			("moveb %2,%0\n\t"
+			 "1:\n\t"
+			 "casb %0,%1,%2\n\t"
+			 "jne 1b"
+			 : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory");
+		break;
+	    case 2:
+		__asm__ __volatile__
+			("movew %2,%0\n\t"
+			 "1:\n\t"
+			 "casw %0,%1,%2\n\t"
+			 "jne 1b"
+			 : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory");
+		break;
+	    case 4:
+		__asm__ __volatile__
+			("movel %2,%0\n\t"
+			 "1:\n\t"
+			 "casl %0,%1,%2\n\t"
+			 "jne 1b"
+			 : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory");
+		break;
+	}
+	return x;
+}
+#endif
+
+/*
+ * Atomic compare and exchange.  Compare OLD with MEM, if identical,
+ * store NEW in MEM.  Return the initial value in MEM.  Success is
+ * indicated by comparing RETURN with OLD.
+ */
+#define __HAVE_ARCH_CMPXCHG	1
+
+static __inline__ unsigned long
+cmpxchg(volatile int *p, int old, int new)
+{
+	unsigned long flags;
+	int prev;
+
+	local_irq_save(flags);
+	if ((prev = *p) == old)
+		*p = new;
+	local_irq_restore(flags);
+	return(prev);
+}
+
+
+#ifdef CONFIG_M68332
+#define HARD_RESET_NOW() ({		\
+        local_irq_disable();		\
+        asm("				\
+	movew   #0x0000, 0xfffa6a;	\
+        reset;				\
+        /*movew #0x1557, 0xfffa44;*/	\
+        /*movew #0x0155, 0xfffa46;*/	\
+        moveal #0, %a0;			\
+        movec %a0, %vbr;		\
+        moveal 0, %sp;			\
+        moveal 4, %a0;			\
+        jmp (%a0);			\
+        ");				\
+})
+#endif
+
+#if defined( CONFIG_M68328 ) || defined( CONFIG_M68EZ328 ) || \
+	defined (CONFIG_M68360) || defined( CONFIG_M68VZ328 )
+#define HARD_RESET_NOW() ({		\
+        local_irq_disable();		\
+        asm("				\
+        moveal #0x10c00000, %a0;	\
+        moveb #0, 0xFFFFF300;		\
+        moveal 0(%a0), %sp;		\
+        moveal 4(%a0), %a0;		\
+        jmp (%a0);			\
+        ");				\
+})
+#endif
+
+#ifdef CONFIG_COLDFIRE
+#if defined(CONFIG_M5272) && defined(CONFIG_NETtel)
+/*
+ *	Need to account for broken early mask of 5272 silicon. So don't
+ *	jump through the original start address. Jump strait into the
+ *	known start of the FLASH code.
+ */
+#define HARD_RESET_NOW() ({		\
+        asm("				\
+	movew #0x2700, %sr;		\
+        jmp 0xf0000400;			\
+        ");				\
+})
+#elif defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3) || defined(CONFIG_CLEOPATRA)
+#define HARD_RESET_NOW() ({		\
+        asm("				\
+	movew #0x2700, %sr;		\
+	moveal #0x10000044, %a0;	\
+	movel #0xffffffff, (%a0);	\
+	moveal #0x10000001, %a0;	\
+	moveb #0x00, (%a0);		\
+        moveal #0xf0000004, %a0;	\
+        moveal (%a0), %a0;		\
+        jmp (%a0);			\
+        ");				\
+})
+#else
+#define HARD_RESET_NOW() ({		\
+        asm("				\
+	movew #0x2700, %sr;		\
+        moveal #0x4, %a0;		\
+        moveal (%a0), %a0;		\
+        jmp (%a0);			\
+        ");				\
+})
+#endif
+#endif
+
+#endif /* _M68KNOMMU_SYSTEM_H */
diff -Nru a/include/asm-m68knommu/termbits.h b/include/asm-m68knommu/termbits.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/termbits.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/termbits.h>
diff -Nru a/include/asm-m68knommu/termios.h b/include/asm-m68knommu/termios.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/termios.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/termios.h>
diff -Nru a/include/asm-m68knommu/thread_info.h b/include/asm-m68knommu/thread_info.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/thread_info.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,100 @@
+/* thread_info.h: m68knommu low-level thread information
+ * adapted from the i386 and PPC versions by Greg Ungerer (gerg@snapgear.com)
+ *
+ * Copyright (C) 2002  David Howells (dhowells@redhat.com)
+ * - Incorporating suggestions made by Linus Torvalds and Dave Miller
+ */
+
+#ifndef _ASM_THREAD_INFO_H
+#define _ASM_THREAD_INFO_H
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+/*
+ * low level task data.
+ * If you change this, change the TI_* offsets below to match.
+ */
+struct thread_info {
+	struct task_struct *task;		/* main task structure */
+	struct exec_domain *exec_domain;	/* execution domain */
+	unsigned long	   flags;		/* low level flags */
+	int		   cpu;			/* cpu we're on */
+	int		   preempt_count;	/* 0 => preemptable, <0 => BUG*/
+};
+
+/*
+ * macros/functions for gaining access to the thread information structure
+ */
+#define INIT_THREAD_INFO(tsk)			\
+{						\
+	task:		&tsk,			\
+	exec_domain:	&default_exec_domain,	\
+	flags:		0,			\
+	cpu:		0,			\
+}
+
+#define init_thread_info	(init_thread_union.thread_info)
+#define init_stack		(init_thread_union.stack)
+
+
+/*
+ * Size of kernel stack for each process. This must be a power of 2...
+ */
+#define THREAD_SIZE		8192	/* 2 pages */
+
+
+/* how to get the thread information struct from C */
+static inline struct thread_info *current_thread_info(void)
+{
+	struct thread_info *ti;
+	__asm__(
+		"move.l	%%sp, %0 \n\t"
+		"and.l	%1, %0"
+		: "=&d"(ti)
+		: "d" (~(THREAD_SIZE-1))
+		);
+	return ti;
+}
+
+/* thread information allocation */
+#define alloc_thread_info() ((struct thread_info *) \
+				__get_free_pages(GFP_KERNEL, 1))
+#define free_thread_info(ti)	free_pages((unsigned long) (ti), 1)
+#define get_thread_info(ti)	get_task_struct((ti)->task)
+#define put_thread_info(ti)	put_task_struct((ti)->task)
+#endif /* __ASSEMBLY__ */
+
+/*
+ * Offsets in thread_info structure, used in assembly code
+ */
+#define TI_TASK		0
+#define TI_EXECDOMAIN	4
+#define TI_FLAGS	8
+#define TI_CPU		12
+
+#define	PREEMPT_ACTIVE	0x4000000
+
+/*
+ * thread information flag bit numbers
+ */
+#define TIF_SYSCALL_TRACE	0	/* syscall trace active */
+#define TIF_NOTIFY_RESUME	1	/* resumption notification requested */
+#define TIF_SIGPENDING		2	/* signal pending */
+#define TIF_NEED_RESCHED	3	/* rescheduling necessary */
+#define TIF_POLLING_NRFLAG	4	/* true if poll_idle() is polling
+					   TIF_NEED_RESCHED */
+
+/* as above, but as bit values */
+#define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
+#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
+#define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
+#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
+
+#define _TIF_WORK_MASK		0x0000FFFE	/* work to do on interrupt/exception return */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_THREAD_INFO_H */
diff -Nru a/include/asm-m68knommu/timex.h b/include/asm-m68knommu/timex.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/timex.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1 @@
+#include <asm-m68k/timex.h>
diff -Nru a/include/asm-m68knommu/tlb.h b/include/asm-m68knommu/tlb.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/tlb.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/tlb.h>
diff -Nru a/include/asm-m68knommu/tlbflush.h b/include/asm-m68knommu/tlbflush.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/tlbflush.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,61 @@
+#ifndef _M68KNOMMU_TLBFLUSH_H
+#define _M68KNOMMU_TLBFLUSH_H
+
+/*
+ * Copyright (C) 2000 Lineo, David McCullough <davidm@uclinux.org>
+ * Copyright (C) 2000-2002, Greg Ungerer <gerg@snapgear.com>
+ */
+
+#include <asm/setup.h>
+
+/*
+ * flush all user-space atc entries.
+ */
+static inline void __flush_tlb(void)
+{
+	BUG();
+}
+
+static inline void __flush_tlb_one(unsigned long addr)
+{
+	BUG();
+}
+
+#define flush_tlb() __flush_tlb()
+
+/*
+ * flush all atc entries (both kernel and user-space entries).
+ */
+static inline void flush_tlb_all(void)
+{
+	BUG();
+}
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+	BUG();
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
+{
+	BUG();
+}
+
+static inline void flush_tlb_range(struct mm_struct *mm,
+				   unsigned long start, unsigned long end)
+{
+	BUG();
+}
+
+extern inline void flush_tlb_kernel_page(unsigned long addr)
+{
+	BUG();
+}
+
+extern inline void flush_tlb_pgtables(struct mm_struct *mm,
+				      unsigned long start, unsigned long end)
+{
+	BUG();
+}
+
+#endif /* _M68KNOMMU_TLBFLUSH_H */
diff -Nru a/include/asm-m68knommu/topology.h b/include/asm-m68knommu/topology.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/topology.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,6 @@
+#ifndef _ASM_M68K_TOPOLOGY_H
+#define _ASM_M68K_TOPOLOGY_H
+
+#include <asm-generic/topology.h>
+
+#endif /* _ASM_M68K_TOPOLOGY_H */
diff -Nru a/include/asm-m68knommu/traps.h b/include/asm-m68knommu/traps.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/traps.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,150 @@
+/*
+ *  linux/include/asm/traps.h
+ *
+ *  Copyright (C) 1993        Hamish Macdonald
+ *
+ * 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.
+ */
+
+#ifndef _M68KNOMMU_TRAPS_H
+#define _M68KNOMMU_TRAPS_H
+
+#ifndef __ASSEMBLY__
+
+typedef void (*e_vector)(void);
+
+extern e_vector vectors[];
+
+#endif
+
+#define VEC_BUSERR  (2)
+#define VEC_ADDRERR (3)
+#define VEC_ILLEGAL (4)
+#define VEC_ZERODIV (5)
+#define VEC_CHK     (6)
+#define VEC_TRAP    (7)
+#define VEC_PRIV    (8)
+#define VEC_TRACE   (9)
+#define VEC_LINE10  (10)
+#define VEC_LINE11  (11)
+#define VEC_RESV1   (12)
+#define VEC_COPROC  (13)
+#define VEC_FORMAT  (14)
+#define VEC_UNINT   (15)
+#define VEC_SPUR    (24)
+#define VEC_INT1    (25)
+#define VEC_INT2    (26)
+#define VEC_INT3    (27)
+#define VEC_INT4    (28)
+#define VEC_INT5    (29)
+#define VEC_INT6    (30)
+#define VEC_INT7    (31)
+#define VEC_SYS     (32)
+#define VEC_TRAP1   (33)
+#define VEC_TRAP2   (34)
+#define VEC_TRAP3   (35)
+#define VEC_TRAP4   (36)
+#define VEC_TRAP5   (37)
+#define VEC_TRAP6   (38)
+#define VEC_TRAP7   (39)
+#define VEC_TRAP8   (40)
+#define VEC_TRAP9   (41)
+#define VEC_TRAP10  (42)
+#define VEC_TRAP11  (43)
+#define VEC_TRAP12  (44)
+#define VEC_TRAP13  (45)
+#define VEC_TRAP14  (46)
+#define VEC_TRAP15  (47)
+#define VEC_FPBRUC  (48)
+#define VEC_FPIR    (49)
+#define VEC_FPDIVZ  (50)
+#define VEC_FPUNDER (51)
+#define VEC_FPOE    (52)
+#define VEC_FPOVER  (53)
+#define VEC_FPNAN   (54)
+#define VEC_FPUNSUP (55)
+#define	VEC_UNIMPEA (60)
+#define	VEC_UNIMPII (61)
+#define VEC_USER    (64)
+
+#define VECOFF(vec) ((vec)<<2)
+
+#ifndef __ASSEMBLY__
+
+/* Status register bits */
+#define PS_T  (0x8000)
+#define PS_S  (0x2000)
+#define PS_M  (0x1000)
+#define PS_C  (0x0001)
+
+/* structure for stack frames */
+
+struct frame {
+    struct pt_regs ptregs;
+    union {
+	    struct {
+		    unsigned long  iaddr;    /* instruction address */
+	    } fmt2;
+	    struct {
+		    unsigned long  effaddr;  /* effective address */
+	    } fmt3;
+	    struct {
+		    unsigned long  effaddr;  /* effective address */
+		    unsigned long  pc;	     /* pc of faulted instr */
+	    } fmt4;
+	    struct {
+		    unsigned long  effaddr;  /* effective address */
+		    unsigned short ssw;      /* special status word */
+		    unsigned short wb3s;     /* write back 3 status */
+		    unsigned short wb2s;     /* write back 2 status */
+		    unsigned short wb1s;     /* write back 1 status */
+		    unsigned long  faddr;    /* fault address */
+		    unsigned long  wb3a;     /* write back 3 address */
+		    unsigned long  wb3d;     /* write back 3 data */
+		    unsigned long  wb2a;     /* write back 2 address */
+		    unsigned long  wb2d;     /* write back 2 data */
+		    unsigned long  wb1a;     /* write back 1 address */
+		    unsigned long  wb1dpd0;  /* write back 1 data/push data 0*/
+		    unsigned long  pd1;      /* push data 1*/
+		    unsigned long  pd2;      /* push data 2*/
+		    unsigned long  pd3;      /* push data 3*/
+	    } fmt7;
+	    struct {
+		    unsigned long  iaddr;    /* instruction address */
+		    unsigned short int1[4];  /* internal registers */
+	    } fmt9;
+	    struct {
+		    unsigned short int1;
+		    unsigned short ssw;      /* special status word */
+		    unsigned short isc;      /* instruction stage c */
+		    unsigned short isb;      /* instruction stage b */
+		    unsigned long  daddr;    /* data cycle fault address */
+		    unsigned short int2[2];
+		    unsigned long  dobuf;    /* data cycle output buffer */
+		    unsigned short int3[2];
+	    } fmta;
+	    struct {
+		    unsigned short int1;
+		    unsigned short ssw;     /* special status word */
+		    unsigned short isc;     /* instruction stage c */
+		    unsigned short isb;     /* instruction stage b */
+		    unsigned long  daddr;   /* data cycle fault address */
+		    unsigned short int2[2];
+		    unsigned long  dobuf;   /* data cycle output buffer */
+		    unsigned short int3[4];
+		    unsigned long  baddr;   /* stage B address */
+		    unsigned short int4[2];
+		    unsigned long  dibuf;   /* data cycle input buffer */
+		    unsigned short int5[3];
+		    unsigned	   ver : 4; /* stack frame version # */
+		    unsigned	   int6:12;
+		    unsigned short int7[18];
+	    } fmtb;
+    } un;
+};
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _M68KNOMMU_TRAPS_H */
diff -Nru a/include/asm-m68knommu/types.h b/include/asm-m68knommu/types.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/types.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,58 @@
+#ifndef _M68K_TYPES_H
+#define _M68K_TYPES_H
+
+/*
+ * This file is never included by application software unless
+ * explicitly requested (e.g., via linux/types.h) in which case the
+ * application is Linux specific so (user-) name space pollution is
+ * not a major issue.  However, for interoperability, libraries still
+ * need to be careful to avoid a name clashes.
+ */
+
+typedef unsigned short umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+#define BITS_PER_LONG 32
+
+/* Dma addresses are 32-bits wide.  */
+
+typedef u32 dma_addr_t;
+
+#endif /* __KERNEL__ */
+
+#endif /* _M68K_TYPES_H */
diff -Nru a/include/asm-m68knommu/uaccess.h b/include/asm-m68knommu/uaccess.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/uaccess.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,184 @@
+#ifndef __M68KNOMMU_UACCESS_H
+#define __M68KNOMMU_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/segment.h>
+
+#define VERIFY_READ	0
+#define VERIFY_WRITE	1
+
+/* We let the MMU do all checking */
+extern inline int access_ok(int type, const void * addr, unsigned long size)
+{
+#define	RANGE_CHECK_OK(addr, size, lower, upper) \
+	(((addr) >= (lower)) && (((addr) + (size)) < (upper)))
+
+#ifdef CONFIG_COLDFIRE
+	extern unsigned long _ramend;
+	return(RANGE_CHECK_OK((unsigned long) addr, size, 0L, _ramend) ||
+			(is_in_rom((unsigned long) addr) &&
+					is_in_rom((unsigned long) addr + size)));
+#else
+	/* DAVIDM - this could be restricted a lot more */
+	return(RANGE_CHECK_OK((unsigned long)addr, size, 0, 0x10f00000));
+#endif
+}
+
+extern inline int verify_area(int type, const void * addr, unsigned long size)
+{
+	return access_ok(type,addr,size)?0:-EFAULT;
+}
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry
+{
+	unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long);
+
+
+/*
+ * These are the main single-value transfer routines.  They automatically
+ * use the right size if we just have the right pointer type.
+ */
+
+#define put_user(x, ptr)				\
+({							\
+    int __pu_err = 0;					\
+    typeof(*(ptr)) __pu_val = (x);			\
+    switch (sizeof (*(ptr))) {				\
+    case 1:						\
+	__put_user_asm(__pu_err, __pu_val, ptr, b);	\
+	break;						\
+    case 2:						\
+	__put_user_asm(__pu_err, __pu_val, ptr, w);	\
+	break;						\
+    case 4:						\
+	__put_user_asm(__pu_err, __pu_val, ptr, l);	\
+	break;						\
+    case 8:						\
+	memcpy(ptr, &__pu_val, sizeof (*(ptr))); \
+	break;						\
+    default:						\
+	__pu_err = __put_user_bad();			\
+	break;						\
+    }							\
+    __pu_err;						\
+})
+#define __put_user(x, ptr) put_user(x, ptr)
+
+extern int __put_user_bad(void);
+
+/*
+ * Tell gcc we read from memory instead of writing: this is because
+ * we do not write to any memory gcc knows about, so there are no
+ * aliasing issues.
+ */
+
+#define __ptr(x) ((unsigned long *)(x))
+
+#define __put_user_asm(err,x,ptr,bwl)				\
+	__asm__ ("move" #bwl " %0,%1"				\
+		: /* no outputs */						\
+		:"d" (x),"m" (*__ptr(ptr)) : "memory")
+
+#define get_user(x, ptr)					\
+({								\
+    int __gu_err = 0;						\
+    typeof(*(ptr)) __gu_val = 0;				\
+    switch (sizeof(*(ptr))) {					\
+    case 1:							\
+	__get_user_asm(__gu_err, __gu_val, ptr, b, "=d");	\
+	break;							\
+    case 2:							\
+	__get_user_asm(__gu_err, __gu_val, ptr, w, "=r");	\
+	break;							\
+    case 4:							\
+	__get_user_asm(__gu_err, __gu_val, ptr, l, "=r");	\
+	break;							\
+    case 8:							\
+	memcpy(&__gu_val, ptr, sizeof (*(ptr))); \
+	break;							\
+    default:							\
+	__gu_val = 0;						\
+	__gu_err = __get_user_bad();				\
+	break;							\
+    }								\
+    (x) = __gu_val;						\
+    __gu_err;							\
+})
+#define __get_user(x, ptr) get_user(x, ptr)
+
+extern int __get_user_bad(void);
+
+#define __get_user_asm(err,x,ptr,bwl,reg)	\
+	__asm__ ("move" #bwl " %1,%0"			\
+		 : "=d" (x)							\
+		 : "m" (*__ptr(ptr)))
+
+#define copy_from_user(to, from, n)		(memcpy(to, from, n), 0)
+#define copy_to_user(to, from, n)		(memcpy(to, from, n), 0)
+
+#define __copy_from_user(to, from, n) copy_from_user(to, from, n)
+#define __copy_to_user(to, from, n) copy_to_user(to, from, n)
+
+#define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n)) return retval; })
+
+#define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n)) return retval; })
+
+/*
+ * Copy a null terminated string from userspace.
+ */
+
+static inline long
+strncpy_from_user(char *dst, const char *src, long count)
+{
+	char *tmp;
+	strncpy(dst, src, count);
+	for (tmp = dst; *tmp && count > 0; tmp++, count--)
+		;
+	return(tmp - dst); /* DAVIDM should we count a NUL ?  check getname */
+}
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 on exception, a value greater than N if too long
+ */
+static inline long strnlen_user(const char *src, long n)
+{
+	return(strlen(src) + 1); /* DAVIDM make safer */
+}
+
+#define strlen_user(str) strnlen_user(str, 32767)
+
+/*
+ * Zero Userspace
+ */
+
+static inline unsigned long
+clear_user(void *to, unsigned long n)
+{
+	memset(to, 0, n);
+    return(0);
+}
+
+#endif /* _M68KNOMMU_UACCESS_H */
diff -Nru a/include/asm-m68knommu/ucontext.h b/include/asm-m68knommu/ucontext.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/ucontext.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,38 @@
+#ifndef _M68KNOMMU_UCONTEXT_H
+#define _M68KNOMMU_UCONTEXT_H
+
+typedef int greg_t;
+#define NGREG 18
+typedef greg_t gregset_t[NGREG];
+
+#ifdef CONFIG_FPU
+typedef struct fpregset {
+	int f_pcr;
+	int f_psr;
+	int f_fpiaddr;
+	int f_fpregs[8][3];
+} fpregset_t;
+#endif
+
+struct mcontext {
+	int version;
+	gregset_t gregs;
+#ifdef CONFIG_FPU
+	fpregset_t fpregs;
+#endif
+};
+
+#define MCONTEXT_VERSION 2
+
+struct ucontext {
+	unsigned long	  uc_flags;
+	struct ucontext  *uc_link;
+	stack_t		  uc_stack;
+	struct mcontext	  uc_mcontext;
+#ifdef CONFIG_FPU
+	unsigned long	  uc_filler[80];
+#endif
+	sigset_t	  uc_sigmask;	/* mask last for extensibility */
+};
+
+#endif
diff -Nru a/include/asm-m68knommu/unaligned.h b/include/asm-m68knommu/unaligned.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/unaligned.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,32 @@
+#ifndef __M68K_UNALIGNED_H
+#define __M68K_UNALIGNED_H
+
+#include <linux/config.h>
+
+#ifdef CONFIG_COLDFIRE
+
+/* Use memmove here, so gcc does not insert a __builtin_memcpy. */
+
+#define get_unaligned(ptr) \
+  ({ __typeof__(*(ptr)) __tmp; memmove(&__tmp, (ptr), sizeof(*(ptr))); __tmp; })
+
+#define put_unaligned(val, ptr)				\
+  ({ __typeof__(*(ptr)) __tmp = (val);			\
+     memmove((ptr), &__tmp, sizeof(*(ptr)));		\
+     (void)0; })
+
+#else
+/*
+ * The m68k can do unaligned accesses itself. 
+ *
+ * The strange macros are there to make sure these can't
+ * be misused in a way that makes them not work on other
+ * architectures where unaligned accesses aren't as simple.
+ */
+
+#define get_unaligned(ptr) (*(ptr))
+#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) ))
+
+#endif
+
+#endif
diff -Nru a/include/asm-m68knommu/unistd.h b/include/asm-m68knommu/unistd.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/unistd.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,418 @@
+#ifndef _ASM_M68K_UNISTD_H_
+#define _ASM_M68K_UNISTD_H_
+
+/*
+ * This file contains the system call numbers.
+ */
+
+#define __NR_exit		  1
+#define __NR_fork		  2
+#define __NR_read		  3
+#define __NR_write		  4
+#define __NR_open		  5
+#define __NR_close		  6
+#define __NR_waitpid		  7
+#define __NR_creat		  8
+#define __NR_link		  9
+#define __NR_unlink		 10
+#define __NR_execve		 11
+#define __NR_chdir		 12
+#define __NR_time		 13
+#define __NR_mknod		 14
+#define __NR_chmod		 15
+#define __NR_chown		 16
+#define __NR_break		 17
+#define __NR_oldstat		 18
+#define __NR_lseek		 19
+#define __NR_getpid		 20
+#define __NR_mount		 21
+#define __NR_umount		 22
+#define __NR_setuid		 23
+#define __NR_getuid		 24
+#define __NR_stime		 25
+#define __NR_ptrace		 26
+#define __NR_alarm		 27
+#define __NR_oldfstat		 28
+#define __NR_pause		 29
+#define __NR_utime		 30
+#define __NR_stty		 31
+#define __NR_gtty		 32
+#define __NR_access		 33
+#define __NR_nice		 34
+#define __NR_ftime		 35
+#define __NR_sync		 36
+#define __NR_kill		 37
+#define __NR_rename		 38
+#define __NR_mkdir		 39
+#define __NR_rmdir		 40
+#define __NR_dup		 41
+#define __NR_pipe		 42
+#define __NR_times		 43
+#define __NR_prof		 44
+#define __NR_brk		 45
+#define __NR_setgid		 46
+#define __NR_getgid		 47
+#define __NR_signal		 48
+#define __NR_geteuid		 49
+#define __NR_getegid		 50
+#define __NR_acct		 51
+#define __NR_umount2		 52
+#define __NR_lock		 53
+#define __NR_ioctl		 54
+#define __NR_fcntl		 55
+#define __NR_mpx		 56
+#define __NR_setpgid		 57
+#define __NR_ulimit		 58
+#define __NR_oldolduname	 59
+#define __NR_umask		 60
+#define __NR_chroot		 61
+#define __NR_ustat		 62
+#define __NR_dup2		 63
+#define __NR_getppid		 64
+#define __NR_getpgrp		 65
+#define __NR_setsid		 66
+#define __NR_sigaction		 67
+#define __NR_sgetmask		 68
+#define __NR_ssetmask		 69
+#define __NR_setreuid		 70
+#define __NR_setregid		 71
+#define __NR_sigsuspend		 72
+#define __NR_sigpending		 73
+#define __NR_sethostname	 74
+#define __NR_setrlimit		 75
+#define __NR_old_getrlimit	 76
+#define __NR_getrusage		 77
+#define __NR_gettimeofday	 78
+#define __NR_settimeofday	 79
+#define __NR_getgroups		 80
+#define __NR_setgroups		 81
+#define __NR_select		 82
+#define __NR_symlink		 83
+#define __NR_oldlstat		 84
+#define __NR_readlink		 85
+#define __NR_uselib		 86
+#define __NR_swapon		 87
+#define __NR_reboot		 88
+#define __NR_readdir		 89
+#define __NR_mmap		 90
+#define __NR_munmap		 91
+#define __NR_truncate		 92
+#define __NR_ftruncate		 93
+#define __NR_fchmod		 94
+#define __NR_fchown		 95
+#define __NR_getpriority	 96
+#define __NR_setpriority	 97
+#define __NR_profil		 98
+#define __NR_statfs		 99
+#define __NR_fstatfs		100
+#define __NR_ioperm		101
+#define __NR_socketcall		102
+#define __NR_syslog		103
+#define __NR_setitimer		104
+#define __NR_getitimer		105
+#define __NR_stat		106
+#define __NR_lstat		107
+#define __NR_fstat		108
+#define __NR_olduname		109
+#define __NR_iopl		/* 110 */ not supported
+#define __NR_vhangup		111
+#define __NR_idle		/* 112 */ Obsolete
+#define __NR_vm86		/* 113 */ not supported
+#define __NR_wait4		114
+#define __NR_swapoff		115
+#define __NR_sysinfo		116
+#define __NR_ipc		117
+#define __NR_fsync		118
+#define __NR_sigreturn		119
+#define __NR_clone		120
+#define __NR_setdomainname	121
+#define __NR_uname		122
+#define __NR_cacheflush		123
+#define __NR_adjtimex		124
+#define __NR_mprotect		125
+#define __NR_sigprocmask	126
+#define __NR_create_module	127
+#define __NR_init_module	128
+#define __NR_delete_module	129
+#define __NR_get_kernel_syms	130
+#define __NR_quotactl		131
+#define __NR_getpgid		132
+#define __NR_fchdir		133
+#define __NR_bdflush		134
+#define __NR_sysfs		135
+#define __NR_personality	136
+#define __NR_afs_syscall	137 /* Syscall for Andrew File System */
+#define __NR_setfsuid		138
+#define __NR_setfsgid		139
+#define __NR__llseek		140
+#define __NR_getdents		141
+#define __NR__newselect		142
+#define __NR_flock		143
+#define __NR_msync		144
+#define __NR_readv		145
+#define __NR_writev		146
+#define __NR_getsid		147
+#define __NR_fdatasync		148
+#define __NR__sysctl		149
+#define __NR_mlock		150
+#define __NR_munlock		151
+#define __NR_mlockall		152
+#define __NR_munlockall		153
+#define __NR_sched_setparam		154
+#define __NR_sched_getparam		155
+#define __NR_sched_setscheduler		156
+#define __NR_sched_getscheduler		157
+#define __NR_sched_yield		158
+#define __NR_sched_get_priority_max	159
+#define __NR_sched_get_priority_min	160
+#define __NR_sched_rr_get_interval	161
+#define __NR_nanosleep		162
+#define __NR_mremap		163
+#define __NR_setresuid		164
+#define __NR_getresuid		165
+#define __NR_query_module	167
+#define __NR_poll		168
+#define __NR_nfsservctl		169
+#define __NR_setresgid		170
+#define __NR_getresgid		171
+#define __NR_prctl		172
+#define __NR_rt_sigreturn	173
+#define __NR_rt_sigaction	174
+#define __NR_rt_sigprocmask	175
+#define __NR_rt_sigpending	176
+#define __NR_rt_sigtimedwait	177
+#define __NR_rt_sigqueueinfo	178
+#define __NR_rt_sigsuspend	179
+#define __NR_pread		180
+#define __NR_pwrite		181
+#define __NR_lchown		182
+#define __NR_getcwd		183
+#define __NR_capget		184
+#define __NR_capset		185
+#define __NR_sigaltstack	186
+#define __NR_sendfile		187
+#define __NR_getpmsg		188	/* some people actually want streams */
+#define __NR_putpmsg		189	/* some people actually want streams */
+#define __NR_vfork		190
+#define __NR_getrlimit		191
+#define __NR_mmap2		192
+#define __NR_truncate64		193
+#define __NR_ftruncate64	194
+#define __NR_stat64		195
+#define __NR_lstat64		196
+#define __NR_fstat64		197
+#define __NR_chown32		198
+#define __NR_getuid32		199
+#define __NR_getgid32		200
+#define __NR_geteuid32		201
+#define __NR_getegid32		202
+#define __NR_setreuid32		203
+#define __NR_setregid32		204
+#define __NR_getgroups32	205
+#define __NR_setgroups32	206
+#define __NR_fchown32		207
+#define __NR_setresuid32	208
+#define __NR_getresuid32	209
+#define __NR_setresgid32	210
+#define __NR_getresgid32	211
+#define __NR_lchown32		212
+#define __NR_setuid32		213
+#define __NR_setgid32		214
+#define __NR_setfsuid32		215
+#define __NR_setfsgid32		216
+
+/* user-visible error numbers are in the range -1 - -122: see
+   <asm-m68k/errno.h> */
+
+#define __syscall_return(type, res) \
+do { \
+	if ((unsigned long)(res) >= (unsigned long)(-125)) { \
+	/* avoid using res which is declared to be in register d0; \
+	   errno might expand to a function call and clobber it.  */ \
+		int __err = -(res); \
+		errno = __err; \
+		res = -1; \
+	} \
+	return (type) (res); \
+} while (0)
+
+#define _syscall0(type, name)							\
+type name(void)									\
+{										\
+  long __res;									\
+  __asm__ __volatile__ ("movel	%1, %%d0\n\t"					\
+  			"trap	#0\n\t"						\
+  			"movel	%%d0, %0"					\
+			: "=g" (__res)						\
+			: "i" (__NR_##name)					\
+			: "cc", "%d0");						\
+  if ((unsigned long)(__res) >= (unsigned long)(-125)) {				\
+    errno = -__res;								\
+    __res = -1;									\
+  }										\
+  return (type)__res;								\
+}
+
+#define _syscall1(type, name, atype, a)						\
+type name(atype a)								\
+{										\
+  long __res;									\
+  __asm__ __volatile__ ("movel	%2, %%d1\n\t"					\
+  			"movel	%1, %%d0\n\t"					\
+  			"trap	#0\n\t"						\
+  			"movel	%%d0, %0"					\
+			: "=g" (__res)						\
+			: "i" (__NR_##name),					\
+			  "g" ((long)a)						\
+			: "cc", "%d0", "%d1");					\
+  if ((unsigned long)(__res) >= (unsigned long)(-125)) {				\
+    errno = -__res;								\
+    __res = -1;									\
+  }										\
+  return (type)__res;								\
+}
+
+#define _syscall2(type, name, atype, a, btype, b)				\
+type name(atype a, btype b)							\
+{										\
+  long __res;									\
+  __asm__ __volatile__ ("movel	%3, %%d2\n\t"					\
+  			"movel	%2, %%d1\n\t"					\
+			"movel	%1, %%d0\n\t"					\
+  			"trap	#0\n\t"						\
+  			"movel	%%d0, %0"					\
+			: "=g" (__res)						\
+			: "i" (__NR_##name),					\
+			  "a" ((long)a),					\
+			  "g" ((long)b)						\
+			: "cc", "%d0", "%d1", "%d2");				\
+  if ((unsigned long)(__res) >= (unsigned long)(-125)) {				\
+    errno = -__res;								\
+    __res = -1;									\
+  }										\
+  return (type)__res;								\
+}
+
+#define _syscall3(type, name, atype, a, btype, b, ctype, c)			\
+type name(atype a, btype b, ctype c)						\
+{										\
+  long __res;									\
+  __asm__ __volatile__ ("movel	%4, %%d3\n\t"					\
+			"movel	%3, %%d2\n\t"					\
+  			"movel	%2, %%d1\n\t"					\
+			"movel	%1, %%d0\n\t"					\
+  			"trap	#0\n\t"						\
+  			"movel	%%d0, %0"					\
+			: "=g" (__res)						\
+			: "i" (__NR_##name),					\
+			  "a" ((long)a),					\
+			  "a" ((long)b),					\
+			  "g" ((long)c)						\
+			: "cc", "%d0", "%d1", "%d2", "%d3");			\
+  if ((unsigned long)(__res) >= (unsigned long)(-125)) {				\
+    errno = -__res;								\
+    __res = -1;									\
+  }										\
+  return (type)__res;								\
+}
+
+#define _syscall4(type, name, atype, a, btype, b, ctype, c, dtype, d)		\
+type name(atype a, btype b, ctype c, dtype d)					\
+{										\
+  long __res;									\
+  __asm__ __volatile__ ("movel	%5, %%d4\n\t"					\
+			"movel	%4, %%d3\n\t"					\
+			"movel	%3, %%d2\n\t"					\
+  			"movel	%2, %%d1\n\t"					\
+			"movel	%1, %%d0\n\t"					\
+  			"trap	#0\n\t"						\
+  			"movel	%%d0, %0"					\
+			: "=g" (__res)						\
+			: "i" (__NR_##name),					\
+			  "a" ((long)a),					\
+			  "a" ((long)b),					\
+			  "a" ((long)c),					\
+			  "g" ((long)d)						\
+			: "cc", "%d0", "%d1", "%d2", "%d3",			\
+			  "%d4");						\
+  if ((unsigned long)(__res) >= (unsigned long)(-125)) {				\
+    errno = -__res;								\
+    __res = -1;									\
+  }										\
+  return (type)__res;								\
+}
+
+#define _syscall5(type, name, atype, a, btype, b, ctype, c, dtype, d, etype, e)	\
+type name(atype a, btype b, ctype c, dtype d, etype e)				\
+{										\
+  long __res;									\
+  __asm__ __volatile__ ("movel	%6, %%d5\n\t"					\
+			"movel	%5, %%d4\n\t"					\
+			"movel	%4, %%d3\n\t"					\
+			"movel	%3, %%d2\n\t"					\
+  			"movel	%2, %%d1\n\t"					\
+			"movel	%1, %%d0\n\t"					\
+  			"trap	#0\n\t"						\
+  			"movel	%%d0, %0"					\
+			: "=g" (__res)						\
+			: "i" (__NR_##name),					\
+			  "a" ((long)a),					\
+			  "a" ((long)b),					\
+			  "a" ((long)c),					\
+			  "a" ((long)d),					\
+			  "g" ((long)e)						\
+			: "cc", "%d0", "%d1", "%d2", "%d3",			\
+			  "%d4", "%d5");					\
+  if ((unsigned long)(__res) >= (unsigned long)(-125)) {				\
+    errno = -__res;								\
+    __res = -1;									\
+  }										\
+  return (type)__res;								\
+}
+		
+
+#ifdef __KERNEL_SYSCALLS__
+
+/*
+ * we need this inline - forking from kernel space will result
+ * in NO COPY ON WRITE (!!!), until an execve is executed. This
+ * is no problem, but for the stack. This is handled by not letting
+ * main() use the stack at all after fork(). Thus, no function
+ * calls - which means inline code for fork too, as otherwise we
+ * would use the stack upon exit from 'fork()'.
+ *
+ * Actually only pause and fork are needed inline, so that there
+ * won't be any messing with the stack from main(), but we define
+ * some others too.
+ */
+#define __NR__exit __NR_exit
+static inline _syscall0(int,pause)
+static inline _syscall0(int,sync)
+static inline _syscall0(pid_t,setsid)
+static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
+static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
+static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
+static inline _syscall1(int,dup,int,fd)
+static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
+static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
+static inline _syscall1(int,close,int,fd)
+static inline _syscall1(int,_exit,int,exitcode)
+static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+static inline _syscall1(int,delete_module,const char *,name)
+
+static inline pid_t wait(int * wait_stat)
+{
+	return waitpid(-1,wait_stat,0);
+}
+
+#endif
+
+/*
+ * "Conditional" syscalls
+ *
+ * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
+ * but it doesn't work on all toolchains, so we just do it by hand
+ */
+#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall");
+
+#endif /* _ASM_M68K_UNISTD_H_ */
diff -Nru a/include/asm-m68knommu/user.h b/include/asm-m68knommu/user.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/user.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+#include <asm-m68k/user.h>
diff -Nru a/include/asm-mips/processor.h b/include/asm-mips/processor.h
--- a/include/asm-mips/processor.h	Mon Nov  4 14:31:00 2002
+++ b/include/asm-mips/processor.h	Mon Nov  4 14:31:00 2002
@@ -210,10 +210,6 @@
 
 extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
-/* Copy and release all segment info associated with a VM */
-#define copy_segments(p, mm) do { } while(0)
-#define release_segments(mm) do { } while(0)
-
 /*
  * Return saved PC of a blocked thread.
  */
diff -Nru a/include/asm-mips/ptrace.h b/include/asm-mips/ptrace.h
--- a/include/asm-mips/ptrace.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-mips/ptrace.h	Mon Nov  4 14:31:02 2002
@@ -59,10 +59,7 @@
 /* #define PTRACE_GETFPXREGS		18 */
 /* #define PTRACE_SETFPXREGS		19 */
 
-#define PTRACE_SETOPTIONS	21
-
-/* options set using PTRACE_SETOPTIONS */
-#define PTRACE_O_TRACESYSGOOD	0x00000001
+#define PTRACE_OLDSETOPTIONS	21
 
 #ifdef _LANGUAGE_ASSEMBLY
 #include <asm/offset.h>
diff -Nru a/include/asm-mips64/processor.h b/include/asm-mips64/processor.h
--- a/include/asm-mips64/processor.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-mips64/processor.h	Mon Nov  4 14:31:02 2002
@@ -233,10 +233,6 @@
 
 extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
-/* Copy and release all segment info associated with a VM */
-#define copy_segments(p, mm) do { } while(0)
-#define release_segments(mm) do { } while(0)
-
 /*
  * Return saved PC of a blocked thread.
  */
diff -Nru a/include/asm-mips64/ptrace.h b/include/asm-mips64/ptrace.h
--- a/include/asm-mips64/ptrace.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-mips64/ptrace.h	Mon Nov  4 14:31:02 2002
@@ -64,10 +64,7 @@
 /* #define PTRACE_GETFPXREGS		18 */
 /* #define PTRACE_SETFPXREGS		19 */
 
-#define PTRACE_SETOPTIONS	21
-
-/* options set using PTRACE_SETOPTIONS */
-#define PTRACE_O_TRACESYSGOOD	0x00000001
+#define PTRACE_OLDSETOPTIONS	21
 
 #ifdef _LANGUAGE_ASSEMBLY
 #include <asm/offset.h>
diff -Nru a/include/asm-parisc/dma.h b/include/asm-parisc/dma.h
--- a/include/asm-parisc/dma.h	Mon Nov  4 14:31:03 2002
+++ b/include/asm-parisc/dma.h	Mon Nov  4 14:31:03 2002
@@ -1,4 +1,4 @@
-/* $Id: dma.h,v 1.1 2002/07/20 15:52:25 rhirst Exp $
+/* $Id: dma.h,v 1.2 1999/04/27 00:46:18 deller Exp $
  * linux/include/asm/dma.h: Defines for using and allocating dma channels.
  * Written by Hennus Bergman, 1992.
  * High DMA channel support & info by Hannu Savolainen
@@ -177,11 +177,7 @@
 }
 
 
-
-/* These are in kernel/dma.c: */
-extern int request_dma(unsigned int dmanr, const char * device_id);	/* reserve a DMA channel */
-extern void free_dma(unsigned int dmanr);	/* release it again */
-extern int get_dma_list(char *buf);		/* proc/dma support  */
+#define free_dma(dmanr)
 
 #ifdef CONFIG_PCI
 extern int isa_dma_bridge_buggy;
diff -Nru a/include/asm-parisc/gsc.h b/include/asm-parisc/gsc.h
--- a/include/asm-parisc/gsc.h	Mon Nov  4 14:31:02 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,31 +0,0 @@
-#ifndef ASM_PARISC_GSC_H
-#define ASM_PARISC_GSC_H
-#ifdef __KERNEL__
-
-#include <linux/types.h>
-#include <asm/io.h> /* temporary for __raw_{read,write} */
-
-/* Please, call ioremap and use {read,write}[bwl] instead.  These functions
- * are not very fast.
- */
-#define gsc_readb(x) __raw_readb((unsigned long)x)
-#define gsc_readw(x) __raw_readw((unsigned long)x)
-#define gsc_readl(x) __raw_readl((unsigned long)x)
-#define gsc_writeb(x, y) __raw_writeb(x, (unsigned long)y)
-#define gsc_writew(x, y) __raw_writew(x, (unsigned long)y)
-#define gsc_writel(x, y) __raw_writel(x, (unsigned long)y)
-
-struct gsc_irq {
-	unsigned long txn_addr;	/* IRQ "target" */
-	int txn_data;		/* HW "IRQ" */
-	int irq;		/* virtual IRQ */
-};
-
-/* PA I/O Architected devices support at least 5 bits in the EIM register. */
-#define GSC_EIM_WIDTH 5
-
-extern int gsc_alloc_irq(struct gsc_irq *dev);	/* dev needs an irq */
-extern int gsc_claim_irq(struct gsc_irq *dev, int irq);	/* dev needs this irq */
-
-#endif /* __KERNEL__ */
-#endif /* LINUX_GSC_H */
diff -Nru a/include/asm-parisc/io.h b/include/asm-parisc/io.h
--- a/include/asm-parisc/io.h	Mon Nov  4 14:31:00 2002
+++ b/include/asm-parisc/io.h	Mon Nov  4 14:31:00 2002
@@ -182,6 +182,18 @@
 #define isa_memcpy_fromio(a,b,c) memcpy_fromio((a), EISA_BASE | (b), (c))
 #define isa_memcpy_toio(a,b,c) memcpy_toio(EISA_BASE | (a), (b), (c))
 
+/* 
+ * These functions support PA-RISC drivers which don't yet call ioremap().
+ * They will disappear once the last of these drivers is gone.
+ */
+#define gsc_readb(x) __raw_readb((unsigned long)x)
+#define gsc_readw(x) __raw_readw((unsigned long)x)
+#define gsc_readl(x) __raw_readl((unsigned long)x)
+#define gsc_writeb(x, y) __raw_writeb(x, (unsigned long)y)
+#define gsc_writew(x, y) __raw_writew(x, (unsigned long)y)
+#define gsc_writel(x, y) __raw_writel(x, (unsigned long)y)
+
+
 /*
  * XXX - We don't have csum_partial_copy_fromio() yet, so we cheat here and 
  * just copy it. The net code will then do the checksum later. Presently 
diff -Nru a/include/asm-parisc/poll.h b/include/asm-parisc/poll.h
--- a/include/asm-parisc/poll.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-parisc/poll.h	Mon Nov  4 14:31:01 2002
@@ -15,6 +15,7 @@
 #define POLLWRNORM	0x0100
 #define POLLWRBAND	0x0200
 #define POLLMSG		0x0400
+#define POLLREMOVE	0x1000
 
 struct pollfd {
 	int fd;
diff -Nru a/include/asm-parisc/processor.h b/include/asm-parisc/processor.h
--- a/include/asm-parisc/processor.h	Mon Nov  4 14:31:03 2002
+++ b/include/asm-parisc/processor.h	Mon Nov  4 14:31:03 2002
@@ -73,10 +73,8 @@
 ** Per CPU data structure - ie varies per CPU.
 */
 struct cpuinfo_parisc {
-
-	struct irq_region *region;
-	unsigned long it_value;     /* Interval Timer value at last timer Intr */
-	unsigned long it_delta;     /* Interval Timer delta (tic_10ms / HZ * 100) */
+	unsigned long it_value;     /* Interval Timer at last timer Intr */
+	unsigned long it_delta;     /* Interval delta (tic_10ms / HZ * 100) */
 	unsigned long irq_count;    /* number of IRQ's since boot */
 	unsigned long irq_max_cr16; /* longest time to handle a single IRQ */
 	unsigned long cpuid;        /* aka slot_number or set to NO_PROC_ID */
@@ -296,12 +294,6 @@
 extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
 extern void map_hpux_gateway_page(struct task_struct *tsk, struct mm_struct *mm);
-
-#define copy_segments(tsk, mm)  do { \
-					if (tsk->personality == PER_HPUX)  \
-					    map_hpux_gateway_page(tsk,mm); \
-				} while (0)
-#define release_segments(mm)	do { } while (0)
 
 static inline unsigned long get_wchan(struct task_struct *p)
 {
diff -Nru a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h
--- a/include/asm-ppc/processor.h	Mon Nov  4 14:31:00 2002
+++ b/include/asm-ppc/processor.h	Mon Nov  4 14:31:00 2002
@@ -736,9 +736,6 @@
 #define thread_saved_pc(tsk)	\
 	((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
 
-#define copy_segments(tsk, mm)		do { } while (0)
-#define release_segments(mm)		do { } while (0)
-
 unsigned long get_wchan(struct task_struct *p);
 
 #define KSTK_EIP(tsk)  ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
diff -Nru a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h
--- a/include/asm-ppc64/processor.h	Mon Nov  4 14:31:00 2002
+++ b/include/asm-ppc64/processor.h	Mon Nov  4 14:31:00 2002
@@ -682,10 +682,6 @@
 #define thread_saved_pc(tsk)    \
         ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
 
-#define copy_segments(tsk, mm)		do { } while (0)
-#define release_segments(mm)		do { } while (0)
-#define forget_segments()		do { } while (0)
-
 unsigned long get_wchan(struct task_struct *p);
 
 #define KSTK_EIP(tsk)  ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
diff -Nru a/include/asm-s390/processor.h b/include/asm-s390/processor.h
--- a/include/asm-s390/processor.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-s390/processor.h	Mon Nov  4 14:31:01 2002
@@ -114,10 +114,6 @@
 extern void release_thread(struct task_struct *);
 extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
-/* Copy and release all segment info associated with a VM */
-#define copy_segments(nr, mm)           do { } while (0)
-#define release_segments(mm)            do { } while (0)
-
 /*
  * Return saved PC of a blocked thread.
  */
diff -Nru a/include/asm-s390/ptrace.h b/include/asm-s390/ptrace.h
--- a/include/asm-s390/ptrace.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-s390/ptrace.h	Mon Nov  4 14:31:02 2002
@@ -105,10 +105,7 @@
 
 #define STACK_FRAME_OVERHEAD	96	/* size of minimum stack frame */
 
-#define PTRACE_SETOPTIONS         21
-
-/* options set using PTRACE_SETOPTIONS */
-#define PTRACE_O_TRACESYSGOOD     0x00000001
+#define PTRACE_OLDSETOPTIONS         21
 
 #ifndef __ASSEMBLY__
 #include <linux/config.h>
diff -Nru a/include/asm-s390x/processor.h b/include/asm-s390x/processor.h
--- a/include/asm-s390x/processor.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-s390x/processor.h	Mon Nov  4 14:31:02 2002
@@ -131,10 +131,6 @@
 extern void release_thread(struct task_struct *);
 extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
-/* Copy and release all segment info associated with a VM */
-#define copy_segments(nr, mm)           do { } while (0)
-#define release_segments(mm)            do { } while (0)
-
 /*
  * Return saved PC of a blocked thread.
  */
diff -Nru a/include/asm-s390x/ptrace.h b/include/asm-s390x/ptrace.h
--- a/include/asm-s390x/ptrace.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-s390x/ptrace.h	Mon Nov  4 14:31:01 2002
@@ -85,10 +85,7 @@
 
 #define STACK_FRAME_OVERHEAD    160      /* size of minimum stack frame */
 
-#define PTRACE_SETOPTIONS         21
-
-/* options set using PTRACE_SETOPTIONS */
-#define PTRACE_O_TRACESYSGOOD     0x00000001
+#define PTRACE_OLDSETOPTIONS         21
 
 #ifndef __ASSEMBLY__
 #include <linux/config.h>
diff -Nru a/include/asm-sh/processor.h b/include/asm-sh/processor.h
--- a/include/asm-sh/processor.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-sh/processor.h	Mon Nov  4 14:31:01 2002
@@ -147,11 +147,6 @@
 #define MCA_bus 0
 #define MCA_bus__is_a_macro /* for versions in ksyms.c */
 
-
-/* Copy and release all segment info associated with a VM */
-#define copy_segments(p, mm)	do { } while(0)
-#define release_segments(mm)	do { } while(0)
-
 /*
  * FPU lazy state save handling.
  */
diff -Nru a/include/asm-sh/ptrace.h b/include/asm-sh/ptrace.h
--- a/include/asm-sh/ptrace.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-sh/ptrace.h	Mon Nov  4 14:31:02 2002
@@ -44,10 +44,7 @@
 #define REG_XDREG14	47
 #define REG_FPSCR	48
 
-#define PTRACE_SETOPTIONS         21
-
-/* options set using PTRACE_SETOPTIONS */
-#define PTRACE_O_TRACESYSGOOD     0x00000001
+#define PTRACE_OLDSETOPTIONS         21
 
 /*
  * This struct defines the way the registers are stored on the
diff -Nru a/include/asm-sparc/mman.h b/include/asm-sparc/mman.h
--- a/include/asm-sparc/mman.h	Mon Nov  4 14:31:02 2002
+++ b/include/asm-sparc/mman.h	Mon Nov  4 14:31:02 2002
@@ -32,6 +32,9 @@
 #define MCL_CURRENT     0x2000          /* lock all currently mapped pages */
 #define MCL_FUTURE      0x4000          /* lock all additions to address space */
 
+#define MAP_POPULATE	0x8000		/* populate (prefault) pagetables */
+#define MAP_NONBLOCK	0x10000		/* do not block on IO */
+
 /* XXX Need to add flags to SunOS's mctl, mlockall, and madvise system
  * XXX calls.
  */
diff -Nru a/include/asm-sparc/processor.h b/include/asm-sparc/processor.h
--- a/include/asm-sparc/processor.h	Mon Nov  4 14:31:03 2002
+++ b/include/asm-sparc/processor.h	Mon Nov  4 14:31:03 2002
@@ -140,10 +140,6 @@
 #define release_thread(tsk)		do { } while(0)
 extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
-
-#define copy_segments(tsk, mm)		do { } while (0)
-#define release_segments(mm)		do { } while (0)
-
 #define get_wchan(__TSK) \
 ({	extern void scheduling_functions_start_here(void); \
 	extern void scheduling_functions_end_here(void); \
diff -Nru a/include/asm-sparc64/mman.h b/include/asm-sparc64/mman.h
--- a/include/asm-sparc64/mman.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-sparc64/mman.h	Mon Nov  4 14:31:01 2002
@@ -32,6 +32,9 @@
 #define MCL_CURRENT     0x2000          /* lock all currently mapped pages */
 #define MCL_FUTURE      0x4000          /* lock all additions to address space */
 
+#define MAP_POPULATE	0x8000		/* populate (prefault) pagetables */
+#define MAP_NONBLOCK	0x10000		/* do not block on IO */
+
 /* XXX Need to add flags to SunOS's mctl, mlockall, and madvise system
  * XXX calls.
  */
diff -Nru a/include/asm-sparc64/processor.h b/include/asm-sparc64/processor.h
--- a/include/asm-sparc64/processor.h	Mon Nov  4 14:31:00 2002
+++ b/include/asm-sparc64/processor.h	Mon Nov  4 14:31:00 2002
@@ -188,9 +188,6 @@
 
 extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
-#define copy_segments(tsk, mm)		do { } while (0)
-#define release_segments(mm)		do { } while (0)
-
 #define get_wchan(__TSK) \
 ({	extern void scheduling_functions_start_here(void); \
 	extern void scheduling_functions_end_here(void); \
diff -Nru a/include/asm-um/processor-generic.h b/include/asm-um/processor-generic.h
--- a/include/asm-um/processor-generic.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-um/processor-generic.h	Mon Nov  4 14:31:01 2002
@@ -92,17 +92,6 @@
 extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 extern void dump_thread(struct pt_regs *regs, struct user *u);
 
-static inline void release_segments(struct mm_struct *mm)
-{
-}
-
-static inline void copy_segments(struct task_struct *p, 
-				 struct mm_struct *new_mm)
-{
-}
-
-#define forget_segments() do ; while(0)
-
 extern unsigned long thread_saved_pc(struct task_struct *t);
 
 #define init_stack	(init_thread_union.stack)
diff -Nru a/include/asm-v850/a.out.h b/include/asm-v850/a.out.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/a.out.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,21 @@
+#ifndef __V850_A_OUT_H__
+#define __V850_A_OUT_H__
+
+struct exec
+{
+  unsigned long a_info;		/* Use macros N_MAGIC, etc for access */
+  unsigned a_text;		/* length of text, in bytes */
+  unsigned a_data;		/* length of data, in bytes */
+  unsigned a_bss;		/* length of uninitialized data area for file, in bytes */
+  unsigned a_syms;		/* length of symbol table data in file, in bytes */
+  unsigned a_entry;		/* start address */
+  unsigned a_trsize;		/* length of relocation info for text, in bytes */
+  unsigned a_drsize;		/* length of relocation info for data, in bytes */
+};
+
+#define N_TRSIZE(a)	((a).a_trsize)
+#define N_DRSIZE(a)	((a).a_drsize)
+#define N_SYMSIZE(a)	((a).a_syms)
+
+
+#endif /* __V850_A_OUT_H__ */
diff -Nru a/include/asm-v850/anna.h b/include/asm-v850/anna.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/anna.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,150 @@
+/*
+ * include/asm-v850/anna.h -- Anna V850E2 evaluation cpu chip/board
+ *
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_ANNA_H__
+#define __V850_ANNA_H__
+
+
+#define CPU_ARCH 	"v850e2"
+#define CPU_MODEL	"v850e2/anna"
+#define CPU_MODEL_LONG	"NEC V850E2/Anna"
+#define PLATFORM	"anna"
+#define PLATFORM_LONG	"NEC/Midas lab V850E2/Anna evaluation board"
+
+#define CPU_CLOCK_FREQ	200000000 /*  200MHz */
+#define SYS_CLOCK_FREQ	 33300000 /* 33.3MHz */
+
+
+/* 1MB of static RAM.  This memory is mirrored 64 times.  */
+#define SRAM_ADDR	0x04000000
+#define SRAM_SIZE	0x00100000 /* 1MB */
+/* 64MB of DRAM.  */
+#define SDRAM_ADDR	0x08000000	
+#define SDRAM_SIZE	0x04000000 /* 64MB */
+
+
+/* For <asm/page.h> */
+#define PAGE_OFFSET 	SRAM_ADDR
+
+/* We use on-chip RAM, for a few miscellaneous variables that must be
+   accessible using a load instruction relative to R0.  The Anna chip has
+   128K of `dLB' ram nominally located at 0xFFF00000, but it's mirrored
+   every 128K, so we can use the `last mirror' (except for the portion at
+   the top which is overridden by I/O space).  In addition, the early
+   sample chip we're using has lots of memory errors in the dLB ram, so we
+   use a specially chosen location that has at least 20 bytes of contiguous
+   valid memory (xxxF0020 - xxxF003F).  */
+#define R0_RAM_ADDR			0xFFFF8020
+
+
+/* Anna specific control registers.  */
+#define ANNA_CSC_ADDR(n)		(0xFFFFF060 + (n) * 2)
+#define ANNA_CSC(n)			(*(volatile u16 *)ANNA_CSC_ADDR(n))
+#define ANNA_BPC_ADDR			0xFFFFF064
+#define ANNA_BPC			(*(volatile u16 *)ANNA_BPC_ADDR)
+#define ANNA_BSC_ADDR			0xFFFFF066
+#define ANNA_BSC			(*(volatile u16 *)ANNA_BSC_ADDR)
+#define ANNA_BEC_ADDR			0xFFFFF068
+#define ANNA_BEC			(*(volatile u16 *)ANNA_BEC_ADDR)
+#define ANNA_BHC_ADDR			0xFFFFF06A
+#define ANNA_BHC			(*(volatile u16 *)ANNA_BHC_ADDR)
+#define ANNA_BCT_ADDR(n)		(0xFFFFF480 + (n) * 2)
+#define ANNA_BCT(n)			(*(volatile u16 *)ANNA_BCT_ADDR(n))
+#define ANNA_DWC_ADDR(n)		(0xFFFFF484 + (n) * 2)
+#define ANNA_DWC(n)			(*(volatile u16 *)ANNA_DWC_ADDR(n))
+#define ANNA_BCC_ADDR			0xFFFFF488
+#define ANNA_BCC			(*(volatile u16 *)ANNA_BCC_ADDR)
+#define ANNA_ASC_ADDR			0xFFFFF48A
+#define ANNA_ASC			(*(volatile u16 *)ANNA_ASC_ADDR)
+#define ANNA_LBS_ADDR			0xFFFFF48E
+#define ANNA_LBS			(*(volatile u16 *)ANNA_LBS_ADDR)
+#define ANNA_SCR3_ADDR			0xFFFFF4AC
+#define ANNA_SCR3			(*(volatile u16 *)ANNA_SCR3_ADDR)
+#define ANNA_RFS3_ADDR			0xFFFFF4AE
+#define ANNA_RFS3			(*(volatile u16 *)ANNA_RFS3_ADDR)
+#define ANNA_ILBEN_ADDR			0xFFFFF7F2
+#define ANNA_ILBEN			(*(volatile u16 *)ANNA_ILBEN_ADDR)
+
+
+/* I/O port P0-P3. */
+/* Direct I/O.  Bits 0-7 are pins Pn0-Pn7.  */
+#define ANNA_PORT_IO_ADDR(n)		(0xFFFFF400 + (n) * 2)
+#define ANNA_PORT_IO(n)			(*(volatile u8 *)ANNA_PORT_IO_ADDR(n))
+/* Port mode (for direct I/O, 0 = output, 1 = input).  */
+#define ANNA_PORT_PM_ADDR(n)		(0xFFFFF410 + (n) * 2)
+#define ANNA_PORT_PM(n)			(*(volatile u8 *)ANNA_PORT_PM_ADDR(n))
+
+
+/* NB85E-style interrupt system.  */
+#include <asm/nb85e_intc.h>
+
+/* Hardware-specific interrupt numbers (in the kernel IRQ namespace).  */
+#define IRQ_INTP(n)	(n)	/* Pnnn (pin) interrupts 0-15 */
+#define IRQ_INTP_NUM	16
+#define IRQ_INTOV(n)	(0x10 + (n)) /* 0-2 */
+#define IRQ_INTOV_NUM	2
+#define IRQ_INTCCC(n)	(0x12 + (n))
+#define IRQ_INTCCC_NUM	4
+#define IRQ_INTCMD(n)	(0x16 + (n)) /* interval timer interrupts 0-5 */
+#define IRQ_INTCMD_NUM	6
+#define IRQ_INTDMA(n)	(0x1C + (n)) /* DMA interrupts 0-3 */
+#define IRQ_INTDMA_NUM	4
+#define IRQ_INTDMXER	0x20
+#define IRQ_INTSRE(n)	(0x21 + (n)*3) /* UART 0-1 reception error */
+#define IRQ_INTSRE_NUM	2
+#define IRQ_INTSR(n)	(0x22 + (n)*3) /* UART 0-1 reception completion */
+#define IRQ_INTSR_NUM	2
+#define IRQ_INTST(n)	(0x23 + (n)*3) /* UART 0-1 transmission completion */
+#define IRQ_INTST_NUM	2
+
+#define NUM_CPU_IRQS	64
+
+#ifndef __ASSEMBLY__
+/* Initialize chip interrupts.  */
+extern void anna_init_irqs (void);
+#endif
+
+
+/* Anna UART details (basically the same as the V850E/MA1, but 2 channels).  */
+#define NB85E_UART_NUM_CHANNELS		2
+#define NB85E_UART_BASE_FREQ		(SYS_CLOCK_FREQ / 2)
+#define NB85E_UART_CHIP_NAME 		"V850E2/NA85E2A"
+
+/* This is a function that gets called before configuring the UART.  */
+#define NB85E_UART_PRE_CONFIGURE	anna_uart_pre_configure
+#ifndef __ASSEMBLY__
+extern void anna_uart_pre_configure (unsigned chan,
+				     unsigned cflags, unsigned baud);
+#endif
+
+
+/* Timer C details.  */
+#define NB85E_TIMER_C_BASE_ADDR		0xFFFFF600
+
+/* Timer D details (the Anna actually has 5 of these; should change later). */
+#define NB85E_TIMER_D_BASE_ADDR		0xFFFFF540
+#define NB85E_TIMER_D_TMD_BASE_ADDR 	(NB85E_TIMER_D_BASE_ADDR + 0x0)
+#define NB85E_TIMER_D_CMD_BASE_ADDR 	(NB85E_TIMER_D_BASE_ADDR + 0x2)
+#define NB85E_TIMER_D_TMCD_BASE_ADDR 	(NB85E_TIMER_D_BASE_ADDR + 0x4)
+
+#define NB85E_TIMER_D_BASE_FREQ		SYS_CLOCK_FREQ
+#define NB85E_TIMER_D_TMCD_CS_MIN	1 /* min 2^1 divider */
+
+
+/* For <asm/param.h> */
+#ifndef HZ
+#define HZ	100
+#endif
+
+
+#endif /* __V850_ANNA_H__ */
diff -Nru a/include/asm-v850/asm.h b/include/asm-v850/asm.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/asm.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,25 @@
+/*
+ * include/asm-v850/asm.h -- Macros for writing assembly code
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#define G_ENTRY(name)							      \
+   .align 4;								      \
+   .globl name;								      \
+   .type  name,@function;						      \
+   name
+#define END(name)							      \
+   .size  name,.-name
+
+#define L_ENTRY(name)							      \
+   .align 4;								      \
+   .type  name,@function;						      \
+   name
diff -Nru a/include/asm-v850/atomic.h b/include/asm-v850/atomic.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/atomic.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,89 @@
+/*
+ * include/asm-v850/atomic.h -- Atomic operations
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_ATOMIC_H__
+#define __V850_ATOMIC_H__
+
+#include <linux/config.h>
+
+#include <asm/system.h>
+
+#ifdef CONFIG_SMP
+#error SMP not supported
+#endif
+
+typedef struct { int counter; } atomic_t;
+
+#define ATOMIC_INIT(i)	{ (i) }
+
+#ifdef __KERNEL__
+
+#define atomic_read(v)		((v)->counter)
+#define atomic_set(v,i)		(((v)->counter) = (i))
+
+extern __inline__ int atomic_add_return (int i, volatile atomic_t *v)
+{
+	unsigned long flags;
+	int res;
+
+	local_irq_save (flags);
+	res = v->counter + i;
+	v->counter = res;
+	local_irq_restore (flags);
+
+	return res;
+}
+
+static __inline__ int atomic_sub_return (int i, volatile atomic_t *v)
+{
+	unsigned long flags;
+	int res;
+
+	local_irq_save (flags);
+	res = v->counter - i;
+	v->counter = res;
+	local_irq_restore (flags);
+
+	return res;
+}
+
+static __inline__ void atomic_clear_mask (unsigned long mask, unsigned long *addr)
+{
+	unsigned long flags;
+
+	local_irq_save (flags);
+	*addr &= ~mask;
+	local_irq_restore (flags);
+}
+
+#endif
+
+#define atomic_add(i, v)	atomic_add_return ((i), (v))
+#define atomic_sub(i, v)	atomic_sub_return ((i), (v))
+
+#define atomic_dec_return(v)	atomic_sub_return (1, (v))
+#define atomic_inc_return(v)	atomic_add_return (1, (v))
+#define atomic_inc(v) 		atomic_inc_return (v)
+#define atomic_dec(v) 		atomic_dec_return (v)
+
+#define atomic_sub_and_test(i,v)	(atomic_sub_return ((i), (v)) == 0)
+#define atomic_dec_and_test(v)		(atomic_sub_return (1, (v)) == 0)
+#define atomic_add_negative(i,v)	(atomic_add_return ((i), (v)) < 0)
+
+/* Atomic operations are already serializing on ARM */
+#define smp_mb__before_atomic_dec()	barrier()
+#define smp_mb__after_atomic_dec()	barrier()
+#define smp_mb__before_atomic_inc()	barrier()
+#define smp_mb__after_atomic_inc()	barrier()
+
+#endif /* __V850_ATOMIC_H__ */
diff -Nru a/include/asm-v850/bitops.h b/include/asm-v850/bitops.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/bitops.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,269 @@
+/*
+ * include/asm-v850/bitops.h -- Bit operations
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 1992  Linus Torvalds.
+ *
+ * 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.
+ */
+
+#ifndef __V850_BITOPS_H__
+#define __V850_BITOPS_H__
+
+
+#include <linux/config.h>
+#include <linux/compiler.h>	/* unlikely  */
+#include <asm/byteorder.h>	/* swab32 */
+#include <asm/system.h>		/* interrupt enable/disable */
+
+
+#ifdef __KERNEL__
+
+/*
+ * The __ functions are not atomic
+ */
+
+/*
+ * ffz = Find First Zero in word. Undefined if no zero exists,
+ * so code should check against ~0UL first..
+ */
+extern __inline__ unsigned long ffz (unsigned long word)
+{
+	unsigned long result = 0;
+
+	while (word & 1) {
+		result++;
+		word >>= 1;
+	}
+	return result;
+}
+
+
+/* In the following constant-bit-op macros, a "g" constraint is used when
+   we really need an integer ("i" constraint).  This is to avoid
+   warnings/errors from the compiler in the case where the associated
+   operand _isn't_ an integer, and shouldn't produce bogus assembly because
+   use of that form is protected by a guard statement that checks for
+   constants, and should otherwise be removed by the optimizer.  This
+   _usually_ works -- however, __builtin_constant_p returns true for a
+   variable with a known constant value too, and unfortunately gcc will
+   happily put the variable in a register and use the register for the "g"
+   constraint'd asm operand.  To avoid the latter problem, we add a
+   constant offset to the operand and subtract it back in the asm code;
+   forcing gcc to do arithmetic on the value is usually enough to get it
+   to use a real constant value.  This is horrible, and ultimately
+   unreliable too, but it seems to work for now (hopefully gcc will offer
+   us more control in the future, so we can do a better job).  */
+
+#define __const_bit_op(op, nr, addr)					\
+  ({ __asm__ (op " (%0 - 0x123), %1"					\
+	      :: "g" (((nr) & 0x7) + 0x123),				\
+		 "m" (*((char *)(addr) + ((nr) >> 3)))			\
+	      : "memory"); })
+#define __var_bit_op(op, nr, addr)					\
+  ({ int __nr = (nr);							\
+     __asm__ (op " %0, [%1]"						\
+	      :: "r" (__nr & 0x7),					\
+		 "r" ((char *)(addr) + (__nr >> 3))			\
+	      : "memory"); })
+#define __bit_op(op, nr, addr)						\
+  ((__builtin_constant_p (nr) && (unsigned)(nr) <= 0x7FFFF)		\
+   ? __const_bit_op (op, nr, addr)					\
+   : __var_bit_op (op, nr, addr))
+
+#define __set_bit(nr, addr)		__bit_op ("set1", nr, addr)
+#define __clear_bit(nr, addr)		__bit_op ("clr1", nr, addr)
+#define __change_bit(nr, addr)		__bit_op ("not1", nr, addr)
+
+/* The bit instructions used by `non-atomic' variants are actually atomic.  */
+#define set_bit __set_bit
+#define clear_bit __clear_bit
+#define change_bit __change_bit
+
+
+#define __const_tns_bit_op(op, nr, addr)				\
+  ({ int __tns_res;							\
+     __asm__ ("tst1 (%1 - 0x123), %2; setf nz, %0; " op " (%1 - 0x123), %2" \
+	      : "=&r" (__tns_res)					\
+	      : "g" (((nr) & 0x7) + 0x123),				\
+		"m" (*((char *)(addr) + ((nr) >> 3)))			\
+	      : "memory");						\
+     __tns_res;							\
+  })
+#define __var_tns_bit_op(op, nr, addr)					\
+  ({ int __nr = (nr);							\
+     int __tns_res;							\
+     __asm__ ("tst1 %1, [%2]; setf nz, %0; " op " %1, [%2]"		\
+	      : "=&r" (__tns_res)					\
+	      : "r" (__nr & 0x7),					\
+		"r" ((char *)(addr) + (__nr >> 3))			\
+	      : "memory");						\
+     __tns_res;							\
+  })
+#define __tns_bit_op(op, nr, addr)					\
+  ((__builtin_constant_p (nr) && (unsigned)(nr) <= 0x7FFFF)		\
+   ? __const_tns_bit_op (op, nr, addr)					\
+   : __var_tns_bit_op (op, nr, addr))
+#define __tns_atomic_bit_op(op, nr, addr)				\
+  ({ int __tns_atomic_res, __tns_atomic_flags;				\
+     local_irq_save (__tns_atomic_flags);				\
+     __tns_atomic_res = __tns_bit_op (op, nr, addr);			\
+     local_irq_restore (__tns_atomic_flags);				\
+     __tns_atomic_res;							\
+  })
+
+#define __test_and_set_bit(nr, addr)	__tns_bit_op ("set1", nr, addr)
+#define test_and_set_bit(nr, addr)	__tns_atomic_bit_op ("set1", nr, addr)
+
+#define __test_and_clear_bit(nr, addr)	__tns_bit_op ("clr1", nr, addr)
+#define test_and_clear_bit(nr, addr)	__tns_atomic_bit_op ("clr1", nr, addr)
+
+#define __test_and_change_bit(nr, addr)	__tns_bit_op ("not1", nr, addr)
+#define test_and_change_bit(nr, addr)	__tns_atomic_bit_op ("not1", nr, addr)
+
+
+#define __const_test_bit(nr, addr)					\
+  ({ int __test_bit_res;						\
+     __asm__ ("tst1 (%1 - 0x123), %2; setf nz, %0"			\
+	      : "=r" (__test_bit_res)					\
+	      : "g" (((nr) & 0x7) + 0x123),				\
+                "m" (*((const char *)(addr) + ((nr) >> 3))));		\
+     __test_bit_res;							\
+  })
+extern __inline__ int __test_bit (int nr, void *addr)
+{
+	int res;
+	__asm__ ("tst1 %1, [%2]; setf nz, %0"
+		 : "=r" (res)
+		 : "r" (nr & 0x7), "r" (addr + (nr >> 3)));
+	return res;
+}
+#define test_bit(nr,addr)						\
+  ((__builtin_constant_p (nr) && (unsigned)(nr) <= 0x7FFFF)		\
+   ? __const_test_bit ((nr), (addr))					\
+   : __test_bit ((nr), (addr)))
+
+
+/* clear_bit doesn't provide any barrier for the compiler.  */
+#define smp_mb__before_clear_bit()	barrier ()
+#define smp_mb__after_clear_bit()	barrier ()
+
+
+#define find_first_zero_bit(addr, size) \
+  find_next_zero_bit ((addr), (size), 0)
+
+extern __inline__ int find_next_zero_bit (void *addr, int size, int offset)
+{
+	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if (offset) {
+		tmp = * (p++);
+		tmp |= ~0UL >> (32-offset);
+		if (size < 32)
+			goto found_first;
+		if (~tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while (size & ~31UL) {
+		if (~ (tmp = * (p++)))
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if (!size)
+		return result;
+	tmp = *p;
+
+ found_first:
+	tmp |= ~0UL >> size;
+ found_middle:
+	return result + ffz (tmp);
+}
+
+#define ffs(x) generic_ffs (x)
+#define fls(x) generic_fls (x)
+#define __ffs(x) ffs(x)
+
+/*
+ * This is just `generic_ffs' from <linux/bitops.h>, except that it assumes
+ * that at least one bit is set, and returns the real index of the bit
+ * (rather than the bit index + 1, like ffs does).
+ */
+static inline int sched_ffs(int x)
+{
+	int r = 0;
+
+	if (!(x & 0xffff)) {
+		x >>= 16;
+		r += 16;
+	}
+	if (!(x & 0xff)) {
+		x >>= 8;
+		r += 8;
+	}
+	if (!(x & 0xf)) {
+		x >>= 4;
+		r += 4;
+	}
+	if (!(x & 3)) {
+		x >>= 2;
+		r += 2;
+	}
+	if (!(x & 1)) {
+		x >>= 1;
+		r += 1;
+	}
+	return r;
+}
+
+/*
+ * Every architecture must define this function. It's the fastest
+ * way of searching a 140-bit bitmap where the first 100 bits are
+ * unlikely to be set. It's guaranteed that at least one of the 140
+ * bits is set.
+ */
+static inline int sched_find_first_bit(unsigned long *b)
+{
+	unsigned offs = 0;
+	while (! *b) {
+		b++;
+		offs += 32;
+	}
+	return sched_ffs (*b) + offs;
+}
+
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
+#define hweight32(x) 			generic_hweight32 (x)
+#define hweight16(x) 			generic_hweight16 (x)
+#define hweight8(x) 			generic_hweight8 (x)
+
+#define ext2_set_bit			test_and_set_bit
+#define ext2_clear_bit			test_and_clear_bit
+#define ext2_test_bit			test_bit
+#define ext2_find_first_zero_bit	find_first_zero_bit
+#define ext2_find_next_zero_bit		find_next_zero_bit
+
+/* Bitmap functions for the minix filesystem.  */
+#define minix_test_and_set_bit		test_and_set_bit
+#define minix_set_bit			set_bit
+#define minix_test_and_clear_bit	test_and_clear_bit
+#define minix_test_bit 			test_bit
+#define minix_find_first_zero_bit 	find_first_zero_bit
+
+#endif /* __KERNEL__ */
+
+#endif /* __V850_BITOPS_H__ */
diff -Nru a/include/asm-v850/bugs.h b/include/asm-v850/bugs.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/bugs.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,16 @@
+/*
+ *  include/asm-v850e/bugs.h
+ *
+ *  Copyright (C) 1994  Linus Torvalds
+ */
+
+/*
+ * This is included by init/main.c to check for architecture-dependent bugs.
+ *
+ * Needs:
+ *	void check_bugs(void);
+ */
+
+static void check_bugs(void)
+{
+}
diff -Nru a/include/asm-v850/byteorder.h b/include/asm-v850/byteorder.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/byteorder.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,47 @@
+/*
+ * include/asm-v850/byteorder.h -- Endian id and conversion ops
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_BYTEORDER_H__
+#define __V850_BYTEORDER_H__
+
+#include <asm/types.h>
+
+#ifdef __GNUC__
+
+static __inline__ __const__ __u32 ___arch__swab32 (__u32 word)
+{
+	__u32 res;
+	__asm__ ("bsw %1, %0" : "=r" (res) : "r" (word));
+	return res;
+}
+
+static __inline__ __const__ __u16 ___arch__swab16 (__u16 half_word)
+{
+	__u16 res;
+	__asm__ ("bsh %1, %0" : "=r" (res) : "r" (half_word));
+	return res;
+}
+
+#define __arch__swab32(x) ___arch__swab32(x)
+#define __arch__swab16(x) ___arch__swab16(x)
+
+#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#  define __BYTEORDER_HAS_U64__
+#  define __SWAB_64_THRU_32__
+#endif
+
+#endif /* __GNUC__ */
+
+#include <linux/byteorder/little_endian.h>
+
+#endif /* __V850_BYTEORDER_H__ */
diff -Nru a/include/asm-v850/cache.h b/include/asm-v850/cache.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/cache.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,25 @@
+/*
+ * include/asm-v850/cache.h -- Cache operations
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_CACHE_H__
+#define __V850_CACHE_H__
+
+/* All cache operations are machine-dependent.  */
+#include <asm/machdep.h>
+
+#ifndef L1_CACHE_BYTES
+/* This processor has no cache, so just choose an arbitrary value.  */
+#define L1_CACHE_BYTES		16
+#endif
+
+#endif /* __V850_CACHE_H__ */
diff -Nru a/include/asm-v850/cacheflush.h b/include/asm-v850/cacheflush.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/cacheflush.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,42 @@
+/*
+ * include/asm-v850/cacheflush.h
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_CACHEFLUSH_H__
+#define __V850_CACHEFLUSH_H__
+
+/* Somebody depends on this; sigh...  */
+#include <linux/mm.h>
+
+#include <asm/setup.h>
+#include <asm/machdep.h>
+
+
+#ifndef flush_cache_all
+/* If there's no flush_cache_all macro defined by <asm/machdep.h>, then
+   this processor has no cache, so just define these as nops.  */
+
+#define flush_cache_all()			((void)0)
+#define flush_cache_mm(mm)			((void)0)
+#define flush_cache_range(vma, start, end)	((void)0)
+#define flush_cache_page(vma, vmaddr)		((void)0)
+#define flush_page_to_ram(page)			((void)0)
+#define flush_dcache_page(page)			((void)0)
+#define flush_icache()				((void)0)
+#define flush_icache_range(start, end)		((void)0)
+#define flush_icache_page(vma,pg)		((void)0)
+#define flush_icache_user_range(vma,pg,adr,len)	((void)0)
+#define flush_cache_sigtramp(vaddr)		((void)0)
+
+#endif /* !flush_cache_all */
+
+#endif /* __V850_CACHEFLUSH_H__ */
diff -Nru a/include/asm-v850/checksum.h b/include/asm-v850/checksum.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/checksum.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,115 @@
+/*
+ * include/asm-v850/checksum.h -- Checksum ops
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_CHECKSUM_H__
+#define __V850_CHECKSUM_H__
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+extern unsigned int csum_partial (const unsigned char * buff, int len,
+				  unsigned int sum);
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+extern unsigned csum_partial_copy (const char *src, char *dst, int len,
+				   unsigned sum);
+
+
+/*
+ * the same as csum_partial_copy, but copies from user space.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+extern unsigned csum_partial_copy_from_user (const char *src, char *dst,
+					     int len, unsigned sum,
+					     int *csum_err);
+
+#define csum_partial_copy_nocheck(src, dst, len, sum)	\
+	csum_partial_copy ((src), (dst), (len), (sum))
+
+unsigned short ip_fast_csum (unsigned char *iph, unsigned int ihl);
+
+/*
+ *	Fold a partial checksum
+ */
+static inline unsigned int csum_fold (unsigned long sum)
+{
+	unsigned int result;
+	/*
+			        %0		%1
+	      hsw %1, %0	H     L		L     H
+	      add %1, %0	H     L		H+L+C H+L
+	*/
+	asm ("hsw %1, %0; add %1, %0" : "=&r" (result) : "r" (sum));
+	return (~result) >> 16;
+}
+
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static inline unsigned int
+csum_tcpudp_nofold (unsigned long saddr, unsigned long daddr,
+		    unsigned short len,
+		    unsigned short proto, unsigned int sum)
+{
+	int __carry;
+	__asm__ ("add %2, %0;"
+		 "setf c, %1;"
+		 "add %1, %0;"
+		 "add %3, %0;"
+		 "setf c, %1;"
+		 "add %1, %0;"
+		 "add %4, %0;"
+		 "setf c, %1;"
+		 "add %1, %0"
+		 : "=&r" (sum), "=&r" (__carry)
+		 : "r" (daddr), "r" (saddr),
+		 "r" (ntohs (len) + (proto << 8)),
+		 "0" (sum));
+	return sum;
+}
+
+static inline unsigned short int
+csum_tcpudp_magic (unsigned long saddr, unsigned long daddr,
+		   unsigned short len,
+		   unsigned short proto, unsigned int sum)
+{
+	return csum_fold (csum_tcpudp_nofold (saddr, daddr, len, proto, sum));
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+extern unsigned short ip_compute_csum (const unsigned char * buff, int len);
+
+
+#endif /* __V850_CHECKSUM_H__ */
diff -Nru a/include/asm-v850/clinkage.h b/include/asm-v850/clinkage.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/clinkage.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,25 @@
+/*
+ * include/asm-v850/clinkage.h -- Macros to reflect C symbol-naming conventions
+ *
+ *  Copyright (C) 2001,02  NEC Corporatione
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __CLINKAGE_H__
+#define __V850_CLINKAGE_H__
+
+#include <asm/macrology.h>
+#include <asm/asm.h>
+
+#define C_SYMBOL_NAME(name) 	macrology_paste(_, name)
+#define C_SYMBOL_STRING(name)	macrology_stringify(C_SYMBOL_NAME(name))
+#define C_ENTRY(name)		G_ENTRY(C_SYMBOL_NAME(name))
+#define C_END(name)		END(C_SYMBOL_NAME(name))
+
+#endif /* __V850_CLINKAGE_H__ */
diff -Nru a/include/asm-v850/current.h b/include/asm-v850/current.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/current.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,44 @@
+/*
+ * include/asm-v850/current.h -- Current task
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_CURRENT_H__
+#define __V850_CURRENT_H__
+
+#include <asm/macrology.h>
+#include <asm/thread_info.h>
+
+
+/* Register used to hold the current task pointer while in the kernel.
+   Any `call clobbered' register without a special meaning should be OK,
+   but check asm/v850/kernel/entry.S to be sure.  */
+#define CURRENT_TASK_REGNUM	16
+#define CURRENT_TASK 		macrology_paste (r, CURRENT_TASK_REGNUM)
+
+
+#ifdef __ASSEMBLY__
+
+/* Put a pointer to the current task structure into REG.  */
+#define GET_CURRENT_TASK(reg)						\
+	GET_CURRENT_THREAD(reg);					\
+	ld.w	TI_TASK[reg], reg
+
+#else /* !__ASSEMBLY__ */
+
+/* A pointer to the current task.  */
+register struct task_struct *current					\
+   __asm__ (macrology_stringify (CURRENT_TASK));
+
+#endif /* __ASSEMBLY__ */
+
+
+#endif /* _V850_CURRENT_H */
diff -Nru a/include/asm-v850/delay.h b/include/asm-v850/delay.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/delay.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,46 @@
+/*
+ * include/asm-v850/delay.h -- Delay routines, using a pre-computed
+ * 	"loops_per_second" value
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 1994 Hamish Macdonald
+ *
+ * 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.
+ */
+
+#ifndef __V850_DELAY_H__
+#define __V850_DELAY_H__
+
+#include <asm/param.h>
+
+extern __inline__ void __delay(unsigned long loops)
+{
+	__asm__ __volatile__ ("1: add -1, %0; bnz 1b"
+			      : "=r" (loops) : "0" (loops));
+}
+
+/*
+ * Use only for very small delays ( < 1 msec).  Should probably use a
+ * lookup table, really, as the multiplications take much too long with
+ * short delays.  This is a "reasonable" implementation, though (and the
+ * first constant multiplications gets optimized away if the delay is
+ * a constant)  
+ */
+
+extern unsigned long loops_per_jiffy;
+
+extern __inline__ void udelay(unsigned long usecs)
+{
+	register unsigned long full_loops, part_loops;
+
+	full_loops = ((usecs * HZ) / 1000000) * loops_per_jiffy;
+	usecs %= (1000000 / HZ);
+	part_loops = (usecs * HZ * loops_per_jiffy) / 1000000;
+
+	__delay(full_loops + part_loops);
+}
+
+#endif /* __V850_DELAY_H__ */
diff -Nru a/include/asm-v850/div64.h b/include/asm-v850/div64.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/div64.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,11 @@
+#ifndef __V850_DIV64_H__
+#define __V850_DIV64_H__
+
+/* We're not 64-bit, but... */
+#define do_div(n,base) ({ \
+	int __res; \
+	__res = ((unsigned long) n) % (unsigned) base; \
+	n = ((unsigned long) n) / (unsigned) base; \
+	__res; })
+
+#endif /* __V850_DIV64_H__ */
diff -Nru a/include/asm-v850/dma.h b/include/asm-v850/dma.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/dma.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,18 @@
+#ifndef __V850_DMA_H__
+#define __V850_DMA_H__
+
+/* What should this be?  */
+#define MAX_DMA_ADDRESS	0xFFFFFFFF
+
+/* reserve a DMA channel */
+extern int request_dma (unsigned int dmanr, const char * device_id);
+/* release it again */
+extern void free_dma (unsigned int dmanr);
+
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy    (0)
+#endif
+
+#endif /* __V850_DMA_H__ */
diff -Nru a/include/asm-v850/elf.h b/include/asm-v850/elf.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/elf.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,75 @@
+#ifndef __V850_ELF_H__
+#define __V850_ELF_H__
+
+/*
+ * ELF register definitions..
+ */
+
+#include <asm/ptrace.h>
+#include <asm/user.h>
+#include <asm/byteorder.h>
+
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct user_fpu_struct elf_fpregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ( (x)->e_machine == EM_CYGNUS_V850 )
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS	ELFCLASS32
+#ifdef __LITTLE_ENDIAN__
+#define ELF_DATA	ELFDATA2LSB
+#else
+#define ELF_DATA	ELFDATA2MSB
+#endif
+#define ELF_ARCH	EM_V850
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE	4096
+
+
+#define ELF_CORE_COPY_REGS(_dest,_regs)				\
+	memcpy((char *) &_dest, (char *) _regs,			\
+	       sizeof(struct pt_regs));
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this CPU supports.  This could be done in user space,
+   but it's not easy, and we've already done it here.  */
+
+#define ELF_HWCAP	(0)
+
+/* This yields a string that ld.so will use to load implementation
+   specific libraries for optimization.  This is more specific in
+   intent than poking at uname or /proc/cpuinfo.
+
+   For the moment, we have only optimizations for the Intel generations,
+   but that could change... */
+
+#define ELF_PLATFORM  (NULL)
+
+#define ELF_PLAT_INIT(_r)						      \
+  do {									      \
+	 _r->gpr[0] =  _r->gpr[1] =  _r->gpr[2] =  _r->gpr[3] =		      \
+	 _r->gpr[4] =  _r->gpr[5] =  _r->gpr[6] =  _r->gpr[7] =		      \
+	 _r->gpr[8] =  _r->gpr[9] = _r->gpr[10] = _r->gpr[11] =		      \
+	_r->gpr[12] = _r->gpr[13] = _r->gpr[14] = _r->gpr[15] =		      \
+	_r->gpr[16] = _r->gpr[17] = _r->gpr[18] = _r->gpr[19] =		      \
+	_r->gpr[20] = _r->gpr[21] = _r->gpr[22] = _r->gpr[23] =		      \
+	_r->gpr[24] = _r->gpr[25] = _r->gpr[26] = _r->gpr[27] =		      \
+	_r->gpr[28] = _r->gpr[29] = _r->gpr[30] = _r->gpr[31] =		      \
+	0;								      \
+  } while (0)
+
+#ifdef __KERNEL__
+#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
+#endif
+
+#endif /* __V850_ELF_H__ */
diff -Nru a/include/asm-v850/entry.h b/include/asm-v850/entry.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/entry.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,128 @@
+/*
+ * include/asm-v850/entry.h -- Definitions used by low-level trap handlers
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_ENTRY_H__
+#define __V850_ENTRY_H__
+
+
+#include <asm/ptrace.h>
+#include <asm/machdep.h>
+
+
+/* If true, system calls save and restore all registers (except result
+   registers, of course).  If false, then `call clobbered' registers
+   will not be preserved, on the theory that system calls are basically
+   function calls anyway, and the caller should be able to deal with it.
+   This is a security risk, of course, as `internal' values may leak out
+   after a system call, but that certainly doesn't matter very much for
+   a processor with no MMU protection!  For a protected-mode kernel, it
+   would be faster to just zero those registers before returning.  */
+#define TRAPS_PRESERVE_CALL_CLOBBERED_REGS	0
+
+/* If TRAPS_PRESERVE_CALL_CLOBBERED_REGS is false, then zero `call
+   clobbered' registers before returning from a system call.  */
+#define TRAPS_ZERO_CALL_CLOBBERED_REGS		0
+
+
+/* These are special variables using by the kernel trap/interrupt code
+   to save registers in, at a time when there are no spare registers we
+   can use to do so, and we can't depend on the value of the stack
+   pointer.  This means that they must be within a signed 16-bit
+   displacement of 0x00000000.  */
+
+#define KERNEL_VAR_SPACE_ADDR	R0_RAM_ADDR
+
+#ifdef __ASSEMBLY__
+#define KERNEL_VAR(addr)	addr[r0]
+#else
+#define KERNEL_VAR(addr)	(*(volatile unsigned long *)(addr))
+#endif
+
+/* Kernel stack pointer, 4 bytes.  */
+#define KSP_ADDR		(KERNEL_VAR_SPACE_ADDR +  0)
+#define KSP			KERNEL_VAR (KSP_ADDR)
+/* 1 if in kernel-mode, 0 if in user mode, 1 byte.  */
+#define KM_ADDR 		(KERNEL_VAR_SPACE_ADDR +  4)
+#define KM			KERNEL_VAR (KM_ADDR)
+/* Temporary storage for interrupt handlers, 4 bytes.  */
+#define INT_SCRATCH_ADDR	(KERNEL_VAR_SPACE_ADDR +  8)
+#define INT_SCRATCH		KERNEL_VAR (INT_SCRATCH_ADDR)
+/* Where the stack-pointer is saved when jumping to various sorts of
+   interrupt handlers.  ENTRY_SP is used by everything except NMIs,
+   which have their own location.  Higher-priority NMIs can clobber the
+   value written by a lower priority NMI, since they can't be disabled,
+   but that's OK, because only NMI0 (the lowest-priority one) is allowed
+   to return.  */
+#define ENTRY_SP_ADDR		(KERNEL_VAR_SPACE_ADDR + 12)
+#define ENTRY_SP		KERNEL_VAR (ENTRY_SP_ADDR)
+#define NMI_ENTRY_SP_ADDR	(KERNEL_VAR_SPACE_ADDR + 16)
+#define NMI_ENTRY_SP		KERNEL_VAR (NMI_ENTRY_SP_ADDR)
+
+#ifdef CONFIG_RESET_GUARD
+/* Used to detect unexpected resets (since the v850 has no MMU, any call
+   through a null pointer will jump to the reset vector).  We detect
+   such resets by checking for a magic value, RESET_GUARD_ACTIVE, in
+   this location.  Properly resetting the machine stores zero there, so
+   it shouldn't trigger the guard; the power-on value is uncertain, but
+   it's unlikely to be RESET_GUARD_ACTIVE.  */
+#define RESET_GUARD_ADDR	(KERNEL_VAR_SPACE_ADDR + 28)
+#define RESET_GUARD		KERNEL_VAR (RESET_GUARD_ADDR)
+#define RESET_GUARD_ACTIVE	0xFAB4BEEF
+#endif /* CONFIG_RESET_GUARD */
+
+#ifdef CONFIG_V850E_MA1_HIGHRES_TIMER
+#define HIGHRES_TIMER_SLOW_TICKS_ADDR (KERNEL_VAR_SPACE_ADDR + 32)
+#define HIGHRES_TIMER_SLOW_TICKS     KERNEL_VAR (HIGHRES_TIMER_SLOW_TICKS_ADDR)
+#endif /* CONFIG_V850E_MA1_HIGHRES_TIMER */
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_RESET_GUARD
+/* Turn off reset guard, so that resetting the machine works normally.
+   This should be called in the various machine_halt, etc., functions.  */
+static inline void disable_reset_guard (void)
+{
+	RESET_GUARD = 0;
+}
+#endif /* CONFIG_RESET_GUARD */
+
+#endif /* !__ASSEMBLY__ */
+
+
+/* A `state save frame' is a struct pt_regs preceded by some extra space
+   suitable for a function call stack frame.  */
+
+/* Amount of room on the stack reserved for arguments and to satisfy the
+   C calling conventions, in addition to the space used by the struct
+   pt_regs that actually holds saved values.  */
+#define STATE_SAVE_ARG_SPACE	(6*4) /* Up to six arguments.  */
+
+
+#ifdef __ASSEMBLY__
+
+/* The size of a state save frame.  */
+#define STATE_SAVE_SIZE		(PT_SIZE + STATE_SAVE_ARG_SPACE)
+
+#else /* !__ASSEMBLY__ */
+
+/* The size of a state save frame.  */
+#define STATE_SAVE_SIZE	       (sizeof (struct pt_regs) + STATE_SAVE_ARG_SPACE)
+
+#endif /* __ASSEMBLY__ */
+
+
+/* Offset of the struct pt_regs in a state save frame.  */
+#define STATE_SAVE_PT_OFFSET	STATE_SAVE_ARG_SPACE
+
+
+#endif /* __V850_ENTRY_H__ */
diff -Nru a/include/asm-v850/errno.h b/include/asm-v850/errno.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/errno.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,6 @@
+#ifndef __V850_ERRNO_H__
+#define __V850_ERRNO_H__
+
+#include <asm-generic/errno.h>
+
+#endif /* __V850_ERRNO_H__ */
diff -Nru a/include/asm-v850/fcntl.h b/include/asm-v850/fcntl.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/fcntl.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,86 @@
+#ifndef __V850_FCNTL_H__
+#define __V850_FCNTL_H__
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+   located on an ext2 file system */
+#define O_ACCMODE	  0003
+#define O_RDONLY	    00
+#define O_WRONLY	    01
+#define O_RDWR		    02
+#define O_CREAT		  0100	/* not fcntl */
+#define O_EXCL		  0200	/* not fcntl */
+#define O_NOCTTY	  0400	/* not fcntl */
+#define O_TRUNC		 01000	/* not fcntl */
+#define O_APPEND	 02000
+#define O_NONBLOCK	 04000
+#define O_NDELAY	O_NONBLOCK
+#define O_SYNC		010000
+#define FASYNC		020000	/* fcntl, for BSD compatibility */
+#define O_DIRECTORY	040000	/* must be a directory */
+#define O_NOFOLLOW     0100000	/* don't follow links */
+#define O_DIRECT       0200000	/* direct disk access hint - currently ignored */
+#define O_LARGEFILE    0400000
+
+#define F_DUPFD		0	/* dup */
+#define F_GETFD		1	/* get close_on_exec */
+#define F_SETFD		2	/* set/clear close_on_exec */
+#define F_GETFL		3	/* get file->f_flags */
+#define F_SETFL		4	/* set file->f_flags */
+#define F_GETLK		5
+#define F_SETLK		6
+#define F_SETLKW	7
+
+#define F_SETOWN	8	/*  for sockets. */
+#define F_GETOWN	9	/*  for sockets. */
+#define F_SETSIG	10	/*  for sockets. */
+#define F_GETSIG	11	/*  for sockets. */
+
+#define F_GETLK64	12	/*  using 'struct flock64' */
+#define F_SETLK64	13
+#define F_SETLKW64	14
+
+/* for F_[GET|SET]FL */
+#define FD_CLOEXEC	1	/* actually anything with low bit set goes */
+
+/* for posix fcntl() and lockf() */
+#define F_RDLCK		0
+#define F_WRLCK		1
+#define F_UNLCK		2
+
+/* for old implementation of bsd flock () */
+#define F_EXLCK		4	/* or 3 */
+#define F_SHLCK		8	/* or 4 */
+
+/* for leases */
+#define F_INPROGRESS	16
+
+/* operations for bsd flock(), also used by the kernel implementation */
+#define LOCK_SH		1	/* shared lock */
+#define LOCK_EX		2	/* exclusive lock */
+#define LOCK_NB		4	/* or'd with one of the above to prevent
+				   blocking */
+#define LOCK_UN		8	/* remove lock */
+
+#define LOCK_MAND	32	/* This is a mandatory flock */
+#define LOCK_READ	64	/* ... Which allows concurrent read operations */
+#define LOCK_WRITE	128	/* ... Which allows concurrent write operations */
+#define LOCK_RW		192	/* ... Which allows concurrent read & write ops */
+
+struct flock {
+	short l_type;
+	short l_whence;
+	off_t l_start;
+	off_t l_len;
+	pid_t l_pid;
+};
+
+struct flock64 {
+	short  l_type;
+	short  l_whence;
+	loff_t l_start;
+	loff_t l_len;
+	pid_t  l_pid;
+};
+
+#define F_LINUX_SPECIFIC_BASE	1024
+#endif /* __V850_FCNTL_H__ */
diff -Nru a/include/asm-v850/fpga85e2c.h b/include/asm-v850/fpga85e2c.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/fpga85e2c.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,107 @@
+/*
+ * include/asm-v850/fpga85e2c.h -- Machine-dependent defs for
+ *	FPGA implementation of V850E2/NA85E2C
+ *
+ *  Copyright (C) 2002  NEC Corporation
+ *  Copyright (C) 2002  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_FPGA85E2C_H__
+#define __V850_FPGA85E2C_H__
+
+
+#include <asm/clinkage.h>
+
+
+#define CPU_ARCH		"v850e2"
+#define CPU_MODEL		"FPGA NA85E2C/V850E2"
+
+
+/* `external ram'.  */
+#define ERAM_ADDR		0
+#define ERAM_SIZE		0x00100000 /* 1MB */
+
+
+/* FPGA specific control registers.  */
+
+/* Writing a non-zero value to FLGREG(0) will signal the controlling CPU
+   to stop execution.  */
+#define FLGREG_ADDR(n)		(0xFFE80100 + 2*(n))
+#define FLGREG(n)		(*(volatile unsigned char *)FLGREG_ADDR (n))
+#define FLGREG_NUM		2
+
+#define CSDEV_ADDR(n)		(0xFFE80110 + 2*(n))
+#define CSDEV(n)		(*(volatile unsigned char *)CSDEV_ADDR (n))
+
+/* The BSC register controls bus-sizing.  Each memory area CSn uses a pair
+   of bits N*2 and N*2+1, where 00 means an 8-bit bus size, 01 16-bit, and
+   10 32-bit.  */
+#define BSC_ADDR		0xFFFFF066
+#define BSC			(*(volatile unsigned short *)BSC_ADDR)
+
+#define DWC_ADDR(n)		(0xFFFFF484 + 2*(n))
+#define DWC(n)			(*(volatile unsigned short *)DWC_ADDR (n))
+
+#define ASC_ADDR		0xFFFFF48A
+#define ASC			(*(volatile unsigned short *)ASC_ADDR)
+
+#define BTSC_ADDR		0xFFFFF070
+#define BTSC			(*(volatile unsigned short *)BTSC_ADDR)
+
+#define BHC_ADDR		0xFFFFF06A
+#define BHC			(*(volatile unsigned short *)BHC_ADDR)
+
+
+/* NB85E-style interrupt system.  */
+#include <asm/nb85e_intc.h>
+
+/* Timer interrupts 0-3, interrupt at intervals from CLK/4096 to CLK/16384.  */
+#define IRQ_RPU(n)		(60 + (n))
+#define IRQ_RPU_NUM		4
+
+/* For <asm/irq.h> */
+#define NUM_CPU_IRQS		64
+
+
+/* General-purpose timer.  */
+/* control/status register (can only be read/written via bit insns) */
+#define RPU_GTMC_ADDR		0xFFFFFB00
+#define RPU_GTMC		(*(volatile unsigned char *)RPU_GTMC_ADDR)
+#define RPU_GTMC_CE_BIT		7 /* clock enable (control) */
+#define RPU_GTMC_OV_BIT		6 /* overflow (status) */
+#define RPU_GTMC_CLK_BIT	1 /* 0 = .5 MHz CLK, 1 = 1 Mhz (control) */
+/* 32-bit count (8 least-significant bits are always zero).  */
+#define RPU_GTM_ADDR		0xFFFFFB28
+#define RPU_GTM			(*(volatile unsigned long *)RPU_GTMC_ADDR)
+
+
+/* For <asm/page.h> */
+#define PAGE_OFFSET		ERAM_ADDR /* minimum allocatable address */
+
+
+/* For <asm/entry.h> */
+/* `R0 RAM', used for a few miscellaneous variables that must be accessible
+   using a load instruction relative to R0.  The FPGA implementation
+   actually has no on-chip RAM, so we use part of main ram just after the
+   interrupt vectors.  */
+#ifdef __ASSEMBLY__
+#define R0_RAM_ADDR		lo(C_SYMBOL_NAME(_r0_ram))
+#else
+extern char _r0_ram;
+#define R0_RAM_ADDR		((unsigned long)&_r0_ram);
+#endif
+
+
+/* For <asm/param.h> */
+#ifndef HZ
+#define HZ			122 /* actually, 8.192ms ticks =~ 122.07 */
+#endif
+
+
+#endif /* __V850_FPGA85E2C_H__ */
diff -Nru a/include/asm-v850/gbus_int.h b/include/asm-v850/gbus_int.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/gbus_int.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,97 @@
+/*
+ * include/asm-v850/gbus_int.h -- Midas labs GBUS interrupt support
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_GBUS_INT_H__
+#define __V850_GBUS_INT_H__
+
+
+/* The GBUS interrupt interface has 32 interrupts shared among 4
+   processor interrupts.  The 32 GBUS interrupts are divided into two
+   sets of 16 each, for allocating among control registers, etc (there
+   are two of each control register, with bits 0-15 controlling an
+   interrupt each).  */
+
+/* The GBUS interrupts themselves.  */
+#define IRQ_GBUS_INT(n)		(GBUS_INT_BASE_IRQ + (n))
+#define IRQ_GBUS_INT_NUM	32
+
+/* Control registers.  */
+#define GBUS_INT_STATUS_ADDR(w)	(GBUS_INT_BASE_ADDR + (w)*0x40)
+#define GBUS_INT_STATUS(w)	(*(volatile u16 *)GBUS_INT_STATUS_ADDR(w))
+#define GBUS_INT_CLEAR_ADDR(w)	(GBUS_INT_BASE_ADDR + 0x10 + (w)*0x40)
+#define GBUS_INT_CLEAR(w)	(*(volatile u16 *)GBUS_INT_CLEAR_ADDR(w))
+#define GBUS_INT_EDGE_ADDR(w)	(GBUS_INT_BASE_ADDR + 0x20 + (w)*0x40)
+#define GBUS_INT_EDGE(w)	(*(volatile u16 *)GBUS_INT_EDGE_ADDR(w))
+#define GBUS_INT_POLARITY_ADDR(w)	(GBUS_INT_BASE_ADDR + 0x30 + (w)*0x40)
+#define GBUS_INT_POLARITY(w)	(*(volatile u16 *)GBUS_INT_POLARITY_ADDR(w))
+/* This allows enabling interrupt bits in word W for interrupt GINTn.  */
+#define GBUS_INT_ENABLE_ADDR(w, n) \
+   (GBUS_INT_BASE_ADDR + 0x100 + (w)*0x10 + (n)*0x20)
+#define GBUS_INT_ENABLE(w, n)	(*(volatile u16 *)GBUS_INT_ENABLE_ADDR(w, n))
+
+/* Mapping between kernel interrupt numbers and hardware control regs/bits.  */
+#define GBUS_INT_BITS_PER_WORD	16
+#define GBUS_INT_NUM_WORDS	(IRQ_GBUS_INT_NUM / GBUS_INT_BITS_PER_WORD)
+#define GBUS_INT_IRQ_WORD(irq)	(((irq) - GBUS_INT_BASE_IRQ) >> 4)
+#define GBUS_INT_IRQ_BIT(irq)	(((irq) - GBUS_INT_BASE_IRQ) & 0xF)
+#define GBUS_INT_IRQ_MASK(irq)	(1 << GBUS_INT_IRQ_BIT(irq))
+
+
+/* Possible priorities for GBUS interrupts.  */
+#define GBUS_INT_PRIORITY_HIGH		2
+#define GBUS_INT_PRIORITY_MEDIUM	4
+#define GBUS_INT_PRIORITY_LOW		6
+
+
+#ifndef __ASSEMBLY__
+
+/* Enable interrupt handling for interrupt IRQ.  */
+extern void gbus_int_enable_irq (unsigned irq);
+/* Disable interrupt handling for interrupt IRQ.  Note that any
+   interrupts received while disabled will be delivered once the
+   interrupt is enabled again, unless they are explicitly cleared using
+   `gbus_int_clear_pending_irq'.  */
+extern void gbus_int_disable_irq (unsigned irq);
+/* Return true if interrupt handling for interrupt IRQ is enabled.  */
+extern int gbus_int_irq_enabled (unsigned irq);
+/* Disable all GBUS irqs.  */
+extern int gbus_int_disable_irqs (void);
+/* Clear any pending interrupts for IRQ.  */
+extern void gbus_int_clear_pending_irq (unsigned irq);
+/* Return true if interrupt IRQ is pending (but disabled).  */
+extern int gbus_int_irq_pending (unsigned irq);
+
+
+struct gbus_int_irq_init {
+	const char *name;	/* name of interrupt type */
+
+	/* Range of kernel irq numbers for this type:
+	   BASE, BASE+INTERVAL, ..., BASE+INTERVAL*NUM  */
+	unsigned base, num, interval;
+
+	unsigned priority;	/* interrupt priority to assign */
+};
+struct hw_interrupt_type;	/* fwd decl */
+
+/* Initialize HW_IRQ_TYPES for GBUS irqs described in array
+   INITS (which is terminated by an entry with the name field == 0).  */
+extern void gbus_int_init_irq_types (struct gbus_int_irq_init *inits,
+				     struct hw_interrupt_type *hw_irq_types);
+
+/* Initialize GBUS interrupts.  */
+extern void gbus_int_init_irqs (void);
+
+#endif /* !__ASSEMBLY__ */
+
+
+#endif /* __V850_GBUS_INT_H__ */
diff -Nru a/include/asm-v850/hardirq.h b/include/asm-v850/hardirq.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/hardirq.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,96 @@
+#ifndef __V850_HARDIRQ_H__
+#define __V850_HARDIRQ_H__
+
+#include <linux/config.h>
+#include <linux/threads.h>
+
+typedef struct {
+	unsigned int __softirq_pending;
+	unsigned int __syscall_count;
+	struct task_struct * __ksoftirqd_task;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
+
+/*
+ * We put the hardirq and softirq counter into the preemption
+ * counter. The bitmask has the following meaning:
+ *
+ * - bits 0-7 are the preemption count (max preemption depth: 256)
+ * - bits 8-15 are the softirq count (max # of softirqs: 256)
+ * - bits 16-23 are the hardirq count (max # of hardirqs: 256)
+ *
+ * - ( bit 26 is the PREEMPT_ACTIVE flag. )
+ *
+ * PREEMPT_MASK: 0x000000ff
+ * HARDIRQ_MASK: 0x0000ff00
+ * SOFTIRQ_MASK: 0x00ff0000
+ */
+
+#define PREEMPT_BITS	8
+#define SOFTIRQ_BITS	8
+#define HARDIRQ_BITS	8
+
+#define PREEMPT_SHIFT	0
+#define SOFTIRQ_SHIFT	(PREEMPT_SHIFT + PREEMPT_BITS)
+#define HARDIRQ_SHIFT	(SOFTIRQ_SHIFT + SOFTIRQ_BITS)
+
+#define __MASK(x)	((1UL << (x))-1)
+
+#define PREEMPT_MASK	(__MASK(PREEMPT_BITS) << PREEMPT_SHIFT)
+#define HARDIRQ_MASK	(__MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT)
+#define SOFTIRQ_MASK	(__MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT)
+
+#define hardirq_count()	(preempt_count() & HARDIRQ_MASK)
+#define softirq_count()	(preempt_count() & SOFTIRQ_MASK)
+#define irq_count()	(preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK))
+
+#define PREEMPT_OFFSET	(1UL << PREEMPT_SHIFT)
+#define SOFTIRQ_OFFSET	(1UL << SOFTIRQ_SHIFT)
+#define HARDIRQ_OFFSET	(1UL << HARDIRQ_SHIFT)
+
+/*
+ * The hardirq mask has to be large enough to have
+ * space for potentially all IRQ sources in the system
+ * nesting on a single CPU:
+ */
+#if (1 << HARDIRQ_BITS) < NR_IRQS
+# error HARDIRQ_BITS is too low!
+#endif
+
+/*
+ * Are we doing bottom half or hardware interrupt processing?
+ * Are we in a softirq context? Interrupt context?
+ */
+#define in_irq()		(hardirq_count())
+#define in_softirq()		(softirq_count())
+#define in_interrupt()		(irq_count())
+
+#define hardirq_trylock()	(!in_interrupt())
+#define hardirq_endlock()	do { } while (0)
+
+#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
+
+#if CONFIG_PREEMPT
+# define in_atomic()    (preempt_count() != kernel_locked())
+# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
+#else
+# define in_atomic()    (preempt_count() != 0)
+# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
+#endif
+
+#define irq_exit()							\
+do {									\
+		preempt_count() -= IRQ_EXIT_OFFSET;			\
+		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
+			do_softirq();					\
+		preempt_enable_no_resched();				\
+} while (0)
+
+#ifndef CONFIG_SMP
+# define synchronize_irq(irq)	barrier()
+#else
+# error v850nommu SMP is not available
+#endif /* CONFIG_SMP */
+
+#endif /* __V850_HARDIRQ_H__ */
diff -Nru a/include/asm-v850/highres_timer.h b/include/asm-v850/highres_timer.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/highres_timer.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,44 @@
+/*
+ * include/asm-v850/highres_timer.h -- High resolution timing routines
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_HIGHRES_TIMER_H__
+#define __V850_HIGHRES_TIMER_H__
+
+#ifndef __ASSEMBLY__
+#include <linux/time.h>
+#endif
+
+#include <asm/entry.h>
+
+
+/* Frequency of the `slow ticks' (one tick each time the fast-tick
+   counter overflows).  */
+#define HIGHRES_TIMER_SLOW_TICK_RATE	25
+
+/* Which timer in the nb85e `Timer D' we use.  */
+#define HIGHRES_TIMER_TIMER_D_UNIT	3
+
+
+#ifndef __ASSEMBLY__
+
+extern void highres_timer_start (void), highres_timer_stop (void);
+extern void highres_timer_reset (void);
+extern void highres_timer_read_ticks (u32 *slow_ticks, u32 *fast_ticks);
+extern void highres_timer_ticks_to_timeval (u32 slow_ticks, u32 fast_ticks,
+					    struct timeval *tv);
+extern void highres_timer_read (struct timeval *tv);
+
+#endif /* !__ASSEMBLY__ */
+
+
+#endif /* __V850_HIGHRES_TIMER_H__ */
diff -Nru a/include/asm-v850/hw_irq.h b/include/asm-v850/hw_irq.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/hw_irq.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,8 @@
+#ifndef __V850_HW_IRQ_H__
+#define __V850_HW_IRQ_H__
+
+extern inline void hw_resend_irq (struct hw_interrupt_type *h, unsigned int i)
+{
+}
+
+#endif /* __V850_HW_IRQ_H__ */
diff -Nru a/include/asm-v850/io.h b/include/asm-v850/io.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/io.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,106 @@
+/*
+ * include/asm-v850/io.h -- Misc I/O operations
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_IO_H__
+#define __V850_IO_H__
+
+#define IO_SPACE_LIMIT 0xFFFFFFFF
+
+#define readb(addr) \
+  ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; })
+#define readw(addr) \
+  ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; })
+#define readl(addr) \
+  ({ unsigned long __v = (*(volatile unsigned long *) (addr)); __v; })
+
+#define writeb(b, addr) \
+  (void)((*(volatile unsigned char *) (addr)) = (b))
+#define writew(b, addr) \
+  (void)((*(volatile unsigned short *) (addr)) = (b))
+#define writel(b, addr) \
+  (void)((*(volatile unsigned int *) (addr)) = (b))
+
+#define inb(addr)	readb (addr)
+#define inw(addr)	readw (addr)
+#define inl(addr)	readl (addr)
+#define outb(x, addr)	((void) writeb (x, addr))
+#define outw(x, addr)	((void) writew (x, addr))
+#define outl(x, addr)	((void) writel (x, addr))
+
+#define inb_p(port)		inb((port))
+#define outb_p(val, port)	outb((val), (port))
+#define inw_p(port)		inw((port))
+#define outw_p(val, port)	outw((val), (port))
+#define inl_p(port)		inl((port))
+#define outl_p(val, port)	outl((val), (port))
+
+static inline void insb (unsigned long port, void *dst, unsigned long count)
+{
+	unsigned char *p = dst;
+	while (count--)
+		*p++ = inb (port);
+}
+static inline void insw (unsigned long port, void *dst, unsigned long count)
+{
+	unsigned short *p = dst;
+	while (count--)
+		*p++ = inw (port);
+}
+static inline void insl (unsigned long port, void *dst, unsigned long count)
+{
+	unsigned long *p = dst;
+	while (count--)
+		*p++ = inl (port);
+}
+
+static inline void
+outsb (unsigned long port, const void *src, unsigned long count)
+{
+	const unsigned char *p = src;
+	while (count--)
+		outb (*p++, port);
+}
+static inline void
+outsw (unsigned long port, const void *src, unsigned long count)
+{
+	const unsigned short *p = src;
+	while (count--)
+		outw (*p++, port);
+}
+static inline void
+outsl (unsigned long port, const void *src, unsigned long count)
+{
+	const unsigned long *p = src;
+	while (count--)
+		outl (*p++, port);
+}
+
+#define iounmap(addr)				((void)0)
+#define ioremap(physaddr, size)			(physaddr)
+#define ioremap_nocache(physaddr, size)		(physaddr)
+#define ioremap_writethrough(physaddr, size)	(physaddr)
+#define ioremap_fullcache(physaddr, size)	(physaddr)
+
+#define page_to_phys(page)      ((page - mem_map) << PAGE_SHIFT)
+#if 0
+/* This is really stupid; don't define it.  */
+#define page_to_bus(page)       page_to_phys (page)
+#endif
+
+/* Conversion between virtual and physical mappings.  */
+#define mm_ptov(addr)		((void *)__phys_to_virt (addr))
+#define mm_vtop(addr)		((unsigned long)__virt_to_phys (addr))
+#define phys_to_virt(addr)	((void *)__phys_to_virt (addr))
+#define virt_to_phys(addr)	((unsigned long)__virt_to_phys (addr))
+
+#endif /* __V850_IO_H__ */
diff -Nru a/include/asm-v850/ioctl.h b/include/asm-v850/ioctl.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/ioctl.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,80 @@
+/* $Id: ioctl.h,v 1.1 2002/09/28 14:58:41 gerg Exp $
+ *
+ * linux/ioctl.h for Linux by H.H. Bergman.
+ */
+
+#ifndef _V850_IOCTL_H
+#define _V850_IOCTL_H
+
+/* ioctl command encoding: 32 bits total, command in lower 16 bits,
+ * size of the parameter structure in the lower 14 bits of the
+ * upper 16 bits.
+ * Encoding the size of the parameter structure in the ioctl request
+ * is useful for catching programs compiled with old versions
+ * and to avoid overwriting user space outside the user buffer area.
+ * The highest 2 bits are reserved for indicating the ``access mode''.
+ * NOTE: This limits the max parameter size to 16kB -1 !
+ */
+
+/*
+ * I don't really have any idea about what this should look like, so
+ * for the time being, this is heavily based on the PC definitions.
+ */
+
+/*
+ * The following is for compatibility across the various Linux
+ * platforms.  The i386 ioctl numbering scheme doesn't really enforce
+ * a type field.  De facto, however, the top 8 bits of the lower 16
+ * bits are indeed used as a type field, so we might just as well make
+ * this explicit here.  Please be sure to use the decoding macros
+ * below from now on.
+ */
+#define _IOC_NRBITS	8
+#define _IOC_TYPEBITS	8
+#define _IOC_SIZEBITS	14
+#define _IOC_DIRBITS	2
+
+#define _IOC_NRMASK	((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK	((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK	((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK	((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT	0
+#define _IOC_TYPESHIFT	(_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT	(_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT	(_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits.
+ */
+#define _IOC_NONE	0U
+#define _IOC_WRITE	1U
+#define _IOC_READ	2U
+
+#define _IOC(dir,type,nr,size) \
+	(((dir)  << _IOC_DIRSHIFT) | \
+	 ((type) << _IOC_TYPESHIFT) | \
+	 ((nr)   << _IOC_NRSHIFT) | \
+	 ((size) << _IOC_SIZESHIFT))
+
+/* used to create numbers */
+#define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+/* used to decode ioctl numbers.. */
+#define _IOC_DIR(nr)		(((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr)		(((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr)		(((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr)		(((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+/* ...and for the drivers/sound files... */
+
+#define IOC_IN		(_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT		(_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT	((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK	(_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT	(_IOC_SIZESHIFT)
+
+#endif /* __V850_IOCTL_H__ */
diff -Nru a/include/asm-v850/ioctls.h b/include/asm-v850/ioctls.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/ioctls.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,81 @@
+#ifndef __V850_IOCTLS_H__
+#define __V850_IOCTLS_H__
+
+#include <asm/ioctl.h>
+
+/* 0x54 is just a magic number to make these relatively unique ('T') */
+
+#define TCGETS		0x5401
+#define TCSETS		0x5402
+#define TCSETSW		0x5403
+#define TCSETSF		0x5404
+#define TCGETA		0x5405
+#define TCSETA		0x5406
+#define TCSETAW		0x5407
+#define TCSETAF		0x5408
+#define TCSBRK		0x5409
+#define TCXONC		0x540A
+#define TCFLSH		0x540B
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+#define TIOCGPGRP	0x540F
+#define TIOCSPGRP	0x5410
+#define TIOCOUTQ	0x5411
+#define TIOCSTI		0x5412
+#define TIOCGWINSZ	0x5413
+#define TIOCSWINSZ	0x5414
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define FIONREAD	0x541B
+#define TIOCINQ		FIONREAD
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT		0x5420
+#define FIONBIO		0x5421
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425	/* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT	0x5426  /* For debugging only */
+#define TIOCSBRK	0x5427  /* BSD compatibility */
+#define TIOCCBRK	0x5428  /* BSD compatibility */
+#define TIOCGSID	0x5429  /* Return the session ID of FD */
+#define TIOCGPTN	_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define TIOCSPTLCK	_IOW('T',0x31, int)  /* Lock/unlock Pty */
+
+#define FIONCLEX	0x5450  /* these numbers need to be adjusted. */
+#define FIOCLEX		0x5451
+#define FIOASYNC	0x5452
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
+#define TIOCSERGETLSR   0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
+#define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+#define FIOQSIZE	0x545E
+
+/* Used for packet mode */
+#define TIOCPKT_DATA		 0
+#define TIOCPKT_FLUSHREAD	 1
+#define TIOCPKT_FLUSHWRITE	 2
+#define TIOCPKT_STOP		 4
+#define TIOCPKT_START		 8
+#define TIOCPKT_NOSTOP		16
+#define TIOCPKT_DOSTOP		32
+
+#define TIOCSER_TEMT    0x01	/* Transmitter physically empty */
+
+#endif /* __V850_IOCTLS_H__ */
diff -Nru a/include/asm-v850/ipc.h b/include/asm-v850/ipc.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/ipc.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,31 @@
+#ifndef __V850_IPC_H__
+#define __V850_IPC_H__
+
+/* 
+ * These are used to wrap system calls on v850.
+ *
+ * See arch/v850/kernel/syscalls.c for ugly details..
+ */
+struct ipc_kludge {
+	struct msgbuf *msgp;
+	long msgtyp;
+};
+
+#define SEMOP		 1
+#define SEMGET		 2
+#define SEMCTL		 3
+#define MSGSND		11
+#define MSGRCV		12
+#define MSGGET		13
+#define MSGCTL		14
+#define SHMAT		21
+#define SHMDT		22
+#define SHMGET		23
+#define SHMCTL		24
+
+/* Used by the DIPC package, try and avoid reusing it */
+#define DIPC		25
+
+#define IPCCALL(version,op)	((version)<<16 | (op))
+
+#endif /* __V850_IPC_H__ */
diff -Nru a/include/asm-v850/ipcbuf.h b/include/asm-v850/ipcbuf.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/ipcbuf.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,29 @@
+#ifndef __V850E_IPCBUF_H__
+#define __V850E_IPCBUF_H__
+
+/*
+ * The user_ipc_perm structure for v850e architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct ipc64_perm
+{
+	__kernel_key_t		key;
+	__kernel_uid32_t	uid;
+	__kernel_gid32_t	gid;
+	__kernel_uid32_t	cuid;
+	__kernel_gid32_t	cgid;
+	__kernel_mode_t		mode;
+	unsigned short		__pad1;
+	unsigned short		seq;
+	unsigned short		__pad2;
+	unsigned long		__unused1;
+	unsigned long		__unused2;
+};
+
+#endif /* __V850E_IPCBUF_H__ */
diff -Nru a/include/asm-v850/irq.h b/include/asm-v850/irq.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/irq.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,57 @@
+/*
+ * include/asm-v850/irq.h -- Machine interrupt handling
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_IRQ_H__
+#define __V850_IRQ_H__
+
+#include <asm/machdep.h>
+
+/* Default NUM_MACH_IRQS.  */
+#ifndef NUM_MACH_IRQS
+#define NUM_MACH_IRQS	NUM_CPU_IRQS
+#endif
+
+/* NMIs have IRQ numbers from FIRST_NMI to FIRST_NMI+NUM_NMIS-1.  */
+#define FIRST_NMI	NUM_MACH_IRQS
+#define IRQ_NMI(n)	(FIRST_NMI + (n))
+/* v850 processors have 3 non-maskable interrupts.  */
+#define NUM_NMIS	3
+
+/* Includes both maskable and non-maskable irqs.  */
+#define NR_IRQS		(NUM_MACH_IRQS + NUM_NMIS)
+
+
+#ifndef __ASSEMBLY__
+
+struct pt_regs;
+struct hw_interrupt_type;
+struct irqaction;
+
+#define irq_cannonicalize(irq)	(irq)
+
+/* Initialize irq handling for IRQs.
+   BASE_IRQ, BASE_IRQ+INTERVAL, ..., BASE_IRQ+NUM*INTERVAL
+   to IRQ_TYPE.  An IRQ_TYPE of 0 means to use a generic interrupt type.  */
+extern void
+init_irq_handlers (int base_irq, int num, int interval,
+		   struct hw_interrupt_type *irq_type);
+
+typedef void (*irq_handler_t)(int irq, void *data, struct pt_regs *regs);
+
+/* Handle interrupt IRQ.  REGS are the registers at the time of ther
+   interrupt.  */
+extern unsigned int handle_irq (int irq, struct pt_regs *regs);
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __V850_IRQ_H__ */
diff -Nru a/include/asm-v850/kmap_types.h b/include/asm-v850/kmap_types.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/kmap_types.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,19 @@
+#ifndef __V850_KMAP_TYPES_H__
+#define __V850_KMAP_TYPES_H__
+
+enum km_type {
+	KM_BOUNCE_READ,
+	KM_SKB_SUNRPC_DATA,
+	KM_SKB_DATA_SOFTIRQ,
+	KM_USER0,
+	KM_USER1,
+	KM_BIO_SRC_IRQ,
+	KM_BIO_DST_IRQ,
+	KM_PTE0,
+	KM_PTE1,
+	KM_IRQ0,
+	KM_IRQ1,
+	KM_TYPE_NR
+};
+
+#endif /* __V850_KMAP_TYPES_H__ */
diff -Nru a/include/asm-v850/linkage.h b/include/asm-v850/linkage.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/linkage.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,6 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+/* Nothing to see here... */
+
+#endif
diff -Nru a/include/asm-v850/ma.h b/include/asm-v850/ma.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/ma.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,102 @@
+/*
+ * include/asm-v850/ma.h -- V850E/MA series of cpu chips
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_MA_H__
+#define __V850_MA_H__
+
+
+/* The MA series uses the NB85E cpu core.  */
+#include <asm/nb85e.h>
+
+
+/* For <asm/entry.h> */
+/* We use on-chip RAM, for a few miscellaneous variables that must be
+   accessible using a load instruction relative to R0.  The amount
+   varies between chip models, but there's always at least 4K, and it
+   should always start at FFFFC000.  */
+#define R0_RAM_ADDR			0xFFFFC000
+
+
+/* MA series UART details.  */
+#define NB85E_UART_BASE_FREQ		CPU_CLOCK_FREQ
+
+/* This is a function that gets called before configuring the UART.  */
+#define NB85E_UART_PRE_CONFIGURE	ma_uart_pre_configure
+#ifndef __ASSEMBLY__
+extern void ma_uart_pre_configure (unsigned chan,
+				   unsigned cflags, unsigned baud);
+#endif
+
+
+/* MA series timer C details.  */
+#define NB85E_TIMER_C_BASE_ADDR		0xFFFFF600
+
+
+/* MA series timer D details.  */
+#define NB85E_TIMER_D_BASE_ADDR		0xFFFFF540
+#define NB85E_TIMER_D_TMD_BASE_ADDR 	(NB85E_TIMER_D_BASE_ADDR + 0x0)
+#define NB85E_TIMER_D_CMD_BASE_ADDR 	(NB85E_TIMER_D_BASE_ADDR + 0x2)
+#define NB85E_TIMER_D_TMCD_BASE_ADDR 	(NB85E_TIMER_D_BASE_ADDR + 0x4)
+
+#define NB85E_TIMER_D_BASE_FREQ		CPU_CLOCK_FREQ
+
+
+/* Port 0 */
+/* Direct I/O.  Bits 0-7 are pins P00-P07.  */
+#define MA_PORT0_IO_ADDR		0xFFFFF400
+#define MA_PORT0_IO			(*(volatile u8 *)MA_PORT0_IO_ADDR)
+/* Port mode (for direct I/O, 0 = output, 1 = input).  */
+#define MA_PORT0_PM_ADDR		0xFFFFF420
+#define MA_PORT0_PM			(*(volatile u8 *)MA_PORT0_PM_ADDR)
+/* Port mode control (0 = direct I/O mode, 1 = alternative I/O mode).  */
+#define MA_PORT0_PMC_ADDR		0xFFFFF440
+#define MA_PORT0_PMC			(*(volatile u8 *)MA_PORT0_PMC_ADDR)
+/* Port function control (for P04-P07, 0 = IRQ, 1 = DMARQ).  */
+#define MA_PORT0_PFC_ADDR		0xFFFFF460
+#define MA_PORT0_PFC			(*(volatile u8 *)MA_PORT0_PFC_ADDR)
+
+/* Port 1 */
+/* Direct I/O.  Bits 0-3 are pins P10-P13.  */
+#define MA_PORT1_IO_ADDR		0xFFFFF402
+#define MA_PORT1_IO			(*(volatile u8 *)MA_PORT1_IO_ADDR)
+/* Port mode (for direct I/O, 0 = output, 1 = input).  */
+#define MA_PORT1_PM_ADDR		0xFFFFF420
+#define MA_PORT1_PM			(*(volatile u8 *)MA_PORT1_PM_ADDR)
+/* Port mode control (0 = direct I/O mode, 1 = alternative I/O mode).  */
+#define MA_PORT1_PMC_ADDR		0xFFFFF442
+#define MA_PORT1_PMC			(*(volatile u8 *)MA_PORT1_PMC_ADDR)
+
+/* Port 4 */
+/* Direct I/O.  Bits 0-5 are pins P40-P45.  */
+#define MA_PORT4_IO_ADDR		0xFFFFF408
+#define MA_PORT4_IO			(*(volatile u8 *)MA_PORT4_IO_ADDR)
+/* Port mode (for direct I/O, 0 = output, 1 = input).  */
+#define MA_PORT4_PM_ADDR		0xFFFFF428
+#define MA_PORT4_PM			(*(volatile u8 *)MA_PORT4_PM_ADDR)
+/* Port mode control (0 = direct I/O mode, 1 = alternative I/O mode).  */
+#define MA_PORT4_PMC_ADDR		0xFFFFF448
+#define MA_PORT4_PMC			(*(volatile u8 *)MA_PORT4_PMC_ADDR)
+/* Port function control (for serial interfaces, 0 = CSI, 1 = UART).  */
+#define MA_PORT4_PFC_ADDR		0xFFFFF468
+#define MA_PORT4_PFC			(*(volatile u8 *)MA_PORT4_PFC_ADDR)
+
+
+#ifndef __ASSEMBLY__
+
+/* Initialize MA chip interrupts.  */
+extern void ma_init_irqs (void);
+
+#endif /* !__ASSEMBLY__ */
+
+
+#endif /* __V850_MA_H__ */
diff -Nru a/include/asm-v850/ma1.h b/include/asm-v850/ma1.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/ma1.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,51 @@
+/*
+ * include/asm-v850/ma1.h -- V850E/MA1 cpu chip
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_MA1_H__
+#define __V850_MA1_H__
+
+/* Inherit more generic details from MA series.  */
+#include <asm/ma.h>
+
+
+#define CPU_MODEL	"v850e/ma1"
+#define CPU_MODEL_LONG	"NEC V850E/MA1"
+
+
+/* Hardware-specific interrupt numbers (in the kernel IRQ namespace).  */
+#define IRQ_INTOV(n)	(n)	/* 0-3 */
+#define IRQ_INTOV_NUM	4
+#define IRQ_INTP(n)	(0x4  + (n)) /* Pnnn (pin) interrupts */
+#define IRQ_INTP_NUM	24
+#define IRQ_INTCMD(n)	(0x1c + (n)) /* interval timer interrupts 0-3 */
+#define IRQ_INTCMD_NUM	4
+#define IRQ_INTDMA(n)	(0x20 + (n)) /* DMA interrupts 0-3 */
+#define IRQ_INTDMA_NUM	4
+#define IRQ_INTCSI(n)	(0x24 + (n)*4)/* CSI 0-2 transmit/receive completion */
+#define IRQ_INTCSI_NUM	3
+#define IRQ_INTSER(n)	(0x25 + (n)*4) /* UART 0-2 reception error */
+#define IRQ_INTSER_NUM	3
+#define IRQ_INTSR(n)	(0x26 + (n)*4) /* UART 0-2 reception completion */
+#define IRQ_INTSR_NUM	3
+#define IRQ_INTST(n)	(0x27 + (n)*4) /* UART 0-2 transmission completion */
+#define IRQ_INTST_NUM	3
+
+/* For <asm/irq.h> */
+#define NUM_CPU_IRQS	0x30
+
+
+/* The MA1 has a UART with 3 channels.  */
+#define NB85E_UART_NUM_CHANNELS	3
+
+
+#endif /* __V850_MA1_H__ */
diff -Nru a/include/asm-v850/machdep.h b/include/asm-v850/machdep.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/machdep.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,49 @@
+/*
+ * include/asm-v850/machdep.h -- Machine-dependent definitions
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_MACHDEP_H__
+#define __V850_MACHDEP_H__
+
+#include <linux/config.h>
+
+/* chips */
+#ifdef CONFIG_V850E_MA1
+#include <asm/ma1.h>
+#endif
+#ifdef CONFIG_V850E_TEG
+#include <asm/teg.h>
+#endif
+
+/* Anna is both a chip _and_ a platform, so put it in the middle... */
+#ifdef CONFIG_V850E2_ANNA
+#include <asm/anna.h>
+#endif
+
+/* platforms */
+#ifdef CONFIG_RTE_CB_MA1
+#include <asm/rte_ma1_cb.h>
+#endif
+#ifdef CONFIG_RTE_CB_NB85E
+#include <asm/rte_nb85e_cb.h>
+#endif
+#ifdef CONFIG_V850E_SIM
+#include <asm/sim.h>
+#endif
+#ifdef CONFIG_V850E2_SIM85E2C
+#include <asm/sim85e2c.h>
+#endif
+#ifdef CONFIG_V850E2_FPGA85E2C
+#include <asm/fpga85e2c.h>
+#endif
+
+#endif /* __V850_MACHDEP_H__ */
diff -Nru a/include/asm-v850/macrology.h b/include/asm-v850/macrology.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/macrology.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,17 @@
+/*
+ * include/asm-v850/macrology.h -- Various useful CPP macros
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#define macrology_paste(arg1, arg2)	macrology_paste_1(arg1, arg2)
+#define macrology_paste_1(arg1, arg2)	arg1 ## arg2
+#define macrology_stringify(sym)	macrology_stringify_1(sym)
+#define macrology_stringify_1(sym)	#sym
diff -Nru a/include/asm-v850/mman.h b/include/asm-v850/mman.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/mman.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,38 @@
+#ifndef __V850_MMAN_H__
+#define __V850_MMAN_H__
+
+#define PROT_READ	0x1		/* page can be read */
+#define PROT_WRITE	0x2		/* page can be written */
+#define PROT_EXEC	0x4		/* page can be executed */
+#define PROT_NONE	0x0		/* page can not be accessed */
+
+#define MAP_SHARED	0x01		/* Share changes */
+#define MAP_PRIVATE	0x02		/* Changes are private */
+#define MAP_TYPE	0x0f		/* Mask for type of mapping */
+#define MAP_FIXED	0x10		/* Interpret addr exactly */
+#define MAP_ANONYMOUS	0x20		/* don't use a file */
+
+#define MAP_GROWSDOWN	0x0100		/* stack-like segment */
+#define MAP_DENYWRITE	0x0800		/* ETXTBSY */
+#define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
+#define MAP_LOCKED	0x2000		/* pages are locked */
+#define MAP_NORESERVE	0x4000		/* don't check for reservations */
+
+#define MS_ASYNC	1		/* sync memory asynchronously */
+#define MS_INVALIDATE	2		/* invalidate the caches */
+#define MS_SYNC		4		/* synchronous memory sync */
+
+#define MCL_CURRENT	1		/* lock all current mappings */
+#define MCL_FUTURE	2		/* lock all future mappings */
+
+#define MADV_NORMAL	0x0		/* default page-in behavior */
+#define MADV_RANDOM	0x1		/* page-in minimum required */
+#define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
+#define MADV_WILLNEED	0x3		/* pre-fault pages */
+#define MADV_DONTNEED	0x4		/* discard these pages */
+
+/* compatibility flags */
+#define MAP_ANON	MAP_ANONYMOUS
+#define MAP_FILE	0
+
+#endif /* __V850_MMAN_H__ */
diff -Nru a/include/asm-v850/mmu.h b/include/asm-v850/mmu.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/mmu.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,22 @@
+/* Copyright (C) 2002, David McCullough <davidm@snapgear.com> */
+
+#ifndef __V850_MMU_H__
+#define __V850_MMU_H__
+
+struct mm_rblock_struct {
+	int		size;
+	int		refcount;
+	void	*kblock;
+};
+
+struct mm_tblock_struct {
+	struct mm_rblock_struct	*rblock;
+	struct mm_tblock_struct	*next;
+};
+
+typedef struct {
+	struct mm_tblock_struct	tblock;
+	unsigned long			end_brk;
+} mm_context_t;
+
+#endif /* __V850_MMU_H__ */
diff -Nru a/include/asm-v850/mmu_context.h b/include/asm-v850/mmu_context.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/mmu_context.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,12 @@
+#ifndef __V850_MMU_CONTEXT_H__
+#define __V850_MMU_CONTEXT_H__
+
+#include <linux/sched.h>
+
+#define destroy_context(mm)		((void)0)
+#define init_new_context(tsk,mm)	0
+#define switch_mm(prev,next,tsk,cpu)	((void)0)
+#define activate_mm(prev,next)		((void)0)
+#define enter_lazy_tlb(mm,tsk,cpu)	((void)0)
+
+#endif /* __V850_MMU_CONTEXT_H__ */
diff -Nru a/include/asm-v850/module.h b/include/asm-v850/module.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/module.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,22 @@
+/*
+ * include/asm-v850/module.h -- Architecture-specific module hooks
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_MODULE_H__
+#define __V850_MODULE_H__
+
+#define arch_init_modules(x)	((void)0)
+#define module_arch_init(x)	(0)
+#define module_map(sz)		vmalloc (sz)
+#define module_unmap(sz)	vfree (sz)
+
+#endif /* __V850_MODULE_H__ */
diff -Nru a/include/asm-v850/msgbuf.h b/include/asm-v850/msgbuf.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/msgbuf.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,31 @@
+#ifndef __V850_MSGBUF_H__
+#define __V850_MSGBUF_H__
+
+/* 
+ * The msqid64_ds structure for v850 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct msqid64_ds {
+	struct ipc64_perm msg_perm;
+	__kernel_time_t msg_stime;	/* last msgsnd time */
+	unsigned long	__unused1;
+	__kernel_time_t msg_rtime;	/* last msgrcv time */
+	unsigned long	__unused2;
+	__kernel_time_t msg_ctime;	/* last change time */
+	unsigned long	__unused3;
+	unsigned long  msg_cbytes;	/* current number of bytes on queue */
+	unsigned long  msg_qnum;	/* number of messages in queue */
+	unsigned long  msg_qbytes;	/* max number of bytes on queue */
+	__kernel_pid_t msg_lspid;	/* pid of last msgsnd */
+	__kernel_pid_t msg_lrpid;	/* last receive pid */
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+#endif /* __V850_MSGBUF_H__ */
diff -Nru a/include/asm-v850/namei.h b/include/asm-v850/namei.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/namei.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,17 @@
+/*
+ * linux/include/asm-v850/namei.h
+ *
+ * Included from linux/fs/namei.c
+ */
+
+#ifndef __V850_NAMEI_H__
+#define __V850_NAMEI_H__
+
+/* This dummy routine maybe changed to something useful
+ * for /usr/gnemul/ emulation stuff.
+ * Look at asm-sparc/namei.h for details.
+ */
+
+#define __emul_prefix() NULL
+
+#endif /* __V850_NAMEI_H__ */
diff -Nru a/include/asm-v850/nb85e.h b/include/asm-v850/nb85e.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/nb85e.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,21 @@
+/*
+ * include/asm-v850/nb85e.h -- NB85E cpu core
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_NB85E_H__
+#define __V850_NB85E_H__
+
+#include <asm/nb85e_intc.h>
+
+#define CPU_ARCH "v850e"
+
+#endif /* __V850_NB85E_H__ */
diff -Nru a/include/asm-v850/nb85e_cache.h b/include/asm-v850/nb85e_cache.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/nb85e_cache.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,106 @@
+/*
+ * include/asm-v850/nb85e_cache_cache.h -- Cache control for NB85E_CACHE212 and
+ * 	NB85E_CACHE213 cache memories
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_NB85E_CACHE_H__
+#define __V850_NB85E_CACHE_H__
+
+/* Cache control registers.  */
+#define NB85E_CACHE_ICC_ADDR		0xFFFFF070
+#define NB85E_CACHE_DCC_ADDR		0xFFFFF078
+
+/* Size of a cache line in bytes.  */
+#define NB85E_CACHE_LINE_SIZE		16
+
+
+#ifndef __ASSEMBLY__
+
+extern inline void nb85e_cache_flush_cache (unsigned long cache_control_addr)
+{
+	/*
+	   From the NB85E Instruction/Data Cache manual, how to flush
+	   the instruction cache (ICC is the `Instruction Cache Control
+	   Register'):
+
+		mov	0x3, r2
+	  LOP0:
+		ld.h	ICC[r0], r1
+		cmp	r0, r1
+		bnz	LOP0
+		st.h	r2, ICC[r0]
+	  LOP1:				- First TAG clear
+		ld.h	ICC[r0], r1
+		cmp	r0, r1
+		bnz	LOP1
+		st.h	r2, ICC[r0]
+	  LOP2:				- Second TAG clear
+		ld.h	ICC[r0], r1
+		cmp	r0, r1
+		bnz	LOP2
+	*/
+	int cache_flush_bits, ccr_contents;
+	__asm__ __volatile__ (
+		"	mov	0x3, %1;"
+		"1:	ld.h	0[%2], %0;"
+		"	cmp	r0, %0;"
+		"	bnz	1b;"
+		"	st.h	%1, 0[%2];"
+		"2:	ld.h	0[%2], %0;"
+		"	cmp	r0, %0;"
+		"	bnz	2b;"
+		"	st.h	%1, 0[%2];"
+		"3:	ld.h	0[%2], %0;"
+		"	cmp	r0, %0;"
+		"	bnz	3b"
+		: "=&r" (ccr_contents), "=&r" (cache_flush_bits)
+		: "r" (cache_control_addr)
+		: "memory");
+}
+
+extern inline void nb85e_cache_flush_icache (void)
+{
+	nb85e_cache_flush_cache (NB85E_CACHE_ICC_ADDR);
+}
+
+extern inline void nb85e_cache_flush_dcache (void)
+{
+	nb85e_cache_flush_cache (NB85E_CACHE_DCC_ADDR);
+}
+
+extern inline void nb85e_cache_flush (void)
+{
+	nb85e_cache_flush_icache ();
+	nb85e_cache_flush_dcache ();
+}
+
+#endif /* !__ASSEMBLY__ */
+
+
+/* Define standard definitions in terms of processor-specific ones.  */
+
+/* For <asm/cache.h> */
+#define L1_CACHE_BYTES				NB85E_CACHE_LINE_SIZE
+
+/* For <asm/pgalloc.h> */
+#define flush_cache_all()			nb85e_cache_flush ()
+#define flush_cache_mm(mm)			nb85e_cache_flush ()
+#define flush_cache_range(mm, start, end)	nb85e_cache_flush ()
+#define flush_cache_page(vma, vmaddr)		nb85e_cache_flush ()
+#define flush_page_to_ram(page)			nb85e_cache_flush ()
+#define flush_dcache_page(page)			nb85e_cache_flush_dcache ()
+#define flush_icache_range(start, end)		nb85e_cache_flush_icache ()
+#define flush_icache_page(vma,pg)		nb85e_cache_flush_icache ()
+#define flush_icache()				nb85e_cache_flush_icache ()
+#define flush_cache_sigtramp(vaddr)		nb85e_cache_flush_icache ()
+
+#endif /* __V850_NB85E_CACHE_H__ */
diff -Nru a/include/asm-v850/nb85e_intc.h b/include/asm-v850/nb85e_intc.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/nb85e_intc.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,126 @@
+/*
+ * include/asm-v850/nb85e_intc.h -- NB85E cpu core interrupt controller (INTC)
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_NB85E_INTC_H__
+#define __V850_NB85E_INTC_H__
+
+
+/* There are 4 16-bit `Interrupt Mask Registers' located contiguously
+   starting from this base.  Each interrupt uses a single bit to
+   indicated enabled/disabled status.  */
+#define NB85E_INTC_IMR_BASE_ADDR  0xFFFFF100
+#define NB85E_INTC_IMR_ADDR(irq)  (NB85E_INTC_IMR_BASE_ADDR + ((irq) >> 3))
+#define NB85E_INTC_IMR_BIT(irq)	  ((irq) & 0x7)
+
+/* Each maskable interrupt has a single-byte control register at this
+   address.  */
+#define NB85E_INTC_IC_BASE_ADDR	  0xFFFFF110
+#define NB85E_INTC_IC_ADDR(irq)	  (NB85E_INTC_IC_BASE_ADDR + ((irq) << 1))
+#define NB85E_INTC_IC(irq)	  (*(char *)NB85E_INTC_IC_ADDR(irq))
+/* Encode priority PR for storing in an interrupt control register.  */
+#define NB85E_INTC_IC_PR(pr)	  (pr)
+/* Interrupt disable bit in an interrupt control register.  */
+#define NB85E_INTC_IC_MK_BIT	  6
+#define NB85E_INTC_IC_MK	  (1 << NB85E_INTC_IC_MK_BIT)
+/* Interrupt pending flag in an interrupt control register.  */
+#define NB85E_INTC_IC_IF_BIT	  7
+#define NB85E_INTC_IC_IF	  (1 << NB85E_INTC_IC_IF_BIT)
+
+#ifndef __ASSEMBLY__
+
+/* Enable interrupt handling for interrupt IRQ.  */
+static inline void nb85e_intc_enable_irq (unsigned irq)
+{
+	__asm__ __volatile__ ("clr1 %0, [%1]"
+			      :: "r" (NB85E_INTC_IMR_BIT (irq)),
+			         "r" (NB85E_INTC_IMR_ADDR (irq))
+			      : "memory");
+}
+
+/* Disable interrupt handling for interrupt IRQ.  Note that any
+   interrupts received while disabled will be delivered once the
+   interrupt is enabled again, unless they are explicitly cleared using
+   `nb85e_intc_clear_pending_irq'.  */
+static inline void nb85e_intc_disable_irq (unsigned irq)
+{
+	__asm__ __volatile__ ("set1 %0, [%1]"
+			      :: "r" (NB85E_INTC_IMR_BIT (irq)),
+			         "r" (NB85E_INTC_IMR_ADDR (irq))
+			      : "memory");
+}
+
+/* Return true if interrupt handling for interrupt IRQ is enabled.  */
+static inline int nb85e_intc_irq_enabled (unsigned irq)
+{
+	int rval;
+	__asm__ __volatile__ ("tst1 %1, [%2]; setf z, %0"
+			      : "=r" (rval)
+			      : "r" (NB85E_INTC_IMR_BIT (irq)),
+			        "r" (NB85E_INTC_IMR_ADDR (irq)));
+	return rval;
+}
+
+/* Disable irqs from 0 until LIMIT.  LIMIT must be a multiple of 8.  */
+static inline void _nb85e_intc_disable_irqs (unsigned limit)
+{
+	unsigned long addr;
+	for (addr = NB85E_INTC_IMR_BASE_ADDR; limit >= 8; addr++, limit -= 8)
+		*(char *)addr = 0xFF;
+}
+
+/* Disable all irqs.  This is purposely a macro, because NUM_MACH_IRQS
+   will be only be defined later.  */
+#define nb85e_intc_disable_irqs()   _nb85e_intc_disable_irqs (NUM_MACH_IRQS)
+
+/* Clear any pending interrupts for IRQ.  */
+static inline void nb85e_intc_clear_pending_irq (unsigned irq)
+{
+	__asm__ __volatile__ ("clr1 %0, 0[%1]"
+			      :: "i" (NB85E_INTC_IC_IF_BIT),
+			         "r" (NB85E_INTC_IC_ADDR (irq))
+			      : "memory");
+}
+
+/* Return true if interrupt IRQ is pending (but disabled).  */
+static inline int nb85e_intc_irq_pending (unsigned irq)
+{
+	int rval;
+	__asm__ __volatile__ ("tst1 %1, 0[%2]; setf nz, %0"
+			      : "=r" (rval)
+			      : "i" (NB85E_INTC_IC_IF_BIT),
+			        "r" (NB85E_INTC_IC_ADDR (irq)));
+	return rval;
+}
+
+
+struct nb85e_intc_irq_init {
+	const char *name;	/* name of interrupt type */
+
+	/* Range of kernel irq numbers for this type:
+	   BASE, BASE+INTERVAL, ..., BASE+INTERVAL*NUM  */
+	unsigned base, num, interval;
+
+	unsigned priority;	/* interrupt priority to assign */
+};
+struct hw_interrupt_type;	/* fwd decl */
+
+/* Initialize HW_IRQ_TYPES for INTC-controlled irqs described in array
+   INITS (which is terminated by an entry with the name field == 0).  */
+extern void nb85e_intc_init_irq_types (struct nb85e_intc_irq_init *inits,
+				       struct hw_interrupt_type *hw_irq_types);
+
+
+#endif /* !__ASSEMBLY__ */
+
+
+#endif /* __V850_NB85E_INTC_H__ */
diff -Nru a/include/asm-v850/nb85e_timer_c.h b/include/asm-v850/nb85e_timer_c.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/nb85e_timer_c.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,48 @@
+/*
+ * include/asm-v850/nb85e_timer_c.h -- `Timer C' component often used
+ *	with the NB85E cpu core
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+/* NOTE: this include file currently contains only enough to allow us to
+   use timer C as an interrupt pass-through.  */
+
+#ifndef __V850_NB85E_TIMER_C_H__
+#define __V850_NB85E_TIMER_C_H__
+
+#include <asm/types.h>
+#include <asm/machdep.h>	/* Pick up chip-specific defs.  */
+
+
+/* Timer C (16-bit interval timers).  */
+
+/* Control register 0 for timer C.  */
+#define NB85E_TIMER_C_TMCC0_ADDR(n) (NB85E_TIMER_C_BASE_ADDR + 0x6 + 0x10 *(n))
+#define NB85E_TIMER_C_TMCC0(n)	  (*(volatile u8 *)NB85E_TIMER_C_TMCC0_ADDR(n))
+#define NB85E_TIMER_C_TMCC0_CAE	  0x01 /* clock action enable */
+#define NB85E_TIMER_C_TMCC0_CE	  0x02 /* count enable */
+/* ... */
+
+/* Control register 1 for timer C.  */
+#define NB85E_TIMER_C_TMCC1_ADDR(n) (NB85E_TIMER_C_BASE_ADDR + 0x8 + 0x10 *(n))
+#define NB85E_TIMER_C_TMCC1(n)	  (*(volatile u8 *)NB85E_TIMER_C_TMCC1_ADDR(n))
+#define NB85E_TIMER_C_TMCC1_CMS0  0x01 /* capture/compare mode select (ccc0) */
+#define NB85E_TIMER_C_TMCC1_CMS1  0x02 /* capture/compare mode select (ccc1) */
+/* ... */
+
+/* Interrupt edge-sensitivity control for timer C.  */
+#define NB85E_TIMER_C_SESC_ADDR(n) (NB85E_TIMER_C_BASE_ADDR + 0x9 + 0x10 *(n))
+#define NB85E_TIMER_C_SESC(n)	  (*(volatile u8 *)NB85E_TIMER_C_SESC_ADDR(n))
+
+/* ...etc... */
+
+
+#endif /* __V850_NB85E_TIMER_C_H__  */
diff -Nru a/include/asm-v850/nb85e_timer_d.h b/include/asm-v850/nb85e_timer_d.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/nb85e_timer_d.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,62 @@
+/*
+ * include/asm-v850/nb85e_timer_d.h -- `Timer D' component often used
+ *	with the NB85E cpu core
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_NB85E_TIMER_D_H__
+#define __V850_NB85E_TIMER_D_H__
+
+#include <asm/types.h>
+#include <asm/machdep.h>	/* Pick up chip-specific defs.  */
+
+
+/* Timer D (16-bit interval timers).  */
+
+/* Count registers for timer D.  */
+#define NB85E_TIMER_D_TMD_ADDR(n) (NB85E_TIMER_D_TMD_BASE_ADDR + 0x10 * (n))
+#define NB85E_TIMER_D_TMD(n)	  (*(volatile u16 *)NB85E_TIMER_D_TMD_ADDR(n))
+
+/* Count compare registers for timer D.  */
+#define NB85E_TIMER_D_CMD_ADDR(n) (NB85E_TIMER_D_CMD_BASE_ADDR + 0x10 * (n))
+#define NB85E_TIMER_D_CMD(n)	  (*(u16 *)NB85E_TIMER_D_CMD_ADDR(n))
+
+/* Control registers for timer D.  */
+#define NB85E_TIMER_D_TMCD_ADDR(n) (NB85E_TIMER_D_TMCD_BASE_ADDR + 0x10 * (n))
+#define NB85E_TIMER_D_TMCD(n)	   (*(volatile u8 *)NB85E_TIMER_D_TMCD_ADDR(n))
+/* Control bits for timer D.  */
+#define NB85E_TIMER_D_TMCD_CE  	   0x2 /* count enable */
+#define NB85E_TIMER_D_TMCD_CAE	   0x1 /* clock action enable */
+/* Clock divider setting (log2).  */
+#define NB85E_TIMER_D_TMCD_CS(divlog2) (((divlog2) - NB85E_TIMER_D_TMCD_CS_MIN) << 4)
+/* Minimum clock divider setting (log2).  */
+#ifndef NB85E_TIMER_D_TMCD_CS_MIN /* Can be overridden by mach-specific hdrs */
+#define NB85E_TIMER_D_TMCD_CS_MIN  2 /* Default is correct for the v850e/ma1 */
+#endif
+/* Maximum clock divider setting (log2).  */
+#define NB85E_TIMER_D_TMCD_CS_MAX  (NB85E_TIMER_D_TMCD_CS_MIN + 7)
+
+/* Return the clock-divider (log2) of timer D unit N.  */
+#define NB85E_TIMER_D_DIVLOG2(n) \
+  (((NB85E_TIMER_D_TMCD(n) >> 4) & 0x7) + NB85E_TIMER_D_TMCD_CS_MIN)
+
+
+#ifndef __ASSEMBLY__
+
+/* Start interval timer TIMER (0-3).  The timer will issue the
+   corresponding INTCMD interrupt RATE times per second.  This function
+   does not enable the interrupt.  */
+extern void nb85e_timer_d_configure (unsigned timer, unsigned rate);
+
+#endif /* !__ASSEMBLY__ */
+
+
+#endif /* __V850_NB85E_TIMER_D_H__  */
diff -Nru a/include/asm-v850/nb85e_uart.h b/include/asm-v850/nb85e_uart.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/nb85e_uart.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,142 @@
+/*
+ * include/asm-v850/nb85e_uart.h -- On-chip UART often used with the
+ *	NB85E cpu core
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+/* There's not actually a single UART implementation used by nb85e
+   derivatives, but rather a series of implementations that are all
+   `close' to one another.  This file attempts to capture some
+   commonality between them.  */
+
+#ifndef __V850_NB85E_UART_H__
+#define __V850_NB85E_UART_H__
+
+#include <asm/types.h>
+#include <asm/machdep.h>	/* Pick up chip-specific defs.  */
+
+
+/* The base address of the UART control registers for channel N.
+   The default is the address used on the V850E/MA1.  */
+#ifndef NB85E_UART_BASE_ADDR
+#define NB85E_UART_BASE_ADDR(n)		(0xFFFFFA00 + 0x10 * (n))
+#endif 
+
+/* Addresses of specific UART control registers for channel N.
+   The defaults are the addresses used on the V850E/MA1; if a platform
+   wants to redefine any of these, it must redefine them all.  */
+#ifndef NB85E_UART_ASIM_ADDR
+#define NB85E_UART_ASIM_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0x0)
+#define NB85E_UART_RXB_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0x2)
+#define NB85E_UART_ASIS_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0x3)
+#define NB85E_UART_TXB_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0x4)
+#define NB85E_UART_ASIF_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0x5)
+#define NB85E_UART_CKSR_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0x6)
+#define NB85E_UART_BRGC_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0x7)
+#endif
+
+
+/* UART config registers.  */
+#define NB85E_UART_ASIM(n)	(*(volatile u8 *)NB85E_UART_ASIM_ADDR(n))
+/* Control bits for config registers.  */
+#define NB85E_UART_ASIM_CAE	0x80 /* clock enable */
+#define NB85E_UART_ASIM_TXE	0x40 /* transmit enable */
+#define NB85E_UART_ASIM_RXE	0x20 /* receive enable */
+#define NB85E_UART_ASIM_PS_MASK	0x18 /* mask covering parity-select bits */
+#define NB85E_UART_ASIM_PS_NONE	0x00 /* no parity */
+#define NB85E_UART_ASIM_PS_ZERO	0x08 /* zero parity */
+#define NB85E_UART_ASIM_PS_ODD	0x10 /* odd parity */
+#define NB85E_UART_ASIM_PS_EVEN	0x18 /* even parity */
+#define NB85E_UART_ASIM_CL_8	0x04 /* char len is 8 bits (otherwise, 7) */
+#define NB85E_UART_ASIM_SL_2	0x02 /* 2 stop bits (otherwise, 1) */
+#define NB85E_UART_ASIM_ISRM	0x01 /* generate INTSR interrupt on errors
+					(otherwise, generate INTSER) */
+
+/* UART serial interface status registers.  */
+#define NB85E_UART_ASIS(n)	(*(volatile u8 *)NB85E_UART_ASIS_ADDR(n))
+/* Control bits for status registers.  */
+#define NB85E_UART_ASIS_PE	0x04 /* parity error */
+#define NB85E_UART_ASIS_FE	0x02 /* framing error */
+#define NB85E_UART_ASIS_OVE	0x01 /* overrun error */
+
+/* UART serial interface transmission status registers.  */
+#define NB85E_UART_ASIF(n)	(*(volatile u8 *)NB85E_UART_ASIF_ADDR(n))
+#define NB85E_UART_ASIF_TXBF	0x02 /* transmit buffer flag (data in TXB) */
+#define NB85E_UART_ASIF_TXSF	0x01 /* transmit shift flag (sending data) */
+
+/* UART receive buffer register.  */
+#define NB85E_UART_RXB(n)	(*(volatile u8 *)NB85E_UART_RXB_ADDR(n))
+
+/* UART transmit buffer register.  */
+#define NB85E_UART_TXB(n)	(*(volatile u8 *)NB85E_UART_TXB_ADDR(n))
+
+/* UART baud-rate generator control registers.  */
+#define NB85E_UART_CKSR(n)	(*(volatile u8 *)NB85E_UART_CKSR_ADDR(n))
+#define NB85E_UART_CKSR_MAX	11
+#define NB85E_UART_CKSR_MAX_FREQ (25*1000*1000)
+#define NB85E_UART_BRGC(n)	(*(volatile u8 *)NB85E_UART_BRGC_ADDR(n))
+
+
+/* This UART doesn't implement RTS/CTS by default, but some platforms
+   implement them externally, so check to see if <asm/machdep.h> defined
+   anything.  */
+#ifdef NB85E_UART_CTS
+#define nb85e_uart_cts(n)	NB85E_UART_CTS(n)
+#else
+#define nb85e_uart_cts(n)	(1)
+#endif
+
+/* Do the same for RTS.  */
+#ifdef NB85E_UART_SET_RTS
+#define nb85e_uart_set_rts(n,v)	NB85E_UART_SET_RTS(n,v)
+#else
+#define nb85e_uart_set_rts(n,v)	((void)0)
+#endif
+
+/* Return true if all characters awaiting transmission on uart channel N
+   have been transmitted.  */
+#define nb85e_uart_xmit_done(n)						      \
+   (! (NB85E_UART_ASIF(n) & NB85E_UART_ASIF_TXBF))
+/* Wait for this to be true.  */
+#define nb85e_uart_wait_for_xmit_done(n)				      \
+   do { } while (! nb85e_uart_xmit_done (n))
+
+/* Return true if uart channel N is ready to transmit a character.  */
+#define nb85e_uart_xmit_ok(n)						      \
+   (nb85e_uart_xmit_done(n) && nb85e_uart_cts(n))
+/* Wait for this to be true.  */
+#define nb85e_uart_wait_for_xmit_ok(n)					      \
+   do { } while (! nb85e_uart_xmit_ok (n))
+
+/* Write character CH to uart channel N.  */
+#define nb85e_uart_putc(n, ch)	(NB85E_UART_TXB(n) = (ch))
+
+
+#define NB85E_UART_MINOR_BASE	64
+
+
+#ifndef __ASSEMBLY__
+
+/* Setup a console using channel 0 of the builtin uart.  */
+extern void nb85e_uart_cons_init (unsigned chan);
+
+/* Configure and turn on uart channel CHAN, using the termios `control
+   modes' bits in CFLAGS, and a baud-rate of BAUD.  */
+void nb85e_uart_configure (unsigned chan, unsigned cflags, unsigned baud);
+
+/* If the macro NB85E_UART_PRE_CONFIGURE is defined (presumably by a
+   <asm/machdep.h>), it is called from nb85e_uart_pre_configure before
+   anything else is done, with interrupts disabled.  */
+
+#endif /* !__ASSEMBLY__ */
+
+
+#endif /* __V850_NB85E_UART_H__ */
diff -Nru a/include/asm-v850/nb85e_utils.h b/include/asm-v850/nb85e_utils.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/nb85e_utils.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,35 @@
+/*
+ * include/asm-v850/nb85e_utils.h -- Utility functions associated with
+ *	the NB85E cpu core
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_NB85E_UTILS_H__
+#define __V850_NB85E_UTILS_H__
+
+/* Calculate counter clock-divider and count values to attain the
+   desired frequency RATE from the base frequency BASE_FREQ.  The
+   counter is expected to have a clock-divider, which can divide the
+   system cpu clock by a power of two value from MIN_DIVLOG2 to
+   MAX_DIV_LOG2, and a word-size of COUNTER_SIZE bits (the counter
+   counts up and resets whenever it's equal to the compare register,
+   generating an interrupt or whatever when it does so).  The returned
+   values are: *DIVLOG2 -- log2 of the desired clock divider and *COUNT
+   -- the counter compare value to use.  Returns true if it was possible
+   to find a reasonable value, otherwise false (and the other return
+   values will be set to be as good as possible).  */
+extern int calc_counter_params (unsigned long base_freq,
+				unsigned long rate,
+				unsigned min_divlog2, unsigned max_divlog2,
+				unsigned counter_size,
+				unsigned *divlog2, unsigned *count);
+
+#endif /* __V850_NB85E_UTILS_H__ */
diff -Nru a/include/asm-v850/page.h b/include/asm-v850/page.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/page.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,144 @@
+/*
+ * include/asm-v850/page.h -- VM ops
+ *
+ *  Copyright (C) 2001, 2002  NEC Corporation
+ *  Copyright (C) 2001, 2002  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_PAGE_H__
+#define __V850_PAGE_H__
+
+#include <asm/machdep.h>
+
+
+#define PAGE_SHIFT	12
+#define PAGE_SIZE       (1UL << PAGE_SHIFT)
+#define PAGE_MASK       (~(PAGE_SIZE-1))
+
+
+/*
+ * PAGE_OFFSET -- the first address of the first page of memory. For archs with
+ * no MMU this corresponds to the first free page in physical memory (aligned
+ * on a page boundary).
+ */
+#ifndef PAGE_OFFSET
+#define PAGE_OFFSET  0x0000000
+#endif
+
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+#define STRICT_MM_TYPECHECKS
+
+#define clear_page(page)	memset ((void *)(page), 0, PAGE_SIZE)
+#define copy_page(to, from)	memcpy ((void *)(to), (void *)from, PAGE_SIZE)
+
+#define clear_user_page(page, vaddr, pg)	clear_page (page)
+#define copy_user_page(to, from, vaddr,pg)	copy_page (to, from)
+
+#ifdef STRICT_MM_TYPECHECKS
+/*
+ * These are used to make use of C type-checking..
+ */
+
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long pmd; } pmd_t;
+typedef struct { unsigned long pgd; } pgd_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+#define pte_val(x)      ((x).pte)
+#define pmd_val(x)      ((x).pmd)
+#define pgd_val(x)      ((x).pgd)
+#define pgprot_val(x)   ((x).pgprot)
+
+#define __pte(x)        ((pte_t) { (x) } )
+#define __pmd(x)        ((pmd_t) { (x) } )
+#define __pgd(x)        ((pgd_t) { (x) } )
+#define __pgprot(x)     ((pgprot_t) { (x) } )
+
+#else /* !STRICT_MM_TYPECHECKS */
+/*
+ * .. while these make it easier on the compiler
+ */
+
+typedef unsigned long pte_t;
+typedef unsigned long pmd_t;
+typedef unsigned long pgd_t;
+typedef unsigned long pgprot_t;
+
+#define pte_val(x)      (x)
+#define pmd_val(x)      (x)
+#define pgd_val(x)      (x)
+#define pgprot_val(x)   (x)
+
+#define __pte(x)        (x)
+#define __pmd(x)        (x)
+#define __pgd(x)        (x)
+#define __pgprot(x)     (x)
+
+#endif /* STRICT_MM_TYPECHECKS */
+
+#endif /* !__ASSEMBLY__ */
+
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr)	(((addr) + PAGE_SIZE - 1) & PAGE_MASK)
+
+
+#ifndef __ASSEMBLY__
+
+extern void __bug (void) __attribute__ ((noreturn));
+#define BUG()		__bug()
+#define PAGE_BUG(page)	__bug()
+
+/* Pure 2^n version of get_order */
+extern __inline__ int get_order (unsigned long size)
+{
+	int order;
+
+	size = (size-1) >> (PAGE_SHIFT-1);
+	order = -1;
+	do {
+		size >>= 1;
+		order++;
+	} while (size);
+	return order;
+}
+
+#endif /* !__ASSEMBLY__ */
+
+
+/* No current v850 processor has virtual memory.  */
+#define __virt_to_phys(addr)	(addr)
+#define __phys_to_virt(addr)	(addr)
+
+#define virt_to_pfn(kaddr)	(__virt_to_phys (kaddr) >> PAGE_SHIFT)
+#define pfn_to_virt(pfn)	__phys_to_virt ((pfn) << PAGE_SHIFT)
+
+#define MAP_NR(kaddr) \
+  (((unsigned long)(kaddr) - PAGE_OFFSET) >> PAGE_SHIFT)
+#define virt_to_page(kaddr)	(mem_map + MAP_NR (kaddr))
+#define page_to_virt(page) \
+  ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)
+
+#define pfn_to_page(pfn)	virt_to_page (pfn_to_virt (pfn))
+#define page_to_pfn(page)	virt_to_pfn (page_to_virt (page))
+
+#define	virt_addr_valid(kaddr)						\
+  (((void *)(kaddr) >= (void *)PAGE_OFFSET) && MAP_NR (kaddr) < max_mapnr)
+
+
+#define __pa(x)		     __virt_to_phys ((unsigned long)(x))
+#define __va(x)		     ((void *)__phys_to_virt ((unsigned long)(x)))
+
+
+#endif /* KERNEL */
+
+#endif /* __V850_PAGE_H__ */
diff -Nru a/include/asm-v850/param.h b/include/asm-v850/param.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/param.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,36 @@
+/*
+ * include/asm-v850/param.h -- Varions kernel parameters
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_PARAM_H__
+#define __V850_PARAM_H__
+
+#include <asm/machdep.h>	/* For HZ */
+
+#define EXEC_PAGESIZE	4096
+
+#ifndef NGROUPS
+#define NGROUPS		32
+#endif
+
+#ifndef NOGROUP
+#define NOGROUP		(-1)
+#endif
+
+#define MAXHOSTNAMELEN	64	/* max length of hostname */
+
+#ifdef __KERNEL__
+# define USER_HZ	100
+# define CLOCKS_PER_SEC	USER_HZ
+#endif
+
+#endif /* __V850_PARAM_H__ */
diff -Nru a/include/asm-v850/pci.h b/include/asm-v850/pci.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/pci.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,77 @@
+/*
+ * include/asm-v850/pci.h -- PCI support
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_PCI_H__
+#define __V850_PCI_H__
+
+/* Get any platform-dependent definitions.  */
+#include <asm/machdep.h>
+
+/* Generic declarations.  */
+
+struct scatterlist;
+
+extern void pcibios_set_master (struct pci_dev *dev);
+
+/* `Grant' to PDEV the memory block at CPU_ADDR, for doing DMA.  The
+   32-bit PCI bus mastering address to use is returned.  the device owns
+   this memory until either pci_unmap_single or pci_dma_sync_single is
+   performed.  */
+extern dma_addr_t
+pci_map_single (struct pci_dev *pdev, void *cpu_addr, size_t size, int dir);
+
+/* Return to the CPU the PCI DMA memory block previously `granted' to
+   PDEV, at DMA_ADDR.  */
+extern void
+pci_unmap_single (struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
+		  int dir);
+
+/* Make physical memory consistant for a single streaming mode DMA
+   translation after a transfer.
+
+   If you perform a pci_map_single() but wish to interrogate the
+   buffer using the cpu, yet do not wish to teardown the PCI dma
+   mapping, you must call this function before doing so.  At the next
+   point you give the PCI dma address back to the card, the device
+   again owns the buffer.  */
+extern void
+pci_dma_sync_single (struct pci_dev *dev, dma_addr_t dma_addr, size_t size,
+		     int dir);
+
+
+/* Do multiple DMA mappings at once.  */
+extern int
+pci_map_sg (struct pci_dev *pdev, struct scatterlist *sg, int sg_len, int dir);
+
+/* Unmap multiple DMA mappings at once.  */
+extern void
+pci_unmap_sg (struct pci_dev *pdev, struct scatterlist *sg, int sg_len,
+	      int dir);
+
+/* Allocate and map kernel buffer using consistent mode DMA for PCI
+   device.  Returns non-NULL cpu-view pointer to the buffer if
+   successful and sets *DMA_ADDR to the pci side dma address as well,
+   else DMA_ADDR is undefined.  */
+extern void *
+pci_alloc_consistent (struct pci_dev *pdev, size_t size, dma_addr_t *dma_addr);
+
+/* Free and unmap a consistent DMA buffer.  CPU_ADDR and DMA_ADDR must
+   be values that were returned from pci_alloc_consistent.  SIZE must be
+   the same as what as passed into pci_alloc_consistent.  References to
+   the memory and mappings assosciated with CPU_ADDR or DMA_ADDR past
+   this call are illegal.  */
+extern void
+pci_free_consistent (struct pci_dev *pdev, size_t size, void *cpu_addr,
+		     dma_addr_t dma_addr);
+
+#endif /* __V850_PCI_H__ */
diff -Nru a/include/asm-v850/percpu.h b/include/asm-v850/percpu.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/percpu.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,6 @@
+#ifndef __V850_PERCPU_H__
+#define __V850_PERCPU_H__
+
+#include <asm-generic/percpu.h>
+
+#endif /* __V850_PERCPU_H__ */
diff -Nru a/include/asm-v850/pgalloc.h b/include/asm-v850/pgalloc.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/pgalloc.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,22 @@
+/*
+ * include/asm-v850/pgalloc.h
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_PGALLOC_H__
+#define __V850_PGALLOC_H__
+
+#include <linux/mm.h>  /* some crap code expects this */
+
+/* ... and then, there was one.  */
+#define check_pgt_cache()	((void)0)
+
+#endif /* __V850_PGALLOC_H__ */
diff -Nru a/include/asm-v850/pgtable.h b/include/asm-v850/pgtable.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/pgtable.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,58 @@
+#ifndef __V850_PGTABLE_H__
+#define __V850_PGTABLE_H__
+
+#include <linux/config.h>
+#include <asm/page.h>
+
+
+typedef pte_t *pte_addr_t;
+
+#define pgd_present(pgd)	(1) /* pages are always present on NO_MM */
+#define pgd_none(pgd)		(0)
+#define pgd_bad(pgd)		(0)
+#define pgd_clear(pgdp)		((void)0)
+
+#define	pmd_offset(a, b)	((void *)0)
+
+#define kern_addr_valid(addr)	(1)
+
+
+#define __swp_type(x)		(0)
+#define __swp_offset(x)		(0)
+#define __swp_entry(typ,off)	((swp_entry_t) { ((typ) | ((off) << 7)) })
+#define __pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(x)	((pte_t) { (x).val })
+
+
+/* These mean nothing to !CONFIG_MMU.  */
+#define PAGE_NONE		__pgprot(0)
+#define PAGE_SHARED		__pgprot(0)
+#define PAGE_COPY		__pgprot(0)
+#define PAGE_READONLY		__pgprot(0)
+#define PAGE_KERNEL		__pgprot(0)
+
+
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc.  When CONFIG_MMU is not defined, this
+ * should never actually be used, so just define it to something that's
+ * will hopefully cause a bus error if it is.
+ */
+#define ZERO_PAGE(vaddr)	((void *)0x87654321)
+
+
+/* Some bogus code in procfs uses these; whatever.  */
+#define VMALLOC_START	0
+#define VMALLOC_END	(~0)
+
+
+extern void paging_init (void);
+#define swapper_pg_dir ((pgd_t *) 0)
+
+#define pgtable_cache_init()   ((void)0)
+
+
+extern unsigned int kobjsize(const void *objp);
+
+
+#endif /* __V850_PGTABLE_H__ */
diff -Nru a/include/asm-v850/poll.h b/include/asm-v850/poll.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/poll.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,23 @@
+#ifndef __V850_POLL_H__
+#define __V850_POLL_H__
+
+#define POLLIN		0x0001
+#define POLLPRI		0x0002
+#define POLLOUT		0x0004
+#define POLLERR		0x0008
+#define POLLHUP		0x0010
+#define POLLNVAL	0x0020
+#define POLLRDNORM	0x0040
+#define POLLWRNORM	POLLOUT
+#define POLLRDBAND	0x0080
+#define POLLWRBAND	0x0100
+#define POLLMSG		0x0400
+#define POLLREMOVE	0x1000
+
+struct pollfd {
+	int fd;
+	short events;
+	short revents;
+};
+
+#endif /* __V850_POLL_H__ */
diff -Nru a/include/asm-v850/posix_types.h b/include/asm-v850/posix_types.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/posix_types.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,73 @@
+/*
+ * include/asm-v850/posix_types.h -- Kernel versions of standard types
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_POSIX_TYPES_H__
+#define __V850_POSIX_TYPES_H__
+
+typedef unsigned int	__kernel_dev_t;
+typedef unsigned long	__kernel_ino_t;
+typedef unsigned long long __kernel_ino64_t;
+typedef unsigned int	__kernel_mode_t;
+typedef unsigned int	__kernel_nlink_t;
+typedef long		__kernel_off_t;
+typedef long long	__kernel_loff_t;
+typedef int		__kernel_pid_t;
+typedef unsigned short	__kernel_ipc_pid_t;
+typedef unsigned int	__kernel_uid_t;
+typedef unsigned int	__kernel_gid_t;
+typedef unsigned int	__kernel_size_t;
+typedef int		__kernel_ssize_t;
+typedef int		__kernel_ptrdiff_t;
+typedef long		__kernel_time_t;
+typedef long		__kernel_suseconds_t;
+typedef long		__kernel_clock_t;
+typedef int		__kernel_daddr_t;
+typedef char *		__kernel_caddr_t;
+typedef unsigned short	__kernel_uid16_t;
+typedef unsigned short	__kernel_gid16_t;
+typedef unsigned int	__kernel_uid32_t;
+typedef unsigned int	__kernel_gid32_t;
+
+/* Some bogus code depends on this; we don't care.  */
+typedef __kernel_uid_t __kernel_old_uid_t;
+
+
+typedef struct {
+#if defined(__KERNEL__) || defined(__USE_ALL)
+	int	val[2];
+#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+	int	__val[2];
+#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+} __kernel_fsid_t;
+
+
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+
+#include <asm/bitops.h>
+
+#undef	__FD_SET
+#define __FD_SET(fd, fd_set) \
+  __set_bit (fd, (void *)&((__kernel_fd_set *)fd_set)->fds_bits)
+#undef __FD_CLR
+#define __FD_CLR(fd, fd_set) \
+  __clear_bit (fd, (void *)&((__kernel_fd_set *)fd_set)->fds_bits)
+#undef	__FD_ISSET
+#define __FD_ISSET(fd, fd_set) \
+  __test_bit (fd, (void *)&((__kernel_fd_set *)fd_set)->fds_bits)
+#undef	__FD_ZERO
+#define __FD_ZERO(fd_set) \
+  memset (fd_set, 0, sizeof (*(fd_set *)fd_set))
+
+#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+
+#endif /* __V850_POSIX_TYPES_H__ */
diff -Nru a/include/asm-v850/processor.h b/include/asm-v850/processor.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/processor.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,116 @@
+/*
+ * include/asm-v850/processor.h
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_PROCESSOR_H__
+#define __V850_PROCESSOR_H__
+
+#include <linux/config.h>
+
+#include <asm/ptrace.h>
+#include <asm/thread_info.h>
+#include <asm/entry.h>
+
+/* Some code expects `segment' stuff to be defined here.  */
+#include <asm/segment.h>
+
+
+/*
+ * The only places this is used seem to be horrible bletcherous kludges,
+ * so we just define it to be as large as possible.
+ */
+#define TASK_SIZE	(0xFFFFFFFF)
+
+
+#ifndef __ASSEMBLY__
+
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr()	({ __label__ _l; _l: &&_l;})
+
+
+/*
+ * Bus types
+ */
+#define EISA_bus 0
+#define EISA_bus__is_a_macro /* for versions in ksyms.c */
+#define MCA_bus 0
+#define MCA_bus__is_a_macro /* for versions in ksyms.c */
+
+/* If you change this, you must change the associated assembly-languages
+   constants defined below, THREAD_*.  */
+struct thread_struct {
+	/* kernel stack pointer (must be first field in structure) */
+	unsigned long  ksp;
+};
+
+#define INIT_THREAD { sizeof init_stack + (unsigned long)init_stack }
+
+
+/* Do necessary setup to start up a newly executed thread.  */
+extern inline void start_thread (struct pt_regs *regs,
+				 unsigned long pc, unsigned long usp)
+{
+	regs->pc = pc;
+	regs->gpr[GPR_SP] = usp;
+	regs->kernel_mode = 0;
+}
+
+/* Free all resources held by a thread. */
+extern inline void release_thread (struct task_struct *dead_task)
+{
+}
+
+extern int kernel_thread (int (*fn)(void *), void * arg, unsigned long flags);
+
+/* Free current thread data structures etc.  */
+static inline void exit_thread (void)
+{
+}
+
+/* Return saved (kernel) PC of a blocked thread.  */
+extern inline unsigned long thread_saved_pc (struct thread_struct *t)
+{
+	struct pt_regs *r = (struct pt_regs *)(t->ksp + STATE_SAVE_PT_OFFSET);
+	/* Actually, we return the LP register, because the thread is
+	   actually blocked in switch_thread, and we're interested in
+	   the PC it will _return_ to.  */
+	return r->gpr[GPR_LP];
+}
+
+unsigned long get_wchan (struct task_struct *p);
+
+
+/* Return some info about the user process TASK.  */
+#define task_tos(task)	((unsigned long)(task)->thread_info + THREAD_SIZE)
+#define task_regs(task) ((struct pt_regs *)task_tos (task) - 1)
+#define task_sp(task)	(task_regs (task)->gpr[GPR_SP])
+#define task_pc(task)	(task_regs (task)->pc)
+/* Grotty old names for some.  */
+#define KSTK_EIP(task)	task_pc (task)
+#define KSTK_ESP(task)	task_sp (task)
+
+
+#define cpu_relax()    ((void)0)
+
+
+#else /* __ASSEMBLY__ */
+
+#define THREAD_KSP	0
+
+#endif /* !__ASSEMBLY__ */
+
+
+#endif /* __V850_PROCESSOR_H__ */
diff -Nru a/include/asm-v850/ptrace.h b/include/asm-v850/ptrace.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/ptrace.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,111 @@
+/*
+ * include/asm-v850/ptrace.h -- Access to CPU registers
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_PTRACE_H__
+#define __V850_PTRACE_H__
+
+
+/* v850 general purpose registers with special meanings.  */
+#define GPR_ZERO	0	/* constant zero */
+#define GPR_ASM		1	/* reserved for assembler */
+#define GPR_SP		3	/* stack pointer */
+#define GPR_GP		4	/* global data pointer */
+#define GPR_TP		5	/* `text pointer' */
+#define GPR_EP		30	/* `element pointer' */
+#define GPR_LP		31	/* link pointer (current return address) */
+
+/* These aren't official names, but they make some code more descriptive.  */
+#define GPR_ARG0	6
+#define GPR_ARG1	7
+#define GPR_ARG2	8
+#define GPR_ARG3	9
+#define GPR_RVAL0	10
+#define GPR_RVAL1	11
+#define GPR_RVAL	GPR_RVAL0
+
+#define NUM_GPRS	32
+
+/* v850 `system' registers.  */
+#define SR_EIPC		0
+#define SR_EIPSW	1
+#define SR_FEPC		2
+#define SR_FEPSW	3
+#define SR_ECR		4
+#define SR_PSW		5
+#define SR_CTPC		16
+#define SR_CTPSW	17
+#define SR_DBPC		18
+#define SR_DBPSW	19
+#define SR_CTBP		20
+#define SR_DIR		21
+#define SR_ASID		23
+
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned long v850_reg_t;
+
+/* How processor state is stored on the stack during a syscall/signal.
+   If you change this structure, change the associated assembly-language
+   macros below too (PT_*)!  */
+struct pt_regs
+{
+	/* General purpose registers.  */
+	v850_reg_t gpr[NUM_GPRS];
+
+	v850_reg_t pc;		/* program counter */
+	v850_reg_t psw;		/* program status word */
+
+	/* Registers used by `callt' instruction:  */
+	v850_reg_t ctpc;	/* saved program counter */
+	v850_reg_t ctpsw;	/* saved psw */
+	v850_reg_t ctbp;	/* base pointer for callt table */
+
+	char kernel_mode;	/* 1 if in `kernel mode', 0 if user mode */
+};
+
+
+#define instruction_pointer(regs)	((regs)->pc)
+#define user_mode(regs)			(!(regs)->kernel_mode)
+
+/* When a struct pt_regs is used to save user state for a system call in
+   the kernel, the system call is stored in the space for R0 (since it's
+   never used otherwise, R0 being a constant 0).  Non-system-calls
+   simply store 0 there.  */
+#define PT_REGS_SYSCALL(regs)		(regs)->gpr[0]
+#define PT_REGS_SET_SYSCALL(regs, val)	((regs)->gpr[0] = (val))
+
+#endif /* !__ASSEMBLY__ */
+
+
+/* The number of bytes used to store each register.  */
+#define _PT_REG_SIZE	4
+
+/* Offset of a general purpose register in a stuct pt_regs.  */
+#define PT_GPR(num)	((num) * _PT_REG_SIZE)
+
+/* Offsets of various special registers & fields in a struct pt_regs.  */
+#define PT_PC		((NUM_GPRS + 0) * _PT_REG_SIZE)
+#define PT_PSW		((NUM_GPRS + 1) * _PT_REG_SIZE)
+#define PT_CTPC		((NUM_GPRS + 2) * _PT_REG_SIZE)
+#define PT_CTPSW	((NUM_GPRS + 3) * _PT_REG_SIZE)
+#define PT_CTBP		((NUM_GPRS + 4) * _PT_REG_SIZE)
+#define PT_KERNEL_MODE	((NUM_GPRS + 5) * _PT_REG_SIZE)
+
+#define PT_SYSCALL	PT_GPR(0)
+
+/* Size of struct pt_regs, including alignment.  */
+#define PT_SIZE		((NUM_GPRS + 6) * _PT_REG_SIZE)
+
+
+#endif /* __V850_PTRACE_H__ */
diff -Nru a/include/asm-v850/resource.h b/include/asm-v850/resource.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/resource.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,47 @@
+#ifndef __V850_RESOURCE_H__
+#define __V850_RESOURCE_H__
+
+/*
+ * Resource limits
+ */
+
+#define RLIMIT_CPU	0		/* CPU time in ms */
+#define RLIMIT_FSIZE	1		/* Maximum filesize */
+#define RLIMIT_DATA	2		/* max data size */
+#define RLIMIT_STACK	3		/* max stack size */
+#define RLIMIT_CORE	4		/* max core file size */
+#define RLIMIT_RSS	5		/* max resident set size */
+#define RLIMIT_NPROC	6		/* max number of processes */
+#define RLIMIT_NOFILE	7		/* max number of open files */
+#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
+#define RLIMIT_AS	9		/* address space limit */
+#define RLIMIT_LOCKS	10		/* maximum file locks held */
+
+#define RLIM_NLIMITS	11
+
+/*
+ * SuS says limits have to be unsigned.
+ * Which makes a ton more sense anyway.
+ */
+#define RLIM_INFINITY	(~0UL)
+
+#ifdef __KERNEL__
+
+#define INIT_RLIMITS					\
+{							\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{      _STK_LIM, RLIM_INFINITY },		\
+	{             0, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{             0,             0 },		\
+	{      INR_OPEN,     INR_OPEN  },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+        { RLIM_INFINITY, RLIM_INFINITY },		\
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* __V850_RESOURCE_H__ */
diff -Nru a/include/asm-v850/rmap.h b/include/asm-v850/rmap.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/rmap.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1 @@
+/* Do not need anything here */
diff -Nru a/include/asm-v850/rte_cb.h b/include/asm-v850/rte_cb.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/rte_cb.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,87 @@
+/*
+ * include/asm-v850/rte_cb.h -- Midas labs RTE-CB series of evaluation boards
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_RTE_CB_H__
+#define __V850_RTE_CB_H__
+
+
+/* CPU addresses of GBUS memory spaces.  */
+#define GCS0_ADDR		0x05000000 /* GCS0 - Common SRAM (2MB) */
+#define GCS0_SIZE		0x00200000 /*   2MB */
+#define GCS1_ADDR		0x06000000 /* GCS1 - Flash ROM (8MB) */
+#define GCS1_SIZE		0x00800000 /*   8MB */
+#define GCS2_ADDR		0x07900000 /* GCS2 - I/O registers */
+#define GCS2_SIZE		0x00400000 /*   4MB */
+#define GCS5_ADDR		0x04000000 /* GCS5 - PCI bus space */
+#define GCS5_SIZE		0x01000000 /*   16MB */
+#define GCS6_ADDR		0x07980000 /* GCS6 - PCI control registers */
+#define GCS6_SIZE		0x00000200 /*   512B */
+
+/* The SRAM on the Mother-A motherboard.  */
+#define MB_A_SRAM_ADDR		GCS0_ADDR
+#define MB_A_SRAM_SIZE		0x00200000 /* 2MB */
+
+
+/* GBUS interrupt support.  */
+#define GBUS_INT_BASE_IRQ	NUM_CPU_IRQS
+#define GBUS_INT_BASE_ADDR	(GCS2_ADDR + 0x00006000)
+#include <asm/gbus_int.h>
+
+/* We define NUM_MACH_IRQS to include extra interrupts from the GBUS.  */
+#define NUM_MACH_IRQS		(NUM_CPU_IRQS + IRQ_GBUS_INT_NUM)
+
+/* Some specific interrupts.  */
+#define IRQ_MB_A_LAN		IRQ_GBUS_INT(10)
+#define IRQ_MB_A_PCI1(n)	(IRQ_GBUS_INT(16) + (n))
+#define IRQ_MB_A_PCI1_NUM	4
+#define IRQ_MB_A_PCI2(n)	(IRQ_GBUS_INT(20) + (n))
+#define IRQ_MB_A_PCI2_NUM	4
+#define IRQ_MB_A_EXT(n)		(IRQ_GBUS_INT(24) + (n))
+#define IRQ_MB_A_EXT_NUM	4
+#define IRQ_MB_A_USB_OC(n)	(IRQ_GBUS_INT(28) + (n))
+#define IRQ_MB_A_USB_OC_NUM	2
+#define IRQ_MB_A_PCMCIA_OC	IRQ_GBUS_INT(30)
+
+
+/* Mother-A PCI bus support.  */
+#include <asm/rte_mb_a_pci.h>
+
+/* These are the base addresses used for allocating device address
+   space.  512K of the motherboard SRAM is in the same space, so we have
+   to be careful not to let it be allocated.  */
+#define PCIBIOS_MIN_MEM		(MB_A_PCI_MEM_ADDR + 0x80000)
+#define PCIBIOS_MIN_IO		MB_A_PCI_IO_ADDR
+
+/* As we don't really support PCI DMA to cpu memory, and use bounce-buffers
+   instead, perversely enough, this becomes always true! */
+#define pci_dma_supported(dev, mask)		1
+#define pci_dac_dma_supported(dev, mask)	0
+#define pci_controller_num(dev)			0
+#define pcibios_assign_all_busses()		1
+
+
+
+/* For <asm/param.h> */
+#ifndef HZ
+#define HZ	100
+#endif
+
+
+#ifndef __ASSEMBLY__
+
+extern void rte_cb_init_irqs (void);
+
+#endif /* !__ASSEMBLY__ */
+
+
+#endif /* __V850_RTE_CB_H__ */
diff -Nru a/include/asm-v850/rte_ma1_cb.h b/include/asm-v850/rte_ma1_cb.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/rte_ma1_cb.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,112 @@
+/*
+ * include/asm-v850/rte_ma1_cb.h -- Midas labs RTE-V850/MA1-CB board
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_RTE_MA1_CB_H__
+#define __V850_RTE_MA1_CB_H__
+
+#include <asm/rte_cb.h>		/* Common defs for Midas RTE-CB boards.  */
+
+
+/* The GBUS GINT0 - GINT4 interrupts are connected to the INTP000 - INTP011
+   pins on the CPU.  These are shared among the GBUS interrupts.  */
+#define IRQ_GINT(n)		IRQ_INTP(n)
+#define IRQ_GINT_NUM		4
+
+
+#define PLATFORM		"rte-v850e/ma1-cb"
+#define PLATFORM_LONG		"Midas lab RTE-V850E/MA1-CB"
+
+#define CPU_CLOCK_FREQ		50000000 /* 50MHz */
+
+/* 1MB of onboard SRAM.  Note that the monitor ROM uses parts of this
+   for its own purposes, so care must be taken.  Some address lines are
+   not decoded, so the SRAM area is mirrored every 1MB from 0x400000 to
+   0x800000 (exclusive).  */
+#define SRAM_ADDR		0x00400000
+#define SRAM_SIZE		0x00100000 /* 1MB */
+
+/* 32MB of onbard SDRAM.  */
+#define SDRAM_ADDR		0x00800000
+#define SDRAM_SIZE		0x02000000 /* 32MB */
+
+
+/* For <asm/page.h> */
+#define PAGE_OFFSET 		SRAM_ADDR
+
+
+#ifdef CONFIG_ROM_KERNEL
+/* Kernel is in ROM, starting at address 0.  */
+
+#define INTV_BASE		0
+
+#else /* !CONFIG_ROM_KERNEL */
+
+#ifdef CONFIG_RTE_CB_MULTI
+/* Using RAM kernel with ROM monitor for Multi debugger.  */
+
+/* The chip's real interrupt vectors are in ROM, but they jump to a
+   secondary interrupt vector table in RAM.  */
+#define INTV_BASE		0x004F8000
+
+/* Scratch memory used by the ROM monitor, which shouldn't be used by
+   linux (except for the alternate interrupt vector area, defined
+   above).  */
+#define MON_SCRATCH_ADDR	0x004F8000
+#define MON_SCRATCH_SIZE	0x00008000 /* 32KB */
+
+#else /* !CONFIG_RTE_CB_MULTI */
+/* Using RAM-kernel.  Assume some sort of boot-loader got us loaded at
+   address 0.  */
+
+#define INTV_BASE		0
+
+#endif /* CONFIG_RTE_CB_MULTI */
+
+#endif /* CONFIG_ROM_KERNEL */
+
+
+/* Some misc. on-board devices.  */
+
+/* Seven-segment LED display (two digits).  Write-only.  */
+#define LED_ADDR(n)		(0x07802000 + (n))
+#define LED(n)			(*(volatile unsigned char *)LED_ADDR(n))
+#define LED_NUM_DIGITS		2
+
+
+/* Override the basic MA uart pre-initialization so that we can
+   initialize extra stuff.  */
+#undef NB85E_UART_PRE_CONFIGURE	/* should be defined by <asm/ma.h> */
+#define NB85E_UART_PRE_CONFIGURE	rte_ma1_cb_uart_pre_configure
+#ifndef __ASSEMBLY__
+extern void rte_ma1_cb_uart_pre_configure (unsigned chan,
+					   unsigned cflags, unsigned baud);
+#endif
+
+/* This board supports RTS/CTS for the on-chip UART, but only for channel 0. */
+
+/* CTS for UART channel 0 is pin P43 (bit 3 of port 4).  */
+#define NB85E_UART_CTS(chan)	((chan) == 0 ? !(MA_PORT4_IO & 0x8) : 1)
+/* RTS for UART channel 0 is pin P42 (bit 2 of port 4).  */
+#define NB85E_UART_SET_RTS(chan, val)					      \
+   do {									      \
+	   if (chan == 0) {						      \
+		   unsigned old = MA_PORT4_IO; 				      \
+		   if (val)						      \
+			   MA_PORT4_IO = old & ~0x4;			      \
+		   else							      \
+			   MA_PORT4_IO = old | 0x4;			      \
+	   }								      \
+   } while (0)
+
+
+#endif /* __V850_RTE_MA1_CB_H__ */
diff -Nru a/include/asm-v850/rte_mb_a_pci.h b/include/asm-v850/rte_mb_a_pci.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/rte_mb_a_pci.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,56 @@
+/*
+ * include/asm-v850/mb_a_pci.h -- PCI support for Midas lab RTE-MOTHER-A board
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_MB_A_PCI_H__
+#define __V850_MB_A_PCI_H__
+
+
+#define MB_A_PCI_MEM_ADDR	GCS5_ADDR
+#define MB_A_PCI_MEM_SIZE	(GCS5_SIZE / 2)
+#define MB_A_PCI_IO_ADDR	(GCS5_ADDR + MB_A_PCI_MEM_SIZE)
+#define MB_A_PCI_IO_SIZE	(GCS5_SIZE / 2)
+#define MB_A_PCI_REG_BASE_ADDR	GCS6_ADDR
+
+#define MB_A_PCI_PCICR_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0x4)
+#define MB_A_PCI_PCICR		(*(volatile u16 *)MB_A_PCI_PCICR_ADDR)
+#define MB_A_PCI_PCISR_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0x6)
+#define MB_A_PCI_PCISR		(*(volatile u16 *)MB_A_PCI_PCISR_ADDR)
+#define MB_A_PCI_PCILTR_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0xD)
+#define MB_A_PCI_PCILTR		(*(volatile u8 *)MB_A_PCI_PCILTR_ADDR)
+#define MB_A_PCI_PCIBAR0_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0x10)
+#define MB_A_PCI_PCIBAR0	(*(volatile u32 *)MB_A_PCI_PCIBAR0_ADDR)
+#define MB_A_PCI_PCIBAR1_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0x14)
+#define MB_A_PCI_PCIBAR1	(*(volatile u32 *)MB_A_PCI_PCIBAR1_ADDR)
+#define MB_A_PCI_PCIBAR2_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0x18)
+#define MB_A_PCI_PCIBAR2	(*(volatile u32 *)MB_A_PCI_PCIBAR2_ADDR)
+#define MB_A_PCI_VENDOR_ID_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0x2C)
+#define MB_A_PCI_VENDOR_ID	(*(volatile u16 *)MB_A_PCI_VENDOR_ID_ADDR)
+#define MB_A_PCI_DEVICE_ID_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0x2E)
+#define MB_A_PCI_DEVICE_ID	(*(volatile u16 *)MB_A_PCI_DEVICE_ID_ADDR)
+#define MB_A_PCI_DMRR_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0x9C)
+#define MB_A_PCI_DMRR		(*(volatile u32 *)MB_A_PCI_DMRR_ADDR)
+#define MB_A_PCI_DMLBAM_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0xA0)
+#define MB_A_PCI_DMLBAM		(*(volatile u32 *)MB_A_PCI_DMLBAM_ADDR)
+#define MB_A_PCI_DMLBAI_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0xA4)
+#define MB_A_PCI_DMLBAI		(*(volatile u32 *)MB_A_PCI_DMLBAI_ADDR)
+#define MB_A_PCI_PCIPBAM_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0xA8)
+#define MB_A_PCI_PCIPBAM	(*(volatile u32 *)MB_A_PCI_PCIPBAM_ADDR)
+/* `PCI Configuration Address Register for Direct Master to PCI IO/CFG'  */
+#define MB_A_PCI_DMCFGA_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0xAC)
+#define MB_A_PCI_DMCFGA		(*(volatile u32 *)MB_A_PCI_DMCFGA_ADDR)
+/* `PCI Permanent Configuration ID Register'  */
+#define MB_A_PCI_PCIHIDR_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0xF0)
+#define MB_A_PCI_PCIHIDR	(*(volatile u32 *)MB_A_PCI_PCIHIDR_ADDR)
+
+
+#endif /* __V850_MB_A_PCI_H__ */
diff -Nru a/include/asm-v850/rte_nb85e_cb.h b/include/asm-v850/rte_nb85e_cb.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/rte_nb85e_cb.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,63 @@
+/*
+ * include/asm-v850/rte_nb85e_cb.h -- Midas labs RTE-V850/NB85E-CB board
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_RTE_NB85E_CB_H__
+#define __V850_RTE_NB85E_CB_H__
+
+#include <asm/rte_cb.h>		/* Common defs for Midas RTE-CB boards.  */
+
+#define PLATFORM	"rte-v850e/nb85e-cb"
+#define PLATFORM_LONG	"Midas lab RTE-V850E/NB85E-CB"
+
+#define CPU_CLOCK_FREQ	50000000 /* 50MHz */
+
+/* 1MB of onboard SRAM.  Note that the monitor ROM uses parts of this
+   for its own purposes, so care must be taken.  */
+#define SRAM_ADDR	0x03C00000
+#define SRAM_SIZE	0x00100000 /* 1MB */
+
+/* 16MB of onbard SDRAM.  */
+#define SDRAM_ADDR	0x01000000
+#define SDRAM_SIZE	0x01000000 /* 16MB */
+
+
+#ifdef CONFIG_ROM_KERNEL
+/* Kernel is in ROM, starting at address 0.  */
+
+#define INTV_BASE	0
+
+#else /* !CONFIG_ROM_KERNEL */
+/* We're using the ROM monitor.  */
+
+/* The chip's real interrupt vectors are in ROM, but they jump to a
+   secondary interrupt vector table in RAM.  */
+#define INTV_BASE	0x004F8000
+
+/* Scratch memory used by the ROM monitor, which shouldn't be used by
+   linux (except for the alternate interrupt vector area, defined
+   above).  */
+#define MON_SCRATCH_ADDR	0x03CE8000
+#define MON_SCRATCH_SIZE	0x00008000 /* 32KB */
+
+#endif /* CONFIG_ROM_KERNEL */
+
+
+/* Some misc. on-board devices.  */
+
+/* Seven-segment LED display (two digits).  Write-only.  */
+#define LED_ADDR(n)	(0x03802000 + (n))
+#define LED(n)		(*(volatile unsigned char *)LED_ADDR(n))
+#define LED_NUM_DIGITS	4
+
+
+#endif /* __V850_RTE_NB85E_CB_H__ */
diff -Nru a/include/asm-v850/scatterlist.h b/include/asm-v850/scatterlist.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/scatterlist.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,26 @@
+/*
+ * include/asm-v850/scatterlist.h
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_SCATTERLIST_H__
+#define __V850_SCATTERLIST_H__
+
+struct scatterlist {
+	struct page	*page;
+	unsigned	offset;
+	dma_addr_t	dma_address;
+	unsigned	length;
+};
+
+#define ISA_DMA_THRESHOLD	(~0UL)
+
+#endif /* __V850_SCATTERLIST_H__ */
diff -Nru a/include/asm-v850/segment.h b/include/asm-v850/segment.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/segment.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,36 @@
+#ifndef __V850_SEGMENT_H__
+#define __V850_SEGMENT_H__
+
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned long mm_segment_t;	/* domain register */
+
+#endif /* !__ASSEMBLY__ */
+
+
+#define __KERNEL_CS	0x0
+#define __KERNEL_DS	0x0
+
+#define __USER_CS	0x1
+#define __USER_DS	0x1
+
+#define KERNEL_DS	__KERNEL_DS
+#define KERNEL_CS	__KERNEL_CS
+#define USER_DS		__USER_DS
+#define USER_CS		__USER_CS
+
+#define segment_eq(a,b)	((a) == (b))
+
+#define get_ds()	(KERNEL_DS)
+#define get_fs()	(USER_DS)
+
+#define set_fs(seg)	((void)(seg))
+
+
+#define copy_segments(task, mm)	((void)((void)(task), (mm)))
+#define release_segments(mm)	((void)(mm))
+#define forget_segments()	((void)0)
+
+
+#endif /* __V850_SEGMENT_H__ */
diff -Nru a/include/asm-v850/semaphore.h b/include/asm-v850/semaphore.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/semaphore.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,86 @@
+#ifndef __V850_SEMAPHORE_H__
+#define __V850_SEMAPHORE_H__
+
+#include <linux/linkage.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <linux/rwsem.h>
+
+#include <asm/atomic.h>
+
+struct semaphore {
+	atomic_t count;
+	int sleepers;
+	wait_queue_head_t wait;
+};
+
+#define __SEMAPHORE_INITIALIZER(name,count)				      \
+	{ ATOMIC_INIT (count), 0,					      \
+	  __WAIT_QUEUE_HEAD_INITIALIZER ((name).wait) }
+
+#define __MUTEX_INITIALIZER(name)					      \
+	__SEMAPHORE_INITIALIZER (name,1)
+
+#define __DECLARE_SEMAPHORE_GENERIC(name,count)	\
+	struct semaphore name = __SEMAPHORE_INITIALIZER (name,count)
+
+#define DECLARE_MUTEX(name)		__DECLARE_SEMAPHORE_GENERIC (name,1)
+#define DECLARE_MUTEX_LOCKED(name)	__DECLARE_SEMAPHORE_GENERIC (name,0)
+
+extern inline void sema_init (struct semaphore *sem, int val)
+{
+	*sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
+}
+
+static inline void init_MUTEX (struct semaphore *sem)
+{
+	sema_init (sem, 1);
+}
+
+static inline void init_MUTEX_LOCKED (struct semaphore *sem)
+{
+	sema_init (sem, 0);
+}
+
+/*
+ * special register calling convention
+ */
+asmlinkage void __down_failed (void);
+asmlinkage int  __down_interruptible_failed (void);
+asmlinkage int  __down_trylock_failed (void);
+asmlinkage void __up_wakeup (void);
+
+extern void __down (struct semaphore * sem);
+extern int  __down_interruptible (struct semaphore * sem);
+extern int  __down_trylock (struct semaphore * sem);
+extern void __up (struct semaphore * sem);
+
+extern inline void down (struct semaphore * sem)
+{
+	if (atomic_dec_return (&sem->count) < 0)
+		__down (sem);
+}
+
+extern inline int down_interruptible (struct semaphore * sem)
+{
+	int ret = 0;
+	if (atomic_dec_return (&sem->count) < 0)
+		ret = __down_interruptible (sem);
+	return ret;
+}
+
+extern inline int down_trylock (struct semaphore *sem)
+{
+	int ret = 0;
+	if (atomic_dec_return (&sem->count) < 0)
+		ret = __down_trylock (sem);
+	return ret;
+}
+
+extern inline void up (struct semaphore * sem)
+{
+	if (atomic_inc_return (&sem->count) <= 0)
+		__up (sem);
+}
+
+#endif /* __V850_SEMAPHORE_H__ */
diff -Nru a/include/asm-v850/sembuf.h b/include/asm-v850/sembuf.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/sembuf.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,25 @@
+#ifndef __V850_SEMBUF_H__
+#define __V850_SEMBUF_H__
+
+/* 
+ * The semid64_ds structure for v850 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct semid64_ds {
+	struct ipc64_perm sem_perm;		/* permissions .. see ipc.h */
+	__kernel_time_t	sem_otime;		/* last semop time */
+	unsigned long	__unused1;
+	__kernel_time_t	sem_ctime;		/* last change time */
+	unsigned long	__unused2;
+	unsigned long	sem_nsems;		/* no. of semaphores in array */
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* __V850_SEMBUF_H__ */
diff -Nru a/include/asm-v850/setup.h b/include/asm-v850/setup.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/setup.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,37 @@
+/*
+ * include/asm-v850/setup.h
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_SETUP_H__
+#define __V850_SETUP_H__
+
+/* Linux/v850 platforms.  This corresponds roughly to what the outside
+   the CPU looks like.  */
+#define MACH_SIM	1	/* GDB architectural simulator */
+
+/* v850 cpu architectures.  This is what a user-program would be
+   concerned with.  */
+#define CPU_ARCH_V850E	1
+#define CPU_ARCH_V850E2	2
+
+/* v850 cpu `cores'.  These are system-level extensions to the basic CPU,
+   defining such things as interrupt-handling.  */
+#define CPU_CORE_NB85E	1
+#define CPU_CORE_NB85ET	2
+#define CPU_CORE_NU85E	3
+#define CPU_CORE_NU85ET	4
+
+/* Specific v850 cpu chips.  These each incorporate a `core', and add
+   varions peripheral services.  */
+#define CPU_CHIP_MA1	1
+
+#endif /* __V850_SETUP_H__ */
diff -Nru a/include/asm-v850/shmbuf.h b/include/asm-v850/shmbuf.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/shmbuf.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,42 @@
+#ifndef __V850_SHMBUF_H__
+#define __V850_SHMBUF_H__
+
+/* 
+ * The shmid64_ds structure for v850 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct shmid64_ds {
+	struct ipc64_perm	shm_perm;	/* operation perms */
+	size_t			shm_segsz;	/* size of segment (bytes) */
+	__kernel_time_t		shm_atime;	/* last attach time */
+	unsigned long		__unused1;
+	__kernel_time_t		shm_dtime;	/* last detach time */
+	unsigned long		__unused2;
+	__kernel_time_t		shm_ctime;	/* last change time */
+	unsigned long		__unused3;
+	__kernel_pid_t		shm_cpid;	/* pid of creator */
+	__kernel_pid_t		shm_lpid;	/* pid of last operator */
+	unsigned long		shm_nattch;	/* no. of current attaches */
+	unsigned long		__unused4;
+	unsigned long		__unused5;
+};
+
+struct shminfo64 {
+	unsigned long	shmmax;
+	unsigned long	shmmin;
+	unsigned long	shmmni;
+	unsigned long	shmseg;
+	unsigned long	shmall;
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* __V850_SHMBUF_H__ */
diff -Nru a/include/asm-v850/shmparam.h b/include/asm-v850/shmparam.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/shmparam.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,6 @@
+#ifndef __V850_SHMPARAM_H__
+#define __V850_SHMPARAM_H__
+
+#define	SHMLBA		PAGE_SIZE	/* attach addr a multiple of this */
+
+#endif /* __V850_SHMPARAM_H__ */
diff -Nru a/include/asm-v850/sigcontext.h b/include/asm-v850/sigcontext.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/sigcontext.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,25 @@
+/*
+ * include/asm-v850/sigcontext.h -- Signal contexts
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_SIGCONTEXT_H__
+#define __V850_SIGCONTEXT_H__
+
+#include <asm/ptrace.h>
+
+struct sigcontext
+{
+	struct pt_regs 	regs;
+	unsigned long	oldmask;
+};
+
+#endif /* __V850_SIGCONTEXT_H__ */
diff -Nru a/include/asm-v850/siginfo.h b/include/asm-v850/siginfo.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/siginfo.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,6 @@
+#ifndef __V850_SIGINFO_H__
+#define __V850_SIGINFO_H__
+
+#include <asm-generic/siginfo.h>
+
+#endif /* __V850_SIGINFO_H__ */
diff -Nru a/include/asm-v850/signal.h b/include/asm-v850/signal.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/signal.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,193 @@
+#ifndef __V850_SIGNAL_H__
+#define __V850_SIGNAL_H__
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+
+
+#ifdef __KERNEL__
+
+/* Most things should be clean enough to redefine this at will, if care
+   is taken to make libc match.  */
+#define _NSIG		64
+#define _NSIG_BPW	32
+#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t;		/* at least 32 bits */
+
+typedef struct {
+	unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#else /* !__KERNEL__ */
+
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+#define NSIG		32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+#define SIGBUS		 7
+#define SIGFPE		 8
+#define SIGKILL		 9
+#define SIGUSR1		10
+#define SIGSEGV		11
+#define SIGUSR2		12
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGSTKFLT	16
+#define SIGCHLD		17
+#define SIGCONT		18
+#define SIGSTOP		19
+#define SIGTSTP		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGURG		23
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGIO		29
+#define SIGPOLL		SIGIO
+/*
+#define SIGLOST		29
+*/
+#define SIGPWR		30
+#define SIGSYS		31
+#define	SIGUNUSED	31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN	32
+#define SIGRTMAX	(_NSIG-1)
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP	0x00000001
+#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_SIGINFO	0x00000004
+#define SA_ONSTACK	0x08000000
+#define SA_RESTART	0x10000000
+#define SA_NODEFER	0x40000000
+#define SA_RESETHAND	0x80000000
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+#define SA_INTERRUPT	0x20000000 /* dummy -- ignored */
+
+#define SA_RESTORER	0x04000000
+
+/* 
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	2048
+#define SIGSTKSZ	8192
+
+
+#ifdef __KERNEL__
+/*
+ * These values of sa_flags are used only by the kernel as part of the
+ * irq handling routines.
+ *
+ * SA_INTERRUPT is also used by the irq handling routines.
+ * SA_SHIRQ is for shared interrupt support on PCI and EISA.
+ */
+#define SA_PROBE		SA_ONESHOT
+#define SA_SAMPLE_RANDOM	SA_RESTART
+#define SA_SHIRQ		0x04000000
+#endif /* __KERNEL__ */
+
+
+#define SIG_BLOCK          0	/* for blocking signals */
+#define SIG_UNBLOCK        1	/* for unblocking signals */
+#define SIG_SETMASK        2	/* for setting the signal mask */
+
+/* Type of a signal handler.  */
+typedef void (*__sighandler_t)(int);
+
+#define SIG_DFL	((__sighandler_t)0)	/* default signal handling */
+#define SIG_IGN	((__sighandler_t)1)	/* ignore signal */
+#define SIG_ERR	((__sighandler_t)-1)	/* error return from signal */
+
+
+#ifdef __KERNEL__
+
+struct old_sigaction {
+	__sighandler_t sa_handler;
+	old_sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+struct sigaction {
+	__sighandler_t sa_handler;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+	sigset_t sa_mask;		/* mask last for extensibility */
+};
+
+struct k_sigaction {
+	struct sigaction sa;
+};
+
+#else /* !__KERNEL__ */
+
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+struct sigaction {
+	union {
+	  __sighandler_t _sa_handler;
+	  void (*_sa_sigaction)(int, struct siginfo *, void *);
+	} _u;
+	sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+#define sa_handler	_u._sa_handler
+#define sa_sigaction	_u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+
+typedef struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+} stack_t;
+
+#ifdef __KERNEL__
+
+#include <asm/sigcontext.h>
+#undef __HAVE_ARCH_SIG_BITOPS
+
+#endif /* __KERNEL__ */
+
+#endif /* __V850_SIGNAL_H__ */
diff -Nru a/include/asm-v850/sim.h b/include/asm-v850/sim.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/sim.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,49 @@
+/*
+ * include/asm-v850/sim.h -- Machine-dependent defs for GDB v850e simulator
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_SIM_H__
+#define __V850_SIM_H__
+
+
+#define CPU_ARCH		"v850e"
+#define CPU_MODEL		"GDB/v850e simulator"
+
+
+/* We use a wierd value for RAM, not just 0, for testing purposes.
+   These must match the values used in the linker script.  */
+#define RAM_ADDR		0x8F000000
+#define RAM_SIZE		0x01000000
+
+
+/* For <asm/page.h> */
+#define PAGE_OFFSET 		RAM_ADDR
+
+
+/* For <asm/entry.h> */
+/* `R0 RAM', used for a few miscellaneous variables that must be
+   accessible using a load instruction relative to R0.  On real
+   processors, this usually is on-chip RAM, but here we just
+   choose an arbitrary address that meets the above constraint.  */
+#define R0_RAM_ADDR		0xFFFFF000
+
+
+/* For <asm/param.h> */
+#ifndef HZ
+#define HZ			24	/* Minimum supported frequency.  */
+#endif
+
+/* For <asm/irq.h> */
+#define NUM_CPU_IRQS		6
+
+
+#endif /* __V850_SIM_H__ */
diff -Nru a/include/asm-v850/sim85e2c.h b/include/asm-v850/sim85e2c.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/sim85e2c.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,89 @@
+/*
+ * include/asm-v850/sim85e2c.h -- Machine-dependent defs for
+ *	V850E2 RTL simulator
+ *
+ *  Copyright (C) 2002  NEC Corporation
+ *  Copyright (C) 2002  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_SIM85E2C_H__
+#define __V850_SIM85E2C_H__
+
+
+#define CPU_ARCH		"v850e2"
+#define CPU_MODEL		"sim85e2c simulator"
+
+
+/* Various memory areas supported by the simulator.
+   These should match the corresponding definitions in the linker script.  */
+
+/* `instruction RAM'; instruction fetches are much faster from IRAM than
+   from DRAM.  */
+#define IRAM_ADDR		0
+#define IRAM_SIZE		0x00100000 /* 1MB */
+/* `data RAM', below and contiguous with the I/O space.
+   Data fetches are much faster from DRAM than from IRAM.  */
+#define DRAM_ADDR		0xfff00000
+#define DRAM_SIZE		0x000ff000 /* 1020KB */
+/* `external ram'.  Unlike the above RAM areas, this memory is cached,
+   so both instruction and data fetches should be (mostly) fast --
+   however, currently only write-through caching is supported, so writes
+   to ERAM will be slow.  */
+#define ERAM_ADDR		0x00100000
+#define ERAM_SIZE		0x07f00000 /* 127MB (max) */
+
+
+/* CPU core control registers; these should be expanded and moved into
+   separate header files when we support some other processors based on
+   the same E2 core.  */
+/* Bus Transaction Control Register */
+#define NA85E2C_CACHE_BTSC_ADDR	0xfffff070
+#define NA85E2C_CACHE_BTSC 	(*(volatile unsigned short *)NA85E2C_CACHE_BTSC_ADDR)
+#define NA85E2C_CACHE_BTSC_ICM	0x1 /* icache enable */
+#define NA85E2C_CACHE_BTSC_DCM0	0x4 /* dcache enable, bit 0 */
+#define NA85E2C_CACHE_BTSC_DCM1	0x8 /* dcache enable, bit 1 */
+/* Cache Configuration Register */
+#define NA85E2C_BUSM_BHC_ADDR	0xfffff06a
+#define NA85E2C_BUSM_BHC	(*(volatile unsigned short *)NA85E2C_BUSM_BHC_ADDR)
+
+/* Simulator specific control registers.  */
+/* NOTHAL controls whether the simulator will stop at a `halt' insn.  */
+#define NOTHAL_ADDR		0xffffff22
+#define NOTHAL			(*(volatile unsigned char *)NOTHAL_ADDR)
+/* The simulator will stop N cycles after N is written to SIMFIN.  */
+#define SIMFIN_ADDR		0xffffff24
+#define SIMFIN			(*(volatile unsigned short *)SIMFIN_ADDR)
+
+
+/* The simulator has an nb85e-style interrupt system.  */
+#include <asm/nb85e_intc.h>
+
+/* For <asm/irq.h> */
+#define NUM_CPU_IRQS		64
+
+
+/* For <asm/page.h> */
+#define PAGE_OFFSET		DRAM_ADDR
+
+
+/* For <asm/entry.h> */
+/* `R0 RAM', used for a few miscellaneous variables that must be accessible
+   using a load instruction relative to R0.  The sim85e2c simulator
+   actually puts 1020K of RAM from FFF00000 to FFFFF000, so we arbitarily
+   choose a small portion at the end of that.  */
+#define R0_RAM_ADDR		0xFFFFE000
+
+
+/* For <asm/param.h> */
+#ifndef HZ
+#define HZ			24	/* Minimum supported frequency.  */
+#endif
+
+
+#endif /* __V850_SIM85E2C_H__ */
diff -Nru a/include/asm-v850/simsyscall.h b/include/asm-v850/simsyscall.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/simsyscall.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,99 @@
+/*
+ * include/asm-v850/simsyscall.h -- `System calls' under the v850e emulator
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_SIMSYSCALL_H__
+#define __V850_SIMSYSCALL_H__
+
+#define V850_SIM_SYS_exit(a...)		V850_SIM_SYSCALL_1 (1	, ##a)
+#define V850_SIM_SYS_fork(a...)		V850_SIM_SYSCALL_0 (2	, ##a)
+#define V850_SIM_SYS_read(a...)		V850_SIM_SYSCALL_3 (3	, ##a)
+#define V850_SIM_SYS_write(a...)	V850_SIM_SYSCALL_3 (4	, ##a)
+#define V850_SIM_SYS_open(a...)		V850_SIM_SYSCALL_2 (5	, ##a)
+#define V850_SIM_SYS_close(a...)	V850_SIM_SYSCALL_1 (6	, ##a)
+#define V850_SIM_SYS_wait4(a...)	V850_SIM_SYSCALL_4 (7	, ##a)
+/* #define V850_SIM_SYS_creat(a...)	V850_SIM_SYSCALL_1 (8	, ##a) */
+/* #define V850_SIM_SYS_link(a...)	V850_SIM_SYSCALL_1 (9	, ##a) */
+/* #define V850_SIM_SYS_unlink(a...)	V850_SIM_SYSCALL_1 (10	, ##a) */
+#define V850_SIM_SYS_execv(a...)	V850_SIM_SYSCALL_2 (11	, ##a)
+/* #define V850_SIM_SYS_chdir(a...)	V850_SIM_SYSCALL_1 (12	, ##a) */
+/* #define V850_SIM_SYS_mknod(a...)	V850_SIM_SYSCALL_1 (14	, ##a) */
+#define V850_SIM_SYS_chmod(a...)	V850_SIM_SYSCALL_2 (15	, ##a)
+#define V850_SIM_SYS_chown(a...)	V850_SIM_SYSCALL_2 (16	, ##a)
+#define V850_SIM_SYS_lseek(a...)	V850_SIM_SYSCALL_3 (19	, ##a)
+/* #define V850_SIM_SYS_getpid(a...)	V850_SIM_SYSCALL_1 (20	, ##a) */
+/* #define V850_SIM_SYS_isatty(a...)	V850_SIM_SYSCALL_1 (21	, ##a) */
+/* #define V850_SIM_SYS_fstat(a...)	V850_SIM_SYSCALL_1 (22	, ##a) */
+#define V850_SIM_SYS_time(a...)		V850_SIM_SYSCALL_1 (23	, ##a)
+#define V850_SIM_SYS_poll(a...)		V850_SIM_SYSCALL_3 (24	, ##a)
+#define V850_SIM_SYS_stat(a...)		V850_SIM_SYSCALL_2 (38	, ##a)
+#define V850_SIM_SYS_pipe(a...)		V850_SIM_SYSCALL_1 (42	, ##a)
+#define V850_SIM_SYS_times(a...)	V850_SIM_SYSCALL_1 (43	, ##a)
+#define V850_SIM_SYS_execve(a...)	V850_SIM_SYSCALL_3 (59	, ##a)
+#define V850_SIM_SYS_gettimeofday(a...)	V850_SIM_SYSCALL_2 (116	, ##a)
+/* #define V850_SIM_SYS_utime(a...)	V850_SIM_SYSCALL_2 (201	, ##a) */
+/* #define V850_SIM_SYS_wait(a...)	V850_SIM_SYSCALL_1 (202	, ##a) */
+
+#define V850_SIM_SYS_make_raw(a...)	V850_SIM_SYSCALL_1 (1024 , ##a)
+
+
+#define V850_SIM_SYSCALL_0(_call)					      \
+({									      \
+	register int call __asm__ ("r6") = _call;			      \
+	register int rval __asm__ ("r10");				      \
+	__asm__ __volatile__ ("trap 31"					      \
+			      : "=r" (rval)				      \
+			      : "r" (call)				      \
+			      : "r11", "memory");			      \
+	rval;								      \
+})
+#define V850_SIM_SYSCALL_1(_call, _arg0)				      \
+({									      \
+	register int call __asm__ ("r6") = _call;			      \
+	register long arg0 __asm__ ("r7") = (long)_arg0;		      \
+	register int rval __asm__ ("r10");				      \
+	__asm__ __volatile__ ("trap 31"					      \
+			      : "=r" (rval)				      \
+			      : "r" (call), "r" (arg0)			      \
+			      : "r11", "memory");			      \
+	rval;								      \
+})
+#define V850_SIM_SYSCALL_2(_call, _arg0, _arg1)				      \
+({									      \
+	register int call __asm__ ("r6") = _call;			      \
+	register long arg0 __asm__ ("r7") = (long)_arg0;		      \
+	register long arg1 __asm__ ("r8") = (long)_arg1;		      \
+	register int rval __asm__ ("r10");				      \
+	__asm__ __volatile__ ("trap 31"					      \
+			      : "=r" (rval)				      \
+			      : "r" (call), "r" (arg0), "r" (arg1)	      \
+			      : "r11", "memory");			      \
+	rval;								      \
+})
+#define V850_SIM_SYSCALL_3(_call, _arg0, _arg1, _arg2)			      \
+({									      \
+	register int call __asm__ ("r6") = _call;			      \
+	register long arg0 __asm__ ("r7") = (long)_arg0;		      \
+	register long arg1 __asm__ ("r8") = (long)_arg1;		      \
+	register long arg2 __asm__ ("r9") = (long)_arg2;		      \
+	register int rval __asm__ ("r10");				      \
+	__asm__ __volatile__ ("trap 31"					      \
+			      : "=r" (rval)				      \
+			      : "r" (call), "r" (arg0), "r" (arg1), "r" (arg2)\
+			      : "r11", "memory");			      \
+	rval;								      \
+})
+
+#define V850_SIM_SYSCALL(call, args...) \
+   V850_SIM_SYS_##call (args)
+
+#endif /* __V850_SIMSYSCALL_H__ */
diff -Nru a/include/asm-v850/socket.h b/include/asm-v850/socket.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/socket.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,64 @@
+#ifndef __V850_SOCKET_H__
+#define __V850_SOCKET_H__
+
+#include <asm/sockios.h>
+
+/* For setsockoptions(2) */
+#define SOL_SOCKET	1
+
+#define SO_DEBUG	1
+#define SO_REUSEADDR	2
+#define SO_TYPE		3
+#define SO_ERROR	4
+#define SO_DONTROUTE	5
+#define SO_BROADCAST	6
+#define SO_SNDBUF	7
+#define SO_RCVBUF	8
+#define SO_KEEPALIVE	9
+#define SO_OOBINLINE	10
+#define SO_NO_CHECK	11
+#define SO_PRIORITY	12
+#define SO_LINGER	13
+#define SO_BSDCOMPAT	14
+/* To add :#define SO_REUSEPORT 15 */
+#define SO_PASSCRED	16
+#define SO_PEERCRED	17
+#define SO_RCVLOWAT	18
+#define SO_SNDLOWAT	19
+#define SO_RCVTIMEO	20
+#define SO_SNDTIMEO	21
+
+/* Security levels - as per NRL IPv6 - don't actually do anything */
+#define SO_SECURITY_AUTHENTICATION		22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT	23
+#define SO_SECURITY_ENCRYPTION_NETWORK		24
+
+#define SO_BINDTODEVICE	25
+
+/* Socket filtering */
+#define SO_ATTACH_FILTER        26
+#define SO_DETACH_FILTER        27
+
+#define SO_PEERNAME             28
+#define SO_TIMESTAMP		29
+#define SCM_TIMESTAMP		SO_TIMESTAMP
+
+#define SO_ACCEPTCONN		30
+
+/* Nast libc5 fixup - bletch */
+#if defined(__KERNEL__)
+/* Socket types. */
+#define SOCK_STREAM	1		/* stream (connection) socket	*/
+#define SOCK_DGRAM	2		/* datagram (conn.less) socket	*/
+#define SOCK_RAW	3		/* raw socket			*/
+#define SOCK_RDM	4		/* reliably-delivered message	*/
+#define SOCK_SEQPACKET	5		/* sequential packet socket	*/
+#define SOCK_PACKET	10		/* linux specific way of	*/
+					/* getting packets at the dev	*/
+					/* level.  For writing rarp and	*/
+					/* other similar things on the	*/
+					/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
+#endif
+
+#endif /* __V850_SOCKET_H__ */
diff -Nru a/include/asm-v850/sockios.h b/include/asm-v850/sockios.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/sockios.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,12 @@
+#ifndef __V850_SOCKIOS_H__
+#define __V850_SOCKIOS_H__
+
+/* Socket-level I/O control calls. */
+#define FIOSETOWN 	0x8901
+#define SIOCSPGRP	0x8902
+#define FIOGETOWN	0x8903
+#define SIOCGPGRP	0x8904
+#define SIOCATMARK	0x8905
+#define SIOCGSTAMP	0x8906		/* Get stamp */
+
+#endif /* __V850_SOCKIOS_H__ */
diff -Nru a/include/asm-v850/softirq.h b/include/asm-v850/softirq.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/softirq.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,20 @@
+#ifndef __V850_SOFTIRQ_H__
+#define __V850_SOFTIRQ_H__
+
+#include <linux/preempt.h>
+#include <asm/hardirq.h>
+
+#define local_bh_disable() \
+		do { preempt_count() += SOFTIRQ_OFFSET; barrier(); } while (0)
+#define __local_bh_enable() \
+		do { barrier(); preempt_count() -= SOFTIRQ_OFFSET; } while (0)
+
+#define local_bh_enable()						\
+do {									\
+	__local_bh_enable();						\
+	if (unlikely(!in_interrupt() && softirq_pending(smp_processor_id()))) \
+		do_softirq();						\
+	preempt_check_resched();					\
+} while (0)
+
+#endif	/* __V850_SOFTIRQ_H__ */
diff -Nru a/include/asm-v850/stat.h b/include/asm-v850/stat.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/stat.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,60 @@
+#ifndef __V850_STAT_H__
+#define __V850_STAT_H__
+
+struct stat {
+	__kernel_dev_t	st_dev;
+	__kernel_ino_t	st_ino;
+	__kernel_mode_t	st_mode;
+	__kernel_nlink_t st_nlink;
+	__kernel_uid_t 	st_uid;
+	__kernel_gid_t 	st_gid;
+	__kernel_dev_t	st_rdev;
+	__kernel_off_t	st_size;
+	unsigned long	st_blksize;
+	unsigned long	st_blocks;
+	unsigned long	st_atime;
+	unsigned long	__unused1;
+	unsigned long	st_mtime;
+	unsigned long	__unused2;
+	unsigned long	st_ctime;
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+	unsigned long	__unused5;
+};
+
+struct stat64 {
+	__kernel_dev_t	st_dev;
+	unsigned long	__unused0;
+	unsigned long	__unused1;
+
+	__kernel_ino64_t st_ino;
+
+	__kernel_mode_t	st_mode;
+	__kernel_nlink_t st_nlink;
+
+	__kernel_uid_t	st_uid;
+	__kernel_gid_t	st_gid;
+
+	__kernel_dev_t	st_rdev;
+	unsigned long	__unused2;
+	unsigned long	__unused3;
+
+	__kernel_loff_t	st_size;
+	unsigned long	st_blksize;
+
+	unsigned long	st_blocks; /* No. of 512-byte blocks allocated */
+	unsigned long	__unused4; /* future possible st_blocks high bits */
+
+	unsigned long	st_atime;
+	unsigned long	__unused5;
+
+	unsigned long	st_mtime;
+	unsigned long	__unused6;
+
+	unsigned long	st_ctime;
+	unsigned long	__unused7; /* high 32 bits of ctime someday */
+
+	unsigned long	__unused8;
+};
+
+#endif /* __V850_STAT_H__ */
diff -Nru a/include/asm-v850/statfs.h b/include/asm-v850/statfs.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/statfs.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,25 @@
+#ifndef __V850_STATFS_H__
+#define __V850_STATFS_H__
+
+#ifndef __KERNEL_STRICT_NAMES
+
+#include <linux/types.h>
+
+typedef __kernel_fsid_t	fsid_t;
+
+#endif
+
+struct statfs {
+	long f_type;
+	long f_bsize;
+	long f_blocks;
+	long f_bfree;
+	long f_bavail;
+	long f_files;
+	long f_ffree;
+	__kernel_fsid_t f_fsid;
+	long f_namelen;
+	long f_spare[6];
+};
+
+#endif /* __V850_STATFS_H__ */
diff -Nru a/include/asm-v850/string.h b/include/asm-v850/string.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/string.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,27 @@
+/*
+ * include/asm-v850/string.h -- Architecture specific string routines
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_STRING_H__
+#define __V850_STRING_H__
+
+#define __HAVE_ARCH_BCOPY
+#define __HAVE_ARCH_MEMCPY
+#define __HAVE_ARCH_MEMSET
+#define __HAVE_ARCH_MEMMOVE
+
+extern void *memcpy (void *, const void *, __kernel_size_t);
+extern void bcopy (const char *, char *, int);
+extern void *memset (void *, int, __kernel_size_t);
+extern void *memmove (void *, const void *, __kernel_size_t);
+
+#endif /* __V850_STRING_H__ */
diff -Nru a/include/asm-v850/system.h b/include/asm-v850/system.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/system.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,115 @@
+/*
+ * include/asm-v850/system.h -- Low-level interrupt/thread ops
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_SYSTEM_H__
+#define __V850_SYSTEM_H__
+
+#include <linux/linkage.h>
+#include <asm/ptrace.h>
+
+
+#define prepare_to_switch()	do { } while (0)
+
+/*
+ * switch_to(n) should switch tasks to task ptr, first checking that
+ * ptr isn't the current task, in which case it does nothing.
+ */
+struct thread_struct;
+extern void *switch_thread (struct thread_struct *last,
+			    struct thread_struct *next);
+#define switch_to(prev,next,last)					      \
+  do {									      \
+        if (prev != next) {						      \
+ 		(last) = switch_thread (&prev->thread, &next->thread);	      \
+	}								      \
+  } while (0)
+
+
+/* Enable/disable interrupts.  */
+#define local_irq_enable()	__asm__ __volatile__ ("ei")
+#define local_irq_disable()	__asm__ __volatile__ ("di")
+
+#define local_save_flags(flags) \
+  __asm__ __volatile__ ("stsr %1, %0" : "=r" (flags) : "i" (SR_PSW))
+#define local_restore_flags(flags) \
+  __asm__ __volatile__ ("ldsr %0, %1" :: "r" (flags), "i" (SR_PSW))
+
+/* For spinlocks etc */
+#define	local_irq_save(flags) \
+  do { local_save_flags (flags); local_irq_disable (); } while (0) 
+#define local_irq_restore(flags) \
+  local_restore_flags (flags);
+
+
+static inline int irqs_disabled (void)
+{
+	unsigned flags;
+	local_save_flags (flags);
+	return !!(flags & 0x20);
+}
+
+
+/*
+ * Force strict CPU ordering.
+ * Not really required on v850...
+ */
+#define nop()			__asm__ __volatile__ ("nop")
+#define mb()			__asm__ __volatile__ ("" ::: "memory")
+#define rmb()			mb ()
+#define wmb()			mb ()
+#define set_rmb(var, value)	do { xchg (&var, value); } while (0)
+#define set_mb(var, value)	set_rmb (var, value)
+#define set_wmb(var, value)	do { var = value; wmb (); } while (0)
+
+#ifdef CONFIG_SMP
+#define smp_mb()	mb ()
+#define smp_rmb()	rmb ()
+#define smp_wmb()	wmb ()
+#else
+#define smp_mb()	barrier ()
+#define smp_rmb()	barrier ()
+#define smp_wmb()	barrier ()
+#endif
+
+#define xchg(ptr, with) \
+  ((__typeof__ (*(ptr)))__xchg ((unsigned long)(with), (ptr), sizeof (*(ptr))))
+#define tas(ptr) (xchg ((ptr), 1))
+
+extern inline unsigned long __xchg (unsigned long with,
+				    __volatile__ void *ptr, int size)
+{
+	unsigned long tmp, flags;
+
+	local_irq_save (flags);
+
+	switch (size) {
+	case 1:
+		tmp = *(unsigned char *)ptr;
+		*(unsigned char *)ptr = with;
+		break;
+	case 2:
+		tmp = *(unsigned short *)ptr;
+		*(unsigned short *)ptr = with;
+		break;
+	case 4:
+		tmp = *(unsigned long *)ptr;
+		*(unsigned long *)ptr = with;
+		break;
+	}
+
+	local_irq_restore (flags);
+
+	return tmp;
+}
+
+#endif /* __V850_SYSTEM_H__ */
diff -Nru a/include/asm-v850/teg.h b/include/asm-v850/teg.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/teg.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,58 @@
+/*
+ * include/asm-v850/nb85e_teg.h -- NB85E-TEG cpu chip
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_NB85E_TEG_H__
+#define __V850_NB85E_TEG_H__
+
+/* The NB85E_TEG uses the NB85E cpu core.  */
+#include <asm/nb85e.h>
+
+#define CHIP		"v850e/nb85e-teg"
+#define CHIP_LONG	"NEC V850E/NB85E TEG"
+
+/* Hardware-specific interrupt numbers (in the kernel IRQ namespace).  */
+#define IRQ_INTOV(n)	(n)	/* 0-3 */
+#define IRQ_INTOV_NUM	4
+#define IRQ_INTCMD(n)	(0x1c + (n)) /* interval timer interrupts 0-3 */
+#define IRQ_INTCMD_NUM	4
+#define IRQ_INTDMA(n)	(0x20 + (n)) /* DMA interrupts 0-3 */
+#define IRQ_INTDMA_NUM	4
+#define IRQ_INTCSI(n)	(0x24 + (n)) /* CSI 0-2 transmit/receive completion */
+#define IRQ_INTCSI_NUM	3
+#define IRQ_INTSER(n)	(0x25 + (n)) /* UART 0-2 reception error */
+#define IRQ_INTSER_NUM	3
+#define IRQ_INTSR(n)	(0x26 + (n)) /* UART 0-2 reception completion */
+#define IRQ_INTSR_NUM	3
+#define IRQ_INTST(n)	(0x27 + (n)) /* UART 0-2 transmission completion */
+#define IRQ_INTST_NUM	3
+
+/* For <asm/irq.h> */
+#define NUM_MACH_IRQS	0x30
+
+/* TEG UART details.  */
+#define NB85E_UART_BASE_ADDR(n)		(0xFFFFF600 + 0x10 * (n))
+#define NB85E_UART_ASIM_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0x0)
+#define NB85E_UART_ASIS_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0x2)
+#define NB85E_UART_ASIF_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0x4)
+#define NB85E_UART_CKSR_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0x6)
+#define NB85E_UART_BRGC_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0x8)
+#define NB85E_UART_TXB_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0xA)
+#define NB85E_UART_RXB_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0xC)
+#define NB85E_UART_NUM_CHANNELS		1
+#define NB85E_UART_BASE_FREQ		CPU_CLOCK_FREQ
+
+/* The TEG RTPU.  */
+#define NB85E_RTPU_BASE_ADDR		0xFFFFF210
+
+
+#endif /* __V850_NB85E_TEG_H__ */
diff -Nru a/include/asm-v850/termbits.h b/include/asm-v850/termbits.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/termbits.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,174 @@
+#ifndef __V850_TERMBITS_H__
+#define __V850_TERMBITS_H__
+
+#include <linux/posix_types.h>
+
+typedef unsigned char	cc_t;
+typedef unsigned int	speed_t;
+typedef unsigned int	tcflag_t;
+
+#define NCCS 19
+struct termios {
+	tcflag_t c_iflag;		/* input mode flags */
+	tcflag_t c_oflag;		/* output mode flags */
+	tcflag_t c_cflag;		/* control mode flags */
+	tcflag_t c_lflag;		/* local mode flags */
+	cc_t c_line;			/* line discipline */
+	cc_t c_cc[NCCS];		/* control characters */
+};
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+
+/* c_iflag bits */
+#define IGNBRK	0000001
+#define BRKINT	0000002
+#define IGNPAR	0000004
+#define PARMRK	0000010
+#define INPCK	0000020
+#define ISTRIP	0000040
+#define INLCR	0000100
+#define IGNCR	0000200
+#define ICRNL	0000400
+#define IUCLC	0001000
+#define IXON	0002000
+#define IXANY	0004000
+#define IXOFF	0010000
+#define IMAXBEL	0020000
+
+/* c_oflag bits */
+#define OPOST	0000001
+#define OLCUC	0000002
+#define ONLCR	0000004
+#define OCRNL	0000010
+#define ONOCR	0000020
+#define ONLRET	0000040
+#define OFILL	0000100
+#define OFDEL	0000200
+#define NLDLY	0000400
+#define   NL0	0000000
+#define   NL1	0000400
+#define CRDLY	0003000
+#define   CR0	0000000
+#define   CR1	0001000
+#define   CR2	0002000
+#define   CR3	0003000
+#define TABDLY	0014000
+#define   TAB0	0000000
+#define   TAB1	0004000
+#define   TAB2	0010000
+#define   TAB3	0014000
+#define   XTABS	0014000
+#define BSDLY	0020000
+#define   BS0	0000000
+#define   BS1	0020000
+#define VTDLY	0040000
+#define   VT0	0000000
+#define   VT1	0040000
+#define FFDLY	0100000
+#define   FF0	0000000
+#define   FF1	0100000
+
+/* c_cflag bit meaning */
+#define CBAUD	0010017
+#define  B0	0000000		/* hang up */
+#define  B50	0000001
+#define  B75	0000002
+#define  B110	0000003
+#define  B134	0000004
+#define  B150	0000005
+#define  B200	0000006
+#define  B300	0000007
+#define  B600	0000010
+#define  B1200	0000011
+#define  B1800	0000012
+#define  B2400	0000013
+#define  B4800	0000014
+#define  B9600	0000015
+#define  B19200	0000016
+#define  B38400	0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE	0000060
+#define   CS5	0000000
+#define   CS6	0000020
+#define   CS7	0000040
+#define   CS8	0000060
+#define CSTOPB	0000100
+#define CREAD	0000200
+#define PARENB	0000400
+#define PARODD	0001000
+#define HUPCL	0002000
+#define CLOCAL	0004000
+#define CBAUDEX 0010000
+#define    B57600 0010001
+#define   B115200 0010002
+#define   B230400 0010003
+#define   B460800 0010004
+#define   B500000 0010005
+#define   B576000 0010006
+#define   B921600 0010007
+#define  B1000000 0010010
+#define  B1152000 0010011
+#define  B1500000 0010012
+#define  B2000000 0010013
+#define  B2500000 0010014
+#define  B3000000 0010015
+#define  B3500000 0010016
+#define  B4000000 0010017
+#define CIBAUD	  002003600000	/* input baud rate (not used) */
+#define CMSPAR	  010000000000		/* mark or space (stick) parity */
+#define CRTSCTS	  020000000000		/* flow control */
+
+/* c_lflag bits */
+#define ISIG	0000001
+#define ICANON	0000002
+#define XCASE	0000004
+#define ECHO	0000010
+#define ECHOE	0000020
+#define ECHOK	0000040
+#define ECHONL	0000100
+#define NOFLSH	0000200
+#define TOSTOP	0000400
+#define ECHOCTL	0001000
+#define ECHOPRT	0002000
+#define ECHOKE	0004000
+#define FLUSHO	0010000
+#define PENDIN	0040000
+#define IEXTEN	0100000
+
+
+/* tcflow() and TCXONC use these */
+#define	TCOOFF		0
+#define	TCOON		1
+#define	TCIOFF		2
+#define	TCION		3
+
+/* tcflush() and TCFLSH use these */
+#define	TCIFLUSH	0
+#define	TCOFLUSH	1
+#define	TCIOFLUSH	2
+
+/* tcsetattr uses these */
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+
+#endif /* __V850_TERMBITS_H__ */
diff -Nru a/include/asm-v850/termios.h b/include/asm-v850/termios.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/termios.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,106 @@
+#ifndef __V850_TERMIOS_H__
+#define __V850_TERMIOS_H__
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+	unsigned short c_iflag;		/* input mode flags */
+	unsigned short c_oflag;		/* output mode flags */
+	unsigned short c_cflag;		/* control mode flags */
+	unsigned short c_lflag;		/* local mode flags */
+	unsigned char c_line;		/* line discipline */
+	unsigned char c_cc[NCC];	/* control characters */
+};
+
+/* modem lines */
+#define TIOCM_LE	0x001
+#define TIOCM_DTR	0x002
+#define TIOCM_RTS	0x004
+#define TIOCM_ST	0x008
+#define TIOCM_SR	0x010
+#define TIOCM_CTS	0x020
+#define TIOCM_CAR	0x040
+#define TIOCM_RNG	0x080
+#define TIOCM_DSR	0x100
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RI	TIOCM_RNG
+#define TIOCM_OUT1	0x2000
+#define TIOCM_OUT2	0x4000
+#define TIOCM_LOOP	0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+/* line disciplines */
+#define N_TTY		0
+#define N_SLIP		1
+#define N_MOUSE		2
+#define N_PPP		3
+#define N_STRIP		4
+#define N_AX25		5
+#define N_X25		6	/* X.25 async */
+#define N_6PACK		7
+#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
+#define N_R3964		9	/* Reserved for Simatic R3964 module */
+#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
+#define N_IRDA		11	/* Linux IR - http://irda.sourceforge.net/ */
+#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
+#define N_HDLC		13	/* synchronous HDLC */
+#define N_SYNC_PPP	14	/* synchronous PPP */
+#define N_HCI		15  /* Bluetooth HCI UART */
+
+#ifdef __KERNEL__
+
+/*	intr=^C		quit=^\		erase=del	kill=^U
+	eof=^D		vtime=\0	vmin=\1		sxtc=\0
+	start=^Q	stop=^S		susp=^Z		eol=\0
+	reprint=^R	discard=^U	werase=^W	lnext=^V
+	eol2=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
+	unsigned short __tmp; \
+	get_user(__tmp,&(termio)->x); \
+	*(unsigned short *) &(termios)->x = __tmp; \
+}
+
+#define user_termio_to_kernel_termios(termios, termio) \
+({ \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
+	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+})
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ */
+#define kernel_termios_to_user_termio(termio, termios) \
+({ \
+	put_user((termios)->c_iflag, &(termio)->c_iflag); \
+	put_user((termios)->c_oflag, &(termio)->c_oflag); \
+	put_user((termios)->c_cflag, &(termio)->c_cflag); \
+	put_user((termios)->c_lflag, &(termio)->c_lflag); \
+	put_user((termios)->c_line,  &(termio)->c_line); \
+	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+})
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
+
+#endif	/* __KERNEL__ */
+
+#endif	/* __V850_TERMIOS_H__ */
diff -Nru a/include/asm-v850/thread_info.h b/include/asm-v850/thread_info.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/thread_info.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,129 @@
+/*
+ * include/asm-v850/thread_info.h -- v850 low-level thread information
+ *
+ *  Copyright (C) 2002  NEC Corporation
+ *  Copyright (C) 2002  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 2002  David Howells (dhowells@redhat.com)
+ *    - Incorporating suggestions made by Linus Torvalds and Dave Miller
+ *
+ * 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.
+ *
+ * This file was derived from the PPC version, include/asm-ppc/thread_info.h
+ * which was adapted from the i386 version by Paul Mackerras
+ */
+
+#ifndef __V850_THREAD_INFO_H__
+#define __V850_THREAD_INFO_H__
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+/*
+ * low level task data.
+ * If you change this, change the TI_* offsets below to match.
+ */
+struct thread_info {
+	struct task_struct	*task;		/* main task structure */
+	struct exec_domain	*exec_domain;	/* execution domain */
+	unsigned long		flags;		/* low level flags */
+	int			cpu;		/* cpu we're on */
+	int			preempt_count;
+};
+
+#define INIT_THREAD_INFO(tsk)			\
+{						\
+	.task =		&tsk,			\
+	.exec_domain =	&default_exec_domain,	\
+	.flags =	0,			\
+	.cpu =		0,			\
+	.preempt_count = 1			\
+}
+
+#define init_thread_info	(init_thread_union.thread_info)
+#define init_stack		(init_thread_union.stack)
+
+/*
+ * macros/functions for gaining access to the thread information structure
+ */
+
+/* thread information allocation */
+#define alloc_thread_info() ((struct thread_info *) \
+				__get_free_pages(GFP_KERNEL, 1))
+#define free_thread_info(ti)	free_pages((unsigned long) (ti), 1)
+#define get_thread_info(ti)	get_task_struct((ti)->task)
+#define put_thread_info(ti)	put_task_struct((ti)->task)
+
+#endif /* __ASSEMBLY__ */
+
+
+/*
+ * Offsets in thread_info structure, used in assembly code
+ */
+#define TI_TASK		0
+#define TI_EXECDOMAIN	4
+#define TI_FLAGS	8
+#define TI_CPU		12
+#define TI_PREEMPT	16
+#define TI_SOFTIRQ	20
+#define TI_HARDIRQ	24
+
+#define PREEMPT_ACTIVE		0x4000000
+
+/*
+ * thread information flag bit numbers
+ */
+#define TIF_SYSCALL_TRACE	0	/* syscall trace active */
+#define TIF_NOTIFY_RESUME	1	/* resumption notification requested */
+#define TIF_SIGPENDING		2	/* signal pending */
+#define TIF_NEED_RESCHED	3	/* rescheduling necessary */
+#define TIF_POLLING_NRFLAG	4	/* true if poll_idle() is polling
+					   TIF_NEED_RESCHED */
+
+/* as above, but as bit values */
+#define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
+#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
+#define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
+#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
+
+
+/* Size of kernel stack for each process.  */
+#define THREAD_SIZE		0x2000
+
+/* The alignment of kernel threads, with thread_info structures at their
+   base.  Thus, a pointer for a task's task structure can be derived from
+   its kernel stack pointer.  */
+#define THREAD_ALIGNMENT	THREAD_SIZE
+#define THREAD_MASK		(-THREAD_ALIGNMENT)
+
+
+#ifdef __ASSEMBLY__
+
+/* Put a pointer to the current thread_info structure into REG.  Note that
+   this definition requires THREAD_MASK to be representable as a signed
+   16-bit value.  */
+#define GET_CURRENT_THREAD(reg)						\
+        /* Use `addi' and then `and' instead of just `andi', because	\
+	   `addi' sign-extends the immediate value, whereas `andi'	\
+	   zero-extends it.  */						\
+	addi	THREAD_MASK, r0, reg;					\
+	and	sp, reg
+
+#else
+
+/* Return a pointer to the current thread_info structure.  */
+static inline struct thread_info *current_thread_info (void)
+{
+	register unsigned long sp __asm__ ("sp");
+	return (struct thread_info *)(sp & THREAD_MASK);
+}
+
+#endif /* __ASSEMBLY__ */
+
+
+#endif /* __KERNEL__ */
+
+#endif /* __V850_THREAD_INFO_H__ */
diff -Nru a/include/asm-v850/timex.h b/include/asm-v850/timex.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/timex.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,22 @@
+/*
+ * linux/include/asm-v850/timex.h
+ *
+ * v850 architecture timex specifications
+ */
+#ifndef __V850_TIMEX_H__
+#define __V850_TIMEX_H__
+
+#define CLOCK_TICK_RATE	1193180 /* Underlying HZ */
+#define CLOCK_TICK_FACTOR	20	/* Factor of both 1000000 and CLOCK_TICK_RATE */
+#define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \
+	(1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \
+		<< (SHIFT_SCALE-SHIFT_HZ)) / HZ)
+
+typedef unsigned long cycles_t;
+
+static inline cycles_t get_cycles(void)
+{
+	return 0;
+}
+
+#endif /* __V850_TIMEX_H__ */
diff -Nru a/include/asm-v850/tlb.h b/include/asm-v850/tlb.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/tlb.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,21 @@
+/*
+ * include/asm-v850/tlb.h
+ *
+ *  Copyright (C) 2002  NEC Corporation
+ *  Copyright (C) 2002  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_TLB_H__
+#define __V850_TLB_H__
+
+#define tlb_flush(tlb)	((void)0)
+
+#include <asm-generic/tlb.h>
+
+#endif /* __V850_TLB_H__ */
diff -Nru a/include/asm-v850/tlbflush.h b/include/asm-v850/tlbflush.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/tlbflush.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,71 @@
+/*
+ * include/asm-v850/tlbflush.h
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_TLBFLUSH_H__
+#define __V850_TLBFLUSH_H__
+
+#include <asm/setup.h>
+#include <asm/machdep.h>
+
+
+/*
+ * flush all user-space atc entries.
+ */
+static inline void __flush_tlb(void)
+{
+	BUG ();
+}
+
+static inline void __flush_tlb_one(unsigned long addr)
+{
+	BUG ();
+}
+
+#define flush_tlb() __flush_tlb()
+
+/*
+ * flush all atc entries (both kernel and user-space entries).
+ */
+static inline void flush_tlb_all(void)
+{
+	BUG ();
+}
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+	BUG ();
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
+{
+	BUG ();
+}
+
+static inline void flush_tlb_range(struct vm_area_struct *vma,
+				   unsigned long start, unsigned long end)
+{
+	BUG ();
+}
+
+extern inline void flush_tlb_kernel_page(unsigned long addr)
+{
+	BUG ();
+}
+
+extern inline void flush_tlb_pgtables(struct mm_struct *mm,
+				      unsigned long start, unsigned long end)
+{
+	BUG ();
+}
+
+#endif /* __V850_TLBFLUSH_H__ */
diff -Nru a/include/asm-v850/topology.h b/include/asm-v850/topology.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/topology.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,6 @@
+#ifndef __V850_TOPOLOGY_H__
+#define __V850_TOPOLOGY_H__
+
+#include <asm-generic/topology.h>
+
+#endif /* __V850_TOPOLOGY_H__ */
diff -Nru a/include/asm-v850/types.h b/include/asm-v850/types.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/types.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,62 @@
+#ifndef __V850_TYPES_H__
+#define __V850_TYPES_H__
+
+#ifndef __ASSEMBLY__
+
+/*
+ * This file is never included by application software unless
+ * explicitly requested (e.g., via linux/types.h) in which case the
+ * application is Linux specific so (user-) name space pollution is
+ * not a major issue.  However, for interoperability, libraries still
+ * need to be careful to avoid a name clashes.
+ */
+
+typedef unsigned short umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+#define BITS_PER_LONG 32
+
+/* Dma addresses are 32-bits wide.  */
+
+typedef u32 dma_addr_t;
+
+#endif /* __KERNEL__ */
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __V850_TYPES_H__ */
diff -Nru a/include/asm-v850/uaccess.h b/include/asm-v850/uaccess.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/uaccess.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,159 @@
+#ifndef __V850_UACCESS_H__
+#define __V850_UACCESS_H__
+
+/*
+ * User space memory access functions
+ */
+#include <linux/sched.h>
+
+#include <asm/segment.h>
+#include <asm/machdep.h>
+
+#define VERIFY_READ	0
+#define VERIFY_WRITE	1
+
+extern inline int access_ok (int type, const void *addr, unsigned long size)
+{
+	/* XXX I guess we should check against real ram bounds at least, and
+	   possibly make sure ADDR is not within the kernel.
+	   For now we just check to make sure it's not a small positive
+	   or negative value, as that will at least catch some kinds of
+	   error.  In particular, we make sure that ADDR's not within the
+	   interrupt vector area, which we know starts at zero, or within the
+	   peripheral-I/O area, which is located just _before_ zero.  */
+	unsigned long val = (unsigned long)addr;
+	return val >= (0x80 + NUM_CPU_IRQS*16) && val < 0xFFFFF000;
+}
+
+extern inline int verify_area (int type, const void *addr, unsigned long size)
+{
+	return access_ok (type, addr, size) ? 0 : -EFAULT;
+}
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry
+{
+	unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table (unsigned long);
+
+
+/*
+ * These are the main single-value transfer routines.  They automatically
+ * use the right size if we just have the right pointer type.
+ */
+
+extern int bad_user_access_length (void);
+
+#define __get_user(var, ptr)						      \
+  ({									      \
+	  int __gu_err = 0;						      \
+	  typeof(*(ptr)) __gu_val = 0;					      \
+	  switch (sizeof (*(ptr))) {					      \
+	  case 1:							      \
+	  case 2:							      \
+	  case 4:							      \
+		  __gu_val = *(ptr);					      \
+		  break;						      \
+	  case 8:							      \
+		  memcpy(&__gu_val, ptr, sizeof(__gu_val));		      \
+		  break;						      \
+	  default:							      \
+		  __gu_val = 0;						      \
+		  __gu_err = __get_user_bad ();				      \
+		  break;						      \
+	  }								      \
+	  (var) = __gu_val;						      \
+	  __gu_err;							      \
+  })
+#define __get_user_bad()	(bad_user_access_length (), (-EFAULT))
+
+#define __put_user(var, ptr)						      \
+  ({									      \
+	  int __pu_err = 0;						      \
+	  switch (sizeof (*(ptr))) {					      \
+	  case 1:							      \
+	  case 2:							      \
+	  case 4:							      \
+		  *(ptr) = (var);					      \
+		  break;						      \
+	  case 8: {							      \
+	  	  typeof(*(ptr)) __pu_val = 0;				      \
+		  memcpy(ptr, &__pu_val, sizeof(__pu_val));		      \
+		  }							      \
+		  break;						      \
+	  default:							      \
+		  __pu_err = __put_user_bad ();				      \
+		  break;						      \
+	  }								      \
+	  __pu_err;							      \
+  })
+#define __put_user_bad()	(bad_user_access_length (), (-EFAULT))
+
+#define put_user(x, ptr)	__put_user(x, ptr)
+#define get_user(x, ptr)	__get_user(x, ptr)
+
+#define __copy_from_user(to, from, n)	(memcpy (to, from, n), 0)
+#define __copy_to_user(to, from, n)	(memcpy(to, from, n), 0)
+
+#define copy_from_user(to, from, n)	__copy_from_user (to, from, n)
+#define copy_to_user(to, from, n) 	__copy_to_user(to, from, n)
+
+#define copy_to_user_ret(to,from,n,retval) \
+  ({ if (copy_to_user (to,from,n)) return retval; })
+
+#define copy_from_user_ret(to,from,n,retval) \
+  ({ if (copy_from_user (to,from,n)) return retval; })
+
+/*
+ * Copy a null terminated string from userspace.
+ */
+
+static inline long
+strncpy_from_user (char *dst, const char *src, long count)
+{
+	char *tmp;
+	strncpy (dst, src, count);
+	for (tmp = dst; *tmp && count > 0; tmp++, count--)
+		;
+	return tmp - dst;
+}
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 on exception, a value greater than N if too long
+ */
+static inline long strnlen_user (const char *src, long n)
+{
+	return strlen (src) + 1;
+}
+
+#define strlen_user(str)	strnlen_user (str, 32767)
+
+/*
+ * Zero Userspace
+ */
+
+static inline unsigned long
+clear_user (void *to, unsigned long n)
+{
+	memset (to, 0, n);
+	return 0;
+}
+
+#endif /* __V850_UACCESS_H__ */
diff -Nru a/include/asm-v850/ucontext.h b/include/asm-v850/ucontext.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/ucontext.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,14 @@
+#ifndef __V850_UCONTEXT_H__
+#define __V850_UCONTEXT_H__
+
+#include <asm/sigcontext.h>
+
+struct ucontext {
+	unsigned long	  uc_flags;
+	struct ucontext  *uc_link;
+	stack_t		  uc_stack;
+	struct sigcontext uc_mcontext;
+	sigset_t	  uc_sigmask;	/* mask last for extensibility */
+};
+
+#endif /* __V850_UCONTEXT_H__ */
diff -Nru a/include/asm-v850/unaligned.h b/include/asm-v850/unaligned.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/unaligned.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,130 @@
+/*
+ * include/asm-v850/unaligned.h -- Unaligned memory access
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * This file is a copy of the arm version, include/asm-arm/unaligned.h
+ *
+ * Note that some v850 chips support unaligned access, but it seems too
+ * annoying to use.
+ */
+
+#ifndef __V850_UNALIGNED_H__
+#define __V850_UNALIGNED_H__
+
+#include <asm/types.h>
+
+extern int __bug_unaligned_x(void *ptr);
+
+/*
+ * What is the most efficient way of loading/storing an unaligned value?
+ *
+ * That is the subject of this file.  Efficiency here is defined as
+ * minimum code size with minimum register usage for the common cases.
+ * It is currently not believed that long longs are common, so we
+ * trade efficiency for the chars, shorts and longs against the long
+ * longs.
+ *
+ * Current stats with gcc 2.7.2.2 for these functions:
+ *
+ *	ptrsize	get:	code	regs	put:	code	regs
+ *	1		1	1		1	2
+ *	2		3	2		3	2
+ *	4		7	3		7	3
+ *	8		20	6		16	6
+ *
+ * gcc 2.95.1 seems to code differently:
+ *
+ *	ptrsize	get:	code	regs	put:	code	regs
+ *	1		1	1		1	2
+ *	2		3	2		3	2
+ *	4		7	4		7	4
+ *	8		19	8		15	6
+ *
+ * which may or may not be more efficient (depending upon whether
+ * you can afford the extra registers).  Hopefully the gcc 2.95
+ * is inteligent enough to decide if it is better to use the
+ * extra register, but evidence so far seems to suggest otherwise.
+ *
+ * Unfortunately, gcc is not able to optimise the high word
+ * out of long long >> 32, or the low word from long long << 32
+ */
+
+#define __get_unaligned_2(__p)					\
+	(__p[0] | __p[1] << 8)
+
+#define __get_unaligned_4(__p)					\
+	(__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24)
+
+#define get_unaligned(ptr)					\
+	({							\
+		__typeof__(*(ptr)) __v;				\
+		__u8 *__p = (__u8 *)(ptr);			\
+		switch (sizeof(*(ptr))) {			\
+		case 1:	__v = *(ptr);			break;	\
+		case 2: __v = __get_unaligned_2(__p);	break;	\
+		case 4: __v = __get_unaligned_4(__p);	break;	\
+		case 8: {					\
+				unsigned int __v1, __v2;	\
+				__v2 = __get_unaligned_4((__p+4)); \
+				__v1 = __get_unaligned_4(__p);	\
+				__v = ((unsigned long long)__v2 << 32 | __v1);	\
+			}					\
+			break;					\
+		default: __v = __bug_unaligned_x(__p);	break;	\
+		}						\
+		__v;						\
+	})
+
+
+extern inline void __put_unaligned_2(__u32 __v, register __u8 *__p)
+{
+	*__p++ = __v;
+	*__p++ = __v >> 8;
+}
+
+extern inline void __put_unaligned_4(__u32 __v, register __u8 *__p)
+{
+	__put_unaligned_2(__v >> 16, __p + 2);
+	__put_unaligned_2(__v, __p);
+}
+
+extern inline void __put_unaligned_8(const unsigned long long __v, register __u8 *__p)
+{
+	/*
+	 * tradeoff: 8 bytes of stack for all unaligned puts (2
+	 * instructions), or an extra register in the long long
+	 * case - go for the extra register.
+	 */
+	__put_unaligned_4(__v >> 32, __p+4);
+	__put_unaligned_4(__v, __p);
+}
+
+/*
+ * Try to store an unaligned value as efficiently as possible.
+ */
+#define put_unaligned(val,ptr)					\
+	({							\
+		switch (sizeof(*(ptr))) {			\
+		case 1:						\
+			*(ptr) = (val);				\
+			break;					\
+		case 2: __put_unaligned_2((val),(__u8 *)(ptr));	\
+			break;					\
+		case 4:	__put_unaligned_4((val),(__u8 *)(ptr));	\
+			break;					\
+		case 8:	__put_unaligned_8((val),(__u8 *)(ptr)); \
+			break;					\
+		default: __bug_unaligned_x(ptr);		\
+			break;					\
+		}						\
+		(void) 0;					\
+	})
+
+
+#endif /* __V850_UNALIGNED_H__ */
diff -Nru a/include/asm-v850/unistd.h b/include/asm-v850/unistd.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/unistd.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,411 @@
+/*
+ * include/asm-v850/unistd.h -- System call numbers and invocation mechanism
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_UNISTD_H__
+#define __V850_UNISTD_H__
+
+#include <asm/clinkage.h>
+
+#define __NR_exit		  1
+#define __NR_fork		  2
+#define __NR_read		  3
+#define __NR_write		  4
+#define __NR_open		  5
+#define __NR_close		  6
+#define __NR_waitpid		  7
+#define __NR_creat		  8
+#define __NR_link		  9
+#define __NR_unlink		 10
+#define __NR_execve		 11
+#define __NR_chdir		 12
+#define __NR_time		 13
+#define __NR_mknod		 14
+#define __NR_chmod		 15
+#define __NR_chown		 16
+#define __NR_break		 17
+#define __NR_lseek		 19
+#define __NR_getpid		 20
+#define __NR_mount		 21
+#define __NR_umount		 22
+#define __NR_setuid		 23
+#define __NR_getuid		 24
+#define __NR_stime		 25
+#define __NR_ptrace		 26
+#define __NR_alarm		 27
+#define __NR_pause		 29
+#define __NR_utime		 30
+#define __NR_stty		 31
+#define __NR_gtty		 32
+#define __NR_access		 33
+#define __NR_nice		 34
+#define __NR_ftime		 35
+#define __NR_sync		 36
+#define __NR_kill		 37
+#define __NR_rename		 38
+#define __NR_mkdir		 39
+#define __NR_rmdir		 40
+#define __NR_dup		 41
+#define __NR_pipe		 42
+#define __NR_times		 43
+#define __NR_prof		 44
+#define __NR_brk		 45
+#define __NR_setgid		 46
+#define __NR_getgid		 47
+#define __NR_signal		 48
+#define __NR_geteuid		 49
+#define __NR_getegid		 50
+#define __NR_acct		 51
+#define __NR_umount2		 52
+#define __NR_lock		 53
+#define __NR_ioctl		 54
+#define __NR_fcntl		 55
+#define __NR_setpgid		 57
+#define __NR_umask		 60
+#define __NR_chroot		 61
+#define __NR_ustat		 62
+#define __NR_dup2		 63
+#define __NR_getppid		 64
+#define __NR_getpgrp		 65
+#define __NR_setsid		 66
+#define __NR_sigaction		 67
+#define __NR_sgetmask		 68
+#define __NR_ssetmask		 69
+#define __NR_setreuid		 70
+#define __NR_setregid		 71
+#define __NR_sigsuspend		 72
+#define __NR_sigpending		 73
+#define __NR_sethostname	 74
+#define __NR_setrlimit		 75
+#define __NR_ugetrlimit	 	 76
+#define __NR_getrusage		 77
+#define __NR_gettimeofday	 78
+#define __NR_settimeofday	 79
+#define __NR_getgroups		 80
+#define __NR_setgroups		 81
+#define __NR_select		 82
+#define __NR_symlink		 83
+#define __NR_readlink		 85
+#define __NR_uselib		 86
+#define __NR_swapon		 87
+#define __NR_reboot		 88
+#define __NR_readdir		 89
+#define __NR_mmap		 90
+#define __NR_munmap		 91
+#define __NR_truncate		 92
+#define __NR_ftruncate		 93
+#define __NR_fchmod		 94
+#define __NR_fchown		 95
+#define __NR_getpriority	 96
+#define __NR_setpriority	 97
+#define __NR_profil		 98
+#define __NR_statfs		 99
+#define __NR_fstatfs		100
+#define __NR_socketcall		102
+#define __NR_syslog		103
+#define __NR_setitimer		104
+#define __NR_getitimer		105
+#define __NR_stat		106
+#define __NR_lstat		107
+#define __NR_fstat		108
+#define __NR_vhangup		111
+#define __NR_wait4		114
+#define __NR_swapoff		115
+#define __NR_sysinfo		116
+#define __NR_ipc		117
+#define __NR_fsync		118
+#define __NR_sigreturn		119
+#define __NR_clone		120
+#define __NR_setdomainname	121
+#define __NR_uname		122
+#define __NR_cacheflush		123
+#define __NR_adjtimex		124
+#define __NR_mprotect		125
+#define __NR_sigprocmask	126
+#define __NR_create_module	127
+#define __NR_init_module	128
+#define __NR_delete_module	129
+#define __NR_get_kernel_syms	130
+#define __NR_quotactl		131
+#define __NR_getpgid		132
+#define __NR_fchdir		133
+#define __NR_bdflush		134
+#define __NR_sysfs		135
+#define __NR_personality	136
+#define __NR_afs_syscall	137 /* Syscall for Andrew File System */
+#define __NR_setfsuid		138
+#define __NR_setfsgid		139
+#define __NR__llseek		140
+#define __NR_getdents		141
+#define __NR_flock		143
+#define __NR_msync		144
+#define __NR_readv		145
+#define __NR_writev		146
+#define __NR_getsid		147
+#define __NR_fdatasync		148
+#define __NR__sysctl		149
+#define __NR_mlock		150
+#define __NR_munlock		151
+#define __NR_mlockall		152
+#define __NR_munlockall		153
+#define __NR_sched_setparam		154
+#define __NR_sched_getparam		155
+#define __NR_sched_setscheduler		156
+#define __NR_sched_getscheduler		157
+#define __NR_sched_yield		158
+#define __NR_sched_get_priority_max	159
+#define __NR_sched_get_priority_min	160
+#define __NR_sched_rr_get_interval	161
+#define __NR_nanosleep		162
+#define __NR_mremap		163
+#define __NR_setresuid		164
+#define __NR_getresuid		165
+#define __NR_query_module	167
+#define __NR_poll		168
+#define __NR_nfsservctl		169
+#define __NR_setresgid		170
+#define __NR_getresgid		171
+#define __NR_prctl		172
+#define __NR_rt_sigreturn	173
+#define __NR_rt_sigaction	174
+#define __NR_rt_sigprocmask	175
+#define __NR_rt_sigpending	176
+#define __NR_rt_sigtimedwait	177
+#define __NR_rt_sigqueueinfo	178
+#define __NR_rt_sigsuspend	179
+#define __NR_pread		180
+#define __NR_pwrite		181
+#define __NR_lchown		182
+#define __NR_getcwd		183
+#define __NR_capget		184
+#define __NR_capset		185
+#define __NR_sigaltstack	186
+#define __NR_sendfile		187
+#define __NR_getpmsg		188	/* some people actually want streams */
+#define __NR_putpmsg		189	/* some people actually want streams */
+#define __NR_vfork		190
+#define __NR_mmap2		192
+#define __NR_truncate64		193
+#define __NR_ftruncate64	194
+#define __NR_stat64		195
+#define __NR_lstat64		196
+#define __NR_fstat64		197
+#define __NR_fcntl64		198
+#define __NR_getdents64		199
+#define __NR_pivot_root		200
+#define __NR_gettid		201
+#define __NR_tkill		202
+/* #define __NR_mincore		203 */
+/* #define __NR_madvise		204 */
+
+
+/* Syscall protocol:
+   Syscall number in r12, args in r6-r9, r13-r14
+   Return value in r10
+   Trap 0 for `short' syscalls, where all the args can fit in function
+   call argument registers, and trap 1 when there are additional args in
+   r13-r14.  */
+
+#define SYSCALL_NUM	"r12"
+#define SYSCALL_ARG0	"r6"
+#define SYSCALL_ARG1	"r7"
+#define SYSCALL_ARG2	"r8"
+#define SYSCALL_ARG3	"r9"
+#define SYSCALL_ARG4	"r13"
+#define SYSCALL_ARG5	"r14"
+#define SYSCALL_RET	"r10"
+
+#define SYSCALL_SHORT_TRAP	"0"
+#define SYSCALL_LONG_TRAP	"1"
+
+/* Registers clobbered by any syscall.  This _doesn't_ include the syscall
+   number (r12) or the `extended arg' registers (r13, r14), even though
+   they are actually clobbered too (this is because gcc's `asm' statement
+   doesn't allow a clobber to be used as an input or output).  */
+#define SYSCALL_CLOBBERS	"r1", "r5", "r11", "r15", "r16", \
+				"r17", "r18", "r19"
+
+/* Registers clobbered by a `short' syscall.  This includes all clobbers
+   except the syscall number (r12).  */
+#define SYSCALL_SHORT_CLOBBERS	SYSCALL_CLOBBERS, "r13", "r14"
+
+
+#define __syscall_return(type, res)					      \
+  do {									      \
+	  /* user-visible error numbers are in the range -1 - -124:	      \
+	     see <asm-v850/errno.h> */					      \
+	  if ((unsigned long)(res) >= (unsigned long)(-125)) {		      \
+		  errno = -(res);					      \
+		  res = -1;						      \
+	  }								      \
+	  return (type) (res);						      \
+  } while (0)
+
+
+#define _syscall0(type, name)						      \
+type name (void)							      \
+{									      \
+  register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name;	      \
+  register unsigned long __ret __asm__ (SYSCALL_RET);			      \
+  __asm__ __volatile__ ("trap " SYSCALL_SHORT_TRAP			      \
+			: "=r" (__ret), "=r" (__syscall)	 	      \
+			: "1" (__syscall)				      \
+			: SYSCALL_SHORT_CLOBBERS);			      \
+  __syscall_return (type, __ret);					      \
+}
+
+#define _syscall1(type, name, atype, a)					      \
+type name (atype a)							      \
+{									      \
+  register atype __a __asm__ (SYSCALL_ARG0) = a;			      \
+  register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name;	      \
+  register unsigned long __ret __asm__ (SYSCALL_RET);			      \
+  __asm__ __volatile__ ("trap " SYSCALL_SHORT_TRAP			      \
+			: "=r" (__ret), "=r" (__syscall)		      \
+			: "1" (__syscall), "r" (__a)			      \
+			: SYSCALL_SHORT_CLOBBERS);			      \
+  __syscall_return (type, __ret);					      \
+}
+
+#define _syscall2(type, name, atype, a, btype, b)			      \
+type name (atype a, btype b)						      \
+{									      \
+  register atype __a __asm__ (SYSCALL_ARG0) = a;			      \
+  register btype __b __asm__ (SYSCALL_ARG1) = b;			      \
+  register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name;	      \
+  register unsigned long __ret __asm__ (SYSCALL_RET);			      \
+  __asm__ __volatile__ ("trap " SYSCALL_SHORT_TRAP			      \
+			: "=r" (__ret), "=r" (__syscall)		      \
+			: "1" (__syscall), "r" (__a), "r" (__b)		      \
+			: SYSCALL_SHORT_CLOBBERS);			      \
+  __syscall_return (type, __ret);					      \
+}
+
+#define _syscall3(type, name, atype, a, btype, b, ctype, c)		      \
+type name (atype a, btype b, ctype c)					      \
+{									      \
+  register atype __a __asm__ (SYSCALL_ARG0) = a;			      \
+  register btype __b __asm__ (SYSCALL_ARG1) = b;			      \
+  register ctype __c __asm__ (SYSCALL_ARG2) = c;			      \
+  register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name;	      \
+  register unsigned long __ret __asm__ (SYSCALL_RET);			      \
+  __asm__ __volatile__ ("trap " SYSCALL_SHORT_TRAP			      \
+			: "=r" (__ret), "=r" (__syscall)		      \
+			: "1" (__syscall), "r" (__a), "r" (__b), "r" (__c)    \
+			: SYSCALL_SHORT_CLOBBERS);			      \
+  __syscall_return (type, __ret);					      \
+}
+
+#define _syscall4(type, name, atype, a, btype, b, ctype, c, dtype, d)	      \
+type name (atype a, btype b, ctype c, dtype d)				      \
+{									      \
+  register atype __a __asm__ (SYSCALL_ARG0) = a;			      \
+  register btype __b __asm__ (SYSCALL_ARG1) = b;			      \
+  register ctype __c __asm__ (SYSCALL_ARG2) = c;			      \
+  register dtype __d __asm__ (SYSCALL_ARG3) = d;			      \
+  register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name;	      \
+  register unsigned long __ret __asm__ (SYSCALL_RET);			      \
+  __asm__ __volatile__ ("trap " SYSCALL_SHORT_TRAP			      \
+			: "=r" (__ret), "=r" (__syscall)		      \
+			: "1" (__syscall),				      \
+			"r" (__a), "r" (__b), "r" (__c), "r" (__d)	      \
+			: SYSCALL_SHORT_CLOBBERS);			      \
+  __syscall_return (type, __ret);					      \
+}
+
+#define _syscall5(type, name, atype, a, btype, b, ctype, c, dtype, d, etype,e)\
+type name (atype a, btype b, ctype c, dtype d, etype e)			      \
+{									      \
+  register atype __a __asm__ (SYSCALL_ARG0) = a;			      \
+  register btype __b __asm__ (SYSCALL_ARG1) = b;			      \
+  register ctype __c __asm__ (SYSCALL_ARG2) = c;			      \
+  register dtype __d __asm__ (SYSCALL_ARG3) = d;			      \
+  register etype __e __asm__ (SYSCALL_ARG4) = e;			      \
+  register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name;	      \
+  register unsigned long __ret __asm__ (SYSCALL_RET);			      \
+  __asm__ __volatile__ ("trap " SYSCALL_LONG_TRAP			      \
+			: "=r" (__ret), "=r" (__syscall), "=r" (__e)	      \
+			: "1" (__syscall),				      \
+			"r" (__a), "r" (__b), "r" (__c), "r" (__d), "2" (__e) \
+			: SYSCALL_CLOBBERS);				      \
+  __syscall_return (type, __ret);					      \
+}
+
+#define _syscall6(type, name, atype, a, btype, b, ctype, c, dtype, d, etype, e, ftype, f) \
+type name (atype a, btype b, ctype c, dtype d, etype e, ftype f)	      \
+{									      \
+  register atype __a __asm__ (SYSCALL_ARG0) = a;			      \
+  register btype __b __asm__ (SYSCALL_ARG1) = b;			      \
+  register ctype __c __asm__ (SYSCALL_ARG2) = c;			      \
+  register dtype __d __asm__ (SYSCALL_ARG3) = d;			      \
+  register etype __e __asm__ (SYSCALL_ARG4) = e;			      \
+  register etype __f __asm__ (SYSCALL_ARG5) = f;			      \
+  register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name;	      \
+  register unsigned long __ret __asm__ (SYSCALL_RET);			      \
+  __asm__ __volatile__ ("trap " SYSCALL_LONG_TRAP			      \
+			: "=r" (__ret), "=r" (__syscall), 		      \
+ 			"=r" (__e), "=r" (__f)				      \
+			: "1" (__syscall),				      \
+			"r" (__a), "r" (__b), "r" (__c), "r" (__d),	      \
+			"2" (__e), "3" (__f)				      \
+			: SYSCALL_CLOBBERS);				      \
+  __syscall_return (type, __ret);					      \
+}
+		
+
+#ifdef __KERNEL_SYSCALLS__
+
+/*
+ * we need this inline - forking from kernel space will result
+ * in NO COPY ON WRITE (!!!), until an execve is executed. This
+ * is no problem, but for the stack. This is handled by not letting
+ * main() use the stack at all after fork(). Thus, no function
+ * calls - which means inline code for fork too, as otherwise we
+ * would use the stack upon exit from 'fork()'.
+ *
+ * Actually only pause and fork are needed inline, so that there
+ * won't be any messing with the stack from main(), but we define
+ * some others too.
+ */
+#define __NR__exit __NR_exit
+extern inline _syscall0(pid_t,setsid)
+extern inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
+extern inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
+extern inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
+extern inline _syscall1(int,dup,int,fd)
+extern inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
+extern inline _syscall3(int,open,const char *,file,int,flag,int,mode)
+extern inline _syscall1(int,close,int,fd)
+extern inline _syscall1(int,_exit,int,exitcode)
+extern inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+
+extern inline pid_t wait(int * wait_stat)
+{
+	return waitpid (-1, wait_stat, 0);
+}
+
+#endif
+
+/*
+ * "Conditional" syscalls
+ */
+#define cond_syscall(name)						\
+  asm (".weak\t" C_SYMBOL_STRING(name) ";"				\
+       ".set\t" C_SYMBOL_STRING(name) "," C_SYMBOL_STRING(sys_ni_syscall));
+#if 0
+/* This doesn't work if there's a function prototype for NAME visible,
+   because the argument types probably won't match.  */
+#define cond_syscall(name)  \
+  void name (void) __attribute__ ((weak, alias ("sys_ni_syscall")));
+#endif
+
+#endif /* __V850_UNISTD_H__ */
diff -Nru a/include/asm-v850/user.h b/include/asm-v850/user.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-v850/user.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,56 @@
+#ifndef __V850_USER_H__
+#define __V850_USER_H__
+
+/* Adapted from <asm-ppc/user.h>.  */
+
+#ifdef __KERNEL__
+
+#include <linux/ptrace.h>
+#include <asm/page.h>
+
+/*
+ * Core file format: The core file is written in such a way that gdb
+ * can understand it and provide useful information to the user (under
+ * linux we use the `trad-core' bfd, NOT the osf-core).  The file contents
+ * are as follows:
+ *
+ *  upage: 1 page consisting of a user struct that tells gdb
+ *	what is present in the file.  Directly after this is a
+ *	copy of the task_struct, which is currently not used by gdb,
+ *	but it may come in handy at some point.  All of the registers
+ *	are stored as part of the upage.  The upage should always be
+ *	only one page long.
+ *  data: The data segment follows next.  We use current->end_text to
+ *	current->brk to pick up all of the user variables, plus any memory
+ *	that may have been sbrk'ed.  No attempt is made to determine if a
+ *	page is demand-zero or if a page is totally unused, we just cover
+ *	the entire range.  All of the addresses are rounded in such a way
+ *	that an integral number of pages is written.
+ *  stack: We need the stack information in order to get a meaningful
+ *	backtrace.  We need to write the data from usp to
+ *	current->start_stack, so we round each of these in order to be able
+ *	to write an integer number of pages.
+ */
+struct user {
+	struct pt_regs	regs;			/* entire machine state */
+	size_t		u_tsize;		/* text size (pages) */
+	size_t		u_dsize;		/* data size (pages) */
+	size_t		u_ssize;		/* stack size (pages) */
+	unsigned long	start_code;		/* text starting address */
+	unsigned long	start_data;		/* data starting address */
+	unsigned long	start_stack;		/* stack starting address */
+	long int	signal;			/* signal causing core dump */
+	struct regs *	u_ar0;			/* help gdb find registers */
+	unsigned long	magic;			/* identifies a core file */
+	char		u_comm[32];		/* user command name */
+};
+
+#define NBPG			PAGE_SIZE
+#define UPAGES			1
+#define HOST_TEXT_START_ADDR	(u.start_code)
+#define HOST_DATA_START_ADDR	(u.start_data)
+#define HOST_STACK_END_ADDR	(u.start_stack + u.u_ssize * NBPG)
+
+#endif /* __KERNEL__ */
+
+#endif /* __V850_USER_H__ */
diff -Nru a/include/asm-x86_64/mman.h b/include/asm-x86_64/mman.h
--- a/include/asm-x86_64/mman.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-x86_64/mman.h	Mon Nov  4 14:31:01 2002
@@ -19,6 +19,8 @@
 #define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
 #define MAP_LOCKED	0x2000		/* pages are locked */
 #define MAP_NORESERVE	0x4000		/* don't check for reservations */
+#define MAP_POPULATE	0x8000		/* populate (prefault) pagetables */
+#define MAP_NONBLOCK	0x10000		/* do not block on IO */
 
 #define MS_ASYNC	1		/* sync memory asynchronously */
 #define MS_INVALIDATE	2		/* invalidate the caches */
diff -Nru a/include/asm-x86_64/poll.h b/include/asm-x86_64/poll.h
--- a/include/asm-x86_64/poll.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-x86_64/poll.h	Mon Nov  4 14:31:01 2002
@@ -15,6 +15,7 @@
 #define POLLWRNORM	0x0100
 #define POLLWRBAND	0x0200
 #define POLLMSG		0x0400
+#define POLLREMOVE	0x1000
 
 struct pollfd {
 	int fd;
diff -Nru a/include/asm-x86_64/ptrace.h b/include/asm-x86_64/ptrace.h
--- a/include/asm-x86_64/ptrace.h	Mon Nov  4 14:31:01 2002
+++ b/include/asm-x86_64/ptrace.h	Mon Nov  4 14:31:01 2002
@@ -32,10 +32,7 @@
 /* top of stack page */ 
 #define FRAME_SIZE 168
 
-#define PTRACE_SETOPTIONS         21
-
-/* options set using PTRACE_SETOPTIONS */
-#define PTRACE_O_TRACESYSGOOD     0x00000001
+#define PTRACE_OLDSETOPTIONS         21
 
 /* Dummy values for ptrace */ 
 #define FS 1000 
diff -Nru a/include/linux/blkdev.h b/include/linux/blkdev.h
--- a/include/linux/blkdev.h	Mon Nov  4 14:31:01 2002
+++ b/include/linux/blkdev.h	Mon Nov  4 14:31:01 2002
@@ -11,6 +11,22 @@
 
 #include <asm/scatterlist.h>
 
+/*
+ * Disk stats ...
+ */
+
+#define DK_MAX_MAJOR 16
+#define DK_MAX_DISK 16
+ 
+struct disk_stat {
+        unsigned int drive[DK_MAX_MAJOR][DK_MAX_DISK];
+        unsigned int drive_rio[DK_MAX_MAJOR][DK_MAX_DISK];
+        unsigned int drive_wio[DK_MAX_MAJOR][DK_MAX_DISK];
+        unsigned int drive_rblk[DK_MAX_MAJOR][DK_MAX_DISK];
+        unsigned int drive_wblk[DK_MAX_MAJOR][DK_MAX_DISK];
+};
+extern struct disk_stat dkstat;
+
 struct request_queue;
 typedef struct request_queue request_queue_t;
 struct elevator_s;
@@ -31,7 +47,6 @@
 				     * blkdev_dequeue_request! */
 	unsigned long flags;		/* see REQ_ bits below */
 
-	kdev_t rq_dev;
 	sector_t sector;
 	unsigned long nr_sectors;
 	unsigned int current_nr_sectors;
@@ -77,6 +92,7 @@
 	/*
 	 * when request is used as a packet command carrier
 	 */
+	unsigned int cmd_len;
 	unsigned char cmd[16];
 
 	unsigned int data_len;
diff -Nru a/include/linux/cpu.h b/include/linux/cpu.h
--- a/include/linux/cpu.h	Mon Nov  4 14:31:01 2002
+++ b/include/linux/cpu.h	Mon Nov  4 14:31:01 2002
@@ -1,5 +1,5 @@
 /*
- * cpu.h - generic cpu defition
+ * include/linux/cpu.h - generic cpu definition
  *
  * This is mainly for topological representation. We define the 
  * basic 'struct cpu' here, which can be embedded in per-arch 
@@ -15,14 +15,18 @@
  * See the following for how to do this: 
  * - drivers/base/intf.c 
  * - Documentation/driver-model/interface.txt
- *
  */
+#ifndef _LINUX_CPU_H_
+#define _LINUX_CPU_H_
 
 #include <linux/device.h>
-
-extern struct device_class cpu_devclass;
+#include <linux/node.h>
 
 struct cpu {
+	int node_id;		/* The node which contains the CPU */
 	struct sys_device sysdev;
 };
 
+extern int register_cpu(struct cpu *, int, struct node *);
+
+#endif /* _LINUX_CPU_H_ */
diff -Nru a/include/linux/cpufreq.h b/include/linux/cpufreq.h
--- a/include/linux/cpufreq.h	Mon Nov  4 14:31:02 2002
+++ b/include/linux/cpufreq.h	Mon Nov  4 14:31:02 2002
@@ -5,7 +5,7 @@
  *            (C) 2002 Dominik Brodowski <linux@brodo.de>
  *            
  *
- * $Id: cpufreq.h,v 1.26 2002/09/21 09:05:29 db Exp $
+ * $Id: cpufreq.h,v 1.27 2002/10/08 14:54:23 db Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -148,11 +148,9 @@
 int cpufreq_set_policy(struct cpufreq_policy *policy);
 int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu);
 
-#ifdef CONFIG_CPU_FREQ_26_API
 #ifdef CONFIG_PM
 int cpufreq_restore(void);
 #endif
-#endif
 
 
 #ifdef CONFIG_CPU_FREQ_24_API
@@ -160,9 +158,6 @@
  *                        CPUFREQ 2.4. INTERFACE                     *
  *********************************************************************/
 int cpufreq_setmax(unsigned int cpu);
-#ifdef CONFIG_PM
-int cpufreq_restore(void);
-#endif
 int cpufreq_set(unsigned int kHz, unsigned int cpu);
 unsigned int cpufreq_get(unsigned int cpu);
 
diff -Nru a/include/linux/dcache.h b/include/linux/dcache.h
--- a/include/linux/dcache.h	Mon Nov  4 14:31:03 2002
+++ b/include/linux/dcache.h	Mon Nov  4 14:31:03 2002
@@ -7,6 +7,7 @@
 #include <linux/mount.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
+#include <linux/cache.h>
 #include <asm/page.h>			/* for BUG() */
 
 /*
@@ -64,7 +65,7 @@
 	return end_name_hash(hash);
 }
 
-#define DNAME_INLINE_LEN 16
+#define DNAME_INLINE_LEN_MIN 16
 
 struct dcookie_struct;
  
@@ -85,10 +86,12 @@
 	struct super_block * d_sb;	/* The root of the dentry tree */
 	unsigned long d_vfs_flags;
 	void * d_fsdata;		/* fs-specific data */
-	unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
 	struct dcookie_struct * d_cookie; /* cookie, if any */
-};
+	unsigned char d_iname[DNAME_INLINE_LEN_MIN]; /* small names */
+} ____cacheline_aligned;
 
+#define DNAME_INLINE_LEN	(sizeof(struct dentry)-offsetof(struct dentry,d_iname))
+ 
 struct dentry_operations {
 	int (*d_revalidate)(struct dentry *, int);
 	int (*d_hash) (struct dentry *, struct qstr *);
diff -Nru a/include/linux/dcookies.h b/include/linux/dcookies.h
--- a/include/linux/dcookies.h	Mon Nov  4 14:31:01 2002
+++ b/include/linux/dcookies.h	Mon Nov  4 14:31:01 2002
@@ -44,7 +44,7 @@
  * Returns 0 on success, with *cookie filled in
  */
 int get_dcookie(struct dentry * dentry, struct vfsmount * vfsmnt,
-	u32 * cookie);
+	unsigned long * cookie);
 
 #else
 
@@ -59,7 +59,7 @@
 }
  
 static inline int get_dcookie(struct dentry * dentry,
-	struct vfsmount * vfsmnt, u32 * cookie)
+	struct vfsmount * vfsmnt, unsigned long * cookie)
 {
 	return -ENOSYS;
 } 
diff -Nru a/include/linux/device.h b/include/linux/device.h
--- a/include/linux/device.h	Mon Nov  4 14:31:02 2002
+++ b/include/linux/device.h	Mon Nov  4 14:31:02 2002
@@ -28,7 +28,7 @@
 #include <linux/ioport.h>
 #include <linux/list.h>
 #include <linux/sched.h>
-#include <linux/driverfs_fs.h>
+#include <linux/kobject.h>
 
 #define DEVICE_NAME_SIZE	80
 #define DEVICE_ID_SIZE		32
@@ -65,14 +65,13 @@
 	atomic_t		refcount;
 	u32			present;
 
+	struct subsystem	subsys;
+	struct subsystem	drvsubsys;
+	struct subsystem	devsubsys;
 	struct list_head	node;
 	struct list_head	devices;
 	struct list_head	drivers;
 
-	struct driver_dir_entry	dir;
-	struct driver_dir_entry	device_dir;
-	struct driver_dir_entry	driver_dir;
-
 	int		(*match)(struct device * dev, struct device_driver * drv);
 	struct device * (*add)	(struct device * parent, char * bus_id);
 	int		(*hotplug) (struct device *dev, char **envp, 
@@ -119,12 +118,11 @@
 	atomic_t		refcount;
 	u32			present;
 
+	struct kobject		kobj;
 	struct list_head	bus_list;
 	struct list_head	class_list;
 	struct list_head	devices;
 
-	struct driver_dir_entry	dir;
-
 	int	(*probe)	(struct device * dev);
 	int 	(*remove)	(struct device * dev);
 	void	(*shutdown)	(struct device * dev);
@@ -177,14 +175,13 @@
 
 	u32			devnum;
 
+	struct subsystem	subsys;
+	struct subsystem	devsubsys;
+	struct subsystem	drvsubsys;
 	struct list_head	node;
 	struct list_head	drivers;
 	struct list_head	intf_list;
 
-	struct driver_dir_entry	dir;
-	struct driver_dir_entry	driver_dir;
-	struct driver_dir_entry	device_dir;
-
 	int	(*add_device)(struct device *);
 	void	(*remove_device)(struct device *);
 	int	(*hotplug)(struct device *dev, char **envp, 
@@ -232,9 +229,9 @@
 	char			* name;
 	struct device_class	* devclass;
 
+	struct kobject		kobj;
 	struct list_head	node;
 	struct list_head	devices;
-	struct driver_dir_entry	dir;
 
 	u32			devnum;
 
@@ -275,6 +272,7 @@
 	struct list_head intf_list;
 	struct device 	* parent;
 
+	struct kobject kobj;
 	char	name[DEVICE_NAME_SIZE];	/* descriptive ascii string */
 	char	bus_id[BUS_ID_SIZE];	/* position on parent bus */
 
@@ -285,8 +283,6 @@
 					 * persists for the right amount of time */
 
 	struct bus_type	* bus;		/* type of bus device is on */
-	struct driver_dir_entry	dir;
-
 	struct device_driver *driver;	/* which driver has allocated this
 					   device */
 	void		*driver_data;	/* data private to the driver */
@@ -437,6 +433,11 @@
 extern int device_suspend(u32 state, u32 level);
 extern void device_resume(u32 level);
 extern void device_shutdown(void);
+
+
+/* drivrs/base/firmware.c */
+extern int firmware_register(struct subsystem *);
+extern void firmware_uregister(struct subsystem *);
 
 /* debugging and troubleshooting/diagnostic helpers. */
 #ifdef DEBUG
diff -Nru a/include/linux/driverfs_fs.h b/include/linux/driverfs_fs.h
--- a/include/linux/driverfs_fs.h	Mon Nov  4 14:31:02 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,68 +0,0 @@
-/*
- * driverfs_fs.h - definitions for the device driver filesystem
- *
- * Copyright (c) 2001 Patrick Mochel <mochel@osdl.org>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * This is a simple, ram-based filesystem, which allows kernel
- * callbacks for read/write of files.
- *
- * Please see Documentation/filesystems/driverfs.txt for more information.
- */
-
-#ifndef _DRIVER_FS_H_
-#define _DRIVER_FS_H_
-
-struct driver_dir_entry;
-struct attribute;
-
-struct driverfs_ops {
-	int	(*open)(struct driver_dir_entry *);
-	int	(*close)(struct driver_dir_entry *);
-	ssize_t	(*show)(struct driver_dir_entry *, struct attribute *,char *, size_t, loff_t);
-	ssize_t	(*store)(struct driver_dir_entry *,struct attribute *,const char *, size_t, loff_t);
-};
-
-struct driver_dir_entry {
-	char			* name;
-	struct dentry		* dentry;
-	mode_t			mode;
-	struct driverfs_ops	* ops;
-};
-
-struct attribute {
-	char			* name;
-	mode_t			mode;
-};
-
-extern int
-driverfs_create_dir(struct driver_dir_entry *, struct driver_dir_entry *);
-
-extern void
-driverfs_remove_dir(struct driver_dir_entry * entry);
-
-extern int
-driverfs_create_file(struct attribute * attr,
-		     struct driver_dir_entry * parent);
-
-extern int 
-driverfs_create_symlink(struct driver_dir_entry * parent, 
-			char * name, char * target);
-
-extern void
-driverfs_remove_file(struct driver_dir_entry *, const char * name);
-
-#endif /* _DDFS_H_ */
diff -Nru a/include/linux/elf.h b/include/linux/elf.h
--- a/include/linux/elf.h	Mon Nov  4 14:31:01 2002
+++ b/include/linux/elf.h	Mon Nov  4 14:31:01 2002
@@ -81,6 +81,9 @@
 
 #define EM_CRIS         76      /* Axis Communications 32-bit embedded processor */
 
+#define EM_V850		87	/* NEC v850 */
+
+
 /*
  * This is an interim value that we will use until the committee comes
  * up with a final number.
diff -Nru a/include/linux/eventpoll.h b/include/linux/eventpoll.h
--- a/include/linux/eventpoll.h	Mon Nov  4 14:31:01 2002
+++ b/include/linux/eventpoll.h	Mon Nov  4 14:31:01 2002
@@ -1,6 +1,6 @@
 /*
  *  include/linux/eventpoll.h ( Efficent event polling implementation )
- *  Copyright (C) 2001,...,2002  Davide Libenzi
+ *  Copyright (C) 2001,...,2002	 Davide Libenzi
  *
  *  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
@@ -14,37 +14,25 @@
 #ifndef _LINUX_EVENTPOLL_H
 #define _LINUX_EVENTPOLL_H
 
+/* Forward declarations to avoid compiler errors */
+struct file;
+struct pollfd;
 
-#define EVENTPOLL_MINOR	124
-#define POLLFD_X_PAGE (PAGE_SIZE / sizeof(struct pollfd))
-#define MAX_FDS_IN_EVENTPOLL (1024 * 128)
-#define MAX_EVENTPOLL_PAGES (MAX_FDS_IN_EVENTPOLL / POLLFD_X_PAGE)
-#define EVENT_PAGE_INDEX(n) ((n) / POLLFD_X_PAGE)
-#define EVENT_PAGE_REM(n) ((n) % POLLFD_X_PAGE)
-#define EVENT_PAGE_OFFSET(n) (((n) % POLLFD_X_PAGE) * sizeof(struct pollfd))
-#define EP_FDS_PAGES(n) (((n) + POLLFD_X_PAGE - 1) / POLLFD_X_PAGE)
-#define EP_MAP_SIZE(n) (EP_FDS_PAGES(n) * PAGE_SIZE * 2)
-
-
-struct evpoll {
-	int ep_timeout;
-	unsigned long ep_resoff;
-};
-
-#define EP_ALLOC _IOR('P', 1, int)
-#define EP_POLL _IOWR('P', 2, struct evpoll)
-#define EP_FREE _IO('P', 3)
-#define EP_ISPOLLED _IOWR('P', 4, struct pollfd)
 
+/* Valid opcodes to issue to sys_epoll_ctl() */
 #define EP_CTL_ADD 1
 #define EP_CTL_DEL 2
 #define EP_CTL_MOD 3
 
 
-asmlinkage int sys_epoll_create(int maxfds);
+/* Kernel space functions implementing the user space "epoll" API */
+asmlinkage int sys_epoll_create(int size);
 asmlinkage int sys_epoll_ctl(int epfd, int op, int fd, unsigned int events);
-asmlinkage int sys_epoll_wait(int epfd, struct pollfd const **events, int timeout);
+asmlinkage int sys_epoll_wait(int epfd, struct pollfd *events, int maxevents,
+			      int timeout);
 
+/* Used in fs/file_table.c:__fput() to unlink files from the eventpoll interface */
+void ep_notify_file_close(struct file *file);
 
 
 #endif
diff -Nru a/include/linux/ext2_fs.h b/include/linux/ext2_fs.h
--- a/include/linux/ext2_fs.h	Mon Nov  4 14:31:01 2002
+++ b/include/linux/ext2_fs.h	Mon Nov  4 14:31:01 2002
@@ -58,8 +58,6 @@
  */
 #define	EXT2_BAD_INO		 1	/* Bad blocks inode */
 #define EXT2_ROOT_INO		 2	/* Root inode */
-#define EXT2_ACL_IDX_INO	 3	/* ACL inode */
-#define EXT2_ACL_DATA_INO	 4	/* ACL inode */
 #define EXT2_BOOT_LOADER_INO	 5	/* Boot loader inode */
 #define EXT2_UNDEL_DIR_INO	 6	/* Undelete directory inode */
 
@@ -99,7 +97,6 @@
 #else
 # define EXT2_BLOCK_SIZE(s)		(EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
 #endif
-#define EXT2_ACLE_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry))
 #define	EXT2_ADDR_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (__u32))
 #ifdef __KERNEL__
 # define EXT2_BLOCK_SIZE_BITS(s)	((s)->s_blocksize_bits)
@@ -134,28 +131,6 @@
 #endif
 
 /*
- * ACL structures
- */
-struct ext2_acl_header	/* Header of Access Control Lists */
-{
-	__u32	aclh_size;
-	__u32	aclh_file_count;
-	__u32	aclh_acle_count;
-	__u32	aclh_first_acle;
-};
-
-struct ext2_acl_entry	/* Access Control List Entry */
-{
-	__u32	acle_size;
-	__u16	acle_perms;	/* Access permissions */
-	__u16	acle_type;	/* Type of entry */
-	__u16	acle_tag;	/* User or group identity */
-	__u16	acle_pad1;
-	__u32	acle_next;	/* Pointer on next entry for the */
-					/* same inode or on next free entry */
-};
-
-/*
  * Structure of a blocks group descriptor
  */
 struct ext2_group_desc
@@ -216,10 +191,11 @@
 #define EXT2_JOURNAL_DATA_FL		0x00004000 /* Reserved for ext3 */
 #define EXT2_NOTAIL_FL			0x00008000 /* file tail should not be merged */
 #define EXT2_DIRSYNC_FL			0x00010000 /* dirsync behaviour (directories only) */
+#define EXT2_TOPDIR_FL			0x00020000 /* Top of directory hierarchies*/
 #define EXT2_RESERVED_FL		0x80000000 /* reserved for ext2 lib */
 
-#define EXT2_FL_USER_VISIBLE		0x00011FFF /* User visible flags */
-#define EXT2_FL_USER_MODIFIABLE		0x000100FF /* User modifiable flags */
+#define EXT2_FL_USER_VISIBLE		0x0003DFFF /* User visible flags */
+#define EXT2_FL_USER_MODIFIABLE		0x000380FF /* User modifiable flags */
 
 /*
  * ioctl commands
@@ -325,6 +301,7 @@
  * Mount flags
  */
 #define EXT2_MOUNT_CHECK		0x0001	/* Do mount-time checks */
+#define EXT2_MOUNT_OLDALLOC		0x0002  /* Don't use the new Orlov allocator */
 #define EXT2_MOUNT_GRPID		0x0004	/* Create files with directory's group */
 #define EXT2_MOUNT_DEBUG		0x0008	/* Some debugging messages */
 #define EXT2_MOUNT_ERRORS_CONT		0x0010	/* Continue on errors */
@@ -332,6 +309,8 @@
 #define EXT2_MOUNT_ERRORS_PANIC		0x0040	/* Panic on errors */
 #define EXT2_MOUNT_MINIX_DF		0x0080	/* Mimics the Minix statfs */
 #define EXT2_MOUNT_NO_UID32		0x0200  /* Disable 32-bit UIDs */
+#define EXT2_MOUNT_XATTR_USER		0x4000	/* Extended user attributes */
+#define EXT2_MOUNT_POSIX_ACL		0x8000	/* POSIX Access Control Lists */
 
 #define clear_opt(o, opt)		o &= ~EXT2_MOUNT_##opt
 #define set_opt(o, opt)			o |= EXT2_MOUNT_##opt
@@ -410,7 +389,20 @@
 	__u8	s_prealloc_blocks;	/* Nr of blocks to try to preallocate*/
 	__u8	s_prealloc_dir_blocks;	/* Nr to preallocate for dirs */
 	__u16	s_padding1;
-	__u32	s_reserved[204];	/* Padding to the end of the block */
+	/*
+	 * Journaling support valid if EXT3_FEATURE_COMPAT_HAS_JOURNAL set.
+	 */
+	__u8	s_journal_uuid[16];	/* uuid of journal superblock */
+	__u32	s_journal_inum;		/* inode number of journal file */
+	__u32	s_journal_dev;		/* device number of journal file */
+	__u32	s_last_orphan;		/* start of list of inodes to delete */
+	__u32	s_hash_seed[4];		/* HTREE hash seed */
+	__u8	s_def_hash_version;	/* Default hash version to use */
+	__u8	s_reserved_char_pad;
+	__u16	s_reserved_word_pad;
+	__u32	s_default_mount_opts;
+ 	__u32	s_first_meta_bg; 	/* First metablock block group */
+	__u32	s_reserved[190];	/* Padding to the end of the block */
 };
 
 /*
@@ -473,10 +465,12 @@
 #define EXT2_FEATURE_INCOMPAT_FILETYPE		0x0002
 #define EXT3_FEATURE_INCOMPAT_RECOVER		0x0004
 #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV	0x0008
+#define EXT2_FEATURE_INCOMPAT_META_BG		0x0010
 #define EXT2_FEATURE_INCOMPAT_ANY		0xffffffff
 
-#define EXT2_FEATURE_COMPAT_SUPP	0
-#define EXT2_FEATURE_INCOMPAT_SUPP	EXT2_FEATURE_INCOMPAT_FILETYPE
+#define EXT2_FEATURE_COMPAT_SUPP	EXT2_FEATURE_COMPAT_EXT_ATTR
+#define EXT2_FEATURE_INCOMPAT_SUPP	(EXT2_FEATURE_INCOMPAT_FILETYPE| \
+					 EXT2_FEATURE_INCOMPAT_META_BG)
 #define EXT2_FEATURE_RO_COMPAT_SUPP	(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
 					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
 					 EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
@@ -488,6 +482,20 @@
  */
 #define	EXT2_DEF_RESUID		0
 #define	EXT2_DEF_RESGID		0
+
+/*
+ * Default mount options
+ */
+#define EXT2_DEFM_DEBUG		0x0001
+#define EXT2_DEFM_BSDGROUPS	0x0002
+#define EXT2_DEFM_XATTR_USER	0x0004
+#define EXT2_DEFM_ACL		0x0008
+#define EXT2_DEFM_UID16		0x0010
+    /* Not used by ext2, but reserved for use by ext3 */
+#define EXT3_DEFM_JMODE		0x0060 
+#define EXT3_DEFM_JMODE_DATA	0x0020
+#define EXT3_DEFM_JMODE_ORDERED	0x0040
+#define EXT3_DEFM_JMODE_WBACK	0x0060
 
 /*
  * Structure of a directory entry
diff -Nru a/include/linux/ext2_fs_sb.h b/include/linux/ext2_fs_sb.h
--- a/include/linux/ext2_fs_sb.h	Mon Nov  4 14:31:02 2002
+++ b/include/linux/ext2_fs_sb.h	Mon Nov  4 14:31:02 2002
@@ -43,6 +43,8 @@
 	int s_inode_size;
 	int s_first_ino;
 	u32 s_next_generation;
+	unsigned long s_dir_count;
+	u8 *s_debts;
 };
 
 #endif	/* _LINUX_EXT2_FS_SB */
diff -Nru a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
--- a/include/linux/ext3_fs.h	Mon Nov  4 14:31:02 2002
+++ b/include/linux/ext3_fs.h	Mon Nov  4 14:31:02 2002
@@ -64,8 +64,6 @@
  */
 #define	EXT3_BAD_INO		 1	/* Bad blocks inode */
 #define EXT3_ROOT_INO		 2	/* Root inode */
-#define EXT3_ACL_IDX_INO	 3	/* ACL inode */
-#define EXT3_ACL_DATA_INO	 4	/* ACL inode */
 #define EXT3_BOOT_LOADER_INO	 5	/* Boot loader inode */
 #define EXT3_UNDEL_DIR_INO	 6	/* Undelete directory inode */
 #define EXT3_RESIZE_INO		 7	/* Reserved group descriptors inode */
@@ -95,7 +93,6 @@
 #else
 # define EXT3_BLOCK_SIZE(s)		(EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size)
 #endif
-#define EXT3_ACLE_PER_BLOCK(s)		(EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_acl_entry))
 #define	EXT3_ADDR_PER_BLOCK(s)		(EXT3_BLOCK_SIZE(s) / sizeof (__u32))
 #ifdef __KERNEL__
 # define EXT3_BLOCK_SIZE_BITS(s)	((s)->s_blocksize_bits)
@@ -130,28 +127,6 @@
 #endif
 
 /*
- * ACL structures
- */
-struct ext3_acl_header	/* Header of Access Control Lists */
-{
-	__u32	aclh_size;
-	__u32	aclh_file_count;
-	__u32	aclh_acle_count;
-	__u32	aclh_first_acle;
-};
-
-struct ext3_acl_entry	/* Access Control List Entry */
-{
-	__u32	acle_size;
-	__u16	acle_perms;	/* Access permissions */
-	__u16	acle_type;	/* Type of entry */
-	__u16	acle_tag;	/* User or group identity */
-	__u16	acle_pad1;
-	__u32	acle_next;	/* Pointer on next entry for the */
-					/* same inode or on next free entry */
-};
-
-/*
  * Structure of a blocks group descriptor
  */
 struct ext3_group_desc
@@ -211,10 +186,11 @@
 #define EXT3_JOURNAL_DATA_FL		0x00004000 /* file data should be journaled */
 #define EXT3_NOTAIL_FL			0x00008000 /* file tail should not be merged */
 #define EXT3_DIRSYNC_FL			0x00010000 /* dirsync behaviour (directories only) */
+#define EXT3_TOPDIR_FL			0x00020000 /* Top of directory hierarchies*/
 #define EXT3_RESERVED_FL		0x80000000 /* reserved for ext3 lib */
 
-#define EXT3_FL_USER_VISIBLE		0x00015FFF /* User visible flags */
-#define EXT3_FL_USER_MODIFIABLE		0x000100FF /* User modifiable flags */
+#define EXT3_FL_USER_VISIBLE		0x0003DFFF /* User visible flags */
+#define EXT3_FL_USER_MODIFIABLE		0x000380FF /* User modifiable flags */
 
 /*
  * Inode dynamic state flags
@@ -333,6 +309,7 @@
  * Mount flags
  */
 #define EXT3_MOUNT_CHECK		0x0001	/* Do mount-time checks */
+#define EXT3_MOUNT_OLDALLOC		0x0002  /* Don't use the new Orlov allocator */
 #define EXT3_MOUNT_GRPID		0x0004	/* Create files with directory's group */
 #define EXT3_MOUNT_DEBUG		0x0008	/* Some debugging messages */
 #define EXT3_MOUNT_ERRORS_CONT		0x0010	/* Continue on errors */
@@ -347,6 +324,8 @@
   #define EXT3_MOUNT_WRITEBACK_DATA	0x0C00	/* No data ordering */
 #define EXT3_MOUNT_UPDATE_JOURNAL	0x1000	/* Update the journal format */
 #define EXT3_MOUNT_NO_UID32		0x2000  /* Disable 32-bit UIDs */
+#define EXT3_MOUNT_XATTR_USER		0x4000	/* Extended user attributes */
+#define EXT3_MOUNT_POSIX_ACL		0x8000	/* POSIX Access Control Lists */
 
 /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
 #ifndef _LINUX_EXT2_FS_H
@@ -357,6 +336,7 @@
 #else
 #define EXT2_MOUNT_NOLOAD		EXT3_MOUNT_NOLOAD
 #define EXT2_MOUNT_ABORT		EXT3_MOUNT_ABORT
+#define EXT2_MOUNT_DATA_FLAGS		EXT3_MOUNT_DATA_FLAGS
 #endif
 
 #define ext3_set_bit			ext2_set_bit
@@ -449,7 +429,9 @@
 	__u8	s_def_hash_version;	/* Default hash version to use */
 	__u8	s_reserved_char_pad;
 	__u16	s_reserved_word_pad;
-	__u32	s_reserved[192];	/* Padding to the end of the block */
+	__u32	s_default_mount_opts;
+	__u32	s_first_meta_bg; 	/* First metablock block group */
+	__u32	s_reserved[190];	/* Padding to the end of the block */
 };
 
 #ifdef __KERNEL__
@@ -528,8 +510,11 @@
 #define EXT3_FEATURE_INCOMPAT_FILETYPE		0x0002
 #define EXT3_FEATURE_INCOMPAT_RECOVER		0x0004 /* Needs recovery */
 #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV	0x0008 /* Journal device */
+#define EXT3_FEATURE_INCOMPAT_META_BG		0x0010
 
-#define EXT3_FEATURE_COMPAT_SUPP	0
+#define EXT3_FEATURE_COMPAT_SUPP	EXT2_FEATURE_COMPAT_EXT_ATTR
+#define EXT2_FEATURE_INCOMPAT_SUPP	(EXT2_FEATURE_INCOMPAT_FILETYPE| \
+					 EXT2_FEATURE_INCOMPAT_META_BG)
 #define EXT3_FEATURE_INCOMPAT_SUPP	(EXT3_FEATURE_INCOMPAT_FILETYPE| \
 					 EXT3_FEATURE_INCOMPAT_RECOVER)
 #define EXT3_FEATURE_RO_COMPAT_SUPP	(EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \
@@ -543,6 +528,19 @@
 #define	EXT3_DEF_RESGID		0
 
 /*
+ * Default mount options
+ */
+#define EXT3_DEFM_DEBUG		0x0001
+#define EXT3_DEFM_BSDGROUPS	0x0002
+#define EXT3_DEFM_XATTR_USER	0x0004
+#define EXT3_DEFM_ACL		0x0008
+#define EXT3_DEFM_UID16		0x0010
+#define EXT3_DEFM_JMODE		0x0060
+#define EXT3_DEFM_JMODE_DATA	0x0020
+#define EXT3_DEFM_JMODE_ORDERED	0x0040
+#define EXT3_DEFM_JMODE_WBACK	0x0060
+
+/*
  * Structure of a directory entry
  */
 #define EXT3_NAME_LEN 255
@@ -708,11 +706,13 @@
 extern void ext3_free_inode (handle_t *, struct inode *);
 extern struct inode * ext3_orphan_get (struct super_block *, ino_t);
 extern unsigned long ext3_count_free_inodes (struct super_block *);
+extern unsigned long ext3_count_dirs (struct super_block *);
 extern void ext3_check_inodes_bitmap (struct super_block *);
 extern unsigned long ext3_count_free (struct buffer_head *, unsigned);
 
 
 /* inode.c */
+extern int ext3_forget(handle_t *, int, struct inode *, struct buffer_head *, int);
 extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
 extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
 
@@ -781,8 +781,10 @@
 
 /* namei.c */
 extern struct inode_operations ext3_dir_inode_operations;
+extern struct inode_operations ext3_special_inode_operations;
 
 /* symlink.c */
+extern struct inode_operations ext3_symlink_inode_operations;
 extern struct inode_operations ext3_fast_symlink_inode_operations;
 
 
diff -Nru a/include/linux/ext3_fs_i.h b/include/linux/ext3_fs_i.h
--- a/include/linux/ext3_fs_i.h	Mon Nov  4 14:31:00 2002
+++ b/include/linux/ext3_fs_i.h	Mon Nov  4 14:31:00 2002
@@ -41,6 +41,10 @@
 	__u32	i_prealloc_count;
 #endif
 	__u32	i_dir_start_lookup;
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
+	struct posix_acl	*i_acl;
+	struct posix_acl	*i_default_acl;
+#endif
 	
 	struct list_head i_orphan;	/* unlinked but open inodes */
 
diff -Nru a/include/linux/ext3_fs_sb.h b/include/linux/ext3_fs_sb.h
--- a/include/linux/ext3_fs_sb.h	Mon Nov  4 14:31:02 2002
+++ b/include/linux/ext3_fs_sb.h	Mon Nov  4 14:31:02 2002
@@ -50,6 +50,8 @@
 	u32 s_next_generation;
 	u32 s_hash_seed[4];
 	int s_def_hash_version;
+	unsigned long s_dir_count;
+	u8 *s_debts;
 
 	/* Journaling */
 	struct inode * s_journal_inode;
diff -Nru a/include/linux/ext3_jbd.h b/include/linux/ext3_jbd.h
--- a/include/linux/ext3_jbd.h	Mon Nov  4 14:31:00 2002
+++ b/include/linux/ext3_jbd.h	Mon Nov  4 14:31:00 2002
@@ -30,13 +30,19 @@
 
 #define EXT3_SINGLEDATA_TRANS_BLOCKS	8
 
+/* Extended attributes may touch two data buffers, two bitmap buffers,
+ * and two group and summaries. */
+
+#define EXT3_XATTR_TRANS_BLOCKS		8
+
 /* Define the minimum size for a transaction which modifies data.  This
  * needs to take into account the fact that we may end up modifying two
  * quota files too (one for the group, one for the user quota).  The
  * superblock only gets updated once, of course, so don't bother
  * counting that again for the quota updates. */
 
-#define EXT3_DATA_TRANS_BLOCKS		(3 * EXT3_SINGLEDATA_TRANS_BLOCKS - 2)
+#define EXT3_DATA_TRANS_BLOCKS		(3 * EXT3_SINGLEDATA_TRANS_BLOCKS + \
+					 EXT3_XATTR_TRANS_BLOCKS - 2)
 
 extern int ext3_writepage_trans_blocks(struct inode *inode);
 
diff -Nru a/include/linux/fcblist.h b/include/linux/fcblist.h
--- a/include/linux/fcblist.h	Mon Nov  4 14:31:02 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,71 +0,0 @@
-/*
- *  include/linux/fcblist.h ( File event callbacks handling )
- *  Copyright (C) 2001,...,2002  Davide Libenzi
- *
- *  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.
- *
- *  Davide Libenzi <davidel@xmailserver.org>
- *
- */
-
-#ifndef __LINUX_FCBLIST_H
-#define __LINUX_FCBLIST_H
-
-#include <linux/config.h>
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <linux/fs.h>
-#include <linux/file.h>
-
-
-
-/* file callback notification events */
-#define ION_IN		1
-#define ION_OUT		2
-#define ION_HUP		3
-#define ION_ERR		4
-
-#define FCB_LOCAL_SIZE	4
-
-
-struct fcb_struct {
-	struct list_head llink;
-	void (*cbproc)(struct file *, void *, unsigned long *, long *);
-	void *data;
-	unsigned long local[FCB_LOCAL_SIZE];
-};
-
-
-extern long ion_band_table[];
-extern long poll_band_table[];
-
-
-void file_notify_event(struct file *filep, long *event);
-
-int file_notify_addcb(struct file *filep,
-		      void (*cbproc)(struct file *, void *, unsigned long *, long *),
-		      void *data);
-
-int file_notify_delcb(struct file *filep,
-		      void (*cbproc)(struct file *, void *, unsigned long *, long *));
-
-void file_notify_cleanup(struct file *filep);
-
-
-static inline void file_notify_init(struct file *filep)
-{
-	rwlock_init(&filep->f_cblock);
-	INIT_LIST_HEAD(&filep->f_cblist);
-}
-
-static inline void file_send_notify(struct file *filep, long ioevt, long plevt)
-{
-	long event[] = { ioevt, plevt, -1 };
-
-	file_notify_event(filep, event);
-}
-
-#endif
diff -Nru a/include/linux/flat.h b/include/linux/flat.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/flat.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,83 @@
+
+/* Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>
+ *                     The Silver Hammer Group, Ltd.
+ * Copyright (C) 2002  David McCullough <davidm@snapgear.com>
+ */
+
+#ifndef _LINUX_FLAT_H
+#define _LINUX_FLAT_H
+
+#define	FLAT_VERSION			0x00000004L
+
+/*
+ * To make everything easier to port and manage cross platform
+ * development,  all fields are in network byte order.
+ */
+
+struct flat_hdr {
+	char magic[4];
+	unsigned long rev;          /* version (as above) */
+	unsigned long entry;        /* Offset of first executable instruction
+	                               with text segment from beginning of file */
+	unsigned long data_start;   /* Offset of data segment from beginning of
+	                               file */
+	unsigned long data_end;     /* Offset of end of data segment
+	                               from beginning of file */
+	unsigned long bss_end;      /* Offset of end of bss segment from beginning
+	                               of file */
+
+	/* (It is assumed that data_end through bss_end forms the bss segment.) */
+
+	unsigned long stack_size;   /* Size of stack, in bytes */
+	unsigned long reloc_start;  /* Offset of relocation records from
+	                               beginning of file */
+	unsigned long reloc_count;  /* Number of relocation records */
+	unsigned long flags;       
+	unsigned long build_date;   /* When the program/library was built */
+	unsigned long filler[5];    /* Reservered, set to zero */
+};
+
+#define FLAT_FLAG_RAM    0x0001 /* load program entirely into RAM */
+#define FLAT_FLAG_GOTPIC 0x0002 /* program is PIC with GOT */
+#define FLAT_FLAG_GZIP   0x0004 /* all but the header is compressed */
+#define FLAT_FLAG_GZDATA 0x0008 /* only data/relocs are compressed (for XIP) */
+
+
+/*
+ * While it would be nice to keep this header clean,  users of older
+ * tools still need this support in the kernel.  So this section is
+ * purely for compatibility with old tool chains.
+ *
+ * DO NOT make changes or enhancements to the old format please,  just work
+ *        with the format above,  except to fix bugs with old format support.
+ */
+
+#include <asm/byteorder.h>
+
+#define	OLD_FLAT_VERSION			0x00000002L
+#define OLD_FLAT_RELOC_TYPE_TEXT	0
+#define OLD_FLAT_RELOC_TYPE_DATA	1
+#define OLD_FLAT_RELOC_TYPE_BSS		2
+
+typedef union {
+	unsigned long	value;
+	struct {
+# if defined(mc68000) && !defined(CONFIG_COLDFIRE)
+		signed long offset : 30;
+		unsigned long type : 2;
+#   	define OLD_FLAT_FLAG_RAM    0x1 /* load program entirely into RAM */
+# elif defined(__BIG_ENDIAN_BITFIELD)
+		unsigned long type : 2;
+		signed long offset : 30;
+#   	define OLD_FLAT_FLAG_RAM    0x1 /* load program entirely into RAM */
+# elif defined(__LITTLE_ENDIAN_BITFIELD)
+		signed long offset : 30;
+		unsigned long type : 2;
+#   	define OLD_FLAT_FLAG_RAM    0x1 /* load program entirely into RAM */
+# else
+#   	error "Unknown bitfield order for flat files."
+# endif
+	} reloc;
+} flat_v2_reloc_t;
+
+#endif /* _LINUX_FLAT_H */
diff -Nru a/include/linux/fs.h b/include/linux/fs.h
--- a/include/linux/fs.h	Mon Nov  4 14:31:01 2002
+++ b/include/linux/fs.h	Mon Nov  4 14:31:01 2002
@@ -110,6 +110,7 @@
 #define MS_MOVE		8192
 #define MS_REC		16384
 #define MS_VERBOSE	32768
+#define MS_POSIXACL	(1<<16)	/* VFS does not apply the umask */
 #define MS_ACTIVE	(1<<30)
 #define MS_NOUSER	(1<<31)
 
@@ -164,6 +165,7 @@
 #define IS_IMMUTABLE(inode)	((inode)->i_flags & S_IMMUTABLE)
 #define IS_NOATIME(inode)	(__IS_FLG(inode, MS_NOATIME) || ((inode)->i_flags & S_NOATIME))
 #define IS_NODIRATIME(inode)	__IS_FLG(inode, MS_NODIRATIME)
+#define IS_POSIXACL(inode)	__IS_FLG(inode, MS_POSIXACL)
 
 #define IS_DEADDIR(inode)	((inode)->i_flags & S_DEAD)
 
@@ -504,10 +506,6 @@
 
 	/* needed for tty driver, and maybe others */
 	void			*private_data;
-
-	/* file callback list */
-	rwlock_t f_cblock;
-	struct list_head f_cblist;
 };
 extern spinlock_t files_lock;
 #define file_list_lock() spin_lock(&files_lock);
@@ -1147,6 +1145,7 @@
 extern int filemap_fdatawait(struct address_space *);
 extern void sync_supers(void);
 extern sector_t bmap(struct inode *, sector_t);
+extern int setattr_mask(unsigned int);
 extern int notify_change(struct dentry *, struct iattr *);
 extern int permission(struct inode *, int);
 extern int vfs_permission(struct inode *, int);
@@ -1225,6 +1224,7 @@
 
 extern void __iget(struct inode * inode);
 extern void clear_inode(struct inode *);
+extern void destroy_inode(struct inode *);
 extern struct inode *new_inode(struct super_block *);
 extern void remove_suid(struct dentry *);
 
diff -Nru a/include/linux/genhd.h b/include/linux/genhd.h
--- a/include/linux/genhd.h	Mon Nov  4 14:31:01 2002
+++ b/include/linux/genhd.h	Mon Nov  4 14:31:01 2002
@@ -62,7 +62,7 @@
 	sector_t start_sect;
 	sector_t nr_sects;
 	devfs_handle_t de;              /* primary (master) devfs entry  */
-	struct device *hd_driverfs_dev;  /* support driverfs hiearchy     */
+	struct kobject kobj;
 	unsigned reads, read_sectors, writes, write_sectors;
 	int policy;
 };
@@ -93,7 +93,7 @@
 	devfs_handle_t de;		/* more of the same */
 	devfs_handle_t disk_de;		/* piled higher and deeper */
 	struct device *driverfs_dev;
-	struct device disk_dev;
+	struct kobject kobj;
 
 	struct timer_rand_state *random;
 	int policy;
@@ -129,8 +129,6 @@
 {
 	disk->capacity = size;
 }
-
-extern struct device_class disk_devclass;
 
 #endif  /*  __KERNEL__  */
 
diff -Nru a/include/linux/hugetlb.h b/include/linux/hugetlb.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/hugetlb.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,53 @@
+#ifndef _LINUX_HUGETLB_H
+#define _LINUX_HUGETLB_H
+
+#ifdef CONFIG_HUGETLB_PAGE
+static inline int is_vm_hugetlb_page(struct vm_area_struct *vma)
+{
+	return vma->vm_flags & VM_HUGETLB;
+}
+
+int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *, struct vm_area_struct *);
+int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, struct page **, struct vm_area_struct **, unsigned long *, int *, int);
+void zap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long);
+void unmap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long);
+int hugetlb_prefault(struct address_space *, struct vm_area_struct *);
+void huge_page_release(struct page *);
+#else /* !CONFIG_HUGETLB_PAGE */
+static inline int is_vm_hugetlb_page(struct vm_area_struct *vma)
+{
+	return 0;
+}
+
+#define follow_hugetlb_page(m,v,p,vs,a,b,i)		({ BUG(); 0; })
+#define copy_hugetlb_page_range(src, dst, vma)	({ BUG(); 0; })
+#define hugetlb_prefault(mapping, vma)		({ BUG(); 0; })
+#define zap_hugepage_range(vma, start, len)	BUG()
+#define unmap_hugepage_range(vma, start, end)	BUG()
+#define huge_page_release(page)			BUG()
+
+#endif /* !CONFIG_HUGETLB_PAGE */
+
+#ifdef CONFIG_HUGETLBFS
+extern struct file_operations hugetlbfs_file_operations;
+extern struct vm_operations_struct hugetlb_vm_ops;
+struct file *hugetlb_zero_setup(size_t);
+
+static inline int is_file_hugepages(struct file *file)
+{
+	return file->f_op == &hugetlbfs_file_operations;
+}
+
+static inline void set_file_hugepages(struct file *file)
+{
+	file->f_op = &hugetlbfs_file_operations;
+}
+#else /* !CONFIG_HUGETLBFS */
+
+#define is_file_hugepages(file)		0
+#define set_file_hugepages(file)	BUG()
+#define hugetlb_zero_setup(size)	ERR_PTR(-ENOSYS)
+
+#endif /* !CONFIG_HUGETLBFS */
+
+#endif /* _LINUX_HUGETLB_H */
diff -Nru a/include/linux/ipc.h b/include/linux/ipc.h
--- a/include/linux/ipc.h	Mon Nov  4 14:31:00 2002
+++ b/include/linux/ipc.h	Mon Nov  4 14:31:00 2002
@@ -56,6 +56,8 @@
 /* used by in-kernel data structures */
 struct kern_ipc_perm
 {
+	spinlock_t	lock;
+	int		deleted;
 	key_t		key;
 	uid_t		uid;
 	gid_t		gid;
diff -Nru a/include/linux/isapnp.h b/include/linux/isapnp.h
--- a/include/linux/isapnp.h	Mon Nov  4 14:31:01 2002
+++ b/include/linux/isapnp.h	Mon Nov  4 14:31:01 2002
@@ -196,7 +196,7 @@
 int isapnp_proc_done(void);
 #else
 static inline isapnp_proc_init(void) { return 0; }
-static inline isapnp_proc_done(void) { return 0; )
+static inline isapnp_proc_done(void) { return 0; }
 #endif
 
 /* misc */
diff -Nru a/include/linux/kdev_t.h b/include/linux/kdev_t.h
--- a/include/linux/kdev_t.h	Mon Nov  4 14:31:02 2002
+++ b/include/linux/kdev_t.h	Mon Nov  4 14:31:02 2002
@@ -36,7 +36,7 @@
 Admissible operations on an object of type kdev_t:
 - passing it along
 - comparing it for equality with another such object
-- storing it in inode->i_rdev, req->rq_dev, de->dc_dev, tty->device
+- storing it in inode->i_rdev or tty->device
 - using its bit pattern as argument in a hash function
 - finding its major and minor
 - complaining about it
diff -Nru a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h
--- a/include/linux/kernel_stat.h	Mon Nov  4 14:31:01 2002
+++ b/include/linux/kernel_stat.h	Mon Nov  4 14:31:01 2002
@@ -5,6 +5,7 @@
 #include <asm/irq.h>
 #include <linux/smp.h>
 #include <linux/threads.h>
+#include <linux/percpu.h>
 
 /*
  * 'kernel_stat.h' contains the definitions needed for doing
@@ -12,26 +13,25 @@
  * used by rstatd/perfmeter
  */
 
-#define DK_MAX_MAJOR 16
-#define DK_MAX_DISK 16
+struct cpu_usage_stat {
+	unsigned int user;
+	unsigned int nice;
+	unsigned int system;
+	unsigned int idle;
+	unsigned int iowait;
+};
 
 struct kernel_stat {
-	unsigned int per_cpu_user[NR_CPUS],
-	             per_cpu_nice[NR_CPUS],
-	             per_cpu_system[NR_CPUS],
-	             per_cpu_idle[NR_CPUS],
-	             per_cpu_iowait[NR_CPUS];
-	unsigned int dk_drive[DK_MAX_MAJOR][DK_MAX_DISK];
-	unsigned int dk_drive_rio[DK_MAX_MAJOR][DK_MAX_DISK];
-	unsigned int dk_drive_wio[DK_MAX_MAJOR][DK_MAX_DISK];
-	unsigned int dk_drive_rblk[DK_MAX_MAJOR][DK_MAX_DISK];
-	unsigned int dk_drive_wblk[DK_MAX_MAJOR][DK_MAX_DISK];
+	struct cpu_usage_stat	cpustat;
 #if !defined(CONFIG_ARCH_S390)
-	unsigned int irqs[NR_CPUS][NR_IRQS];
+	unsigned int irqs[NR_IRQS];
 #endif
 };
 
-extern struct kernel_stat kstat;
+DECLARE_PER_CPU(struct kernel_stat, kstat);
+
+#define kstat_cpu(cpu)	per_cpu(kstat, cpu)
+#define kstat_this_cpu	kstat_cpu(smp_processor_id())
 
 extern unsigned long nr_context_switches(void);
 
@@ -50,8 +50,9 @@
 {
 	int i, sum=0;
 
-	for (i = 0 ; i < NR_CPUS ; i++)
-		sum += kstat.irqs[i][irq];
+	for (i = 0 ; i < NR_CPUS ; i++) 
+		if (cpu_possible(i)) 
+			sum += kstat_cpu(i).irqs[irq];
 
 	return sum;
 }
diff -Nru a/include/linux/kobject.h b/include/linux/kobject.h
--- a/include/linux/kobject.h	Mon Nov  4 14:31:00 2002
+++ b/include/linux/kobject.h	Mon Nov  4 14:31:00 2002
@@ -12,8 +12,10 @@
 #include <linux/rwsem.h>
 #include <asm/atomic.h>
 
+#define KOBJ_NAME_LEN	16
+
 struct kobject {
-	char			name[16];
+	char			name[KOBJ_NAME_LEN];
 	atomic_t		refcount;
 	struct list_head	entry;
 	struct kobject		* parent;
diff -Nru a/include/linux/mbcache.h b/include/linux/mbcache.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/mbcache.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,72 @@
+/*
+  File: linux/mbcache.h
+
+  (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
+*/
+
+/* Hardwire the number of additional indexes */
+#define MB_CACHE_INDEXES_COUNT 1
+
+struct mb_cache_entry;
+
+struct mb_cache_op {
+	void (*free)(struct mb_cache_entry *);
+};
+
+struct mb_cache {
+	struct list_head		c_cache_list;
+	const char			*c_name;
+	struct mb_cache_op		c_op;
+	atomic_t			c_entry_count;
+	int				c_bucket_bits;
+#ifndef MB_CACHE_INDEXES_COUNT
+	int				c_indexes_count;
+#endif
+	kmem_cache_t			*c_entry_cache;
+	struct list_head		*c_block_hash;
+	struct list_head		*c_indexes_hash[0];
+};
+
+struct mb_cache_entry_index {
+	struct list_head		o_list;
+	unsigned int			o_key;
+};
+
+struct mb_cache_entry {
+	struct list_head		e_lru_list;
+	struct mb_cache			*e_cache;
+	atomic_t			e_used;
+	struct block_device		*e_bdev;
+	sector_t			e_block;
+	struct list_head		e_block_list;
+	struct mb_cache_entry_index	e_indexes[0];
+};
+
+/* Functions on caches */
+
+struct mb_cache * mb_cache_create(const char *, struct mb_cache_op *, size_t,
+				  int, int);
+void mb_cache_shrink(struct mb_cache *, struct block_device *);
+void mb_cache_destroy(struct mb_cache *);
+
+/* Functions on cache entries */
+
+struct mb_cache_entry *mb_cache_entry_alloc(struct mb_cache *);
+int mb_cache_entry_insert(struct mb_cache_entry *, struct block_device *,
+			  sector_t, unsigned int[]);
+void mb_cache_entry_rehash(struct mb_cache_entry *, unsigned int[]);
+void mb_cache_entry_release(struct mb_cache_entry *);
+void mb_cache_entry_takeout(struct mb_cache_entry *);
+void mb_cache_entry_free(struct mb_cache_entry *);
+struct mb_cache_entry *mb_cache_entry_dup(struct mb_cache_entry *);
+struct mb_cache_entry *mb_cache_entry_get(struct mb_cache *,
+					  struct block_device *,
+					  sector_t);
+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
+struct mb_cache_entry *mb_cache_entry_find_first(struct mb_cache *cache, int,
+						 struct block_device *, 
+						 unsigned int);
+struct mb_cache_entry *mb_cache_entry_find_next(struct mb_cache_entry *, int,
+						struct block_device *, 
+						unsigned int);
+#endif
diff -Nru a/include/linux/memblk.h b/include/linux/memblk.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/memblk.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,32 @@
+/*
+ * include/linux/memblk.h - generic memblk definition
+ *
+ * This is mainly for topological representation. We define the 
+ * basic 'struct memblk' here, which can be embedded in per-arch 
+ * definitions of memory blocks.
+ *
+ * Basic handling of the devices is done in drivers/base/memblk.c
+ * and system devices are handled in drivers/base/sys.c. 
+ *
+ * MemBlks are exported via driverfs in the class/memblk/devices/
+ * directory. 
+ *
+ * Per-memblk interfaces can be implemented using a struct device_interface. 
+ * See the following for how to do this: 
+ * - drivers/base/intf.c 
+ * - Documentation/driver-model/interface.txt
+ */
+#ifndef _LINUX_MEMBLK_H_
+#define _LINUX_MEMBLK_H_
+
+#include <linux/device.h>
+#include <linux/node.h>
+
+struct memblk {
+	int node_id;		/* The node which contains the MemBlk */
+	struct sys_device sysdev;
+};
+
+extern int register_memblk(struct memblk *, int, struct node *);
+
+#endif /* _LINUX_MEMBLK_H_ */
diff -Nru a/include/linux/miscdevice.h b/include/linux/miscdevice.h
--- a/include/linux/miscdevice.h	Mon Nov  4 14:31:02 2002
+++ b/include/linux/miscdevice.h	Mon Nov  4 14:31:02 2002
@@ -7,12 +7,12 @@
 #define PSMOUSE_MINOR  1
 #define MS_BUSMOUSE_MINOR 2
 #define ATIXL_BUSMOUSE_MINOR 3
-#define AMIGAMOUSE_MINOR 4
+/*#define AMIGAMOUSE_MINOR 4	FIXME OBSOLETE */
 #define ATARIMOUSE_MINOR 5
 #define SUN_MOUSE_MINOR 6
 #define APOLLO_MOUSE_MINOR 7
 #define PC110PAD_MINOR 9
-#define ADB_MOUSE_MINOR 10
+/*#define ADB_MOUSE_MINOR 10	FIXME OBSOLETE */
 #define WATCHDOG_MINOR		130	/* Watchdog timer     */
 #define TEMP_MINOR		131	/* Temperature Sensor */
 #define RTC_MINOR 135
diff -Nru a/include/linux/mm.h b/include/linux/mm.h
--- a/include/linux/mm.h	Mon Nov  4 14:31:00 2002
+++ b/include/linux/mm.h	Mon Nov  4 14:31:00 2002
@@ -130,6 +130,7 @@
 	void (*open)(struct vm_area_struct * area);
 	void (*close)(struct vm_area_struct * area);
 	struct page * (*nopage)(struct vm_area_struct * area, unsigned long address, int unused);
+	int (*populate)(struct vm_area_struct * area, unsigned long address, unsigned long len, unsigned long prot, unsigned long pgoff, int nonblock);
 };
 
 /* forward declaration; pte_chain is meant to be internal to rmap.c */
@@ -365,9 +366,12 @@
 extern pmd_t *FASTCALL(__pmd_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address));
 extern pte_t *FASTCALL(pte_alloc_kernel(struct mm_struct *mm, pmd_t *pmd, unsigned long address));
 extern pte_t *FASTCALL(pte_alloc_map(struct mm_struct *mm, pmd_t *pmd, unsigned long address));
+extern int install_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, struct page *page, unsigned long prot);
 extern int handle_mm_fault(struct mm_struct *mm,struct vm_area_struct *vma, unsigned long address, int write_access);
 extern int make_pages_present(unsigned long addr, unsigned long end);
 extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
+extern int sys_remap_file_pages(unsigned long start, unsigned long size, unsigned long prot, unsigned long pgoff, unsigned long nonblock);
+
 
 extern struct page * follow_page(struct mm_struct *mm, unsigned long address, int write);
 int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start,
@@ -376,20 +380,6 @@
 int __set_page_dirty_buffers(struct page *page);
 int __set_page_dirty_nobuffers(struct page *page);
 
-#ifdef CONFIG_HUGETLB_PAGE
-#define is_vm_hugetlb_page(vma) (vma->vm_flags & VM_HUGETLB)
-extern int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *, struct vm_area_struct *);
-extern int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, struct page **, struct vm_area_struct **, unsigned long *, int *, int);
-extern	int free_hugepages(struct vm_area_struct *);
-
-#else
-#define is_vm_hugetlb_page(vma) (0)
-#define follow_hugetlb_page(mm, vma, pages, vmas, start, len, i) (0)
-#define copy_hugetlb_page_range(dst, src, vma) (0)
-#define free_hugepages(mpnt)  do { } while(0)
-#endif
-
-
 /*
  * Prototype to add a shrinker callback for ageable caches.
  * 
@@ -449,11 +439,11 @@
 extern void mem_init(void);
 extern void show_mem(void);
 extern void si_meminfo(struct sysinfo * val);
+#ifdef CONFIG_NUMA
+extern void si_meminfo_node(struct sysinfo *val, int nid);
+#endif
 extern void swapin_readahead(swp_entry_t);
 
-extern int can_share_swap_page(struct page *);
-extern int remove_exclusive_swap_page(struct page *);
-
 /* mmap.c */
 extern void insert_vm_struct(struct mm_struct *, struct vm_area_struct *);
 extern void build_mmap_rb(struct mm_struct *);
@@ -533,6 +523,7 @@
 					     struct vm_area_struct **pprev);
 extern int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
 		     unsigned long addr, int new_below);
+extern void unmap_vma(struct mm_struct *mm, struct vm_area_struct *area);
 
 /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
    NULL if none.  Assume start_addr < end_addr. */
diff -Nru a/include/linux/mmzone.h b/include/linux/mmzone.h
--- a/include/linux/mmzone.h	Mon Nov  4 14:31:00 2002
+++ b/include/linux/mmzone.h	Mon Nov  4 14:31:00 2002
@@ -279,6 +279,61 @@
 
 #endif /* !CONFIG_DISCONTIGMEM */
 
+
+extern DECLARE_BITMAP(node_online_map, MAX_NUMNODES);
+extern DECLARE_BITMAP(memblk_online_map, MAX_NR_MEMBLKS);
+
+#if defined(CONFIG_DISCONTIGMEM) || defined(CONFIG_NUMA)
+
+#define node_online(node)	test_bit(node, node_online_map)
+#define node_set_online(node)	set_bit(node, node_online_map)
+#define node_set_offline(node)	clear_bit(node, node_online_map)
+static inline unsigned int num_online_nodes(void)
+{
+	int i, num = 0;
+
+	for(i = 0; i < MAX_NUMNODES; i++){
+		if (node_online(i))
+			num++;
+	}
+	return num;
+}
+
+#define memblk_online(memblk)		test_bit(memblk, memblk_online_map)
+#define memblk_set_online(memblk)	set_bit(memblk, memblk_online_map)
+#define memblk_set_offline(memblk)	clear_bit(memblk, memblk_online_map)
+static inline unsigned int num_online_memblks(void)
+{
+	int i, num = 0;
+
+	for(i = 0; i < MAX_NR_MEMBLKS; i++){
+		if (memblk_online(i))
+			num++;
+	}
+	return num;
+}
+
+#else /* !CONFIG_DISCONTIGMEM && !CONFIG_NUMA */
+
+#define node_online(node) \
+	({ BUG_ON((node) != 0); test_bit(node, node_online_map); })
+#define node_set_online(node) \
+	({ BUG_ON((node) != 0); set_bit(node, node_online_map); })
+#define node_set_offline(node) \
+	({ BUG_ON((node) != 0); clear_bit(node, node_online_map); })
+#define num_online_nodes()	1
+
+#define memblk_online(memblk) \
+	({ BUG_ON((memblk) != 0); test_bit(memblk, memblk_online_map); })
+#define memblk_set_online(memblk) \
+	({ BUG_ON((memblk) != 0); set_bit(memblk, memblk_online_map); })
+#define memblk_set_offline(memblk) \
+	({ BUG_ON((memblk) != 0); clear_bit(memblk, memblk_online_map); })
+#define num_online_memblks()		1
+
+#endif /* CONFIG_DISCONTIGMEM || CONFIG_NUMA */
+
+
 #define MAP_ALIGN(x)	((((x) % sizeof(struct page)) == 0) ? (x) : ((x) + \
 		sizeof(struct page) - ((x) % sizeof(struct page))))
 
diff -Nru a/include/linux/mtd/compatmac.h b/include/linux/mtd/compatmac.h
--- a/include/linux/mtd/compatmac.h	Mon Nov  4 14:31:02 2002
+++ b/include/linux/mtd/compatmac.h	Mon Nov  4 14:31:02 2002
@@ -193,6 +193,7 @@
 #define spin_lock_bh(lock) do {start_bh_atomic();spin_lock(lock);} while(0)
 #define spin_unlock_bh(lock) do {spin_unlock(lock);end_bh_atomic();} while(0)
 #else
+#include <linux/interrupt.h>
 #include <asm/softirq.h>
 #include <linux/spinlock.h>
 #endif
diff -Nru a/include/linux/node.h b/include/linux/node.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/node.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,34 @@
+/*
+ * include/linux/node.h - generic node definition
+ *
+ * This is mainly for topological representation. We define the 
+ * basic 'struct node' here, which can be embedded in per-arch 
+ * definitions of processors.
+ *
+ * Basic handling of the devices is done in drivers/base/node.c
+ * and system devices are handled in drivers/base/sys.c. 
+ *
+ * Nodes are exported via driverfs in the class/node/devices/
+ * directory. 
+ *
+ * Per-node interfaces can be implemented using a struct device_interface. 
+ * See the following for how to do this: 
+ * - drivers/base/intf.c 
+ * - Documentation/driver-model/interface.txt
+ */
+#ifndef _LINUX_NODE_H_
+#define _LINUX_NODE_H_
+
+#include <linux/device.h>
+
+struct node {
+	unsigned long cpumap;	/* Bitmap of CPUs on the Node */
+	struct sys_root sysroot;
+};
+
+extern int register_node(struct node *, int, struct node *);
+
+#define to_node(_root) container_of(_root, struct node, sysroot)
+#define to_root(_dev) container_of(_dev, struct sys_root, dev)
+
+#endif /* _LINUX_NODE_H_ */
diff -Nru a/include/linux/page-flags.h b/include/linux/page-flags.h
--- a/include/linux/page-flags.h	Mon Nov  4 14:31:02 2002
+++ b/include/linux/page-flags.h	Mon Nov  4 14:31:02 2002
@@ -114,9 +114,10 @@
 
 #define mod_page_state(member, delta)					\
 	do {								\
-		int cpu = get_cpu();					\
-		per_cpu(page_states, cpu).member += (delta);		\
-		put_cpu();						\
+		unsigned long flags;					\
+		local_irq_save(flags);					\
+		__get_cpu_var(page_states).member += (delta);		\
+		local_irq_restore(flags);				\
 	} while (0)
 
 #define inc_page_state(member)	mod_page_state(member, 1UL)
@@ -236,8 +237,12 @@
  * The PageSwapCache predicate doesn't use a PG_flag at this time,
  * but it may again do so one day.
  */
+#ifdef CONFIG_SWAP
 extern struct address_space swapper_space;
 #define PageSwapCache(page) ((page)->mapping == &swapper_space)
+#else
+#define PageSwapCache(page) 0
+#endif
 
 struct page;	/* forward declaration */
 
diff -Nru a/include/linux/pagevec.h b/include/linux/pagevec.h
--- a/include/linux/pagevec.h	Mon Nov  4 14:31:03 2002
+++ b/include/linux/pagevec.h	Mon Nov  4 14:31:03 2002
@@ -20,7 +20,7 @@
 void __pagevec_release_nonlru(struct pagevec *pvec);
 void __pagevec_free(struct pagevec *pvec);
 void __pagevec_lru_add(struct pagevec *pvec);
-void lru_add_drain(void);
+void __pagevec_lru_add_active(struct pagevec *pvec);
 void pagevec_deactivate_inactive(struct pagevec *pvec);
 void pagevec_strip(struct pagevec *pvec);
 unsigned int pagevec_lookup(struct pagevec *pvec, struct address_space *mapping,
diff -Nru a/include/linux/pci.h b/include/linux/pci.h
--- a/include/linux/pci.h	Mon Nov  4 14:31:01 2002
+++ b/include/linux/pci.h	Mon Nov  4 14:31:01 2002
@@ -643,6 +643,10 @@
 void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle);
 void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr);
 
+#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
+extern struct pci_dev *isa_bridge;
+#endif
+
 #endif /* CONFIG_PCI */
 
 /* Include architecture-dependent settings and functions */
@@ -702,6 +706,8 @@
 
 #define pci_for_each_dev(dev) \
 	for(dev = NULL; 0; )
+
+#define	isa_bridge	((struct pci_dev *)NULL)
 
 #else
 
diff -Nru a/include/linux/personality.h b/include/linux/personality.h
--- a/include/linux/personality.h	Mon Nov  4 14:31:02 2002
+++ b/include/linux/personality.h	Mon Nov  4 14:31:02 2002
@@ -63,6 +63,7 @@
 	PER_SOLARIS =		0x000d | STICKY_TIMEOUTS,
 	PER_UW7 =		0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
 	PER_OSF4 =		0x000f,			 /* OSF/1 v4 */
+	PER_HPUX =		0x0010,
 	PER_MASK =		0x00ff,
 };
 
diff -Nru a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
--- a/include/linux/pipe_fs_i.h	Mon Nov  4 14:31:02 2002
+++ b/include/linux/pipe_fs_i.h	Mon Nov  4 14:31:02 2002
@@ -12,8 +12,6 @@
 	unsigned int waiting_writers;
 	unsigned int r_counter;
 	unsigned int w_counter;
-	struct file *rdfile;
-	struct file *wrfile;
 	struct fasync_struct *fasync_readers;
 	struct fasync_struct *fasync_writers;
 };
@@ -32,8 +30,6 @@
 #define PIPE_WAITING_WRITERS(inode)	((inode).i_pipe->waiting_writers)
 #define PIPE_RCOUNTER(inode)	((inode).i_pipe->r_counter)
 #define PIPE_WCOUNTER(inode)	((inode).i_pipe->w_counter)
-#define PIPE_READFILE(inode)	((inode).i_pipe->rdfile)
-#define PIPE_WRITEFILE(inode)	((inode).i_pipe->wrfile)
 #define PIPE_FASYNC_READERS(inode)     (&((inode).i_pipe->fasync_readers))
 #define PIPE_FASYNC_WRITERS(inode)     (&((inode).i_pipe->fasync_writers))
 
diff -Nru a/include/linux/poll.h b/include/linux/poll.h
--- a/include/linux/poll.h	Mon Nov  4 14:31:01 2002
+++ b/include/linux/poll.h	Mon Nov  4 14:31:01 2002
@@ -13,6 +13,9 @@
 struct poll_table_page;
 
 typedef struct poll_table_struct {
+	int queue;
+	void *priv;
+	void (*qproc)(void *, wait_queue_head_t *);
 	int error;
 	struct poll_table_page * table;
 } poll_table;
@@ -27,9 +30,24 @@
 
 static inline void poll_initwait(poll_table* pt)
 {
+	pt->queue = 1;
+	pt->qproc = NULL;
+	pt->priv = NULL;
 	pt->error = 0;
 	pt->table = NULL;
 }
+
+static inline void poll_initwait_ex(poll_table* pt, int queue,
+				    void (*qproc)(void *, wait_queue_head_t *),
+				    void *priv)
+{
+	pt->queue = queue;
+	pt->qproc = qproc;
+	pt->priv = priv;
+	pt->error = 0;
+	pt->table = NULL;
+}
+
 extern void poll_freewait(poll_table* pt);
 
 
diff -Nru a/include/linux/posix_acl.h b/include/linux/posix_acl.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/posix_acl.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,87 @@
+/*
+  File: linux/posix_acl.h
+
+  (C) 2002 Andreas Gruenbacher, <a.gruenbacher@computer.org>
+*/
+
+
+#ifndef __LINUX_POSIX_ACL_H
+#define __LINUX_POSIX_ACL_H
+
+#include <linux/slab.h>
+
+#define ACL_UNDEFINED_ID	(-1)
+
+/* a_type field in acl_user_posix_entry_t */
+#define ACL_TYPE_ACCESS		(0x8000)
+#define ACL_TYPE_DEFAULT	(0x4000)
+
+/* e_tag entry in struct posix_acl_entry */
+#define ACL_USER_OBJ		(0x01)
+#define ACL_USER		(0x02)
+#define ACL_GROUP_OBJ		(0x04)
+#define ACL_GROUP		(0x08)
+#define ACL_MASK		(0x10)
+#define ACL_OTHER		(0x20)
+
+/* permissions in the e_perm field */
+#define ACL_READ		(0x04)
+#define ACL_WRITE		(0x02)
+#define ACL_EXECUTE		(0x01)
+//#define ACL_ADD		(0x08)
+//#define ACL_DELETE		(0x10)
+
+struct posix_acl_entry {
+	short			e_tag;
+	unsigned short		e_perm;
+	unsigned int		e_id;
+};
+
+struct posix_acl {
+	atomic_t		a_refcount;
+	unsigned int		a_count;
+	struct posix_acl_entry	a_entries[0];
+};
+
+#define FOREACH_ACL_ENTRY(pa, acl, pe) \
+	for(pa=(acl)->a_entries, pe=pa+(acl)->a_count; pa<pe; pa++)
+
+
+/*
+ * Duplicate an ACL handle.
+ */
+static inline struct posix_acl *
+posix_acl_dup(struct posix_acl *acl)
+{
+	if (acl)
+		atomic_inc(&acl->a_refcount);
+	return acl;
+}
+
+/*
+ * Free an ACL handle.
+ */
+static inline void
+posix_acl_release(struct posix_acl *acl)
+{
+	if (acl && atomic_dec_and_test(&acl->a_refcount))
+		kfree(acl);
+}
+
+
+/* posix_acl.c */
+
+extern struct posix_acl *posix_acl_alloc(int, int);
+extern struct posix_acl *posix_acl_clone(const struct posix_acl *, int);
+extern int posix_acl_valid(const struct posix_acl *);
+extern int posix_acl_permission(struct inode *, const struct posix_acl *, int);
+extern struct posix_acl *posix_acl_from_mode(mode_t, int);
+extern int posix_acl_equiv_mode(const struct posix_acl *, mode_t *);
+extern int posix_acl_create_masq(struct posix_acl *, mode_t *);
+extern int posix_acl_chmod_masq(struct posix_acl *, mode_t);
+extern int posix_acl_masq_nfs_mode(struct posix_acl *, mode_t *);
+
+extern struct posix_acl *get_posix_acl(struct inode *, int);
+extern int set_posix_acl(struct inode *, int, struct posix_acl *);
+
+#endif  /* __LINUX_POSIX_ACL_H */
diff -Nru a/include/linux/posix_acl_xattr.h b/include/linux/posix_acl_xattr.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/posix_acl_xattr.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,55 @@
+/*
+  File: linux/posix_acl_xattr.h
+
+  Extended attribute system call representation of Access Control Lists.
+
+  Copyright (C) 2000 by Andreas Gruenbacher <a.gruenbacher@computer.org>
+  Copyright (C) 2002 SGI - Silicon Graphics, Inc <linux-xfs@oss.sgi.com>
+ */
+#ifndef _POSIX_ACL_XATTR_H
+#define _POSIX_ACL_XATTR_H
+
+#include <linux/posix_acl.h>
+
+/* Extended attribute names */
+#define POSIX_ACL_XATTR_ACCESS	"system.posix_acl_access"
+#define POSIX_ACL_XATTR_DEFAULT	"system.posix_acl_default"
+
+/* Supported ACL a_version fields */
+#define POSIX_ACL_XATTR_VERSION	0x0002
+
+
+/* An undefined entry e_id value */
+#define ACL_UNDEFINED_ID	(-1)
+
+typedef struct {
+	__u16			e_tag;
+	__u16			e_perm;
+	__u32			e_id;
+} posix_acl_xattr_entry;
+
+typedef struct {
+	__u32			a_version;
+	posix_acl_xattr_entry	a_entries[0];
+} posix_acl_xattr_header;
+
+
+static inline size_t
+posix_acl_xattr_size(int count)
+{
+	return (sizeof(posix_acl_xattr_header) +
+		(count * sizeof(posix_acl_xattr_entry)));
+}
+
+static inline int
+posix_acl_xattr_count(size_t size)
+{
+	if (size < sizeof(posix_acl_xattr_header))
+		return -1;
+	size -= sizeof(posix_acl_xattr_header);
+	if (size % sizeof(posix_acl_xattr_entry))
+		return -1;
+	return size / sizeof(posix_acl_xattr_entry);
+}
+
+#endif	/* _POSIX_ACL_XATTR_H */
diff -Nru a/include/linux/ptrace.h b/include/linux/ptrace.h
--- a/include/linux/ptrace.h	Mon Nov  4 14:31:00 2002
+++ b/include/linux/ptrace.h	Mon Nov  4 14:31:00 2002
@@ -23,6 +23,23 @@
 
 #define PTRACE_SYSCALL		  24
 
+/* 0x4200-0x4300 are reserved for architecture-independent additions.  */
+#define PTRACE_SETOPTIONS	0x4200
+#define PTRACE_GETEVENTMSG	0x4201
+
+/* options set using PTRACE_SETOPTIONS */
+#define PTRACE_O_TRACESYSGOOD	0x00000001
+#define PTRACE_O_TRACEFORK	0x00000002
+#define PTRACE_O_TRACEVFORK	0x00000004
+#define PTRACE_O_TRACECLONE	0x00000008
+#define PTRACE_O_TRACEEXEC	0x00000010
+
+/* Wait extended result codes for the above trace options.  */
+#define PTRACE_EVENT_FORK	1
+#define PTRACE_EVENT_VFORK	2
+#define PTRACE_EVENT_CLONE	3
+#define PTRACE_EVENT_EXEC	4
+
 #include <asm/ptrace.h>
 #include <linux/sched.h>
 
@@ -32,6 +49,8 @@
 extern int ptrace_detach(struct task_struct *, unsigned int);
 extern void ptrace_disable(struct task_struct *);
 extern int ptrace_check_attach(struct task_struct *task, int kill);
+extern int ptrace_request(struct task_struct *child, long request, long addr, long data);
+extern void ptrace_notify(int exit_code);
 extern void __ptrace_link(struct task_struct *child,
 				struct task_struct *new_parent);
 extern void __ptrace_unlink(struct task_struct *child);
diff -Nru a/include/linux/sched.h b/include/linux/sched.h
--- a/include/linux/sched.h	Mon Nov  4 14:31:00 2002
+++ b/include/linux/sched.h	Mon Nov  4 14:31:00 2002
@@ -51,6 +51,7 @@
 #define CLONE_SETTID	0x00100000	/* write the TID back to userspace */
 #define CLONE_CLEARTID	0x00200000	/* clear the userspace TID */
 #define CLONE_DETACHED	0x00400000	/* parent wants no child-exit signal */
+#define CLONE_UNTRACED  0x00800000	/* set if the tracing process can't force CLONE_PTRACE on this clone */
 
 /*
  * List of flags we want to share for kernel threads,
@@ -173,6 +174,7 @@
 	struct vm_area_struct * mmap;		/* list of VMAs */
 	struct rb_root mm_rb;
 	struct vm_area_struct * mmap_cache;	/* last find_vma result */
+	unsigned long free_area_cache;		/* first hole */
 	pgd_t * pgd;
 	atomic_t mm_users;			/* How many users with user space? */
 	atomic_t mm_count;			/* How many references to "struct mm_struct" (users count as 1) */
@@ -388,6 +390,8 @@
 	void *journal_info;
 	struct dentry *proc_dentry;
 	struct backing_dev_info *backing_dev_info;
+
+	unsigned long ptrace_message;
 };
 
 extern void __put_task_struct(struct task_struct *tsk);
@@ -426,6 +430,10 @@
 #define PT_DTRACE	0x00000002	/* delayed trace (used on m68k, i386) */
 #define PT_TRACESYSGOOD	0x00000004
 #define PT_PTRACE_CAP	0x00000008	/* ptracer can follow suid-exec */
+#define PT_TRACE_FORK	0x00000010
+#define PT_TRACE_VFORK	0x00000020
+#define PT_TRACE_CLONE	0x00000040
+#define PT_TRACE_EXEC	0x00000080
 
 /*
  * Limit the stack by to some sane default: root can always
diff -Nru a/include/linux/sem.h b/include/linux/sem.h
--- a/include/linux/sem.h	Mon Nov  4 14:31:01 2002
+++ b/include/linux/sem.h	Mon Nov  4 14:31:01 2002
@@ -2,6 +2,7 @@
 #define _LINUX_SEM_H
 
 #include <linux/ipc.h>
+#include <asm/atomic.h>
 
 /* semop flags */
 #define SEM_UNDO        0x1000  /* undo the operation on exit */
diff -Nru a/include/linux/serial_core.h b/include/linux/serial_core.h
--- a/include/linux/serial_core.h	Mon Nov  4 14:31:00 2002
+++ b/include/linux/serial_core.h	Mon Nov  4 14:31:00 2002
@@ -154,6 +154,7 @@
 	unsigned int		flags;
 
 #define UPF_HUP_NOTIFY		(1 << 0)
+#define UPF_FOURPORT		(1 << 1)
 #define UPF_SAK			(1 << 2)
 #define UPF_SPD_MASK		(0x1030)
 #define UPF_SPD_HI		(0x0010)
@@ -167,6 +168,9 @@
 #define UPF_LOW_LATENCY		(1 << 13)
 #define UPF_BUGGY_UART		(1 << 14)
 #define UPF_AUTOPROBE		(1 << 15)
+#define UPF_BOOT_ONLYMCA	(1 << 22)
+#define UPF_CONS_FLOW		(1 << 23)
+#define UPF_SHARE_IRQ		(1 << 24)
 #define UPF_BOOT_AUTOCONF	(1 << 28)
 #define UPF_RESOURCES		(1 << 30)
 #define UPF_IOREMAP		(1 << 31)
@@ -247,8 +251,6 @@
 /* number of characters left in xmit buffer before we ask for more */
 #define WAKEUP_CHARS		256
 
-#define EVT_WRITE_WAKEUP	0
-
 struct module;
 struct tty_driver;
 
@@ -269,7 +271,7 @@
 	struct tty_driver	*tty_driver;
 };
 
-void uart_event(struct uart_port *port, int event);
+void uart_write_wakeup(struct uart_port *port);
 struct uart_port *uart_get_console(struct uart_port *ports, int nr,
 				   struct console *c);
 void uart_parse_options(char *options, int *baud, int *parity, int *bits,
@@ -380,7 +382,7 @@
 			if (status) {
 				tty->hw_stopped = 0;
 				port->ops->start_tx(port, 0);
-				uart_event(port, EVT_WRITE_WAKEUP);
+				uart_write_wakeup(port);
 			}
 		} else {
 			if (!status) {
diff -Nru a/include/linux/shm.h b/include/linux/shm.h
--- a/include/linux/shm.h	Mon Nov  4 14:31:02 2002
+++ b/include/linux/shm.h	Mon Nov  4 14:31:02 2002
@@ -88,6 +88,7 @@
 /* shm_mode upper byte flags */
 #define	SHM_DEST	01000	/* segment will be destroyed on last detach */
 #define SHM_LOCKED      02000   /* segment will not be swapped */
+#define SHM_HUGETLB     04000   /* segment will use huge TLB pages */
 
 asmlinkage long sys_shmget (key_t key, size_t size, int flag);
 asmlinkage long sys_shmat (int shmid, char *shmaddr, int shmflg, unsigned long *addr);
diff -Nru a/include/linux/som.h b/include/linux/som.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/som.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,154 @@
+#ifndef _LINUX_SOM_H
+#define _LINUX_SOM_H
+
+/* File format definition for SOM executables / shared libraries */
+
+/* we need struct timespec */
+#include <linux/time.h>
+
+#define SOM_PAGESIZE 4096
+
+/* this is the SOM header */
+struct som_hdr {
+	short		system_id;		/* magic number - system */
+	short		a_magic;		/* magic number - file type */
+	unsigned int	version_id;		/* versiod ID: YYMMDDHH */
+	struct timespec	file_time;		/* system clock */
+	unsigned int	entry_space;		/* space for entry point */
+	unsigned int	entry_subspace;		/* subspace for entry point */
+	unsigned int	entry_offset;		/* offset of entry point */
+	unsigned int	aux_header_location;	/* auxiliary header location */
+	unsigned int	aux_header_size;	/* auxiliary header size */
+	unsigned int	som_length;		/* length of entire SOM */
+	unsigned int	presumed_dp;		/* compiler's DP value */
+	unsigned int	space_location;		/* space dictionary location */
+	unsigned int	space_total;		/* number of space entries */
+	unsigned int	subspace_location;	/* subspace entries location */
+	unsigned int	subspace_total;		/* number of subspace entries */
+	unsigned int	loader_fixup_location;	/* MPE/iX loader fixup */
+	unsigned int	loader_fixup_total;	/* number of fixup records */
+	unsigned int	space_strings_location;	/* (sub)space names */
+	unsigned int	space_strings_size;	/* size of strings area */
+	unsigned int	init_array_location;	/* reserved */
+	unsigned int	init_array_total;	/* reserved */
+	unsigned int	compiler_location;	/* module dictionary */
+	unsigned int	compiler_total;		/* number of modules */
+	unsigned int	symbol_location;	/* symbol dictionary */
+	unsigned int	symbol_total;		/* number of symbols */
+	unsigned int	fixup_request_location;	/* fixup requests */
+	unsigned int	fixup_request_total;	/* number of fixup requests */
+	unsigned int	symbol_strings_location;/* module & symbol names area */
+	unsigned int	symbol_strings_size;	/* size of strings area */
+	unsigned int	unloadable_sp_location;	/* unloadable spaces location */
+	unsigned int	unloadable_sp_size;	/* size of data */
+	unsigned int	checksum;
+};
+
+/* values for system_id */
+
+#define SOM_SID_PARISC_1_0	0x020b
+#define SOM_SID_PARISC_1_1	0x0210
+#define SOM_SID_PARISC_2_0	0x0214
+
+/* values for a_magic */
+
+#define SOM_LIB_EXEC		0x0104
+#define SOM_RELOCATABLE		0x0106
+#define SOM_EXEC_NONSHARE	0x0107
+#define SOM_EXEC_SHARE		0x0108
+#define SOM_EXEC_DEMAND		0x010B
+#define SOM_LIB_DYN		0x010D
+#define SOM_LIB_SHARE		0x010E
+#define SOM_LIB_RELOC		0x0619
+
+/* values for version_id.  Decimal not hex, yes.  Grr. */
+
+#define SOM_ID_OLD		85082112
+#define SOM_ID_NEW		87102412
+
+struct aux_id {
+	unsigned int	mandatory :1;	/* the linker must understand this */
+	unsigned int	copy	  :1;	/* Must be copied by the linker */
+	unsigned int	append	  :1;	/* Must be merged by the linker */
+	unsigned int	ignore	  :1;	/* Discard section if unknown */
+	unsigned int	reserved  :12;
+	unsigned int	type	  :16;	/* Header type */
+	unsigned int	length;		/* length of _following_ data */
+};
+
+/* The Exec Auxiliary Header.  Called The HP-UX Header within HP apparently. */
+struct som_exec_auxhdr {
+	struct aux_id	som_auxhdr;
+	int		exec_tsize;	/* Text size in bytes */
+	int		exec_tmem;	/* Address to load text at */
+	int		exec_tfile;	/* Location of text in file */
+	int		exec_dsize;	/* Data size in bytes */
+	int		exec_dmem;	/* Address to load data at */
+	int		exec_dfile;	/* Location of data in file */
+	int		exec_bsize;	/* Uninitialised data (bss) */
+	int		exec_entry;	/* Address to start executing */
+	int		exec_flags;	/* loader flags */
+	int		exec_bfill;	/* initialisation value for bss */
+};
+
+/* Oh, the things people do to avoid casts.  Shame it'll break with gcc's
+ * new aliasing rules really.
+ */
+union name_pt {
+	char *		n_name;
+	unsigned int	n_strx;
+};
+
+/* The Space Dictionary */
+struct space_dictionary_record {
+	union name_pt	name;			/* index to subspace name */
+	unsigned int	is_loadable	:1;	/* loadable */
+	unsigned int	is_defined	:1;	/* defined within file */
+	unsigned int	is_private	:1;	/* not sharable */
+	unsigned int	has_intermediate_code :1; /* contains intermediate code */
+	unsigned int	is_tspecific	:1;	/* thread specific */
+	unsigned int	reserved	:11;	/* for future expansion */
+	unsigned int	sort_key	:8;	/* for linker */
+	unsigned int	reserved2	:8;	/* for future expansion */
+
+	int		space_number;		/* index */
+	int		subspace_index;		/* index into subspace dict */
+	unsigned int	subspace_quantity;	/* number of subspaces */
+	int		loader_fix_index;	/* for loader */
+	unsigned int	loader_fix_quantity;	/* for loader */
+	int		init_pointer_index;	/* data pointer array index */
+	unsigned int	init_pointer_quantity;	/* number of data pointers */
+};
+
+/* The Subspace Dictionary */
+struct subspace_dictionary_record {
+	int		space_index;
+	unsigned int	access_control_bits :7;
+	unsigned int	memory_resident	:1;
+	unsigned int	dup_common	:1;
+	unsigned int	is_common	:1;
+	unsigned int	quadrant	:2;
+	unsigned int	initially_frozen :1;
+	unsigned int	is_first	:1;
+	unsigned int	code_only	:1;
+	unsigned int	sort_key	:8;
+	unsigned int	replicate_init	:1;
+	unsigned int	continuation	:1;
+	unsigned int	is_tspecific	:1;
+	unsigned int	is_comdat	:1;
+	unsigned int	reserved	:4;
+
+	int		file_loc_init_value;
+	unsigned int	initialization_length;
+	unsigned int	subspace_start;
+	unsigned int	subspace_length;
+
+	unsigned int	reserved2	:5;
+	unsigned int	alignment	:27;
+
+	union name_pt	name;
+	int		fixup_request_index;
+	unsigned int	fixup_request_quantity;
+};
+
+#endif /* _LINUX_SOM_H */
diff -Nru a/include/linux/swap.h b/include/linux/swap.h
--- a/include/linux/swap.h	Mon Nov  4 14:31:00 2002
+++ b/include/linux/swap.h	Mon Nov  4 14:31:00 2002
@@ -1,11 +1,13 @@
 #ifndef _LINUX_SWAP_H
 #define _LINUX_SWAP_H
 
+#include <linux/config.h>
 #include <linux/spinlock.h>
 #include <linux/kdev_t.h>
 #include <linux/linkage.h>
 #include <linux/mmzone.h>
 #include <linux/list.h>
+#include <asm/atomic.h>
 #include <asm/page.h>
 
 #define SWAP_FLAG_PREFER	0x8000	/* set if swap priority specified */
@@ -36,13 +38,11 @@
  * bootbits...
  */
 union swap_header {
-	struct 
-	{
+	struct {
 		char reserved[PAGE_SIZE - 10];
 		char magic[10];			/* SWAP-SPACE or SWAPSPACE2 */
 	} magic;
-	struct 
-	{
+	struct {
 		char	     bootbits[1024];	/* Space for disklabel etc. */
 		unsigned int version;
 		unsigned int last_page;
@@ -62,6 +62,10 @@
 
 #ifdef __KERNEL__
 
+struct sysinfo;
+struct address_space;
+struct zone;
+
 /*
  * A swap extent maps a range of a swapfile's PAGE_SIZE pages onto a range of
  * disk blocks.  A list of swap extents maps the entire swapfile.  (Where the
@@ -84,8 +88,6 @@
 #define MAX_SWAP_BADPAGES \
 	((__swapoffset(magic.magic) - __swapoffset(info.badpages)) / sizeof(int))
 
-#include <asm/atomic.h>
-
 enum {
 	SWP_USED	= (1 << 0),	/* is slot in swap_info[] used? */
 	SWP_WRITEOK	= (1 << 1),	/* ok to write to this swap?	*/
@@ -122,24 +124,40 @@
 	int next;			/* next entry on swap list */
 };
 
-struct inode;
-extern int nr_swap_pages;
+struct swap_list_t {
+	int head;	/* head of priority-ordered swapfile list */
+	int next;	/* swapfile to be used next */
+};
 
 /* Swap 50% full? Release swapcache more aggressively.. */
 #define vm_swap_full() (nr_swap_pages*2 < total_swap_pages)
 
+/* linux/mm/page_alloc.c */
 extern unsigned long totalram_pages;
 extern unsigned long totalhigh_pages;
+extern int nr_swap_pages;	/* XXX: shouldn't this be ulong? --hch */
 extern unsigned int nr_free_pages(void);
+extern unsigned int nr_free_pages_pgdat(pg_data_t *pgdat);
 extern unsigned int nr_free_buffer_pages(void);
 extern unsigned int nr_free_pagecache_pages(void);
 
-/* Incomplete types for prototype declarations: */
-struct task_struct;
-struct vm_area_struct;
-struct sysinfo;
-struct address_space;
-struct zone;
+/* linux/mm/filemap.c */
+extern void FASTCALL(mark_page_accessed(struct page *));
+
+/* linux/mm/swap.c */
+extern void FASTCALL(lru_cache_add(struct page *));
+extern void FASTCALL(lru_cache_add_active(struct page *));
+extern void FASTCALL(activate_page(struct page *));
+extern void lru_add_drain(void);
+extern void swap_setup(void);
+
+/* linux/mm/vmscan.c */
+extern int try_to_free_pages(struct zone *, unsigned int, unsigned int);
+extern int shrink_all_memory(int);
+extern int vm_swappiness;
+
+/* linux/mm/oom_kill.c */
+extern void out_of_memory(void);
 
 /* linux/mm/rmap.c */
 extern int FASTCALL(page_referenced(struct page *));
@@ -154,42 +172,31 @@
 #define	SWAP_FAIL	2
 #define	SWAP_ERROR	3
 
-/* linux/mm/swap.c */
-extern void FASTCALL(lru_cache_add(struct page *));
-
-extern void FASTCALL(activate_page(struct page *));
-
-extern void swap_setup(void);
-
-/* linux/mm/vmscan.c */
-extern int try_to_free_pages(struct zone *, unsigned int, unsigned int);
-int shrink_all_memory(int nr_pages);
-extern int vm_swappiness;
+/* linux/mm/shmem.c */
+extern int shmem_unuse(swp_entry_t entry, struct page *page);
 
+#ifdef CONFIG_SWAP
 /* linux/mm/page_io.c */
-int swap_readpage(struct file *file, struct page *page);
-int swap_writepage(struct page *page);
-int rw_swap_page_sync(int rw, swp_entry_t entry, struct page *page);
-
-/* linux/mm/page_alloc.c */
+extern int swap_readpage(struct file *, struct page *);
+extern int swap_writepage(struct page *);
+extern int rw_swap_page_sync(int, swp_entry_t, struct page *);
 
 /* linux/mm/swap_state.c */
+extern struct address_space swapper_space;
+#define total_swapcache_pages  swapper_space.nrpages
 extern void show_swap_cache_info(void);
 extern int add_to_swap_cache(struct page *, swp_entry_t);
 extern int add_to_swap(struct page *);
-extern void __delete_from_swap_cache(struct page *page);
-extern void delete_from_swap_cache(struct page *page);
-extern int move_to_swap_cache(struct page *page, swp_entry_t entry);
-extern int move_from_swap_cache(struct page *page, unsigned long index,
-		struct address_space *mapping);
-extern void free_page_and_swap_cache(struct page *page);
-extern void free_pages_and_swap_cache(struct page **pages, int nr);
+extern void __delete_from_swap_cache(struct page *);
+extern void delete_from_swap_cache(struct page *);
+extern int move_to_swap_cache(struct page *, swp_entry_t);
+extern int move_from_swap_cache(struct page *, unsigned long,
+		struct address_space *);
+extern void free_page_and_swap_cache(struct page *);
+extern void free_pages_and_swap_cache(struct page **, int);
 extern struct page * lookup_swap_cache(swp_entry_t);
 extern struct page * read_swap_cache_async(swp_entry_t);
 
-/* linux/mm/oom_kill.c */
-extern void out_of_memory(void);
-
 /* linux/mm/swapfile.c */
 extern int total_swap_pages;
 extern unsigned int nr_swapfiles;
@@ -200,19 +207,12 @@
 extern int valid_swaphandles(swp_entry_t, unsigned long *);
 extern void swap_free(swp_entry_t);
 extern void free_swap_and_cache(swp_entry_t);
-sector_t map_swap_page(struct swap_info_struct *p, pgoff_t offset);
-struct swap_info_struct *get_swap_info_struct(unsigned type);
+extern sector_t map_swap_page(struct swap_info_struct *, pgoff_t);
+extern struct swap_info_struct *get_swap_info_struct(unsigned);
+extern int can_share_swap_page(struct page *);
+extern int remove_exclusive_swap_page(struct page *);
 
-struct swap_list_t {
-	int head;	/* head of priority-ordered swapfile list */
-	int next;	/* swapfile to be used next */
-};
 extern struct swap_list_t swap_list;
-asmlinkage long sys_swapoff(const char *);
-asmlinkage long sys_swapon(const char *, int);
-
-extern void FASTCALL(mark_page_accessed(struct page *));
-
 extern spinlock_t swaplock;
 
 #define swap_list_lock()	spin_lock(&swaplock)
@@ -220,8 +220,39 @@
 #define swap_device_lock(p)	spin_lock(&p->sdev_lock)
 #define swap_device_unlock(p)	spin_unlock(&p->sdev_lock)
 
-extern int shmem_unuse(swp_entry_t entry, struct page *page);
+#else /* CONFIG_SWAP */
 
-#endif /* __KERNEL__*/
+#define total_swap_pages			0
+#define total_swapcache_pages			0UL
+
+#define si_swapinfo(val) \
+	do { (val)->freeswap = (val)->totalswap = 0; } while (0)
+#define free_page_and_swap_cache(page) \
+	page_cache_release(page)
+#define free_pages_and_swap_cache(pages, nr) \
+	release_pages((pages), (nr), 0);
+
+#define show_swap_cache_info()			/*NOTHING*/
+#define free_swap_and_cache(swp)		/*NOTHING*/
+#define swap_duplicate(swp)			/*NOTHING*/
+#define swap_free(swp)				/*NOTHING*/
+#define read_swap_cache_async(swp)		NULL
+#define lookup_swap_cache(swp)			NULL
+#define valid_swaphandles(swp, off)		0
+#define can_share_swap_page(p)			0
+#define remove_exclusive_swap_page(p)		0
+#define move_to_swap_cache(p, swp)		1
+#define move_from_swap_cache(p, i, m)		1
+#define __delete_from_swap_cache(p)		/*NOTHING*/
+#define delete_from_swap_cache(p)		/*NOTHING*/
+
+static inline swp_entry_t get_swap_page(void)
+{
+	swp_entry_t entry;
+	entry.val = 0;
+	return entry;
+}
 
+#endif /* CONFIG_SWAP */
+#endif /* __KERNEL__*/
 #endif /* _LINUX_SWAP_H */
diff -Nru a/include/linux/sysfs.h b/include/linux/sysfs.h
--- a/include/linux/sysfs.h	Mon Nov  4 14:31:01 2002
+++ b/include/linux/sysfs.h	Mon Nov  4 14:31:01 2002
@@ -9,18 +9,16 @@
 #ifndef _SYSFS_H_
 #define _SYSFS_H_
 
-struct driver_dir_entry;
-struct attribute;
 struct kobject;
 
-struct sysfs_ops {
-	ssize_t	(*show)(struct kobject *, struct attribute *,char *, size_t, loff_t);
-	ssize_t	(*store)(struct kobject *,struct attribute *,const char *, size_t, loff_t);
-};
-
 struct attribute {
 	char			* name;
 	mode_t			mode;
+};
+
+struct sysfs_ops {
+	ssize_t	(*show)(struct kobject *, struct attribute *,char *, size_t, loff_t);
+	ssize_t	(*store)(struct kobject *,struct attribute *,const char *, size_t, loff_t);
 };
 
 extern int
diff -Nru a/include/linux/videodev.h b/include/linux/videodev.h
--- a/include/linux/videodev.h	Mon Nov  4 14:31:03 2002
+++ b/include/linux/videodev.h	Mon Nov  4 14:31:03 2002
@@ -4,10 +4,10 @@
 #include <linux/types.h>
 #include <linux/version.h>
 
-#if 0
+#if 1
 /*
  * v4l2 is still work-in-progress, integration planed for 2.5.x
- *   v4l2 project homepage:   http://www.thedirks.org/v4l2/
+ *   documentation:           http://bytesex.org/v4l/
  *   patches available from:  http://bytesex.org/patches/
  */ 
 # define HAVE_V4L2 1
@@ -32,10 +32,7 @@
 	int minor;
 
  	/* new interface -- we will use file_operations directly
- 	 * like soundcore does.
- 	 * kernel_ioctl() will be called by video_generic_ioctl.
- 	 * video_generic_ioctl() does the userspace copying of the
- 	 * ioctl arguments */
+ 	 * like soundcore does. */
  	struct file_operations *fops;
 	void *priv;		/* Used to be 'private' but that upsets C++ */
 
@@ -397,7 +394,7 @@
 #define VID_HARDWARE_PWC	31	/* Philips webcams */
 #define VID_HARDWARE_MEYE	32	/* Sony Vaio MotionEye cameras */
 #define VID_HARDWARE_CPIA2	33
-#define VID_HARDWARE_VICAM	34
+#define VID_HARDWARE_VICAM      34
 
 #endif /* __LINUX_VIDEODEV_H */
 
diff -Nru a/include/linux/videodev2.h b/include/linux/videodev2.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/videodev2.h	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,859 @@
+#ifndef __LINUX_VIDEODEV2_H
+#define __LINUX_VIDEODEV2_H
+/*
+ *	Video for Linux Two
+ *
+ *	Header file for v4l or V4L2 drivers and applications, for
+ *	Linux kernels 2.2.x or 2.4.x.
+ *
+ *	See http://bytesex.org/v4l/ for API specs and other
+ *	v4l2 documentation.
+ *
+ *	Author: Bill Dirks <bdirks@pacbell.net>
+ *		Justin Schoeman
+ *		et al.
+ */
+#include <linux/time.h> /* need struct timeval */
+
+/*
+ *	M I S C E L L A N E O U S
+ */
+
+/*  Four-character-code (FOURCC) */
+#define v4l2_fourcc(a,b,c,d)\
+        (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
+
+/*
+ *	E N U M S
+ */
+enum v4l2_field {
+	V4L2_FIELD_ANY        = 0, /* driver can choose from none,
+				      top, bottom, interlaced
+				      depending on whatever it thinks
+				      is approximate ... */
+	V4L2_FIELD_NONE       = 1, /* this device has no fields ... */
+	V4L2_FIELD_TOP        = 2, /* top field only */
+	V4L2_FIELD_BOTTOM     = 3, /* bottom field only */
+	V4L2_FIELD_INTERLACED = 4, /* both fields interlaced */
+	V4L2_FIELD_SEQ_TB     = 5, /* both fields sequential into one
+				      buffer, top-bottom order */
+	V4L2_FIELD_SEQ_BT     = 6, /* same as above + bottom-top order */
+	V4L2_FIELD_ALTERNATE  = 7, /* both fields alternating into
+				      separate buffers */
+};
+#define V4L2_FIELD_HAS_TOP(field)	\
+	((field) == V4L2_FIELD_TOP 	||\
+	 (field) == V4L2_FIELD_INTERLACED ||\
+	 (field) == V4L2_FIELD_SEQ_TB	||\
+	 (field) == V4L2_FIELD_SEQ_BT)
+#define V4L2_FIELD_HAS_BOTTOM(field)	\
+	((field) == V4L2_FIELD_BOTTOM 	||\
+	 (field) == V4L2_FIELD_INTERLACED ||\
+	 (field) == V4L2_FIELD_SEQ_TB	||\
+	 (field) == V4L2_FIELD_SEQ_BT)
+#define V4L2_FIELD_HAS_BOTH(field)	\
+	((field) == V4L2_FIELD_INTERLACED ||\
+	 (field) == V4L2_FIELD_SEQ_TB	||\
+	 (field) == V4L2_FIELD_SEQ_BT)
+
+enum v4l2_buf_type {
+	V4L2_BUF_TYPE_VIDEO_CAPTURE  = 1,
+	V4L2_BUF_TYPE_VIDEO_OUTPUT   = 2,
+	V4L2_BUF_TYPE_VIDEO_OVERLAY  = 3,
+	V4L2_BUF_TYPE_VBI_CAPTURE    = 4,
+	V4L2_BUF_TYPE_VBI_OUTPUT     = 5,
+	V4L2_BUF_TYPE_PRIVATE        = 0x80,
+};
+
+enum v4l2_ctrl_type {
+	V4L2_CTRL_TYPE_INTEGER	     = 1,
+	V4L2_CTRL_TYPE_BOOLEAN	     = 2,
+	V4L2_CTRL_TYPE_MENU	     = 3,
+	V4L2_CTRL_TYPE_BUTTON	     = 4,
+};
+
+enum v4l2_tuner_type {
+	V4L2_TUNER_RADIO	     = 1,
+	V4L2_TUNER_ANALOG_TV	     = 2,
+};
+
+enum v4l2_memory {
+	V4L2_MEMORY_MMAP             = 1,
+	V4L2_MEMORY_USERPTR          = 2,
+	V4L2_MEMORY_OVERLAY          = 3,
+};
+
+/* see also http://vektor.theorem.ca/graphics/ycbcr/ */
+enum v4l2_colorspace {
+	/* ITU-R 601 -- broadcast NTSC/PAL */
+	V4L2_COLORSPACE_SMPTE170M     = 1,
+
+	/* 1125-Line (US) HDTV */
+	V4L2_COLORSPACE_SMPTE240M     = 2,
+
+	/* HD and modern captures. */
+	V4L2_COLORSPACE_REC709        = 3,
+	
+	/* broken BT878 extents (601, luma range 16-253 instead of 16-235) */
+	V4L2_COLORSPACE_BT878         = 4,
+	
+	/* These should be useful.  Assume 601 extents. */
+	V4L2_COLORSPACE_470_SYSTEM_M  = 5,
+	V4L2_COLORSPACE_470_SYSTEM_BG = 6,
+	
+	/* I know there will be cameras that send this.  So, this is
+	 * unspecified chromaticities and full 0-255 on each of the
+	 * Y'CbCr components
+	 */
+	V4L2_COLORSPACE_JPEG          = 7,
+	
+	/* For RGB colourspaces, this is probably a good start. */
+	V4L2_COLORSPACE_SRGB          = 8,
+};
+
+struct v4l2_rect {
+	__s32   left;
+	__s32   top;
+	__s32   width;
+	__s32   height;
+};
+
+struct v4l2_fract {
+	__u32   numerator;
+	__u32   denominator;
+};
+
+/*
+ *	D R I V E R   C A P A B I L I T I E S
+ */
+struct v4l2_capability
+{
+	__u8	driver[16];	/* i.e. "bttv" */
+	__u8	card[32];	/* i.e. "Hauppauge WinTV" */
+	__u8	bus_info[32];	/* "PCI:" + pci_dev->slot_name */
+	__u32   version;        /* should use KERNEL_VERSION() */
+	__u32	capabilities;	/* Device capabilities */
+	__u32	reserved[4];
+};
+
+/* Values for 'capabilities' field */
+#define V4L2_CAP_VIDEO_CAPTURE	0x00000001  /* Is a video capture device */
+#define V4L2_CAP_VIDEO_OUTPUT	0x00000002  /* Is a video output device */
+#define V4L2_CAP_VIDEO_OVERLAY	0x00000004  /* Can do video overlay */
+#define V4L2_CAP_VBI_CAPTURE	0x00000010  /* Is a VBI capture device */
+#define V4L2_CAP_VBI_OUTPUT	0x00000020  /* Is a VBI output device */
+#define V4L2_CAP_RDS_CAPTURE	0x00000100  /* RDS data capture */
+
+#define V4L2_CAP_TUNER		0x00010000  /* Has a tuner */
+#define V4L2_CAP_AUDIO		0x00020000  /* has audio support */
+
+#define V4L2_CAP_READWRITE      0x01000000  /* read/write systemcalls */
+#define V4L2_CAP_ASYNCIO        0x02000000  /* async I/O */
+#define V4L2_CAP_STREAMING      0x04000000  /* streaming I/O ioctls */
+
+/*
+ *	V I D E O   I M A G E   F O R M A T
+ */
+
+struct v4l2_pix_format
+{
+	__u32         	 	width;
+	__u32	         	height;
+	__u32	         	pixelformat;
+	enum v4l2_field  	field;
+	__u32            	bytesperline;	/* for padding, zero if unused */
+	__u32          	 	sizeimage;
+        enum v4l2_colorspace	colorspace;
+	__u32			priv;		/* private data, depends on pixelformat */
+};
+
+/*           Pixel format    FOURCC                  depth  Description   */
+#define V4L2_PIX_FMT_RGB332  v4l2_fourcc('R','G','B','1') /*  8  RGB-3-3-2     */
+#define V4L2_PIX_FMT_RGB555  v4l2_fourcc('R','G','B','O') /* 16  RGB-5-5-5     */
+#define V4L2_PIX_FMT_RGB565  v4l2_fourcc('R','G','B','P') /* 16  RGB-5-6-5     */
+#define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R','G','B','Q') /* 16  RGB-5-5-5 BE  */
+#define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R','G','B','R') /* 16  RGB-5-6-5 BE  */
+#define V4L2_PIX_FMT_BGR24   v4l2_fourcc('B','G','R','3') /* 24  BGR-8-8-8     */
+#define V4L2_PIX_FMT_RGB24   v4l2_fourcc('R','G','B','3') /* 24  RGB-8-8-8     */
+#define V4L2_PIX_FMT_BGR32   v4l2_fourcc('B','G','R','4') /* 32  BGR-8-8-8-8   */
+#define V4L2_PIX_FMT_RGB32   v4l2_fourcc('R','G','B','4') /* 32  RGB-8-8-8-8   */
+#define V4L2_PIX_FMT_GREY    v4l2_fourcc('G','R','E','Y') /*  8  Greyscale     */
+#define V4L2_PIX_FMT_YVU410  v4l2_fourcc('Y','V','U','9') /*  9  YVU 4:1:0     */
+#define V4L2_PIX_FMT_YVU420  v4l2_fourcc('Y','V','1','2') /* 12  YVU 4:2:0     */
+#define V4L2_PIX_FMT_YUYV    v4l2_fourcc('Y','U','Y','V') /* 16  YUV 4:2:2     */
+#define V4L2_PIX_FMT_UYVY    v4l2_fourcc('U','Y','V','Y') /* 16  YUV 4:2:2     */
+#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4','2','2','P') /* 16  YVU422 planar */
+#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4','1','1','P') /* 16  YVU411 planar */
+#define V4L2_PIX_FMT_Y41P    v4l2_fourcc('Y','4','1','P') /* 12  YUV 4:1:1     */
+
+/* two planes -- one Y, one Cr + Cb interleaved  */
+#define V4L2_PIX_FMT_NV12    v4l2_fourcc('N','V','1','2') /* 12  Y/CbCr 4:2:0  */
+#define V4L2_PIX_FMT_NV21    v4l2_fourcc('N','V','2','1') /* 12  Y/CrCb 4:2:0  */
+
+/*  The following formats are not defined in the V4L2 specification */
+#define V4L2_PIX_FMT_YUV410  v4l2_fourcc('Y','U','V','9') /*  9  YUV 4:1:0     */
+#define V4L2_PIX_FMT_YUV420  v4l2_fourcc('Y','U','1','2') /* 12  YUV 4:2:0     */
+#define V4L2_PIX_FMT_YYUV    v4l2_fourcc('Y','Y','U','V') /* 16  YUV 4:2:2     */
+#define V4L2_PIX_FMT_HI240   v4l2_fourcc('H','I','2','4') /*  8  8-bit color   */
+
+/* compressed formats */
+#define V4L2_PIX_FMT_MJPEG    v4l2_fourcc('M','J','P','G') /* Motion-JPEG   */
+#define V4L2_PIX_FMT_JPEG     v4l2_fourcc('J','P','E','G') /* JFIF JPEG     */
+#define V4L2_PIX_FMT_DV       v4l2_fourcc('d','v','s','d') /* 1394          */
+#define V4L2_PIX_FMT_MPEG     v4l2_fourcc('M','P','E','G') /* MPEG          */
+
+/*  Vendor-specific formats   */
+#define V4L2_PIX_FMT_WNVA    v4l2_fourcc('W','N','V','A') /* Winnov hw compres */
+
+/*
+ *	F O R M A T   E N U M E R A T I O N
+ */
+struct v4l2_fmtdesc
+{
+	__u32	            index;             /* Format number      */
+	enum v4l2_buf_type  type;              /* buffer type        */
+	__u32               flags;
+	__u8	            description[32];   /* Description string */
+	__u32	            pixelformat;       /* Format fourcc      */
+	__u32	            reserved[4];
+};
+
+#define V4L2_FMT_FLAG_COMPRESSED 0x0001
+
+
+/*
+ *	T I M E C O D E
+ */
+struct v4l2_timecode
+{
+	__u32	type;
+	__u32	flags;
+	__u8	frames;
+	__u8	seconds;
+	__u8	minutes;
+	__u8	hours;
+	__u8	userbits[4];
+};
+
+/*  Type  */
+#define V4L2_TC_TYPE_24FPS		1
+#define V4L2_TC_TYPE_25FPS		2
+#define V4L2_TC_TYPE_30FPS		3
+#define V4L2_TC_TYPE_50FPS		4
+#define V4L2_TC_TYPE_60FPS		5
+
+/*  Flags  */
+#define V4L2_TC_FLAG_DROPFRAME		0x0001 /* "drop-frame" mode */
+#define V4L2_TC_FLAG_COLORFRAME		0x0002
+#define V4L2_TC_USERBITS_field		0x000C
+#define V4L2_TC_USERBITS_USERDEFINED	0x0000
+#define V4L2_TC_USERBITS_8BITCHARS	0x0008
+/* The above is based on SMPTE timecodes */
+
+
+/*
+ *	C O M P R E S S I O N   P A R A M E T E R S
+ */
+#if 0
+/* ### generic compression settings don't work, there is too much
+ * ### codec-specific stuff.  Maybe reuse that for MPEG codec settings
+ * ### later ... */
+struct v4l2_compression
+{
+	__u32	quality;
+	__u32	keyframerate;
+	__u32	pframerate;
+	__u32	reserved[5];
+};
+#endif
+
+struct v4l2_jpegcompression
+{
+	int quality;
+
+	int  APPn;              /* Number of APP segment to be written,
+				 * must be 0..15 */
+	int  APP_len;           /* Length of data in JPEG APPn segment */
+	char APP_data[60];      /* Data in the JPEG APPn segment. */
+	
+	int  COM_len;           /* Length of data in JPEG COM segment */
+	char COM_data[60];      /* Data in JPEG COM segment */
+	
+	__u32 jpeg_markers;     /* Which markers should go into the JPEG
+				 * output. Unless you exactly know what
+				 * you do, leave them untouched.
+				 * Inluding less markers will make the
+				 * resulting code smaller, but there will
+				 * be fewer aplications which can read it.
+				 * The presence of the APP and COM marker
+				 * is influenced by APP_len and COM_len
+				 * ONLY, not by this property! */
+	
+#define V4L2_JPEG_MARKER_DHT (1<<3)    /* Define Huffman Tables */
+#define V4L2_JPEG_MARKER_DQT (1<<4)    /* Define Quantization Tables */
+#define V4L2_JPEG_MARKER_DRI (1<<5)    /* Define Restart Interval */
+#define V4L2_JPEG_MARKER_COM (1<<6)    /* Comment segment */
+#define V4L2_JPEG_MARKER_APP (1<<7)    /* App segment, driver will
+                                        * allways use APP0 */
+};
+
+
+/*
+ *	M E M O R Y - M A P P I N G   B U F F E R S
+ */
+struct v4l2_requestbuffers
+{
+	__u32	                count;
+	enum v4l2_buf_type      type;
+	enum v4l2_memory        memory;
+	__u32	                reserved[2];
+};
+
+struct v4l2_buffer
+{
+	__u32			index;
+	enum v4l2_buf_type      type;
+	__u32			bytesused;
+	__u32			flags;
+	enum v4l2_field		field;
+	struct timeval		timestamp;
+	struct v4l2_timecode	timecode;
+	__u32			sequence;
+
+	/* memory location */
+	enum v4l2_memory        memory;
+	union {
+		__u32           offset;
+		unsigned long   userptr;
+	} m;
+	__u32			length;
+
+	__u32			reserved[2];
+};
+
+/*  Flags for 'flags' field */
+#define V4L2_BUF_FLAG_MAPPED	0x0001  /* Buffer is mapped (flag) */
+#define V4L2_BUF_FLAG_QUEUED	0x0002	/* Buffer is queued for processing */
+#define V4L2_BUF_FLAG_DONE	0x0004	/* Buffer is ready */
+#define V4L2_BUF_FLAG_KEYFRAME	0x0008	/* Image is a keyframe (I-frame) */
+#define V4L2_BUF_FLAG_PFRAME	0x0010	/* Image is a P-frame */
+#define V4L2_BUF_FLAG_BFRAME	0x0020	/* Image is a B-frame */
+#define V4L2_BUF_FLAG_TIMECODE	0x0100	/* timecode field is valid */
+
+/*
+ *	O V E R L A Y   P R E V I E W
+ */
+struct v4l2_framebuffer
+{
+	__u32			capability;
+	__u32			flags;
+/* FIXME: in theory we should pass something like PCI device + memory
+ * region + offset instead of some physical address */
+	void*                   base;
+	struct v4l2_pix_format	fmt;
+};
+/*  Flags for the 'capability' field. Read only */
+#define V4L2_FBUF_CAP_EXTERNOVERLAY	0x0001
+#define V4L2_FBUF_CAP_CHROMAKEY		0x0002
+#define V4L2_FBUF_CAP_LIST_CLIPPING     0x0004
+#define V4L2_FBUF_CAP_BITMAP_CLIPPING	0x0008
+/*  Flags for the 'flags' field. */
+#define V4L2_FBUF_FLAG_PRIMARY		0x0001
+#define V4L2_FBUF_FLAG_OVERLAY		0x0002
+#define V4L2_FBUF_FLAG_CHROMAKEY	0x0004
+
+struct v4l2_clip
+{
+	struct v4l2_rect        c;
+	struct v4l2_clip	*next;
+};
+
+struct v4l2_window
+{
+	struct v4l2_rect        w;
+	enum v4l2_field  	field;
+	__u32			chromakey;
+	struct v4l2_clip	*clips;
+	__u32			clipcount;
+	void			*bitmap;
+};
+
+
+/*
+ *	C A P T U R E   P A R A M E T E R S
+ */
+struct v4l2_captureparm
+{
+	__u32		   capability;	  /*  Supported modes */
+	__u32		   capturemode;	  /*  Current mode */
+	struct v4l2_fract  timeperframe;  /*  Time per frame in .1us units */
+	__u32		   extendedmode;  /*  Driver-specific extensions */
+	__u32              readbuffers;   /*  # of buffers for read */
+	__u32		   reserved[4];
+};
+/*  Flags for 'capability' and 'capturemode' fields */
+#define V4L2_MODE_HIGHQUALITY	0x0001	/*  High quality imaging mode */
+#define V4L2_CAP_TIMEPERFRAME	0x1000	/*  timeperframe field is supported */
+
+struct v4l2_outputparm
+{
+	__u32		   capability;	 /*  Supported modes */
+	__u32		   outputmode;	 /*  Current mode */
+	struct v4l2_fract  timeperframe; /*  Time per frame in seconds */
+	__u32		   extendedmode; /*  Driver-specific extensions */
+	__u32              writebuffers; /*  # of buffers for write */
+	__u32		   reserved[4];
+};
+
+/*
+ *	I N P U T   I M A G E   C R O P P I N G
+ */
+
+struct v4l2_cropcap {
+	enum v4l2_buf_type      type;	
+        struct v4l2_rect        bounds;
+        struct v4l2_rect        defrect;
+        struct v4l2_fract       pixelaspect;
+};
+
+struct v4l2_crop {
+	enum v4l2_buf_type      type;
+	struct v4l2_rect        c;
+};
+
+/*
+ *      A N A L O G   V I D E O   S T A N D A R D
+ */
+
+typedef __u64 v4l2_std_id;
+
+/* one bit for each */
+#define V4L2_STD_PAL_B          ((v4l2_std_id)0x00000001)
+#define V4L2_STD_PAL_B1         ((v4l2_std_id)0x00000002)
+#define V4L2_STD_PAL_G          ((v4l2_std_id)0x00000004)
+#define V4L2_STD_PAL_H          ((v4l2_std_id)0x00000008)
+#define V4L2_STD_PAL_I          ((v4l2_std_id)0x00000010)
+#define V4L2_STD_PAL_D          ((v4l2_std_id)0x00000020)
+#define V4L2_STD_PAL_D1         ((v4l2_std_id)0x00000040)
+#define V4L2_STD_PAL_K          ((v4l2_std_id)0x00000080)
+
+#define V4L2_STD_PAL_M          ((v4l2_std_id)0x00000100)
+#define V4L2_STD_PAL_N          ((v4l2_std_id)0x00000200)
+#define V4L2_STD_PAL_Nc         ((v4l2_std_id)0x00000400)
+#define V4L2_STD_PAL_60         ((v4l2_std_id)0x00000800)
+
+#define V4L2_STD_NTSC_M         ((v4l2_std_id)0x00001000)
+#define V4L2_STD_NTSC_M_JP      ((v4l2_std_id)0x00002000)
+
+#define V4L2_STD_SECAM_B        ((v4l2_std_id)0x00010000)
+#define V4L2_STD_SECAM_D        ((v4l2_std_id)0x00020000)
+#define V4L2_STD_SECAM_G        ((v4l2_std_id)0x00040000)
+#define V4L2_STD_SECAM_H        ((v4l2_std_id)0x00080000)
+#define V4L2_STD_SECAM_K        ((v4l2_std_id)0x00100000)
+#define V4L2_STD_SECAM_K1       ((v4l2_std_id)0x00200000)
+#define V4L2_STD_SECAM_L        ((v4l2_std_id)0x00400000)
+
+/* ATSC/HDTV */
+#define V4L2_STD_ATSC_8_VSB     ((v4l2_std_id)0x01000000)
+#define V4L2_STD_ATSC_16_VSB    ((v4l2_std_id)0x02000000)
+
+/* some common needed stuff */
+#define V4L2_STD_PAL_BG		(V4L2_STD_PAL_B		|\
+				 V4L2_STD_PAL_B1	|\
+				 V4L2_STD_PAL_G)
+#define V4L2_STD_PAL_DK		(V4L2_STD_PAL_D		|\
+				 V4L2_STD_PAL_D1	|\
+				 V4L2_STD_PAL_K)
+#define V4L2_STD_PAL		(V4L2_STD_PAL_BG	|\
+				 V4L2_STD_PAL_DK	|\
+				 V4L2_STD_PAL_H		|\
+				 V4L2_STD_PAL_I)
+#define V4L2_STD_NTSC           (V4L2_STD_NTSC_M	|\
+				 V4L2_STD_NTSC_M_JP)
+#define V4L2_STD_SECAM		(V4L2_STD_SECAM_B	|\
+				 V4L2_STD_SECAM_D	|\
+				 V4L2_STD_SECAM_G	|\
+				 V4L2_STD_SECAM_H	|\
+				 V4L2_STD_SECAM_K	|\
+				 V4L2_STD_SECAM_K1	|\
+				 V4L2_STD_SECAM_L)
+
+#define V4L2_STD_525_60		(V4L2_STD_PAL_M		|\
+				 V4L2_STD_PAL_60	|\
+				 V4L2_STD_NTSC)
+#define V4L2_STD_625_50		(V4L2_STD_PAL		|\
+				 V4L2_STD_PAL_N		|\
+				 V4L2_STD_PAL_Nc	|\
+				 V4L2_STD_SECAM)
+
+#define V4L2_STD_UNKNOWN        0
+#define V4L2_STD_ALL            (V4L2_STD_525_60	|\
+				 V4L2_STD_625_50)
+
+struct v4l2_standard
+{
+	__u32	       	     index;
+	v4l2_std_id          id;
+	__u8		     name[24];
+	struct v4l2_fract    frameperiod; /* Frames, not fields */
+	__u32		     framelines;
+	__u32		     reserved[4];
+};
+
+
+/*
+ *	V I D E O   I N P U T S
+ */
+struct v4l2_input
+{
+	__u32	     index;		/*  Which input */
+	__u8	     name[32];	        /*  Label */
+	__u32	     type;		/*  Type of input */
+	__u32	     audioset;	        /*  Associated audios (bitfield) */
+	__u32        tuner;             /*  Associated tuner */
+	v4l2_std_id  std;
+	__u32	     status;
+	__u32	     reserved[4];
+};
+/*  Values for the 'type' field */
+#define V4L2_INPUT_TYPE_TUNER		1
+#define V4L2_INPUT_TYPE_CAMERA		2
+
+/* field 'status' - general */
+#define V4L2_IN_ST_NO_POWER    0x00000001  /* Attached device is off */
+#define V4L2_IN_ST_NO_SIGNAL   0x00000002
+#define V4L2_IN_ST_NO_COLOR    0x00000004
+
+/* field 'status' - analog */
+#define V4L2_IN_ST_NO_H_LOCK   0x00000100  /* No horizontal sync lock */
+#define V4L2_IN_ST_COLOR_KILL  0x00000200  /* Color killer is active */
+
+/* field 'status' - digital */
+#define V4L2_IN_ST_NO_SYNC     0x00010000  /* No synchronization lock */
+#define V4L2_IN_ST_NO_EQU      0x00020000  /* No equalizer lock */
+#define V4L2_IN_ST_NO_CARRIER  0x00040000  /* Carrier recovery failed */
+
+/* field 'status' - VCR and set-top box */
+#define V4L2_IN_ST_MACROVISION 0x01000000  /* Macrovision detected */
+#define V4L2_IN_ST_NO_ACCESS   0x02000000  /* Conditional access denied */
+#define V4L2_IN_ST_VTR         0x04000000  /* VTR time constant */
+
+/*
+ *	V I D E O   O U T P U T S
+ */
+struct v4l2_output
+{
+	__u32	     index;		/*  Which output */
+	__u8	     name[32];	        /*  Label */
+	__u32	     type;		/*  Type of output */
+	__u32	     audioset;	        /*  Associated audios (bitfield) */
+	__u32	     modulator;         /*  Associated modulator */
+	v4l2_std_id  std;
+	__u32	     reserved[4];
+};
+/*  Values for the 'type' field */
+#define V4L2_OUTPUT_TYPE_MODULATOR		1
+#define V4L2_OUTPUT_TYPE_ANALOG			2
+#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY	3
+
+/*
+ *	C O N T R O L S
+ */
+struct v4l2_control
+{
+	__u32		     id;
+	__s32		     value;
+};
+
+/*  Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
+struct v4l2_queryctrl
+{
+	__u32	             id;
+	enum v4l2_ctrl_type  type;
+	__u8		     name[32];	/* Whatever */
+	__s32		     minimum;	/* Note signedness */
+	__s32		     maximum;
+	__s32	             step;
+	__s32		     default_value;
+	__u32                flags;
+	__u32		     reserved[2];
+};
+
+/*  Used in the VIDIOC_QUERYMENU ioctl for querying menu items */
+struct v4l2_querymenu
+{
+	__u32		id;
+	__u32		index;
+	__u8		name[32];	/* Whatever */
+	__u32		reserved;
+};
+
+/*  Control flags  */
+#define V4L2_CTRL_FLAG_DISABLED		0x0001
+#define V4L2_CTRL_FLAG_GRABBED		0x0002
+
+/*  Control IDs defined by V4L2 */
+#define V4L2_CID_BASE			0x00980900
+/*  IDs reserved for driver specific controls */
+#define V4L2_CID_PRIVATE_BASE		0x08000000
+
+#define V4L2_CID_BRIGHTNESS		(V4L2_CID_BASE+0)
+#define V4L2_CID_CONTRAST		(V4L2_CID_BASE+1)
+#define V4L2_CID_SATURATION		(V4L2_CID_BASE+2)
+#define V4L2_CID_HUE			(V4L2_CID_BASE+3)
+#define V4L2_CID_AUDIO_VOLUME		(V4L2_CID_BASE+5)
+#define V4L2_CID_AUDIO_BALANCE		(V4L2_CID_BASE+6)
+#define V4L2_CID_AUDIO_BASS		(V4L2_CID_BASE+7)
+#define V4L2_CID_AUDIO_TREBLE		(V4L2_CID_BASE+8)
+#define V4L2_CID_AUDIO_MUTE		(V4L2_CID_BASE+9)
+#define V4L2_CID_AUDIO_LOUDNESS		(V4L2_CID_BASE+10)
+#define V4L2_CID_BLACK_LEVEL		(V4L2_CID_BASE+11)
+#define V4L2_CID_AUTO_WHITE_BALANCE	(V4L2_CID_BASE+12)
+#define V4L2_CID_DO_WHITE_BALANCE	(V4L2_CID_BASE+13)
+#define V4L2_CID_RED_BALANCE		(V4L2_CID_BASE+14)
+#define V4L2_CID_BLUE_BALANCE		(V4L2_CID_BASE+15)
+#define V4L2_CID_GAMMA			(V4L2_CID_BASE+16)
+#define V4L2_CID_WHITENESS		(V4L2_CID_GAMMA) /* ? Not sure */
+#define V4L2_CID_EXPOSURE		(V4L2_CID_BASE+17)
+#define V4L2_CID_AUTOGAIN		(V4L2_CID_BASE+18)
+#define V4L2_CID_GAIN			(V4L2_CID_BASE+19)
+#define V4L2_CID_HFLIP			(V4L2_CID_BASE+20)
+#define V4L2_CID_VFLIP			(V4L2_CID_BASE+21)
+#define V4L2_CID_HCENTER		(V4L2_CID_BASE+22)
+#define V4L2_CID_VCENTER		(V4L2_CID_BASE+23)
+#define V4L2_CID_LASTP1			(V4L2_CID_BASE+24) /* last CID + 1 */
+
+/*
+ *	T U N I N G
+ */
+struct v4l2_tuner
+{
+	__u32                   index;
+	__u8			name[32];
+	enum v4l2_tuner_type    type;
+	__u32			capability;
+	__u32			rangelow;
+	__u32			rangehigh;
+	__u32			rxsubchans;
+	__u32			audmode;
+	__s32			signal;
+	__s32			afc;
+	__u32			reserved[4];
+};
+
+struct v4l2_modulator
+{
+	__u32			index;
+	__u8			name[32];
+	__u32			capability;
+	__u32			rangelow;
+	__u32			rangehigh;
+	__u32			txsubchans;
+	__u32			reserved[4];
+};
+
+/*  Flags for the 'capability' field */
+#define V4L2_TUNER_CAP_LOW		0x0001
+#define V4L2_TUNER_CAP_NORM		0x0002
+#define V4L2_TUNER_CAP_STEREO		0x0010
+#define V4L2_TUNER_CAP_LANG2		0x0020
+#define V4L2_TUNER_CAP_SAP		0x0020
+#define V4L2_TUNER_CAP_LANG1		0x0040
+
+/*  Flags for the 'rxsubchans' field */
+#define V4L2_TUNER_SUB_MONO		0x0001
+#define V4L2_TUNER_SUB_STEREO		0x0002
+#define V4L2_TUNER_SUB_LANG2		0x0004
+#define V4L2_TUNER_SUB_SAP		0x0004
+#define V4L2_TUNER_SUB_LANG1		0x0008
+
+/*  Values for the 'audmode' field */
+#define V4L2_TUNER_MODE_MONO		0x0000
+#define V4L2_TUNER_MODE_STEREO		0x0001
+#define V4L2_TUNER_MODE_LANG2		0x0002
+#define V4L2_TUNER_MODE_SAP		0x0002
+#define V4L2_TUNER_MODE_LANG1		0x0003
+
+struct v4l2_frequency
+{
+	__u32	              tuner;
+	enum v4l2_tuner_type  type;
+        __u32	              frequency;
+	__u32	              reserved[8];
+};
+
+/*
+ *	A U D I O
+ */
+struct v4l2_audio
+{
+	__u32	index;
+	__u8	name[32];
+	__u32	capability;
+	__u32	mode;
+	__u32	reserved[2];
+};
+/*  Flags for the 'capability' field */
+#define V4L2_AUDCAP_STEREO		0x00001
+#define V4L2_AUDCAP_AVL			0x00002
+
+/*  Flags for the 'mode' field */
+#define V4L2_AUDMODE_AVL		0x00001
+
+struct v4l2_audioout
+{
+	__u32	index;
+	__u8	name[32];
+	__u32	capability;
+	__u32	mode;
+	__u32	reserved[2];
+};
+
+/*
+ *	D A T A   S E R V I C E S   ( V B I )
+ *
+ *	Data services API by Michael Schimek
+ */
+
+struct v4l2_vbi_format
+{
+	__u32	sampling_rate;		/* in 1 Hz */
+	__u32	offset;
+	__u32	samples_per_line;
+	__u32	sample_format;		/* V4L2_PIX_FMT_* */
+	__s32	start[2];
+	__u32	count[2];
+	__u32	flags;			/* V4L2_VBI_* */
+	__u32	reserved[2];		/* must be zero */
+};
+
+/*  VBI flags  */
+#define V4L2_VBI_UNSYNC		(1<< 0)
+#define V4L2_VBI_INTERLACED	(1<< 1)
+
+
+/*
+ *	A G G R E G A T E   S T R U C T U R E S
+ */
+
+/*	Stream data format
+ */
+struct v4l2_format
+{
+	enum v4l2_buf_type type;
+	union
+	{
+		struct v4l2_pix_format	pix;  // V4L2_BUF_TYPE_VIDEO_CAPTURE
+		struct v4l2_window	win;  // V4L2_BUF_TYPE_VIDEO_OVERLAY
+		struct v4l2_vbi_format	vbi;  // V4L2_BUF_TYPE_VBI_CAPTURE
+		__u8	raw_data[200];        // user-defined
+	} fmt;
+};
+
+
+/*	Stream type-dependent parameters
+ */
+struct v4l2_streamparm
+{
+	enum v4l2_buf_type type;
+	union
+	{
+		struct v4l2_captureparm	capture;
+		struct v4l2_outputparm	output;
+		__u8	raw_data[200];  /* user-defined */
+	} parm;
+};
+
+
+
+/*
+ *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
+ *
+ */
+#define VIDIOC_QUERYCAP		_IOR  ('V',  0, struct v4l2_capability)
+#define VIDIOC_RESERVED		_IO   ('V',  1)
+#define VIDIOC_ENUM_FMT         _IOWR ('V',  2, struct v4l2_fmtdesc)
+#define VIDIOC_G_FMT		_IOWR ('V',  4, struct v4l2_format)
+#define VIDIOC_S_FMT		_IOWR ('V',  5, struct v4l2_format)
+#if 0
+#define VIDIOC_G_COMP		_IOR  ('V',  6, struct v4l2_compression)
+#define VIDIOC_S_COMP		_IOW  ('V',  7, struct v4l2_compression)
+#endif
+#define VIDIOC_REQBUFS		_IOWR ('V',  8, struct v4l2_requestbuffers)
+#define VIDIOC_QUERYBUF		_IOWR ('V',  9, struct v4l2_buffer)
+#define VIDIOC_G_FBUF		_IOR  ('V', 10, struct v4l2_framebuffer)
+#define VIDIOC_S_FBUF		_IOW  ('V', 11, struct v4l2_framebuffer)
+#define VIDIOC_OVERLAY		_IOWR ('V', 14, int)
+#define VIDIOC_QBUF		_IOWR ('V', 15, struct v4l2_buffer)
+#define VIDIOC_DQBUF		_IOWR ('V', 17, struct v4l2_buffer)
+#define VIDIOC_STREAMON		_IOW  ('V', 18, int)
+#define VIDIOC_STREAMOFF	_IOW  ('V', 19, int)
+#define VIDIOC_G_PARM		_IOWR ('V', 21, struct v4l2_streamparm)
+#define VIDIOC_S_PARM		_IOW  ('V', 22, struct v4l2_streamparm)
+#define VIDIOC_G_STD		_IOR  ('V', 23, v4l2_std_id)
+#define VIDIOC_S_STD		_IOW  ('V', 24, v4l2_std_id)
+#define VIDIOC_ENUMSTD		_IOWR ('V', 25, struct v4l2_standard)
+#define VIDIOC_ENUMINPUT	_IOWR ('V', 26, struct v4l2_input)
+#define VIDIOC_G_CTRL		_IOWR ('V', 27, struct v4l2_control)
+#define VIDIOC_S_CTRL		_IOW  ('V', 28, struct v4l2_control)
+#define VIDIOC_G_TUNER		_IOWR ('V', 29, struct v4l2_tuner)
+#define VIDIOC_S_TUNER		_IOW  ('V', 30, struct v4l2_tuner)
+#define VIDIOC_G_AUDIO		_IOWR ('V', 33, struct v4l2_audio)
+#define VIDIOC_S_AUDIO		_IOW  ('V', 34, struct v4l2_audio)
+#define VIDIOC_QUERYCTRL	_IOWR ('V', 36, struct v4l2_queryctrl)
+#define VIDIOC_QUERYMENU	_IOWR ('V', 37, struct v4l2_querymenu)
+#define VIDIOC_G_INPUT		_IOR  ('V', 38, int)
+#define VIDIOC_S_INPUT		_IOWR ('V', 39, int)
+#define VIDIOC_G_OUTPUT		_IOR  ('V', 46, int)
+#define VIDIOC_S_OUTPUT		_IOWR ('V', 47, int)
+#define VIDIOC_ENUMOUTPUT	_IOWR ('V', 48, struct v4l2_output)
+#define VIDIOC_G_AUDOUT		_IOWR ('V', 49, struct v4l2_audioout)
+#define VIDIOC_S_AUDOUT		_IOW  ('V', 50, struct v4l2_audioout)
+#define VIDIOC_G_MODULATOR	_IOWR ('V', 54, struct v4l2_modulator)
+#define VIDIOC_S_MODULATOR	_IOW  ('V', 55, struct v4l2_modulator)
+#define VIDIOC_G_FREQUENCY	_IOWR ('V', 56, struct v4l2_frequency)
+#define VIDIOC_S_FREQUENCY	_IOW  ('V', 57, struct v4l2_frequency)
+#define VIDIOC_CROPCAP		_IOR  ('V', 58, struct v4l2_cropcap)
+#define VIDIOC_G_CROP		_IOWR ('V', 59, struct v4l2_crop)
+#define VIDIOC_S_CROP		_IOW  ('V', 60, struct v4l2_crop)
+#define VIDIOC_G_JPEGCOMP	_IOR  ('V', 61, struct v4l2_jpegcompression)
+#define VIDIOC_S_JPEGCOMP	_IOW  ('V', 62, struct v4l2_jpegcompression)
+#define VIDIOC_QUERYSTD      	_IOR  ('V', 63, v4l2_std_id)
+#define VIDIOC_TRY_FMT      	_IOWR ('V', 63, struct v4l2_format)
+
+#define BASE_VIDIOC_PRIVATE	192		/* 192-255 are private */
+
+
+#ifdef __KERNEL__
+/*
+ *
+ *	V 4 L 2   D R I V E R   H E L P E R   A P I
+ *
+ *	Some commonly needed functions for drivers (v4l2-common.o module)
+ */
+#include <linux/fs.h>
+
+/*  Video standard functions  */
+extern unsigned int v4l2_video_std_fps(struct v4l2_standard *vs);
+extern int v4l2_video_std_construct(struct v4l2_standard *vs,
+				    int id, char *name);
+
+/*  Compatibility layer interface  */
+typedef int (*v4l2_kioctl)(struct inode *inode, struct file *file,
+			   unsigned int cmd, void *arg);
+int v4l_compat_translate_ioctl(struct inode *inode, struct file *file,
+			       int cmd, void *arg, v4l2_kioctl driver_ioctl);
+
+/* names for fancy debug output */
+extern char *v4l2_field_names[];
+extern char *v4l2_type_names[];
+extern char *v4l2_ioctl_names[];
+
+#endif /* __KERNEL__ */
+#endif /* __LINUX_VIDEODEV2_H */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff -Nru a/include/linux/xattr_acl.h b/include/linux/xattr_acl.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/xattr_acl.h	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,50 @@
+/*
+  File: linux/xattr_acl.h
+
+  (extended attribute representation of access control lists)
+
+  (C) 2000 Andreas Gruenbacher, <a.gruenbacher@computer.org>
+*/
+
+#ifndef _LINUX_XATTR_ACL_H
+#define _LINUX_XATTR_ACL_H
+
+#include <linux/posix_acl.h>
+
+#define XATTR_NAME_ACL_ACCESS	"system.posix_acl_access"
+#define XATTR_NAME_ACL_DEFAULT	"system.posix_acl_default"
+
+#define XATTR_ACL_VERSION	0x0002
+
+typedef struct {
+	__u16		e_tag;
+	__u16		e_perm;
+	__u32		e_id;
+} xattr_acl_entry;
+
+typedef struct {
+	__u32		a_version;
+	xattr_acl_entry	a_entries[0];
+} xattr_acl_header;
+
+static inline size_t xattr_acl_size(int count)
+{
+	return sizeof(xattr_acl_header) + count * sizeof(xattr_acl_entry);
+}
+
+static inline int xattr_acl_count(size_t size)
+{
+	if (size < sizeof(xattr_acl_header))
+		return -1;
+	size -= sizeof(xattr_acl_header);
+	if (size % sizeof(xattr_acl_entry))
+		return -1;
+	return size / sizeof(xattr_acl_entry);
+}
+
+struct posix_acl * posix_acl_from_xattr(const void *value, size_t size);
+int posix_acl_to_xattr(const struct posix_acl *acl, void *buffer, size_t size);
+
+
+
+#endif /* _LINUX_XATTR_ACL_H */
diff -Nru a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
--- a/include/net/bluetooth/bluetooth.h	Mon Nov  4 14:31:01 2002
+++ b/include/net/bluetooth/bluetooth.h	Mon Nov  4 14:31:01 2002
@@ -53,7 +53,7 @@
 #define SOL_SCO     17
 #define SOL_RFCOMM  18
 
-#define BT_INFO(fmt, arg...) printk(KERN_INFO fmt "\n" , ## arg)
+#define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg)
 #define BT_DBG(fmt, arg...)  printk(KERN_INFO "%s: " fmt "\n" , __FUNCTION__ , ## arg)
 #define BT_ERR(fmt, arg...)  printk(KERN_ERR  "%s: " fmt "\n" , __FUNCTION__ , ## arg)
 
@@ -62,6 +62,8 @@
 #else
 #define BT_DMP(D...)
 #endif
+
+extern struct proc_dir_entry *proc_bt;
 
 /* Connection and socket states */
 enum {
diff -Nru a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
--- a/include/net/bluetooth/hci_core.h	Mon Nov  4 14:31:02 2002
+++ b/include/net/bluetooth/hci_core.h	Mon Nov  4 14:31:02 2002
@@ -29,6 +29,7 @@
 #ifndef __HCI_CORE_H
 #define __HCI_CORE_H
 
+#include <linux/proc_fs.h>
 #include <net/bluetooth/hci.h>
 
 /* HCI upper protocols */
@@ -37,6 +38,8 @@
 
 #define HCI_INIT_TIMEOUT (HZ * 10)
 
+extern struct proc_dir_entry *proc_bt_hci;
+
 /* HCI Core structures */
 
 struct inquiry_entry {
@@ -111,6 +114,10 @@
 
 	atomic_t 		promisc;
 
+#ifdef CONFIG_PROC_FS
+	struct proc_dir_entry   *proc;
+#endif
+
 	int (*open)(struct hci_dev *hdev);
 	int (*close)(struct hci_dev *hdev);
 	int (*flush)(struct hci_dev *hdev);
@@ -148,8 +155,8 @@
 };
 
 extern struct hci_proto *hci_proto[];
-extern struct list_head hdev_list;
-extern rwlock_t hdev_list_lock;
+extern struct list_head hci_dev_list;
+extern rwlock_t hci_dev_list_lock;
 
 /* ----- Inquiry cache ----- */
 #define INQUIRY_CACHE_AGE_MAX   (HZ*30)   // 30 seconds
@@ -344,6 +351,9 @@
 	hci_sched_rx(hdev);
 	return 0;
 }
+
+int  hci_dev_proc_init(struct hci_dev *hdev);
+void hci_dev_proc_cleanup(struct hci_dev *hdev);
 
 /* ----- LMP capabilities ----- */
 #define lmp_rswitch_capable(dev) (dev->features[0] & LMP_RSWITCH)
diff -Nru a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
--- a/include/net/bluetooth/rfcomm.h	Mon Nov  4 14:31:01 2002
+++ b/include/net/bluetooth/rfcomm.h	Mon Nov  4 14:31:01 2002
@@ -345,4 +345,6 @@
 int  rfcomm_init_ttys(void);
 void rfcomm_cleanup_ttys(void);
 
+extern struct proc_dir_entry *proc_bt_rfcomm;
+
 #endif /* __RFCOMM_H */
diff -Nru a/include/net/sock.h b/include/net/sock.h
--- a/include/net/sock.h	Mon Nov  4 14:31:02 2002
+++ b/include/net/sock.h	Mon Nov  4 14:31:02 2002
@@ -52,9 +52,6 @@
 #include <asm/atomic.h>
 #include <net/dst.h>
 #include <net/scm.h>
-#include <linux/fs.h>
-#include <linux/file.h>
-#include <linux/fcblist.h>
 
 /*
  * This structure really needs to be cleaned up.
@@ -769,13 +766,8 @@
 
 static inline void sk_wake_async(struct sock *sk, int how, int band)
 {
-	if (sk->socket) {
-		if (sk->socket->file)
-			file_send_notify(sk->socket->file, ion_band_table[band - POLL_IN],
-					 poll_band_table[band - POLL_IN]);
-		if (sk->socket->fasync_list)
-			sock_wake_async(sk->socket, how, band);
-	}
+	if (sk->socket && sk->socket->fasync_list)
+		sock_wake_async(sk->socket, how, band);
 }
 
 #define SOCK_MIN_SNDBUF 2048
diff -Nru a/include/rxrpc/call.h b/include/rxrpc/call.h
--- a/include/rxrpc/call.h	Mon Nov  4 14:31:01 2002
+++ b/include/rxrpc/call.h	Mon Nov  4 14:31:01 2002
@@ -153,7 +153,7 @@
 	(CALL)->app_scr_alloc += (SIZE);						\
 	if ((SIZE)>RXRPC_CALL_SCRATCH_SIZE ||						\
 	    (size_t)((CALL)->app_scr_alloc - (u8*)(CALL)) > RXRPC_CALL_SCRATCH_SIZE) {	\
-		printk("rxrpc_call_alloc_scratch(%p,%u)\n",(CALL),(SIZE));		\
+		printk("rxrpc_call_alloc_scratch(%p,%Zu)\n",(CALL),(size_t)(SIZE));	\
 		BUG();									\
 	}										\
 	ptr;										\
@@ -167,7 +167,7 @@
 	(CALL)->app_scr_alloc += size;							\
 	if (size>RXRPC_CALL_SCRATCH_SIZE ||						\
 	    (size_t)((CALL)->app_scr_alloc - (u8*)(CALL)) > RXRPC_CALL_SCRATCH_SIZE) {	\
-		printk("rxrpc_call_alloc_scratch(%p,%u)\n",(CALL),size);		\
+		printk("rxrpc_call_alloc_scratch(%p,%Zu)\n",(CALL),size);		\
 		BUG();									\
 	}										\
 	ptr;										\
diff -Nru a/include/rxrpc/peer.h b/include/rxrpc/peer.h
--- a/include/rxrpc/peer.h	Mon Nov  4 14:31:02 2002
+++ b/include/rxrpc/peer.h	Mon Nov  4 14:31:02 2002
@@ -57,8 +57,8 @@
 	/* calculated RTT cache */
 #define RXRPC_RTT_CACHE_SIZE 32
 	suseconds_t		rtt;		/* current RTT estimate (in uS) */
-	unsigned short		rtt_point;	/* next entry at which to insert */
-	unsigned short		rtt_usage;	/* amount of cache actually used */
+	unsigned		rtt_point;	/* next entry at which to insert */
+	unsigned		rtt_usage;	/* amount of cache actually used */
 	suseconds_t		rtt_cache[RXRPC_RTT_CACHE_SIZE]; /* calculated RTT cache */
 };
 
diff -Nru a/include/scsi/scsi.h b/include/scsi/scsi.h
--- a/include/scsi/scsi.h	Mon Nov  4 14:31:03 2002
+++ b/include/scsi/scsi.h	Mon Nov  4 14:31:03 2002
@@ -15,6 +15,13 @@
 */
 
 /*
+ * SCSI command lengths
+ */
+
+extern const unsigned char scsi_command_size[8];
+#define COMMAND_SIZE(opcode) scsi_command_size[((opcode) >> 5) & 7]
+
+/*
  *      SCSI opcodes
  */
 
diff -Nru a/init/Makefile b/init/Makefile
--- a/init/Makefile	Mon Nov  4 14:31:01 2002
+++ b/init/Makefile	Mon Nov  4 14:31:01 2002
@@ -2,7 +2,7 @@
 # Makefile for the linux kernel.
 #
 
-obj-y    := main.o version.o do_mounts.o
+obj-y    := main.o version.o do_mounts.o initramfs.o
 
 # files to be removed upon make clean
 clean-files := ../include/linux/compile.h
diff -Nru a/init/do_mounts.c b/init/do_mounts.c
--- a/init/do_mounts.c	Mon Nov  4 14:31:01 2002
+++ b/init/do_mounts.c	Mon Nov  4 14:31:01 2002
@@ -101,7 +101,7 @@
 
 	/* read device number from .../dev */
 
-	sprintf(path, "/sys/bus/block/devices/%s/dev", name);
+	sprintf(path, "/sys/block/%s/dev", name);
 	fd = open(path, 0, 0);
 	if (fd < 0)
 		goto fail;
@@ -119,7 +119,7 @@
 		return res;
 
 	/* otherwise read range from .../range */
-	sprintf(path, "/sys/bus/block/devices/%s/range", name);
+	sprintf(path, "/sys/block/%s/range", name);
 	fd = open(path, 0, 0);
 	if (fd < 0)
 		goto fail;
@@ -166,7 +166,7 @@
 	int part;
 
 	sys_mkdir("/sys", 0700);
-	if (sys_mount("driverfs", "/sys", "driverfs", 0, NULL) < 0)
+	if (sys_mount("sysfs", "/sys", "sysfs", 0, NULL) < 0)
 		goto out;
 
 	if (strncmp(name, "/dev/", 5) != 0) {
@@ -748,9 +748,7 @@
 		mount_initrd = 0;
 	real_root_dev = ROOT_DEV;
 #endif
-	sys_mkdir("/dev", 0700);
-	sys_mkdir("/root", 0700);
-	sys_mknod("/dev/console", S_IFCHR|0600, MKDEV(TTYAUX_MAJOR, 1));
+
 #ifdef CONFIG_DEVFS_FS
 	sys_mount("devfs", "/dev", "devfs", 0, NULL);
 	do_devfs = 1;
diff -Nru a/init/initramfs.c b/init/initramfs.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/init/initramfs.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,462 @@
+#define __KERNEL_SYSCALLS__
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/unistd.h>
+#include <linux/delay.h>
+
+static void __init error(char *x)
+{
+	panic("populate_root: %s\n", x);
+}
+
+static void __init *malloc(int size)
+{
+	return kmalloc(size, GFP_KERNEL);
+}
+
+static void __init free(void *where)
+{
+	kfree(where);
+}
+
+asmlinkage long sys_mkdir(char *name, int mode);
+asmlinkage long sys_mknod(char *name, int mode, dev_t dev);
+asmlinkage long sys_symlink(char *old, char *new);
+asmlinkage long sys_link(char *old, char *new);
+asmlinkage long sys_write(int fd, const char *buf, size_t size);
+asmlinkage long sys_chown(char *name, uid_t uid, gid_t gid);
+asmlinkage long sys_lchown(char *name, uid_t uid, gid_t gid);
+asmlinkage long sys_fchown(int fd, uid_t uid, gid_t gid);
+asmlinkage long sys_chmod(char *name, mode_t mode);
+asmlinkage long sys_fchmod(int fd, mode_t mode);
+
+/* link hash */
+
+static struct hash {
+	int ino, minor, major;
+	struct hash *next;
+	char *name;
+} *head[32];
+
+static inline int hash(int major, int minor, int ino)
+{
+	unsigned long tmp = ino + minor + (major << 3);
+	tmp += tmp >> 5;
+	return tmp & 31;
+}
+
+static char __init *find_link(int major, int minor, int ino, char *name)
+{
+	struct hash **p, *q;
+	for (p = head + hash(major, minor, ino); *p; p = &(*p)->next) {
+		if ((*p)->ino != ino)
+			continue;
+		if ((*p)->minor != minor)
+			continue;
+		if ((*p)->major != major)
+			continue;
+		return (*p)->name;
+	}
+	q = (struct hash *)malloc(sizeof(struct hash));
+	if (!q)
+		error("can't allocate link hash entry");
+	q->ino = ino;
+	q->minor = minor;
+	q->major = major;
+	q->name = name;
+	q->next = NULL;
+	*p = q;
+	return NULL;
+}
+
+static void __init free_hash(void)
+{
+	struct hash **p, *q;
+	for (p = head; p < head + 32; p++) {
+		while (*p) {
+			q = *p;
+			*p = q->next;
+			free(q);
+		}
+	}
+}
+
+/* cpio header parsing */
+
+static __initdata unsigned long ino, major, minor, nlink;
+static __initdata mode_t mode;
+static __initdata unsigned long body_len, name_len;
+static __initdata uid_t uid;
+static __initdata gid_t gid;
+static __initdata dev_t rdev;
+
+static void __init parse_header(char *s)
+{
+	unsigned long parsed[12];
+	char buf[9];
+	int i;
+
+	buf[8] = '\0';
+	for (i = 0, s += 6; i < 12; i++, s += 8) {
+		memcpy(buf, s, 8);
+		parsed[i] = simple_strtoul(buf, NULL, 16);
+	}
+	ino = parsed[0];
+	mode = parsed[1];
+	uid = parsed[2];
+	gid = parsed[3];
+	nlink = parsed[4];
+	body_len = parsed[6];
+	major = parsed[7];
+	minor = parsed[8];
+	rdev = MKDEV(parsed[9], parsed[10]);
+	name_len = parsed[11];
+}
+
+/* FSM */
+
+enum state {
+	Start,
+	Collect,
+	GotHeader,
+	SkipIt,
+	GotName,
+	CopyFile,
+	GotSymlink,
+	Reset
+} state, next_state;
+
+char *victim;
+unsigned count;
+loff_t this_header, next_header;
+
+static inline void eat(unsigned n)
+{
+	victim += n;
+	this_header += n;
+	count -= n;
+}
+
+#define N_ALIGN(len) ((((len) + 1) & ~3) + 2)
+
+static __initdata char *collected;
+static __initdata int remains;
+static __initdata char *collect;
+
+static void __init read_into(char *buf, unsigned size, enum state next)
+{
+	if (count >= size) {
+		collected = victim;
+		eat(size);
+		state = next;
+	} else {
+		collect = collected = buf;
+		remains = size;
+		next_state = next;
+		state = Collect;
+	}
+}
+
+static __initdata char *header_buf, *symlink_buf, *name_buf;
+
+static int __init do_start(void)
+{
+	read_into(header_buf, 110, GotHeader);
+	return 0;
+}
+
+static int __init do_collect(void)
+{
+	unsigned n = remains;
+	if (count < n)
+		n = count;
+	memcpy(collect, victim, n);
+	eat(n);
+	collect += n;
+	if (remains -= n)
+		return 1;
+	state = next_state;
+	return 0;
+}
+
+static int __init do_header(void)
+{
+	parse_header(collected);
+	next_header = this_header + N_ALIGN(name_len) + body_len;
+	next_header = (next_header + 3) & ~3;
+	if (name_len <= 0 || name_len > PATH_MAX)
+		state = SkipIt;
+	else if (S_ISLNK(mode)) {
+		if (body_len > PATH_MAX)
+			state = SkipIt;
+		else {
+			collect = collected = symlink_buf;
+			remains = N_ALIGN(name_len) + body_len;
+			next_state = GotSymlink;
+			state = Collect;
+		}
+	} else if (body_len && !S_ISREG(mode))
+		state = SkipIt;
+	else
+		read_into(name_buf, N_ALIGN(name_len), GotName);
+	return 0;
+}
+
+static int __init do_skip(void)
+{
+	if (this_header + count <= next_header) {
+		eat(count);
+		return 1;
+	} else {
+		eat(next_header - this_header);
+		state = next_state;
+		return 0;
+	}
+}
+
+static int __init do_reset(void)
+{
+	while(count && *victim == '\0')
+		eat(1);
+	if (count && (this_header & 3))
+		error("broken padding");
+	return 1;
+}
+
+static int __init maybe_link(void)
+{
+	if (nlink >= 2) {
+		char *old = find_link(major, minor, ino, collected);
+		if (old)
+			return (sys_link(old, collected) < 0) ? -1 : 1;
+	}
+	return 0;
+}
+
+static __initdata int wfd;
+
+static int __init do_name(void)
+{
+	state = SkipIt;
+	next_state = Start;
+	if (strcmp(collected, "TRAILER!!!") == 0) {
+		free_hash();
+		next_state = Reset;
+		return 0;
+	}
+	printk(KERN_INFO "-> %s\n", collected);
+	if (S_ISREG(mode)) {
+		if (maybe_link() >= 0) {
+			wfd = sys_open(collected, O_WRONLY|O_CREAT, mode);
+			if (wfd >= 0) {
+				sys_fchown(wfd, uid, gid);
+				sys_fchmod(wfd, mode);
+				state = CopyFile;
+			}
+		}
+	} else if (S_ISDIR(mode)) {
+		sys_mkdir(collected, mode);
+		sys_chown(collected, uid, gid);
+	} else if (S_ISBLK(mode) || S_ISCHR(mode) ||
+		   S_ISFIFO(mode) || S_ISSOCK(mode)) {
+		if (maybe_link() == 0) {
+			sys_mknod(collected, mode, rdev);
+			sys_chown(collected, uid, gid);
+		}
+	} else
+		panic("populate_root: bogus mode: %o\n", mode);
+	return 0;
+}
+
+static int __init do_copy(void)
+{
+	if (count >= body_len) {
+		sys_write(wfd, victim, body_len);
+		sys_close(wfd);
+		eat(body_len);
+		state = SkipIt;
+		return 0;
+	} else {
+		sys_write(wfd, victim, count);
+		body_len -= count;
+		eat(count);
+		return 1;
+	}
+}
+
+static int __init do_symlink(void)
+{
+	collected[N_ALIGN(name_len) + body_len] = '\0';
+	sys_symlink(collected + N_ALIGN(name_len), collected);
+	sys_lchown(collected, uid, gid);
+	state = SkipIt;
+	next_state = Start;
+	return 0;
+}
+
+static __initdata int (*actions[])(void) = {
+	[Start]		do_start,
+	[Collect]	do_collect,
+	[GotHeader]	do_header,
+	[SkipIt]	do_skip,
+	[GotName]	do_name,
+	[CopyFile]	do_copy,
+	[GotSymlink]	do_symlink,
+	[Reset]		do_reset,
+};
+
+static int __init write_buffer(char *buf, unsigned len)
+{
+	count = len;
+	victim = buf;
+
+	while (!actions[state]())
+		;
+	return len - count;
+}
+
+static void __init flush_buffer(char *buf, unsigned len)
+{
+	int written;
+	while ((written = write_buffer(buf, len)) < len) {
+		char c = buf[written];
+		if (c == '0') {
+			buf += written;
+			len -= written;
+			state = Start;
+			continue;
+		} else
+			error("junk in compressed archive");
+	}
+}
+
+/*
+ * gzip declarations
+ */
+
+#define OF(args)  args
+
+#ifndef memzero
+#define memzero(s, n)     memset ((s), 0, (n))
+#endif
+
+typedef unsigned char  uch;
+typedef unsigned short ush;
+typedef unsigned long  ulg;
+
+#define WSIZE 0x8000    /* window size--must be a power of two, and */
+			/*  at least 32K for zip's deflate method */
+
+static uch *inbuf;
+static uch *window;
+
+static unsigned insize;  /* valid bytes in inbuf */
+static unsigned inptr;   /* index of next byte to be processed in inbuf */
+static unsigned outcnt;  /* bytes in output buffer */
+static long bytes_out;
+
+#define get_byte()  (inptr < insize ? inbuf[inptr++] : -1)
+		
+/* Diagnostic functions (stubbed out) */
+#define Assert(cond,msg)
+#define Trace(x)
+#define Tracev(x)
+#define Tracevv(x)
+#define Tracec(c,x)
+#define Tracecv(c,x)
+
+#define STATIC static
+
+static void flush_window(void);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+#include "../lib/inflate.c"
+
+static void __init gzip_mark(void **ptr)
+{
+}
+
+static void __init gzip_release(void **ptr)
+{
+}
+
+/* ===========================================================================
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+static void __init flush_window(void)
+{
+	ulg c = crc;         /* temporary variable */
+	unsigned n;
+	uch *in, ch;
+
+	flush_buffer(window, outcnt);
+	in = window;
+	for (n = 0; n < outcnt; n++) {
+		ch = *in++;
+		c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+	}
+	crc = c;
+	bytes_out += (ulg)outcnt;
+	outcnt = 0;
+}
+
+static void __init unpack_to_rootfs(char *buf, unsigned len)
+{
+	int written;
+	header_buf = malloc(110);
+	symlink_buf = malloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1);
+	name_buf = malloc(N_ALIGN(PATH_MAX));
+	window = malloc(WSIZE);
+	if (!window || !header_buf || !symlink_buf || !name_buf)
+		error("can't allocate buffers");
+	state = Start;
+	this_header = 0;
+	while (len) {
+		loff_t saved_offset = this_header;
+		if (*buf == '0' && !(this_header & 3)) {
+			state = Start;
+			written = write_buffer(buf, len);
+			buf += written;
+			len -= written;
+			continue;
+		} else if (!*buf) {
+			buf++;
+			len--;
+			this_header++;
+			continue;
+		}
+		this_header = 0;
+		insize = len;
+		inbuf = buf;
+		inptr = 0;
+		outcnt = 0;		/* bytes in output buffer */
+		bytes_out = 0;
+		crc = (ulg)0xffffffffL; /* shift register contents */
+		makecrc();
+		if (gunzip())
+			error("ungzip failed");
+		if (state != Reset)
+			error("junk in gzipped archive");
+		this_header = saved_offset + inptr;
+		buf += inptr;
+		len -= inptr;
+	}
+	free(window);
+	free(name_buf);
+	free(symlink_buf);
+	free(header_buf);
+}
+
+extern char __initramfs_start, __initramfs_end;
+
+void __init populate_rootfs(void)
+{
+	unpack_to_rootfs(&__initramfs_start,
+			 &__initramfs_end - &__initramfs_start);
+}
diff -Nru a/init/main.c b/init/main.c
--- a/init/main.c	Mon Nov  4 14:31:01 2002
+++ b/init/main.c	Mon Nov  4 14:31:01 2002
@@ -72,6 +72,7 @@
 extern void pte_chain_init(void);
 extern void radix_tree_init(void);
 extern void free_initmem(void);
+extern void populate_rootfs(void);
 
 #ifdef CONFIG_TC
 extern void tc_init(void);
@@ -101,7 +102,7 @@
 char *execute_command;
 
 /* Setup configured maximum number of CPUs to activate */
-static unsigned int max_cpus = UINT_MAX;
+static unsigned int max_cpus = NR_CPUS;
 
 /*
  * Setup routine for controlling SMP activation
@@ -433,6 +434,7 @@
 	vfs_caches_init(num_physpages);
 	radix_tree_init();
 	signals_init();
+	populate_rootfs();
 #ifdef CONFIG_PROC_FS
 	proc_root_init();
 #endif
diff -Nru a/ipc/msg.c b/ipc/msg.c
--- a/ipc/msg.c	Mon Nov  4 14:31:00 2002
+++ b/ipc/msg.c	Mon Nov  4 14:31:00 2002
@@ -65,7 +65,7 @@
 static struct ipc_ids msg_ids;
 
 #define msg_lock(id)	((struct msg_queue*)ipc_lock(&msg_ids,id))
-#define msg_unlock(id)	ipc_unlock(&msg_ids,id)
+#define msg_unlock(msq)	ipc_unlock(&(msq)->q_perm)
 #define msg_rmid(id)	((struct msg_queue*)ipc_rmid(&msg_ids,id))
 #define msg_checkid(msq, msgid)	\
 	ipc_checkid(&msg_ids,&msq->q_perm,msgid)
@@ -93,7 +93,7 @@
 	int retval;
 	struct msg_queue *msq;
 
-	msq  = (struct msg_queue *) kmalloc (sizeof (*msq), GFP_KERNEL);
+	msq  = ipc_rcu_alloc(sizeof(*msq));
 	if (!msq) 
 		return -ENOMEM;
 
@@ -103,14 +103,14 @@
 	msq->q_perm.security = NULL;
 	retval = security_ops->msg_queue_alloc_security(msq);
 	if (retval) {
-		kfree(msq);
+		ipc_rcu_free(msq, sizeof(*msq));
 		return retval;
 	}
 
 	id = ipc_addid(&msg_ids, &msq->q_perm, msg_ctlmni);
 	if(id == -1) {
 		security_ops->msg_queue_free_security(msq);
-		kfree(msq);
+		ipc_rcu_free(msq, sizeof(*msq));
 		return -ENOSPC;
 	}
 
@@ -122,7 +122,7 @@
 	INIT_LIST_HEAD(&msq->q_messages);
 	INIT_LIST_HEAD(&msq->q_receivers);
 	INIT_LIST_HEAD(&msq->q_senders);
-	msg_unlock(id);
+	msg_unlock(msq);
 
 	return msg_buildid(id,msq->q_perm.seq);
 }
@@ -271,7 +271,7 @@
 
 	expunge_all(msq,-EIDRM);
 	ss_wakeup(&msq->q_senders,1);
-	msg_unlock(id);
+	msg_unlock(msq);
 		
 	tmp = msq->q_messages.next;
 	while(tmp != &msq->q_messages) {
@@ -282,7 +282,7 @@
 	}
 	atomic_sub(msq->q_cbytes, &msg_bytes);
 	security_ops->msg_queue_free_security(msq);
-	kfree(msq);
+	ipc_rcu_free(msq, sizeof(struct msg_queue));
 }
 
 asmlinkage long sys_msgget (key_t key, int msgflg)
@@ -308,7 +308,7 @@
 			ret = -EACCES;
 		else
 			ret = msg_buildid(id, msq->q_perm.seq);
-		msg_unlock(id);
+		msg_unlock(msq);
 	}
 	up(&msg_ids.sem);
 	return ret;
@@ -488,7 +488,7 @@
 		tbuf.msg_qbytes = msq->q_qbytes;
 		tbuf.msg_lspid  = msq->q_lspid;
 		tbuf.msg_lrpid  = msq->q_lrpid;
-		msg_unlock(msqid);
+		msg_unlock(msq);
 		if (copy_msqid_to_user(buf, &tbuf, version))
 			return -EFAULT;
 		return success_return;
@@ -541,7 +541,7 @@
 		 * due to a larger queue size.
 		 */
 		ss_wakeup(&msq->q_senders,0);
-		msg_unlock(msqid);
+		msg_unlock(msq);
 		break;
 	}
 	case IPC_RMID:
@@ -553,10 +553,10 @@
 	up(&msg_ids.sem);
 	return err;
 out_unlock_up:
-	msg_unlock(msqid);
+	msg_unlock(msq);
 	goto out_up;
 out_unlock:
-	msg_unlock(msqid);
+	msg_unlock(msq);
 	return err;
 }
 
@@ -651,7 +651,7 @@
 			goto out_unlock_free;
 		}
 		ss_add(msq, &s);
-		msg_unlock(msqid);
+		msg_unlock(msq);
 		schedule();
 		current->state= TASK_RUNNING;
 
@@ -684,7 +684,7 @@
 	msg = NULL;
 
 out_unlock_free:
-	msg_unlock(msqid);
+	msg_unlock(msq);
 out_free:
 	if(msg!=NULL)
 		free_msg(msg);
@@ -766,7 +766,7 @@
 		atomic_sub(msg->m_ts,&msg_bytes);
 		atomic_dec(&msg_hdrs);
 		ss_wakeup(&msq->q_senders,0);
-		msg_unlock(msqid);
+		msg_unlock(msq);
 out_success:
 		msgsz = (msgsz > msg->m_ts) ? msg->m_ts : msgsz;
 		if (put_user (msg->m_type, &msgp->mtype) ||
@@ -777,7 +777,6 @@
 		return msgsz;
 	} else
 	{
-		struct msg_queue *t;
 		/* no message waiting. Prepare for pipelined
 		 * receive.
 		 */
@@ -795,7 +794,7 @@
 		 	msr_d.r_maxsize = msgsz;
 		msr_d.r_msg = ERR_PTR(-EAGAIN);
 		current->state = TASK_INTERRUPTIBLE;
-		msg_unlock(msqid);
+		msg_unlock(msq);
 
 		schedule();
 		current->state = TASK_RUNNING;
@@ -804,21 +803,19 @@
 		if(!IS_ERR(msg)) 
 			goto out_success;
 
-		t = msg_lock(msqid);
-		if(t==NULL)
-			msqid=-1;
+		msq = msg_lock(msqid);
 		msg = (struct msg_msg*)msr_d.r_msg;
 		if(!IS_ERR(msg)) {
 			/* our message arived while we waited for
 			 * the spinlock. Process it.
 			 */
-			if(msqid!=-1)
-				msg_unlock(msqid);
+			if(msq)
+				msg_unlock(msq);
 			goto out_success;
 		}
 		err = PTR_ERR(msg);
 		if(err == -EAGAIN) {
-			if(msqid==-1)
+			if(!msq)
 				BUG();
 			list_del(&msr_d.r_list);
 			if (signal_pending(current))
@@ -828,8 +825,8 @@
 		}
 	}
 out_unlock:
-	if(msqid!=-1)
-		msg_unlock(msqid);
+	if(msq)
+		msg_unlock(msq);
 	return err;
 }
 
@@ -862,7 +859,7 @@
 				msq->q_stime,
 				msq->q_rtime,
 				msq->q_ctime);
-			msg_unlock(i);
+			msg_unlock(msq);
 
 			pos += len;
 			if(pos < offset) {
diff -Nru a/ipc/sem.c b/ipc/sem.c
--- a/ipc/sem.c	Mon Nov  4 14:31:01 2002
+++ b/ipc/sem.c	Mon Nov  4 14:31:01 2002
@@ -69,7 +69,7 @@
 
 
 #define sem_lock(id)	((struct sem_array*)ipc_lock(&sem_ids,id))
-#define sem_unlock(id)	ipc_unlock(&sem_ids,id)
+#define sem_unlock(sma)	ipc_unlock(&(sma)->sem_perm)
 #define sem_rmid(id)	((struct sem_array*)ipc_rmid(&sem_ids,id))
 #define sem_checkid(sma, semid)	\
 	ipc_checkid(&sem_ids,&sma->sem_perm,semid)
@@ -126,7 +126,7 @@
 		return -ENOSPC;
 
 	size = sizeof (*sma) + nsems * sizeof (struct sem);
-	sma = (struct sem_array *) ipc_alloc(size);
+	sma = ipc_rcu_alloc(size);
 	if (!sma) {
 		return -ENOMEM;
 	}
@@ -138,14 +138,14 @@
 	sma->sem_perm.security = NULL;
 	retval = security_ops->sem_alloc_security(sma);
 	if (retval) {
-		ipc_free(sma, size);
+		ipc_rcu_free(sma, size);
 		return retval;
 	}
 
 	id = ipc_addid(&sem_ids, &sma->sem_perm, sc_semmni);
 	if(id == -1) {
 		security_ops->sem_free_security(sma);
-		ipc_free(sma, size);
+		ipc_rcu_free(sma, size);
 		return -ENOSPC;
 	}
 	used_sems += nsems;
@@ -156,7 +156,7 @@
 	/* sma->undo = NULL; */
 	sma->sem_nsems = nsems;
 	sma->sem_ctime = CURRENT_TIME;
-	sem_unlock(id);
+	sem_unlock(sma);
 
 	return sem_buildid(id, sma->sem_perm.seq);
 }
@@ -189,7 +189,7 @@
 			err = -EACCES;
 		else
 			err = sem_buildid(id, sma->sem_perm.seq);
-		sem_unlock(id);
+		sem_unlock(sma);
 	}
 
 	up(&sem_ids.sem);
@@ -205,12 +205,12 @@
 	if(smanew==NULL)
 		return -EIDRM;
 	if(smanew != sma || sem_checkid(sma,semid) || sma->sem_nsems != nsems) {
-		sem_unlock(semid);
+		sem_unlock(smanew);
 		return -EIDRM;
 	}
 
 	if (ipcperms(&sma->sem_perm, flg)) {
-		sem_unlock(semid);
+		sem_unlock(smanew);
 		return -EACCES;
 	}
 	return 0;
@@ -423,12 +423,12 @@
 		q->prev = NULL;
 		wake_up_process(q->sleeper); /* doesn't sleep */
 	}
-	sem_unlock(id);
+	sem_unlock(sma);
 
 	used_sems -= sma->sem_nsems;
 	size = sizeof (*sma) + sma->sem_nsems * sizeof (struct sem);
 	security_ops->sem_free_security(sma);
-	ipc_free(sma, size);
+	ipc_rcu_free(sma, size);
 }
 
 static unsigned long copy_semid_to_user(void *buf, struct semid64_ds *in, int version)
@@ -456,6 +456,7 @@
 static int semctl_nolock(int semid, int semnum, int cmd, int version, union semun arg)
 {
 	int err = -EINVAL;
+	struct sem_array *sma;
 
 	switch(cmd) {
 	case IPC_INFO:
@@ -489,7 +490,6 @@
 	}
 	case SEM_STAT:
 	{
-		struct sem_array *sma;
 		struct semid64_ds tbuf;
 		int id;
 
@@ -511,7 +511,7 @@
 		tbuf.sem_otime  = sma->sem_otime;
 		tbuf.sem_ctime  = sma->sem_ctime;
 		tbuf.sem_nsems  = sma->sem_nsems;
-		sem_unlock(semid);
+		sem_unlock(sma);
 		if (copy_semid_to_user (arg.buf, &tbuf, version))
 			return -EFAULT;
 		return id;
@@ -521,7 +521,7 @@
 	}
 	return err;
 out_unlock:
-	sem_unlock(semid);
+	sem_unlock(sma);
 	return err;
 }
 
@@ -555,7 +555,7 @@
 		int i;
 
 		if(nsems > SEMMSL_FAST) {
-			sem_unlock(semid);			
+			sem_unlock(sma);			
 			sem_io = ipc_alloc(sizeof(ushort)*nsems);
 			if(sem_io == NULL)
 				return -ENOMEM;
@@ -566,7 +566,7 @@
 
 		for (i = 0; i < sma->sem_nsems; i++)
 			sem_io[i] = sma->sem_base[i].semval;
-		sem_unlock(semid);
+		sem_unlock(sma);
 		err = 0;
 		if(copy_to_user(array, sem_io, nsems*sizeof(ushort)))
 			err = -EFAULT;
@@ -577,7 +577,7 @@
 		int i;
 		struct sem_undo *un;
 
-		sem_unlock(semid);
+		sem_unlock(sma);
 
 		if(nsems > SEMMSL_FAST) {
 			sem_io = ipc_alloc(sizeof(ushort)*nsems);
@@ -619,7 +619,7 @@
 		tbuf.sem_otime  = sma->sem_otime;
 		tbuf.sem_ctime  = sma->sem_ctime;
 		tbuf.sem_nsems  = sma->sem_nsems;
-		sem_unlock(semid);
+		sem_unlock(sma);
 		if (copy_semid_to_user (arg.buf, &tbuf, version))
 			return -EFAULT;
 		return 0;
@@ -665,7 +665,7 @@
 	}
 	}
 out_unlock:
-	sem_unlock(semid);
+	sem_unlock(sma);
 out_free:
 	if(sem_io != fast_sem_io)
 		ipc_free(sem_io, sizeof(ushort)*nsems);
@@ -750,18 +750,18 @@
 		ipcp->mode = (ipcp->mode & ~S_IRWXUGO)
 				| (setbuf.mode & S_IRWXUGO);
 		sma->sem_ctime = CURRENT_TIME;
-		sem_unlock(semid);
+		sem_unlock(sma);
 		err = 0;
 		break;
 	default:
-		sem_unlock(semid);
+		sem_unlock(sma);
 		err = -EINVAL;
 		break;
 	}
 	return err;
 
 out_unlock:
-	sem_unlock(semid);
+	sem_unlock(sma);
 	return err;
 }
 
@@ -914,7 +914,7 @@
 	saved_add_count = 0;
 	if (current->sysvsem.undo_list != NULL)
 		saved_add_count = current->sysvsem.undo_list->add_count;
-	sem_unlock(semid);
+	sem_unlock(sma);
 	unlock_semundo();
 
 	error = get_undo_list(&undo_list);
@@ -1052,18 +1052,17 @@
 	current->sysvsem.sleep_list = &queue;
 
 	for (;;) {
-		struct sem_array* tmp;
 		queue.status = -EINTR;
 		queue.sleeper = current;
 		current->state = TASK_INTERRUPTIBLE;
-		sem_unlock(semid);
+		sem_unlock(sma);
 		unlock_semundo();
 
 		schedule();
 
 		lock_semundo();
-		tmp = sem_lock(semid);
-		if(tmp==NULL) {
+		sma = sem_lock(semid);
+		if(sma==NULL) {
 			if(queue.prev != NULL)
 				BUG();
 			current->sysvsem.sleep_list = NULL;
@@ -1098,7 +1097,7 @@
 	if (alter)
 		update_queue (sma);
 out_unlock_semundo_free:
-	sem_unlock(semid);
+	sem_unlock(sma);
 out_semundo_free:
 	unlock_semundo();
 out_free:
@@ -1185,7 +1184,7 @@
 			remove_from_queue(q->sma,q);
 		}
 		if(sma!=NULL)
-			sem_unlock(semid);
+			sem_unlock(sma);
 	}
 
 	undo_list = current->sysvsem.undo_list;
@@ -1233,7 +1232,7 @@
 		/* maybe some queued-up processes were waiting for this */
 		update_queue(sma);
 next_entry:
-		sem_unlock(semid);
+		sem_unlock(sma);
 	}
 	__exit_semundo(current);
 
@@ -1265,7 +1264,7 @@
 				sma->sem_perm.cgid,
 				sma->sem_otime,
 				sma->sem_ctime);
-			sem_unlock(i);
+			sem_unlock(sma);
 
 			pos += len;
 			if(pos < offset) {
diff -Nru a/ipc/shm.c b/ipc/shm.c
--- a/ipc/shm.c	Mon Nov  4 14:31:02 2002
+++ b/ipc/shm.c	Mon Nov  4 14:31:02 2002
@@ -18,6 +18,7 @@
 #include <linux/config.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
+#include <linux/hugetlb.h>
 #include <linux/shm.h>
 #include <linux/init.h>
 #include <linux/file.h>
@@ -37,9 +38,7 @@
 static struct ipc_ids shm_ids;
 
 #define shm_lock(id)	((struct shmid_kernel*)ipc_lock(&shm_ids,id))
-#define shm_unlock(id)	ipc_unlock(&shm_ids,id)
-#define shm_lockall()	ipc_lockall(&shm_ids)
-#define shm_unlockall()	ipc_unlockall(&shm_ids)
+#define shm_unlock(shp)	ipc_unlock(&(shp)->shm_perm)
 #define shm_get(id)	((struct shmid_kernel*)ipc_get(&shm_ids,id))
 #define shm_buildid(id, seq) \
 	ipc_buildid(&shm_ids, id, seq)
@@ -92,7 +91,7 @@
 	shp->shm_atim = CURRENT_TIME;
 	shp->shm_lprid = current->pid;
 	shp->shm_nattch++;
-	shm_unlock(id);
+	shm_unlock(shp);
 }
 
 /* This is called by fork, once for every shm attach. */
@@ -113,11 +112,12 @@
 {
 	shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
 	shm_rmid (shp->id);
-	shm_unlock(shp->id);
-	shmem_lock(shp->shm_file, 0);
+	shm_unlock(shp);
+	if (!is_file_hugepages(shp->shm_file))
+		shmem_lock(shp->shm_file, 0);
 	fput (shp->shm_file);
 	security_ops->shm_free_security(shp);
-	kfree (shp);
+	ipc_rcu_free(shp, sizeof(struct shmid_kernel));
 }
 
 /*
@@ -143,7 +143,7 @@
 	   shp->shm_flags & SHM_DEST)
 		shm_destroy (shp);
 	else
-		shm_unlock(id);
+		shm_unlock(shp);
 	up (&shm_ids.sem);
 }
 
@@ -180,7 +180,7 @@
 	if (shm_tot + numpages >= shm_ctlall)
 		return -ENOSPC;
 
-	shp = (struct shmid_kernel *) kmalloc (sizeof (*shp), GFP_USER);
+	shp = ipc_rcu_alloc(sizeof(*shp));
 	if (!shp)
 		return -ENOMEM;
 
@@ -190,12 +190,16 @@
 	shp->shm_perm.security = NULL;
 	error = security_ops->shm_alloc_security(shp);
 	if (error) {
-		kfree(shp);
+		ipc_rcu_free(shp, sizeof(*shp));
 		return error;
 	}
 
-	sprintf (name, "SYSV%08x", key);
-	file = shmem_file_setup(name, size, VM_ACCOUNT);
+	if (shmflg & SHM_HUGETLB)
+		file = hugetlb_zero_setup(size);
+	else {
+		sprintf (name, "SYSV%08x", key);
+		file = shmem_file_setup(name, size, VM_ACCOUNT);
+	}
 	error = PTR_ERR(file);
 	if (IS_ERR(file))
 		goto no_file;
@@ -214,16 +218,19 @@
 	shp->id = shm_buildid(id,shp->shm_perm.seq);
 	shp->shm_file = file;
 	file->f_dentry->d_inode->i_ino = shp->id;
-	file->f_op = &shm_file_operations;
+	if (shmflg & SHM_HUGETLB)
+		set_file_hugepages(file);
+	else
+		file->f_op = &shm_file_operations;
 	shm_tot += numpages;
-	shm_unlock (id);
+	shm_unlock(shp);
 	return shp->id;
 
 no_id:
 	fput(file);
 no_file:
 	security_ops->shm_free_security(shp);
-	kfree(shp);
+	ipc_rcu_free(shp, sizeof(*shp));
 	return error;
 }
 
@@ -252,9 +259,10 @@
 			err = -EACCES;
 		else
 			err = shm_buildid(id, shp->shm_perm.seq);
-		shm_unlock(id);
+		shm_unlock(shp);
 	}
 	up(&shm_ids.sem);
+
 	return err;
 }
 
@@ -379,8 +387,10 @@
 	struct shmid_kernel *shp;
 	int err, version;
 
-	if (cmd < 0 || shmid < 0)
-		return -EINVAL;
+	if (cmd < 0 || shmid < 0) {
+		err = -EINVAL;
+		goto out;
+	}
 
 	version = ipc_parse_version(&cmd);
 
@@ -401,7 +411,7 @@
 		err= shm_ids.max_id;
 		if(err<0)
 			err = 0;
-		return err;
+		goto out;
 	}
 	case SHM_INFO:
 	{
@@ -409,19 +419,20 @@
 
 		memset(&shm_info,0,sizeof(shm_info));
 		down(&shm_ids.sem);
-		shm_lockall();
 		shm_info.used_ids = shm_ids.in_use;
 		shm_get_stat (&shm_info.shm_rss, &shm_info.shm_swp);
 		shm_info.shm_tot = shm_tot;
 		shm_info.swap_attempts = 0;
 		shm_info.swap_successes = 0;
 		err = shm_ids.max_id;
-		shm_unlockall();
 		up(&shm_ids.sem);
-		if(copy_to_user (buf, &shm_info, sizeof(shm_info)))
-			return -EFAULT;
+		if(copy_to_user (buf, &shm_info, sizeof(shm_info))) {
+			err = -EFAULT;
+			goto out;
+		}
 
-		return err < 0 ? 0 : err;
+		err = err < 0 ? 0 : err;
+		goto out;
 	}
 	case SHM_STAT:
 	case IPC_STAT:
@@ -430,9 +441,10 @@
 		int result;
 		memset(&tbuf, 0, sizeof(tbuf));
 		shp = shm_lock(shmid);
-		if(shp==NULL)
-			return -EINVAL;
-		if(cmd==SHM_STAT) {
+		if(shp==NULL) {
+			err = -EINVAL;
+			goto out;
+		} else if(cmd==SHM_STAT) {
 			err = -EINVAL;
 			if (shmid > shm_ids.max_id)
 				goto out_unlock;
@@ -454,10 +466,12 @@
 		tbuf.shm_cpid	= shp->shm_cprid;
 		tbuf.shm_lpid	= shp->shm_lprid;
 		tbuf.shm_nattch	= shp->shm_nattch;
-		shm_unlock(shmid);
+		shm_unlock(shp);
 		if(copy_shmid_to_user (buf, &tbuf, version))
-			return -EFAULT;
-		return result;
+			err = -EFAULT;
+		else
+			err = result;
+		goto out;
 	}
 	case SHM_LOCK:
 	case SHM_UNLOCK:
@@ -465,24 +479,30 @@
 /* Allow superuser to lock segment in memory */
 /* Should the pages be faulted in here or leave it to user? */
 /* need to determine interaction with current->swappable */
-		if (!capable(CAP_IPC_LOCK))
-			return -EPERM;
+		if (!capable(CAP_IPC_LOCK)) {
+			err = -EPERM;
+			goto out;
+		}
 
 		shp = shm_lock(shmid);
-		if(shp==NULL)
-			return -EINVAL;
+		if(shp==NULL) {
+			err = -EINVAL;
+			goto out;
+		}
 		err = shm_checkid(shp,shmid);
 		if(err)
 			goto out_unlock;
 		if(cmd==SHM_LOCK) {
-			shmem_lock(shp->shm_file, 1);
+			if (!is_file_hugepages(shp->shm_file))
+				shmem_lock(shp->shm_file, 1);
 			shp->shm_flags |= SHM_LOCKED;
 		} else {
-			shmem_lock(shp->shm_file, 0);
+			if (!is_file_hugepages(shp->shm_file))
+				shmem_lock(shp->shm_file, 0);
 			shp->shm_flags &= ~SHM_LOCKED;
 		}
-		shm_unlock(shmid);
-		return err;
+		shm_unlock(shp);
+		goto out;
 	}
 	case IPC_RMID:
 	{
@@ -514,17 +534,19 @@
 			shp->shm_flags |= SHM_DEST;
 			/* Do not find it any more */
 			shp->shm_perm.key = IPC_PRIVATE;
-			shm_unlock(shmid);
+			shm_unlock(shp);
 		} else
 			shm_destroy (shp);
 		up(&shm_ids.sem);
-		return err;
+		goto out;
 	}
 
 	case IPC_SET:
 	{
-		if(copy_shmid_from_user (&setbuf, buf, version))
-			return -EFAULT;
+		if(copy_shmid_from_user (&setbuf, buf, version)) {
+			err = -EFAULT;
+			goto out;
+		}
 		down(&shm_ids.sem);
 		shp = shm_lock(shmid);
 		err=-EINVAL;
@@ -549,17 +571,19 @@
 	}
 
 	default:
-		return -EINVAL;
+		err = -EINVAL;
+		goto out;
 	}
 
 	err = 0;
 out_unlock_up:
-	shm_unlock(shmid);
+	shm_unlock(shp);
 out_up:
 	up(&shm_ids.sem);
-	return err;
+	goto out;
 out_unlock:
-	shm_unlock(shmid);
+	shm_unlock(shp);
+out:
 	return err;
 }
 
@@ -579,10 +603,10 @@
 	int acc_mode;
 	void *user_addr;
 
-	if (shmid < 0)
-		return -EINVAL;
-
-	if ((addr = (ulong)shmaddr)) {
+	if (shmid < 0) {
+		err = -EINVAL;
+		goto out;
+	} else if ((addr = (ulong)shmaddr)) {
 		if (addr & (SHMLBA-1)) {
 			if (shmflg & SHM_RND)
 				addr &= ~(SHMLBA-1);	   /* round down */
@@ -612,21 +636,24 @@
 	 * additional creator id...
 	 */
 	shp = shm_lock(shmid);
-	if(shp == NULL)
-		return -EINVAL;
+	if(shp == NULL) {
+		err = -EINVAL;
+		goto out;
+	}
 	err = shm_checkid(shp,shmid);
 	if (err) {
-		shm_unlock(shmid);
-		return err;
+		shm_unlock(shp);
+		goto out;
 	}
 	if (ipcperms(&shp->shm_perm, acc_mode)) {
-		shm_unlock(shmid);
-		return -EACCES;
+		shm_unlock(shp);
+		err = -EACCES;
+		goto out;
 	}
 	file = shp->shm_file;
 	size = file->f_dentry->d_inode->i_size;
 	shp->shm_nattch++;
-	shm_unlock(shmid);
+	shm_unlock(shp);
 
 	down_write(&current->mm->mmap_sem);
 	if (addr && !(shmflg & SHM_REMAP)) {
@@ -655,15 +682,15 @@
 	   shp->shm_flags & SHM_DEST)
 		shm_destroy (shp);
 	else
-		shm_unlock(shmid);
+		shm_unlock(shp);
 	up (&shm_ids.sem);
 
 	*raddr = (unsigned long) user_addr;
 	err = 0;
 	if (IS_ERR(user_addr))
 		err = PTR_ERR(user_addr);
+out:
 	return err;
-
 }
 
 /*
@@ -673,18 +700,24 @@
 asmlinkage long sys_shmdt (char *shmaddr)
 {
 	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *shmd, *shmdnext;
+	struct vm_area_struct *vma;
+	unsigned long address = (unsigned long)shmaddr;
 	int retval = -EINVAL;
 
 	down_write(&mm->mmap_sem);
-	for (shmd = mm->mmap; shmd; shmd = shmdnext) {
-		shmdnext = shmd->vm_next;
-		if (shmd->vm_ops == &shm_vm_ops
-		    && shmd->vm_start - (shmd->vm_pgoff << PAGE_SHIFT) == (ulong) shmaddr) {
-			do_munmap(mm, shmd->vm_start, shmd->vm_end - shmd->vm_start);
-			retval = 0;
-		}
-	}
+	vma = find_vma(mm, address);
+	if (!vma)
+		goto out;
+	if (vma->vm_start != address)
+		goto out;
+	
+	/* ->vm_pgoff is always 0, see do_mmap() in sys_shmat() */
+	retval = 0;
+	if (vma->vm_ops == &shm_vm_ops || (vma->vm_flags & VM_HUGETLB))
+		do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start);
+	else
+		retval = -EINVAL;
+out:
 	up_write(&mm->mmap_sem);
 	return retval;
 }
@@ -727,7 +760,7 @@
 				shp->shm_atim,
 				shp->shm_dtim,
 				shp->shm_ctim);
-			shm_unlock(i);
+			shm_unlock(shp);
 
 			pos += len;
 			if(pos < offset) {
diff -Nru a/ipc/util.c b/ipc/util.c
--- a/ipc/util.c	Mon Nov  4 14:31:01 2002
+++ b/ipc/util.c	Mon Nov  4 14:31:01 2002
@@ -8,6 +8,8 @@
  *            Chris Evans, <chris@ferret.lmh.ox.ac.uk>
  * Nov 1999 - ipc helper functions, unified SMP locking
  *	      Manfred Spraul <manfreds@colorfullife.com>
+ * Oct 2002 - One lock per IPC id. RCU ipc_free for lock-free grow_ary().
+ *            Mingming Cao <cmm@us.ibm.com>
  */
 
 #include <linux/config.h>
@@ -20,6 +22,8 @@
 #include <linux/slab.h>
 #include <linux/highuid.h>
 #include <linux/security.h>
+#include <linux/rcupdate.h>
+#include <linux/workqueue.h>
 
 #if defined(CONFIG_SYSVIPC)
 
@@ -69,13 +73,12 @@
 		 	ids->seq_max = seq_limit;
 	}
 
-	ids->entries = ipc_alloc(sizeof(struct ipc_id)*size);
+	ids->entries = ipc_rcu_alloc(sizeof(struct ipc_id)*size);
 
 	if(ids->entries == NULL) {
 		printk(KERN_ERR "ipc_init_ids() failed, ipc service disabled.\n");
 		ids->size = 0;
 	}
-	ids->ary = SPIN_LOCK_UNLOCKED;
 	for(i=0;i<ids->size;i++)
 		ids->entries[i].p = NULL;
 }
@@ -84,7 +87,8 @@
  *	ipc_findkey	-	find a key in an ipc identifier set	
  *	@ids: Identifier set
  *	@key: The key to find
- *
+ *	
+ *	Requires ipc_ids.sem locked.
  *	Returns the identifier if found or -1 if not.
  */
  
@@ -92,8 +96,9 @@
 {
 	int id;
 	struct kern_ipc_perm* p;
+	int max_id = ids->max_id;
 
-	for (id = 0; id <= ids->max_id; id++) {
+	for (id = 0; id <= max_id; id++) {
 		p = ids->entries[id].p;
 		if(p==NULL)
 			continue;
@@ -103,6 +108,9 @@
 	return -1;
 }
 
+/*
+ * Requires ipc_ids.sem locked
+ */
 static int grow_ary(struct ipc_ids* ids, int newsize)
 {
 	struct ipc_id* new;
@@ -114,21 +122,21 @@
 	if(newsize <= ids->size)
 		return newsize;
 
-	new = ipc_alloc(sizeof(struct ipc_id)*newsize);
+	new = ipc_rcu_alloc(sizeof(struct ipc_id)*newsize);
 	if(new == NULL)
 		return ids->size;
 	memcpy(new, ids->entries, sizeof(struct ipc_id)*ids->size);
 	for(i=ids->size;i<newsize;i++) {
 		new[i].p = NULL;
 	}
-	spin_lock(&ids->ary);
-
 	old = ids->entries;
-	ids->entries = new;
 	i = ids->size;
+	
+	ids->entries = new;
+	wmb();
 	ids->size = newsize;
-	spin_unlock(&ids->ary);
-	ipc_free(old, sizeof(struct ipc_id)*i);
+
+	ipc_rcu_free(old, sizeof(struct ipc_id)*i);
 	return ids->size;
 }
 
@@ -166,7 +174,10 @@
 	if(ids->seq > ids->seq_max)
 		ids->seq = 0;
 
-	spin_lock(&ids->ary);
+	new->lock = SPIN_LOCK_UNLOCKED;
+	new->deleted = 0;
+	rcu_read_lock();
+	spin_lock(&new->lock);
 	ids->entries[id].p = new;
 	return id;
 }
@@ -180,6 +191,8 @@
  *	fed an invalid identifier. The entry is removed and internal
  *	variables recomputed. The object associated with the identifier
  *	is returned.
+ *	ipc_ids.sem and the spinlock for this ID is hold before this function
+ *	is called, and remain locked on the exit.
  */
  
 struct kern_ipc_perm* ipc_rmid(struct ipc_ids* ids, int id)
@@ -188,6 +201,7 @@
 	int lid = id % SEQ_MULTIPLIER;
 	if(lid >= ids->size)
 		BUG();
+	
 	p = ids->entries[lid].p;
 	ids->entries[lid].p = NULL;
 	if(p==NULL)
@@ -202,6 +216,7 @@
 		} while (ids->entries[lid].p == NULL);
 		ids->max_id = lid;
 	}
+	p->deleted = 1;
 	return p;
 }
 
@@ -224,14 +239,14 @@
 }
 
 /**
- *	ipc_free	-	free ipc space
+ *	ipc_free        -       free ipc space
  *	@ptr: pointer returned by ipc_alloc
  *	@size: size of block
  *
  *	Free a block created with ipc_alloc. The caller must know the size
  *	used in the allocation call.
  */
- 
+
 void ipc_free(void* ptr, int size)
 {
 	if(size > PAGE_SIZE)
@@ -240,6 +255,85 @@
 		kfree(ptr);
 }
 
+struct ipc_rcu_kmalloc
+{
+	struct rcu_head rcu;
+	/* "void *" makes sure alignment of following data is sane. */
+	void *data[0];
+};
+
+struct ipc_rcu_vmalloc
+{
+	struct rcu_head rcu;
+	struct work_struct work;
+	/* "void *" makes sure alignment of following data is sane. */
+	void *data[0];
+};
+
+static inline int rcu_use_vmalloc(int size)
+{
+	/* Too big for a single page? */
+	if (sizeof(struct ipc_rcu_kmalloc) + size > PAGE_SIZE)
+		return 1;
+	return 0;
+}
+
+/**
+ *	ipc_rcu_alloc	-	allocate ipc and rcu space 
+ *	@size: size desired
+ *
+ *	Allocate memory for the rcu header structure +  the object.
+ *	Returns the pointer to the object.
+ *	NULL is returned if the allocation fails. 
+ */
+ 
+void* ipc_rcu_alloc(int size)
+{
+	void* out;
+	/* 
+	 * We prepend the allocation with the rcu struct, and
+	 * workqueue if necessary (for vmalloc). 
+	 */
+	if (rcu_use_vmalloc(size)) {
+		out = vmalloc(sizeof(struct ipc_rcu_vmalloc) + size);
+		if (out) out += sizeof(struct ipc_rcu_vmalloc);
+	} else {
+		out = kmalloc(sizeof(struct ipc_rcu_kmalloc)+size, GFP_KERNEL);
+		if (out) out += sizeof(struct ipc_rcu_kmalloc);
+	}
+
+	return out;
+}
+
+/**
+ *	ipc_schedule_free	- free ipc + rcu space
+ * 
+ * Since RCU callback function is called in bh,
+ * we need to defer the vfree to schedule_work
+ */
+static void ipc_schedule_free(void* arg)
+{
+	struct ipc_rcu_vmalloc *free = arg;
+
+	INIT_WORK(&free->work, vfree, free);
+	schedule_work(&free->work);
+}
+
+void ipc_rcu_free(void* ptr, int size)
+{
+	if (rcu_use_vmalloc(size)) {
+		struct ipc_rcu_vmalloc *free;
+		free = ptr - sizeof(*free);
+		call_rcu(&free->rcu, ipc_schedule_free, free);
+	} else {
+		struct ipc_rcu_kmalloc *free;
+		free = ptr - sizeof(*free);
+		/* kfree takes a "const void *" so gcc warns.  So we cast. */
+		call_rcu(&free->rcu, (void (*)(void *))kfree, free);
+	}
+
+}
+
 /**
  *	ipcperms	-	check IPC permissions
  *	@ipcp: IPC permission set
@@ -311,6 +405,77 @@
 	out->cgid	= NEW_TO_OLD_GID(in->cgid);
 	out->mode	= in->mode;
 	out->seq	= in->seq;
+}
+
+/*
+ * ipc_get() requires ipc_ids.sem down, otherwise we need a rmb() here
+ * to sync with grow_ary();
+ *
+ * So far only shm_get_stat() uses ipc_get() via shm_get().  So ipc_get()
+ * is called with shm_ids.sem locked.  Thus a rmb() is not needed here,
+ * as grow_ary() also requires shm_ids.sem down(for shm).
+ *
+ * But if ipc_get() is used in the future without ipc_ids.sem down,
+ * we need to add a rmb() before accessing the entries array
+ */
+struct kern_ipc_perm* ipc_get(struct ipc_ids* ids, int id)
+{
+	struct kern_ipc_perm* out;
+	int lid = id % SEQ_MULTIPLIER;
+	if(lid >= ids->size)
+		return NULL;
+	rmb();
+	out = ids->entries[lid].p;
+	return out;
+}
+
+struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id)
+{
+	struct kern_ipc_perm* out;
+	int lid = id % SEQ_MULTIPLIER;
+
+	rcu_read_lock();
+	if(lid >= ids->size) {
+		rcu_read_unlock();
+		return NULL;
+	}
+
+	/* we need a barrier here to sync with grow_ary() */
+	rmb();
+	out = ids->entries[lid].p;
+	if(out == NULL) {
+		rcu_read_unlock();
+		return NULL;
+	}
+	spin_lock(&out->lock);
+	
+	/* ipc_rmid() may have already freed the ID while ipc_lock
+	 * was spinning: here verify that the structure is still valid
+	 */
+	if (out->deleted) {
+		spin_unlock(&out->lock);
+		rcu_read_unlock();
+		return NULL;
+	}
+	return out;
+}
+
+void ipc_unlock(struct kern_ipc_perm* perm)
+{
+	spin_unlock(&perm->lock);
+	rcu_read_unlock();
+}
+
+int ipc_buildid(struct ipc_ids* ids, int id, int seq)
+{
+	return SEQ_MULTIPLIER*seq + id;
+}
+
+int ipc_checkid(struct ipc_ids* ids, struct kern_ipc_perm* ipcp, int uid)
+{
+	if(uid/SEQ_MULTIPLIER != ipcp->seq)
+		return 1;
+	return 0;
 }
 
 #ifndef __ia64__
diff -Nru a/ipc/util.h b/ipc/util.h
--- a/ipc/util.h	Mon Nov  4 14:31:02 2002
+++ b/ipc/util.h	Mon Nov  4 14:31:02 2002
@@ -4,7 +4,6 @@
  *
  * ipc helper functions (c) 1999 Manfred Spraul <manfreds@colorfullife.com>
  */
-
 #define USHRT_MAX 0xffff
 #define SEQ_MULTIPLIER	(IPCMNI)
 
@@ -19,7 +18,6 @@
 	unsigned short seq;
 	unsigned short seq_max;
 	struct semaphore sem;	
-	spinlock_t ary;
 	struct ipc_id* entries;
 };
 
@@ -27,7 +25,6 @@
 	struct kern_ipc_perm* p;
 };
 
-
 void __init ipc_init_ids(struct ipc_ids* ids, int size);
 
 /* must be called with ids->sem acquired.*/
@@ -44,57 +41,17 @@
  */
 void* ipc_alloc(int size);
 void ipc_free(void* ptr, int size);
+/* for allocation that need to be freed by RCU
+ * both function can sleep
+ */
+void* ipc_rcu_alloc(int size);
+void ipc_rcu_free(void* arg, int size);
 
-extern inline void ipc_lockall(struct ipc_ids* ids)
-{
-	spin_lock(&ids->ary);
-}
-
-extern inline struct kern_ipc_perm* ipc_get(struct ipc_ids* ids, int id)
-{
-	struct kern_ipc_perm* out;
-	int lid = id % SEQ_MULTIPLIER;
-	if(lid >= ids->size)
-		return NULL;
-
-	out = ids->entries[lid].p;
-	return out;
-}
-
-extern inline void ipc_unlockall(struct ipc_ids* ids)
-{
-	spin_unlock(&ids->ary);
-}
-extern inline struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id)
-{
-	struct kern_ipc_perm* out;
-	int lid = id % SEQ_MULTIPLIER;
-	if(lid >= ids->size)
-		return NULL;
-
-	spin_lock(&ids->ary);
-	out = ids->entries[lid].p;
-	if(out==NULL)
-		spin_unlock(&ids->ary);
-	return out;
-}
-
-extern inline void ipc_unlock(struct ipc_ids* ids, int id)
-{
-	spin_unlock(&ids->ary);
-}
-
-extern inline int ipc_buildid(struct ipc_ids* ids, int id, int seq)
-{
-	return SEQ_MULTIPLIER*seq + id;
-}
-
-extern inline int ipc_checkid(struct ipc_ids* ids, struct kern_ipc_perm* ipcp, int uid)
-{
-	if(uid/SEQ_MULTIPLIER != ipcp->seq)
-		return 1;
-	return 0;
-}
+struct kern_ipc_perm* ipc_get(struct ipc_ids* ids, int id);
+struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id);
+void ipc_unlock(struct kern_ipc_perm* perm);
+int ipc_buildid(struct ipc_ids* ids, int id, int seq);
+int ipc_checkid(struct ipc_ids* ids, struct kern_ipc_perm* ipcp, int uid);
 
 void kernel_to_ipc64_perm(struct kern_ipc_perm *in, struct ipc64_perm *out);
 void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out);
diff -Nru a/kernel/cpufreq.c b/kernel/cpufreq.c
--- a/kernel/cpufreq.c	Mon Nov  4 14:31:01 2002
+++ b/kernel/cpufreq.c	Mon Nov  4 14:31:01 2002
@@ -4,7 +4,7 @@
  *  Copyright (C) 2001 Russell King
  *            (C) 2002 Dominik Brodowski <linux@brodo.de>
  *
- *  $Id: cpufreq.c,v 1.43 2002/09/21 09:05:29 db Exp $
+ *  $Id: cpufreq.c,v 1.45 2002/10/08 14:54:23 db Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -21,13 +21,10 @@
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
 #include <linux/ctype.h>
+#include <linux/proc_fs.h>
 
 #include <asm/uaccess.h>
 
-#ifdef CONFIG_CPU_FREQ_26_API
-#include <linux/proc_fs.h>
-#endif
-
 #ifdef CONFIG_CPU_FREQ_24_API
 #include <linux/sysctl.h>
 #endif
@@ -200,7 +197,6 @@
 __setup("cpufreq=", cpufreq_setup);
 
 
-#ifdef CONFIG_CPU_FREQ_26_API
 #ifdef CONFIG_PROC_FS
 
 /**
@@ -335,7 +331,6 @@
 	return;
 }
 #endif /* CONFIG_PROC_FS */
-#endif /* CONFIG_CPU_FREQ_26_API */
 
 
 
@@ -344,10 +339,6 @@
  *********************************************************************/
 
 #ifdef CONFIG_CPU_FREQ_24_API
-/* NOTE #1: when you use this API, you may not use any other calls,
- * except cpufreq_[un]register_notifier, of course.
- */
-
 /** 
  * cpufreq_set - set the CPU frequency
  * @freq: target frequency in kHz
@@ -879,7 +870,7 @@
 		cpufreq_driver->policy[policy->cpu].max    = policy->max;
 		cpufreq_driver->policy[policy->cpu].policy = policy->policy;
 	}
-	
+
 #ifdef CONFIG_CPU_FREQ_24_API
 	if (policy->cpu == CPUFREQ_ALL_CPUS) {
 		for (i=0;i<NR_CPUS;i++)
@@ -945,6 +936,14 @@
 	case CPUFREQ_POSTCHANGE:
 		adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
 		notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_POSTCHANGE, freqs);
+#ifdef CONFIG_CPU_FREQ_24_API
+		if (freqs->cpu == CPUFREQ_ALL_CPUS) {
+			int i;
+			for (i=0;i<NR_CPUS;i++)
+				cpu_cur_freq[i] = freqs->new;
+		} else
+			cpu_cur_freq[freqs->cpu] = freqs->new;
+#endif
 		break;
 	}
 	up(&cpufreq_notifier_sem);
@@ -992,9 +991,7 @@
 
 	ret = cpufreq_set_policy(&default_policy);
 
-#ifdef CONFIG_CPU_FREQ_26_API
 	cpufreq_proc_init();
-#endif
 
 #ifdef CONFIG_CPU_FREQ_24_API
 	down(&cpufreq_driver_sem);
@@ -1042,9 +1039,7 @@
 
 	up(&cpufreq_driver_sem);
 
-#ifdef CONFIG_CPU_FREQ_26_API
 	cpufreq_proc_exit();
-#endif
 
 #ifdef CONFIG_CPU_FREQ_24_API
 	cpufreq_sysctl_exit();
@@ -1086,13 +1081,7 @@
 		policy.cpu    = i;
 		up(&cpufreq_driver_sem);
 
-#ifdef CONFIG_CPU_FREQ_26_API
 		cpufreq_set_policy(&policy);
-#endif
-
-#ifdef CONFIG_CPU_FREQ_24_API
-		cpufreq_set(cpu_cur_freq[i], i);
-#endif
 	}
 
 	return 0;
diff -Nru a/kernel/fork.c b/kernel/fork.c
--- a/kernel/fork.c	Mon Nov  4 14:31:00 2002
+++ b/kernel/fork.c	Mon Nov  4 14:31:00 2002
@@ -215,6 +215,7 @@
 	mm->locked_vm = 0;
 	mm->mmap = NULL;
 	mm->mmap_cache = NULL;
+	mm->free_area_cache = TASK_UNMAPPED_BASE;
 	mm->map_count = 0;
 	mm->rss = 0;
 	mm->cpu_vm_mask = 0;
@@ -308,6 +309,8 @@
 	mm->page_table_lock = SPIN_LOCK_UNLOCKED;
 	mm->ioctx_list_lock = RW_LOCK_UNLOCKED;
 	mm->default_kioctx = (struct kioctx)INIT_KIOCTX(mm->default_kioctx, *mm);
+	mm->free_area_cache = TASK_UNMAPPED_BASE;
+
 	mm->pgd = pgd_alloc(mm);
 	if (mm->pgd)
 		return mm;
@@ -943,6 +946,22 @@
 	goto fork_out;
 }
 
+static inline int fork_traceflag (unsigned clone_flags)
+{
+	if (clone_flags & (CLONE_UNTRACED | CLONE_IDLETASK))
+		return 0;
+	else if (clone_flags & CLONE_VFORK) {
+		if (current->ptrace & PT_TRACE_VFORK)
+			return PTRACE_EVENT_VFORK;
+	} else if ((clone_flags & CSIGNAL) != SIGCHLD) {
+		if (current->ptrace & PT_TRACE_CLONE)
+			return PTRACE_EVENT_CLONE;
+	} else if (current->ptrace & PT_TRACE_FORK)
+		return PTRACE_EVENT_FORK;
+
+	return 0;
+}
+
 /*
  *  Ok, this is the main fork-routine.
  *
@@ -956,6 +975,13 @@
 			    int *user_tid)
 {
 	struct task_struct *p;
+	int trace = 0;
+
+	if (unlikely(current->ptrace)) {
+		trace = fork_traceflag (clone_flags);
+		if (trace)
+			clone_flags |= CLONE_PTRACE;
+	}
 
 	p = copy_process(clone_flags, stack_start, regs, stack_size, user_tid);
 	if (!IS_ERR(p)) {
@@ -971,6 +997,12 @@
 
 		wake_up_forked_process(p);		/* do this last */
 		++total_forks;
+
+		if (unlikely (trace)) {
+			current->ptrace_message = (unsigned long) p->pid;
+			ptrace_notify ((trace << 8) | SIGTRAP);
+		}
+
 		if (clone_flags & CLONE_VFORK)
 			wait_for_completion(&vfork);
 		else
diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c
--- a/kernel/ksyms.c	Mon Nov  4 14:31:00 2002
+++ b/kernel/ksyms.c	Mon Nov  4 14:31:00 2002
@@ -493,7 +493,6 @@
 EXPORT_SYMBOL(loops_per_jiffy);
 #endif
 
-EXPORT_SYMBOL(kstat);
 
 /* misc */
 EXPORT_SYMBOL(panic);
diff -Nru a/kernel/module.c b/kernel/module.c
--- a/kernel/module.c	Mon Nov  4 14:31:02 2002
+++ b/kernel/module.c	Mon Nov  4 14:31:02 2002
@@ -425,11 +425,11 @@
 		printk(KERN_ERR "init_module: mod->deps out of bounds.\n");
 		goto err2;
 	}
-	if (mod->init && !mod_bound(mod->init, 0, mod)) {
+	if (mod->init && !mod_bound((unsigned long)mod->init, 0, mod)) {
 		printk(KERN_ERR "init_module: mod->init out of bounds.\n");
 		goto err2;
 	}
-	if (mod->cleanup && !mod_bound(mod->cleanup, 0, mod)) {
+	if (mod->cleanup && !mod_bound((unsigned long)mod->cleanup, 0, mod)) {
 		printk(KERN_ERR "init_module: mod->cleanup out of bounds.\n");
 		goto err2;
 	}
@@ -449,7 +449,7 @@
 		goto err2;
 	}
 	if (mod_member_present(mod, can_unload)
-	    && mod->can_unload && !mod_bound(mod->can_unload, 0, mod)) {
+	    && mod->can_unload && !mod_bound((unsigned long)mod->can_unload, 0, mod)) {
 		printk(KERN_ERR "init_module: mod->can_unload out of bounds.\n");
 		goto err2;
 	}
diff -Nru a/kernel/ptrace.c b/kernel/ptrace.c
--- a/kernel/ptrace.c	Mon Nov  4 14:31:03 2002
+++ b/kernel/ptrace.c	Mon Nov  4 14:31:03 2002
@@ -248,3 +248,72 @@
 	}
 	return copied;
 }
+
+static int ptrace_setoptions(struct task_struct *child, long data)
+{
+	if (data & PTRACE_O_TRACESYSGOOD)
+		child->ptrace |= PT_TRACESYSGOOD;
+	else
+		child->ptrace &= ~PT_TRACESYSGOOD;
+
+	if (data & PTRACE_O_TRACEFORK)
+		child->ptrace |= PT_TRACE_FORK;
+	else
+		child->ptrace &= ~PT_TRACE_FORK;
+
+	if (data & PTRACE_O_TRACEVFORK)
+		child->ptrace |= PT_TRACE_VFORK;
+	else
+		child->ptrace &= ~PT_TRACE_VFORK;
+
+	if (data & PTRACE_O_TRACECLONE)
+		child->ptrace |= PT_TRACE_CLONE;
+	else
+		child->ptrace &= ~PT_TRACE_CLONE;
+
+	if (data & PTRACE_O_TRACEEXEC)
+		child->ptrace |= PT_TRACE_EXEC;
+	else
+		child->ptrace &= ~PT_TRACE_EXEC;
+
+	if ((data & (PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACEFORK
+		    | PTRACE_O_TRACEVFORK | PTRACE_O_TRACECLONE
+		    | PTRACE_O_TRACEEXEC))
+	    != data)
+		return -EINVAL;
+
+	return 0;
+}
+
+int ptrace_request(struct task_struct *child, long request,
+		   long addr, long data)
+{
+	int ret = -EIO;
+
+	switch (request) {
+#ifdef PTRACE_OLDSETOPTIONS
+	case PTRACE_OLDSETOPTIONS:
+#endif
+	case PTRACE_SETOPTIONS:
+		ret = ptrace_setoptions(child, data);
+		break;
+	case PTRACE_GETEVENTMSG:
+		ret = put_user(child->ptrace_message, (unsigned long *) data);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+void ptrace_notify(int exit_code)
+{
+	BUG_ON (!(current->ptrace & PT_PTRACED));
+
+	/* Let the debugger run.  */
+	current->exit_code = exit_code;
+	set_current_state(TASK_STOPPED);
+	notify_parent(current, SIGCHLD);
+	schedule();
+}
diff -Nru a/kernel/sched.c b/kernel/sched.c
--- a/kernel/sched.c	Mon Nov  4 14:31:02 2002
+++ b/kernel/sched.c	Mon Nov  4 14:31:02 2002
@@ -839,6 +839,8 @@
 
 #endif
 
+DEFINE_PER_CPU(struct kernel_stat, kstat);
+
 /*
  * We place interactive tasks back into the active array, if possible.
  *
@@ -872,21 +874,21 @@
 	if (p == rq->idle) {
 		/* note: this timer irq context must be accounted for as well */
 		if (irq_count() - HARDIRQ_OFFSET >= SOFTIRQ_OFFSET)
-			kstat.per_cpu_system[cpu] += sys_ticks;
+			kstat_cpu(cpu).cpustat.system += sys_ticks;
 		else if (atomic_read(&nr_iowait_tasks) > 0)
-			kstat.per_cpu_iowait[cpu] += sys_ticks;
+			kstat_cpu(cpu).cpustat.iowait += sys_ticks;
 		else
-			kstat.per_cpu_idle[cpu] += sys_ticks;
+			kstat_cpu(cpu).cpustat.idle += sys_ticks;
 #if CONFIG_SMP
 		idle_tick(rq);
 #endif
 		return;
 	}
 	if (TASK_NICE(p) > 0)
-		kstat.per_cpu_nice[cpu] += user_ticks;
+		kstat_cpu(cpu).cpustat.nice += user_ticks;
 	else
-		kstat.per_cpu_user[cpu] += user_ticks;
-	kstat.per_cpu_system[cpu] += sys_ticks;
+		kstat_cpu(cpu).cpustat.user += user_ticks;
+	kstat_cpu(cpu).cpustat.system += sys_ticks;
 
 	/* Task might have expired already, but not scheduled off yet */
 	if (p->array != rq->active) {
@@ -2112,11 +2114,44 @@
 spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
 #endif
 
+static void kstat_init_cpu(int cpu)
+{
+        /* Add any initialisation to kstat here */
+        /* Useful when cpu offlining logic is added.. */
+}
+
+static int __devinit kstat_cpu_notify(struct notifier_block *self,
+                                unsigned long action, void *hcpu)
+{
+	int cpu = (unsigned long)hcpu;
+	switch(action) {
+	case CPU_UP_PREPARE:
+		kstat_init_cpu(cpu);
+		break;
+	default:
+		break;
+	}
+	return NOTIFY_OK;
+}
+ 
+static struct notifier_block __devinitdata kstat_nb = {
+	.notifier_call  = kstat_cpu_notify,
+	.next           = NULL,
+};
+
+__init static void init_kstat(void) {
+	kstat_cpu_notify(&kstat_nb, (unsigned long)CPU_UP_PREPARE,
+			(void *)(long)smp_processor_id());
+	register_cpu_notifier(&kstat_nb);  
+}
+
 void __init sched_init(void)
 {
 	runqueue_t *rq;
 	int i, j, k;
 
+	/* Init the kstat counters */
+	init_kstat();
 	for (i = 0; i < NR_CPUS; i++) {
 		prio_array_t *array;
 
diff -Nru a/kernel/sys.c b/kernel/sys.c
--- a/kernel/sys.c	Mon Nov  4 14:31:00 2002
+++ b/kernel/sys.c	Mon Nov  4 14:31:00 2002
@@ -204,6 +204,8 @@
 cond_syscall(sys_quotactl)
 cond_syscall(sys_acct)
 cond_syscall(sys_lookup_dcookie)
+cond_syscall(sys_swapon)
+cond_syscall(sys_swapoff)
 
 static int set_one_prio(struct task_struct *p, int niceval, int error)
 {
diff -Nru a/kernel/timer.c b/kernel/timer.c
--- a/kernel/timer.c	Mon Nov  4 14:31:01 2002
+++ b/kernel/timer.c	Mon Nov  4 14:31:01 2002
@@ -409,7 +409,6 @@
 /* Don't completely fail for HZ > 500.  */
 int tickadj = 500/HZ ? : 1;		/* microsecs */
 
-struct kernel_stat kstat;
 
 /*
  * phase-lock loop variables
diff -Nru a/lib/kobject.c b/lib/kobject.c
--- a/lib/kobject.c	Mon Nov  4 14:31:02 2002
+++ b/lib/kobject.c	Mon Nov  4 14:31:02 2002
@@ -2,9 +2,10 @@
  * kobject.c - library routines for handling generic kernel objects
  */
 
-#define DEBUG 1
+#define DEBUG 0
 
 #include <linux/kobject.h>
+#include <linux/string.h>
 #include <linux/module.h>
 #include <linux/stat.h>
 
@@ -76,11 +77,13 @@
 		}
 		up_write(&s->rwsem);
 	}
-	error = sysfs_create_dir(kobj);
-	if (!error) {
-		error = kobject_populate_dir(kobj);
-		if (error)
-			sysfs_remove_dir(kobj);
+	if (strlen(kobj->name)) {
+		error = sysfs_create_dir(kobj);
+		if (!error) {
+			error = kobject_populate_dir(kobj);
+			if (error)
+				sysfs_remove_dir(kobj);
+		}
 	}
 	return error;
 }
diff -Nru a/lib/rwsem-spinlock.c b/lib/rwsem-spinlock.c
--- a/lib/rwsem-spinlock.c	Mon Nov  4 14:31:01 2002
+++ b/lib/rwsem-spinlock.c	Mon Nov  4 14:31:01 2002
@@ -290,7 +290,7 @@
  */
 void __downgrade_write(struct rw_semaphore *sem)
 {
-	rwsemtrace(sem,"Entering __rwsem_downgrade");
+	rwsemtrace(sem,"Entering __downgrade_write");
 
 	spin_lock(&sem->wait_lock);
 
@@ -300,7 +300,7 @@
 
 	spin_unlock(&sem->wait_lock);
 
-	rwsemtrace(sem,"Leaving __rwsem_downgrade");
+	rwsemtrace(sem,"Leaving __downgrade_write");
 }
 
 EXPORT_SYMBOL(init_rwsem);
diff -Nru a/mm/Makefile b/mm/Makefile
--- a/mm/Makefile	Mon Nov  4 14:31:02 2002
+++ b/mm/Makefile	Mon Nov  4 14:31:02 2002
@@ -4,11 +4,12 @@
 
 export-objs := shmem.o filemap.o mempool.o page_alloc.o page-writeback.o
 
-obj-y	 := memory.o mmap.o filemap.o mprotect.o mlock.o mremap.o \
-	    vmalloc.o slab.o bootmem.o swap.o vmscan.o page_io.o \
-	    page_alloc.o swap_state.o swapfile.o oom_kill.o \
-	    shmem.o highmem.o mempool.o msync.o mincore.o readahead.o \
-	    pdflush.o page-writeback.o rmap.o madvise.o vcache.o \
-	    truncate.o
+obj-y	 := memory.o mmap.o filemap.o fremap.o mprotect.o mlock.o mremap.o \
+	    vmalloc.o slab.o bootmem.o swap.o vmscan.o page_alloc.o \
+	    oom_kill.o shmem.o highmem.o mempool.o msync.o mincore.o \
+	    readahead.o pdflush.o page-writeback.o rmap.o madvise.o \
+	    vcache.o truncate.o
+
+obj-$(CONFIG_SWAP)	+= page_io.o swap_state.o swapfile.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/mm/filemap.c b/mm/filemap.c
--- a/mm/filemap.c	Mon Nov  4 14:31:01 2002
+++ b/mm/filemap.c	Mon Nov  4 14:31:01 2002
@@ -9,6 +9,7 @@
  * most "normal" filesystems (but you don't /have/ to use this:
  * the NFS filesystem used to do this differently, for example)
  */
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/compiler.h>
@@ -248,37 +249,6 @@
 }
 
 /*
- * This adds the requested page to the page cache if it isn't already there,
- * and schedules an I/O to read in its contents from disk.
- */
-static int FASTCALL(page_cache_read(struct file * file, unsigned long offset));
-static int page_cache_read(struct file * file, unsigned long offset)
-{
-	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
-	struct page *page; 
-	int error;
-
-	page = page_cache_alloc_cold(mapping);
-	if (!page)
-		return -ENOMEM;
-
-	error = add_to_page_cache_lru(page, mapping, offset);
-	if (!error) {
-		error = mapping->a_ops->readpage(file, page);
-		page_cache_release(page);
-		return error;
-	}
-
-	/*
-	 * We arrive here in the unlikely event that someone 
-	 * raced with us and added our page to the cache first
-	 * or we are out of memory for radix-tree nodes.
-	 */
-	page_cache_release(page);
-	return error == -EEXIST ? 0 : error;
-}
-
-/*
  * In order to wait for pages to become available there must be
  * waitqueues associated with pages. By using a hash table of
  * waitqueues where the bucket discipline is to maintain all
@@ -288,7 +258,7 @@
  * at a cost of "thundering herd" phenomena during rare hash
  * collisions.
  */
-static inline wait_queue_head_t *page_waitqueue(struct page *page)
+static wait_queue_head_t *page_waitqueue(struct page *page)
 {
 	const struct zone *zone = page_zone(page);
 
@@ -550,24 +520,6 @@
 }
 
 /*
- * Mark a page as having seen activity.
- *
- * inactive,unreferenced	->	inactive,referenced
- * inactive,referenced		->	active,unreferenced
- * active,unreferenced		->	active,referenced
- */
-void mark_page_accessed(struct page *page)
-{
-	if (!PageActive(page) && PageReferenced(page)) {
-		activate_page(page);
-		ClearPageReferenced(page);
-		return;
-	} else if (!PageReferenced(page)) {
-		SetPageReferenced(page);
-	}
-}
-
-/*
  * This is a generic file read routine, and uses the
  * inode->i_op->readpage() function for the actual low-level
  * stuff.
@@ -758,7 +710,7 @@
 	return ret;
 }
 
-static inline void fault_in_pages_readable(const char *uaddr, int size)
+static void fault_in_pages_readable(const char *uaddr, int size)
 {
 	volatile char c;
 	int ret;
@@ -996,6 +948,38 @@
 	return ret;
 }
 
+#ifdef CONFIG_MMU
+/*
+ * This adds the requested page to the page cache if it isn't already there,
+ * and schedules an I/O to read in its contents from disk.
+ */
+static int FASTCALL(page_cache_read(struct file * file, unsigned long offset));
+static int page_cache_read(struct file * file, unsigned long offset)
+{
+	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
+	struct page *page; 
+	int error;
+
+	page = page_cache_alloc_cold(mapping);
+	if (!page)
+		return -ENOMEM;
+
+	error = add_to_page_cache_lru(page, mapping, offset);
+	if (!error) {
+		error = mapping->a_ops->readpage(file, page);
+		page_cache_release(page);
+		return error;
+	}
+
+	/*
+	 * We arrive here in the unlikely event that someone 
+	 * raced with us and added our page to the cache first
+	 * or we are out of memory for radix-tree nodes.
+	 */
+	page_cache_release(page);
+	return error == -EEXIST ? 0 : error;
+}
+
 /*
  * filemap_nopage() is invoked via the vma operations vector for a
  * mapped memory region to read in file data during a page fault.
@@ -1004,7 +988,6 @@
  * it in the page cache, and handles the special cases reasonably without
  * having a lot of duplicated code.
  */
-
 struct page * filemap_nopage(struct vm_area_struct * area, unsigned long address, int unused)
 {
 	int error;
@@ -1166,8 +1149,159 @@
 	return NULL;
 }
 
+static struct page * filemap_getpage(struct file *file, unsigned long pgoff,
+					int nonblock)
+{
+	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
+	struct page *page;
+	int error;
+
+	/*
+	 * Do we have something in the page cache already?
+	 */
+retry_find:
+	page = find_get_page(mapping, pgoff);
+	if (!page) {
+		if (nonblock)
+			return NULL;
+		goto no_cached_page;
+	}
+
+	/*
+	 * Ok, found a page in the page cache, now we need to check
+	 * that it's up-to-date.
+	 */
+	if (!PageUptodate(page))
+		goto page_not_uptodate;
+
+success:
+	/*
+	 * Found the page and have a reference on it, need to check sharing
+	 * and possibly copy it over to another page..
+	 */
+	mark_page_accessed(page);
+	flush_page_to_ram(page);
+
+	return page;
+
+no_cached_page:
+	error = page_cache_read(file, pgoff);
+
+	/*
+	 * The page we want has now been added to the page cache.
+	 * In the unlikely event that someone removed it in the
+	 * meantime, we'll just come back here and read it again.
+	 */
+	if (error >= 0)
+		goto retry_find;
+
+	/*
+	 * An error return from page_cache_read can result if the
+	 * system is low on memory, or a problem occurs while trying
+	 * to schedule I/O.
+	 */
+	return NULL;
+
+page_not_uptodate:
+	lock_page(page);
+
+	/* Did it get unhashed while we waited for it? */
+	if (!page->mapping) {
+		unlock_page(page);
+		goto err;
+	}
+
+	/* Did somebody else get it up-to-date? */
+	if (PageUptodate(page)) {
+		unlock_page(page);
+		goto success;
+	}
+
+	if (!mapping->a_ops->readpage(file, page)) {
+		wait_on_page_locked(page);
+		if (PageUptodate(page))
+			goto success;
+	}
+
+	/*
+	 * Umm, take care of errors if the page isn't up-to-date.
+	 * Try to re-read it _once_. We do this synchronously,
+	 * because there really aren't any performance issues here
+	 * and we need to check for errors.
+	 */
+	lock_page(page);
+
+	/* Somebody truncated the page on us? */
+	if (!page->mapping) {
+		unlock_page(page);
+		goto err;
+	}
+	/* Somebody else successfully read it in? */
+	if (PageUptodate(page)) {
+		unlock_page(page);
+		goto success;
+	}
+
+	ClearPageError(page);
+	if (!mapping->a_ops->readpage(file, page)) {
+		wait_on_page_locked(page);
+		if (PageUptodate(page))
+			goto success;
+	}
+
+	/*
+	 * Things didn't work out. Return zero to tell the
+	 * mm layer so, possibly freeing the page cache page first.
+	 */
+err:
+	page_cache_release(page);
+
+	return NULL;
+}
+
+static int filemap_populate(struct vm_area_struct *vma,
+			unsigned long addr,
+			unsigned long len,
+			unsigned long prot,
+			unsigned long pgoff,
+			int nonblock)
+{
+	struct file *file = vma->vm_file;
+	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
+	struct inode *inode = mapping->host;
+	unsigned long size;
+	struct mm_struct *mm = vma->vm_mm;
+	struct page *page;
+	int err;
+
+repeat:
+	size = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+	if (pgoff + (len >> PAGE_CACHE_SHIFT) > size)
+		return -EINVAL;
+
+	page = filemap_getpage(file, pgoff, nonblock);
+	if (!page && !nonblock)
+		return -ENOMEM;
+	if (page) {
+		err = install_page(mm, vma, addr, page, prot);
+		if (err) {
+			page_cache_release(page);
+			return err;
+		}
+	}
+
+	len -= PAGE_SIZE;
+	addr += PAGE_SIZE;
+	pgoff++;
+	if (len)
+		goto repeat;
+
+	return 0;
+}
+
 static struct vm_operations_struct generic_file_vm_ops = {
 	.nopage		= filemap_nopage,
+	.populate	= filemap_populate,
 };
 
 /* This is used for a general mmap of a disk file */
@@ -1187,6 +1321,12 @@
 	vma->vm_ops = &generic_file_vm_ops;
 	return 0;
 }
+#else
+int generic_file_mmap(struct file * file, struct vm_area_struct * vma)
+{
+	return -ENOSYS;
+}
+#endif /* CONFIG_MMU */
 
 static inline struct page *__read_cache_page(struct address_space *mapping,
 				unsigned long index,
@@ -1296,7 +1436,7 @@
 	return page;
 }
 
-inline void remove_suid(struct dentry *dentry)
+void remove_suid(struct dentry *dentry)
 {
 	struct iattr newattrs;
 	struct inode *inode = dentry->d_inode;
@@ -1332,7 +1472,7 @@
 	return left;
 }
 
-static inline int
+static int
 __filemap_copy_from_user_iovec(char *vaddr, 
 			const struct iovec *iov, size_t base, size_t bytes)
 {
diff -Nru a/mm/fremap.c b/mm/fremap.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/mm/fremap.c	Mon Nov  4 14:31:03 2002
@@ -0,0 +1,146 @@
+/*
+ *   linux/mm/mpopulate.c
+ * 
+ * Explicit pagetable population and nonlinear (random) mappings support.
+ *
+ * started by Ingo Molnar, Copyright (C) 2002
+ */
+
+#include <linux/mm.h>
+#include <linux/file.h>
+#include <linux/mman.h>
+#include <linux/pagemap.h>
+#include <linux/swapops.h>
+#include <asm/mmu_context.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+
+static inline void zap_pte(struct mm_struct *mm, pte_t *ptep)
+{
+	pte_t pte = *ptep;
+
+	if (pte_none(pte))
+		return;
+	if (pte_present(pte)) {
+		unsigned long pfn = pte_pfn(pte);
+
+		pte = ptep_get_and_clear(ptep);
+		if (pfn_valid(pfn)) {
+			struct page *page = pfn_to_page(pfn);
+			if (!PageReserved(page)) {
+				if (pte_dirty(pte))
+					set_page_dirty(page);
+				page_remove_rmap(page, ptep);
+				page_cache_release(page);
+				mm->rss--;
+			}
+		}
+	} else {
+		free_swap_and_cache(pte_to_swp_entry(pte));
+		pte_clear(ptep);
+	}
+}
+
+/*
+ * Install a page to a given virtual memory address, release any
+ * previously existing mapping.
+ */
+int install_page(struct mm_struct *mm, struct vm_area_struct *vma,
+		unsigned long addr, struct page *page, unsigned long prot)
+{
+	int err = -ENOMEM;
+	pte_t *pte, entry;
+	pgd_t *pgd;
+	pmd_t *pmd;
+
+	pgd = pgd_offset(mm, addr);
+	spin_lock(&mm->page_table_lock);
+
+	pmd = pmd_alloc(mm, pgd, addr);
+	if (!pmd)
+		goto err_unlock;
+
+	pte = pte_alloc_map(mm, pmd, addr);
+	if (!pte)
+		goto err_unlock;
+
+	zap_pte(mm, pte);
+
+	mm->rss++;
+	flush_page_to_ram(page);
+	flush_icache_page(vma, page);
+	entry = mk_pte(page, protection_map[prot]);
+	if (prot & PROT_WRITE)
+		entry = pte_mkwrite(pte_mkdirty(entry));
+	set_pte(pte, entry);
+	page_add_rmap(page, pte);
+	pte_unmap(pte);
+	flush_tlb_page(vma, addr);
+
+	spin_unlock(&mm->page_table_lock);
+
+	return 0;
+
+err_unlock:
+	spin_unlock(&mm->page_table_lock);
+	return err;
+}
+
+/***
+ * sys_remap_file_pages - remap arbitrary pages of a shared backing store
+ *                        file within an existing vma.
+ * @start: start of the remapped virtual memory range
+ * @size: size of the remapped virtual memory range
+ * @prot: new protection bits of the range
+ * @pgoff: to be mapped page of the backing store file
+ * @flags: 0 or MAP_NONBLOCKED - the later will cause no IO.
+ *
+ * this syscall works purely via pagetables, so it's the most efficient
+ * way to map the same (large) file into a given virtual window. Unlike
+ * mremap()/mmap() it does not create any new vmas.
+ *
+ * The new mappings do not live across swapout, so either use MAP_LOCKED
+ * or use PROT_NONE in the original linear mapping and add a special
+ * SIGBUS pagefault handler to reinstall zapped mappings.
+ */
+int sys_remap_file_pages(unsigned long start, unsigned long size,
+	unsigned long prot, unsigned long pgoff, unsigned long flags)
+{
+	struct mm_struct *mm = current->mm;
+	unsigned long end = start + size;
+	struct vm_area_struct *vma;
+	int err = -EINVAL;
+
+	/*
+	 * Sanitize the syscall parameters:
+	 */
+	start = PAGE_ALIGN(start);
+	size = PAGE_ALIGN(size);
+	prot &= 0xf;
+
+	down_read(&mm->mmap_sem);
+
+	vma = find_vma(mm, start);
+	/*
+	 * Make sure the vma is shared, that it supports prefaulting,
+	 * and that the remapped range is valid and fully within
+	 * the single existing vma:
+	 */
+	if (vma && (vma->vm_flags & VM_SHARED) &&
+		vma->vm_ops && vma->vm_ops->populate &&
+			end > start && start >= vma->vm_start &&
+				end <= vma->vm_end) {
+		/*
+		 * Change the default protection to PROT_NONE:
+		 */
+		if (pgprot_val(vma->vm_page_prot) != pgprot_val(__S000))
+			vma->vm_page_prot = __S000;
+		err = vma->vm_ops->populate(vma, start, size, prot,
+						pgoff, flags & MAP_NONBLOCK);
+	}
+
+	up_read(&mm->mmap_sem);
+
+	return err;
+}
+
diff -Nru a/mm/highmem.c b/mm/highmem.c
--- a/mm/highmem.c	Mon Nov  4 14:31:02 2002
+++ b/mm/highmem.c	Mon Nov  4 14:31:02 2002
@@ -229,7 +229,7 @@
 /*
  * highmem version, map in to vec
  */
-static inline void bounce_copy_vec(struct bio_vec *to, unsigned char *vfrom)
+static void bounce_copy_vec(struct bio_vec *to, unsigned char *vfrom)
 {
 	unsigned long flags;
 	unsigned char *vto;
@@ -272,7 +272,7 @@
  * queue gfp mask set, *to may or may not be a highmem page. kmap it
  * always, it will do the Right Thing
  */
-static inline void copy_to_high_bio_irq(struct bio *to, struct bio *from)
+static void copy_to_high_bio_irq(struct bio *to, struct bio *from)
 {
 	unsigned char *vfrom;
 	struct bio_vec *tovec, *fromvec;
@@ -338,7 +338,7 @@
 	return 0;
 }
 
-static inline void __bounce_end_io_read(struct bio *bio, mempool_t *pool)
+static void __bounce_end_io_read(struct bio *bio, mempool_t *pool)
 {
 	struct bio *bio_orig = bio->bi_private;
 
diff -Nru a/mm/memory.c b/mm/memory.c
--- a/mm/memory.c	Mon Nov  4 14:31:01 2002
+++ b/mm/memory.c	Mon Nov  4 14:31:01 2002
@@ -38,6 +38,7 @@
 
 #include <linux/kernel_stat.h>
 #include <linux/mm.h>
+#include <linux/hugetlb.h>
 #include <linux/mman.h>
 #include <linux/swap.h>
 #include <linux/highmem.h>
@@ -397,6 +398,11 @@
 {
 	pgd_t * dir;
 
+	if (is_vm_hugetlb_page(vma)) {
+		unmap_hugepage_range(vma, address, end);
+		return;
+	}
+
 	BUG_ON(address >= end);
 
 	dir = pgd_offset(vma->vm_mm, address);
@@ -436,6 +442,11 @@
 	mmu_gather_t *tlb;
 	unsigned long end, block;
 
+	if (is_vm_hugetlb_page(vma)) {
+		zap_hugepage_range(vma, address, size);
+		return;
+	}
+
 	spin_lock(&mm->page_table_lock);
 
   	/*
@@ -573,6 +584,7 @@
 					i = -EFAULT;
 					goto out;
 				}
+				flush_dcache_page(pages[i]);
 				if (!PageReserved(pages[i]))
 					page_cache_get(pages[i]);
 			}
@@ -588,7 +600,7 @@
 	return i;
 }
 
-static inline void zeromap_pte_range(pte_t * pte, unsigned long address,
+static void zeromap_pte_range(pte_t * pte, unsigned long address,
                                      unsigned long size, pgprot_t prot)
 {
 	unsigned long end;
@@ -830,7 +842,7 @@
 		page_remove_rmap(old_page, page_table);
 		break_cow(vma, new_page, address, page_table);
 		page_add_rmap(new_page, page_table);
-		lru_cache_add(new_page);
+		lru_cache_add_active(new_page);
 
 		/* Free the old page.. */
 		new_page = old_page;
@@ -955,12 +967,13 @@
 	num = valid_swaphandles(entry, &offset);
 	for (i = 0; i < num; offset++, i++) {
 		/* Ok, do the async read-ahead now */
-		new_page = read_swap_cache_async(swp_entry(swp_type(entry), offset));
+		new_page = read_swap_cache_async(swp_entry(swp_type(entry),
+						offset));
 		if (!new_page)
 			break;
 		page_cache_release(new_page);
 	}
-	return;
+	lru_add_drain();	/* Push any new pages onto the LRU now */
 }
 
 /*
@@ -995,7 +1008,7 @@
 				ret = VM_FAULT_MINOR;
 			pte_unmap(page_table);
 			spin_unlock(&mm->page_table_lock);
-			return ret;
+			goto out;
 		}
 
 		/* Had to read the page from swap area: Major fault */
@@ -1017,7 +1030,8 @@
 		spin_unlock(&mm->page_table_lock);
 		unlock_page(page);
 		page_cache_release(page);
-		return VM_FAULT_MINOR;
+		ret = VM_FAULT_MINOR;
+		goto out;
 	}
 
 	/* The page isn't present yet, go ahead with the fault. */
@@ -1041,6 +1055,7 @@
 	update_mmu_cache(vma, address, pte);
 	pte_unmap(page_table);
 	spin_unlock(&mm->page_table_lock);
+out:
 	return ret;
 }
 
@@ -1080,7 +1095,7 @@
 		mm->rss++;
 		flush_page_to_ram(page);
 		entry = pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
-		lru_cache_add(page);
+		lru_cache_add_active(page);
 		mark_page_accessed(page);
 	}
 
@@ -1139,7 +1154,7 @@
 		}
 		copy_user_highpage(page, new_page, address);
 		page_cache_release(new_page);
-		lru_cache_add(page);
+		lru_cache_add_active(page);
 		new_page = page;
 	}
 
diff -Nru a/mm/mmap.c b/mm/mmap.c
--- a/mm/mmap.c	Mon Nov  4 14:31:02 2002
+++ b/mm/mmap.c	Mon Nov  4 14:31:02 2002
@@ -16,6 +16,7 @@
 #include <linux/fs.h>
 #include <linux/personality.h>
 #include <linux/security.h>
+#include <linux/hugetlb.h>
 #include <linux/profile.h>
 
 #include <asm/uaccess.h>
@@ -95,7 +96,7 @@
 		 * this compensates for the swap-space over-allocation
 		 * (ie "nr_swap_pages" being too small).
 		 */
-		free += swapper_space.nrpages;
+		free += total_swapcache_pages;
 
 		/*
 		 * The code below doesn't account for free space in the
@@ -132,7 +133,7 @@
 }
 
 /* Remove one vm structure from the inode's i_mapping address space. */
-static inline void remove_shared_vm_struct(struct vm_area_struct *vma)
+static void remove_shared_vm_struct(struct vm_area_struct *vma)
 {
 	struct file *file = vma->vm_file;
 
@@ -301,7 +302,7 @@
 	}
 }
 
-static inline void __vma_link_rb(struct mm_struct * mm, struct vm_area_struct * vma,
+static void __vma_link_rb(struct mm_struct * mm, struct vm_area_struct * vma,
 				 struct rb_node ** rb_link, struct rb_node * rb_parent)
 {
 	rb_link_node(&vma->vm_rb, rb_parent, rb_link);
@@ -335,8 +336,9 @@
 	__vma_link_file(vma);
 }
 
-static inline void vma_link(struct mm_struct * mm, struct vm_area_struct * vma, struct vm_area_struct * prev,
-			    struct rb_node ** rb_link, struct rb_node * rb_parent)
+static void vma_link(struct mm_struct *mm, struct vm_area_struct *vma,
+			struct vm_area_struct *prev, struct rb_node **rb_link,
+			struct rb_node *rb_parent)
 {
 	struct address_space *mapping = NULL;
 
@@ -606,6 +608,12 @@
 		mm->locked_vm += len >> PAGE_SHIFT;
 		make_pages_present(addr, addr + len);
 	}
+	if (flags & MAP_POPULATE) {
+		up_write(&mm->mmap_sem);
+		sys_remap_file_pages(addr, len, prot,
+					pgoff, flags & MAP_NONBLOCK);
+		down_write(&mm->mmap_sem);
+	}
 	return addr;
 
 unmap_and_free_vma:
@@ -638,24 +646,33 @@
 #ifndef HAVE_ARCH_UNMAPPED_AREA
 static inline unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
 {
+	struct mm_struct *mm = current->mm;
 	struct vm_area_struct *vma;
+	int found_hole = 0;
 
 	if (len > TASK_SIZE)
 		return -ENOMEM;
 
 	if (addr) {
 		addr = PAGE_ALIGN(addr);
-		vma = find_vma(current->mm, addr);
+		vma = find_vma(mm, addr);
 		if (TASK_SIZE - len >= addr &&
 		    (!vma || addr + len <= vma->vm_start))
 			return addr;
 	}
-	addr = PAGE_ALIGN(TASK_UNMAPPED_BASE);
+	addr = mm->free_area_cache;
 
-	for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
+	for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
 		/* At this point:  (!vma || addr < vma->vm_end). */
 		if (TASK_SIZE - len < addr)
 			return -ENOMEM;
+		/*
+		 * Record the first available hole.
+		 */
+		if (!found_hole && (!vma || addr < vma->vm_start)) {
+			mm->free_area_cache = addr;
+			found_hole = 1;
+		}
 		if (!vma || addr + len <= vma->vm_start)
 			return addr;
 		addr = vma->vm_end;
@@ -939,13 +956,19 @@
  * By the time this function is called, the area struct has been
  * removed from the process mapping list.
  */
-static void unmap_vma(struct mm_struct *mm, struct vm_area_struct *area)
+void unmap_vma(struct mm_struct *mm, struct vm_area_struct *area)
 {
 	size_t len = area->vm_end - area->vm_start;
 
 	area->vm_mm->total_vm -= len >> PAGE_SHIFT;
 	if (area->vm_flags & VM_LOCKED)
 		area->vm_mm->locked_vm -= len >> PAGE_SHIFT;
+	/*
+	 * Is this a new hole at the lowest possible address?
+	 */
+	if (area->vm_start >= TASK_UNMAPPED_BASE &&
+				area->vm_start < area->vm_mm->free_area_cache)
+	      area->vm_mm->free_area_cache = area->vm_start;
 
 	remove_shared_vm_struct(area);
 
@@ -1024,14 +1047,10 @@
 	touched = NULL;
 	do {
 		struct vm_area_struct *next = mpnt->vm_next;
-		if (!(is_vm_hugetlb_page(mpnt))) {
-			mpnt->vm_next = touched;
-			touched = mpnt;
-			rb_erase(&mpnt->vm_rb, &mm->mm_rb);
-			mm->map_count--;
-		}
-		else
-			free_hugepages(mpnt);
+		mpnt->vm_next = touched;
+		touched = mpnt;
+		rb_erase(&mpnt->vm_rb, &mm->mm_rb);
+		mm->map_count--;
 		mpnt = next;
 	} while (mpnt && mpnt->vm_start < end);
 	*npp = mpnt;
@@ -1264,8 +1283,6 @@
 
 	profile_exit_mmap(mm);
  
-	release_segments(mm);
- 
 	spin_lock(&mm->page_table_lock);
 
 	tlb = tlb_gather_mmu(mm, 1);
@@ -1284,10 +1301,7 @@
 			vm_unacct_memory((end - start) >> PAGE_SHIFT);
 
 		mm->map_count--;
-		if (!(is_vm_hugetlb_page(mpnt)))
-			unmap_page_range(tlb, mpnt, start, end);
-		else
-			mpnt->vm_ops->close(mpnt);
+		unmap_page_range(tlb, mpnt, start, end);
 		mpnt = mpnt->vm_next;
 	}
 
diff -Nru a/mm/mprotect.c b/mm/mprotect.c
--- a/mm/mprotect.c	Mon Nov  4 14:31:01 2002
+++ b/mm/mprotect.c	Mon Nov  4 14:31:01 2002
@@ -9,6 +9,7 @@
  */
 
 #include <linux/mm.h>
+#include <linux/hugetlb.h>
 #include <linux/slab.h>
 #include <linux/shm.h>
 #include <linux/mman.h>
diff -Nru a/mm/mremap.c b/mm/mremap.c
--- a/mm/mremap.c	Mon Nov  4 14:31:02 2002
+++ b/mm/mremap.c	Mon Nov  4 14:31:02 2002
@@ -8,6 +8,7 @@
  */
 
 #include <linux/mm.h>
+#include <linux/hugetlb.h>
 #include <linux/slab.h>
 #include <linux/shm.h>
 #include <linux/mman.h>
@@ -20,7 +21,7 @@
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 
-static inline pte_t *get_one_pte_map_nested(struct mm_struct *mm, unsigned long addr)
+static pte_t *get_one_pte_map_nested(struct mm_struct *mm, unsigned long addr)
 {
 	pgd_t * pgd;
 	pmd_t * pmd;
@@ -80,7 +81,7 @@
 	return pte;
 }
 
-static inline int copy_one_pte(struct mm_struct *mm, pte_t * src, pte_t * dst)
+static int copy_one_pte(struct mm_struct *mm, pte_t * src, pte_t * dst)
 {
 	int error = 0;
 	pte_t pte;
@@ -169,7 +170,7 @@
 	return -1;
 }
 
-static inline unsigned long move_vma(struct vm_area_struct * vma,
+static unsigned long move_vma(struct vm_area_struct * vma,
 	unsigned long addr, unsigned long old_len, unsigned long new_len,
 	unsigned long new_addr)
 {
diff -Nru a/mm/msync.c b/mm/msync.c
--- a/mm/msync.c	Mon Nov  4 14:31:01 2002
+++ b/mm/msync.c	Mon Nov  4 14:31:01 2002
@@ -39,7 +39,7 @@
 	return 0;
 }
 
-static inline int filemap_sync_pte_range(pmd_t * pmd,
+static int filemap_sync_pte_range(pmd_t * pmd,
 	unsigned long address, unsigned long end, 
 	struct vm_area_struct *vma, unsigned int flags)
 {
diff -Nru a/mm/page_alloc.c b/mm/page_alloc.c
--- a/mm/page_alloc.c	Mon Nov  4 14:31:00 2002
+++ b/mm/page_alloc.c	Mon Nov  4 14:31:00 2002
@@ -29,6 +29,10 @@
 #include <linux/slab.h>
 #include <linux/notifier.h>
 
+#include <asm/topology.h>
+
+DECLARE_BITMAP(node_online_map, MAX_NUMNODES);
+DECLARE_BITMAP(memblk_online_map, MAX_NR_MEMBLKS);
 struct pglist_data *pgdat_list;
 unsigned long totalram_pages;
 unsigned long totalhigh_pages;
@@ -51,7 +55,7 @@
 /*
  * Temporary debugging check for pages not lying within a given zone.
  */
-static inline int bad_range(struct zone *zone, struct page *page)
+static int bad_range(struct zone *zone, struct page *page)
 {
 	if (page_to_pfn(page) >= zone->zone_start_pfn + zone->spanned_pages)
 		return 1;
@@ -209,14 +213,29 @@
 	return page;
 }
 
+static inline void set_page_refs(struct page *page, int order)
+{
+#ifdef CONFIG_MMU
+	set_page_count(page, 1);
+#else
+	int i;
+
+	/*
+	 * We need to reference all the pages for this order, otherwise if
+	 * anyone accesses one of the pages with (get/put) it will be freed.
+	 */
+	for (i = 0; i < (1 << order); i++)
+		set_page_count(page+i, 1);
+#endif /* CONFIG_MMU */
+}
+
 /*
  * This page is about to be returned from the page allocator
  */
-static void prep_new_page(struct page *page)
+static void prep_new_page(struct page *page, int order)
 {
-	if (	page->mapping ||
-		page_mapped(page) ||
-		(page->flags & (
+	if (page->mapping || page_mapped(page) ||
+	    (page->flags & (
 			1 << PG_private	|
 			1 << PG_locked	|
 			1 << PG_lru	|
@@ -228,7 +247,7 @@
 	page->flags &= ~(1 << PG_uptodate | 1 << PG_error |
 			1 << PG_referenced | 1 << PG_arch_1 |
 			1 << PG_checked);
-	set_page_count(page, 1);
+	set_page_refs(page, order);
 }
 
 /* 
@@ -295,7 +314,7 @@
 	list_for_each(curr, &temp) {
 		page = list_entry(curr, struct page, list);
 		BUG_ON(bad_range(zone, page));
-		prep_new_page(page);
+		prep_new_page(page, order);
 	}
 	list_splice(&temp, list->prev);
 	return allocated;
@@ -386,7 +405,7 @@
 
 	if (page != NULL) {
 		BUG_ON(bad_range(zone, page));
-		prep_new_page(page);
+		prep_new_page(page, order);
 	}
 	return page;
 }
@@ -461,7 +480,7 @@
 	/* here we're in the low on memory slow path */
 
 rebalance:
-	if (current->flags & (PF_MEMALLOC | PF_MEMDIE)) {
+	if ((current->flags & (PF_MEMALLOC | PF_MEMDIE)) && !in_interrupt()) {
 		/* go through the zonelist yet again, ignoring mins */
 		for (i = 0; zones[i] != NULL; i++) {
 			struct zone *z = zones[i];
@@ -470,13 +489,6 @@
 			if (page)
 				return page;
 		}
-nopage:
-		if (!(current->flags & PF_NOWARN)) {
-			printk("%s: page allocation failure."
-				" order:%d, mode:0x%x\n",
-				current->comm, order, gfp_mask);
-		}
-		return NULL;
 	}
 
 	/* Atomic allocations - we can't balance anything */
@@ -502,13 +514,21 @@
 		}
 	}
 
-	/* Don't let big-order allocations loop */
-	if (order > 3)
-		goto nopage;
+	/*
+	 * Don't let big-order allocations loop.  Yield for kswapd, try again.
+	 */
+	if (order <= 3) {
+		yield();
+		goto rebalance;
+	}
 
-	/* Yield for kswapd, and try again */
-	yield();
-	goto rebalance;
+nopage:
+	if (!(current->flags & PF_NOWARN)) {
+		printk("%s: page allocation failure."
+			" order:%d, mode:0x%x\n",
+			current->comm, order, gfp_mask);
+	}
+	return NULL;
 }
 
 /*
@@ -594,6 +614,18 @@
 	return pages;
 }
 
+#ifdef CONFIG_NUMA
+unsigned int nr_free_pages_pgdat(pg_data_t *pgdat)
+{
+	unsigned int i, sum = 0;
+
+	for (i = 0; i < MAX_NR_ZONES; i++)
+		sum += pgdat->node_zones[i].free_pages;
+
+	return sum;
+}
+#endif
+
 static unsigned int nr_free_zone_pages(int offset)
 {
 	pg_data_t *pgdat;
@@ -721,6 +753,19 @@
 	val->mem_unit = PAGE_SIZE;
 }
 
+#ifdef CONFIG_NUMA
+void si_meminfo_node(struct sysinfo *val, int nid)
+{
+	pg_data_t *pgdat = NODE_DATA(nid);
+
+	val->totalram = pgdat->node_size;
+	val->freeram = nr_free_pages_pgdat(pgdat);
+	val->totalhigh = pgdat->node_zones[ZONE_HIGHMEM].spanned_pages;
+	val->freehigh = pgdat->node_zones[ZONE_HIGHMEM].free_pages;
+	val->mem_unit = PAGE_SIZE;
+}
+#endif
+
 #define K(x) ((x) << (PAGE_SHIFT-10))
 
 /*
@@ -1138,6 +1183,7 @@
 	pgdat->node_mem_map = node_mem_map;
 
 	free_area_init_core(pgdat, zones_size, zholes_size);
+	memblk_set_online(__node_to_memblk(nid));
 
 	calculate_zone_bitmap(pgdat, zones_size);
 }
diff -Nru a/mm/shmem.c b/mm/shmem.c
--- a/mm/shmem.c	Mon Nov  4 14:31:01 2002
+++ b/mm/shmem.c	Mon Nov  4 14:31:01 2002
@@ -53,6 +53,7 @@
 
 /* Flag allocation requirements to shmem_getpage and shmem_swp_alloc */
 enum sgp_type {
+	SGP_QUICK,	/* don't try more than file page cache lookup */
 	SGP_READ,	/* don't exceed i_size, don't allocate page */
 	SGP_CACHE,	/* don't exceed i_size, may allocate page */
 	SGP_WRITE,	/* may exceed i_size, may allocate page */
@@ -757,6 +758,8 @@
 	if (filepage && PageUptodate(filepage))
 		goto done;
 	error = 0;
+	if (sgp == SGP_QUICK)
+		goto failed;
 
 	spin_lock(&info->lock);
 	shmem_recalc_inode(inode);
@@ -949,6 +952,42 @@
 	return page;
 }
 
+static int shmem_populate(struct vm_area_struct *vma,
+	unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long pgoff, int nonblock)
+{
+	struct inode *inode = vma->vm_file->f_dentry->d_inode;
+	struct mm_struct *mm = vma->vm_mm;
+	enum sgp_type sgp = nonblock? SGP_QUICK: SGP_CACHE;
+	unsigned long size;
+
+	size = (inode->i_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+	if (pgoff >= size || pgoff + (len >> PAGE_SHIFT) > size)
+		return -EINVAL;
+	
+	while ((long) len > 0) {
+		struct page *page = NULL;
+		int err;
+		/*
+		 * Will need changing if PAGE_CACHE_SIZE != PAGE_SIZE
+		 */
+		err = shmem_getpage(inode, pgoff, &page, sgp);
+		if (err)
+			return err;
+		if (page) {
+			err = install_page(mm, vma, addr, page, prot);
+			if (err) {
+				page_cache_release(page);
+				return err;
+			}
+		}
+		len -= PAGE_SIZE;
+		addr += PAGE_SIZE;
+		pgoff++;
+	}
+	return 0;
+}
+
 void shmem_lock(struct file *file, int lock)
 {
 	struct inode *inode = file->f_dentry->d_inode;
@@ -1821,6 +1860,7 @@
 
 static struct vm_operations_struct shmem_vm_ops = {
 	.nopage		= shmem_nopage,
+	.populate	= shmem_populate,
 };
 
 static struct super_block *shmem_get_sb(struct file_system_type *fs_type,
diff -Nru a/mm/slab.c b/mm/slab.c
--- a/mm/slab.c	Mon Nov  4 14:31:02 2002
+++ b/mm/slab.c	Mon Nov  4 14:31:02 2002
@@ -2058,6 +2058,7 @@
 next_irqon:
 		local_irq_enable();
 next:
+		;
 	}
 	check_irq_on();
 	up(&cache_chain_sem);
diff -Nru a/mm/swap.c b/mm/swap.c
--- a/mm/swap.c	Mon Nov  4 14:31:01 2002
+++ b/mm/swap.c	Mon Nov  4 14:31:01 2002
@@ -22,6 +22,7 @@
 #include <linux/mm_inline.h>
 #include <linux/buffer_head.h>
 #include <linux/prefetch.h>
+#include <linux/percpu.h>
 
 /* How many pages do we try to swap or page in/out together? */
 int page_cluster;
@@ -43,15 +44,33 @@
 	spin_unlock_irq(&zone->lru_lock);
 }
 
+/*
+ * Mark a page as having seen activity.
+ *
+ * inactive,unreferenced	->	inactive,referenced
+ * inactive,referenced		->	active,unreferenced
+ * active,unreferenced		->	active,referenced
+ */
+void mark_page_accessed(struct page *page)
+{
+	if (!PageActive(page) && PageReferenced(page) && PageLRU(page)) {
+		activate_page(page);
+		ClearPageReferenced(page);
+	} else if (!PageReferenced(page)) {
+		SetPageReferenced(page);
+	}
+}
+
 /**
  * lru_cache_add: add a page to the page lists
  * @page: the page to add
  */
-static struct pagevec lru_add_pvecs[NR_CPUS];
+static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, };
+static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, };
 
 void lru_cache_add(struct page *page)
 {
-	struct pagevec *pvec = &lru_add_pvecs[get_cpu()];
+	struct pagevec *pvec = &per_cpu(lru_add_pvecs, get_cpu());
 
 	page_cache_get(page);
 	if (!pagevec_add(pvec, page))
@@ -59,12 +78,26 @@
 	put_cpu();
 }
 
+void lru_cache_add_active(struct page *page)
+{
+	struct pagevec *pvec = &per_cpu(lru_add_active_pvecs, get_cpu());
+
+	page_cache_get(page);
+	if (!pagevec_add(pvec, page))
+		__pagevec_lru_add_active(pvec);
+	put_cpu();
+}
+
 void lru_add_drain(void)
 {
-	struct pagevec *pvec = &lru_add_pvecs[get_cpu()];
+	int cpu = get_cpu();
+	struct pagevec *pvec = &per_cpu(lru_add_pvecs, cpu);
 
 	if (pagevec_count(pvec))
 		__pagevec_lru_add(pvec);
+	pvec = &per_cpu(lru_add_active_pvecs, cpu);
+	if (pagevec_count(pvec))
+		__pagevec_lru_add_active(pvec);
 	put_cpu();
 }
 
@@ -198,8 +231,6 @@
 /*
  * Add the passed pages to the LRU, then drop the caller's refcount
  * on them.  Reinitialises the caller's pagevec.
- *
- * Mapped pages go onto the active list.
  */
 void __pagevec_lru_add(struct pagevec *pvec)
 {
@@ -218,13 +249,33 @@
 		}
 		if (TestSetPageLRU(page))
 			BUG();
-		if (page_mapped(page)) {
-			if (TestSetPageActive(page))
-				BUG();
-			add_page_to_active_list(zone, page);
-		} else {
-			add_page_to_inactive_list(zone, page);
+		add_page_to_inactive_list(zone, page);
+	}
+	if (zone)
+		spin_unlock_irq(&zone->lru_lock);
+	pagevec_release(pvec);
+}
+
+void __pagevec_lru_add_active(struct pagevec *pvec)
+{
+	int i;
+	struct zone *zone = NULL;
+
+	for (i = 0; i < pagevec_count(pvec); i++) {
+		struct page *page = pvec->pages[i];
+		struct zone *pagezone = page_zone(page);
+
+		if (pagezone != zone) {
+			if (zone)
+				spin_unlock_irq(&zone->lru_lock);
+			zone = pagezone;
+			spin_lock_irq(&zone->lru_lock);
 		}
+		if (TestSetPageLRU(page))
+			BUG();
+		if (TestSetPageActive(page))
+			BUG();
+		add_page_to_active_list(zone, page);
 	}
 	if (zone)
 		spin_unlock_irq(&zone->lru_lock);
diff -Nru a/mm/swap_state.c b/mm/swap_state.c
--- a/mm/swap_state.c	Mon Nov  4 14:31:01 2002
+++ b/mm/swap_state.c	Mon Nov  4 14:31:01 2002
@@ -376,7 +376,7 @@
 			/*
 			 * Initiate read into locked page and return.
 			 */
-			lru_cache_add(new_page);
+			lru_cache_add_active(new_page);
 			swap_readpage(NULL, new_page);
 			return new_page;
 		}
diff -Nru a/mm/swapfile.c b/mm/swapfile.c
--- a/mm/swapfile.c	Mon Nov  4 14:31:01 2002
+++ b/mm/swapfile.c	Mon Nov  4 14:31:01 2002
@@ -16,7 +16,9 @@
 #include <linux/shm.h>
 #include <linux/blkdev.h>
 #include <linux/buffer_head.h>
+#include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/init.h>
 
 #include <asm/pgtable.h>
 #include <linux/swapops.h>
@@ -389,7 +391,7 @@
 }
 
 /* mmlist_lock and vma->vm_mm->page_table_lock are held */
-static inline void unuse_pmd(struct vm_area_struct * vma, pmd_t *dir,
+static void unuse_pmd(struct vm_area_struct * vma, pmd_t *dir,
 	unsigned long address, unsigned long size, unsigned long offset,
 	swp_entry_t entry, struct page* page)
 {
@@ -418,7 +420,7 @@
 }
 
 /* mmlist_lock and vma->vm_mm->page_table_lock are held */
-static inline void unuse_pgd(struct vm_area_struct * vma, pgd_t *dir,
+static void unuse_pgd(struct vm_area_struct * vma, pgd_t *dir,
 	unsigned long address, unsigned long size,
 	swp_entry_t entry, struct page* page)
 {
@@ -1121,12 +1123,35 @@
 	return 0;
 }
 
-struct seq_operations swaps_op = {
+static struct seq_operations swaps_op = {
 	.start =	swap_start,
 	.next =		swap_next,
 	.stop =		swap_stop,
 	.show =		swap_show
 };
+
+static int swaps_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &swaps_op);
+}
+
+static struct file_operations proc_swaps_operations = {
+	.open		= swaps_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release,
+};
+
+static int __init procswaps_init(void)
+{
+	struct proc_dir_entry *entry;
+
+	entry = create_proc_entry("swaps", 0, NULL);
+	if (entry)
+		entry->proc_fops = &proc_swaps_operations;
+	return 0;
+}
+__initcall(procswaps_init);
 #endif /* CONFIG_PROC_FS */
 
 /*
diff -Nru a/mm/vmalloc.c b/mm/vmalloc.c
--- a/mm/vmalloc.c	Mon Nov  4 14:31:02 2002
+++ b/mm/vmalloc.c	Mon Nov  4 14:31:02 2002
@@ -23,7 +23,7 @@
 rwlock_t vmlist_lock = RW_LOCK_UNLOCKED;
 struct vm_struct *vmlist;
 
-static inline void unmap_area_pte(pmd_t *pmd, unsigned long address,
+static void unmap_area_pte(pmd_t *pmd, unsigned long address,
 				  unsigned long size)
 {
 	unsigned long end;
@@ -56,7 +56,7 @@
 	} while (address < end);
 }
 
-static inline void unmap_area_pmd(pgd_t *dir, unsigned long address,
+static void unmap_area_pmd(pgd_t *dir, unsigned long address,
 				  unsigned long size)
 {
 	unsigned long end;
@@ -83,7 +83,7 @@
 	} while (address < end);
 }
 
-static inline int map_area_pte(pte_t *pte, unsigned long address,
+static int map_area_pte(pte_t *pte, unsigned long address,
 			       unsigned long size, pgprot_t prot,
 			       struct page ***pages)
 {
@@ -110,7 +110,7 @@
 	return 0;
 }
 
-static inline int map_area_pmd(pmd_t *pmd, unsigned long address,
+static int map_area_pmd(pmd_t *pmd, unsigned long address,
 			       unsigned long size, pgprot_t prot,
 			       struct page ***pages)
 {
diff -Nru a/mm/vmscan.c b/mm/vmscan.c
--- a/mm/vmscan.c	Mon Nov  4 14:31:00 2002
+++ b/mm/vmscan.c	Mon Nov  4 14:31:00 2002
@@ -166,7 +166,7 @@
 }
 
 /* Must be called with page's pte_chain_lock held. */
-static inline int page_mapping_inuse(struct page * page)
+static inline int page_mapping_inuse(struct page *page)
 {
 	struct address_space *mapping = page->mapping;
 
@@ -178,8 +178,14 @@
 	if (!mapping)
 		return 0;
 
+	/* Be more reluctant to reclaim swapcache than pagecache */
+	if (PageSwapCache(page))
+		return 1;
+
 	/* File is mmap'd by somebody. */
-	if (!list_empty(&mapping->i_mmap) || !list_empty(&mapping->i_mmap_shared))
+	if (!list_empty(&mapping->i_mmap))
+		return 1;
+	if (!list_empty(&mapping->i_mmap_shared))
 		return 1;
 
 	return 0;
@@ -193,7 +199,7 @@
 /*
  * shrink_list returns the number of reclaimed pages
  */
-static /* inline */ int
+static int
 shrink_list(struct list_head *page_list, unsigned int gfp_mask,
 		int *max_scan, int *nr_mapped)
 {
@@ -243,6 +249,7 @@
 
 		mapping = page->mapping;
 
+#ifdef CONFIG_SWAP
 		/*
 		 * Anonymous process memory without backing store. Try to
 		 * allocate it some swap space here.
@@ -275,6 +282,7 @@
 			}
 		}
 		pte_chain_unlock(page);
+#endif /* CONFIG_SWAP */
 
 		/*
 		 * FIXME: this is CPU-inefficient for shared mappings.
@@ -370,16 +378,21 @@
 			goto keep_locked;
 		}
 
+#ifdef CONFIG_SWAP
 		if (PageSwapCache(page)) {
 			swp_entry_t swap = { .val = page->index };
 			__delete_from_swap_cache(page);
 			write_unlock(&mapping->page_lock);
 			swap_free(swap);
-		} else {
-			__remove_from_page_cache(page);
-			write_unlock(&mapping->page_lock);
+			__put_page(page);	/* The pagecache ref */
+			goto free_it;
 		}
-		__put_page(page);	/* The pagecache ref */
+#endif /* CONFIG_SWAP */
+
+		__remove_from_page_cache(page);
+		write_unlock(&mapping->page_lock);
+		__put_page(page);
+
 free_it:
 		unlock_page(page);
 		ret++;
@@ -417,7 +430,7 @@
  * For pagecache intensive workloads, the first loop here is the hottest spot
  * in the kernel (apart from the copy_*_user functions).
  */
-static /* inline */ int
+static int
 shrink_cache(const int nr_pages, struct zone *zone,
 		unsigned int gfp_mask, int max_scan, int *nr_mapped)
 {
@@ -521,7 +534,7 @@
  * The downside is that we have to touch page->count against each page.
  * But we had to alter page->flags anyway.
  */
-static /* inline */ void
+static void
 refill_inactive_zone(struct zone *zone, const int nr_pages_in,
 			struct page_state *ps, int priority)
 {
@@ -667,7 +680,7 @@
  * pages.  This is a basic per-zone page freer.  Used by both kswapd and
  * direct reclaim.
  */
-static /* inline */ int
+static int
 shrink_zone(struct zone *zone, int max_scan, unsigned int gfp_mask,
 	const int nr_pages, int *nr_mapped, struct page_state *ps, int priority)
 {
diff -Nru a/net/bluetooth/Makefile b/net/bluetooth/Makefile
--- a/net/bluetooth/Makefile	Mon Nov  4 14:31:01 2002
+++ b/net/bluetooth/Makefile	Mon Nov  4 14:31:01 2002
@@ -10,6 +10,6 @@
 obj-$(CONFIG_BT_RFCOMM)	+= rfcomm/
 obj-$(CONFIG_BT_BNEP)	+= bnep/
 
-bluetooth-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o lib.o syms.o
+bluetooth-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o hci_proc.o lib.o syms.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
--- a/net/bluetooth/af_bluetooth.c	Mon Nov  4 14:31:01 2002
+++ b/net/bluetooth/af_bluetooth.c	Mon Nov  4 14:31:01 2002
@@ -56,6 +56,10 @@
 #define BT_DBG( A... )
 #endif
 
+#ifdef CONFIG_PROC_FS
+struct proc_dir_entry *proc_bt;
+#endif
+
 /* Bluetooth sockets */
 #define BT_MAX_PROTO	5
 static struct net_proto_family *bt_proto[BT_MAX_PROTO];
@@ -323,14 +327,14 @@
 
 extern int hci_sock_init(void);
 extern int hci_sock_cleanup(void);
+extern int hci_proc_init(void);
+extern int hci_proc_cleanup(void);
 
 static int __init bt_init(void)
 {
-	BT_INFO("Bluetooth Core ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-		 VERSION);
-	BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
+	BT_INFO("Core ver %s", VERSION);
 
-	proc_mkdir("bluetooth", NULL);
+	proc_bt = proc_mkdir("bluetooth", NULL);
 
 	/* Init socket cache */
 	bt_sock_cache = kmem_cache_create("bt_sock",
@@ -338,12 +342,15 @@
 			SLAB_HWCACHE_ALIGN, 0, 0);
 
 	if (!bt_sock_cache) {
-		BT_ERR("Bluetooth socket cache creation failed");
+		BT_ERR("Socket cache creation failed");
 		return -ENOMEM;
 	}
 	
 	sock_register(&bt_sock_family_ops);
 
+	BT_INFO("HCI device and connection manager initialized");
+
+	hci_proc_init();
 	hci_sock_init();
 	return 0;
 }
@@ -351,6 +358,7 @@
 static void __exit bt_cleanup(void)
 {
 	hci_sock_cleanup();
+	hci_proc_cleanup();
 
 	sock_unregister(PF_BLUETOOTH);
 	kmem_cache_destroy(bt_sock_cache);
diff -Nru a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
--- a/net/bluetooth/bnep/core.c	Mon Nov  4 14:31:02 2002
+++ b/net/bluetooth/bnep/core.c	Mon Nov  4 14:31:02 2002
@@ -561,6 +561,8 @@
 	else
 		strcpy(dev->name, "bnep%d");
 
+	memset(dev->broadcast, 0xff, ETH_ALEN);
+	
 	/* This is rx header therefor addresses are swaped.
 	 * ie eh.h_dest is our local address. */
 	memcpy(s->eh.h_dest,   &src, ETH_ALEN);
@@ -701,17 +703,22 @@
 }
 
 static int __init bnep_init_module(void)
-{
-	BT_INFO("BNEP: BNEP2 ver %s\n"
-		"BNEP: Copyright (C) 2002 Inventel\n"
-		"BNEP: Written 2001,2002 by\n"
-		"BNEP: \tClement Moreau <clement.moreau@inventel.fr> "
-			"David Libault <david.libault@inventel.fr>\n"
-		"BNEP: Copyright (C) 2002 Maxim Krasnyanskiy <maxk@qualcomm.com>",
-			VERSION);
+{	
+	char flt[50] = "";	
 
-	bnep_sock_init();
+#ifdef CONFIG_BT_BNEP_PROTO_FILTER
+	strcat(flt, "protocol ");
+#endif
 
+#ifdef CONFIG_BT_BNEP_MC_FILTER
+	strcat(flt, "multicast");
+#endif
+
+	BT_INFO("BNEP (Ethernet Emulation) ver %s", VERSION);
+	if (flt[0])
+		BT_INFO("BNEP filters: %s", flt);
+
+	bnep_sock_init();
 	return 0;
 }
 
@@ -723,6 +730,6 @@
 module_init(bnep_init_module);
 module_exit(bnep_cleanup_module);
 
-MODULE_DESCRIPTION("BNEP ver " VERSION);
-MODULE_AUTHOR("David Libault <david.libault@inventel.fr> Maxim Krasnyanskiy <maxk@qualcomm.com>");
+MODULE_DESCRIPTION("Bluetooth BNEP ver " VERSION);
+MODULE_AUTHOR("David Libault <david.libault@inventel.fr>, Maxim Krasnyanskiy <maxk@qualcomm.com>");
 MODULE_LICENSE("GPL");
diff -Nru a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
--- a/net/bluetooth/hci_conn.c	Mon Nov  4 14:31:03 2002
+++ b/net/bluetooth/hci_conn.c	Mon Nov  4 14:31:03 2002
@@ -215,9 +215,9 @@
 
 	BT_DBG("%s -> %s", batostr(src), batostr(dst));
 
-	read_lock_bh(&hdev_list_lock);
+	read_lock_bh(&hci_dev_list_lock);
 
-	list_for_each(p, &hdev_list) {
+	list_for_each(p, &hci_dev_list) {
 		struct hci_dev *d;
 		d = list_entry(p, struct hci_dev, list);
 		
@@ -243,7 +243,7 @@
 	if (hdev)
 		hci_dev_hold(hdev);
 
-	read_unlock_bh(&hdev_list_lock);
+	read_unlock_bh(&hci_dev_list_lock);
 	return hdev;
 }
 
diff -Nru a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
--- a/net/bluetooth/hci_core.c	Mon Nov  4 14:31:01 2002
+++ b/net/bluetooth/hci_core.c	Mon Nov  4 14:31:01 2002
@@ -66,8 +66,8 @@
 rwlock_t hci_task_lock = RW_LOCK_UNLOCKED;
 
 /* HCI device list */
-LIST_HEAD(hdev_list);
-rwlock_t hdev_list_lock = RW_LOCK_UNLOCKED;
+LIST_HEAD(hci_dev_list);
+rwlock_t hci_dev_list_lock = RW_LOCK_UNLOCKED;
 
 /* HCI protocols */
 #define HCI_MAX_PROTO	2
@@ -298,8 +298,8 @@
 	if (index < 0)
 		return NULL;
 
-	read_lock(&hdev_list_lock);
-	list_for_each(p, &hdev_list) {
+	read_lock(&hci_dev_list_lock);
+	list_for_each(p, &hci_dev_list) {
 		hdev = list_entry(p, struct hci_dev, list);
 		if (hdev->id == index) {
 			hci_dev_hold(hdev);
@@ -308,7 +308,7 @@
 	}
 	hdev = NULL;
 done:
-	read_unlock(&hdev_list_lock);
+	read_unlock(&hci_dev_list_lock);
 	return hdev;
 }
 
@@ -727,8 +727,8 @@
 		return -ENOMEM;
 	dr = dl->dev_req;
 
-	read_lock_bh(&hdev_list_lock);
-	list_for_each(p, &hdev_list) {
+	read_lock_bh(&hci_dev_list_lock);
+	list_for_each(p, &hci_dev_list) {
 		struct hci_dev *hdev;
 		hdev = list_entry(p, struct hci_dev, list);
 		(dr + n)->dev_id  = hdev->id;
@@ -736,7 +736,7 @@
 		if (++n >= dev_num)
 			break;
 	}
-	read_unlock_bh(&hdev_list_lock);
+	read_unlock_bh(&hci_dev_list_lock);
 
 	dl->dev_num = n;
 	size = n * sizeof(struct hci_dev_req) + sizeof(__u16);
@@ -787,7 +787,7 @@
 /* Register HCI device */
 int hci_register_dev(struct hci_dev *hdev)
 {
-	struct list_head *head = &hdev_list, *p;
+	struct list_head *head = &hci_dev_list, *p;
 	int id = 0;
 
 	BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
@@ -795,10 +795,10 @@
 	if (!hdev->open || !hdev->close || !hdev->destruct)
 		return -EINVAL;
 
-	write_lock_bh(&hdev_list_lock);
+	write_lock_bh(&hci_dev_list_lock);
 
 	/* Find first available device id */
-	list_for_each(p, &hdev_list) {
+	list_for_each(p, &hci_dev_list) {
 	       	if (list_entry(p, struct hci_dev, list)->id != id)
 			break;
 		head = p; id++;
@@ -836,7 +836,9 @@
 		
 	MOD_INC_USE_COUNT;
 
-	write_unlock_bh(&hdev_list_lock);
+	write_unlock_bh(&hci_dev_list_lock);
+
+	hci_dev_proc_init(hdev);
 
 	hci_notify(hdev, HCI_DEV_REG);
 	hci_run_hotplug(hdev->name, "register");
@@ -849,9 +851,11 @@
 {
 	BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
 
-	write_lock_bh(&hdev_list_lock);
+	hci_dev_proc_cleanup(hdev);
+
+	write_lock_bh(&hci_dev_list_lock);
 	list_del(&hdev->list);
-	write_unlock_bh(&hdev_list_lock);
+	write_unlock_bh(&hci_dev_list_lock);
 
 	hci_dev_do_close(hdev);
 
diff -Nru a/net/bluetooth/hci_proc.c b/net/bluetooth/hci_proc.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/bluetooth/hci_proc.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,187 @@
+/* 
+   BlueZ - Bluetooth protocol stack for Linux
+   Copyright (C) 2000-2001 Qualcomm Incorporated
+
+   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License version 2 as
+   published by the Free Software Foundation;
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
+   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
+   SOFTWARE IS DISCLAIMED.
+*/
+
+/*
+ * Bluetooth HCI Proc FS support.
+ *
+ * $Id: hci_proc.c,v 1.0 2002/04/17 17:37:16 maxk Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/fcntl.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <net/sock.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#ifndef CONFIG_BT_HCI_CORE_DEBUG
+#undef  BT_DBG
+#define BT_DBG( A... )
+#endif
+
+#ifdef CONFIG_PROC_FS
+struct proc_dir_entry *proc_bt_hci;
+
+static int hci_seq_open(struct file *file, struct seq_operations *op, void *priv)
+{
+	struct seq_file *seq;
+
+	if (seq_open(file, op))
+		return -ENOMEM;
+
+	seq = file->private_data;
+	seq->private = priv;
+	return 0;
+}
+
+static void *inq_seq_start(struct seq_file *seq, loff_t *pos)
+{
+	struct hci_dev *hdev = seq->private;
+	struct inquiry_entry *inq;
+	loff_t l = *pos;
+	
+	hci_dev_lock_bh(hdev);
+
+	for (inq = hdev->inq_cache.list; inq; inq = inq->next)
+		if (!l--)
+			return inq;
+	return NULL;
+}
+
+static void *inq_seq_next(struct seq_file *seq, void *e, loff_t *pos)
+{
+	struct inquiry_entry *inq = e;
+	return inq->next;
+}
+
+static void inq_seq_stop(struct seq_file *seq, void *e)
+{
+	struct hci_dev *hdev = seq->private;
+	hci_dev_unlock_bh(hdev);
+}
+
+static int  inq_seq_show(struct seq_file *seq, void *e)
+{
+	struct inquiry_entry *inq = e;
+	struct inquiry_info  *info = &inq->info;
+
+	seq_printf(seq, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %u\n", batostr(&info->bdaddr), 
+			info->pscan_rep_mode, info->pscan_period_mode, info->pscan_mode,
+			info->dev_class[0], info->dev_class[1], info->dev_class[2],
+			info->clock_offset, inq->timestamp);
+	return 0;
+}
+
+static struct seq_operations inq_seq_ops = {
+	.start  = inq_seq_start,
+	.next   = inq_seq_next,
+	.stop   = inq_seq_stop,
+	.show   = inq_seq_show 
+};
+
+static int inq_seq_open(struct inode *inode, struct file *file)
+{
+	return hci_seq_open(file, &inq_seq_ops, PDE(inode)->data);
+}
+
+static struct file_operations inq_seq_fops = {
+	.open    = inq_seq_open,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = seq_release,
+};
+
+int hci_dev_proc_init(struct hci_dev *hdev)
+{
+	struct proc_dir_entry *e;
+	char id[10];
+
+	sprintf(id, "%d", hdev->id);
+
+	hdev->proc = proc_mkdir(id, proc_bt_hci);
+	if (!hdev->proc)
+		return -ENOMEM;
+
+	e = create_proc_entry("inquiry_cache", S_IRUGO, hdev->proc);
+	if (e) {
+		e->proc_fops = &inq_seq_fops;
+		e->data = (void *) hdev;
+	}
+
+        return 0;
+}
+
+void hci_dev_proc_cleanup(struct hci_dev *hdev)
+{
+	char id[10];
+	sprintf(id, "%d", hdev->id);
+
+	remove_proc_entry("inquiry_cache", hdev->proc);
+
+	remove_proc_entry(id, proc_bt_hci);
+}
+
+int __init hci_proc_init(void)
+{
+	proc_bt_hci = proc_mkdir("hci", proc_bt);
+        return 0;
+}
+
+void __init hci_proc_cleanup(void)
+{
+	remove_proc_entry("hci", proc_bt);
+}
+
+#else /* CONFIG_PROC_FS */
+
+int hci_dev_proc_init(struct hci_dev *hdev)
+{
+        return 0;
+}
+
+void hci_dev_proc_cleanup(struct hci_dev *hdev)
+{
+        return;
+}
+
+int  __init hci_proc_init(void)
+{
+        return 0;
+}
+
+void __init hci_proc_cleanup(void)
+{
+        return;
+}
+
+#endif /* CONFIG_PROC_FS */
diff -Nru a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
--- a/net/bluetooth/hci_sock.c	Mon Nov  4 14:31:02 2002
+++ b/net/bluetooth/hci_sock.c	Mon Nov  4 14:31:02 2002
@@ -628,18 +628,21 @@
 int hci_sock_init(void)
 {
 	if (bt_sock_register(BTPROTO_HCI, &hci_sock_family_ops)) {
-		BT_ERR("Can't register HCI socket");
+		BT_ERR("HCI socket registration failed");
 		return -EPROTO;
 	}
 
 	hci_register_notifier(&hci_sock_nblock);
+
+	BT_INFO("HCI socket layer initialized");
+
 	return 0;
 }
 
 int hci_sock_cleanup(void)
 {
 	if (bt_sock_unregister(BTPROTO_HCI))
-		BT_ERR("Can't unregister HCI socket");
+		BT_ERR("HCI socket unregistration failed");
 
 	hci_unregister_notifier(&hci_sock_nblock);
 	return 0;
diff -Nru a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
--- a/net/bluetooth/l2cap.c	Mon Nov  4 14:31:02 2002
+++ b/net/bluetooth/l2cap.c	Mon Nov  4 14:31:02 2002
@@ -46,6 +46,7 @@
 #include <linux/socket.h>
 #include <linux/skbuff.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/list.h>
 #include <net/sock.h>
 
@@ -1993,52 +1994,90 @@
 }
 
 /* ---- Proc fs support ---- */
-static int l2cap_sock_dump(char *buf, struct bt_sock_list *list)
+#ifdef CONFIG_PROC_FS
+static void *l2cap_seq_start(struct seq_file *seq, loff_t *pos)
 {
-	struct l2cap_pinfo *pi;
 	struct sock *sk;
-	char *ptr = buf;
+	loff_t l = *pos;
 
-	read_lock_bh(&list->lock);
+	read_lock_bh(&l2cap_sk_list.lock);
 
-	for (sk = list->head; sk; sk = sk->next) {
-		pi = l2cap_pi(sk);
-		ptr += sprintf(ptr, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d 0x%x\n",
-				batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), 
-				sk->state, pi->psm, pi->scid, pi->dcid, pi->imtu, pi->omtu,
-				pi->link_mode);
-	}
+	for (sk = l2cap_sk_list.head; sk; sk = sk->next)
+		if (!l--)
+			return sk;
+	return NULL;
+}
 
-	read_unlock_bh(&list->lock);
+static void *l2cap_seq_next(struct seq_file *seq, void *e, loff_t *pos)
+{
+	struct sock *sk = e;
+	(*pos)++;
+	return sk->next;
+}
 
-	ptr += sprintf(ptr, "\n");
-	return ptr - buf;
+static void l2cap_seq_stop(struct seq_file *seq, void *e)
+{
+	read_unlock_bh(&l2cap_sk_list.lock);
 }
 
-static int l2cap_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
+static int  l2cap_seq_show(struct seq_file *seq, void *e)
 {
-	char *ptr = buf;
-	int len;
+	struct sock *sk = e;
+	struct l2cap_pinfo *pi = l2cap_pi(sk);
 
-	BT_DBG("count %d, offset %ld", count, offset);
+	seq_printf(seq, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d 0x%x\n",
+			batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), 
+			sk->state, pi->psm, pi->scid, pi->dcid, pi->imtu, pi->omtu,
+			pi->link_mode);
+	return 0;
+}
 
-	ptr += l2cap_sock_dump(ptr, &l2cap_sk_list);
-	len  = ptr - buf;
+static struct seq_operations l2cap_seq_ops = {
+	.start  = l2cap_seq_start,
+	.next   = l2cap_seq_next,
+	.stop   = l2cap_seq_stop,
+	.show   = l2cap_seq_show 
+};
 
-	if (len <= count + offset)
-		*eof = 1;
+static int l2cap_seq_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &l2cap_seq_ops);
+}
 
-	*start = buf + offset;
-	len -= offset;
+static struct file_operations l2cap_seq_fops = {
+	.open    = l2cap_seq_open,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = seq_release,
+};
 
-	if (len > count)
-		len = count;
-	if (len < 0)
-		len = 0;
+static int __init l2cap_proc_init(void)
+{
+        struct proc_dir_entry *p = create_proc_entry("l2cap", S_IRUGO, proc_bt);
+        if (!p)
+                return -ENOMEM;
+        p->proc_fops = &l2cap_seq_fops;
+        return 0;
+}
 
-	return len;
+static void __init l2cap_proc_cleanup(void)
+{
+        remove_proc_entry("l2cap", proc_bt);
 }
 
+#else /* CONFIG_PROC_FS */
+
+static int __init l2cap_proc_init(void)
+{
+        return 0;
+}
+
+static void __init l2cap_proc_cleanup(void)
+{
+        return 0;
+}
+#endif /* CONFIG_PROC_FS */
+
 static struct proto_ops l2cap_sock_ops = {
 	.family  =      PF_BLUETOOTH,
 	.release =      l2cap_sock_release,
@@ -2079,32 +2118,34 @@
 	int err;
 
 	if ((err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops))) {
-		BT_ERR("Can't register L2CAP socket");
+		BT_ERR("L2CAP socket registration failed");
 		return err;
 	}
 
 	if ((err = hci_register_proto(&l2cap_hci_proto))) {
-		BT_ERR("Can't register L2CAP protocol");
+		BT_ERR("L2CAP protocol registration failed");
 		return err;
 	}
 
-	create_proc_read_entry("bluetooth/l2cap", 0, 0, l2cap_read_proc, NULL);
 
-	BT_INFO("Bluetooth L2CAP ver %s Copyright (C) 2000,2001 Qualcomm Inc", VERSION);
-	BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
+	l2cap_proc_init();
+	
+	BT_INFO("L2CAP ver %s", VERSION);
+	BT_INFO("L2CAP socket layer initialized");
+
 	return 0;
 }
 
 void l2cap_cleanup(void)
 {
-	remove_proc_entry("bluetooth/l2cap", NULL);
+	l2cap_proc_cleanup();
 
 	/* Unregister socket and protocol */
 	if (bt_sock_unregister(BTPROTO_L2CAP))
-		BT_ERR("Can't unregister L2CAP socket");
+		BT_ERR("L2CAP socket unregistration failed");
 
 	if (hci_unregister_proto(&l2cap_hci_proto))
-		BT_ERR("Can't unregister L2CAP protocol");
+		BT_ERR("L2CAP protocol unregistration failed");
 }
 
 module_init(l2cap_init);
diff -Nru a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
--- a/net/bluetooth/rfcomm/core.c	Mon Nov  4 14:31:00 2002
+++ b/net/bluetooth/rfcomm/core.c	Mon Nov  4 14:31:00 2002
@@ -43,6 +43,7 @@
 #include <linux/wait.h>
 #include <linux/net.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <net/sock.h>
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
@@ -58,6 +59,10 @@
 #define BT_DBG(D...)
 #endif
 
+#ifdef CONFIG_PROC_FS
+struct proc_dir_entry *proc_bt_rfcomm;
+#endif
+
 struct task_struct *rfcomm_thread;
 DECLARE_MUTEX(rfcomm_sem);
 unsigned long rfcomm_event;
@@ -1723,77 +1728,128 @@
 }
 
 /* ---- Proc fs support ---- */
-static int rfcomm_dlc_dump(char *buf)
+#ifdef CONFIG_PROC_FS
+static void *rfcomm_seq_start(struct seq_file *seq, loff_t *pos)
 {
 	struct rfcomm_session *s;
-	struct sock *sk;
-	struct list_head *p, *pp;
-	char *ptr = buf;
+	struct list_head *pp, *p;
+	loff_t l = *pos;
 
 	rfcomm_lock();
 
 	list_for_each(p, &session_list) {
 		s = list_entry(p, struct rfcomm_session, list);
-		sk = s->sock->sk;
+		list_for_each(pp, &s->dlcs)
+			if (!l--) {
+				seq->private = s;
+				return pp;
+			}
+	}
+	return NULL;
+}
+
+static void *rfcomm_seq_next(struct seq_file *seq, void *e, loff_t *pos)
+{
+	struct rfcomm_session *s = seq->private;
+	struct list_head *pp, *p = e;
+	(*pos)++;
 
-		list_for_each(pp, &s->dlcs) {
-		struct rfcomm_dlc *d;
-			d = list_entry(pp, struct rfcomm_dlc, list);
-
-			ptr += sprintf(ptr, "dlc %s %s %ld %d %d %d %d\n",
-				batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
-				d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits);
+	if (p->next != &s->dlcs)
+		return p->next;
+
+	for (p = s->list.next; p != &session_list; p = p->next) {
+		s = list_entry(p, struct rfcomm_session, list);
+		__list_for_each(pp, &s->dlcs) {
+			seq->private = s;
+			return pp;
 		}
 	}
-	
+	return NULL;
+}
+
+static void rfcomm_seq_stop(struct seq_file *seq, void *e)
+{
 	rfcomm_unlock();
+}
+
+static int  rfcomm_seq_show(struct seq_file *seq, void *e)
+{
+	struct rfcomm_session *s = seq->private;
+	struct sock *sk = s->sock->sk;
+	struct rfcomm_dlc *d = list_entry(e, struct rfcomm_dlc, list);
 
-	return ptr - buf;
+	seq_printf(seq, "%s %s %ld %d %d %d %d\n",
+			batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
+			d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits);
+	return 0;
+}
+
+static struct seq_operations rfcomm_seq_ops = {
+	.start  = rfcomm_seq_start,
+	.next   = rfcomm_seq_next,
+	.stop   = rfcomm_seq_stop,
+	.show   = rfcomm_seq_show 
+};
+
+static int rfcomm_seq_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &rfcomm_seq_ops);
 }
 
-extern int rfcomm_sock_dump(char *buf);
+static struct file_operations rfcomm_seq_fops = {
+	.open    = rfcomm_seq_open,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = seq_release,
+};
 
-static int rfcomm_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
+static int __init rfcomm_proc_init(void)
 {
-	char *ptr = buf;
-	int len;
+        struct proc_dir_entry *p;
 
-	BT_DBG("count %d, offset %ld", count, offset);
+	proc_bt_rfcomm = proc_mkdir("rfcomm", proc_bt);
 
-	ptr += rfcomm_dlc_dump(ptr);
-	ptr += rfcomm_sock_dump(ptr);
-	len  = ptr - buf;
+        p = create_proc_entry("dlc", S_IRUGO, proc_bt_rfcomm);
+        if (p)
+        	p->proc_fops = &rfcomm_seq_fops;
+        return 0;
+}
 
-	if (len <= count + offset)
-		*eof = 1;
+static void __init rfcomm_proc_cleanup(void)
+{
+        remove_proc_entry("dlc", proc_bt_rfcomm);
 
-	*start = buf + offset;
-	len -= offset;
+	remove_proc_entry("rfcomm", proc_bt);
+}
 
-	if (len > count)
-		len = count;
-	if (len < 0)
-		len = 0;
+#else /* CONFIG_PROC_FS */
 
-	return len;
+static int __init rfcomm_proc_init(void)
+{
+        return 0;
 }
 
+static void __init rfcomm_proc_cleanup(void)
+{
+        return 0;
+}
+#endif /* CONFIG_PROC_FS */
+
 /* ---- Initialization ---- */
 int __init rfcomm_init(void)
 {
 	kernel_thread(rfcomm_run, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
 
+	BT_INFO("RFCOMM ver %s", VERSION);
+
+	rfcomm_proc_init();
+
 	rfcomm_init_sockets();
 
 #ifdef CONFIG_BT_RFCOMM_TTY
 	rfcomm_init_ttys();
 #endif
 
-	create_proc_read_entry("bluetooth/rfcomm", 0, 0, rfcomm_read_proc, NULL);
-
-	BT_INFO("Bluetooth RFCOMM ver %s", VERSION);
-	BT_INFO("Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>");
-	BT_INFO("Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>");
 	return 0;
 }
 
@@ -1808,14 +1864,13 @@
 	while (atomic_read(&running))
 		schedule();
 
-	remove_proc_entry("bluetooth/rfcomm", NULL);
-
 #ifdef CONFIG_BT_RFCOMM_TTY
 	rfcomm_cleanup_ttys();
 #endif
 
 	rfcomm_cleanup_sockets();
-	return;
+
+	rfcomm_proc_cleanup();
 }
 
 module_init(rfcomm_init);
diff -Nru a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
--- a/net/bluetooth/rfcomm/sock.c	Mon Nov  4 14:31:02 2002
+++ b/net/bluetooth/rfcomm/sock.c	Mon Nov  4 14:31:02 2002
@@ -44,6 +44,8 @@
 #include <linux/socket.h>
 #include <linux/skbuff.h>
 #include <linux/list.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <net/sock.h>
 
 #include <asm/system.h>
@@ -772,27 +774,87 @@
 }
 
 /* ---- Proc fs support ---- */
-int rfcomm_sock_dump(char *buf)
+#ifdef CONFIG_PROC_FS
+static void *rfcomm_seq_start(struct seq_file *seq, loff_t *pos)
 {
-	struct bt_sock_list *list = &rfcomm_sk_list;
-	struct rfcomm_pinfo *pi;
 	struct sock *sk;
-	char *ptr = buf;
+	loff_t l = *pos;
 
-	write_lock_bh(&list->lock);
+	read_lock_bh(&rfcomm_sk_list.lock);
 
-	for (sk = list->head; sk; sk = sk->next) {
-		pi = rfcomm_pi(sk);
-		ptr += sprintf(ptr, "sk  %s %s %d %d\n",
-				batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
-				sk->state, rfcomm_pi(sk)->channel);
-	}
+	for (sk = rfcomm_sk_list.head; sk; sk = sk->next)
+		if (!l--)
+			return sk;
+	return NULL;
+}
+
+static void *rfcomm_seq_next(struct seq_file *seq, void *e, loff_t *pos)
+{
+	struct sock *sk = e;
+	(*pos)++;
+	return sk->next;
+}
+
+static void rfcomm_seq_stop(struct seq_file *seq, void *e)
+{
+	read_unlock_bh(&rfcomm_sk_list.lock);
+}
 
-	write_unlock_bh(&list->lock);
+static int  rfcomm_seq_show(struct seq_file *seq, void *e)
+{
+	struct sock *sk = e;
+	seq_printf(seq, "%s %s %d %d\n",
+			batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
+			sk->state, rfcomm_pi(sk)->channel);
+	return 0;
+}
+
+static struct seq_operations rfcomm_seq_ops = {
+	.start  = rfcomm_seq_start,
+	.next   = rfcomm_seq_next,
+	.stop   = rfcomm_seq_stop,
+	.show   = rfcomm_seq_show 
+};
 
-	return ptr - buf;
+static int rfcomm_seq_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &rfcomm_seq_ops);
 }
 
+static struct file_operations rfcomm_seq_fops = {
+	.open    = rfcomm_seq_open,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = seq_release,
+};
+
+static int __init rfcomm_sock_proc_init(void)
+{
+        struct proc_dir_entry *p = create_proc_entry("sock", S_IRUGO, proc_bt_rfcomm);
+        if (!p)
+                return -ENOMEM;
+        p->proc_fops = &rfcomm_seq_fops;
+        return 0;
+}
+
+static void __init rfcomm_sock_proc_cleanup(void)
+{
+        remove_proc_entry("sock", proc_bt_rfcomm);
+}
+
+#else /* CONFIG_PROC_FS */
+
+static int __init rfcomm_sock_proc_init(void)
+{
+        return 0;
+}
+
+static void __init rfcomm_sock_proc_cleanup(void)
+{
+        return 0;
+}
+#endif /* CONFIG_PROC_FS */
+
 static struct proto_ops rfcomm_sock_ops = {
 	.family		= PF_BLUETOOTH,
 	.release	= rfcomm_sock_release,
@@ -822,10 +884,13 @@
 	int err;
 
 	if ((err = bt_sock_register(BTPROTO_RFCOMM, &rfcomm_sock_family_ops))) {
-		BT_ERR("Can't register RFCOMM socket layer");
+		BT_ERR("RFCOMM socket layer registration failed. %d", err);
 		return err;
 	}
 
+	rfcomm_sock_proc_init();
+
+	BT_INFO("RFCOMM socket layer initialized");
 	return 0;
 }
 
@@ -833,7 +898,9 @@
 {
 	int err;
 
+	rfcomm_sock_proc_cleanup();
+
 	/* Unregister socket, protocol and notifier */
 	if ((err = bt_sock_unregister(BTPROTO_RFCOMM)))
-		BT_ERR("Can't unregister RFCOMM socket layer %d", err);
+		BT_ERR("RFCOMM socket layer unregistration failed. %d", err);
 }
diff -Nru a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
--- a/net/bluetooth/rfcomm/tty.c	Mon Nov  4 14:31:02 2002
+++ b/net/bluetooth/rfcomm/tty.c	Mon Nov  4 14:31:02 2002
@@ -500,10 +500,10 @@
 	BT_DBG("dlc %p dev %p v24_sig 0x%02x", dlc, dev, v24_sig);
 
 	dev->modem_status = 
-		(v24_sig & RFCOMM_V24_RTC) ? (TIOCM_DSR | TIOCM_DTR) : 0 |
-		(v24_sig & RFCOMM_V24_RTR) ? (TIOCM_RTS | TIOCM_CTS) : 0 |
-		(v24_sig & RFCOMM_V24_IC)  ? TIOCM_RI : 0 |
-		(v24_sig & RFCOMM_V24_DV)  ? TIOCM_CD : 0;
+		((v24_sig & RFCOMM_V24_RTC) ? (TIOCM_DSR | TIOCM_DTR) : 0) |
+		((v24_sig & RFCOMM_V24_RTR) ? (TIOCM_RTS | TIOCM_CTS) : 0) |
+		((v24_sig & RFCOMM_V24_IC)  ? TIOCM_RI : 0) |
+		((v24_sig & RFCOMM_V24_DV)  ? TIOCM_CD : 0);
 }
 
 /* ---- TTY functions ---- */
@@ -572,6 +572,11 @@
 		if (dlc->state == BT_CONNECTED)
 			break;
 
+		if (signal_pending(current)) {
+			err = -EINTR;
+			break;
+		}
+
 		schedule();
 	}
 	set_current_state(TASK_RUNNING);
@@ -898,6 +903,8 @@
 		BT_ERR("Can't register RFCOMM TTY driver");
 		return -1;
 	}
+
+	BT_INFO("RFCOMM TTY layer initialized");
 
 	return 0;
 }
diff -Nru a/net/bluetooth/sco.c b/net/bluetooth/sco.c
--- a/net/bluetooth/sco.c	Mon Nov  4 14:31:01 2002
+++ b/net/bluetooth/sco.c	Mon Nov  4 14:31:01 2002
@@ -46,6 +46,7 @@
 #include <linux/socket.h>
 #include <linux/skbuff.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/list.h>
 #include <net/sock.h>
 
@@ -884,52 +885,86 @@
 	return 0;
 }
 
-/* ----- Proc fs support ------ */
-static int sco_sock_dump(char *buf, struct bt_sock_list *list)
+/* ---- Proc fs support ---- */
+#ifdef CONFIG_PROC_FS
+static void *sco_seq_start(struct seq_file *seq, loff_t *pos)
 {
-	struct sco_pinfo *pi;
 	struct sock *sk;
-	char *ptr = buf;
+	loff_t l = *pos;
 
-	read_lock_bh(&list->lock);
+	read_lock_bh(&sco_sk_list.lock);
 
-	for (sk = list->head; sk; sk = sk->next) {
-		pi = sco_pi(sk);
-		ptr += sprintf(ptr, "%s %s %d\n",
-				batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
-				sk->state); 
-	}
+	for (sk = sco_sk_list.head; sk; sk = sk->next)
+		if (!l--)
+			return sk;
+	return NULL;
+}
 
-	read_unlock_bh(&list->lock);
+static void *sco_seq_next(struct seq_file *seq, void *e, loff_t *pos)
+{
+	struct sock *sk = e;
+	(*pos)++;
+	return sk->next;
+}
 
-	ptr += sprintf(ptr, "\n");
+static void sco_seq_stop(struct seq_file *seq, void *e)
+{
+	read_unlock_bh(&sco_sk_list.lock);
+}
 
-	return ptr - buf;
+static int  sco_seq_show(struct seq_file *seq, void *e)
+{
+	struct sock *sk = e;
+	seq_printf(seq, "%s %s %d\n",
+			batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), sk->state);
+	return 0;
 }
 
-static int sco_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
+static struct seq_operations sco_seq_ops = {
+	.start  = sco_seq_start,
+	.next   = sco_seq_next,
+	.stop   = sco_seq_stop,
+	.show   = sco_seq_show 
+};
+
+static int sco_seq_open(struct inode *inode, struct file *file)
 {
-	char *ptr = buf;
-	int len;
+	return seq_open(file, &sco_seq_ops);
+}
 
-	BT_DBG("count %d, offset %ld", count, offset);
+static struct file_operations sco_seq_fops = {
+	.open    = sco_seq_open,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = seq_release,
+};
 
-	ptr += sco_sock_dump(ptr, &sco_sk_list);
-	len  = ptr - buf;
+static int __init sco_proc_init(void)
+{
+        struct proc_dir_entry *p = create_proc_entry("sco", S_IRUGO, proc_bt);
+        if (!p)
+                return -ENOMEM;
+        p->proc_fops = &sco_seq_fops;
+        return 0;
+}
 
-	if (len <= count + offset)
-		*eof = 1;
+static void __init sco_proc_cleanup(void)
+{
+        remove_proc_entry("sco", proc_bt);
+}
 
-	*start = buf + offset;
-	len -= offset;
+#else /* CONFIG_PROC_FS */
 
-	if (len > count)
-		len = count;
-	if (len < 0)
-		len = 0;
+static int __init sco_proc_init(void)
+{
+        return 0;
+}
 
-	return len;
+static void __init sco_proc_cleanup(void)
+{
+        return 0;
 }
+#endif /* CONFIG_PROC_FS */
 
 static struct proto_ops sco_sock_ops = {
 	.family  =      PF_BLUETOOTH,
@@ -969,19 +1004,20 @@
 	int err;
 
 	if ((err = bt_sock_register(BTPROTO_SCO, &sco_sock_family_ops))) {
-		BT_ERR("Can't register SCO socket layer");
+		BT_ERR("SCO socket registration failed");
 		return err;
 	}
 
 	if ((err = hci_register_proto(&sco_hci_proto))) {
-		BT_ERR("Can't register SCO protocol");
+		BT_ERR("SCO protocol registration failed");
 		return err;
 	}
 
-	create_proc_read_entry("bluetooth/sco", 0, 0, sco_read_proc, NULL);
+	sco_proc_init();
+	
+	BT_INFO("SCO (Voice Link) ver %s", VERSION);
+	BT_INFO("SCO socket layer initialized");
 
-	BT_INFO("Bluetooth SCO ver %s Copyright (C) 2000,2001 Qualcomm Inc", VERSION);
-	BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
 	return 0;
 }
 
@@ -989,14 +1025,14 @@
 {
 	int err;
 
-	remove_proc_entry("bluetooth/sco", NULL);
+	sco_proc_cleanup();
 
 	/* Unregister socket, protocol and notifier */
 	if ((err = bt_sock_unregister(BTPROTO_SCO)))
-		BT_ERR("Can't unregister SCO socket layer %d", err);
+		BT_ERR("SCO socket unregistration failed. %d", err);
 
 	if ((err = hci_unregister_proto(&sco_hci_proto)))
-		BT_ERR("Can't unregister SCO protocol %d", err);
+		BT_ERR("SCO protocol unregistration failed. %d", err);
 }
 
 module_init(sco_init);
diff -Nru a/net/bluetooth/syms.c b/net/bluetooth/syms.c
--- a/net/bluetooth/syms.c	Mon Nov  4 14:31:02 2002
+++ b/net/bluetooth/syms.c	Mon Nov  4 14:31:02 2002
@@ -78,3 +78,5 @@
 EXPORT_SYMBOL(bt_accept_enqueue);
 EXPORT_SYMBOL(bt_accept_dequeue);
 EXPORT_SYMBOL(bt_sock_w4_connect);
+
+EXPORT_SYMBOL(proc_bt);
diff -Nru a/net/ipv4/tcp.c b/net/ipv4/tcp.c
--- a/net/ipv4/tcp.c	Mon Nov  4 14:31:01 2002
+++ b/net/ipv4/tcp.c	Mon Nov  4 14:31:01 2002
@@ -476,8 +476,8 @@
 		if (sk->sleep && waitqueue_active(sk->sleep))
 			wake_up_interruptible(sk->sleep);
 
-		if (!(sk->shutdown & SEND_SHUTDOWN))
-			sk_wake_async(sk, 2, POLL_OUT);
+		if (sock->fasync_list && !(sk->shutdown & SEND_SHUTDOWN))
+			sock_wake_async(sock, 2, POLL_OUT);
 	}
 }
 
diff -Nru a/net/rxrpc/Makefile b/net/rxrpc/Makefile
--- a/net/rxrpc/Makefile	Mon Nov  4 14:31:02 2002
+++ b/net/rxrpc/Makefile	Mon Nov  4 14:31:02 2002
@@ -15,19 +15,13 @@
 	rxrpc_syms.o \
 	transport.o
 
-#ifeq ($(CONFIG_PROC_FS),y)
-rxrpc-objs	+= proc.o
-#endif
-#ifeq ($(CONFIG_SYSCTL),y)
+ifeq ($(CONFIG_PROC_FS),y)
+rxrpc-objs += proc.o
+endif
+ifeq ($(CONFIG_SYSCTL),y)
 rxrpc-objs += sysctl.o
-#endif
-
-obj-m  := rxrpc.o
-
-# superfluous for 2.5, but needed for 2.4..
-ifeq "$(VERSION).$(PATCHLEVEL)" "2.4"
-rxrpc.o: $(rxrpc-objs)
-	$(LD) -r -o $@ $(rxrpc-objs)
 endif
+
+obj-$(CONFIG_RXRPC) := rxrpc.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/net/rxrpc/call.c b/net/rxrpc/call.c
--- a/net/rxrpc/call.c	Mon Nov  4 14:31:01 2002
+++ b/net/rxrpc/call.c	Mon Nov  4 14:31:01 2002
@@ -26,10 +26,10 @@
 LIST_HEAD(rxrpc_calls);
 DECLARE_RWSEM(rxrpc_calls_sem);
 
-unsigned rxrpc_call_rcv_timeout		= 30;
-unsigned rxrpc_call_acks_timeout	= 30;
-unsigned rxrpc_call_dfr_ack_timeout	= 5;
-unsigned short rxrpc_call_max_resend	= 10;
+unsigned rxrpc_call_rcv_timeout		= HZ/3;
+unsigned rxrpc_call_acks_timeout	= HZ/3;
+unsigned rxrpc_call_dfr_ack_timeout	= HZ/20;
+unsigned short rxrpc_call_max_resend	= HZ/10;
 
 const char *rxrpc_call_states[] = {
 	"COMPLETE",
@@ -131,6 +131,22 @@
 
 /*****************************************************************************/
 /*
+ * calculate a timeout based on an RTT value
+ */
+static inline unsigned long __rxrpc_rtt_based_timeout(struct rxrpc_call *call, unsigned long val)
+{
+	unsigned long expiry = call->conn->peer->rtt / (1000000/HZ);
+
+	expiry += 10;
+	if (expiry<HZ/25) expiry = HZ/25;
+	if (expiry>HZ) expiry = HZ;
+
+	_leave(" = %lu jiffies",expiry);
+	return jiffies + expiry;
+} /* end __rxrpc_rtt_based_timeout() */
+
+/*****************************************************************************/
+/*
  * create a new call record
  */
 static inline int __rxrpc_create_call(struct rxrpc_connection *conn,
@@ -321,7 +337,10 @@
 
 	spin_lock(&conn->lock);
 
-	if (!conn->channels[cix]) {
+	if (!conn->channels[cix] ||
+	    conn->channels[cix]->app_call_state == RXRPC_CSTATE_COMPLETE ||
+	    conn->channels[cix]->app_call_state == RXRPC_CSTATE_ERROR
+	    ) {
 		conn->channels[cix] = call;
 		rxrpc_get_connection(conn);
 		ret = 0;
@@ -329,9 +348,10 @@
 
 	spin_unlock(&conn->lock);
 
-	if (ret<0) free_page((unsigned long)call);
-
-	_leave(" = %p",call);
+	if (ret<0) {
+		free_page((unsigned long)call);
+		call = NULL;
+	}
 
 	if (ret==0) {
 		down_write(&rxrpc_calls_sem);
@@ -341,6 +361,7 @@
 		*_call = call;
 	}
 
+	_leave(" = %d [%p]",ret,call);
 	return ret;
 } /* end rxrpc_incoming_call() */
 
@@ -367,7 +388,8 @@
 		return;
 	}
 
-	conn->channels[ntohl(call->chan_ix)] = NULL;
+	if (conn->channels[ntohl(call->chan_ix)]==call)
+		conn->channels[ntohl(call->chan_ix)] = NULL;
 
 	spin_unlock(&conn->lock);
 
@@ -1005,7 +1027,7 @@
 	}
 
 	/* next in sequence - simply append into the call's ready queue */
-	_debug("Call add packet %d to readyq (+%d => %d bytes)",
+	_debug("Call add packet %d to readyq (+%Zd => %Zd bytes)",
 	       msg->seq,msg->dsize,call->app_ready_qty);
 
 	spin_lock(&call->lock);
@@ -1021,7 +1043,7 @@
 			break;
 
 		/* next in sequence - just move list-to-list */
-		_debug("Call transfer packet %d to readyq (+%d => %d bytes)",
+		_debug("Call transfer packet %d to readyq (+%Zd => %Zd bytes)",
 		       pmsg->seq,pmsg->dsize,call->app_ready_qty);
 
 		call->app_ready_seq = pmsg->seq;
@@ -1156,7 +1178,7 @@
 	/* otherwise just invoke the data function whenever we can satisfy its desire for more
 	 * data
 	 */
-	_proto("Rx Received Op Data: st=%u qty=%u mk=%u%s",
+	_proto("Rx Received Op Data: st=%u qty=%Zu mk=%Zu%s",
 	       call->app_call_state,call->app_ready_qty,call->app_mark,
 	       call->app_last_rcv ? " last-rcvd" : "");
 
@@ -1394,7 +1416,7 @@
 	char resend, now_complete;
 	u8 acks[16];
 
-	_enter("%p{apc=%u ads=%u},%p,%u,%u",
+	_enter("%p{apc=%u ads=%u},%p,%u,%Zu",
 	       call,call->acks_pend_cnt,call->acks_dftv_seq,msg,seq,count);
 
 	/* handle re-ACK'ing of definitively ACK'd packets (may be out-of-order ACKs) */
@@ -1443,7 +1465,7 @@
 		}
 
 		_proto("Rx ACK of packets #%u-#%u [%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c] (pend=%u)",
-		       seq,seq+chunk-1,
+		       seq,(unsigned)(seq+chunk-1),
 		       _acktype[acks[0x0]],
 		       _acktype[acks[0x1]],
 		       _acktype[acks[0x2]],
@@ -1552,7 +1574,7 @@
 	size_t qty;
 	int ret;
 
-	_enter("%p{as=%d buf=%p qty=%u/%u}",
+	_enter("%p{as=%d buf=%p qty=%Zu/%Zu}",
 	       call,call->app_async_read,call->app_read_buf,call->app_ready_qty,call->app_mark);
 
 	/* check the state */
@@ -1560,7 +1582,7 @@
 	case RXRPC_CSTATE_SRVR_RCV_ARGS:
 	case RXRPC_CSTATE_CLNT_RCV_REPLY:
 		if (call->app_last_rcv) {
-			printk("%s(%p,%p,%d): Inconsistent call state (%s, last pkt)",
+			printk("%s(%p,%p,%Zd): Inconsistent call state (%s, last pkt)",
 			      __FUNCTION__,call,call->app_read_buf,call->app_mark,
 			      rxrpc_call_states[call->app_call_state]);
 			BUG();
@@ -1574,7 +1596,7 @@
 
 	case RXRPC_CSTATE_SRVR_SND_REPLY:
 		if (!call->app_last_rcv) {
-			printk("%s(%p,%p,%d): Inconsistent call state (%s, not last pkt)",
+			printk("%s(%p,%p,%Zd): Inconsistent call state (%s, not last pkt)",
 			      __FUNCTION__,call,call->app_read_buf,call->app_mark,
 			      rxrpc_call_states[call->app_call_state]);
 			BUG();
@@ -1616,11 +1638,11 @@
 		/* drag as much data as we need out of this packet */
 		qty = min(call->app_mark,msg->dsize);
 
-		_debug("reading %u from skb=%p off=%lu",qty,msg->pkt,msg->offset);
+		_debug("reading %Zu from skb=%p off=%lu",qty,msg->pkt,msg->offset);
 
 		if (call->app_read_buf)
 			if (skb_copy_bits(msg->pkt,msg->offset,call->app_read_buf,qty)<0)
-				panic("%s: Failed to copy data from packet: (%p,%p,%d)",
+				panic("%s: Failed to copy data from packet: (%p,%p,%Zd)",
 				      __FUNCTION__,call,call->app_read_buf,qty);
 
 		/* if that packet is now empty, discard it */
@@ -1673,7 +1695,7 @@
 	}
 
 	if (call->app_last_rcv) {
-		_debug("Insufficient data (%u/%u)",call->app_ready_qty,call->app_mark);
+		_debug("Insufficient data (%Zu/%Zu)",call->app_ready_qty,call->app_mark);
 		call->app_async_read = 0;
 		call->app_mark = RXRPC_APP_MARK_EOF;
 		call->app_read_buf = NULL;
@@ -1703,7 +1725,7 @@
 {
 	int ret;
 
-	_enter("%p{arq=%u},%p,%d,%x",call,call->app_ready_qty,buffer,size,flags);
+	_enter("%p{arq=%Zu},%p,%Zd,%x",call,call->app_ready_qty,buffer,size,flags);
 
 	spin_lock(&call->lock);
 
@@ -1799,7 +1821,7 @@
 	char *buf;
 	int ret;
 
-	_enter("%p,%u,%p,%02x,%x,%d,%p",call,sioc,siov,rxhdr_flags,alloc_flags,dup_data,size_sent);
+	_enter("%p,%Zu,%p,%02x,%x,%d,%p",call,sioc,siov,rxhdr_flags,alloc_flags,dup_data,size_sent);
 
 	*size_sent = 0;
 	size = 0;
@@ -1827,7 +1849,7 @@
 		size += sptr->iov_len;
 	}
 
-	_debug("- size=%u mtu=%u",size,call->conn->mtu_size);
+	_debug("- size=%Zu mtu=%Zu",size,call->conn->mtu_size);
 
 	do {
 		/* make sure there's a message under construction */
@@ -1837,7 +1859,7 @@
 						0,NULL,alloc_flags,&call->snd_nextmsg);
 			if (ret<0)
 				goto out;
-			_debug("- allocated new message [ds=%u]",call->snd_nextmsg->dsize);
+			_debug("- allocated new message [ds=%Zu]",call->snd_nextmsg->dsize);
 		}
 
 		msg = call->snd_nextmsg;
@@ -1857,7 +1879,7 @@
 		space = call->conn->mtu_size - msg->dsize;
 		chunk = min(space,size);
 
-		_debug("- [before] space=%u chunk=%u",space,chunk);
+		_debug("- [before] space=%Zu chunk=%Zu",space,chunk);
 
 		while (!siov->iov_len)
 			siov++;
@@ -1916,7 +1938,7 @@
 			}
 		}
 
-		_debug("- [loaded] chunk=%u size=%u",chunk,size);
+		_debug("- [loaded] chunk=%Zu size=%Zu",chunk,size);
 
 		/* dispatch the message when full, final or requesting ACK */
 		if (msg->dsize>=call->conn->mtu_size || rxhdr_flags) {
@@ -1929,7 +1951,7 @@
 
 	ret = 0;
  out:
-	_leave(" = %d (%d queued, %d rem)",ret,*size_sent,size);
+	_leave(" = %d (%Zd queued, %Zd rem)",ret,*size_sent,size);
 	return ret;
 
 } /* end rxrpc_call_write_data() */
@@ -1960,7 +1982,7 @@
 			msg->hdr.flags |= RXRPC_MORE_PACKETS;
 		}
 
-		_proto("Sending DATA message { ds=%u dc=%u df=%02lu }",
+		_proto("Sending DATA message { ds=%Zu dc=%u df=%02lu }",
 		       msg->dsize,msg->dcount,msg->dfree);
 
 		/* queue and adjust call state */
@@ -1993,7 +2015,8 @@
 
 		call->acks_pend_cnt++;
 
-		mod_timer(&call->acks_timeout,jiffies + rxrpc_call_acks_timeout);
+		mod_timer(&call->acks_timeout,
+			  __rxrpc_rtt_based_timeout(call,rxrpc_call_acks_timeout));
 
 		spin_unlock(&call->lock);
 
@@ -2061,7 +2084,7 @@
 		spin_unlock(&call->lock);
 
 		/* send each message again (and ignore any errors we might incur) */
-		_proto("Resending DATA message { ds=%u dc=%u df=%02lu }",
+		_proto("Resending DATA message { ds=%Zu dc=%u df=%02lu }",
 		       msg->dsize,msg->dcount,msg->dfree);
 
 		if (rxrpc_conn_sendmsg(call->conn,msg)==0)
@@ -2073,7 +2096,7 @@
 	}
 
 	/* reset the timeout */
-	mod_timer(&call->acks_timeout,jiffies + rxrpc_call_acks_timeout);
+	mod_timer(&call->acks_timeout,__rxrpc_rtt_based_timeout(call,rxrpc_call_acks_timeout));
 
 	spin_unlock(&call->lock);
 
diff -Nru a/net/rxrpc/connection.c b/net/rxrpc/connection.c
--- a/net/rxrpc/connection.c	Mon Nov  4 14:31:02 2002
+++ b/net/rxrpc/connection.c	Mon Nov  4 14:31:02 2002
@@ -121,7 +121,7 @@
 	conn->out_epoch		= rxrpc_epoch;
 	conn->in_clientflag	= 0;
 	conn->out_clientflag	= RXRPC_CLIENT_INITIATED;
-	conn->conn_id		= htonl((unsigned) conn & RXRPC_CIDMASK);
+	conn->conn_id		= htonl((unsigned long) conn & RXRPC_CIDMASK);
 	conn->service_id	= htons(service_id);
 
 	/* attach to peer */
@@ -547,7 +547,7 @@
 	msghdr.msg_controllen	= 0;
 	msghdr.msg_flags	= MSG_CONFIRM|MSG_DONTWAIT;
 
-	_net("Sending message type %d of %d bytes to %08x:%d",
+	_net("Sending message type %d of %Zd bytes to %08x:%d",
 	     msg->hdr.type,
 	     msg->dsize,
 	     htonl(conn->addr.sin_addr.s_addr),
diff -Nru a/net/rxrpc/internal.h b/net/rxrpc/internal.h
--- a/net/rxrpc/internal.h	Mon Nov  4 14:31:01 2002
+++ b/net/rxrpc/internal.h	Mon Nov  4 14:31:01 2002
@@ -29,24 +29,24 @@
 /*
  * debug tracing
  */
-#define kenter(FMT,...)	printk("==> %s("FMT")\n",__FUNCTION__,##__VA_ARGS__)
-#define kleave(FMT,...)	printk("<== %s()"FMT"\n",__FUNCTION__,##__VA_ARGS__)
-#define kdebug(FMT,...)	printk("    "FMT"\n",##__VA_ARGS__)
-#define kproto(FMT,...)	printk("### "FMT"\n",##__VA_ARGS__)
-#define knet(FMT,...)	printk("    "FMT"\n",##__VA_ARGS__)
+#define kenter(FMT, a...)	printk("==> %s("FMT")\n",__FUNCTION__ , ##a)
+#define kleave(FMT, a...)	printk("<== %s()"FMT"\n",__FUNCTION__ , ##a)
+#define kdebug(FMT, a...)	printk("    "FMT"\n" , ##a)
+#define kproto(FMT, a...)	printk("### "FMT"\n" , ##a)
+#define knet(FMT, a...)		printk("    "FMT"\n" , ##a)
 
 #if 0
-#define _enter(FMT,...)	kenter(FMT,##__VA_ARGS__)
-#define _leave(FMT,...)	kleave(FMT,##__VA_ARGS__)
-#define _debug(FMT,...)	kdebug(FMT,##__VA_ARGS__)
-#define _proto(FMT,...)	kproto(FMT,##__VA_ARGS__)
-#define _net(FMT,...)	knet(FMT,##__VA_ARGS__)
+#define _enter(FMT, a...)	kenter(FMT , ##a)
+#define _leave(FMT, a...)	kleave(FMT , ##a)
+#define _debug(FMT, a...)	kdebug(FMT , ##a)
+#define _proto(FMT, a...)	kproto(FMT , ##a)
+#define _net(FMT, a...)		knet(FMT , ##a)
 #else
-#define _enter(FMT,...)	do { if (rxrpc_ktrace) kenter(FMT,##__VA_ARGS__); } while(0)
-#define _leave(FMT,...)	do { if (rxrpc_ktrace) kleave(FMT,##__VA_ARGS__); } while(0)
-#define _debug(FMT,...)	do { if (rxrpc_kdebug) kdebug(FMT,##__VA_ARGS__); } while(0)
-#define _proto(FMT,...)	do { if (rxrpc_kproto) kproto(FMT,##__VA_ARGS__); } while(0)
-#define _net(FMT,...)	do { if (rxrpc_knet)   knet  (FMT,##__VA_ARGS__); } while(0)
+#define _enter(FMT, a...)	do { if (rxrpc_ktrace) kenter(FMT , ##a); } while(0)
+#define _leave(FMT, a...)	do { if (rxrpc_ktrace) kleave(FMT , ##a); } while(0)
+#define _debug(FMT, a...)	do { if (rxrpc_kdebug) kdebug(FMT , ##a); } while(0)
+#define _proto(FMT, a...)	do { if (rxrpc_kproto) kproto(FMT , ##a); } while(0)
+#define _net(FMT, a...)		do { if (rxrpc_knet)   knet  (FMT , ##a); } while(0)
 #endif
 
 static inline void rxrpc_discard_my_signals(void)
diff -Nru a/net/rxrpc/krxiod.c b/net/rxrpc/krxiod.c
--- a/net/rxrpc/krxiod.c	Mon Nov  4 14:31:00 2002
+++ b/net/rxrpc/krxiod.c	Mon Nov  4 14:31:00 2002
@@ -49,11 +49,7 @@
 	/* only certain signals are of interest */
 	spin_lock_irq(&current->sig->siglock);
 	siginitsetinv(&current->blocked,0);
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,3)
 	recalc_sigpending();
-#else
-	recalc_sigpending(current);
-#endif
 	spin_unlock_irq(&current->sig->siglock);
 
 	/* loop around waiting for work to do */
diff -Nru a/net/rxrpc/krxsecd.c b/net/rxrpc/krxsecd.c
--- a/net/rxrpc/krxsecd.c	Mon Nov  4 14:31:01 2002
+++ b/net/rxrpc/krxsecd.c	Mon Nov  4 14:31:01 2002
@@ -61,11 +61,7 @@
 	/* only certain signals are of interest */
 	spin_lock_irq(&current->sig->siglock);
 	siginitsetinv(&current->blocked,0);
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,3)
 	recalc_sigpending();
-#else
-	recalc_sigpending(current);
-#endif
 	spin_unlock_irq(&current->sig->siglock);
 
 	/* loop around waiting for work to do */
diff -Nru a/net/rxrpc/krxtimod.c b/net/rxrpc/krxtimod.c
--- a/net/rxrpc/krxtimod.c	Mon Nov  4 14:31:00 2002
+++ b/net/rxrpc/krxtimod.c	Mon Nov  4 14:31:00 2002
@@ -79,11 +79,7 @@
 	/* only certain signals are of interest */
 	spin_lock_irq(&current->sig->siglock);
 	siginitsetinv(&current->blocked,0);
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,3)
 	recalc_sigpending();
-#else
-	recalc_sigpending(current);
-#endif
 	spin_unlock_irq(&current->sig->siglock);
 
 	/* loop around looking for things to attend to */
diff -Nru a/net/rxrpc/main.c b/net/rxrpc/main.c
--- a/net/rxrpc/main.c	Mon Nov  4 14:31:02 2002
+++ b/net/rxrpc/main.c	Mon Nov  4 14:31:02 2002
@@ -123,5 +123,5 @@
 	__RXACCT(printk("Outstanding Peers      : %d\n",atomic_read(&rxrpc_peer_count)));
 	__RXACCT(printk("Outstanding Transports : %d\n",atomic_read(&rxrpc_transport_count)));
 
-	kleave();
+	kleave("");
 } /* end rxrpc_cleanup() */
diff -Nru a/net/rxrpc/peer.c b/net/rxrpc/peer.c
--- a/net/rxrpc/peer.c	Mon Nov  4 14:31:01 2002
+++ b/net/rxrpc/peer.c	Mon Nov  4 14:31:01 2002
@@ -370,11 +370,13 @@
 	if (peer->rtt_usage<RXRPC_RTT_CACHE_SIZE) peer->rtt_usage++;
 
 	/* recalculate RTT */
+	rtt = 0;
 	for (loop=peer->rtt_usage-1; loop>=0; loop--)
 		rtt += peer->rtt_cache[loop];
 
-	peer->rtt = do_div(rtt,peer->rtt_usage);
+	do_div(rtt,peer->rtt_usage);
+	peer->rtt = rtt;
 
-	_leave(" RTT=%lu.%lums",peer->rtt/1000,peer->rtt%1000);
+	_leave(" RTT=%lu.%lums",(long)(peer->rtt/1000),(long)(peer->rtt%1000));
 
 } /* end rxrpc_peer_calculate_rtt() */
diff -Nru a/net/rxrpc/proc.c b/net/rxrpc/proc.c
--- a/net/rxrpc/proc.c	Mon Nov  4 14:31:02 2002
+++ b/net/rxrpc/proc.c	Mon Nov  4 14:31:02 2002
@@ -22,13 +22,6 @@
 #include <rxrpc/message.h>
 #include "internal.h"
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-static inline struct proc_dir_entry *PDE(const struct inode *inode)
-{
-	return (struct proc_dir_entry *)inode->u.generic_ip;
-}
-#endif
-
 static struct proc_dir_entry *proc_rxrpc;
 
 static int rxrpc_proc_transports_open(struct inode *inode, struct file *file);
@@ -379,14 +372,14 @@
 	if (!list_empty(&peer->timeout.link))
 		timeout = (signed long)peer->timeout.timo_jif - (signed long)jiffies;
 
-	seq_printf(m,"%5hu %08x %5d %5d %8ld %5u %7lu\n",
+	seq_printf(m,"%5hu %08x %5d %5d %8ld %5Zu %7lu\n",
 		   peer->trans->port,
 		   ntohl(peer->addr.s_addr),
 		   atomic_read(&peer->usage),
 		   atomic_read(&peer->conn_count),
 		   timeout,
 		   peer->if_mtu,
-		   peer->rtt
+		   (long) peer->rtt
 		   );
 
 	return 0;
@@ -484,7 +477,7 @@
 	if (!list_empty(&conn->timeout.link))
 		timeout = (signed long)conn->timeout.timo_jif - (signed long)jiffies;
 
-	seq_printf(m,"%5hu %08x %5hu %04hx %08x %-3.3s %08x %08x %5u %8ld\n",
+	seq_printf(m,"%5hu %08x %5hu %04hx %08x %-3.3s %08x %08x %5Zu %8ld\n",
 		   conn->trans->port,
 		   ntohl(conn->addr.sin_addr.s_addr),
 		   ntohs(conn->addr.sin_port),
diff -Nru a/net/rxrpc/transport.c b/net/rxrpc/transport.c
--- a/net/rxrpc/transport.c	Mon Nov  4 14:31:02 2002
+++ b/net/rxrpc/transport.c	Mon Nov  4 14:31:02 2002
@@ -691,12 +691,12 @@
 		msg.msg_controllen = (char*)msg.msg_control - (char*)&emsg;
 
 		if (msg.msg_controllen<sizeof(emsg.cmsg) || msg.msg_namelen<sizeof(sin)) {
-			printk("%s: short control message (nlen=%u clen=%u fl=%x)\n",
+			printk("%s: short control message (nlen=%u clen=%Zu fl=%x)\n",
 			       __FUNCTION__,msg.msg_namelen,msg.msg_controllen,msg.msg_flags);
 			continue;
 		}
 
-		_net("Rx Received control message { len=%u level=%u type=%u }",
+		_net("Rx Received control message { len=%Zu level=%u type=%u }",
 		     emsg.cmsg.cmsg_len,emsg.cmsg.cmsg_level,emsg.cmsg.cmsg_type);
 
 		if (sin.sin_family!=AF_INET) {
@@ -715,7 +715,7 @@
 		}
 
 		if (msg.msg_controllen<sizeof(emsg.cmsg)+sizeof(emsg.ee)) {
-			printk("%s: short error message (%u)\n",__FUNCTION__,msg.msg_controllen);
+			printk("%s: short error message (%Zu)\n",__FUNCTION__,msg.msg_controllen);
 			_leave("");
 			return;
 		}
diff -Nru a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
--- a/net/sunrpc/xdr.c	Mon Nov  4 14:31:02 2002
+++ b/net/sunrpc/xdr.c	Mon Nov  4 14:31:02 2002
@@ -244,6 +244,11 @@
 		pglen -= base;
 		base  += xdr->page_base;
 		ppage += base >> PAGE_CACHE_SHIFT;
+		/* Note: The offset means that the length of the first
+		 * page is really (PAGE_CACHE_SIZE - (base & ~PAGE_CACHE_MASK)).
+		 * In order to avoid an extra test inside the loop,
+		 * we bump pglen here, and just subtract PAGE_CACHE_SIZE... */
+		pglen += base & ~PAGE_CACHE_MASK;
 	}
 	for (;;) {
 		flush_dcache_page(*ppage);
diff -Nru a/scripts/Makefile.build b/scripts/Makefile.build
--- a/scripts/Makefile.build	Mon Nov  4 14:31:02 2002
+++ b/scripts/Makefile.build	Mon Nov  4 14:31:02 2002
@@ -7,7 +7,7 @@
 .PHONY: __build
 __build:
 
-ifdef include-config
+ifdef include_config
 include .config
 endif
 
diff -Nru a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
--- a/scripts/kconfig/Makefile	Mon Nov  4 14:31:03 2002
+++ b/scripts/kconfig/Makefile	Mon Nov  4 14:31:03 2002
@@ -34,6 +34,7 @@
 
 $(obj)/qconf.o: $(obj)/.tmp_qtcheck
 
+ifeq ($(MAKECMDGOALS),$(obj)/qconf)
 -include $(obj)/.tmp_qtcheck
 
 # QT needs some extra effort...
@@ -52,6 +53,7 @@
 	LIB=qt; \
 	if [ -f $$DIR/lib/libqt-mt.so ]; then LIB=qt-mt; fi; \
 	echo "QTDIR=$$DIR" > $@; echo "QTLIB=$$LIB" >> $@
+endif
 
 $(obj)/zconf.tab.o: $(obj)/lex.zconf.c
 
diff -Nru a/sound/oss/i810_audio.c b/sound/oss/i810_audio.c
--- a/sound/oss/i810_audio.c	Mon Nov  4 14:31:02 2002
+++ b/sound/oss/i810_audio.c	Mon Nov  4 14:31:02 2002
@@ -2669,7 +2669,7 @@
 		codec->codec_write = i810_ac97_set;
 	
 		if(!i810_ac97_probe_and_powerup(card,codec)) {
-			printk("i810_audio: timed out waiting for codec %d analog ready", num_ac97);
+			printk("i810_audio: timed out waiting for codec %d analog ready.\n", num_ac97);
 			kfree(codec);
 			break;	/* it didn't work */
 		}
diff -Nru a/sound/oss/trident.c b/sound/oss/trident.c
--- a/sound/oss/trident.c	Mon Nov  4 14:31:02 2002
+++ b/sound/oss/trident.c	Mon Nov  4 14:31:02 2002
@@ -3930,9 +3930,11 @@
 		wReg = ali_ac97_get(card, 0, AC97_POWER_CONTROL);
 		if((wReg & 0x000f) == 0x000f)
 			return 0;
-		udelay(500);
+		udelay(5000);
 	}
-	return 0;
+
+	printk(KERN_ERR "ALi 5451 did not come out of reset.\n");
+	return 1;
 }
 
 /* AC97 codec initialisation. */
diff -Nru a/usr/Makefile b/usr/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/usr/Makefile	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,18 @@
+
+include arch/$(ARCH)/Makefile
+
+obj-y := initramfs_data.o
+
+host-progs := gen_init_cpio
+
+clean-files := initramfs_data.cpio.gz
+
+$(obj)/initramfs_data.o: $(obj)/initramfs_data.cpio.gz
+	$(OBJCOPY) $(ARCHBLOBLFLAGS) \
+		--rename-section .data=.init.initramfs \
+		$(obj)/initramfs_data.cpio.gz $(obj)/initramfs_data.o
+	$(STRIP) -s $(obj)/initramfs_data.o
+
+$(obj)/initramfs_data.cpio.gz: $(obj)/gen_init_cpio
+	( cd $(obj) ; ./gen_init_cpio | gzip -9c > initramfs_data.cpio.gz )
+
diff -Nru a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/usr/gen_init_cpio.c	Mon Nov  4 14:31:04 2002
@@ -0,0 +1,137 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+
+static unsigned int offset;
+static unsigned int ino = 721;
+
+static void push_rest(const char *name)
+{
+	unsigned int name_len = strlen(name) + 1;
+	unsigned int tmp_ofs;
+
+	fputs(name, stdout);
+	putchar(0);
+	offset += name_len;
+
+	tmp_ofs = name_len + 110;
+	while (tmp_ofs & 3) {
+		putchar(0);
+		offset++;
+		tmp_ofs++;
+	}
+}
+
+static void push_hdr(const char *s)
+{
+	fputs(s, stdout);
+	offset += 110;
+}
+
+static void cpio_trailer(void)
+{
+	char s[256];
+	const char *name = "TRAILER!!!";
+
+	sprintf(s, "%s%08X%08X%08lX%08lX%08X%08lX"
+	       "%08X%08X%08X%08X%08X%08X%08X",
+		"070701",		/* magic */
+		0,			/* ino */
+		0,			/* mode */
+		(long) 0,		/* uid */
+		(long) 0,		/* gid */
+		1,			/* nlink */
+		(long) 0,		/* mtime */
+		0,			/* filesize */
+		0,			/* major */
+		0,			/* minor */
+		0,			/* rmajor */
+		0,			/* rminor */
+		strlen(name) + 1,	/* namesize */
+		0);			/* chksum */
+	push_hdr(s);
+	push_rest(name);
+
+	while (offset % 512) {
+		putchar(0);
+		offset++;
+	}
+}
+
+static void cpio_mkdir(const char *name, unsigned int mode,
+		       uid_t uid, gid_t gid)
+{
+	char s[256];
+	time_t mtime = time(NULL);
+
+	sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
+	       "%08X%08X%08X%08X%08X%08X%08X",
+		"070701",		/* magic */
+		ino++,			/* ino */
+		S_IFDIR | mode,		/* mode */
+		(long) uid,		/* uid */
+		(long) gid,		/* gid */
+		2,			/* nlink */
+		(long) mtime,		/* mtime */
+		0,			/* filesize */
+		3,			/* major */
+		1,			/* minor */
+		0,			/* rmajor */
+		0,			/* rminor */
+		strlen(name) + 1,	/* namesize */
+		0);			/* chksum */
+	push_hdr(s);
+	push_rest(name);
+}
+
+static void cpio_mknod(const char *name, unsigned int mode,
+		       uid_t uid, gid_t gid, int dev_type,
+		       unsigned int maj, unsigned int min)
+{
+	char s[256];
+	time_t mtime = time(NULL);
+
+	if (dev_type == 'b')
+		mode |= S_IFBLK;
+	else
+		mode |= S_IFCHR;
+
+	sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
+	       "%08X%08X%08X%08X%08X%08X%08X",
+		"070701",		/* magic */
+		ino++,			/* ino */
+		mode,			/* mode */
+		(long) uid,		/* uid */
+		(long) gid,		/* gid */
+		1,			/* nlink */
+		(long) mtime,		/* mtime */
+		0,			/* filesize */
+		3,			/* major */
+		1,			/* minor */
+		maj,			/* rmajor */
+		min,			/* rminor */
+		strlen(name) + 1,	/* namesize */
+		0);			/* chksum */
+	push_hdr(s);
+	push_rest(name);
+}
+
+int main (int argc, char *argv[])
+{
+	cpio_mkdir("/dev", 0700, 0, 0);
+	cpio_mknod("/dev/console", 0600, 0, 0, 'c', 5, 1);
+	cpio_mkdir("/root", 0700, 0, 0);
+	cpio_trailer();
+
+	exit(0);
+
+	/* silence compiler warnings */
+	return 0;
+	(void) argc;
+	(void) argv;
+}
+
