diff -u --recursive --new-file v2.4.12/linux/Documentation/README.nsp_cs.eng linux/Documentation/README.nsp_cs.eng
--- v2.4.12/linux/Documentation/README.nsp_cs.eng	Wed Jul 25 17:10:16 2001
+++ linux/Documentation/README.nsp_cs.eng	Thu Oct 11 11:17:22 2001
@@ -8,9 +8,9 @@
 for Linux.
 
 2. My Linux environment
-Linux kernel: 2.4.0 / 2.2.18
-pcmcia-cs:    3.1.24
-gcc:          gcc-2.95.2
+Linux kernel: 2.4.7 / 2.2.19
+pcmcia-cs:    3.1.27
+gcc:          gcc-2.95.4
 PC card:      I-O data PCSC-F (NinjaSCSI-3)
               I-O data CBSC-II in 16 bit mode (NinjaSCSI-32Bi)
 SCSI device:  I-O data CDPS-PX24 (CD-ROM drive)
@@ -55,6 +55,8 @@
 [4] Extract this driver's archive somewhere, and edit Makefile, then do make.
 $ tar -zxvf nsp_cs-x.x.tar.gz
 $ cd nsp_cs-x.x
+$ emacs Makefile
+...
 $ make
 
 [5] Copy nsp_cs.o to suitable plase, like /lib/modules/<Kernel version>/pcmcia/ .
@@ -95,7 +97,7 @@
   bind "nsp_cs"
 -------------------------------------
 
-[7] Boot (or reboot) pcmcia-cs.
+[7] Start (or restart) pcmcia-cs.
 # /etc/rc.d/rc.pcmcia start        (BSD style)
 or
 # /etc/init.d/pcmcia start         (SYSV style)
@@ -111,7 +113,8 @@
 your data. Please backup your data when you use this driver.
 
 6. Known Bugs
- Some write error occurs when you use slow device.
+ In 2.4 kernel, you can't use 640MB Optical disk. This error comes from
+high level SCSI driver.
 
 7. Testing
  Please send me some reports(bug reports etc..) of this software.
@@ -124,4 +127,4 @@
  See GPL.
 
 
-2001/02/01 yokota@netlab.is.tsukuba.ac.jp <YOKOTA Hiroshi>
+2001/08/08 yokota@netlab.is.tsukuba.ac.jp <YOKOTA Hiroshi>
diff -u --recursive --new-file v2.4.12/linux/Documentation/arm/README linux/Documentation/arm/README
--- v2.4.12/linux/Documentation/arm/README	Wed Apr 11 19:02:27 2001
+++ linux/Documentation/arm/README	Thu Oct 11 09:04:57 2001
@@ -162,7 +162,7 @@
     <description of your architecture>
 
   Please follow this format - it is an automated system.  You should
-  receive a reply within one day.
+  receive a reply in short order.
 
 ---
 Russell King (26/01/2001)
diff -u --recursive --new-file v2.4.12/linux/Documentation/arm/SA1100/ADSBitsy linux/Documentation/arm/SA1100/ADSBitsy
--- v2.4.12/linux/Documentation/arm/SA1100/ADSBitsy	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/arm/SA1100/ADSBitsy	Thu Oct 11 09:04:57 2001
@@ -0,0 +1,43 @@
+ADS Bitsy Single Board Computer
+(It is different from Bitsy(iPAQ) of Compaq)
+
+For more details, contact Applied Data Systems or see
+http://www.applieddata.net/products.html
+
+The Linux support for this product has been provided by
+Woojung Huh <whuh@applieddata.net>
+
+Use 'make adsbitsy_config' before any 'make config'.
+This will set up defaults for ADS Bitsy support.
+
+The kernel zImage is linked to be loaded and executed at 0xc0400000.
+
+Linux can  be used with the ADS BootLoader that ships with the
+newer rev boards. See their documentation on how to load Linux.
+
+Supported peripherals:
+- SA1100 LCD frame buffer (8/16bpp...sort of)
+- SA1111 USB Master
+- SA1100 serial port
+- pcmcia, compact flash
+- touchscreen(ucb1200)
+- console on LCD screen
+- serial ports (ttyS[0-2])
+  - ttyS0 is default for serial console
+
+To do:
+- everything else!  :-)
+
+Notes:
+
+- The flash on board is divided into 3 partitions.
+  You should be careful to use flash on board.
+  It's partition is different from GraphicsClient Plus and GraphicsMaster
+
+- 16bpp mode requires a different cable than what ships with the board.
+  Contact ADS or look through the manual to wire your own. Currently,
+  if you compile with 16bit mode support and switch into a lower bpp
+  mode, the timing is off so the image is corrupted.  This will be
+  fixed soon.
+
+Any contribution can be sent to nico@cam.org and will be greatly welcome!
diff -u --recursive --new-file v2.4.12/linux/Documentation/arm/SA1100/GraphicsMaster linux/Documentation/arm/SA1100/GraphicsMaster
--- v2.4.12/linux/Documentation/arm/SA1100/GraphicsMaster	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/arm/SA1100/GraphicsMaster	Thu Oct 11 09:04:57 2001
@@ -0,0 +1,53 @@
+ADS GraphicsMaster Single Board Computer
+
+For more details, contact Applied Data Systems or see
+http://www.applieddata.net/products.html
+
+The original Linux support for this product has been provided by
+Nicolas Pitre <nico@cam.org>. Continued development work by
+Woojung Huh <whuh@applieddata.net>
+
+Use 'make graphicsmaster_config' before any 'make config'.
+This will set up defaults for GraphicsMaster support.
+
+The kernel zImage is linked to be loaded and executed at 0xc0400000.
+
+Linux can  be used with the ADS BootLoader that ships with the
+newer rev boards. See their documentation on how to load Linux.
+
+Supported peripherals:
+- SA1100 LCD frame buffer (8/16bpp...sort of)
+- SA1111 USB Master
+- on-board SMC 92C96 ethernet NIC
+- SA1100 serial port
+- flash memory access (MTD/JFFS)
+- pcmcia, compact flash
+- touchscreen(ucb1200)
+- ps/2 keyboard
+- console on LCD screen
+- serial ports (ttyS[0-2])
+  - ttyS0 is default for serial console
+- Smart I/O (ADC, keypad, digital inputs, etc)
+  See http://www.applieddata.com/developers/linux for IOCTL documentation
+  and example user space code. ps/2 keybd is multiplexed through this driver
+
+To do:
+- everything else!  :-)
+
+Notes:
+
+- The flash on board is divided into 3 partitions.  mtd0 is where
+  the zImage is stored.  It's been marked as read-only to keep you
+  from blasting over the bootloader. :)  mtd1 is
+  for the ramdisk.gz image.  mtd2 is user flash space and can be
+  utilized for either JFFS or if you're feeling crazy, running ext2
+  on top of it. If you're not using the ADS bootloader, you're
+  welcome to blast over the mtd1 partition also.
+
+- 16bpp mode requires a different cable than what ships with the board.
+  Contact ADS or look through the manual to wire your own. Currently,
+  if you compile with 16bit mode support and switch into a lower bpp
+  mode, the timing is off so the image is corrupted.  This will be
+  fixed soon.
+
+Any contribution can be sent to nico@cam.org and will be greatly welcome!
diff -u --recursive --new-file v2.4.12/linux/Documentation/arm/SA1100/Pangolin linux/Documentation/arm/SA1100/Pangolin
--- v2.4.12/linux/Documentation/arm/SA1100/Pangolin	Sun Sep 23 11:40:54 2001
+++ linux/Documentation/arm/SA1100/Pangolin	Thu Oct 11 09:04:57 2001
@@ -2,7 +2,7 @@
 by Dialogue Technology (http://www.dialogue.com.tw/).
 It has EISA slots for ease of configuration with SDRAM/Flash
 memory card, USB/Serial/Audio card, Compact Flash card,
-and TFT-LCD card.
+PCMCIA/IDE card and TFT-LCD card.
 
 To compile for Pangolin, you must issue the following commands:
 
@@ -18,3 +18,7 @@
 - UDA1341 sound driver
 - SA1100 LCD controller for 800x600 16bpp TFT-LCD
 - MQ-200 driver for 800x600 16bpp TFT-LCD
+- Penmount(touch panel) driver
+- PCMCIA driver
+- SMC91C94 LAN driver
+- IDE driver (experimental)
diff -u --recursive --new-file v2.4.12/linux/Documentation/cciss.txt linux/Documentation/cciss.txt
--- v2.4.12/linux/Documentation/cciss.txt	Sat Feb  3 12:13:19 2001
+++ linux/Documentation/cciss.txt	Thu Oct 11 09:04:57 2001
@@ -8,8 +8,9 @@
 	* SA 5300
 	* SA 5i 
 	* SA 532
+	* SA 5312
 
-If notes are not already created in the /dev/cciss directory
+If nodes are not already created in the /dev/cciss directory
 
 # mkdev.cciss [ctlrs]
 
@@ -47,3 +48,78 @@
 /dev/cciss/c1d1p1		Controller 1, disk 1, partition 1
 /dev/cciss/c1d1p2		Controller 1, disk 1, partition 2
 /dev/cciss/c1d1p3		Controller 1, disk 1, partition 3
+
+SCSI tape drive and medium changer support
+------------------------------------------
+
+SCSI sequential access devices and medium changer devices are supported and 
+appropriate device nodes are automatically created.  (e.g.  
+/dev/st0, /dev/st1, etc.  See the "st" man page for more details.) 
+You must enable "SCSI tape drive support for Smart Array 5xxx" and 
+"SCSI support" in your kernel configuration to be able to use SCSI
+tape drives with your Smart Array 5xxx controller.
+
+Additionally, note that the driver will not engage the SCSI core at init 
+time.  The driver must be directed to dynamically engage the SCSI core via 
+the /proc filesystem entry which the "block" side of the driver creates as 
+/proc/driver/cciss/cciss* at runtime.  This is because at driver init time, 
+the SCSI core may not yet be initialized (because the driver is a block 
+driver) and attempting to register it with the SCSI core in such a case 
+would cause a hang.  This is best done via an initialization script 
+(typically in /etc/init.d, but could vary depending on distibution). 
+For example:
+
+	for x in /proc/driver/cciss/cciss[0-9]*
+	do
+		echo "engage scsi" > $x
+	done
+
+Once the SCSI core is engaged by the driver, it cannot be disengaged 
+(except by unloading the driver, if it happens to be linked as a module.)
+
+Note also that if no sequential access devices or medium changers are
+detected, the SCSI core will not be engaged by the action of the above
+script.
+
+Hot plug support for SCSI tape drives
+-------------------------------------
+
+Hot plugging of SCSI tape drives is supported, with some caveats.
+The cciss driver must be informed that changes to the SCSI bus
+have been made, in addition to and prior to informing the the SCSI 
+mid layer.  This may be done via the /proc filesystem.  For example:
+
+	echo "rescan" > /proc/scsi/cciss0/1
+
+This causes the adapter to query the adapter about changes to the 
+physical SCSI buses and/or fibre channel arbitrated loop and the 
+driver to make note of any new or removed sequential access devices
+or medium changers.  The driver will output messages indicating what 
+devices have been added or removed and the controller, bus, target and 
+lun used to address the device.  Once this is done, the SCSI mid layer 
+can be informed of changes to the virtual SCSI bus which the driver 
+presents to it in the usual way. For example: 
+
+	echo add-single-device 3 2 1 0 > /proc/scsi/scsi
+ 
+to add a device on controller 3, bus 2, target 1, lun 0.   Note that
+the driver makes an effort to preserve the devices positions
+in the virtual SCSI bus, so if you are only moving tape drives 
+around on the same adapter and not adding or removing tape drives 
+from the adapter, informing the SCSI mid layer may not be necessary.
+
+Note that the naming convention of the /proc filesystem entries 
+contains a number in addition to the driver name.  (E.g. "cciss0" 
+instead of just "cciss" which you might expect.)   This is because 
+of changes to the 2.4 kernel PCI interface related to PCI hot plug
+that imply the driver must register with the SCSI mid layer once per
+adapter instance rather than once per driver.
+
+Note: ONLY sequential access devices and medium changers are presented 
+as SCSI devices to the SCSI mid layer by the cciss driver.  Specifically, 
+physical SCSI disk drives are NOT presented to the SCSI mid layer.  The 
+physical SCSI disk drives are controlled directly by the array controller 
+hardware and it is important to prevent the OS from attempting to directly 
+access these devices too, as if the array controller were merely a SCSI 
+controller in the same way that we are allowing it to access SCSI tape drives.
+
diff -u --recursive --new-file v2.4.12/linux/Documentation/i2c/dev-interface linux/Documentation/i2c/dev-interface
--- v2.4.12/linux/Documentation/i2c/dev-interface	Fri Jul 28 12:50:51 2000
+++ linux/Documentation/i2c/dev-interface	Thu Oct 11 08:05:47 2001
@@ -70,6 +70,9 @@
     /* buf[0] contains the read byte */
   }
 
+IMPORTANT: because of the use of inline functions, you *have* to use
+'-O' or some variation when you compile your program!
+
 
 Full interface description
 ==========================
diff -u --recursive --new-file v2.4.12/linux/Documentation/i2c/summary linux/Documentation/i2c/summary
--- v2.4.12/linux/Documentation/i2c/summary	Thu Dec 16 13:59:38 1999
+++ linux/Documentation/i2c/summary	Thu Oct 11 08:05:47 2001
@@ -1,9 +1,9 @@
-This is an explanation of what i2c is, and what is supported.
+This is an explanation of what i2c is, and what is supported in this package.
 
 I2C and SMBus
 =============
 
-I2C (pronounce: I square C) is a protocol developed by Philips. It is a 
+I2C (pronounce: I squared C) is a protocol developed by Philips. It is a 
 slow two-wire protocol (10-100 kHz), but it suffices for many types of 
 devices.
 
@@ -25,6 +25,7 @@
             Adapter
   Device -> Driver
             Client
+
 An Algorithm driver contains general code that can be used for a whole class
 of I2C adapters. Each specific adapter driver depends on one algorithm
 driver.
@@ -35,29 +36,40 @@
 
 For a given configuration, you will need a driver for your I2C bus (usually
 a separate Adapter and Algorithm driver), and drivers for your I2C devices
-(usually one driver for each device).
+(usually one driver for each device). There are no I2C device drivers
+in this package. See the lm_sensors project http://www.lm-sensors.nu
+for device drivers.
+
 
+Included Bus Drivers
+====================
+Note that not only stable drivers are patched into the kernel by 'mkpatch'.
 
-Included Drivers
-================
 
 Base modules
 ------------
 
 i2c-core: The basic I2C code, including the /proc interface
 i2c-dev:  The /dev interface
+i2c-proc: The /proc interface for device (client) drivers
 
 Algorithm drivers
 -----------------
 
-i2c-algo-bit: A bit-banging algorithm
-i2c-algo-pcf: A PCF 8584 style algorithm
+i2c-algo-8xx:    An algorithm for CPM's I2C device in Motorola 8xx processors (NOT BUILT BY DEFAULT)
+i2c-algo-bit:    A bit-banging algorithm
+i2c-algo-pcf:    A PCF 8584 style algorithm
+i2c-algo-ppc405: An algorithm for the I2C device in IBM 405xx processors (NOT BUILT BY DEFAULT)
 
 Adapter drivers
 ---------------
 
 i2c-elektor:     Elektor ISA card (uses i2c-algo-pcf)
 i2c-elv:         ELV parallel port adapter (uses i2c-algo-bit)
+i2c-pcf-epp:     PCF8584 on a EPP parallel port (uses i2c-algo-pcf) (BROKEN - missing i2c-pcf-epp.h)
 i2c-philips-par: Philips style parallel port adapter (uses i2c-algo-bit)
+i2c-ppc405:      IBM 405xx processor I2C device (uses i2c-algo-ppc405) (NOT BUILT BY DEFAULT)
+i2c-pport:       Primitive parallel port adapter (uses i2c-algo-bit)
+i2c-rpx:         RPX board Motorola 8xx I2C device (uses i2c-algo-8xx) (NOT BUILT BY DEFAULT)
 i2c-velleman:    Velleman K9000 parallel port adapter (uses i2c-algo-bit)
 
diff -u --recursive --new-file v2.4.12/linux/Documentation/i2c/writing-clients linux/Documentation/i2c/writing-clients
--- v2.4.12/linux/Documentation/i2c/writing-clients	Fri Jul 28 12:50:51 2000
+++ linux/Documentation/i2c/writing-clients	Thu Oct 11 08:05:47 2001
@@ -33,7 +33,7 @@
     /* detach_client  */  &foo_detach_client,
     /* command        */  &foo_command,   /* May be NULL */
     /* inc_use        */  &foo_inc_use,   /* May be NULL */
-    /* dec_use        */  &foo_dev_use    /* May be NULL */
+    /* dec_use        */  &foo_dec_use    /* May be NULL */
   }
  
 The name can be chosen freely, and may be upto 40 characters long. Please
@@ -190,7 +190,7 @@
 detection algorithm.
 
 You do not have to use this parameter interface; but don't try to use
-function i2c_probe() (or sensors_detect()) if you don't.
+function i2c_probe() (or i2c_detect()) if you don't.
 
 NOTE: If you want to write a `sensors' driver, the interface is slightly
       different! See below.
@@ -344,17 +344,17 @@
     return i2c_probe(adapter,&addr_data,&foo_detect_client);
   }
 
-For `sensors' drivers, use the sensors_detect function instead:
+For `sensors' drivers, use the i2c_detect function instead:
   
   int foo_attach_adapter(struct i2c_adapter *adapter)
   { 
-    return sensors_detect(adapter,&addr_data,&foo_detect_client);
+    return i2c_detect(adapter,&addr_data,&foo_detect_client);
   }
 
 Remember, structure `addr_data' is defined by the macros explained above,
 so you do not have to define it yourself.
 
-The i2c_probe or sensors_detect function will call the foo_detect_client
+The i2c_probe or i2c_detect function will call the foo_detect_client
 function only for those i2c addresses that actually have a device on
 them (unless a `force' parameter was used). In addition, addresses that
 are already in use (by some other registered client) are skipped.
@@ -363,9 +363,9 @@
 The detect client function
 --------------------------
 
-The detect client function is called by i2c_probe or sensors_detect.
+The detect client function is called by i2c_probe or i2c_detect.
 The `kind' parameter contains 0 if this call is due to a `force'
-parameter, and 0 otherwise (for sensors_detect, it contains 0 if
+parameter, and 0 otherwise (for i2c_detect, it contains 0 if
 this call is due to the generic `force' parameter, and the chip type
 number if it is due to a specific `force' parameter).
 
@@ -530,7 +530,7 @@
     /* SENSORS ONLY BEGIN */
     /* Register a new directory entry with module sensors. See below for
        the `template' structure. */
-    if ((i = sensors_register_entry(new_client, type_name,
+    if ((i = i2c_register_entry(new_client, type_name,
                                     foo_dir_table_template,THIS_MODULE)) < 0) {
       err = i;
       goto ERROR4;
@@ -574,8 +574,8 @@
     int err,i;
 
     /* SENSORS ONLY START */
-    /* Deregister with the `sensors' module. */
-    sensors_deregister_entry(((struct lm78_data *)(client->data))->sysctl_id);
+    /* Deregister with the `i2c-proc' module. */
+    i2c_deregister_entry(((struct lm78_data *)(client->data))->sysctl_id);
     /* SENSORS ONLY END */
 
     /* Try to detach the client from i2c space */
@@ -772,12 +772,12 @@
 
 First, I will give an example definition.
   static ctl_table foo_dir_table_template[] = {
-    { FOO_SYSCTL_FUNC1, "func1", NULL, 0, 0644, NULL, &sensors_proc_real,
-      &sensors_sysctl_real,NULL,&foo_func },
-    { FOO_SYSCTL_FUNC2, "func2", NULL, 0, 0644, NULL, &sensors_proc_real,
-      &sensors_sysctl_real,NULL,&foo_func },
-    { FOO_SYSCTL_DATA, "data", NULL, 0, 0644, NULL, &sensors_proc_real,
-      &sensors_sysctl_real,NULL,&foo_data },
+    { FOO_SYSCTL_FUNC1, "func1", NULL, 0, 0644, NULL, &i2c_proc_real,
+      &i2c_sysctl_real,NULL,&foo_func },
+    { FOO_SYSCTL_FUNC2, "func2", NULL, 0, 0644, NULL, &i2c_proc_real,
+      &i2c_sysctl_real,NULL,&foo_func },
+    { FOO_SYSCTL_DATA, "data", NULL, 0, 0644, NULL, &i2c_proc_real,
+      &i2c_sysctl_real,NULL,&foo_data },
     { 0 }
   };
 
@@ -791,8 +791,8 @@
 fourth should always be 0. The fifth is the mode of the /proc file;
 0644 is safe, as the file will be owned by root:root. 
 
-The seventh and eighth parameters should be &sensors_proc_real and
-&sensors_sysctl_real if you want to export lists of reals (scaled
+The seventh and eighth parameters should be &i2c_proc_real and
+&i2c_sysctl_real if you want to export lists of reals (scaled
 integers). You can also use your own function for them, as usual.
 Finally, the last parameter is the call-back to gather the data
 (see below) if you use the *_proc_real functions. 
diff -u --recursive --new-file v2.4.12/linux/Documentation/s390/CommonIO linux/Documentation/s390/CommonIO
--- v2.4.12/linux/Documentation/s390/CommonIO	Sun Aug 12 13:27:58 2001
+++ linux/Documentation/s390/CommonIO	Thu Oct 11 09:04:57 2001
@@ -101,6 +101,17 @@
   the device driver will be notified if possible, so the device will become
   available to the system.
 
+  You can also add ranges of devices to be ignored by piping to 
+  /proc/cio_ignore; "add <devnorange>, <devnorange>, ..." will ignore the 
+  specified devices.
+
+  Note: Already known devices cannot be ignored; this also applies to devices
+        which are gone after a machine check.
+
+  For example, if device abcd is already known and all other devices a000-afff 
+  are not known, "echo add 0xa000-0xaccc, 0xaf00-0xafff > /proc/cio_ignore" 
+  will add af00-afff to the list of ignored devices and skip a000-accc.
+
 
 * /proc/s390dbf/cio_*/ (S/390 debug feature)
 
@@ -122,3 +133,7 @@
   /proc/s390dbf/cio_*/level a number between 0 and 6; see the documentation on
   the S/390 debug feature (Documentation/s390/s390dbf.txt) for details.
 
+* /proc/irq_count
+
+  This entry counts how many times s390_process_IRQ has been called for each 
+  CPU. This info is in /proc/interrupts on other architectures.
diff -u --recursive --new-file v2.4.12/linux/Documentation/s390/chandev.8 linux/Documentation/s390/chandev.8
--- v2.4.12/linux/Documentation/s390/chandev.8	Sun Aug 12 13:27:58 2001
+++ linux/Documentation/s390/chandev.8	Thu Oct 11 09:04:57 2001
@@ -124,17 +124,16 @@
 .B (ctc|escon|lcs|osad|qeth)<devif_num>, 
 read_devno,write_devno,<data_devno,memory_usage_in_k,port_no/protocol_no,checksum_received_ip_pkts,use_hw_stats>
 .It
-devif_num of -1 indicates you don't care what device interface number is chosen, omitting it indicates this is a range of devices for which you want to force to be detected as a particular type.
-The data_devno field is only valid for qeth devices when not forcing a range of devices.
-all parameters after & including memory_usage_in_k can be set optionally if not set they
+devif_num of -1 indicates you don't care what device interface number is chosen, omitting it indicates this is a range of devices for which you want to force to be detected as a particular type, qeth devices can't be forced as a range as it makes no sense for them.
+The data_devno field is only valid for qeth devices, all parameters including & after memory_usage_in_k can be set optionally, if not set they
 go to default values. memory_usage_in_k ( 0 the default ) means let the driver choose,checksum_received_ip_pkts & use_hw_stats are set to false
 .It
 e.g. ctc0,0x7c00,0x7c01
 .It
 Tells the channel layer to force ctc0 if detected to use cuu's 7c00 & 7c01 port,port_no is the relative adapter no on lcs, on ctc/escon this field is the ctc/escon protocol number ( default 0 ), don't do checksumming on received ip packets & as ctc doesn't have hardware stats so it ignores this parameter. This can be used for instance to force a device if it presents bad sense data to the IO layer & thus autodetection fails.
 .It
-qeth,0x7c00,0x7d00,-1,4096
-All devices between 0x7c00 & 7d00 should be detected as gigabit ethernet, let the driver use 4096k for each instance, don't care what port relative adapter number is chosen, don't checksum received ip packets & use hw stats .
+lcs,0x7c00,0x7d00,-1,4096
+All devices between 0x7c00 & 7d00 should be detected as lcs, let the driver use 4096k for each instance, don't care what port relative adapter number is chosen, don't checksum received ip packets & use hw stats .
 .It
 qeth1,0x7c00,0x7c01,0x7c02
 .It
@@ -368,6 +367,12 @@
 Force drivers modules to stay loaded even if no device is found,
 this is useful for debugging & one wishes to examine debug entries in 
 /proc/s390dbf/ to find out why a module failed to load.
+.It
+e.g.
+.It
+persist,-1 forces all devices to persist.
+.It
+persist,0 forces all channel devices to be non persistent.
 .El
 
 .It
diff -u --recursive --new-file v2.4.12/linux/Documentation/s390/s390dbf.txt linux/Documentation/s390/s390dbf.txt
--- v2.4.12/linux/Documentation/s390/s390dbf.txt	Wed Apr 11 19:02:27 2001
+++ linux/Documentation/s390/s390dbf.txt	Thu Oct 11 09:04:57 2001
@@ -336,7 +336,7 @@
 Example:
 
 > ls /proc/s390dbf/dasd
-hex_ascii  level      raw
+flush  hex_ascii  level      raw 
 > cat /proc/s390dbf/dasd/hex_ascii | sort +1
 00 00974733272:680099 2 - 02 0006ad7e  07 ea 4a 90 | ....
 00 00974733272:682210 2 - 02 0006ade6  46 52 45 45 | FREE
@@ -362,6 +362,20 @@
 > echo "5" > /proc/s390dbf/dasd/level
 > cat /proc/s390dbf/dasd/level
 5
+
+Flushing debug areas
+--------------------
+Debug areas can be flushed with piping the number of the desired
+area (0...n) to the proc file "flush". When using "-" all debug areas
+are flushed.
+
+Examples:
+
+1. Flush debug area 0:
+> echo "0" > /proc/s390dbf/dasd/flush  
+
+2. Flush all debug areas:
+> echo "-" > /proc/s390dbf/dasd/flush
 
 lcrash Interface
 ----------------
diff -u --recursive --new-file v2.4.12/linux/Documentation/sonypi.txt linux/Documentation/sonypi.txt
--- v2.4.12/linux/Documentation/sonypi.txt	Mon Aug 27 12:41:37 2001
+++ linux/Documentation/sonypi.txt	Thu Oct 11 09:04:57 2001
@@ -15,6 +15,8 @@
 	- capture button events (only on Vaio Picturebook series)
 	- Fn keys
 	- bluetooth button (only on C1VR model)
+	- back button (PCG-GR7/K model)
+	- lid open/close events (Z600NE model)
 
 Those events (see linux/sonypi.h) can be polled using the character device node
 /dev/sonypi (major 10, minor auto allocated or specified as a option).
@@ -36,6 +38,14 @@
 Module options:
 ---------------
 
+Several options can be passed to the sonypi driver, either by adding them
+to /etc/modules.conf file, when the driver is compiled as a module or by
+adding the following to the kernel command line (in your bootloader):
+
+	sonypi=minor[[[[,camera],fnkeyinit],verbose],compat]
+
+where:
+
 	minor: 		minor number of the misc device /dev/sonypi, 
 			default is -1 (automatic allocation, see /proc/misc
 			or kernel logs)
@@ -48,6 +58,11 @@
 			get enabled unless you set this parameter to 1
 
 	verbose:	print unknown events from the sonypi device
+
+	compat:		uses some compatibility code for enabling the sonypi
+			events. If the driver worked for you in the past
+			(prior to version 1.5) and does not work anymore,
+			add this option and report to the author.
 
 Module use:
 -----------
diff -u --recursive --new-file v2.4.12/linux/Documentation/video4linux/README.buz linux/Documentation/video4linux/README.buz
--- v2.4.12/linux/Documentation/video4linux/README.buz	Thu Jan  6 14:46:18 2000
+++ linux/Documentation/video4linux/README.buz	Wed Dec 31 16:00:00 1969
@@ -1,212 +0,0 @@
-Iomega Buz Driver for Linux
-===========================
-
-by Rainer Johanni <Rainer@Johanni.de>
-
-Compiling and Loading the Driver
-================================
-
-You must run a 2.2.x kernel in order to use this driver.
-
-To compile the driver, just type make.
-
-Besides the files in this directory, the driver needs the
-'videodev' and the 'i2c' module from the Linux kernel.
-In order to get these modules available, enable module support
-for VIDEODEV and BTTV (which implies i2c) in your kernel
-configuration. You find these devices in the menu
-"Character Devices" in your Kernel Configuration.
-
-Before you load the driver you must have a video device
-at major device node 81. If you don't have it yet, do the
-following (as root!):
-
-cd /dev
-mknod video0 c 81 0
-ln -s video0 video
-
-Edit the 'update' script if you want to give the driver
-special options and then type (as root)
-
-./update
-
-to insert all the necessary modules into the kernel.
-
-If you want to make full use of the Video for Linux uncompressed
-grabbing facilities, you must either
-
-- obtain and install the "big_physarea patch" for your kernel and
-  set aside the necessary memory during boot time.
-  There seem to be several versions of this patch against
-  various kernel versions floating around in the net,
-  you may obtain one e.g. from:
-  http://www.polyware.nl/~middelin/patch/bigphysarea-2.2.1.tar.gz
-  You also have to compile your driver AFTER installing that patch
-  in order to get it working
-
-  or
-
-- start your kernel with the mem=xxx option, where xxx is your
-  real memory minus the memory needed for the buffers.
-  For doing this add an entry in lilo.conf (if you use lilo):
-    append "mem=xxxM"
-  or add a line in your linux.par file (if you use loadlin):
-    mem=xxxM
-
-The second method is by far easier, however it is dangerous
-if more than one driver at a time has the idea to use the memory
-leftover by setting the mem=xxx parameter below the actual
-memory size.
-
-Read also below how to use this memory!
-
-
-
-Driver Options
-==============
-
-You are able to customize the behavior of the driver by giving
-it some options at start time.
-
-default_input, default_norm
----------------------------
-
-As soon as the driver is loaded, the Buz samples video signals
-from one of its input ports and displays it on its output.
-The driver uses the Composite Input and the video norm PAL for this.
-If you want to change this default behavior, set default_input=1
-(for S-VHS input) or default_norm=1 for NTSC.
-
-v4l_nbufs, v4l_bufsize
-----------------------
-
-In order to make to make full use of the Video for Linux picture
-grabbing facilities of the driver (which are needed by many
-Video for Linux applications), the driver needs a set of
-physically contiguous buffers for grabbing. These parameters
-determine how many buffers of which size the driver will
-allocate at open (the open will fail if it is unable to do so!).
-
-These values do not affect the MJPEG grabbing facilities of the driver,
-they are needed for uncompressed image grabbing only!!!
-
-v4l_nbufs is the number of buffers to allocate, a value of 2 (the default)
-should be sufficient in almost all cases. Only special applications
-(streaming captures) will need more buffers and then mostly the
-MJPEG capturing features of the Buz will be more appropriate.
-So leave this parameter at it's default unless you know what you do.
-
-The things for v4l_bufsize are more complicated:
-v4l_bufsize is set by default to 128 [KB] which is the maximum
-amount of physically contiguous memory Linux is able to allocate
-without kernel changes. This is sufficient for grabbing 24 bit color images
-up to sizes of approx. 240x180 pixels (240*180*3 = 129600, 128 KB = 131072).
-
-In order to be able to capture bigger images you have either to
-- obtain and install the "big_physarea patch" and set aside
-  the necessary memory during boot time or
-- start your kernel with the mem=xxx option, where xxx is your
-  real memory minus the memory needed for the buffers.
-In that case, useful settings for v4l_bufsize are
-- 1296 [Kb] for grabbing 24 bit images of max size 768*576
-- 1728 [Kb] for 32bit images of same size (4*768*576 = 1728 Kb!)
-You may reduce these numbers accordingly if you know you are only
-grabbing 720 pixels wide images or NTSC images (max height 480).
-
-In some cases it may happen that Linux isn't even able to obtain
-the default 128 KB buffers. If you don't need uncompressed image
-grabbing at all, set v4l_bufsize to an arbitrary small value (e.g. 4)
-in order to be able to open the video device.
-
-vidmem
-------
-
-The video mem address of the video card.
-The driver has a little database for some videocards
-to determine it from there. If your video card is not in there
-you have either to give it to the driver as a parameter
-or set in in a VIDIOCSFBUF ioctl
-
-The videocard database is contained in the file "videocards.h"
-Gernot Ziegler wants to keep an actual version of that file.
-If your card is not contained in that file, look at
-http://www.lysator.liu.se/~gz/buz/ for an actual version of
-"videocards.h".
-
-triton, natoma
---------------
-
-The driver tries to detect if you have a triton or natome chipset
-in order to take special measures for these chipsets.
-If this detection fails but you are sure you have such a chipset,
-set the corresponding variable to 1.
-This is a very special option and may go away in the future.
-
-
-
-Programming interface
-=====================
-
-This driver should be fully compliant to Video for Linux, so all
-tools working with Video for Linux should work with (hopefully)
-no problems.
-
-A description of the Video for Linux programming interface can be found at:
-http://roadrunner.swansea.linux.org.uk/v4lapi.shtml
-
-Besides the Video for Linux interface, the driver has a "proprietary"
-interface for accessing the Buz's MJPEG capture and playback facilities.
-
-The ioctls for that interface are as follows:
-
-BUZIOC_G_PARAMS
-BUZIOC_S_PARAMS
-
-Get and set the parameters of the buz. The user should always
-do a BUZIOC_G_PARAMS (with a struct buz_params) to obtain the default
-settings, change what he likes and then make a BUZIOC_S_PARAMS call.
-A typical application should at least set the members
-input, norm and decimation of the struct buz_params.
-For a full description of all members see "buz.h"
-
-BUZIOC_REQBUFS
-
-Before being able to capture/playback, the user has to request
-the buffers he is wanting to use. Fill the structure
-buz_requestbuffers with the size (recommended: 256*1024) and
-the number (recommended 32 up to 256). There are no such restrictions
-as for the Video for Linux buffers, you should LEAVE SUFFICIENT
-MEMORY for your system however, else strange things will happen ....
-On return, the buz_requestbuffers structure contains number and
-size of the actually allocated buffers.
-You should use these numbers for doing a mmap of the buffers
-into the user space.
-The BUZIOC_REQBUFS ioctl also makes it happen, that the next mmap
-maps the MJPEG buffer instead of the V4L buffers.
-
-BUZIOC_QBUF_CAPT
-BUZIOC_QBUF_PLAY
-
-Queue a buffer for capture or playback. The first call also starts
-streaming capture. When streaming capture is going on, you may
-only queue further buffers or issue syncs until streaming
-capture is switched off again with a argument of -1 to
-a BUZIOC_QBUF_CAPT/BUZIOC_QBUF_PLAY ioctl.
-
-BUZIOC_SYNC
-
-Issue this ioctl when all buffers are queued. This ioctl will
-block until the first buffer becomes free for saving its
-data to disk (after BUZIOC_QBUF_CAPT) or for reuse (after BUZIOC_QBUF_PLAY).
-
-BUZIOC_G_STATUS
-
-Get the status of the input lines (video source connected/norm).
-This ioctl may be subject to change.
-
-
-
-
-
-See the examples directory delivered with this driver
-for actual coding examples!
diff -u --recursive --new-file v2.4.12/linux/Documentation/video4linux/meye.txt linux/Documentation/video4linux/meye.txt
--- v2.4.12/linux/Documentation/video4linux/meye.txt	Wed Jul 25 17:10:17 2001
+++ linux/Documentation/video4linux/meye.txt	Thu Oct 11 09:04:57 2001
@@ -4,7 +4,10 @@
 	Copyright (C) 2000 Andrew Tridgell <tridge@samba.org>
 
 This driver enable the use of video4linux compatible applications with the
-Motion Eye camera.
+Motion Eye camera. This driver requires the "Sony Vaio Programmable I/O 
+Control Device" driver (which can be found in the "Character drivers" 
+section of the kernel configuration utility) to be compiled and installed
+(using its "camera=1" parameter).
 
 It can do at maximum 30 fps @ 320x240 or 15 fps @ 640x480.
 
diff -u --recursive --new-file v2.4.12/linux/MAINTAINERS linux/MAINTAINERS
--- v2.4.12/linux/MAINTAINERS	Tue Oct  9 17:06:51 2001
+++ linux/MAINTAINERS	Thu Oct 11 09:04:57 2001
@@ -1053,6 +1053,12 @@
 L:     linux-net@vger.kernel.org
 S:     Maintained
 
+NINJA SCSI-3 / NINJA SCSI-32Bi PCMCIA SCSI HOST ADAPTER DRIVER
+P:	YOKOTA Hiroshi
+M:	yokota@netlab.is.tsukuba.ac.jp
+W:	http://www.netlab.is.tsukuba.ac.jp/~yokota/izumi/ninja/
+S:	Maintained
+
 NON-IDE/NON-SCSI CDROM DRIVERS [GENERAL] (come on, crew - mark your responsibility)
 P:	Eberhard Moenkeberg
 M:	emoenke@gwdg.de
@@ -1397,6 +1403,13 @@
 L:	linux-net@vger.kernel.org
 L:	linux-tr@linuxtr.net
 W:	http://www.linuxtr.net
+S:	Maintained
+
+TOSHIBA SMM DRIVER
+P:	Jonathan Buzzard
+M:	jonathan@buzzard.org.uk
+L:	tlinux-users@tce.toshiba-dme.co.jp
+W:	http://www.buzzard.org.uk/toshiba/
 S:	Maintained
 
 TRIDENT 4DWAVE/SIS 7018 PCI AUDIO CORE
diff -u --recursive --new-file v2.4.12/linux/Makefile linux/Makefile
--- v2.4.12/linux/Makefile	Thu Oct 11 08:02:26 2001
+++ linux/Makefile	Thu Oct 11 08:34:28 2001
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
-SUBLEVEL = 12
-EXTRAVERSION =
+SUBLEVEL = 13
+EXTRAVERSION =-pre1
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -u --recursive --new-file v2.4.12/linux/arch/arm/Makefile linux/arch/arm/Makefile
--- v2.4.12/linux/arch/arm/Makefile	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/Makefile	Thu Oct 11 09:04:57 2001
@@ -45,8 +45,6 @@
 CFLAGS		+=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float
 AFLAGS		+=$(apcs-y) $(arch-y) -mno-fpu
 
-LIBGCC		:= $(shell $(CC) $(CFLAGS) --print-libgcc-file-name)
-
 ifeq ($(CONFIG_CPU_26),y)
 PROCESSOR	 = armo
   ifeq ($(CONFIG_ROM_KERNEL),y)
@@ -123,7 +121,7 @@
 endif
 
 ifeq ($(CONFIG_ARCH_CLPS711X),y)
-TEXTADDR	 = 0xc0018000
+TEXTADDR	 = 0xc0028000
 MACHINE		 = clps711x
 endif
 
@@ -131,7 +129,7 @@
 MACHINE		 = anakin
 endif
 
-export	LIBGCC MACHINE PROCESSOR TEXTADDR GZFLAGS
+export	MACHINE PROCESSOR TEXTADDR GZFLAGS
 
 # Only set INCDIR if its not already defined above
 # Grr, ?= doesn't work as all the other assignment operators do.  Make bug?
@@ -155,7 +153,7 @@
 SUBDIRS		+= arch/arm/kernel arch/arm/mm arch/arm/lib arch/arm/nwfpe \
 		   arch/arm/fastfpe
 CORE_FILES	:= arch/arm/kernel/kernel.o arch/arm/mm/mm.o $(CORE_FILES)
-LIBS		:= arch/arm/lib/lib.a $(LIBS) $(LIBGCC)
+LIBS		:= arch/arm/lib/lib.a $(LIBS)
 
 ifeq ($(CONFIG_FPE_NWFPE),y)
 LIBS		:= arch/arm/nwfpe/math-emu.o $(LIBS)
diff -u --recursive --new-file v2.4.12/linux/arch/arm/boot/Makefile linux/arch/arm/boot/Makefile
--- v2.4.12/linux/arch/arm/boot/Makefile	Tue Jul  3 17:08:18 2001
+++ linux/arch/arm/boot/Makefile	Thu Oct 11 09:04:57 2001
@@ -69,12 +69,21 @@
 ZBSSADDR	 = 0xf03e0000
 endif
 
-ifeq ($(CONFIG_ARCH_P720T),y)
-ZTEXTADDR	 = 0xc0018000
+# The standard locations for stuff on CLPS711x type processors
+ifeq ($(CONFIG_ARCH_CLPS711X),y)
+ZTEXTADDR	 = 0xc0028000
 PARAMS_PHYS	 = 0xc0000100
+endif
+
+# Should probably have some agreement on these...
+ifeq ($(CONFIG_ARCH_P720T),y)
 INITRD_PHYS	 = 0xc0400000
 INITRD_VIRT	 = 0xc0400000
 endif
+ifeq ($(CONFIG_ARCH_CDB89712),y)
+INITRD_PHYS	 = 0x00700000
+INITRD_VIRT	 = 0xc0300000
+endif
 
 ifeq ($(CONFIG_ARCH_SA1100),y)
 ZTEXTADDR	 = 0xc0008000
@@ -89,6 +98,12 @@
 endif
 ifeq ($(CONFIG_SA1100_GRAPHICSCLIENT),y)
   ZTEXTADDR	 = 0xC0200000
+endif
+ifeq ($(CONFIG_SA1100_GRAPHICSMASTER),y)
+  ZTEXTADDR	 = 0xC0400000
+endif
+ifeq ($(CONFIG_SA1100_ADSBITSY),y)
+  ZTEXTADDR	 = 0xC0400000
 endif
 ifeq ($(CONFIG_SA1100_YOPY),y)
   ZTEXTADDR      = 0x00080000
diff -u --recursive --new-file v2.4.12/linux/arch/arm/boot/bootp/Makefile linux/arch/arm/boot/bootp/Makefile
--- v2.4.12/linux/arch/arm/boot/bootp/Makefile	Thu Feb  8 16:32:44 2001
+++ linux/arch/arm/boot/bootp/Makefile	Thu Oct 11 09:04:57 2001
@@ -3,7 +3,6 @@
 #
 
 ZSYSTEM		=$(TOPDIR)/arch/arm/boot/zImage
-INITRD		=$(ZSYSTEM)
 ZLDFLAGS	=-p -X -T bootp.lds \
 		 --defsym initrd_addr=$(INITRD_PHYS) \
 		 --defsym initrd_virt=$(INITRD_VIRT) \
diff -u --recursive --new-file v2.4.12/linux/arch/arm/boot/bootp/init.S linux/arch/arm/boot/bootp/init.S
--- v2.4.12/linux/arch/arm/boot/bootp/init.S	Thu Feb  8 16:32:44 2001
+++ linux/arch/arm/boot/bootp/init.S	Thu Oct 11 09:04:57 2001
@@ -39,7 +39,7 @@
  * method by looking at the first word; this should either indicate a page
  * size of 4K, 16K or 32K.
  */
-		ldmia	r13, {r5-r8}		@ get size and addr of initrd
+		ldmia	r13, {r4-r8}		@ get size and addr of initrd
 						@ r5 = ATAG_INITRD
 						@ r6 = initrd start
 						@ r7 = initrd end
@@ -48,10 +48,25 @@
 		teq	r9, #0x1000		@ 4K?
 		teqne	r9, #0x4000		@ 16K?
 		teqne	r9, #0x8000		@ 32K?
-		beq	no_taglist
+		beq	param_struct
+
+		ldr	r9, [r8, #4]		@ get first tag
+		teq	r9, r4
+		bne	taglist			@ ok, we have a tag list
+
+/*
+ * We didn't find a valid tag list - create one.
+ */
+		str	r4, [r8, #4]
+		mov	r4, #8
+		str	r4, [r8, #0]
+		mov	r4, #0
+		str	r4, [r8, #8]
 
 /*
  * find the end of the tag list, and then add an INITRD tag on the end.
+ * If there is already an INITRD tag, then we ignore it; the last INITRD
+ * tag takes precidence.
  */
 taglist:	ldr	r9, [r8, #0]		@ tag length
 		teq	r9, #0			@ last tag?
@@ -63,7 +78,10 @@
 		stmia	r8, {r4, r5, r6, r7, r9}
 		mov	pc, r12			@ call kernel
 
-no_taglist:	add	r8, r8, #16*4
+/*
+ * We found a param struct.  Modify the param struct for the initrd
+ */
+param_struct:	add	r8, r8, #16*4
 		stmia	r8, {r6,r7}		@ save in param_struct
 		mov	pc, r12			@ call kernel
 
@@ -83,6 +101,7 @@
 		.word	kernel_addr
 		.word	kernel_len
 
+		.word	0x54410001		@ r4 = ATAG_CORE
 		.word	0x54410005		@ r5 = ATAG_INITRD
 		.word	initrd_virt		@ r6
 		.word	initrd_len		@ r7
diff -u --recursive --new-file v2.4.12/linux/arch/arm/boot/compressed/Makefile linux/arch/arm/boot/compressed/Makefile
--- v2.4.12/linux/arch/arm/boot/compressed/Makefile	Tue Jul  3 17:08:18 2001
+++ linux/arch/arm/boot/compressed/Makefile	Thu Oct 11 09:04:57 2001
@@ -51,7 +51,7 @@
 endif
 
 ifeq ($(CONFIG_ARCH_SA1100),y)
-OBJS		+= head-sa1100.o setup-sa1100.o
+OBJS		+= head-sa1100.o
 ifeq ($(CONFIG_SA1100_NANOENGINE),y)
   OBJS += hw-bse.o
 endif
@@ -64,6 +64,8 @@
 else
 SEDFLAGS	+= s/BSS_START/ALIGN(4)/
 endif
+
+LIBGCC		:= $(shell $(CC) $(CFLAGS) --print-libgcc-file-name)
 
 all:		vmlinux
 
diff -u --recursive --new-file v2.4.12/linux/arch/arm/boot/compressed/head-sa1100.S linux/arch/arm/boot/compressed/head-sa1100.S
--- v2.4.12/linux/arch/arm/boot/compressed/head-sa1100.S	Thu Feb  8 16:32:44 2001
+++ linux/arch/arm/boot/compressed/head-sa1100.S	Thu Oct 11 09:04:57 2001
@@ -17,6 +17,24 @@
 
 		@ Preserve r8/r7 i.e. kernel entry values
 
+#if defined(CONFIG_SA1100_GRAPHICSCLIENT) && !defined(CONFIG_ANGELBOOT)
+		mov	r7, #MACH_TYPE_GRAPHICSCLIENT
+		mov	r8, #0
+#endif
+#if defined(CONFIG_SA1100_GRAPHICSMASTER) && !defined(CONFIG_ANGELBOOT)
+		mov	r7, #MACH_TYPE_GRAPHICSMASTER
+		mov	r8, #0
+#endif
+#if defined(CONFIG_SA1100_ADSBITSY) && !defined(CONFIG_ANGELBOOT)
+		mov	r7, #MACH_TYPE_ADSBITSY
+		mov	r8, #0
+#endif
+
+#ifdef CONFIG_SA1100_PFS168
+		@ REVISIT_PFS168: Temporary until firmware updated to use assigned machine number
+		mov	r7, #MACH_TYPE_PFS168
+#endif
+
 #ifdef CONFIG_SA1100_VICTOR
 		teq	r7, #MACH_TYPE_VICTOR
 		bne	10f
@@ -51,7 +69,6 @@
 		bic	r0, r0, #0x1000		@ clear Icache
 		mcr	p15, 0, r0, c1, c0, 0
 
-#ifdef CONFIG_ANGELBOOT
 /*
  * Pause for a short time so that we give enough time
  * for the host to start a terminal up.
@@ -59,5 +76,4 @@
 		mov	r0, #0x00200000
 1:		subs	r0, r0, #1
 		bne	1b
-#endif
 
diff -u --recursive --new-file v2.4.12/linux/arch/arm/boot/compressed/setup-sa1100.S linux/arch/arm/boot/compressed/setup-sa1100.S
--- v2.4.12/linux/arch/arm/boot/compressed/setup-sa1100.S	Tue Jul  3 17:08:18 2001
+++ linux/arch/arm/boot/compressed/setup-sa1100.S	Wed Dec 31 16:00:00 1969
@@ -1,163 +0,0 @@
-/*
- * linux/arch/arm/boot/compressed/setup-sa1100.S
- *
- * Copyright (C) 2000 Nicolas Pitre <nico@cam.org>
- *
- * SA1100 setup routines, to be used after BSS has been cleared.
- *
- * John G Dorsey <john+@cs.cmu.edu>  2000/05/25 :
- *  Runtime test for Neponset added.
- */
-
-#include <linux/linkage.h>
-#include <linux/config.h>
-#include <asm/mach-types.h>
-
-		.text
-
-GPIO_BASE:	.long	0x90040000
-#define GPLR		0x00
-#define GPDR		0x04
-#define GPSR		0x08
-#define GAFR		0x1c
-
-PPC_BASE:	.long	0x90060000
-#define PPAR		0x08
-
-IC_BASE:	.long	0x90050000
-#define ICMR		0x04
-
-UART1_BASE:	.long	0x80010000
-UART3_BASE:	.long	0x80050000
-#define UTCR0           0x00
-#define UTCR1           0x04
-#define UTCR2           0x08
-#define UTCR3           0x0c
-#define UTSR0           0x1c
-#define UTSR1           0x20
-
-#ifndef CONFIG_SA1100_DEFAULT_BAUDRATE
-#define CONFIG_SA1100_DEFAULT_BAUDRATE	9600
-#endif
-
-#define BAUD_DIV	((230400/CONFIG_SA1100_DEFAULT_BAUDRATE)-1)
-
-SCR_loc:	.long	SYMBOL_NAME(SCR_value)
-#define GPIO_2_9	0x3fc
-
-
-/*
- * void sa1100_setup( int arch_id );
- *
- * This is called from decompress_kernel() with the arch_decomp_setup() macro.
- */
-
-ENTRY(sa1100_setup)
-		mov	r3, r0			@ keep machine type in r3
-
-		@ Clear all interrupt sources
-		ldr	r0, IC_BASE
-		mov	r1, #0
-		str	r1, [r0, #ICMR]
-
-@ Read System Configuration "Register" for Assabet.
-@ (taken from "Intel StrongARM SA-1110 Microprocessor Development Board
-@ User's Guide," p.4-9)
-
-		teq	r3, #MACH_TYPE_ASSABET
-		bne	skip_SCR
-
-		ldr	r0, GPIO_BASE
-		ldr	r1, [r0, #GPDR]
-		and	r1, r1, #GPIO_2_9
-		str	r1, [r0, #GPDR]
-		mov	r1, #GPIO_2_9
-		str	r1, [r0, #GPSR]
-		ldr	r1, [r0, #GPDR]
-		bic	r1, r1, #GPIO_2_9
-		str	r1, [r0, #GPDR]
-
-		mov	r2, #100
-1:		ldr	r1, [r0, #GPLR]
-		subs	r2, r2, #1
-		bne	1b
-
-		and	r2, r1, #GPIO_2_9
-		ldr	r1, SCR_loc
-		str	r2, [r1]
-
-		ldr	r1, [r0, #GPDR]
-		and	r1, r1, #GPIO_2_9
-		str	r1, [r0, #GPDR]
-
-skip_SCR:
-
-		@ Initialize UART (if bootloader has not done it yet)...
-		teq	r3, #MACH_TYPE_BRUTUS
-		teqne	r3, #MACH_TYPE_ASSABET
-		teqne   r3, #MACH_TYPE_ITSY
-		teqne   r3, #MACH_TYPE_OMNIMETER
-		teqne   r3, #MACH_TYPE_JORNADA720
-		teqne	r3, #MACH_TYPE_GRAPHICSCLIENT
-		teqne	r3, #MACH_TYPE_FLEXANET
-		bne	skip_uart
-
-		@ UART3 if Assabet is used with Neponset
-		teq	r3, #MACH_TYPE_ASSABET	@ if Assabet 
-		tsteq	r2, #(1 << 9)		@ ... and Neponset present
-		ldreq	r0, UART3_BASE
-		beq	uart_init
-
-		@ UART3 on GraphicsClient
-		teq	r3, #MACH_TYPE_GRAPHICSCLIENT
-		ldreq	r0, UART3_BASE
-		beq	uart_init
-
-		@ At least for Brutus, the UART1 is used through
-		@ the alternate GPIO function...
-		teq	r3, #MACH_TYPE_BRUTUS
-		bne	uart1
-
-alt_GPIO_uart:	ldr	r0, GPIO_BASE
-		ldr	r1, [r0, #GPDR]
-		bic	r1, r1, #1<<15
-		orr	r1, r1, #1<<14
-		str	r1, [r0, #GPDR]
-		ldr	r1, [r0, #GAFR]
-		orr	r1, r1, #(1<<15)|(1<<14)
-		str	r1, [r0, #GAFR]
-		ldr	r0, PPC_BASE
-		ldr	r1, [r0, #PPAR]
-		orr	r1, r1, #1<<12
-		str	r1, [r0, #PPAR]
-
-uart1:		ldr	r0, UART1_BASE
-
-uart_init:
-1:		ldr	r1, [r0, #UTSR1]
-		tst	r1, #1<<0		@ TBY
-		bne	1b
-		mov	r1, #0
-		str	r1, [r0, #UTCR3]
-		mov	r1, #0x08		@ 8N1
-		str	r1, [r0, #UTCR0]
-		mov	r1, #BAUD_DIV
-		str	r1, [r0, #UTCR2]
-		mov	r1, r1, lsr #8
-		str	r1, [r0, #UTCR1]
-		mov	r1, #0x03		@ RXE + TXE
-		str	r1, [r0, #UTCR3]
-		mov	r1, #0xff		@ flush status reg
-		str	r1, [r0, #UTSR0]
-skip_uart:
-
-		@ Extra specific setup calls
-		@ The machine type is passed in r0
-		mov	r0, r3
-#ifdef CONFIG_SA1100_NANOENGINE
-		teq	r0, #MACH_TYPE_NANOENGINE
-		beq	SYMBOL_NAME(bse_setup)
-#endif
-
-out:		mov	pc, lr
-
diff -u --recursive --new-file v2.4.12/linux/arch/arm/config.in linux/arch/arm/config.in
--- v2.4.12/linux/arch/arm/config.in	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/config.in	Thu Oct 11 09:04:57 2001
@@ -11,6 +11,7 @@
 define_bool CONFIG_UID16 y
 define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
 define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+define_bool CONFIG_GENERIC_BUST_SPINLOCK n
 
 
 mainmenu_option next_comment
@@ -68,12 +69,13 @@
 comment 'SA11x0 Implementations'
 dep_bool '  Assabet' CONFIG_SA1100_ASSABET $CONFIG_ARCH_SA1100
 dep_bool '    Include support for Neponset' CONFIG_ASSABET_NEPONSET $CONFIG_SA1100_ASSABET
+dep_bool '  ADS Bitsy' CONFIG_SA1100_ADSBITSY $CONFIG_ARCH_SA1100
 dep_bool '  Brutus' CONFIG_SA1100_BRUTUS $CONFIG_ARCH_SA1100
 dep_bool '  CerfBoard' CONFIG_SA1100_CERF $CONFIG_ARCH_SA1100
 if [ "$CONFIG_SA1100_CERF" = "y" ]; then
    bool '    32MB Cerf support' CONFIG_SA1100_CERF_32MB
 fi
-dep_bool '  Compaq iPAQ H3600 (Bitsy)' CONFIG_SA1100_BITSY $CONFIG_ARCH_SA1100
+dep_bool '  Compaq iPAQ H3600' CONFIG_SA1100_H3600 $CONFIG_ARCH_SA1100
 #dep_bool '  Empeg' CONFIG_SA1100_EMPEG $CONFIG_ARCH_SA1100
 dep_bool '  Extenex HandHeld Theater (Squashtail)' CONFIG_SA1100_EXTENEX1 $CONFIG_ARCH_SA1100
 if [ "$CONFIG_SA1100_EXTENEX1" = "y" ]; then
@@ -82,6 +84,7 @@
 dep_bool '  FlexaNet' CONFIG_SA1100_FLEXANET $CONFIG_ARCH_SA1100
 dep_bool '  FreeBird-v1.1' CONFIG_SA1100_FREEBIRD $CONFIG_ARCH_SA1100
 dep_bool '  GraphicsClient Plus' CONFIG_SA1100_GRAPHICSCLIENT $CONFIG_ARCH_SA1100
+dep_bool '  GraphicsMaster' CONFIG_SA1100_GRAPHICSMASTER $CONFIG_ARCH_SA1100
 dep_bool '  HP Jornada 720' CONFIG_SA1100_JORNADA720 $CONFIG_ARCH_SA1100
 dep_bool '  HuW WebPanel' CONFIG_SA1100_HUW_WEBPANEL $CONFIG_ARCH_SA1100
 dep_bool '  Itsy' CONFIG_SA1100_ITSY $CONFIG_ARCH_SA1100
@@ -101,14 +104,38 @@
 if [ "$CONFIG_ASSABET_NEPONSET" = "y" -o \
      "$CONFIG_SA1100_JORNADA720" = "y" -o \
      "$CONFIG_SA1100_PFS168" = "y" -o \
-     "$CONFIG_SA1100_XP860" = "y" ]; then
+     "$CONFIG_SA1100_XP860" = "y" -o \
+     "$CONFIG_SA1100_GRAPHICSMASTER" = "y" -o \
+     "$CONFIG_SA1100_ADSBITSY" = "y" ]; then
    define_bool CONFIG_SA1111 y
+   define_int CONFIG_FORCE_MAX_ZONEORDER 9
 fi
 endmenu
 
 mainmenu_option next_comment
 comment 'CLPS711X/EP721X Implementations'
+dep_bool '  CDB89712' CONFIG_ARCH_CDB89712 $CONFIG_ARCH_CLPS711X
+dep_bool '  CLEP7312' CONFIG_ARCH_CLEP7312 $CONFIG_ARCH_CLPS711X
+dep_bool '  EDB7211' CONFIG_ARCH_EDB7211 $CONFIG_ARCH_CLPS711X
 dep_bool '  P720T' CONFIG_ARCH_P720T $CONFIG_ARCH_CLPS711X
+
+# XXX Maybe these should indicate register compatibility
+# instead of being mutually exclusive.
+if [ "$CONFIG_ARCH_EDB7211" = "y" ]; then
+   define_bool CONFIG_ARCH_EP7211 y
+else
+   define_bool CONFIG_ARCH_EP7211 n
+fi
+if [ "$CONFIG_ARCH_P720T" = "y" ]; then
+   define_bool CONFIG_ARCH_EP7212 y
+else
+   define_bool CONFIG_ARCH_EP7212 n
+fi
+
+if [ "$CONFIG_ARCH_EP7211" = "y" -o \
+     "$CONFIG_ARCH_EP7212" = "y" ]; then
+   bool '  EP72xx ROM boot' CONFIG_EP72XX_ROM_BOOT
+fi
 endmenu
 
 # Definitions to make life easier
@@ -196,7 +223,9 @@
 fi
 
 # ARM720T
-if [ "$CONFIG_ARCH_CLPS711X" = "y" -o "$CONFIG_ARCH_L7200" = "y" ]; then
+if [ "$CONFIG_ARCH_CLPS711X" = "y" -o \
+     "$CONFIG_ARCH_L7200"    = "y" -o \
+     "$CONFIG_ARCH_CDB89712" = "y" ]; then
    define_bool CONFIG_CPU_ARM720T y
 else
    if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
@@ -255,12 +284,13 @@
    define_bool CONFIG_CPU_SA1100 n
 fi
 
-#if [ "$CONFIG_CPU_32" = "y" ]; then
-#   bool 'Support Thumb instructions' CONFIG_ARM_THUMB
-#fi
+if [ "$CONFIG_CPU_32" = "y" ]; then
+   dep_bool 'Support Thumb instructions (experimental)' CONFIG_ARM_THUMB $CONFIG_EXPERIMENTAL
+fi
 
 # Select various configuration options depending on the machine type
-if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
+if [ "$CONFIG_ARCH_EDB7211" = "y" -o \
+     "$CONFIG_ARCH_SA1100" = "y" ]; then
    define_bool CONFIG_DISCONTIGMEM y
 else
    define_bool CONFIG_DISCONTIGMEM n
@@ -289,6 +319,8 @@
      "$CONFIG_ARCH_SHARK" = "y" -o \
      "$CONFIG_ARCH_CLPS7500" = "y" -o \
      "$CONFIG_ARCH_EBSA110" = "y" -o \
+     "$CONFIG_ARCH_CDB89712" = "y" -o \
+     "$CONFIG_ARCH_EDB7211" = "y" -o \
      "$CONFIG_ARCH_SA1100" = "y" ]; then
    define_bool CONFIG_ISA y
 else
@@ -318,6 +350,7 @@
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
+comment 'At least one math emulation must be selected'
 tristate 'NWFPE math emulation' CONFIG_FPE_NWFPE
 dep_tristate 'FastFPE math emulation (experimental)' CONFIG_FPE_FASTFPE $CONFIG_EXPERIMENTAL
 choice 'Kernel core (/proc/kcore) format' \
@@ -335,6 +368,7 @@
      "$CONFIG_ARCH_PERSONAL_SERVER" = "y" -o \
      "$CONFIG_ARCH_CATS" = "y" -o            \
      "$CONFIG_ARCH_P720T" = "y" -o	     \
+     "$CONFIG_ARCH_CDB89712" = "y" -o	     \
      "$CONFIG_ARCH_ANAKIN" = "y" ]; then
    string 'Default kernel command string' CONFIG_CMDLINE ""
 fi
@@ -346,6 +380,7 @@
      "$CONFIG_ARCH_CO285" = "y" -o      \
      "$CONFIG_ARCH_SA1100" = "y" -o     \
      "$CONFIG_ARCH_INTEGRATOR" = "y" -o \
+     "$CONFIG_ARCH_CDB89712" = "y" -o   \
      "$CONFIG_ARCH_P720T" = "y" ]; then
    bool 'Timer and CPU usage LEDs' CONFIG_LEDS
    if [ "$CONFIG_LEDS" = "y" ]; then
@@ -429,7 +464,7 @@
 
 source drivers/ieee1394/Config.in
 
-source drivers/i2o/Config.in
+source drivers/message/i2o/Config.in
 
 mainmenu_option next_comment
 comment 'ISDN subsystem'
@@ -509,6 +544,8 @@
    fi
    endmenu
 fi
+
+source drivers/misc/Config.in
 
 source drivers/usb/Config.in
 
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/Makefile linux/arch/arm/kernel/Makefile
--- v2.4.12/linux/arch/arm/kernel/Makefile	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/kernel/Makefile	Thu Oct 11 09:04:57 2001
@@ -41,7 +41,7 @@
 export-objs	:= armksyms.o dma.o ecard.o fiq.o io.o oldlatches.o time.o
 
 no-irq-arch	:= $(CONFIG_ARCH_INTEGRATOR) $(CONFIG_ARCH_CLPS711X) \
-		   $(CONFIG_ARCH_FOOTBRIDGE) $(CONFIG_ARCH_EBSA110) \
+		   $(CONFIG_FOOTBRIDGE) $(CONFIG_ARCH_EBSA110) \
 		   $(CONFIG_ARCH_SA1100)
 
 ifneq ($(findstring y,$(no-irq-arch)),y)
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/armksyms.c linux/arch/arm/kernel/armksyms.c
--- v2.4.12/linux/arch/arm/kernel/armksyms.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/kernel/armksyms.c	Thu Oct 11 09:04:57 2001
@@ -54,22 +54,16 @@
  * 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 __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);
 
 extern void ret_from_exception(void);
@@ -213,23 +207,27 @@
 EXPORT_SYMBOL(uaccess_user);
 #endif
 
+EXPORT_SYMBOL_NOVERS(__get_user_1);
+EXPORT_SYMBOL_NOVERS(__get_user_2);
+EXPORT_SYMBOL_NOVERS(__get_user_4);
+EXPORT_SYMBOL_NOVERS(__get_user_8);
+
+EXPORT_SYMBOL_NOVERS(__put_user_1);
+EXPORT_SYMBOL_NOVERS(__put_user_2);
+EXPORT_SYMBOL_NOVERS(__put_user_4);
+EXPORT_SYMBOL_NOVERS(__put_user_8);
+
 	/* 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(__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);
 
 	/* bitops */
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/bios32.c linux/arch/arm/kernel/bios32.c
--- v2.4.12/linux/arch/arm/kernel/bios32.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/kernel/bios32.c	Thu Oct 11 09:04:57 2001
@@ -288,8 +288,11 @@
 
 	if (dev) {
 		for (i = 0; i < 3; i++) {
-			bus->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];
-			bus->resource[i]->name  = bus->name;
+			if(root->resource[i]) {
+				bus->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];
+				bus->resource[i]->end  = root->resource[i]->end;
+				bus->resource[i]->name = bus->name;
+			}
 		}
 		bus->resource[0]->flags |= pci_bridge_check_io(dev);
 		bus->resource[1]->flags |= IORESOURCE_MEM;
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/compat.c linux/arch/arm/kernel/compat.c
--- v2.4.12/linux/arch/arm/kernel/compat.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/kernel/compat.c	Thu Oct 11 09:04:57 2001
@@ -8,7 +8,7 @@
  * published by the Free Software Foundation.
  *
  * We keep the old params compatibility cruft in one place (here)
- * so we don't end up with lots of 
+ * so we don't end up with lots of mess around other places.
  */
 #include <linux/config.h>
 #include <linux/types.h>
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/dma-isa.c linux/arch/arm/kernel/dma-isa.c
--- v2.4.12/linux/arch/arm/kernel/dma-isa.c	Mon Sep 18 15:15:24 2000
+++ linux/arch/arm/kernel/dma-isa.c	Thu Oct 11 09:04:57 2001
@@ -148,17 +148,22 @@
 
 void __init isa_init_dma(dma_t *dma)
 {
-	int dmac_found;
-
+	/*
+	 * Try to autodetect presence of an ISA DMA controller.
+	 * We do some minimal initialisation, and check that
+	 * channel 0's DMA address registers are writeable.
+	 */
 	outb(0xff, 0x0d);
 	outb(0xff, 0xda);
 
+	/*
+	 * Write high and low address, and then read them back
+	 * in the same order.
+	 */
 	outb(0x55, 0x00);
 	outb(0xaa, 0x00);
 
-	dmac_found = inb(0x00) == 0x55 && inb(0x00) == 0xaa;
-
-	if (dmac_found) {
+	if (inb(0) == 0x55 && inb(0) == 0xaa) {
 		int channel, i;
 
 		for (channel = 0; channel < 8; channel++) {
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/entry-armv.S linux/arch/arm/kernel/entry-armv.S
--- v2.4.12/linux/arch/arm/kernel/entry-armv.S	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/kernel/entry-armv.S	Thu Oct 11 09:04:57 2001
@@ -404,6 +404,7 @@
 		.endm
 
 #elif defined(CONFIG_ARCH_L7200)
+#include <asm/hardware.h>
 	
 		.equ	irq_base_addr,	IO_BASE_2
 
@@ -625,8 +626,8 @@
  * This routine must not corrupt r9
  */
 #ifdef MULTI_CPU
-		ldr	r2, .LCprocfns
-		mov	lr, pc
+		ldr	r2, .LCprocfns			@ pass r0, r3 to
+		mov	lr, pc				@ processor code
 		ldr	pc, [r2]			@ call processor specific code
 #else
 		bl	cpu_data_abort
@@ -722,16 +723,16 @@
 		.align	5
 __dabt_usr:	sub	sp, sp, #S_FRAME_SIZE		@ Allocate frame size in one go
 		stmia	sp, {r0 - r12}			@ save r0 - r12
-		ldr	r4, .LCabt
-		add	r3, sp, #S_PC
-		ldmia	r4, {r0 - r2}			@ Get USR pc, cpsr
-		stmia	r3, {r0 - r2}			@ Save USR pc, cpsr, old_r0
-		stmdb	r3, {sp, lr}^
-		alignment_trap r4, r7, __temp_abt
+		ldr	r7, .LCabt
+		add	r5, sp, #S_PC
+		ldmia	r7, {r0, r3, r4}		@ Get USR pc, cpsr
+		stmia	r5, {r0, r3, r4}		@ Save USR pc, cpsr, old_r0
+		stmdb	r5, {sp, lr}^
+		alignment_trap r7, r7, __temp_abt
 		zero_fp
 #ifdef MULTI_CPU
-		ldr	r2, .LCprocfns
-		mov	lr, pc
+		ldr	r2, .LCprocfns			@ pass r0, r3 to
+		mov	lr, pc				@ processor code
 		ldr	pc, [r2]			@ call processor specific code
 #else
 		bl	cpu_data_abort
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/entry-common.S linux/arch/arm/kernel/entry-common.S
--- v2.4.12/linux/arch/arm/kernel/entry-common.S	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/kernel/entry-common.S	Thu Oct 11 09:04:57 2001
@@ -123,9 +123,8 @@
 	.align	5
 ENTRY(vector_swi)
 	save_user_regs
-	mask_pc	lr, lr
 	zero_fp
-	ldr	scno, [lr, #-4]			@ get SWI instruction
+	get_scno
 	arm710_bug_check scno, ip
 
 #ifdef CONFIG_ALIGNMENT_TRAP
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/entry-header.S linux/arch/arm/kernel/entry-header.S
--- v2.4.12/linux/arch/arm/kernel/entry-header.S	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/kernel/entry-header.S	Thu Oct 11 09:04:57 2001
@@ -75,9 +75,9 @@
 		stmia	sp, {r0 - r12}			@ Calling r0 - r12
 		add	r8, sp, #S_PC
 		stmdb	r8, {sp, lr}^			@ Calling sp, lr
-		mrs	r7, spsr
+		mrs	r8, spsr			@ called from non-FIQ mode, so ok.
 		str	lr, [sp, #S_PC]			@ Save calling PC
-		str	r7, [sp, #S_PSR]		@ Save CPSR
+		str	r8, [sp, #S_PSR]		@ Save CPSR
 		str	r0, [sp, #S_OLD_R0]		@ Save OLD_R0
 		.endm
 
@@ -186,16 +186,34 @@
 
 #endif
 
+
 /*
  * These are the registers used in the syscall handler, and allow us to
- * have in theory up to 7 arguments to a function.  Note that tbl == why
- * is intentional.
+ * have in theory up to 7 arguments to a function - r0 to r6.
+ *
+ * r7 is reserved for the system call number for thumb mode.
+ *
+ * Note that tbl == why is intentional.
  *
  * We must set at least "tsk" and "why" when calling ret_with_reschedule.
  */
-scno	.req	r9				@ syscall number
+scno	.req	r7				@ syscall number
 tbl	.req	r8				@ syscall table pointer
 why	.req	r8				@ Linux syscall (!= 0)
-tsk	.req	r7				@ current task
+tsk	.req	r9				@ current task
+
+/*
+ * Get the system call number.
+ */
+	.macro	get_scno
+#ifdef CONFIG_ARM_THUMB
+	tst	r8, #T_BIT		@ this is SPSR from save_user_regs
+	addne	scno, r7, #OS_NUMBER << 20 @ put OS number in
+	ldreq	scno, [lr, #-4]
 
+#else
+	mask_pc	lr, lr
+	ldr	scno, [lr, #-4]		@ get SWI instruction
+#endif
+	.endm
 
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/head-armv.S linux/arch/arm/kernel/head-armv.S
--- v2.4.12/linux/arch/arm/kernel/head-armv.S	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/kernel/head-armv.S	Thu Oct 11 09:04:57 2001
@@ -418,5 +418,4 @@
 		mov	r7, #0				@ unknown architecture
 		mov	pc, lr
 2:		ldmib	r4, {r5, r6, r7}		@ found, get results
-		mov	r7, r7, lsr #18			@ pagetable byte offset
 		mov	pc, lr
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/init_task.c linux/arch/arm/kernel/init_task.c
--- v2.4.12/linux/arch/arm/kernel/init_task.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/arm/kernel/init_task.c	Thu Oct 11 09:04:57 2001
@@ -9,6 +9,7 @@
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 
+static struct vm_area_struct init_mmap = INIT_MMAP;
 static struct fs_struct init_fs = INIT_FS;
 static struct files_struct init_files = INIT_FILES;
 static struct signal_struct init_signals = INIT_SIGNALS;
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/setup.c linux/arch/arm/kernel/setup.c
--- v2.4.12/linux/arch/arm/kernel/setup.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/kernel/setup.c	Thu Oct 11 09:04:57 2001
@@ -260,10 +260,10 @@
 	struct resource *res;
 	int i;
 
-	kernel_code.start  = __virt_to_bus(init_mm.start_code);
-	kernel_code.end    = __virt_to_bus(init_mm.end_code - 1);
-	kernel_data.start  = __virt_to_bus(init_mm.end_code);
-	kernel_data.end    = __virt_to_bus(init_mm.brk - 1);
+	kernel_code.start  = __virt_to_phys(init_mm.start_code);
+	kernel_code.end    = __virt_to_phys(init_mm.end_code - 1);
+	kernel_data.start  = __virt_to_phys(init_mm.end_code);
+	kernel_data.end    = __virt_to_phys(init_mm.brk - 1);
 
 	for (i = 0; i < mi->nr_banks; i++) {
 		unsigned long virt_start, virt_end;
@@ -520,9 +520,44 @@
 #endif
 }
 
-int get_cpuinfo(char * buffer)
+static const char *hwcap_str[] = {
+	"swp",
+	"half",
+	"thumb",
+	"26bit",
+	"fastmult",
+	"fpa",
+	"vfp",
+	"edsp",
+	NULL
+};
+
+/*
+ * get_cpuinfo - Get information on one CPU for use by the procfs.
+ *
+ *	Prints info on the next CPU into buffer.  Beware, doesn't check for
+ *	buffer overflow.  Current implementation of procfs assumes that the
+ *	resulting data is <= 1K.
+ *
+ * Args:
+ *	buffer	-- you guessed it, the data buffer
+ *	cpu_np	-- Input: next cpu to get (start at 0).  Output: Updated.
+ *
+ *	Returns number of bytes written to buffer.
+ */
+
+int get_cpuinfo(char *buffer, unsigned *cpu_np)
 {
 	char *p = buffer;
+	unsigned n;
+	int i;
+
+ 	/* No SMP at the moment, so just toggle 0/1 */
+	n = *cpu_np;
+	*cpu_np = 1;
+	if (n != 0) {
+		return (0);
+	}
 
 	p += sprintf(p, "Processor\t: %s %s rev %d (%s)\n",
 		     proc_info.manufacturer, proc_info.cpu_name,
@@ -531,6 +566,15 @@
 	p += sprintf(p, "BogoMIPS\t: %lu.%02lu\n",
 		     loops_per_jiffy / (500000/HZ),
 		     (loops_per_jiffy / (5000/HZ)) % 100);
+
+	/* dump out the processor features */
+	p += sprintf(p, "Features\t: ");
+
+	for (i = 0; hwcap_str[i]; i++)
+		if (elf_hwcap & (1 << i))
+			p += sprintf(p, "%s ", hwcap_str[i]);
+
+	p += sprintf(p, "\n\n");
 
 	p += sprintf(p, "Hardware\t: %s\n", machine_name);
 
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/signal.c linux/arch/arm/kernel/signal.c
--- v2.4.12/linux/arch/arm/kernel/signal.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/kernel/signal.c	Thu Oct 11 09:04:57 2001
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/arm/kernel/signal.c
  *
- *  Copyright (C) 1995, 1996 Russell King
+ *  Copyright (C) 1995-2001 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -19,7 +19,9 @@
 #include <linux/ptrace.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
+#include <linux/personality.h>
 #include <linux/tty.h>
+#include <linux/elf.h>
 
 #include <asm/pgalloc.h>
 #include <asm/ucontext.h>
@@ -29,8 +31,23 @@
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-#define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn))
-#define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn))
+/*
+ * For ARM syscalls, we encode the syscall number into the instruction.
+ */
+#define SWI_SYS_SIGRETURN	(0xef000000|(__NR_sigreturn))
+#define SWI_SYS_RT_SIGRETURN	(0xef000000|(__NR_rt_sigreturn))
+
+/*
+ * For Thumb syscalls, we pass the syscall number via r7.  We therefore
+ * need two 16-bit instructions.
+ */
+#define SWI_THUMB_SIGRETURN	(0xdf00 << 16 | 0x2700 | (__NR_sigreturn - __NR_SYSCALL_BASE))
+#define SWI_THUMB_RT_SIGRETURN	(0xdf00 << 16 | 0x2700 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE))
+
+static const unsigned long retcodes[4] = {
+	SWI_SYS_SIGRETURN,	SWI_THUMB_SIGRETURN,
+	SWI_SYS_RT_SIGRETURN,	SWI_THUMB_RT_SIGRETURN
+};
 
 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall);
 
@@ -208,11 +225,11 @@
 	sigset_t set;
 
 	/*
-	 * Since we stacked the signal on a word boundary,
+	 * Since we stacked the signal on a 64-bit boundary,
 	 * then 'sp' should be word aligned here.  If it's
 	 * not, then the user is trying to mess with us.
 	 */
-	if (regs->ARM_sp & 3)
+	if (regs->ARM_sp & 7)
 		goto badframe;
 
 	frame = (struct sigframe *)regs->ARM_sp;
@@ -251,11 +268,11 @@
 	sigset_t set;
 
 	/*
-	 * Since we stacked the signal on a word boundary,
+	 * Since we stacked the signal on a 64-bit boundary,
 	 * then 'sp' should be word aligned here.  If it's
 	 * not, then the user is trying to mess with us.
 	 */
-	if (regs->ARM_sp & 3)
+	if (regs->ARM_sp & 7)
 		goto badframe;
 
 	frame = (struct rt_sigframe *)regs->ARM_sp;
@@ -319,8 +336,8 @@
 	return err;
 }
 
-static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
-				 unsigned long framesize)
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, int framesize)
 {
 	unsigned long sp = regs->ARM_sp;
 
@@ -331,77 +348,103 @@
 		sp = current->sas_ss_sp + current->sas_ss_size;
 
 	/*
-	 * No matter what happens, 'sp' must be word
-	 * aligned otherwise nasty things could happen
+	 * ATPCS B01 mandates 8-byte alignment
 	 */
-	/* ATPCS B01 mandates 8-byte alignment */
 	return (void *)((sp - framesize) & ~7);
 }
 
-static void setup_frame(int sig, struct k_sigaction *ka,
-			sigset_t *set, struct pt_regs *regs)
+static int
+setup_return(struct pt_regs *regs, struct k_sigaction *ka,
+	     unsigned long *rc, void *frame, int usig)
 {
-	struct sigframe *frame;
+	unsigned long handler = (unsigned long)ka->sa.sa_handler;
 	unsigned long retcode;
-	int err = 0;
-
-	frame = get_sigframe(ka, regs, sizeof(*frame));
-
-	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
-		goto segv_and_exit;
+	int thumb = 0;
+#ifdef CONFIG_CPU_32
+	unsigned long cpsr = regs->ARM_cpsr;
 
-	err |= setup_sigcontext(&frame->sc, /*&frame->fpstate,*/ regs, set->sig[0]);
+	/*
+	 * Maybe we need to deliver a 32-bit signal to a 26-bit task.
+	 */
+	if (ka->sa.sa_flags & SA_THIRTYTWO)
+		cpsr = (cpsr & ~MODE_MASK) | USR_MODE;
 
-	if (_NSIG_WORDS > 1) {
-		err |= __copy_to_user(frame->extramask, &set->sig[1],
-				      sizeof(frame->extramask));
+#ifdef CONFIG_ARM_THUMB
+	if (elf_hwcap & HWCAP_THUMB) {
+		/*
+		 * The LSB of the handler determines if we're going to
+		 * be using THUMB or ARM mode for this signal handler.
+		 */
+		thumb = handler & 1;
+
+		if (thumb)
+			cpsr |= T_BIT;
+		else
+			cpsr &= ~T_BIT;
 	}
+#endif
+#endif
 
-	/* Set up to return from userspace.  If provided, use a stub
-	   already in userspace.  */
 	if (ka->sa.sa_flags & SA_RESTORER) {
 		retcode = (unsigned long)ka->sa.sa_restorer;
 	} else {
-		retcode = (unsigned long)&frame->retcode;
-		__put_user_error(SWI_SYS_SIGRETURN, &frame->retcode, err);
-		flush_icache_range(retcode, retcode + 4);
-	}
+		unsigned int idx = thumb;
 
-	if (err)
-		goto segv_and_exit;
+		if (ka->sa.sa_flags & SA_SIGINFO)
+			idx += 2;
 
-	if (current->exec_domain && current->exec_domain->signal_invmap && sig < 32)
-		regs->ARM_r0 = current->exec_domain->signal_invmap[sig];
-	else
-		regs->ARM_r0 = sig;
+		if (__put_user(retcodes[idx], rc))
+			return 1;
+
+		flush_icache_range((unsigned long)rc,
+				   (unsigned long)(rc + 1));
+
+		retcode = ((unsigned long)rc) + thumb;
+	}
+
+	regs->ARM_r0 = usig;
 	regs->ARM_sp = (unsigned long)frame;
 	regs->ARM_lr = retcode;
-	regs->ARM_pc = (unsigned long)ka->sa.sa_handler;
-#if defined(CONFIG_CPU_32)
-	/* Maybe we need to deliver a 32-bit signal to a 26-bit task. */
-	if (ka->sa.sa_flags & SA_THIRTYTWO)
-		regs->ARM_cpsr = USR_MODE;
+	regs->ARM_pc = handler & (thumb ? ~1 : ~3);
+
+#ifdef CONFIG_CPU_32
+	regs->ARM_cpsr = cpsr;
 #endif
-	if (valid_user_regs(regs))
-		return;
 
-segv_and_exit:
-	if (sig == SIGSEGV)
-		ka->sa.sa_handler = SIG_DFL;
-	force_sig(SIGSEGV, current);
+	return 0;
 }
 
-static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-			   sigset_t *set, struct pt_regs *regs)
+static int
+setup_frame(int usig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *regs)
 {
-	struct rt_sigframe *frame;
-	unsigned long retcode;
+	struct sigframe *frame = get_sigframe(ka, regs, sizeof(*frame));
 	int err = 0;
 
-	frame = get_sigframe(ka, regs, sizeof(struct rt_sigframe));
+	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+		return 1;
+
+	err |= setup_sigcontext(&frame->sc, /*&frame->fpstate,*/ regs, set->sig[0]);
+
+	if (_NSIG_WORDS > 1) {
+		err |= __copy_to_user(frame->extramask, &set->sig[1],
+				      sizeof(frame->extramask));
+	}
+
+	if (err == 0)
+		err = setup_return(regs, ka, &frame->retcode, frame, usig);
+
+	return err;
+}
+
+static int
+setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
+	       sigset_t *set, struct pt_regs *regs)
+{
+	struct rt_sigframe *frame = get_sigframe(ka, regs, sizeof(*frame));
+	int err = 0;
 
 	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
-		goto segv_and_exit;
+		return 1;
 
 	__put_user_error(&frame->info, &frame->pinfo, err);
 	__put_user_error(&frame->uc, &frame->puc, err);
@@ -414,47 +457,20 @@
 				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) {
-		retcode = (unsigned long)ka->sa.sa_restorer;
-	} else {
-		retcode = (unsigned long)&frame->retcode;
-		__put_user_error(SWI_SYS_RT_SIGRETURN, &frame->retcode, err);
-		flush_icache_range(retcode, retcode + 4);
-	}
-
-	if (err)
-		goto segv_and_exit;
-
-	if (current->exec_domain && current->exec_domain->signal_invmap && sig < 32)
-		regs->ARM_r0 = current->exec_domain->signal_invmap[sig];
-	else
-		regs->ARM_r0 = sig;
+	if (err == 0)
+		err = setup_return(regs, ka, &frame->retcode, frame, usig);
 
-	/*
-	 * For realtime signals we must also set the second and third
-	 * arguments for the signal handler.
-	 *   -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 2000-12-06
-	 */
-	regs->ARM_r1 = (unsigned long)frame->pinfo;
-	regs->ARM_r2 = (unsigned long)frame->puc;
-
-	regs->ARM_sp = (unsigned long)frame;
-	regs->ARM_lr = retcode;
-	regs->ARM_pc = (unsigned long)ka->sa.sa_handler;
-#if defined(CONFIG_CPU_32)
-	/* Maybe we need to deliver a 32-bit signal to a 26-bit task. */
-	if (ka->sa.sa_flags & SA_THIRTYTWO)
-		regs->ARM_cpsr = USR_MODE;
-#endif
-	if (valid_user_regs(regs))
-		return;
+	if (err == 0) {
+		/*
+		 * For realtime signals we must also set the second and third
+		 * arguments for the signal handler.
+		 *   -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 2000-12-06
+		 */
+		regs->ARM_r1 = (unsigned long)frame->pinfo;
+		regs->ARM_r2 = (unsigned long)frame->puc;
+	}
 
-segv_and_exit:
-	if (sig == SIGSEGV)
-		ka->sa.sa_handler = SIG_DFL;
-	force_sig(SIGSEGV, current);
+	return err;
 }
 
 /*
@@ -464,22 +480,47 @@
 handle_signal(unsigned long sig, struct k_sigaction *ka,
 	      siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
 {
-	/* Set up the stack frame */
+	struct task_struct *tsk = current;
+	int usig = sig;
+	int ret;
+
+	/*
+	 * translate the signal
+	 */
+	if (usig < 32 && tsk->exec_domain && tsk->exec_domain->signal_invmap)
+		usig = tsk->exec_domain->signal_invmap[usig];
+
+	/*
+	 * Set up the stack frame
+	 */
 	if (ka->sa.sa_flags & SA_SIGINFO)
-		setup_rt_frame(sig, ka, info, oldset, regs);
+		ret = setup_rt_frame(usig, ka, info, oldset, regs);
 	else
-		setup_frame(sig, ka, oldset, regs);
+		ret = setup_frame(usig, ka, oldset, regs);
 
-	if (ka->sa.sa_flags & SA_ONESHOT)
-		ka->sa.sa_handler = SIG_DFL;
+	/*
+	 * Check that the resulting registers are actually sane.
+	 */
+	ret |= !valid_user_regs(regs);
 
-	if (!(ka->sa.sa_flags & SA_NODEFER)) {
-		spin_lock_irq(&current->sigmask_lock);
-		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
-		sigaddset(&current->blocked,sig);
-		recalc_sigpending(current);
-		spin_unlock_irq(&current->sigmask_lock);
+	if (ret == 0) {
+		if (ka->sa.sa_flags & SA_ONESHOT)
+			ka->sa.sa_handler = SIG_DFL;
+
+		if (!(ka->sa.sa_flags & SA_NODEFER)) {
+			spin_lock_irq(&tsk->sigmask_lock);
+			sigorsets(&tsk->blocked, &tsk->blocked,
+				  &ka->sa.sa_mask);
+			sigaddset(&tsk->blocked, sig);
+			recalc_sigpending(tsk);
+			spin_unlock_irq(&tsk->sigmask_lock);
+		}
+		return;
 	}
+
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, tsk);
 }
 
 /*
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/time.c linux/arch/arm/kernel/time.c
--- v2.4.12/linux/arch/arm/kernel/time.c	Thu Feb  8 16:32:44 2001
+++ linux/arch/arm/kernel/time.c	Thu Oct 11 09:04:57 2001
@@ -33,7 +33,6 @@
 #include <asm/hardware.h>
 
 extern int setup_arm_irq(int, struct irqaction *);
-extern void setup_timer(void);
 extern rwlock_t xtime_lock;
 extern unsigned long wall_jiffies;
 
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/traps.c linux/arch/arm/kernel/traps.c
--- v2.4.12/linux/arch/arm/kernel/traps.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/arm/kernel/traps.c	Thu Oct 11 09:04:57 2001
@@ -22,6 +22,7 @@
 #include <linux/personality.h>
 #include <linux/ptrace.h>
 #include <linux/elf.h>
+#include <linux/interrupt.h>
 #include <linux/init.h>
 
 #include <asm/atomic.h>
@@ -176,7 +177,7 @@
 	printk("Process %s (pid: %d, stackpage=%08lx)\n",
 		current->comm, current->pid, 4096+(unsigned long)tsk);
 
-	if (!user_mode(regs)) {
+	if (!user_mode(regs) || in_interrupt()) {
 		mm_segment_t fs;
 
 		/*
@@ -209,7 +210,7 @@
 
 asmlinkage void do_undefinstr(int address, struct pt_regs *regs, int mode)
 {
-	unsigned long addr;
+	unsigned long *pc;
 	siginfo_t info;
 
 	/*
@@ -217,11 +218,11 @@
 	 * whether we're in Thumb mode or not.
 	 */
 	regs->ARM_pc -= thumb_mode(regs) ? 2 : 4;
-	addr = instruction_pointer(regs);
+	pc = (unsigned long *)instruction_pointer(regs);
 
 #ifdef CONFIG_DEBUG_USER
-	printk(KERN_INFO "%s (%d): undefined instruction: pc=%08lx\n",
-		current->comm, current->pid, addr);
+	printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
+		current->comm, current->pid, pc);
 	dump_instr(regs);
 #endif
 
@@ -231,7 +232,7 @@
 	info.si_signo = SIGILL;
 	info.si_errno = 0;
 	info.si_code  = ILL_ILLOPC;
-	info.si_addr  = (void *)addr;
+	info.si_addr  = pc;
 
 	force_sig_info(SIGILL, &info, current);
 
diff -u --recursive --new-file v2.4.12/linux/arch/arm/lib/Makefile linux/arch/arm/lib/Makefile
--- v2.4.12/linux/arch/arm/lib/Makefile	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/lib/Makefile	Thu Oct 11 09:04:57 2001
@@ -13,15 +13,20 @@
 		   copy_page.o delay.o findbit.o memchr.o memcpy.o    \
 		   memset.o memzero.o setbit.o strncpy_from_user.o    \
 		   strnlen_user.o strchr.o strrchr.o testchangebit.o  \
-		   testclearbit.o testsetbit.o uaccess.o
+		   testclearbit.o testsetbit.o uaccess.o getuser.o    \
+		   putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o   \
+		   ucmpdi2.o udivdi3.o lib1funcs.o
 obj-m		:=
 obj-n		:=
 
+obj-$(CONFIG_VT)+= kbd.o
+
 obj-arc		:= ecard.o io-acorn.o floppydma.o
 obj-rpc		:= ecard.o io-acorn.o floppydma.o
 obj-clps7500	:= io-acorn.o
 obj-l7200     	:= io-acorn.o
 obj-shark	:= io-shark.o
+obj-edb7211	:= io-acorn.o
 
 obj-y		+= $(obj-$(MACHINE))
 
diff -u --recursive --new-file v2.4.12/linux/arch/arm/lib/ashldi3.c linux/arch/arm/lib/ashldi3.c
--- v2.4.12/linux/arch/arm/lib/ashldi3.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/ashldi3.c	Thu Oct 11 09:04:57 2001
@@ -0,0 +1,61 @@
+/* More subroutines needed by GCC output code on some machines.  */
+/* Compile this one with gcc.  */
+/* 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.  */
+
+/* As a special exception, if you link this library with other files,
+   some of which are compiled with GCC, to produce an executable,
+   this library does not by itself 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.
+ */
+/* support functions required by the kernel. based on code from gcc-2.95.3 */
+/* I Molton	29/07/01 */
+
+#include "gcclib.h"
+
+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 -u --recursive --new-file v2.4.12/linux/arch/arm/lib/ashrdi3.c linux/arch/arm/lib/ashrdi3.c
--- v2.4.12/linux/arch/arm/lib/ashrdi3.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/ashrdi3.c	Thu Oct 11 09:04:57 2001
@@ -0,0 +1,61 @@
+/* More subroutines needed by GCC output code on some machines.  */
+/* Compile this one with gcc.  */
+/* 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.  */
+
+/* As a special exception, if you link this library with other files,
+   some of which are compiled with GCC, to produce an executable,
+   this library does not by itself 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.
+ */
+/* support functions required by the kernel. based on code from gcc-2.95.3 */
+/* I Molton     29/07/01 */
+
+#include "gcclib.h"
+
+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 -u --recursive --new-file v2.4.12/linux/arch/arm/lib/gcclib.h linux/arch/arm/lib/gcclib.h
--- v2.4.12/linux/arch/arm/lib/gcclib.h	Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/gcclib.h	Thu Oct 11 09:04:57 2001
@@ -0,0 +1,25 @@
+/* gcclib.h -- definitions for various functions 'borrowed' from gcc-2.95.3 */
+/* I Molton     29/07/01 */
+
+#define BITS_PER_UNIT  8
+#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
+
+typedef unsigned int UQItype    __attribute__ ((mode (QI)));
+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__)));
+typedef unsigned int UDItype    __attribute__ ((mode (DI)));
+
+#if 0 /* FIXME: endian test here!!! */
+  struct DIstruct {SItype high, low;};
+#else
+  struct DIstruct {SItype low, high;};
+#endif
+
+typedef union
+{
+  struct DIstruct s;
+  DItype ll;
+} DIunion;
+
diff -u --recursive --new-file v2.4.12/linux/arch/arm/lib/getuser.S linux/arch/arm/lib/getuser.S
--- v2.4.12/linux/arch/arm/lib/getuser.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/getuser.S	Thu Oct 11 09:04:57 2001
@@ -0,0 +1,96 @@
+/*
+ *  linux/arch/arm/lib/getuser.S
+ *
+ *  Copyright (C) 2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Idea from x86 version, (C) Copyright 1998 Linus Torvalds
+ *
+ * These functions have a non-standard call interface to make them more
+ * efficient, especially as they return an error value in addition to
+ * the "real" return value.
+ *
+ * __get_user_X
+ *
+ * Inputs:	r0 contains the address
+ * Outputs:	r0 is the error code
+ *		r1, r2 contains the zero-extended value
+ *		lr corrupted
+ *
+ * No other registers must be altered.  (see include/asm-arm/uaccess.h
+ * for specific ASM register usage).
+ *
+ * Note that ADDR_LIMIT is either 0 or 0xc0000000.
+ * Note also that it is intended that __get_user_bad is not global.
+ */
+#include <asm/constants.h>
+
+	.global	__get_user_1
+__get_user_1:
+	bic	r1, sp, #0x1f00
+	bic	r1, r1, #0x00ff
+	ldr	r1, [r1, #TSK_ADDR_LIMIT]
+	sub	r1, r1, #1
+	cmp	r0, r1
+1:	ldrlsbt	r1, [r0]
+	movls	r0, #0
+	movls	pc, lr
+	b	__get_user_bad
+
+	.global	__get_user_2
+__get_user_2:
+	bic	r2, sp, #0x1f00
+	bic	r2, r2, #0x00ff
+	ldr	r2, [r2, #TSK_ADDR_LIMIT]
+	sub	r2, r2, #2
+	cmp	r0, r2
+2:	ldrlsbt	r1, [r0], #1
+3:	ldrlsbt	r2, [r0]
+	orrls	r1, r1, r2, lsl #8
+	movls	r0, #0
+	movls	pc, lr
+	b	__get_user_bad
+
+	.global	__get_user_4
+__get_user_4:
+	bic	r1, sp, #0x1f00
+	bic	r1, r1, #0x00ff
+	ldr	r1, [r1, #TSK_ADDR_LIMIT]
+	sub	r1, r1, #4
+	cmp	r0, r1
+4:	ldrlst	r1, [r0]
+	movls	r0, #0
+	movls	pc, lr
+	b	__get_user_bad
+
+	.global	__get_user_8
+__get_user_8:
+	bic	r2, sp, #0x1f00
+	bic	r2, r2, #0x00ff
+	ldr	r2, [r2, #TSK_ADDR_LIMIT]
+	sub	r2, r2, #8
+	cmp	r0, r2
+5:	ldrlst	r1, [r0], #4
+6:	ldrlst	r2, [r0]
+	movls	r0, #0
+	movls	pc, lr
+
+	/* fall through */
+
+__get_user_bad:
+	mov	r2, #0
+	mov	r1, #0
+	mov	r0, #-14
+	mov	pc, lr
+
+.section __ex_table, "a"
+	.long	1b, __get_user_bad
+	.long	2b, __get_user_bad
+	.long	3b, __get_user_bad
+	.long	4b, __get_user_bad
+	.long	5b, __get_user_bad
+	.long	6b, __get_user_bad
+.previous
diff -u --recursive --new-file v2.4.12/linux/arch/arm/lib/kbd.c linux/arch/arm/lib/kbd.c
--- v2.4.12/linux/arch/arm/lib/kbd.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/kbd.c	Thu Oct 11 09:04:57 2001
@@ -0,0 +1,13 @@
+#include <linux/config.h>
+#include <linux/kd.h>
+
+int  (*k_setkeycode)(unsigned int, unsigned int);
+int  (*k_getkeycode)(unsigned int);
+int  (*k_translate)(unsigned char, unsigned char *, char);
+char (*k_unexpected_up)(unsigned char);
+void (*k_leds)(unsigned char);
+
+#ifdef CONFIG_MAGIC_SYSRQ
+int k_sysrq_key;
+unsigned char *k_sysrq_xlate;
+#endif
diff -u --recursive --new-file v2.4.12/linux/arch/arm/lib/lib1funcs.S linux/arch/arm/lib/lib1funcs.S
--- v2.4.12/linux/arch/arm/lib/lib1funcs.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/lib1funcs.S	Thu Oct 11 09:04:57 2001
@@ -0,0 +1,320 @@
+@ libgcc1 routines for ARM cpu.
+@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
+
+/* Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
+
+This file 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 other files,
+   some of which are compiled with GCC, to produce an executable,
+   this library does not by itself 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.
+ */
+/* This code is derived from gcc 2.95.3 */
+/* I Molton     29/07/01 */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+#include <linux/config.h>
+
+#ifdef CONFIG_CPU_26
+#define RET	movs
+#define RETc(x)	mov##x##s
+#define RETCOND ^
+#else
+#define RET	mov
+#define RETc(x)	mov##x
+#define RETCOND
+#endif
+
+dividend	.req	r0
+divisor		.req	r1
+result		.req	r2
+overdone        .req    r2
+curbit		.req	r3
+ip		.req	r12
+sp		.req	r13
+lr		.req	r14
+pc		.req	r15
+	
+ENTRY(__udivsi3)
+	cmp	divisor, #0
+	beq	Ldiv0
+	mov	curbit, #1
+	mov	result, #0
+	cmp	dividend, divisor
+	bcc	Lgot_result_udivsi3
+1:
+	@ Unless the divisor is very big, shift it up in multiples of
+	@ four bits, since this is the amount of unwinding in the main
+	@ division loop.  Continue shifting until the divisor is 
+	@ larger than the dividend.
+	cmp	divisor, #0x10000000
+	cmpcc	divisor, dividend
+	movcc	divisor, divisor, lsl #4
+	movcc	curbit, curbit, lsl #4
+	bcc	1b
+
+2:
+	@ For very big divisors, we must shift it a bit at a time, or
+	@ we will be in danger of overflowing.
+	cmp	divisor, #0x80000000
+	cmpcc	divisor, dividend
+	movcc	divisor, divisor, lsl #1
+	movcc	curbit, curbit, lsl #1
+	bcc	2b
+
+3:
+	@ Test for possible subtractions, and note which bits
+	@ are done in the result.  On the final pass, this may subtract
+	@ too much from the dividend, but the result will be ok, since the
+	@ "bit" will have been shifted out at the bottom.
+	cmp	dividend, divisor
+	subcs	dividend, dividend, divisor
+	orrcs	result, result, curbit
+	cmp	dividend, divisor, lsr #1
+	subcs	dividend, dividend, divisor, lsr #1
+	orrcs	result, result, curbit, lsr #1
+	cmp	dividend, divisor, lsr #2
+	subcs	dividend, dividend, divisor, lsr #2
+	orrcs	result, result, curbit, lsr #2
+	cmp	dividend, divisor, lsr #3
+	subcs	dividend, dividend, divisor, lsr #3
+	orrcs	result, result, curbit, lsr #3
+	cmp	dividend, #0			@ Early termination?
+	movnes	curbit, curbit, lsr #4		@ No, any more bits to do?
+	movne	divisor, divisor, lsr #4
+	bne	3b
+Lgot_result_udivsi3:
+	mov	r0, result
+	RET	pc, lr
+
+Ldiv0:
+	str	lr, [sp, #-4]!
+	bl	__div0
+	mov	r0, #0			@ about as wrong as it could be
+	ldmia	sp!, {pc}RETCOND
+
+/* __umodsi3 ----------------------- */
+
+ENTRY(__umodsi3)
+	cmp	divisor, #0
+	beq	Ldiv0
+	mov	curbit, #1
+	cmp	dividend, divisor
+	RETc(cc)	pc, lr
+1:
+	@ Unless the divisor is very big, shift it up in multiples of
+	@ four bits, since this is the amount of unwinding in the main
+	@ division loop.  Continue shifting until the divisor is 
+	@ larger than the dividend.
+	cmp	divisor, #0x10000000
+	cmpcc	divisor, dividend
+	movcc	divisor, divisor, lsl #4
+	movcc	curbit, curbit, lsl #4
+	bcc	1b
+
+2:
+	@ For very big divisors, we must shift it a bit at a time, or
+	@ we will be in danger of overflowing.
+	cmp	divisor, #0x80000000
+	cmpcc	divisor, dividend
+	movcc	divisor, divisor, lsl #1
+	movcc	curbit, curbit, lsl #1
+	bcc	2b
+
+3:
+	@ Test for possible subtractions.  On the final pass, this may 
+	@ subtract too much from the dividend, so keep track of which
+	@ subtractions are done, we can fix them up afterwards...
+	mov	overdone, #0
+	cmp	dividend, divisor
+	subcs	dividend, dividend, divisor
+	cmp	dividend, divisor, lsr #1
+	subcs	dividend, dividend, divisor, lsr #1
+	orrcs	overdone, overdone, curbit, ror #1
+	cmp	dividend, divisor, lsr #2
+	subcs	dividend, dividend, divisor, lsr #2
+	orrcs	overdone, overdone, curbit, ror #2
+	cmp	dividend, divisor, lsr #3
+	subcs	dividend, dividend, divisor, lsr #3
+	orrcs	overdone, overdone, curbit, ror #3
+	mov	ip, curbit
+	cmp	dividend, #0			@ Early termination?
+	movnes	curbit, curbit, lsr #4		@ No, any more bits to do?
+	movne	divisor, divisor, lsr #4
+	bne	3b
+
+	@ Any subtractions that we should not have done will be recorded in
+	@ the top three bits of "overdone".  Exactly which were not needed
+	@ are governed by the position of the bit, stored in ip.
+	@ If we terminated early, because dividend became zero,
+	@ then none of the below will match, since the bit in ip will not be
+	@ in the bottom nibble.
+	ands	overdone, overdone, #0xe0000000
+	RETc(eq)	pc, lr				@ No fixups needed
+	tst	overdone, ip, ror #3
+	addne	dividend, dividend, divisor, lsr #3
+	tst	overdone, ip, ror #2
+	addne	dividend, dividend, divisor, lsr #2
+	tst	overdone, ip, ror #1
+	addne	dividend, dividend, divisor, lsr #1
+	RET	pc, lr
+
+ENTRY(__divsi3)
+	eor	ip, dividend, divisor		@ Save the sign of the result.
+	mov	curbit, #1
+	mov	result, #0
+	cmp	divisor, #0
+	rsbmi	divisor, divisor, #0		@ Loops below use unsigned.
+	beq	Ldiv0
+	cmp	dividend, #0
+	rsbmi	dividend, dividend, #0
+	cmp	dividend, divisor
+	bcc	Lgot_result_divsi3
+
+1:
+	@ Unless the divisor is very big, shift it up in multiples of
+	@ four bits, since this is the amount of unwinding in the main
+	@ division loop.  Continue shifting until the divisor is 
+	@ larger than the dividend.
+	cmp	divisor, #0x10000000
+	cmpcc	divisor, dividend
+	movcc	divisor, divisor, lsl #4
+	movcc	curbit, curbit, lsl #4
+	bcc	1b
+
+2:
+	@ For very big divisors, we must shift it a bit at a time, or
+	@ we will be in danger of overflowing.
+	cmp	divisor, #0x80000000
+	cmpcc	divisor, dividend
+	movcc	divisor, divisor, lsl #1
+	movcc	curbit, curbit, lsl #1
+	bcc	2b
+
+3:
+	@ Test for possible subtractions, and note which bits
+	@ are done in the result.  On the final pass, this may subtract
+	@ too much from the dividend, but the result will be ok, since the
+	@ "bit" will have been shifted out at the bottom.
+	cmp	dividend, divisor
+	subcs	dividend, dividend, divisor
+	orrcs	result, result, curbit
+	cmp	dividend, divisor, lsr #1
+	subcs	dividend, dividend, divisor, lsr #1
+	orrcs	result, result, curbit, lsr #1
+	cmp	dividend, divisor, lsr #2
+	subcs	dividend, dividend, divisor, lsr #2
+	orrcs	result, result, curbit, lsr #2
+	cmp	dividend, divisor, lsr #3
+	subcs	dividend, dividend, divisor, lsr #3
+	orrcs	result, result, curbit, lsr #3
+	cmp	dividend, #0			@ Early termination?
+	movnes	curbit, curbit, lsr #4		@ No, any more bits to do?
+	movne	divisor, divisor, lsr #4
+	bne	3b
+Lgot_result_divsi3:
+	mov	r0, result
+	cmp	ip, #0
+	rsbmi	r0, r0, #0
+	RET	pc, lr
+
+ENTRY(__modsi3)
+	mov	curbit, #1
+	cmp	divisor, #0
+	rsbmi	divisor, divisor, #0		@ Loops below use unsigned.
+	beq	Ldiv0
+	@ Need to save the sign of the dividend, unfortunately, we need
+	@ ip later on; this is faster than pushing lr and using that.
+	str	dividend, [sp, #-4]!
+	cmp	dividend, #0
+	rsbmi	dividend, dividend, #0
+	cmp	dividend, divisor
+	bcc	Lgot_result_modsi3
+
+1:
+	@ Unless the divisor is very big, shift it up in multiples of
+	@ four bits, since this is the amount of unwinding in the main
+	@ division loop.  Continue shifting until the divisor is 
+	@ larger than the dividend.
+	cmp	divisor, #0x10000000
+	cmpcc	divisor, dividend
+	movcc	divisor, divisor, lsl #4
+	movcc	curbit, curbit, lsl #4
+	bcc	1b
+
+2:
+	@ For very big divisors, we must shift it a bit at a time, or
+	@ we will be in danger of overflowing.
+	cmp	divisor, #0x80000000
+	cmpcc	divisor, dividend
+	movcc	divisor, divisor, lsl #1
+	movcc	curbit, curbit, lsl #1
+	bcc	2b
+
+3:
+	@ Test for possible subtractions.  On the final pass, this may 
+	@ subtract too much from the dividend, so keep track of which
+	@ subtractions are done, we can fix them up afterwards...
+	mov	overdone, #0
+	cmp	dividend, divisor
+	subcs	dividend, dividend, divisor
+	cmp	dividend, divisor, lsr #1
+	subcs	dividend, dividend, divisor, lsr #1
+	orrcs	overdone, overdone, curbit, ror #1
+	cmp	dividend, divisor, lsr #2
+	subcs	dividend, dividend, divisor, lsr #2
+	orrcs	overdone, overdone, curbit, ror #2
+	cmp	dividend, divisor, lsr #3
+	subcs	dividend, dividend, divisor, lsr #3
+	orrcs	overdone, overdone, curbit, ror #3
+	mov	ip, curbit
+	cmp	dividend, #0			@ Early termination?
+	movnes	curbit, curbit, lsr #4		@ No, any more bits to do?
+	movne	divisor, divisor, lsr #4
+	bne	3b
+
+	@ Any subtractions that we should not have done will be recorded in
+	@ the top three bits of "overdone".  Exactly which were not needed
+	@ are governed by the position of the bit, stored in ip.
+	@ If we terminated early, because dividend became zero,
+	@ then none of the below will match, since the bit in ip will not be
+	@ in the bottom nibble.
+	ands	overdone, overdone, #0xe0000000
+	beq	Lgot_result_modsi3
+	tst	overdone, ip, ror #3
+	addne	dividend, dividend, divisor, lsr #3
+	tst	overdone, ip, ror #2
+	addne	dividend, dividend, divisor, lsr #2
+	tst	overdone, ip, ror #1
+	addne	dividend, dividend, divisor, lsr #1
+Lgot_result_modsi3:
+	ldr	ip, [sp], #4
+	cmp	ip, #0
+	rsbmi	dividend, dividend, #0
+	RET	pc, lr
diff -u --recursive --new-file v2.4.12/linux/arch/arm/lib/longlong.h linux/arch/arm/lib/longlong.h
--- v2.4.12/linux/arch/arm/lib/longlong.h	Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/longlong.h	Thu Oct 11 09:04:57 2001
@@ -0,0 +1,184 @@
+/* longlong.h -- based on code from gcc-2.95.3
+
+   definitions for mixed size 32/64 bit arithmetic.
+   Copyright (C) 1991, 92, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
+
+   This definition file 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.
+
+   This definition 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; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* Borrowed from GCC 2.95.3, I Molton 29/07/01 */
+
+#ifndef SI_TYPE_SIZE
+#define SI_TYPE_SIZE 32
+#endif
+
+#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 auxiliary asm macros.
+
+   1) umul_ppmm(high_prod, low_prod, multipler, multiplicand)
+   multiplies two USItype integers MULTIPLER and MULTIPLICAND,
+   and generates a two-part USItype product in HIGH_PROD and
+   LOW_PROD.
+
+   2) __umulsidi3(a,b) multiplies two USItype integers A and B,
+   and returns a UDItype product.  This is just a variant of umul_ppmm.
+
+   3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+   denominator) divides a two-word unsigned integer, composed by the
+   integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and
+   places the quotient in QUOTIENT and the remainder in REMAINDER.
+   HIGH_NUMERATOR must be less than DENOMINATOR for correct operation.
+   If, in addition, the most significant bit of DENOMINATOR must be 1,
+   then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1.
+
+   4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+   denominator).  Like udiv_qrnnd but the numbers are signed.  The
+   quotient is rounded towards 0.
+
+   5) count_leading_zeros(count, x) counts the number of zero-bits from
+   the msb to the first non-zero bit.  This is the number of steps X
+   needs to be shifted left to set the msb.  Undefined for X == 0.
+
+   6) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
+   high_addend_2, low_addend_2) adds two two-word unsigned integers,
+   composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and
+   LOW_ADDEND_2 respectively.  The result is placed in HIGH_SUM and
+   LOW_SUM.  Overflow (i.e. carry out) is not stored anywhere, and is
+   lost.
+
+   7) sub_ddmmss(high_difference, low_difference, high_minuend,
+   low_minuend, high_subtrahend, low_subtrahend) subtracts two
+   two-word unsigned integers, composed by HIGH_MINUEND_1 and
+   LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2
+   respectively.  The result is placed in HIGH_DIFFERENCE and
+   LOW_DIFFERENCE.  Overflow (i.e. carry out) is not stored anywhere,
+   and is lost.
+
+   If any of these macros are left undefined for a particular CPU,
+   C macros are used.  */
+
+#if defined (__arm__)
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+  __asm__ ("adds	%1, %4, %5
+	adc	%0, %2, %3"						\
+	   : "=r" ((USItype) (sh)),					\
+	     "=&r" ((USItype) (sl))					\
+	   : "%r" ((USItype) (ah)),					\
+	     "rI" ((USItype) (bh)),					\
+	     "%r" ((USItype) (al)),					\
+	     "rI" ((USItype) (bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+  __asm__ ("subs	%1, %4, %5
+	sbc	%0, %2, %3"						\
+	   : "=r" ((USItype) (sh)),					\
+	     "=&r" ((USItype) (sl))					\
+	   : "r" ((USItype) (ah)),					\
+	     "rI" ((USItype) (bh)),					\
+	     "r" ((USItype) (al)),					\
+	     "rI" ((USItype) (bl)))
+#define umul_ppmm(xh, xl, a, b) \
+{register USItype __t0, __t1, __t2;					\
+  __asm__ ("%@ Inlined umul_ppmm
+	mov	%2, %5, lsr #16
+	mov	%0, %6, lsr #16
+	bic	%3, %5, %2, lsl #16
+	bic	%4, %6, %0, lsl #16
+	mul	%1, %3, %4
+	mul	%4, %2, %4
+	mul	%3, %0, %3
+	mul	%0, %2, %0
+	adds	%3, %4, %3
+	addcs	%0, %0, #65536
+	adds	%1, %1, %3, lsl #16
+	adc	%0, %0, %3, lsr #16"					\
+	   : "=&r" ((USItype) (xh)),					\
+	     "=r" ((USItype) (xl)),					\
+	     "=&r" (__t0), "=&r" (__t1), "=r" (__t2)			\
+	   : "r" ((USItype) (a)),					\
+	     "r" ((USItype) (b)));}
+#define UMUL_TIME 20
+#define UDIV_TIME 100
+#endif /* __arm__ */
+
+#define __umulsidi3(u, v) \
+  ({DIunion __w;							\
+    umul_ppmm (__w.s.high, __w.s.low, u, v);				\
+    __w.ll; })
+
+#define __udiv_qrnnd_c(q, r, n1, n0, d) \
+  do {									\
+    USItype __d1, __d0, __q1, __q0;					\
+    USItype __r1, __r0, __m;						\
+    __d1 = __ll_highpart (d);						\
+    __d0 = __ll_lowpart (d);						\
+									\
+    __r1 = (n1) % __d1;							\
+    __q1 = (n1) / __d1;							\
+    __m = (USItype) __q1 * __d0;					\
+    __r1 = __r1 * __ll_B | __ll_highpart (n0);				\
+    if (__r1 < __m)							\
+      {									\
+	__q1--, __r1 += (d);						\
+	if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
+	  if (__r1 < __m)						\
+	    __q1--, __r1 += (d);					\
+      }									\
+    __r1 -= __m;							\
+									\
+    __r0 = __r1 % __d1;							\
+    __q0 = __r1 / __d1;							\
+    __m = (USItype) __q0 * __d0;					\
+    __r0 = __r0 * __ll_B | __ll_lowpart (n0);				\
+    if (__r0 < __m)							\
+      {									\
+	__q0--, __r0 += (d);						\
+	if (__r0 >= (d))						\
+	  if (__r0 < __m)						\
+	    __q0--, __r0 += (d);					\
+      }									\
+    __r0 -= __m;							\
+									\
+    (q) = (USItype) __q1 * __ll_B | __q0;				\
+    (r) = __r0;								\
+  } while (0)
+
+#define UDIV_NEEDS_NORMALIZATION 1
+#define udiv_qrnnd __udiv_qrnnd_c
+
+extern const UQItype __clz_tab[];
+#define count_leading_zeros(count, x) \
+  do {									\
+    USItype __xr = (x);							\
+    USItype __a;							\
+									\
+    if (SI_TYPE_SIZE <= 32)						\
+      {									\
+	__a = __xr < ((USItype)1<<2*__BITS4)				\
+	  ? (__xr < ((USItype)1<<__BITS4) ? 0 : __BITS4)		\
+	  : (__xr < ((USItype)1<<3*__BITS4) ?  2*__BITS4 : 3*__BITS4);	\
+      }									\
+    else								\
+      {									\
+	for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8)			\
+	  if (((__xr >> __a) & 0xff) != 0)				\
+	    break;							\
+      }									\
+									\
+    (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a);		\
+  } while (0)
diff -u --recursive --new-file v2.4.12/linux/arch/arm/lib/lshrdi3.c linux/arch/arm/lib/lshrdi3.c
--- v2.4.12/linux/arch/arm/lib/lshrdi3.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/lshrdi3.c	Thu Oct 11 09:04:57 2001
@@ -0,0 +1,61 @@
+/* More subroutines needed by GCC output code on some machines.  */
+/* Compile this one with gcc.  */
+/* 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.  */
+
+/* As a special exception, if you link this library with other files,
+   some of which are compiled with GCC, to produce an executable,
+   this library does not by itself 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.
+ */
+/* support functions required by the kernel. based on code from gcc-2.95.3 */
+/* I Molton     29/07/01 */
+
+#include "gcclib.h"
+
+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 -u --recursive --new-file v2.4.12/linux/arch/arm/lib/muldi3.c linux/arch/arm/lib/muldi3.c
--- v2.4.12/linux/arch/arm/lib/muldi3.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/muldi3.c	Thu Oct 11 09:04:57 2001
@@ -0,0 +1,77 @@
+/* More subroutines needed by GCC output code on some machines.  */
+/* Compile this one with gcc.  */
+/* 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.  */
+
+/* As a special exception, if you link this library with other files,
+   some of which are compiled with GCC, to produce an executable,
+   this library does not by itself 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.
+ */
+/* support functions required by the kernel. based on code from gcc-2.95.3 */
+/* I Molton     29/07/01 */
+
+#include "gcclib.h"
+
+#define umul_ppmm(xh, xl, a, b) \
+{register USItype __t0, __t1, __t2;                                     \
+  __asm__ ("%@ Inlined umul_ppmm
+        mov     %2, %5, lsr #16
+        mov     %0, %6, lsr #16
+        bic     %3, %5, %2, lsl #16
+        bic     %4, %6, %0, lsl #16
+        mul     %1, %3, %4
+        mul     %4, %2, %4
+        mul     %3, %0, %3
+        mul     %0, %2, %0
+        adds    %3, %4, %3
+        addcs   %0, %0, #65536
+        adds    %1, %1, %3, lsl #16
+        adc     %0, %0, %3, lsr #16"                                    \
+           : "=&r" ((USItype) (xh)),                                    \
+             "=r" ((USItype) (xl)),                                     \
+             "=&r" (__t0), "=&r" (__t1), "=r" (__t2)                    \
+           : "r" ((USItype) (a)),                                       \
+             "r" ((USItype) (b)));}
+
+
+#define __umulsidi3(u, v) \
+  ({DIunion __w;                                                        \
+    umul_ppmm (__w.s.high, __w.s.low, u, v);                            \
+    __w.ll; })
+
+
+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 -u --recursive --new-file v2.4.12/linux/arch/arm/lib/putuser.S linux/arch/arm/lib/putuser.S
--- v2.4.12/linux/arch/arm/lib/putuser.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/putuser.S	Thu Oct 11 09:04:57 2001
@@ -0,0 +1,94 @@
+/*
+ *  linux/arch/arm/lib/putuser.S
+ *
+ *  Copyright (C) 2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Idea from x86 version, (C) Copyright 1998 Linus Torvalds
+ *
+ * These functions have a non-standard call interface to make
+ * them more efficient, especially as they return an error
+ * value in addition to the "real" return value.
+ *
+ * __put_user_X
+ *
+ * Inputs:	r0 contains the address
+ *		r1, r2 contains the value
+ * Outputs:	r0 is the error code
+ *		lr corrupted
+ *
+ * No other registers must be altered.  (see include/asm-arm/uaccess.h
+ * for specific ASM register usage).
+ *
+ * Note that ADDR_LIMIT is either 0 or 0xc0000000
+ * Note also that it is intended that __put_user_bad is not global.
+ */
+#include <asm/constants.h>
+
+	.global	__put_user_1
+__put_user_1:
+	bic	r2, sp, #0x1f00
+	bic	r2, r2, #0x00ff
+	ldr	r2, [r2, #TSK_ADDR_LIMIT]
+	sub	r2, r2, #1
+	cmp	r0, r2
+1:	strlsbt	r1, [r0]
+	movls	r0, #0
+	movls	pc, lr
+	b	__put_user_bad
+
+	.global	__put_user_2
+__put_user_2:
+	bic	r2, sp, #0x1f00
+	bic	r2, r2, #0x00ff
+	ldr	r2, [r2, #TSK_ADDR_LIMIT]
+	sub	r2, r2, #2
+	cmp	r0, r2
+2:	strlsbt	r1, [r0], #1
+	movls	r1, r1, lsr #8
+3:	strlsbt	r1, [r0]
+	movls	r0, #0
+	movls	pc, lr
+	b	__put_user_bad
+
+	.global	__put_user_4
+__put_user_4:
+	bic	r2, sp, #0x1f00
+	bic	r2, r2, #0x00ff
+	ldr	r2, [r2, #TSK_ADDR_LIMIT]
+	sub	r2, r2, #4
+	cmp	r0, r2
+4:	strlst	r1, [r0]
+	movls	r0, #0
+	movls	pc, lr
+	b	__put_user_bad
+
+	.global	__put_user_8
+__put_user_8:
+	bic	ip, sp, #0x1f00
+	bic	ip, ip, #0x00ff
+	ldr	ip, [ip, #TSK_ADDR_LIMIT]
+	sub	ip, ip, #8
+	cmp	r0, ip
+5:	strlst	r1, [r0], #4
+6:	strlst	r2, [r0]
+	movls	r0, #0
+	movls	pc, lr
+
+	/* fall through */
+
+__put_user_bad:
+	mov	r0, #-14
+	mov	pc, lr
+
+.section __ex_table, "a"
+	.long	1b, __put_user_bad
+	.long	2b, __put_user_bad
+	.long	3b, __put_user_bad
+	.long	4b, __put_user_bad
+	.long	5b, __put_user_bad
+	.long	6b, __put_user_bad
+.previous
diff -u --recursive --new-file v2.4.12/linux/arch/arm/lib/ucmpdi2.c linux/arch/arm/lib/ucmpdi2.c
--- v2.4.12/linux/arch/arm/lib/ucmpdi2.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/ucmpdi2.c	Thu Oct 11 09:04:57 2001
@@ -0,0 +1,51 @@
+/* More subroutines needed by GCC output code on some machines.  */
+/* Compile this one with gcc.  */
+/* 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.  */
+
+/* As a special exception, if you link this library with other files,
+   some of which are compiled with GCC, to produce an executable,
+   this library does not by itself 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.
+ */
+/* support functions required by the kernel. based on code from gcc-2.95.3 */
+/* I Molton     29/07/01 */
+
+#include "gcclib.h"
+
+word_type
+__ucmpdi2 (DItype a, DItype b)
+{
+  DIunion au, bu;
+
+  au.ll = a, bu.ll = b;
+
+  if ((USItype) au.s.high < (USItype) bu.s.high)
+    return 0;
+  else if ((USItype) au.s.high > (USItype) bu.s.high)
+    return 2;
+  if ((USItype) au.s.low < (USItype) bu.s.low)
+    return 0;
+  else if ((USItype) au.s.low > (USItype) bu.s.low)
+    return 2;
+  return 1;
+}
+
diff -u --recursive --new-file v2.4.12/linux/arch/arm/lib/udivdi3.c linux/arch/arm/lib/udivdi3.c
--- v2.4.12/linux/arch/arm/lib/udivdi3.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/udivdi3.c	Thu Oct 11 09:04:57 2001
@@ -0,0 +1,231 @@
+/* More subroutines needed by GCC output code on some machines.  */
+/* Compile this one with gcc.  */
+/* 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.  */
+
+/* As a special exception, if you link this library with other files,
+   some of which are compiled with GCC, to produce an executable,
+   this library does not by itself 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.
+ */
+/* support functions required by the kernel. based on code from gcc-2.95.3 */
+/* I Molton     29/07/01 */
+
+#include "gcclib.h"
+#include "longlong.h"
+
+static const UQItype __clz_tab[] =
+{
+  0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+};
+
+UDItype
+__udivmoddi4 (UDItype n, UDItype d, UDItype *rp)
+{
+  DIunion ww;
+  DIunion nn, dd;
+  DIunion rr;
+  USItype d0, d1, n0, n1, n2;
+  USItype q0, q1;
+  USItype b, bm;
+
+  nn.ll = n;
+  dd.ll = d;
+
+  d0 = dd.s.low;
+  d1 = dd.s.high;
+  n0 = nn.s.low;
+  n1 = nn.s.high;
+
+  if (d1 == 0)
+    {
+      if (d0 > n1)
+        {
+          /* 0q = nn / 0D */
+
+          count_leading_zeros (bm, d0);
+
+          if (bm != 0)
+            {
+              /* Normalize, i.e. make the most significant bit of the
+                 denominator set.  */
+
+              d0 = d0 << bm;
+              n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
+              n0 = n0 << bm;
+            }
+
+          udiv_qrnnd (q0, n0, n1, n0, d0);
+          q1 = 0;
+
+          /* Remainder in n0 >> bm.  */
+        }
+      else
+        {
+          /* qq = NN / 0d */
+
+          if (d0 == 0)
+            d0 = 1 / d0;        /* Divide intentionally by zero.  */
+
+          count_leading_zeros (bm, d0);
+
+          if (bm == 0)
+            {
+              /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
+                 conclude (the most significant bit of n1 is set) /\ (the
+                 leading quotient digit q1 = 1).
+
+                 This special case is necessary, not an optimization.
+                 (Shifts counts of SI_TYPE_SIZE are undefined.)  */
+
+              n1 -= d0;
+              q1 = 1;
+            }
+          else
+            {
+              /* Normalize.  */
+
+              b = SI_TYPE_SIZE - bm;
+
+              d0 = d0 << bm;
+              n2 = n1 >> b;
+              n1 = (n1 << bm) | (n0 >> b);
+              n0 = n0 << bm;
+
+              udiv_qrnnd (q1, n1, n2, n1, d0);
+            }
+
+          /* n1 != d0...  */
+
+          udiv_qrnnd (q0, n0, n1, n0, d0);
+
+          /* Remainder in n0 >> bm.  */
+        }
+
+      if (rp != 0)
+        {
+          rr.s.low = n0 >> bm;
+          rr.s.high = 0;
+          *rp = rr.ll;
+        }
+    }
+  else
+    {
+      if (d1 > n1)
+        {
+          /* 00 = nn / DD */
+
+          q0 = 0;
+          q1 = 0;
+
+          /* Remainder in n1n0.  */
+          if (rp != 0)
+            {
+              rr.s.low = n0;
+              rr.s.high = n1;
+              *rp = rr.ll;
+            }
+        }
+      else
+        {
+          /* 0q = NN / dd */
+
+          count_leading_zeros (bm, d1);
+          if (bm == 0)
+            {
+              /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
+                 conclude (the most significant bit of n1 is set) /\ (the
+                 quotient digit q0 = 0 or 1).
+
+                 This special case is necessary, not an optimization.  */
+
+              /* The condition on the next line takes advantage of that
+                 n1 >= d1 (true due to program flow).  */
+              if (n1 > d1 || n0 >= d0)
+                {
+                  q0 = 1;
+                  sub_ddmmss (n1, n0, n1, n0, d1, d0);
+                }
+              else
+                q0 = 0;
+
+              q1 = 0;
+
+              if (rp != 0)
+                {
+                  rr.s.low = n0;
+                  rr.s.high = n1;
+                  *rp = rr.ll;
+                }
+            }
+          else
+            {
+              USItype m1, m0;
+              /* Normalize.  */
+
+              b = SI_TYPE_SIZE - bm;
+
+              d1 = (d1 << bm) | (d0 >> b);
+              d0 = d0 << bm;
+              n2 = n1 >> b;
+              n1 = (n1 << bm) | (n0 >> b);
+              n0 = n0 << bm;
+
+              udiv_qrnnd (q0, n1, n2, n1, d1);
+              umul_ppmm (m1, m0, q0, d0);
+
+              if (m1 > n1 || (m1 == n1 && m0 > n0))
+                {
+                  q0--;
+                  sub_ddmmss (m1, m0, m1, m0, d1, d0);
+                }
+
+              q1 = 0;
+
+              /* Remainder in (n1n0 - m1m0) >> bm.  */
+              if (rp != 0)
+                {
+                  sub_ddmmss (n1, n0, n1, n0, m1, m0);
+                  rr.s.low = (n1 << b) | (n0 >> bm);
+                  rr.s.high = n1 >> bm;
+                  *rp = rr.ll;
+                }
+            }
+        }
+    }
+
+  ww.s.low = q0;
+  ww.s.high = q1;
+  return ww.ll;
+}
+
+UDItype
+__udivdi3 (UDItype n, UDItype d)
+{
+  return __udivmoddi4 (n, d, (UDItype *) 0);
+}
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-ebsa110/io.c linux/arch/arm/mach-ebsa110/io.c
--- v2.4.12/linux/arch/arm/mach-ebsa110/io.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-ebsa110/io.c	Thu Oct 11 09:04:57 2001
@@ -279,6 +279,9 @@
 	__raw_readsb(ISAIO_BASE + off, from, len);
 }
 
+EXPORT_SYMBOL(outsb);
+EXPORT_SYMBOL(insb);
+
 void outsw(unsigned int port, const void *from, int len)
 {
 	u32 off;
@@ -308,6 +311,9 @@
 
 	__raw_readsw(ISAIO_BASE + off, from, len);
 }
+
+EXPORT_SYMBOL(outsw);
+EXPORT_SYMBOL(insw);
 
 void outsl(unsigned int port, const void *from, int len)
 {
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-integrator/cpu.c linux/arch/arm/mach-integrator/cpu.c
--- v2.4.12/linux/arch/arm/mach-integrator/cpu.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-integrator/cpu.c	Thu Oct 11 09:04:57 2001
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 2001 Deep Blue Solutions Ltd.
  *
- *  $Id: cpu.c,v 1.1 2001/06/17 10:12:37 rmk Exp $
+ *  $Id: cpu.c,v 1.2 2001/09/22 12:11:17 rmk 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
@@ -70,7 +70,7 @@
  * Validate the speed in khz.  If it is outside our
  * range, then return the lowest.
  */
-unsigned int cpufreq_validatespeed(unsigned int freq_khz)
+unsigned int integrator_validatespeed(unsigned int freq_khz)
 {
 	struct vco vco;
 
@@ -87,7 +87,7 @@
 	return vco_to_freq(vco, 1);
 }
 
-void cpufreq_setspeed(unsigned int freq_khz)
+void integrator_setspeed(unsigned int freq_khz)
 {
 	struct vco vco = freq_to_vco(freq_khz, 1);
 	u_int cm_osc;
@@ -122,6 +122,7 @@
 
 #ifdef CONFIG_CPU_FREQ
 	cpufreq_init(cpu_freq_khz);
+	cpufreq_setfunctions(integrator_validatespeed, integrator_setspeed);
 #endif
 
 	cm_stat = __raw_readl(CM_STAT);
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-integrator/dma.c linux/arch/arm/mach-integrator/dma.c
--- v2.4.12/linux/arch/arm/mach-integrator/dma.c	Fri Mar  2 18:38:39 2001
+++ linux/arch/arm/mach-integrator/dma.c	Thu Oct 11 09:04:57 2001
@@ -19,7 +19,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/sched.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/mman.h>
 #include <linux/init.h>
 
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-integrator/pci_v3.c linux/arch/arm/mach-integrator/pci_v3.c
--- v2.4.12/linux/arch/arm/mach-integrator/pci_v3.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-integrator/pci_v3.c	Thu Oct 11 09:04:57 2001
@@ -24,7 +24,7 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/ptrace.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/Makefile linux/arch/arm/mach-sa1100/Makefile
--- v2.4.12/linux/arch/arm/mach-sa1100/Makefile	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/Makefile	Thu Oct 11 09:04:57 2001
@@ -14,31 +14,38 @@
 obj-n :=
 obj-  :=
 
-export-objs :=	assabet.o bitsy.o freebird.o huw_webpanel.o yopy.o \
+export-objs :=	assabet.o h3600.o freebird.o huw_webpanel.o yopy.o \
 		generic.o hwtimer.o irq.o usb_ctl.o usb_recv.o usb_send.o \
-		dma-sa1100.o dma-sa1111.o pcipool.o
+		dma-sa1100.o dma-sa1111.o pcipool.o sa1111-pcibuf.o
 
 # Common support (must be linked before board specific support)
 obj-y += generic.o irq.o dma-sa1100.o
-obj-$(CONFIG_SA1111) += sa1111.o dma-sa1111.o sa1111-pcibuf.o pcipool.o
 
 # This needs to be cleaned up.  We probably need to have SA1100
 # and SA1110 config symbols.
+#
+# We link the CPU support next, so that RAM timings can be tuned.
 ifeq ($(CONFIG_CPU_FREQ),y)
 obj-$(CONFIG_SA1100_ASSABET) += cpu-sa1110.o
 obj-$(CONFIG_SA1100_LART) += cpu-sa1100.o
 endif
 
+# Next, the SA1111 stuff.
+obj-$(CONFIG_SA1111) += sa1111.o dma-sa1111.o
+obj-$(CONFIG_USB_OHCI_SA1111) += sa1111-pcibuf.o pcipool.o
+
 # Specific board support
+obj-$(CONFIG_SA1100_ADSBITSY) += adsbitsy.o
 obj-$(CONFIG_SA1100_ASSABET) += assabet.o
 obj-$(CONFIG_ASSABET_NEPONSET) += neponset.o
-obj-$(CONFIG_SA1100_BITSY) += bitsy.o
 obj-$(CONFIG_SA1100_BRUTUS) += brutus.o
 obj-$(CONFIG_SA1100_CERF) += cerf.o
 obj-$(CONFIG_SA1100_EMPEG) += empeg.o
 obj-$(CONFIG_SA1100_FLEXANET) += flexanet.o
 obj-$(CONFIG_SA1100_FREEBIRD) += freebird.o
 obj-$(CONFIG_SA1100_GRAPHICSCLIENT) += graphicsclient.o
+obj-$(CONFIG_SA1100_GRAPHICSMASTER) += graphicsmaster.o
+obj-$(CONFIG_SA1100_H3600) += h3600.o
 obj-$(CONFIG_SA1100_HUW_WEBPANEL) += huw_webpanel.o
 obj-$(CONFIG_SA1100_ITSY) += itsy.o
 obj-$(CONFIG_SA1100_JORNADA720) += jornada720.o
@@ -63,6 +70,7 @@
 leds-$(CONFIG_SA1100_GRAPHICSCLIENT) += leds-graphicsclient.o
 leds-$(CONFIG_SA1100_LART) += leds-lart.o
 leds-$(CONFIG_SA1100_PFS168) += leds-pfs168.o
+leds-$(CONFIG_SA1100_GRAPHICSMASTER) += leds-graphicsmaster.o
 obj-$(CONFIG_LEDS) += $(leds-y)
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/adsbitsy.c linux/arch/arm/mach-sa1100/adsbitsy.c
--- v2.4.12/linux/arch/arm/mach-sa1100/adsbitsy.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/mach-sa1100/adsbitsy.c	Thu Oct 11 09:04:57 2001
@@ -0,0 +1,180 @@
+/*
+ * linux/arch/arm/mach-sa1100/adsbitsy.c
+ *
+ * Author: Woojung Huh
+ *
+ * Pieces specific to the ADS Bitsy
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/serial_core.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include <asm/arch/irq.h>
+
+#include "generic.h"
+#include "sa1111.h"
+
+static int __init adsbitsy_init(void)
+{
+	int ret;
+
+	if (!machine_is_adsbitsy())
+		return -ENODEV;
+
+	/*
+	 * Ensure that the memory bus request/grant signals are setup,
+	 * and the grant is held in its inactive state
+	 */
+	sa1110_mb_disable();
+
+	/*
+	 * Reset SA1111
+	 */
+	GPCR |= GPIO_GPIO26;
+	udelay(1000);
+	GPSR |= GPIO_GPIO26;
+
+	/*
+	 * Probe for SA1111.
+	 */
+	ret = sa1111_probe();
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * We found it.  Wake the chip up.
+	 */
+	sa1111_wake();
+
+	/*
+	 * The SDRAM configuration of the SA1110 and the SA1111 must
+	 * match.  This is very important to ensure that SA1111 accesses
+	 * don't corrupt the SDRAM.  Note that this ungates the SA1111's
+	 * MBGNT signal, so we must have called sa1110_mb_disable()
+	 * beforehand.
+	 */
+	sa1111_configure_smc(1,
+			     FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
+			     FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
+
+	/*
+	 * Enable PWM control for LCD
+	 */
+	SKPCR |= SKPCR_PWMCLKEN;
+	SKPWM0 = 0x7F;				// VEE
+	SKPEN0 = 1;
+	SKPWM1 = 0x01;				// Backlight
+	SKPEN1 = 1;
+
+	/*
+	 * We only need to turn on DCLK whenever we want to use the
+	 * DMA.  It can otherwise be held firmly in the off position.
+	 */
+	SKPCR |= SKPCR_DCLKEN;
+
+	/*
+	 * Enable the SA1110 memory bus request and grant signals.
+	 */
+	sa1110_mb_enable();
+
+	set_GPIO_IRQ_edge(GPIO_GPIO0, GPIO_RISING_EDGE);
+	sa1111_init_irq(SA1100_GPIO_TO_IRQ(0));
+
+	return 0;
+}
+
+__initcall(adsbitsy_init);
+
+static void __init adsbitsy_init_irq(void)
+{
+	/* First the standard SA1100 IRQs */
+	sa1100_init_irq();
+}
+
+
+/*
+ * Initialization fixup
+ */
+
+static void __init
+fixup_adsbitsy(struct machine_desc *desc, struct param_struct *params,
+		     char **cmdline, struct meminfo *mi)
+{
+	SET_BANK( 0, 0xc0000000, 32*1024*1024 );
+	mi->nr_banks = 1;
+
+	ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+	setup_ramdisk( 1, 0, 0, 8192 );
+	setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
+}
+
+static struct map_desc adsbitsy_io_desc[] __initdata = {
+ /* virtual     physical    length      domain     r  w  c  b */
+  { 0xe8000000, 0x08000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */
+  { 0xf4000000, 0x18000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA1111 */
+  LAST_DESC
+};
+
+static int adsbitsy_uart_open(struct uart_port *port, struct uart_info *info)
+{
+	if (port->mapbase == _Ser1UTCR0) {
+		Ser1SDCR0 |= SDCR0_UART;
+		// Set RTS Output and High (should be done in the set_mctrl fn)
+		GPDR |= GPIO_GPIO15;
+		GPCR |= GPIO_GPIO15;
+		// Set CTS Input
+		GPDR &= ~GPIO_GPIO14;
+	} else if (port->mapbase == _Ser2UTCR0) {
+		Ser2UTCR4 = Ser2HSCR0 = 0;
+		// Set RTS Output and High (should be done in the set_mctrl fn)
+		GPDR |= GPIO_GPIO17;
+		GPCR |= GPIO_GPIO17;
+		// Set CTS Input
+		GPDR &= ~GPIO_GPIO16;
+	} else if (port->mapbase == _Ser2UTCR0) {
+		// Set RTS Output and High (should be done in the set_mctrl fn)
+		GPDR |= GPIO_GPIO19;
+		GPCR |= GPIO_GPIO19;
+		// Set CTS Input
+		GPDR &= ~GPIO_GPIO18;
+	}
+	return 0;
+}
+
+static struct sa1100_port_fns adsbitsy_port_fns __initdata = {
+	open:	adsbitsy_uart_open,
+};
+
+static void __init adsbitsy_map_io(void)
+{
+	sa1100_map_io();
+	iotable_init(adsbitsy_io_desc);
+
+	sa1110_register_uart_fns(&adsbitsy_port_fns);
+	sa1100_register_uart(0, 3);
+	sa1100_register_uart(1, 1);
+	sa1100_register_uart(2, 2);
+}
+
+MACHINE_START(ADSBITSY, "ADS Bitsy")
+	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+	FIXUP(fixup_adsbitsy)
+	MAPIO(adsbitsy_map_io)
+	INITIRQ(adsbitsy_init_irq)
+MACHINE_END
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/assabet.c linux/arch/arm/mach-sa1100/assabet.c
--- v2.4.12/linux/arch/arm/mach-sa1100/assabet.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/assabet.c	Thu Oct 11 09:04:57 2001
@@ -47,6 +47,7 @@
 		 * or BCR_clear().
 		 */
 		BCR = BCR_value = BCR_DB1111;
+		NCR_0 = 0;
 
 #ifndef CONFIG_ASSABET_NEPONSET
 		printk( "Warning: Neponset detected but full support "
@@ -101,6 +102,8 @@
 	SCR_value = scr;
 }
 
+extern void convert_to_tag_list(struct param_struct *params, int mem_init);
+
 static void __init
 fixup_assabet(struct machine_desc *desc, struct param_struct *params,
 	      char **cmdline, struct meminfo *mi)
@@ -114,6 +117,12 @@
 	if (machine_has_neponset())
 		printk("Neponset expansion board detected\n");
 
+	/*
+	 * Apparantly bootldr uses a param_struct.  Groan.
+	 */
+	if (t->hdr.tag != ATAG_CORE)
+		convert_to_tag_list(params, 1);
+
 	if (t->hdr.tag != ATAG_CORE) {
 		t->hdr.tag = ATAG_CORE;
 		t->hdr.size = tag_size(tag_core);
@@ -265,7 +274,6 @@
 	neponset_map_io();
 #endif
 
-	sa1100_register_uart(1, 2);
 	if (machine_has_neponset()) {
 		/*
 		 * When Neponset is attached, the first UART should be
@@ -295,7 +303,7 @@
 	 * excessive power drain.  --rmk
 	 */
 	GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
-	GPCR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
+	GPCR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
 }
 
 
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/bitsy.c linux/arch/arm/mach-sa1100/bitsy.c
--- v2.4.12/linux/arch/arm/mach-sa1100/bitsy.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/bitsy.c	Wed Dec 31 16:00:00 1969
@@ -1,175 +0,0 @@
-/*
- * linux/arch/arm/mach-sa1100/bitsy.c
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/tty.h>
-#include <linux/sched.h>
-
-#include <asm/irq.h>
-#include <asm/hardware.h>
-#include <asm/setup.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/serial_sa1100.h>
-#include <linux/serial_core.h>
-
-#include "generic.h"
-
-
-/*
- * Bitsy has extended, write-only memory-mapped GPIO's
- */
-
-static int bitsy_egpio = EGPIO_BITSY_RS232_ON;
-
-void clr_bitsy_egpio(unsigned long x)
-{
-	bitsy_egpio &= ~x;
-	BITSY_EGPIO = bitsy_egpio;
-}
-
-void set_bitsy_egpio(unsigned long x)
-{
-	bitsy_egpio |= x;
-	BITSY_EGPIO = bitsy_egpio;
-}
-
-EXPORT_SYMBOL(clr_bitsy_egpio);
-EXPORT_SYMBOL(set_bitsy_egpio);
-
-
-/*
- * low-level UART features
- */
-
-static void bitsy_uart_set_mctrl(struct uart_port *port, u_int mctrl)
-{
-	if (port->mapbase == _Ser3UTCR0) {
-		if (mctrl & TIOCM_RTS)
-			GPCR = GPIO_BITSY_COM_RTS;
-		else
-			GPSR = GPIO_BITSY_COM_RTS;
-	}
-}
-
-static int bitsy_uart_get_mctrl(struct uart_port *port)
-{
-	int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
-
-	if (port->mapbase == _Ser3UTCR0) {
-		int gplr = GPLR;
-		if (gplr & GPIO_BITSY_COM_DCD)
-			ret &= ~TIOCM_CD;
-		if (gplr & GPIO_BITSY_COM_CTS)
-			ret &= ~TIOCM_CTS;
-	}
-
-	return ret;
-}
-
-static void bitsy_dcd_intr(int irq, void *dev_id, struct pt_regs *regs)
-{
-	struct uart_info *info = dev_id;
-	/* Note: should only call this if something has changed */
-	uart_handle_dcd_change(info, GPLR & GPIO_BITSY_COM_DCD);
-}
-
-static void bitsy_cts_intr(int irq, void *dev_id, struct pt_regs *regs)
-{
-	struct uart_info *info = dev_id;
-	/* Note: should only call this if something has changed */
-	uart_handle_cts_change(info, GPLR & GPIO_BITSY_COM_CTS);
-}
-
-static void bitsy_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
-{
-	if (port->mapbase == _Ser2UTCR0) {
-		if (state == 0) {
-			set_bitsy_egpio(EGPIO_BITSY_IR_ON);
-		} else {
-			clr_bitsy_egpio(EGPIO_BITSY_IR_ON);
-		}
-	} else if (port->mapbase == _Ser3UTCR0) {
-		if (state == 0) {
-			set_bitsy_egpio(EGPIO_BITSY_RS232_ON);
-		} else {
-			clr_bitsy_egpio(EGPIO_BITSY_RS232_ON);
-		}
-	}
-}
-
-static int bitsy_uart_open(struct uart_port *port, struct uart_info *info)
-{
-	int ret = 0;
-
-	if (port->mapbase == _Ser2UTCR0) {
-		Ser2UTCR4 = UTCR4_HSE;
-		Ser2HSCR0 = 0;
-		Ser2HSSR0 = HSSR0_EIF | HSSR0_TUR |
-			    HSSR0_RAB | HSSR0_FRE;
-	} else if (port->mapbase == _Ser3UTCR0) {
-		GPDR &= ~(GPIO_BITSY_COM_DCD|GPIO_BITSY_COM_CTS);
-		GPDR |= GPIO_BITSY_COM_RTS;
-		set_GPIO_IRQ_edge(GPIO_BITSY_COM_DCD|GPIO_BITSY_COM_CTS,
-				  GPIO_BOTH_EDGES);
-
-		ret = request_irq(IRQ_GPIO_BITSY_COM_DCD, bitsy_dcd_intr,
-				  0, "RS232 DCD", info);
-		if (ret)
-			return ret;
-
-		ret = request_irq(IRQ_GPIO_BITSY_COM_CTS, bitsy_cts_intr,
-				  0, "RS232 CTS", info);
-		if (ret)
-			free_irq(IRQ_GPIO_BITSY_COM_DCD, info);
-	}
-	return ret;
-}
-
-static void bitsy_uart_close(struct uart_port *port, struct uart_info *info)
-{
-	if (port->mapbase == _Ser3UTCR0) {
-		free_irq(IRQ_GPIO_BITSY_COM_DCD, info);
-		free_irq(IRQ_GPIO_BITSY_COM_CTS, info);
-	}
-}
-
-static struct sa1100_port_fns bitsy_port_fns __initdata = {
-	set_mctrl:	bitsy_uart_set_mctrl,
-	get_mctrl:	bitsy_uart_get_mctrl,
-	pm:		bitsy_uart_pm,
-	open:		bitsy_uart_open,
-	close:		bitsy_uart_close,
-};
-
-static struct map_desc bitsy_io_desc[] __initdata = {
- /* virtual     physical    length      domain     r  w  c  b */
-  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
-  { 0xf0000000, 0x49000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* EGPIO 0 */
-  { 0xf1000000, 0x10000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* static memory bank 2 */
-  { 0xf3000000, 0x40000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* static memory bank 4 */
-  LAST_DESC
-};
-
-static void __init bitsy_map_io(void)
-{
-	sa1100_map_io();
-	iotable_init(bitsy_io_desc);
-
-	sa1100_register_uart_fns(&bitsy_port_fns);
-	sa1100_register_uart(0, 3);
-	sa1100_register_uart(1, 1); /* isn't this one driven elsewhere? */
-	sa1100_register_uart(2, 2);
-}
-
-MACHINE_START(BITSY, "Compaq iPAQ")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	BOOT_PARAMS(0xc0000100)
-	MAPIO(bitsy_map_io)
-	INITIRQ(sa1100_init_irq)
-MACHINE_END
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/cpu-sa1110.c linux/arch/arm/mach-sa1100/cpu-sa1110.c
--- v2.4.12/linux/arch/arm/mach-sa1100/cpu-sa1110.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/cpu-sa1110.c	Thu Oct 11 09:04:57 2001
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 2001 Russell King
  *
- *  $Id: cpu-sa1110.c,v 1.3 2001/08/12 15:41:53 rmk Exp $
+ *  $Id: cpu-sa1110.c,v 1.5 2001/09/10 13:25:58 rmk 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
@@ -258,14 +258,13 @@
 {
 	struct sdram_params *sdram = NULL;
 	unsigned int cur_freq = cpufreq_get(smp_processor_id());
-	int ret = -ENODEV;
 
 	if (machine_is_assabet())
 		sdram = &tc59sm716_cl3_params;
 
 	if (sdram) {
 		printk(KERN_DEBUG "SDRAM: tck: %d trcd: %d trp: %d"
-			" twr: %d refresh: %d cas_latency: %d",
+			" twr: %d refresh: %d cas_latency: %d\n",
 			sdram->tck, sdram->trcd, sdram->trp,
 			sdram->twr, sdram->refresh, sdram->cas_latency);
 
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/dma-sa1100.c linux/arch/arm/mach-sa1100/dma-sa1100.c
--- v2.4.12/linux/arch/arm/mach-sa1100/dma-sa1100.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/dma-sa1100.c	Thu Oct 11 09:04:57 2001
@@ -68,26 +68,30 @@
 {
 	dma_regs_t *regs = dma->regs;
 	int status;
-	int use_bufa;
 
 	status = regs->RdDCSR;
 
 	/* If both DMA buffers are started, there's nothing else we can do. */
-	if ((status & DCSR_STRTA) && (status & DCSR_STRTB)) {
+	if ((status & (DCSR_STRTA | DCSR_STRTB)) == (DCSR_STRTA | DCSR_STRTB)) {
 		DPRINTK("start: st %#x busy\n", status);
 		return -EBUSY;
 	}
 
-	use_bufa = (((status & DCSR_BIU) && (status & DCSR_STRTB)) ||
-		    (!(status & DCSR_BIU) && !(status & DCSR_STRTA)));
-	if (use_bufa) {
-		regs->ClrDCSR = DCSR_DONEA | DCSR_STRTA;
+	if (((status & DCSR_BIU) && (status & DCSR_STRTB)) ||
+	    (!(status & DCSR_BIU) && !(status & DCSR_STRTA))) {
+		if (status & DCSR_DONEA) {
+			/* give a chance for the interrupt to be processed */
+			goto irq_pending;
+		}
 		regs->DBSA = dma_ptr;
 		regs->DBTA = size;
 		regs->SetDCSR = DCSR_STRTA | DCSR_IE | DCSR_RUN;
 		DPRINTK("start a=%#x s=%d on A\n", dma_ptr, size);
 	} else {
-		regs->ClrDCSR = DCSR_DONEB | DCSR_STRTB;
+		if (status & DCSR_DONEB) {
+			/* give a chance for the interrupt to be processed */
+			goto irq_pending;
+		}
 		regs->DBSB = dma_ptr;
 		regs->DBTB = size;
 		regs->SetDCSR = DCSR_STRTB | DCSR_IE | DCSR_RUN;
@@ -95,6 +99,9 @@
 	}
 
 	return 0;
+
+irq_pending:
+	return -EAGAIN;
 }
 
 
@@ -204,11 +211,16 @@
 
 	DPRINTK("IRQ: b=%#x st=%#x\n", (int) dma->curr->id, status);
 
-	dma->regs->ClrDCSR = DCSR_ERROR | DCSR_DONEA | DCSR_DONEB;
-	if (!(status & (DCSR_DONEA | DCSR_DONEB)))
-		return;
+	if (status & (DCSR_ERROR)) {
+		printk(KERN_ERR "DMA on \"%s\" caused an error\n", dma->device_id);
+		dma->regs->ClrDCSR = DCSR_ERROR;
+	}
 
-	sa1100_dma_done (dma);
+	dma->regs->ClrDCSR = status & (DCSR_DONEA | DCSR_DONEB);
+	if (status & DCSR_DONEA)
+		sa1100_dma_done (dma);
+	if (status & DCSR_DONEB)
+		sa1100_dma_done (dma);
 }
 
 
@@ -435,7 +447,7 @@
 		dma->curr = NULL;
 	}
 	dma->spin_ref = 0;
-	dma->regs->ClrDCSR = DCSR_STRTA|DCSR_STRTB;
+	dma->regs->ClrDCSR = DCSR_STRTA|DCSR_STRTB|DCSR_DONEA|DCSR_DONEB;
 	process_dma(dma);
 	local_irq_restore(flags);
 	return 0;
@@ -455,7 +467,6 @@
 	if (dma->stopped) {
 		int flags;
 		save_flags_cli(flags);
-		dma->regs->ClrDCSR = DCSR_STRTA|DCSR_STRTB|DCSR_RUN|DCSR_IE;
 		dma->stopped = 0;
 		dma->spin_ref = 0;
 		process_dma(dma);
@@ -478,7 +489,7 @@
 	if (channel_is_sa1111_sac(channel))
 		sa1111_reset_sac_dma(channel);
 	else
-		dma->regs->ClrDCSR = DCSR_STRTA|DCSR_STRTB|DCSR_RUN|DCSR_IE;
+		dma->regs->ClrDCSR = DCSR_STRTA|DCSR_STRTB|DCSR_DONEA|DCSR_DONEB|DCSR_RUN|DCSR_IE;
 	buf = dma->curr;
 	if (!buf)
 		buf = dma->tail;
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/dma-sa1111.c linux/arch/arm/mach-sa1100/dma-sa1111.c
--- v2.4.12/linux/arch/arm/mach-sa1100/dma-sa1111.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/dma-sa1111.c	Thu Oct 11 09:04:57 2001
@@ -314,7 +314,7 @@
 	if(physaddr<(1<<20))
 	  	return 0;
 
-	switch(FExtr(SMCR, SMCR_DRAC)){
+	switch(FExtr(SBI_SMCR, SMCR_DRAC)){
 	case 01: /* 10 row + bank address bits, A<20> must not be set */
 	  	if(physaddr & (1<<20))
 		  	return -1;
@@ -341,7 +341,7 @@
 		break;
 	default:
 	  	printk(KERN_ERR "%s(): invalid SMCR DRAC value 0%o\n",
-		       __FUNCTION__, FExtr(SMCR, SMCR_DRAC));
+		       __FUNCTION__, FExtr(SBI_SMCR, SMCR_DRAC));
 		return -1;
 	}
 
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/generic.c linux/arch/arm/mach-sa1100/generic.c
--- v2.4.12/linux/arch/arm/mach-sa1100/generic.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/generic.c	Thu Oct 11 09:04:57 2001
@@ -69,7 +69,7 @@
  * Validate the speed in khz.  If we can't generate the precise
  * frequency requested, round it down (to be on the safe side).
  */
-unsigned int cpufreq_validatespeed(unsigned int khz)
+unsigned int sa1100_validatespeed(unsigned int khz)
 {
 	int i;
 
@@ -87,7 +87,7 @@
  * above, we can match for an exact frequency.  If we don't find
  * an exact match, we will to set the lowest frequency to be safe.
  */
-void cpufreq_setspeed(unsigned int khz)
+void sa1100_setspeed(unsigned int khz)
 {
 	int i;
 
@@ -103,6 +103,7 @@
 static int __init sa1100_init_clock(void)
 {
 	cpufreq_init(get_cclk_frequency() * 100);
+	cpufreq_setfunctions(sa1100_validatespeed, sa1100_setspeed);
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/graphicsclient.c linux/arch/arm/mach-sa1100/graphicsclient.c
--- v2.4.12/linux/arch/arm/mach-sa1100/graphicsclient.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/graphicsclient.c	Thu Oct 11 09:04:57 2001
@@ -131,14 +131,15 @@
 	mi->nr_banks = 2;
 
 	ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
-	setup_ramdisk( 1, 0, 0, 4096 );
+	setup_ramdisk( 1, 0, 0, 8192 );
 	setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
 }
 
 static struct map_desc graphicsclient_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xe8000000, 0x08000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */
+  { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */
   { 0xf0000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */
+  { 0xf1000000, 0x18000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CAN */
   LAST_DESC
 };
 
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/graphicsmaster.c linux/arch/arm/mach-sa1100/graphicsmaster.c
--- v2.4.12/linux/arch/arm/mach-sa1100/graphicsmaster.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/mach-sa1100/graphicsmaster.c	Thu Oct 11 09:04:57 2001
@@ -0,0 +1,225 @@
+/*
+ * linux/arch/arm/mach-sa1100/graphicsmaster.c
+ *
+ * Pieces specific to the GraphicsMaster board
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include <asm/arch/irq.h>
+
+#include "generic.h"
+#include "sa1111.h"
+
+static int __init graphicsmaster_init(void)
+{
+	int ret;
+
+	if (!machine_is_graphicsmaster())
+		return -ENODEV;
+
+	/*
+	 * Ensure that the memory bus request/grant signals are setup,
+	 * and the grant is held in its inactive state
+	 */
+	sa1110_mb_disable();
+
+	/*
+	 * Probe for SA1111.
+	 */
+	ret = sa1111_probe();
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * We found it.  Wake the chip up.
+	 */
+	sa1111_wake();
+
+	/*
+	 * The SDRAM configuration of the SA1110 and the SA1111 must
+	 * match.  This is very important to ensure that SA1111 accesses
+	 * don't corrupt the SDRAM.  Note that this ungates the SA1111's
+	 * MBGNT signal, so we must have called sa1110_mb_disable()
+	 * beforehand.
+	 */
+	sa1111_configure_smc(1,
+			     FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
+			     FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
+
+	/*
+	 * Enable PWM control for LCD
+	 */
+	SKPCR |= SKPCR_PWMCLKEN;
+	SKPWM0 = 0x7F;				// VEE
+	SKPEN0 = 1;
+	SKPWM1 = 0x01;				// Backlight
+	SKPEN1 = 1;
+
+	/*
+	 * We only need to turn on DCLK whenever we want to use the
+	 * DMA.  It can otherwise be held firmly in the off position.
+	 */
+	SKPCR |= SKPCR_DCLKEN;
+
+	/*
+	 * Enable the SA1110 memory bus request and grant signals.
+	 */
+	sa1110_mb_enable();
+
+	sa1111_init_irq(ADS_EXT_IRQ(0));
+
+	return 0;
+}
+
+__initcall(graphicsmaster_init);
+
+/*
+ * Handlers for GraphicsMaster's external IRQ logic
+ */
+
+static void ADS_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs )
+{
+	int i;
+
+	while( (irq = ADS_INT_ST1 | (ADS_INT_ST2 << 8)) ){
+		for( i = 0; i < 16; i++ )
+			if( irq & (1<<i) ) {
+				do_IRQ( ADS_EXT_IRQ(i), regs );
+			}
+	}
+}
+
+static struct irqaction ADS_ext_irq = {
+	name:		"ADS_ext_IRQ",
+	handler:	ADS_IRQ_demux,
+	flags:		SA_INTERRUPT
+};
+
+static void ADS_mask_and_ack_irq0(unsigned int irq)
+{
+	int mask = (1 << (irq - ADS_EXT_IRQ(0)));
+	ADS_INT_EN1 &= ~mask;
+	ADS_INT_ST1 = mask;
+}
+
+static void ADS_mask_irq0(unsigned int irq)
+{
+	ADS_INT_ST1 = (1 << (irq - ADS_EXT_IRQ(0)));
+}
+
+static void ADS_unmask_irq0(unsigned int irq)
+{
+	ADS_INT_EN1 |= (1 << (irq - ADS_EXT_IRQ(0)));
+}
+
+static void ADS_mask_and_ack_irq1(unsigned int irq)
+{
+	int mask = (1 << (irq - ADS_EXT_IRQ(8)));
+	ADS_INT_EN2 &= ~mask;
+	ADS_INT_ST2 = mask;
+}
+
+static void ADS_mask_irq1(unsigned int irq)
+{
+	ADS_INT_ST2 = (1 << (irq - ADS_EXT_IRQ(8)));
+}
+
+static void ADS_unmask_irq1(unsigned int irq)
+{
+	ADS_INT_EN2 |= (1 << (irq - ADS_EXT_IRQ(8)));
+}
+
+static void __init graphicsmaster_init_irq(void)
+{
+	int irq;
+
+	/* First the standard SA1100 IRQs */
+	sa1100_init_irq();
+
+	/* disable all IRQs */
+	ADS_INT_EN1 = 0;
+	ADS_INT_EN2 = 0;
+	/* clear all IRQs */
+	ADS_INT_ST1 = 0xff;
+	ADS_INT_ST2 = 0xff;
+
+	for (irq = ADS_EXT_IRQ(0); irq <= ADS_EXT_IRQ(7); irq++) {
+		irq_desc[irq].valid	= 1;
+		irq_desc[irq].probe_ok	= 1;
+		irq_desc[irq].mask_ack	= ADS_mask_and_ack_irq0;
+		irq_desc[irq].mask	= ADS_mask_irq0;
+		irq_desc[irq].unmask	= ADS_unmask_irq0;
+	}
+	for (irq = ADS_EXT_IRQ(8); irq <= ADS_EXT_IRQ(15); irq++) {
+		irq_desc[irq].valid	= 1;
+		irq_desc[irq].probe_ok	= 1;
+		irq_desc[irq].mask_ack	= ADS_mask_and_ack_irq1;
+		irq_desc[irq].mask	= ADS_mask_irq1;
+		irq_desc[irq].unmask	= ADS_unmask_irq1;
+	}
+	GPDR &= ~GPIO_GPIO0;
+	set_GPIO_IRQ_edge(GPIO_GPIO0, GPIO_FALLING_EDGE);
+	setup_arm_irq( IRQ_GPIO0, &ADS_ext_irq );
+}
+
+
+/*
+ * Initialization fixup
+ */
+
+static void __init
+fixup_graphicsmaster(struct machine_desc *desc, struct param_struct *params,
+		     char **cmdline, struct meminfo *mi)
+{
+	SET_BANK( 0, 0xc0000000, 16*1024*1024 );
+	mi->nr_banks = 1;
+	SET_BANK( 1, 0xc8000000, 16*1024*1024 );
+	mi->nr_banks = 2;
+
+	ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+	setup_ramdisk( 1, 0, 0, 8192 );
+	setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
+}
+
+static struct map_desc graphicsmaster_io_desc[] __initdata = {
+ /* virtual     physical    length      domain     r  w  c  b */
+  { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */
+  { 0xf0000000, 0x10000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* CPLD */
+  { 0xf1000000, 0x40000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* CAN */
+  { 0xf4000000, 0x18000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA-1111 */
+  LAST_DESC
+};
+
+static void __init graphicsmaster_map_io(void)
+{
+	sa1100_map_io();
+	iotable_init(graphicsmaster_io_desc);
+
+	sa1100_register_uart(0, 3);
+	sa1100_register_uart(1, 1);
+	sa1100_register_uart(2, 2);
+}
+
+MACHINE_START(GRAPHICSMASTER, "ADS GraphicsMaster")
+	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+	FIXUP(fixup_graphicsmaster)
+	MAPIO(graphicsmaster_map_io)
+	INITIRQ(graphicsmaster_init_irq)
+MACHINE_END
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/h3600.c linux/arch/arm/mach-sa1100/h3600.c
--- v2.4.12/linux/arch/arm/mach-sa1100/h3600.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/mach-sa1100/h3600.c	Thu Oct 11 09:04:57 2001
@@ -0,0 +1,189 @@
+/*
+ * linux/arch/arm/mach-sa1100/h3600.c
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+#include <linux/sched.h>
+
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/setup.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+#include <linux/serial_core.h>
+
+#include "generic.h"
+
+
+/*
+ * Bitsy has extended, write-only memory-mapped GPIO's
+ */
+
+static int h3600_egpio = EGPIO_H3600_RS232_ON;
+
+void clr_h3600_egpio(unsigned long x)
+{
+	h3600_egpio &= ~x;
+	H3600_EGPIO = h3600_egpio;
+}
+
+void set_h3600_egpio(unsigned long x)
+{
+	h3600_egpio |= x;
+	H3600_EGPIO = h3600_egpio;
+}
+
+EXPORT_SYMBOL(clr_h3600_egpio);
+EXPORT_SYMBOL(set_h3600_egpio);
+
+
+/*
+ * Low-level UART features.
+ *
+ * Note that RTS, CTS and DCD are all active low.
+ */
+
+static void h3600_uart_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+	if (port->mapbase == _Ser3UTCR0) {
+		if (mctrl & TIOCM_RTS)
+			GPCR = GPIO_H3600_COM_RTS;
+		else
+			GPSR = GPIO_H3600_COM_RTS;
+	}
+}
+
+static int h3600_uart_get_mctrl(struct uart_port *port)
+{
+	int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
+
+	if (port->mapbase == _Ser3UTCR0) {
+		int gplr = GPLR;
+		if (gplr & GPIO_H3600_COM_DCD)
+			ret &= ~TIOCM_CD;
+		if (gplr & GPIO_H3600_COM_CTS)
+			ret &= ~TIOCM_CTS;
+	}
+
+	return ret;
+}
+
+static void h3600_dcd_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct uart_info *info = dev_id;
+	/* Note: should only call this if something has changed */
+	uart_handle_dcd_change(info, !(GPLR & GPIO_H3600_COM_DCD));
+}
+
+static void h3600_cts_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct uart_info *info = dev_id;
+	/* Note: should only call this if something has changed */
+	uart_handle_cts_change(info, !(GPLR & GPIO_H3600_COM_CTS));
+}
+
+static void h3600_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
+{
+	if (port->mapbase == _Ser2UTCR0) {
+		if (state == 0) {
+			set_h3600_egpio(EGPIO_H3600_IR_ON);
+		} else {
+			clr_h3600_egpio(EGPIO_H3600_IR_ON);
+		}
+	} else if (port->mapbase == _Ser3UTCR0) {
+		if (state == 0) {
+			set_h3600_egpio(EGPIO_H3600_RS232_ON);
+		} else {
+			clr_h3600_egpio(EGPIO_H3600_RS232_ON);
+		}
+	}
+}
+
+static int h3600_uart_open(struct uart_port *port, struct uart_info *info)
+{
+	int ret = 0;
+
+	if (port->mapbase == _Ser2UTCR0) {
+		Ser2UTCR4 = UTCR4_HSE;
+		Ser2HSCR0 = 0;
+		Ser2HSSR0 = HSSR0_EIF | HSSR0_TUR |
+			    HSSR0_RAB | HSSR0_FRE;
+	} else if (port->mapbase == _Ser3UTCR0) {
+		GPDR &= ~(GPIO_H3600_COM_DCD|GPIO_H3600_COM_CTS);
+		GPDR |= GPIO_H3600_COM_RTS;
+		set_GPIO_IRQ_edge(GPIO_H3600_COM_DCD|GPIO_H3600_COM_CTS,
+				  GPIO_BOTH_EDGES);
+
+		ret = request_irq(IRQ_GPIO_H3600_COM_DCD, h3600_dcd_intr,
+				  0, "RS232 DCD", info);
+		if (ret)
+			return ret;
+
+		ret = request_irq(IRQ_GPIO_H3600_COM_CTS, h3600_cts_intr,
+				  0, "RS232 CTS", info);
+		if (ret)
+			free_irq(IRQ_GPIO_H3600_COM_DCD, info);
+	}
+	return ret;
+}
+
+static void h3600_uart_close(struct uart_port *port, struct uart_info *info)
+{
+	if (port->mapbase == _Ser3UTCR0) {
+		free_irq(IRQ_GPIO_H3600_COM_DCD, info);
+		free_irq(IRQ_GPIO_H3600_COM_CTS, info);
+	}
+}
+
+static struct sa1100_port_fns h3600_port_fns __initdata = {
+	set_mctrl:	h3600_uart_set_mctrl,
+	get_mctrl:	h3600_uart_get_mctrl,
+	pm:		h3600_uart_pm,
+	open:		h3600_uart_open,
+	close:		h3600_uart_close,
+};
+
+static struct map_desc h3600_io_desc[] __initdata = {
+ /* virtual     physical    length      domain     r  w  c  b */
+  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
+  { 0xf0000000, 0x49000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* EGPIO 0 */
+  { 0xf1000000, 0x10000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* static memory bank 2 */
+  { 0xf3000000, 0x40000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* static memory bank 4 */
+  LAST_DESC
+};
+
+static void __init h3600_map_io(void)
+{
+	sa1100_map_io();
+	iotable_init(h3600_io_desc);
+
+	sa1100_register_uart_fns(&h3600_port_fns);
+	sa1100_register_uart(0, 3);
+	sa1100_register_uart(1, 1); /* isn't this one driven elsewhere? */
+	sa1100_register_uart(2, 2);
+
+	/*
+	 * Default GPIO settings.
+	 */
+	GPCR = 0x0fffffff;
+	GPDR = 0x0401f3fc;
+
+	/*
+	 * Ensure those pins are outputs and driving low.
+	 */
+	PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
+	PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+}
+
+MACHINE_START(H3600, "Compaq iPAQ")
+	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+	BOOT_PARAMS(0xc0000100)
+	MAPIO(h3600_map_io)
+	INITIRQ(sa1100_init_irq)
+MACHINE_END
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/jornada720.c linux/arch/arm/mach-sa1100/jornada720.c
--- v2.4.12/linux/arch/arm/mach-sa1100/jornada720.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/jornada720.c	Thu Oct 11 09:04:57 2001
@@ -46,7 +46,8 @@
 	PPDR |= PPC_LDD3 | PPC_LDD4;
 
 	/* initialize extra IRQs */
-	sa1111_init_irq(1);	/* chained on GPIO 1 */
+	set_GPIO_IRQ_edge(GPIO_GPIO(1), GPIO_RISING_EDGE);
+	sa1111_init_irq(SA1100_GPIO_TO_IRQ(1));	/* chained on GPIO 1 */
 
 	sa1100_register_uart(0, 3);
 	sa1100_register_uart(1, 1);
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/leds-graphicsmaster.c linux/arch/arm/mach-sa1100/leds-graphicsmaster.c
--- v2.4.12/linux/arch/arm/mach-sa1100/leds-graphicsmaster.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/mach-sa1100/leds-graphicsmaster.c	Thu Oct 11 09:04:57 2001
@@ -0,0 +1,104 @@
+/*
+ *  linux/arch/arm/mach-sa1100/leds-graphicsmaster.c
+ *
+ * GraphicsClient Plus LEDs support
+ * Woojung Huh, Feb 13, 2001
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include "leds.h"
+
+
+#define LED_STATE_ENABLED	1
+#define LED_STATE_CLAIMED	2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+#define LED_TIMER       ADS_LED0  /* green heartbeat */
+#define LED_USER        ADS_LED1  /* amber, boots to on */
+#define LED_IDLE        ADS_LED2  /* red has the idle led, if any */
+
+#define LED_MASK	(ADS_LED0|ADS_LED1|ADS_LED2)
+
+void graphicsmaster_leds_event(led_event_t evt)
+{
+	unsigned long flags;
+
+	save_flags_cli(flags);
+
+	switch (evt) {
+	case led_start:
+		hw_led_state = 0;        /* gc leds are positive logic */
+		led_state = LED_STATE_ENABLED;
+		break;
+
+	case led_stop:
+		led_state &= ~LED_STATE_ENABLED;
+		break;
+
+	case led_claim:
+		led_state |= LED_STATE_CLAIMED;
+		hw_led_state = LED_MASK;
+		break;
+
+	case led_release:
+		led_state &= ~LED_STATE_CLAIMED;
+		hw_led_state = LED_MASK;
+		break;
+
+#ifdef CONFIG_LEDS_TIMER
+	case led_timer:
+		if (!(led_state & LED_STATE_CLAIMED))
+			hw_led_state ^= LED_TIMER;
+		break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+	case led_idle_start:
+		if (!(led_state & LED_STATE_CLAIMED))
+			hw_led_state &= ~LED_IDLE;
+		break;
+
+	case led_idle_end:
+		if (!(led_state & LED_STATE_CLAIMED))
+			hw_led_state |= LED_IDLE;
+		break;
+#endif
+
+	case led_green_on:
+		break;
+
+	case led_green_off:
+		break;
+
+	case led_amber_on:
+		hw_led_state |= LED_USER;
+		break;
+
+	case led_amber_off:
+		hw_led_state &= ~LED_USER;
+		break;
+
+	case led_red_on:
+		break;
+
+	case led_red_off:
+		break;
+
+	default:
+		break;
+	}
+
+	if  (led_state & LED_STATE_ENABLED) {
+		GPSR = hw_led_state;
+		GPCR = hw_led_state ^ LED_MASK;
+	}
+
+	restore_flags(flags);
+}
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/leds.c linux/arch/arm/mach-sa1100/leds.c
--- v2.4.12/linux/arch/arm/mach-sa1100/leds.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/leds.c	Thu Oct 11 09:04:57 2001
@@ -30,6 +30,8 @@
 		leds_event = lart_leds_event;
 	if (machine_is_pfs168())
 		leds_event = pfs168_leds_event;
+	if (machine_is_graphicsmaster())
+		leds_event = graphicsmaster_leds_event;
 
 	leds_event(led_start);
 	return 0;
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/leds.h linux/arch/arm/mach-sa1100/leds.h
--- v2.4.12/linux/arch/arm/mach-sa1100/leds.h	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/leds.h	Thu Oct 11 09:04:57 2001
@@ -5,4 +5,4 @@
 extern void graphicsclient_leds_event(led_event_t evt);
 extern void lart_leds_event(led_event_t evt);
 extern void pfs168_leds_event(led_event_t evt);
-
+extern void graphicsmaster_leds_event(led_event_t evt);
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/neponset.c linux/arch/arm/mach-sa1100/neponset.c
--- v2.4.12/linux/arch/arm/mach-sa1100/neponset.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/neponset.c	Thu Oct 11 09:04:57 2001
@@ -74,36 +74,73 @@
 
 static int __init neponset_init(void)
 {
-	/* only on assabet */
+	int ret;
+
+	/*
+	 * The Neponset is only present on the Assabet machine type.
+	 */
 	if (!machine_is_assabet())
-		return 0;
+		return -ENODEV;
+
+	/*
+	 * Ensure that the memory bus request/grant signals are setup,
+	 * and the grant is held in its inactive state, whether or not
+	 * we actually have a Neponset attached.
+	 */
+	sa1110_mb_disable();
+
+	if (!machine_has_neponset()) {
+		printk(KERN_DEBUG "Neponset expansion board not present\n");
+		return -ENODEV;
+	}
+
+	if (WHOAMI != 0x11) {
+		printk(KERN_WARNING "Neponset board detected, but "
+			"wrong ID: %02x\n", WHOAMI);
+		return -ENODEV;
+	}
+
+	/*
+	 * Neponset has SA1111 connected to CS4.  We know that after
+	 * reset the chip will be configured for variable latency IO.
+	 */
+	/* FIXME: setup MSC2 */
+
+	/*
+	 * Probe for a SA1111.
+	 */
+	ret = sa1111_probe();
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * We found it.  Wake the chip up.
+	 */
+	sa1111_wake();
+
+	/*
+	 * The SDRAM configuration of the SA1110 and the SA1111 must
+	 * match.  This is very important to ensure that SA1111 accesses
+	 * don't corrupt the SDRAM.  Note that this ungates the SA1111's
+	 * MBGNT signal, so we must have called sa1110_mb_disable()
+	 * beforehand.
+	 */
+	sa1111_configure_smc(1,
+			     FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
+			     FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
+
+	/*
+	 * We only need to turn on DCLK whenever we want to use the
+	 * DMA.  It can otherwise be held firmly in the off position.
+	 */
+	SKPCR |= SKPCR_DCLKEN;
 
-	if (machine_has_neponset()) {
-		LEDS = WHOAMI;
+	/*
+	 * Enable the SA1110 memory bus request and grant signals.
+	 */
+	sa1110_mb_enable();
 
-		if (sa1111_init() < 0)
-			return -EINVAL;
-		/*
-		 * Assabet is populated by default with two Samsung
-		 * KM416S8030T-G8
-		 * 128Mb SDRAMs, which are organized as 12-bit (row addr) x
-		 * 9-bit
-		 * (column addr), according to the data sheet. Apparently, the
-		 * bank selects factor into the row address, as Angel sets up
-		 * the
-		 * SA-1110 to use 14x9 addresses. The SDRAM datasheet specifies
-		 * that when running at 100-125MHz, the CAS latency for -8
-		 * parts
-		 * is 3 cycles, which is consistent with Angel.
-		 */
-		SMCR = (SMCR_DTIM | SMCR_MBGE |
-			FInsrt(FExtr(MDCNFG, MDCNFG_SA1110_DRAC0), SMCR_DRAC) |
-			((FExtr(MDCNFG, MDCNFG_SA1110_TDL0)==3) ? SMCR_CLAT : 0));
-		SKPCR |= SKPCR_DCLKEN;
-
-		neponset_init_irq();
-	} else
-		printk("Neponset expansion board not present\n");
+	neponset_init_irq();
 
 	return 0;
 }
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/pangolin.c linux/arch/arm/mach-sa1100/pangolin.c
--- v2.4.12/linux/arch/arm/mach-sa1100/pangolin.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/pangolin.c	Thu Oct 11 09:04:57 2001
@@ -20,7 +20,7 @@
 fixup_pangolin(struct machine_desc *desc, struct param_struct *params,
 	       char **cmdline, struct meminfo *mi)
 {
-	SET_BANK( 0, 0xc0000000, 64*1024*1024 );
+	SET_BANK( 0, 0xc0000000, 128*1024*1024 );
 	mi->nr_banks = 1;
 
 	ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/pfs168.c linux/arch/arm/mach-sa1100/pfs168.c
--- v2.4.12/linux/arch/arm/mach-sa1100/pfs168.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/pfs168.c	Thu Oct 11 09:04:57 2001
@@ -20,14 +20,53 @@
 
 static int __init pfs168_init(void)
 {
-	if (sa1111_init() < 0)
-		return -EINVAL;
-	SMCR = (SMCR_DTIM | SMCR_MBGE |
-		FInsrt(FExtr(MDCNFG, MDCNFG_SA1110_DRAC0), SMCR_DRAC) |
-		((FExtr(MDCNFG, MDCNFG_SA1110_TDL0)==3) ? SMCR_CLAT : 0));
+	int ret;
+
+	if (!machine_is_pfs168())
+		return -ENODEV;
+
+	/*
+	 * Ensure that the memory bus request/grant signals are setup,
+	 * and the grant is held in its inactive state
+	 */
+	sa1110_mb_disable();
+
+	/*
+	 * Probe for SA1111.
+	 */
+	ret = sa1111_probe();
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * We found it.  Wake the chip up.
+	 */
+	sa1111_wake();
+
+	/*
+	 * The SDRAM configuration of the SA1110 and the SA1111 must
+	 * match.  This is very important to ensure that SA1111 accesses
+	 * don't corrupt the SDRAM.  Note that this ungates the SA1111's
+	 * MBGNT signal, so we must have called sa1110_mb_disable()
+	 * beforehand.
+	 */
+	sa1111_configure_smc(1,
+			     FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
+			     FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
+
+	/*
+	 * We only need to turn on DCLK whenever we want to use the
+	 * DMA.  It can otherwise be held firmly in the off position.
+	 */
 	SKPCR |= SKPCR_DCLKEN;
 
-	sa1111_init_irq(25);	/* SA1111 IRQ on GPIO 25 */
+	/*
+	 * Enable the SA1110 memory bus request and grant signals.
+	 */
+	sa1110_mb_enable();
+
+	set_GPIO_IRQ_edge(GPIO_GPIO(25), GPIO_RISING_EDGE);
+	sa1111_init_irq(SA1100_GPIO_TO_IRQ(25));	/* SA1111 IRQ on GPIO 25 */
 
 	return 0;
 }
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/sa1111-pcibuf.c linux/arch/arm/mach-sa1100/sa1111-pcibuf.c
--- v2.4.12/linux/arch/arm/mach-sa1100/sa1111-pcibuf.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/sa1111-pcibuf.c	Thu Oct 11 09:04:57 2001
@@ -13,7 +13,6 @@
  *
  *  06/13/2001 - created.
  */
-
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -64,13 +63,6 @@
 	return 0;
 }
 
-static void
-free_safe_buffers(void)
-{
-	pci_pool_destroy(small_buffer_cache);
-	pci_pool_destroy(large_buffer_cache);
-}
-
 /* allocate a 'safe' buffer and keep track of it */
 static char *
 alloc_safe_buffer(char *unsafe, int size, dma_addr_t *pbus)
@@ -183,17 +175,11 @@
  * we assume calls to map_single are symmetric with calls to unmap_single...
  */
 dma_addr_t
-pci_map_single(struct pci_dev *hwdev, void *virtptr,
+sa1111_map_single(struct pci_dev *hwdev, void *virtptr,
 	       size_t size, int direction)
 {
 	dma_addr_t busptr;
 
-	/* hack; usb-ohci.c never sends hwdev==NULL, all others do */
-	if (hwdev == NULL) {
-		consistent_sync(virtptr, size, direction);
-		return virt_to_bus(virtptr);
-	}
-
 	mapped_alloc_size += size;
 
 	if (0) printk("pci_map_single(hwdev=%p,ptr=%p,size=%d,dir=%x) "
@@ -235,7 +221,7 @@
  * (basically return things back to the way they should be)
  */
 void
-pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
+sa1111_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
 		 size_t size, int direction)
 {
 	char *safe, *unsafe;
@@ -267,13 +253,21 @@
 	}
 }
 
-EXPORT_SYMBOL(pci_map_single);
-EXPORT_SYMBOL(pci_unmap_single);
+EXPORT_SYMBOL(sa1111_map_single);
+EXPORT_SYMBOL(sa1111_unmap_single);
 
-static void __init sa1111_init_safe_buffers(void)
+static int __init sa1111_init_safe_buffers(void)
 {
 	printk("Initializing SA1111 buffer pool for DMA workaround\n");
 	init_safe_buffers(NULL);
+	return 0;
+}
+
+static void free_safe_buffers(void)
+{
+	pci_pool_destroy(small_buffer_cache);
+	pci_pool_destroy(large_buffer_cache);
 }
 
-__initcall(sa1111_init_safe_buffers);
+module_init(sa1111_init_safe_buffers);
+module_exit(free_safe_buffers);
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/sa1111.c linux/arch/arm/mach-sa1100/sa1111.c
--- v2.4.12/linux/arch/arm/mach-sa1100/sa1111.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/sa1111.c	Thu Oct 11 09:04:57 2001
@@ -15,7 +15,6 @@
  * All initialization functions provided here are intended to be called
  * from machine specific code with proper arguments when required.
  */
-
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
@@ -23,8 +22,6 @@
 #include <linux/interrupt.h>
 #include <linux/ptrace.h>
 #include <linux/errno.h>
-#include <linux/pci.h>
-#include <linux/mm.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
@@ -33,64 +30,6 @@
 
 #include "sa1111.h"
 
-static int sa1111_ohci_hcd_init(void);
-
-/*
- * SA1111 initialization
- */
-
-int __init sa1111_init(void)
-{
-	unsigned long id = SKID;
-
-	if((id & SKID_ID_MASK) == SKID_SA1111_ID)
-		printk( KERN_INFO "SA-1111 Microprocessor Companion Chip: "
-			"silicon revision %lx, metal revision %lx\n",
-			(id & SKID_SIREV_MASK)>>4, (id & SKID_MTREV_MASK));
-	else {
-		printk(KERN_ERR "Could not detect SA-1111!\n");
-		return -EINVAL;
-	}
-
-	/*
-	 * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
-	 * (SA-1110 Developer's Manual, section 9.1.2.1)
-	 */
-	GAFR |= GPIO_32_768kHz;
-	GPDR |= GPIO_32_768kHz;
-	TUCR = TUCR_3_6864MHz;
-
-	/* Now, set up the PLL and RCLK in the SA-1111: */
-	SKCR = SKCR_PLL_BYPASS | SKCR_RDYEN | SKCR_OE_EN;
-	udelay(100);
-	SKCR = SKCR_PLL_BYPASS | SKCR_RCLKEN | SKCR_RDYEN | SKCR_OE_EN;
-
-	/*
-	 * SA-1111 Register Access Bus should now be available. Clocks for
-	 * any other SA-1111 functional blocks must be enabled separately
-	 * using the SKPCR.
-	 */
-
-	/*
-	 * If the system is going to use the SA-1111 DMA engines, set up
-	 * the memory bus request/grant pins. Also configure the shared
-	 * memory controller on the SA-1111 (SA-1111 Developer's Manual,
-	 * section 3.2.3) and power up the DMA bus clock:
-	 */
-	GAFR |= (GPIO_MBGNT | GPIO_MBREQ);
-	GPDR |= GPIO_MBGNT;
-	GPDR &= ~GPIO_MBREQ;
-	TUCR |= TUCR_MR;
-
-#ifdef CONFIG_USB_OHCI
-	/* setup up sa1111 usb host controller h/w */
-	sa1111_ohci_hcd_init();
-#endif
-
-	return 0;
-}
-
-
 /*
  * SA1111  Interrupt support
  */
@@ -159,7 +98,7 @@
 	INTEN1 |= 1 << ((irq - SA1111_IRQ(32)));
 }
 
-void __init sa1111_init_irq(int gpio_nr)
+void __init sa1111_init_irq(int irq_nr)
 {
 	int irq;
 
@@ -181,144 +120,146 @@
 
 	for (irq = SA1111_IRQ(0); irq <= SA1111_IRQ(26); irq++) {
 		irq_desc[irq].valid	= 1;
-		irq_desc[irq].probe_ok	= 1;
+		irq_desc[irq].probe_ok	= 0;
 		irq_desc[irq].mask_ack	= sa1111_mask_and_ack_lowirq;
 		irq_desc[irq].mask	= sa1111_mask_lowirq;
 		irq_desc[irq].unmask	= sa1111_unmask_lowirq;
 	}
 	for (irq = SA1111_IRQ(32); irq <= SA1111_IRQ(54); irq++) {
 		irq_desc[irq].valid	= 1;
-		irq_desc[irq].probe_ok	= 1;
+		irq_desc[irq].probe_ok	= 0;
 		irq_desc[irq].mask_ack	= sa1111_mask_and_ack_highirq;
 		irq_desc[irq].mask	= sa1111_mask_highirq;
 		irq_desc[irq].unmask	= sa1111_unmask_highirq;
 	}
 
-	/* Not every machines has the SA1111 interrupt routed to a GPIO */
-	if (gpio_nr >= 0) {
-		set_GPIO_IRQ_edge (GPIO_GPIO(gpio_nr), GPIO_RISING_EDGE);
-		setup_arm_irq (SA1100_GPIO_TO_IRQ(gpio_nr), &sa1111_irq);
-	}
+	/* Register SA1111 interrupt */
+	if (irq_nr >= 0)
+		setup_arm_irq(irq_nr, &sa1111_irq);
 }
 
-/* ----------------- */
-
-#ifdef CONFIG_USB_OHCI
-
-#if defined(CONFIG_SA1100_XP860) || defined(CONFIG_ASSABET_NEPONSET) || defined(CONFIG_SA1100_PFS168)
-#define PwrSensePolLow  1
-#define PwrCtrlPolLow   1
-#else
-#define PwrSensePolLow  0
-#define PwrCtrlPolLow   0
-#endif
-
 /*
- * The SA-1111 errata says that the DMA hardware needs to be exercised
- * before the clocks are turned on to work properly.  This code does
- * a tiny dma transfer to prime to hardware.
+ * Probe for a SA1111 chip.
  */
-static void __init sa1111_dma_setup(void)
+
+int __init sa1111_probe(void)
 {
-	dma_addr_t vbuf;
-	void * pbuf;
+	unsigned long id = SBI_SKID;
+	int ret = -ENODEV;
 
-	/* DMA init & setup */
+	if ((id & SKID_ID_MASK) == SKID_SA1111_ID) {
+		printk(KERN_INFO "SA-1111 Microprocessor Companion Chip: "
+			"silicon revision %lx, metal revision %lx\n",
+			(id & SKID_SIREV_MASK)>>4, (id & SKID_MTREV_MASK));
+		ret = 0;
+	} else {
+		printk(KERN_DEBUG "SA-1111 not detected: ID = %08lx\n", id);
+	}
 
-	/* WARNING: The SA-1111 L3 function is used as part of this
-	 * SA-1111 DMA errata workaround.
-	 *
-	 * N.B., When the L3 function is enabled, it uses GPIO_B<4:5>
-	 * and takes precedence over the PS/2 mouse and GPIO_B
-	 * functions. Refer to "Intel StrongARM SA-1111 Microprocessor
-	 * Companion Chip, Sect 10.2" for details.  So this "fix" may
-	 * "break" support of either PS/2 mouse or GPIO_B if
-	 * precautions are not taken to avoid collisions in
-	 * configuration and use of these pins. AFAIK, no precautions
-	 * are taken at this time. So it is likely that the action
-	 * taken here may cause problems in PS/2 mouse and/or GPIO_B
-	 * pin use elsewhere.
-	 *
-	 * But wait, there's more... What we're doing here is
-	 * obviously altogether a bad idea. We're indiscrimanately bit
-	 * flipping config for a few different functions here which
-	 * are "owned" by other drivers. This needs to be handled
-	 * better than it is being done here at this time.  */
-
-	/* prime the dma engine with a tiny dma */
-	SKPCR |= SKPCR_I2SCLKEN;
-	SKAUD |= SKPCR_L3CLKEN | SKPCR_SCLKEN;
-
-	SACR0 |= 0x00003305;
-	SACR1 = 0x00000000;
-
-	/* we need memory below 1mb */
-	pbuf = consistent_alloc(GFP_KERNEL | GFP_DMA, 4, &vbuf);
+	return ret;
+}
 
-	SADTSA = (unsigned long)pbuf;
-	SADTCA = 4;
+/*
+ * Bring the SA1111 out of reset.  This requires a set procedure:
+ *  1. nRESET asserted (by hardware)
+ *  2. CLK turned on from SA1110
+ *  3. nRESET deasserted
+ *  4. VCO turned on, PLL_BYPASS turned off
+ *  5. Wait lock time, then assert RCLKEn
+ *  7. PCR set to allow clocking of individual functions
+ *
+ * Until we've done this, the only registers we can access are:
+ *   SBI_SKCR
+ *   SBI_SMCR
+ *   SBI_SKID
+ */
+void sa1111_wake(void)
+{
+	/*
+	 * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
+	 * (SA-1110 Developer's Manual, section 9.1.2.1)
+	 */
+	GAFR |= GPIO_32_768kHz;
+	GPDR |= GPIO_32_768kHz;
+	TUCR = TUCR_3_6864MHz;
 
-	SADTCS |= 0x00000011;
-	SKPCR |= SKPCR_DCLKEN;
+	/*
+	 * Turn VCO on, and disable PLL Bypass.
+	 */
+	SBI_SKCR &= ~SKCR_VCO_OFF;
+	SBI_SKCR |= SKCR_PLL_BYPASS | SKCR_OE_EN;
 
-	/* wait */
+	/*
+	 * Wait lock time.  SA1111 manual _doesn't_
+	 * specify a figure for this!  We choose 100us.
+	 */
 	udelay(100);
 
-	SACR0 &= ~(0x00000002);
-	SACR0 &= ~(0x00000001);
-
-	/* */
-	SACR0 |= 0x00000004;
-	SACR0 &= ~(0x00000004);
+	/*
+	 * Enable RCLK.  We also ensure that RDYEN is set.
+	 */
+	SBI_SKCR |= SKCR_RCLKEN | SKCR_RDYEN;
 
-	SKAUD &= ~(SKPCR_L3CLKEN | SKPCR_SCLKEN);
+	/*
+	 * Wait 14 RCLK cycles for the chip to finish coming out
+	 * of reset. (RCLK=24MHz).  This is 590ns.
+	 */
+	udelay(1);
 
-	SKPCR &= ~SKPCR_I2SCLKEN;
+	/*
+	 * Ensure all clocks are initially off.
+	 */
+	SKPCR = 0;
+}
 
-	consistent_free(pbuf, 4, vbuf);
+void sa1111_doze(void)
+{
+	if (SKPCR & SKPCR_UCLKEN) {
+		printk("SA1111 doze mode refused\n");
+		return;
+	}
+	SBI_SKCR &= ~SKCR_RCLKEN;
 }
 
-#ifdef CONFIG_USB_OHCI
 /*
- * reset the SA-1111 usb controller and turn on it's clocks
+ * Configure the SA1111 shared memory controller.
  */
-static int __init sa1111_ohci_hcd_init(void)
+void sa1111_configure_smc(int sdram, unsigned int drac, unsigned int cas_latency)
 {
-	volatile unsigned long *Reset = (void *)SA1111_p2v(_SA1111(0x051c));
-	volatile unsigned long *Status = (void *)SA1111_p2v(_SA1111(0x0518));
-
-	/* turn on clocks */
-	SKPCR |= SKPCR_UCLKEN;
-	udelay(100);
-
-	/* force a reset */
-	*Reset = 0x01;
-	*Reset |= 0x02;
-	udelay(100);
+	unsigned int smcr = SMCR_DTIM | SMCR_MBGE | FInsrt(drac, SMCR_DRAC);
 
-	*Reset = 0;
+	if (cas_latency == 3)
+		smcr |= SMCR_CLAT;
 
-	/* take out of reset */
-	/* set power sense and control lines (this from the diags code) */
-        *Reset = ( PwrSensePolLow << 6 )
-               | ( PwrCtrlPolLow << 7 );
-
-	*Status = 0;
+	SBI_SMCR = smcr;
+}
 
-	udelay(10);
+/*
+ * Disable the memory bus request/grant signals on the SA1110 to
+ * ensure that we don't receive spurious memory requests.  We set
+ * the MBGNT signal false to ensure the SA1111 doesn't own the
+ * SDRAM bus.
+ */
+void __init sa1110_mb_disable(void)
+{
+	PGSR &= ~GPIO_MBGNT;
+	GPCR = GPIO_MBGNT;
+	GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT;
 
-	/* compensate for dma bug */
-	sa1111_dma_setup();
+	GAFR &= ~(GPIO_MBGNT | GPIO_MBREQ);
 
-	return 0;
 }
 
-void sa1111_ohci_hcd_cleanup(void)
+/*
+ * If the system is going to use the SA-1111 DMA engines, set up
+ * the memory bus request/grant pins.
+ */
+void __init sa1110_mb_enable(void)
 {
-	/* turn the USB clock off */
-	SKPCR &= ~SKPCR_UCLKEN;
-}
-#endif
-
+	PGSR &= ~GPIO_MBGNT;
+	GPCR = GPIO_MBGNT;
+	GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT;
 
-#endif /* CONFIG_USB_OHCI */
+	GAFR |= (GPIO_MBGNT | GPIO_MBREQ);
+	TUCR |= TUCR_MR;
+}
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/sa1111.h linux/arch/arm/mach-sa1100/sa1111.h
--- v2.4.12/linux/arch/arm/mach-sa1100/sa1111.h	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/sa1111.h	Thu Oct 11 09:04:57 2001
@@ -2,7 +2,33 @@
  * linux/arch/arm/mach-sa1100/sa1111.h
  */
 
-extern int __init sa1111_init(void);
-extern void __init sa1111_init_irq(int gpio_nr);
+/*
+ * These two don't really belong in here.
+ */
+extern void sa1110_mb_enable(void);
+extern void sa1110_mb_disable(void);
+
+/*
+ * Probe for a SA1111 chip.
+ */
+extern int sa1111_probe(void);
+
+/*
+ * Wake up a SA1111 chip.
+ */
+extern void sa1111_wake(void);
+
+/*
+ * Doze the SA1111 chip.
+ */
+extern void sa1111_doze(void);
+
+/*
+ * Configure the SA1111 shared memory controller.
+ */
+extern void sa1111_configure_smc(int sdram, unsigned int drac, unsigned int cas_latency);
+
+
+extern void sa1111_init_irq(int irq_nr);
 extern void sa1111_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs );
 
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/xp860.c linux/arch/arm/mach-sa1100/xp860.c
--- v2.4.12/linux/arch/arm/mach-sa1100/xp860.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/xp860.c	Thu Oct 11 09:04:57 2001
@@ -28,10 +28,27 @@
 	while(1);
 }
 
+/*
+ * Note: I replaced the sa1111_init() without the full SA1111 initialisation
+ * because this machine doesn't appear to use the DMA features.  If this is
+ * wrong, please look at neponset.c to fix it properly.
+ */
 static int __init xp860_init(void)
 {
 	pm_power_off = xp860_power_off;
-	sa1111_init();
+
+	/*
+	 * Probe for SA1111.
+	 */
+	ret = sa1111_probe();
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * We found it.  Wake the chip up.
+	 */
+	sa1111_wake();
+
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mm/extable.c linux/arch/arm/mm/extable.c
--- v2.4.12/linux/arch/arm/mm/extable.c	Mon Sep 18 15:15:25 2000
+++ linux/arch/arm/mm/extable.c	Thu Oct 11 09:04:57 2001
@@ -30,6 +30,8 @@
         return 0;
 }
 
+extern spinlock_t modlist_lock;
+
 unsigned long
 search_exception_table(unsigned long addr)
 {
@@ -38,18 +40,24 @@
 #ifndef CONFIG_MODULES
 	/* There is only the kernel to search.  */
 	ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
-	if (ret) return ret;
 #else
 	/* The kernel is the last "module" -- no need to treat it special.  */
+	unsigned long flags;
 	struct module *mp;
+
+	ret = 0;
+	spin_lock_irqsave(&modlist_lock, flags);
 	for (mp = module_list; mp != NULL; mp = mp->next) {
-		if (mp->ex_table_start == NULL)
+		if (mp->ex_table_start == NULL ||
+		    !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING)))
 			continue;
 		ret = search_one_table(mp->ex_table_start,
 				       mp->ex_table_end - 1, addr);
-		if (ret) return ret;
+		if (ret)
+			break;
 	}
+	spin_unlock_irqrestore(&modlist_lock, flags);
 #endif
 
-	return 0;
+	return ret;
 }
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mm/fault-armv.c linux/arch/arm/mm/fault-armv.c
--- v2.4.12/linux/arch/arm/mm/fault-armv.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/arm/mm/fault-armv.c	Thu Oct 11 09:04:57 2001
@@ -599,10 +599,10 @@
 	if (!inf->fn(addr, error_code, regs))
 		return;
 bad:
-	force_sig(inf->sig, current);
 	printk(KERN_ALERT "Unhandled fault: %s (%X) at 0x%08lx\n",
 		inf->name, fsr, addr);
 	show_pte(current->mm, addr);
+	force_sig(inf->sig, current);
 	die_if_kernel("Oops", regs, 0);
 	return;
 
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mm/fault-common.c linux/arch/arm/mm/fault-common.c
--- v2.4.12/linux/arch/arm/mm/fault-common.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mm/fault-common.c	Thu Oct 11 09:04:57 2001
@@ -301,6 +301,10 @@
 	tsk->thread.error_code = error_code;
 	tsk->thread.trap_no = 14;
 	force_sig(SIGBUS, tsk);
+#ifdef CONFIG_DEBUG_USER
+	printk(KERN_DEBUG "%s: sigbus at 0x%08lx, pc=0x%08lx\n",
+		current->comm, addr, instruction_pointer(regs));
+#endif
 
 	/* Kernel mode? Handle exceptions or die */
 	if (user_mode(regs))
@@ -339,13 +343,10 @@
 	if (addr < TASK_SIZE)
 		return do_page_fault(addr, error_code, regs);
 
-	tsk = current;
-	mm  = tsk->active_mm;
-
 	offset = __pgd_offset(addr);
 
+	pgd = cpu_get_pgd() + offset;
 	pgd_k = init_mm.pgd + offset;
-	pgd   = mm->pgd + offset;
 
 	if (pgd_none(*pgd_k))
 		goto bad_area;
@@ -365,6 +366,9 @@
 	return 0;
 
 bad_area:
+	tsk = current;
+	mm  = tsk->active_mm;
+
 	do_bad_area(tsk, mm, addr, error_code, regs);
 	return 0;
 }
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mm/init.c linux/arch/arm/mm/init.c
--- v2.4.12/linux/arch/arm/mm/init.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mm/init.c	Thu Oct 11 09:04:57 2001
@@ -96,10 +96,22 @@
 }
 #endif
 
+/* This is currently broken
+ * PG_skip is used on sparc/sparc64 architectures to "skip" certain
+ * parts of the address space.
+ *
+ * #define PG_skip	10
+ * #define PageSkip(page) (machine_is_riscpc() && test_bit(PG_skip, &(page)->flags))
+ *			if (PageSkip(page)) {
+ *				page = page->next_hash;
+ *				if (page == NULL)
+ *					break;
+ *			}
+ */
 void show_mem(void)
 {
 	int free = 0, total = 0, reserved = 0;
-	int shared = 0, cached = 0, node;
+	int shared = 0, cached = 0, slab = 0, node;
 
 	printk("Mem-info:\n");
 	show_free_areas();
@@ -112,23 +124,13 @@
 		end  = page + NODE_DATA(node)->node_size;
 
 		do {
-/* This is currently broken
- * PG_skip is used on sparc/sparc64 architectures to "skip" certain
- * parts of the address space.
- *
- * #define PG_skip	10
- * #define PageSkip(page) (machine_is_riscpc() && test_bit(PG_skip, &(page)->flags))
- *			if (PageSkip(page)) {
- *				page = page->next_hash;
- *				if (page == NULL)
- *					break;
- *			}
- */
 			total++;
 			if (PageReserved(page))
 				reserved++;
 			else if (PageSwapCache(page))
 				cached++;
+			else if (PageSlab(page))
+				slab++;
 			else if (!page_count(page))
 				free++;
 			else
@@ -140,6 +142,7 @@
 	printk("%d pages of RAM\n", total);
 	printk("%d free pages\n", free);
 	printk("%d reserved pages\n", reserved);
+	printk("%d slab pages\n", slab);
 	printk("%d pages shared\n", shared);
 	printk("%d pages swap cached\n", cached);
 #ifndef CONFIG_NO_PGT_CACHE
@@ -375,6 +378,8 @@
 	 */
 	if (machine_is_archimedes() || machine_is_a5k())
 		reserve_bootmem_node(pgdat, 0x02000000, 0x00080000);
+	if (machine_is_edb7211())
+		reserve_bootmem_node(pgdat, 0xc0000000, 0x00020000);
 	if (machine_is_p720t())
 		reserve_bootmem_node(pgdat, PHYS_OFFSET, 0x00014000);
 #ifdef CONFIG_SA1111
@@ -471,6 +476,7 @@
 
 	if (map_pg != bootmap_pfn + bootmap_pages)
 		BUG();
+
 }
 
 /*
@@ -528,6 +534,12 @@
 				(bdata->node_boot_start >> PAGE_SHIFT);
 
 		/*
+		 * If this zone has zero size, skip it.
+		 */
+		if (!zone_size[0])
+			continue;
+
+		/*
 		 * For each bank in this node, calculate the size of the
 		 * holes.  holes = node_size - sum(bank_sizes_in_node)
 		 */
@@ -598,8 +610,12 @@
 		create_memmap_holes(&meminfo);
 
 	/* this will put all unused low memory onto the freelists */
-	for (node = 0; node < numnodes; node++)
-		totalram_pages += free_all_bootmem_node(NODE_DATA(node));
+	for (node = 0; node < numnodes; node++) {
+		pg_data_t *pgdat = NODE_DATA(node);
+
+		if (pgdat->node_size != 0)
+			totalram_pages += free_all_bootmem_node(pgdat);
+	}
 
 #ifdef CONFIG_SA1111
 	/* now that our DMA memory is actually so designated, we can free it */
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mm/mm-ftvpci.c linux/arch/arm/mm/mm-ftvpci.c
--- v2.4.12/linux/arch/arm/mm/mm-ftvpci.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/mm/mm-ftvpci.c	Thu Oct 11 09:04:57 2001
@@ -0,0 +1,32 @@
+/*
+ *  linux/arch/arm/mm/mm-nexuspci.c
+ *   from linux/arch/arm/mm/mm-ebsa110.c
+ *
+ *  Copyright (C) 1998-1999 Phil Blundell
+ *  Copyright (C) 1998-1999 Russell King
+ *
+ *  Extra MM routines for the FTV/PCI architecture
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+ 
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/io.h>
+
+#include <asm/mach/map.h>
+
+static struct map_desc nexuspci_io_desc[] __initdata = {
+ 	{ INTCONT_BASE,	INTCONT_START,	0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+ 	{ PLX_BASE,	PLX_START,	0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+ 	{ PCIO_BASE,	PLX_IO_START,	0x00100000, DOMAIN_IO, 0, 1, 0, 0 },
+ 	{ DUART_BASE,	DUART_START,	0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+	{ STATUS_BASE,	STATUS_START,	0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+	LAST_DESC
+};
+
+void __init nexuspci_map_io(void)
+{
+	iotable_init(nexuspci_io_desc);
+}
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mm/mm-nexuspci.c linux/arch/arm/mm/mm-nexuspci.c
--- v2.4.12/linux/arch/arm/mm/mm-nexuspci.c	Mon Sep 18 15:15:25 2000
+++ linux/arch/arm/mm/mm-nexuspci.c	Wed Dec 31 16:00:00 1969
@@ -1,32 +0,0 @@
-/*
- *  linux/arch/arm/mm/mm-nexuspci.c
- *   from linux/arch/arm/mm/mm-ebsa110.c
- *
- *  Copyright (C) 1998-1999 Phil Blundell
- *  Copyright (C) 1998-1999 Russell King
- *
- *  Extra MM routines for the FTV/PCI architecture
- */
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/init.h>
- 
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/io.h>
-
-#include <asm/mach/map.h>
-
-static struct map_desc nexuspci_io_desc[] __initdata = {
- 	{ INTCONT_BASE,	INTCONT_START,	0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
- 	{ PLX_BASE,	PLX_START,	0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
- 	{ PCIO_BASE,	PLX_IO_START,	0x00100000, DOMAIN_IO, 0, 1, 0, 0 },
- 	{ DUART_BASE,	DUART_START,	0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
-	{ STATUS_BASE,	STATUS_START,	0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
-	LAST_DESC
-};
-
-void __init nexuspci_map_io(void)
-{
-	iotable_init(nexuspci_io_desc);
-}
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mm/proc-arm720.S linux/arch/arm/mm/proc-arm720.S
--- v2.4.12/linux/arch/arm/mm/proc-arm720.S	Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mm/proc-arm720.S	Thu Oct 11 09:04:57 2001
@@ -108,6 +108,7 @@
  * Function: arm720_data_abort ()
  *
  * Params  : r0 = address of aborted instruction
+ *         : r3 = saved SPSR
  *
  * Purpose : obtain information about current aborted instruction
  *
@@ -143,6 +144,8 @@
 		mov	pc, lr
 
 ENTRY(cpu_arm720_data_abort)
+		tst	r3, #T_BIT
+		bne	.data_thumb_abort
 		ldr	r4, [r0]			@ read instruction causing problem
 		tst	r4, r4, lsr #21			@ C = bit 20
 		sbc	r1, r1, r1			@ r1 = C - 1
@@ -169,7 +172,7 @@
 Ldata_unknown:	@ Part of jumptable
 		mov	r0, r2
 		mov	r1, r4
-		mov	r2, r3
+		mov	r2, sp
 		bl	baddataabort
 		b	ret_from_exception
 
@@ -255,6 +258,77 @@
 		addeq	r7, r0, r2
 		b	Ldata_saver7
 
+.data_thumb_abort:
+		ldrh	r4, [r0]			@ read instruction
+		tst	r4, r4, lsr #12			@ C = bit 11
+		sbc	r1, r1, r1			@ r1 = C - 1
+		and	r2, r4, #15 << 12
+		add	pc, pc, r2, lsr #10		@ lookup in table
+		nop
+
+/* 0 */		b	Ldata_unknown
+/* 1 */		b	Ldata_unknown
+/* 2 */		b	Ldata_unknown
+/* 3 */		b	Ldata_unknown
+/* 4 */		b	Ldata_unknown
+/* 5 */		b	.data_thumb_reg
+/* 6 */		b	Ldata_simple
+/* 7 */		b	Ldata_simple
+/* 8 */		b	Ldata_simple
+/* 9 */		b	Ldata_simple
+/* A */		b	Ldata_unknown
+/* B */		b	.data_thumb_pushpop
+/* C */		b	.data_thumb_ldmstm
+/* D */		b	Ldata_unknown
+/* E */		b	Ldata_unknown
+/* F */		b	Ldata_unknown
+
+.data_thumb_reg:
+		tst	r4, #1 << 9
+		beq	Ldata_simple
+		tst	r4, #1 << 10		@ If 'S' (signed) bit is set
+		movne	r1, #0			@ it must be a load instr
+		b	Ldata_simple
+
+.data_thumb_pushpop:
+		tst	r4, #1 << 10
+		beq	Ldata_unknown
+		mov	r7, #0x11
+		and	r0, r4, r7
+		and	r2, r4, r7, lsl #1
+		add	r0, r0, r2, lsr #1
+		and	r2, r4, r7, lsl #2
+		add	r0, r0, r2, lsr #2
+		and	r2, r4, r7, lsl #3
+		add	r0, r0, r2, lsr #3
+		add	r0, r0, r0, lsr #4
+		and	r2, r4, #0x0100			@ catch 'R' bit for push/pop
+		add	r0, r0, r2, lsr #8
+		and	r0, r0, #15			@ number of regs to transfer
+		ldr	r7, [sp, #13 << 2]
+		tst	r4, #1 << 11
+		addne	r7, r7, r0, lsl #2		@ increment SP if PUSH
+		subeq	r7, r7, r0, lsr #2		@ decrement SP if POP
+		str	r7, [sp, #13 << 2]
+		b	Ldata_simple
+
+.data_thumb_ldmstm:
+		mov	r7, #0x11
+		and	r0, r4, r7
+		and	r2, r4, r7, lsl #1
+		add	r0, r0, r2, lsr #1
+		and	r2, r4, r7, lsl #2
+		add	r0, r0, r2, lsr #2
+		and	r2, r4, r7, lsl #3
+		add	r0, r0, r2, lsr #3
+		add	r0, r0, r0, lsr #4
+		and	r0, r0, #15			@ number of regs to transfer
+		and	r5, r4, #7 << 8
+		ldr	r7, [sp, r5, lsr #6]
+		sub	r7, r7, r0, lsr #2		@ always decrement
+		str	r7, [sp, r5, lsr #6]
+		b	Ldata_simple
+
 /*
  * Function: arm720_check_bugs (void)
  *	   : arm720_proc_init (void)
@@ -437,7 +511,7 @@
 		.align
 
 /*
- * See /include/asm-arm for a definition of this structure.
+ * See linux/include/asm-arm/procinfo.h for a definition of this structure.
  */
 	
 		.section ".proc.info", #alloc, #execinstr
@@ -450,7 +524,7 @@
 		b	__arm720_setup				@ cpu_flush
 		.long	cpu_arch_name				@ arch_name
 		.long	cpu_elf_name				@ elf_name
-		.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT	@ elf_hwcap
+		.long	HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_26BIT	@ elf_hwcap
 		.long	cpu_arm720_info				@ info
 		.long	arm720_processor_functions
 		.size	__arm720_proc_info, . - __arm720_proc_info
diff -u --recursive --new-file v2.4.12/linux/arch/arm/tools/Makefile linux/arch/arm/tools/Makefile
--- v2.4.12/linux/arch/arm/tools/Makefile	Sun Sep 23 11:40:55 2001
+++ linux/arch/arm/tools/Makefile	Thu Oct 11 09:04:57 2001
@@ -12,13 +12,15 @@
 
 # Generate the constants.h header file using the compiler.  We get
 # the compiler to spit out assembly code, and then mundge it into
-# what we want.
+# what we want.  We do this in several stages so make picks up on
+# any errors that occur along the way.
 
 $(TOPDIR)/include/asm-arm/constants.h: constants-hdr getconstants.c
-	$(CC) $(CFLAGS) -S -o - getconstants.c | \
-	 sed 's/^\(#define .* \)[#$$]\(.*\)/\1\2/;/^#define/!d' | \
-	 cat constants-hdr - > $@.tmp
-	cmp $@.tmp $@ >/dev/null 2>&1 || mv $@.tmp $@; $(RM) $@.tmp
+	$(CC) $(CFLAGS) -S -o - getconstants.c > $@.tmp.1
+	sed 's/^\(#define .* \)[#$$]\(.*\)/\1\2/;/^#define/!d' $@.tmp.1 > $@.tmp.2
+	cat constants-hdr $@.tmp.2 > $@.tmp
+	cmp $@.tmp $@ >/dev/null 2>&1 || mv $@.tmp $@
+	$(RM) $@.tmp*
 
 # Build our dependencies, and then generate the constants and
 # mach-types header files.  If we do it now, mkdep will pick
diff -u --recursive --new-file v2.4.12/linux/arch/arm/tools/getconstants.c linux/arch/arm/tools/getconstants.c
--- v2.4.12/linux/arch/arm/tools/getconstants.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/arm/tools/getconstants.c	Thu Oct 11 09:04:57 2001
@@ -14,8 +14,14 @@
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
 
-#ifndef __APCS_32__
-#error APCS-32 required
+/*
+ * Make sure that the compiler and target are compatible.
+ */
+#if defined(__APCS_32__) && defined(CONFIG_CPU_26)
+#error Your compiler targets APCS-32 but this kernel requires APCS-26
+#endif
+#if defined(__APCS_26__) && defined(CONFIG_CPU_32)
+#error Your compiler targets APCS-26 but this kernel requires APCS-32
 #endif
 
 #define OFF_TSK(n) (unsigned long)&(((struct task_struct *)0)->n)
diff -u --recursive --new-file v2.4.12/linux/arch/arm/tools/mach-types linux/arch/arm/tools/mach-types
--- v2.4.12/linux/arch/arm/tools/mach-types	Sun Sep 23 11:40:55 2001
+++ linux/arch/arm/tools/mach-types	Thu Oct 11 09:04:57 2001
@@ -6,7 +6,7 @@
 # To add an entry into this database, please see Documentation/arm/README,
 # or contact rmk@arm.linux.org.uk
 #
-# Last update: Thu Aug 23 12:38:13 2001
+# Last update: Fri Oct 5 18:40:53 2001
 #
 # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
 #
@@ -71,7 +71,7 @@
 jupiter			SA1100_JUPITER		JUPITER			59
 psionw			ARCH_PSIONW		PSIONW			60
 aln			SA1100_ALN		ALN			61
-camelot			ARCH_CAMELOT		CAMELOT			62
+epxa10db		ARCH_CAMELOT		CAMELOT			62
 gds2200			SA1100_GDS2200		GDS2200			63
 psion_series7		SA1100_PSION_SERIES7	PSION_SERIES7		64
 xfile			SA1100_XFILE		XFILE			65
@@ -114,7 +114,7 @@
 gator			SA1100_GATOR		GATOR			103
 granite			ARCH_GRANITE		GRANITE			104
 consus			SA1100_CONSUS		CONSUS			105
-aaec2000_aaed20		ARCH_AAEC2000_AAED2000	AAEC2000_AAED2000	106
+agilent_aaed2000	ARCH_AAEC2000_AAED2000	AAEC2000_AAED2000	106
 cdb89712		ARCH_CDB89712		CDB89712		107
 graphicsmaster		SA1100_GRAPHICSMASTER	GRAPHICSMASTER		108
 adsbitsy		SA1100_ADSBITSY		ADSBITSY		109
@@ -122,3 +122,12 @@
 plce			ARCH_PLCE		PLCE			111
 pt_system3		SA1100_PT_SYSTEM3	PT_SYSTEM3		112
 medalb			ARCH_MEDALB		MEDALB			113
+eagle			ARCH_EAGLE		EAGLE			114
+dsc21			ARCH_DSC21		DSC21			115
+dsc24			ARCH_DSC24		DSC24			116
+ti5472			ARCH_TI5472		TI5472			117
+autcpu12		ARCH_AUTCPU12		AUTCPU12		118
+uengine			ARCH_UENGINE		UENGINE			119
+bluestem		SA1100_BLUESTEM		BLUESTEM		120
+xingu8			ARCH_XINGU8		XINGU8			121
+bushstb			ARCH_BUSHSTB		BUSHSTB			122
diff -u --recursive --new-file v2.4.12/linux/arch/i386/kernel/bluesmoke.c linux/arch/i386/kernel/bluesmoke.c
--- v2.4.12/linux/arch/i386/kernel/bluesmoke.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/i386/kernel/bluesmoke.c	Thu Oct 11 09:04:57 2001
@@ -6,6 +6,8 @@
 #include <asm/processor.h> 
 #include <asm/msr.h>
 
+static int mce_disabled __initdata = 0;
+
 /*
  *	Machine Check Handler For PII/PIII
  */
@@ -111,7 +113,7 @@
  *	Set up machine check reporting for Intel processors
  */
 
-void __init intel_mcheck_init(struct cpuinfo_x86 *c)
+static void __init intel_mcheck_init(struct cpuinfo_x86 *c)
 {
 	u32 l, h;
 	int i;
@@ -130,6 +132,9 @@
 	
 	if(c->x86 == 5)
 	{
+		/* Default P5 to off as its often misconnected */
+		if(mce_disabled != -1)
+			return;
 		machine_check_vector = pentium_machine_check;
 		wmb();
 		/* Read registers before enabling */
@@ -137,11 +142,8 @@
 		rdmsr(MSR_IA32_P5_MC_TYPE, l, h);
 		if(done==0)
 			printk(KERN_INFO "Intel old style machine check architecture supported.\n");
-		/* Enable MCE */		
-		__asm__ __volatile__ (
-			"movl %%cr4, %%eax\n\t"
-			"orl $0x40, %%eax\n\t"
-			"movl %%eax, %%cr4\n\t" : : : "eax");
+ 		/* Enable MCE */
+		set_in_cr4(X86_CR4_MCE);
 		printk(KERN_INFO "Intel old style machine check reporting enabled on CPU#%d.\n", smp_processor_id());
 		return;
 	}
@@ -195,10 +197,7 @@
 	lo|= (1<<2);	/* Enable EIERRINT (int 18 MCE) */
 	lo&= ~(1<<4);	/* Enable MCE */
 	wrmsr(MSR_IDT_FCR1, lo, hi);
-	__asm__ __volatile__ (
-		"movl %%cr4, %%eax\n\t"
-		"orl $0x40, %%eax\n\t"
-		"movl %%eax, %%cr4\n\t" : : : "eax");
+	set_in_cr4(X86_CR4_MCE);
 	printk(KERN_INFO "Winchip machine check reporting enabled on CPU#%d.\n", smp_processor_id());
 }
 
@@ -208,11 +207,10 @@
  */
 
 
-static int mce_disabled = 0;
 
 void __init mcheck_init(struct cpuinfo_x86 *c)
 {
-	if(mce_disabled)
+	if(mce_disabled==1)
 		return;
 		
 	switch(c->x86_vendor)
@@ -230,6 +228,8 @@
 		case X86_VENDOR_CENTAUR:
 			winchip_mcheck_init(c);
 			break;
+		default:
+			break;
 	}
 }
 
@@ -238,4 +238,12 @@
 	mce_disabled = 1;
 	return 0;
 }
+
+static int __init mcheck_enable(char *str)
+{
+	mce_disabled = -1;
+	return 0;
+}
+
 __setup("nomce", mcheck_disable);
+__setup("mce", mcheck_enable);
diff -u --recursive --new-file v2.4.12/linux/arch/i386/kernel/cpuid.c linux/arch/i386/kernel/cpuid.c
--- v2.4.12/linux/arch/i386/kernel/cpuid.c	Sun Aug 12 13:27:58 2001
+++ linux/arch/i386/kernel/cpuid.c	Thu Oct 11 09:04:57 2001
@@ -163,3 +163,4 @@
 
 MODULE_AUTHOR("H. Peter Anvin <hpa@zytor.com>");
 MODULE_DESCRIPTION("x86 generic CPUID driver");
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/arch/i386/kernel/dmi_scan.c linux/arch/i386/kernel/dmi_scan.c
--- v2.4.12/linux/arch/i386/kernel/dmi_scan.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/i386/kernel/dmi_scan.c	Thu Oct 11 13:47:17 2001
@@ -10,6 +10,8 @@
 #include <linux/keyboard.h>
 #include <asm/keyboard.h>
 
+int is_sony_vaio_laptop;
+
 struct dmi_header
 {
 	u8	type;
@@ -322,8 +324,6 @@
  * This one isn't a bug detect for those who asked, we simply want to
  * activate Sony specific goodies like the camera and jogdial..
  */
-int is_sony_vaio_laptop;
-
 static __init int sony_vaio_laptop(struct dmi_blacklist *d)
 {
 	if (is_sony_vaio_laptop == 0)
diff -u --recursive --new-file v2.4.12/linux/arch/i386/kernel/i386_ksyms.c linux/arch/i386/kernel/i386_ksyms.c
--- v2.4.12/linux/arch/i386/kernel/i386_ksyms.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/i386/kernel/i386_ksyms.c	Thu Oct 11 13:47:50 2001
@@ -170,8 +170,5 @@
 EXPORT_SYMBOL(do_BUG);
 #endif
 
-#if defined(CONFIG_SONYPI) || defined(CONFIG_SONYPI_MODULE)
 extern int is_sony_vaio_laptop;
 EXPORT_SYMBOL(is_sony_vaio_laptop);
-#endif
-
diff -u --recursive --new-file v2.4.12/linux/arch/i386/kernel/microcode.c linux/arch/i386/kernel/microcode.c
--- v2.4.12/linux/arch/i386/kernel/microcode.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/i386/kernel/microcode.c	Thu Oct 11 09:04:57 2001
@@ -65,6 +65,7 @@
 
 MODULE_DESCRIPTION("Intel CPU (IA-32) microcode update driver");
 MODULE_AUTHOR("Tigran Aivazian <tigran@veritas.com>");
+MODULE_LICENSE("GPL");
 EXPORT_NO_SYMBOLS;
 
 #define MICRO_DEBUG 0
diff -u --recursive --new-file v2.4.12/linux/arch/i386/kernel/msr.c linux/arch/i386/kernel/msr.c
--- v2.4.12/linux/arch/i386/kernel/msr.c	Sun Aug 12 13:27:58 2001
+++ linux/arch/i386/kernel/msr.c	Thu Oct 11 09:04:57 2001
@@ -271,3 +271,4 @@
 
 MODULE_AUTHOR("H. Peter Anvin <hpa@zytor.com>");
 MODULE_DESCRIPTION("x86 generic MSR driver");
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/arch/i386/kernel/mtrr.c linux/arch/i386/kernel/mtrr.c
--- v2.4.12/linux/arch/i386/kernel/mtrr.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/i386/kernel/mtrr.c	Thu Oct 11 09:04:57 2001
@@ -1253,7 +1253,8 @@
 	break;
 
     case MTRR_IF_INTEL:
-	/*  For Intel PPro stepping <= 7, must be 4 MiB aligned  */
+	/*  For Intel PPro stepping <= 7, must be 4 MiB aligned 
+	    and not touch 0x70000000->0x7003FFFF */
 	if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
 	     boot_cpu_data.x86 == 6 &&
 	     boot_cpu_data.x86_model == 1 &&
@@ -1263,6 +1264,12 @@
 	    {
 		printk (KERN_WARNING "mtrr: base(0x%lx000) is not 4 MiB aligned\n", base);
 		return -EINVAL;
+	    }
+	    if (!(base + size < 0x70000000 || base > 0x7003FFFF) &&
+		 (type == MTRR_TYPE_WRCOMB || type == MTRR_TYPE_WRBACK))
+	    {
+		printk (KERN_WARNING "mtrr: writable mtrr between 0x70000000 and 0x7003FFFF may hang the CPU.\n");
+	        return -EINVAL;
 	    }
 	}
 	/* Fall through */
diff -u --recursive --new-file v2.4.12/linux/arch/ppc/Makefile linux/arch/ppc/Makefile
--- v2.4.12/linux/arch/ppc/Makefile	Sun Sep 23 11:40:56 2001
+++ linux/arch/ppc/Makefile	Thu Oct 11 09:04:57 2001
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.21 08/19/01 20:06:47 paulus
+# BK Id: SCCS/s.Makefile 1.23 09/18/01 11:19:05 paulus
 #
 # 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
diff -u --recursive --new-file v2.4.12/linux/arch/ppc/amiga/config.c linux/arch/ppc/amiga/config.c
--- v2.4.12/linux/arch/ppc/amiga/config.c	Sun Sep 23 11:40:56 2001
+++ linux/arch/ppc/amiga/config.c	Thu Oct 11 09:04:57 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.config.c 1.7 05/21/01 00:48:24 cort
+ * BK Id: SCCS/s.config.c 1.12 09/18/01 11:19:06 paulus
  */
 #define m68k_debug_device debug_device
 
diff -u --recursive --new-file v2.4.12/linux/arch/s390/Makefile linux/arch/s390/Makefile
--- v2.4.12/linux/arch/s390/Makefile	Sun Aug 12 13:27:58 2001
+++ linux/arch/s390/Makefile	Thu Oct 11 09:04:57 2001
@@ -55,16 +55,6 @@
 
 MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
 
-MAKESILO = $(MAKE) -C arch/$(ARCH)/tools/silo
-
-MAKEDASDFMT = $(MAKE) -C arch/$(ARCH)/tools/dasdfmt
-
-silo:
-	@$(MAKESILO) silo
-
-dasdfmt:
-	@$(MAKEDASDFMT) dasdfmt
-
 image: vmlinux 
 	@$(MAKEBOOT) image
 
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/Makefile linux/arch/s390/kernel/Makefile
--- v2.4.12/linux/arch/s390/kernel/Makefile	Wed Apr 11 19:02:27 2001
+++ linux/arch/s390/kernel/Makefile	Thu Oct 11 09:04:57 2001
@@ -15,7 +15,7 @@
 O_TARGET := kernel.o
 
 export-objs	:= debug.o ebcdic.o irq.o s390_ext.o smp.o s390_ksyms.o
-obj-y	:= lowcore.o entry.o bitmap.o traps.o time.o process.o irq.o \
+obj-y	:= entry.o bitmap.o traps.o time.o process.o irq.o \
             setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
             semaphore.o s390fpu.o reipl.o s390_ext.o debug.o
 
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/debug.c linux/arch/s390/kernel/debug.c
--- v2.4.12/linux/arch/s390/kernel/debug.c	Sun Aug 12 13:27:58 2001
+++ linux/arch/s390/kernel/debug.c	Thu Oct 11 09:04:57 2001
@@ -83,6 +83,9 @@
 static int debug_input_level_fn(debug_info_t * id, struct debug_view *view,
 				struct file *file, const char *user_buf,
 				size_t user_buf_size, loff_t * offset);
+static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
+                                struct file *file, const char *user_buf,
+                                size_t user_buf_size, loff_t * offset);
 static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view,
                                 char *out_buf, const char *in_buf);
 static int debug_raw_format_fn(debug_info_t * id,
@@ -123,6 +126,15 @@
 	NULL
 };
 
+struct debug_view debug_flush_view = {
+        "flush",
+        NULL,
+        NULL,
+        NULL,
+        &debug_input_flush_fn,
+        NULL
+};
+
 struct debug_view debug_sprintf_view = {
 	"sprintf",
 	NULL,
@@ -664,6 +676,7 @@
 	if(!rc) 
 		goto out;
 	debug_register_view(rc, &debug_level_view);
+        debug_register_view(rc, &debug_flush_view);
 	printk(KERN_INFO
 	       "debug: reserved %d areas of %d pages for debugging %s\n",
 	       nr_areas, 1 << page_order, rc->name);
@@ -1027,6 +1040,73 @@
       out:
 	*offset += in_buf_size;
 	return rc;		/* number of input characters */
+}
+
+
+/*
+ * flushes debug areas
+ */
+ 
+void debug_flush(debug_info_t* id, int area)
+{
+        unsigned long flags;
+        int i;
+
+        if(!id)
+                return;
+        spin_lock_irqsave(&id->lock,flags);
+        if(area == DEBUG_FLUSH_ALL){
+                id->active_area = 0;
+                memset(id->active_entry, 0, id->nr_areas * sizeof(int));
+                for (i = 0; i < id->nr_areas; i++) 
+                        memset(id->areas[i], 0, PAGE_SIZE << id->page_order);
+                printk(KERN_INFO "debug: %s: all areas flushed\n",id->name);
+        } else if(area >= 0 && area < id->nr_areas) {
+                id->active_entry[area] = 0;
+                memset(id->areas[area], 0, PAGE_SIZE << id->page_order);
+                printk(KERN_INFO
+                        "debug: %s: area %i has been flushed\n",
+                        id->name, area);
+        } else {
+                printk(KERN_INFO
+                        "debug: %s: area %i cannot be flushed (range: %i - %i)\n",
+                        id->name, area, 0, id->nr_areas-1);
+        }
+        spin_unlock_irqrestore(&id->lock,flags);
+}
+
+/*
+ * view function: flushes debug areas 
+ */
+ 
+static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
+                                struct file *file, const char *user_buf,
+                                size_t in_buf_size, loff_t * offset)
+{
+        char input_buf[1];
+        int rc = in_buf_size;
+ 
+        if (*offset != 0)
+                goto out;
+        if (copy_from_user(input_buf, user_buf, 1)){
+                rc = -EFAULT;
+                goto out;
+        }
+        if(input_buf[0] == '-') { 
+                debug_flush(id, DEBUG_FLUSH_ALL);
+                goto out;
+        }
+        if (isdigit(input_buf[0])) {
+                int area = ((int) input_buf[0] - (int) '0');
+                debug_flush(id, area);
+                goto out;
+        }
+
+        printk(KERN_INFO "debug: area `%c` is not valid\n", input_buf[0]);
+
+      out:
+        *offset += in_buf_size;
+        return rc;              /* number of input characters */
 }
 
 /*
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/entry.S linux/arch/s390/kernel/entry.S
--- v2.4.12/linux/arch/s390/kernel/entry.S	Tue Oct  9 17:06:51 2001
+++ linux/arch/s390/kernel/entry.S	Thu Oct 11 09:04:57 2001
@@ -97,17 +97,27 @@
  *    R15 - kernel stack pointer
  */
 
-        .macro  SAVE_ALL psworg           # system entry macro
+        .macro  SAVE_ALL psworg,sync      # system entry macro
         stm     %r13,%r15,__LC_SAVE_AREA
-        stam    %a2,%a4,__LC_SAVE_AREA+12
         basr    %r13,0                    #  temp base pointer
         l       %r13,.Lentry_base-.(%r13) # load &entry_base to %r13 
         tm      \psworg+1,0x01            # test problem state bit
-        bz      BASED(.+12)               # skip stack setup save
-        l       %r15,__LC_KERNEL_STACK    # problem state -> load ksp
-        lam     %a2,%a4,BASED(.Lc_ac)     # set ac.reg. 2 to primary space
-                                          # and access reg. 4 to home space
-0:      s       %r15,BASED(.Lc_spsize)    # make room for registers & psw
+        stam    %a2,%a4,__LC_SAVE_AREA+12
+	.if	\sync
+        bz      BASED(1f)                 # skip stack setup save
+	.else
+        bnz     BASED(0f)                 # from user -> load kernel stack
+	l	%r14,__LC_ASYNC_STACK	  # are we already on the async stack ?
+	slr     %r14,%r15
+	sra	%r14,13
+	be	BASED(1f)
+        l       %r15,__LC_ASYNC_STACK     # load async. stack
+	b	BASED(1f)
+	.endif
+0:      l       %r15,__LC_KERNEL_STACK    # problem state -> load ksp
+	lam	%a2,%a4,BASED(.Lc_ac)	  # set ac.reg. 2 to primary space
+					  # and ac.reg. 4 to home space
+1:      s       %r15,BASED(.Lc_spsize)    # make room for registers & psw
         n       %r15,BASED(.Lc0xfffffff8) # align stack pointer to 8
         stm     %r0,%r12,SP_R0(%r15)      # store gprs 0-12 to kernel stack
         st      %r2,SP_ORIG_R2(%r15)      # store original content of gpr 2
@@ -120,7 +130,7 @@
         xc      0(4,%r15),0(%r15)         # clear back chain
         .endm
 
-        .macro  RESTORE_ALL               # system exit macro
+        .macro  RESTORE_ALL sync          # system exit macro
         mvc     __LC_RETURN_PSW(8),SP_PSW(%r15)  # move user PSW to lowcore
         lam     %a0,%a15,SP_AREGS(%r15)   # load the access registers
         lm      %r0,%r15,SP_R0(%r15)      # load gprs 0-15 of user
@@ -129,8 +139,8 @@
         .endm
 
         .macro  GET_CURRENT
-        lr      %r9,%r15                  # load pointer to task_struct to %r9
-        n       %r9,BASED(.Lc0xffffe000)
+	l	%r9,BASED(.Lc0xffffe000)  # load pointer to task_struct to %r9
+	al	%r9,__LC_KERNEL_STACK
         .endm
 
 
@@ -171,13 +181,35 @@
         br      %r14
 
 /*
+ * do_softirq calling function. We want to run the softirq functions on the
+ * asynchronous interrupt stack.
+ */
+	.global do_call_softirq
+do_call_softirq:
+	stm	%r12,%r15,24(%r15)
+	lr	%r12,%r15
+        basr    %r13,0
+do_call_base:
+	l	%r0,__LC_ASYNC_STACK
+	slr     %r0,%r15
+	sra	%r0,13
+	be	0f-do_call_base(%r13)
+	l	%r15,__LC_ASYNC_STACK
+0:	sl	%r15,.Lc_overhead-do_call_base(%r13)
+        st	%r12,0(%r15)	# store backchain
+	l	%r1,.Ldo_softirq-do_call_base(%r13)
+	basr	%r14,%r1
+	lm	%r12,%r15,24(%r12)
+	br	%r14
+	
+/*
  * SVC interrupt handler routine. System calls are synchronous events and
  * are executed with interrupts enabled.
  */
 
 	.globl  system_call
 system_call:
-        SAVE_ALL __LC_SVC_OLD_PSW
+        SAVE_ALL __LC_SVC_OLD_PSW,1
 	mvi     SP_PGM_OLD_ILC(%r15),1  # mark PGM_OLD_ILC as invalid
 pgm_system_call:	
         GET_CURRENT               # load pointer to task_struct to R9
@@ -207,7 +239,7 @@
 	tm      SP_PGM_OLD_ILC(%r15),0xff
         bz      BASED(pgm_svcret)
 	stnsm   24(%r15),0xfc            # disable I/O and ext. interrupts
-        RESTORE_ALL
+        RESTORE_ALL 1
 
 #
 # call do_signal before return
@@ -557,7 +589,10 @@
         .long  sys_madvise
 	.long  sys_getdents64		 /* 220 */
         .long  sys_fcntl64 
-	.rept  255-221
+	.long  sys_ni_syscall		 /* 222 - reserved for posix_acl */
+	.long  sys_ni_syscall		 /* 223 - reserved for posix_acl */
+	.long  sys_ni_syscall		 /* 224 - reserved for posix_acl */
+	.rept  255-224
 	.long  sys_ni_syscall
 	.endr
 
@@ -581,10 +616,10 @@
  * for LPSW?).
  */
 	stm     %r13,%r15,__LC_SAVE_AREA
-	stam    %a2,%a4,__LC_SAVE_AREA+12
 	basr    %r13,0                   # temp base pointer
 	l       %r13,.Lentry_base-.(%r13)# load &entry_base to %r13
         tm      __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
+	stam    %a2,%a4,__LC_SAVE_AREA+12
         bz      BASED(pgm_sv)            # skip if not
         tm      __LC_PGM_OLD_PSW,0x40    # test if per event recording is on
         bnz     BASED(pgm_sv)            # skip if it is
@@ -677,7 +712,7 @@
 
         .globl io_int_handler
 io_int_handler:
-        SAVE_ALL __LC_IO_OLD_PSW
+        SAVE_ALL __LC_IO_OLD_PSW,0
         GET_CURRENT               # load pointer to task_struct to R9
         la      %r2,SP_PTREGS(%r15) # address of register-save area
         sr      %r3,%r3
@@ -710,7 +745,7 @@
         bnz     BASED(io_signal_return)
 io_leave:
         stnsm   24(%r15),0xfc            # disable I/O and ext. interrupts
-        RESTORE_ALL
+        RESTORE_ALL 0
 
 #
 # call do_softirq
@@ -744,7 +779,7 @@
 
         .globl  ext_int_handler
 ext_int_handler:
-        SAVE_ALL __LC_EXT_OLD_PSW
+        SAVE_ALL __LC_EXT_OLD_PSW,0
         GET_CURRENT                    # load pointer to task_struct to R9
         la      %r2,SP_PTREGS(%r15)    # address of register-save area
         lh      %r3,__LC_EXT_INT_CODE  # error code
@@ -772,11 +807,11 @@
 
         .globl mcck_int_handler
 mcck_int_handler:
-        SAVE_ALL __LC_MCK_OLD_PSW
+        SAVE_ALL __LC_MCK_OLD_PSW,0
 	l       %r1,BASED(.Ls390_mcck)
 	basr    %r14,%r1	  # call machine check handler
 mcck_return:
-        RESTORE_ALL
+        RESTORE_ALL 0
 
 #ifdef CONFIG_SMP
 /*
@@ -784,7 +819,7 @@
  */
         .globl restart_int_handler
 restart_int_handler:
-        l       %r15,__LC_KERNEL_STACK # load ksp
+        l       %r15,__LC_SAVE_AREA+60 # load ksp
         lctl    %c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs
         lam     %a0,%a15,__LC_AREGS_SAVE_AREA
         stosm   0(%r15),0x04           # now we can turn dat on
@@ -817,6 +852,7 @@
 .Lc0xffffe000: .long  -8192        # to round stack pointer to &task_struct
 .Lc8191:       .long  8191
 .Lc_spsize:    .long  SP_SIZE
+.Lc_overhead:  .long  STACK_FRAME_OVERHEAD
 .Lc_ac:        .long  0,0,1
 .Lc_ENOSYS:    .long  -ENOSYS
 .Lc4:          .long  4
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/gdb-stub.c linux/arch/s390/kernel/gdb-stub.c
--- v2.4.12/linux/arch/s390/kernel/gdb-stub.c	Fri May 12 11:41:44 2000
+++ linux/arch/s390/kernel/gdb-stub.c	Thu Oct 11 09:04:57 2001
@@ -65,7 +65,8 @@
  * $m0,10#2a               +$00010203040506070809101112131415#42
  *
  */
-
+#define TRUE 1
+#define FALSE 0
 #include <asm/gdb-stub.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
@@ -74,14 +75,15 @@
 #include <linux/mm.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
+#include <linux/stddef.h>
 
+#define S390_REGS_COMMON_SIZE offsetof(struct gdb_pt_regs,orig_gpr2)
 
 /*
  * external low-level support routines
  */
 
-extern int putDebugChar(char c);    /* write a single character      */
-extern char getDebugChar(void);     /* read and return a single char */
+
 extern void fltr_set_mem_err(void);
 extern void trap_low(void);
 
@@ -247,8 +249,10 @@
 
 	while (count-- > 0) {
 		ch = *(mem++);
+#if 0
 		if (mem_err)
 			return 0;
+#endif
 		*buf++ = hexchars[ch >> 4];
 		*buf++ = hexchars[ch & 0xf];
 	}
@@ -276,8 +280,10 @@
 		ch = hex(*buf++) << 4;
 		ch |= hex(*buf++);
 		*(mem++) = ch;
+#if 0
 		if (mem_err)
 			return 0;
+#endif
 	}
 
 /*	set_mem_fault_trap(0); */
@@ -349,7 +355,7 @@
 	return (numChars);
 }
 
-void gdb_stub_get_non_pt_regs(gdb_pt_regs *regs)
+void gdb_stub_get_non_pt_regs(struct gdb_pt_regs *regs)
 {
 	s390_fp_regs *fpregs=&regs->fp_regs;
 	int has_ieee=save_fp_regs1(fpregs);
@@ -365,7 +371,7 @@
 	}
 }
 
-void gdb_stub_set_non_pt_regs(gdb_pt_regs *regs)
+void gdb_stub_set_non_pt_regs(struct gdb_pt_regs *regs)
 {
 	restore_fp_regs1(&regs->fp_regs);
 }
@@ -390,7 +396,7 @@
  * returns 1 if you should skip the instruction at the trap address, 0
  * otherwise.
  */
-void gdb_stub_handle_exception(gdb_pt_regs *regs,int sigval)
+void gdb_stub_handle_exception(struct gdb_pt_regs *regs,int sigval)
 {
 	int trap;			/* Trap type */
 	int addr;
@@ -402,19 +408,23 @@
 	/*
 	 * reply to host that an exception has occurred
 	 */
+#if 0
 	send_signal(sigval);
-
+#endif
 	/*
 	 * Wait for input from remote GDB
 	 */
-	while (1) {
+	while (1) 
+	{
 		output_buffer[0] = 0;
 		getpacket(input_buffer);
 
 		switch (input_buffer[0])
 		{
 		case '?':
+#if 0
 			send_signal(sigval);
+#endif
 			continue;
 
 		case 'd':
@@ -427,9 +437,9 @@
 		case 'g':
 			gdb_stub_get_non_pt_regs(regs);
 			ptr = output_buffer;
-			ptr=  mem2hex((char *)regs,ptr,sizeof(s390_regs_common),FALSE);
+			ptr=  mem2hex((char *)regs,ptr,S390_REGS_COMMON_SIZE,FALSE);
 			ptr=  mem2hex((char *)&regs->crs[0],ptr,NUM_CRS*CR_SIZE,FALSE);
-			ptr = mem2hex((char *)&regs->fp_regs, ptr,sizeof(s390_fp_regs));
+			ptr = mem2hex((char *)&regs->fp_regs, ptr,sizeof(s390_fp_regs),FALSE);
 			break;
 	  
 		/*
@@ -438,11 +448,11 @@
 		 */
 		case 'G':
 			ptr=input_buffer;
-			hex2mem (ptr, (char *)regs,sizeof(s390_regs_common), FALSE);
-			ptr+=sizeof(s390_regs_common)*2;
+			hex2mem (ptr, (char *)regs,S390_REGS_COMMON_SIZE, FALSE);
+			ptr+=S390_REGS_COMMON_SIZE*2;
 			hex2mem (ptr, (char *)regs->crs[0],NUM_CRS*CR_SIZE, FALSE);
 			ptr+=NUM_CRS*CR_SIZE*2;
-			hex2mem (ptr, (char *)regs->fp_regs,sizeof(s390_fp_regs), FALSE);
+			hex2mem (ptr, (char *)&regs->fp_regs,sizeof(s390_fp_regs), FALSE);
 			gdb_stub_set_non_pt_regs(regs);
 			strcpy(output_buffer,"OK");
 		break;
@@ -472,7 +482,8 @@
 			if (hexToInt(&ptr, &addr)
 				&& *ptr++ == ','
 				&& hexToInt(&ptr, &length)
-				&& *ptr++ == ':') {
+				&& *ptr++ == ':') 
+			{
 				if (hex2mem(ptr, (char *)addr, length, 1))
 					strcpy(output_buffer, "OK");
 				else
@@ -490,8 +501,7 @@
 
 			ptr = &input_buffer[1];
 			if (hexToInt(&ptr, &addr))
-				regs->cp0_epc = addr;
-	  
+				regs->psw.addr = addr;
 			/*
 			 * Need to flush the instruction cache here, as we may
 			 * have deposited a breakpoint, and the icache probably
@@ -529,22 +539,22 @@
 			 * There is no single step insn in the MIPS ISA, so we
 			 * use breakpoints and continue, instead.
 			 */
+#if 0
 			single_step(regs);
+#endif
 			flush_cache_all();
 			return;
 			/* NOTREACHED */
+			break;
 
-		}
-		break;
-
-		}			/* switch */
-
-		/*
-		 * reply to the request
-		 */
+		}      /* switch */
 
+	/*
+	 * reply to the request
+	 */
+	
 		putpacket(output_buffer);
-
+	
 	} /* while */
 }
 
@@ -558,13 +568,9 @@
 {
 	if (!gdb_stub_initialised)
 		return;
-	__asm__ __volatile__(
-			".globl	breakinst\n"
-			"breakinst:\t.word   %0\n\t"
-			:
-			: "i" (S390_BREAKPOINT_U16)
-				:
-				);
+	asm volatile (".globl	breakinst\n"
+		"breakinst:\t.word   %0"
+		: : "i" (S390_BREAKPOINT_U16) );
 }
 
 
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/head.S linux/arch/s390/kernel/head.S
--- v2.4.12/linux/arch/s390/kernel/head.S	Sun Aug 12 13:27:58 2001
+++ linux/arch/s390/kernel/head.S	Thu Oct 11 09:04:57 2001
@@ -461,28 +461,52 @@
         .org  0x10000
 startup:basr  %r13,0                     # get base
 .LPG1:  lctl  %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
-	la    %r12,parmarea-.LPG1(%r13)  # pointer to parameter area
+	la    %r12,_pstart-.LPG1(%r13)   # pointer to parameter area
 					 # move IPL device to lowcore
         mvc   __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
 	
 #
-# find out memory size.
+# find memory chunks.
 #
 	mvc   __LC_PGM_NEW_PSW(8),.Lpcmem-.LPG1(%r13)
-        lhi   %r2,1
-        sll   %r2,17                     # test in increments of 128KB
-	lr    %r1,%r2
-	ahi   %r1,-4                     # test last word in the segment
-.Lloop:	
-	l     %r0,0(%r1)                 # test 128KB segment
-	st    %r0,0(%r1)
-	ar    %r1,%r2                    # add 128KB
-	bnm   .Lloop-.LPG1(%r13)         # r1 < 0x80000000 -> loop
-.Lchkmem:
-	n     %r1,.L4malign-.LPG1(%r13)  # align to multiples of 4M
-        l     %r2,.Lmemsize-.LPG1(%r13)  # address of variable memory_size
-	st    %r1,0(%r2)                 # store memory size
-
+	la    %r1,1                      # test in increments of 128KB
+	sll   %r1,17
+	l     %r3,.Lmchunk-.LPG1(%r13)   # get pointer to memory_chunk array
+	slr   %r4,%r4                    # set start of chunk to zero
+	slr   %r5,%r5                    # set end of chunk to zero
+	slr   %r6,%r6			 # set access code to zero
+.Lloop:
+	tprot 0(%r5),0			 # test protection of first byte
+	ipm   %r7
+	srl   %r7,28
+	clr   %r6,%r7			 # compare cc with last access code
+	be    .Lsame-.LPG1(%r13)
+	clr   %r4,%r5			 # chunk size > 0?
+	be    .Lsize0-.LPG1(%r13)
+	st    %r4,0(%r3)		 # store start address of chunk
+	lr    %r0,%r5
+	slr   %r0,%r4
+	st    %r0,4(%r3)		 # store size of chunk
+	st    %r6,8(%r3)		 # store type of chunk
+	la    %r3,12(%r3)
+	lr    %r4,%r5			 # set start to end
+.Lsize0:
+	lr    %r6,%r7			 # set access code to last cc
+.Lsame:
+	ar    %r5,%r1			 # add 128KB to end of chunk
+	bno   .Lloop-.LPG1(%r13)	 # r1 < 0x80000000 -> loop
+.Lchkmem:				 # > 2GB or tprot got a program check
+	clr   %r4,%r5			 # chunk size > 0?
+	be    .Ldonemem-.LPG1(%r13)
+	st    %r4,0(%r3)		 # store start address of chunk
+	lr    %r0,%r5
+	slr   %r0,%r4
+	st    %r0,4(%r3)		 # store size of chunk
+	st    %r6,8(%r3)		 # store type of chunk
+.Ldonemem:		
+        l     %r1,.Lmemsize-.LPG1(%r13)  # address of variable memory_size
+	st    %r5,0(%r1)                 # store last end to memory size
+	
         l      %r12,.Lmflags-.LPG1(%r13) # get address of machine_flags
 #
 # find out if we are running under VM
@@ -534,7 +558,7 @@
 .Lentry:.long  0x00080000,0x80000000 + _stext
 .Lctl:  .long  0x04b50002               # cr0: various things
         .long  0                        # cr1: primary space segment table
-        .long  0                        # cr2: access register translation
+        .long  .Lduct                   # cr2: dispatchable unit control table
         .long  0                        # cr3: instruction authorization
         .long  0                        # cr4: instruction authorization
         .long  0                        # cr5:  various things
@@ -552,47 +576,50 @@
 .Lpcfpu:.long  0x00080000,0x80000000 + .Lchkfpu
 .Lpccsp:.long  0x00080000,0x80000000 + .Lchkcsp
 .Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg
-.L4malign:.long 0xffc00000
 .Lmemsize:.long memory_size
+.Lmchunk:.long memory_chunk
 .Lmflags:.long machine_flags
 
+	.org PARMAREA-64
+.Lduct:	.long 0,0,0,0,0,0,0,0
+	.long 0,0,0,0,0,0,0,0
+
 #
 # params at 10400 (setup.h)
 #
 	.org   PARMAREA
-parmarea:	
+	.global _pstart
+_pstart:	
         .long  0,0                      # IPL_DEVICE
         .long  0,RAMDISK_ORIGIN         # INITRD_START
-        .long  0,0x800000               # INITRD_SIZE
+        .long  0,RAMDISK_SIZE           # INITRD_SIZE
 
         .org   COMMAND_LINE
     	.byte  "root=/dev/ram0 ro"
         .byte  0
+	.org   0x11000
+	.global _pend
+_pend:	
 
-#
-# startup-code, running in virtual mode
-#
 #ifdef CONFIG_SHARED_KERNEL
 	.org   0x100000
-#else
-        .org   0x10800
 #endif
+
+#
+# startup-code, running in virtual mode
+#
         .globl _stext
 _stext:	basr  %r13,0                    # get base
 .LPG2:
 #
-# Setup lowcore
+# Setup stack
 #
-        l     %r1,__LC_IPLDEV           # load ipl device number
-        spx   .Lprefix-.LPG2(%r13)      # set prefix to linux lowcore
-        st    %r1,__LC_IPLDEV           # store ipl device number
         l     %r15,.Linittu-.LPG2(%r13)
-        ahi   %r15,8192                 # init_task_union + 8191
+        ahi   %r15,8192                 # init_task_union + 8192
         st    %r15,__LC_KERNEL_STACK    # set end of kernel stack
         ahi   %r15,-96
         xc    0(4,%r15),0(%r15)         # set backchain to zero
-        lhi   %r0,-1
-        st    %r0,__LC_KERNEL_LEVEL     # set interrupt count to -1
+
 #
 # clear bss memory
 #
@@ -622,7 +649,6 @@
 #
             .align 8
 .Ldw:	    .long  0x000a0000,0x00000000
-.Lprefix:   .long  init_S390_lowcore	
 .Linittu:   .long  init_task_union
 .Lstart:    .long  start_kernel
 .Lbss_bgn:  .long  __bss_start
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/lowcore.S linux/arch/s390/kernel/lowcore.S
--- v2.4.12/linux/arch/s390/kernel/lowcore.S	Fri May 12 11:41:44 2000
+++ linux/arch/s390/kernel/lowcore.S	Wed Dec 31 16:00:00 1969
@@ -1,60 +0,0 @@
-/*
- *  arch/s390/kernel/lowcore.S
- *    S390 lowcore definition.
- *
- *  S390 version
- *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Hartmut Penner (hp@de.ibm.com)
- *               Martin Schwidefsky (schwidefsky@de.ibm.com),
- */
-
-#include <asm/lowcore.h>
-         .align 4096
-         .globl init_S390_lowcore
-init_S390_lowcore:      
-         .long  _RESTART_PSW_MASK
-         .long  restart_int_handler + _ADDR_31
-         .long  0,0
-         .long  0,0
-EXT_OLD: .long  0,0
-SVC_OLD: .long  0,0
-PGM_OLD: .long  0,0
-MCCK_OLD:.long  0,0
-IO_OLD:  .long  0,0
-         .long  0,0,0,0,0,0
-#
-# new psws need all to be physical
-# because we start with dat off
-#
-EXT_PSW: .long  _EXT_PSW_MASK
-         .long  ext_int_handler + _ADDR_31
-#
-SVC_PSW: .long  _SVC_PSW_MASK
-         .long  system_call + _ADDR_31
-#
-PGM_PSW: .long  _PGM_PSW_MASK
-         .long  pgm_check_handler + _ADDR_31
-#
-MCCK_PSW:.long  _MCCK_PSW_MASK
-         .long  mcck_int_handler + _ADDR_31
-#
-IO_PSW:  .long  _IO_PSW_MASK
-         .long  io_int_handler + _ADDR_31
-#
-#
-#
-EXTERNAL_PARAMETER:     .long  0
-CPU_ADDRESS:            .word 0
-EXT_INTERRUPT_CODE:     .word 0
-SVC_ILC:                .word 0
-SVC_CODE:               .word 0
-PGM_ILC:                .word 0
-PGM_CODE:               .word 0
-TRANS_EXC_ADDR:         .long  0                         # 090
-                        .fill 0xC00-0x094,1,0
-SAVE_AREA:              .fill 0x40,1,0                   # C00
-KERNEL_STACK:           .long 0                          # C40
-KERNEL_LEVEL:           .long 0                          # C44
-CPUID:                  .long 0,0                        # C48
-                        .fill 0x1000-0xC50,1,0
-
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/process.c linux/arch/s390/kernel/process.c
--- v2.4.12/linux/arch/s390/kernel/process.c	Tue Oct  9 17:06:51 2001
+++ linux/arch/s390/kernel/process.c	Thu Oct 11 09:04:57 2001
@@ -44,8 +44,6 @@
 #include <asm/processor.h>
 #include <asm/irq.h>
 
-spinlock_t semaphore_wake_lock = SPIN_LOCK_UNLOCKED;
-
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
 
 /*
@@ -209,7 +207,7 @@
 void show_regs(struct pt_regs *regs)
 {
 	char buff[80];
-	int line;
+	int i, line;
 
         printk("CPU:    %d\n",smp_processor_id());
         printk("Process %s (pid: %d, stackpage=%08X)\n",
@@ -217,6 +215,17 @@
 	
 	for (line = 0; sprintf_regs(line, buff, current, regs); line++)
 		printk(buff);
+
+	if (regs->psw.mask & PSW_PROBLEM_STATE)
+	{
+		printk("User Code:\n");
+		memset(buff, 0, 20);
+		copy_from_user(buff,
+			       (char *) (regs->psw.addr & PSW_ADDR_MASK), 20);
+		for (i = 0; i < 20; i++)
+			printk("%02x ", buff[i]);
+		printk("\n");
+	}
 }
 
 char *task_show_regs(struct task_struct *task, char *buffer)
@@ -324,28 +333,19 @@
 
 asmlinkage int sys_fork(struct pt_regs regs)
 {
-        int ret;
-
-        lock_kernel();
-        ret = do_fork(SIGCHLD, regs.gprs[15], &regs, 0);
-        unlock_kernel();
-        return ret;
+        return do_fork(SIGCHLD, regs.gprs[15], &regs, 0);
 }
 
 asmlinkage int sys_clone(struct pt_regs regs)
 {
         unsigned long clone_flags;
         unsigned long newsp;
-        int ret;
 
-        lock_kernel();
         clone_flags = regs.gprs[3];
         newsp = regs.orig_gpr2;
         if (!newsp)
                 newsp = regs.gprs[15];
-        ret = do_fork(clone_flags, newsp, &regs, 0);
-        unlock_kernel();
-        return ret;
+        return do_fork(clone_flags, newsp, &regs, 0);
 }
 
 /*
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/s390_ksyms.c linux/arch/s390/kernel/s390_ksyms.c
--- v2.4.12/linux/arch/s390/kernel/s390_ksyms.c	Sun Aug 12 13:27:58 2001
+++ linux/arch/s390/kernel/s390_ksyms.c	Thu Oct 11 09:04:57 2001
@@ -15,11 +15,11 @@
 /*
  * memory management
  */
-EXPORT_SYMBOL(_oi_bitmap);
-EXPORT_SYMBOL(_ni_bitmap);
-EXPORT_SYMBOL(_zb_findmap);
-EXPORT_SYMBOL(__copy_from_user_fixup);
-EXPORT_SYMBOL(__copy_to_user_fixup);
+EXPORT_SYMBOL_NOVERS(_oi_bitmap);
+EXPORT_SYMBOL_NOVERS(_ni_bitmap);
+EXPORT_SYMBOL_NOVERS(_zb_findmap);
+EXPORT_SYMBOL_NOVERS(__copy_from_user_fixup);
+EXPORT_SYMBOL_NOVERS(__copy_to_user_fixup);
 
 /*
  * semaphore ops
@@ -56,10 +56,7 @@
 EXPORT_SYMBOL(csum_fold);
 EXPORT_SYMBOL(console_mode);
 EXPORT_SYMBOL(console_device);
+EXPORT_SYMBOL_NOVERS(do_call_softirq);
 
-#if CONFIG_IP_MULTICAST
-/* Required for lcs gigabit ethernet multicast support */
-EXPORT_SYMBOL(arp_mc_map);
-#endif
 
 
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/setup.c linux/arch/s390/kernel/setup.c
--- v2.4.12/linux/arch/s390/kernel/setup.c	Sun Aug 12 13:27:58 2001
+++ linux/arch/s390/kernel/setup.c	Thu Oct 11 09:04:57 2001
@@ -47,6 +47,9 @@
 unsigned int console_device = -1;
 unsigned long memory_size = 0;
 unsigned long machine_flags = 0;
+struct { unsigned long addr, size, type; } memory_chunk[16];
+#define CHUNK_READ_WRITE 0
+#define CHUNK_READ_ONLY 1
 __u16 boot_cpu_addr;
 int cpus_initialized = 0;
 unsigned long cpu_initialized = 0;
@@ -258,6 +261,8 @@
  * Setup function called from init/main.c just after the banner
  * was printed.
  */
+extern char _pstart, _pend, _stext;
+
 void __init setup_arch(char **cmdline_p)
 {
         unsigned long bootmap_size;
@@ -267,19 +272,14 @@
 	unsigned long start_pfn, end_pfn;
         static unsigned int smptrap=0;
         unsigned long delay = 0;
+	struct _lowcore *lowcore;
+	int i;
 
         if (smptrap)
                 return;
         smptrap=1;
 
         /*
-         * Setup lowcore information for boot cpu
-         */
-        cpu_init();
-        boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
-        __cpu_logical_map[0] = boot_cpu_addr;
-
-        /*
          * print what head.S has found out about the machine 
          */
 	printk((MACHINE_IS_VM) ?
@@ -291,7 +291,7 @@
 
         ROOT_DEV = to_kdev_t(0x0100);
         memory_start = (unsigned long) &_end;    /* fixit if use $CODELO etc*/
-	memory_end = memory_size;
+	memory_end = memory_size & ~0x400000UL;  /* align memory end to 4MB */
         /*
          * We need some free virtual space to be able to do vmalloc.
          * On a machine with 2GB memory we make sure that we have at
@@ -373,10 +373,25 @@
 	bootmap_size = init_bootmem(start_pfn, end_pfn);
 
 	/*
-	 * Register RAM pages with the bootmem allocator.
+	 * Register RAM areas with the bootmem allocator.
 	 */
-	free_bootmem(start_pfn << PAGE_SHIFT, 
-		     (end_pfn - start_pfn) << PAGE_SHIFT);
+	for (i = 0; i < 16 && memory_chunk[i].size > 0; i++) {
+		unsigned long start_chunk, end_chunk;
+
+		if (memory_chunk[i].type != CHUNK_READ_WRITE)
+			continue;
+		start_chunk = (memory_chunk[i].addr + PAGE_SIZE - 1);
+		start_chunk >>= PAGE_SHIFT;
+		end_chunk = (memory_chunk[i].addr + memory_chunk[i].size);
+		end_chunk >>= PAGE_SHIFT;
+		if (start_chunk < start_pfn)
+			start_chunk = start_pfn;
+		if (end_chunk > end_pfn)
+			end_chunk = end_pfn;
+		if (start_chunk < end_chunk)
+			free_bootmem(start_chunk << PAGE_SHIFT,
+				     (end_chunk - start_chunk) << PAGE_SHIFT);
+	}
 
         /*
          * Reserve the bootmem bitmap itself as well. We do this in two
@@ -401,6 +416,36 @@
         }
 #endif
 
+        /*
+         * Setup lowcore for boot cpu
+         */
+	lowcore = (struct _lowcore *)
+		__alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0);
+	memset(lowcore, 0, PAGE_SIZE);
+	lowcore->restart_psw.mask = _RESTART_PSW_MASK;
+	lowcore->restart_psw.addr = _ADDR_31 + (addr_t) &restart_int_handler;
+	lowcore->external_new_psw.mask = _EXT_PSW_MASK;
+	lowcore->external_new_psw.addr = _ADDR_31 + (addr_t) &ext_int_handler;
+	lowcore->svc_new_psw.mask = _SVC_PSW_MASK;
+	lowcore->svc_new_psw.addr = _ADDR_31 + (addr_t) &system_call;
+	lowcore->program_new_psw.mask = _PGM_PSW_MASK;
+	lowcore->program_new_psw.addr = _ADDR_31 + (addr_t) &pgm_check_handler;
+        lowcore->mcck_new_psw.mask = _MCCK_PSW_MASK;
+	lowcore->mcck_new_psw.addr = _ADDR_31 + (addr_t) &mcck_int_handler;
+	lowcore->io_new_psw.mask = _IO_PSW_MASK;
+	lowcore->io_new_psw.addr = _ADDR_31 + (addr_t) &io_int_handler;
+	lowcore->ipl_device = S390_lowcore.ipl_device;
+	lowcore->kernel_stack = ((__u32) &init_task_union) + 8192;
+	lowcore->async_stack = (__u32)
+		__alloc_bootmem(2*PAGE_SIZE, 2*PAGE_SIZE, 0) + 8192;
+	set_prefix((__u32) lowcore);
+        cpu_init();
+        boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
+        __cpu_logical_map[0] = boot_cpu_addr;
+
+	/*
+	 * Create kernel page tables and switch to virtual addressing.
+	 */
         paging_init();
 
 	res = alloc_bootmem_low(sizeof(struct resource));
@@ -433,30 +478,49 @@
 }
 
 /*
- *	Get CPU information for use by the procfs.
+ * get_cpuinfo - Get information on one CPU for use by procfs.
+ *
+ *	Prints info on the next CPU into buffer.  Beware, doesn't check for
+ *	buffer overflow.  Current implementation of procfs assumes that the
+ *	resulting data is <= 1K.
+ *
+ * Args:
+ *	buffer	-- you guessed it, the data buffer
+ *	cpu_np	-- Input: next cpu to get (start at 0).  Output: Updated.
+ *
+ *	Returns number of bytes written to buffer.
  */
 
-int get_cpuinfo(char * buffer)
+int get_cpuinfo(char *buffer, unsigned *cpu_np)
 {
         struct cpuinfo_S390 *cpuinfo;
         char *p = buffer;
-        int i;
+	unsigned n;
 
-        p += sprintf(p,"vendor_id       : IBM/S390\n"
-                       "# processors    : %i\n"
-                       "bogomips per cpu: %lu.%02lu\n",
-                       smp_num_cpus, loops_per_jiffy/(500000/HZ),
-                       (loops_per_jiffy/(5000/HZ))%100);
-        for (i = 0; i < smp_num_cpus; i++) {
-                cpuinfo = &safe_get_cpu_lowcore(i).cpu_data;
-                p += sprintf(p,"processor %i: "
-                               "version = %02X,  "
-                               "identification = %06X,  "
-                               "machine = %04X\n",
-                               i, cpuinfo->cpu_id.version,
-                               cpuinfo->cpu_id.ident,
-                               cpuinfo->cpu_id.machine);
-        }
+	n = *cpu_np;
+	while (n < NR_CPUS && (cpu_online_map & (1 << n)) == 0)
+		n++;
+	if (n >= NR_CPUS) {
+		*cpu_np = NR_CPUS;
+		return (0);
+	}
+	*cpu_np = n + 1;
+
+	if (n == 0) {
+		p += sprintf(p,"vendor_id       : IBM/S390\n"
+			       "# processors    : %i\n"
+			       "bogomips per cpu: %lu.%02lu\n",
+			       smp_num_cpus, loops_per_jiffy/(500000/HZ),
+			       (loops_per_jiffy/(5000/HZ))%100);
+	}
+	cpuinfo = &safe_get_cpu_lowcore(n).cpu_data;
+	p += sprintf(p,"processor %i: "
+		       "version = %02X,  "
+		       "identification = %06X,  "
+		       "machine = %04X\n",
+		       n, cpuinfo->cpu_id.version,
+		       cpuinfo->cpu_id.ident,
+		       cpuinfo->cpu_id.machine);
         return p - buffer;
 }
 
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/signal.c linux/arch/s390/kernel/signal.c
--- v2.4.12/linux/arch/s390/kernel/signal.c	Sun Aug 12 13:27:58 2001
+++ linux/arch/s390/kernel/signal.c	Thu Oct 11 09:04:57 2001
@@ -12,6 +12,7 @@
  *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
  */
 
+#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
@@ -23,31 +24,25 @@
 #include <linux/ptrace.h>
 #include <linux/unistd.h>
 #include <linux/stddef.h>
+#include <linux/personality.h>
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
 
-#define DEBUG_SIG 0
-
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-/* pretcode & sig are used to store the return addr on Intel
-   & the signal no as the first parameter we do this differently
-   using gpr14 & gpr2. */
-
-#define SIGFRAME_COMMON \
-__u8     callee_used_stack[__SIGNAL_FRAMESIZE]; \
-struct sigcontext sc; \
-_sigregs sregs; \
-__u8 retcode[S390_SYSCALL_SIZE];
 
 typedef struct 
 {
-	SIGFRAME_COMMON
+	__u8 callee_used_stack[__SIGNAL_FRAMESIZE];
+	struct sigcontext sc;
+	_sigregs sregs;
+	__u8 retcode[S390_SYSCALL_SIZE];
 } sigframe;
 
 typedef struct 
 {
-	SIGFRAME_COMMON
+	__u8 callee_used_stack[__SIGNAL_FRAMESIZE];
+	__u8 retcode[S390_SYSCALL_SIZE];
 	struct siginfo info;
 	struct ucontext uc;
 } rt_sigframe;
@@ -205,7 +200,7 @@
 	err=__copy_from_user(regs,&sregs->regs,sizeof(_s390_regs_common));
 	if(!err)
 	{
-		regs->orig_gpr2 = -1;		/* disable syscall checks */
+		regs->trap = -1;		/* disable syscall checks */
 		regs->psw.mask=(saved_psw.mask&~PSW_MASK_DEBUGCHANGE)|
 		(regs->psw.mask&PSW_MASK_DEBUGCHANGE);
 		regs->psw.addr=(saved_psw.addr&~PSW_ADDR_DEBUGCHANGE)|
@@ -217,53 +212,51 @@
 	return(err);
 }
 
-static int
-restore_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
-		 _sigregs *sregs,sigset_t *set)
-{
-	unsigned int err;
-
-	err=restore_sigregs(regs,sregs);
-	if(!err)
-		err=__copy_from_user(&set->sig,&sc->oldmask,_SIGMASK_COPY_SIZE);
-		return(err);
-}
-
-int sigreturn_common(struct pt_regs *regs,int framesize)
+asmlinkage long sys_sigreturn(struct pt_regs *regs)
 {
 	sigframe *frame = (sigframe *)regs->gprs[15];
 	sigset_t set;
 
 	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
-		return -1;
-	if (restore_sigcontext(&frame->sc,regs,&frame->sregs,&set))
-	        return -1;
+		goto badframe;
+	if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE))
+		goto badframe;
+
 	sigdelsetmask(&set, ~_BLOCKABLE);
 	spin_lock_irq(&current->sigmask_lock);
 	current->blocked = set;
 	recalc_sigpending(current);
 	spin_unlock_irq(&current->sigmask_lock);
-	return 0;
-}
-
-asmlinkage int sys_sigreturn(struct pt_regs *regs)
-{
 
-	if (sigreturn_common(regs,sizeof(sigframe)))
+	if (restore_sigregs(regs, &frame->sregs))
 		goto badframe;
+
 	return regs->gprs[2];
 
 badframe:
 	force_sig(SIGSEGV, current);
 	return 0;
-}	
+}
 
-asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
+asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
 {
 	rt_sigframe *frame = (rt_sigframe *)regs->gprs[15];
+	sigset_t set;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__copy_from_user(&set.sig, &frame->uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
 
-	if (sigreturn_common(regs,sizeof(rt_sigframe)))
+	if (restore_sigregs(regs, &frame->uc.uc_mcontext))
 		goto badframe;
+
 	/* It is more difficult to avoid calling this function than to
 	   call it and ignore errors.  */
 	do_sigaltstack(&frame->uc.uc_stack, NULL, regs->gprs[15]);
@@ -272,7 +265,7 @@
 badframe:
 	force_sig(SIGSEGV, current);
 	return 0;
-}	
+}
 
 /*
  * Set up a signal frame.
@@ -306,58 +299,48 @@
 	return (void *)((sp - frame_size) & -8ul);
 }
 
-static void *setup_frame_common(int sig, struct k_sigaction *ka,
-			sigset_t *set, struct pt_regs * regs,
-				int frame_size,u16 retcode)
+static inline int map_signal(int sig)
 {
-	sigframe *frame;
-	int err;
+	if (current->exec_domain
+	    && current->exec_domain->signal_invmap
+	    && sig < 32)
+		return current->exec_domain->signal_invmap[sig];
+	else
+		return sig;
+}
 
-	frame = get_sigframe(ka, regs,frame_size);
-	if (!access_ok(VERIFY_WRITE, frame,frame_size))
-		return 0;
-	err = save_sigregs(regs,&frame->sregs);
-	if(!err)
-		err=__put_user(&frame->sregs,&frame->sc.sregs);
-	if(!err)
+static void setup_frame(int sig, struct k_sigaction *ka,
+			sigset_t *set, struct pt_regs * regs)
+{
+	sigframe *frame = get_sigframe(ka, regs, sizeof(sigframe));
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe)))
+		goto give_sigsegv;
+
+	if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE))
+		goto give_sigsegv;
+
+	if (save_sigregs(regs, &frame->sregs))
+		goto give_sigsegv;
+	if (__put_user(&frame->sregs, &frame->sc.sregs))
+		goto give_sigsegv;
 
-		err=__copy_to_user(&frame->sc.oldmask,&set->sig,_SIGMASK_COPY_SIZE);
-	if(!err)
-	{
-		regs->gprs[2]=(current->exec_domain
-		           && current->exec_domain->signal_invmap
-		           && sig < 32
-		           ? current->exec_domain->signal_invmap[sig]
-		           : sig);
-		/* Set up registers for signal handler */
-		regs->gprs[15] = (addr_t)frame;
-		regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
-		regs->psw.mask = _USER_PSW_MASK;
-	}
 	/* Set up to return from userspace.  If provided, use a stub
 	   already in userspace.  */
 	if (ka->sa.sa_flags & SA_RESTORER) {
                 regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer);
 	} else {
                 regs->gprs[14] = FIX_PSW(frame->retcode);
-		err |= __put_user(retcode, (u16 *)(frame->retcode));
+		if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, 
+	                       (u16 *)(frame->retcode)))
+			goto give_sigsegv;
 	}
-	return(err ? 0:frame);
-}
 
-static void setup_frame(int sig, struct k_sigaction *ka,
-			sigset_t *set, struct pt_regs * regs)
-{
-	sigframe *frame;
+	/* Set up registers for signal handler */
+	regs->gprs[15] = (addr_t)frame;
+	regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
+	regs->psw.mask = _USER_PSW_MASK;
 
-	if((frame=setup_frame_common(sig,ka,set,regs,sizeof(sigframe),
-		    (S390_SYSCALL_OPCODE|__NR_sigreturn)))==0)
-		goto give_sigsegv;
-#if DEBUG_SIG
-	printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
-		current->comm, current->pid, frame, regs->eip, frame->pretcode);
-#endif
-	/* Martin wants this for pthreads */
+	regs->gprs[2] = map_signal(sig);
 	regs->gprs[3] = (addr_t)&frame->sc;
 
 	/* We forgot to include these in the sigcontext.
@@ -375,34 +358,44 @@
 static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 			   sigset_t *set, struct pt_regs * regs)
 {
-	rt_sigframe *frame;
-	addr_t      orig_sp=regs->gprs[15];
-	int err;
+	int err = 0;
+	rt_sigframe *frame = get_sigframe(ka, regs, sizeof(rt_sigframe));
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe)))
+		goto give_sigsegv;
 
-	if((frame=setup_frame_common(sig,ka,set,regs,sizeof(rt_sigframe),
-		    (S390_SYSCALL_OPCODE|__NR_rt_sigreturn)))==0)
+	if (copy_siginfo_to_user(&frame->info, info))
 		goto give_sigsegv;
-	
-	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(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
-	err |= __put_user(sas_ss_flags(orig_sp),
+	err |= __put_user(sas_ss_flags(regs->gprs[15]),
 			  &frame->uc.uc_stack.ss_flags);
 	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
-	err |= __put_user(&frame->sc,&frame->uc.sc);
-	regs->gprs[3] = (addr_t)&frame->info;
-	regs->gprs[4] = (addr_t)&frame->uc;
-
+	err |= save_sigregs(regs, &frame->uc.uc_mcontext);
+	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 	if (err)
 		goto give_sigsegv;
 
-#if DEBUG_SIG
-	printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
-		current->comm, current->pid, frame, regs->eip, frame->pretcode);
-#endif
+	/* Set up to return from userspace.  If provided, use a stub
+	   already in userspace.  */
+	if (ka->sa.sa_flags & SA_RESTORER) {
+                regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer);
+	} else {
+                regs->gprs[14] = FIX_PSW(frame->retcode);
+		err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, 
+	                          (u16 *)(frame->retcode));
+	}
+
+	/* Set up registers for signal handler */
+	regs->gprs[15] = (addr_t)frame;
+	regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
+	regs->psw.mask = _USER_PSW_MASK;
+
+	regs->gprs[2] = map_signal(sig);
+	regs->gprs[3] = (addr_t)&frame->info;
+	regs->gprs[4] = (addr_t)&frame->uc;
 	return;
 
 give_sigsegv:
@@ -551,13 +544,16 @@
 					continue;
 				/* FALLTHRU */
 
-			case SIGSTOP:
+			case SIGSTOP: {
+				struct signal_struct *sig;
 				set_current_state(TASK_STOPPED);
 				current->exit_code = signr;
-				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
+				sig = current->p_pptr->sig;
+				if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
 					notify_parent(current, SIGCHLD);
 				schedule();
 				continue;
+			}
 
 			case SIGQUIT: case SIGILL: case SIGTRAP:
 			case SIGABRT: case SIGFPE: case SIGSEGV:
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/smp.c linux/arch/s390/kernel/smp.c
--- v2.4.12/linux/arch/s390/kernel/smp.c	Sun Aug 12 13:27:58 2001
+++ linux/arch/s390/kernel/smp.c	Thu Oct 11 09:04:57 2001
@@ -57,6 +57,8 @@
 
 spinlock_t       kernel_flag = SPIN_LOCK_UNLOCKED;
 
+unsigned long	 cpu_online_map;
+
 /*
  *      Setup routine for controlling SMP activation
  *
@@ -92,6 +94,95 @@
 
 extern void reipl(unsigned long devno);
 
+static sigp_ccode smp_ext_bitcall(int, ec_bit_sig);
+static void smp_ext_bitcall_others(ec_bit_sig);
+
+/*
+ * Structure and data for smp_call_function(). This is designed to minimise
+ * static memory requirements. It also looks cleaner.
+ */
+static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
+
+struct call_data_struct {
+	void (*func) (void *info);
+	void *info;
+	atomic_t started;
+	atomic_t finished;
+	int wait;
+};
+
+static struct call_data_struct * call_data;
+
+/*
+ * 'Call function' interrupt callback
+ */
+static void do_call_function(void)
+{
+	void (*func) (void *info) = call_data->func;
+	void *info = call_data->info;
+	int wait = call_data->wait;
+
+	atomic_inc(&call_data->started);
+	(*func)(info);
+	if (wait)
+		atomic_inc(&call_data->finished);
+}
+
+/*
+ * this function sends a 'generic call function' IPI to all other CPUs
+ * in the system.
+ */
+
+int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
+			int wait)
+/*
+ * [SUMMARY] Run a function on all other CPUs.
+ * <func> The function to run. This must be fast and non-blocking.
+ * <info> An arbitrary pointer to pass to the function.
+ * <nonatomic> currently unused.
+ * <wait> If true, wait (atomically) until function has completed on other CPUs.
+ * [RETURNS] 0 on success, else a negative status code. Does not return until
+ * remote CPUs are nearly ready to execute <<func>> or are or have executed.
+ *
+ * You must not call this function with disabled interrupts or from a
+ * hardware interrupt handler, you may call it from a bottom half handler.
+ */
+{
+	struct call_data_struct data;
+	int cpus = smp_num_cpus-1;
+
+	if (!cpus || !atomic_read(&smp_commenced))
+		return 0;
+
+	data.func = func;
+	data.info = info;
+	atomic_set(&data.started, 0);
+	data.wait = wait;
+	if (wait)
+		atomic_set(&data.finished, 0);
+
+	spin_lock_bh(&call_lock);
+	call_data = &data;
+	/* Send a message to all other CPUs and wait for them to respond */
+        smp_ext_bitcall_others(ec_call_function);
+
+	/* Wait for response */
+	while (atomic_read(&data.started) != cpus)
+		barrier();
+
+	if (wait)
+		while (atomic_read(&data.finished) != cpus)
+			barrier();
+	spin_unlock_bh(&call_lock);
+
+	return 0;
+}
+
+
+/*
+ * Various special callbacks
+ */
+
 void do_machine_restart(void)
 {
         smp_send_stop();
@@ -148,7 +239,6 @@
 
 void do_ext_call_interrupt(struct pt_regs *regs, __u16 code)
 {
-        ec_ext_call *ec, *next;
         int bits;
 
         /*
@@ -169,131 +259,15 @@
 		do_machine_halt();
         if (test_bit(ec_power_off, &bits))
 		do_machine_power_off();
-	if (test_bit(ec_ptlb, &bits))
-	        local_flush_tlb();
-
-        /*
-         * Handle external call commands with a parameter area
-         */
-        do {
-                ec = (ec_ext_call *) atomic_read(&S390_lowcore.ext_call_queue);
-        } while (atomic_compare_and_swap((int) ec, 0,
-                                         &S390_lowcore.ext_call_queue));
-        if (ec == NULL)
-                return;   /* no command signals */
-
-        /* Make a fifo out of the lifo */
-        next = ec->next;
-        ec->next = NULL;
-        while (next != NULL) {
-                ec_ext_call *tmp = next->next;
-                next->next = ec;
-                ec = next;
-                next = tmp;
-        }
-
-        /* Execute every sigp command on the queue */
-        while (ec != NULL) {
-                switch (ec->cmd) {
-                case ec_callback_async: {
-                        void (*func)(void *info);
-                        void *info;
-
-                        func = ec->func;
-                        info = ec->info;
-                        atomic_set(&ec->status,ec_executing);
-                        (func)(info);
-                        return;
-                }
-                case ec_callback_sync:
-                        atomic_set(&ec->status,ec_executing);
-                        (ec->func)(ec->info);
-                        atomic_set(&ec->status,ec_done);
-                        return;
-                default:
-                }
-                ec = ec->next;
-        }
-}
-
-/*
- * Send a callback sigp to another cpu.
- */
-sigp_ccode
-smp_ext_call(int cpu, void (*func)(void *info), void *info, int wait)
-{
-        struct _lowcore *lowcore = &get_cpu_lowcore(cpu);
-        sigp_ccode ccode;
-        ec_ext_call ec;
-
-        ec.cmd = wait ? ec_callback_sync : ec_callback_async;
-        atomic_set(&ec.status, ec_pending);
-	ec.func = func;
-        ec.info = info;
-        do {
-                ec.next = (ec_ext_call*) atomic_read(&lowcore->ext_call_queue);
-        } while (atomic_compare_and_swap((int) ec.next, (int)(&ec),
-                                         &lowcore->ext_call_queue));
-        /*
-         * We try once to deliver the signal. There are four possible
-         * return codes:
-         * 0) Order code accepted - can't show up on an external call
-         * 1) Status stored - fine, wait for completion.
-         * 2) Busy - there is another signal pending. Thats fine too, because
-         *    do_ext_call from the pending signal will execute all signals on
-         *    the queue. We wait for completion.
-         * 3) Not operational - something very bad has happened to the cpu.
-         *    do not wait for completion.
-         */
-        ccode = signal_processor(cpu, sigp_external_call);
-
-        if (ccode != sigp_not_operational)
-                /* wait for completion, FIXME: possible seed of a deadlock */
-                while (atomic_read(&ec.status) != (wait?ec_done:ec_executing));
-
-        return ccode;
-}
-
-/*
- * Send a callback sigp to every other cpu in the system.
- */
-void smp_ext_call_others(void (*func)(void *info), void *info, int wait)
-{
-        struct _lowcore *lowcore;
-        ec_ext_call ec[NR_CPUS];
-        sigp_ccode ccode;
-        int i;
-
-        for (i = 0; i < smp_num_cpus; i++) {
-                if (smp_processor_id() == i)
-                        continue;
-                lowcore = &get_cpu_lowcore(i);
-		ec[i].cmd = wait ? ec_callback_sync : ec_callback_async;
-		atomic_set(&ec[i].status, ec_pending);
-		ec[i].func = func;
-		ec[i].info = info;
-                do {
-                        ec[i].next = (ec_ext_call *)
-                                        atomic_read(&lowcore->ext_call_queue);
-                } while (atomic_compare_and_swap((int) ec[i].next, (int)(ec+i),
-                                                 &lowcore->ext_call_queue));
-                ccode = signal_processor(i, sigp_external_call);
-        }
-
-        /* wait for completion, FIXME: possible seed of a deadlock */
-        for (i = 0; i < smp_num_cpus; i++) {
-                if (smp_processor_id() == i)
-                        continue;
-                while (atomic_read(&ec[i].status) != 
-		       (wait ? ec_done:ec_executing));
-        }
+	if (test_bit(ec_call_function, &bits)) 
+		do_call_function();
 }
 
 /*
  * Send an external call sigp to another cpu and return without waiting
  * for its completion.
  */
-sigp_ccode smp_ext_bitcall(int cpu, ec_bit_sig sig)
+static sigp_ccode smp_ext_bitcall(int cpu, ec_bit_sig sig)
 {
         struct _lowcore *lowcore = &get_cpu_lowcore(cpu);
         sigp_ccode ccode;
@@ -310,7 +284,7 @@
  * Send an external call sigp to every other cpu in the system and
  * return without waiting for its completion.
  */
-void smp_ext_bitcall_others(ec_bit_sig sig)
+static void smp_ext_bitcall_others(ec_bit_sig sig)
 {
         struct _lowcore *lowcore;
         sigp_ccode ccode;
@@ -329,51 +303,6 @@
 }
 
 /*
- * cycles through all the cpus,
- * returns early if info is not NULL & the processor has something
- * of intrest to report in the info structure.
- * it returns the next cpu to check if it returns early.
- * i.e. it should be used as follows if you wish to receive info.
- * next_cpu=0;
- * do
- * {
- *    info->cpu=next_cpu;
- *    next_cpu=smp_signal_others(order_code,parameter,1,info);
- *    ... check info here
- * } while(next_cpu<=smp_num_cpus)
- *
- *  if you are lazy just use it like
- * smp_signal_others(order_code,parameter,0,1,NULL);
- */
-int smp_signal_others(sigp_order_code order_code, u32 parameter,
-                      int spin, sigp_info *info)
-{
-        sigp_ccode   ccode;
-        u32          dummy;
-        u16          i;
-
-        if (info)
-                info->intresting = 0;
-        for (i = (info ? info->cpu : 0); i < smp_num_cpus; i++) {
-                if (smp_processor_id() != i) {
-                        do {
-                                ccode = signal_processor_ps(
-                                        (info ? &info->status : &dummy),
-                                        parameter, i, order_code);
-                        } while(spin && ccode == sigp_busy);
-                        if (info && ccode != sigp_order_code_accepted) {
-                                info->intresting = 1;
-                                info->cpu = i;
-                                info->ccode = ccode;
-                                i++;
-                                break;
-                        }
-                }
-        }
-        return i;
-}
-
-/*
  * this function sends a 'stop' sigp to all other CPUs in the system.
  * it goes straight through.
  */
@@ -390,7 +319,18 @@
 
         /* stop all processors */
 
-        smp_signal_others(sigp_stop, 0, 1, NULL);
+        for (i =  0; i < smp_num_cpus; i++) {
+                if (smp_processor_id() != i) {
+                        int ccode;
+                        do {
+                                ccode = signal_processor_ps(
+                                   &dummy,
+                                   0,
+                                   i,
+                                   sigp_stop);
+                        } while(ccode == sigp_busy);
+                }
+        }
 
         /* store status of all processors in their lowcores (real 0) */
 
@@ -419,7 +359,7 @@
 
 void smp_ptlb_all(void)
 {
-        smp_ext_call_others(smp_ptlb_callback, NULL, 1);
+        smp_call_function(smp_ptlb_callback, NULL, 0, 1);
 	local_flush_tlb();
 }
 
@@ -482,7 +422,7 @@
                 parms.end_ctl = cr;
                 parms.orvals[cr] = 1 << bit;
                 parms.andvals[cr] = 0xFFFFFFFF;
-                smp_ext_call_others(smp_ctl_bit_callback, &parms, 1);
+                smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
         }
         __ctl_set_bit(cr, bit);
 }
@@ -498,36 +438,12 @@
                 parms.end_ctl = cr;
                 parms.orvals[cr] = 0x00000000;
                 parms.andvals[cr] = ~(1 << bit);
-                smp_ext_call_others(smp_ctl_bit_callback, &parms, 1);
+                smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
         }
         __ctl_clear_bit(cr, bit);
 }
 
 /*
- * Call a function on all other processors
- */
-
-int
-smp_call_function(void (*func)(void *info), void *info, int retry, int wait)
-/*
- * [SUMMARY] Run a function on all other CPUs.
- * <func> The function to run. This must be fast and non-blocking.
- * <info> An arbitrary pointer to pass to the function.
- * <retry> currently unused.
- * <wait> If true, wait (atomically) until function has completed on other CPUs.
- * [RETURNS] 0 on success, else a negative status code. Does not return until
- * remote CPUs are nearly ready to execute <<func>> or are or have executed.
- *
- * You must not call this function with disabled interrupts or from a
- * hardware interrupt handler, you may call it from a bottom half handler.
- */
-{
-        if (atomic_read(&smp_commenced) != 0)
-                smp_ext_call_others(func, info, wait);
-        return 0;
-}
-
-/*
  * Lets check how many CPUs we have.
  */
 
@@ -537,6 +453,7 @@
 
         current->processor = 0;
         smp_num_cpus = 1;
+	cpu_online_map = 1;
         for (curr_cpu = 0;
              curr_cpu <= 65535 && smp_num_cpus < max_cpus; curr_cpu++) {
                 if ((__u16) curr_cpu == boot_cpu_addr)
@@ -556,6 +473,7 @@
  *      Activate a secondary processor.
  */
 extern void init_100hz_timer(void);
+extern int pfault_init(void);
 extern int pfault_token(void);
 
 int __init start_secondary(void *cpuvoid)
@@ -620,15 +538,20 @@
         init_tasks[cpu] = idle;
 
         cpu_lowcore=&get_cpu_lowcore(cpu);
-        cpu_lowcore->kernel_stack=idle->thread.ksp;
-        __asm__ __volatile__("stctl 0,15,%0\n\t"
-                             "stam  0,15,%1"
+	cpu_lowcore->save_area[15] = idle->thread.ksp;
+	cpu_lowcore->kernel_stack = (idle->thread.ksp | 8191) + 1;
+        __asm__ __volatile__("la    1,%0\n\t"
+			     "stctl 0,15,0(1)\n\t"
+			     "la    1,%1\n\t"
+                             "stam  0,15,0(1)"
                              : "=m" (cpu_lowcore->cregs_save_area[0]),
                                "=m" (cpu_lowcore->access_regs_save_area[0])
-                             : : "memory");
+                             : : "1", "memory");
 
         eieio();
         signal_processor(cpu,sigp_restart);
+	/* Mark this cpu as online */
+	set_bit(cpu, &cpu_online_map);
 }
 
 /*
@@ -650,12 +573,12 @@
 }
 
 /*
- *	Cycle through the processors sending APIC IPIs to boot each.
+ *	Cycle through the processors sending sigp_restart to boot each.
  */
 
 void __init smp_boot_cpus(void)
 {
-        struct _lowcore *curr_lowcore;
+	unsigned long async_stack;
         sigp_ccode   ccode;
         int i;
 
@@ -680,34 +603,37 @@
 
         for(i = 0; i < smp_num_cpus; i++)
         {
-                curr_lowcore = (struct _lowcore *)
-                                    __get_free_page(GFP_KERNEL|GFP_DMA);
-                if (curr_lowcore == NULL) {
-                        printk("smp_boot_cpus failed to allocate prefix memory\n");
-                        break;
-                }
-                lowcore_ptr[i] = curr_lowcore;
-                memcpy(curr_lowcore, &S390_lowcore, sizeof(struct _lowcore));
+		lowcore_ptr[i] = (struct _lowcore *)
+			__get_free_page(GFP_KERNEL|GFP_DMA);
+                if (lowcore_ptr[i] == NULL)
+                        panic("smp_boot_cpus failed to "
+			      "allocate prefix memory\n");
+		async_stack = __get_free_pages(GFP_KERNEL,1);
+		if (async_stack == 0)
+			panic("smp_boot_cpus failed to allocate "
+			      "asyncronous interrupt stack\n");
+
+                memcpy(lowcore_ptr[i], &S390_lowcore, sizeof(struct _lowcore));
+		lowcore_ptr[i]->async_stack = async_stack + (2 * PAGE_SIZE);
                 /*
                  * Most of the parameters are set up when the cpu is
                  * started up.
                  */
-                if (smp_processor_id() == i)
-                        set_prefix((u32) curr_lowcore);
-                else {
-                        ccode = signal_processor_p((u32)(curr_lowcore),
-                                                   i, sigp_set_prefix);
-                        if(ccode) {
-                                /* if this gets troublesome I'll have to do
-                                 * something about it. */
-                                printk("ccode %d for cpu %d  returned when "
-                                       "setting prefix in smp_boot_cpus not good.\n",
-                                       (int) ccode, (int) i);
-                        }
-                        else
-                                do_boot_cpu(i);
-                }
-        }
+		if (smp_processor_id() == i)
+			set_prefix((u32) lowcore_ptr[i]);
+		else {
+			ccode = signal_processor_p((u32)(lowcore_ptr[i]),
+						   i, sigp_set_prefix);
+			if (ccode)
+				/* if this gets troublesome I'll have to do
+				 * something about it. */
+				printk("ccode %d for cpu %d  returned when "
+				       "setting prefix in smp_boot_cpus not good.\n",
+				       (int) ccode, (int) i);
+			else
+				do_boot_cpu(i);
+		}
+	}
 }
 
 /*
@@ -746,8 +672,6 @@
                 s390_do_profile(regs->psw.addr);
 
         if (!--prof_counter[cpu]) {
-                int system = 1-user;
-                struct task_struct * p = current;
 
                 /*
                  * The multiplier may have changed since the last time we got
@@ -771,9 +695,7 @@
                  * WrongThing (tm) to do.
                  */
 
-                irq_enter(cpu, 0);
 		update_process_times(user);
-                irq_exit(cpu, 0);
         }
 }
 
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/time.c linux/arch/s390/kernel/time.c
--- v2.4.12/linux/arch/s390/kernel/time.c	Sun Aug 12 13:27:58 2001
+++ linux/arch/s390/kernel/time.c	Thu Oct 11 09:04:57 2001
@@ -151,15 +151,14 @@
 
 void do_timer_interrupt(struct pt_regs *regs, __u16 error_code)
 {
-        unsigned long flags;
+	int cpu = smp_processor_id();
+
+	irq_enter(cpu, 0);
 
         /*
          * reset timer to 10ms minus time already elapsed
          * since timer-interrupt pending
          */
- 
-        save_flags(flags);
-        cli();
 #ifdef CONFIG_SMP
 	if(S390_lowcore.cpu_data.cpu_addr==boot_cpu_addr) {
 		write_lock(&xtime_lock);
@@ -195,8 +194,8 @@
 		write_unlock(&xtime_lock);
 #endif
 	}
-        restore_flags(flags);
 
+	irq_exit(cpu, 0);
 }
 
 /*
@@ -250,4 +249,7 @@
         init_timer_cc -= 0x8126d60e46000000LL -
                          (0x3c26700LL*1000000*4096);
         tod_to_timeval(init_timer_cc, &xtime);
+
+	/* Set do_get_fast_time function pointer.  */
+	do_get_fast_time = do_gettimeofday;
 }
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/traps.c linux/arch/s390/kernel/traps.c
--- v2.4.12/linux/arch/s390/kernel/traps.c	Sun Aug 12 13:27:58 2001
+++ linux/arch/s390/kernel/traps.c	Thu Oct 11 09:04:57 2001
@@ -60,14 +60,16 @@
 extern void pfault_interrupt(struct pt_regs *regs, __u16 error_code);
 #endif
 
-spinlock_t die_lock;
+spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
 
 void die(const char * str, struct pt_regs * regs, long err)
 {
         console_verbose();
         spin_lock_irq(&die_lock);
+	bust_spinlocks(1);
         printk("%s: %04lx\n", str, err & 0xffff);
         show_regs(regs);
+	bust_spinlocks(0);
         spin_unlock_irq(&die_lock);
         do_exit(SIGSEGV);
 }
@@ -135,7 +137,7 @@
 #if CONFIG_REMOTE_DEBUG
 		if(gdb_stub_initialised)
 		{
-			gdb_stub_handle_exception((gdb_pt_regs *)regs,signal);
+			gdb_stub_handle_exception((struct gdb_pt_regs *)regs,signal);
 			return 0;
 		}
 #endif
@@ -211,7 +213,7 @@
 specification_exception(struct pt_regs * regs, long interruption_code)
 {
         __u8 opcode[6];
-	__u16 *location;
+	__u16 *location = NULL;
 	int signal = 0;
 
         if (regs->psw.mask & PSW_PROBLEM_STATE) {
diff -u --recursive --new-file v2.4.12/linux/arch/s390/math-emu/math.c linux/arch/s390/math-emu/math.c
--- v2.4.12/linux/arch/s390/math-emu/math.c	Thu Apr 12 12:16:35 2001
+++ linux/arch/s390/math-emu/math.c	Thu Oct 11 09:04:57 2001
@@ -1471,20 +1471,98 @@
 }
 
 /* Test data class long double */
-static int emu_tcxb (int rx, double *val) {
-        display_emulation_not_implemented("tcxb");
+static int emu_tcxb (int rx, long val) {
+        FP_DECL_Q(QA);
+	mathemu_ldcv cvt;
+	int bit;
+
+        cvt.w.high = current->thread.fp_regs.fprs[rx].ui;
+        cvt.w.low = current->thread.fp_regs.fprs[rx+2].ui;
+        FP_UNPACK_RAW_QP(QA, &cvt.ld);
+	switch (QA_e) {
+	default:
+		bit = 8;		/* normalized number */
+		break;
+	case 0:
+		if (_FP_FRAC_ZEROP_4(QA))
+			bit = 10;	/* zero */
+		else
+			bit = 6;	/* denormalized number */
+		break;
+	case _FP_EXPMAX_Q:
+		if (_FP_FRAC_ZEROP_4(QA))
+			bit = 4;	/* infinity */
+		else if (_FP_FRAC_HIGH_RAW_Q(QA) & _FP_QNANBIT_Q)
+			bit = 2;	/* quiet NAN */
+		else
+			bit = 0;	/* signaling NAN */
+		break;
+	}
+	if (!QA_s)
+		bit++;
+	emu_set_CC(((__u32) val >> bit) & 1);
         return 0;
 }
 
 /* Test data class double */
-static int emu_tcdb (int rx, double *val) {
-        display_emulation_not_implemented("tcdb");
+static int emu_tcdb (int rx, long val) {
+        FP_DECL_D(DA);
+	int bit;
+
+        FP_UNPACK_RAW_DP(DA, &current->thread.fp_regs.fprs[rx].d);
+	switch (DA_e) {
+	default:
+		bit = 8;		/* normalized number */
+		break;
+	case 0:
+		if (_FP_FRAC_ZEROP_2(DA))
+			bit = 10;	/* zero */
+		else
+			bit = 6;	/* denormalized number */
+		break;
+	case _FP_EXPMAX_D:
+		if (_FP_FRAC_ZEROP_2(DA))
+			bit = 4;	/* infinity */
+		else if (_FP_FRAC_HIGH_RAW_D(DA) & _FP_QNANBIT_D)
+			bit = 2;	/* quiet NAN */
+		else
+			bit = 0;	/* signaling NAN */
+		break;
+	}
+	if (!DA_s)
+		bit++;
+	emu_set_CC(((__u32) val >> bit) & 1);
         return 0;
 }
 
 /* Test data class float */
-static int emu_tceb (int rx, __u32 val) {
-        display_emulation_not_implemented("tceb");
+static int emu_tceb (int rx, long val) {
+        FP_DECL_S(SA);
+	int bit;
+
+        FP_UNPACK_RAW_SP(SA, &current->thread.fp_regs.fprs[rx].f);
+	switch (SA_e) {
+	default:
+		bit = 8;		/* normalized number */
+		break;
+	case 0:
+		if (_FP_FRAC_ZEROP_1(SA))
+			bit = 10;	/* zero */
+		else
+			bit = 6;	/* denormalized number */
+		break;
+	case _FP_EXPMAX_S:
+		if (_FP_FRAC_ZEROP_1(SA))
+			bit = 4;	/* infinity */
+		else if (_FP_FRAC_HIGH_RAW_S(SA) & _FP_QNANBIT_S)
+			bit = 2;	/* quiet NAN */
+		else
+			bit = 0;	/* signaling NAN */
+		break;
+	}
+	if (!SA_s)
+		bit++;
+	emu_set_CC(((__u32) val >> bit) & 1);
         return 0;
 }
 
@@ -1796,13 +1874,13 @@
         int _fex = 0;
 
         static const __u8 format_table[256] = {
-                [0x04] = 0x08,[0x05] = 0x07,[0x06] = 0x09,[0x07] = 0x07,
-		[0x08] = 0x03,[0x09] = 0x03,[0x0a] = 0x03,[0x0b] = 0x03,
-		[0x0c] = 0x08,[0x0d] = 0x03,[0x0e] = 0x06,[0x0f] = 0x06,
-                [0x10] = 0x03,[0x11] = 0x02,[0x12] = 0x01,[0x14] = 0x03,
-		[0x15] = 0x02,[0x17] = 0x03,[0x18] = 0x02,[0x19] = 0x02,
-		[0x1a] = 0x02,[0x1b] = 0x02,[0x1c] = 0x02,[0x1d] = 0x02,
-                [0x1e] = 0x05,[0x1f] = 0x05,
+                [0x04] = 0x06,[0x05] = 0x05,[0x06] = 0x07,[0x07] = 0x05,
+		[0x08] = 0x02,[0x09] = 0x02,[0x0a] = 0x02,[0x0b] = 0x02,
+		[0x0c] = 0x06,[0x0d] = 0x02,[0x0e] = 0x04,[0x0f] = 0x04,
+                [0x10] = 0x08,[0x11] = 0x09,[0x12] = 0x0a,[0x14] = 0x02,
+		[0x15] = 0x01,[0x17] = 0x02,[0x18] = 0x01,[0x19] = 0x01,
+		[0x1a] = 0x01,[0x1b] = 0x01,[0x1c] = 0x01,[0x1d] = 0x01,
+                [0x1e] = 0x03,[0x1f] = 0x03,
         };
         static const void *jump_table[]= {
                 [0x04] = emu_ldeb,[0x05] = emu_lxdb,[0x06] = emu_lxeb,
@@ -1817,25 +1895,7 @@
         };
 
         switch (format_table[opcode[5]]) {
-        case 1: /* RXE format, long double constant */ {
-                __u64 *dxb, temp[2];
-                __u32 opc;
-
-                if ((opcode[1] >> 4) & 2)
-			return SIGILL;
-                emu_store_regd((opcode[1] >> 4) & 15);
-                emu_store_regd(((opcode[1] >> 4) & 15) + 2);
-                opc = *((__u32 *) opcode);
-                dxb = (__u64 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
-                mathemu_copy_from_user(&temp, dxb, 16);
-                /* call the emulation function */
-                _fex = ((int (*)(int, long double *)) jump_table[opcode[5]])
-                        (opcode[1] >> 4, (long double *) &temp);
-                emu_load_regd((opcode[1] >> 4) & 15);
-                emu_load_regd(((opcode[1] >> 4) & 15) + 2);
-                break;
-        }
-        case 2: /* RXE format, double constant */ {
+        case 1: /* RXE format, double constant */ {
                 __u64 *dxb, temp;
                 __u32 opc;
 
@@ -1849,7 +1909,7 @@
                 emu_load_regd((opcode[1] >> 4) & 15);
                 break;
         }
-        case 3: /* RXE format, float constant */ {
+        case 2: /* RXE format, float constant */ {
                 __u32 *dxb, temp;
                 __u32 opc;
 
@@ -1863,27 +1923,7 @@
                 emu_load_rege((opcode[1] >> 4) & 15);
                 break;
         }
-        case 4: /* RXF format, long double constant */ {
-                __u64 *dxb, temp[2];
-                __u32 opc;
-
-                if (((opcode[1] >> 4) & 0x20) || ((opcode[4] >> 4) & 0x20))
-			return SIGILL;
-                emu_store_regd((opcode[1] >> 4) & 15);
-                emu_store_regd(((opcode[1] >> 4) & 15) + 2);
-                emu_store_regd((opcode[4] >> 4) & 15);
-                emu_store_regd(((opcode[4] >> 4) & 15) + 2);
-                opc = *((__u32 *) opcode);
-                dxb = (__u64 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
-                mathemu_copy_from_user(&temp, dxb, 16);
-                /* call the emulation function */
-                _fex = ((int (*)(int,long double *,int)) jump_table[opcode[5]])
-                        (opcode[1] >> 4, (double *) &temp, opcode[4] >> 4);
-                emu_load_regd((opcode[1] >> 4) & 15);
-                emu_load_regd(((opcode[1] >> 4) & 15) + 2);
-                break;
-        }
-        case 5: /* RXF format, double constant */ {
+        case 3: /* RXF format, double constant */ {
                 __u64 *dxb, temp;
                 __u32 opc;
 
@@ -1898,7 +1938,7 @@
                 emu_load_regd((opcode[1] >> 4) & 15);
                 break;
         }
-        case 6: /* RXF format, float constant */ {
+        case 4: /* RXF format, float constant */ {
                 __u32 *dxb, temp;
                 __u32 opc;
 
@@ -1913,7 +1953,7 @@
                 emu_load_rege((opcode[4] >> 4) & 15);
                 break;
         }
-        case 7: /* RXE format, double constant */
+        case 5: /* RXE format, double constant */
                 /* store double and load long double */ 
         {
                 __u64 *dxb, temp;
@@ -1931,7 +1971,7 @@
                 emu_load_regd(((opcode[1] >> 4) & 15) + 2);
                 break;
         }
-        case 8: /* RXE format, float constant */
+        case 6: /* RXE format, float constant */
                 /* store float and load double */ 
         {
                 __u32 *dxb, temp;
@@ -1946,7 +1986,7 @@
                 emu_load_regd((opcode[1] >> 4) & 15);
                 break;
         }
-        case 9: /* RXE format, float constant */
+        case 7: /* RXE format, float constant */
                 /* store float and load long double */ 
         {
                 __u32 *dxb, temp;
@@ -1962,6 +2002,45 @@
                         (opcode[1] >> 4, (float *) &temp);
                 emu_load_regd((opcode[1] >> 4) & 15);
                 emu_load_regd(((opcode[1] >> 4) & 15) + 2);
+                break;
+        }
+        case 8: /* RXE format, RX address used as int value */ {
+                __u64 dxb;
+                __u32 opc;
+
+                emu_store_rege((opcode[1] >> 4) & 15);
+                opc = *((__u32 *) opcode);
+                dxb = (__u64) calc_addr(regs, opc >> 16, opc >> 12, opc);
+                /* call the emulation function */
+                _fex = ((int (*)(int, long)) jump_table[opcode[5]])
+                        (opcode[1] >> 4, dxb);
+                break;
+        }
+        case 9: /* RXE format, RX address used as int value */ {
+                __u64 dxb;
+                __u32 opc;
+
+                emu_store_regd((opcode[1] >> 4) & 15);
+                opc = *((__u32 *) opcode);
+                dxb = (__u64) calc_addr(regs, opc >> 16, opc >> 12, opc);
+                /* call the emulation function */
+                _fex = ((int (*)(int, long)) jump_table[opcode[5]])
+                        (opcode[1] >> 4, dxb);
+                break;
+        }
+        case 10: /* RXE format, RX address used as int value */ {
+                __u64 dxb;
+                __u32 opc;
+
+                if ((opcode[1] >> 4) & 2)
+			return SIGILL;
+                emu_store_regd((opcode[1] >> 4) & 15);
+                emu_store_regd(((opcode[1] >> 4) & 15) + 2);
+                opc = *((__u32 *) opcode);
+                dxb = (__u64) calc_addr(regs, opc >> 16, opc >> 12, opc);
+                /* call the emulation function */
+                _fex = ((int (*)(int, long)) jump_table[opcode[5]])
+                        (opcode[1] >> 4, dxb);
                 break;
         }
         default: /* invalid operation */
diff -u --recursive --new-file v2.4.12/linux/arch/s390/mm/extable.c linux/arch/s390/mm/extable.c
--- v2.4.12/linux/arch/s390/mm/extable.c	Fri May 12 11:41:45 2000
+++ linux/arch/s390/mm/extable.c	Thu Oct 11 09:04:57 2001
@@ -10,6 +10,7 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/spinlock.h>
 #include <asm/uaccess.h>
 
 extern const struct exception_table_entry __start___ex_table[];
@@ -36,28 +37,37 @@
         return 0;
 }
 
+extern spinlock_t modlist_lock;
+
 unsigned long
 search_exception_table(unsigned long addr)
 {
-	unsigned long ret;
+	unsigned long ret = 0;
+	unsigned long flags;
 
 #ifndef CONFIG_MODULES
         addr &= 0x7fffffff;  /* remove amode bit from address */
 	/* There is only the kernel to search.  */
 	ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
-	if (ret) return FIX_PSW(ret);
+	if (ret) ret = FIX_PSW(ret);
+	return ret;
 #else
 	/* The kernel is the last "module" -- no need to treat it special.  */
 	struct module *mp;
         addr &= 0x7fffffff;  /* remove amode bit from address */
+
+	spin_lock_irqsave(&modlist_lock, flags);
 	for (mp = module_list; mp != NULL; mp = mp->next) {
-		if (mp->ex_table_start == NULL)
+		if (mp->ex_table_start == NULL || !(mp->flags&(MOD_RUNNING|MOD_INITIALIZING)))
 			continue;
 		ret = search_one_table(mp->ex_table_start,
 				       mp->ex_table_end - 1, addr);
-		if (ret) return FIX_PSW(ret);
+		if (ret) {
+			ret = FIX_PSW(ret);
+			break;
+		}
 	}
+	spin_unlock_irqrestore(&modlist_lock, flags);
+	return ret;
 #endif
-
-	return 0;
 }
diff -u --recursive --new-file v2.4.12/linux/arch/s390/mm/fault.c linux/arch/s390/mm/fault.c
--- v2.4.12/linux/arch/s390/mm/fault.c	Sun Aug 12 13:27:58 2001
+++ linux/arch/s390/mm/fault.c	Thu Oct 11 09:04:57 2001
@@ -4,6 +4,7 @@
  *  S390 version
  *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
  *    Author(s): Hartmut Penner (hp@de.ibm.com)
+ *               Ulrich Weigand (uweigand@de.ibm.com)
  *
  *  Derived from "arch/i386/mm/fault.c"
  *    Copyright (C) 1995  Linus Torvalds
@@ -23,6 +24,7 @@
 #include <linux/smp_lock.h>
 #include <linux/compatmac.h>
 #include <linux/init.h>
+#include <linux/console.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -34,6 +36,34 @@
 #endif
 
 extern void die(const char *,struct pt_regs *,long);
+static void force_sigsegv(struct task_struct *tsk, int code, void *address);
+
+extern spinlock_t timerlist_lock;
+
+/*
+ * Unlock any spinlocks which will prevent us from getting the
+ * message out (timerlist_lock is acquired through the
+ * console unblank code)
+ */
+void bust_spinlocks(int yes)
+{
+	spin_lock_init(&timerlist_lock);
+	if (yes) {
+		oops_in_progress = 1;
+	} else {
+		int loglevel_save = console_loglevel;
+		oops_in_progress = 0;
+		console_unblank();
+		/*
+		 * OK, the message is on the console.  Now we call printk()
+		 * without oops_in_progress set so that printk will give klogd
+		 * a poke.  Hold onto your hats...
+		 */
+		console_loglevel = 15;
+		printk(" ");
+		console_loglevel = loglevel_save;
+	}
+}
 
 /*
  * This routine handles page faults.  It determines the address,
@@ -56,18 +86,36 @@
 	int si_code = SEGV_MAPERR;
 	int kernel_address = 0;
 
+        tsk = current;
+        mm = tsk->mm;
+	
+	/* 
+         * Check for low-address protection.  This needs to be treated
+	 * as a special case because the translation exception code 
+	 * field is not guaranteed to contain valid data in this case.
+	 */
+	if ((error_code & 0xff) == 4 && !(S390_lowcore.trans_exc_code & 4)) {
+
+		/* Low-address protection hit in kernel mode means 
+		   NULL pointer write access in kernel mode.  */
+ 		if (!(regs->psw.mask & PSW_PROBLEM_STATE)) {
+			address = 0;
+			kernel_address = 1;
+			goto no_context;
+		}
+
+		/* Low-address protection hit in user mode 'cannot happen'.  */
+		die ("Low-address protection", regs, error_code);
+        	do_exit(SIGKILL);
+	}
+
         /* 
          * get the failing address 
          * more specific the segment and page table portion of 
          * the address 
          */
-        address = S390_lowcore.trans_exc_code&0x7ffff000;
 
-        tsk = current;
-        mm = tsk->mm;
-
-        if (in_interrupt() || !mm)
-                goto no_context;
+        address = S390_lowcore.trans_exc_code&0x7ffff000;
 
 
 	/*
@@ -99,6 +147,7 @@
 			}
 		}
 		die("page fault via unknown access register", regs, error_code);
+        	do_exit(SIGKILL);
 		break;
 
 	case 2: /* Secondary Segment Table Descriptor */
@@ -107,6 +156,11 @@
 		break;
 	}
 
+	/*
+	 * Check whether we have a user MM in the first place.
+	 */
+        if (in_interrupt() || !mm)
+                goto no_context;
 
 	/*
 	 * When we get here, the fault happened in the current
@@ -146,6 +200,7 @@
                        goto bad_area;
         }
 
+ survive:
 	/*
 	 * If for any reason at all we couldn't handle the fault,
 	 * make sure we exit gracefully rather than endlessly redo
@@ -176,7 +231,6 @@
 
         /* User mode accesses just cause a SIGSEGV */
         if (regs->psw.mask & PSW_PROBLEM_STATE) {
-		struct siginfo si;
                 tsk->thread.prot_addr = address;
                 tsk->thread.trap_no = error_code;
 #ifndef CONFIG_SYSCTL
@@ -193,10 +247,8 @@
 			show_regs(regs);
 		}
 #endif
-		si.si_signo = SIGSEGV;
-		si.si_code = si_code;
-		si.si_addr = (void*) address;
-		force_sig_info(SIGSEGV, &si, tsk);
+
+		force_sigsegv(tsk, si_code, (void *)address);
                 return;
 	}
 
@@ -218,9 +270,6 @@
         else
                 printk(KERN_ALERT "Unable to handle kernel paging request"
 		       " at virtual user address %08lx\n", address);
-/*
- * need to define, which information is useful here
- */
 
         die("Oops", regs, error_code);
         do_exit(SIGKILL);
@@ -232,6 +281,12 @@
 */
 out_of_memory:
 	up_read(&mm->mmap_sem);
+	if (tsk->pid == 1) {
+		tsk->policy |= SCHED_YIELD;
+		schedule();
+		down_read(&mm->mmap_sem);
+		goto survive;
+	}
 	printk("VM: killing process %s\n", tsk->comm);
 	if (regs->psw.mask & PSW_PROBLEM_STATE)
 		do_exit(SIGKILL);
@@ -253,6 +308,18 @@
 		goto no_context;
 }
 
+/*
+ * Send SIGSEGV to task.  This is an external routine
+ * to keep the stack usage of do_page_fault small.
+ */
+static void force_sigsegv(struct task_struct *tsk, int code, void *address)
+{
+	struct siginfo si;
+	si.si_signo = SIGSEGV;
+	si.si_code = code;
+	si.si_addr = address;
+	force_sig_info(SIGSEGV, &si, tsk);
+}
 
 typedef struct _pseudo_wait_t {
        struct _pseudo_wait_t *next;
@@ -434,7 +501,6 @@
 asmlinkage void
 pfault_interrupt(struct pt_regs *regs, __u16 error_code)
 {
-        DECLARE_WAITQUEUE(wait, current);
 	struct task_struct *tsk;
 	wait_queue_head_t queue;
 	wait_queue_head_t *qp;
@@ -447,7 +513,7 @@
          * external interrupt. 
 	 */
 	subcode = S390_lowcore.cpu_addr;
-	if ((subcode & 0xff00) != 0x06)
+	if ((subcode & 0xff00) != 0x0600)
 		return;
 
 	/*
diff -u --recursive --new-file v2.4.12/linux/arch/s390/mm/init.c linux/arch/s390/mm/init.c
--- v2.4.12/linux/arch/s390/mm/init.c	Sun Sep 23 11:40:56 2001
+++ linux/arch/s390/mm/init.c	Thu Oct 11 09:04:57 2001
@@ -44,44 +44,23 @@
 pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE)));
 char  empty_zero_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
 
-static int test_access(unsigned long loc)
-{
-	static const int ssm_mask = 0x07000000L;
-	int rc, i;
-
-        rc = 0;
-	for (i=0; i<4; i++) {
-		__asm__ __volatile__(
-                        "    slr   %0,%0\n"
-			"    ssm   %1\n"
-			"    tprot 0(%2),0\n"
-			"0:  jne   1f\n"
-			"    lhi   %0,1\n"
-			"1:  ssm   %3\n"
-                        ".section __ex_table,\"a\"\n"
-                        "   .align 4\n"
-                        "   .long  0b,1b\n"
-                        ".previous"
-			: "+&d" (rc) : "i" (0), "a" (loc), "m" (ssm_mask)
-			: "cc");
-		if (rc == 0)
-			break;
-		loc += 0x100000;
-	}
-	return rc;
-}
-
 int do_check_pgt_cache(int low, int high)
 {
         int freed = 0;
         if(pgtable_cache_size > high) {
                 do {
-                        if(pgd_quicklist)
-                                free_pgd_slow(get_pgd_fast()), freed += 2;
-                        if(pmd_quicklist)
-                                pmd_free_slow(pmd_alloc_one_fast(NULL, 0)), freed++;
-                        if(pte_quicklist)
-                                pte_free_slow(pte_alloc_one_fast(NULL, 0)), freed++;
+                        if(pgd_quicklist) {
+                                free_pgd_slow(get_pgd_fast());
+				freed += 2;
+			}
+                        if(pmd_quicklist) {
+                                pmd_free_slow(pmd_alloc_one_fast(NULL, 0));
+				freed++;
+			}
+                        if(pte_quicklist) {
+                                pte_free_slow(pte_alloc_one_fast(NULL, 0));
+				freed++;
+			}
                 } while(pgtable_cache_size > low);
         }
         return freed;
@@ -200,7 +179,6 @@
 void __init mem_init(void)
 {
 	int codesize, reservedpages, datasize, initsize;
-        int tmp;
 
         max_mapnr = num_physpages = max_low_pfn;
         high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
@@ -211,24 +189,7 @@
 	/* this will put all low memory onto the freelists */
 	totalram_pages += free_all_bootmem();
 
-        /* mark usable pages in the mem_map[] and count reserved pages */
 	reservedpages = 0;
-	tmp = 0;
-	do {
-		if (tmp && (tmp & 0x3ff) == 0 && 
-                    test_access(tmp * PAGE_SIZE) == 0) {
-                        printk("4M Segment %lX not available\n",tmp*PAGE_SIZE);
-			do {
-                                set_bit(PG_reserved, &mem_map[tmp].flags);
-				reservedpages++;
-				tmp++;
-			} while (tmp < max_low_pfn && (tmp & 0x3ff));
-		} else {
-			if (PageReserved(mem_map+tmp))
-				reservedpages++;
-			tmp++;
-		}
-	} while (tmp < max_low_pfn);
 
 	codesize =  (unsigned long) &_etext - (unsigned long) &_text;
 	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/Makefile linux/arch/s390x/Makefile
--- v2.4.12/linux/arch/s390x/Makefile	Sun Aug 12 13:27:58 2001
+++ linux/arch/s390x/Makefile	Thu Oct 11 09:04:57 2001
@@ -52,16 +52,6 @@
 
 MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
 
-MAKESILO = $(MAKE) -C arch/$(ARCH)/tools/silo
-
-MAKEDASDFMT = $(MAKE) -C arch/$(ARCH)/tools/dasdfmt
-
-silo:
-	@$(MAKE) -C arch/$(ARCH)/tools/silo
-
-dasdfmt:
-	@$(MAKE) -C arch/$(ARCH)/tools/dasdfmt
-
 image: vmlinux 
 	@$(MAKEBOOT) image
 
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/config.in linux/arch/s390x/config.in
--- v2.4.12/linux/arch/s390x/config.in	Sun Aug 12 13:27:58 2001
+++ linux/arch/s390x/config.in	Thu Oct 11 09:04:57 2001
@@ -8,6 +8,7 @@
 define_bool CONFIG_MCA n
 define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
 define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+define_bool CONFIG_GENERIC_BUST_SPINLOCK n
 
 mainmenu_name "Linux Kernel Configuration"
 define_bool CONFIG_ARCH_S390 y
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/defconfig linux/arch/s390x/defconfig
--- v2.4.12/linux/arch/s390x/defconfig	Sun Aug 12 13:27:58 2001
+++ linux/arch/s390x/defconfig	Thu Oct 11 09:04:57 2001
@@ -6,6 +6,7 @@
 # CONFIG_MCA is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_GENERIC_BUST_SPINLOCK=n
 CONFIG_ARCH_S390=y
 CONFIG_ARCH_S390X=y
 
@@ -72,6 +73,7 @@
 CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
 CONFIG_MD_RAID5=m
+# CONFIG_MD_MULTIPATH is not set
 CONFIG_BLK_DEV_LVM=m
 
 #
@@ -247,6 +249,7 @@
 CONFIG_IBM_PARTITION=y
 # CONFIG_MAC_PARTITION is not set
 # CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/Makefile linux/arch/s390x/kernel/Makefile
--- v2.4.12/linux/arch/s390x/kernel/Makefile	Wed Apr 11 19:02:29 2001
+++ linux/arch/s390x/kernel/Makefile	Thu Oct 11 09:04:57 2001
@@ -12,12 +12,14 @@
 
 all: kernel.o head.o init_task.o
 
-O_TARGET := kernel.o
+O_TARGET	:= kernel.o
 
-export-objs	:= debug.o ebcdic.o irq.o s390_ext.o smp.o s390_ksyms.o
-obj-y	:= lowcore.o entry.o bitmap.o traps.o time.o process.o irq.o \
-            setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
-            semaphore.o s390fpu.o reipl.o s390_ext.o debug.o
+export-objs	:= debug.o ebcdic.o irq.o s390_ext.o smp.o s390_ksyms.o \
+		   exec32.o
+
+obj-y		:= entry.o bitmap.o traps.o time.o process.o irq.o \
+		   setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
+		   semaphore.o s390fpu.o reipl.o s390_ext.o debug.o
 
 obj-$(CONFIG_MODULES)		+= s390_ksyms.o
 obj-$(CONFIG_SMP)		+= smp.o
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/cpcmd.c linux/arch/s390x/kernel/cpcmd.c
--- v2.4.12/linux/arch/s390x/kernel/cpcmd.c	Wed Apr 11 19:02:29 2001
+++ linux/arch/s390x/kernel/cpcmd.c	Thu Oct 11 09:04:57 2001
@@ -6,21 +6,25 @@
  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
  */
 
-#include <linux/stddef.h>
-#include <linux/kernel.h>
 #include <linux/string.h>
-#include <asm/ebcdic.h>
+#include <linux/spinlock.h>
 #include <asm/cpcmd.h>
+#include <asm/ebcdic.h>
+#include <asm/system.h>
+
+static spinlock_t cpcmd_lock = SPIN_LOCK_UNLOCKED;
+static char cpcmd_buf[128];
 
 void cpcmd(char *cmd, char *response, int rlen)
 {
         const int mask = 0x40000000L;
-        char obuffer[128];
-        int olen;
+	unsigned long flags;
+        int cmdlen;
 
-        olen = strlen(cmd);
-        strcpy(obuffer, cmd);
-        ASCEBC(obuffer,olen);
+	spin_lock_irqsave(&cpcmd_lock, flags);
+        cmdlen = strlen(cmd);
+        strcpy(cpcmd_buf, cmd);
+        ASCEBC(cpcmd_buf, cmdlen);
 
         if (response != NULL && rlen > 0) {
                 asm volatile ("   lrag  2,0(%0)\n"
@@ -32,7 +36,7 @@
                               "   .long 0x83240008 # Diagnose 83\n"
                               "   sam64"
                               : /* no output */
-                              : "a" (obuffer), "d" (olen),
+                              : "a" (cpcmd_buf), "d" (cmdlen),
                                 "a" (response), "d" (rlen), "m" (mask)
                               : "2", "3", "4", "5" );
                 EBCASC(response, rlen);
@@ -43,8 +47,9 @@
                               "   .long 0x83230008 # Diagnose 83\n"
                               "   sam64"
                               : /* no output */
-                              : "a" (obuffer), "d" (olen)
+                              : "a" (cpcmd_buf), "d" (cmdlen)
                               : "2", "3"  );
         }
+	spin_unlock_irqrestore(&cpcmd_lock, flags);
 }
 
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/debug.c linux/arch/s390x/kernel/debug.c
--- v2.4.12/linux/arch/s390x/kernel/debug.c	Sun Aug 12 13:27:58 2001
+++ linux/arch/s390x/kernel/debug.c	Thu Oct 11 09:04:57 2001
@@ -83,6 +83,9 @@
 static int debug_input_level_fn(debug_info_t * id, struct debug_view *view,
 				struct file *file, const char *user_buf,
 				size_t user_buf_size, loff_t * offset);
+static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
+                                struct file *file, const char *user_buf,
+                                size_t user_buf_size, loff_t * offset);
 static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view,
                                 char *out_buf, const char *in_buf);
 static int debug_raw_format_fn(debug_info_t * id,
@@ -123,6 +126,15 @@
 	NULL
 };
 
+struct debug_view debug_flush_view = {
+        "flush",
+        NULL,
+        NULL,
+        NULL,
+        &debug_input_flush_fn,
+        NULL
+};
+
 struct debug_view debug_sprintf_view = {
 	"sprintf",
 	NULL,
@@ -664,6 +676,7 @@
 	if(!rc) 
 		goto out;
 	debug_register_view(rc, &debug_level_view);
+        debug_register_view(rc, &debug_flush_view);
 	printk(KERN_INFO
 	       "debug: reserved %d areas of %d pages for debugging %s\n",
 	       nr_areas, 1 << page_order, rc->name);
@@ -1027,6 +1040,73 @@
       out:
 	*offset += in_buf_size;
 	return rc;		/* number of input characters */
+}
+
+
+/*
+ * flushes debug areas
+ */
+ 
+void debug_flush(debug_info_t* id, int area)
+{
+        unsigned long flags;
+        int i;
+
+        if(!id)
+                return;
+        spin_lock_irqsave(&id->lock,flags);
+        if(area == DEBUG_FLUSH_ALL){
+                id->active_area = 0;
+                memset(id->active_entry, 0, id->nr_areas * sizeof(int));
+                for (i = 0; i < id->nr_areas; i++) 
+                        memset(id->areas[i], 0, PAGE_SIZE << id->page_order);
+                printk(KERN_INFO "debug: %s: all areas flushed\n",id->name);
+        } else if(area >= 0 && area < id->nr_areas) {
+                id->active_entry[area] = 0;
+                memset(id->areas[area], 0, PAGE_SIZE << id->page_order);
+                printk(KERN_INFO
+                        "debug: %s: area %i has been flushed\n",
+                        id->name, area);
+        } else {
+                printk(KERN_INFO
+                        "debug: %s: area %i cannot be flushed (range: %i - %i)\n",
+                        id->name, area, 0, id->nr_areas-1);
+        }
+        spin_unlock_irqrestore(&id->lock,flags);
+}
+
+/*
+ * view function: flushes debug areas 
+ */
+ 
+static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
+                                struct file *file, const char *user_buf,
+                                size_t in_buf_size, loff_t * offset)
+{
+        char input_buf[1];
+        int rc = in_buf_size;
+ 
+        if (*offset != 0)
+                goto out;
+        if (copy_from_user(input_buf, user_buf, 1)){
+                rc = -EFAULT;
+                goto out;
+        }
+        if(input_buf[0] == '-') { 
+                debug_flush(id, DEBUG_FLUSH_ALL);
+                goto out;
+        }
+        if (isdigit(input_buf[0])) {
+                int area = ((int) input_buf[0] - (int) '0');
+                debug_flush(id, area);
+                goto out;
+        }
+
+        printk(KERN_INFO "debug: area `%c` is not valid\n", input_buf[0]);
+
+      out:
+        *offset += in_buf_size;
+        return rc;              /* number of input characters */
 }
 
 /*
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/entry.S linux/arch/s390x/kernel/entry.S
--- v2.4.12/linux/arch/s390x/kernel/entry.S	Tue Oct  9 17:06:51 2001
+++ linux/arch/s390x/kernel/entry.S	Thu Oct 11 09:04:57 2001
@@ -89,17 +89,25 @@
  *    R15 - kernel stack pointer
  */
 
-        .macro  SAVE_ALL psworg          # system entry macro
+        .macro  SAVE_ALL psworg,sync     # system entry macro
         stmg    %r14,%r15,__LC_SAVE_AREA
-        stam    %a2,%a4,__LC_SAVE_AREA+16
         tm      \psworg+1,0x01           # test problem state bit
-        jz      0f                       # skip stack setup save
-        lg      %r15,__LC_KERNEL_STACK   # problem state -> load ksp
-        slr     %r14,%r14
-        sar     %a2,%r14                 # set ac.reg. 2 to primary space
-        lhi     %r14,1
-        sar     %a4,%r14                 # set access reg. 4 to home space
-0:      aghi    %r15,-SP_SIZE            # make room for registers & psw
+	stam    %a2,%a4,__LC_SAVE_AREA+16
+	.if	\sync
+        jz      1f                       # skip stack setup save
+	.else
+	jnz	0f			 # from user -> load kernel stack
+	lg	%r14,__LC_ASYNC_STACK	 # are we already on the async. stack ?
+	slgr	%r14,%r15
+	srag	%r14,%r14,14
+	jz	1f
+	lg	%r15,__LC_ASYNC_STACK	 # load async. stack
+	j	1f
+	.endif
+0:	lg      %r15,__LC_KERNEL_STACK   # problem state -> load ksp
+	larl	%r14,.Lc_ac
+	lam	%a2,%a4,0(%r14)
+1:      aghi    %r15,-SP_SIZE            # make room for registers & psw
         nill    %r15,0xfff8              # align stack pointer to 8
         stmg    %r0,%r14,SP_R0(%r15)     # store gprs 0-14 to kernel stack
         stg     %r2,SP_ORIG_R2(%r15)     # store original content of gpr 2
@@ -112,7 +120,7 @@
         xc      0(8,%r15),0(%r15)        # clear back chain
         .endm
 
-        .macro  RESTORE_ALL              # system exit macro
+        .macro  RESTORE_ALL sync         # system exit macro
         mvc     __LC_RETURN_PSW(16),SP_PSW(%r15) # move user PSW to lowcore
         lam     %a0,%a15,SP_AREGS(%r15)  # load the access registers
         lmg     %r0,%r15,SP_R0(%r15)     # load gprs 0-15 of user
@@ -121,8 +129,8 @@
         .endm
 
         .macro  GET_CURRENT
-        lghi    %r9,-16384               # load pointer to task_struct to %r9
-        ngr     %r9,15
+	lg	%r9,__LC_KERNEL_STACK    # load pointer to task_struct to %r9
+	aghi	%r9,-16384
         .endm
 
 
@@ -161,13 +169,32 @@
         br      %r14
 
 /*
+ * do_softirq calling function. We want to run the softirq functions on the
+ * asynchronous interrupt stack.
+ */
+	.global do_call_softirq
+do_call_softirq:
+	stmg	%r12,%r15,48(%r15)
+	lgr	%r12,%r15
+	lg	%r0,__LC_ASYNC_STACK
+	slgr    %r0,%r15
+	srag	%r0,%r0,14
+	je	0f
+	lg	%r15,__LC_ASYNC_STACK
+0:	aghi	%r15,-STACK_FRAME_OVERHEAD
+	stg	%r12,0(%r15)		# store back chain
+	brasl	%r14,do_softirq
+	lmg	%r12,%r15,48(%r12)
+	br	%r14
+	
+/*
  * SVC interrupt handler routine. System calls are synchronous events and
  * are executed with interrupts enabled.
  */
 
 	.globl  system_call
 system_call:
-        SAVE_ALL __LC_SVC_OLD_PSW
+        SAVE_ALL __LC_SVC_OLD_PSW,1
 	mvi     SP_PGM_OLD_ILC(%r15),1  # mark PGM_OLD_ILC as invalid
 pgm_system_call:
         GET_CURRENT               # load pointer to task_struct to R9
@@ -202,7 +229,7 @@
         tm      SP_PGM_OLD_ILC(%r15),0xff
         jz      pgm_svcret
 	stnsm   48(%r15),0xfc         # disable I/O and ext. interrupts
-        RESTORE_ALL
+        RESTORE_ALL 1
 
 #
 # call do_signal before return
@@ -565,9 +592,9 @@
 	.long  SYSCALL(sys_mmap2,sys32_mmap2_wrapper)
 	.long  SYSCALL(sys_ni_syscall,sys32_truncate64_wrapper)
         .long  SYSCALL(sys_ni_syscall,sys32_ftruncate64_wrapper)
-        .long  SYSCALL(sys_ni_syscall,sys32_stat64)     /* 195 */
-        .long  SYSCALL(sys_ni_syscall,sys32_lstat64)   
-        .long  SYSCALL(sys_ni_syscall,sys32_fstat64)    
+        .long  SYSCALL(sys_ni_syscall,sys32_stat64_wrapper)     /* 195 */
+        .long  SYSCALL(sys_ni_syscall,sys32_lstat64_wrapper)   
+        .long  SYSCALL(sys_ni_syscall,sys32_fstat64_wrapper)    
 	.long  SYSCALL(sys_lchown,sys32_lchown_wrapper)
 	.long  SYSCALL(sys_getuid,sys_getuid)
 	.long  SYSCALL(sys_getgid,sys_getgid)         /* 200 */
@@ -592,7 +619,10 @@
         .long  SYSCALL(sys_madvise,sys32_madvise_wrapper)
 	.long  SYSCALL(sys_getdents64,sys32_getdents64_wrapper)/* 220 */
 	.long  SYSCALL(sys_ni_syscall,sys32_fcntl64_wrapper)
-        .rept  255-221
+	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 222 - reserved for posix_acl */
+	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 223 - reserved for posix_acl */
+	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 224 - reserved for posix_acl */
+        .rept  255-224
 	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
 	.endr
 
@@ -626,7 +656,7 @@
 	lpswe   __LC_PGM_OLD_PSW
 # it was a single stepped SVC that is causing all the trouble
 pgm_svcper:
-	SAVE_ALL __LC_SVC_OLD_PSW
+	SAVE_ALL __LC_SVC_OLD_PSW,1
         mvc     SP_PGM_OLD_ILC(4,%r15),__LC_PGM_ILC # save program check information
         j       pgm_system_call          # now do the svc
 pgm_svcret:
@@ -636,7 +666,7 @@
         mvi     SP_PGM_OLD_ILC(%r15),1   # mark PGM_OLD_ILC as invalid
 	j       pgm_no_sv
 pgm_sv:
-	SAVE_ALL __LC_PGM_OLD_PSW
+	SAVE_ALL __LC_PGM_OLD_PSW,1
         mvi     SP_PGM_OLD_ILC(%r15),1   # mark PGM_OLD_ILC as invalid
         llgh    %r7,__LC_PGM_ILC         # load instruction length
 	GET_CURRENT
@@ -668,7 +698,7 @@
  */
         .globl io_int_handler
 io_int_handler:
-        SAVE_ALL __LC_IO_OLD_PSW
+        SAVE_ALL __LC_IO_OLD_PSW,0
         GET_CURRENT                    # load pointer to task_struct to R9
         la      %r2,SP_PTREGS(%r15)    # address of register-save area
 	llgh    %r3,__LC_SUBCHANNEL_NR # load subchannel number
@@ -701,7 +731,7 @@
         jnz     io_signal_return
 io_leave:
         stnsm   48(%r15),0xfc          # disable I/O and ext. interrupts
-        RESTORE_ALL
+        RESTORE_ALL 0
 
 #
 # call do_softirq and return from syscall, if interrupt-level
@@ -732,7 +762,7 @@
  */
         .globl  ext_int_handler
 ext_int_handler:
-        SAVE_ALL __LC_EXT_OLD_PSW
+        SAVE_ALL __LC_EXT_OLD_PSW,0
         GET_CURRENT                    # load pointer to task_struct to R9
         la      %r2,SP_PTREGS(%r15)    # address of register-save area
         llgh    %r3,__LC_EXT_INT_CODE  # error code
@@ -760,10 +790,10 @@
  */
         .globl mcck_int_handler
 mcck_int_handler:
-        SAVE_ALL __LC_MCK_OLD_PSW
+        SAVE_ALL __LC_MCK_OLD_PSW,0
 	brasl   %r14,s390_do_machine_check
 mcck_return:
-        RESTORE_ALL
+        RESTORE_ALL 0
 
 #ifdef CONFIG_SMP
 /*
@@ -771,10 +801,10 @@
  */
         .globl restart_int_handler
 restart_int_handler:
-        lg      %r15,__LC_KERNEL_STACK # load ksp
-        lhi     %r10,__LC_CREGS_SAVE_AREA
+        lg      %r15,__LC_SAVE_AREA+120 # load ksp
+        lghi    %r10,__LC_CREGS_SAVE_AREA
         lctlg   %c0,%c15,0(%r10) # get new ctl regs
-        lhi     %r10,__LC_AREGS_SAVE_AREA
+        lghi    %r10,__LC_AREGS_SAVE_AREA
         lam     %a0,%a15,0(%r10)
         stosm   0(%r15),0x04           # now we can turn dat on
         lmg     %r6,%r15,48(%r15)      # load registers from clone
@@ -794,3 +824,8 @@
 restart_go:
 #endif
 
+/*
+ * Integer constants
+ */
+               .align 4
+.Lc_ac:        .long  0,0,1
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/head.S linux/arch/s390x/kernel/head.S
--- v2.4.12/linux/arch/s390x/kernel/head.S	Sun Aug 12 13:27:58 2001
+++ linux/arch/s390x/kernel/head.S	Thu Oct 11 09:04:57 2001
@@ -261,7 +261,7 @@
 	l     %r1,0xb8                         # load ipl subchannel number
         la    %r2,IPL_BS                       # load start address
         bas   %r14,.Lloader                    # load rest of ipl image
-        larl  %r12,parmarea                    # pointer to parameter area
+        larl  %r12,_pstart                     # pointer to parameter area
         st    %r1,IPL_DEVICE+4-PARMAREA(%r12)  # store ipl device number
 
 #
@@ -464,7 +464,7 @@
         sigp  %r1,%r0,0x12               # switch to esame mode
 	sam64				 # switch to 64 bit mode
 	lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
-	larl  %r12,parmarea              # pointer to parameter area
+	larl  %r12,_pstart               # pointer to parameter area
 					 # move IPL device to lowcore
         mvc   __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12)
 					 # set program check new psw mask
@@ -472,42 +472,64 @@
 
 
 #
-# find out memory size.
+# find memory chunks.
 #
-	la    %r1,1f-.LPG1(%r13)         # set program check address
+	larl  %r1,.Lchkmem               # set program check address
 	stg   %r1,__LC_PGM_NEW_PSW+8
-        lghi  %r2,1
-        sllg  %r2,%r2,17                 # test in increments of 128KB
-	lgr   %r1,%r2
-	aghi  %r1,-8                     # test last word in the segment
-0:	lg    %r0,0(%r1)                 # test 128KB segment
-        stg   %r0,0(%r1)
-	algr  %r1,%r2                    # add 128KB
-	bc    12,0b-.LPG1(%r13)          # r1 < 2^64 -> loop
-1:	ng    %r1,.L4malign-.LPG1(%r13)  # align to multiples of 4M
-	larl  %r3,memory_size-.
-	stg   %r1,0(%r3)                 # store memory size
-#
-# find out memory size part 2. Running native the HSA is located at
-# 2GB and we will get an addressing exception trying to access it.
-# We have to restart the scan at 2GB to find out if the machine has
-# more than 2GB of storage.
-#
-	la    %r1,1f-.LPG1(%r13)         # set program check address
-	stg   %r1,__LC_PGM_NEW_PSW+8
-	lg    %r1,.Lscan2g-.LPG1(%r13)   # restart scanning @ 2GB + 128K - 8
-0:	lg    %r0,0(%r1)                 # test 128KB segment
-	stg   %r0,0(%r1)
-	algr  %r1,%r2                    # add 128 KB
-	bc    12,0b-.LPG1(%r13)          # r1 < 2^64 -> loop
-1:	clg   %r1,.Lscan2g-.LPG1(%r13)   # program check @ 2GB + 128K - 8 ?
-	be    2f-.LPG1(%r13)
-	ng    %r1,.L4malign-.LPG1(%r13)  # align to multiples of 4M
-	larl  %r3,memory_size-.
-	stg   %r1,0(%r3)                 # store memory size
-2:
+	la    %r1,1                      # test in increments of 128KB
+	sllg  %r1,%r1,17
+	larl  %r3,memory_chunk
+	slgr  %r4,%r4                    # set start of chunk to zero
+	slgr  %r5,%r5                    # set end of chunk to zero
+	slr  %r6,%r6			 # set access code to zero
+.Lloop:
+	tprot 0(%r5),0			 # test protection of first byte
+	ipm   %r7
+	srl   %r7,28
+	clr   %r6,%r7			 # compare cc with last access code
+	je    .Lsame
+	clgr  %r4,%r5			 # chunk size > 0?
+	je    .Lsize0
+	stg   %r4,0(%r3)		 # store start address of chunk
+	lgr   %r0,%r5
+	slgr  %r0,%r4
+	stg   %r0,8(%r3)		 # store size of chunk
+	st    %r6,20(%r3)		 # store type of chunk
+	la    %r3,24(%r3)
+	lgr   %r4,%r5			 # set start to end
+	larl  %r8,memory_size
+	stg   %r5,0(%r8)                 # store memory size
+.Lsize0:
+	lr    %r6,%r7			 # set access code to last cc
+.Lsame:
+	algr  %r5,%r1			 # add 128KB to end of chunk
+	brc   12,.Lloop
+.Lchkmem:				 # > 16EB or tprot got a program check
+	clgr  %r4,%r5			 # chunk size > 0?
+	je    .Ldonemem
+	stg   %r4,0(%r3)		 # store start address of chunk
+	lgr   %r0,%r5
+	slgr  %r0,%r4
+	stg   %r0,8(%r3)		 # store size of chunk
+	st    %r6,20(%r3)		 # store type of chunk
+	la    %r3,24(%r3)
+	lgr   %r4,%r5
+	larl  %r8,memory_size
+	stg   %r5,0(%r8)                 # store memory size
+#
+# Running native the HSA is located at 2GB and we will get an
+# addressing exception trying to access it. We have to restart
+# the scan at 2GB to find out if the machine has more than 2GB.
+#
+	lghi  %r4,1
+	sllg  %r4,%r4,31
+	clgr  %r5,%r4
+	jhe   .Ldonemem
+	lgr   %r5,%r4
+	j     .Lloop
+.Ldonemem:		
 
-	larl  %r12,machine_flags-.
+	larl  %r12,machine_flags
 #
 # find out if we are running under VM
 #
@@ -539,7 +561,7 @@
 .Lentry:.quad  0x0000000180000000,_stext
 .Lctl:  .quad  0x04b50002               # cr0: various things
         .quad  0                        # cr1: primary space segment table
-        .quad  0                        # cr2: access register translation
+        .quad  .Lduct                   # cr2: dispatchable unit control table
         .quad  0                        # cr3: instruction authorization
         .quad  0                        # cr4: instruction authorization
         .quad  0                        # cr5:  various things
@@ -557,11 +579,16 @@
 .L4malign:.quad 0xffffffffffc00000
 .Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8
 
+	.org PARMAREA-64
+.Lduct:	.long 0,0,0,0,0,0,0,0
+	.long 0,0,0,0,0,0,0,0
+
 #
 # params at 10400 (setup.h)
 #
 	.org   PARMAREA
-parmarea:
+	.global _pstart
+_pstart:
 	.quad  0                        # IPL_DEVICE
         .quad  RAMDISK_ORIGIN           # INITRD_START
         .quad  RAMDISK_SIZE             # INITRD_SIZE
@@ -569,31 +596,28 @@
         .org   COMMAND_LINE
     	.byte  "root=/dev/ram0 ro"
         .byte  0
+	.org   0x11000
+	.global _pend
+_pend:	
 
-#
-# startup-code, running in virtual mode
-#
 #ifdef CONFIG_SHARED_KERNEL
 	.org   0x100000
-#else
-        .org   0x10800
 #endif
+	
+#
+# startup-code, running in virtual mode
+#
         .globl _stext
 _stext:	basr  %r13,0                    # get base
 .LPG2:
 #
-# Setup lowcore
+# Setup stack
 #
-        l     %r1,__LC_IPLDEV           # load ipl device number
-        spx   .Lprefix-.LPG2(%r13)      # set prefix to linux lowcore
-        st    %r1,__LC_IPLDEV           # store ipl device number
 	larl  %r15,init_task_union
         aghi  %r15,16384                # init_task_union + 16384
         stg   %r15,__LC_KERNEL_STACK    # set end of kernel stack
         aghi  %r15,-160
         xc    0(8,%r15),0(%r15)         # set backchain to zero
-        lghi  %r0,-1
-        stg   %r0,__LC_KERNEL_LEVEL     # set interrupt count to -1
 #
 # clear bss memory
 #
@@ -621,6 +645,5 @@
 #
             .align 8
 .Ldw:       .quad  0x0002000180000000,0x0000000000000000
-.Lprefix:   .long  init_S390_lowcore	
 .Laregs:    .long  0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0
 
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/ioctl32.c linux/arch/s390x/kernel/ioctl32.c
--- v2.4.12/linux/arch/s390x/kernel/ioctl32.c	Mon Aug 27 12:41:39 2001
+++ linux/arch/s390x/kernel/ioctl32.c	Thu Oct 11 09:04:57 2001
@@ -27,6 +27,7 @@
 #include <asm/types.h>
 #include <asm/uaccess.h>
 #include <asm/dasd.h>
+#include <asm/sockios.h>
 
 #include "linux32.h"
 
@@ -451,6 +452,8 @@
 	IOCTL32_DEFAULT(VT_RESIZEX),
 	IOCTL32_DEFAULT(VT_LOCKSWITCH),
 	IOCTL32_DEFAULT(VT_UNLOCKSWITCH),
+
+	IOCTL32_DEFAULT(SIOCGSTAMP),
 
 	IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32),
 	IOCTL32_HANDLER(SIOCGIFCONF, dev_ifconf),
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/linux32.c linux/arch/s390x/kernel/linux32.c
--- v2.4.12/linux/arch/s390x/kernel/linux32.c	Mon Aug 27 12:41:39 2001
+++ linux/arch/s390x/kernel/linux32.c	Thu Oct 11 09:04:57 2001
@@ -2884,7 +2884,7 @@
 			err = copy_from_user(kaddr + offset, (char *)A(str),
 					     bytes_to_copy);
 			flush_page_to_ram(page);
-			kunmap((unsigned long)kaddr);
+			kunmap(page);
 
 			if (err)
 				return -EFAULT;
@@ -4038,57 +4038,55 @@
 }
 
 struct stat64_emu31 {
-        unsigned short  st_dev;
-        unsigned char   __pad0[6];
-
-        long long	st_ino;
-        unsigned int    st_mode;
-        unsigned int    st_nlink;
-
-        __u32		st_uid;
-        __u32		st_gid;
-
-        unsigned short  st_rdev;
-        unsigned char   __pad3[10];
-
-        long long       st_size;
-        __u32		st_blksize;
-
-        __u32		st_blocks;      /* Number 512-byte blocks allocated. */
-        __u32		__pad4;         /* future possible st_blocks high bits */
-
-        __u32		st_atime;
-        __u32		__pad5;
-
-        __u32		st_mtime;
-        __u32		__pad6;
-
-        __u32		st_ctime;
-        __u32		__pad7;         /* will be high 32 bits of ctime someday */
-
-        __u32		__unused1;
-        __u32		__unused2;
-};
+	unsigned char   __pad0[6];
+	unsigned short  st_dev;
+	unsigned int    __pad1;
+#define STAT64_HAS_BROKEN_ST_INO        1
+	u32             __st_ino;
+	unsigned int    st_mode;
+	unsigned int    st_nlink;
+	u32             st_uid;
+	u32             st_gid;
+	unsigned char   __pad2[6];
+	unsigned short  st_rdev;
+	unsigned int    __pad3;
+	long            st_size;
+	u32             st_blksize;
+	unsigned char   __pad4[4];
+	u32             __pad5;     /* future possible st_blocks high bits */
+	u32             st_blocks;  /* Number 512-byte blocks allocated. */
+	u32             st_atime;
+	u32             __pad6;
+	u32             st_mtime;
+	u32             __pad7;
+	u32             st_ctime;
+	u32             __pad8;     /* will be high 32 bits of ctime someday */
+	unsigned long   st_ino;
+};	
 
 static inline int
 putstat64 (struct stat64_emu31 *ubuf, struct stat *kbuf)
 {
-    int err;
-    
-    err = put_user (kbuf->st_dev, &ubuf->st_dev);
-    err |= __put_user (kbuf->st_ino, &ubuf->st_ino);
-    err |= __put_user (kbuf->st_mode, &ubuf->st_mode);
-    err |= __put_user (kbuf->st_nlink, &ubuf->st_nlink);
-    err |= __put_user (kbuf->st_uid, &ubuf->st_uid);
-    err |= __put_user (kbuf->st_gid, &ubuf->st_gid);
-    err |= __put_user (kbuf->st_rdev, &ubuf->st_rdev);
-    err |= __put_user (kbuf->st_size, &ubuf->st_size);
-    err |= __put_user (kbuf->st_blksize, &ubuf->st_blksize);
-    err |= __put_user (kbuf->st_blocks, &ubuf->st_blocks);
-    err |= __put_user (kbuf->st_atime, &ubuf->st_atime);
-    err |= __put_user (kbuf->st_mtime, &ubuf->st_mtime);
-    err |= __put_user (kbuf->st_ctime, &ubuf->st_ctime);
-    return err;
+    struct stat64_emu31 tmp;
+   
+    memset(&tmp, 0, sizeof(tmp));
+
+    tmp.st_dev = (unsigned short)kbuf->st_dev;
+    tmp.st_ino = kbuf->st_ino;
+    tmp.__st_ino = (u32)kbuf->st_ino;
+    tmp.st_mode = kbuf->st_mode;
+    tmp.st_nlink = (unsigned int)kbuf->st_nlink;
+    tmp.st_uid = kbuf->st_uid;
+    tmp.st_gid = kbuf->st_gid;
+    tmp.st_rdev = (unsigned short)kbuf->st_rdev;
+    tmp.st_size = kbuf->st_size;
+    tmp.st_blksize = (u32)kbuf->st_blksize;
+    tmp.st_blocks = (u32)kbuf->st_blocks;
+    tmp.st_atime = (u32)kbuf->st_atime;
+    tmp.st_mtime = (u32)kbuf->st_mtime;
+    tmp.st_ctime = (u32)kbuf->st_ctime;
+
+    return copy_to_user(ubuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; 
 }
 
 extern asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
@@ -4131,7 +4129,7 @@
 	    return err;
 
     set_fs (KERNEL_DS);
-    ret = sys_newstat(tmp, &s);
+    ret = sys_newlstat(tmp, &s);
     set_fs (old_fs);
     putname(tmp);
     if (putstat64 (statbuf, &s)) 
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/linux32.h linux/arch/s390x/kernel/linux32.h
--- v2.4.12/linux/arch/s390x/kernel/linux32.h	Tue Feb 13 14:13:44 2001
+++ linux/arch/s390x/kernel/linux32.h	Thu Oct 11 09:04:57 2001
@@ -237,8 +237,8 @@
 	__u32			uc_flags;
 	__u32			uc_link;	/* pointer */	
 	stack_t32		uc_stack;
+	_sigregs32		uc_mcontext;
 	sigset_t32		uc_sigmask;	/* mask last for extensibility */
-	__u32			sc;		/* pointer */
 };
 
 #endif /* !CONFIG_S390_SUPPORT */
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/lowcore.S linux/arch/s390x/kernel/lowcore.S
--- v2.4.12/linux/arch/s390x/kernel/lowcore.S	Tue Feb 13 14:13:44 2001
+++ linux/arch/s390x/kernel/lowcore.S	Wed Dec 31 16:00:00 1969
@@ -1,28 +0,0 @@
-/*
- *  arch/s390/kernel/lowcore.S
- *    S390 lowcore definition.
- *
- *  S390 64 bit Version
- *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Hartmut Penner (hpenner@de.ibm.com)
- *               Martin Schwidefsky (schwidefsky@de.ibm.com),
- */
-#include <asm/lowcore.h>
-	
-         .align 8192
-         .globl init_S390_lowcore
-init_S390_lowcore:      
-         .fill 0x1a0-0x000,1,0	
-         .quad  _RESTART_PSW_MASK
-         .quad  restart_int_handler 
-         .quad  _EXT_PSW_MASK
-         .quad  ext_int_handler 
-         .quad  _SVC_PSW_MASK
-         .quad  system_call
-         .quad  _PGM_PSW_MASK
-         .quad  pgm_check_handler 
-         .quad  _MCCK_PSW_MASK
-         .quad  mcck_int_handler 
-EXT_PSW: .quad  _IO_PSW_MASK
-         .quad  io_int_handler
-	 .fill  0x2000-0x200,1,0
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/mathemu.c linux/arch/s390x/kernel/mathemu.c
--- v2.4.12/linux/arch/s390x/kernel/mathemu.c	Tue Feb 13 14:13:44 2001
+++ linux/arch/s390x/kernel/mathemu.c	Wed Dec 31 16:00:00 1969
@@ -1,920 +0,0 @@
-/*
- *  arch/s390/kernel/mathemu.c
- *
- *  S390 version
- *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
- *
- * 'mathemu.c' handles IEEE instructions on a S390 processor
- * that does not have the IEEE fpu
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/ptrace.h>
-
-#include <asm/uaccess.h>
-#include <asm/mathemu.h>
-
-#ifdef CONFIG_SYSCTL
-int sysctl_ieee_emulation_warnings=1;
-#endif
-
-static void display_emulation_not_implemented(char *instr)
-{
-	struct pt_regs *regs;
-	__u16 *location;
-	
-#if CONFIG_SYSCTL
-	if(sysctl_ieee_emulation_warnings)
-#endif
-	{
-		regs=current->thread.regs;
-		location = (__u16 *)(regs->psw.addr-S390_lowcore.pgm_ilc);
-		printk("%s ieee fpu instruction not emulated process name: %s pid: %d \n",
-		       instr,
-		       current->comm, current->pid);
-		printk("%s's PSW:    %08lx %08lx\n",instr,
-		       (unsigned long) regs->psw.mask,
-		       (unsigned long) location);
-	}
-}
-
-
-static void set_CC_df(__u64 val1,__u64 val2) {
-        int rc;
-        rc = __cmpdf2(val1,val2);
-        current->thread.regs->psw.mask &= 0xFFFFCFFFFFFFFFFFL;
-        switch (rc) {
-                case -1:
-                        current->thread.regs->psw.mask |= 0x0000100000000000L;
-                        break;
-                case 1:
-                        current->thread.regs->psw.mask |= 0x0000200000000000L;
-                        break;
-        }
-}
-
-static void set_CC_sf(__u32 val1,__u32 val2) {
-        int rc;
-        rc = __cmpsf2(val1,val2);
-        current->thread.regs->psw.mask &= 0xFFFFCFFFFFFFFFFF;
-        switch (rc) {
-                case -1:
-                        current->thread.regs->psw.mask |= 0x0000100000000000L;
-                        break;
-                case 1:
-                        current->thread.regs->psw.mask |= 0x0000200000000000L;
-                        break;
-        }
-}
-
-
-static void emu_adb (int rx, __u64 val) {
-        current->thread.fp_regs.fprs[rx].d = __adddf3(current->thread.fp_regs.fprs[rx].d,val);
-        set_CC_df(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_adbr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].d = __adddf3(current->thread.fp_regs.fprs[rx].d,
-                                         current->thread.fp_regs.fprs[ry].d);
-        set_CC_df(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_aeb (int rx, __u32 val) {
-        current->thread.fp_regs.fprs[rx].f = __addsf3(current->thread.fp_regs.fprs[rx].f,val);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_aebr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].f = __addsf3(current->thread.fp_regs.fprs[rx].f,
-                                        current->thread.fp_regs.fprs[ry].f);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_axbr (int rx, int ry) {
-        display_emulation_not_implemented("axbr");
-}
-
-static void emu_cdb (int rx, __u64 val) {
-        set_CC_df(current->thread.fp_regs.fprs[rx].d,val);
-}
-
-static void emu_cdbr (int rx, int ry) {
-        set_CC_df(current->thread.fp_regs.fprs[rx].d,current->thread.fp_regs.fprs[ry].d);
-}
-
-static void emu_cdfbr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].d =
-                     __floatsidf(current->thread.regs->gprs[ry]);
-}
-
-static void emu_ceb (int rx, __u32 val) {
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,val);
-}
-
-static void emu_cebr (int rx, int ry) {
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,current->thread.fp_regs.fprs[ry].f);
-}
-
-static void emu_cefbr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].f =
-                     __floatsisf(current->thread.regs->gprs[ry]);
-}
-
-static void emu_cfdbr (int rx, int ry, int mask) {
-        current->thread.regs->gprs[rx] =
-                     __fixdfsi(current->thread.fp_regs.fprs[ry].d);
-}
-
-static void emu_cfebr (int rx, int ry, int mask) {
-        current->thread.regs->gprs[rx] =
-                     __fixsfsi(current->thread.fp_regs.fprs[ry].f);
-}
-
-static void emu_cfxbr (int rx, int ry, int mask) {
-        display_emulation_not_implemented("cfxbr");
-}
-
-static void emu_cxbr (int rx, int ry) {
-        display_emulation_not_implemented("cxbr");
-}
-
-static void emu_cxfbr (int rx, int ry) {
-        display_emulation_not_implemented("cxfbr");
-}
-
-static void emu_ddb (int rx, __u64 val) {
-        current->thread.fp_regs.fprs[rx].d = __divdf3(current->thread.fp_regs.fprs[rx].d,val);
-        set_CC_df(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_ddbr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].d = __divdf3(current->thread.fp_regs.fprs[rx].d,
-                                         current->thread.fp_regs.fprs[ry].d);
-        set_CC_df(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_deb (int rx, __u32 val) {
-        current->thread.fp_regs.fprs[rx].f = __divsf3(current->thread.fp_regs.fprs[rx].f,val);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_debr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].f = __divsf3(current->thread.fp_regs.fprs[rx].f,
-                                         current->thread.fp_regs.fprs[ry].f);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_didbr (int rx, int ry, int mask) {
-        display_emulation_not_implemented("didbr");
-}
-
-static void emu_diebr (int rx, int ry, int mask) {
-        display_emulation_not_implemented("diebr");
-}
-
-static void emu_dxbr (int rx, int ry) {
-        display_emulation_not_implemented("dxbr");
-}
-
-static void emu_efpc (int rx, int ry) {
-        display_emulation_not_implemented("efpc");
-}
-
-static void emu_fidbr (int rx, int ry, int mask) {
-        display_emulation_not_implemented("fidbr");
-}
-
-static void emu_fiebr (int rx, int ry, int mask) {
-        display_emulation_not_implemented("fiebr");
-}
-
-static void emu_fixbr (int rx, int ry, int mask) {
-        display_emulation_not_implemented("fixbr");
-}
-
-static void emu_kdb (int rx, __u64 val) {
-        display_emulation_not_implemented("kdb");
-}
-
-static void emu_kdbr (int rx, int ry) {
-        display_emulation_not_implemented("kdbr");
-}
-
-static void emu_keb (int rx, __u32 val) {
-        display_emulation_not_implemented("keb");
-}
-
-static void emu_kebr (int rx, int ry) {
-        display_emulation_not_implemented("kebr");
-}
-
-static void emu_kxbr (int rx, int ry) {
-        display_emulation_not_implemented("kxbr");
-}
-
-static void emu_lcdbr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].d =
-        __negdf2(current->thread.fp_regs.fprs[ry].d);
-        set_CC_df(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_lcebr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].f =
-        __negsf2(current->thread.fp_regs.fprs[ry].f);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_lcxbr (int rx, int ry) {
-        display_emulation_not_implemented("lcxbr");
-}
-
-static void emu_ldeb (int rx, __u32 val) {
-        current->thread.fp_regs.fprs[rx].d = __extendsfdf2(val);
-}
-
-static void emu_ldebr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].d =
-        __extendsfdf2(current->thread.fp_regs.fprs[ry].f);
-}
-
-static void emu_ldxbr (int rx, int ry) {
-        display_emulation_not_implemented("ldxbr");
-}
-
-static void emu_ledbr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].f = __truncdfsf2(current->thread.fp_regs.fprs[ry].d);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_lexbr (int rx, int ry) {
-        display_emulation_not_implemented("lexbr");
-}
-
-static void emu_lndbr (int rx, int ry) {
-        display_emulation_not_implemented("lndbr");
-}
-
-static void emu_lnebr (int rx, int ry) {
-        display_emulation_not_implemented("lnebr");
-}
-
-static void emu_lnxbr (int rx, int ry) {
-        display_emulation_not_implemented("lnxbr");
-}
-
-static void emu_lpdbr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].d = __absdf2(current->thread.fp_regs.fprs[ry].d);
-        set_CC_df(current->thread.fp_regs.fprs[rx].d,0);
-}
-
-static void emu_lpebr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].f = __abssf2(current->thread.fp_regs.fprs[ry].f);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_lpxbr (int rx, int ry) {
-        display_emulation_not_implemented("lpxbr");
-}
-
-static void emu_ltdbr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].d = current->thread.fp_regs.fprs[ry].d;
-        set_CC_df(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_ltebr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].f = current->thread.fp_regs.fprs[ry].f;
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_ltxbr (int rx, int ry) {
-        display_emulation_not_implemented("ltxbr");
-}
-
-static void emu_lxdb (int rx, __u64 val) {
-        display_emulation_not_implemented("lxdb");
-}
-
-static void emu_lxdbr (int rx, int ry) {
-        display_emulation_not_implemented("lxdbr");
-}
-
-static void emu_lxeb (int rx, __u32 val) {
-        display_emulation_not_implemented("lxeb");
-}
-
-static void emu_lxebr (int rx, int ry) {
-        display_emulation_not_implemented("lxebr");
-}
-
-static void emu_madb (int rx, __u64 val, int mask) {
-        display_emulation_not_implemented("madb");
-}
-
-static void emu_madbr (int rx, int ry, int mask) {
-        display_emulation_not_implemented("madbr");
-}
-
-static void emu_maeb (int rx, __u32 val, int mask) {
-        display_emulation_not_implemented("maeb");
-}
-
-static void emu_maebr (int rx, int ry, int mask) {
-        display_emulation_not_implemented("maebr");
-}
-
-static void emu_mdb (int rx, __u64 val) {
-        current->thread.fp_regs.fprs[rx].d = __muldf3(current->thread.fp_regs.fprs[rx].d,val);
-        set_CC_df(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_mdbr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].d = __muldf3(current->thread.fp_regs.fprs[rx].d,
-                                         current->thread.fp_regs.fprs[ry].d);
-        set_CC_df(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_mdeb (int rx, __u32 val) {
-        display_emulation_not_implemented("mdeb");
-}
-
-static void emu_mdebr (int rx, int ry) {
-        display_emulation_not_implemented("mdebr");
-}
-
-static void emu_meeb (int rx, __u32 val) {
-        current->thread.fp_regs.fprs[rx].f = __mulsf3(current->thread.fp_regs.fprs[rx].f,
-                                         val);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_meebr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].f = __mulsf3(current->thread.fp_regs.fprs[rx].f,
-                                         current->thread.fp_regs.fprs[ry].f);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_msdb (int rx, __u64 val, int mask) {
-        display_emulation_not_implemented("msdb");
-}
-
-static void emu_msdbr (int rx, int ry, int mask) {
-        display_emulation_not_implemented("msdbr");
-}
-
-static void emu_mseb (int rx, __u32 val, int mask) {
-        display_emulation_not_implemented("mseb");
-}
-
-static void emu_msebr (int rx, int ry, int mask) {
-        display_emulation_not_implemented("msebr");
-}
-
-static void emu_mxbr (int rx, int ry) {
-        display_emulation_not_implemented("mxbr");
-}
-
-static void emu_mxdb (int rx, __u64 val) {
-        display_emulation_not_implemented("mxdb");
-}
-
-static void emu_mxdbr (int rx, int ry) {
-        display_emulation_not_implemented("mxdbr");
-}
-
-static void emu_sdb (int rx, __u64 val) {
-        current->thread.fp_regs.fprs[rx].d = __subdf3(current->thread.fp_regs.fprs[rx].d,
-                                         val);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_sdbr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].d = __subdf3(current->thread.fp_regs.fprs[rx].d,
-                                         current->thread.fp_regs.fprs[ry].d);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_seb (int rx, __u32 val) {
-        current->thread.fp_regs.fprs[rx].f = __subsf3(current->thread.fp_regs.fprs[rx].f,
-                                         val);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_sebr (int rx, int ry) {
-        current->thread.fp_regs.fprs[rx].f = __subsf3(current->thread.fp_regs.fprs[rx].f,
-                                         current->thread.fp_regs.fprs[ry].f);
-        set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_sfpc (int rx, int ry) {
-        display_emulation_not_implemented("sfpc");
-}
-
-static void emu_sqdb (int rx, __u64 val) {
-        display_emulation_not_implemented("sqdb");
-}
-
-static void emu_sqdbr (int rx, int ry) {
-        display_emulation_not_implemented("sqdbr");
-}
-
-static void emu_sqeb (int rx, __u32 val) {
-        display_emulation_not_implemented("sqeb");
-}
-
-static void emu_sqebr (int rx, int ry) {
-        display_emulation_not_implemented("sqebr");
-}
-
-static void emu_sqxbr (int rx, int ry) {
-        display_emulation_not_implemented("sqxbr");
-}
-
-static void emu_sxbr (int rx, int ry) {
-        display_emulation_not_implemented("sxbr");
-}
-
-static void emu_tcdb (int rx, __u64 val) {
-        display_emulation_not_implemented("tcdb");
-}
-
-static void emu_tceb (int rx, __u32 val) {
-        display_emulation_not_implemented("tceb");
-}
-
-static void emu_tcxb (int rx, __u64 val) {
-        display_emulation_not_implemented("tcxb");
-}
-
-
-static inline void emu_load_regd(int reg) {
-        if ((reg&9) == 0) {                /* test if reg in {0,2,4,6} */
-                __asm__ __volatile (       /* load reg from fp_regs.fprs[reg] */
-                        "     bras  1,0f\n"
-                        "     ld    0,0(%1)\n"
-                        "0:   ex    %0,0(1)"
-                        : /* no output */
-                        : "a" (reg<<4), "a" (&current->thread.fp_regs.fprs[reg].d)
-                        : "1" );
-        }
-}
-
-static inline void emu_load_rege(int reg) {
-        if ((reg&9) == 0) {                /* test if reg in {0,2,4,6} */
-                __asm__ __volatile (       /* load reg from fp_regs.fprs[reg] */
-                        "     bras  1,0f\n"
-                        "     le    0,0(%1)\n"
-                        "0:   ex    %0,0(1)"
-                        : /* no output */
-                        : "a" (reg<<4), "a" (&current->thread.fp_regs.fprs[reg].f)
-                        : "1" );
-        }
-}
-
-static inline void emu_store_regd(int reg) {
-        if ((reg&9) == 0) {                /* test if reg in {0,2,4,6} */
-                __asm__ __volatile (       /* store reg to fp_regs.fprs[reg] */
-                        "     bras  1,0f\n"
-                        "     std   0,0(%1)\n"
-                        "0:   ex    %0,0(1)"
-                        : /* no output */
-                        : "a" (reg<<4), "a" (&current->thread.fp_regs.fprs[reg].d)
-                        : "1" );
-        }
-}
-
-
-static inline void emu_store_rege(int reg) {
-        if ((reg&9) == 0) {                /* test if reg in {0,2,4,6} */
-                __asm__ __volatile (       /* store reg to fp_regs.fprs[reg] */
-                        "     bras  1,0f\n"
-                        "     ste   0,0(%1)\n"
-                        "0:   ex    %0,0(1)"
-                        : /* no output */
-                        : "a" (reg<<4), "a" (&current->thread.fp_regs.fprs[reg].f)
-                        : "1" );
-        }
-}
-
-int math_emu_b3(__u8 *opcode, struct pt_regs * regs) {
-        static const __u8 format_table[] = {
-                2, 2, 2, 2, 9, 1, 2, 1, 2, 2, 2, 2, 9, 2, 4, 4,
-                1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 3, 3,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                1, 1, 1, 1,10, 1, 1, 3, 1, 1, 1, 1, 1, 1, 0, 0,
-                0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 3,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,
-                0, 0, 0, 0, 5, 6, 6, 0, 7, 8, 8, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-        };
-        static const void *jump_table[]= {
-                emu_lpebr, emu_lnebr, emu_ltebr, emu_lcebr,
-                emu_ldebr, emu_lxdbr, emu_lxebr, emu_mxdbr,
-                emu_kebr,  emu_cebr,  emu_aebr,  emu_sebr,
-                emu_mdebr, emu_debr,  emu_maebr, emu_msebr,
-                emu_lpdbr, emu_lndbr, emu_ltdbr, emu_lcdbr,
-                emu_sqebr, emu_sqdbr, emu_sqxbr, emu_meebr,
-                emu_kdbr,  emu_cdbr,  emu_adbr,  emu_sdbr,
-                emu_mdbr,  emu_ddbr,  emu_madbr, emu_msdbr,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                emu_lpxbr, emu_lnxbr, emu_ltxbr, emu_lcxbr,
-                emu_ledbr, emu_ldxbr, emu_lexbr, emu_fixbr,
-                emu_kxbr,  emu_cxbr,  emu_axbr,  emu_sxbr,
-                emu_mxbr,  emu_dxbr,  NULL,      NULL,
-                NULL,      NULL,      NULL,      emu_diebr,
-                NULL,      NULL,      NULL,      emu_fiebr,
-                NULL,      NULL,      NULL,      emu_didbr,
-                NULL,      NULL,      NULL,      emu_fidbr,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                emu_sfpc,  NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                emu_efpc,  NULL,      NULL,      NULL,
-                NULL,      NULL,      NULL,      NULL,
-                emu_cefbr, emu_cdfbr, emu_cxfbr, NULL,
-                emu_cfebr, emu_cfdbr, emu_cfxbr
-        };
-
-        switch (format_table[opcode[1]]) {
-        case 1: /* RRE format, double operation */
-                emu_store_regd((opcode[3]>>4)&15);
-                emu_store_regd(opcode[3]&15);
-                /* call the emulation function */
-                ((void (*)(int, int))jump_table[opcode[1]])
-                        (opcode[3]>>4,opcode[3]&15);
-                emu_load_regd((opcode[3]>>4)&15);
-                emu_load_regd(opcode[3]&15);
-                return 0;
-        case 2: /* RRE format, float operation */
-                emu_store_rege((opcode[3]>>4)&15);
-                emu_store_rege(opcode[3]&15);
-                /* call the emulation function */
-                ((void (*)(int, int))jump_table[opcode[1]])
-                        (opcode[3]>>4,opcode[3]&15);
-                emu_load_rege((opcode[3]>>4)&15);
-                emu_load_rege(opcode[3]&15);
-                return 0;
-        case 3: /* RRF format, double operation */
-                emu_store_regd((opcode[3]>>4)&15);
-                emu_store_regd(opcode[3]&15);
-                /* call the emulation function */
-                ((void (*)(int, int, int))jump_table[opcode[1]])
-                        (opcode[3]>>4,opcode[3]&15,opcode[2]>>4);
-                emu_load_regd((opcode[3]>>4)&15);
-                emu_load_regd(opcode[3]&15);
-                return 0;
-        case 4: /* RRF format, float operation */
-                emu_store_rege((opcode[3]>>4)&15);
-                emu_store_rege(opcode[3]&15);
-                /* call the emulation function */
-                ((void (*)(int, int, int))jump_table[opcode[1]])
-                        (opcode[3]>>4,opcode[3]&15,opcode[2]>>4);
-                emu_load_rege((opcode[3]>>4)&15);
-                emu_load_rege(opcode[3]&15);
-                return 0;
-        case 5: /* RRE format, cefbr instruction */
-                emu_store_rege((opcode[3]>>4)&15);
-                /* call the emulation function */
-                ((void (*)(int, int))jump_table[opcode[1]])
-                        (opcode[3]>>4,opcode[3]&15);
-                emu_load_rege((opcode[3]>>4)&15);
-                return 0;
-        case 6: /* RRE format, cdfbr & cxfbr instruction */
-                emu_store_regd((opcode[3]>>4)&15);
-                /* call the emulation function */
-                ((void (*)(int, int))jump_table[opcode[1]])
-                        (opcode[3]>>4,opcode[3]&15);
-                emu_load_regd((opcode[3]>>4)&15);
-                return 0;
-                /* FIXME !! */
-                return 0;
-        case 7: /* RRF format, cfebr instruction */
-                emu_store_rege(opcode[3]&15);
-                /* call the emulation function */
-                ((void (*)(int, int, int))jump_table[opcode[1]])
-                        (opcode[3]>>4,opcode[3]&15,opcode[2]>>4);
-                return 0;
-        case 8: /* RRF format, cfdbr & cfxbr instruction */
-                emu_store_regd(opcode[3]&15);
-                /* call the emulation function */
-                ((void (*)(int, int, int))jump_table[opcode[1]])
-                        (opcode[3]>>4,opcode[3]&15,opcode[2]>>4);
-                return 0;
-	case 9: /* RRE format, ldebr & mdebr instruction */
-		/* float store but double load */
-                emu_store_rege((opcode[3]>>4)&15);
-                emu_store_rege(opcode[3]&15);
-                /* call the emulation function */
-                ((void (*)(int, int))jump_table[opcode[1]])
-                        (opcode[3]>>4,opcode[3]&15);
-                emu_load_regd((opcode[3]>>4)&15);
-                return 0;
-        case 10: /* RRE format, ledbr instruction */
-		/* double store but float load */
-                emu_store_regd((opcode[3]>>4)&15);
-                emu_store_regd(opcode[3]&15);
-                /* call the emulation function */
-                ((void (*)(int, int))jump_table[opcode[1]])
-                        (opcode[3]>>4,opcode[3]&15);
-                emu_load_rege((opcode[3]>>4)&15);
-                return 0;
-        default:
-                return 1;
-        }
-}
-
-static void* calc_addr(struct pt_regs *regs,int rx,int rb,int disp)
-{
-  rx &= 0xf;
-  rb &= 0xf;
-  disp &= 0xfff;
-  return (void*) ((rx != 0 ? regs->gprs[rx] : 0)  + /* index */   
-         (rb != 0 ? regs->gprs[rb] : 0)  + /* base */
-         disp);
-}
-    
-int math_emu_ed(__u8 *opcode, struct pt_regs * regs) {
-        static const __u8 format_table[] = {
-                0, 0, 0, 0, 5, 1, 2, 1, 2, 2, 2, 2, 5, 2, 4, 4,
-                2, 1, 1, 0, 2, 1, 0, 2, 1, 1, 1, 1, 1, 1, 3, 3,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-        };
-        static const void *jump_table[]= {
-                NULL,     NULL,     NULL,     NULL,
-                emu_ldeb, emu_lxdb, emu_lxeb, emu_mxdb,
-                emu_keb,  emu_ceb,  emu_aeb,  emu_seb,
-                emu_mdeb, emu_deb,  emu_maeb, emu_mseb,
-                emu_tceb, emu_tcdb, emu_tcxb, NULL,
-                emu_sqeb, emu_sqdb, NULL,     emu_meeb,
-                emu_kdb,  emu_cdb,  emu_adb,  emu_sdb,
-                emu_mdb,  emu_ddb,  emu_madb, emu_msdb
-        };
-
-        switch (format_table[opcode[5]]) {
-        case 1: /* RXE format, __u64 constant */ {
-                __u64 *dxb, temp;
-                __u32 opc;
-
-                emu_store_regd((opcode[1]>>4)&15);
-                opc = *((__u32 *) opcode);
-                dxb = (__u64 *) calc_addr(regs,opc>>16,opc>>12,opc);
-                /* FIXME: how to react if copy_from_user fails ? */
-                copy_from_user(&temp, dxb, 8);
-                /* call the emulation function */
-                ((void (*)(int, __u64))jump_table[opcode[5]])
-                        (opcode[1]>>4,temp);
-                emu_load_regd((opcode[1]>>4)&15);
-                return 0;
-        }
-        case 2: /* RXE format, __u32 constant */ {
-                __u32 *dxb, temp;
-                __u32 opc;
-
-                emu_store_rege((opcode[1]>>4)&15);
-                opc = *((__u32 *) opcode);
-                dxb = (__u32 *) calc_addr(regs,opc>>16,opc>>12,opc);
-                /* FIXME: how to react if get_user fails ? */
-                get_user(temp, dxb);
-                /* call the emulation function */
-                ((void (*)(int, __u32))jump_table[opcode[5]])
-                        (opcode[1]>>4,temp);
-                emu_load_rege((opcode[1]>>4)&15);
-                return 0;
-        }
-        case 3: /* RXF format, __u64 constant */ {
-                __u32 *dxb, temp;
-                __u32 opc;
-
-                emu_store_regd((opcode[1]>>4)&15);
-                opc = *((__u32 *) opcode);
-                dxb = (__u32 *) calc_addr(regs,opc>>16,opc>>12,opc);
-                /* FIXME: how to react if copy_from_user fails ? */
-                copy_from_user(&temp, dxb, 8);
-                /* call the emulation function */
-                ((void (*)(int, __u32, int))jump_table[opcode[5]])
-                        (opcode[1]>>4,temp,opcode[4]>>4);
-                emu_load_regd((opcode[1]>>4)&15);
-                return 0;
-        }
-        case 4: /* RXF format, __u32 constant */ {
-                __u32 *dxb, temp;
-                __u32 opc;
-
-                emu_store_rege((opcode[1]>>4)&15);
-                opc = *((__u32 *) opcode);
-                dxb = (__u32 *) calc_addr(regs,opc>>16,opc>>12,opc);
-                /* FIXME: how to react if get_user fails ? */
-                get_user(temp, dxb);
-                /* call the emulation function */
-                ((void (*)(int, __u32, int))jump_table[opcode[5]])
-                        (opcode[1]>>4,temp,opcode[4]>>4);
-                emu_load_rege((opcode[1]>>4)&15);
-                return 0;
-        }
-	case 5: /* RXE format, __u32 constant */
-                /* store_rege and load_regd */ 
-		{
-                __u32 *dxb, temp;
-                __u32 opc;
-                emu_store_rege((opcode[1]>>4)&15);
-                opc = *((__u32 *) opcode);
-                dxb = (__u32 *) calc_addr(regs,opc>>16,opc>>12,opc);
-                /* FIXME: how to react if get_user fails ? */
-                get_user(temp, dxb);
-                /* call the emulation function */
-                ((void (*)(int, __u32))jump_table[opcode[5]])
-                        (opcode[1]>>4,temp);
-                emu_load_regd((opcode[1]>>4)&15);
-                return 0;
-        }
-        default:
-                return 1;
-        }
-}
-
-/*
- * Emulate LDR Rx,Ry with Rx or Ry not in {0, 2, 4, 6}
- */
-void math_emu_ldr(__u8 *opcode) {
-        __u16 opc = *((__u16 *) opcode);
-
-        if ((opc & 0x0090) == 0) {         /* test if rx in {0,2,4,6} */
-                /* we got an exception therfore ry can't be in {0,2,4,6} */
-                __asm__ __volatile (       /* load rx from fp_regs.fprs[ry] */
-                        "     bras  1,0f\n"
-                        "     ld    0,0(%1)\n"
-                        "0:   ex    %0,0(1)"
-                        : /* no output */
-                        : "a" (opc&0x00f0),
-                          "a" (&current->thread.fp_regs.fprs[opc&0x000f].d)
-                        : "1" );
-        } else if ((opc & 0x0009) == 0) {  /* test if ry in {0,2,4,6} */
-                __asm__ __volatile (       /* store ry to fp_regs.fprs[rx] */
-                        "     bras  1,0f\n"
-                        "     std   0,0(%1)\n"
-                        "0:   ex    %0,0(1)"
-                        : /* no output */
-                        : "a" ((opc&0x000f)<<4),
-                          "a" (&current->thread.fp_regs.fprs[(opc&0x00f0)>>4].d)
-                        : "1" );
-        } else {                          /* move fp_regs.fprs[ry] to fp_regs.fprs[rx] */
-                current->thread.fp_regs.fprs[(opc&0x00f0)>>4] =
-                        current->thread.fp_regs.fprs[opc&0x000f];
-        }
-}
-
-/*
- * Emulate LER Rx,Ry with Rx or Ry not in {0, 2, 4, 6}
- */
-void math_emu_ler(__u8 *opcode) {
-        __u16 opc = *((__u16 *) opcode);
-
-        if ((opc & 0x0090) == 0) {         /* test if rx in {0,2,4,6} */
-                /* we got an exception therfore ry can't be in {0,2,4,6} */
-                __asm__ __volatile (       /* load rx from fp_regs.fprs[ry] */
-                        "     bras  1,0f\n"
-                        "     le    0,0(%1)\n"
-                        "0:   ex    %0,0(1)"
-                        : /* no output */
-                        : "a" (opc&0x00f0),
-                          "a" (&current->thread.fp_regs.fprs[opc&0x000f].f)
-                        : "1" );
-        } else if ((opc & 0x0009) == 0) {  /* test if ry in {0,2,4,6} */
-                __asm__ __volatile (       /* store ry to fp_regs.fprs[rx] */
-                        "     bras  1,0f\n"
-                        "     ste   0,0(%1)\n"
-                        "0:   ex    %0,0(1)"
-                        : /* no output */
-                        : "a" ((opc&0x000f)<<4),
-                          "a" (&current->thread.fp_regs.fprs[(opc&0x00f0)>>4].f)
-                        : "1" );
-        } else {                          /* move fp_regs.fprs[ry] to fp_regs.fprs[rx] */
-                current->thread.fp_regs.fprs[(opc&0x00f0)>>4] =
-                        current->thread.fp_regs.fprs[opc&0x000f];
-        }
-}
-
-/*
- * Emulate LD R,D(X,B) with R not in {0, 2, 4, 6}
- */
-void math_emu_ld(__u8 *opcode, struct pt_regs * regs) {
-        __u32 opc = *((__u32 *) opcode);
-        __u64 *dxb;
-
-        dxb = (__u64 *) calc_addr(regs,opc>>16,opc>>12,opc);
-        /* FIXME: how to react if copy_from_user fails ? */
-        copy_from_user(&current->thread.fp_regs.fprs[(opc>>20)&15].d, dxb, 8);
-}
-
-/*
- * Emulate LE R,D(X,B) with R not in {0, 2, 4, 6}
- */
-void math_emu_le(__u8 *opcode, struct pt_regs * regs) {
-        __u32 opc = *((__u32 *) opcode);
-        __u32 *mem, *dxb;
-
-        dxb = (__u32 *) calc_addr(regs,opc>>16,opc>>12,opc);
-        /* FIXME: how to react if get_user fails ? */
-        mem = (__u32 *) (&current->thread.fp_regs.fprs[(opc>>20)&15].f);
-        get_user(mem[0], dxb);
-}
-
-/*
- * Emulate STD R,D(X,B) with R not in {0, 2, 4, 6}
- */
-void math_emu_std(__u8 *opcode, struct pt_regs * regs) {
-        __u32 opc = *((__u32 *) opcode);
-        __u64 *dxb;
-        dxb = (__u64 *) calc_addr(regs,opc>>16,opc>>12,opc);
-        /* FIXME: how to react if copy_to_user fails ? */
-        copy_to_user(dxb, &current->thread.fp_regs.fprs[(opc>>20)&15].d, 8);
-}
-
-/*
- * Emulate STE R,D(X,B) with R not in {0, 2, 4, 6}
- */
-void math_emu_ste(__u8 *opcode, struct pt_regs * regs) {
-        __u32 opc = *((__u32 *) opcode);
-        __u32 *mem, *dxb;
-        dxb = (__u32 *) calc_addr(regs,opc>>16,opc>>12,opc);
-        /* FIXME: how to react if put_user fails ? */
-        mem = (__u32 *) (&current->thread.fp_regs.fprs[(opc>>20)&15].f);
-        put_user(mem[0], dxb);
-}
-
-/*
- * Emulate LFPC D(B)
- */
-int math_emu_lfpc(__u8 *opcode, struct pt_regs *regs) {
-        /* FIXME: how to do that ?!? */
-        return 0;
-}
-
-/*
- * Emulate STFPC D(B)
- */
-int math_emu_stfpc(__u8 *opcode, struct pt_regs *regs) {
-        /* FIXME: how to do that ?!? */
-        return 0;
-}
-
-/*
- * Emulate SRNM D(B)
- */
-int math_emu_srnm(__u8 *opcode, struct pt_regs *regs) {
-        /* FIXME: how to do that ?!? */
-        return 0;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/process.c linux/arch/s390x/kernel/process.c
--- v2.4.12/linux/arch/s390x/kernel/process.c	Tue Oct  9 17:06:51 2001
+++ linux/arch/s390x/kernel/process.c	Thu Oct 11 09:04:57 2001
@@ -44,8 +44,6 @@
 #include <asm/processor.h>
 #include <asm/irq.h>
 
-spinlock_t semaphore_wake_lock = SPIN_LOCK_UNLOCKED;
-
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
 
 /*
@@ -210,7 +208,7 @@
 void show_regs(struct pt_regs *regs)
 {
 	char buff[80];
-	int line;
+	int i, line;
 
         printk("CPU:    %d\n",smp_processor_id());
         printk("Process %s (pid: %d, stackpage=%016lX)\n",
@@ -218,6 +216,17 @@
 	
 	for (line = 0; sprintf_regs(line, buff, current, regs); line++)
 		printk(buff);
+
+	if (regs->psw.mask & PSW_PROBLEM_STATE)
+	{
+		printk("User Code:\n");
+		memset(buff, 0, 20);
+		copy_from_user(buff,
+			       (char *) (regs->psw.addr & PSW_ADDR_MASK), 20);
+		for (i = 0; i < 20; i++)
+			printk("%02x ", buff[i]);
+		printk("\n");
+	}
 }
 
 char *task_show_regs(struct task_struct *task, char *buffer)
@@ -323,28 +332,19 @@
 
 asmlinkage int sys_fork(struct pt_regs regs)
 {
-        int ret;
-
-        lock_kernel();
-        ret = do_fork(SIGCHLD, regs.gprs[15], &regs, 0);
-        unlock_kernel();
-        return ret;
+        return do_fork(SIGCHLD, regs.gprs[15], &regs, 0);
 }
 
 asmlinkage int sys_clone(struct pt_regs regs)
 {
         unsigned long clone_flags;
         unsigned long newsp;
-        int ret;
 
-        lock_kernel();
         clone_flags = regs.gprs[3];
         newsp = regs.orig_gpr2;
         if (!newsp)
                 newsp = regs.gprs[15];
-        ret = do_fork(clone_flags, newsp, &regs, 0);
-        unlock_kernel();
-        return ret;
+        return do_fork(clone_flags, newsp, &regs, 0);
 }
 
 /*
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/s390_ksyms.c linux/arch/s390x/kernel/s390_ksyms.c
--- v2.4.12/linux/arch/s390x/kernel/s390_ksyms.c	Sun Aug 12 13:27:58 2001
+++ linux/arch/s390x/kernel/s390_ksyms.c	Thu Oct 11 09:04:57 2001
@@ -18,11 +18,11 @@
 /*
  * memory management
  */
-EXPORT_SYMBOL(_oi_bitmap);
-EXPORT_SYMBOL(_ni_bitmap);
-EXPORT_SYMBOL(_zb_findmap);
-EXPORT_SYMBOL(__copy_from_user_fixup);
-EXPORT_SYMBOL(__copy_to_user_fixup);
+EXPORT_SYMBOL_NOVERS(_oi_bitmap);
+EXPORT_SYMBOL_NOVERS(_ni_bitmap);
+EXPORT_SYMBOL_NOVERS(_zb_findmap);
+EXPORT_SYMBOL_NOVERS(__copy_from_user_fixup);
+EXPORT_SYMBOL_NOVERS(__copy_to_user_fixup);
 
 /*
  * semaphore ops
@@ -41,12 +41,12 @@
 EXPORT_SYMBOL_NOVERS(strlen);
 EXPORT_SYMBOL_NOVERS(strchr);
 EXPORT_SYMBOL_NOVERS(strcmp);
-EXPORT_SYMBOL_NOVERS(strcat);
 EXPORT_SYMBOL_NOVERS(strncat);
 EXPORT_SYMBOL_NOVERS(strncmp);
 EXPORT_SYMBOL_NOVERS(strncpy);
 EXPORT_SYMBOL_NOVERS(strnlen);
 EXPORT_SYMBOL_NOVERS(strrchr);
+EXPORT_SYMBOL_NOVERS(strstr);
 EXPORT_SYMBOL_NOVERS(strtok);
 EXPORT_SYMBOL_NOVERS(strpbrk);
 
@@ -66,8 +66,5 @@
 EXPORT_SYMBOL(kernel_thread);
 EXPORT_SYMBOL(console_mode);
 EXPORT_SYMBOL(console_device);
+EXPORT_SYMBOL_NOVERS(do_call_softirq);
 
-#if CONFIG_IP_MULTICAST
-/* Required for lcs gigibit ethernet multicast support */
-EXPORT_SYMBOL(arp_mc_map);
-#endif
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/setup.c linux/arch/s390x/kernel/setup.c
--- v2.4.12/linux/arch/s390x/kernel/setup.c	Sun Aug 12 13:27:58 2001
+++ linux/arch/s390x/kernel/setup.c	Thu Oct 11 09:04:57 2001
@@ -47,6 +47,9 @@
 unsigned int console_device = -1;
 unsigned long memory_size = 0;
 unsigned long machine_flags = 0;
+struct { unsigned long addr, size, type; } memory_chunk[16];
+#define CHUNK_READ_WRITE 0
+#define CHUNK_READ_ONLY 1
 __u16 boot_cpu_addr;
 int cpus_initialized = 0;
 unsigned long cpu_initialized = 0;
@@ -257,6 +260,8 @@
  * Setup function called from init/main.c just after the banner
  * was printed.
  */
+extern char _pstart, _pend, _stext;
+
 void __init setup_arch(char **cmdline_p)
 {
         unsigned long bootmap_size;
@@ -266,19 +271,14 @@
 	unsigned long start_pfn, end_pfn;
         static unsigned int smptrap=0;
         unsigned long delay = 0;
+	struct _lowcore *lowcore;
+	int i;
 
         if (smptrap)
                 return;
         smptrap=1;
 
         /*
-         * Setup lowcore information for boot cpu
-         */
-        cpu_init();
-        boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
-        __cpu_logical_map[0] = boot_cpu_addr;
-
-        /*
          * print what head.S has found out about the machine 
          */
 	printk((MACHINE_IS_VM) ?
@@ -287,7 +287,7 @@
 
         ROOT_DEV = to_kdev_t(0x0100);
         memory_start = (unsigned long) &_end;    /* fixit if use $CODELO etc*/
-	memory_end = memory_size;                /* detected in head.s */
+	memory_end = memory_size & ~0x200000UL;  /* detected in head.s */
         init_mm.start_code = PAGE_OFFSET;
         init_mm.end_code = (unsigned long) &_etext;
         init_mm.end_data = (unsigned long) &_edata;
@@ -362,11 +362,26 @@
 	bootmap_size = init_bootmem(start_pfn, end_pfn);
 
 	/*
-	 * Register RAM pages with the bootmem allocator.
+	 * Register RAM areas with the bootmem allocator.
 	 */
-	free_bootmem(start_pfn << PAGE_SHIFT, 
-		     (end_pfn - start_pfn) << PAGE_SHIFT);
+	for (i = 0; i < 16 && memory_chunk[i].size > 0; i++) {
+		unsigned long start_chunk, end_chunk;
 
+		if (memory_chunk[i].type != CHUNK_READ_WRITE)
+			continue;
+		start_chunk = (memory_chunk[i].addr + PAGE_SIZE - 1);
+		start_chunk >>= PAGE_SHIFT;
+		end_chunk = (memory_chunk[i].addr + memory_chunk[i].size);
+		end_chunk >>= PAGE_SHIFT;
+		if (start_chunk < start_pfn)
+			start_chunk = start_pfn;
+		if (end_chunk > end_pfn)
+			end_chunk = end_pfn;
+		if (start_chunk < end_chunk)
+			free_bootmem(start_chunk << PAGE_SHIFT,
+				     (end_chunk - start_chunk) << PAGE_SHIFT);
+	}
+	
         /*
          * Reserve the bootmem bitmap itself as well. We do this in two
          * steps (first step was init_bootmem()) because this catches
@@ -390,6 +405,36 @@
         }
 #endif
 
+        /*
+         * Setup lowcore for boot cpu
+         */
+	lowcore = (struct _lowcore *) 
+		__alloc_bootmem(2*PAGE_SIZE, 2*PAGE_SIZE, 0);
+	memset(lowcore, 0, 2*PAGE_SIZE);
+	lowcore->restart_psw.mask = _RESTART_PSW_MASK;
+	lowcore->restart_psw.addr = (addr_t) &restart_int_handler;
+	lowcore->external_new_psw.mask = _EXT_PSW_MASK;
+	lowcore->external_new_psw.addr = (addr_t) &ext_int_handler;
+	lowcore->svc_new_psw.mask = _SVC_PSW_MASK;
+	lowcore->svc_new_psw.addr = (addr_t) &system_call;
+	lowcore->program_new_psw.mask = _PGM_PSW_MASK;
+	lowcore->program_new_psw.addr = (addr_t) &pgm_check_handler;
+	lowcore->mcck_new_psw.mask = _MCCK_PSW_MASK;
+	lowcore->mcck_new_psw.addr = (addr_t) &mcck_int_handler;
+	lowcore->io_new_psw.mask = _IO_PSW_MASK;
+	lowcore->io_new_psw.addr = (addr_t) &io_int_handler;
+	lowcore->ipl_device = S390_lowcore.ipl_device;
+	lowcore->kernel_stack = ((__u32) &init_task_union) + 16384;
+	lowcore->async_stack = (__u64)
+		__alloc_bootmem(4*PAGE_SIZE, 4*PAGE_SIZE, 0) + 16384;
+	set_prefix((__u32)(__u64) lowcore);
+        cpu_init();
+        boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
+        __cpu_logical_map[0] = boot_cpu_addr;
+
+	/*
+	 * Create kernel page tables and switch to virtual addressing.
+	 */
         paging_init();
 
 	res = alloc_bootmem_low(sizeof(struct resource));
@@ -422,30 +467,49 @@
 }
 
 /*
- *	Get CPU information for use by the procfs.
+ * get_cpuinfo - Get information on one CPU for use by procfs.
+ *
+ *	Prints info on the next CPU into buffer.  Beware, doesn't check for
+ *	buffer overflow.  Current implementation of procfs assumes that the
+ *	resulting data is <= 1K.
+ *
+ * Args:
+ *	buffer	-- you guessed it, the data buffer
+ *	cpu_np	-- Input: next cpu to get (start at 0).  Output: Updated.
+ *
+ *	Returns number of bytes written to buffer.
  */
 
-int get_cpuinfo(char * buffer)
+int get_cpuinfo(char *buffer, unsigned *cpu_np)
 {
         struct cpuinfo_S390 *cpuinfo;
         char *p = buffer;
-        int i;
+	unsigned n;
 
-        p += sprintf(p,"vendor_id       : IBM/S390\n"
-                       "# processors    : %i\n"
-                       "bogomips per cpu: %lu.%02lu\n",
-                       smp_num_cpus, loops_per_jiffy/(500000/HZ),
-                       (loops_per_jiffy/(5000/HZ))%100);
-        for (i = 0; i < smp_num_cpus; i++) {
-                cpuinfo = &safe_get_cpu_lowcore(i).cpu_data;
-                p += sprintf(p,"processor %i: "
-                               "version = %02X,  "
-                               "identification = %06X,  "
-                               "machine = %04X\n",
-                               i, cpuinfo->cpu_id.version,
-                               cpuinfo->cpu_id.ident,
-                               cpuinfo->cpu_id.machine);
-        }
+	n = *cpu_np;
+	while (n < NR_CPUS && (cpu_online_map & (1 << n)) == 0)
+		n++;
+	if (n >= NR_CPUS) {
+		*cpu_np = NR_CPUS;
+		return (0);
+	}
+	*cpu_np = n + 1;
+
+	if (n == 0) {
+		p += sprintf(p, "vendor_id       : IBM/S390\n"
+				"# processors    : %i\n"
+				"bogomips per cpu: %lu.%02lu\n",
+				smp_num_cpus, loops_per_jiffy/(500000/HZ),
+				(loops_per_jiffy/(5000/HZ))%100);
+	}
+	cpuinfo = &safe_get_cpu_lowcore(n).cpu_data;
+	p += sprintf(p, "processor %i: "
+			"version = %02X,  "
+			"identification = %06X,  "
+			"machine = %04X\n",
+			n, cpuinfo->cpu_id.version,
+			cpuinfo->cpu_id.ident,
+			cpuinfo->cpu_id.machine);
         return p - buffer;
 }
 
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/signal.c linux/arch/s390x/kernel/signal.c
--- v2.4.12/linux/arch/s390x/kernel/signal.c	Sun Aug 12 13:27:58 2001
+++ linux/arch/s390x/kernel/signal.c	Thu Oct 11 09:04:57 2001
@@ -24,31 +24,25 @@
 #include <linux/ptrace.h>
 #include <linux/unistd.h>
 #include <linux/stddef.h>
+#include <linux/personality.h>
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
 
-#define DEBUG_SIG 0
-
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-/* pretcode & sig are used to store the return addr on Intel
-   & the signal no as the first parameter we do this differently
-   using gpr14 & gpr2. */
-
-#define SIGFRAME_COMMON \
-__u8     callee_used_stack[__SIGNAL_FRAMESIZE]; \
-struct sigcontext sc; \
-_sigregs sregs; \
-__u8 retcode[S390_SYSCALL_SIZE];
 
 typedef struct 
 {
-	SIGFRAME_COMMON
+	__u8 callee_used_stack[__SIGNAL_FRAMESIZE];
+	struct sigcontext sc;
+	_sigregs sregs;
+	__u8 retcode[S390_SYSCALL_SIZE];
 } sigframe;
 
 typedef struct 
 {
-	SIGFRAME_COMMON
+	__u8 callee_used_stack[__SIGNAL_FRAMESIZE];
+	__u8 retcode[S390_SYSCALL_SIZE];
 	struct siginfo info;
 	struct ucontext uc;
 } rt_sigframe;
@@ -206,7 +200,7 @@
 	err=__copy_from_user(regs,&sregs->regs,sizeof(_s390_regs_common));
 	if(!err)
 	{
-		regs->orig_gpr2 = -1;		/* disable syscall checks */
+		regs->trap = -1;		/* disable syscall checks */
 		regs->psw.mask=(saved_psw.mask&~PSW_MASK_DEBUGCHANGE)|
 		(regs->psw.mask&PSW_MASK_DEBUGCHANGE);
 		regs->psw.addr=(saved_psw.addr&~PSW_ADDR_DEBUGCHANGE)|
@@ -218,53 +212,51 @@
 	return(err);
 }
 
-static int
-restore_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
-		 _sigregs *sregs,sigset_t *set)
-{
-	unsigned int err;
-
-	err=restore_sigregs(regs,sregs);
-	if(!err)
-		err=__copy_from_user(&set->sig,&sc->oldmask,_SIGMASK_COPY_SIZE);
-		return(err);
-}
-
-int sigreturn_common(struct pt_regs *regs,int framesize)
+asmlinkage long sys_sigreturn(struct pt_regs *regs)
 {
 	sigframe *frame = (sigframe *)regs->gprs[15];
 	sigset_t set;
 
 	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
-		return -1;
-	if (restore_sigcontext(&frame->sc,regs,&frame->sregs,&set))
-	        return -1;
+		goto badframe;
+	if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE))
+		goto badframe;
+
 	sigdelsetmask(&set, ~_BLOCKABLE);
 	spin_lock_irq(&current->sigmask_lock);
 	current->blocked = set;
 	recalc_sigpending(current);
 	spin_unlock_irq(&current->sigmask_lock);
-	return 0;
-}
 
-asmlinkage long sys_sigreturn(struct pt_regs *regs)
-{
-
-	if (sigreturn_common(regs,sizeof(sigframe)))
+	if (restore_sigregs(regs, &frame->sregs))
 		goto badframe;
+
 	return regs->gprs[2];
 
 badframe:
 	force_sig(SIGSEGV, current);
 	return 0;
-}	
+}
 
 asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
 {
 	rt_sigframe *frame = (rt_sigframe *)regs->gprs[15];
+	sigset_t set;
 
-	if (sigreturn_common(regs,sizeof(rt_sigframe)))
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
 		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	if (restore_sigregs(regs, &frame->uc.uc_mcontext))
+		goto badframe;
+
 	/* It is more difficult to avoid calling this function than to
 	   call it and ignore errors.  */
 	do_sigaltstack(&frame->uc.uc_stack, NULL, regs->gprs[15]);
@@ -273,7 +265,7 @@
 badframe:
 	force_sig(SIGSEGV, current);
 	return 0;
-}	
+}
 
 /*
  * Set up a signal frame.
@@ -307,58 +299,48 @@
 	return (void *)((sp - frame_size) & -8ul);
 }
 
-static void *setup_frame_common(int sig, struct k_sigaction *ka,
-			sigset_t *set, struct pt_regs * regs,
-				int frame_size,u16 retcode)
+static inline int map_signal(int sig)
 {
-	sigframe *frame;
-	int err;
+	if (current->exec_domain
+	    && current->exec_domain->signal_invmap
+	    && sig < 32)
+		return current->exec_domain->signal_invmap[sig];
+	else
+		return sig;
+}
 
-	frame = get_sigframe(ka, regs,frame_size);
-	if (!access_ok(VERIFY_WRITE, frame,frame_size))
-		return 0;
-	err = save_sigregs(regs,&frame->sregs);
-	if(!err)
-		err=__put_user(&frame->sregs,&frame->sc.sregs);
-	if(!err)
+static void setup_frame(int sig, struct k_sigaction *ka,
+			sigset_t *set, struct pt_regs * regs)
+{
+	sigframe *frame = get_sigframe(ka, regs, sizeof(sigframe));
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe)))
+		goto give_sigsegv;
+
+	if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE))
+		goto give_sigsegv;
+
+	if (save_sigregs(regs, &frame->sregs))
+		goto give_sigsegv;
+	if (__put_user(&frame->sregs, &frame->sc.sregs))
+		goto give_sigsegv;
 
-		err=__copy_to_user(&frame->sc.oldmask,&set->sig,_SIGMASK_COPY_SIZE);
-	if(!err)
-	{
-		regs->gprs[2]=(current->exec_domain
-		           && current->exec_domain->signal_invmap
-		           && sig < 32
-		           ? current->exec_domain->signal_invmap[sig]
-		           : sig);
-		/* Set up registers for signal handler */
-		regs->gprs[15] = (addr_t)frame;
-		regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
-		regs->psw.mask = _USER_PSW_MASK;
-	}
 	/* Set up to return from userspace.  If provided, use a stub
 	   already in userspace.  */
 	if (ka->sa.sa_flags & SA_RESTORER) {
                 regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer);
 	} else {
                 regs->gprs[14] = FIX_PSW(frame->retcode);
-		err |= __put_user(retcode, (u16 *)(frame->retcode));
+		if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, 
+	                       (u16 *)(frame->retcode)))
+			goto give_sigsegv;
 	}
-	return(err ? 0:frame);
-}
 
-static void setup_frame(int sig, struct k_sigaction *ka,
-			sigset_t *set, struct pt_regs * regs)
-{
-	sigframe *frame;
+	/* Set up registers for signal handler */
+	regs->gprs[15] = (addr_t)frame;
+	regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
+	regs->psw.mask = _USER_PSW_MASK;
 
-	if((frame=setup_frame_common(sig,ka,set,regs,sizeof(sigframe),
-		    (S390_SYSCALL_OPCODE|__NR_sigreturn)))==0)
-		goto give_sigsegv;
-#if DEBUG_SIG
-	printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
-		current->comm, current->pid, frame, regs->eip, frame->pretcode);
-#endif
-	/* Martin wants this for pthreads */
+	regs->gprs[2] = map_signal(sig);
 	regs->gprs[3] = (addr_t)&frame->sc;
 
 	/* We forgot to include these in the sigcontext.
@@ -376,34 +358,44 @@
 static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 			   sigset_t *set, struct pt_regs * regs)
 {
-	rt_sigframe *frame;
-	addr_t      orig_sp=regs->gprs[15];
-	int err;
+	int err = 0;
+	rt_sigframe *frame = get_sigframe(ka, regs, sizeof(rt_sigframe));
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe)))
+		goto give_sigsegv;
 
-	if((frame=setup_frame_common(sig,ka,set,regs,sizeof(rt_sigframe),
-		    (S390_SYSCALL_OPCODE|__NR_rt_sigreturn)))==0)
+	if (copy_siginfo_to_user(&frame->info, info))
 		goto give_sigsegv;
-	
-	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(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
-	err |= __put_user(sas_ss_flags(orig_sp),
+	err |= __put_user(sas_ss_flags(regs->gprs[15]),
 			  &frame->uc.uc_stack.ss_flags);
 	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
-	err |= __put_user(&frame->sc,&frame->uc.sc);
-	regs->gprs[3] = (addr_t)&frame->info;
-	regs->gprs[4] = (addr_t)&frame->uc;
-
+	err |= save_sigregs(regs, &frame->uc.uc_mcontext);
+	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 	if (err)
 		goto give_sigsegv;
 
-#if DEBUG_SIG
-	printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
-		current->comm, current->pid, frame, regs->eip, frame->pretcode);
-#endif
+	/* Set up to return from userspace.  If provided, use a stub
+	   already in userspace.  */
+	if (ka->sa.sa_flags & SA_RESTORER) {
+                regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer);
+	} else {
+                regs->gprs[14] = FIX_PSW(frame->retcode);
+		err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, 
+	                          (u16 *)(frame->retcode));
+	}
+
+	/* Set up registers for signal handler */
+	regs->gprs[15] = (addr_t)frame;
+	regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
+	regs->psw.mask = _USER_PSW_MASK;
+
+	regs->gprs[2] = map_signal(sig);
+	regs->gprs[3] = (addr_t)&frame->info;
+	regs->gprs[4] = (addr_t)&frame->uc;
 	return;
 
 give_sigsegv:
@@ -558,13 +550,16 @@
 					continue;
 				/* FALLTHRU */
 
-			case SIGSTOP:
+			case SIGSTOP: {
+				struct signal_struct *sig;
 				set_current_state(TASK_STOPPED);
 				current->exit_code = signr;
-				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
+				sig = current->p_pptr->sig;
+				if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
 					notify_parent(current, SIGCHLD);
 				schedule();
 				continue;
+			}
 
 			case SIGQUIT: case SIGILL: case SIGTRAP:
 			case SIGABRT: case SIGFPE: case SIGSEGV:
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/signal32.c linux/arch/s390x/kernel/signal32.c
--- v2.4.12/linux/arch/s390x/kernel/signal32.c	Wed Apr 11 19:02:29 2001
+++ linux/arch/s390x/kernel/signal32.c	Thu Oct 11 09:04:57 2001
@@ -11,6 +11,7 @@
  *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
  */
 
+#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
@@ -22,32 +23,27 @@
 #include <linux/ptrace.h>
 #include <linux/unistd.h>
 #include <linux/stddef.h>
+#include <linux/personality.h>
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
 #include "linux32.h"
 
-#define DEBUG_SIG 0
-
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-/* pretcode & sig are used to store the return addr on Intel
-   & the signal no as the first parameter we do this differently
-   using gpr14 & gpr2. */
-
-#define SIGFRAME_COMMON32 \
-__u8     callee_used_stack[__SIGNAL_FRAMESIZE32]; \
-struct sigcontext32 sc; \
-_sigregs32 sregs; \
-__u8 retcode[S390_SYSCALL_SIZE];
+#define _USER_PSW_MASK32 0x0701C00080000000
 
 typedef struct 
 {
-	SIGFRAME_COMMON32
+	__u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
+	struct sigcontext32 sc;
+	_sigregs32 sregs;
+	__u8 retcode[S390_SYSCALL_SIZE];
 } sigframe32;
 
 typedef struct 
 {
-	SIGFRAME_COMMON32
+	__u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
+	__u8 retcode[S390_SYSCALL_SIZE];
 	struct siginfo32 info;
 	struct ucontext32 uc;
 } rt_sigframe32;
@@ -328,7 +324,7 @@
 
 	if(!err)
 	{
-		regs->orig_gpr2 = -1;		/* disable syscall checks */
+		regs->trap = -1;		/* disable syscall checks */
 		regs->psw.mask=(saved_psw.mask&~PSW_MASK_DEBUGCHANGE)|
 		(regs->psw.mask&PSW_MASK_DEBUGCHANGE);
 		regs->psw.addr=(saved_psw.addr&~PSW_ADDR_DEBUGCHANGE)|
@@ -342,40 +338,25 @@
 	return(err);
 }
 
-static int
-restore_sigcontext32(struct sigcontext32 *sc, struct pt_regs *regs,
-		 _sigregs32 *sregs,sigset_t *set)
-{
-	unsigned int err;
-
-	err=restore_sigregs32(regs,sregs);
-	if(!err)
-		err=__copy_from_user(&set->sig,&sc->oldmask,_SIGMASK_COPY_SIZE32);
-	return(err);
-}
-
-int sigreturn_common32(struct pt_regs *regs)
+asmlinkage long sys32_sigreturn(struct pt_regs *regs)
 {
 	sigframe32 *frame = (sigframe32 *)regs->gprs[15];
 	sigset_t set;
 
 	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
-		return -1;
-	if (restore_sigcontext32(&frame->sc,regs,&frame->sregs,&set))
-	        return -1;
+		goto badframe;
+	if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32))
+		goto badframe;
+
 	sigdelsetmask(&set, ~_BLOCKABLE);
 	spin_lock_irq(&current->sigmask_lock);
 	current->blocked = set;
 	recalc_sigpending(current);
 	spin_unlock_irq(&current->sigmask_lock);
-	return 0;
-}
 
-asmlinkage long sys32_sigreturn(struct pt_regs *regs)
-{
-
-	if (sigreturn_common32(regs))
+	if (restore_sigregs32(regs, &frame->sregs))
 		goto badframe;
+
 	return regs->gprs[2];
 
 badframe:
@@ -386,11 +367,23 @@
 asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
 {
 	rt_sigframe32 *frame = (rt_sigframe32 *)regs->gprs[15];
+	sigset_t set;
 	stack_t st;
 	int err;
 	mm_segment_t old_fs = get_fs();
 
-	if (sigreturn_common32(regs))
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	if (restore_sigregs32(regs, &frame->uc.uc_mcontext))
 		goto badframe;
 
 	err = __get_user(st.ss_sp, &frame->uc.uc_stack.ss_sp);
@@ -399,17 +392,18 @@
 	err |= __get_user(st.ss_flags, &frame->uc.uc_stack.ss_flags);
 	if (err)
 		goto badframe; 
-	set_fs (KERNEL_DS);   
+
 	/* It is more difficult to avoid calling this function than to
 	   call it and ignore errors.  */
+	set_fs (KERNEL_DS);   
 	do_sigaltstack(&st, NULL, regs->gprs[15]);
 	set_fs (old_fs);
 
 	return regs->gprs[2];
 
 badframe:
-	force_sig(SIGSEGV, current);
-	return 0;
+        force_sig(SIGSEGV, current);
+        return 0;
 }	
 
 /*
@@ -444,58 +438,54 @@
 	return (void *)((sp - frame_size) & -8ul);
 }
 
-static void *setup_frame_common32(int sig, struct k_sigaction *ka,
-			sigset_t *set, struct pt_regs * regs,
-				int frame_size,u16 retcode)
+static inline int map_signal(int sig)
 {
-	sigframe32 *frame;
-	int err;
+	if (current->exec_domain
+	    && current->exec_domain->signal_invmap
+	    && sig < 32)
+		return current->exec_domain->signal_invmap[sig];
+        else
+		return sig;
+}
 
-	frame = get_sigframe(ka, regs,frame_size);
-	if (!access_ok(VERIFY_WRITE, frame,frame_size))
-		return 0;
-	err = save_sigregs32(regs,&frame->sregs);
-	if(!err)
-		err=__put_user(&frame->sregs,&frame->sc.sregs);
-	if(!err)
+static void setup_frame32(int sig, struct k_sigaction *ka,
+			sigset_t *set, struct pt_regs * regs)
+{
+	sigframe32 *frame = get_sigframe(ka, regs, sizeof(sigframe32));
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe32)))
+		goto give_sigsegv;
+
+	if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE32))
+		goto give_sigsegv;
+
+	if (save_sigregs32(regs, &frame->sregs))
+		goto give_sigsegv;
+	if (__put_user(&frame->sregs, &frame->sc.sregs))
+		goto give_sigsegv;
 
-		err=__copy_to_user(&frame->sc.oldmask,&set->sig,_SIGMASK_COPY_SIZE32);
-	if(!err)
-	{
-		regs->gprs[2]=(current->exec_domain
-		           && current->exec_domain->signal_invmap
-		           && sig < 32
-		           ? current->exec_domain->signal_invmap[sig]
-		           : sig);
-		/* Set up registers for signal handler */
-		regs->gprs[15] = (addr_t)frame;
-		regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
-	}
 	/* Set up to return from userspace.  If provided, use a stub
 	   already in userspace.  */
 	if (ka->sa.sa_flags & SA_RESTORER) {
-                regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer);
+		regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer);
 	} else {
-                regs->gprs[14] = FIX_PSW(frame->retcode);
-		err |= __put_user(retcode, (u16 *)(frame->retcode));
-	}
-	return(err ? 0:frame);
-}
+		regs->gprs[14] = FIX_PSW(frame->retcode);
+		if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
+		               (u16 *)(frame->retcode)))
+			goto give_sigsegv;
+        }
 
-static void setup_frame32(int sig, struct k_sigaction *ka,
-			sigset_t *set, struct pt_regs * regs)
-{
-	sigframe32 *frame;
-         
-	if((frame=setup_frame_common32(sig,ka,set,regs,sizeof(sigframe32),
-		    (S390_SYSCALL_OPCODE|__NR_sigreturn)))==0)
-		goto give_sigsegv;
-#if DEBUG_SIG
-	printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
-		current->comm, current->pid, frame, regs->eip, frame->pretcode);
-#endif
-	 /* Martin wants this for pthreads */
-	regs->gprs[3] = (addr_t)&frame->sc;   
+	/* Set up registers for signal handler */
+	regs->gprs[15] = (addr_t)frame;
+	regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
+	regs->psw.mask = _USER_PSW_MASK32;
+
+	regs->gprs[2] = map_signal(sig);
+	regs->gprs[3] = (addr_t)&frame->sc;
+
+	/* We forgot to include these in the sigcontext.
+	   To avoid breaking binary compatibility, they are passed as args. */
+	regs->gprs[4] = current->thread.trap_no;
+	regs->gprs[5] = current->thread.prot_addr;
 	return;
 
 give_sigsegv:
@@ -507,33 +497,44 @@
 static void setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
 			   sigset_t *set, struct pt_regs * regs)
 {
-	rt_sigframe32 *frame;
-	addr_t      orig_sp=regs->gprs[15];
-	int err;
+	int err = 0;
+	rt_sigframe32 *frame = get_sigframe(ka, regs, sizeof(rt_sigframe32));
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe32)))
+		goto give_sigsegv;
 
-	if((frame=setup_frame_common32(sig,ka,set,regs,sizeof(rt_sigframe32),
-		    (S390_SYSCALL_OPCODE|__NR_rt_sigreturn)))==0)
+	if (copy_siginfo_to_user32(&frame->info, info))
 		goto give_sigsegv;
-	
-	err = copy_siginfo_to_user32(&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(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
-	err |= __put_user(sas_ss_flags(orig_sp),
-			  &frame->uc.uc_stack.ss_flags);
+	err |= __put_user(sas_ss_flags(regs->gprs[15]),
+	                  &frame->uc.uc_stack.ss_flags);
 	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
-	regs->gprs[3] = (addr_t)&frame->info;
-	regs->gprs[4] = (addr_t)&frame->uc;
-
+	err |= save_sigregs32(regs, &frame->uc.uc_mcontext);
+	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 	if (err)
 		goto give_sigsegv;
 
-#if DEBUG_SIG
-	printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
-		current->comm, current->pid, frame, regs->eip, frame->pretcode);
-#endif
+	/* Set up to return from userspace.  If provided, use a stub
+	   already in userspace.  */
+	if (ka->sa.sa_flags & SA_RESTORER) {
+		regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer);
+	} else {
+		regs->gprs[14] = FIX_PSW(frame->retcode);
+		err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
+		                  (u16 *)(frame->retcode));
+	}
+
+	/* Set up registers for signal handler */
+	regs->gprs[15] = (addr_t)frame;
+	regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
+	regs->psw.mask = _USER_PSW_MASK32;
+
+	regs->gprs[2] = map_signal(sig);
+	regs->gprs[3] = (addr_t)&frame->info;
+	regs->gprs[4] = (addr_t)&frame->uc;
 	return;
 
 give_sigsegv:
@@ -551,7 +552,7 @@
 	      siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
 {
 	/* Are we from a system call? */
-	if (regs->orig_gpr2 >= 0) {
+	if (regs->trap == __LC_SVC_OLD_PSW) {
 		/* If so, check system call restarting.. */
 		switch (regs->gprs[2]) {
 			case -ERESTARTNOHAND:
@@ -692,12 +693,12 @@
 
 			case SIGQUIT: case SIGILL: case SIGTRAP:
 			case SIGABRT: case SIGFPE: case SIGSEGV:
+			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
                                 if (do_coredump(signr, regs))
                                         exit_code |= 0x80;
                                 /* FALLTHRU */
 
 			default:
-				lock_kernel();
 				sigaddset(&current->pending.signal, signr);
 				recalc_sigpending(current);
 				current->flags |= PF_SIGNALED;
@@ -712,7 +713,7 @@
 	}
 
 	/* Did we come from a system call? */
-	if ( regs->trap ==  __LC_SVC_OLD_PSW /* System Call! */ ) {
+	if ( regs->trap == __LC_SVC_OLD_PSW /* System Call! */ ) {
 		/* Restart the system call - no handlers present */
 		if (regs->gprs[2] == -ERESTARTNOHAND ||
 		    regs->gprs[2] == -ERESTARTSYS ||
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/smp.c linux/arch/s390x/kernel/smp.c
--- v2.4.12/linux/arch/s390x/kernel/smp.c	Sun Aug 12 13:27:58 2001
+++ linux/arch/s390x/kernel/smp.c	Thu Oct 11 09:04:57 2001
@@ -57,6 +57,8 @@
 
 spinlock_t       kernel_flag = SPIN_LOCK_UNLOCKED;
 
+unsigned long	 cpu_online_map;
+
 /*
  *      Setup routine for controlling SMP activation
  *
@@ -92,6 +94,95 @@
 
 extern void reipl(unsigned long devno);
 
+static sigp_ccode smp_ext_bitcall(int, ec_bit_sig);
+static void smp_ext_bitcall_others(ec_bit_sig);
+
+/*
+ * Structure and data for smp_call_function(). This is designed to minimise
+ * static memory requirements. It also looks cleaner.
+ */
+static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
+
+struct call_data_struct {
+	void (*func) (void *info);
+	void *info;
+	atomic_t started;
+	atomic_t finished;
+	int wait;
+};
+
+static struct call_data_struct * call_data;
+
+/*
+ * 'Call function' interrupt callback
+ */
+static void do_call_function(void)
+{
+	void (*func) (void *info) = call_data->func;
+	void *info = call_data->info;
+	int wait = call_data->wait;
+
+	atomic_inc(&call_data->started);
+	(*func)(info);
+	if (wait)
+		atomic_inc(&call_data->finished);
+}
+
+/*
+ * this function sends a 'generic call function' IPI to all other CPUs
+ * in the system.
+ */
+
+int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
+			int wait)
+/*
+ * [SUMMARY] Run a function on all other CPUs.
+ * <func> The function to run. This must be fast and non-blocking.
+ * <info> An arbitrary pointer to pass to the function.
+ * <nonatomic> currently unused.
+ * <wait> If true, wait (atomically) until function has completed on other CPUs.
+ * [RETURNS] 0 on success, else a negative status code. Does not return until
+ * remote CPUs are nearly ready to execute <<func>> or are or have executed.
+ *
+ * You must not call this function with disabled interrupts or from a
+ * hardware interrupt handler, you may call it from a bottom half handler.
+ */
+{
+	struct call_data_struct data;
+	int cpus = smp_num_cpus-1;
+
+	if (!cpus || !atomic_read(&smp_commenced))
+		return 0;
+
+	data.func = func;
+	data.info = info;
+	atomic_set(&data.started, 0);
+	data.wait = wait;
+	if (wait)
+		atomic_set(&data.finished, 0);
+
+	spin_lock_bh(&call_lock);
+	call_data = &data;
+	/* Send a message to all other CPUs and wait for them to respond */
+        smp_ext_bitcall_others(ec_call_function);
+
+	/* Wait for response */
+	while (atomic_read(&data.started) != cpus)
+		barrier();
+
+	if (wait)
+		while (atomic_read(&data.finished) != cpus)
+			barrier();
+	spin_unlock_bh(&call_lock);
+
+	return 0;
+}
+
+
+/*
+ * Various special callbacks
+ */
+
 void do_machine_restart(void)
 {
         smp_send_stop();
@@ -148,7 +239,6 @@
 
 void do_ext_call_interrupt(struct pt_regs *regs, __u16 code)
 {
-        ec_ext_call *ec, *next;
         unsigned long bits;
 
         /*
@@ -167,138 +257,15 @@
 		do_machine_halt();
         if (test_bit(ec_power_off, &bits))
 		do_machine_power_off();
-
-        /*
-         * Handle external call commands with a parameter area
-         */
-	ec = (ec_ext_call *) xchg(&S390_lowcore.ext_call_queue, 0);
-        if (ec == NULL)
-                return;   /* no command signals */
-
-        /* Make a fifo out of the lifo */
-        next = ec->next;
-        ec->next = NULL;
-        while (next != NULL) {
-                ec_ext_call *tmp = next->next;
-                next->next = ec;
-                ec = next;
-                next = tmp;
-        }
-
-        /* Execute every sigp command on the queue */
-        while (ec != NULL) {
-                switch (ec->cmd) {
-                case ec_callback_async: {
-                        void (*func)(void *info);
-                        void *info;
-
-                        func = ec->func;
-                        info = ec->info;
-                        atomic_set(&ec->status,ec_executing);
-                        (func)(info);
-                        return;
-                }
-                case ec_callback_sync:
-                        atomic_set(&ec->status,ec_executing);
-                        (ec->func)(ec->info);
-                        atomic_set(&ec->status,ec_done);
-                        return;
-                default:
-                }
-                ec = ec->next;
-        }
-}
-
-/*
- * Swap in a new request to external call queue 
- */
-static inline void smp_add_ext_call(ec_ext_call *ec, struct _lowcore *lowcore)
-{
-	int success;
-
-	while (1) {
-		ec->next = (ec_ext_call*) lowcore->ext_call_queue;
-		__asm__ __volatile__ (
-                        "   lgr 0,%2\n"
-			"   csg 0,%3,%1\n"
-			"   ipm %0\n"
-			"   srl %0,28\n"
-			: "=d" (success), "+m" (lowcore->ext_call_queue)
-			: "d" (ec->next), "d" (ec)
-			: "cc", "0" );
-		if (success == 0) break;
-	}
-}
-
-/*
- * Send an external call sigp to another cpu and wait for its completion.
- */
-sigp_ccode
-smp_ext_call(int cpu, void (*func)(void *info), void *info, int wait)
-{
-        sigp_ccode ccode;
-        ec_ext_call ec;
-
-        ec.cmd = wait ? ec_callback_sync:ec_callback_async;
-        atomic_set(&ec.status, ec_pending);
-        ec.func = func;
-	ec.info = info;
-	/* swap in new request to external call queue */
-	smp_add_ext_call(&ec, &get_cpu_lowcore(cpu));
-        /*
-         * We try once to deliver the signal. There are four possible
-         * return codes:
-         * 0) Order code accepted - can't show up on an external call
-         * 1) Status stored - fine, wait for completion.
-         * 2) Busy - there is another signal pending. Thats fine too, because
-         *    do_ext_call from the pending signal will execute all signals on
-         *    the queue. We wait for completion.
-         * 3) Not operational - something very bad has happened to the cpu.
-         *    do not wait for completion.
-         */
-        ccode = signal_processor(cpu, sigp_external_call);
-
-        if (ccode != sigp_not_operational)
-                /* wait for completion, FIXME: possible seed of a deadlock */
-                while (atomic_read(&ec.status) != (wait?ec_done:ec_executing));
-
-        return ccode;
-}
-
-/*
- * Send a callback sigp to every other cpu in the system.
- */
-void smp_ext_call_others(void (*func)(void *info), void *info, int wait)
-{
-        ec_ext_call ec[NR_CPUS];
-        sigp_ccode ccode;
-        int i;
-
-        for (i = 0; i < smp_num_cpus; i++) {
-                if (smp_processor_id() == i)
-                        continue;
-		ec[i].cmd = wait ? ec_callback_sync : ec_callback_async;
-		atomic_set(&ec[i].status, ec_pending);
-		ec[i].func = func;
-		ec[i].info = info;
-		smp_add_ext_call(ec+i, &get_cpu_lowcore(i));
-                ccode = signal_processor(i, sigp_external_call);
-        }
-
-        /* wait for completion, FIXME: possible seed of a deadlock */
-        for (i = 0; i < smp_num_cpus; i++) {
-                if (smp_processor_id() == i)
-                        continue;
-                while (atomic_read(&ec[i].status) != 
-		       (wait ? ec_done:ec_executing));
-        }
+        if (test_bit(ec_call_function, &bits))
+		do_call_function();
 }
 
 /*
  * Send an external call sigp to another cpu and return without waiting
  * for its completion.
  */
-sigp_ccode smp_ext_bitcall(int cpu, ec_bit_sig sig)
+static sigp_ccode smp_ext_bitcall(int cpu, ec_bit_sig sig)
 {
         sigp_ccode ccode;
 
@@ -314,7 +281,7 @@
  * Send an external call sigp to every other cpu in the system and
  * return without waiting for its completion.
  */
-void smp_ext_bitcall_others(ec_bit_sig sig)
+static void smp_ext_bitcall_others(ec_bit_sig sig)
 {
         sigp_ccode ccode;
         int i;
@@ -331,51 +298,6 @@
 }
 
 /*
- * cycles through all the cpus,
- * returns early if info is not NULL & the processor has something
- * of intrest to report in the info structure.
- * it returns the next cpu to check if it returns early.
- * i.e. it should be used as follows if you wish to receive info.
- * next_cpu=0;
- * do
- * {
- *    info->cpu=next_cpu;
- *    next_cpu=smp_signal_others(order_code,parameter,1,info);
- *    ... check info here
- * } while(next_cpu<=smp_num_cpus)
- *
- *  if you are lazy just use it like
- * smp_signal_others(order_code,parameter,0,1,NULL);
- */
-int smp_signal_others(sigp_order_code order_code, u32 parameter,
-                      int spin, sigp_info *info)
-{
-        sigp_ccode   ccode;
-        u32          dummy;
-        u16          i;
-
-        if (info)
-                info->intresting = 0;
-        for (i = (info ? info->cpu : 0); i < smp_num_cpus; i++) {
-                if (smp_processor_id() != i) {
-                        do {
-                                ccode = signal_processor_ps(
-                                        (info ? &info->status : &dummy),
-                                        parameter, i, order_code);
-                        } while(spin && ccode == sigp_busy);
-                        if (info && ccode != sigp_order_code_accepted) {
-                                info->intresting = 1;
-                                info->cpu = i;
-                                info->ccode = ccode;
-                                i++;
-                                break;
-                        }
-                }
-        }
-        return i;
-}
-
-/*
  * this function sends a 'stop' sigp to all other CPUs in the system.
  * it goes straight through.
  */
@@ -392,7 +314,18 @@
 
         /* stop all processors */
 
-        smp_signal_others(sigp_stop, 0, 1, NULL);
+        for (i =  0; i < smp_num_cpus; i++) {
+                if (smp_processor_id() != i) {
+                        int ccode;
+                        do {
+                                ccode = signal_processor_ps(
+                                   &dummy,
+                                   0,
+                                   i,
+                                   sigp_stop);
+                        } while(ccode == sigp_busy);
+                }
+        }
 
         /* store status of all processors in their lowcores (real 0) */
 
@@ -469,7 +402,7 @@
                 parms.end_ctl = cr;
                 parms.orvals[cr] = 1 << bit;
                 parms.andvals[cr] = -1L;
-                smp_ext_call_others(smp_ctl_bit_callback, &parms, 1);
+                smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
         }
         __ctl_set_bit(cr, bit);
 }
@@ -485,34 +418,11 @@
                 parms.end_ctl = cr;
                 parms.orvals[cr] = 0;
                 parms.andvals[cr] = ~(1L << bit);
-                smp_ext_call_others(smp_ctl_bit_callback, &parms, 1);
+                smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
         }
         __ctl_clear_bit(cr, bit);
 }
 
-/*
- * Call a function on all other processors
- */
-
-int
-smp_call_function(void (*func)(void *info), void *info, int retry, int wait)
-/*
- * [SUMMARY] Run a function on all other CPUs.
- * <func> The function to run. This must be fast and non-blocking.
- * <info> An arbitrary pointer to pass to the function.
- * <retry> currently unused.
- * <wait> If true, wait (atomically) until function has completed on other CPUs.
- * [RETURNS] 0 on success, else a negative status code. Does not return until
- * remote CPUs are nearly ready to execute <<func>> or are or have executed.
- *
- * You must not call this function with disabled interrupts or from a
- * hardware interrupt handler, you may call it from a bottom half handler.
- */
-{
-        if (atomic_read(&smp_commenced) != 0)
-                smp_ext_call_others(func, info, wait);
-        return 0;
-}
 
 /*
  * Lets check how many CPUs we have.
@@ -607,15 +517,20 @@
         init_tasks[cpu] = idle;
 
         cpu_lowcore=&get_cpu_lowcore(cpu);
-        cpu_lowcore->kernel_stack=idle->thread.ksp;
-        __asm__ __volatile__("stctg 0,15,%0\n\t"
-                             "stam  0,15,%1"
+	cpu_lowcore->save_area[15] = idle->thread.ksp;
+	cpu_lowcore->kernel_stack = (idle->thread.ksp | 16383) + 1;
+        __asm__ __volatile__("la    1,%0\n\t"
+			     "stctg 0,15,0(1)\n\t"
+			     "la    1,%1\n\t"
+                             "stam  0,15,0(1)"
                              : "=m" (cpu_lowcore->cregs_save_area[0]),
                                "=m" (cpu_lowcore->access_regs_save_area[0])
-                             : : "memory");
+                             : : "1", "memory");
 
         eieio();
         signal_processor(cpu,sigp_restart);
+	/* Mark this cpu as online. */
+	set_bit(cpu, &cpu_online_map);
 }
 
 /*
@@ -643,6 +558,7 @@
 void __init smp_boot_cpus(void)
 {
         struct _lowcore *curr_lowcore;
+	unsigned long async_stack;
         sigp_ccode   ccode;
         int i;
 
@@ -673,8 +589,16 @@
                         printk("smp_boot_cpus failed to allocate prefix memory\n");
                         break;
                 }
+		async_stack = __get_free_pages(GFP_KERNEL,2);
+		if (async_stack == 0) {
+			printk("smp_boot_cpus failed to allocate asyncronous"
+			       " interrupt stack\n");
+			free_page((unsigned long) curr_lowcore);
+			break;
+		}
                 lowcore_ptr[i] = curr_lowcore;
                 memcpy(curr_lowcore, &S390_lowcore, sizeof(struct _lowcore));
+		curr_lowcore->async_stack = async_stack + (4 * PAGE_SIZE);
                 /*
                  * Most of the parameters are set up when the cpu is
                  * started up.
@@ -733,8 +657,6 @@
                 s390_do_profile(regs->psw.addr);
 
         if (!--prof_counter[cpu]) {
-                int system = 1-user;
-                struct task_struct * p = current;
 
                 /*
                  * The multiplier may have changed since the last time we got
@@ -756,9 +678,7 @@
                  * WrongThing (tm) to do.
                  */
 
-                irq_enter(cpu, 0);
 		update_process_times(user);
-                irq_exit(cpu, 0);
         }
 }
 
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/time.c linux/arch/s390x/kernel/time.c
--- v2.4.12/linux/arch/s390x/kernel/time.c	Sun Aug 12 13:27:58 2001
+++ linux/arch/s390x/kernel/time.c	Thu Oct 11 09:04:57 2001
@@ -155,17 +155,16 @@
 extern __u16 boot_cpu_addr;
 #endif
 
-void do_timer_interrupt(struct pt_regs *regs,int error_code)
+void do_timer_interrupt(struct pt_regs *regs, __u16 error_code)
 {
-        unsigned long flags;
+	int cpu = smp_processor_id();
+
+	irq_enter(cpu, 0);
 
         /*
          * reset timer to 10ms minus time already elapsed
          * since timer-interrupt pending
          */
- 
-        save_flags(flags);
-        cli();
 #ifdef CONFIG_SMP
 	if(S390_lowcore.cpu_data.cpu_addr==boot_cpu_addr) {
 		write_lock(&xtime_lock);
@@ -201,8 +200,8 @@
 		write_unlock(&xtime_lock);
 #endif
 	}
-        restore_flags(flags);
 
+	irq_exit(cpu, 0);
 }
 
 /*
@@ -256,4 +255,7 @@
         init_timer_cc -= 0x8126d60e46000000LL -
                          (0x3c26700LL*1000000*4096);
         tod_to_timeval(init_timer_cc, &xtime);
+
+	/* Set do_get_fast_time function pointer.  */
+	do_get_fast_time = do_gettimeofday;
 }
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/traps.c linux/arch/s390x/kernel/traps.c
--- v2.4.12/linux/arch/s390x/kernel/traps.c	Sun Aug 12 13:27:58 2001
+++ linux/arch/s390x/kernel/traps.c	Thu Oct 11 09:04:57 2001
@@ -31,7 +31,6 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/atomic.h>
-#include <asm/mathemu.h>
 #if CONFIG_REMOTE_DEBUG
 #include <asm/gdb-stub.h>
 #endif
@@ -59,14 +58,16 @@
 extern void pfault_interrupt(struct pt_regs *regs, __u16 error_code);
 #endif
 
-spinlock_t die_lock;
+spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
 
 void die(const char * str, struct pt_regs * regs, long err)
 {
         console_verbose();
         spin_lock_irq(&die_lock);
+	bust_spinlocks(1);
         printk("%s: %04lx\n", str, err & 0xffff);
         show_regs(regs);
+	bust_spinlocks(0);
         spin_unlock_irq(&die_lock);
         do_exit(SIGSEGV);
 }
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/wrapper32.S linux/arch/s390x/kernel/wrapper32.S
--- v2.4.12/linux/arch/s390x/kernel/wrapper32.S	Tue Feb 13 14:13:44 2001
+++ linux/arch/s390x/kernel/wrapper32.S	Thu Oct 11 09:04:57 2001
@@ -1069,3 +1069,23 @@
 	llgfr	%r4,%r4			# unsigned long
 	jg	sys32_fcntl64		# branch to system call
 
+	.globl	sys32_stat64_wrapper
+sys32_stat64_wrapper:
+	llgtr	%r2,%r2			# char *
+	llgtr	%r3,%r3			# struct stat64 *
+	llgfr	%r4,%r4			# long
+	jg	sys32_stat64		# branch to system call
+
+	.globl	sys32_lstat64_wrapper
+sys32_lstat64_wrapper:
+	llgtr	%r2,%r2			# char *
+	llgtr	%r3,%r3			# struct stat64 *
+	llgfr	%r4,%r4			# long
+	jg	sys32_lstat64		# branch to system call
+
+	.globl	sys32_fstat64_wrapper
+sys32_fstat64_wrapper:
+	llgfr	%r2,%r2			# unsigned long
+	llgtr	%r3,%r3			# struct stat64 *
+	llgfr	%r4,%r4			# long
+	jg	sys32_fstat64		# branch to system call
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/mm/extable.c linux/arch/s390x/mm/extable.c
--- v2.4.12/linux/arch/s390x/mm/extable.c	Tue Feb 13 14:13:44 2001
+++ linux/arch/s390x/mm/extable.c	Thu Oct 11 09:04:57 2001
@@ -10,6 +10,7 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/spinlock.h>
 #include <asm/uaccess.h>
 
 extern const struct exception_table_entry __start___ex_table[];
@@ -36,26 +37,32 @@
         return 0;
 }
 
+extern spinlock_t modlist_lock;
+
 unsigned long
 search_exception_table(unsigned long addr)
 {
-	unsigned long ret;
+	unsigned long ret = 0;
+	unsigned long flags;
 
 #ifndef CONFIG_MODULES
 	/* There is only the kernel to search.  */
 	ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
-	if (ret) return FIX_PSW(ret);
+	return ret;
 #else
 	/* The kernel is the last "module" -- no need to treat it special.  */
 	struct module *mp;
+
+	spin_lock_irqsave(&modlist_lock, flags);
 	for (mp = module_list; mp != NULL; mp = mp->next) {
-		if (mp->ex_table_start == NULL)
+		if (mp->ex_table_start == NULL || !(mp->flags&(MOD_RUNNING|MOD_INITIALIZING)))
 			continue;
 		ret = search_one_table(mp->ex_table_start,
 				       mp->ex_table_end - 1, addr);
-		if (ret) return FIX_PSW(ret);
+		if (ret) 
+			break;
 	}
+	spin_unlock_irqrestore(&modlist_lock, flags);
+	return ret;
 #endif
-
-	return 0;
 }
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/mm/fault.c linux/arch/s390x/mm/fault.c
--- v2.4.12/linux/arch/s390x/mm/fault.c	Sun Aug 12 13:27:59 2001
+++ linux/arch/s390x/mm/fault.c	Thu Oct 11 09:04:57 2001
@@ -4,6 +4,7 @@
  *  S390 version
  *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
  *    Author(s): Hartmut Penner (hp@de.ibm.com)
+ *               Ulrich Weigand (uweigand@de.ibm.com)
  *
  *  Derived from "arch/i386/mm/fault.c"
  *    Copyright (C) 1995  Linus Torvalds
@@ -22,6 +23,7 @@
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/init.h>
+#include <linux/console.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -33,33 +35,33 @@
 #endif
 
 extern void die(const char *,struct pt_regs *,long);
+static void force_sigsegv(struct task_struct *tsk, int code, void *address);
 
 extern spinlock_t timerlist_lock;
 
 /*
  * Unlock any spinlocks which will prevent us from getting the
- * message out
+ * message out (timerlist_lock is acquired through the
+ * console unblank code)
  */
 void bust_spinlocks(int yes)
 {
-        spin_lock_init(&timerlist_lock);
-        if (yes) {
-                oops_in_progress = 1;
-#ifdef CONFIG_SMP
-                atomic_set(&global_irq_lock,0);
-#endif
-        } else {
-                int loglevel_save = console_loglevel;
-                oops_in_progress = 0;
-                /*
-                 * OK, the message is on the console.  Now we call printk()
-                 * without oops_in_progress set so that printk will give klogd
-                 * a poke.  Hold onto your hats...
-                 */
-                console_loglevel = 15;          /* NMI oopser may have shut the console up */
-                printk(" ");
-                console_loglevel = loglevel_save;
-        }
+	spin_lock_init(&timerlist_lock);
+	if (yes) {
+		oops_in_progress = 1;
+	} else {
+		int loglevel_save = console_loglevel;
+		oops_in_progress = 0;
+		console_unblank();
+		/*
+		 * OK, the message is on the console.  Now we call printk()
+		 * without oops_in_progress set so that printk will give klogd
+		 * a poke.  Hold onto your hats...
+		 */
+		console_loglevel = 15;
+		printk(" ");
+		console_loglevel = loglevel_save;
+	}
 }
 
 /*
@@ -84,6 +86,29 @@
 	int si_code = SEGV_MAPERR;
 	int kernel_address = 0;
 
+        tsk = current;
+        mm = tsk->mm;
+	
+	/* 
+         * Check for low-address protection.  This needs to be treated
+	 * as a special case because the translation exception code 
+	 * field is not guaranteed to contain valid data in this case.
+	 */
+	if ((error_code & 0xff) == 4 && !(S390_lowcore.trans_exc_code & 4)) {
+
+		/* Low-address protection hit in kernel mode means 
+		   NULL pointer write access in kernel mode.  */
+ 		if (!(regs->psw.mask & PSW_PROBLEM_STATE)) {
+			address = 0;
+			kernel_address = 1;
+			goto no_context;
+		}
+
+		/* Low-address protection hit in user mode 'cannot happen'.  */
+		die ("Low-address protection", regs, error_code);
+        	do_exit(SIGKILL);
+	}
+
         /* 
          * get the failing address 
          * more specific the segment and page table portion of 
@@ -92,11 +117,6 @@
 
         address = S390_lowcore.trans_exc_code&-4096L;
 
-        tsk = current;
-        mm = tsk->mm;
-
-        if (in_interrupt() || !mm)
-                goto no_context;
 
 	/*
 	 * Check which address space the address belongs to
@@ -127,6 +147,7 @@
 			}
 		}
 		die("page fault via unknown access register", regs, error_code);
+        	do_exit(SIGKILL);
 		break;
 
 	case 2: /* Secondary Segment Table Descriptor */
@@ -135,6 +156,11 @@
 		break;
 	}
 
+	/*
+	 * Check whether we have a user MM in the first place.
+	 */
+        if (in_interrupt() || !mm)
+                goto no_context;
 
 	/*
 	 * When we get here, the fault happened in the current
@@ -144,10 +170,8 @@
         down_read(&mm->mmap_sem);
 
         vma = find_vma(mm, address);
-        if (!vma) {
-	        printk("no vma for address %lX\n",address);
+        if (!vma)
                 goto bad_area;
-        }
         if (vma->vm_start <= address) 
                 goto good_area;
         if (!(vma->vm_flags & VM_GROWSDOWN))
@@ -177,6 +201,7 @@
                        goto bad_area;
         }
 
+ survive:
 	/*
 	 * If for any reason at all we couldn't handle the fault,
 	 * make sure we exit gracefully rather than endlessly redo
@@ -207,7 +232,6 @@
 
         /* User mode accesses just cause a SIGSEGV */
         if (regs->psw.mask & PSW_PROBLEM_STATE) {
-		struct siginfo si;
                 tsk->thread.prot_addr = address;
                 tsk->thread.trap_no = error_code;
 #ifndef CONFIG_SYSCTL
@@ -224,10 +248,8 @@
 			show_regs(regs);
 		}
 #endif
-		si.si_signo = SIGSEGV;
-		si.si_code = si_code;
-		si.si_addr = (void*) address;
-		force_sig_info(SIGSEGV, &si, tsk);
+
+		force_sigsegv(tsk, si_code, (void *)address);
                 return;
 	}
 
@@ -242,6 +264,7 @@
  * Oops. The kernel tried to access some bad page. We'll have to
  * terminate things with extreme prejudice.
  */
+
         if (kernel_address)
                 printk(KERN_ALERT "Unable to handle kernel pointer dereference"
         	       " at virtual kernel address %016lx\n", address);
@@ -249,10 +272,6 @@
                 printk(KERN_ALERT "Unable to handle kernel paging request"
 		       " at virtual user address %016lx\n", address);
 
-/*
- * need to define, which information is useful here
- */
-
         die("Oops", regs, error_code);
         do_exit(SIGKILL);
 
@@ -263,6 +282,12 @@
 */
 out_of_memory:
 	up_read(&mm->mmap_sem);
+	if (tsk->pid == 1) {
+		tsk->policy |= SCHED_YIELD;
+		schedule();
+		down_read(&mm->mmap_sem);
+		goto survive;
+	}
 	printk("VM: killing process %s\n", tsk->comm);
 	if (regs->psw.mask & PSW_PROBLEM_STATE)
 		do_exit(SIGKILL);
@@ -284,6 +309,20 @@
 		goto no_context;
 }
 
+/*
+ * Send SIGSEGV to task.  This is an external routine
+ * to keep the stack usage of do_page_fault small.
+ */
+static void force_sigsegv(struct task_struct *tsk, int code, void *address)
+{
+	struct siginfo si;
+	si.si_signo = SIGSEGV;
+	si.si_code = code;
+	si.si_addr = address;
+	force_sig_info(SIGSEGV, &si, tsk);
+}
+
+
 #ifdef CONFIG_PFAULT
 /*
  * 'pfault' pseudo page faults routines.
@@ -316,13 +355,11 @@
        int resolved;
 } pseudo_wait_t;
 
-static pseudo_wait_t *pseudo_lock_queue = NULL;
-static spinlock_t pseudo_wait_spinlock; /* spinlock to protect lock queue */
-
 int pfault_init(void)
 {
 	pfault_refbk_t refbk =
-	{ 0x258, 0, 5, 2, __LC_KERNEL_STACK, 1ULL << 48, 1ULL << 48, 0ULL };
+	{ 0x258, 0, 5, 2, __LC_KERNEL_STACK, 1ULL << 48, 1ULL << 48,
+          0x8000000000000000ULL };
         int rc;
 
 	if (pfault_disable)
@@ -362,7 +399,6 @@
 asmlinkage void
 pfault_interrupt(struct pt_regs *regs, __u16 error_code)
 {
-        DECLARE_WAITQUEUE(wait, current);
 	struct task_struct *tsk;
 	wait_queue_head_t queue;
 	wait_queue_head_t *qp;
@@ -375,7 +411,7 @@
          * external interrupt. 
 	 */
 	subcode = S390_lowcore.cpu_addr;
-	if ((subcode & 0xff00) != 0x06)
+	if ((subcode & 0xff00) != 0x0600)
 		return;
 
 	/*
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/mm/init.c linux/arch/s390x/mm/init.c
--- v2.4.12/linux/arch/s390x/mm/init.c	Sun Sep 23 11:40:56 2001
+++ linux/arch/s390x/mm/init.c	Thu Oct 11 09:04:57 2001
@@ -36,7 +36,7 @@
 #include <asm/dma.h>
 #include <asm/lowcore.h>
 #include <asm/tlb.h>
- 
+
 mmu_gather_t mmu_gathers[NR_CPUS];
 
 static unsigned long totalram_pages;
@@ -44,44 +44,23 @@
 pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE)));
 char  empty_zero_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
 
-static int test_access(unsigned long loc)
-{
-	static const int ssm_mask = 0x07000000L;
-	int rc, i;
-
-        rc = 0;
-	for (i=0; i<2; i++) {
-		__asm__ __volatile__(
-                        "    slgr  %0,%0\n"
-			"    ssm   %1\n"
-			"    tprot 0(%2),0\n"
-			"0:  jne   1f\n"
-			"    lghi  %0,1\n"
-			"1:  ssm   %3\n"
-                        ".section __ex_table,\"a\"\n"
-                        "   .align 8\n"
-                        "   .quad  0b,1b\n"
-                        ".previous"
-			: "+&d" (rc) : "i" (0), "a" (loc), "m" (ssm_mask)
-			: "cc");
-		if (rc == 0)
-			break;
-		loc += 0x100000;
-	}
-	return rc;
-}
-
 int do_check_pgt_cache(int low, int high)
 {
         int freed = 0;
         if(pgtable_cache_size > high) {
                 do {
-                        if(pgd_quicklist)
-                                free_pgd_slow(get_pgd_fast()), freed += 4;
-                        if(pmd_quicklist)
-                                pmd_free_slow(pmd_alloc_one_fast(NULL, 0)), freed += 4;
-                        if(pte_quicklist)
-                                pte_free_slow(pte_alloc_one_fast(NULL, 0)), freed++;
+                        if(pgd_quicklist) {
+				free_pgd_slow(get_pgd_fast());
+				freed += 4;
+			}
+                        if(pmd_quicklist) {
+				pmd_free_slow(pmd_alloc_one_fast(NULL, 0));
+				freed += 4;
+			}
+                        if(pte_quicklist) {
+				pte_free_slow(pte_alloc_one_fast(NULL, 0));
+				freed += 4;
+			}
                 } while(pgtable_cache_size > low);
         }
         return freed;
@@ -139,7 +118,7 @@
 	int     i,j,k;
         unsigned long address=0;
         unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) |
-          _REGION_TABLE;
+          _KERN_REGION_TABLE;
 	unsigned long end_mem = (unsigned long) __va(max_low_pfn*PAGE_SIZE);
 	static const int ssm_mask = 0x04000000L;
 
@@ -212,7 +191,6 @@
 void __init mem_init(void)
 {
 	unsigned long codesize, reservedpages, datasize, initsize;
-        unsigned long tmp;
 
         max_mapnr = num_physpages = max_low_pfn;
         high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
@@ -223,25 +201,7 @@
 	/* this will put all low memory onto the freelists */
 	totalram_pages += free_all_bootmem();
 
-        /* mark usable pages in the mem_map[] and count reserved pages */
 	reservedpages = 0;
-	tmp = 0;
-	do {
-		if (tmp && (tmp & 0x1ff) == 0 && 
-                    test_access(tmp * PAGE_SIZE) == 0) {
-                        printk("2M Segment 0x%016lX not available\n",
-                               tmp * PAGE_SIZE);
-			do {
-                                set_bit(PG_reserved, &mem_map[tmp].flags);
-				reservedpages++;
-				tmp++;
-			} while (tmp < max_low_pfn && (tmp & 0x1ff));
-		} else {
-			if (PageReserved(mem_map+tmp))
-				reservedpages++;
-			tmp++;
-		}
-	} while (tmp < max_low_pfn);
 
 	codesize =  (unsigned long) &_etext - (unsigned long) &_text;
 	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
diff -u --recursive --new-file v2.4.12/linux/drivers/acorn/char/mouse_rpc.c linux/drivers/acorn/char/mouse_rpc.c
--- v2.4.12/linux/drivers/acorn/char/mouse_rpc.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/acorn/char/mouse_rpc.c	Thu Oct 11 09:04:57 2001
@@ -83,3 +83,8 @@
 
 module_init(mouse_rpc_init);
 module_exit(mouse_rpc_exit);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("RiscPC mouse driver");
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.12/linux/drivers/acorn/scsi/acornscsi.c linux/drivers/acorn/scsi/acornscsi.c
--- v2.4.12/linux/drivers/acorn/scsi/acornscsi.c	Sun Sep 23 11:40:56 2001
+++ linux/drivers/acorn/scsi/acornscsi.c	Thu Oct 11 09:04:57 2001
@@ -3159,5 +3159,7 @@
 module_init(acornscsi_init);
 module_exit(acornscsi_exit);
 
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("AcornSCSI driver");
 MODULE_LICENSE("GPL");
 EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.12/linux/drivers/acorn/scsi/arxescsi.c linux/drivers/acorn/scsi/arxescsi.c
--- v2.4.12/linux/drivers/acorn/scsi/arxescsi.c	Sun Sep 23 11:40:56 2001
+++ linux/drivers/acorn/scsi/arxescsi.c	Thu Oct 11 09:04:57 2001
@@ -439,4 +439,7 @@
 module_init(init_arxe_scsi_driver);
 module_exit(exit_arxe_scsi_driver);
 
+MODULE_AUTHOR("Stefan Hanske");
+MODULE_DESCRIPTION("ARXESCSI driver for Acorn machines");
 MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.12/linux/drivers/acorn/scsi/cumana_2.c linux/drivers/acorn/scsi/cumana_2.c
--- v2.4.12/linux/drivers/acorn/scsi/cumana_2.c	Sun Sep 23 11:40:56 2001
+++ linux/drivers/acorn/scsi/cumana_2.c	Thu Oct 11 09:04:57 2001
@@ -82,12 +82,6 @@
 
 static struct expansion_card *ecs[MAX_ECARDS];
 
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("Cumana SCSI II driver");
-MODULE_PARM(term, "1-8i");
-MODULE_PARM_DESC(term, "SCSI bus termination");
-MODULE_LICENSE("GPL");
-
 /*
  * Use term=0,1,0,0,0 to turn terminators on/off
  */
@@ -600,3 +594,10 @@
 
 module_init(cumanascsi2_init);
 module_exit(cumanascsi2_exit);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("Cumana SCSI-2 driver for Acorn machines");
+MODULE_PARM(term, "1-8i");
+MODULE_PARM_DESC(term, "SCSI bus termination");
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.12/linux/drivers/acorn/scsi/ecoscsi.c linux/drivers/acorn/scsi/ecoscsi.c
--- v2.4.12/linux/drivers/acorn/scsi/ecoscsi.c	Sun Sep 23 11:40:56 2001
+++ linux/drivers/acorn/scsi/ecoscsi.c	Thu Oct 11 09:04:57 2001
@@ -293,5 +293,7 @@
 module_init(ecoscsi_init);
 module_exit(ecoscsi_exit);
 
-EXPORT_NO_SYMBOLS;
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("Econet-SCSI driver for Acorn machines");
 MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.12/linux/drivers/acorn/scsi/eesox.c linux/drivers/acorn/scsi/eesox.c
--- v2.4.12/linux/drivers/acorn/scsi/eesox.c	Sun Sep 23 11:40:56 2001
+++ linux/drivers/acorn/scsi/eesox.c	Thu Oct 11 09:04:57 2001
@@ -80,11 +80,6 @@
 
 static struct expansion_card *ecs[MAX_ECARDS];
 
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("EESOX SCSI driver");
-MODULE_PARM(term, "1-8i");
-MODULE_PARM_DESC(term, "SCSI bus termination");
-
 /*
  * Use term=0,1,0,0,0 to turn terminators on/off
  */
@@ -602,5 +597,9 @@
 module_init(eesox_init);
 module_exit(eesox_exit);
 
-EXPORT_NO_SYMBOLS;
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("EESOX 'Fast' SCSI driver for Acorn machines");
+MODULE_PARM(term, "1-8i");
+MODULE_PARM_DESC(term, "SCSI bus termination");
 MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.12/linux/drivers/acorn/scsi/fas216.c linux/drivers/acorn/scsi/fas216.c
--- v2.4.12/linux/drivers/acorn/scsi/fas216.c	Sun Sep 23 11:40:56 2001
+++ linux/drivers/acorn/scsi/fas216.c	Thu Oct 11 09:04:57 2001
@@ -60,9 +60,6 @@
 #include "../../scsi/hosts.h"
 #include "fas216.h"
 
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("Generic FAS216/NCR53C9x driver");
-
 #define VER_MAJOR	0
 #define VER_MINOR	0
 #define VER_PATCH	5
@@ -2767,15 +2764,6 @@
 EXPORT_SYMBOL(fas216_print_stats);
 EXPORT_SYMBOL(fas216_print_device);
 
-#ifdef MODULE
-int __init init_module(void)
-{
-	return 0;
-}
-
-void __exit cleanup_module(void)
-{
-}
-#endif
-
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("Generic FAS216/NCR53C9x driver core");
 MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/acorn/scsi/msgqueue.c linux/drivers/acorn/scsi/msgqueue.c
--- v2.4.12/linux/drivers/acorn/scsi/msgqueue.c	Sun Sep 23 11:40:56 2001
+++ linux/drivers/acorn/scsi/msgqueue.c	Thu Oct 11 09:04:57 2001
@@ -16,10 +16,6 @@
 
 #include "msgqueue.h"
 
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("SCSI message queue handling");
-MODULE_LICENSE("GPL");
-
 /*
  * Function: struct msgqueue_entry *mqe_alloc(MsgQueue_t *msgq)
  * Purpose : Allocate a message queue entry
@@ -170,13 +166,6 @@
 EXPORT_SYMBOL(msgqueue_addmsg);
 EXPORT_SYMBOL(msgqueue_flush);
 
-#ifdef MODULE
-int __init init_module(void)
-{
-	return 0;
-}
-
-void __exit cleanup_module(void)
-{
-}
-#endif
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("SCSI message queue handling");
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/acorn/scsi/oak.c linux/drivers/acorn/scsi/oak.c
--- v2.4.12/linux/drivers/acorn/scsi/oak.c	Sun Sep 23 11:40:56 2001
+++ linux/drivers/acorn/scsi/oak.c	Thu Oct 11 09:04:57 2001
@@ -286,5 +286,7 @@
 module_init(oakscsi_init);
 module_exit(oakscsi_exit);
 
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("Oak SCSI driver");
 MODULE_LICENSE("GPL");
 EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.12/linux/drivers/acorn/scsi/powertec.c linux/drivers/acorn/scsi/powertec.c
--- v2.4.12/linux/drivers/acorn/scsi/powertec.c	Sun Sep 23 11:40:56 2001
+++ linux/drivers/acorn/scsi/powertec.c	Thu Oct 11 09:04:57 2001
@@ -77,12 +77,6 @@
 #define VER_MINOR	0
 #define VER_PATCH	5
 
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("Powertec SCSI driver");
-MODULE_PARM(term, "1-8i");
-MODULE_PARM_DESC(term, "SCSI bus termination");
-MODULE_LICENSE("GPL");
-
 static struct expansion_card *ecs[MAX_ECARDS];
 
 /*
@@ -502,3 +496,10 @@
 
 module_init(powertecscsi_init);
 module_exit(powertecscsi_exit);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("Powertec SCSI driver");
+MODULE_PARM(term, "1-8i");
+MODULE_PARM_DESC(term, "SCSI bus termination");
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.12/linux/drivers/acorn/scsi/queue.c linux/drivers/acorn/scsi/queue.c
--- v2.4.12/linux/drivers/acorn/scsi/queue.c	Sun Sep 23 11:40:56 2001
+++ linux/drivers/acorn/scsi/queue.c	Thu Oct 11 09:04:57 2001
@@ -25,10 +25,6 @@
 
 #include "../../scsi/scsi.h"
 
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("SCSI command queueing");
-MODULE_LICENSE("GPL");
-
 #define DEBUG
 
 typedef struct queue_entry {
@@ -296,13 +292,6 @@
 EXPORT_SYMBOL(queue_remove_cmd);
 EXPORT_SYMBOL(queue_probetgtlun);
 
-#ifdef MODULE
-int __init init_module (void)
-{
-	return 0;
-}
-
-void __exit cleanup_module (void)
-{
-}
-#endif
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("SCSI command queueing");
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/acpi/ospm/thermal/tz_osl.c linux/drivers/acpi/ospm/thermal/tz_osl.c
--- v2.4.12/linux/drivers/acpi/ospm/thermal/tz_osl.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/acpi/ospm/thermal/tz_osl.c	Thu Oct 11 09:04:57 2001
@@ -177,7 +177,7 @@
 tz_osl_add_device(
 	TZ_CONTEXT		*thermal_zone)
 {
-	struct proc_dir_entry	*proc_entry = NULL;
+	struct proc_dir_entry	*proc_entry = NULL, *proc;
 
 	if (!thermal_zone) {
 		return(AE_BAD_PARAMETER);
@@ -186,15 +186,18 @@
 	printk("Thermal Zone: found\n");
 
 	proc_entry = proc_mkdir(thermal_zone->uid, tz_proc_root);
-	if (!proc_entry) {
+	if (!proc_entry)
 		return(AE_ERROR);
-	}
 
-	create_proc_read_entry(TZ_PROC_STATUS, S_IFREG | S_IRUGO,
+	proc = create_proc_read_entry(TZ_PROC_STATUS, S_IFREG | S_IRUGO,
 		proc_entry, tz_osl_proc_read_status, (void*)thermal_zone);
+	if (!proc)
+		return(AE_ERROR);
 
-	create_proc_read_entry(TZ_PROC_INFO, S_IFREG | S_IRUGO,
+	proc = create_proc_read_entry(TZ_PROC_INFO, S_IFREG | S_IRUGO,
 		proc_entry, tz_osl_proc_read_info, (void*)thermal_zone);
+	if (!proc)
+		return(AE_ERROR);
 
 	return(AE_OK);
 }
diff -u --recursive --new-file v2.4.12/linux/drivers/block/nbd.c linux/drivers/block/nbd.c
--- v2.4.12/linux/drivers/block/nbd.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/block/nbd.c	Thu Oct 11 09:04:57 2001
@@ -542,4 +542,6 @@
 module_exit(nbd_cleanup);
 
 MODULE_DESCRIPTION("Network Block Device");
+MODULE_LICENSE("GPL");
+
 
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/aten.c linux/drivers/block/paride/aten.c
--- v2.4.12/linux/drivers/block/paride/aten.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/block/paride/aten.c	Thu Oct 11 09:04:57 2001
@@ -171,3 +171,4 @@
 #endif
 
 /* end of aten.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/bpck.c linux/drivers/block/paride/bpck.c
--- v2.4.12/linux/drivers/block/paride/bpck.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/block/paride/bpck.c	Thu Oct 11 09:04:57 2001
@@ -482,3 +482,4 @@
 #endif
 
 /* end of bpck.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/comm.c linux/drivers/block/paride/comm.c
--- v2.4.12/linux/drivers/block/paride/comm.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/block/paride/comm.c	Thu Oct 11 09:04:57 2001
@@ -227,3 +227,4 @@
 #endif
 
 /* end of comm.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/dstr.c linux/drivers/block/paride/dstr.c
--- v2.4.12/linux/drivers/block/paride/dstr.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/block/paride/dstr.c	Thu Oct 11 09:04:57 2001
@@ -242,3 +242,4 @@
 #endif
 
 /* end of dstr.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/epat.c linux/drivers/block/paride/epat.c
--- v2.4.12/linux/drivers/block/paride/epat.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/block/paride/epat.c	Thu Oct 11 09:04:57 2001
@@ -320,3 +320,4 @@
 #endif
 
 /* end of epat.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/epia.c linux/drivers/block/paride/epia.c
--- v2.4.12/linux/drivers/block/paride/epia.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/block/paride/epia.c	Thu Oct 11 09:04:57 2001
@@ -325,3 +325,4 @@
 
 /* end of epia.c */
 
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/fit2.c linux/drivers/block/paride/fit2.c
--- v2.4.12/linux/drivers/block/paride/fit2.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/block/paride/fit2.c	Thu Oct 11 09:04:57 2001
@@ -160,3 +160,4 @@
 #endif
 
 /* end of fit2.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/fit3.c linux/drivers/block/paride/fit3.c
--- v2.4.12/linux/drivers/block/paride/fit3.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/block/paride/fit3.c	Thu Oct 11 09:04:57 2001
@@ -220,3 +220,4 @@
 #endif
 
 /* end of fit3.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/friq.c linux/drivers/block/paride/friq.c
--- v2.4.12/linux/drivers/block/paride/friq.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/block/paride/friq.c	Thu Oct 11 09:04:57 2001
@@ -281,3 +281,4 @@
 #endif
 
 /* end of friq.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/frpw.c linux/drivers/block/paride/frpw.c
--- v2.4.12/linux/drivers/block/paride/frpw.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/block/paride/frpw.c	Thu Oct 11 09:04:57 2001
@@ -322,3 +322,4 @@
 #endif
 
 /* end of frpw.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/kbic.c linux/drivers/block/paride/kbic.c
--- v2.4.12/linux/drivers/block/paride/kbic.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/block/paride/kbic.c	Thu Oct 11 09:04:57 2001
@@ -310,3 +310,4 @@
 #endif
 
 /* end of kbic.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/ktti.c linux/drivers/block/paride/ktti.c
--- v2.4.12/linux/drivers/block/paride/ktti.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/block/paride/ktti.c	Thu Oct 11 09:04:57 2001
@@ -137,3 +137,4 @@
 #endif
 
 /* end of ktti.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/on20.c linux/drivers/block/paride/on20.c
--- v2.4.12/linux/drivers/block/paride/on20.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/block/paride/on20.c	Thu Oct 11 09:04:57 2001
@@ -162,3 +162,4 @@
 #endif
 
 /* end of on20.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/on26.c linux/drivers/block/paride/on26.c
--- v2.4.12/linux/drivers/block/paride/on26.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/block/paride/on26.c	Thu Oct 11 09:04:57 2001
@@ -328,3 +328,4 @@
 
 /* end of on26.c */
 
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/paride.c linux/drivers/block/paride/paride.c
--- v2.4.12/linux/drivers/block/paride/paride.c	Tue Oct  9 17:06:51 2001
+++ linux/drivers/block/paride/paride.c	Thu Oct 11 09:04:57 2001
@@ -547,3 +547,4 @@
 #endif
 
 /* end of paride.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/pcd.c linux/drivers/block/paride/pcd.c
--- v2.4.12/linux/drivers/block/paride/pcd.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/block/paride/pcd.c	Thu Oct 11 09:04:57 2001
@@ -948,3 +948,4 @@
 
 /* end of pcd.c */
 
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/pd.c linux/drivers/block/paride/pd.c
--- v2.4.12/linux/drivers/block/paride/pd.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/block/paride/pd.c	Thu Oct 11 09:04:57 2001
@@ -586,8 +586,7 @@
 }
 
 void    cleanup_module(void)
-
-{       struct gendisk **gdp;
+{
 	int unit;
 
         devfs_unregister_blkdev(MAJOR_NR,name);
@@ -1069,3 +1068,4 @@
 
 /* end of pd.c */
 
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/pf.c linux/drivers/block/paride/pf.c
--- v2.4.12/linux/drivers/block/paride/pf.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/block/paride/pf.c	Thu Oct 11 09:04:57 2001
@@ -1111,3 +1111,4 @@
 
 /* end of pf.c */
 
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/pg.c linux/drivers/block/paride/pg.c
--- v2.4.12/linux/drivers/block/paride/pg.c	Fri Feb  9 11:30:22 2001
+++ linux/drivers/block/paride/pg.c	Thu Oct 11 09:04:57 2001
@@ -694,3 +694,4 @@
 
 /* end of pg.c */
 
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/ppc6lnx.c linux/drivers/block/paride/ppc6lnx.c
--- v2.4.12/linux/drivers/block/paride/ppc6lnx.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/block/paride/ppc6lnx.c	Thu Oct 11 09:04:57 2001
@@ -724,3 +724,4 @@
 
 //***************************************************************************
 
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/pt.c linux/drivers/block/paride/pt.c
--- v2.4.12/linux/drivers/block/paride/pt.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/block/paride/pt.c	Thu Oct 11 09:04:57 2001
@@ -964,3 +964,4 @@
 
 /* end of pt.c */
 
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/char/Config.in linux/drivers/char/Config.in
--- v2.4.12/linux/drivers/char/Config.in	Tue Oct  9 17:06:51 2001
+++ linux/drivers/char/Config.in	Thu Oct 11 09:07:00 2001
@@ -155,6 +155,7 @@
    tristate '  Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG
    tristate '  Acquire SBC Watchdog Timer' CONFIG_ACQUIRE_WDT
    tristate '  Advantech SBC Watchdog Timer' CONFIG_ADVANTECH_WDT
+   tristate '  IB700 SBC Watchdog Timer' CONFIG_IB700_WDT
    tristate '  SBC-60XX Watchdog Timer' CONFIG_60XX_WDT
    tristate '  W83877F (EMACS) Watchdog Timer' CONFIG_W83877F_WDT
    tristate '  Mixcom Watchdog' CONFIG_MIXCOMWD 
@@ -191,7 +192,7 @@
 tristate 'Double Talk PC internal speech card support' CONFIG_DTLK
 tristate 'Siemens R3964 line discipline' CONFIG_R3964
 tristate 'Applicom intelligent fieldbus card support' CONFIG_APPLICOM
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_X86" = "y" ]; then
    dep_tristate 'Sony Vaio Programmable I/O Control Device support' CONFIG_SONYPI $CONFIG_PCI
 fi
 
diff -u --recursive --new-file v2.4.12/linux/drivers/char/Makefile linux/drivers/char/Makefile
--- v2.4.12/linux/drivers/char/Makefile	Tue Oct  9 17:06:51 2001
+++ linux/drivers/char/Makefile	Thu Oct 11 09:07:00 2001
@@ -220,6 +220,7 @@
 obj-$(CONFIG_PCWATCHDOG) += pcwd.o
 obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
 obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o
+obj-$(CONFIG_IB700_WDT) += ib700wdt.o
 obj-$(CONFIG_MIXCOMWD) += mixcomwd.o
 obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o
 obj-$(CONFIG_WDT) += wdt.o
diff -u --recursive --new-file v2.4.12/linux/drivers/char/adbmouse.c linux/drivers/char/adbmouse.c
--- v2.4.12/linux/drivers/char/adbmouse.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/char/adbmouse.c	Thu Oct 11 09:07:00 2001
@@ -206,4 +206,4 @@
 module_init(adb_mouse_init);
 module_exit(adb_mouse_cleanup);
 
-MODULE_LICENSE("GPL"):
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/char/i810_rng.c linux/drivers/char/i810_rng.c
--- v2.4.12/linux/drivers/char/i810_rng.c	Thu Apr 12 12:15:25 2001
+++ linux/drivers/char/i810_rng.c	Thu Oct 11 09:14:32 2001
@@ -342,6 +342,7 @@
 
 MODULE_AUTHOR("Jeff Garzik, Philipp Rumpf, Matt Sottek");
 MODULE_DESCRIPTION("Intel i8xx chipset Random Number Generator (RNG) driver");
+MODULE_LICENSE("GPL");
 
 
 /*
diff -u --recursive --new-file v2.4.12/linux/drivers/char/ib700wdt.c linux/drivers/char/ib700wdt.c
--- v2.4.12/linux/drivers/char/ib700wdt.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/ib700wdt.c	Thu Oct 11 09:07:00 2001
@@ -0,0 +1,272 @@
+/*
+ *	IB700 Single Board Computer WDT driver for Linux 2.4.x
+ *
+ *	(c) Copyright 2001 Charles Howes <chowes@vsol.net>
+ *
+ *      Based on advantechwdt.c which is based on acquirewdt.c which
+ *       is based on wdt.c.
+ *
+ *	(c) Copyright 2000-2001 Marek Michalkiewicz <marekm@linux.org.pl>
+ *
+ *	Based on acquirewdt.c which is based on wdt.c.
+ *	Original copyright messages:
+ *
+ *	(c) Copyright 1996 Alan Cox <alan@redhat.com>, All Rights Reserved.
+ *				http://www.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.
+ *
+ *	Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
+ *	warranty for any of this software. This material is provided
+ *	"AS-IS" and at no charge.
+ *
+ *	(c) Copyright 1995    Alan Cox <alan@redhat.com>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/fcntl.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
+
+static int ibwdt_is_open;
+static spinlock_t ibwdt_lock;
+
+/*
+ *
+ * Watchdog Timer Configuration
+ *
+ * The function of the watchdog timer is to reset the system
+ * automatically and is defined at I/O port 0443H.  To enable the
+ * watchdog timer and allow the system to reset, write I/O port 0443H.
+ * To disable the timer, write I/O port 0441H for the system to stop the
+ * watchdog function.  The timer has a tolerance of 20% for its
+ * intervals.
+ *
+ * The following describes how the timer should be programmed.
+ *
+ * Enabling Watchdog:
+ * MOV AX,000FH (Choose the values from 0 to F)
+ * MOV DX,0443H
+ * OUT DX,AX
+ *
+ * Disabling Watchdog:
+ * MOV AX,000FH (Any value is fine.)
+ * MOV DX,0441H
+ * OUT DX,AX
+ *
+ * Watchdog timer control table:
+ * Level   Value  Time/sec | Level Value Time/sec
+ *   1       F       0     |   9     7      16
+ *   2       E       2     |   10    6      18
+ *   3       D       4     |   11    5      20
+ *   4       C       6     |   12    4      22
+ *   5       B       8     |   13    3      24
+ *   6       A       10    |   14    2      26
+ *   7       9       12    |   15    1      28
+ *   8       8       14    |   16    0      30
+ *
+ */
+
+#define WDT_STOP 0x441
+#define WDT_START 0x443
+
+#define WD_TIMO 0		/* 30 seconds +/- 20%, from table */
+
+/*
+ *	Kernel methods.
+ */
+
+static void
+ibwdt_ping(void)
+{
+	/* Write a watchdog value */
+	outb_p(WD_TIMO, WDT_START);
+}
+
+static ssize_t
+ibwdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+{
+	/*  Can't seek (pwrite) on this device  */
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+
+	if (count) {
+		ibwdt_ping();
+		return 1;
+	}
+	return 0;
+}
+
+static ssize_t
+ibwdt_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+{
+	return -EINVAL;
+}
+
+static int
+ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+	  unsigned long arg)
+{
+	static struct watchdog_info ident = {
+		WDIOF_KEEPALIVEPING, 1, "IB700 WDT"
+	};
+
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+	  if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)))
+	    return -EFAULT;
+	  break;
+
+	case WDIOC_GETSTATUS:
+	  if (copy_to_user((int *)arg, &ibwdt_is_open,  sizeof(int)))
+	    return -EFAULT;
+	  break;
+
+	case WDIOC_KEEPALIVE:
+	  ibwdt_ping();
+	  break;
+
+	default:
+	  return -ENOTTY;
+	}
+	return 0;
+}
+
+static int
+ibwdt_open(struct inode *inode, struct file *file)
+{
+	switch (MINOR(inode->i_rdev)) {
+		case WATCHDOG_MINOR:
+			spin_lock(&ibwdt_lock);
+			if (ibwdt_is_open) {
+				spin_unlock(&ibwdt_lock);
+				return -EBUSY;
+			}
+			/*
+			 *	Activate
+			 */
+
+			ibwdt_is_open = 1;
+			ibwdt_ping();
+			spin_unlock(&ibwdt_lock);
+			return 0;
+		default:
+			return -ENODEV;
+	}
+}
+
+static int
+ibwdt_close(struct inode *inode, struct file *file)
+{
+	lock_kernel();
+	if (MINOR(inode->i_rdev) == WATCHDOG_MINOR) {
+		spin_lock(&ibwdt_lock);
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+		outb_p(WD_TIMO, WDT_STOP);
+#endif
+		ibwdt_is_open = 0;
+		spin_unlock(&ibwdt_lock);
+	}
+	unlock_kernel();
+	return 0;
+}
+
+/*
+ *	Notifier for system down
+ */
+
+static int
+ibwdt_notify_sys(struct notifier_block *this, unsigned long code,
+	void *unused)
+{
+	if (code == SYS_DOWN || code == SYS_HALT) {
+		/* Turn the WDT off */
+		outb_p(WD_TIMO, WDT_STOP);
+	}
+	return NOTIFY_DONE;
+}
+
+/*
+ *	Kernel Interfaces
+ */
+
+static struct file_operations ibwdt_fops = {
+	owner:		THIS_MODULE,
+	read:		ibwdt_read,
+	write:		ibwdt_write,
+	ioctl:		ibwdt_ioctl,
+	open:		ibwdt_open,
+	release:	ibwdt_close,
+};
+
+static struct miscdevice ibwdt_miscdev = {
+	WATCHDOG_MINOR,
+	"watchdog",
+	&ibwdt_fops
+};
+
+/*
+ *	The WDT needs to learn about soft shutdowns in order to
+ *	turn the timebomb registers off.
+ */
+
+static struct notifier_block ibwdt_notifier = {
+	ibwdt_notify_sys,
+	NULL,
+	0
+};
+
+static int __init
+ibwdt_init(void)
+{
+	printk("WDT driver for IB700 single board computer initialising.\n");
+
+	spin_lock_init(&ibwdt_lock);
+	misc_register(&ibwdt_miscdev);
+#if WDT_START != WDT_STOP
+	request_region(WDT_STOP, 1, "IB700 WDT");
+#endif
+	request_region(WDT_START, 1, "IB700 WDT");
+	register_reboot_notifier(&ibwdt_notifier);
+	return 0;
+}
+
+static void __exit
+ibwdt_exit(void)
+{
+	misc_deregister(&ibwdt_miscdev);
+	unregister_reboot_notifier(&ibwdt_notifier);
+#if WDT_START != WDT_STOP
+	release_region(WDT_STOP,1);
+#endif
+	release_region(WDT_START,1);
+}
+
+module_init(ibwdt_init);
+module_exit(ibwdt_exit);
+
+MODULE_AUTHOR("Charles Howes <chowes@vsol.net>");
+MODULE_DESCRIPTION("IB700 SBC watchdog driver");
+MODULE_LICENSE("GPL");
+
+/* end of ib700wdt.c */
diff -u --recursive --new-file v2.4.12/linux/drivers/char/ip2main.c linux/drivers/char/ip2main.c
--- v2.4.12/linux/drivers/char/ip2main.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/char/ip2main.c	Thu Oct 11 09:14:32 2001
@@ -3458,3 +3458,4 @@
 }
 
 
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/char/istallion.c linux/drivers/char/istallion.c
--- v2.4.12/linux/drivers/char/istallion.c	Wed Jul 25 17:10:19 2001
+++ linux/drivers/char/istallion.c	Thu Oct 11 09:14:32 2001
@@ -386,6 +386,8 @@
  */
 MODULE_AUTHOR("Greg Ungerer");
 MODULE_DESCRIPTION("Stallion Intelligent Multiport Serial Driver");
+MODULE_LICENSE("GPL");
+
 
 MODULE_PARM(board0, "1-3s");
 MODULE_PARM_DESC(board0, "Board 0 config -> name[,ioaddr[,memaddr]");
diff -u --recursive --new-file v2.4.12/linux/drivers/char/mwave/mwavedd.c linux/drivers/char/mwave/mwavedd.c
--- v2.4.12/linux/drivers/char/mwave/mwavedd.c	Tue Oct  9 17:06:51 2001
+++ linux/drivers/char/mwave/mwavedd.c	Thu Oct 11 09:14:32 2001
@@ -71,6 +71,10 @@
 #define __exit
 #endif
 
+MODULE_DESCRIPTION("3780i Advanced Communications Processor (Mwave) driver");
+MODULE_AUTHOR("Mike Sullivan and Paul Schroeder");
+MODULE_LICENSE("GPL");
+
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 static int mwave_get_info(char *buf, char **start, off_t offset, int len);
 #else
diff -u --recursive --new-file v2.4.12/linux/drivers/char/sonypi.c linux/drivers/char/sonypi.c
--- v2.4.12/linux/drivers/char/sonypi.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/char/sonypi.c	Thu Oct 11 09:04:57 2001
@@ -39,6 +39,7 @@
 #include <linux/delay.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
+#include <asm/system.h>
 
 #include "sonypi.h"
 #include <linux/sonypi.h>
@@ -48,7 +49,7 @@
 static int verbose; /* = 0 */
 static int fnkeyinit; /* = 0 */
 static int camera; /* = 0 */
-extern int is_sony_vaio_laptop; /* set in DMI table parse routines */
+static int compat; /* = 0 */
 
 /* Inits the queue */
 static inline void sonypi_initq(void) {
@@ -110,27 +111,27 @@
 
 static void sonypi_ecrset(u16 addr, u16 value) {
 
-	wait_on_command(inw_p(SONYPI_CST_IOPORT) & 3);
+	wait_on_command(1, inw_p(SONYPI_CST_IOPORT) & 3);
 	outw_p(0x81, SONYPI_CST_IOPORT);
-	wait_on_command(inw_p(SONYPI_CST_IOPORT) & 2);
+	wait_on_command(0, inw_p(SONYPI_CST_IOPORT) & 2);
 	outw_p(addr, SONYPI_DATA_IOPORT);
-	wait_on_command(inw_p(SONYPI_CST_IOPORT) & 2);
+	wait_on_command(0, inw_p(SONYPI_CST_IOPORT) & 2);
 	outw_p(value, SONYPI_DATA_IOPORT);
-	wait_on_command(inw_p(SONYPI_CST_IOPORT) & 2);
+	wait_on_command(0, inw_p(SONYPI_CST_IOPORT) & 2);
 }
 
 static u16 sonypi_ecrget(u16 addr) {
 
-	wait_on_command(inw_p(SONYPI_CST_IOPORT) & 3);
+	wait_on_command(1, inw_p(SONYPI_CST_IOPORT) & 3);
 	outw_p(0x80, SONYPI_CST_IOPORT);
-	wait_on_command(inw_p(SONYPI_CST_IOPORT) & 2);
+	wait_on_command(0, inw_p(SONYPI_CST_IOPORT) & 2);
 	outw_p(addr, SONYPI_DATA_IOPORT);
-	wait_on_command(inw_p(SONYPI_CST_IOPORT) & 2);
+	wait_on_command(0, inw_p(SONYPI_CST_IOPORT) & 2);
 	return inw_p(SONYPI_DATA_IOPORT);
 }
 
 /* Initializes the device - this comes from the AML code in the ACPI bios */
-static void __devinit sonypi_normal_srs(void) {
+static void __devinit sonypi_type1_srs(void) {
 	u32 v;
 
 	pci_read_config_dword(sonypi_device.dev, SONYPI_G10A, &v);
@@ -152,7 +153,7 @@
 	pci_write_config_dword(sonypi_device.dev, SONYPI_G10A, v);
 }
 
-static void __devinit sonypi_r505_srs(void) {
+static void __devinit sonypi_type2_srs(void) {
 	sonypi_ecrset(SONYPI_SHIB, (sonypi_device.ioport1 & 0xFF00) >> 8);
 	sonypi_ecrset(SONYPI_SLOB,  sonypi_device.ioport1 & 0x00FF);
 	sonypi_ecrset(SONYPI_SIRQ,  sonypi_device.bits);
@@ -160,7 +161,7 @@
 }
 
 /* Disables the device - this comes from the AML code in the ACPI bios */
-static void __devexit sonypi_normal_dis(void) {
+static void __devexit sonypi_type1_dis(void) {
 	u32 v;
 
 	pci_read_config_dword(sonypi_device.dev, SONYPI_G10A, &v);
@@ -172,7 +173,7 @@
 	outl(v, SONYPI_IRQ_PORT);
 }
 
-static void __devexit sonypi_r505_dis(void) {
+static void __devexit sonypi_type2_dis(void) {
 	sonypi_ecrset(SONYPI_SHIB, 0);
 	sonypi_ecrset(SONYPI_SLOB, 0);
 	sonypi_ecrset(SONYPI_SIRQ, 0);
@@ -181,7 +182,7 @@
 static u8 sonypi_call1(u8 dev) {
 	u8 v1, v2;
 
-	wait_on_command(inb_p(sonypi_device.ioport2) & 2);
+	wait_on_command(0, inb_p(sonypi_device.ioport2) & 2);
 	outb(dev, sonypi_device.ioport2);
 	v1 = inb_p(sonypi_device.ioport2);
 	v2 = inb_p(sonypi_device.ioport1);
@@ -191,9 +192,9 @@
 static u8 sonypi_call2(u8 dev, u8 fn) {
 	u8 v1;
 
-	wait_on_command(inb_p(sonypi_device.ioport2) & 2);
+	wait_on_command(0, inb_p(sonypi_device.ioport2) & 2);
 	outb(dev, sonypi_device.ioport2);
-	wait_on_command(inb_p(sonypi_device.ioport2) & 2);
+	wait_on_command(0, inb_p(sonypi_device.ioport2) & 2);
 	outb(fn, sonypi_device.ioport1);
 	v1 = inb_p(sonypi_device.ioport1);
 	return v1;
@@ -202,11 +203,11 @@
 static u8 sonypi_call3(u8 dev, u8 fn, u8 v) {
 	u8 v1;
 
-	wait_on_command(inb_p(sonypi_device.ioport2) & 2);
+	wait_on_command(0, inb_p(sonypi_device.ioport2) & 2);
 	outb(dev, sonypi_device.ioport2);
-	wait_on_command(inb_p(sonypi_device.ioport2) & 2);
+	wait_on_command(0, inb_p(sonypi_device.ioport2) & 2);
 	outb(fn, sonypi_device.ioport1);
-	wait_on_command(inb_p(sonypi_device.ioport2) & 2);
+	wait_on_command(0, inb_p(sonypi_device.ioport2) & 2);
 	outb(v, sonypi_device.ioport1);
 	v1 = inb_p(sonypi_device.ioport1);
 	return v1;
@@ -228,7 +229,7 @@
 /* Set brightness, hue etc */
 static void sonypi_set(u8 fn, u8 v) {
 	
-	wait_on_command(sonypi_call3(0x90, fn, v));
+	wait_on_command(0, sonypi_call3(0x90, fn, v));
 }
 
 /* Tests if the camera is ready */
@@ -291,19 +292,19 @@
 	int i;
 	u8 sonypi_jogger_ev, sonypi_fnkey_ev;
 
-	if (sonypi_device.model == SONYPI_DEVICE_MODEL_R505) {
-		sonypi_jogger_ev = SONYPI_R505_JOGGER_EV;
-		sonypi_fnkey_ev = SONYPI_R505_FNKEY_EV;
+	if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) {
+		sonypi_jogger_ev = SONYPI_TYPE2_JOGGER_EV;
+		sonypi_fnkey_ev = SONYPI_TYPE2_FNKEY_EV;
 	}
 	else {
-		sonypi_jogger_ev = SONYPI_NORMAL_JOGGER_EV;
-		sonypi_fnkey_ev = SONYPI_NORMAL_FNKEY_EV;
+		sonypi_jogger_ev = SONYPI_TYPE1_JOGGER_EV;
+		sonypi_fnkey_ev = SONYPI_TYPE1_FNKEY_EV;
 	}
 
 	v1 = inb_p(sonypi_device.ioport1);
 	v2 = inb_p(sonypi_device.ioport2);
 
-	if ((v2 & SONYPI_NORMAL_PKEY_EV) == SONYPI_NORMAL_PKEY_EV) {
+	if ((v2 & SONYPI_TYPE1_PKEY_EV) == SONYPI_TYPE1_PKEY_EV) {
 		for (i = 0; sonypi_pkeyev[i].event; i++)
 			if (sonypi_pkeyev[i].data == v1) {
 				event = sonypi_pkeyev[i].event;
@@ -338,9 +339,23 @@
 				goto found;
 			}
 	}
+	if ((v2 & SONYPI_BACK_EV) == SONYPI_BACK_EV) {
+		for (i = 0; sonypi_backev[i].event; i++)
+			if (sonypi_backev[i].data == v1) {
+				event = sonypi_backev[i].event;
+				goto found;
+			}
+	}
+	if ((v2 & SONYPI_LID_EV) == SONYPI_LID_EV) {
+		for (i = 0; sonypi_lidev[i].event; i++)
+			if (sonypi_lidev[i].data == v1) {
+				event = sonypi_lidev[i].event;
+				goto found;
+			}
+	}
 	if (verbose)
 		printk(KERN_WARNING 
-		       "sonypi: unknown event port1=0x%x,port2=0x%x\n",v1,v2);
+		       "sonypi: unknown event port1=0x%02x,port2=0x%02x\n",v1,v2);
 	return;
 
 found:
@@ -564,15 +579,15 @@
 		goto out1;
 	}
 
-	if (sonypi_device.model == SONYPI_DEVICE_MODEL_R505) {
-		ioport_list = sonypi_r505_ioport_list;
-		sonypi_device.region_size = SONYPI_R505_REGION_SIZE;
-		irq_list = sonypi_r505_irq_list;
+	if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) {
+		ioport_list = sonypi_type2_ioport_list;
+		sonypi_device.region_size = SONYPI_TYPE2_REGION_SIZE;
+		irq_list = sonypi_type2_irq_list;
 	}
 	else {
-		ioport_list = sonypi_normal_ioport_list;
-		sonypi_device.region_size = SONYPI_NORMAL_REGION_SIZE;
-		irq_list = sonypi_normal_irq_list;
+		ioport_list = sonypi_type1_ioport_list;
+		sonypi_device.region_size = SONYPI_TYPE1_REGION_SIZE;
+		irq_list = sonypi_type1_irq_list;
 	}
 
 	for (i = 0; ioport_list[i].port1; i++) {
@@ -608,22 +623,28 @@
 	if (fnkeyinit)
 		outb(0xf0, 0xb2);
 
-	if (sonypi_device.model == SONYPI_DEVICE_MODEL_R505)
-		sonypi_r505_srs();
+	if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2)
+		sonypi_type2_srs();
 	else
-		sonypi_normal_srs();
+		sonypi_type1_srs();
 
 	sonypi_call1(0x82);
 	sonypi_call2(0x81, 0xff);
-	sonypi_call1(0x92); 
+	if (compat)
+		sonypi_call1(0x92); 
+	else
+		sonypi_call1(0x82);
 
 	printk(KERN_INFO "sonypi: Sony Programmable I/O Controller Driver v%d.%d.\n",
 	       SONYPI_DRIVER_MAJORVERSION,
 	       SONYPI_DRIVER_MINORVERSION);
-	printk(KERN_INFO "sonypi: detected %s model, camera = %s\n",
-	       (sonypi_device.model == SONYPI_DEVICE_MODEL_NORMAL) ?
-	       "normal" : "R505",
-	       camera ? "on" : "off");
+	printk(KERN_INFO "sonypi: detected %s model (%04x:%04x), "
+	       "camera = %s, compat = %s\n",
+	       (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) ?
+			"type1" : "type2",
+	       sonypi_device.dev->vendor, sonypi_device.dev->device,
+	       camera ? "on" : "off",
+	       compat ? "on" : "off");
 	printk(KERN_INFO "sonypi: enabled at irq=%d, port1=0x%x, port2=0x%x\n",
 	       sonypi_device.irq, 
 	       sonypi_device.ioport1, sonypi_device.ioport2);
@@ -645,10 +666,10 @@
 	sonypi_call2(0x81, 0); /* make sure we don't get any more events */
 	if (camera)
 		sonypi_camera_off();
-	if (sonypi_device.model == SONYPI_DEVICE_MODEL_R505)
-		sonypi_r505_dis();
+	if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2)
+		sonypi_type2_dis();
 	else
-		sonypi_normal_dis();
+		sonypi_type1_dis();
 	free_irq(sonypi_device.irq, sonypi_irq);
 	release_region(sonypi_device.ioport1, sonypi_device.region_size);
 	misc_deregister(&sonypi_misc_device);
@@ -658,10 +679,13 @@
 static struct pci_device_id sonypi_id_tbl[] __devinitdata = {
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, 
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
-	  (unsigned long) SONYPI_DEVICE_MODEL_NORMAL },
+	  (unsigned long) SONYPI_DEVICE_MODEL_TYPE1 },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
-	  (unsigned long) SONYPI_DEVICE_MODEL_R505 },
+	  (unsigned long) SONYPI_DEVICE_MODEL_TYPE2 },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+	  (unsigned long) SONYPI_DEVICE_MODEL_TYPE2 },
 	{ }
 };
 
@@ -685,6 +709,33 @@
 	pci_unregister_driver(&sonypi_driver);
 }
 
+#ifndef MODULE
+static int __init sonypi_setup(char *str)  {
+	int ints[6];
+
+	str = get_options(str, ARRAY_SIZE(ints), ints);
+	if (ints[0] <= 0) 
+		goto out;
+	minor = ints[1];
+	if (ints[0] == 1)
+		goto out;
+	verbose = ints[2];
+	if (ints[0] == 2)
+		goto out;
+	fnkeyinit = ints[3];
+	if (ints[0] == 3)
+		goto out;
+	camera = ints[4];
+	if (ints[0] == 4)
+		goto out;
+	compat = ints[5];
+out:
+	return 1;
+}
+
+__setup("sonypi=", sonypi_setup);
+#endif /* !MODULE */
+	
 /* Module entry points */
 module_init(sonypi_init_module);
 module_exit(sonypi_cleanup_module);
@@ -702,5 +753,7 @@
 MODULE_PARM_DESC(fnkeyinit, "set this if your Fn keys do not generate any event");
 MODULE_PARM(camera,"i");
 MODULE_PARM_DESC(camera, "set this if you have a MotionEye camera (PictureBook series)");
+MODULE_PARM(compat,"i");
+MODULE_PARM_DESC(compat, "set this if you want to enable backward compatibility mode");
 
 EXPORT_SYMBOL(sonypi_camera_command);
diff -u --recursive --new-file v2.4.12/linux/drivers/char/sonypi.h linux/drivers/char/sonypi.h
--- v2.4.12/linux/drivers/char/sonypi.h	Sun Sep 23 11:40:57 2001
+++ linux/drivers/char/sonypi.h	Thu Oct 11 09:04:57 2001
@@ -35,26 +35,26 @@
 #ifdef __KERNEL__
 
 #define SONYPI_DRIVER_MAJORVERSION	1
-#define SONYPI_DRIVER_MINORVERSION	5
+#define SONYPI_DRIVER_MINORVERSION	6
 
 #include <linux/types.h>
 #include <linux/pci.h>
 #include "linux/sonypi.h"
 
-/* Normal models use those */
+/* type1 models use those */
 #define SONYPI_IRQ_PORT			0x8034
 #define SONYPI_IRQ_SHIFT		22
 #define SONYPI_BASE			0x50
 #define SONYPI_G10A			(SONYPI_BASE+0x14)
-#define SONYPI_NORMAL_REGION_SIZE	0x08
+#define SONYPI_TYPE1_REGION_SIZE	0x08
 
-/* R505 series specifics */
-#define SONYPI_SIRQ		0x9b
-#define SONYPI_SLOB		0x9c
-#define SONYPI_SHIB		0x9d
-#define SONYPI_R505_REGION_SIZE	0x20
+/* type2 series specifics */
+#define SONYPI_SIRQ			0x9b
+#define SONYPI_SLOB			0x9c
+#define SONYPI_SHIB			0x9d
+#define SONYPI_TYPE2_REGION_SIZE	0x20
 
-/* ioports used for brightness and R505 events */
+/* ioports used for brightness and type2 events */
 #define SONYPI_DATA_IOPORT	0x62
 #define SONYPI_CST_IOPORT	0x66
 
@@ -64,7 +64,7 @@
 	u16	port2;
 };
 
-static struct sonypi_ioport_list sonypi_normal_ioport_list[] = {
+static struct sonypi_ioport_list sonypi_type1_ioport_list[] = {
 	{ 0x10c0, 0x10c4 },	/* looks like the default on C1Vx */
 	{ 0x1080, 0x1084 },
 	{ 0x1090, 0x1094 },
@@ -73,7 +73,7 @@
 	{ 0x0, 0x0 }
 };
 
-static struct sonypi_ioport_list sonypi_r505_ioport_list[] = {
+static struct sonypi_ioport_list sonypi_type2_ioport_list[] = {
 	{ 0x1080, 0x1084 },
 	{ 0x10a0, 0x10a4 },
 	{ 0x10c0, 0x10c4 },
@@ -87,14 +87,14 @@
 	u16	bits;
 };
 
-static struct sonypi_irq_list sonypi_normal_irq_list[] = {
+static struct sonypi_irq_list sonypi_type1_irq_list[] = {
 	{ 11, 0x2 },	/* IRQ 11, GO22=0,GO23=1 in AML */
 	{ 10, 0x1 },	/* IRQ 10, GO22=1,GO23=0 in AML */
 	{  5, 0x0 },	/* IRQ  5, GO22=0,GO23=0 in AML */
 	{  0, 0x3 }	/* no IRQ, GO22=1,GO23=1 in AML */
 };
 
-static struct sonypi_irq_list sonypi_r505_irq_list[] = {
+static struct sonypi_irq_list sonypi_type2_irq_list[] = {
 	{ 11, 0x80 },	/* IRQ 11, 0x80 in SIRQ in AML */
 	{ 10, 0x40 },	/* IRQ 10, 0x40 in SIRQ in AML */
 	{  9, 0x20 },	/* IRQ  9, 0x20 in SIRQ in AML */
@@ -132,13 +132,15 @@
 #define SONYPI_CAMERA_ROMVERSION 		9
 
 /* key press event data (ioport2) */
-#define SONYPI_NORMAL_JOGGER_EV	0x10
-#define SONYPI_R505_JOGGER_EV	0x08
+#define SONYPI_TYPE1_JOGGER_EV	0x10
+#define SONYPI_TYPE2_JOGGER_EV	0x08
 #define SONYPI_CAPTURE_EV	0x60
-#define SONYPI_NORMAL_FNKEY_EV	0x20
-#define SONYPI_R505_FNKEY_EV	0x08
+#define SONYPI_TYPE1_FNKEY_EV	0x20
+#define SONYPI_TYPE2_FNKEY_EV	0x08
 #define SONYPI_BLUETOOTH_EV	0x30
-#define SONYPI_NORMAL_PKEY_EV	0x40
+#define SONYPI_TYPE1_PKEY_EV	0x40
+#define SONYPI_BACK_EV		0x08
+#define SONYPI_LID_EV		0x38
 
 struct sonypi_event {
 	u8	data;
@@ -204,6 +206,19 @@
 	{ 0x00, 0x00 }
 };
 
+/* The set of possible back button events */
+static struct sonypi_event sonypi_backev[] = {
+	{ 0x20, SONYPI_EVENT_BACK_PRESSED },
+	{ 0x00, 0x00 }
+};
+
+/* The set of possible lid events */
+static struct sonypi_event sonypi_lidev[] = {
+	{ 0x51, SONYPI_EVENT_LID_CLOSED },
+	{ 0x50, SONYPI_EVENT_LID_OPENED },
+	{ 0x00, 0x00 }
+};
+
 #define SONYPI_BUF_SIZE	128
 struct sonypi_queue {
 	unsigned long head;
@@ -215,8 +230,8 @@
 	unsigned char buf[SONYPI_BUF_SIZE];
 };
 
-#define SONYPI_DEVICE_MODEL_NORMAL	1
-#define SONYPI_DEVICE_MODEL_R505	2
+#define SONYPI_DEVICE_MODEL_TYPE1	1
+#define SONYPI_DEVICE_MODEL_TYPE2	2
 
 struct sonypi_device {
 	struct pci_dev *dev;
@@ -232,11 +247,11 @@
 	int model;
 };
 
-#define wait_on_command(command) { \
+#define wait_on_command(quiet, command) { \
 	unsigned int n = 10000; \
 	while (--n && (command)) \
 		udelay(1); \
-	if (!n) \
+	if (!n && (verbose || !quiet)) \
 		printk(KERN_WARNING "sonypi command failed at " __FILE__ " : " __FUNCTION__ "(line %d)\n", __LINE__); \
 }
 
diff -u --recursive --new-file v2.4.12/linux/drivers/char/toshiba.c linux/drivers/char/toshiba.c
--- v2.4.12/linux/drivers/char/toshiba.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/char/toshiba.c	Thu Oct 11 09:04:57 2001
@@ -17,7 +17,9 @@
  *     0xfc15: Tom May <tom@you-bastards.com>
  *     0xfc17: Dave Konrad <konrad@xenia.it>
  *     0xfc1a: George Betzos <betzos@engr.colostate.edu>
+ *     0xfc1b: Munemasa Wada <munemasa@jnovel.co.jp>
  *     0xfc1d: Arthur Liu <armie@slap.mine.nu>
+ *     0xfc5a: Jacques L'helgoualc'h <lhh@free.fr>
  *     0xfcd1: Mr. Dave Konrad <konrad@xenia.it>
  *
  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -51,7 +53,7 @@
  *
  */
 
-#define TOSH_VERSION "1.9 22/3/2001"
+#define TOSH_VERSION "1.11 26/9/2001"
 #define TOSH_DEBUG 0
 
 #include <linux/module.h>
@@ -264,7 +266,7 @@
 	if (!arg)
 		return -EINVAL;
 
-	if(copy_from_user(&regs, (SMMRegisters *) arg, sizeof(SMMRegisters)))
+	if (copy_from_user(&regs, (SMMRegisters *) arg, sizeof(SMMRegisters)))
 		return -EFAULT;
 
 	switch (cmd) {
@@ -288,7 +290,7 @@
 			return -EINVAL;
 	}
 
-        if(copy_to_user((SMMRegisters *) arg, &regs, sizeof(SMMRegisters)))
+        if (copy_to_user((SMMRegisters *) arg, &regs, sizeof(SMMRegisters)))
         	return -EFAULT;
 
 	return (err==0) ? 0:-EINVAL;
@@ -335,7 +337,8 @@
 {
 	switch (tosh_id) {
 		case 0xfc02: case 0xfc04: case 0xfc09: case 0xfc0a: case 0xfc10:
-		case 0xfc11: case 0xfc13: case 0xfc15: case 0xfc1a:
+		case 0xfc11: case 0xfc13: case 0xfc15: case 0xfc1a: case 0xfc1b:
+		case 0xfc5a:
 			tosh_fn = 0x62;
 			break;
 		case 0xfc08: case 0xfc17: case 0xfc1d: case 0xfcd1: case 0xfce0:
@@ -412,8 +415,19 @@
  */
 int tosh_probe(void)
 {
-	int major,minor,day,year,month,flag;
+	int i,major,minor,day,year,month,flag;
+	unsigned char signature[7] = { 0x54,0x4f,0x53,0x48,0x49,0x42,0x41 };
 	SMMRegisters regs;
+
+	/* extra sanity check for the string "TOSHIBA" in the BIOS because
+	   some machines that are not Toshiba's pass the next test */
+
+	for (i=0;i<7;i++) {
+		if (isa_readb(0xfe010+i)!=signature[i]) {
+			printk("toshiba: not a supported Toshiba laptop\n");
+			return -ENODEV;
+		}
+	}
 
 	/* call the Toshiba SCI support check routine */
 	
diff -u --recursive --new-file v2.4.12/linux/drivers/fc4/soc.c linux/drivers/fc4/soc.c
--- v2.4.12/linux/drivers/fc4/soc.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/fc4/soc.c	Thu Oct 11 09:14:32 2001
@@ -764,3 +764,4 @@
 
 module_init(soc_probe);
 module_exit(soc_cleanup);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/fc4/socal.c linux/drivers/fc4/socal.c
--- v2.4.12/linux/drivers/fc4/socal.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/fc4/socal.c	Thu Oct 11 09:14:32 2001
@@ -904,3 +904,4 @@
 
 module_init(socal_probe);
 module_exit(socal_cleanup);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/i2c/Config.in linux/drivers/i2c/Config.in
--- v2.4.12/linux/drivers/i2c/Config.in	Sun Sep 23 11:40:57 2001
+++ linux/drivers/i2c/Config.in	Thu Oct 11 08:05:47 2001
@@ -26,11 +26,24 @@
          dep_tristate '  ITE I2C Adapter' CONFIG_ITE_I2C_ADAP $CONFIG_ITE_I2C_ALGO
       fi
    fi
+   if [ "$CONFIG_8xx" = "y" ]; then
+      dep_tristate 'MPC8xx CPM I2C interface' CONFIG_I2C_ALGO8XX $CONFIG_I2C
+      if [ "$CONFIG_RPXLITE" = "y" -o "$CONFIG_RPXCLASSIC" = "y" ]; then
+         dep_tristate '  Embedded Planet RPX Lite/Classic suppoort' CONFIG_I2C_RPXLITE $CONFIG_I2C_ALGO8XX
+      fi
+   fi
+   if [ "$CONFIG_405" = "y" ]; then
+      dep_tristate 'PPC 405 I2C Algorithm' CONFIG_I2C_PPC405_ALGO $CONFIG_I2C
+      if [ "$CONFIG_I2C_PPC405_ALGO" != "n" ]; then
+         dep_tristate '  PPC 405 I2C Adapter' CONFIG_I2C_PPC405_ADAP $CONFIG_I2C_PPC405_ALGO
+      fi
+   fi
 
 # This is needed for automatic patch generation: sensors code starts here
 # This is needed for automatic patch generation: sensors code ends here
 
    dep_tristate 'I2C device interface' CONFIG_I2C_CHARDEV $CONFIG_I2C
+   dep_tristate 'I2C /proc interface (required for hardware sensors)' CONFIG_I2C_PROC $CONFIG_I2C
 
 fi
 endmenu
diff -u --recursive --new-file v2.4.12/linux/drivers/i2c/Makefile linux/drivers/i2c/Makefile
--- v2.4.12/linux/drivers/i2c/Makefile	Fri Dec 29 14:07:21 2000
+++ linux/drivers/i2c/Makefile	Thu Oct 11 08:05:47 2001
@@ -4,7 +4,8 @@
 
 O_TARGET := i2c.o
 
-export-objs	:= i2c-core.o i2c-algo-bit.o i2c-algo-pcf.o
+export-objs	:= i2c-core.o i2c-algo-bit.o i2c-algo-pcf.o \
+		   i2c-algo-ite.o i2c-proc.o
 
 obj-$(CONFIG_I2C)		+= i2c-core.o
 obj-$(CONFIG_I2C_CHARDEV)	+= i2c-dev.o
@@ -14,6 +15,9 @@
 obj-$(CONFIG_I2C_VELLEMAN)	+= i2c-velleman.o
 obj-$(CONFIG_I2C_ALGOPCF)	+= i2c-algo-pcf.o
 obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o
+obj-$(CONFIG_ITE_I2C_ALGO)	+= i2c-algo-ite.o
+obj-$(CONFIG_ITE_I2C_ADAP)	+= i2c-adap-ite.o
+obj-$(CONFIG_I2C_PROC)		+= i2c-proc.o
 
 # This is needed for automatic patch generation: sensors code starts here
 # This is needed for automatic patch generation: sensors code ends here
diff -u --recursive --new-file v2.4.12/linux/drivers/i2c/i2c-adap-ite.c linux/drivers/i2c/i2c-adap-ite.c
--- v2.4.12/linux/drivers/i2c/i2c-adap-ite.c	Tue Oct  9 17:06:51 2001
+++ linux/drivers/i2c/i2c-adap-ite.c	Thu Oct 11 08:05:47 2001
@@ -37,7 +37,7 @@
 #include <linux/ioport.h>
 #include <linux/module.h>
 #include <linux/delay.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/version.h>
 #include <linux/init.h>
 #include <asm/irq.h>
diff -u --recursive --new-file v2.4.12/linux/drivers/i2c/i2c-algo-bit.c linux/drivers/i2c/i2c-algo-bit.c
--- v2.4.12/linux/drivers/i2c/i2c-algo-bit.c	Tue Oct  9 17:06:51 2001
+++ linux/drivers/i2c/i2c-algo-bit.c	Thu Oct 11 08:05:47 2001
@@ -21,7 +21,7 @@
 /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
    Frodo Looijaard <frodol@dds.nl> */
 
-/* $Id: i2c-algo-bit.c,v 1.27 2000/07/09 15:16:16 frodo Exp $ */
+/* $Id: i2c-algo-bit.c,v 1.30 2001/07/29 02:44:25 mds Exp $ */
 
 #include <linux/kernel.h>
 #include <linux/module.h>
diff -u --recursive --new-file v2.4.12/linux/drivers/i2c/i2c-algo-ite.c linux/drivers/i2c/i2c-algo-ite.c
--- v2.4.12/linux/drivers/i2c/i2c-algo-ite.c	Tue Oct  9 17:06:51 2001
+++ linux/drivers/i2c/i2c-algo-ite.c	Thu Oct 11 08:05:47 2001
@@ -37,7 +37,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/delay.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/version.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.12/linux/drivers/i2c/i2c-algo-pcf.c linux/drivers/i2c/i2c-algo-pcf.c
--- v2.4.12/linux/drivers/i2c/i2c-algo-pcf.c	Tue Oct  9 17:06:51 2001
+++ linux/drivers/i2c/i2c-algo-pcf.c	Thu Oct 11 08:05:47 2001
@@ -1,4 +1,3 @@
-
 /* ------------------------------------------------------------------------- */
 /* i2c-algo-pcf.c i2c driver algorithms for PCF8584 adapters		     */
 /* ------------------------------------------------------------------------- */
@@ -24,7 +23,9 @@
    Frodo Looijaard <frodol@dds.nl> ,and also from Martin Bailey
    <mbailey@littlefeet-inc.com> */
 
-/* $Id: i2c-algo-pcf.c,v 1.25 2000/11/10 13:43:32 frodo Exp $ */
+/* Partially rewriten by Oleg I. Vdovikin <vdovikin@jscc.ru> to handle multiple
+   messages, proper stop/repstart signaling during receive,
+   added detect code */
 
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -49,26 +50,9 @@
  	/* debug the protocol by showing transferred bits */
 #define DEF_TIMEOUT 16
 
-/* debugging - slow down transfer to have a look at the data .. 	*/
-/* I use this with two leds&resistors, each one connected to sda,scl 	*/
-/* respectively. This makes sure that the algorithm works. Some chips   */
-/* might not like this, as they have an internal timeout of some mils	*/
-/*
-#define SLO_IO      jif=jiffies;while(jiffies<=jif+i2c_table[minor].veryslow)\
-                        if (need_resched) schedule();
-*/
-
-
-/* ----- global variables ---------------------------------------------	*/
-
-#ifdef SLO_IO
-	int jif;
-#endif
-
 /* module parameters:
  */
-static int i2c_debug=1;
-static int pcf_test=0;	/* see if the line-setting functions work	*/
+static int i2c_debug=0;
 static int pcf_scan=0;	/* have a look at what's hanging 'round		*/
 
 /* --- setting states on the bus with the right timing: ---------------	*/
@@ -80,7 +64,6 @@
 #define i2c_outb(adap, val) adap->setpcf(adap->data, 0, val)
 #define i2c_inb(adap) adap->getpcf(adap->data, 0)
 
-
 /* --- other auxiliary functions --------------------------------------	*/
 
 static void i2c_start(struct i2c_algo_pcf_data *adap) 
@@ -111,16 +94,15 @@
 	status = get_pcf(adap, 1);
 #ifndef STUB_I2C
 	while (timeout-- && !(status & I2C_PCF_BB)) {
-		udelay(1000); /* How much is this? */
+		udelay(100); /* wait for 100 us */
 		status = get_pcf(adap, 1);
 	}
 #endif
-	if (timeout<=0)
+	if (timeout <= 0) {
 		printk("Timeout waiting for Bus Busy\n");
-	/*
-	set_pcf(adap, 1, I2C_PCF_STOP);
-	*/
-	return(timeout<=0);
+	}
+	
+	return (timeout<=0);
 }
 
 
@@ -147,7 +129,6 @@
 		return(0);
 }
 
-
 /* 
  * This should perform the 'PCF8584 initialization sequence' as described
  * in the Philips IC12 data book (1995, Aug 29).
@@ -156,111 +137,64 @@
  * There should be a delay at the end equal to the longest I2C message
  * to synchronize the BB-bit (in multimaster systems). How long is
  * this? I assume 1 second is always long enough.
+ *
+ * vdovikin: added detect code for PCF8584
  */
 static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
 {
+	unsigned char temp;
+
+	DEB3(printk("i2c-algo-pcf.o: PCF state 0x%02x\n", get_pcf(adap, 1)));
 
-	/* S1=0x80: S0 selected, serial interface off			*/
+	/* S1=0x80: S0 selected, serial interface off */
 	set_pcf(adap, 1, I2C_PCF_PIN);
+	/* check to see S1 now used as R/W ctrl -
+	   PCF8584 does that when ESO is zero */
+	/* PCF also resets PIN bit */
+	if ((temp = get_pcf(adap, 1)) != (0)) {
+		DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp));
+		return -ENXIO; /* definetly not PCF8584 */
+	}
 
 	/* load own address in S0, effective address is (own << 1)	*/
 	i2c_outb(adap, get_own(adap));
+	/* check it's realy writen */
+	if ((temp = i2c_inb(adap)) != get_own(adap)) {
+		DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't set S0 (0x%02x).\n", temp));
+		return -ENXIO;
+	}
 
 	/* S1=0xA0, next byte in S2					*/
 	set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1);
+	/* check to see S2 now selected */
+	if ((temp = get_pcf(adap, 1)) != I2C_PCF_ES1) {
+		DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't select S2 (0x%02x).\n", temp));
+		return -ENXIO;
+	}
 
 	/* load clock register S2					*/
 	i2c_outb(adap, get_clock(adap));
+	/* check it's realy writen, the only 5 lowest bits does matter */
+	if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) {
+		DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't set S2 (0x%02x).\n", temp));
+		return -ENXIO;
+	}
 
 	/* Enable serial interface, idle, S0 selected			*/
 	set_pcf(adap, 1, I2C_PCF_IDLE);
 
-	DEB2(printk("i2c-algo-pcf.o: irq: Initialized 8584.\n"));
-	return 0;
-}
-
-
-/*
- * Sanity check for the adapter hardware - check the reaction of
- * the bus lines only if it seems to be idle.
- */
-static int test_bus(struct i2c_algo_pcf_data *adap, char *name) {
-#if 0
-	int scl,sda;
-	sda=getsda(adap);
-	if (adap->getscl==NULL) {
-		printk("i2c-algo-pcf.o: Warning: Adapter can't read from clock line - skipping test.\n");
-		return 0;		
-	}
-	scl=getscl(adap);
-	printk("i2c-algo-pcf.o: Adapter: %s scl: %d  sda: %d -- testing...\n",
-	name,getscl(adap),getsda(adap));
-	if (!scl || !sda ) {
-		printk("i2c-algo-pcf.o: %s seems to be busy.\n",adap->name);
-		goto bailout;
-	}
-	sdalo(adap);
-	printk("i2c-algo-pcf.o:1 scl: %d  sda: %d \n",getscl(adap),
-	       getsda(adap));
-	if ( 0 != getsda(adap) ) {
-		printk("i2c-algo-pcf.o: %s SDA stuck high!\n",name);
-		sdahi(adap);
-		goto bailout;
-	}
-	if ( 0 == getscl(adap) ) {
-		printk("i2c-algo-pcf.o: %s SCL unexpected low while pulling SDA low!\n",
-			name);
-		goto bailout;
-	}		
-	sdahi(adap);
-	printk("i2c-algo-pcf.o:2 scl: %d  sda: %d \n",getscl(adap),
-	       getsda(adap));
-	if ( 0 == getsda(adap) ) {
-		printk("i2c-algo-pcf.o: %s SDA stuck low!\n",name);
-		sdahi(adap);
-		goto bailout;
-	}
-	if ( 0 == getscl(adap) ) {
-		printk("i2c-algo-pcf.o: %s SCL unexpected low while SDA high!\n",
-		       adap->name);
-	goto bailout;
+	/* check to see PCF is realy idled and we can access status register */
+	if ((temp = get_pcf(adap, 1)) != (I2C_PCF_PIN | I2C_PCF_BB)) {
+		DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp));
+		return -ENXIO;
 	}
-	scllo(adap);
-	printk("i2c-algo-pcf.o:3 scl: %d  sda: %d \n",getscl(adap),
-	       getsda(adap));
-	if ( 0 != getscl(adap) ) {
-		printk("i2c-algo-pcf.o: %s SCL stuck high!\n",name);
-		sclhi(adap);
-		goto bailout;
-	}
-	if ( 0 == getsda(adap) ) {
-		printk("i2c-algo-pcf.o: %s SDA unexpected low while pulling SCL low!\n",
-			name);
-		goto bailout;
-	}
-	sclhi(adap);
-	printk("i2c-algo-pcf.o:4 scl: %d  sda: %d \n",getscl(adap),
-	       getsda(adap));
-	if ( 0 == getscl(adap) ) {
-		printk("i2c-algo-pcf.o: %s SCL stuck low!\n",name);
-		sclhi(adap);
-		goto bailout;
-	}
-	if ( 0 == getsda(adap) ) {
-		printk("i2c-algo-pcf.o: %s SDA unexpected low while SCL high!\n",
-			name);
-		goto bailout;
-	}
-	printk("i2c-algo-pcf.o: %s passed test.\n",name);
+	
+	printk("i2c-algo-pcf.o: deteted and initialized PCF8584.\n");
+
 	return 0;
-bailout:
-	sdahi(adap);
-	sclhi(adap);
-	return -ENODEV;
-#endif
-	return (0);
 }
 
+
 /* ----- Utility functions
  */
 
@@ -287,8 +221,8 @@
 }
 
 
-static int pcf_sendbytes(struct i2c_adapter *i2c_adap,const char *buf,
-                         int count)
+static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf,
+                         int count, int last)
 {
 	struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
 	int wrcount, status, timeout;
@@ -313,58 +247,59 @@
 		}
 #endif
 	}
-	i2c_stop(adap);
+	if (last) {
+		i2c_stop(adap);
+	}
+	else {
+		i2c_repstart(adap);
+	}
+
 	return (wrcount);
 }
 
 
-static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count)
+static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf,
+                         int count, int last)
 {
-	int rdcount=0, i, status, timeout, dummy=1;
+	int i, status;
 	struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
-    
-	for (i=0; i<count; ++i) {
-		buf[rdcount] = i2c_inb(adap);
-		if (dummy) {
-			dummy = 0;
-		} else {
-			rdcount++;
-		}
-		timeout = wait_for_pin(adap, &status);
-		if (timeout) {
+
+	/* increment number of bytes to read by one -- read dummy byte */
+	for (i = 0; i <= count; i++) {
+
+		if (wait_for_pin(adap, &status)) {
 			i2c_stop(adap);
-			printk("i2c-algo-pcf.o: i2c_read: "
-			       "i2c_inb timed out.\n");
+			printk("i2c-algo-pcf.o: pcf_readbytes timed out.\n");
 			return (-1);
 		}
+
 #ifndef STUB_I2C
-		if (status & I2C_PCF_LRB) {
+		if ((status & I2C_PCF_LRB) && (i != count)) {
 			i2c_stop(adap);
 			printk("i2c-algo-pcf.o: i2c_read: i2c_inb, No ack.\n");
 			return (-1);
 		}
 #endif
-	}
-	set_pcf(adap, 1, I2C_PCF_ESO);
-	buf[rdcount] = i2c_inb(adap);
-	if (dummy) {
-		dummy = 0;
-	} else {
-		rdcount++;
-	}
-	timeout = wait_for_pin(adap, &status);
-	if (timeout) {
-		i2c_stop(adap);
-		printk("i2c-algo-pcf.o: i2c_read: i2c_inb timed out.\n");
-		return (-1);
-	}
-    
-	i2c_stop(adap);
+		
+		if (i == count - 1) {
+			set_pcf(adap, 1, I2C_PCF_ESO);
+		} else 
+		if (i == count) {
+			if (last) {
+				i2c_stop(adap);
+			} else {
+				i2c_repstart(adap);
+			}
+		};
 
-	/* Read final byte from S0 register */
-	buf[rdcount++] = i2c_inb(adap);
+		if (i) {
+			buf[i - 1] = i2c_inb(adap);
+		} else {
+			i2c_inb(adap); /* dummy read */
+		}
+	}
 
-	return (rdcount);
+	return (i - 1);
 }
 
 
@@ -418,16 +353,10 @@
 {
 	struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
 	struct i2c_msg *pmsg;
-	int i = 0;
-	int ret, timeout, status;
-    
-	pmsg = &msgs[i];
-    
-	/* Send address here if Read */
-	if (pmsg->flags & I2C_M_RD) {
-		ret = pcf_doAddress(adap, pmsg, i2c_adap->retries);
-	}
+	int i;
+	int ret=0, timeout, status;
     
+
 	/* Check for bus busy */
 	timeout = wait_for_bb(adap);
 	if (timeout) {
@@ -435,60 +364,68 @@
 		            "Timeout waiting for BB in pcf_xfer\n");)
 		return -EIO;
 	}
+	
+	for (i = 0;ret >= 0 && i < num; i++) {
+		pmsg = &msgs[i];
+
+		DEB2(printk("i2c-algo-pcf.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n",
+		     pmsg->flags & I2C_M_RD ? "read" : "write",
+                     pmsg->len, pmsg->addr, i + 1, num);)
     
-	/* Send address here if Write */
-	if (!(pmsg->flags & I2C_M_RD)) {
 		ret = pcf_doAddress(adap, pmsg, i2c_adap->retries);
-	}
-	/* Send START */
-	i2c_start(adap);
+
+		/* Send START */
+		if (i == 0) {
+			i2c_start(adap); 
+		}
     
-	/* Wait for PIN (pending interrupt NOT) */
-	timeout = wait_for_pin(adap, &status);
-	if (timeout) {
-		i2c_stop(adap);
-		DEB2(printk("i2c-algo-pcf.o: Timeout waiting "
-		            "for PIN(1) in pcf_xfer\n");)
-		return (-EREMOTEIO);
-	}
+		/* Wait for PIN (pending interrupt NOT) */
+		timeout = wait_for_pin(adap, &status);
+		if (timeout) {
+			i2c_stop(adap);
+			DEB2(printk("i2c-algo-pcf.o: Timeout waiting "
+				    "for PIN(1) in pcf_xfer\n");)
+			return (-EREMOTEIO);
+		}
     
 #ifndef STUB_I2C
-	/* Check LRB (last rcvd bit - slave ack) */
-	if (status & I2C_PCF_LRB) {
-		i2c_stop(adap);
-		DEB2(printk("i2c-algo-pcf.o: No LRB(1) in pcf_xfer\n");)
-		return (-EREMOTEIO);
-	}
+		/* Check LRB (last rcvd bit - slave ack) */
+		if (status & I2C_PCF_LRB) {
+			i2c_stop(adap);
+			DEB2(printk("i2c-algo-pcf.o: No LRB(1) in pcf_xfer\n");)
+			return (-EREMOTEIO);
+		}
 #endif
     
-	DEB3(printk("i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n",
-	            i, msgs[i].addr, msgs[i].flags, msgs[i].len);)
+		DEB3(printk("i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n",
+			    i, msgs[i].addr, msgs[i].flags, msgs[i].len);)
     
-	/* Read */
-	if (pmsg->flags & I2C_M_RD) {
+		/* Read */
+		if (pmsg->flags & I2C_M_RD) {
+			/* read bytes into buffer*/
+			ret = pcf_readbytes(i2c_adap, pmsg->buf, pmsg->len,
+                                            (i + 1 == num));
         
-		/* read bytes into buffer*/
-		ret = pcf_readbytes(i2c_adap, pmsg->buf, pmsg->len);
-        
-		if (ret != pmsg->len) {
-			DEB2(printk("i2c-algo-pcf.o: fail: "
-			            "only read %d bytes.\n",ret));
-		} else {
-			DEB2(printk("i2c-algo-pcf.o: read %d bytes.\n",ret));
-		}
-	} else { /* Write */
-        
-        /* Write bytes from buffer */
-		ret = pcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len);
+			if (ret != pmsg->len) {
+				DEB2(printk("i2c-algo-pcf.o: fail: "
+					    "only read %d bytes.\n",ret));
+			} else {
+				DEB2(printk("i2c-algo-pcf.o: read %d bytes.\n",ret));
+			}
+		} else { /* Write */
+			ret = pcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len,
+                                            (i + 1 == num));
         
-		if (ret != pmsg->len) {
-			DEB2(printk("i2c-algo-pcf.o: fail: "
-			            "only wrote %d bytes.\n",ret));
-		} else {
-			DEB2(printk("i2c-algo-pcf.o: wrote %d bytes.\n",ret));
+			if (ret != pmsg->len) {
+				DEB2(printk("i2c-algo-pcf.o: fail: "
+					    "only wrote %d bytes.\n",ret));
+			} else {
+				DEB2(printk("i2c-algo-pcf.o: wrote %d bytes.\n",ret));
+			}
 		}
 	}
-	return (num);
+
+	return (i);
 }
 
 static int algo_control(struct i2c_adapter *adapter, 
@@ -524,12 +461,6 @@
 	int i, status;
 	struct i2c_algo_pcf_data *pcf_adap = adap->algo_data;
 
-	if (pcf_test) {
-		int ret = test_bus(pcf_adap, adap->name);
-		if (ret<0)
-			return -ENODEV;
-	}
-
 	DEB2(printk("i2c-algo-pcf.o: hw routines for %s registered.\n",
 	            adap->name));
 
@@ -538,21 +469,29 @@
 	adap->id |= pcf_algo.id;
 	adap->algo = &pcf_algo;
 
-	adap->timeout = 100;	/* default values, should	*/
+	adap->timeout = 100;		/* default values, should	*/
 	adap->retries = 3;		/* be replaced by defines	*/
 
+	if ((i = pcf_init_8584(pcf_adap))) {
+		return i;
+	}
+
 #ifdef MODULE
 	MOD_INC_USE_COUNT;
 #endif
 
 	i2c_add_adapter(adap);
-	pcf_init_8584(pcf_adap);
 
 	/* scan bus */
 	if (pcf_scan) {
 		printk(KERN_INFO " i2c-algo-pcf.o: scanning bus %s.\n",
 		       adap->name);
 		for (i = 0x00; i < 0xff; i+=2) {
+			if (wait_for_bb(pcf_adap)) {
+    			printk(KERN_INFO " i2c-algo-pcf.o: scanning bus %s - TIMEOUTed.\n",
+		           adap->name);
+			    break;
+			}
 			i2c_outb(pcf_adap, i);
 			i2c_start(pcf_adap);
 			if ((wait_for_pin(pcf_adap, &status) >= 0) && 
@@ -598,11 +537,9 @@
 MODULE_DESCRIPTION("I2C-Bus PCF8584 algorithm");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(pcf_test, "i");
 MODULE_PARM(pcf_scan, "i");
 MODULE_PARM(i2c_debug,"i");
 
-MODULE_PARM_DESC(pcf_test, "Test if the I2C bus is available");
 MODULE_PARM_DESC(pcf_scan, "Scan for active chips on the bus");
 MODULE_PARM_DESC(i2c_debug,
         "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol");
diff -u --recursive --new-file v2.4.12/linux/drivers/i2c/i2c-core.c linux/drivers/i2c/i2c-core.c
--- v2.4.12/linux/drivers/i2c/i2c-core.c	Tue Oct  9 17:06:51 2001
+++ linux/drivers/i2c/i2c-core.c	Thu Oct 11 08:05:47 2001
@@ -20,7 +20,7 @@
 /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>.
    All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl> */
 
-/* $Id: i2c-core.c,v 1.58 2000/10/29 22:57:38 frodo Exp $ */
+/* $Id: i2c-core.c,v 1.64 2001/08/13 01:35:56 mds Exp $ */
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -248,7 +248,7 @@
 		     */
 			if ((res=client->driver->detach_client(client))) {
 				printk("i2c-core.o: adapter %s not "
-					"unregisted, because client at "
+					"unregistered, because client at "
 					"address %02x can't be detached. ",
 					adap->name, client->addr);
 				goto ERROR0;
@@ -563,6 +563,7 @@
 			if(adapters[j]->clients[i]->flags & I2C_CLIENT_ALLOW_USE)	
 				return adapters[j]->clients[i];
 		}
+		i = 0;
 	}
 
 	return 0;
@@ -658,7 +659,7 @@
 	int i,j,k,order_nr,len=0,len_total;
 	int order[I2C_CLIENT_MAX];
 
-	if (count < 0)
+	if (count > 4000)
 		return -EINVAL; 
 	len_total = file->f_pos + count;
 	/* Too bad if this gets longer (unlikely) */
@@ -1277,14 +1278,41 @@
 }
 
 #ifndef MODULE
+#ifdef CONFIG_I2C_CHARDEV
 	extern int i2c_dev_init(void);
+#endif
+#ifdef CONFIG_I2C_ALGOBIT
 	extern int i2c_algo_bit_init(void);
+#endif
+#ifdef CONFIG_I2C_CONFIG_I2C_PHILIPSPAR
 	extern int i2c_bitlp_init(void);
+#endif
+#ifdef CONFIG_I2C_ELV
 	extern int i2c_bitelv_init(void);
+#endif
+#ifdef CONFIG_I2C_VELLEMAN
 	extern int i2c_bitvelle_init(void);
+#endif
+#ifdef CONFIG_I2C_BITVIA
 	extern int i2c_bitvia_init(void);
+#endif
+
+#ifdef CONFIG_I2C_ALGOPCF
 	extern int i2c_algo_pcf_init(void);	
+#endif
+#ifdef CONFIG_I2C_ELEKTOR
 	extern int i2c_pcfisa_init(void);
+#endif
+
+#ifdef CONFIG_I2C_ALGO8XX
+	extern int i2c_algo_8xx_init(void);
+#endif
+#ifdef CONFIG_I2C_RPXLITE
+	extern int i2c_rpx_init(void);
+#endif
+#ifdef CONFIG_I2C_PROC
+	extern int sensors_init(void);
+#endif
 
 /* This is needed for automatic patch generation: sensors code starts here */
 /* This is needed for automatic patch generation: sensors code ends here   */
@@ -1317,6 +1345,19 @@
 #endif
 #ifdef CONFIG_I2C_ELEKTOR
 	i2c_pcfisa_init();
+#endif
+
+	/* --------------------- 8xx -------- */
+#ifdef CONFIG_I2C_ALGO8XX
+	i2c_algo_8xx_init();
+#endif
+#ifdef CONFIG_I2C_RPXLITE
+	i2c_rpx_init();
+#endif
+
+	/* -------------- proc interface ---- */
+#ifdef CONFIG_I2C_PROC
+	sensors_init();
 #endif
 /* This is needed for automatic patch generation: sensors code starts here */
 /* This is needed for automatic patch generation: sensors code ends here */
diff -u --recursive --new-file v2.4.12/linux/drivers/i2c/i2c-dev.c linux/drivers/i2c/i2c-dev.c
--- v2.4.12/linux/drivers/i2c/i2c-dev.c	Tue Oct  9 17:06:51 2001
+++ linux/drivers/i2c/i2c-dev.c	Thu Oct 11 08:05:47 2001
@@ -28,7 +28,7 @@
 /* The devfs code is contributed by Philipp Matthias Hahn 
    <pmhahn@titan.lahn.de> */
 
-/* $Id: i2c-dev.c,v 1.36 2000/09/22 02:19:35 mds Exp $ */
+/* $Id: i2c-dev.c,v 1.40 2001/08/25 01:28:01 mds Exp $ */
 
 #include <linux/config.h>
 #include <linux/kernel.h>
@@ -60,6 +60,9 @@
 
 /* struct file_operations changed too often in the 2.1 series for nice code */
 
+#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,9)
+static loff_t i2cdev_lseek (struct file *file, loff_t offset, int origin);
+#endif
 static ssize_t i2cdev_read (struct file *file, char *buf, size_t count, 
                             loff_t *offset);
 static ssize_t i2cdev_write (struct file *file, const char *buf, size_t count, 
@@ -88,7 +91,11 @@
 #if LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0)
 	owner:		THIS_MODULE,
 #endif /* LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) */
+#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,9)
+	llseek:		i2cdev_lseek,
+#else
 	llseek:		no_llseek,
+#endif
 	read:		i2cdev_read,
 	write:		i2cdev_write,
 	ioctl:		i2cdev_ioctl,
@@ -126,6 +133,20 @@
 
 static int i2cdev_initialized;
 
+#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,9)
+/* Note that the lseek function is called llseek in 2.1 kernels. But things
+   are complicated enough as is. */
+loff_t i2cdev_lseek (struct file *file, loff_t offset, int origin)
+{
+#ifdef DEBUG
+	struct inode *inode = file->f_dentry->d_inode;
+	printk("i2c-dev.o: i2c-%d lseek to %ld bytes relative to %d.\n",
+	       MINOR(inode->i_rdev),(long) offset,origin);
+#endif /* DEBUG */
+	return -ESPIPE;
+}
+#endif
+
 static ssize_t i2cdev_read (struct file *file, char *buf, size_t count,
                             loff_t *offset)
 {
@@ -227,9 +248,6 @@
 				   sizeof(rdwr_arg)))
 			return -EFAULT;
 
-		if(rdwr_arg.nmsgs > 2048)
-			return -EINVAL;
-			
 		rdwr_pa = (struct i2c_msg *)
 			kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg), 
 			GFP_KERNEL);
@@ -505,7 +523,7 @@
 			       "module not removed.\n");
 			return res;
 		}
-	i2cdev_initialized ++;
+	i2cdev_initialized --;
 	}
 
 	if (i2cdev_initialized >= 1) {
diff -u --recursive --new-file v2.4.12/linux/drivers/i2c/i2c-elektor.c linux/drivers/i2c/i2c-elektor.c
--- v2.4.12/linux/drivers/i2c/i2c-elektor.c	Tue Oct  9 17:06:51 2001
+++ linux/drivers/i2c/i2c-elektor.c	Thu Oct 11 08:05:47 2001
@@ -22,7 +22,8 @@
 /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
    Frodo Looijaard <frodol@dds.nl> */
 
-/* $Id: i2c-elektor.c,v 1.19 2000/07/25 23:52:17 frodo Exp $ */
+/* Partialy rewriten by Oleg I. Vdovikin for mmapped support of 
+   for Alpha Processor Inc. UP-2000(+) boards */
 
 #include <linux/kernel.h>
 #include <linux/ioport.h>
@@ -31,6 +32,7 @@
 #include <linux/slab.h>
 #include <linux/version.h>
 #include <linux/init.h>
+#include <linux/pci.h>
 #include <asm/irq.h>
 #include <asm/io.h>
 
@@ -39,17 +41,20 @@
 #include <linux/i2c-elektor.h>
 #include "i2c-pcf8584.h"
 
-#define DEFAULT_BASE 0x300
-#define DEFAULT_IRQ      0
-#define DEFAULT_CLOCK 0x1c
-#define DEFAULT_OWN   0x55
-
-static int base  = 0;
-static int irq   = 0;
-static int clock = 0;
-static int own   = 0;
-static int i2c_debug=0;
-static struct i2c_pcf_isa gpi;
+#define DEFAULT_BASE 0x330
+
+static int base   = 0;
+static int irq    = 0;
+static int clock  = 0x1c;
+static int own    = 0x55;
+static int mmapped = 0;
+static int i2c_debug = 0;
+
+/* vdovikin: removed static struct i2c_pcf_isa gpi; code - 
+  this module in real supports only one device, due to missing arguments
+  in some functions, called from the algo-pcf module. Sometimes it's
+  need to be rewriten - but for now just remove this for simpler reading */
+
 #if (LINUX_VERSION_CODE < 0x020301)
 static struct wait_queue *pcf_wait = NULL;
 #else
@@ -63,81 +68,63 @@
 #define DEB3(x) if (i2c_debug>=3) x
 #define DEBE(x)	x	/* error messages 				*/
 
-
-/* --- Convenience defines for the i2c port:			*/
-#define BASE	((struct i2c_pcf_isa *)(data))->pi_base
-#define DATA	BASE			/* Adapter data port		*/
-#define CTRL	(BASE+1)		/* Adapter control port	        */
-
 /* ----- local functions ----------------------------------------------	*/
 
 static void pcf_isa_setbyte(void *data, int ctl, int val)
 {
-        unsigned long j = jiffies + 10;
+	int address = ctl ? (base + 1) : base;
 
-        if (ctl) {
-		if (gpi.pi_irq > 0) {
-			DEB3(printk("i2c-elektor.o: Write Ctrl 0x%02X\n",
-			     val|I2C_PCF_ENI));
-                        DEB3({while (jiffies < j) schedule();})
-			outb(val | I2C_PCF_ENI, CTRL);
-		} else {
-			 DEB3(printk("i2c-elektor.o: Write Ctrl 0x%02X\n", val|I2C_PCF_ENI));
-                         DEB3({while (jiffies < j) schedule();})
-			 outb(val|I2C_PCF_ENI, CTRL);
-		}
-	} else {
-		DEB3(printk("i2c-elektor.o: Write Data 0x%02X\n", val&0xff));
-                DEB3({while (jiffies < j) schedule();})
-		outb(val, DATA);
+	if (ctl && irq) {
+		val |= I2C_PCF_ENI;
+	}
+
+	DEB3(printk("i2c-elektor.o: Write 0x%X 0x%02X\n", address, val & 255));
+
+	switch (mmapped) {
+	case 0: /* regular I/O */
+		outb(val, address);
+		break;
+	case 2: /* double mapped I/O needed for UP2000 board,
+                   I don't know why this... */
+		writeb(val, address);
+		/* fall */
+	case 1: /* memory mapped I/O */
+		writeb(val, address);
+		break;
 	}
 }
 
 static int pcf_isa_getbyte(void *data, int ctl)
 {
-	int val;
+	int address = ctl ? (base + 1) : base;
+	int val = mmapped ? readb(address) : inb(address);
+
+	DEB3(printk("i2c-elektor.o: Read 0x%X 0x%02X\n", address, val));
 
-	if (ctl) {
-		val = inb(CTRL);
-		DEB3(printk("i2c-elektor.o: Read Ctrl 0x%02X\n", val));
-	} else {
-		val = inb(DATA);
-		DEB3(printk("i2c-elektor.o: Read Data 0x%02X\n", val));
-	}
 	return (val);
 }
 
 static int pcf_isa_getown(void *data)
 {
-	return (gpi.pi_own);
+	return (own);
 }
 
 
 static int pcf_isa_getclock(void *data)
 {
-	return (gpi.pi_clock);
-}
-
-
-
-#if 0
-static void pcf_isa_sleep(unsigned long timeout)
-{
-	schedule_timeout( timeout * HZ);
+	return (clock);
 }
-#endif
-
 
 static void pcf_isa_waitforpin(void) {
 
 	int timeout = 2;
 
-	if (gpi.pi_irq > 0) {
+	if (irq > 0) {
 		cli();
-	if (pcf_pending == 0) {
-		interruptible_sleep_on_timeout(&pcf_wait, timeout*HZ );
-	} else
-		pcf_pending = 0;
+		if (pcf_pending == 0) {
+			interruptible_sleep_on_timeout(&pcf_wait, timeout*HZ );
+		} else
+			pcf_pending = 0;
 		sti();
 	} else {
 		udelay(100);
@@ -153,30 +140,34 @@
 
 static int pcf_isa_init(void)
 {
-	if (check_region(gpi.pi_base, 2) < 0 ) {
-		return -ENODEV;
-	} else {
-		request_region(gpi.pi_base, 2, "i2c (isa bus adapter)");
+	if (!mmapped) {
+		if (check_region(base, 2) < 0 ) {
+			printk("i2c-elektor.o: requested I/O region (0x%X:2) is in use.\n", base);
+			return -ENODEV;
+		} else {
+			request_region(base, 2, "i2c (isa bus adapter)");
+		}
 	}
-	if (gpi.pi_irq > 0) {
-		if (request_irq(gpi.pi_irq, pcf_isa_handler, 0, "PCF8584", 0)
-		    < 0) {
-		printk("i2c-elektor.o: Request irq%d failed\n", gpi.pi_irq);
-		gpi.pi_irq = 0;
-	} else
-		enable_irq(gpi.pi_irq);
+	if (irq > 0) {
+		if (request_irq(irq, pcf_isa_handler, 0, "PCF8584", 0) < 0) {
+			printk("i2c-elektor.o: Request irq%d failed\n", irq);
+			irq = 0;
+		} else
+			enable_irq(irq);
 	}
 	return 0;
 }
 
 
-static void pcf_isa_exit(void)
+static void __exit pcf_isa_exit(void)
 {
-	if (gpi.pi_irq > 0) {
-		disable_irq(gpi.pi_irq);
-		free_irq(gpi.pi_irq, 0);
+	if (irq > 0) {
+		disable_irq(irq);
+		free_irq(irq, 0);
+	}
+	if (!mmapped) {
+		release_region(base , 2);
 	}
-	release_region(gpi.pi_base , 2);
 }
 
 
@@ -217,7 +208,7 @@
 	pcf_isa_getown,
 	pcf_isa_getclock,
 	pcf_isa_waitforpin,
-	80, 80, 100,		/*	waits, timeout */
+	10, 10, 100,		/*	waits, timeout */
 };
 
 static struct i2c_adapter pcf_isa_ops = {
@@ -233,31 +224,61 @@
 
 int __init i2c_pcfisa_init(void) 
 {
+#ifdef __alpha__
+	/* check to see we have memory mapped PCF8584 connected to the 
+	Cypress cy82c693 PCI-ISA bridge as on UP2000 board */
+	if ((base == 0) && pci_present()) {
+		
+		struct pci_dev *cy693_dev =
+                    pci_find_device(PCI_VENDOR_ID_CONTAQ, 
+		                    PCI_DEVICE_ID_CONTAQ_82C693, NULL);
+
+		if (cy693_dev) {
+			char config;
+			/* yeap, we've found cypress, let's check config */
+			if (!pci_read_config_byte(cy693_dev, 0x47, &config)) {
+				
+				DEB3(printk("i2c-elektor.o: found cy82c693, config register 0x47 = 0x%02x.\n", config));
+
+				/* UP2000 board has this register set to 0xe1,
+                                   but the most significant bit as seems can be 
+				   reset during the proper initialisation
+                                   sequence if guys from API decides to do that
+                                   (so, we can even enable Tsunami Pchip
+                                   window for the upper 1 Gb) */
+
+				/* so just check for ROMCS at 0xe0000,
+                                   ROMCS enabled for writes
+				   and external XD Bus buffer in use. */
+				if ((config & 0x7f) == 0x61) {
+					/* seems to be UP2000 like board */
+					base = 0xe0000;
+                                        /* I don't know why we need to
+                                           write twice */
+					mmapped = 2;
+                                        /* UP2000 drives ISA with
+					   8.25 MHz (PCI/4) clock
+					   (this can be read from cypress) */
+					clock = I2C_PCF_CLK | I2C_PCF_TRNS90;
+					printk("i2c-elektor.o: found API UP2000 like board, will probe PCF8584 later.\n");
+				}
+			}
+		}
+	}
+#endif
 
-	struct i2c_pcf_isa *pisa = &gpi;
+	/* sanity checks for mmapped I/O */
+	if (mmapped && base < 0xc8000) {
+		printk("i2c-elektor.o: incorrect base address (0x%0X) specified for mmapped I/O.\n", base);
+		return -ENODEV;
+	}
 
 	printk("i2c-elektor.o: i2c pcf8584-isa adapter module\n");
-	if (base == 0)
-		pisa->pi_base = DEFAULT_BASE;
-	else
-		pisa->pi_base = base;
-
-	if (irq == 0)
-		pisa->pi_irq = DEFAULT_IRQ;
-	else
-		pisa->pi_irq = irq;
-
-	if (clock == 0)
-		pisa->pi_clock = DEFAULT_CLOCK;
-	else
-		pisa->pi_clock = clock;
-
-	if (own == 0)
-		pisa->pi_own = DEFAULT_OWN;
-	else
-		pisa->pi_own = own;
 
-	pcf_isa_data.data = (void *)pisa;
+	if (base == 0) {
+		base = DEFAULT_BASE;
+	}
+
 #if (LINUX_VERSION_CODE >= 0x020301)
 	init_waitqueue_head(&pcf_wait);
 #endif
@@ -267,7 +288,9 @@
 	} else {
 		return -ENODEV;
 	}
-	printk("i2c-elektor.o: found device at %#x.\n", pisa->pi_base);
+	
+	printk("i2c-elektor.o: found device at %#x.\n", base);
+
 	return 0;
 }
 
@@ -283,7 +306,8 @@
 MODULE_PARM(irq, "i");
 MODULE_PARM(clock, "i");
 MODULE_PARM(own, "i");
-MODULE_PARM(i2c_debug,"i");
+MODULE_PARM(mmapped, "i");
+MODULE_PARM(i2c_debug, "i");
 
 int init_module(void) 
 {
diff -u --recursive --new-file v2.4.12/linux/drivers/i2c/i2c-elv.c linux/drivers/i2c/i2c-elv.c
--- v2.4.12/linux/drivers/i2c/i2c-elv.c	Tue Oct  9 17:06:51 2001
+++ linux/drivers/i2c/i2c-elv.c	Thu Oct 11 08:05:47 2001
@@ -21,7 +21,7 @@
 /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
    Frodo Looijaard <frodol@dds.nl> */
 
-/* $Id: i2c-elv.c,v 1.16 2000/01/18 23:54:07 frodo Exp $ */
+/* $Id: i2c-elv.c,v 1.17 2001/07/29 02:44:25 mds Exp $ */
 
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -115,7 +115,7 @@
 	return 0;
 }
 
-static void bit_elv_exit(void)
+static void __exit bit_elv_exit(void)
 {
 	release_region( base , (base == 0x3bc)? 3 : 8 );
 }
diff -u --recursive --new-file v2.4.12/linux/drivers/i2c/i2c-proc.c linux/drivers/i2c/i2c-proc.c
--- v2.4.12/linux/drivers/i2c/i2c-proc.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/i2c/i2c-proc.c	Thu Oct 11 08:05:47 2001
@@ -0,0 +1,906 @@
+/*
+    i2c-proc.c - Part of lm_sensors, Linux kernel modules for hardware
+                monitoring
+    Copyright (c) 1998 - 2001 Frodo Looijaard <frodol@dds.nl> and
+    Mark D. Studebaker <mdsxyz123@yahoo.com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+    This driver puts entries in /proc/sys/dev/sensors for each I2C device
+*/
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/sysctl.h>
+#include <linux/proc_fs.h>
+#include <linux/ioport.h>
+#include <asm/uaccess.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-proc.h>
+
+#include <linux/init.h>
+
+/* FIXME need i2c versioning */
+#define LM_DATE "20010825"
+#define LM_VERSION "2.6.1"
+
+#ifndef THIS_MODULE
+#define THIS_MODULE NULL
+#endif
+
+static int i2c_create_name(char **name, const char *prefix,
+			       struct i2c_adapter *adapter, int addr);
+static int i2c_parse_reals(int *nrels, void *buffer, int bufsize,
+			       long *results, int magnitude);
+static int i2c_write_reals(int nrels, void *buffer, int *bufsize,
+			       long *results, int magnitude);
+static int i2c_proc_chips(ctl_table * ctl, int write,
+			      struct file *filp, void *buffer,
+			      size_t * lenp);
+static int i2c_sysctl_chips(ctl_table * table, int *name, int nlen,
+				void *oldval, size_t * oldlenp,
+				void *newval, size_t newlen,
+				void **context);
+
+int __init sensors_init(void);
+
+#define SENSORS_ENTRY_MAX 20
+static struct ctl_table_header *i2c_entries[SENSORS_ENTRY_MAX];
+
+static struct i2c_client *i2c_clients[SENSORS_ENTRY_MAX];
+static unsigned short i2c_inodes[SENSORS_ENTRY_MAX];
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1)
+static void i2c_fill_inode(struct inode *inode, int fill);
+static void i2c_dir_fill_inode(struct inode *inode, int fill);
+#endif			/* LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1) */
+
+static ctl_table sysctl_table[] = {
+	{CTL_DEV, "dev", NULL, 0, 0555},
+	{0},
+	{DEV_SENSORS, "sensors", NULL, 0, 0555},
+	{0},
+	{0, NULL, NULL, 0, 0555},
+	{0}
+};
+
+static ctl_table i2c_proc_dev_sensors[] = {
+	{SENSORS_CHIPS, "chips", NULL, 0, 0644, NULL, &i2c_proc_chips,
+	 &i2c_sysctl_chips},
+	{0}
+};
+
+static ctl_table i2c_proc_dev[] = {
+	{DEV_SENSORS, "sensors", NULL, 0, 0555, i2c_proc_dev_sensors},
+	{0},
+};
+
+
+static ctl_table i2c_proc[] = {
+	{CTL_DEV, "dev", NULL, 0, 0555, i2c_proc_dev},
+	{0}
+};
+
+
+static struct ctl_table_header *i2c_proc_header;
+static int i2c_initialized;
+
+/* This returns a nice name for a new directory; for example lm78-isa-0310
+   (for a LM78 chip on the ISA bus at port 0x310), or lm75-i2c-3-4e (for
+   a LM75 chip on the third i2c bus at address 0x4e).  
+   name is allocated first. */
+int i2c_create_name(char **name, const char *prefix,
+			struct i2c_adapter *adapter, int addr)
+{
+	char name_buffer[50];
+	int id;
+	if (i2c_is_isa_adapter(adapter))
+		sprintf(name_buffer, "%s-isa-%04x", prefix, addr);
+	else {
+		if ((id = i2c_adapter_id(adapter)) < 0)
+			return -ENOENT;
+		sprintf(name_buffer, "%s-i2c-%d-%02x", prefix, id, addr);
+	}
+	*name = kmalloc(strlen(name_buffer) + 1, GFP_KERNEL);
+	strcpy(*name, name_buffer);
+	return 0;
+}
+
+/* This rather complex function must be called when you want to add an entry
+   to /proc/sys/dev/sensors/chips. It also creates a new directory within 
+   /proc/sys/dev/sensors/.
+   ctl_template should be a template of the newly created directory. It is
+   copied in memory. The extra2 field of each file is set to point to client.
+   If any driver wants subdirectories within the newly created directory,
+   this function must be updated! 
+   controlling_mod is the controlling module. It should usually be
+   THIS_MODULE when calling. Note that this symbol is not defined in
+   kernels before 2.3.13; define it to NULL in that case. We will not use it
+   for anything older than 2.3.27 anyway. */
+int i2c_register_entry(struct i2c_client *client, const char *prefix,
+			   ctl_table * ctl_template,
+			   struct module *controlling_mod)
+{
+	int i, res, len, id;
+	ctl_table *new_table;
+	char *name;
+	struct ctl_table_header *new_header;
+
+	if ((res = i2c_create_name(&name, prefix, client->adapter,
+				       client->addr))) return res;
+
+	for (id = 0; id < SENSORS_ENTRY_MAX; id++)
+		if (!i2c_entries[id]) {
+			break;
+		}
+	if (id == SENSORS_ENTRY_MAX) {
+		kfree(name);
+		return -ENOMEM;
+	}
+	id += 256;
+
+	len = 0;
+	while (ctl_template[len].procname)
+		len++;
+	len += 7;
+	if (!(new_table = kmalloc(sizeof(ctl_table) * len, GFP_KERNEL))) {
+		kfree(name);
+		return -ENOMEM;
+	}
+
+	memcpy(new_table, sysctl_table, 6 * sizeof(ctl_table));
+	new_table[0].child = &new_table[2];
+	new_table[2].child = &new_table[4];
+	new_table[4].child = &new_table[6];
+	new_table[4].procname = name;
+	new_table[4].ctl_name = id;
+	memcpy(new_table + 6, ctl_template, (len - 6) * sizeof(ctl_table));
+	for (i = 6; i < len; i++)
+		new_table[i].extra2 = client;
+
+	if (!(new_header = register_sysctl_table(new_table, 0))) {
+		kfree(new_table);
+		kfree(name);
+		return -ENOMEM;
+	}
+
+	i2c_entries[id - 256] = new_header;
+
+	i2c_clients[id - 256] = client;
+#ifdef DEBUG
+	if (!new_header || !new_header->ctl_table ||
+	    !new_header->ctl_table->child ||
+	    !new_header->ctl_table->child->child ||
+	    !new_header->ctl_table->child->child->de) {
+		printk
+		    ("i2c-proc.o: NULL pointer when trying to install fill_inode fix!\n");
+		return id;
+	}
+#endif				/* DEBUG */
+	i2c_inodes[id - 256] =
+	    new_header->ctl_table->child->child->de->low_ino;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27))
+	new_header->ctl_table->child->child->de->owner = controlling_mod;
+#else
+	new_header->ctl_table->child->child->de->fill_inode =
+	    &i2c_dir_fill_inode;
+#endif	/* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27)) */
+
+	return id;
+}
+
+void i2c_deregister_entry(int id)
+{
+	ctl_table *table;
+	char *temp;
+	id -= 256;
+	if (i2c_entries[id]) {
+		table = i2c_entries[id]->ctl_table;
+		unregister_sysctl_table(i2c_entries[id]);
+		/* 2-step kfree needed to keep gcc happy about const points */
+		(const char *) temp = table[4].procname;
+		kfree(temp);
+		kfree(table);
+		i2c_entries[id] = NULL;
+		i2c_clients[id] = NULL;
+	}
+}
+
+/* Monitor access for /proc/sys/dev/sensors; make unloading i2c-proc.o 
+   impossible if some process still uses it or some file in it */
+void i2c_fill_inode(struct inode *inode, int fill)
+{
+	if (fill)
+		MOD_INC_USE_COUNT;
+	else
+		MOD_DEC_USE_COUNT;
+}
+
+/* Monitor access for /proc/sys/dev/sensors/ directories; make unloading
+   the corresponding module impossible if some process still uses it or
+   some file in it */
+void i2c_dir_fill_inode(struct inode *inode, int fill)
+{
+	int i;
+	struct i2c_client *client;
+
+#ifdef DEBUG
+	if (!inode) {
+		printk("i2c-proc.o: Warning: inode NULL in fill_inode()\n");
+		return;
+	}
+#endif				/* def DEBUG */
+
+	for (i = 0; i < SENSORS_ENTRY_MAX; i++)
+		if (i2c_clients[i]
+		    && (i2c_inodes[i] == inode->i_ino)) break;
+#ifdef DEBUG
+	if (i == SENSORS_ENTRY_MAX) {
+		printk
+		    ("i2c-proc.o: Warning: inode (%ld) not found in fill_inode()\n",
+		     inode->i_ino);
+		return;
+	}
+#endif				/* def DEBUG */
+	client = i2c_clients[i];
+	if (fill)
+		client->driver->inc_use(client);
+	else
+		client->driver->dec_use(client);
+}
+
+int i2c_proc_chips(ctl_table * ctl, int write, struct file *filp,
+		       void *buffer, size_t * lenp)
+{
+	char BUF[SENSORS_PREFIX_MAX + 30];
+	int buflen, curbufsize, i;
+	struct ctl_table *client_tbl;
+
+	if (write)
+		return 0;
+
+	/* If buffer is size 0, or we try to read when not at the start, we
+	   return nothing. Note that I think writing when not at the start
+	   does not work either, but anyway, this is straight from the kernel
+	   sources. */
+	if (!*lenp || (filp->f_pos && !write)) {
+		*lenp = 0;
+		return 0;
+	}
+	curbufsize = 0;
+	for (i = 0; i < SENSORS_ENTRY_MAX; i++)
+		if (i2c_entries[i]) {
+			client_tbl =
+			    i2c_entries[i]->ctl_table->child->child;
+			buflen =
+			    sprintf(BUF, "%d\t%s\n", client_tbl->ctl_name,
+				    client_tbl->procname);
+			if (buflen + curbufsize > *lenp)
+				buflen = *lenp - curbufsize;
+			if(copy_to_user(buffer, BUF, buflen))
+				return -EFAULT;
+			curbufsize += buflen;
+			(char *) buffer += buflen;
+		}
+	*lenp = curbufsize;
+	filp->f_pos += curbufsize;
+	return 0;
+}
+
+int i2c_sysctl_chips(ctl_table * table, int *name, int nlen,
+			 void *oldval, size_t * oldlenp, void *newval,
+			 size_t newlen, void **context)
+{
+	struct i2c_chips_data data;
+	int i, oldlen, nrels, maxels,ret=0;
+	struct ctl_table *client_tbl;
+
+	if (oldval && oldlenp && !((ret = get_user(oldlen, oldlenp))) && 
+	    oldlen) {
+		maxels = oldlen / sizeof(struct i2c_chips_data);
+		nrels = 0;
+		for (i = 0; (i < SENSORS_ENTRY_MAX) && (nrels < maxels);
+		     i++)
+			if (i2c_entries[i]) {
+				client_tbl =
+				    i2c_entries[i]->ctl_table->child->
+				    child;
+				data.sysctl_id = client_tbl->ctl_name;
+				strcpy(data.name, client_tbl->procname);
+				if(copy_to_user(oldval, &data,
+					     sizeof(struct
+						    i2c_chips_data)))
+					return -EFAULT;
+				(char *) oldval +=
+				    sizeof(struct i2c_chips_data);
+				nrels++;
+			}
+		oldlen = nrels * sizeof(struct i2c_chips_data);
+		if(put_user(oldlen, oldlenp))
+			return -EFAULT;
+	}
+	return ret;
+}
+
+
+/* This funcion reads or writes a 'real' value (encoded by the combination
+   of an integer and a magnitude, the last is the power of ten the value
+   should be divided with) to a /proc/sys directory. To use this function,
+   you must (before registering the ctl_table) set the extra2 field to the
+   client, and the extra1 field to a function of the form:
+      void func(struct i2c_client *client, int operation, int ctl_name,
+                int *nrels_mag, long *results)
+   This function can be called for three values of operation. If operation
+   equals SENSORS_PROC_REAL_INFO, the magnitude should be returned in 
+   nrels_mag. If operation equals SENSORS_PROC_REAL_READ, values should
+   be read into results. nrels_mag should return the number of elements
+   read; the maximum number is put in it on entry. Finally, if operation
+   equals SENSORS_PROC_REAL_WRITE, the values in results should be
+   written to the chip. nrels_mag contains on entry the number of elements
+   found.
+   In all cases, client points to the client we wish to interact with,
+   and ctl_name is the SYSCTL id of the file we are accessing. */
+int i2c_proc_real(ctl_table * ctl, int write, struct file *filp,
+		      void *buffer, size_t * lenp)
+{
+#define MAX_RESULTS 32
+	int mag, nrels = MAX_RESULTS;
+	long results[MAX_RESULTS];
+	i2c_real_callback callback = ctl->extra1;
+	struct i2c_client *client = ctl->extra2;
+	int res;
+
+	/* If buffer is size 0, or we try to read when not at the start, we
+	   return nothing. Note that I think writing when not at the start
+	   does not work either, but anyway, this is straight from the kernel
+	   sources. */
+	if (!*lenp || (filp->f_pos && !write)) {
+		*lenp = 0;
+		return 0;
+	}
+
+	/* Get the magnitude */
+	callback(client, SENSORS_PROC_REAL_INFO, ctl->ctl_name, &mag,
+		 NULL);
+
+	if (write) {
+		/* Read the complete input into results, converting to longs */
+		res = i2c_parse_reals(&nrels, buffer, *lenp, results, mag);
+		if (res)
+			return res;
+
+		if (!nrels)
+			return 0;
+
+		/* Now feed this information back to the client */
+		callback(client, SENSORS_PROC_REAL_WRITE, ctl->ctl_name,
+			 &nrels, results);
+
+		filp->f_pos += *lenp;
+		return 0;
+	} else {		/* read */
+		/* Get the information from the client into results */
+		callback(client, SENSORS_PROC_REAL_READ, ctl->ctl_name,
+			 &nrels, results);
+
+		/* And write them to buffer, converting to reals */
+		res = i2c_write_reals(nrels, buffer, lenp, results, mag);
+		if (res)
+			return res;
+		filp->f_pos += *lenp;
+		return 0;
+	}
+}
+
+/* This function is equivalent to i2c_proc_real, only it interacts with
+   the sysctl(2) syscall, and returns no reals, but integers */
+int i2c_sysctl_real(ctl_table * table, int *name, int nlen,
+			void *oldval, size_t * oldlenp, void *newval,
+			size_t newlen, void **context)
+{
+	long results[MAX_RESULTS];
+	int oldlen, nrels = MAX_RESULTS,ret=0;
+	i2c_real_callback callback = table->extra1;
+	struct i2c_client *client = table->extra2;
+
+	/* Check if we need to output the old values */
+	if (oldval && oldlenp && !((ret=get_user(oldlen, oldlenp))) && oldlen) {
+		callback(client, SENSORS_PROC_REAL_READ, table->ctl_name,
+			 &nrels, results);
+
+		/* Note the rounding factor! */
+		if (nrels * sizeof(long) < oldlen)
+			oldlen = nrels * sizeof(long);
+		oldlen = (oldlen / sizeof(long)) * sizeof(long);
+		if(copy_to_user(oldval, results, oldlen))
+			return -EFAULT;
+		if(put_user(oldlen, oldlenp))
+			return -EFAULT;
+	}
+
+	if (newval && newlen) {
+		/* Note the rounding factor! */
+		newlen -= newlen % sizeof(long);
+		nrels = newlen / sizeof(long);
+		if(copy_from_user(results, newval, newlen))
+			return -EFAULT;
+
+		/* Get the new values back to the client */
+		callback(client, SENSORS_PROC_REAL_WRITE, table->ctl_name,
+			 &nrels, results);
+	}
+	return ret;
+}
+
+
+/* nrels contains initially the maximum number of elements which can be
+   put in results, and finally the number of elements actually put there.
+   A magnitude of 1 will multiply everything with 10; etc.
+   buffer, bufsize is the character buffer we read from and its length.
+   results will finally contain the parsed integers. 
+
+   Buffer should contain several reals, separated by whitespace. A real
+   has the following syntax:
+     [ Minus ] Digit* [ Dot Digit* ] 
+   (everything between [] is optional; * means zero or more).
+   When the next character is unparsable, everything is skipped until the
+   next whitespace.
+
+   WARNING! This is tricky code. I have tested it, but there may still be
+            hidden bugs in it, even leading to crashes and things!
+*/
+int i2c_parse_reals(int *nrels, void *buffer, int bufsize,
+			 long *results, int magnitude)
+{
+	int maxels, min, mag;
+	long res,ret=0;
+	char nextchar = 0;
+
+	maxels = *nrels;
+	*nrels = 0;
+
+	while (bufsize && (*nrels < maxels)) {
+
+		/* Skip spaces at the start */
+		while (bufsize && 
+		       !((ret=get_user(nextchar, (char *) buffer))) &&
+		       isspace((int) nextchar)) {
+			bufsize--;
+			((char *) buffer)++;
+		}
+
+		if (ret)
+			return -EFAULT;	
+		/* Well, we may be done now */
+		if (!bufsize)
+			return 0;
+
+		/* New defaults for our result */
+		min = 0;
+		res = 0;
+		mag = magnitude;
+
+		/* Check for a minus */
+		if (!((ret=get_user(nextchar, (char *) buffer)))
+		    && (nextchar == '-')) {
+			min = 1;
+			bufsize--;
+			((char *) buffer)++;
+		}
+		if (ret)
+			return -EFAULT;
+
+		/* Digits before a decimal dot */
+		while (bufsize && 
+		       !((ret=get_user(nextchar, (char *) buffer))) &&
+		       isdigit((int) nextchar)) {
+			res = res * 10 + nextchar - '0';
+			bufsize--;
+			((char *) buffer)++;
+		}
+		if (ret)
+			return -EFAULT;
+
+		/* If mag < 0, we must actually divide here! */
+		while (mag < 0) {
+			res = res / 10;
+			mag++;
+		}
+
+		if (bufsize && (nextchar == '.')) {
+			/* Skip the dot */
+			bufsize--;
+			((char *) buffer)++;
+
+			/* Read digits while they are significant */
+			while (bufsize && (mag > 0) &&
+			       !((ret=get_user(nextchar, (char *) buffer))) &&
+			       isdigit((int) nextchar)) {
+				res = res * 10 + nextchar - '0';
+				mag--;
+				bufsize--;
+				((char *) buffer)++;
+			}
+			if (ret)
+				return -EFAULT;
+		}
+		/* If we are out of data, but mag > 0, we need to scale here */
+		while (mag > 0) {
+			res = res * 10;
+			mag--;
+		}
+
+		/* Skip everything until we hit whitespace */
+		while (bufsize && 
+		       !((ret=get_user(nextchar, (char *) buffer))) &&
+		       isspace((int) nextchar)) {
+			bufsize--;
+			((char *) buffer)++;
+		}
+		if (ret)
+			return -EFAULT;
+
+		/* Put res in results */
+		results[*nrels] = (min ? -1 : 1) * res;
+		(*nrels)++;
+	}
+
+	/* Well, there may be more in the buffer, but we need no more data. 
+	   Ignore anything that is left. */
+	return 0;
+}
+
+int i2c_write_reals(int nrels, void *buffer, int *bufsize,
+			 long *results, int magnitude)
+{
+#define BUFLEN 20
+	char BUF[BUFLEN + 1];	/* An individual representation should fit! */
+	char printfstr[10];
+	int nr = 0;
+	int buflen, mag, times;
+	int curbufsize = 0;
+
+	while ((nr < nrels) && (curbufsize < *bufsize)) {
+		mag = magnitude;
+
+		if (nr != 0) {
+			if(put_user(' ', (char *) buffer))
+				return -EFAULT;
+			curbufsize++;
+			((char *) buffer)++;
+		}
+
+		/* Fill BUF with the representation of the next string */
+		if (mag <= 0) {
+			buflen = sprintf(BUF, "%ld", results[nr]);
+			if (buflen < 0) {	/* Oops, a sprintf error! */
+				*bufsize = 0;
+				return -EINVAL;
+			}
+			while ((mag < 0) && (buflen < BUFLEN)) {
+				BUF[buflen++] = '0';
+				mag++;
+			}
+			BUF[buflen] = 0;
+		} else {
+			times = 1;
+			for (times = 1; mag-- > 0; times *= 10);
+			if (results[nr] < 0) {
+				BUF[0] = '-';
+				buflen = 1;
+			} else
+				buflen = 0;
+			strcpy(printfstr, "%ld.%0Xld");
+			printfstr[6] = magnitude + '0';
+			buflen +=
+			    sprintf(BUF + buflen, printfstr,
+				    abs(results[nr]) / times,
+				    abs(results[nr]) % times);
+			if (buflen < 0) {	/* Oops, a sprintf error! */
+				*bufsize = 0;
+				return -EINVAL;
+			}
+		}
+
+		/* Now copy it to the user-space buffer */
+		if (buflen + curbufsize > *bufsize)
+			buflen = *bufsize - curbufsize;
+		if(copy_to_user(buffer, BUF, buflen))
+			return -EFAULT;
+		curbufsize += buflen;
+		(char *) buffer += buflen;
+
+		nr++;
+	}
+	if (curbufsize < *bufsize) {
+		if(put_user('\n', (char *) buffer))
+			return -EFAULT;
+		curbufsize++;
+	}
+	*bufsize = curbufsize;
+	return 0;
+}
+
+
+/* Very inefficient for ISA detects, and won't work for 10-bit addresses! */
+int i2c_detect(struct i2c_adapter *adapter,
+		   struct i2c_address_data *address_data,
+		   i2c_found_addr_proc * found_proc)
+{
+	int addr, i, found, j, err;
+	struct i2c_force_data *this_force;
+	int is_isa = i2c_is_isa_adapter(adapter);
+	int adapter_id =
+	    is_isa ? SENSORS_ISA_BUS : i2c_adapter_id(adapter);
+
+	/* Forget it if we can't probe using SMBUS_QUICK */
+	if ((!is_isa)
+	    && !i2c_check_functionality(adapter,
+					I2C_FUNC_SMBUS_QUICK)) return -1;
+
+	for (addr = 0x00; addr <= (is_isa ? 0xffff : 0x7f); addr++) {
+		if ((is_isa && check_region(addr, 1)) ||
+		    (!is_isa && i2c_check_addr(adapter, addr)))
+			continue;
+
+		/* If it is in one of the force entries, we don't do any
+		   detection at all */
+		found = 0;
+		for (i = 0;
+		     !found
+		     && (this_force =
+			 address_data->forces + i, this_force->force); i++) {
+			for (j = 0;
+			     !found
+			     && (this_force->force[j] != SENSORS_I2C_END);
+			     j += 2) {
+				if (
+				    ((adapter_id == this_force->force[j])
+				     ||
+				     ((this_force->
+				       force[j] == SENSORS_ANY_I2C_BUS)
+				      && !is_isa))
+				    && (addr == this_force->force[j + 1])) {
+#ifdef DEBUG
+					printk
+					    ("i2c-proc.o: found force parameter for adapter %d, addr %04x\n",
+					     adapter_id, addr);
+#endif
+					if (
+					    (err =
+					     found_proc(adapter, addr, 0,
+							this_force->
+							kind))) return err;
+					found = 1;
+				}
+			}
+		}
+		if (found)
+			continue;
+
+		/* If this address is in one of the ignores, we can forget about it
+		   right now */
+		for (i = 0;
+		     !found
+		     && (address_data->ignore[i] != SENSORS_I2C_END);
+		     i += 2) {
+			if (
+			    ((adapter_id == address_data->ignore[i])
+			     ||
+			     ((address_data->
+			       ignore[i] == SENSORS_ANY_I2C_BUS)
+			      && !is_isa))
+			    && (addr == address_data->ignore[i + 1])) {
+#ifdef DEBUG
+				printk
+				    ("i2c-proc.o: found ignore parameter for adapter %d, "
+				     "addr %04x\n", adapter_id, addr);
+#endif
+				found = 1;
+			}
+		}
+		for (i = 0;
+		     !found
+		     && (address_data->ignore_range[i] != SENSORS_I2C_END);
+		     i += 3) {
+			if (
+			    ((adapter_id == address_data->ignore_range[i])
+			     ||
+			     ((address_data->
+			       ignore_range[i] ==
+			       SENSORS_ANY_I2C_BUS) & !is_isa))
+			    && (addr >= address_data->ignore_range[i + 1])
+			    && (addr <= address_data->ignore_range[i + 2])) {
+#ifdef DEBUG
+				printk
+				    ("i2c-proc.o: found ignore_range parameter for adapter %d, "
+				     "addr %04x\n", adapter_id, addr);
+#endif
+				found = 1;
+			}
+		}
+		if (found)
+			continue;
+
+		/* Now, we will do a detection, but only if it is in the normal or 
+		   probe entries */
+		if (is_isa) {
+			for (i = 0;
+			     !found
+			     && (address_data->normal_isa[i] !=
+				 SENSORS_ISA_END); i += 1) {
+				if (addr == address_data->normal_isa[i]) {
+#ifdef DEBUG
+					printk
+					    ("i2c-proc.o: found normal isa entry for adapter %d, "
+					     "addr %04x\n", adapter_id,
+					     addr);
+#endif
+					found = 1;
+				}
+			}
+			for (i = 0;
+			     !found
+			     && (address_data->normal_isa_range[i] !=
+				 SENSORS_ISA_END); i += 3) {
+				if ((addr >=
+				     address_data->normal_isa_range[i])
+				    && (addr <=
+					address_data->normal_isa_range[i + 1])
+				    &&
+				    ((addr -
+				      address_data->normal_isa_range[i]) %
+				     address_data->normal_isa_range[i + 2] ==
+				     0)) {
+#ifdef DEBUG
+					printk
+					    ("i2c-proc.o: found normal isa_range entry for adapter %d, "
+					     "addr %04x", adapter_id, addr);
+#endif
+					found = 1;
+				}
+			}
+		} else {
+			for (i = 0;
+			     !found && (address_data->normal_i2c[i] !=
+				 SENSORS_I2C_END); i += 1) {
+				if (addr == address_data->normal_i2c[i]) {
+					found = 1;
+#ifdef DEBUG
+					printk
+					    ("i2c-proc.o: found normal i2c entry for adapter %d, "
+					     "addr %02x", adapter_id, addr);
+#endif
+				}
+			}
+			for (i = 0;
+			     !found
+			     && (address_data->normal_i2c_range[i] !=
+				 SENSORS_I2C_END); i += 2) {
+				if ((addr >=
+				     address_data->normal_i2c_range[i])
+				    && (addr <=
+					address_data->normal_i2c_range[i + 1]))
+				{
+#ifdef DEBUG
+					printk
+					    ("i2c-proc.o: found normal i2c_range entry for adapter %d, "
+					     "addr %04x\n", adapter_id, addr);
+#endif
+					found = 1;
+				}
+			}
+		}
+
+		for (i = 0;
+		     !found && (address_data->probe[i] != SENSORS_I2C_END);
+		     i += 2) {
+			if (((adapter_id == address_data->probe[i]) ||
+			     ((address_data->
+			       probe[i] == SENSORS_ANY_I2C_BUS) & !is_isa))
+			    && (addr == address_data->probe[i + 1])) {
+#ifdef DEBUG
+				printk
+				    ("i2c-proc.o: found probe parameter for adapter %d, "
+				     "addr %04x\n", adapter_id, addr);
+#endif
+				found = 1;
+			}
+		}
+		for (i = 0; !found &&
+		           (address_data->probe_range[i] != SENSORS_I2C_END);
+		     i += 3) {
+			if (
+			    ((adapter_id == address_data->probe_range[i])
+			     ||
+			     ((address_data->probe_range[i] ==
+			       SENSORS_ANY_I2C_BUS) & !is_isa))
+			    && (addr >= address_data->probe_range[i + 1])
+			    && (addr <= address_data->probe_range[i + 2])) {
+				found = 1;
+#ifdef DEBUG
+				printk
+				    ("i2c-proc.o: found probe_range parameter for adapter %d, "
+				     "addr %04x\n", adapter_id, addr);
+#endif
+			}
+		}
+		if (!found)
+			continue;
+
+		/* OK, so we really should examine this address. First check
+		   whether there is some client here at all! */
+		if (is_isa ||
+		    (i2c_smbus_xfer
+		     (adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL) >= 0))
+			if ((err = found_proc(adapter, addr, 0, -1)))
+				return err;
+	}
+	return 0;
+}
+
+int __init sensors_init(void)
+{
+	printk("i2c-proc.o version %s (%s)\n", LM_VERSION, LM_DATE);
+	i2c_initialized = 0;
+	if (!
+	    (i2c_proc_header =
+	     register_sysctl_table(i2c_proc, 0))) return -ENOMEM;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,1))
+	i2c_proc_header->ctl_table->child->de->owner = THIS_MODULE;
+#else
+	i2c_proc_header->ctl_table->child->de->fill_inode =
+	    &i2c_fill_inode;
+#endif			/* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,1)) */
+	i2c_initialized++;
+	return 0;
+}
+
+EXPORT_SYMBOL(i2c_deregister_entry);
+EXPORT_SYMBOL(i2c_detect);
+EXPORT_SYMBOL(i2c_proc_real);
+EXPORT_SYMBOL(i2c_register_entry);
+EXPORT_SYMBOL(i2c_sysctl_real);
+
+#ifdef MODULE
+
+MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
+MODULE_DESCRIPTION("i2c-proc driver");
+MODULE_LICENSE("GPL");
+
+int i2c_cleanup(void)
+{
+	if (i2c_initialized >= 1) {
+		unregister_sysctl_table(i2c_proc_header);
+		i2c_initialized--;
+	}
+	return 0;
+}
+
+int init_module(void)
+{
+	return sensors_init();
+}
+
+int cleanup_module(void)
+{
+	return i2c_cleanup();
+}
+#endif				/* MODULE */
diff -u --recursive --new-file v2.4.12/linux/drivers/i2c/i2c-velleman.c linux/drivers/i2c/i2c-velleman.c
--- v2.4.12/linux/drivers/i2c/i2c-velleman.c	Tue Oct  9 17:06:51 2001
+++ linux/drivers/i2c/i2c-velleman.c	Thu Oct 11 08:05:47 2001
@@ -103,7 +103,7 @@
 	return 0;
 }
 
-static void bit_velle_exit(void)
+static void __exit bit_velle_exit(void)
 {	
 	release_region( base , (base == 0x3bc)? 3 : 8 );
 }
diff -u --recursive --new-file v2.4.12/linux/drivers/ide/hptraid.c linux/drivers/ide/hptraid.c
--- v2.4.12/linux/drivers/ide/hptraid.c	Tue Oct  9 17:06:51 2001
+++ linux/drivers/ide/hptraid.c	Thu Oct 11 09:43:29 2001
@@ -15,6 +15,8 @@
    Based on work
    	Copyleft  (C) 2001 by Wilfried Weissmann <wweissmann@gmx.at>
 	Copyright (C) 1994-96 Marc ZYNGIER <zyngier@ufr-info-p7.ibp.fr>
+   Based on work done by Søren Schmidt for FreeBSD
+
    
 */
 
diff -u --recursive --new-file v2.4.12/linux/drivers/ide/hptraid.h linux/drivers/ide/hptraid.h
--- v2.4.12/linux/drivers/ide/hptraid.h	Sun Sep 23 11:40:57 2001
+++ linux/drivers/ide/hptraid.h	Thu Oct 11 09:43:29 2001
@@ -1,4 +1,32 @@
-
+/*-
+ * Copyright (c) 2000,2001 Søren Schmidt <sos@FreeBSD.org>
+ * 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, immediately at the beginning of the file.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `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 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 OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+                            
 struct highpoint_raid_conf
 {
        int8_t  filler1[32];
diff -u --recursive --new-file v2.4.12/linux/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
--- v2.4.12/linux/drivers/ide/ide-disk.c	Tue Oct  9 17:06:51 2001
+++ linux/drivers/ide/ide-disk.c	Thu Oct 11 09:14:32 2001
@@ -890,3 +890,4 @@
 
 module_init(idedisk_init);
 module_exit(idedisk_exit);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/ide/ide-floppy.c linux/drivers/ide/ide-floppy.c
--- v2.4.12/linux/drivers/ide/ide-floppy.c	Tue Oct  9 17:06:51 2001
+++ linux/drivers/ide/ide-floppy.c	Thu Oct 11 09:14:32 2001
@@ -2116,3 +2116,4 @@
 
 module_init(idefloppy_init);
 module_exit(idefloppy_exit);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/ide/ide-probe.c linux/drivers/ide/ide-probe.c
--- v2.4.12/linux/drivers/ide/ide-probe.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/ide/ide-probe.c	Thu Oct 11 09:14:32 2001
@@ -928,4 +928,5 @@
 {
 	ide_probe = NULL;
 }
+MODULE_LICENSE("GPL");
 #endif /* MODULE */
diff -u --recursive --new-file v2.4.12/linux/drivers/ide/ide.c linux/drivers/ide/ide.c
--- v2.4.12/linux/drivers/ide/ide.c	Tue Oct  9 17:06:51 2001
+++ linux/drivers/ide/ide.c	Thu Oct 11 09:14:32 2001
@@ -3749,6 +3749,7 @@
 #ifdef MODULE
 char *options = NULL;
 MODULE_PARM(options,"s");
+MODULE_LICENSE("GPL");
 
 static void __init parse_options (char *line)
 {
diff -u --recursive --new-file v2.4.12/linux/drivers/ide/rapide.c linux/drivers/ide/rapide.c
--- v2.4.12/linux/drivers/ide/rapide.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/ide/rapide.c	Thu Oct 11 09:14:32 2001
@@ -69,6 +69,7 @@
 }
 
 #ifdef MODULE
+MODULE_LICENSE("GPL");
 
 int init_module (void)
 {
diff -u --recursive --new-file v2.4.12/linux/drivers/input/keybdev.c linux/drivers/input/keybdev.c
--- v2.4.12/linux/drivers/input/keybdev.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/input/keybdev.c	Thu Oct 11 09:14:32 2001
@@ -246,3 +246,4 @@
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
 MODULE_DESCRIPTION("Input driver to keyboard driver binding");
 MODULE_PARM(jp_kbd_109, "i");
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/media/video/bw-qcam.c linux/drivers/media/video/bw-qcam.c
--- v2.4.12/linux/drivers/media/video/bw-qcam.c	Tue Oct  9 17:06:51 2001
+++ linux/drivers/media/video/bw-qcam.c	Thu Oct 11 09:14:32 2001
@@ -1,8 +1,6 @@
 /*
  *    QuickCam Driver For Video4Linux.
  *
- *	This version only works as a module.
- *
  *	Video4Linux conversion work by Alan Cox.
  *	Parport compatibility by Phil Blundell.
  *	Busy loop avoidance by Mark Cooke.
@@ -991,11 +989,20 @@
 MODULE_PARM(parport, "1-" __MODULE_STRING(MAX_CAMS) "s");
 #endif
 
-#ifdef MODULE
-int init_module(void)
+static void __exit exit_bw_qcams(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < num_cams; i++)
+		close_bwqcam(qcams[i]);
+}
+
+static int __init init_bw_qcams(void)
 {
 	struct parport *port;
+#ifdef MODULE
 	int n;
+	
 	if(parport[0] && strncmp(parport[0], "auto", 4)){
 		/* user gave parport parameters */
 		for(n=0; parport[n] && n<MAX_CAMS; n++){
@@ -1033,22 +1040,14 @@
 	}
 
 	return (num_cams)?0:-ENODEV;
-}
-
-void cleanup_module(void)
-{
-	unsigned int i;
-	for (i = 0; i < num_cams; i++)
-		close_bwqcam(qcams[i]);
-}
 #else
-int __init init_bw_qcams(struct video_init *unused)
-{
-	struct parport *port;
-
 	for (port = parport_enumerate(); port; port=port->next)
 		init_bwqcam(port);
 	return 0;
-}
 #endif
+}
+
+module_init(init_bw_qcams);
+module_exit(exit_bw_qcams);
+
 MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/media/video/planb.c linux/drivers/media/video/planb.c
--- v2.4.12/linux/drivers/media/video/planb.c	Tue Oct  9 17:06:51 2001
+++ linux/drivers/media/video/planb.c	Thu Oct 11 09:14:32 2001
@@ -55,12 +55,18 @@
 #include "planb.h"
 #include "saa7196.h"
 
-
 /* Would you mind for some ugly debugging? */
-//#define DEBUG(x...) printk(KERN_DEBUG ## x) /* Debug driver */
-#define DEBUG(x...) 		/* Don't debug driver */	
-//#define IDEBUG(x...) printk(KERN_DEBUG ## x) /* Debug interrupt part */
+#if 0
+#define DEBUG(x...) printk(KERN_DEBUG ## x) /* Debug driver */
+#else
+#define DEBUG(x...) 		/* Don't debug driver */
+#endif
+
+#if 0
+#define IDEBUG(x...) printk(KERN_DEBUG ## x) /* Debug interrupt part */
+#endif
 #define IDEBUG(x...) 		/* Don't debug interrupt part */
+#endif
 
 /* Ever seen a Mac with more than 1 of these? */
 #define PLANB_MAX 1
@@ -2271,14 +2277,8 @@
 	}
 }
 
-#ifdef MODULE
-
-int init_module(void)
-{
-#else
-int __init init_planbs(struct video_init *unused)
+static int __init init_planbs(void)
 {
-#endif
 	int i;
   
 	if (find_planb()<=0)
@@ -2296,11 +2296,10 @@
 	return 0;
 }
 
-#ifdef MODULE
-
-void cleanup_module(void)
+static void __exit exit_planbs(void)
 {
 	release_planb();
 }
 
-#endif
+module_init(init_planbs);
+module_exit(exit_planbs);
diff -u --recursive --new-file v2.4.12/linux/drivers/media/video/saa7110.c linux/drivers/media/video/saa7110.c
--- v2.4.12/linux/drivers/media/video/saa7110.c	Tue Oct  9 17:06:51 2001
+++ linux/drivers/media/video/saa7110.c	Thu Oct 11 09:14:32 2001
@@ -306,7 +306,7 @@
 				saa7110_write(decoder, 0x0D, 0x06);
 				saa7110_write(decoder, 0x11, 0x2C);
 				saa7110_write(decoder, 0x30, 0x81);
-saa7110_write(decoder, 0x2A, 0xDF);
+				saa7110_write(decoder, 0x2A, 0xDF);
 				break;
 			 case VIDEO_MODE_PAL:
 				saa7110_write(decoder, 0x0D, 0x06);
diff -u --recursive --new-file v2.4.12/linux/drivers/media/video/videodev.c linux/drivers/media/video/videodev.c
--- v2.4.12/linux/drivers/media/video/videodev.c	Tue Oct  9 17:06:51 2001
+++ linux/drivers/media/video/videodev.c	Thu Oct 11 09:14:32 2001
@@ -63,29 +63,6 @@
 #endif /* CONFIG_PROC_FS && CONFIG_VIDEO_PROC_FS */
 
 
-#ifdef CONFIG_VIDEO_BWQCAM
-extern int init_bw_qcams(struct video_init *);
-#endif
-#ifdef CONFIG_VIDEO_CPIA
-extern int cpia_init(struct video_init *);
-#endif
-#ifdef CONFIG_VIDEO_PLANB
-extern int init_planbs(struct video_init *);
-#endif
-
-static struct video_init video_init_list[]={
-#ifdef CONFIG_VIDEO_BWQCAM
-	{"bw-qcam", init_bw_qcams},
-#endif	
-#ifdef CONFIG_VIDEO_CPIA
-	{"cpia", cpia_init},
-#endif	
-#ifdef CONFIG_VIDEO_PLANB
-	{"planb", init_planbs},
-#endif
-	{"end", NULL}
-};
-
 /*
  *	Read will do some smarts later on. Buffer pin etc.
  */
@@ -118,7 +95,7 @@
 
 /*
  *	Poll to see if we're readable, can probably be used for timing on incoming
- *  frames, etc..
+ *	frames, etc..
  */
 
 static unsigned int video_poll(struct file *file, poll_table * wait)
@@ -222,8 +199,7 @@
 /*
  *	We need to do MMAP support
  */
- 
- 
+  
 int video_mmap(struct file *file, struct vm_area_struct *vma)
 {
 	int ret = -EINVAL;
@@ -548,8 +524,6 @@
  
 static int __init videodev_init(void)
 {
-	struct video_init *vfli = video_init_list;
-	
 	printk(KERN_INFO "Linux video capture interface: v1.00\n");
 	if(devfs_register_chrdev(VIDEO_MAJOR,"video_capture", &video_fops))
 	{
@@ -557,19 +531,10 @@
 		return -EIO;
 	}
 
-	/*
-	 *	Init kernel installed video drivers
-	 */
-	 	
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
 	videodev_proc_create ();
 #endif
 	
-	while(vfli->init!=NULL)
-	{
-		vfli->init(vfli);
-		vfli++;
-	}
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.12/linux/drivers/message/fusion/isense.c linux/drivers/message/fusion/isense.c
--- v2.4.12/linux/drivers/message/fusion/isense.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/message/fusion/isense.c	Thu Oct 11 09:14:32 2001
@@ -87,6 +87,7 @@
 EXPORT_NO_SYMBOLS;
 MODULE_AUTHOR(MODULEAUTHOR);
 MODULE_DESCRIPTION(my_NAME);
+MODULE_LICENSE("GPL");
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 int __init isense_init(void)
diff -u --recursive --new-file v2.4.12/linux/drivers/mtd/Config.in linux/drivers/mtd/Config.in
--- v2.4.12/linux/drivers/mtd/Config.in	Tue Oct  9 17:06:51 2001
+++ linux/drivers/mtd/Config.in	Thu Oct 11 09:14:32 2001
@@ -13,10 +13,10 @@
    fi
    dep_tristate '  MTD partitioning support' CONFIG_MTD_PARTITIONS $CONFIG_MTD
    dep_tristate '  RedBoot partition table parsing' CONFIG_MTD_REDBOOT_PARTS $CONFIG_MTD_PARTITIONS
-if [ "$CONFIG_ARM" = "y" ]; then
-   dep_tristate '  Compaq bootldr partition table parsing' CONFIG_MTD_BOOTLDR_PARTS $CONFIG_MTD_PARTITIONS
-   dep_tristate '  ARM Firmware Suite partition parsing' CONFIG_MTD_AFS_PARTS $CONFIG_MTD_PARTITIONS
-fi
+   if [ "$CONFIG_ARM" = "y" ]; then
+      dep_tristate '  Compaq bootldr partition table parsing' CONFIG_MTD_BOOTLDR_PARTS $CONFIG_MTD_PARTITIONS
+      dep_tristate '  ARM Firmware Suite partition parsing' CONFIG_MTD_AFS_PARTS $CONFIG_MTD_PARTITIONS
+   fi
 
 comment 'User Modules And Translation Layers'
    dep_tristate '  Direct char device access to MTD devices' CONFIG_MTD_CHAR $CONFIG_MTD
diff -u --recursive --new-file v2.4.12/linux/drivers/net/Config.in linux/drivers/net/Config.in
--- v2.4.12/linux/drivers/net/Config.in	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/Config.in	Thu Oct 11 09:18:31 2001
@@ -191,7 +191,7 @@
       if [ "$CONFIG_OBSOLETE" = "y" ]; then
 	 dep_bool '    Zenith Z-Note support (EXPERIMENTAL)' CONFIG_ZNET $CONFIG_ISA
       fi
-      if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_MIPS" = "y" ]; then
 	 bool '    Philips SAA9730 Ethernet support (EXPERIMENTAL)' CONFIG_LAN_SAA9730
       fi
    fi
diff -u --recursive --new-file v2.4.12/linux/drivers/net/ppp_generic.c linux/drivers/net/ppp_generic.c
--- v2.4.12/linux/drivers/net/ppp_generic.c	Tue Oct  9 17:06:52 2001
+++ linux/drivers/net/ppp_generic.c	Thu Oct 11 09:18:31 2001
@@ -2481,3 +2481,4 @@
 EXPORT_SYMBOL(ppp_unregister_compressor);
 EXPORT_SYMBOL(all_ppp_units); /* for debugging */
 EXPORT_SYMBOL(all_channels); /* for debugging */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/net/ppp_synctty.c linux/drivers/net/ppp_synctty.c
--- v2.4.12/linux/drivers/net/ppp_synctty.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/ppp_synctty.c	Thu Oct 11 11:17:22 2001
@@ -44,13 +44,6 @@
 #include <linux/init.h>
 #include <asm/uaccess.h>
 
-#ifndef spin_trylock_bh
-#define spin_trylock_bh(lock)	({ int __r; local_bh_disable();	\
-				   __r = spin_trylock(lock);	\
-				   if (!__r) local_bh_enable();	\
-				   __r; })
-#endif
-
 #define PPP_VERSION	"2.4.1"
 
 /* Structure for storing local state. */
@@ -708,3 +701,4 @@
 
 module_init(ppp_sync_init);
 module_exit(ppp_sync_cleanup);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/nubus/nubus_syms.c linux/drivers/nubus/nubus_syms.c
--- v2.4.12/linux/drivers/nubus/nubus_syms.c	Sat Sep  4 13:08:32 1999
+++ linux/drivers/nubus/nubus_syms.c	Thu Oct 11 09:18:31 2001
@@ -12,6 +12,8 @@
 EXPORT_SYMBOL(nubus_proc_detach_device);
 #endif
 
+MODULE_LICENSE("GPL");
+
 EXPORT_SYMBOL(nubus_find_device);
 EXPORT_SYMBOL(nubus_find_type);
 EXPORT_SYMBOL(nubus_find_slot);
diff -u --recursive --new-file v2.4.12/linux/drivers/parport/ieee1284_ops.c linux/drivers/parport/ieee1284_ops.c
--- v2.4.12/linux/drivers/parport/ieee1284_ops.c	Thu Oct 11 08:02:26 2001
+++ linux/drivers/parport/ieee1284_ops.c	Thu Oct 11 07:53:24 2001
@@ -362,7 +362,7 @@
 	} else {
 		DPRINTK (KERN_DEBUG "%s: ECP direction: failed to reverse\n",
 			 port->name);
-		port->ieee1284.phase = IEEE1284_PH_DIR_UNKNOWN;
+		port->ieee1284.phase = IEEE1284_PH_ECP_DIR_UNKNOWN;
 	}
 
 	return retval;
@@ -394,7 +394,7 @@
 		DPRINTK (KERN_DEBUG
 			 "%s: ECP direction: failed to switch forward\n",
 			 port->name);
-		port->ieee1284.phase = IEEE1284_PH_DIR_UNKNOWN;
+		port->ieee1284.phase = IEEE1284_PH_ECP_DIR_UNKNOWN;
 	}
 
 
diff -u --recursive --new-file v2.4.12/linux/drivers/parport/parport_amiga.c linux/drivers/parport/parport_amiga.c
--- v2.4.12/linux/drivers/parport/parport_amiga.c	Tue May 22 19:54:04 2001
+++ linux/drivers/parport/parport_amiga.c	Thu Oct 11 09:18:31 2001
@@ -298,6 +298,7 @@
 MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>");
 MODULE_DESCRIPTION("Parport Driver for Amiga builtin Port");
 MODULE_SUPPORTED_DEVICE("Amiga builtin Parallel Port");
+MODULE_LICENSE("GPL");
 
 module_init(parport_amiga_init)
 module_exit(parport_amiga_exit)
diff -u --recursive --new-file v2.4.12/linux/drivers/parport/parport_atari.c linux/drivers/parport/parport_atari.c
--- v2.4.12/linux/drivers/parport/parport_atari.c	Mon Nov 27 17:11:26 2000
+++ linux/drivers/parport/parport_atari.c	Thu Oct 11 09:18:31 2001
@@ -249,6 +249,7 @@
 MODULE_AUTHOR("Andreas Schwab");
 MODULE_DESCRIPTION("Parport Driver for Atari builtin Port");
 MODULE_SUPPORTED_DEVICE("Atari builtin Parallel Port");
+MODULE_LICENSE("GPL");
 
 int
 init_module(void)
diff -u --recursive --new-file v2.4.12/linux/drivers/parport/parport_pc.c linux/drivers/parport/parport_pc.c
--- v2.4.12/linux/drivers/parport/parport_pc.c	Thu Oct 11 08:02:26 2001
+++ linux/drivers/parport/parport_pc.c	Thu Oct 11 09:18:31 2001
@@ -2884,6 +2884,8 @@
 
 MODULE_AUTHOR("Phil Blundell, Tim Waugh, others");
 MODULE_DESCRIPTION("PC-style parallel port driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM_DESC(io, "Base I/O address (SPP regs)");
 MODULE_PARM(io, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "i");
 MODULE_PARM_DESC(io_hi, "Base I/O address (ECR)");
diff -u --recursive --new-file v2.4.12/linux/drivers/pci/gen-devlist.c linux/drivers/pci/gen-devlist.c
--- v2.4.12/linux/drivers/pci/gen-devlist.c	Mon Oct 16 12:56:50 2000
+++ linux/drivers/pci/gen-devlist.c	Thu Oct 11 09:18:31 2001
@@ -68,6 +68,7 @@
 							bra[-1] = 0;
 						if (vendor_len + strlen(c) + 1 > MAX_NAME_SIZE) {
 							fprintf(stderr, "Line %d: Device name too long\n", lino);
+							fprintf(stderr, "%s\n", c);
 							return 1;
 						}
 					}
diff -u --recursive --new-file v2.4.12/linux/drivers/pci/pci.ids linux/drivers/pci/pci.ids
--- v2.4.12/linux/drivers/pci/pci.ids	Tue Oct  9 17:06:52 2001
+++ linux/drivers/pci/pci.ids	Thu Oct 11 09:18:32 2001
@@ -3107,34 +3107,104 @@
 	0396  SDRAM controller
 	0397  BIOS scratchpad
 127a  Rockwell International
-	1002  HCF 56k V90 FaxModem
-		127a 1002  HCF 56k V90 Modem
-	1003  HCF 56k V90 FaxModem
-		127a 1003  PCI56RX Modem
-		13df 1003  PCI56RX Modem
-	1004  HCF 56k V90 FaxModem
-	1005  HCF 56k V90 FaxModem
-		122d 4008  MDP3858SP-A SVD Modem
-		127a 1005  PCI56RVP Modem 
-		13df 1005  PCI56RVP Modem 
-		1436 1005  WS-5614PS3G
-	1025  HCF 56k PCI Modem
-		127a 1025  HCF 56k PCI Modem
+	1002  HCF 56k Data/Fax Modem
+		122d 4002  HPG / MDP3858-U # Aztech
+		122d 4005  MDP3858-E # Aztech
+		122d 4007  MDP3858-A/-NZ # Aztech
+		122d 4012  MDP3858-SA # Aztech
+		122d 4017  MDP3858-W # Aztech
+		122d 4018  MDP3858-W # Aztech
+	1003  HCF 56k Data/Fax Modem
+		0e11 b0bc  229-DF Zephyr # Compaq
+		0e11 b114  229-DF Cheetah # Compaq
+		1033 802b  229-DF # NEC
+		13df 1003  PCI56RX Modem # E-Tech Inc
+		13e0 0117  IBM # GVC
+		13e0 0147  IBM # GVC
+		13e0 0197  IBM # GVC
+		13e0 01c7  IBM # GVC
+		13e0 01f7  IBM # GVC
+		1436 1003  IBM # CIS
+		1436 1103  IBM # CIS
+		1436 1602  Compaq 229-DF Ducati
+	1004  HCF 56k Data/Fax/Voice Modem
+		10cf 1059  Fujitsu 229-DFRT
+	1005  HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+		1033 8029  229-DFSV # NEC
+		1033 8054  Modem # NEC
+		10cf 103c  Fujitsu
+		10cf 1055  Fujitsu 229-DFSV
+		10cf 1056  Fujitsu 229-DFSV
+		122d 4003  MDP3858SP-U # Aztech
+		122d 4006  Packard Bell MDP3858V-E # Aztech
+		122d 4008  MDP3858SP-A/SP-NZ # Aztech
+		122d 4009  MDP3858SP-E # Aztech
+		122d 4010  MDP3858V-U # Aztech
+		122d 4011  MDP3858SP-SA # Aztech
+		122d 4013  MDP3858V-A/V-NZ # Aztech
+		122d 4015  MDP3858SP-W # Aztech
+		122d 4016  MDP3858V-W # Aztech
+		122d 4019  MDP3858V-SA # Aztech
+		13df 1005  PCI56RVP Modem  # E-Tech Inc
+		13e0 0187  IBM # GVC
+		13e0 01a7  IBM # GVC
+		13e0 01b7  IBM # GVC
+		13e0 01d7  IBM # GVC
+		1436 1005  IBM # CIS
+		1436 1105  IBM # CIS
+	1023  HCF 56k Data/Fax Modem
+		122d 4020  Packard Bell MDP3858-WE # Aztech
+		122d 4023  MDP3858-UE # Aztech
+		13e0 0247  IBM # GVC
+		13e0 0297  IBM # GVC
+		13e0 02c7  IBM # GVC
+		1436 1203  IBM # CIS
+		1436 1303  IBM # CIS
+	1024  HCF 56k Data/Fax/Voice Modem
+	1025  HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+		10cf 106a  Fujitsu 235-DFSV
+		122d 4021  Packard Bell MDP3858V-WE # Aztech
+		122d 4022  MDP3858SP-WE # Aztech
+		122d 4024  MDP3858V-UE # Aztech
+		122d 4025  MDP3858SP-UE # Aztech
 	1026  HCF 56k PCI Speakerphone Modem
-		127a 1026  HCF 56k PCI Speakerphone Modem
 	1035  HCF 56k PCI Speakerphone Modem
-		127a 1035  HCF 56k PCI Speakerphone Modem
-	1085  Volcano HCF 56k PCI Modem
-		127a 1085  Volcano HCF 56k PCI Modem
-	2005  HCF 56k V90 FaxModem
-		127a 2005  Conexant SoftK56 Speakerphone Modem
-	2015  Conexant SoftK56 Speakerphone Modem
-		127a 2015  Conexant SoftK56 Speakerphone Modem
-		14c8 2115  Conexant SoftK56 Speakerphone Modem
+	1085  HCF 56k Volcano PCI Modem
+	2005  HCF 56k Data/Fax Modem
+		104d 8044  229-DFSV # Sony
+		104d 8045  229-DFSV # Sony
+		104d 8055  PBE/Aztech 235W-DFSV # Sony
+		104d 8056  235-DFSV # Sony
+		104d 805a  Modem # Sony
+		104d 805f  Modem # Sony
+		104d 8074  Modem # Sony
+	2013  HSF 56k Data/Fax Modem
+		1179 0001  Modem # Toshiba
+		1179 ff00  Modem # Toshiba
+	2014  HSF 56k Data/Fax/Voice Modem
+		10cf 1057  Fujitsu Citicorp III
+		122d 4050  MSP3880-U # Aztech
+		122d 4055  MSP3880-W # Aztech
+	2015  HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+		10cf 1063  Fujitsu
+		10cf 1064  Fujitsu
+		1468 2015  Fujitsu
+	2016  HSF 56k Data/Fax/Voice/Spkp Modem
+		122d 4051  MSP3880V-W # Aztech
+		122d 4052  MSP3880SP-W # Aztech
+		122d 4054  MSP3880V-U # Aztech
+		122d 4056  MSP3880SP-U # Aztech
+		122d 4057  MSP3880SP-A # Aztech
+	4311  Riptide HSF 56k PCI Modem
+		127a 4311  Ring Modular? Riptide HSF RT HP Dom
+		13e0 0210  HP-GVC
 	4320  Riptide PCI Audio Controller
 		1235 4320  Riptide PCI Audio Controller
 	4321  Riptide HCF 56k PCI Modem
-		1235 4321  Riptide HCF 56k PCI Modem
+		1235 4321  Hewlett Packard DF
+		1235 4324  Hewlett Packard DF
+		13e0 0210  Hewlett Packard DF
+		144d 2321  Riptide # Samsung
 	4322  Riptide PCI Game Controller
 		1235 4322  Riptide PCI Game Controller
 	8234  RapidFire 616X ATM155 Adapter
@@ -3884,6 +3954,7 @@
 148b  INNOMEDIALOGIC Inc.
 148c  C.P. Technology Co. Ltd
 148d  DIGICOM Systems, Inc.
+	1003  HCF 56k Data/Fax Modem
 148e  OSI Plus Corporation
 148f  Plant Equipment, Inc.
 1490  Stone Microsystems PTY Ltd.
@@ -4021,30 +4092,123 @@
 14ee  MASPRO KENKOH Corp
 14ef  CARRY Computer ENG. CO Ltd
 14f0  CANON RESEACH CENTRE FRANCE
-14f1  CONEXANT
-	1033  56K Winmodem
-		13e0 02b0  56K Winmodem
-	1035  PCI Modem Enumerator
-	2003  SoftK56 Winmodem
-		14f1 2003  SoftK56 Winmodem
-	2004  SoftK56 RemoteTAM Winmodem
-		14f1 2004  SoftK56 RemoteTAM Winmodem
-	2005  SoftK56 Speakerphone Winmodem
-		14f1 2005  SoftK56 Speakerphone Winmodem
-	2006  SoftK56 Speakerphone Winmodem
-		14f1 2006  SoftK56 Speakerphone Winmodem
-	2013  HSP MicroModem 56K
-		14f1 2013  SoftK56 Winmodem
-	2014  SoftK56 RemoteTAM Winmodem
-		144f 101c  SoftK56 RemoteTAM Winmodem
-		144f 2014  SoftK56 RemoteTAM Winmodem
-	2015  SoftK56 Speakerphone Winmodem
-		14c8 2115  SoftK56 Speakerphone Winmodem
-		14f1 2015  SoftK56 Speakerphone Winmodem
-	2016  SoftK56 Speakerphone Winmodem
-		14f1 2016  SoftK56 Speakerphone Winmodem
-	2443  SoftK56 Speakerphone Winmodem
-		14f1 2443  SoftK56 Speakerphone Winmodem
+14f1  Conexant
+	1033  HCF 56k Data/Fax Modem
+		1033 8077  NEC
+		122d 4027  Dell Zeus - MDP3880-W(B) Data Fax Modem # Aztech
+		122d 4030  Dell Mercury - MDP3880-U(B) Data Fax Modem # Aztech
+		122d 4034  Dell Thor - MDP3880-W(U) Data Fax Modem # Aztech
+		13e0 020d  Dell Copper
+		13e0 020e  Dell Silver
+		13e0 0261  IBM # GVC
+		13e0 0290  Compaq Goldwing
+		13e0 02a0  IBM # GVC
+		13e0 02b0  IBM # GVC
+		13e0 02c0  Compaq Scooter
+		13e0 02d0  IBM # GVC
+		144f 1500  IBM P85-DF # Askey
+		144f 1501  IBM P85-DF # Askey
+		144f 150a  IBM P85-DF # Askey
+		144f 150b  IBM P85-DF Low Profile # Askey
+		144f 1510  IBM P85-DF Low Profile # Askey
+	1034  HCF 56k Data/Fax/Voice Modem
+	1035  HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+		10cf 1098  Fujitsu P85-DFSV
+	1036  HCF 56k Data/Fax/Voice/Spkp Modem
+		122d 4029  MDP3880SP-W # Aztech
+		122d 4031  MDP3880SP-U # Aztech
+		13e0 0209  Dell Titanium
+		13e0 020a  Dell Graphite
+		13e0 0260  Gateway Red Owl
+		13e0 0270  Gateway White Horse
+	1052  HCF 56k Data/Fax Modem (Worldwide)
+	1053  HCF 56k Data/Fax Modem (Worldwide)
+	1054  HCF 56k Data/Fax/Voice Modem (Worldwide)
+	1055  HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Worldwide)
+	1056  HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide)
+	1057  HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide)
+	1059  HCF 56k Data/Fax/Voice Modem (Worldwide)
+	1063  HCF 56k Data/Fax Modem
+	1064  HCF 56k Data/Fax/Voice Modem
+	1065  HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+	1066  HCF 56k Data/Fax/Voice/Spkp Modem
+		122d 4033  Dell Athena - MDP3900V-U # Aztech
+	1433  HCF 56k Data/Fax Modem
+	1434  HCF 56k Data/Fax/Voice Modem
+	1435  HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+	1436  HCF 56k Data/Fax Modem
+	1453  HCF 56k Data/Fax Modem
+		13e0 0240  IBM # GVC
+		13e0 0250  IBM # GVC
+		144f 1502  IBM P95-DF # Askey
+		144f 1503  IBM P95-DF # Askey
+	1454  HCF 56k Data/Fax/Voice Modem
+	1455  HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+	1456  HCF 56k Data/Fax/Voice/Spkp Modem
+		122d 4035  Dell Europa - MDP3900V-W # Aztech
+		122d 4302  MP3930V-W(C) MiniPCI # Aztech
+	1803  HCF 56k Modem
+		0e11 0023 623-LAN Grizzly # Compaq
+		0e11 0043 623-LAN Yogi # Compaq
+	1815  HCF 56k Modem
+		0e11 0022  Grizzly # Compaq
+		0e11 0042  Yogi # Compaq
+	2003  HSF 56k Data/Fax Modem
+	2004  HSF 56k Data/Fax/Voice Modem
+	2005  HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+	2006  HSF 56k Data/Fax/Voice/Spkp Modem
+	2013  HSF 56k Data/Fax Modem
+		0e11 b195  Bear # Compaq
+		0e11 b196  Seminole 1 # Compaq
+		0e11 b1be  Seminole 2 # Compaq
+		1025 8013  Acer
+		1033 809d  NEC
+		1033 80bc  NEC
+		155d 6793  HP
+		155d 8850  E Machines
+	2014  HSF 56k Data/Fax/Voice Modem
+	2015  HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+	2016  HSF 56k Data/Fax/Voice/Spkp Modem
+	2043  HSF 56k Data/Fax Modem (Worldwide SmartDAA)
+	2044  HSF 56k Data/Fax/Voice Modem (Worldwide SmartDAA)
+	2045  HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Worldwide SmartDAA)
+	2046  HSF 56k Data/Fax/Voice/Spkp Modem (Worldwide SmartDAA)
+	2063  HSF 56k Data/Fax Modem (SmartDAA)
+	2064  HSF 56k Data/Fax/Voice Modem (SmartDAA)
+	2065  HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (SmartDAA)
+	2066  HSF 56k Data/Fax/Voice/Spkp Modem (SmartDAA)
+	2093  HSF 56k Modem
+		155d 2f07  Legend
+	2143  HSF 56k Data/Fax/Cell Modem (Mobile Worldwide SmartDAA)
+	2144  HSF 56k Data/Fax/Voice/Cell Modem (Mobile Worldwide SmartDAA)
+	2145  HSF 56k Data/Fax/Voice/Spkp (w/HS)/Cell Modem (Mob WW SmartDAA)
+	2146  HSF 56k Data/Fax/Voice/Spkp/Cell Modem (Mobile Worldwide SmartDAA)
+	2163  HSF 56k Data/Fax/Cell Modem (Mobile SmartDAA)
+	2164  HSF 56k Data/Fax/Voice/Cell Modem (Mobile SmartDAA)
+	2165  HSF 56k Data/Fax/Voice/Spkp (w/Handset)/Cell Modem (Mobile SmartDAA)
+	2166  HSF 56k Data/Fax/Voice/Spkp/Cell Modem (Mobile SmartDAA)
+	2343  HSF 56k Data/Fax CardBus Modem (Mobile Worldwide SmartDAA)
+	2344  HSF 56k Data/Fax/Voice CardBus Modem (Mobile Worldwide SmartDAA)
+	2345  HSF 56k Data/Fax/Voice/Spkp (w/HS) CardBus Modem (Mob WW SmartDAA)
+	2346  HSF 56k Data/Fax/Voice/Spkp CardBus Modem (Mobile Worldwide SmartDAA)
+	2363  HSF 56k Data/Fax CardBus Modem (Mobile SmartDAA)
+	2364  HSF 56k Data/Fax/Voice CardBus Modem (Mobile SmartDAA)
+	2365  HSF 56k Data/Fax/Voice/Spkp (w/HS) CardBus Modem (Mob SmartDAA)
+	2366  HSF 56k Data/Fax/Voice/Spkp CardBus Modem (Mobile SmartDAA)
+	2443  HSF 56k Data/Fax Modem (Mobile Worldwide SmartDAA)
+		104d 8075  Modem # Sony
+		104d 8083  Modem # Sony
+		104d 8097  Modem # Sony
+	2444  HSF 56k Data/Fax/Voice Modem (Mobile Worldwide SmartDAA)
+	2445  HSF 56k Data/Fax/Voice/Spkp (w/HS) Modem (Mobile WW SmartDAA)
+	2446  HSF 56k Data/Fax/Voice/Spkp Modem (Mobile Worldwide SmartDAA)
+	2463  HSF 56k Data/Fax Modem (Mobile SmartDAA)
+	2464  HSF 56k Data/Fax/Voice Modem (Mobile SmartDAA)
+	2465  HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Mobile SmartDAA)
+	2466  HSF 56k Data/Fax/Voice/Spkp Modem (Mobile SmartDAA)
+	2f00  HSF 56k HSFi Modem
+		13e0 8d84  IBM HSFi V.90
+		13e0 8d85  Compaq Stinger
 14f2  MOBILITY Electronics
 14f3  BROADLOGIC
 14f4  TOKYO Electronic Industry CO Ltd
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/Makefile linux/drivers/pcmcia/Makefile
--- v2.4.12/linux/drivers/pcmcia/Makefile	Mon Mar 26 15:36:30 2001
+++ linux/drivers/pcmcia/Makefile	Thu Oct 11 09:43:29 2001
@@ -53,10 +53,33 @@
   endif
 endif
 
+obj-$(CONFIG_PCMCIA_SA1100)	+= sa1100_cs.o
+
+sa1100_cs-objs-y				:= sa1100_generic.o
+sa1100_cs-objs-$(CONFIG_SA1100_ASSABET)		+= sa1100_assabet.o
+sa1100_cs-objs-$(CONFIG_ASSABET_NEPONSET)	+= sa1100_neponset.o
+sa1100_cs-objs-$(CONFIG_SA1100_H3600)		+= sa1100_h3600.o
+sa1100_cs-objs-$(CONFIG_SA1100_CERF)		+= sa1100_cerf.o
+sa1100_cs-objs-$(CONFIG_SA1100_GRAPHICSCLIENT)	+= sa1100_graphicsclient.o
+sa1100_cs-objs-$(CONFIG_SA1100_XP860)		+= sa1100_xp860.o
+sa1100_cs-objs-$(CONFIG_SA1100_PANGOLIN)	+= sa1100_pangolin.o
+sa1100_cs-objs-$(CONFIG_SA1100_YOPY)		+= sa1100_yopy.o
+sa1100_cs-objs-$(CONFIG_SA1100_FREEBIRD)	+= sa1100_freebird.o
+sa1100_cs-objs-$(CONFIG_SA1100_PFS168)		+= sa1100_pfs168.o
+sa1100_cs-objs-$(CONFIG_SA1100_JORNADA720)	+= sa1100_jornada720.o
+sa1100_cs-objs-$(CONFIG_SA1100_FLEXANET)	+= sa1100_flexanet.o
+sa1100_cs-objs-$(CONFIG_SA1100_SIMPAD)		+= sa1100_simpad.o
+sa1100_cs-objs-$(CONFIG_SA1100_GRAPHICSMASTER)	+= sa1100_graphicsmaster.o
+sa1100_cs-objs-$(CONFIG_SA1100_ADSBITSY)	+= sa1100_adsbitsy.o
+sa1100_cs-objs-$(CONFIG_SA1100_STORK)		+= sa1100_stork.o
+
 include $(TOPDIR)/Rules.make
 
 pcmcia_core.o:  $(pcmcia_core-objs)
 	$(LD) $(LD_RFLAG) -r -o $@ $(pcmcia_core-objs)
+
+sa1100_cs.o: $(sa1100_cs-objs-y)
+	$(LD) -r -o $@ $(sa1100_cs-objs-y)
 
 yenta_socket.o: $(yenta_socket-objs)
 	$(LD) $(LD_RFLAG) -r -o $@ $(yenta_socket-objs)
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/cs.c linux/drivers/pcmcia/cs.c
--- v2.4.12/linux/drivers/pcmcia/cs.c	Tue Oct  9 17:06:52 2001
+++ linux/drivers/pcmcia/cs.c	Thu Oct 11 09:43:29 2001
@@ -789,6 +789,10 @@
 	      *base, align);
 	align = 0;
     }
+    if ((s->cap.features & SS_CAP_STATIC_MAP) && s->cap.io_offset) {
+	*base = s->cap.io_offset | (*base & 0x0fff);
+	return 0;
+    }
     /* Check for an already-allocated window that must conflict with
        what was asked for.  It is a hack because it does not catch all
        potential conflicts, just the most obvious ones. */
@@ -833,7 +837,8 @@
 			     ioaddr_t num)
 {
     int i;
-    release_region(base, num);
+    if(!(s->cap.features & SS_CAP_STATIC_MAP))
+	release_region(base, num);
     for (i = 0; i < MAX_IO_WIN; i++) {
 	if ((s->io[i].BasePort <= base) &&
 	    (s->io[i].BasePort+s->io[i].NumPorts >= base+num)) {
@@ -1623,7 +1628,8 @@
     s->state &= ~SOCKET_WIN_REQ(win->index);
 
     /* Release system memory */
-    release_mem_region(win->base, win->size);
+    if(!(s->cap.features & SS_CAP_STATIC_MAP))
+	release_mem_region(win->base, win->size);
     win->handle->state &= ~CLIENT_WIN_REQ(win->index);
 
     win->magic = 0;
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100.h linux/drivers/pcmcia/sa1100.h
--- v2.4.12/linux/drivers/pcmcia/sa1100.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100.h	Thu Oct 11 09:43:29 2001
@@ -0,0 +1,202 @@
+/*======================================================================
+
+    Device driver for the PCMCIA control functionality of StrongARM
+    SA-1100 microprocessors.
+
+    The contents of this file are subject to the Mozilla Public
+    License Version 1.1 (the "License"); you may not use this file
+    except in compliance with the License. You may obtain a copy of
+    the License at http://www.mozilla.org/MPL/
+
+    Software distributed under the License is distributed on an "AS
+    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+    implied. See the License for the specific language governing
+    rights and limitations under the License.
+
+    The initial developer of the original code is John G. Dorsey
+    <john+@cs.cmu.edu>.  Portions created by John G. Dorsey are
+    Copyright (C) 1999 John G. Dorsey.  All Rights Reserved.
+
+    Alternatively, the contents of this file may be used under the
+    terms of the GNU Public License version 2 (the "GPL"), in which
+    case the provisions of the GPL are applicable instead of the
+    above.  If you wish to allow the use of your version of this file
+    only under the terms of the GPL and not to allow others to use
+    your version of this file under the MPL, indicate your decision
+    by deleting the provisions above and replace them with the notice
+    and other provisions required by the GPL.  If you do not delete
+    the provisions above, a recipient may use your version of this
+    file under either the MPL or the GPL.
+    
+======================================================================*/
+
+#if !defined(_PCMCIA_SA1100_H)
+# define _PCMCIA_SA1100_H
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/ss.h>
+#include <pcmcia/bulkmem.h>
+#include <pcmcia/cistpl.h>
+#include "cs_internal.h"
+
+#include <asm/arch/pcmcia.h>
+
+
+/* MECR: Expansion Memory Configuration Register
+ * (SA-1100 Developers Manual, p.10-13; SA-1110 Developers Manual, p.10-24)
+ *
+ * MECR layout is:  
+ *
+ *   FAST1 BSM1<4:0> BSA1<4:0> BSIO1<4:0> FAST0 BSM0<4:0> BSA0<4:0> BSIO0<4:0>
+ *
+ * (This layout is actually true only for the SA-1110; the FASTn bits are
+ * reserved on the SA-1100.)
+ */
+
+#define MECR_SOCKET_0_SHIFT (0)
+#define MECR_SOCKET_1_SHIFT (16)
+
+#define MECR_BS_MASK        (0x1f)
+#define MECR_FAST_MODE_MASK (0x01)
+
+#define MECR_BSIO_SHIFT (0)
+#define MECR_BSA_SHIFT  (5)
+#define MECR_BSM_SHIFT  (10)
+#define MECR_FAST_SHIFT (15)
+
+#define MECR_SET(mecr, sock, shift, mask, bs) \
+((mecr)=((mecr)&~(((mask)<<(shift))<<\
+                  ((sock)==0?MECR_SOCKET_0_SHIFT:MECR_SOCKET_1_SHIFT)))|\
+        (((bs)<<(shift))<<((sock)==0?MECR_SOCKET_0_SHIFT:MECR_SOCKET_1_SHIFT)))
+
+#define MECR_GET(mecr, sock, shift, mask) \
+((((mecr)>>(((sock)==0)?MECR_SOCKET_0_SHIFT:MECR_SOCKET_1_SHIFT))>>\
+ (shift))&(mask))
+
+#define MECR_BSIO_SET(mecr, sock, bs) \
+MECR_SET((mecr), (sock), MECR_BSIO_SHIFT, MECR_BS_MASK, (bs))
+
+#define MECR_BSIO_GET(mecr, sock) \
+MECR_GET((mecr), (sock), MECR_BSIO_SHIFT, MECR_BS_MASK)
+
+#define MECR_BSA_SET(mecr, sock, bs) \
+MECR_SET((mecr), (sock), MECR_BSA_SHIFT, MECR_BS_MASK, (bs))
+
+#define MECR_BSA_GET(mecr, sock) \
+MECR_GET((mecr), (sock), MECR_BSA_SHIFT, MECR_BS_MASK)
+
+#define MECR_BSM_SET(mecr, sock, bs) \
+MECR_SET((mecr), (sock), MECR_BSM_SHIFT, MECR_BS_MASK, (bs))
+
+#define MECR_BSM_GET(mecr, sock) \
+MECR_GET((mecr), (sock), MECR_BSM_SHIFT, MECR_BS_MASK)
+
+#define MECR_FAST_SET(mecr, sock, fast) \
+MECR_SET((mecr), (sock), MECR_FAST_SHIFT, MECR_FAST_MODE_MASK, (fast))
+
+#define MECR_FAST_GET(mecr, sock) \
+MECR_GET((mecr), (sock), MECR_FAST_SHIFT, MECR_FAST_MODE_MASK)
+
+
+/* This function implements the BS value calculation for setting the MECR
+ * using integer arithmetic:
+ */
+static inline unsigned int sa1100_pcmcia_mecr_bs(unsigned int pcmcia_cycle_ns,
+						 unsigned int cpu_clock_khz){
+  unsigned int t = ((pcmcia_cycle_ns * cpu_clock_khz) / 6) - 1000000;
+  return (t / 1000000) + (((t % 1000000) == 0) ? 0 : 1);
+}
+
+/* This function returns the (approxmiate) command assertion period, in
+ * nanoseconds, for a given CPU clock frequency and MECR BS value:
+ */
+static inline unsigned int sa1100_pcmcia_cmd_time(unsigned int cpu_clock_khz,
+						  unsigned int pcmcia_mecr_bs){
+  return (((10000000 * 2) / cpu_clock_khz) * (3 * (pcmcia_mecr_bs + 1))) / 10;
+}
+
+
+/* SA-1100 PCMCIA Memory and I/O timing
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * The SA-1110 Developer's Manual, section 10.2.5, says the following:
+ *
+ *  "To calculate the recommended BS_xx value for each address space:
+ *   divide the command width time (the greater of twIOWR and twIORD,
+ *   or the greater of twWE and twOE) by processor cycle time; divide
+ *   by 2; divide again by 3 (number of BCLK's per command assertion);
+ *   round up to the next whole number; and subtract 1."
+ *
+ * The PC Card Standard, Release 7, section 4.13.4, says that twIORD
+ * has a minimum value of 165ns. Section 4.13.5 says that twIOWR has
+ * a minimum value of 165ns, as well. Section 4.7.2 (describing
+ * common and attribute memory write timing) says that twWE has a
+ * minimum value of 150ns for a 250ns cycle time (for 5V operation;
+ * see section 4.7.4), or 300ns for a 600ns cycle time (for 3.3V
+ * operation, also section 4.7.4). Section 4.7.3 says that taOE
+ * has a maximum value of 150ns for a 300ns cycle time (for 5V
+ * operation), or 300ns for a 600ns cycle time (for 3.3V operation).
+ *
+ * When configuring memory maps, Card Services appears to adopt the policy
+ * that a memory access time of "0" means "use the default." The default
+ * PCMCIA I/O command width time is 165ns. The default PCMCIA 5V attribute
+ * and memory command width time is 150ns; the PCMCIA 3.3V attribute and
+ * memory command width time is 300ns.
+ */
+#define SA1100_PCMCIA_IO_ACCESS      (165)
+#define SA1100_PCMCIA_5V_MEM_ACCESS  (150)
+#define SA1100_PCMCIA_3V_MEM_ACCESS  (300)
+
+
+/* The socket driver actually works nicely in interrupt-driven form,
+ * so the (relatively infrequent) polling is "just to be sure."
+ */
+#define SA1100_PCMCIA_POLL_PERIOD    (2*HZ)
+
+
+/* This structure encapsulates per-socket state which we might need to
+ * use when responding to a Card Services query of some kind.
+ */
+struct sa1100_pcmcia_socket {
+  socket_state_t        cs_state;
+  struct pcmcia_state   k_state;
+  unsigned int          irq;
+  void                  (*handler)(void *, unsigned int);
+  void                  *handler_info;
+  pccard_io_map         io_map[MAX_IO_WIN];
+  pccard_mem_map        mem_map[MAX_WIN];
+  ioaddr_t              virt_io, phys_attr, phys_mem;
+  unsigned short        speed_io, speed_attr, speed_mem;
+};
+
+
+/* I/O pins replacing memory pins
+ * (PCMCIA System Architecture, 2nd ed., by Don Anderson, p.75)
+ *
+ * These signals change meaning when going from memory-only to 
+ * memory-or-I/O interface:
+ */
+#define iostschg bvd1
+#define iospkr   bvd2
+
+
+/*
+ * Declaration for all implementation specific low_level operations.
+ */
+extern struct pcmcia_low_level assabet_pcmcia_ops;
+extern struct pcmcia_low_level neponset_pcmcia_ops;
+extern struct pcmcia_low_level h3600_pcmcia_ops;
+extern struct pcmcia_low_level cerf_pcmcia_ops;
+extern struct pcmcia_low_level gcplus_pcmcia_ops;
+extern struct pcmcia_low_level xp860_pcmcia_ops;
+extern struct pcmcia_low_level yopy_pcmcia_ops;
+extern struct pcmcia_low_level pangolin_pcmcia_ops;
+extern struct pcmcia_low_level freebird_pcmcia_ops;
+extern struct pcmcia_low_level pfs168_pcmcia_ops;
+extern struct pcmcia_low_level jornada720_pcmcia_ops;
+extern struct pcmcia_low_level flexanet_pcmcia_ops;
+extern struct pcmcia_low_level simpad_pcmcia_ops;
+extern struct pcmcia_low_level graphicsmaster_pcmcia_ops;
+extern struct pcmcia_low_level adsbitsy_pcmcia_ops;
+extern struct pcmcia_low_level stork_pcmcia_ops;
+
+#endif  /* !defined(_PCMCIA_SA1100_H) */
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_adsbitsy.c linux/drivers/pcmcia/sa1100_adsbitsy.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_adsbitsy.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_adsbitsy.c	Thu Oct 11 09:43:29 2001
@@ -0,0 +1,216 @@
+/*
+ * drivers/pcmcia/sa1100_adsbitsy.c
+ *
+ * PCMCIA implementation routines for ADS Bitsy
+ *
+ * 9/18/01 Woojung
+ *         Fixed wrong PCMCIA voltage setting
+ *
+ * 7/5/01 Woojung Huh <whuh@applieddata.net>
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/delay.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+static int adsbitsy_pcmcia_init(struct pcmcia_init *init)
+{
+  int return_val=0;
+
+  /* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
+  PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
+
+  /* Disable Power 3.3V/5V for PCMCIA/CF */
+  PA_DWR |= GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3;
+
+  INTPOL1 |= (1 << (S0_READY_NINT - SA1111_IRQ(32))) |
+			 (1 << (S1_READY_NINT - SA1111_IRQ(32))) |
+    		 (1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+    		 (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+    		 (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+    		 (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32)));
+
+  return_val+=request_irq(S0_CD_VALID, init->handler, SA_INTERRUPT,
+			  "GC Master PCMCIA (0) CD", NULL);
+  return_val+=request_irq(S1_CD_VALID, init->handler, SA_INTERRUPT,
+			  "GC Master CF (1) CD", NULL);
+  return_val+=request_irq(S0_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+			  "GC Master PCMCIA (0) BVD1", NULL);
+  return_val+=request_irq(S1_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+			  "GC Master CF (1) BVD1", NULL);
+
+  MECR = 0x09430943;
+
+  return (return_val<0) ? -1 : 2;
+}
+
+static int adsbitsy_pcmcia_shutdown(void)
+{
+
+  free_irq(S0_CD_VALID, NULL);
+  free_irq(S1_CD_VALID, NULL);
+  free_irq(S0_BVD1_STSCHG, NULL);
+  free_irq(S1_BVD1_STSCHG, NULL);
+
+  INTPOL1 &= ~((1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+			   (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+      		   (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+      		   (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32))));
+
+  return 0;
+}
+
+static int adsbitsy_pcmcia_socket_state(struct pcmcia_state_array *state_array)
+{
+  unsigned long status;
+  int return_val=1;
+
+  if(state_array->size<2) return -1;
+
+  memset(state_array->state, 0,
+	 (state_array->size)*sizeof(struct pcmcia_state));
+
+  status=PCSR;
+
+  state_array->state[0].detect=((status & PCSR_S0_DETECT)==0)?1:0;
+
+  state_array->state[0].ready=((status & PCSR_S0_READY)==0)?0:1;
+
+  state_array->state[0].bvd1=((status & PCSR_S0_BVD1)==0)?0:1;
+
+  state_array->state[0].bvd2=((status & PCSR_S0_BVD2)==0)?0:1;
+
+  state_array->state[0].wrprot=((status & PCSR_S0_WP)==0)?0:1;
+
+  state_array->state[0].vs_3v=((status & PCSR_S0_VS1)==0)?1:0;
+
+  state_array->state[0].vs_Xv=((status & PCSR_S0_VS2)==0)?1:0;
+
+  state_array->state[1].detect=((status & PCSR_S1_DETECT)==0)?1:0;
+
+  state_array->state[1].ready=((status & PCSR_S1_READY)==0)?0:1;
+
+  state_array->state[1].bvd1=((status & PCSR_S1_BVD1)==0)?0:1;
+
+  state_array->state[1].bvd2=((status & PCSR_S1_BVD2)==0)?0:1;
+
+  state_array->state[1].wrprot=((status & PCSR_S1_WP)==0)?0:1;
+
+  state_array->state[1].vs_3v=((status & PCSR_S1_VS1)==0)?1:0;
+
+  state_array->state[1].vs_Xv=((status & PCSR_S1_VS2)==0)?1:0;
+
+  return return_val;
+}
+
+static int adsbitsy_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+
+  switch(info->sock){
+  case 0:
+    info->irq=S0_READY_NINT;
+    break;
+
+  case 1:
+    info->irq=S1_READY_NINT;
+    break;
+
+  default:
+    return -1;
+  }
+
+  return 0;
+}
+
+static int adsbitsy_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+{
+  unsigned long pccr=PCCR, gpio=PA_DWR;
+
+  switch(configure->sock){
+  case 0:
+
+    switch(configure->vcc){
+    case 0:
+      pccr = (pccr & ~PCCR_S0_FLT);
+      gpio |= GPIO_GPIO0 | GPIO_GPIO1;
+      break;
+
+    case 33:
+      pccr = (pccr & ~PCCR_S0_PSE) | PCCR_S0_FLT | PCCR_S0_PWAITEN;
+      gpio &= ~(GPIO_GPIO0 | GPIO_GPIO1);
+	  gpio &= ~GPIO_GPIO0;
+      break;
+
+    case 50:
+      pccr = (pccr | PCCR_S0_PSE | PCCR_S0_FLT | PCCR_S0_PWAITEN);
+      gpio &= ~(GPIO_GPIO0 | GPIO_GPIO1);
+	  gpio |= GPIO_GPIO0;
+      break;
+
+    default:
+      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+	     configure->vcc);
+      return -1;
+    }
+
+    pccr=(configure->reset)?(pccr | PCCR_S0_RST):(pccr & ~PCCR_S0_RST);
+
+    break;
+
+  case 1:
+    switch(configure->vcc){
+    case 0:
+      pccr = (pccr & ~PCCR_S1_FLT);
+      gpio &= ~(GPIO_GPIO2 | GPIO_GPIO3);
+      break;
+
+    case 33:
+      pccr = (pccr & ~PCCR_S1_PSE) | PCCR_S1_FLT | PCCR_S1_PWAITEN;
+      gpio &= ~(GPIO_GPIO2 | GPIO_GPIO3);
+	  gpio |= GPIO_GPIO2;
+      break;
+
+    case 50:
+      pccr = (pccr | PCCR_S1_PSE | PCCR_S1_FLT | PCCR_S1_PWAITEN);
+      gpio &= ~(GPIO_GPIO2 | GPIO_GPIO3);
+	  gpio |= GPIO_GPIO3;
+      break;
+
+    default:
+      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+	     configure->vcc);
+      return -1;
+    }
+
+    if(configure->vpp!=configure->vcc && configure->vpp!=0){
+      printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n", __FUNCTION__,
+	     configure->vpp);
+      return -1;
+    }
+
+    pccr=(configure->reset)?(pccr | PCCR_S1_RST):(pccr & ~PCCR_S1_RST);
+
+    break;
+
+  default:
+    return -1;
+  }
+
+  PCCR = pccr;
+  PA_DWR = gpio;
+
+  return 0;
+}
+
+struct pcmcia_low_level adsbitsy_pcmcia_ops = {
+  adsbitsy_pcmcia_init,
+  adsbitsy_pcmcia_shutdown,
+  adsbitsy_pcmcia_socket_state,
+  adsbitsy_pcmcia_get_irq_info,
+  adsbitsy_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_assabet.c linux/drivers/pcmcia/sa1100_assabet.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_assabet.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_assabet.c	Thu Oct 11 09:43:29 2001
@@ -0,0 +1,149 @@
+/*
+ * drivers/pcmcia/sa1100_assabet.c
+ *
+ * PCMCIA implementation routines for Assabet
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+
+static int assabet_pcmcia_init(struct pcmcia_init *init){
+  int irq, res;
+
+  /* Enable CF bus: */
+  BCR_clear(BCR_CF_BUS_OFF);
+
+  /* All those are inputs */
+  GPDR &= ~(GPIO_CF_CD | GPIO_CF_BVD2 | GPIO_CF_BVD1 | GPIO_CF_IRQ);
+
+  /* Set transition detect */
+  set_GPIO_IRQ_edge( GPIO_CF_CD|GPIO_CF_BVD2|GPIO_CF_BVD1, GPIO_BOTH_EDGES );
+  set_GPIO_IRQ_edge( GPIO_CF_IRQ, GPIO_FALLING_EDGE );
+
+  /* Register interrupts */
+  irq = IRQ_GPIO_CF_CD;
+  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_CD", NULL );
+  if( res < 0 ) goto irq_err;
+  irq = IRQ_GPIO_CF_BVD2;
+  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_BVD2", NULL );
+  if( res < 0 ) goto irq_err;
+  irq = IRQ_GPIO_CF_BVD1;
+  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_BVD1", NULL );
+  if( res < 0 ) goto irq_err;
+
+  /* There's only one slot, but it's "Slot 1": */
+  return 2;
+
+irq_err:
+  printk( KERN_ERR "%s: Request for IRQ %u failed\n", __FUNCTION__, irq );
+  return -1;
+}
+
+static int assabet_pcmcia_shutdown(void)
+{
+  /* disable IRQs */
+  free_irq( IRQ_GPIO_CF_CD, NULL );
+  free_irq( IRQ_GPIO_CF_BVD2, NULL );
+  free_irq( IRQ_GPIO_CF_BVD1, NULL );
+  
+  /* Disable CF bus: */
+  BCR_set(BCR_CF_BUS_OFF);
+
+  return 0;
+}
+
+static int assabet_pcmcia_socket_state(struct pcmcia_state_array
+				       *state_array){
+  unsigned long levels;
+
+  if(state_array->size<2) return -1;
+
+  memset(state_array->state, 0, 
+	 (state_array->size)*sizeof(struct pcmcia_state));
+
+  levels=GPLR;
+
+  state_array->state[1].detect=((levels & GPIO_CF_CD)==0)?1:0;
+
+  state_array->state[1].ready=(levels & GPIO_CF_IRQ)?1:0;
+
+  state_array->state[1].bvd1=(levels & GPIO_CF_BVD1)?1:0;
+
+  state_array->state[1].bvd2=(levels & GPIO_CF_BVD2)?1:0;
+
+  state_array->state[1].wrprot=0; /* Not available on Assabet. */
+
+  state_array->state[1].vs_3v=1;  /* Can only apply 3.3V on Assabet. */
+
+  state_array->state[1].vs_Xv=0;
+
+  return 1;
+}
+
+static int assabet_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+
+  if(info->sock>1) return -1;
+
+  if(info->sock==1)
+    info->irq=IRQ_GPIO_CF_IRQ;
+
+  return 0;
+}
+
+static int assabet_pcmcia_configure_socket(const struct pcmcia_configure
+					   *configure)
+{
+  unsigned long value, flags;
+
+  if(configure->sock>1) return -1;
+
+  if(configure->sock==0) return 0;
+
+  save_flags_cli(flags);
+
+  value = BCR_value;
+
+  switch(configure->vcc){
+  case 0:
+    value &= ~BCR_CF_PWR;
+    break;
+
+  case 50:
+    printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n",
+	   __FUNCTION__);
+
+  case 33:  /* Can only apply 3.3V to the CF slot. */
+    value |= BCR_CF_PWR;
+    break;
+
+  default:
+    printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+	   configure->vcc);
+    restore_flags(flags);
+    return -1;
+  }
+
+  value = (configure->reset) ? (value | BCR_CF_RST) : (value & ~BCR_CF_RST);
+
+  /* Silently ignore Vpp, output enable, speaker enable. */
+
+  BCR = BCR_value = value;
+
+  restore_flags(flags);
+
+  return 0;
+}
+
+struct pcmcia_low_level assabet_pcmcia_ops = { 
+  assabet_pcmcia_init,
+  assabet_pcmcia_shutdown,
+  assabet_pcmcia_socket_state,
+  assabet_pcmcia_get_irq_info,
+  assabet_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_cerf.c linux/drivers/pcmcia/sa1100_cerf.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_cerf.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_cerf.c	Thu Oct 11 09:43:29 2001
@@ -0,0 +1,150 @@
+/*
+ * drivers/pcmcia/sa1100_cerf.c
+ *
+ * PCMCIA implementation routines for CerfBoard
+ * Based off the Assabet.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+
+static int cerf_pcmcia_init(struct pcmcia_init *init){
+  int irq, res;
+
+  /* Enable CF bus: */
+//  BCR_clear(BCR_CF_BUS_OFF);
+
+  /* All those are inputs */
+  GPDR &= ~(GPIO_CF_CD | GPIO_CF_BVD2 | GPIO_CF_BVD1 | GPIO_CF_IRQ);
+
+  /* Set transition detect */
+  set_GPIO_IRQ_edge( GPIO_CF_CD|GPIO_CF_BVD2|GPIO_CF_BVD1, GPIO_BOTH_EDGES );
+  set_GPIO_IRQ_edge( GPIO_CF_IRQ, GPIO_FALLING_EDGE );
+
+  /* Register interrupts */
+  irq = IRQ_GPIO_CF_CD;
+  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_CD", NULL );
+  if( res < 0 ) goto irq_err;
+  irq = IRQ_GPIO_CF_BVD2;
+  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_BVD2", NULL );
+  if( res < 0 ) goto irq_err;
+  irq = IRQ_GPIO_CF_BVD1;
+  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_BVD1", NULL );
+  if( res < 0 ) goto irq_err;
+
+  /* There's only one slot, but it's "Slot 1": */
+  return 2;
+
+irq_err:
+  printk( KERN_ERR "%s: Request for IRQ %lu failed\n", __FUNCTION__, irq );
+  return -1;
+}
+
+static int cerf_pcmcia_shutdown(void)
+{
+  /* disable IRQs */
+  free_irq( IRQ_GPIO_CF_CD, NULL );
+  free_irq( IRQ_GPIO_CF_BVD2, NULL );
+  free_irq( IRQ_GPIO_CF_BVD1, NULL );
+  
+  /* Disable CF bus: */
+//  BCR_set(BCR_CF_BUS_OFF);
+
+  return 0;
+}
+
+static int cerf_pcmcia_socket_state(struct pcmcia_state_array
+				       *state_array){
+  unsigned long levels;
+
+  if(state_array->size<2) return -1;
+
+  memset(state_array->state, 0, 
+	 (state_array->size)*sizeof(struct pcmcia_state));
+
+  levels=GPLR;
+
+  state_array->state[1].detect=((levels & GPIO_CF_CD)==0)?1:0;
+
+  state_array->state[1].ready=(levels & GPIO_CF_IRQ)?1:0;
+
+  state_array->state[1].bvd1=(levels & GPIO_CF_BVD1)?1:0;
+
+  state_array->state[1].bvd2=(levels & GPIO_CF_BVD2)?1:0;
+
+  state_array->state[1].wrprot=0; /* Not available on Assabet. */
+
+  state_array->state[1].vs_3v=1;  /* Can only apply 3.3V on Assabet. */
+
+  state_array->state[1].vs_Xv=0;
+
+  return 1;
+}
+
+static int cerf_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+
+  if(info->sock>1) return -1;
+
+  if(info->sock==1)
+    info->irq=IRQ_GPIO_CF_IRQ;
+
+  return 0;
+}
+
+static int cerf_pcmcia_configure_socket(const struct pcmcia_configure
+					   *configure)
+{
+  unsigned long value, flags;
+
+  if(configure->sock>1) return -1;
+
+  if(configure->sock==0) return 0;
+
+  save_flags_cli(flags);
+
+//  value = BCR_value;
+
+  switch(configure->vcc){
+  case 0:
+//    value &= ~BCR_CF_PWR;
+    break;
+
+  case 50:
+    printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n",
+	   __FUNCTION__);
+
+  case 33:  /* Can only apply 3.3V to the CF slot. */
+//    value |= BCR_CF_PWR;
+    break;
+
+  default:
+    printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+	   configure->vcc);
+    restore_flags(flags);
+    return -1;
+  }
+
+//  value = (configure->reset) ? (value | BCR_CF_RST) : (value & ~BCR_CF_RST);
+
+  /* Silently ignore Vpp, output enable, speaker enable. */
+
+//  BCR = BCR_value = value;
+
+  restore_flags(flags);
+
+  return 0;
+}
+
+struct pcmcia_low_level cerf_pcmcia_ops = { 
+  cerf_pcmcia_init,
+  cerf_pcmcia_shutdown,
+  cerf_pcmcia_socket_state,
+  cerf_pcmcia_get_irq_info,
+  cerf_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_flexanet.c linux/drivers/pcmcia/sa1100_flexanet.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_flexanet.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_flexanet.c	Thu Oct 11 09:43:29 2001
@@ -0,0 +1,84 @@
+/*
+ * drivers/pcmcia/sa1100_flexanet.c
+ *
+ * PCMCIA implementation routines for Flexanet.
+ * by Jordi Colomer, 09/05/2001
+ *
+ * Yet to be defined.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+
+/*
+ * Socket initialization.
+ *
+ * Called by sa1100_pcmcia_driver_init on startup.
+ * Must return the number of slots.
+ *
+ */
+static int flexanet_pcmcia_init(struct pcmcia_init *init){
+
+  return 0;
+}
+
+
+/*
+ * Socket shutdown
+ *
+ */
+static int flexanet_pcmcia_shutdown(void)
+{
+  return 0;
+}
+
+
+/*
+ * Get the state of the sockets.
+ *
+ *  Sockets in Flexanet are 3.3V only, without BVD2.
+ *
+ */
+static int flexanet_pcmcia_socket_state(struct pcmcia_state_array
+				       *state_array){
+  return -1;
+}
+
+
+/*
+ * Return the IRQ information for a given socket number (the IRQ number)
+ *
+ */
+static int flexanet_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+
+  return -1;
+}
+
+
+/*
+ *
+ */
+static int flexanet_pcmcia_configure_socket(const struct pcmcia_configure
+					   *configure)
+{
+  return -1;
+}
+
+
+/*
+ * The set of socket operations
+ *
+ */
+struct pcmcia_low_level flexanet_pcmcia_ops = {
+  flexanet_pcmcia_init,
+  flexanet_pcmcia_shutdown,
+  flexanet_pcmcia_socket_state,
+  flexanet_pcmcia_get_irq_info,
+  flexanet_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_freebird.c linux/drivers/pcmcia/sa1100_freebird.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_freebird.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_freebird.c	Thu Oct 11 09:43:29 2001
@@ -0,0 +1,160 @@
+/*
+ * drivers/pcmcia/sa1100_freebird.c
+ *
+ * Created by Eric Peng <ericpeng@coventive.com>
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+
+static int freebird_pcmcia_init(struct pcmcia_init *init){
+  int irq, res;
+
+  /* Enable Linkup CF card */
+  LINKUP_PRC = 0xc0;
+  mdelay(100);
+  LINKUP_PRC = 0xc1;
+  mdelay(100);
+  LINKUP_PRC = 0xd1;
+  mdelay(100);
+  LINKUP_PRC = 0xd1;
+  mdelay(100);
+  LINKUP_PRC = 0xc0;
+
+  /* All those are inputs */
+  ////GPDR &= ~(GPIO_CF_CD | GPIO_CF_BVD2 | GPIO_CF_BVD1 | GPIO_CF_IRQ);
+  GPDR &= ~(GPIO_FREEBIRD_CF_CD | GPIO_FREEBIRD_CF_IRQ | GPIO_FREEBIRD_CF_BVD);
+
+  /* Set transition detect */
+  //set_GPIO_IRQ_edge( GPIO_CF_CD|GPIO_CF_BVD2|GPIO_CF_BVD1, GPIO_BOTH_EDGES );
+  //set_GPIO_IRQ_edge( GPIO_CF_IRQ, GPIO_FALLING_EDGE );
+  set_GPIO_IRQ_edge(GPIO_FREEBIRD_CF_CD|GPIO_FREEBIRD_CF_BVD,GPIO_BOTH_EDGES);
+  set_GPIO_IRQ_edge(GPIO_FREEBIRD_CF_IRQ, GPIO_FALLING_EDGE);
+
+  /* Register interrupts */
+  irq = IRQ_GPIO_FREEBIRD_CF_CD;
+  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_CD", NULL );
+  if( res < 0 ) goto irq_err;
+  irq = IRQ_GPIO_FREEBIRD_CF_BVD;
+  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_BVD1", NULL );
+  if( res < 0 ) goto irq_err;
+
+  /* There's only one slot, but it's "Slot 1": */
+  return 2;
+
+irq_err:
+  printk( KERN_ERR "%s: Request for IRQ %lu failed\n", __FUNCTION__, irq );
+  return -1;
+}
+
+static int freebird_pcmcia_shutdown(void)
+{
+  /* disable IRQs */
+  free_irq( IRQ_GPIO_FREEBIRD_CF_CD, NULL );
+  free_irq( IRQ_GPIO_FREEBIRD_CF_BVD, NULL );
+
+  /* Disable CF card */
+  LINKUP_PRC = 0x40;  /* SSP=1   SOE=0 */
+  mdelay(100);
+
+  return 0;
+}
+
+static int freebird_pcmcia_socket_state(struct pcmcia_state_array
+				       *state_array){
+  unsigned long levels;
+
+  if(state_array->size<2) return -1;
+
+  memset(state_array->state, 0,
+	 (state_array->size)*sizeof(struct pcmcia_state));
+
+  levels = LINKUP_PRS;
+//printk("LINKUP_PRS=%x \n",levels);
+
+  state_array->state[0].detect=
+    ((levels & (LINKUP_CD1 | LINKUP_CD2))==0)?1:0;
+
+  state_array->state[0].ready=(levels & LINKUP_RDY)?1:0;
+
+  state_array->state[0].bvd1=(levels & LINKUP_BVD1)?1:0;
+
+  state_array->state[0].bvd2=(levels & LINKUP_BVD2)?1:0;
+
+  state_array->state[0].wrprot=0; /* Not available on Assabet. */
+
+  state_array->state[0].vs_3v=1;  /* Can only apply 3.3V on Assabet. */
+
+  state_array->state[0].vs_Xv=0;
+
+  return 1;
+}
+
+static int freebird_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+
+  if(info->sock>1) return -1;
+
+  if(info->sock==0)
+    info->irq=IRQ_GPIO_FREEBIRD_CF_IRQ;
+
+  return 0;
+}
+
+static int freebird_pcmcia_configure_socket(const struct pcmcia_configure
+					   *configure)
+{
+  unsigned long value, flags;
+
+  if(configure->sock>1) return -1;
+
+  if(configure->sock==1) return 0;
+
+  save_flags_cli(flags);
+
+  value = 0xc0;   /* SSP=1  SOE=1  CFE=1 */
+
+  switch(configure->vcc){
+  case 0:
+
+    break;
+
+  case 50:
+    printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n",
+	   __FUNCTION__);
+
+  case 33:  /* Can only apply 3.3V to the CF slot. */
+    value |= LINKUP_S1;
+    break;
+
+  default:
+    printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+	   configure->vcc);
+    restore_flags(flags);
+    return -1;
+  }
+
+  if (configure->reset)
+  value = (configure->reset) ? (value | LINKUP_RESET) : (value & ~LINKUP_RESET);
+
+  /* Silently ignore Vpp, output enable, speaker enable. */
+
+  LINKUP_PRC = value;
+//printk("LINKUP_PRC=%x\n",value);
+  restore_flags(flags);
+
+  return 0;
+}
+
+struct pcmcia_low_level freebird_pcmcia_ops = {
+  freebird_pcmcia_init,
+  freebird_pcmcia_shutdown,
+  freebird_pcmcia_socket_state,
+  freebird_pcmcia_get_irq_info,
+  freebird_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_generic.c linux/drivers/pcmcia/sa1100_generic.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_generic.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_generic.c	Thu Oct 11 09:43:29 2001
@@ -0,0 +1,1168 @@
+/*======================================================================
+
+    Device driver for the PCMCIA control functionality of StrongARM
+    SA-1100 microprocessors.
+
+    The contents of this file are subject to the Mozilla Public
+    License Version 1.1 (the "License"); you may not use this file
+    except in compliance with the License. You may obtain a copy of
+    the License at http://www.mozilla.org/MPL/
+
+    Software distributed under the License is distributed on an "AS
+    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+    implied. See the License for the specific language governing
+    rights and limitations under the License.
+
+    The initial developer of the original code is John G. Dorsey
+    <john+@cs.cmu.edu>.  Portions created by John G. Dorsey are
+    Copyright (C) 1999 John G. Dorsey.  All Rights Reserved.
+
+    Alternatively, the contents of this file may be used under the
+    terms of the GNU Public License version 2 (the "GPL"), in which
+    case the provisions of the GPL are applicable instead of the
+    above.  If you wish to allow the use of your version of this file
+    only under the terms of the GPL and not to allow others to use
+    your version of this file under the MPL, indicate your decision
+    by deleting the provisions above and replace them with the notice
+    and other provisions required by the GPL.  If you do not delete
+    the provisions above, a recipient may use your version of this
+    file under either the MPL or the GPL.
+    
+======================================================================*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/tqueue.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/notifier.h>
+#include <linux/proc_fs.h>
+#include <linux/version.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/ss.h>
+#include <pcmcia/bus_ops.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#include "sa1100.h"
+
+#ifdef PCMCIA_DEBUG
+static int pc_debug;
+#endif
+
+MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
+MODULE_DESCRIPTION("Linux PCMCIA Card Services: SA-1100 Socket Controller");
+
+/* This structure maintains housekeeping state for each socket, such
+ * as the last known values of the card detect pins, or the Card Services
+ * callback value associated with the socket:
+ */
+static struct sa1100_pcmcia_socket 
+sa1100_pcmcia_socket[SA1100_PCMCIA_MAX_SOCK];
+
+static int sa1100_pcmcia_socket_count;
+
+
+/* Returned by the low-level PCMCIA interface: */
+static struct pcmcia_low_level *pcmcia_low_level;
+
+/* Event poll timer structure */
+static struct timer_list poll_timer;
+
+
+/* Prototypes for routines which are used internally: */
+
+static int  sa1100_pcmcia_driver_init(void);
+static void sa1100_pcmcia_driver_shutdown(void);
+static void sa1100_pcmcia_task_handler(void *data);
+static void sa1100_pcmcia_poll_event(unsigned long data);
+static void sa1100_pcmcia_interrupt(int irq, void *dev,
+				    struct pt_regs *regs);
+static struct tq_struct sa1100_pcmcia_task;
+
+#ifdef CONFIG_PROC_FS
+static int  sa1100_pcmcia_proc_status(char *buf, char **start, off_t pos,
+				      int count, int *eof, void *data);
+#endif
+
+
+/* Prototypes for operations which are exported to the
+ * new-and-impr^H^H^H^H^H^H^H^H^H^H in-kernel PCMCIA core:
+ */
+
+static int sa1100_pcmcia_init(unsigned int sock);
+static int sa1100_pcmcia_suspend(unsigned int sock);
+static int sa1100_pcmcia_register_callback(unsigned int sock,
+					   void (*handler)(void *, 
+							   unsigned int),
+					   void *info);
+static int sa1100_pcmcia_inquire_socket(unsigned int sock, 
+					socket_cap_t *cap);
+static int sa1100_pcmcia_get_status(unsigned int sock, u_int *value);
+static int sa1100_pcmcia_get_socket(unsigned int sock, 
+				    socket_state_t *state);
+static int sa1100_pcmcia_set_socket(unsigned int sock,
+				    socket_state_t *state);
+static int sa1100_pcmcia_get_io_map(unsigned int sock,
+				    struct pccard_io_map *io);
+static int sa1100_pcmcia_set_io_map(unsigned int sock,
+				    struct pccard_io_map *io);
+static int sa1100_pcmcia_get_mem_map(unsigned int sock,
+				     struct pccard_mem_map *mem);
+static int sa1100_pcmcia_set_mem_map(unsigned int sock,
+				     struct pccard_mem_map *mem);
+#ifdef CONFIG_PROC_FS
+static void sa1100_pcmcia_proc_setup(unsigned int sock,
+				     struct proc_dir_entry *base);
+#endif
+
+static struct pccard_operations sa1100_pcmcia_operations = {
+  sa1100_pcmcia_init,
+  sa1100_pcmcia_suspend,
+  sa1100_pcmcia_register_callback,
+  sa1100_pcmcia_inquire_socket,
+  sa1100_pcmcia_get_status,
+  sa1100_pcmcia_get_socket,
+  sa1100_pcmcia_set_socket,
+  sa1100_pcmcia_get_io_map,
+  sa1100_pcmcia_set_io_map,
+  sa1100_pcmcia_get_mem_map,
+  sa1100_pcmcia_set_mem_map,
+#ifdef CONFIG_PROC_FS
+  sa1100_pcmcia_proc_setup
+#endif
+};
+
+#ifdef CONFIG_CPU_FREQ
+/* forward declaration */
+static struct notifier_block sa1100_pcmcia_notifier_block;
+#endif
+
+
+/* sa1100_pcmcia_driver_init()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ *
+ * This routine performs a basic sanity check to ensure that this
+ * kernel has been built with the appropriate board-specific low-level
+ * PCMCIA support, performs low-level PCMCIA initialization, registers
+ * this socket driver with Card Services, and then spawns the daemon
+ * thread which is the real workhorse of the socket driver.
+ *
+ * Please see linux/Documentation/arm/SA1100/PCMCIA for more information
+ * on the low-level kernel interface.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+static int __init sa1100_pcmcia_driver_init(void){
+  servinfo_t info;
+  struct pcmcia_init pcmcia_init;
+  struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK];
+  struct pcmcia_state_array state_array;
+  unsigned int i, clock;
+  unsigned long mecr;
+
+  printk(KERN_INFO "SA-1100 PCMCIA (CS release %s)\n", CS_RELEASE);
+
+  CardServices(GetCardServicesInfo, &info);
+
+  if(info.Revision!=CS_RELEASE_CODE){
+    printk(KERN_ERR "Card Services release codes do not match\n");
+    return -1;
+  }
+
+  if(machine_is_assabet()){
+#ifdef CONFIG_SA1100_ASSABET
+    if(machine_has_neponset()){
+#ifdef CONFIG_ASSABET_NEPONSET
+      pcmcia_low_level=&neponset_pcmcia_ops;
+#else
+      printk(KERN_ERR "Card Services disabled: missing Neponset support\n");
+      return -1;
+#endif
+    }else{
+      pcmcia_low_level=&assabet_pcmcia_ops;
+    }
+#endif
+  } else if (machine_is_freebird()) {
+#ifdef CONFIG_SA1100_FREEBIRD
+    pcmcia_low_level = &freebird_pcmcia_ops;
+#endif
+  } else if (machine_is_h3600()) {
+#ifdef CONFIG_SA1100_H3600
+    pcmcia_low_level = &h3600_pcmcia_ops;
+#endif    
+  } else if (machine_is_cerf()) {
+#ifdef CONFIG_SA1100_CERF
+    pcmcia_low_level = &cerf_pcmcia_ops;
+#endif
+  } else if (machine_is_graphicsclient()) {
+#ifdef CONFIG_SA1100_GRAPHICSCLIENT
+    pcmcia_low_level = &gcplus_pcmcia_ops;
+#endif
+  } else if (machine_is_xp860()) {
+#ifdef CONFIG_SA1100_XP860
+    pcmcia_low_level = &xp860_pcmcia_ops;
+#endif
+  } else if (machine_is_yopy()) {
+#ifdef CONFIG_SA1100_YOPY
+    pcmcia_low_level = &yopy_pcmcia_ops;
+#endif
+  } else if (machine_is_pangolin()) {
+#ifdef CONFIG_SA1100_PANGOLIN
+    pcmcia_low_level = &pangolin_pcmcia_ops;
+#endif
+  } else if (machine_is_jornada720()) {
+#ifdef CONFIG_SA1100_JORNADA720
+    pcmcia_low_level = &jornada720_pcmcia_ops;
+#endif
+  } else if(machine_is_pfs168()){
+#ifdef CONFIG_SA1100_PFS168
+    pcmcia_low_level=&pfs168_pcmcia_ops;
+#endif
+  } else if(machine_is_flexanet()){
+#ifdef CONFIG_SA1100_FLEXANET
+    pcmcia_low_level=&flexanet_pcmcia_ops;
+#endif
+ } else if(machine_is_simpad()){
+#ifdef CONFIG_SA1100_SIMPAD
+    pcmcia_low_level=&simpad_pcmcia_ops;
+#endif
+  } else if(machine_is_graphicsmaster()) {
+#ifdef CONFIG_SA1100_GRAPHICSMASTER
+    pcmcia_low_level=&graphicsmaster_pcmcia_ops;
+#endif
+  } else if(machine_is_adsbitsy()) {
+#ifdef CONFIG_SA1100_ADSBITSY
+    pcmcia_low_level=&adsbitsy_pcmcia_ops;
+#endif
+  } else if(machine_is_stork()) {
+#ifdef CONFIG_SA1100_STORK
+    pcmcia_low_level=&stork_pcmcia_ops;
+#endif
+  }
+
+  if (!pcmcia_low_level) {
+    printk(KERN_ERR "This hardware is not supported by the SA1100 Card Service driver\n");
+    return -ENODEV;
+  }
+
+  pcmcia_init.handler=sa1100_pcmcia_interrupt;
+
+  if((sa1100_pcmcia_socket_count=pcmcia_low_level->init(&pcmcia_init))<0){
+    printk(KERN_ERR "Unable to initialize kernel PCMCIA service.\n");
+    return -EIO;
+  }
+
+  state_array.size=sa1100_pcmcia_socket_count;
+  state_array.state=state;
+
+  if(pcmcia_low_level->socket_state(&state_array)<0){
+    printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n");
+    return -EIO;
+  }
+
+  /* We initialize the MECR to default values here, because we are
+   * not guaranteed to see a SetIOMap operation at runtime.
+   */
+  mecr=0;
+
+  clock = get_cclk_frequency() * 100;
+
+  for(i=0; i<sa1100_pcmcia_socket_count; ++i){
+    sa1100_pcmcia_socket[i].k_state=state[i];
+
+    /* This is an interim fix. Apparently, SetSocket is no longer
+     * called to initialize each socket (prior to the first detect
+     * event). For now, we'll just manually set up the mask.
+     */
+    sa1100_pcmcia_socket[i].cs_state.csc_mask=SS_DETECT;
+
+    sa1100_pcmcia_socket[i].virt_io=(i==0)?PCMCIA_IO_0_BASE:PCMCIA_IO_1_BASE;
+    sa1100_pcmcia_socket[i].phys_attr=_PCMCIAAttr(i);
+    sa1100_pcmcia_socket[i].phys_mem=_PCMCIAMem(i);
+
+    MECR_FAST_SET(mecr, i, 0);
+    MECR_BSIO_SET(mecr, i,
+		  sa1100_pcmcia_mecr_bs(SA1100_PCMCIA_IO_ACCESS, clock));
+    MECR_BSA_SET(mecr, i,
+		 sa1100_pcmcia_mecr_bs(SA1100_PCMCIA_5V_MEM_ACCESS, clock));
+    MECR_BSM_SET(mecr, i,
+		 sa1100_pcmcia_mecr_bs(SA1100_PCMCIA_5V_MEM_ACCESS, clock));
+
+    sa1100_pcmcia_socket[i].speed_io=SA1100_PCMCIA_IO_ACCESS;
+    sa1100_pcmcia_socket[i].speed_attr=SA1100_PCMCIA_5V_MEM_ACCESS;
+    sa1100_pcmcia_socket[i].speed_mem=SA1100_PCMCIA_5V_MEM_ACCESS;
+  }
+
+  MECR=mecr;
+
+#ifdef CONFIG_CPU_FREQ
+  if(cpufreq_register_notifier(&sa1100_pcmcia_notifier_block) < 0){
+    printk(KERN_ERR "Unable to register CPU frequency change notifier\n");
+    return -ENXIO;
+  }
+#endif
+
+  /* Only advertise as many sockets as we can detect: */
+  if(register_ss_entry(sa1100_pcmcia_socket_count, 
+		       &sa1100_pcmcia_operations)<0){
+    printk(KERN_ERR "Unable to register socket service routine\n");
+    return -ENXIO;
+  }
+
+  /* Start the event poll timer.  It will reschedule by itself afterwards. */
+  sa1100_pcmcia_poll_event(0);
+
+  DEBUG(1, "sa1100: initialization complete\n");
+
+  return 0;
+
+}  /* sa1100_pcmcia_driver_init() */
+
+module_init(sa1100_pcmcia_driver_init);
+
+
+/* sa1100_pcmcia_driver_shutdown()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Invokes the low-level kernel service to free IRQs associated with this
+ * socket controller and reset GPIO edge detection.
+ */
+static void __exit sa1100_pcmcia_driver_shutdown(void){
+
+  del_timer_sync(&poll_timer);
+  unregister_ss_entry(&sa1100_pcmcia_operations);
+#ifdef CONFIG_CPU_FREQ
+  cpufreq_unregister_notifier(&sa1100_pcmcia_notifier_block);
+#endif
+  pcmcia_low_level->shutdown();
+  flush_scheduled_tasks();
+
+  DEBUG(1, "sa1100: shutdown complete\n");
+}
+
+module_exit(sa1100_pcmcia_driver_shutdown);
+
+
+/* sa1100_pcmcia_init()
+ * ^^^^^^^^^^^^^^^^^^^^
+ * We perform all of the interesting initialization tasks in 
+ * sa1100_pcmcia_driver_init().
+ *
+ * Returns: 0
+ */
+static int sa1100_pcmcia_init(unsigned int sock){
+  
+  DEBUG(2, "%s(): initializing socket %u\n", __FUNCTION__, sock);
+
+  return 0;
+}
+
+
+/* sa1100_pcmcia_suspend()
+ * ^^^^^^^^^^^^^^^^^^^^^^^
+ * We don't currently perform any actions on a suspend.
+ *
+ * Returns: 0
+ */
+static int sa1100_pcmcia_suspend(unsigned int sock){
+
+  DEBUG(2, "%s(): suspending socket %u\n", __FUNCTION__, sock);
+
+  return 0;
+}
+
+
+/* sa1100_pcmcia_events()
+ * ^^^^^^^^^^^^^^^^^^^^^^
+ * Helper routine to generate a Card Services event mask based on
+ * state information obtained from the kernel low-level PCMCIA layer
+ * in a recent (and previous) sampling. Updates `prev_state'.
+ *
+ * Returns: an event mask for the given socket state.
+ */
+static inline unsigned sa1100_pcmcia_events(struct pcmcia_state *state,
+					    struct pcmcia_state *prev_state,
+					    unsigned int mask,
+					    unsigned int flags){
+  unsigned int events=0;
+
+  if(state->detect!=prev_state->detect){
+
+    DEBUG(2, "%s(): card detect value %u\n", __FUNCTION__, state->detect);
+
+    events|=mask&SS_DETECT;
+  }
+
+  if(state->ready!=prev_state->ready){
+
+    DEBUG(2, "%s(): card ready value %u\n", __FUNCTION__, state->ready);
+
+    events|=mask&((flags&SS_IOCARD)?0:SS_READY);
+  }
+
+  if(state->bvd1!=prev_state->bvd1){
+
+    DEBUG(2, "%s(): card BVD1 value %u\n", __FUNCTION__, state->bvd1);
+
+    events|=mask&(flags&SS_IOCARD)?SS_STSCHG:SS_BATDEAD;
+  }
+
+  if(state->bvd2!=prev_state->bvd2){
+
+    DEBUG(2, "%s(): card BVD2 value %u\n", __FUNCTION__, state->bvd2);
+
+    events|=mask&(flags&SS_IOCARD)?0:SS_BATWARN;
+  }
+
+  DEBUG(2, "events: %s%s%s%s%s%s\n",
+	(events==0)?"<NONE>":"",
+	(events&SS_DETECT)?"DETECT ":"",
+	(events&SS_READY)?"READY ":"",
+	(events&SS_BATDEAD)?"BATDEAD ":"",
+	(events&SS_BATWARN)?"BATWARN ":"",
+	(events&SS_STSCHG)?"STSCHG ":"");
+
+  *prev_state=*state;
+
+  return events;
+
+}  /* sa1100_pcmcia_events() */
+
+
+/* sa1100_pcmcia_task_handler()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Processes serviceable socket events using the "eventd" thread context.
+ *
+ * Event processing (specifically, the invocation of the Card Services event
+ * callback) occurs in this thread rather than in the actual interrupt
+ * handler due to the use of scheduling operations in the PCMCIA core.
+ */
+static void sa1100_pcmcia_task_handler(void *data) {
+  struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK];
+  struct pcmcia_state_array state_array;
+  int i, events, all_events, irq_status;
+
+  DEBUG(2, "%s(): entering PCMCIA monitoring thread\n", __FUNCTION__);
+
+  state_array.size=sa1100_pcmcia_socket_count;
+  state_array.state=state;
+
+  do {
+
+    DEBUG(3, "%s(): interrogating low-level PCMCIA service\n", __FUNCTION__);
+
+    if((irq_status=pcmcia_low_level->socket_state(&state_array))<0)
+      printk(KERN_ERR "Error in kernel low-level PCMCIA service.\n");
+
+    all_events=0;
+
+    if(irq_status>0){
+
+      for(i=0; i<state_array.size; ++i, all_events|=events)
+	if((events=
+	    sa1100_pcmcia_events(&state[i],
+				 &sa1100_pcmcia_socket[i].k_state,
+				 sa1100_pcmcia_socket[i].cs_state.csc_mask,
+				 sa1100_pcmcia_socket[i].cs_state.flags)))
+	  if(sa1100_pcmcia_socket[i].handler!=NULL)
+	    sa1100_pcmcia_socket[i].handler(sa1100_pcmcia_socket[i].handler_info,
+					    events);
+    }
+
+  } while(all_events);
+}  /* sa1100_pcmcia_task_handler() */
+
+static struct tq_struct sa1100_pcmcia_task = {
+	routine: sa1100_pcmcia_task_handler
+};
+
+
+/* sa1100_pcmcia_poll_event()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Let's poll for events in addition to IRQs since IRQ only is unreliable...
+ */
+static void sa1100_pcmcia_poll_event(unsigned long dummy)
+{
+  DEBUG(3, "%s(): polling for events\n", __FUNCTION__);
+  poll_timer.function = sa1100_pcmcia_poll_event;
+  poll_timer.expires = jiffies + SA1100_PCMCIA_POLL_PERIOD;
+  add_timer(&poll_timer);
+  schedule_task(&sa1100_pcmcia_task);
+}
+
+
+/* sa1100_pcmcia_interrupt()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Service routine for socket driver interrupts (requested by the
+ * low-level PCMCIA init() operation via sa1100_pcmcia_thread()).
+ * The actual interrupt-servicing work is performed by
+ * sa1100_pcmcia_thread(), largely because the Card Services event-
+ * handling code performs scheduling operations which cannot be
+ * executed from within an interrupt context.
+ */
+static void sa1100_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs){
+  DEBUG(3, "%s(): servicing IRQ %d\n", __FUNCTION__, irq);
+  schedule_task(&sa1100_pcmcia_task);
+}
+
+
+/* sa1100_pcmcia_register_callback()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the register_callback() operation for the in-kernel
+ * PCMCIA service (formerly SS_RegisterCallback in Card Services). If 
+ * the function pointer `handler' is not NULL, remember the callback 
+ * location in the state for `sock', and increment the usage counter 
+ * for the driver module. (The callback is invoked from the interrupt
+ * service routine, sa1100_pcmcia_interrupt(), to notify Card Services
+ * of interesting events.) Otherwise, clear the callback pointer in the
+ * socket state and decrement the module usage count.
+ *
+ * Returns: 0
+ */
+static int sa1100_pcmcia_register_callback(unsigned int sock,
+					   void (*handler)(void *,
+							   unsigned int),
+					   void *info){
+  if(handler==NULL){
+    sa1100_pcmcia_socket[sock].handler=NULL;
+    MOD_DEC_USE_COUNT;
+  } else {
+    MOD_INC_USE_COUNT;
+    sa1100_pcmcia_socket[sock].handler=handler;
+    sa1100_pcmcia_socket[sock].handler_info=info;
+  }
+
+  return 0;
+}
+
+
+/* sa1100_pcmcia_inquire_socket()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the inquire_socket() operation for the in-kernel PCMCIA
+ * service (formerly SS_InquireSocket in Card Services). Of note is
+ * the setting of the SS_CAP_PAGE_REGS bit in the `features' field of
+ * `cap' to "trick" Card Services into tolerating large "I/O memory" 
+ * addresses. Also set is SS_CAP_STATIC_MAP, which disables the memory
+ * resource database check. (Mapped memory is set up within the socket
+ * driver itself.)
+ *
+ * In conjunction with the STATIC_MAP capability is a new field,
+ * `io_offset', recommended by David Hinds. Rather than go through
+ * the SetIOMap interface (which is not quite suited for communicating
+ * window locations up from the socket driver), we just pass up
+ * an offset which is applied to client-requested base I/O addresses
+ * in alloc_io_space().
+ *
+ * Returns: 0 on success, -1 if no pin has been configured for `sock'
+ */
+static int sa1100_pcmcia_inquire_socket(unsigned int sock,
+					socket_cap_t *cap){
+  struct pcmcia_irq_info irq_info;
+
+  DEBUG(3, "%s() for sock %u\n", __FUNCTION__, sock);
+
+  if(sock>=sa1100_pcmcia_socket_count){
+    printk(KERN_ERR "sa1100: socket %u not configured\n", sock);
+    return -1;
+  }
+
+  /* SS_CAP_PAGE_REGS: used by setup_cis_mem() in cistpl.c to set the
+   *   force_low argument to validate_mem() in rsrc_mgr.c -- since in
+   *   general, the mapped * addresses of the PCMCIA memory regions
+   *   will not be within 0xffff, setting force_low would be
+   *   undesirable.
+   *
+   * SS_CAP_STATIC_MAP: don't bother with the (user-configured) memory
+   *   resource database; we instead pass up physical address ranges
+   *   and allow other parts of Card Services to deal with remapping.
+   *
+   * SS_CAP_PCCARD: we can deal with 16-bit PCMCIA & CF cards, but
+   *   not 32-bit CardBus devices.
+   */
+  cap->features=(SS_CAP_PAGE_REGS  | SS_CAP_STATIC_MAP | SS_CAP_PCCARD);
+
+  irq_info.sock=sock;
+  irq_info.irq=-1;
+
+  if(pcmcia_low_level->get_irq_info(&irq_info)<0){
+    printk(KERN_ERR "Error obtaining IRQ info from kernel for socket %u\n",
+	   sock);
+    return -1;
+  }
+
+  cap->irq_mask=0;
+  cap->map_size=PAGE_SIZE;
+  cap->pci_irq=irq_info.irq;
+  cap->io_offset=sa1100_pcmcia_socket[sock].virt_io;
+
+  return 0;
+
+}  /* sa1100_pcmcia_inquire_socket() */
+
+
+/* sa1100_pcmcia_get_status()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the get_status() operation for the in-kernel PCMCIA
+ * service (formerly SS_GetStatus in Card Services). Essentially just
+ * fills in bits in `status' according to internal driver state or
+ * the value of the voltage detect chipselect register.
+ *
+ * As a debugging note, during card startup, the PCMCIA core issues
+ * three set_socket() commands in a row the first with RESET deasserted,
+ * the second with RESET asserted, and the last with RESET deasserted
+ * again. Following the third set_socket(), a get_status() command will
+ * be issued. The kernel is looking for the SS_READY flag (see
+ * setup_socket(), reset_socket(), and unreset_socket() in cs.c).
+ *
+ * Returns: 0
+ */
+static int sa1100_pcmcia_get_status(unsigned int sock,
+				    unsigned int *status){
+  struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK];
+  struct pcmcia_state_array state_array;
+
+  DEBUG(3, "%s() for sock %u\n", __FUNCTION__, sock);
+
+  state_array.size=sa1100_pcmcia_socket_count;
+  state_array.state=state;
+
+  if((pcmcia_low_level->socket_state(&state_array))<0){
+    printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n");
+    return -1;
+  }
+
+  sa1100_pcmcia_socket[sock].k_state=state[sock];
+
+  *status=state[sock].detect?SS_DETECT:0;
+
+  *status|=state[sock].ready?SS_READY:0;
+
+  /* The power status of individual sockets is not available
+   * explicitly from the hardware, so we just remember the state
+   * and regurgitate it upon request:
+   */
+  *status|=sa1100_pcmcia_socket[sock].cs_state.Vcc?SS_POWERON:0;
+
+  if(sa1100_pcmcia_socket[sock].cs_state.flags&SS_IOCARD)
+    *status|=state[sock].bvd1?SS_STSCHG:0;
+  else {
+    if(state[sock].bvd1==0)
+      *status|=SS_BATDEAD;
+    else if(state[sock].bvd2==0)
+      *status|=SS_BATWARN;
+  }
+
+  *status|=state[sock].vs_3v?SS_3VCARD:0;
+
+  *status|=state[sock].vs_Xv?SS_XVCARD:0;
+
+  DEBUG(3, "\tstatus: %s%s%s%s%s%s%s%s\n",
+	(*status&SS_DETECT)?"DETECT ":"",
+	(*status&SS_READY)?"READY ":"", 
+	(*status&SS_BATDEAD)?"BATDEAD ":"",
+	(*status&SS_BATWARN)?"BATWARN ":"",
+	(*status&SS_POWERON)?"POWERON ":"",
+	(*status&SS_STSCHG)?"STSCHG ":"",
+	(*status&SS_3VCARD)?"3VCARD ":"",
+	(*status&SS_XVCARD)?"XVCARD ":"");
+
+  return 0;
+
+}  /* sa1100_pcmcia_get_status() */
+
+
+/* sa1100_pcmcia_get_socket()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the get_socket() operation for the in-kernel PCMCIA
+ * service (formerly SS_GetSocket in Card Services). Not a very 
+ * exciting routine.
+ *
+ * Returns: 0
+ */
+static int sa1100_pcmcia_get_socket(unsigned int sock,
+				    socket_state_t *state){
+
+  DEBUG(3, "%s() for sock %u\n", __FUNCTION__, sock);
+
+  /* This information was given to us in an earlier call to set_socket(),
+   * so we're just regurgitating it here:
+   */
+  *state=sa1100_pcmcia_socket[sock].cs_state;
+
+  return 0;
+}
+
+
+/* sa1100_pcmcia_set_socket()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the set_socket() operation for the in-kernel PCMCIA
+ * service (formerly SS_SetSocket in Card Services). We more or
+ * less punt all of this work and let the kernel handle the details
+ * of power configuration, reset, &c. We also record the value of
+ * `state' in order to regurgitate it to the PCMCIA core later.
+ *
+ * Returns: 0
+ */
+static int sa1100_pcmcia_set_socket(unsigned int sock,
+				    socket_state_t *state){
+  struct pcmcia_configure configure;
+
+  DEBUG(3, "%s() for sock %u\n", __FUNCTION__, sock);
+
+  DEBUG(3, "\tmask:  %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n"
+	"\tVcc %d  Vpp %d  irq %d\n",
+	(state->csc_mask==0)?"<NONE>":"",
+	(state->csc_mask&SS_DETECT)?"DETECT ":"",
+	(state->csc_mask&SS_READY)?"READY ":"",
+	(state->csc_mask&SS_BATDEAD)?"BATDEAD ":"",
+	(state->csc_mask&SS_BATWARN)?"BATWARN ":"",
+	(state->csc_mask&SS_STSCHG)?"STSCHG ":"",
+	(state->flags==0)?"<NONE>":"",
+	(state->flags&SS_PWR_AUTO)?"PWR_AUTO ":"",
+	(state->flags&SS_IOCARD)?"IOCARD ":"",
+	(state->flags&SS_RESET)?"RESET ":"",
+	(state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"",
+	(state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"",
+	state->Vcc, state->Vpp, state->io_irq);
+
+  configure.sock=sock;
+  configure.vcc=state->Vcc;
+  configure.vpp=state->Vpp;
+  configure.output=(state->flags&SS_OUTPUT_ENA)?1:0;
+  configure.speaker=(state->flags&SS_SPKR_ENA)?1:0;
+  configure.reset=(state->flags&SS_RESET)?1:0;
+
+  if(pcmcia_low_level->configure_socket(&configure)<0){
+    printk(KERN_ERR "Unable to configure socket %u\n", sock);
+    return -1;
+  }
+
+  sa1100_pcmcia_socket[sock].cs_state=*state;
+  
+  return 0;
+
+}  /* sa1100_pcmcia_set_socket() */
+
+
+/* sa1100_pcmcia_get_io_map()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the get_io_map() operation for the in-kernel PCMCIA
+ * service (formerly SS_GetIOMap in Card Services). Just returns an
+ * I/O map descriptor which was assigned earlier by a set_io_map().
+ *
+ * Returns: 0 on success, -1 if the map index was out of range
+ */
+static int sa1100_pcmcia_get_io_map(unsigned int sock,
+				    struct pccard_io_map *map){
+
+  DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
+
+  if(map->map>=MAX_IO_WIN){
+    printk(KERN_ERR "%s(): map (%d) out of range\n", __FUNCTION__,
+	   map->map);
+    return -1;
+  }
+
+  *map=sa1100_pcmcia_socket[sock].io_map[map->map];
+
+  return 0;
+}
+
+
+/* sa1100_pcmcia_set_io_map()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the set_io_map() operation for the in-kernel PCMCIA
+ * service (formerly SS_SetIOMap in Card Services). We configure
+ * the map speed as requested, but override the address ranges
+ * supplied by Card Services.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+static int sa1100_pcmcia_set_io_map(unsigned int sock,
+				    struct pccard_io_map *map){
+  unsigned int clock, speed;
+  unsigned long mecr, start;
+
+  DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
+
+  DEBUG(4, "\tmap %u  speed %u\n\tstart 0x%08lx  stop 0x%08lx\n"
+	"\tflags: %s%s%s%s%s%s%s%s\n",
+	map->map, map->speed, map->start, map->stop,
+	(map->flags==0)?"<NONE>":"",
+	(map->flags&MAP_ACTIVE)?"ACTIVE ":"",
+	(map->flags&MAP_16BIT)?"16BIT ":"",
+	(map->flags&MAP_AUTOSZ)?"AUTOSZ ":"",
+	(map->flags&MAP_0WS)?"0WS ":"",
+	(map->flags&MAP_WRPROT)?"WRPROT ":"",
+	(map->flags&MAP_USE_WAIT)?"USE_WAIT ":"",
+	(map->flags&MAP_PREFETCH)?"PREFETCH ":"");
+
+  if(map->map>=MAX_IO_WIN){
+    printk(KERN_ERR "%s(): map (%d) out of range\n", __FUNCTION__,
+	   map->map);
+    return -1;
+  }
+
+  if(map->flags&MAP_ACTIVE){
+
+    speed=(map->speed>0)?map->speed:SA1100_PCMCIA_IO_ACCESS;
+
+    clock = get_cclk_frequency() * 100;
+
+    mecr=MECR;
+
+    MECR_BSIO_SET(mecr, sock, sa1100_pcmcia_mecr_bs(speed, clock));
+
+    sa1100_pcmcia_socket[sock].speed_io=speed;
+
+    DEBUG(4, "%s(): FAST%u %lx  BSM%u %lx  BSA%u %lx  BSIO%u %lx\n",
+	  __FUNCTION__, sock, MECR_FAST_GET(mecr, sock), sock,
+	  MECR_BSM_GET(mecr, sock), sock, MECR_BSA_GET(mecr, sock), 
+	  sock, MECR_BSIO_GET(mecr, sock));
+
+    MECR=mecr;
+
+  }
+
+  start=map->start;
+
+  if(map->stop==1)
+    map->stop=PAGE_SIZE-1;
+
+  map->start=sa1100_pcmcia_socket[sock].virt_io;
+  map->stop=map->start+(map->stop-start);
+
+  sa1100_pcmcia_socket[sock].io_map[map->map]=*map;
+
+  return 0;
+
+}  /* sa1100_pcmcia_set_io_map() */
+
+
+/* sa1100_pcmcia_get_mem_map()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the get_mem_map() operation for the in-kernel PCMCIA
+ * service (formerly SS_GetMemMap in Card Services). Just returns a
+ *  memory map descriptor which was assigned earlier by a
+ *  set_mem_map() request.
+ *
+ * Returns: 0 on success, -1 if the map index was out of range
+ */
+static int sa1100_pcmcia_get_mem_map(unsigned int sock,
+				     struct pccard_mem_map *map){
+
+  DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
+
+  if(map->map>=MAX_WIN){
+    printk(KERN_ERR "%s(): map (%d) out of range\n", __FUNCTION__,
+	   map->map);
+    return -1;
+  }
+
+  *map=sa1100_pcmcia_socket[sock].mem_map[map->map];
+
+  return 0;
+}
+
+
+/* sa1100_pcmcia_set_mem_map()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the set_mem_map() operation for the in-kernel PCMCIA
+ * service (formerly SS_SetMemMap in Card Services). We configure
+ * the map speed as requested, but override the address ranges
+ * supplied by Card Services.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+static int sa1100_pcmcia_set_mem_map(unsigned int sock,
+				     struct pccard_mem_map *map){
+  unsigned int clock, speed;
+  unsigned long mecr, start;
+
+  DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
+
+  DEBUG(4, "\tmap %u  speed %u\n\tsys_start  %#lx\n"
+	"\tsys_stop   %#lx\n\tcard_start %#x\n"
+	"\tflags: %s%s%s%s%s%s%s%s\n",
+	map->map, map->speed, map->sys_start, map->sys_stop,
+	map->card_start, (map->flags==0)?"<NONE>":"",
+	(map->flags&MAP_ACTIVE)?"ACTIVE ":"",
+	(map->flags&MAP_16BIT)?"16BIT ":"",
+	(map->flags&MAP_AUTOSZ)?"AUTOSZ ":"",
+	(map->flags&MAP_0WS)?"0WS ":"",
+	(map->flags&MAP_WRPROT)?"WRPROT ":"",
+	(map->flags&MAP_ATTRIB)?"ATTRIB ":"",
+	(map->flags&MAP_USE_WAIT)?"USE_WAIT ":"");
+
+  if(map->map>=MAX_WIN){
+    printk(KERN_ERR "%s(): map (%d) out of range\n", __FUNCTION__,
+	   map->map);
+    return -1;
+  }
+
+  if(map->flags&MAP_ACTIVE){
+
+    /* When clients issue RequestMap, the access speed is not always
+     * properly configured:
+     */
+    if(map->speed > 0)
+      speed = map->speed;
+    else
+      switch(sa1100_pcmcia_socket[sock].cs_state.Vcc){
+      case 33:
+	speed = SA1100_PCMCIA_3V_MEM_ACCESS;
+	break;
+      default:
+	speed = SA1100_PCMCIA_5V_MEM_ACCESS;
+      }
+
+    clock = get_cclk_frequency() * 100;
+    
+    mecr=MECR;
+    
+    if(map->flags&MAP_ATTRIB){
+
+      MECR_BSA_SET(mecr, sock, sa1100_pcmcia_mecr_bs(speed, clock));
+      sa1100_pcmcia_socket[sock].speed_attr=speed;
+
+    } else {
+
+      MECR_BSM_SET(mecr, sock, sa1100_pcmcia_mecr_bs(speed, clock));
+      sa1100_pcmcia_socket[sock].speed_mem=speed;
+
+    }
+    
+    DEBUG(4, "%s(): FAST%u %lx  BSM%u %lx  BSA%u %lx  BSIO%u %lx\n",
+	  __FUNCTION__, sock, MECR_FAST_GET(mecr, sock), sock,
+	  MECR_BSM_GET(mecr, sock), sock, MECR_BSA_GET(mecr, sock), 
+	  sock, MECR_BSIO_GET(mecr, sock));
+    
+    MECR=mecr;
+
+  }
+
+  start=map->sys_start;
+
+  if(map->sys_stop==0)
+    map->sys_stop=PAGE_SIZE-1;
+
+  map->sys_start=(map->flags & MAP_ATTRIB)?\
+    sa1100_pcmcia_socket[sock].phys_attr:\
+    sa1100_pcmcia_socket[sock].phys_mem;
+
+  map->sys_stop=map->sys_start+(map->sys_stop-start);
+
+  sa1100_pcmcia_socket[sock].mem_map[map->map]=*map;
+
+  return 0;
+
+}  /* sa1100_pcmcia_set_mem_map() */
+
+
+#if defined(CONFIG_PROC_FS)
+
+/* sa1100_pcmcia_proc_setup()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the proc_setup() operation for the in-kernel PCMCIA
+ * service (formerly SS_ProcSetup in Card Services).
+ *
+ * Returns: 0 on success, -1 on error
+ */
+static void sa1100_pcmcia_proc_setup(unsigned int sock,
+				     struct proc_dir_entry *base){
+  struct proc_dir_entry *entry;
+
+  DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
+
+  if((entry=create_proc_entry("status", 0, base))==NULL){
+    printk(KERN_ERR "Unable to install \"status\" procfs entry\n");
+    return;
+  }
+
+  entry->read_proc=sa1100_pcmcia_proc_status;
+  entry->data=(void *)sock;
+}
+
+
+/* sa1100_pcmcia_proc_status()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the /proc/bus/pccard/??/status file.
+ *
+ * Returns: the number of characters added to the buffer
+ */
+static int sa1100_pcmcia_proc_status(char *buf, char **start, off_t pos,
+				     int count, int *eof, void *data){
+  char *p=buf;
+  unsigned int sock=(unsigned int)data;
+  unsigned int clock = get_cclk_frequency() * 100;
+  unsigned long mecr = MECR;
+
+  p+=sprintf(p, "k_flags  : %s%s%s%s%s%s%s\n", 
+	     sa1100_pcmcia_socket[sock].k_state.detect?"detect ":"",
+	     sa1100_pcmcia_socket[sock].k_state.ready?"ready ":"",
+	     sa1100_pcmcia_socket[sock].k_state.bvd1?"bvd1 ":"",
+	     sa1100_pcmcia_socket[sock].k_state.bvd2?"bvd2 ":"",
+	     sa1100_pcmcia_socket[sock].k_state.wrprot?"wrprot ":"",
+	     sa1100_pcmcia_socket[sock].k_state.vs_3v?"vs_3v ":"",
+	     sa1100_pcmcia_socket[sock].k_state.vs_Xv?"vs_Xv ":"");
+
+  p+=sprintf(p, "status   : %s%s%s%s%s%s%s%s%s\n",
+	     sa1100_pcmcia_socket[sock].k_state.detect?"SS_DETECT ":"",
+	     sa1100_pcmcia_socket[sock].k_state.ready?"SS_READY ":"",
+	     sa1100_pcmcia_socket[sock].cs_state.Vcc?"SS_POWERON ":"",
+	     sa1100_pcmcia_socket[sock].cs_state.flags&SS_IOCARD?\
+	     "SS_IOCARD ":"",
+	     (sa1100_pcmcia_socket[sock].cs_state.flags&SS_IOCARD &&
+	      sa1100_pcmcia_socket[sock].k_state.bvd1)?"SS_STSCHG ":"",
+	     ((sa1100_pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 &&
+	      (sa1100_pcmcia_socket[sock].k_state.bvd1==0))?"SS_BATDEAD ":"",
+	     ((sa1100_pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 &&
+	      (sa1100_pcmcia_socket[sock].k_state.bvd2==0))?"SS_BATWARN ":"",
+	     sa1100_pcmcia_socket[sock].k_state.vs_3v?"SS_3VCARD ":"",
+	     sa1100_pcmcia_socket[sock].k_state.vs_Xv?"SS_XVCARD ":"");
+
+  p+=sprintf(p, "mask     : %s%s%s%s%s\n",
+	     sa1100_pcmcia_socket[sock].cs_state.csc_mask&SS_DETECT?\
+	     "SS_DETECT ":"",
+	     sa1100_pcmcia_socket[sock].cs_state.csc_mask&SS_READY?\
+	     "SS_READY ":"",
+	     sa1100_pcmcia_socket[sock].cs_state.csc_mask&SS_BATDEAD?\
+	     "SS_BATDEAD ":"",
+	     sa1100_pcmcia_socket[sock].cs_state.csc_mask&SS_BATWARN?\
+	     "SS_BATWARN ":"",
+	     sa1100_pcmcia_socket[sock].cs_state.csc_mask&SS_STSCHG?\
+	     "SS_STSCHG ":"");
+
+  p+=sprintf(p, "cs_flags : %s%s%s%s%s\n",
+	     sa1100_pcmcia_socket[sock].cs_state.flags&SS_PWR_AUTO?\
+	     "SS_PWR_AUTO ":"",
+	     sa1100_pcmcia_socket[sock].cs_state.flags&SS_IOCARD?\
+	     "SS_IOCARD ":"",
+	     sa1100_pcmcia_socket[sock].cs_state.flags&SS_RESET?\
+	     "SS_RESET ":"",
+	     sa1100_pcmcia_socket[sock].cs_state.flags&SS_SPKR_ENA?\
+	     "SS_SPKR_ENA ":"",
+	     sa1100_pcmcia_socket[sock].cs_state.flags&SS_OUTPUT_ENA?\
+	     "SS_OUTPUT_ENA ":"");
+
+  p+=sprintf(p, "Vcc      : %d\n", sa1100_pcmcia_socket[sock].cs_state.Vcc);
+
+  p+=sprintf(p, "Vpp      : %d\n", sa1100_pcmcia_socket[sock].cs_state.Vpp);
+
+  p+=sprintf(p, "irq      : %d\n", sa1100_pcmcia_socket[sock].cs_state.io_irq);
+
+  p+=sprintf(p, "I/O      : %u (%u)\n", sa1100_pcmcia_socket[sock].speed_io,
+	     sa1100_pcmcia_cmd_time(clock, MECR_BSIO_GET(mecr, sock)));
+
+  p+=sprintf(p, "attribute: %u (%u)\n", sa1100_pcmcia_socket[sock].speed_attr,
+	     sa1100_pcmcia_cmd_time(clock, MECR_BSA_GET(mecr, sock)));
+
+  p+=sprintf(p, "common   : %u (%u)\n", sa1100_pcmcia_socket[sock].speed_mem,
+	     sa1100_pcmcia_cmd_time(clock, MECR_BSM_GET(mecr, sock)));
+
+  return p-buf;
+}
+
+#endif  /* defined(CONFIG_PROC_FS) */
+
+
+#ifdef CONFIG_CPU_FREQ
+
+/* sa1100_pcmcia_update_mecr()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * When sa1100_pcmcia_notifier() decides that a MECR adjustment (due
+ * to a core clock frequency change) is needed, this routine establishes
+ * new BS_xx values consistent with the clock speed `clock'.
+ */
+static void sa1100_pcmcia_update_mecr(unsigned int clock){
+  unsigned int sock;
+  unsigned long mecr = MECR;
+
+  for(sock = 0; sock < SA1100_PCMCIA_MAX_SOCK; ++sock){
+
+    MECR_BSIO_SET(mecr, sock,
+		  sa1100_pcmcia_mecr_bs(sa1100_pcmcia_socket[sock].speed_io,
+					clock));
+    MECR_BSA_SET(mecr, sock,
+		 sa1100_pcmcia_mecr_bs(sa1100_pcmcia_socket[sock].speed_attr,
+				       clock));
+    MECR_BSM_SET(mecr, sock,
+		 sa1100_pcmcia_mecr_bs(sa1100_pcmcia_socket[sock].speed_mem,
+				       clock));
+  }
+
+  MECR = mecr;
+
+}
+
+/* sa1100_pcmcia_notifier()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^
+ * When changing the processor core clock frequency, it is necessary
+ * to adjust the MECR timings accordingly. We've recorded the timings
+ * requested by Card Services, so this is just a matter of finding
+ * out what our current speed is, and then recomputing the new MECR
+ * values.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+static int sa1100_pcmcia_notifier(struct notifier_block *nb,
+				  unsigned long val, void *data){
+  struct cpufreq_info *ci = data;
+
+  switch(val){
+  case CPUFREQ_MINMAX:
+
+    break;
+
+  case CPUFREQ_PRECHANGE:
+
+    if(ci->new_freq > ci->old_freq){
+      DEBUG(2, "%s(): new frequency %u.%uMHz > %u.%uMHz, pre-updating\n",
+	    __FUNCTION__,
+	    ci->new_freq / 1000, (ci->new_freq / 100) % 10,
+	    ci->old_freq / 1000, (ci->old_freq / 100) % 10);
+      sa1100_pcmcia_update_mecr(ci->new_freq);
+    }
+
+    break;
+
+  case CPUFREQ_POSTCHANGE:
+
+    if(ci->new_freq < ci->old_freq){
+      DEBUG(2, "%s(): new frequency %u.%uMHz < %u.%uMHz, post-updating\n",
+	    __FUNCTION__,
+	    ci->new_freq / 1000, (ci->new_freq / 100) % 10,
+	    ci->old_freq / 1000, (ci->old_freq / 100) % 10);
+      sa1100_pcmcia_update_mecr(ci->new_freq);
+    }
+
+    break;
+
+  default:
+    printk(KERN_ERR "%s(): unknown CPU frequency event %lx\n", __FUNCTION__,
+	   val);
+    return -1;
+
+  }
+
+  return 0;
+
+}
+
+static struct notifier_block sa1100_pcmcia_notifier_block = {
+  notifier_call: sa1100_pcmcia_notifier
+};
+
+#endif
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_graphicsclient.c linux/drivers/pcmcia/sa1100_graphicsclient.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_graphicsclient.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_graphicsclient.c	Thu Oct 11 09:43:29 2001
@@ -0,0 +1,154 @@
+/*
+ * drivers/pcmcia/sa1100_graphicsclient.c
+ *
+ * PCMCIA implementation routines for Graphics Client Plus
+ *
+ * 9/12/01   Woojung
+ *    Turn power OFF at startup
+ * 1/31/2001 Woojung Huh
+ *    Fix for GC Plus PCMCIA Reset Problem
+ * 2/27/2001 Woojung Huh [whuh@applieddata.net]
+ *    Fix
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+#define	S0_CD_IRQ		60				// Socket 0 Card Detect IRQ
+#define	S0_STS_IRQ		55				// Socket 0 PCMCIA IRQ
+
+static volatile unsigned long *PCMCIA_Status = 
+		((volatile unsigned long *) ADS_p2v(_ADS_CS_STATUS));
+
+static volatile unsigned long *PCMCIA_Power = 
+		((volatile unsigned long *) ADS_p2v(_ADS_CS_PR));
+
+static int gcplus_pcmcia_init(struct pcmcia_init *init)
+{
+  int irq, res;
+
+  // Reset PCMCIA
+  // Reset Timing for CPLD(U2) version 8001E or later
+  *PCMCIA_Power &= ~ ADS_CS_PR_A_RESET;
+  udelay(12);			// 12 uSec
+
+  *PCMCIA_Power |= ADS_CS_PR_A_RESET;
+  mdelay(30);			// 30 mSec
+
+  // Turn off 5V
+  *PCMCIA_Power &= ~0x03;
+
+  /* Register interrupts */
+  irq = S0_CD_IRQ;
+  res = request_irq(irq, init->handler, SA_INTERRUPT, "PCMCIA 0 CD", NULL);
+  if (res < 0) {
+	  printk(KERN_ERR "%s: Request for IRQ %lu failed\n", __FUNCTION__, irq);
+	  return	-1;
+  }
+
+  return 1;			// 1 PCMCIA Slot
+}
+
+static int gcplus_pcmcia_shutdown(void)
+{
+  /* disable IRQs */
+  free_irq( S0_CD_IRQ, NULL);
+  
+  /* Shutdown PCMCIA power */
+  mdelay(2);						// 2msec
+  *PCMCIA_Power &= ~0x03;
+
+  return 0;
+}
+
+static int gcplus_pcmcia_socket_state(struct pcmcia_state_array
+				       *state_array){
+  unsigned long levels;
+
+  if(state_array->size<1) return -1;
+
+  memset(state_array->state, 0, 
+	 (state_array->size)*sizeof(struct pcmcia_state));
+
+  levels=*PCMCIA_Status;
+
+  state_array->state[0].detect=(levels & ADS_CS_ST_A_CD)?1:0;
+  state_array->state[0].ready=(levels & ADS_CS_ST_A_READY)?1:0;
+  state_array->state[0].bvd1= 0;
+  state_array->state[0].bvd2= 0;
+  state_array->state[0].wrprot=0;
+  state_array->state[0].vs_3v=0;
+  state_array->state[0].vs_Xv=0;
+
+  return 1;
+}
+
+static int gcplus_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+	if (info->sock > 1)
+		return -1;
+
+	if (info->sock == 0)
+		info->irq = S0_STS_IRQ;
+
+  	return 0;
+}
+
+static int gcplus_pcmcia_configure_socket(const struct pcmcia_configure
+					   *configure)
+{
+  unsigned long flags;
+
+  if(configure->sock>1) return -1;
+
+  save_flags_cli(flags);
+
+  switch (configure->vcc) {
+  case 0:
+	  *PCMCIA_Power &= ~(ADS_CS_PR_A_3V_POWER | ADS_CS_PR_A_5V_POWER);
+    break;
+
+  case 50:
+	  *PCMCIA_Power &= ~(ADS_CS_PR_A_3V_POWER | ADS_CS_PR_A_5V_POWER);
+	  *PCMCIA_Power |= ADS_CS_PR_A_5V_POWER;
+	break;
+
+  case 33:
+	  *PCMCIA_Power &= ~(ADS_CS_PR_A_3V_POWER | ADS_CS_PR_A_5V_POWER);
+	  *PCMCIA_Power |= ADS_CS_PR_A_3V_POWER;
+    break;
+
+  default:
+    printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+	   configure->vcc);
+    restore_flags(flags);
+    return -1;
+  }
+
+  /* Silently ignore Vpp, output enable, speaker enable. */
+
+  // Reset PCMCIA
+  *PCMCIA_Power &= ~ ADS_CS_PR_A_RESET;
+  udelay(12);
+
+  *PCMCIA_Power |= ADS_CS_PR_A_RESET;
+  mdelay(30);
+
+  restore_flags(flags);
+
+  return 0;
+}
+
+struct pcmcia_low_level gcplus_pcmcia_ops = { 
+  gcplus_pcmcia_init,
+  gcplus_pcmcia_shutdown,
+  gcplus_pcmcia_socket_state,
+  gcplus_pcmcia_get_irq_info,
+  gcplus_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_graphicsmaster.c linux/drivers/pcmcia/sa1100_graphicsmaster.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_graphicsmaster.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_graphicsmaster.c	Thu Oct 11 09:43:29 2001
@@ -0,0 +1,215 @@
+/*
+ * drivers/pcmcia/sa1100_graphicsmaster.c
+ *
+ * PCMCIA implementation routines for GraphicsMaster
+ *
+ * 9/18/01 Woojung
+ *         Fixed wrong PCMCIA voltage setting
+ * 7/5/01 Woojung Huh <whuh@applieddata.net>
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/delay.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+static int graphicsmaster_pcmcia_init(struct pcmcia_init *init)
+{
+  int return_val=0;
+
+  /* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
+  PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
+
+  /* Disable Power 3.3V/5V for PCMCIA/CF */
+  PA_DWR |= GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3;
+
+  INTPOL1 |= (1 << (S0_READY_NINT - SA1111_IRQ(32))) |
+			 (1 << (S1_READY_NINT - SA1111_IRQ(32))) |
+    		 (1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+    		 (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+    		 (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+    		 (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32)));
+
+  return_val+=request_irq(S0_CD_VALID, init->handler, SA_INTERRUPT,
+			  "GC Master PCMCIA (0) CD", NULL);
+  return_val+=request_irq(S1_CD_VALID, init->handler, SA_INTERRUPT,
+			  "GC Master CF (1) CD", NULL);
+  return_val+=request_irq(S0_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+			  "GC Master PCMCIA (0) BVD1", NULL);
+  return_val+=request_irq(S1_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+			  "GC Master CF (1) BVD1", NULL);
+
+  MECR = 0x09430943;
+
+  return (return_val<0) ? -1 : 2;
+}
+
+static int graphicsmaster_pcmcia_shutdown(void)
+{
+
+  free_irq(S0_CD_VALID, NULL);
+  free_irq(S1_CD_VALID, NULL);
+  free_irq(S0_BVD1_STSCHG, NULL);
+  free_irq(S1_BVD1_STSCHG, NULL);
+
+  INTPOL1 &= ~((1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+			   (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+      		   (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+      		   (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32))));
+
+  return 0;
+}
+
+static int graphicsmaster_pcmcia_socket_state(struct pcmcia_state_array *state_array)
+{
+  unsigned long status;
+  int return_val=1;
+
+  if(state_array->size<2) return -1;
+
+  memset(state_array->state, 0,
+	 (state_array->size)*sizeof(struct pcmcia_state));
+
+  status=PCSR;
+
+  state_array->state[0].detect=((status & PCSR_S0_DETECT)==0)?1:0;
+
+  state_array->state[0].ready=((status & PCSR_S0_READY)==0)?0:1;
+
+  state_array->state[0].bvd1=((status & PCSR_S0_BVD1)==0)?0:1;
+
+  state_array->state[0].bvd2=((status & PCSR_S0_BVD2)==0)?0:1;
+
+  state_array->state[0].wrprot=((status & PCSR_S0_WP)==0)?0:1;
+
+  state_array->state[0].vs_3v=((status & PCSR_S0_VS1)==0)?1:0;
+
+  state_array->state[0].vs_Xv=((status & PCSR_S0_VS2)==0)?1:0;
+
+  state_array->state[1].detect=((status & PCSR_S1_DETECT)==0)?1:0;
+
+  state_array->state[1].ready=((status & PCSR_S1_READY)==0)?0:1;
+
+  state_array->state[1].bvd1=((status & PCSR_S1_BVD1)==0)?0:1;
+
+  state_array->state[1].bvd2=((status & PCSR_S1_BVD2)==0)?0:1;
+
+  state_array->state[1].wrprot=((status & PCSR_S1_WP)==0)?0:1;
+
+  state_array->state[1].vs_3v=((status & PCSR_S1_VS1)==0)?1:0;
+
+  state_array->state[1].vs_Xv=((status & PCSR_S1_VS2)==0)?1:0;
+
+  return return_val;
+}
+
+static int graphicsmaster_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+
+  switch(info->sock){
+  case 0:
+    info->irq=S0_READY_NINT;
+    break;
+
+  case 1:
+    info->irq=S1_READY_NINT;
+    break;
+
+  default:
+    return -1;
+  }
+
+  return 0;
+}
+
+static int graphicsmaster_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+{
+  unsigned long pccr=PCCR, gpio=PA_DWR;
+
+  switch(configure->sock){
+  case 0:
+
+    switch(configure->vcc){
+    case 0:
+      pccr = (pccr & ~PCCR_S0_FLT);
+      gpio |= GPIO_GPIO0 | GPIO_GPIO1;
+      break;
+
+    case 33:
+      pccr = (pccr & ~PCCR_S0_PSE) | PCCR_S0_FLT | PCCR_S0_PWAITEN;
+      gpio &= ~(GPIO_GPIO0 | GPIO_GPIO1);
+	  gpio &= ~GPIO_GPIO0;
+      break;
+
+    case 50:
+      pccr = (pccr | PCCR_S0_PSE | PCCR_S0_FLT | PCCR_S0_PWAITEN);
+      gpio &= ~(GPIO_GPIO0 | GPIO_GPIO1);
+	  gpio |= GPIO_GPIO0;
+      break;
+
+    default:
+      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+	     configure->vcc);
+      return -1;
+    }
+
+    pccr=(configure->reset)?(pccr | PCCR_S0_RST):(pccr & ~PCCR_S0_RST);
+
+    break;
+
+  case 1:
+    switch(configure->vcc){
+    case 0:
+      pccr = (pccr & ~PCCR_S1_FLT);
+      gpio |= GPIO_GPIO2 | GPIO_GPIO3;
+      break;
+
+    case 33:
+      pccr = (pccr & ~PCCR_S1_PSE) | PCCR_S1_FLT | PCCR_S1_PWAITEN;
+      gpio &= ~(GPIO_GPIO2 | GPIO_GPIO3);
+	  gpio &= ~GPIO_GPIO2;
+      break;
+
+    case 50:
+      pccr = (pccr | PCCR_S1_PSE | PCCR_S1_FLT | PCCR_S1_PWAITEN);
+      gpio &= ~(GPIO_GPIO2 | GPIO_GPIO3);
+	  gpio |= GPIO_GPIO2;
+      break;
+
+    default:
+      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+	     configure->vcc);
+      return -1;
+    }
+
+    if(configure->vpp!=configure->vcc && configure->vpp!=0){
+      printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n", __FUNCTION__,
+	     configure->vpp);
+      return -1;
+    }
+
+    pccr=(configure->reset)?(pccr | PCCR_S1_RST):(pccr & ~PCCR_S1_RST);
+
+    break;
+
+  default:
+    return -1;
+  }
+
+  PCCR = pccr;
+  PA_DWR = gpio;
+
+  return 0;
+}
+
+struct pcmcia_low_level graphicsmaster_pcmcia_ops = {
+  graphicsmaster_pcmcia_init,
+  graphicsmaster_pcmcia_shutdown,
+  graphicsmaster_pcmcia_socket_state,
+  graphicsmaster_pcmcia_get_irq_info,
+  graphicsmaster_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_h3600.c linux/drivers/pcmcia/sa1100_h3600.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_h3600.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_h3600.c	Thu Oct 11 09:43:29 2001
@@ -0,0 +1,147 @@
+/*
+ * drivers/pcmcia/sa1100_h3600.c
+ *
+ * PCMCIA implementation routines for H3600
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+
+static int h3600_pcmcia_init(struct pcmcia_init *init){
+  int irq, res;
+
+  /* Enable CF bus: */
+  set_h3600_egpio(EGPIO_H3600_OPT_NVRAM_ON);
+  clr_h3600_egpio(EGPIO_H3600_OPT_RESET);
+
+  /* All those are inputs */
+  GPDR &= ~(GPIO_H3600_PCMCIA_CD0 | GPIO_H3600_PCMCIA_CD1 | GPIO_H3600_PCMCIA_IRQ0| GPIO_H3600_PCMCIA_IRQ1);
+
+  /* Set transition detect */
+  set_GPIO_IRQ_edge( GPIO_H3600_PCMCIA_CD0 | GPIO_H3600_PCMCIA_CD1, GPIO_BOTH_EDGES );
+  set_GPIO_IRQ_edge( GPIO_H3600_PCMCIA_IRQ0| GPIO_H3600_PCMCIA_IRQ1, GPIO_FALLING_EDGE );
+
+  /* Register interrupts */
+  irq = IRQ_GPIO_H3600_PCMCIA_CD0;
+  res = request_irq( irq, init->handler, SA_INTERRUPT, "PCMCIA_CD0", NULL );
+  if( res < 0 ) goto irq_err;
+  irq = IRQ_GPIO_H3600_PCMCIA_CD1;
+  res = request_irq( irq, init->handler, SA_INTERRUPT, "PCMCIA_CD1", NULL );
+  if( res < 0 ) goto irq_err;
+
+  return 2;
+
+irq_err:
+  printk( KERN_ERR __FUNCTION__ ": Request for IRQ %u failed\n", irq );
+  return -1;
+}
+
+static int h3600_pcmcia_shutdown(void)
+{
+  /* disable IRQs */
+  free_irq( IRQ_GPIO_H3600_PCMCIA_CD0, NULL );
+  free_irq( IRQ_GPIO_H3600_PCMCIA_CD1, NULL );
+  
+  /* Disable CF bus: */
+  clr_h3600_egpio(EGPIO_H3600_OPT_NVRAM_ON|EGPIO_H3600_OPT_ON);
+  set_h3600_egpio(EGPIO_H3600_OPT_RESET);
+
+  return 0;
+}
+
+static int h3600_pcmcia_socket_state(struct pcmcia_state_array
+				       *state_array){
+  unsigned long levels;
+
+  if(state_array->size<2) return -1;
+
+  memset(state_array->state, 0, 
+	 (state_array->size)*sizeof(struct pcmcia_state));
+
+  levels=GPLR;
+
+  state_array->state[0].detect=((levels & GPIO_H3600_PCMCIA_CD0)==0)?1:0;
+  state_array->state[0].ready=(levels & GPIO_H3600_PCMCIA_IRQ0)?1:0;
+  state_array->state[0].bvd1= 0;
+  state_array->state[0].bvd2= 0;
+  state_array->state[0].wrprot=0; /* Not available on H3600. */
+  state_array->state[0].vs_3v=0;
+  state_array->state[0].vs_Xv=0;
+
+  state_array->state[1].detect=((levels & GPIO_H3600_PCMCIA_CD1)==0)?1:0;
+  state_array->state[1].ready=(levels & GPIO_H3600_PCMCIA_IRQ1)?1:0;
+  state_array->state[1].bvd1=0;
+  state_array->state[1].bvd2=0;
+  state_array->state[1].wrprot=0; /* Not available on H3600. */
+  state_array->state[1].vs_3v=0;
+  state_array->state[1].vs_Xv=0;
+
+  return 1;
+}
+
+static int h3600_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+
+  switch (info->sock) {
+  case 0:
+    info->irq=IRQ_GPIO_H3600_PCMCIA_IRQ0;
+    break;
+  case 1:
+    info->irq=IRQ_GPIO_H3600_PCMCIA_IRQ1;
+    break;
+  default:
+    return -1;
+  }
+  return 0;
+}
+
+static int h3600_pcmcia_configure_socket(const struct pcmcia_configure
+					   *configure)
+{
+  unsigned long flags;
+
+  if(configure->sock>1) return -1;
+
+  save_flags_cli(flags);
+
+  switch (configure->vcc) {
+  case 0:
+    clr_h3600_egpio(EGPIO_H3600_OPT_ON);
+    break;
+
+  case 33:
+  case 50:
+    set_h3600_egpio(EGPIO_H3600_OPT_ON);
+    break;
+
+  default:
+    printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+	   configure->vcc);
+    restore_flags(flags);
+    return -1;
+  }
+
+  if (configure->reset)
+    set_h3600_egpio(EGPIO_H3600_CARD_RESET);
+  else
+    clr_h3600_egpio(EGPIO_H3600_CARD_RESET);
+
+  /* Silently ignore Vpp, output enable, speaker enable. */
+
+  restore_flags(flags);
+
+  return 0;
+}
+
+struct pcmcia_low_level h3600_pcmcia_ops = { 
+  h3600_pcmcia_init,
+  h3600_pcmcia_shutdown,
+  h3600_pcmcia_socket_state,
+  h3600_pcmcia_get_irq_info,
+  h3600_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_jornada720.c linux/drivers/pcmcia/sa1100_jornada720.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_jornada720.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_jornada720.c	Thu Oct 11 09:43:29 2001
@@ -0,0 +1,215 @@
+/*
+ * drivers/pcmcia/sa1100_jornada720.c
+ *
+ * Jornada720 PCMCIA specific routines
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/delay.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+#define SOCKET0_POWER   GPIO_GPIO0
+#define SOCKET0_3V      GPIO_GPIO2
+#define SOCKET1_POWER   (GPIO_GPIO1 | GPIO_GPIO3)
+#define SOCKET1_3V   GPIO_GPIO3
+
+static int jornada720_pcmcia_init(struct pcmcia_init *init)
+{
+  int return_val=0;
+
+  GRER |= 0x00000002;
+  /* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
+  PA_DDR = 0;
+  PA_DWR = 0;
+  PA_SDR = 0;
+  PA_SSR = 0;
+
+  PB_DDR = 0;
+  PB_DWR = 0x01;
+  PB_SDR = 0;
+  PB_SSR = 0;
+
+  PC_DDR = 0x88;
+  PC_DWR = 0x20;
+  PC_SDR = 0;
+  PC_SSR = 0;
+
+  INTPOL1 |=
+    (1 << (S0_READY_NINT - SA1111_IRQ(32))) |
+    (1 << (S1_READY_NINT - SA1111_IRQ(32))) |
+    (1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+    (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+    (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+    (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32)));
+
+  return_val+=request_irq(S0_CD_VALID, init->handler, SA_INTERRUPT,
+			  "Jornada720 PCMCIA (0) CD", NULL);
+  return_val+=request_irq(S1_CD_VALID, init->handler, SA_INTERRUPT,
+			  "Jornada720 CF (1) CD", NULL);
+  return_val+=request_irq(S0_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+			  "Jornada720 PCMCIA (0) BVD1", NULL);
+  return_val+=request_irq(S1_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+			  "Jornada720 CF (1) BVD1", NULL);
+
+  return (return_val<0) ? -1 : 2;
+}
+
+static int jornada720_pcmcia_shutdown(void)
+{
+  free_irq(S0_CD_VALID, NULL);
+  free_irq(S1_CD_VALID, NULL);
+  free_irq(S0_BVD1_STSCHG, NULL);
+  free_irq(S1_BVD1_STSCHG, NULL);
+
+  INTPOL1 &=
+    ~((1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+      (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+      (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+      (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32))));
+
+  return 0;
+}
+
+static int jornada720_pcmcia_socket_state(struct pcmcia_state_array
+					*state_array)
+{
+  unsigned long status;
+  int return_val=1;
+
+  if(state_array->size<2) return -1;
+
+  memset(state_array->state, 0,
+	 (state_array->size)*sizeof(struct pcmcia_state));
+  status=PCSR;
+  state_array->state[0].detect=((status & PCSR_S0_DETECT)==0)?1:0;
+  state_array->state[0].ready=((status & PCSR_S0_READY)==0)?0:1;
+  state_array->state[0].bvd1=((status & PCSR_S0_BVD1)==0)?0:1;
+  state_array->state[0].bvd2=((status & PCSR_S0_BVD2)==0)?0:1;
+  state_array->state[0].wrprot=((status & PCSR_S0_WP)==0)?0:1;
+  state_array->state[0].vs_3v=((status & PCSR_S0_VS1)==0)?1:0;
+  state_array->state[0].vs_Xv=((status & PCSR_S0_VS2)==0)?1:0;
+  state_array->state[1].detect=((status & PCSR_S1_DETECT)==0)?1:0;
+  state_array->state[1].ready=((status & PCSR_S1_READY)==0)?0:1;
+  state_array->state[1].bvd1=((status & PCSR_S1_BVD1)==0)?0:1;
+  state_array->state[1].bvd2=((status & PCSR_S1_BVD2)==0)?0:1;
+  state_array->state[1].wrprot=((status & PCSR_S1_WP)==0)?0:1;
+  state_array->state[1].vs_3v=((status & PCSR_S1_VS1)==0)?1:0;
+  state_array->state[1].vs_Xv=((status & PCSR_S1_VS2)==0)?1:0;
+  return return_val;
+}
+
+static int jornada720_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+  switch(info->sock){
+  case 0:
+    info->irq=S0_READY_NINT;
+    break;
+
+  case 1:
+    info->irq=S1_READY_NINT;
+    break;
+
+  default:
+    return -1;
+  }
+  return 0;
+}
+
+static int jornada720_pcmcia_configure_socket(const struct pcmcia_configure
+					    *configure)
+{
+  unsigned long pccr=PCCR, gpio=PA_DWR;
+
+printk("%s(): config socket %d vcc %d vpp %d\n", __FUNCTION__,
+	       configure->sock, configure->vcc, configure->vpp);
+  switch(configure->sock){
+  case 0:
+    switch(configure->vcc){
+    case 0:
+      pccr = (pccr & ~PCCR_S0_FLT);
+      gpio&=~(SOCKET0_POWER | SOCKET0_3V);
+      break;
+
+    case 33:
+      pccr = (pccr & ~PCCR_S0_PSE) | PCCR_S0_FLT | PCCR_S0_PWAITEN;
+      gpio |= SOCKET0_POWER | SOCKET0_3V;
+      break;
+
+    case 50:
+      pccr = (pccr | PCCR_S0_PSE | PCCR_S0_FLT | PCCR_S0_PWAITEN);
+      gpio = (gpio & ~SOCKET0_3V) | SOCKET0_POWER;
+      break;
+
+    default:
+      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+	     configure->vcc);
+      return -1;
+    }
+    switch(configure->vpp){
+    case 0:
+      break;
+    case 50:
+	printk(KERN_ERR "%s(): 5.0 Vpp %u\n", __FUNCTION__,
+	       configure->vpp);
+      break;
+    case 120:
+	printk(KERN_ERR "%s(): 12 Vpp %u\n", __FUNCTION__,
+	       configure->vpp);
+      break;
+    default:
+	printk(KERN_ERR "%s(): unrecognized Vpp %u\n", __FUNCTION__,
+	       configure->vpp);
+	return -1;
+    }
+    pccr=(configure->reset)?(pccr | PCCR_S0_RST):(pccr & ~PCCR_S0_RST);
+    break;
+
+  case 1:
+    switch(configure->vcc){
+    case 0:
+      pccr = (pccr & ~PCCR_S1_FLT);
+      gpio &= ~(SOCKET1_POWER);
+      break;
+
+    case 33:
+      pccr = (pccr & ~PCCR_S1_PSE) | PCCR_S1_FLT | PCCR_S1_PWAITEN;
+      gpio |= SOCKET1_POWER;
+      break;
+
+    case 50:
+      pccr = (pccr | PCCR_S1_PSE | PCCR_S1_FLT | PCCR_S1_PWAITEN);
+      gpio = (gpio & ~(SOCKET1_POWER)) | SOCKET1_POWER;
+      break;
+
+    default:
+      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+	     configure->vcc);
+      return -1;
+    }
+    if(configure->vpp!=configure->vcc && configure->vpp!=0){
+      printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n", __FUNCTION__,
+	     configure->vpp);
+      return -1;
+    }
+    pccr=(configure->reset)?(pccr | PCCR_S1_RST):(pccr & ~PCCR_S1_RST);
+    break;
+  default:
+    return -1;
+  }
+  PCCR = pccr;
+  PA_DWR = gpio;
+  return 0;
+}
+
+struct pcmcia_low_level jornada720_pcmcia_ops = {
+  jornada720_pcmcia_init,
+  jornada720_pcmcia_shutdown,
+  jornada720_pcmcia_socket_state,
+  jornada720_pcmcia_get_irq_info,
+  jornada720_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_neponset.c linux/drivers/pcmcia/sa1100_neponset.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_neponset.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_neponset.c	Thu Oct 11 09:43:29 2001
@@ -0,0 +1,248 @@
+/*
+ * drivers/pcmcia/sa1100_neponset.c
+ *
+ * Neponset PCMCIA specific routines
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/delay.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+static int neponset_pcmcia_init(struct pcmcia_init *init){
+  int return_val=0;
+
+  /* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
+  PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
+  
+  /* MAX1600 to standby mode: */
+  PA_DWR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
+  NCR_0 &= ~(NCR_A0VPP | NCR_A1VPP);
+
+  INTPOL1 |= 
+    (1 << (S0_READY_NINT - SA1111_IRQ(32))) |
+    (1 << (S1_READY_NINT - SA1111_IRQ(32))) |
+    (1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+    (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+    (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+    (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32)));
+
+  return_val+=request_irq(S0_CD_VALID, init->handler, SA_INTERRUPT,
+			  "Neponset PCMCIA (0) CD", NULL);
+  return_val+=request_irq(S1_CD_VALID, init->handler, SA_INTERRUPT,
+			  "Neponset CF (1) CD", NULL);
+  return_val+=request_irq(S0_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+			  "Neponset PCMCIA (0) BVD1", NULL);
+  return_val+=request_irq(S1_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+			  "Neponset CF (1) BVD1", NULL);
+
+  return (return_val<0) ? -1 : 2;
+}
+
+static int neponset_pcmcia_shutdown(void){
+
+  free_irq(S0_CD_VALID, NULL);
+  free_irq(S1_CD_VALID, NULL);
+  free_irq(S0_BVD1_STSCHG, NULL);
+  free_irq(S1_BVD1_STSCHG, NULL);
+
+  INTPOL1 &= 
+    ~((1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+      (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+      (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+      (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32))));
+
+  return 0;
+}
+
+static int neponset_pcmcia_socket_state(struct pcmcia_state_array
+					*state_array){
+  unsigned long status;
+  int return_val=1;
+
+  if(state_array->size<2) return -1;
+
+  memset(state_array->state, 0, 
+	 (state_array->size)*sizeof(struct pcmcia_state));
+
+  status=PCSR;
+
+  state_array->state[0].detect=((status & PCSR_S0_DETECT)==0)?1:0;
+
+  state_array->state[0].ready=((status & PCSR_S0_READY)==0)?0:1;
+
+  state_array->state[0].bvd1=((status & PCSR_S0_BVD1)==0)?0:1;
+
+  state_array->state[0].bvd2=((status & PCSR_S0_BVD2)==0)?0:1;
+
+  state_array->state[0].wrprot=((status & PCSR_S0_WP)==0)?0:1;
+
+  state_array->state[0].vs_3v=((status & PCSR_S0_VS1)==0)?1:0;
+
+  state_array->state[0].vs_Xv=((status & PCSR_S0_VS2)==0)?1:0;
+
+  state_array->state[1].detect=((status & PCSR_S1_DETECT)==0)?1:0;
+
+  state_array->state[1].ready=((status & PCSR_S1_READY)==0)?0:1;
+
+  state_array->state[1].bvd1=((status & PCSR_S1_BVD1)==0)?0:1;
+
+  state_array->state[1].bvd2=((status & PCSR_S1_BVD2)==0)?0:1;
+
+  state_array->state[1].wrprot=((status & PCSR_S1_WP)==0)?0:1;
+
+  state_array->state[1].vs_3v=((status & PCSR_S1_VS1)==0)?1:0;
+
+  state_array->state[1].vs_Xv=((status & PCSR_S1_VS2)==0)?1:0;
+
+  return return_val;
+}
+
+static int neponset_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+
+  switch(info->sock){
+  case 0:
+    info->irq=S0_READY_NINT;
+    break;
+
+  case 1:
+    info->irq=S1_READY_NINT;
+    break;
+
+  default:
+    return -1;
+  }
+
+  return 0;
+}
+
+static int neponset_pcmcia_configure_socket(const struct pcmcia_configure
+					    *configure){
+  unsigned long pccr=PCCR, ncr=NCR_0, gpio=PA_DWR;
+
+  /* Neponset uses the Maxim MAX1600, with the following connections:
+   *
+   *   MAX1600      Neponset
+   *
+   *    A0VCC        SA-1111 GPIO A<1>
+   *    A1VCC        SA-1111 GPIO A<0>
+   *    A0VPP        CPLD NCR A0VPP
+   *    A1VPP        CPLD NCR A1VPP
+   *    B0VCC        SA-1111 GPIO A<2>
+   *    B1VCC        SA-1111 GPIO A<3>
+   *    B0VPP        ground (slot B is CF)
+   *    B1VPP        ground (slot B is CF)
+   *
+   *     VX          VCC (5V)
+   *     VY          VCC3_3 (3.3V)
+   *     12INA       12V
+   *     12INB       ground (slot B is CF)
+   *
+   * The MAX1600 CODE pin is tied to ground, placing the device in 
+   * "Standard Intel code" mode. Refer to the Maxim data sheet for
+   * the corresponding truth table.
+   */
+
+  switch(configure->sock){
+  case 0:
+    
+    switch(configure->vcc){
+    case 0:
+      pccr=(pccr & ~PCCR_S0_FLT);
+      gpio&=~(GPIO_GPIO0 | GPIO_GPIO1);
+      break;
+
+    case 33:
+      pccr=(pccr & ~PCCR_S0_PSE) | PCCR_S0_FLT | PCCR_S0_PWAITEN;
+      gpio=(gpio & ~(GPIO_GPIO0 | GPIO_GPIO1)) | GPIO_GPIO1;
+      break;
+
+    case 50:
+      pccr=(pccr | PCCR_S0_PSE | PCCR_S0_FLT | PCCR_S0_PWAITEN);
+      gpio=(gpio & ~(GPIO_GPIO0 | GPIO_GPIO1)) | GPIO_GPIO0;
+      break;
+
+    default:
+      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+	     configure->vcc);
+      return -1;
+    }
+
+    switch(configure->vpp){
+    case 0:
+      ncr&=~(NCR_A0VPP | NCR_A1VPP);
+      break;
+
+    case 120:
+      ncr=(ncr & ~(NCR_A0VPP | NCR_A1VPP)) | NCR_A1VPP;
+      break;
+
+    default:
+      if(configure->vpp == configure->vcc)
+	ncr=(ncr & ~(NCR_A0VPP | NCR_A1VPP)) | NCR_A0VPP;
+      else {
+	printk(KERN_ERR "%s(): unrecognized Vpp %u\n", __FUNCTION__,
+	       configure->vpp);
+	return -1;
+      }
+    }
+
+    pccr=(configure->reset)?(pccr | PCCR_S0_RST):(pccr & ~PCCR_S0_RST);
+
+    break;
+
+  case 1:
+    switch(configure->vcc){
+    case 0:
+      pccr=(pccr & ~PCCR_S1_FLT);
+      gpio&=~(GPIO_GPIO2 | GPIO_GPIO3);
+      break;
+
+    case 33:
+      pccr=(pccr & ~PCCR_S1_PSE) | PCCR_S1_FLT | PCCR_S1_PWAITEN;
+      gpio=(gpio & ~(GPIO_GPIO2 | GPIO_GPIO3)) | GPIO_GPIO2;
+      break;
+
+    case 50:
+      pccr=(pccr | PCCR_S1_PSE | PCCR_S1_FLT | PCCR_S1_PWAITEN);
+      gpio=(gpio & ~(GPIO_GPIO2 | GPIO_GPIO3)) | GPIO_GPIO3;
+      break;
+
+    default:
+      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+	     configure->vcc);
+      return -1;
+    }
+
+    if(configure->vpp!=configure->vcc && configure->vpp!=0){
+      printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n", __FUNCTION__,
+	     configure->vpp);
+      return -1;
+    }
+
+    pccr=(configure->reset)?(pccr | PCCR_S1_RST):(pccr & ~PCCR_S1_RST);
+
+    break;
+
+  default:
+    return -1;
+  }
+
+  PCCR = pccr;
+  NCR_0 = ncr;
+  PA_DWR = gpio;
+
+  return 0;
+}
+
+struct pcmcia_low_level neponset_pcmcia_ops = { 
+  neponset_pcmcia_init,
+  neponset_pcmcia_shutdown,
+  neponset_pcmcia_socket_state,
+  neponset_pcmcia_get_irq_info,
+  neponset_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_pangolin.c linux/drivers/pcmcia/sa1100_pangolin.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_pangolin.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_pangolin.c	Thu Oct 11 09:43:29 2001
@@ -0,0 +1,157 @@
+/*
+ * drivers/pcmcia/sa1100_pangolin.c
+ *
+ * PCMCIA implementation routines for Pangolin
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+static int pangolin_pcmcia_init(struct pcmcia_init *init){
+  int irq, res;
+
+  /* set GPIO_PCMCIA_CD & GPIO_PCMCIA_IRQ as inputs */
+  GPDR &= ~(GPIO_PCMCIA_CD|GPIO_PCMCIA_IRQ);
+#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
+  /* set GPIO pins GPIO_PCMCIA_BUS_ON & GPIO_PCMCIA_RESET as output */
+  GPDR |= (GPIO_PCMCIA_BUS_ON|GPIO_PCMCIA_RESET);
+  /* Enable PCMCIA bus: */
+  GPCR = GPIO_PCMCIA_BUS_ON;
+#else
+  /* set GPIO pin GPIO_PCMCIA_RESET as output */
+  GPDR |= GPIO_PCMCIA_RESET;
+#endif
+  /* Set transition detect */
+  set_GPIO_IRQ_edge( GPIO_PCMCIA_CD, GPIO_BOTH_EDGES );
+  set_GPIO_IRQ_edge( GPIO_PCMCIA_IRQ, GPIO_FALLING_EDGE );
+
+  /* Register interrupts */
+  irq = IRQ_PCMCIA_CD;
+  res = request_irq( irq, init->handler, SA_INTERRUPT, "PCMCIA_CD", NULL );
+  if( res < 0 ) goto irq_err;
+
+  /* There's only one slot, but it's "Slot 1": */
+  return 2;
+
+irq_err:
+  printk( KERN_ERR "%s: Request for IRQ %lu failed\n", __FUNCTION__, irq );
+  return -1;
+}
+
+static int pangolin_pcmcia_shutdown(void)
+{
+  /* disable IRQs */
+  free_irq( IRQ_PCMCIA_CD, NULL );
+#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
+    /* Disable PCMCIA bus: */
+    GPSR = GPIO_PCMCIA_BUS_ON;
+#endif
+  return 0;
+}
+
+static int pangolin_pcmcia_socket_state(struct pcmcia_state_array
+				       *state_array){
+  unsigned long levels;
+
+  if(state_array->size<2) return -1;
+
+  memset(state_array->state, 0, 
+	 (state_array->size)*sizeof(struct pcmcia_state));
+
+  levels=GPLR;
+#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
+  state_array->state[1].detect=((levels & GPIO_PCMCIA_CD)==0)?1:0;
+  state_array->state[1].ready=(levels & GPIO_PCMCIA_IRQ)?1:0;
+  state_array->state[1].bvd1=1; /* Not available on Pangolin. */
+  state_array->state[1].bvd2=1; /* Not available on Pangolin. */
+  state_array->state[1].wrprot=0; /* Not available on Pangolin. */
+  state_array->state[1].vs_3v=1;  /* Can only apply 3.3V on Pangolin. */
+  state_array->state[1].vs_Xv=0;
+#else
+  state_array->state[0].detect=((levels & GPIO_PCMCIA_CD)==0)?1:0;
+  state_array->state[0].ready=(levels & GPIO_PCMCIA_IRQ)?1:0;
+  state_array->state[0].bvd1=1; /* Not available on Pangolin. */
+  state_array->state[0].bvd2=1; /* Not available on Pangolin. */
+  state_array->state[0].wrprot=0; /* Not available on Pangolin. */
+  state_array->state[0].vs_3v=0;  /* voltage level is determined by jumper setting */
+  state_array->state[0].vs_Xv=0;
+#endif
+  return 1;
+}
+
+static int pangolin_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+
+  if(info->sock>1) return -1;
+#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
+  if(info->sock==1)
+	info->irq=IRQ_PCMCIA_IRQ;
+#else
+  if(info->sock==0)
+        info->irq=IRQ_PCMCIA_IRQ;
+#endif
+  return 0;
+}
+
+static int pangolin_pcmcia_configure_socket(const struct pcmcia_configure
+					   *configure)
+{
+  unsigned long value, flags;
+
+  if(configure->sock>1) return -1;
+#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
+  if(configure->sock==0) return 0;
+#endif
+  save_flags_cli(flags);
+
+  /* Murphy: BUS_ON different from POWER ? */
+
+  switch(configure->vcc){
+  case 0:
+    break;
+#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
+  case 50:
+    printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n",
+	   __FUNCTION__);
+  case 33:  /* Can only apply 3.3V to the CF slot. */
+    break;
+#else
+  case 50:
+    printk(KERN_WARNING "%s(): CS asked for 5V, determinded by jumper setting...\n", __FUNCTION__);
+    break;
+  case 33:
+    printk(KERN_WARNING "%s(): CS asked for 3.3V, determined by jumper setting...\n", __FUNCTION__);
+    break;
+#endif
+  default:
+    printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+	   configure->vcc);
+    restore_flags(flags);
+    return -1;
+  }
+#ifdef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
+  /* reset & unreset request */
+  if(configure->sock==0) {
+	if(configure->reset) {
+		GPSR |= GPIO_PCMCIA_RESET;
+	} else {
+		GPCR |= GPIO_PCMCIA_RESET;
+	}
+  }
+#endif
+  /* Silently ignore Vpp, output enable, speaker enable. */
+  restore_flags(flags);
+  return 0;
+}
+
+struct pcmcia_low_level pangolin_pcmcia_ops = { 
+  pangolin_pcmcia_init,
+  pangolin_pcmcia_shutdown,
+  pangolin_pcmcia_socket_state,
+  pangolin_pcmcia_get_irq_info,
+  pangolin_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_pfs168.c linux/drivers/pcmcia/sa1100_pfs168.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_pfs168.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_pfs168.c	Thu Oct 11 09:43:29 2001
@@ -0,0 +1,237 @@
+#warning	"REVISIT_PFS168: Need to verify and test GPIO power encodings."
+/*
+ * drivers/pcmcia/sa1100_pfs168.c
+ *
+ * PFS168 PCMCIA specific routines
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/delay.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+static int pfs168_pcmcia_init(struct pcmcia_init *init){
+  int return_val=0;
+
+  /* TPS2211 to standby mode: */
+  PA_DWR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
+
+  /* Set GPIO_A<3:0> to be outputs for PCMCIA (socket 0) power controller: */
+  PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
+
+  INTPOL1 |=
+    (1 << (S0_READY_NINT - SA1111_IRQ(32))) |
+    (1 << (S1_READY_NINT - SA1111_IRQ(32))) |
+    (1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+    (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+    (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+    (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32)));
+
+  return_val+=request_irq(S0_CD_VALID, init->handler, SA_INTERRUPT,
+			  "PFS168 PCMCIA (0) CD", NULL);
+  return_val+=request_irq(S1_CD_VALID, init->handler, SA_INTERRUPT,
+			  "PFS168 CF (1) CD", NULL);
+  return_val+=request_irq(S0_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+			  "PFS168 PCMCIA (0) BVD1", NULL);
+  return_val+=request_irq(S1_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+			  "PFS168 CF (1) BVD1", NULL);
+
+  return (return_val<0) ? -1 : 2;
+}
+
+static int pfs168_pcmcia_shutdown(void){
+
+  free_irq(S0_CD_VALID, NULL);
+  free_irq(S1_CD_VALID, NULL);
+  free_irq(S0_BVD1_STSCHG, NULL);
+  free_irq(S1_BVD1_STSCHG, NULL);
+
+  INTPOL1 &=
+    ~((1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+      (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+      (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+      (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32))));
+
+  return 0;
+}
+
+static int pfs168_pcmcia_socket_state(struct pcmcia_state_array
+					*state_array){
+  unsigned long status;
+  int return_val=1;
+
+  if(state_array->size<2) return -1;
+
+  memset(state_array->state, 0,
+	 (state_array->size)*sizeof(struct pcmcia_state));
+
+  status=PCSR;
+
+  state_array->state[0].detect=((status & PCSR_S0_DETECT)==0)?1:0;
+
+  state_array->state[0].ready=((status & PCSR_S0_READY)==0)?0:1;
+
+  state_array->state[0].bvd1=((status & PCSR_S0_BVD1)==0)?0:1;
+
+  state_array->state[0].bvd2=((status & PCSR_S0_BVD2)==0)?0:1;
+
+  state_array->state[0].wrprot=((status & PCSR_S0_WP)==0)?0:1;
+
+  state_array->state[0].vs_3v=((status & PCSR_S0_VS1)==0)?1:0;
+
+  state_array->state[0].vs_Xv=((status & PCSR_S0_VS2)==0)?1:0;
+
+  state_array->state[1].detect=((status & PCSR_S1_DETECT)==0)?1:0;
+
+  state_array->state[1].ready=((status & PCSR_S1_READY)==0)?0:1;
+
+  state_array->state[1].bvd1=((status & PCSR_S1_BVD1)==0)?0:1;
+
+  state_array->state[1].bvd2=((status & PCSR_S1_BVD2)==0)?0:1;
+
+  state_array->state[1].wrprot=((status & PCSR_S1_WP)==0)?0:1;
+
+  state_array->state[1].vs_3v=((status & PCSR_S1_VS1)==0)?1:0;
+
+  state_array->state[1].vs_Xv=((status & PCSR_S1_VS2)==0)?1:0;
+
+  return return_val;
+}
+
+static int pfs168_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+
+  switch(info->sock){
+  case 0:
+    info->irq=S0_READY_NINT;
+    break;
+
+  case 1:
+    info->irq=S1_READY_NINT;
+    break;
+
+  default:
+    return -1;
+  }
+
+  return 0;
+}
+
+static int pfs168_pcmcia_configure_socket(const struct pcmcia_configure
+					    *configure){
+  unsigned long pccr=PCCR, gpio=PA_DWR;
+
+  /* PFS168 uses the Texas Instruments TPS2211 for PCMCIA (socket 0) voltage control only,
+   * with the following connections:
+   *
+   *   TPS2211      PFS168
+   *
+   *    -VCCD0      SA-1111 GPIO A<0>
+   *    -VCCD0      SA-1111 GPIO A<1>
+   *     VPPD0      SA-1111 GPIO A<2>
+   *     VPPD0      SA-1111 GPIO A<2>
+   *
+   */
+
+  switch(configure->sock){
+  case 0:
+
+    switch(configure->vcc){
+    case 0:
+      pccr = (pccr & ~PCCR_S0_FLT);
+      gpio &= ~(GPIO_GPIO0 | GPIO_GPIO1);
+      break;
+
+    case 33:
+      pccr = (pccr & ~PCCR_S0_PSE) | PCCR_S0_FLT | PCCR_S0_PWAITEN;
+      gpio = (gpio & ~(GPIO_GPIO0 | GPIO_GPIO1)) | GPIO_GPIO0;
+      break;
+
+    case 50:
+      pccr = (pccr | PCCR_S0_PSE | PCCR_S0_FLT | PCCR_S0_PWAITEN);
+      gpio = (gpio & ~(GPIO_GPIO0 | GPIO_GPIO1)) | GPIO_GPIO1;
+      break;
+
+    default:
+      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+	     configure->vcc);
+      return -1;
+    }
+
+    switch(configure->vpp){
+    case 0:
+      gpio &= ~(GPIO_GPIO2 | GPIO_GPIO3);
+      break;
+
+    case 120:
+      printk(KERN_ERR "%s(): PFS-168 does not support Vpp %uV\n", __FUNCTION__,
+	     configure->vpp/10);
+      return -1;
+      break;
+
+    default:
+      if(configure->vpp == configure->vcc)
+        gpio = (gpio & ~(GPIO_GPIO2 | GPIO_GPIO3)) | GPIO_GPIO3;
+      else {
+	printk(KERN_ERR "%s(): unrecognized Vpp %u\n", __FUNCTION__,
+	       configure->vpp);
+	return -1;
+      }
+    }
+
+    pccr = (configure->reset)?(pccr | PCCR_S0_RST):(pccr & ~PCCR_S0_RST);
+
+    PA_DWR = gpio;
+
+    break;
+
+  case 1:
+    switch(configure->vcc){
+    case 0:
+      pccr = (pccr & ~PCCR_S1_FLT);
+      break;
+
+    case 33:
+      pccr = (pccr & ~PCCR_S1_PSE) | PCCR_S1_FLT | PCCR_S1_PWAITEN;
+      break;
+
+    case 50:
+      printk(KERN_ERR "%s(): PFS-168 CompactFlash socket does not support Vcc %uV\n", __FUNCTION__,
+	     configure->vcc/10);
+      return -1;
+      break;
+
+    default:
+      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+	     configure->vcc);
+      return -1;
+    }
+
+    if(configure->vpp!=configure->vcc && configure->vpp!=0){
+      printk(KERN_ERR "%s(): CompactFlash socket does not support Vpp %uV\n", __FUNCTION__,
+	     configure->vpp/10);
+      return -1;
+    }
+
+    pccr = (configure->reset)?(pccr | PCCR_S1_RST):(pccr & ~PCCR_S1_RST);
+
+    break;
+
+  default:
+    return -1;
+  }
+
+  PCCR = pccr;
+
+  return 0;
+}
+
+struct pcmcia_low_level pfs168_pcmcia_ops = {
+  pfs168_pcmcia_init,
+  pfs168_pcmcia_shutdown,
+  pfs168_pcmcia_socket_state,
+  pfs168_pcmcia_get_irq_info,
+  pfs168_pcmcia_configure_socket
+};
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_simpad.c linux/drivers/pcmcia/sa1100_simpad.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_simpad.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_simpad.c	Thu Oct 11 09:43:29 2001
@@ -0,0 +1,136 @@
+/*
+ * drivers/pcmcia/sa1100_pangolin.c
+ *
+ * PCMCIA implementation routines for simpad
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+static int simpad_pcmcia_init(struct pcmcia_init *init){
+  int irq, res;
+
+  /* set GPIO_CF_CD & GPIO_CF_IRQ as inputs */
+  GPDR &= ~(GPIO_CF_CD|GPIO_CF_IRQ);
+  //init_simpad_cs3();
+  printk("\nCS3:%x\n",cs3_shadow);
+  PCMCIA_setbit(PCMCIA_RESET);
+  PCMCIA_clearbit(PCMCIA_BUFF_DIS);
+
+  /* Set transition detect */
+  set_GPIO_IRQ_edge( GPIO_CF_CD, GPIO_BOTH_EDGES );
+  set_GPIO_IRQ_edge( GPIO_CF_IRQ, GPIO_FALLING_EDGE );
+
+  /* Register interrupts */
+  irq = IRQ_GPIO_CF_CD;
+  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_CD", NULL );
+  if( res < 0 ) goto irq_err;
+
+  /* There's only one slot, but it's "Slot 1": */
+  return 2;
+
+irq_err:
+  printk( KERN_ERR "%s: Request for IRQ %lu failed\n", __FUNCTION__, irq );
+  return -1;
+}
+
+static int simpad_pcmcia_shutdown(void)
+{
+  /* disable IRQs */
+  free_irq( IRQ_GPIO_CF_CD, NULL );
+
+  /* Disable CF bus: */
+
+  PCMCIA_setbit(PCMCIA_BUFF_DIS);
+  PCMCIA_clearbit(PCMCIA_RESET);
+  return 0;
+}
+
+static int simpad_pcmcia_socket_state(struct pcmcia_state_array
+				       *state_array)
+{
+  unsigned long levels;
+
+  if(state_array->size<2) return -1;
+
+  memset(state_array->state, 0,
+	 (state_array->size)*sizeof(struct pcmcia_state));
+
+  levels=GPLR;
+
+  state_array->state[1].detect=((levels & GPIO_CF_CD)==0)?1:0;
+
+  state_array->state[1].ready=(levels & GPIO_CF_IRQ)?1:0;
+
+  state_array->state[1].bvd1=1; /* Not available on Simpad. */
+
+  state_array->state[1].bvd2=1; /* Not available on Simpad. */
+
+  state_array->state[1].wrprot=0; /* Not available on Simpad. */
+
+  state_array->state[1].vs_3v=1;  /* Can only apply 3.3V on Simpad. */
+
+  state_array->state[1].vs_Xv=0;
+
+  return 1;
+}
+
+static int simpad_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+
+  if(info->sock>1) return -1;
+
+  if(info->sock==1)
+    info->irq=IRQ_GPIO_CF_IRQ;
+
+  return 0;
+}
+
+static int simpad_pcmcia_configure_socket(const struct pcmcia_configure
+					   *configure)
+{
+  unsigned long value, flags;
+
+  if(configure->sock>1) return -1;
+
+  if(configure->sock==0) return 0;
+
+  save_flags_cli(flags);
+
+  /* Murphy: BUS_ON different from POWER ? */
+
+  switch(configure->vcc){
+  case 0:
+    PCMCIA_setbit(PCMCIA_BUFF_DIS);
+    break;
+
+  case 33:
+  case 50:
+    PCMCIA_setbit(PCMCIA_BUFF_DIS);
+    break;
+
+  default:
+    printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+	   configure->vcc);
+    restore_flags(flags);
+    return -1;
+  }
+
+  /* Silently ignore Vpp, output enable, speaker enable. */
+
+  restore_flags(flags);
+
+  return 0;
+}
+
+struct pcmcia_low_level simpad_pcmcia_ops = {
+  simpad_pcmcia_init,
+  simpad_pcmcia_shutdown,
+  simpad_pcmcia_socket_state,
+  simpad_pcmcia_get_irq_info,
+  simpad_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_stork.c linux/drivers/pcmcia/sa1100_stork.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_stork.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_stork.c	Thu Oct 11 09:43:29 2001
@@ -0,0 +1,202 @@
+/* 
+ * drivers/pcmcia/sa1100_stork.c
+ *
+    Copyright 2001 (C) Ken Gordon
+
+    This is derived from pre-existing drivers/pcmcia/sa1100_?????.c
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License.
+
+    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.
+
+ * 
+ * PCMCIA implementation routines for stork
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/i2c.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+static int debug = 0;
+
+static struct pcmcia_init sa1100_stork_pcmcia_init;
+
+static int stork_pcmcia_init(struct pcmcia_init *init)
+{
+        int irq, res;
+        printk("in stork_pcmcia_init\n");
+
+        sa1100_stork_pcmcia_init = *init;
+
+        /* Enable CF bus: */
+        storkSetLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
+
+        /* All those are inputs */
+	GPDR &= ~(GPIO_STORK_PCMCIA_A_CARD_DETECT | GPIO_STORK_PCMCIA_B_CARD_DETECT | GPIO_STORK_PCMCIA_A_RDY| GPIO_STORK_PCMCIA_B_RDY);
+
+	/* Set transition detect */
+	set_GPIO_IRQ_edge( GPIO_STORK_PCMCIA_A_CARD_DETECT | GPIO_STORK_PCMCIA_B_CARD_DETECT, GPIO_BOTH_EDGES );
+        set_GPIO_IRQ_edge( GPIO_STORK_PCMCIA_A_RDY| GPIO_STORK_PCMCIA_B_RDY, GPIO_FALLING_EDGE );
+
+	/* Register interrupts */
+	irq = IRQ_GPIO_STORK_PCMCIA_A_CARD_DETECT;
+	res = request_irq( irq, init->handler, SA_INTERRUPT, "PCMCIA_CD0", NULL );
+	if( res < 0 ) goto irq_err;
+	irq = IRQ_GPIO_STORK_PCMCIA_B_CARD_DETECT;
+	res = request_irq( irq, init->handler, SA_INTERRUPT, "PCMCIA_CD1", NULL );
+	if( res < 0 ) goto irq_err;
+
+        return 2;
+
+ irq_err:
+        printk( KERN_ERR __FUNCTION__ ": Request for IRQ %u failed\n", irq );
+        return -1;
+}
+
+static int stork_pcmcia_shutdown(void)
+{
+        printk(__FUNCTION__ "\n");
+        /* disable IRQs */
+        free_irq( IRQ_GPIO_STORK_PCMCIA_A_CARD_DETECT, NULL );
+        free_irq( IRQ_GPIO_STORK_PCMCIA_B_CARD_DETECT, NULL );
+  
+        /* Disable CF bus: */
+        storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
+	storkClearLatchA(STORK_PCMCIA_A_POWER_ON);
+	storkClearLatchA(STORK_PCMCIA_B_POWER_ON);
+        return 0;
+}
+
+static int stork_pcmcia_socket_state(struct pcmcia_state_array *state_array)
+{
+        unsigned long levels;
+
+        if(state_array->size<2) return -1;
+
+        memset(state_array->state, 0, 
+               (state_array->size)*sizeof(struct pcmcia_state));
+
+        levels=GPLR;
+
+	if (debug > 1)
+		printk(__FUNCTION__ " GPLR=%x IRQ[1:0]=%x\n", GPLR, (GPLR & (GPIO_STORK_PCMCIA_A_RDY|GPIO_STORK_PCMCIA_B_RDY)));
+	state_array->state[0].detect=((levels & GPIO_STORK_PCMCIA_A_CARD_DETECT)==0)?1:0;
+	state_array->state[0].ready=(levels & GPIO_STORK_PCMCIA_A_RDY)?1:0;
+	state_array->state[0].bvd1= 1;
+	state_array->state[0].bvd2= 1;
+	state_array->state[0].wrprot=0;
+	state_array->state[0].vs_3v=1;
+	state_array->state[0].vs_Xv=0;
+
+	state_array->state[1].detect=((levels & GPIO_STORK_PCMCIA_B_CARD_DETECT)==0)?1:0;
+	state_array->state[1].ready=(levels & GPIO_STORK_PCMCIA_B_RDY)?1:0;
+	state_array->state[1].bvd1=1;
+	state_array->state[1].bvd2=1;
+	state_array->state[1].wrprot=0;
+	state_array->state[1].vs_3v=1;
+	state_array->state[1].vs_Xv=0;
+
+        return 1;
+}
+
+static int stork_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+
+        switch (info->sock) {
+        case 0:
+                info->irq=IRQ_GPIO_STORK_PCMCIA_A_RDY;
+                break;
+        case 1:
+                info->irq=IRQ_GPIO_STORK_PCMCIA_B_RDY;
+                break;
+        default:
+                return -1;
+        }
+        return 0;
+}
+
+static int stork_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+{
+        int card = configure->sock;
+	unsigned long flags;
+
+        int DETECT, RDY, POWER, RESET;
+
+        if (card > 1) return -1;
+
+	printk(__FUNCTION__ ": socket=%d vcc=%d vpp=%d reset=%d\n", 
+                       card, configure->vcc, configure->vpp, configure->reset);
+
+	save_flags_cli(flags);
+
+        if (card == 0) {
+    	    DETECT = GPIO_STORK_PCMCIA_A_CARD_DETECT;
+    	    RDY = GPIO_STORK_PCMCIA_A_RDY;
+    	    POWER = STORK_PCMCIA_A_POWER_ON;
+    	    RESET = STORK_PCMCIA_A_RESET;
+        } else {
+    	    DETECT = GPIO_STORK_PCMCIA_B_CARD_DETECT;
+    	    RDY = GPIO_STORK_PCMCIA_B_RDY;
+    	    POWER = STORK_PCMCIA_B_POWER_ON;
+    	    RESET = STORK_PCMCIA_B_RESET;
+        }
+    
+/*
+        if (storkTestGPIO(DETECT)) {
+           printk("no card detected - but resetting anyway\r\n");
+        }
+*/
+	switch (configure->vcc) {
+	case 0:
+		storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
+                storkClearLatchA(POWER);
+		break;
+
+	case 50:
+	case 33:
+                storkSetLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
+                storkSetLatchA(POWER);
+		break;
+
+	default:
+		printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+		       configure->vcc);
+		restore_flags(flags);
+		return -1;
+	}
+
+	if (configure->reset)
+                storkSetLatchB(RESET);
+	else
+                storkClearLatchB(RESET);
+
+	restore_flags(flags);
+
+        /* silently ignore vpp and speaker enables. */
+
+        printk(__FUNCTION__ ": finished\n");
+
+        return 0;
+}
+
+struct pcmcia_low_level stork_pcmcia_ops = { 
+        stork_pcmcia_init,
+        stork_pcmcia_shutdown,
+        stork_pcmcia_socket_state,
+        stork_pcmcia_get_irq_info,
+        stork_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_xp860.c linux/drivers/pcmcia/sa1100_xp860.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_xp860.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_xp860.c	Thu Oct 11 09:43:29 2001
@@ -0,0 +1,255 @@
+/*
+ * drivers/pcmcia/sa1100_xp860.c
+ *
+ * XP860 PCMCIA specific routines
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+#define NCR_A0VPP	(1<<16)
+#define NCR_A1VPP	(1<<17)
+
+static int xp860_pcmcia_init(struct pcmcia_init *init){
+  int return_val=0;
+
+  /* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
+  PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
+  
+  /* MAX1600 to standby mode: */
+  PA_DWR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
+  GPDR |= (NCR_A0VPP | NCR_A1VPP);
+  GPCR &= ~(NCR_A0VPP | NCR_A1VPP);
+
+  INTPOL1 |= 
+    (1 << (S0_READY_NINT - SA1111_IRQ(32))) |
+    (1 << (S1_READY_NINT - SA1111_IRQ(32))) |
+    (1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+    (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+    (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+    (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32)));
+
+  return_val+=request_irq(S0_CD_VALID, init->handler, SA_INTERRUPT,
+			  "XP860 PCMCIA (0) CD", NULL);
+  return_val+=request_irq(S1_CD_VALID, init->handler, SA_INTERRUPT,
+			  "XP860 CF (1) CD", NULL);
+  return_val+=request_irq(S0_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+			  "XP860 PCMCIA (0) BVD1", NULL);
+  return_val+=request_irq(S1_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+			  "XP860 CF (1) BVD1", NULL);
+
+  return (return_val<0) ? -1 : 2;
+}
+
+static int xp860_pcmcia_shutdown(void){
+
+  free_irq(S0_CD_VALID, NULL);
+  free_irq(S1_CD_VALID, NULL);
+  free_irq(S0_BVD1_STSCHG, NULL);
+  free_irq(S1_BVD1_STSCHG, NULL);
+
+  INTPOL1 &= 
+    ~((1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+      (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+      (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+      (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32))));
+
+  return 0;
+}
+
+static int xp860_pcmcia_socket_state(struct pcmcia_state_array
+					*state_array){
+  unsigned long status;
+  int return_val=1;
+
+  if(state_array->size<2) return -1;
+
+  memset(state_array->state, 0, 
+	 (state_array->size)*sizeof(struct pcmcia_state));
+
+  status=PCSR;
+
+  state_array->state[0].detect=((status & PCSR_S0_DETECT)==0)?1:0;
+
+  state_array->state[0].ready=((status & PCSR_S0_READY)==0)?0:1;
+
+  state_array->state[0].bvd1=((status & PCSR_S0_BVD1)==0)?0:1;
+
+  state_array->state[0].bvd2=((status & PCSR_S0_BVD2)==0)?0:1;
+
+  state_array->state[0].wrprot=((status & PCSR_S0_WP)==0)?0:1;
+
+  state_array->state[0].vs_3v=((status & PCSR_S0_VS1)==0)?1:0;
+
+  state_array->state[0].vs_Xv=((status & PCSR_S0_VS2)==0)?1:0;
+
+  state_array->state[1].detect=((status & PCSR_S1_DETECT)==0)?1:0;
+
+  state_array->state[1].ready=((status & PCSR_S1_READY)==0)?0:1;
+
+  state_array->state[1].bvd1=((status & PCSR_S1_BVD1)==0)?0:1;
+
+  state_array->state[1].bvd2=((status & PCSR_S1_BVD2)==0)?0:1;
+
+  state_array->state[1].wrprot=((status & PCSR_S1_WP)==0)?0:1;
+
+  state_array->state[1].vs_3v=((status & PCSR_S1_VS1)==0)?1:0;
+
+  state_array->state[1].vs_Xv=((status & PCSR_S1_VS2)==0)?1:0;
+
+  return return_val;
+}
+
+static int xp860_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+
+  switch(info->sock){
+  case 0:
+    info->irq=S0_READY_NINT;
+    break;
+
+  case 1:
+    info->irq=S1_READY_NINT;
+    break;
+
+  default:
+    return -1;
+  }
+
+  return 0;
+}
+
+static int xp860_pcmcia_configure_socket(const struct pcmcia_configure
+					    *configure){
+  unsigned long pccr=PCCR, ncr=GPLR, gpio=PA_DWR;
+
+
+  /* Neponset uses the Maxim MAX1600, with the following connections:
+   *
+   *   MAX1600      Neponset
+   *
+   *    A0VCC        SA-1111 GPIO A<1>
+   *    A1VCC        SA-1111 GPIO A<0>
+   *    A0VPP        CPLD NCR A0VPP
+   *    A1VPP        CPLD NCR A1VPP
+   *    B0VCC        SA-1111 GPIO A<2>
+   *    B1VCC        SA-1111 GPIO A<3>
+   *    B0VPP        ground (slot B is CF)
+   *    B1VPP        ground (slot B is CF)
+   *
+   *     VX          VCC (5V)
+   *     VY          VCC3_3 (3.3V)
+   *     12INA       12V
+   *     12INB       ground (slot B is CF)
+   *
+   * The MAX1600 CODE pin is tied to ground, placing the device in 
+   * "Standard Intel code" mode. Refer to the Maxim data sheet for
+   * the corresponding truth table.
+   */
+
+  switch(configure->sock){
+  case 0:
+    
+    switch(configure->vcc){
+    case 0:
+      gpio&=~(GPIO_GPIO0 | GPIO_GPIO1);
+      break;
+
+    case 33:
+      pccr=(pccr & ~PCCR_S0_PSE);
+      gpio=(gpio & ~(GPIO_GPIO0 | GPIO_GPIO1)) | GPIO_GPIO1;
+      break;
+
+    case 50:
+      pccr=(pccr | PCCR_S0_PSE);
+      gpio=(gpio & ~(GPIO_GPIO0 | GPIO_GPIO1)) | GPIO_GPIO0;
+      break;
+
+    default:
+      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+	     configure->vcc);
+      return -1;
+    }
+
+    switch(configure->vpp){
+    case 0:
+      ncr&=~(NCR_A0VPP | NCR_A1VPP);
+      break;
+
+    case 120:
+      ncr=(ncr & ~(NCR_A0VPP | NCR_A1VPP)) | NCR_A1VPP;
+      break;
+
+    default:
+      if(configure->vpp == configure->vcc)
+	ncr=(ncr & ~(NCR_A0VPP | NCR_A1VPP)) | NCR_A0VPP;
+      else {
+	printk(KERN_ERR "%s(): unrecognized Vpp %u\n", __FUNCTION__,
+	       configure->vpp);
+	return -1;
+      }
+    }
+
+    pccr=(configure->reset)?(pccr | PCCR_S0_RST):(pccr & ~PCCR_S0_RST);
+    pccr=(configure->output)?(pccr | PCCR_S0_FLT):(pccr & ~PCCR_S0_FLT);
+
+    break;
+
+  case 1:
+    switch(configure->vcc){
+    case 0:
+      gpio&=~(GPIO_GPIO2 | GPIO_GPIO3);
+      break;
+
+    case 33:
+      pccr=(pccr & ~PCCR_S1_PSE);
+      gpio=(gpio & ~(GPIO_GPIO2 | GPIO_GPIO3)) | GPIO_GPIO2;
+      break;
+
+    case 50:
+      pccr=(pccr | PCCR_S1_PSE);
+      gpio=(gpio & ~(GPIO_GPIO2 | GPIO_GPIO3)) | GPIO_GPIO3;
+      break;
+
+    default:
+      printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+	     configure->vcc);
+      return -1;
+    }
+
+    if(configure->vpp!=configure->vcc && configure->vpp!=0){
+      printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n", __FUNCTION__,
+	     configure->vpp);
+      return -1;
+    }
+
+    pccr=(configure->reset)?(pccr | PCCR_S1_RST):(pccr & ~PCCR_S1_RST);
+    pccr=(configure->output)?(pccr | PCCR_S1_FLT):(pccr & ~PCCR_S1_FLT);
+
+    break;
+
+  default:
+    return -1;
+  }
+
+  PCCR = pccr;
+  ncr &= NCR_A0VPP|NCR_A1VPP;
+  GPSR = ncr;
+  GPCR = (~ncr)&(NCR_A0VPP|NCR_A1VPP);
+  PA_DWR = gpio;
+
+  return 0;
+}
+
+struct pcmcia_low_level xp860_pcmcia_ops = { 
+  xp860_pcmcia_init,
+  xp860_pcmcia_shutdown,
+  xp860_pcmcia_socket_state,
+  xp860_pcmcia_get_irq_info,
+  xp860_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_yopy.c linux/drivers/pcmcia/sa1100_yopy.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_yopy.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_yopy.c	Thu Oct 11 09:43:29 2001
@@ -0,0 +1,139 @@
+/*
+ * drivers/pcmcia/sa1100_yopy.c
+ *
+ * PCMCIA implementation routines for Yopy
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+
+static inline void pcmcia_power(int on) {
+	/* high for power up */
+	yopy_gpio_set(GPIO_CF_POWER, on);
+}
+
+static inline void pcmcia_reset(int reset)
+{
+	/* high for reset */
+	yopy_gpio_set(GPIO_CF_RESET, reset);
+}
+
+static int yopy_pcmcia_init(struct pcmcia_init *init)
+{
+	int irq, res;
+
+	pcmcia_power(0);
+	pcmcia_reset(1);
+
+	/* All those are inputs */
+	GPDR &= ~(GPIO_CF_CD | GPIO_CF_BVD2 | GPIO_CF_BVD1 | GPIO_CF_IREQ);
+	GAFR &= ~(GPIO_CF_CD | GPIO_CF_BVD2 | GPIO_CF_BVD1 | GPIO_CF_IREQ);
+
+	/* Set transition detect */
+	set_GPIO_IRQ_edge( GPIO_CF_CD|GPIO_CF_BVD2|GPIO_CF_BVD1,
+			   GPIO_BOTH_EDGES );
+	set_GPIO_IRQ_edge( GPIO_CF_IREQ, GPIO_FALLING_EDGE );
+
+	/* Register interrupts */
+	irq = IRQ_CF_CD;
+	res = request_irq(irq, init->handler, SA_INTERRUPT, "CF_CD", NULL);
+	if (res < 0) goto irq_err;
+	irq = IRQ_CF_BVD2;
+	res = request_irq(irq, init->handler, SA_INTERRUPT, "CF_BVD2", NULL);
+	if (res < 0) goto irq_err;
+	irq = IRQ_CF_BVD1;
+	res = request_irq(irq, init->handler, SA_INTERRUPT, "CF_BVD1", NULL);
+	if (res < 0) goto irq_err;
+
+	return 1;
+irq_err:
+	printk(KERN_ERR "%s: Request for IRQ %d failed\n", __FUNCTION__, irq);
+	return -1;
+}
+
+static int yopy_pcmcia_shutdown(void)
+{
+	/* disable IRQs */
+	free_irq( IRQ_CF_CD, NULL );
+	free_irq( IRQ_CF_BVD2, NULL );
+	free_irq( IRQ_CF_BVD1, NULL );
+
+	/* Disable CF */
+	pcmcia_reset(1);
+	pcmcia_power(0);
+
+	return 0;
+}
+
+static int yopy_pcmcia_socket_state(struct pcmcia_state_array *state_array)
+{
+	unsigned long levels;
+
+	if (state_array->size != 1)
+		return -1;
+
+	memset(state_array->state, 0,
+	       state_array->size * sizeof(struct pcmcia_state));
+
+	levels = GPLR;
+
+	state_array->state[0].detect = (levels & GPIO_CF_CD)    ? 0 : 1;
+	state_array->state[0].ready  = (levels & GPIO_CF_READY) ? 1 : 0;
+	state_array->state[0].bvd1   = (levels & GPIO_CF_BVD1)  ? 1 : 0;
+	state_array->state[0].bvd2   = (levels & GPIO_CF_BVD2)  ? 1 : 0;
+	state_array->state[0].wrprot = 0; /* Not available on Yopy. */
+	state_array->state[0].vs_3v  = 0; /* FIXME Can only apply 3.3V on Yopy. */
+	state_array->state[0].vs_Xv  = 0;
+
+	return 1;
+}
+
+static int yopy_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+	if (info->sock != 0)
+		return -1;
+
+	info->irq = IRQ_CF_IREQ;
+
+	return 0;
+}
+
+static int yopy_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+{
+	if (configure->sock != 0)
+		return -1;
+
+	switch (configure->vcc) {
+	case 0:	/* power off */;
+		pcmcia_power(0);
+		break;
+	case 50:
+		printk(KERN_WARNING __FUNCTION__"(): CS asked for 5V, applying 3.3V..\n");
+	case 33:
+		pcmcia_power(1);
+		break;
+	default:
+		printk(KERN_ERR __FUNCTION__"(): unrecognized Vcc %u\n",
+		       configure->vcc);
+		return -1;
+	}
+
+	pcmcia_reset(configure->reset);
+
+	/* Silently ignore Vpp, output enable, speaker enable. */
+
+	return 0;
+}
+
+struct pcmcia_low_level yopy_pcmcia_ops = {
+	yopy_pcmcia_init,
+	yopy_pcmcia_shutdown,
+	yopy_pcmcia_socket_state,
+	yopy_pcmcia_get_irq_info,
+	yopy_pcmcia_configure_socket
+};
diff -u --recursive --new-file v2.4.12/linux/drivers/pnp/isapnp.c linux/drivers/pnp/isapnp.c
--- v2.4.12/linux/drivers/pnp/isapnp.c	Wed Jul 25 17:10:22 2001
+++ linux/drivers/pnp/isapnp.c	Thu Oct 11 09:43:29 2001
@@ -87,6 +87,7 @@
 MODULE_PARM_DESC(isapnp_reserve_io, "ISA Plug & Play - reserve I/O region(s) - port,size");
 MODULE_PARM(isapnp_reserve_mem, "1-16i");
 MODULE_PARM_DESC(isapnp_reserve_mem, "ISA Plug & Play - reserve memory region(s) - address,size");
+MODULE_LICENSE("GPL");
 
 #define _PIDXR		0x279
 #define _PNPWRP		0xa79
@@ -1673,8 +1674,8 @@
 	}
 	isapnp_for_each_dev(dev) {
 		if (dev->active) {
-			if (dev->irq_resource[0].start == irq ||
-			    dev->irq_resource[1].start == irq)
+			if ((dev->irq_resource[0].flags && dev->irq_resource[0].start == irq) ||
+			    (dev->irq_resource[1].flags && dev->irq_resource[1].start == irq))
 				return 1;
 		}
 	}
@@ -1763,7 +1764,8 @@
 	}
 	isapnp_for_each_dev(dev) {
 		if (dev->active) {
-			if (dev->dma_resource[0].start == dma || dev->dma_resource[1].start == dma)
+			if ((dev->dma_resource[0].flags && dev->dma_resource[0].start == dma) ||
+			    (dev->dma_resource[1].flags && dev->dma_resource[1].start == dma))
 				return 1;
 		}
 	}
@@ -1784,6 +1786,10 @@
 
 static int isapnp_valid_dma(struct isapnp_cfgtmp *cfg, int idx)
 {
+	/* DMA priority: this table is good for i386 */
+	static unsigned short xtab[16] = {
+		1, 3, 5, 6, 7, 0, 2, 4
+	};
 	int err, i;
 	unsigned long *value1, *value2;
 	struct isapnp_dma *dma;
@@ -1799,15 +1805,16 @@
       	value1 = &cfg->result.dma_resource[idx].start;
       	value2 = &cfg->result.dma_resource[idx].end;
 	if (cfg->result.dma_resource[idx].flags & IORESOURCE_AUTO) {
-		for (i = 0; i < 8 && !(dma->map & (1<<i)); i++);
+		for (i = 0; i < 8 && !(dma->map & (1<<xtab[i])); i++);
 		if (i >= 8)
 			return -ENOENT;
 		cfg->result.dma_resource[idx].flags &= ~IORESOURCE_AUTO;
-		if (!isapnp_check_dma(cfg, *value1 = *value2 = i, idx))
+		if (!isapnp_check_dma(cfg, *value1 = *value2 = xtab[i], idx))
 			return 0;
 	}
 	do {
-		for (i = *value1 + 1; i < 8 && !(dma->map & (1<<i)); i++);
+		for (i = 0; i < 8 && xtab[i] != *value1; i++);
+		for (i++; i < 8 && !(dma->map & (1<<xtab[i])); i++);
 		if (i >= 8) {
 			if (dma->res && dma->res->alt) {
 				if ((err = isapnp_alternative_switch(cfg, dma->res, dma->res->alt))<0)
@@ -1816,7 +1823,7 @@
 			}
 			return -ENOENT;
 		} else {
-			*value1 = *value2 = i;
+			*value1 = *value2 = xtab[i];
 		}
 	} while (isapnp_check_dma(cfg, *value1, idx));
 	return 0;
diff -u --recursive --new-file v2.4.12/linux/drivers/s390/block/dasd.c linux/drivers/s390/block/dasd.c
--- v2.4.12/linux/drivers/s390/block/dasd.c	Tue Oct  9 17:06:52 2001
+++ linux/drivers/s390/block/dasd.c	Thu Oct 11 09:43:29 2001
@@ -1092,9 +1092,11 @@
 		BUG ();
 		}
         if (device->lowmem_cqr==NULL) {
-                DASD_MESSAGE (KERN_WARNING, device, 
-                              "Low memory! Using emergency request %p",
-                              device->lowmem_ccws);
+                DASD_DRIVER_DEBUG_EVENT (2, dasd_alloc_request,
+                                         "(%04x) Low memory! Using emergency request %p.",
+                                         device->devinfo.devno,
+                                         device->lowmem_ccws);
+
                 device->lowmem_cqr=device->lowmem_ccws;
                 rv = device->lowmem_ccws;
 		memset (rv, 0, PAGE_SIZE);
@@ -1105,10 +1107,11 @@
 		rv->data = (void *) ((long) rv + PAGE_SIZE - datasize);
 		rv->cpaddr = (ccw1_t *) ((long) rv + sizeof (ccw_req_t));
         } else {
-                DASD_MESSAGE (KERN_WARNING, device,
-                              "Refusing emergency mem for request "
-                              "NULL, already in use at %p.",
-                              device->lowmem_ccws);
+                DASD_DRIVER_DEBUG_EVENT (2, dasd_alloc_request,
+                                         "(%04x) Refusing emergency mem for request "
+                                         "NULL, already in use at %p.",
+                                         device->devinfo.devno,
+                                         device->lowmem_ccws);
 	}
 	return rv;
 }
@@ -1219,6 +1222,7 @@
                         CQR_STATUS_QUEUED);
 
        
+#ifdef DASD_PROFILE
         /* save profile information for non erp cqr */
         if (cqr->refers == NULL) {
                 unsigned int  counter = 0;
@@ -1235,6 +1239,7 @@
                 dasd_global_profile.dasd_io_nr_req[counter]++;
                 device->profile.dasd_io_nr_req[counter]++;
         }
+#endif 
 }
 
 /*
@@ -1671,9 +1676,12 @@
 		    chanq_max_size > 0 || (req->nr_sectors >= chanq_min_size)) {
 			ccw_req_t *cqr = NULL;
                         if (is_read_only(device->kdev) && req->cmd == WRITE) {
-                            DASD_MESSAGE (KERN_WARNING, device,
-                                          "rejecting write request %p\n",
-                                          req);
+
+                                DASD_DRIVER_DEBUG_EVENT (3, dasd_int_handler,
+                                                         "(%04x) Rejecting write request %p\n",
+                                                         device->devinfo.devno,
+                                                         req);
+
                                 dasd_end_request (req, 0);
                                 dasd_dequeue_request (queue,req);
                         } else {
@@ -1683,9 +1691,12 @@
                                 part[MINOR (req->rq_dev)].start_sect;
                             cqr = device->discipline->build_cp_from_req (device, req);
                             if (cqr == NULL) {
-				    DASD_MESSAGE (KERN_WARNING, device,
-                                                  "CCW creation failed on request %p\n",
-                                                  req);
+
+                                    DASD_DRIVER_DEBUG_EVENT (3, dasd_int_handler,
+                                                             "(%04x) CCW creation failed "
+                                                             "on request %p\n",
+                                                             device->devinfo.devno,
+                                                             req);
                                     /* revert relocation of request */
                                     req->sector -=
                                         device->major_info->gendisk.
@@ -2032,7 +2043,7 @@
 	}
 
 	erp->cpaddr->cmd_code = CCW_CMD_TIC;
-	erp->cpaddr->cda = (__u32) (void *) cqr->cpaddr;
+	erp->cpaddr->cda = (__u32) (addr_t) cqr->cpaddr;
 	erp->function = dasd_default_erp_action;
 	erp->refers = cqr;
 	erp->device = cqr->device;
@@ -2232,13 +2243,7 @@
 	}
 	for (i = (1 << DASD_PARTN_BITS) - 1; i >= 0; i--) {
                 int major = device->major_info->gendisk.major;
-		int minor = start + i;
-		kdev_t devi = MKDEV (major, minor);
-		struct super_block *sb = get_super (devi);
-		//sync_dev (devi);
-		if (sb)
-			invalidate_inodes (sb);
-		invalidate_buffers (devi);
+		invalidate_device(MKDEV (major, start+i), 1);
 	}
         dasd_destroy_partitions(device);
         dasd_setup_partitions(device);
@@ -2285,20 +2290,20 @@
 #endif
 	switch (no) {
         case DASDAPIVER: {
-                       int ver = DASD_API_VERSION;
-                       rc = copy_to_user ((int *) data, &ver, sizeof (int));
-                       if (rc)
-                               rc = -EFAULT;
-                       break;
+			int ver = DASD_API_VERSION;
+			rc = put_user(ver, (int *) data);
+			break;
         }
 	case BLKGETSIZE:{	/* Return device size */
 			long blocks = major_info->gendisk.sizes 
                                       [MINOR (inp->i_rdev)] << 1;
-			rc =
-			    copy_to_user ((long *) data, &blocks,
-					  sizeof (long));
-			if (rc)
-				rc = -EFAULT;
+			rc = put_user(blocks, (long *) data);
+			break;
+		}
+	case BLKGETSIZE64:{
+			u64 blocks = major_info->gendisk.sizes 
+                                      [MINOR (inp->i_rdev)];
+			rc = put_user(blocks << 10, (u64 *) data);
 			break;
 		}
 	case BLKRRPART:{
@@ -3253,10 +3258,6 @@
         int rc = 0;
         unsigned long flags;
 
-        printk (KERN_ERR PRINTK_HEADER
-                "called dasd_state_accept_to_init for device %02x\n",
-                device->devinfo.devno);
-
         if ( device->discipline->init_analysis ) {
                 device->init_cqr=device->discipline->init_analysis (device);
                 if ( device->init_cqr != NULL ) {
@@ -3297,8 +3298,10 @@
                                 rc = -EMEDIUMTYPE;
                         }
         if ( device->init_cqr ) {
+                /* This pointer is no longer needed, BUT dont't free the       */ 
+                /* memory, because this is done in bh for finished request!!!! */
                 atomic_dec(&dasd_init_pending);
-                device->init_cqr = NULL; /* This one is no longer needed */
+                device->init_cqr = NULL; 
         }
         device->level = DASD_STATE_READY;
         return rc;
@@ -3378,7 +3381,6 @@
 dasd_deactivate_queue (dasd_device_t *device)
 {
         int i;
-        int major = MAJOR(device->kdev);
         int minor = MINOR(device->kdev);
 
         for (i = 0; i < (1 << DASD_PARTN_BITS); i++) {
@@ -3764,7 +3766,14 @@
 		vfree (buffer);
 		return -EFAULT;
 	}
-	buffer[user_len] = 0;
+
+        /* replace LF with '\0' */
+        if (buffer[user_len -1] == '\n') {
+                buffer[user_len -1] = '\0';
+        } else {
+                buffer[user_len] = '\0';
+        }
+
 	printk (KERN_INFO PRINTK_HEADER "/proc/dasd/devices: '%s'\n", buffer);
 	if (strncmp (buffer, "set ", 4) && strncmp (buffer, "add ", 4)) {
 		printk (KERN_WARNING PRINTK_HEADER
@@ -3798,7 +3807,7 @@
             range.to   == -EINVAL   ) {
                 
                 printk (KERN_WARNING PRINTK_HEADER
-                        "/proc/dasd/devices: parse error in '%s'", 
+                        "/proc/dasd/devices: range parse error in '%s'\n", 
                         buffer);
         } else {
                 off = (long) temp - (long) buffer;
@@ -3814,7 +3823,8 @@
                                 dasd_disable_ranges (&range, NULL, 0, 1);
                         } else {
                                 printk (KERN_WARNING PRINTK_HEADER
-                                        "/proc/dasd/devices: parse error in '%s'", buffer);
+                                        "/proc/dasd/devices: parse error in '%s'\n",
+                                        buffer);
                         }
                 }
         }
diff -u --recursive --new-file v2.4.12/linux/drivers/s390/block/dasd_3990_erp.c linux/drivers/s390/block/dasd_3990_erp.c
--- v2.4.12/linux/drivers/s390/block/dasd_3990_erp.c	Tue Oct  9 17:06:52 2001
+++ linux/drivers/s390/block/dasd_3990_erp.c	Thu Oct 11 09:43:29 2001
@@ -761,7 +761,7 @@
  * DASD_3990_HANDLE_ENV_DATA
  *
  * DESCRIPTION
- *   Handles 24 byte 'Enviromental data present'.
+ *   Handles 24 byte 'Environmental data present'.
  *   Does a analysis of the sense data (message Format)
  *   and prints the error messages.
  *
diff -u --recursive --new-file v2.4.12/linux/drivers/s390/char/Makefile linux/drivers/s390/char/Makefile
--- v2.4.12/linux/drivers/s390/char/Makefile	Sun Aug 12 13:28:00 2001
+++ linux/drivers/s390/char/Makefile	Thu Oct 11 09:43:29 2001
@@ -5,6 +5,7 @@
 O_TARGET := s390-char.o
 
 list-multi	:= tub3270.o tape390.o
+export-objs	:= hwc_rw.o
 
 tub3270-objs := tuball.o tubfs.o tubtty.o \
                      tubttyaid.o tubttybld.o tubttyscl.o \
diff -u --recursive --new-file v2.4.12/linux/drivers/s390/char/hwc_cpi.c linux/drivers/s390/char/hwc_cpi.c
--- v2.4.12/linux/drivers/s390/char/hwc_cpi.c	Tue Oct  9 17:06:52 2001
+++ linux/drivers/s390/char/hwc_cpi.c	Thu Oct 11 09:43:29 2001
@@ -9,7 +9,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/errno.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/version.h>
 #include <asm/semaphore.h>
 #include <asm/ebcdic.h>
diff -u --recursive --new-file v2.4.12/linux/drivers/s390/char/tape34xx.c linux/drivers/s390/char/tape34xx.c
--- v2.4.12/linux/drivers/s390/char/tape34xx.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/s390/char/tape34xx.c	Thu Oct 11 09:43:29 2001
@@ -1670,7 +1670,7 @@
 	tapestate_set (ti, TS_DONE);
 	ti->rc = 0;
 	ti->wanna_wakeup=1;
-	wake_up_interruptible (&ti->wq);
+	wake_up (&ti->wq);
 }
 
 void
@@ -2274,6 +2274,8 @@
 	ti->wanna_wakeup=1;
 	switch (tapestate_get(ti)) {
 	case TS_REW_RELEASE_INIT:
+	case TS_RFO_INIT:
+	case TS_RBA_INIT:
 	    tapestate_set(ti,TS_FAILED);
 	    wake_up (&ti->wq);
 	    break;
diff -u --recursive --new-file v2.4.12/linux/drivers/s390/char/tapechar.c linux/drivers/s390/char/tapechar.c
--- v2.4.12/linux/drivers/s390/char/tapechar.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/s390/char/tapechar.c	Thu Oct 11 09:43:29 2001
@@ -204,13 +204,9 @@
 	    return rc;
 	}
 	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
-	wait_event_interruptible (ti->wq,ti->wanna_wakeup);
+	wait_event (ti->wq,ti->wanna_wakeup);
 	ti->cqr = NULL;
 	ti->discipline->free_read_block (cqr, ti);
-	if (signal_pending (current)) {
-		tapestate_set (ti, TS_IDLE);
-		return -ERESTARTSYS;
-	}
 	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
 	if (tapestate_get (ti) == TS_FAILED) {
 		tapestate_set (ti, TS_IDLE);
diff -u --recursive --new-file v2.4.12/linux/drivers/s390/char/tuball.c linux/drivers/s390/char/tuball.c
--- v2.4.12/linux/drivers/s390/char/tuball.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/s390/char/tuball.c	Thu Oct 11 09:43:29 2001
@@ -93,8 +93,8 @@
 	NULL			/* next */
 };
 
-bcb_t tub3270_con_bcb;			/* Buffer that receives con writes */
-spinlock_t tub3270_con_bcblock;		/* Lock for the buffer */
+static bcb_t tub3270_con_bcb;		/* Buffer that receives con writes */
+static spinlock_t tub3270_con_bcblock;	/* Lock for the buffer */
 int tub3270_con_irq = -1;		/* set nonneg by _activate() */
 tub_t *tub3270_con_tubp;		/* set nonzero by _activate() */
 struct tty_driver tty3270_con_driver;	/* for /dev/console at 4, 64 */
diff -u --recursive --new-file v2.4.12/linux/drivers/s390/char/tubtty.c linux/drivers/s390/char/tubtty.c
--- v2.4.12/linux/drivers/s390/char/tubtty.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/s390/char/tubtty.c	Thu Oct 11 09:43:29 2001
@@ -992,8 +992,8 @@
 
 	if (tty)
 		len += sprintf(buf+len,
-				"    write_wait=%.8x read_wait=%.8x\n",
-				(int)&tty->write_wait, (int)&tty->read_wait);
+				"    write_wait=%p read_wait=%p\n",
+				&tty->write_wait, &tty->read_wait);
 
 	if (tty && ((mp = tty->termios)))
 		len += sprintf(buf+len,"    iflag=%.8x oflag=%.8x "
diff -u --recursive --new-file v2.4.12/linux/drivers/s390/net/ctcmain.c linux/drivers/s390/net/ctcmain.c
--- v2.4.12/linux/drivers/s390/net/ctcmain.c	Tue Oct  9 17:06:52 2001
+++ linux/drivers/s390/net/ctcmain.c	Thu Oct 11 09:43:29 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: ctcmain.c,v 1.49 2001/08/31 14:50:05 felfert Exp $
+ * $Id: ctcmain.c,v 1.51 2001/09/24 10:38:02 mschwide Exp $
  *
  * CTC / ESCON network driver
  *
@@ -35,7 +35,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.49 $
+ * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.51 $
  *
  */
 
@@ -43,7 +43,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
@@ -96,6 +96,7 @@
 #ifdef MODULE
 MODULE_AUTHOR("(C) 2000 IBM Corp. by Fritz Elfert (felfert@millenux.com)");
 MODULE_DESCRIPTION("Linux for S/390 CTC/Escon Driver");
+MODULE_LICENSE("GPL");
 #ifndef CTC_CHANDEV
 MODULE_PARM(ctc, "s");
 MODULE_PARM_DESC(ctc,
@@ -296,6 +297,8 @@
 	net_device          *netdev;
 
 	ctc_profile         prof;
+
+	unsigned char       *trans_skb_data;
 } channel;
 
 #define CHANNEL_FLAGS_READ            0
@@ -382,7 +385,7 @@
  */
 static void print_banner(void) {
 	static int printed = 0;
-	char vbuf[] = "$Revision: 1.49 $";
+	char vbuf[] = "$Revision: 1.51 $";
 	char *version = vbuf;
 
 	if (printed)
@@ -951,6 +954,7 @@
 			return -ENOMEM;
 		}
 		ch->ccw[1].count = 0;
+		ch->trans_skb_data = ch->trans_skb->data;
 		ch->flags &= ~CHANNEL_FLAGS_BUFSIZE_CHANGED;
 	}
 	return 0;
@@ -1016,7 +1020,7 @@
 			spin_unlock(&ch->collect_lock);
 			return;
 		}
-		ch->trans_skb->tail = ch->trans_skb->data;
+		ch->trans_skb->tail = ch->trans_skb->data = ch->trans_skb_data;
 		ch->trans_skb->len = 0;
 		if (ch->prof.maxmulti < (ch->collect_len + 2))
 			ch->prof.maxmulti = ch->collect_len + 2;
@@ -1089,7 +1093,6 @@
 	int            len = ch->max_bufsize - ch->devstat->rescnt;
 	struct sk_buff *skb = ch->trans_skb;
 	__u16          block_len = *((__u16*)skb->data);
-	char           *saved_data = skb->data;
 	int            check_len;
 	int            rc;
 
@@ -1138,7 +1141,7 @@
 		ctc_unpack_skb(ch, skb);
 	}
  again:
-	skb->data = skb->tail = saved_data;
+	skb->data = skb->tail = ch->trans_skb_data;
 	skb->len = 0;
 	if (ctc_checkalloc_buffer(ch, 1))
 		return;
@@ -1548,9 +1551,9 @@
 	channel *ch = (channel *)arg;
 	net_device *dev = ch->netdev;
 
+	fsm_deltimer(&ch->timer);
 	printk(KERN_DEBUG "%s: %s channel restart\n", dev->name,
 	       (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
-
 	fsm_addtimer(&ch->timer, CTC_TIMEOUT_5SEC, CH_EVENT_TIMER, ch);
 	oldstate = fsm_getstate(fi);
 	fsm_newstate(fi, CH_STATE_STARTWAIT);
@@ -1716,8 +1719,7 @@
 #ifdef DEBUG
 	printk(KERN_DEBUG "ccw[4].cda = %08x\n", ch->ccw[4].cda);
 #endif
-			rc = do_IO(ch->irq, &ch->ccw[3],
-				   (intparm_t)ch, 0xff, 0);
+			rc = do_IO(ch->irq, &ch->ccw[3], (intparm_t)ch, 0xff, 0);
 			if (event == CH_EVENT_TIMER)
 				s390irq_spin_unlock_irqrestore(ch->irq,
 							       saveflags);
@@ -2539,7 +2541,8 @@
 		if (rc != 0) {
 			fsm_deltimer(&ch->timer);
 			ccw_check_return_code(ch, rc);
-			skb_dequeue_tail(&ch->io_queue);
+			if (ccw_idx == 3)
+				skb_dequeue_tail(&ch->io_queue);
 			/**
 			 * Remove our header. It gets added
 			 * again on retransmit.
diff -u --recursive --new-file v2.4.12/linux/drivers/s390/net/iucv.c linux/drivers/s390/net/iucv.c
--- v2.4.12/linux/drivers/s390/net/iucv.c	Tue Oct  9 17:06:52 2001
+++ linux/drivers/s390/net/iucv.c	Thu Oct 11 09:43:29 2001
@@ -39,7 +39,7 @@
 #include <linux/version.h>
 #include <linux/spinlock.h>
 #include <linux/kernel.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/tqueue.h>
 #include <linux/interrupt.h>
@@ -53,10 +53,6 @@
 
 #undef DEBUG
 
-#ifndef min
-#define min(a,b) (((a)<(b))?(a):(b))
-#endif
-
 /* FLAGS:
  * All flags are defined in the field IPFLAGS1 of each function
  * and can be found in CP Programming Services.
@@ -1163,7 +1159,7 @@
 
 	parm = (iparml_db *)grab_param();
 
-	parm->ipbfadr1 = (__u32) buffer;
+	parm->ipbfadr1 = (__u32) (addr_t) buffer;
 	parm->ipbfln1f = (__u32) ((ulong) buflen);
 	parm->ipmsgid = msgid;
 	parm->ippathid = pathid;
@@ -1186,7 +1182,7 @@
 			if (residual_buffer)
 				*residual_buffer = parm->ipbfadr1;
 		} else {
-			moved = min (buflen, 8);
+			moved = min_t (unsigned long, buflen, 8);
 
 			memcpy ((char *) buffer,
 				(char *) &parm->ipbfadr1, moved);
@@ -1283,7 +1279,8 @@
 
 			while ((moved < 8) && (moved < buflen)) {
 				dyn_len =
-				    min ((buffer + i)->length, need_to_move);
+				    min_t (unsigned int,
+					 (buffer + i)->length, need_to_move);
 
 				memcpy ((char *)((ulong)((buffer + i)->address)),
 					((char *) &parm->ipbfadr1) + moved,
diff -u --recursive --new-file v2.4.12/linux/drivers/s390/net/netiucv.c linux/drivers/s390/net/netiucv.c
--- v2.4.12/linux/drivers/s390/net/netiucv.c	Tue Oct  9 17:06:52 2001
+++ linux/drivers/s390/net/netiucv.c	Thu Oct 11 09:43:29 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: netiucv.c,v 1.11 2001/07/16 17:00:02 felfert Exp $
+ * $Id: netiucv.c,v 1.12 2001/09/24 10:38:02 mschwide Exp $
  *
  * IUCV network driver
  *
@@ -28,7 +28,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: IUCV network driver $Revision: 1.11 $
+ * RELEASE-TAG: IUCV network driver $Revision: 1.12 $
  *
  */
 
@@ -36,7 +36,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
@@ -2002,7 +2002,7 @@
 static void
 netiucv_banner(void)
 {
-	char vbuf[] = "$Revision: 1.11 $";
+	char vbuf[] = "$Revision: 1.12 $";
 	char *version = vbuf;
 
 	if ((version = strchr(version, ':'))) {
@@ -2115,7 +2115,8 @@
 	return 0;
 }
 
-module_init(netiucv_init);
 #ifdef MODULE
+module_init(netiucv_init);
 module_exit(netiucv_exit);
+MODULE_LICENSE("GPL");
 #endif
diff -u --recursive --new-file v2.4.12/linux/drivers/sbus/audio/amd7930.c linux/drivers/sbus/audio/amd7930.c
--- v2.4.12/linux/drivers/sbus/audio/amd7930.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/sbus/audio/amd7930.c	Thu Oct 11 09:43:29 2001
@@ -1716,6 +1716,7 @@
 
 module_init(amd7930_init);
 module_exit(amd7930_exit);
+MODULE_LICENSE("GPL");
 
 /*************************************************************/
 /*                 Audio format conversion                   */
diff -u --recursive --new-file v2.4.12/linux/drivers/sbus/char/bpp.c linux/drivers/sbus/char/bpp.c
--- v2.4.12/linux/drivers/sbus/char/bpp.c	Thu Oct 11 08:02:26 2001
+++ linux/drivers/sbus/char/bpp.c	Thu Oct 11 09:43:29 2001
@@ -1073,4 +1073,3 @@
 
 module_init(bpp_init);
 module_exit(bpp_cleanup);
-MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/53c700.c linux/drivers/scsi/53c700.c
--- v2.4.12/linux/drivers/scsi/53c700.c	Tue Oct  9 17:06:52 2001
+++ linux/drivers/scsi/53c700.c	Thu Oct 11 09:43:29 2001
@@ -51,6 +51,12 @@
 
 /* CHANGELOG
  *
+ * Version 2.6
+ *
+ * Following test of the 64 bit parisc kernel by Richard Hirst,
+ * several problems have now been corrected.  Also adds support for
+ * consistent memory allocation.
+ *
  * Version 2.5
  * 
  * More Compatibility changes for 710 (now actually works).  Enhanced
@@ -90,7 +96,7 @@
  * Initial modularisation from the D700.  See NCR_D700.c for the rest of
  * the changelog.
  * */
-#define NCR_700_VERSION "2.5"
+#define NCR_700_VERSION "2.6"
 
 #include <linux/config.h>
 #include <linux/version.h>
@@ -217,18 +223,39 @@
 NCR_700_detect(Scsi_Host_Template *tpnt,
 	       struct NCR_700_Host_Parameters *hostdata)
 {
-	dma_addr_t pScript, pSlots;
+	dma_addr_t pScript, pMemory, pSlots;
+	__u8 *memory;
 	__u32 *script;
 	struct Scsi_Host *host;
 	static int banner = 0;
 	int j;
 
-	/* This separation of pScript and script is not strictly
-	 * necessay, but may be useful in architectures which can
-	 * allocate consistent memory on which virt_to_bus will not
-	 * work */
-	script = kmalloc(sizeof(SCRIPT), GFP_KERNEL);
-	pScript = virt_to_bus(script);
+#ifdef CONFIG_53C700_USE_CONSISTENT
+	memory = pci_alloc_consistent(hostdata->pci_dev, TOTAL_MEM_SIZE,
+				      &pMemory);
+	hostdata->consistent = 1;
+	if(memory == NULL ) {
+		printk(KERN_WARNING "53c700: consistent memory allocation failed\n");
+#endif
+		memory = kmalloc(TOTAL_MEM_SIZE, GFP_KERNEL);
+		if(memory == NULL) {
+			printk(KERN_ERR "53c700: Failed to allocate memory for driver, detatching\n");
+			return NULL;
+		}
+		pMemory = pci_map_single(hostdata->pci_dev, memory,
+					 TOTAL_MEM_SIZE, PCI_DMA_BIDIRECTIONAL);
+#ifdef CONFIG_53C700_USE_CONSISTENT
+		hostdata->consistent = 0;
+	}
+#endif
+	script = (__u32 *)memory;
+	pScript = pMemory;
+	hostdata->msgin = memory + MSGIN_OFFSET;
+	hostdata->msgout = memory + MSGOUT_OFFSET;
+	hostdata->status = memory + STATUS_OFFSET;
+	hostdata->slots = (struct NCR_700_command_slot *)(memory + SLOTS_OFFSET);
+		
+	pSlots = pMemory + SLOTS_OFFSET;
 
 	/* Fill in the missing routines from the host template */
 	tpnt->queuecommand = NCR_700_queuecommand;
@@ -251,29 +278,6 @@
 
 	if((host = scsi_register(tpnt, 4)) == NULL)
 		return NULL;
-	if(script == NULL) {
-		printk(KERN_ERR "53c700: Failed to allocate script, detatching\n");
-		scsi_unregister(host);
-		return NULL;
-	}
-
-	/* This separation of slots and pSlots may facilitate later
-	 * migration to consistent memory on architectures which
-	 * support it */
-	hostdata->slots = kmalloc(sizeof(struct NCR_700_command_slot)
-				  * NCR_700_COMMAND_SLOTS_PER_HOST,
-				  GFP_KERNEL);
-	pSlots = virt_to_bus(hostdata->slots);
-
-	hostdata->msgin = kmalloc(MSG_ARRAY_SIZE, GFP_KERNEL);
-	hostdata->msgout = kmalloc(MSG_ARRAY_SIZE, GFP_KERNEL);
-	hostdata->status = kmalloc(MSG_ARRAY_SIZE, GFP_KERNEL);
-	if(hostdata->slots == NULL || hostdata->msgin == NULL
-	   || hostdata->msgout == NULL || hostdata->status==NULL) {
-		printk(KERN_ERR "53c700: Failed to allocate command slots or message buffers, detatching\n");
-		scsi_unregister(host);
-		return NULL;
-	}
 	memset(hostdata->slots, 0, sizeof(struct NCR_700_command_slot)
 	       * NCR_700_COMMAND_SLOTS_PER_HOST);
 	for(j = 0; j < NCR_700_COMMAND_SLOTS_PER_HOST; j++) {
@@ -295,19 +299,17 @@
 	for(j = 0; j < PATCHES; j++) {
 		script[LABELPATCHES[j]] = bS_to_host(pScript + SCRIPT[LABELPATCHES[j]]);
 	}
-	/* now patch up fixed addresses. 
-	 * NOTE: virt_to_bus may be wrong if consistent memory is used
-	 * for these in the future */
+	/* now patch up fixed addresses. */
 	script_patch_32(script, MessageLocation,
-			virt_to_bus(&hostdata->msgout[0]));
+			pScript + MSGOUT_OFFSET);
 	script_patch_32(script, StatusAddress,
-			virt_to_bus(&hostdata->status[0]));
+			pScript + STATUS_OFFSET);
 	script_patch_32(script, ReceiveMsgAddress,
-			virt_to_bus(&hostdata->msgin[0]));
+			pScript + MSGIN_OFFSET);
 
 	hostdata->script = script;
 	hostdata->pScript = pScript;
-	dma_cache_wback((unsigned long)script, sizeof(SCRIPT));
+	NCR_700_dma_cache_wback((unsigned long)script, sizeof(SCRIPT));
 	hostdata->state = NCR_700_HOST_FREE;
 	spin_lock_init(&hostdata->lock);
 	hostdata->cmd = NULL;
@@ -344,13 +346,18 @@
 	struct NCR_700_Host_Parameters *hostdata = 
 		(struct NCR_700_Host_Parameters *)host->hostdata[0];
 
-	/* NOTE: these may be NULL if we weren't fully initialised before
-	 * the scsi_unregister was called */
-	kfree(hostdata->script);
-	kfree(hostdata->slots);
-	kfree(hostdata->msgin);
-	kfree(hostdata->msgout);
-	kfree(hostdata->status);
+#ifdef CONFIG_53C700_USE_CONSISTENT
+	if(hostdata->consistent) {
+		pci_free_consistent(hostdata->pci_dev, TOTAL_MEM_SIZE,
+				    hostdata->script, hostdata->pScript);
+	} else {
+#endif
+		pci_unmap_single(hostdata->pci_dev, hostdata->pScript,
+				 TOTAL_MEM_SIZE, PCI_DMA_BIDIRECTIONAL);
+		kfree(hostdata->script);
+#ifdef CONFIG_53C700_USE_CONSISTENT
+	}
+#endif
 	return 1;
 }
 
@@ -620,7 +627,25 @@
 	}
 	return (offset & 0x0f) | (XFERP & 0x07)<<4;
 }
-	
+
+STATIC inline void
+NCR_700_unmap(struct NCR_700_Host_Parameters *hostdata, Scsi_Cmnd *SCp,
+	      struct NCR_700_command_slot *slot)
+{
+	if(SCp->sc_data_direction != SCSI_DATA_NONE &&
+	   SCp->sc_data_direction != SCSI_DATA_UNKNOWN) {
+		int pci_direction = scsi_to_pci_dma_dir(SCp->sc_data_direction);
+		if(SCp->use_sg) {
+			pci_unmap_sg(hostdata->pci_dev, SCp->buffer,
+				     SCp->use_sg, pci_direction);
+		} else {
+			pci_unmap_single(hostdata->pci_dev,
+					 slot->dma_handle,
+					 SCp->request_bufflen,
+					 pci_direction);
+		}
+	}
+}
 
 STATIC inline void
 NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata,
@@ -632,31 +657,22 @@
 	if(SCp != NULL) {
 		struct NCR_700_command_slot *slot = 
 			(struct NCR_700_command_slot *)SCp->host_scribble;
-
+		
+		NCR_700_unmap(hostdata, SCp, slot);
+		pci_unmap_single(hostdata->pci_dev, slot->pCmd,
+				 sizeof(SCp->cmnd), PCI_DMA_TODEVICE);
 		if(SCp->cmnd[0] == REQUEST_SENSE && SCp->cmnd[6] == NCR_700_INTERNAL_SENSE_MAGIC) {
 #ifdef NCR_700_DEBUG
 			printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n",
 			       SCp, SCp->cmnd[7], result);
 			print_sense("53c700", SCp);
+
 #endif
+			SCp->use_sg = SCp->cmnd[8];
 			if(result == 0)
 				result = SCp->cmnd[7];
 		}
 
-		if(SCp->sc_data_direction != SCSI_DATA_NONE &&
-		   SCp->sc_data_direction != SCSI_DATA_UNKNOWN) {
-			int pci_direction = scsi_to_pci_dma_dir(SCp->sc_data_direction);
-			if(SCp->use_sg) {
-				pci_unmap_sg(hostdata->pci_dev, SCp->buffer,
-					     SCp->use_sg, pci_direction);
-			} else {
-				pci_unmap_single(hostdata->pci_dev,
-						 slot->dma_handle,
-						 SCp->request_bufflen,
-						 pci_direction);
-			}
-		}
-
 		free_slot(slot, hostdata);
 
 		SCp->host_scribble = NULL;
@@ -850,7 +866,7 @@
 			printk(KERN_WARNING "scsi%d Unexpected SDTR msg\n",
 			       host->host_no);
 			hostdata->msgout[0] = A_REJECT_MSG;
-			dma_cache_wback((unsigned long)hostdata->msgout, 1);
+			NCR_700_dma_cache_wback((unsigned long)hostdata->msgout, 1);
 			script_patch_16(hostdata->script, MessageCount, 1);
 			/* SendMsgOut returns, so set up the return
 			 * address */
@@ -862,7 +878,7 @@
 		printk(KERN_INFO "scsi%d: (%d:%d), Unsolicited WDTR after CMD, Rejecting\n",
 		       host->host_no, pun, lun);
 		hostdata->msgout[0] = A_REJECT_MSG;
-		dma_cache_wback((unsigned long)hostdata->msgout, 1);
+		NCR_700_dma_cache_wback((unsigned long)hostdata->msgout, 1);
 		script_patch_16(hostdata->script, MessageCount, 1);
 		resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
 
@@ -876,7 +892,7 @@
 		printk("\n");
 		/* just reject it */
 		hostdata->msgout[0] = A_REJECT_MSG;
-		dma_cache_wback((unsigned long)hostdata->msgout, 1);
+		NCR_700_dma_cache_wback((unsigned long)hostdata->msgout, 1);
 		script_patch_16(hostdata->script, MessageCount, 1);
 		/* SendMsgOut returns, so set up the return
 		 * address */
@@ -954,7 +970,7 @@
 		printk("\n");
 		/* just reject it */
 		hostdata->msgout[0] = A_REJECT_MSG;
-		dma_cache_wback((unsigned long)hostdata->msgout, 1);
+		NCR_700_dma_cache_wback((unsigned long)hostdata->msgout, 1);
 		script_patch_16(hostdata->script, MessageCount, 1);
 		/* SendMsgOut returns, so set up the return
 		 * address */
@@ -964,7 +980,7 @@
 	}
 	NCR_700_writel(temp, host, TEMP_REG);
 	/* set us up to receive another message */
-	dma_cache_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);
+	NCR_700_dma_cache_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);
 	return resume_offset;
 }
 
@@ -1002,10 +1018,15 @@
 				printk("  cmd %p has status %d, requesting sense\n",
 				       SCp, hostdata->status[0]);
 #endif
-				/* we can destroy the command here because the
-				 * contingent allegiance condition will cause a 
-				 * retry which will re-copy the command from the
-				 * saved data_cmnd */
+				/* we can destroy the command here
+				 * because the contingent allegiance
+				 * condition will cause a retry which
+				 * will re-copy the command from the
+				 * saved data_cmnd.  We also unmap any
+				 * data associated with the command
+				 * here */
+				NCR_700_unmap(hostdata, SCp, slot);
+
 				SCp->cmnd[0] = REQUEST_SENSE;
 				SCp->cmnd[1] = (SCp->lun & 0x7) << 5;
 				SCp->cmnd[2] = 0;
@@ -1013,21 +1034,29 @@
 				SCp->cmnd[4] = sizeof(SCp->sense_buffer);
 				SCp->cmnd[5] = 0;
 				SCp->cmd_len = 6;
-				/* Here's a quiet hack: the REQUEST_SENSE command is
-				 * six bytes, so store a flag indicating that this
-				 * was an internal sense request and the original
-				 * status at the end of the command */
+				/* Here's a quiet hack: the
+				 * REQUEST_SENSE command is six bytes,
+				 * so store a flag indicating that
+				 * this was an internal sense request
+				 * and the original status at the end
+				 * of the command */
 				SCp->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC;
 				SCp->cmnd[7] = hostdata->status[0];
+				SCp->cmnd[8] = SCp->use_sg;
+				SCp->use_sg = 0;
 				SCp->sc_data_direction = SCSI_DATA_READ;
-				dma_cache_wback((unsigned long)SCp->cmnd, SCp->cmd_len);
+				pci_dma_sync_single(hostdata->pci_dev,
+						    slot->pCmd,
+						    SCp->cmd_len,
+						    PCI_DMA_TODEVICE);
+				slot->dma_handle = pci_map_single(hostdata->pci_dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), PCI_DMA_FROMDEVICE);
 				slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer));
-				slot->SG[0].pAddr = bS_to_host(virt_to_bus(SCp->sense_buffer));
+				slot->SG[0].pAddr = bS_to_host(slot->dma_handle);
 				slot->SG[1].ins = bS_to_host(SCRIPT_RETURN);
 				slot->SG[1].pAddr = 0;
 				slot->resume_offset = hostdata->pScript;
-				dma_cache_wback((unsigned long)slot->SG, sizeof(slot->SG[0])*2);
-				dma_cache_inv((unsigned long)SCp->sense_buffer, sizeof(SCp->sense_buffer));
+				NCR_700_dma_cache_wback((unsigned long)slot->SG, sizeof(slot->SG[0])*2);
+				NCR_700_dma_cache_inv((unsigned long)SCp->sense_buffer, sizeof(SCp->sense_buffer));
 				
 				/* queue the command for reissue */
 				slot->state = NCR_700_SLOT_QUEUED;
@@ -1136,7 +1165,7 @@
 
 			/* re-patch for this command */
 			script_patch_32_abs(hostdata->script, CommandAddress, 
-					    virt_to_bus(slot->cmnd->cmnd));
+					    slot->pCmd);
 			script_patch_16(hostdata->script,
 					CommandCount, slot->cmnd->cmd_len);
 			script_patch_32_abs(hostdata->script, SGScriptStartAddress,
@@ -1149,13 +1178,13 @@
 			 * should therefore always clear ACK */
 			NCR_700_writeb(NCR_700_get_SXFER(hostdata->cmd->device),
 				       host, SXFER_REG);
-			dma_cache_inv((unsigned long)hostdata->msgin,
+			NCR_700_dma_cache_inv((unsigned long)hostdata->msgin,
 				      MSG_ARRAY_SIZE);
-			dma_cache_wback((unsigned long)hostdata->msgout,
+			NCR_700_dma_cache_wback((unsigned long)hostdata->msgout,
 					MSG_ARRAY_SIZE);
 			/* I'm just being paranoid here, the command should
 			 * already have been flushed from the cache */
-			dma_cache_wback((unsigned long)slot->cmnd->cmnd,
+			NCR_700_dma_cache_wback((unsigned long)slot->cmnd->cmnd,
 					slot->cmnd->cmd_len);
 
 
@@ -1219,7 +1248,8 @@
 		hostdata->reselection_id = reselection_id;
 		/* just in case we have a stale simple tag message, clear it */
 		hostdata->msgin[1] = 0;
-		dma_cache_wback_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);
+		NCR_700_dma_cache_wback_inv((unsigned long)hostdata->msgin,
+					    MSG_ARRAY_SIZE);
 		if(hostdata->tag_negotiated & (1<<reselection_id)) {
 			resume_offset = hostdata->pScript + Ent_GetReselectionWithTag;
 		} else {
@@ -1334,7 +1364,7 @@
 	hostdata->cmd = NULL;
 	/* clear any stale simple tag message */
 	hostdata->msgin[1] = 0;
-	dma_cache_wback_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);
+	NCR_700_dma_cache_wback_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);
 
 	if(id == 0xff) {
 		/* Selected as target, Ignore */
@@ -1404,7 +1434,7 @@
 	 * set up so we cannot take a selection interrupt */
 
 	hostdata->msgout[0] = NCR_700_identify(SCp->cmnd[0] != REQUEST_SENSE,
-					    SCp->lun);
+					       SCp->lun);
 	/* for INQUIRY or REQUEST_SENSE commands, we cannot be sure
 	 * if the negotiated transfer parameters still hold, so
 	 * always renegotiate them */
@@ -1437,7 +1467,7 @@
 			Device_ID, 1<<SCp->target);
 
 	script_patch_32_abs(hostdata->script, CommandAddress, 
-			virt_to_bus(SCp->cmnd));
+			    slot->pCmd);
 	script_patch_16(hostdata->script, CommandCount, SCp->cmd_len);
 	/* finally plumb the beginning of the SG list into the script
 	 * */
@@ -1448,10 +1478,10 @@
 	if(slot->resume_offset == 0)
 		slot->resume_offset = hostdata->pScript;
 	/* now perform all the writebacks and invalidates */
-	dma_cache_wback((unsigned long)hostdata->msgout, count);
-	dma_cache_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);
-	dma_cache_wback((unsigned long)SCp->cmnd, SCp->cmd_len);
-	dma_cache_inv((unsigned long)hostdata->status, 1);
+	NCR_700_dma_cache_wback((unsigned long)hostdata->msgout, count);
+	NCR_700_dma_cache_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);
+	NCR_700_dma_cache_wback((unsigned long)SCp->cmnd, SCp->cmd_len);
+	NCR_700_dma_cache_inv((unsigned long)hostdata->status, 1);
 
 	/* set the synchronous period/offset */
 	NCR_700_writeb(NCR_700_get_SXFER(SCp->device),
@@ -1519,7 +1549,7 @@
 
 		DEBUG(("scsi%d: istat %02x sstat0 %02x dstat %02x dsp %04x[%08x] dsps 0x%x\n",
 		       host->host_no, istat, sstat0, dstat,
-		       (dsp - (__u32)virt_to_bus(hostdata->script))/4,
+		       (dsp - (__u32)(hostdata->pScript))/4,
 		       dsp, dsps));
 
 		if(SCp != NULL) {
@@ -1632,7 +1662,7 @@
 					slot->SG[i].ins = bS_to_host(SCRIPT_NOP);
 					slot->SG[i].pAddr = 0;
 				}
-				dma_cache_wback((unsigned long)slot->SG, sizeof(slot->SG));
+				NCR_700_dma_cache_wback((unsigned long)slot->SG, sizeof(slot->SG));
 				/* and pretend we disconnected after
 				 * the command phase */
 				resume_offset = hostdata->pScript + Ent_MsgInDuringData;
@@ -1847,7 +1877,13 @@
 #endif
 		
 		if(old != NULL && old->tag == SCp->device->current_tag) {
-			printk(KERN_WARNING "scsi%d (%d:%d) Tag clock back to current, queueing\n", SCp->host->host_no, SCp->target, SCp->lun);
+			/* On some badly starving drives, this can be
+			 * a frequent occurance, so print the message
+			 * only once */
+			if(NCR_700_is_flag_clear(SCp->device, NCR_700_DEV_TAG_STARVATION_WARNED)) {
+				printk(KERN_WARNING "scsi%d (%d:%d) Target is suffering from tag starvation.\n", SCp->host->host_no, SCp->target, SCp->lun);
+				NCR_700_set_flag(SCp->device, NCR_700_DEV_TAG_STARVATION_WARNED);
+			}
 			return 1;
 		}
 		slot->tag = SCp->device->current_tag++;
@@ -1900,6 +1936,18 @@
 		hostdata->ITL_Hash_back[hash] = slot;
 	slot->ITL_back = NULL;
 
+	/* sanity check: some of the commands generated by the mid-layer
+	 * have an eccentric idea of their sc_data_direction */
+	if(!SCp->use_sg && !SCp->request_bufflen 
+	   && SCp->sc_data_direction != SCSI_DATA_NONE) {
+#ifdef NCR_700_DEBUG
+		printk("53c700: Command");
+		print_command(SCp->cmnd);
+		printk("Has wrong data direction %d\n", SCp->sc_data_direction);
+#endif
+		SCp->sc_data_direction = SCSI_DATA_NONE;
+	}
+
 	switch (SCp->cmnd[0]) {
 	case REQUEST_SENSE:
 		/* clear the internal sense magic */
@@ -1965,12 +2013,14 @@
 		}
 		slot->SG[i].ins = bS_to_host(SCRIPT_RETURN);
 		slot->SG[i].pAddr = 0;
-		dma_cache_wback((unsigned long)slot->SG, sizeof(slot->SG));
+		NCR_700_dma_cache_wback((unsigned long)slot->SG, sizeof(slot->SG));
 		DEBUG((" SETTING %08lx to %x\n",
-		       virt_to_bus(&slot->SG[i].ins), 
+		       (&slot->pSG[i].ins), 
 		       slot->SG[i].ins));
 	}
 	slot->resume_offset = 0;
+	slot->pCmd = pci_map_single(hostdata->pci_dev, SCp->cmnd,
+				    sizeof(SCp->cmnd), PCI_DMA_TODEVICE);
 	NCR_700_start_command(SCp);
 	return 0;
 }
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/53c700.h linux/drivers/scsi/53c700.h
--- v2.4.12/linux/drivers/scsi/53c700.h	Tue Oct  9 17:06:52 2001
+++ linux/drivers/scsi/53c700.h	Thu Oct 11 09:43:29 2001
@@ -40,6 +40,24 @@
 #error "Config.in must define either CONFIG_53C700_IO_MAPPED or CONFIG_53C700_MEM_MAPPED to use this scsi core."
 #endif
 
+/* macros for consistent memory allocation */
+
+#ifdef CONFIG_53C700_USE_CONSISTENT
+#define NCR_700_dma_cache_wback(mem, size) \
+	if(!hostdata->consistent) \
+		dma_cache_wback(mem, size)
+#define NCR_700_dma_cache_inv(mem, size) \
+	if(!hostdata->consistent) \
+		dma_cache_inv(mem, size)
+#define NCR_700_dma_cache_wback_inv(mem, size) \
+	if(!hostdata->consistent) \
+		dma_cache_wback_inv(mem, size)
+#else
+#define NCR_700_dma_cache_wback(mem, size) dma_cache_wback(mem,size)
+#define NCR_700_dma_cache_inv(mem, size) dma_cache_inv(mem,size)
+#define NCR_700_dma_cache_wback_inv(mem, size) dma_cache_wback_inv(mem,size)
+#endif
+
 
 struct NCR_700_Host_Parameters;
 
@@ -86,6 +104,7 @@
 #define NCR_700_DEV_NEGOTIATED_SYNC	(1<<16)
 #define NCR_700_DEV_BEGIN_SYNC_NEGOTIATION	(1<<17)
 #define NCR_700_DEV_BEGIN_TAG_QUEUEING	(1<<18)
+#define NCR_700_DEV_TAG_STARVATION_WARNED (1<<19)
 
 static inline void
 NCR_700_set_SXFER(Scsi_Device *SDp, __u8 sxfer)
@@ -174,6 +193,8 @@
 	__u16	tag;
 	__u32	resume_offset;
 	Scsi_Cmnd	*cmnd;
+	/* The pci_mapped address of the actual command in cmnd */
+	dma_addr_t	pCmd;
 	__u32		temp;
 	/* if this command is a pci_single mapping, holds the dma address
 	 * for later unmapping in the done routine */
@@ -191,19 +212,22 @@
 	int	clock;			/* board clock speed in MHz */
 	__u32	base;			/* the base for the port (copied to host) */
 	struct pci_dev	*pci_dev;
-	__u8	dmode_extra;	/* adjustable bus settings */
-	__u8	differential:1;	/* if we are differential */
+	__u32	dmode_extra;	/* adjustable bus settings */
+	__u32	differential:1;	/* if we are differential */
 #ifdef CONFIG_53C700_LE_ON_BE
 	/* This option is for HP only.  Set it if your chip is wired for
 	 * little endian on this platform (which is big endian) */
-	__u8	force_le_on_be:1;
+	__u32	force_le_on_be:1;
 #endif
-	__u8	chip710:1;	/* set if really a 710 not 700 */
-	__u8	burst_disable:1;	/* set to 1 to disable 710 bursting */
+	__u32	chip710:1;	/* set if really a 710 not 700 */
+	__u32	burst_disable:1;	/* set to 1 to disable 710 bursting */
 
 	/* NOTHING BELOW HERE NEEDS ALTERING */
-	__u8	fast:1;		/* if we can alter the SCSI bus clock
+	__u32	fast:1;		/* if we can alter the SCSI bus clock
                                    speed (so can negiotiate sync) */
+#ifdef CONFIG_53C700_USE_CONSISTENT
+	__u32	consistent:1;
+#endif
 
 	int	sync_clock;	/* The speed of the SYNC core */
 
@@ -216,15 +240,23 @@
 	spinlock_t lock;
 	enum NCR_700_Host_State state; /* protected by state lock */
 	Scsi_Cmnd *cmd;
-
+	/* Note: pScript contains the single consistent block of
+	 * memory.  All the msgin, msgout and status are allocated in
+	 * this memory too (at separate cache lines).  TOTAL_MEM_SIZE
+	 * represents the total size of this area */
+#define	MSG_ARRAY_SIZE	8
+#define	MSGOUT_OFFSET	(L1_CACHE_ALIGN(sizeof(SCRIPT)))
 	__u8	*msgout;
-#define	MSG_ARRAY_SIZE	16
-	__u8	tag_negotiated;
-	__u8	*status;
+#define MSGIN_OFFSET	(MSGOUT_OFFSET + L1_CACHE_ALIGN(MSG_ARRAY_SIZE))
 	__u8	*msgin;
+#define STATUS_OFFSET	(MSGIN_OFFSET + L1_CACHE_ALIGN(MSG_ARRAY_SIZE))
+	__u8	*status;
+#define SLOTS_OFFSET	(STATUS_OFFSET + L1_CACHE_ALIGN(MSG_ARRAY_SIZE))
 	struct NCR_700_command_slot	*slots;
+#define	TOTAL_MEM_SIZE	(SLOTS_OFFSET + L1_CACHE_ALIGN(sizeof(struct NCR_700_command_slot) * NCR_700_COMMAND_SLOTS_PER_HOST))
 	int	saved_slot_position;
 	int	command_slot_count; /* protected by state lock */
+	__u8	tag_negotiated;
 	__u8	rev;
 	__u8	reselection_id;
 	/* flags for the host */
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/Config.in linux/drivers/scsi/Config.in
--- v2.4.12/linux/drivers/scsi/Config.in	Tue Oct  9 17:06:52 2001
+++ linux/drivers/scsi/Config.in	Thu Oct 11 09:43:29 2001
@@ -122,10 +122,11 @@
    fi
 fi
 if [ "$CONFIG_PARISC" = "y" ]; then
-   dep_tristate 'HP LASI SCSI support for 53c700' CONFIG_SCSI_LASI700 $CONFIG_SCSI
+   dep_tristate 'HP LASI SCSI support for 53c700/710' CONFIG_SCSI_LASI700 $CONFIG_SCSI
    if [ "$CONFIG_SCSI_LASI700" != "n" ]; then
       define_bool CONFIG_53C700_MEM_MAPPED y
       define_bool CONFIG_53C700_LE_ON_BE y
+      define_bool CONFIG_53C700_USE_CONSISTENT y
    fi
 fi
 dep_tristate 'NCR53c7,8xx SCSI support'  CONFIG_SCSI_NCR53C7xx $CONFIG_SCSI $CONFIG_PCI
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/README.53c700 linux/drivers/scsi/README.53c700
--- v2.4.12/linux/drivers/scsi/README.53c700	Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/README.53c700	Thu Oct 11 09:43:29 2001
@@ -1,17 +1,154 @@
-This driver supports the 53c700 and 53c700-66 chips only.  It is full
-featured and does sync (-66 only), disconnects and tag command
-queueing.
+General Description
+===================
+
+This driver supports the 53c700 and 53c700-66 chips.  It also supports
+the 53c710 but only in 53c700 emulation mode.  It is full featured and
+does sync (-66 and 710 only), disconnects and tag command queueing.
 
 Since the 53c700 must be interfaced to a bus, you need to wrapper the
 card detector around this driver.  For an example, see the
-NCR_D700.[ch] files.
+NCR_D700.[ch] or lasi700.[ch] files.
 
 The comments in the 53c700.[ch] files tell you which parts you need to
 fill in to get the driver working.
 
-The driver is currently I/O mapped only, but it should be easy enough
-to memory map (just make the port reads #defines with MEM_MAPPED for
-memory mapping or nothing for I/O mapping, specify an extra rule for
-53c700-mem.o with the -DMEM_MAPPED flag and make your driver use it,
-that way the make rules will generate the correct version).
+
+Compile Time Flags
+==================
+
+The driver may be either io mapped or memory mapped.  This is
+selectable by configuration flags:
+
+CONFIG_53C700_MEM_MAPPED
+
+define if the driver is memory mapped.
+
+CONFIG_53C700_IO_MAPPED
+
+define if the driver is to be io mapped.
+
+One or other of the above flags *must* be defined.
+
+Other flags are:
+
+CONFIG_53C700_LE_ON_BE
+
+define if the chipset must be supported in little endian mode on a big
+endian architecture (used for the 700 on parisc).
+
+CONFIG_53C700_USE_CONSISTENT
+
+allocate consistent memory (should only be used if your architecture
+has a mixture of consistent and inconsistent memory).  Fully
+consistent or fully inconsistent architectures should not define this.
+
+
+Using the Chip Core Driver
+==========================
+
+In order to plumb the 53c700 chip core driver into a working SCSI
+driver, you need to know three things about the way the chip is wired
+into your system (or expansion card).
+
+1. The clock speed of the SCSI core
+2. The interrupt line used
+3. The memory (or io space) location of the 53c700 registers.
+
+Optionally, you may also need to know other things, like how to read
+the SCSI Id from the card bios or whether the chip is wired for
+differential operation.
+
+Usually you can find items 2. and 3. from general spec. documents or
+even by examining the configuration of a working driver under another
+operating system.
+
+The clock speed is usually buried deep in the technical literature.
+It is required because it is used to set up both the synchronous and
+asynchronous dividers for the chip.  As a general rule of thumb,
+manufacturers set the clock speed at the lowest possible setting
+consistent with the best operation of the chip (although some choose
+to drive it off the CPU or bus clock rather than going to the expense
+of an extra clock chip).  The best operation clock speeds are:
+
+53c700 - 25MHz
+53c700-66 - 50MHz
+53c710 - 40Mhz
+
+Writing Your Glue Driver
+========================
+
+This will be a standard SCSI driver (I don't know of a good document
+describing this, just copy from some other driver) with at least a
+detect and release entry.
+
+In the detect routine, you need to allocate a struct
+NCR_700_Host_Parameters sized memory area and clear it (so that the
+default values for everything are 0).  Then you must fill in the
+parameters that matter to you (see below), plumb the NCR_700_intr
+routine into the interrupt line and call NCR_700_detect with the host
+template and the new parameters as arguments.  You should also call
+the relevant request_*_region function and place the register base
+address into the `base' pointer of the host parameters.
+
+In the release routine, you must free the NCR_700_Host_Parameters that
+you allocated, call the corresponding release_*_region and free the
+interrupt.
+
+Handling Interrupts
+-------------------
+
+In general, you should just plumb the card's interrupt line in with 
+
+request_irq(irq, NCR_700_intr, <irq flags>, <driver name>, host);
+
+where host is the return from the relevant NCR_700_detect() routine.
+
+You may also write your own interrupt handling routine which calls
+NCR_700_intr() directly.  However, you should only really do this if
+you have a card with more than one chip on it and you can read a
+register to tell which set of chips wants the interrupt.
+
+Settable NCR_700_Host_Parameters
+--------------------------------
+
+The following are a list of the user settable parameters:
+
+clock: (MANDATORY)
+
+Set to the clock speed of the chip in MHz.
+
+base: (MANDATORY)
+
+set to the base of the io or mem region for the register set. On 64
+bit architectures this is only 32 bits wide, so the registers must be
+mapped into the low 32 bits of memory.
+
+pci_dev: (OPTIONAL)
+
+set to the PCI board device.  Leave NULL for a non-pci board.  This is
+used for the pci_alloc_consistent() and pci_map_*() functions.
+
+dmode_extra: (OPTIONAL, 53c710 only)
+
+extra flags for the DMODE register.  These are used to control bus
+output pins on the 710.  The settings should be a combination of
+DMODE_FC1 and DMODE_FC2.  What these pins actually do is entirely up
+to the board designer.  Usually it is safe to ignore this setting.
+
+differential: (OPTIONAL)
+
+set to 1 if the chip drives a differential bus.
+
+force_le_on_be: (OPTIONAL, only if CONFIG_53C700_LE_ON_BE is set)
+
+set to 1 if the chip is operating in little endian mode on a big
+endian architecture.
+
+chip710: (OPTIONAL)
+
+set to 1 if the chip is a 53c710.
+
+burst_disable: (OPTIONAL, 53c710 only)
+
+disable 8 byte bursting for DMA transfers.
 
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c
--- v2.4.12/linux/drivers/scsi/aha152x.c	Tue Oct  9 17:06:52 2001
+++ linux/drivers/scsi/aha152x.c	Thu Oct 11 09:43:29 2001
@@ -390,13 +390,11 @@
 #endif /* !defined(AHA152X_DEBUG) */
 
 #ifdef __ISAPNP__
-
 static struct isapnp_device_id id_table[] __devinitdata = {
 	{ ISAPNP_DEVICE_SINGLE('A','D','P',0x1505, 'A','D','P',0x1505), },
 	{ ISAPNP_DEVICE_SINGLE_END, }
 };
 MODULE_DEVICE_TABLE(isapnp, id_table);
-
 #endif /* ISAPNP */
 #endif /* MODULE */
 
@@ -981,28 +979,6 @@
 			}
 		printk("ok\n");
 	}
-#ifdef __ISAPNP__
-	while (setup_count <= 2 &&
-	       (dev = isapnp_find_dev (NULL, ISAPNP_VENDOR('A','D','P'),
-				       ISAPNP_FUNCTION(0x1505), dev))) {
-		if (dev->prepare(dev) < 0)
-			continue;
-		if (dev->active)
-			continue;
-		if (!(dev->resource[0].flags & IORESOURCE_IO))
-			continue;
-		dev->resource[0].flags |= IORESOURCE_AUTO;
-		if (dev->activate(dev) < 0)
-			continue;
-		setup[setup_count].io_port = dev->resource[0].start;
-		setup[setup_count].irq = dev->irq_resource[0].start;
-		pnpdev[num_pnpdevs++] = dev;
-		printk (KERN_INFO
-			"aha152x: found ISAPnP AVA-1505A at address 0x%03X, IRQ %d\n",
-			setup[setup_count].io_port, setup[setup_count].irq);
-		setup_count++;
-	}
-#endif
 
 #if defined(SETUP0)
 	if (setup_count < 2) {
@@ -1132,6 +1108,41 @@
 			       setup[setup_count].ext_trans);
 	}
 #endif
+
+#ifdef __ISAPNP__
+	while ( setup_count<2 && (dev=isapnp_find_dev(NULL, ISAPNP_VENDOR('A','D','P'), ISAPNP_FUNCTION(0x1505), dev)) ) {
+		if (dev->prepare(dev) < 0)
+			continue;
+		if (dev->active)
+			continue;
+		if (!(dev->resource[0].flags & IORESOURCE_IO))
+			continue;
+		dev->resource[0].flags |= IORESOURCE_AUTO;
+		if (dev->activate(dev) < 0)
+			continue;
+		if ( setup_count==1 && dev->resource[0].start==setup[0].io_port) {
+			dev->deactivate(dev);
+			continue;
+		}
+		setup[setup_count].io_port     = dev->resource[0].start;
+		setup[setup_count].irq         = dev->irq_resource[0].start;
+		setup[setup_count].scsiid      = 7;
+		setup[setup_count].reconnect   = 1;
+		setup[setup_count].parity      = 1;
+		setup[setup_count].synchronous = 1;
+		setup[setup_count].delay       = DELAY_DEFAULT;
+		setup[setup_count].ext_trans   = 0;
+#if defined(AHA152X_DEBUG)
+		setup[setup_count].debug       = DEBUG_DEFAULT;
+#endif
+		pnpdev[num_pnpdevs++] = dev;
+		printk (KERN_INFO
+			"aha152x: found ISAPnP AVA-1505A at io=0x%03x, irq=%d\n",
+			setup[setup_count].io_port, setup[setup_count].irq);
+		setup_count++;
+	}
+#endif
+
 
 #if defined(AUTOCONF)
 	if (setup_count < 2) {
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/aic7xxx_old.c linux/drivers/scsi/aic7xxx_old.c
--- v2.4.12/linux/drivers/scsi/aic7xxx_old.c	Thu Oct 11 08:02:26 2001
+++ linux/drivers/scsi/aic7xxx_old.c	Thu Oct 11 09:43:30 2001
@@ -220,11 +220,6 @@
  */
  
 #include <linux/module.h>
-
-#if defined(PCMCIA)
-#  undef MODULE
-#endif
-
 #include <stdarg.h>
 #include <asm/io.h>
 #include <asm/irq.h>
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/dpt_i2o.c linux/drivers/scsi/dpt_i2o.c
--- v2.4.12/linux/drivers/scsi/dpt_i2o.c	Tue Oct  9 17:06:52 2001
+++ linux/drivers/scsi/dpt_i2o.c	Thu Oct 11 09:43:30 2001
@@ -1838,7 +1838,7 @@
 #endif
 
 #if defined __alpha__ 
-static void adpt_sparc_info(sysInfo_S* si)
+static void adpt_alpha_info(sysInfo_S* si)
 {
 	// This is all the info we need for now
 	// We will add more info as our new
@@ -3324,4 +3324,4 @@
 static Scsi_Host_Template driver_template = DPT_I2O;
 #include "scsi_module.c"
 EXPORT_NO_SYMBOLS;
-MODULE_LICENSE("BSD without advertising clause");
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/i60uscsi.h linux/drivers/scsi/i60uscsi.h
--- v2.4.12/linux/drivers/scsi/i60uscsi.h	Fri Mar  2 18:38:38 2001
+++ linux/drivers/scsi/i60uscsi.h	Thu Oct 11 09:43:30 2001
@@ -61,6 +61,7 @@
  **************************************************************************/
 
 #include <linux/config.h>
+#include <linux/types.h>
 
 #define ULONG   unsigned long
 #define PVOID   void *
@@ -72,11 +73,7 @@
 #define UBYTE   unsigned char
 #define UWORD   unsigned short
 #define UDWORD  unsigned long
-#ifdef ALPHA
-#define U32     unsigned int
-#else
-#define U32     unsigned long
-#endif
+#define U32     u32
 
 #ifndef NULL
 #define NULL     0		/* zero          */
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/i91uscsi.h linux/drivers/scsi/i91uscsi.h
--- v2.4.12/linux/drivers/scsi/i91uscsi.h	Fri Mar  2 18:38:38 2001
+++ linux/drivers/scsi/i91uscsi.h	Thu Oct 11 09:43:30 2001
@@ -54,6 +54,7 @@
  **************************************************************************/
 
 #include <linux/config.h>
+#include <linux/types.h>
 
 #define ULONG   unsigned long
 #define USHORT  unsigned short
@@ -64,11 +65,7 @@
 #define UBYTE   unsigned char
 #define UWORD   unsigned short
 #define UDWORD  unsigned long
-#ifdef ALPHA
-#define U32     unsigned int
-#else
-#define U32     unsigned long
-#endif
+#define U32     u32
 
 #ifndef NULL
 #define NULL     0		/* zero          */
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/ini9100u.h linux/drivers/scsi/ini9100u.h
--- v2.4.12/linux/drivers/scsi/ini9100u.h	Fri Apr 27 13:59:18 2001
+++ linux/drivers/scsi/ini9100u.h	Thu Oct 11 09:43:30 2001
@@ -74,6 +74,7 @@
 #ifndef	LINUX_VERSION_CODE
 #include <linux/version.h>
 #endif
+#include <linux/types.h>
 
 #include "sd.h"
 
@@ -121,17 +122,13 @@
 #define ULONG   unsigned long
 #define USHORT  unsigned short
 #define UCHAR   unsigned char
-#define BYTE    unsigned char
+#define BYTE    u8
 #define WORD    unsigned short
 #define DWORD   unsigned long
-#define UBYTE   unsigned char
+#define UBYTE   u8
 #define UWORD   unsigned short
 #define UDWORD  unsigned long
-#ifdef ALPHA
-#define U32   unsigned int
-#else
-#define U32   unsigned long
-#endif
+#define U32   u32
 
 #ifndef NULL
 #define NULL     0		/* zero          */
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/inia100.h linux/drivers/scsi/inia100.h
--- v2.4.12/linux/drivers/scsi/inia100.h	Fri Mar  2 18:38:38 2001
+++ linux/drivers/scsi/inia100.h	Thu Oct 11 09:43:30 2001
@@ -68,6 +68,8 @@
 #include <linux/version.h>
 #endif
 
+#include <linux/types.h>
+
 #include "sd.h"
 
 extern int inia100_detect(Scsi_Host_Template *);
@@ -122,11 +124,7 @@
 #define UBYTE   unsigned char
 #define UWORD   unsigned short
 #define UDWORD  unsigned long
-#ifdef ALPHA
-#define U32     unsigned int
-#else
-#define U32     unsigned long
-#endif
+#define U32     u32
 
 #ifndef NULL
 #define NULL     0		/* zero          */
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/pcmcia/nsp_cs.c linux/drivers/scsi/pcmcia/nsp_cs.c
--- v2.4.12/linux/drivers/scsi/pcmcia/nsp_cs.c	Tue Oct  9 17:06:52 2001
+++ linux/drivers/scsi/pcmcia/nsp_cs.c	Thu Oct 11 09:04:57 2001
@@ -23,7 +23,7 @@
 
 ***********************************************************************/
 
-/* $Id: nsp_cs.c,v 1.35 2001/07/05 16:58:24 elca Exp $ */
+/* $Id: nsp_cs.c,v 1.42 2001/09/10 10:30:58 elca Exp $ */
 
 #ifdef NSP_KERNEL_2_2
 #include <pcmcia/config.h>
@@ -66,15 +66,14 @@
 
 MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>");
 MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module");
-MODULE_LICENSE("GPL");
-
 MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
+MODULE_LICENSE("GPL");
 
 #ifdef PCMCIA_DEBUG
 static int pc_debug = PCMCIA_DEBUG;
 MODULE_PARM(pc_debug, "i");
 MODULE_PARM_DESC(pc_debug, "set debug level");
-static char *version = "$Id: nsp_cs.c,v 1.35 2001/07/05 16:58:24 elca Exp $";
+static char *version = "$Id: nsp_cs.c,v 1.42 2001/09/10 10:30:58 elca Exp $";
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
 #else
 #define DEBUG(n, args...) /* */
@@ -93,18 +92,6 @@
 	struct bus_operations *bus;
 } scsi_info_t;
 
-static void nsp_cs_release(u_long arg);
-static int nsp_cs_event(event_t event, int priority,
-		     event_callback_args_t *args);
-static dev_link_t *nsp_cs_attach(void);
-static void nsp_cs_detach(dev_link_t *);
-static int nsp_detect(Scsi_Host_Template * );
-static int nsp_release(struct Scsi_Host *shpnt);
-static const char * nsp_info(struct Scsi_Host *shpnt);
-static int nsp_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
-static int nsp_abort(Scsi_Cmnd *);
-static int nsp_reset(Scsi_Cmnd *, unsigned int);
-
 
 /*----------------------------------------------------------------*/
 
@@ -191,7 +178,7 @@
 		data->CurrentSC = NULL;
 		SCpnt->result   = DID_BAD_TARGET << 16;
 		done(SCpnt);
-		return FALSE;
+		return -1;
 	}
 
 	show_command(SCpnt);
@@ -229,12 +216,12 @@
 		data->CurrentSC = NULL;
 		SCpnt->result   = DID_NO_CONNECT << 16;
 		done(SCpnt);
-		return FALSE;
+		return -1;
 	}
 
 
 	//DEBUG(0, __FUNCTION__ "() out\n");
-	return TRUE;
+	return 0;
 }
 
 /*
@@ -1185,7 +1172,7 @@
 	return;
 }
 
-#ifdef DBG_SHOWCOMMAND
+#ifdef PCMCIA_DEBUG
 #include "nsp_debug.c"
 #endif	/* DBG_SHOWCOMMAND */
 
@@ -1205,13 +1192,13 @@
 	host->unique_id	  = data->BaseAddress;
 	host->n_io_port	  = data->NumAddress;
 	host->irq	  = data->IrqNumber;
-	host->dma_channel = -1;
+	host->dma_channel = 0xff;             /* not use dms */
 
 	sprintf(nspinfo,
 /* Buffer size is 100 bytes */
 /*  0         1         2         3         4         5         6         7         8         9         0*/
 /*  01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890*/
-   "NinjaSCSI-3/32Bi Driver version 2.7, I/O 0x%04lx-0x%04lx IRQ %2d",
+   "NinjaSCSI-3/32Bi Driver $Revision: 1.42 $, I/O 0x%04lx-0x%04lx IRQ %2d",
 		host->io_port, host->io_port + host->n_io_port,
 		host->irq);
 	sht->name	  = nspinfo;
@@ -1221,6 +1208,7 @@
 	return 1; /* detect done. */
 }
 
+/* nsp_cs requires own release handler because its uses dev_id (=data) */
 static int nsp_release(struct Scsi_Host *shpnt)
 {
 	nsp_hw_data *data = &nsp_data;
@@ -1228,7 +1216,7 @@
         if (shpnt->irq) {
                 free_irq(shpnt->irq, data);
 	}
-        if (shpnt->io_port) {
+        if (shpnt->io_port && shpnt->n_io_port) {
 		release_region(shpnt->io_port, shpnt->n_io_port);
 	}
 	return 0;
@@ -1249,7 +1237,9 @@
 {
 	DEBUG(0, __FUNCTION__ " SCpnt=0x%p why=%d\n", SCpnt, why);
 
-	return nsp_eh_bus_reset(SCpnt);
+	nsp_eh_bus_reset(SCpnt);
+
+	return SCSI_RESET_SUCCESS;
 }
 
 static int nsp_abort(Scsi_Cmnd *SCpnt)
@@ -1258,7 +1248,7 @@
 
 	nsp_eh_bus_reset(SCpnt);
 
-	return SUCCESS;
+	return SCSI_ABORT_SUCCESS;
 }
 
 /*static int nsp_eh_strategy(struct Scsi_Host *Shost)
@@ -1271,6 +1261,7 @@
 	DEBUG(0, __FUNCTION__ " SCpnt=0x%p\n", SCpnt);
 
 	nsp_eh_bus_reset(SCpnt);
+
 	return SUCCESS;
 }
 
@@ -1309,9 +1300,8 @@
 	DEBUG(0, __FUNCTION__ "\n");
 
 	nsphw_init(data);
-	nsp_eh_bus_reset(SCpnt);
 
-	return SUCCESS;
+	return nsp_eh_bus_reset(SCpnt);
 }
 
 
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/pcmcia/nsp_cs.h linux/drivers/scsi/pcmcia/nsp_cs.h
--- v2.4.12/linux/drivers/scsi/pcmcia/nsp_cs.h	Sun Aug 12 13:28:00 2001
+++ linux/drivers/scsi/pcmcia/nsp_cs.h	Thu Oct 11 09:04:57 2001
@@ -6,22 +6,17 @@
     Ver 0.1 : Initial version.
 
     This software may be used and distributed according to the terms of
-    the GNU Public License.
+    the GNU General Public License.
 
 =========================================================*/
 
-/* $Id: nsp_cs.h,v 1.21 2001/07/04 14:45:31 elca Exp $ */
+/* $Id: nsp_cs.h,v 1.27 2001/09/10 10:31:13 elca Exp $ */
 
 #ifndef  __nsp_cs__
 #define  __nsp_cs__
 
 /* for debugging */
-/*
-#define DBG
-#define DBG_PRINT
-#define DBG_SHOWCOMMAND
-#define PCMCIA_DEBUG 9
-*/
+/*#define PCMCIA_DEBUG 9*/
 
 /*
 #define static
@@ -258,25 +253,36 @@
 } nsp_hw_data;
 
 
+static void nsp_cs_release(u_long arg);
+static int nsp_cs_event(event_t event, int priority, event_callback_args_t *args);
+static dev_link_t *nsp_cs_attach(void);
+static void nsp_cs_detach(dev_link_t *);
+
 static unsigned int nsphw_start_selection(Scsi_Cmnd *SCpnt, nsp_hw_data *data);
 static void nsp_start_timer(Scsi_Cmnd *SCpnt, nsp_hw_data *data, int time);
 
+static int nsp_detect(Scsi_Host_Template * );
+static int nsp_release(struct Scsi_Host *shpnt);
+static const char * nsp_info(struct Scsi_Host *shpnt);
+static int nsp_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
+
+static int nsp_abort(Scsi_Cmnd *);
+static int nsp_reset(Scsi_Cmnd *, unsigned int);
+
 static int nsp_eh_abort(Scsi_Cmnd * SCpnt);
 static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt);
 static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt);
 static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt);
 
-static int nsp_fifo_count(Scsi_Cmnd *SCpnt);
+static int  nsp_fifo_count(Scsi_Cmnd *SCpnt);
 static void nsp_pio_read(Scsi_Cmnd *SCpnt, nsp_hw_data *data);
-static int nsp_nexus(Scsi_Cmnd *SCpnt, nsp_hw_data *data);
+static int  nsp_nexus(Scsi_Cmnd *SCpnt, nsp_hw_data *data);
 
 #ifdef PCMCIA_DEBUG
-# ifdef DBG_SHOWCOMMAND
 static void show_command(Scsi_Cmnd *ptr);
 static void show_phase(Scsi_Cmnd *SCpnt);
 static void show_busphase(unsigned char stat);
 static void show_message(nsp_hw_data *data);
-# endif /* DBG_SHOWCOMMAND */
 #else
 # define show_command(ptr)   /* */
 # define show_phase(SCpnt)   /* */
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/pcmcia/nsp_debug.c linux/drivers/scsi/pcmcia/nsp_debug.c
--- v2.4.12/linux/drivers/scsi/pcmcia/nsp_debug.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/pcmcia/nsp_debug.c	Thu Oct 11 09:04:57 2001
@@ -6,7 +6,7 @@
     the GNU General Public License.
 =========================================================================*/
 
-/* $Id: nsp_debug.c,v 1.6 2001/07/04 14:43:53 elca Exp $ */
+/* $Id: nsp_debug.c,v 1.8 2001/09/07 04:32:28 elca Exp $ */
 
 /*
  * Show the command data of a command
@@ -85,7 +85,7 @@
 	}
 }
 
-void print_commandk (unsigned char *command)
+static void print_commandk (unsigned char *command)
 {
 	int i,s;
 	printk(KERN_DEBUG);
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/pcmcia/nsp_io.h linux/drivers/scsi/pcmcia/nsp_io.h
--- v2.4.12/linux/drivers/scsi/pcmcia/nsp_io.h	Sun Aug 12 13:28:00 2001
+++ linux/drivers/scsi/pcmcia/nsp_io.h	Thu Oct 11 09:04:57 2001
@@ -3,11 +3,11 @@
       By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
  
   This software may be used and distributed according to the terms of
-  the GNU Public License.
+  the GNU General Public License.
 
   */
 
-/* $Id: nsp_io.h,v 1.8 2001/01/30 05:16:02 elca Exp $ */
+/* $Id: nsp_io.h,v 1.9 2001/09/07 04:32:42 elca Exp $ */
 
 #ifndef __NSP_IO_H__
 #define __NSP_IO_H__
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/pcmcia/nsp_message.c linux/drivers/scsi/pcmcia/nsp_message.c
--- v2.4.12/linux/drivers/scsi/pcmcia/nsp_message.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/pcmcia/nsp_message.c	Thu Oct 11 09:04:57 2001
@@ -6,7 +6,7 @@
    the GNU General Public License.
  */
 
-/* $Id: nsp_message.c,v 1.6 2001/07/05 10:56:37 elca Exp $ */
+/* $Id: nsp_message.c,v 1.7 2001/09/07 04:33:01 elca Exp $ */
 
 static void nsp_message_in(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
 {
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/scsi_scan.c linux/drivers/scsi/scsi_scan.c
--- v2.4.12/linux/drivers/scsi/scsi_scan.c	Tue Oct  9 17:06:52 2001
+++ linux/drivers/scsi/scsi_scan.c	Thu Oct 11 09:43:30 2001
@@ -421,6 +421,10 @@
 					 max_scsi_luns : shpnt->max_lun);
 					sparse_lun = 0;
 					for (lun = 0, lun0_sl = SCSI_2; lun < max_dev_lun; ++lun) {
+						/* don't probe further for luns > 7 for targets <= SCSI_2 */
+						if ((lun0_sl < SCSI_3) && (lun > 7))
+							break;
+
 						if (!scan_scsis_single(channel, order_dev, lun, lun0_sl,
 							 	       &max_dev_lun, &sparse_lun, &SDpnt, shpnt,
 								       scsi_result)
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c
--- v2.4.12/linux/drivers/scsi/sd.c	Tue Oct  9 17:06:52 2001
+++ linux/drivers/scsi/sd.c	Thu Oct 11 09:43:30 2001
@@ -786,7 +786,7 @@
 			SRpnt->sr_cmd_len = 0;
 			SRpnt->sr_sense_buffer[0] = 0;
 			SRpnt->sr_sense_buffer[2] = 0;
-			SRpnt->sr_data_direction = SCSI_DATA_READ;
+			SRpnt->sr_data_direction = SCSI_DATA_NONE;
 
 			scsi_wait_req (SRpnt, (void *) cmd, (void *) buffer,
 				0/*512*/, SD_TIMEOUT, MAX_RETRIES);
diff -u --recursive --new-file v2.4.12/linux/drivers/sgi/char/graphics.c linux/drivers/sgi/char/graphics.c
--- v2.4.12/linux/drivers/sgi/char/graphics.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/sgi/char/graphics.c	Thu Oct 11 09:43:30 2001
@@ -343,6 +343,8 @@
 }
 
 #ifdef MODULE
+MODULE_LICENSE("GPL");
+
 int init_module(void) {
 	static int initiated = 0;
 
diff -u --recursive --new-file v2.4.12/linux/drivers/sound/cmpci.c linux/drivers/sound/cmpci.c
--- v2.4.12/linux/drivers/sound/cmpci.c	Tue Oct  9 17:06:52 2001
+++ linux/drivers/sound/cmpci.c	Thu Oct 11 09:43:30 2001
@@ -74,6 +74,7 @@
  *    18/05/2001 - .bss nitpicks, fix a bug in set_dac_channels where it
  *    		   was calling prog_dmabuf with s->lock held, call missing
  *    		   unlock_kernel in cm_midi_release
+ *    08/10/2001 - use set_current_state in some more places
  *
  *	Carlos Eduardo Gorges <carlos@techlinux.com.br>
  *	Fri May 25 2001 
@@ -1483,7 +1484,7 @@
 
 	if (s->dma_dac.mapped || !s->dma_dac.ready)
 		return 0;
-        current->state = TASK_INTERRUPTIBLE;
+        set_current_state(TASK_INTERRUPTIBLE);
         add_wait_queue(&s->dma_dac.wait, &wait);
         for (;;) {
                 spin_lock_irqsave(&s->lock, flags);
@@ -1495,7 +1496,7 @@
                         break;
                 if (nonblock) {
                         remove_wait_queue(&s->dma_dac.wait, &wait);
-                        current->state = TASK_RUNNING;
+                        set_current_state(TASK_RUNNING);
                         return -EBUSY;
                 }
 		tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->ratedac;
@@ -1504,7 +1505,7 @@
 			printk(KERN_DEBUG "cmpci: dma timed out??\n");
         }
         remove_wait_queue(&s->dma_dac.wait, &wait);
-        current->state = TASK_RUNNING;
+        set_current_state(TASK_RUNNING);
         if (signal_pending(current))
                 return -ERESTARTSYS;
         return 0;
diff -u --recursive --new-file v2.4.12/linux/drivers/sound/ite8172.c linux/drivers/sound/ite8172.c
--- v2.4.12/linux/drivers/sound/ite8172.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/ite8172.c	Thu Oct 11 09:43:30 2001
@@ -58,7 +58,7 @@
 #include <linux/sched.h>
 #include <linux/delay.h>
 #include <linux/sound.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/soundcard.h>
 #include <linux/pci.h>
 #include <linux/init.h>
diff -u --recursive --new-file v2.4.12/linux/drivers/sound/maestro3.c linux/drivers/sound/maestro3.c
--- v2.4.12/linux/drivers/sound/maestro3.c	Tue Oct  9 17:06:52 2001
+++ linux/drivers/sound/maestro3.c	Thu Oct 11 09:43:30 2001
@@ -172,7 +172,7 @@
 #define SND_DEV_DSP16       5 
    
 #ifdef M_DEBUG
-static int debug=0;
+static int debug;
 #define DPMOD   1   /* per module load */
 #define DPSTR   2   /* per 'stream' */
 #define DPSYS   3   /* per syscall */
@@ -365,7 +365,7 @@
     return r;
 }
 
-static struct m3_card *devs = NULL;
+static struct m3_card *devs;
 
 /*
  * I'm not very good at laying out functions in a file :)
@@ -1289,7 +1289,7 @@
 
     if (s->dma_dac.mapped || !s->dma_dac.ready)
         return 0;
-    current->state = TASK_INTERRUPTIBLE;
+    set_current_state(TASK_INTERRUPTIBLE);
     add_wait_queue(&s->dma_dac.wait, &wait);
     for (;;) {
         spin_lock_irqsave(&s->lock, flags);
@@ -1301,7 +1301,7 @@
             break;
         if (nonblock) {
             remove_wait_queue(&s->dma_dac.wait, &wait);
-            current->state = TASK_RUNNING;
+            set_current_state(TASK_RUNNING);
             return -EBUSY;
         }
         tmo = (count * HZ) / s->ratedac;
@@ -1312,7 +1312,7 @@
             DPRINTK(DPCRAP,"dma timed out?? %ld\n",jiffies);
     }
     remove_wait_queue(&s->dma_dac.wait, &wait);
-    current->state = TASK_RUNNING;
+    set_current_state(TASK_RUNNING);
     if (signal_pending(current))
             return -ERESTARTSYS;
     return 0;
@@ -2251,7 +2251,7 @@
         if(busywait)  {
             mdelay(delay1);
         } else {
-            current->state = TASK_UNINTERRUPTIBLE;
+            set_current_state(TASK_UNINTERRUPTIBLE);
             schedule_timeout((delay1 * HZ) / 1000);
         }
 
@@ -2264,7 +2264,7 @@
         if(busywait) {
             mdelay(delay2);
         } else {
-            current->state = TASK_UNINTERRUPTIBLE;
+            set_current_state(TASK_UNINTERRUPTIBLE);
             schedule_timeout((delay2 * HZ) / 1000);
         }
         if(! try_read_vendor(card))
@@ -2958,8 +2958,8 @@
 
     card->in_suspend++;
     add_wait_queue(&card->suspend_queue, &wait);
-    current->state = TASK_UNINTERRUPTIBLE;
+    set_current_state(TASK_UNINTERRUPTIBLE);
     schedule();
     remove_wait_queue(&card->suspend_queue, &wait);
-    current->state = TASK_RUNNING;
+    set_current_state(TASK_RUNNING);
 }
diff -u --recursive --new-file v2.4.12/linux/drivers/sound/nec_vrc5477.c linux/drivers/sound/nec_vrc5477.c
--- v2.4.12/linux/drivers/sound/nec_vrc5477.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/nec_vrc5477.c	Thu Oct 11 09:43:30 2001
@@ -67,7 +67,7 @@
 #include <linux/sched.h>
 #include <linux/delay.h>
 #include <linux/sound.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/soundcard.h>
 #include <linux/pci.h>
 #include <linux/init.h>
diff -u --recursive --new-file v2.4.12/linux/drivers/sound/opl3sa2.c linux/drivers/sound/opl3sa2.c
--- v2.4.12/linux/drivers/sound/opl3sa2.c	Tue Oct  9 17:06:52 2001
+++ linux/drivers/sound/opl3sa2.c	Thu Oct 11 09:43:30 2001
@@ -862,9 +862,9 @@
 
 	/* Our own config: */
 	hw_cfg->io_base = dev->resource[4].start;
-	hw_cfg->irq     = 0;
-	hw_cfg->dma     = -1;
-	hw_cfg->dma2    = -1;
+	hw_cfg->irq     = dev->irq_resource[0].start;
+	hw_cfg->dma     = dev->dma_resource[0].start;
+	hw_cfg->dma2    = dev->dma_resource[1].start;
 	
 	/* The MSS config: */
 	mss_cfg->io_base      = dev->resource[1].start;
@@ -944,9 +944,9 @@
 			 *  give pretty output from conf_printf. :)
 			 */
 			cfg[card].io_base = io;
-			cfg[card].irq     = 0;
-			cfg[card].dma     = -1;
-			cfg[card].dma2    = -1;
+			cfg[card].irq     = irq;
+			cfg[card].dma     = dma;
+			cfg[card].dma2    = dma2;
 	
 			/* The MSS config: */
 			cfg_mss[card].io_base      = mss_io;
diff -u --recursive --new-file v2.4.12/linux/drivers/sound/sb_card.c linux/drivers/sound/sb_card.c
--- v2.4.12/linux/drivers/sound/sb_card.c	Tue Oct  9 17:06:52 2001
+++ linux/drivers/sound/sb_card.c	Thu Oct 11 09:43:30 2001
@@ -53,6 +53,9 @@
  *
  * 28-10-2000 Added pnplegacy support
  * 	Daniel Church <dchurch@mbhs.edu>
+ *
+ * 01-10-2001 Added a new flavor of Creative SB AWE64 PnP (CTL00E9).
+ *      Jerome Cornet <jcornet@free.fr>
  */
 
 #include <linux/config.h>
@@ -434,6 +437,11 @@
 		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045),
 		0,0,0,0,
 		0,1,1,-1},
+	{"Sound Blaster AWE 64",
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00E9), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045),
+		0,0,0,0,
+		0,1,1,-1},
 	{"ESS 1688",
 		ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x0968), 
 		ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x0968),
@@ -621,6 +629,9 @@
 		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), 0 },
 
 	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00E4), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00E9),
 		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), 0 },
 
 	{	ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x0968), 
diff -u --recursive --new-file v2.4.12/linux/drivers/sound/trident.c linux/drivers/sound/trident.c
--- v2.4.12/linux/drivers/sound/trident.c	Tue Oct  9 17:06:52 2001
+++ linux/drivers/sound/trident.c	Thu Oct 11 09:43:30 2001
@@ -36,6 +36,10 @@
  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  *  History
+ *  v0.14.9d
+ *  	October 8 2001 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *	use set_current_state, properly release resources on failure in
+ *	trident_probe, get rid of check_region
  *  v0.14.9c
  *	August 10 2001 Peter Wächtler <pwaechtler@loewe-komp.de>
  *	added support for Tvia (formerly Integraphics/IGST) CyberPro5050
@@ -176,7 +180,7 @@
 
 #include <linux/pm.h>
 
-#define DRIVER_VERSION "0.14.9c"
+#define DRIVER_VERSION "0.14.9d"
 
 /* magic numbers to protect our data structures */
 #define TRIDENT_CARD_MAGIC	0x5072696E /* "Prin" */
@@ -1358,7 +1362,7 @@
 	for (;;) {
 		/* It seems that we have to set the current state to TASK_INTERRUPTIBLE
 		   every time to make the process really go to sleep */
-		current->state = TASK_INTERRUPTIBLE;
+		set_current_state(TASK_INTERRUPTIBLE);
 
 		spin_lock_irqsave(&state->card->lock, flags);
 		count = dmabuf->count;
@@ -1372,7 +1376,7 @@
 
 		if (nonblock) {
 			remove_wait_queue(&dmabuf->wait, &wait);
-			current->state = TASK_RUNNING;
+			set_current_state(TASK_RUNNING);
 			return -EBUSY;
 		}
 
@@ -1395,7 +1399,7 @@
 		}
 	}
 	remove_wait_queue(&dmabuf->wait, &wait);
-	current->state = TASK_RUNNING;
+	set_current_state(TASK_RUNNING);
 	if (signal_pending(current))
 		return -ERESTARTSYS;
 
@@ -3695,7 +3699,7 @@
 }
 
 #ifdef CONFIG_PROC_FS
-struct proc_dir_entry *res = NULL;
+struct proc_dir_entry *res;
 static int ali_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
 {
 	struct trident_card *card = (struct trident_card *)data;
@@ -3936,14 +3940,15 @@
 	int i = 0;
 	u16 temp;
 	struct pci_dev *pci_dev_m1533 = NULL;
+	int rc = -ENODEV;
 
 	if (pci_enable_device(pci_dev))
-		return -ENODEV;
+		goto out;
 
 	if (pci_set_dma_mask(pci_dev, TRIDENT_DMA_MASK)) {
 		printk(KERN_ERR "trident: architecture does not support"
 		       " 30bit PCI busmaster DMA\n");
-		return -ENODEV;
+		goto out;
 	}
 	pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &revision);
 
@@ -3952,15 +3957,16 @@
 	else
 		iobase = pci_resource_start(pci_dev, 0);
 
-	if (check_region(iobase, 256)) {
+	if (!request_region(iobase, 256, card_names[pci_id->driver_data])) {
 		printk(KERN_ERR "trident: can't allocate I/O space at 0x%4.4lx\n",
 		       iobase);
-		return -ENODEV;
+		goto out;
 	}
 
+	rc = -ENOMEM;
 	if ((card = kmalloc(sizeof(struct trident_card), GFP_KERNEL)) == NULL) {
 		printk(KERN_ERR "trident: out of memory\n");
-		return -ENOMEM;
+		goto out_release_region;
 	}
 	memset(card, 0, sizeof(*card));
 
@@ -4014,8 +4020,9 @@
 		/* Add H/W Volume Control By Matt Wu Jul. 06, 2001 */
 		card->hwvolctl = 0;
 		pci_dev_m1533 = pci_find_device(PCI_VENDOR_ID_AL,PCI_DEVICE_ID_AL_M1533, pci_dev_m1533);
+		rc = -ENODEV;
 		if (pci_dev_m1533 == NULL)
-			return -ENODEV;
+			goto out_proc_fs;
 		pci_read_config_byte(pci_dev_m1533, 0x63, &bits);
 		if (bits & (1<<5))
 			card->hwvolctl = 1;
@@ -4044,22 +4051,17 @@
 		card->address_interrupt = trident_address_interrupt;
 	}
 
-	/* claim our iospace and irq */
-	request_region(card->iobase, 256, card_names[pci_id->driver_data]);
+	/* claim our irq */
+	rc = -ENODEV;
 	if (request_irq(card->irq, &trident_interrupt, SA_SHIRQ,
 			card_names[pci_id->driver_data], card)) {
 		printk(KERN_ERR "trident: unable to allocate irq %d\n", card->irq);
-		release_region(card->iobase, 256);
-		kfree(card);
-		return -ENODEV;
+		goto out_proc_fs;
 	}
 	/* register /dev/dsp */
 	if ((card->dev_audio = register_sound_dsp(&trident_audio_fops, -1)) < 0) {
 		printk(KERN_ERR "trident: couldn't register DSP device!\n");
-		release_region(iobase, 256);
-		free_irq(card->irq, card);
-		kfree(card);
-		return -ENODEV;
+		goto out_free_irq;
 	}
 	card->mixer_regs_ready = 0;
 	/* initialize AC97 codec and register /dev/mixer */
@@ -4071,11 +4073,7 @@
 				kfree (card->ac97_codec[i]);
 			}
 		}
-		unregister_sound_dsp(card->dev_audio);
-		release_region(iobase, 256);
-		free_irq(card->irq, card);
-		kfree(card);
-		return -ENODEV;
+		goto out_unregister_sound_dsp;
 	}
 	card->mixer_regs_ready = 1;
 	outl(0x00, TRID_REG(card, T4D_MUSICVOL_WAVEVOL));
@@ -4112,13 +4110,28 @@
 #endif
 		/* edited by HMSEO for GT sound*/
 	}
-
+	rc = 0;
 	pci_set_drvdata(pci_dev, card);
 
 	/* Enable Address Engine Interrupts */
 	trident_enable_loop_interrupts(card);
-
-	return 0;
+out:	return rc;
+out_unregister_sound_dsp:
+	unregister_sound_dsp(card->dev_audio);
+out_free_irq:
+	free_irq(card->irq, card);
+out_proc_fs:
+#ifdef CONFIG_PROC_FS
+	if (res) {
+		remove_proc_entry("ALi5451", NULL);
+		res = NULL;
+	}
+#endif
+	kfree(card);
+	devs = NULL;
+out_release_region:
+	release_region(iobase, 256);
+	goto out;
 }
 
 static void __exit trident_remove(struct pci_dev *pci_dev)
diff -u --recursive --new-file v2.4.12/linux/drivers/sound/vidc.c linux/drivers/sound/vidc.c
--- v2.4.12/linux/drivers/sound/vidc.c	Fri Apr 13 20:26:07 2001
+++ linux/drivers/sound/vidc.c	Thu Oct 11 09:43:30 2001
@@ -542,3 +542,8 @@
 
 module_init(init_vidc);
 module_exit(cleanup_vidc);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("VIDC20 audio driver");
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.12/linux/drivers/tc/tc.c linux/drivers/tc/tc.c
--- v2.4.12/linux/drivers/tc/tc.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/tc/tc.c	Thu Oct 11 09:43:30 2001
@@ -25,6 +25,7 @@
 
 #define TC_DEBUG
 
+MODULE_LICENSE("GPL");
 slot_info tc_bus[MAX_SLOT];
 static int max_tcslot;
 static tcinfo *info;
diff -u --recursive --new-file v2.4.12/linux/drivers/usb/uhci.c linux/drivers/usb/uhci.c
--- v2.4.12/linux/drivers/usb/uhci.c	Thu Oct 11 08:02:26 2001
+++ linux/drivers/usb/uhci.c	Thu Oct 11 10:38:54 2001
@@ -2565,7 +2565,7 @@
 static int alloc_uhci(struct pci_dev *dev, unsigned int io_addr, unsigned int io_size)
 {
 	struct uhci *uhci;
-	int retval = -EBUSY;
+	int retval;
 	char buf[8], *bufp = buf;
 	int i, port;
 	struct usb_bus *bus;
@@ -2574,27 +2574,27 @@
 	struct proc_dir_entry *ent;
 #endif
 
-	if (!request_region(io_addr, io_size, "usb-uhci")) {
-		err("couldn't allocate I/O range %x - %x", io_addr,
-			io_addr + io_size - 1);
-		goto err_request_region;
+	retval = -ENODEV;
+	if (pci_enable_device(dev) < 0) {
+		err("couldn't enable PCI device");
+		goto err_enable_device;
 	}
 
 	if (!dev->irq) {
 		err("found UHCI device with no IRQ assigned. check BIOS settings!");
-		retval = -EINVAL;
 		goto err_invalid_irq;
 	}
 
 	if (!pci_dma_supported(dev, 0xFFFFFFFF)) {
 		err("PCI subsystem doesn't support 32 bit addressing?");
-		retval = -ENODEV;
 		goto err_pci_dma_supported;
 	}
 
-	if (pci_enable_device(dev) < 0) {
-		err("couldn't enable PCI device");
-		goto err_enable_device;
+	retval = -EBUSY;
+	if (!request_region(io_addr, io_size, "usb-uhci")) {
+		err("couldn't allocate I/O range %x - %x", io_addr,
+			io_addr + io_size - 1);
+		goto err_request_region;
 	}
 
 	pci_set_master(dev);
@@ -2897,15 +2897,15 @@
 err_alloc_uhci:
 
 err_pci_set_dma_mask:
+	release_region(io_addr, io_size);
 
-err_enable_device:
+err_request_region:
 
 err_pci_dma_supported:
-	release_region(io_addr, io_size);
 
 err_invalid_irq:
 
-err_request_region:
+err_enable_device:
 
 	return retval;
 }
diff -u --recursive --new-file v2.4.12/linux/drivers/video/acornfb.c linux/drivers/video/acornfb.c
--- v2.4.12/linux/drivers/video/acornfb.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/acornfb.c	Thu Oct 11 09:43:30 2001
@@ -1772,4 +1772,7 @@
 	return 0;
 }
 
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("VIDC 1/1a/20 framebuffer driver");
 MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.12/linux/drivers/video/cyber2000fb.c linux/drivers/video/cyber2000fb.c
--- v2.4.12/linux/drivers/video/cyber2000fb.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/cyber2000fb.c	Thu Oct 11 09:43:30 2001
@@ -3,6 +3,9 @@
  *
  *  Copyright (C) 1998-2000 Russell King
  *
+ *  MIPS and 50xx clock support
+ *  Copyright (C) 2001 Bradley D. LaRonde <brad@ltc.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.
@@ -53,14 +56,14 @@
  */
 /*#define CFB16_IS_CFB15*/
 
-static char			*CyberRegs;
-
 #include "cyber2000fb.h"
 
 struct cfb_info {
 	struct fb_info		fb;
 	struct display_switch	*dispsw;
 	struct pci_dev		*dev;
+	unsigned char 		*region;
+	unsigned char		*regs;
 	signed int		currcon;
 	int			func_use_count;
 	u_long			ref_ps;
@@ -80,19 +83,67 @@
 	u_char			mclk_div;
 };
 
+static char default_font_storage[40];
+static char *default_font = "Acorn8x8";
+MODULE_PARM(default_font, "s");
+MODULE_PARM_DESC(default_font, "Default font name");
+
+/*
+ * Our access methods.
+ */
+#define cyber2000fb_writel(val,reg,cfb)	writel(val, (cfb)->regs + (reg))
+#define cyber2000fb_writew(val,reg,cfb)	writew(val, (cfb)->regs + (reg))
+#define cyber2000fb_writeb(val,reg,cfb)	writeb(val, (cfb)->regs + (reg))
+
+#define cyber2000fb_readb(reg,cfb)	readb((cfb)->regs + (reg))
+
+static inline void
+cyber2000_crtcw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
+{
+	cyber2000fb_writew((reg & 255) | val << 8, 0x3d4, cfb);
+}
+
+static inline void
+cyber2000_grphw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
+{
+	cyber2000fb_writew((reg & 255) | val << 8, 0x3ce, cfb);
+}
+
+static inline unsigned int
+cyber2000_grphr(unsigned int reg, struct cfb_info *cfb)
+{
+	cyber2000fb_writeb(reg, 0x3ce, cfb);
+	return cyber2000fb_readb(0x3cf, cfb);
+}
+
+static inline void
+cyber2000_attrw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
+{
+	cyber2000fb_readb(0x3da, cfb);
+	cyber2000fb_writeb(reg, 0x3c0, cfb);
+	cyber2000fb_readb(0x3c1, cfb);
+	cyber2000fb_writeb(val, 0x3c0, cfb);
+}
+
+static inline void
+cyber2000_seqw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
+{
+	cyber2000fb_writew((reg & 255) | val << 8, 0x3c4, cfb);
+}
+
 /* -------------------- Hardware specific routines ------------------------- */
 
 /*
  * Hardware Cyber2000 Acceleration
  */
-static void cyber2000_accel_wait(void)
+static void cyber2000_accel_wait(struct cfb_info *cfb)
 {
 	int count = 100000;
 
-	while (cyber2000_inb(CO_REG_CONTROL) & 0x80) {
+	while (cyber2000fb_readb(CO_REG_CONTROL, cfb) & 0x80) {
 		if (!count--) {
 			debug_printf("accel_wait timed out\n");
-			cyber2000_outb(0, CO_REG_CONTROL);
+			cyber2000fb_writeb(0, CO_REG_CONTROL, cfb);
 			return;
 		}
 		udelay(1);
@@ -110,6 +161,7 @@
 cyber2000_accel_bmove(struct display *p, int sy, int sx, int dy, int dx,
 		      int height, int width)
 {
+	struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
 	struct fb_var_screeninfo *var = &p->fb_info->var;
 	u_long src, dst;
 	u_int fh, fw;
@@ -142,29 +194,30 @@
 	src    = sx + sy * var->xres_virtual;
 	dst    = dx + dy * var->xres_virtual;
 
-	cyber2000_accel_wait();
-	cyber2000_outb(0x00,  CO_REG_CONTROL);
-	cyber2000_outb(0x03,  CO_REG_FORE_MIX);
-	cyber2000_outw(width, CO_REG_WIDTH);
+	cyber2000_accel_wait(cfb);
+	cyber2000fb_writeb(0x00,  CO_REG_CONTROL, cfb);
+	cyber2000fb_writeb(0x03,  CO_REG_FORE_MIX, cfb);
+	cyber2000fb_writew(width, CO_REG_WIDTH, cfb);
 
 	if (var->bits_per_pixel != 24) {
-		cyber2000_outl(dst, CO_REG_DEST_PTR);
-		cyber2000_outl(src, CO_REG_SRC_PTR);
+		cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb);
+		cyber2000fb_writel(src, CO_REG_SRC_PTR, cfb);
 	} else {
-		cyber2000_outl(dst * 3, CO_REG_DEST_PTR);
-		cyber2000_outb(dst,     CO_REG_X_PHASE);
-		cyber2000_outl(src * 3, CO_REG_SRC_PTR);
+		cyber2000fb_writel(dst * 3, CO_REG_DEST_PTR, cfb);
+		cyber2000fb_writeb(dst,     CO_REG_X_PHASE, cfb);
+		cyber2000fb_writel(src * 3, CO_REG_SRC_PTR, cfb);
 	}
 
-	cyber2000_outw(height, CO_REG_HEIGHT);
-	cyber2000_outw(cmd,    CO_REG_CMD_L);
-	cyber2000_outw(0x2800, CO_REG_CMD_H);
+	cyber2000fb_writew(height, CO_REG_HEIGHT, cfb);
+	cyber2000fb_writew(cmd,    CO_REG_CMD_L, cfb);
+	cyber2000fb_writew(0x2800, CO_REG_CMD_H, cfb);
 }
 
 static void
 cyber2000_accel_clear(struct vc_data *conp, struct display *p, int sy, int sx,
 		      int height, int width)
 {
+	struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
 	struct fb_var_screeninfo *var = &p->fb_info->var;
 	u_long dst;
 	u_int fw, fh;
@@ -177,30 +230,30 @@
 	width  = width * fw - 1;
 	height = height * fh - 1;
 
-	cyber2000_accel_wait();
-	cyber2000_outb(0x00,   CO_REG_CONTROL);
-	cyber2000_outb(0x03,   CO_REG_FORE_MIX);
-	cyber2000_outw(width,  CO_REG_WIDTH);
-	cyber2000_outw(height, CO_REG_HEIGHT);
+	cyber2000_accel_wait(cfb);
+	cyber2000fb_writeb(0x00,   CO_REG_CONTROL,  cfb);
+	cyber2000fb_writeb(0x03,   CO_REG_FORE_MIX, cfb);
+	cyber2000fb_writew(width,  CO_REG_WIDTH,    cfb);
+	cyber2000fb_writew(height, CO_REG_HEIGHT,   cfb);
 
 	switch (var->bits_per_pixel) {
 	case 15:
 	case 16:
 		bgx = ((u16 *)p->dispsw_data)[bgx];
 	case 8:
-		cyber2000_outl(dst, CO_REG_DEST_PTR);
+		cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb);
 		break;
 
 	case 24:
-		cyber2000_outl(dst * 3, CO_REG_DEST_PTR);
-		cyber2000_outb(dst, CO_REG_X_PHASE);
+		cyber2000fb_writel(dst * 3, CO_REG_DEST_PTR, cfb);
+		cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb);
 		bgx = ((u32 *)p->dispsw_data)[bgx];
 		break;
 	}
 
-	cyber2000_outl(bgx, CO_REG_FOREGROUND);
-	cyber2000_outw(CO_CMD_L_PATTERN_FGCOL, CO_REG_CMD_L);
-	cyber2000_outw(0x0800, CO_REG_CMD_H);
+	cyber2000fb_writel(bgx, CO_REG_FOREGROUND, cfb);
+	cyber2000fb_writew(CO_CMD_L_PATTERN_FGCOL, CO_REG_CMD_L, cfb);
+	cyber2000fb_writew(0x0800, CO_REG_CMD_H, cfb);
 }
 
 static void
@@ -209,7 +262,7 @@
 {
 	struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
 
-	cyber2000_accel_wait();
+	cyber2000_accel_wait(cfb);
 	cfb->dispsw->putc(conp, p, c, yy, xx);
 }
 
@@ -219,7 +272,7 @@
 {
 	struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
 
-	cyber2000_accel_wait();
+	cyber2000_accel_wait(cfb);
 	cfb->dispsw->putcs(conp, p, s, count, yy, xx);
 }
 
@@ -227,7 +280,7 @@
 {
 	struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
 
-	cyber2000_accel_wait();
+	cyber2000_accel_wait(cfb);
 	cfb->dispsw->revc(p, xx, yy);
 }
 
@@ -274,10 +327,10 @@
 	switch (cfb->fb.var.bits_per_pixel) {
 #ifdef FBCON_HAS_CFB8
 	case 8:
-		cyber2000_outb(regno, 0x3c8);
-		cyber2000_outb(red,   0x3c9);
-		cyber2000_outb(green, 0x3c9);
-		cyber2000_outb(blue,  0x3c9);
+		cyber2000fb_writeb(regno, 0x3c8, cfb);
+		cyber2000fb_writeb(red,   0x3c9, cfb);
+		cyber2000fb_writeb(green, 0x3c9, cfb);
+		cyber2000fb_writeb(blue,  0x3c9, cfb);
 		break;
 #endif
 
@@ -286,18 +339,18 @@
 #ifndef CFB16_IS_CFB15
 		if (regno < 64) {
 			/* write green */
-			cyber2000_outb(regno << 2, 0x3c8);
-			cyber2000_outb(cfb->palette[regno >> 1].red, 0x3c9);
-			cyber2000_outb(green, 0x3c9);
-			cyber2000_outb(cfb->palette[regno >> 1].blue, 0x3c9);
+			cyber2000fb_writeb(regno << 2, 0x3c8, cfb);
+			cyber2000fb_writeb(cfb->palette[regno >> 1].red, 0x3c9, cfb);
+			cyber2000fb_writeb(green, 0x3c9, cfb);
+			cyber2000fb_writeb(cfb->palette[regno >> 1].blue, 0x3c9, cfb);
 		}
 
 		if (regno < 32) {
 			/* write red,blue */
-			cyber2000_outb(regno << 3, 0x3c8);
-			cyber2000_outb(red, 0x3c9);
-			cyber2000_outb(cfb->palette[regno << 1].green, 0x3c9);
-			cyber2000_outb(blue, 0x3c9);
+			cyber2000fb_writeb(regno << 3, 0x3c8, cfb);
+			cyber2000fb_writeb(red, 0x3c9, cfb);
+			cyber2000fb_writeb(cfb->palette[regno << 1].green, 0x3c9, cfb);
+			cyber2000fb_writeb(blue, 0x3c9, cfb);
 		}
 
 		if (regno < 16)
@@ -308,10 +361,10 @@
 
 	case 15:
 		if (regno < 32) {
-			cyber2000_outb(regno << 3, 0x3c8);
-			cyber2000_outb(red, 0x3c9);
-			cyber2000_outb(green, 0x3c9);
-			cyber2000_outb(blue, 0x3c9);
+			cyber2000fb_writeb(regno << 3, 0x3c8, cfb);
+			cyber2000fb_writeb(red, 0x3c9, cfb);
+			cyber2000fb_writeb(green, 0x3c9, cfb);
+			cyber2000fb_writeb(blue, 0x3c9, cfb);
 		}
 		if (regno < 16)
 			((u16 *)cfb->fb.pseudo_palette)[regno] =
@@ -322,10 +375,10 @@
 
 #ifdef FBCON_HAS_CFB24
 	case 24:
-		cyber2000_outb(regno, 0x3c8);
-		cyber2000_outb(red,   0x3c9);
-		cyber2000_outb(green, 0x3c9);
-		cyber2000_outb(blue,  0x3c9);
+		cyber2000fb_writeb(regno, 0x3c8, cfb);
+		cyber2000fb_writeb(red,   0x3c9, cfb);
+		cyber2000fb_writeb(green, 0x3c9, cfb);
+		cyber2000fb_writeb(blue,  0x3c9, cfb);
 
 		if (regno < 16)
 			((u32 *)cfb->fb.pseudo_palette)[regno] =
@@ -375,92 +428,92 @@
 	 * Blank palette
 	 */
 	for (i = 0; i < NR_PALETTE; i++) {
-		cyber2000_outb(i, 0x3c8);
-		cyber2000_outb(0, 0x3c9);
-		cyber2000_outb(0, 0x3c9);
-		cyber2000_outb(0, 0x3c9);
-	}
-
-	cyber2000_outb(0xef, 0x3c2);
-	cyber2000_crtcw(0x11, 0x0b);
-	cyber2000_attrw(0x11, 0x00);
-
-	cyber2000_seqw(0x00, 0x01);
-	cyber2000_seqw(0x01, 0x01);
-	cyber2000_seqw(0x02, 0x0f);
-	cyber2000_seqw(0x03, 0x00);
-	cyber2000_seqw(0x04, 0x0e);
-	cyber2000_seqw(0x00, 0x03);
+		cyber2000fb_writeb(i, 0x3c8, cfb);
+		cyber2000fb_writeb(0, 0x3c9, cfb);
+		cyber2000fb_writeb(0, 0x3c9, cfb);
+		cyber2000fb_writeb(0, 0x3c9, cfb);
+	}
+
+	cyber2000fb_writeb(0xef, 0x3c2, cfb);
+	cyber2000_crtcw(0x11, 0x0b, cfb);
+	cyber2000_attrw(0x11, 0x00, cfb);
+
+	cyber2000_seqw(0x00, 0x01, cfb);
+	cyber2000_seqw(0x01, 0x01, cfb);
+	cyber2000_seqw(0x02, 0x0f, cfb);
+	cyber2000_seqw(0x03, 0x00, cfb);
+	cyber2000_seqw(0x04, 0x0e, cfb);
+	cyber2000_seqw(0x00, 0x03, cfb);
 
 	for (i = 0; i < sizeof(crtc_idx); i++)
-		cyber2000_crtcw(crtc_idx[i], hw->crtc[i]);
+		cyber2000_crtcw(crtc_idx[i], hw->crtc[i], cfb);
 
 	for (i = 0x0a; i < 0x10; i++)
-		cyber2000_crtcw(i, 0);
+		cyber2000_crtcw(i, 0, cfb);
 
-	cyber2000_grphw(0x11, hw->crtc_ofl);
-	cyber2000_grphw(0x00, 0x00);
-	cyber2000_grphw(0x01, 0x00);
-	cyber2000_grphw(0x02, 0x00);
-	cyber2000_grphw(0x03, 0x00);
-	cyber2000_grphw(0x04, 0x00);
-	cyber2000_grphw(0x05, 0x60);
-	cyber2000_grphw(0x06, 0x05);
-	cyber2000_grphw(0x07, 0x0f);
-	cyber2000_grphw(0x08, 0xff);
+	cyber2000_grphw(0x11, hw->crtc_ofl, cfb);
+	cyber2000_grphw(0x00, 0x00, cfb);
+	cyber2000_grphw(0x01, 0x00, cfb);
+	cyber2000_grphw(0x02, 0x00, cfb);
+	cyber2000_grphw(0x03, 0x00, cfb);
+	cyber2000_grphw(0x04, 0x00, cfb);
+	cyber2000_grphw(0x05, 0x60, cfb);
+	cyber2000_grphw(0x06, 0x05, cfb);
+	cyber2000_grphw(0x07, 0x0f, cfb);
+	cyber2000_grphw(0x08, 0xff, cfb);
 
 	/* Attribute controller registers */
 	for (i = 0; i < 16; i++)
-		cyber2000_attrw(i, i);
+		cyber2000_attrw(i, i, cfb);
 
-	cyber2000_attrw(0x10, 0x01);
-	cyber2000_attrw(0x11, 0x00);
-	cyber2000_attrw(0x12, 0x0f);
-	cyber2000_attrw(0x13, 0x00);
-	cyber2000_attrw(0x14, 0x00);
+	cyber2000_attrw(0x10, 0x01, cfb);
+	cyber2000_attrw(0x11, 0x00, cfb);
+	cyber2000_attrw(0x12, 0x0f, cfb);
+	cyber2000_attrw(0x13, 0x00, cfb);
+	cyber2000_attrw(0x14, 0x00, cfb);
 
 	/* woody: set the interlaced bit... */
 	/* FIXME: what about doublescan? */
-	cyber2000_outb(0x11, 0x3ce);
-	i = cyber2000_inb(0x3cf);
+	cyber2000fb_writeb(0x11, 0x3ce, cfb);
+	i = cyber2000fb_readb(0x3cf, cfb);
 	if (hw->vmode == FB_VMODE_INTERLACED)
 		i |= 0x20;
 	else
 		i &= ~0x20;
-	cyber2000_outb(i, 0x3cf);
+	cyber2000fb_writeb(i, 0x3cf, cfb);
 
 	/* PLL registers */
-	cyber2000_grphw(DCLK_MULT, hw->clock_mult);
-	cyber2000_grphw(DCLK_DIV,  hw->clock_div);
-	cyber2000_grphw(MCLK_MULT, cfb->mclk_mult);
-	cyber2000_grphw(MCLK_DIV,  cfb->mclk_div);
-	cyber2000_grphw(0x90, 0x01);
-	cyber2000_grphw(0xb9, 0x80);
-	cyber2000_grphw(0xb9, 0x00);
-
-	cyber2000_outb(0x56, 0x3ce);
-	i = cyber2000_inb(0x3cf);
-	cyber2000_outb(i | 4, 0x3cf);
-	cyber2000_outb(hw->palette_ctrl, 0x3c6);
-	cyber2000_outb(i,    0x3cf);
+	cyber2000_grphw(DCLK_MULT, hw->clock_mult, cfb);
+	cyber2000_grphw(DCLK_DIV,  hw->clock_div, cfb);
+	cyber2000_grphw(MCLK_MULT, cfb->mclk_mult, cfb);
+	cyber2000_grphw(MCLK_DIV,  cfb->mclk_div, cfb);
+	cyber2000_grphw(0x90, 0x01, cfb);
+	cyber2000_grphw(0xb9, 0x80, cfb);
+	cyber2000_grphw(0xb9, 0x00, cfb);
+
+	cyber2000fb_writeb(0x56, 0x3ce, cfb);
+	i = cyber2000fb_readb(0x3cf, cfb);
+	cyber2000fb_writeb(i | 4, 0x3cf, cfb);
+	cyber2000fb_writeb(hw->palette_ctrl, 0x3c6, cfb);
+	cyber2000fb_writeb(i,    0x3cf, cfb);
 
-	cyber2000_outb(0x20, 0x3c0);
-	cyber2000_outb(0xff, 0x3c6);
+	cyber2000fb_writeb(0x20, 0x3c0, cfb);
+	cyber2000fb_writeb(0xff, 0x3c6, cfb);
 
-	cyber2000_grphw(0x14, hw->fetch);
+	cyber2000_grphw(0x14, hw->fetch, cfb);
 	cyber2000_grphw(0x15, ((hw->fetch >> 8) & 0x03) |
-			      ((hw->pitch >> 4) & 0x30));
-	cyber2000_grphw(0x77, hw->visualid);
+			      ((hw->pitch >> 4) & 0x30), cfb);
+	cyber2000_grphw(0x77, hw->visualid, cfb);
 
 	/* make sure we stay in linear mode */
-	cyber2000_grphw(0x33, 0x0d);
+	cyber2000_grphw(0x33, 0x0d, cfb);
 
 	/*
 	 * Set up accelerator registers
 	 */
-	cyber2000_outw(hw->width, CO_REG_SRC_WIDTH);
-	cyber2000_outw(hw->width, CO_REG_DEST_WIDTH);
-	cyber2000_outb(hw->pixformat, CO_REG_PIX_FORMAT);
+	cyber2000fb_writew(hw->width,     CO_REG_SRC_WIDTH,  cfb);
+	cyber2000fb_writew(hw->width,     CO_REG_DEST_WIDTH, cfb);
+	cyber2000fb_writeb(hw->pixformat, CO_REG_PIX_FORMAT, cfb);
 }
 
 static inline int
@@ -475,9 +528,9 @@
 	if (base >= 1 << 20)
 		return -EINVAL;
 
-	cyber2000_grphw(0x10, base >> 16 | 0x10);
-	cyber2000_crtcw(0x0c, base >> 8);
-	cyber2000_crtcw(0x0d, base);
+	cyber2000_grphw(0x10, base >> 16 | 0x10, cfb);
+	cyber2000_crtcw(0x0c, base >> 8, cfb);
+	cyber2000_crtcw(0x0d, base, cfb);
 
 	return 0;
 }
@@ -623,6 +676,7 @@
 	const u_long ref_ps = cfb->ref_ps;
 	u_int div2, t_div1, best_div1, best_mult;
 	int best_diff;
+	int vco;
 
 	/*
 	 * Step 1:
@@ -697,6 +751,11 @@
 	hw->clock_mult = best_mult - 1;
 	hw->clock_div  = div2 << 6 | (best_div1 - 1);
 
+	vco = ref_ps * best_div1 / best_mult;
+	if ((ref_ps == 40690) && (vco < 5556))
+		/* Set VFSEL when VCO > 180MHz (5.556 ps). */
+		hw->clock_div |= DCLK_DIV_VFSEL;
+
 	return 0;
 }
 
@@ -1057,30 +1116,30 @@
      
 	switch (blank) {
 	case 4:	/* powerdown - both sync lines down */
-    		cyber2000_grphw(0x16, 0x05);
+    		cyber2000_grphw(0x16, 0x05, cfb);
 		break;	
 	case 3:	/* hsync off */
-    		cyber2000_grphw(0x16, 0x01);
+    		cyber2000_grphw(0x16, 0x01, cfb);
 		break;	
 	case 2:	/* vsync off */
-    		cyber2000_grphw(0x16, 0x04);
+    		cyber2000_grphw(0x16, 0x04, cfb);
 		break;	
 	case 1:	/* soft blank */
-		cyber2000_grphw(0x16, 0x00);
+		cyber2000_grphw(0x16, 0x00, cfb);
 		for (i = 0; i < NR_PALETTE; i++) {
-			cyber2000_outb(i, 0x3c8);
-			cyber2000_outb(0, 0x3c9);
-			cyber2000_outb(0, 0x3c9);
-			cyber2000_outb(0, 0x3c9);
+			cyber2000fb_writeb(i, 0x3c8, cfb);
+			cyber2000fb_writeb(0, 0x3c9, cfb);
+			cyber2000fb_writeb(0, 0x3c9, cfb);
+			cyber2000fb_writeb(0, 0x3c9, cfb);
 		}
 		break;
 	default: /* unblank */
-		cyber2000_grphw(0x16, 0x00);
+		cyber2000_grphw(0x16, 0x00, cfb);
 		for (i = 0; i < NR_PALETTE; i++) {
-			cyber2000_outb(i, 0x3c8);
-			cyber2000_outb(cfb->palette[i].red, 0x3c9);
-			cyber2000_outb(cfb->palette[i].green, 0x3c9);
-			cyber2000_outb(cfb->palette[i].blue, 0x3c9);
+			cyber2000fb_writeb(i, 0x3c8, cfb);
+			cyber2000fb_writeb(cfb->palette[i].red, 0x3c9, cfb);
+			cyber2000fb_writeb(cfb->palette[i].green, 0x3c9, cfb);
+			cyber2000fb_writeb(cfb->palette[i].blue, 0x3c9, cfb);
 		}
 		break;
 	}
@@ -1136,8 +1195,8 @@
 	if (cfb->func_use_count == 1) {
 		int old;
 
-		old = cyber2000_grphr(FUNC_CTL);
-		cyber2000_grphw(FUNC_CTL, old | FUNC_CTL_EXTREGENBL);
+		old = cyber2000_grphr(FUNC_CTL, cfb);
+		cyber2000_grphw(FUNC_CTL, old | FUNC_CTL_EXTREGENBL, cfb);
 	}
 }
 
@@ -1149,8 +1208,8 @@
 	if (cfb->func_use_count == 1) {
 		int old;
 
-		old = cyber2000_grphr(FUNC_CTL);
-		cyber2000_grphw(FUNC_CTL, old & ~FUNC_CTL_EXTREGENBL);
+		old = cyber2000_grphr(FUNC_CTL, cfb);
+		cyber2000_grphw(FUNC_CTL, old & ~FUNC_CTL_EXTREGENBL, cfb);
 	}
 
 	cfb->func_use_count -= 1;
@@ -1170,7 +1229,7 @@
 {
 	if (int_cfb_info != NULL) {
 		info->dev	      = int_cfb_info->dev;
-		info->regs	      = CyberRegs;
+		info->regs	      = int_cfb_info->regs;
 		info->fb	      = int_cfb_info->fb.screen_base;
 		info->fb_size	      = int_cfb_info->fb.fix.smem_len;
 		info->enable_extregs  = cyber2000fb_enable_extregs;
@@ -1281,14 +1340,14 @@
 		 * initialising this card for the first time.
 		 * FIXME: what about hotplug?
 		 */
-		cfb->mclk_mult = cyber2000_grphr(MCLK_MULT);
-		cfb->mclk_div  = cyber2000_grphr(MCLK_DIV);
+		cfb->mclk_mult = cyber2000_grphr(MCLK_MULT, cfb);
+		cfb->mclk_div  = cyber2000_grphr(MCLK_DIV, cfb);
 	}
 #endif
-#if defined(__i386__) || defined(__x86_64__)
+#if defined(__i386__) || defined(__x86_64__) || defined(__mips__)
 	/*
-	 * x86 is simple, we just do regular outb's instead of
-	 * cyber2000_outb.
+	 * x86 and MIPS are simple, we just do regular
+	 * outb's instead of cyber2000fb_writeb.
 	 */
 	outb(0x18, 0x46e8);
 	outb(0x01, 0x102);
@@ -1302,16 +1361,16 @@
 		 * initialising this card for the first time.
 		 * FIXME: what about hotplug?
 		 */
-		cfb->mclk_mult = cyber2000_grphr(MCLK_MULT);
-		cfb->mclk_div  = cyber2000_grphr(MCLK_DIV);
+		cfb->mclk_mult = cyber2000_grphr(MCLK_MULT, cfb);
+		cfb->mclk_div  = cyber2000_grphr(MCLK_DIV, cfb);
 	}
 #endif
 #ifdef __arm__
-	cyber2000_outb(0x18, 0x46e8);
-	cyber2000_outb(0x01, 0x102);
-	cyber2000_outb(0x08, 0x46e8);
-	cyber2000_outb(0x33, 0x3ce);
-	cyber2000_outb(0x01, 0x3cf);
+	cyber2000fb_writeb(0x18, 0x46e8, cfb);
+	cyber2000fb_writeb(0x01, 0x102, cfb);
+	cyber2000fb_writeb(0x08, 0x46e8, cfb);
+	cyber2000fb_writeb(0x33, 0x3ce, cfb);
+	cyber2000fb_writeb(0x01, 0x3cf, cfb);
 
 	/*
 	 * MCLK on the NetWinder and the Shark is fixed at 75MHz
@@ -1324,7 +1383,7 @@
 	 * Initialise the CyberPro
 	 */
 	for (i = 0; i < sizeof(igs_regs); i += 2)
-		cyber2000_grphw(igs_regs[i], igs_regs[i+1]);
+		cyber2000_grphw(igs_regs[i], igs_regs[i+1], cfb);
 
 	if (at_boot) {
 		/*
@@ -1332,14 +1391,14 @@
 		 * This should have been already initialised by the BIOS,
 		 * but if it's garbage, claim default 1MB VRAM (woody)
 		 */
-		cfb->mem_ctl1 = cyber2000_grphr(MEM_CTL1);
-		cfb->mem_ctl2 = cyber2000_grphr(MEM_CTL2);
+		cfb->mem_ctl1 = cyber2000_grphr(MEM_CTL1, cfb);
+		cfb->mem_ctl2 = cyber2000_grphr(MEM_CTL2, cfb);
 	} else {
 		/*
 		 * Reprogram the MEM_CTL1 and MEM_CTL2 registers
 		 */
-		cyber2000_grphw(MEM_CTL1, cfb->mem_ctl1);
-		cyber2000_grphw(MEM_CTL2, cfb->mem_ctl2);
+		cyber2000_grphw(MEM_CTL1, cfb->mem_ctl1, cfb);
+		cyber2000_grphw(MEM_CTL2, cfb->mem_ctl2, cfb);
 	}
 
 	/*
@@ -1347,8 +1406,8 @@
 	 * (CyberPro 5000's may be programmed to use
 	 * an additional set of PLLs.
 	 */
-	cyber2000_outb(0xba, 0x3ce);
-	cyber2000_outb(cyber2000_inb(0x3cf) & 0x80, 0x3cf);
+	cyber2000fb_writeb(0xba, 0x3ce, cfb);
+	cyber2000fb_writeb(cyber2000fb_readb(0x3cf, cfb) & 0x80, 0x3cf, cfb);
 }
 
 static struct cfb_info * __devinit
@@ -1366,15 +1425,20 @@
 
 	cfb->currcon		= -1;
 	cfb->dev		= dev;
-	cfb->ref_ps		= 69842;
+
+	if (id->driver_data == FB_ACCEL_IGS_CYBER5000)
+		cfb->ref_ps	= 40690; // 24.576 MHz
+	else
+		cfb->ref_ps	= 69842; // 14.31818 MHz (69841?)
+
 	cfb->divisors[0]	= 1;
 	cfb->divisors[1]	= 2;
 	cfb->divisors[2]	= 4;
 
-	if (id->driver_data == FB_ACCEL_IGS_CYBER2010)
-		cfb->divisors[3] = 6;
-	else
+	if (id->driver_data == FB_ACCEL_IGS_CYBER2000)
 		cfb->divisors[3] = 8;
+	else
+		cfb->divisors[3] = 6;
 
 	strcpy(cfb->fb.fix.id, name);
 
@@ -1392,7 +1456,7 @@
 	cfb->fb.var.accel_flags	= FB_ACCELF_TEXT;
 
 	strcpy(cfb->fb.modename, cfb->fb.fix.id);
-	strcpy(cfb->fb.fontname, "Acorn8x8");
+	strcpy(cfb->fb.fontname, default_font);
 
 	cfb->fb.fbops		= &cyber2000fb_ops;
 	cfb->fb.changevar	= NULL;
@@ -1422,69 +1486,32 @@
 }
 
 /*
- * Map in the registers
- */
-static int __devinit
-cyberpro_map_mmio(struct cfb_info *cfb, struct pci_dev *dev)
-{
-	u_long mmio_base;
-
-	mmio_base = pci_resource_start(dev, 0) + MMIO_OFFSET;
-
-	cfb->fb.fix.mmio_start = mmio_base;
-	cfb->fb.fix.mmio_len   = MMIO_SIZE;
-
-	CyberRegs = ioremap(mmio_base, MMIO_SIZE);
-	if (!CyberRegs) {
-		printk("%s: unable to map memory mapped IO\n",
-		       cfb->fb.fix.id);
-		return -ENOMEM;
-	}
-	return 0;
-}
-
-/*
- * Unmap registers
+ * Parse Cyber2000fb options.  Usage:
+ *  video=cyber2000:font:fontname
  */
-static void __devinit cyberpro_unmap_mmio(struct cfb_info *cfb)
+int
+cyber2000fb_setup(char *options)
 {
-	if (cfb && CyberRegs) {
-		iounmap(CyberRegs);
-		CyberRegs = NULL;
-	}
-}
+	char *opt;
 
-/*
- * Map in screen memory
- */
-static int __devinit
-cyberpro_map_smem(struct cfb_info *cfb, struct pci_dev *dev, u_long smem_len)
-{
-	u_long smem_base;
+	if (!options || !*options)
+		return 0;
 
-	smem_base = pci_resource_start(dev, 0);
+	while ((opt = strsep(&options, ",")) != NULL) {
+		if (!*opt)
+			continue;
 
-	cfb->fb.fix.smem_start	= smem_base;
-	cfb->fb.fix.smem_len	= smem_len;
+		if (strncmp(opt, "font:", 5) == 0) {
+			strncpy(default_font_storage, opt + 5, sizeof(default_font_storage));
+			default_font = default_font_storage;
+			continue;
+		}
 
-	cfb->fb.screen_base = ioremap(smem_base, smem_len);
-	if (!cfb->fb.screen_base) {
-		printk("%s: unable to map screen memory\n",
-		       cfb->fb.fix.id);
-		return -ENOMEM;
+		printk(KERN_ERR "CyberPro20x0: unknown parameter: %s\n", opt);
 	}
-
 	return 0;
 }
 
-static void __devinit cyberpro_unmap_smem(struct cfb_info *cfb)
-{
-	if (cfb && cfb->fb.screen_base) {
-		iounmap(cfb->fb.screen_base);
-		cfb->fb.screen_base = NULL;
-	}
-}
-
 static int __devinit
 cyberpro_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
@@ -1507,11 +1534,14 @@
 	err = -ENOMEM;
 	cfb = cyberpro_alloc_fb_info(dev, id, name);
 	if (!cfb)
-		goto failed;
+		goto failed_release;
 
-	err = cyberpro_map_mmio(cfb, dev);
-	if (err)
-		goto failed;
+	cfb->region = ioremap(pci_resource_start(dev, 0),
+			      pci_resource_len(dev, 0));
+	if (!cfb->region)
+		goto failed_ioremap;
+
+	cfb->regs = cfb->region + MMIO_OFFSET;
 
 	cyberpro_init_hw(cfb, 1);
 
@@ -1521,9 +1551,15 @@
 	default:		smem_size = 0x00100000; break;
 	}
 
-	err = cyberpro_map_smem(cfb, dev, smem_size);
-	if (err)
-		goto failed;
+	/*
+	 * Hmm, we _need_ a portable way of finding the address for
+	 * the remap stuff, both for mmio and for smem.
+	 */
+	cfb->fb.fix.mmio_start = pci_resource_start(dev, 0) + MMIO_OFFSET;
+	cfb->fb.fix.smem_start = pci_resource_start(dev, 0);
+	cfb->fb.fix.mmio_len   = MMIO_SIZE;
+	cfb->fb.fix.smem_len   = smem_size;
+	cfb->fb.screen_base    = cfb->region;
 
 	if (!fb_find_mode(&cfb->fb.var, &cfb->fb, NULL, NULL, 0,
 	    		  &cyber2000fb_default_mode, 8)) {
@@ -1570,11 +1606,10 @@
 	return 0;
 
 failed:
-	cyberpro_unmap_smem(cfb);
-	cyberpro_unmap_mmio(cfb);
+	iounmap(cfb->region);
+failed_ioremap:
 	cyberpro_free_fb_info(cfb);
-
-release:
+failed_release:
 	pci_release_regions(dev);
 
 	return err;
@@ -1594,8 +1629,7 @@
 			printk(KERN_WARNING "%s: danger Will Robinson, "
 				"danger danger!  Oopsen imminent!\n",
 				cfb->fb.fix.id);
-		cyberpro_unmap_smem(cfb);
-		cyberpro_unmap_mmio(cfb);
+		iounmap(cfb->region);
 		cyberpro_free_fb_info(cfb);
 
 		/*
@@ -1673,7 +1707,10 @@
 }
 
 #ifdef MODULE
-MODULE_LICENSE("GPL");
 module_init(cyber2000fb_init);
 #endif
 module_exit(cyberpro_exit);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("CyberPro 2000, 2010 and 5000 framebuffer driver");
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/video/cyber2000fb.h linux/drivers/video/cyber2000fb.h
--- v2.4.12/linux/drivers/video/cyber2000fb.h	Mon Sep 18 15:15:22 2000
+++ linux/drivers/video/cyber2000fb.h	Thu Oct 11 09:43:30 2001
@@ -11,14 +11,6 @@
  */
 #include <linux/config.h>
 
-#define cyber2000_outb(dat,reg)	writeb(dat, CyberRegs + reg)
-#define cyber2000_outw(dat,reg)	writew(dat, CyberRegs + reg)
-#define cyber2000_outl(dat,reg)	writel(dat, CyberRegs + reg)
-
-#define cyber2000_inb(reg)	readb(CyberRegs + reg)
-#define cyber2000_inw(reg)	readw(CyberRegs + reg)
-#define cyber2000_inl(reg)	readl(CyberRegs + reg)
-
 /*
  * Internal CyberPro sizes and offsets.
  */
@@ -30,6 +22,7 @@
 #if defined(DEBUG) && defined(CONFIG_DEBUG_LL)
 static void debug_printf(char *fmt, ...)
 {
+	extern void printascii(const char *);
 	char buffer[128];
 	va_list ap;
 
@@ -43,38 +36,6 @@
 #define debug_printf(x...) do { } while (0)
 #endif
 
-static inline void cyber2000_crtcw(int reg, int val)
-{
-	cyber2000_outb(reg, 0x3d4);
-	cyber2000_outb(val, 0x3d5);
-}
-
-static inline void cyber2000_grphw(int reg, int val)
-{
-	cyber2000_outb(reg, 0x3ce);
-	cyber2000_outb(val, 0x3cf);
-}
-
-static inline unsigned int cyber2000_grphr(int reg)
-{
-	cyber2000_outb(reg, 0x3ce);
-	return cyber2000_inb(0x3cf);
-}
-
-static inline void cyber2000_attrw(int reg, int val)
-{
-	cyber2000_inb(0x3da);
-	cyber2000_outb(reg, 0x3c0);
-	cyber2000_inb(0x3c1);
-	cyber2000_outb(val, 0x3c0);
-}
-
-static inline void cyber2000_seqw(int reg, int val)
-{
-	cyber2000_outb(reg, 0x3c4);
-	cyber2000_outb(val, 0x3c5);
-}
-
 #define PIXFORMAT_8BPP		0
 #define PIXFORMAT_16BPP		1
 #define PIXFORMAT_24BPP		2
@@ -166,6 +127,7 @@
 
 #define DCLK_MULT		0xb0
 #define DCLK_DIV		0xb1
+#define DCLK_DIV_VFSEL			0x20
 #define MCLK_MULT		0xb2
 #define MCLK_DIV		0xb3
 
diff -u --recursive --new-file v2.4.12/linux/fs/attr.c linux/fs/attr.c
--- v2.4.12/linux/fs/attr.c	Tue Oct  9 17:06:53 2001
+++ linux/fs/attr.c	Thu Oct 11 09:43:30 2001
@@ -137,7 +137,7 @@
 			    (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid))
 				error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
 			if (!error)
-				inode_setattr(inode, attr);
+				error = inode_setattr(inode, attr);
 		}
 	}
 	unlock_kernel();
diff -u --recursive --new-file v2.4.12/linux/fs/block_dev.c linux/fs/block_dev.c
--- v2.4.12/linux/fs/block_dev.c	Tue Oct  9 17:06:53 2001
+++ linux/fs/block_dev.c	Thu Oct 11 08:32:35 2001
@@ -24,29 +24,6 @@
 
 #define MAX_BUF_PER_PAGE (PAGE_CACHE_SIZE / 512)
 
-static inline unsigned int blksize_bits(unsigned int size)
-{
-	unsigned int bits = 8;
-	do {
-		bits++;
-		size >>= 1;
-	} while (size > 256);
-	return bits;
-}
-
-static inline unsigned int block_size(kdev_t dev)
-{
-	int retval = BLOCK_SIZE;
-	int major = MAJOR(dev);
-
-	if (blksize_size[major]) {
-		int minor = MINOR(dev);
-		if (blksize_size[major][minor])
-			retval = blksize_size[major][minor];
-	}
-	return retval;
-}
-
 static unsigned long max_block(kdev_t dev)
 {
 	unsigned int retval = ~0U;
diff -u --recursive --new-file v2.4.12/linux/fs/devfs/util.c linux/fs/devfs/util.c
--- v2.4.12/linux/fs/devfs/util.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/devfs/util.c	Thu Oct 11 09:43:30 2001
@@ -52,7 +52,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/devfs_fs_kernel.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include <asm/bitops.h>
diff -u --recursive --new-file v2.4.12/linux/fs/ext2/Makefile linux/fs/ext2/Makefile
--- v2.4.12/linux/fs/ext2/Makefile	Fri Dec 29 14:07:23 2000
+++ linux/fs/ext2/Makefile	Thu Oct 11 08:05:18 2001
@@ -9,7 +9,7 @@
 
 O_TARGET := ext2.o
 
-obj-y    := acl.o balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
+obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
 		ioctl.o namei.o super.o symlink.o
 obj-m    := $(O_TARGET)
 
diff -u --recursive --new-file v2.4.12/linux/fs/ext2/acl.c linux/fs/ext2/acl.c
--- v2.4.12/linux/fs/ext2/acl.c	Tue Dec 14 11:16:22 1999
+++ linux/fs/ext2/acl.c	Wed Dec 31 16:00:00 1969
@@ -1,17 +0,0 @@
-/*
- * linux/fs/ext2/acl.c
- *
- * Copyright (C) 1993, 1994, 1995
- * Remy Card (card@masi.ibp.fr)
- * Laboratoire MASI - Institut Blaise Pascal
- * Universite Pierre et Marie Curie (Paris VI)
- */
-
-#include <linux/fs.h>
-#include <linux/sched.h>
-
-
-/*
- * This file will contain the Access Control Lists management for the
- * second extended file system.
- */
diff -u --recursive --new-file v2.4.12/linux/fs/ext2/file.c linux/fs/ext2/file.c
--- v2.4.12/linux/fs/ext2/file.c	Wed Jul 25 17:10:24 2001
+++ linux/fs/ext2/file.c	Thu Oct 11 08:05:18 2001
@@ -22,51 +22,6 @@
 #include <linux/ext2_fs.h>
 #include <linux/sched.h>
 
-static loff_t ext2_file_lseek(struct file *, loff_t, int);
-static int ext2_open_file (struct inode *, struct file *);
-
-#define EXT2_MAX_SIZE(bits)							\
-	(((EXT2_NDIR_BLOCKS + (1LL << (bits - 2)) + 				\
-	   (1LL << (bits - 2)) * (1LL << (bits - 2)) + 				\
-	   (1LL << (bits - 2)) * (1LL << (bits - 2)) * (1LL << (bits - 2))) * 	\
-	  (1LL << bits)) - 1)
-
-static long long ext2_max_sizes[] = {
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-EXT2_MAX_SIZE(10), EXT2_MAX_SIZE(11), EXT2_MAX_SIZE(12), EXT2_MAX_SIZE(13)
-};
-
-/*
- * Make sure the offset never goes beyond the 32-bit mark..
- */
-static loff_t ext2_file_lseek(
-	struct file *file,
-	loff_t offset,
-	int origin)
-{
-	struct inode *inode = file->f_dentry->d_inode;
-
-	switch (origin) {
-		case 2:
-			offset += inode->i_size;
-			break;
-		case 1:
-			offset += file->f_pos;
-	}
-	if (offset<0)
-		return -EINVAL;
-	if (((unsigned long long) offset >> 32) != 0) {
-		if (offset > ext2_max_sizes[EXT2_BLOCK_SIZE_BITS(inode->i_sb)])
-			return -EINVAL;
-	} 
-	if (offset != file->f_pos) {
-		file->f_pos = offset;
-		file->f_reada = 0;
-		file->f_version = ++event;
-	}
-	return offset;
-}
-
 /*
  * Called when an inode is released. Note that this is different
  * from ext2_open_file: open gets called at every open, but release
@@ -80,30 +35,16 @@
 }
 
 /*
- * Called when an inode is about to be open.
- * We use this to disallow opening RW large files on 32bit systems if
- * the caller didn't specify O_LARGEFILE.  On 64bit systems we force
- * on this flag in sys_open.
- */
-static int ext2_open_file (struct inode * inode, struct file * filp)
-{
-	if (!(filp->f_flags & O_LARGEFILE) &&
-	    inode->i_size > 0x7FFFFFFFLL)
-		return -EFBIG;
-	return 0;
-}
-
-/*
  * We have mostly NULL's here: the current defaults are ok for
  * the ext2 filesystem.
  */
 struct file_operations ext2_file_operations = {
-	llseek:		ext2_file_lseek,
+	llseek:		generic_file_llseek,
 	read:		generic_file_read,
 	write:		generic_file_write,
 	ioctl:		ext2_ioctl,
 	mmap:		generic_file_mmap,
-	open:		ext2_open_file,
+	open:		generic_file_open,
 	release:	ext2_release_file,
 	fsync:		ext2_sync_file,
 };
diff -u --recursive --new-file v2.4.12/linux/fs/ext2/inode.c linux/fs/ext2/inode.c
--- v2.4.12/linux/fs/ext2/inode.c	Thu Oct 11 08:02:26 2001
+++ linux/fs/ext2/inode.c	Thu Oct 11 09:43:38 2001
@@ -29,6 +29,12 @@
 #include <linux/sched.h>
 #include <linux/highuid.h>
 #include <linux/quotaops.h>
+#include <linux/module.h>
+
+MODULE_AUTHOR("Remy Card and others");
+MODULE_DESCRIPTION("Second Extended Filesystem");
+MODULE_LICENSE("GPL");
+
 
 static int ext2_update_inode(struct inode * inode, int do_sync);
 
@@ -592,7 +598,7 @@
 	sync_page: block_sync_page,
 	prepare_write: ext2_prepare_write,
 	commit_write: generic_commit_write,
-	bmap: ext2_bmap,
+	bmap: ext2_bmap
 };
 
 /*
diff -u --recursive --new-file v2.4.12/linux/fs/freevxfs/vxfs_super.c linux/fs/freevxfs/vxfs_super.c
--- v2.4.12/linux/fs/freevxfs/vxfs_super.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/freevxfs/vxfs_super.c	Thu Oct 11 09:43:38 2001
@@ -49,6 +49,7 @@
 
 MODULE_AUTHOR("Christoph Hellwig");
 MODULE_DESCRIPTION("Veritas Filesystem (VxFS) driver");
+MODULE_LICENSE("Dual BSD/GPL");
 
 
 static void		vxfs_put_super(struct super_block *);
diff -u --recursive --new-file v2.4.12/linux/fs/lockd/clntproc.c linux/fs/lockd/clntproc.c
--- v2.4.12/linux/fs/lockd/clntproc.c	Tue Oct  9 17:06:53 2001
+++ linux/fs/lockd/clntproc.c	Thu Oct 11 07:52:18 2001
@@ -6,6 +6,7 @@
  * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
  */
 
+#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
@@ -676,6 +677,18 @@
 	case NLM_LCK_BLOCKED:
 		printk(KERN_NOTICE "lockd: unexpected status NLM_BLOCKED\n");
 		return -ENOLCK;
+#ifdef CONFIG_LOCKD_V4
+	case NLM_DEADLCK:
+		return -EDEADLK;
+	case NLM_ROFS:
+		return -EROFS;
+	case NLM_STALE_FH:
+		return -ESTALE;
+	case NLM_FBIG:
+		return -EOVERFLOW;
+	case NLM_FAILED:
+		return -ENOLCK;
+#endif
 	}
 	printk(KERN_NOTICE "lockd: unexpected server status %d\n", status);
 	return -ENOLCK;
diff -u --recursive --new-file v2.4.12/linux/fs/lockd/svclock.c linux/fs/lockd/svclock.c
--- v2.4.12/linux/fs/lockd/svclock.c	Tue Nov  7 10:18:57 2000
+++ linux/fs/lockd/svclock.c	Thu Oct 11 07:52:18 2001
@@ -31,9 +31,14 @@
 #include <linux/lockd/nlm.h>
 #include <linux/lockd/lockd.h>
 
-
 #define NLMDBG_FACILITY		NLMDBG_SVCLOCK
 
+#ifdef CONFIG_LOCKD_V4
+#define nlm_deadlock	nlm4_deadlock
+#else
+#define nlm_deadlock	nlm_lck_denied
+#endif
+
 static void	nlmsvc_insert_block(struct nlm_block *block, unsigned long);
 static int	nlmsvc_remove_block(struct nlm_block *block);
 static void	nlmsvc_grant_callback(struct rpc_task *task);
@@ -330,12 +335,7 @@
 		case 0:
 			return nlm_granted;
 		case EDEADLK:
-#ifdef CONFIG_LOCKD_V4
-			return nlm4_deadlock; /* will be downgraded to lck_deined if this
-					       * is a NLMv1,3 request */
-#else
-			/* no applicable NLM status */
-#endif
+			return nlm_deadlock;
 		case EAGAIN:
 			return nlm_lck_denied;
 		default:			/* includes ENOLCK */
@@ -346,6 +346,11 @@
 	if (!wait) {
 		up(&file->f_sema);
 		return nlm_lck_denied;
+	}
+
+	if (posix_locks_deadlock(&lock->fl, conflock)) {
+		up(&file->f_sema);
+		return nlm_deadlock;
 	}
 
 	/* If we don't have a block, create and initialize it. Then
diff -u --recursive --new-file v2.4.12/linux/fs/lockd/svcproc.c linux/fs/lockd/svcproc.c
--- v2.4.12/linux/fs/lockd/svcproc.c	Tue Oct  9 17:06:53 2001
+++ linux/fs/lockd/svcproc.c	Thu Oct 11 07:52:18 2001
@@ -29,17 +29,20 @@
 static u32
 cast_to_nlm(u32 status, u32 vers)
 {
-
+	/* Note: status is assumed to be in network byte order !!! */
 	if (vers != 4){
-		switch(ntohl(status)){
-		case NLM_LCK_GRANTED:
-		case NLM_LCK_DENIED:
-		case NLM_LCK_DENIED_NOLOCKS:
-		case NLM_LCK_BLOCKED:
-		case NLM_LCK_DENIED_GRACE_PERIOD:
+		switch (status) {
+		case nlm_granted:
+		case nlm_lck_denied:
+		case nlm_lck_denied_nolocks:
+		case nlm_lck_blocked:
+		case nlm_lck_denied_grace_period:
+			break;
+		case nlm4_deadlock:
+			status = nlm_lck_denied;
 			break;
 		default:
-			status = NLM_LCK_DENIED_NOLOCKS;
+			status = nlm_lck_denied_nolocks;
 		}
 	}
 
diff -u --recursive --new-file v2.4.12/linux/fs/locks.c linux/fs/locks.c
--- v2.4.12/linux/fs/locks.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/locks.c	Thu Oct 11 07:52:18 2001
@@ -548,7 +548,7 @@
 		return (1);
 
 	default:
-		printk("locks_conflict(): impossible lock type - %d\n",
+		printk(KERN_ERR "locks_conflict(): impossible lock type - %d\n",
 		       caller_fl->fl_type);
 		break;
 	}
@@ -660,7 +660,7 @@
  * from a broken NFS client. But broken NFS clients have a lot more to
  * worry about than proper deadlock detection anyway... --okir
  */
-static int posix_locks_deadlock(struct file_lock *caller_fl,
+int posix_locks_deadlock(struct file_lock *caller_fl,
 				struct file_lock *block_fl)
 {
 	struct list_head *tmp;
@@ -715,6 +715,9 @@
 	struct file_lock *new_fl = locks_alloc_lock(0);
 	int error;
 
+	if (new_fl == NULL)
+		return -ENOMEM;
+
 	new_fl->fl_owner = current->files;
 	new_fl->fl_pid = current->pid;
 	new_fl->fl_file = filp;
@@ -1428,6 +1431,9 @@
 	struct inode *inode;
 	int error;
 
+	if (file_lock == NULL)
+		return -ENOLCK;
+
 	/*
 	 * This might block, so we do it before checking the inode.
 	 */
@@ -1580,6 +1586,9 @@
 	struct flock64 flock;
 	struct inode *inode;
 	int error;
+
+	if (file_lock == NULL)
+		return -ENOLCK;
 
 	/*
 	 * This might block, so we do it before checking the inode.
diff -u --recursive --new-file v2.4.12/linux/fs/nfs/read.c linux/fs/nfs/read.c
--- v2.4.12/linux/fs/nfs/read.c	Tue Apr  3 13:45:37 2001
+++ linux/fs/nfs/read.c	Thu Oct 11 08:12:52 2001
@@ -59,7 +59,7 @@
 static __inline__ struct nfs_read_data *nfs_readdata_alloc(void)
 {
 	struct nfs_read_data   *p;
-	p = kmem_cache_alloc(nfs_rdata_cachep, SLAB_NFS);
+	p = kmem_cache_alloc(nfs_rdata_cachep, SLAB_NOFS);
 	if (p) {
 		memset(p, 0, sizeof(*p));
 		INIT_LIST_HEAD(&p->pages);
diff -u --recursive --new-file v2.4.12/linux/fs/nfs/write.c linux/fs/nfs/write.c
--- v2.4.12/linux/fs/nfs/write.c	Tue Oct  9 17:06:53 2001
+++ linux/fs/nfs/write.c	Thu Oct 11 08:12:52 2001
@@ -109,7 +109,7 @@
 static __inline__ struct nfs_page *nfs_page_alloc(void)
 {
 	struct nfs_page	*p;
-	p = kmem_cache_alloc(nfs_page_cachep, SLAB_KERNEL);
+	p = kmem_cache_alloc(nfs_page_cachep, SLAB_NOFS);
 	if (p) {
 		memset(p, 0, sizeof(*p));
 		INIT_LIST_HEAD(&p->wb_hash);
@@ -127,7 +127,7 @@
 static __inline__ struct nfs_write_data *nfs_writedata_alloc(void)
 {
 	struct nfs_write_data	*p;
-	p = kmem_cache_alloc(nfs_wdata_cachep, SLAB_NFS);
+	p = kmem_cache_alloc(nfs_wdata_cachep, SLAB_NOFS);
 	if (p) {
 		memset(p, 0, sizeof(*p));
 		INIT_LIST_HEAD(&p->pages);
diff -u --recursive --new-file v2.4.12/linux/fs/nfsd/nfsxdr.c linux/fs/nfsd/nfsxdr.c
--- v2.4.12/linux/fs/nfsd/nfsxdr.c	Tue Oct  9 17:06:53 2001
+++ linux/fs/nfsd/nfsxdr.c	Thu Oct 11 07:49:46 2001
@@ -70,7 +70,6 @@
 			if (*name == '\0' || *name == '/')
 				return NULL;
 		}
-		*name = '\0';
 	}
 
 	return p;
diff -u --recursive --new-file v2.4.12/linux/fs/partitions/check.c linux/fs/partitions/check.c
--- v2.4.12/linux/fs/partitions/check.c	Tue Oct  9 17:06:53 2001
+++ linux/fs/partitions/check.c	Thu Oct 11 08:32:35 2001
@@ -247,6 +247,7 @@
 		printk(KERN_INFO " %s:", disk_name(hd, MINOR(dev), buf));
 	bdev = bdget(kdev_t_to_nr(dev));
 	bdev->bd_inode->i_size = (loff_t)hd->part[MINOR(dev)].nr_sects << 9;
+	bdev->bd_inode->i_blkbits = blksize_bits(block_size(dev));
 	for (i = 0; check_part[i]; i++) {
 		int res;
 		res = check_part[i](hd, bdev, first_sector, first_part_minor);
diff -u --recursive --new-file v2.4.12/linux/fs/partitions/msdos.c linux/fs/partitions/msdos.c
--- v2.4.12/linux/fs/partitions/msdos.c	Tue Oct  9 17:06:53 2001
+++ linux/fs/partitions/msdos.c	Thu Oct 11 08:07:07 2001
@@ -103,21 +103,20 @@
  */
 
 static void extended_partition(struct gendisk *hd, struct block_device *bdev,
-				int minor, int *current_minor)
+			int minor, unsigned long first_size, int *current_minor)
 {
 	struct partition *p;
 	Sector sect;
 	unsigned char *data;
-	unsigned long first_sector, first_size, this_sector, this_size;
+	unsigned long first_sector, this_sector, this_size;
 	int mask = (1 << hd->minor_shift) - 1;
 	int sector_size = get_hardsect_size(to_kdev_t(bdev->bd_dev)) / 512;
 	int loopct = 0;		/* number of links followed
 				   without finding a data partition */
 	int i;
 
-	first_sector = hd->part[minor].start_sect;
-	first_size = hd->part[minor].nr_sects;
-	this_sector = first_sector;
+	this_sector = first_sector = hd->part[minor].start_sect;
+	this_size = first_size;
 
 	while (1) {
 		if (++loopct > 100)
@@ -133,8 +132,6 @@
 
 		p = (struct partition *) (data + 0x1be);
 
-		this_size = hd->part[minor].nr_sects;
-
 		/*
 		 * Usually, the first entry is the real data partition,
 		 * the 2nd entry is the next extended partition, or empty,
@@ -196,6 +193,7 @@
 			goto done;	 /* nothing left to do */
 
 		this_sector = first_sector + START_SECT(p) * sector_size;
+		this_size = NR_SECTS(p) * sector_size;
 		minor = *current_minor;
 		put_dev_sector(sect);
 	}
@@ -586,12 +584,13 @@
 		}
 #endif
 		if (is_extended_partition(p)) {
+			unsigned long size = hd->part[minor].nr_sects;
 			printk(" <");
 			/* prevent someone doing mkfs or mkswap on an
 			   extended partition, but leave room for LILO */
-			if (hd->part[minor].nr_sects > 2)
+			if (size > 2)
 				hd->part[minor].nr_sects = 2;
-			extended_partition(hd, bdev, minor, &current_minor);
+			extended_partition(hd, bdev, minor, size, &current_minor);
 			printk(" >");
 		}
 	}
diff -u --recursive --new-file v2.4.12/linux/fs/proc/array.c linux/fs/proc/array.c
--- v2.4.12/linux/fs/proc/array.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/proc/array.c	Thu Oct 11 09:00:01 2001
@@ -151,12 +151,13 @@
 	read_lock(&tasklist_lock);
 	buffer += sprintf(buffer,
 		"State:\t%s\n"
+		"Tgid:\t%d\n"
 		"Pid:\t%d\n"
 		"PPid:\t%d\n"
 		"TracerPid:\t%d\n"
 		"Uid:\t%d\t%d\t%d\t%d\n"
 		"Gid:\t%d\t%d\t%d\t%d\n",
-		get_task_state(p),
+		get_task_state(p), p->tgid,
 		p->pid, p->pid ? p->p_opptr->pid : 0, 0,
 		p->uid, p->euid, p->suid, p->fsuid,
 		p->gid, p->egid, p->sgid, p->fsgid);
diff -u --recursive --new-file v2.4.12/linux/fs/proc/proc_misc.c linux/fs/proc/proc_misc.c
--- v2.4.12/linux/fs/proc/proc_misc.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/proc/proc_misc.c	Thu Oct 11 10:46:57 2001
@@ -140,6 +140,7 @@
 {
 	struct sysinfo i;
 	int len;
+	int pg_size ;
 
 /*
  * display in kilobytes.
@@ -148,12 +149,14 @@
 #define B(x) ((unsigned long long)(x) << PAGE_SHIFT)
 	si_meminfo(&i);
 	si_swapinfo(&i);
+	pg_size = atomic_read(&page_cache_size) - i.bufferram ;
+
 	len = sprintf(page, "        total:    used:    free:  shared: buffers:  cached:\n"
 		"Mem:  %8Lu %8Lu %8Lu %8Lu %8Lu %8Lu\n"
 		"Swap: %8Lu %8Lu %8Lu\n",
 		B(i.totalram), B(i.totalram-i.freeram), B(i.freeram),
 		B(i.sharedram), B(i.bufferram),
-		B(atomic_read(&page_cache_size)), B(i.totalswap),
+		B(pg_size), B(i.totalswap),
 		B(i.totalswap-i.freeswap), B(i.freeswap));
 	/*
 	 * Tagged format, for easy grepping and expansion.
@@ -179,7 +182,7 @@
 		K(i.freeram),
 		K(i.sharedram),
 		K(i.bufferram),
-		K(atomic_read(&page_cache_size) - swapper_space.nrpages),
+		K(pg_size - swapper_space.nrpages),
 		K(swapper_space.nrpages),
 		K(nr_active_pages),
 		K(nr_inactive_pages),
diff -u --recursive --new-file v2.4.12/linux/fs/udf/balloc.c linux/fs/udf/balloc.c
--- v2.4.12/linux/fs/udf/balloc.c	Tue Oct  9 17:06:53 2001
+++ linux/fs/udf/balloc.c	Thu Oct 11 08:59:24 2001
@@ -44,12 +44,15 @@
 #define leBPL_to_cpup(x) leNUM_to_cpup(BITS_PER_LONG, x)
 #define leNUM_to_cpup(x,y) xleNUM_to_cpup(x,y)
 #define xleNUM_to_cpup(x,y) (le ## x ## _to_cpup(y))
+#define UintBPL Uint(BITS_PER_LONG)
+#define Uint(x) xUint(x)
+#define xUint(x) Uint ## x
 
 extern inline int find_next_one_bit (void * addr, int size, int offset)
 {
-	unsigned long * p = ((unsigned long *) addr) + (offset / BITS_PER_LONG);
-	unsigned long result = offset & ~(BITS_PER_LONG-1);
-	unsigned long tmp;
+	UintBPL * p = ((UintBPL *) addr) + (offset / BITS_PER_LONG);
+	UintBPL result = offset & ~(BITS_PER_LONG-1);
+	UintBPL tmp;
 
 	if (offset >= size)
 		return size;
@@ -126,7 +129,7 @@
 	}
 }
 
-static inline int load_block_bitmap(struct super_block *sb,
+static inline int load_block_bitmap(struct super_block * sb,
 	struct udf_bitmap *bitmap, unsigned int block_group)
 {
 	int slot;
@@ -142,7 +145,8 @@
 	return slot;
 }
 
-static void udf_bitmap_free_blocks(struct inode * inode,
+static void udf_bitmap_free_blocks(struct super_block * sb,
+	struct inode * inode,
 	struct udf_bitmap *bitmap, lb_addr bloc, Uint32 offset, Uint32 count)
 {
 	struct buffer_head * bh = NULL;
@@ -152,14 +156,6 @@
 	unsigned long i;
 	int bitmap_nr;
 	unsigned long overflow;
-	struct super_block * sb;
-
-	sb = inode->i_sb;
-	if (!sb)
-	{
-		udf_debug("nonexistent device");
-		return;
-	}
 
 	lock_super(sb);
 	if (bloc.logicalBlockNum < 0 ||
@@ -200,7 +196,8 @@
 		}
 		else
 		{
-			DQUOT_FREE_BLOCK(inode, 1);
+			if (inode)
+				DQUOT_FREE_BLOCK(inode, 1);
 			if (UDF_SB_LVIDBH(sb))
 			{
 				UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)] =
@@ -223,7 +220,8 @@
 	return;
 }
 
-static int udf_bitmap_prealloc_blocks(struct inode * inode,
+static int udf_bitmap_prealloc_blocks(struct super_block * sb,
+	struct inode * inode,
 	struct udf_bitmap *bitmap, Uint16 partition, Uint32 first_block,
 	Uint32 block_count)
 {
@@ -231,14 +229,7 @@
 	int bit, block, block_group, group_start;
 	int nr_groups, bitmap_nr;
 	struct buffer_head *bh;
-	struct super_block *sb;
 
-	sb = inode->i_sb;
-	if (!sb)
-	{
-		udf_debug("nonexistent device\n");
-		return 0;
-	}
 	lock_super(sb);
 
 	if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
@@ -293,23 +284,17 @@
 	return alloc_count;
 }
 
-static int udf_bitmap_new_block(struct inode * inode,
+static int udf_bitmap_new_block(struct super_block * sb,
+	struct inode * inode,
 	struct udf_bitmap *bitmap, Uint16 partition, Uint32 goal, int *err)
 {
 	int newbit, bit=0, block, block_group, group_start;
 	int end_goal, nr_groups, bitmap_nr, i;
 	struct buffer_head *bh = NULL;
-	struct super_block *sb;
 	char *ptr;
 	int newblock = 0;
 
 	*err = -ENOSPC;
-	sb = inode->i_sb;
-	if (!sb)
-	{
-		udf_debug("nonexistent device\n");
-		return newblock;
-	}
 	lock_super(sb);
 
 repeat:
@@ -404,7 +389,7 @@
 	/*
 	 * Check quota for allocation of this block.
 	 */
-	if (DQUOT_ALLOC_BLOCK(inode, 1))
+	if (inode && DQUOT_ALLOC_BLOCK(inode, 1))
 	{
 		unlock_super(sb);
 		*err = -EDQUOT;
@@ -439,30 +424,17 @@
 	return 0;
 }
 
-static void udf_table_free_blocks(struct inode * inode,
+static void udf_table_free_blocks(struct super_block * sb,
+	struct inode * inode,
 	struct inode * table, lb_addr bloc, Uint32 offset, Uint32 count)
 {
-	struct super_block * sb;
 	Uint32 start, end;
 	Uint32 nextoffset, oextoffset, elen;
 	lb_addr nbloc, obloc, eloc;
 	struct buffer_head *obh, *nbh;
-	char etype;
+	Sint8 etype;
 	int i;
 
-	udf_debug("ino=%ld, bloc=%d, offset=%d, count=%d\n",
-		inode->i_ino, bloc.logicalBlockNum, offset, count);
-
-	sb = inode->i_sb;
-	if (!sb)
-	{
-		udf_debug("nonexistent device");
-		return;
-	}
-
-	if (table == NULL)
-		return;
-
 	lock_super(sb);
 	if (bloc.logicalBlockNum < 0 ||
 		(bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
@@ -475,7 +447,8 @@
 
 	/* We do this up front - There are some error conditions that could occure,
 	   but.. oh well */
-	DQUOT_FREE_BLOCK(inode, count);
+	if (inode)
+		DQUOT_FREE_BLOCK(inode, count);
 	if (UDF_SB_LVIDBH(sb))
 	{
 		UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)] =
@@ -690,33 +663,20 @@
 	return;
 }
 
-static int udf_table_prealloc_blocks(struct inode * inode,
+static int udf_table_prealloc_blocks(struct super_block * sb,
+	struct inode * inode,
 	struct inode *table, Uint16 partition, Uint32 first_block,
 	Uint32 block_count)
 {
-	struct super_block *sb;
 	int alloc_count = 0;
 	Uint32 extoffset, elen, adsize;
 	lb_addr bloc, eloc;
 	struct buffer_head *bh;
-	char etype = -1;
-
-	udf_debug("ino=%ld, partition=%d, first_block=%d, block_count=%d\n",
-		inode->i_ino, partition, first_block, block_count);
-
-	sb = inode->i_sb;
-	if (!sb)
-	{
-		udf_debug("nonexistent device\n");
-		return 0;
-	}
+	Sint8 etype = -1;
 
 	if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
 		return 0;
 
-	if (table == NULL)
-		return 0;
-
 	if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_SHORT)
 		adsize = sizeof(short_ad);
 	else if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_LONG)
@@ -745,7 +705,9 @@
 		extoffset -= adsize;
 
 		alloc_count = (elen >> sb->s_blocksize_bits);
-		if (alloc_count > block_count)
+		if (inode && DQUOT_PREALLOC_BLOCK(inode, alloc_count > block_count ? block_count : alloc_count))
+			alloc_count = 0;
+		else if (alloc_count > block_count)
 		{
 			alloc_count = block_count;
 			eloc.logicalBlockNum += alloc_count;
@@ -765,37 +727,24 @@
 		UDF_SB_LVID(sb)->freeSpaceTable[partition] =
 			cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[partition])-alloc_count);
 		mark_buffer_dirty(UDF_SB_LVIDBH(sb));
+		sb->s_dirt = 1;
 	}
-	sb->s_dirt = 1;
 	unlock_super(sb);
-	udf_debug("alloc_count=%d\n", alloc_count);
 	return alloc_count;
 }
 
-static int udf_table_new_block(const struct inode * inode,
+static int udf_table_new_block(struct super_block * sb,
+	struct inode * inode,
 	struct inode *table, Uint16 partition, Uint32 goal, int *err)
 {
-	struct super_block *sb;
 	Uint32 spread = 0xFFFFFFFF, nspread;
 	Uint32 newblock = 0, adsize;
 	Uint32 extoffset, goal_extoffset, elen, goal_elen = 0;
 	lb_addr bloc, goal_bloc, eloc, goal_eloc;
 	struct buffer_head *bh, *goal_bh;
-	char etype;
-
-	udf_debug("ino=%ld, partition=%d, goal=%d\n",
-		inode->i_ino, partition, goal);
+	Sint8 etype;
 
 	*err = -ENOSPC;
-	sb = inode->i_sb;
-	if (!sb)
-	{
-		udf_debug("nonexistent device\n");
-		return newblock;
-	}
-
-	if (table == NULL)
-		return newblock;
 
 	if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_SHORT)
 		adsize = sizeof(short_ad);
@@ -868,6 +817,14 @@
 	goal_eloc.logicalBlockNum ++;
 	goal_elen -= sb->s_blocksize;
 
+	if (inode && DQUOT_ALLOC_BLOCK(inode, 1))
+	{
+		udf_release_data(goal_bh);
+		unlock_super(sb);
+		*err = -EDQUOT;
+		return 0;
+	}
+
 	if (goal_elen)
 		udf_write_aext(table, goal_bloc, &goal_extoffset, goal_eloc, goal_elen, goal_bh, 1);
 	else
@@ -887,93 +844,98 @@
 	return newblock;
 }
 
-inline void udf_free_blocks(struct inode * inode, lb_addr bloc,
-	Uint32 offset, Uint32 count)
+inline void udf_free_blocks(struct super_block * sb,
+	struct inode * inode,
+	lb_addr bloc, Uint32 offset, Uint32 count)
 {
-	if (UDF_SB_PARTFLAGS(inode->i_sb, bloc.partitionReferenceNum) & UDF_PART_FLAG_UNALLOC_BITMAP)
+	Uint16 partition = bloc.partitionReferenceNum;
+
+	if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
 	{
-		return udf_bitmap_free_blocks(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_uspace.s_bitmap,
+		return udf_bitmap_free_blocks(sb, inode,
+			UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap,
 			bloc, offset, count);
 	}
-	else if (UDF_SB_PARTFLAGS(inode->i_sb, bloc.partitionReferenceNum) & UDF_PART_FLAG_UNALLOC_TABLE)
+	else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
 	{
-		return udf_table_free_blocks(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_uspace.s_table,
+		return udf_table_free_blocks(sb, inode,
+			UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_table,
 			bloc, offset, count);
 	}
-	else if (UDF_SB_PARTFLAGS(inode->i_sb, bloc.partitionReferenceNum) & UDF_PART_FLAG_FREED_BITMAP)
+	else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
 	{
-		return udf_bitmap_free_blocks(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_fspace.s_bitmap,
+		return udf_bitmap_free_blocks(sb, inode,
+			UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_bitmap,
 			bloc, offset, count);
 	}
-	else if (UDF_SB_PARTFLAGS(inode->i_sb, bloc.partitionReferenceNum) & UDF_PART_FLAG_FREED_TABLE)
+	else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_TABLE)
 	{
-		return udf_table_free_blocks(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_fspace.s_table,
+		return udf_table_free_blocks(sb, inode,
+			UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_table,
 			bloc, offset, count);
 	}
 	else
 		return;
 }
 
-inline int udf_prealloc_blocks(struct inode * inode, Uint16 partition,
-	Uint32 first_block, Uint32 block_count)
+inline int udf_prealloc_blocks(struct super_block * sb,
+	struct inode * inode,
+	Uint16 partition, Uint32 first_block, Uint32 block_count)
 {
-	if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
+	if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
 	{
-		return udf_bitmap_prealloc_blocks(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.s_bitmap,
+		return udf_bitmap_prealloc_blocks(sb, inode,
+			UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap,
 			partition, first_block, block_count);
 	}
-	else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
+	else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
 	{
-		return udf_table_prealloc_blocks(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.s_table,
+		return udf_table_prealloc_blocks(sb, inode,
+			UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_table,
 			partition, first_block, block_count);
 	}
-	else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
+	else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
 	{
-		return udf_bitmap_prealloc_blocks(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.s_bitmap,
+		return udf_bitmap_prealloc_blocks(sb, inode,
+			UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_bitmap,
 			partition, first_block, block_count);
 	}
-	else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_FREED_TABLE)
+	else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_TABLE)
 	{
-		return udf_table_prealloc_blocks(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.s_table,
+		return udf_table_prealloc_blocks(sb, inode,
+			UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_table,
 			partition, first_block, block_count);
 	}
 	else
 		return 0;
 }
 
-inline int udf_new_block(struct inode * inode, Uint16 partition,
-	Uint32 goal, int *err)
+inline int udf_new_block(struct super_block * sb,
+	struct inode * inode,
+	Uint16 partition, Uint32 goal, int *err)
 {
-	if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
+	if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
 	{
-		return udf_bitmap_new_block(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.s_bitmap,
+		return udf_bitmap_new_block(sb, inode,
+			UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap,
 			partition, goal, err);
 	}
-	else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
+	else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
 	{
-		return udf_table_new_block(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.s_table,
+		return udf_table_new_block(sb, inode,
+			UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_table,
 			partition, goal, err);
 	}
-	else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
+	else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
 	{
-		return udf_bitmap_new_block(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.s_bitmap,
+		return udf_bitmap_new_block(sb, inode,
+			UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_bitmap,
 			partition, goal, err);
 	}
-	else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_FREED_TABLE)
+	else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_TABLE)
 	{
-		return udf_table_new_block(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.s_table,
+		return udf_table_new_block(sb, inode,
+			UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_table,
 			partition, goal, err);
 	}
 	else
diff -u --recursive --new-file v2.4.12/linux/fs/udf/dir.c linux/fs/udf/dir.c
--- v2.4.12/linux/fs/udf/dir.c	Tue Jul  3 17:08:21 2001
+++ linux/fs/udf/dir.c	Thu Oct 11 08:59:24 2001
@@ -186,7 +186,7 @@
 				udf_release_data(fibh.ebh);
 			udf_release_data(fibh.sbh);
 			udf_release_data(bh);
-			return -ENOENT;
+			return 0;
 		}
 
 		liu = le16_to_cpu(cfi.lengthOfImpUse);
diff -u --recursive --new-file v2.4.12/linux/fs/udf/file.c linux/fs/udf/file.c
--- v2.4.12/linux/fs/udf/file.c	Tue Jul  3 17:08:21 2001
+++ linux/fs/udf/file.c	Thu Oct 11 08:59:24 2001
@@ -206,7 +206,7 @@
 int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
 	unsigned long arg)
 {
-	int result = -1;
+	int result = -EINVAL;
 	struct buffer_head *bh = NULL;
 	long_ad eaicb;
 	Uint8 *ea = NULL;
@@ -228,16 +228,16 @@
 	switch (cmd)
 	{
 		case UDF_GETVOLIDENT:
-			if ( (result == verify_area(VERIFY_WRITE, (char *)arg, 32)) == 0)
-				result = copy_to_user((char *)arg, UDF_SB_VOLIDENT(inode->i_sb), 32);
-			return result;
+			return copy_to_user((char *)arg,
+				UDF_SB_VOLIDENT(inode->i_sb), 32) ? -EFAULT : 0;
 		case UDF_RELOCATE_BLOCKS:
 		{
 			long old, new;
 
 			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-			get_user(old, (long *)arg);
-			if ((result = udf_relocate_blocks(inode->i_sb, old, &new)) == 0)
+			if (get_user(old, (long *)arg)) return -EFAULT;
+			if ((result = udf_relocate_blocks(inode->i_sb,
+					old, &new)) == 0)
 				result = put_user(new, (long *)arg);
 
 			return result;
@@ -277,16 +277,12 @@
 	switch (cmd) 
 	{
 		case UDF_GETEASIZE:
-			if ( (result = verify_area(VERIFY_WRITE, (char *)arg, 4)) == 0) 
-				result = put_user(UDF_I_LENEATTR(inode), (int *)arg);
+			result = put_user(UDF_I_LENEATTR(inode), (int *)arg);
 			break;
 
 		case UDF_GETEABLOCK:
-			if ( (result = verify_area(VERIFY_WRITE, (char *)arg, UDF_I_LENEATTR(inode))) == 0) 
-				result = copy_to_user((char *)arg, ea, UDF_I_LENEATTR(inode));
-			break;
-
-		default:
+			result = copy_to_user((char *)arg, ea,
+				UDF_I_LENEATTR(inode)) ? -EFAULT : 0;
 			break;
 	}
 
diff -u --recursive --new-file v2.4.12/linux/fs/udf/ialloc.c linux/fs/udf/ialloc.c
--- v2.4.12/linux/fs/udf/ialloc.c	Tue Oct  9 17:06:53 2001
+++ linux/fs/udf/ialloc.c	Thu Oct 11 08:59:24 2001
@@ -64,10 +64,9 @@
 		
 		mark_buffer_dirty(UDF_SB_LVIDBH(sb));
 	}
-
 	unlock_super(sb);
 
-	udf_free_blocks(inode, UDF_I_LOCATION(inode), 0, 1);
+	udf_free_blocks(sb, NULL, UDF_I_LOCATION(inode), 0, 1);
 }
 
 struct inode * udf_new_inode (struct inode *dir, int mode, int * err)
@@ -87,7 +86,7 @@
 	}
 	*err = -ENOSPC;
 
-	block = udf_new_block(dir, UDF_I_LOCATION(dir).partitionReferenceNum,
+	block = udf_new_block(dir->i_sb, NULL, UDF_I_LOCATION(dir).partitionReferenceNum,
 		start, err);
 	if (*err)
 	{
diff -u --recursive --new-file v2.4.12/linux/fs/udf/inode.c linux/fs/udf/inode.c
--- v2.4.12/linux/fs/udf/inode.c	Tue Jul  3 17:08:21 2001
+++ linux/fs/udf/inode.c	Thu Oct 11 08:59:24 2001
@@ -236,7 +236,7 @@
 	}
 
 	/* alloc block, and copy data to it */
-	*block = udf_new_block(inode,
+	*block = udf_new_block(inode->i_sb, inode,
 		UDF_I_LOCATION(inode).partitionReferenceNum,
 		UDF_I_LOCATION(inode).logicalBlockNum, err);
 
@@ -302,7 +302,6 @@
 	udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &sbh, 0);
 	/* UniqueID stuff */
 
-	inode->i_blocks = inode->i_sb->s_blocksize / 512;
 	mark_buffer_dirty(sbh);
 	udf_release_data(sbh);
 	mark_inode_dirty(inode);
@@ -402,14 +401,14 @@
 	Uint32 elen = 0;
 	lb_addr eloc, pbloc, cbloc, nbloc;
 	int c = 1;
-	int lbcount = 0, b_off = 0, offset = 0;
-	Uint32 newblocknum, newblock;
-	char etype;
+	Uint64 lbcount = 0, b_off = 0;
+	Uint32 newblocknum, newblock, offset = 0;
+	Sint8 etype;
 	int goal = 0, pgoal = UDF_I_LOCATION(inode).logicalBlockNum;
 	char lastblock = 0;
 
 	pextoffset = cextoffset = nextoffset = udf_file_entry_alloc_offset(inode);
-	b_off = block << inode->i_sb->s_blocksize_bits;
+	b_off = (Uint64)block << inode->i_sb->s_blocksize_bits;
 	pbloc = cbloc = nbloc = UDF_I_LOCATION(inode);
 
 	/* find the extent which contains the block we are looking for.
@@ -546,7 +545,7 @@
 				goal = UDF_I_LOCATION(inode).logicalBlockNum + 1;
 		}
 
-		if (!(newblocknum = udf_new_block(inode,
+		if (!(newblocknum = udf_new_block(inode->i_sb, inode,
 			UDF_I_LOCATION(inode).partitionReferenceNum, goal, err)))
 		{
 			udf_release_data(pbh);
@@ -588,7 +587,7 @@
 	UDF_I_NEXT_ALLOC_GOAL(inode) = newblocknum;
 	inode->i_ctime = CURRENT_TIME;
 	UDF_I_UCTIME(inode) = CURRENT_UTIME;
-	inode->i_blocks += inode->i_sb->s_blocksize / 512;
+
 	if (IS_SYNC(inode))
 		udf_sync_inode(inode);
 	else
@@ -692,7 +691,7 @@
 		int next = laarr[start].extLocation.logicalBlockNum +
 			(((laarr[start].extLength & UDF_EXTENT_LENGTH_MASK) +
 			inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
-		int numalloc = udf_prealloc_blocks(inode,
+		int numalloc = udf_prealloc_blocks(inode->i_sb, inode,
 			laarr[start].extLocation.partitionReferenceNum,
 			next, (UDF_DEFAULT_PREALLOC_BLOCKS > length ? length :
 				UDF_DEFAULT_PREALLOC_BLOCKS) - currlength);
@@ -825,9 +824,6 @@
 	int create, int * err)
 {
 	struct buffer_head * bh = NULL;
-	int prev_blocks;
-
-	prev_blocks = inode->i_blocks;
 
 	bh = udf_getblk(inode, block, create, err);
 	if (!bh)
@@ -1602,7 +1598,7 @@
 	return inode;
 }
 
-int udf_add_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
+Sint8 udf_add_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
 	lb_addr eloc, Uint32 elen, struct buffer_head **bh, int inc)
 {
 	int adsize;
@@ -1637,7 +1633,7 @@
 		int err, loffset;
 		lb_addr obloc = *bloc;
 
-		if (!(bloc->logicalBlockNum = udf_new_block(inode,
+		if (!(bloc->logicalBlockNum = udf_new_block(inode->i_sb, inode,
 			obloc.partitionReferenceNum, obloc.logicalBlockNum, &err)))
 		{
 			return -1;
@@ -1739,7 +1735,7 @@
 	return ret;
 }
 
-int udf_write_aext(struct inode *inode, lb_addr bloc, int *extoffset,
+Sint8 udf_write_aext(struct inode *inode, lb_addr bloc, int *extoffset,
     lb_addr eloc, Uint32 elen, struct buffer_head *bh, int inc)
 {
 	int adsize;
@@ -1808,12 +1804,12 @@
 	return (elen >> 30);
 }
 
-int udf_next_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
+Sint8 udf_next_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
 	lb_addr *eloc, Uint32 *elen, struct buffer_head **bh, int inc)
 {
 	Uint16 tagIdent;
 	int pos, alen;
-	Uint8 etype;
+	Sint8 etype;
 
 	if (!(*bh))
 	{
@@ -1932,11 +1928,11 @@
 	return -1;
 }
 
-int udf_current_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
+Sint8 udf_current_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
 	lb_addr *eloc, Uint32 *elen, struct buffer_head **bh, int inc)
 {
 	int pos, alen;
-	Uint8 etype;
+	Sint8 etype;
 
 	if (!(*bh))
 	{
@@ -2013,12 +2009,12 @@
 	return -1;
 }
 
-int udf_insert_aext(struct inode *inode, lb_addr bloc, int extoffset,
+Sint8 udf_insert_aext(struct inode *inode, lb_addr bloc, int extoffset,
 	lb_addr neloc, Uint32 nelen, struct buffer_head *bh)
 {
 	lb_addr oeloc;
 	Uint32 oelen;
-	int type;
+	Sint8 etype;
 
 	if (!bh)
 	{
@@ -2034,25 +2030,25 @@
 	else
 		atomic_inc(&bh->b_count);
 
-	while ((type = udf_next_aext(inode, &bloc, &extoffset, &oeloc, &oelen, &bh, 0)) != -1)
+	while ((etype = udf_next_aext(inode, &bloc, &extoffset, &oeloc, &oelen, &bh, 0)) != -1)
 	{
 		udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);
 
 		neloc = oeloc;
-		nelen = (type << 30) | oelen;
+		nelen = (etype << 30) | oelen;
 	}
 	udf_add_aext(inode, &bloc, &extoffset, neloc, nelen, &bh, 1);
 	udf_release_data(bh);
 	return (nelen >> 30);
 }
 
-int udf_delete_aext(struct inode *inode, lb_addr nbloc, int nextoffset,
+Sint8 udf_delete_aext(struct inode *inode, lb_addr nbloc, int nextoffset,
 	lb_addr eloc, Uint32 elen, struct buffer_head *nbh)
 {
 	struct buffer_head *obh;
 	lb_addr obloc;
 	int oextoffset, adsize;
-	char type;
+	Sint8 etype;
 	struct AllocExtDesc *aed;
 
 	if (!(nbh))
@@ -2084,9 +2080,9 @@
 	if (udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1) == -1)
 		return -1;
 
-	while ((type = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1)
+	while ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1)
 	{
-		udf_write_aext(inode, obloc, &oextoffset, eloc, (type << 30) | elen, obh, 1);
+		udf_write_aext(inode, obloc, &oextoffset, eloc, (etype << 30) | elen, obh, 1);
 		if (memcmp(&nbloc, &obloc, sizeof(lb_addr)))
 		{
 			obloc = nbloc;
@@ -2101,7 +2097,7 @@
 
 	if (memcmp(&nbloc, &obloc, sizeof(lb_addr)))
 	{
-		udf_free_blocks(inode, nbloc, 0, 1);
+		udf_free_blocks(inode->i_sb, inode, nbloc, 0, 1);
 		udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
 		udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
 		if (!memcmp(&UDF_I_LOCATION(inode), &obloc, sizeof(lb_addr)))
@@ -2147,11 +2143,11 @@
 	return (elen >> 30);
 }
 
-int inode_bmap(struct inode *inode, int block, lb_addr *bloc, Uint32 *extoffset,
+Sint8 inode_bmap(struct inode *inode, int block, lb_addr *bloc, Uint32 *extoffset,
 	lb_addr *eloc, Uint32 *elen, Uint32 *offset, struct buffer_head **bh)
 {
-	Uint64 lbcount = 0, bcount = block << inode->i_sb->s_blocksize_bits;
-	char etype;
+	Uint64 lbcount = 0, bcount = (Uint64)block << inode->i_sb->s_blocksize_bits;
+	Sint8 etype;
 
 	if (block < 0)
 	{
diff -u --recursive --new-file v2.4.12/linux/fs/udf/namei.c linux/fs/udf/namei.c
--- v2.4.12/linux/fs/udf/namei.c	Tue Jul  3 17:08:21 2001
+++ linux/fs/udf/namei.c	Thu Oct 11 08:59:24 2001
@@ -835,7 +835,7 @@
 static int udf_rmdir(struct inode * dir, struct dentry * dentry)
 {
 	int retval;
-	struct inode * inode;
+	struct inode * inode = dentry->d_inode;
 	struct udf_fileident_bh fibh;
 	struct FileIdentDesc *fi, cfi;
 
@@ -844,9 +844,6 @@
 	if (!fi)
 		goto out;
 
-	inode = dentry->d_inode;
-	DQUOT_INIT(inode);
-
 	retval = -EIO;
 	if (udf_get_lb_pblock(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation), 0) != inode->i_ino)
 		goto end_rmdir;
@@ -881,7 +878,7 @@
 static int udf_unlink(struct inode * dir, struct dentry * dentry)
 {
 	int retval;
-	struct inode * inode;
+	struct inode * inode = dentry->d_inode;
 	struct udf_fileident_bh fibh;
 	struct FileIdentDesc *fi;
 	struct FileIdentDesc cfi;
@@ -891,9 +888,6 @@
 	if (!fi)
 		goto out;
 
-	inode = dentry->d_inode;
-	DQUOT_INIT(inode);
-
 	retval = -EIO;
 
 	if (udf_get_lb_pblock(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation), 0) !=
@@ -954,7 +948,7 @@
 		lb_addr bloc, eloc;
 		Uint32 elen, extoffset;
 
-		block = udf_new_block(inode,
+		block = udf_new_block(inode->i_sb, inode,
 			UDF_I_LOCATION(inode).partitionReferenceNum,
 			UDF_I_LOCATION(inode).logicalBlockNum, &err);
 		if (!block)
@@ -968,7 +962,6 @@
 		udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 0);
 		udf_release_data(bh);
 
-		inode->i_blocks = inode->i_sb->s_blocksize / 512;
 		block = udf_get_pblock(inode->i_sb, block,
 			UDF_I_LOCATION(inode).partitionReferenceNum, 0);
 		bh = udf_tread(inode->i_sb, block, inode->i_sb->s_blocksize);
@@ -1150,13 +1143,13 @@
 static int udf_rename (struct inode * old_dir, struct dentry * old_dentry,
 	struct inode * new_dir, struct dentry * new_dentry)
 {
-	struct inode * old_inode, * new_inode;
+	struct inode * old_inode = old_dentry->d_inode;
+	struct inode * new_inode = new_dentry->d_inode;
 	struct udf_fileident_bh ofibh, nfibh;
 	struct FileIdentDesc *ofi = NULL, *nfi = NULL, *dir_fi = NULL, ocfi, ncfi;
 	struct buffer_head *dir_bh = NULL;
 	int retval = -ENOENT;
 
-	old_inode = old_dentry->d_inode;
 	if ((ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi)))
 	{
 		if (ofibh.sbh != ofibh.ebh)
@@ -1169,7 +1162,6 @@
 		goto end_rename;
 	}
 
-	new_inode = new_dentry->d_inode;
 	nfi = udf_find_entry(new_dir, new_dentry, &nfibh, &ncfi);
 	if (nfi)
 	{
@@ -1179,10 +1171,6 @@
 				udf_release_data(nfibh.ebh);
 			udf_release_data(nfibh.sbh);
 			nfi = NULL;
-		}
-		else
-		{
-			DQUOT_INIT(new_inode);
 		}
 	}
 	if (S_ISDIR(old_inode->i_mode))
diff -u --recursive --new-file v2.4.12/linux/fs/udf/super.c linux/fs/udf/super.c
--- v2.4.12/linux/fs/udf/super.c	Tue Jul  3 17:08:21 2001
+++ linux/fs/udf/super.c	Thu Oct 11 08:59:24 2001
@@ -85,7 +85,7 @@
 static int udf_load_partition(struct super_block *, lb_addr *);
 static int udf_load_logicalvol(struct super_block *, struct buffer_head *, lb_addr *);
 static void udf_load_logicalvolint(struct super_block *, extent_ad);
-static int udf_find_anchor(struct super_block *, int, int);
+static void udf_find_anchor(struct super_block *);
 static int udf_find_fileset(struct super_block *, lb_addr *, lb_addr *);
 static void udf_load_pvoldesc(struct super_block *, struct buffer_head *);
 static void udf_load_fileset(struct super_block *, struct buffer_head *, lb_addr *);
@@ -164,7 +164,7 @@
  *	noadinicb	Don't embed data in the inode
  *	shortad		Use short ad's
  *	longad		Use long ad's (default)
- *	strict		Set strict conformance
+ *	nostrict	Unset strict conformance
  *	iocharset=	Set the NLS character set
  *
  *	The remaining are for debugging and disaster recovery:
@@ -208,8 +208,8 @@
 	uopt->blocksize = 2048;
 	uopt->partition = 0xFFFF;
 	uopt->session = 0xFFFFFFFF;
-	uopt->lastblock = 0xFFFFFFFF;
-	uopt->anchor = 0xFFFFFFFF;
+	uopt->lastblock = 0;
+	uopt->anchor = 0;
 	uopt->volume = 0xFFFFFFFF;
 	uopt->rootdir = 0xFFFFFFFF;
 	uopt->fileset = 0xFFFFFFFF;
@@ -244,8 +244,8 @@
 			uopt->gid = simple_strtoul(val, NULL, 0);
 		else if (!strcmp(opt, "umask") && val)
 			uopt->umask = simple_strtoul(val, NULL, 0);
-		else if (!strcmp(opt, "strict") && !val)
-			uopt->flags |= (1 << UDF_FLAG_STRICT);
+		else if (!strcmp(opt, "nostrict") && !val)
+			uopt->flags &= ~(1 << UDF_FLAG_STRICT);
 		else if (!strcmp(opt, "uid") && val)
 			uopt->uid = simple_strtoul(val, NULL, 0);
 		else if (!strcmp(opt, "session") && val)
@@ -496,72 +496,36 @@
  *	July 1, 1997 - Andrew E. Mileski
  *	Written, tested, and released.
  */
-static int
-udf_find_anchor(struct super_block *sb, int useranchor, int lastblock)
+static void
+udf_find_anchor(struct super_block *sb)
 {
-	int varlastblock = udf_variable_to_fixed(lastblock);
-	int last[] =  { lastblock, lastblock - 2,
-			lastblock - 150, lastblock - 152,
-			varlastblock, varlastblock - 2,
-			varlastblock - 150, varlastblock - 152 };
+	int lastblock = UDF_SB_LASTBLOCK(sb);
 	struct buffer_head *bh = NULL;
 	Uint16 ident;
 	Uint32 location;
 	int i;
 
-	UDF_SB_ANCHOR(sb)[0] = 0;
-	UDF_SB_ANCHOR(sb)[1] = 0;
-	UDF_SB_ANCHOR(sb)[2] = 0;
-	UDF_SB_ANCHOR(sb)[3] = 256 + UDF_SB_SESSION(sb);
+	if (lastblock)
+	{
+		int varlastblock = udf_variable_to_fixed(lastblock);
+		int last[] =  { lastblock, lastblock - 2,
+				lastblock - 150, lastblock - 152,
+				varlastblock, varlastblock - 2,
+				varlastblock - 150, varlastblock - 152 };
 
-	lastblock = 0;
+		lastblock = 0;
 
-	/* Search for an anchor volume descriptor pointer */
+		/* Search for an anchor volume descriptor pointer */
 
-	/*  according to spec, anchor is in either:
-	 *     block 256
-	 *     lastblock-256
-	 *     lastblock
-	 *  however, if the disc isn't closed, it could be 512 */
+		/*  according to spec, anchor is in either:
+		 *     block 256
+		 *     lastblock-256
+		 *     lastblock
+		 *  however, if the disc isn't closed, it could be 512 */
 
-	for (i=0; (!lastblock && i<sizeof(last)/sizeof(int)); i++)
-	{
-		if (last[i] < 0 || !(bh = bread(sb->s_dev, last[i], sb->s_blocksize)))
-		{
-			ident = location = 0;
-		}
-		else
+		for (i=0; (!lastblock && i<sizeof(last)/sizeof(int)); i++)
 		{
-			ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
-			location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
-			udf_release_data(bh);
-		}
-
-		if (ident == TID_ANCHOR_VOL_DESC_PTR)
-		{
-			if (location == last[i] - UDF_SB_SESSION(sb))
-			{
-				lastblock = UDF_SB_ANCHOR(sb)[0] = last[i];
-				UDF_SB_ANCHOR(sb)[1] = last[i] - 256;
-			}
-			else if (location == udf_variable_to_fixed(last[i]) - UDF_SB_SESSION(sb))
-			{
-				UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
-				lastblock = UDF_SB_ANCHOR(sb)[0] = udf_variable_to_fixed(last[i]);
-				UDF_SB_ANCHOR(sb)[1] = lastblock - 256;
-			}
-			else
-				udf_debug("Anchor found at block %d, location mismatch %d.\n",
-					last[i], location);
-		}
-		else if (ident == TID_FILE_ENTRY || ident == TID_EXTENDED_FILE_ENTRY)
-		{
-			lastblock = last[i];
-			UDF_SB_ANCHOR(sb)[2] = 512 + UDF_SB_SESSION(sb);
-		}
-		else
-		{
-			if (!(bh = bread(sb->s_dev, last[i] - 256, sb->s_blocksize)))
+			if (last[i] < 0 || !(bh = bread(sb->s_dev, last[i], sb->s_blocksize)))
 			{
 				ident = location = 0;
 			}
@@ -571,17 +535,32 @@
 				location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
 				udf_release_data(bh);
 			}
-
-			if (ident == TID_ANCHOR_VOL_DESC_PTR &&
-				location == last[i] - 256 - UDF_SB_SESSION(sb))
+	
+			if (ident == TID_ANCHOR_VOL_DESC_PTR)
+			{
+				if (location == last[i] - UDF_SB_SESSION(sb))
+				{
+					lastblock = UDF_SB_ANCHOR(sb)[0] = last[i];
+					UDF_SB_ANCHOR(sb)[1] = last[i] - 256;
+				}
+				else if (location == udf_variable_to_fixed(last[i]) - UDF_SB_SESSION(sb))
+				{
+					UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
+					lastblock = UDF_SB_ANCHOR(sb)[0] = udf_variable_to_fixed(last[i]);
+					UDF_SB_ANCHOR(sb)[1] = lastblock - 256;
+				}
+				else
+					udf_debug("Anchor found at block %d, location mismatch %d.\n",
+						last[i], location);
+			}
+			else if (ident == TID_FILE_ENTRY || ident == TID_EXTENDED_FILE_ENTRY)
 			{
 				lastblock = last[i];
-				UDF_SB_ANCHOR(sb)[1] = last[i] - 256;
+				UDF_SB_ANCHOR(sb)[3] = 512 + UDF_SB_SESSION(sb);
 			}
 			else
 			{
-				if (!(bh = bread(sb->s_dev, last[i] - 312 - UDF_SB_SESSION(sb),
-					sb->s_blocksize)))
+				if (last[i] < 256 || !(bh = bread(sb->s_dev, last[i] - 256, sb->s_blocksize)))
 				{
 					ident = location = 0;
 				}
@@ -591,13 +570,34 @@
 					location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
 					udf_release_data(bh);
 				}
-
+	
 				if (ident == TID_ANCHOR_VOL_DESC_PTR &&
-					location == udf_variable_to_fixed(last[i]) - 256)
+					location == last[i] - 256 - UDF_SB_SESSION(sb))
 				{
-					UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
-					lastblock = udf_variable_to_fixed(last[i]);
-					UDF_SB_ANCHOR(sb)[1] = lastblock - 256;
+					lastblock = last[i];
+					UDF_SB_ANCHOR(sb)[1] = last[i] - 256;
+				}
+				else
+				{
+					if (last[i] < 312 + UDF_SB_SESSION(sb) || !(bh = bread(sb->s_dev, last[i] - 312 - UDF_SB_SESSION(sb),
+						sb->s_blocksize)))
+					{
+						ident = location = 0;
+					}
+					else
+					{
+						ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
+						location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
+						udf_release_data(bh);
+					}
+	
+					if (ident == TID_ANCHOR_VOL_DESC_PTR &&
+						location == udf_variable_to_fixed(last[i]) - 256)
+					{
+						UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
+						lastblock = udf_variable_to_fixed(last[i]);
+						UDF_SB_ANCHOR(sb)[1] = lastblock - 256;
+					}
 				}
 			}
 		}
@@ -636,15 +636,9 @@
 				}
 			}
 		}
-		else if (useranchor != 0xFFFFFFFF)
-		{
-			UDF_SB_ANCHOR(sb)[i] = useranchor;
-			useranchor = 0xFFFFFFFF;
-			i --;
-		}
 	}
 
-	return lastblock;
+	UDF_SB_LASTBLOCK(sb) = lastblock;
 }
 
 static int 
@@ -985,8 +979,10 @@
 	struct buffer_head *bh = NULL;
 	Uint16 ident;
 
-	while ((bh = udf_read_tagged(sb, loc.extLocation, loc.extLocation, &ident)) &&
-		ident == TID_LOGICAL_VOL_INTEGRITY_DESC && loc.extLength > 0)
+	while (loc.extLength > 0 &&
+		(bh = udf_read_tagged(sb, loc.extLocation,
+			loc.extLocation, &ident)) &&
+		ident == TID_LOGICAL_VOL_INTEGRITY_DESC)
 	{
 		UDF_SB_LVIDBH(sb) = bh;
 		
@@ -1152,6 +1148,8 @@
 	else if ((block = udf_vrs(sb, silent)) == -1)
 	{
 		udf_debug("Failed to read byte 32768. Assuming open disc. Skipping validity check\n");
+		if (!UDF_SB_LASTBLOCK(sb))
+			UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb);
 		return 0;
 	}
 	else 
@@ -1220,6 +1218,12 @@
 
 				if (!UDF_SB_LASTBLOCK(sb))
 				{
+					UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb);
+					udf_find_anchor(sb);
+				}
+
+				if (!UDF_SB_LASTBLOCK(sb))
+				{
 					udf_debug("Unable to determine Lastblock (For Virtual Partition)\n");
 					return 1;
 				}
@@ -1355,7 +1359,7 @@
 	struct udf_options uopt;
 	lb_addr rootdir, fileset;
 
-	uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB);
+	uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT);
 	uopt.uid = -1;
 	uopt.gid = -1;
 	uopt.umask = 0;
@@ -1409,14 +1413,10 @@
 
 	udf_debug("Multi-session=%d\n", UDF_SB_SESSION(sb));
 
-	if ( uopt.lastblock == 0xFFFFFFFF )
-		UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb);
-	else
-		UDF_SB_LASTBLOCK(sb) = uopt.lastblock;
-
-	UDF_SB_LASTBLOCK(sb) = udf_find_anchor(sb, uopt.anchor, UDF_SB_LASTBLOCK(sb));
-
-	udf_debug("Lastblock=%d\n", UDF_SB_LASTBLOCK(sb));
+	UDF_SB_LASTBLOCK(sb) = uopt.lastblock;
+	UDF_SB_ANCHOR(sb)[0] = UDF_SB_ANCHOR(sb)[1] = 0;
+	UDF_SB_ANCHOR(sb)[2] = uopt.anchor;
+	UDF_SB_ANCHOR(sb)[3] = UDF_SB_SESSION(sb) + 256;
 
 	if (udf_check_valid(sb, uopt.novrs, silent)) /* read volume recognition sequences */
 	{
@@ -1424,6 +1424,8 @@
  		goto error_out;
 	}
 
+	udf_find_anchor(sb);
+
 	/* Fill in the rest of the superblock */
 	sb->s_op = &udf_sb_ops;
 	sb->dq_op = NULL;
@@ -1436,6 +1438,8 @@
 		goto error_out;
 	}
 
+	udf_debug("Lastblock=%d\n", UDF_SB_LASTBLOCK(sb));
+
 	if ( UDF_SB_LVIDBH(sb) )
 	{
 		Uint16 minUDFReadRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev);
@@ -1744,7 +1748,7 @@
 	unsigned int accum = 0;
 	Uint32 extoffset, elen;
 	lb_addr bloc, eloc;
-	char etype;
+	Sint8 etype;
 	struct buffer_head *bh = NULL;
 
 	bloc = UDF_I_LOCATION(table);
@@ -1763,6 +1767,20 @@
 {
 	unsigned int accum = 0;
 
+	if (UDF_SB_LVIDBH(sb))
+	{
+		if (le32_to_cpu(UDF_SB_LVID(sb)->numOfPartitions) > UDF_SB_PARTITION(sb))
+		{
+			accum = le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)]);
+
+			if (accum == 0xFFFFFFFF)
+				accum = 0;
+		}
+	}
+
+	if (accum)
+		return accum;
+
 	if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP)
 	{
 		accum += udf_count_free_bitmap(sb,
@@ -1786,18 +1804,6 @@
 		accum += udf_count_free_table(sb,
 			UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table);
 	}
-	if (accum)
-		return accum;
 
-	if (UDF_SB_LVIDBH(sb))
-	{
-		if (le32_to_cpu(UDF_SB_LVID(sb)->numOfPartitions) > UDF_SB_PARTITION(sb))
-		{
-			accum = le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)]);
-
-			if (accum == 0xFFFFFFFF)
-				accum = 0;
-		}
-	}
 	return accum;
 }
diff -u --recursive --new-file v2.4.12/linux/fs/udf/truncate.c linux/fs/udf/truncate.c
--- v2.4.12/linux/fs/udf/truncate.c	Tue Jul  3 17:08:21 2001
+++ linux/fs/udf/truncate.c	Thu Oct 11 08:59:24 2001
@@ -33,10 +33,9 @@
 #include "udf_sb.h"
 
 static void extent_trunc(struct inode * inode, lb_addr bloc, int extoffset,
-	lb_addr eloc, Uint8 etype, Uint32 elen, struct buffer_head *bh, Uint32 nelen)
+	lb_addr eloc, Sint8 etype, Uint32 elen, struct buffer_head *bh, Uint32 nelen)
 {
 	lb_addr neloc = { 0, 0 };
-	int blocks = inode->i_sb->s_blocksize / 512;
 	int last_block = (elen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
 	int first_block = (nelen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
 
@@ -52,12 +51,10 @@
 		if (last_block - first_block > 0)
 		{
 			if (etype == EXTENT_RECORDED_ALLOCATED)
-			{
-				inode->i_blocks -= (blocks * (last_block - first_block));
 				mark_inode_dirty(inode);
-			}
+
 			if (etype != EXTENT_NOT_RECORDED_NOT_ALLOCATED)
-				udf_free_blocks(inode, eloc, first_block, last_block - first_block);
+				udf_free_blocks(inode->i_sb, inode, eloc, first_block, last_block - first_block);
 		}
 	}
 }
@@ -66,7 +63,7 @@
 {
 	lb_addr bloc, eloc, neloc = { 0, 0 };
 	Uint32 extoffset, elen, offset, nelen = 0, lelen = 0, lenalloc;
-	int etype;
+	Sint8 etype;
 	int first_block = inode->i_size >> inode->i_sb->s_blocksize_bits;
 	struct buffer_head *bh = NULL;
 	int adsize;
@@ -108,7 +105,7 @@
 						memset(bh->b_data, 0x00, udf_file_entry_alloc_offset(inode));
 					else
 						memset(bh->b_data, 0x00, sizeof(struct AllocExtDesc));
-					udf_free_blocks(inode, bloc, 0, lelen);
+					udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen);
 				}
 				else
 				{
@@ -153,7 +150,7 @@
 				memset(bh->b_data, 0x00, udf_file_entry_alloc_offset(inode));
 			else
 				memset(bh->b_data, 0x00, sizeof(struct AllocExtDesc));
-			udf_free_blocks(inode, bloc, 0, lelen);
+			udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen);
 		}
 		else
 		{
diff -u --recursive --new-file v2.4.12/linux/fs/udf/udfdecl.h linux/fs/udf/udfdecl.h
--- v2.4.12/linux/fs/udf/udfdecl.h	Tue Oct  9 17:06:53 2001
+++ linux/fs/udf/udfdecl.h	Thu Oct 11 08:59:24 2001
@@ -11,7 +11,6 @@
 
 #include <linux/config.h>
 #include <linux/types.h>
-
 #include <linux/fs.h>
 
 #if !defined(CONFIG_UDF_FS) && !defined(CONFIG_UDF_FS_MODULE)
@@ -129,13 +128,13 @@
 extern void udf_delete_inode(struct inode *);
 extern void udf_write_inode(struct inode *, int);
 extern long udf_block_map(struct inode *, long);
-extern int inode_bmap(struct inode *, int, lb_addr *, Uint32 *, lb_addr *, Uint32 *, Uint32 *, struct buffer_head **);
-extern int udf_add_aext(struct inode *, lb_addr *, int *, lb_addr, Uint32, struct buffer_head **, int);
-extern int udf_write_aext(struct inode *, lb_addr, int *, lb_addr, Uint32, struct buffer_head *, int);
-extern int udf_insert_aext(struct inode *, lb_addr, int, lb_addr, Uint32, struct buffer_head *);
-extern int udf_delete_aext(struct inode *, lb_addr, int, lb_addr, Uint32, struct buffer_head *);
-extern int udf_next_aext(struct inode *, lb_addr *, int *, lb_addr *, Uint32 *, struct buffer_head **, int);
-extern int udf_current_aext(struct inode *, lb_addr *, int *, lb_addr *, Uint32 *, struct buffer_head **, int);
+extern Sint8 inode_bmap(struct inode *, int, lb_addr *, Uint32 *, lb_addr *, Uint32 *, Uint32 *, struct buffer_head **);
+extern Sint8 udf_add_aext(struct inode *, lb_addr *, int *, lb_addr, Uint32, struct buffer_head **, int);
+extern Sint8 udf_write_aext(struct inode *, lb_addr, int *, lb_addr, Uint32, struct buffer_head *, int);
+extern Sint8 udf_insert_aext(struct inode *, lb_addr, int, lb_addr, Uint32, struct buffer_head *);
+extern Sint8 udf_delete_aext(struct inode *, lb_addr, int, lb_addr, Uint32, struct buffer_head *);
+extern Sint8 udf_next_aext(struct inode *, lb_addr *, int *, lb_addr *, Uint32 *, struct buffer_head **, int);
+extern Sint8 udf_current_aext(struct inode *, lb_addr *, int *, lb_addr *, Uint32 *, struct buffer_head **, int);
 extern void udf_discard_prealloc(struct inode *);
 
 /* misc.c */
@@ -171,9 +170,9 @@
 extern void udf_truncate_extents(struct inode *);
 
 /* balloc.c */
-extern void udf_free_blocks(struct inode *, lb_addr, Uint32, Uint32);
-extern int udf_prealloc_blocks(struct inode *, Uint16, Uint32, Uint32);
-extern int udf_new_block(struct inode *, Uint16, Uint32, int *);
+extern void udf_free_blocks(struct super_block *, struct inode *, lb_addr, Uint32, Uint32);
+extern int udf_prealloc_blocks(struct super_block *, struct inode *, Uint16, Uint32, Uint32);
+extern int udf_new_block(struct super_block *, struct inode *, Uint16, Uint32, int *);
 
 /* fsync.c */
 extern int udf_fsync_file(struct file *, struct dentry *, int);
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/a.out.h linux/include/asm-arm/a.out.h
--- v2.4.12/linux/include/asm-arm/a.out.h	Sun Aug 13 09:54:15 2000
+++ linux/include/asm-arm/a.out.h	Thu Oct 11 09:04:57 2001
@@ -1,6 +1,7 @@
 #ifndef __ARM_A_OUT_H__
 #define __ARM_A_OUT_H__
 
+#include <linux/personality.h>
 #include <asm/types.h>
 
 struct exec
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/arch-sa1100/SA-1111.h linux/include/asm-arm/arch-sa1100/SA-1111.h
--- v2.4.12/linux/include/asm-arm/arch-sa1100/SA-1111.h	Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/arch-sa1100/SA-1111.h	Thu Oct 11 09:04:57 2001
@@ -42,15 +42,15 @@
  *    SKID	ID Register
  */
 
-#define _SKCR		_SA1111( 0x0000 )
-#define _SMCR		_SA1111( 0x0004 )
-#define _SKID		_SA1111( 0x0008 )
+#define _SBI_SKCR	_SA1111( 0x0000 )
+#define _SBI_SMCR	_SA1111( 0x0004 )
+#define _SBI_SKID	_SA1111( 0x0008 )
 
 #if LANGUAGE == C
 
-#define SKCR		(*((volatile Word *) SA1111_p2v (_SKCR)))
-#define SMCR		(*((volatile Word *) SA1111_p2v (_SMCR)))
-#define SKID		(*((volatile Word *) SA1111_p2v (_SKID)))
+#define SBI_SKCR	(*((volatile Word *) SA1111_p2v (_SBI_SKCR)))
+#define SBI_SMCR	(*((volatile Word *) SA1111_p2v (_SBI_SMCR)))
+#define SBI_SKID	(*((volatile Word *) SA1111_p2v (_SBI_SKID)))
 
 #endif  /* LANGUAGE == C */
 
@@ -66,6 +66,18 @@
 #define SKCR_OPPC	(1<<9)
 #define SKCR_PLLTSTEN	(1<<10)
 #define SKCR_USBIOTSTEN	(1<<11)
+/*
+ * Don't believe the specs!  Take them, throw them outside.  Leave them
+ * there for a week.  Spit on them.  Walk on them.  Stamp on them.
+ * Pour gasoline over them and finally burn them.  Now think about coding.
+ *  - The October 1999 errata (278260-007) says its bit 13, 1 to enable.
+ *  - The Feb 2001 errata (278260-010) says that the previous errata
+ *    (278260-009) is wrong, and its bit actually 12, fixed in spec
+ *    278242-003.
+ *  - The SA1111 manual (278242) says bit 12, but 0 to enable.
+ *  - Reality is bit 13, 1 to enable.
+ *      -- rmk
+ */
 #define SKCR_OE_EN	(1<<13)
 
 #define SMCR_DTIM	(1<<0)
@@ -129,6 +141,34 @@
 #define SKPCR_PTCLKEN	(1<<6)
 #define SKPCR_DCLKEN	(1<<7)
 #define SKPCR_PWMCLKEN	(1<<8)
+
+/*
+ * USB Host controller
+ */
+#define _USB_OHCI_OP_BASE	_SA1111( 0x400 )
+#define _USB_STATUS		_SA1111( 0x518 )
+#define _USB_RESET		_SA1111( 0x51c )
+#define _USB_INTERRUPTEST	_SA1111( 0x520 )
+
+#define _USB_EXTENT		(_USB_INTERRUPTEST - _USB_OHCI_OP_BASE + 4)
+
+#if LANGUAGE == C
+
+#define USB_OHCI_OP_BASE	(*((volatile Word *) SA1111_p2v (_USB_OHCI_OP_BASE)))
+#define USB_STATUS		(*((volatile Word *) SA1111_p2v (_USB_STATUS)))
+#define USB_RESET		(*((volatile Word *) SA1111_p2v (_USB_RESET)))
+#define USB_INTERRUPTEST	(*((volatile Word *) SA1111_p2v (_USB_INTERRUPTEST)))
+
+#endif  /* LANGUAGE == C */
+
+#define USB_RESET_FORCEIFRESET	(1 << 0)
+#define USB_RESET_FORCEHCRESET	(1 << 1)
+#define USB_RESET_CLKGENRESET	(1 << 2)
+#define USB_RESET_SIMSCALEDOWN	(1 << 3)
+#define USB_RESET_USBINTTEST	(1 << 4)
+#define USB_RESET_SLEEPSTBYEN	(1 << 5)
+#define USB_RESET_PWRSENSELOW	(1 << 6)
+#define USB_RESET_PWRCTRLLOW	(1 << 7)
 
 /*
  * Serial Audio Controller
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/arch-sa1100/adsbitsy.h linux/include/asm-arm/arch-sa1100/adsbitsy.h
--- v2.4.12/linux/include/asm-arm/arch-sa1100/adsbitsy.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/arch-sa1100/adsbitsy.h	Thu Oct 11 09:04:57 2001
@@ -0,0 +1,14 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/adsbitsy.h
+ *
+ * Created 7/3/01 by Woojung <whuh@applieddata.net>
+ *
+ * This file contains the hardware specific definitions for the
+ * ADS Bitsy Board
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#error "include <asm/hardware.h> instead"
+#endif
+
+#define	SA1111_BASE		(0x18000000)
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/arch-sa1100/assabet.h linux/include/asm-arm/arch-sa1100/assabet.h
--- v2.4.12/linux/include/asm-arm/arch-sa1100/assabet.h	Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/arch-sa1100/assabet.h	Thu Oct 11 09:04:57 2001
@@ -38,7 +38,7 @@
 #define BCR_DB1111 \
 	(BCR_SPK_OFF  | BCR_QMUTE     | BCR_LED_GREEN  | BCR_LED_RED   | \
 	 BCR_RS232EN  | BCR_LCD_12RGB | BCR_CF_BUS_OFF | BCR_STEREO_LB | \
-	 BCR_IRDA_MD1 | BCR_CF_RST)
+	 BCR_IRDA_MD0 | BCR_CF_RST)
 
 #define BCR_CF_PWR	(1<<0)	/* Compact Flash Power (1 = 3.3v, 0 = off) */
 #define BCR_CF_RST	(1<<1)	/* Compact Flash Reset (1 = power up reset) */
@@ -183,6 +183,10 @@
 #define NCR_A1VPP		(1<<6)
 
 #ifndef __ASSEMBLY__
+#ifdef CONFIG_ASSABET_NEPONSET
 #define machine_has_neponset()  ((SCR_value & SCR_SA1111) == 0)
+#else
+#define machine_has_neponset()	(0)
+#endif
 #endif
 
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/arch-sa1100/bitsy.h linux/include/asm-arm/arch-sa1100/bitsy.h
--- v2.4.12/linux/include/asm-arm/arch-sa1100/bitsy.h	Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/arch-sa1100/bitsy.h	Wed Dec 31 16:00:00 1969
@@ -1,81 +0,0 @@
-/*
-*
-* Definitions for H3600 Handheld Computer
-*
-* Copyright 2000 Compaq Computer Corporation.
-*
-* Use consistent with the GNU GPL is permitted,
-* provided that this copyright notice is
-* preserved in its entirety in all copies and derived works.
-*
-* COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
-* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
-* FITNESS FOR ANY PARTICULAR PURPOSE.
-*
-* Author: Jamey Hicks.
-*
-*/
-
-#ifndef _INCLUDE_BITSY_H_
-#define _INCLUDE_BITSY_H_
-
-#define GPIO_BITSY_NPOWER_BUTTON	GPIO_GPIO (0)
-#define GPIO_BITSY_ACTION_BUTTON	GPIO_GPIO (18)
-
-#define GPIO_BITSY_PCMCIA_CD0		GPIO_GPIO (17)
-#define GPIO_BITSY_PCMCIA_CD1		GPIO_GPIO (10)
-#define GPIO_BITSY_PCMCIA_IRQ0		GPIO_GPIO (21)
-#define GPIO_BITSY_PCMCIA_IRQ1		GPIO_GPIO (11)
-
-/* audio sample rate clock generator */
-#define GPIO_BITSY_CLK_SET0		GPIO_GPIO (12)
-#define GPIO_BITSY_CLK_SET1		GPIO_GPIO (13)
-
-/* UDA1341 L3 Interface */
-#define GPIO_BITSY_L3_DATA		GPIO_GPIO (14)
-#define GPIO_BITSY_L3_CLOCK		GPIO_GPIO (16)
-#define GPIO_BITSY_L3_MODE		GPIO_GPIO (15)
-
-#define GPIO_BITSY_OPT_LOCK		GPIO_GPIO (22)
-#define GPIO_BITSY_OPT_IRQ		GPIO_GPIO (24)
-#define GPIO_BITSY_OPT_DET		GPIO_GPIO (27)
-
-#define GPIO_BITSY_COM_DCD		GPIO_GPIO (23)
-#define GPIO_BITSY_COM_CTS		GPIO_GPIO (25)
-#define GPIO_BITSY_COM_RTS		GPIO_GPIO (26)
-
-#define IRQ_GPIO_BITSY_NPOWER_BUTTON    IRQ_GPIO0
-#define IRQ_GPIO_BITSY_ACTION_BUTTON    IRQ_GPIO18
-#define IRQ_GPIO_BITSY_PCMCIA_CD0	IRQ_GPIO17
-#define IRQ_GPIO_BITSY_PCMCIA_CD1	IRQ_GPIO10
-#define IRQ_GPIO_BITSY_PCMCIA_IRQ0	IRQ_GPIO21
-#define IRQ_GPIO_BITSY_PCMCIA_IRQ1	IRQ_GPIO11
-#define IRQ_GPIO_BITSY_OPT_IRQ		IRQ_GPIO24
-#define IRQ_GPIO_BITSY_OPT_DET		IRQ_GPIO27
-#define IRQ_GPIO_BITSY_COM_DCD          IRQ_GPIO23
-#define IRQ_GPIO_BITSY_COM_CTS          IRQ_GPIO25
-
-#define EGPIO_BITSY_VPP_ON		(1 << 0)
-#define EGPIO_BITSY_CARD_RESET		(1 << 1)  /* reset the attached pcmcia/compactflash card.  active high. */
-#define EGPIO_BITSY_OPT_RESET		(1 << 2)  /* reset the attached option pack.  active high. */
-#define EGPIO_BITSY_CODEC_NRESET	(1 << 3)  /* reset the onboard UDA1341.  active low. */
-#define EGPIO_BITSY_OPT_NVRAM_ON	(1 << 4)  /* apply power to optionpack nvram, active high. */
-#define EGPIO_BITSY_OPT_ON		(1 << 5)  /* full power to option pack.  active high. */
-#define EGPIO_BITSY_LCD_ON       	(1 << 6)  /* enable 3.3V to LCD.  active high. */
-#define EGPIO_BITSY_RS232_ON		(1 << 7)  /* UART3 transceiver force on.  Active high. */
-#define EGPIO_BITSY_LCD_PCI		(1 << 8)  /* LCD control IC enable.  active high. */
-#define EGPIO_BITSY_IR_ON		(1 << 9)  /* apply power to IR module.  active high. */
-#define EGPIO_BITSY_AUD_AMP_ON		(1 << 10) /* apply power to audio power amp.  active high. */
-#define EGPIO_BITSY_AUD_PWR_ON		(1 << 11) /* apply poewr to reset of audio circuit.  active high. */
-#define EGPIO_BITSY_QMUTE		(1 << 12) /* mute control for onboard UDA1341.  active high. */
-#define EGPIO_BITSY_IR_FSEL		(1 << 13) /* IR speed select: 1->fast, 0->slow */
-#define EGPIO_BITSY_LCD_5V_ON		(1 << 14) /* enable 5V to LCD. active high. */
-#define EGPIO_BITSY_LVDD_ON		(1 << 15) /* enable 9V and -6.5V to LCD. */
-
-#ifndef __ASSEMBLY__
-#define BITSY_EGPIO	(*(volatile int *)0xf0000000)
-extern void clr_bitsy_egpio(unsigned long x);
-extern void set_bitsy_egpio(unsigned long x);
-#endif
-
-#endif
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/arch-sa1100/dma.h linux/include/asm-arm/arch-sa1100/dma.h
--- v2.4.12/linux/include/asm-arm/arch-sa1100/dma.h	Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/arch-sa1100/dma.h	Thu Oct 11 09:04:57 2001
@@ -109,8 +109,13 @@
 static inline void
 __arch_adjust_zones(int node, unsigned long *size, unsigned long *holes)
 {
-	size[1] = size[0] - 256;
-	size[0] = 256;
+	unsigned int sz = 256;
+
+	if (node != 0)
+		sz = 0;
+
+	size[1] = size[0] - sz;
+	size[0] = sz;
 }
 
 #define arch_adjust_zones(node,size,holes) __arch_adjust_zones(node,size,holes)
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/arch-sa1100/graphicsmaster.h linux/include/asm-arm/arch-sa1100/graphicsmaster.h
--- v2.4.12/linux/include/asm-arm/arch-sa1100/graphicsmaster.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/arch-sa1100/graphicsmaster.h	Thu Oct 11 09:04:57 2001
@@ -0,0 +1,66 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/graphicsmaster.h
+ *
+ * Created 2000/12/18 by Woojung Huh <whuh@applieddata.net>
+ *
+ * This file comes from graphicsclient.h of Nicolas Pitre <nico@cam.org>
+ *
+ * This file contains the hardware specific definitions for the
+ * ADS GraphicsMaster
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#error "include <asm/hardware.h> instead"
+#endif
+
+#define ADS_CPLD_BASE		(0x10000000)
+#define ADS_p2v( x )		((x) - ADS_CPLD_BASE + 0xf0000000)
+#define ADS_v2p( x )		((x) - 0xf0000000 + ADS_CPLD_BASE)
+
+
+#define _ADS_SW_SWITCHES	0x10060000	/* Software Switches */
+
+/* Extra IRQ Controller */
+#define _ADS_INT_ST1		0x10080000	/* IRQ Status #1 */
+#define _ADS_INT_ST2		0x10080004	/* IRQ Status #2 */
+#define _ADS_INT_EN1		0x10080008	/* IRQ Enable #1 */
+#define _ADS_INT_EN2		0x1008000c	/* IRQ Enable #2 */
+#define _ADS_DCR			0x10080018	/* Discrete Control Reg */
+
+/* Discrete Controller (AVR:Atmel AT90LS8535) */
+#define _ADS_AVR_REG		0x10080018
+
+/* On-Board Ethernet */
+#define _ADS_ETHERNET		0x100e0000	/* Ethernet */
+
+/* On-Board Quad UART 16C554 */
+#define	ADS_QUAD_UART1		0x10100000
+#define	ADS_QUAD_UART2		0x10120000
+#define	ADS_QUAD_UART3		0x10140000
+#define	ADS_QUAD_UART4		0x10160000
+
+/* LEDs */
+#define ADS_LED0	GPIO_GPIO20		/* on-board Green */
+#define ADS_LED1	GPIO_GPIO25		/* on-board Yellow */
+#define ADS_LED2	GPIO_GPIO26		/* on-board Red */
+
+/* DCR */
+#define DCR_AVR_RESET		0x01
+#define DCR_SA1111_RESET	0x02
+#define	DCR_BACKLITE_ON		0x04
+
+/* Virtual register addresses */
+
+#ifndef __ASSEMBLY__
+#define ADS_INT_ST1	(*((volatile u_char *) ADS_p2v(_ADS_INT_ST1)))
+#define ADS_INT_ST2	(*((volatile u_char *) ADS_p2v(_ADS_INT_ST2)))
+#define ADS_INT_EN1	(*((volatile u_char *) ADS_p2v(_ADS_INT_EN1)))
+#define ADS_INT_EN2	(*((volatile u_char *) ADS_p2v(_ADS_INT_EN2)))
+#define ADS_ETHERNET	((int) ADS_p2v(_ADS_ETHERNET))
+#define ADS_AVR_REG	(*((volatile u_char *) ADS_p2v(_ADS_AVR_REG)))
+#define ADS_DCR		(*((volatile u_char *) ADS_p2v(_ADS_DCR)))
+#endif
+
+#define	SA1111_BASE	(0x18000000)
+
+#include "SA-1111.h"
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/arch-sa1100/h3600.h linux/include/asm-arm/arch-sa1100/h3600.h
--- v2.4.12/linux/include/asm-arm/arch-sa1100/h3600.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/arch-sa1100/h3600.h	Thu Oct 11 09:04:57 2001
@@ -0,0 +1,81 @@
+/*
+*
+* Definitions for H3600 Handheld Computer
+*
+* Copyright 2000 Compaq Computer Corporation.
+*
+* Use consistent with the GNU GPL is permitted,
+* provided that this copyright notice is
+* preserved in its entirety in all copies and derived works.
+*
+* COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
+* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
+* FITNESS FOR ANY PARTICULAR PURPOSE.
+*
+* Author: Jamey Hicks.
+*
+*/
+
+#ifndef _INCLUDE_H3600_H_
+#define _INCLUDE_H3600_H_
+
+#define GPIO_H3600_NPOWER_BUTTON	GPIO_GPIO (0)
+#define GPIO_H3600_ACTION_BUTTON	GPIO_GPIO (18)
+
+#define GPIO_H3600_PCMCIA_CD0		GPIO_GPIO (17)
+#define GPIO_H3600_PCMCIA_CD1		GPIO_GPIO (10)
+#define GPIO_H3600_PCMCIA_IRQ0		GPIO_GPIO (21)
+#define GPIO_H3600_PCMCIA_IRQ1		GPIO_GPIO (11)
+
+/* audio sample rate clock generator */
+#define GPIO_H3600_CLK_SET0		GPIO_GPIO (12)
+#define GPIO_H3600_CLK_SET1		GPIO_GPIO (13)
+
+/* UDA1341 L3 Interface */
+#define GPIO_H3600_L3_DATA		GPIO_GPIO (14)
+#define GPIO_H3600_L3_CLOCK		GPIO_GPIO (16)
+#define GPIO_H3600_L3_MODE		GPIO_GPIO (15)
+
+#define GPIO_H3600_OPT_LOCK		GPIO_GPIO (22)
+#define GPIO_H3600_OPT_IRQ		GPIO_GPIO (24)
+#define GPIO_H3600_OPT_DET		GPIO_GPIO (27)
+
+#define GPIO_H3600_COM_DCD		GPIO_GPIO (23)
+#define GPIO_H3600_COM_CTS		GPIO_GPIO (25)
+#define GPIO_H3600_COM_RTS		GPIO_GPIO (26)
+
+#define IRQ_GPIO_H3600_NPOWER_BUTTON    IRQ_GPIO0
+#define IRQ_GPIO_H3600_ACTION_BUTTON    IRQ_GPIO18
+#define IRQ_GPIO_H3600_PCMCIA_CD0	IRQ_GPIO17
+#define IRQ_GPIO_H3600_PCMCIA_CD1	IRQ_GPIO10
+#define IRQ_GPIO_H3600_PCMCIA_IRQ0	IRQ_GPIO21
+#define IRQ_GPIO_H3600_PCMCIA_IRQ1	IRQ_GPIO11
+#define IRQ_GPIO_H3600_OPT_IRQ		IRQ_GPIO24
+#define IRQ_GPIO_H3600_OPT_DET		IRQ_GPIO27
+#define IRQ_GPIO_H3600_COM_DCD          IRQ_GPIO23
+#define IRQ_GPIO_H3600_COM_CTS          IRQ_GPIO25
+
+#define EGPIO_H3600_VPP_ON		(1 << 0)
+#define EGPIO_H3600_CARD_RESET		(1 << 1)  /* reset the attached pcmcia/compactflash card.  active high. */
+#define EGPIO_H3600_OPT_RESET		(1 << 2)  /* reset the attached option pack.  active high. */
+#define EGPIO_H3600_CODEC_NRESET	(1 << 3)  /* reset the onboard UDA1341.  active low. */
+#define EGPIO_H3600_OPT_NVRAM_ON	(1 << 4)  /* apply power to optionpack nvram, active high. */
+#define EGPIO_H3600_OPT_ON		(1 << 5)  /* full power to option pack.  active high. */
+#define EGPIO_H3600_LCD_ON       	(1 << 6)  /* enable 3.3V to LCD.  active high. */
+#define EGPIO_H3600_RS232_ON		(1 << 7)  /* UART3 transceiver force on.  Active high. */
+#define EGPIO_H3600_LCD_PCI		(1 << 8)  /* LCD control IC enable.  active high. */
+#define EGPIO_H3600_IR_ON		(1 << 9)  /* apply power to IR module.  active high. */
+#define EGPIO_H3600_AUD_AMP_ON		(1 << 10) /* apply power to audio power amp.  active high. */
+#define EGPIO_H3600_AUD_PWR_ON		(1 << 11) /* apply poewr to reset of audio circuit.  active high. */
+#define EGPIO_H3600_QMUTE		(1 << 12) /* mute control for onboard UDA1341.  active high. */
+#define EGPIO_H3600_IR_FSEL		(1 << 13) /* IR speed select: 1->fast, 0->slow */
+#define EGPIO_H3600_LCD_5V_ON		(1 << 14) /* enable 5V to LCD. active high. */
+#define EGPIO_H3600_LVDD_ON		(1 << 15) /* enable 9V and -6.5V to LCD. */
+
+#ifndef __ASSEMBLY__
+#define H3600_EGPIO	(*(volatile int *)0xf0000000)
+extern void clr_h3600_egpio(unsigned long x);
+extern void set_h3600_egpio(unsigned long x);
+#endif
+
+#endif
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/arch-sa1100/hardware.h linux/include/asm-arm/arch-sa1100/hardware.h
--- v2.4.12/linux/include/asm-arm/arch-sa1100/hardware.h	Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/arch-sa1100/hardware.h	Thu Oct 11 09:04:57 2001
@@ -122,8 +122,8 @@
 #include "empeg.h"
 #endif
 
-#ifdef CONFIG_SA1100_BITSY
-#include "bitsy.h"
+#ifdef CONFIG_SA1100_H3600
+#include "h3600.h"
 #endif
 
 #ifdef CONFIG_SA1100_ITSY
@@ -152,6 +152,14 @@
 
 #ifdef CONFIG_SA1100_SIMPAD
 #include "simpad.h"
+#endif
+
+#if defined(CONFIG_SA1100_GRAPHICSMASTER)
+#include "graphicsmaster.h"
+#endif
+
+#if defined(CONFIG_SA1100_ADSBITSY)
+#include "adsbitsy.h"
 #endif
 
 #ifdef CONFIG_SA1101
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/arch-sa1100/irqs.h linux/include/asm-arm/arch-sa1100/irqs.h
--- v2.4.12/linux/include/asm-arm/arch-sa1100/irqs.h	Thu Feb  8 16:32:44 2001
+++ linux/include/asm-arm/arch-sa1100/irqs.h	Thu Oct 11 09:04:57 2001
@@ -72,7 +72,7 @@
 #define	NR_IRQS		(IRQ_GPIO27 + 1)
 
 
-#if defined(CONFIG_SA1100_GRAPHICSCLIENT)
+#if defined(CONFIG_SA1100_GRAPHICSCLIENT) || defined(CONFIG_SA1100_GRAPHICSMASTER)
 #define ADS_EXT_IRQ(x)	(IRQ_GPIO27 + 1 + (x))
 #undef NR_IRQS
 #define NR_IRQS		(ADS_EXT_IRQ(15) + 1)
@@ -81,7 +81,11 @@
 
 #if defined(CONFIG_SA1111)
 
+#if defined(CONFIG_SA1100_GRAPHICSMASTER)
+#define	SA1111_IRQ(x)	(ADS_EXT_IRQ(15) + 1 + 1 + (x))
+#else
 #define SA1111_IRQ(x)	(IRQ_GPIO27 + 1 + (x))
+#endif
 
 #define GPAIN0		SA1111_IRQ(0)
 #define GPAIN1		SA1111_IRQ(1)
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/arch-sa1100/keyboard.h linux/include/asm-arm/arch-sa1100/keyboard.h
--- v2.4.12/linux/include/asm-arm/arch-sa1100/keyboard.h	Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/arch-sa1100/keyboard.h	Thu Oct 11 09:04:57 2001
@@ -8,11 +8,37 @@
 #define _SA1100_KEYBOARD_H
 
 #include <linux/config.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
 
+extern struct kbd_ops_struct *kbd_ops;
 
-// #ifdef CONFIG_SA1100_BRUTUS
-/* need fixing... */
-#if 0
+#define kbd_disable_irq()	do { } while(0);
+#define kbd_enable_irq()	do { } while(0);
+
+
+/*
+ * SA1111 keyboard driver
+ */
+extern void sa1111_kbd_init_hw(void);
+
+/*
+ * GraphicsClient keyboard driver
+ */
+extern void gc_kbd_init_hw(void);
+
+static inline void kbd_init_hw(void)
+{
+	if (machine_is_assabet() && machine_has_neponset())
+		sa1111_kbd_init_hw();
+
+	if (machine_is_graphicsclient())
+		gc_kbd_init_hw();
+}
+
+
+
+#if 0	 /* Brutus needs fixing */
 
 extern int Brutus_kbd_translate(unsigned char scancode, unsigned char *keycode,
 			   char raw_mode);
@@ -34,7 +60,9 @@
 
 #define SYSRQ_KEY 0x54
 
-#elif CONFIG_SA1100_GRAPHICSCLIENT
+#elif 0 // CONFIG_SA1100_GRAPHICSCLIENT
+extern int gc_kbd_setkeycode(unsigned int scancode, unsigned int keycode);
+extern int gc_kbd_getkeycode(unsigned int scancode);
 extern int gc_kbd_translate(unsigned char scancode, unsigned char *keycode, char raw_mode);
 extern void gc_kbd_leds(unsigned char leds);
 extern void gc_kbd_init_hw(void);
@@ -42,137 +70,17 @@
 extern void gc_kbd_disable_irq(void);
 extern unsigned char gc_kbd_sysrq_xlate[128];
 
-#define kbd_setkeycode(x...)    (-ENOSYS)
-#define kbd_getkeycode(x...)    (-ENOSYS)
+#define kbd_setkeycode(x...)    gc_kbd_setkeycode	//(-ENOSYS)
+#define kbd_getkeycode(x...)    gc_kbd_getkeycode	//(-ENOSYS)
 #define kbd_translate           gc_kbd_translate
 #define kbd_unexpected_up(x...) (1)
 #define kbd_leds                gc_kbd_leds
 #define kbd_init_hw             gc_kbd_init_hw
 #define kbd_enable_irq          gc_kbd_enable_irq
 #define kbd_disable_irq         gc_kbd_disable_irq
-#define kbd_sysrq_xlate         gc_kbd_sysrq_xlate
-
-#elif CONFIG_SA1100_BITSY
-
-#define kbd_setkeycode(x...)    (-ENOSYS)
-#define kbd_getkeycode(x...)    (-ENOSYS)
-#define kbd_translate(sc_,kc_,rm_)	((*(kc_)=(sc_)),1)
-#define kbd_unexpected_up(x...) (1)
-#define kbd_leds(x...)		do { } while (0)
-#define kbd_init_hw(x...)	do { } while (0)
-#define kbd_enable_irq(x...)	do { } while (0)
-#define kbd_disable_irq(x...)	do { } while (0)
-
-#elif 0 //defined(CONFIG_SA1111)   /*@@@@@*/
-
-#define KEYBOARD_IRQ           TPRXINT
-#define DISABLE_KBD_DURING_INTERRUPTS  0
-
-/* redefine some macros */
-#ifdef KBD_DATA_REG
-#undef KBD_DATA_REG
-#endif
-#ifdef KBD_STATUS_REG
-#undef KBD_STATUS_REG
-#endif
-#ifdef KBD_CNTL_REG
-#undef KBD_CNTL_REG
-#endif
-#define KBD_DATA_REG           KBDDATA
-#define KBD_STATUS_REG         KBDSTAT
-#define KBD_CNTL_REG           KBDCR
-
-extern int sa1111_setkeycode(unsigned int scancode, unsigned int keycode);
-extern int sa1111_getkeycode(unsigned int scancode);
-extern int sa1111_translate(unsigned char scancode, unsigned char *keycode,
-				char raw_mode);
-extern char sa1111_unexpected_up(unsigned char keycode);
-extern void sa1111_leds(unsigned char leds);
-extern void sa1111_init_hw(void);
-extern unsigned char sa1111_sysrq_xlate[128];
-
-#define kbd_setkeycode		sa1111_setkeycode
-#define kbd_getkeycode		sa1111_getkeycode
-#define kbd_translate		sa1111_translate
-#define kbd_unexpected_up	sa1111_unexpected_up
-#define kbd_leds		sa1111_leds
-#define kbd_init_hw		sa1111_init_hw
-#define kbd_sysrq_xlate		sa1111_sysrq_xlate
-#define kbd_disable_irq(x...)	do{;}while(0)
-#define kbd_enable_irq(x...)	do{;}while(0)
-
-#define SYSRQ_KEY 0x54
-
-/* resource allocation */
-#define kbd_request_region()
-#define kbd_request_irq(handler) request_irq(KEYBOARD_IRQ, handler, 0, \
-					"keyboard", NULL)
-
-/* How to access the keyboard macros on this platform.  */
-#define kbd_read_input()	(*KBDDATA & 0x00ff)
-#define kbd_read_status()	(*KBDSTAT & 0x01ff)
-#define kbd_write_output(val)	(*KBDDATA = (val))
-#define kbd_write_command(val)	(*KBDCR = (val))
-
-/* Some stoneage hardware needs delays after some operations.  */
-#define kbd_pause() do {;} while(0)
-
-/* bit definitions for some registers */
-#define KBD_CR_ENA	(1<<3)
-
-#define KBD_STAT_RXB	(1<<4)
-#define KBD_STAT_RXF	(1<<5)
-#define KBD_STAT_TXB	(1<<6)
-#define KBD_STAT_TXE	(1<<7)
-#define KBD_STAT_STP	(1<<8)
-
-/*
- * Machine specific bits for the PS/2 driver
- */
-
-#define AUX_IRQ		MSRXINT
-
-#define aux_request_irq(hand, dev_id)  \
-		request_irq(AUX_IRQ, hand, SA_SHIRQ, "PS/2 Mouse", dev_id)
-#define aux_free_irq(dev_id) free_irq(AUX_IRQ, dev_id)
-
-/* How to access the mouse macros on this platform.  */
-#define mse_read_input()	(*MSEDATA & 0x00ff)
-#define mse_read_status()	(*MSESTAT & 0x01ff)
-#define mse_write_output(val)	(*MSEDATA = (val))
-#define mse_write_command(val)	(*MSECR = (val))
-
-/* bit definitions for some registers */
-#define MSE_CR_ENA	(1<<3)
-
-#define MSE_STAT_RXB	(1<<4)
-#define MSE_STAT_RXF	(1<<5)
-#define MSE_STAT_TXB	(1<<6)
-#define MSE_STAT_TXE	(1<<7)
-#define MSE_STAT_STP	(1<<8)
-
-
-#else
-
-/* dummy i.e. no real keyboard */
-#define kbd_setkeycode(x...)	(-ENOSYS)
-#define kbd_getkeycode(x...)	(-ENOSYS)
-#define kbd_translate(x...)	(0)
-#define kbd_unexpected_up(x...)	(1)
-#define kbd_leds(x...)		do {;} while (0)
-#define kbd_init_hw(x...)	do {;} while (0)
-#define kbd_enable_irq(x...)	do {;} while (0)
-#define kbd_disable_irq(x...)	do {;} while (0)
+#define kbd_sysrq_xlate         (1)
 
 #endif
-
-
-/* needed if MAGIC_SYSRQ is enabled for serial console */
-#ifndef SYSRQ_KEY
-#define SYSRQ_KEY		((unsigned char)(-1))
-#define kbd_sysrq_xlate         ((unsigned char *)NULL)
-#endif
-
 
 #endif  /* _SA1100_KEYBOARD_H */
 
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/arch-sa1100/pangolin.h linux/include/asm-arm/arch-sa1100/pangolin.h
--- v2.4.12/linux/include/asm-arm/arch-sa1100/pangolin.h	Thu Feb  8 16:32:44 2001
+++ linux/include/asm-arm/arch-sa1100/pangolin.h	Thu Oct 11 09:04:57 2001
@@ -11,6 +11,7 @@
 #error "include <asm/hardware.h> instead"
 #endif
 
+#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
 
 /* GPIOs for which the generic definition doesn't say much */
 #define GPIO_CF_BUS_ON		GPIO_GPIO (3)
@@ -20,3 +21,41 @@
 
 #define IRQ_GPIO_CF_IRQ		IRQ_GPIO21
 #define IRQ_GPIO_CF_CD		IRQ_GPIO22
+
+#else
+/*
+ *  These definitions are for PCMCIA/IDE card
+ *
+ *  PSKTSEL = 0 ---> PCMCIA
+ *  PCMCIA_RESET = GPIO_7        ( output )( 0: normal   1: reset )
+ *  PCMCIA_IRQ = GPIO_24         ( input )
+ *  PCMCIA_CD = GPIO_25          ( input )
+ *
+ *  PSKTSEL = 1 ---> IDE port
+ *  IDE_IRQ = GPIO_23            ( input )
+ *
+ *  !!WARNING!!
+ *  When the PCMCIA/IDE card is inserted, the CF slot
+ *  should not have any card inserted!!
+ *
+ */
+
+#define GPIO_PCMCIA_RESET       GPIO_GPIO (7)
+#define GPIO_PCMCIA_IRQ         GPIO_GPIO (24)
+#define GPIO_PCMCIA_CD          GPIO_GPIO (25)
+#define GPIO_IDE_IRQ            GPIO_GPIO (8)
+
+#define IRQ_PCMCIA_IRQ          IRQ_GPIO24
+#define IRQ_PCMCIA_CD           IRQ_GPIO25
+#define IRQ_IDE_IRQ             IRQ_GPIO8
+
+#endif
+
+/*
+ * On board LAN chip
+ */
+#define PANGOLIN_LAN_ADDR      0x32000000
+#define PANGOLIN_LAN_RESET     GPIO_GPIO (8)
+#define PANGOLIN_LAN_IRQ       GPIO_GPIO (26)
+#define PANGOLIN_IRQ_LAN_IRQ   IRQ_GPIO26
+
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/arch-sa1100/uncompress.h linux/include/asm-arm/arch-sa1100/uncompress.h
--- v2.4.12/linux/include/asm-arm/arch-sa1100/uncompress.h	Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/arch-sa1100/uncompress.h	Thu Oct 11 09:04:57 2001
@@ -3,23 +3,16 @@
  *
  * (C) 1999 Nicolas Pitre <nico@cam.org>
  *
- * Reorganised to use machine_is_*() macros.
+ * Reorganised to be machine independent.
  */
 
 #include "hardware.h"
 
-#include <asm/mach-types.h>
-
-/* Assabet's Status Control "Register" */
-unsigned long SCR_value;
-
-/* sa1100_setup() will perform any special initialization for UART, etc. */
-extern void sa1100_setup( int arch_id );
-#define arch_decomp_setup()	sa1100_setup(arch_id)
-
 /*
  * The following code assumes the serial port has already been
- * initialized by the bootloader or such...
+ * initialized by the bootloader.  We search for the first enabled
+ * port in the most probable order.  If you didn't setup a port in
+ * your bootloader then nothing will appear (which might be desired).
  */
 
 #define UART(x)		(*(volatile unsigned long *)(serial_port + (x)))
@@ -28,22 +21,15 @@
 {
 	unsigned long serial_port;
 
-	if (machine_is_assabet()) {
-		if( machine_has_neponset() )
-			serial_port = _Ser3UTCR0;
-		else
-			serial_port = _Ser1UTCR0;
-	} else if (machine_is_brutus()||machine_is_nanoengine() ||
-		   machine_is_pangolin() || machine_is_freebird() ||
-		   machine_is_pfs168() || machine_is_flexanet())
-		serial_port = _Ser1UTCR0;
-	else if (machine_is_empeg() || machine_is_bitsy() ||
-		 machine_is_victor() || machine_is_lart() ||
-		 machine_is_sherman() || machine_is_yopy() ||
-		 machine_is_huw_webpanel() || machine_is_itsy() )
+	do {
 		serial_port = _Ser3UTCR0;
-	else
+		if (UART(UTCR3) & UTCR3_TXE) break;
+		serial_port = _Ser1UTCR0;
+		if (UART(UTCR3) & UTCR3_TXE) break;
+		serial_port = _Ser2UTCR0;
+		if (UART(UTCR3) & UTCR3_TXE) break;
 		return;
+	} while (0);
 
 	for (; *s; s++) {
 		/* wait for space in the UART's transmiter */
@@ -63,4 +49,5 @@
 /*
  * Nothing to do for these
  */
+#define arch_decomp_setup()
 #define arch_decomp_wdog()
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/atomic.h linux/include/asm-arm/atomic.h
--- v2.4.12/linux/include/asm-arm/atomic.h	Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/atomic.h	Thu Oct 11 09:04:57 2001
@@ -22,11 +22,7 @@
 #error SMP not supported
 #endif
 
-#ifdef CONFIG_ARCH_CO285
 typedef struct { volatile int counter; } atomic_t;
-#else
-typedef struct { int counter; } atomic_t;
-#endif
 
 #define ATOMIC_INIT(i)	{ (i) }
 
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/cpu-multi32.h linux/include/asm-arm/cpu-multi32.h
--- v2.4.12/linux/include/asm-arm/cpu-multi32.h	Mon Sep 18 15:15:23 2000
+++ linux/include/asm-arm/cpu-multi32.h	Thu Oct 11 09:04:57 2001
@@ -9,6 +9,7 @@
  */
 #ifndef __ASSEMBLY__
 
+#include <asm/memory.h>
 #include <asm/page.h>
 
 /* forward-declare task_struct */
@@ -155,5 +156,14 @@
 #define cpu_set_pte(ptep, pte)			processor.pgtable.set_pte(ptep, pte)
 
 #define cpu_switch_mm(pgd,tsk)			cpu_set_pgd(__virt_to_phys((unsigned long)(pgd)))
+
+#define cpu_get_pgd()	\
+	({						\
+		unsigned long pg;			\
+		__asm__("mrc p15, 0, %0, c2, c0, 0"	\
+			 : "=r" (pg));			\
+		pg &= ~0x3fff;				\
+		(pgd_t *)phys_to_virt(pg);		\
+	})
 
 #endif
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/cpu-single.h linux/include/asm-arm/cpu-single.h
--- v2.4.12/linux/include/asm-arm/cpu-single.h	Mon Sep 18 15:15:23 2000
+++ linux/include/asm-arm/cpu-single.h	Thu Oct 11 09:04:57 2001
@@ -51,6 +51,7 @@
 
 #ifndef __ASSEMBLY__
 
+#include <asm/memory.h>
 #include <asm/page.h>
 
 /* forward declare task_struct */
@@ -85,5 +86,14 @@
 extern volatile void cpu_reset(unsigned long addr);
 
 #define cpu_switch_mm(pgd,tsk) cpu_set_pgd(__virt_to_phys((unsigned long)(pgd)))
+
+#define cpu_get_pgd()	\
+	({						\
+		unsigned long pg;			\
+		__asm__("mrc p15, 0, %0, c2, c0, 0"	\
+			 : "=r" (pg));			\
+		pg &= ~0x3fff;				\
+		(pgd_t *)phys_to_virt(pg);		\
+	})
 
 #endif
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/hardirq.h linux/include/asm-arm/hardirq.h
--- v2.4.12/linux/include/asm-arm/hardirq.h	Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/hardirq.h	Thu Oct 11 09:04:57 2001
@@ -2,6 +2,7 @@
 #define __ASM_HARDIRQ_H
 
 #include <linux/config.h>
+#include <linux/cache.h>
 #include <linux/threads.h>
 
 /* softirq.h is sensitive to the offsets of these fields */
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/hardware/pci_v3.h linux/include/asm-arm/hardware/pci_v3.h
--- v2.4.12/linux/include/asm-arm/hardware/pci_v3.h	Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/hardware/pci_v3.h	Thu Oct 11 09:04:57 2001
@@ -102,6 +102,10 @@
 
 /*  PCI_CFG bits
  */
+#define V3_PCI_CFG_M_I2O_EN		(1 << 15)
+#define V3_PCI_CFG_M_IO_REG_DIS		(1 << 14)
+#define V3_PCI_CFG_M_IO_DIS		(1 << 13)
+#define V3_PCI_CFG_M_EN3V		(1 << 12)
 #define V3_PCI_CFG_M_RETRY_EN           (1 << 10)
 #define V3_PCI_CFG_M_AD_LOW1            (1 << 9)
 #define V3_PCI_CFG_M_AD_LOW0            (1 << 8)
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/io.h linux/include/asm-arm/io.h
--- v2.4.12/linux/include/asm-arm/io.h	Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/io.h	Thu Oct 11 09:04:57 2001
@@ -72,18 +72,22 @@
 #include <asm/arch/io.h>
 
 /*
- * IO definitions.  We define {out,in,outs,ins}[bwl] if __io is
- * defined by the machine.  Otherwise, these definitions are left
- * for the machine specific header files to pick up.
+ * IO definitions.  We define {out,in,outs,ins}[bwl] if __io is defined
+ * by the machine.  Otherwise, these definitions are left for the machine
+ * specific header files to pick up.
+ *
+ * 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.
  */
 #ifdef __io
 #define outb(v,p)			__raw_writeb(v,__io(p))
 #define outw(v,p)			__raw_writew(v,__io(p))
 #define outl(v,p)			__raw_writel(v,__io(p))
 
-#define inb(p)				__raw_readb(__io(p))
-#define inw(p)				__raw_readw(__io(p))
-#define inl(p)				__raw_readl(__io(p))
+#define inb(p)		({ unsigned int __v = __raw_readb(__io(p)); __v; })
+#define inw(p)		({ unsigned int __v = __raw_readw(__io(p)); __v; })
+#define inl(p)		({ unsigned int __v = __raw_readl(__io(p)); __v; })
 
 #define outsb(p,d,l)			__raw_writesb(__io(p),d,l)
 #define outsw(p,d,l)			__raw_writesw(__io(p),d,l)
@@ -168,9 +172,10 @@
  */
 #ifdef __mem_pci
 
-#define readb(addr)			__raw_readb(__mem_pci(addr))
-#define readw(addr)			__raw_readw(__mem_pci(addr))
-#define readl(addr)			__raw_readl(__mem_pci(addr))
+#define readb(addr) ({ unsigned int __v = __raw_readb(__mem_pci(addr)); __v; })
+#define readw(addr) ({ unsigned int __v = __raw_readw(__mem_pci(addr)); __v; })
+#define readl(addr) ({ unsigned int __v = __raw_readl(__mem_pci(addr)); __v; })
+
 #define writeb(val,addr)		__raw_writeb(val,__mem_pci(addr))
 #define writew(val,addr)		__raw_writew(val,__mem_pci(addr))
 #define writel(val,addr)		__raw_writel(val,__mem_pci(addr))
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/mach/arch.h linux/include/asm-arm/mach/arch.h
--- v2.4.12/linux/include/asm-arm/mach/arch.h	Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/mach/arch.h	Thu Oct 11 09:04:57 2001
@@ -27,7 +27,8 @@
 	unsigned int		nr;		/* architecture number	*/
 	unsigned int		phys_ram;	/* start of physical ram */
 	unsigned int		phys_io;	/* start of physical io	*/
-	unsigned int		virt_io;	/* start of virtual io	*/
+	unsigned int		io_pg_offst;	/* byte offset for io 
+						 * page tabe entry	*/
 
 	const char		*name;		/* architecture name	*/
 	unsigned int		param_offset;	/* parameter page	*/
@@ -59,9 +60,9 @@
 #define MAINTAINER(n)
 
 #define BOOT_MEM(_pram,_pio,_vio)		\
-	phys_ram:	_pram,			\
-	phys_io:	_pio,			\
-	virt_io:	_vio,
+	phys_ram:	_pram,	                \
+	phys_io:	_pio,  	                \
+	io_pg_offst:	((_vio)>>18)&0xfffc,
 
 #define BOOT_PARAMS(_params)			\
 	param_offset:	_params,
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/param.h linux/include/asm-arm/param.h
--- v2.4.12/linux/include/asm-arm/param.h	Tue Mar  6 19:44:35 2001
+++ linux/include/asm-arm/param.h	Thu Oct 11 09:04:57 2001
@@ -16,6 +16,9 @@
 #ifndef HZ
 #define HZ 100
 #endif
+#if defined(__KERNEL__) && (HZ == 100)
+#define hz_to_std(a) (a)
+#endif
 
 #ifndef NGROUPS
 #define NGROUPS         32
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/pci.h linux/include/asm-arm/pci.h
--- v2.4.12/linux/include/asm-arm/pci.h	Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/pci.h	Thu Oct 11 09:04:57 2001
@@ -44,7 +44,6 @@
 	consistent_free(vaddr, size, dma_handle);
 }
 
-#if !defined(CONFIG_SA1111)
 /* Map a single buffer of the indicated size for DMA in streaming mode.
  * The 32-bit bus address to use is returned.
  *
@@ -54,6 +53,17 @@
 static inline dma_addr_t
 pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
 {
+#ifdef CONFIG_SA1111
+	extern dma_addr_t sa1111_map_single(struct pci_dev *, void *, size_t, int);
+
+	/*
+	 * for SA1111 these functions are "magic" and relocate buffers.  We
+	 * only need to do these if hwdev is non-null; otherwise we expect
+	 * the buffer to already be suitable for DMA.
+	 */
+	if (hwdev != NULL)
+		return sa1111_map_single(hwdev, ptr, size, direction);
+#endif
 	consistent_sync(ptr, size, direction);
 	return virt_to_bus(ptr);
 }
@@ -68,16 +78,14 @@
 static inline void
 pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction)
 {
+#ifdef CONFIG_SA1111
+	extern void sa1111_unmap_single(struct pci_dev *, dma_addr_t, size_t, int);
+
+	if (hwdev != NULL)
+		sa1111_unmap_single(hwdev, dma_addr, size, direction);
+#endif
 	/* nothing to do */
 }
-#else
-/* for SA1111 these functions are "magic" and relocate buffers */
-extern dma_addr_t pci_map_single(struct pci_dev *hwdev,
-				 void *ptr, size_t size, int direction);
-extern void pci_unmap_single(struct pci_dev *hwdev,
-			     dma_addr_t dma_addr,
-			     size_t size, int direction);
-#endif
 
 /* Map a set of buffers described by scatterlist in streaming
  * mode for DMA.  This is the scather-gather version of the
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/pgtable.h linux/include/asm-arm/pgtable.h
--- v2.4.12/linux/include/asm-arm/pgtable.h	Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/pgtable.h	Thu Oct 11 09:04:57 2001
@@ -175,6 +175,8 @@
 
 #include <asm-generic/pgtable.h>
 
+extern void pgtable_cache_init(void);
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* _ASMARM_PGTABLE_H */
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/processor.h linux/include/asm-arm/processor.h
--- v2.4.12/linux/include/asm-arm/processor.h	Tue Oct  9 17:06:53 2001
+++ linux/include/asm-arm/processor.h	Thu Oct 11 09:04:57 2001
@@ -68,6 +68,13 @@
 	EXTRA_THREAD_STRUCT
 };
 
+#define INIT_MMAP {					\
+	vm_mm:		&init_mm,			\
+	vm_page_prot:	PAGE_SHARED,			\
+	vm_flags:	VM_READ | VM_WRITE | VM_EXEC,	\
+	vm_avl_height:	1,				\
+}
+
 #define INIT_THREAD  {					\
 	refcount:	ATOMIC_INIT(1),			\
 	EXTRA_THREAD_STRUCT_INIT			\
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/setup.h linux/include/asm-arm/setup.h
--- v2.4.12/linux/include/asm-arm/setup.h	Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/setup.h	Thu Oct 11 09:04:57 2001
@@ -126,7 +126,7 @@
 
 struct tag_ramdisk {
 	u32 flags;	/* bit 0 = load, bit 1 = prompt */
-	u32 size;	/* decompressed ramdisk size */
+	u32 size;	/* decompressed ramdisk size in _kilo_ bytes */
 	u32 start;	/* starting block of floppy-based RAM disk image */
 };
 
@@ -135,7 +135,7 @@
 
 struct tag_initrd {
 	u32 start;	/* physical start address */
-	u32 size;	/* size of compressed ramdisk image */
+	u32 size;	/* size of compressed ramdisk image in bytes */
 };
 
 /* board serial number. "64 bits should be enough for everybody" */
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/signal.h linux/include/asm-arm/signal.h
--- v2.4.12/linux/include/asm-arm/signal.h	Thu Nov 18 19:37:03 1999
+++ linux/include/asm-arm/signal.h	Thu Oct 11 09:04:57 2001
@@ -75,13 +75,16 @@
 /*
  * SA_FLAGS values:
  *
- * SA_ONSTACK is not currently supported, but will allow sigaltstack(2).
- * 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_NOCLDSTOP		flag to turn off SIGCHLD when children stop.
+ * SA_NOCLDWAIT		flag on SIGCHLD to inhibit zombies.
+ * SA_SIGINFO		deliver the signal with SIGINFO structs
+ * SA_THIRTYTWO		delivers the signal in 32-bit mode, even if the task 
+ *			is running in 26-bit.
+ * SA_ONSTACK		allows alternate signal stacks (see sigaltstack(2)).
+ * SA_RESTART		flag to get restarting signals (which were the default long ago)
+ * SA_INTERRUPT		is a no-op, but left due to historical reasons. Use the
+ * SA_NODEFER		prevents the current signal from being masked in the handler.
+ * SA_RESETHAND		clears the handler when the signal is delivered.
  *
  * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
  * Unix names RESETHAND and NODEFER respectively.
@@ -89,6 +92,8 @@
 #define SA_NOCLDSTOP	0x00000001
 #define SA_NOCLDWAIT	0x00000002 /* not supported yet */
 #define SA_SIGINFO	0x00000004
+#define SA_THIRTYTWO	0x02000000
+#define SA_RESTORER	0x04000000
 #define SA_ONSTACK	0x08000000
 #define SA_RESTART	0x10000000
 #define SA_NODEFER	0x40000000
@@ -98,9 +103,6 @@
 #define SA_ONESHOT	SA_RESETHAND
 #define SA_INTERRUPT	0x20000000 /* dummy -- ignored */
 
-#define SA_RESTORER	0x04000000
-#define SA_THIRTYTWO	0x02000000 /* deliver signal in 32-bit mode even if
-				      task is running 26 bits. */
 
 /* 
  * sigaltstack controls
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/uaccess.h linux/include/asm-arm/uaccess.h
--- v2.4.12/linux/include/asm-arm/uaccess.h	Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/uaccess.h	Thu Oct 11 09:04:57 2001
@@ -63,11 +63,81 @@
  * error occurs, and leave it unchanged on success.  Note that these
  * versions are void (ie, don't return a value as such).
  */
-#define get_user(x,p)		__get_user_check((x),(p),sizeof(*(p)))
+
+extern int __get_user_1(void *);
+extern int __get_user_2(void *);
+extern int __get_user_4(void *);
+extern int __get_user_8(void *);
+extern int __get_user_bad(void);
+
+#define __get_user_x(__r1,__p,__e,__s,__i...)				\
+	   __asm__ __volatile__ ("bl	__get_user_" #__s		\
+		: "=&r" (__e), "=r" (__r1)				\
+		: "0" (__p)						\
+		: __i)
+
+#define get_user(x,p)							\
+	({								\
+		const register typeof(*(p)) *__p asm("r0") = (p);	\
+		register typeof(*(p)) __r1 asm("r1");			\
+		register int __e asm("r0");				\
+		switch (sizeof(*(p))) {					\
+		case 1:							\
+			__get_user_x(__r1, __p, __e, 1, "lr");		\
+	       		break;						\
+		case 2:							\
+			__get_user_x(__r1, __p, __e, 2, "r2", "lr");	\
+			break;						\
+		case 4:							\
+	       		__get_user_x(__r1, __p, __e, 4, "lr");		\
+			break;						\
+		case 8:							\
+			__get_user_x(__r1, __p, __e, 8, "lr");		\
+	       		break;						\
+		default: __e = __get_user_bad(); break;			\
+		}							\
+		x = __r1;						\
+		__e;							\
+	})
+
 #define __get_user(x,p)		__get_user_nocheck((x),(p),sizeof(*(p)))
 #define __get_user_error(x,p,e)	__get_user_nocheck_error((x),(p),sizeof(*(p)),(e))
 
-#define put_user(x,p)		__put_user_check((__typeof(*(p)))(x),(p),sizeof(*(p)))
+extern int __put_user_1(void *, unsigned int);
+extern int __put_user_2(void *, unsigned int);
+extern int __put_user_4(void *, unsigned int);
+extern int __put_user_8(void *, unsigned long long);
+extern int __put_user_bad(void);
+
+#define __put_user_x(__r1,__p,__e,__s,__i...)				\
+	   __asm__ __volatile__ ("bl	__put_user_" #__s		\
+		: "=&r" (__e)						\
+		: "0" (__p), "r" (__r1)					\
+		: __i)
+
+#define put_user(x,p)							\
+	({								\
+		const register typeof(*(p)) *__p asm("r0") = (p);	\
+		const register typeof(*(p)) __r1 asm("r1") = (x);	\
+		register int __e asm("r0");				\
+		switch (sizeof(*(p))) {					\
+		case 1:							\
+			__put_user_x(__r1, __p, __e, 1, "r2", "lr");	\
+			break;						\
+		case 2:							\
+			__put_user_x(__r1, __p, __e, 2, "r2", "lr");	\
+			break;						\
+		case 4:							\
+			__put_user_x(__r1, __p, __e, 4, "r2", "lr");	\
+			break;						\
+		case 8:							\
+			__put_user_x(__r1, __p, __e, 8, "ip", "lr");	\
+			break;						\
+		default: __e = __put_user_bad(); break;			\
+		}							\
+		__e;							\
+	})
+
 #define __put_user(x,p)		__put_user_nocheck((__typeof(*(p)))(x),(p),sizeof(*(p)))
 #define __put_user_error(x,p,e)	__put_user_nocheck_error((x),(p),sizeof(*(p)),(e))
 
@@ -142,6 +212,7 @@
 /*
  * These are the work horses of the get/put_user functions
  */
+#if 0
 #define __get_user_check(x,ptr,size)					\
 ({									\
 	long __gu_err = -EFAULT, __gu_val = 0;				\
@@ -153,6 +224,7 @@
 	(x) = (__typeof__(*(ptr)))__gu_val;				\
 	__gu_err;							\
 })
+#endif
 
 #define __get_user_nocheck(x,ptr,size)					\
 ({									\
@@ -195,8 +267,6 @@
 	(void) 0;							\
 })
 
-extern long __get_user_bad(void);
-
 #define __get_user_size(x,ptr,size,retval)				\
 do {									\
 	switch (size) {							\
@@ -206,8 +276,6 @@
 	default: (x) = __get_user_bad();				\
 	}								\
 } while (0)
-
-extern long __put_user_bad(void);
 
 #define __put_user_size(x,ptr,size,retval)				\
 do {									\
diff -u --recursive --new-file v2.4.12/linux/include/asm-i386/system.h linux/include/asm-i386/system.h
--- v2.4.12/linux/include/asm-i386/system.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-i386/system.h	Thu Oct 11 13:56:05 2001
@@ -281,10 +281,19 @@
  * I expect future Intel CPU's to have a weaker ordering,
  * but I'd also expect them to finally get their act together
  * and add some real memory barriers if so.
+ *
+ * Some non intel clones support out of order store. wmb() ceases to be a
+ * nop for these.
  */
+ 
 #define mb() 	__asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
 #define rmb()	mb()
+
+#ifdef CONFIG_X86_OOSTORE
+#define wmb() 	__asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
+#else
 #define wmb()	__asm__ __volatile__ ("": : :"memory")
+#endif
 
 #ifdef CONFIG_SMP
 #define smp_mb()	mb()
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/chandev.h linux/include/asm-s390/chandev.h
--- v2.4.12/linux/include/asm-s390/chandev.h	Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390/chandev.h	Thu Oct 11 09:43:38 2001
@@ -139,6 +139,10 @@
  * not operational the previous status is sent in the prevstatus variable.
  * This can be used in cases when the default handling isn't quite adequete
  * e.g. if a ssch is needed to reinitialize long running channel programs.
+ *
+ * This returns the number of devices found or -ENOMEM if the code didn't
+ * have enough memory to allocate the chandev control block
+ * or -EPERM if a duplicate entry is found.
  */
 int chandev_register_and_probe(chandev_probefunc probefunc,
 			       chandev_shutdownfunc shutdownfunc,
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/current.h linux/include/asm-s390/current.h
--- v2.4.12/linux/include/asm-s390/current.h	Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390/current.h	Thu Oct 11 09:43:38 2001
@@ -19,7 +19,7 @@
 {
         struct task_struct *current;
         __asm__("lhi   %0,-8192\n\t"
-                "nr    %0,15"
+                "al    %0,0xc40"
                 : "=&r" (current) : : "cc" );
         return current;
  }
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/dasd.h linux/include/asm-s390/dasd.h
--- v2.4.12/linux/include/asm-s390/dasd.h	Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390/dasd.h	Thu Oct 11 09:43:38 2001
@@ -36,6 +36,7 @@
         unsigned int dasd_io_time2[32];	 /* histogram of time from start to irq */
         unsigned int dasd_io_time2ps[32]; /* histogram of time from start to irq */
         unsigned int dasd_io_time3[32];	 /* histogram of time from irq to end */
+        unsigned int dasd_io_nr_req[32]; /* histogram of # of requests in chanq */
 } dasd_profile_info_t;
 
 /* 
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/debug.h linux/include/asm-s390/debug.h
--- v2.4.12/linux/include/asm-s390/debug.h	Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390/debug.h	Thu Oct 11 09:43:38 2001
@@ -44,6 +44,7 @@
 
 #define DEBUG_MAX_LEVEL            6  /* debug levels range from 0 to 6 */
 #define DEBUG_OFF_LEVEL            -1 /* level where debug is switched off */
+#define DEBUG_FLUSH_ALL            -1 /* parameter to flush all areas */
 #define DEBUG_MAX_VIEWS            10 /* max number of views in proc fs */
 #define DEBUG_MAX_PROCF_LEN        16 /* max length for a proc file name */
 #define DEBUG_DEFAULT_LEVEL        3  /* initial debug level */
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/gdb-stub.h linux/include/asm-s390/gdb-stub.h
--- v2.4.12/linux/include/asm-s390/gdb-stub.h	Fri May 12 11:41:44 2000
+++ linux/include/asm-s390/gdb-stub.h	Thu Oct 11 09:43:38 2001
@@ -10,9 +10,13 @@
 #define __S390_GDB_STUB__
 #include <linux/config.h>
 #if CONFIG_REMOTE_DEBUG
-#include <asm/s390-gdbregs.h>
 #include <asm/ptrace.h>
 extern int    gdb_stub_initialised;
-extern void gdb_stub_handle_exception(gdb_pt_regs *regs,int sigval);
+extern void gdb_stub_handle_exception(struct gdb_pt_regs *regs,int sigval);
+struct net_device;
+struct net_device *gdb_dev;
+void gdb_do_timers(void);
+extern int putDebugChar(char c);    /* write a single character      */
+extern char getDebugChar(void);     /* read and return a single char */
 #endif
 #endif
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/lowcore.h linux/include/asm-s390/lowcore.h
--- v2.4.12/linux/include/asm-s390/lowcore.h	Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390/lowcore.h	Thu Oct 11 09:43:38 2001
@@ -41,7 +41,7 @@
 
 #define __LC_SAVE_AREA                  0xC00
 #define __LC_KERNEL_STACK               0xC40
-#define __LC_KERNEL_LEVEL               0xC44
+#define __LC_ASYNC_STACK                0xC44
 #define __LC_CPUID                      0xC60
 #define __LC_CPUADDR                    0xC68
 #define __LC_IPLDEV                     0xC7C
@@ -86,6 +86,12 @@
 #include <asm/atomic.h>
 #include <asm/sigp.h>
 
+void restart_int_handler(void);
+void ext_int_handler(void);
+void system_call(void);
+void pgm_check_handler(void);
+void mcck_int_handler(void);
+void io_int_handler(void);
 
 struct _lowcore
 {
@@ -107,7 +113,7 @@
 	__u16        cpu_addr;                 /* 0x084 */
 	__u16        ext_int_code;             /* 0x086 */
         __u16        svc_ilc;                  /* 0x088 */
-        __u16        scv_code;                 /* 0x08a */
+        __u16        svc_code;                 /* 0x08a */
         __u16        pgm_ilc;                  /* 0x08c */
         __u16        pgm_code;                 /* 0x08e */
 	__u32        trans_exc_code;           /* 0x090 */
@@ -147,7 +153,7 @@
         /* System info area */
 	__u32        save_area[16];            /* 0xc00 */
 	__u32        kernel_stack;             /* 0xc40 */
-	__u32        kernel_level;             /* 0xc44 */
+	__u32        async_stack;              /* 0xc44 */
 	/* entry.S sensitive area start */
 	__u8         pad10[0xc60-0xc48];       /* 0xc5c */
 	struct       cpuinfo_S390 cpu_data;    /* 0xc60 */
@@ -157,9 +163,7 @@
         /* SMP info area: defined by DJB */
         __u64        jiffy_timer_cc;           /* 0xc80 */
 	atomic_t     ext_call_fast;            /* 0xc88 */
-	atomic_t     ext_call_queue;           /* 0xc8c */
-        atomic_t     ext_call_count;           /* 0xc90 */
-        __u8         pad11[0xe00-0xc94];       /* 0xc94 */
+        __u8         pad11[0xe00-0xc8c];       /* 0xc8c */
 
         /* 0xe00 is used as indicator for dump tools */
         /* whether the kernel died with panic() or not */
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/pgalloc.h linux/include/asm-s390/pgalloc.h
--- v2.4.12/linux/include/asm-s390/pgalloc.h	Mon Apr 23 15:28:07 2001
+++ linux/include/asm-s390/pgalloc.h	Thu Oct 11 09:43:38 2001
@@ -84,6 +84,8 @@
 #define pmd_alloc_one_fast(mm, address) ({ BUG(); ((pmd_t *)1); })
 #define pmd_alloc_one(mm,address)       ({ BUG(); ((pmd_t *)2); })
 #define pmd_free(x)                     do { } while (0)
+#define pmd_free_slow(x)		do { } while (0)
+#define pmd_free_fast(x)                do { } while (0)
 #define pgd_populate(mm, pmd, pte)      BUG()
 
 extern inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/pgtable.h linux/include/asm-s390/pgtable.h
--- v2.4.12/linux/include/asm-s390/pgtable.h	Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390/pgtable.h	Thu Oct 11 09:43:38 2001
@@ -58,13 +58,6 @@
 #endif /* !__ASSEMBLY__ */
 
 /*
- * Certain architectures need to do special things when PTEs
- * within a page table are directly modified.  Thus, the following
- * hook is made available.
- */
-#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
-
-/*
  * PMD_SHIFT determines the size of the area a second-level page
  * table can map
  */
@@ -162,6 +155,7 @@
 
 /* Bits in the page table entry */
 #define _PAGE_PRESENT   0x001          /* Software                         */
+#define _PAGE_MKCLEAR   0x002          /* Software                         */
 #define _PAGE_RO        0x200          /* HW read-only                     */
 #define _PAGE_INVALID   0x400          /* HW invalid                       */
 
@@ -226,6 +220,25 @@
 #define __S111  PAGE_SHARED
 
 /*
+ * Certain architectures need to do special things when PTEs
+ * within a page table are directly modified.  Thus, the following
+ * hook is made available.
+ */
+extern inline void set_pte(pte_t *pteptr, pte_t pteval)
+{
+	if ((pte_val(pteval) & (_PAGE_MKCLEAR|_PAGE_INVALID))
+	    == _PAGE_MKCLEAR) 
+	{
+		pte_val(pteval) &= ~_PAGE_MKCLEAR;
+               
+		asm volatile ("sske %0,%1" 
+				: : "d" (0), "a" (pte_val(pteval)));
+	}
+
+	*pteptr = pteval;
+}
+
+/*
  * Permanent address of a page.
  */
 #define page_address(page) ((page)->virtual)
@@ -323,23 +336,22 @@
 
 extern inline pte_t pte_mkclean(pte_t pte)
 {
-	/* We can't clear the changed bit atomically. The iske/and/sske
-         * sequence has a race condition with the page referenced bit.
-         * At the moment pte_mkclean is always followed by a pte_mkold.
-         * So its safe to ignore the problem for now. Hope this will
-         * never change ... */
-	asm volatile ("sske %0,%1" 
-	              : : "d" (0), "a" (pte_val(pte)));
+	/* The only user of pte_mkclean is the fork() code.
+	   We must *not* clear the *physical* page dirty bit
+	   just because fork() wants to clear the dirty bit in
+	   *one* of the page's mappings.  So we just do nothing. */
 	return pte;
 }
 
 extern inline pte_t pte_mkdirty(pte_t pte)
 {
-	/* We can't set the changed bit atomically either. For now we
+	/* We can't set the changed bit atomically. For now we
          * set (!) the page referenced bit. */
 	asm volatile ("sske %0,%1" 
 	              : : "d" (_PAGE_CHANGED|_PAGE_REFERENCED),
 		          "a" (pte_val(pte)));
+
+	pte_val(pte) &= ~_PAGE_MKCLEAR;
 	return pte;
 }
 
@@ -411,7 +423,23 @@
 	pte_val(__pte) = physpage + pgprot_val(pgprot);
 	return __pte;
 }
-#define mk_pte(page,pgprot) mk_pte_phys(__pa(((page)-mem_map)<<PAGE_SHIFT),pgprot)
+
+#define mk_pte(pg, pgprot)                                                \
+({                                                                        \
+	struct page *__page = (pg);                                       \
+	unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT);  \
+	pte_t __pte = mk_pte_phys(__physpage, (pgprot));                  \
+	                                                                  \
+	if (__page != ZERO_PAGE(__physpage)) {                            \
+		int __users = page_count(__page);                         \
+		__users -= !!__page->buffers + !!__page->mapping;         \
+	                                                                  \
+		if (__users == 1)                                         \
+			pte_val(__pte) |= _PAGE_MKCLEAR;                  \
+        }                                                                 \
+	                                                                  \
+	__pte;                                                            \
+})
 
 #define pte_page(x) (mem_map+(unsigned long)((pte_val(x) >> PAGE_SHIFT)))
 
@@ -472,6 +500,11 @@
 /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
 #define PageSkip(page)          (0)
 #define kern_addr_valid(addr)   (1)
+
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init()	do { } while (0)
 
 #endif /* _S390_PAGE_H */
 
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/ptrace.h linux/include/asm-s390/ptrace.h
--- v2.4.12/linux/include/asm-s390/ptrace.h	Wed Apr 11 19:02:28 2001
+++ linux/include/asm-s390/ptrace.h	Thu Oct 11 09:43:38 2001
@@ -191,6 +191,7 @@
 	__u32 trap;
 	__u32 crs[16];
 	s390_fp_regs fp_regs;
+	__u32 old_ilc;
 };
 #endif
 
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/sigp.h linux/include/asm-s390/sigp.h
--- v2.4.12/linux/include/asm-s390/sigp.h	Wed Apr 11 19:02:28 2001
+++ linux/include/asm-s390/sigp.h	Thu Oct 11 09:43:38 2001
@@ -62,34 +62,9 @@
         ec_restart,
         ec_halt,
         ec_power_off,
-        ec_ptlb,
+	ec_call_function,
 	ec_bit_last
 } ec_bit_sig;
-
-/* Signals which come with a parameter area, synchronous */
-typedef enum
-{
-        ec_callback_async,
-        ec_callback_sync
-} ec_cmd_sig;
-
-/* state information for synchronous signals */
-typedef enum
-{
-	ec_pending,
-	ec_executing,
-	ec_done
-} ec_state;
-
-/* header for the queuing of signals with a parameter area */
-typedef struct ec_ext_call
-{
-	ec_cmd_sig cmd;
-	atomic_t status;
-	struct ec_ext_call *next;
-        void (*func)(void *info);
-        void *info;
-} ec_ext_call;
 
 /*
  * Signal processor
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/smp.h linux/include/asm-s390/smp.h
--- v2.4.12/linux/include/asm-s390/smp.h	Wed Apr 11 19:02:28 2001
+++ linux/include/asm-s390/smp.h	Thu Oct 11 09:43:38 2001
@@ -26,6 +26,8 @@
 	__u16      cpu;
 } sigp_info;
 
+extern unsigned long cpu_online_map;
+
 #define NO_PROC_ID		0xFF		/* No processor magic marker */
 
 /*
@@ -64,12 +66,5 @@
 
 void smp_local_timer_interrupt(struct pt_regs * regs);
 
-sigp_ccode smp_ext_call(int cpu, void (*cb)(void *info), void *info, int wait);
-void smp_ext_call_others(void (*cb)(void *info), void *info, int wait);
-sigp_ccode smp_ext_bitcall(int cpu, ec_bit_sig sig);
-void smp_ext_bitcall_others(ec_bit_sig sig);
-
-int smp_signal_others(sigp_order_code order_code,__u32 parameter,
-                      int spin,sigp_info *info);
 #endif
 #endif
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/softirq.h linux/include/asm-s390/softirq.h
--- v2.4.12/linux/include/asm-s390/softirq.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-s390/softirq.h	Thu Oct 11 09:43:38 2001
@@ -18,22 +18,25 @@
 #include <asm/lowcore.h>
 
 #define __cpu_bh_enable(cpu) \
-		do { barrier(); local_bh_count(cpu)--; } while (0)
+                do { barrier(); local_bh_count(cpu)--; } while (0)
 #define cpu_bh_disable(cpu) \
-		do { local_bh_count(cpu)++; barrier(); } while (0)
+                do { local_bh_count(cpu)++; barrier(); } while (0)
 
 #define local_bh_disable()      cpu_bh_disable(smp_processor_id())
 #define __local_bh_enable()     __cpu_bh_enable(smp_processor_id())
 
 #define in_softirq() (local_bh_count(smp_processor_id()) != 0)
 
+extern void do_call_softirq(void);
+
 #define local_bh_enable()			          	        \
 do {							                \
-	unsigned int *ptr = &local_bh_count(smp_processor_id());        \
-	barrier();                                                      \
-	if (!--*ptr)							\
+        unsigned int *ptr = &local_bh_count(smp_processor_id());        \
+        barrier();                                                      \
+        if (!--*ptr)							\
 		if (softirq_pending(smp_processor_id()))		\
-			do_softirq();					\
+			/* Use the async. stack for softirq */		\
+			do_call_softirq();				\
 } while (0)
 
 #endif	/* __ASM_SOFTIRQ_H */
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/spinlock.h linux/include/asm-s390/spinlock.h
--- v2.4.12/linux/include/asm-s390/spinlock.h	Wed Apr 11 19:02:28 2001
+++ linux/include/asm-s390/spinlock.h	Thu Oct 11 09:43:38 2001
@@ -32,20 +32,19 @@
         __asm__ __volatile("    bras  1,1f\n"
                            "0:  diag  0,0,68\n"
                            "1:  slr   0,0\n"
-                           "    cs    0,1,%1\n"
+                           "    cs    0,1,0(%0)\n"
                            "    jl    0b\n"
-                           : "=m" (lp->lock)
-                           : "0" (lp->lock) : "0", "1", "cc" );
+                           : : "a" (&lp->lock) : "0", "1", "cc", "memory" );
 }
 
 extern inline int spin_trylock(spinlock_t *lp)
 {
 	unsigned long result;
-	__asm__ __volatile("    slr   %1,%1\n"
+	__asm__ __volatile("    slr   %0,%0\n"
 			   "    basr  1,0\n"
-			   "0:  cs    %1,1,%0"
-			   : "=m" (lp->lock), "=&d" (result)
-			   : "0" (lp->lock) : "1", "cc" );
+			   "0:  cs    %0,1,0(%1)"
+			   : "=&d" (result)
+			   : "a" (&lp->lock) : "1", "cc", "memory" );
 	return !result;
 }
 
@@ -53,7 +52,7 @@
 {
 	__asm__ __volatile("    xc 0(4,%0),0(%0)\n"
                            "    bcr 15,0"
-			   : /* no output */ : "a" (lp) : "memory", "cc" );
+			   : : "a" (&lp->lock) : "memory", "cc" );
 }
 		
 /*
@@ -76,24 +75,24 @@
 #define rwlock_init(x)	do { *(x) = RW_LOCK_UNLOCKED; } while(0)
 
 #define read_lock(rw)   \
-        asm volatile("   l     2,%0\n"   \
+        asm volatile("   l     2,0(%0)\n"   \
                      "   j     1f\n"     \
                      "0: diag  0,0,68\n" \
-                     "1: la    2,0(2)\n"  /* clear high (=write) bit */ \
-                     "   la    3,1(2)\n"  /* one more reader */ \
-                     "   cs    2,3,%0\n"  /* try to write new value */ \
+                     "1: la    2,0(2)\n"     /* clear high (=write) bit */ \
+                     "   la    3,1(2)\n"     /* one more reader */ \
+                     "   cs    2,3,0(%0)\n"  /* try to write new value */ \
                      "   jl    0b"       \
-                     : "+m" ((rw)->lock) : : "2", "3", "cc" );
+                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
 
 #define read_unlock(rw) \
-        asm volatile("   l     2,%0\n"   \
+        asm volatile("   l     2,0(%0)\n"   \
                      "   j     1f\n"     \
                      "0: diag  0,0,68\n" \
                      "1: lr    3,2\n"    \
                      "   ahi   3,-1\n"    /* one less reader */ \
-                     "   cs    2,3,%0\n" \
+                     "   cs    2,3,0(%0)\n" \
                      "   jl    0b"       \
-                     : "+m" ((rw)->lock) : : "2", "3", "cc" );
+                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
 
 #define write_lock(rw) \
         asm volatile("   lhi   3,1\n"    \
@@ -101,9 +100,9 @@
                      "   j     1f\n"     \
                      "0: diag  0,0,68\n" \
                      "1: slr   2,2\n"     /* old lock value must be 0 */ \
-                     "   cs    2,3,%0\n" \
+                     "   cs    2,3,0(%0)\n" \
                      "   jl    0b"       \
-                     : "+m" ((rw)->lock) : : "2", "3", "cc" );
+                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
 
 #define write_unlock(rw) \
         asm volatile("   slr   3,3\n"     /* new lock value = 0 */ \
@@ -111,8 +110,8 @@
                      "0: diag  0,0,68\n" \
                      "1: lhi   2,1\n"    \
                      "   sll   2,31\n"    /* old lock value must be 0x80000000 */ \
-                     "   cs    2,3,%0\n" \
+                     "   cs    2,3,0(%0)\n" \
                      "   jl    0b"       \
-                     : "+m" ((rw)->lock) : : "2", "3", "cc" );
+                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
 
 #endif /* __ASM_SPINLOCK_H */
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/uaccess.h linux/include/asm-s390/uaccess.h
--- v2.4.12/linux/include/asm-s390/uaccess.h	Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390/uaccess.h	Thu Oct 11 09:43:38 2001
@@ -78,6 +78,35 @@
  * use the right size if we just have the right pointer type.
  */
 
+extern inline int __put_user_asm_8(__u64 x, void *ptr)
+{
+        int err;
+
+        __asm__ __volatile__ (  "   sr    %1,%1\n"
+				"   la    2,%2\n"
+				"   la    4,%0\n"
+                                "   sacf  512\n"
+                                "0: mvc   0(8,4),0(2)\n"
+                                "   sacf  0\n"
+				"1:\n"
+				".section .fixup,\"ax\"\n"
+				"2: sacf  0\n"
+				"   lhi   %1,%h3\n"
+				"   bras  4,3f\n"
+				"   .long 1b\n"
+				"3: l     4,0(4)\n"
+				"   br    4\n"
+				".previous\n"
+				".section __ex_table,\"a\"\n"
+				"   .align 4\n"
+				"   .long  0b,2b\n"
+				".previous"
+                                : "=m" (*((__u32*) ptr)), "=&d" (err)
+                                : "m" (x), "K" (-EFAULT)
+                                : "cc", "2", "4" );
+        return err;
+}
+
 extern inline int __put_user_asm_4(__u32 x, void *ptr)
 {
         int err;
@@ -179,6 +208,9 @@
                 case 4:                                         \
                         __pu_err = __put_user_asm_4((__u32) x,(ptr));\
                         break;                                  \
+		case 8:						\
+			__pu_err = __put_user_asm_8((__u64) x,(ptr));\
+			break;					\
                 default:                                        \
                 __pu_err = __put_user_bad();                    \
                 break;                                          \
@@ -200,6 +232,31 @@
 
 extern int __put_user_bad(void);
 
+#define __get_user_asm_8(x, ptr, err)                                      \
+({                                                                         \
+        __asm__ __volatile__ (  "   sr    %1,%1\n"                         \
+				"   la    2,%0\n"			   \
+                                "   la    4,%2\n"                          \
+                                "   sacf  512\n"                           \
+                                "0: mvc   0(8,2),0(4)\n"                   \
+                                "   sacf  0\n"                             \
+                                "1:\n"                                     \
+                                ".section .fixup,\"ax\"\n"                 \
+                                "2: sacf  0\n"                             \
+                                "   lhi   %1,%h3\n"                        \
+                                "   bras  4,3f\n"                          \
+                                "   .long 1b\n"                            \
+                                "3: l     4,0(4)\n"                        \
+                                "   br    4\n"                             \
+                                ".previous\n"                              \
+                                ".section __ex_table,\"a\"\n"              \
+                                "   .align 4\n"                            \
+                                "   .long 0b,2b\n"                         \
+                                ".previous"                                \
+                                : "=m" (x) , "=&d" (err)                   \
+                                : "m" (*(const __u64*)(ptr)),"K" (-EFAULT) \
+                                : "cc", "2", "4" );                        \
+})
 
 #define __get_user_asm_4(x, ptr, err)                                      \
 ({                                                                         \
@@ -290,6 +347,9 @@
                 case 4:                                         \
                         __get_user_asm_4(x,ptr,__gu_err);       \
                         break;                                  \
+                case 8:                                         \
+                        __get_user_asm_8(x,ptr,__gu_err);       \
+                        break;                                  \
                 default:                                        \
                         (x) = 0;                                \
                         __gu_err = __get_user_bad();            \
@@ -372,7 +432,7 @@
                                 "0: mvcle 2,4,0\n"
                                 "   jo    0b\n"
                                 "   sacf  0\n"
-                                "   lr    %0,3\n"
+                                "   lr    %0,5\n"
 				".section __ex_table,\"a\"\n"
 				"   .align 4\n"
 				"   .long  0b,__copy_from_user_fixup\n"
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/ucontext.h linux/include/asm-s390/ucontext.h
--- v2.4.12/linux/include/asm-s390/ucontext.h	Tue Feb 13 14:13:44 2001
+++ linux/include/asm-s390/ucontext.h	Thu Oct 11 09:43:38 2001
@@ -13,10 +13,8 @@
 	unsigned long	  uc_flags;
 	struct ucontext  *uc_link;
 	stack_t		  uc_stack;
+	_sigregs          uc_mcontext;
 	sigset_t	  uc_sigmask;	/* mask last for extensibility */
-	struct sigcontext *sc; /* Added for pthread support */
 };
-
-
 
 #endif /* !_ASM_S390_UCONTEXT_H */
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/unistd.h linux/include/asm-s390/unistd.h
--- v2.4.12/linux/include/asm-s390/unistd.h	Tue Feb 13 14:13:44 2001
+++ linux/include/asm-s390/unistd.h	Thu Oct 11 09:43:38 2001
@@ -178,6 +178,8 @@
 #define __NR_capset             185
 #define __NR_sigaltstack        186
 #define __NR_sendfile           187
+#define __NR_getpmsg		188
+#define __NR_putpmsg		189
 #define __NR_vfork		190
 #define __NR_ugetrlimit		191	/* SuS compliant getrlimit */
 #define __NR_mmap2		192
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/vtoc.h linux/include/asm-s390/vtoc.h
--- v2.4.12/linux/include/asm-s390/vtoc.h	Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390/vtoc.h	Thu Oct 11 09:43:38 2001
@@ -39,135 +39,6 @@
 
 #define VTOC_ERROR "VTOC error:"
 
-enum failure {unable_to_open,
-	      unable_to_seek,
-	      unable_to_write,
-	      unable_to_read};
-
-unsigned char ASCtoEBC[256] =
-{
-  /*00  NL    SH    SX    EX    ET    NQ    AK    BL */
-  0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
-  /*08  BS    HT    LF    VT    FF    CR    SO    SI */
-  0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
-  /*10  DL    D1    D2    D3    D4    NK    SN    EB */
-  0x10, 0x11, 0x12, 0x13, 0x3C, 0x15, 0x32, 0x26,
-  /*18  CN    EM    SB    EC    FS    GS    RS    US */
-  0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F,
-  /*20  SP     !     "     #     $     %     &     ' */
-  0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
-  /*28   (     )     *     +     ,     -    .      / */
-  0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
-  /*30   0     1     2     3     4     5     6     7 */
-  0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
-  /*38   8     9     :     ;     <     =     >     ? */
-  0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
-  /*40   @     A     B     C     D     E     F     G */
-  0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
-  /*48   H     I     J     K     L     M     N     O */
-  0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
-  /*50   P     Q     R     S     T     U     V     W */
-  0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
-  /*58   X     Y     Z     [     \     ]     ^     _ */
-  0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
-  /*60   `     a     b     c     d     e     f     g */
-  0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
-  /*68   h     i     j     k     l     m     n     o */
-  0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
-  /*70   p     q     r     s     t     u     v     w */
-  0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
-  /*78   x     y     z     {     |     }     ~    DL */
-  0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xFF
-};
-
-
-unsigned char EBCtoASC[256] =
-{
- /* 0x00   NUL   SOH   STX   ETX  *SEL    HT  *RNL   DEL */
-          0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F,
- /* 0x08   -GE  -SPS  -RPT    VT    FF    CR    SO    SI */
-          0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- /* 0x10   DLE   DC1   DC2   DC3  -RES   -NL    BS  -POC
-                                  -ENP  ->LF             */
-          0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07,
- /* 0x18   CAN    EM  -UBS  -CU1  -IFS  -IGS  -IRS  -ITB
-                                                    -IUS */
-          0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- /* 0x20   -DS  -SOS    FS  -WUS  -BYP    LF   ETB   ESC
-                                  -INP                   */
-          0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
- /* 0x28   -SA  -SFE   -SM  -CSP  -MFA   ENQ   ACK   BEL
-                       -SW                               */ 
-          0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
- /* 0x30  ----  ----   SYN   -IR   -PP  -TRN  -NBS   EOT */
-          0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
- /* 0x38  -SBS   -IT  -RFF  -CU3   DC4   NAK  ----   SUB */
-          0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
- /* 0x40    SP   RSP           ä              ----       */
-          0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
- /* 0x48                       .     <     (     +     | */
-          0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
- /* 0x50     &                                      ---- */
-          0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
- /* 0x58           ß     !     $     *     )     ;       */
-          0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA,
- /* 0x60     -     /  ----     Ä  ----  ----  ----       */
-          0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F,
- /* 0x68              ----     ,     %     _     >     ? */ 
-          0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
- /* 0x70  ----        ----  ----  ----  ----  ----  ---- */
-          0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- /* 0x78     *     `     :     #     @     '     =     " */
-          0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
- /* 0x80     *     a     b     c     d     e     f     g */
-          0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- /* 0x88     h     i              ----  ----  ----       */
-          0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
- /* 0x90     °     j     k     l     m     n     o     p */
-          0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
- /* 0x98     q     r                    ----        ---- */
-          0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
- /* 0xA0           ~     s     t     u     v     w     x */
-          0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
- /* 0xA8     y     z              ----  ----  ----  ---- */
-          0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
- /* 0xB0     ^                    ----     §  ----       */
-          0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
- /* 0xB8        ----     [     ]  ----  ----  ----  ---- */
-          0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07,
- /* 0xC0     {     A     B     C     D     E     F     G */
-          0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- /* 0xC8     H     I  ----           ö              ---- */
-          0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
- /* 0xD0     }     J     K     L     M     N     O     P */
-          0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
- /* 0xD8     Q     R  ----           ü                   */
-          0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
- /* 0xE0     \           S     T     U     V     W     X */
-          0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
- /* 0xE8     Y     Z        ----     Ö  ----  ----  ---- */
-          0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07,
- /* 0xF0     0     1     2     3     4     5     6     7 */
-          0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- /* 0xF8     8     9  ----  ----     Ü  ----  ----  ---- */
-          0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07
-};
 
 typedef struct ttr 
 {
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/chandev.h linux/include/asm-s390x/chandev.h
--- v2.4.12/linux/include/asm-s390x/chandev.h	Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390x/chandev.h	Thu Oct 11 09:43:38 2001
@@ -139,6 +139,10 @@
  * not operational the previous status is sent in the prevstatus variable.
  * This can be used in cases when the default handling isn't quite adequete
  * e.g. if a ssch is needed to reinitialize long running channel programs.
+ *
+ * This returns the number of devices found or -ENOMEM if the code didn't
+ * have enough memory to allocate the chandev control block
+ * or -EPERM if a duplicate entry is found.
  */
 int chandev_register_and_probe(chandev_probefunc probefunc,
 			       chandev_shutdownfunc shutdownfunc,
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/current.h linux/include/asm-s390x/current.h
--- v2.4.12/linux/include/asm-s390x/current.h	Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390x/current.h	Thu Oct 11 09:43:38 2001
@@ -19,7 +19,7 @@
 {
         struct task_struct *current;
         __asm__("lghi  %0,-16384\n\t"
-                "ngr   %0,15"
+                "alg   %0,0xd40"
                 : "=&r" (current) : : "cc" );
         return current;
  }
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/dasd.h linux/include/asm-s390x/dasd.h
--- v2.4.12/linux/include/asm-s390x/dasd.h	Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390x/dasd.h	Thu Oct 11 09:43:38 2001
@@ -36,6 +36,7 @@
         unsigned int dasd_io_time2[32];	 /* histogram of time from start to irq */
         unsigned int dasd_io_time2ps[32]; /* histogram of time from start to irq */
         unsigned int dasd_io_time3[32];	 /* histogram of time from irq to end */
+        unsigned int dasd_io_nr_req[32]; /* histogram of # of requests in chanq */
 } dasd_profile_info_t;
 
 /* 
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/debug.h linux/include/asm-s390x/debug.h
--- v2.4.12/linux/include/asm-s390x/debug.h	Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390x/debug.h	Thu Oct 11 09:43:38 2001
@@ -44,6 +44,7 @@
 
 #define DEBUG_MAX_LEVEL            6  /* debug levels range from 0 to 6 */
 #define DEBUG_OFF_LEVEL            -1 /* level where debug is switched off */
+#define DEBUG_FLUSH_ALL            -1 /* parameter to flush all areas */
 #define DEBUG_MAX_VIEWS            10 /* max number of views in proc fs */
 #define DEBUG_MAX_PROCF_LEN        16 /* max length for a proc file name */
 #define DEBUG_DEFAULT_LEVEL        3  /* initial debug level */
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/lowcore.h linux/include/asm-s390x/lowcore.h
--- v2.4.12/linux/include/asm-s390x/lowcore.h	Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390x/lowcore.h	Thu Oct 11 09:43:38 2001
@@ -1,3 +1,4 @@
+
 /*
  *  include/asm-s390/lowcore.h
  *
@@ -39,7 +40,7 @@
 
 #define __LC_SAVE_AREA                  0xC00
 #define __LC_KERNEL_STACK               0xD40
-#define __LC_KERNEL_LEVEL               0xD48
+#define __LC_ASYNC_STACK                0xD48
 #define __LC_CPUID                      0xD90
 #define __LC_CPUADDR                    0xD98
 #define __LC_IPLDEV                     0xDB8
@@ -85,6 +86,12 @@
 #include <asm/atomic.h>
 #include <asm/sigp.h>
 
+void restart_int_handler(void);
+void ext_int_handler(void);
+void system_call(void);
+void pgm_check_handler(void);
+void mcck_int_handler(void);
+void io_int_handler(void);
 
 struct _lowcore
 {
@@ -96,7 +103,7 @@
 	__u16        cpu_addr;                 /* 0x084 */
 	__u16        ext_int_code;             /* 0x086 */
         __u16        svc_ilc;                  /* 0x088 */
-        __u16        scv_code;                 /* 0x08a */
+        __u16        svc_code;                 /* 0x08a */
         __u16        pgm_ilc;                  /* 0x08c */
         __u16        pgm_code;                 /* 0x08e */
 	__u32        data_exc_code;            /* 0x090 */
@@ -142,7 +149,7 @@
 	__u64        save_area[16];            /* 0xc00 */
         __u8         pad9[0xd40-0xc80];        /* 0xc80 */
  	__u64        kernel_stack;             /* 0xd40 */
-	__u64        kernel_level;             /* 0xd48 */
+	__u64        async_stack;              /* 0xd48 */
 	/* entry.S sensitive area start */
 	__u8         pad10[0xd80-0xd50];       /* 0xd64 */
 	struct       cpuinfo_S390 cpu_data;    /* 0xd80 */
@@ -153,10 +160,7 @@
         /* SMP info area: defined by DJB */
         __u64        jiffy_timer_cc;           /* 0xdc0 */
 	__u64        ext_call_fast;            /* 0xdc8 */
-	__u64        ext_call_queue;           /* 0xdd0 */
-        __u64        ext_call_count;           /* 0xdd8 */
-
-        __u8         pad12[0xe00-0xde0];       /* 0xde0 */
+        __u8         pad12[0xe00-0xdd0];       /* 0xdd0 */
 
         /* 0xe00 is used as indicator for dump tools */
         /* whether the kernel died with panic() or not */
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/mathemu.h linux/include/asm-s390x/mathemu.h
--- v2.4.12/linux/include/asm-s390x/mathemu.h	Tue Feb 13 14:13:44 2001
+++ linux/include/asm-s390x/mathemu.h	Wed Dec 31 16:00:00 1969
@@ -1,48 +0,0 @@
-/*
- *  arch/s390/kernel/mathemu.h
- *    IEEE floating point emulation.
- *
- *  S390 version
- *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
- */
-
-#ifndef __MATHEMU__
-#define __MATHEMU__
-
-extern int math_emu_b3(__u8 *, struct pt_regs *);
-extern int math_emu_ed(__u8 *, struct pt_regs *);
-extern void math_emu_ldr(__u8 *);
-extern void math_emu_ler(__u8 *);
-extern void math_emu_std(__u8 *, struct pt_regs *);
-extern void math_emu_ld(__u8 *, struct pt_regs *);
-extern void math_emu_ste(__u8 *, struct pt_regs *);
-extern void math_emu_le(__u8 *, struct pt_regs *);
-extern int math_emu_lfpc(__u8 *, struct pt_regs *);
-extern int math_emu_stfpc(__u8 *, struct pt_regs *);
-extern int math_emu_srnm(__u8 *, struct pt_regs *);
-
-
-extern __u64 __adddf3(__u64,__u64);
-extern __u64 __subdf3(__u64,__u64);
-extern __u64 __muldf3(__u64,__u64);
-extern __u64 __divdf3(__u64,__u64);
-extern long  __cmpdf2(__u64,__u64);
-extern __u64 __negdf2(__u64);
-extern __u64 __absdf2(__u64);
-extern __u32 __addsf3(__u32,__u32);
-extern __u32 __subsf3(__u32,__u32);
-extern __u32 __mulsf3(__u32,__u32);
-extern __u32 __divsf3(__u32,__u32);
-extern __u32 __negsf2(__u32);
-extern __u32 __abssf2(__u32);
-extern long  __cmpsf2(__u32,__u32);
-extern __u32 __truncdfsf2(__u64);
-extern __u32 __fixsfsi(__u32);
-extern __u32 __fixdfsi(__u64);
-extern __u64  __floatsidf(__u32);
-extern __u32  __floatsisf(__u32);
-extern __u64  __extendsfdf2(__u32);
-
-#endif                                 /* __MATHEMU__                      */
-
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/page.h linux/include/asm-s390x/page.h
--- v2.4.12/linux/include/asm-s390x/page.h	Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390x/page.h	Thu Oct 11 09:43:38 2001
@@ -110,11 +110,6 @@
 /* to align the pointer to the (next) page boundary */
 #define PAGE_ALIGN(addr)        (((addr)+PAGE_SIZE-1)&PAGE_MASK)
 
-/*
- *
- *
- */
-
 #define __PAGE_OFFSET           0x0UL
 #define PAGE_OFFSET             0x0UL
 #define __pa(x)                 (unsigned long)(x)
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/param.h linux/include/asm-s390x/param.h
--- v2.4.12/linux/include/asm-s390x/param.h	Tue Feb 13 14:13:44 2001
+++ linux/include/asm-s390x/param.h	Thu Oct 11 09:43:38 2001
@@ -11,6 +11,9 @@
 
 #ifndef HZ
 #define HZ 100
+#ifdef __KERNEL__
+#define hz_to_std(a) (a)
+#endif
 #endif
 
 #define EXEC_PAGESIZE	4096
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/pgtable.h linux/include/asm-s390x/pgtable.h
--- v2.4.12/linux/include/asm-s390x/pgtable.h	Sun Aug 12 13:28:01 2001
+++ linux/include/asm-s390x/pgtable.h	Thu Oct 11 09:43:38 2001
@@ -54,13 +54,6 @@
 #endif /* !__ASSEMBLY__ */
 
 /*
- * Certain architectures need to do special things when PTEs
- * within a page table are directly modified.  Thus, the following
- * hook is made available.
- */
-#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
-
-/*
  * PMD_SHIFT determines the size of the area a second-level page
  * table can map
  */
@@ -164,6 +157,7 @@
 
 /* Bits in the page table entry */
 #define _PAGE_PRESENT   0x001          /* Software                         */
+#define _PAGE_MKCLEAR   0x002          /* Software                         */
 #define _PAGE_RO        0x200          /* HW read-only                     */
 #define _PAGE_INVALID   0x400          /* HW invalid                       */
 
@@ -180,7 +174,8 @@
  */
 #define _REGION_THIRD       0x4
 #define _REGION_THIRD_LEN   0x3 
-#define _REGION_TABLE       (_REGION_THIRD|_REGION_THIRD_LEN|0x40)
+#define _REGION_TABLE       (_REGION_THIRD|_REGION_THIRD_LEN|0x40|0x100)
+#define _KERN_REGION_TABLE  (_REGION_THIRD|_REGION_THIRD_LEN)
 
 /* Bits in the storage key */
 #define _PAGE_CHANGED    0x02          /* HW changed bit                   */
@@ -220,6 +215,25 @@
 #define __S111  PAGE_SHARED
 
 /*
+ * Certain architectures need to do special things when PTEs
+ * within a page table are directly modified.  Thus, the following
+ * hook is made available.
+ */
+extern inline void set_pte(pte_t *pteptr, pte_t pteval)
+{
+	if ((pte_val(pteval) & (_PAGE_MKCLEAR|_PAGE_INVALID))
+	    == _PAGE_MKCLEAR) 
+	{
+		pte_val(pteval) &= ~_PAGE_MKCLEAR;
+               
+		asm volatile ("sske %0,%1" 
+				: : "d" (0), "a" (pte_val(pteval)));
+	}
+
+	*pteptr = pteval;
+}
+
+/*
  * Permanent address of a page.
  */
 #define page_address(page) ((page)->virtual)
@@ -341,13 +355,10 @@
 
 extern inline pte_t pte_mkclean(pte_t pte)
 {
-	/* We can't clear the changed bit atomically. The iske/and/sske
-         * sequence has a race condition with the page referenced bit.
-         * At the moment pte_mkclean is always followed by a pte_mkold.
-         * So its safe to ignore the problem for now. Hope this will
-         * never change ... */
-	asm volatile ("sske %0,%1" 
-	              : : "d" (0), "a" (pte_val(pte)));
+	/* The only user of pte_mkclean is the fork() code.
+	   We must *not* clear the *physical* page dirty bit
+	   just because fork() wants to clear the dirty bit in
+	   *one* of the page's mappings.  So we just do nothing. */
 	return pte;
 }
 
@@ -358,6 +369,8 @@
 	asm volatile ("sske %0,%1" 
 	              : : "d" (_PAGE_CHANGED|_PAGE_REFERENCED),
 		          "a" (pte_val(pte)));
+
+	pte_val(pte) &= ~_PAGE_MKCLEAR;
 	return pte;
 }
 
@@ -429,7 +442,23 @@
 	pte_val(__pte) = physpage + pgprot_val(pgprot);
 	return __pte;
 }
-#define mk_pte(page,pgprot) mk_pte_phys(__pa(((page)-mem_map)<<PAGE_SHIFT),pgprot)
+
+#define mk_pte(pg, pgprot)                                                \
+({                                                                        \
+	struct page *__page = (pg);                                       \
+	unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT);  \
+	pte_t __pte = mk_pte_phys(__physpage, (pgprot));                  \
+	                                                                  \
+	if (__page != ZERO_PAGE(__physpage)) {                            \
+		int __users = page_count(__page);                         \
+		__users -= !!__page->buffers + !!__page->mapping;         \
+	                                                                  \
+		if (__users == 1)                                         \
+			pte_val(__pte) |= _PAGE_MKCLEAR;                  \
+        }                                                                 \
+	                                                                  \
+	__pte;                                                            \
+})
 
 #define pte_page(x) (mem_map+(unsigned long)((pte_val(x) >> PAGE_SHIFT)))
 
@@ -491,6 +520,11 @@
 /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
 #define PageSkip(page)          (0)
 #define kern_addr_valid(addr)   (1)
+
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init()	do { } while (0)
 
 #endif /* _S390_PAGE_H */
 
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/sigp.h linux/include/asm-s390x/sigp.h
--- v2.4.12/linux/include/asm-s390x/sigp.h	Wed Apr 11 19:02:29 2001
+++ linux/include/asm-s390x/sigp.h	Thu Oct 11 09:43:38 2001
@@ -62,33 +62,10 @@
         ec_restart,
         ec_halt,
         ec_power_off,
+	ec_call_function,
 	ec_bit_last
 } ec_bit_sig;
 
-/* Signals which come with a parameter area */
-typedef enum
-{
-        ec_callback_sync,
-        ec_callback_async
-} ec_cmd_sig;
-
-/* state information for signals */
-typedef enum
-{
-	ec_pending,
-	ec_executing,
-	ec_done
-} ec_state;
-
-/* header for the queuing of callbacks */
-typedef struct ec_ext_call
-{
-	ec_cmd_sig cmd;
-	atomic_t status;
-	struct ec_ext_call *next;
-	void (*func)(void *info);
-	void *info;
-} ec_ext_call;
 
 /*
  * Signal processor
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/smp.h linux/include/asm-s390x/smp.h
--- v2.4.12/linux/include/asm-s390x/smp.h	Wed Apr 11 19:02:29 2001
+++ linux/include/asm-s390x/smp.h	Thu Oct 11 09:43:38 2001
@@ -26,6 +26,8 @@
 	__u16      cpu;
 } sigp_info;
 
+extern unsigned long cpu_online_map;
+
 #define NO_PROC_ID		0xFF		/* No processor magic marker */
 
 /*
@@ -64,12 +66,5 @@
 
 void smp_local_timer_interrupt(struct pt_regs * regs);
 
-sigp_ccode smp_ext_call(int cpu, void (*cb)(void *info), void *info, int wait);
-void smp_ext_call_others(void (*cb)(void *info), void *info, int wait);
-sigp_ccode smp_ext_bitcall(int cpu, ec_bit_sig sig);
-void smp_ext_bitcall_others(ec_bit_sig sig);
-
-int smp_signal_others(sigp_order_code order_code,__u32 parameter,
-                      int spin,sigp_info *info);
 #endif
 #endif
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/softirq.h linux/include/asm-s390x/softirq.h
--- v2.4.12/linux/include/asm-s390x/softirq.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-s390x/softirq.h	Thu Oct 11 09:43:38 2001
@@ -18,22 +18,25 @@
 #include <asm/lowcore.h>
 
 #define __cpu_bh_enable(cpu) \
-		do { barrier(); local_bh_count(cpu)--; } while (0)
+                do { barrier(); local_bh_count(cpu)--; } while (0)
 #define cpu_bh_disable(cpu) \
-		do { local_bh_count(cpu)++; barrier(); } while (0)
+                do { local_bh_count(cpu)++; barrier(); } while (0)
 
 #define local_bh_disable()      cpu_bh_disable(smp_processor_id())
 #define __local_bh_enable()     __cpu_bh_enable(smp_processor_id())
 
 #define in_softirq() (local_bh_count(smp_processor_id()) != 0)
 
+extern void do_call_softirq(void);
+
 #define local_bh_enable()			          	        \
 do {							                \
-	unsigned int *ptr = &local_bh_count(smp_processor_id());        \
-	barrier();                                                      \
-	if (!--*ptr)							\
+        unsigned int *ptr = &local_bh_count(smp_processor_id());        \
+        barrier();                                                      \
+        if (!--*ptr)							\
 		if (softirq_pending(smp_processor_id()))		\
-			do_softirq();					\
+			/* Use the async. stack for softirq */		\
+			do_call_softirq();				\
 } while (0)
 
 #endif	/* __ASM_SOFTIRQ_H */
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/spinlock.h linux/include/asm-s390x/spinlock.h
--- v2.4.12/linux/include/asm-s390x/spinlock.h	Wed Apr 11 19:02:29 2001
+++ linux/include/asm-s390x/spinlock.h	Thu Oct 11 09:43:38 2001
@@ -32,20 +32,19 @@
         __asm__ __volatile("    bras  1,1f\n"
                            "0:  # diag  0,0,68\n"
                            "1:  slr   0,0\n"
-                           "    cs    0,1,%1\n"
+                           "    cs    0,1,0(%0)\n"
                            "    jl    0b\n"
-                           : "=m" (lp->lock)
-                           : "0" (lp->lock) : "0", "1", "cc" );
+                           : : "a" (&lp->lock) : "0", "1", "cc", "memory" );
 }
 
 extern inline int spin_trylock(spinlock_t *lp)
 {
 	unsigned int result;
-	__asm__ __volatile("    slr   %1,%1\n"
+	__asm__ __volatile("    slr   %0,%0\n"
 			   "    basr  1,0\n"
-			   "0:  cs    %1,1,%0"
-			   : "=m" (lp->lock), "=&d" (result)
-			   : "0" (lp->lock) : "1", "cc" );
+			   "0:  cs    %0,1,0(%1)"
+			   : "=&d" (result)
+			   : "a" (&lp->lock) : "1", "cc", "memory" );
 	return !result;
 }
 
@@ -53,7 +52,7 @@
 {
 	__asm__ __volatile("    xc 0(4,%0),0(%0)\n"
                            "    bcr 15,0"
-			   : /* no output */ : "a" (lp) : "memory", "cc" );
+			   : : "a" (&lp->lock) : "memory", "cc" );
 }
 		
 /*
@@ -76,46 +75,42 @@
 #define rwlock_init(x)	do { *(x) = RW_LOCK_UNLOCKED; } while(0)
 
 #define read_lock(rw)   \
-        asm volatile("   la    1,%0\n"   \
-                     "   lg    2,0(1)\n"   \
+        asm volatile("   lg    2,0(%0)\n"   \
                      "   j     1f\n"     \
                      "0: # diag  0,0,68\n" \
                      "1: nihh  2,0x7fff\n" /* clear high (=write) bit */ \
                      "   la    3,1(2)\n"   /* one more reader */  \
-                     "   csg   2,3,0(1)\n" /* try to write new value */ \
+                     "   csg   2,3,0(%0)\n" /* try to write new value */ \
                      "   jl    0b"       \
-                     : "+m" ((rw)->lock) : : "1", "2", "3", "cc" );
+                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
 
 #define read_unlock(rw) \
-        asm volatile("   la    1,%0\n"   \
-                     "   lg    2,0(1)\n"   \
+        asm volatile("   lg    2,0(%0)\n"   \
                      "   j     1f\n"     \
                      "0: # diag  0,0,68\n" \
                      "1: lgr   3,2\n"    \
                      "   bctgr 3,0\n"    /* one less reader */ \
-                     "   csg   2,3,0(1)\n" \
+                     "   csg   2,3,0(%0)\n" \
                      "   jl    0b"       \
-                     : "+m" ((rw)->lock) : : "1", "2", "3", "cc" );
+                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
 
 #define write_lock(rw) \
-        asm volatile("   la    1,%0\n"     \
-                     "   llihh 3,0x8000\n" /* new lock value = 0x80...0 */ \
+        asm volatile("   llihh 3,0x8000\n" /* new lock value = 0x80...0 */ \
                      "   j     1f\n"       \
                      "0: # diag  0,0,68\n"   \
                      "1: slgr  2,2\n"      /* old lock value must be 0 */ \
-                     "   csg   2,3,0(1)\n" \
+                     "   csg   2,3,0(%0)\n" \
                      "   jl    0b"         \
-                     : "+m" ((rw)->lock) : : "1", "2", "3", "cc" );
+                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
 
 #define write_unlock(rw) \
-        asm volatile("   la    1,%0\n"     \
-                     "   slgr  3,3\n"      /* new lock value = 0 */ \
+        asm volatile("   slgr  3,3\n"      /* new lock value = 0 */ \
                      "   j     1f\n"       \
                      "0: # diag  0,0,68\n"   \
                      "1: llihh 2,0x8000\n" /* old lock value must be 0x8..0 */\
-                     "   csg   2,3,0(1)\n"   \
+                     "   csg   2,3,0(%0)\n"   \
                      "   jl    0b"         \
-                     : "+m" ((rw)->lock) : : "1", "2", "3", "cc" );
+                     : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
 
 #endif /* __ASM_SPINLOCK_H */
 
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/ucontext.h linux/include/asm-s390x/ucontext.h
--- v2.4.12/linux/include/asm-s390x/ucontext.h	Tue Feb 13 14:13:44 2001
+++ linux/include/asm-s390x/ucontext.h	Thu Oct 11 09:43:38 2001
@@ -13,10 +13,8 @@
 	unsigned long	  uc_flags;
 	struct ucontext  *uc_link;
 	stack_t		  uc_stack;
+	_sigregs          uc_mcontext;
 	sigset_t	  uc_sigmask;	/* mask last for extensibility */
-	struct sigcontext *sc; /* Added for pthread support */
 };
-
-
 
 #endif /* !_ASM_S390_UCONTEXT_H */
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/unistd.h linux/include/asm-s390x/unistd.h
--- v2.4.12/linux/include/asm-s390x/unistd.h	Sun Aug 12 13:28:01 2001
+++ linux/include/asm-s390x/unistd.h	Thu Oct 11 09:43:38 2001
@@ -154,6 +154,8 @@
 #define __NR_capset             185
 #define __NR_sigaltstack        186
 #define __NR_sendfile           187
+#define __NR_getpmsg		188
+#define __NR_putpmsg		189
 #define __NR_vfork		190
 #define __NR_getrlimit		191	/* SuS compliant getrlimit */
 #define __NR_lchown  		198
@@ -199,7 +201,7 @@
         long __res;                                          \
         __asm__ __volatile__ (                               \
                 "    svc %b1\n"                              \
-                "    lr  %0,2"                               \
+                "    lgr  %0,2"                              \
                 : "=d" (__res)                               \
                 : "i" (__NR_##name)                          \
                 : _svc_clobber );                            \
@@ -212,7 +214,7 @@
         long __res;                                          \
         __asm__ __volatile__ (                               \
                 "    svc %b1\n"                              \
-                "    lr  %0,2"                               \
+                "    lgr  %0,2"                              \
                 : "=d" (__res)                               \
                 : "i" (__NR_##name),                         \
                   "d" (__arg1)                               \
@@ -227,7 +229,7 @@
         long __res;                                          \
         __asm__ __volatile__ (                               \
                 "    svc %b1\n"                              \
-                "    lr  %0,2"                               \
+                "    lgr  %0,2"                              \
                 : "=d" (__res)                               \
                 : "i" (__NR_##name),                         \
                   "d" (__arg1),                              \
@@ -244,7 +246,7 @@
         long __res;                                          \
         __asm__ __volatile__ (                               \
                 "    svc %b1\n"                              \
-                "    lr  %0,2"                               \
+                "    lgr  %0,2"                              \
                 : "=d" (__res)                               \
                 : "i" (__NR_##name),                         \
                   "d" (__arg1),                              \
@@ -264,7 +266,7 @@
         long __res;                                          \
         __asm__ __volatile__ (                               \
                 "    svc %b1\n"                              \
-                "    lr  %0,2"                               \
+                "    lgr  %0,2"                              \
                 : "=d" (__res)                               \
                 : "i" (__NR_##name),                         \
                   "d" (__arg1),                              \
@@ -287,7 +289,7 @@
         long __res;                                          \
         __asm__ __volatile__ (                               \
                 "    svc %b1\n"                              \
-                "    lr  %0,2"                               \
+                "    lgr  %0,2"                              \
                 : "=d" (__res)                               \
                 : "i" (__NR_##name),                         \
                   "d" (__arg1),                              \
diff -u --recursive --new-file v2.4.12/linux/include/linux/b1lli.h linux/include/linux/b1lli.h
--- v2.4.12/linux/include/linux/b1lli.h	Sat May 19 17:54:14 2001
+++ linux/include/linux/b1lli.h	Thu Oct 11 09:47:33 2001
@@ -1,9 +1,11 @@
-/*
- * $Id: b1lli.h,v 1.8.8.2 2001/05/17 20:41:52 kai Exp $
+/* $Id: b1lli.h,v 1.8.8.3 2001/09/23 22:25:05 kai Exp $
  *
  * ISDN lowlevel-module for AVM B1-card.
  *
  * Copyright 1996 by Carsten Paeth (calle@calle.in-berlin.de)
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.12/linux/include/linux/b1pcmcia.h linux/include/linux/b1pcmcia.h
--- v2.4.12/linux/include/linux/b1pcmcia.h	Sat May 19 17:54:14 2001
+++ linux/include/linux/b1pcmcia.h	Thu Oct 11 09:47:33 2001
@@ -1,10 +1,12 @@
-/*
- * $Id: b1pcmcia.h,v 1.1.8.1 2001/05/17 20:41:52 kai Exp $
+/* $Id: b1pcmcia.h,v 1.1.8.2 2001/09/23 22:25:05 kai Exp $
  *
  * Exported functions of module b1pcmcia to be called by
  * avm_cs card services module.
  *
  * Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.12/linux/include/linux/blkdev.h linux/include/linux/blkdev.h
--- v2.4.12/linux/include/linux/blkdev.h	Tue Oct  9 17:06:53 2001
+++ linux/include/linux/blkdev.h	Thu Oct 11 13:57:50 2001
@@ -203,4 +203,27 @@
 #define blk_finished_io(nsects)	do { } while (0)
 #define blk_started_io(nsects)	do { } while (0)
 
+static inline unsigned int blksize_bits(unsigned int size)
+{
+	unsigned int bits = 8;
+	do {
+		bits++;
+		size >>= 1;
+	} while (size > 256);
+	return bits;
+}
+
+static inline unsigned int block_size(kdev_t dev)
+{
+	int retval = BLOCK_SIZE;
+	int major = MAJOR(dev);
+
+	if (blksize_size[major]) {
+		int minor = MINOR(dev);
+		if (blksize_size[major][minor])
+			retval = blksize_size[major][minor];
+	}
+	return retval;
+}
+
 #endif
diff -u --recursive --new-file v2.4.12/linux/include/linux/console_struct.h linux/include/linux/console_struct.h
--- v2.4.12/linux/include/linux/console_struct.h	Mon Oct 16 12:53:18 2000
+++ linux/include/linux/console_struct.h	Thu Oct 11 11:17:22 2001
@@ -68,7 +68,7 @@
 	unsigned char	vc_utf		: 1;	/* Unicode UTF-8 encoding */
 	unsigned char	vc_utf_count;
 		 int	vc_utf_char;
-	unsigned int	vc_tab_stop[5];		/* Tab stops. 160 columns. */
+	unsigned int	vc_tab_stop[8];		/* Tab stops. 256 columns. */
 	unsigned char   vc_palette[16*3];       /* Colour palette for VGA+ */
 	unsigned short * vc_translate;
 	unsigned char 	vc_G0_charset;
diff -u --recursive --new-file v2.4.12/linux/include/linux/ext2_fs.h linux/include/linux/ext2_fs.h
--- v2.4.12/linux/include/linux/ext2_fs.h	Thu Oct 11 08:02:26 2001
+++ linux/include/linux/ext2_fs.h	Thu Oct 11 13:56:27 2001
@@ -558,14 +558,15 @@
 						    unsigned int block_group,
 						    struct buffer_head ** bh);
 
-/* bitmap.c */
-extern unsigned long ext2_count_free (struct buffer_head *, unsigned);
-
 /* dir.c */
-
-/* file.c */
-extern int ext2_read (struct inode *, struct file *, char *, int);
-extern int ext2_write (struct inode *, struct file *, char *, int);
+extern int ext2_add_link (struct dentry *, struct inode *);
+extern ino_t ext2_inode_by_name(struct inode *, struct dentry *);
+extern int ext2_make_empty(struct inode *, struct inode *);
+extern struct ext2_dir_entry_2 * ext2_find_entry (struct inode *,struct dentry *, struct page **);
+extern int ext2_delete_entry (struct ext2_dir_entry_2 *, struct page *);
+extern int ext2_empty_dir (struct inode *);
+extern struct ext2_dir_entry_2 * ext2_dotdot (struct inode *, struct page **);
+extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, struct inode *);
 
 /* fsync.c */
 extern int ext2_sync_file (struct file *, struct dentry *, int);
@@ -576,26 +577,21 @@
 extern void ext2_free_inode (struct inode *);
 extern unsigned long ext2_count_free_inodes (struct super_block *);
 extern void ext2_check_inodes_bitmap (struct super_block *);
+extern unsigned long ext2_count_free (struct buffer_head *, unsigned);
 
 /* inode.c */
-
-extern struct buffer_head * ext2_getblk (struct inode *, long, int, int *);
-extern struct buffer_head * ext2_bread (struct inode *, int, int, int *);
-
 extern void ext2_read_inode (struct inode *);
 extern void ext2_write_inode (struct inode *, int);
 extern void ext2_put_inode (struct inode *);
 extern void ext2_delete_inode (struct inode *);
 extern int ext2_sync_inode (struct inode *);
 extern void ext2_discard_prealloc (struct inode *);
+extern void ext2_truncate (struct inode *);
 
 /* ioctl.c */
 extern int ext2_ioctl (struct inode *, struct file *, unsigned int,
 		       unsigned long);
 
-/* namei.c */
-extern struct inode_operations ext2_dir_inode_operations;
-
 /* super.c */
 extern void ext2_error (struct super_block *, const char *, const char *, ...)
 	__attribute__ ((format (printf, 3, 4)));
@@ -611,32 +607,25 @@
 extern struct super_block * ext2_read_super (struct super_block *,void *,int);
 extern int ext2_statfs (struct super_block *, struct statfs *);
 
-/* truncate.c */
-extern void ext2_truncate (struct inode *);
-
 /*
  * Inodes and files operations
  */
 
 /* dir.c */
 extern struct file_operations ext2_dir_operations;
-extern int ext2_add_link (struct dentry *, struct inode *);
-extern ino_t ext2_inode_by_name(struct inode *, struct dentry *);
-extern int ext2_make_empty(struct inode *, struct inode *);
-extern struct ext2_dir_entry_2 * ext2_find_entry (struct inode *,struct dentry *, struct page **);
-extern int ext2_delete_entry (struct ext2_dir_entry_2 *, struct page *);
-extern int ext2_empty_dir (struct inode *);
-extern struct ext2_dir_entry_2 * ext2_dotdot (struct inode *, struct page **);
-extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, struct inode *);
 
 /* file.c */
 extern struct inode_operations ext2_file_inode_operations;
 extern struct file_operations ext2_file_operations;
 
+/* inode.c */
+extern struct address_space_operations ext2_aops;
+
+/* namei.c */
+extern struct inode_operations ext2_dir_inode_operations;
+
 /* symlink.c */
 extern struct inode_operations ext2_fast_symlink_inode_operations;
-
-extern struct address_space_operations ext2_aops;
 
 #endif	/* __KERNEL__ */
 
diff -u --recursive --new-file v2.4.12/linux/include/linux/fs.h linux/include/linux/fs.h
--- v2.4.12/linux/include/linux/fs.h	Thu Oct 11 08:02:26 2001
+++ linux/include/linux/fs.h	Thu Oct 11 13:56:06 2001
@@ -604,6 +604,7 @@
 extern int posix_lock_file(struct file *, struct file_lock *, unsigned int);
 extern void posix_block_lock(struct file_lock *, struct file_lock *);
 extern void posix_unblock_lock(struct file_lock *);
+extern int posix_locks_deadlock(struct file_lock *, struct file_lock *);
 extern int __get_lease(struct inode *inode, unsigned int flags);
 extern time_t lease_get_mtime(struct inode *);
 extern int lock_may_read(struct inode *, loff_t start, unsigned long count);
diff -u --recursive --new-file v2.4.12/linux/include/linux/i2c-dev.h linux/include/linux/i2c-dev.h
--- v2.4.12/linux/include/linux/i2c-dev.h	Sun Aug 12 13:28:01 2001
+++ linux/include/linux/i2c-dev.h	Thu Oct 11 08:05:47 2001
@@ -19,7 +19,7 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-/* $Id: i2c-dev.h,v 1.8 2000/08/12 16:37:15 mds Exp $ */
+/* $Id: i2c-dev.h,v 1.9 2001/08/15 03:04:58 mds Exp $ */
 
 #ifndef I2C_DEV_H
 #define I2C_DEV_H
diff -u --recursive --new-file v2.4.12/linux/include/linux/i2c-elektor.h linux/include/linux/i2c-elektor.h
--- v2.4.12/linux/include/linux/i2c-elektor.h	Fri Jan 28 19:36:23 2000
+++ linux/include/linux/i2c-elektor.h	Thu Oct 11 08:05:47 2001
@@ -22,22 +22,26 @@
 /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
    Frodo Looijaard <frodol@dds.nl> */
 
-/* $Id: i2c-elektor.h,v 1.4 2000/01/18 23:54:07 frodo Exp $ */
+/* $Id: i2c-elektor.h,v 1.5 2001/06/05 01:46:33 mds Exp $ */
 
 #ifndef I2C_PCF_ELEKTOR_H
 #define I2C_PCF_ELEKTOR_H 1
 
 /*
- * This struct contains the hw-dependent functions of PCF8584 adapters to 
- * manipulate the registers, and to init any hw-specific features. 
- */
+ * This struct contains the hw-dependent functions of PCF8584 adapters to
+ * manipulate the registers, and to init any hw-specific features.
+ * vdovikin: removed: this module in real supports only one device,
+ * due to missing arguments in some functions, called from the algo-pcf module.
+ * Sometimes it's need to be rewriten -
+ * but for now just remove this for simpler reading */
 
+/*
 struct i2c_pcf_isa {
 	int pi_base;
 	int pi_irq;
 	int pi_clock;
 	int pi_own;
 };
-
+*/
 
 #endif /* PCF_ELEKTOR_H */
diff -u --recursive --new-file v2.4.12/linux/include/linux/i2c-id.h linux/include/linux/i2c-id.h
--- v2.4.12/linux/include/linux/i2c-id.h	Sun Sep 23 11:41:01 2001
+++ linux/include/linux/i2c-id.h	Thu Oct 11 08:05:47 2001
@@ -20,7 +20,7 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.		     */
 /* ------------------------------------------------------------------------- */
 
-/* $Id: i2c-id.h,v 1.25 2000/10/12 07:27:29 simon Exp $ */
+/* $Id: i2c-id.h,v 1.35 2001/08/12 17:22:20 mds Exp $ */
 
 #ifndef I2C_ID_H
 #define I2C_ID_H
@@ -65,7 +65,7 @@
 #define I2C_DRIVERID_BT829	19	/* pc to tv encoder		*/
 #define I2C_DRIVERID_TDA9850	20	/* audio mixer			*/
 #define I2C_DRIVERID_TDA9855	21	/* audio mixer			*/
-#define I2C_DRIVERID_SAA7110	22	/* 				*/
+#define I2C_DRIVERID_SAA7110	22	/* video decoder		*/
 #define I2C_DRIVERID_MGATVO	23	/* Matrox TVOut			*/
 #define I2C_DRIVERID_SAA5249	24	/* SAA5249 and compatibles	*/
 #define I2C_DRIVERID_PCF8583	25	/* real time clock		*/
@@ -84,7 +84,12 @@
 #define I2C_DRIVERID_VES1820	37     /* VLSI DVB-C decoder		*/
 #define I2C_DRIVERID_SAA7113	38     /* video decoder			*/
 #define I2C_DRIVERID_TDA8444	39     /* octuple 6-bit DAC             */
-
+#define I2C_DRIVERID_BT819	40     /* video decoder			*/
+#define I2C_DRIVERID_BT856	41     /* video encoder			*/
+#define I2C_DRIVERID_VPX32XX	42     /* video decoder+vbi/vtxt	*/
+#define I2C_DRIVERID_DRP3510	43     /* ADR decoder (Astra Radio)	*/
+#define I2C_DRIVERID_SP5055	44     /* Satellite tuner		*/
+#define I2C_DRIVERID_STV0030	45     /* Multipurpose switch		*/
 
 #define I2C_DRIVERID_EXP0	0xF0	/* experimental use id's	*/
 #define I2C_DRIVERID_EXP1	0xF1
@@ -94,6 +99,35 @@
 #define I2C_DRIVERID_I2CDEV	900
 #define I2C_DRIVERID_I2CPROC	901
 
+/* IDs --   Use DRIVERIDs 1000-1999 for sensors. 
+   These were originally in sensors.h in the lm_sensors package */
+#define I2C_DRIVERID_LM78 1002
+#define I2C_DRIVERID_LM75 1003
+#define I2C_DRIVERID_GL518 1004
+#define I2C_DRIVERID_EEPROM 1005
+#define I2C_DRIVERID_W83781D 1006
+#define I2C_DRIVERID_LM80 1007
+#define I2C_DRIVERID_ADM1021 1008
+#define I2C_DRIVERID_ADM9240 1009
+#define I2C_DRIVERID_LTC1710 1010
+#define I2C_DRIVERID_SIS5595 1011
+#define I2C_DRIVERID_ICSPLL 1012
+#define I2C_DRIVERID_BT869 1013
+#define I2C_DRIVERID_MAXILIFE 1014
+#define I2C_DRIVERID_MATORB 1015
+#define I2C_DRIVERID_GL520 1016
+#define I2C_DRIVERID_THMC50 1017
+#define I2C_DRIVERID_DDCMON 1018
+#define I2C_DRIVERID_VIA686A 1019
+#define I2C_DRIVERID_ADM1025 1020
+#define I2C_DRIVERID_LM87 1021
+#define I2C_DRIVERID_PCF8574 1022
+#define I2C_DRIVERID_MTP008 1023
+#define I2C_DRIVERID_DS1621 1024
+#define I2C_DRIVERID_ADM1024 1025
+#define I2C_DRIVERID_IT87 1026
+#define I2C_DRIVERID_CH700X 1027 /* single driver for CH7003-7009 digital pc to tv encoders */
+
 /*
  * ---- Adapter types ----------------------------------------------------
  *
@@ -109,7 +143,6 @@
 #define I2C_ALGO_ISA 	0x050000	/* lm_sensors ISA pseudo-adapter */
 #define I2C_ALGO_SAA7146 0x060000	/* SAA 7146 video decoder bus	*/
 #define I2C_ALGO_ACB 	0x070000	/* ACCESS.bus algorithm         */
-#define I2C_ALGO_IIC    0x080000 	/* ITE IIC bus */
 
 #define I2C_ALGO_EC     0x100000        /* ACPI embedded controller     */
 
@@ -140,8 +173,10 @@
 #define I2C_HW_B_G400	0x09	/* Matrox G400				*/
 #define I2C_HW_B_I810	0x0a	/* Intel I810 				*/
 #define I2C_HW_B_VOO	0x0b	/* 3dfx Voodoo 3 / Banshee      	*/
+#define I2C_HW_B_PPORT  0x0c	/* Primitive parallel port adapter	*/
 #define I2C_HW_B_RIVA	0x10	/* Riva based graphics cards		*/
 #define I2C_HW_B_IOC	0x11	/* IOC bit-wiggling			*/
+#define I2C_HW_B_TSUNA  0x12	/* DEC Tsunami chipset			*/
 
 /* --- PCF 8584 based algorithms					*/
 #define I2C_HW_P_LP	0x00	/* Parallel port interface		*/
@@ -153,9 +188,6 @@
 
 /* --- MPC8xx PowerPC adapters						*/
 #define I2C_HW_MPC8XX_EPON 0x00	/* Eponymous MPC8xx I2C adapter 	*/
-
-/* --- ITE based algorithms						*/
-#define I2C_HW_I_IIC	0x00	/* controller on the ITE */
 
 /* --- SMBus only adapters						*/
 #define I2C_HW_SMBUS_PIIX4	0x00
diff -u --recursive --new-file v2.4.12/linux/include/linux/i2c-proc.h linux/include/linux/i2c-proc.h
--- v2.4.12/linux/include/linux/i2c-proc.h	Wed Dec 31 16:00:00 1969
+++ linux/include/linux/i2c-proc.h	Thu Oct 11 08:05:47 2001
@@ -0,0 +1,396 @@
+/*
+    sensors.h - Part of lm_sensors, Linux kernel modules for hardware
+                monitoring
+    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef SENSORS_SENSORS_H
+#define SENSORS_SENSORS_H
+
+#ifdef __KERNEL__
+
+/* Next two must be included before sysctl.h can be included, in 2.0 kernels */
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/sysctl.h>
+
+/* The type of callback functions used in sensors_{proc,sysctl}_real */
+typedef void (*i2c_real_callback) (struct i2c_client * client,
+				       int operation, int ctl_name,
+				       int *nrels_mag, long *results);
+
+/* Values for the operation field in the above function type */
+#define SENSORS_PROC_REAL_INFO 1
+#define SENSORS_PROC_REAL_READ 2
+#define SENSORS_PROC_REAL_WRITE 3
+
+/* These funcion reads or writes a 'real' value (encoded by the combination
+   of an integer and a magnitude, the last is the power of ten the value
+   should be divided with) to a /proc/sys directory. To use these functions,
+   you must (before registering the ctl_table) set the extra2 field to the
+   client, and the extra1 field to a function of the form:
+      void func(struct i2c_client *client, int operation, int ctl_name,
+                int *nrels_mag, long *results)
+   This last function can be called for three values of operation. If
+   operation equals SENSORS_PROC_REAL_INFO, the magnitude should be returned
+   in nrels_mag. If operation equals SENSORS_PROC_REAL_READ, values should
+   be read into results. nrels_mag should return the number of elements
+   read; the maximum number is put in it on entry. Finally, if operation
+   equals SENSORS_PROC_REAL_WRITE, the values in results should be
+   written to the chip. nrels_mag contains on entry the number of elements
+   found.
+   In all cases, client points to the client we wish to interact with,
+   and ctl_name is the SYSCTL id of the file we are accessing. */
+extern int i2c_sysctl_real(ctl_table * table, int *name, int nlen,
+			       void *oldval, size_t * oldlenp,
+			       void *newval, size_t newlen,
+			       void **context);
+extern int i2c_proc_real(ctl_table * ctl, int write, struct file *filp,
+			     void *buffer, size_t * lenp);
+
+
+
+/* These rather complex functions must be called when you want to add or
+   delete an entry in /proc/sys/dev/sensors/chips (not yet implemented). It
+   also creates a new directory within /proc/sys/dev/sensors/.
+   ctl_template should be a template of the newly created directory. It is
+   copied in memory. The extra2 field of each file is set to point to client.
+   If any driver wants subdirectories within the newly created directory,
+   these functions must be updated! */
+extern int i2c_register_entry(struct i2c_client *client,
+				  const char *prefix,
+				  ctl_table * ctl_template,
+				  struct module *controlling_mod);
+
+extern void i2c_deregister_entry(int id);
+
+
+/* A structure containing detect information.
+   Force variables overrule all other variables; they force a detection on
+   that place. If a specific chip is given, the module blindly assumes this
+   chip type is present; if a general force (kind == 0) is given, the module
+   will still try to figure out what type of chip is present. This is useful
+   if for some reasons the detect for SMBus or ISA address space filled
+   fails.
+   probe: insmod parameter. Initialize this list with SENSORS_I2C_END values.
+     A list of pairs. The first value is a bus number (SENSORS_ISA_BUS for
+     the ISA bus, -1 for any I2C bus), the second is the address. 
+   kind: The kind of chip. 0 equals any chip.
+*/
+struct i2c_force_data {
+	unsigned short *force;
+	unsigned short kind;
+};
+
+/* A structure containing the detect information.
+   normal_i2c: filled in by the module writer. Terminated by SENSORS_I2C_END.
+     A list of I2C addresses which should normally be examined.
+   normal_i2c_range: filled in by the module writer. Terminated by 
+     SENSORS_I2C_END
+     A list of pairs of I2C addresses, each pair being an inclusive range of
+     addresses which should normally be examined.
+   normal_isa: filled in by the module writer. Terminated by SENSORS_ISA_END.
+     A list of ISA addresses which should normally be examined.
+   normal_isa_range: filled in by the module writer. Terminated by 
+     SENSORS_ISA_END
+     A list of triples. The first two elements are ISA addresses, being an
+     range of addresses which should normally be examined. The third is the
+     modulo parameter: only addresses which are 0 module this value relative
+     to the first address of the range are actually considered.
+   probe: insmod parameter. Initialize this list with SENSORS_I2C_END values.
+     A list of pairs. The first value is a bus number (SENSORS_ISA_BUS for
+     the ISA bus, -1 for any I2C bus), the second is the address. These
+     addresses are also probed, as if they were in the 'normal' list.
+   probe_range: insmod parameter. Initialize this list with SENSORS_I2C_END 
+     values.
+     A list of triples. The first value is a bus number (SENSORS_ISA_BUS for
+     the ISA bus, -1 for any I2C bus), the second and third are addresses. 
+     These form an inclusive range of addresses that are also probed, as
+     if they were in the 'normal' list.
+   ignore: insmod parameter. Initialize this list with SENSORS_I2C_END values.
+     A list of pairs. The first value is a bus number (SENSORS_ISA_BUS for
+     the ISA bus, -1 for any I2C bus), the second is the I2C address. These
+     addresses are never probed. This parameter overrules 'normal' and 
+     'probe', but not the 'force' lists.
+   ignore_range: insmod parameter. Initialize this list with SENSORS_I2C_END 
+      values.
+     A list of triples. The first value is a bus number (SENSORS_ISA_BUS for
+     the ISA bus, -1 for any I2C bus), the second and third are addresses. 
+     These form an inclusive range of I2C addresses that are never probed.
+     This parameter overrules 'normal' and 'probe', but not the 'force' lists.
+   force_data: insmod parameters. A list, ending with an element of which
+     the force field is NULL.
+*/
+struct i2c_address_data {
+	unsigned short *normal_i2c;
+	unsigned short *normal_i2c_range;
+	unsigned int *normal_isa;
+	unsigned int *normal_isa_range;
+	unsigned short *probe;
+	unsigned short *probe_range;
+	unsigned short *ignore;
+	unsigned short *ignore_range;
+	struct i2c_force_data *forces;
+};
+
+/* Internal numbers to terminate lists */
+#define SENSORS_I2C_END 0xfffe
+#define SENSORS_ISA_END 0xfffefffe
+
+/* The numbers to use to set an ISA or I2C bus address */
+#define SENSORS_ISA_BUS 9191
+#define SENSORS_ANY_I2C_BUS 0xffff
+
+/* The length of the option lists */
+#define SENSORS_MAX_OPTS 48
+
+/* Default fill of many variables */
+#define SENSORS_DEFAULTS {SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+                          SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END}
+
+/* This is ugly. We need to evaluate SENSORS_MAX_OPTS before it is 
+   stringified */
+#define SENSORS_MODPARM_AUX1(x) "1-" #x "h"
+#define SENSORS_MODPARM_AUX(x) SENSORS_MODPARM_AUX1(x)
+#define SENSORS_MODPARM SENSORS_MODPARM_AUX(SENSORS_MAX_OPTS)
+
+/* SENSORS_MODULE_PARM creates a module parameter, and puts it in the
+   module header */
+#define SENSORS_MODULE_PARM(var,desc) \
+  static unsigned short var[SENSORS_MAX_OPTS] = SENSORS_DEFAULTS; \
+  MODULE_PARM(var,SENSORS_MODPARM); \
+  MODULE_PARM_DESC(var,desc)
+
+/* SENSORS_MODULE_PARM creates a 'force_*' module parameter, and puts it in
+   the module header */
+#define SENSORS_MODULE_PARM_FORCE(name) \
+  SENSORS_MODULE_PARM(force_ ## name, \
+                      "List of adapter,address pairs which are unquestionably" \
+                      " assumed to contain a `" # name "' chip")
+
+
+/* This defines several insmod variables, and the addr_data structure */
+#define SENSORS_INSMOD \
+  SENSORS_MODULE_PARM(probe, \
+                      "List of adapter,address pairs to scan additionally"); \
+  SENSORS_MODULE_PARM(probe_range, \
+                      "List of adapter,start-addr,end-addr triples to scan " \
+                      "additionally"); \
+  SENSORS_MODULE_PARM(ignore, \
+                      "List of adapter,address pairs not to scan"); \
+  SENSORS_MODULE_PARM(ignore_range, \
+                      "List of adapter,start-addr,end-addr triples not to " \
+                      "scan"); \
+  static struct i2c_address_data addr_data = \
+                                       {normal_i2c, normal_i2c_range, \
+                                        normal_isa, normal_isa_range, \
+                                        probe, probe_range, \
+                                        ignore, ignore_range, \
+                                        forces}
+
+/* The following functions create an enum with the chip names as elements. 
+   The first element of the enum is any_chip. These are the only macros
+   a module will want to use. */
+
+#define SENSORS_INSMOD_0 \
+  enum chips { any_chip }; \
+  SENSORS_MODULE_PARM(force, \
+                      "List of adapter,address pairs to boldly assume " \
+                      "to be present"); \
+  static struct i2c_force_data forces[] = {{force,any_chip},{NULL}}; \
+  SENSORS_INSMOD
+
+#define SENSORS_INSMOD_1(chip1) \
+  enum chips { any_chip, chip1 }; \
+  SENSORS_MODULE_PARM(force, \
+                      "List of adapter,address pairs to boldly assume " \
+                      "to be present"); \
+  SENSORS_MODULE_PARM_FORCE(chip1); \
+  static struct i2c_force_data forces[] = {{force,any_chip},\
+                                                 {force_ ## chip1,chip1}, \
+                                                 {NULL}}; \
+  SENSORS_INSMOD
+
+#define SENSORS_INSMOD_2(chip1,chip2) \
+  enum chips { any_chip, chip1, chip2 }; \
+  SENSORS_MODULE_PARM(force, \
+                      "List of adapter,address pairs to boldly assume " \
+                      "to be present"); \
+  SENSORS_MODULE_PARM_FORCE(chip1); \
+  SENSORS_MODULE_PARM_FORCE(chip2); \
+  static struct i2c_force_data forces[] = {{force,any_chip}, \
+                                                 {force_ ## chip1,chip1}, \
+                                                 {force_ ## chip2,chip2}, \
+                                                 {NULL}}; \
+  SENSORS_INSMOD
+
+#define SENSORS_INSMOD_3(chip1,chip2,chip3) \
+  enum chips { any_chip, chip1, chip2, chip3 }; \
+  SENSORS_MODULE_PARM(force, \
+                      "List of adapter,address pairs to boldly assume " \
+                      "to be present"); \
+  SENSORS_MODULE_PARM_FORCE(chip1); \
+  SENSORS_MODULE_PARM_FORCE(chip2); \
+  SENSORS_MODULE_PARM_FORCE(chip3); \
+  static struct i2c_force_data forces[] = {{force,any_chip}, \
+                                                 {force_ ## chip1,chip1}, \
+                                                 {force_ ## chip2,chip2}, \
+                                                 {force_ ## chip3,chip3}, \
+                                                 {NULL}}; \
+  SENSORS_INSMOD
+
+#define SENSORS_INSMOD_4(chip1,chip2,chip3,chip4) \
+  enum chips { any_chip, chip1, chip2, chip3, chip4 }; \
+  SENSORS_MODULE_PARM(force, \
+                      "List of adapter,address pairs to boldly assume " \
+                      "to be present"); \
+  SENSORS_MODULE_PARM_FORCE(chip1); \
+  SENSORS_MODULE_PARM_FORCE(chip2); \
+  SENSORS_MODULE_PARM_FORCE(chip3); \
+  SENSORS_MODULE_PARM_FORCE(chip4); \
+  static struct i2c_force_data forces[] = {{force,any_chip}, \
+                                                 {force_ ## chip1,chip1}, \
+                                                 {force_ ## chip2,chip2}, \
+                                                 {force_ ## chip3,chip3}, \
+                                                 {force_ ## chip4,chip4}, \
+                                                 {NULL}}; \
+  SENSORS_INSMOD
+
+#define SENSORS_INSMOD_5(chip1,chip2,chip3,chip4,chip5) \
+  enum chips { any_chip, chip1, chip2, chip3, chip4, chip5 }; \
+  SENSORS_MODULE_PARM(force, \
+                      "List of adapter,address pairs to boldly assume " \
+                      "to be present"); \
+  SENSORS_MODULE_PARM_FORCE(chip1); \
+  SENSORS_MODULE_PARM_FORCE(chip2); \
+  SENSORS_MODULE_PARM_FORCE(chip3); \
+  SENSORS_MODULE_PARM_FORCE(chip4); \
+  SENSORS_MODULE_PARM_FORCE(chip5); \
+  static struct i2c_force_data forces[] = {{force,any_chip}, \
+                                                 {force_ ## chip1,chip1}, \
+                                                 {force_ ## chip2,chip2}, \
+                                                 {force_ ## chip3,chip3}, \
+                                                 {force_ ## chip4,chip4}, \
+                                                 {force_ ## chip5,chip5}, \
+                                                 {NULL}}; \
+  SENSORS_INSMOD
+
+#define SENSORS_INSMOD_6(chip1,chip2,chip3,chip4,chip5,chip6) \
+  enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6 }; \
+  SENSORS_MODULE_PARM(force, \
+                      "List of adapter,address pairs to boldly assume " \
+                      "to be present"); \
+  SENSORS_MODULE_PARM_FORCE(chip1); \
+  SENSORS_MODULE_PARM_FORCE(chip2); \
+  SENSORS_MODULE_PARM_FORCE(chip3); \
+  SENSORS_MODULE_PARM_FORCE(chip4); \
+  SENSORS_MODULE_PARM_FORCE(chip5); \
+  SENSORS_MODULE_PARM_FORCE(chip6); \
+  static struct i2c_force_data forces[] = {{force,any_chip}, \
+                                                 {force_ ## chip1,chip1}, \
+                                                 {force_ ## chip2,chip2}, \
+                                                 {force_ ## chip3,chip3}, \
+                                                 {force_ ## chip4,chip4}, \
+                                                 {force_ ## chip5,chip5}, \
+                                                 {force_ ## chip6,chip6}, \
+                                                 {NULL}}; \
+  SENSORS_INSMOD
+
+#define SENSORS_INSMOD_7(chip1,chip2,chip3,chip4,chip5,chip6,chip7) \
+  enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, chip7 }; \
+  SENSORS_MODULE_PARM(force, \
+                      "List of adapter,address pairs to boldly assume " \
+                      "to be present"); \
+  SENSORS_MODULE_PARM_FORCE(chip1); \
+  SENSORS_MODULE_PARM_FORCE(chip2); \
+  SENSORS_MODULE_PARM_FORCE(chip3); \
+  SENSORS_MODULE_PARM_FORCE(chip4); \
+  SENSORS_MODULE_PARM_FORCE(chip5); \
+  SENSORS_MODULE_PARM_FORCE(chip6); \
+  SENSORS_MODULE_PARM_FORCE(chip7); \
+  static struct i2c_force_data forces[] = {{force,any_chip}, \
+                                                 {force_ ## chip1,chip1}, \
+                                                 {force_ ## chip2,chip2}, \
+                                                 {force_ ## chip3,chip3}, \
+                                                 {force_ ## chip4,chip4}, \
+                                                 {force_ ## chip5,chip5}, \
+                                                 {force_ ## chip6,chip6}, \
+                                                 {force_ ## chip7,chip7}, \
+                                                 {NULL}}; \
+  SENSORS_INSMOD
+
+typedef int i2c_found_addr_proc(struct i2c_adapter *adapter,
+				    int addr, unsigned short flags,
+				    int kind);
+
+/* Detect function. It iterates over all possible addresses itself. For
+   SMBus addresses, it will only call found_proc if some client is connected
+   to the SMBus (unless a 'force' matched); for ISA detections, this is not
+   done. */
+extern int i2c_detect(struct i2c_adapter *adapter,
+			  struct i2c_address_data *address_data,
+			  i2c_found_addr_proc * found_proc);
+
+
+/* This macro is used to scale user-input to sensible values in almost all
+   chip drivers. */
+extern inline int SENSORS_LIMIT(long value, long low, long high)
+{
+	if (value < low)
+		return low;
+	else if (value > high)
+		return high;
+	else
+		return value;
+}
+
+#endif				/* def __KERNEL__ */
+
+
+/* The maximum length of the prefix */
+#define SENSORS_PREFIX_MAX 20
+
+/* Sysctl IDs */
+#ifdef DEV_HWMON
+#define DEV_SENSORS DEV_HWMON
+#else				/* ndef DEV_HWMOM */
+#define DEV_SENSORS 2		/* The id of the lm_sensors directory within the
+				   dev table */
+#endif				/* def DEV_HWMON */
+
+#define SENSORS_CHIPS 1
+struct i2c_chips_data {
+	int sysctl_id;
+	char name[SENSORS_PREFIX_MAX + 13];
+};
+
+#endif				/* def SENSORS_SENSORS_H */
+
diff -u --recursive --new-file v2.4.12/linux/include/linux/i2c.h linux/include/linux/i2c.h
--- v2.4.12/linux/include/linux/i2c.h	Tue Mar  6 19:44:37 2001
+++ linux/include/linux/i2c.h	Thu Oct 11 08:05:47 2001
@@ -23,11 +23,14 @@
 /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and
    Frodo Looijaard <frodol@dds.nl> */
 
-/* $Id: i2c.h,v 1.42 2000/09/06 20:14:06 frodo Exp $ */
+/* $Id: i2c.h,v 1.46 2001/08/31 00:04:07 phil Exp $ */
 
 #ifndef I2C_H
 #define I2C_H
 
+#define I2C_DATE "20010830"
+#define I2C_VERSION "2.6.1"
+
 #include <linux/i2c-id.h>	/* id values of adapters et. al. 	*/
 #include <linux/types.h>
 
@@ -202,7 +205,7 @@
 	char name[32];				/* textual description 	*/
 	unsigned int id;
 
-	/* If a adapter algorithm can't to I2C-level access, set master_xfer
+	/* If an adapter algorithm can't to I2C-level access, set master_xfer
 	   to NULL. If an adapter algorithm can do SMBus access, set 
 	   smbus_xfer. If set to NULL, the SMBus protocol is simulated
 	   using common I2C messages */
@@ -344,7 +347,7 @@
    you can cheat by simply not registering. Not recommended, of course! */
 extern int i2c_check_addr (struct i2c_adapter *adapter, int addr);
 
-/* Detect function. It itterates over all possible addresses itself.
+/* Detect function. It iterates over all possible addresses itself.
  * It will only call found_proc if some client is connected at the
  * specific address (unless a 'force' matched);
  */
@@ -360,7 +363,7 @@
 extern int i2c_control(struct i2c_client *,unsigned int, unsigned long);
 
 /* This call returns a unique low identifier for each registered adapter,
- * or -1 if the adapter was not regisitered. 
+ * or -1 if the adapter was not registered. 
  */
 extern int i2c_adapter_id(struct i2c_adapter *adap);
 
@@ -454,8 +457,9 @@
  *	corresponding header files.
  */
 				/* -> bit-adapter specific ioctls	*/
-#define I2C_RETRIES	0x0701	/* number times a device address should	*/
-				/* be polled when not acknowledging 	*/
+#define I2C_RETRIES	0x0701	/* number of times a device address      */
+				/* should be polled when not            */
+                                /* acknowledging 			*/
 #define I2C_TIMEOUT	0x0702	/* set timeout - call with int 		*/
 
 
@@ -548,6 +552,13 @@
                                         probe, probe_range, \
                                         ignore, ignore_range, \
                                         force}
+
+/* Detect whether we are on the isa bus. If this returns true, all i2c
+   access will fail! */
+#define i2c_is_isa_client(clientptr) \
+        ((clientptr)->adapter->algo->id == I2C_ALGO_ISA)
+#define i2c_is_isa_adapter(adapptr) \
+        ((adapptr)->algo->id == I2C_ALGO_ISA)
 
 #endif /* def __KERNEL__ */
 #endif /* I2C_H */
diff -u --recursive --new-file v2.4.12/linux/include/linux/i2o-dev.h linux/include/linux/i2o-dev.h
--- v2.4.12/linux/include/linux/i2o-dev.h	Wed Apr 12 09:38:53 2000
+++ linux/include/linux/i2o-dev.h	Thu Oct 11 11:17:22 2001
@@ -34,11 +34,11 @@
 #define I2OLCTGET		_IOWR(I2O_MAGIC_NUMBER,2,struct i2o_cmd_hrtlct)
 #define I2OPARMSET		_IOWR(I2O_MAGIC_NUMBER,3,struct i2o_cmd_psetget)
 #define I2OPARMGET		_IOWR(I2O_MAGIC_NUMBER,4,struct i2o_cmd_psetget)
-#define I2OSWDL			_IOWR(I2O_MAGIC_NUMBER,5,struct i2o_sw_xfer)
-#define I2OSWUL			_IOWR(I2O_MAGIC_NUMBER,6,struct i2o_sw_xfer)
+#define I2OSWDL 		_IOWR(I2O_MAGIC_NUMBER,5,struct i2o_sw_xfer)
+#define I2OSWUL 		_IOWR(I2O_MAGIC_NUMBER,6,struct i2o_sw_xfer)
 #define I2OSWDEL		_IOWR(I2O_MAGIC_NUMBER,7,struct i2o_sw_xfer)
 #define I2OVALIDATE		_IOR(I2O_MAGIC_NUMBER,8,u32)
-#define I2OHTML			_IOWR(I2O_MAGIC_NUMBER,9,struct i2o_html)
+#define I2OHTML 		_IOWR(I2O_MAGIC_NUMBER,9,struct i2o_html)
 #define I2OEVTREG		_IOW(I2O_MAGIC_NUMBER,10,struct i2o_evt_id)
 #define I2OEVTGET		_IOR(I2O_MAGIC_NUMBER,11,struct i2o_evt_info)
 
@@ -68,7 +68,7 @@
 	void *buf;		/* Pointer to software buffer */
 	unsigned int *swlen;	/* Length of software data */
 	unsigned int *maxfrag;	/* Maximum fragment count */
-        unsigned int *curfrag;	/* Current fragment count */
+	unsigned int *curfrag;	/* Current fragment count */
 };
 
 struct i2o_html
@@ -98,7 +98,7 @@
 {
 	struct i2o_evt_id id;
 	unsigned char evt_data[I2O_EVT_DATA_SIZE];
- 	unsigned int data_size;
+	unsigned int data_size;
 };
 
 struct i2o_evt_get
@@ -119,8 +119,8 @@
 #define I2O_BUS_PCI	4
 #define I2O_BUS_PCMCIA	5
 #define I2O_BUS_NUBUS	6
-#define I2O_BUS_CARDBUS	7
-#define I2O_BUS_UNKNOWN	0x80
+#define I2O_BUS_CARDBUS 7
+#define I2O_BUS_UNKNOWN 0x80
 
 #ifndef __KERNEL__
 
@@ -130,127 +130,139 @@
 
 #endif /* __KERNEL__ */
 
-typedef struct _i2o_pci_bus {
-	u8 PciFunctionNumber;
-	u8 PciDeviceNumber;
-	u8 PciBusNumber;
-	u8 reserved;
-	u16 PciVendorID;
-	u16 PciDeviceID;
+typedef struct _i2o_pci_bus
+{
+	u8	PciFunctionNumber;
+	u8	PciDeviceNumber;
+	u8	PciBusNumber;
+	u8	reserved;
+	u16	PciVendorID;
+	u16	PciDeviceID;
 } i2o_pci_bus;
 
-typedef struct _i2o_local_bus {
-	u16 LbBaseIOPort;
-	u16 reserved;
-	u32 LbBaseMemoryAddress;
+typedef struct _i2o_local_bus
+{
+	u16	LbBaseIOPort;
+	u16	reserved;
+	u32	LbBaseMemoryAddress;
 } i2o_local_bus;
 
-typedef struct _i2o_isa_bus {
-	u16 IsaBaseIOPort;
-	u8 CSN;
-	u8 reserved;
-	u32 IsaBaseMemoryAddress;
+typedef struct _i2o_isa_bus
+{
+	u16	IsaBaseIOPort;
+	u8	CSN;
+	u8	reserved;
+	u32	IsaBaseMemoryAddress;
 } i2o_isa_bus;
 
-typedef struct _i2o_eisa_bus_info {
-	u16 EisaBaseIOPort;
-	u8 reserved;
-	u8 EisaSlotNumber;
-	u32 EisaBaseMemoryAddress;
+typedef struct _i2o_eisa_bus_info
+{
+	u16	EisaBaseIOPort;
+	u8	reserved;
+	u8	EisaSlotNumber;
+	u32	EisaBaseMemoryAddress;
 } i2o_eisa_bus;
 
-typedef struct _i2o_mca_bus {
-	u16 McaBaseIOPort;
-	u8 reserved;
-	u8 McaSlotNumber;
-	u32 McaBaseMemoryAddress;
+typedef struct _i2o_mca_bus
+{
+	u16	McaBaseIOPort;
+	u8	reserved;
+	u8	McaSlotNumber;
+	u32	McaBaseMemoryAddress;
 } i2o_mca_bus;
 
-typedef struct _i2o_other_bus {
+typedef struct _i2o_other_bus
+{
 	u16 BaseIOPort;
 	u16 reserved;
 	u32 BaseMemoryAddress;
 } i2o_other_bus;
 
-typedef struct _i2o_hrt_entry {
-	u32 adapter_id;
-	u32 parent_tid:12;
-	u32 state:4;
-	u32 bus_num:8;
-	u32 bus_type:8;
-	union {
-		i2o_pci_bus pci_bus;
-		i2o_local_bus local_bus;
-		i2o_isa_bus isa_bus;
-		i2o_eisa_bus eisa_bus;
-		i2o_mca_bus mca_bus;
-		i2o_other_bus other_bus;
+typedef struct _i2o_hrt_entry
+{
+	u32	adapter_id;
+	u32	parent_tid:12;
+	u32 	tate:4;
+	u32	bus_num:8;
+	u32	bus_type:8;
+	union
+	{
+		i2o_pci_bus	pci_bus;
+		i2o_local_bus	local_bus;
+		i2o_isa_bus	isa_bus;
+		i2o_eisa_bus	eisa_bus;
+		i2o_mca_bus	mca_bus;
+		i2o_other_bus	other_bus;
 	} bus;
 } i2o_hrt_entry;
 
-typedef struct _i2o_hrt {
-	u16 num_entries;
-	u8 entry_len;
-	u8 hrt_version;
-	u32 change_ind;
+typedef struct _i2o_hrt
+{
+	u16	num_entries;
+	u8	entry_len;
+	u8	hrt_version;
+	u32	change_ind;
 	i2o_hrt_entry hrt_entry[1];
 } i2o_hrt;
 
-typedef struct _i2o_lct_entry {
-	u32 entry_size:16;
-	u32 tid:12;
-	u32 reserved:4;
-	u32 change_ind;
-	u32 device_flags;
-	u32 class_id:12;
-	u32 version:4;
-	u32 vendor_id:16;
-	u32 sub_class;
-	u32 user_tid:12;
-	u32 parent_tid:12;
-	u32 bios_info:8;
-	u8 identity_tag[8];
-	u32 event_capabilities;
+typedef struct _i2o_lct_entry
+{
+	u32	entry_size:16;
+	u32	tid:12;
+	u32	reserved:4;
+	u32	change_ind;
+	u32	device_flags;
+	u32	class_id:12;
+	u32	version:4;
+	u32	vendor_id:16;
+	u32	sub_class;
+	u32	user_tid:12;
+	u32	parent_tid:12;
+	u32	bios_info:8;
+	u8	identity_tag[8];
+	u32	event_capabilities;
 } i2o_lct_entry;
 
-typedef struct _i2o_lct {
-	u32 table_size:16;
-	u32 boot_tid:12;
-	u32 lct_ver:4;
-	u32 iop_flags;
-	u32 change_ind;
+typedef struct _i2o_lct
+{
+	u32	table_size:16;
+	u32	boot_tid:12;
+	u32	lct_ver:4;
+	u32	iop_flags;
+	u32	change_ind;
 	i2o_lct_entry lct_entry[1];
 } i2o_lct;
 
-typedef struct _i2o_status_block {
-	u16 org_id;
-	u16 reserved;
-	u16 iop_id:12;
-	u16 reserved1:4;
-	u16 host_unit_id;
-	u16 segment_number:12;
-	u16 i2o_version:4;
-	u8 iop_state;
-	u8 msg_type;
-	u16 inbound_frame_size;
-	u8 init_code;	
-	u8 reserved2;
-	u32 max_inbound_frames;
-	u32 cur_inbound_frames;
-	u32 max_outbound_frames;
-	char product_id[24];	
-	u32 expected_lct_size;
-	u32 iop_capabilities;
-	u32 desired_mem_size;
-	u32 current_mem_size;
-	u32 current_mem_base;
-	u32 desired_io_size;
-	u32 current_io_size;
-	u32 current_io_base;
-	u32 reserved3:24;
-	u32 cmd_status:8;
+typedef struct _i2o_status_block
+{
+	u16	org_id;
+	u16	reserved;
+	u16	iop_id:12;
+	u16	reserved1:4;
+	u16	host_unit_id;
+	u16	segment_number:12;
+	u16	i2o_version:4;
+	u8	iop_state;
+	u8	msg_type;
+	u16	inbound_frame_size;
+	u8	init_code;
+	u8	reserved2;
+	u32	max_inbound_frames;
+	u32	cur_inbound_frames;
+	u32	max_outbound_frames;
+	char	product_id[24];
+	u32	expected_lct_size;
+	u32	iop_capabilities;
+	u32	desired_mem_size;
+	u32	current_mem_size;
+	u32	current_mem_base;
+	u32	desired_io_size;
+	u32	current_io_size;
+	u32	current_io_base;
+	u32	reserved3:24;
+	u32	cmd_status:8;
 } i2o_status_block;
- 
+
 /* Event indicator mask flags */
 #define I2O_EVT_IND_STATE_CHANGE		0x80000000
 #define I2O_EVT_IND_GENERAL_WARNING		0x40000000
@@ -269,7 +281,7 @@
 #define I2O_EVT_IND_EXEC_ADAPTER_FAULT		0x00000004
 #define I2O_EVT_IND_EXEC_POWER_FAIL		0x00000008
 #define I2O_EVT_IND_EXEC_RESET_PENDING		0x00000010
-#define I2O_EVT_IND_EXEC_RESET_IMMINENT		0x00000020
+#define I2O_EVT_IND_EXEC_RESET_IMMINENT 	0x00000020
 #define I2O_EVT_IND_EXEC_HW_FAIL		0x00000040
 #define I2O_EVT_IND_EXEC_XCT_CHANGE		0x00000080
 #define I2O_EVT_IND_EXEC_NEW_LCT_ENTRY		0x00000100
@@ -280,14 +292,14 @@
 #define I2O_EVT_IND_BSA_VOLUME_LOAD		0x00000001
 #define I2O_EVT_IND_BSA_VOLUME_UNLOAD		0x00000002
 #define I2O_EVT_IND_BSA_VOLUME_UNLOAD_REQ	0x00000004
-#define I2O_EVT_IND_BSA_CAPACITY_CHANGE		0x00000008
+#define I2O_EVT_IND_BSA_CAPACITY_CHANGE 	0x00000008
 #define I2O_EVT_IND_BSA_SCSI_SMART		0x00000010
 
 /* Event data for generic events */
 #define I2O_EVT_STATE_CHANGE_NORMAL		0x00
 #define I2O_EVT_STATE_CHANGE_SUSPENDED		0x01
 #define I2O_EVT_STATE_CHANGE_RESTART		0x02
-#define I2O_EVT_STATE_CHANGE_NA_RECOVER		0x03
+#define I2O_EVT_STATE_CHANGE_NA_RECOVER 	0x03
 #define I2O_EVT_STATE_CHANGE_NA_NO_RECOVER	0x04
 #define I2O_EVT_STATE_CHANGE_QUIESCE_REQUEST	0x05
 #define I2O_EVT_STATE_CHANGE_FAILED		0x10
@@ -295,7 +307,7 @@
 
 #define I2O_EVT_GEN_WARNING_NORMAL		0x00
 #define I2O_EVT_GEN_WARNING_ERROR_THRESHOLD	0x01
-#define I2O_EVT_GEN_WARNING_MEDIA_FAULT		0x02
+#define I2O_EVT_GEN_WARNING_MEDIA_FAULT 	0x02
 
 #define I2O_EVT_CAPABILITY_OTHER		0x01
 #define I2O_EVT_CAPABILITY_CHANGED		0x02
@@ -309,89 +321,89 @@
 /*  Class ID and Code Assignments
  *  (LCT.ClassID.Version field)
  */
-#define    I2O_CLASS_VERSION_10                        0x00
-#define    I2O_CLASS_VERSION_11                        0x01
+#define I2O_CLASS_VERSION_10			0x00
+#define I2O_CLASS_VERSION_11			0x01
 
 /*  Class code names
  *  (from v1.5 Table 6-1 Class Code Assignments.)
  */
- 
-#define    I2O_CLASS_EXECUTIVE                         0x000
-#define    I2O_CLASS_DDM                               0x001
-#define    I2O_CLASS_RANDOM_BLOCK_STORAGE              0x010
-#define    I2O_CLASS_SEQUENTIAL_STORAGE                0x011
-#define    I2O_CLASS_LAN                               0x020
-#define    I2O_CLASS_WAN                               0x030
-#define    I2O_CLASS_FIBRE_CHANNEL_PORT                0x040
-#define    I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL          0x041
-#define    I2O_CLASS_SCSI_PERIPHERAL                   0x051
-#define    I2O_CLASS_ATE_PORT                          0x060
-#define    I2O_CLASS_ATE_PERIPHERAL                    0x061
-#define    I2O_CLASS_FLOPPY_CONTROLLER                 0x070
-#define    I2O_CLASS_FLOPPY_DEVICE                     0x071
-#define    I2O_CLASS_BUS_ADAPTER_PORT                  0x080
-#define    I2O_CLASS_PEER_TRANSPORT_AGENT              0x090
-#define    I2O_CLASS_PEER_TRANSPORT                    0x091
+
+#define I2O_CLASS_EXECUTIVE			0x000
+#define I2O_CLASS_DDM				0x001
+#define I2O_CLASS_RANDOM_BLOCK_STORAGE		0x010
+#define I2O_CLASS_SEQUENTIAL_STORAGE		0x011
+#define I2O_CLASS_LAN				0x020
+#define I2O_CLASS_WAN				0x030
+#define I2O_CLASS_FIBRE_CHANNEL_PORT		0x040
+#define I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL	0x041
+#define I2O_CLASS_SCSI_PERIPHERAL		0x051
+#define I2O_CLASS_ATE_PORT			0x060
+#define I2O_CLASS_ATE_PERIPHERAL		0x061
+#define I2O_CLASS_FLOPPY_CONTROLLER		0x070
+#define I2O_CLASS_FLOPPY_DEVICE 		0x071
+#define I2O_CLASS_BUS_ADAPTER_PORT		0x080
+#define I2O_CLASS_PEER_TRANSPORT_AGENT		0x090
+#define I2O_CLASS_PEER_TRANSPORT		0x091
 
 /* 
  *  Rest of 0x092 - 0x09f reserved for peer-to-peer classes
  */
- 
-#define    I2O_CLASS_MATCH_ANYCLASS                    0xffffffff
+
+#define I2O_CLASS_MATCH_ANYCLASS		0xffffffff
 
 /* 
  *  Subclasses
  */
 
-#define    I2O_SUBCLASS_i960                           0x001
-#define    I2O_SUBCLASS_HDM                            0x020
-#define    I2O_SUBCLASS_ISM                            0x021
- 
+#define I2O_SUBCLASS_i960			0x001
+#define I2O_SUBCLASS_HDM			0x020
+#define I2O_SUBCLASS_ISM			0x021
+
 /* Operation functions */
 
-#define I2O_PARAMS_FIELD_GET	0x0001
-#define I2O_PARAMS_LIST_GET	0x0002
-#define I2O_PARAMS_MORE_GET	0x0003
-#define I2O_PARAMS_SIZE_GET	0x0004
-#define I2O_PARAMS_TABLE_GET	0x0005
-#define I2O_PARAMS_FIELD_SET	0x0006
-#define I2O_PARAMS_LIST_SET	0x0007
-#define I2O_PARAMS_ROW_ADD	0x0008
-#define I2O_PARAMS_ROW_DELETE	0x0009
-#define I2O_PARAMS_TABLE_CLEAR	0x000A
+#define I2O_PARAMS_FIELD_GET			0x0001
+#define I2O_PARAMS_LIST_GET			0x0002
+#define I2O_PARAMS_MORE_GET			0x0003
+#define I2O_PARAMS_SIZE_GET			0x0004
+#define I2O_PARAMS_TABLE_GET			0x0005
+#define I2O_PARAMS_FIELD_SET			0x0006
+#define I2O_PARAMS_LIST_SET			0x0007
+#define I2O_PARAMS_ROW_ADD			0x0008
+#define I2O_PARAMS_ROW_DELETE			0x0009
+#define I2O_PARAMS_TABLE_CLEAR			0x000A
 
 /*
  * I2O serial number conventions / formats 
  * (circa v1.5)
  */
 
-#define    I2O_SNFORMAT_UNKNOWN                        0
-#define    I2O_SNFORMAT_BINARY                         1
-#define    I2O_SNFORMAT_ASCII                          2
-#define    I2O_SNFORMAT_UNICODE                        3
-#define    I2O_SNFORMAT_LAN48_MAC                      4
-#define    I2O_SNFORMAT_WAN                            5
+#define I2O_SNFORMAT_UNKNOWN			0
+#define I2O_SNFORMAT_BINARY			1
+#define I2O_SNFORMAT_ASCII			2
+#define I2O_SNFORMAT_UNICODE			3
+#define I2O_SNFORMAT_LAN48_MAC			4
+#define I2O_SNFORMAT_WAN			5
 
 /* 
  * Plus new in v2.0 (Yellowstone pdf doc)
  */
 
-#define    I2O_SNFORMAT_LAN64_MAC                      6
-#define    I2O_SNFORMAT_DDM                            7
-#define    I2O_SNFORMAT_IEEE_REG64                     8
-#define    I2O_SNFORMAT_IEEE_REG128                    9
-#define    I2O_SNFORMAT_UNKNOWN2                       0xff
+#define I2O_SNFORMAT_LAN64_MAC			6
+#define I2O_SNFORMAT_DDM			7
+#define I2O_SNFORMAT_IEEE_REG64 		8
+#define I2O_SNFORMAT_IEEE_REG128		9
+#define I2O_SNFORMAT_UNKNOWN2			0xff
 
 /*
  *	I2O Get Status State values 
  */
 
-#define	ADAPTER_STATE_INITIALIZING		0x01
-#define	ADAPTER_STATE_RESET			0x02
-#define	ADAPTER_STATE_HOLD			0x04
-#define 	ADAPTER_STATE_READY			0x05
-#define	ADAPTER_STATE_OPERATIONAL		0x08
-#define	ADAPTER_STATE_FAILED			0x10
-#define	ADAPTER_STATE_FAULTED			0x11
-	
+#define ADAPTER_STATE_INITIALIZING		0x01
+#define ADAPTER_STATE_RESET			0x02
+#define ADAPTER_STATE_HOLD			0x04
+#define ADAPTER_STATE_READY			0x05
+#define ADAPTER_STATE_OPERATIONAL		0x08
+#define ADAPTER_STATE_FAILED			0x10
+#define ADAPTER_STATE_FAULTED			0x11
+
 #endif /* _I2O_DEV_H */
diff -u --recursive --new-file v2.4.12/linux/include/linux/i2o.h linux/include/linux/i2o.h
--- v2.4.12/linux/include/linux/i2o.h	Mon Aug 27 12:41:48 2001
+++ linux/include/linux/i2o.h	Thu Oct 11 11:17:22 2001
@@ -17,24 +17,24 @@
 
 #ifndef _I2O_H
 #define _I2O_H
-#ifdef __KERNEL__	/* This file to be included by kernel only */
+
+#ifdef __KERNEL__ /* This file to be included by kernel only */
 
 #include <linux/i2o-dev.h>
 
-/* How many different OSM's are we allowing */ 
+/* How many different OSM's are we allowing */
 #define MAX_I2O_MODULES		64
 
 /* How many OSMs can register themselves for device status updates? */
 #define I2O_MAX_MANAGERS	4
 
-#include <asm/semaphore.h> /* Needed for MUTEX init macros */
+#include <asm/semaphore.h>	/* Needed for MUTEX init macros */
 #include <linux/config.h>
 #include <linux/notifier.h>
-#include <linux/ioport.h>
 #include <asm/atomic.h>
 
 /*
- * message structures
+ *	Message structures
  */
 struct i2o_message
 {
@@ -43,7 +43,7 @@
 	u16	size;
 	u32	target_tid:12;
 	u32	init_tid:12;
-	u32	function:8;	
+	u32	function:8;
 	u32	initiator_context;
 	/* List follows */
 };
@@ -54,18 +54,19 @@
  */
 struct i2o_device
 {
-	i2o_lct_entry lct_data; /* Device LCT information */
-	u32 flags;		
-	int i2oversion;		/* I2O version supported. Actually there
-				 * should be high and low version */
+	i2o_lct_entry lct_data;		/* Device LCT information */
+	u32 flags;
+	int i2oversion;			/* I2O version supported. Actually
+					 * there should be high and low
+					 * version */
 
-	struct proc_dir_entry* proc_entry;	/* /proc dir */
+	struct proc_dir_entry *proc_entry;	/* /proc dir */
 
 	/* Primary user */
 	struct i2o_handler *owner;
 
 	/* Management users */
-	struct i2o_handler *managers[I2O_MAX_MANAGERS];		
+	struct i2o_handler *managers[I2O_MAX_MANAGERS];
 	int num_managers;
 
 	struct i2o_controller *controller;	/* Controlling IOP */
@@ -76,24 +77,23 @@
 
 /*
  *	Resource data for each PCI I2O controller
- */	 	
+ */
 struct i2o_pci
 {
-	struct pci_dev *pdev;	/* PCI device */
-	int irq;
-	int queue_buggy:1;	/* Don't send a lot of messages */
-	int short_req:1;	/* Use small block sizes	*/
-	int dpt:1;		/* Don't quiesce		*/
+	int		irq;
+	int		queue_buggy:1;	/* Don't send a lot of messages */
+	int		short_req:1;	/* Use small block sizes        */
+	int		dpt:1;		/* Don't quiesce                */
 #ifdef CONFIG_MTRR
-	int mtrr_reg0;
-	int mtrr_reg1;
+	int		mtrr_reg0;
+	int		mtrr_reg1;
 #endif
 };
 
 /*
  * Transport types supported by I2O stack
  */
-#define I2O_TYPE_PCI		0x01		/* PCI I2O controller */	
+#define I2O_TYPE_PCI		0x01		/* PCI I2O controller */
 
 
 /*
@@ -101,6 +101,8 @@
  */
 struct i2o_controller
 {
+	struct pci_dev *pdev;		/* PCI device */
+
 	char name[16];
 	int unit;
 	int type;
@@ -126,35 +128,35 @@
 
 	u32 mem_offset;				/* MFA offset */
 	u32 mem_phys;				/* MFA physical */
-	
+
 	int battery:1;				/* Has a battery backup */
 	int io_alloc:1;				/* An I/O resource was allocated */
 	int mem_alloc:1;			/* A memory resource was allocated */
-	
+
 	struct resource io_resource;		/* I/O resource allocated to the IOP */
 	struct resource mem_resource;		/* Mem resource allocated to the IOP */
 
-	struct proc_dir_entry* proc_entry;	/* /proc dir */
+	struct proc_dir_entry *proc_entry;	/* /proc dir */
 
-	union
-	{					/* Bus information */
+	union {					/* Bus information */
 		struct i2o_pci pci;
 	} bus;
 
 	/* Bus specific destructor */
-	void (*destructor)(struct i2o_controller *);		
+	void (*destructor)(struct i2o_controller *);
 
 	/* Bus specific attach/detach */
-	int (*bind)(struct i2o_controller *, struct i2o_device *);	
+	int (*bind)(struct i2o_controller *, struct i2o_device *);
 
 	/* Bus specific initiator */
 	int (*unbind)(struct i2o_controller *, struct i2o_device *);
 
 	/* Bus specific enable/disable */
-	void (*bus_enable)(struct i2o_controller *c);
-	void (*bus_disable)(struct i2o_controller *c);
+	void (*bus_enable)(struct i2o_controller *);
+	void (*bus_disable)(struct i2o_controller *);
 
-	void *page_frame;		/* Message buffers */
+	void *page_frame;			/* Message buffers */
+	dma_addr_t page_frame_map;		/* Cache map */
 };
 
 /*
@@ -169,7 +171,8 @@
 struct i2o_handler
 {
 	/* Message reply handler */
-	void (*reply)(struct i2o_handler *, struct i2o_controller *, struct i2o_message *);
+	void (*reply)(struct i2o_handler *, struct i2o_controller *,
+		      struct i2o_message *);
 
 	/* New device notification handler */
 	void (*new_dev_notify)(struct i2o_controller *, struct i2o_device *);
@@ -181,7 +184,7 @@
 	void (*reboot_notify)(void);
 
 	char *name;		/* OSM name */
-	int context;	/* Low 8 bits of the transaction info */
+	int context;		/* Low 8 bits of the transaction info */
 	u32 class;		/* I2O classes that this driver handles */
 	/* User data follows */
 };
@@ -201,12 +204,12 @@
 {
 	int	(*install)(struct i2o_controller *);
 	int	(*activate)(struct i2o_controller *);
-	struct  i2o_controller*	(*find)(int);
+	struct i2o_controller *(*find)(int);
 	void	(*unlock)(struct i2o_controller *);
-	void	(*run_queue)(struct i2o_controller *c);
+	void	(*run_queue)(struct i2o_controller * c);
 	int	(*delete)(struct i2o_controller *);
 };
-#endif // MODULE
+#endif /* MODULE */
 
 /*
  * I2O System table entry
@@ -222,9 +225,9 @@
 	u32	iop_id:12;
 	u32	reserved2:20;
 	u16	seg_num:12;
-	u16 	i2o_version:4;
-	u8 	iop_state;
-	u8 	msg_type;
+	u16	i2o_version:4;
+	u8	iop_state;
+	u8	msg_type;
 	u16	frame_size;
 	u16	reserved3;
 	u32	last_changed;
@@ -235,14 +238,14 @@
 
 struct i2o_sys_tbl
 {
-	u8 	num_entries;
-	u8 	version;
-	u16 	reserved1;
+	u8	num_entries;
+	u8	version;
+	u16	reserved1;
 	u32	change_ind;
 	u32	reserved2;
 	u32	reserved3;
 	struct i2o_sys_tbl_entry iops[0];
-};	
+};
 
 /*
  *	Messenger inlines
@@ -265,9 +268,9 @@
 
 static inline void I2O_REPLY_WRITE32(struct i2o_controller *c, u32 Val)
 {
-	*c->reply_port= Val;
+	*c->reply_port = Val;
 }
- 
+
 
 static inline u32 I2O_IRQ_READ32(struct i2o_controller *c)
 {
@@ -283,13 +286,13 @@
 static inline void i2o_post_message(struct i2o_controller *c, u32 m)
 {
 	/* The second line isnt spurious - thats forcing PCI posting */
-	I2O_POST_WRITE32(c,m);
+	I2O_POST_WRITE32(c, m);
 	(void) I2O_IRQ_READ32(c);
 }
 
 static inline void i2o_flush_reply(struct i2o_controller *c, u32 m)
 {
-	I2O_REPLY_WRITE32(c,m);
+	I2O_REPLY_WRITE32(c, m);
 }
 
 extern struct i2o_controller *i2o_find_controller(int);
@@ -304,23 +307,27 @@
 extern int i2o_claim_device(struct i2o_device *, struct i2o_handler *);
 extern int i2o_release_device(struct i2o_device *, struct i2o_handler *);
 extern int i2o_device_notify_on(struct i2o_device *, struct i2o_handler *);
-extern int i2o_device_notify_off(struct i2o_device *, struct i2o_handler *);
+extern int i2o_device_notify_off(struct i2o_device *,
+				 struct i2o_handler *);
 
 extern int i2o_post_this(struct i2o_controller *, u32 *, int);
 extern int i2o_post_wait(struct i2o_controller *, u32 *, int, int);
-extern int i2o_post_wait_mem(struct i2o_controller *, u32 *, int, int, void *, void *);
+extern int i2o_post_wait_mem(struct i2o_controller *, u32 *, int, int,
+			     void *, void *);
 
-extern int i2o_query_scalar(struct i2o_controller *, int, int, int, void *, int);
-extern int i2o_set_scalar(struct i2o_controller *, int, int, int, void *, int);
-extern int i2o_query_table(int, struct i2o_controller *, int, int, int, void *,
-			   int, void *, int);
-extern int i2o_clear_table(struct i2o_controller *, int, int); 
-extern int i2o_row_add_table(struct i2o_controller *, int, int, int, void *,
-			     int);
-extern int i2o_issue_params(int, struct i2o_controller *, int, void *,
-			    int, void *, int); 
+extern int i2o_query_scalar(struct i2o_controller *, int, int, int, void *,
+			    int);
+extern int i2o_set_scalar(struct i2o_controller *, int, int, int, void *,
+			  int);
+extern int i2o_query_table(int, struct i2o_controller *, int, int, int,
+			   void *, int, void *, int);
+extern int i2o_clear_table(struct i2o_controller *, int, int);
+extern int i2o_row_add_table(struct i2o_controller *, int, int, int,
+			     void *, int);
+extern int i2o_issue_params(int, struct i2o_controller *, int, void *, int,
+			    void *, int);
 
-extern int i2o_event_register(struct i2o_controller *, u32, u32, u32, u32); 
+extern int i2o_event_register(struct i2o_controller *, u32, u32, u32, u32);
 extern int i2o_event_ack(struct i2o_controller *, u32 *);
 
 extern void i2o_report_status(const char *, const char *, u32 *);
@@ -339,7 +346,7 @@
 
 /*
  * Executive Class
- */ 
+ */
 #define	I2O_CMD_ADAPTER_ASSIGN		0xB3
 #define	I2O_CMD_ADAPTER_READ		0xB2
 #define	I2O_CMD_ADAPTER_RELEASE		0xB5
@@ -524,7 +531,7 @@
 #define	I2O_CLAIM_MANAGEMENT					0x02000000
 #define	I2O_CLAIM_AUTHORIZED					0x03000000
 #define	I2O_CLAIM_SECONDARY					0x04000000
- 
+
 /* Message header defines for VersionOffset */
 #define I2OVER15	0x0001
 #define I2OVER20	0x0002
diff -u --recursive --new-file v2.4.12/linux/include/linux/pci_ids.h linux/include/linux/pci_ids.h
--- v2.4.12/linux/include/linux/pci_ids.h	Thu Oct 11 08:02:26 2001
+++ linux/include/linux/pci_ids.h	Thu Oct 11 11:17:22 2001
@@ -1594,6 +1594,16 @@
 #define PCI_DEVICE_ID_INTEL_82801BA_9	0x244b
 #define PCI_DEVICE_ID_INTEL_82801BA_10	0x244c
 #define PCI_DEVICE_ID_INTEL_82801BA_11	0x244e
+#define PCI_DEVICE_ID_INTEL_82801CA_0	0x2480
+#define PCI_DEVICE_ID_INTEL_82801CA_2	0x2482
+#define PCI_DEVICE_ID_INTEL_82801CA_3	0x2483
+#define PCI_DEVICE_ID_INTEL_82801CA_4	0x2484
+#define PCI_DEVICE_ID_INTEL_82801CA_5	0x2485
+#define PCI_DEVICE_ID_INTEL_82801CA_6	0x2486
+#define PCI_DEVICE_ID_INTEL_82801CA_7	0x2487
+#define PCI_DEVICE_ID_INTEL_82801CA_10	0x248a
+#define PCI_DEVICE_ID_INTEL_82801CA_11	0x248b
+#define PCI_DEVICE_ID_INTEL_82801CA_12	0x248c
 #define PCI_DEVICE_ID_INTEL_82810_MC1	0x7120
 #define PCI_DEVICE_ID_INTEL_82810_IG1	0x7121
 #define PCI_DEVICE_ID_INTEL_82810_MC3	0x7122
diff -u --recursive --new-file v2.4.12/linux/include/linux/sonypi.h linux/include/linux/sonypi.h
--- v2.4.12/linux/include/linux/sonypi.h	Sun Sep 23 11:41:01 2001
+++ linux/include/linux/sonypi.h	Thu Oct 11 11:17:22 2001
@@ -67,9 +67,12 @@
 #define SONYPI_EVENT_FNKEY_S			29
 #define SONYPI_EVENT_FNKEY_B			30
 #define SONYPI_EVENT_BLUETOOTH_PRESSED		31
-#define SONYPI_EVENT_PKEY_P1                    32
-#define SONYPI_EVENT_PKEY_P2                    33
-#define SONYPI_EVENT_PKEY_P3                    34
+#define SONYPI_EVENT_PKEY_P1			32
+#define SONYPI_EVENT_PKEY_P2			33
+#define SONYPI_EVENT_PKEY_P3			34
+#define SONYPI_EVENT_BACK_PRESSED		35
+#define SONYPI_EVENT_LID_CLOSED			36
+#define SONYPI_EVENT_LID_OPENED			37
 
 
 /* brightness etc. ioctls */
diff -u --recursive --new-file v2.4.12/linux/include/linux/spinlock.h linux/include/linux/spinlock.h
--- v2.4.12/linux/include/linux/spinlock.h	Tue Oct  9 17:06:53 2001
+++ linux/include/linux/spinlock.h	Thu Oct 11 13:56:05 2001
@@ -30,6 +30,10 @@
 #define write_unlock_irqrestore(lock, flags)	do { write_unlock(lock); local_irq_restore(flags); } while (0)
 #define write_unlock_irq(lock)			do { write_unlock(lock); local_irq_enable();       } while (0)
 #define write_unlock_bh(lock)			do { write_unlock(lock); local_bh_enable();        } while (0)
+#define spin_trylock_bh(lock)			({ int __r; local_bh_disable();\
+						__r = spin_trylock(lock);      \
+						if (!__r) local_bh_enable();   \
+						__r; })
 
 #ifdef CONFIG_SMP
 #include <asm/spinlock.h>
diff -u --recursive --new-file v2.4.12/linux/include/linux/udf_fs.h linux/include/linux/udf_fs.h
--- v2.4.12/linux/include/linux/udf_fs.h	Tue Jul  3 17:08:22 2001
+++ linux/include/linux/udf_fs.h	Thu Oct 11 08:59:24 2001
@@ -37,8 +37,8 @@
 #define UDF_PREALLOCATE
 #define UDF_DEFAULT_PREALLOC_BLOCKS	8
 
-#define UDFFS_DATE			"2001/06/13"
-#define UDFFS_VERSION			"0.9.4.1"
+#define UDFFS_DATE			"2001/10/10"
+#define UDFFS_VERSION			"0.9.5"
 
 #if !defined(UDFFS_RW)
 
diff -u --recursive --new-file v2.4.12/linux/include/linux/udf_fs_sb.h linux/include/linux/udf_fs_sb.h
--- v2.4.12/linux/include/linux/udf_fs_sb.h	Tue Aug  7 12:48:40 2001
+++ linux/include/linux/udf_fs_sb.h	Thu Oct 11 08:59:24 2001
@@ -18,10 +18,6 @@
 #if !defined(_LINUX_UDF_FS_SB_H)
 #define _LINUX_UDF_FS_SB_H
 
-#ifndef LINUX_VERSION_CODE
-#include <linux/version.h>
-#endif
-
 #pragma pack(1)
 
 #define UDF_MAX_BLOCK_LOADED	8
@@ -89,7 +85,7 @@
 	__u16			s_partition;
 
 	/* Sector headers */
-	__u32			s_session;
+	__s32			s_session;
 	__u32			s_anchor[4];
 	__u32			s_lastblock;
 
diff -u --recursive --new-file v2.4.12/linux/include/linux/videodev.h linux/include/linux/videodev.h
--- v2.4.12/linux/include/linux/videodev.h	Sun Aug 12 13:28:01 2001
+++ linux/include/linux/videodev.h	Thu Oct 11 11:17:22 2001
@@ -185,7 +185,7 @@
 {
 	__u32 	x,y;			/* Offsets into image */
 	__u32	width, height;		/* Area to capture */
-	__u16	decimation;		/* Decimation divder */
+	__u16	decimation;		/* Decimation divider */
 	__u16	flags;			/* Flags for capture */
 #define VIDEO_CAPTURE_ODD		0	/* Temporal */
 #define VIDEO_CAPTURE_EVEN		1
@@ -377,15 +377,5 @@
 #define VID_HARDWARE_PWC	31	/* Philips webcams */
 #define VID_HARDWARE_MEYE	32	/* Sony Vaio MotionEye cameras */
 #define VID_HARDWARE_CPIA2	33
-
-/*
- *	Initialiser list
- */
- 
-struct video_init
-{
-	char *name;
-	int (*init)(struct video_init *);
-};
 
 #endif
diff -u --recursive --new-file v2.4.12/linux/include/pcmcia/cs_types.h linux/include/pcmcia/cs_types.h
--- v2.4.12/linux/include/pcmcia/cs_types.h	Fri Feb 16 16:02:37 2001
+++ linux/include/pcmcia/cs_types.h	Thu Oct 11 09:43:29 2001
@@ -36,8 +36,13 @@
 #include <sys/types.h>
 #endif
 
-typedef u_short	socket_t;
+#ifdef __arm__
+typedef u_int   ioaddr_t;
+#else
 typedef u_short	ioaddr_t;
+#endif
+
+typedef u_short	socket_t;
 typedef u_int	event_t;
 typedef u_char	cisdata_t;
 typedef u_short	page_t;
diff -u --recursive --new-file v2.4.12/linux/include/pcmcia/ss.h linux/include/pcmcia/ss.h
--- v2.4.12/linux/include/pcmcia/ss.h	Fri Feb 16 16:02:37 2001
+++ linux/include/pcmcia/ss.h	Thu Oct 11 09:43:29 2001
@@ -30,6 +30,8 @@
 #ifndef _LINUX_SS_H
 #define _LINUX_SS_H
 
+#include <pcmcia/cs_types.h>
+
 /* Definitions for card status flags for GetStatus */
 #define SS_WRPROT	0x0001
 #define SS_CARDLOCK	0x0002
@@ -52,6 +54,7 @@
     u_int	features;
     u_int	irq_mask;
     u_int	map_size;
+    ioaddr_t	io_offset;
     u_char	pci_irq;
     struct pci_dev *cb_dev;
     struct bus_operations *bus;
@@ -101,7 +104,7 @@
     u_char	map;
     u_char	flags;
     u_short	speed;
-    u_short	start, stop;
+    ioaddr_t	start, stop;
 } pccard_io_map;
 
 typedef struct pccard_mem_map {
diff -u --recursive --new-file v2.4.12/linux/kernel/context.c linux/kernel/context.c
--- v2.4.12/linux/kernel/context.c	Sat May 19 17:47:55 2001
+++ linux/kernel/context.c	Thu Oct 11 11:17:22 2001
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/unistd.h>
 #include <linux/signal.h>
+#include <linux/completion.h>
 
 static DECLARE_TASK_QUEUE(tq_context);
 static DECLARE_WAIT_QUEUE_HEAD(context_task_wq);
@@ -63,7 +64,7 @@
 	return ret;
 }
 
-static int context_thread(void *dummy)
+static int context_thread(void *startup)
 {
 	struct task_struct *curtask = current;
 	DECLARE_WAITQUEUE(wait, curtask);
@@ -79,6 +80,8 @@
 	recalc_sigpending(curtask);
 	spin_unlock_irq(&curtask->sigmask_lock);
 
+	complete((struct completion *)startup);
+
 	/* Install a handler so SIGCLD is delivered */
 	sa.sa.sa_handler = SIG_IGN;
 	sa.sa.sa_flags = 0;
@@ -150,7 +153,10 @@
 	
 int start_context_thread(void)
 {
-	kernel_thread(context_thread, NULL, CLONE_FS | CLONE_FILES);
+	static struct completion startup __initdata = COMPLETION_INITIALIZER(startup);
+
+	kernel_thread(context_thread, &startup, CLONE_FS | CLONE_FILES);
+	wait_for_completion(&startup);
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.12/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v2.4.12/linux/kernel/ksyms.c	Tue Oct  9 17:06:53 2001
+++ linux/kernel/ksyms.c	Thu Oct 11 07:52:18 2001
@@ -223,6 +223,7 @@
 EXPORT_SYMBOL(posix_test_lock);
 EXPORT_SYMBOL(posix_block_lock);
 EXPORT_SYMBOL(posix_unblock_lock);
+EXPORT_SYMBOL(posix_locks_deadlock);
 EXPORT_SYMBOL(locks_mandatory_area);
 EXPORT_SYMBOL(dput);
 EXPORT_SYMBOL(have_submounts);
diff -u --recursive --new-file v2.4.12/linux/lib/vsprintf.c linux/lib/vsprintf.c
--- v2.4.12/linux/lib/vsprintf.c	Sun Sep 23 11:41:01 2001
+++ linux/lib/vsprintf.c	Thu Oct 11 11:17:22 2001
@@ -18,6 +18,7 @@
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
+#include <linux/kernel.h>
 
 #include <asm/div64.h>
 
@@ -519,36 +520,44 @@
 	int num = 0;
 	int qualifier;
 	int base;
-	unsigned int field_width;
+	int field_width = -1;
 	int is_sign = 0;
 
-	for (; *fmt; fmt++) {
+	while(*fmt && *str) {
 		/* skip any white space in format */
+		/* white space in format matchs any amount of
+		 * white space, including none, in the input.
+		 */
 		if (isspace(*fmt)) {
-			continue;
+			while (isspace(*fmt))
+				++fmt;
+			while (isspace(*str))
+				++str;
 		}
 
 		/* anything that is not a conversion must match exactly */
-		if (*fmt != '%') {
+		if (*fmt != '%' && *fmt) {
 			if (*fmt++ != *str++)
-				return num;
+				break;
 			continue;
 		}
+
+		if (!*fmt)
+			break;
 		++fmt;
 		
 		/* skip this conversion.
 		 * advance both strings to next white space
 		 */
 		if (*fmt == '*') {
-			while (!isspace(*fmt))
+			while (!isspace(*fmt) && *fmt)
 				fmt++;
-			while(!isspace(*str))
+			while (!isspace(*str) && *str)
 				str++;
 			continue;
 		}
 
 		/* get field width */
-		field_width = 0xffffffffUL;
 		if (isdigit(*fmt))
 			field_width = skip_atoi(&fmt);
 
@@ -561,25 +570,32 @@
 		base = 10;
 		is_sign = 0;
 
-		switch(*fmt) {
+		if (!*fmt || !*str)
+			break;
+
+		switch(*fmt++) {
 		case 'c':
 		{
 			char *s = (char *) va_arg(args,char*);
+			if (field_width == -1)
+				field_width = 1;
 			do {
 				*s++ = *str++;
-			} while(field_width-- > 0);
+			} while(field_width-- > 0 && *str);
 			num++;
 		}
 		continue;
 		case 's':
 		{
 			char *s = (char *) va_arg(args, char *);
+			if(field_width == -1)
+				field_width = INT_MAX;
 			/* first, skip leading white space in buffer */
 			while (isspace(*str))
 				str++;
 
 			/* now copy until next white space */
-			while (!isspace(*str) && field_width--) {
+			while (*str && !isspace(*str) && field_width--) {
 				*s++ = *str++;
 			}
 			*s = '\0';
@@ -620,6 +636,9 @@
 		 */
 		while (isspace(*str))
 			str++;
+
+		if (!*str || !isdigit(*str))
+			break;
 
 		switch(qualifier) {
 		case 'h':
diff -u --recursive --new-file v2.4.12/linux/mm/filemap.c linux/mm/filemap.c
--- v2.4.12/linux/mm/filemap.c	Tue Oct  9 17:06:53 2001
+++ linux/mm/filemap.c	Thu Oct 11 08:02:06 2001
@@ -667,8 +667,7 @@
 static int FASTCALL(page_cache_read(struct file * file, unsigned long offset));
 static int page_cache_read(struct file * file, unsigned long offset)
 {
-	struct inode *inode = file->f_dentry->d_inode;
-	struct address_space *mapping = inode->i_mapping;
+	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
 	struct page **hash = page_hash(mapping, offset);
 	struct page *page; 
 
@@ -1589,8 +1588,8 @@
 {
 	int error;
 	struct file *file = area->vm_file;
-	struct inode *inode = file->f_dentry->d_inode;
-	struct address_space *mapping = inode->i_mapping;
+	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
+	struct inode *inode = mapping->host;
 	struct page *page, **hash, *old_page;
 	unsigned long size, pgoff;
 
@@ -1851,15 +1850,14 @@
 
 int generic_file_mmap(struct file * file, struct vm_area_struct * vma)
 {
-	struct inode *inode = file->f_dentry->d_inode;
+	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
+	struct inode *inode = mapping->host;
 
 	if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE)) {
-		if (!inode->i_mapping->a_ops->writepage)
+		if (!mapping->a_ops->writepage)
 			return -EINVAL;
 	}
-	if (!inode->i_sb || !S_ISREG(inode->i_mode))
-		return -EACCES;
-	if (!inode->i_mapping->a_ops->readpage)
+	if (!mapping->a_ops->readpage)
 		return -ENOEXEC;
 	UPDATE_ATIME(inode);
 	vma->vm_ops = &generic_file_vm_ops;
diff -u --recursive --new-file v2.4.12/linux/net/ipv4/ipconfig.c linux/net/ipv4/ipconfig.c
--- v2.4.12/linux/net/ipv4/ipconfig.c	Tue Oct  9 17:06:53 2001
+++ linux/net/ipv4/ipconfig.c	Thu Oct 11 11:17:22 2001
@@ -95,7 +95,7 @@
  */
 
 /* This is used by platforms which might be able to set the ipconfig
- * variabled using firmware environment vars.  If this is set, it will
+ * variables using firmware environment vars.  If this is set, it will
  * ignore such firmware variables.
  */
 int ic_set_manually __initdata = 0;		/* IPconfig parameters set manually */
diff -u --recursive --new-file v2.4.12/linux/net/sunrpc/sched.c linux/net/sunrpc/sched.c
--- v2.4.12/linux/net/sunrpc/sched.c	Tue Oct  9 17:06:53 2001
+++ linux/net/sunrpc/sched.c	Thu Oct 11 08:12:52 2001
@@ -30,7 +30,7 @@
 /*
  * We give RPC the same get_free_pages priority as NFS
  */
-#define GFP_RPC			GFP_NFS
+#define GFP_RPC			GFP_NOFS
 
 static void			__rpc_default_timer(struct rpc_task *task);
 static void			rpciod_killall(void);
@@ -744,7 +744,7 @@
  * for readahead):
  *
  *   sync user requests:	GFP_KERNEL
- *   async requests:		GFP_RPC		(== GFP_NFS)
+ *   async requests:		GFP_RPC		(== GFP_NOFS)
  *   swap requests:		GFP_ATOMIC	(or new GFP_SWAPPER)
  */
 void *
@@ -1067,8 +1067,6 @@
 	spin_unlock_irq(&current->sigmask_lock);
 
 	strcpy(current->comm, "rpciod");
-
-	current->flags |= PF_MEMALLOC;
 
 	dprintk("RPC: rpciod starting (pid %d)\n", rpciod_pid);
 	while (rpciod_users) {
diff -u --recursive --new-file v2.4.12/linux/net/sunrpc/stats.c linux/net/sunrpc/stats.c
--- v2.4.12/linux/net/sunrpc/stats.c	Tue Dec  7 10:03:12 1999
+++ linux/net/sunrpc/stats.c	Thu Oct 11 11:17:22 2001
@@ -202,3 +202,4 @@
 	rpc_proc_exit();
 }
 #endif
+MODULE_LICENSE("GPL");
